diff options
Diffstat (limited to 'drivers/staging')
601 files changed, 93993 insertions, 113398 deletions
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 06c9081..eac0a7f 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -64,6 +64,8 @@ source "drivers/staging/rtl8712/Kconfig" source "drivers/staging/rts_pstor/Kconfig" +source "drivers/staging/rts5139/Kconfig" + source "drivers/staging/frontier/Kconfig" source "drivers/staging/pohmelfs/Kconfig" @@ -126,8 +128,6 @@ source "drivers/staging/quickstart/Kconfig" source "drivers/staging/sbe-2t3e3/Kconfig" -source "drivers/staging/ath6kl/Kconfig" - source "drivers/staging/keucr/Kconfig" source "drivers/staging/bcm/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index f3c5e33..20be112 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -25,6 +25,7 @@ obj-$(CONFIG_RTL8192U) += rtl8192u/ obj-$(CONFIG_RTL8192E) += rtl8192e/ obj-$(CONFIG_R8712U) += rtl8712/ obj-$(CONFIG_RTS_PSTOR) += rts_pstor/ +obj-$(CONFIG_RTS5139) += rts5139/ obj-$(CONFIG_SPECTRA) += spectra/ obj-$(CONFIG_TRANZPORT) += frontier/ obj-$(CONFIG_POHMELFS) += pohmelfs/ @@ -54,7 +55,6 @@ obj-$(CONFIG_SOLO6X10) += solo6x10/ obj-$(CONFIG_TIDSPBRIDGE) += tidspbridge/ obj-$(CONFIG_ACPI_QUICKSTART) += quickstart/ obj-$(CONFIG_SBE_2T3E3) += sbe-2t3e3/ -obj-$(CONFIG_ATH6K_LEGACY) += ath6kl/ obj-$(CONFIG_USB_ENESTORAGE) += keucr/ obj-$(CONFIG_BCM_WIMAX) += bcm/ obj-$(CONFIG_FT1000) += ft1000/ diff --git a/drivers/staging/altera-stapl/altera.c b/drivers/staging/altera-stapl/altera.c index 8d73a86..c2eff6a 100644 --- a/drivers/staging/altera-stapl/altera.c +++ b/drivers/staging/altera-stapl/altera.c @@ -28,6 +28,7 @@ #include <linux/string.h> #include <linux/firmware.h> #include <linux/slab.h> +#include <linux/module.h> #include "altera.h" #include "altera-exprt.h" #include "altera-jtag.h" @@ -2384,7 +2385,7 @@ static int altera_get_act_info(u8 *p, act_proc_attribute = (p[proc_table + (13 * act_proc_id) + 8] & 0x03); - procptr = (struct altera_procinfo *) + procptr = kzalloc(sizeof(struct altera_procinfo), GFP_KERNEL); diff --git a/drivers/staging/ath6kl/Kconfig b/drivers/staging/ath6kl/Kconfig deleted file mode 100644 index afd6cc1..0000000 --- a/drivers/staging/ath6kl/Kconfig +++ /dev/null @@ -1,158 +0,0 @@ -config ATH6K_LEGACY - tristate "Atheros AR6003 support (non mac80211)" - depends on MMC && WLAN - depends on CFG80211 - select WIRELESS_EXT - select WEXT_PRIV - help - This module adds support for wireless adapters based on Atheros AR6003 chipset running over SDIO. If you choose to build it as a module, it will be called ath6kl. Pls note that AR6002 and AR6001 are not supported by this driver. - -choice - prompt "AR6003 Board Data Configuration" - depends on ATH6K_LEGACY - default AR600x_SD31_XXX - help - Select the appropriate board data template from the list below that matches your AR6003 based reference design. - -config AR600x_SD31_XXX - bool "SD31-xxx" - help - Board Data file for a standard SD31 reference design (File: bdata.SD31.bin) - -config AR600x_WB31_XXX - bool "WB31-xxx" - help - Board Data file for a standard WB31 (BT/WiFi) reference design (File: bdata.WB31.bin) - -config AR600x_SD32_XXX - bool "SD32-xxx" - help - Board Data file for a standard SD32 (5GHz) reference design (File: bdata.SD32.bin) - -config AR600x_CUSTOM_XXX - bool "CUSTOM-xxx" - help - Board Data file for a custom reference design (File: should be named as bdata.CUSTOM.bin) -endchoice - -config ATH6KL_ENABLE_COEXISTENCE - bool "BT Coexistence support" - depends on ATH6K_LEGACY - help - Enables WLAN/BT coexistence support. Select the apprpriate configuration from below. - -choice - prompt "Front-End Antenna Configuration" - depends on ATH6KL_ENABLE_COEXISTENCE - default AR600x_DUAL_ANTENNA - help - Indicates the number of antennas being used by BT and WLAN. Select the appropriate configuration from the list below that matches your AR6003 based reference design. - -config AR600x_DUAL_ANTENNA - bool "Dual Antenna" - help - Dual Antenna Design - -config AR600x_SINGLE_ANTENNA - bool "Single Antenna" - help - Single Antenna Design -endchoice - -choice - prompt "Collocated Bluetooth Type" - depends on ATH6KL_ENABLE_COEXISTENCE - default AR600x_BT_AR3001 - help - Select the appropriate configuration from the list below that matches your AR6003 based reference design. - -config AR600x_BT_QCOM - bool "Qualcomm BTS4020X" - help - Qualcomm BT (3 Wire PTA) - -config AR600x_BT_CSR - bool "CSR BC06" - help - CSR BT (3 Wire PTA) - -config AR600x_BT_AR3001 - bool "Atheros AR3001" - help - Atheros BT (3 Wire PTA) -endchoice - -config ATH6KL_HCI_BRIDGE - bool "HCI over SDIO support" - depends on ATH6K_LEGACY - help - Enables BT over SDIO. Applicable only for combo designs (eg: WB31) - -config ATH6KL_CONFIG_GPIO_BT_RESET - bool "Configure BT Reset GPIO" - depends on ATH6KL_HCI_BRIDGE - help - Configure a WLAN GPIO for use with BT. - -config AR600x_BT_RESET_PIN - int "GPIO" - depends on ATH6KL_CONFIG_GPIO_BT_RESET - default 22 - help - WLAN GPIO to be used for resetting BT - -config ATH6KL_HTC_RAW_INTERFACE - bool "RAW HTC support" - depends on ATH6K_LEGACY - help - Enables raw HTC interface. Allows application to directly talk to the HTC interface via the ioctl interface - -config ATH6KL_VIRTUAL_SCATTER_GATHER - bool "Virtual Scatter-Gather support" - depends on ATH6K_LEGACY - help - Enables virtual scatter gather support for the hardware that does not support it natively. - -config ATH6KL_SKIP_ABI_VERSION_CHECK - bool "Skip ABI version check support" - depends on ATH6K_LEGACY - help - Forces the driver to disable ABI version check. Caution: Incompatilbity between the host driver and target firmware may lead to unknown side effects. - -config ATH6KL_BT_UART_FC_POLARITY - int "UART Flow Control Polarity" - depends on ATH6KL_LEGACY - default 0 - help - Configures the polarity of UART Flow Control. A value of 0 implies active low and is the default setting. Set it to 1 for active high. - -config ATH6KL_DEBUG - bool "Debug support" - depends on ATH6K_LEGACY - help - Enables debug support - -config ATH6KL_ENABLE_HOST_DEBUG - bool "Host Debug support" - depends on ATH6KL_DEBUG - help - Enables debug support in the driver - -config ATH6KL_ENABLE_TARGET_DEBUG_PRINTS - bool "Target Debug support - Enable UART prints" - depends on ATH6KL_DEBUG - help - Enables uart prints - -config AR600x_DEBUG_UART_TX_PIN - int "GPIO" - depends on ATH6KL_ENABLE_TARGET_DEBUG_PRINTS - default 8 - help - WLAN GPIO to be used for Debug UART (Tx) - -config ATH6KL_DISABLE_TARGET_DBGLOGS - bool "Target Debug support - Disable Debug logs" - depends on ATH6KL_DEBUG - help - Enables debug logs diff --git a/drivers/staging/ath6kl/Makefile b/drivers/staging/ath6kl/Makefile deleted file mode 100644 index 1d3f239..0000000 --- a/drivers/staging/ath6kl/Makefile +++ /dev/null @@ -1,122 +0,0 @@ -#------------------------------------------------------------------------------ -# Copyright (c) 2004-2010 Atheros Communications Inc. -# All rights reserved. -# -# -# -# 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. -# -# -# -# Author(s): ="Atheros" -#------------------------------------------------------------------------------ - -ccflags-y += -I$(obj)/include -ccflags-y += -I$(obj)/include/common -ccflags-y += -I$(obj)/wlan/include -ccflags-y += -I$(obj)/os/linux/include -ccflags-y += -I$(obj)/os -ccflags-y += -I$(obj)/bmi/include -ccflags-y += -I$(obj)/include/common/AR6002/hw4.0 - -ifeq ($(CONFIG_AR600x_DUAL_ANTENNA),y) -ccflags-y += -DAR600x_DUAL_ANTENNA -endif - -ifeq ($(CONFIG_AR600x_SINGLE_ANTENNA),y) -ccflags-y += -DAR600x_SINGLE_ANTENNA -endif - -ifeq ($(CONFIG_AR600x_BT_QCOM),y) -ccflags-y += -DAR600x_BT_QCOM -endif - -ifeq ($(CONFIG_AR600x_BT_CSR),y) -ccflags-y += -DAR600x_BT_CSR -endif - -ifeq ($(CONFIG_AR600x_BT_AR3001),y) -ccflags-y += -DAR600x_BT_AR3001 -endif - -ifeq ($(CONFIG_ATH6KL_HCI_BRIDGE),y) -ccflags-y += -DATH_AR6K_ENABLE_GMBOX -ccflags-y += -DHCI_TRANSPORT_SDIO -ccflags-y += -DSETUPHCI_ENABLED -ccflags-y += -DSETUPBTDEV_ENABLED -ath6kl-y += htc2/AR6000/ar6k_gmbox.o -ath6kl-y += htc2/AR6000/ar6k_gmbox_hciuart.o -ath6kl-y += miscdrv/ar3kconfig.o -ath6kl-y += miscdrv/ar3kps/ar3kpsconfig.o -ath6kl-y += miscdrv/ar3kps/ar3kpsparser.o -endif - -ifeq ($(CONFIG_ATH6KL_CONFIG_GPIO_BT_RESET),y) -ccflags-y += -DATH6KL_CONFIG_GPIO_BT_RESET -endif - -ifeq ($(CONFIG_ATH6KL_HTC_RAW_INTERFACE),y) -ccflags-y += -DHTC_RAW_INTERFACE -endif - -ifeq ($(CONFIG_ATH6KL_ENABLE_HOST_DEBUG),y) -ccflags-y += -DDEBUG -ccflags-y += -DATH_DEBUG_MODULE -endif - -ifeq ($(CONFIG_ATH6KL_ENABLE_TARGET_DEBUG_PRINTS),y) -ccflags-y += -DENABLEUARTPRINT_SET -endif - -ifeq ($(CONFIG_ATH6KL_DISABLE_TARGET_DBGLOGS),y) -ccflags-y += -DATH6KL_DISABLE_TARGET_DBGLOGS -endif - -ifeq ($(CONFIG_ATH6KL_VIRTUAL_SCATTER_GATHER),y) -ccflags-y += -DATH6KL_CONFIG_HIF_VIRTUAL_SCATTER -endif - -ifeq ($(CONFIG_ATH6KL_SKIP_ABI_VERSION_CHECK),y) -ccflags-y += -DATH6KL_SKIP_ABI_VERSION_CHECK -endif - -ccflags-y += -DWAPI_ENABLE -ccflags-y += -DCHECKSUM_OFFLOAD - -obj-$(CONFIG_ATH6K_LEGACY) := ath6kl.o -ath6kl-y += htc2/AR6000/ar6k.o -ath6kl-y += htc2/AR6000/ar6k_events.o -ath6kl-y += htc2/htc_send.o -ath6kl-y += htc2/htc_recv.o -ath6kl-y += htc2/htc_services.o -ath6kl-y += htc2/htc.o -ath6kl-y += bmi/src/bmi.o -ath6kl-y += os/linux/cfg80211.o -ath6kl-y += os/linux/ar6000_drv.o -ath6kl-y += os/linux/ar6000_raw_if.o -ath6kl-y += os/linux/ar6000_pm.o -ath6kl-y += os/linux/netbuf.o -ath6kl-y += os/linux/hci_bridge.o -ath6kl-y += miscdrv/common_drv.o -ath6kl-y += miscdrv/credit_dist.o -ath6kl-y += wmi/wmi.o -ath6kl-y += reorder/rcv_aggr.o -ath6kl-y += wlan/src/wlan_node.o -ath6kl-y += wlan/src/wlan_recv_beacon.o -ath6kl-y += wlan/src/wlan_utils.o - -# ATH_HIF_TYPE := sdio -ccflags-y += -I$(obj)/hif/sdio/linux_sdio/include -ccflags-y += -DSDIO -ath6kl-y += hif/sdio/linux_sdio/src/hif.o -ath6kl-y += hif/sdio/linux_sdio/src/hif_scatter.o diff --git a/drivers/staging/ath6kl/TODO b/drivers/staging/ath6kl/TODO deleted file mode 100644 index 7be4b46..0000000 --- a/drivers/staging/ath6kl/TODO +++ /dev/null @@ -1,25 +0,0 @@ -TODO: - -We are working hard on cleaning up the driver. There's sooooooooo much todo -so instead of editing this file please use the wiki: - -http://wireless.kernel.org/en/users/Drivers/ath6kl - -There's a respective TODO page there. Please also subscribe to the wiki page -to get e-mail updates on changes. - -IRC: - -We *really* need to coordinate development for ath6kl as the cleanup -patches will break pretty much any other patches. Please use IRC to -help coordinate better: - -irc.freenode.net -#ath6kl - -Send patches to: - - - Greg Kroah-Hartman <greg@kroah.com> - - Luis R. Rodriguez <mcgrof@gmail.com> - - Joe Perches <joe@perches.com> - - Naveen Singh <nsingh@atheros.com> diff --git a/drivers/staging/ath6kl/bmi/include/bmi_internal.h b/drivers/staging/ath6kl/bmi/include/bmi_internal.h deleted file mode 100644 index 8e25770..0000000 --- a/drivers/staging/ath6kl/bmi/include/bmi_internal.h +++ /dev/null @@ -1,54 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2004-2010 Atheros Communications Inc. -// All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// -// Author(s): ="Atheros" -//============================================================================== -#ifndef BMI_INTERNAL_H -#define BMI_INTERNAL_H - -#include "a_config.h" -#include "athdefs.h" -#include "a_osapi.h" -#define ATH_MODULE_NAME bmi -#include "a_debug.h" -#include "hw/mbox_host_reg.h" -#include "bmi_msg.h" - -#define ATH_DEBUG_BMI ATH_DEBUG_MAKE_MODULE_MASK(0) - - -#define BMI_COMMUNICATION_TIMEOUT 100000 - -/* ------ Global Variable Declarations ------- */ -static bool bmiDone; - -int -bmiBufferSend(struct hif_device *device, - u8 *buffer, - u32 length); - -int -bmiBufferReceive(struct hif_device *device, - u8 *buffer, - u32 length, - bool want_timeout); - -#endif diff --git a/drivers/staging/ath6kl/bmi/src/bmi.c b/drivers/staging/ath6kl/bmi/src/bmi.c deleted file mode 100644 index f1f085e..0000000 --- a/drivers/staging/ath6kl/bmi/src/bmi.c +++ /dev/null @@ -1,1010 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="bmi.c" company="Atheros"> -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// -// Author(s): ="Atheros" -//============================================================================== - - -#ifdef THREAD_X -#include <string.h> -#endif - -#include "hif.h" -#include "bmi.h" -#include "htc_api.h" -#include "bmi_internal.h" - -#ifdef ATH_DEBUG_MODULE -static struct ath_debug_mask_description bmi_debug_desc[] = { - { ATH_DEBUG_BMI , "BMI Tracing"}, -}; - -ATH_DEBUG_INSTANTIATE_MODULE_VAR(bmi, - "bmi", - "Boot Manager Interface", - ATH_DEBUG_MASK_DEFAULTS, - ATH_DEBUG_DESCRIPTION_COUNT(bmi_debug_desc), - bmi_debug_desc); - -#endif - -/* -Although we had envisioned BMI to run on top of HTC, this is not how the -final implementation ended up. On the Target side, BMI is a part of the BSP -and does not use the HTC protocol nor even DMA -- it is intentionally kept -very simple. -*/ - -static bool pendingEventsFuncCheck = false; -static u32 *pBMICmdCredits; -static u8 *pBMICmdBuf; -#define MAX_BMI_CMDBUF_SZ (BMI_DATASZ_MAX + \ - sizeof(u32) /* cmd */ + \ - sizeof(u32) /* addr */ + \ - sizeof(u32))/* length */ -#define BMI_COMMAND_FITS(sz) ((sz) <= MAX_BMI_CMDBUF_SZ) - -/* APIs visible to the driver */ -void -BMIInit(void) -{ - bmiDone = false; - pendingEventsFuncCheck = false; - - /* - * On some platforms, it's not possible to DMA to a static variable - * in a device driver (e.g. Linux loadable driver module). - * So we need to A_MALLOC space for "command credits" and for commands. - * - * Note: implicitly relies on A_MALLOC to provide a buffer that is - * suitable for DMA (or PIO). This buffer will be passed down the - * bus stack. - */ - if (!pBMICmdCredits) { - pBMICmdCredits = (u32 *)A_MALLOC_NOWAIT(4); - A_ASSERT(pBMICmdCredits); - } - - if (!pBMICmdBuf) { - pBMICmdBuf = (u8 *)A_MALLOC_NOWAIT(MAX_BMI_CMDBUF_SZ); - A_ASSERT(pBMICmdBuf); - } - - A_REGISTER_MODULE_DEBUG_INFO(bmi); -} - -void -BMICleanup(void) -{ - if (pBMICmdCredits) { - kfree(pBMICmdCredits); - pBMICmdCredits = NULL; - } - - if (pBMICmdBuf) { - kfree(pBMICmdBuf); - pBMICmdBuf = NULL; - } -} - -int -BMIDone(struct hif_device *device) -{ - int status; - u32 cid; - - if (bmiDone) { - AR_DEBUG_PRINTF (ATH_DEBUG_BMI, ("BMIDone skipped\n")); - return 0; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Done: Enter (device: 0x%p)\n", device)); - bmiDone = true; - cid = BMI_DONE; - - status = bmiBufferSend(device, (u8 *)&cid, sizeof(cid)); - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); - return A_ERROR; - } - - if (pBMICmdCredits) { - kfree(pBMICmdCredits); - pBMICmdCredits = NULL; - } - - if (pBMICmdBuf) { - kfree(pBMICmdBuf); - pBMICmdBuf = NULL; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Done: Exit\n")); - - return 0; -} - -int -BMIGetTargetInfo(struct hif_device *device, struct bmi_target_info *targ_info) -{ - int status; - u32 cid; - - if (bmiDone) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); - return A_ERROR; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Get Target Info: Enter (device: 0x%p)\n", device)); - cid = BMI_GET_TARGET_INFO; - - status = bmiBufferSend(device, (u8 *)&cid, sizeof(cid)); - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); - return A_ERROR; - } - - status = bmiBufferReceive(device, (u8 *)&targ_info->target_ver, - sizeof(targ_info->target_ver), true); - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Version from the device\n")); - return A_ERROR; - } - - if (targ_info->target_ver == TARGET_VERSION_SENTINAL) { - /* Determine how many bytes are in the Target's targ_info */ - status = bmiBufferReceive(device, (u8 *)&targ_info->target_info_byte_count, - sizeof(targ_info->target_info_byte_count), true); - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Info Byte Count from the device\n")); - return A_ERROR; - } - - /* - * The Target's targ_info doesn't match the Host's targ_info. - * We need to do some backwards compatibility work to make this OK. - */ - A_ASSERT(targ_info->target_info_byte_count == sizeof(*targ_info)); - - /* Read the remainder of the targ_info */ - status = bmiBufferReceive(device, - ((u8 *)targ_info)+sizeof(targ_info->target_info_byte_count), - sizeof(*targ_info)-sizeof(targ_info->target_info_byte_count), true); - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read Target Info (%d bytes) from the device\n", - targ_info->target_info_byte_count)); - return A_ERROR; - } - } - - AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Get Target Info: Exit (ver: 0x%x type: 0x%x)\n", - targ_info->target_ver, targ_info->target_type)); - - return 0; -} - -int -BMIReadMemory(struct hif_device *device, - u32 address, - u8 *buffer, - u32 length) -{ - u32 cid; - int status; - u32 offset; - u32 remaining, rxlen; - - A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX + sizeof(cid) + sizeof(address) + sizeof(length))); - memset (pBMICmdBuf, 0, BMI_DATASZ_MAX + sizeof(cid) + sizeof(address) + sizeof(length)); - - if (bmiDone) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); - return A_ERROR; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_BMI, - ("BMI Read Memory: Enter (device: 0x%p, address: 0x%x, length: %d)\n", - device, address, length)); - - cid = BMI_READ_MEMORY; - - remaining = length; - - while (remaining) - { - rxlen = (remaining < BMI_DATASZ_MAX) ? remaining : BMI_DATASZ_MAX; - offset = 0; - memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); - offset += sizeof(cid); - memcpy(&(pBMICmdBuf[offset]), &address, sizeof(address)); - offset += sizeof(address); - memcpy(&(pBMICmdBuf[offset]), &rxlen, sizeof(rxlen)); - offset += sizeof(length); - - status = bmiBufferSend(device, pBMICmdBuf, offset); - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); - return A_ERROR; - } - status = bmiBufferReceive(device, pBMICmdBuf, rxlen, true); - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n")); - return A_ERROR; - } - memcpy(&buffer[length - remaining], pBMICmdBuf, rxlen); - remaining -= rxlen; address += rxlen; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read Memory: Exit\n")); - return 0; -} - -int -BMIWriteMemory(struct hif_device *device, - u32 address, - u8 *buffer, - u32 length) -{ - u32 cid; - int status; - u32 offset; - u32 remaining, txlen; - const u32 header = sizeof(cid) + sizeof(address) + sizeof(length); - u8 alignedBuffer[BMI_DATASZ_MAX]; - u8 *src; - - A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX + header)); - memset (pBMICmdBuf, 0, BMI_DATASZ_MAX + header); - - if (bmiDone) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); - return A_ERROR; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_BMI, - ("BMI Write Memory: Enter (device: 0x%p, address: 0x%x, length: %d)\n", - device, address, length)); - - cid = BMI_WRITE_MEMORY; - - remaining = length; - while (remaining) - { - src = &buffer[length - remaining]; - if (remaining < (BMI_DATASZ_MAX - header)) { - if (remaining & 3) { - /* align it with 4 bytes */ - remaining = remaining + (4 - (remaining & 3)); - memcpy(alignedBuffer, src, remaining); - src = alignedBuffer; - } - txlen = remaining; - } else { - txlen = (BMI_DATASZ_MAX - header); - } - offset = 0; - memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); - offset += sizeof(cid); - memcpy(&(pBMICmdBuf[offset]), &address, sizeof(address)); - offset += sizeof(address); - memcpy(&(pBMICmdBuf[offset]), &txlen, sizeof(txlen)); - offset += sizeof(txlen); - memcpy(&(pBMICmdBuf[offset]), src, txlen); - offset += txlen; - status = bmiBufferSend(device, pBMICmdBuf, offset); - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); - return A_ERROR; - } - remaining -= txlen; address += txlen; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Write Memory: Exit\n")); - - return 0; -} - -int -BMIExecute(struct hif_device *device, - u32 address, - u32 *param) -{ - u32 cid; - int status; - u32 offset; - - A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address) + sizeof(param))); - memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address) + sizeof(param)); - - if (bmiDone) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); - return A_ERROR; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_BMI, - ("BMI Execute: Enter (device: 0x%p, address: 0x%x, param: %d)\n", - device, address, *param)); - - cid = BMI_EXECUTE; - - offset = 0; - memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); - offset += sizeof(cid); - memcpy(&(pBMICmdBuf[offset]), &address, sizeof(address)); - offset += sizeof(address); - memcpy(&(pBMICmdBuf[offset]), param, sizeof(*param)); - offset += sizeof(*param); - status = bmiBufferSend(device, pBMICmdBuf, offset); - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); - return A_ERROR; - } - - status = bmiBufferReceive(device, pBMICmdBuf, sizeof(*param), false); - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n")); - return A_ERROR; - } - - memcpy(param, pBMICmdBuf, sizeof(*param)); - - AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Execute: Exit (param: %d)\n", *param)); - return 0; -} - -int -BMISetAppStart(struct hif_device *device, - u32 address) -{ - u32 cid; - int status; - u32 offset; - - A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address))); - memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address)); - - if (bmiDone) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); - return A_ERROR; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_BMI, - ("BMI Set App Start: Enter (device: 0x%p, address: 0x%x)\n", - device, address)); - - cid = BMI_SET_APP_START; - - offset = 0; - memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); - offset += sizeof(cid); - memcpy(&(pBMICmdBuf[offset]), &address, sizeof(address)); - offset += sizeof(address); - status = bmiBufferSend(device, pBMICmdBuf, offset); - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); - return A_ERROR; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Set App Start: Exit\n")); - return 0; -} - -int -BMIReadSOCRegister(struct hif_device *device, - u32 address, - u32 *param) -{ - u32 cid; - int status; - u32 offset; - - A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address))); - memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address)); - - if (bmiDone) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); - return A_ERROR; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_BMI, - ("BMI Read SOC Register: Enter (device: 0x%p, address: 0x%x)\n", - device, address)); - - cid = BMI_READ_SOC_REGISTER; - - offset = 0; - memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); - offset += sizeof(cid); - memcpy(&(pBMICmdBuf[offset]), &address, sizeof(address)); - offset += sizeof(address); - - status = bmiBufferSend(device, pBMICmdBuf, offset); - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); - return A_ERROR; - } - - status = bmiBufferReceive(device, pBMICmdBuf, sizeof(*param), true); - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n")); - return A_ERROR; - } - memcpy(param, pBMICmdBuf, sizeof(*param)); - - AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read SOC Register: Exit (value: %d)\n", *param)); - return 0; -} - -int -BMIWriteSOCRegister(struct hif_device *device, - u32 address, - u32 param) -{ - u32 cid; - int status; - u32 offset; - - A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address) + sizeof(param))); - memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address) + sizeof(param)); - - if (bmiDone) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); - return A_ERROR; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_BMI, - ("BMI Write SOC Register: Enter (device: 0x%p, address: 0x%x, param: %d)\n", - device, address, param)); - - cid = BMI_WRITE_SOC_REGISTER; - - offset = 0; - memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); - offset += sizeof(cid); - memcpy(&(pBMICmdBuf[offset]), &address, sizeof(address)); - offset += sizeof(address); - memcpy(&(pBMICmdBuf[offset]), ¶m, sizeof(param)); - offset += sizeof(param); - status = bmiBufferSend(device, pBMICmdBuf, offset); - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); - return A_ERROR; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read SOC Register: Exit\n")); - return 0; -} - -int -BMIrompatchInstall(struct hif_device *device, - u32 ROM_addr, - u32 RAM_addr, - u32 nbytes, - u32 do_activate, - u32 *rompatch_id) -{ - u32 cid; - int status; - u32 offset; - - A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(ROM_addr) + sizeof(RAM_addr) + - sizeof(nbytes) + sizeof(do_activate))); - memset(pBMICmdBuf, 0, sizeof(cid) + sizeof(ROM_addr) + sizeof(RAM_addr) + - sizeof(nbytes) + sizeof(do_activate)); - - if (bmiDone) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); - return A_ERROR; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_BMI, - ("BMI rompatch Install: Enter (device: 0x%p, ROMaddr: 0x%x, RAMaddr: 0x%x length: %d activate: %d)\n", - device, ROM_addr, RAM_addr, nbytes, do_activate)); - - cid = BMI_ROMPATCH_INSTALL; - - offset = 0; - memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); - offset += sizeof(cid); - memcpy(&(pBMICmdBuf[offset]), &ROM_addr, sizeof(ROM_addr)); - offset += sizeof(ROM_addr); - memcpy(&(pBMICmdBuf[offset]), &RAM_addr, sizeof(RAM_addr)); - offset += sizeof(RAM_addr); - memcpy(&(pBMICmdBuf[offset]), &nbytes, sizeof(nbytes)); - offset += sizeof(nbytes); - memcpy(&(pBMICmdBuf[offset]), &do_activate, sizeof(do_activate)); - offset += sizeof(do_activate); - status = bmiBufferSend(device, pBMICmdBuf, offset); - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); - return A_ERROR; - } - - status = bmiBufferReceive(device, pBMICmdBuf, sizeof(*rompatch_id), true); - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n")); - return A_ERROR; - } - memcpy(rompatch_id, pBMICmdBuf, sizeof(*rompatch_id)); - - AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI rompatch Install: (rompatch_id=%d)\n", *rompatch_id)); - return 0; -} - -int -BMIrompatchUninstall(struct hif_device *device, - u32 rompatch_id) -{ - u32 cid; - int status; - u32 offset; - - A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(rompatch_id))); - memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(rompatch_id)); - - if (bmiDone) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); - return A_ERROR; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_BMI, - ("BMI rompatch Uninstall: Enter (device: 0x%p, rompatch_id: %d)\n", - device, rompatch_id)); - - cid = BMI_ROMPATCH_UNINSTALL; - - offset = 0; - memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); - offset += sizeof(cid); - memcpy(&(pBMICmdBuf[offset]), &rompatch_id, sizeof(rompatch_id)); - offset += sizeof(rompatch_id); - status = bmiBufferSend(device, pBMICmdBuf, offset); - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); - return A_ERROR; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI rompatch UNinstall: (rompatch_id=0x%x)\n", rompatch_id)); - return 0; -} - -static int -_BMIrompatchChangeActivation(struct hif_device *device, - u32 rompatch_count, - u32 *rompatch_list, - u32 do_activate) -{ - u32 cid; - int status; - u32 offset; - u32 length; - - A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX + sizeof(cid) + sizeof(rompatch_count))); - memset(pBMICmdBuf, 0, BMI_DATASZ_MAX + sizeof(cid) + sizeof(rompatch_count)); - - if (bmiDone) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); - return A_ERROR; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_BMI, - ("BMI Change rompatch Activation: Enter (device: 0x%p, count: %d)\n", - device, rompatch_count)); - - cid = do_activate ? BMI_ROMPATCH_ACTIVATE : BMI_ROMPATCH_DEACTIVATE; - - offset = 0; - memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); - offset += sizeof(cid); - memcpy(&(pBMICmdBuf[offset]), &rompatch_count, sizeof(rompatch_count)); - offset += sizeof(rompatch_count); - length = rompatch_count * sizeof(*rompatch_list); - memcpy(&(pBMICmdBuf[offset]), rompatch_list, length); - offset += length; - status = bmiBufferSend(device, pBMICmdBuf, offset); - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); - return A_ERROR; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Change rompatch Activation: Exit\n")); - - return 0; -} - -int -BMIrompatchActivate(struct hif_device *device, - u32 rompatch_count, - u32 *rompatch_list) -{ - return _BMIrompatchChangeActivation(device, rompatch_count, rompatch_list, 1); -} - -int -BMIrompatchDeactivate(struct hif_device *device, - u32 rompatch_count, - u32 *rompatch_list) -{ - return _BMIrompatchChangeActivation(device, rompatch_count, rompatch_list, 0); -} - -int -BMILZData(struct hif_device *device, - u8 *buffer, - u32 length) -{ - u32 cid; - int status; - u32 offset; - u32 remaining, txlen; - const u32 header = sizeof(cid) + sizeof(length); - - A_ASSERT(BMI_COMMAND_FITS(BMI_DATASZ_MAX+header)); - memset (pBMICmdBuf, 0, BMI_DATASZ_MAX+header); - - if (bmiDone) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); - return A_ERROR; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_BMI, - ("BMI Send LZ Data: Enter (device: 0x%p, length: %d)\n", - device, length)); - - cid = BMI_LZ_DATA; - - remaining = length; - while (remaining) - { - txlen = (remaining < (BMI_DATASZ_MAX - header)) ? - remaining : (BMI_DATASZ_MAX - header); - offset = 0; - memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); - offset += sizeof(cid); - memcpy(&(pBMICmdBuf[offset]), &txlen, sizeof(txlen)); - offset += sizeof(txlen); - memcpy(&(pBMICmdBuf[offset]), &buffer[length - remaining], txlen); - offset += txlen; - status = bmiBufferSend(device, pBMICmdBuf, offset); - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n")); - return A_ERROR; - } - remaining -= txlen; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI LZ Data: Exit\n")); - - return 0; -} - -int -BMILZStreamStart(struct hif_device *device, - u32 address) -{ - u32 cid; - int status; - u32 offset; - - A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + sizeof(address))); - memset (pBMICmdBuf, 0, sizeof(cid) + sizeof(address)); - - if (bmiDone) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n")); - return A_ERROR; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_BMI, - ("BMI LZ Stream Start: Enter (device: 0x%p, address: 0x%x)\n", - device, address)); - - cid = BMI_LZ_STREAM_START; - offset = 0; - memcpy(&(pBMICmdBuf[offset]), &cid, sizeof(cid)); - offset += sizeof(cid); - memcpy(&(pBMICmdBuf[offset]), &address, sizeof(address)); - offset += sizeof(address); - status = bmiBufferSend(device, pBMICmdBuf, offset); - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to Start LZ Stream to the device\n")); - return A_ERROR; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI LZ Stream Start: Exit\n")); - - return 0; -} - -/* BMI Access routines */ -int -bmiBufferSend(struct hif_device *device, - u8 *buffer, - u32 length) -{ - int status; - u32 timeout; - u32 address; - u32 mboxAddress[HTC_MAILBOX_NUM_MAX]; - - HIFConfigureDevice(device, HIF_DEVICE_GET_MBOX_ADDR, - &mboxAddress[0], sizeof(mboxAddress)); - - *pBMICmdCredits = 0; - timeout = BMI_COMMUNICATION_TIMEOUT; - - while(timeout-- && !(*pBMICmdCredits)) { - /* Read the counter register to get the command credits */ - address = COUNT_DEC_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 4; - /* hit the credit counter with a 4-byte access, the first byte read will hit the counter and cause - * a decrement, while the remaining 3 bytes has no effect. The rationale behind this is to - * make all HIF accesses 4-byte aligned */ - status = HIFReadWrite(device, address, (u8 *)pBMICmdCredits, 4, - HIF_RD_SYNC_BYTE_INC, NULL); - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to decrement the command credit count register\n")); - return A_ERROR; - } - /* the counter is only 8=bits, ignore anything in the upper 3 bytes */ - (*pBMICmdCredits) &= 0xFF; - } - - if (*pBMICmdCredits) { - address = mboxAddress[ENDPOINT1]; - status = HIFReadWrite(device, address, buffer, length, - HIF_WR_SYNC_BYTE_INC, NULL); - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to send the BMI data to the device\n")); - return A_ERROR; - } - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI Communication timeout - bmiBufferSend\n")); - return A_ERROR; - } - - return status; -} - -int -bmiBufferReceive(struct hif_device *device, - u8 *buffer, - u32 length, - bool want_timeout) -{ - int status; - u32 address; - u32 mboxAddress[HTC_MAILBOX_NUM_MAX]; - struct hif_pending_events_info hifPendingEvents; - static HIF_PENDING_EVENTS_FUNC getPendingEventsFunc = NULL; - - if (!pendingEventsFuncCheck) { - /* see if the HIF layer implements an alternative function to get pending events - * do this only once! */ - HIFConfigureDevice(device, - HIF_DEVICE_GET_PENDING_EVENTS_FUNC, - &getPendingEventsFunc, - sizeof(getPendingEventsFunc)); - pendingEventsFuncCheck = true; - } - - HIFConfigureDevice(device, HIF_DEVICE_GET_MBOX_ADDR, - &mboxAddress[0], sizeof(mboxAddress)); - - /* - * During normal bootup, small reads may be required. - * Rather than issue an HIF Read and then wait as the Target - * adds successive bytes to the FIFO, we wait here until - * we know that response data is available. - * - * This allows us to cleanly timeout on an unexpected - * Target failure rather than risk problems at the HIF level. In - * particular, this avoids SDIO timeouts and possibly garbage - * data on some host controllers. And on an interconnect - * such as Compact Flash (as well as some SDIO masters) which - * does not provide any indication on data timeout, it avoids - * a potential hang or garbage response. - * - * Synchronization is more difficult for reads larger than the - * size of the MBOX FIFO (128B), because the Target is unable - * to push the 129th byte of data until AFTER the Host posts an - * HIF Read and removes some FIFO data. So for large reads the - * Host proceeds to post an HIF Read BEFORE all the data is - * actually available to read. Fortunately, large BMI reads do - * not occur in practice -- they're supported for debug/development. - * - * So Host/Target BMI synchronization is divided into these cases: - * CASE 1: length < 4 - * Should not happen - * - * CASE 2: 4 <= length <= 128 - * Wait for first 4 bytes to be in FIFO - * If CONSERVATIVE_BMI_READ is enabled, also wait for - * a BMI command credit, which indicates that the ENTIRE - * response is available in the the FIFO - * - * CASE 3: length > 128 - * Wait for the first 4 bytes to be in FIFO - * - * For most uses, a small timeout should be sufficient and we will - * usually see a response quickly; but there may be some unusual - * (debug) cases of BMI_EXECUTE where we want an larger timeout. - * For now, we use an unbounded busy loop while waiting for - * BMI_EXECUTE. - * - * If BMI_EXECUTE ever needs to support longer-latency execution, - * especially in production, this code needs to be enhanced to sleep - * and yield. Also note that BMI_COMMUNICATION_TIMEOUT is currently - * a function of Host processor speed. - */ - if (length >= 4) { /* NB: Currently, always true */ - /* - * NB: word_available is declared static for esoteric reasons - * having to do with protection on some OSes. - */ - static u32 word_available; - u32 timeout; - - word_available = 0; - timeout = BMI_COMMUNICATION_TIMEOUT; - while((!want_timeout || timeout--) && !word_available) { - - if (getPendingEventsFunc != NULL) { - status = getPendingEventsFunc(device, - &hifPendingEvents, - NULL); - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMI: Failed to get pending events \n")); - break; - } - - if (hifPendingEvents.AvailableRecvBytes >= sizeof(u32)) { - word_available = 1; - } - continue; - } - - status = HIFReadWrite(device, RX_LOOKAHEAD_VALID_ADDRESS, (u8 *)&word_available, - sizeof(word_available), HIF_RD_SYNC_BYTE_INC, NULL); - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read RX_LOOKAHEAD_VALID register\n")); - return A_ERROR; - } - /* We did a 4-byte read to the same register; all we really want is one bit */ - word_available &= (1 << ENDPOINT1); - } - - if (!word_available) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI Communication timeout - bmiBufferReceive FIFO empty\n")); - return A_ERROR; - } - } - -#define CONSERVATIVE_BMI_READ 0 -#if CONSERVATIVE_BMI_READ - /* - * This is an extra-conservative CREDIT check. It guarantees - * that ALL data is available in the FIFO before we start to - * read from the interconnect. - * - * This credit check is useless when firmware chooses to - * allow multiple outstanding BMI Command Credits, since the next - * credit will already be present. To restrict the Target to one - * BMI Command Credit, see HI_OPTION_BMI_CRED_LIMIT. - * - * And for large reads (when HI_OPTION_BMI_CRED_LIMIT is set) - * we cannot wait for the next credit because the Target's FIFO - * will not hold the entire response. So we need the Host to - * start to empty the FIFO sooner. (And again, large reads are - * not used in practice; they are for debug/development only.) - * - * For a more conservative Host implementation (which would be - * safer for a Compact Flash interconnect): - * Set CONSERVATIVE_BMI_READ (above) to 1 - * Set HI_OPTION_BMI_CRED_LIMIT and - * reduce BMI_DATASZ_MAX to 32 or 64 - */ - if ((length > 4) && (length < 128)) { /* check against MBOX FIFO size */ - u32 timeout; - - *pBMICmdCredits = 0; - timeout = BMI_COMMUNICATION_TIMEOUT; - while((!want_timeout || timeout--) && !(*pBMICmdCredits) { - /* Read the counter register to get the command credits */ - address = COUNT_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 1; - /* read the counter using a 4-byte read. Since the counter is NOT auto-decrementing, - * we can read this counter multiple times using a non-incrementing address mode. - * The rationale here is to make all HIF accesses a multiple of 4 bytes */ - status = HIFReadWrite(device, address, (u8 *)pBMICmdCredits, sizeof(*pBMICmdCredits), - HIF_RD_SYNC_BYTE_FIX, NULL); - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read the command credit count register\n")); - return A_ERROR; - } - /* we did a 4-byte read to the same count register so mask off upper bytes */ - (*pBMICmdCredits) &= 0xFF; - } - - if (!(*pBMICmdCredits)) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI Communication timeout- bmiBufferReceive no credit\n")); - return A_ERROR; - } - } -#endif - - address = mboxAddress[ENDPOINT1]; - status = HIFReadWrite(device, address, buffer, length, HIF_RD_SYNC_BYTE_INC, NULL); - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read the BMI data from the device\n")); - return A_ERROR; - } - - return 0; -} - -int -BMIFastDownload(struct hif_device *device, u32 address, u8 *buffer, u32 length) -{ - int status = A_ERROR; - u32 lastWord = 0; - u32 lastWordOffset = length & ~0x3; - u32 unalignedBytes = length & 0x3; - - status = BMILZStreamStart (device, address); - if (status) { - return A_ERROR; - } - - if (unalignedBytes) { - /* copy the last word into a zero padded buffer */ - memcpy(&lastWord, &buffer[lastWordOffset], unalignedBytes); - } - - status = BMILZData(device, buffer, lastWordOffset); - - if (status) { - return A_ERROR; - } - - if (unalignedBytes) { - status = BMILZData(device, (u8 *)&lastWord, 4); - } - - if (!status) { - // - // Close compressed stream and open a new (fake) one. This serves mainly to flush Target caches. - // - status = BMILZStreamStart (device, 0x00); - if (status) { - return A_ERROR; - } - } - return status; -} - -int -BMIRawWrite(struct hif_device *device, u8 *buffer, u32 length) -{ - return bmiBufferSend(device, buffer, length); -} - -int -BMIRawRead(struct hif_device *device, u8 *buffer, u32 length, bool want_timeout) -{ - return bmiBufferReceive(device, buffer, length, want_timeout); -} diff --git a/drivers/staging/ath6kl/hif/common/hif_sdio_common.h b/drivers/staging/ath6kl/hif/common/hif_sdio_common.h deleted file mode 100644 index 93a2adc..0000000 --- a/drivers/staging/ath6kl/hif/common/hif_sdio_common.h +++ /dev/null @@ -1,87 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved. -// -// -// Permission to use, copy, modify, and/or distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// common header file for HIF modules designed for SDIO -// -// Author(s): ="Atheros" -//============================================================================== - -#ifndef HIF_SDIO_COMMON_H_ -#define HIF_SDIO_COMMON_H_ - - /* SDIO manufacturer ID and Codes */ -#define MANUFACTURER_ID_AR6002_BASE 0x200 -#define MANUFACTURER_ID_AR6003_BASE 0x300 -#define MANUFACTURER_ID_AR6K_BASE_MASK 0xFF00 -#define FUNCTION_CLASS 0x0 -#define MANUFACTURER_CODE 0x271 /* Atheros */ - - /* Mailbox address in SDIO address space */ -#define HIF_MBOX_BASE_ADDR 0x800 -#define HIF_MBOX_WIDTH 0x800 -#define HIF_MBOX_START_ADDR(mbox) \ - ( HIF_MBOX_BASE_ADDR + mbox * HIF_MBOX_WIDTH) - -#define HIF_MBOX_END_ADDR(mbox) \ - (HIF_MBOX_START_ADDR(mbox) + HIF_MBOX_WIDTH - 1) - - /* extended MBOX address for larger MBOX writes to MBOX 0*/ -#define HIF_MBOX0_EXTENDED_BASE_ADDR 0x2800 -#define HIF_MBOX0_EXTENDED_WIDTH_AR6002 (6*1024) -#define HIF_MBOX0_EXTENDED_WIDTH_AR6003 (18*1024) - - /* version 1 of the chip has only a 12K extended mbox range */ -#define HIF_MBOX0_EXTENDED_BASE_ADDR_AR6003_V1 0x4000 -#define HIF_MBOX0_EXTENDED_WIDTH_AR6003_V1 (12*1024) - - /* GMBOX addresses */ -#define HIF_GMBOX_BASE_ADDR 0x7000 -#define HIF_GMBOX_WIDTH 0x4000 - - /* for SDIO we recommend a 128-byte block size */ -#define HIF_DEFAULT_IO_BLOCK_SIZE 128 - - /* set extended MBOX window information for SDIO interconnects */ -static INLINE void SetExtendedMboxWindowInfo(u16 Manfid, struct hif_device_mbox_info *pInfo) -{ - switch (Manfid & MANUFACTURER_ID_AR6K_BASE_MASK) { - case MANUFACTURER_ID_AR6002_BASE : - /* MBOX 0 has an extended range */ - pInfo->MboxProp[0].ExtendedAddress = HIF_MBOX0_EXTENDED_BASE_ADDR; - pInfo->MboxProp[0].ExtendedSize = HIF_MBOX0_EXTENDED_WIDTH_AR6002; - break; - case MANUFACTURER_ID_AR6003_BASE : - /* MBOX 0 has an extended range */ - pInfo->MboxProp[0].ExtendedAddress = HIF_MBOX0_EXTENDED_BASE_ADDR_AR6003_V1; - pInfo->MboxProp[0].ExtendedSize = HIF_MBOX0_EXTENDED_WIDTH_AR6003_V1; - pInfo->GMboxAddress = HIF_GMBOX_BASE_ADDR; - pInfo->GMboxSize = HIF_GMBOX_WIDTH; - break; - default: - A_ASSERT(false); - break; - } -} - -/* special CCCR (func 0) registers */ - -#define CCCR_SDIO_IRQ_MODE_REG 0xF0 /* interrupt mode register */ -#define SDIO_IRQ_MODE_ASYNC_4BIT_IRQ (1 << 0) /* mode to enable special 4-bit interrupt assertion without clock*/ - -#endif /*HIF_SDIO_COMMON_H_*/ diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h b/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h deleted file mode 100644 index ed7ad47..0000000 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/include/hif_internal.h +++ /dev/null @@ -1,131 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="hif_internal.h" company="Atheros"> -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// internal header file for hif layer -// -// Author(s): ="Atheros" -//============================================================================== -#ifndef _HIF_INTERNAL_H_ -#define _HIF_INTERNAL_H_ - -#include "a_config.h" -#include "athdefs.h" -#include "a_osapi.h" -#include "hif.h" -#include "../../../common/hif_sdio_common.h" -#include <linux/scatterlist.h> -#define HIF_LINUX_MMC_SCATTER_SUPPORT - -#define BUS_REQUEST_MAX_NUM 64 - -#define SDIO_CLOCK_FREQUENCY_DEFAULT 25000000 -#define SDWLAN_ENABLE_DISABLE_TIMEOUT 20 -#define FLAGS_CARD_ENAB 0x02 -#define FLAGS_CARD_IRQ_UNMSK 0x04 - -#define HIF_MBOX_BLOCK_SIZE HIF_DEFAULT_IO_BLOCK_SIZE -#define HIF_MBOX0_BLOCK_SIZE 1 -#define HIF_MBOX1_BLOCK_SIZE HIF_MBOX_BLOCK_SIZE -#define HIF_MBOX2_BLOCK_SIZE HIF_MBOX_BLOCK_SIZE -#define HIF_MBOX3_BLOCK_SIZE HIF_MBOX_BLOCK_SIZE - -typedef struct bus_request { - struct bus_request *next; /* link list of available requests */ - struct bus_request *inusenext; /* link list of in use requests */ - struct semaphore sem_req; - u32 address; /* request data */ - u8 *buffer; - u32 length; - u32 request; - void *context; - int status; - struct hif_scatter_req_priv *pScatterReq; /* this request is a scatter request */ -} BUS_REQUEST; - -struct hif_device { - struct sdio_func *func; - spinlock_t asynclock; - struct task_struct* async_task; /* task to handle async commands */ - struct semaphore sem_async; /* wake up for async task */ - int async_shutdown; /* stop the async task */ - struct completion async_completion; /* thread completion */ - BUS_REQUEST *asyncreq; /* request for async tasklet */ - BUS_REQUEST *taskreq; /* async tasklet data */ - spinlock_t lock; - BUS_REQUEST *s_busRequestFreeQueue; /* free list */ - BUS_REQUEST busRequest[BUS_REQUEST_MAX_NUM]; /* available bus requests */ - void *claimedContext; - HTC_CALLBACKS htcCallbacks; - u8 *dma_buffer; - struct dl_list ScatterReqHead; /* scatter request list head */ - bool scatter_enabled; /* scatter enabled flag */ - bool is_suspend; - bool is_disabled; - atomic_t irqHandling; - HIF_DEVICE_POWER_CHANGE_TYPE powerConfig; - const struct sdio_device_id *id; -}; - -#define HIF_DMA_BUFFER_SIZE (32 * 1024) -#define CMD53_FIXED_ADDRESS 1 -#define CMD53_INCR_ADDRESS 2 - -BUS_REQUEST *hifAllocateBusRequest(struct hif_device *device); -void hifFreeBusRequest(struct hif_device *device, BUS_REQUEST *busrequest); -void AddToAsyncList(struct hif_device *device, BUS_REQUEST *busrequest); - -#ifdef HIF_LINUX_MMC_SCATTER_SUPPORT - -#define MAX_SCATTER_REQUESTS 4 -#define MAX_SCATTER_ENTRIES_PER_REQ 16 -#define MAX_SCATTER_REQ_TRANSFER_SIZE 32*1024 - -struct hif_scatter_req_priv { - struct hif_scatter_req *pHifScatterReq; /* HIF scatter request with allocated entries */ - struct hif_device *device; /* this device */ - BUS_REQUEST *busrequest; /* request associated with request */ - /* scatter list for linux */ - struct scatterlist sgentries[MAX_SCATTER_ENTRIES_PER_REQ]; -}; - -#define ATH_DEBUG_SCATTER ATH_DEBUG_MAKE_MODULE_MASK(0) - -int SetupHIFScatterSupport(struct hif_device *device, struct hif_device_scatter_support_info *pInfo); -void CleanupHIFScatterResources(struct hif_device *device); -int DoHifReadWriteScatter(struct hif_device *device, BUS_REQUEST *busrequest); - -#else // HIF_LINUX_MMC_SCATTER_SUPPORT - -static inline int SetupHIFScatterSupport(struct hif_device *device, struct hif_device_scatter_support_info *pInfo) -{ - return A_ENOTSUP; -} - -static inline int DoHifReadWriteScatter(struct hif_device *device, BUS_REQUEST *busrequest) -{ - return A_ENOTSUP; -} - -#define CleanupHIFScatterResources(d) { } - -#endif // HIF_LINUX_MMC_SCATTER_SUPPORT - -#endif // _HIF_INTERNAL_H_ - diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c deleted file mode 100644 index 5f5d677..0000000 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c +++ /dev/null @@ -1,1273 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="hif.c" company="Atheros"> -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// HIF layer reference implementation for Linux Native MMC stack -// -// Author(s): ="Atheros" -//============================================================================== -#include <linux/mmc/card.h> -#include <linux/mmc/mmc.h> -#include <linux/mmc/host.h> -#include <linux/mmc/sdio_func.h> -#include <linux/mmc/sdio_ids.h> -#include <linux/mmc/sdio.h> -#include <linux/mmc/sd.h> -#include <linux/kthread.h> - -/* by default setup a bounce buffer for the data packets, if the underlying host controller driver - does not use DMA you may be able to skip this step and save the memory allocation and transfer time */ -#define HIF_USE_DMA_BOUNCE_BUFFER 1 -#include "hif_internal.h" -#define ATH_MODULE_NAME hif -#include "a_debug.h" -#include "hw/mbox_host_reg.h" - -#if HIF_USE_DMA_BOUNCE_BUFFER -/* macro to check if DMA buffer is WORD-aligned and DMA-able. Most host controllers assume the - * buffer is DMA'able and will bug-check otherwise (i.e. buffers on the stack). - * virt_addr_valid check fails on stack memory. - */ -#define BUFFER_NEEDS_BOUNCE(buffer) (((unsigned long)(buffer) & 0x3) || !virt_addr_valid((buffer))) -#else -#define BUFFER_NEEDS_BOUNCE(buffer) (false) -#endif - -/* ATHENV */ -#if defined(CONFIG_PM) -#define dev_to_sdio_func(d) container_of(d, struct sdio_func, dev) -#define to_sdio_driver(d) container_of(d, struct sdio_driver, drv) -#endif /* CONFIG_PM */ -static void delHifDevice(struct hif_device * device); -static int Func0_CMD52WriteByte(struct mmc_card *card, unsigned int address, unsigned char byte); -static int Func0_CMD52ReadByte(struct mmc_card *card, unsigned int address, unsigned char *byte); - -static int hifEnableFunc(struct hif_device *device, struct sdio_func *func); -static int hifDisableFunc(struct hif_device *device, struct sdio_func *func); -OSDRV_CALLBACKS osdrvCallbacks; - -int reset_sdio_on_unload = 0; -module_param(reset_sdio_on_unload, int, 0644); - -extern u32 nohifscattersupport; - -static struct hif_device *ath6kl_alloc_hifdev(struct sdio_func *func) -{ - struct hif_device *hifdevice; - - hifdevice = kzalloc(sizeof(struct hif_device), GFP_KERNEL); - -#if HIF_USE_DMA_BOUNCE_BUFFER - hifdevice->dma_buffer = kmalloc(HIF_DMA_BUFFER_SIZE, GFP_KERNEL); -#endif - hifdevice->func = func; - hifdevice->powerConfig = HIF_DEVICE_POWER_UP; - sdio_set_drvdata(func, hifdevice); - - return hifdevice; -} - -static struct hif_device *ath6kl_get_hifdev(struct sdio_func *func) -{ - return (struct hif_device *) sdio_get_drvdata(func); -} - -static const struct sdio_device_id ath6kl_hifdev_ids[] = { - { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6002_BASE | 0x0)) }, - { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6002_BASE | 0x1)) }, - { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x0)) }, - { SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x1)) }, - { /* null */ }, -}; - -MODULE_DEVICE_TABLE(sdio, ath6kl_hifdev_ids); - -static int ath6kl_hifdev_probe(struct sdio_func *func, - const struct sdio_device_id *id) -{ - int ret; - struct hif_device *device; - int count; - - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, - ("ath6kl: Function: 0x%X, Vendor ID: 0x%X, " - "Device ID: 0x%X, block size: 0x%X/0x%X\n", - func->num, func->vendor, func->device, - func->max_blksize, func->cur_blksize)); - - ath6kl_alloc_hifdev(func); - device = ath6kl_get_hifdev(func); - - device->id = id; - device->is_disabled = true; - - spin_lock_init(&device->lock); - spin_lock_init(&device->asynclock); - - DL_LIST_INIT(&device->ScatterReqHead); - - /* Try to allow scatter unless globally overridden */ - if (!nohifscattersupport) - device->scatter_enabled = true; - - A_MEMZERO(device->busRequest, sizeof(device->busRequest)); - - for (count = 0; count < BUS_REQUEST_MAX_NUM; count++) { - sema_init(&device->busRequest[count].sem_req, 0); - hifFreeBusRequest(device, &device->busRequest[count]); - } - - sema_init(&device->sem_async, 0); - - ret = hifEnableFunc(device, func); - - return ret; -} - -static void ath6kl_hifdev_remove(struct sdio_func *func) -{ - int status = 0; - struct hif_device *device; - - device = ath6kl_get_hifdev(func); - if (device->claimedContext != NULL) - status = osdrvCallbacks. - deviceRemovedHandler(device->claimedContext, device); - - if (device->is_disabled) - device->is_disabled = false; - else - status = hifDisableFunc(device, func); - - CleanupHIFScatterResources(device); - - delHifDevice(device); -} - -#if defined(CONFIG_PM) -static int ath6kl_hifdev_suspend(struct device *dev) -{ - struct sdio_func *func = dev_to_sdio_func(dev); - int status = 0; - struct hif_device *device; - - device = ath6kl_get_hifdev(func); - - if (device && device->claimedContext && - osdrvCallbacks.deviceSuspendHandler) { - /* set true first for PowerStateChangeNotify(..) */ - device->is_suspend = true; - status = osdrvCallbacks. - deviceSuspendHandler(device->claimedContext); - if (status) - device->is_suspend = false; - } - - CleanupHIFScatterResources(device); - - switch (status) { - case 0: - return 0; - case A_EBUSY: - /* Hack for kernel in order to support deep sleep and wow */ - return -EBUSY; - default: - return -1; - } -} - -static int ath6kl_hifdev_resume(struct device *dev) -{ - struct sdio_func *func = dev_to_sdio_func(dev); - int status = 0; - struct hif_device *device; - - device = ath6kl_get_hifdev(func); - if (device && device->claimedContext && - osdrvCallbacks.deviceSuspendHandler) { - status = osdrvCallbacks. - deviceResumeHandler(device->claimedContext); - if (status == 0) - device->is_suspend = false; - } - - return status; -} - -static const struct dev_pm_ops ath6kl_hifdev_pmops = { - .suspend = ath6kl_hifdev_suspend, - .resume = ath6kl_hifdev_resume, -}; -#endif /* CONFIG_PM */ - -static struct sdio_driver ath6kl_hifdev_driver = { - .name = "ath6kl_hifdev", - .id_table = ath6kl_hifdev_ids, - .probe = ath6kl_hifdev_probe, - .remove = ath6kl_hifdev_remove, -#if defined(CONFIG_PM) - .drv = { - .pm = &ath6kl_hifdev_pmops, - }, -#endif -}; - -/* make sure we only unregister when registered. */ -static int registered = 0; - -extern u32 onebitmode; -extern u32 busspeedlow; -extern u32 debughif; - -static void ResetAllCards(void); - -#ifdef DEBUG - -ATH_DEBUG_INSTANTIATE_MODULE_VAR(hif, - "hif", - "(Linux MMC) Host Interconnect Framework", - ATH_DEBUG_MASK_DEFAULTS, - 0, - NULL); - -#endif - - -/* ------ Functions ------ */ -int HIFInit(OSDRV_CALLBACKS *callbacks) -{ - int r; - AR_DEBUG_ASSERT(callbacks != NULL); - - A_REGISTER_MODULE_DEBUG_INFO(hif); - - /* store the callback handlers */ - osdrvCallbacks = *callbacks; - - /* Register with bus driver core */ - registered = 1; - - r = sdio_register_driver(&ath6kl_hifdev_driver); - if (r < 0) - return r; - - return 0; -} - -static int -__HIFReadWrite(struct hif_device *device, - u32 address, - u8 *buffer, - u32 length, - u32 request, - void *context) -{ - u8 opcode; - int status = 0; - int ret; - u8 *tbuffer; - bool bounced = false; - - AR_DEBUG_ASSERT(device != NULL); - AR_DEBUG_ASSERT(device->func != NULL); - - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device: 0x%p, buffer:0x%p (addr:0x%X)\n", - device, buffer, address)); - - do { - if (request & HIF_EXTENDED_IO) { - //AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Command type: CMD53\n")); - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, - ("AR6000: Invalid command type: 0x%08x\n", request)); - status = A_EINVAL; - break; - } - - if (request & HIF_BLOCK_BASIS) { - /* round to whole block length size */ - length = (length / HIF_MBOX_BLOCK_SIZE) * HIF_MBOX_BLOCK_SIZE; - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, - ("AR6000: Block mode (BlockLen: %d)\n", - length)); - } else if (request & HIF_BYTE_BASIS) { - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, - ("AR6000: Byte mode (BlockLen: %d)\n", - length)); - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, - ("AR6000: Invalid data mode: 0x%08x\n", request)); - status = A_EINVAL; - break; - } - -#if 0 - /* useful for checking register accesses */ - if (length & 0x3) { - A_PRINTF(KERN_ALERT"AR6000: HIF (%s) is not a multiple of 4 bytes, addr:0x%X, len:%d\n", - request & HIF_WRITE ? "write":"read", address, length); - } -#endif - - if (request & HIF_WRITE) { - if ((address >= HIF_MBOX_START_ADDR(0)) && - (address <= HIF_MBOX_END_ADDR(3))) - { - - AR_DEBUG_ASSERT(length <= HIF_MBOX_WIDTH); - - /* - * Mailbox write. Adjust the address so that the last byte - * falls on the EOM address. - */ - address += (HIF_MBOX_WIDTH - length); - } - } - - if (request & HIF_FIXED_ADDRESS) { - opcode = CMD53_FIXED_ADDRESS; - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Address mode: Fixed 0x%X\n", address)); - } else if (request & HIF_INCREMENTAL_ADDRESS) { - opcode = CMD53_INCR_ADDRESS; - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Address mode: Incremental 0x%X\n", address)); - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, - ("AR6000: Invalid address mode: 0x%08x\n", request)); - status = A_EINVAL; - break; - } - - if (request & HIF_WRITE) { -#if HIF_USE_DMA_BOUNCE_BUFFER - if (BUFFER_NEEDS_BOUNCE(buffer)) { - AR_DEBUG_ASSERT(device->dma_buffer != NULL); - tbuffer = device->dma_buffer; - /* copy the write data to the dma buffer */ - AR_DEBUG_ASSERT(length <= HIF_DMA_BUFFER_SIZE); - memcpy(tbuffer, buffer, length); - bounced = true; - } else { - tbuffer = buffer; - } -#else - tbuffer = buffer; -#endif - if (opcode == CMD53_FIXED_ADDRESS) { - ret = sdio_writesb(device->func, address, tbuffer, length); - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: writesb ret=%d address: 0x%X, len: %d, 0x%X\n", - ret, address, length, *(int *)tbuffer)); - } else { - ret = sdio_memcpy_toio(device->func, address, tbuffer, length); - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: writeio ret=%d address: 0x%X, len: %d, 0x%X\n", - ret, address, length, *(int *)tbuffer)); - } - } else if (request & HIF_READ) { -#if HIF_USE_DMA_BOUNCE_BUFFER - if (BUFFER_NEEDS_BOUNCE(buffer)) { - AR_DEBUG_ASSERT(device->dma_buffer != NULL); - AR_DEBUG_ASSERT(length <= HIF_DMA_BUFFER_SIZE); - tbuffer = device->dma_buffer; - bounced = true; - } else { - tbuffer = buffer; - } -#else - tbuffer = buffer; -#endif - if (opcode == CMD53_FIXED_ADDRESS) { - ret = sdio_readsb(device->func, tbuffer, address, length); - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: readsb ret=%d address: 0x%X, len: %d, 0x%X\n", - ret, address, length, *(int *)tbuffer)); - } else { - ret = sdio_memcpy_fromio(device->func, tbuffer, address, length); - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: readio ret=%d address: 0x%X, len: %d, 0x%X\n", - ret, address, length, *(int *)tbuffer)); - } -#if HIF_USE_DMA_BOUNCE_BUFFER - if (bounced) { - /* copy the read data from the dma buffer */ - memcpy(buffer, tbuffer, length); - } -#endif - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, - ("AR6000: Invalid direction: 0x%08x\n", request)); - status = A_EINVAL; - break; - } - - if (ret) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, - ("AR6000: SDIO bus operation failed! MMC stack returned : %d \n", ret)); - status = A_ERROR; - } - } while (false); - - return status; -} - -void AddToAsyncList(struct hif_device *device, BUS_REQUEST *busrequest) -{ - unsigned long flags; - BUS_REQUEST *async; - BUS_REQUEST *active; - - spin_lock_irqsave(&device->asynclock, flags); - active = device->asyncreq; - if (active == NULL) { - device->asyncreq = busrequest; - device->asyncreq->inusenext = NULL; - } else { - for (async = device->asyncreq; - async != NULL; - async = async->inusenext) { - active = async; - } - active->inusenext = busrequest; - busrequest->inusenext = NULL; - } - spin_unlock_irqrestore(&device->asynclock, flags); -} - - -/* queue a read/write request */ -int -HIFReadWrite(struct hif_device *device, - u32 address, - u8 *buffer, - u32 length, - u32 request, - void *context) -{ - int status = 0; - BUS_REQUEST *busrequest; - - - AR_DEBUG_ASSERT(device != NULL); - AR_DEBUG_ASSERT(device->func != NULL); - - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device: %p addr:0x%X\n", device,address)); - - do { - if ((request & HIF_ASYNCHRONOUS) || (request & HIF_SYNCHRONOUS)){ - /* serialize all requests through the async thread */ - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Execution mode: %s\n", - (request & HIF_ASYNCHRONOUS)?"Async":"Synch")); - busrequest = hifAllocateBusRequest(device); - if (busrequest == NULL) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, - ("AR6000: no async bus requests available (%s, addr:0x%X, len:%d) \n", - request & HIF_READ ? "READ":"WRITE", address, length)); - return A_ERROR; - } - busrequest->address = address; - busrequest->buffer = buffer; - busrequest->length = length; - busrequest->request = request; - busrequest->context = context; - - AddToAsyncList(device, busrequest); - - if (request & HIF_SYNCHRONOUS) { - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: queued sync req: 0x%lX\n", (unsigned long)busrequest)); - - /* wait for completion */ - up(&device->sem_async); - if (down_interruptible(&busrequest->sem_req) != 0) { - /* interrupted, exit */ - return A_ERROR; - } else { - int status = busrequest->status; - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: sync return freeing 0x%lX: 0x%X\n", - (unsigned long)busrequest, busrequest->status)); - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: freeing req: 0x%X\n", (unsigned int)request)); - hifFreeBusRequest(device, busrequest); - return status; - } - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: queued async req: 0x%lX\n", (unsigned long)busrequest)); - up(&device->sem_async); - return A_PENDING; - } - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, - ("AR6000: Invalid execution mode: 0x%08x\n", (unsigned int)request)); - status = A_EINVAL; - break; - } - } while(0); - - return status; -} -/* thread to serialize all requests, both sync and async */ -static int async_task(void *param) - { - struct hif_device *device; - BUS_REQUEST *request; - int status; - unsigned long flags; - - device = (struct hif_device *)param; - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async task\n")); - set_current_state(TASK_INTERRUPTIBLE); - while(!device->async_shutdown) { - /* wait for work */ - if (down_interruptible(&device->sem_async) != 0) { - /* interrupted, exit */ - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async task interrupted\n")); - break; - } - if (device->async_shutdown) { - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async task stopping\n")); - break; - } - /* we want to hold the host over multiple cmds if possible, but holding the host blocks card interrupts */ - sdio_claim_host(device->func); - spin_lock_irqsave(&device->asynclock, flags); - /* pull the request to work on */ - while (device->asyncreq != NULL) { - request = device->asyncreq; - if (request->inusenext != NULL) { - device->asyncreq = request->inusenext; - } else { - device->asyncreq = NULL; - } - spin_unlock_irqrestore(&device->asynclock, flags); - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task processing req: 0x%lX\n", (unsigned long)request)); - - if (request->pScatterReq != NULL) { - A_ASSERT(device->scatter_enabled); - /* this is a queued scatter request, pass the request to scatter routine which - * executes it synchronously, note, no need to free the request since scatter requests - * are maintained on a separate list */ - status = DoHifReadWriteScatter(device,request); - } else { - /* call HIFReadWrite in sync mode to do the work */ - status = __HIFReadWrite(device, request->address, request->buffer, - request->length, request->request & ~HIF_SYNCHRONOUS, NULL); - if (request->request & HIF_ASYNCHRONOUS) { - void *context = request->context; - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task freeing req: 0x%lX\n", (unsigned long)request)); - hifFreeBusRequest(device, request); - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task completion routine req: 0x%lX\n", (unsigned long)request)); - device->htcCallbacks.rwCompletionHandler(context, status); - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: async_task upping req: 0x%lX\n", (unsigned long)request)); - request->status = status; - up(&request->sem_req); - } - } - spin_lock_irqsave(&device->asynclock, flags); - } - spin_unlock_irqrestore(&device->asynclock, flags); - sdio_release_host(device->func); - } - - complete_and_exit(&device->async_completion, 0); - return 0; -} - -static s32 IssueSDCommand(struct hif_device *device, u32 opcode, u32 arg, u32 flags, u32 *resp) -{ - struct mmc_command cmd; - s32 err; - struct mmc_host *host; - struct sdio_func *func; - - func = device->func; - host = func->card->host; - - memset(&cmd, 0, sizeof(struct mmc_command)); - cmd.opcode = opcode; - cmd.arg = arg; - cmd.flags = flags; - err = mmc_wait_for_cmd(host, &cmd, 3); - - if ((!err) && (resp)) { - *resp = cmd.resp[0]; - } - - return err; -} - -int ReinitSDIO(struct hif_device *device) -{ - s32 err; - struct mmc_host *host; - struct mmc_card *card; - struct sdio_func *func; - u8 cmd52_resp; - u32 clock; - - func = device->func; - card = func->card; - host = card->host; - - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +ReinitSDIO \n")); - sdio_claim_host(func); - - do { - if (!device->is_suspend) { - u32 resp; - u16 rca; - u32 i; - int bit = fls(host->ocr_avail) - 1; - /* emulate the mmc_power_up(...) */ - host->ios.vdd = bit; - host->ios.chip_select = MMC_CS_DONTCARE; - host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; - host->ios.power_mode = MMC_POWER_UP; - host->ios.bus_width = MMC_BUS_WIDTH_1; - host->ios.timing = MMC_TIMING_LEGACY; - host->ops->set_ios(host, &host->ios); - /* - * This delay should be sufficient to allow the power supply - * to reach the minimum voltage. - */ - msleep(2); - - host->ios.clock = host->f_min; - host->ios.power_mode = MMC_POWER_ON; - host->ops->set_ios(host, &host->ios); - - /* - * This delay must be at least 74 clock sizes, or 1 ms, or the - * time required to reach a stable voltage. - */ - msleep(2); - - /* Issue CMD0. Goto idle state */ - host->ios.chip_select = MMC_CS_HIGH; - host->ops->set_ios(host, &host->ios); - msleep(1); - err = IssueSDCommand(device, MMC_GO_IDLE_STATE, 0, (MMC_RSP_NONE | MMC_CMD_BC), NULL); - host->ios.chip_select = MMC_CS_DONTCARE; - host->ops->set_ios(host, &host->ios); - msleep(1); - host->use_spi_crc = 0; - - if (err) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD0 failed : %d \n",err)); - break; - } - - if (!host->ocr) { - /* Issue CMD5, arg = 0 */ - err = IssueSDCommand(device, SD_IO_SEND_OP_COND, 0, (MMC_RSP_R4 | MMC_CMD_BCR), &resp); - if (err) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD5 failed : %d \n",err)); - break; - } - host->ocr = resp; - } - - /* Issue CMD5, arg = ocr. Wait till card is ready */ - for (i=0;i<100;i++) { - err = IssueSDCommand(device, SD_IO_SEND_OP_COND, host->ocr, (MMC_RSP_R4 | MMC_CMD_BCR), &resp); - if (err) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD5 failed : %d \n",err)); - break; - } - if (resp & MMC_CARD_BUSY) { - break; - } - msleep(10); - } - - if ((i == 100) || (err)) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: card in not ready : %d %d \n",i,err)); - break; - } - - /* Issue CMD3, get RCA */ - err = IssueSDCommand(device, SD_SEND_RELATIVE_ADDR, 0, MMC_RSP_R6 | MMC_CMD_BCR, &resp); - if (err) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD3 failed : %d \n",err)); - break; - } - rca = resp >> 16; - host->ios.bus_mode = MMC_BUSMODE_PUSHPULL; - host->ops->set_ios(host, &host->ios); - - /* Issue CMD7, select card */ - err = IssueSDCommand(device, MMC_SELECT_CARD, (rca << 16), MMC_RSP_R1 | MMC_CMD_AC, NULL); - if (err) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD7 failed : %d \n",err)); - break; - } - } - - /* Enable high speed */ - if (card->host->caps & MMC_CAP_SD_HIGHSPEED) { - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("ReinitSDIO: Set high speed mode\n")); - err = Func0_CMD52ReadByte(card, SDIO_CCCR_SPEED, &cmd52_resp); - if (err) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD52 read to CCCR speed register failed : %d \n",err)); - card->state &= ~MMC_STATE_HIGHSPEED; - /* no need to break */ - } else { - err = Func0_CMD52WriteByte(card, SDIO_CCCR_SPEED, (cmd52_resp | SDIO_SPEED_EHS)); - if (err) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD52 write to CCCR speed register failed : %d \n",err)); - break; - } - mmc_card_set_highspeed(card); - host->ios.timing = MMC_TIMING_SD_HS; - host->ops->set_ios(host, &host->ios); - } - } - - /* Set clock */ - if (mmc_card_highspeed(card)) { - clock = 50000000; - } else { - clock = card->cis.max_dtr; - } - - if (clock > host->f_max) { - clock = host->f_max; - } - host->ios.clock = clock; - host->ops->set_ios(host, &host->ios); - - - if (card->host->caps & MMC_CAP_4_BIT_DATA) { - /* CMD52: Set bus width & disable card detect resistor */ - err = Func0_CMD52WriteByte(card, SDIO_CCCR_IF, SDIO_BUS_CD_DISABLE | SDIO_BUS_WIDTH_4BIT); - if (err) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("ReinitSDIO: CMD52 to set bus mode failed : %d \n",err)); - break; - } - host->ios.bus_width = MMC_BUS_WIDTH_4; - host->ops->set_ios(host, &host->ios); - } - } while (0); - - sdio_release_host(func); - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -ReinitSDIO \n")); - - return (err) ? A_ERROR : 0; -} - -int -PowerStateChangeNotify(struct hif_device *device, HIF_DEVICE_POWER_CHANGE_TYPE config) -{ - int status = 0; -#if defined(CONFIG_PM) - struct sdio_func *func = device->func; - int old_reset_val; - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +PowerStateChangeNotify %d\n", config)); - switch (config) { - case HIF_DEVICE_POWER_DOWN: - case HIF_DEVICE_POWER_CUT: - old_reset_val = reset_sdio_on_unload; - reset_sdio_on_unload = 1; - status = hifDisableFunc(device, func); - reset_sdio_on_unload = old_reset_val; - if (!device->is_suspend) { - struct mmc_host *host = func->card->host; - host->ios.clock = 0; - host->ios.vdd = 0; - host->ios.bus_mode = MMC_BUSMODE_OPENDRAIN; - host->ios.chip_select = MMC_CS_DONTCARE; - host->ios.power_mode = MMC_POWER_OFF; - host->ios.bus_width = MMC_BUS_WIDTH_1; - host->ios.timing = MMC_TIMING_LEGACY; - host->ops->set_ios(host, &host->ios); - } - break; - case HIF_DEVICE_POWER_UP: - if (device->powerConfig == HIF_DEVICE_POWER_CUT) { - status = ReinitSDIO(device); - } - if (status == 0) { - status = hifEnableFunc(device, func); - } - break; - } - device->powerConfig = config; - - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -PowerStateChangeNotify\n")); -#endif - return status; -} - -int -HIFConfigureDevice(struct hif_device *device, HIF_DEVICE_CONFIG_OPCODE opcode, - void *config, u32 configLen) -{ - u32 count; - int status = 0; - - switch(opcode) { - case HIF_DEVICE_GET_MBOX_BLOCK_SIZE: - ((u32 *)config)[0] = HIF_MBOX0_BLOCK_SIZE; - ((u32 *)config)[1] = HIF_MBOX1_BLOCK_SIZE; - ((u32 *)config)[2] = HIF_MBOX2_BLOCK_SIZE; - ((u32 *)config)[3] = HIF_MBOX3_BLOCK_SIZE; - break; - - case HIF_DEVICE_GET_MBOX_ADDR: - for (count = 0; count < 4; count ++) { - ((u32 *)config)[count] = HIF_MBOX_START_ADDR(count); - } - - if (configLen >= sizeof(struct hif_device_mbox_info)) { - SetExtendedMboxWindowInfo((u16)device->func->device, - (struct hif_device_mbox_info *)config); - } - - break; - case HIF_DEVICE_GET_IRQ_PROC_MODE: - *((HIF_DEVICE_IRQ_PROCESSING_MODE *)config) = HIF_DEVICE_IRQ_SYNC_ONLY; - break; - case HIF_CONFIGURE_QUERY_SCATTER_REQUEST_SUPPORT: - if (!device->scatter_enabled) { - return A_ENOTSUP; - } - status = SetupHIFScatterSupport(device, (struct hif_device_scatter_support_info *)config); - if (status) { - device->scatter_enabled = false; - } - break; - case HIF_DEVICE_GET_OS_DEVICE: - /* pass back a pointer to the SDIO function's "dev" struct */ - ((struct hif_device_os_device_info *)config)->pOSDevice = &device->func->dev; - break; - case HIF_DEVICE_POWER_STATE_CHANGE: - status = PowerStateChangeNotify(device, *(HIF_DEVICE_POWER_CHANGE_TYPE *)config); - break; - default: - AR_DEBUG_PRINTF(ATH_DEBUG_WARN, - ("AR6000: Unsupported configuration opcode: %d\n", opcode)); - status = A_ERROR; - } - - return status; -} - -void -HIFShutDownDevice(struct hif_device *device) -{ - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +HIFShutDownDevice\n")); - if (device != NULL) { - AR_DEBUG_ASSERT(device->func != NULL); - } else { - /* since we are unloading the driver anyways, reset all cards in case the SDIO card - * is externally powered and we are unloading the SDIO stack. This avoids the problem when - * the SDIO stack is reloaded and attempts are made to re-enumerate a card that is already - * enumerated */ - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: HIFShutDownDevice, resetting\n")); - ResetAllCards(); - - /* Unregister with bus driver core */ - if (registered) { - registered = 0; - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, - ("AR6000: Unregistering with the bus driver\n")); - sdio_unregister_driver(&ath6kl_hifdev_driver); - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, - ("AR6000: Unregistered\n")); - } - } - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -HIFShutDownDevice\n")); -} - -static void -hifIRQHandler(struct sdio_func *func) -{ - int status; - struct hif_device *device; - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifIRQHandler\n")); - - device = ath6kl_get_hifdev(func); - atomic_set(&device->irqHandling, 1); - /* release the host during ints so we can pick it back up when we process cmds */ - sdio_release_host(device->func); - status = device->htcCallbacks.dsrHandler(device->htcCallbacks.context); - sdio_claim_host(device->func); - atomic_set(&device->irqHandling, 0); - AR_DEBUG_ASSERT(status == 0 || status == A_ECANCELED); - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifIRQHandler\n")); -} - -/* handle HTC startup via thread*/ -static int startup_task(void *param) -{ - struct hif_device *device; - - device = (struct hif_device *)param; - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: call HTC from startup_task\n")); - /* start up inform DRV layer */ - if ((osdrvCallbacks.deviceInsertedHandler(osdrvCallbacks.context,device)) != 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device rejected\n")); - } - return 0; -} - -#if defined(CONFIG_PM) -static int enable_task(void *param) -{ - struct hif_device *device; - device = (struct hif_device *)param; - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: call from resume_task\n")); - - /* start up inform DRV layer */ - if (device && - device->claimedContext && - osdrvCallbacks.devicePowerChangeHandler && - osdrvCallbacks.devicePowerChangeHandler(device->claimedContext, HIF_DEVICE_POWER_UP) != 0) - { - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: Device rejected\n")); - } - - return 0; -} -#endif - -void -HIFAckInterrupt(struct hif_device *device) -{ - AR_DEBUG_ASSERT(device != NULL); - - /* Acknowledge our function IRQ */ -} - -void -HIFUnMaskInterrupt(struct hif_device *device) -{ - int ret; - - AR_DEBUG_ASSERT(device != NULL); - AR_DEBUG_ASSERT(device->func != NULL); - - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: HIFUnMaskInterrupt\n")); - - /* Register the IRQ Handler */ - sdio_claim_host(device->func); - ret = sdio_claim_irq(device->func, hifIRQHandler); - sdio_release_host(device->func); - AR_DEBUG_ASSERT(ret == 0); -} - -void HIFMaskInterrupt(struct hif_device *device) -{ - int ret; - AR_DEBUG_ASSERT(device != NULL); - AR_DEBUG_ASSERT(device->func != NULL); - - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: HIFMaskInterrupt\n")); - - /* Mask our function IRQ */ - sdio_claim_host(device->func); - while (atomic_read(&device->irqHandling)) { - sdio_release_host(device->func); - schedule_timeout(HZ/10); - sdio_claim_host(device->func); - } - ret = sdio_release_irq(device->func); - sdio_release_host(device->func); - AR_DEBUG_ASSERT(ret == 0); -} - -BUS_REQUEST *hifAllocateBusRequest(struct hif_device *device) -{ - BUS_REQUEST *busrequest; - unsigned long flag; - - /* Acquire lock */ - spin_lock_irqsave(&device->lock, flag); - - /* Remove first in list */ - if((busrequest = device->s_busRequestFreeQueue) != NULL) - { - device->s_busRequestFreeQueue = busrequest->next; - } - /* Release lock */ - spin_unlock_irqrestore(&device->lock, flag); - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: hifAllocateBusRequest: 0x%p\n", busrequest)); - return busrequest; -} - -void -hifFreeBusRequest(struct hif_device *device, BUS_REQUEST *busrequest) -{ - unsigned long flag; - - AR_DEBUG_ASSERT(busrequest != NULL); - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: hifFreeBusRequest: 0x%p\n", busrequest)); - /* Acquire lock */ - spin_lock_irqsave(&device->lock, flag); - - - /* Insert first in list */ - busrequest->next = device->s_busRequestFreeQueue; - busrequest->inusenext = NULL; - device->s_busRequestFreeQueue = busrequest; - - /* Release lock */ - spin_unlock_irqrestore(&device->lock, flag); -} - -static int hifDisableFunc(struct hif_device *device, struct sdio_func *func) -{ - int ret; - int status = 0; - - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifDisableFunc\n")); - device = ath6kl_get_hifdev(func); - if (!IS_ERR(device->async_task)) { - init_completion(&device->async_completion); - device->async_shutdown = 1; - up(&device->sem_async); - wait_for_completion(&device->async_completion); - device->async_task = NULL; - } - /* Disable the card */ - sdio_claim_host(device->func); - ret = sdio_disable_func(device->func); - if (ret) { - status = A_ERROR; - } - - if (reset_sdio_on_unload) { - /* reset the SDIO interface. This is useful in automated testing where the card - * does not need to be removed at the end of the test. It is expected that the user will - * also unload/reload the host controller driver to force the bus driver to re-enumerate the slot */ - AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("AR6000: reseting SDIO card back to uninitialized state \n")); - - /* NOTE : sdio_f0_writeb() cannot be used here, that API only allows access - * to undefined registers in the range of: 0xF0-0xFF */ - - ret = Func0_CMD52WriteByte(device->func->card, SDIO_CCCR_ABORT, (1 << 3)); - if (ret) { - status = A_ERROR; - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR6000: reset failed : %d \n",ret)); - } - } - - sdio_release_host(device->func); - - if (status == 0) { - device->is_disabled = true; - } - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifDisableFunc\n")); - - return status; -} - -static int hifEnableFunc(struct hif_device *device, struct sdio_func *func) -{ - struct task_struct* pTask; - const char *taskName = NULL; - int (*taskFunc)(void *) = NULL; - int ret = 0; - - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: +hifEnableFunc\n")); - device = ath6kl_get_hifdev(func); - - if (device->is_disabled) { - /* enable the SDIO function */ - sdio_claim_host(func); - - if ((device->id->device & MANUFACTURER_ID_AR6K_BASE_MASK) >= MANUFACTURER_ID_AR6003_BASE) { - /* enable 4-bit ASYNC interrupt on AR6003 or later devices */ - ret = Func0_CMD52WriteByte(func->card, CCCR_SDIO_IRQ_MODE_REG, SDIO_IRQ_MODE_ASYNC_4BIT_IRQ); - if (ret) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR6000: failed to enable 4-bit ASYNC IRQ mode %d \n",ret)); - sdio_release_host(func); - return ret; - } - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: 4-bit ASYNC IRQ mode enabled\n")); - } - /* give us some time to enable, in ms */ - func->enable_timeout = 100; - ret = sdio_enable_func(func); - if (ret) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable to enable AR6K: 0x%X\n", - __FUNCTION__, ret)); - sdio_release_host(func); - return ret; - } - ret = sdio_set_block_size(func, HIF_MBOX_BLOCK_SIZE); - sdio_release_host(func); - if (ret) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), Unable to set block size 0x%x AR6K: 0x%X\n", - __FUNCTION__, HIF_MBOX_BLOCK_SIZE, ret)); - return ret; - } - device->is_disabled = false; - /* create async I/O thread */ - if (!device->async_task) { - device->async_shutdown = 0; - device->async_task = kthread_create(async_task, - (void *)device, - "AR6K Async"); - if (IS_ERR(device->async_task)) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create async task\n", __FUNCTION__)); - return -ENOMEM; - } - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: start async task\n")); - wake_up_process(device->async_task ); - } - } - - if (!device->claimedContext) { - taskFunc = startup_task; - taskName = "AR6K startup"; - ret = 0; -#if defined(CONFIG_PM) - } else { - taskFunc = enable_task; - taskName = "AR6K enable"; - ret = -ENOMEM; -#endif /* CONFIG_PM */ - } - /* create resume thread */ - pTask = kthread_create(taskFunc, (void *)device, taskName); - if (IS_ERR(pTask)) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("AR6000: %s(), to create enabel task\n", __FUNCTION__)); - return -ENOMEM; - } - wake_up_process(pTask); - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: -hifEnableFunc\n")); - - /* task will call the enable func, indicate pending */ - return ret; -} - -/* - * This should be moved to AR6K HTC layer. - */ -int hifWaitForPendingRecv(struct hif_device *device) -{ - s32 cnt = 10; - u8 host_int_status; - int status = 0; - - do { - while (atomic_read(&device->irqHandling)) { - /* wait until irq handler finished all the jobs */ - schedule_timeout(HZ/10); - } - /* check if there is any pending irq due to force done */ - host_int_status = 0; - status = HIFReadWrite(device, HOST_INT_STATUS_ADDRESS, - (u8 *)&host_int_status, sizeof(host_int_status), - HIF_RD_SYNC_BYTE_INC, NULL); - host_int_status = !status ? (host_int_status & (1 << 0)) : 0; - if (host_int_status) { - schedule(); /* schedule for next dsrHandler */ - } - } while (host_int_status && --cnt > 0); - - if (host_int_status && cnt == 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, - ("AR6000: %s(), Unable clear up pending IRQ before the system suspended\n", __FUNCTION__)); - } - - return 0; -} - -static void -delHifDevice(struct hif_device * device) -{ - AR_DEBUG_ASSERT(device!= NULL); - AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: delHifDevice; 0x%p\n", device)); - kfree(device->dma_buffer); - kfree(device); -} - -static void ResetAllCards(void) -{ -} - -void HIFClaimDevice(struct hif_device *device, void *context) -{ - device->claimedContext = context; -} - -void HIFReleaseDevice(struct hif_device *device) -{ - device->claimedContext = NULL; -} - -int HIFAttachHTC(struct hif_device *device, HTC_CALLBACKS *callbacks) -{ - if (device->htcCallbacks.context != NULL) { - /* already in use! */ - return A_ERROR; - } - device->htcCallbacks = *callbacks; - return 0; -} - -void HIFDetachHTC(struct hif_device *device) -{ - A_MEMZERO(&device->htcCallbacks,sizeof(device->htcCallbacks)); -} - -#define SDIO_SET_CMD52_ARG(arg,rw,func,raw,address,writedata) \ - (arg) = (((rw) & 1) << 31) | \ - (((func) & 0x7) << 28) | \ - (((raw) & 1) << 27) | \ - (1 << 26) | \ - (((address) & 0x1FFFF) << 9) | \ - (1 << 8) | \ - ((writedata) & 0xFF) - -#define SDIO_SET_CMD52_READ_ARG(arg,func,address) \ - SDIO_SET_CMD52_ARG(arg,0,(func),0,address,0x00) -#define SDIO_SET_CMD52_WRITE_ARG(arg,func,address,value) \ - SDIO_SET_CMD52_ARG(arg,1,(func),0,address,value) - -static int Func0_CMD52WriteByte(struct mmc_card *card, unsigned int address, unsigned char byte) -{ - struct mmc_command ioCmd; - unsigned long arg; - - memset(&ioCmd,0,sizeof(ioCmd)); - SDIO_SET_CMD52_WRITE_ARG(arg,0,address,byte); - ioCmd.opcode = SD_IO_RW_DIRECT; - ioCmd.arg = arg; - ioCmd.flags = MMC_RSP_R5 | MMC_CMD_AC; - - return mmc_wait_for_cmd(card->host, &ioCmd, 0); -} - -static int Func0_CMD52ReadByte(struct mmc_card *card, unsigned int address, unsigned char *byte) -{ - struct mmc_command ioCmd; - unsigned long arg; - s32 err; - - memset(&ioCmd,0,sizeof(ioCmd)); - SDIO_SET_CMD52_READ_ARG(arg,0,address); - ioCmd.opcode = SD_IO_RW_DIRECT; - ioCmd.arg = arg; - ioCmd.flags = MMC_RSP_R5 | MMC_CMD_AC; - - err = mmc_wait_for_cmd(card->host, &ioCmd, 0); - - if ((!err) && (byte)) { - *byte = ioCmd.resp[0] & 0xFF; - } - - return err; -} diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c deleted file mode 100644 index 7516d91..0000000 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif_scatter.c +++ /dev/null @@ -1,393 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// HIF scatter implementation -// -// Author(s): ="Atheros" -//============================================================================== - -#include <linux/mmc/card.h> -#include <linux/mmc/host.h> -#include <linux/mmc/sdio_func.h> -#include <linux/mmc/sdio_ids.h> -#include <linux/mmc/sdio.h> -#include <linux/kthread.h> -#include "hif_internal.h" -#define ATH_MODULE_NAME hif -#include "a_debug.h" - -#ifdef HIF_LINUX_MMC_SCATTER_SUPPORT - -#define _CMD53_ARG_READ 0 -#define _CMD53_ARG_WRITE 1 -#define _CMD53_ARG_BLOCK_BASIS 1 -#define _CMD53_ARG_FIXED_ADDRESS 0 -#define _CMD53_ARG_INCR_ADDRESS 1 - -#define SDIO_SET_CMD53_ARG(arg,rw,func,mode,opcode,address,bytes_blocks) \ - (arg) = (((rw) & 1) << 31) | \ - (((func) & 0x7) << 28) | \ - (((mode) & 1) << 27) | \ - (((opcode) & 1) << 26) | \ - (((address) & 0x1FFFF) << 9) | \ - ((bytes_blocks) & 0x1FF) - -static void FreeScatterReq(struct hif_device *device, struct hif_scatter_req *pReq) -{ - unsigned long flag; - - spin_lock_irqsave(&device->lock, flag); - - DL_ListInsertTail(&device->ScatterReqHead, &pReq->ListLink); - - spin_unlock_irqrestore(&device->lock, flag); - -} - -static struct hif_scatter_req *AllocScatterReq(struct hif_device *device) -{ - struct dl_list *pItem; - unsigned long flag; - - spin_lock_irqsave(&device->lock, flag); - - pItem = DL_ListRemoveItemFromHead(&device->ScatterReqHead); - - spin_unlock_irqrestore(&device->lock, flag); - - if (pItem != NULL) { - return A_CONTAINING_STRUCT(pItem, struct hif_scatter_req, ListLink); - } - - return NULL; -} - - /* called by async task to perform the operation synchronously using direct MMC APIs */ -int DoHifReadWriteScatter(struct hif_device *device, BUS_REQUEST *busrequest) -{ - int i; - u8 rw; - u8 opcode; - struct mmc_request mmcreq; - struct mmc_command cmd; - struct mmc_data data; - struct hif_scatter_req_priv *pReqPriv; - struct hif_scatter_req *pReq; - int status = 0; - struct scatterlist *pSg; - - pReqPriv = busrequest->pScatterReq; - - A_ASSERT(pReqPriv != NULL); - - pReq = pReqPriv->pHifScatterReq; - - memset(&mmcreq, 0, sizeof(struct mmc_request)); - memset(&cmd, 0, sizeof(struct mmc_command)); - memset(&data, 0, sizeof(struct mmc_data)); - - data.blksz = HIF_MBOX_BLOCK_SIZE; - data.blocks = pReq->TotalLength / HIF_MBOX_BLOCK_SIZE; - - AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER: (%s) Address: 0x%X, (BlockLen: %d, BlockCount: %d) , (tot:%d,sg:%d)\n", - (pReq->Request & HIF_WRITE) ? "WRITE":"READ", pReq->Address, data.blksz, data.blocks, - pReq->TotalLength,pReq->ValidScatterEntries)); - - if (pReq->Request & HIF_WRITE) { - rw = _CMD53_ARG_WRITE; - data.flags = MMC_DATA_WRITE; - } else { - rw = _CMD53_ARG_READ; - data.flags = MMC_DATA_READ; - } - - if (pReq->Request & HIF_FIXED_ADDRESS) { - opcode = _CMD53_ARG_FIXED_ADDRESS; - } else { - opcode = _CMD53_ARG_INCR_ADDRESS; - } - - /* fill SG entries */ - pSg = pReqPriv->sgentries; - sg_init_table(pSg, pReq->ValidScatterEntries); - - /* assemble SG list */ - for (i = 0 ; i < pReq->ValidScatterEntries ; i++, pSg++) { - /* setup each sg entry */ - if ((unsigned long)pReq->ScatterList[i].pBuffer & 0x3) { - /* note some scatter engines can handle unaligned buffers, print this - * as informational only */ - AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, - ("HIF: (%s) Scatter Buffer is unaligned 0x%lx\n", - pReq->Request & HIF_WRITE ? "WRITE":"READ", - (unsigned long)pReq->ScatterList[i].pBuffer)); - } - - AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, (" %d: Addr:0x%lX, Len:%d \n", - i,(unsigned long)pReq->ScatterList[i].pBuffer,pReq->ScatterList[i].Length)); - - sg_set_buf(pSg, pReq->ScatterList[i].pBuffer, pReq->ScatterList[i].Length); - } - /* set scatter-gather table for request */ - data.sg = pReqPriv->sgentries; - data.sg_len = pReq->ValidScatterEntries; - /* set command argument */ - SDIO_SET_CMD53_ARG(cmd.arg, - rw, - device->func->num, - _CMD53_ARG_BLOCK_BASIS, - opcode, - pReq->Address, - data.blocks); - - cmd.opcode = SD_IO_RW_EXTENDED; - cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC; - - mmcreq.cmd = &cmd; - mmcreq.data = &data; - - mmc_set_data_timeout(&data, device->func->card); - /* synchronous call to process request */ - mmc_wait_for_req(device->func->card->host, &mmcreq); - - if (cmd.error) { - status = A_ERROR; - AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("HIF-SCATTER: cmd error: %d \n",cmd.error)); - } - - if (data.error) { - status = A_ERROR; - AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("HIF-SCATTER: data error: %d \n",data.error)); - } - - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, ("HIF-SCATTER: FAILED!!! (%s) Address: 0x%X, Block mode (BlockLen: %d, BlockCount: %d)\n", - (pReq->Request & HIF_WRITE) ? "WRITE":"READ",pReq->Address, data.blksz, data.blocks)); - } - - /* set completion status, fail or success */ - pReq->CompletionStatus = status; - - if (pReq->Request & HIF_ASYNCHRONOUS) { - AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER: async_task completion routine req: 0x%lX (%d)\n",(unsigned long)busrequest, status)); - /* complete the request */ - A_ASSERT(pReq->CompletionRoutine != NULL); - pReq->CompletionRoutine(pReq); - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER async_task upping busrequest : 0x%lX (%d)\n", (unsigned long)busrequest,status)); - /* signal wait */ - up(&busrequest->sem_req); - } - - return status; -} - - /* callback to issue a read-write scatter request */ -static int HifReadWriteScatter(struct hif_device *device, struct hif_scatter_req *pReq) -{ - int status = A_EINVAL; - u32 request = pReq->Request; - struct hif_scatter_req_priv *pReqPriv = (struct hif_scatter_req_priv *)pReq->HIFPrivate[0]; - - do { - - A_ASSERT(pReqPriv != NULL); - - AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER: total len: %d Scatter Entries: %d\n", - pReq->TotalLength, pReq->ValidScatterEntries)); - - if (!(request & HIF_EXTENDED_IO)) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, - ("HIF-SCATTER: Invalid command type: 0x%08x\n", request)); - break; - } - - if (!(request & (HIF_SYNCHRONOUS | HIF_ASYNCHRONOUS))) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, - ("HIF-SCATTER: Invalid execution mode: 0x%08x\n", request)); - break; - } - - if (!(request & HIF_BLOCK_BASIS)) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, - ("HIF-SCATTER: Invalid data mode: 0x%08x\n", request)); - break; - } - - if (pReq->TotalLength > MAX_SCATTER_REQ_TRANSFER_SIZE) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERROR, - ("HIF-SCATTER: Invalid length: %d \n", pReq->TotalLength)); - break; - } - - if (pReq->TotalLength == 0) { - A_ASSERT(false); - break; - } - - /* add bus request to the async list for the async I/O thread to process */ - AddToAsyncList(device, pReqPriv->busrequest); - - if (request & HIF_SYNCHRONOUS) { - AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER: queued sync req: 0x%lX\n", (unsigned long)pReqPriv->busrequest)); - /* signal thread and wait */ - up(&device->sem_async); - if (down_interruptible(&pReqPriv->busrequest->sem_req) != 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERROR,("HIF-SCATTER: interrupted! \n")); - /* interrupted, exit */ - status = A_ERROR; - break; - } else { - status = pReq->CompletionStatus; - } - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_SCATTER, ("HIF-SCATTER: queued async req: 0x%lX\n", (unsigned long)pReqPriv->busrequest)); - /* wake thread, it will process and then take care of the async callback */ - up(&device->sem_async); - status = 0; - } - - } while (false); - - if (status && (request & HIF_ASYNCHRONOUS)) { - pReq->CompletionStatus = status; - pReq->CompletionRoutine(pReq); - status = 0; - } - - return status; -} - - /* setup of HIF scatter resources */ -int SetupHIFScatterSupport(struct hif_device *device, struct hif_device_scatter_support_info *pInfo) -{ - int status = A_ERROR; - int i; - struct hif_scatter_req_priv *pReqPriv; - BUS_REQUEST *busrequest; - - do { - - /* check if host supports scatter requests and it meets our requirements */ - if (device->func->card->host->max_segs < MAX_SCATTER_ENTRIES_PER_REQ) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HIF-SCATTER : host only supports scatter of : %d entries, need: %d \n", - device->func->card->host->max_segs, MAX_SCATTER_ENTRIES_PER_REQ)); - status = A_ENOTSUP; - break; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("HIF-SCATTER Enabled: max scatter req : %d entries: %d \n", - MAX_SCATTER_REQUESTS, MAX_SCATTER_ENTRIES_PER_REQ)); - - for (i = 0; i < MAX_SCATTER_REQUESTS; i++) { - /* allocate the private request blob */ - pReqPriv = (struct hif_scatter_req_priv *)A_MALLOC(sizeof(struct hif_scatter_req_priv)); - if (NULL == pReqPriv) { - break; - } - A_MEMZERO(pReqPriv, sizeof(struct hif_scatter_req_priv)); - /* save the device instance*/ - pReqPriv->device = device; - /* allocate the scatter request */ - pReqPriv->pHifScatterReq = (struct hif_scatter_req *)A_MALLOC(sizeof(struct hif_scatter_req) + - (MAX_SCATTER_ENTRIES_PER_REQ - 1) * (sizeof(struct hif_scatter_item))); - - if (NULL == pReqPriv->pHifScatterReq) { - kfree(pReqPriv); - break; - } - /* just zero the main part of the scatter request */ - A_MEMZERO(pReqPriv->pHifScatterReq, sizeof(struct hif_scatter_req)); - /* back pointer to the private struct */ - pReqPriv->pHifScatterReq->HIFPrivate[0] = pReqPriv; - /* allocate a bus request for this scatter request */ - busrequest = hifAllocateBusRequest(device); - if (NULL == busrequest) { - kfree(pReqPriv->pHifScatterReq); - kfree(pReqPriv); - break; - } - /* assign the scatter request to this bus request */ - busrequest->pScatterReq = pReqPriv; - /* point back to the request */ - pReqPriv->busrequest = busrequest; - /* add it to the scatter pool */ - FreeScatterReq(device,pReqPriv->pHifScatterReq); - } - - if (i != MAX_SCATTER_REQUESTS) { - status = A_NO_MEMORY; - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HIF-SCATTER : failed to alloc scatter resources !\n")); - break; - } - - /* set scatter function pointers */ - pInfo->pAllocateReqFunc = AllocScatterReq; - pInfo->pFreeReqFunc = FreeScatterReq; - pInfo->pReadWriteScatterFunc = HifReadWriteScatter; - pInfo->MaxScatterEntries = MAX_SCATTER_ENTRIES_PER_REQ; - pInfo->MaxTransferSizePerScatterReq = MAX_SCATTER_REQ_TRANSFER_SIZE; - - status = 0; - - } while (false); - - if (status) { - CleanupHIFScatterResources(device); - } - - return status; -} - - /* clean up scatter support */ -void CleanupHIFScatterResources(struct hif_device *device) -{ - struct hif_scatter_req_priv *pReqPriv; - struct hif_scatter_req *pReq; - - /* empty the free list */ - - while (1) { - - pReq = AllocScatterReq(device); - - if (NULL == pReq) { - break; - } - - pReqPriv = (struct hif_scatter_req_priv *)pReq->HIFPrivate[0]; - A_ASSERT(pReqPriv != NULL); - - if (pReqPriv->busrequest != NULL) { - pReqPriv->busrequest->pScatterReq = NULL; - /* free bus request */ - hifFreeBusRequest(device, pReqPriv->busrequest); - pReqPriv->busrequest = NULL; - } - - if (pReqPriv->pHifScatterReq != NULL) { - kfree(pReqPriv->pHifScatterReq); - pReqPriv->pHifScatterReq = NULL; - } - - kfree(pReqPriv); - } -} - -#endif // HIF_LINUX_MMC_SCATTER_SUPPORT diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k.c deleted file mode 100644 index f8607bc..0000000 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.c +++ /dev/null @@ -1,1479 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="ar6k.c" company="Atheros"> -// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// AR6K device layer that handles register level I/O -// -// Author(s): ="Atheros" -//============================================================================== - -#include "a_config.h" -#include "athdefs.h" -#include "hw/mbox_host_reg.h" -#include "a_osapi.h" -#include "../htc_debug.h" -#include "hif.h" -#include "htc_packet.h" -#include "ar6k.h" - -#define MAILBOX_FOR_BLOCK_SIZE 1 - -int DevEnableInterrupts(struct ar6k_device *pDev); -int DevDisableInterrupts(struct ar6k_device *pDev); - -static void DevCleanupVirtualScatterSupport(struct ar6k_device *pDev); - -void AR6KFreeIOPacket(struct ar6k_device *pDev, struct htc_packet *pPacket) -{ - LOCK_AR6K(pDev); - HTC_PACKET_ENQUEUE(&pDev->RegisterIOList,pPacket); - UNLOCK_AR6K(pDev); -} - -struct htc_packet *AR6KAllocIOPacket(struct ar6k_device *pDev) -{ - struct htc_packet *pPacket; - - LOCK_AR6K(pDev); - pPacket = HTC_PACKET_DEQUEUE(&pDev->RegisterIOList); - UNLOCK_AR6K(pDev); - - return pPacket; -} - -void DevCleanup(struct ar6k_device *pDev) -{ - DevCleanupGMbox(pDev); - - if (pDev->HifAttached) { - HIFDetachHTC(pDev->HIFDevice); - pDev->HifAttached = false; - } - - DevCleanupVirtualScatterSupport(pDev); - - if (A_IS_MUTEX_VALID(&pDev->Lock)) { - A_MUTEX_DELETE(&pDev->Lock); - } -} - -int DevSetup(struct ar6k_device *pDev) -{ - u32 blocksizes[AR6K_MAILBOXES]; - int status = 0; - int i; - HTC_CALLBACKS htcCallbacks; - - do { - - DL_LIST_INIT(&pDev->ScatterReqHead); - /* initialize our free list of IO packets */ - INIT_HTC_PACKET_QUEUE(&pDev->RegisterIOList); - A_MUTEX_INIT(&pDev->Lock); - - A_MEMZERO(&htcCallbacks, sizeof(HTC_CALLBACKS)); - /* the device layer handles these */ - htcCallbacks.rwCompletionHandler = DevRWCompletionHandler; - htcCallbacks.dsrHandler = DevDsrHandler; - htcCallbacks.context = pDev; - - status = HIFAttachHTC(pDev->HIFDevice, &htcCallbacks); - - if (status) { - break; - } - - pDev->HifAttached = true; - - /* get the addresses for all 4 mailboxes */ - status = HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_MBOX_ADDR, - &pDev->MailBoxInfo, sizeof(pDev->MailBoxInfo)); - - if (status) { - A_ASSERT(false); - break; - } - - /* carve up register I/O packets (these are for ASYNC register I/O ) */ - for (i = 0; i < AR6K_MAX_REG_IO_BUFFERS; i++) { - struct htc_packet *pIOPacket; - pIOPacket = &pDev->RegIOBuffers[i].HtcPacket; - SET_HTC_PACKET_INFO_RX_REFILL(pIOPacket, - pDev, - pDev->RegIOBuffers[i].Buffer, - AR6K_REG_IO_BUFFER_SIZE, - 0); /* don't care */ - AR6KFreeIOPacket(pDev,pIOPacket); - } - - /* get the block sizes */ - status = HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_MBOX_BLOCK_SIZE, - blocksizes, sizeof(blocksizes)); - - if (status) { - A_ASSERT(false); - break; - } - - /* note: we actually get the block size of a mailbox other than 0, for SDIO the block - * size on mailbox 0 is artificially set to 1. So we use the block size that is set - * for the other 3 mailboxes */ - pDev->BlockSize = blocksizes[MAILBOX_FOR_BLOCK_SIZE]; - /* must be a power of 2 */ - A_ASSERT((pDev->BlockSize & (pDev->BlockSize - 1)) == 0); - - /* assemble mask, used for padding to a block */ - pDev->BlockMask = pDev->BlockSize - 1; - - AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("BlockSize: %d, MailboxAddress:0x%X \n", - pDev->BlockSize, pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX])); - - pDev->GetPendingEventsFunc = NULL; - /* see if the HIF layer implements the get pending events function */ - HIFConfigureDevice(pDev->HIFDevice, - HIF_DEVICE_GET_PENDING_EVENTS_FUNC, - &pDev->GetPendingEventsFunc, - sizeof(pDev->GetPendingEventsFunc)); - - /* assume we can process HIF interrupt events asynchronously */ - pDev->HifIRQProcessingMode = HIF_DEVICE_IRQ_ASYNC_SYNC; - - /* see if the HIF layer overrides this assumption */ - HIFConfigureDevice(pDev->HIFDevice, - HIF_DEVICE_GET_IRQ_PROC_MODE, - &pDev->HifIRQProcessingMode, - sizeof(pDev->HifIRQProcessingMode)); - - switch (pDev->HifIRQProcessingMode) { - case HIF_DEVICE_IRQ_SYNC_ONLY: - AR_DEBUG_PRINTF(ATH_DEBUG_WARN,("HIF Interrupt processing is SYNC ONLY\n")); - /* see if HIF layer wants HTC to yield */ - HIFConfigureDevice(pDev->HIFDevice, - HIF_DEVICE_GET_IRQ_YIELD_PARAMS, - &pDev->HifIRQYieldParams, - sizeof(pDev->HifIRQYieldParams)); - - if (pDev->HifIRQYieldParams.RecvPacketYieldCount > 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_WARN, - ("HIF requests that DSR yield per %d RECV packets \n", - pDev->HifIRQYieldParams.RecvPacketYieldCount)); - pDev->DSRCanYield = true; - } - break; - case HIF_DEVICE_IRQ_ASYNC_SYNC: - AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("HIF Interrupt processing is ASYNC and SYNC\n")); - break; - default: - A_ASSERT(false); - } - - pDev->HifMaskUmaskRecvEvent = NULL; - - /* see if the HIF layer implements the mask/unmask recv events function */ - HIFConfigureDevice(pDev->HIFDevice, - HIF_DEVICE_GET_RECV_EVENT_MASK_UNMASK_FUNC, - &pDev->HifMaskUmaskRecvEvent, - sizeof(pDev->HifMaskUmaskRecvEvent)); - - AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("HIF special overrides : 0x%lX , 0x%lX\n", - (unsigned long)pDev->GetPendingEventsFunc, (unsigned long)pDev->HifMaskUmaskRecvEvent)); - - status = DevDisableInterrupts(pDev); - - if (status) { - break; - } - - status = DevSetupGMbox(pDev); - - } while (false); - - if (status) { - if (pDev->HifAttached) { - HIFDetachHTC(pDev->HIFDevice); - pDev->HifAttached = false; - } - } - - return status; - -} - -int DevEnableInterrupts(struct ar6k_device *pDev) -{ - int status; - struct ar6k_irq_enable_registers regs; - - LOCK_AR6K(pDev); - - /* Enable all the interrupts except for the internal AR6000 CPU interrupt */ - pDev->IrqEnableRegisters.int_status_enable = INT_STATUS_ENABLE_ERROR_SET(0x01) | - INT_STATUS_ENABLE_CPU_SET(0x01) | - INT_STATUS_ENABLE_COUNTER_SET(0x01); - - if (NULL == pDev->GetPendingEventsFunc) { - pDev->IrqEnableRegisters.int_status_enable |= INT_STATUS_ENABLE_MBOX_DATA_SET(0x01); - } else { - /* The HIF layer provided us with a pending events function which means that - * the detection of pending mbox messages is handled in the HIF layer. - * This is the case for the SPI2 interface. - * In the normal case we enable MBOX interrupts, for the case - * with HIFs that offer this mechanism, we keep these interrupts - * masked */ - pDev->IrqEnableRegisters.int_status_enable &= ~INT_STATUS_ENABLE_MBOX_DATA_SET(0x01); - } - - - /* Set up the CPU Interrupt Status Register */ - pDev->IrqEnableRegisters.cpu_int_status_enable = CPU_INT_STATUS_ENABLE_BIT_SET(0x00); - - /* Set up the Error Interrupt Status Register */ - pDev->IrqEnableRegisters.error_status_enable = - ERROR_STATUS_ENABLE_RX_UNDERFLOW_SET(0x01) | - ERROR_STATUS_ENABLE_TX_OVERFLOW_SET(0x01); - - /* Set up the Counter Interrupt Status Register (only for debug interrupt to catch fatal errors) */ - pDev->IrqEnableRegisters.counter_int_status_enable = - COUNTER_INT_STATUS_ENABLE_BIT_SET(AR6K_TARGET_DEBUG_INTR_MASK); - - /* copy into our temp area */ - memcpy(®s,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE); - - UNLOCK_AR6K(pDev); - - /* always synchronous */ - status = HIFReadWrite(pDev->HIFDevice, - INT_STATUS_ENABLE_ADDRESS, - ®s.int_status_enable, - AR6K_IRQ_ENABLE_REGS_SIZE, - HIF_WR_SYNC_BYTE_INC, - NULL); - - if (status) { - /* Can't write it for some reason */ - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("Failed to update interrupt control registers err: %d\n", status)); - - } - - return status; -} - -int DevDisableInterrupts(struct ar6k_device *pDev) -{ - struct ar6k_irq_enable_registers regs; - - LOCK_AR6K(pDev); - /* Disable all interrupts */ - pDev->IrqEnableRegisters.int_status_enable = 0; - pDev->IrqEnableRegisters.cpu_int_status_enable = 0; - pDev->IrqEnableRegisters.error_status_enable = 0; - pDev->IrqEnableRegisters.counter_int_status_enable = 0; - /* copy into our temp area */ - memcpy(®s,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE); - - UNLOCK_AR6K(pDev); - - /* always synchronous */ - return HIFReadWrite(pDev->HIFDevice, - INT_STATUS_ENABLE_ADDRESS, - ®s.int_status_enable, - AR6K_IRQ_ENABLE_REGS_SIZE, - HIF_WR_SYNC_BYTE_INC, - NULL); -} - -/* enable device interrupts */ -int DevUnmaskInterrupts(struct ar6k_device *pDev) -{ - /* for good measure, make sure interrupt are disabled before unmasking at the HIF - * layer. - * The rationale here is that between device insertion (where we clear the interrupts the first time) - * and when HTC is finally ready to handle interrupts, other software can perform target "soft" resets. - * The AR6K interrupt enables reset back to an "enabled" state when this happens. - * */ - int IntStatus = 0; - DevDisableInterrupts(pDev); - -#ifdef THREAD_X - // Tobe verified... - IntStatus = DevEnableInterrupts(pDev); - /* Unmask the host controller interrupts */ - HIFUnMaskInterrupt(pDev->HIFDevice); -#else - /* Unmask the host controller interrupts */ - HIFUnMaskInterrupt(pDev->HIFDevice); - IntStatus = DevEnableInterrupts(pDev); -#endif - - return IntStatus; -} - -/* disable all device interrupts */ -int DevMaskInterrupts(struct ar6k_device *pDev) -{ - /* mask the interrupt at the HIF layer, we don't want a stray interrupt taken while - * we zero out our shadow registers in DevDisableInterrupts()*/ - HIFMaskInterrupt(pDev->HIFDevice); - - return DevDisableInterrupts(pDev); -} - -/* callback when our fetch to enable/disable completes */ -static void DevDoEnableDisableRecvAsyncHandler(void *Context, struct htc_packet *pPacket) -{ - struct ar6k_device *pDev = (struct ar6k_device *)Context; - - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevDoEnableDisableRecvAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev)); - - if (pPacket->Status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - (" Failed to disable receiver, status:%d \n", pPacket->Status)); - } - /* free this IO packet */ - AR6KFreeIOPacket(pDev,pPacket); - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevDoEnableDisableRecvAsyncHandler \n")); -} - -/* disable packet reception (used in case the host runs out of buffers) - * this is the "override" method when the HIF reports another methods to - * disable recv events */ -static int DevDoEnableDisableRecvOverride(struct ar6k_device *pDev, bool EnableRecv, bool AsyncMode) -{ - int status = 0; - struct htc_packet *pIOPacket = NULL; - - AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("DevDoEnableDisableRecvOverride: Enable:%d Mode:%d\n", - EnableRecv,AsyncMode)); - - do { - - if (AsyncMode) { - - pIOPacket = AR6KAllocIOPacket(pDev); - - if (NULL == pIOPacket) { - status = A_NO_MEMORY; - A_ASSERT(false); - break; - } - - /* stick in our completion routine when the I/O operation completes */ - pIOPacket->Completion = DevDoEnableDisableRecvAsyncHandler; - pIOPacket->pContext = pDev; - - /* call the HIF layer override and do this asynchronously */ - status = pDev->HifMaskUmaskRecvEvent(pDev->HIFDevice, - EnableRecv ? HIF_UNMASK_RECV : HIF_MASK_RECV, - pIOPacket); - break; - } - - /* if we get here we are doing it synchronously */ - status = pDev->HifMaskUmaskRecvEvent(pDev->HIFDevice, - EnableRecv ? HIF_UNMASK_RECV : HIF_MASK_RECV, - NULL); - - } while (false); - - if (status && (pIOPacket != NULL)) { - AR6KFreeIOPacket(pDev,pIOPacket); - } - - return status; -} - -/* disable packet reception (used in case the host runs out of buffers) - * this is the "normal" method using the interrupt enable registers through - * the host I/F */ -static int DevDoEnableDisableRecvNormal(struct ar6k_device *pDev, bool EnableRecv, bool AsyncMode) -{ - int status = 0; - struct htc_packet *pIOPacket = NULL; - struct ar6k_irq_enable_registers regs; - - /* take the lock to protect interrupt enable shadows */ - LOCK_AR6K(pDev); - - if (EnableRecv) { - pDev->IrqEnableRegisters.int_status_enable |= INT_STATUS_ENABLE_MBOX_DATA_SET(0x01); - } else { - pDev->IrqEnableRegisters.int_status_enable &= ~INT_STATUS_ENABLE_MBOX_DATA_SET(0x01); - } - - /* copy into our temp area */ - memcpy(®s,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE); - UNLOCK_AR6K(pDev); - - do { - - if (AsyncMode) { - - pIOPacket = AR6KAllocIOPacket(pDev); - - if (NULL == pIOPacket) { - status = A_NO_MEMORY; - A_ASSERT(false); - break; - } - - /* copy values to write to our async I/O buffer */ - memcpy(pIOPacket->pBuffer,®s,AR6K_IRQ_ENABLE_REGS_SIZE); - - /* stick in our completion routine when the I/O operation completes */ - pIOPacket->Completion = DevDoEnableDisableRecvAsyncHandler; - pIOPacket->pContext = pDev; - - /* write it out asynchronously */ - HIFReadWrite(pDev->HIFDevice, - INT_STATUS_ENABLE_ADDRESS, - pIOPacket->pBuffer, - AR6K_IRQ_ENABLE_REGS_SIZE, - HIF_WR_ASYNC_BYTE_INC, - pIOPacket); - break; - } - - /* if we get here we are doing it synchronously */ - - status = HIFReadWrite(pDev->HIFDevice, - INT_STATUS_ENABLE_ADDRESS, - ®s.int_status_enable, - AR6K_IRQ_ENABLE_REGS_SIZE, - HIF_WR_SYNC_BYTE_INC, - NULL); - - } while (false); - - if (status && (pIOPacket != NULL)) { - AR6KFreeIOPacket(pDev,pIOPacket); - } - - return status; -} - - -int DevStopRecv(struct ar6k_device *pDev, bool AsyncMode) -{ - if (NULL == pDev->HifMaskUmaskRecvEvent) { - return DevDoEnableDisableRecvNormal(pDev,false,AsyncMode); - } else { - return DevDoEnableDisableRecvOverride(pDev,false,AsyncMode); - } -} - -int DevEnableRecv(struct ar6k_device *pDev, bool AsyncMode) -{ - if (NULL == pDev->HifMaskUmaskRecvEvent) { - return DevDoEnableDisableRecvNormal(pDev,true,AsyncMode); - } else { - return DevDoEnableDisableRecvOverride(pDev,true,AsyncMode); - } -} - -int DevWaitForPendingRecv(struct ar6k_device *pDev,u32 TimeoutInMs,bool *pbIsRecvPending) -{ - int status = 0; - u8 host_int_status = 0x0; - u32 counter = 0x0; - - if(TimeoutInMs < 100) - { - TimeoutInMs = 100; - } - - counter = TimeoutInMs / 100; - - do - { - //Read the Host Interrupt Status Register - status = HIFReadWrite(pDev->HIFDevice, - HOST_INT_STATUS_ADDRESS, - &host_int_status, - sizeof(u8), - HIF_RD_SYNC_BYTE_INC, - NULL); - if (status) - { - AR_DEBUG_PRINTF(ATH_LOG_ERR,("DevWaitForPendingRecv:Read HOST_INT_STATUS_ADDRESS Failed 0x%X\n",status)); - break; - } - - host_int_status = !status ? (host_int_status & (1 << 0)):0; - if(!host_int_status) - { - status = 0; - *pbIsRecvPending = false; - break; - } - else - { - *pbIsRecvPending = true; - } - - A_MDELAY(100); - - counter--; - - }while(counter); - return status; -} - -void DevDumpRegisters(struct ar6k_device *pDev, - struct ar6k_irq_proc_registers *pIrqProcRegs, - struct ar6k_irq_enable_registers *pIrqEnableRegs) -{ - - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("\n<------- Register Table -------->\n")); - - if (pIrqProcRegs != NULL) { - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, - ("Host Int Status: 0x%x\n",pIrqProcRegs->host_int_status)); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, - ("CPU Int Status: 0x%x\n",pIrqProcRegs->cpu_int_status)); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, - ("Error Int Status: 0x%x\n",pIrqProcRegs->error_int_status)); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, - ("Counter Int Status: 0x%x\n",pIrqProcRegs->counter_int_status)); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, - ("Mbox Frame: 0x%x\n",pIrqProcRegs->mbox_frame)); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, - ("Rx Lookahead Valid: 0x%x\n",pIrqProcRegs->rx_lookahead_valid)); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, - ("Rx Lookahead 0: 0x%x\n",pIrqProcRegs->rx_lookahead[0])); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, - ("Rx Lookahead 1: 0x%x\n",pIrqProcRegs->rx_lookahead[1])); - - if (pDev->MailBoxInfo.GMboxAddress != 0) { - /* if the target supports GMBOX hardware, dump some additional state */ - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, - ("GMBOX Host Int Status 2: 0x%x\n",pIrqProcRegs->host_int_status2)); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, - ("GMBOX RX Avail: 0x%x\n",pIrqProcRegs->gmbox_rx_avail)); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, - ("GMBOX lookahead alias 0: 0x%x\n",pIrqProcRegs->rx_gmbox_lookahead_alias[0])); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, - ("GMBOX lookahead alias 1: 0x%x\n",pIrqProcRegs->rx_gmbox_lookahead_alias[1])); - } - - } - - if (pIrqEnableRegs != NULL) { - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, - ("Int Status Enable: 0x%x\n",pIrqEnableRegs->int_status_enable)); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, - ("Counter Int Status Enable: 0x%x\n",pIrqEnableRegs->counter_int_status_enable)); - } - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("<------------------------------->\n")); -} - - -#define DEV_GET_VIRT_DMA_INFO(p) ((struct dev_scatter_dma_virtual_info *)((p)->HIFPrivate[0])) - -static struct hif_scatter_req *DevAllocScatterReq(struct hif_device *Context) -{ - struct dl_list *pItem; - struct ar6k_device *pDev = (struct ar6k_device *)Context; - LOCK_AR6K(pDev); - pItem = DL_ListRemoveItemFromHead(&pDev->ScatterReqHead); - UNLOCK_AR6K(pDev); - if (pItem != NULL) { - return A_CONTAINING_STRUCT(pItem, struct hif_scatter_req, ListLink); - } - return NULL; -} - -static void DevFreeScatterReq(struct hif_device *Context, struct hif_scatter_req *pReq) -{ - struct ar6k_device *pDev = (struct ar6k_device *)Context; - LOCK_AR6K(pDev); - DL_ListInsertTail(&pDev->ScatterReqHead, &pReq->ListLink); - UNLOCK_AR6K(pDev); -} - -int DevCopyScatterListToFromDMABuffer(struct hif_scatter_req *pReq, bool FromDMA) -{ - u8 *pDMABuffer = NULL; - int i, remaining; - u32 length; - - pDMABuffer = pReq->pScatterBounceBuffer; - - if (pDMABuffer == NULL) { - A_ASSERT(false); - return A_EINVAL; - } - - remaining = (int)pReq->TotalLength; - - for (i = 0; i < pReq->ValidScatterEntries; i++) { - - length = min((int)pReq->ScatterList[i].Length, remaining); - - if (length != (int)pReq->ScatterList[i].Length) { - A_ASSERT(false); - /* there is a problem with the scatter list */ - return A_EINVAL; - } - - if (FromDMA) { - /* from DMA buffer */ - memcpy(pReq->ScatterList[i].pBuffer, pDMABuffer , length); - } else { - /* to DMA buffer */ - memcpy(pDMABuffer, pReq->ScatterList[i].pBuffer, length); - } - - pDMABuffer += length; - remaining -= length; - } - - return 0; -} - -static void DevReadWriteScatterAsyncHandler(void *Context, struct htc_packet *pPacket) -{ - struct ar6k_device *pDev = (struct ar6k_device *)Context; - struct hif_scatter_req *pReq = (struct hif_scatter_req *)pPacket->pPktContext; - - AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+DevReadWriteScatterAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev)); - - pReq->CompletionStatus = pPacket->Status; - - AR6KFreeIOPacket(pDev,pPacket); - - pReq->CompletionRoutine(pReq); - - AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-DevReadWriteScatterAsyncHandler \n")); -} - -static int DevReadWriteScatter(struct hif_device *Context, struct hif_scatter_req *pReq) -{ - struct ar6k_device *pDev = (struct ar6k_device *)Context; - int status = 0; - struct htc_packet *pIOPacket = NULL; - u32 request = pReq->Request; - - do { - - if (pReq->TotalLength > AR6K_MAX_TRANSFER_SIZE_PER_SCATTER) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("Invalid length: %d \n", pReq->TotalLength)); - break; - } - - if (pReq->TotalLength == 0) { - A_ASSERT(false); - break; - } - - if (request & HIF_ASYNCHRONOUS) { - /* use an I/O packet to carry this request */ - pIOPacket = AR6KAllocIOPacket(pDev); - if (NULL == pIOPacket) { - status = A_NO_MEMORY; - break; - } - - /* save the request */ - pIOPacket->pPktContext = pReq; - /* stick in our completion routine when the I/O operation completes */ - pIOPacket->Completion = DevReadWriteScatterAsyncHandler; - pIOPacket->pContext = pDev; - } - - if (request & HIF_WRITE) { - /* in virtual DMA, we are issuing the requests through the legacy HIFReadWrite API - * this API will adjust the address automatically for the last byte to fall on the mailbox - * EOM. */ - - /* if the address is an extended address, we can adjust the address here since the extended - * address will bypass the normal checks in legacy HIF layers */ - if (pReq->Address == pDev->MailBoxInfo.MboxProp[HTC_MAILBOX].ExtendedAddress) { - pReq->Address += pDev->MailBoxInfo.MboxProp[HTC_MAILBOX].ExtendedSize - pReq->TotalLength; - } - } - - /* use legacy readwrite */ - status = HIFReadWrite(pDev->HIFDevice, - pReq->Address, - DEV_GET_VIRT_DMA_INFO(pReq)->pVirtDmaBuffer, - pReq->TotalLength, - request, - (request & HIF_ASYNCHRONOUS) ? pIOPacket : NULL); - - } while (false); - - if ((status != A_PENDING) && status && (request & HIF_ASYNCHRONOUS)) { - if (pIOPacket != NULL) { - AR6KFreeIOPacket(pDev,pIOPacket); - } - pReq->CompletionStatus = status; - pReq->CompletionRoutine(pReq); - status = 0; - } - - return status; -} - - -static void DevCleanupVirtualScatterSupport(struct ar6k_device *pDev) -{ - struct hif_scatter_req *pReq; - - while (1) { - pReq = DevAllocScatterReq((struct hif_device *)pDev); - if (NULL == pReq) { - break; - } - kfree(pReq); - } - -} - - /* function to set up virtual scatter support if HIF layer has not implemented the interface */ -static int DevSetupVirtualScatterSupport(struct ar6k_device *pDev) -{ - int status = 0; - int bufferSize, sgreqSize; - int i; - struct dev_scatter_dma_virtual_info *pVirtualInfo; - struct hif_scatter_req *pReq; - - bufferSize = sizeof(struct dev_scatter_dma_virtual_info) + - 2 * (A_GET_CACHE_LINE_BYTES()) + AR6K_MAX_TRANSFER_SIZE_PER_SCATTER; - - sgreqSize = sizeof(struct hif_scatter_req) + - (AR6K_SCATTER_ENTRIES_PER_REQ - 1) * (sizeof(struct hif_scatter_item)); - - for (i = 0; i < AR6K_SCATTER_REQS; i++) { - /* allocate the scatter request, buffer info and the actual virtual buffer itself */ - pReq = (struct hif_scatter_req *)A_MALLOC(sgreqSize + bufferSize); - - if (NULL == pReq) { - status = A_NO_MEMORY; - break; - } - - A_MEMZERO(pReq, sgreqSize); - - /* the virtual DMA starts after the scatter request struct */ - pVirtualInfo = (struct dev_scatter_dma_virtual_info *)((u8 *)pReq + sgreqSize); - A_MEMZERO(pVirtualInfo, sizeof(struct dev_scatter_dma_virtual_info)); - - pVirtualInfo->pVirtDmaBuffer = &pVirtualInfo->DataArea[0]; - /* align buffer to cache line in case host controller can actually DMA this */ - pVirtualInfo->pVirtDmaBuffer = A_ALIGN_TO_CACHE_LINE(pVirtualInfo->pVirtDmaBuffer); - /* store the structure in the private area */ - pReq->HIFPrivate[0] = pVirtualInfo; - /* we emulate a DMA bounce interface */ - pReq->ScatterMethod = HIF_SCATTER_DMA_BOUNCE; - pReq->pScatterBounceBuffer = pVirtualInfo->pVirtDmaBuffer; - /* free request to the list */ - DevFreeScatterReq((struct hif_device *)pDev,pReq); - } - - if (status) { - DevCleanupVirtualScatterSupport(pDev); - } else { - pDev->HifScatterInfo.pAllocateReqFunc = DevAllocScatterReq; - pDev->HifScatterInfo.pFreeReqFunc = DevFreeScatterReq; - pDev->HifScatterInfo.pReadWriteScatterFunc = DevReadWriteScatter; - if (pDev->MailBoxInfo.MboxBusIFType == MBOX_BUS_IF_SPI) { - AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("AR6K: SPI bus requires RX scatter limits\n")); - pDev->HifScatterInfo.MaxScatterEntries = AR6K_MIN_SCATTER_ENTRIES_PER_REQ; - pDev->HifScatterInfo.MaxTransferSizePerScatterReq = AR6K_MIN_TRANSFER_SIZE_PER_SCATTER; - } else { - pDev->HifScatterInfo.MaxScatterEntries = AR6K_SCATTER_ENTRIES_PER_REQ; - pDev->HifScatterInfo.MaxTransferSizePerScatterReq = AR6K_MAX_TRANSFER_SIZE_PER_SCATTER; - } - pDev->ScatterIsVirtual = true; - } - - return status; -} - -int DevCleanupMsgBundling(struct ar6k_device *pDev) -{ - if(NULL != pDev) - { - DevCleanupVirtualScatterSupport(pDev); - } - - return 0; -} - -int DevSetupMsgBundling(struct ar6k_device *pDev, int MaxMsgsPerTransfer) -{ - int status; - - if (pDev->MailBoxInfo.Flags & HIF_MBOX_FLAG_NO_BUNDLING) { - AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("HIF requires bundling disabled\n")); - return A_ENOTSUP; - } - - status = HIFConfigureDevice(pDev->HIFDevice, - HIF_CONFIGURE_QUERY_SCATTER_REQUEST_SUPPORT, - &pDev->HifScatterInfo, - sizeof(pDev->HifScatterInfo)); - - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_WARN, - ("AR6K: ** HIF layer does not support scatter requests (%d) \n",status)); - - /* we can try to use a virtual DMA scatter mechanism using legacy HIFReadWrite() */ - status = DevSetupVirtualScatterSupport(pDev); - - if (!status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, - ("AR6K: virtual scatter transfers enabled (max scatter items:%d: maxlen:%d) \n", - DEV_GET_MAX_MSG_PER_BUNDLE(pDev), DEV_GET_MAX_BUNDLE_LENGTH(pDev))); - } - - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, - ("AR6K: HIF layer supports scatter requests (max scatter items:%d: maxlen:%d) \n", - DEV_GET_MAX_MSG_PER_BUNDLE(pDev), DEV_GET_MAX_BUNDLE_LENGTH(pDev))); - } - - if (!status) { - /* for the recv path, the maximum number of bytes per recv bundle is just limited - * by the maximum transfer size at the HIF layer */ - pDev->MaxRecvBundleSize = pDev->HifScatterInfo.MaxTransferSizePerScatterReq; - - if (pDev->MailBoxInfo.MboxBusIFType == MBOX_BUS_IF_SPI) { - AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("AR6K : SPI bus requires TX bundling disabled\n")); - pDev->MaxSendBundleSize = 0; - } else { - /* for the send path, the max transfer size is limited by the existence and size of - * the extended mailbox address range */ - if (pDev->MailBoxInfo.MboxProp[0].ExtendedAddress != 0) { - pDev->MaxSendBundleSize = pDev->MailBoxInfo.MboxProp[0].ExtendedSize; - } else { - /* legacy */ - pDev->MaxSendBundleSize = AR6K_LEGACY_MAX_WRITE_LENGTH; - } - - if (pDev->MaxSendBundleSize > pDev->HifScatterInfo.MaxTransferSizePerScatterReq) { - /* limit send bundle size to what the HIF can support for scatter requests */ - pDev->MaxSendBundleSize = pDev->HifScatterInfo.MaxTransferSizePerScatterReq; - } - } - - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, - ("AR6K: max recv: %d max send: %d \n", - DEV_GET_MAX_BUNDLE_RECV_LENGTH(pDev), DEV_GET_MAX_BUNDLE_SEND_LENGTH(pDev))); - - } - return status; -} - -int DevSubmitScatterRequest(struct ar6k_device *pDev, struct hif_scatter_req *pScatterReq, bool Read, bool Async) -{ - int status; - - if (Read) { - /* read operation */ - pScatterReq->Request = (Async) ? HIF_RD_ASYNC_BLOCK_FIX : HIF_RD_SYNC_BLOCK_FIX; - pScatterReq->Address = pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX]; - A_ASSERT(pScatterReq->TotalLength <= (u32)DEV_GET_MAX_BUNDLE_RECV_LENGTH(pDev)); - } else { - u32 mailboxWidth; - - /* write operation */ - pScatterReq->Request = (Async) ? HIF_WR_ASYNC_BLOCK_INC : HIF_WR_SYNC_BLOCK_INC; - A_ASSERT(pScatterReq->TotalLength <= (u32)DEV_GET_MAX_BUNDLE_SEND_LENGTH(pDev)); - if (pScatterReq->TotalLength > AR6K_LEGACY_MAX_WRITE_LENGTH) { - /* for large writes use the extended address */ - pScatterReq->Address = pDev->MailBoxInfo.MboxProp[HTC_MAILBOX].ExtendedAddress; - mailboxWidth = pDev->MailBoxInfo.MboxProp[HTC_MAILBOX].ExtendedSize; - } else { - pScatterReq->Address = pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX]; - mailboxWidth = AR6K_LEGACY_MAX_WRITE_LENGTH; - } - - if (!pDev->ScatterIsVirtual) { - /* we are passing this scatter list down to the HIF layer' scatter request handler, fixup the address - * so that the last byte falls on the EOM, we do this for those HIFs that support the - * scatter API */ - pScatterReq->Address += (mailboxWidth - pScatterReq->TotalLength); - } - - } - - AR_DEBUG_PRINTF(ATH_DEBUG_RECV | ATH_DEBUG_SEND, - ("DevSubmitScatterRequest, Entries: %d, Total Length: %d Mbox:0x%X (mode: %s : %s)\n", - pScatterReq->ValidScatterEntries, - pScatterReq->TotalLength, - pScatterReq->Address, - Async ? "ASYNC" : "SYNC", - (Read) ? "RD" : "WR")); - - status = DEV_PREPARE_SCATTER_OPERATION(pScatterReq); - - if (status) { - if (Async) { - pScatterReq->CompletionStatus = status; - pScatterReq->CompletionRoutine(pScatterReq); - return 0; - } - return status; - } - - status = pDev->HifScatterInfo.pReadWriteScatterFunc(pDev->ScatterIsVirtual ? pDev : pDev->HIFDevice, - pScatterReq); - if (!Async) { - /* in sync mode, we can touch the scatter request */ - pScatterReq->CompletionStatus = status; - DEV_FINISH_SCATTER_OPERATION(pScatterReq); - } else { - if (status == A_PENDING) { - status = 0; - } - } - - return status; -} - - -#ifdef MBOXHW_UNIT_TEST - - -/* This is a mailbox hardware unit test that must be called in a schedulable context - * This test is very simple, it will send a list of buffers with a counting pattern - * and the target will invert the data and send the message back - * - * the unit test has the following constraints: - * - * The target has at least 8 buffers of 256 bytes each. The host will send - * the following pattern of buffers in rapid succession : - * - * 1 buffer - 128 bytes - * 1 buffer - 256 bytes - * 1 buffer - 512 bytes - * 1 buffer - 1024 bytes - * - * The host will send the buffers to one mailbox and wait for buffers to be reflected - * back from the same mailbox. The target sends the buffers FIFO order. - * Once the final buffer has been received for a mailbox, the next mailbox is tested. - * - * - * Note: To simplifythe test , we assume that the chosen buffer sizes - * will fall on a nice block pad - * - * It is expected that higher-order tests will be written to stress the mailboxes using - * a message-based protocol (with some performance timming) that can create more - * randomness in the packets sent over mailboxes. - * - * */ - -#define A_ROUND_UP_PWR2(x, align) (((int) (x) + ((align)-1)) & ~((align)-1)) - -#define BUFFER_BLOCK_PAD 128 - -#if 0 -#define BUFFER1 128 -#define BUFFER2 256 -#define BUFFER3 512 -#define BUFFER4 1024 -#endif - -#if 1 -#define BUFFER1 80 -#define BUFFER2 200 -#define BUFFER3 444 -#define BUFFER4 800 -#endif - -#define TOTAL_BYTES (A_ROUND_UP_PWR2(BUFFER1,BUFFER_BLOCK_PAD) + \ - A_ROUND_UP_PWR2(BUFFER2,BUFFER_BLOCK_PAD) + \ - A_ROUND_UP_PWR2(BUFFER3,BUFFER_BLOCK_PAD) + \ - A_ROUND_UP_PWR2(BUFFER4,BUFFER_BLOCK_PAD) ) - -#define TEST_BYTES (BUFFER1 + BUFFER2 + BUFFER3 + BUFFER4) - -#define TEST_CREDITS_RECV_TIMEOUT 100 - -static u8 g_Buffer[TOTAL_BYTES]; -static u32 g_MailboxAddrs[AR6K_MAILBOXES]; -static u32 g_BlockSizes[AR6K_MAILBOXES]; - -#define BUFFER_PROC_LIST_DEPTH 4 - -struct buffer_proc_list { - u8 *pBuffer; - u32 length; -}; - - -#define PUSH_BUFF_PROC_ENTRY(pList,len,pCurrpos) \ -{ \ - (pList)->pBuffer = (pCurrpos); \ - (pList)->length = (len); \ - (pCurrpos) += (len); \ - (pList)++; \ -} - -/* a simple and crude way to send different "message" sizes */ -static void AssembleBufferList(struct buffer_proc_list *pList) -{ - u8 *pBuffer = g_Buffer; - -#if BUFFER_PROC_LIST_DEPTH < 4 -#error "Buffer processing list depth is not deep enough!!" -#endif - - PUSH_BUFF_PROC_ENTRY(pList,BUFFER1,pBuffer); - PUSH_BUFF_PROC_ENTRY(pList,BUFFER2,pBuffer); - PUSH_BUFF_PROC_ENTRY(pList,BUFFER3,pBuffer); - PUSH_BUFF_PROC_ENTRY(pList,BUFFER4,pBuffer); - -} - -#define FILL_ZERO true -#define FILL_COUNTING false -static void InitBuffers(bool Zero) -{ - u16 *pBuffer16 = (u16 *)g_Buffer; - int i; - - /* fill buffer with 16 bit counting pattern or zeros */ - for (i = 0; i < (TOTAL_BYTES / 2) ; i++) { - if (!Zero) { - pBuffer16[i] = (u16)i; - } else { - pBuffer16[i] = 0; - } - } -} - - -static bool CheckOneBuffer(u16 *pBuffer16, int Length) -{ - int i; - u16 startCount; - bool success = true; - - /* get the starting count */ - startCount = pBuffer16[0]; - /* invert it, this is the expected value */ - startCount = ~startCount; - /* scan the buffer and verify */ - for (i = 0; i < (Length / 2) ; i++,startCount++) { - /* target will invert all the data */ - if ((u16)pBuffer16[i] != (u16)~startCount) { - success = false; - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid Data Got:0x%X, Expecting:0x%X (offset:%d, total:%d) \n", - pBuffer16[i], ((u16)~startCount), i, Length)); - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("0x%X 0x%X 0x%X 0x%X \n", - pBuffer16[i], pBuffer16[i + 1], pBuffer16[i + 2],pBuffer16[i+3])); - break; - } - } - - return success; -} - -static bool CheckBuffers(void) -{ - int i; - bool success = true; - struct buffer_proc_list checkList[BUFFER_PROC_LIST_DEPTH]; - - /* assemble the list */ - AssembleBufferList(checkList); - - /* scan the buffers and verify */ - for (i = 0; i < BUFFER_PROC_LIST_DEPTH ; i++) { - success = CheckOneBuffer((u16 *)checkList[i].pBuffer, checkList[i].length); - if (!success) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Buffer : 0x%X, Length:%d failed verify \n", - (u32)checkList[i].pBuffer, checkList[i].length)); - break; - } - } - - return success; -} - - /* find the end marker for the last buffer we will be sending */ -static u16 GetEndMarker(void) -{ - u8 *pBuffer; - struct buffer_proc_list checkList[BUFFER_PROC_LIST_DEPTH]; - - /* fill up buffers with the normal counting pattern */ - InitBuffers(FILL_COUNTING); - - /* assemble the list we will be sending down */ - AssembleBufferList(checkList); - /* point to the last 2 bytes of the last buffer */ - pBuffer = &(checkList[BUFFER_PROC_LIST_DEPTH - 1].pBuffer[(checkList[BUFFER_PROC_LIST_DEPTH - 1].length) - 2]); - - /* the last count in the last buffer is the marker */ - return (u16)pBuffer[0] | ((u16)pBuffer[1] << 8); -} - -#define ATH_PRINT_OUT_ZONE ATH_DEBUG_ERR - -/* send the ordered buffers to the target */ -static int SendBuffers(struct ar6k_device *pDev, int mbox) -{ - int status = 0; - u32 request = HIF_WR_SYNC_BLOCK_INC; - struct buffer_proc_list sendList[BUFFER_PROC_LIST_DEPTH]; - int i; - int totalBytes = 0; - int paddedLength; - int totalwPadding = 0; - - AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Sending buffers on mailbox : %d \n",mbox)); - - /* fill buffer with counting pattern */ - InitBuffers(FILL_COUNTING); - - /* assemble the order in which we send */ - AssembleBufferList(sendList); - - for (i = 0; i < BUFFER_PROC_LIST_DEPTH; i++) { - - /* we are doing block transfers, so we need to pad everything to a block size */ - paddedLength = (sendList[i].length + (g_BlockSizes[mbox] - 1)) & - (~(g_BlockSizes[mbox] - 1)); - - /* send each buffer synchronously */ - status = HIFReadWrite(pDev->HIFDevice, - g_MailboxAddrs[mbox], - sendList[i].pBuffer, - paddedLength, - request, - NULL); - if (status) { - break; - } - totalBytes += sendList[i].length; - totalwPadding += paddedLength; - } - - AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Sent %d bytes (%d padded bytes) to mailbox : %d \n",totalBytes,totalwPadding,mbox)); - - return status; -} - -/* poll the mailbox credit counter until we get a credit or timeout */ -static int GetCredits(struct ar6k_device *pDev, int mbox, int *pCredits) -{ - int status = 0; - int timeout = TEST_CREDITS_RECV_TIMEOUT; - u8 credits = 0; - u32 address; - - while (true) { - - /* Read the counter register to get credits, this auto-decrements */ - address = COUNT_DEC_ADDRESS + (AR6K_MAILBOXES + mbox) * 4; - status = HIFReadWrite(pDev->HIFDevice, address, &credits, sizeof(credits), - HIF_RD_SYNC_BYTE_FIX, NULL); - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("Unable to decrement the command credit count register (mbox=%d)\n",mbox)); - status = A_ERROR; - break; - } - - if (credits) { - break; - } - - timeout--; - - if (timeout <= 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - (" Timeout reading credit registers (mbox=%d, address:0x%X) \n",mbox,address)); - status = A_ERROR; - break; - } - - /* delay a little, target may not be ready */ - A_MDELAY(1000); - - } - - if (status == 0) { - *pCredits = credits; - } - - return status; -} - - -/* wait for the buffers to come back */ -static int RecvBuffers(struct ar6k_device *pDev, int mbox) -{ - int status = 0; - u32 request = HIF_RD_SYNC_BLOCK_INC; - struct buffer_proc_list recvList[BUFFER_PROC_LIST_DEPTH]; - int curBuffer; - int credits; - int i; - int totalBytes = 0; - int paddedLength; - int totalwPadding = 0; - - AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Waiting for buffers on mailbox : %d \n",mbox)); - - /* zero the buffers */ - InitBuffers(FILL_ZERO); - - /* assemble the order in which we should receive */ - AssembleBufferList(recvList); - - curBuffer = 0; - - while (curBuffer < BUFFER_PROC_LIST_DEPTH) { - - /* get number of buffers that have been completed, this blocks - * until we get at least 1 credit or it times out */ - status = GetCredits(pDev, mbox, &credits); - - if (status) { - break; - } - - AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Got %d messages on mailbox : %d \n",credits, mbox)); - - /* get all the buffers that are sitting on the queue */ - for (i = 0; i < credits; i++) { - A_ASSERT(curBuffer < BUFFER_PROC_LIST_DEPTH); - /* recv the current buffer synchronously, the buffers should come back in - * order... with padding applied by the target */ - paddedLength = (recvList[curBuffer].length + (g_BlockSizes[mbox] - 1)) & - (~(g_BlockSizes[mbox] - 1)); - - status = HIFReadWrite(pDev->HIFDevice, - g_MailboxAddrs[mbox], - recvList[curBuffer].pBuffer, - paddedLength, - request, - NULL); - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to read %d bytes on mailbox:%d : address:0x%X \n", - recvList[curBuffer].length, mbox, g_MailboxAddrs[mbox])); - break; - } - - totalwPadding += paddedLength; - totalBytes += recvList[curBuffer].length; - curBuffer++; - } - - if (status) { - break; - } - /* go back and get some more */ - credits = 0; - } - - if (totalBytes != TEST_BYTES) { - A_ASSERT(false); - } else { - AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Got all buffers on mbox:%d total recv :%d (w/Padding : %d) \n", - mbox, totalBytes, totalwPadding)); - } - - return status; - - -} - -static int DoOneMboxHWTest(struct ar6k_device *pDev, int mbox) -{ - int status; - - do { - /* send out buffers */ - status = SendBuffers(pDev,mbox); - - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Sending buffers Failed : %d mbox:%d\n",status,mbox)); - break; - } - - /* go get them, this will block */ - status = RecvBuffers(pDev, mbox); - - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Recv buffers Failed : %d mbox:%d\n",status,mbox)); - break; - } - - /* check the returned data patterns */ - if (!CheckBuffers()) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Buffer Verify Failed : mbox:%d\n",mbox)); - status = A_ERROR; - break; - } - - AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, (" Send/Recv success! mailbox : %d \n",mbox)); - - } while (false); - - return status; -} - -/* here is where the test starts */ -int DoMboxHWTest(struct ar6k_device *pDev) -{ - int i; - int status; - int credits = 0; - u8 params[4]; - int numBufs; - int bufferSize; - u16 temp; - - - AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, (" DoMboxHWTest START - \n")); - - do { - /* get the addresses for all 4 mailboxes */ - status = HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_MBOX_ADDR, - g_MailboxAddrs, sizeof(g_MailboxAddrs)); - - if (status) { - A_ASSERT(false); - break; - } - - /* get the block sizes */ - status = HIFConfigureDevice(pDev->HIFDevice, HIF_DEVICE_GET_MBOX_BLOCK_SIZE, - g_BlockSizes, sizeof(g_BlockSizes)); - - if (status) { - A_ASSERT(false); - break; - } - - /* note, the HIF layer usually reports mbox 0 to have a block size of - * 1, but our test wants to run in block-mode for all mailboxes, so we treat all mailboxes - * the same. */ - g_BlockSizes[0] = g_BlockSizes[1]; - AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Block Size to use: %d \n",g_BlockSizes[0])); - - if (g_BlockSizes[1] > BUFFER_BLOCK_PAD) { - AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("%d Block size is too large for buffer pad %d\n", - g_BlockSizes[1], BUFFER_BLOCK_PAD)); - break; - } - - AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Waiting for target.... \n")); - - /* the target lets us know it is ready by giving us 1 credit on - * mailbox 0 */ - status = GetCredits(pDev, 0, &credits); - - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to wait for target ready \n")); - break; - } - - AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Target is ready ...\n")); - - /* read the first 4 scratch registers */ - status = HIFReadWrite(pDev->HIFDevice, - SCRATCH_ADDRESS, - params, - 4, - HIF_RD_SYNC_BYTE_INC, - NULL); - - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to wait get parameters \n")); - break; - } - - numBufs = params[0]; - bufferSize = (int)(((u16)params[2] << 8) | (u16)params[1]); - - AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, - ("Target parameters: bufs per mailbox:%d, buffer size:%d bytes (total space: %d, minimum required space (w/padding): %d) \n", - numBufs, bufferSize, (numBufs * bufferSize), TOTAL_BYTES)); - - if ((numBufs * bufferSize) < TOTAL_BYTES) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Not Enough buffer space to run test! need:%d, got:%d \n", - TOTAL_BYTES, (numBufs*bufferSize))); - status = A_ERROR; - break; - } - - temp = GetEndMarker(); - - status = HIFReadWrite(pDev->HIFDevice, - SCRATCH_ADDRESS + 4, - (u8 *)&temp, - 2, - HIF_WR_SYNC_BYTE_INC, - NULL); - - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to write end marker \n")); - break; - } - - AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("End Marker: 0x%X \n",temp)); - - temp = (u16)g_BlockSizes[1]; - /* convert to a mask */ - temp = temp - 1; - status = HIFReadWrite(pDev->HIFDevice, - SCRATCH_ADDRESS + 6, - (u8 *)&temp, - 2, - HIF_WR_SYNC_BYTE_INC, - NULL); - - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to write block mask \n")); - break; - } - - AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, ("Set Block Mask: 0x%X \n",temp)); - - /* execute the test on each mailbox */ - for (i = 0; i < AR6K_MAILBOXES; i++) { - status = DoOneMboxHWTest(pDev, i); - if (status) { - break; - } - } - - } while (false); - - if (status == 0) { - AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, (" DoMboxHWTest DONE - SUCCESS! - \n")); - } else { - AR_DEBUG_PRINTF(ATH_PRINT_OUT_ZONE, (" DoMboxHWTest DONE - FAILED! - \n")); - } - /* don't let HTC_Start continue, the target is actually not running any HTC code */ - return A_ERROR; -} -#endif - - - diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h b/drivers/staging/ath6kl/htc2/AR6000/ar6k.h deleted file mode 100644 index e551dbe..0000000 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k.h +++ /dev/null @@ -1,401 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="ar6k.h" company="Atheros"> -// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// AR6K device layer that handles register level I/O -// -// Author(s): ="Atheros" -//============================================================================== -#ifndef AR6K_H_ -#define AR6K_H_ - -#include "hci_transport_api.h" -#include "../htc_debug.h" - -#define AR6K_MAILBOXES 4 - -/* HTC runs over mailbox 0 */ -#define HTC_MAILBOX 0 - -#define AR6K_TARGET_DEBUG_INTR_MASK 0x01 - -#define OTHER_INTS_ENABLED (INT_STATUS_ENABLE_ERROR_MASK | \ - INT_STATUS_ENABLE_CPU_MASK | \ - INT_STATUS_ENABLE_COUNTER_MASK) - - -//#define MBOXHW_UNIT_TEST 1 - -PREPACK struct ar6k_irq_proc_registers { - u8 host_int_status; - u8 cpu_int_status; - u8 error_int_status; - u8 counter_int_status; - u8 mbox_frame; - u8 rx_lookahead_valid; - u8 host_int_status2; - u8 gmbox_rx_avail; - u32 rx_lookahead[2]; - u32 rx_gmbox_lookahead_alias[2]; -} POSTPACK; - -#define AR6K_IRQ_PROC_REGS_SIZE sizeof(struct ar6k_irq_proc_registers) - -PREPACK struct ar6k_irq_enable_registers { - u8 int_status_enable; - u8 cpu_int_status_enable; - u8 error_status_enable; - u8 counter_int_status_enable; -} POSTPACK; - -PREPACK struct ar6k_gmbox_ctrl_registers { - u8 int_status_enable; -} POSTPACK; - -#define AR6K_IRQ_ENABLE_REGS_SIZE sizeof(struct ar6k_irq_enable_registers) - -#define AR6K_REG_IO_BUFFER_SIZE 32 -#define AR6K_MAX_REG_IO_BUFFERS 8 -#define FROM_DMA_BUFFER true -#define TO_DMA_BUFFER false -#define AR6K_SCATTER_ENTRIES_PER_REQ 16 -#define AR6K_MAX_TRANSFER_SIZE_PER_SCATTER 16*1024 -#define AR6K_SCATTER_REQS 4 -#define AR6K_LEGACY_MAX_WRITE_LENGTH 2048 - -#ifndef A_CACHE_LINE_PAD -#define A_CACHE_LINE_PAD 128 -#endif -#define AR6K_MIN_SCATTER_ENTRIES_PER_REQ 2 -#define AR6K_MIN_TRANSFER_SIZE_PER_SCATTER 4*1024 - -/* buffers for ASYNC I/O */ -struct ar6k_async_reg_io_buffer { - struct htc_packet HtcPacket; /* we use an HTC packet as a wrapper for our async register-based I/O */ - u8 _Pad1[A_CACHE_LINE_PAD]; - u8 Buffer[AR6K_REG_IO_BUFFER_SIZE]; /* cache-line safe with pads around */ - u8 _Pad2[A_CACHE_LINE_PAD]; -}; - -struct ar6k_gmbox_info { - void *pProtocolContext; - int (*pMessagePendingCallBack)(void *pContext, u8 LookAheadBytes[], int ValidBytes); - int (*pCreditsPendingCallback)(void *pContext, int NumCredits, bool CreditIRQEnabled); - void (*pTargetFailureCallback)(void *pContext, int Status); - void (*pStateDumpCallback)(void *pContext); - bool CreditCountIRQEnabled; -}; - -struct ar6k_device { - A_MUTEX_T Lock; - u8 _Pad1[A_CACHE_LINE_PAD]; - struct ar6k_irq_proc_registers IrqProcRegisters; /* cache-line safe with pads around */ - u8 _Pad2[A_CACHE_LINE_PAD]; - struct ar6k_irq_enable_registers IrqEnableRegisters; /* cache-line safe with pads around */ - u8 _Pad3[A_CACHE_LINE_PAD]; - void *HIFDevice; - u32 BlockSize; - u32 BlockMask; - struct hif_device_mbox_info MailBoxInfo; - HIF_PENDING_EVENTS_FUNC GetPendingEventsFunc; - void *HTCContext; - struct htc_packet_queue RegisterIOList; - struct ar6k_async_reg_io_buffer RegIOBuffers[AR6K_MAX_REG_IO_BUFFERS]; - void (*TargetFailureCallback)(void *Context); - int (*MessagePendingCallback)(void *Context, - u32 LookAheads[], - int NumLookAheads, - bool *pAsyncProc, - int *pNumPktsFetched); - HIF_DEVICE_IRQ_PROCESSING_MODE HifIRQProcessingMode; - HIF_MASK_UNMASK_RECV_EVENT HifMaskUmaskRecvEvent; - bool HifAttached; - struct hif_device_irq_yield_params HifIRQYieldParams; - bool DSRCanYield; - int CurrentDSRRecvCount; - struct hif_device_scatter_support_info HifScatterInfo; - struct dl_list ScatterReqHead; - bool ScatterIsVirtual; - int MaxRecvBundleSize; - int MaxSendBundleSize; - struct ar6k_gmbox_info GMboxInfo; - bool GMboxEnabled; - struct ar6k_gmbox_ctrl_registers GMboxControlRegisters; - int RecheckIRQStatusCnt; -}; - -#define LOCK_AR6K(p) A_MUTEX_LOCK(&(p)->Lock); -#define UNLOCK_AR6K(p) A_MUTEX_UNLOCK(&(p)->Lock); -#define REF_IRQ_STATUS_RECHECK(p) (p)->RecheckIRQStatusCnt = 1 /* note: no need to lock this, it only gets set */ - -int DevSetup(struct ar6k_device *pDev); -void DevCleanup(struct ar6k_device *pDev); -int DevUnmaskInterrupts(struct ar6k_device *pDev); -int DevMaskInterrupts(struct ar6k_device *pDev); -int DevPollMboxMsgRecv(struct ar6k_device *pDev, - u32 *pLookAhead, - int TimeoutMS); -int DevRWCompletionHandler(void *context, int status); -int DevDsrHandler(void *context); -int DevCheckPendingRecvMsgsAsync(void *context); -void DevAsyncIrqProcessComplete(struct ar6k_device *pDev); -void DevDumpRegisters(struct ar6k_device *pDev, - struct ar6k_irq_proc_registers *pIrqProcRegs, - struct ar6k_irq_enable_registers *pIrqEnableRegs); - -#define DEV_STOP_RECV_ASYNC true -#define DEV_STOP_RECV_SYNC false -#define DEV_ENABLE_RECV_ASYNC true -#define DEV_ENABLE_RECV_SYNC false -int DevStopRecv(struct ar6k_device *pDev, bool ASyncMode); -int DevEnableRecv(struct ar6k_device *pDev, bool ASyncMode); -int DevEnableInterrupts(struct ar6k_device *pDev); -int DevDisableInterrupts(struct ar6k_device *pDev); -int DevWaitForPendingRecv(struct ar6k_device *pDev,u32 TimeoutInMs,bool *pbIsRecvPending); - -#define DEV_CALC_RECV_PADDED_LEN(pDev, length) (((length) + (pDev)->BlockMask) & (~((pDev)->BlockMask))) -#define DEV_CALC_SEND_PADDED_LEN(pDev, length) DEV_CALC_RECV_PADDED_LEN(pDev,length) -#define DEV_IS_LEN_BLOCK_ALIGNED(pDev, length) (((length) % (pDev)->BlockSize) == 0) - -static INLINE int DevSendPacket(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 SendLength) { - u32 paddedLength; - bool sync = (pPacket->Completion == NULL) ? true : false; - int status; - - /* adjust the length to be a multiple of block size if appropriate */ - paddedLength = DEV_CALC_SEND_PADDED_LEN(pDev, SendLength); - -#if 0 - if (paddedLength > pPacket->BufferLength) { - A_ASSERT(false); - if (pPacket->Completion != NULL) { - COMPLETE_HTC_PACKET(pPacket,A_EINVAL); - return 0; - } - return A_EINVAL; - } -#endif - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, - ("DevSendPacket, Padded Length: %d Mbox:0x%X (mode:%s)\n", - paddedLength, - pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX], - sync ? "SYNC" : "ASYNC")); - - status = HIFReadWrite(pDev->HIFDevice, - pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX], - pPacket->pBuffer, - paddedLength, /* the padded length */ - sync ? HIF_WR_SYNC_BLOCK_INC : HIF_WR_ASYNC_BLOCK_INC, - sync ? NULL : pPacket); /* pass the packet as the context to the HIF request */ - - if (sync) { - pPacket->Status = status; - } else { - if (status == A_PENDING) { - status = 0; - } - } - - return status; -} - -static INLINE int DevRecvPacket(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 RecvLength) { - u32 paddedLength; - int status; - bool sync = (pPacket->Completion == NULL) ? true : false; - - /* adjust the length to be a multiple of block size if appropriate */ - paddedLength = DEV_CALC_RECV_PADDED_LEN(pDev, RecvLength); - - if (paddedLength > pPacket->BufferLength) { - A_ASSERT(false); - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("DevRecvPacket, Not enough space for padlen:%d recvlen:%d bufferlen:%d \n", - paddedLength,RecvLength,pPacket->BufferLength)); - if (pPacket->Completion != NULL) { - COMPLETE_HTC_PACKET(pPacket,A_EINVAL); - return 0; - } - return A_EINVAL; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_RECV, - ("DevRecvPacket (0x%lX : hdr:0x%X) Padded Length: %d Mbox:0x%X (mode:%s)\n", - (unsigned long)pPacket, pPacket->PktInfo.AsRx.ExpectedHdr, - paddedLength, - pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX], - sync ? "SYNC" : "ASYNC")); - - status = HIFReadWrite(pDev->HIFDevice, - pDev->MailBoxInfo.MboxAddresses[HTC_MAILBOX], - pPacket->pBuffer, - paddedLength, - sync ? HIF_RD_SYNC_BLOCK_FIX : HIF_RD_ASYNC_BLOCK_FIX, - sync ? NULL : pPacket); /* pass the packet as the context to the HIF request */ - - if (sync) { - pPacket->Status = status; - } - - return status; -} - -#define DEV_CHECK_RECV_YIELD(pDev) \ - ((pDev)->CurrentDSRRecvCount >= (pDev)->HifIRQYieldParams.RecvPacketYieldCount) - -#define IS_DEV_IRQ_PROC_SYNC_MODE(pDev) (HIF_DEVICE_IRQ_SYNC_ONLY == (pDev)->HifIRQProcessingMode) -#define IS_DEV_IRQ_PROCESSING_ASYNC_ALLOWED(pDev) ((pDev)->HifIRQProcessingMode != HIF_DEVICE_IRQ_SYNC_ONLY) - -/**************************************************/ -/****** Scatter Function and Definitions - * - * - */ - -int DevCopyScatterListToFromDMABuffer(struct hif_scatter_req *pReq, bool FromDMA); - - /* copy any READ data back into scatter list */ -#define DEV_FINISH_SCATTER_OPERATION(pR) \ -do { \ - if (!((pR)->CompletionStatus) && \ - !((pR)->Request & HIF_WRITE) && \ - ((pR)->ScatterMethod == HIF_SCATTER_DMA_BOUNCE)) { \ - (pR)->CompletionStatus = \ - DevCopyScatterListToFromDMABuffer((pR), \ - FROM_DMA_BUFFER); \ - } \ -} while (0) - - /* copy any WRITE data to bounce buffer */ -static INLINE int DEV_PREPARE_SCATTER_OPERATION(struct hif_scatter_req *pReq) { - if ((pReq->Request & HIF_WRITE) && (pReq->ScatterMethod == HIF_SCATTER_DMA_BOUNCE)) { - return DevCopyScatterListToFromDMABuffer(pReq,TO_DMA_BUFFER); - } else { - return 0; - } -} - - -int DevSetupMsgBundling(struct ar6k_device *pDev, int MaxMsgsPerTransfer); - -int DevCleanupMsgBundling(struct ar6k_device *pDev); - -#define DEV_GET_MAX_MSG_PER_BUNDLE(pDev) (pDev)->HifScatterInfo.MaxScatterEntries -#define DEV_GET_MAX_BUNDLE_LENGTH(pDev) (pDev)->HifScatterInfo.MaxTransferSizePerScatterReq -#define DEV_ALLOC_SCATTER_REQ(pDev) \ - (pDev)->HifScatterInfo.pAllocateReqFunc((pDev)->ScatterIsVirtual ? (pDev) : (pDev)->HIFDevice) - -#define DEV_FREE_SCATTER_REQ(pDev,pR) \ - (pDev)->HifScatterInfo.pFreeReqFunc((pDev)->ScatterIsVirtual ? (pDev) : (pDev)->HIFDevice,(pR)) - -#define DEV_GET_MAX_BUNDLE_RECV_LENGTH(pDev) (pDev)->MaxRecvBundleSize -#define DEV_GET_MAX_BUNDLE_SEND_LENGTH(pDev) (pDev)->MaxSendBundleSize - -#define DEV_SCATTER_READ true -#define DEV_SCATTER_WRITE false -#define DEV_SCATTER_ASYNC true -#define DEV_SCATTER_SYNC false -int DevSubmitScatterRequest(struct ar6k_device *pDev, struct hif_scatter_req *pScatterReq, bool Read, bool Async); - -#ifdef MBOXHW_UNIT_TEST -int DoMboxHWTest(struct ar6k_device *pDev); -#endif - - /* completely virtual */ -struct dev_scatter_dma_virtual_info { - u8 *pVirtDmaBuffer; /* dma-able buffer - CPU accessible address */ - u8 DataArea[1]; /* start of data area */ -}; - - - -void DumpAR6KDevState(struct ar6k_device *pDev); - -/**************************************************/ -/****** GMBOX functions and definitions - * - * - */ - -#ifdef ATH_AR6K_ENABLE_GMBOX - -void DevCleanupGMbox(struct ar6k_device *pDev); -int DevSetupGMbox(struct ar6k_device *pDev); -int DevCheckGMboxInterrupts(struct ar6k_device *pDev); -void DevNotifyGMboxTargetFailure(struct ar6k_device *pDev); - -#else - - /* compiled out */ -#define DevCleanupGMbox(p) -#define DevCheckGMboxInterrupts(p) 0 -#define DevNotifyGMboxTargetFailure(p) - -static INLINE int DevSetupGMbox(struct ar6k_device *pDev) { - pDev->GMboxEnabled = false; - return 0; -} - -#endif - -#ifdef ATH_AR6K_ENABLE_GMBOX - - /* GMBOX protocol modules must expose each of these internal APIs */ -HCI_TRANSPORT_HANDLE GMboxAttachProtocol(struct ar6k_device *pDev, struct hci_transport_config_info *pInfo); -int GMboxProtocolInstall(struct ar6k_device *pDev); -void GMboxProtocolUninstall(struct ar6k_device *pDev); - - /* API used by GMBOX protocol modules */ -struct ar6k_device *HTCGetAR6KDevice(void *HTCHandle); -#define DEV_GMBOX_SET_PROTOCOL(pDev,recv_callback,credits_pending,failure,statedump,context) \ -{ \ - (pDev)->GMboxInfo.pProtocolContext = (context); \ - (pDev)->GMboxInfo.pMessagePendingCallBack = (recv_callback); \ - (pDev)->GMboxInfo.pCreditsPendingCallback = (credits_pending); \ - (pDev)->GMboxInfo.pTargetFailureCallback = (failure); \ - (pDev)->GMboxInfo.pStateDumpCallback = (statedump); \ -} - -#define DEV_GMBOX_GET_PROTOCOL(pDev) (pDev)->GMboxInfo.pProtocolContext - -int DevGMboxWrite(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 WriteLength); -int DevGMboxRead(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 ReadLength); - -#define PROC_IO_ASYNC true -#define PROC_IO_SYNC false -typedef enum GMBOX_IRQ_ACTION_TYPE { - GMBOX_ACTION_NONE = 0, - GMBOX_DISABLE_ALL, - GMBOX_ERRORS_IRQ_ENABLE, - GMBOX_RECV_IRQ_ENABLE, - GMBOX_RECV_IRQ_DISABLE, - GMBOX_CREDIT_IRQ_ENABLE, - GMBOX_CREDIT_IRQ_DISABLE, -} GMBOX_IRQ_ACTION_TYPE; - -int DevGMboxIRQAction(struct ar6k_device *pDev, GMBOX_IRQ_ACTION_TYPE, bool AsyncMode); -int DevGMboxReadCreditCounter(struct ar6k_device *pDev, bool AsyncMode, int *pCredits); -int DevGMboxReadCreditSize(struct ar6k_device *pDev, int *pCreditSize); -int DevGMboxRecvLookAheadPeek(struct ar6k_device *pDev, u8 *pLookAheadBuffer, int *pLookAheadBytes); -int DevGMboxSetTargetInterrupt(struct ar6k_device *pDev, int SignalNumber, int AckTimeoutMS); - -#endif - -#endif /*AR6K_H_*/ diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c deleted file mode 100644 index d7af68f..0000000 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_events.c +++ /dev/null @@ -1,783 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="ar6k_events.c" company="Atheros"> -// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// AR6K Driver layer event handling (i.e. interrupts, message polling) -// -// Author(s): ="Atheros" -//============================================================================== - -#include "a_config.h" -#include "athdefs.h" -#include "hw/mbox_host_reg.h" -#include "a_osapi.h" -#include "../htc_debug.h" -#include "hif.h" -#include "htc_packet.h" -#include "ar6k.h" - -extern void AR6KFreeIOPacket(struct ar6k_device *pDev, struct htc_packet *pPacket); -extern struct htc_packet *AR6KAllocIOPacket(struct ar6k_device *pDev); - -static int DevServiceDebugInterrupt(struct ar6k_device *pDev); - -#define DELAY_PER_INTERVAL_MS 10 /* 10 MS delay per polling interval */ - -/* completion routine for ALL HIF layer async I/O */ -int DevRWCompletionHandler(void *context, int status) -{ - struct htc_packet *pPacket = (struct htc_packet *)context; - - AR_DEBUG_PRINTF(ATH_DEBUG_RECV, - ("+DevRWCompletionHandler (Pkt:0x%lX) , Status: %d \n", - (unsigned long)pPacket, - status)); - - COMPLETE_HTC_PACKET(pPacket,status); - - AR_DEBUG_PRINTF(ATH_DEBUG_RECV, - ("-DevRWCompletionHandler\n")); - - return 0; -} - -/* mailbox recv message polling */ -int DevPollMboxMsgRecv(struct ar6k_device *pDev, - u32 *pLookAhead, - int TimeoutMS) -{ - int status = 0; - int timeout = TimeoutMS/DELAY_PER_INTERVAL_MS; - - A_ASSERT(timeout > 0); - - AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+DevPollMboxMsgRecv \n")); - - while (true) { - - if (pDev->GetPendingEventsFunc != NULL) { - - struct hif_pending_events_info events; - -#ifdef THREAD_X - events.Polling =1; -#endif - - /* the HIF layer uses a special mechanism to get events, do this - * synchronously */ - status = pDev->GetPendingEventsFunc(pDev->HIFDevice, - &events, - NULL); - if (status) - { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to get pending events \n")); - break; - } - - if (events.Events & HIF_RECV_MSG_AVAIL) - { - /* there is a message available, the lookahead should be valid now */ - *pLookAhead = events.LookAhead; - - break; - } - } else { - - /* this is the standard HIF way.... */ - /* load the register table */ - status = HIFReadWrite(pDev->HIFDevice, - HOST_INT_STATUS_ADDRESS, - (u8 *)&pDev->IrqProcRegisters, - AR6K_IRQ_PROC_REGS_SIZE, - HIF_RD_SYNC_BYTE_INC, - NULL); - - if (status){ - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to read register table \n")); - break; - } - - /* check for MBOX data and valid lookahead */ - if (pDev->IrqProcRegisters.host_int_status & (1 << HTC_MAILBOX)) { - if (pDev->IrqProcRegisters.rx_lookahead_valid & (1 << HTC_MAILBOX)) - { - /* mailbox has a message and the look ahead is valid */ - *pLookAhead = pDev->IrqProcRegisters.rx_lookahead[HTC_MAILBOX]; - break; - } - } - - } - - timeout--; - - if (timeout <= 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, (" Timeout waiting for recv message \n")); - status = A_ERROR; - - /* check if the target asserted */ - if ( pDev->IrqProcRegisters.counter_int_status & AR6K_TARGET_DEBUG_INTR_MASK) { - /* target signaled an assert, process this pending interrupt - * this will call the target failure handler */ - DevServiceDebugInterrupt(pDev); - } - - break; - } - - /* delay a little */ - A_MDELAY(DELAY_PER_INTERVAL_MS); - AR_DEBUG_PRINTF(ATH_DEBUG_RECV,(" Retry Mbox Poll : %d \n",timeout)); - } - - AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-DevPollMboxMsgRecv \n")); - - return status; -} - -static int DevServiceCPUInterrupt(struct ar6k_device *pDev) -{ - int status; - u8 cpu_int_status; - u8 regBuffer[4]; - - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("CPU Interrupt\n")); - cpu_int_status = pDev->IrqProcRegisters.cpu_int_status & - pDev->IrqEnableRegisters.cpu_int_status_enable; - A_ASSERT(cpu_int_status); - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, - ("Valid interrupt source(s) in CPU_INT_STATUS: 0x%x\n", - cpu_int_status)); - - /* Clear the interrupt */ - pDev->IrqProcRegisters.cpu_int_status &= ~cpu_int_status; /* W1C */ - - /* set up the register transfer buffer to hit the register 4 times , this is done - * to make the access 4-byte aligned to mitigate issues with host bus interconnects that - * restrict bus transfer lengths to be a multiple of 4-bytes */ - - /* set W1C value to clear the interrupt, this hits the register first */ - regBuffer[0] = cpu_int_status; - /* the remaining 4 values are set to zero which have no-effect */ - regBuffer[1] = 0; - regBuffer[2] = 0; - regBuffer[3] = 0; - - status = HIFReadWrite(pDev->HIFDevice, - CPU_INT_STATUS_ADDRESS, - regBuffer, - 4, - HIF_WR_SYNC_BYTE_FIX, - NULL); - - A_ASSERT(status == 0); - return status; -} - - -static int DevServiceErrorInterrupt(struct ar6k_device *pDev) -{ - int status; - u8 error_int_status; - u8 regBuffer[4]; - - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("Error Interrupt\n")); - error_int_status = pDev->IrqProcRegisters.error_int_status & 0x0F; - A_ASSERT(error_int_status); - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, - ("Valid interrupt source(s) in ERROR_INT_STATUS: 0x%x\n", - error_int_status)); - - if (ERROR_INT_STATUS_WAKEUP_GET(error_int_status)) { - /* Wakeup */ - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("Error : Wakeup\n")); - } - - if (ERROR_INT_STATUS_RX_UNDERFLOW_GET(error_int_status)) { - /* Rx Underflow */ - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Error : Rx Underflow\n")); - } - - if (ERROR_INT_STATUS_TX_OVERFLOW_GET(error_int_status)) { - /* Tx Overflow */ - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Error : Tx Overflow\n")); - } - - /* Clear the interrupt */ - pDev->IrqProcRegisters.error_int_status &= ~error_int_status; /* W1C */ - - /* set up the register transfer buffer to hit the register 4 times , this is done - * to make the access 4-byte aligned to mitigate issues with host bus interconnects that - * restrict bus transfer lengths to be a multiple of 4-bytes */ - - /* set W1C value to clear the interrupt, this hits the register first */ - regBuffer[0] = error_int_status; - /* the remaining 4 values are set to zero which have no-effect */ - regBuffer[1] = 0; - regBuffer[2] = 0; - regBuffer[3] = 0; - - status = HIFReadWrite(pDev->HIFDevice, - ERROR_INT_STATUS_ADDRESS, - regBuffer, - 4, - HIF_WR_SYNC_BYTE_FIX, - NULL); - - A_ASSERT(status == 0); - return status; -} - -static int DevServiceDebugInterrupt(struct ar6k_device *pDev) -{ - u32 dummy; - int status; - - /* Send a target failure event to the application */ - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Target debug interrupt\n")); - - if (pDev->TargetFailureCallback != NULL) { - pDev->TargetFailureCallback(pDev->HTCContext); - } - - if (pDev->GMboxEnabled) { - DevNotifyGMboxTargetFailure(pDev); - } - - /* clear the interrupt , the debug error interrupt is - * counter 0 */ - /* read counter to clear interrupt */ - status = HIFReadWrite(pDev->HIFDevice, - COUNT_DEC_ADDRESS, - (u8 *)&dummy, - 4, - HIF_RD_SYNC_BYTE_INC, - NULL); - - A_ASSERT(status == 0); - return status; -} - -static int DevServiceCounterInterrupt(struct ar6k_device *pDev) -{ - u8 counter_int_status; - - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("Counter Interrupt\n")); - - counter_int_status = pDev->IrqProcRegisters.counter_int_status & - pDev->IrqEnableRegisters.counter_int_status_enable; - - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, - ("Valid interrupt source(s) in COUNTER_INT_STATUS: 0x%x\n", - counter_int_status)); - - /* Check if the debug interrupt is pending - * NOTE: other modules like GMBOX may use the counter interrupt for - * credit flow control on other counters, we only need to check for the debug assertion - * counter interrupt */ - if (counter_int_status & AR6K_TARGET_DEBUG_INTR_MASK) { - return DevServiceDebugInterrupt(pDev); - } - - return 0; -} - -/* callback when our fetch to get interrupt status registers completes */ -static void DevGetEventAsyncHandler(void *Context, struct htc_packet *pPacket) -{ - struct ar6k_device *pDev = (struct ar6k_device *)Context; - u32 lookAhead = 0; - bool otherInts = false; - - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevGetEventAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev)); - - do { - - if (pPacket->Status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - (" GetEvents I/O request failed, status:%d \n", pPacket->Status)); - /* bail out, don't unmask HIF interrupt */ - break; - } - - if (pDev->GetPendingEventsFunc != NULL) { - /* the HIF layer collected the information for us */ - struct hif_pending_events_info *pEvents = (struct hif_pending_events_info *)pPacket->pBuffer; - if (pEvents->Events & HIF_RECV_MSG_AVAIL) { - lookAhead = pEvents->LookAhead; - if (0 == lookAhead) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" DevGetEventAsyncHandler1, lookAhead is zero! \n")); - } - } - if (pEvents->Events & HIF_OTHER_EVENTS) { - otherInts = true; - } - } else { - /* standard interrupt table handling.... */ - struct ar6k_irq_proc_registers *pReg = (struct ar6k_irq_proc_registers *)pPacket->pBuffer; - u8 host_int_status; - - host_int_status = pReg->host_int_status & pDev->IrqEnableRegisters.int_status_enable; - - if (host_int_status & (1 << HTC_MAILBOX)) { - host_int_status &= ~(1 << HTC_MAILBOX); - if (pReg->rx_lookahead_valid & (1 << HTC_MAILBOX)) { - /* mailbox has a message and the look ahead is valid */ - lookAhead = pReg->rx_lookahead[HTC_MAILBOX]; - if (0 == lookAhead) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" DevGetEventAsyncHandler2, lookAhead is zero! \n")); - } - } - } - - if (host_int_status) { - /* there are other interrupts to handle */ - otherInts = true; - } - } - - if (otherInts || (lookAhead == 0)) { - /* if there are other interrupts to process, we cannot do this in the async handler so - * ack the interrupt which will cause our sync handler to run again - * if however there are no more messages, we can now ack the interrupt */ - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, - (" Acking interrupt from DevGetEventAsyncHandler (otherints:%d, lookahead:0x%X)\n", - otherInts, lookAhead)); - HIFAckInterrupt(pDev->HIFDevice); - } else { - int fetched = 0; - int status; - - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, - (" DevGetEventAsyncHandler : detected another message, lookahead :0x%X \n", - lookAhead)); - /* lookahead is non-zero and there are no other interrupts to service, - * go get the next message */ - status = pDev->MessagePendingCallback(pDev->HTCContext, &lookAhead, 1, NULL, &fetched); - - if (!status && !fetched) { - /* HTC layer could not pull out messages due to lack of resources, stop IRQ processing */ - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("MessagePendingCallback did not pull any messages, force-ack \n")); - DevAsyncIrqProcessComplete(pDev); - } - } - - } while (false); - - /* free this IO packet */ - AR6KFreeIOPacket(pDev,pPacket); - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevGetEventAsyncHandler \n")); -} - -/* called by the HTC layer when it wants us to check if the device has any more pending - * recv messages, this starts off a series of async requests to read interrupt registers */ -int DevCheckPendingRecvMsgsAsync(void *context) -{ - struct ar6k_device *pDev = (struct ar6k_device *)context; - int status = 0; - struct htc_packet *pIOPacket; - - /* this is called in an ASYNC only context, we may NOT block, sleep or call any apis that can - * cause us to switch contexts */ - - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevCheckPendingRecvMsgsAsync: (dev: 0x%lX)\n", (unsigned long)pDev)); - - do { - - if (HIF_DEVICE_IRQ_SYNC_ONLY == pDev->HifIRQProcessingMode) { - /* break the async processing chain right here, no need to continue. - * The DevDsrHandler() will handle things in a loop when things are driven - * synchronously */ - break; - } - - /* an optimization to bypass reading the IRQ status registers unecessarily which can re-wake - * the target, if upper layers determine that we are in a low-throughput mode, we can - * rely on taking another interrupt rather than re-checking the status registers which can - * re-wake the target */ - if (pDev->RecheckIRQStatusCnt == 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("Bypassing IRQ Status re-check, re-acking HIF interrupts\n")); - /* ack interrupt */ - HIFAckInterrupt(pDev->HIFDevice); - break; - } - - /* first allocate one of our HTC packets we created for async I/O - * we reuse HTC packet definitions so that we can use the completion mechanism - * in DevRWCompletionHandler() */ - pIOPacket = AR6KAllocIOPacket(pDev); - - if (NULL == pIOPacket) { - /* there should be only 1 asynchronous request out at a time to read these registers - * so this should actually never happen */ - status = A_NO_MEMORY; - A_ASSERT(false); - break; - } - - /* stick in our completion routine when the I/O operation completes */ - pIOPacket->Completion = DevGetEventAsyncHandler; - pIOPacket->pContext = pDev; - - if (pDev->GetPendingEventsFunc) { - /* HIF layer has it's own mechanism, pass the IO to it.. */ - status = pDev->GetPendingEventsFunc(pDev->HIFDevice, - (struct hif_pending_events_info *)pIOPacket->pBuffer, - pIOPacket); - - } else { - /* standard way, read the interrupt register table asynchronously again */ - status = HIFReadWrite(pDev->HIFDevice, - HOST_INT_STATUS_ADDRESS, - pIOPacket->pBuffer, - AR6K_IRQ_PROC_REGS_SIZE, - HIF_RD_ASYNC_BYTE_INC, - pIOPacket); - } - - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,(" Async IO issued to get interrupt status...\n")); - } while (false); - - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevCheckPendingRecvMsgsAsync \n")); - - return status; -} - -void DevAsyncIrqProcessComplete(struct ar6k_device *pDev) -{ - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("DevAsyncIrqProcessComplete - forcing HIF IRQ ACK \n")); - HIFAckInterrupt(pDev->HIFDevice); -} - -/* process pending interrupts synchronously */ -static int ProcessPendingIRQs(struct ar6k_device *pDev, bool *pDone, bool *pASyncProcessing) -{ - int status = 0; - u8 host_int_status = 0; - u32 lookAhead = 0; - - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+ProcessPendingIRQs: (dev: 0x%lX)\n", (unsigned long)pDev)); - - /*** NOTE: the HIF implementation guarantees that the context of this call allows - * us to perform SYNCHRONOUS I/O, that is we can block, sleep or call any API that - * can block or switch thread/task ontexts. - * This is a fully schedulable context. - * */ - do { - - if (pDev->IrqEnableRegisters.int_status_enable == 0) { - /* interrupt enables have been cleared, do not try to process any pending interrupts that - * may result in more bus transactions. The target may be unresponsive at this - * point. */ - break; - } - - if (pDev->GetPendingEventsFunc != NULL) { - struct hif_pending_events_info events; - -#ifdef THREAD_X - events.Polling= 0; -#endif - /* the HIF layer uses a special mechanism to get events - * get this synchronously */ - status = pDev->GetPendingEventsFunc(pDev->HIFDevice, - &events, - NULL); - - if (status) { - break; - } - - if (events.Events & HIF_RECV_MSG_AVAIL) { - lookAhead = events.LookAhead; - if (0 == lookAhead) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" ProcessPendingIRQs1 lookAhead is zero! \n")); - } - } - - if (!(events.Events & HIF_OTHER_EVENTS) || - !(pDev->IrqEnableRegisters.int_status_enable & OTHER_INTS_ENABLED)) { - /* no need to read the register table, no other interesting interrupts. - * Some interfaces (like SPI) can shadow interrupt sources without - * requiring the host to do a full table read */ - break; - } - - /* otherwise fall through and read the register table */ - } - - /* - * Read the first 28 bytes of the HTC register table. This will yield us - * the value of different int status registers and the lookahead - * registers. - * length = sizeof(int_status) + sizeof(cpu_int_status) + - * sizeof(error_int_status) + sizeof(counter_int_status) + - * sizeof(mbox_frame) + sizeof(rx_lookahead_valid) + - * sizeof(hole) + sizeof(rx_lookahead) + - * sizeof(int_status_enable) + sizeof(cpu_int_status_enable) + - * sizeof(error_status_enable) + - * sizeof(counter_int_status_enable); - * - */ -#ifdef CONFIG_MMC_SDHCI_S3C - pDev->IrqProcRegisters.host_int_status = 0; - pDev->IrqProcRegisters.rx_lookahead_valid = 0; - pDev->IrqProcRegisters.host_int_status2 = 0; - pDev->IrqProcRegisters.rx_lookahead[0] = 0; - pDev->IrqProcRegisters.rx_lookahead[1] = 0xaaa5555; -#endif /* CONFIG_MMC_SDHCI_S3C */ - status = HIFReadWrite(pDev->HIFDevice, - HOST_INT_STATUS_ADDRESS, - (u8 *)&pDev->IrqProcRegisters, - AR6K_IRQ_PROC_REGS_SIZE, - HIF_RD_SYNC_BYTE_INC, - NULL); - - if (status) { - break; - } - -#ifdef ATH_DEBUG_MODULE - if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_IRQ)) { - DevDumpRegisters(pDev, - &pDev->IrqProcRegisters, - &pDev->IrqEnableRegisters); - } -#endif - - /* Update only those registers that are enabled */ - host_int_status = pDev->IrqProcRegisters.host_int_status & - pDev->IrqEnableRegisters.int_status_enable; - - if (NULL == pDev->GetPendingEventsFunc) { - /* only look at mailbox status if the HIF layer did not provide this function, - * on some HIF interfaces reading the RX lookahead is not valid to do */ - if (host_int_status & (1 << HTC_MAILBOX)) { - /* mask out pending mailbox value, we use "lookAhead" as the real flag for - * mailbox processing below */ - host_int_status &= ~(1 << HTC_MAILBOX); - if (pDev->IrqProcRegisters.rx_lookahead_valid & (1 << HTC_MAILBOX)) { - /* mailbox has a message and the look ahead is valid */ - lookAhead = pDev->IrqProcRegisters.rx_lookahead[HTC_MAILBOX]; - if (0 == lookAhead) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" ProcessPendingIRQs2, lookAhead is zero! \n")); - } - } - } - } else { - /* not valid to check if the HIF has another mechanism for reading mailbox pending status*/ - host_int_status &= ~(1 << HTC_MAILBOX); - } - - if (pDev->GMboxEnabled) { - /*call GMBOX layer to process any interrupts of interest */ - status = DevCheckGMboxInterrupts(pDev); - } - - } while (false); - - - do { - - /* did the interrupt status fetches succeed? */ - if (status) { - break; - } - - if ((0 == host_int_status) && (0 == lookAhead)) { - /* nothing to process, the caller can use this to break out of a loop */ - *pDone = true; - break; - } - - if (lookAhead != 0) { - int fetched = 0; - - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("Pending mailbox message, LookAhead: 0x%X\n",lookAhead)); - /* Mailbox Interrupt, the HTC layer may issue async requests to empty the - * mailbox... - * When emptying the recv mailbox we use the async handler above called from the - * completion routine of the callers read request. This can improve performance - * by reducing context switching when we rapidly pull packets */ - status = pDev->MessagePendingCallback(pDev->HTCContext, &lookAhead, 1, pASyncProcessing, &fetched); - if (status) { - break; - } - - if (!fetched) { - /* HTC could not pull any messages out due to lack of resources */ - /* force DSR handler to ack the interrupt */ - *pASyncProcessing = false; - pDev->RecheckIRQStatusCnt = 0; - } - } - - /* now handle the rest of them */ - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, - (" Valid interrupt source(s) for OTHER interrupts: 0x%x\n", - host_int_status)); - - if (HOST_INT_STATUS_CPU_GET(host_int_status)) { - /* CPU Interrupt */ - status = DevServiceCPUInterrupt(pDev); - if (status){ - break; - } - } - - if (HOST_INT_STATUS_ERROR_GET(host_int_status)) { - /* Error Interrupt */ - status = DevServiceErrorInterrupt(pDev); - if (status){ - break; - } - } - - if (HOST_INT_STATUS_COUNTER_GET(host_int_status)) { - /* Counter Interrupt */ - status = DevServiceCounterInterrupt(pDev); - if (status){ - break; - } - } - - } while (false); - - /* an optimization to bypass reading the IRQ status registers unecessarily which can re-wake - * the target, if upper layers determine that we are in a low-throughput mode, we can - * rely on taking another interrupt rather than re-checking the status registers which can - * re-wake the target. - * - * NOTE : for host interfaces that use the special GetPendingEventsFunc, this optimization cannot - * be used due to possible side-effects. For example, SPI requires the host to drain all - * messages from the mailbox before exiting the ISR routine. */ - if (!(*pASyncProcessing) && (pDev->RecheckIRQStatusCnt == 0) && (pDev->GetPendingEventsFunc == NULL)) { - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("Bypassing IRQ Status re-check, forcing done \n")); - *pDone = true; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-ProcessPendingIRQs: (done:%d, async:%d) status=%d \n", - *pDone, *pASyncProcessing, status)); - - return status; -} - - -/* Synchronousinterrupt handler, this handler kicks off all interrupt processing.*/ -int DevDsrHandler(void *context) -{ - struct ar6k_device *pDev = (struct ar6k_device *)context; - int status = 0; - bool done = false; - bool asyncProc = false; - - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevDsrHandler: (dev: 0x%lX)\n", (unsigned long)pDev)); - - /* reset the recv counter that tracks when we need to yield from the DSR */ - pDev->CurrentDSRRecvCount = 0; - /* reset counter used to flag a re-scan of IRQ status registers on the target */ - pDev->RecheckIRQStatusCnt = 0; - - while (!done) { - status = ProcessPendingIRQs(pDev, &done, &asyncProc); - if (status) { - break; - } - - if (HIF_DEVICE_IRQ_SYNC_ONLY == pDev->HifIRQProcessingMode) { - /* the HIF layer does not allow async IRQ processing, override the asyncProc flag */ - asyncProc = false; - /* this will cause us to re-enter ProcessPendingIRQ() and re-read interrupt status registers. - * this has a nice side effect of blocking us until all async read requests are completed. - * This behavior is required on some HIF implementations that do not allow ASYNC - * processing in interrupt handlers (like Windows CE) */ - - if (pDev->DSRCanYield && DEV_CHECK_RECV_YIELD(pDev)) { - /* ProcessPendingIRQs() pulled enough recv messages to satisfy the yield count, stop - * checking for more messages and return */ - break; - } - } - - if (asyncProc) { - /* the function performed some async I/O for performance, we - need to exit the ISR immediately, the check below will prevent the interrupt from being - Ack'd while we handle it asynchronously */ - break; - } - - } - - if (!status && !asyncProc) { - /* Ack the interrupt only if : - * 1. we did not get any errors in processing interrupts - * 2. there are no outstanding async processing requests */ - if (pDev->DSRCanYield) { - /* if the DSR can yield do not ACK the interrupt, there could be more pending messages. - * The HIF layer must ACK the interrupt on behalf of HTC */ - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,(" Yield in effect (cur RX count: %d) \n", pDev->CurrentDSRRecvCount)); - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,(" Acking interrupt from DevDsrHandler \n")); - HIFAckInterrupt(pDev->HIFDevice); - } - } - - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevDsrHandler \n")); - return status; -} - -#ifdef ATH_DEBUG_MODULE -void DumpAR6KDevState(struct ar6k_device *pDev) -{ - int status; - struct ar6k_irq_enable_registers regs; - struct ar6k_irq_proc_registers procRegs; - - LOCK_AR6K(pDev); - /* copy into our temp area */ - memcpy(®s,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE); - UNLOCK_AR6K(pDev); - - /* load the register table from the device */ - status = HIFReadWrite(pDev->HIFDevice, - HOST_INT_STATUS_ADDRESS, - (u8 *)&procRegs, - AR6K_IRQ_PROC_REGS_SIZE, - HIF_RD_SYNC_BYTE_INC, - NULL); - - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("DumpAR6KDevState : Failed to read register table (%d) \n",status)); - return; - } - - DevDumpRegisters(pDev,&procRegs,®s); - - if (pDev->GMboxInfo.pStateDumpCallback != NULL) { - pDev->GMboxInfo.pStateDumpCallback(pDev->GMboxInfo.pProtocolContext); - } - - /* dump any bus state at the HIF layer */ - HIFConfigureDevice(pDev->HIFDevice,HIF_DEVICE_DEBUG_BUS_STATE,NULL,0); - -} -#endif - - diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c deleted file mode 100644 index 725540f..0000000 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox.c +++ /dev/null @@ -1,755 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="ar6k_gmbox.c" company="Atheros"> -// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Generic MBOX API implementation -// -// Author(s): ="Atheros" -//============================================================================== -#include "a_config.h" -#include "athdefs.h" -#include "a_osapi.h" -#include "../htc_debug.h" -#include "hif.h" -#include "htc_packet.h" -#include "ar6k.h" -#include "hw/mbox_host_reg.h" -#include "gmboxif.h" - -/* - * This file provides management functions and a toolbox for GMBOX protocol modules. - * Only one protocol module can be installed at a time. The determination of which protocol - * module is installed is determined at compile time. - * - */ -#ifdef ATH_AR6K_ENABLE_GMBOX - /* GMBOX definitions */ -#define GMBOX_INT_STATUS_ENABLE_REG 0x488 -#define GMBOX_INT_STATUS_RX_DATA (1 << 0) -#define GMBOX_INT_STATUS_TX_OVERFLOW (1 << 1) -#define GMBOX_INT_STATUS_RX_OVERFLOW (1 << 2) - -#define GMBOX_LOOKAHEAD_MUX_REG 0x498 -#define GMBOX_LA_MUX_OVERRIDE_2_3 (1 << 0) - -#define AR6K_GMBOX_CREDIT_DEC_ADDRESS (COUNT_DEC_ADDRESS + 4 * AR6K_GMBOX_CREDIT_COUNTER) -#define AR6K_GMBOX_CREDIT_SIZE_ADDRESS (COUNT_ADDRESS + AR6K_GMBOX_CREDIT_SIZE_COUNTER) - - - /* external APIs for allocating and freeing internal I/O packets to handle ASYNC I/O */ -extern void AR6KFreeIOPacket(struct ar6k_device *pDev, struct htc_packet *pPacket); -extern struct htc_packet *AR6KAllocIOPacket(struct ar6k_device *pDev); - - -/* callback when our fetch to enable/disable completes */ -static void DevGMboxIRQActionAsyncHandler(void *Context, struct htc_packet *pPacket) -{ - struct ar6k_device *pDev = (struct ar6k_device *)Context; - - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevGMboxIRQActionAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev)); - - if (pPacket->Status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("IRQAction Operation (%d) failed! status:%d \n", pPacket->PktInfo.AsRx.HTCRxFlags,pPacket->Status)); - } - /* free this IO packet */ - AR6KFreeIOPacket(pDev,pPacket); - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevGMboxIRQActionAsyncHandler \n")); -} - -static int DevGMboxCounterEnableDisable(struct ar6k_device *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, bool AsyncMode) -{ - int status = 0; - struct ar6k_irq_enable_registers regs; - struct htc_packet *pIOPacket = NULL; - - LOCK_AR6K(pDev); - - if (GMBOX_CREDIT_IRQ_ENABLE == IrqAction) { - pDev->GMboxInfo.CreditCountIRQEnabled = true; - pDev->IrqEnableRegisters.counter_int_status_enable |= - COUNTER_INT_STATUS_ENABLE_BIT_SET(1 << AR6K_GMBOX_CREDIT_COUNTER); - pDev->IrqEnableRegisters.int_status_enable |= INT_STATUS_ENABLE_COUNTER_SET(0x01); - } else { - pDev->GMboxInfo.CreditCountIRQEnabled = false; - pDev->IrqEnableRegisters.counter_int_status_enable &= - ~(COUNTER_INT_STATUS_ENABLE_BIT_SET(1 << AR6K_GMBOX_CREDIT_COUNTER)); - } - /* copy into our temp area */ - memcpy(®s,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE); - - UNLOCK_AR6K(pDev); - - do { - - if (AsyncMode) { - - pIOPacket = AR6KAllocIOPacket(pDev); - - if (NULL == pIOPacket) { - status = A_NO_MEMORY; - A_ASSERT(false); - break; - } - - /* copy values to write to our async I/O buffer */ - memcpy(pIOPacket->pBuffer,&pDev->IrqEnableRegisters,AR6K_IRQ_ENABLE_REGS_SIZE); - - /* stick in our completion routine when the I/O operation completes */ - pIOPacket->Completion = DevGMboxIRQActionAsyncHandler; - pIOPacket->pContext = pDev; - pIOPacket->PktInfo.AsRx.HTCRxFlags = IrqAction; - /* write it out asynchronously */ - HIFReadWrite(pDev->HIFDevice, - INT_STATUS_ENABLE_ADDRESS, - pIOPacket->pBuffer, - AR6K_IRQ_ENABLE_REGS_SIZE, - HIF_WR_ASYNC_BYTE_INC, - pIOPacket); - - pIOPacket = NULL; - break; - } - - /* if we get here we are doing it synchronously */ - status = HIFReadWrite(pDev->HIFDevice, - INT_STATUS_ENABLE_ADDRESS, - ®s.int_status_enable, - AR6K_IRQ_ENABLE_REGS_SIZE, - HIF_WR_SYNC_BYTE_INC, - NULL); - } while (false); - - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - (" IRQAction Operation (%d) failed! status:%d \n", IrqAction, status)); - } else { - if (!AsyncMode) { - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, - (" IRQAction Operation (%d) success \n", IrqAction)); - } - } - - if (pIOPacket != NULL) { - AR6KFreeIOPacket(pDev,pIOPacket); - } - - return status; -} - - -int DevGMboxIRQAction(struct ar6k_device *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, bool AsyncMode) -{ - int status = 0; - struct htc_packet *pIOPacket = NULL; - u8 GMboxIntControl[4]; - - if (GMBOX_CREDIT_IRQ_ENABLE == IrqAction) { - return DevGMboxCounterEnableDisable(pDev, GMBOX_CREDIT_IRQ_ENABLE, AsyncMode); - } else if(GMBOX_CREDIT_IRQ_DISABLE == IrqAction) { - return DevGMboxCounterEnableDisable(pDev, GMBOX_CREDIT_IRQ_DISABLE, AsyncMode); - } - - if (GMBOX_DISABLE_ALL == IrqAction) { - /* disable credit IRQ, those are on a different set of registers */ - DevGMboxCounterEnableDisable(pDev, GMBOX_CREDIT_IRQ_DISABLE, AsyncMode); - } - - /* take the lock to protect interrupt enable shadows */ - LOCK_AR6K(pDev); - - switch (IrqAction) { - - case GMBOX_DISABLE_ALL: - pDev->GMboxControlRegisters.int_status_enable = 0; - break; - case GMBOX_ERRORS_IRQ_ENABLE: - pDev->GMboxControlRegisters.int_status_enable |= GMBOX_INT_STATUS_TX_OVERFLOW | - GMBOX_INT_STATUS_RX_OVERFLOW; - break; - case GMBOX_RECV_IRQ_ENABLE: - pDev->GMboxControlRegisters.int_status_enable |= GMBOX_INT_STATUS_RX_DATA; - break; - case GMBOX_RECV_IRQ_DISABLE: - pDev->GMboxControlRegisters.int_status_enable &= ~GMBOX_INT_STATUS_RX_DATA; - break; - case GMBOX_ACTION_NONE: - default: - A_ASSERT(false); - break; - } - - GMboxIntControl[0] = pDev->GMboxControlRegisters.int_status_enable; - GMboxIntControl[1] = GMboxIntControl[0]; - GMboxIntControl[2] = GMboxIntControl[0]; - GMboxIntControl[3] = GMboxIntControl[0]; - - UNLOCK_AR6K(pDev); - - do { - - if (AsyncMode) { - - pIOPacket = AR6KAllocIOPacket(pDev); - - if (NULL == pIOPacket) { - status = A_NO_MEMORY; - A_ASSERT(false); - break; - } - - /* copy values to write to our async I/O buffer */ - memcpy(pIOPacket->pBuffer,GMboxIntControl,sizeof(GMboxIntControl)); - - /* stick in our completion routine when the I/O operation completes */ - pIOPacket->Completion = DevGMboxIRQActionAsyncHandler; - pIOPacket->pContext = pDev; - pIOPacket->PktInfo.AsRx.HTCRxFlags = IrqAction; - /* write it out asynchronously */ - HIFReadWrite(pDev->HIFDevice, - GMBOX_INT_STATUS_ENABLE_REG, - pIOPacket->pBuffer, - sizeof(GMboxIntControl), - HIF_WR_ASYNC_BYTE_FIX, - pIOPacket); - pIOPacket = NULL; - break; - } - - /* if we get here we are doing it synchronously */ - - status = HIFReadWrite(pDev->HIFDevice, - GMBOX_INT_STATUS_ENABLE_REG, - GMboxIntControl, - sizeof(GMboxIntControl), - HIF_WR_SYNC_BYTE_FIX, - NULL); - - } while (false); - - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - (" IRQAction Operation (%d) failed! status:%d \n", IrqAction, status)); - } else { - if (!AsyncMode) { - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, - (" IRQAction Operation (%d) success \n", IrqAction)); - } - } - - if (pIOPacket != NULL) { - AR6KFreeIOPacket(pDev,pIOPacket); - } - - return status; -} - -void DevCleanupGMbox(struct ar6k_device *pDev) -{ - if (pDev->GMboxEnabled) { - pDev->GMboxEnabled = false; - GMboxProtocolUninstall(pDev); - } -} - -int DevSetupGMbox(struct ar6k_device *pDev) -{ - int status = 0; - u8 muxControl[4]; - - do { - - if (0 == pDev->MailBoxInfo.GMboxAddress) { - break; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_ANY,(" GMBOX Advertised: Address:0x%X , size:%d \n", - pDev->MailBoxInfo.GMboxAddress, pDev->MailBoxInfo.GMboxSize)); - - status = DevGMboxIRQAction(pDev, GMBOX_DISABLE_ALL, PROC_IO_SYNC); - - if (status) { - break; - } - - /* write to mailbox look ahead mux control register, we want the - * GMBOX lookaheads to appear on lookaheads 2 and 3 - * the register is 1-byte wide so we need to hit it 4 times to align the operation - * to 4-bytes */ - muxControl[0] = GMBOX_LA_MUX_OVERRIDE_2_3; - muxControl[1] = GMBOX_LA_MUX_OVERRIDE_2_3; - muxControl[2] = GMBOX_LA_MUX_OVERRIDE_2_3; - muxControl[3] = GMBOX_LA_MUX_OVERRIDE_2_3; - - status = HIFReadWrite(pDev->HIFDevice, - GMBOX_LOOKAHEAD_MUX_REG, - muxControl, - sizeof(muxControl), - HIF_WR_SYNC_BYTE_FIX, /* hit this register 4 times */ - NULL); - - if (status) { - break; - } - - status = GMboxProtocolInstall(pDev); - - if (status) { - break; - } - - pDev->GMboxEnabled = true; - - } while (false); - - return status; -} - -int DevCheckGMboxInterrupts(struct ar6k_device *pDev) -{ - int status = 0; - u8 counter_int_status; - int credits; - u8 host_int_status2; - - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("+DevCheckGMboxInterrupts \n")); - - /* the caller guarantees that this is a context that allows for blocking I/O */ - - do { - - host_int_status2 = pDev->IrqProcRegisters.host_int_status2 & - pDev->GMboxControlRegisters.int_status_enable; - - if (host_int_status2 & GMBOX_INT_STATUS_TX_OVERFLOW) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("GMBOX : TX Overflow \n")); - status = A_ECOMM; - } - - if (host_int_status2 & GMBOX_INT_STATUS_RX_OVERFLOW) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("GMBOX : RX Overflow \n")); - status = A_ECOMM; - } - - if (status) { - if (pDev->GMboxInfo.pTargetFailureCallback != NULL) { - pDev->GMboxInfo.pTargetFailureCallback(pDev->GMboxInfo.pProtocolContext, status); - } - break; - } - - if (host_int_status2 & GMBOX_INT_STATUS_RX_DATA) { - if (pDev->IrqProcRegisters.gmbox_rx_avail > 0) { - A_ASSERT(pDev->GMboxInfo.pMessagePendingCallBack != NULL); - status = pDev->GMboxInfo.pMessagePendingCallBack( - pDev->GMboxInfo.pProtocolContext, - (u8 *)&pDev->IrqProcRegisters.rx_gmbox_lookahead_alias[0], - pDev->IrqProcRegisters.gmbox_rx_avail); - } - } - - if (status) { - break; - } - - counter_int_status = pDev->IrqProcRegisters.counter_int_status & - pDev->IrqEnableRegisters.counter_int_status_enable; - - /* check if credit interrupt is pending */ - if (counter_int_status & (COUNTER_INT_STATUS_ENABLE_BIT_SET(1 << AR6K_GMBOX_CREDIT_COUNTER))) { - - /* do synchronous read */ - status = DevGMboxReadCreditCounter(pDev, PROC_IO_SYNC, &credits); - - if (status) { - break; - } - - A_ASSERT(pDev->GMboxInfo.pCreditsPendingCallback != NULL); - status = pDev->GMboxInfo.pCreditsPendingCallback(pDev->GMboxInfo.pProtocolContext, - credits, - pDev->GMboxInfo.CreditCountIRQEnabled); - } - - } while (false); - - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ, ("-DevCheckGMboxInterrupts (%d) \n",status)); - - return status; -} - - -int DevGMboxWrite(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 WriteLength) -{ - u32 paddedLength; - bool sync = (pPacket->Completion == NULL) ? true : false; - int status; - u32 address; - - /* adjust the length to be a multiple of block size if appropriate */ - paddedLength = DEV_CALC_SEND_PADDED_LEN(pDev, WriteLength); - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, - ("DevGMboxWrite, Padded Length: %d Mbox:0x%X (mode:%s)\n", - WriteLength, - pDev->MailBoxInfo.GMboxAddress, - sync ? "SYNC" : "ASYNC")); - - /* last byte of packet has to hit the EOM marker */ - address = pDev->MailBoxInfo.GMboxAddress + pDev->MailBoxInfo.GMboxSize - paddedLength; - - status = HIFReadWrite(pDev->HIFDevice, - address, - pPacket->pBuffer, - paddedLength, /* the padded length */ - sync ? HIF_WR_SYNC_BLOCK_INC : HIF_WR_ASYNC_BLOCK_INC, - sync ? NULL : pPacket); /* pass the packet as the context to the HIF request */ - - if (sync) { - pPacket->Status = status; - } else { - if (status == A_PENDING) { - status = 0; - } - } - - return status; -} - -int DevGMboxRead(struct ar6k_device *pDev, struct htc_packet *pPacket, u32 ReadLength) -{ - - u32 paddedLength; - int status; - bool sync = (pPacket->Completion == NULL) ? true : false; - - /* adjust the length to be a multiple of block size if appropriate */ - paddedLength = DEV_CALC_RECV_PADDED_LEN(pDev, ReadLength); - - if (paddedLength > pPacket->BufferLength) { - A_ASSERT(false); - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("DevGMboxRead, Not enough space for padlen:%d recvlen:%d bufferlen:%d \n", - paddedLength,ReadLength,pPacket->BufferLength)); - if (pPacket->Completion != NULL) { - COMPLETE_HTC_PACKET(pPacket,A_EINVAL); - return 0; - } - return A_EINVAL; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_RECV, - ("DevGMboxRead (0x%lX : hdr:0x%X) Padded Length: %d Mbox:0x%X (mode:%s)\n", - (unsigned long)pPacket, pPacket->PktInfo.AsRx.ExpectedHdr, - paddedLength, - pDev->MailBoxInfo.GMboxAddress, - sync ? "SYNC" : "ASYNC")); - - status = HIFReadWrite(pDev->HIFDevice, - pDev->MailBoxInfo.GMboxAddress, - pPacket->pBuffer, - paddedLength, - sync ? HIF_RD_SYNC_BLOCK_FIX : HIF_RD_ASYNC_BLOCK_FIX, - sync ? NULL : pPacket); /* pass the packet as the context to the HIF request */ - - if (sync) { - pPacket->Status = status; - } - - return status; -} - - -static int ProcessCreditCounterReadBuffer(u8 *pBuffer, int Length) -{ - int credits = 0; - - /* theory of how this works: - * We read the credit decrement register multiple times on a byte-wide basis. - * The number of times (32) aligns the I/O operation to be a multiple of 4 bytes and provides a - * reasonable chance to acquire "all" pending credits in a single I/O operation. - * - * Once we obtain the filled buffer, we can walk through it looking for credit decrement transitions. - * Each non-zero byte represents a single credit decrement (which is a credit given back to the host) - * For example if the target provides 3 credits and added 4 more during the 32-byte read operation the following - * pattern "could" appear: - * - * 0x3 0x2 0x1 0x0 0x0 0x0 0x0 0x0 0x1 0x0 0x1 0x0 0x1 0x0 0x1 0x0 ......rest zeros - * <---------> <-----------------------------> - * \_ credits aleady there \_ target adding 4 more credits - * - * The total available credits would be 7, since there are 7 non-zero bytes in the buffer. - * - * */ - - if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) { - DebugDumpBytes(pBuffer, Length, "GMBOX Credit read buffer"); - } - - while (Length) { - if (*pBuffer != 0) { - credits++; - } - Length--; - pBuffer++; - } - - return credits; -} - - -/* callback when our fetch to enable/disable completes */ -static void DevGMboxReadCreditsAsyncHandler(void *Context, struct htc_packet *pPacket) -{ - struct ar6k_device *pDev = (struct ar6k_device *)Context; - - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevGMboxReadCreditsAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev)); - - if (pPacket->Status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("Read Credit Operation failed! status:%d \n", pPacket->Status)); - } else { - int credits = 0; - credits = ProcessCreditCounterReadBuffer(pPacket->pBuffer, AR6K_REG_IO_BUFFER_SIZE); - pDev->GMboxInfo.pCreditsPendingCallback(pDev->GMboxInfo.pProtocolContext, - credits, - pDev->GMboxInfo.CreditCountIRQEnabled); - - - } - /* free this IO packet */ - AR6KFreeIOPacket(pDev,pPacket); - AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("-DevGMboxReadCreditsAsyncHandler \n")); -} - -int DevGMboxReadCreditCounter(struct ar6k_device *pDev, bool AsyncMode, int *pCredits) -{ - int status = 0; - struct htc_packet *pIOPacket = NULL; - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+DevGMboxReadCreditCounter (%s) \n", AsyncMode ? "ASYNC" : "SYNC")); - - do { - - pIOPacket = AR6KAllocIOPacket(pDev); - - if (NULL == pIOPacket) { - status = A_NO_MEMORY; - A_ASSERT(false); - break; - } - - A_MEMZERO(pIOPacket->pBuffer,AR6K_REG_IO_BUFFER_SIZE); - - if (AsyncMode) { - /* stick in our completion routine when the I/O operation completes */ - pIOPacket->Completion = DevGMboxReadCreditsAsyncHandler; - pIOPacket->pContext = pDev; - /* read registers asynchronously */ - HIFReadWrite(pDev->HIFDevice, - AR6K_GMBOX_CREDIT_DEC_ADDRESS, - pIOPacket->pBuffer, - AR6K_REG_IO_BUFFER_SIZE, /* hit the register multiple times */ - HIF_RD_ASYNC_BYTE_FIX, - pIOPacket); - pIOPacket = NULL; - break; - } - - pIOPacket->Completion = NULL; - /* if we get here we are doing it synchronously */ - status = HIFReadWrite(pDev->HIFDevice, - AR6K_GMBOX_CREDIT_DEC_ADDRESS, - pIOPacket->pBuffer, - AR6K_REG_IO_BUFFER_SIZE, - HIF_RD_SYNC_BYTE_FIX, - NULL); - } while (false); - - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - (" DevGMboxReadCreditCounter failed! status:%d \n", status)); - } - - if (pIOPacket != NULL) { - if (!status) { - /* sync mode processing */ - *pCredits = ProcessCreditCounterReadBuffer(pIOPacket->pBuffer, AR6K_REG_IO_BUFFER_SIZE); - } - AR6KFreeIOPacket(pDev,pIOPacket); - } - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-DevGMboxReadCreditCounter (%s) (%d) \n", - AsyncMode ? "ASYNC" : "SYNC", status)); - - return status; -} - -int DevGMboxReadCreditSize(struct ar6k_device *pDev, int *pCreditSize) -{ - int status; - u8 buffer[4]; - - status = HIFReadWrite(pDev->HIFDevice, - AR6K_GMBOX_CREDIT_SIZE_ADDRESS, - buffer, - sizeof(buffer), - HIF_RD_SYNC_BYTE_FIX, /* hit the register 4 times to align the I/O */ - NULL); - - if (!status) { - if (buffer[0] == 0) { - *pCreditSize = 256; - } else { - *pCreditSize = buffer[0]; - } - - } - - return status; -} - -void DevNotifyGMboxTargetFailure(struct ar6k_device *pDev) -{ - /* Target ASSERTED!!! */ - if (pDev->GMboxInfo.pTargetFailureCallback != NULL) { - pDev->GMboxInfo.pTargetFailureCallback(pDev->GMboxInfo.pProtocolContext, A_HARDWARE); - } -} - -int DevGMboxRecvLookAheadPeek(struct ar6k_device *pDev, u8 *pLookAheadBuffer, int *pLookAheadBytes) -{ - - int status = 0; - struct ar6k_irq_proc_registers procRegs; - int maxCopy; - - do { - /* on entry the caller provides the length of the lookahead buffer */ - if (*pLookAheadBytes > sizeof(procRegs.rx_gmbox_lookahead_alias)) { - A_ASSERT(false); - status = A_EINVAL; - break; - } - - maxCopy = *pLookAheadBytes; - *pLookAheadBytes = 0; - /* load the register table from the device */ - status = HIFReadWrite(pDev->HIFDevice, - HOST_INT_STATUS_ADDRESS, - (u8 *)&procRegs, - AR6K_IRQ_PROC_REGS_SIZE, - HIF_RD_SYNC_BYTE_INC, - NULL); - - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("DevGMboxRecvLookAheadPeek : Failed to read register table (%d) \n",status)); - break; - } - - if (procRegs.gmbox_rx_avail > 0) { - int bytes = procRegs.gmbox_rx_avail > maxCopy ? maxCopy : procRegs.gmbox_rx_avail; - memcpy(pLookAheadBuffer,&procRegs.rx_gmbox_lookahead_alias[0],bytes); - *pLookAheadBytes = bytes; - } - - } while (false); - - return status; -} - -int DevGMboxSetTargetInterrupt(struct ar6k_device *pDev, int Signal, int AckTimeoutMS) -{ - int status = 0; - int i; - u8 buffer[4]; - - A_MEMZERO(buffer, sizeof(buffer)); - - do { - - if (Signal >= MBOX_SIG_HCI_BRIDGE_MAX) { - status = A_EINVAL; - break; - } - - /* set the last buffer to do the actual signal trigger */ - buffer[3] = (1 << Signal); - - status = HIFReadWrite(pDev->HIFDevice, - INT_WLAN_ADDRESS, - buffer, - sizeof(buffer), - HIF_WR_SYNC_BYTE_FIX, /* hit the register 4 times to align the I/O */ - NULL); - - if (status) { - break; - } - - } while (false); - - - if (!status) { - /* now read back the register to see if the bit cleared */ - while (AckTimeoutMS) { - status = HIFReadWrite(pDev->HIFDevice, - INT_WLAN_ADDRESS, - buffer, - sizeof(buffer), - HIF_RD_SYNC_BYTE_FIX, - NULL); - - if (status) { - break; - } - - for (i = 0; i < sizeof(buffer); i++) { - if (buffer[i] & (1 << Signal)) { - /* bit is still set */ - break; - } - } - - if (i >= sizeof(buffer)) { - /* done */ - break; - } - - AckTimeoutMS--; - A_MDELAY(1); - } - - if (0 == AckTimeoutMS) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("DevGMboxSetTargetInterrupt : Ack Timed-out (sig:%d) \n",Signal)); - status = A_ERROR; - } - } - - return status; - -} - -#endif //ATH_AR6K_ENABLE_GMBOX - - - - diff --git a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c b/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c deleted file mode 100644 index 56a0d71..0000000 --- a/drivers/staging/ath6kl/htc2/AR6000/ar6k_gmbox_hciuart.c +++ /dev/null @@ -1,1284 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="ar6k_prot_hciUart.c" company="Atheros"> -// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Protocol module for use in bridging HCI-UART packets over the GMBOX interface -// -// Author(s): ="Atheros" -//============================================================================== -#include "a_config.h" -#include "athdefs.h" -#include "a_osapi.h" -#include "../htc_debug.h" -#include "hif.h" -#include "htc_packet.h" -#include "ar6k.h" -#include "hci_transport_api.h" -#include "gmboxif.h" -#include "ar6000_diag.h" -#include "hw/apb_map.h" -#include "hw/mbox_reg.h" - -#ifdef ATH_AR6K_ENABLE_GMBOX -#define HCI_UART_COMMAND_PKT 0x01 -#define HCI_UART_ACL_PKT 0x02 -#define HCI_UART_SCO_PKT 0x03 -#define HCI_UART_EVENT_PKT 0x04 - -#define HCI_RECV_WAIT_BUFFERS (1 << 0) - -#define HCI_SEND_WAIT_CREDITS (1 << 0) - -#define HCI_UART_BRIDGE_CREDIT_SIZE 128 - -#define CREDIT_POLL_COUNT 256 - -#define HCI_DELAY_PER_INTERVAL_MS 10 -#define BTON_TIMEOUT_MS 500 -#define BTOFF_TIMEOUT_MS 500 -#define BAUD_TIMEOUT_MS 1 -#define BTPWRSAV_TIMEOUT_MS 1 - -struct gmbox_proto_hci_uart { - struct hci_transport_config_info HCIConfig; - bool HCIAttached; - bool HCIStopped; - u32 RecvStateFlags; - u32 SendStateFlags; - HCI_TRANSPORT_PACKET_TYPE WaitBufferType; - struct htc_packet_queue SendQueue; /* write queue holding HCI Command and ACL packets */ - struct htc_packet_queue HCIACLRecvBuffers; /* recv queue holding buffers for incomming ACL packets */ - struct htc_packet_queue HCIEventBuffers; /* recv queue holding buffers for incomming event packets */ - struct ar6k_device *pDev; - A_MUTEX_T HCIRxLock; - A_MUTEX_T HCITxLock; - int CreditsMax; - int CreditsConsumed; - int CreditsAvailable; - int CreditSize; - int CreditsCurrentSeek; - int SendProcessCount; -}; - -#define LOCK_HCI_RX(t) A_MUTEX_LOCK(&(t)->HCIRxLock); -#define UNLOCK_HCI_RX(t) A_MUTEX_UNLOCK(&(t)->HCIRxLock); -#define LOCK_HCI_TX(t) A_MUTEX_LOCK(&(t)->HCITxLock); -#define UNLOCK_HCI_TX(t) A_MUTEX_UNLOCK(&(t)->HCITxLock); - -#define DO_HCI_RECV_INDICATION(p, pt) \ -do { \ - AR_DEBUG_PRINTF(ATH_DEBUG_RECV, \ - ("HCI: Indicate Recv on packet:0x%lX status:%d len:%d type:%d \n", \ - (unsigned long)(pt), \ - (pt)->Status, \ - !(pt)->Status ? (pt)->ActualLength : 0, \ - HCI_GET_PACKET_TYPE(pt))); \ - (p)->HCIConfig.pHCIPktRecv((p)->HCIConfig.pContext, (pt)); \ -} while (0) - -#define DO_HCI_SEND_INDICATION(p,pt) \ -{ AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: Indicate Send on packet:0x%lX status:%d type:%d \n", \ - (unsigned long)(pt),(pt)->Status,HCI_GET_PACKET_TYPE(pt))); \ - (p)->HCIConfig.pHCISendComplete((p)->HCIConfig.pContext, (pt)); \ -} - -static int HCITrySend(struct gmbox_proto_hci_uart *pProt, struct htc_packet *pPacket, bool Synchronous); - -static void HCIUartCleanup(struct gmbox_proto_hci_uart *pProtocol) -{ - A_ASSERT(pProtocol != NULL); - - A_MUTEX_DELETE(&pProtocol->HCIRxLock); - A_MUTEX_DELETE(&pProtocol->HCITxLock); - - kfree(pProtocol); -} - -static int InitTxCreditState(struct gmbox_proto_hci_uart *pProt) -{ - int status; - int credits; - int creditPollCount = CREDIT_POLL_COUNT; - bool gotCredits = false; - - pProt->CreditsConsumed = 0; - - do { - - if (pProt->CreditsMax != 0) { - /* we can only call this only once per target reset */ - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HCI: InitTxCreditState - already called! \n")); - A_ASSERT(false); - status = A_EINVAL; - break; - } - - /* read the credit counter. At startup the target will set the credit counter - * to the max available, we read this in a loop because it may take - * multiple credit counter reads to get all credits */ - - while (creditPollCount) { - - credits = 0; - - status = DevGMboxReadCreditCounter(pProt->pDev, PROC_IO_SYNC, &credits); - - if (status) { - break; - } - - if (!gotCredits && (0 == credits)) { - creditPollCount--; - AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: credit is 0, retrying (%d) \n",creditPollCount)); - A_MDELAY(HCI_DELAY_PER_INTERVAL_MS); - continue; - } else { - gotCredits = true; - } - - if (0 == credits) { - break; - } - - pProt->CreditsMax += credits; - } - - if (status) { - break; - } - - if (0 == creditPollCount) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("** HCI : Failed to get credits! GMBOX Target was not available \n")); - status = A_ERROR; - break; - } - - /* now get the size */ - status = DevGMboxReadCreditSize(pProt->pDev, &pProt->CreditSize); - - if (status) { - break; - } - - } while (false); - - if (!status) { - pProt->CreditsAvailable = pProt->CreditsMax; - AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("HCI : InitTxCreditState - credits avail: %d, size: %d \n", - pProt->CreditsAvailable, pProt->CreditSize)); - } - - return status; -} - -static int CreditsAvailableCallback(void *pContext, int Credits, bool CreditIRQEnabled) -{ - struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)pContext; - bool enableCreditIrq = false; - bool disableCreditIrq = false; - bool doPendingSends = false; - int status = 0; - - /** this callback is called under 2 conditions: - * 1. The credit IRQ interrupt was enabled and signaled. - * 2. A credit counter read completed. - * - * The function must not assume that the calling context can block ! - */ - - AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+CreditsAvailableCallback (Credits:%d, IRQ:%s) \n", - Credits, CreditIRQEnabled ? "ON" : "OFF")); - - LOCK_HCI_TX(pProt); - - do { - - if (0 == Credits) { - if (!CreditIRQEnabled) { - /* enable credit IRQ */ - enableCreditIrq = true; - } - break; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: current credit state, consumed:%d available:%d max:%d seek:%d\n", - pProt->CreditsConsumed, - pProt->CreditsAvailable, - pProt->CreditsMax, - pProt->CreditsCurrentSeek)); - - pProt->CreditsAvailable += Credits; - A_ASSERT(pProt->CreditsAvailable <= pProt->CreditsMax); - pProt->CreditsConsumed -= Credits; - A_ASSERT(pProt->CreditsConsumed >= 0); - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: new credit state, consumed:%d available:%d max:%d seek:%d\n", - pProt->CreditsConsumed, - pProt->CreditsAvailable, - pProt->CreditsMax, - pProt->CreditsCurrentSeek)); - - if (pProt->CreditsAvailable >= pProt->CreditsCurrentSeek) { - /* we have enough credits to fulfill at least 1 packet waiting in the queue */ - pProt->CreditsCurrentSeek = 0; - pProt->SendStateFlags &= ~HCI_SEND_WAIT_CREDITS; - doPendingSends = true; - if (CreditIRQEnabled) { - /* credit IRQ was enabled, we shouldn't need it anymore */ - disableCreditIrq = true; - } - } else { - /* not enough credits yet, enable credit IRQ if we haven't already */ - if (!CreditIRQEnabled) { - enableCreditIrq = true; - } - } - - } while (false); - - UNLOCK_HCI_TX(pProt); - - if (enableCreditIrq) { - AR_DEBUG_PRINTF(ATH_DEBUG_RECV,(" Enabling credit count IRQ...\n")); - /* must use async only */ - status = DevGMboxIRQAction(pProt->pDev, GMBOX_CREDIT_IRQ_ENABLE, PROC_IO_ASYNC); - } else if (disableCreditIrq) { - /* must use async only */ - AR_DEBUG_PRINTF(ATH_DEBUG_RECV,(" Disabling credit count IRQ...\n")); - status = DevGMboxIRQAction(pProt->pDev, GMBOX_CREDIT_IRQ_DISABLE, PROC_IO_ASYNC); - } - - if (doPendingSends) { - HCITrySend(pProt, NULL, false); - } - - AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+CreditsAvailableCallback \n")); - return status; -} - -static INLINE void NotifyTransportFailure(struct gmbox_proto_hci_uart *pProt, int status) -{ - if (pProt->HCIConfig.TransportFailure != NULL) { - pProt->HCIConfig.TransportFailure(pProt->HCIConfig.pContext, status); - } -} - -static void FailureCallback(void *pContext, int Status) -{ - struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)pContext; - - /* target assertion occurred */ - NotifyTransportFailure(pProt, Status); -} - -static void StateDumpCallback(void *pContext) -{ - struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)pContext; - - AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("============ HCIUart State ======================\n")); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("RecvStateFlags : 0x%X \n",pProt->RecvStateFlags)); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("SendStateFlags : 0x%X \n",pProt->SendStateFlags)); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("WaitBufferType : %d \n",pProt->WaitBufferType)); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("SendQueue Depth : %d \n",HTC_PACKET_QUEUE_DEPTH(&pProt->SendQueue))); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("CreditsMax : %d \n",pProt->CreditsMax)); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("CreditsConsumed : %d \n",pProt->CreditsConsumed)); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("CreditsAvailable : %d \n",pProt->CreditsAvailable)); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("==================================================\n")); -} - -static int HCIUartMessagePending(void *pContext, u8 LookAheadBytes[], int ValidBytes) -{ - struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)pContext; - int status = 0; - int totalRecvLength = 0; - HCI_TRANSPORT_PACKET_TYPE pktType = HCI_PACKET_INVALID; - bool recvRefillCalled = false; - bool blockRecv = false; - struct htc_packet *pPacket = NULL; - - /** caller guarantees that this is a fully block-able context (synch I/O is allowed) */ - - AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HCIUartMessagePending Lookahead Bytes:%d \n",ValidBytes)); - - LOCK_HCI_RX(pProt); - - do { - - if (ValidBytes < 3) { - /* not enough for ACL or event header */ - break; - } - - if ((LookAheadBytes[0] == HCI_UART_ACL_PKT) && (ValidBytes < 5)) { - /* not enough for ACL data header */ - break; - } - - switch (LookAheadBytes[0]) { - case HCI_UART_EVENT_PKT: - AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("HCI Event: %d param length: %d \n", - LookAheadBytes[1], LookAheadBytes[2])); - totalRecvLength = LookAheadBytes[2]; - totalRecvLength += 3; /* add type + event code + length field */ - pktType = HCI_EVENT_TYPE; - break; - case HCI_UART_ACL_PKT: - totalRecvLength = (LookAheadBytes[4] << 8) | LookAheadBytes[3]; - AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("HCI ACL: conn:0x%X length: %d \n", - ((LookAheadBytes[2] & 0xF0) << 8) | LookAheadBytes[1], totalRecvLength)); - totalRecvLength += 5; /* add type + connection handle + length field */ - pktType = HCI_ACL_TYPE; - break; - default: - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("**Invalid HCI packet type: %d \n",LookAheadBytes[0])); - status = A_EPROTO; - break; - } - - if (status) { - break; - } - - if (pProt->HCIConfig.pHCIPktRecvAlloc != NULL) { - UNLOCK_HCI_RX(pProt); - /* user is using a per-packet allocation callback */ - pPacket = pProt->HCIConfig.pHCIPktRecvAlloc(pProt->HCIConfig.pContext, - pktType, - totalRecvLength); - LOCK_HCI_RX(pProt); - - } else { - struct htc_packet_queue *pQueue; - /* user is using a refill handler that can refill multiple HTC buffers */ - - /* select buffer queue */ - if (pktType == HCI_ACL_TYPE) { - pQueue = &pProt->HCIACLRecvBuffers; - } else { - pQueue = &pProt->HCIEventBuffers; - } - - if (HTC_QUEUE_EMPTY(pQueue)) { - AR_DEBUG_PRINTF(ATH_DEBUG_RECV, - ("** HCI pkt type: %d has no buffers available calling allocation handler \n", - pktType)); - /* check for refill handler */ - if (pProt->HCIConfig.pHCIPktRecvRefill != NULL) { - recvRefillCalled = true; - UNLOCK_HCI_RX(pProt); - /* call the re-fill handler */ - pProt->HCIConfig.pHCIPktRecvRefill(pProt->HCIConfig.pContext, - pktType, - 0); - LOCK_HCI_RX(pProt); - /* check if we have more buffers */ - pPacket = HTC_PACKET_DEQUEUE(pQueue); - /* fall through */ - } - } else { - pPacket = HTC_PACKET_DEQUEUE(pQueue); - AR_DEBUG_PRINTF(ATH_DEBUG_RECV, - ("HCI pkt type: %d now has %d recv buffers left \n", - pktType, HTC_PACKET_QUEUE_DEPTH(pQueue))); - } - } - - if (NULL == pPacket) { - AR_DEBUG_PRINTF(ATH_DEBUG_RECV, - ("** HCI pkt type: %d has no buffers available stopping recv...\n", pktType)); - /* this is not an error, we simply need to mark that we are waiting for buffers.*/ - pProt->RecvStateFlags |= HCI_RECV_WAIT_BUFFERS; - pProt->WaitBufferType = pktType; - blockRecv = true; - break; - } - - if (totalRecvLength > (int)pPacket->BufferLength) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("** HCI-UART pkt: %d requires %d bytes (%d buffer bytes avail) ! \n", - LookAheadBytes[0], totalRecvLength, pPacket->BufferLength)); - status = A_EINVAL; - break; - } - - } while (false); - - UNLOCK_HCI_RX(pProt); - - /* locks are released, we can go fetch the packet */ - - do { - - if (status || (NULL == pPacket)) { - break; - } - - /* do this synchronously, we don't need to be fast here */ - pPacket->Completion = NULL; - - AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("HCI : getting recv packet len:%d hci-uart-type: %s \n", - totalRecvLength, (LookAheadBytes[0] == HCI_UART_EVENT_PKT) ? "EVENT" : "ACL")); - - status = DevGMboxRead(pProt->pDev, pPacket, totalRecvLength); - - if (status) { - break; - } - - if (pPacket->pBuffer[0] != LookAheadBytes[0]) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("** HCI buffer does not contain expected packet type: %d ! \n", - pPacket->pBuffer[0])); - status = A_EPROTO; - break; - } - - if (pPacket->pBuffer[0] == HCI_UART_EVENT_PKT) { - /* validate event header fields */ - if ((pPacket->pBuffer[1] != LookAheadBytes[1]) || - (pPacket->pBuffer[2] != LookAheadBytes[2])) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("** HCI buffer does not match lookahead! \n")); - DebugDumpBytes(LookAheadBytes, 3, "Expected HCI-UART Header"); - DebugDumpBytes(pPacket->pBuffer, 3, "** Bad HCI-UART Header"); - status = A_EPROTO; - break; - } - } else if (pPacket->pBuffer[0] == HCI_UART_ACL_PKT) { - /* validate acl header fields */ - if ((pPacket->pBuffer[1] != LookAheadBytes[1]) || - (pPacket->pBuffer[2] != LookAheadBytes[2]) || - (pPacket->pBuffer[3] != LookAheadBytes[3]) || - (pPacket->pBuffer[4] != LookAheadBytes[4])) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("** HCI buffer does not match lookahead! \n")); - DebugDumpBytes(LookAheadBytes, 5, "Expected HCI-UART Header"); - DebugDumpBytes(pPacket->pBuffer, 5, "** Bad HCI-UART Header"); - status = A_EPROTO; - break; - } - } - - /* adjust buffer to move past packet ID */ - pPacket->pBuffer++; - pPacket->ActualLength = totalRecvLength - 1; - pPacket->Status = 0; - /* indicate packet */ - DO_HCI_RECV_INDICATION(pProt,pPacket); - pPacket = NULL; - - /* check if we need to refill recv buffers */ - if ((pProt->HCIConfig.pHCIPktRecvRefill != NULL) && !recvRefillCalled) { - struct htc_packet_queue *pQueue; - int watermark; - - if (pktType == HCI_ACL_TYPE) { - watermark = pProt->HCIConfig.ACLRecvBufferWaterMark; - pQueue = &pProt->HCIACLRecvBuffers; - } else { - watermark = pProt->HCIConfig.EventRecvBufferWaterMark; - pQueue = &pProt->HCIEventBuffers; - } - - if (HTC_PACKET_QUEUE_DEPTH(pQueue) < watermark) { - AR_DEBUG_PRINTF(ATH_DEBUG_RECV, - ("** HCI pkt type: %d watermark hit (%d) current:%d \n", - pktType, watermark, HTC_PACKET_QUEUE_DEPTH(pQueue))); - /* call the re-fill handler */ - pProt->HCIConfig.pHCIPktRecvRefill(pProt->HCIConfig.pContext, - pktType, - HTC_PACKET_QUEUE_DEPTH(pQueue)); - } - } - - } while (false); - - /* check if we need to disable the receiver */ - if (status || blockRecv) { - DevGMboxIRQAction(pProt->pDev, GMBOX_RECV_IRQ_DISABLE, PROC_IO_SYNC); - } - - /* see if we need to recycle the recv buffer */ - if (status && (pPacket != NULL)) { - struct htc_packet_queue queue; - - if (A_EPROTO == status) { - DebugDumpBytes(pPacket->pBuffer, totalRecvLength, "Bad HCI-UART Recv packet"); - } - /* recycle packet */ - HTC_PACKET_RESET_RX(pPacket); - INIT_HTC_PACKET_QUEUE_AND_ADD(&queue,pPacket); - HCI_TransportAddReceivePkts(pProt,&queue); - NotifyTransportFailure(pProt,status); - } - - - AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-HCIUartMessagePending \n")); - - return status; -} - -static void HCISendPacketCompletion(void *Context, struct htc_packet *pPacket) -{ - struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)Context; - AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HCISendPacketCompletion (pPacket:0x%lX) \n",(unsigned long)pPacket)); - - if (pPacket->Status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" Send Packet (0x%lX) failed: %d , len:%d \n", - (unsigned long)pPacket, pPacket->Status, pPacket->ActualLength)); - } - - DO_HCI_SEND_INDICATION(pProt,pPacket); - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HCISendPacketCompletion \n")); -} - -static int SeekCreditsSynch(struct gmbox_proto_hci_uart *pProt) -{ - int status = 0; - int credits; - int retry = 100; - - while (true) { - credits = 0; - status = DevGMboxReadCreditCounter(pProt->pDev, PROC_IO_SYNC, &credits); - if (status) { - break; - } - LOCK_HCI_TX(pProt); - pProt->CreditsAvailable += credits; - pProt->CreditsConsumed -= credits; - if (pProt->CreditsAvailable >= pProt->CreditsCurrentSeek) { - pProt->CreditsCurrentSeek = 0; - UNLOCK_HCI_TX(pProt); - break; - } - UNLOCK_HCI_TX(pProt); - retry--; - if (0 == retry) { - status = A_EBUSY; - break; - } - A_MDELAY(20); - } - - return status; -} - -static int HCITrySend(struct gmbox_proto_hci_uart *pProt, struct htc_packet *pPacket, bool Synchronous) -{ - int status = 0; - int transferLength; - int creditsRequired, remainder; - u8 hciUartType; - bool synchSendComplete = false; - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HCITrySend (pPacket:0x%lX) %s \n",(unsigned long)pPacket, - Synchronous ? "SYNC" :"ASYNC")); - - LOCK_HCI_TX(pProt); - - /* increment write processing count on entry */ - pProt->SendProcessCount++; - - do { - - if (pProt->HCIStopped) { - status = A_ECANCELED; - break; - } - - if (pPacket != NULL) { - /* packet was supplied */ - if (Synchronous) { - /* in synchronous mode, the send queue can only hold 1 packet */ - if (!HTC_QUEUE_EMPTY(&pProt->SendQueue)) { - status = A_EBUSY; - A_ASSERT(false); - break; - } - - if (pProt->SendProcessCount > 1) { - /* another thread or task is draining the TX queues */ - status = A_EBUSY; - A_ASSERT(false); - break; - } - - HTC_PACKET_ENQUEUE(&pProt->SendQueue,pPacket); - - } else { - /* see if adding this packet hits the max depth (asynchronous mode only) */ - if ((pProt->HCIConfig.MaxSendQueueDepth > 0) && - ((HTC_PACKET_QUEUE_DEPTH(&pProt->SendQueue) + 1) >= pProt->HCIConfig.MaxSendQueueDepth)) { - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("HCI Send queue is full, Depth:%d, Max:%d \n", - HTC_PACKET_QUEUE_DEPTH(&pProt->SendQueue), - pProt->HCIConfig.MaxSendQueueDepth)); - /* queue will be full, invoke any callbacks to determine what action to take */ - if (pProt->HCIConfig.pHCISendFull != NULL) { - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, - ("HCI : Calling driver's send full callback.... \n")); - if (pProt->HCIConfig.pHCISendFull(pProt->HCIConfig.pContext, - pPacket) == HCI_SEND_FULL_DROP) { - /* drop it */ - status = A_NO_RESOURCE; - break; - } - } - } - - HTC_PACKET_ENQUEUE(&pProt->SendQueue,pPacket); - } - - } - - if (pProt->SendStateFlags & HCI_SEND_WAIT_CREDITS) { - break; - } - - if (pProt->SendProcessCount > 1) { - /* another thread or task is draining the TX queues */ - break; - } - - /***** beyond this point only 1 thread may enter ******/ - - /* now drain the send queue for transmission as long as we have enough - * credits */ - while (!HTC_QUEUE_EMPTY(&pProt->SendQueue)) { - - pPacket = HTC_PACKET_DEQUEUE(&pProt->SendQueue); - - switch (HCI_GET_PACKET_TYPE(pPacket)) { - case HCI_COMMAND_TYPE: - hciUartType = HCI_UART_COMMAND_PKT; - break; - case HCI_ACL_TYPE: - hciUartType = HCI_UART_ACL_PKT; - break; - default: - status = A_EINVAL; - A_ASSERT(false); - break; - } - - if (status) { - break; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: Got head packet:0x%lX , Type:%d Length: %d Remaining Queue Depth: %d\n", - (unsigned long)pPacket, HCI_GET_PACKET_TYPE(pPacket), pPacket->ActualLength, - HTC_PACKET_QUEUE_DEPTH(&pProt->SendQueue))); - - transferLength = 1; /* UART type header is 1 byte */ - transferLength += pPacket->ActualLength; - transferLength = DEV_CALC_SEND_PADDED_LEN(pProt->pDev, transferLength); - - /* figure out how many credits this message requires */ - creditsRequired = transferLength / pProt->CreditSize; - remainder = transferLength % pProt->CreditSize; - - if (remainder) { - creditsRequired++; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: Creds Required:%d Got:%d\n", - creditsRequired, pProt->CreditsAvailable)); - - if (creditsRequired > pProt->CreditsAvailable) { - if (Synchronous) { - /* in synchronous mode we need to seek credits in synchronously */ - pProt->CreditsCurrentSeek = creditsRequired; - UNLOCK_HCI_TX(pProt); - status = SeekCreditsSynch(pProt); - LOCK_HCI_TX(pProt); - if (status) { - break; - } - /* fall through and continue processing this send op */ - } else { - /* not enough credits, queue back to the head */ - HTC_PACKET_ENQUEUE_TO_HEAD(&pProt->SendQueue,pPacket); - /* waiting for credits */ - pProt->SendStateFlags |= HCI_SEND_WAIT_CREDITS; - /* provide a hint to reduce attempts to re-send if credits are dribbling back - * this hint is the short fall of credits */ - pProt->CreditsCurrentSeek = creditsRequired; - AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: packet:0x%lX placed back in queue. head packet needs: %d credits \n", - (unsigned long)pPacket, pProt->CreditsCurrentSeek)); - pPacket = NULL; - UNLOCK_HCI_TX(pProt); - - /* schedule a credit counter read, our CreditsAvailableCallback callback will be called - * with the result */ - DevGMboxReadCreditCounter(pProt->pDev, PROC_IO_ASYNC, NULL); - - LOCK_HCI_TX(pProt); - break; - } - } - - /* caller guarantees some head room */ - pPacket->pBuffer--; - pPacket->pBuffer[0] = hciUartType; - - pProt->CreditsAvailable -= creditsRequired; - pProt->CreditsConsumed += creditsRequired; - A_ASSERT(pProt->CreditsConsumed <= pProt->CreditsMax); - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("HCI: new credit state: consumed:%d available:%d max:%d\n", - pProt->CreditsConsumed, pProt->CreditsAvailable, pProt->CreditsMax)); - - UNLOCK_HCI_TX(pProt); - - /* write it out */ - if (Synchronous) { - pPacket->Completion = NULL; - pPacket->pContext = NULL; - } else { - pPacket->Completion = HCISendPacketCompletion; - pPacket->pContext = pProt; - } - - status = DevGMboxWrite(pProt->pDev,pPacket,transferLength); - if (Synchronous) { - synchSendComplete = true; - } else { - pPacket = NULL; - } - - LOCK_HCI_TX(pProt); - - } - - } while (false); - - pProt->SendProcessCount--; - A_ASSERT(pProt->SendProcessCount >= 0); - UNLOCK_HCI_TX(pProt); - - if (Synchronous) { - A_ASSERT(pPacket != NULL); - if (!status && (!synchSendComplete)) { - status = A_EBUSY; - A_ASSERT(false); - LOCK_HCI_TX(pProt); - if (pPacket->ListLink.pNext != NULL) { - /* remove from the queue */ - HTC_PACKET_REMOVE(&pProt->SendQueue,pPacket); - } - UNLOCK_HCI_TX(pProt); - } - } else { - if (status && (pPacket != NULL)) { - pPacket->Status = status; - DO_HCI_SEND_INDICATION(pProt,pPacket); - } - } - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HCITrySend: \n")); - return status; -} - -static void FlushSendQueue(struct gmbox_proto_hci_uart *pProt) -{ - struct htc_packet *pPacket; - struct htc_packet_queue discardQueue; - - INIT_HTC_PACKET_QUEUE(&discardQueue); - - LOCK_HCI_TX(pProt); - - if (!HTC_QUEUE_EMPTY(&pProt->SendQueue)) { - HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&discardQueue,&pProt->SendQueue); - } - - UNLOCK_HCI_TX(pProt); - - /* discard packets */ - while (!HTC_QUEUE_EMPTY(&discardQueue)) { - pPacket = HTC_PACKET_DEQUEUE(&discardQueue); - pPacket->Status = A_ECANCELED; - DO_HCI_SEND_INDICATION(pProt,pPacket); - } - -} - -static void FlushRecvBuffers(struct gmbox_proto_hci_uart *pProt) -{ - struct htc_packet_queue discardQueue; - struct htc_packet *pPacket; - - INIT_HTC_PACKET_QUEUE(&discardQueue); - - LOCK_HCI_RX(pProt); - /*transfer list items from ACL and event buffer queues to the discard queue */ - if (!HTC_QUEUE_EMPTY(&pProt->HCIACLRecvBuffers)) { - HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&discardQueue,&pProt->HCIACLRecvBuffers); - } - if (!HTC_QUEUE_EMPTY(&pProt->HCIEventBuffers)) { - HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&discardQueue,&pProt->HCIEventBuffers); - } - UNLOCK_HCI_RX(pProt); - - /* now empty the discard queue */ - while (!HTC_QUEUE_EMPTY(&discardQueue)) { - pPacket = HTC_PACKET_DEQUEUE(&discardQueue); - pPacket->Status = A_ECANCELED; - DO_HCI_RECV_INDICATION(pProt,pPacket); - } - -} - -/*** protocol module install entry point ***/ - -int GMboxProtocolInstall(struct ar6k_device *pDev) -{ - int status = 0; - struct gmbox_proto_hci_uart *pProtocol = NULL; - - do { - - pProtocol = A_MALLOC(sizeof(struct gmbox_proto_hci_uart)); - - if (NULL == pProtocol) { - status = A_NO_MEMORY; - break; - } - - A_MEMZERO(pProtocol, sizeof(*pProtocol)); - pProtocol->pDev = pDev; - INIT_HTC_PACKET_QUEUE(&pProtocol->SendQueue); - INIT_HTC_PACKET_QUEUE(&pProtocol->HCIACLRecvBuffers); - INIT_HTC_PACKET_QUEUE(&pProtocol->HCIEventBuffers); - A_MUTEX_INIT(&pProtocol->HCIRxLock); - A_MUTEX_INIT(&pProtocol->HCITxLock); - - } while (false); - - if (!status) { - LOCK_AR6K(pDev); - DEV_GMBOX_SET_PROTOCOL(pDev, - HCIUartMessagePending, - CreditsAvailableCallback, - FailureCallback, - StateDumpCallback, - pProtocol); - UNLOCK_AR6K(pDev); - } else { - if (pProtocol != NULL) { - HCIUartCleanup(pProtocol); - } - } - - return status; -} - -/*** protocol module uninstall entry point ***/ -void GMboxProtocolUninstall(struct ar6k_device *pDev) -{ - struct gmbox_proto_hci_uart *pProtocol = (struct gmbox_proto_hci_uart *)DEV_GMBOX_GET_PROTOCOL(pDev); - - if (pProtocol != NULL) { - - /* notify anyone attached */ - if (pProtocol->HCIAttached) { - A_ASSERT(pProtocol->HCIConfig.TransportRemoved != NULL); - pProtocol->HCIConfig.TransportRemoved(pProtocol->HCIConfig.pContext); - pProtocol->HCIAttached = false; - } - - HCIUartCleanup(pProtocol); - DEV_GMBOX_SET_PROTOCOL(pDev,NULL,NULL,NULL,NULL,NULL); - } - -} - -static int NotifyTransportReady(struct gmbox_proto_hci_uart *pProt) -{ - struct hci_transport_properties props; - int status = 0; - - do { - - A_MEMZERO(&props,sizeof(props)); - - /* HCI UART only needs one extra byte at the head to indicate the packet TYPE */ - props.HeadRoom = 1; - props.TailRoom = 0; - props.IOBlockPad = pProt->pDev->BlockSize; - if (pProt->HCIAttached) { - AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("HCI: notifying attached client to transport... \n")); - A_ASSERT(pProt->HCIConfig.TransportReady != NULL); - status = pProt->HCIConfig.TransportReady(pProt, - &props, - pProt->HCIConfig.pContext); - } - - } while (false); - - return status; -} - -/*********** HCI UART protocol implementation ************************************************/ - -HCI_TRANSPORT_HANDLE HCI_TransportAttach(void *HTCHandle, struct hci_transport_config_info *pInfo) -{ - struct gmbox_proto_hci_uart *pProtocol = NULL; - struct ar6k_device *pDev; - - AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("+HCI_TransportAttach \n")); - - pDev = HTCGetAR6KDevice(HTCHandle); - - LOCK_AR6K(pDev); - - do { - - pProtocol = (struct gmbox_proto_hci_uart *)DEV_GMBOX_GET_PROTOCOL(pDev); - - if (NULL == pProtocol) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("GMBOX protocol not installed! \n")); - break; - } - - if (pProtocol->HCIAttached) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("GMBOX protocol already attached! \n")); - break; - } - - memcpy(&pProtocol->HCIConfig, pInfo, sizeof(struct hci_transport_config_info)); - - A_ASSERT(pProtocol->HCIConfig.pHCIPktRecv != NULL); - A_ASSERT(pProtocol->HCIConfig.pHCISendComplete != NULL); - - pProtocol->HCIAttached = true; - - } while (false); - - UNLOCK_AR6K(pDev); - - if (pProtocol != NULL) { - /* TODO ... should we use a worker? */ - NotifyTransportReady(pProtocol); - } - - AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("-HCI_TransportAttach (0x%lX) \n",(unsigned long)pProtocol)); - return (HCI_TRANSPORT_HANDLE)pProtocol; -} - -void HCI_TransportDetach(HCI_TRANSPORT_HANDLE HciTrans) -{ - struct gmbox_proto_hci_uart *pProtocol = (struct gmbox_proto_hci_uart *)HciTrans; - struct ar6k_device *pDev = pProtocol->pDev; - - AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("+HCI_TransportDetach \n")); - - LOCK_AR6K(pDev); - if (!pProtocol->HCIAttached) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("GMBOX protocol not attached! \n")); - UNLOCK_AR6K(pDev); - return; - } - pProtocol->HCIAttached = false; - UNLOCK_AR6K(pDev); - - HCI_TransportStop(HciTrans); - AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("-HCI_TransportAttach \n")); -} - -int HCI_TransportAddReceivePkts(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet_queue *pQueue) -{ - struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)HciTrans; - int status = 0; - bool unblockRecv = false; - struct htc_packet *pPacket; - - AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HCI_TransportAddReceivePkt \n")); - - LOCK_HCI_RX(pProt); - - do { - - if (pProt->HCIStopped) { - status = A_ECANCELED; - break; - } - - pPacket = HTC_GET_PKT_AT_HEAD(pQueue); - - if (NULL == pPacket) { - status = A_EINVAL; - break; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_RECV,(" HCI recv packet added, type :%d, len:%d num:%d \n", - HCI_GET_PACKET_TYPE(pPacket), pPacket->BufferLength, HTC_PACKET_QUEUE_DEPTH(pQueue))); - - if (HCI_GET_PACKET_TYPE(pPacket) == HCI_EVENT_TYPE) { - HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&pProt->HCIEventBuffers, pQueue); - } else if (HCI_GET_PACKET_TYPE(pPacket) == HCI_ACL_TYPE) { - HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&pProt->HCIACLRecvBuffers, pQueue); - } else { - status = A_EINVAL; - break; - } - - if (pProt->RecvStateFlags & HCI_RECV_WAIT_BUFFERS) { - if (pProt->WaitBufferType == HCI_GET_PACKET_TYPE(pPacket)) { - AR_DEBUG_PRINTF(ATH_DEBUG_RECV,(" HCI recv was blocked on packet type :%d, unblocking.. \n", - pProt->WaitBufferType)); - pProt->RecvStateFlags &= ~HCI_RECV_WAIT_BUFFERS; - pProt->WaitBufferType = HCI_PACKET_INVALID; - unblockRecv = true; - } - } - - } while (false); - - UNLOCK_HCI_RX(pProt); - - if (status) { - while (!HTC_QUEUE_EMPTY(pQueue)) { - pPacket = HTC_PACKET_DEQUEUE(pQueue); - pPacket->Status = A_ECANCELED; - DO_HCI_RECV_INDICATION(pProt,pPacket); - } - } - - if (unblockRecv) { - DevGMboxIRQAction(pProt->pDev, GMBOX_RECV_IRQ_ENABLE, PROC_IO_ASYNC); - } - - AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-HCI_TransportAddReceivePkt \n")); - - return 0; -} - -int HCI_TransportSendPkt(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet *pPacket, bool Synchronous) -{ - struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)HciTrans; - - return HCITrySend(pProt,pPacket,Synchronous); -} - -void HCI_TransportStop(HCI_TRANSPORT_HANDLE HciTrans) -{ - struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)HciTrans; - - AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("+HCI_TransportStop \n")); - - LOCK_AR6K(pProt->pDev); - if (pProt->HCIStopped) { - UNLOCK_AR6K(pProt->pDev); - AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("-HCI_TransportStop \n")); - return; - } - pProt->HCIStopped = true; - UNLOCK_AR6K(pProt->pDev); - - /* disable interrupts */ - DevGMboxIRQAction(pProt->pDev, GMBOX_DISABLE_ALL, PROC_IO_SYNC); - FlushSendQueue(pProt); - FlushRecvBuffers(pProt); - - /* signal bridge side to power down BT */ - DevGMboxSetTargetInterrupt(pProt->pDev, MBOX_SIG_HCI_BRIDGE_BT_OFF, BTOFF_TIMEOUT_MS); - - AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("-HCI_TransportStop \n")); -} - -int HCI_TransportStart(HCI_TRANSPORT_HANDLE HciTrans) -{ - int status; - struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)HciTrans; - - AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("+HCI_TransportStart \n")); - - /* set stopped in case we have a problem in starting */ - pProt->HCIStopped = true; - - do { - - status = InitTxCreditState(pProt); - - if (status) { - break; - } - - status = DevGMboxIRQAction(pProt->pDev, GMBOX_ERRORS_IRQ_ENABLE, PROC_IO_SYNC); - - if (status) { - break; - } - /* enable recv */ - status = DevGMboxIRQAction(pProt->pDev, GMBOX_RECV_IRQ_ENABLE, PROC_IO_SYNC); - - if (status) { - break; - } - /* signal bridge side to power up BT */ - status = DevGMboxSetTargetInterrupt(pProt->pDev, MBOX_SIG_HCI_BRIDGE_BT_ON, BTON_TIMEOUT_MS); - - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HCI_TransportStart : Failed to trigger BT ON \n")); - break; - } - - /* we made it */ - pProt->HCIStopped = false; - - } while (false); - - AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("-HCI_TransportStart \n")); - - return status; -} - -int HCI_TransportEnableDisableAsyncRecv(HCI_TRANSPORT_HANDLE HciTrans, bool Enable) -{ - struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)HciTrans; - return DevGMboxIRQAction(pProt->pDev, - Enable ? GMBOX_RECV_IRQ_ENABLE : GMBOX_RECV_IRQ_DISABLE, - PROC_IO_SYNC); - -} - -int HCI_TransportRecvHCIEventSync(HCI_TRANSPORT_HANDLE HciTrans, - struct htc_packet *pPacket, - int MaxPollMS) -{ - struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)HciTrans; - int status = 0; - u8 lookAhead[8]; - int bytes; - int totalRecvLength; - - MaxPollMS = MaxPollMS / 16; - - if (MaxPollMS < 2) { - MaxPollMS = 2; - } - - while (MaxPollMS) { - - bytes = sizeof(lookAhead); - status = DevGMboxRecvLookAheadPeek(pProt->pDev,lookAhead,&bytes); - if (status) { - break; - } - - if (bytes < 3) { - AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("HCI recv poll got bytes: %d, retry : %d \n", - bytes, MaxPollMS)); - A_MDELAY(16); - MaxPollMS--; - continue; - } - - totalRecvLength = 0; - switch (lookAhead[0]) { - case HCI_UART_EVENT_PKT: - AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("HCI Event: %d param length: %d \n", - lookAhead[1], lookAhead[2])); - totalRecvLength = lookAhead[2]; - totalRecvLength += 3; /* add type + event code + length field */ - break; - default: - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("**Invalid HCI packet type: %d \n",lookAhead[0])); - status = A_EPROTO; - break; - } - - if (status) { - break; - } - - pPacket->Completion = NULL; - status = DevGMboxRead(pProt->pDev,pPacket,totalRecvLength); - if (status) { - break; - } - - pPacket->pBuffer++; - pPacket->ActualLength = totalRecvLength - 1; - pPacket->Status = 0; - break; - } - - if (MaxPollMS == 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HCI recv poll timeout! \n")); - status = A_ERROR; - } - - return status; -} - -#define LSB_SCRATCH_IDX 4 -#define MSB_SCRATCH_IDX 5 -int HCI_TransportSetBaudRate(HCI_TRANSPORT_HANDLE HciTrans, u32 Baud) -{ - struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)HciTrans; - struct hif_device *pHIFDevice = (struct hif_device *)(pProt->pDev->HIFDevice); - u32 scaledBaud, scratchAddr; - int status = 0; - - /* Divide the desired baud rate by 100 - * Store the LSB in the local scratch register 4 and the MSB in the local - * scratch register 5 for the target to read - */ - scratchAddr = MBOX_BASE_ADDRESS | (LOCAL_SCRATCH_ADDRESS + 4 * LSB_SCRATCH_IDX); - scaledBaud = (Baud / 100) & LOCAL_SCRATCH_VALUE_MASK; - status = ar6000_WriteRegDiag(pHIFDevice, &scratchAddr, &scaledBaud); - scratchAddr = MBOX_BASE_ADDRESS | (LOCAL_SCRATCH_ADDRESS + 4 * MSB_SCRATCH_IDX); - scaledBaud = ((Baud / 100) >> (LOCAL_SCRATCH_VALUE_MSB+1)) & LOCAL_SCRATCH_VALUE_MASK; - status |= ar6000_WriteRegDiag(pHIFDevice, &scratchAddr, &scaledBaud); - if (0 != status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to set up baud rate in scratch register!")); - return status; - } - - /* Now interrupt the target to tell it about the baud rate */ - status = DevGMboxSetTargetInterrupt(pProt->pDev, MBOX_SIG_HCI_BRIDGE_BAUD_SET, BAUD_TIMEOUT_MS); - if (0 != status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Failed to tell target to change baud rate!")); - } - - return status; -} - -int HCI_TransportEnablePowerMgmt(HCI_TRANSPORT_HANDLE HciTrans, bool Enable) -{ - int status; - struct gmbox_proto_hci_uart *pProt = (struct gmbox_proto_hci_uart *)HciTrans; - - if (Enable) { - status = DevGMboxSetTargetInterrupt(pProt->pDev, MBOX_SIG_HCI_BRIDGE_PWR_SAV_ON, BTPWRSAV_TIMEOUT_MS); - } else { - status = DevGMboxSetTargetInterrupt(pProt->pDev, MBOX_SIG_HCI_BRIDGE_PWR_SAV_OFF, BTPWRSAV_TIMEOUT_MS); - } - - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to enable/disable HCI power management!\n")); - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HCI power management enabled/disabled!\n")); - } - - return status; -} - -#endif //ATH_AR6K_ENABLE_GMBOX - diff --git a/drivers/staging/ath6kl/htc2/htc.c b/drivers/staging/ath6kl/htc2/htc.c deleted file mode 100644 index ae54e64..0000000 --- a/drivers/staging/ath6kl/htc2/htc.c +++ /dev/null @@ -1,575 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="htc.c" company="Atheros"> -// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Author(s): ="Atheros" -//============================================================================== -#include "htc_internal.h" - -#ifdef ATH_DEBUG_MODULE -static struct ath_debug_mask_description g_HTCDebugDescription[] = { - { ATH_DEBUG_SEND , "Send"}, - { ATH_DEBUG_RECV , "Recv"}, - { ATH_DEBUG_SYNC , "Sync"}, - { ATH_DEBUG_DUMP , "Dump Data (RX or TX)"}, - { ATH_DEBUG_IRQ , "Interrupt Processing"} -}; - -ATH_DEBUG_INSTANTIATE_MODULE_VAR(htc, - "htc", - "Host Target Communications", - ATH_DEBUG_MASK_DEFAULTS, - ATH_DEBUG_DESCRIPTION_COUNT(g_HTCDebugDescription), - g_HTCDebugDescription); - -#endif - -static void HTCReportFailure(void *Context); -static void ResetEndpointStates(struct htc_target *target); - -void HTCFreeControlBuffer(struct htc_target *target, struct htc_packet *pPacket, struct htc_packet_queue *pList) -{ - LOCK_HTC(target); - HTC_PACKET_ENQUEUE(pList,pPacket); - UNLOCK_HTC(target); -} - -struct htc_packet *HTCAllocControlBuffer(struct htc_target *target, struct htc_packet_queue *pList) -{ - struct htc_packet *pPacket; - - LOCK_HTC(target); - pPacket = HTC_PACKET_DEQUEUE(pList); - UNLOCK_HTC(target); - - return pPacket; -} - -/* cleanup the HTC instance */ -static void HTCCleanup(struct htc_target *target) -{ - s32 i; - - DevCleanup(&target->Device); - - for (i = 0;i < NUM_CONTROL_BUFFERS;i++) { - if (target->HTCControlBuffers[i].Buffer) { - kfree(target->HTCControlBuffers[i].Buffer); - } - } - - if (A_IS_MUTEX_VALID(&target->HTCLock)) { - A_MUTEX_DELETE(&target->HTCLock); - } - - if (A_IS_MUTEX_VALID(&target->HTCRxLock)) { - A_MUTEX_DELETE(&target->HTCRxLock); - } - - if (A_IS_MUTEX_VALID(&target->HTCTxLock)) { - A_MUTEX_DELETE(&target->HTCTxLock); - } - /* free our instance */ - kfree(target); -} - -/* registered target arrival callback from the HIF layer */ -HTC_HANDLE HTCCreate(void *hif_handle, struct htc_init_info *pInfo) -{ - struct htc_target *target = NULL; - int status = 0; - int i; - u32 ctrl_bufsz; - u32 blocksizes[HTC_MAILBOX_NUM_MAX]; - - AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCCreate - Enter\n")); - - A_REGISTER_MODULE_DEBUG_INFO(htc); - - do { - - /* allocate target memory */ - if ((target = (struct htc_target *)A_MALLOC(sizeof(struct htc_target))) == NULL) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to allocate memory\n")); - status = A_ERROR; - break; - } - - A_MEMZERO(target, sizeof(struct htc_target)); - A_MUTEX_INIT(&target->HTCLock); - A_MUTEX_INIT(&target->HTCRxLock); - A_MUTEX_INIT(&target->HTCTxLock); - INIT_HTC_PACKET_QUEUE(&target->ControlBufferTXFreeList); - INIT_HTC_PACKET_QUEUE(&target->ControlBufferRXFreeList); - - /* give device layer the hif device handle */ - target->Device.HIFDevice = hif_handle; - /* give the device layer our context (for event processing) - * the device layer will register it's own context with HIF - * so we need to set this so we can fetch it in the target remove handler */ - target->Device.HTCContext = target; - /* set device layer target failure callback */ - target->Device.TargetFailureCallback = HTCReportFailure; - /* set device layer recv message pending callback */ - target->Device.MessagePendingCallback = HTCRecvMessagePendingHandler; - target->EpWaitingForBuffers = ENDPOINT_MAX; - - memcpy(&target->HTCInitInfo,pInfo,sizeof(struct htc_init_info)); - - ResetEndpointStates(target); - - /* setup device layer */ - status = DevSetup(&target->Device); - - if (status) { - break; - } - - - /* get the block sizes */ - status = HIFConfigureDevice(hif_handle, HIF_DEVICE_GET_MBOX_BLOCK_SIZE, - blocksizes, sizeof(blocksizes)); - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to get block size info from HIF layer...\n")); - break; - } - - /* Set the control buffer size based on the block size */ - if (blocksizes[1] > HTC_MAX_CONTROL_MESSAGE_LENGTH) { - ctrl_bufsz = blocksizes[1] + HTC_HDR_LENGTH; - } else { - ctrl_bufsz = HTC_MAX_CONTROL_MESSAGE_LENGTH + HTC_HDR_LENGTH; - } - for (i = 0;i < NUM_CONTROL_BUFFERS;i++) { - target->HTCControlBuffers[i].Buffer = A_MALLOC(ctrl_bufsz); - if (target->HTCControlBuffers[i].Buffer == NULL) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to allocate memory\n")); - status = A_ERROR; - break; - } - } - - if (status) { - break; - } - - /* carve up buffers/packets for control messages */ - for (i = 0; i < NUM_CONTROL_RX_BUFFERS; i++) { - struct htc_packet *pControlPacket; - pControlPacket = &target->HTCControlBuffers[i].HtcPacket; - SET_HTC_PACKET_INFO_RX_REFILL(pControlPacket, - target, - target->HTCControlBuffers[i].Buffer, - ctrl_bufsz, - ENDPOINT_0); - HTC_FREE_CONTROL_RX(target,pControlPacket); - } - - for (;i < NUM_CONTROL_BUFFERS;i++) { - struct htc_packet *pControlPacket; - pControlPacket = &target->HTCControlBuffers[i].HtcPacket; - INIT_HTC_PACKET_INFO(pControlPacket, - target->HTCControlBuffers[i].Buffer, - ctrl_bufsz); - HTC_FREE_CONTROL_TX(target,pControlPacket); - } - - } while (false); - - if (status) { - if (target != NULL) { - HTCCleanup(target); - target = NULL; - } - } - - AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCCreate - Exit\n")); - - return target; -} - -void HTCDestroy(HTC_HANDLE HTCHandle) -{ - struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); - AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCDestroy .. Destroying :0x%lX \n",(unsigned long)target)); - HTCCleanup(target); - AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCDestroy \n")); -} - -/* get the low level HIF device for the caller , the caller may wish to do low level - * HIF requests */ -void *HTCGetHifDevice(HTC_HANDLE HTCHandle) -{ - struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); - return target->Device.HIFDevice; -} - -/* wait for the target to arrive (sends HTC Ready message) - * this operation is fully synchronous and the message is polled for */ -int HTCWaitTarget(HTC_HANDLE HTCHandle) -{ - struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); - int status; - struct htc_packet *pPacket = NULL; - HTC_READY_EX_MSG *pRdyMsg; - - struct htc_service_connect_req connect; - struct htc_service_connect_resp resp; - - AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCWaitTarget - Enter (target:0x%lX) \n", (unsigned long)target)); - - do { - -#ifdef MBOXHW_UNIT_TEST - - status = DoMboxHWTest(&target->Device); - - if (status) { - break; - } - -#endif - - /* we should be getting 1 control message that the target is ready */ - status = HTCWaitforControlMessage(target, &pPacket); - - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, (" Target Not Available!!\n")); - break; - } - - /* we controlled the buffer creation so it has to be properly aligned */ - pRdyMsg = (HTC_READY_EX_MSG *)pPacket->pBuffer; - - if ((pRdyMsg->Version2_0_Info.MessageID != HTC_MSG_READY_ID) || - (pPacket->ActualLength < sizeof(HTC_READY_MSG))) { - /* this message is not valid */ - AR_DEBUG_ASSERT(false); - status = A_EPROTO; - break; - } - - - if (pRdyMsg->Version2_0_Info.CreditCount == 0 || pRdyMsg->Version2_0_Info.CreditSize == 0) { - /* this message is not valid */ - AR_DEBUG_ASSERT(false); - status = A_EPROTO; - break; - } - - target->TargetCredits = pRdyMsg->Version2_0_Info.CreditCount; - target->TargetCreditSize = pRdyMsg->Version2_0_Info.CreditSize; - - AR_DEBUG_PRINTF(ATH_DEBUG_WARN, (" Target Ready: credits: %d credit size: %d\n", - target->TargetCredits, target->TargetCreditSize)); - - /* check if this is an extended ready message */ - if (pPacket->ActualLength >= sizeof(HTC_READY_EX_MSG)) { - /* this is an extended message */ - target->HTCTargetVersion = pRdyMsg->HTCVersion; - target->MaxMsgPerBundle = pRdyMsg->MaxMsgsPerHTCBundle; - } else { - /* legacy */ - target->HTCTargetVersion = HTC_VERSION_2P0; - target->MaxMsgPerBundle = 0; - } - -#ifdef HTC_FORCE_LEGACY_2P0 - /* for testing and comparison...*/ - target->HTCTargetVersion = HTC_VERSION_2P0; - target->MaxMsgPerBundle = 0; -#endif - - AR_DEBUG_PRINTF(ATH_DEBUG_TRC, - ("Using HTC Protocol Version : %s (%d)\n ", - (target->HTCTargetVersion == HTC_VERSION_2P0) ? "2.0" : ">= 2.1", - target->HTCTargetVersion)); - - if (target->MaxMsgPerBundle > 0) { - /* limit what HTC can handle */ - target->MaxMsgPerBundle = min(HTC_HOST_MAX_MSG_PER_BUNDLE, target->MaxMsgPerBundle); - /* target supports message bundling, setup device layer */ - if (DevSetupMsgBundling(&target->Device,target->MaxMsgPerBundle)) { - /* device layer can't handle bundling */ - target->MaxMsgPerBundle = 0; - } else { - /* limit bundle what the device layer can handle */ - target->MaxMsgPerBundle = min(DEV_GET_MAX_MSG_PER_BUNDLE(&target->Device), - target->MaxMsgPerBundle); - } - } - - if (target->MaxMsgPerBundle > 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_TRC, - (" HTC bundling allowed. Max Msg Per HTC Bundle: %d\n", target->MaxMsgPerBundle)); - - if (DEV_GET_MAX_BUNDLE_SEND_LENGTH(&target->Device) != 0) { - target->SendBundlingEnabled = true; - } - if (DEV_GET_MAX_BUNDLE_RECV_LENGTH(&target->Device) != 0) { - target->RecvBundlingEnabled = true; - } - - if (!DEV_IS_LEN_BLOCK_ALIGNED(&target->Device,target->TargetCreditSize)) { - AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("*** Credit size: %d is not block aligned! Disabling send bundling \n", - target->TargetCreditSize)); - /* disallow send bundling since the credit size is not aligned to a block size - * the I/O block padding will spill into the next credit buffer which is fatal */ - target->SendBundlingEnabled = false; - } - } - - /* setup our pseudo HTC control endpoint connection */ - A_MEMZERO(&connect,sizeof(connect)); - A_MEMZERO(&resp,sizeof(resp)); - connect.EpCallbacks.pContext = target; - connect.EpCallbacks.EpTxComplete = HTCControlTxComplete; - connect.EpCallbacks.EpRecv = HTCControlRecv; - connect.EpCallbacks.EpRecvRefill = NULL; /* not needed */ - connect.EpCallbacks.EpSendFull = NULL; /* not nedded */ - connect.MaxSendQueueDepth = NUM_CONTROL_BUFFERS; - connect.ServiceID = HTC_CTRL_RSVD_SVC; - - /* connect fake service */ - status = HTCConnectService((HTC_HANDLE)target, - &connect, - &resp); - - if (!status) { - break; - } - - } while (false); - - if (pPacket != NULL) { - HTC_FREE_CONTROL_RX(target,pPacket); - } - - AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCWaitTarget - Exit\n")); - - return status; -} - - - -/* Start HTC, enable interrupts and let the target know host has finished setup */ -int HTCStart(HTC_HANDLE HTCHandle) -{ - struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); - struct htc_packet *pPacket; - int status; - - AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Enter\n")); - - /* make sure interrupts are disabled at the chip level, - * this function can be called again from a reboot of the target without shutting down HTC */ - DevDisableInterrupts(&target->Device); - /* make sure state is cleared again */ - target->OpStateFlags = 0; - target->RecvStateFlags = 0; - - /* now that we are starting, push control receive buffers into the - * HTC control endpoint */ - - while (1) { - pPacket = HTC_ALLOC_CONTROL_RX(target); - if (NULL == pPacket) { - break; - } - HTCAddReceivePkt((HTC_HANDLE)target,pPacket); - } - - do { - - AR_DEBUG_ASSERT(target->InitCredits != NULL); - AR_DEBUG_ASSERT(target->EpCreditDistributionListHead != NULL); - AR_DEBUG_ASSERT(target->EpCreditDistributionListHead->pNext != NULL); - - /* call init credits callback to do the distribution , - * NOTE: the first entry in the distribution list is ENDPOINT_0, so - * we pass the start of the list after this one. */ - target->InitCredits(target->pCredDistContext, - target->EpCreditDistributionListHead->pNext, - target->TargetCredits); - -#ifdef ATH_DEBUG_MODULE - - if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_TRC)) { - DumpCreditDistStates(target); - } -#endif - - /* the caller is done connecting to services, so we can indicate to the - * target that the setup phase is complete */ - status = HTCSendSetupComplete(target); - - if (status) { - break; - } - - /* unmask interrupts */ - status = DevUnmaskInterrupts(&target->Device); - - if (status) { - HTCStop(target); - } - - } while (false); - - AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Exit\n")); - return status; -} - -static void ResetEndpointStates(struct htc_target *target) -{ - struct htc_endpoint *pEndpoint; - int i; - - for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) { - pEndpoint = &target->EndPoint[i]; - - A_MEMZERO(&pEndpoint->CreditDist, sizeof(pEndpoint->CreditDist)); - pEndpoint->ServiceID = 0; - pEndpoint->MaxMsgLength = 0; - pEndpoint->MaxTxQueueDepth = 0; - A_MEMZERO(&pEndpoint->EndPointStats,sizeof(pEndpoint->EndPointStats)); - INIT_HTC_PACKET_QUEUE(&pEndpoint->RxBuffers); - INIT_HTC_PACKET_QUEUE(&pEndpoint->TxQueue); - INIT_HTC_PACKET_QUEUE(&pEndpoint->RecvIndicationQueue); - pEndpoint->target = target; - } - /* reset distribution list */ - target->EpCreditDistributionListHead = NULL; -} - -/* stop HTC communications, i.e. stop interrupt reception, and flush all queued buffers */ -void HTCStop(HTC_HANDLE HTCHandle) -{ - struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); - AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCStop \n")); - - LOCK_HTC(target); - /* mark that we are shutting down .. */ - target->OpStateFlags |= HTC_OP_STATE_STOPPING; - UNLOCK_HTC(target); - - /* Masking interrupts is a synchronous operation, when this function returns - * all pending HIF I/O has completed, we can safely flush the queues */ - DevMaskInterrupts(&target->Device); - -#ifdef THREAD_X - // - // Is this delay required - // - A_MDELAY(200); // wait for IRQ process done -#endif - /* flush all send packets */ - HTCFlushSendPkts(target); - /* flush all recv buffers */ - HTCFlushRecvBuffers(target); - - DevCleanupMsgBundling(&target->Device); - - ResetEndpointStates(target); - - AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCStop \n")); -} - -#ifdef ATH_DEBUG_MODULE -void HTCDumpCreditStates(HTC_HANDLE HTCHandle) -{ - struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); - - LOCK_HTC_TX(target); - - DumpCreditDistStates(target); - - UNLOCK_HTC_TX(target); - - DumpAR6KDevState(&target->Device); -} -#endif -/* report a target failure from the device, this is a callback from the device layer - * which uses a mechanism to report errors from the target (i.e. special interrupts) */ -static void HTCReportFailure(void *Context) -{ - struct htc_target *target = (struct htc_target *)Context; - - target->TargetFailure = true; - - if (target->HTCInitInfo.TargetFailure != NULL) { - /* let upper layer know, it needs to call HTCStop() */ - target->HTCInitInfo.TargetFailure(target->HTCInitInfo.pContext, A_ERROR); - } -} - -bool HTCGetEndpointStatistics(HTC_HANDLE HTCHandle, - HTC_ENDPOINT_ID Endpoint, - HTC_ENDPOINT_STAT_ACTION Action, - struct htc_endpoint_stats *pStats) -{ - - struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); - bool clearStats = false; - bool sample = false; - - switch (Action) { - case HTC_EP_STAT_SAMPLE : - sample = true; - break; - case HTC_EP_STAT_SAMPLE_AND_CLEAR : - sample = true; - clearStats = true; - break; - case HTC_EP_STAT_CLEAR : - clearStats = true; - break; - default: - break; - } - - A_ASSERT(Endpoint < ENDPOINT_MAX); - - /* lock out TX and RX while we sample and/or clear */ - LOCK_HTC_TX(target); - LOCK_HTC_RX(target); - - if (sample) { - A_ASSERT(pStats != NULL); - /* return the stats to the caller */ - memcpy(pStats, &target->EndPoint[Endpoint].EndPointStats, sizeof(struct htc_endpoint_stats)); - } - - if (clearStats) { - /* reset stats */ - A_MEMZERO(&target->EndPoint[Endpoint].EndPointStats, sizeof(struct htc_endpoint_stats)); - } - - UNLOCK_HTC_RX(target); - UNLOCK_HTC_TX(target); - - return true; -} - -struct ar6k_device *HTCGetAR6KDevice(void *HTCHandle) -{ - struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); - return &target->Device; -} - diff --git a/drivers/staging/ath6kl/htc2/htc_debug.h b/drivers/staging/ath6kl/htc2/htc_debug.h deleted file mode 100644 index 8455703..0000000 --- a/drivers/staging/ath6kl/htc2/htc_debug.h +++ /dev/null @@ -1,38 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="htc_debug.h" company="Atheros"> -// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Author(s): ="Atheros" -//============================================================================== -#ifndef HTC_DEBUG_H_ -#define HTC_DEBUG_H_ - -#define ATH_MODULE_NAME htc -#include "a_debug.h" - -/* ------- Debug related stuff ------- */ - -#define ATH_DEBUG_SEND ATH_DEBUG_MAKE_MODULE_MASK(0) -#define ATH_DEBUG_RECV ATH_DEBUG_MAKE_MODULE_MASK(1) -#define ATH_DEBUG_SYNC ATH_DEBUG_MAKE_MODULE_MASK(2) -#define ATH_DEBUG_DUMP ATH_DEBUG_MAKE_MODULE_MASK(3) -#define ATH_DEBUG_IRQ ATH_DEBUG_MAKE_MODULE_MASK(4) - - -#endif /*HTC_DEBUG_H_*/ diff --git a/drivers/staging/ath6kl/htc2/htc_internal.h b/drivers/staging/ath6kl/htc2/htc_internal.h deleted file mode 100644 index cac9735..0000000 --- a/drivers/staging/ath6kl/htc2/htc_internal.h +++ /dev/null @@ -1,211 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="htc_internal.h" company="Atheros"> -// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Author(s): ="Atheros" -//============================================================================== -#ifndef _HTC_INTERNAL_H_ -#define _HTC_INTERNAL_H_ - -/* for debugging, uncomment this to capture the last frame header, on frame header - * processing errors, the last frame header is dump for comparison */ -//#define HTC_CAPTURE_LAST_FRAME - - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* Header files */ - -#include "a_config.h" -#include "athdefs.h" -#include "a_osapi.h" -#include "htc_debug.h" -#include "htc.h" -#include "htc_api.h" -#include "bmi_msg.h" -#include "hif.h" -#include "AR6000/ar6k.h" - -/* HTC operational parameters */ -#define HTC_TARGET_RESPONSE_TIMEOUT 2000 /* in ms */ -#define HTC_TARGET_DEBUG_INTR_MASK 0x01 -#define HTC_TARGET_CREDIT_INTR_MASK 0xF0 - -#define HTC_HOST_MAX_MSG_PER_BUNDLE 8 -#define HTC_MIN_HTC_MSGS_TO_BUNDLE 2 - -/* packet flags */ - -#define HTC_RX_PKT_IGNORE_LOOKAHEAD (1 << 0) -#define HTC_RX_PKT_REFRESH_HDR (1 << 1) -#define HTC_RX_PKT_PART_OF_BUNDLE (1 << 2) -#define HTC_RX_PKT_NO_RECYCLE (1 << 3) - -/* scatter request flags */ - -#define HTC_SCATTER_REQ_FLAGS_PARTIAL_BUNDLE (1 << 0) - -struct htc_endpoint { - HTC_ENDPOINT_ID Id; - HTC_SERVICE_ID ServiceID; /* service ID this endpoint is bound to - non-zero value means this endpoint is in use */ - struct htc_packet_queue TxQueue; /* HTC frame buffer TX queue */ - struct htc_packet_queue RxBuffers; /* HTC frame buffer RX list */ - struct htc_endpoint_credit_dist CreditDist; /* credit distribution structure (exposed to driver layer) */ - struct htc_ep_callbacks EpCallBacks; /* callbacks associated with this endpoint */ - int MaxTxQueueDepth; /* max depth of the TX queue before we need to - call driver's full handler */ - int MaxMsgLength; /* max length of endpoint message */ - int TxProcessCount; /* reference count to continue tx processing */ - struct htc_packet_queue RecvIndicationQueue; /* recv packets ready to be indicated */ - int RxProcessCount; /* reference count to allow single processing context */ - struct htc_target *target; /* back pointer to target */ - u8 SeqNo; /* TX seq no (helpful) for debugging */ - u32 LocalConnectionFlags; /* local connection flags */ - struct htc_endpoint_stats EndPointStats; /* endpoint statistics */ -}; - -#define INC_HTC_EP_STAT(p,stat,count) (p)->EndPointStats.stat += (count); -#define HTC_SERVICE_TX_PACKET_TAG HTC_TX_PACKET_TAG_INTERNAL - -#define NUM_CONTROL_BUFFERS 8 -#define NUM_CONTROL_TX_BUFFERS 2 -#define NUM_CONTROL_RX_BUFFERS (NUM_CONTROL_BUFFERS - NUM_CONTROL_TX_BUFFERS) - -struct htc_control_buffer { - struct htc_packet HtcPacket; - u8 *Buffer; -}; - -#define HTC_RECV_WAIT_BUFFERS (1 << 0) -#define HTC_OP_STATE_STOPPING (1 << 0) - -/* our HTC target state */ -struct htc_target { - struct htc_endpoint EndPoint[ENDPOINT_MAX]; - struct htc_control_buffer HTCControlBuffers[NUM_CONTROL_BUFFERS]; - struct htc_endpoint_credit_dist *EpCreditDistributionListHead; - struct htc_packet_queue ControlBufferTXFreeList; - struct htc_packet_queue ControlBufferRXFreeList; - HTC_CREDIT_DIST_CALLBACK DistributeCredits; - HTC_CREDIT_INIT_CALLBACK InitCredits; - void *pCredDistContext; - int TargetCredits; - unsigned int TargetCreditSize; - A_MUTEX_T HTCLock; - A_MUTEX_T HTCRxLock; - A_MUTEX_T HTCTxLock; - struct ar6k_device Device; /* AR6K - specific state */ - u32 OpStateFlags; - u32 RecvStateFlags; - HTC_ENDPOINT_ID EpWaitingForBuffers; - bool TargetFailure; -#ifdef HTC_CAPTURE_LAST_FRAME - struct htc_frame_hdr LastFrameHdr; /* useful for debugging */ - u8 LastTrailer[256]; - u8 LastTrailerLength; -#endif - struct htc_init_info HTCInitInfo; - u8 HTCTargetVersion; - int MaxMsgPerBundle; /* max messages per bundle for HTC */ - bool SendBundlingEnabled; /* run time enable for send bundling (dynamic) */ - int RecvBundlingEnabled; /* run time enable for recv bundling (dynamic) */ -}; - -#define HTC_STOPPING(t) ((t)->OpStateFlags & HTC_OP_STATE_STOPPING) -#define LOCK_HTC(t) A_MUTEX_LOCK(&(t)->HTCLock); -#define UNLOCK_HTC(t) A_MUTEX_UNLOCK(&(t)->HTCLock); -#define LOCK_HTC_RX(t) A_MUTEX_LOCK(&(t)->HTCRxLock); -#define UNLOCK_HTC_RX(t) A_MUTEX_UNLOCK(&(t)->HTCRxLock); -#define LOCK_HTC_TX(t) A_MUTEX_LOCK(&(t)->HTCTxLock); -#define UNLOCK_HTC_TX(t) A_MUTEX_UNLOCK(&(t)->HTCTxLock); - -#define GET_HTC_TARGET_FROM_HANDLE(hnd) ((struct htc_target *)(hnd)) -#define HTC_RECYCLE_RX_PKT(target,p,e) \ -{ \ - if ((p)->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_NO_RECYCLE) { \ - HTC_PACKET_RESET_RX(pPacket); \ - pPacket->Status = A_ECANCELED; \ - (e)->EpCallBacks.EpRecv((e)->EpCallBacks.pContext, \ - (p)); \ - } else { \ - HTC_PACKET_RESET_RX(pPacket); \ - HTCAddReceivePkt((HTC_HANDLE)(target),(p)); \ - } \ -} - -/* internal HTC functions */ -void HTCControlTxComplete(void *Context, struct htc_packet *pPacket); -void HTCControlRecv(void *Context, struct htc_packet *pPacket); -int HTCWaitforControlMessage(struct htc_target *target, struct htc_packet **ppControlPacket); -struct htc_packet *HTCAllocControlBuffer(struct htc_target *target, struct htc_packet_queue *pList); -void HTCFreeControlBuffer(struct htc_target *target, struct htc_packet *pPacket, struct htc_packet_queue *pList); -int HTCIssueSend(struct htc_target *target, struct htc_packet *pPacket); -void HTCRecvCompleteHandler(void *Context, struct htc_packet *pPacket); -int HTCRecvMessagePendingHandler(void *Context, u32 MsgLookAheads[], int NumLookAheads, bool *pAsyncProc, int *pNumPktsFetched); -void HTCProcessCreditRpt(struct htc_target *target, HTC_CREDIT_REPORT *pRpt, int NumEntries, HTC_ENDPOINT_ID FromEndpoint); -int HTCSendSetupComplete(struct htc_target *target); -void HTCFlushRecvBuffers(struct htc_target *target); -void HTCFlushSendPkts(struct htc_target *target); - -#ifdef ATH_DEBUG_MODULE -void DumpCreditDist(struct htc_endpoint_credit_dist *pEPDist); -void DumpCreditDistStates(struct htc_target *target); -void DebugDumpBytes(u8 *buffer, u16 length, char *pDescription); -#endif - -static INLINE struct htc_packet *HTC_ALLOC_CONTROL_TX(struct htc_target *target) { - struct htc_packet *pPacket = HTCAllocControlBuffer(target,&target->ControlBufferTXFreeList); - if (pPacket != NULL) { - /* set payload pointer area with some headroom */ - pPacket->pBuffer = pPacket->pBufferStart + HTC_HDR_LENGTH; - } - return pPacket; -} - -#define HTC_FREE_CONTROL_TX(t,p) HTCFreeControlBuffer((t),(p),&(t)->ControlBufferTXFreeList) -#define HTC_ALLOC_CONTROL_RX(t) HTCAllocControlBuffer((t),&(t)->ControlBufferRXFreeList) -#define HTC_FREE_CONTROL_RX(t,p) \ -{ \ - HTC_PACKET_RESET_RX(p); \ - HTCFreeControlBuffer((t),(p),&(t)->ControlBufferRXFreeList); \ -} - -#define HTC_PREPARE_SEND_PKT(pP,sendflags,ctrl0,ctrl1) \ -{ \ - u8 *pHdrBuf; \ - (pP)->pBuffer -= HTC_HDR_LENGTH; \ - pHdrBuf = (pP)->pBuffer; \ - A_SET_UINT16_FIELD(pHdrBuf,struct htc_frame_hdr,PayloadLen,(u16)(pP)->ActualLength); \ - A_SET_UINT8_FIELD(pHdrBuf,struct htc_frame_hdr,Flags,(sendflags)); \ - A_SET_UINT8_FIELD(pHdrBuf,struct htc_frame_hdr,EndpointID, (u8)(pP)->Endpoint); \ - A_SET_UINT8_FIELD(pHdrBuf,struct htc_frame_hdr,ControlBytes[0], (u8)(ctrl0)); \ - A_SET_UINT8_FIELD(pHdrBuf,struct htc_frame_hdr,ControlBytes[1], (u8)(ctrl1)); \ -} - -#define HTC_UNPREPARE_SEND_PKT(pP) \ - (pP)->pBuffer += HTC_HDR_LENGTH; \ - -#ifdef __cplusplus -} -#endif - -#endif /* _HTC_INTERNAL_H_ */ diff --git a/drivers/staging/ath6kl/htc2/htc_recv.c b/drivers/staging/ath6kl/htc2/htc_recv.c deleted file mode 100644 index 974cc8c..0000000 --- a/drivers/staging/ath6kl/htc2/htc_recv.c +++ /dev/null @@ -1,1572 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="htc_recv.c" company="Atheros"> -// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Author(s): ="Atheros" -//============================================================================== -#include "htc_internal.h" - -#define HTCIssueRecv(t, p) \ - DevRecvPacket(&(t)->Device, \ - (p), \ - (p)->ActualLength) - -#define DO_RCV_COMPLETION(e,q) DoRecvCompletion(e,q) - -#define DUMP_RECV_PKT_INFO(pP) \ - AR_DEBUG_PRINTF(ATH_DEBUG_RECV, (" HTC RECV packet 0x%lX (%d bytes) (hdr:0x%X) on ep : %d \n", \ - (unsigned long)(pP), \ - (pP)->ActualLength, \ - (pP)->PktInfo.AsRx.ExpectedHdr, \ - (pP)->Endpoint)) - -#define HTC_RX_STAT_PROFILE(t,ep,numLookAheads) \ -{ \ - INC_HTC_EP_STAT((ep), RxReceived, 1); \ - if ((numLookAheads) == 1) { \ - INC_HTC_EP_STAT((ep), RxLookAheads, 1); \ - } else if ((numLookAheads) > 1) { \ - INC_HTC_EP_STAT((ep), RxBundleLookAheads, 1); \ - } \ -} - -static void DoRecvCompletion(struct htc_endpoint *pEndpoint, - struct htc_packet_queue *pQueueToIndicate) -{ - - do { - - if (HTC_QUEUE_EMPTY(pQueueToIndicate)) { - /* nothing to indicate */ - break; - } - - if (pEndpoint->EpCallBacks.EpRecvPktMultiple != NULL) { - AR_DEBUG_PRINTF(ATH_DEBUG_RECV, (" HTC calling ep %d, recv multiple callback (%d pkts) \n", - pEndpoint->Id, HTC_PACKET_QUEUE_DEPTH(pQueueToIndicate))); - /* a recv multiple handler is being used, pass the queue to the handler */ - pEndpoint->EpCallBacks.EpRecvPktMultiple(pEndpoint->EpCallBacks.pContext, - pQueueToIndicate); - INIT_HTC_PACKET_QUEUE(pQueueToIndicate); - } else { - struct htc_packet *pPacket; - /* using legacy EpRecv */ - do { - pPacket = HTC_PACKET_DEQUEUE(pQueueToIndicate); - AR_DEBUG_PRINTF(ATH_DEBUG_RECV, (" HTC calling ep %d recv callback on packet 0x%lX \n", \ - pEndpoint->Id, (unsigned long)(pPacket))); - pEndpoint->EpCallBacks.EpRecv(pEndpoint->EpCallBacks.pContext, pPacket); - } while (!HTC_QUEUE_EMPTY(pQueueToIndicate)); - } - - } while (false); - -} - -static INLINE int HTCProcessTrailer(struct htc_target *target, - u8 *pBuffer, - int Length, - u32 *pNextLookAheads, - int *pNumLookAheads, - HTC_ENDPOINT_ID FromEndpoint) -{ - HTC_RECORD_HDR *pRecord; - u8 *pRecordBuf; - HTC_LOOKAHEAD_REPORT *pLookAhead; - u8 *pOrigBuffer; - int origLength; - int status; - - AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("+HTCProcessTrailer (length:%d) \n", Length)); - - if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) { - AR_DEBUG_PRINTBUF(pBuffer,Length,"Recv Trailer"); - } - - pOrigBuffer = pBuffer; - origLength = Length; - status = 0; - - while (Length > 0) { - - if (Length < sizeof(HTC_RECORD_HDR)) { - status = A_EPROTO; - break; - } - /* these are byte aligned structs */ - pRecord = (HTC_RECORD_HDR *)pBuffer; - Length -= sizeof(HTC_RECORD_HDR); - pBuffer += sizeof(HTC_RECORD_HDR); - - if (pRecord->Length > Length) { - /* no room left in buffer for record */ - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - (" invalid record length: %d (id:%d) buffer has: %d bytes left \n", - pRecord->Length, pRecord->RecordID, Length)); - status = A_EPROTO; - break; - } - /* start of record follows the header */ - pRecordBuf = pBuffer; - - switch (pRecord->RecordID) { - case HTC_RECORD_CREDITS: - AR_DEBUG_ASSERT(pRecord->Length >= sizeof(HTC_CREDIT_REPORT)); - HTCProcessCreditRpt(target, - (HTC_CREDIT_REPORT *)pRecordBuf, - pRecord->Length / (sizeof(HTC_CREDIT_REPORT)), - FromEndpoint); - break; - case HTC_RECORD_LOOKAHEAD: - AR_DEBUG_ASSERT(pRecord->Length >= sizeof(HTC_LOOKAHEAD_REPORT)); - pLookAhead = (HTC_LOOKAHEAD_REPORT *)pRecordBuf; - if ((pLookAhead->PreValid == ((~pLookAhead->PostValid) & 0xFF)) && - (pNextLookAheads != NULL)) { - - AR_DEBUG_PRINTF(ATH_DEBUG_RECV, - (" LookAhead Report Found (pre valid:0x%X, post valid:0x%X) \n", - pLookAhead->PreValid, - pLookAhead->PostValid)); - - /* look ahead bytes are valid, copy them over */ - ((u8 *)(&pNextLookAheads[0]))[0] = pLookAhead->LookAhead[0]; - ((u8 *)(&pNextLookAheads[0]))[1] = pLookAhead->LookAhead[1]; - ((u8 *)(&pNextLookAheads[0]))[2] = pLookAhead->LookAhead[2]; - ((u8 *)(&pNextLookAheads[0]))[3] = pLookAhead->LookAhead[3]; - -#ifdef ATH_DEBUG_MODULE - if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) { - DebugDumpBytes((u8 *)pNextLookAheads,4,"Next Look Ahead"); - } -#endif - /* just one normal lookahead */ - *pNumLookAheads = 1; - } - break; - case HTC_RECORD_LOOKAHEAD_BUNDLE: - AR_DEBUG_ASSERT(pRecord->Length >= sizeof(HTC_BUNDLED_LOOKAHEAD_REPORT)); - if (pRecord->Length >= sizeof(HTC_BUNDLED_LOOKAHEAD_REPORT) && - (pNextLookAheads != NULL)) { - HTC_BUNDLED_LOOKAHEAD_REPORT *pBundledLookAheadRpt; - int i; - - pBundledLookAheadRpt = (HTC_BUNDLED_LOOKAHEAD_REPORT *)pRecordBuf; - -#ifdef ATH_DEBUG_MODULE - if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) { - DebugDumpBytes(pRecordBuf,pRecord->Length,"Bundle LookAhead"); - } -#endif - - if ((pRecord->Length / (sizeof(HTC_BUNDLED_LOOKAHEAD_REPORT))) > - HTC_HOST_MAX_MSG_PER_BUNDLE) { - /* this should never happen, the target restricts the number - * of messages per bundle configured by the host */ - A_ASSERT(false); - status = A_EPROTO; - break; - } - - for (i = 0; i < (int)(pRecord->Length / (sizeof(HTC_BUNDLED_LOOKAHEAD_REPORT))); i++) { - ((u8 *)(&pNextLookAheads[i]))[0] = pBundledLookAheadRpt->LookAhead[0]; - ((u8 *)(&pNextLookAheads[i]))[1] = pBundledLookAheadRpt->LookAhead[1]; - ((u8 *)(&pNextLookAheads[i]))[2] = pBundledLookAheadRpt->LookAhead[2]; - ((u8 *)(&pNextLookAheads[i]))[3] = pBundledLookAheadRpt->LookAhead[3]; - pBundledLookAheadRpt++; - } - - *pNumLookAheads = i; - } - break; - default: - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, (" unhandled record: id:%d length:%d \n", - pRecord->RecordID, pRecord->Length)); - break; - } - - if (status) { - break; - } - - /* advance buffer past this record for next time around */ - pBuffer += pRecord->Length; - Length -= pRecord->Length; - } - -#ifdef ATH_DEBUG_MODULE - if (status) { - DebugDumpBytes(pOrigBuffer,origLength,"BAD Recv Trailer"); - } -#endif - - AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("-HTCProcessTrailer \n")); - return status; - -} - -/* process a received message (i.e. strip off header, process any trailer data) - * note : locks must be released when this function is called */ -static int HTCProcessRecvHeader(struct htc_target *target, - struct htc_packet *pPacket, - u32 *pNextLookAheads, - int *pNumLookAheads) -{ - u8 temp; - u8 *pBuf; - int status = 0; - u16 payloadLen; - u32 lookAhead; - - pBuf = pPacket->pBuffer; - - if (pNumLookAheads != NULL) { - *pNumLookAheads = 0; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("+HTCProcessRecvHeader \n")); - - if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) { - AR_DEBUG_PRINTBUF(pBuf,pPacket->ActualLength,"HTC Recv PKT"); - } - - do { - /* note, we cannot assume the alignment of pBuffer, so we use the safe macros to - * retrieve 16 bit fields */ - payloadLen = A_GET_UINT16_FIELD(pBuf, struct htc_frame_hdr, PayloadLen); - - ((u8 *)&lookAhead)[0] = pBuf[0]; - ((u8 *)&lookAhead)[1] = pBuf[1]; - ((u8 *)&lookAhead)[2] = pBuf[2]; - ((u8 *)&lookAhead)[3] = pBuf[3]; - - if (pPacket->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_REFRESH_HDR) { - /* refresh expected hdr, since this was unknown at the time we grabbed the packets - * as part of a bundle */ - pPacket->PktInfo.AsRx.ExpectedHdr = lookAhead; - /* refresh actual length since we now have the real header */ - pPacket->ActualLength = payloadLen + HTC_HDR_LENGTH; - - /* validate the actual header that was refreshed */ - if (pPacket->ActualLength > pPacket->BufferLength) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("Refreshed HDR payload length (%d) in bundled RECV is invalid (hdr: 0x%X) \n", - payloadLen, lookAhead)); - /* limit this to max buffer just to print out some of the buffer */ - pPacket->ActualLength = min(pPacket->ActualLength, pPacket->BufferLength); - status = A_EPROTO; - break; - } - - if (pPacket->Endpoint != A_GET_UINT8_FIELD(pBuf, struct htc_frame_hdr, EndpointID)) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("Refreshed HDR endpoint (%d) does not match expected endpoint (%d) \n", - A_GET_UINT8_FIELD(pBuf, struct htc_frame_hdr, EndpointID), pPacket->Endpoint)); - status = A_EPROTO; - break; - } - } - - if (lookAhead != pPacket->PktInfo.AsRx.ExpectedHdr) { - /* somehow the lookahead that gave us the full read length did not - * reflect the actual header in the pending message */ - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("HTCProcessRecvHeader, lookahead mismatch! (pPkt:0x%lX flags:0x%X) \n", - (unsigned long)pPacket, pPacket->PktInfo.AsRx.HTCRxFlags)); -#ifdef ATH_DEBUG_MODULE - DebugDumpBytes((u8 *)&pPacket->PktInfo.AsRx.ExpectedHdr,4,"Expected Message LookAhead"); - DebugDumpBytes(pBuf,sizeof(struct htc_frame_hdr),"Current Frame Header"); -#ifdef HTC_CAPTURE_LAST_FRAME - DebugDumpBytes((u8 *)&target->LastFrameHdr,sizeof(struct htc_frame_hdr),"Last Frame Header"); - if (target->LastTrailerLength != 0) { - DebugDumpBytes(target->LastTrailer, - target->LastTrailerLength, - "Last trailer"); - } -#endif -#endif - status = A_EPROTO; - break; - } - - /* get flags */ - temp = A_GET_UINT8_FIELD(pBuf, struct htc_frame_hdr, Flags); - - if (temp & HTC_FLAGS_RECV_TRAILER) { - /* this packet has a trailer */ - - /* extract the trailer length in control byte 0 */ - temp = A_GET_UINT8_FIELD(pBuf, struct htc_frame_hdr, ControlBytes[0]); - - if ((temp < sizeof(HTC_RECORD_HDR)) || (temp > payloadLen)) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("HTCProcessRecvHeader, invalid header (payloadlength should be :%d, CB[0] is:%d) \n", - payloadLen, temp)); - status = A_EPROTO; - break; - } - - if (pPacket->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_IGNORE_LOOKAHEAD) { - /* this packet was fetched as part of an HTC bundle, the embedded lookahead is - * not valid since the next packet may have already been fetched as part of the - * bundle */ - pNextLookAheads = NULL; - pNumLookAheads = NULL; - } - - /* process trailer data that follows HDR + application payload */ - status = HTCProcessTrailer(target, - (pBuf + HTC_HDR_LENGTH + payloadLen - temp), - temp, - pNextLookAheads, - pNumLookAheads, - pPacket->Endpoint); - - if (status) { - break; - } - -#ifdef HTC_CAPTURE_LAST_FRAME - memcpy(target->LastTrailer, (pBuf + HTC_HDR_LENGTH + payloadLen - temp), temp); - target->LastTrailerLength = temp; -#endif - /* trim length by trailer bytes */ - pPacket->ActualLength -= temp; - } -#ifdef HTC_CAPTURE_LAST_FRAME - else { - target->LastTrailerLength = 0; - } -#endif - - /* if we get to this point, the packet is good */ - /* remove header and adjust length */ - pPacket->pBuffer += HTC_HDR_LENGTH; - pPacket->ActualLength -= HTC_HDR_LENGTH; - - } while (false); - - if (status) { - /* dump the whole packet */ -#ifdef ATH_DEBUG_MODULE - DebugDumpBytes(pBuf,pPacket->ActualLength < 256 ? pPacket->ActualLength : 256 ,"BAD HTC Recv PKT"); -#endif - } else { -#ifdef HTC_CAPTURE_LAST_FRAME - memcpy(&target->LastFrameHdr,pBuf,sizeof(struct htc_frame_hdr)); -#endif - if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_RECV)) { - if (pPacket->ActualLength > 0) { - AR_DEBUG_PRINTBUF(pPacket->pBuffer,pPacket->ActualLength,"HTC - Application Msg"); - } - } - } - - AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("-HTCProcessRecvHeader \n")); - return status; -} - -static INLINE void HTCAsyncRecvCheckMorePackets(struct htc_target *target, - u32 NextLookAheads[], - int NumLookAheads, - bool CheckMoreMsgs) -{ - /* was there a lookahead for the next packet? */ - if (NumLookAheads > 0) { - int nextStatus; - int fetched = 0; - AR_DEBUG_PRINTF(ATH_DEBUG_RECV, - ("HTCAsyncRecvCheckMorePackets - num lookaheads were non-zero : %d \n", - NumLookAheads)); - /* force status re-check */ - REF_IRQ_STATUS_RECHECK(&target->Device); - /* we have more packets, get the next packet fetch started */ - nextStatus = HTCRecvMessagePendingHandler(target, NextLookAheads, NumLookAheads, NULL, &fetched); - if (A_EPROTO == nextStatus) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("Next look ahead from recv header was INVALID\n")); -#ifdef ATH_DEBUG_MODULE - DebugDumpBytes((u8 *)NextLookAheads, - NumLookAheads * (sizeof(u32)), - "BAD lookaheads from lookahead report"); -#endif - } - if (!nextStatus && !fetched) { - /* we could not fetch any more packets due to resources */ - DevAsyncIrqProcessComplete(&target->Device); - } - } else { - if (CheckMoreMsgs) { - AR_DEBUG_PRINTF(ATH_DEBUG_RECV, - ("HTCAsyncRecvCheckMorePackets - rechecking for more messages...\n")); - /* if we did not get anything on the look-ahead, - * call device layer to asynchronously re-check for messages. If we can keep the async - * processing going we get better performance. If there is a pending message we will keep processing - * messages asynchronously which should pipeline things nicely */ - DevCheckPendingRecvMsgsAsync(&target->Device); - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("HTCAsyncRecvCheckMorePackets - no check \n")); - } - } - - -} - - /* unload the recv completion queue */ -static INLINE void DrainRecvIndicationQueue(struct htc_target *target, struct htc_endpoint *pEndpoint) -{ - struct htc_packet_queue recvCompletions; - - AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("+DrainRecvIndicationQueue \n")); - - INIT_HTC_PACKET_QUEUE(&recvCompletions); - - LOCK_HTC_RX(target); - - /* increment rx processing count on entry */ - pEndpoint->RxProcessCount++; - if (pEndpoint->RxProcessCount > 1) { - pEndpoint->RxProcessCount--; - /* another thread or task is draining the RX completion queue on this endpoint - * that thread will reset the rx processing count when the queue is drained */ - UNLOCK_HTC_RX(target); - return; - } - - /******* at this point only 1 thread may enter ******/ - - while (true) { - - /* transfer items from main recv queue to the local one so we can release the lock */ - HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&recvCompletions, &pEndpoint->RecvIndicationQueue); - - if (HTC_QUEUE_EMPTY(&recvCompletions)) { - /* all drained */ - break; - } - - /* release lock while we do the recv completions - * other threads can now queue more recv completions */ - UNLOCK_HTC_RX(target); - - AR_DEBUG_PRINTF(ATH_DEBUG_RECV, - ("DrainRecvIndicationQueue : completing %d RECV packets \n", - HTC_PACKET_QUEUE_DEPTH(&recvCompletions))); - /* do completion */ - DO_RCV_COMPLETION(pEndpoint,&recvCompletions); - - /* re-acquire lock to grab some more completions */ - LOCK_HTC_RX(target); - } - - /* reset count */ - pEndpoint->RxProcessCount = 0; - UNLOCK_HTC_RX(target); - - AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("-DrainRecvIndicationQueue \n")); - -} - - /* optimization for recv packets, we can indicate a "hint" that there are more - * single-packets to fetch on this endpoint */ -#define SET_MORE_RX_PACKET_INDICATION_FLAG(L,N,E,P) \ - if ((N) > 0) { SetRxPacketIndicationFlags((L)[0],(E),(P)); } - - /* for bundled frames, we can force the flag to indicate there are more packets */ -#define FORCE_MORE_RX_PACKET_INDICATION_FLAG(P) \ - (P)->PktInfo.AsRx.IndicationFlags |= HTC_RX_FLAGS_INDICATE_MORE_PKTS; - - /* note: this function can be called with the RX lock held */ -static INLINE void SetRxPacketIndicationFlags(u32 LookAhead, - struct htc_endpoint *pEndpoint, - struct htc_packet *pPacket) -{ - struct htc_frame_hdr *pHdr = (struct htc_frame_hdr *)&LookAhead; - /* check to see if the "next" packet is from the same endpoint of the - completing packet */ - if (pHdr->EndpointID == pPacket->Endpoint) { - /* check that there is a buffer available to actually fetch it */ - if (!HTC_QUEUE_EMPTY(&pEndpoint->RxBuffers)) { - /* provide a hint that there are more RX packets to fetch */ - FORCE_MORE_RX_PACKET_INDICATION_FLAG(pPacket); - } - } -} - - -/* asynchronous completion handler for recv packet fetching, when the device layer - * completes a read request, it will call this completion handler */ -void HTCRecvCompleteHandler(void *Context, struct htc_packet *pPacket) -{ - struct htc_target *target = (struct htc_target *)Context; - struct htc_endpoint *pEndpoint; - u32 nextLookAheads[HTC_HOST_MAX_MSG_PER_BUNDLE]; - int numLookAheads = 0; - int status; - bool checkMorePkts = true; - - AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("+HTCRecvCompleteHandler (pkt:0x%lX, status:%d, ep:%d) \n", - (unsigned long)pPacket, pPacket->Status, pPacket->Endpoint)); - - A_ASSERT(!IS_DEV_IRQ_PROC_SYNC_MODE(&target->Device)); - AR_DEBUG_ASSERT(pPacket->Endpoint < ENDPOINT_MAX); - pEndpoint = &target->EndPoint[pPacket->Endpoint]; - pPacket->Completion = NULL; - - /* get completion status */ - status = pPacket->Status; - - do { - - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HTCRecvCompleteHandler: request failed (status:%d, ep:%d) \n", - pPacket->Status, pPacket->Endpoint)); - break; - } - /* process the header for any trailer data */ - status = HTCProcessRecvHeader(target,pPacket,nextLookAheads,&numLookAheads); - - if (status) { - break; - } - - if (pPacket->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_IGNORE_LOOKAHEAD) { - /* this packet was part of a bundle that had to be broken up. - * It was fetched one message at a time. There may be other asynchronous reads queued behind this one. - * Do no issue another check for more packets since the last one in the series of requests - * will handle it */ - checkMorePkts = false; - } - - DUMP_RECV_PKT_INFO(pPacket); - LOCK_HTC_RX(target); - SET_MORE_RX_PACKET_INDICATION_FLAG(nextLookAheads,numLookAheads,pEndpoint,pPacket); - /* we have a good packet, queue it to the completion queue */ - HTC_PACKET_ENQUEUE(&pEndpoint->RecvIndicationQueue,pPacket); - HTC_RX_STAT_PROFILE(target,pEndpoint,numLookAheads); - UNLOCK_HTC_RX(target); - - /* check for more recv packets before indicating */ - HTCAsyncRecvCheckMorePackets(target,nextLookAheads,numLookAheads,checkMorePkts); - - } while (false); - - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("HTCRecvCompleteHandler , message fetch failed (status = %d) \n", - status)); - /* recycle this packet */ - HTC_RECYCLE_RX_PKT(target, pPacket, pEndpoint); - } else { - /* a good packet was queued, drain the queue */ - DrainRecvIndicationQueue(target,pEndpoint); - } - - AR_DEBUG_PRINTF(ATH_DEBUG_RECV, ("-HTCRecvCompleteHandler\n")); -} - -/* synchronously wait for a control message from the target, - * This function is used at initialization time ONLY. At init messages - * on ENDPOINT 0 are expected. */ -int HTCWaitforControlMessage(struct htc_target *target, struct htc_packet **ppControlPacket) -{ - int status; - u32 lookAhead; - struct htc_packet *pPacket = NULL; - struct htc_frame_hdr *pHdr; - - AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HTCWaitforControlMessage \n")); - - do { - - *ppControlPacket = NULL; - - /* call the polling function to see if we have a message */ - status = DevPollMboxMsgRecv(&target->Device, - &lookAhead, - HTC_TARGET_RESPONSE_TIMEOUT); - - if (status) { - break; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_RECV, - ("HTCWaitforControlMessage : lookAhead : 0x%X \n", lookAhead)); - - /* check the lookahead */ - pHdr = (struct htc_frame_hdr *)&lookAhead; - - if (pHdr->EndpointID != ENDPOINT_0) { - /* unexpected endpoint number, should be zero */ - AR_DEBUG_ASSERT(false); - status = A_EPROTO; - break; - } - - if (status) { - /* bad message */ - AR_DEBUG_ASSERT(false); - status = A_EPROTO; - break; - } - - pPacket = HTC_ALLOC_CONTROL_RX(target); - - if (pPacket == NULL) { - AR_DEBUG_ASSERT(false); - status = A_NO_MEMORY; - break; - } - - pPacket->PktInfo.AsRx.HTCRxFlags = 0; - pPacket->PktInfo.AsRx.ExpectedHdr = lookAhead; - pPacket->ActualLength = pHdr->PayloadLen + HTC_HDR_LENGTH; - - if (pPacket->ActualLength > pPacket->BufferLength) { - AR_DEBUG_ASSERT(false); - status = A_EPROTO; - break; - } - - /* we want synchronous operation */ - pPacket->Completion = NULL; - - /* get the message from the device, this will block */ - status = HTCIssueRecv(target, pPacket); - - if (status) { - break; - } - - /* process receive header */ - status = HTCProcessRecvHeader(target,pPacket,NULL,NULL); - - pPacket->Status = status; - - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("HTCWaitforControlMessage, HTCProcessRecvHeader failed (status = %d) \n", - status)); - break; - } - - /* give the caller this control message packet, they are responsible to free */ - *ppControlPacket = pPacket; - - } while (false); - - if (status) { - if (pPacket != NULL) { - /* cleanup buffer on error */ - HTC_FREE_CONTROL_RX(target,pPacket); - } - } - - AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-HTCWaitforControlMessage \n")); - - return status; -} - -static int AllocAndPrepareRxPackets(struct htc_target *target, - u32 LookAheads[], - int Messages, - struct htc_endpoint *pEndpoint, - struct htc_packet_queue *pQueue) -{ - int status = 0; - struct htc_packet *pPacket; - struct htc_frame_hdr *pHdr; - int i,j; - int numMessages; - int fullLength; - bool noRecycle; - - /* lock RX while we assemble the packet buffers */ - LOCK_HTC_RX(target); - - for (i = 0; i < Messages; i++) { - - pHdr = (struct htc_frame_hdr *)&LookAheads[i]; - - if (pHdr->EndpointID >= ENDPOINT_MAX) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Invalid Endpoint in look-ahead: %d \n",pHdr->EndpointID)); - /* invalid endpoint */ - status = A_EPROTO; - break; - } - - if (pHdr->EndpointID != pEndpoint->Id) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Invalid Endpoint in look-ahead: %d should be : %d (index:%d)\n", - pHdr->EndpointID, pEndpoint->Id, i)); - /* invalid endpoint */ - status = A_EPROTO; - break; - } - - if (pHdr->PayloadLen > HTC_MAX_PAYLOAD_LENGTH) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Payload length %d exceeds max HTC : %d !\n", - pHdr->PayloadLen, (u32)HTC_MAX_PAYLOAD_LENGTH)); - status = A_EPROTO; - break; - } - - if (0 == pEndpoint->ServiceID) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Endpoint %d is not connected !\n",pHdr->EndpointID)); - /* endpoint isn't even connected */ - status = A_EPROTO; - break; - } - - if ((pHdr->Flags & HTC_FLAGS_RECV_BUNDLE_CNT_MASK) == 0) { - /* HTC header only indicates 1 message to fetch */ - numMessages = 1; - } else { - /* HTC header indicates that every packet to follow has the same padded length so that it can - * be optimally fetched as a full bundle */ - numMessages = (pHdr->Flags & HTC_FLAGS_RECV_BUNDLE_CNT_MASK) >> HTC_FLAGS_RECV_BUNDLE_CNT_SHIFT; - /* the count doesn't include the starter frame, just a count of frames to follow */ - numMessages++; - A_ASSERT(numMessages <= target->MaxMsgPerBundle); - INC_HTC_EP_STAT(pEndpoint, RxBundleIndFromHdr, 1); - AR_DEBUG_PRINTF(ATH_DEBUG_RECV, - ("HTC header indicates :%d messages can be fetched as a bundle \n",numMessages)); - } - - fullLength = DEV_CALC_RECV_PADDED_LEN(&target->Device,pHdr->PayloadLen + sizeof(struct htc_frame_hdr)); - - /* get packet buffers for each message, if there was a bundle detected in the header, - * use pHdr as a template to fetch all packets in the bundle */ - for (j = 0; j < numMessages; j++) { - - /* reset flag, any packets allocated using the RecvAlloc() API cannot be recycled on cleanup, - * they must be explicitly returned */ - noRecycle = false; - - if (pEndpoint->EpCallBacks.EpRecvAlloc != NULL) { - UNLOCK_HTC_RX(target); - noRecycle = true; - /* user is using a per-packet allocation callback */ - pPacket = pEndpoint->EpCallBacks.EpRecvAlloc(pEndpoint->EpCallBacks.pContext, - pEndpoint->Id, - fullLength); - LOCK_HTC_RX(target); - - } else if ((pEndpoint->EpCallBacks.EpRecvAllocThresh != NULL) && - (fullLength > pEndpoint->EpCallBacks.RecvAllocThreshold)) { - INC_HTC_EP_STAT(pEndpoint,RxAllocThreshHit,1); - INC_HTC_EP_STAT(pEndpoint,RxAllocThreshBytes,pHdr->PayloadLen); - /* threshold was hit, call the special recv allocation callback */ - UNLOCK_HTC_RX(target); - noRecycle = true; - /* user wants to allocate packets above a certain threshold */ - pPacket = pEndpoint->EpCallBacks.EpRecvAllocThresh(pEndpoint->EpCallBacks.pContext, - pEndpoint->Id, - fullLength); - LOCK_HTC_RX(target); - - } else { - /* user is using a refill handler that can refill multiple HTC buffers */ - - /* get a packet from the endpoint recv queue */ - pPacket = HTC_PACKET_DEQUEUE(&pEndpoint->RxBuffers); - - if (NULL == pPacket) { - /* check for refill handler */ - if (pEndpoint->EpCallBacks.EpRecvRefill != NULL) { - UNLOCK_HTC_RX(target); - /* call the re-fill handler */ - pEndpoint->EpCallBacks.EpRecvRefill(pEndpoint->EpCallBacks.pContext, - pEndpoint->Id); - LOCK_HTC_RX(target); - /* check if we have more buffers */ - pPacket = HTC_PACKET_DEQUEUE(&pEndpoint->RxBuffers); - /* fall through */ - } - } - } - - if (NULL == pPacket) { - /* this is not an error, we simply need to mark that we are waiting for buffers.*/ - target->RecvStateFlags |= HTC_RECV_WAIT_BUFFERS; - target->EpWaitingForBuffers = pEndpoint->Id; - status = A_NO_RESOURCE; - break; - } - - AR_DEBUG_ASSERT(pPacket->Endpoint == pEndpoint->Id); - /* clear flags */ - pPacket->PktInfo.AsRx.HTCRxFlags = 0; - pPacket->PktInfo.AsRx.IndicationFlags = 0; - pPacket->Status = 0; - - if (noRecycle) { - /* flag that these packets cannot be recycled, they have to be returned to the - * user */ - pPacket->PktInfo.AsRx.HTCRxFlags |= HTC_RX_PKT_NO_RECYCLE; - } - /* add packet to queue (also incase we need to cleanup down below) */ - HTC_PACKET_ENQUEUE(pQueue,pPacket); - - if (HTC_STOPPING(target)) { - status = A_ECANCELED; - break; - } - - /* make sure this message can fit in the endpoint buffer */ - if ((u32)fullLength > pPacket->BufferLength) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("Payload Length Error : header reports payload of: %d (%d) endpoint buffer size: %d \n", - pHdr->PayloadLen, fullLength, pPacket->BufferLength)); - status = A_EPROTO; - break; - } - - if (j > 0) { - /* for messages fetched in a bundle the expected lookahead is unknown since we - * are only using the lookahead of the first packet as a template of what to - * expect for lengths */ - /* flag that once we get the real HTC header we need to refesh the information */ - pPacket->PktInfo.AsRx.HTCRxFlags |= HTC_RX_PKT_REFRESH_HDR; - /* set it to something invalid */ - pPacket->PktInfo.AsRx.ExpectedHdr = 0xFFFFFFFF; - } else { - - pPacket->PktInfo.AsRx.ExpectedHdr = LookAheads[i]; /* set expected look ahead */ - } - /* set the amount of data to fetch */ - pPacket->ActualLength = pHdr->PayloadLen + HTC_HDR_LENGTH; - } - - if (status) { - if (A_NO_RESOURCE == status) { - /* this is actually okay */ - status = 0; - } - break; - } - - } - - UNLOCK_HTC_RX(target); - - if (status) { - while (!HTC_QUEUE_EMPTY(pQueue)) { - pPacket = HTC_PACKET_DEQUEUE(pQueue); - /* recycle all allocated packets */ - HTC_RECYCLE_RX_PKT(target,pPacket,&target->EndPoint[pPacket->Endpoint]); - } - } - - return status; -} - -static void HTCAsyncRecvScatterCompletion(struct hif_scatter_req *pScatterReq) -{ - int i; - struct htc_packet *pPacket; - struct htc_endpoint *pEndpoint; - u32 lookAheads[HTC_HOST_MAX_MSG_PER_BUNDLE]; - int numLookAheads = 0; - struct htc_target *target = (struct htc_target *)pScatterReq->Context; - int status; - bool partialBundle = false; - struct htc_packet_queue localRecvQueue; - bool procError = false; - - AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HTCAsyncRecvScatterCompletion TotLen: %d Entries: %d\n", - pScatterReq->TotalLength, pScatterReq->ValidScatterEntries)); - - A_ASSERT(!IS_DEV_IRQ_PROC_SYNC_MODE(&target->Device)); - - if (pScatterReq->CompletionStatus) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("** Recv Scatter Request Failed: %d \n",pScatterReq->CompletionStatus)); - } - - if (pScatterReq->CallerFlags & HTC_SCATTER_REQ_FLAGS_PARTIAL_BUNDLE) { - partialBundle = true; - } - - DEV_FINISH_SCATTER_OPERATION(pScatterReq); - - INIT_HTC_PACKET_QUEUE(&localRecvQueue); - - pPacket = (struct htc_packet *)pScatterReq->ScatterList[0].pCallerContexts[0]; - /* note: all packets in a scatter req are for the same endpoint ! */ - pEndpoint = &target->EndPoint[pPacket->Endpoint]; - - /* walk through the scatter list and process */ - /* **** NOTE: DO NOT HOLD ANY LOCKS here, HTCProcessRecvHeader can take the TX lock - * as it processes credit reports */ - for (i = 0; i < pScatterReq->ValidScatterEntries; i++) { - pPacket = (struct htc_packet *)pScatterReq->ScatterList[i].pCallerContexts[0]; - A_ASSERT(pPacket != NULL); - /* reset count, we are only interested in the look ahead in the last packet when we - * break out of this loop */ - numLookAheads = 0; - - if (!pScatterReq->CompletionStatus) { - /* process header for each of the recv packets */ - status = HTCProcessRecvHeader(target,pPacket,lookAheads,&numLookAheads); - } else { - status = A_ERROR; - } - - if (!status) { - LOCK_HTC_RX(target); - HTC_RX_STAT_PROFILE(target,pEndpoint,numLookAheads); - INC_HTC_EP_STAT(pEndpoint, RxPacketsBundled, 1); - UNLOCK_HTC_RX(target); - if (i == (pScatterReq->ValidScatterEntries - 1)) { - /* last packet's more packets flag is set based on the lookahead */ - SET_MORE_RX_PACKET_INDICATION_FLAG(lookAheads,numLookAheads,pEndpoint,pPacket); - } else { - /* packets in a bundle automatically have this flag set */ - FORCE_MORE_RX_PACKET_INDICATION_FLAG(pPacket); - } - - DUMP_RECV_PKT_INFO(pPacket); - /* since we can't hold a lock in this loop, we insert into our local recv queue for - * storage until we can transfer them to the recv completion queue */ - HTC_PACKET_ENQUEUE(&localRecvQueue,pPacket); - - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" Recv packet scatter entry %d failed (out of %d) \n", - i, pScatterReq->ValidScatterEntries)); - /* recycle failed recv */ - HTC_RECYCLE_RX_PKT(target, pPacket, pEndpoint); - /* set flag and continue processing the remaining scatter entries */ - procError = true; - } - - } - - /* free scatter request */ - DEV_FREE_SCATTER_REQ(&target->Device,pScatterReq); - - LOCK_HTC_RX(target); - /* transfer the packets in the local recv queue to the recv completion queue */ - HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&pEndpoint->RecvIndicationQueue, &localRecvQueue); - - UNLOCK_HTC_RX(target); - - if (!procError) { - /* pipeline the next check (asynchronously) for more packets */ - HTCAsyncRecvCheckMorePackets(target, - lookAheads, - numLookAheads, - partialBundle ? false : true); - } - - /* now drain the indication queue */ - DrainRecvIndicationQueue(target,pEndpoint); - - AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-HTCAsyncRecvScatterCompletion \n")); -} - -static int HTCIssueRecvPacketBundle(struct htc_target *target, - struct htc_packet_queue *pRecvPktQueue, - struct htc_packet_queue *pSyncCompletionQueue, - int *pNumPacketsFetched, - bool PartialBundle) -{ - int status = 0; - struct hif_scatter_req *pScatterReq; - int i, totalLength; - int pktsToScatter; - struct htc_packet *pPacket; - bool asyncMode = (pSyncCompletionQueue == NULL) ? true : false; - int scatterSpaceRemaining = DEV_GET_MAX_BUNDLE_RECV_LENGTH(&target->Device); - - pktsToScatter = HTC_PACKET_QUEUE_DEPTH(pRecvPktQueue); - pktsToScatter = min(pktsToScatter, target->MaxMsgPerBundle); - - if ((HTC_PACKET_QUEUE_DEPTH(pRecvPktQueue) - pktsToScatter) > 0) { - /* we were forced to split this bundle receive operation - * all packets in this partial bundle must have their lookaheads ignored */ - PartialBundle = true; - /* this would only happen if the target ignored our max bundle limit */ - AR_DEBUG_PRINTF(ATH_DEBUG_WARN, - ("HTCIssueRecvPacketBundle : partial bundle detected num:%d , %d \n", - HTC_PACKET_QUEUE_DEPTH(pRecvPktQueue), pktsToScatter)); - } - - totalLength = 0; - - AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HTCIssueRecvPacketBundle (Numpackets: %d , actual : %d) \n", - HTC_PACKET_QUEUE_DEPTH(pRecvPktQueue), pktsToScatter)); - - do { - - pScatterReq = DEV_ALLOC_SCATTER_REQ(&target->Device); - - if (pScatterReq == NULL) { - /* no scatter resources left, just let caller handle it the legacy way */ - break; - } - - pScatterReq->CallerFlags = 0; - - if (PartialBundle) { - /* mark that this is a partial bundle, this has special ramifications to the - * scatter completion routine */ - pScatterReq->CallerFlags |= HTC_SCATTER_REQ_FLAGS_PARTIAL_BUNDLE; - } - - /* convert HTC packets to scatter list */ - for (i = 0; i < pktsToScatter; i++) { - int paddedLength; - - pPacket = HTC_PACKET_DEQUEUE(pRecvPktQueue); - A_ASSERT(pPacket != NULL); - - paddedLength = DEV_CALC_RECV_PADDED_LEN(&target->Device, pPacket->ActualLength); - - if ((scatterSpaceRemaining - paddedLength) < 0) { - /* exceeds what we can transfer, put the packet back */ - HTC_PACKET_ENQUEUE_TO_HEAD(pRecvPktQueue,pPacket); - break; - } - - scatterSpaceRemaining -= paddedLength; - - if (PartialBundle || (i < (pktsToScatter - 1))) { - /* packet 0..n-1 cannot be checked for look-aheads since we are fetching a bundle - * the last packet however can have it's lookahead used */ - pPacket->PktInfo.AsRx.HTCRxFlags |= HTC_RX_PKT_IGNORE_LOOKAHEAD; - } - - /* note: 1 HTC packet per scatter entry */ - /* setup packet into */ - pScatterReq->ScatterList[i].pBuffer = pPacket->pBuffer; - pScatterReq->ScatterList[i].Length = paddedLength; - - pPacket->PktInfo.AsRx.HTCRxFlags |= HTC_RX_PKT_PART_OF_BUNDLE; - - if (asyncMode) { - /* save HTC packet for async completion routine */ - pScatterReq->ScatterList[i].pCallerContexts[0] = pPacket; - } else { - /* queue to caller's sync completion queue, caller will unload this when we return */ - HTC_PACKET_ENQUEUE(pSyncCompletionQueue,pPacket); - } - - A_ASSERT(pScatterReq->ScatterList[i].Length); - totalLength += pScatterReq->ScatterList[i].Length; - } - - pScatterReq->TotalLength = totalLength; - pScatterReq->ValidScatterEntries = i; - - if (asyncMode) { - pScatterReq->CompletionRoutine = HTCAsyncRecvScatterCompletion; - pScatterReq->Context = target; - } - - status = DevSubmitScatterRequest(&target->Device, pScatterReq, DEV_SCATTER_READ, asyncMode); - - if (!status) { - *pNumPacketsFetched = i; - } - - if (!asyncMode) { - /* free scatter request */ - DEV_FREE_SCATTER_REQ(&target->Device, pScatterReq); - } - - } while (false); - - AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-HTCIssueRecvPacketBundle (status:%d) (fetched:%d) \n", - status,*pNumPacketsFetched)); - - return status; -} - -static INLINE void CheckRecvWaterMark(struct htc_endpoint *pEndpoint) -{ - /* see if endpoint is using a refill watermark - * ** no need to use a lock here, since we are only inspecting... - * caller may must not hold locks when calling this function */ - if (pEndpoint->EpCallBacks.RecvRefillWaterMark > 0) { - if (HTC_PACKET_QUEUE_DEPTH(&pEndpoint->RxBuffers) < pEndpoint->EpCallBacks.RecvRefillWaterMark) { - /* call the re-fill handler before we continue */ - pEndpoint->EpCallBacks.EpRecvRefill(pEndpoint->EpCallBacks.pContext, - pEndpoint->Id); - } - } -} - -/* callback when device layer or lookahead report parsing detects a pending message */ -int HTCRecvMessagePendingHandler(void *Context, u32 MsgLookAheads[], int NumLookAheads, bool *pAsyncProc, int *pNumPktsFetched) -{ - struct htc_target *target = (struct htc_target *)Context; - int status = 0; - struct htc_packet *pPacket; - struct htc_endpoint *pEndpoint; - bool asyncProc = false; - u32 lookAheads[HTC_HOST_MAX_MSG_PER_BUNDLE]; - int pktsFetched; - struct htc_packet_queue recvPktQueue, syncCompletedPktsQueue; - bool partialBundle; - HTC_ENDPOINT_ID id; - int totalFetched = 0; - - AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("+HTCRecvMessagePendingHandler NumLookAheads: %d \n",NumLookAheads)); - - if (pNumPktsFetched != NULL) { - *pNumPktsFetched = 0; - } - - if (IS_DEV_IRQ_PROCESSING_ASYNC_ALLOWED(&target->Device)) { - /* We use async mode to get the packets if the device layer supports it. - * The device layer interfaces with HIF in which HIF may have restrictions on - * how interrupts are processed */ - asyncProc = true; - } - - if (pAsyncProc != NULL) { - /* indicate to caller how we decided to process this */ - *pAsyncProc = asyncProc; - } - - if (NumLookAheads > HTC_HOST_MAX_MSG_PER_BUNDLE) { - A_ASSERT(false); - return A_EPROTO; - } - - /* on first entry copy the lookaheads into our temp array for processing */ - memcpy(lookAheads, MsgLookAheads, (sizeof(u32)) * NumLookAheads); - - while (true) { - - /* reset packets queues */ - INIT_HTC_PACKET_QUEUE(&recvPktQueue); - INIT_HTC_PACKET_QUEUE(&syncCompletedPktsQueue); - - if (NumLookAheads > HTC_HOST_MAX_MSG_PER_BUNDLE) { - status = A_EPROTO; - A_ASSERT(false); - break; - } - - /* first lookahead sets the expected endpoint IDs for all packets in a bundle */ - id = ((struct htc_frame_hdr *)&lookAheads[0])->EndpointID; - pEndpoint = &target->EndPoint[id]; - - if (id >= ENDPOINT_MAX) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MsgPend, Invalid Endpoint in look-ahead: %d \n",id)); - status = A_EPROTO; - break; - } - - /* try to allocate as many HTC RX packets indicated by the lookaheads - * these packets are stored in the recvPkt queue */ - status = AllocAndPrepareRxPackets(target, - lookAheads, - NumLookAheads, - pEndpoint, - &recvPktQueue); - if (status) { - break; - } - - if (HTC_PACKET_QUEUE_DEPTH(&recvPktQueue) >= 2) { - /* a recv bundle was detected, force IRQ status re-check again */ - REF_IRQ_STATUS_RECHECK(&target->Device); - } - - totalFetched += HTC_PACKET_QUEUE_DEPTH(&recvPktQueue); - - /* we've got packet buffers for all we can currently fetch, - * this count is not valid anymore */ - NumLookAheads = 0; - partialBundle = false; - - /* now go fetch the list of HTC packets */ - while (!HTC_QUEUE_EMPTY(&recvPktQueue)) { - - pktsFetched = 0; - - if (target->RecvBundlingEnabled && (HTC_PACKET_QUEUE_DEPTH(&recvPktQueue) > 1)) { - /* there are enough packets to attempt a bundle transfer and recv bundling is allowed */ - status = HTCIssueRecvPacketBundle(target, - &recvPktQueue, - asyncProc ? NULL : &syncCompletedPktsQueue, - &pktsFetched, - partialBundle); - if (status) { - break; - } - - if (HTC_PACKET_QUEUE_DEPTH(&recvPktQueue) != 0) { - /* we couldn't fetch all packets at one time, this creates a broken - * bundle */ - partialBundle = true; - } - } - - /* see if the previous operation fetched any packets using bundling */ - if (0 == pktsFetched) { - /* dequeue one packet */ - pPacket = HTC_PACKET_DEQUEUE(&recvPktQueue); - A_ASSERT(pPacket != NULL); - - if (asyncProc) { - /* we use async mode to get the packet if the device layer supports it - * set our callback and context */ - pPacket->Completion = HTCRecvCompleteHandler; - pPacket->pContext = target; - } else { - /* fully synchronous */ - pPacket->Completion = NULL; - } - - if (HTC_PACKET_QUEUE_DEPTH(&recvPktQueue) > 0) { - /* lookaheads in all packets except the last one in the bundle must be ignored */ - pPacket->PktInfo.AsRx.HTCRxFlags |= HTC_RX_PKT_IGNORE_LOOKAHEAD; - } - - /* go fetch the packet */ - status = HTCIssueRecv(target, pPacket); - if (status) { - break; - } - - if (!asyncProc) { - /* sent synchronously, queue this packet for synchronous completion */ - HTC_PACKET_ENQUEUE(&syncCompletedPktsQueue,pPacket); - } - - } - - } - - if (!status) { - CheckRecvWaterMark(pEndpoint); - } - - if (asyncProc) { - /* we did this asynchronously so we can get out of the loop, the asynch processing - * creates a chain of requests to continue processing pending messages in the - * context of callbacks */ - break; - } - - /* synchronous handling */ - if (target->Device.DSRCanYield) { - /* for the SYNC case, increment count that tracks when the DSR should yield */ - target->Device.CurrentDSRRecvCount++; - } - - /* in the sync case, all packet buffers are now filled, - * we can process each packet, check lookaheads and then repeat */ - - /* unload sync completion queue */ - while (!HTC_QUEUE_EMPTY(&syncCompletedPktsQueue)) { - struct htc_packet_queue container; - - pPacket = HTC_PACKET_DEQUEUE(&syncCompletedPktsQueue); - A_ASSERT(pPacket != NULL); - - pEndpoint = &target->EndPoint[pPacket->Endpoint]; - /* reset count on each iteration, we are only interested in the last packet's lookahead - * information when we break out of this loop */ - NumLookAheads = 0; - /* process header for each of the recv packets - * note: the lookahead of the last packet is useful for us to continue in this loop */ - status = HTCProcessRecvHeader(target,pPacket,lookAheads,&NumLookAheads); - if (status) { - break; - } - - if (HTC_QUEUE_EMPTY(&syncCompletedPktsQueue)) { - /* last packet's more packets flag is set based on the lookahead */ - SET_MORE_RX_PACKET_INDICATION_FLAG(lookAheads,NumLookAheads,pEndpoint,pPacket); - } else { - /* packets in a bundle automatically have this flag set */ - FORCE_MORE_RX_PACKET_INDICATION_FLAG(pPacket); - } - /* good packet, indicate it */ - HTC_RX_STAT_PROFILE(target,pEndpoint,NumLookAheads); - - if (pPacket->PktInfo.AsRx.HTCRxFlags & HTC_RX_PKT_PART_OF_BUNDLE) { - INC_HTC_EP_STAT(pEndpoint, RxPacketsBundled, 1); - } - - INIT_HTC_PACKET_QUEUE_AND_ADD(&container,pPacket); - DO_RCV_COMPLETION(pEndpoint,&container); - } - - if (status) { - break; - } - - if (NumLookAheads == 0) { - /* no more look aheads */ - break; - } - - /* when we process recv synchronously we need to check if we should yield and stop - * fetching more packets indicated by the embedded lookaheads */ - if (target->Device.DSRCanYield) { - if (DEV_CHECK_RECV_YIELD(&target->Device)) { - /* break out, don't fetch any more packets */ - break; - } - } - - - /* check whether other OS contexts have queued any WMI command/data for WLAN. - * This check is needed only if WLAN Tx and Rx happens in same thread context */ - A_CHECK_DRV_TX(); - - /* for SYNCH processing, if we get here, we are running through the loop again due to a detected lookahead. - * Set flag that we should re-check IRQ status registers again before leaving IRQ processing, - * this can net better performance in high throughput situations */ - REF_IRQ_STATUS_RECHECK(&target->Device); - } - - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("Failed to get pending recv messages (%d) \n",status)); - /* cleanup any packets we allocated but didn't use to actually fetch any packets */ - while (!HTC_QUEUE_EMPTY(&recvPktQueue)) { - pPacket = HTC_PACKET_DEQUEUE(&recvPktQueue); - /* clean up packets */ - HTC_RECYCLE_RX_PKT(target, pPacket, &target->EndPoint[pPacket->Endpoint]); - } - /* cleanup any packets in sync completion queue */ - while (!HTC_QUEUE_EMPTY(&syncCompletedPktsQueue)) { - pPacket = HTC_PACKET_DEQUEUE(&syncCompletedPktsQueue); - /* clean up packets */ - HTC_RECYCLE_RX_PKT(target, pPacket, &target->EndPoint[pPacket->Endpoint]); - } - if (HTC_STOPPING(target)) { - AR_DEBUG_PRINTF(ATH_DEBUG_WARN, - (" Host is going to stop. blocking receiver for HTCStop.. \n")); - DevStopRecv(&target->Device, asyncProc ? DEV_STOP_RECV_ASYNC : DEV_STOP_RECV_SYNC); - } - } - /* before leaving, check to see if host ran out of buffers and needs to stop the - * receiver */ - if (target->RecvStateFlags & HTC_RECV_WAIT_BUFFERS) { - AR_DEBUG_PRINTF(ATH_DEBUG_WARN, - (" Host has no RX buffers, blocking receiver to prevent overrun.. \n")); - /* try to stop receive at the device layer */ - DevStopRecv(&target->Device, asyncProc ? DEV_STOP_RECV_ASYNC : DEV_STOP_RECV_SYNC); - } - - if (pNumPktsFetched != NULL) { - *pNumPktsFetched = totalFetched; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("-HTCRecvMessagePendingHandler \n")); - - return status; -} - -int HTCAddReceivePktMultiple(HTC_HANDLE HTCHandle, struct htc_packet_queue *pPktQueue) -{ - struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); - struct htc_endpoint *pEndpoint; - bool unblockRecv = false; - int status = 0; - struct htc_packet *pFirstPacket; - - pFirstPacket = HTC_GET_PKT_AT_HEAD(pPktQueue); - - if (NULL == pFirstPacket) { - A_ASSERT(false); - return A_EINVAL; - } - - AR_DEBUG_ASSERT(pFirstPacket->Endpoint < ENDPOINT_MAX); - - AR_DEBUG_PRINTF(ATH_DEBUG_RECV, - ("+- HTCAddReceivePktMultiple : endPointId: %d, cnt:%d, length: %d\n", - pFirstPacket->Endpoint, - HTC_PACKET_QUEUE_DEPTH(pPktQueue), - pFirstPacket->BufferLength)); - - do { - - pEndpoint = &target->EndPoint[pFirstPacket->Endpoint]; - - LOCK_HTC_RX(target); - - if (HTC_STOPPING(target)) { - struct htc_packet *pPacket; - - UNLOCK_HTC_RX(target); - - /* walk through queue and mark each one canceled */ - HTC_PACKET_QUEUE_ITERATE_ALLOW_REMOVE(pPktQueue,pPacket) { - pPacket->Status = A_ECANCELED; - } HTC_PACKET_QUEUE_ITERATE_END; - - DO_RCV_COMPLETION(pEndpoint,pPktQueue); - break; - } - - /* store receive packets */ - HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&pEndpoint->RxBuffers, pPktQueue); - - /* check if we are blocked waiting for a new buffer */ - if (target->RecvStateFlags & HTC_RECV_WAIT_BUFFERS) { - if (target->EpWaitingForBuffers == pFirstPacket->Endpoint) { - AR_DEBUG_PRINTF(ATH_DEBUG_RECV,(" receiver was blocked on ep:%d, unblocking.. \n", - target->EpWaitingForBuffers)); - target->RecvStateFlags &= ~HTC_RECV_WAIT_BUFFERS; - target->EpWaitingForBuffers = ENDPOINT_MAX; - unblockRecv = true; - } - } - - UNLOCK_HTC_RX(target); - - if (unblockRecv && !HTC_STOPPING(target)) { - /* TODO : implement a buffer threshold count? */ - DevEnableRecv(&target->Device,DEV_ENABLE_RECV_SYNC); - } - - } while (false); - - return status; -} - -/* Makes a buffer available to the HTC module */ -int HTCAddReceivePkt(HTC_HANDLE HTCHandle, struct htc_packet *pPacket) -{ - struct htc_packet_queue queue; - INIT_HTC_PACKET_QUEUE_AND_ADD(&queue,pPacket); - return HTCAddReceivePktMultiple(HTCHandle, &queue); -} - -void HTCUnblockRecv(HTC_HANDLE HTCHandle) -{ - struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); - bool unblockRecv = false; - - LOCK_HTC_RX(target); - - /* check if we are blocked waiting for a new buffer */ - if (target->RecvStateFlags & HTC_RECV_WAIT_BUFFERS) { - AR_DEBUG_PRINTF(ATH_DEBUG_RECV,("HTCUnblockRx : receiver was blocked on ep:%d, unblocking.. \n", - target->EpWaitingForBuffers)); - target->RecvStateFlags &= ~HTC_RECV_WAIT_BUFFERS; - target->EpWaitingForBuffers = ENDPOINT_MAX; - unblockRecv = true; - } - - UNLOCK_HTC_RX(target); - - if (unblockRecv && !HTC_STOPPING(target)) { - /* re-enable */ - DevEnableRecv(&target->Device,DEV_ENABLE_RECV_ASYNC); - } -} - -static void HTCFlushRxQueue(struct htc_target *target, struct htc_endpoint *pEndpoint, struct htc_packet_queue *pQueue) -{ - struct htc_packet *pPacket; - struct htc_packet_queue container; - - LOCK_HTC_RX(target); - - while (1) { - pPacket = HTC_PACKET_DEQUEUE(pQueue); - if (NULL == pPacket) { - break; - } - UNLOCK_HTC_RX(target); - pPacket->Status = A_ECANCELED; - pPacket->ActualLength = 0; - AR_DEBUG_PRINTF(ATH_DEBUG_RECV, (" Flushing RX packet:0x%lX, length:%d, ep:%d \n", - (unsigned long)pPacket, pPacket->BufferLength, pPacket->Endpoint)); - INIT_HTC_PACKET_QUEUE_AND_ADD(&container,pPacket); - /* give the packet back */ - DO_RCV_COMPLETION(pEndpoint,&container); - LOCK_HTC_RX(target); - } - - UNLOCK_HTC_RX(target); -} - -static void HTCFlushEndpointRX(struct htc_target *target, struct htc_endpoint *pEndpoint) -{ - /* flush any recv indications not already made */ - HTCFlushRxQueue(target,pEndpoint,&pEndpoint->RecvIndicationQueue); - /* flush any rx buffers */ - HTCFlushRxQueue(target,pEndpoint,&pEndpoint->RxBuffers); -} - -void HTCFlushRecvBuffers(struct htc_target *target) -{ - struct htc_endpoint *pEndpoint; - int i; - - for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) { - pEndpoint = &target->EndPoint[i]; - if (pEndpoint->ServiceID == 0) { - /* not in use.. */ - continue; - } - HTCFlushEndpointRX(target,pEndpoint); - } -} - - -void HTCEnableRecv(HTC_HANDLE HTCHandle) -{ - struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); - - if (!HTC_STOPPING(target)) { - /* re-enable */ - DevEnableRecv(&target->Device,DEV_ENABLE_RECV_SYNC); - } -} - -void HTCDisableRecv(HTC_HANDLE HTCHandle) -{ - struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); - - if (!HTC_STOPPING(target)) { - /* disable */ - DevStopRecv(&target->Device,DEV_ENABLE_RECV_SYNC); - } -} - -int HTCGetNumRecvBuffers(HTC_HANDLE HTCHandle, - HTC_ENDPOINT_ID Endpoint) -{ - struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); - return HTC_PACKET_QUEUE_DEPTH(&(target->EndPoint[Endpoint].RxBuffers)); -} - -int HTCWaitForPendingRecv(HTC_HANDLE HTCHandle, - u32 TimeoutInMs, - bool *pbIsRecvPending) -{ - int status = 0; - struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); - - status = DevWaitForPendingRecv(&target->Device, - TimeoutInMs, - pbIsRecvPending); - - return status; -} diff --git a/drivers/staging/ath6kl/htc2/htc_send.c b/drivers/staging/ath6kl/htc2/htc_send.c deleted file mode 100644 index 9310d4d..0000000 --- a/drivers/staging/ath6kl/htc2/htc_send.c +++ /dev/null @@ -1,1018 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="htc_send.c" company="Atheros"> -// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Author(s): ="Atheros" -//============================================================================== -#include "htc_internal.h" - -typedef enum _HTC_SEND_QUEUE_RESULT { - HTC_SEND_QUEUE_OK = 0, /* packet was queued */ - HTC_SEND_QUEUE_DROP = 1, /* this packet should be dropped */ -} HTC_SEND_QUEUE_RESULT; - -#define DO_EP_TX_COMPLETION(ep,q) DoSendCompletion(ep,q) - -/* call the distribute credits callback with the distribution */ -#define DO_DISTRIBUTION(t,reason,description,pList) \ -{ \ - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, \ - (" calling distribute function (%s) (dfn:0x%lX, ctxt:0x%lX, dist:0x%lX) \n", \ - (description), \ - (unsigned long)(t)->DistributeCredits, \ - (unsigned long)(t)->pCredDistContext, \ - (unsigned long)pList)); \ - (t)->DistributeCredits((t)->pCredDistContext, \ - (pList), \ - (reason)); \ -} - -static void DoSendCompletion(struct htc_endpoint *pEndpoint, - struct htc_packet_queue *pQueueToIndicate) -{ - do { - - if (HTC_QUEUE_EMPTY(pQueueToIndicate)) { - /* nothing to indicate */ - break; - } - - if (pEndpoint->EpCallBacks.EpTxCompleteMultiple != NULL) { - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" HTC calling ep %d, send complete multiple callback (%d pkts) \n", - pEndpoint->Id, HTC_PACKET_QUEUE_DEPTH(pQueueToIndicate))); - /* a multiple send complete handler is being used, pass the queue to the handler */ - pEndpoint->EpCallBacks.EpTxCompleteMultiple(pEndpoint->EpCallBacks.pContext, - pQueueToIndicate); - /* all packets are now owned by the callback, reset queue to be safe */ - INIT_HTC_PACKET_QUEUE(pQueueToIndicate); - } else { - struct htc_packet *pPacket; - /* using legacy EpTxComplete */ - do { - pPacket = HTC_PACKET_DEQUEUE(pQueueToIndicate); - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" HTC calling ep %d send complete callback on packet 0x%lX \n", \ - pEndpoint->Id, (unsigned long)(pPacket))); - pEndpoint->EpCallBacks.EpTxComplete(pEndpoint->EpCallBacks.pContext, pPacket); - } while (!HTC_QUEUE_EMPTY(pQueueToIndicate)); - } - - } while (false); - -} - -/* do final completion on sent packet */ -static INLINE void CompleteSentPacket(struct htc_target *target, struct htc_endpoint *pEndpoint, struct htc_packet *pPacket) -{ - pPacket->Completion = NULL; - - if (pPacket->Status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("CompleteSentPacket: request failed (status:%d, ep:%d, length:%d creds:%d) \n", - pPacket->Status, pPacket->Endpoint, pPacket->ActualLength, pPacket->PktInfo.AsTx.CreditsUsed)); - /* on failure to submit, reclaim credits for this packet */ - LOCK_HTC_TX(target); - pEndpoint->CreditDist.TxCreditsToDist += pPacket->PktInfo.AsTx.CreditsUsed; - pEndpoint->CreditDist.TxQueueDepth = HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue); - DO_DISTRIBUTION(target, - HTC_CREDIT_DIST_SEND_COMPLETE, - "Send Complete", - target->EpCreditDistributionListHead->pNext); - UNLOCK_HTC_TX(target); - } - /* first, fixup the head room we allocated */ - pPacket->pBuffer += HTC_HDR_LENGTH; -} - -/* our internal send packet completion handler when packets are submited to the AR6K device - * layer */ -static void HTCSendPktCompletionHandler(void *Context, struct htc_packet *pPacket) -{ - struct htc_target *target = (struct htc_target *)Context; - struct htc_endpoint *pEndpoint = &target->EndPoint[pPacket->Endpoint]; - struct htc_packet_queue container; - - CompleteSentPacket(target,pEndpoint,pPacket); - INIT_HTC_PACKET_QUEUE_AND_ADD(&container,pPacket); - /* do completion */ - DO_EP_TX_COMPLETION(pEndpoint,&container); -} - -int HTCIssueSend(struct htc_target *target, struct htc_packet *pPacket) -{ - int status; - bool sync = false; - - if (pPacket->Completion == NULL) { - /* mark that this request was synchronously issued */ - sync = true; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, - ("+-HTCIssueSend: transmit length : %d (%s) \n", - pPacket->ActualLength + (u32)HTC_HDR_LENGTH, - sync ? "SYNC" : "ASYNC" )); - - /* send message to device */ - status = DevSendPacket(&target->Device, - pPacket, - pPacket->ActualLength + HTC_HDR_LENGTH); - - if (sync) { - /* use local sync variable. If this was issued asynchronously, pPacket is no longer - * safe to access. */ - pPacket->pBuffer += HTC_HDR_LENGTH; - } - - /* if this request was asynchronous, the packet completion routine will be invoked by - * the device layer when the HIF layer completes the request */ - - return status; -} - - /* get HTC send packets from the TX queue on an endpoint */ -static INLINE void GetHTCSendPackets(struct htc_target *target, - struct htc_endpoint *pEndpoint, - struct htc_packet_queue *pQueue) -{ - int creditsRequired; - int remainder; - u8 sendFlags; - struct htc_packet *pPacket; - unsigned int transferLength; - - /****** NOTE : the TX lock is held when this function is called *****************/ - AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+GetHTCSendPackets \n")); - - /* loop until we can grab as many packets out of the queue as we can */ - while (true) { - - sendFlags = 0; - /* get packet at head, but don't remove it */ - pPacket = HTC_GET_PKT_AT_HEAD(&pEndpoint->TxQueue); - if (pPacket == NULL) { - break; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" Got head packet:0x%lX , Queue Depth: %d\n", - (unsigned long)pPacket, HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue))); - - transferLength = DEV_CALC_SEND_PADDED_LEN(&target->Device, pPacket->ActualLength + HTC_HDR_LENGTH); - - if (transferLength <= target->TargetCreditSize) { - creditsRequired = 1; - } else { - /* figure out how many credits this message requires */ - creditsRequired = transferLength / target->TargetCreditSize; - remainder = transferLength % target->TargetCreditSize; - - if (remainder) { - creditsRequired++; - } - } - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" Creds Required:%d Got:%d\n", - creditsRequired, pEndpoint->CreditDist.TxCredits)); - - if (pEndpoint->CreditDist.TxCredits < creditsRequired) { - - /* not enough credits */ - if (pPacket->Endpoint == ENDPOINT_0) { - /* leave it in the queue */ - break; - } - /* invoke the registered distribution function only if this is not - * endpoint 0, we let the driver layer provide more credits if it can. - * We pass the credit distribution list starting at the endpoint in question - * */ - - /* set how many credits we need */ - pEndpoint->CreditDist.TxCreditsSeek = - creditsRequired - pEndpoint->CreditDist.TxCredits; - DO_DISTRIBUTION(target, - HTC_CREDIT_DIST_SEEK_CREDITS, - "Seek Credits", - &pEndpoint->CreditDist); - pEndpoint->CreditDist.TxCreditsSeek = 0; - - if (pEndpoint->CreditDist.TxCredits < creditsRequired) { - /* still not enough credits to send, leave packet in the queue */ - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, - (" Not enough credits for ep %d leaving packet in queue..\n", - pPacket->Endpoint)); - break; - } - - } - - pEndpoint->CreditDist.TxCredits -= creditsRequired; - INC_HTC_EP_STAT(pEndpoint, TxCreditsConsummed, creditsRequired); - - /* check if we need credits back from the target */ - if (pEndpoint->CreditDist.TxCredits < pEndpoint->CreditDist.TxCreditsPerMaxMsg) { - /* we are getting low on credits, see if we can ask for more from the distribution function */ - pEndpoint->CreditDist.TxCreditsSeek = - pEndpoint->CreditDist.TxCreditsPerMaxMsg - pEndpoint->CreditDist.TxCredits; - - DO_DISTRIBUTION(target, - HTC_CREDIT_DIST_SEEK_CREDITS, - "Seek Credits", - &pEndpoint->CreditDist); - - pEndpoint->CreditDist.TxCreditsSeek = 0; - /* see if we were successful in getting more */ - if (pEndpoint->CreditDist.TxCredits < pEndpoint->CreditDist.TxCreditsPerMaxMsg) { - /* tell the target we need credits ASAP! */ - sendFlags |= HTC_FLAGS_NEED_CREDIT_UPDATE; - INC_HTC_EP_STAT(pEndpoint, TxCreditLowIndications, 1); - AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" Host Needs Credits \n")); - } - } - - /* now we can fully dequeue */ - pPacket = HTC_PACKET_DEQUEUE(&pEndpoint->TxQueue); - /* save the number of credits this packet consumed */ - pPacket->PktInfo.AsTx.CreditsUsed = creditsRequired; - /* all TX packets are handled asynchronously */ - pPacket->Completion = HTCSendPktCompletionHandler; - pPacket->pContext = target; - INC_HTC_EP_STAT(pEndpoint, TxIssued, 1); - /* save send flags */ - pPacket->PktInfo.AsTx.SendFlags = sendFlags; - pPacket->PktInfo.AsTx.SeqNo = pEndpoint->SeqNo; - pEndpoint->SeqNo++; - /* queue this packet into the caller's queue */ - HTC_PACKET_ENQUEUE(pQueue,pPacket); - } - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-GetHTCSendPackets \n")); - -} - -static void HTCAsyncSendScatterCompletion(struct hif_scatter_req *pScatterReq) -{ - int i; - struct htc_packet *pPacket; - struct htc_endpoint *pEndpoint = (struct htc_endpoint *)pScatterReq->Context; - struct htc_target *target = (struct htc_target *)pEndpoint->target; - int status = 0; - struct htc_packet_queue sendCompletes; - - INIT_HTC_PACKET_QUEUE(&sendCompletes); - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HTCAsyncSendScatterCompletion TotLen: %d Entries: %d\n", - pScatterReq->TotalLength, pScatterReq->ValidScatterEntries)); - - DEV_FINISH_SCATTER_OPERATION(pScatterReq); - - if (pScatterReq->CompletionStatus) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("** Send Scatter Request Failed: %d \n",pScatterReq->CompletionStatus)); - status = A_ERROR; - } - - /* walk through the scatter list and process */ - for (i = 0; i < pScatterReq->ValidScatterEntries; i++) { - pPacket = (struct htc_packet *)(pScatterReq->ScatterList[i].pCallerContexts[0]); - A_ASSERT(pPacket != NULL); - pPacket->Status = status; - CompleteSentPacket(target,pEndpoint,pPacket); - /* add it to the completion queue */ - HTC_PACKET_ENQUEUE(&sendCompletes, pPacket); - } - - /* free scatter request */ - DEV_FREE_SCATTER_REQ(&target->Device,pScatterReq); - /* complete all packets */ - DO_EP_TX_COMPLETION(pEndpoint,&sendCompletes); - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HTCAsyncSendScatterCompletion \n")); -} - - /* drain a queue and send as bundles - * this function may return without fully draining the queue under the following conditions : - * - scatter resources are exhausted - * - a message that will consume a partial credit will stop the bundling process early - * - we drop below the minimum number of messages for a bundle - * */ -static void HTCIssueSendBundle(struct htc_endpoint *pEndpoint, - struct htc_packet_queue *pQueue, - int *pBundlesSent, - int *pTotalBundlesPkts) -{ - int pktsToScatter; - unsigned int scatterSpaceRemaining; - struct hif_scatter_req *pScatterReq = NULL; - int i, packetsInScatterReq; - unsigned int transferLength; - struct htc_packet *pPacket; - bool done = false; - int bundlesSent = 0; - int totalPktsInBundle = 0; - struct htc_target *target = pEndpoint->target; - int creditRemainder = 0; - int creditPad; - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HTCIssueSendBundle \n")); - - while (!done) { - - pktsToScatter = HTC_PACKET_QUEUE_DEPTH(pQueue); - pktsToScatter = min(pktsToScatter, target->MaxMsgPerBundle); - - if (pktsToScatter < HTC_MIN_HTC_MSGS_TO_BUNDLE) { - /* not enough to bundle */ - break; - } - - pScatterReq = DEV_ALLOC_SCATTER_REQ(&target->Device); - - if (pScatterReq == NULL) { - /* no scatter resources */ - AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" No more scatter resources \n")); - break; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" pkts to scatter: %d \n", pktsToScatter)); - - pScatterReq->TotalLength = 0; - pScatterReq->ValidScatterEntries = 0; - - packetsInScatterReq = 0; - scatterSpaceRemaining = DEV_GET_MAX_BUNDLE_SEND_LENGTH(&target->Device); - - for (i = 0; i < pktsToScatter; i++) { - - pScatterReq->ScatterList[i].pCallerContexts[0] = NULL; - - pPacket = HTC_GET_PKT_AT_HEAD(pQueue); - if (pPacket == NULL) { - A_ASSERT(false); - break; - } - - creditPad = 0; - transferLength = DEV_CALC_SEND_PADDED_LEN(&target->Device, - pPacket->ActualLength + HTC_HDR_LENGTH); - /* see if the padded transfer length falls on a credit boundary */ - creditRemainder = transferLength % target->TargetCreditSize; - - if (creditRemainder != 0) { - /* the transfer consumes a "partial" credit, this packet cannot be bundled unless - * we add additional "dummy" padding (max 255 bytes) to consume the entire credit - *** NOTE: only allow the send padding if the endpoint is allowed to */ - if (pEndpoint->LocalConnectionFlags & HTC_LOCAL_CONN_FLAGS_ENABLE_SEND_BUNDLE_PADDING) { - if (transferLength < target->TargetCreditSize) { - /* special case where the transfer is less than a credit */ - creditPad = target->TargetCreditSize - transferLength; - } else { - creditPad = creditRemainder; - } - - /* now check to see if we can indicate padding in the HTC header */ - if ((creditPad > 0) && (creditPad <= 255)) { - /* adjust the transferlength of this packet with the new credit padding */ - transferLength += creditPad; - } else { - /* the amount to pad is too large, bail on this packet, we have to - * send it using the non-bundled method */ - pPacket = NULL; - } - } else { - /* bail on this packet, user does not want padding applied */ - pPacket = NULL; - } - } - - if (NULL == pPacket) { - /* can't bundle */ - done = true; - break; - } - - if (scatterSpaceRemaining < transferLength) { - /* exceeds what we can transfer */ - break; - } - - scatterSpaceRemaining -= transferLength; - /* now remove it from the queue */ - pPacket = HTC_PACKET_DEQUEUE(pQueue); - /* save it in the scatter list */ - pScatterReq->ScatterList[i].pCallerContexts[0] = pPacket; - /* prepare packet and flag message as part of a send bundle */ - HTC_PREPARE_SEND_PKT(pPacket, - pPacket->PktInfo.AsTx.SendFlags | HTC_FLAGS_SEND_BUNDLE, - creditPad, - pPacket->PktInfo.AsTx.SeqNo); - pScatterReq->ScatterList[i].pBuffer = pPacket->pBuffer; - pScatterReq->ScatterList[i].Length = transferLength; - A_ASSERT(transferLength); - pScatterReq->TotalLength += transferLength; - pScatterReq->ValidScatterEntries++; - packetsInScatterReq++; - AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" %d, Adding packet : 0x%lX, len:%d (remaining space:%d) \n", - i, (unsigned long)pPacket,transferLength,scatterSpaceRemaining)); - } - - if (packetsInScatterReq >= HTC_MIN_HTC_MSGS_TO_BUNDLE) { - /* send path is always asynchronous */ - pScatterReq->CompletionRoutine = HTCAsyncSendScatterCompletion; - pScatterReq->Context = pEndpoint; - bundlesSent++; - totalPktsInBundle += packetsInScatterReq; - packetsInScatterReq = 0; - AR_DEBUG_PRINTF(ATH_DEBUG_SEND,(" Send Scatter total bytes: %d , entries: %d\n", - pScatterReq->TotalLength,pScatterReq->ValidScatterEntries)); - DevSubmitScatterRequest(&target->Device, pScatterReq, DEV_SCATTER_WRITE, DEV_SCATTER_ASYNC); - /* we don't own this anymore */ - pScatterReq = NULL; - /* try to send some more */ - continue; - } - - /* not enough packets to use the scatter request, cleanup */ - if (pScatterReq != NULL) { - if (packetsInScatterReq > 0) { - /* work backwards to requeue requests */ - for (i = (packetsInScatterReq - 1); i >= 0; i--) { - pPacket = (struct htc_packet *)(pScatterReq->ScatterList[i].pCallerContexts[0]); - if (pPacket != NULL) { - /* undo any prep */ - HTC_UNPREPARE_SEND_PKT(pPacket); - /* queue back to the head */ - HTC_PACKET_ENQUEUE_TO_HEAD(pQueue,pPacket); - } - } - } - DEV_FREE_SCATTER_REQ(&target->Device,pScatterReq); - } - - /* if we get here, we sent all that we could, get out */ - break; - - } - - *pBundlesSent = bundlesSent; - *pTotalBundlesPkts = totalPktsInBundle; - AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HTCIssueSendBundle (sent:%d) \n",bundlesSent)); - - return; -} - -/* - * if there are no credits, the packet(s) remains in the queue. - * this function returns the result of the attempt to send a queue of HTC packets */ -static HTC_SEND_QUEUE_RESULT HTCTrySend(struct htc_target *target, - struct htc_endpoint *pEndpoint, - struct htc_packet_queue *pCallersSendQueue) -{ - struct htc_packet_queue sendQueue; /* temp queue to hold packets at various stages */ - struct htc_packet *pPacket; - int bundlesSent; - int pktsInBundles; - int overflow; - HTC_SEND_QUEUE_RESULT result = HTC_SEND_QUEUE_OK; - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("+HTCTrySend (Queue:0x%lX Depth:%d)\n", - (unsigned long)pCallersSendQueue, - (pCallersSendQueue == NULL) ? 0 : HTC_PACKET_QUEUE_DEPTH(pCallersSendQueue))); - - /* init the local send queue */ - INIT_HTC_PACKET_QUEUE(&sendQueue); - - do { - - if (NULL == pCallersSendQueue) { - /* caller didn't provide a queue, just wants us to check queues and send */ - break; - } - - if (HTC_QUEUE_EMPTY(pCallersSendQueue)) { - /* empty queue */ - result = HTC_SEND_QUEUE_DROP; - break; - } - - if (HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue) >= pEndpoint->MaxTxQueueDepth) { - /* we've already overflowed */ - overflow = HTC_PACKET_QUEUE_DEPTH(pCallersSendQueue); - } else { - /* figure out how much we will overflow by */ - overflow = HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue); - overflow += HTC_PACKET_QUEUE_DEPTH(pCallersSendQueue); - /* figure out how much we will overflow the TX queue by */ - overflow -= pEndpoint->MaxTxQueueDepth; - } - - /* if overflow is negative or zero, we are okay */ - if (overflow > 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, - (" Endpoint %d, TX queue will overflow :%d , Tx Depth:%d, Max:%d \n", - pEndpoint->Id, overflow, HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue), pEndpoint->MaxTxQueueDepth)); - } - if ((overflow <= 0) || (pEndpoint->EpCallBacks.EpSendFull == NULL)) { - /* all packets will fit or caller did not provide send full indication handler - * -- just move all of them to the local sendQueue object */ - HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&sendQueue, pCallersSendQueue); - } else { - int i; - int goodPkts = HTC_PACKET_QUEUE_DEPTH(pCallersSendQueue) - overflow; - - A_ASSERT(goodPkts >= 0); - /* we have overflowed, and a callback is provided */ - /* dequeue all non-overflow packets into the sendqueue */ - for (i = 0; i < goodPkts; i++) { - /* pop off caller's queue*/ - pPacket = HTC_PACKET_DEQUEUE(pCallersSendQueue); - A_ASSERT(pPacket != NULL); - /* insert into local queue */ - HTC_PACKET_ENQUEUE(&sendQueue,pPacket); - } - - /* the caller's queue has all the packets that won't fit*/ - /* walk through the caller's queue and indicate each one to the send full handler */ - ITERATE_OVER_LIST_ALLOW_REMOVE(&pCallersSendQueue->QueueHead, pPacket, struct htc_packet, ListLink) { - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Indicating overflowed TX packet: 0x%lX \n", - (unsigned long)pPacket)); - if (pEndpoint->EpCallBacks.EpSendFull(pEndpoint->EpCallBacks.pContext, - pPacket) == HTC_SEND_FULL_DROP) { - /* callback wants the packet dropped */ - INC_HTC_EP_STAT(pEndpoint, TxDropped, 1); - /* leave this one in the caller's queue for cleanup */ - } else { - /* callback wants to keep this packet, remove from caller's queue */ - HTC_PACKET_REMOVE(pCallersSendQueue, pPacket); - /* put it in the send queue */ - HTC_PACKET_ENQUEUE(&sendQueue,pPacket); - } - - } ITERATE_END; - - if (HTC_QUEUE_EMPTY(&sendQueue)) { - /* no packets made it in, caller will cleanup */ - result = HTC_SEND_QUEUE_DROP; - break; - } - } - - } while (false); - - if (result != HTC_SEND_QUEUE_OK) { - AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HTCTrySend: \n")); - return result; - } - - LOCK_HTC_TX(target); - - if (!HTC_QUEUE_EMPTY(&sendQueue)) { - /* transfer packets */ - HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(&pEndpoint->TxQueue,&sendQueue); - A_ASSERT(HTC_QUEUE_EMPTY(&sendQueue)); - INIT_HTC_PACKET_QUEUE(&sendQueue); - } - - /* increment tx processing count on entry */ - pEndpoint->TxProcessCount++; - if (pEndpoint->TxProcessCount > 1) { - /* another thread or task is draining the TX queues on this endpoint - * that thread will reset the tx processing count when the queue is drained */ - pEndpoint->TxProcessCount--; - UNLOCK_HTC_TX(target); - AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HTCTrySend (busy) \n")); - return HTC_SEND_QUEUE_OK; - } - - /***** beyond this point only 1 thread may enter ******/ - - /* now drain the endpoint TX queue for transmission as long as we have enough - * credits */ - while (true) { - - if (HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue) == 0) { - break; - } - - /* get all the packets for this endpoint that we can for this pass */ - GetHTCSendPackets(target, pEndpoint, &sendQueue); - - if (HTC_PACKET_QUEUE_DEPTH(&sendQueue) == 0) { - /* didn't get any packets due to a lack of credits */ - break; - } - - UNLOCK_HTC_TX(target); - - /* any packets to send are now in our local send queue */ - - bundlesSent = 0; - pktsInBundles = 0; - - while (true) { - - /* try to send a bundle on each pass */ - if ((target->SendBundlingEnabled) && - (HTC_PACKET_QUEUE_DEPTH(&sendQueue) >= HTC_MIN_HTC_MSGS_TO_BUNDLE)) { - int temp1,temp2; - /* bundling is enabled and there is at least a minimum number of packets in the send queue - * send what we can in this pass */ - HTCIssueSendBundle(pEndpoint, &sendQueue, &temp1, &temp2); - bundlesSent += temp1; - pktsInBundles += temp2; - } - - /* if not bundling or there was a packet that could not be placed in a bundle, pull it out - * and send it the normal way */ - pPacket = HTC_PACKET_DEQUEUE(&sendQueue); - if (NULL == pPacket) { - /* local queue is fully drained */ - break; - } - HTC_PREPARE_SEND_PKT(pPacket, - pPacket->PktInfo.AsTx.SendFlags, - 0, - pPacket->PktInfo.AsTx.SeqNo); - HTCIssueSend(target, pPacket); - - /* go back and see if we can bundle some more */ - } - - LOCK_HTC_TX(target); - - INC_HTC_EP_STAT(pEndpoint, TxBundles, bundlesSent); - INC_HTC_EP_STAT(pEndpoint, TxPacketsBundled, pktsInBundles); - - } - - /* done with this endpoint, we can clear the count */ - pEndpoint->TxProcessCount = 0; - UNLOCK_HTC_TX(target); - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND,("-HTCTrySend: \n")); - - return HTC_SEND_QUEUE_OK; -} - -int HTCSendPktsMultiple(HTC_HANDLE HTCHandle, struct htc_packet_queue *pPktQueue) -{ - struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); - struct htc_endpoint *pEndpoint; - struct htc_packet *pPacket; - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("+HTCSendPktsMultiple: Queue: 0x%lX, Pkts %d \n", - (unsigned long)pPktQueue, HTC_PACKET_QUEUE_DEPTH(pPktQueue))); - - /* get packet at head to figure out which endpoint these packets will go into */ - pPacket = HTC_GET_PKT_AT_HEAD(pPktQueue); - if (NULL == pPacket) { - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("-HTCSendPktsMultiple \n")); - return A_EINVAL; - } - - AR_DEBUG_ASSERT(pPacket->Endpoint < ENDPOINT_MAX); - pEndpoint = &target->EndPoint[pPacket->Endpoint]; - - HTCTrySend(target, pEndpoint, pPktQueue); - - /* do completion on any packets that couldn't get in */ - if (!HTC_QUEUE_EMPTY(pPktQueue)) { - - HTC_PACKET_QUEUE_ITERATE_ALLOW_REMOVE(pPktQueue,pPacket) { - if (HTC_STOPPING(target)) { - pPacket->Status = A_ECANCELED; - } else { - pPacket->Status = A_NO_RESOURCE; - } - } HTC_PACKET_QUEUE_ITERATE_END; - - DO_EP_TX_COMPLETION(pEndpoint,pPktQueue); - } - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("-HTCSendPktsMultiple \n")); - - return 0; -} - -/* HTC API - HTCSendPkt */ -int HTCSendPkt(HTC_HANDLE HTCHandle, struct htc_packet *pPacket) -{ - struct htc_packet_queue queue; - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, - ("+-HTCSendPkt: Enter endPointId: %d, buffer: 0x%lX, length: %d \n", - pPacket->Endpoint, (unsigned long)pPacket->pBuffer, pPacket->ActualLength)); - INIT_HTC_PACKET_QUEUE_AND_ADD(&queue,pPacket); - return HTCSendPktsMultiple(HTCHandle, &queue); -} - -/* check TX queues to drain because of credit distribution update */ -static INLINE void HTCCheckEndpointTxQueues(struct htc_target *target) -{ - struct htc_endpoint *pEndpoint; - struct htc_endpoint_credit_dist *pDistItem; - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("+HTCCheckEndpointTxQueues \n")); - pDistItem = target->EpCreditDistributionListHead; - - /* run through the credit distribution list to see - * if there are packets queued - * NOTE: no locks need to be taken since the distribution list - * is not dynamic (cannot be re-ordered) and we are not modifying any state */ - while (pDistItem != NULL) { - pEndpoint = (struct htc_endpoint *)pDistItem->pHTCReserved; - - if (HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue) > 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Ep %d has %d credits and %d Packets in TX Queue \n", - pDistItem->Endpoint, pEndpoint->CreditDist.TxCredits, HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue))); - /* try to start the stalled queue, this list is ordered by priority. - * Highest priority queue get's processed first, if there are credits available the - * highest priority queue will get a chance to reclaim credits from lower priority - * ones */ - HTCTrySend(target, pEndpoint, NULL); - } - - pDistItem = pDistItem->pNext; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("-HTCCheckEndpointTxQueues \n")); -} - -/* process credit reports and call distribution function */ -void HTCProcessCreditRpt(struct htc_target *target, HTC_CREDIT_REPORT *pRpt, int NumEntries, HTC_ENDPOINT_ID FromEndpoint) -{ - int i; - struct htc_endpoint *pEndpoint; - int totalCredits = 0; - bool doDist = false; - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("+HTCProcessCreditRpt, Credit Report Entries:%d \n", NumEntries)); - - /* lock out TX while we update credits */ - LOCK_HTC_TX(target); - - for (i = 0; i < NumEntries; i++, pRpt++) { - if (pRpt->EndpointID >= ENDPOINT_MAX) { - AR_DEBUG_ASSERT(false); - break; - } - - pEndpoint = &target->EndPoint[pRpt->EndpointID]; - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Endpoint %d got %d credits \n", - pRpt->EndpointID, pRpt->Credits)); - - INC_HTC_EP_STAT(pEndpoint, TxCreditRpts, 1); - INC_HTC_EP_STAT(pEndpoint, TxCreditsReturned, pRpt->Credits); - - if (FromEndpoint == pRpt->EndpointID) { - /* this credit report arrived on the same endpoint indicating it arrived in an RX - * packet */ - INC_HTC_EP_STAT(pEndpoint, TxCreditsFromRx, pRpt->Credits); - INC_HTC_EP_STAT(pEndpoint, TxCreditRptsFromRx, 1); - } else if (FromEndpoint == ENDPOINT_0) { - /* this credit arrived on endpoint 0 as a NULL message */ - INC_HTC_EP_STAT(pEndpoint, TxCreditsFromEp0, pRpt->Credits); - INC_HTC_EP_STAT(pEndpoint, TxCreditRptsFromEp0, 1); - } else { - /* arrived on another endpoint */ - INC_HTC_EP_STAT(pEndpoint, TxCreditsFromOther, pRpt->Credits); - INC_HTC_EP_STAT(pEndpoint, TxCreditRptsFromOther, 1); - } - - if (ENDPOINT_0 == pRpt->EndpointID) { - /* always give endpoint 0 credits back */ - pEndpoint->CreditDist.TxCredits += pRpt->Credits; - } else { - /* for all other endpoints, update credits to distribute, the distribution function - * will handle giving out credits back to the endpoints */ - pEndpoint->CreditDist.TxCreditsToDist += pRpt->Credits; - /* flag that we have to do the distribution */ - doDist = true; - } - - /* refresh tx depth for distribution function that will recover these credits - * NOTE: this is only valid when there are credits to recover! */ - pEndpoint->CreditDist.TxQueueDepth = HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue); - - totalCredits += pRpt->Credits; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, (" Report indicated %d credits to distribute \n", totalCredits)); - - if (doDist) { - /* this was a credit return based on a completed send operations - * note, this is done with the lock held */ - DO_DISTRIBUTION(target, - HTC_CREDIT_DIST_SEND_COMPLETE, - "Send Complete", - target->EpCreditDistributionListHead->pNext); - } - - UNLOCK_HTC_TX(target); - - if (totalCredits) { - HTCCheckEndpointTxQueues(target); - } - - AR_DEBUG_PRINTF(ATH_DEBUG_SEND, ("-HTCProcessCreditRpt \n")); -} - -/* flush endpoint TX queue */ -static void HTCFlushEndpointTX(struct htc_target *target, struct htc_endpoint *pEndpoint, HTC_TX_TAG Tag) -{ - struct htc_packet *pPacket; - struct htc_packet_queue discardQueue; - struct htc_packet_queue container; - - /* initialize the discard queue */ - INIT_HTC_PACKET_QUEUE(&discardQueue); - - LOCK_HTC_TX(target); - - /* interate from the front of the TX queue and flush out packets */ - ITERATE_OVER_LIST_ALLOW_REMOVE(&pEndpoint->TxQueue.QueueHead, pPacket, struct htc_packet, ListLink) { - - /* check for removal */ - if ((HTC_TX_PACKET_TAG_ALL == Tag) || (Tag == pPacket->PktInfo.AsTx.Tag)) { - /* remove from queue */ - HTC_PACKET_REMOVE(&pEndpoint->TxQueue, pPacket); - /* add it to the discard pile */ - HTC_PACKET_ENQUEUE(&discardQueue, pPacket); - } - - } ITERATE_END; - - UNLOCK_HTC_TX(target); - - /* empty the discard queue */ - while (1) { - pPacket = HTC_PACKET_DEQUEUE(&discardQueue); - if (NULL == pPacket) { - break; - } - pPacket->Status = A_ECANCELED; - AR_DEBUG_PRINTF(ATH_DEBUG_TRC, (" Flushing TX packet:0x%lX, length:%d, ep:%d tag:0x%X \n", - (unsigned long)pPacket, pPacket->ActualLength, pPacket->Endpoint, pPacket->PktInfo.AsTx.Tag)); - INIT_HTC_PACKET_QUEUE_AND_ADD(&container,pPacket); - DO_EP_TX_COMPLETION(pEndpoint,&container); - } - -} - -void DumpCreditDist(struct htc_endpoint_credit_dist *pEPDist) -{ - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("--- EP : %d ServiceID: 0x%X --------------\n", - pEPDist->Endpoint, pEPDist->ServiceID)); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" this:0x%lX next:0x%lX prev:0x%lX\n", - (unsigned long)pEPDist, (unsigned long)pEPDist->pNext, (unsigned long)pEPDist->pPrev)); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" DistFlags : 0x%X \n", pEPDist->DistFlags)); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsNorm : %d \n", pEPDist->TxCreditsNorm)); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsMin : %d \n", pEPDist->TxCreditsMin)); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCredits : %d \n", pEPDist->TxCredits)); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsAssigned : %d \n", pEPDist->TxCreditsAssigned)); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsSeek : %d \n", pEPDist->TxCreditsSeek)); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditSize : %d \n", pEPDist->TxCreditSize)); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsPerMaxMsg : %d \n", pEPDist->TxCreditsPerMaxMsg)); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxCreditsToDist : %d \n", pEPDist->TxCreditsToDist)); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, (" TxQueueDepth : %d \n", - HTC_PACKET_QUEUE_DEPTH(&((struct htc_endpoint *)pEPDist->pHTCReserved)->TxQueue))); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, ("----------------------------------------------------\n")); -} - -void DumpCreditDistStates(struct htc_target *target) -{ - struct htc_endpoint_credit_dist *pEPList = target->EpCreditDistributionListHead; - - while (pEPList != NULL) { - DumpCreditDist(pEPList); - pEPList = pEPList->pNext; - } - - if (target->DistributeCredits != NULL) { - DO_DISTRIBUTION(target, - HTC_DUMP_CREDIT_STATE, - "Dump State", - NULL); - } -} - -/* flush all send packets from all endpoint queues */ -void HTCFlushSendPkts(struct htc_target *target) -{ - struct htc_endpoint *pEndpoint; - int i; - - if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_TRC)) { - DumpCreditDistStates(target); - } - - for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) { - pEndpoint = &target->EndPoint[i]; - if (pEndpoint->ServiceID == 0) { - /* not in use.. */ - continue; - } - HTCFlushEndpointTX(target,pEndpoint,HTC_TX_PACKET_TAG_ALL); - } - - -} - -/* HTC API to flush an endpoint's TX queue*/ -void HTCFlushEndpoint(HTC_HANDLE HTCHandle, HTC_ENDPOINT_ID Endpoint, HTC_TX_TAG Tag) -{ - struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); - struct htc_endpoint *pEndpoint = &target->EndPoint[Endpoint]; - - if (pEndpoint->ServiceID == 0) { - AR_DEBUG_ASSERT(false); - /* not in use.. */ - return; - } - - HTCFlushEndpointTX(target, pEndpoint, Tag); -} - -/* HTC API to indicate activity to the credit distribution function */ -void HTCIndicateActivityChange(HTC_HANDLE HTCHandle, - HTC_ENDPOINT_ID Endpoint, - bool Active) -{ - struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); - struct htc_endpoint *pEndpoint = &target->EndPoint[Endpoint]; - bool doDist = false; - - if (pEndpoint->ServiceID == 0) { - AR_DEBUG_ASSERT(false); - /* not in use.. */ - return; - } - - LOCK_HTC_TX(target); - - if (Active) { - if (!(pEndpoint->CreditDist.DistFlags & HTC_EP_ACTIVE)) { - /* mark active now */ - pEndpoint->CreditDist.DistFlags |= HTC_EP_ACTIVE; - doDist = true; - } - } else { - if (pEndpoint->CreditDist.DistFlags & HTC_EP_ACTIVE) { - /* mark inactive now */ - pEndpoint->CreditDist.DistFlags &= ~HTC_EP_ACTIVE; - doDist = true; - } - } - - if (doDist) { - /* indicate current Tx Queue depth to the credit distribution function */ - pEndpoint->CreditDist.TxQueueDepth = HTC_PACKET_QUEUE_DEPTH(&pEndpoint->TxQueue); - /* do distribution again based on activity change - * note, this is done with the lock held */ - DO_DISTRIBUTION(target, - HTC_CREDIT_DIST_ACTIVITY_CHANGE, - "Activity Change", - target->EpCreditDistributionListHead->pNext); - } - - UNLOCK_HTC_TX(target); - - if (doDist && !Active) { - /* if a stream went inactive and this resulted in a credit distribution change, - * some credits may now be available for HTC packets that are stuck in - * HTC queues */ - HTCCheckEndpointTxQueues(target); - } -} - -bool HTCIsEndpointActive(HTC_HANDLE HTCHandle, - HTC_ENDPOINT_ID Endpoint) -{ - struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); - struct htc_endpoint *pEndpoint = &target->EndPoint[Endpoint]; - - if (pEndpoint->ServiceID == 0) { - return false; - } - - if (pEndpoint->CreditDist.DistFlags & HTC_EP_ACTIVE) { - return true; - } - - return false; -} diff --git a/drivers/staging/ath6kl/htc2/htc_services.c b/drivers/staging/ath6kl/htc2/htc_services.c deleted file mode 100644 index c48070c..0000000 --- a/drivers/staging/ath6kl/htc2/htc_services.c +++ /dev/null @@ -1,450 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="htc_services.c" company="Atheros"> -// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Author(s): ="Atheros" -//============================================================================== -#include "htc_internal.h" - -void HTCControlTxComplete(void *Context, struct htc_packet *pPacket) -{ - /* not implemented - * we do not send control TX frames during normal runtime, only during setup */ - AR_DEBUG_ASSERT(false); -} - - /* callback when a control message arrives on this endpoint */ -void HTCControlRecv(void *Context, struct htc_packet *pPacket) -{ - AR_DEBUG_ASSERT(pPacket->Endpoint == ENDPOINT_0); - - if (pPacket->Status == A_ECANCELED) { - /* this is a flush operation, return the control packet back to the pool */ - HTC_FREE_CONTROL_RX((struct htc_target*)Context,pPacket); - return; - } - - /* the only control messages we are expecting are NULL messages (credit resports) */ - if (pPacket->ActualLength > 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("HTCControlRecv, got message with length:%d \n", - pPacket->ActualLength + (u32)HTC_HDR_LENGTH)); - -#ifdef ATH_DEBUG_MODULE - /* dump header and message */ - DebugDumpBytes(pPacket->pBuffer - HTC_HDR_LENGTH, - pPacket->ActualLength + HTC_HDR_LENGTH, - "Unexpected ENDPOINT 0 Message"); -#endif - } - - HTC_RECYCLE_RX_PKT((struct htc_target*)Context,pPacket,&((struct htc_target*)Context)->EndPoint[0]); -} - -int HTCSendSetupComplete(struct htc_target *target) -{ - struct htc_packet *pSendPacket = NULL; - int status; - - do { - /* allocate a packet to send to the target */ - pSendPacket = HTC_ALLOC_CONTROL_TX(target); - - if (NULL == pSendPacket) { - status = A_NO_MEMORY; - break; - } - - if (target->HTCTargetVersion >= HTC_VERSION_2P1) { - HTC_SETUP_COMPLETE_EX_MSG *pSetupCompleteEx; - u32 setupFlags = 0; - - pSetupCompleteEx = (HTC_SETUP_COMPLETE_EX_MSG *)pSendPacket->pBuffer; - A_MEMZERO(pSetupCompleteEx, sizeof(HTC_SETUP_COMPLETE_EX_MSG)); - pSetupCompleteEx->MessageID = HTC_MSG_SETUP_COMPLETE_EX_ID; - if (target->MaxMsgPerBundle > 0) { - /* host can do HTC bundling, indicate this to the target */ - setupFlags |= HTC_SETUP_COMPLETE_FLAGS_ENABLE_BUNDLE_RECV; - pSetupCompleteEx->MaxMsgsPerBundledRecv = target->MaxMsgPerBundle; - } - memcpy(&pSetupCompleteEx->SetupFlags, &setupFlags, sizeof(pSetupCompleteEx->SetupFlags)); - SET_HTC_PACKET_INFO_TX(pSendPacket, - NULL, - (u8 *)pSetupCompleteEx, - sizeof(HTC_SETUP_COMPLETE_EX_MSG), - ENDPOINT_0, - HTC_SERVICE_TX_PACKET_TAG); - - } else { - HTC_SETUP_COMPLETE_MSG *pSetupComplete; - /* assemble setup complete message */ - pSetupComplete = (HTC_SETUP_COMPLETE_MSG *)pSendPacket->pBuffer; - A_MEMZERO(pSetupComplete, sizeof(HTC_SETUP_COMPLETE_MSG)); - pSetupComplete->MessageID = HTC_MSG_SETUP_COMPLETE_ID; - SET_HTC_PACKET_INFO_TX(pSendPacket, - NULL, - (u8 *)pSetupComplete, - sizeof(HTC_SETUP_COMPLETE_MSG), - ENDPOINT_0, - HTC_SERVICE_TX_PACKET_TAG); - } - - /* we want synchronous operation */ - pSendPacket->Completion = NULL; - HTC_PREPARE_SEND_PKT(pSendPacket,0,0,0); - /* send the message */ - status = HTCIssueSend(target,pSendPacket); - - } while (false); - - if (pSendPacket != NULL) { - HTC_FREE_CONTROL_TX(target,pSendPacket); - } - - return status; -} - - -int HTCConnectService(HTC_HANDLE HTCHandle, - struct htc_service_connect_req *pConnectReq, - struct htc_service_connect_resp *pConnectResp) -{ - struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); - int status = 0; - struct htc_packet *pRecvPacket = NULL; - struct htc_packet *pSendPacket = NULL; - HTC_CONNECT_SERVICE_RESPONSE_MSG *pResponseMsg; - HTC_CONNECT_SERVICE_MSG *pConnectMsg; - HTC_ENDPOINT_ID assignedEndpoint = ENDPOINT_MAX; - struct htc_endpoint *pEndpoint; - unsigned int maxMsgSize = 0; - - AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("+HTCConnectService, target:0x%lX SvcID:0x%X \n", - (unsigned long)target, pConnectReq->ServiceID)); - - do { - - AR_DEBUG_ASSERT(pConnectReq->ServiceID != 0); - - if (HTC_CTRL_RSVD_SVC == pConnectReq->ServiceID) { - /* special case for pseudo control service */ - assignedEndpoint = ENDPOINT_0; - maxMsgSize = HTC_MAX_CONTROL_MESSAGE_LENGTH; - } else { - /* allocate a packet to send to the target */ - pSendPacket = HTC_ALLOC_CONTROL_TX(target); - - if (NULL == pSendPacket) { - AR_DEBUG_ASSERT(false); - status = A_NO_MEMORY; - break; - } - /* assemble connect service message */ - pConnectMsg = (HTC_CONNECT_SERVICE_MSG *)pSendPacket->pBuffer; - AR_DEBUG_ASSERT(pConnectMsg != NULL); - A_MEMZERO(pConnectMsg,sizeof(HTC_CONNECT_SERVICE_MSG)); - pConnectMsg->MessageID = HTC_MSG_CONNECT_SERVICE_ID; - pConnectMsg->ServiceID = pConnectReq->ServiceID; - pConnectMsg->ConnectionFlags = pConnectReq->ConnectionFlags; - /* check caller if it wants to transfer meta data */ - if ((pConnectReq->pMetaData != NULL) && - (pConnectReq->MetaDataLength <= HTC_SERVICE_META_DATA_MAX_LENGTH)) { - /* copy meta data into message buffer (after header ) */ - memcpy((u8 *)pConnectMsg + sizeof(HTC_CONNECT_SERVICE_MSG), - pConnectReq->pMetaData, - pConnectReq->MetaDataLength); - pConnectMsg->ServiceMetaLength = pConnectReq->MetaDataLength; - } - - SET_HTC_PACKET_INFO_TX(pSendPacket, - NULL, - (u8 *)pConnectMsg, - sizeof(HTC_CONNECT_SERVICE_MSG) + pConnectMsg->ServiceMetaLength, - ENDPOINT_0, - HTC_SERVICE_TX_PACKET_TAG); - - /* we want synchronous operation */ - pSendPacket->Completion = NULL; - HTC_PREPARE_SEND_PKT(pSendPacket,0,0,0); - status = HTCIssueSend(target,pSendPacket); - - if (status) { - break; - } - - /* wait for response */ - status = HTCWaitforControlMessage(target, &pRecvPacket); - - if (status) { - break; - } - /* we controlled the buffer creation so it has to be properly aligned */ - pResponseMsg = (HTC_CONNECT_SERVICE_RESPONSE_MSG *)pRecvPacket->pBuffer; - - if ((pResponseMsg->MessageID != HTC_MSG_CONNECT_SERVICE_RESPONSE_ID) || - (pRecvPacket->ActualLength < sizeof(HTC_CONNECT_SERVICE_RESPONSE_MSG))) { - /* this message is not valid */ - AR_DEBUG_ASSERT(false); - status = A_EPROTO; - break; - } - - pConnectResp->ConnectRespCode = pResponseMsg->Status; - /* check response status */ - if (pResponseMsg->Status != HTC_SERVICE_SUCCESS) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - (" Target failed service 0x%X connect request (status:%d)\n", - pResponseMsg->ServiceID, pResponseMsg->Status)); - status = A_EPROTO; - break; - } - - assignedEndpoint = (HTC_ENDPOINT_ID) pResponseMsg->EndpointID; - maxMsgSize = pResponseMsg->MaxMsgSize; - - if ((pConnectResp->pMetaData != NULL) && - (pResponseMsg->ServiceMetaLength > 0) && - (pResponseMsg->ServiceMetaLength <= HTC_SERVICE_META_DATA_MAX_LENGTH)) { - /* caller supplied a buffer and the target responded with data */ - int copyLength = min((int)pConnectResp->BufferLength, (int)pResponseMsg->ServiceMetaLength); - /* copy the meta data */ - memcpy(pConnectResp->pMetaData, - ((u8 *)pResponseMsg) + sizeof(HTC_CONNECT_SERVICE_RESPONSE_MSG), - copyLength); - pConnectResp->ActualLength = copyLength; - } - - } - - /* the rest of these are parameter checks so set the error status */ - status = A_EPROTO; - - if (assignedEndpoint >= ENDPOINT_MAX) { - AR_DEBUG_ASSERT(false); - break; - } - - if (0 == maxMsgSize) { - AR_DEBUG_ASSERT(false); - break; - } - - pEndpoint = &target->EndPoint[assignedEndpoint]; - pEndpoint->Id = assignedEndpoint; - if (pEndpoint->ServiceID != 0) { - /* endpoint already in use! */ - AR_DEBUG_ASSERT(false); - break; - } - - /* return assigned endpoint to caller */ - pConnectResp->Endpoint = assignedEndpoint; - pConnectResp->MaxMsgLength = maxMsgSize; - - /* setup the endpoint */ - pEndpoint->ServiceID = pConnectReq->ServiceID; /* this marks the endpoint in use */ - pEndpoint->MaxTxQueueDepth = pConnectReq->MaxSendQueueDepth; - pEndpoint->MaxMsgLength = maxMsgSize; - /* copy all the callbacks */ - pEndpoint->EpCallBacks = pConnectReq->EpCallbacks; - /* set the credit distribution info for this endpoint, this information is - * passed back to the credit distribution callback function */ - pEndpoint->CreditDist.ServiceID = pConnectReq->ServiceID; - pEndpoint->CreditDist.pHTCReserved = pEndpoint; - pEndpoint->CreditDist.Endpoint = assignedEndpoint; - pEndpoint->CreditDist.TxCreditSize = target->TargetCreditSize; - - if (pConnectReq->MaxSendMsgSize != 0) { - /* override TxCreditsPerMaxMsg calculation, this optimizes the credit-low indications - * since the host will actually issue smaller messages in the Send path */ - if (pConnectReq->MaxSendMsgSize > maxMsgSize) { - /* can't be larger than the maximum the target can support */ - AR_DEBUG_ASSERT(false); - break; - } - pEndpoint->CreditDist.TxCreditsPerMaxMsg = pConnectReq->MaxSendMsgSize / target->TargetCreditSize; - } else { - pEndpoint->CreditDist.TxCreditsPerMaxMsg = maxMsgSize / target->TargetCreditSize; - } - - if (0 == pEndpoint->CreditDist.TxCreditsPerMaxMsg) { - pEndpoint->CreditDist.TxCreditsPerMaxMsg = 1; - } - - /* save local connection flags */ - pEndpoint->LocalConnectionFlags = pConnectReq->LocalConnectionFlags; - - status = 0; - - } while (false); - - if (pSendPacket != NULL) { - HTC_FREE_CONTROL_TX(target,pSendPacket); - } - - if (pRecvPacket != NULL) { - HTC_FREE_CONTROL_RX(target,pRecvPacket); - } - - AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCConnectService \n")); - - return status; -} - -static void AddToEndpointDistList(struct htc_target *target, struct htc_endpoint_credit_dist *pEpDist) -{ - struct htc_endpoint_credit_dist *pCurEntry,*pLastEntry; - - if (NULL == target->EpCreditDistributionListHead) { - target->EpCreditDistributionListHead = pEpDist; - pEpDist->pNext = NULL; - pEpDist->pPrev = NULL; - return; - } - - /* queue to the end of the list, this does not have to be very - * fast since this list is built at startup time */ - pCurEntry = target->EpCreditDistributionListHead; - - while (pCurEntry) { - pLastEntry = pCurEntry; - pCurEntry = pCurEntry->pNext; - } - - pLastEntry->pNext = pEpDist; - pEpDist->pPrev = pLastEntry; - pEpDist->pNext = NULL; -} - - - -/* default credit init callback */ -static void HTCDefaultCreditInit(void *Context, - struct htc_endpoint_credit_dist *pEPList, - int TotalCredits) -{ - struct htc_endpoint_credit_dist *pCurEpDist; - int totalEps = 0; - int creditsPerEndpoint; - - pCurEpDist = pEPList; - /* first run through the list and figure out how many endpoints we are dealing with */ - while (pCurEpDist != NULL) { - pCurEpDist = pCurEpDist->pNext; - totalEps++; - } - - /* even distribution */ - creditsPerEndpoint = TotalCredits/totalEps; - - pCurEpDist = pEPList; - /* run through the list and set minimum and normal credits and - * provide the endpoint with some credits to start */ - while (pCurEpDist != NULL) { - - if (creditsPerEndpoint < pCurEpDist->TxCreditsPerMaxMsg) { - /* too many endpoints and not enough credits */ - AR_DEBUG_ASSERT(false); - break; - } - /* our minimum is set for at least 1 max message */ - pCurEpDist->TxCreditsMin = pCurEpDist->TxCreditsPerMaxMsg; - /* this value is ignored by our credit alg, since we do - * not dynamically adjust credits, this is the policy of - * the "default" credit distribution, something simple and easy */ - pCurEpDist->TxCreditsNorm = 0xFFFF; - /* give the endpoint minimum credits */ - pCurEpDist->TxCredits = creditsPerEndpoint; - pCurEpDist->TxCreditsAssigned = creditsPerEndpoint; - pCurEpDist = pCurEpDist->pNext; - } - -} - -/* default credit distribution callback, NOTE, this callback holds the TX lock */ -void HTCDefaultCreditDist(void *Context, - struct htc_endpoint_credit_dist *pEPDistList, - HTC_CREDIT_DIST_REASON Reason) -{ - struct htc_endpoint_credit_dist *pCurEpDist; - - if (Reason == HTC_CREDIT_DIST_SEND_COMPLETE) { - pCurEpDist = pEPDistList; - /* simple distribution */ - while (pCurEpDist != NULL) { - if (pCurEpDist->TxCreditsToDist > 0) { - /* just give the endpoint back the credits */ - pCurEpDist->TxCredits += pCurEpDist->TxCreditsToDist; - pCurEpDist->TxCreditsToDist = 0; - } - pCurEpDist = pCurEpDist->pNext; - } - } - - /* note we do not need to handle the other reason codes as this is a very - * simple distribution scheme, no need to seek for more credits or handle inactivity */ -} - -void HTCSetCreditDistribution(HTC_HANDLE HTCHandle, - void *pCreditDistContext, - HTC_CREDIT_DIST_CALLBACK CreditDistFunc, - HTC_CREDIT_INIT_CALLBACK CreditInitFunc, - HTC_SERVICE_ID ServicePriorityOrder[], - int ListLength) -{ - struct htc_target *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); - int i; - int ep; - - if (CreditInitFunc != NULL) { - /* caller has supplied their own distribution functions */ - target->InitCredits = CreditInitFunc; - AR_DEBUG_ASSERT(CreditDistFunc != NULL); - target->DistributeCredits = CreditDistFunc; - target->pCredDistContext = pCreditDistContext; - } else { - /* caller wants HTC to do distribution */ - /* if caller wants service to handle distributions then - * it must set both of these to NULL! */ - AR_DEBUG_ASSERT(CreditDistFunc == NULL); - target->InitCredits = HTCDefaultCreditInit; - target->DistributeCredits = HTCDefaultCreditDist; - target->pCredDistContext = target; - } - - /* always add HTC control endpoint first, we only expose the list after the - * first one, this is added for TX queue checking */ - AddToEndpointDistList(target, &target->EndPoint[ENDPOINT_0].CreditDist); - - /* build the list of credit distribution structures in priority order - * supplied by the caller, these will follow endpoint 0 */ - for (i = 0; i < ListLength; i++) { - /* match services with endpoints and add the endpoints to the distribution list - * in FIFO order */ - for (ep = ENDPOINT_1; ep < ENDPOINT_MAX; ep++) { - if (target->EndPoint[ep].ServiceID == ServicePriorityOrder[i]) { - /* queue this one to the list */ - AddToEndpointDistList(target, &target->EndPoint[ep].CreditDist); - break; - } - } - AR_DEBUG_ASSERT(ep < ENDPOINT_MAX); - } - -} diff --git a/drivers/staging/ath6kl/include/a_config.h b/drivers/staging/ath6kl/include/a_config.h deleted file mode 100644 index f7c0931..0000000 --- a/drivers/staging/ath6kl/include/a_config.h +++ /dev/null @@ -1,31 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="a_config.h" company="Atheros"> -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// Permission to use, copy, modify, and/or distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// This file contains software configuration options that enables -// specific software "features" -// -// Author(s): ="Atheros" -//============================================================================== -#ifndef _A_CONFIG_H_ -#define _A_CONFIG_H_ - -#include "../os/linux/include/config_linux.h" - -#endif diff --git a/drivers/staging/ath6kl/include/a_debug.h b/drivers/staging/ath6kl/include/a_debug.h deleted file mode 100644 index 5154fcb..0000000 --- a/drivers/staging/ath6kl/include/a_debug.h +++ /dev/null @@ -1,195 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="a_debug.h" company="Atheros"> -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Author(s): ="Atheros" -//============================================================================== -#ifndef _A_DEBUG_H_ -#define _A_DEBUG_H_ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -#include <a_osapi.h> - - /* standard debug print masks bits 0..7 */ -#define ATH_DEBUG_ERR (1 << 0) /* errors */ -#define ATH_DEBUG_WARN (1 << 1) /* warnings */ -#define ATH_DEBUG_INFO (1 << 2) /* informational (module startup info) */ -#define ATH_DEBUG_TRC (1 << 3) /* generic function call tracing */ -#define ATH_DEBUG_RSVD1 (1 << 4) -#define ATH_DEBUG_RSVD2 (1 << 5) -#define ATH_DEBUG_RSVD3 (1 << 6) -#define ATH_DEBUG_RSVD4 (1 << 7) - -#define ATH_DEBUG_MASK_DEFAULTS (ATH_DEBUG_ERR | ATH_DEBUG_WARN) -#define ATH_DEBUG_ANY 0xFFFF - - /* other aliases used throughout */ -#define ATH_DEBUG_ERROR ATH_DEBUG_ERR -#define ATH_LOG_ERR ATH_DEBUG_ERR -#define ATH_LOG_INF ATH_DEBUG_INFO -#define ATH_LOG_TRC ATH_DEBUG_TRC -#define ATH_DEBUG_TRACE ATH_DEBUG_TRC -#define ATH_DEBUG_INIT ATH_DEBUG_INFO - - /* bits 8..31 are module-specific masks */ -#define ATH_DEBUG_MODULE_MASK_SHIFT 8 - - /* macro to make a module-specific masks */ -#define ATH_DEBUG_MAKE_MODULE_MASK(index) (1 << (ATH_DEBUG_MODULE_MASK_SHIFT + (index))) - -void DebugDumpBytes(u8 *buffer, u16 length, char *pDescription); - -/* Debug support on a per-module basis - * - * Usage: - * - * Each module can utilize it's own debug mask variable. A set of commonly used - * masks are provided (ERRORS, WARNINGS, TRACE etc..). It is up to each module - * to define module-specific masks using the macros above. - * - * Each module defines a single debug mask variable debug_XXX where the "name" of the module is - * common to all C-files within that module. This requires every C-file that includes a_debug.h - * to define the module name in that file. - * - * Example: - * - * #define ATH_MODULE_NAME htc - * #include "a_debug.h" - * - * This will define a debug mask structure called debug_htc and all debug macros will reference this - * variable. - * - * A module can define module-specific bit masks using the ATH_DEBUG_MAKE_MODULE_MASK() macro: - * - * #define ATH_DEBUG_MY_MASK1 ATH_DEBUG_MAKE_MODULE_MASK(0) - * #define ATH_DEBUG_MY_MASK2 ATH_DEBUG_MAKE_MODULE_MASK(1) - * - * The instantiation of the debug structure should be made by the module. When a module is - * instantiated, the module can set a description string, a default mask and an array of description - * entries containing information on each module-defined debug mask. - * NOTE: The instantiation is statically allocated, only one instance can exist per module. - * - * Example: - * - * - * #define ATH_DEBUG_BMI ATH_DEBUG_MAKE_MODULE_MASK(0) - * - * #ifdef DEBUG - * static struct ath_debug_mask_description bmi_debug_desc[] = { - * { ATH_DEBUG_BMI , "BMI Tracing"}, <== description of the module specific mask - * }; - * - * ATH_DEBUG_INSTANTIATE_MODULE_VAR(bmi, - * "bmi" <== module name - * "Boot Manager Interface", <== description of module - * ATH_DEBUG_MASK_DEFAULTS, <== defaults - * ATH_DEBUG_DESCRIPTION_COUNT(bmi_debug_desc), - * bmi_debug_desc); - * - * #endif - * - * A module can optionally register it's debug module information in order for other tools to change the - * bit mask at runtime. A module can call A_REGISTER_MODULE_DEBUG_INFO() in it's module - * init code. This macro can be called multiple times without consequence. The debug info maintains - * state to indicate whether the information was previously registered. - * - * */ - -#define ATH_DEBUG_MAX_MASK_DESC_LENGTH 32 -#define ATH_DEBUG_MAX_MOD_DESC_LENGTH 64 - -struct ath_debug_mask_description { - u32 Mask; - char Description[ATH_DEBUG_MAX_MASK_DESC_LENGTH]; -}; - -#define ATH_DEBUG_INFO_FLAGS_REGISTERED (1 << 0) - -typedef struct _ATH_DEBUG_MODULE_DBG_INFO{ - struct _ATH_DEBUG_MODULE_DBG_INFO *pNext; - char ModuleName[16]; - char ModuleDescription[ATH_DEBUG_MAX_MOD_DESC_LENGTH]; - u32 Flags; - u32 CurrentMask; - int MaxDescriptions; - struct ath_debug_mask_description *pMaskDescriptions; /* pointer to array of descriptions */ -} ATH_DEBUG_MODULE_DBG_INFO; - -#define ATH_DEBUG_DESCRIPTION_COUNT(d) (int)((sizeof((d))) / (sizeof(struct ath_debug_mask_description))) - -#define GET_ATH_MODULE_DEBUG_VAR_NAME(s) _XGET_ATH_MODULE_NAME_DEBUG_(s) -#define GET_ATH_MODULE_DEBUG_VAR_MASK(s) _XGET_ATH_MODULE_NAME_DEBUG_(s).CurrentMask -#define _XGET_ATH_MODULE_NAME_DEBUG_(s) debug_ ## s - -#ifdef ATH_DEBUG_MODULE - - /* for source files that will instantiate the debug variables */ -#define ATH_DEBUG_INSTANTIATE_MODULE_VAR(s,name,moddesc,initmask,count,descriptions) \ -ATH_DEBUG_MODULE_DBG_INFO GET_ATH_MODULE_DEBUG_VAR_NAME(s) = \ - {NULL,(name),(moddesc),0,(initmask),count,(descriptions)} - -#ifdef ATH_MODULE_NAME -extern ATH_DEBUG_MODULE_DBG_INFO GET_ATH_MODULE_DEBUG_VAR_NAME(ATH_MODULE_NAME); -#define AR_DEBUG_LVL_CHECK(lvl) (GET_ATH_MODULE_DEBUG_VAR_MASK(ATH_MODULE_NAME) & (lvl)) -#endif /* ATH_MODULE_NAME */ - -#define ATH_DEBUG_SET_DEBUG_MASK(s,lvl) GET_ATH_MODULE_DEBUG_VAR_MASK(s) = (lvl) - -#define ATH_DEBUG_DECLARE_EXTERN(s) \ - extern ATH_DEBUG_MODULE_DBG_INFO GET_ATH_MODULE_DEBUG_VAR_NAME(s) - -#define AR_DEBUG_PRINTBUF(buffer, length, desc) DebugDumpBytes(buffer,length,desc) - - -#define AR_DEBUG_ASSERT A_ASSERT - -void a_dump_module_debug_info(ATH_DEBUG_MODULE_DBG_INFO *pInfo); -void a_register_module_debug_info(ATH_DEBUG_MODULE_DBG_INFO *pInfo); -#define A_DUMP_MODULE_DEBUG_INFO(s) a_dump_module_debug_info(&(GET_ATH_MODULE_DEBUG_VAR_NAME(s))) -#define A_REGISTER_MODULE_DEBUG_INFO(s) a_register_module_debug_info(&(GET_ATH_MODULE_DEBUG_VAR_NAME(s))) - -#else /* !ATH_DEBUG_MODULE */ - /* NON ATH_DEBUG_MODULE */ -#define ATH_DEBUG_INSTANTIATE_MODULE_VAR(s,name,moddesc,initmask,count,descriptions) -#define AR_DEBUG_LVL_CHECK(lvl) 0 -#define AR_DEBUG_PRINTBUF(buffer, length, desc) -#define AR_DEBUG_ASSERT(test) -#define ATH_DEBUG_DECLARE_EXTERN(s) -#define ATH_DEBUG_SET_DEBUG_MASK(s,lvl) -#define A_DUMP_MODULE_DEBUG_INFO(s) -#define A_REGISTER_MODULE_DEBUG_INFO(s) - -#endif - -int a_get_module_mask(char *module_name, u32 *pMask); -int a_set_module_mask(char *module_name, u32 Mask); -void a_dump_module_debug_info_by_name(char *module_name); -void a_module_debug_support_init(void); -void a_module_debug_support_cleanup(void); - -#include "../os/linux/include/debug_linux.h" - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif diff --git a/drivers/staging/ath6kl/include/a_drv.h b/drivers/staging/ath6kl/include/a_drv.h deleted file mode 100644 index 1548604..0000000 --- a/drivers/staging/ath6kl/include/a_drv.h +++ /dev/null @@ -1,32 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="a_drv.h" company="Atheros"> -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// Permission to use, copy, modify, and/or distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// This file contains the definitions of the basic atheros data types. -// It is used to map the data types in atheros files to a platform specific -// type. -// -// Author(s): ="Atheros" -//============================================================================== -#ifndef _A_DRV_H_ -#define _A_DRV_H_ - -#include "../os/linux/include/athdrv_linux.h" - -#endif /* _ADRV_H_ */ diff --git a/drivers/staging/ath6kl/include/a_drv_api.h b/drivers/staging/ath6kl/include/a_drv_api.h deleted file mode 100644 index a40d97a..0000000 --- a/drivers/staging/ath6kl/include/a_drv_api.h +++ /dev/null @@ -1,204 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="a_drv_api.h" company="Atheros"> -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Author(s): ="Atheros" -//============================================================================== -#ifndef _A_DRV_API_H_ -#define _A_DRV_API_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/****************************************************************************/ -/****************************************************************************/ -/** **/ -/** WMI related hooks **/ -/** **/ -/****************************************************************************/ -/****************************************************************************/ - -#include <ar6000_api.h> - -#define A_WMI_CHANNELLIST_RX(devt, numChan, chanList) \ - ar6000_channelList_rx((devt), (numChan), (chanList)) - -#define A_WMI_SET_NUMDATAENDPTS(devt, num) \ - ar6000_set_numdataendpts((devt), (num)) - -#define A_WMI_CONTROL_TX(devt, osbuf, streamID) \ - ar6000_control_tx((devt), (osbuf), (streamID)) - -#define A_WMI_TARGETSTATS_EVENT(devt, pStats, len) \ - ar6000_targetStats_event((devt), (pStats), (len)) - -#define A_WMI_SCANCOMPLETE_EVENT(devt, status) \ - ar6000_scanComplete_event((devt), (status)) - -#ifdef CONFIG_HOST_DSET_SUPPORT - -#define A_WMI_DSET_DATA_REQ(devt, access_cookie, offset, length, targ_buf, targ_reply_fn, targ_reply_arg) \ - ar6000_dset_data_req((devt), (access_cookie), (offset), (length), (targ_buf), (targ_reply_fn), (targ_reply_arg)) - -#define A_WMI_DSET_CLOSE(devt, access_cookie) \ - ar6000_dset_close((devt), (access_cookie)) - -#endif - -#define A_WMI_DSET_OPEN_REQ(devt, id, targ_handle, targ_reply_fn, targ_reply_arg) \ - ar6000_dset_open_req((devt), (id), (targ_handle), (targ_reply_fn), (targ_reply_arg)) - -#define A_WMI_CONNECT_EVENT(devt, channel, bssid, listenInterval, beaconInterval, networkType, beaconIeLen, assocReqLen, assocRespLen, assocInfo) \ - ar6000_connect_event((devt), (channel), (bssid), (listenInterval), (beaconInterval), (networkType), (beaconIeLen), (assocReqLen), (assocRespLen), (assocInfo)) - -#define A_WMI_PSPOLL_EVENT(devt, aid)\ - ar6000_pspoll_event((devt),(aid)) - -#define A_WMI_DTIMEXPIRY_EVENT(devt)\ - ar6000_dtimexpiry_event((devt)) - -#ifdef WAPI_ENABLE -#define A_WMI_WAPI_REKEY_EVENT(devt, type, mac)\ - ap_wapi_rekey_event((devt),(type),(mac)) -#endif - -#define A_WMI_REGDOMAIN_EVENT(devt, regCode) \ - ar6000_regDomain_event((devt), (regCode)) - -#define A_WMI_NEIGHBORREPORT_EVENT(devt, numAps, info) \ - ar6000_neighborReport_event((devt), (numAps), (info)) - -#define A_WMI_DISCONNECT_EVENT(devt, reason, bssid, assocRespLen, assocInfo, protocolReasonStatus) \ - ar6000_disconnect_event((devt), (reason), (bssid), (assocRespLen), (assocInfo), (protocolReasonStatus)) - -#define A_WMI_TKIP_MICERR_EVENT(devt, keyid, ismcast) \ - ar6000_tkip_micerr_event((devt), (keyid), (ismcast)) - -#define A_WMI_BITRATE_RX(devt, rateKbps) \ - ar6000_bitrate_rx((devt), (rateKbps)) - -#define A_WMI_TXPWR_RX(devt, txPwr) \ - ar6000_txPwr_rx((devt), (txPwr)) - -#define A_WMI_READY_EVENT(devt, datap, phyCap, sw_ver, abi_ver) \ - ar6000_ready_event((devt), (datap), (phyCap), (sw_ver), (abi_ver)) - -#define A_WMI_DBGLOG_INIT_DONE(ar) \ - ar6000_dbglog_init_done(ar); - -#define A_WMI_RSSI_THRESHOLD_EVENT(devt, newThreshold, rssi) \ - ar6000_rssiThreshold_event((devt), (newThreshold), (rssi)) - -#define A_WMI_REPORT_ERROR_EVENT(devt, errorVal) \ - ar6000_reportError_event((devt), (errorVal)) - -#define A_WMI_ROAM_TABLE_EVENT(devt, pTbl) \ - ar6000_roam_tbl_event((devt), (pTbl)) - -#define A_WMI_ROAM_DATA_EVENT(devt, p) \ - ar6000_roam_data_event((devt), (p)) - -#define A_WMI_WOW_LIST_EVENT(devt, num_filters, wow_filters) \ - ar6000_wow_list_event((devt), (num_filters), (wow_filters)) - -#define A_WMI_CAC_EVENT(devt, ac, cac_indication, statusCode, tspecSuggestion) \ - ar6000_cac_event((devt), (ac), (cac_indication), (statusCode), (tspecSuggestion)) - -#define A_WMI_CHANNEL_CHANGE_EVENT(devt, oldChannel, newChannel) \ - ar6000_channel_change_event((devt), (oldChannel), (newChannel)) - -#define A_WMI_PMKID_LIST_EVENT(devt, num_pmkid, pmkid_list, bssid_list) \ - ar6000_pmkid_list_event((devt), (num_pmkid), (pmkid_list), (bssid_list)) - -#define A_WMI_PEER_EVENT(devt, eventCode, bssid) \ - ar6000_peer_event ((devt), (eventCode), (bssid)) - -#ifdef CONFIG_HOST_TCMD_SUPPORT -#define A_WMI_TCMD_RX_REPORT_EVENT(devt, results, len) \ - ar6000_tcmd_rx_report_event((devt), (results), (len)) -#endif - -#define A_WMI_HBCHALLENGERESP_EVENT(devt, cookie, source) \ - ar6000_hbChallengeResp_event((devt), (cookie), (source)) - -#define A_WMI_TX_RETRY_ERR_EVENT(devt) \ - ar6000_tx_retry_err_event((devt)) - -#define A_WMI_SNR_THRESHOLD_EVENT_RX(devt, newThreshold, snr) \ - ar6000_snrThresholdEvent_rx((devt), (newThreshold), (snr)) - -#define A_WMI_LQ_THRESHOLD_EVENT_RX(devt, range, lqVal) \ - ar6000_lqThresholdEvent_rx((devt), (range), (lqVal)) - -#define A_WMI_RATEMASK_RX(devt, ratemask) \ - ar6000_ratemask_rx((devt), (ratemask)) - -#define A_WMI_KEEPALIVE_RX(devt, configured) \ - ar6000_keepalive_rx((devt), (configured)) - -#define A_WMI_BSSINFO_EVENT_RX(ar, datp, len) \ - ar6000_bssInfo_event_rx((ar), (datap), (len)) - -#define A_WMI_DBGLOG_EVENT(ar, dropped, buffer, length) \ - ar6000_dbglog_event((ar), (dropped), (buffer), (length)); - -#define A_WMI_STREAM_TX_ACTIVE(devt,trafficClass) \ - ar6000_indicate_tx_activity((devt),(trafficClass), true) - -#define A_WMI_STREAM_TX_INACTIVE(devt,trafficClass) \ - ar6000_indicate_tx_activity((devt),(trafficClass), false) -#define A_WMI_Ac2EndpointID(devht, ac)\ - ar6000_ac2_endpoint_id((devht), (ac)) - -#define A_WMI_AGGR_RECV_ADDBA_REQ_EVT(devt, cmd)\ - ar6000_aggr_rcv_addba_req_evt((devt), (cmd)) -#define A_WMI_AGGR_RECV_ADDBA_RESP_EVT(devt, cmd)\ - ar6000_aggr_rcv_addba_resp_evt((devt), (cmd)) -#define A_WMI_AGGR_RECV_DELBA_REQ_EVT(devt, cmd)\ - ar6000_aggr_rcv_delba_req_evt((devt), (cmd)) -#define A_WMI_HCI_EVENT_EVT(devt, cmd)\ - ar6000_hci_event_rcv_evt((devt), (cmd)) - -#define A_WMI_Endpoint2Ac(devt, ep) \ - ar6000_endpoint_id2_ac((devt), (ep)) - -#define A_WMI_BTCOEX_CONFIG_EVENT(devt, evt, len)\ - ar6000_btcoex_config_event((devt), (evt), (len)) - -#define A_WMI_BTCOEX_STATS_EVENT(devt, datap, len)\ - ar6000_btcoex_stats_event((devt), (datap), (len)) - -/****************************************************************************/ -/****************************************************************************/ -/** **/ -/** HTC related hooks **/ -/** **/ -/****************************************************************************/ -/****************************************************************************/ - -#if defined(CONFIG_TARGET_PROFILE_SUPPORT) -#define A_WMI_PROF_COUNT_RX(addr, count) prof_count_rx((addr), (count)) -#endif /* CONFIG_TARGET_PROFILE_SUPPORT */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/drivers/staging/ath6kl/include/a_osapi.h b/drivers/staging/ath6kl/include/a_osapi.h deleted file mode 100644 index fd7ae0d..0000000 --- a/drivers/staging/ath6kl/include/a_osapi.h +++ /dev/null @@ -1,32 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="a_osapi.h" company="Atheros"> -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// Permission to use, copy, modify, and/or distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// This file contains the definitions of the basic atheros data types. -// It is used to map the data types in atheros files to a platform specific -// type. -// -// Author(s): ="Atheros" -//============================================================================== -#ifndef _A_OSAPI_H_ -#define _A_OSAPI_H_ - -#include "../os/linux/include/osapi_linux.h" - -#endif /* _OSAPI_H_ */ diff --git a/drivers/staging/ath6kl/include/aggr_recv_api.h b/drivers/staging/ath6kl/include/aggr_recv_api.h deleted file mode 100644 index 5ead58d..0000000 --- a/drivers/staging/ath6kl/include/aggr_recv_api.h +++ /dev/null @@ -1,140 +0,0 @@ -/* - * - * Copyright (c) 2004-2010 Atheros Communications Inc. - * All rights reserved. - * - * -// -// 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 __AGGR_RECV_API_H__ -#define __AGGR_RECV_API_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void (* RX_CALLBACK)(void * dev, void *osbuf); - -typedef void (* ALLOC_NETBUFS)(A_NETBUF_QUEUE_T *q, u16 num); - -/* - * aggr_init: - * Initialises the data structures, allocates data queues and - * os buffers. Netbuf allocator is the input param, used by the - * aggr module for allocation of NETBUFs from driver context. - * These NETBUFs are used for AMSDU processing. - * Returns the context for the aggr module. - */ -void * -aggr_init(ALLOC_NETBUFS netbuf_allocator); - - -/* - * aggr_register_rx_dispatcher: - * Registers OS call back function to deliver the - * frames to OS. This is generally the topmost layer of - * the driver context, after which the frames go to - * IP stack via the call back function. - * This dispatcher is active only when aggregation is ON. - */ -void -aggr_register_rx_dispatcher(void *cntxt, void * dev, RX_CALLBACK fn); - - -/* - * aggr_process_bar: - * When target receives BAR, it communicates to host driver - * for modifying window parameters. Target indicates this via the - * event: WMI_ADDBA_REQ_EVENTID. Host will dequeue all frames - * up to the indicated sequence number. - */ -void -aggr_process_bar(void *cntxt, u8 tid, u16 seq_no); - - -/* - * aggr_recv_addba_req_evt: - * This event is to initiate/modify the receive side window. - * Target will send WMI_ADDBA_REQ_EVENTID event to host - to setup - * recv re-ordering queues. Target will negotiate ADDBA with peer, - * and indicate via this event after successfully completing the - * negotiation. This happens in two situations: - * 1. Initial setup of aggregation - * 2. Renegotiation of current recv window. - * Window size for re-ordering is limited by target buffer - * space, which is reflected in win_sz. - * (Re)Start the periodic timer to deliver long standing frames, - * in hold_q to OS. - */ -void -aggr_recv_addba_req_evt(void * cntxt, u8 tid, u16 seq_no, u8 win_sz); - - -/* - * aggr_recv_delba_req_evt: - * Target indicates deletion of a BA window for a tid via the - * WMI_DELBA_EVENTID. Host would deliver all the frames in the - * hold_q, reset tid config and disable the periodic timer, if - * aggr is not enabled on any tid. - */ -void -aggr_recv_delba_req_evt(void * cntxt, u8 tid); - - - -/* - * aggr_process_recv_frm: - * Called only for data frames. When aggr is ON for a tid, the buffer - * is always consumed, and osbuf would be NULL. For a non-aggr case, - * osbuf is not modified. - * AMSDU frames are consumed and are later freed. They are sliced and - * diced to individual frames and dispatched to stack. - * After consuming a osbuf(when aggr is ON), a previously registered - * callback may be called to deliver frames in order. - */ -void -aggr_process_recv_frm(void *cntxt, u8 tid, u16 seq_no, bool is_amsdu, void **osbuf); - - -/* - * aggr_module_destroy: - * Frees up all the queues and frames in them. Releases the cntxt to OS. - */ -void -aggr_module_destroy(void *cntxt); - -/* - * Dumps the aggregation stats - */ -void -aggr_dump_stats(void *cntxt, PACKET_LOG **log_buf); - -/* - * aggr_reset_state -- Called when it is deemed necessary to clear the aggregate - * hold Q state. Examples include when a Connect event or disconnect event is - * received. - */ -void -aggr_reset_state(void *cntxt); - - -#ifdef __cplusplus -} -#endif - -#endif /*__AGGR_RECV_API_H__ */ diff --git a/drivers/staging/ath6kl/include/ar3kconfig.h b/drivers/staging/ath6kl/include/ar3kconfig.h deleted file mode 100644 index 91bc4ee..0000000 --- a/drivers/staging/ath6kl/include/ar3kconfig.h +++ /dev/null @@ -1,65 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Author(s): ="Atheros" -//============================================================================== - -/* AR3K module configuration APIs for HCI-bridge operation */ - -#ifndef AR3KCONFIG_H_ -#define AR3KCONFIG_H_ - -#include <net/bluetooth/bluetooth.h> -#include <net/bluetooth/hci_core.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#define AR3K_CONFIG_FLAG_FORCE_MINBOOT_EXIT (1 << 0) -#define AR3K_CONFIG_FLAG_SET_AR3K_BAUD (1 << 1) -#define AR3K_CONFIG_FLAG_AR3K_BAUD_CHANGE_DELAY (1 << 2) -#define AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP (1 << 3) - - -struct ar3k_config_info { - u32 Flags; /* config flags */ - void *pHCIDev; /* HCI bridge device */ - struct hci_transport_properties *pHCIProps; /* HCI bridge props */ - struct hif_device *pHIFDevice; /* HIF layer device */ - - u32 AR3KBaudRate; /* AR3K operational baud rate */ - u16 AR6KScale; /* AR6K UART scale value */ - u16 AR6KStep; /* AR6K UART step value */ - struct hci_dev *pBtStackHCIDev; /* BT Stack HCI dev */ - u32 PwrMgmtEnabled; /* TLPM enabled? */ - u16 IdleTimeout; /* TLPM idle timeout */ - u16 WakeupTimeout; /* TLPM wakeup timeout */ - u8 bdaddr[6]; /* Bluetooth device address */ -}; - -int AR3KConfigure(struct ar3k_config_info *pConfigInfo); - -int AR3KConfigureExit(void *config); - -#ifdef __cplusplus -} -#endif - -#endif /*AR3KCONFIG_H_*/ diff --git a/drivers/staging/ath6kl/include/ar6000_api.h b/drivers/staging/ath6kl/include/ar6000_api.h deleted file mode 100644 index e946080..0000000 --- a/drivers/staging/ath6kl/include/ar6000_api.h +++ /dev/null @@ -1,32 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="ar6000_api.h" company="Atheros"> -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// Permission to use, copy, modify, and/or distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// This file contains the API to access the OS dependent atheros host driver -// by the WMI or WLAN generic modules. -// -// Author(s): ="Atheros" -//============================================================================== -#ifndef _AR6000_API_H_ -#define _AR6000_API_H_ - -#include "../os/linux/include/ar6xapi_linux.h" - -#endif /* _AR6000_API_H */ - diff --git a/drivers/staging/ath6kl/include/ar6000_diag.h b/drivers/staging/ath6kl/include/ar6000_diag.h deleted file mode 100644 index 739c01c..0000000 --- a/drivers/staging/ath6kl/include/ar6000_diag.h +++ /dev/null @@ -1,48 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="ar6000_diag.h" company="Atheros"> -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Author(s): ="Atheros" -//============================================================================== - -#ifndef AR6000_DIAG_H_ -#define AR6000_DIAG_H_ - - -int -ar6000_ReadRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data); - -int -ar6000_WriteRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data); - -int -ar6000_ReadDataDiag(struct hif_device *hifDevice, u32 address, - u8 *data, u32 length); - -int -ar6000_WriteDataDiag(struct hif_device *hifDevice, u32 address, - u8 *data, u32 length); - -int -ar6k_ReadTargetRegister(struct hif_device *hifDevice, int regsel, u32 *regval); - -void -ar6k_FetchTargetRegs(struct hif_device *hifDevice, u32 *targregs); - -#endif /*AR6000_DIAG_H_*/ diff --git a/drivers/staging/ath6kl/include/ar6kap_common.h b/drivers/staging/ath6kl/include/ar6kap_common.h deleted file mode 100644 index 532d8eb..0000000 --- a/drivers/staging/ath6kl/include/ar6kap_common.h +++ /dev/null @@ -1,44 +0,0 @@ -//------------------------------------------------------------------------------ - -// <copyright file="ar6kap_common.h" company="Atheros"> -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// Permission to use, copy, modify, and/or distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -// -// -//------------------------------------------------------------------------------ - -//============================================================================== - -// This file contains the definitions of common AP mode data structures. -// -// Author(s): ="Atheros" -//============================================================================== - -#ifndef _AR6KAP_COMMON_H_ -#define _AR6KAP_COMMON_H_ -/* - * Used with AR6000_XIOCTL_AP_GET_STA_LIST - */ -typedef struct { - u8 mac[ATH_MAC_LEN]; - u8 aid; - u8 keymgmt; - u8 ucipher; - u8 auth; -} station_t; -typedef struct { - station_t sta[AP_MAX_NUM_STA]; -} ap_get_sta_t; -#endif /* _AR6KAP_COMMON_H_ */ diff --git a/drivers/staging/ath6kl/include/athbtfilter.h b/drivers/staging/ath6kl/include/athbtfilter.h deleted file mode 100644 index 81456ee..0000000 --- a/drivers/staging/ath6kl/include/athbtfilter.h +++ /dev/null @@ -1,135 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="athbtfilter.h" company="Atheros"> -// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Public Bluetooth filter APIs -// Author(s): ="Atheros" -//============================================================================== -#ifndef ATHBTFILTER_H_ -#define ATHBTFILTER_H_ - -#define ATH_DEBUG_INFO (1 << 2) -#define ATH_DEBUG_INF ATH_DEBUG_INFO - -typedef enum _ATHBT_HCI_CTRL_TYPE { - ATHBT_HCI_COMMAND = 0, - ATHBT_HCI_EVENT = 1, -} ATHBT_HCI_CTRL_TYPE; - -typedef enum _ATHBT_STATE_INDICATION { - ATH_BT_NOOP = 0, - ATH_BT_INQUIRY = 1, - ATH_BT_CONNECT = 2, - ATH_BT_SCO = 3, - ATH_BT_ACL = 4, - ATH_BT_A2DP = 5, - ATH_BT_ESCO = 6, - /* new states go here.. */ - - ATH_BT_MAX_STATE_INDICATION -} ATHBT_STATE_INDICATION; - - /* filter function for OUTGOING commands and INCOMMING events */ -typedef void (*ATHBT_FILTER_CMD_EVENTS_FN)(void *pContext, ATHBT_HCI_CTRL_TYPE Type, unsigned char *pBuffer, int Length); - - /* filter function for OUTGOING data HCI packets */ -typedef void (*ATHBT_FILTER_DATA_FN)(void *pContext, unsigned char *pBuffer, int Length); - -typedef enum _ATHBT_STATE { - STATE_OFF = 0, - STATE_ON = 1, - STATE_MAX -} ATHBT_STATE; - - /* BT state indication (when filter functions are not used) */ - -typedef void (*ATHBT_INDICATE_STATE_FN)(void *pContext, ATHBT_STATE_INDICATION Indication, ATHBT_STATE State, unsigned char LMPVersion); - -struct athbt_filter_instance { -#ifdef UNDER_CE - WCHAR *pWlanAdapterName; /* filled in by user */ -#else - char *pWlanAdapterName; /* filled in by user */ -#endif /* UNDER_CE */ - int FilterEnabled; /* filtering is enabled */ - int Attached; /* filter library is attached */ - void *pContext; /* private context for filter library */ - ATHBT_FILTER_CMD_EVENTS_FN pFilterCmdEvents; /* function ptr to filter a command or event */ - ATHBT_FILTER_DATA_FN pFilterAclDataOut; /* function ptr to filter ACL data out (to radio) */ - ATHBT_FILTER_DATA_FN pFilterAclDataIn; /* function ptr to filter ACL data in (from radio) */ - ATHBT_INDICATE_STATE_FN pIndicateState; /* function ptr to indicate a state */ -}; /* XXX: unused ? */ - - -/* API MACROS */ - -#define AthBtFilterHciCommand(instance,packet,length) \ - if ((instance)->FilterEnabled) { \ - (instance)->pFilterCmdEvents((instance)->pContext, \ - ATHBT_HCI_COMMAND, \ - (unsigned char *)(packet), \ - (length)); \ - } - -#define AthBtFilterHciEvent(instance,packet,length) \ - if ((instance)->FilterEnabled) { \ - (instance)->pFilterCmdEvents((instance)->pContext, \ - ATHBT_HCI_EVENT, \ - (unsigned char *)(packet), \ - (length)); \ - } - -#define AthBtFilterHciAclDataOut(instance,packet,length) \ - if ((instance)->FilterEnabled) { \ - (instance)->pFilterAclDataOut((instance)->pContext, \ - (unsigned char *)(packet), \ - (length)); \ - } - -#define AthBtFilterHciAclDataIn(instance,packet,length) \ - if ((instance)->FilterEnabled) { \ - (instance)->pFilterAclDataIn((instance)->pContext, \ - (unsigned char *)(packet), \ - (length)); \ - } - -/* if filtering is not desired, the application can indicate the state directly using this - * macro: - */ -#define AthBtIndicateState(instance,indication,state) \ - if ((instance)->FilterEnabled) { \ - (instance)->pIndicateState((instance)->pContext, \ - (indication), \ - (state), \ - 0); \ - } - -#ifdef __cplusplus -extern "C" { -#endif - -/* API prototypes */ -int AthBtFilter_Attach(ATH_BT_FILTER_INSTANCE *pInstance, unsigned int flags); -void AthBtFilter_Detach(ATH_BT_FILTER_INSTANCE *pInstance); - -#ifdef __cplusplus -} -#endif - -#endif /*ATHBTFILTER_H_*/ diff --git a/drivers/staging/ath6kl/include/bmi.h b/drivers/staging/ath6kl/include/bmi.h deleted file mode 100644 index d3227f7..0000000 --- a/drivers/staging/ath6kl/include/bmi.h +++ /dev/null @@ -1,134 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="bmi.h" company="Atheros"> -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// BMI declarations and prototypes -// -// Author(s): ="Atheros" -//============================================================================== -#ifndef _BMI_H_ -#define _BMI_H_ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* Header files */ -#include "a_config.h" -#include "athdefs.h" -#include "hif.h" -#include "a_osapi.h" -#include "bmi_msg.h" - -void -BMIInit(void); - -void -BMICleanup(void); - -int -BMIDone(struct hif_device *device); - -int -BMIGetTargetInfo(struct hif_device *device, struct bmi_target_info *targ_info); - -int -BMIReadMemory(struct hif_device *device, - u32 address, - u8 *buffer, - u32 length); - -int -BMIWriteMemory(struct hif_device *device, - u32 address, - u8 *buffer, - u32 length); - -int -BMIExecute(struct hif_device *device, - u32 address, - u32 *param); - -int -BMISetAppStart(struct hif_device *device, - u32 address); - -int -BMIReadSOCRegister(struct hif_device *device, - u32 address, - u32 *param); - -int -BMIWriteSOCRegister(struct hif_device *device, - u32 address, - u32 param); - -int -BMIrompatchInstall(struct hif_device *device, - u32 ROM_addr, - u32 RAM_addr, - u32 nbytes, - u32 do_activate, - u32 *patch_id); - -int -BMIrompatchUninstall(struct hif_device *device, - u32 rompatch_id); - -int -BMIrompatchActivate(struct hif_device *device, - u32 rompatch_count, - u32 *rompatch_list); - -int -BMIrompatchDeactivate(struct hif_device *device, - u32 rompatch_count, - u32 *rompatch_list); - -int -BMILZStreamStart(struct hif_device *device, - u32 address); - -int -BMILZData(struct hif_device *device, - u8 *buffer, - u32 length); - -int -BMIFastDownload(struct hif_device *device, - u32 address, - u8 *buffer, - u32 length); - -int -BMIRawWrite(struct hif_device *device, - u8 *buffer, - u32 length); - -int -BMIRawRead(struct hif_device *device, - u8 *buffer, - u32 length, - bool want_timeout); - -#ifdef __cplusplus -} -#endif - -#endif /* _BMI_H_ */ diff --git a/drivers/staging/ath6kl/include/common/AR6002/AR6K_version.h b/drivers/staging/ath6kl/include/common/AR6002/AR6K_version.h deleted file mode 100644 index 5407e05d..0000000 --- a/drivers/staging/ath6kl/include/common/AR6002/AR6K_version.h +++ /dev/null @@ -1,52 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="AR6K_version.h" company="Atheros"> -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Author(s): ="Atheros" -//============================================================================== - -#define __VER_MAJOR_ 3 -#define __VER_MINOR_ 0 -#define __VER_PATCH_ 0 - -/* The makear6ksdk script (used for release builds) modifies the following line. */ -#define __BUILD_NUMBER_ 233 - - -/* Format of the version number. */ -#define VER_MAJOR_BIT_OFFSET 28 -#define VER_MINOR_BIT_OFFSET 24 -#define VER_PATCH_BIT_OFFSET 16 -#define VER_BUILD_NUM_BIT_OFFSET 0 - - -/* - * The version has the following format: - * Bits 28-31: Major version - * Bits 24-27: Minor version - * Bits 16-23: Patch version - * Bits 0-15: Build number (automatically generated during build process ) - * E.g. Build 1.1.3.7 would be represented as 0x11030007. - * - * DO NOT split the following macro into multiple lines as this may confuse the build scripts. - */ -#define AR6K_SW_VERSION ( ( __VER_MAJOR_ << VER_MAJOR_BIT_OFFSET ) + ( __VER_MINOR_ << VER_MINOR_BIT_OFFSET ) + ( __VER_PATCH_ << VER_PATCH_BIT_OFFSET ) + ( __BUILD_NUMBER_ << VER_BUILD_NUM_BIT_OFFSET ) ) - -/* ABI Version. Reflects the version of binary interface exposed by AR6K target firmware. Needs to be incremented by 1 for any change in the firmware that requires upgrade of the driver on the host side for the change to work correctly */ -#define AR6K_ABI_VERSION 1 diff --git a/drivers/staging/ath6kl/include/common/AR6002/addrs.h b/drivers/staging/ath6kl/include/common/AR6002/addrs.h deleted file mode 100644 index bbf8d42..0000000 --- a/drivers/staging/ath6kl/include/common/AR6002/addrs.h +++ /dev/null @@ -1,90 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -// -// Author(s): ="Atheros" -//------------------------------------------------------------------------------ - -#ifndef __ADDRS_H__ -#define __ADDRS_H__ - -/* - * Special AR6002 Addresses that may be needed by special - * applications (e.g. ART) on the Host as well as Target. - */ - -#if defined(AR6002_REV2) -#define AR6K_RAM_START 0x00500000 -#define TARG_RAM_OFFSET(vaddr) ((u32)(vaddr) & 0xfffff) -#define TARG_RAM_SZ (184*1024) -#define TARG_ROM_SZ (80*1024) -#endif -#if defined(AR6002_REV4) || defined(AR6003) -#define AR6K_RAM_START 0x00540000 -#define TARG_RAM_OFFSET(vaddr) (((u32)(vaddr) & 0xfffff) - 0x40000) -#define TARG_RAM_SZ (256*1024) -#define TARG_ROM_SZ (256*1024) -#endif - -#define AR6002_BOARD_DATA_SZ 768 -#define AR6002_BOARD_EXT_DATA_SZ 0 -#define AR6003_BOARD_DATA_SZ 1024 -#define AR6003_BOARD_EXT_DATA_SZ 768 - -#define AR6K_RAM_ADDR(byte_offset) (AR6K_RAM_START+(byte_offset)) -#define TARG_RAM_ADDRS(byte_offset) AR6K_RAM_ADDR(byte_offset) - -#define AR6K_ROM_START 0x004e0000 -#define TARG_ROM_OFFSET(vaddr) (((u32)(vaddr) & 0x1fffff) - 0xe0000) -#define AR6K_ROM_ADDR(byte_offset) (AR6K_ROM_START+(byte_offset)) -#define TARG_ROM_ADDRS(byte_offset) AR6K_ROM_ADDR(byte_offset) - -/* - * At this ROM address is a pointer to the start of the ROM DataSet Index. - * If there are no ROM DataSets, there's a 0 at this address. - */ -#define ROM_DATASET_INDEX_ADDR (TARG_ROM_ADDRS(TARG_ROM_SZ)-8) -#define ROM_MBIST_CKSUM_ADDR (TARG_ROM_ADDRS(TARG_ROM_SZ)-4) - -/* - * The API A_BOARD_DATA_ADDR() is the proper way to get a read pointer to - * board data. - */ - -/* Size of Board Data, in bytes */ -#if defined(AR6002_REV4) || defined(AR6003) -#define BOARD_DATA_SZ AR6003_BOARD_DATA_SZ -#else -#define BOARD_DATA_SZ AR6002_BOARD_DATA_SZ -#endif - - -/* - * Constants used by ASM code to access fields of host_interest_s, - * which is at a fixed location in RAM. - */ -#if defined(AR6002_REV4) || defined(AR6003) -#define HOST_INTEREST_FLASH_IS_PRESENT_ADDR (AR6K_RAM_START + 0x60c) -#else -#define HOST_INTEREST_FLASH_IS_PRESENT_ADDR (AR6K_RAM_START + 0x40c) -#endif -#define FLASH_IS_PRESENT_TARGADDR HOST_INTEREST_FLASH_IS_PRESENT_ADDR - -#endif /* __ADDRS_H__ */ - - - diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_athr_wlan_map.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_athr_wlan_map.h deleted file mode 100644 index 609eb98..0000000 --- a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_athr_wlan_map.h +++ /dev/null @@ -1,40 +0,0 @@ -// ------------------------------------------------------------------ -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -// ------------------------------------------------------------------ -//=================================================================== -// Author(s): ="Atheros" -//=================================================================== - - -#ifndef _APB_ATHR_WLAN_MAP_H_ -#define _APB_ATHR_WLAN_MAP_H_ - -#define WLAN_RTC_BASE_ADDRESS 0x00004000 -#define WLAN_VMC_BASE_ADDRESS 0x00008000 -#define WLAN_UART_BASE_ADDRESS 0x0000c000 -#define WLAN_DBG_UART_BASE_ADDRESS 0x0000d000 -#define WLAN_UMBOX_BASE_ADDRESS 0x0000e000 -#define WLAN_SI_BASE_ADDRESS 0x00010000 -#define WLAN_GPIO_BASE_ADDRESS 0x00014000 -#define WLAN_MBOX_BASE_ADDRESS 0x00018000 -#define WLAN_ANALOG_INTF_BASE_ADDRESS 0x0001c000 -#define WLAN_MAC_BASE_ADDRESS 0x00020000 -#define WLAN_RDMA_BASE_ADDRESS 0x00030100 -#define EFUSE_BASE_ADDRESS 0x00031000 - -#endif /* _APB_ATHR_WLAN_MAP_REG_H_ */ diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_map.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_map.h deleted file mode 100644 index 0068ca3..0000000 --- a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/apb_map.h +++ /dev/null @@ -1,40 +0,0 @@ -// ------------------------------------------------------------------ -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -// ------------------------------------------------------------------ -//=================================================================== -// Author(s): ="Atheros" -//=================================================================== - - -#include "apb_athr_wlan_map.h" - -#ifndef BT_HEADERS - -#define RTC_BASE_ADDRESS WLAN_RTC_BASE_ADDRESS -#define VMC_BASE_ADDRESS WLAN_VMC_BASE_ADDRESS -#define UART_BASE_ADDRESS WLAN_UART_BASE_ADDRESS -#define DBG_UART_BASE_ADDRESS WLAN_DBG_UART_BASE_ADDRESS -#define UMBOX_BASE_ADDRESS WLAN_UMBOX_BASE_ADDRESS -#define SI_BASE_ADDRESS WLAN_SI_BASE_ADDRESS -#define GPIO_BASE_ADDRESS WLAN_GPIO_BASE_ADDRESS -#define MBOX_BASE_ADDRESS WLAN_MBOX_BASE_ADDRESS -#define ANALOG_INTF_BASE_ADDRESS WLAN_ANALOG_INTF_BASE_ADDRESS -#define MAC_BASE_ADDRESS WLAN_MAC_BASE_ADDRESS -#define RDMA_BASE_ADDRESS WLAN_RDMA_BASE_ADDRESS - -#endif diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_host_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_host_reg.h deleted file mode 100644 index 109f24e..0000000 --- a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_host_reg.h +++ /dev/null @@ -1,24 +0,0 @@ -// ------------------------------------------------------------------ -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -// ------------------------------------------------------------------ -//=================================================================== -// Author(s): ="Atheros" -//=================================================================== - - -#include "mbox_wlan_host_reg.h" diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_reg.h deleted file mode 100644 index 72fa483..0000000 --- a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_reg.h +++ /dev/null @@ -1,552 +0,0 @@ -// ------------------------------------------------------------------ -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -// ------------------------------------------------------------------ -//=================================================================== -// Author(s): ="Atheros" -//=================================================================== - - -#include "mbox_wlan_reg.h" - -#ifndef BT_HEADERS - -#define MBOX_FIFO_ADDRESS WLAN_MBOX_FIFO_ADDRESS -#define MBOX_FIFO_OFFSET WLAN_MBOX_FIFO_OFFSET -#define MBOX_FIFO_DATA_MSB WLAN_MBOX_FIFO_DATA_MSB -#define MBOX_FIFO_DATA_LSB WLAN_MBOX_FIFO_DATA_LSB -#define MBOX_FIFO_DATA_MASK WLAN_MBOX_FIFO_DATA_MASK -#define MBOX_FIFO_DATA_GET(x) WLAN_MBOX_FIFO_DATA_GET(x) -#define MBOX_FIFO_DATA_SET(x) WLAN_MBOX_FIFO_DATA_SET(x) -#define MBOX_FIFO_STATUS_ADDRESS WLAN_MBOX_FIFO_STATUS_ADDRESS -#define MBOX_FIFO_STATUS_OFFSET WLAN_MBOX_FIFO_STATUS_OFFSET -#define MBOX_FIFO_STATUS_EMPTY_MSB WLAN_MBOX_FIFO_STATUS_EMPTY_MSB -#define MBOX_FIFO_STATUS_EMPTY_LSB WLAN_MBOX_FIFO_STATUS_EMPTY_LSB -#define MBOX_FIFO_STATUS_EMPTY_MASK WLAN_MBOX_FIFO_STATUS_EMPTY_MASK -#define MBOX_FIFO_STATUS_EMPTY_GET(x) WLAN_MBOX_FIFO_STATUS_EMPTY_GET(x) -#define MBOX_FIFO_STATUS_EMPTY_SET(x) WLAN_MBOX_FIFO_STATUS_EMPTY_SET(x) -#define MBOX_FIFO_STATUS_FULL_MSB WLAN_MBOX_FIFO_STATUS_FULL_MSB -#define MBOX_FIFO_STATUS_FULL_LSB WLAN_MBOX_FIFO_STATUS_FULL_LSB -#define MBOX_FIFO_STATUS_FULL_MASK WLAN_MBOX_FIFO_STATUS_FULL_MASK -#define MBOX_FIFO_STATUS_FULL_GET(x) WLAN_MBOX_FIFO_STATUS_FULL_GET(x) -#define MBOX_FIFO_STATUS_FULL_SET(x) WLAN_MBOX_FIFO_STATUS_FULL_SET(x) -#define MBOX_DMA_POLICY_ADDRESS WLAN_MBOX_DMA_POLICY_ADDRESS -#define MBOX_DMA_POLICY_OFFSET WLAN_MBOX_DMA_POLICY_OFFSET -#define MBOX_DMA_POLICY_TX_QUANTUM_MSB WLAN_MBOX_DMA_POLICY_TX_QUANTUM_MSB -#define MBOX_DMA_POLICY_TX_QUANTUM_LSB WLAN_MBOX_DMA_POLICY_TX_QUANTUM_LSB -#define MBOX_DMA_POLICY_TX_QUANTUM_MASK WLAN_MBOX_DMA_POLICY_TX_QUANTUM_MASK -#define MBOX_DMA_POLICY_TX_QUANTUM_GET(x) WLAN_MBOX_DMA_POLICY_TX_QUANTUM_GET(x) -#define MBOX_DMA_POLICY_TX_QUANTUM_SET(x) WLAN_MBOX_DMA_POLICY_TX_QUANTUM_SET(x) -#define MBOX_DMA_POLICY_TX_ORDER_MSB WLAN_MBOX_DMA_POLICY_TX_ORDER_MSB -#define MBOX_DMA_POLICY_TX_ORDER_LSB WLAN_MBOX_DMA_POLICY_TX_ORDER_LSB -#define MBOX_DMA_POLICY_TX_ORDER_MASK WLAN_MBOX_DMA_POLICY_TX_ORDER_MASK -#define MBOX_DMA_POLICY_TX_ORDER_GET(x) WLAN_MBOX_DMA_POLICY_TX_ORDER_GET(x) -#define MBOX_DMA_POLICY_TX_ORDER_SET(x) WLAN_MBOX_DMA_POLICY_TX_ORDER_SET(x) -#define MBOX_DMA_POLICY_RX_QUANTUM_MSB WLAN_MBOX_DMA_POLICY_RX_QUANTUM_MSB -#define MBOX_DMA_POLICY_RX_QUANTUM_LSB WLAN_MBOX_DMA_POLICY_RX_QUANTUM_LSB -#define MBOX_DMA_POLICY_RX_QUANTUM_MASK WLAN_MBOX_DMA_POLICY_RX_QUANTUM_MASK -#define MBOX_DMA_POLICY_RX_QUANTUM_GET(x) WLAN_MBOX_DMA_POLICY_RX_QUANTUM_GET(x) -#define MBOX_DMA_POLICY_RX_QUANTUM_SET(x) WLAN_MBOX_DMA_POLICY_RX_QUANTUM_SET(x) -#define MBOX_DMA_POLICY_RX_ORDER_MSB WLAN_MBOX_DMA_POLICY_RX_ORDER_MSB -#define MBOX_DMA_POLICY_RX_ORDER_LSB WLAN_MBOX_DMA_POLICY_RX_ORDER_LSB -#define MBOX_DMA_POLICY_RX_ORDER_MASK WLAN_MBOX_DMA_POLICY_RX_ORDER_MASK -#define MBOX_DMA_POLICY_RX_ORDER_GET(x) WLAN_MBOX_DMA_POLICY_RX_ORDER_GET(x) -#define MBOX_DMA_POLICY_RX_ORDER_SET(x) WLAN_MBOX_DMA_POLICY_RX_ORDER_SET(x) -#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS -#define MBOX0_DMA_RX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_OFFSET -#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB -#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB -#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK -#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) -#define MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) -#define MBOX0_DMA_RX_CONTROL_ADDRESS WLAN_MBOX0_DMA_RX_CONTROL_ADDRESS -#define MBOX0_DMA_RX_CONTROL_OFFSET WLAN_MBOX0_DMA_RX_CONTROL_OFFSET -#define MBOX0_DMA_RX_CONTROL_RESUME_MSB WLAN_MBOX0_DMA_RX_CONTROL_RESUME_MSB -#define MBOX0_DMA_RX_CONTROL_RESUME_LSB WLAN_MBOX0_DMA_RX_CONTROL_RESUME_LSB -#define MBOX0_DMA_RX_CONTROL_RESUME_MASK WLAN_MBOX0_DMA_RX_CONTROL_RESUME_MASK -#define MBOX0_DMA_RX_CONTROL_RESUME_GET(x) WLAN_MBOX0_DMA_RX_CONTROL_RESUME_GET(x) -#define MBOX0_DMA_RX_CONTROL_RESUME_SET(x) WLAN_MBOX0_DMA_RX_CONTROL_RESUME_SET(x) -#define MBOX0_DMA_RX_CONTROL_START_MSB WLAN_MBOX0_DMA_RX_CONTROL_START_MSB -#define MBOX0_DMA_RX_CONTROL_START_LSB WLAN_MBOX0_DMA_RX_CONTROL_START_LSB -#define MBOX0_DMA_RX_CONTROL_START_MASK WLAN_MBOX0_DMA_RX_CONTROL_START_MASK -#define MBOX0_DMA_RX_CONTROL_START_GET(x) WLAN_MBOX0_DMA_RX_CONTROL_START_GET(x) -#define MBOX0_DMA_RX_CONTROL_START_SET(x) WLAN_MBOX0_DMA_RX_CONTROL_START_SET(x) -#define MBOX0_DMA_RX_CONTROL_STOP_MSB WLAN_MBOX0_DMA_RX_CONTROL_STOP_MSB -#define MBOX0_DMA_RX_CONTROL_STOP_LSB WLAN_MBOX0_DMA_RX_CONTROL_STOP_LSB -#define MBOX0_DMA_RX_CONTROL_STOP_MASK WLAN_MBOX0_DMA_RX_CONTROL_STOP_MASK -#define MBOX0_DMA_RX_CONTROL_STOP_GET(x) WLAN_MBOX0_DMA_RX_CONTROL_STOP_GET(x) -#define MBOX0_DMA_RX_CONTROL_STOP_SET(x) WLAN_MBOX0_DMA_RX_CONTROL_STOP_SET(x) -#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS -#define MBOX0_DMA_TX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_OFFSET -#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB -#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB -#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK -#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) -#define MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) -#define MBOX0_DMA_TX_CONTROL_ADDRESS WLAN_MBOX0_DMA_TX_CONTROL_ADDRESS -#define MBOX0_DMA_TX_CONTROL_OFFSET WLAN_MBOX0_DMA_TX_CONTROL_OFFSET -#define MBOX0_DMA_TX_CONTROL_RESUME_MSB WLAN_MBOX0_DMA_TX_CONTROL_RESUME_MSB -#define MBOX0_DMA_TX_CONTROL_RESUME_LSB WLAN_MBOX0_DMA_TX_CONTROL_RESUME_LSB -#define MBOX0_DMA_TX_CONTROL_RESUME_MASK WLAN_MBOX0_DMA_TX_CONTROL_RESUME_MASK -#define MBOX0_DMA_TX_CONTROL_RESUME_GET(x) WLAN_MBOX0_DMA_TX_CONTROL_RESUME_GET(x) -#define MBOX0_DMA_TX_CONTROL_RESUME_SET(x) WLAN_MBOX0_DMA_TX_CONTROL_RESUME_SET(x) -#define MBOX0_DMA_TX_CONTROL_START_MSB WLAN_MBOX0_DMA_TX_CONTROL_START_MSB -#define MBOX0_DMA_TX_CONTROL_START_LSB WLAN_MBOX0_DMA_TX_CONTROL_START_LSB -#define MBOX0_DMA_TX_CONTROL_START_MASK WLAN_MBOX0_DMA_TX_CONTROL_START_MASK -#define MBOX0_DMA_TX_CONTROL_START_GET(x) WLAN_MBOX0_DMA_TX_CONTROL_START_GET(x) -#define MBOX0_DMA_TX_CONTROL_START_SET(x) WLAN_MBOX0_DMA_TX_CONTROL_START_SET(x) -#define MBOX0_DMA_TX_CONTROL_STOP_MSB WLAN_MBOX0_DMA_TX_CONTROL_STOP_MSB -#define MBOX0_DMA_TX_CONTROL_STOP_LSB WLAN_MBOX0_DMA_TX_CONTROL_STOP_LSB -#define MBOX0_DMA_TX_CONTROL_STOP_MASK WLAN_MBOX0_DMA_TX_CONTROL_STOP_MASK -#define MBOX0_DMA_TX_CONTROL_STOP_GET(x) WLAN_MBOX0_DMA_TX_CONTROL_STOP_GET(x) -#define MBOX0_DMA_TX_CONTROL_STOP_SET(x) WLAN_MBOX0_DMA_TX_CONTROL_STOP_SET(x) -#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS -#define MBOX1_DMA_RX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_OFFSET -#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB -#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB -#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK -#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) -#define MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) -#define MBOX1_DMA_RX_CONTROL_ADDRESS WLAN_MBOX1_DMA_RX_CONTROL_ADDRESS -#define MBOX1_DMA_RX_CONTROL_OFFSET WLAN_MBOX1_DMA_RX_CONTROL_OFFSET -#define MBOX1_DMA_RX_CONTROL_RESUME_MSB WLAN_MBOX1_DMA_RX_CONTROL_RESUME_MSB -#define MBOX1_DMA_RX_CONTROL_RESUME_LSB WLAN_MBOX1_DMA_RX_CONTROL_RESUME_LSB -#define MBOX1_DMA_RX_CONTROL_RESUME_MASK WLAN_MBOX1_DMA_RX_CONTROL_RESUME_MASK -#define MBOX1_DMA_RX_CONTROL_RESUME_GET(x) WLAN_MBOX1_DMA_RX_CONTROL_RESUME_GET(x) -#define MBOX1_DMA_RX_CONTROL_RESUME_SET(x) WLAN_MBOX1_DMA_RX_CONTROL_RESUME_SET(x) -#define MBOX1_DMA_RX_CONTROL_START_MSB WLAN_MBOX1_DMA_RX_CONTROL_START_MSB -#define MBOX1_DMA_RX_CONTROL_START_LSB WLAN_MBOX1_DMA_RX_CONTROL_START_LSB -#define MBOX1_DMA_RX_CONTROL_START_MASK WLAN_MBOX1_DMA_RX_CONTROL_START_MASK -#define MBOX1_DMA_RX_CONTROL_START_GET(x) WLAN_MBOX1_DMA_RX_CONTROL_START_GET(x) -#define MBOX1_DMA_RX_CONTROL_START_SET(x) WLAN_MBOX1_DMA_RX_CONTROL_START_SET(x) -#define MBOX1_DMA_RX_CONTROL_STOP_MSB WLAN_MBOX1_DMA_RX_CONTROL_STOP_MSB -#define MBOX1_DMA_RX_CONTROL_STOP_LSB WLAN_MBOX1_DMA_RX_CONTROL_STOP_LSB -#define MBOX1_DMA_RX_CONTROL_STOP_MASK WLAN_MBOX1_DMA_RX_CONTROL_STOP_MASK -#define MBOX1_DMA_RX_CONTROL_STOP_GET(x) WLAN_MBOX1_DMA_RX_CONTROL_STOP_GET(x) -#define MBOX1_DMA_RX_CONTROL_STOP_SET(x) WLAN_MBOX1_DMA_RX_CONTROL_STOP_SET(x) -#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS -#define MBOX1_DMA_TX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_OFFSET -#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB -#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB -#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK -#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) -#define MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) -#define MBOX1_DMA_TX_CONTROL_ADDRESS WLAN_MBOX1_DMA_TX_CONTROL_ADDRESS -#define MBOX1_DMA_TX_CONTROL_OFFSET WLAN_MBOX1_DMA_TX_CONTROL_OFFSET -#define MBOX1_DMA_TX_CONTROL_RESUME_MSB WLAN_MBOX1_DMA_TX_CONTROL_RESUME_MSB -#define MBOX1_DMA_TX_CONTROL_RESUME_LSB WLAN_MBOX1_DMA_TX_CONTROL_RESUME_LSB -#define MBOX1_DMA_TX_CONTROL_RESUME_MASK WLAN_MBOX1_DMA_TX_CONTROL_RESUME_MASK -#define MBOX1_DMA_TX_CONTROL_RESUME_GET(x) WLAN_MBOX1_DMA_TX_CONTROL_RESUME_GET(x) -#define MBOX1_DMA_TX_CONTROL_RESUME_SET(x) WLAN_MBOX1_DMA_TX_CONTROL_RESUME_SET(x) -#define MBOX1_DMA_TX_CONTROL_START_MSB WLAN_MBOX1_DMA_TX_CONTROL_START_MSB -#define MBOX1_DMA_TX_CONTROL_START_LSB WLAN_MBOX1_DMA_TX_CONTROL_START_LSB -#define MBOX1_DMA_TX_CONTROL_START_MASK WLAN_MBOX1_DMA_TX_CONTROL_START_MASK -#define MBOX1_DMA_TX_CONTROL_START_GET(x) WLAN_MBOX1_DMA_TX_CONTROL_START_GET(x) -#define MBOX1_DMA_TX_CONTROL_START_SET(x) WLAN_MBOX1_DMA_TX_CONTROL_START_SET(x) -#define MBOX1_DMA_TX_CONTROL_STOP_MSB WLAN_MBOX1_DMA_TX_CONTROL_STOP_MSB -#define MBOX1_DMA_TX_CONTROL_STOP_LSB WLAN_MBOX1_DMA_TX_CONTROL_STOP_LSB -#define MBOX1_DMA_TX_CONTROL_STOP_MASK WLAN_MBOX1_DMA_TX_CONTROL_STOP_MASK -#define MBOX1_DMA_TX_CONTROL_STOP_GET(x) WLAN_MBOX1_DMA_TX_CONTROL_STOP_GET(x) -#define MBOX1_DMA_TX_CONTROL_STOP_SET(x) WLAN_MBOX1_DMA_TX_CONTROL_STOP_SET(x) -#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS -#define MBOX2_DMA_RX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_OFFSET -#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB -#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB -#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK -#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) -#define MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) -#define MBOX2_DMA_RX_CONTROL_ADDRESS WLAN_MBOX2_DMA_RX_CONTROL_ADDRESS -#define MBOX2_DMA_RX_CONTROL_OFFSET WLAN_MBOX2_DMA_RX_CONTROL_OFFSET -#define MBOX2_DMA_RX_CONTROL_RESUME_MSB WLAN_MBOX2_DMA_RX_CONTROL_RESUME_MSB -#define MBOX2_DMA_RX_CONTROL_RESUME_LSB WLAN_MBOX2_DMA_RX_CONTROL_RESUME_LSB -#define MBOX2_DMA_RX_CONTROL_RESUME_MASK WLAN_MBOX2_DMA_RX_CONTROL_RESUME_MASK -#define MBOX2_DMA_RX_CONTROL_RESUME_GET(x) WLAN_MBOX2_DMA_RX_CONTROL_RESUME_GET(x) -#define MBOX2_DMA_RX_CONTROL_RESUME_SET(x) WLAN_MBOX2_DMA_RX_CONTROL_RESUME_SET(x) -#define MBOX2_DMA_RX_CONTROL_START_MSB WLAN_MBOX2_DMA_RX_CONTROL_START_MSB -#define MBOX2_DMA_RX_CONTROL_START_LSB WLAN_MBOX2_DMA_RX_CONTROL_START_LSB -#define MBOX2_DMA_RX_CONTROL_START_MASK WLAN_MBOX2_DMA_RX_CONTROL_START_MASK -#define MBOX2_DMA_RX_CONTROL_START_GET(x) WLAN_MBOX2_DMA_RX_CONTROL_START_GET(x) -#define MBOX2_DMA_RX_CONTROL_START_SET(x) WLAN_MBOX2_DMA_RX_CONTROL_START_SET(x) -#define MBOX2_DMA_RX_CONTROL_STOP_MSB WLAN_MBOX2_DMA_RX_CONTROL_STOP_MSB -#define MBOX2_DMA_RX_CONTROL_STOP_LSB WLAN_MBOX2_DMA_RX_CONTROL_STOP_LSB -#define MBOX2_DMA_RX_CONTROL_STOP_MASK WLAN_MBOX2_DMA_RX_CONTROL_STOP_MASK -#define MBOX2_DMA_RX_CONTROL_STOP_GET(x) WLAN_MBOX2_DMA_RX_CONTROL_STOP_GET(x) -#define MBOX2_DMA_RX_CONTROL_STOP_SET(x) WLAN_MBOX2_DMA_RX_CONTROL_STOP_SET(x) -#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS -#define MBOX2_DMA_TX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_OFFSET -#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB -#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB -#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK -#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) -#define MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) -#define MBOX2_DMA_TX_CONTROL_ADDRESS WLAN_MBOX2_DMA_TX_CONTROL_ADDRESS -#define MBOX2_DMA_TX_CONTROL_OFFSET WLAN_MBOX2_DMA_TX_CONTROL_OFFSET -#define MBOX2_DMA_TX_CONTROL_RESUME_MSB WLAN_MBOX2_DMA_TX_CONTROL_RESUME_MSB -#define MBOX2_DMA_TX_CONTROL_RESUME_LSB WLAN_MBOX2_DMA_TX_CONTROL_RESUME_LSB -#define MBOX2_DMA_TX_CONTROL_RESUME_MASK WLAN_MBOX2_DMA_TX_CONTROL_RESUME_MASK -#define MBOX2_DMA_TX_CONTROL_RESUME_GET(x) WLAN_MBOX2_DMA_TX_CONTROL_RESUME_GET(x) -#define MBOX2_DMA_TX_CONTROL_RESUME_SET(x) WLAN_MBOX2_DMA_TX_CONTROL_RESUME_SET(x) -#define MBOX2_DMA_TX_CONTROL_START_MSB WLAN_MBOX2_DMA_TX_CONTROL_START_MSB -#define MBOX2_DMA_TX_CONTROL_START_LSB WLAN_MBOX2_DMA_TX_CONTROL_START_LSB -#define MBOX2_DMA_TX_CONTROL_START_MASK WLAN_MBOX2_DMA_TX_CONTROL_START_MASK -#define MBOX2_DMA_TX_CONTROL_START_GET(x) WLAN_MBOX2_DMA_TX_CONTROL_START_GET(x) -#define MBOX2_DMA_TX_CONTROL_START_SET(x) WLAN_MBOX2_DMA_TX_CONTROL_START_SET(x) -#define MBOX2_DMA_TX_CONTROL_STOP_MSB WLAN_MBOX2_DMA_TX_CONTROL_STOP_MSB -#define MBOX2_DMA_TX_CONTROL_STOP_LSB WLAN_MBOX2_DMA_TX_CONTROL_STOP_LSB -#define MBOX2_DMA_TX_CONTROL_STOP_MASK WLAN_MBOX2_DMA_TX_CONTROL_STOP_MASK -#define MBOX2_DMA_TX_CONTROL_STOP_GET(x) WLAN_MBOX2_DMA_TX_CONTROL_STOP_GET(x) -#define MBOX2_DMA_TX_CONTROL_STOP_SET(x) WLAN_MBOX2_DMA_TX_CONTROL_STOP_SET(x) -#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS -#define MBOX3_DMA_RX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_OFFSET -#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB -#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB -#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK -#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) -#define MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) -#define MBOX3_DMA_RX_CONTROL_ADDRESS WLAN_MBOX3_DMA_RX_CONTROL_ADDRESS -#define MBOX3_DMA_RX_CONTROL_OFFSET WLAN_MBOX3_DMA_RX_CONTROL_OFFSET -#define MBOX3_DMA_RX_CONTROL_RESUME_MSB WLAN_MBOX3_DMA_RX_CONTROL_RESUME_MSB -#define MBOX3_DMA_RX_CONTROL_RESUME_LSB WLAN_MBOX3_DMA_RX_CONTROL_RESUME_LSB -#define MBOX3_DMA_RX_CONTROL_RESUME_MASK WLAN_MBOX3_DMA_RX_CONTROL_RESUME_MASK -#define MBOX3_DMA_RX_CONTROL_RESUME_GET(x) WLAN_MBOX3_DMA_RX_CONTROL_RESUME_GET(x) -#define MBOX3_DMA_RX_CONTROL_RESUME_SET(x) WLAN_MBOX3_DMA_RX_CONTROL_RESUME_SET(x) -#define MBOX3_DMA_RX_CONTROL_START_MSB WLAN_MBOX3_DMA_RX_CONTROL_START_MSB -#define MBOX3_DMA_RX_CONTROL_START_LSB WLAN_MBOX3_DMA_RX_CONTROL_START_LSB -#define MBOX3_DMA_RX_CONTROL_START_MASK WLAN_MBOX3_DMA_RX_CONTROL_START_MASK -#define MBOX3_DMA_RX_CONTROL_START_GET(x) WLAN_MBOX3_DMA_RX_CONTROL_START_GET(x) -#define MBOX3_DMA_RX_CONTROL_START_SET(x) WLAN_MBOX3_DMA_RX_CONTROL_START_SET(x) -#define MBOX3_DMA_RX_CONTROL_STOP_MSB WLAN_MBOX3_DMA_RX_CONTROL_STOP_MSB -#define MBOX3_DMA_RX_CONTROL_STOP_LSB WLAN_MBOX3_DMA_RX_CONTROL_STOP_LSB -#define MBOX3_DMA_RX_CONTROL_STOP_MASK WLAN_MBOX3_DMA_RX_CONTROL_STOP_MASK -#define MBOX3_DMA_RX_CONTROL_STOP_GET(x) WLAN_MBOX3_DMA_RX_CONTROL_STOP_GET(x) -#define MBOX3_DMA_RX_CONTROL_STOP_SET(x) WLAN_MBOX3_DMA_RX_CONTROL_STOP_SET(x) -#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS -#define MBOX3_DMA_TX_DESCRIPTOR_BASE_OFFSET WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_OFFSET -#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB -#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB -#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK -#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) -#define MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) -#define MBOX3_DMA_TX_CONTROL_ADDRESS WLAN_MBOX3_DMA_TX_CONTROL_ADDRESS -#define MBOX3_DMA_TX_CONTROL_OFFSET WLAN_MBOX3_DMA_TX_CONTROL_OFFSET -#define MBOX3_DMA_TX_CONTROL_RESUME_MSB WLAN_MBOX3_DMA_TX_CONTROL_RESUME_MSB -#define MBOX3_DMA_TX_CONTROL_RESUME_LSB WLAN_MBOX3_DMA_TX_CONTROL_RESUME_LSB -#define MBOX3_DMA_TX_CONTROL_RESUME_MASK WLAN_MBOX3_DMA_TX_CONTROL_RESUME_MASK -#define MBOX3_DMA_TX_CONTROL_RESUME_GET(x) WLAN_MBOX3_DMA_TX_CONTROL_RESUME_GET(x) -#define MBOX3_DMA_TX_CONTROL_RESUME_SET(x) WLAN_MBOX3_DMA_TX_CONTROL_RESUME_SET(x) -#define MBOX3_DMA_TX_CONTROL_START_MSB WLAN_MBOX3_DMA_TX_CONTROL_START_MSB -#define MBOX3_DMA_TX_CONTROL_START_LSB WLAN_MBOX3_DMA_TX_CONTROL_START_LSB -#define MBOX3_DMA_TX_CONTROL_START_MASK WLAN_MBOX3_DMA_TX_CONTROL_START_MASK -#define MBOX3_DMA_TX_CONTROL_START_GET(x) WLAN_MBOX3_DMA_TX_CONTROL_START_GET(x) -#define MBOX3_DMA_TX_CONTROL_START_SET(x) WLAN_MBOX3_DMA_TX_CONTROL_START_SET(x) -#define MBOX3_DMA_TX_CONTROL_STOP_MSB WLAN_MBOX3_DMA_TX_CONTROL_STOP_MSB -#define MBOX3_DMA_TX_CONTROL_STOP_LSB WLAN_MBOX3_DMA_TX_CONTROL_STOP_LSB -#define MBOX3_DMA_TX_CONTROL_STOP_MASK WLAN_MBOX3_DMA_TX_CONTROL_STOP_MASK -#define MBOX3_DMA_TX_CONTROL_STOP_GET(x) WLAN_MBOX3_DMA_TX_CONTROL_STOP_GET(x) -#define MBOX3_DMA_TX_CONTROL_STOP_SET(x) WLAN_MBOX3_DMA_TX_CONTROL_STOP_SET(x) -#define MBOX_INT_STATUS_ADDRESS WLAN_MBOX_INT_STATUS_ADDRESS -#define MBOX_INT_STATUS_OFFSET WLAN_MBOX_INT_STATUS_OFFSET -#define MBOX_INT_STATUS_RX_DMA_COMPLETE_MSB WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_MSB -#define MBOX_INT_STATUS_RX_DMA_COMPLETE_LSB WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_LSB -#define MBOX_INT_STATUS_RX_DMA_COMPLETE_MASK WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_MASK -#define MBOX_INT_STATUS_RX_DMA_COMPLETE_GET(x) WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_GET(x) -#define MBOX_INT_STATUS_RX_DMA_COMPLETE_SET(x) WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_SET(x) -#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MSB WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MSB -#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB -#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK -#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_GET(x) WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_GET(x) -#define MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_SET(x) WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_SET(x) -#define MBOX_INT_STATUS_TX_DMA_COMPLETE_MSB WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_MSB -#define MBOX_INT_STATUS_TX_DMA_COMPLETE_LSB WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_LSB -#define MBOX_INT_STATUS_TX_DMA_COMPLETE_MASK WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_MASK -#define MBOX_INT_STATUS_TX_DMA_COMPLETE_GET(x) WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_GET(x) -#define MBOX_INT_STATUS_TX_DMA_COMPLETE_SET(x) WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_SET(x) -#define MBOX_INT_STATUS_TX_OVERFLOW_MSB WLAN_MBOX_INT_STATUS_TX_OVERFLOW_MSB -#define MBOX_INT_STATUS_TX_OVERFLOW_LSB WLAN_MBOX_INT_STATUS_TX_OVERFLOW_LSB -#define MBOX_INT_STATUS_TX_OVERFLOW_MASK WLAN_MBOX_INT_STATUS_TX_OVERFLOW_MASK -#define MBOX_INT_STATUS_TX_OVERFLOW_GET(x) WLAN_MBOX_INT_STATUS_TX_OVERFLOW_GET(x) -#define MBOX_INT_STATUS_TX_OVERFLOW_SET(x) WLAN_MBOX_INT_STATUS_TX_OVERFLOW_SET(x) -#define MBOX_INT_STATUS_RX_UNDERFLOW_MSB WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_MSB -#define MBOX_INT_STATUS_RX_UNDERFLOW_LSB WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_LSB -#define MBOX_INT_STATUS_RX_UNDERFLOW_MASK WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_MASK -#define MBOX_INT_STATUS_RX_UNDERFLOW_GET(x) WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_GET(x) -#define MBOX_INT_STATUS_RX_UNDERFLOW_SET(x) WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_SET(x) -#define MBOX_INT_STATUS_TX_NOT_EMPTY_MSB WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_MSB -#define MBOX_INT_STATUS_TX_NOT_EMPTY_LSB WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_LSB -#define MBOX_INT_STATUS_TX_NOT_EMPTY_MASK WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_MASK -#define MBOX_INT_STATUS_TX_NOT_EMPTY_GET(x) WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_GET(x) -#define MBOX_INT_STATUS_TX_NOT_EMPTY_SET(x) WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_SET(x) -#define MBOX_INT_STATUS_RX_NOT_FULL_MSB WLAN_MBOX_INT_STATUS_RX_NOT_FULL_MSB -#define MBOX_INT_STATUS_RX_NOT_FULL_LSB WLAN_MBOX_INT_STATUS_RX_NOT_FULL_LSB -#define MBOX_INT_STATUS_RX_NOT_FULL_MASK WLAN_MBOX_INT_STATUS_RX_NOT_FULL_MASK -#define MBOX_INT_STATUS_RX_NOT_FULL_GET(x) WLAN_MBOX_INT_STATUS_RX_NOT_FULL_GET(x) -#define MBOX_INT_STATUS_RX_NOT_FULL_SET(x) WLAN_MBOX_INT_STATUS_RX_NOT_FULL_SET(x) -#define MBOX_INT_STATUS_HOST_MSB WLAN_MBOX_INT_STATUS_HOST_MSB -#define MBOX_INT_STATUS_HOST_LSB WLAN_MBOX_INT_STATUS_HOST_LSB -#define MBOX_INT_STATUS_HOST_MASK WLAN_MBOX_INT_STATUS_HOST_MASK -#define MBOX_INT_STATUS_HOST_GET(x) WLAN_MBOX_INT_STATUS_HOST_GET(x) -#define MBOX_INT_STATUS_HOST_SET(x) WLAN_MBOX_INT_STATUS_HOST_SET(x) -#define MBOX_INT_ENABLE_ADDRESS WLAN_MBOX_INT_ENABLE_ADDRESS -#define MBOX_INT_ENABLE_OFFSET WLAN_MBOX_INT_ENABLE_OFFSET -#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_MSB WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_MSB -#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB -#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK -#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_GET(x) WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_GET(x) -#define MBOX_INT_ENABLE_RX_DMA_COMPLETE_SET(x) WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_SET(x) -#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MSB WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MSB -#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB -#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK -#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_GET(x) WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_GET(x) -#define MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_SET(x) WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_SET(x) -#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_MSB WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_MSB -#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB -#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK -#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_GET(x) WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_GET(x) -#define MBOX_INT_ENABLE_TX_DMA_COMPLETE_SET(x) WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_SET(x) -#define MBOX_INT_ENABLE_TX_OVERFLOW_MSB WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_MSB -#define MBOX_INT_ENABLE_TX_OVERFLOW_LSB WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_LSB -#define MBOX_INT_ENABLE_TX_OVERFLOW_MASK WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_MASK -#define MBOX_INT_ENABLE_TX_OVERFLOW_GET(x) WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_GET(x) -#define MBOX_INT_ENABLE_TX_OVERFLOW_SET(x) WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_SET(x) -#define MBOX_INT_ENABLE_RX_UNDERFLOW_MSB WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_MSB -#define MBOX_INT_ENABLE_RX_UNDERFLOW_LSB WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_LSB -#define MBOX_INT_ENABLE_RX_UNDERFLOW_MASK WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_MASK -#define MBOX_INT_ENABLE_RX_UNDERFLOW_GET(x) WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_GET(x) -#define MBOX_INT_ENABLE_RX_UNDERFLOW_SET(x) WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_SET(x) -#define MBOX_INT_ENABLE_TX_NOT_EMPTY_MSB WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_MSB -#define MBOX_INT_ENABLE_TX_NOT_EMPTY_LSB WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_LSB -#define MBOX_INT_ENABLE_TX_NOT_EMPTY_MASK WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_MASK -#define MBOX_INT_ENABLE_TX_NOT_EMPTY_GET(x) WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_GET(x) -#define MBOX_INT_ENABLE_TX_NOT_EMPTY_SET(x) WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_SET(x) -#define MBOX_INT_ENABLE_RX_NOT_FULL_MSB WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_MSB -#define MBOX_INT_ENABLE_RX_NOT_FULL_LSB WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_LSB -#define MBOX_INT_ENABLE_RX_NOT_FULL_MASK WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_MASK -#define MBOX_INT_ENABLE_RX_NOT_FULL_GET(x) WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_GET(x) -#define MBOX_INT_ENABLE_RX_NOT_FULL_SET(x) WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_SET(x) -#define MBOX_INT_ENABLE_HOST_MSB WLAN_MBOX_INT_ENABLE_HOST_MSB -#define MBOX_INT_ENABLE_HOST_LSB WLAN_MBOX_INT_ENABLE_HOST_LSB -#define MBOX_INT_ENABLE_HOST_MASK WLAN_MBOX_INT_ENABLE_HOST_MASK -#define MBOX_INT_ENABLE_HOST_GET(x) WLAN_MBOX_INT_ENABLE_HOST_GET(x) -#define MBOX_INT_ENABLE_HOST_SET(x) WLAN_MBOX_INT_ENABLE_HOST_SET(x) -#define INT_HOST_ADDRESS WLAN_INT_HOST_ADDRESS -#define INT_HOST_OFFSET WLAN_INT_HOST_OFFSET -#define INT_HOST_VECTOR_MSB WLAN_INT_HOST_VECTOR_MSB -#define INT_HOST_VECTOR_LSB WLAN_INT_HOST_VECTOR_LSB -#define INT_HOST_VECTOR_MASK WLAN_INT_HOST_VECTOR_MASK -#define INT_HOST_VECTOR_GET(x) WLAN_INT_HOST_VECTOR_GET(x) -#define INT_HOST_VECTOR_SET(x) WLAN_INT_HOST_VECTOR_SET(x) -#define LOCAL_COUNT_ADDRESS WLAN_LOCAL_COUNT_ADDRESS -#define LOCAL_COUNT_OFFSET WLAN_LOCAL_COUNT_OFFSET -#define LOCAL_COUNT_VALUE_MSB WLAN_LOCAL_COUNT_VALUE_MSB -#define LOCAL_COUNT_VALUE_LSB WLAN_LOCAL_COUNT_VALUE_LSB -#define LOCAL_COUNT_VALUE_MASK WLAN_LOCAL_COUNT_VALUE_MASK -#define LOCAL_COUNT_VALUE_GET(x) WLAN_LOCAL_COUNT_VALUE_GET(x) -#define LOCAL_COUNT_VALUE_SET(x) WLAN_LOCAL_COUNT_VALUE_SET(x) -#define COUNT_INC_ADDRESS WLAN_COUNT_INC_ADDRESS -#define COUNT_INC_OFFSET WLAN_COUNT_INC_OFFSET -#define COUNT_INC_VALUE_MSB WLAN_COUNT_INC_VALUE_MSB -#define COUNT_INC_VALUE_LSB WLAN_COUNT_INC_VALUE_LSB -#define COUNT_INC_VALUE_MASK WLAN_COUNT_INC_VALUE_MASK -#define COUNT_INC_VALUE_GET(x) WLAN_COUNT_INC_VALUE_GET(x) -#define COUNT_INC_VALUE_SET(x) WLAN_COUNT_INC_VALUE_SET(x) -#define LOCAL_SCRATCH_ADDRESS WLAN_LOCAL_SCRATCH_ADDRESS -#define LOCAL_SCRATCH_OFFSET WLAN_LOCAL_SCRATCH_OFFSET -#define LOCAL_SCRATCH_VALUE_MSB WLAN_LOCAL_SCRATCH_VALUE_MSB -#define LOCAL_SCRATCH_VALUE_LSB WLAN_LOCAL_SCRATCH_VALUE_LSB -#define LOCAL_SCRATCH_VALUE_MASK WLAN_LOCAL_SCRATCH_VALUE_MASK -#define LOCAL_SCRATCH_VALUE_GET(x) WLAN_LOCAL_SCRATCH_VALUE_GET(x) -#define LOCAL_SCRATCH_VALUE_SET(x) WLAN_LOCAL_SCRATCH_VALUE_SET(x) -#define USE_LOCAL_BUS_ADDRESS WLAN_USE_LOCAL_BUS_ADDRESS -#define USE_LOCAL_BUS_OFFSET WLAN_USE_LOCAL_BUS_OFFSET -#define USE_LOCAL_BUS_PIN_INIT_MSB WLAN_USE_LOCAL_BUS_PIN_INIT_MSB -#define USE_LOCAL_BUS_PIN_INIT_LSB WLAN_USE_LOCAL_BUS_PIN_INIT_LSB -#define USE_LOCAL_BUS_PIN_INIT_MASK WLAN_USE_LOCAL_BUS_PIN_INIT_MASK -#define USE_LOCAL_BUS_PIN_INIT_GET(x) WLAN_USE_LOCAL_BUS_PIN_INIT_GET(x) -#define USE_LOCAL_BUS_PIN_INIT_SET(x) WLAN_USE_LOCAL_BUS_PIN_INIT_SET(x) -#define SDIO_CONFIG_ADDRESS WLAN_SDIO_CONFIG_ADDRESS -#define SDIO_CONFIG_OFFSET WLAN_SDIO_CONFIG_OFFSET -#define SDIO_CONFIG_CCCR_IOR1_MSB WLAN_SDIO_CONFIG_CCCR_IOR1_MSB -#define SDIO_CONFIG_CCCR_IOR1_LSB WLAN_SDIO_CONFIG_CCCR_IOR1_LSB -#define SDIO_CONFIG_CCCR_IOR1_MASK WLAN_SDIO_CONFIG_CCCR_IOR1_MASK -#define SDIO_CONFIG_CCCR_IOR1_GET(x) WLAN_SDIO_CONFIG_CCCR_IOR1_GET(x) -#define SDIO_CONFIG_CCCR_IOR1_SET(x) WLAN_SDIO_CONFIG_CCCR_IOR1_SET(x) -#define MBOX_DEBUG_ADDRESS WLAN_MBOX_DEBUG_ADDRESS -#define MBOX_DEBUG_OFFSET WLAN_MBOX_DEBUG_OFFSET -#define MBOX_DEBUG_SEL_MSB WLAN_MBOX_DEBUG_SEL_MSB -#define MBOX_DEBUG_SEL_LSB WLAN_MBOX_DEBUG_SEL_LSB -#define MBOX_DEBUG_SEL_MASK WLAN_MBOX_DEBUG_SEL_MASK -#define MBOX_DEBUG_SEL_GET(x) WLAN_MBOX_DEBUG_SEL_GET(x) -#define MBOX_DEBUG_SEL_SET(x) WLAN_MBOX_DEBUG_SEL_SET(x) -#define MBOX_FIFO_RESET_ADDRESS WLAN_MBOX_FIFO_RESET_ADDRESS -#define MBOX_FIFO_RESET_OFFSET WLAN_MBOX_FIFO_RESET_OFFSET -#define MBOX_FIFO_RESET_INIT_MSB WLAN_MBOX_FIFO_RESET_INIT_MSB -#define MBOX_FIFO_RESET_INIT_LSB WLAN_MBOX_FIFO_RESET_INIT_LSB -#define MBOX_FIFO_RESET_INIT_MASK WLAN_MBOX_FIFO_RESET_INIT_MASK -#define MBOX_FIFO_RESET_INIT_GET(x) WLAN_MBOX_FIFO_RESET_INIT_GET(x) -#define MBOX_FIFO_RESET_INIT_SET(x) WLAN_MBOX_FIFO_RESET_INIT_SET(x) -#define MBOX_TXFIFO_POP_ADDRESS WLAN_MBOX_TXFIFO_POP_ADDRESS -#define MBOX_TXFIFO_POP_OFFSET WLAN_MBOX_TXFIFO_POP_OFFSET -#define MBOX_TXFIFO_POP_DATA_MSB WLAN_MBOX_TXFIFO_POP_DATA_MSB -#define MBOX_TXFIFO_POP_DATA_LSB WLAN_MBOX_TXFIFO_POP_DATA_LSB -#define MBOX_TXFIFO_POP_DATA_MASK WLAN_MBOX_TXFIFO_POP_DATA_MASK -#define MBOX_TXFIFO_POP_DATA_GET(x) WLAN_MBOX_TXFIFO_POP_DATA_GET(x) -#define MBOX_TXFIFO_POP_DATA_SET(x) WLAN_MBOX_TXFIFO_POP_DATA_SET(x) -#define MBOX_RXFIFO_POP_ADDRESS WLAN_MBOX_RXFIFO_POP_ADDRESS -#define MBOX_RXFIFO_POP_OFFSET WLAN_MBOX_RXFIFO_POP_OFFSET -#define MBOX_RXFIFO_POP_DATA_MSB WLAN_MBOX_RXFIFO_POP_DATA_MSB -#define MBOX_RXFIFO_POP_DATA_LSB WLAN_MBOX_RXFIFO_POP_DATA_LSB -#define MBOX_RXFIFO_POP_DATA_MASK WLAN_MBOX_RXFIFO_POP_DATA_MASK -#define MBOX_RXFIFO_POP_DATA_GET(x) WLAN_MBOX_RXFIFO_POP_DATA_GET(x) -#define MBOX_RXFIFO_POP_DATA_SET(x) WLAN_MBOX_RXFIFO_POP_DATA_SET(x) -#define SDIO_DEBUG_ADDRESS WLAN_SDIO_DEBUG_ADDRESS -#define SDIO_DEBUG_OFFSET WLAN_SDIO_DEBUG_OFFSET -#define SDIO_DEBUG_SEL_MSB WLAN_SDIO_DEBUG_SEL_MSB -#define SDIO_DEBUG_SEL_LSB WLAN_SDIO_DEBUG_SEL_LSB -#define SDIO_DEBUG_SEL_MASK WLAN_SDIO_DEBUG_SEL_MASK -#define SDIO_DEBUG_SEL_GET(x) WLAN_SDIO_DEBUG_SEL_GET(x) -#define SDIO_DEBUG_SEL_SET(x) WLAN_SDIO_DEBUG_SEL_SET(x) -#define GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS -#define GMBOX0_DMA_RX_DESCRIPTOR_BASE_OFFSET WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_OFFSET -#define GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB -#define GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB -#define GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK -#define GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) -#define GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) -#define GMBOX0_DMA_RX_CONTROL_ADDRESS WLAN_GMBOX0_DMA_RX_CONTROL_ADDRESS -#define GMBOX0_DMA_RX_CONTROL_OFFSET WLAN_GMBOX0_DMA_RX_CONTROL_OFFSET -#define GMBOX0_DMA_RX_CONTROL_RESUME_MSB WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_MSB -#define GMBOX0_DMA_RX_CONTROL_RESUME_LSB WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_LSB -#define GMBOX0_DMA_RX_CONTROL_RESUME_MASK WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_MASK -#define GMBOX0_DMA_RX_CONTROL_RESUME_GET(x) WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_GET(x) -#define GMBOX0_DMA_RX_CONTROL_RESUME_SET(x) WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_SET(x) -#define GMBOX0_DMA_RX_CONTROL_START_MSB WLAN_GMBOX0_DMA_RX_CONTROL_START_MSB -#define GMBOX0_DMA_RX_CONTROL_START_LSB WLAN_GMBOX0_DMA_RX_CONTROL_START_LSB -#define GMBOX0_DMA_RX_CONTROL_START_MASK WLAN_GMBOX0_DMA_RX_CONTROL_START_MASK -#define GMBOX0_DMA_RX_CONTROL_START_GET(x) WLAN_GMBOX0_DMA_RX_CONTROL_START_GET(x) -#define GMBOX0_DMA_RX_CONTROL_START_SET(x) WLAN_GMBOX0_DMA_RX_CONTROL_START_SET(x) -#define GMBOX0_DMA_RX_CONTROL_STOP_MSB WLAN_GMBOX0_DMA_RX_CONTROL_STOP_MSB -#define GMBOX0_DMA_RX_CONTROL_STOP_LSB WLAN_GMBOX0_DMA_RX_CONTROL_STOP_LSB -#define GMBOX0_DMA_RX_CONTROL_STOP_MASK WLAN_GMBOX0_DMA_RX_CONTROL_STOP_MASK -#define GMBOX0_DMA_RX_CONTROL_STOP_GET(x) WLAN_GMBOX0_DMA_RX_CONTROL_STOP_GET(x) -#define GMBOX0_DMA_RX_CONTROL_STOP_SET(x) WLAN_GMBOX0_DMA_RX_CONTROL_STOP_SET(x) -#define GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS -#define GMBOX0_DMA_TX_DESCRIPTOR_BASE_OFFSET WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_OFFSET -#define GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB -#define GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB -#define GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK -#define GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) -#define GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) -#define GMBOX0_DMA_TX_CONTROL_ADDRESS WLAN_GMBOX0_DMA_TX_CONTROL_ADDRESS -#define GMBOX0_DMA_TX_CONTROL_OFFSET WLAN_GMBOX0_DMA_TX_CONTROL_OFFSET -#define GMBOX0_DMA_TX_CONTROL_RESUME_MSB WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_MSB -#define GMBOX0_DMA_TX_CONTROL_RESUME_LSB WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_LSB -#define GMBOX0_DMA_TX_CONTROL_RESUME_MASK WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_MASK -#define GMBOX0_DMA_TX_CONTROL_RESUME_GET(x) WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_GET(x) -#define GMBOX0_DMA_TX_CONTROL_RESUME_SET(x) WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_SET(x) -#define GMBOX0_DMA_TX_CONTROL_START_MSB WLAN_GMBOX0_DMA_TX_CONTROL_START_MSB -#define GMBOX0_DMA_TX_CONTROL_START_LSB WLAN_GMBOX0_DMA_TX_CONTROL_START_LSB -#define GMBOX0_DMA_TX_CONTROL_START_MASK WLAN_GMBOX0_DMA_TX_CONTROL_START_MASK -#define GMBOX0_DMA_TX_CONTROL_START_GET(x) WLAN_GMBOX0_DMA_TX_CONTROL_START_GET(x) -#define GMBOX0_DMA_TX_CONTROL_START_SET(x) WLAN_GMBOX0_DMA_TX_CONTROL_START_SET(x) -#define GMBOX0_DMA_TX_CONTROL_STOP_MSB WLAN_GMBOX0_DMA_TX_CONTROL_STOP_MSB -#define GMBOX0_DMA_TX_CONTROL_STOP_LSB WLAN_GMBOX0_DMA_TX_CONTROL_STOP_LSB -#define GMBOX0_DMA_TX_CONTROL_STOP_MASK WLAN_GMBOX0_DMA_TX_CONTROL_STOP_MASK -#define GMBOX0_DMA_TX_CONTROL_STOP_GET(x) WLAN_GMBOX0_DMA_TX_CONTROL_STOP_GET(x) -#define GMBOX0_DMA_TX_CONTROL_STOP_SET(x) WLAN_GMBOX0_DMA_TX_CONTROL_STOP_SET(x) -#define GMBOX_INT_STATUS_ADDRESS WLAN_GMBOX_INT_STATUS_ADDRESS -#define GMBOX_INT_STATUS_OFFSET WLAN_GMBOX_INT_STATUS_OFFSET -#define GMBOX_INT_STATUS_TX_OVERFLOW_MSB WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_MSB -#define GMBOX_INT_STATUS_TX_OVERFLOW_LSB WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_LSB -#define GMBOX_INT_STATUS_TX_OVERFLOW_MASK WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_MASK -#define GMBOX_INT_STATUS_TX_OVERFLOW_GET(x) WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_GET(x) -#define GMBOX_INT_STATUS_TX_OVERFLOW_SET(x) WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_SET(x) -#define GMBOX_INT_STATUS_RX_UNDERFLOW_MSB WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_MSB -#define GMBOX_INT_STATUS_RX_UNDERFLOW_LSB WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_LSB -#define GMBOX_INT_STATUS_RX_UNDERFLOW_MASK WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_MASK -#define GMBOX_INT_STATUS_RX_UNDERFLOW_GET(x) WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_GET(x) -#define GMBOX_INT_STATUS_RX_UNDERFLOW_SET(x) WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_SET(x) -#define GMBOX_INT_STATUS_RX_DMA_COMPLETE_MSB WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_MSB -#define GMBOX_INT_STATUS_RX_DMA_COMPLETE_LSB WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_LSB -#define GMBOX_INT_STATUS_RX_DMA_COMPLETE_MASK WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_MASK -#define GMBOX_INT_STATUS_RX_DMA_COMPLETE_GET(x) WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_GET(x) -#define GMBOX_INT_STATUS_RX_DMA_COMPLETE_SET(x) WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_SET(x) -#define GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MSB WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MSB -#define GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB -#define GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK -#define GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_GET(x) WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_GET(x) -#define GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_SET(x) WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_SET(x) -#define GMBOX_INT_STATUS_TX_DMA_COMPLETE_MSB WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_MSB -#define GMBOX_INT_STATUS_TX_DMA_COMPLETE_LSB WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_LSB -#define GMBOX_INT_STATUS_TX_DMA_COMPLETE_MASK WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_MASK -#define GMBOX_INT_STATUS_TX_DMA_COMPLETE_GET(x) WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_GET(x) -#define GMBOX_INT_STATUS_TX_DMA_COMPLETE_SET(x) WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_SET(x) -#define GMBOX_INT_STATUS_TX_NOT_EMPTY_MSB WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_MSB -#define GMBOX_INT_STATUS_TX_NOT_EMPTY_LSB WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_LSB -#define GMBOX_INT_STATUS_TX_NOT_EMPTY_MASK WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_MASK -#define GMBOX_INT_STATUS_TX_NOT_EMPTY_GET(x) WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_GET(x) -#define GMBOX_INT_STATUS_TX_NOT_EMPTY_SET(x) WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_SET(x) -#define GMBOX_INT_STATUS_RX_NOT_FULL_MSB WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_MSB -#define GMBOX_INT_STATUS_RX_NOT_FULL_LSB WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_LSB -#define GMBOX_INT_STATUS_RX_NOT_FULL_MASK WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_MASK -#define GMBOX_INT_STATUS_RX_NOT_FULL_GET(x) WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_GET(x) -#define GMBOX_INT_STATUS_RX_NOT_FULL_SET(x) WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_SET(x) -#define GMBOX_INT_ENABLE_ADDRESS WLAN_GMBOX_INT_ENABLE_ADDRESS -#define GMBOX_INT_ENABLE_OFFSET WLAN_GMBOX_INT_ENABLE_OFFSET -#define GMBOX_INT_ENABLE_TX_OVERFLOW_MSB WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_MSB -#define GMBOX_INT_ENABLE_TX_OVERFLOW_LSB WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_LSB -#define GMBOX_INT_ENABLE_TX_OVERFLOW_MASK WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_MASK -#define GMBOX_INT_ENABLE_TX_OVERFLOW_GET(x) WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_GET(x) -#define GMBOX_INT_ENABLE_TX_OVERFLOW_SET(x) WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_SET(x) -#define GMBOX_INT_ENABLE_RX_UNDERFLOW_MSB WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_MSB -#define GMBOX_INT_ENABLE_RX_UNDERFLOW_LSB WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_LSB -#define GMBOX_INT_ENABLE_RX_UNDERFLOW_MASK WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_MASK -#define GMBOX_INT_ENABLE_RX_UNDERFLOW_GET(x) WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_GET(x) -#define GMBOX_INT_ENABLE_RX_UNDERFLOW_SET(x) WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_SET(x) -#define GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MSB WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MSB -#define GMBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB -#define GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK -#define GMBOX_INT_ENABLE_RX_DMA_COMPLETE_GET(x) WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_GET(x) -#define GMBOX_INT_ENABLE_RX_DMA_COMPLETE_SET(x) WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_SET(x) -#define GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MSB WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MSB -#define GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB -#define GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK -#define GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_GET(x) WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_GET(x) -#define GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_SET(x) WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_SET(x) -#define GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MSB WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MSB -#define GMBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB -#define GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK -#define GMBOX_INT_ENABLE_TX_DMA_COMPLETE_GET(x) WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_GET(x) -#define GMBOX_INT_ENABLE_TX_DMA_COMPLETE_SET(x) WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_SET(x) -#define GMBOX_INT_ENABLE_TX_NOT_EMPTY_MSB WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_MSB -#define GMBOX_INT_ENABLE_TX_NOT_EMPTY_LSB WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_LSB -#define GMBOX_INT_ENABLE_TX_NOT_EMPTY_MASK WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_MASK -#define GMBOX_INT_ENABLE_TX_NOT_EMPTY_GET(x) WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_GET(x) -#define GMBOX_INT_ENABLE_TX_NOT_EMPTY_SET(x) WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_SET(x) -#define GMBOX_INT_ENABLE_RX_NOT_FULL_MSB WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_MSB -#define GMBOX_INT_ENABLE_RX_NOT_FULL_LSB WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_LSB -#define GMBOX_INT_ENABLE_RX_NOT_FULL_MASK WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_MASK -#define GMBOX_INT_ENABLE_RX_NOT_FULL_GET(x) WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_GET(x) -#define GMBOX_INT_ENABLE_RX_NOT_FULL_SET(x) WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_SET(x) -#define HOST_IF_WINDOW_ADDRESS WLAN_HOST_IF_WINDOW_ADDRESS -#define HOST_IF_WINDOW_OFFSET WLAN_HOST_IF_WINDOW_OFFSET -#define HOST_IF_WINDOW_DATA_MSB WLAN_HOST_IF_WINDOW_DATA_MSB -#define HOST_IF_WINDOW_DATA_LSB WLAN_HOST_IF_WINDOW_DATA_LSB -#define HOST_IF_WINDOW_DATA_MASK WLAN_HOST_IF_WINDOW_DATA_MASK -#define HOST_IF_WINDOW_DATA_GET(x) WLAN_HOST_IF_WINDOW_DATA_GET(x) -#define HOST_IF_WINDOW_DATA_SET(x) WLAN_HOST_IF_WINDOW_DATA_SET(x) - -#endif diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_host_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_host_reg.h deleted file mode 100644 index 038d0d0..0000000 --- a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_host_reg.h +++ /dev/null @@ -1,471 +0,0 @@ -// ------------------------------------------------------------------ -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -// ------------------------------------------------------------------ -//=================================================================== -// Author(s): ="Atheros" -//=================================================================== - - -#ifndef _MBOX_WLAN_HOST_REG_REG_H_ -#define _MBOX_WLAN_HOST_REG_REG_H_ - -#define HOST_INT_STATUS_ADDRESS 0x00000400 -#define HOST_INT_STATUS_OFFSET 0x00000400 -#define HOST_INT_STATUS_ERROR_MSB 7 -#define HOST_INT_STATUS_ERROR_LSB 7 -#define HOST_INT_STATUS_ERROR_MASK 0x00000080 -#define HOST_INT_STATUS_ERROR_GET(x) (((x) & HOST_INT_STATUS_ERROR_MASK) >> HOST_INT_STATUS_ERROR_LSB) -#define HOST_INT_STATUS_ERROR_SET(x) (((x) << HOST_INT_STATUS_ERROR_LSB) & HOST_INT_STATUS_ERROR_MASK) -#define HOST_INT_STATUS_CPU_MSB 6 -#define HOST_INT_STATUS_CPU_LSB 6 -#define HOST_INT_STATUS_CPU_MASK 0x00000040 -#define HOST_INT_STATUS_CPU_GET(x) (((x) & HOST_INT_STATUS_CPU_MASK) >> HOST_INT_STATUS_CPU_LSB) -#define HOST_INT_STATUS_CPU_SET(x) (((x) << HOST_INT_STATUS_CPU_LSB) & HOST_INT_STATUS_CPU_MASK) -#define HOST_INT_STATUS_INT_MSB 5 -#define HOST_INT_STATUS_INT_LSB 5 -#define HOST_INT_STATUS_INT_MASK 0x00000020 -#define HOST_INT_STATUS_INT_GET(x) (((x) & HOST_INT_STATUS_INT_MASK) >> HOST_INT_STATUS_INT_LSB) -#define HOST_INT_STATUS_INT_SET(x) (((x) << HOST_INT_STATUS_INT_LSB) & HOST_INT_STATUS_INT_MASK) -#define HOST_INT_STATUS_COUNTER_MSB 4 -#define HOST_INT_STATUS_COUNTER_LSB 4 -#define HOST_INT_STATUS_COUNTER_MASK 0x00000010 -#define HOST_INT_STATUS_COUNTER_GET(x) (((x) & HOST_INT_STATUS_COUNTER_MASK) >> HOST_INT_STATUS_COUNTER_LSB) -#define HOST_INT_STATUS_COUNTER_SET(x) (((x) << HOST_INT_STATUS_COUNTER_LSB) & HOST_INT_STATUS_COUNTER_MASK) -#define HOST_INT_STATUS_MBOX_DATA_MSB 3 -#define HOST_INT_STATUS_MBOX_DATA_LSB 0 -#define HOST_INT_STATUS_MBOX_DATA_MASK 0x0000000f -#define HOST_INT_STATUS_MBOX_DATA_GET(x) (((x) & HOST_INT_STATUS_MBOX_DATA_MASK) >> HOST_INT_STATUS_MBOX_DATA_LSB) -#define HOST_INT_STATUS_MBOX_DATA_SET(x) (((x) << HOST_INT_STATUS_MBOX_DATA_LSB) & HOST_INT_STATUS_MBOX_DATA_MASK) - -#define CPU_INT_STATUS_ADDRESS 0x00000401 -#define CPU_INT_STATUS_OFFSET 0x00000401 -#define CPU_INT_STATUS_BIT_MSB 7 -#define CPU_INT_STATUS_BIT_LSB 0 -#define CPU_INT_STATUS_BIT_MASK 0x000000ff -#define CPU_INT_STATUS_BIT_GET(x) (((x) & CPU_INT_STATUS_BIT_MASK) >> CPU_INT_STATUS_BIT_LSB) -#define CPU_INT_STATUS_BIT_SET(x) (((x) << CPU_INT_STATUS_BIT_LSB) & CPU_INT_STATUS_BIT_MASK) - -#define ERROR_INT_STATUS_ADDRESS 0x00000402 -#define ERROR_INT_STATUS_OFFSET 0x00000402 -#define ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_MSB 6 -#define ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_LSB 6 -#define ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_MASK 0x00000040 -#define ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_GET(x) (((x) & ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_MASK) >> ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_LSB) -#define ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_SET(x) (((x) << ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_LSB) & ERROR_INT_STATUS_UART_HCI_FRAMER_SYNC_ERROR_MASK) -#define ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_MSB 5 -#define ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_LSB 5 -#define ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_MASK 0x00000020 -#define ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_GET(x) (((x) & ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_MASK) >> ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_LSB) -#define ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_SET(x) (((x) << ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_LSB) & ERROR_INT_STATUS_UART_HCI_FRAMER_OVERFLOW_MASK) -#define ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_MSB 4 -#define ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_LSB 4 -#define ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_MASK 0x00000010 -#define ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_GET(x) (((x) & ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_MASK) >> ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_LSB) -#define ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_SET(x) (((x) << ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_LSB) & ERROR_INT_STATUS_UART_HCI_FRAMER_UNDERFLOW_MASK) -#define ERROR_INT_STATUS_SPI_MSB 3 -#define ERROR_INT_STATUS_SPI_LSB 3 -#define ERROR_INT_STATUS_SPI_MASK 0x00000008 -#define ERROR_INT_STATUS_SPI_GET(x) (((x) & ERROR_INT_STATUS_SPI_MASK) >> ERROR_INT_STATUS_SPI_LSB) -#define ERROR_INT_STATUS_SPI_SET(x) (((x) << ERROR_INT_STATUS_SPI_LSB) & ERROR_INT_STATUS_SPI_MASK) -#define ERROR_INT_STATUS_WAKEUP_MSB 2 -#define ERROR_INT_STATUS_WAKEUP_LSB 2 -#define ERROR_INT_STATUS_WAKEUP_MASK 0x00000004 -#define ERROR_INT_STATUS_WAKEUP_GET(x) (((x) & ERROR_INT_STATUS_WAKEUP_MASK) >> ERROR_INT_STATUS_WAKEUP_LSB) -#define ERROR_INT_STATUS_WAKEUP_SET(x) (((x) << ERROR_INT_STATUS_WAKEUP_LSB) & ERROR_INT_STATUS_WAKEUP_MASK) -#define ERROR_INT_STATUS_RX_UNDERFLOW_MSB 1 -#define ERROR_INT_STATUS_RX_UNDERFLOW_LSB 1 -#define ERROR_INT_STATUS_RX_UNDERFLOW_MASK 0x00000002 -#define ERROR_INT_STATUS_RX_UNDERFLOW_GET(x) (((x) & ERROR_INT_STATUS_RX_UNDERFLOW_MASK) >> ERROR_INT_STATUS_RX_UNDERFLOW_LSB) -#define ERROR_INT_STATUS_RX_UNDERFLOW_SET(x) (((x) << ERROR_INT_STATUS_RX_UNDERFLOW_LSB) & ERROR_INT_STATUS_RX_UNDERFLOW_MASK) -#define ERROR_INT_STATUS_TX_OVERFLOW_MSB 0 -#define ERROR_INT_STATUS_TX_OVERFLOW_LSB 0 -#define ERROR_INT_STATUS_TX_OVERFLOW_MASK 0x00000001 -#define ERROR_INT_STATUS_TX_OVERFLOW_GET(x) (((x) & ERROR_INT_STATUS_TX_OVERFLOW_MASK) >> ERROR_INT_STATUS_TX_OVERFLOW_LSB) -#define ERROR_INT_STATUS_TX_OVERFLOW_SET(x) (((x) << ERROR_INT_STATUS_TX_OVERFLOW_LSB) & ERROR_INT_STATUS_TX_OVERFLOW_MASK) - -#define COUNTER_INT_STATUS_ADDRESS 0x00000403 -#define COUNTER_INT_STATUS_OFFSET 0x00000403 -#define COUNTER_INT_STATUS_COUNTER_MSB 7 -#define COUNTER_INT_STATUS_COUNTER_LSB 0 -#define COUNTER_INT_STATUS_COUNTER_MASK 0x000000ff -#define COUNTER_INT_STATUS_COUNTER_GET(x) (((x) & COUNTER_INT_STATUS_COUNTER_MASK) >> COUNTER_INT_STATUS_COUNTER_LSB) -#define COUNTER_INT_STATUS_COUNTER_SET(x) (((x) << COUNTER_INT_STATUS_COUNTER_LSB) & COUNTER_INT_STATUS_COUNTER_MASK) - -#define MBOX_FRAME_ADDRESS 0x00000404 -#define MBOX_FRAME_OFFSET 0x00000404 -#define MBOX_FRAME_RX_EOM_MSB 7 -#define MBOX_FRAME_RX_EOM_LSB 4 -#define MBOX_FRAME_RX_EOM_MASK 0x000000f0 -#define MBOX_FRAME_RX_EOM_GET(x) (((x) & MBOX_FRAME_RX_EOM_MASK) >> MBOX_FRAME_RX_EOM_LSB) -#define MBOX_FRAME_RX_EOM_SET(x) (((x) << MBOX_FRAME_RX_EOM_LSB) & MBOX_FRAME_RX_EOM_MASK) -#define MBOX_FRAME_RX_SOM_MSB 3 -#define MBOX_FRAME_RX_SOM_LSB 0 -#define MBOX_FRAME_RX_SOM_MASK 0x0000000f -#define MBOX_FRAME_RX_SOM_GET(x) (((x) & MBOX_FRAME_RX_SOM_MASK) >> MBOX_FRAME_RX_SOM_LSB) -#define MBOX_FRAME_RX_SOM_SET(x) (((x) << MBOX_FRAME_RX_SOM_LSB) & MBOX_FRAME_RX_SOM_MASK) - -#define RX_LOOKAHEAD_VALID_ADDRESS 0x00000405 -#define RX_LOOKAHEAD_VALID_OFFSET 0x00000405 -#define RX_LOOKAHEAD_VALID_MBOX_MSB 3 -#define RX_LOOKAHEAD_VALID_MBOX_LSB 0 -#define RX_LOOKAHEAD_VALID_MBOX_MASK 0x0000000f -#define RX_LOOKAHEAD_VALID_MBOX_GET(x) (((x) & RX_LOOKAHEAD_VALID_MBOX_MASK) >> RX_LOOKAHEAD_VALID_MBOX_LSB) -#define RX_LOOKAHEAD_VALID_MBOX_SET(x) (((x) << RX_LOOKAHEAD_VALID_MBOX_LSB) & RX_LOOKAHEAD_VALID_MBOX_MASK) - -#define HOST_INT_STATUS2_ADDRESS 0x00000406 -#define HOST_INT_STATUS2_OFFSET 0x00000406 -#define HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_MSB 2 -#define HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_LSB 2 -#define HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_MASK 0x00000004 -#define HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_GET(x) (((x) & HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_MASK) >> HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_LSB) -#define HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_SET(x) (((x) << HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_LSB) & HOST_INT_STATUS2_GMBOX_RX_UNDERFLOW_MASK) -#define HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_MSB 1 -#define HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_LSB 1 -#define HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_MASK 0x00000002 -#define HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_GET(x) (((x) & HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_MASK) >> HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_LSB) -#define HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_SET(x) (((x) << HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_LSB) & HOST_INT_STATUS2_GMBOX_TX_OVERFLOW_MASK) -#define HOST_INT_STATUS2_GMBOX_DATA_MSB 0 -#define HOST_INT_STATUS2_GMBOX_DATA_LSB 0 -#define HOST_INT_STATUS2_GMBOX_DATA_MASK 0x00000001 -#define HOST_INT_STATUS2_GMBOX_DATA_GET(x) (((x) & HOST_INT_STATUS2_GMBOX_DATA_MASK) >> HOST_INT_STATUS2_GMBOX_DATA_LSB) -#define HOST_INT_STATUS2_GMBOX_DATA_SET(x) (((x) << HOST_INT_STATUS2_GMBOX_DATA_LSB) & HOST_INT_STATUS2_GMBOX_DATA_MASK) - -#define GMBOX_RX_AVAIL_ADDRESS 0x00000407 -#define GMBOX_RX_AVAIL_OFFSET 0x00000407 -#define GMBOX_RX_AVAIL_BYTE_MSB 6 -#define GMBOX_RX_AVAIL_BYTE_LSB 0 -#define GMBOX_RX_AVAIL_BYTE_MASK 0x0000007f -#define GMBOX_RX_AVAIL_BYTE_GET(x) (((x) & GMBOX_RX_AVAIL_BYTE_MASK) >> GMBOX_RX_AVAIL_BYTE_LSB) -#define GMBOX_RX_AVAIL_BYTE_SET(x) (((x) << GMBOX_RX_AVAIL_BYTE_LSB) & GMBOX_RX_AVAIL_BYTE_MASK) - -#define RX_LOOKAHEAD0_ADDRESS 0x00000408 -#define RX_LOOKAHEAD0_OFFSET 0x00000408 -#define RX_LOOKAHEAD0_DATA_MSB 7 -#define RX_LOOKAHEAD0_DATA_LSB 0 -#define RX_LOOKAHEAD0_DATA_MASK 0x000000ff -#define RX_LOOKAHEAD0_DATA_GET(x) (((x) & RX_LOOKAHEAD0_DATA_MASK) >> RX_LOOKAHEAD0_DATA_LSB) -#define RX_LOOKAHEAD0_DATA_SET(x) (((x) << RX_LOOKAHEAD0_DATA_LSB) & RX_LOOKAHEAD0_DATA_MASK) - -#define RX_LOOKAHEAD1_ADDRESS 0x0000040c -#define RX_LOOKAHEAD1_OFFSET 0x0000040c -#define RX_LOOKAHEAD1_DATA_MSB 7 -#define RX_LOOKAHEAD1_DATA_LSB 0 -#define RX_LOOKAHEAD1_DATA_MASK 0x000000ff -#define RX_LOOKAHEAD1_DATA_GET(x) (((x) & RX_LOOKAHEAD1_DATA_MASK) >> RX_LOOKAHEAD1_DATA_LSB) -#define RX_LOOKAHEAD1_DATA_SET(x) (((x) << RX_LOOKAHEAD1_DATA_LSB) & RX_LOOKAHEAD1_DATA_MASK) - -#define RX_LOOKAHEAD2_ADDRESS 0x00000410 -#define RX_LOOKAHEAD2_OFFSET 0x00000410 -#define RX_LOOKAHEAD2_DATA_MSB 7 -#define RX_LOOKAHEAD2_DATA_LSB 0 -#define RX_LOOKAHEAD2_DATA_MASK 0x000000ff -#define RX_LOOKAHEAD2_DATA_GET(x) (((x) & RX_LOOKAHEAD2_DATA_MASK) >> RX_LOOKAHEAD2_DATA_LSB) -#define RX_LOOKAHEAD2_DATA_SET(x) (((x) << RX_LOOKAHEAD2_DATA_LSB) & RX_LOOKAHEAD2_DATA_MASK) - -#define RX_LOOKAHEAD3_ADDRESS 0x00000414 -#define RX_LOOKAHEAD3_OFFSET 0x00000414 -#define RX_LOOKAHEAD3_DATA_MSB 7 -#define RX_LOOKAHEAD3_DATA_LSB 0 -#define RX_LOOKAHEAD3_DATA_MASK 0x000000ff -#define RX_LOOKAHEAD3_DATA_GET(x) (((x) & RX_LOOKAHEAD3_DATA_MASK) >> RX_LOOKAHEAD3_DATA_LSB) -#define RX_LOOKAHEAD3_DATA_SET(x) (((x) << RX_LOOKAHEAD3_DATA_LSB) & RX_LOOKAHEAD3_DATA_MASK) - -#define INT_STATUS_ENABLE_ADDRESS 0x00000418 -#define INT_STATUS_ENABLE_OFFSET 0x00000418 -#define INT_STATUS_ENABLE_ERROR_MSB 7 -#define INT_STATUS_ENABLE_ERROR_LSB 7 -#define INT_STATUS_ENABLE_ERROR_MASK 0x00000080 -#define INT_STATUS_ENABLE_ERROR_GET(x) (((x) & INT_STATUS_ENABLE_ERROR_MASK) >> INT_STATUS_ENABLE_ERROR_LSB) -#define INT_STATUS_ENABLE_ERROR_SET(x) (((x) << INT_STATUS_ENABLE_ERROR_LSB) & INT_STATUS_ENABLE_ERROR_MASK) -#define INT_STATUS_ENABLE_CPU_MSB 6 -#define INT_STATUS_ENABLE_CPU_LSB 6 -#define INT_STATUS_ENABLE_CPU_MASK 0x00000040 -#define INT_STATUS_ENABLE_CPU_GET(x) (((x) & INT_STATUS_ENABLE_CPU_MASK) >> INT_STATUS_ENABLE_CPU_LSB) -#define INT_STATUS_ENABLE_CPU_SET(x) (((x) << INT_STATUS_ENABLE_CPU_LSB) & INT_STATUS_ENABLE_CPU_MASK) -#define INT_STATUS_ENABLE_INT_MSB 5 -#define INT_STATUS_ENABLE_INT_LSB 5 -#define INT_STATUS_ENABLE_INT_MASK 0x00000020 -#define INT_STATUS_ENABLE_INT_GET(x) (((x) & INT_STATUS_ENABLE_INT_MASK) >> INT_STATUS_ENABLE_INT_LSB) -#define INT_STATUS_ENABLE_INT_SET(x) (((x) << INT_STATUS_ENABLE_INT_LSB) & INT_STATUS_ENABLE_INT_MASK) -#define INT_STATUS_ENABLE_COUNTER_MSB 4 -#define INT_STATUS_ENABLE_COUNTER_LSB 4 -#define INT_STATUS_ENABLE_COUNTER_MASK 0x00000010 -#define INT_STATUS_ENABLE_COUNTER_GET(x) (((x) & INT_STATUS_ENABLE_COUNTER_MASK) >> INT_STATUS_ENABLE_COUNTER_LSB) -#define INT_STATUS_ENABLE_COUNTER_SET(x) (((x) << INT_STATUS_ENABLE_COUNTER_LSB) & INT_STATUS_ENABLE_COUNTER_MASK) -#define INT_STATUS_ENABLE_MBOX_DATA_MSB 3 -#define INT_STATUS_ENABLE_MBOX_DATA_LSB 0 -#define INT_STATUS_ENABLE_MBOX_DATA_MASK 0x0000000f -#define INT_STATUS_ENABLE_MBOX_DATA_GET(x) (((x) & INT_STATUS_ENABLE_MBOX_DATA_MASK) >> INT_STATUS_ENABLE_MBOX_DATA_LSB) -#define INT_STATUS_ENABLE_MBOX_DATA_SET(x) (((x) << INT_STATUS_ENABLE_MBOX_DATA_LSB) & INT_STATUS_ENABLE_MBOX_DATA_MASK) - -#define CPU_INT_STATUS_ENABLE_ADDRESS 0x00000419 -#define CPU_INT_STATUS_ENABLE_OFFSET 0x00000419 -#define CPU_INT_STATUS_ENABLE_BIT_MSB 7 -#define CPU_INT_STATUS_ENABLE_BIT_LSB 0 -#define CPU_INT_STATUS_ENABLE_BIT_MASK 0x000000ff -#define CPU_INT_STATUS_ENABLE_BIT_GET(x) (((x) & CPU_INT_STATUS_ENABLE_BIT_MASK) >> CPU_INT_STATUS_ENABLE_BIT_LSB) -#define CPU_INT_STATUS_ENABLE_BIT_SET(x) (((x) << CPU_INT_STATUS_ENABLE_BIT_LSB) & CPU_INT_STATUS_ENABLE_BIT_MASK) - -#define ERROR_STATUS_ENABLE_ADDRESS 0x0000041a -#define ERROR_STATUS_ENABLE_OFFSET 0x0000041a -#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_MSB 6 -#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_LSB 6 -#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_MASK 0x00000040 -#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_GET(x) (((x) & ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_MASK) >> ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_LSB) -#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_SET(x) (((x) << ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_LSB) & ERROR_STATUS_ENABLE_UART_HCI_FRAMER_SYNC_ERROR_MASK) -#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_MSB 5 -#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_LSB 5 -#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_MASK 0x00000020 -#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_GET(x) (((x) & ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_MASK) >> ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_LSB) -#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_SET(x) (((x) << ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_LSB) & ERROR_STATUS_ENABLE_UART_HCI_FRAMER_OVERFLOW_MASK) -#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_MSB 4 -#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_LSB 4 -#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_MASK 0x00000010 -#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_GET(x) (((x) & ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_MASK) >> ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_LSB) -#define ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_SET(x) (((x) << ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_LSB) & ERROR_STATUS_ENABLE_UART_HCI_FRAMER_UNDERFLOW_MASK) -#define ERROR_STATUS_ENABLE_WAKEUP_MSB 2 -#define ERROR_STATUS_ENABLE_WAKEUP_LSB 2 -#define ERROR_STATUS_ENABLE_WAKEUP_MASK 0x00000004 -#define ERROR_STATUS_ENABLE_WAKEUP_GET(x) (((x) & ERROR_STATUS_ENABLE_WAKEUP_MASK) >> ERROR_STATUS_ENABLE_WAKEUP_LSB) -#define ERROR_STATUS_ENABLE_WAKEUP_SET(x) (((x) << ERROR_STATUS_ENABLE_WAKEUP_LSB) & ERROR_STATUS_ENABLE_WAKEUP_MASK) -#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_MSB 1 -#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB 1 -#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK 0x00000002 -#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_GET(x) (((x) & ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK) >> ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB) -#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_SET(x) (((x) << ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB) & ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK) -#define ERROR_STATUS_ENABLE_TX_OVERFLOW_MSB 0 -#define ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB 0 -#define ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK 0x00000001 -#define ERROR_STATUS_ENABLE_TX_OVERFLOW_GET(x) (((x) & ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK) >> ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB) -#define ERROR_STATUS_ENABLE_TX_OVERFLOW_SET(x) (((x) << ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB) & ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK) - -#define COUNTER_INT_STATUS_ENABLE_ADDRESS 0x0000041b -#define COUNTER_INT_STATUS_ENABLE_OFFSET 0x0000041b -#define COUNTER_INT_STATUS_ENABLE_BIT_MSB 7 -#define COUNTER_INT_STATUS_ENABLE_BIT_LSB 0 -#define COUNTER_INT_STATUS_ENABLE_BIT_MASK 0x000000ff -#define COUNTER_INT_STATUS_ENABLE_BIT_GET(x) (((x) & COUNTER_INT_STATUS_ENABLE_BIT_MASK) >> COUNTER_INT_STATUS_ENABLE_BIT_LSB) -#define COUNTER_INT_STATUS_ENABLE_BIT_SET(x) (((x) << COUNTER_INT_STATUS_ENABLE_BIT_LSB) & COUNTER_INT_STATUS_ENABLE_BIT_MASK) - -#define COUNT_ADDRESS 0x00000420 -#define COUNT_OFFSET 0x00000420 -#define COUNT_VALUE_MSB 7 -#define COUNT_VALUE_LSB 0 -#define COUNT_VALUE_MASK 0x000000ff -#define COUNT_VALUE_GET(x) (((x) & COUNT_VALUE_MASK) >> COUNT_VALUE_LSB) -#define COUNT_VALUE_SET(x) (((x) << COUNT_VALUE_LSB) & COUNT_VALUE_MASK) - -#define COUNT_DEC_ADDRESS 0x00000440 -#define COUNT_DEC_OFFSET 0x00000440 -#define COUNT_DEC_VALUE_MSB 7 -#define COUNT_DEC_VALUE_LSB 0 -#define COUNT_DEC_VALUE_MASK 0x000000ff -#define COUNT_DEC_VALUE_GET(x) (((x) & COUNT_DEC_VALUE_MASK) >> COUNT_DEC_VALUE_LSB) -#define COUNT_DEC_VALUE_SET(x) (((x) << COUNT_DEC_VALUE_LSB) & COUNT_DEC_VALUE_MASK) - -#define SCRATCH_ADDRESS 0x00000460 -#define SCRATCH_OFFSET 0x00000460 -#define SCRATCH_VALUE_MSB 7 -#define SCRATCH_VALUE_LSB 0 -#define SCRATCH_VALUE_MASK 0x000000ff -#define SCRATCH_VALUE_GET(x) (((x) & SCRATCH_VALUE_MASK) >> SCRATCH_VALUE_LSB) -#define SCRATCH_VALUE_SET(x) (((x) << SCRATCH_VALUE_LSB) & SCRATCH_VALUE_MASK) - -#define FIFO_TIMEOUT_ADDRESS 0x00000468 -#define FIFO_TIMEOUT_OFFSET 0x00000468 -#define FIFO_TIMEOUT_VALUE_MSB 7 -#define FIFO_TIMEOUT_VALUE_LSB 0 -#define FIFO_TIMEOUT_VALUE_MASK 0x000000ff -#define FIFO_TIMEOUT_VALUE_GET(x) (((x) & FIFO_TIMEOUT_VALUE_MASK) >> FIFO_TIMEOUT_VALUE_LSB) -#define FIFO_TIMEOUT_VALUE_SET(x) (((x) << FIFO_TIMEOUT_VALUE_LSB) & FIFO_TIMEOUT_VALUE_MASK) - -#define FIFO_TIMEOUT_ENABLE_ADDRESS 0x00000469 -#define FIFO_TIMEOUT_ENABLE_OFFSET 0x00000469 -#define FIFO_TIMEOUT_ENABLE_SET_MSB 0 -#define FIFO_TIMEOUT_ENABLE_SET_LSB 0 -#define FIFO_TIMEOUT_ENABLE_SET_MASK 0x00000001 -#define FIFO_TIMEOUT_ENABLE_SET_GET(x) (((x) & FIFO_TIMEOUT_ENABLE_SET_MASK) >> FIFO_TIMEOUT_ENABLE_SET_LSB) -#define FIFO_TIMEOUT_ENABLE_SET_SET(x) (((x) << FIFO_TIMEOUT_ENABLE_SET_LSB) & FIFO_TIMEOUT_ENABLE_SET_MASK) - -#define DISABLE_SLEEP_ADDRESS 0x0000046a -#define DISABLE_SLEEP_OFFSET 0x0000046a -#define DISABLE_SLEEP_FOR_INT_MSB 1 -#define DISABLE_SLEEP_FOR_INT_LSB 1 -#define DISABLE_SLEEP_FOR_INT_MASK 0x00000002 -#define DISABLE_SLEEP_FOR_INT_GET(x) (((x) & DISABLE_SLEEP_FOR_INT_MASK) >> DISABLE_SLEEP_FOR_INT_LSB) -#define DISABLE_SLEEP_FOR_INT_SET(x) (((x) << DISABLE_SLEEP_FOR_INT_LSB) & DISABLE_SLEEP_FOR_INT_MASK) -#define DISABLE_SLEEP_ON_MSB 0 -#define DISABLE_SLEEP_ON_LSB 0 -#define DISABLE_SLEEP_ON_MASK 0x00000001 -#define DISABLE_SLEEP_ON_GET(x) (((x) & DISABLE_SLEEP_ON_MASK) >> DISABLE_SLEEP_ON_LSB) -#define DISABLE_SLEEP_ON_SET(x) (((x) << DISABLE_SLEEP_ON_LSB) & DISABLE_SLEEP_ON_MASK) - -#define LOCAL_BUS_ADDRESS 0x00000470 -#define LOCAL_BUS_OFFSET 0x00000470 -#define LOCAL_BUS_STATE_MSB 1 -#define LOCAL_BUS_STATE_LSB 0 -#define LOCAL_BUS_STATE_MASK 0x00000003 -#define LOCAL_BUS_STATE_GET(x) (((x) & LOCAL_BUS_STATE_MASK) >> LOCAL_BUS_STATE_LSB) -#define LOCAL_BUS_STATE_SET(x) (((x) << LOCAL_BUS_STATE_LSB) & LOCAL_BUS_STATE_MASK) - -#define INT_WLAN_ADDRESS 0x00000472 -#define INT_WLAN_OFFSET 0x00000472 -#define INT_WLAN_VECTOR_MSB 7 -#define INT_WLAN_VECTOR_LSB 0 -#define INT_WLAN_VECTOR_MASK 0x000000ff -#define INT_WLAN_VECTOR_GET(x) (((x) & INT_WLAN_VECTOR_MASK) >> INT_WLAN_VECTOR_LSB) -#define INT_WLAN_VECTOR_SET(x) (((x) << INT_WLAN_VECTOR_LSB) & INT_WLAN_VECTOR_MASK) - -#define WINDOW_DATA_ADDRESS 0x00000474 -#define WINDOW_DATA_OFFSET 0x00000474 -#define WINDOW_DATA_DATA_MSB 7 -#define WINDOW_DATA_DATA_LSB 0 -#define WINDOW_DATA_DATA_MASK 0x000000ff -#define WINDOW_DATA_DATA_GET(x) (((x) & WINDOW_DATA_DATA_MASK) >> WINDOW_DATA_DATA_LSB) -#define WINDOW_DATA_DATA_SET(x) (((x) << WINDOW_DATA_DATA_LSB) & WINDOW_DATA_DATA_MASK) - -#define WINDOW_WRITE_ADDR_ADDRESS 0x00000478 -#define WINDOW_WRITE_ADDR_OFFSET 0x00000478 -#define WINDOW_WRITE_ADDR_ADDR_MSB 7 -#define WINDOW_WRITE_ADDR_ADDR_LSB 0 -#define WINDOW_WRITE_ADDR_ADDR_MASK 0x000000ff -#define WINDOW_WRITE_ADDR_ADDR_GET(x) (((x) & WINDOW_WRITE_ADDR_ADDR_MASK) >> WINDOW_WRITE_ADDR_ADDR_LSB) -#define WINDOW_WRITE_ADDR_ADDR_SET(x) (((x) << WINDOW_WRITE_ADDR_ADDR_LSB) & WINDOW_WRITE_ADDR_ADDR_MASK) - -#define WINDOW_READ_ADDR_ADDRESS 0x0000047c -#define WINDOW_READ_ADDR_OFFSET 0x0000047c -#define WINDOW_READ_ADDR_ADDR_MSB 7 -#define WINDOW_READ_ADDR_ADDR_LSB 0 -#define WINDOW_READ_ADDR_ADDR_MASK 0x000000ff -#define WINDOW_READ_ADDR_ADDR_GET(x) (((x) & WINDOW_READ_ADDR_ADDR_MASK) >> WINDOW_READ_ADDR_ADDR_LSB) -#define WINDOW_READ_ADDR_ADDR_SET(x) (((x) << WINDOW_READ_ADDR_ADDR_LSB) & WINDOW_READ_ADDR_ADDR_MASK) - -#define HOST_CTRL_SPI_CONFIG_ADDRESS 0x00000480 -#define HOST_CTRL_SPI_CONFIG_OFFSET 0x00000480 -#define HOST_CTRL_SPI_CONFIG_SPI_RESET_MSB 4 -#define HOST_CTRL_SPI_CONFIG_SPI_RESET_LSB 4 -#define HOST_CTRL_SPI_CONFIG_SPI_RESET_MASK 0x00000010 -#define HOST_CTRL_SPI_CONFIG_SPI_RESET_GET(x) (((x) & HOST_CTRL_SPI_CONFIG_SPI_RESET_MASK) >> HOST_CTRL_SPI_CONFIG_SPI_RESET_LSB) -#define HOST_CTRL_SPI_CONFIG_SPI_RESET_SET(x) (((x) << HOST_CTRL_SPI_CONFIG_SPI_RESET_LSB) & HOST_CTRL_SPI_CONFIG_SPI_RESET_MASK) -#define HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_MSB 3 -#define HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_LSB 3 -#define HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_MASK 0x00000008 -#define HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_GET(x) (((x) & HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_MASK) >> HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_LSB) -#define HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_SET(x) (((x) << HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_LSB) & HOST_CTRL_SPI_CONFIG_INTERRUPT_ENABLE_MASK) -#define HOST_CTRL_SPI_CONFIG_TEST_MODE_MSB 2 -#define HOST_CTRL_SPI_CONFIG_TEST_MODE_LSB 2 -#define HOST_CTRL_SPI_CONFIG_TEST_MODE_MASK 0x00000004 -#define HOST_CTRL_SPI_CONFIG_TEST_MODE_GET(x) (((x) & HOST_CTRL_SPI_CONFIG_TEST_MODE_MASK) >> HOST_CTRL_SPI_CONFIG_TEST_MODE_LSB) -#define HOST_CTRL_SPI_CONFIG_TEST_MODE_SET(x) (((x) << HOST_CTRL_SPI_CONFIG_TEST_MODE_LSB) & HOST_CTRL_SPI_CONFIG_TEST_MODE_MASK) -#define HOST_CTRL_SPI_CONFIG_DATA_SIZE_MSB 1 -#define HOST_CTRL_SPI_CONFIG_DATA_SIZE_LSB 0 -#define HOST_CTRL_SPI_CONFIG_DATA_SIZE_MASK 0x00000003 -#define HOST_CTRL_SPI_CONFIG_DATA_SIZE_GET(x) (((x) & HOST_CTRL_SPI_CONFIG_DATA_SIZE_MASK) >> HOST_CTRL_SPI_CONFIG_DATA_SIZE_LSB) -#define HOST_CTRL_SPI_CONFIG_DATA_SIZE_SET(x) (((x) << HOST_CTRL_SPI_CONFIG_DATA_SIZE_LSB) & HOST_CTRL_SPI_CONFIG_DATA_SIZE_MASK) - -#define HOST_CTRL_SPI_STATUS_ADDRESS 0x00000481 -#define HOST_CTRL_SPI_STATUS_OFFSET 0x00000481 -#define HOST_CTRL_SPI_STATUS_ADDR_ERR_MSB 3 -#define HOST_CTRL_SPI_STATUS_ADDR_ERR_LSB 3 -#define HOST_CTRL_SPI_STATUS_ADDR_ERR_MASK 0x00000008 -#define HOST_CTRL_SPI_STATUS_ADDR_ERR_GET(x) (((x) & HOST_CTRL_SPI_STATUS_ADDR_ERR_MASK) >> HOST_CTRL_SPI_STATUS_ADDR_ERR_LSB) -#define HOST_CTRL_SPI_STATUS_ADDR_ERR_SET(x) (((x) << HOST_CTRL_SPI_STATUS_ADDR_ERR_LSB) & HOST_CTRL_SPI_STATUS_ADDR_ERR_MASK) -#define HOST_CTRL_SPI_STATUS_RD_ERR_MSB 2 -#define HOST_CTRL_SPI_STATUS_RD_ERR_LSB 2 -#define HOST_CTRL_SPI_STATUS_RD_ERR_MASK 0x00000004 -#define HOST_CTRL_SPI_STATUS_RD_ERR_GET(x) (((x) & HOST_CTRL_SPI_STATUS_RD_ERR_MASK) >> HOST_CTRL_SPI_STATUS_RD_ERR_LSB) -#define HOST_CTRL_SPI_STATUS_RD_ERR_SET(x) (((x) << HOST_CTRL_SPI_STATUS_RD_ERR_LSB) & HOST_CTRL_SPI_STATUS_RD_ERR_MASK) -#define HOST_CTRL_SPI_STATUS_WR_ERR_MSB 1 -#define HOST_CTRL_SPI_STATUS_WR_ERR_LSB 1 -#define HOST_CTRL_SPI_STATUS_WR_ERR_MASK 0x00000002 -#define HOST_CTRL_SPI_STATUS_WR_ERR_GET(x) (((x) & HOST_CTRL_SPI_STATUS_WR_ERR_MASK) >> HOST_CTRL_SPI_STATUS_WR_ERR_LSB) -#define HOST_CTRL_SPI_STATUS_WR_ERR_SET(x) (((x) << HOST_CTRL_SPI_STATUS_WR_ERR_LSB) & HOST_CTRL_SPI_STATUS_WR_ERR_MASK) -#define HOST_CTRL_SPI_STATUS_READY_MSB 0 -#define HOST_CTRL_SPI_STATUS_READY_LSB 0 -#define HOST_CTRL_SPI_STATUS_READY_MASK 0x00000001 -#define HOST_CTRL_SPI_STATUS_READY_GET(x) (((x) & HOST_CTRL_SPI_STATUS_READY_MASK) >> HOST_CTRL_SPI_STATUS_READY_LSB) -#define HOST_CTRL_SPI_STATUS_READY_SET(x) (((x) << HOST_CTRL_SPI_STATUS_READY_LSB) & HOST_CTRL_SPI_STATUS_READY_MASK) - -#define NON_ASSOC_SLEEP_EN_ADDRESS 0x00000482 -#define NON_ASSOC_SLEEP_EN_OFFSET 0x00000482 -#define NON_ASSOC_SLEEP_EN_BIT_MSB 0 -#define NON_ASSOC_SLEEP_EN_BIT_LSB 0 -#define NON_ASSOC_SLEEP_EN_BIT_MASK 0x00000001 -#define NON_ASSOC_SLEEP_EN_BIT_GET(x) (((x) & NON_ASSOC_SLEEP_EN_BIT_MASK) >> NON_ASSOC_SLEEP_EN_BIT_LSB) -#define NON_ASSOC_SLEEP_EN_BIT_SET(x) (((x) << NON_ASSOC_SLEEP_EN_BIT_LSB) & NON_ASSOC_SLEEP_EN_BIT_MASK) - -#define CPU_DBG_SEL_ADDRESS 0x00000483 -#define CPU_DBG_SEL_OFFSET 0x00000483 -#define CPU_DBG_SEL_BIT_MSB 5 -#define CPU_DBG_SEL_BIT_LSB 0 -#define CPU_DBG_SEL_BIT_MASK 0x0000003f -#define CPU_DBG_SEL_BIT_GET(x) (((x) & CPU_DBG_SEL_BIT_MASK) >> CPU_DBG_SEL_BIT_LSB) -#define CPU_DBG_SEL_BIT_SET(x) (((x) << CPU_DBG_SEL_BIT_LSB) & CPU_DBG_SEL_BIT_MASK) - -#define CPU_DBG_ADDRESS 0x00000484 -#define CPU_DBG_OFFSET 0x00000484 -#define CPU_DBG_DATA_MSB 7 -#define CPU_DBG_DATA_LSB 0 -#define CPU_DBG_DATA_MASK 0x000000ff -#define CPU_DBG_DATA_GET(x) (((x) & CPU_DBG_DATA_MASK) >> CPU_DBG_DATA_LSB) -#define CPU_DBG_DATA_SET(x) (((x) << CPU_DBG_DATA_LSB) & CPU_DBG_DATA_MASK) - -#define INT_STATUS2_ENABLE_ADDRESS 0x00000488 -#define INT_STATUS2_ENABLE_OFFSET 0x00000488 -#define INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_MSB 2 -#define INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_LSB 2 -#define INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_MASK 0x00000004 -#define INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_GET(x) (((x) & INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_MASK) >> INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_LSB) -#define INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_SET(x) (((x) << INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_LSB) & INT_STATUS2_ENABLE_GMBOX_RX_UNDERFLOW_MASK) -#define INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_MSB 1 -#define INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_LSB 1 -#define INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_MASK 0x00000002 -#define INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_GET(x) (((x) & INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_MASK) >> INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_LSB) -#define INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_SET(x) (((x) << INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_LSB) & INT_STATUS2_ENABLE_GMBOX_TX_OVERFLOW_MASK) -#define INT_STATUS2_ENABLE_GMBOX_DATA_MSB 0 -#define INT_STATUS2_ENABLE_GMBOX_DATA_LSB 0 -#define INT_STATUS2_ENABLE_GMBOX_DATA_MASK 0x00000001 -#define INT_STATUS2_ENABLE_GMBOX_DATA_GET(x) (((x) & INT_STATUS2_ENABLE_GMBOX_DATA_MASK) >> INT_STATUS2_ENABLE_GMBOX_DATA_LSB) -#define INT_STATUS2_ENABLE_GMBOX_DATA_SET(x) (((x) << INT_STATUS2_ENABLE_GMBOX_DATA_LSB) & INT_STATUS2_ENABLE_GMBOX_DATA_MASK) - -#define GMBOX_RX_LOOKAHEAD_ADDRESS 0x00000490 -#define GMBOX_RX_LOOKAHEAD_OFFSET 0x00000490 -#define GMBOX_RX_LOOKAHEAD_DATA_MSB 7 -#define GMBOX_RX_LOOKAHEAD_DATA_LSB 0 -#define GMBOX_RX_LOOKAHEAD_DATA_MASK 0x000000ff -#define GMBOX_RX_LOOKAHEAD_DATA_GET(x) (((x) & GMBOX_RX_LOOKAHEAD_DATA_MASK) >> GMBOX_RX_LOOKAHEAD_DATA_LSB) -#define GMBOX_RX_LOOKAHEAD_DATA_SET(x) (((x) << GMBOX_RX_LOOKAHEAD_DATA_LSB) & GMBOX_RX_LOOKAHEAD_DATA_MASK) - -#define GMBOX_RX_LOOKAHEAD_MUX_ADDRESS 0x00000498 -#define GMBOX_RX_LOOKAHEAD_MUX_OFFSET 0x00000498 -#define GMBOX_RX_LOOKAHEAD_MUX_SEL_MSB 0 -#define GMBOX_RX_LOOKAHEAD_MUX_SEL_LSB 0 -#define GMBOX_RX_LOOKAHEAD_MUX_SEL_MASK 0x00000001 -#define GMBOX_RX_LOOKAHEAD_MUX_SEL_GET(x) (((x) & GMBOX_RX_LOOKAHEAD_MUX_SEL_MASK) >> GMBOX_RX_LOOKAHEAD_MUX_SEL_LSB) -#define GMBOX_RX_LOOKAHEAD_MUX_SEL_SET(x) (((x) << GMBOX_RX_LOOKAHEAD_MUX_SEL_LSB) & GMBOX_RX_LOOKAHEAD_MUX_SEL_MASK) - -#define CIS_WINDOW_ADDRESS 0x00000600 -#define CIS_WINDOW_OFFSET 0x00000600 -#define CIS_WINDOW_DATA_MSB 7 -#define CIS_WINDOW_DATA_LSB 0 -#define CIS_WINDOW_DATA_MASK 0x000000ff -#define CIS_WINDOW_DATA_GET(x) (((x) & CIS_WINDOW_DATA_MASK) >> CIS_WINDOW_DATA_LSB) -#define CIS_WINDOW_DATA_SET(x) (((x) << CIS_WINDOW_DATA_LSB) & CIS_WINDOW_DATA_MASK) - - -#endif /* _MBOX_WLAN_HOST_REG_H_ */ diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_reg.h deleted file mode 100644 index f5167b9..0000000 --- a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/mbox_wlan_reg.h +++ /dev/null @@ -1,589 +0,0 @@ -// ------------------------------------------------------------------ -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -// ------------------------------------------------------------------ -//=================================================================== -// Author(s): ="Atheros" -//=================================================================== - - -#ifndef _MBOX_WLAN_REG_REG_H_ -#define _MBOX_WLAN_REG_REG_H_ - -#define WLAN_MBOX_FIFO_ADDRESS 0x00000000 -#define WLAN_MBOX_FIFO_OFFSET 0x00000000 -#define WLAN_MBOX_FIFO_DATA_MSB 19 -#define WLAN_MBOX_FIFO_DATA_LSB 0 -#define WLAN_MBOX_FIFO_DATA_MASK 0x000fffff -#define WLAN_MBOX_FIFO_DATA_GET(x) (((x) & WLAN_MBOX_FIFO_DATA_MASK) >> WLAN_MBOX_FIFO_DATA_LSB) -#define WLAN_MBOX_FIFO_DATA_SET(x) (((x) << WLAN_MBOX_FIFO_DATA_LSB) & WLAN_MBOX_FIFO_DATA_MASK) - -#define WLAN_MBOX_FIFO_STATUS_ADDRESS 0x00000010 -#define WLAN_MBOX_FIFO_STATUS_OFFSET 0x00000010 -#define WLAN_MBOX_FIFO_STATUS_EMPTY_MSB 19 -#define WLAN_MBOX_FIFO_STATUS_EMPTY_LSB 16 -#define WLAN_MBOX_FIFO_STATUS_EMPTY_MASK 0x000f0000 -#define WLAN_MBOX_FIFO_STATUS_EMPTY_GET(x) (((x) & WLAN_MBOX_FIFO_STATUS_EMPTY_MASK) >> WLAN_MBOX_FIFO_STATUS_EMPTY_LSB) -#define WLAN_MBOX_FIFO_STATUS_EMPTY_SET(x) (((x) << WLAN_MBOX_FIFO_STATUS_EMPTY_LSB) & WLAN_MBOX_FIFO_STATUS_EMPTY_MASK) -#define WLAN_MBOX_FIFO_STATUS_FULL_MSB 15 -#define WLAN_MBOX_FIFO_STATUS_FULL_LSB 12 -#define WLAN_MBOX_FIFO_STATUS_FULL_MASK 0x0000f000 -#define WLAN_MBOX_FIFO_STATUS_FULL_GET(x) (((x) & WLAN_MBOX_FIFO_STATUS_FULL_MASK) >> WLAN_MBOX_FIFO_STATUS_FULL_LSB) -#define WLAN_MBOX_FIFO_STATUS_FULL_SET(x) (((x) << WLAN_MBOX_FIFO_STATUS_FULL_LSB) & WLAN_MBOX_FIFO_STATUS_FULL_MASK) - -#define WLAN_MBOX_DMA_POLICY_ADDRESS 0x00000014 -#define WLAN_MBOX_DMA_POLICY_OFFSET 0x00000014 -#define WLAN_MBOX_DMA_POLICY_TX_QUANTUM_MSB 3 -#define WLAN_MBOX_DMA_POLICY_TX_QUANTUM_LSB 3 -#define WLAN_MBOX_DMA_POLICY_TX_QUANTUM_MASK 0x00000008 -#define WLAN_MBOX_DMA_POLICY_TX_QUANTUM_GET(x) (((x) & WLAN_MBOX_DMA_POLICY_TX_QUANTUM_MASK) >> WLAN_MBOX_DMA_POLICY_TX_QUANTUM_LSB) -#define WLAN_MBOX_DMA_POLICY_TX_QUANTUM_SET(x) (((x) << WLAN_MBOX_DMA_POLICY_TX_QUANTUM_LSB) & WLAN_MBOX_DMA_POLICY_TX_QUANTUM_MASK) -#define WLAN_MBOX_DMA_POLICY_TX_ORDER_MSB 2 -#define WLAN_MBOX_DMA_POLICY_TX_ORDER_LSB 2 -#define WLAN_MBOX_DMA_POLICY_TX_ORDER_MASK 0x00000004 -#define WLAN_MBOX_DMA_POLICY_TX_ORDER_GET(x) (((x) & WLAN_MBOX_DMA_POLICY_TX_ORDER_MASK) >> WLAN_MBOX_DMA_POLICY_TX_ORDER_LSB) -#define WLAN_MBOX_DMA_POLICY_TX_ORDER_SET(x) (((x) << WLAN_MBOX_DMA_POLICY_TX_ORDER_LSB) & WLAN_MBOX_DMA_POLICY_TX_ORDER_MASK) -#define WLAN_MBOX_DMA_POLICY_RX_QUANTUM_MSB 1 -#define WLAN_MBOX_DMA_POLICY_RX_QUANTUM_LSB 1 -#define WLAN_MBOX_DMA_POLICY_RX_QUANTUM_MASK 0x00000002 -#define WLAN_MBOX_DMA_POLICY_RX_QUANTUM_GET(x) (((x) & WLAN_MBOX_DMA_POLICY_RX_QUANTUM_MASK) >> WLAN_MBOX_DMA_POLICY_RX_QUANTUM_LSB) -#define WLAN_MBOX_DMA_POLICY_RX_QUANTUM_SET(x) (((x) << WLAN_MBOX_DMA_POLICY_RX_QUANTUM_LSB) & WLAN_MBOX_DMA_POLICY_RX_QUANTUM_MASK) -#define WLAN_MBOX_DMA_POLICY_RX_ORDER_MSB 0 -#define WLAN_MBOX_DMA_POLICY_RX_ORDER_LSB 0 -#define WLAN_MBOX_DMA_POLICY_RX_ORDER_MASK 0x00000001 -#define WLAN_MBOX_DMA_POLICY_RX_ORDER_GET(x) (((x) & WLAN_MBOX_DMA_POLICY_RX_ORDER_MASK) >> WLAN_MBOX_DMA_POLICY_RX_ORDER_LSB) -#define WLAN_MBOX_DMA_POLICY_RX_ORDER_SET(x) (((x) << WLAN_MBOX_DMA_POLICY_RX_ORDER_LSB) & WLAN_MBOX_DMA_POLICY_RX_ORDER_MASK) - -#define WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS 0x00000018 -#define WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_OFFSET 0x00000018 -#define WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27 -#define WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2 -#define WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc -#define WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) -#define WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) - -#define WLAN_MBOX0_DMA_RX_CONTROL_ADDRESS 0x0000001c -#define WLAN_MBOX0_DMA_RX_CONTROL_OFFSET 0x0000001c -#define WLAN_MBOX0_DMA_RX_CONTROL_RESUME_MSB 2 -#define WLAN_MBOX0_DMA_RX_CONTROL_RESUME_LSB 2 -#define WLAN_MBOX0_DMA_RX_CONTROL_RESUME_MASK 0x00000004 -#define WLAN_MBOX0_DMA_RX_CONTROL_RESUME_GET(x) (((x) & WLAN_MBOX0_DMA_RX_CONTROL_RESUME_MASK) >> WLAN_MBOX0_DMA_RX_CONTROL_RESUME_LSB) -#define WLAN_MBOX0_DMA_RX_CONTROL_RESUME_SET(x) (((x) << WLAN_MBOX0_DMA_RX_CONTROL_RESUME_LSB) & WLAN_MBOX0_DMA_RX_CONTROL_RESUME_MASK) -#define WLAN_MBOX0_DMA_RX_CONTROL_START_MSB 1 -#define WLAN_MBOX0_DMA_RX_CONTROL_START_LSB 1 -#define WLAN_MBOX0_DMA_RX_CONTROL_START_MASK 0x00000002 -#define WLAN_MBOX0_DMA_RX_CONTROL_START_GET(x) (((x) & WLAN_MBOX0_DMA_RX_CONTROL_START_MASK) >> WLAN_MBOX0_DMA_RX_CONTROL_START_LSB) -#define WLAN_MBOX0_DMA_RX_CONTROL_START_SET(x) (((x) << WLAN_MBOX0_DMA_RX_CONTROL_START_LSB) & WLAN_MBOX0_DMA_RX_CONTROL_START_MASK) -#define WLAN_MBOX0_DMA_RX_CONTROL_STOP_MSB 0 -#define WLAN_MBOX0_DMA_RX_CONTROL_STOP_LSB 0 -#define WLAN_MBOX0_DMA_RX_CONTROL_STOP_MASK 0x00000001 -#define WLAN_MBOX0_DMA_RX_CONTROL_STOP_GET(x) (((x) & WLAN_MBOX0_DMA_RX_CONTROL_STOP_MASK) >> WLAN_MBOX0_DMA_RX_CONTROL_STOP_LSB) -#define WLAN_MBOX0_DMA_RX_CONTROL_STOP_SET(x) (((x) << WLAN_MBOX0_DMA_RX_CONTROL_STOP_LSB) & WLAN_MBOX0_DMA_RX_CONTROL_STOP_MASK) - -#define WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS 0x00000020 -#define WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_OFFSET 0x00000020 -#define WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27 -#define WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2 -#define WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc -#define WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) -#define WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) - -#define WLAN_MBOX0_DMA_TX_CONTROL_ADDRESS 0x00000024 -#define WLAN_MBOX0_DMA_TX_CONTROL_OFFSET 0x00000024 -#define WLAN_MBOX0_DMA_TX_CONTROL_RESUME_MSB 2 -#define WLAN_MBOX0_DMA_TX_CONTROL_RESUME_LSB 2 -#define WLAN_MBOX0_DMA_TX_CONTROL_RESUME_MASK 0x00000004 -#define WLAN_MBOX0_DMA_TX_CONTROL_RESUME_GET(x) (((x) & WLAN_MBOX0_DMA_TX_CONTROL_RESUME_MASK) >> WLAN_MBOX0_DMA_TX_CONTROL_RESUME_LSB) -#define WLAN_MBOX0_DMA_TX_CONTROL_RESUME_SET(x) (((x) << WLAN_MBOX0_DMA_TX_CONTROL_RESUME_LSB) & WLAN_MBOX0_DMA_TX_CONTROL_RESUME_MASK) -#define WLAN_MBOX0_DMA_TX_CONTROL_START_MSB 1 -#define WLAN_MBOX0_DMA_TX_CONTROL_START_LSB 1 -#define WLAN_MBOX0_DMA_TX_CONTROL_START_MASK 0x00000002 -#define WLAN_MBOX0_DMA_TX_CONTROL_START_GET(x) (((x) & WLAN_MBOX0_DMA_TX_CONTROL_START_MASK) >> WLAN_MBOX0_DMA_TX_CONTROL_START_LSB) -#define WLAN_MBOX0_DMA_TX_CONTROL_START_SET(x) (((x) << WLAN_MBOX0_DMA_TX_CONTROL_START_LSB) & WLAN_MBOX0_DMA_TX_CONTROL_START_MASK) -#define WLAN_MBOX0_DMA_TX_CONTROL_STOP_MSB 0 -#define WLAN_MBOX0_DMA_TX_CONTROL_STOP_LSB 0 -#define WLAN_MBOX0_DMA_TX_CONTROL_STOP_MASK 0x00000001 -#define WLAN_MBOX0_DMA_TX_CONTROL_STOP_GET(x) (((x) & WLAN_MBOX0_DMA_TX_CONTROL_STOP_MASK) >> WLAN_MBOX0_DMA_TX_CONTROL_STOP_LSB) -#define WLAN_MBOX0_DMA_TX_CONTROL_STOP_SET(x) (((x) << WLAN_MBOX0_DMA_TX_CONTROL_STOP_LSB) & WLAN_MBOX0_DMA_TX_CONTROL_STOP_MASK) - -#define WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS 0x00000028 -#define WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_OFFSET 0x00000028 -#define WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27 -#define WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2 -#define WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc -#define WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) -#define WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX1_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) - -#define WLAN_MBOX1_DMA_RX_CONTROL_ADDRESS 0x0000002c -#define WLAN_MBOX1_DMA_RX_CONTROL_OFFSET 0x0000002c -#define WLAN_MBOX1_DMA_RX_CONTROL_RESUME_MSB 2 -#define WLAN_MBOX1_DMA_RX_CONTROL_RESUME_LSB 2 -#define WLAN_MBOX1_DMA_RX_CONTROL_RESUME_MASK 0x00000004 -#define WLAN_MBOX1_DMA_RX_CONTROL_RESUME_GET(x) (((x) & WLAN_MBOX1_DMA_RX_CONTROL_RESUME_MASK) >> WLAN_MBOX1_DMA_RX_CONTROL_RESUME_LSB) -#define WLAN_MBOX1_DMA_RX_CONTROL_RESUME_SET(x) (((x) << WLAN_MBOX1_DMA_RX_CONTROL_RESUME_LSB) & WLAN_MBOX1_DMA_RX_CONTROL_RESUME_MASK) -#define WLAN_MBOX1_DMA_RX_CONTROL_START_MSB 1 -#define WLAN_MBOX1_DMA_RX_CONTROL_START_LSB 1 -#define WLAN_MBOX1_DMA_RX_CONTROL_START_MASK 0x00000002 -#define WLAN_MBOX1_DMA_RX_CONTROL_START_GET(x) (((x) & WLAN_MBOX1_DMA_RX_CONTROL_START_MASK) >> WLAN_MBOX1_DMA_RX_CONTROL_START_LSB) -#define WLAN_MBOX1_DMA_RX_CONTROL_START_SET(x) (((x) << WLAN_MBOX1_DMA_RX_CONTROL_START_LSB) & WLAN_MBOX1_DMA_RX_CONTROL_START_MASK) -#define WLAN_MBOX1_DMA_RX_CONTROL_STOP_MSB 0 -#define WLAN_MBOX1_DMA_RX_CONTROL_STOP_LSB 0 -#define WLAN_MBOX1_DMA_RX_CONTROL_STOP_MASK 0x00000001 -#define WLAN_MBOX1_DMA_RX_CONTROL_STOP_GET(x) (((x) & WLAN_MBOX1_DMA_RX_CONTROL_STOP_MASK) >> WLAN_MBOX1_DMA_RX_CONTROL_STOP_LSB) -#define WLAN_MBOX1_DMA_RX_CONTROL_STOP_SET(x) (((x) << WLAN_MBOX1_DMA_RX_CONTROL_STOP_LSB) & WLAN_MBOX1_DMA_RX_CONTROL_STOP_MASK) - -#define WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS 0x00000030 -#define WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_OFFSET 0x00000030 -#define WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27 -#define WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2 -#define WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc -#define WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) -#define WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX1_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) - -#define WLAN_MBOX1_DMA_TX_CONTROL_ADDRESS 0x00000034 -#define WLAN_MBOX1_DMA_TX_CONTROL_OFFSET 0x00000034 -#define WLAN_MBOX1_DMA_TX_CONTROL_RESUME_MSB 2 -#define WLAN_MBOX1_DMA_TX_CONTROL_RESUME_LSB 2 -#define WLAN_MBOX1_DMA_TX_CONTROL_RESUME_MASK 0x00000004 -#define WLAN_MBOX1_DMA_TX_CONTROL_RESUME_GET(x) (((x) & WLAN_MBOX1_DMA_TX_CONTROL_RESUME_MASK) >> WLAN_MBOX1_DMA_TX_CONTROL_RESUME_LSB) -#define WLAN_MBOX1_DMA_TX_CONTROL_RESUME_SET(x) (((x) << WLAN_MBOX1_DMA_TX_CONTROL_RESUME_LSB) & WLAN_MBOX1_DMA_TX_CONTROL_RESUME_MASK) -#define WLAN_MBOX1_DMA_TX_CONTROL_START_MSB 1 -#define WLAN_MBOX1_DMA_TX_CONTROL_START_LSB 1 -#define WLAN_MBOX1_DMA_TX_CONTROL_START_MASK 0x00000002 -#define WLAN_MBOX1_DMA_TX_CONTROL_START_GET(x) (((x) & WLAN_MBOX1_DMA_TX_CONTROL_START_MASK) >> WLAN_MBOX1_DMA_TX_CONTROL_START_LSB) -#define WLAN_MBOX1_DMA_TX_CONTROL_START_SET(x) (((x) << WLAN_MBOX1_DMA_TX_CONTROL_START_LSB) & WLAN_MBOX1_DMA_TX_CONTROL_START_MASK) -#define WLAN_MBOX1_DMA_TX_CONTROL_STOP_MSB 0 -#define WLAN_MBOX1_DMA_TX_CONTROL_STOP_LSB 0 -#define WLAN_MBOX1_DMA_TX_CONTROL_STOP_MASK 0x00000001 -#define WLAN_MBOX1_DMA_TX_CONTROL_STOP_GET(x) (((x) & WLAN_MBOX1_DMA_TX_CONTROL_STOP_MASK) >> WLAN_MBOX1_DMA_TX_CONTROL_STOP_LSB) -#define WLAN_MBOX1_DMA_TX_CONTROL_STOP_SET(x) (((x) << WLAN_MBOX1_DMA_TX_CONTROL_STOP_LSB) & WLAN_MBOX1_DMA_TX_CONTROL_STOP_MASK) - -#define WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS 0x00000038 -#define WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_OFFSET 0x00000038 -#define WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27 -#define WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2 -#define WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc -#define WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) -#define WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX2_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) - -#define WLAN_MBOX2_DMA_RX_CONTROL_ADDRESS 0x0000003c -#define WLAN_MBOX2_DMA_RX_CONTROL_OFFSET 0x0000003c -#define WLAN_MBOX2_DMA_RX_CONTROL_RESUME_MSB 2 -#define WLAN_MBOX2_DMA_RX_CONTROL_RESUME_LSB 2 -#define WLAN_MBOX2_DMA_RX_CONTROL_RESUME_MASK 0x00000004 -#define WLAN_MBOX2_DMA_RX_CONTROL_RESUME_GET(x) (((x) & WLAN_MBOX2_DMA_RX_CONTROL_RESUME_MASK) >> WLAN_MBOX2_DMA_RX_CONTROL_RESUME_LSB) -#define WLAN_MBOX2_DMA_RX_CONTROL_RESUME_SET(x) (((x) << WLAN_MBOX2_DMA_RX_CONTROL_RESUME_LSB) & WLAN_MBOX2_DMA_RX_CONTROL_RESUME_MASK) -#define WLAN_MBOX2_DMA_RX_CONTROL_START_MSB 1 -#define WLAN_MBOX2_DMA_RX_CONTROL_START_LSB 1 -#define WLAN_MBOX2_DMA_RX_CONTROL_START_MASK 0x00000002 -#define WLAN_MBOX2_DMA_RX_CONTROL_START_GET(x) (((x) & WLAN_MBOX2_DMA_RX_CONTROL_START_MASK) >> WLAN_MBOX2_DMA_RX_CONTROL_START_LSB) -#define WLAN_MBOX2_DMA_RX_CONTROL_START_SET(x) (((x) << WLAN_MBOX2_DMA_RX_CONTROL_START_LSB) & WLAN_MBOX2_DMA_RX_CONTROL_START_MASK) -#define WLAN_MBOX2_DMA_RX_CONTROL_STOP_MSB 0 -#define WLAN_MBOX2_DMA_RX_CONTROL_STOP_LSB 0 -#define WLAN_MBOX2_DMA_RX_CONTROL_STOP_MASK 0x00000001 -#define WLAN_MBOX2_DMA_RX_CONTROL_STOP_GET(x) (((x) & WLAN_MBOX2_DMA_RX_CONTROL_STOP_MASK) >> WLAN_MBOX2_DMA_RX_CONTROL_STOP_LSB) -#define WLAN_MBOX2_DMA_RX_CONTROL_STOP_SET(x) (((x) << WLAN_MBOX2_DMA_RX_CONTROL_STOP_LSB) & WLAN_MBOX2_DMA_RX_CONTROL_STOP_MASK) - -#define WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS 0x00000040 -#define WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_OFFSET 0x00000040 -#define WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27 -#define WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2 -#define WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc -#define WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) -#define WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX2_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) - -#define WLAN_MBOX2_DMA_TX_CONTROL_ADDRESS 0x00000044 -#define WLAN_MBOX2_DMA_TX_CONTROL_OFFSET 0x00000044 -#define WLAN_MBOX2_DMA_TX_CONTROL_RESUME_MSB 2 -#define WLAN_MBOX2_DMA_TX_CONTROL_RESUME_LSB 2 -#define WLAN_MBOX2_DMA_TX_CONTROL_RESUME_MASK 0x00000004 -#define WLAN_MBOX2_DMA_TX_CONTROL_RESUME_GET(x) (((x) & WLAN_MBOX2_DMA_TX_CONTROL_RESUME_MASK) >> WLAN_MBOX2_DMA_TX_CONTROL_RESUME_LSB) -#define WLAN_MBOX2_DMA_TX_CONTROL_RESUME_SET(x) (((x) << WLAN_MBOX2_DMA_TX_CONTROL_RESUME_LSB) & WLAN_MBOX2_DMA_TX_CONTROL_RESUME_MASK) -#define WLAN_MBOX2_DMA_TX_CONTROL_START_MSB 1 -#define WLAN_MBOX2_DMA_TX_CONTROL_START_LSB 1 -#define WLAN_MBOX2_DMA_TX_CONTROL_START_MASK 0x00000002 -#define WLAN_MBOX2_DMA_TX_CONTROL_START_GET(x) (((x) & WLAN_MBOX2_DMA_TX_CONTROL_START_MASK) >> WLAN_MBOX2_DMA_TX_CONTROL_START_LSB) -#define WLAN_MBOX2_DMA_TX_CONTROL_START_SET(x) (((x) << WLAN_MBOX2_DMA_TX_CONTROL_START_LSB) & WLAN_MBOX2_DMA_TX_CONTROL_START_MASK) -#define WLAN_MBOX2_DMA_TX_CONTROL_STOP_MSB 0 -#define WLAN_MBOX2_DMA_TX_CONTROL_STOP_LSB 0 -#define WLAN_MBOX2_DMA_TX_CONTROL_STOP_MASK 0x00000001 -#define WLAN_MBOX2_DMA_TX_CONTROL_STOP_GET(x) (((x) & WLAN_MBOX2_DMA_TX_CONTROL_STOP_MASK) >> WLAN_MBOX2_DMA_TX_CONTROL_STOP_LSB) -#define WLAN_MBOX2_DMA_TX_CONTROL_STOP_SET(x) (((x) << WLAN_MBOX2_DMA_TX_CONTROL_STOP_LSB) & WLAN_MBOX2_DMA_TX_CONTROL_STOP_MASK) - -#define WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS 0x00000048 -#define WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_OFFSET 0x00000048 -#define WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27 -#define WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2 -#define WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc -#define WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) -#define WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX3_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) - -#define WLAN_MBOX3_DMA_RX_CONTROL_ADDRESS 0x0000004c -#define WLAN_MBOX3_DMA_RX_CONTROL_OFFSET 0x0000004c -#define WLAN_MBOX3_DMA_RX_CONTROL_RESUME_MSB 2 -#define WLAN_MBOX3_DMA_RX_CONTROL_RESUME_LSB 2 -#define WLAN_MBOX3_DMA_RX_CONTROL_RESUME_MASK 0x00000004 -#define WLAN_MBOX3_DMA_RX_CONTROL_RESUME_GET(x) (((x) & WLAN_MBOX3_DMA_RX_CONTROL_RESUME_MASK) >> WLAN_MBOX3_DMA_RX_CONTROL_RESUME_LSB) -#define WLAN_MBOX3_DMA_RX_CONTROL_RESUME_SET(x) (((x) << WLAN_MBOX3_DMA_RX_CONTROL_RESUME_LSB) & WLAN_MBOX3_DMA_RX_CONTROL_RESUME_MASK) -#define WLAN_MBOX3_DMA_RX_CONTROL_START_MSB 1 -#define WLAN_MBOX3_DMA_RX_CONTROL_START_LSB 1 -#define WLAN_MBOX3_DMA_RX_CONTROL_START_MASK 0x00000002 -#define WLAN_MBOX3_DMA_RX_CONTROL_START_GET(x) (((x) & WLAN_MBOX3_DMA_RX_CONTROL_START_MASK) >> WLAN_MBOX3_DMA_RX_CONTROL_START_LSB) -#define WLAN_MBOX3_DMA_RX_CONTROL_START_SET(x) (((x) << WLAN_MBOX3_DMA_RX_CONTROL_START_LSB) & WLAN_MBOX3_DMA_RX_CONTROL_START_MASK) -#define WLAN_MBOX3_DMA_RX_CONTROL_STOP_MSB 0 -#define WLAN_MBOX3_DMA_RX_CONTROL_STOP_LSB 0 -#define WLAN_MBOX3_DMA_RX_CONTROL_STOP_MASK 0x00000001 -#define WLAN_MBOX3_DMA_RX_CONTROL_STOP_GET(x) (((x) & WLAN_MBOX3_DMA_RX_CONTROL_STOP_MASK) >> WLAN_MBOX3_DMA_RX_CONTROL_STOP_LSB) -#define WLAN_MBOX3_DMA_RX_CONTROL_STOP_SET(x) (((x) << WLAN_MBOX3_DMA_RX_CONTROL_STOP_LSB) & WLAN_MBOX3_DMA_RX_CONTROL_STOP_MASK) - -#define WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS 0x00000050 -#define WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_OFFSET 0x00000050 -#define WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27 -#define WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2 -#define WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc -#define WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) -#define WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_MBOX3_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) - -#define WLAN_MBOX3_DMA_TX_CONTROL_ADDRESS 0x00000054 -#define WLAN_MBOX3_DMA_TX_CONTROL_OFFSET 0x00000054 -#define WLAN_MBOX3_DMA_TX_CONTROL_RESUME_MSB 2 -#define WLAN_MBOX3_DMA_TX_CONTROL_RESUME_LSB 2 -#define WLAN_MBOX3_DMA_TX_CONTROL_RESUME_MASK 0x00000004 -#define WLAN_MBOX3_DMA_TX_CONTROL_RESUME_GET(x) (((x) & WLAN_MBOX3_DMA_TX_CONTROL_RESUME_MASK) >> WLAN_MBOX3_DMA_TX_CONTROL_RESUME_LSB) -#define WLAN_MBOX3_DMA_TX_CONTROL_RESUME_SET(x) (((x) << WLAN_MBOX3_DMA_TX_CONTROL_RESUME_LSB) & WLAN_MBOX3_DMA_TX_CONTROL_RESUME_MASK) -#define WLAN_MBOX3_DMA_TX_CONTROL_START_MSB 1 -#define WLAN_MBOX3_DMA_TX_CONTROL_START_LSB 1 -#define WLAN_MBOX3_DMA_TX_CONTROL_START_MASK 0x00000002 -#define WLAN_MBOX3_DMA_TX_CONTROL_START_GET(x) (((x) & WLAN_MBOX3_DMA_TX_CONTROL_START_MASK) >> WLAN_MBOX3_DMA_TX_CONTROL_START_LSB) -#define WLAN_MBOX3_DMA_TX_CONTROL_START_SET(x) (((x) << WLAN_MBOX3_DMA_TX_CONTROL_START_LSB) & WLAN_MBOX3_DMA_TX_CONTROL_START_MASK) -#define WLAN_MBOX3_DMA_TX_CONTROL_STOP_MSB 0 -#define WLAN_MBOX3_DMA_TX_CONTROL_STOP_LSB 0 -#define WLAN_MBOX3_DMA_TX_CONTROL_STOP_MASK 0x00000001 -#define WLAN_MBOX3_DMA_TX_CONTROL_STOP_GET(x) (((x) & WLAN_MBOX3_DMA_TX_CONTROL_STOP_MASK) >> WLAN_MBOX3_DMA_TX_CONTROL_STOP_LSB) -#define WLAN_MBOX3_DMA_TX_CONTROL_STOP_SET(x) (((x) << WLAN_MBOX3_DMA_TX_CONTROL_STOP_LSB) & WLAN_MBOX3_DMA_TX_CONTROL_STOP_MASK) - -#define WLAN_MBOX_INT_STATUS_ADDRESS 0x00000058 -#define WLAN_MBOX_INT_STATUS_OFFSET 0x00000058 -#define WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_MSB 31 -#define WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_LSB 28 -#define WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_MASK 0xf0000000 -#define WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_GET(x) (((x) & WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_MASK) >> WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_LSB) -#define WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_SET(x) (((x) << WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_LSB) & WLAN_MBOX_INT_STATUS_RX_DMA_COMPLETE_MASK) -#define WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MSB 27 -#define WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB 24 -#define WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK 0x0f000000 -#define WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_GET(x) (((x) & WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK) >> WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB) -#define WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_SET(x) (((x) << WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB) & WLAN_MBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK) -#define WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_MSB 23 -#define WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_LSB 20 -#define WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_MASK 0x00f00000 -#define WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_GET(x) (((x) & WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_MASK) >> WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_LSB) -#define WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_SET(x) (((x) << WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_LSB) & WLAN_MBOX_INT_STATUS_TX_DMA_COMPLETE_MASK) -#define WLAN_MBOX_INT_STATUS_TX_OVERFLOW_MSB 17 -#define WLAN_MBOX_INT_STATUS_TX_OVERFLOW_LSB 17 -#define WLAN_MBOX_INT_STATUS_TX_OVERFLOW_MASK 0x00020000 -#define WLAN_MBOX_INT_STATUS_TX_OVERFLOW_GET(x) (((x) & WLAN_MBOX_INT_STATUS_TX_OVERFLOW_MASK) >> WLAN_MBOX_INT_STATUS_TX_OVERFLOW_LSB) -#define WLAN_MBOX_INT_STATUS_TX_OVERFLOW_SET(x) (((x) << WLAN_MBOX_INT_STATUS_TX_OVERFLOW_LSB) & WLAN_MBOX_INT_STATUS_TX_OVERFLOW_MASK) -#define WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_MSB 16 -#define WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_LSB 16 -#define WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_MASK 0x00010000 -#define WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_GET(x) (((x) & WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_MASK) >> WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_LSB) -#define WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_SET(x) (((x) << WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_LSB) & WLAN_MBOX_INT_STATUS_RX_UNDERFLOW_MASK) -#define WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_MSB 15 -#define WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_LSB 12 -#define WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_MASK 0x0000f000 -#define WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_GET(x) (((x) & WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_MASK) >> WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_LSB) -#define WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_SET(x) (((x) << WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_LSB) & WLAN_MBOX_INT_STATUS_TX_NOT_EMPTY_MASK) -#define WLAN_MBOX_INT_STATUS_RX_NOT_FULL_MSB 11 -#define WLAN_MBOX_INT_STATUS_RX_NOT_FULL_LSB 8 -#define WLAN_MBOX_INT_STATUS_RX_NOT_FULL_MASK 0x00000f00 -#define WLAN_MBOX_INT_STATUS_RX_NOT_FULL_GET(x) (((x) & WLAN_MBOX_INT_STATUS_RX_NOT_FULL_MASK) >> WLAN_MBOX_INT_STATUS_RX_NOT_FULL_LSB) -#define WLAN_MBOX_INT_STATUS_RX_NOT_FULL_SET(x) (((x) << WLAN_MBOX_INT_STATUS_RX_NOT_FULL_LSB) & WLAN_MBOX_INT_STATUS_RX_NOT_FULL_MASK) -#define WLAN_MBOX_INT_STATUS_HOST_MSB 7 -#define WLAN_MBOX_INT_STATUS_HOST_LSB 0 -#define WLAN_MBOX_INT_STATUS_HOST_MASK 0x000000ff -#define WLAN_MBOX_INT_STATUS_HOST_GET(x) (((x) & WLAN_MBOX_INT_STATUS_HOST_MASK) >> WLAN_MBOX_INT_STATUS_HOST_LSB) -#define WLAN_MBOX_INT_STATUS_HOST_SET(x) (((x) << WLAN_MBOX_INT_STATUS_HOST_LSB) & WLAN_MBOX_INT_STATUS_HOST_MASK) - -#define WLAN_MBOX_INT_ENABLE_ADDRESS 0x0000005c -#define WLAN_MBOX_INT_ENABLE_OFFSET 0x0000005c -#define WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_MSB 31 -#define WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB 28 -#define WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK 0xf0000000 -#define WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_GET(x) (((x) & WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK) >> WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB) -#define WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_SET(x) (((x) << WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB) & WLAN_MBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK) -#define WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MSB 27 -#define WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB 24 -#define WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK 0x0f000000 -#define WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_GET(x) (((x) & WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK) >> WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB) -#define WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_SET(x) (((x) << WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB) & WLAN_MBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK) -#define WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_MSB 23 -#define WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB 20 -#define WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK 0x00f00000 -#define WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_GET(x) (((x) & WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK) >> WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB) -#define WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_SET(x) (((x) << WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB) & WLAN_MBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK) -#define WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_MSB 17 -#define WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_LSB 17 -#define WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_MASK 0x00020000 -#define WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_GET(x) (((x) & WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_MASK) >> WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_LSB) -#define WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_SET(x) (((x) << WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_LSB) & WLAN_MBOX_INT_ENABLE_TX_OVERFLOW_MASK) -#define WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_MSB 16 -#define WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_LSB 16 -#define WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_MASK 0x00010000 -#define WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_GET(x) (((x) & WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_MASK) >> WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_LSB) -#define WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_SET(x) (((x) << WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_LSB) & WLAN_MBOX_INT_ENABLE_RX_UNDERFLOW_MASK) -#define WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_MSB 15 -#define WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_LSB 12 -#define WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_MASK 0x0000f000 -#define WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_GET(x) (((x) & WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_MASK) >> WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_LSB) -#define WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_SET(x) (((x) << WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_LSB) & WLAN_MBOX_INT_ENABLE_TX_NOT_EMPTY_MASK) -#define WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_MSB 11 -#define WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_LSB 8 -#define WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_MASK 0x00000f00 -#define WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_GET(x) (((x) & WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_MASK) >> WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_LSB) -#define WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_SET(x) (((x) << WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_LSB) & WLAN_MBOX_INT_ENABLE_RX_NOT_FULL_MASK) -#define WLAN_MBOX_INT_ENABLE_HOST_MSB 7 -#define WLAN_MBOX_INT_ENABLE_HOST_LSB 0 -#define WLAN_MBOX_INT_ENABLE_HOST_MASK 0x000000ff -#define WLAN_MBOX_INT_ENABLE_HOST_GET(x) (((x) & WLAN_MBOX_INT_ENABLE_HOST_MASK) >> WLAN_MBOX_INT_ENABLE_HOST_LSB) -#define WLAN_MBOX_INT_ENABLE_HOST_SET(x) (((x) << WLAN_MBOX_INT_ENABLE_HOST_LSB) & WLAN_MBOX_INT_ENABLE_HOST_MASK) - -#define WLAN_INT_HOST_ADDRESS 0x00000060 -#define WLAN_INT_HOST_OFFSET 0x00000060 -#define WLAN_INT_HOST_VECTOR_MSB 7 -#define WLAN_INT_HOST_VECTOR_LSB 0 -#define WLAN_INT_HOST_VECTOR_MASK 0x000000ff -#define WLAN_INT_HOST_VECTOR_GET(x) (((x) & WLAN_INT_HOST_VECTOR_MASK) >> WLAN_INT_HOST_VECTOR_LSB) -#define WLAN_INT_HOST_VECTOR_SET(x) (((x) << WLAN_INT_HOST_VECTOR_LSB) & WLAN_INT_HOST_VECTOR_MASK) - -#define WLAN_LOCAL_COUNT_ADDRESS 0x00000080 -#define WLAN_LOCAL_COUNT_OFFSET 0x00000080 -#define WLAN_LOCAL_COUNT_VALUE_MSB 7 -#define WLAN_LOCAL_COUNT_VALUE_LSB 0 -#define WLAN_LOCAL_COUNT_VALUE_MASK 0x000000ff -#define WLAN_LOCAL_COUNT_VALUE_GET(x) (((x) & WLAN_LOCAL_COUNT_VALUE_MASK) >> WLAN_LOCAL_COUNT_VALUE_LSB) -#define WLAN_LOCAL_COUNT_VALUE_SET(x) (((x) << WLAN_LOCAL_COUNT_VALUE_LSB) & WLAN_LOCAL_COUNT_VALUE_MASK) - -#define WLAN_COUNT_INC_ADDRESS 0x000000a0 -#define WLAN_COUNT_INC_OFFSET 0x000000a0 -#define WLAN_COUNT_INC_VALUE_MSB 7 -#define WLAN_COUNT_INC_VALUE_LSB 0 -#define WLAN_COUNT_INC_VALUE_MASK 0x000000ff -#define WLAN_COUNT_INC_VALUE_GET(x) (((x) & WLAN_COUNT_INC_VALUE_MASK) >> WLAN_COUNT_INC_VALUE_LSB) -#define WLAN_COUNT_INC_VALUE_SET(x) (((x) << WLAN_COUNT_INC_VALUE_LSB) & WLAN_COUNT_INC_VALUE_MASK) - -#define WLAN_LOCAL_SCRATCH_ADDRESS 0x000000c0 -#define WLAN_LOCAL_SCRATCH_OFFSET 0x000000c0 -#define WLAN_LOCAL_SCRATCH_VALUE_MSB 7 -#define WLAN_LOCAL_SCRATCH_VALUE_LSB 0 -#define WLAN_LOCAL_SCRATCH_VALUE_MASK 0x000000ff -#define WLAN_LOCAL_SCRATCH_VALUE_GET(x) (((x) & WLAN_LOCAL_SCRATCH_VALUE_MASK) >> WLAN_LOCAL_SCRATCH_VALUE_LSB) -#define WLAN_LOCAL_SCRATCH_VALUE_SET(x) (((x) << WLAN_LOCAL_SCRATCH_VALUE_LSB) & WLAN_LOCAL_SCRATCH_VALUE_MASK) - -#define WLAN_USE_LOCAL_BUS_ADDRESS 0x000000e0 -#define WLAN_USE_LOCAL_BUS_OFFSET 0x000000e0 -#define WLAN_USE_LOCAL_BUS_PIN_INIT_MSB 0 -#define WLAN_USE_LOCAL_BUS_PIN_INIT_LSB 0 -#define WLAN_USE_LOCAL_BUS_PIN_INIT_MASK 0x00000001 -#define WLAN_USE_LOCAL_BUS_PIN_INIT_GET(x) (((x) & WLAN_USE_LOCAL_BUS_PIN_INIT_MASK) >> WLAN_USE_LOCAL_BUS_PIN_INIT_LSB) -#define WLAN_USE_LOCAL_BUS_PIN_INIT_SET(x) (((x) << WLAN_USE_LOCAL_BUS_PIN_INIT_LSB) & WLAN_USE_LOCAL_BUS_PIN_INIT_MASK) - -#define WLAN_SDIO_CONFIG_ADDRESS 0x000000e4 -#define WLAN_SDIO_CONFIG_OFFSET 0x000000e4 -#define WLAN_SDIO_CONFIG_CCCR_IOR1_MSB 0 -#define WLAN_SDIO_CONFIG_CCCR_IOR1_LSB 0 -#define WLAN_SDIO_CONFIG_CCCR_IOR1_MASK 0x00000001 -#define WLAN_SDIO_CONFIG_CCCR_IOR1_GET(x) (((x) & WLAN_SDIO_CONFIG_CCCR_IOR1_MASK) >> WLAN_SDIO_CONFIG_CCCR_IOR1_LSB) -#define WLAN_SDIO_CONFIG_CCCR_IOR1_SET(x) (((x) << WLAN_SDIO_CONFIG_CCCR_IOR1_LSB) & WLAN_SDIO_CONFIG_CCCR_IOR1_MASK) - -#define WLAN_MBOX_DEBUG_ADDRESS 0x000000e8 -#define WLAN_MBOX_DEBUG_OFFSET 0x000000e8 -#define WLAN_MBOX_DEBUG_SEL_MSB 2 -#define WLAN_MBOX_DEBUG_SEL_LSB 0 -#define WLAN_MBOX_DEBUG_SEL_MASK 0x00000007 -#define WLAN_MBOX_DEBUG_SEL_GET(x) (((x) & WLAN_MBOX_DEBUG_SEL_MASK) >> WLAN_MBOX_DEBUG_SEL_LSB) -#define WLAN_MBOX_DEBUG_SEL_SET(x) (((x) << WLAN_MBOX_DEBUG_SEL_LSB) & WLAN_MBOX_DEBUG_SEL_MASK) - -#define WLAN_MBOX_FIFO_RESET_ADDRESS 0x000000ec -#define WLAN_MBOX_FIFO_RESET_OFFSET 0x000000ec -#define WLAN_MBOX_FIFO_RESET_INIT_MSB 0 -#define WLAN_MBOX_FIFO_RESET_INIT_LSB 0 -#define WLAN_MBOX_FIFO_RESET_INIT_MASK 0x00000001 -#define WLAN_MBOX_FIFO_RESET_INIT_GET(x) (((x) & WLAN_MBOX_FIFO_RESET_INIT_MASK) >> WLAN_MBOX_FIFO_RESET_INIT_LSB) -#define WLAN_MBOX_FIFO_RESET_INIT_SET(x) (((x) << WLAN_MBOX_FIFO_RESET_INIT_LSB) & WLAN_MBOX_FIFO_RESET_INIT_MASK) - -#define WLAN_MBOX_TXFIFO_POP_ADDRESS 0x000000f0 -#define WLAN_MBOX_TXFIFO_POP_OFFSET 0x000000f0 -#define WLAN_MBOX_TXFIFO_POP_DATA_MSB 0 -#define WLAN_MBOX_TXFIFO_POP_DATA_LSB 0 -#define WLAN_MBOX_TXFIFO_POP_DATA_MASK 0x00000001 -#define WLAN_MBOX_TXFIFO_POP_DATA_GET(x) (((x) & WLAN_MBOX_TXFIFO_POP_DATA_MASK) >> WLAN_MBOX_TXFIFO_POP_DATA_LSB) -#define WLAN_MBOX_TXFIFO_POP_DATA_SET(x) (((x) << WLAN_MBOX_TXFIFO_POP_DATA_LSB) & WLAN_MBOX_TXFIFO_POP_DATA_MASK) - -#define WLAN_MBOX_RXFIFO_POP_ADDRESS 0x00000100 -#define WLAN_MBOX_RXFIFO_POP_OFFSET 0x00000100 -#define WLAN_MBOX_RXFIFO_POP_DATA_MSB 0 -#define WLAN_MBOX_RXFIFO_POP_DATA_LSB 0 -#define WLAN_MBOX_RXFIFO_POP_DATA_MASK 0x00000001 -#define WLAN_MBOX_RXFIFO_POP_DATA_GET(x) (((x) & WLAN_MBOX_RXFIFO_POP_DATA_MASK) >> WLAN_MBOX_RXFIFO_POP_DATA_LSB) -#define WLAN_MBOX_RXFIFO_POP_DATA_SET(x) (((x) << WLAN_MBOX_RXFIFO_POP_DATA_LSB) & WLAN_MBOX_RXFIFO_POP_DATA_MASK) - -#define WLAN_SDIO_DEBUG_ADDRESS 0x00000110 -#define WLAN_SDIO_DEBUG_OFFSET 0x00000110 -#define WLAN_SDIO_DEBUG_SEL_MSB 3 -#define WLAN_SDIO_DEBUG_SEL_LSB 0 -#define WLAN_SDIO_DEBUG_SEL_MASK 0x0000000f -#define WLAN_SDIO_DEBUG_SEL_GET(x) (((x) & WLAN_SDIO_DEBUG_SEL_MASK) >> WLAN_SDIO_DEBUG_SEL_LSB) -#define WLAN_SDIO_DEBUG_SEL_SET(x) (((x) << WLAN_SDIO_DEBUG_SEL_LSB) & WLAN_SDIO_DEBUG_SEL_MASK) - -#define WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS 0x00000114 -#define WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_OFFSET 0x00000114 -#define WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MSB 27 -#define WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB 2 -#define WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc -#define WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) -#define WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_GMBOX0_DMA_RX_DESCRIPTOR_BASE_ADDRESS_MASK) - -#define WLAN_GMBOX0_DMA_RX_CONTROL_ADDRESS 0x00000118 -#define WLAN_GMBOX0_DMA_RX_CONTROL_OFFSET 0x00000118 -#define WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_MSB 2 -#define WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_LSB 2 -#define WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_MASK 0x00000004 -#define WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_GET(x) (((x) & WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_MASK) >> WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_LSB) -#define WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_SET(x) (((x) << WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_LSB) & WLAN_GMBOX0_DMA_RX_CONTROL_RESUME_MASK) -#define WLAN_GMBOX0_DMA_RX_CONTROL_START_MSB 1 -#define WLAN_GMBOX0_DMA_RX_CONTROL_START_LSB 1 -#define WLAN_GMBOX0_DMA_RX_CONTROL_START_MASK 0x00000002 -#define WLAN_GMBOX0_DMA_RX_CONTROL_START_GET(x) (((x) & WLAN_GMBOX0_DMA_RX_CONTROL_START_MASK) >> WLAN_GMBOX0_DMA_RX_CONTROL_START_LSB) -#define WLAN_GMBOX0_DMA_RX_CONTROL_START_SET(x) (((x) << WLAN_GMBOX0_DMA_RX_CONTROL_START_LSB) & WLAN_GMBOX0_DMA_RX_CONTROL_START_MASK) -#define WLAN_GMBOX0_DMA_RX_CONTROL_STOP_MSB 0 -#define WLAN_GMBOX0_DMA_RX_CONTROL_STOP_LSB 0 -#define WLAN_GMBOX0_DMA_RX_CONTROL_STOP_MASK 0x00000001 -#define WLAN_GMBOX0_DMA_RX_CONTROL_STOP_GET(x) (((x) & WLAN_GMBOX0_DMA_RX_CONTROL_STOP_MASK) >> WLAN_GMBOX0_DMA_RX_CONTROL_STOP_LSB) -#define WLAN_GMBOX0_DMA_RX_CONTROL_STOP_SET(x) (((x) << WLAN_GMBOX0_DMA_RX_CONTROL_STOP_LSB) & WLAN_GMBOX0_DMA_RX_CONTROL_STOP_MASK) - -#define WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS 0x0000011c -#define WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_OFFSET 0x0000011c -#define WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MSB 27 -#define WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB 2 -#define WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK 0x0ffffffc -#define WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_GET(x) (((x) & WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) >> WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) -#define WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_SET(x) (((x) << WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_LSB) & WLAN_GMBOX0_DMA_TX_DESCRIPTOR_BASE_ADDRESS_MASK) - -#define WLAN_GMBOX0_DMA_TX_CONTROL_ADDRESS 0x00000120 -#define WLAN_GMBOX0_DMA_TX_CONTROL_OFFSET 0x00000120 -#define WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_MSB 2 -#define WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_LSB 2 -#define WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_MASK 0x00000004 -#define WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_GET(x) (((x) & WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_MASK) >> WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_LSB) -#define WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_SET(x) (((x) << WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_LSB) & WLAN_GMBOX0_DMA_TX_CONTROL_RESUME_MASK) -#define WLAN_GMBOX0_DMA_TX_CONTROL_START_MSB 1 -#define WLAN_GMBOX0_DMA_TX_CONTROL_START_LSB 1 -#define WLAN_GMBOX0_DMA_TX_CONTROL_START_MASK 0x00000002 -#define WLAN_GMBOX0_DMA_TX_CONTROL_START_GET(x) (((x) & WLAN_GMBOX0_DMA_TX_CONTROL_START_MASK) >> WLAN_GMBOX0_DMA_TX_CONTROL_START_LSB) -#define WLAN_GMBOX0_DMA_TX_CONTROL_START_SET(x) (((x) << WLAN_GMBOX0_DMA_TX_CONTROL_START_LSB) & WLAN_GMBOX0_DMA_TX_CONTROL_START_MASK) -#define WLAN_GMBOX0_DMA_TX_CONTROL_STOP_MSB 0 -#define WLAN_GMBOX0_DMA_TX_CONTROL_STOP_LSB 0 -#define WLAN_GMBOX0_DMA_TX_CONTROL_STOP_MASK 0x00000001 -#define WLAN_GMBOX0_DMA_TX_CONTROL_STOP_GET(x) (((x) & WLAN_GMBOX0_DMA_TX_CONTROL_STOP_MASK) >> WLAN_GMBOX0_DMA_TX_CONTROL_STOP_LSB) -#define WLAN_GMBOX0_DMA_TX_CONTROL_STOP_SET(x) (((x) << WLAN_GMBOX0_DMA_TX_CONTROL_STOP_LSB) & WLAN_GMBOX0_DMA_TX_CONTROL_STOP_MASK) - -#define WLAN_GMBOX_INT_STATUS_ADDRESS 0x00000124 -#define WLAN_GMBOX_INT_STATUS_OFFSET 0x00000124 -#define WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_MSB 6 -#define WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_LSB 6 -#define WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_MASK 0x00000040 -#define WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_GET(x) (((x) & WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_MASK) >> WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_LSB) -#define WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_SET(x) (((x) << WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_LSB) & WLAN_GMBOX_INT_STATUS_TX_OVERFLOW_MASK) -#define WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_MSB 5 -#define WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_LSB 5 -#define WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_MASK 0x00000020 -#define WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_GET(x) (((x) & WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_MASK) >> WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_LSB) -#define WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_SET(x) (((x) << WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_LSB) & WLAN_GMBOX_INT_STATUS_RX_UNDERFLOW_MASK) -#define WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_MSB 4 -#define WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_LSB 4 -#define WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_MASK 0x00000010 -#define WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_GET(x) (((x) & WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_MASK) >> WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_LSB) -#define WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_SET(x) (((x) << WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_LSB) & WLAN_GMBOX_INT_STATUS_RX_DMA_COMPLETE_MASK) -#define WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MSB 3 -#define WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB 3 -#define WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK 0x00000008 -#define WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_GET(x) (((x) & WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK) >> WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB) -#define WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_SET(x) (((x) << WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_LSB) & WLAN_GMBOX_INT_STATUS_TX_DMA_EOM_COMPLETE_MASK) -#define WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_MSB 2 -#define WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_LSB 2 -#define WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_MASK 0x00000004 -#define WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_GET(x) (((x) & WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_MASK) >> WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_LSB) -#define WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_SET(x) (((x) << WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_LSB) & WLAN_GMBOX_INT_STATUS_TX_DMA_COMPLETE_MASK) -#define WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_MSB 1 -#define WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_LSB 1 -#define WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_MASK 0x00000002 -#define WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_GET(x) (((x) & WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_MASK) >> WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_LSB) -#define WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_SET(x) (((x) << WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_LSB) & WLAN_GMBOX_INT_STATUS_TX_NOT_EMPTY_MASK) -#define WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_MSB 0 -#define WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_LSB 0 -#define WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_MASK 0x00000001 -#define WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_GET(x) (((x) & WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_MASK) >> WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_LSB) -#define WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_SET(x) (((x) << WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_LSB) & WLAN_GMBOX_INT_STATUS_RX_NOT_FULL_MASK) - -#define WLAN_GMBOX_INT_ENABLE_ADDRESS 0x00000128 -#define WLAN_GMBOX_INT_ENABLE_OFFSET 0x00000128 -#define WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_MSB 6 -#define WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_LSB 6 -#define WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_MASK 0x00000040 -#define WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_GET(x) (((x) & WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_MASK) >> WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_LSB) -#define WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_SET(x) (((x) << WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_LSB) & WLAN_GMBOX_INT_ENABLE_TX_OVERFLOW_MASK) -#define WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_MSB 5 -#define WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_LSB 5 -#define WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_MASK 0x00000020 -#define WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_GET(x) (((x) & WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_MASK) >> WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_LSB) -#define WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_SET(x) (((x) << WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_LSB) & WLAN_GMBOX_INT_ENABLE_RX_UNDERFLOW_MASK) -#define WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MSB 4 -#define WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB 4 -#define WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK 0x00000010 -#define WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_GET(x) (((x) & WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK) >> WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB) -#define WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_SET(x) (((x) << WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_LSB) & WLAN_GMBOX_INT_ENABLE_RX_DMA_COMPLETE_MASK) -#define WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MSB 3 -#define WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB 3 -#define WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK 0x00000008 -#define WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_GET(x) (((x) & WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK) >> WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB) -#define WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_SET(x) (((x) << WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_LSB) & WLAN_GMBOX_INT_ENABLE_TX_DMA_EOM_COMPLETE_MASK) -#define WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MSB 2 -#define WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB 2 -#define WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK 0x00000004 -#define WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_GET(x) (((x) & WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK) >> WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB) -#define WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_SET(x) (((x) << WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_LSB) & WLAN_GMBOX_INT_ENABLE_TX_DMA_COMPLETE_MASK) -#define WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_MSB 1 -#define WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_LSB 1 -#define WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_MASK 0x00000002 -#define WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_GET(x) (((x) & WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_MASK) >> WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_LSB) -#define WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_SET(x) (((x) << WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_LSB) & WLAN_GMBOX_INT_ENABLE_TX_NOT_EMPTY_MASK) -#define WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_MSB 0 -#define WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_LSB 0 -#define WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_MASK 0x00000001 -#define WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_GET(x) (((x) & WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_MASK) >> WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_LSB) -#define WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_SET(x) (((x) << WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_LSB) & WLAN_GMBOX_INT_ENABLE_RX_NOT_FULL_MASK) - -#define WLAN_HOST_IF_WINDOW_ADDRESS 0x00002000 -#define WLAN_HOST_IF_WINDOW_OFFSET 0x00002000 -#define WLAN_HOST_IF_WINDOW_DATA_MSB 7 -#define WLAN_HOST_IF_WINDOW_DATA_LSB 0 -#define WLAN_HOST_IF_WINDOW_DATA_MASK 0x000000ff -#define WLAN_HOST_IF_WINDOW_DATA_GET(x) (((x) & WLAN_HOST_IF_WINDOW_DATA_MASK) >> WLAN_HOST_IF_WINDOW_DATA_LSB) -#define WLAN_HOST_IF_WINDOW_DATA_SET(x) (((x) << WLAN_HOST_IF_WINDOW_DATA_LSB) & WLAN_HOST_IF_WINDOW_DATA_MASK) - -#endif /* _MBOX_WLAN_REG_H_ */ diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_reg.h deleted file mode 100644 index fcafec8..0000000 --- a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_reg.h +++ /dev/null @@ -1,187 +0,0 @@ -// ------------------------------------------------------------------ -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -// ------------------------------------------------------------------ -//=================================================================== -// Author(s): ="Atheros" -//=================================================================== - - -#include "rtc_wlan_reg.h" - -#ifndef BT_HEADERS - -#define RESET_CONTROL_ADDRESS WLAN_RESET_CONTROL_ADDRESS -#define RESET_CONTROL_OFFSET WLAN_RESET_CONTROL_OFFSET -#define RESET_CONTROL_DEBUG_UART_RST_MSB WLAN_RESET_CONTROL_DEBUG_UART_RST_MSB -#define RESET_CONTROL_DEBUG_UART_RST_LSB WLAN_RESET_CONTROL_DEBUG_UART_RST_LSB -#define RESET_CONTROL_DEBUG_UART_RST_MASK WLAN_RESET_CONTROL_DEBUG_UART_RST_MASK -#define RESET_CONTROL_DEBUG_UART_RST_GET(x) WLAN_RESET_CONTROL_DEBUG_UART_RST_GET(x) -#define RESET_CONTROL_DEBUG_UART_RST_SET(x) WLAN_RESET_CONTROL_DEBUG_UART_RST_SET(x) -#define RESET_CONTROL_BB_COLD_RST_MSB WLAN_RESET_CONTROL_BB_COLD_RST_MSB -#define RESET_CONTROL_BB_COLD_RST_LSB WLAN_RESET_CONTROL_BB_COLD_RST_LSB -#define RESET_CONTROL_BB_COLD_RST_MASK WLAN_RESET_CONTROL_BB_COLD_RST_MASK -#define RESET_CONTROL_BB_COLD_RST_GET(x) WLAN_RESET_CONTROL_BB_COLD_RST_GET(x) -#define RESET_CONTROL_BB_COLD_RST_SET(x) WLAN_RESET_CONTROL_BB_COLD_RST_SET(x) -#define RESET_CONTROL_BB_WARM_RST_MSB WLAN_RESET_CONTROL_BB_WARM_RST_MSB -#define RESET_CONTROL_BB_WARM_RST_LSB WLAN_RESET_CONTROL_BB_WARM_RST_LSB -#define RESET_CONTROL_BB_WARM_RST_MASK WLAN_RESET_CONTROL_BB_WARM_RST_MASK -#define RESET_CONTROL_BB_WARM_RST_GET(x) WLAN_RESET_CONTROL_BB_WARM_RST_GET(x) -#define RESET_CONTROL_BB_WARM_RST_SET(x) WLAN_RESET_CONTROL_BB_WARM_RST_SET(x) -#define RESET_CONTROL_CPU_INIT_RESET_MSB WLAN_RESET_CONTROL_CPU_INIT_RESET_MSB -#define RESET_CONTROL_CPU_INIT_RESET_LSB WLAN_RESET_CONTROL_CPU_INIT_RESET_LSB -#define RESET_CONTROL_CPU_INIT_RESET_MASK WLAN_RESET_CONTROL_CPU_INIT_RESET_MASK -#define RESET_CONTROL_CPU_INIT_RESET_GET(x) WLAN_RESET_CONTROL_CPU_INIT_RESET_GET(x) -#define RESET_CONTROL_CPU_INIT_RESET_SET(x) WLAN_RESET_CONTROL_CPU_INIT_RESET_SET(x) -#define RESET_CONTROL_VMC_REMAP_RESET_MSB WLAN_RESET_CONTROL_VMC_REMAP_RESET_MSB -#define RESET_CONTROL_VMC_REMAP_RESET_LSB WLAN_RESET_CONTROL_VMC_REMAP_RESET_LSB -#define RESET_CONTROL_VMC_REMAP_RESET_MASK WLAN_RESET_CONTROL_VMC_REMAP_RESET_MASK -#define RESET_CONTROL_VMC_REMAP_RESET_GET(x) WLAN_RESET_CONTROL_VMC_REMAP_RESET_GET(x) -#define RESET_CONTROL_VMC_REMAP_RESET_SET(x) WLAN_RESET_CONTROL_VMC_REMAP_RESET_SET(x) -#define RESET_CONTROL_RST_OUT_MSB WLAN_RESET_CONTROL_RST_OUT_MSB -#define RESET_CONTROL_RST_OUT_LSB WLAN_RESET_CONTROL_RST_OUT_LSB -#define RESET_CONTROL_RST_OUT_MASK WLAN_RESET_CONTROL_RST_OUT_MASK -#define RESET_CONTROL_RST_OUT_GET(x) WLAN_RESET_CONTROL_RST_OUT_GET(x) -#define RESET_CONTROL_RST_OUT_SET(x) WLAN_RESET_CONTROL_RST_OUT_SET(x) -#define RESET_CONTROL_COLD_RST_MSB WLAN_RESET_CONTROL_COLD_RST_MSB -#define RESET_CONTROL_COLD_RST_LSB WLAN_RESET_CONTROL_COLD_RST_LSB -#define RESET_CONTROL_COLD_RST_MASK WLAN_RESET_CONTROL_COLD_RST_MASK -#define RESET_CONTROL_COLD_RST_GET(x) WLAN_RESET_CONTROL_COLD_RST_GET(x) -#define RESET_CONTROL_COLD_RST_SET(x) WLAN_RESET_CONTROL_COLD_RST_SET(x) -#define RESET_CONTROL_WARM_RST_MSB WLAN_RESET_CONTROL_WARM_RST_MSB -#define RESET_CONTROL_WARM_RST_LSB WLAN_RESET_CONTROL_WARM_RST_LSB -#define RESET_CONTROL_WARM_RST_MASK WLAN_RESET_CONTROL_WARM_RST_MASK -#define RESET_CONTROL_WARM_RST_GET(x) WLAN_RESET_CONTROL_WARM_RST_GET(x) -#define RESET_CONTROL_WARM_RST_SET(x) WLAN_RESET_CONTROL_WARM_RST_SET(x) -#define RESET_CONTROL_CPU_WARM_RST_MSB WLAN_RESET_CONTROL_CPU_WARM_RST_MSB -#define RESET_CONTROL_CPU_WARM_RST_LSB WLAN_RESET_CONTROL_CPU_WARM_RST_LSB -#define RESET_CONTROL_CPU_WARM_RST_MASK WLAN_RESET_CONTROL_CPU_WARM_RST_MASK -#define RESET_CONTROL_CPU_WARM_RST_GET(x) WLAN_RESET_CONTROL_CPU_WARM_RST_GET(x) -#define RESET_CONTROL_CPU_WARM_RST_SET(x) WLAN_RESET_CONTROL_CPU_WARM_RST_SET(x) -#define RESET_CONTROL_MAC_COLD_RST_MSB WLAN_RESET_CONTROL_MAC_COLD_RST_MSB -#define RESET_CONTROL_MAC_COLD_RST_LSB WLAN_RESET_CONTROL_MAC_COLD_RST_LSB -#define RESET_CONTROL_MAC_COLD_RST_MASK WLAN_RESET_CONTROL_MAC_COLD_RST_MASK -#define RESET_CONTROL_MAC_COLD_RST_GET(x) WLAN_RESET_CONTROL_MAC_COLD_RST_GET(x) -#define RESET_CONTROL_MAC_COLD_RST_SET(x) WLAN_RESET_CONTROL_MAC_COLD_RST_SET(x) -#define RESET_CONTROL_MAC_WARM_RST_MSB WLAN_RESET_CONTROL_MAC_WARM_RST_MSB -#define RESET_CONTROL_MAC_WARM_RST_LSB WLAN_RESET_CONTROL_MAC_WARM_RST_LSB -#define RESET_CONTROL_MAC_WARM_RST_MASK WLAN_RESET_CONTROL_MAC_WARM_RST_MASK -#define RESET_CONTROL_MAC_WARM_RST_GET(x) WLAN_RESET_CONTROL_MAC_WARM_RST_GET(x) -#define RESET_CONTROL_MAC_WARM_RST_SET(x) WLAN_RESET_CONTROL_MAC_WARM_RST_SET(x) -#define RESET_CONTROL_MBOX_RST_MSB WLAN_RESET_CONTROL_MBOX_RST_MSB -#define RESET_CONTROL_MBOX_RST_LSB WLAN_RESET_CONTROL_MBOX_RST_LSB -#define RESET_CONTROL_MBOX_RST_MASK WLAN_RESET_CONTROL_MBOX_RST_MASK -#define RESET_CONTROL_MBOX_RST_GET(x) WLAN_RESET_CONTROL_MBOX_RST_GET(x) -#define RESET_CONTROL_MBOX_RST_SET(x) WLAN_RESET_CONTROL_MBOX_RST_SET(x) -#define RESET_CONTROL_UART_RST_MSB WLAN_RESET_CONTROL_UART_RST_MSB -#define RESET_CONTROL_UART_RST_LSB WLAN_RESET_CONTROL_UART_RST_LSB -#define RESET_CONTROL_UART_RST_MASK WLAN_RESET_CONTROL_UART_RST_MASK -#define RESET_CONTROL_UART_RST_GET(x) WLAN_RESET_CONTROL_UART_RST_GET(x) -#define RESET_CONTROL_UART_RST_SET(x) WLAN_RESET_CONTROL_UART_RST_SET(x) -#define RESET_CONTROL_SI0_RST_MSB WLAN_RESET_CONTROL_SI0_RST_MSB -#define RESET_CONTROL_SI0_RST_LSB WLAN_RESET_CONTROL_SI0_RST_LSB -#define RESET_CONTROL_SI0_RST_MASK WLAN_RESET_CONTROL_SI0_RST_MASK -#define RESET_CONTROL_SI0_RST_GET(x) WLAN_RESET_CONTROL_SI0_RST_GET(x) -#define RESET_CONTROL_SI0_RST_SET(x) WLAN_RESET_CONTROL_SI0_RST_SET(x) -#define CPU_CLOCK_ADDRESS WLAN_CPU_CLOCK_ADDRESS -#define CPU_CLOCK_OFFSET WLAN_CPU_CLOCK_OFFSET -#define CPU_CLOCK_STANDARD_MSB WLAN_CPU_CLOCK_STANDARD_MSB -#define CPU_CLOCK_STANDARD_LSB WLAN_CPU_CLOCK_STANDARD_LSB -#define CPU_CLOCK_STANDARD_MASK WLAN_CPU_CLOCK_STANDARD_MASK -#define CPU_CLOCK_STANDARD_GET(x) WLAN_CPU_CLOCK_STANDARD_GET(x) -#define CPU_CLOCK_STANDARD_SET(x) WLAN_CPU_CLOCK_STANDARD_SET(x) -#define CLOCK_OUT_ADDRESS WLAN_CLOCK_OUT_ADDRESS -#define CLOCK_OUT_OFFSET WLAN_CLOCK_OUT_OFFSET -#define CLOCK_OUT_SELECT_MSB WLAN_CLOCK_OUT_SELECT_MSB -#define CLOCK_OUT_SELECT_LSB WLAN_CLOCK_OUT_SELECT_LSB -#define CLOCK_OUT_SELECT_MASK WLAN_CLOCK_OUT_SELECT_MASK -#define CLOCK_OUT_SELECT_GET(x) WLAN_CLOCK_OUT_SELECT_GET(x) -#define CLOCK_OUT_SELECT_SET(x) WLAN_CLOCK_OUT_SELECT_SET(x) -#define CLOCK_CONTROL_ADDRESS WLAN_CLOCK_CONTROL_ADDRESS -#define CLOCK_CONTROL_OFFSET WLAN_CLOCK_CONTROL_OFFSET -#define CLOCK_CONTROL_LF_CLK32_MSB WLAN_CLOCK_CONTROL_LF_CLK32_MSB -#define CLOCK_CONTROL_LF_CLK32_LSB WLAN_CLOCK_CONTROL_LF_CLK32_LSB -#define CLOCK_CONTROL_LF_CLK32_MASK WLAN_CLOCK_CONTROL_LF_CLK32_MASK -#define CLOCK_CONTROL_LF_CLK32_GET(x) WLAN_CLOCK_CONTROL_LF_CLK32_GET(x) -#define CLOCK_CONTROL_LF_CLK32_SET(x) WLAN_CLOCK_CONTROL_LF_CLK32_SET(x) -#define CLOCK_CONTROL_SI0_CLK_MSB WLAN_CLOCK_CONTROL_SI0_CLK_MSB -#define CLOCK_CONTROL_SI0_CLK_LSB WLAN_CLOCK_CONTROL_SI0_CLK_LSB -#define CLOCK_CONTROL_SI0_CLK_MASK WLAN_CLOCK_CONTROL_SI0_CLK_MASK -#define CLOCK_CONTROL_SI0_CLK_GET(x) WLAN_CLOCK_CONTROL_SI0_CLK_GET(x) -#define CLOCK_CONTROL_SI0_CLK_SET(x) WLAN_CLOCK_CONTROL_SI0_CLK_SET(x) -#define RESET_CAUSE_ADDRESS WLAN_RESET_CAUSE_ADDRESS -#define RESET_CAUSE_OFFSET WLAN_RESET_CAUSE_OFFSET -#define RESET_CAUSE_LAST_MSB WLAN_RESET_CAUSE_LAST_MSB -#define RESET_CAUSE_LAST_LSB WLAN_RESET_CAUSE_LAST_LSB -#define RESET_CAUSE_LAST_MASK WLAN_RESET_CAUSE_LAST_MASK -#define RESET_CAUSE_LAST_GET(x) WLAN_RESET_CAUSE_LAST_GET(x) -#define RESET_CAUSE_LAST_SET(x) WLAN_RESET_CAUSE_LAST_SET(x) -#define SYSTEM_SLEEP_ADDRESS WLAN_SYSTEM_SLEEP_ADDRESS -#define SYSTEM_SLEEP_OFFSET WLAN_SYSTEM_SLEEP_OFFSET -#define SYSTEM_SLEEP_HOST_IF_MSB WLAN_SYSTEM_SLEEP_HOST_IF_MSB -#define SYSTEM_SLEEP_HOST_IF_LSB WLAN_SYSTEM_SLEEP_HOST_IF_LSB -#define SYSTEM_SLEEP_HOST_IF_MASK WLAN_SYSTEM_SLEEP_HOST_IF_MASK -#define SYSTEM_SLEEP_HOST_IF_GET(x) WLAN_SYSTEM_SLEEP_HOST_IF_GET(x) -#define SYSTEM_SLEEP_HOST_IF_SET(x) WLAN_SYSTEM_SLEEP_HOST_IF_SET(x) -#define SYSTEM_SLEEP_MBOX_MSB WLAN_SYSTEM_SLEEP_MBOX_MSB -#define SYSTEM_SLEEP_MBOX_LSB WLAN_SYSTEM_SLEEP_MBOX_LSB -#define SYSTEM_SLEEP_MBOX_MASK WLAN_SYSTEM_SLEEP_MBOX_MASK -#define SYSTEM_SLEEP_MBOX_GET(x) WLAN_SYSTEM_SLEEP_MBOX_GET(x) -#define SYSTEM_SLEEP_MBOX_SET(x) WLAN_SYSTEM_SLEEP_MBOX_SET(x) -#define SYSTEM_SLEEP_MAC_IF_MSB WLAN_SYSTEM_SLEEP_MAC_IF_MSB -#define SYSTEM_SLEEP_MAC_IF_LSB WLAN_SYSTEM_SLEEP_MAC_IF_LSB -#define SYSTEM_SLEEP_MAC_IF_MASK WLAN_SYSTEM_SLEEP_MAC_IF_MASK -#define SYSTEM_SLEEP_MAC_IF_GET(x) WLAN_SYSTEM_SLEEP_MAC_IF_GET(x) -#define SYSTEM_SLEEP_MAC_IF_SET(x) WLAN_SYSTEM_SLEEP_MAC_IF_SET(x) -#define SYSTEM_SLEEP_LIGHT_MSB WLAN_SYSTEM_SLEEP_LIGHT_MSB -#define SYSTEM_SLEEP_LIGHT_LSB WLAN_SYSTEM_SLEEP_LIGHT_LSB -#define SYSTEM_SLEEP_LIGHT_MASK WLAN_SYSTEM_SLEEP_LIGHT_MASK -#define SYSTEM_SLEEP_LIGHT_GET(x) WLAN_SYSTEM_SLEEP_LIGHT_GET(x) -#define SYSTEM_SLEEP_LIGHT_SET(x) WLAN_SYSTEM_SLEEP_LIGHT_SET(x) -#define SYSTEM_SLEEP_DISABLE_MSB WLAN_SYSTEM_SLEEP_DISABLE_MSB -#define SYSTEM_SLEEP_DISABLE_LSB WLAN_SYSTEM_SLEEP_DISABLE_LSB -#define SYSTEM_SLEEP_DISABLE_MASK WLAN_SYSTEM_SLEEP_DISABLE_MASK -#define SYSTEM_SLEEP_DISABLE_GET(x) WLAN_SYSTEM_SLEEP_DISABLE_GET(x) -#define SYSTEM_SLEEP_DISABLE_SET(x) WLAN_SYSTEM_SLEEP_DISABLE_SET(x) -#define LPO_INIT_DIVIDEND_INT_ADDRESS WLAN_LPO_INIT_DIVIDEND_INT_ADDRESS -#define LPO_INIT_DIVIDEND_INT_OFFSET WLAN_LPO_INIT_DIVIDEND_INT_OFFSET -#define LPO_INIT_DIVIDEND_INT_VALUE_MSB WLAN_LPO_INIT_DIVIDEND_INT_VALUE_MSB -#define LPO_INIT_DIVIDEND_INT_VALUE_LSB WLAN_LPO_INIT_DIVIDEND_INT_VALUE_LSB -#define LPO_INIT_DIVIDEND_INT_VALUE_MASK WLAN_LPO_INIT_DIVIDEND_INT_VALUE_MASK -#define LPO_INIT_DIVIDEND_INT_VALUE_GET(x) WLAN_LPO_INIT_DIVIDEND_INT_VALUE_GET(x) -#define LPO_INIT_DIVIDEND_INT_VALUE_SET(x) WLAN_LPO_INIT_DIVIDEND_INT_VALUE_SET(x) -#define LPO_INIT_DIVIDEND_FRACTION_ADDRESS WLAN_LPO_INIT_DIVIDEND_FRACTION_ADDRESS -#define LPO_INIT_DIVIDEND_FRACTION_OFFSET WLAN_LPO_INIT_DIVIDEND_FRACTION_OFFSET -#define LPO_INIT_DIVIDEND_FRACTION_VALUE_MSB WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_MSB -#define LPO_INIT_DIVIDEND_FRACTION_VALUE_LSB WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_LSB -#define LPO_INIT_DIVIDEND_FRACTION_VALUE_MASK WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_MASK -#define LPO_INIT_DIVIDEND_FRACTION_VALUE_GET(x) WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_GET(x) -#define LPO_INIT_DIVIDEND_FRACTION_VALUE_SET(x) WLAN_LPO_INIT_DIVIDEND_FRACTION_VALUE_SET(x) -#define LPO_CAL_ADDRESS WLAN_LPO_CAL_ADDRESS -#define LPO_CAL_OFFSET WLAN_LPO_CAL_OFFSET -#define LPO_CAL_ENABLE_MSB WLAN_LPO_CAL_ENABLE_MSB -#define LPO_CAL_ENABLE_LSB WLAN_LPO_CAL_ENABLE_LSB -#define LPO_CAL_ENABLE_MASK WLAN_LPO_CAL_ENABLE_MASK -#define LPO_CAL_ENABLE_GET(x) WLAN_LPO_CAL_ENABLE_GET(x) -#define LPO_CAL_ENABLE_SET(x) WLAN_LPO_CAL_ENABLE_SET(x) -#define LPO_CAL_COUNT_MSB WLAN_LPO_CAL_COUNT_MSB -#define LPO_CAL_COUNT_LSB WLAN_LPO_CAL_COUNT_LSB -#define LPO_CAL_COUNT_MASK WLAN_LPO_CAL_COUNT_MASK -#define LPO_CAL_COUNT_GET(x) WLAN_LPO_CAL_COUNT_GET(x) -#define LPO_CAL_COUNT_SET(x) WLAN_LPO_CAL_COUNT_SET(x) - -#endif diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_wlan_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_wlan_reg.h deleted file mode 100644 index 5c048ff..0000000 --- a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/rtc_wlan_reg.h +++ /dev/null @@ -1,162 +0,0 @@ -// ------------------------------------------------------------------ -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -// ------------------------------------------------------------------ -//=================================================================== -// Author(s): ="Atheros" -//=================================================================== - - -#ifndef _RTC_WLAN_REG_REG_H_ -#define _RTC_WLAN_REG_REG_H_ - -#define WLAN_RESET_CONTROL_ADDRESS 0x00000000 -#define WLAN_RESET_CONTROL_OFFSET 0x00000000 -#define WLAN_RESET_CONTROL_DEBUG_UART_RST_MSB 14 -#define WLAN_RESET_CONTROL_DEBUG_UART_RST_LSB 14 -#define WLAN_RESET_CONTROL_DEBUG_UART_RST_MASK 0x00004000 -#define WLAN_RESET_CONTROL_DEBUG_UART_RST_GET(x) (((x) & WLAN_RESET_CONTROL_DEBUG_UART_RST_MASK) >> WLAN_RESET_CONTROL_DEBUG_UART_RST_LSB) -#define WLAN_RESET_CONTROL_DEBUG_UART_RST_SET(x) (((x) << WLAN_RESET_CONTROL_DEBUG_UART_RST_LSB) & WLAN_RESET_CONTROL_DEBUG_UART_RST_MASK) -#define WLAN_RESET_CONTROL_BB_COLD_RST_MSB 13 -#define WLAN_RESET_CONTROL_BB_COLD_RST_LSB 13 -#define WLAN_RESET_CONTROL_BB_COLD_RST_MASK 0x00002000 -#define WLAN_RESET_CONTROL_BB_COLD_RST_GET(x) (((x) & WLAN_RESET_CONTROL_BB_COLD_RST_MASK) >> WLAN_RESET_CONTROL_BB_COLD_RST_LSB) -#define WLAN_RESET_CONTROL_BB_COLD_RST_SET(x) (((x) << WLAN_RESET_CONTROL_BB_COLD_RST_LSB) & WLAN_RESET_CONTROL_BB_COLD_RST_MASK) -#define WLAN_RESET_CONTROL_BB_WARM_RST_MSB 12 -#define WLAN_RESET_CONTROL_BB_WARM_RST_LSB 12 -#define WLAN_RESET_CONTROL_BB_WARM_RST_MASK 0x00001000 -#define WLAN_RESET_CONTROL_BB_WARM_RST_GET(x) (((x) & WLAN_RESET_CONTROL_BB_WARM_RST_MASK) >> WLAN_RESET_CONTROL_BB_WARM_RST_LSB) -#define WLAN_RESET_CONTROL_BB_WARM_RST_SET(x) (((x) << WLAN_RESET_CONTROL_BB_WARM_RST_LSB) & WLAN_RESET_CONTROL_BB_WARM_RST_MASK) -#define WLAN_RESET_CONTROL_CPU_INIT_RESET_MSB 11 -#define WLAN_RESET_CONTROL_CPU_INIT_RESET_LSB 11 -#define WLAN_RESET_CONTROL_CPU_INIT_RESET_MASK 0x00000800 -#define WLAN_RESET_CONTROL_CPU_INIT_RESET_GET(x) (((x) & WLAN_RESET_CONTROL_CPU_INIT_RESET_MASK) >> WLAN_RESET_CONTROL_CPU_INIT_RESET_LSB) -#define WLAN_RESET_CONTROL_CPU_INIT_RESET_SET(x) (((x) << WLAN_RESET_CONTROL_CPU_INIT_RESET_LSB) & WLAN_RESET_CONTROL_CPU_INIT_RESET_MASK) -#define WLAN_RESET_CONTROL_VMC_REMAP_RESET_MSB 10 -#define WLAN_RESET_CONTROL_VMC_REMAP_RESET_LSB 10 -#define WLAN_RESET_CONTROL_VMC_REMAP_RESET_MASK 0x00000400 -#define WLAN_RESET_CONTROL_VMC_REMAP_RESET_GET(x) (((x) & WLAN_RESET_CONTROL_VMC_REMAP_RESET_MASK) >> WLAN_RESET_CONTROL_VMC_REMAP_RESET_LSB) -#define WLAN_RESET_CONTROL_VMC_REMAP_RESET_SET(x) (((x) << WLAN_RESET_CONTROL_VMC_REMAP_RESET_LSB) & WLAN_RESET_CONTROL_VMC_REMAP_RESET_MASK) -#define WLAN_RESET_CONTROL_RST_OUT_MSB 9 -#define WLAN_RESET_CONTROL_RST_OUT_LSB 9 -#define WLAN_RESET_CONTROL_RST_OUT_MASK 0x00000200 -#define WLAN_RESET_CONTROL_RST_OUT_GET(x) (((x) & WLAN_RESET_CONTROL_RST_OUT_MASK) >> WLAN_RESET_CONTROL_RST_OUT_LSB) -#define WLAN_RESET_CONTROL_RST_OUT_SET(x) (((x) << WLAN_RESET_CONTROL_RST_OUT_LSB) & WLAN_RESET_CONTROL_RST_OUT_MASK) -#define WLAN_RESET_CONTROL_COLD_RST_MSB 8 -#define WLAN_RESET_CONTROL_COLD_RST_LSB 8 -#define WLAN_RESET_CONTROL_COLD_RST_MASK 0x00000100 -#define WLAN_RESET_CONTROL_COLD_RST_GET(x) (((x) & WLAN_RESET_CONTROL_COLD_RST_MASK) >> WLAN_RESET_CONTROL_COLD_RST_LSB) -#define WLAN_RESET_CONTROL_COLD_RST_SET(x) (((x) << WLAN_RESET_CONTROL_COLD_RST_LSB) & WLAN_RESET_CONTROL_COLD_RST_MASK) -#define WLAN_RESET_CONTROL_WARM_RST_MSB 7 -#define WLAN_RESET_CONTROL_WARM_RST_LSB 7 -#define WLAN_RESET_CONTROL_WARM_RST_MASK 0x00000080 -#define WLAN_RESET_CONTROL_WARM_RST_GET(x) (((x) & WLAN_RESET_CONTROL_WARM_RST_MASK) >> WLAN_RESET_CONTROL_WARM_RST_LSB) -#define WLAN_RESET_CONTROL_WARM_RST_SET(x) (((x) << WLAN_RESET_CONTROL_WARM_RST_LSB) & WLAN_RESET_CONTROL_WARM_RST_MASK) -#define WLAN_RESET_CONTROL_CPU_WARM_RST_MSB 6 -#define WLAN_RESET_CONTROL_CPU_WARM_RST_LSB 6 -#define WLAN_RESET_CONTROL_CPU_WARM_RST_MASK 0x00000040 -#define WLAN_RESET_CONTROL_CPU_WARM_RST_GET(x) (((x) & WLAN_RESET_CONTROL_CPU_WARM_RST_MASK) >> WLAN_RESET_CONTROL_CPU_WARM_RST_LSB) -#define WLAN_RESET_CONTROL_CPU_WARM_RST_SET(x) (((x) << WLAN_RESET_CONTROL_CPU_WARM_RST_LSB) & WLAN_RESET_CONTROL_CPU_WARM_RST_MASK) -#define WLAN_RESET_CONTROL_MAC_COLD_RST_MSB 5 -#define WLAN_RESET_CONTROL_MAC_COLD_RST_LSB 5 -#define WLAN_RESET_CONTROL_MAC_COLD_RST_MASK 0x00000020 -#define WLAN_RESET_CONTROL_MAC_COLD_RST_GET(x) (((x) & WLAN_RESET_CONTROL_MAC_COLD_RST_MASK) >> WLAN_RESET_CONTROL_MAC_COLD_RST_LSB) -#define WLAN_RESET_CONTROL_MAC_COLD_RST_SET(x) (((x) << WLAN_RESET_CONTROL_MAC_COLD_RST_LSB) & WLAN_RESET_CONTROL_MAC_COLD_RST_MASK) -#define WLAN_RESET_CONTROL_MAC_WARM_RST_MSB 4 -#define WLAN_RESET_CONTROL_MAC_WARM_RST_LSB 4 -#define WLAN_RESET_CONTROL_MAC_WARM_RST_MASK 0x00000010 -#define WLAN_RESET_CONTROL_MAC_WARM_RST_GET(x) (((x) & WLAN_RESET_CONTROL_MAC_WARM_RST_MASK) >> WLAN_RESET_CONTROL_MAC_WARM_RST_LSB) -#define WLAN_RESET_CONTROL_MAC_WARM_RST_SET(x) (((x) << WLAN_RESET_CONTROL_MAC_WARM_RST_LSB) & WLAN_RESET_CONTROL_MAC_WARM_RST_MASK) -#define WLAN_RESET_CONTROL_MBOX_RST_MSB 2 -#define WLAN_RESET_CONTROL_MBOX_RST_LSB 2 -#define WLAN_RESET_CONTROL_MBOX_RST_MASK 0x00000004 -#define WLAN_RESET_CONTROL_MBOX_RST_GET(x) (((x) & WLAN_RESET_CONTROL_MBOX_RST_MASK) >> WLAN_RESET_CONTROL_MBOX_RST_LSB) -#define WLAN_RESET_CONTROL_MBOX_RST_SET(x) (((x) << WLAN_RESET_CONTROL_MBOX_RST_LSB) & WLAN_RESET_CONTROL_MBOX_RST_MASK) -#define WLAN_RESET_CONTROL_UART_RST_MSB 1 -#define WLAN_RESET_CONTROL_UART_RST_LSB 1 -#define WLAN_RESET_CONTROL_UART_RST_MASK 0x00000002 -#define WLAN_RESET_CONTROL_UART_RST_GET(x) (((x) & WLAN_RESET_CONTROL_UART_RST_MASK) >> WLAN_RESET_CONTROL_UART_RST_LSB) -#define WLAN_RESET_CONTROL_UART_RST_SET(x) (((x) << WLAN_RESET_CONTROL_UART_RST_LSB) & WLAN_RESET_CONTROL_UART_RST_MASK) -#define WLAN_RESET_CONTROL_SI0_RST_MSB 0 -#define WLAN_RESET_CONTROL_SI0_RST_LSB 0 -#define WLAN_RESET_CONTROL_SI0_RST_MASK 0x00000001 -#define WLAN_RESET_CONTROL_SI0_RST_GET(x) (((x) & WLAN_RESET_CONTROL_SI0_RST_MASK) >> WLAN_RESET_CONTROL_SI0_RST_LSB) -#define WLAN_RESET_CONTROL_SI0_RST_SET(x) (((x) << WLAN_RESET_CONTROL_SI0_RST_LSB) & WLAN_RESET_CONTROL_SI0_RST_MASK) - -#define WLAN_CPU_CLOCK_ADDRESS 0x00000020 -#define WLAN_CPU_CLOCK_OFFSET 0x00000020 -#define WLAN_CPU_CLOCK_STANDARD_MSB 1 -#define WLAN_CPU_CLOCK_STANDARD_LSB 0 -#define WLAN_CPU_CLOCK_STANDARD_MASK 0x00000003 -#define WLAN_CPU_CLOCK_STANDARD_GET(x) (((x) & WLAN_CPU_CLOCK_STANDARD_MASK) >> WLAN_CPU_CLOCK_STANDARD_LSB) -#define WLAN_CPU_CLOCK_STANDARD_SET(x) (((x) << WLAN_CPU_CLOCK_STANDARD_LSB) & WLAN_CPU_CLOCK_STANDARD_MASK) - -#define WLAN_CLOCK_CONTROL_ADDRESS 0x00000028 -#define WLAN_CLOCK_CONTROL_OFFSET 0x00000028 -#define WLAN_CLOCK_CONTROL_LF_CLK32_MSB 2 -#define WLAN_CLOCK_CONTROL_LF_CLK32_LSB 2 -#define WLAN_CLOCK_CONTROL_LF_CLK32_MASK 0x00000004 -#define WLAN_CLOCK_CONTROL_LF_CLK32_GET(x) (((x) & WLAN_CLOCK_CONTROL_LF_CLK32_MASK) >> WLAN_CLOCK_CONTROL_LF_CLK32_LSB) -#define WLAN_CLOCK_CONTROL_LF_CLK32_SET(x) (((x) << WLAN_CLOCK_CONTROL_LF_CLK32_LSB) & WLAN_CLOCK_CONTROL_LF_CLK32_MASK) -#define WLAN_CLOCK_CONTROL_SI0_CLK_MSB 0 -#define WLAN_CLOCK_CONTROL_SI0_CLK_LSB 0 -#define WLAN_CLOCK_CONTROL_SI0_CLK_MASK 0x00000001 -#define WLAN_CLOCK_CONTROL_SI0_CLK_GET(x) (((x) & WLAN_CLOCK_CONTROL_SI0_CLK_MASK) >> WLAN_CLOCK_CONTROL_SI0_CLK_LSB) -#define WLAN_CLOCK_CONTROL_SI0_CLK_SET(x) (((x) << WLAN_CLOCK_CONTROL_SI0_CLK_LSB) & WLAN_CLOCK_CONTROL_SI0_CLK_MASK) - -#define WLAN_SYSTEM_SLEEP_ADDRESS 0x000000c4 -#define WLAN_SYSTEM_SLEEP_OFFSET 0x000000c4 -#define WLAN_SYSTEM_SLEEP_HOST_IF_MSB 4 -#define WLAN_SYSTEM_SLEEP_HOST_IF_LSB 4 -#define WLAN_SYSTEM_SLEEP_HOST_IF_MASK 0x00000010 -#define WLAN_SYSTEM_SLEEP_HOST_IF_GET(x) (((x) & WLAN_SYSTEM_SLEEP_HOST_IF_MASK) >> WLAN_SYSTEM_SLEEP_HOST_IF_LSB) -#define WLAN_SYSTEM_SLEEP_HOST_IF_SET(x) (((x) << WLAN_SYSTEM_SLEEP_HOST_IF_LSB) & WLAN_SYSTEM_SLEEP_HOST_IF_MASK) -#define WLAN_SYSTEM_SLEEP_MBOX_MSB 3 -#define WLAN_SYSTEM_SLEEP_MBOX_LSB 3 -#define WLAN_SYSTEM_SLEEP_MBOX_MASK 0x00000008 -#define WLAN_SYSTEM_SLEEP_MBOX_GET(x) (((x) & WLAN_SYSTEM_SLEEP_MBOX_MASK) >> WLAN_SYSTEM_SLEEP_MBOX_LSB) -#define WLAN_SYSTEM_SLEEP_MBOX_SET(x) (((x) << WLAN_SYSTEM_SLEEP_MBOX_LSB) & WLAN_SYSTEM_SLEEP_MBOX_MASK) -#define WLAN_SYSTEM_SLEEP_MAC_IF_MSB 2 -#define WLAN_SYSTEM_SLEEP_MAC_IF_LSB 2 -#define WLAN_SYSTEM_SLEEP_MAC_IF_MASK 0x00000004 -#define WLAN_SYSTEM_SLEEP_MAC_IF_GET(x) (((x) & WLAN_SYSTEM_SLEEP_MAC_IF_MASK) >> WLAN_SYSTEM_SLEEP_MAC_IF_LSB) -#define WLAN_SYSTEM_SLEEP_MAC_IF_SET(x) (((x) << WLAN_SYSTEM_SLEEP_MAC_IF_LSB) & WLAN_SYSTEM_SLEEP_MAC_IF_MASK) -#define WLAN_SYSTEM_SLEEP_LIGHT_MSB 1 -#define WLAN_SYSTEM_SLEEP_LIGHT_LSB 1 -#define WLAN_SYSTEM_SLEEP_LIGHT_MASK 0x00000002 -#define WLAN_SYSTEM_SLEEP_LIGHT_GET(x) (((x) & WLAN_SYSTEM_SLEEP_LIGHT_MASK) >> WLAN_SYSTEM_SLEEP_LIGHT_LSB) -#define WLAN_SYSTEM_SLEEP_LIGHT_SET(x) (((x) << WLAN_SYSTEM_SLEEP_LIGHT_LSB) & WLAN_SYSTEM_SLEEP_LIGHT_MASK) -#define WLAN_SYSTEM_SLEEP_DISABLE_MSB 0 -#define WLAN_SYSTEM_SLEEP_DISABLE_LSB 0 -#define WLAN_SYSTEM_SLEEP_DISABLE_MASK 0x00000001 -#define WLAN_SYSTEM_SLEEP_DISABLE_GET(x) (((x) & WLAN_SYSTEM_SLEEP_DISABLE_MASK) >> WLAN_SYSTEM_SLEEP_DISABLE_LSB) -#define WLAN_SYSTEM_SLEEP_DISABLE_SET(x) (((x) << WLAN_SYSTEM_SLEEP_DISABLE_LSB) & WLAN_SYSTEM_SLEEP_DISABLE_MASK) - -#define WLAN_LPO_CAL_ADDRESS 0x000000e0 -#define WLAN_LPO_CAL_OFFSET 0x000000e0 -#define WLAN_LPO_CAL_ENABLE_MSB 20 -#define WLAN_LPO_CAL_ENABLE_LSB 20 -#define WLAN_LPO_CAL_ENABLE_MASK 0x00100000 -#define WLAN_LPO_CAL_ENABLE_GET(x) (((x) & WLAN_LPO_CAL_ENABLE_MASK) >> WLAN_LPO_CAL_ENABLE_LSB) -#define WLAN_LPO_CAL_ENABLE_SET(x) (((x) << WLAN_LPO_CAL_ENABLE_LSB) & WLAN_LPO_CAL_ENABLE_MASK) -#define WLAN_LPO_CAL_COUNT_MSB 19 -#define WLAN_LPO_CAL_COUNT_LSB 0 -#define WLAN_LPO_CAL_COUNT_MASK 0x000fffff -#define WLAN_LPO_CAL_COUNT_GET(x) (((x) & WLAN_LPO_CAL_COUNT_MASK) >> WLAN_LPO_CAL_COUNT_LSB) -#define WLAN_LPO_CAL_COUNT_SET(x) (((x) << WLAN_LPO_CAL_COUNT_LSB) & WLAN_LPO_CAL_COUNT_MASK) - -#endif /* _RTC_WLAN_REG_H_ */ diff --git a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/uart_reg.h b/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/uart_reg.h deleted file mode 100644 index 302b20b..0000000 --- a/drivers/staging/ath6kl/include/common/AR6002/hw4.0/hw/uart_reg.h +++ /dev/null @@ -1,40 +0,0 @@ -// ------------------------------------------------------------------ -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -// ------------------------------------------------------------------ -//=================================================================== -// Author(s): ="Atheros" -//=================================================================== - - -#ifndef _UART_REG_REG_H_ -#define _UART_REG_REG_H_ - -#define UART_CLKDIV_ADDRESS 0x00000008 -#define UART_CLKDIV_OFFSET 0x00000008 -#define UART_CLKDIV_CLK_SCALE_MSB 23 -#define UART_CLKDIV_CLK_SCALE_LSB 16 -#define UART_CLKDIV_CLK_SCALE_MASK 0x00ff0000 -#define UART_CLKDIV_CLK_SCALE_GET(x) (((x) & UART_CLKDIV_CLK_SCALE_MASK) >> UART_CLKDIV_CLK_SCALE_LSB) -#define UART_CLKDIV_CLK_SCALE_SET(x) (((x) << UART_CLKDIV_CLK_SCALE_LSB) & UART_CLKDIV_CLK_SCALE_MASK) -#define UART_CLKDIV_CLK_STEP_MSB 15 -#define UART_CLKDIV_CLK_STEP_LSB 0 -#define UART_CLKDIV_CLK_STEP_MASK 0x0000ffff -#define UART_CLKDIV_CLK_STEP_GET(x) (((x) & UART_CLKDIV_CLK_STEP_MASK) >> UART_CLKDIV_CLK_STEP_LSB) -#define UART_CLKDIV_CLK_STEP_SET(x) (((x) << UART_CLKDIV_CLK_STEP_LSB) & UART_CLKDIV_CLK_STEP_MASK) - -#endif /* _UART_REG_H_ */ diff --git a/drivers/staging/ath6kl/include/common/athdefs.h b/drivers/staging/ath6kl/include/common/athdefs.h deleted file mode 100644 index 7492248..0000000 --- a/drivers/staging/ath6kl/include/common/athdefs.h +++ /dev/null @@ -1,75 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="athdefs.h" company="Atheros"> -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Author(s): ="Atheros" -//============================================================================== -#ifndef __ATHDEFS_H__ -#define __ATHDEFS_H__ - -/* - * This file contains definitions that may be used across both - * Host and Target software. Nothing here is module-dependent - * or platform-dependent. - */ - -/* - * Generic error codes that can be used by hw, sta, ap, sim, dk - * and any other environments. - * Feel free to add any more non-zero codes that you need. - */ - -#define A_ERROR (-1) /* Generic error return */ -#define A_DEVICE_NOT_FOUND 1 /* not able to find PCI device */ -#define A_NO_MEMORY 2 /* not able to allocate memory, - * not avail#defineable */ -#define A_MEMORY_NOT_AVAIL 3 /* memory region is not free for - * mapping */ -#define A_NO_FREE_DESC 4 /* no free descriptors available */ -#define A_BAD_ADDRESS 5 /* address does not match descriptor */ -#define A_WIN_DRIVER_ERROR 6 /* used in NT_HW version, - * if problem at init */ -#define A_REGS_NOT_MAPPED 7 /* registers not correctly mapped */ -#define A_EPERM 8 /* Not superuser */ -#define A_EACCES 0 /* Access denied */ -#define A_ENOENT 10 /* No such entry, search failed, etc. */ -#define A_EEXIST 11 /* The object already exists - * (can't create) */ -#define A_EFAULT 12 /* Bad address fault */ -#define A_EBUSY 13 /* Object is busy */ -#define A_EINVAL 14 /* Invalid parameter */ -#define A_EMSGSIZE 15 /* Bad message buffer length */ -#define A_ECANCELED 16 /* Operation canceled */ -#define A_ENOTSUP 17 /* Operation not supported */ -#define A_ECOMM 18 /* Communication error on send */ -#define A_EPROTO 19 /* Protocol error */ -#define A_ENODEV 20 /* No such device */ -#define A_EDEVNOTUP 21 /* device is not UP */ -#define A_NO_RESOURCE 22 /* No resources for - * requested operation */ -#define A_HARDWARE 23 /* Hardware failure */ -#define A_PENDING 24 /* Asynchronous routine; will send up - * results later - * (typically in callback) */ -#define A_EBADCHANNEL 25 /* The channel cannot be used */ -#define A_DECRYPT_ERROR 26 /* Decryption error */ -#define A_PHY_ERROR 27 /* RX PHY error */ -#define A_CONSUMED 28 /* Object was consumed */ - -#endif /* __ATHDEFS_H__ */ diff --git a/drivers/staging/ath6kl/include/common/bmi_msg.h b/drivers/staging/ath6kl/include/common/bmi_msg.h deleted file mode 100644 index 84e8db5..0000000 --- a/drivers/staging/ath6kl/include/common/bmi_msg.h +++ /dev/null @@ -1,233 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -// -// Author(s): ="Atheros" -//------------------------------------------------------------------------------ - -#ifndef __BMI_MSG_H__ -#define __BMI_MSG_H__ - -/* - * Bootloader Messaging Interface (BMI) - * - * BMI is a very simple messaging interface used during initialization - * to read memory, write memory, execute code, and to define an - * application entry PC. - * - * It is used to download an application to AR6K, to provide - * patches to code that is already resident on AR6K, and generally - * to examine and modify state. The Host has an opportunity to use - * BMI only once during bootup. Once the Host issues a BMI_DONE - * command, this opportunity ends. - * - * The Host writes BMI requests to mailbox0, and reads BMI responses - * from mailbox0. BMI requests all begin with a command - * (see below for specific commands), and are followed by - * command-specific data. - * - * Flow control: - * The Host can only issue a command once the Target gives it a - * "BMI Command Credit", using AR6K Counter #4. As soon as the - * Target has completed a command, it issues another BMI Command - * Credit (so the Host can issue the next command). - * - * BMI handles all required Target-side cache flushing. - */ - - -/* Maximum data size used for BMI transfers */ -#define BMI_DATASZ_MAX 256 - -/* BMI Commands */ - -#define BMI_NO_COMMAND 0 - -#define BMI_DONE 1 - /* - * Semantics: Host is done using BMI - * Request format: - * u32 command (BMI_DONE) - * Response format: none - */ - -#define BMI_READ_MEMORY 2 - /* - * Semantics: Host reads AR6K memory - * Request format: - * u32 command (BMI_READ_MEMORY) - * u32 address - * u32 length, at most BMI_DATASZ_MAX - * Response format: - * u8 data[length] - */ - -#define BMI_WRITE_MEMORY 3 - /* - * Semantics: Host writes AR6K memory - * Request format: - * u32 command (BMI_WRITE_MEMORY) - * u32 address - * u32 length, at most BMI_DATASZ_MAX - * u8 data[length] - * Response format: none - */ - -#define BMI_EXECUTE 4 - /* - * Semantics: Causes AR6K to execute code - * Request format: - * u32 command (BMI_EXECUTE) - * u32 address - * u32 parameter - * Response format: - * u32 return value - */ - -#define BMI_SET_APP_START 5 - /* - * Semantics: Set Target application starting address - * Request format: - * u32 command (BMI_SET_APP_START) - * u32 address - * Response format: none - */ - -#define BMI_READ_SOC_REGISTER 6 - /* - * Semantics: Read a 32-bit Target SOC register. - * Request format: - * u32 command (BMI_READ_REGISTER) - * u32 address - * Response format: - * u32 value - */ - -#define BMI_WRITE_SOC_REGISTER 7 - /* - * Semantics: Write a 32-bit Target SOC register. - * Request format: - * u32 command (BMI_WRITE_REGISTER) - * u32 address - * u32 value - * - * Response format: none - */ - -#define BMI_GET_TARGET_ID 8 -#define BMI_GET_TARGET_INFO 8 - /* - * Semantics: Fetch the 4-byte Target information - * Request format: - * u32 command (BMI_GET_TARGET_ID/INFO) - * Response format1 (old firmware): - * u32 TargetVersionID - * Response format2 (newer firmware): - * u32 TARGET_VERSION_SENTINAL - * struct bmi_target_info; - */ - -PREPACK struct bmi_target_info { - u32 target_info_byte_count; /* size of this structure */ - u32 target_ver; /* Target Version ID */ - u32 target_type; /* Target type */ -} POSTPACK; -#define TARGET_VERSION_SENTINAL 0xffffffff -#define TARGET_TYPE_AR6001 1 -#define TARGET_TYPE_AR6002 2 -#define TARGET_TYPE_AR6003 3 - - -#define BMI_ROMPATCH_INSTALL 9 - /* - * Semantics: Install a ROM Patch. - * Request format: - * u32 command (BMI_ROMPATCH_INSTALL) - * u32 Target ROM Address - * u32 Target RAM Address or Value (depending on Target Type) - * u32 Size, in bytes - * u32 Activate? 1-->activate; - * 0-->install but do not activate - * Response format: - * u32 PatchID - */ - -#define BMI_ROMPATCH_UNINSTALL 10 - /* - * Semantics: Uninstall a previously-installed ROM Patch, - * automatically deactivating, if necessary. - * Request format: - * u32 command (BMI_ROMPATCH_UNINSTALL) - * u32 PatchID - * - * Response format: none - */ - -#define BMI_ROMPATCH_ACTIVATE 11 - /* - * Semantics: Activate a list of previously-installed ROM Patches. - * Request format: - * u32 command (BMI_ROMPATCH_ACTIVATE) - * u32 rompatch_count - * u32 PatchID[rompatch_count] - * - * Response format: none - */ - -#define BMI_ROMPATCH_DEACTIVATE 12 - /* - * Semantics: Deactivate a list of active ROM Patches. - * Request format: - * u32 command (BMI_ROMPATCH_DEACTIVATE) - * u32 rompatch_count - * u32 PatchID[rompatch_count] - * - * Response format: none - */ - - -#define BMI_LZ_STREAM_START 13 - /* - * Semantics: Begin an LZ-compressed stream of input - * which is to be uncompressed by the Target to an - * output buffer at address. The output buffer must - * be sufficiently large to hold the uncompressed - * output from the compressed input stream. This BMI - * command should be followed by a series of 1 or more - * BMI_LZ_DATA commands. - * u32 command (BMI_LZ_STREAM_START) - * u32 address - * Note: Not supported on all versions of ROM firmware. - */ - -#define BMI_LZ_DATA 14 - /* - * Semantics: Host writes AR6K memory with LZ-compressed - * data which is uncompressed by the Target. This command - * must be preceded by a BMI_LZ_STREAM_START command. A series - * of BMI_LZ_DATA commands are considered part of a single - * input stream until another BMI_LZ_STREAM_START is issued. - * Request format: - * u32 command (BMI_LZ_DATA) - * u32 length (of compressed data), - * at most BMI_DATASZ_MAX - * u8 CompressedData[length] - * Response format: none - * Note: Not supported on all versions of ROM firmware. - */ - -#endif /* __BMI_MSG_H__ */ diff --git a/drivers/staging/ath6kl/include/common/cnxmgmt.h b/drivers/staging/ath6kl/include/common/cnxmgmt.h deleted file mode 100644 index 7a902cb..0000000 --- a/drivers/staging/ath6kl/include/common/cnxmgmt.h +++ /dev/null @@ -1,36 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="cnxmgmt.h" company="Atheros"> -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Author(s): ="Atheros" -//============================================================================== - -#ifndef _CNXMGMT_H_ -#define _CNXMGMT_H_ - -typedef enum { - CM_CONNECT_WITHOUT_SCAN = 0x0001, - CM_CONNECT_ASSOC_POLICY_USER = 0x0002, - CM_CONNECT_SEND_REASSOC = 0x0004, - CM_CONNECT_WITHOUT_ROAMTABLE_UPDATE = 0x0008, - CM_CONNECT_DO_WPA_OFFLOAD = 0x0010, - CM_CONNECT_DO_NOT_DEAUTH = 0x0020, -} CM_CONNECT_TYPE; - -#endif /* _CNXMGMT_H_ */ diff --git a/drivers/staging/ath6kl/include/common/dbglog.h b/drivers/staging/ath6kl/include/common/dbglog.h deleted file mode 100644 index 5566e56..0000000 --- a/drivers/staging/ath6kl/include/common/dbglog.h +++ /dev/null @@ -1,126 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="dbglog.h" company="Atheros"> -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Author(s): ="Atheros" -//============================================================================== - -#ifndef _DBGLOG_H_ -#define _DBGLOG_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#define DBGLOG_TIMESTAMP_OFFSET 0 -#define DBGLOG_TIMESTAMP_MASK 0x0000FFFF /* Bit 0-15. Contains bit - 8-23 of the LF0 timer */ -#define DBGLOG_DBGID_OFFSET 16 -#define DBGLOG_DBGID_MASK 0x03FF0000 /* Bit 16-25 */ -#define DBGLOG_DBGID_NUM_MAX 256 /* Upper limit is width of mask */ - -#define DBGLOG_MODULEID_OFFSET 26 -#define DBGLOG_MODULEID_MASK 0x3C000000 /* Bit 26-29 */ -#define DBGLOG_MODULEID_NUM_MAX 16 /* Upper limit is width of mask */ - -/* - * Please ensure that the definition of any new module introduced is captured - * between the DBGLOG_MODULEID_START and DBGLOG_MODULEID_END defines. The - * structure is required for the parser to correctly pick up the values for - * different modules. - */ -#define DBGLOG_MODULEID_START -#define DBGLOG_MODULEID_INF 0 -#define DBGLOG_MODULEID_WMI 1 -#define DBGLOG_MODULEID_MISC 2 -#define DBGLOG_MODULEID_PM 3 -#define DBGLOG_MODULEID_TXRX_MGMTBUF 4 -#define DBGLOG_MODULEID_TXRX_TXBUF 5 -#define DBGLOG_MODULEID_TXRX_RXBUF 6 -#define DBGLOG_MODULEID_WOW 7 -#define DBGLOG_MODULEID_WHAL 8 -#define DBGLOG_MODULEID_DC 9 -#define DBGLOG_MODULEID_CO 10 -#define DBGLOG_MODULEID_RO 11 -#define DBGLOG_MODULEID_CM 12 -#define DBGLOG_MODULEID_MGMT 13 -#define DBGLOG_MODULEID_TMR 14 -#define DBGLOG_MODULEID_BTCOEX 15 -#define DBGLOG_MODULEID_END - -#define DBGLOG_NUM_ARGS_OFFSET 30 -#define DBGLOG_NUM_ARGS_MASK 0xC0000000 /* Bit 30-31 */ -#define DBGLOG_NUM_ARGS_MAX 2 /* Upper limit is width of mask */ - -#define DBGLOG_MODULE_LOG_ENABLE_OFFSET 0 -#define DBGLOG_MODULE_LOG_ENABLE_MASK 0x0000FFFF - -#define DBGLOG_REPORTING_ENABLED_OFFSET 16 -#define DBGLOG_REPORTING_ENABLED_MASK 0x00010000 - -#define DBGLOG_TIMESTAMP_RESOLUTION_OFFSET 17 -#define DBGLOG_TIMESTAMP_RESOLUTION_MASK 0x000E0000 - -#define DBGLOG_REPORT_SIZE_OFFSET 20 -#define DBGLOG_REPORT_SIZE_MASK 0x3FF00000 - -#define DBGLOG_LOG_BUFFER_SIZE 1500 -#define DBGLOG_DBGID_DEFINITION_LEN_MAX 90 - -PREPACK struct dbglog_buf_s { - struct dbglog_buf_s *next; - u8 *buffer; - u32 bufsize; - u32 length; - u32 count; - u32 free; -} POSTPACK; - -PREPACK struct dbglog_hdr_s { - struct dbglog_buf_s *dbuf; - u32 dropped; -} POSTPACK; - -PREPACK struct dbglog_config_s { - u32 cfgvalid; /* Mask with valid config bits */ - union { - /* TODO: Take care of endianness */ - struct { - u32 mmask:16; /* Mask of modules with logging on */ - u32 rep:1; /* Reporting enabled or not */ - u32 tsr:3; /* Time stamp resolution. Def: 1 ms */ - u32 size:10; /* Report size in number of messages */ - u32 reserved:2; - } dbglog_config; - - u32 value; - } u; -} POSTPACK; - -#define cfgmmask u.dbglog_config.mmask -#define cfgrep u.dbglog_config.rep -#define cfgtsr u.dbglog_config.tsr -#define cfgsize u.dbglog_config.size -#define cfgvalue u.value - -#ifdef __cplusplus -} -#endif - -#endif /* _DBGLOG_H_ */ diff --git a/drivers/staging/ath6kl/include/common/dbglog_id.h b/drivers/staging/ath6kl/include/common/dbglog_id.h deleted file mode 100644 index 15ef829..0000000 --- a/drivers/staging/ath6kl/include/common/dbglog_id.h +++ /dev/null @@ -1,558 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="dbglog_id.h" company="Atheros"> -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Author(s): ="Atheros" -//============================================================================== - -#ifndef _DBGLOG_ID_H_ -#define _DBGLOG_ID_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * The nomenclature for the debug identifiers is MODULE_DESCRIPTION. - * Please ensure that the definition of any new debugid introduced is captured - * between the <MODULE>_DBGID_DEFINITION_START and - * <MODULE>_DBGID_DEFINITION_END defines. The structure is required for the - * parser to correctly pick up the values for different debug identifiers. - */ - -/* INF debug identifier definitions */ -#define INF_DBGID_DEFINITION_START -#define INF_ASSERTION_FAILED 1 -#define INF_TARGET_ID 2 -#define INF_DBGID_DEFINITION_END - -/* WMI debug identifier definitions */ -#define WMI_DBGID_DEFINITION_START -#define WMI_CMD_RX_XTND_PKT_TOO_SHORT 1 -#define WMI_EXTENDED_CMD_NOT_HANDLED 2 -#define WMI_CMD_RX_PKT_TOO_SHORT 3 -#define WMI_CALLING_WMI_EXTENSION_FN 4 -#define WMI_CMD_NOT_HANDLED 5 -#define WMI_IN_SYNC 6 -#define WMI_TARGET_WMI_SYNC_CMD 7 -#define WMI_SET_SNR_THRESHOLD_PARAMS 8 -#define WMI_SET_RSSI_THRESHOLD_PARAMS 9 -#define WMI_SET_LQ_TRESHOLD_PARAMS 10 -#define WMI_TARGET_CREATE_PSTREAM_CMD 11 -#define WMI_WI_DTM_INUSE 12 -#define WMI_TARGET_DELETE_PSTREAM_CMD 13 -#define WMI_TARGET_IMPLICIT_DELETE_PSTREAM_CMD 14 -#define WMI_TARGET_GET_BIT_RATE_CMD 15 -#define WMI_GET_RATE_MASK_CMD_FIX_RATE_MASK_IS 16 -#define WMI_TARGET_GET_AVAILABLE_CHANNELS_CMD 17 -#define WMI_TARGET_GET_TX_PWR_CMD 18 -#define WMI_FREE_EVBUF_WMIBUF 19 -#define WMI_FREE_EVBUF_DATABUF 20 -#define WMI_FREE_EVBUF_BADFLAG 21 -#define WMI_HTC_RX_ERROR_DATA_PACKET 22 -#define WMI_HTC_RX_SYNC_PAUSING_FOR_MBOX 23 -#define WMI_INCORRECT_WMI_DATA_HDR_DROPPING_PKT 24 -#define WMI_SENDING_READY_EVENT 25 -#define WMI_SETPOWER_MDOE_TO_MAXPERF 26 -#define WMI_SETPOWER_MDOE_TO_REC 27 -#define WMI_BSSINFO_EVENT_FROM 28 -#define WMI_TARGET_GET_STATS_CMD 29 -#define WMI_SENDING_SCAN_COMPLETE_EVENT 30 -#define WMI_SENDING_RSSI_INDB_THRESHOLD_EVENT 31 -#define WMI_SENDING_RSSI_INDBM_THRESHOLD_EVENT 32 -#define WMI_SENDING_LINK_QUALITY_THRESHOLD_EVENT 33 -#define WMI_SENDING_ERROR_REPORT_EVENT 34 -#define WMI_SENDING_CAC_EVENT 35 -#define WMI_TARGET_GET_ROAM_TABLE_CMD 36 -#define WMI_TARGET_GET_ROAM_DATA_CMD 37 -#define WMI_SENDING_GPIO_INTR_EVENT 38 -#define WMI_SENDING_GPIO_ACK_EVENT 39 -#define WMI_SENDING_GPIO_DATA_EVENT 40 -#define WMI_CMD_RX 41 -#define WMI_CMD_RX_XTND 42 -#define WMI_EVENT_SEND 43 -#define WMI_EVENT_SEND_XTND 44 -#define WMI_CMD_PARAMS_DUMP_START 45 -#define WMI_CMD_PARAMS_DUMP_END 46 -#define WMI_CMD_PARAMS 47 -#define WMI_DBGID_DEFINITION_END - -/* MISC debug identifier definitions */ -#define MISC_DBGID_DEFINITION_START -#define MISC_WLAN_SCHEDULER_EVENT_REGISTER_ERROR 1 -#define TLPM_INIT 2 -#define TLPM_FILTER_POWER_STATE 3 -#define TLPM_NOTIFY_NOT_IDLE 4 -#define TLPM_TIMEOUT_IDLE_HANDLER 5 -#define TLPM_TIMEOUT_WAKEUP_HANDLER 6 -#define TLPM_WAKEUP_SIGNAL_HANDLER 7 -#define TLPM_UNEXPECTED_GPIO_INTR_ERROR 8 -#define TLPM_BREAK_ON_NOT_RECEIVED_ERROR 9 -#define TLPM_BREAK_OFF_NOT_RECIVED_ERROR 10 -#define TLPM_ACK_GPIO_INTR 11 -#define TLPM_ON 12 -#define TLPM_OFF 13 -#define TLPM_WAKEUP_FROM_HOST 14 -#define TLPM_WAKEUP_FROM_BT 15 -#define TLPM_TX_BREAK_RECIVED 16 -#define TLPM_IDLE_TIMER_NOT_RUNNING 17 -#define MISC_DBGID_DEFINITION_END - -/* TXRX debug identifier definitions */ -#define TXRX_TXBUF_DBGID_DEFINITION_START -#define TXRX_TXBUF_ALLOCATE_BUF 1 -#define TXRX_TXBUF_QUEUE_BUF_TO_MBOX 2 -#define TXRX_TXBUF_QUEUE_BUF_TO_TXQ 3 -#define TXRX_TXBUF_TXQ_DEPTH 4 -#define TXRX_TXBUF_IBSS_QUEUE_TO_SFQ 5 -#define TXRX_TXBUF_IBSS_QUEUE_TO_TXQ_FRM_SFQ 6 -#define TXRX_TXBUF_INITIALIZE_TIMER 7 -#define TXRX_TXBUF_ARM_TIMER 8 -#define TXRX_TXBUF_DISARM_TIMER 9 -#define TXRX_TXBUF_UNINITIALIZE_TIMER 10 -#define TXRX_TXBUF_DBGID_DEFINITION_END - -#define TXRX_RXBUF_DBGID_DEFINITION_START -#define TXRX_RXBUF_ALLOCATE_BUF 1 -#define TXRX_RXBUF_QUEUE_TO_HOST 2 -#define TXRX_RXBUF_QUEUE_TO_WLAN 3 -#define TXRX_RXBUF_ZERO_LEN_BUF 4 -#define TXRX_RXBUF_QUEUE_TO_HOST_LASTBUF_IN_RXCHAIN 5 -#define TXRX_RXBUF_LASTBUF_IN_RXCHAIN_ZEROBUF 6 -#define TXRX_RXBUF_QUEUE_EMPTY_QUEUE_TO_WLAN 7 -#define TXRX_RXBUF_SEND_TO_RECV_MGMT 8 -#define TXRX_RXBUF_SEND_TO_IEEE_LAYER 9 -#define TXRX_RXBUF_REQUEUE_ERROR 10 -#define TXRX_RXBUF_DBGID_DEFINITION_END - -#define TXRX_MGMTBUF_DBGID_DEFINITION_START -#define TXRX_MGMTBUF_ALLOCATE_BUF 1 -#define TXRX_MGMTBUF_ALLOCATE_SM_BUF 2 -#define TXRX_MGMTBUF_ALLOCATE_RMBUF 3 -#define TXRX_MGMTBUF_GET_BUF 4 -#define TXRX_MGMTBUF_GET_SM_BUF 5 -#define TXRX_MGMTBUF_QUEUE_BUF_TO_TXQ 6 -#define TXRX_MGMTBUF_REAPED_BUF 7 -#define TXRX_MGMTBUF_REAPED_SM_BUF 8 -#define TXRX_MGMTBUF_WAIT_FOR_TXQ_DRAIN 9 -#define TXRX_MGMTBUF_WAIT_FOR_TXQ_SFQ_DRAIN 10 -#define TXRX_MGMTBUF_ENQUEUE_INTO_DATA_SFQ 11 -#define TXRX_MGMTBUF_DEQUEUE_FROM_DATA_SFQ 12 -#define TXRX_MGMTBUF_PAUSE_DATA_TXQ 13 -#define TXRX_MGMTBUF_RESUME_DATA_TXQ 14 -#define TXRX_MGMTBUF_WAIT_FORTXQ_DRAIN_TIMEOUT 15 -#define TXRX_MGMTBUF_DRAINQ 16 -#define TXRX_MGMTBUF_INDICATE_Q_DRAINED 17 -#define TXRX_MGMTBUF_ENQUEUE_INTO_HW_SFQ 18 -#define TXRX_MGMTBUF_DEQUEUE_FROM_HW_SFQ 19 -#define TXRX_MGMTBUF_PAUSE_HW_TXQ 20 -#define TXRX_MGMTBUF_RESUME_HW_TXQ 21 -#define TXRX_MGMTBUF_TEAR_DOWN_BA 22 -#define TXRX_MGMTBUF_PROCESS_ADDBA_REQ 23 -#define TXRX_MGMTBUF_PROCESS_DELBA 24 -#define TXRX_MGMTBUF_PERFORM_BA 25 -#define TXRX_MGMTBUF_WLAN_RESET_ON_ERROR 26 -#define TXRX_MGMTBUF_DBGID_DEFINITION_END - -/* PM (Power Module) debug identifier definitions */ -#define PM_DBGID_DEFINITION_START -#define PM_INIT 1 -#define PM_ENABLE 2 -#define PM_SET_STATE 3 -#define PM_SET_POWERMODE 4 -#define PM_CONN_NOTIFY 5 -#define PM_REF_COUNT_NEGATIVE 6 -#define PM_INFRA_STA_APSD_ENABLE 7 -#define PM_INFRA_STA_UPDATE_APSD_STATE 8 -#define PM_CHAN_OP_REQ 9 -#define PM_SET_MY_BEACON_POLICY 10 -#define PM_SET_ALL_BEACON_POLICY 11 -#define PM_INFRA_STA_SET_PM_PARAMS1 12 -#define PM_INFRA_STA_SET_PM_PARAMS2 13 -#define PM_ADHOC_SET_PM_CAPS_FAIL 14 -#define PM_ADHOC_UNKNOWN_IBSS_ATTRIB_ID 15 -#define PM_ADHOC_SET_PM_PARAMS 16 -#define PM_ADHOC_STATE1 18 -#define PM_ADHOC_STATE2 19 -#define PM_ADHOC_CONN_MAP 20 -#define PM_FAKE_SLEEP 21 -#define PM_AP_STATE1 22 -#define PM_AP_SET_PM_PARAMS 23 -#define PM_DBGID_DEFINITION_END - -/* Wake on Wireless debug identifier definitions */ -#define WOW_DBGID_DEFINITION_START -#define WOW_INIT 1 -#define WOW_GET_CONFIG_DSET 2 -#define WOW_NO_CONFIG_DSET 3 -#define WOW_INVALID_CONFIG_DSET 4 -#define WOW_USE_DEFAULT_CONFIG 5 -#define WOW_SETUP_GPIO 6 -#define WOW_INIT_DONE 7 -#define WOW_SET_GPIO_PIN 8 -#define WOW_CLEAR_GPIO_PIN 9 -#define WOW_SET_WOW_MODE_CMD 10 -#define WOW_SET_HOST_MODE_CMD 11 -#define WOW_ADD_WOW_PATTERN_CMD 12 -#define WOW_NEW_WOW_PATTERN_AT_INDEX 13 -#define WOW_DEL_WOW_PATTERN_CMD 14 -#define WOW_LIST_CONTAINS_PATTERNS 15 -#define WOW_GET_WOW_LIST_CMD 16 -#define WOW_INVALID_FILTER_ID 17 -#define WOW_INVALID_FILTER_LISTID 18 -#define WOW_NO_VALID_FILTER_AT_ID 19 -#define WOW_NO_VALID_LIST_AT_ID 20 -#define WOW_NUM_PATTERNS_EXCEEDED 21 -#define WOW_NUM_LISTS_EXCEEDED 22 -#define WOW_GET_WOW_STATS 23 -#define WOW_CLEAR_WOW_STATS 24 -#define WOW_WAKEUP_HOST 25 -#define WOW_EVENT_WAKEUP_HOST 26 -#define WOW_EVENT_DISCARD 27 -#define WOW_PATTERN_MATCH 28 -#define WOW_PATTERN_NOT_MATCH 29 -#define WOW_PATTERN_NOT_MATCH_OFFSET 30 -#define WOW_DISABLED_HOST_ASLEEP 31 -#define WOW_ENABLED_HOST_ASLEEP_NO_PATTERNS 32 -#define WOW_ENABLED_HOST_ASLEEP_NO_MATCH_FOUND 33 -#define WOW_DBGID_DEFINITION_END - -/* WHAL debug identifier definitions */ -#define WHAL_DBGID_DEFINITION_START -#define WHAL_ERROR_ANI_CONTROL 1 -#define WHAL_ERROR_CHIP_TEST1 2 -#define WHAL_ERROR_CHIP_TEST2 3 -#define WHAL_ERROR_EEPROM_CHECKSUM 4 -#define WHAL_ERROR_EEPROM_MACADDR 5 -#define WHAL_ERROR_INTERRUPT_HIU 6 -#define WHAL_ERROR_KEYCACHE_RESET 7 -#define WHAL_ERROR_KEYCACHE_SET 8 -#define WHAL_ERROR_KEYCACHE_TYPE 9 -#define WHAL_ERROR_KEYCACHE_TKIPENTRY 10 -#define WHAL_ERROR_KEYCACHE_WEPLENGTH 11 -#define WHAL_ERROR_PHY_INVALID_CHANNEL 12 -#define WHAL_ERROR_POWER_AWAKE 13 -#define WHAL_ERROR_POWER_SET 14 -#define WHAL_ERROR_RECV_STOPDMA 15 -#define WHAL_ERROR_RECV_STOPPCU 16 -#define WHAL_ERROR_RESET_CHANNF1 17 -#define WHAL_ERROR_RESET_CHANNF2 18 -#define WHAL_ERROR_RESET_PM 19 -#define WHAL_ERROR_RESET_OFFSETCAL 20 -#define WHAL_ERROR_RESET_RFGRANT 21 -#define WHAL_ERROR_RESET_RXFRAME 22 -#define WHAL_ERROR_RESET_STOPDMA 23 -#define WHAL_ERROR_RESET_RECOVER 24 -#define WHAL_ERROR_XMIT_COMPUTE 25 -#define WHAL_ERROR_XMIT_NOQUEUE 26 -#define WHAL_ERROR_XMIT_ACTIVEQUEUE 27 -#define WHAL_ERROR_XMIT_BADTYPE 28 -#define WHAL_ERROR_XMIT_STOPDMA 29 -#define WHAL_ERROR_INTERRUPT_BB_PANIC 30 -#define WHAL_ERROR_RESET_TXIQCAL 31 -#define WHAL_ERROR_PAPRD_MAXGAIN_ABOVE_WINDOW 32 -#define WHAL_DBGID_DEFINITION_END - -/* DC debug identifier definitions */ -#define DC_DBGID_DEFINITION_START -#define DC_SCAN_CHAN_START 1 -#define DC_SCAN_CHAN_FINISH 2 -#define DC_BEACON_RECEIVE7 3 -#define DC_SSID_PROBE_CB 4 -#define DC_SEND_NEXT_SSID_PROBE 5 -#define DC_START_SEARCH 6 -#define DC_CANCEL_SEARCH_CB 7 -#define DC_STOP_SEARCH 8 -#define DC_END_SEARCH 9 -#define DC_MIN_CHDWELL_TIMEOUT 10 -#define DC_START_SEARCH_CANCELED 11 -#define DC_SET_POWER_MODE 12 -#define DC_INIT 13 -#define DC_SEARCH_OPPORTUNITY 14 -#define DC_RECEIVED_ANY_BEACON 15 -#define DC_RECEIVED_MY_BEACON 16 -#define DC_PROFILE_IS_ADHOC_BUT_BSS_IS_INFRA 17 -#define DC_PS_ENABLED_BUT_ATHEROS_IE_ABSENT 18 -#define DC_BSS_ADHOC_CHANNEL_NOT_ALLOWED 19 -#define DC_SET_BEACON_UPDATE 20 -#define DC_BEACON_UPDATE_COMPLETE 21 -#define DC_END_SEARCH_BEACON_UPDATE_COMP_CB 22 -#define DC_BSSINFO_EVENT_DROPPED 23 -#define DC_IEEEPS_ENABLED_BUT_ATIM_ABSENT 24 -#define DC_DBGID_DEFINITION_END - -/* CO debug identifier definitions */ -#define CO_DBGID_DEFINITION_START -#define CO_INIT 1 -#define CO_ACQUIRE_LOCK 2 -#define CO_START_OP1 3 -#define CO_START_OP2 4 -#define CO_DRAIN_TX_COMPLETE_CB 5 -#define CO_CHANGE_CHANNEL_CB 6 -#define CO_RETURN_TO_HOME_CHANNEL 7 -#define CO_FINISH_OP_TIMEOUT 8 -#define CO_OP_END 9 -#define CO_CANCEL_OP 10 -#define CO_CHANGE_CHANNEL 11 -#define CO_RELEASE_LOCK 12 -#define CO_CHANGE_STATE 13 -#define CO_DBGID_DEFINITION_END - -/* RO debug identifier definitions */ -#define RO_DBGID_DEFINITION_START -#define RO_REFRESH_ROAM_TABLE 1 -#define RO_UPDATE_ROAM_CANDIDATE 2 -#define RO_UPDATE_ROAM_CANDIDATE_CB 3 -#define RO_UPDATE_ROAM_CANDIDATE_FINISH 4 -#define RO_REFRESH_ROAM_TABLE_DONE 5 -#define RO_PERIODIC_SEARCH_CB 6 -#define RO_PERIODIC_SEARCH_TIMEOUT 7 -#define RO_INIT 8 -#define RO_BMISS_STATE1 9 -#define RO_BMISS_STATE2 10 -#define RO_SET_PERIODIC_SEARCH_ENABLE 11 -#define RO_SET_PERIODIC_SEARCH_DISABLE 12 -#define RO_ENABLE_SQ_THRESHOLD 13 -#define RO_DISABLE_SQ_THRESHOLD 14 -#define RO_ADD_BSS_TO_ROAM_TABLE 15 -#define RO_SET_PERIODIC_SEARCH_MODE 16 -#define RO_CONFIGURE_SQ_THRESHOLD1 17 -#define RO_CONFIGURE_SQ_THRESHOLD2 18 -#define RO_CONFIGURE_SQ_PARAMS 19 -#define RO_LOW_SIGNAL_QUALITY_EVENT 20 -#define RO_HIGH_SIGNAL_QUALITY_EVENT 21 -#define RO_REMOVE_BSS_FROM_ROAM_TABLE 22 -#define RO_UPDATE_CONNECTION_STATE_METRIC 23 -#define RO_DBGID_DEFINITION_END - -/* CM debug identifier definitions */ -#define CM_DBGID_DEFINITION_START -#define CM_INITIATE_HANDOFF 1 -#define CM_INITIATE_HANDOFF_CB 2 -#define CM_CONNECT_EVENT 3 -#define CM_DISCONNECT_EVENT 4 -#define CM_INIT 5 -#define CM_HANDOFF_SOURCE 6 -#define CM_SET_HANDOFF_TRIGGERS 7 -#define CM_CONNECT_REQUEST 8 -#define CM_CONNECT_REQUEST_CB 9 -#define CM_CONTINUE_SCAN_CB 10 -#define CM_DBGID_DEFINITION_END - - -/* mgmt debug identifier definitions */ -#define MGMT_DBGID_DEFINITION_START -#define KEYMGMT_CONNECTION_INIT 1 -#define KEYMGMT_CONNECTION_COMPLETE 2 -#define KEYMGMT_CONNECTION_CLOSE 3 -#define KEYMGMT_ADD_KEY 4 -#define MLME_NEW_STATE 5 -#define MLME_CONN_INIT 6 -#define MLME_CONN_COMPLETE 7 -#define MLME_CONN_CLOSE 8 -#define MGMT_DBGID_DEFINITION_END - -/* TMR debug identifier definitions */ -#define TMR_DBGID_DEFINITION_START -#define TMR_HANG_DETECTED 1 -#define TMR_WDT_TRIGGERED 2 -#define TMR_WDT_RESET 3 -#define TMR_HANDLER_ENTRY 4 -#define TMR_HANDLER_EXIT 5 -#define TMR_SAVED_START 6 -#define TMR_SAVED_END 7 -#define TMR_DBGID_DEFINITION_END - -/* BTCOEX debug identifier definitions */ -#define BTCOEX_DBGID_DEFINITION_START -#define BTCOEX_STATUS_CMD 1 -#define BTCOEX_PARAMS_CMD 2 -#define BTCOEX_ANT_CONFIG 3 -#define BTCOEX_COLOCATED_BT_DEVICE 4 -#define BTCOEX_CLOSE_RANGE_SCO_ON 5 -#define BTCOEX_CLOSE_RANGE_SCO_OFF 6 -#define BTCOEX_CLOSE_RANGE_A2DP_ON 7 -#define BTCOEX_CLOSE_RANGE_A2DP_OFF 8 -#define BTCOEX_A2DP_PROTECT_ON 9 -#define BTCOEX_A2DP_PROTECT_OFF 10 -#define BTCOEX_SCO_PROTECT_ON 11 -#define BTCOEX_SCO_PROTECT_OFF 12 -#define BTCOEX_CLOSE_RANGE_DETECTOR_START 13 -#define BTCOEX_CLOSE_RANGE_DETECTOR_STOP 14 -#define BTCOEX_CLOSE_RANGE_TOGGLE 15 -#define BTCOEX_CLOSE_RANGE_TOGGLE_RSSI_LRCNT 16 -#define BTCOEX_CLOSE_RANGE_RSSI_THRESH 17 -#define BTCOEX_CLOSE_RANGE_LOW_RATE_THRESH 18 -#define BTCOEX_PTA_PRI_INTR_HANDLER 19 -#define BTCOEX_PSPOLL_QUEUED 20 -#define BTCOEX_PSPOLL_COMPLETE 21 -#define BTCOEX_DBG_PM_AWAKE 22 -#define BTCOEX_DBG_PM_SLEEP 23 -#define BTCOEX_DBG_SCO_COEX_ON 24 -#define BTCOEX_SCO_DATARECEIVE 25 -#define BTCOEX_INTR_INIT 26 -#define BTCOEX_PTA_PRI_DIFF 27 -#define BTCOEX_TIM_NOTIFICATION 28 -#define BTCOEX_SCO_WAKEUP_ON_DATA 29 -#define BTCOEX_SCO_SLEEP 30 -#define BTCOEX_SET_WEIGHTS 31 -#define BTCOEX_SCO_DATARECEIVE_LATENCY_VAL 32 -#define BTCOEX_SCO_MEASURE_TIME_DIFF 33 -#define BTCOEX_SET_EOL_VAL 34 -#define BTCOEX_OPT_DETECT_HANDLER 35 -#define BTCOEX_SCO_TOGGLE_STATE 36 -#define BTCOEX_SCO_STOMP 37 -#define BTCOEX_NULL_COMP_CALLBACK 38 -#define BTCOEX_RX_INCOMING 39 -#define BTCOEX_RX_INCOMING_CTL 40 -#define BTCOEX_RX_INCOMING_MGMT 41 -#define BTCOEX_RX_INCOMING_DATA 42 -#define BTCOEX_RTS_RECEPTION 43 -#define BTCOEX_FRAME_PRI_LOW_RATE_THRES 44 -#define BTCOEX_PM_FAKE_SLEEP 45 -#define BTCOEX_ACL_COEX_STATUS 46 -#define BTCOEX_ACL_COEX_DETECTION 47 -#define BTCOEX_A2DP_COEX_STATUS 48 -#define BTCOEX_SCO_STATUS 49 -#define BTCOEX_WAKEUP_ON_DATA 50 -#define BTCOEX_DATARECEIVE 51 -#define BTCOEX_GET_MAX_AGGR_SIZE 53 -#define BTCOEX_MAX_AGGR_AVAIL_TIME 54 -#define BTCOEX_DBG_WBTIMER_INTR 55 -#define BTCOEX_DBG_SCO_SYNC 57 -#define BTCOEX_UPLINK_QUEUED_RATE 59 -#define BTCOEX_DBG_UPLINK_ENABLE_EOL 60 -#define BTCOEX_UPLINK_FRAME_DURATION 61 -#define BTCOEX_UPLINK_SET_EOL 62 -#define BTCOEX_DBG_EOL_EXPIRED 63 -#define BTCOEX_DBG_DATA_COMPLETE 64 -#define BTCOEX_UPLINK_QUEUED_TIMESTAMP 65 -#define BTCOEX_DBG_DATA_COMPLETE_TIME 66 -#define BTCOEX_DBG_A2DP_ROLE_IS_SLAVE 67 -#define BTCOEX_DBG_A2DP_ROLE_IS_MASTER 68 -#define BTCOEX_DBG_UPLINK_SEQ_NUM 69 -#define BTCOEX_UPLINK_AGGR_SEQ 70 -#define BTCOEX_DBG_TX_COMP_SEQ_NO 71 -#define BTCOEX_DBG_MAX_AGGR_PAUSE_STATE 72 -#define BTCOEX_DBG_ACL_TRAFFIC 73 -#define BTCOEX_CURR_AGGR_PROP 74 -#define BTCOEX_DBG_SCO_GET_PER_TIME_DIFF 75 -#define BTCOEX_PSPOLL_PROCESS 76 -#define BTCOEX_RETURN_FROM_MAC 77 -#define BTCOEX_FREED_REQUEUED_CNT 78 -#define BTCOEX_DBG_TOGGLE_LOW_RATES 79 -#define BTCOEX_MAC_GOES_TO_SLEEP 80 -#define BTCOEX_DBG_A2DP_NO_SYNC 81 -#define BTCOEX_RETURN_FROM_MAC_HOLD_Q_INFO 82 -#define BTCOEX_RETURN_FROM_MAC_AC 83 -#define BTCOEX_DBG_DTIM_RECV 84 -#define BTCOEX_IS_PRE_UPDATE 86 -#define BTCOEX_ENQUEUED_BIT_MAP 87 -#define BTCOEX_TX_COMPLETE_FIRST_DESC_STATS 88 -#define BTCOEX_UPLINK_DESC 89 -#define BTCOEX_SCO_GET_PER_FIRST_FRM_TIMESTAMP 90 -#define BTCOEX_DBG_RECV_ACK 94 -#define BTCOEX_DBG_ADDBA_INDICATION 95 -#define BTCOEX_TX_COMPLETE_EOL_FAILED 96 -#define BTCOEX_DBG_A2DP_USAGE_COMPLETE 97 -#define BTCOEX_DBG_A2DP_STOMP_FOR_BCN_HANDLER 98 -#define BTCOEX_DBG_A2DP_SYNC_INTR 99 -#define BTCOEX_DBG_A2DP_STOMP_FOR_BCN_RECEPTION 100 -#define BTCOEX_FORM_AGGR_CURR_AGGR 101 -#define BTCOEX_DBG_TOGGLE_A2DP_BURST_CNT 102 -#define BTCOEX_DBG_BT_TRAFFIC 103 -#define BTCOEX_DBG_STOMP_BT_TRAFFIC 104 -#define BTCOEX_RECV_NULL 105 -#define BTCOEX_DBG_A2DP_MASTER_BT_END 106 -#define BTCOEX_DBG_A2DP_BT_START 107 -#define BTCOEX_DBG_A2DP_SLAVE_BT_END 108 -#define BTCOEX_DBG_A2DP_STOMP_BT 109 -#define BTCOEX_DBG_GO_TO_SLEEP 110 -#define BTCOEX_DBG_A2DP_PKT 111 -#define BTCOEX_DBG_A2DP_PSPOLL_DATA_RECV 112 -#define BTCOEX_DBG_A2DP_NULL 113 -#define BTCOEX_DBG_UPLINK_DATA 114 -#define BTCOEX_DBG_A2DP_STOMP_LOW_PRIO_NULL 115 -#define BTCOEX_DBG_ADD_BA_RESP_TIMEOUT 116 -#define BTCOEX_DBG_TXQ_STATE 117 -#define BTCOEX_DBG_ALLOW_SCAN 118 -#define BTCOEX_DBG_SCAN_REQUEST 119 -#define BTCOEX_A2DP_SLEEP 127 -#define BTCOEX_DBG_DATA_ACTIV_TIMEOUT 128 -#define BTCOEX_DBG_SWITCH_TO_PSPOLL_ON_MODE 129 -#define BTCOEX_DBG_SWITCH_TO_PSPOLL_OFF_MODE 130 -#define BTCOEX_DATARECEIVE_AGGR 131 -#define BTCOEX_DBG_DATA_RECV_SLEEPING_PENDING 132 -#define BTCOEX_DBG_DATARESP_TIMEOUT 133 -#define BTCOEX_BDG_BMISS 134 -#define BTCOEX_DBG_DATA_RECV_WAKEUP_TIM 135 -#define BTCOEX_DBG_SECOND_BMISS 136 -#define BTCOEX_DBG_SET_WLAN_STATE 138 -#define BTCOEX_BDG_FIRST_BMISS 139 -#define BTCOEX_DBG_A2DP_CHAN_OP 140 -#define BTCOEX_DBG_A2DP_INTR 141 -#define BTCOEX_DBG_BT_INQUIRY 142 -#define BTCOEX_DBG_BT_INQUIRY_DATA_FETCH 143 -#define BTCOEX_DBG_POST_INQUIRY_FINISH 144 -#define BTCOEX_DBG_SCO_OPT_MODE_TIMER_HANDLER 145 -#define BTCOEX_DBG_NULL_FRAME_SLEEP 146 -#define BTCOEX_DBG_NULL_FRAME_AWAKE 147 -#define BTCOEX_DBG_SET_AGGR_SIZE 152 -#define BTCOEX_DBG_TEAR_BA_TIMEOUT 153 -#define BTCOEX_DBG_MGMT_FRAME_SEQ_NO 154 -#define BTCOEX_DBG_SCO_STOMP_HIGH_PRI 155 -#define BTCOEX_DBG_COLOCATED_BT_DEV 156 -#define BTCOEX_DBG_FE_ANT_TYPE 157 -#define BTCOEX_DBG_BT_INQUIRY_CMD 158 -#define BTCOEX_DBG_SCO_CONFIG 159 -#define BTCOEX_DBG_SCO_PSPOLL_CONFIG 160 -#define BTCOEX_DBG_SCO_OPTMODE_CONFIG 161 -#define BTCOEX_DBG_A2DP_CONFIG 162 -#define BTCOEX_DBG_A2DP_PSPOLL_CONFIG 163 -#define BTCOEX_DBG_A2DP_OPTMODE_CONFIG 164 -#define BTCOEX_DBG_ACLCOEX_CONFIG 165 -#define BTCOEX_DBG_ACLCOEX_PSPOLL_CONFIG 166 -#define BTCOEX_DBG_ACLCOEX_OPTMODE_CONFIG 167 -#define BTCOEX_DBG_DEBUG_CMD 168 -#define BTCOEX_DBG_SET_BT_OPERATING_STATUS 169 -#define BTCOEX_DBG_GET_CONFIG 170 -#define BTCOEX_DBG_GET_STATS 171 -#define BTCOEX_DBG_BT_OPERATING_STATUS 172 -#define BTCOEX_DBG_PERFORM_RECONNECT 173 -#define BTCOEX_DBG_ACL_WLAN_MED 175 -#define BTCOEX_DBG_ACL_BT_MED 176 -#define BTCOEX_DBG_WLAN_CONNECT 177 -#define BTCOEX_DBG_A2DP_DUAL_START 178 -#define BTCOEX_DBG_PMAWAKE_NOTIFY 179 -#define BTCOEX_DBG_BEACON_SCAN_ENABLE 180 -#define BTCOEX_DBG_BEACON_SCAN_DISABLE 181 -#define BTCOEX_DBG_RX_NOTIFY 182 -#define BTCOEX_SCO_GET_PER_SECOND_FRM_TIMESTAMP 183 -#define BTCOEX_DBG_TXQ_DETAILS 184 -#define BTCOEX_DBG_SCO_STOMP_LOW_PRI 185 -#define BTCOEX_DBG_A2DP_FORCE_SCAN 186 -#define BTCOEX_DBG_DTIM_STOMP_COMP 187 -#define BTCOEX_ACL_PRESENCE_TIMER 188 -#define BTCOEX_DBGID_DEFINITION_END - -#ifdef __cplusplus -} -#endif - -#endif /* _DBGLOG_ID_H_ */ diff --git a/drivers/staging/ath6kl/include/common/discovery.h b/drivers/staging/ath6kl/include/common/discovery.h deleted file mode 100644 index da1b332..0000000 --- a/drivers/staging/ath6kl/include/common/discovery.h +++ /dev/null @@ -1,75 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="discovery.h" company="Atheros"> -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Author(s): ="Atheros" -//============================================================================== - -#ifndef _DISCOVERY_H_ -#define _DISCOVERY_H_ - -/* - * DC_SCAN_PRIORITY is an 8-bit bitmap of the scan priority of a channel - */ -typedef enum { - DEFAULT_SCPRI = 0x01, - POPULAR_SCPRI = 0x02, - SSIDS_SCPRI = 0x04, - PROF_SCPRI = 0x08, -} DC_SCAN_PRIORITY; - -/* The following search type construct can be used to manipulate the behavior of the search module based on different bits set */ -typedef enum { - SCAN_RESET = 0, - SCAN_ALL = (DEFAULT_SCPRI | POPULAR_SCPRI | \ - SSIDS_SCPRI | PROF_SCPRI), - - SCAN_POPULAR = (POPULAR_SCPRI | SSIDS_SCPRI | PROF_SCPRI), - SCAN_SSIDS = (SSIDS_SCPRI | PROF_SCPRI), - SCAN_PROF_MASK = (PROF_SCPRI), - SCAN_MULTI_CHANNEL = 0x000100, - SCAN_DETERMINISTIC = 0x000200, - SCAN_PROFILE_MATCH_TERMINATED = 0x000400, - SCAN_HOME_CHANNEL_SKIP = 0x000800, - SCAN_CHANNEL_LIST_CONTINUE = 0x001000, - SCAN_CURRENT_SSID_SKIP = 0x002000, - SCAN_ACTIVE_PROBE_DISABLE = 0x004000, - SCAN_CHANNEL_HINT_ONLY = 0x008000, - SCAN_ACTIVE_CHANNELS_ONLY = 0x010000, - SCAN_UNUSED1 = 0x020000, /* unused */ - SCAN_PERIODIC = 0x040000, - SCAN_FIXED_DURATION = 0x080000, - SCAN_AP_ASSISTED = 0x100000, -} DC_SCAN_TYPE; - -typedef enum { - BSS_REPORTING_DEFAULT = 0x0, - EXCLUDE_NON_SCAN_RESULTS = 0x1, /* Exclude results outside of scan */ -} DC_BSS_REPORTING_POLICY; - -typedef enum { - DC_IGNORE_WPAx_GROUP_CIPHER = 0x01, - DC_PROFILE_MATCH_DONE = 0x02, - DC_IGNORE_AAC_BEACON = 0x04, - DC_CSA_FOLLOW_BSS = 0x08, -} DC_PROFILE_FILTER; - -#define DEFAULT_DC_PROFILE_FILTER (DC_CSA_FOLLOW_BSS) - -#endif /* _DISCOVERY_H_ */ diff --git a/drivers/staging/ath6kl/include/common/epping_test.h b/drivers/staging/ath6kl/include/common/epping_test.h deleted file mode 100644 index 9eb5fdf..0000000 --- a/drivers/staging/ath6kl/include/common/epping_test.h +++ /dev/null @@ -1,111 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Author(s): ="Atheros" -// - -/* This file contains shared definitions for the host/target endpoint ping test */ - -#ifndef EPPING_TEST_H_ -#define EPPING_TEST_H_ - - /* alignment to 4-bytes */ -#define EPPING_ALIGNMENT_PAD (((sizeof(struct htc_frame_hdr) + 3) & (~0x3)) - sizeof(struct htc_frame_hdr)) - -#ifndef A_OFFSETOF -#define A_OFFSETOF(type,field) (int)(&(((type *)NULL)->field)) -#endif - -#define EPPING_RSVD_FILL 0xCC - -#define HCI_RSVD_EXPECTED_PKT_TYPE_RECV_OFFSET 7 - -typedef PREPACK struct { - u8 _HCIRsvd[8]; /* reserved for HCI packet header (GMBOX) testing */ - u8 StreamEcho_h; /* stream no. to echo this packet on (filled by host) */ - u8 StreamEchoSent_t; /* stream no. packet was echoed to (filled by target) - When echoed: StreamEchoSent_t == StreamEcho_h */ - u8 StreamRecv_t; /* stream no. that target received this packet on (filled by target) */ - u8 StreamNo_h; /* stream number to send on (filled by host) */ - u8 Magic_h[4]; /* magic number to filter for this packet on the host*/ - u8 _rsvd[6]; /* reserved fields that must be set to a "reserved" value - since this packet maps to a 14-byte ethernet frame we want - to make sure ethertype field is set to something unknown */ - - u8 _pad[2]; /* padding for alignment */ - u8 TimeStamp[8]; /* timestamp of packet (host or target) */ - u32 HostContext_h; /* 4 byte host context, target echos this back */ - u32 SeqNo; /* sequence number (set by host or target) */ - u16 Cmd_h; /* ping command (filled by host) */ - u16 CmdFlags_h; /* optional flags */ - u8 CmdBuffer_h[8]; /* buffer for command (host -> target) */ - u8 CmdBuffer_t[8]; /* buffer for command (target -> host) */ - u16 DataLength; /* length of data */ - u16 DataCRC; /* 16 bit CRC of data */ - u16 HeaderCRC; /* header CRC (fields : StreamNo_h to end, minus HeaderCRC) */ -} POSTPACK EPPING_HEADER; - -#define EPPING_PING_MAGIC_0 0xAA -#define EPPING_PING_MAGIC_1 0x55 -#define EPPING_PING_MAGIC_2 0xCE -#define EPPING_PING_MAGIC_3 0xEC - - - -#define IS_EPPING_PACKET(pPkt) (((pPkt)->Magic_h[0] == EPPING_PING_MAGIC_0) && \ - ((pPkt)->Magic_h[1] == EPPING_PING_MAGIC_1) && \ - ((pPkt)->Magic_h[2] == EPPING_PING_MAGIC_2) && \ - ((pPkt)->Magic_h[3] == EPPING_PING_MAGIC_3)) - -#define SET_EPPING_PACKET_MAGIC(pPkt) { (pPkt)->Magic_h[0] = EPPING_PING_MAGIC_0; \ - (pPkt)->Magic_h[1] = EPPING_PING_MAGIC_1; \ - (pPkt)->Magic_h[2] = EPPING_PING_MAGIC_2; \ - (pPkt)->Magic_h[3] = EPPING_PING_MAGIC_3;} - -#define CMD_FLAGS_DATA_CRC (1 << 0) /* DataCRC field is valid */ -#define CMD_FLAGS_DELAY_ECHO (1 << 1) /* delay the echo of the packet */ -#define CMD_FLAGS_NO_DROP (1 << 2) /* do not drop at HTC layer no matter what the stream is */ - -#define IS_EPING_PACKET_NO_DROP(pPkt) ((pPkt)->CmdFlags_h & CMD_FLAGS_NO_DROP) - -#define EPPING_CMD_ECHO_PACKET 1 /* echo packet test */ -#define EPPING_CMD_RESET_RECV_CNT 2 /* reset recv count */ -#define EPPING_CMD_CAPTURE_RECV_CNT 3 /* fetch recv count, 4-byte count returned in CmdBuffer_t */ -#define EPPING_CMD_NO_ECHO 4 /* non-echo packet test (tx-only) */ -#define EPPING_CMD_CONT_RX_START 5 /* continuous RX packets, parameters are in CmdBuffer_h */ -#define EPPING_CMD_CONT_RX_STOP 6 /* stop continuous RX packet transmission */ - - /* test command parameters may be no more than 8 bytes */ -typedef PREPACK struct { - u16 BurstCnt; /* number of packets to burst together (for HTC 2.1 testing) */ - u16 PacketLength; /* length of packet to generate including header */ - u16 Flags; /* flags */ - -#define EPPING_CONT_RX_DATA_CRC (1 << 0) /* Add CRC to all data */ -#define EPPING_CONT_RX_RANDOM_DATA (1 << 1) /* randomize the data pattern */ -#define EPPING_CONT_RX_RANDOM_LEN (1 << 2) /* randomize the packet lengths */ -} POSTPACK EPPING_CONT_RX_PARAMS; - -#define EPPING_HDR_CRC_OFFSET A_OFFSETOF(EPPING_HEADER,StreamNo_h) -#define EPPING_HDR_BYTES_CRC (sizeof(EPPING_HEADER) - EPPING_HDR_CRC_OFFSET - (sizeof(u16))) - -#define HCI_TRANSPORT_STREAM_NUM 16 /* this number is higher than the define WMM AC classes so we - can use this to distinguish packets */ - -#endif /*EPPING_TEST_H_*/ diff --git a/drivers/staging/ath6kl/include/common/gmboxif.h b/drivers/staging/ath6kl/include/common/gmboxif.h deleted file mode 100644 index ea11c14..0000000 --- a/drivers/staging/ath6kl/include/common/gmboxif.h +++ /dev/null @@ -1,70 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Author(s): ="Atheros" -//============================================================================== - -#ifndef __GMBOXIF_H__ -#define __GMBOXIF_H__ - -/* GMBOX interface definitions */ - -#define AR6K_GMBOX_CREDIT_COUNTER 1 /* we use credit counter 1 to track credits */ -#define AR6K_GMBOX_CREDIT_SIZE_COUNTER 2 /* credit counter 2 is used to pass the size of each credit */ - - - /* HCI UART transport definitions when used over GMBOX interface */ -#define HCI_UART_COMMAND_PKT 0x01 -#define HCI_UART_ACL_PKT 0x02 -#define HCI_UART_SCO_PKT 0x03 -#define HCI_UART_EVENT_PKT 0x04 - - /* definitions for BT HCI packets */ -typedef PREPACK struct { - u16 Flags_ConnHandle; - u16 Length; -} POSTPACK BT_HCI_ACL_HEADER; - -typedef PREPACK struct { - u16 Flags_ConnHandle; - u8 Length; -} POSTPACK BT_HCI_SCO_HEADER; - -typedef PREPACK struct { - u16 OpCode; - u8 ParamLength; -} POSTPACK BT_HCI_COMMAND_HEADER; - -typedef PREPACK struct { - u8 EventCode; - u8 ParamLength; -} POSTPACK BT_HCI_EVENT_HEADER; - -/* MBOX host interrupt signal assignments */ - -#define MBOX_SIG_HCI_BRIDGE_MAX 8 -#define MBOX_SIG_HCI_BRIDGE_BT_ON 0 -#define MBOX_SIG_HCI_BRIDGE_BT_OFF 1 -#define MBOX_SIG_HCI_BRIDGE_BAUD_SET 2 -#define MBOX_SIG_HCI_BRIDGE_PWR_SAV_ON 3 -#define MBOX_SIG_HCI_BRIDGE_PWR_SAV_OFF 4 - - -#endif /* __GMBOXIF_H__ */ - diff --git a/drivers/staging/ath6kl/include/common/gpio_reg.h b/drivers/staging/ath6kl/include/common/gpio_reg.h deleted file mode 100644 index f9d425d..0000000 --- a/drivers/staging/ath6kl/include/common/gpio_reg.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _GPIO_REG_REG_H_ -#define _GPIO_REG_REG_H_ - -#define GPIO_PIN10_ADDRESS 0x00000050 -#define GPIO_PIN11_ADDRESS 0x00000054 -#define GPIO_PIN12_ADDRESS 0x00000058 -#define GPIO_PIN13_ADDRESS 0x0000005c - -#endif /* _GPIO_REG_H_ */ diff --git a/drivers/staging/ath6kl/include/common/htc.h b/drivers/staging/ath6kl/include/common/htc.h deleted file mode 100644 index 85cbfa8..0000000 --- a/drivers/staging/ath6kl/include/common/htc.h +++ /dev/null @@ -1,227 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="htc.h" company="Atheros"> -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Author(s): ="Atheros" -//============================================================================== - -#ifndef __HTC_H__ -#define __HTC_H__ - -#define A_OFFSETOF(type,field) (unsigned long)(&(((type *)NULL)->field)) - -#define ASSEMBLE_UNALIGNED_UINT16(p,highbyte,lowbyte) \ - (((u16)(((u8 *)(p))[(highbyte)])) << 8 | (u16)(((u8 *)(p))[(lowbyte)])) - -/* alignment independent macros (little-endian) to fetch UINT16s or UINT8s from a - * structure using only the type and field name. - * Use these macros if there is the potential for unaligned buffer accesses. */ -#define A_GET_UINT16_FIELD(p,type,field) \ - ASSEMBLE_UNALIGNED_UINT16(p,\ - A_OFFSETOF(type,field) + 1, \ - A_OFFSETOF(type,field)) - -#define A_SET_UINT16_FIELD(p,type,field,value) \ -{ \ - ((u8 *)(p))[A_OFFSETOF(type,field)] = (u8)(value); \ - ((u8 *)(p))[A_OFFSETOF(type,field) + 1] = (u8)((value) >> 8); \ -} - -#define A_GET_UINT8_FIELD(p,type,field) \ - ((u8 *)(p))[A_OFFSETOF(type,field)] - -#define A_SET_UINT8_FIELD(p,type,field,value) \ - ((u8 *)(p))[A_OFFSETOF(type,field)] = (value) - -/****** DANGER DANGER *************** - * - * The frame header length and message formats defined herein were - * selected to accommodate optimal alignment for target processing. This reduces code - * size and improves performance. - * - * Any changes to the header length may alter the alignment and cause exceptions - * on the target. When adding to the message structures insure that fields are - * properly aligned. - * - */ - -/* HTC frame header */ -PREPACK struct htc_frame_hdr { - /* do not remove or re-arrange these fields, these are minimally required - * to take advantage of 4-byte lookaheads in some hardware implementations */ - u8 EndpointID; - u8 Flags; - u16 PayloadLen; /* length of data (including trailer) that follows the header */ - - /***** end of 4-byte lookahead ****/ - - u8 ControlBytes[2]; - - /* message payload starts after the header */ - -} POSTPACK; - -/* frame header flags */ - - /* send direction */ -#define HTC_FLAGS_NEED_CREDIT_UPDATE (1 << 0) -#define HTC_FLAGS_SEND_BUNDLE (1 << 1) /* start or part of bundle */ - /* receive direction */ -#define HTC_FLAGS_RECV_UNUSED_0 (1 << 0) /* bit 0 unused */ -#define HTC_FLAGS_RECV_TRAILER (1 << 1) /* bit 1 trailer data present */ -#define HTC_FLAGS_RECV_UNUSED_2 (1 << 0) /* bit 2 unused */ -#define HTC_FLAGS_RECV_UNUSED_3 (1 << 0) /* bit 3 unused */ -#define HTC_FLAGS_RECV_BUNDLE_CNT_MASK (0xF0) /* bits 7..4 */ -#define HTC_FLAGS_RECV_BUNDLE_CNT_SHIFT 4 - -#define HTC_HDR_LENGTH (sizeof(struct htc_frame_hdr)) -#define HTC_MAX_TRAILER_LENGTH 255 -#define HTC_MAX_PAYLOAD_LENGTH (4096 - sizeof(struct htc_frame_hdr)) - -/* HTC control message IDs */ - -#define HTC_MSG_READY_ID 1 -#define HTC_MSG_CONNECT_SERVICE_ID 2 -#define HTC_MSG_CONNECT_SERVICE_RESPONSE_ID 3 -#define HTC_MSG_SETUP_COMPLETE_ID 4 -#define HTC_MSG_SETUP_COMPLETE_EX_ID 5 - -#define HTC_MAX_CONTROL_MESSAGE_LENGTH 256 - -/* base message ID header */ -typedef PREPACK struct { - u16 MessageID; -} POSTPACK HTC_UNKNOWN_MSG; - -/* HTC ready message - * direction : target-to-host */ -typedef PREPACK struct { - u16 MessageID; /* ID */ - u16 CreditCount; /* number of credits the target can offer */ - u16 CreditSize; /* size of each credit */ - u8 MaxEndpoints; /* maximum number of endpoints the target has resources for */ - u8 _Pad1; -} POSTPACK HTC_READY_MSG; - - /* extended HTC ready message */ -typedef PREPACK struct { - HTC_READY_MSG Version2_0_Info; /* legacy version 2.0 information at the front... */ - /* extended information */ - u8 HTCVersion; - u8 MaxMsgsPerHTCBundle; -} POSTPACK HTC_READY_EX_MSG; - -#define HTC_VERSION_2P0 0x00 -#define HTC_VERSION_2P1 0x01 /* HTC 2.1 */ - -#define HTC_SERVICE_META_DATA_MAX_LENGTH 128 - -/* connect service - * direction : host-to-target */ -typedef PREPACK struct { - u16 MessageID; - u16 ServiceID; /* service ID of the service to connect to */ - u16 ConnectionFlags; /* connection flags */ - -#define HTC_CONNECT_FLAGS_REDUCE_CREDIT_DRIBBLE (1 << 2) /* reduce credit dribbling when - the host needs credits */ -#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_MASK (0x3) -#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_ONE_FOURTH 0x0 -#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_ONE_HALF 0x1 -#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_THREE_FOURTHS 0x2 -#define HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_UNITY 0x3 - - u8 ServiceMetaLength; /* length of meta data that follows */ - u8 _Pad1; - - /* service-specific meta data starts after the header */ - -} POSTPACK HTC_CONNECT_SERVICE_MSG; - -/* connect response - * direction : target-to-host */ -typedef PREPACK struct { - u16 MessageID; - u16 ServiceID; /* service ID that the connection request was made */ - u8 Status; /* service connection status */ - u8 EndpointID; /* assigned endpoint ID */ - u16 MaxMsgSize; /* maximum expected message size on this endpoint */ - u8 ServiceMetaLength; /* length of meta data that follows */ - u8 _Pad1; - - /* service-specific meta data starts after the header */ - -} POSTPACK HTC_CONNECT_SERVICE_RESPONSE_MSG; - -typedef PREPACK struct { - u16 MessageID; - /* currently, no other fields */ -} POSTPACK HTC_SETUP_COMPLETE_MSG; - - /* extended setup completion message */ -typedef PREPACK struct { - u16 MessageID; - u32 SetupFlags; - u8 MaxMsgsPerBundledRecv; - u8 Rsvd[3]; -} POSTPACK HTC_SETUP_COMPLETE_EX_MSG; - -#define HTC_SETUP_COMPLETE_FLAGS_ENABLE_BUNDLE_RECV (1 << 0) - -/* connect response status codes */ -#define HTC_SERVICE_SUCCESS 0 /* success */ -#define HTC_SERVICE_NOT_FOUND 1 /* service could not be found */ -#define HTC_SERVICE_FAILED 2 /* specific service failed the connect */ -#define HTC_SERVICE_NO_RESOURCES 3 /* no resources (i.e. no more endpoints) */ -#define HTC_SERVICE_NO_MORE_EP 4 /* specific service is not allowing any more - endpoints */ - -/* report record IDs */ - -#define HTC_RECORD_NULL 0 -#define HTC_RECORD_CREDITS 1 -#define HTC_RECORD_LOOKAHEAD 2 -#define HTC_RECORD_LOOKAHEAD_BUNDLE 3 - -typedef PREPACK struct { - u8 RecordID; /* Record ID */ - u8 Length; /* Length of record */ -} POSTPACK HTC_RECORD_HDR; - -typedef PREPACK struct { - u8 EndpointID; /* Endpoint that owns these credits */ - u8 Credits; /* credits to report since last report */ -} POSTPACK HTC_CREDIT_REPORT; - -typedef PREPACK struct { - u8 PreValid; /* pre valid guard */ - u8 LookAhead[4]; /* 4 byte lookahead */ - u8 PostValid; /* post valid guard */ - - /* NOTE: the LookAhead array is guarded by a PreValid and Post Valid guard bytes. - * The PreValid bytes must equal the inverse of the PostValid byte */ - -} POSTPACK HTC_LOOKAHEAD_REPORT; - -typedef PREPACK struct { - u8 LookAhead[4]; /* 4 byte lookahead */ -} POSTPACK HTC_BUNDLED_LOOKAHEAD_REPORT; - -#endif /* __HTC_H__ */ - diff --git a/drivers/staging/ath6kl/include/common/htc_services.h b/drivers/staging/ath6kl/include/common/htc_services.h deleted file mode 100644 index fb22268..0000000 --- a/drivers/staging/ath6kl/include/common/htc_services.h +++ /dev/null @@ -1,52 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="htc_services.h" company="Atheros"> -// Copyright (c) 2007 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Author(s): ="Atheros" -//============================================================================== - -#ifndef __HTC_SERVICES_H__ -#define __HTC_SERVICES_H__ - -/* Current service IDs */ - -typedef enum { - RSVD_SERVICE_GROUP = 0, - WMI_SERVICE_GROUP = 1, - - HTC_TEST_GROUP = 254, - HTC_SERVICE_GROUP_LAST = 255 -}HTC_SERVICE_GROUP_IDS; - -#define MAKE_SERVICE_ID(group,index) \ - (int)(((int)group << 8) | (int)(index)) - -/* NOTE: service ID of 0x0000 is reserved and should never be used */ -#define HTC_CTRL_RSVD_SVC MAKE_SERVICE_ID(RSVD_SERVICE_GROUP,1) -#define WMI_CONTROL_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP,0) -#define WMI_DATA_BE_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP,1) -#define WMI_DATA_BK_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP,2) -#define WMI_DATA_VI_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP,3) -#define WMI_DATA_VO_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP,4) -#define WMI_MAX_SERVICES 5 - -/* raw stream service (i.e. flash, tcmd, calibration apps) */ -#define HTC_RAW_STREAMS_SVC MAKE_SERVICE_ID(HTC_TEST_GROUP,0) - -#endif /*HTC_SERVICES_H_*/ diff --git a/drivers/staging/ath6kl/include/common/pkt_log.h b/drivers/staging/ath6kl/include/common/pkt_log.h deleted file mode 100644 index a3719ad..0000000 --- a/drivers/staging/ath6kl/include/common/pkt_log.h +++ /dev/null @@ -1,45 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2005-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Author(s): ="Atheros" -//============================================================================== - -#ifndef __PKT_LOG_H__ -#define __PKT_LOG_H__ - -#ifdef __cplusplus -extern "C" { -#endif - - -/* Pkt log info */ -typedef PREPACK struct pkt_log_t { - struct info_t { - u16 st; - u16 end; - u16 cur; - }info[4096]; - u16 last_idx; -}POSTPACK PACKET_LOG; - - -#ifdef __cplusplus -} -#endif -#endif /* __PKT_LOG_H__ */ diff --git a/drivers/staging/ath6kl/include/common/roaming.h b/drivers/staging/ath6kl/include/common/roaming.h deleted file mode 100644 index 8019850..0000000 --- a/drivers/staging/ath6kl/include/common/roaming.h +++ /dev/null @@ -1,41 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="roaming.h" company="Atheros"> -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Author(s): ="Atheros" -//============================================================================== - -#ifndef _ROAMING_H_ -#define _ROAMING_H_ - -/* - * The signal quality could be in terms of either snr or rssi. We should - * have an enum for both of them. For the time being, we are going to move - * it to wmi.h that is shared by both host and the target, since we are - * repartitioning the code to the host - */ -#define SIGNAL_QUALITY_NOISE_FLOOR -96 -#define SIGNAL_QUALITY_METRICS_NUM_MAX 2 -typedef enum { - SIGNAL_QUALITY_METRICS_SNR = 0, - SIGNAL_QUALITY_METRICS_RSSI, - SIGNAL_QUALITY_METRICS_ALL, -} SIGNAL_QUALITY_METRICS_TYPE; - -#endif /* _ROAMING_H_ */ diff --git a/drivers/staging/ath6kl/include/common/targaddrs.h b/drivers/staging/ath6kl/include/common/targaddrs.h deleted file mode 100644 index c866cef..0000000 --- a/drivers/staging/ath6kl/include/common/targaddrs.h +++ /dev/null @@ -1,395 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -// -// Author(s): ="Atheros" -//------------------------------------------------------------------------------ - -#ifndef __TARGADDRS_H__ -#define __TARGADDRS_H__ - -#if defined(AR6002) -#include "AR6002/addrs.h" -#endif - -/* - * AR6K option bits, to enable/disable various features. - * By default, all option bits are 0. - * These bits can be set in LOCAL_SCRATCH register 0. - */ -#define AR6K_OPTION_BMI_DISABLE 0x01 /* Disable BMI comm with Host */ -#define AR6K_OPTION_SERIAL_ENABLE 0x02 /* Enable serial port msgs */ -#define AR6K_OPTION_WDT_DISABLE 0x04 /* WatchDog Timer override */ -#define AR6K_OPTION_SLEEP_DISABLE 0x08 /* Disable system sleep */ -#define AR6K_OPTION_STOP_BOOT 0x10 /* Stop boot processes (for ATE) */ -#define AR6K_OPTION_ENABLE_NOANI 0x20 /* Operate without ANI */ -#define AR6K_OPTION_DSET_DISABLE 0x40 /* Ignore DataSets */ -#define AR6K_OPTION_IGNORE_FLASH 0x80 /* Ignore flash during bootup */ - -/* - * xxx_HOST_INTEREST_ADDRESS is the address in Target RAM of the - * host_interest structure. It must match the address of the _host_interest - * symbol (see linker script). - * - * Host Interest is shared between Host and Target in order to coordinate - * between the two, and is intended to remain constant (with additions only - * at the end) across software releases. - * - * All addresses are available here so that it's possible to - * write a single binary that works with all Target Types. - * May be used in assembler code as well as C. - */ -#define AR6002_HOST_INTEREST_ADDRESS 0x00500400 -#define AR6003_HOST_INTEREST_ADDRESS 0x00540600 - - -#define HOST_INTEREST_MAX_SIZE 0x100 - -#if !defined(__ASSEMBLER__) -struct register_dump_s; -struct dbglog_hdr_s; - -/* - * These are items that the Host may need to access - * via BMI or via the Diagnostic Window. The position - * of items in this structure must remain constant - * across firmware revisions! - * - * Types for each item must be fixed size across - * target and host platforms. - * - * More items may be added at the end. - */ -PREPACK struct host_interest_s { - /* - * Pointer to application-defined area, if any. - * Set by Target application during startup. - */ - u32 hi_app_host_interest; /* 0x00 */ - - /* Pointer to register dump area, valid after Target crash. */ - u32 hi_failure_state; /* 0x04 */ - - /* Pointer to debug logging header */ - u32 hi_dbglog_hdr; /* 0x08 */ - - u32 hi_unused1; /* 0x0c */ - - /* - * General-purpose flag bits, similar to AR6000_OPTION_* flags. - * Can be used by application rather than by OS. - */ - u32 hi_option_flag; /* 0x10 */ - - /* - * Boolean that determines whether or not to - * display messages on the serial port. - */ - u32 hi_serial_enable; /* 0x14 */ - - /* Start address of DataSet index, if any */ - u32 hi_dset_list_head; /* 0x18 */ - - /* Override Target application start address */ - u32 hi_app_start; /* 0x1c */ - - /* Clock and voltage tuning */ - u32 hi_skip_clock_init; /* 0x20 */ - u32 hi_core_clock_setting; /* 0x24 */ - u32 hi_cpu_clock_setting; /* 0x28 */ - u32 hi_system_sleep_setting; /* 0x2c */ - u32 hi_xtal_control_setting; /* 0x30 */ - u32 hi_pll_ctrl_setting_24ghz; /* 0x34 */ - u32 hi_pll_ctrl_setting_5ghz; /* 0x38 */ - u32 hi_ref_voltage_trim_setting; /* 0x3c */ - u32 hi_clock_info; /* 0x40 */ - - /* - * Flash configuration overrides, used only - * when firmware is not executing from flash. - * (When using flash, modify the global variables - * with equivalent names.) - */ - u32 hi_bank0_addr_value; /* 0x44 */ - u32 hi_bank0_read_value; /* 0x48 */ - u32 hi_bank0_write_value; /* 0x4c */ - u32 hi_bank0_config_value; /* 0x50 */ - - /* Pointer to Board Data */ - u32 hi_board_data; /* 0x54 */ - u32 hi_board_data_initialized; /* 0x58 */ - - u32 hi_dset_RAM_index_table; /* 0x5c */ - - u32 hi_desired_baud_rate; /* 0x60 */ - u32 hi_dbglog_config; /* 0x64 */ - u32 hi_end_RAM_reserve_sz; /* 0x68 */ - u32 hi_mbox_io_block_sz; /* 0x6c */ - - u32 hi_num_bpatch_streams; /* 0x70 -- unused */ - u32 hi_mbox_isr_yield_limit; /* 0x74 */ - - u32 hi_refclk_hz; /* 0x78 */ - u32 hi_ext_clk_detected; /* 0x7c */ - u32 hi_dbg_uart_txpin; /* 0x80 */ - u32 hi_dbg_uart_rxpin; /* 0x84 */ - u32 hi_hci_uart_baud; /* 0x88 */ - u32 hi_hci_uart_pin_assignments; /* 0x8C */ - /* NOTE: byte [0] = tx pin, [1] = rx pin, [2] = rts pin, [3] = cts pin */ - u32 hi_hci_uart_baud_scale_val; /* 0x90 */ - u32 hi_hci_uart_baud_step_val; /* 0x94 */ - - u32 hi_allocram_start; /* 0x98 */ - u32 hi_allocram_sz; /* 0x9c */ - u32 hi_hci_bridge_flags; /* 0xa0 */ - u32 hi_hci_uart_support_pins; /* 0xa4 */ - /* NOTE: byte [0] = RESET pin (bit 7 is polarity), bytes[1]..bytes[3] are for future use */ - u32 hi_hci_uart_pwr_mgmt_params; /* 0xa8 */ - /* - * 0xa8 - [1]: 0 = UART FC active low, 1 = UART FC active high - * [31:16]: wakeup timeout in ms - */ - - /* Pointer to extended board data */ - u32 hi_board_ext_data; /* 0xac */ - u32 hi_board_ext_data_config; /* 0xb0 */ - - /* - * Bit [0] : valid - * Bit[31:16: size - */ - /* - * hi_reset_flag is used to do some stuff when target reset. - * such as restore app_start after warm reset or - * preserve host Interest area, or preserve ROM data, literals etc. - */ - u32 hi_reset_flag; /* 0xb4 */ - /* indicate hi_reset_flag is valid */ - u32 hi_reset_flag_valid; /* 0xb8 */ - u32 hi_hci_uart_pwr_mgmt_params_ext; /* 0xbc */ - /* - * 0xbc - [31:0]: idle timeout in ms - */ - /* ACS flags */ - u32 hi_acs_flags; /* 0xc0 */ - u32 hi_console_flags; /* 0xc4 */ - u32 hi_nvram_state; /* 0xc8 */ - u32 hi_option_flag2; /* 0xcc */ - - /* If non-zero, override values sent to Host in WMI_READY event. */ - u32 hi_sw_version_override; /* 0xd0 */ - u32 hi_abi_version_override; /* 0xd4 */ - - /* - * Percentage of high priority RX traffic to total expected RX traffic - - * applicable only to ar6004 - */ - u32 hi_hp_rx_traffic_ratio; /* 0xd8 */ - - /* test applications flags */ - u32 hi_test_apps_related ; /* 0xdc */ - /* location of test script */ - u32 hi_ota_testscript; /* 0xe0 */ - /* location of CAL data */ - u32 hi_cal_data; /* 0xe4 */ - /* Number of packet log buffers */ - u32 hi_pktlog_num_buffers; /* 0xe8 */ - -} POSTPACK; - -/* Bits defined in hi_option_flag */ -#define HI_OPTION_TIMER_WAR 0x01 /* Enable timer workaround */ -#define HI_OPTION_BMI_CRED_LIMIT 0x02 /* Limit BMI command credits */ -#define HI_OPTION_RELAY_DOT11_HDR 0x04 /* Relay Dot11 hdr to/from host */ -/* MAC addr method 0-locally administred 1-globally unique addrs */ -#define HI_OPTION_MAC_ADDR_METHOD 0x08 -#define HI_OPTION_FW_BRIDGE 0x10 /* Firmware Bridging */ -#define HI_OPTION_ENABLE_PROFILE 0x20 /* Enable CPU profiling */ -#define HI_OPTION_DISABLE_DBGLOG 0x40 /* Disable debug logging */ -#define HI_OPTION_SKIP_ERA_TRACKING 0x80 /* Skip Era Tracking */ -#define HI_OPTION_PAPRD_DISABLE 0x100 /* Disable PAPRD (debug) */ -#define HI_OPTION_NUM_DEV_LSB 0x200 -#define HI_OPTION_NUM_DEV_MSB 0x800 -#define HI_OPTION_DEV_MODE_LSB 0x1000 -#define HI_OPTION_DEV_MODE_MSB 0x8000000 -/* Disable LowFreq Timer Stabilization */ -#define HI_OPTION_NO_LFT_STBL 0x10000000 -#define HI_OPTION_SKIP_REG_SCAN 0x20000000 /* Skip regulatory scan */ -/* Do regulatory scan during init beforesending WMI ready event to host */ -#define HI_OPTION_INIT_REG_SCAN 0x40000000 -#define HI_OPTION_SKIP_MEMMAP 0x80000000 /* REV6: Do not adjust memory - map */ - -/* hi_option_flag2 options */ -#define HI_OPTION_OFFLOAD_AMSDU 0x01 -#define HI_OPTION_DFS_SUPPORT 0x02 /* Enable DFS support */ - -#define HI_OPTION_MAC_ADDR_METHOD_SHIFT 3 - -/* 2 bits of hi_option_flag are used to represent 3 modes */ -#define HI_OPTION_FW_MODE_IBSS 0x0 /* IBSS Mode */ -#define HI_OPTION_FW_MODE_BSS_STA 0x1 /* STA Mode */ -#define HI_OPTION_FW_MODE_AP 0x2 /* AP Mode */ - -/* 2 bits of hi_option flag are usedto represent 4 submodes */ -#define HI_OPTION_FW_SUBMODE_NONE 0x0 /* Normal mode */ -#define HI_OPTION_FW_SUBMODE_P2PDEV 0x1 /* p2p device mode */ -#define HI_OPTION_FW_SUBMODE_P2PCLIENT 0x2 /* p2p client mode */ -#define HI_OPTION_FW_SUBMODE_P2PGO 0x3 /* p2p go mode */ - -/* Num dev Mask */ -#define HI_OPTION_NUM_DEV_MASK 0x7 -#define HI_OPTION_NUM_DEV_SHIFT 0x9 - -/* firmware bridging */ -#define HI_OPTION_FW_BRIDGE_SHIFT 0x04 - -/* Fw Mode/SubMode Mask -|------------------------------------------------------------------------------| -| SUB | SUB | SUB | SUB | | | | -| MODE[3] | MODE[2] | MODE[1] | MODE[0] | MODE[3] | MODE[2] | MODE[1] | MODE[0| -| (2) | (2) | (2) | (2) | (2) | (2) | (2) | (2) -|------------------------------------------------------------------------------| -*/ -#define HI_OPTION_FW_MODE_BITS 0x2 -#define HI_OPTION_FW_MODE_MASK 0x3 -#define HI_OPTION_FW_MODE_SHIFT 0xC -#define HI_OPTION_ALL_FW_MODE_MASK 0xFF - -#define HI_OPTION_FW_SUBMODE_BITS 0x2 -#define HI_OPTION_FW_SUBMODE_MASK 0x3 -#define HI_OPTION_FW_SUBMODE_SHIFT 0x14 -#define HI_OPTION_ALL_FW_SUBMODE_MASK 0xFF00 -#define HI_OPTION_ALL_FW_SUBMODE_SHIFT 0x8 - -/* hi_reset_flag */ - -/* preserve App Start address */ -#define HI_RESET_FLAG_PRESERVE_APP_START 0x01 -/* preserve host interest */ -#define HI_RESET_FLAG_PRESERVE_HOST_INTEREST 0x02 -#define HI_RESET_FLAG_PRESERVE_ROMDATA 0x04 /* preserve ROM data */ -#define HI_RESET_FLAG_PRESERVE_NVRAM_STATE 0x08 -#define HI_RESET_FLAG_PRESERVE_BOOT_INFO 0x10 - -#define HI_RESET_FLAG_IS_VALID 0x12345678 /* indicate the reset flag is -valid */ - -#define ON_RESET_FLAGS_VALID() \ - (HOST_INTEREST->hi_reset_flag_valid == HI_RESET_FLAG_IS_VALID) - -#define RESET_FLAGS_VALIDATE() \ - (HOST_INTEREST->hi_reset_flag_valid = HI_RESET_FLAG_IS_VALID) - -#define RESET_FLAGS_INVALIDATE() \ - (HOST_INTEREST->hi_reset_flag_valid = 0) - -#define ON_RESET_PRESERVE_APP_START() \ - (HOST_INTEREST->hi_reset_flag & HI_RESET_FLAG_PRESERVE_APP_START) - -#define ON_RESET_PRESERVE_NVRAM_STATE() \ - (HOST_INTEREST->hi_reset_flag & HI_RESET_FLAG_PRESERVE_NVRAM_STATE) - -#define ON_RESET_PRESERVE_HOST_INTEREST() \ - (HOST_INTEREST->hi_reset_flag & HI_RESET_FLAG_PRESERVE_HOST_INTEREST) - -#define ON_RESET_PRESERVE_ROMDATA() \ - (HOST_INTEREST->hi_reset_flag & HI_RESET_FLAG_PRESERVE_ROMDATA) - -#define ON_RESET_PRESERVE_BOOT_INFO() \ - (HOST_INTEREST->hi_reset_flag & HI_RESET_FLAG_PRESERVE_BOOT_INFO) - -#define HI_ACS_FLAGS_ENABLED (1 << 0) /* ACS is enabled */ -#define HI_ACS_FLAGS_USE_WWAN (1 << 1) /* Use physical WWAN device */ -#define HI_ACS_FLAGS_TEST_VAP (1 << 2) /* Use test VAP */ - -/* CONSOLE FLAGS - * - * Bit Range Meaning - * --------- -------------------------------- - * 2..0 UART ID (0 = Default) - * 3 Baud Select (0 = 9600, 1 = 115200) - * 30..4 Reserved - * 31 Enable Console - * - */ - -#define HI_CONSOLE_FLAGS_ENABLE (1 << 31) -#define HI_CONSOLE_FLAGS_UART_MASK (0x7) -#define HI_CONSOLE_FLAGS_UART_SHIFT 0 -#define HI_CONSOLE_FLAGS_BAUD_SELECT (1 << 3) - -/* - * Intended for use by Host software, this macro returns the Target RAM - * address of any item in the host_interest structure. - * Example: target_addr = AR6002_HOST_INTEREST_ITEM_ADDRESS(hi_board_data); - */ -#define AR6002_HOST_INTEREST_ITEM_ADDRESS(item) \ - (u32)((unsigned long)&((((struct host_interest_s *)(AR6002_HOST_INTEREST_ADDRESS))->item))) - -#define AR6003_HOST_INTEREST_ITEM_ADDRESS(item) \ - (u32)((unsigned long)&((((struct host_interest_s *)(AR6003_HOST_INTEREST_ADDRESS))->item))) - -#define AR6004_HOST_INTEREST_ITEM_ADDRESS(item) \ - ((u32)&((((struct host_interest_s *)(AR6004_HOST_INTEREST_ADDRESS))->item))) - - -#define HOST_INTEREST_DBGLOG_IS_ENABLED() \ - (!(HOST_INTEREST->hi_option_flag & HI_OPTION_DISABLE_DBGLOG)) - -#define HOST_INTEREST_PKTLOG_IS_ENABLED() \ - ((HOST_INTEREST->hi_pktlog_num_buffers)) - - -#define HOST_INTEREST_PROFILE_IS_ENABLED() \ - (HOST_INTEREST->hi_option_flag & HI_OPTION_ENABLE_PROFILE) - -#define LF_TIMER_STABILIZATION_IS_ENABLED() \ - (!(HOST_INTEREST->hi_option_flag & HI_OPTION_NO_LFT_STBL)) - -#define IS_AMSDU_OFFLAOD_ENABLED() \ - ((HOST_INTEREST->hi_option_flag2 & HI_OPTION_OFFLOAD_AMSDU)) - -#define HOST_INTEREST_DFS_IS_ENABLED() \ - ((HOST_INTEREST->hi_option_flag2 & HI_OPTION_DFS_SUPPORT)) - -/* Convert a Target virtual address into a Target physical address */ -#define AR6002_VTOP(vaddr) ((vaddr) & 0x001fffff) -#define AR6003_VTOP(vaddr) ((vaddr) & 0x001fffff) -#define TARG_VTOP(TargetType, vaddr) \ - (((TargetType) == TARGET_TYPE_AR6002) ? AR6002_VTOP(vaddr) : AR6003_VTOP(vaddr)) - -#define AR6003_REV2_APP_START_OVERRIDE 0x944C00 -#define AR6003_REV2_APP_LOAD_ADDRESS 0x543180 -#define AR6003_REV2_BOARD_EXT_DATA_ADDRESS 0x57E500 -#define AR6003_REV2_DATASET_PATCH_ADDRESS 0x57e884 -#define AR6003_REV2_RAM_RESERVE_SIZE 6912 - -#define AR6003_REV3_APP_START_OVERRIDE 0x945d00 -#define AR6003_REV3_APP_LOAD_ADDRESS 0x545000 -#define AR6003_REV3_BOARD_EXT_DATA_ADDRESS 0x542330 -#define AR6003_REV3_DATASET_PATCH_ADDRESS 0x57FF74 -#define AR6003_REV3_RAM_RESERVE_SIZE 512 - -#define AR6003_BOARD_EXT_DATA_ADDRESS 0x57E600 - -/* # of u32 entries in targregs, used by DIAG_FETCH_TARG_REGS */ -#define AR6003_FETCH_TARG_REGS_COUNT 64 - -#endif /* !__ASSEMBLER__ */ - -#endif /* __TARGADDRS_H__ */ diff --git a/drivers/staging/ath6kl/include/common/testcmd.h b/drivers/staging/ath6kl/include/common/testcmd.h deleted file mode 100644 index 7d94aee..0000000 --- a/drivers/staging/ath6kl/include/common/testcmd.h +++ /dev/null @@ -1,185 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="testcmd.h" company="Atheros"> -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Author(s): ="Atheros" -//============================================================================== - -#ifndef TESTCMD_H_ -#define TESTCMD_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef AR6002_REV2 -#define TCMD_MAX_RATES 12 -#else -#define TCMD_MAX_RATES 28 -#endif - -typedef enum { - ZEROES_PATTERN = 0, - ONES_PATTERN, - REPEATING_10, - PN7_PATTERN, - PN9_PATTERN, - PN15_PATTERN -}TX_DATA_PATTERN; - -/* Continuous tx - mode : TCMD_CONT_TX_OFF - Disabling continuous tx - TCMD_CONT_TX_SINE - Enable continuous unmodulated tx - TCMD_CONT_TX_FRAME- Enable continuous modulated tx - freq : Channel freq in Mhz. (e.g 2412 for channel 1 in 11 g) -dataRate: 0 - 1 Mbps - 1 - 2 Mbps - 2 - 5.5 Mbps - 3 - 11 Mbps - 4 - 6 Mbps - 5 - 9 Mbps - 6 - 12 Mbps - 7 - 18 Mbps - 8 - 24 Mbps - 9 - 36 Mbps - 10 - 28 Mbps - 11 - 54 Mbps - txPwr: Tx power in dBm[5 -11] for unmod Tx, [5-14] for mod Tx -antenna: 1 - one antenna - 2 - two antenna -Note : Enable/disable continuous tx test cmd works only when target is awake. -*/ - -typedef enum { - TCMD_CONT_TX_OFF = 0, - TCMD_CONT_TX_SINE, - TCMD_CONT_TX_FRAME, - TCMD_CONT_TX_TX99, - TCMD_CONT_TX_TX100 -} TCMD_CONT_TX_MODE; - -typedef enum { - TCMD_WLAN_MODE_NOHT = 0, - TCMD_WLAN_MODE_HT20 = 1, - TCMD_WLAN_MODE_HT40PLUS = 2, - TCMD_WLAN_MODE_HT40MINUS = 3, -} TCMD_WLAN_MODE; - -typedef PREPACK struct { - u32 testCmdId; - u32 mode; - u32 freq; - u32 dataRate; - s32 txPwr; - u32 antenna; - u32 enANI; - u32 scramblerOff; - u32 aifsn; - u16 pktSz; - u16 txPattern; - u32 shortGuard; - u32 numPackets; - u32 wlanMode; -} POSTPACK TCMD_CONT_TX; - -#define TCMD_TXPATTERN_ZERONE 0x1 -#define TCMD_TXPATTERN_ZERONE_DIS_SCRAMBLE 0x2 - -/* Continuous Rx - act: TCMD_CONT_RX_PROMIS - promiscuous mode (accept all incoming frames) - TCMD_CONT_RX_FILTER - filter mode (accept only frames with dest - address equal specified - mac address (set via act =3) - TCMD_CONT_RX_REPORT off mode (disable cont rx mode and get the - report from the last cont - Rx test) - - TCMD_CONT_RX_SETMAC - set MacAddr mode (sets the MAC address for the - target. This Overrides - the default MAC address.) - -*/ -typedef enum { - TCMD_CONT_RX_PROMIS =0, - TCMD_CONT_RX_FILTER, - TCMD_CONT_RX_REPORT, - TCMD_CONT_RX_SETMAC, - TCMD_CONT_RX_SET_ANT_SWITCH_TABLE -} TCMD_CONT_RX_ACT; - -typedef PREPACK struct { - u32 testCmdId; - u32 act; - u32 enANI; - PREPACK union { - struct PREPACK TCMD_CONT_RX_PARA { - u32 freq; - u32 antenna; - u32 wlanMode; - } POSTPACK para; - struct PREPACK TCMD_CONT_RX_REPORT { - u32 totalPkt; - s32 rssiInDBm; - u32 crcErrPkt; - u32 secErrPkt; - u16 rateCnt[TCMD_MAX_RATES]; - u16 rateCntShortGuard[TCMD_MAX_RATES]; - } POSTPACK report; - struct PREPACK TCMD_CONT_RX_MAC { - u8 addr[ATH_MAC_LEN]; - } POSTPACK mac; - struct PREPACK TCMD_CONT_RX_ANT_SWITCH_TABLE { - u32 antswitch1; - u32 antswitch2; - }POSTPACK antswitchtable; - } POSTPACK u; -} POSTPACK TCMD_CONT_RX; - -/* Force sleep/wake test cmd - mode: TCMD_PM_WAKEUP - Wakeup the target - TCMD_PM_SLEEP - Force the target to sleep. - */ -typedef enum { - TCMD_PM_WAKEUP = 1, /* be consistent with target */ - TCMD_PM_SLEEP, - TCMD_PM_DEEPSLEEP -} TCMD_PM_MODE; - -typedef PREPACK struct { - u32 testCmdId; - u32 mode; -} POSTPACK TCMD_PM; - -typedef enum { - TCMD_CONT_TX_ID, - TCMD_CONT_RX_ID, - TCMD_PM_ID -} TCMD_ID; - -typedef PREPACK union { - TCMD_CONT_TX contTx; - TCMD_CONT_RX contRx; - TCMD_PM pm; -} POSTPACK TEST_CMD; - -#ifdef __cplusplus -} -#endif - -#endif /* TESTCMD_H_ */ diff --git a/drivers/staging/ath6kl/include/common/tlpm.h b/drivers/staging/ath6kl/include/common/tlpm.h deleted file mode 100644 index 659b1c0..0000000 --- a/drivers/staging/ath6kl/include/common/tlpm.h +++ /dev/null @@ -1,38 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Author(s): ="Atheros" -//============================================================================== - -#ifndef __TLPM_H__ -#define __TLPM_H__ - -/* idle timeout in 16-bit value as in HOST_INTEREST hi_hci_uart_pwr_mgmt_params */ -#define TLPM_DEFAULT_IDLE_TIMEOUT_MS 1000 -/* hex in LSB and MSB for HCI command */ -#define TLPM_DEFAULT_IDLE_TIMEOUT_LSB 0xE8 -#define TLPM_DEFAULT_IDLE_TIMEOUT_MSB 0x3 - -/* wakeup timeout in 8-bit value as in HOST_INTEREST hi_hci_uart_pwr_mgmt_params */ -#define TLPM_DEFAULT_WAKEUP_TIMEOUT_MS 10 - -/* default UART FC polarity is low */ -#define TLPM_DEFAULT_UART_FC_POLARITY 0 - -#endif diff --git a/drivers/staging/ath6kl/include/common/wlan_defs.h b/drivers/staging/ath6kl/include/common/wlan_defs.h deleted file mode 100644 index 03e4d23..0000000 --- a/drivers/staging/ath6kl/include/common/wlan_defs.h +++ /dev/null @@ -1,79 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="wlan_defs.h" company="Atheros"> -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Author(s): ="Atheros" -//============================================================================== -#ifndef __WLAN_DEFS_H__ -#define __WLAN_DEFS_H__ - -/* - * This file contains WLAN definitions that may be used across both - * Host and Target software. - */ - -typedef enum { - MODE_11A = 0, /* 11a Mode */ - MODE_11G = 1, /* 11b/g Mode */ - MODE_11B = 2, /* 11b Mode */ - MODE_11GONLY = 3, /* 11g only Mode */ -#ifdef SUPPORT_11N - MODE_11NA_HT20 = 4, /* 11a HT20 mode */ - MODE_11NG_HT20 = 5, /* 11g HT20 mode */ - MODE_11NA_HT40 = 6, /* 11a HT40 mode */ - MODE_11NG_HT40 = 7, /* 11g HT40 mode */ - MODE_UNKNOWN = 8, - MODE_MAX = 8 -#else - MODE_UNKNOWN = 4, - MODE_MAX = 4 -#endif -} WLAN_PHY_MODE; - -typedef enum { - WLAN_11A_CAPABILITY = 1, - WLAN_11G_CAPABILITY = 2, - WLAN_11AG_CAPABILITY = 3, -}WLAN_CAPABILITY; - -#ifdef SUPPORT_11N -typedef unsigned long A_RATEMASK; -#else -typedef unsigned short A_RATEMASK; -#endif - -#ifdef SUPPORT_11N -#define IS_MODE_11A(mode) (((mode) == MODE_11A) || \ - ((mode) == MODE_11NA_HT20) || \ - ((mode) == MODE_11NA_HT40)) -#define IS_MODE_11B(mode) ((mode) == MODE_11B) -#define IS_MODE_11G(mode) (((mode) == MODE_11G) || \ - ((mode) == MODE_11GONLY) || \ - ((mode) == MODE_11NG_HT20) || \ - ((mode) == MODE_11NG_HT40)) -#define IS_MODE_11GONLY(mode) ((mode) == MODE_11GONLY) -#else -#define IS_MODE_11A(mode) ((mode) == MODE_11A) -#define IS_MODE_11B(mode) ((mode) == MODE_11B) -#define IS_MODE_11G(mode) (((mode) == MODE_11G) || \ - ((mode) == MODE_11GONLY)) -#define IS_MODE_11GONLY(mode) ((mode) == MODE_11GONLY) -#endif /* SUPPORT_11N */ - -#endif /* __WLANDEFS_H__ */ diff --git a/drivers/staging/ath6kl/include/common/wmi.h b/drivers/staging/ath6kl/include/common/wmi.h deleted file mode 100644 index d9687443..0000000 --- a/drivers/staging/ath6kl/include/common/wmi.h +++ /dev/null @@ -1,3220 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -// -// Author(s): ="Atheros" -//------------------------------------------------------------------------------ - -/* - * This file contains the definitions of the WMI protocol specified in the - * Wireless Module Interface (WMI). It includes definitions of all the - * commands and events. Commands are messages from the host to the WM. - * Events and Replies are messages from the WM to the host. - * - * Ownership of correctness in regards to commands - * belongs to the host driver and the WMI is not required to validate - * parameters for value, proper range, or any other checking. - * - */ - -#ifndef _WMI_H_ -#define _WMI_H_ - -#include "wmix.h" -#include "wlan_defs.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define HTC_PROTOCOL_VERSION 0x0002 -#define HTC_PROTOCOL_REVISION 0x0000 - -#define WMI_PROTOCOL_VERSION 0x0002 -#define WMI_PROTOCOL_REVISION 0x0000 - -#define ATH_MAC_LEN 6 /* length of mac in bytes */ -#define WMI_CMD_MAX_LEN 100 -#define WMI_CONTROL_MSG_MAX_LEN 256 -#define WMI_OPT_CONTROL_MSG_MAX_LEN 1536 -#define IS_ETHERTYPE(_typeOrLen) ((_typeOrLen) >= 0x0600) -#define RFC1042OUI {0x00, 0x00, 0x00} - -#define IP_ETHERTYPE 0x0800 - -#define WMI_IMPLICIT_PSTREAM 0xFF -#define WMI_MAX_THINSTREAM 15 - -#ifdef AR6002_REV2 -#define IBSS_MAX_NUM_STA 4 -#else -#define IBSS_MAX_NUM_STA 8 -#endif - -PREPACK struct host_app_area_s { - u32 wmi_protocol_ver; -} POSTPACK; - -/* - * Data Path - */ -typedef PREPACK struct { - u8 dstMac[ATH_MAC_LEN]; - u8 srcMac[ATH_MAC_LEN]; - u16 typeOrLen; -} POSTPACK ATH_MAC_HDR; - -typedef PREPACK struct { - u8 dsap; - u8 ssap; - u8 cntl; - u8 orgCode[3]; - u16 etherType; -} POSTPACK ATH_LLC_SNAP_HDR; - -typedef enum { - DATA_MSGTYPE = 0x0, - CNTL_MSGTYPE, - SYNC_MSGTYPE, - OPT_MSGTYPE, -} WMI_MSG_TYPE; - - -/* - * Macros for operating on WMI_DATA_HDR (info) field - */ - -#define WMI_DATA_HDR_MSG_TYPE_MASK 0x03 -#define WMI_DATA_HDR_MSG_TYPE_SHIFT 0 -#define WMI_DATA_HDR_UP_MASK 0x07 -#define WMI_DATA_HDR_UP_SHIFT 2 -/* In AP mode, the same bit (b5) is used to indicate Power save state in - * the Rx dir and More data bit state in the tx direction. - */ -#define WMI_DATA_HDR_PS_MASK 0x1 -#define WMI_DATA_HDR_PS_SHIFT 5 - -#define WMI_DATA_HDR_MORE_MASK 0x1 -#define WMI_DATA_HDR_MORE_SHIFT 5 - -typedef enum { - WMI_DATA_HDR_DATA_TYPE_802_3 = 0, - WMI_DATA_HDR_DATA_TYPE_802_11, - WMI_DATA_HDR_DATA_TYPE_ACL, /* used to be used for the PAL */ -} WMI_DATA_HDR_DATA_TYPE; - -#define WMI_DATA_HDR_DATA_TYPE_MASK 0x3 -#define WMI_DATA_HDR_DATA_TYPE_SHIFT 6 - -#define WMI_DATA_HDR_SET_MORE_BIT(h) ((h)->info |= (WMI_DATA_HDR_MORE_MASK << WMI_DATA_HDR_MORE_SHIFT)) - -#define WMI_DATA_HDR_IS_MSG_TYPE(h, t) (((h)->info & (WMI_DATA_HDR_MSG_TYPE_MASK)) == (t)) -#define WMI_DATA_HDR_SET_MSG_TYPE(h, t) (h)->info = (((h)->info & ~(WMI_DATA_HDR_MSG_TYPE_MASK << WMI_DATA_HDR_MSG_TYPE_SHIFT)) | (t << WMI_DATA_HDR_MSG_TYPE_SHIFT)) -#define WMI_DATA_HDR_GET_UP(h) (((h)->info >> WMI_DATA_HDR_UP_SHIFT) & WMI_DATA_HDR_UP_MASK) -#define WMI_DATA_HDR_SET_UP(h, p) (h)->info = (((h)->info & ~(WMI_DATA_HDR_UP_MASK << WMI_DATA_HDR_UP_SHIFT)) | (p << WMI_DATA_HDR_UP_SHIFT)) - -#define WMI_DATA_HDR_GET_DATA_TYPE(h) (((h)->info >> WMI_DATA_HDR_DATA_TYPE_SHIFT) & WMI_DATA_HDR_DATA_TYPE_MASK) -#define WMI_DATA_HDR_SET_DATA_TYPE(h, p) (h)->info = (((h)->info & ~(WMI_DATA_HDR_DATA_TYPE_MASK << WMI_DATA_HDR_DATA_TYPE_SHIFT)) | ((p) << WMI_DATA_HDR_DATA_TYPE_SHIFT)) - -#define WMI_DATA_HDR_GET_DOT11(h) (WMI_DATA_HDR_GET_DATA_TYPE((h)) == WMI_DATA_HDR_DATA_TYPE_802_11) -#define WMI_DATA_HDR_SET_DOT11(h, p) WMI_DATA_HDR_SET_DATA_TYPE((h), (p)) - -/* Macros for operating on WMI_DATA_HDR (info2) field */ -#define WMI_DATA_HDR_SEQNO_MASK 0xFFF -#define WMI_DATA_HDR_SEQNO_SHIFT 0 - -#define WMI_DATA_HDR_AMSDU_MASK 0x1 -#define WMI_DATA_HDR_AMSDU_SHIFT 12 - -#define WMI_DATA_HDR_META_MASK 0x7 -#define WMI_DATA_HDR_META_SHIFT 13 - -#define GET_SEQ_NO(_v) ((_v) & WMI_DATA_HDR_SEQNO_MASK) -#define GET_ISMSDU(_v) ((_v) & WMI_DATA_HDR_AMSDU_MASK) - -#define WMI_DATA_HDR_GET_SEQNO(h) GET_SEQ_NO((h)->info2 >> WMI_DATA_HDR_SEQNO_SHIFT) -#define WMI_DATA_HDR_SET_SEQNO(h, _v) ((h)->info2 = ((h)->info2 & ~(WMI_DATA_HDR_SEQNO_MASK << WMI_DATA_HDR_SEQNO_SHIFT)) | (GET_SEQ_NO(_v) << WMI_DATA_HDR_SEQNO_SHIFT)) - -#define WMI_DATA_HDR_IS_AMSDU(h) GET_ISMSDU((h)->info2 >> WMI_DATA_HDR_AMSDU_SHIFT) -#define WMI_DATA_HDR_SET_AMSDU(h, _v) ((h)->info2 = ((h)->info2 & ~(WMI_DATA_HDR_AMSDU_MASK << WMI_DATA_HDR_AMSDU_SHIFT)) | (GET_ISMSDU(_v) << WMI_DATA_HDR_AMSDU_SHIFT)) - -#define WMI_DATA_HDR_GET_META(h) (((h)->info2 >> WMI_DATA_HDR_META_SHIFT) & WMI_DATA_HDR_META_MASK) -#define WMI_DATA_HDR_SET_META(h, _v) ((h)->info2 = ((h)->info2 & ~(WMI_DATA_HDR_META_MASK << WMI_DATA_HDR_META_SHIFT)) | ((_v) << WMI_DATA_HDR_META_SHIFT)) - -/* Macros for operating on WMI_DATA_HDR (info3) field */ -#define WMI_DATA_HDR_DEVID_MASK 0xF -#define WMI_DATA_HDR_DEVID_SHIFT 0 -#define GET_DEVID(_v) ((_v) & WMI_DATA_HDR_DEVID_MASK) - -#define WMI_DATA_HDR_GET_DEVID(h) \ - (((h)->info3 >> WMI_DATA_HDR_DEVID_SHIFT) & WMI_DATA_HDR_DEVID_MASK) -#define WMI_DATA_HDR_SET_DEVID(h, _v) \ - ((h)->info3 = ((h)->info3 & ~(WMI_DATA_HDR_DEVID_MASK << WMI_DATA_HDR_DEVID_SHIFT)) | (GET_DEVID(_v) << WMI_DATA_HDR_DEVID_SHIFT)) - -typedef PREPACK struct { - s8 rssi; - u8 info; /* usage of 'info' field(8-bit): - * b1:b0 - WMI_MSG_TYPE - * b4:b3:b2 - UP(tid) - * b5 - Used in AP mode. More-data in tx dir, PS in rx. - * b7:b6 - Dot3 header(0), - * Dot11 Header(1), - * ACL data(2) - */ - - u16 info2; /* usage of 'info2' field(16-bit): - * b11:b0 - seq_no - * b12 - A-MSDU? - * b15:b13 - META_DATA_VERSION 0 - 7 - */ - u16 info3; -} POSTPACK WMI_DATA_HDR; - -/* - * TX META VERSION DEFINITIONS - */ -#define WMI_MAX_TX_META_SZ (12) -#define WMI_MAX_TX_META_VERSION (7) -#define WMI_META_VERSION_1 (0x01) -#define WMI_META_VERSION_2 (0X02) - -#define WMI_ACL_TO_DOT11_HEADROOM 36 - -#if 0 /* removed to prevent compile errors for WM.. */ -typedef PREPACK struct { -/* intentionally empty. Default version is no meta data. */ -} POSTPACK WMI_TX_META_V0; -#endif - -typedef PREPACK struct { - u8 pktID; /* The packet ID to identify the tx request */ - u8 ratePolicyID; /* The rate policy to be used for the tx of this frame */ -} POSTPACK WMI_TX_META_V1; - - -#define WMI_CSUM_DIR_TX (0x1) -#define TX_CSUM_CALC_FILL (0x1) -typedef PREPACK struct { - u8 csumStart; /*Offset from start of the WMI header for csum calculation to begin */ - u8 csumDest; /*Offset from start of WMI header where final csum goes*/ - u8 csumFlags; /*number of bytes over which csum is calculated*/ -} POSTPACK WMI_TX_META_V2; - - -/* - * RX META VERSION DEFINITIONS - */ -/* if RX meta data is present at all then the meta data field - * will consume WMI_MAX_RX_META_SZ bytes of space between the - * WMI_DATA_HDR and the payload. How much of the available - * Meta data is actually used depends on which meta data - * version is active. */ -#define WMI_MAX_RX_META_SZ (12) -#define WMI_MAX_RX_META_VERSION (7) - -#define WMI_RX_STATUS_OK 0 /* success */ -#define WMI_RX_STATUS_DECRYPT_ERR 1 /* decrypt error */ -#define WMI_RX_STATUS_MIC_ERR 2 /* tkip MIC error */ -#define WMI_RX_STATUS_ERR 3 /* undefined error */ - -#define WMI_RX_FLAGS_AGGR 0x0001 /* part of AGGR */ -#define WMI_RX_FlAGS_STBC 0x0002 /* used STBC */ -#define WMI_RX_FLAGS_SGI 0x0004 /* used SGI */ -#define WMI_RX_FLAGS_HT 0x0008 /* is HT packet */ -/* the flags field is also used to store the CRYPTO_TYPE of the frame - * that value is shifted by WMI_RX_FLAGS_CRYPTO_SHIFT */ -#define WMI_RX_FLAGS_CRYPTO_SHIFT 4 -#define WMI_RX_FLAGS_CRYPTO_MASK 0x1f -#define WMI_RX_META_GET_CRYPTO(flags) (((flags) >> WMI_RX_FLAGS_CRYPTO_SHIFT) & WMI_RX_FLAGS_CRYPTO_MASK) - -#if 0 /* removed to prevent compile errors for WM.. */ -typedef PREPACK struct { -/* intentionally empty. Default version is no meta data. */ -} POSTPACK WMI_RX_META_VERSION_0; -#endif - -typedef PREPACK struct { - u8 status; /* one of WMI_RX_STATUS_... */ - u8 rix; /* rate index mapped to rate at which this packet was received. */ - u8 rssi; /* rssi of packet */ - u8 channel;/* rf channel during packet reception */ - u16 flags; /* a combination of WMI_RX_FLAGS_... */ -} POSTPACK WMI_RX_META_V1; - -#define RX_CSUM_VALID_FLAG (0x1) -typedef PREPACK struct { - u16 csum; - u8 csumFlags;/* bit 0 set -partial csum valid - bit 1 set -test mode */ -} POSTPACK WMI_RX_META_V2; - - - -#define WMI_GET_DEVICE_ID(info1) ((info1) & 0xF) -/* Macros for operating on WMI_CMD_HDR (info1) field */ -#define WMI_CMD_HDR_DEVID_MASK 0xF -#define WMI_CMD_HDR_DEVID_SHIFT 0 -#define GET_CMD_DEVID(_v) ((_v) & WMI_CMD_HDR_DEVID_MASK) - -#define WMI_CMD_HDR_GET_DEVID(h) \ - (((h)->info1 >> WMI_CMD_HDR_DEVID_SHIFT) & WMI_CMD_HDR_DEVID_MASK) -#define WMI_CMD_HDR_SET_DEVID(h, _v) \ - ((h)->info1 = ((h)->info1 & \ - ~(WMI_CMD_HDR_DEVID_MASK << WMI_CMD_HDR_DEVID_SHIFT)) | \ - (GET_CMD_DEVID(_v) << WMI_CMD_HDR_DEVID_SHIFT)) - -/* - * Control Path - */ -typedef PREPACK struct { - u16 commandId; -/* - * info1 - 16 bits - * b03:b00 - id - * b15:b04 - unused - */ - u16 info1; - - u16 reserved; /* For alignment */ -} POSTPACK WMI_CMD_HDR; /* used for commands and events */ - -/* - * List of Commnands - */ -typedef enum { - WMI_CONNECT_CMDID = 0x0001, - WMI_RECONNECT_CMDID, - WMI_DISCONNECT_CMDID, - WMI_SYNCHRONIZE_CMDID, - WMI_CREATE_PSTREAM_CMDID, - WMI_DELETE_PSTREAM_CMDID, - WMI_START_SCAN_CMDID, - WMI_SET_SCAN_PARAMS_CMDID, - WMI_SET_BSS_FILTER_CMDID, - WMI_SET_PROBED_SSID_CMDID, /* 10 */ - WMI_SET_LISTEN_INT_CMDID, - WMI_SET_BMISS_TIME_CMDID, - WMI_SET_DISC_TIMEOUT_CMDID, - WMI_GET_CHANNEL_LIST_CMDID, - WMI_SET_BEACON_INT_CMDID, - WMI_GET_STATISTICS_CMDID, - WMI_SET_CHANNEL_PARAMS_CMDID, - WMI_SET_POWER_MODE_CMDID, - WMI_SET_IBSS_PM_CAPS_CMDID, - WMI_SET_POWER_PARAMS_CMDID, /* 20 */ - WMI_SET_POWERSAVE_TIMERS_POLICY_CMDID, - WMI_ADD_CIPHER_KEY_CMDID, - WMI_DELETE_CIPHER_KEY_CMDID, - WMI_ADD_KRK_CMDID, - WMI_DELETE_KRK_CMDID, - WMI_SET_PMKID_CMDID, - WMI_SET_TX_PWR_CMDID, - WMI_GET_TX_PWR_CMDID, - WMI_SET_ASSOC_INFO_CMDID, - WMI_ADD_BAD_AP_CMDID, /* 30 */ - WMI_DELETE_BAD_AP_CMDID, - WMI_SET_TKIP_COUNTERMEASURES_CMDID, - WMI_RSSI_THRESHOLD_PARAMS_CMDID, - WMI_TARGET_ERROR_REPORT_BITMASK_CMDID, - WMI_SET_ACCESS_PARAMS_CMDID, - WMI_SET_RETRY_LIMITS_CMDID, - WMI_SET_OPT_MODE_CMDID, - WMI_OPT_TX_FRAME_CMDID, - WMI_SET_VOICE_PKT_SIZE_CMDID, - WMI_SET_MAX_SP_LEN_CMDID, /* 40 */ - WMI_SET_ROAM_CTRL_CMDID, - WMI_GET_ROAM_TBL_CMDID, - WMI_GET_ROAM_DATA_CMDID, - WMI_ENABLE_RM_CMDID, - WMI_SET_MAX_OFFHOME_DURATION_CMDID, - WMI_EXTENSION_CMDID, /* Non-wireless extensions */ - WMI_SNR_THRESHOLD_PARAMS_CMDID, - WMI_LQ_THRESHOLD_PARAMS_CMDID, - WMI_SET_LPREAMBLE_CMDID, - WMI_SET_RTS_CMDID, /* 50 */ - WMI_CLR_RSSI_SNR_CMDID, - WMI_SET_FIXRATES_CMDID, - WMI_GET_FIXRATES_CMDID, - WMI_SET_AUTH_MODE_CMDID, - WMI_SET_REASSOC_MODE_CMDID, - WMI_SET_WMM_CMDID, - WMI_SET_WMM_TXOP_CMDID, - WMI_TEST_CMDID, - /* COEX AR6002 only*/ - WMI_SET_BT_STATUS_CMDID, - WMI_SET_BT_PARAMS_CMDID, /* 60 */ - - WMI_SET_KEEPALIVE_CMDID, - WMI_GET_KEEPALIVE_CMDID, - WMI_SET_APPIE_CMDID, - WMI_GET_APPIE_CMDID, - WMI_SET_WSC_STATUS_CMDID, - - /* Wake on Wireless */ - WMI_SET_HOST_SLEEP_MODE_CMDID, - WMI_SET_WOW_MODE_CMDID, - WMI_GET_WOW_LIST_CMDID, - WMI_ADD_WOW_PATTERN_CMDID, - WMI_DEL_WOW_PATTERN_CMDID, /* 70 */ - - WMI_SET_FRAMERATES_CMDID, - WMI_SET_AP_PS_CMDID, - WMI_SET_QOS_SUPP_CMDID, - /* WMI_THIN_RESERVED_... mark the start and end - * values for WMI_THIN_RESERVED command IDs. These - * command IDs can be found in wmi_thin.h */ - WMI_THIN_RESERVED_START = 0x8000, - WMI_THIN_RESERVED_END = 0x8fff, - /* - * Developer commands starts at 0xF000 - */ - WMI_SET_BITRATE_CMDID = 0xF000, - WMI_GET_BITRATE_CMDID, - WMI_SET_WHALPARAM_CMDID, - - - /*Should add the new command to the tail for compatible with - * etna. - */ - WMI_SET_MAC_ADDRESS_CMDID, - WMI_SET_AKMP_PARAMS_CMDID, - WMI_SET_PMKID_LIST_CMDID, - WMI_GET_PMKID_LIST_CMDID, - WMI_ABORT_SCAN_CMDID, - WMI_SET_TARGET_EVENT_REPORT_CMDID, - - // Unused - WMI_UNUSED1, - WMI_UNUSED2, - - /* - * AP mode commands - */ - WMI_AP_HIDDEN_SSID_CMDID, - WMI_AP_SET_NUM_STA_CMDID, - WMI_AP_ACL_POLICY_CMDID, - WMI_AP_ACL_MAC_LIST_CMDID, - WMI_AP_CONFIG_COMMIT_CMDID, - WMI_AP_SET_MLME_CMDID, - WMI_AP_SET_PVB_CMDID, - WMI_AP_CONN_INACT_CMDID, - WMI_AP_PROT_SCAN_TIME_CMDID, - WMI_AP_SET_COUNTRY_CMDID, - WMI_AP_SET_DTIM_CMDID, - WMI_AP_MODE_STAT_CMDID, - - WMI_SET_IP_CMDID, - WMI_SET_PARAMS_CMDID, - WMI_SET_MCAST_FILTER_CMDID, - WMI_DEL_MCAST_FILTER_CMDID, - - WMI_ALLOW_AGGR_CMDID, - WMI_ADDBA_REQ_CMDID, - WMI_DELBA_REQ_CMDID, - WMI_SET_HT_CAP_CMDID, - WMI_SET_HT_OP_CMDID, - WMI_SET_TX_SELECT_RATES_CMDID, - WMI_SET_TX_SGI_PARAM_CMDID, - WMI_SET_RATE_POLICY_CMDID, - - WMI_HCI_CMD_CMDID, - WMI_RX_FRAME_FORMAT_CMDID, - WMI_SET_THIN_MODE_CMDID, - WMI_SET_BT_WLAN_CONN_PRECEDENCE_CMDID, - - WMI_AP_SET_11BG_RATESET_CMDID, - WMI_SET_PMK_CMDID, - WMI_MCAST_FILTER_CMDID, - /* COEX CMDID AR6003*/ - WMI_SET_BTCOEX_FE_ANT_CMDID, - WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMDID, - WMI_SET_BTCOEX_SCO_CONFIG_CMDID, - WMI_SET_BTCOEX_A2DP_CONFIG_CMDID, - WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMDID, - WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMDID, - WMI_SET_BTCOEX_DEBUG_CMDID, - WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID, - WMI_GET_BTCOEX_STATS_CMDID, - WMI_GET_BTCOEX_CONFIG_CMDID, - - WMI_SET_DFS_ENABLE_CMDID, /* F034 */ - WMI_SET_DFS_MINRSSITHRESH_CMDID, - WMI_SET_DFS_MAXPULSEDUR_CMDID, - WMI_DFS_RADAR_DETECTED_CMDID, - - /* P2P CMDS */ - WMI_P2P_SET_CONFIG_CMDID, /* F038 */ - WMI_WPS_SET_CONFIG_CMDID, - WMI_SET_REQ_DEV_ATTR_CMDID, - WMI_P2P_FIND_CMDID, - WMI_P2P_STOP_FIND_CMDID, - WMI_P2P_GO_NEG_START_CMDID, - WMI_P2P_LISTEN_CMDID, - - WMI_CONFIG_TX_MAC_RULES_CMDID, /* F040 */ - WMI_SET_PROMISCUOUS_MODE_CMDID, - WMI_RX_FRAME_FILTER_CMDID, - WMI_SET_CHANNEL_CMDID, - - /* WAC commands */ - WMI_ENABLE_WAC_CMDID, - WMI_WAC_SCAN_REPLY_CMDID, - WMI_WAC_CTRL_REQ_CMDID, - WMI_SET_DIV_PARAMS_CMDID, - - WMI_GET_PMK_CMDID, - WMI_SET_PASSPHRASE_CMDID, - WMI_SEND_ASSOC_RES_CMDID, - WMI_SET_ASSOC_REQ_RELAY_CMDID, - WMI_GET_RFKILL_MODE_CMDID, - - /* ACS command, consists of sub-commands */ - WMI_ACS_CTRL_CMDID, - - /* Ultra low power store / recall commands */ - WMI_STORERECALL_CONFIGURE_CMDID, - WMI_STORERECALL_RECALL_CMDID, - WMI_STORERECALL_HOST_READY_CMDID, - WMI_FORCE_TARGET_ASSERT_CMDID, - WMI_SET_EXCESS_TX_RETRY_THRES_CMDID, -} WMI_COMMAND_ID; - -/* - * Frame Types - */ -typedef enum { - WMI_FRAME_BEACON = 0, - WMI_FRAME_PROBE_REQ, - WMI_FRAME_PROBE_RESP, - WMI_FRAME_ASSOC_REQ, - WMI_FRAME_ASSOC_RESP, - WMI_NUM_MGMT_FRAME -} WMI_MGMT_FRAME_TYPE; - -/* - * Connect Command - */ -typedef enum { - INFRA_NETWORK = 0x01, - ADHOC_NETWORK = 0x02, - ADHOC_CREATOR = 0x04, - AP_NETWORK = 0x10, -} NETWORK_TYPE; - -typedef enum { - OPEN_AUTH = 0x01, - SHARED_AUTH = 0x02, - LEAP_AUTH = 0x04, /* different from IEEE_AUTH_MODE definitions */ -} DOT11_AUTH_MODE; - -enum { - AUTH_IDLE, - AUTH_OPEN_IN_PROGRESS, -}; - -typedef enum { - NONE_AUTH = 0x01, - WPA_AUTH = 0x02, - WPA2_AUTH = 0x04, - WPA_PSK_AUTH = 0x08, - WPA2_PSK_AUTH = 0x10, - WPA_AUTH_CCKM = 0x20, - WPA2_AUTH_CCKM = 0x40, -} AUTH_MODE; - -typedef enum { - NONE_CRYPT = 0x01, - WEP_CRYPT = 0x02, - TKIP_CRYPT = 0x04, - AES_CRYPT = 0x08, -#ifdef WAPI_ENABLE - WAPI_CRYPT = 0x10, -#endif /*WAPI_ENABLE*/ -} CRYPTO_TYPE; - -#define WMI_MIN_CRYPTO_TYPE NONE_CRYPT -#define WMI_MAX_CRYPTO_TYPE (AES_CRYPT + 1) - -#ifdef WAPI_ENABLE -#undef WMI_MAX_CRYPTO_TYPE -#define WMI_MAX_CRYPTO_TYPE (WAPI_CRYPT + 1) -#endif /* WAPI_ENABLE */ - -#ifdef WAPI_ENABLE -#define IW_ENCODE_ALG_SM4 0x20 -#define IW_AUTH_WAPI_ENABLED 0x20 -#endif - -#define WMI_MIN_KEY_INDEX 0 -#define WMI_MAX_KEY_INDEX 3 - -#ifdef WAPI_ENABLE -#undef WMI_MAX_KEY_INDEX -#define WMI_MAX_KEY_INDEX 7 /* wapi grpKey 0-3, prwKey 4-7 */ -#endif /* WAPI_ENABLE */ - -#define WMI_MAX_KEY_LEN 32 - -#define WMI_MAX_SSID_LEN 32 - -typedef enum { - CONNECT_ASSOC_POLICY_USER = 0x0001, - CONNECT_SEND_REASSOC = 0x0002, - CONNECT_IGNORE_WPAx_GROUP_CIPHER = 0x0004, - CONNECT_PROFILE_MATCH_DONE = 0x0008, - CONNECT_IGNORE_AAC_BEACON = 0x0010, - CONNECT_CSA_FOLLOW_BSS = 0x0020, - CONNECT_DO_WPA_OFFLOAD = 0x0040, - CONNECT_DO_NOT_DEAUTH = 0x0080, -} WMI_CONNECT_CTRL_FLAGS_BITS; - -#define DEFAULT_CONNECT_CTRL_FLAGS (CONNECT_CSA_FOLLOW_BSS) - -typedef PREPACK struct { - u8 networkType; - u8 dot11AuthMode; - u8 authMode; - u8 pairwiseCryptoType; - u8 pairwiseCryptoLen; - u8 groupCryptoType; - u8 groupCryptoLen; - u8 ssidLength; - u8 ssid[WMI_MAX_SSID_LEN]; - u16 channel; - u8 bssid[ATH_MAC_LEN]; - u32 ctrl_flags; -} POSTPACK WMI_CONNECT_CMD; - -/* - * WMI_RECONNECT_CMDID - */ -typedef PREPACK struct { - u16 channel; /* hint */ - u8 bssid[ATH_MAC_LEN]; /* mandatory if set */ -} POSTPACK WMI_RECONNECT_CMD; - -#define WMI_PMK_LEN 32 -typedef PREPACK struct { - u8 pmk[WMI_PMK_LEN]; -} POSTPACK WMI_SET_PMK_CMD; - -/* - * WMI_SET_EXCESS_TX_RETRY_THRES_CMDID - */ -typedef PREPACK struct { - u32 threshold; -} POSTPACK WMI_SET_EXCESS_TX_RETRY_THRES_CMD; - -/* - * WMI_ADD_CIPHER_KEY_CMDID - */ -typedef enum { - PAIRWISE_USAGE = 0x00, - GROUP_USAGE = 0x01, - TX_USAGE = 0x02, /* default Tx Key - Static WEP only */ -} KEY_USAGE; - -/* - * Bit Flag - * Bit 0 - Initialise TSC - default is Initialize - */ -#define KEY_OP_INIT_TSC 0x01 -#define KEY_OP_INIT_RSC 0x02 -#ifdef WAPI_ENABLE -#define KEY_OP_INIT_WAPIPN 0x10 -#endif /* WAPI_ENABLE */ - -#define KEY_OP_INIT_VAL 0x03 /* Default Initialise the TSC & RSC */ -#define KEY_OP_VALID_MASK 0x03 - -typedef PREPACK struct { - u8 keyIndex; - u8 keyType; - u8 keyUsage; /* KEY_USAGE */ - u8 keyLength; - u8 keyRSC[8]; /* key replay sequence counter */ - u8 key[WMI_MAX_KEY_LEN]; - u8 key_op_ctrl; /* Additional Key Control information */ - u8 key_macaddr[ATH_MAC_LEN]; -} POSTPACK WMI_ADD_CIPHER_KEY_CMD; - -/* - * WMI_DELETE_CIPHER_KEY_CMDID - */ -typedef PREPACK struct { - u8 keyIndex; -} POSTPACK WMI_DELETE_CIPHER_KEY_CMD; - -#define WMI_KRK_LEN 16 -/* - * WMI_ADD_KRK_CMDID - */ -typedef PREPACK struct { - u8 krk[WMI_KRK_LEN]; -} POSTPACK WMI_ADD_KRK_CMD; - -/* - * WMI_SET_TKIP_COUNTERMEASURES_CMDID - */ -typedef enum { - WMI_TKIP_CM_DISABLE = 0x0, - WMI_TKIP_CM_ENABLE = 0x1, -} WMI_TKIP_CM_CONTROL; - -typedef PREPACK struct { - u8 cm_en; /* WMI_TKIP_CM_CONTROL */ -} POSTPACK WMI_SET_TKIP_COUNTERMEASURES_CMD; - -/* - * WMI_SET_PMKID_CMDID - */ - -#define WMI_PMKID_LEN 16 - -typedef enum { - PMKID_DISABLE = 0, - PMKID_ENABLE = 1, -} PMKID_ENABLE_FLG; - -typedef PREPACK struct { - u8 bssid[ATH_MAC_LEN]; - u8 enable; /* PMKID_ENABLE_FLG */ - u8 pmkid[WMI_PMKID_LEN]; -} POSTPACK WMI_SET_PMKID_CMD; - -/* - * WMI_START_SCAN_CMD - */ -typedef enum { - WMI_LONG_SCAN = 0, - WMI_SHORT_SCAN = 1, -} WMI_SCAN_TYPE; - -typedef PREPACK struct { - u32 forceFgScan; - u32 isLegacy; /* For Legacy Cisco AP compatibility */ - u32 homeDwellTime; /* Maximum duration in the home channel(milliseconds) */ - u32 forceScanInterval; /* Time interval between scans (milliseconds)*/ - u8 scanType; /* WMI_SCAN_TYPE */ - u8 numChannels; /* how many channels follow */ - u16 channelList[1]; /* channels in Mhz */ -} POSTPACK WMI_START_SCAN_CMD; - -/* - * WMI_SET_SCAN_PARAMS_CMDID - */ -#define WMI_SHORTSCANRATIO_DEFAULT 3 -/* - * Warning: ScanCtrlFlag value of 0xFF is used to disable all flags in WMI_SCAN_PARAMS_CMD - * Do not add any more flags to WMI_SCAN_CTRL_FLAG_BITS - */ -typedef enum { - CONNECT_SCAN_CTRL_FLAGS = 0x01, /* set if can scan in the Connect cmd */ - SCAN_CONNECTED_CTRL_FLAGS = 0x02, /* set if scan for the SSID it is */ - /* already connected to */ - ACTIVE_SCAN_CTRL_FLAGS = 0x04, /* set if enable active scan */ - ROAM_SCAN_CTRL_FLAGS = 0x08, /* set if enable roam scan when bmiss and lowrssi */ - REPORT_BSSINFO_CTRL_FLAGS = 0x10, /* set if follows customer BSSINFO reporting rule */ - ENABLE_AUTO_CTRL_FLAGS = 0x20, /* if disabled, target doesn't - scan after a disconnect event */ - ENABLE_SCAN_ABORT_EVENT = 0x40 /* Scan complete event with canceled status will be generated when a scan is prempted before it gets completed */ -} WMI_SCAN_CTRL_FLAGS_BITS; - -#define CAN_SCAN_IN_CONNECT(flags) (flags & CONNECT_SCAN_CTRL_FLAGS) -#define CAN_SCAN_CONNECTED(flags) (flags & SCAN_CONNECTED_CTRL_FLAGS) -#define ENABLE_ACTIVE_SCAN(flags) (flags & ACTIVE_SCAN_CTRL_FLAGS) -#define ENABLE_ROAM_SCAN(flags) (flags & ROAM_SCAN_CTRL_FLAGS) -#define CONFIG_REPORT_BSSINFO(flags) (flags & REPORT_BSSINFO_CTRL_FLAGS) -#define IS_AUTO_SCAN_ENABLED(flags) (flags & ENABLE_AUTO_CTRL_FLAGS) -#define SCAN_ABORT_EVENT_ENABLED(flags) (flags & ENABLE_SCAN_ABORT_EVENT) - -#define DEFAULT_SCAN_CTRL_FLAGS (CONNECT_SCAN_CTRL_FLAGS| SCAN_CONNECTED_CTRL_FLAGS| ACTIVE_SCAN_CTRL_FLAGS| ROAM_SCAN_CTRL_FLAGS | ENABLE_AUTO_CTRL_FLAGS) - - -typedef PREPACK struct { - u16 fg_start_period; /* seconds */ - u16 fg_end_period; /* seconds */ - u16 bg_period; /* seconds */ - u16 maxact_chdwell_time; /* msec */ - u16 pas_chdwell_time; /* msec */ - u8 shortScanRatio; /* how many shorts scan for one long */ - u8 scanCtrlFlags; - u16 minact_chdwell_time; /* msec */ - u16 maxact_scan_per_ssid; /* max active scans per ssid */ - u32 max_dfsch_act_time; /* msecs */ -} POSTPACK WMI_SCAN_PARAMS_CMD; - -/* - * WMI_SET_BSS_FILTER_CMDID - */ -typedef enum { - NONE_BSS_FILTER = 0x0, /* no beacons forwarded */ - ALL_BSS_FILTER, /* all beacons forwarded */ - PROFILE_FILTER, /* only beacons matching profile */ - ALL_BUT_PROFILE_FILTER, /* all but beacons matching profile */ - CURRENT_BSS_FILTER, /* only beacons matching current BSS */ - ALL_BUT_BSS_FILTER, /* all but beacons matching BSS */ - PROBED_SSID_FILTER, /* beacons matching probed ssid */ - LAST_BSS_FILTER, /* marker only */ -} WMI_BSS_FILTER; - -typedef PREPACK struct { - u8 bssFilter; /* see WMI_BSS_FILTER */ - u8 reserved1; /* For alignment */ - u16 reserved2; /* For alignment */ - u32 ieMask; -} POSTPACK WMI_BSS_FILTER_CMD; - -/* - * WMI_SET_PROBED_SSID_CMDID - */ -#define MAX_PROBED_SSID_INDEX 9 - -typedef enum { - DISABLE_SSID_FLAG = 0, /* disables entry */ - SPECIFIC_SSID_FLAG = 0x01, /* probes specified ssid */ - ANY_SSID_FLAG = 0x02, /* probes for any ssid */ -} WMI_SSID_FLAG; - -typedef PREPACK struct { - u8 entryIndex; /* 0 to MAX_PROBED_SSID_INDEX */ - u8 flag; /* WMI_SSID_FLG */ - u8 ssidLength; - u8 ssid[32]; -} POSTPACK WMI_PROBED_SSID_CMD; - -/* - * WMI_SET_LISTEN_INT_CMDID - * The Listen interval is between 15 and 3000 TUs - */ -#define MIN_LISTEN_INTERVAL 15 -#define MAX_LISTEN_INTERVAL 5000 -#define MIN_LISTEN_BEACONS 1 -#define MAX_LISTEN_BEACONS 50 - -typedef PREPACK struct { - u16 listenInterval; - u16 numBeacons; -} POSTPACK WMI_LISTEN_INT_CMD; - -/* - * WMI_SET_BEACON_INT_CMDID - */ -typedef PREPACK struct { - u16 beaconInterval; -} POSTPACK WMI_BEACON_INT_CMD; - -/* - * WMI_SET_BMISS_TIME_CMDID - * valid values are between 1000 and 5000 TUs - */ - -#define MIN_BMISS_TIME 1000 -#define MAX_BMISS_TIME 5000 -#define MIN_BMISS_BEACONS 1 -#define MAX_BMISS_BEACONS 50 - -typedef PREPACK struct { - u16 bmissTime; - u16 numBeacons; -} POSTPACK WMI_BMISS_TIME_CMD; - -/* - * WMI_SET_POWER_MODE_CMDID - */ -typedef enum { - REC_POWER = 0x01, - MAX_PERF_POWER, -} WMI_POWER_MODE; - -typedef PREPACK struct { - u8 powerMode; /* WMI_POWER_MODE */ -} POSTPACK WMI_POWER_MODE_CMD; - -typedef PREPACK struct { - s8 status; /* WMI_SET_PARAMS_REPLY */ -} POSTPACK WMI_SET_PARAMS_REPLY; - -typedef PREPACK struct { - u32 opcode; - u32 length; - char buffer[1]; /* WMI_SET_PARAMS */ -} POSTPACK WMI_SET_PARAMS_CMD; - -typedef PREPACK struct { - u8 multicast_mac[ATH_MAC_LEN]; /* WMI_SET_MCAST_FILTER */ -} POSTPACK WMI_SET_MCAST_FILTER_CMD; - -typedef PREPACK struct { - u8 enable; /* WMI_MCAST_FILTER */ -} POSTPACK WMI_MCAST_FILTER_CMD; - -/* - * WMI_SET_POWER_PARAMS_CMDID - */ -typedef enum { - IGNORE_DTIM = 0x01, - NORMAL_DTIM = 0x02, - STICK_DTIM = 0x03, - AUTO_DTIM = 0x04, -} WMI_DTIM_POLICY; - -/* Policy to determnine whether TX should wakeup WLAN if sleeping */ -typedef enum { - TX_WAKEUP_UPON_SLEEP = 1, - TX_DONT_WAKEUP_UPON_SLEEP = 2 -} WMI_TX_WAKEUP_POLICY_UPON_SLEEP; - -/* - * Policy to determnine whether power save failure event should be sent to - * host during scanning - */ -typedef enum { - SEND_POWER_SAVE_FAIL_EVENT_ALWAYS = 1, - IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN = 2, -} POWER_SAVE_FAIL_EVENT_POLICY; - -typedef PREPACK struct { - u16 idle_period; /* msec */ - u16 pspoll_number; - u16 dtim_policy; - u16 tx_wakeup_policy; - u16 num_tx_to_wakeup; - u16 ps_fail_event_policy; -} POSTPACK WMI_POWER_PARAMS_CMD; - -/* Adhoc power save types */ -typedef enum { - ADHOC_PS_DISABLE=1, - ADHOC_PS_ATH=2, - ADHOC_PS_IEEE=3, - ADHOC_PS_OTHER=4, -} WMI_ADHOC_PS_TYPE; - -typedef PREPACK struct { - u8 power_saving; - u8 ttl; /* number of beacon periods */ - u16 atim_windows; /* msec */ - u16 timeout_value; /* msec */ -} POSTPACK WMI_IBSS_PM_CAPS_CMD; - -/* AP power save types */ -typedef enum { - AP_PS_DISABLE=1, - AP_PS_ATH=2, -} WMI_AP_PS_TYPE; - -typedef PREPACK struct { - u32 idle_time; /* in msec */ - u32 ps_period; /* in usec */ - u8 sleep_period; /* in ps periods */ - u8 psType; -} POSTPACK WMI_AP_PS_CMD; - -/* - * WMI_SET_POWERSAVE_TIMERS_POLICY_CMDID - */ -typedef enum { - IGNORE_TIM_ALL_QUEUES_APSD = 0, - PROCESS_TIM_ALL_QUEUES_APSD = 1, - IGNORE_TIM_SIMULATED_APSD = 2, - PROCESS_TIM_SIMULATED_APSD = 3, -} APSD_TIM_POLICY; - -typedef PREPACK struct { - u16 psPollTimeout; /* msec */ - u16 triggerTimeout; /* msec */ - u32 apsdTimPolicy; /* TIM behavior with ques APSD enabled. Default is IGNORE_TIM_ALL_QUEUES_APSD */ - u32 simulatedAPSDTimPolicy; /* TIM behavior with simulated APSD enabled. Default is PROCESS_TIM_SIMULATED_APSD */ -} POSTPACK WMI_POWERSAVE_TIMERS_POLICY_CMD; - -/* - * WMI_SET_VOICE_PKT_SIZE_CMDID - */ -typedef PREPACK struct { - u16 voicePktSize; -} POSTPACK WMI_SET_VOICE_PKT_SIZE_CMD; - -/* - * WMI_SET_MAX_SP_LEN_CMDID - */ -typedef enum { - DELIVER_ALL_PKT = 0x0, - DELIVER_2_PKT = 0x1, - DELIVER_4_PKT = 0x2, - DELIVER_6_PKT = 0x3, -} APSD_SP_LEN_TYPE; - -typedef PREPACK struct { - u8 maxSPLen; -} POSTPACK WMI_SET_MAX_SP_LEN_CMD; - -/* - * WMI_SET_DISC_TIMEOUT_CMDID - */ -typedef PREPACK struct { - u8 disconnectTimeout; /* seconds */ -} POSTPACK WMI_DISC_TIMEOUT_CMD; - -typedef enum { - UPLINK_TRAFFIC = 0, - DNLINK_TRAFFIC = 1, - BIDIR_TRAFFIC = 2, -} DIR_TYPE; - -typedef enum { - DISABLE_FOR_THIS_AC = 0, - ENABLE_FOR_THIS_AC = 1, - ENABLE_FOR_ALL_AC = 2, -} VOICEPS_CAP_TYPE; - -typedef enum { - TRAFFIC_TYPE_APERIODIC = 0, - TRAFFIC_TYPE_PERIODIC = 1, -}TRAFFIC_TYPE; - -/* - * WMI_SYNCHRONIZE_CMDID - */ -typedef PREPACK struct { - u8 dataSyncMap; -} POSTPACK WMI_SYNC_CMD; - -/* - * WMI_CREATE_PSTREAM_CMDID - */ -typedef PREPACK struct { - u32 minServiceInt; /* in milli-sec */ - u32 maxServiceInt; /* in milli-sec */ - u32 inactivityInt; /* in milli-sec */ - u32 suspensionInt; /* in milli-sec */ - u32 serviceStartTime; - u32 minDataRate; /* in bps */ - u32 meanDataRate; /* in bps */ - u32 peakDataRate; /* in bps */ - u32 maxBurstSize; - u32 delayBound; - u32 minPhyRate; /* in bps */ - u32 sba; - u32 mediumTime; - u16 nominalMSDU; /* in octects */ - u16 maxMSDU; /* in octects */ - u8 trafficClass; - u8 trafficDirection; /* DIR_TYPE */ - u8 rxQueueNum; - u8 trafficType; /* TRAFFIC_TYPE */ - u8 voicePSCapability; /* VOICEPS_CAP_TYPE */ - u8 tsid; - u8 userPriority; /* 802.1D user priority */ - u8 nominalPHY; /* nominal phy rate */ -} POSTPACK WMI_CREATE_PSTREAM_CMD; - -/* - * WMI_DELETE_PSTREAM_CMDID - */ -typedef PREPACK struct { - u8 txQueueNumber; - u8 rxQueueNumber; - u8 trafficDirection; - u8 trafficClass; - u8 tsid; -} POSTPACK WMI_DELETE_PSTREAM_CMD; - -/* - * WMI_SET_CHANNEL_PARAMS_CMDID - */ -typedef enum { - WMI_11A_MODE = 0x1, - WMI_11G_MODE = 0x2, - WMI_11AG_MODE = 0x3, - WMI_11B_MODE = 0x4, - WMI_11GONLY_MODE = 0x5, -} WMI_PHY_MODE; - -#define WMI_MAX_CHANNELS 32 - -typedef PREPACK struct { - u8 reserved1; - u8 scanParam; /* set if enable scan */ - u8 phyMode; /* see WMI_PHY_MODE */ - u8 numChannels; /* how many channels follow */ - u16 channelList[1]; /* channels in Mhz */ -} POSTPACK WMI_CHANNEL_PARAMS_CMD; - - -/* - * WMI_RSSI_THRESHOLD_PARAMS_CMDID - * Setting the polltime to 0 would disable polling. - * Threshold values are in the ascending order, and should agree to: - * (lowThreshold_lowerVal < lowThreshold_upperVal < highThreshold_lowerVal - * < highThreshold_upperVal) - */ - -typedef PREPACK struct WMI_RSSI_THRESHOLD_PARAMS{ - u32 pollTime; /* Polling time as a factor of LI */ - s16 thresholdAbove1_Val; /* lowest of upper */ - s16 thresholdAbove2_Val; - s16 thresholdAbove3_Val; - s16 thresholdAbove4_Val; - s16 thresholdAbove5_Val; - s16 thresholdAbove6_Val; /* highest of upper */ - s16 thresholdBelow1_Val; /* lowest of bellow */ - s16 thresholdBelow2_Val; - s16 thresholdBelow3_Val; - s16 thresholdBelow4_Val; - s16 thresholdBelow5_Val; - s16 thresholdBelow6_Val; /* highest of bellow */ - u8 weight; /* "alpha" */ - u8 reserved[3]; -} POSTPACK WMI_RSSI_THRESHOLD_PARAMS_CMD; - -/* - * WMI_SNR_THRESHOLD_PARAMS_CMDID - * Setting the polltime to 0 would disable polling. - */ - -typedef PREPACK struct WMI_SNR_THRESHOLD_PARAMS{ - u32 pollTime; /* Polling time as a factor of LI */ - u8 weight; /* "alpha" */ - u8 thresholdAbove1_Val; /* lowest of uppper*/ - u8 thresholdAbove2_Val; - u8 thresholdAbove3_Val; - u8 thresholdAbove4_Val; /* highest of upper */ - u8 thresholdBelow1_Val; /* lowest of bellow */ - u8 thresholdBelow2_Val; - u8 thresholdBelow3_Val; - u8 thresholdBelow4_Val; /* highest of bellow */ - u8 reserved[3]; -} POSTPACK WMI_SNR_THRESHOLD_PARAMS_CMD; - -/* - * WMI_LQ_THRESHOLD_PARAMS_CMDID - */ -typedef PREPACK struct WMI_LQ_THRESHOLD_PARAMS { - u8 enable; - u8 thresholdAbove1_Val; - u8 thresholdAbove2_Val; - u8 thresholdAbove3_Val; - u8 thresholdAbove4_Val; - u8 thresholdBelow1_Val; - u8 thresholdBelow2_Val; - u8 thresholdBelow3_Val; - u8 thresholdBelow4_Val; - u8 reserved[3]; -} POSTPACK WMI_LQ_THRESHOLD_PARAMS_CMD; - -typedef enum { - WMI_LPREAMBLE_DISABLED = 0, - WMI_LPREAMBLE_ENABLED -} WMI_LPREAMBLE_STATUS; - -typedef enum { - WMI_IGNORE_BARKER_IN_ERP = 0, - WMI_DONOT_IGNORE_BARKER_IN_ERP -} WMI_PREAMBLE_POLICY; - -typedef PREPACK struct { - u8 status; - u8 preamblePolicy; -}POSTPACK WMI_SET_LPREAMBLE_CMD; - -typedef PREPACK struct { - u16 threshold; -}POSTPACK WMI_SET_RTS_CMD; - -/* - * WMI_TARGET_ERROR_REPORT_BITMASK_CMDID - * Sets the error reporting event bitmask in target. Target clears it - * upon an error. Subsequent errors are counted, but not reported - * via event, unless the bitmask is set again. - */ -typedef PREPACK struct { - u32 bitmask; -} POSTPACK WMI_TARGET_ERROR_REPORT_BITMASK; - -/* - * WMI_SET_TX_PWR_CMDID - */ -typedef PREPACK struct { - u8 dbM; /* in dbM units */ -} POSTPACK WMI_SET_TX_PWR_CMD, WMI_TX_PWR_REPLY; - -/* - * WMI_SET_ASSOC_INFO_CMDID - * - * A maximum of 2 private IEs can be sent in the [Re]Assoc request. - * A 3rd one, the CCX version IE can also be set from the host. - */ -#define WMI_MAX_ASSOC_INFO_TYPE 2 -#define WMI_CCX_VER_IE 2 /* ieType to set CCX Version IE */ - -#define WMI_MAX_ASSOC_INFO_LEN 240 - -typedef PREPACK struct { - u8 ieType; - u8 bufferSize; - u8 assocInfo[1]; /* up to WMI_MAX_ASSOC_INFO_LEN */ -} POSTPACK WMI_SET_ASSOC_INFO_CMD; - - -/* - * WMI_GET_TX_PWR_CMDID does not take any parameters - */ - -/* - * WMI_ADD_BAD_AP_CMDID - */ -#define WMI_MAX_BAD_AP_INDEX 1 - -typedef PREPACK struct { - u8 badApIndex; /* 0 to WMI_MAX_BAD_AP_INDEX */ - u8 bssid[ATH_MAC_LEN]; -} POSTPACK WMI_ADD_BAD_AP_CMD; - -/* - * WMI_DELETE_BAD_AP_CMDID - */ -typedef PREPACK struct { - u8 badApIndex; /* 0 to WMI_MAX_BAD_AP_INDEX */ -} POSTPACK WMI_DELETE_BAD_AP_CMD; - -/* - * WMI_SET_ACCESS_PARAMS_CMDID - */ -#define WMI_DEFAULT_TXOP_ACPARAM 0 /* implies one MSDU */ -#define WMI_DEFAULT_ECWMIN_ACPARAM 4 /* corresponds to CWmin of 15 */ -#define WMI_DEFAULT_ECWMAX_ACPARAM 10 /* corresponds to CWmax of 1023 */ -#define WMI_MAX_CW_ACPARAM 15 /* maximum eCWmin or eCWmax */ -#define WMI_DEFAULT_AIFSN_ACPARAM 2 -#define WMI_MAX_AIFSN_ACPARAM 15 -typedef PREPACK struct { - u16 txop; /* in units of 32 usec */ - u8 eCWmin; - u8 eCWmax; - u8 aifsn; - u8 ac; -} POSTPACK WMI_SET_ACCESS_PARAMS_CMD; - - -/* - * WMI_SET_RETRY_LIMITS_CMDID - * - * This command is used to customize the number of retries the - * wlan device will perform on a given frame. - */ -#define WMI_MIN_RETRIES 2 -#define WMI_MAX_RETRIES 13 -typedef enum { - MGMT_FRAMETYPE = 0, - CONTROL_FRAMETYPE = 1, - DATA_FRAMETYPE = 2 -} WMI_FRAMETYPE; - -typedef PREPACK struct { - u8 frameType; /* WMI_FRAMETYPE */ - u8 trafficClass; /* applies only to DATA_FRAMETYPE */ - u8 maxRetries; - u8 enableNotify; -} POSTPACK WMI_SET_RETRY_LIMITS_CMD; - -/* - * WMI_SET_ROAM_CTRL_CMDID - * - * This command is used to influence the Roaming behaviour - * Set the host biases of the BSSs before setting the roam mode as bias - * based. - */ - -/* - * Different types of Roam Control - */ - -typedef enum { - WMI_FORCE_ROAM = 1, /* Roam to the specified BSSID */ - WMI_SET_ROAM_MODE = 2, /* default ,progd bias, no roam */ - WMI_SET_HOST_BIAS = 3, /* Set the Host Bias */ - WMI_SET_LOWRSSI_SCAN_PARAMS = 4, /* Set lowrssi Scan parameters */ -} WMI_ROAM_CTRL_TYPE; - -#define WMI_MIN_ROAM_CTRL_TYPE WMI_FORCE_ROAM -#define WMI_MAX_ROAM_CTRL_TYPE WMI_SET_LOWRSSI_SCAN_PARAMS - -/* - * ROAM MODES - */ - -typedef enum { - WMI_DEFAULT_ROAM_MODE = 1, /* RSSI based ROAM */ - WMI_HOST_BIAS_ROAM_MODE = 2, /* HOST BIAS based ROAM */ - WMI_LOCK_BSS_MODE = 3 /* Lock to the Current BSS - no Roam */ -} WMI_ROAM_MODE; - -/* - * BSS HOST BIAS INFO - */ - -typedef PREPACK struct { - u8 bssid[ATH_MAC_LEN]; - s8 bias; -} POSTPACK WMI_BSS_BIAS; - -typedef PREPACK struct { - u8 numBss; - WMI_BSS_BIAS bssBias[1]; -} POSTPACK WMI_BSS_BIAS_INFO; - -typedef PREPACK struct WMI_LOWRSSI_SCAN_PARAMS { - u16 lowrssi_scan_period; - s16 lowrssi_scan_threshold; - s16 lowrssi_roam_threshold; - u8 roam_rssi_floor; - u8 reserved[1]; /* For alignment */ -} POSTPACK WMI_LOWRSSI_SCAN_PARAMS; - -typedef PREPACK struct { - PREPACK union { - u8 bssid[ATH_MAC_LEN]; /* WMI_FORCE_ROAM */ - u8 roamMode; /* WMI_SET_ROAM_MODE */ - WMI_BSS_BIAS_INFO bssBiasInfo; /* WMI_SET_HOST_BIAS */ - WMI_LOWRSSI_SCAN_PARAMS lrScanParams; - } POSTPACK info; - u8 roamCtrlType ; -} POSTPACK WMI_SET_ROAM_CTRL_CMD; - -/* - * WMI_SET_BT_WLAN_CONN_PRECEDENCE_CMDID - */ -typedef enum { - BT_WLAN_CONN_PRECDENCE_WLAN=0, /* Default */ - BT_WLAN_CONN_PRECDENCE_PAL, -} BT_WLAN_CONN_PRECEDENCE; - -typedef PREPACK struct { - u8 precedence; -} POSTPACK WMI_SET_BT_WLAN_CONN_PRECEDENCE; - -/* - * WMI_ENABLE_RM_CMDID - */ -typedef PREPACK struct { - u32 enable_radio_measurements; -} POSTPACK WMI_ENABLE_RM_CMD; - -/* - * WMI_SET_MAX_OFFHOME_DURATION_CMDID - */ -typedef PREPACK struct { - u8 max_offhome_duration; -} POSTPACK WMI_SET_MAX_OFFHOME_DURATION_CMD; - -typedef PREPACK struct { - u32 frequency; - u8 threshold; -} POSTPACK WMI_SET_HB_CHALLENGE_RESP_PARAMS_CMD; -/*---------------------- BTCOEX RELATED -------------------------------------*/ -/*----------------------COMMON to AR6002 and AR6003 -------------------------*/ -typedef enum { - BT_STREAM_UNDEF = 0, - BT_STREAM_SCO, /* SCO stream */ - BT_STREAM_A2DP, /* A2DP stream */ - BT_STREAM_SCAN, /* BT Discovery or Page */ - BT_STREAM_ESCO, - BT_STREAM_MAX -} BT_STREAM_TYPE; - -typedef enum { - BT_PARAM_SCO_PSPOLL_LATENCY_ONE_FOURTH =1, - BT_PARAM_SCO_PSPOLL_LATENCY_HALF, - BT_PARAM_SCO_PSPOLL_LATENCY_THREE_FOURTH, -} BT_PARAMS_SCO_PSPOLL_LATENCY; - -typedef enum { - BT_PARAMS_SCO_STOMP_SCO_NEVER =1, - BT_PARAMS_SCO_STOMP_SCO_ALWAYS, - BT_PARAMS_SCO_STOMP_SCO_IN_LOWRSSI, -} BT_PARAMS_SCO_STOMP_RULES; - -typedef enum { - BT_STATUS_UNDEF = 0, - BT_STATUS_ON, - BT_STATUS_OFF, - BT_STATUS_MAX -} BT_STREAM_STATUS; - -typedef PREPACK struct { - u8 streamType; - u8 status; -} POSTPACK WMI_SET_BT_STATUS_CMD; - -typedef enum { - BT_ANT_TYPE_UNDEF=0, - BT_ANT_TYPE_DUAL, - BT_ANT_TYPE_SPLITTER, - BT_ANT_TYPE_SWITCH, - BT_ANT_TYPE_HIGH_ISO_DUAL -} BT_ANT_FRONTEND_CONFIG; - -typedef enum { - BT_COLOCATED_DEV_BTS4020=0, - BT_COLCATED_DEV_CSR , - BT_COLOCATED_DEV_VALKYRIE -} BT_COLOCATED_DEV_TYPE; - -/*********************** Applicable to AR6002 ONLY ******************************/ - -typedef enum { - BT_PARAM_SCO = 1, /* SCO stream parameters */ - BT_PARAM_A2DP , - BT_PARAM_ANTENNA_CONFIG, - BT_PARAM_COLOCATED_BT_DEVICE, - BT_PARAM_ACLCOEX, - BT_PARAM_11A_SEPARATE_ANT, - BT_PARAM_MAX -} BT_PARAM_TYPE; - - -#define BT_SCO_ALLOW_CLOSE_RANGE_OPT (1 << 0) -#define BT_SCO_FORCE_AWAKE_OPT (1 << 1) -#define BT_SCO_SET_RSSI_OVERRIDE(flags) ((flags) |= (1 << 2)) -#define BT_SCO_GET_RSSI_OVERRIDE(flags) (((flags) >> 2) & 0x1) -#define BT_SCO_SET_RTS_OVERRIDE(flags) ((flags) |= (1 << 3)) -#define BT_SCO_GET_RTS_OVERRIDE(flags) (((flags) >> 3) & 0x1) -#define BT_SCO_GET_MIN_LOW_RATE_CNT(flags) (((flags) >> 8) & 0xFF) -#define BT_SCO_GET_MAX_LOW_RATE_CNT(flags) (((flags) >> 16) & 0xFF) -#define BT_SCO_SET_MIN_LOW_RATE_CNT(flags,val) (flags) |= (((val) & 0xFF) << 8) -#define BT_SCO_SET_MAX_LOW_RATE_CNT(flags,val) (flags) |= (((val) & 0xFF) << 16) - -typedef PREPACK struct { - u32 numScoCyclesForceTrigger; /* Number SCO cycles after which - force a pspoll. default = 10 */ - u32 dataResponseTimeout; /* Timeout Waiting for Downlink pkt - in response for ps-poll, - default = 10 msecs */ - u32 stompScoRules; - u32 scoOptFlags; /* SCO Options Flags : - bits: meaning: - 0 Allow Close Range Optimization - 1 Force awake during close range - 2 If set use host supplied RSSI for OPT - 3 If set use host supplied RTS COUNT for OPT - 4..7 Unused - 8..15 Low Data Rate Min Cnt - 16..23 Low Data Rate Max Cnt - */ - - u8 stompDutyCyleVal; /* Sco cycles to limit ps-poll queuing - if stomped */ - u8 stompDutyCyleMaxVal; /*firm ware increases stomp duty cycle - gradually uptill this value on need basis*/ - u8 psPollLatencyFraction; /* Fraction of idle - period, within which - additional ps-polls - can be queued */ - u8 noSCOSlots; /* Number of SCO Tx/Rx slots. - HVx, EV3, 2EV3 = 2 */ - u8 noIdleSlots; /* Number of Bluetooth idle slots between - consecutive SCO Tx/Rx slots - HVx, EV3 = 4 - 2EV3 = 10 */ - u8 scoOptOffRssi;/*RSSI value below which we go to ps poll*/ - u8 scoOptOnRssi; /*RSSI value above which we reenter opt mode*/ - u8 scoOptRtsCount; -} POSTPACK BT_PARAMS_SCO; - -#define BT_A2DP_ALLOW_CLOSE_RANGE_OPT (1 << 0) -#define BT_A2DP_FORCE_AWAKE_OPT (1 << 1) -#define BT_A2DP_SET_RSSI_OVERRIDE(flags) ((flags) |= (1 << 2)) -#define BT_A2DP_GET_RSSI_OVERRIDE(flags) (((flags) >> 2) & 0x1) -#define BT_A2DP_SET_RTS_OVERRIDE(flags) ((flags) |= (1 << 3)) -#define BT_A2DP_GET_RTS_OVERRIDE(flags) (((flags) >> 3) & 0x1) -#define BT_A2DP_GET_MIN_LOW_RATE_CNT(flags) (((flags) >> 8) & 0xFF) -#define BT_A2DP_GET_MAX_LOW_RATE_CNT(flags) (((flags) >> 16) & 0xFF) -#define BT_A2DP_SET_MIN_LOW_RATE_CNT(flags,val) (flags) |= (((val) & 0xFF) << 8) -#define BT_A2DP_SET_MAX_LOW_RATE_CNT(flags,val) (flags) |= (((val) & 0xFF) << 16) - -typedef PREPACK struct { - u32 a2dpWlanUsageLimit; /* MAX time firmware uses the medium for - wlan, after it identifies the idle time - default (30 msecs) */ - u32 a2dpBurstCntMin; /* Minimum number of bluetooth data frames - to replenish Wlan Usage limit (default 3) */ - u32 a2dpDataRespTimeout; - u32 a2dpOptFlags; /* A2DP Option flags: - bits: meaning: - 0 Allow Close Range Optimization - 1 Force awake during close range - 2 If set use host supplied RSSI for OPT - 3 If set use host supplied RTS COUNT for OPT - 4..7 Unused - 8..15 Low Data Rate Min Cnt - 16..23 Low Data Rate Max Cnt - */ - u8 isCoLocatedBtRoleMaster; - u8 a2dpOptOffRssi;/*RSSI value below which we go to ps poll*/ - u8 a2dpOptOnRssi; /*RSSI value above which we reenter opt mode*/ - u8 a2dpOptRtsCount; -}POSTPACK BT_PARAMS_A2DP; - -/* During BT ftp/ BT OPP or any another data based acl profile on bluetooth - (non a2dp).*/ -typedef PREPACK struct { - u32 aclWlanMediumUsageTime; /* Wlan usage time during Acl (non-a2dp) - coexistence (default 30 msecs) */ - u32 aclBtMediumUsageTime; /* Bt usage time during acl coexistence - (default 30 msecs)*/ - u32 aclDataRespTimeout; - u32 aclDetectTimeout; /* ACL coexistence enabled if we get - 10 Pkts in X msec(default 100 msecs) */ - u32 aclmaxPktCnt; /* No of ACL pkts to receive before - enabling ACL coex */ - -}POSTPACK BT_PARAMS_ACLCOEX; - -typedef PREPACK struct { - PREPACK union { - BT_PARAMS_SCO scoParams; - BT_PARAMS_A2DP a2dpParams; - BT_PARAMS_ACLCOEX aclCoexParams; - u8 antType; /* 0 -Disabled (default) - 1 - BT_ANT_TYPE_DUAL - 2 - BT_ANT_TYPE_SPLITTER - 3 - BT_ANT_TYPE_SWITCH */ - u8 coLocatedBtDev; /* 0 - BT_COLOCATED_DEV_BTS4020 (default) - 1 - BT_COLCATED_DEV_CSR - 2 - BT_COLOCATED_DEV_VALKYRIe - */ - } POSTPACK info; - u8 paramType ; -} POSTPACK WMI_SET_BT_PARAMS_CMD; - -/************************ END AR6002 BTCOEX *******************************/ -/*-----------------------AR6003 BTCOEX -----------------------------------*/ - -/* ---------------WMI_SET_BTCOEX_FE_ANT_CMDID --------------------------*/ -/* Indicates front end antenna configuration. This command needs to be issued - * right after initialization and after WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMDID. - * AR6003 enables coexistence and antenna switching based on the configuration. - */ -typedef enum { - WMI_BTCOEX_NOT_ENABLED = 0, - WMI_BTCOEX_FE_ANT_SINGLE =1, - WMI_BTCOEX_FE_ANT_DUAL=2, - WMI_BTCOEX_FE_ANT_DUAL_HIGH_ISO=3, - WMI_BTCOEX_FE_ANT_TYPE_MAX -}WMI_BTCOEX_FE_ANT_TYPE; - -typedef PREPACK struct { - u8 btcoexFeAntType; /* 1 - WMI_BTCOEX_FE_ANT_SINGLE for single antenna front end - 2 - WMI_BTCOEX_FE_ANT_DUAL for dual antenna front end - (for isolations less 35dB, for higher isolation there - is not need to pass this command). - (not implemented) - */ -}POSTPACK WMI_SET_BTCOEX_FE_ANT_CMD; - -/* -------------WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMDID ----------------*/ -/* Indicate the bluetooth chip to the firmware. Firmware can have different algorithm based - * bluetooth chip type.Based on bluetooth device, different coexistence protocol would be used. - */ -typedef PREPACK struct { - u8 btcoexCoLocatedBTdev; /*1 - Qcom BT (3 -wire PTA) - 2 - CSR BT (3 wire PTA) - 3 - Atheros 3001 BT (3 wire PTA) - 4 - STE bluetooth (4-wire ePTA) - 5 - Atheros 3002 BT (4-wire MCI) - defaults= 3 (Atheros 3001 BT ) - */ -}POSTPACK WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD; - -/* -------------WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMDID ------------*/ -/* Configuration parameters during bluetooth inquiry and page. Page configuration - * is applicable only on interfaces which can distinguish page (applicable only for ePTA - - * STE bluetooth). - * Bluetooth inquiry start and end is indicated via WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID. - * During this the station will be power-save mode. - */ -typedef PREPACK struct { - u32 btInquiryDataFetchFrequency;/* The frequency of querying the AP for data - (via pspoll) is configured by this parameter. - "default = 10 ms" */ - - u32 protectBmissDurPostBtInquiry;/* The firmware will continue to be in inquiry state - for configured duration, after inquiry completion - . This is to ensure other bluetooth transactions - (RDP, SDP profiles, link key exchange ...etc) - goes through smoothly without wifi stomping. - default = 10 secs*/ - - u32 maxpageStomp; /*Applicable only for STE-BT interface. Currently not - used */ - u32 btInquiryPageFlag; /* Not used */ -}POSTPACK WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD; - -/*---------------------WMI_SET_BTCOEX_SCO_CONFIG_CMDID ---------------*/ -/* Configure SCO parameters. These parameters would be used whenever firmware is indicated - * of (e)SCO profile on bluetooth ( via WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID). - * Configration of BTCOEX_SCO_CONFIG data structure are common configuration and applies - * ps-poll mode and opt mode. - * Ps-poll Mode - Station is in power-save and retrieves downlink data between sco gaps. - * Opt Mode - station is in awake state and access point can send data to station any time. - * BTCOEX_PSPOLLMODE_SCO_CONFIG - Configuration applied only during ps-poll mode. - * BTCOEX_OPTMODE_SCO_CONFIG - Configuration applied only during opt mode. - */ -#define WMI_SCO_CONFIG_FLAG_ALLOW_OPTIMIZATION (1 << 0) -#define WMI_SCO_CONFIG_FLAG_IS_EDR_CAPABLE (1 << 1) -#define WMI_SCO_CONFIG_FLAG_IS_BT_MASTER (1 << 2) -#define WMI_SCO_CONFIG_FLAG_FW_DETECT_OF_PER (1 << 3) -typedef PREPACK struct { - u32 scoSlots; /* Number of SCO Tx/Rx slots. - HVx, EV3, 2EV3 = 2 */ - u32 scoIdleSlots; /* Number of Bluetooth idle slots between - consecutive SCO Tx/Rx slots - HVx, EV3 = 4 - 2EV3 = 10 - */ - u32 scoFlags; /* SCO Options Flags : - bits: meaning: - 0 Allow Close Range Optimization - 1 Is EDR capable or Not - 2 IS Co-located Bt role Master - 3 Firmware determines the periodicity of SCO. - */ - - u32 linkId; /* applicable to STE-BT - not used */ -}POSTPACK BTCOEX_SCO_CONFIG; - -typedef PREPACK struct { - u32 scoCyclesForceTrigger; /* Number SCO cycles after which - force a pspoll. default = 10 */ - u32 scoDataResponseTimeout; /* Timeout Waiting for Downlink pkt - in response for ps-poll, - default = 20 msecs */ - - u32 scoStompDutyCyleVal; /* not implemented */ - - u32 scoStompDutyCyleMaxVal; /*Not implemented */ - - u32 scoPsPollLatencyFraction; /* Fraction of idle - period, within which - additional ps-polls can be queued - 1 - 1/4 of idle duration - 2 - 1/2 of idle duration - 3 - 3/4 of idle duration - default =2 (1/2) - */ -}POSTPACK BTCOEX_PSPOLLMODE_SCO_CONFIG; - -typedef PREPACK struct { - u32 scoStompCntIn100ms;/*max number of SCO stomp in 100ms allowed in - opt mode. If exceeds the configured value, - switch to ps-poll mode - default = 3 */ - - u32 scoContStompMax; /* max number of continuous stomp allowed in opt mode. - if exceeded switch to pspoll mode - default = 3 */ - - u32 scoMinlowRateMbps; /* Low rate threshold */ - - u32 scoLowRateCnt; /* number of low rate pkts (< scoMinlowRateMbps) allowed in 100 ms. - If exceeded switch/stay to ps-poll mode, lower stay in opt mode. - default = 36 - */ - - u32 scoHighPktRatio; /*(Total Rx pkts in 100 ms + 1)/ - ((Total tx pkts in 100 ms - No of high rate pkts in 100 ms) + 1) in 100 ms, - if exceeded switch/stay in opt mode and if lower switch/stay in pspoll mode. - default = 5 (80% of high rates) - */ - - u32 scoMaxAggrSize; /* Max number of Rx subframes allowed in this mode. (Firmware re-negogiates - max number of aggregates if it was negogiated to higher value - default = 1 - Recommended value Basic rate headsets = 1, EDR (2-EV3) =4. - */ -}POSTPACK BTCOEX_OPTMODE_SCO_CONFIG; - -typedef PREPACK struct { - u32 scanInterval; - u32 maxScanStompCnt; -}POSTPACK BTCOEX_WLANSCAN_SCO_CONFIG; - -typedef PREPACK struct { - BTCOEX_SCO_CONFIG scoConfig; - BTCOEX_PSPOLLMODE_SCO_CONFIG scoPspollConfig; - BTCOEX_OPTMODE_SCO_CONFIG scoOptModeConfig; - BTCOEX_WLANSCAN_SCO_CONFIG scoWlanScanConfig; -}POSTPACK WMI_SET_BTCOEX_SCO_CONFIG_CMD; - -/* ------------------WMI_SET_BTCOEX_A2DP_CONFIG_CMDID -------------------*/ -/* Configure A2DP profile parameters. These parameters would be used whenver firmware is indicated - * of A2DP profile on bluetooth ( via WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID). - * Configuration of BTCOEX_A2DP_CONFIG data structure are common configuration and applies to - * ps-poll mode and opt mode. - * Ps-poll Mode - Station is in power-save and retrieves downlink data between a2dp data bursts. - * Opt Mode - station is in power save during a2dp bursts and awake in the gaps. - * BTCOEX_PSPOLLMODE_A2DP_CONFIG - Configuration applied only during ps-poll mode. - * BTCOEX_OPTMODE_A2DP_CONFIG - Configuration applied only during opt mode. - */ - -#define WMI_A2DP_CONFIG_FLAG_ALLOW_OPTIMIZATION (1 << 0) -#define WMI_A2DP_CONFIG_FLAG_IS_EDR_CAPABLE (1 << 1) -#define WMI_A2DP_CONFIG_FLAG_IS_BT_ROLE_MASTER (1 << 2) -#define WMI_A2DP_CONFIG_FLAG_IS_A2DP_HIGH_PRI (1 << 3) -#define WMI_A2DP_CONFIG_FLAG_FIND_BT_ROLE (1 << 4) - -typedef PREPACK struct { - u32 a2dpFlags; /* A2DP Option flags: - bits: meaning: - 0 Allow Close Range Optimization - 1 IS EDR capable - 2 IS Co-located Bt role Master - 3 a2dp traffic is high priority - 4 Fw detect the role of bluetooth. - */ - u32 linkId; /* Applicable only to STE-BT - not used */ - -}POSTPACK BTCOEX_A2DP_CONFIG; - -typedef PREPACK struct { - u32 a2dpWlanMaxDur; /* MAX time firmware uses the medium for - wlan, after it identifies the idle time - default (30 msecs) */ - - u32 a2dpMinBurstCnt; /* Minimum number of bluetooth data frames - to replenish Wlan Usage limit (default 3) */ - - u32 a2dpDataRespTimeout; /* Max duration firmware waits for downlink - by stomping on bluetooth - after ps-poll is acknowledged. - default = 20 ms - */ -}POSTPACK BTCOEX_PSPOLLMODE_A2DP_CONFIG; - -typedef PREPACK struct { - u32 a2dpMinlowRateMbps; /* Low rate threshold */ - - u32 a2dpLowRateCnt; /* number of low rate pkts (< a2dpMinlowRateMbps) allowed in 100 ms. - If exceeded switch/stay to ps-poll mode, lower stay in opt mode. - default = 36 - */ - - u32 a2dpHighPktRatio; /*(Total Rx pkts in 100 ms + 1)/ - ((Total tx pkts in 100 ms - No of high rate pkts in 100 ms) + 1) in 100 ms, - if exceeded switch/stay in opt mode and if lower switch/stay in pspoll mode. - default = 5 (80% of high rates) - */ - - u32 a2dpMaxAggrSize; /* Max number of Rx subframes allowed in this mode. (Firmware re-negogiates - max number of aggregates if it was negogiated to higher value - default = 1 - Recommended value Basic rate headsets = 1, EDR (2-EV3) =8. - */ - u32 a2dpPktStompCnt; /*number of a2dp pkts that can be stomped per burst. - default = 6*/ - -}POSTPACK BTCOEX_OPTMODE_A2DP_CONFIG; - -typedef PREPACK struct { - BTCOEX_A2DP_CONFIG a2dpConfig; - BTCOEX_PSPOLLMODE_A2DP_CONFIG a2dppspollConfig; - BTCOEX_OPTMODE_A2DP_CONFIG a2dpOptConfig; -}POSTPACK WMI_SET_BTCOEX_A2DP_CONFIG_CMD; - -/*------------ WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMDID---------------------*/ -/* Configure non-A2dp ACL profile parameters.The starts of ACL profile can either be - * indicated via WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID orenabled via firmware detection - * which is configured via "aclCoexFlags". - * Configration of BTCOEX_ACLCOEX_CONFIG data structure are common configuration and applies - * ps-poll mode and opt mode. - * Ps-poll Mode - Station is in power-save and retrieves downlink data during wlan medium. - * Opt Mode - station is in power save during bluetooth medium time and awake during wlan duration. - * (Not implemented yet) - * - * BTCOEX_PSPOLLMODE_ACLCOEX_CONFIG - Configuration applied only during ps-poll mode. - * BTCOEX_OPTMODE_ACLCOEX_CONFIG - Configuration applied only during opt mode. - */ - -#define WMI_ACLCOEX_FLAGS_ALLOW_OPTIMIZATION (1 << 0) -#define WMI_ACLCOEX_FLAGS_DISABLE_FW_DETECTION (1 << 1) - -typedef PREPACK struct { - u32 aclWlanMediumDur; /* Wlan usage time during Acl (non-a2dp) - coexistence (default 30 msecs) - */ - - u32 aclBtMediumDur; /* Bt usage time during acl coexistence - (default 30 msecs) - */ - - u32 aclDetectTimeout; /* BT activity observation time limit. - In this time duration, number of bt pkts are counted. - If the Cnt reaches "aclPktCntLowerLimit" value - for "aclIterToEnableCoex" iteration continuously, - firmware gets into ACL coexistence mode. - Similarly, if bt traffic count during ACL coexistence - has not reached "aclPktCntLowerLimit" continuously - for "aclIterToEnableCoex", then ACL coexistence is - disabled. - -default 100 msecs - */ - - u32 aclPktCntLowerLimit; /* Acl Pkt Cnt to be received in duration of - "aclDetectTimeout" for - "aclIterForEnDis" times to enabling ACL coex. - Similar logic is used to disable acl coexistence. - (If "aclPktCntLowerLimit" cnt of acl pkts - are not seen by the for "aclIterForEnDis" - then acl coexistence is disabled). - default = 10 - */ - - u32 aclIterForEnDis; /* number of Iteration of "aclPktCntLowerLimit" for Enabling and - Disabling Acl Coexistence. - default = 3 - */ - - u32 aclPktCntUpperLimit; /* This is upperBound limit, if there is more than - "aclPktCntUpperLimit" seen in "aclDetectTimeout", - ACL coexistence is enabled right away. - - default 15*/ - - u32 aclCoexFlags; /* A2DP Option flags: - bits: meaning: - 0 Allow Close Range Optimization - 1 disable Firmware detection - (Currently supported configuration is aclCoexFlags =0) - */ - u32 linkId; /* Applicable only for STE-BT - not used */ - -}POSTPACK BTCOEX_ACLCOEX_CONFIG; - -typedef PREPACK struct { - u32 aclDataRespTimeout; /* Max duration firmware waits for downlink - by stomping on bluetooth - after ps-poll is acknowledged. - default = 20 ms */ - -}POSTPACK BTCOEX_PSPOLLMODE_ACLCOEX_CONFIG; - - -/* Not implemented yet*/ -typedef PREPACK struct { - u32 aclCoexMinlowRateMbps; - u32 aclCoexLowRateCnt; - u32 aclCoexHighPktRatio; - u32 aclCoexMaxAggrSize; - u32 aclPktStompCnt; -}POSTPACK BTCOEX_OPTMODE_ACLCOEX_CONFIG; - -typedef PREPACK struct { - BTCOEX_ACLCOEX_CONFIG aclCoexConfig; - BTCOEX_PSPOLLMODE_ACLCOEX_CONFIG aclCoexPspollConfig; - BTCOEX_OPTMODE_ACLCOEX_CONFIG aclCoexOptConfig; -}POSTPACK WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD; - -/* -----------WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID ------------------*/ -typedef enum { - WMI_BTCOEX_BT_PROFILE_SCO =1, - WMI_BTCOEX_BT_PROFILE_A2DP, - WMI_BTCOEX_BT_PROFILE_INQUIRY_PAGE, - WMI_BTCOEX_BT_PROFILE_ACLCOEX, -}WMI_BTCOEX_BT_PROFILE; - -typedef PREPACK struct { - u32 btProfileType; - u32 btOperatingStatus; - u32 btLinkId; -}WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD; - -/*--------------------- WMI_SET_BTCOEX_DEBUG_CMDID ---------------------*/ -/* Used for firmware development and debugging */ -typedef PREPACK struct { - u32 btcoexDbgParam1; - u32 btcoexDbgParam2; - u32 btcoexDbgParam3; - u32 btcoexDbgParam4; - u32 btcoexDbgParam5; -}WMI_SET_BTCOEX_DEBUG_CMD; - -/*---------------------WMI_GET_BTCOEX_CONFIG_CMDID --------------------- */ -/* Command to firmware to get configuration parameters of the bt profile - * reported via WMI_BTCOEX_CONFIG_EVENTID */ -typedef PREPACK struct { - u32 btProfileType; /* 1 - SCO - 2 - A2DP - 3 - INQUIRY_PAGE - 4 - ACLCOEX - */ - u32 linkId; /* not used */ -}WMI_GET_BTCOEX_CONFIG_CMD; - -/*------------------WMI_REPORT_BTCOEX_CONFIG_EVENTID------------------- */ -/* Event from firmware to host, sent in response to WMI_GET_BTCOEX_CONFIG_CMDID - * */ -typedef PREPACK struct { - u32 btProfileType; - u32 linkId; /* not used */ - PREPACK union { - WMI_SET_BTCOEX_SCO_CONFIG_CMD scoConfigCmd; - WMI_SET_BTCOEX_A2DP_CONFIG_CMD a2dpConfigCmd; - WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD aclcoexConfig; - WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD btinquiryPageConfigCmd; - } POSTPACK info; -} POSTPACK WMI_BTCOEX_CONFIG_EVENT; - -/*------------- WMI_REPORT_BTCOEX_BTCOEX_STATS_EVENTID--------------------*/ -/* Used for firmware development and debugging*/ -typedef PREPACK struct { - u32 highRatePktCnt; - u32 firstBmissCnt; - u32 psPollFailureCnt; - u32 nullFrameFailureCnt; - u32 optModeTransitionCnt; -}BTCOEX_GENERAL_STATS; - -typedef PREPACK struct { - u32 scoStompCntAvg; - u32 scoStompIn100ms; - u32 scoMaxContStomp; - u32 scoAvgNoRetries; - u32 scoMaxNoRetriesIn100ms; -}BTCOEX_SCO_STATS; - -typedef PREPACK struct { - u32 a2dpBurstCnt; - u32 a2dpMaxBurstCnt; - u32 a2dpAvgIdletimeIn100ms; - u32 a2dpAvgStompCnt; -}BTCOEX_A2DP_STATS; - -typedef PREPACK struct { - u32 aclPktCntInBtTime; - u32 aclStompCntInWlanTime; - u32 aclPktCntIn100ms; -}BTCOEX_ACLCOEX_STATS; - -typedef PREPACK struct { - BTCOEX_GENERAL_STATS coexStats; - BTCOEX_SCO_STATS scoStats; - BTCOEX_A2DP_STATS a2dpStats; - BTCOEX_ACLCOEX_STATS aclCoexStats; -}WMI_BTCOEX_STATS_EVENT; - - -/*--------------------------END OF BTCOEX -------------------------------------*/ -typedef PREPACK struct { - u32 sleepState; -}WMI_REPORT_SLEEP_STATE_EVENT; - -typedef enum { - WMI_REPORT_SLEEP_STATUS_IS_DEEP_SLEEP =0, - WMI_REPORT_SLEEP_STATUS_IS_AWAKE -} WMI_REPORT_SLEEP_STATUS; -typedef enum { - DISCONN_EVT_IN_RECONN = 0, /* default */ - NO_DISCONN_EVT_IN_RECONN -} TARGET_EVENT_REPORT_CONFIG; - -typedef PREPACK struct { - u32 evtConfig; -} POSTPACK WMI_SET_TARGET_EVENT_REPORT_CMD; - - -typedef PREPACK struct { - u16 cmd_buf_sz; /* HCI cmd buffer size */ - u8 buf[1]; /* Absolute HCI cmd */ -} POSTPACK WMI_HCI_CMD; - -/* - * Command Replies - */ - -/* - * WMI_GET_CHANNEL_LIST_CMDID reply - */ -typedef PREPACK struct { - u8 reserved1; - u8 numChannels; /* number of channels in reply */ - u16 channelList[1]; /* channel in Mhz */ -} POSTPACK WMI_CHANNEL_LIST_REPLY; - -typedef enum { - A_SUCCEEDED = 0, - A_FAILED_DELETE_STREAM_DOESNOT_EXIST=250, - A_SUCCEEDED_MODIFY_STREAM=251, - A_FAILED_INVALID_STREAM = 252, - A_FAILED_MAX_THINSTREAMS = 253, - A_FAILED_CREATE_REMOVE_PSTREAM_FIRST = 254, -} PSTREAM_REPLY_STATUS; - -typedef PREPACK struct { - u8 status; /* PSTREAM_REPLY_STATUS */ - u8 txQueueNumber; - u8 rxQueueNumber; - u8 trafficClass; - u8 trafficDirection; /* DIR_TYPE */ -} POSTPACK WMI_CRE_PRIORITY_STREAM_REPLY; - -typedef PREPACK struct { - u8 status; /* PSTREAM_REPLY_STATUS */ - u8 txQueueNumber; - u8 rxQueueNumber; - u8 trafficDirection; /* DIR_TYPE */ - u8 trafficClass; -} POSTPACK WMI_DEL_PRIORITY_STREAM_REPLY; - -/* - * List of Events (target to host) - */ -typedef enum { - WMI_READY_EVENTID = 0x1001, - WMI_CONNECT_EVENTID, - WMI_DISCONNECT_EVENTID, - WMI_BSSINFO_EVENTID, - WMI_CMDERROR_EVENTID, - WMI_REGDOMAIN_EVENTID, - WMI_PSTREAM_TIMEOUT_EVENTID, - WMI_NEIGHBOR_REPORT_EVENTID, - WMI_TKIP_MICERR_EVENTID, - WMI_SCAN_COMPLETE_EVENTID, /* 0x100a */ - WMI_REPORT_STATISTICS_EVENTID, - WMI_RSSI_THRESHOLD_EVENTID, - WMI_ERROR_REPORT_EVENTID, - WMI_OPT_RX_FRAME_EVENTID, - WMI_REPORT_ROAM_TBL_EVENTID, - WMI_EXTENSION_EVENTID, - WMI_CAC_EVENTID, - WMI_SNR_THRESHOLD_EVENTID, - WMI_LQ_THRESHOLD_EVENTID, - WMI_TX_RETRY_ERR_EVENTID, /* 0x1014 */ - WMI_REPORT_ROAM_DATA_EVENTID, - WMI_TEST_EVENTID, - WMI_APLIST_EVENTID, - WMI_GET_WOW_LIST_EVENTID, - WMI_GET_PMKID_LIST_EVENTID, - WMI_CHANNEL_CHANGE_EVENTID, - WMI_PEER_NODE_EVENTID, - WMI_PSPOLL_EVENTID, - WMI_DTIMEXPIRY_EVENTID, - WMI_WLAN_VERSION_EVENTID, - WMI_SET_PARAMS_REPLY_EVENTID, - WMI_ADDBA_REQ_EVENTID, /*0x1020 */ - WMI_ADDBA_RESP_EVENTID, - WMI_DELBA_REQ_EVENTID, - WMI_TX_COMPLETE_EVENTID, - WMI_HCI_EVENT_EVENTID, - WMI_ACL_DATA_EVENTID, - WMI_REPORT_SLEEP_STATE_EVENTID, -#ifdef WAPI_ENABLE - WMI_WAPI_REKEY_EVENTID, -#endif - WMI_REPORT_BTCOEX_STATS_EVENTID, - WMI_REPORT_BTCOEX_CONFIG_EVENTID, - WMI_GET_PMK_EVENTID, - - /* DFS Events */ - WMI_DFS_HOST_ATTACH_EVENTID, - WMI_DFS_HOST_INIT_EVENTID, - WMI_DFS_RESET_DELAYLINES_EVENTID, - WMI_DFS_RESET_RADARQ_EVENTID, - WMI_DFS_RESET_AR_EVENTID, - WMI_DFS_RESET_ARQ_EVENTID, - WMI_DFS_SET_DUR_MULTIPLIER_EVENTID, - WMI_DFS_SET_BANGRADAR_EVENTID, - WMI_DFS_SET_DEBUGLEVEL_EVENTID, - WMI_DFS_PHYERR_EVENTID, - /* CCX Evants */ - WMI_CCX_RM_STATUS_EVENTID, - - /* P2P Events */ - WMI_P2P_GO_NEG_RESULT_EVENTID, - - WMI_WAC_SCAN_DONE_EVENTID, - WMI_WAC_REPORT_BSS_EVENTID, - WMI_WAC_START_WPS_EVENTID, - WMI_WAC_CTRL_REQ_REPLY_EVENTID, - - /* RFKILL Events */ - WMI_RFKILL_STATE_CHANGE_EVENTID, - WMI_RFKILL_GET_MODE_CMD_EVENTID, - WMI_THIN_RESERVED_START_EVENTID = 0x8000, - - /* - * Events in this range are reserved for thinmode - * See wmi_thin.h for actual definitions - */ - WMI_THIN_RESERVED_END_EVENTID = 0x8fff, - - WMI_SET_CHANNEL_EVENTID, - WMI_ASSOC_REQ_EVENTID, - - /* generic ACS event */ - WMI_ACS_EVENTID, - WMI_REPORT_WMM_PARAMS_EVENTID -} WMI_EVENT_ID; - - -typedef enum { - WMI_11A_CAPABILITY = 1, - WMI_11G_CAPABILITY = 2, - WMI_11AG_CAPABILITY = 3, - WMI_11NA_CAPABILITY = 4, - WMI_11NG_CAPABILITY = 5, - WMI_11NAG_CAPABILITY = 6, - // END CAPABILITY - WMI_11N_CAPABILITY_OFFSET = (WMI_11NA_CAPABILITY - WMI_11A_CAPABILITY), -} WMI_PHY_CAPABILITY; - -typedef PREPACK struct { - u8 macaddr[ATH_MAC_LEN]; - u8 phyCapability; /* WMI_PHY_CAPABILITY */ -} POSTPACK WMI_READY_EVENT_1; - -typedef PREPACK struct { - u32 sw_version; - u32 abi_version; - u8 macaddr[ATH_MAC_LEN]; - u8 phyCapability; /* WMI_PHY_CAPABILITY */ -} POSTPACK WMI_READY_EVENT_2; - -#if defined(ATH_TARGET) -#ifdef AR6002_REV2 -#define WMI_READY_EVENT WMI_READY_EVENT_1 /* AR6002_REV2 target code */ -#else -#define WMI_READY_EVENT WMI_READY_EVENT_2 /* AR6001, AR6002_REV4, AR6002_REV5 */ -#endif -#else -#define WMI_READY_EVENT WMI_READY_EVENT_2 /* host code */ -#endif - - -/* - * Connect Event - */ -typedef PREPACK struct { - u16 channel; - u8 bssid[ATH_MAC_LEN]; - u16 listenInterval; - u16 beaconInterval; - u32 networkType; - u8 beaconIeLen; - u8 assocReqLen; - u8 assocRespLen; - u8 assocInfo[1]; -} POSTPACK WMI_CONNECT_EVENT; - -/* - * Disconnect Event - */ -typedef enum { - NO_NETWORK_AVAIL = 0x01, - LOST_LINK = 0x02, /* bmiss */ - DISCONNECT_CMD = 0x03, - BSS_DISCONNECTED = 0x04, - AUTH_FAILED = 0x05, - ASSOC_FAILED = 0x06, - NO_RESOURCES_AVAIL = 0x07, - CSERV_DISCONNECT = 0x08, - INVALID_PROFILE = 0x0a, - DOT11H_CHANNEL_SWITCH = 0x0b, - PROFILE_MISMATCH = 0x0c, - CONNECTION_EVICTED = 0x0d, - IBSS_MERGE = 0xe, -} WMI_DISCONNECT_REASON; - -typedef PREPACK struct { - u16 protocolReasonStatus; /* reason code, see 802.11 spec. */ - u8 bssid[ATH_MAC_LEN]; /* set if known */ - u8 disconnectReason ; /* see WMI_DISCONNECT_REASON */ - u8 assocRespLen; - u8 assocInfo[1]; -} POSTPACK WMI_DISCONNECT_EVENT; - -/* - * BSS Info Event. - * Mechanism used to inform host of the presence and characteristic of - * wireless networks present. Consists of bss info header followed by - * the beacon or probe-response frame body. The 802.11 header is not included. - */ -typedef enum { - BEACON_FTYPE = 0x1, - PROBERESP_FTYPE, - ACTION_MGMT_FTYPE, - PROBEREQ_FTYPE, -} WMI_BI_FTYPE; - -enum { - BSS_ELEMID_CHANSWITCH = 0x01, - BSS_ELEMID_ATHEROS = 0x02, -}; - -typedef PREPACK struct { - u16 channel; - u8 frameType; /* see WMI_BI_FTYPE */ - u8 snr; - s16 rssi; - u8 bssid[ATH_MAC_LEN]; - u32 ieMask; -} POSTPACK WMI_BSS_INFO_HDR; - -/* - * BSS INFO HDR version 2.0 - * With 6 bytes HTC header and 6 bytes of WMI header - * WMI_BSS_INFO_HDR cannot be accommodated in the removed 802.11 management - * header space. - * - Reduce the ieMask to 2 bytes as only two bit flags are used - * - Remove rssi and compute it on the host. rssi = snr - 95 - */ -typedef PREPACK struct { - u16 channel; - u8 frameType; /* see WMI_BI_FTYPE */ - u8 snr; - u8 bssid[ATH_MAC_LEN]; - u16 ieMask; -} POSTPACK WMI_BSS_INFO_HDR2; - -/* - * Command Error Event - */ -typedef enum { - INVALID_PARAM = 0x01, - ILLEGAL_STATE = 0x02, - INTERNAL_ERROR = 0x03, -} WMI_ERROR_CODE; - -typedef PREPACK struct { - u16 commandId; - u8 errorCode; -} POSTPACK WMI_CMD_ERROR_EVENT; - -/* - * New Regulatory Domain Event - */ -typedef PREPACK struct { - u32 regDomain; -} POSTPACK WMI_REG_DOMAIN_EVENT; - -typedef PREPACK struct { - u8 txQueueNumber; - u8 rxQueueNumber; - u8 trafficDirection; - u8 trafficClass; -} POSTPACK WMI_PSTREAM_TIMEOUT_EVENT; - -typedef PREPACK struct { - u8 reserve1; - u8 reserve2; - u8 reserve3; - u8 trafficClass; -} POSTPACK WMI_ACM_REJECT_EVENT; - -/* - * The WMI_NEIGHBOR_REPORT Event is generated by the target to inform - * the host of BSS's it has found that matches the current profile. - * It can be used by the host to cache PMKs and/to initiate pre-authentication - * if the BSS supports it. The first bssid is always the current associated - * BSS. - * The bssid and bssFlags information repeats according to the number - * or APs reported. - */ -typedef enum { - WMI_DEFAULT_BSS_FLAGS = 0x00, - WMI_PREAUTH_CAPABLE_BSS = 0x01, - WMI_PMKID_VALID_BSS = 0x02, -} WMI_BSS_FLAGS; - -typedef PREPACK struct { - u8 bssid[ATH_MAC_LEN]; - u8 bssFlags; /* see WMI_BSS_FLAGS */ -} POSTPACK WMI_NEIGHBOR_INFO; - -typedef PREPACK struct { - s8 numberOfAps; - WMI_NEIGHBOR_INFO neighbor[1]; -} POSTPACK WMI_NEIGHBOR_REPORT_EVENT; - -/* - * TKIP MIC Error Event - */ -typedef PREPACK struct { - u8 keyid; - u8 ismcast; -} POSTPACK WMI_TKIP_MICERR_EVENT; - -/* - * WMI_SCAN_COMPLETE_EVENTID - no parameters (old), staus parameter (new) - */ -typedef PREPACK struct { - s32 status; -} POSTPACK WMI_SCAN_COMPLETE_EVENT; - -#define MAX_OPT_DATA_LEN 1400 - -/* - * WMI_SET_ADHOC_BSSID_CMDID - */ -typedef PREPACK struct { - u8 bssid[ATH_MAC_LEN]; -} POSTPACK WMI_SET_ADHOC_BSSID_CMD; - -/* - * WMI_SET_OPT_MODE_CMDID - */ -typedef enum { - SPECIAL_OFF, - SPECIAL_ON, -} OPT_MODE_TYPE; - -typedef PREPACK struct { - u8 optMode; -} POSTPACK WMI_SET_OPT_MODE_CMD; - -/* - * WMI_TX_OPT_FRAME_CMDID - */ -typedef enum { - OPT_PROBE_REQ = 0x01, - OPT_PROBE_RESP = 0x02, - OPT_CPPP_START = 0x03, - OPT_CPPP_STOP = 0x04, -} WMI_OPT_FTYPE; - -typedef PREPACK struct { - u16 optIEDataLen; - u8 frmType; - u8 dstAddr[ATH_MAC_LEN]; - u8 bssid[ATH_MAC_LEN]; - u8 reserved; /* For alignment */ - u8 optIEData[1]; -} POSTPACK WMI_OPT_TX_FRAME_CMD; - -/* - * Special frame receive Event. - * Mechanism used to inform host of the receiption of the special frames. - * Consists of special frame info header followed by special frame body. - * The 802.11 header is not included. - */ -typedef PREPACK struct { - u16 channel; - u8 frameType; /* see WMI_OPT_FTYPE */ - s8 snr; - u8 srcAddr[ATH_MAC_LEN]; - u8 bssid[ATH_MAC_LEN]; -} POSTPACK WMI_OPT_RX_INFO_HDR; - -/* - * Reporting statistics. - */ -typedef PREPACK struct { - u32 tx_packets; - u32 tx_bytes; - u32 tx_unicast_pkts; - u32 tx_unicast_bytes; - u32 tx_multicast_pkts; - u32 tx_multicast_bytes; - u32 tx_broadcast_pkts; - u32 tx_broadcast_bytes; - u32 tx_rts_success_cnt; - u32 tx_packet_per_ac[4]; - u32 tx_errors_per_ac[4]; - - u32 tx_errors; - u32 tx_failed_cnt; - u32 tx_retry_cnt; - u32 tx_mult_retry_cnt; - u32 tx_rts_fail_cnt; - s32 tx_unicast_rate; -}POSTPACK tx_stats_t; - -typedef PREPACK struct { - u32 rx_packets; - u32 rx_bytes; - u32 rx_unicast_pkts; - u32 rx_unicast_bytes; - u32 rx_multicast_pkts; - u32 rx_multicast_bytes; - u32 rx_broadcast_pkts; - u32 rx_broadcast_bytes; - u32 rx_fragment_pkt; - - u32 rx_errors; - u32 rx_crcerr; - u32 rx_key_cache_miss; - u32 rx_decrypt_err; - u32 rx_duplicate_frames; - s32 rx_unicast_rate; -}POSTPACK rx_stats_t; - -typedef PREPACK struct { - u32 tkip_local_mic_failure; - u32 tkip_counter_measures_invoked; - u32 tkip_replays; - u32 tkip_format_errors; - u32 ccmp_format_errors; - u32 ccmp_replays; -}POSTPACK tkip_ccmp_stats_t; - -typedef PREPACK struct { - u32 power_save_failure_cnt; - u16 stop_tx_failure_cnt; - u16 atim_tx_failure_cnt; - u16 atim_rx_failure_cnt; - u16 bcn_rx_failure_cnt; -}POSTPACK pm_stats_t; - -typedef PREPACK struct { - u32 cs_bmiss_cnt; - u32 cs_lowRssi_cnt; - u16 cs_connect_cnt; - u16 cs_disconnect_cnt; - s16 cs_aveBeacon_rssi; - u16 cs_roam_count; - s16 cs_rssi; - u8 cs_snr; - u8 cs_aveBeacon_snr; - u8 cs_lastRoam_msec; -} POSTPACK cserv_stats_t; - -typedef PREPACK struct { - tx_stats_t tx_stats; - rx_stats_t rx_stats; - tkip_ccmp_stats_t tkipCcmpStats; -}POSTPACK wlan_net_stats_t; - -typedef PREPACK struct { - u32 arp_received; - u32 arp_matched; - u32 arp_replied; -} POSTPACK arp_stats_t; - -typedef PREPACK struct { - u32 wow_num_pkts_dropped; - u16 wow_num_events_discarded; - u8 wow_num_host_pkt_wakeups; - u8 wow_num_host_event_wakeups; -} POSTPACK wlan_wow_stats_t; - -typedef PREPACK struct { - u32 lqVal; - s32 noise_floor_calibation; - pm_stats_t pmStats; - wlan_net_stats_t txrxStats; - wlan_wow_stats_t wowStats; - arp_stats_t arpStats; - cserv_stats_t cservStats; -} POSTPACK WMI_TARGET_STATS; - -/* - * WMI_RSSI_THRESHOLD_EVENTID. - * Indicate the RSSI events to host. Events are indicated when we breach a - * thresold value. - */ -typedef enum{ - WMI_RSSI_THRESHOLD1_ABOVE = 0, - WMI_RSSI_THRESHOLD2_ABOVE, - WMI_RSSI_THRESHOLD3_ABOVE, - WMI_RSSI_THRESHOLD4_ABOVE, - WMI_RSSI_THRESHOLD5_ABOVE, - WMI_RSSI_THRESHOLD6_ABOVE, - WMI_RSSI_THRESHOLD1_BELOW, - WMI_RSSI_THRESHOLD2_BELOW, - WMI_RSSI_THRESHOLD3_BELOW, - WMI_RSSI_THRESHOLD4_BELOW, - WMI_RSSI_THRESHOLD5_BELOW, - WMI_RSSI_THRESHOLD6_BELOW -}WMI_RSSI_THRESHOLD_VAL; - -typedef PREPACK struct { - s16 rssi; - u8 range; -}POSTPACK WMI_RSSI_THRESHOLD_EVENT; - -/* - * WMI_ERROR_REPORT_EVENTID - */ -typedef enum{ - WMI_TARGET_PM_ERR_FAIL = 0x00000001, - WMI_TARGET_KEY_NOT_FOUND = 0x00000002, - WMI_TARGET_DECRYPTION_ERR = 0x00000004, - WMI_TARGET_BMISS = 0x00000008, - WMI_PSDISABLE_NODE_JOIN = 0x00000010, - WMI_TARGET_COM_ERR = 0x00000020, - WMI_TARGET_FATAL_ERR = 0x00000040 -} WMI_TARGET_ERROR_VAL; - -typedef PREPACK struct { - u32 errorVal; -}POSTPACK WMI_TARGET_ERROR_REPORT_EVENT; - -typedef PREPACK struct { - u8 retrys; -}POSTPACK WMI_TX_RETRY_ERR_EVENT; - -typedef enum{ - WMI_SNR_THRESHOLD1_ABOVE = 1, - WMI_SNR_THRESHOLD1_BELOW, - WMI_SNR_THRESHOLD2_ABOVE, - WMI_SNR_THRESHOLD2_BELOW, - WMI_SNR_THRESHOLD3_ABOVE, - WMI_SNR_THRESHOLD3_BELOW, - WMI_SNR_THRESHOLD4_ABOVE, - WMI_SNR_THRESHOLD4_BELOW -} WMI_SNR_THRESHOLD_VAL; - -typedef PREPACK struct { - u8 range; /* WMI_SNR_THRESHOLD_VAL */ - u8 snr; -}POSTPACK WMI_SNR_THRESHOLD_EVENT; - -typedef enum{ - WMI_LQ_THRESHOLD1_ABOVE = 1, - WMI_LQ_THRESHOLD1_BELOW, - WMI_LQ_THRESHOLD2_ABOVE, - WMI_LQ_THRESHOLD2_BELOW, - WMI_LQ_THRESHOLD3_ABOVE, - WMI_LQ_THRESHOLD3_BELOW, - WMI_LQ_THRESHOLD4_ABOVE, - WMI_LQ_THRESHOLD4_BELOW -} WMI_LQ_THRESHOLD_VAL; - -typedef PREPACK struct { - s32 lq; - u8 range; /* WMI_LQ_THRESHOLD_VAL */ -}POSTPACK WMI_LQ_THRESHOLD_EVENT; -/* - * WMI_REPORT_ROAM_TBL_EVENTID - */ -#define MAX_ROAM_TBL_CAND 5 - -typedef PREPACK struct { - s32 roam_util; - u8 bssid[ATH_MAC_LEN]; - s8 rssi; - s8 rssidt; - s8 last_rssi; - s8 util; - s8 bias; - u8 reserved; /* For alignment */ -} POSTPACK WMI_BSS_ROAM_INFO; - - -typedef PREPACK struct { - u16 roamMode; - u16 numEntries; - WMI_BSS_ROAM_INFO bssRoamInfo[1]; -} POSTPACK WMI_TARGET_ROAM_TBL; - -/* - * WMI_HCI_EVENT_EVENTID - */ -typedef PREPACK struct { - u16 evt_buf_sz; /* HCI event buffer size */ - u8 buf[1]; /* HCI event */ -} POSTPACK WMI_HCI_EVENT; - -/* - * WMI_CAC_EVENTID - */ -typedef enum { - CAC_INDICATION_ADMISSION = 0x00, - CAC_INDICATION_ADMISSION_RESP = 0x01, - CAC_INDICATION_DELETE = 0x02, - CAC_INDICATION_NO_RESP = 0x03, -}CAC_INDICATION; - -#define WMM_TSPEC_IE_LEN 63 - -typedef PREPACK struct { - u8 ac; - u8 cac_indication; - u8 statusCode; - u8 tspecSuggestion[WMM_TSPEC_IE_LEN]; -}POSTPACK WMI_CAC_EVENT; - -/* - * WMI_APLIST_EVENTID - */ - -typedef enum { - APLIST_VER1 = 1, -} APLIST_VER; - -typedef PREPACK struct { - u8 bssid[ATH_MAC_LEN]; - u16 channel; -} POSTPACK WMI_AP_INFO_V1; - -typedef PREPACK union { - WMI_AP_INFO_V1 apInfoV1; -} POSTPACK WMI_AP_INFO; - -typedef PREPACK struct { - u8 apListVer; - u8 numAP; - WMI_AP_INFO apList[1]; -} POSTPACK WMI_APLIST_EVENT; - -/* - * developer commands - */ - -/* - * WMI_SET_BITRATE_CMDID - * - * Get bit rate cmd uses same definition as set bit rate cmd - */ -typedef enum { - RATE_AUTO = -1, - RATE_1Mb = 0, - RATE_2Mb = 1, - RATE_5_5Mb = 2, - RATE_11Mb = 3, - RATE_6Mb = 4, - RATE_9Mb = 5, - RATE_12Mb = 6, - RATE_18Mb = 7, - RATE_24Mb = 8, - RATE_36Mb = 9, - RATE_48Mb = 10, - RATE_54Mb = 11, - RATE_MCS_0_20 = 12, - RATE_MCS_1_20 = 13, - RATE_MCS_2_20 = 14, - RATE_MCS_3_20 = 15, - RATE_MCS_4_20 = 16, - RATE_MCS_5_20 = 17, - RATE_MCS_6_20 = 18, - RATE_MCS_7_20 = 19, - RATE_MCS_0_40 = 20, - RATE_MCS_1_40 = 21, - RATE_MCS_2_40 = 22, - RATE_MCS_3_40 = 23, - RATE_MCS_4_40 = 24, - RATE_MCS_5_40 = 25, - RATE_MCS_6_40 = 26, - RATE_MCS_7_40 = 27, -} WMI_BIT_RATE; - -typedef PREPACK struct { - s8 rateIndex; /* see WMI_BIT_RATE */ - s8 mgmtRateIndex; - s8 ctlRateIndex; -} POSTPACK WMI_BIT_RATE_CMD; - - -typedef PREPACK struct { - s8 rateIndex; /* see WMI_BIT_RATE */ -} POSTPACK WMI_BIT_RATE_REPLY; - - -/* - * WMI_SET_FIXRATES_CMDID - * - * Get fix rates cmd uses same definition as set fix rates cmd - */ -#define FIX_RATE_1Mb ((u32)0x1) -#define FIX_RATE_2Mb ((u32)0x2) -#define FIX_RATE_5_5Mb ((u32)0x4) -#define FIX_RATE_11Mb ((u32)0x8) -#define FIX_RATE_6Mb ((u32)0x10) -#define FIX_RATE_9Mb ((u32)0x20) -#define FIX_RATE_12Mb ((u32)0x40) -#define FIX_RATE_18Mb ((u32)0x80) -#define FIX_RATE_24Mb ((u32)0x100) -#define FIX_RATE_36Mb ((u32)0x200) -#define FIX_RATE_48Mb ((u32)0x400) -#define FIX_RATE_54Mb ((u32)0x800) -#define FIX_RATE_MCS_0_20 ((u32)0x1000) -#define FIX_RATE_MCS_1_20 ((u32)0x2000) -#define FIX_RATE_MCS_2_20 ((u32)0x4000) -#define FIX_RATE_MCS_3_20 ((u32)0x8000) -#define FIX_RATE_MCS_4_20 ((u32)0x10000) -#define FIX_RATE_MCS_5_20 ((u32)0x20000) -#define FIX_RATE_MCS_6_20 ((u32)0x40000) -#define FIX_RATE_MCS_7_20 ((u32)0x80000) -#define FIX_RATE_MCS_0_40 ((u32)0x100000) -#define FIX_RATE_MCS_1_40 ((u32)0x200000) -#define FIX_RATE_MCS_2_40 ((u32)0x400000) -#define FIX_RATE_MCS_3_40 ((u32)0x800000) -#define FIX_RATE_MCS_4_40 ((u32)0x1000000) -#define FIX_RATE_MCS_5_40 ((u32)0x2000000) -#define FIX_RATE_MCS_6_40 ((u32)0x4000000) -#define FIX_RATE_MCS_7_40 ((u32)0x8000000) - -typedef PREPACK struct { - u32 fixRateMask; /* see WMI_BIT_RATE */ -} POSTPACK WMI_FIX_RATES_CMD, WMI_FIX_RATES_REPLY; - -typedef PREPACK struct { - u8 bEnableMask; - u8 frameType; /*type and subtype*/ - u32 frameRateMask; /* see WMI_BIT_RATE */ -} POSTPACK WMI_FRAME_RATES_CMD, WMI_FRAME_RATES_REPLY; - -/* - * WMI_SET_RECONNECT_AUTH_MODE_CMDID - * - * Set authentication mode - */ -typedef enum { - RECONN_DO_AUTH = 0x00, - RECONN_NOT_AUTH = 0x01 -} WMI_AUTH_MODE; - -typedef PREPACK struct { - u8 mode; -} POSTPACK WMI_SET_AUTH_MODE_CMD; - -/* - * WMI_SET_REASSOC_MODE_CMDID - * - * Set authentication mode - */ -typedef enum { - REASSOC_DO_DISASSOC = 0x00, - REASSOC_DONOT_DISASSOC = 0x01 -} WMI_REASSOC_MODE; - -typedef PREPACK struct { - u8 mode; -}POSTPACK WMI_SET_REASSOC_MODE_CMD; - -typedef enum { - ROAM_DATA_TIME = 1, /* Get The Roam Time Data */ -} ROAM_DATA_TYPE; - -typedef PREPACK struct { - u32 disassoc_time; - u32 no_txrx_time; - u32 assoc_time; - u32 allow_txrx_time; - u8 disassoc_bssid[ATH_MAC_LEN]; - s8 disassoc_bss_rssi; - u8 assoc_bssid[ATH_MAC_LEN]; - s8 assoc_bss_rssi; -} POSTPACK WMI_TARGET_ROAM_TIME; - -typedef PREPACK struct { - PREPACK union { - WMI_TARGET_ROAM_TIME roamTime; - } POSTPACK u; - u8 roamDataType ; -} POSTPACK WMI_TARGET_ROAM_DATA; - -typedef enum { - WMI_WMM_DISABLED = 0, - WMI_WMM_ENABLED -} WMI_WMM_STATUS; - -typedef PREPACK struct { - u8 status; -}POSTPACK WMI_SET_WMM_CMD; - -typedef PREPACK struct { - u8 status; -}POSTPACK WMI_SET_QOS_SUPP_CMD; - -typedef enum { - WMI_TXOP_DISABLED = 0, - WMI_TXOP_ENABLED -} WMI_TXOP_CFG; - -typedef PREPACK struct { - u8 txopEnable; -}POSTPACK WMI_SET_WMM_TXOP_CMD; - -typedef PREPACK struct { - u8 keepaliveInterval; -} POSTPACK WMI_SET_KEEPALIVE_CMD; - -typedef PREPACK struct { - u32 configured; - u8 keepaliveInterval; -} POSTPACK WMI_GET_KEEPALIVE_CMD; - -/* - * Add Application specified IE to a management frame - */ -#define WMI_MAX_IE_LEN 255 - -typedef PREPACK struct { - u8 mgmtFrmType; /* one of WMI_MGMT_FRAME_TYPE */ - u8 ieLen; /* Length of the IE that should be added to the MGMT frame */ - u8 ieInfo[1]; -} POSTPACK WMI_SET_APPIE_CMD; - -/* - * Notify the WSC registration status to the target - */ -#define WSC_REG_ACTIVE 1 -#define WSC_REG_INACTIVE 0 -/* Generic Hal Interface for setting hal paramters. */ -/* Add new Set HAL Param cmdIds here for newer params */ -typedef enum { - WHAL_SETCABTO_CMDID = 1, -}WHAL_CMDID; - -typedef PREPACK struct { - u8 cabTimeOut; -} POSTPACK WHAL_SETCABTO_PARAM; - -typedef PREPACK struct { - u8 whalCmdId; - u8 data[1]; -} POSTPACK WHAL_PARAMCMD; - - -#define WOW_MAX_FILTER_LISTS 1 /*4*/ -#define WOW_MAX_FILTERS_PER_LIST 4 -#define WOW_PATTERN_SIZE 64 -#define WOW_MASK_SIZE 64 - -#define MAC_MAX_FILTERS_PER_LIST 4 - -typedef PREPACK struct { - u8 wow_valid_filter; - u8 wow_filter_id; - u8 wow_filter_size; - u8 wow_filter_offset; - u8 wow_filter_mask[WOW_MASK_SIZE]; - u8 wow_filter_pattern[WOW_PATTERN_SIZE]; -} POSTPACK WOW_FILTER; - - -typedef PREPACK struct { - u8 wow_valid_list; - u8 wow_list_id; - u8 wow_num_filters; - u8 wow_total_list_size; - WOW_FILTER list[WOW_MAX_FILTERS_PER_LIST]; -} POSTPACK WOW_FILTER_LIST; - -typedef PREPACK struct { - u8 valid_filter; - u8 mac_addr[ATH_MAC_LEN]; -} POSTPACK MAC_FILTER; - - -typedef PREPACK struct { - u8 total_list_size; - u8 enable; - MAC_FILTER list[MAC_MAX_FILTERS_PER_LIST]; -} POSTPACK MAC_FILTER_LIST; - -#define MAX_IP_ADDRS 2 -typedef PREPACK struct { - u32 ips[MAX_IP_ADDRS]; /* IP in Network Byte Order */ -} POSTPACK WMI_SET_IP_CMD; - -typedef PREPACK struct { - u32 awake; - u32 asleep; -} POSTPACK WMI_SET_HOST_SLEEP_MODE_CMD; - -typedef enum { - WOW_FILTER_SSID = 0x1 -} WMI_WOW_FILTER; - -typedef PREPACK struct { - u32 enable_wow; - WMI_WOW_FILTER filter; - u16 hostReqDelay; -} POSTPACK WMI_SET_WOW_MODE_CMD; - -typedef PREPACK struct { - u8 filter_list_id; -} POSTPACK WMI_GET_WOW_LIST_CMD; - -/* - * WMI_GET_WOW_LIST_CMD reply - */ -typedef PREPACK struct { - u8 num_filters; /* number of patterns in reply */ - u8 this_filter_num; /* this is filter # x of total num_filters */ - u8 wow_mode; - u8 host_mode; - WOW_FILTER wow_filters[1]; -} POSTPACK WMI_GET_WOW_LIST_REPLY; - -typedef PREPACK struct { - u8 filter_list_id; - u8 filter_size; - u8 filter_offset; - u8 filter[1]; -} POSTPACK WMI_ADD_WOW_PATTERN_CMD; - -typedef PREPACK struct { - u16 filter_list_id; - u16 filter_id; -} POSTPACK WMI_DEL_WOW_PATTERN_CMD; - -typedef PREPACK struct { - u8 macaddr[ATH_MAC_LEN]; -} POSTPACK WMI_SET_MAC_ADDRESS_CMD; - -/* - * WMI_SET_AKMP_PARAMS_CMD - */ - -#define WMI_AKMP_MULTI_PMKID_EN 0x000001 - -typedef PREPACK struct { - u32 akmpInfo; -} POSTPACK WMI_SET_AKMP_PARAMS_CMD; - -typedef PREPACK struct { - u8 pmkid[WMI_PMKID_LEN]; -} POSTPACK WMI_PMKID; - -/* - * WMI_SET_PMKID_LIST_CMD - */ -#define WMI_MAX_PMKID_CACHE 8 - -typedef PREPACK struct { - u32 numPMKID; - WMI_PMKID pmkidList[WMI_MAX_PMKID_CACHE]; -} POSTPACK WMI_SET_PMKID_LIST_CMD; - -/* - * WMI_GET_PMKID_LIST_CMD Reply - * Following the Number of PMKIDs is the list of PMKIDs - */ -typedef PREPACK struct { - u32 numPMKID; - u8 bssidList[ATH_MAC_LEN][1]; - WMI_PMKID pmkidList[1]; -} POSTPACK WMI_PMKID_LIST_REPLY; - -typedef PREPACK struct { - u16 oldChannel; - u32 newChannel; -} POSTPACK WMI_CHANNEL_CHANGE_EVENT; - -typedef PREPACK struct { - u32 version; -} POSTPACK WMI_WLAN_VERSION_EVENT; - - -/* WMI_ADDBA_REQ_EVENTID */ -typedef PREPACK struct { - u8 tid; - u8 win_sz; - u16 st_seq_no; - u8 status; /* f/w response for ADDBA Req; OK(0) or failure(!=0) */ -} POSTPACK WMI_ADDBA_REQ_EVENT; - -/* WMI_ADDBA_RESP_EVENTID */ -typedef PREPACK struct { - u8 tid; - u8 status; /* OK(0), failure (!=0) */ - u16 amsdu_sz; /* Three values: Not supported(0), 3839, 8k */ -} POSTPACK WMI_ADDBA_RESP_EVENT; - -/* WMI_DELBA_EVENTID - * f/w received a DELBA for peer and processed it. - * Host is notified of this - */ -typedef PREPACK struct { - u8 tid; - u8 is_peer_initiator; - u16 reason_code; -} POSTPACK WMI_DELBA_EVENT; - - -#ifdef WAPI_ENABLE -#define WAPI_REKEY_UCAST 1 -#define WAPI_REKEY_MCAST 2 -typedef PREPACK struct { - u8 type; - u8 macAddr[ATH_MAC_LEN]; -} POSTPACK WMI_WAPIREKEY_EVENT; -#endif - - -/* WMI_ALLOW_AGGR_CMDID - * Configures tid's to allow ADDBA negotiations - * on each tid, in each direction - */ -typedef PREPACK struct { - u16 tx_allow_aggr; /* 16-bit mask to allow uplink ADDBA negotiation - bit position indicates tid*/ - u16 rx_allow_aggr; /* 16-bit mask to allow donwlink ADDBA negotiation - bit position indicates tid*/ -} POSTPACK WMI_ALLOW_AGGR_CMD; - -/* WMI_ADDBA_REQ_CMDID - * f/w starts performing ADDBA negotiations with peer - * on the given tid - */ -typedef PREPACK struct { - u8 tid; -} POSTPACK WMI_ADDBA_REQ_CMD; - -/* WMI_DELBA_REQ_CMDID - * f/w would teardown BA with peer. - * is_send_initiator indicates if it's or tx or rx side - */ -typedef PREPACK struct { - u8 tid; - u8 is_sender_initiator; - -} POSTPACK WMI_DELBA_REQ_CMD; - -#define PEER_NODE_JOIN_EVENT 0x00 -#define PEER_NODE_LEAVE_EVENT 0x01 -#define PEER_FIRST_NODE_JOIN_EVENT 0x10 -#define PEER_LAST_NODE_LEAVE_EVENT 0x11 -typedef PREPACK struct { - u8 eventCode; - u8 peerMacAddr[ATH_MAC_LEN]; -} POSTPACK WMI_PEER_NODE_EVENT; - -#define IEEE80211_FRAME_TYPE_MGT 0x00 -#define IEEE80211_FRAME_TYPE_CTL 0x04 - -/* - * Transmit complete event data structure(s) - */ - - -typedef PREPACK struct { -#define TX_COMPLETE_STATUS_SUCCESS 0 -#define TX_COMPLETE_STATUS_RETRIES 1 -#define TX_COMPLETE_STATUS_NOLINK 2 -#define TX_COMPLETE_STATUS_TIMEOUT 3 -#define TX_COMPLETE_STATUS_OTHER 4 - - u8 status; /* one of TX_COMPLETE_STATUS_... */ - u8 pktID; /* packet ID to identify parent packet */ - u8 rateIdx; /* rate index on successful transmission */ - u8 ackFailures; /* number of ACK failures in tx attempt */ -#if 0 /* optional params currently omitted. */ - u32 queueDelay; // usec delay measured Tx Start time - host delivery time - u32 mediaDelay; // usec delay measured ACK rx time - host delivery time -#endif -} POSTPACK TX_COMPLETE_MSG_V1; /* version 1 of tx complete msg */ - -typedef PREPACK struct { - u8 numMessages; /* number of tx comp msgs following this struct */ - u8 msgLen; /* length in bytes for each individual msg following this struct */ - u8 msgType; /* version of tx complete msg data following this struct */ - u8 reserved; /* individual messages follow this header */ -} POSTPACK WMI_TX_COMPLETE_EVENT; - -#define WMI_TXCOMPLETE_VERSION_1 (0x01) - - -/* - * ------- AP Mode definitions -------------- - */ - -/* - * !!! Warning !!! - * -Changing the following values needs compilation of both driver and firmware - */ -#ifdef AR6002_REV2 -#define AP_MAX_NUM_STA 4 -#else -#define AP_MAX_NUM_STA 8 -#endif -#define AP_ACL_SIZE 10 -#define IEEE80211_MAX_IE 256 -#define MCAST_AID 0xFF /* Spl. AID used to set DTIM flag in the beacons */ -#define DEF_AP_COUNTRY_CODE "US " -#define DEF_AP_WMODE_G WMI_11G_MODE -#define DEF_AP_WMODE_AG WMI_11AG_MODE -#define DEF_AP_DTIM 5 -#define DEF_BEACON_INTERVAL 100 - -/* AP mode disconnect reasons */ -#define AP_DISCONNECT_STA_LEFT 101 -#define AP_DISCONNECT_FROM_HOST 102 -#define AP_DISCONNECT_COMM_TIMEOUT 103 - -/* - * Used with WMI_AP_HIDDEN_SSID_CMDID - */ -#define HIDDEN_SSID_FALSE 0 -#define HIDDEN_SSID_TRUE 1 -typedef PREPACK struct { - u8 hidden_ssid; -} POSTPACK WMI_AP_HIDDEN_SSID_CMD; - -/* - * Used with WMI_AP_ACL_POLICY_CMDID - */ -#define AP_ACL_DISABLE 0x00 -#define AP_ACL_ALLOW_MAC 0x01 -#define AP_ACL_DENY_MAC 0x02 -#define AP_ACL_RETAIN_LIST_MASK 0x80 -typedef PREPACK struct { - u8 policy; -} POSTPACK WMI_AP_ACL_POLICY_CMD; - -/* - * Used with WMI_AP_ACL_MAC_LIST_CMDID - */ -#define ADD_MAC_ADDR 1 -#define DEL_MAC_ADDR 2 -typedef PREPACK struct { - u8 action; - u8 index; - u8 mac[ATH_MAC_LEN]; - u8 wildcard; -} POSTPACK WMI_AP_ACL_MAC_CMD; - -typedef PREPACK struct { - u16 index; - u8 acl_mac[AP_ACL_SIZE][ATH_MAC_LEN]; - u8 wildcard[AP_ACL_SIZE]; - u8 policy; -} POSTPACK WMI_AP_ACL; - -/* - * Used with WMI_AP_SET_NUM_STA_CMDID - */ -typedef PREPACK struct { - u8 num_sta; -} POSTPACK WMI_AP_SET_NUM_STA_CMD; - -/* - * Used with WMI_AP_SET_MLME_CMDID - */ -typedef PREPACK struct { - u8 mac[ATH_MAC_LEN]; - u16 reason; /* 802.11 reason code */ - u8 cmd; /* operation to perform */ -#define WMI_AP_MLME_ASSOC 1 /* associate station */ -#define WMI_AP_DISASSOC 2 /* disassociate station */ -#define WMI_AP_DEAUTH 3 /* deauthenticate station */ -#define WMI_AP_MLME_AUTHORIZE 4 /* authorize station */ -#define WMI_AP_MLME_UNAUTHORIZE 5 /* unauthorize station */ -} POSTPACK WMI_AP_SET_MLME_CMD; - -typedef PREPACK struct { - u32 period; -} POSTPACK WMI_AP_CONN_INACT_CMD; - -typedef PREPACK struct { - u32 period_min; - u32 dwell_ms; -} POSTPACK WMI_AP_PROT_SCAN_TIME_CMD; - -typedef PREPACK struct { - u32 flag; - u16 aid; -} POSTPACK WMI_AP_SET_PVB_CMD; - -#define WMI_DISABLE_REGULATORY_CODE "FF" - -typedef PREPACK struct { - u8 countryCode[3]; -} POSTPACK WMI_AP_SET_COUNTRY_CMD; - -typedef PREPACK struct { - u8 dtim; -} POSTPACK WMI_AP_SET_DTIM_CMD; - -typedef PREPACK struct { - u8 band; /* specifies which band to apply these values */ - u8 enable; /* allows 11n to be disabled on a per band basis */ - u8 chan_width_40M_supported; - u8 short_GI_20MHz; - u8 short_GI_40MHz; - u8 intolerance_40MHz; - u8 max_ampdu_len_exp; -} POSTPACK WMI_SET_HT_CAP_CMD; - -typedef PREPACK struct { - u8 sta_chan_width; -} POSTPACK WMI_SET_HT_OP_CMD; - -typedef PREPACK struct { - u32 rateMasks[8]; -} POSTPACK WMI_SET_TX_SELECT_RATES_CMD; - -typedef PREPACK struct { - u32 sgiMask; - u8 sgiPERThreshold; -} POSTPACK WMI_SET_TX_SGI_PARAM_CMD; - -#define DEFAULT_SGI_MASK 0x08080000 -#define DEFAULT_SGI_PER 10 - -typedef PREPACK struct { - u32 rateField; /* 1 bit per rate corresponding to index */ - u8 id; - u8 shortTrys; - u8 longTrys; - u8 reserved; /* padding */ -} POSTPACK WMI_SET_RATE_POLICY_CMD; - -typedef PREPACK struct { - u8 metaVersion; /* version of meta data for rx packets <0 = default> (0-7 = valid) */ - u8 dot11Hdr; /* 1 == leave .11 header intact , 0 == replace .11 header with .3 <default> */ - u8 defragOnHost; /* 1 == defragmentation is performed by host, 0 == performed by target <default> */ - u8 reserved[1]; /* alignment */ -} POSTPACK WMI_RX_FRAME_FORMAT_CMD; - - -typedef PREPACK struct { - u8 enable; /* 1 == device operates in thin mode , 0 == normal mode <default> */ - u8 reserved[3]; -} POSTPACK WMI_SET_THIN_MODE_CMD; - -/* AP mode events */ -/* WMI_PS_POLL_EVENT */ -typedef PREPACK struct { - u16 aid; -} POSTPACK WMI_PSPOLL_EVENT; - -typedef PREPACK struct { - u32 tx_bytes; - u32 tx_pkts; - u32 tx_error; - u32 tx_discard; - u32 rx_bytes; - u32 rx_pkts; - u32 rx_error; - u32 rx_discard; - u32 aid; -} POSTPACK WMI_PER_STA_STAT; - -#define AP_GET_STATS 0 -#define AP_CLEAR_STATS 1 - -typedef PREPACK struct { - u32 action; - WMI_PER_STA_STAT sta[AP_MAX_NUM_STA+1]; -} POSTPACK WMI_AP_MODE_STAT; -#define WMI_AP_MODE_STAT_SIZE(numSta) (sizeof(u32) + ((numSta + 1) * sizeof(WMI_PER_STA_STAT))) - -#define AP_11BG_RATESET1 1 -#define AP_11BG_RATESET2 2 -#define DEF_AP_11BG_RATESET AP_11BG_RATESET1 -typedef PREPACK struct { - u8 rateset; -} POSTPACK WMI_AP_SET_11BG_RATESET_CMD; -/* - * End of AP mode definitions - */ - -#ifdef __cplusplus -} -#endif - -#endif /* _WMI_H_ */ diff --git a/drivers/staging/ath6kl/include/common/wmix.h b/drivers/staging/ath6kl/include/common/wmix.h deleted file mode 100644 index 9435eab..0000000 --- a/drivers/staging/ath6kl/include/common/wmix.h +++ /dev/null @@ -1,271 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="wmix.h" company="Atheros"> -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Author(s): ="Atheros" -//============================================================================== - -/* - * This file contains extensions of the WMI protocol specified in the - * Wireless Module Interface (WMI). It includes definitions of all - * extended commands and events. Extensions include useful commands - * that are not directly related to wireless activities. They may - * be hardware-specific, and they might not be supported on all - * implementations. - * - * Extended WMIX commands are encapsulated in a WMI message with - * cmd=WMI_EXTENSION_CMD. - */ - -#ifndef _WMIX_H_ -#define _WMIX_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "dbglog.h" - -/* - * Extended WMI commands are those that are needed during wireless - * operation, but which are not really wireless commands. This allows, - * for instance, platform-specific commands. Extended WMI commands are - * embedded in a WMI command message with WMI_COMMAND_ID=WMI_EXTENSION_CMDID. - * Extended WMI events are similarly embedded in a WMI event message with - * WMI_EVENT_ID=WMI_EXTENSION_EVENTID. - */ -typedef PREPACK struct { - u32 commandId; -} POSTPACK WMIX_CMD_HDR; - -typedef enum { - WMIX_DSETOPEN_REPLY_CMDID = 0x2001, - WMIX_DSETDATA_REPLY_CMDID, - WMIX_GPIO_OUTPUT_SET_CMDID, - WMIX_GPIO_INPUT_GET_CMDID, - WMIX_GPIO_REGISTER_SET_CMDID, - WMIX_GPIO_REGISTER_GET_CMDID, - WMIX_GPIO_INTR_ACK_CMDID, - WMIX_HB_CHALLENGE_RESP_CMDID, - WMIX_DBGLOG_CFG_MODULE_CMDID, - WMIX_PROF_CFG_CMDID, /* 0x200a */ - WMIX_PROF_ADDR_SET_CMDID, - WMIX_PROF_START_CMDID, - WMIX_PROF_STOP_CMDID, - WMIX_PROF_COUNT_GET_CMDID, -} WMIX_COMMAND_ID; - -typedef enum { - WMIX_DSETOPENREQ_EVENTID = 0x3001, - WMIX_DSETCLOSE_EVENTID, - WMIX_DSETDATAREQ_EVENTID, - WMIX_GPIO_INTR_EVENTID, - WMIX_GPIO_DATA_EVENTID, - WMIX_GPIO_ACK_EVENTID, - WMIX_HB_CHALLENGE_RESP_EVENTID, - WMIX_DBGLOG_EVENTID, - WMIX_PROF_COUNT_EVENTID, -} WMIX_EVENT_ID; - -/* - * =============DataSet support================= - */ - -/* - * WMIX_DSETOPENREQ_EVENTID - * DataSet Open Request Event - */ -typedef PREPACK struct { - u32 dset_id; - u32 targ_dset_handle; /* echo'ed, not used by Host, */ - u32 targ_reply_fn; /* echo'ed, not used by Host, */ - u32 targ_reply_arg; /* echo'ed, not used by Host, */ -} POSTPACK WMIX_DSETOPENREQ_EVENT; - -/* - * WMIX_DSETCLOSE_EVENTID - * DataSet Close Event - */ -typedef PREPACK struct { - u32 access_cookie; -} POSTPACK WMIX_DSETCLOSE_EVENT; - -/* - * WMIX_DSETDATAREQ_EVENTID - * DataSet Data Request Event - */ -typedef PREPACK struct { - u32 access_cookie; - u32 offset; - u32 length; - u32 targ_buf; /* echo'ed, not used by Host, */ - u32 targ_reply_fn; /* echo'ed, not used by Host, */ - u32 targ_reply_arg; /* echo'ed, not used by Host, */ -} POSTPACK WMIX_DSETDATAREQ_EVENT; - -typedef PREPACK struct { - u32 status; - u32 targ_dset_handle; - u32 targ_reply_fn; - u32 targ_reply_arg; - u32 access_cookie; - u32 size; - u32 version; -} POSTPACK WMIX_DSETOPEN_REPLY_CMD; - -typedef PREPACK struct { - u32 status; - u32 targ_buf; - u32 targ_reply_fn; - u32 targ_reply_arg; - u32 length; - u8 buf[1]; -} POSTPACK WMIX_DSETDATA_REPLY_CMD; - - -/* - * =============GPIO support================= - * All masks are 18-bit masks with bit N operating on GPIO pin N. - */ - - -/* - * Set GPIO pin output state. - * In order for output to be driven, a pin must be enabled for output. - * This can be done during initialization through the GPIO Configuration - * DataSet, or during operation with the enable_mask. - * - * If a request is made to simultaneously set/clear or set/disable or - * clear/disable or disable/enable, results are undefined. - */ -typedef PREPACK struct { - u32 set_mask; /* pins to set */ - u32 clear_mask; /* pins to clear */ - u32 enable_mask; /* pins to enable for output */ - u32 disable_mask; /* pins to disable/tristate */ -} POSTPACK WMIX_GPIO_OUTPUT_SET_CMD; - -/* - * Set a GPIO register. For debug/exceptional cases. - * Values for gpioreg_id are GPIO_REGISTER_IDs, defined in a - * platform-dependent header. - */ -typedef PREPACK struct { - u32 gpioreg_id; /* GPIO register ID */ - u32 value; /* value to write */ -} POSTPACK WMIX_GPIO_REGISTER_SET_CMD; - -/* Get a GPIO register. For debug/exceptional cases. */ -typedef PREPACK struct { - u32 gpioreg_id; /* GPIO register to read */ -} POSTPACK WMIX_GPIO_REGISTER_GET_CMD; - -/* - * Host acknowledges and re-arms GPIO interrupts. A single - * message should be used to acknowledge all interrupts that - * were delivered in an earlier WMIX_GPIO_INTR_EVENT message. - */ -typedef PREPACK struct { - u32 ack_mask; /* interrupts to acknowledge */ -} POSTPACK WMIX_GPIO_INTR_ACK_CMD; - -/* - * Target informs Host of GPIO interrupts that have occurred since the - * last WMIX_GIPO_INTR_ACK_CMD was received. Additional information -- - * the current GPIO input values is provided -- in order to support - * use of a GPIO interrupt as a Data Valid signal for other GPIO pins. - */ -typedef PREPACK struct { - u32 intr_mask; /* pending GPIO interrupts */ - u32 input_values; /* recent GPIO input values */ -} POSTPACK WMIX_GPIO_INTR_EVENT; - -/* - * Target responds to Host's earlier WMIX_GPIO_INPUT_GET_CMDID request - * using a GPIO_DATA_EVENT with - * value set to the mask of GPIO pin inputs and - * reg_id set to GPIO_ID_NONE - * - * - * Target responds to Hosts's earlier WMIX_GPIO_REGISTER_GET_CMDID request - * using a GPIO_DATA_EVENT with - * value set to the value of the requested register and - * reg_id identifying the register (reflects the original request) - * NB: reg_id supports the future possibility of unsolicited - * WMIX_GPIO_DATA_EVENTs (for polling GPIO input), and it may - * simplify Host GPIO support. - */ -typedef PREPACK struct { - u32 value; - u32 reg_id; -} POSTPACK WMIX_GPIO_DATA_EVENT; - -/* - * =============Error Detection support================= - */ - -/* - * WMIX_HB_CHALLENGE_RESP_CMDID - * Heartbeat Challenge Response command - */ -typedef PREPACK struct { - u32 cookie; - u32 source; -} POSTPACK WMIX_HB_CHALLENGE_RESP_CMD; - -/* - * WMIX_HB_CHALLENGE_RESP_EVENTID - * Heartbeat Challenge Response Event - */ -#define WMIX_HB_CHALLENGE_RESP_EVENT WMIX_HB_CHALLENGE_RESP_CMD - -typedef PREPACK struct { - struct dbglog_config_s config; -} POSTPACK WMIX_DBGLOG_CFG_MODULE_CMD; - -/* - * =============Target Profiling support================= - */ - -typedef PREPACK struct { - u32 period; /* Time (in 30.5us ticks) between samples */ - u32 nbins; -} POSTPACK WMIX_PROF_CFG_CMD; - -typedef PREPACK struct { - u32 addr; -} POSTPACK WMIX_PROF_ADDR_SET_CMD; - -/* - * Target responds to Hosts's earlier WMIX_PROF_COUNT_GET_CMDID request - * using a WMIX_PROF_COUNT_EVENT with - * addr set to the next address - * count set to the corresponding count - */ -typedef PREPACK struct { - u32 addr; - u32 count; -} POSTPACK WMIX_PROF_COUNT_EVENT; - - -#ifdef __cplusplus -} -#endif - -#endif /* _WMIX_H_ */ diff --git a/drivers/staging/ath6kl/include/common_drv.h b/drivers/staging/ath6kl/include/common_drv.h deleted file mode 100644 index 34db299..0000000 --- a/drivers/staging/ath6kl/include/common_drv.h +++ /dev/null @@ -1,104 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Author(s): ="Atheros" -//============================================================================== -#ifndef COMMON_DRV_H_ -#define COMMON_DRV_H_ - -#include "hif.h" -#include "htc_packet.h" -#include "htc_api.h" - -/* structure that is the state information for the default credit distribution callback - * drivers should instantiate (zero-init as well) this structure in their driver instance - * and pass it as a context to the HTC credit distribution functions */ -struct common_credit_state_info { - int TotalAvailableCredits; /* total credits in the system at startup */ - int CurrentFreeCredits; /* credits available in the pool that have not been - given out to endpoints */ - struct htc_endpoint_credit_dist *pLowestPriEpDist; /* pointer to the lowest priority endpoint dist struct */ -}; - -struct hci_transport_callbacks { - s32 (*setupTransport)(void *ar); - void (*cleanupTransport)(void *ar); -}; - -struct hci_transport_misc_handles { - void *netDevice; - void *hifDevice; - void *htcHandle; -}; - -/* HTC TX packet tagging definitions */ -#define AR6K_CONTROL_PKT_TAG HTC_TX_PACKET_TAG_USER_DEFINED -#define AR6K_DATA_PKT_TAG (AR6K_CONTROL_PKT_TAG + 1) - -#define AR6002_VERSION_REV1 0x20000086 -#define AR6002_VERSION_REV2 0x20000188 -#define AR6003_VERSION_REV1 0x300002ba -#define AR6003_VERSION_REV2 0x30000384 - -#define AR6002_CUST_DATA_SIZE 112 -#define AR6003_CUST_DATA_SIZE 16 - -#ifdef __cplusplus -extern "C" { -#endif - -/* OS-independent APIs */ -int ar6000_setup_credit_dist(HTC_HANDLE HTCHandle, struct common_credit_state_info *pCredInfo); - -int ar6000_ReadRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data); - -int ar6000_WriteRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data); - -int ar6000_ReadDataDiag(struct hif_device *hifDevice, u32 address, u8 *data, u32 length); - -int ar6000_reset_device(struct hif_device *hifDevice, u32 TargetType, bool waitForCompletion, bool coldReset); - -void ar6000_dump_target_assert_info(struct hif_device *hifDevice, u32 TargetType); - -int ar6000_set_htc_params(struct hif_device *hifDevice, - u32 TargetType, - u32 MboxIsrYieldValue, - u8 HtcControlBuffers); - -int ar6000_set_hci_bridge_flags(struct hif_device *hifDevice, - u32 TargetType, - u32 Flags); - -void ar6000_copy_cust_data_from_target(struct hif_device *hifDevice, u32 TargetType); - -u8 *ar6000_get_cust_data_buffer(u32 TargetType); - -int ar6000_setBTState(void *context, u8 *pInBuf, u32 InBufSize); - -int ar6000_setDevicePowerState(void *context, u8 *pInBuf, u32 InBufSize); - -int ar6000_setWowMode(void *context, u8 *pInBuf, u32 InBufSize); - -int ar6000_setHostMode(void *context, u8 *pInBuf, u32 InBufSize); - -#ifdef __cplusplus -} -#endif - -#endif /*COMMON_DRV_H_*/ diff --git a/drivers/staging/ath6kl/include/dbglog_api.h b/drivers/staging/ath6kl/include/dbglog_api.h deleted file mode 100644 index a53aed3..0000000 --- a/drivers/staging/ath6kl/include/dbglog_api.h +++ /dev/null @@ -1,52 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="dbglog_api.h" company="Atheros"> -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// Permission to use, copy, modify, and/or distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// This file contains host side debug primitives. -// -// Author(s): ="Atheros" -//============================================================================== -#ifndef _DBGLOG_API_H_ -#define _DBGLOG_API_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "dbglog.h" - -#define DBGLOG_HOST_LOG_BUFFER_SIZE DBGLOG_LOG_BUFFER_SIZE - -#define DBGLOG_GET_DBGID(arg) \ - ((arg & DBGLOG_DBGID_MASK) >> DBGLOG_DBGID_OFFSET) - -#define DBGLOG_GET_MODULEID(arg) \ - ((arg & DBGLOG_MODULEID_MASK) >> DBGLOG_MODULEID_OFFSET) - -#define DBGLOG_GET_NUMARGS(arg) \ - ((arg & DBGLOG_NUM_ARGS_MASK) >> DBGLOG_NUM_ARGS_OFFSET) - -#define DBGLOG_GET_TIMESTAMP(arg) \ - ((arg & DBGLOG_TIMESTAMP_MASK) >> DBGLOG_TIMESTAMP_OFFSET) - -#ifdef __cplusplus -} -#endif - -#endif /* _DBGLOG_API_H_ */ diff --git a/drivers/staging/ath6kl/include/dl_list.h b/drivers/staging/ath6kl/include/dl_list.h deleted file mode 100644 index 13b1e69..0000000 --- a/drivers/staging/ath6kl/include/dl_list.h +++ /dev/null @@ -1,153 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="dl_list.h" company="Atheros"> -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Double-link list definitions (adapted from Atheros SDIO stack) -// -// Author(s): ="Atheros" -//============================================================================== -#ifndef __DL_LIST_H___ -#define __DL_LIST_H___ - -#include "a_osapi.h" - -#define A_CONTAINING_STRUCT(address, struct_type, field_name)\ - ((struct_type *)((unsigned long)(address) - (unsigned long)(&((struct_type *)0)->field_name))) - -/* list functions */ -/* pointers for the list */ -struct dl_list { - struct dl_list *pPrev; - struct dl_list *pNext; -}; -/* - * DL_LIST_INIT , initialize doubly linked list -*/ -#define DL_LIST_INIT(pList)\ - {(pList)->pPrev = pList; (pList)->pNext = pList;} - -/* faster macro to init list and add a single item */ -#define DL_LIST_INIT_AND_ADD(pList,pItem) \ -{ (pList)->pPrev = (pItem); \ - (pList)->pNext = (pItem); \ - (pItem)->pNext = (pList); \ - (pItem)->pPrev = (pList); \ -} - -#define DL_LIST_IS_EMPTY(pList) (((pList)->pPrev == (pList)) && ((pList)->pNext == (pList))) -#define DL_LIST_GET_ITEM_AT_HEAD(pList) (pList)->pNext -#define DL_LIST_GET_ITEM_AT_TAIL(pList) (pList)->pPrev -/* - * ITERATE_OVER_LIST pStart is the list, pTemp is a temp list member - * NOT: do not use this function if the items in the list are deleted inside the - * iteration loop -*/ -#define ITERATE_OVER_LIST(pStart, pTemp) \ - for((pTemp) =(pStart)->pNext; pTemp != (pStart); (pTemp) = (pTemp)->pNext) - - -/* safe iterate macro that allows the item to be removed from the list - * the iteration continues to the next item in the list - */ -#define ITERATE_OVER_LIST_ALLOW_REMOVE(pStart,pItem,st,offset) \ -{ \ - struct dl_list * pTemp; \ - pTemp = (pStart)->pNext; \ - while (pTemp != (pStart)) { \ - (pItem) = A_CONTAINING_STRUCT(pTemp,st,offset); \ - pTemp = pTemp->pNext; \ - -#define ITERATE_END }} - -/* - * DL_ListInsertTail - insert pAdd to the end of the list -*/ -static INLINE struct dl_list *DL_ListInsertTail(struct dl_list *pList, struct dl_list *pAdd) { - /* insert at tail */ - pAdd->pPrev = pList->pPrev; - pAdd->pNext = pList; - pList->pPrev->pNext = pAdd; - pList->pPrev = pAdd; - return pAdd; -} - -/* - * DL_ListInsertHead - insert pAdd into the head of the list -*/ -static INLINE struct dl_list * DL_ListInsertHead(struct dl_list * pList, struct dl_list * pAdd) { - /* insert at head */ - pAdd->pPrev = pList; - pAdd->pNext = pList->pNext; - pList->pNext->pPrev = pAdd; - pList->pNext = pAdd; - return pAdd; -} - -#define DL_ListAdd(pList,pItem) DL_ListInsertHead((pList),(pItem)) -/* - * DL_ListRemove - remove pDel from list -*/ -static INLINE struct dl_list * DL_ListRemove(struct dl_list * pDel) { - pDel->pNext->pPrev = pDel->pPrev; - pDel->pPrev->pNext = pDel->pNext; - /* point back to itself just to be safe, incase remove is called again */ - pDel->pNext = pDel; - pDel->pPrev = pDel; - return pDel; -} - -/* - * DL_ListRemoveItemFromHead - get a list item from the head -*/ -static INLINE struct dl_list * DL_ListRemoveItemFromHead(struct dl_list * pList) { - struct dl_list * pItem = NULL; - if (pList->pNext != pList) { - pItem = pList->pNext; - /* remove the first item from head */ - DL_ListRemove(pItem); - } - return pItem; -} - -static INLINE struct dl_list * DL_ListRemoveItemFromTail(struct dl_list * pList) { - struct dl_list * pItem = NULL; - if (pList->pPrev != pList) { - pItem = pList->pPrev; - /* remove the item from tail */ - DL_ListRemove(pItem); - } - return pItem; -} - -/* transfer src list items to the tail of the destination list */ -static INLINE void DL_ListTransferItemsToTail(struct dl_list * pDest, struct dl_list * pSrc) { - /* only concatenate if src is not empty */ - if (!DL_LIST_IS_EMPTY(pSrc)) { - /* cut out circular list in src and re-attach to end of dest */ - pSrc->pPrev->pNext = pDest; - pSrc->pNext->pPrev = pDest->pPrev; - pDest->pPrev->pNext = pSrc->pNext; - pDest->pPrev = pSrc->pPrev; - /* terminate src list, it is now empty */ - pSrc->pPrev = pSrc; - pSrc->pNext = pSrc; - } -} - -#endif /* __DL_LIST_H___ */ diff --git a/drivers/staging/ath6kl/include/dset_api.h b/drivers/staging/ath6kl/include/dset_api.h deleted file mode 100644 index fe901ba..0000000 --- a/drivers/staging/ath6kl/include/dset_api.h +++ /dev/null @@ -1,65 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="dset_api.h" company="Atheros"> -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Host-side DataSet API. -// -// Author(s): ="Atheros" -//============================================================================== -#ifndef _DSET_API_H_ -#define _DSET_API_H_ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* - * Host-side DataSet support is optional, and is not - * currently required for correct operation. To disable - * Host-side DataSet support, set this to 0. - */ -#ifndef CONFIG_HOST_DSET_SUPPORT -#define CONFIG_HOST_DSET_SUPPORT 1 -#endif - -/* Called to send a DataSet Open Reply back to the Target. */ -int wmi_dset_open_reply(struct wmi_t *wmip, - u32 status, - u32 access_cookie, - u32 size, - u32 version, - u32 targ_handle, - u32 targ_reply_fn, - u32 targ_reply_arg); - -/* Called to send a DataSet Data Reply back to the Target. */ -int wmi_dset_data_reply(struct wmi_t *wmip, - u32 status, - u8 *host_buf, - u32 length, - u32 targ_buf, - u32 targ_reply_fn, - u32 targ_reply_arg); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - - -#endif /* _DSET_API_H_ */ diff --git a/drivers/staging/ath6kl/include/hci_transport_api.h b/drivers/staging/ath6kl/include/hci_transport_api.h deleted file mode 100644 index 5e903fa..0000000 --- a/drivers/staging/ath6kl/include/hci_transport_api.h +++ /dev/null @@ -1,259 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Author(s): ="Atheros" -//============================================================================== -#ifndef _HCI_TRANSPORT_API_H_ -#define _HCI_TRANSPORT_API_H_ - - /* Bluetooth HCI packets are stored in HTC packet containers */ -#include "htc_packet.h" - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -typedef void *HCI_TRANSPORT_HANDLE; - -typedef HTC_ENDPOINT_ID HCI_TRANSPORT_PACKET_TYPE; - - /* we map each HCI packet class to a static Endpoint ID */ -#define HCI_COMMAND_TYPE ENDPOINT_1 -#define HCI_EVENT_TYPE ENDPOINT_2 -#define HCI_ACL_TYPE ENDPOINT_3 -#define HCI_PACKET_INVALID ENDPOINT_MAX - -#define HCI_GET_PACKET_TYPE(pP) (pP)->Endpoint -#define HCI_SET_PACKET_TYPE(pP,s) (pP)->Endpoint = (s) - -/* callback when an HCI packet was completely sent */ -typedef void (*HCI_TRANSPORT_SEND_PKT_COMPLETE)(void *, struct htc_packet *); -/* callback when an HCI packet is received */ -typedef void (*HCI_TRANSPORT_RECV_PKT)(void *, struct htc_packet *); -/* Optional receive buffer re-fill callback, - * On some OSes (like Linux) packets are allocated from a global pool and indicated up - * to the network stack. The driver never gets the packets back from the OS. For these OSes - * a refill callback can be used to allocate and re-queue buffers into HTC. - * A refill callback is used for the reception of ACL and EVENT packets. The caller must - * set the watermark trigger point to cause a refill. - */ -typedef void (*HCI_TRANSPORT_RECV_REFILL)(void *, HCI_TRANSPORT_PACKET_TYPE Type, int BuffersAvailable); -/* Optional receive packet refill - * On some systems packet buffers are an extremely limited resource. Rather than - * queue largest-possible-sized buffers to the HCI bridge, some systems would rather - * allocate a specific size as the packet is received. The trade off is - * slightly more processing (callback invoked for each RX packet) - * for the benefit of committing fewer buffer resources into the bridge. - * - * The callback is provided the length of the pending packet to fetch. This includes the - * full transport header, HCI header, plus the length of payload. The callback can return a pointer to - * the allocated HTC packet for immediate use. - * - * NOTE*** This callback is mutually exclusive with the the refill callback above. - * - * */ -typedef struct htc_packet *(*HCI_TRANSPORT_RECV_ALLOC)(void *, HCI_TRANSPORT_PACKET_TYPE Type, int Length); - -typedef enum _HCI_SEND_FULL_ACTION { - HCI_SEND_FULL_KEEP = 0, /* packet that overflowed should be kept in the queue */ - HCI_SEND_FULL_DROP = 1, /* packet that overflowed should be dropped */ -} HCI_SEND_FULL_ACTION; - -/* callback when an HCI send queue exceeds the caller's MaxSendQueueDepth threshold, - * the callback must return the send full action to take (either DROP or KEEP) */ -typedef HCI_SEND_FULL_ACTION (*HCI_TRANSPORT_SEND_FULL)(void *, struct htc_packet *); - -struct hci_transport_properties { - int HeadRoom; /* number of bytes in front of HCI packet for header space */ - int TailRoom; /* number of bytes at the end of the HCI packet for tail space */ - int IOBlockPad; /* I/O block padding required (always a power of 2) */ -}; - -struct hci_transport_config_info { - int ACLRecvBufferWaterMark; /* low watermark to trigger recv refill */ - int EventRecvBufferWaterMark; /* low watermark to trigger recv refill */ - int MaxSendQueueDepth; /* max number of packets in the single send queue */ - void *pContext; /* context for all callbacks */ - void (*TransportFailure)(void *pContext, int Status); /* transport failure callback */ - int (*TransportReady)(HCI_TRANSPORT_HANDLE, struct hci_transport_properties *,void *pContext); /* transport is ready */ - void (*TransportRemoved)(void *pContext); /* transport was removed */ - /* packet processing callbacks */ - HCI_TRANSPORT_SEND_PKT_COMPLETE pHCISendComplete; - HCI_TRANSPORT_RECV_PKT pHCIPktRecv; - HCI_TRANSPORT_RECV_REFILL pHCIPktRecvRefill; - HCI_TRANSPORT_RECV_ALLOC pHCIPktRecvAlloc; - HCI_TRANSPORT_SEND_FULL pHCISendFull; -}; - -/* ------ Function Prototypes ------ */ -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - @desc: Attach to the HCI transport module - @function name: HCI_TransportAttach - @input: HTCHandle - HTC handle (see HTC apis) - pInfo - initialization information - @output: - @return: HCI_TRANSPORT_HANDLE on success, NULL on failure - @notes: The HTC module provides HCI transport services. - @example: - @see also: HCI_TransportDetach -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -HCI_TRANSPORT_HANDLE HCI_TransportAttach(void *HTCHandle, struct hci_transport_config_info *pInfo); - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - @desc: Detach from the HCI transport module - @function name: HCI_TransportDetach - @input: HciTrans - HCI transport handle - pInfo - initialization information - @output: - @return: - @notes: - @example: - @see also: -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -void HCI_TransportDetach(HCI_TRANSPORT_HANDLE HciTrans); - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - @desc: Add receive packets to the HCI transport - @function name: HCI_TransportAddReceivePkts - @input: HciTrans - HCI transport handle - pQueue - a queue holding one or more packets - @output: - @return: 0 on success - @notes: user must supply HTC packets for capturing incomming HCI packets. The caller - must initialize each HTC packet using the SET_HTC_PACKET_INFO_RX_REFILL() - macro. Each packet in the queue must be of the same type and length - @example: - @see also: -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -int HCI_TransportAddReceivePkts(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet_queue *pQueue); - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - @desc: Send an HCI packet packet - @function name: HCI_TransportSendPkt - @input: HciTrans - HCI transport handle - pPacket - packet to send - Synchronous - send the packet synchronously (blocking) - @output: - @return: 0 - @notes: Caller must initialize packet using SET_HTC_PACKET_INFO_TX() and - HCI_SET_PACKET_TYPE() macros to prepare the packet. - If Synchronous is set to false the call is fully asynchronous. On error or completion, - the registered send complete callback will be called. - If Synchronous is set to true, the call will block until the packet is sent, if the - interface cannot send the packet within a 2 second timeout, the function will return - the failure code : A_EBUSY. - - Synchronous Mode should only be used at start-up to initialize the HCI device using - custom HCI commands. It should NOT be mixed with Asynchronous operations. Mixed synchronous - and asynchronous operation behavior is undefined. - - @example: - @see also: -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -int HCI_TransportSendPkt(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet *pPacket, bool Synchronous); - - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - @desc: Stop HCI transport - @function name: HCI_TransportStop - @input: HciTrans - hci transport handle - @output: - @return: - @notes: HCI transport communication will be halted. All receive and pending TX packets will - be flushed. - @example: - @see also: -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -void HCI_TransportStop(HCI_TRANSPORT_HANDLE HciTrans); - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - @desc: Start the HCI transport - @function name: HCI_TransportStart - @input: HciTrans - hci transport handle - @output: - @return: 0 on success - @notes: HCI transport communication will begin, the caller can expect the arrival - of HCI recv packets as soon as this call returns. - @example: - @see also: -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -int HCI_TransportStart(HCI_TRANSPORT_HANDLE HciTrans); - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - @desc: Enable or Disable Asynchronous Recv - @function name: HCI_TransportEnableDisableAsyncRecv - @input: HciTrans - hci transport handle - Enable - enable or disable asynchronous recv - @output: - @return: 0 on success - @notes: This API must be called when HCI recv is handled synchronously - @example: - @see also: -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -int HCI_TransportEnableDisableAsyncRecv(HCI_TRANSPORT_HANDLE HciTrans, bool Enable); - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - @desc: Receive an event packet from the HCI transport synchronously using polling - @function name: HCI_TransportRecvHCIEventSync - @input: HciTrans - hci transport handle - pPacket - HTC packet to hold the recv data - MaxPollMS - maximum polling duration in Milliseconds; - @output: - @return: 0 on success - @notes: This API should be used only during HCI device initialization, the caller must call - HCI_TransportEnableDisableAsyncRecv with Enable=false prior to using this API. - This API will only capture HCI Event packets. - @example: - @see also: HCI_TransportEnableDisableAsyncRecv -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -int HCI_TransportRecvHCIEventSync(HCI_TRANSPORT_HANDLE HciTrans, - struct htc_packet *pPacket, - int MaxPollMS); - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - @desc: Set the desired baud rate for the underlying transport layer - @function name: HCI_TransportSetBaudRate - @input: HciTrans - hci transport handle - Baud - baud rate in bps - @output: - @return: 0 on success - @notes: This API should be used only after HCI device initialization - @example: - @see also: -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -int HCI_TransportSetBaudRate(HCI_TRANSPORT_HANDLE HciTrans, u32 Baud); - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - @desc: Enable/Disable HCI Transport Power Management - @function name: HCI_TransportEnablePowerMgmt - @input: HciTrans - hci transport handle - Enable - 1 = Enable, 0 = Disable - @output: - @return: 0 on success - @notes: - @example: - @see also: -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -int HCI_TransportEnablePowerMgmt(HCI_TRANSPORT_HANDLE HciTrans, bool Enable); - -#ifdef __cplusplus -} -#endif - -#endif /* _HCI_TRANSPORT_API_H_ */ diff --git a/drivers/staging/ath6kl/include/hif.h b/drivers/staging/ath6kl/include/hif.h deleted file mode 100644 index 24200e7..0000000 --- a/drivers/staging/ath6kl/include/hif.h +++ /dev/null @@ -1,456 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="hif.h" company="Atheros"> -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// HIF specific declarations and prototypes -// -// Author(s): ="Atheros" -//============================================================================== -#ifndef _HIF_H_ -#define _HIF_H_ - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* Header files */ -#include "a_config.h" -#include "athdefs.h" -#include "a_osapi.h" -#include "dl_list.h" - - -typedef struct htc_callbacks HTC_CALLBACKS; -struct hif_device; - -/* - * direction - Direction of transfer (HIF_READ/HIF_WRITE). - */ -#define HIF_READ 0x00000001 -#define HIF_WRITE 0x00000002 -#define HIF_DIR_MASK (HIF_READ | HIF_WRITE) - -/* - * type - An interface may support different kind of read/write commands. - * For example: SDIO supports CMD52/CMD53s. In case of MSIO it - * translates to using different kinds of TPCs. The command type - * is thus divided into a basic and an extended command and can - * be specified using HIF_BASIC_IO/HIF_EXTENDED_IO. - */ -#define HIF_BASIC_IO 0x00000004 -#define HIF_EXTENDED_IO 0x00000008 -#define HIF_TYPE_MASK (HIF_BASIC_IO | HIF_EXTENDED_IO) - -/* - * emode - This indicates the whether the command is to be executed in a - * blocking or non-blocking fashion (HIF_SYNCHRONOUS/ - * HIF_ASYNCHRONOUS). The read/write data paths in HTC have been - * implemented using the asynchronous mode allowing the the bus - * driver to indicate the completion of operation through the - * registered callback routine. The requirement primarily comes - * from the contexts these operations get called from (a driver's - * transmit context or the ISR context in case of receive). - * Support for both of these modes is essential. - */ -#define HIF_SYNCHRONOUS 0x00000010 -#define HIF_ASYNCHRONOUS 0x00000020 -#define HIF_EMODE_MASK (HIF_SYNCHRONOUS | HIF_ASYNCHRONOUS) - -/* - * dmode - An interface may support different kinds of commands based on - * the tradeoff between the amount of data it can carry and the - * setup time. Byte and Block modes are supported (HIF_BYTE_BASIS/ - * HIF_BLOCK_BASIS). In case of latter, the data is rounded off - * to the nearest block size by padding. The size of the block is - * configurable at compile time using the HIF_BLOCK_SIZE and is - * negotiated with the target during initialization after the - * AR6000 interrupts are enabled. - */ -#define HIF_BYTE_BASIS 0x00000040 -#define HIF_BLOCK_BASIS 0x00000080 -#define HIF_DMODE_MASK (HIF_BYTE_BASIS | HIF_BLOCK_BASIS) - -/* - * amode - This indicates if the address has to be incremented on AR6000 - * after every read/write operation (HIF?FIXED_ADDRESS/ - * HIF_INCREMENTAL_ADDRESS). - */ -#define HIF_FIXED_ADDRESS 0x00000100 -#define HIF_INCREMENTAL_ADDRESS 0x00000200 -#define HIF_AMODE_MASK (HIF_FIXED_ADDRESS | HIF_INCREMENTAL_ADDRESS) - -#define HIF_WR_ASYNC_BYTE_FIX \ - (HIF_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS) -#define HIF_WR_ASYNC_BYTE_INC \ - (HIF_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS) -#define HIF_WR_ASYNC_BLOCK_INC \ - (HIF_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS) -#define HIF_WR_SYNC_BYTE_FIX \ - (HIF_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS) -#define HIF_WR_SYNC_BYTE_INC \ - (HIF_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS) -#define HIF_WR_SYNC_BLOCK_INC \ - (HIF_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS) -#define HIF_WR_ASYNC_BLOCK_FIX \ - (HIF_WRITE | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS) -#define HIF_WR_SYNC_BLOCK_FIX \ - (HIF_WRITE | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS) -#define HIF_RD_SYNC_BYTE_INC \ - (HIF_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS) -#define HIF_RD_SYNC_BYTE_FIX \ - (HIF_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS) -#define HIF_RD_ASYNC_BYTE_FIX \ - (HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_FIXED_ADDRESS) -#define HIF_RD_ASYNC_BLOCK_FIX \ - (HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS) -#define HIF_RD_ASYNC_BYTE_INC \ - (HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS) -#define HIF_RD_ASYNC_BLOCK_INC \ - (HIF_READ | HIF_ASYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS) -#define HIF_RD_SYNC_BLOCK_INC \ - (HIF_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS) -#define HIF_RD_SYNC_BLOCK_FIX \ - (HIF_READ | HIF_SYNCHRONOUS | HIF_EXTENDED_IO | HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS) - -typedef enum { - HIF_DEVICE_POWER_STATE = 0, - HIF_DEVICE_GET_MBOX_BLOCK_SIZE, - HIF_DEVICE_GET_MBOX_ADDR, - HIF_DEVICE_GET_PENDING_EVENTS_FUNC, - HIF_DEVICE_GET_IRQ_PROC_MODE, - HIF_DEVICE_GET_RECV_EVENT_MASK_UNMASK_FUNC, - HIF_DEVICE_POWER_STATE_CHANGE, - HIF_DEVICE_GET_IRQ_YIELD_PARAMS, - HIF_CONFIGURE_QUERY_SCATTER_REQUEST_SUPPORT, - HIF_DEVICE_GET_OS_DEVICE, - HIF_DEVICE_DEBUG_BUS_STATE, -} HIF_DEVICE_CONFIG_OPCODE; - -/* - * HIF CONFIGURE definitions: - * - * HIF_DEVICE_GET_MBOX_BLOCK_SIZE - * input : none - * output : array of 4 u32s - * notes: block size is returned for each mailbox (4) - * - * HIF_DEVICE_GET_MBOX_ADDR - * input : none - * output : struct hif_device_mbox_info - * notes: - * - * HIF_DEVICE_GET_PENDING_EVENTS_FUNC - * input : none - * output: HIF_PENDING_EVENTS_FUNC function pointer - * notes: this is optional for the HIF layer, if the request is - * not handled then it indicates that the upper layer can use - * the standard device methods to get pending events (IRQs, mailbox messages etc..) - * otherwise it can call the function pointer to check pending events. - * - * HIF_DEVICE_GET_IRQ_PROC_MODE - * input : none - * output : HIF_DEVICE_IRQ_PROCESSING_MODE (interrupt processing mode) - * note: the hif layer interfaces with the underlying OS-specific bus driver. The HIF - * layer can report whether IRQ processing is requires synchronous behavior or - * can be processed using asynchronous bus requests (typically faster). - * - * HIF_DEVICE_GET_RECV_EVENT_MASK_UNMASK_FUNC - * input : - * output : HIF_MASK_UNMASK_RECV_EVENT function pointer - * notes: this is optional for the HIF layer. The HIF layer may require a special mechanism - * to mask receive message events. The upper layer can call this pointer when it needs - * to mask/unmask receive events (in case it runs out of buffers). - * - * HIF_DEVICE_POWER_STATE_CHANGE - * - * input : HIF_DEVICE_POWER_CHANGE_TYPE - * output : none - * note: this is optional for the HIF layer. The HIF layer can handle power on/off state change - * requests in an interconnect specific way. This is highly OS and bus driver dependent. - * The caller must guarantee that no HIF read/write requests will be made after the device - * is powered down. - * - * HIF_DEVICE_GET_IRQ_YIELD_PARAMS - * - * input : none - * output : struct hif_device_irq_yield_params - * note: This query checks if the HIF layer wishes to impose a processing yield count for the DSR handler. - * The DSR callback handler will exit after a fixed number of RX packets or events are processed. - * This query is only made if the device reports an IRQ processing mode of HIF_DEVICE_IRQ_SYNC_ONLY. - * The HIF implementation can ignore this command if it does not desire the DSR callback to yield. - * The HIF layer can indicate the maximum number of IRQ processing units (RX packets) before the - * DSR handler callback must yield and return control back to the HIF layer. When a yield limit is - * used the DSR callback will not call HIFAckInterrupts() as it would normally do before returning. - * The HIF implementation that requires a yield count must call HIFAckInterrupt() when it is prepared - * to process interrupts again. - * - * HIF_CONFIGURE_QUERY_SCATTER_REQUEST_SUPPORT - * input : none - * output : struct hif_device_scatter_support_info - * note: This query checks if the HIF layer implements the SCATTER request interface. Scatter requests - * allows upper layers to submit mailbox I/O operations using a list of buffers. This is useful for - * multi-message transfers that can better utilize the bus interconnect. - * - * - * HIF_DEVICE_GET_OS_DEVICE - * intput : none - * output : struct hif_device_os_device_info; - * note: On some operating systems, the HIF layer has a parent device object for the bus. This object - * may be required to register certain types of logical devices. - * - * HIF_DEVICE_DEBUG_BUS_STATE - * input : none - * output : none - * note: This configure option triggers the HIF interface to dump as much bus interface state. This - * configuration request is optional (No-OP on some HIF implementations) - * - */ - -struct hif_mbox_properties { - u32 ExtendedAddress; /* extended address for larger writes */ - u32 ExtendedSize; -}; - -#define HIF_MBOX_FLAG_NO_BUNDLING (1 << 0) /* do not allow bundling over the mailbox */ - -typedef enum _MBOX_BUF_IF_TYPE { - MBOX_BUS_IF_SDIO = 0, - MBOX_BUS_IF_SPI = 1, -} MBOX_BUF_IF_TYPE; - -struct hif_device_mbox_info { - u32 MboxAddresses[4]; /* must be first element for legacy HIFs that return the address in - and ARRAY of 32-bit words */ - - /* the following describe extended mailbox properties */ - struct hif_mbox_properties MboxProp[4]; - /* if the HIF supports the GMbox extended address region it can report it - * here, some interfaces cannot support the GMBOX address range and not set this */ - u32 GMboxAddress; - u32 GMboxSize; - u32 Flags; /* flags to describe mbox behavior or usage */ - MBOX_BUF_IF_TYPE MboxBusIFType; /* mailbox bus interface type */ -}; - -typedef enum { - HIF_DEVICE_IRQ_SYNC_ONLY, /* for HIF implementations that require the DSR to process all - interrupts before returning */ - HIF_DEVICE_IRQ_ASYNC_SYNC, /* for HIF implementations that allow DSR to process interrupts - using ASYNC I/O (that is HIFAckInterrupt can be called at a - later time */ -} HIF_DEVICE_IRQ_PROCESSING_MODE; - -typedef enum { - HIF_DEVICE_POWER_UP, /* HIF layer should power up interface and/or module */ - HIF_DEVICE_POWER_DOWN, /* HIF layer should initiate bus-specific measures to minimize power */ - HIF_DEVICE_POWER_CUT /* HIF layer should initiate bus-specific AND/OR platform-specific measures - to completely power-off the module and associated hardware (i.e. cut power supplies) - */ -} HIF_DEVICE_POWER_CHANGE_TYPE; - -struct hif_device_irq_yield_params { - int RecvPacketYieldCount; /* max number of packets to force DSR to return */ -}; - - -struct hif_scatter_item { - u8 *pBuffer; /* CPU accessible address of buffer */ - int Length; /* length of transfer to/from this buffer */ - void *pCallerContexts[2]; /* space for caller to insert a context associated with this item */ -}; - -struct hif_scatter_req; -typedef void ( *HIF_SCATTER_COMP_CB)(struct hif_scatter_req *); - -typedef enum _HIF_SCATTER_METHOD { - HIF_SCATTER_NONE = 0, - HIF_SCATTER_DMA_REAL, /* Real SG support no restrictions */ - HIF_SCATTER_DMA_BOUNCE, /* Uses SG DMA but HIF layer uses an internal bounce buffer */ -} HIF_SCATTER_METHOD; - -struct hif_scatter_req { - struct dl_list ListLink; /* link management */ - u32 Address; /* address for the read/write operation */ - u32 Request; /* request flags */ - u32 TotalLength; /* total length of entire transfer */ - u32 CallerFlags; /* caller specific flags can be stored here */ - HIF_SCATTER_COMP_CB CompletionRoutine; /* completion routine set by caller */ - int CompletionStatus; /* status of completion */ - void *Context; /* caller context for this request */ - int ValidScatterEntries; /* number of valid entries set by caller */ - HIF_SCATTER_METHOD ScatterMethod; /* scatter method handled by HIF */ - void *HIFPrivate[4]; /* HIF private area */ - u8 *pScatterBounceBuffer; /* bounce buffer for upper layers to copy to/from */ - struct hif_scatter_item ScatterList[1]; /* start of scatter list */ -}; - -typedef struct hif_scatter_req * ( *HIF_ALLOCATE_SCATTER_REQUEST)(struct hif_device *device); -typedef void ( *HIF_FREE_SCATTER_REQUEST)(struct hif_device *device, struct hif_scatter_req *request); -typedef int ( *HIF_READWRITE_SCATTER)(struct hif_device *device, struct hif_scatter_req *request); - -struct hif_device_scatter_support_info { - /* information returned from HIF layer */ - HIF_ALLOCATE_SCATTER_REQUEST pAllocateReqFunc; - HIF_FREE_SCATTER_REQUEST pFreeReqFunc; - HIF_READWRITE_SCATTER pReadWriteScatterFunc; - int MaxScatterEntries; - int MaxTransferSizePerScatterReq; -}; - -struct hif_device_os_device_info { - void *pOSDevice; -}; - -#define HIF_MAX_DEVICES 1 - -struct htc_callbacks { - void *context; /* context to pass to the dsrhandler - note : rwCompletionHandler is provided the context passed to HIFReadWrite */ - int (* rwCompletionHandler)(void *rwContext, int status); - int (* dsrHandler)(void *context); -}; - -typedef struct osdrv_callbacks { - void *context; /* context to pass for all callbacks except deviceRemovedHandler - the deviceRemovedHandler is only called if the device is claimed */ - int (* deviceInsertedHandler)(void *context, void *hif_handle); - int (* deviceRemovedHandler)(void *claimedContext, void *hif_handle); - int (* deviceSuspendHandler)(void *context); - int (* deviceResumeHandler)(void *context); - int (* deviceWakeupHandler)(void *context); - int (* devicePowerChangeHandler)(void *context, HIF_DEVICE_POWER_CHANGE_TYPE config); -} OSDRV_CALLBACKS; - -#define HIF_OTHER_EVENTS (1 << 0) /* other interrupts (non-Recv) are pending, host - needs to read the register table to figure out what */ -#define HIF_RECV_MSG_AVAIL (1 << 1) /* pending recv packet */ - -struct hif_pending_events_info { - u32 Events; - u32 LookAhead; - u32 AvailableRecvBytes; -#ifdef THREAD_X - u32 Polling; - u32 INT_CAUSE_REG; -#endif -}; - - /* function to get pending events , some HIF modules use special mechanisms - * to detect packet available and other interrupts */ -typedef int ( *HIF_PENDING_EVENTS_FUNC)(struct hif_device *device, - struct hif_pending_events_info *pEvents, - void *AsyncContext); - -#define HIF_MASK_RECV true -#define HIF_UNMASK_RECV false - /* function to mask recv events */ -typedef int ( *HIF_MASK_UNMASK_RECV_EVENT)(struct hif_device *device, - bool Mask, - void *AsyncContext); - - -/* - * This API is used to perform any global initialization of the HIF layer - * and to set OS driver callbacks (i.e. insertion/removal) to the HIF layer - * - */ -int HIFInit(OSDRV_CALLBACKS *callbacks); - -/* This API claims the HIF device and provides a context for handling removal. - * The device removal callback is only called when the OSDRV layer claims - * a device. The claimed context must be non-NULL */ -void HIFClaimDevice(struct hif_device *device, void *claimedContext); -/* release the claimed device */ -void HIFReleaseDevice(struct hif_device *device); - -/* This API allows the HTC layer to attach to the HIF device */ -int HIFAttachHTC(struct hif_device *device, HTC_CALLBACKS *callbacks); -/* This API detaches the HTC layer from the HIF device */ -void HIFDetachHTC(struct hif_device *device); - -/* - * This API is used to provide the read/write interface over the specific bus - * interface. - * address - Starting address in the AR6000's address space. For mailbox - * writes, it refers to the start of the mbox boundary. It should - * be ensured that the last byte falls on the mailbox's EOM. For - * mailbox reads, it refers to the end of the mbox boundary. - * buffer - Pointer to the buffer containg the data to be transmitted or - * received. - * length - Amount of data to be transmitted or received. - * request - Characterizes the attributes of the command. - */ -int -HIFReadWrite(struct hif_device *device, - u32 address, - u8 *buffer, - u32 length, - u32 request, - void *context); - -/* - * This can be initiated from the unload driver context when the OSDRV layer has no more use for - * the device. - */ -void HIFShutDownDevice(struct hif_device *device); - -/* - * This should translate to an acknowledgment to the bus driver indicating that - * the previous interrupt request has been serviced and the all the relevant - * sources have been cleared. HTC is ready to process more interrupts. - * This should prevent the bus driver from raising an interrupt unless the - * previous one has been serviced and acknowledged using the previous API. - */ -void HIFAckInterrupt(struct hif_device *device); - -void HIFMaskInterrupt(struct hif_device *device); - -void HIFUnMaskInterrupt(struct hif_device *device); - -#ifdef THREAD_X -/* - * This set of functions are to be used by the bus driver to notify - * the HIF module about various events. - * These are not implemented if the bus driver provides an alternative - * way for this notification though callbacks for instance. - */ -int HIFInsertEventNotify(void); - -int HIFRemoveEventNotify(void); - -int HIFIRQEventNotify(void); - -int HIFRWCompleteEventNotify(void); -#endif - -int -HIFConfigureDevice(struct hif_device *device, HIF_DEVICE_CONFIG_OPCODE opcode, - void *config, u32 configLen); - -/* - * This API wait for the remaining MBOX messages to be drained - * This should be moved to HTC AR6K layer - */ -int hifWaitForPendingRecv(struct hif_device *device); - -#ifdef __cplusplus -} -#endif - -#endif /* _HIF_H_ */ diff --git a/drivers/staging/ath6kl/include/host_version.h b/drivers/staging/ath6kl/include/host_version.h deleted file mode 100644 index 74f1982..0000000 --- a/drivers/staging/ath6kl/include/host_version.h +++ /dev/null @@ -1,52 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="host_version.h" company="Atheros"> -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// Permission to use, copy, modify, and/or distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// This file contains version information for the sample host driver for the -// AR6000 chip -// -// Author(s): ="Atheros" -//============================================================================== -#ifndef _HOST_VERSION_H_ -#define _HOST_VERSION_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include <AR6002/AR6K_version.h> - -/* - * The version number is made up of major, minor, patch and build - * numbers. These are 16 bit numbers. The build and release script will - * set the build number using a Perforce counter. Here the build number is - * set to 9999 so that builds done without the build-release script are easily - * identifiable. - */ - -#define ATH_SW_VER_MAJOR __VER_MAJOR_ -#define ATH_SW_VER_MINOR __VER_MINOR_ -#define ATH_SW_VER_PATCH __VER_PATCH_ -#define ATH_SW_VER_BUILD __BUILD_NUMBER_ - -#ifdef __cplusplus -} -#endif - -#endif /* _HOST_VERSION_H_ */ diff --git a/drivers/staging/ath6kl/include/htc_api.h b/drivers/staging/ath6kl/include/htc_api.h deleted file mode 100644 index 4fb7675..0000000 --- a/drivers/staging/ath6kl/include/htc_api.h +++ /dev/null @@ -1,575 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="htc_api.h" company="Atheros"> -// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Author(s): ="Atheros" -//============================================================================== -#ifndef _HTC_API_H_ -#define _HTC_API_H_ - -#include "htc_packet.h" -#include <htc.h> -#include <htc_services.h> - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - -/* TODO.. for BMI */ -#define ENDPOINT1 0 -// TODO -remove me, but we have to fix BMI first -#define HTC_MAILBOX_NUM_MAX 4 - -/* this is the amount of header room required by users of HTC */ -#define HTC_HEADER_LEN HTC_HDR_LENGTH - -typedef void *HTC_HANDLE; - -typedef u16 HTC_SERVICE_ID; - -struct htc_init_info { - void *pContext; /* context for target failure notification */ - void (*TargetFailure)(void *Instance, int Status); -}; - -/* per service connection send completion */ -typedef void (*HTC_EP_SEND_PKT_COMPLETE)(void *,struct htc_packet *); -/* per service connection callback when a plurality of packets have been sent - * The struct htc_packet_queue is a temporary queue object (e.g. freed on return from the callback) - * to hold a list of completed send packets. - * If the handler cannot fully traverse the packet queue before returning, it should - * transfer the items of the queue into the caller's private queue using: - * HTC_PACKET_ENQUEUE() */ -typedef void (*HTC_EP_SEND_PKT_COMP_MULTIPLE)(void *,struct htc_packet_queue *); -/* per service connection pkt received */ -typedef void (*HTC_EP_RECV_PKT)(void *,struct htc_packet *); -/* per service connection callback when a plurality of packets are received - * The struct htc_packet_queue is a temporary queue object (e.g. freed on return from the callback) - * to hold a list of recv packets. - * If the handler cannot fully traverse the packet queue before returning, it should - * transfer the items of the queue into the caller's private queue using: - * HTC_PACKET_ENQUEUE() */ -typedef void (*HTC_EP_RECV_PKT_MULTIPLE)(void *,struct htc_packet_queue *); - -/* Optional per service connection receive buffer re-fill callback, - * On some OSes (like Linux) packets are allocated from a global pool and indicated up - * to the network stack. The driver never gets the packets back from the OS. For these OSes - * a refill callback can be used to allocate and re-queue buffers into HTC. - * - * On other OSes, the network stack can call into the driver's OS-specifc "return_packet" handler and - * the driver can re-queue these buffers into HTC. In this regard a refill callback is - * unnecessary */ -typedef void (*HTC_EP_RECV_REFILL)(void *, HTC_ENDPOINT_ID Endpoint); - -/* Optional per service connection receive buffer allocation callback. - * On some systems packet buffers are an extremely limited resource. Rather than - * queue largest-possible-sized buffers to HTC, some systems would rather - * allocate a specific size as the packet is received. The trade off is - * slightly more processing (callback invoked for each RX packet) - * for the benefit of committing fewer buffer resources into HTC. - * - * The callback is provided the length of the pending packet to fetch. This includes the - * HTC header length plus the length of payload. The callback can return a pointer to - * the allocated HTC packet for immediate use. - * - * Alternatively a variant of this handler can be used to allocate large receive packets as needed. - * For example an application can use the refill mechanism for normal packets and the recv-alloc mechanism to - * handle the case where a large packet buffer is required. This can significantly reduce the - * amount of "committed" memory used to receive packets. - * - * */ -typedef struct htc_packet *(*HTC_EP_RECV_ALLOC)(void *, HTC_ENDPOINT_ID Endpoint, int Length); - -typedef enum _HTC_SEND_FULL_ACTION { - HTC_SEND_FULL_KEEP = 0, /* packet that overflowed should be kept in the queue */ - HTC_SEND_FULL_DROP = 1, /* packet that overflowed should be dropped */ -} HTC_SEND_FULL_ACTION; - -/* Optional per service connection callback when a send queue is full. This can occur if the - * host continues queueing up TX packets faster than credits can arrive - * To prevent the host (on some Oses like Linux) from continuously queueing packets - * and consuming resources, this callback is provided so that that the host - * can disable TX in the subsystem (i.e. network stack). - * This callback is invoked for each packet that "overflows" the HTC queue. The callback can - * determine whether the new packet that overflowed the queue can be kept (HTC_SEND_FULL_KEEP) or - * dropped (HTC_SEND_FULL_DROP). If a packet is dropped, the EpTxComplete handler will be called - * and the packet's status field will be set to A_NO_RESOURCE. - * Other OSes require a "per-packet" indication for each completed TX packet, this - * closed loop mechanism will prevent the network stack from overunning the NIC - * The packet to keep or drop is passed for inspection to the registered handler the handler - * must ONLY inspect the packet, it may not free or reclaim the packet. */ -typedef HTC_SEND_FULL_ACTION (*HTC_EP_SEND_QUEUE_FULL)(void *, struct htc_packet *pPacket); - -struct htc_ep_callbacks { - void *pContext; /* context for each callback */ - HTC_EP_SEND_PKT_COMPLETE EpTxComplete; /* tx completion callback for connected endpoint */ - HTC_EP_RECV_PKT EpRecv; /* receive callback for connected endpoint */ - HTC_EP_RECV_REFILL EpRecvRefill; /* OPTIONAL receive re-fill callback for connected endpoint */ - HTC_EP_SEND_QUEUE_FULL EpSendFull; /* OPTIONAL send full callback */ - HTC_EP_RECV_ALLOC EpRecvAlloc; /* OPTIONAL recv allocation callback */ - HTC_EP_RECV_ALLOC EpRecvAllocThresh; /* OPTIONAL recv allocation callback based on a threshold */ - HTC_EP_SEND_PKT_COMP_MULTIPLE EpTxCompleteMultiple; /* OPTIONAL completion handler for multiple complete - indications (EpTxComplete must be NULL) */ - HTC_EP_RECV_PKT_MULTIPLE EpRecvPktMultiple; /* OPTIONAL completion handler for multiple - recv packet indications (EpRecv must be NULL) */ - int RecvAllocThreshold; /* if EpRecvAllocThresh is non-NULL, HTC will compare the - threshold value to the current recv packet length and invoke - the EpRecvAllocThresh callback to acquire a packet buffer */ - int RecvRefillWaterMark; /* if a EpRecvRefill handler is provided, this value - can be used to set a trigger refill callback - when the recv queue drops below this value - if set to 0, the refill is only called when packets - are empty */ -}; - -/* service connection information */ -struct htc_service_connect_req { - HTC_SERVICE_ID ServiceID; /* service ID to connect to */ - u16 ConnectionFlags; /* connection flags, see htc protocol definition */ - u8 *pMetaData; /* ptr to optional service-specific meta-data */ - u8 MetaDataLength; /* optional meta data length */ - struct htc_ep_callbacks EpCallbacks; /* endpoint callbacks */ - int MaxSendQueueDepth; /* maximum depth of any send queue */ - u32 LocalConnectionFlags; /* HTC flags for the host-side (local) connection */ - unsigned int MaxSendMsgSize; /* override max message size in send direction */ -}; - -#define HTC_LOCAL_CONN_FLAGS_ENABLE_SEND_BUNDLE_PADDING (1 << 0) /* enable send bundle padding for this endpoint */ - -/* service connection response information */ -struct htc_service_connect_resp { - u8 *pMetaData; /* caller supplied buffer to optional meta-data */ - u8 BufferLength; /* length of caller supplied buffer */ - u8 ActualLength; /* actual length of meta data */ - HTC_ENDPOINT_ID Endpoint; /* endpoint to communicate over */ - unsigned int MaxMsgLength; /* max length of all messages over this endpoint */ - u8 ConnectRespCode; /* connect response code from target */ -}; - -/* endpoint distribution structure */ -struct htc_endpoint_credit_dist { - struct htc_endpoint_credit_dist *pNext; - struct htc_endpoint_credit_dist *pPrev; - HTC_SERVICE_ID ServiceID; /* Service ID (set by HTC) */ - HTC_ENDPOINT_ID Endpoint; /* endpoint for this distribution struct (set by HTC) */ - u32 DistFlags; /* distribution flags, distribution function can - set default activity using SET_EP_ACTIVE() macro */ - int TxCreditsNorm; /* credits for normal operation, anything above this - indicates the endpoint is over-subscribed, this field - is only relevant to the credit distribution function */ - int TxCreditsMin; /* floor for credit distribution, this field is - only relevant to the credit distribution function */ - int TxCreditsAssigned; /* number of credits assigned to this EP, this field - is only relevant to the credit dist function */ - int TxCredits; /* current credits available, this field is used by - HTC to determine whether a message can be sent or - must be queued */ - int TxCreditsToDist; /* pending credits to distribute on this endpoint, this - is set by HTC when credit reports arrive. - The credit distribution functions sets this to zero - when it distributes the credits */ - int TxCreditsSeek; /* this is the number of credits that the current pending TX - packet needs to transmit. This is set by HTC when - and endpoint needs credits in order to transmit */ - int TxCreditSize; /* size in bytes of each credit (set by HTC) */ - int TxCreditsPerMaxMsg; /* credits required for a maximum sized messages (set by HTC) */ - void *pHTCReserved; /* reserved for HTC use */ - int TxQueueDepth; /* current depth of TX queue , i.e. messages waiting for credits - This field is valid only when HTC_CREDIT_DIST_ACTIVITY_CHANGE - or HTC_CREDIT_DIST_SEND_COMPLETE is indicated on an endpoint - that has non-zero credits to recover - */ -}; - -#define HTC_EP_ACTIVE ((u32) (1u << 31)) - -/* macro to check if an endpoint has gone active, useful for credit - * distributions */ -#define IS_EP_ACTIVE(epDist) ((epDist)->DistFlags & HTC_EP_ACTIVE) -#define SET_EP_ACTIVE(epDist) (epDist)->DistFlags |= HTC_EP_ACTIVE - - /* credit distibution code that is passed into the distrbution function, - * there are mandatory and optional codes that must be handled */ -typedef enum _HTC_CREDIT_DIST_REASON { - HTC_CREDIT_DIST_SEND_COMPLETE = 0, /* credits available as a result of completed - send operations (MANDATORY) resulting in credit reports */ - HTC_CREDIT_DIST_ACTIVITY_CHANGE = 1, /* a change in endpoint activity occurred (OPTIONAL) */ - HTC_CREDIT_DIST_SEEK_CREDITS, /* an endpoint needs to "seek" credits (OPTIONAL) */ - HTC_DUMP_CREDIT_STATE /* for debugging, dump any state information that is kept by - the distribution function */ -} HTC_CREDIT_DIST_REASON; - -typedef void (*HTC_CREDIT_DIST_CALLBACK)(void *Context, - struct htc_endpoint_credit_dist *pEPList, - HTC_CREDIT_DIST_REASON Reason); - -typedef void (*HTC_CREDIT_INIT_CALLBACK)(void *Context, - struct htc_endpoint_credit_dist *pEPList, - int TotalCredits); - - /* endpoint statistics action */ -typedef enum _HTC_ENDPOINT_STAT_ACTION { - HTC_EP_STAT_SAMPLE = 0, /* only read statistics */ - HTC_EP_STAT_SAMPLE_AND_CLEAR = 1, /* sample and immediately clear statistics */ - HTC_EP_STAT_CLEAR /* clear only */ -} HTC_ENDPOINT_STAT_ACTION; - - /* endpoint statistics */ -struct htc_endpoint_stats { - u32 TxCreditLowIndications; /* number of times the host set the credit-low flag in a send message on - this endpoint */ - u32 TxIssued; /* running count of total TX packets issued */ - u32 TxPacketsBundled; /* running count of TX packets that were issued in bundles */ - u32 TxBundles; /* running count of TX bundles that were issued */ - u32 TxDropped; /* tx packets that were dropped */ - u32 TxCreditRpts; /* running count of total credit reports received for this endpoint */ - u32 TxCreditRptsFromRx; /* credit reports received from this endpoint's RX packets */ - u32 TxCreditRptsFromOther; /* credit reports received from RX packets of other endpoints */ - u32 TxCreditRptsFromEp0; /* credit reports received from endpoint 0 RX packets */ - u32 TxCreditsFromRx; /* count of credits received via Rx packets on this endpoint */ - u32 TxCreditsFromOther; /* count of credits received via another endpoint */ - u32 TxCreditsFromEp0; /* count of credits received via another endpoint */ - u32 TxCreditsConsummed; /* count of consummed credits */ - u32 TxCreditsReturned; /* count of credits returned */ - u32 RxReceived; /* count of RX packets received */ - u32 RxLookAheads; /* count of lookahead records - found in messages received on this endpoint */ - u32 RxPacketsBundled; /* count of recv packets received in a bundle */ - u32 RxBundleLookAheads; /* count of number of bundled lookaheads */ - u32 RxBundleIndFromHdr; /* count of the number of bundle indications from the HTC header */ - u32 RxAllocThreshHit; /* count of the number of times the recv allocation threshold was hit */ - u32 RxAllocThreshBytes; /* total number of bytes */ -}; - -/* ------ Function Prototypes ------ */ -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - @desc: Create an instance of HTC over the underlying HIF device - @function name: HTCCreate - @input: HifDevice - hif device handle, - pInfo - initialization information - @output: - @return: HTC_HANDLE on success, NULL on failure - @notes: - @example: - @see also: HTCDestroy -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -HTC_HANDLE HTCCreate(void *HifDevice, struct htc_init_info *pInfo); -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - @desc: Get the underlying HIF device handle - @function name: HTCGetHifDevice - @input: HTCHandle - handle passed into the AddInstance callback - @output: - @return: opaque HIF device handle usable in HIF API calls. - @notes: - @example: - @see also: -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -void *HTCGetHifDevice(HTC_HANDLE HTCHandle); -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - @desc: Set credit distribution parameters - @function name: HTCSetCreditDistribution - @input: HTCHandle - HTC handle - pCreditDistCont - caller supplied context to pass into distribution functions - CreditDistFunc - Distribution function callback - CreditDistInit - Credit Distribution initialization callback - ServicePriorityOrder - Array containing list of service IDs, lowest index is highest - priority - ListLength - number of elements in ServicePriorityOrder - @output: - @return: - @notes: The user can set a custom credit distribution function to handle special requirements - for each endpoint. A default credit distribution routine can be used by setting - CreditInitFunc to NULL. The default credit distribution is only provided for simple - "fair" credit distribution without regard to any prioritization. - - @example: - @see also: -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -void HTCSetCreditDistribution(HTC_HANDLE HTCHandle, - void *pCreditDistContext, - HTC_CREDIT_DIST_CALLBACK CreditDistFunc, - HTC_CREDIT_INIT_CALLBACK CreditInitFunc, - HTC_SERVICE_ID ServicePriorityOrder[], - int ListLength); -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - @desc: Wait for the target to indicate the HTC layer is ready - @function name: HTCWaitTarget - @input: HTCHandle - HTC handle - @output: - @return: - @notes: This API blocks until the target responds with an HTC ready message. - The caller should not connect services until the target has indicated it is - ready. - @example: - @see also: HTCConnectService -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -int HTCWaitTarget(HTC_HANDLE HTCHandle); -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - @desc: Start target service communications - @function name: HTCStart - @input: HTCHandle - HTC handle - @output: - @return: - @notes: This API indicates to the target that the service connection phase is complete - and the target can freely start all connected services. This API should only be - called AFTER all service connections have been made. TCStart will issue a - SETUP_COMPLETE message to the target to indicate that all service connections - have been made and the target can start communicating over the endpoints. - @example: - @see also: HTCConnectService -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -int HTCStart(HTC_HANDLE HTCHandle); -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - @desc: Add receive packet to HTC - @function name: HTCAddReceivePkt - @input: HTCHandle - HTC handle - pPacket - HTC receive packet to add - @output: - @return: 0 on success - @notes: user must supply HTC packets for capturing incomming HTC frames. The caller - must initialize each HTC packet using the SET_HTC_PACKET_INFO_RX_REFILL() - macro. - @example: - @see also: -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -int HTCAddReceivePkt(HTC_HANDLE HTCHandle, struct htc_packet *pPacket); -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - @desc: Connect to an HTC service - @function name: HTCConnectService - @input: HTCHandle - HTC handle - pReq - connection details - @output: pResp - connection response - @return: - @notes: Service connections must be performed before HTCStart. User provides callback handlers - for various endpoint events. - @example: - @see also: HTCStart -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -int HTCConnectService(HTC_HANDLE HTCHandle, - struct htc_service_connect_req *pReq, - struct htc_service_connect_resp *pResp); -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - @desc: Send an HTC packet - @function name: HTCSendPkt - @input: HTCHandle - HTC handle - pPacket - packet to send - @output: - @return: 0 - @notes: Caller must initialize packet using SET_HTC_PACKET_INFO_TX() macro. - This interface is fully asynchronous. On error, HTC SendPkt will - call the registered Endpoint callback to cleanup the packet. - @example: - @see also: HTCFlushEndpoint -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -int HTCSendPkt(HTC_HANDLE HTCHandle, struct htc_packet *pPacket); -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - @desc: Stop HTC service communications - @function name: HTCStop - @input: HTCHandle - HTC handle - @output: - @return: - @notes: HTC communications is halted. All receive and pending TX packets will - be flushed. - @example: - @see also: -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -void HTCStop(HTC_HANDLE HTCHandle); -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - @desc: Destroy HTC service - @function name: HTCDestroy - @input: HTCHandle - @output: - @return: - @notes: This cleans up all resources allocated by HTCCreate(). - @example: - @see also: HTCCreate -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -void HTCDestroy(HTC_HANDLE HTCHandle); -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - @desc: Flush pending TX packets - @function name: HTCFlushEndpoint - @input: HTCHandle - HTC handle - Endpoint - Endpoint to flush - Tag - flush tag - @output: - @return: - @notes: The Tag parameter is used to selectively flush packets with matching tags. - The value of 0 forces all packets to be flush regardless of tag. - @example: - @see also: HTCSendPkt -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -void HTCFlushEndpoint(HTC_HANDLE HTCHandle, HTC_ENDPOINT_ID Endpoint, HTC_TX_TAG Tag); -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - @desc: Dump credit distribution state - @function name: HTCDumpCreditStates - @input: HTCHandle - HTC handle - @output: - @return: - @notes: This dumps all credit distribution information to the debugger - @example: - @see also: -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -void HTCDumpCreditStates(HTC_HANDLE HTCHandle); -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - @desc: Indicate a traffic activity change on an endpoint - @function name: HTCIndicateActivityChange - @input: HTCHandle - HTC handle - Endpoint - endpoint in which activity has changed - Active - true if active, false if it has become inactive - @output: - @return: - @notes: This triggers the registered credit distribution function to - re-adjust credits for active/inactive endpoints. - @example: - @see also: -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -void HTCIndicateActivityChange(HTC_HANDLE HTCHandle, - HTC_ENDPOINT_ID Endpoint, - bool Active); - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - @desc: Get endpoint statistics - @function name: HTCGetEndpointStatistics - @input: HTCHandle - HTC handle - Endpoint - Endpoint identifier - Action - action to take with statistics - @output: - pStats - statistics that were sampled (can be NULL if Action is HTC_EP_STAT_CLEAR) - - @return: true if statistics profiling is enabled, otherwise false. - - @notes: Statistics is a compile-time option and this function may return false - if HTC is not compiled with profiling. - - The caller can specify the statistic "action" to take when sampling - the statistics. This includes: - - HTC_EP_STAT_SAMPLE: The pStats structure is filled with the current values. - HTC_EP_STAT_SAMPLE_AND_CLEAR: The structure is filled and the current statistics - are cleared. - HTC_EP_STAT_CLEA : the statistics are cleared, the called can pass a NULL value for - pStats - - @example: - @see also: -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -bool HTCGetEndpointStatistics(HTC_HANDLE HTCHandle, - HTC_ENDPOINT_ID Endpoint, - HTC_ENDPOINT_STAT_ACTION Action, - struct htc_endpoint_stats *pStats); - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - @desc: Unblock HTC message reception - @function name: HTCUnblockRecv - @input: HTCHandle - HTC handle - @output: - @return: - @notes: - HTC will block the receiver if the EpRecvAlloc callback fails to provide a packet. - The caller can use this API to indicate to HTC when resources (buffers) are available - such that the receiver can be unblocked and HTC may re-attempt fetching the pending message. - - This API is not required if the user uses the EpRecvRefill callback or uses the HTCAddReceivePacket() - API to recycle or provide receive packets to HTC. - - @example: - @see also: -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -void HTCUnblockRecv(HTC_HANDLE HTCHandle); - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - @desc: send a series of HTC packets - @function name: HTCSendPktsMultiple - @input: HTCHandle - HTC handle - pPktQueue - local queue holding packets to send - @output: - @return: 0 - @notes: Caller must initialize each packet using SET_HTC_PACKET_INFO_TX() macro. - The queue must only contain packets directed at the same endpoint. - Caller supplies a pointer to an struct htc_packet_queue structure holding the TX packets in FIFO order. - This API will remove the packets from the pkt queue and place them into the HTC Tx Queue - and bundle messages where possible. - The caller may allocate the pkt queue on the stack to hold the packets. - This interface is fully asynchronous. On error, HTCSendPkts will - call the registered Endpoint callback to cleanup the packet. - @example: - @see also: HTCFlushEndpoint -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -int HTCSendPktsMultiple(HTC_HANDLE HTCHandle, struct htc_packet_queue *pPktQueue); - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - @desc: Add multiple receive packets to HTC - @function name: HTCAddReceivePktMultiple - @input: HTCHandle - HTC handle - pPktQueue - HTC receive packet queue holding packets to add - @output: - @return: 0 on success - @notes: user must supply HTC packets for capturing incomming HTC frames. The caller - must initialize each HTC packet using the SET_HTC_PACKET_INFO_RX_REFILL() - macro. The queue must only contain recv packets for the same endpoint. - Caller supplies a pointer to an struct htc_packet_queue structure holding the recv packet. - This API will remove the packets from the pkt queue and place them into internal - recv packet list. - The caller may allocate the pkt queue on the stack to hold the packets. - @example: - @see also: -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -int HTCAddReceivePktMultiple(HTC_HANDLE HTCHandle, struct htc_packet_queue *pPktQueue); - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - @desc: Check if an endpoint is marked active - @function name: HTCIsEndpointActive - @input: HTCHandle - HTC handle - Endpoint - endpoint to check for active state - @output: - @return: returns true if Endpoint is Active - @notes: - @example: - @see also: -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -bool HTCIsEndpointActive(HTC_HANDLE HTCHandle, - HTC_ENDPOINT_ID Endpoint); - - -/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - @desc: Get the number of recv buffers currently queued into an HTC endpoint - @function name: HTCGetNumRecvBuffers - @input: HTCHandle - HTC handle - Endpoint - endpoint to check - @output: - @return: returns number of buffers in queue - @notes: - @example: - @see also: -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/ -int HTCGetNumRecvBuffers(HTC_HANDLE HTCHandle, - HTC_ENDPOINT_ID Endpoint); - -/* internally used functions for testing... */ -void HTCEnableRecv(HTC_HANDLE HTCHandle); -void HTCDisableRecv(HTC_HANDLE HTCHandle); -int HTCWaitForPendingRecv(HTC_HANDLE HTCHandle, - u32 TimeoutInMs, - bool *pbIsRecvPending); - -#ifdef __cplusplus -} -#endif - -#endif /* _HTC_API_H_ */ diff --git a/drivers/staging/ath6kl/include/htc_packet.h b/drivers/staging/ath6kl/include/htc_packet.h deleted file mode 100644 index ba65c34..0000000 --- a/drivers/staging/ath6kl/include/htc_packet.h +++ /dev/null @@ -1,227 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="htc_packet.h" company="Atheros"> -// Copyright (c) 2007-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Author(s): ="Atheros" -//============================================================================== -#ifndef HTC_PACKET_H_ -#define HTC_PACKET_H_ - - -#include "dl_list.h" - -/* ------ Endpoint IDS ------ */ -typedef enum -{ - ENDPOINT_UNUSED = -1, - ENDPOINT_0 = 0, - ENDPOINT_1 = 1, - ENDPOINT_2 = 2, - ENDPOINT_3, - ENDPOINT_4, - ENDPOINT_5, - ENDPOINT_6, - ENDPOINT_7, - ENDPOINT_8, - ENDPOINT_MAX, -} HTC_ENDPOINT_ID; - -struct htc_packet; - -typedef void (* HTC_PACKET_COMPLETION)(void *,struct htc_packet *); - -typedef u16 HTC_TX_TAG; - -struct htc_tx_packet_info { - HTC_TX_TAG Tag; /* tag used to selective flush packets */ - int CreditsUsed; /* number of credits used for this TX packet (HTC internal) */ - u8 SendFlags; /* send flags (HTC internal) */ - int SeqNo; /* internal seq no for debugging (HTC internal) */ -}; - -#define HTC_TX_PACKET_TAG_ALL 0 /* a tag of zero is reserved and used to flush ALL packets */ -#define HTC_TX_PACKET_TAG_INTERNAL 1 /* internal tags start here */ -#define HTC_TX_PACKET_TAG_USER_DEFINED (HTC_TX_PACKET_TAG_INTERNAL + 9) /* user-defined tags start here */ - -struct htc_rx_packet_info { - u32 ExpectedHdr; /* HTC internal use */ - u32 HTCRxFlags; /* HTC internal use */ - u32 IndicationFlags; /* indication flags set on each RX packet indication */ -}; - -#define HTC_RX_FLAGS_INDICATE_MORE_PKTS (1 << 0) /* more packets on this endpoint are being fetched */ - -/* wrapper around endpoint-specific packets */ -struct htc_packet { - struct dl_list ListLink; /* double link */ - void *pPktContext; /* caller's per packet specific context */ - - u8 *pBufferStart; /* the true buffer start , the caller can - store the real buffer start here. In - receive callbacks, the HTC layer sets pBuffer - to the start of the payload past the header. This - field allows the caller to reset pBuffer when it - recycles receive packets back to HTC */ - /* - * Pointer to the start of the buffer. In the transmit - * direction this points to the start of the payload. In the - * receive direction, however, the buffer when queued up - * points to the start of the HTC header but when returned - * to the caller points to the start of the payload - */ - u8 *pBuffer; /* payload start (RX/TX) */ - u32 BufferLength; /* length of buffer */ - u32 ActualLength; /* actual length of payload */ - HTC_ENDPOINT_ID Endpoint; /* endpoint that this packet was sent/recv'd from */ - int Status; /* completion status */ - union { - struct htc_tx_packet_info AsTx; /* Tx Packet specific info */ - struct htc_rx_packet_info AsRx; /* Rx Packet specific info */ - } PktInfo; - - /* the following fields are for internal HTC use */ - HTC_PACKET_COMPLETION Completion; /* completion */ - void *pContext; /* HTC private completion context */ -}; - - - -#define COMPLETE_HTC_PACKET(p,status) \ -{ \ - (p)->Status = (status); \ - (p)->Completion((p)->pContext,(p)); \ -} - -#define INIT_HTC_PACKET_INFO(p,b,len) \ -{ \ - (p)->pBufferStart = (b); \ - (p)->BufferLength = (len); \ -} - -/* macro to set an initial RX packet for refilling HTC */ -#define SET_HTC_PACKET_INFO_RX_REFILL(p,c,b,len,ep) \ -{ \ - (p)->pPktContext = (c); \ - (p)->pBuffer = (b); \ - (p)->pBufferStart = (b); \ - (p)->BufferLength = (len); \ - (p)->Endpoint = (ep); \ -} - -/* fast macro to recycle an RX packet that will be re-queued to HTC */ -#define HTC_PACKET_RESET_RX(p) \ - { (p)->pBuffer = (p)->pBufferStart; (p)->ActualLength = 0; } - -/* macro to set packet parameters for TX */ -#define SET_HTC_PACKET_INFO_TX(p,c,b,len,ep,tag) \ -{ \ - (p)->pPktContext = (c); \ - (p)->pBuffer = (b); \ - (p)->ActualLength = (len); \ - (p)->Endpoint = (ep); \ - (p)->PktInfo.AsTx.Tag = (tag); \ -} - -/* HTC Packet Queueing Macros */ -struct htc_packet_queue { - struct dl_list QueueHead; - int Depth; -}; - -/* initialize queue */ -#define INIT_HTC_PACKET_QUEUE(pQ) \ -{ \ - DL_LIST_INIT(&(pQ)->QueueHead); \ - (pQ)->Depth = 0; \ -} - -/* enqueue HTC packet to the tail of the queue */ -#define HTC_PACKET_ENQUEUE(pQ,p) \ -{ DL_ListInsertTail(&(pQ)->QueueHead,&(p)->ListLink); \ - (pQ)->Depth++; \ -} - -/* enqueue HTC packet to the tail of the queue */ -#define HTC_PACKET_ENQUEUE_TO_HEAD(pQ,p) \ -{ DL_ListInsertHead(&(pQ)->QueueHead,&(p)->ListLink); \ - (pQ)->Depth++; \ -} -/* test if a queue is empty */ -#define HTC_QUEUE_EMPTY(pQ) ((pQ)->Depth == 0) -/* get packet at head without removing it */ -static INLINE struct htc_packet *HTC_GET_PKT_AT_HEAD(struct htc_packet_queue *queue) { - if (queue->Depth == 0) { - return NULL; - } - return A_CONTAINING_STRUCT((DL_LIST_GET_ITEM_AT_HEAD(&queue->QueueHead)),struct htc_packet,ListLink); -} -/* remove a packet from a queue, where-ever it is in the queue */ -#define HTC_PACKET_REMOVE(pQ,p) \ -{ \ - DL_ListRemove(&(p)->ListLink); \ - (pQ)->Depth--; \ -} - -/* dequeue an HTC packet from the head of the queue */ -static INLINE struct htc_packet *HTC_PACKET_DEQUEUE(struct htc_packet_queue *queue) { - struct dl_list *pItem = DL_ListRemoveItemFromHead(&queue->QueueHead); - if (pItem != NULL) { - queue->Depth--; - return A_CONTAINING_STRUCT(pItem, struct htc_packet, ListLink); - } - return NULL; -} - -/* dequeue an HTC packet from the tail of the queue */ -static INLINE struct htc_packet *HTC_PACKET_DEQUEUE_TAIL(struct htc_packet_queue *queue) { - struct dl_list *pItem = DL_ListRemoveItemFromTail(&queue->QueueHead); - if (pItem != NULL) { - queue->Depth--; - return A_CONTAINING_STRUCT(pItem, struct htc_packet, ListLink); - } - return NULL; -} - -#define HTC_PACKET_QUEUE_DEPTH(pQ) (pQ)->Depth - - -#define HTC_GET_ENDPOINT_FROM_PKT(p) (p)->Endpoint -#define HTC_GET_TAG_FROM_PKT(p) (p)->PktInfo.AsTx.Tag - - /* transfer the packets from one queue to the tail of another queue */ -#define HTC_PACKET_QUEUE_TRANSFER_TO_TAIL(pQDest,pQSrc) \ -{ \ - DL_ListTransferItemsToTail(&(pQDest)->QueueHead,&(pQSrc)->QueueHead); \ - (pQDest)->Depth += (pQSrc)->Depth; \ - (pQSrc)->Depth = 0; \ -} - - /* fast version to init and add a single packet to a queue */ -#define INIT_HTC_PACKET_QUEUE_AND_ADD(pQ,pP) \ -{ \ - DL_LIST_INIT_AND_ADD(&(pQ)->QueueHead,&(pP)->ListLink) \ - (pQ)->Depth = 1; \ -} - -#define HTC_PACKET_QUEUE_ITERATE_ALLOW_REMOVE(pQ, pPTemp) \ - ITERATE_OVER_LIST_ALLOW_REMOVE(&(pQ)->QueueHead,(pPTemp), struct htc_packet, ListLink) - -#define HTC_PACKET_QUEUE_ITERATE_END ITERATE_END - -#endif /*HTC_PACKET_H_*/ diff --git a/drivers/staging/ath6kl/include/wlan_api.h b/drivers/staging/ath6kl/include/wlan_api.h deleted file mode 100644 index 9eea587..0000000 --- a/drivers/staging/ath6kl/include/wlan_api.h +++ /dev/null @@ -1,128 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// Permission to use, copy, modify, and/or distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// This file contains the API for the host wlan module -// -// Author(s): ="Atheros" -//============================================================================== -#ifndef _HOST_WLAN_API_H_ -#define _HOST_WLAN_API_H_ - - -#ifdef __cplusplus -extern "C" { -#endif - -#include <a_osapi.h> - -struct ieee80211_node_table; -struct ieee80211_frame; - -struct ieee80211_common_ie { - u16 ie_chan; - u8 *ie_tstamp; - u8 *ie_ssid; - u8 *ie_rates; - u8 *ie_xrates; - u8 *ie_country; - u8 *ie_wpa; - u8 *ie_rsn; - u8 *ie_wmm; - u8 *ie_ath; - u16 ie_capInfo; - u16 ie_beaconInt; - u8 *ie_tim; - u8 *ie_chswitch; - u8 ie_erp; - u8 *ie_wsc; - u8 *ie_htcap; - u8 *ie_htop; -#ifdef WAPI_ENABLE - u8 *ie_wapi; -#endif -}; - -typedef struct bss { - u8 ni_macaddr[6]; - u8 ni_snr; - s16 ni_rssi; - struct bss *ni_list_next; - struct bss *ni_list_prev; - struct bss *ni_hash_next; - struct bss *ni_hash_prev; - struct ieee80211_common_ie ni_cie; - u8 *ni_buf; - u16 ni_framelen; - struct ieee80211_node_table *ni_table; - u32 ni_refcnt; - int ni_scangen; - - u32 ni_tstamp; - u32 ni_actcnt; -#ifdef OS_ROAM_MANAGEMENT - u32 ni_si_gen; -#endif -} bss_t; - -typedef void wlan_node_iter_func(void *arg, bss_t *); - -bss_t *wlan_node_alloc(struct ieee80211_node_table *nt, int wh_size); -void wlan_node_free(bss_t *ni); -void wlan_setup_node(struct ieee80211_node_table *nt, bss_t *ni, - const u8 *macaddr); -bss_t *wlan_find_node(struct ieee80211_node_table *nt, const u8 *macaddr); -void wlan_node_reclaim(struct ieee80211_node_table *nt, bss_t *ni); -void wlan_free_allnodes(struct ieee80211_node_table *nt); -void wlan_iterate_nodes(struct ieee80211_node_table *nt, wlan_node_iter_func *f, - void *arg); - -void wlan_node_table_init(void *wmip, struct ieee80211_node_table *nt); -void wlan_node_table_reset(struct ieee80211_node_table *nt); -void wlan_node_table_cleanup(struct ieee80211_node_table *nt); - -int wlan_parse_beacon(u8 *buf, int framelen, - struct ieee80211_common_ie *cie); - -u16 wlan_ieee2freq(int chan); -u32 wlan_freq2ieee(u16 freq); - -void wlan_set_nodeage(struct ieee80211_node_table *nt, u32 nodeAge); - -void -wlan_refresh_inactive_nodes (struct ieee80211_node_table *nt); - -bss_t * -wlan_find_Ssidnode (struct ieee80211_node_table *nt, u8 *pSsid, - u32 ssidLength, bool bIsWPA2, bool bMatchSSID); - -void -wlan_node_return (struct ieee80211_node_table *nt, bss_t *ni); - -bss_t *wlan_node_remove(struct ieee80211_node_table *nt, u8 *bssid); - -bss_t * -wlan_find_matching_Ssidnode (struct ieee80211_node_table *nt, u8 *pSsid, - u32 ssidLength, u32 dot11AuthMode, u32 authMode, - u32 pairwiseCryptoType, u32 grpwiseCryptoTyp); - -#ifdef __cplusplus -} -#endif - -#endif /* _HOST_WLAN_API_H_ */ diff --git a/drivers/staging/ath6kl/include/wmi_api.h b/drivers/staging/ath6kl/include/wmi_api.h deleted file mode 100644 index c8583e0..0000000 --- a/drivers/staging/ath6kl/include/wmi_api.h +++ /dev/null @@ -1,441 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="wmi_api.h" company="Atheros"> -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// Permission to use, copy, modify, and/or distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// This file contains the definitions for the Wireless Module Interface (WMI). -// -// Author(s): ="Atheros" -//============================================================================== -#ifndef _WMI_API_H_ -#define _WMI_API_H_ - -#ifdef __cplusplus -extern "C" { -#endif - - /* WMI converts a dix frame with an ethernet payload (up to 1500 bytes) - * to an 802.3 frame (adds SNAP header) and adds on a WMI data header */ -#define WMI_MAX_TX_DATA_FRAME_LENGTH (1500 + sizeof(WMI_DATA_HDR) + sizeof(ATH_MAC_HDR) + sizeof(ATH_LLC_SNAP_HDR)) - - /* A normal WMI data frame */ -#define WMI_MAX_NORMAL_RX_DATA_FRAME_LENGTH (1500 + sizeof(WMI_DATA_HDR) + sizeof(ATH_MAC_HDR) + sizeof(ATH_LLC_SNAP_HDR)) - - /* An AMSDU frame */ /* The MAX AMSDU length of AR6003 is 3839 */ -#define WMI_MAX_AMSDU_RX_DATA_FRAME_LENGTH (3840 + sizeof(WMI_DATA_HDR) + sizeof(ATH_MAC_HDR) + sizeof(ATH_LLC_SNAP_HDR)) - -/* - * IP QoS Field definitions according to 802.1p - */ -#define BEST_EFFORT_PRI 0 -#define BACKGROUND_PRI 1 -#define EXCELLENT_EFFORT_PRI 3 -#define CONTROLLED_LOAD_PRI 4 -#define VIDEO_PRI 5 -#define VOICE_PRI 6 -#define NETWORK_CONTROL_PRI 7 -#define MAX_NUM_PRI 8 - -#define UNDEFINED_PRI (0xff) - -#define WMI_IMPLICIT_PSTREAM_INACTIVITY_INT 5000 /* 5 seconds */ - -#define A_ROUND_UP(x, y) ((((x) + ((y) - 1)) / (y)) * (y)) - -typedef enum { - ATHEROS_COMPLIANCE = 0x1, -}TSPEC_PARAM_COMPLIANCE; - -struct wmi_t; - -void *wmi_init(void *devt); - -void wmi_qos_state_init(struct wmi_t *wmip); -void wmi_shutdown(struct wmi_t *wmip); -HTC_ENDPOINT_ID wmi_get_control_ep(struct wmi_t * wmip); -void wmi_set_control_ep(struct wmi_t * wmip, HTC_ENDPOINT_ID eid); -u16 wmi_get_mapped_qos_queue(struct wmi_t *, u8 ); -int wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf); -int wmi_data_hdr_add(struct wmi_t *wmip, void *osbuf, u8 msgType, bool bMoreData, WMI_DATA_HDR_DATA_TYPE data_type,u8 metaVersion, void *pTxMetaS); -int wmi_dot3_2_dix(void *osbuf); - -int wmi_dot11_hdr_remove (struct wmi_t *wmip, void *osbuf); -int wmi_dot11_hdr_add(struct wmi_t *wmip, void *osbuf, NETWORK_TYPE mode); - -int wmi_data_hdr_remove(struct wmi_t *wmip, void *osbuf); -int wmi_syncpoint(struct wmi_t *wmip); -int wmi_syncpoint_reset(struct wmi_t *wmip); -u8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, u32 layer2Priority, bool wmmEnabled); - -u8 wmi_determine_userPriority (u8 *pkt, u32 layer2Pri); - -int wmi_control_rx(struct wmi_t *wmip, void *osbuf); -void wmi_iterate_nodes(struct wmi_t *wmip, wlan_node_iter_func *f, void *arg); -void wmi_free_allnodes(struct wmi_t *wmip); -bss_t *wmi_find_node(struct wmi_t *wmip, const u8 *macaddr); -void wmi_free_node(struct wmi_t *wmip, const u8 *macaddr); - - -typedef enum { - NO_SYNC_WMIFLAG = 0, - SYNC_BEFORE_WMIFLAG, /* transmit all queued data before cmd */ - SYNC_AFTER_WMIFLAG, /* any new data waits until cmd execs */ - SYNC_BOTH_WMIFLAG, - END_WMIFLAG /* end marker */ -} WMI_SYNC_FLAG; - -int wmi_cmd_send(struct wmi_t *wmip, void *osbuf, WMI_COMMAND_ID cmdId, - WMI_SYNC_FLAG flag); - -int wmi_connect_cmd(struct wmi_t *wmip, - NETWORK_TYPE netType, - DOT11_AUTH_MODE dot11AuthMode, - AUTH_MODE authMode, - CRYPTO_TYPE pairwiseCrypto, - u8 pairwiseCryptoLen, - CRYPTO_TYPE groupCrypto, - u8 groupCryptoLen, - int ssidLength, - u8 *ssid, - u8 *bssid, - u16 channel, - u32 ctrl_flags); - -int wmi_reconnect_cmd(struct wmi_t *wmip, - u8 *bssid, - u16 channel); -int wmi_disconnect_cmd(struct wmi_t *wmip); -int wmi_getrev_cmd(struct wmi_t *wmip); -int wmi_startscan_cmd(struct wmi_t *wmip, WMI_SCAN_TYPE scanType, - u32 forceFgScan, u32 isLegacy, - u32 homeDwellTime, u32 forceScanInterval, - s8 numChan, u16 *channelList); -int wmi_scanparams_cmd(struct wmi_t *wmip, u16 fg_start_sec, - u16 fg_end_sec, u16 bg_sec, - u16 minact_chdw_msec, - u16 maxact_chdw_msec, u16 pas_chdw_msec, - u8 shScanRatio, u8 scanCtrlFlags, - u32 max_dfsch_act_time, - u16 maxact_scan_per_ssid); -int wmi_bssfilter_cmd(struct wmi_t *wmip, u8 filter, u32 ieMask); -int wmi_probedSsid_cmd(struct wmi_t *wmip, u8 index, u8 flag, - u8 ssidLength, u8 *ssid); -int wmi_listeninterval_cmd(struct wmi_t *wmip, u16 listenInterval, u16 listenBeacons); -int wmi_bmisstime_cmd(struct wmi_t *wmip, u16 bmisstime, u16 bmissbeacons); -int wmi_associnfo_cmd(struct wmi_t *wmip, u8 ieType, - u8 ieLen, u8 *ieInfo); -int wmi_powermode_cmd(struct wmi_t *wmip, u8 powerMode); -int wmi_ibsspmcaps_cmd(struct wmi_t *wmip, u8 pmEnable, u8 ttl, - u16 atim_windows, u16 timeout_value); -int wmi_apps_cmd(struct wmi_t *wmip, u8 psType, u32 idle_time, - u32 ps_period, u8 sleep_period); -int wmi_pmparams_cmd(struct wmi_t *wmip, u16 idlePeriod, - u16 psPollNum, u16 dtimPolicy, - u16 wakup_tx_policy, u16 num_tx_to_wakeup, - u16 ps_fail_event_policy); -int wmi_disctimeout_cmd(struct wmi_t *wmip, u8 timeout); -int wmi_sync_cmd(struct wmi_t *wmip, u8 syncNumber); -int wmi_create_pstream_cmd(struct wmi_t *wmip, WMI_CREATE_PSTREAM_CMD *pstream); -int wmi_delete_pstream_cmd(struct wmi_t *wmip, u8 trafficClass, u8 streamID); -int wmi_set_framerate_cmd(struct wmi_t *wmip, u8 bEnable, u8 type, u8 subType, u16 rateMask); -int wmi_set_bitrate_cmd(struct wmi_t *wmip, s32 dataRate, s32 mgmtRate, s32 ctlRate); -int wmi_get_bitrate_cmd(struct wmi_t *wmip); -s8 wmi_validate_bitrate(struct wmi_t *wmip, s32 rate, s8 *rate_idx); -int wmi_get_regDomain_cmd(struct wmi_t *wmip); -int wmi_get_channelList_cmd(struct wmi_t *wmip); -int wmi_set_channelParams_cmd(struct wmi_t *wmip, u8 scanParam, - WMI_PHY_MODE mode, s8 numChan, - u16 *channelList); - -int wmi_set_snr_threshold_params(struct wmi_t *wmip, - WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd); -int wmi_set_rssi_threshold_params(struct wmi_t *wmip, - WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd); -int wmi_clr_rssi_snr(struct wmi_t *wmip); -int wmi_set_lq_threshold_params(struct wmi_t *wmip, - WMI_LQ_THRESHOLD_PARAMS_CMD *lqCmd); -int wmi_set_rts_cmd(struct wmi_t *wmip, u16 threshold); -int wmi_set_lpreamble_cmd(struct wmi_t *wmip, u8 status, u8 preamblePolicy); - -int wmi_set_error_report_bitmask(struct wmi_t *wmip, u32 bitmask); - -int wmi_get_challenge_resp_cmd(struct wmi_t *wmip, u32 cookie, - u32 source); - -int wmi_config_debug_module_cmd(struct wmi_t *wmip, u16 mmask, - u16 tsr, bool rep, u16 size, - u32 valid); - -int wmi_get_stats_cmd(struct wmi_t *wmip); - -int wmi_addKey_cmd(struct wmi_t *wmip, u8 keyIndex, - CRYPTO_TYPE keyType, u8 keyUsage, - u8 keyLength,u8 *keyRSC, - u8 *keyMaterial, u8 key_op_ctrl, u8 *mac, - WMI_SYNC_FLAG sync_flag); -int wmi_add_krk_cmd(struct wmi_t *wmip, u8 *krk); -int wmi_delete_krk_cmd(struct wmi_t *wmip); -int wmi_deleteKey_cmd(struct wmi_t *wmip, u8 keyIndex); -int wmi_set_akmp_params_cmd(struct wmi_t *wmip, - WMI_SET_AKMP_PARAMS_CMD *akmpParams); -int wmi_get_pmkid_list_cmd(struct wmi_t *wmip); -int wmi_set_pmkid_list_cmd(struct wmi_t *wmip, - WMI_SET_PMKID_LIST_CMD *pmkInfo); -int wmi_abort_scan_cmd(struct wmi_t *wmip); -int wmi_set_txPwr_cmd(struct wmi_t *wmip, u8 dbM); -int wmi_get_txPwr_cmd(struct wmi_t *wmip); -int wmi_addBadAp_cmd(struct wmi_t *wmip, u8 apIndex, u8 *bssid); -int wmi_deleteBadAp_cmd(struct wmi_t *wmip, u8 apIndex); -int wmi_set_tkip_countermeasures_cmd(struct wmi_t *wmip, bool en); -int wmi_setPmkid_cmd(struct wmi_t *wmip, u8 *bssid, u8 *pmkId, - bool set); -int wmi_set_access_params_cmd(struct wmi_t *wmip, u8 ac, u16 txop, - u8 eCWmin, u8 eCWmax, - u8 aifsn); -int wmi_set_retry_limits_cmd(struct wmi_t *wmip, u8 frameType, - u8 trafficClass, u8 maxRetries, - u8 enableNotify); - -void wmi_get_current_bssid(struct wmi_t *wmip, u8 *bssid); - -int wmi_get_roam_tbl_cmd(struct wmi_t *wmip); -int wmi_get_roam_data_cmd(struct wmi_t *wmip, u8 roamDataType); -int wmi_set_roam_ctrl_cmd(struct wmi_t *wmip, WMI_SET_ROAM_CTRL_CMD *p, - u8 size); -int wmi_set_powersave_timers_cmd(struct wmi_t *wmip, - WMI_POWERSAVE_TIMERS_POLICY_CMD *pCmd, - u8 size); - -int wmi_set_opt_mode_cmd(struct wmi_t *wmip, u8 optMode); -int wmi_opt_tx_frame_cmd(struct wmi_t *wmip, - u8 frmType, - u8 *dstMacAddr, - u8 *bssid, - u16 optIEDataLen, - u8 *optIEData); - -int wmi_set_adhoc_bconIntvl_cmd(struct wmi_t *wmip, u16 intvl); -int wmi_set_voice_pkt_size_cmd(struct wmi_t *wmip, u16 voicePktSize); -int wmi_set_max_sp_len_cmd(struct wmi_t *wmip, u8 maxSpLen); -u8 convert_userPriority_to_trafficClass(u8 userPriority); -u8 wmi_get_power_mode_cmd(struct wmi_t *wmip); -int wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, int tspecCompliance); - -#ifdef CONFIG_HOST_TCMD_SUPPORT -int wmi_test_cmd(struct wmi_t *wmip, u8 *buf, u32 len); -#endif - -int wmi_set_bt_status_cmd(struct wmi_t *wmip, u8 streamType, u8 status); -int wmi_set_bt_params_cmd(struct wmi_t *wmip, WMI_SET_BT_PARAMS_CMD* cmd); - -int wmi_set_btcoex_fe_ant_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_FE_ANT_CMD * cmd); - -int wmi_set_btcoex_colocated_bt_dev_cmd(struct wmi_t *wmip, - WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD * cmd); - -int wmi_set_btcoex_btinquiry_page_config_cmd(struct wmi_t *wmip, - WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD *cmd); - -int wmi_set_btcoex_sco_config_cmd(struct wmi_t *wmip, - WMI_SET_BTCOEX_SCO_CONFIG_CMD * cmd); - -int wmi_set_btcoex_a2dp_config_cmd(struct wmi_t *wmip, - WMI_SET_BTCOEX_A2DP_CONFIG_CMD* cmd); - - -int wmi_set_btcoex_aclcoex_config_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD* cmd); - -int wmi_set_btcoex_debug_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_DEBUG_CMD * cmd); - -int wmi_set_btcoex_bt_operating_status_cmd(struct wmi_t * wmip, - WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD * cmd); - -int wmi_get_btcoex_config_cmd(struct wmi_t * wmip, WMI_GET_BTCOEX_CONFIG_CMD * cmd); - -int wmi_get_btcoex_stats_cmd(struct wmi_t * wmip); - -int wmi_SGI_cmd(struct wmi_t *wmip, u32 sgiMask, u8 sgiPERThreshold); - -/* - * This function is used to configure the fix rates mask to the target. - */ -int wmi_set_fixrates_cmd(struct wmi_t *wmip, u32 fixRatesMask); -int wmi_get_ratemask_cmd(struct wmi_t *wmip); - -int wmi_set_authmode_cmd(struct wmi_t *wmip, u8 mode); - -int wmi_set_reassocmode_cmd(struct wmi_t *wmip, u8 mode); - -int wmi_set_qos_supp_cmd(struct wmi_t *wmip,u8 status); -int wmi_set_wmm_cmd(struct wmi_t *wmip, WMI_WMM_STATUS status); -int wmi_set_wmm_txop(struct wmi_t *wmip, WMI_TXOP_CFG txEnable); -int wmi_set_country(struct wmi_t *wmip, u8 *countryCode); - -int wmi_get_keepalive_configured(struct wmi_t *wmip); -u8 wmi_get_keepalive_cmd(struct wmi_t *wmip); -int wmi_set_keepalive_cmd(struct wmi_t *wmip, u8 keepaliveInterval); - -int wmi_set_appie_cmd(struct wmi_t *wmip, u8 mgmtFrmType, - u8 ieLen,u8 *ieInfo); - -int wmi_set_halparam_cmd(struct wmi_t *wmip, u8 *cmd, u16 dataLen); - -s32 wmi_get_rate(s8 rateindex); - -int wmi_set_ip_cmd(struct wmi_t *wmip, WMI_SET_IP_CMD *cmd); - -/*Wake on Wireless WMI commands*/ -int wmi_set_host_sleep_mode_cmd(struct wmi_t *wmip, WMI_SET_HOST_SLEEP_MODE_CMD *cmd); -int wmi_set_wow_mode_cmd(struct wmi_t *wmip, WMI_SET_WOW_MODE_CMD *cmd); -int wmi_get_wow_list_cmd(struct wmi_t *wmip, WMI_GET_WOW_LIST_CMD *cmd); -int wmi_add_wow_pattern_cmd(struct wmi_t *wmip, - WMI_ADD_WOW_PATTERN_CMD *cmd, u8 *pattern, u8 *mask, u8 pattern_size); -int wmi_del_wow_pattern_cmd(struct wmi_t *wmip, - WMI_DEL_WOW_PATTERN_CMD *cmd); -int wmi_set_wsc_status_cmd(struct wmi_t *wmip, u32 status); - -int -wmi_set_params_cmd(struct wmi_t *wmip, u32 opcode, u32 length, char *buffer); - -int -wmi_set_mcast_filter_cmd(struct wmi_t *wmip, u8 dot1, u8 dot2, u8 dot3, u8 dot4); - -int -wmi_del_mcast_filter_cmd(struct wmi_t *wmip, u8 dot1, u8 dot2, u8 dot3, u8 dot4); - -int -wmi_mcast_filter_cmd(struct wmi_t *wmip, u8 enable); - -bss_t * -wmi_find_Ssidnode (struct wmi_t *wmip, u8 *pSsid, - u32 ssidLength, bool bIsWPA2, bool bMatchSSID); - - -void -wmi_node_return (struct wmi_t *wmip, bss_t *bss); - -void -wmi_set_nodeage(struct wmi_t *wmip, u32 nodeAge); - -#if defined(CONFIG_TARGET_PROFILE_SUPPORT) -int wmi_prof_cfg_cmd(struct wmi_t *wmip, u32 period, u32 nbins); -int wmi_prof_addr_set_cmd(struct wmi_t *wmip, u32 addr); -int wmi_prof_start_cmd(struct wmi_t *wmip); -int wmi_prof_stop_cmd(struct wmi_t *wmip); -int wmi_prof_count_get_cmd(struct wmi_t *wmip); -#endif /* CONFIG_TARGET_PROFILE_SUPPORT */ -#ifdef OS_ROAM_MANAGEMENT -void wmi_scan_indication (struct wmi_t *wmip); -#endif - -int -wmi_set_target_event_report_cmd(struct wmi_t *wmip, WMI_SET_TARGET_EVENT_REPORT_CMD* cmd); - -bss_t *wmi_rm_current_bss (struct wmi_t *wmip, u8 *id); -int wmi_add_current_bss (struct wmi_t *wmip, u8 *id, bss_t *bss); - - -/* - * AP mode - */ -int -wmi_ap_profile_commit(struct wmi_t *wmip, WMI_CONNECT_CMD *p); - -int -wmi_ap_set_hidden_ssid(struct wmi_t *wmip, u8 hidden_ssid); - -int -wmi_ap_set_num_sta(struct wmi_t *wmip, u8 num_sta); - -int -wmi_ap_set_acl_policy(struct wmi_t *wmip, u8 policy); - -int -wmi_ap_acl_mac_list(struct wmi_t *wmip, WMI_AP_ACL_MAC_CMD *a); - -u8 acl_add_del_mac(WMI_AP_ACL *a, WMI_AP_ACL_MAC_CMD *acl); - -int -wmi_ap_set_mlme(struct wmi_t *wmip, u8 cmd, u8 *mac, u16 reason); - -int -wmi_set_pvb_cmd(struct wmi_t *wmip, u16 aid, bool flag); - -int -wmi_ap_conn_inact_time(struct wmi_t *wmip, u32 period); - -int -wmi_ap_bgscan_time(struct wmi_t *wmip, u32 period, u32 dwell); - -int -wmi_ap_set_dtim(struct wmi_t *wmip, u8 dtim); - -int -wmi_ap_set_rateset(struct wmi_t *wmip, u8 rateset); - -int -wmi_set_ht_cap_cmd(struct wmi_t *wmip, WMI_SET_HT_CAP_CMD *cmd); - -int -wmi_set_ht_op_cmd(struct wmi_t *wmip, u8 sta_chan_width); - -int -wmi_send_hci_cmd(struct wmi_t *wmip, u8 *buf, u16 sz); - -int -wmi_set_tx_select_rates_cmd(struct wmi_t *wmip, u32 *pMaskArray); - -int -wmi_setup_aggr_cmd(struct wmi_t *wmip, u8 tid); - -int -wmi_delete_aggr_cmd(struct wmi_t *wmip, u8 tid, bool uplink); - -int -wmi_allow_aggr_cmd(struct wmi_t *wmip, u16 tx_tidmask, u16 rx_tidmask); - -int -wmi_set_rx_frame_format_cmd(struct wmi_t *wmip, u8 rxMetaVersion, bool rxDot11Hdr, bool defragOnHost); - -int -wmi_set_thin_mode_cmd(struct wmi_t *wmip, bool bThinMode); - -int -wmi_set_wlan_conn_precedence_cmd(struct wmi_t *wmip, BT_WLAN_CONN_PRECEDENCE precedence); - -int -wmi_set_pmk_cmd(struct wmi_t *wmip, u8 *pmk); - -int -wmi_set_excess_tx_retry_thres_cmd(struct wmi_t *wmip, WMI_SET_EXCESS_TX_RETRY_THRES_CMD *cmd); - -u16 wmi_ieee2freq (int chan); - -u32 wmi_freq2ieee (u16 freq); - -bss_t * -wmi_find_matching_Ssidnode (struct wmi_t *wmip, u8 *pSsid, - u32 ssidLength, - u32 dot11AuthMode, u32 authMode, - u32 pairwiseCryptoType, u32 grpwiseCryptoTyp); - -#ifdef __cplusplus -} -#endif - -#endif /* _WMI_API_H_ */ diff --git a/drivers/staging/ath6kl/miscdrv/ar3kconfig.c b/drivers/staging/ath6kl/miscdrv/ar3kconfig.c deleted file mode 100644 index e0ea218..0000000 --- a/drivers/staging/ath6kl/miscdrv/ar3kconfig.c +++ /dev/null @@ -1,565 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// AR3K configuration implementation -// -// Author(s): ="Atheros" -//============================================================================== - -#include "a_config.h" -#include "athdefs.h" -#include "a_osapi.h" -#define ATH_MODULE_NAME misc -#include "a_debug.h" -#include "common_drv.h" -#ifdef EXPORT_HCI_BRIDGE_INTERFACE -#include "export_hci_transport.h" -#else -#include "hci_transport_api.h" -#endif -#include "ar3kconfig.h" -#include "tlpm.h" - -#define BAUD_CHANGE_COMMAND_STATUS_OFFSET 5 -#define HCI_EVENT_RESP_TIMEOUTMS 3000 -#define HCI_CMD_OPCODE_BYTE_LOW_OFFSET 0 -#define HCI_CMD_OPCODE_BYTE_HI_OFFSET 1 -#define HCI_EVENT_OPCODE_BYTE_LOW 3 -#define HCI_EVENT_OPCODE_BYTE_HI 4 -#define HCI_CMD_COMPLETE_EVENT_CODE 0xE -#define HCI_MAX_EVT_RECV_LENGTH 257 -#define EXIT_MIN_BOOT_COMMAND_STATUS_OFFSET 5 - -int AthPSInitialize(struct ar3k_config_info *hdev); - -static int SendHCICommand(struct ar3k_config_info *pConfig, - u8 *pBuffer, - int Length) -{ - struct htc_packet *pPacket = NULL; - int status = 0; - - do { - - pPacket = (struct htc_packet *)A_MALLOC(sizeof(struct htc_packet)); - if (NULL == pPacket) { - status = A_NO_MEMORY; - break; - } - - A_MEMZERO(pPacket,sizeof(struct htc_packet)); - SET_HTC_PACKET_INFO_TX(pPacket, - NULL, - pBuffer, - Length, - HCI_COMMAND_TYPE, - AR6K_CONTROL_PKT_TAG); - - /* issue synchronously */ - status = HCI_TransportSendPkt(pConfig->pHCIDev,pPacket,true); - - } while (false); - - if (pPacket != NULL) { - kfree(pPacket); - } - - return status; -} - -static int RecvHCIEvent(struct ar3k_config_info *pConfig, - u8 *pBuffer, - int *pLength) -{ - int status = 0; - struct htc_packet *pRecvPacket = NULL; - - do { - - pRecvPacket = (struct htc_packet *)A_MALLOC(sizeof(struct htc_packet)); - if (NULL == pRecvPacket) { - status = A_NO_MEMORY; - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to alloc HTC struct \n")); - break; - } - - A_MEMZERO(pRecvPacket,sizeof(struct htc_packet)); - - SET_HTC_PACKET_INFO_RX_REFILL(pRecvPacket,NULL,pBuffer,*pLength,HCI_EVENT_TYPE); - - status = HCI_TransportRecvHCIEventSync(pConfig->pHCIDev, - pRecvPacket, - HCI_EVENT_RESP_TIMEOUTMS); - if (status) { - break; - } - - *pLength = pRecvPacket->ActualLength; - - } while (false); - - if (pRecvPacket != NULL) { - kfree(pRecvPacket); - } - - return status; -} - -int SendHCICommandWaitCommandComplete(struct ar3k_config_info *pConfig, - u8 *pHCICommand, - int CmdLength, - u8 **ppEventBuffer, - u8 **ppBufferToFree) -{ - int status = 0; - u8 *pBuffer = NULL; - u8 *pTemp; - int length; - bool commandComplete = false; - u8 opCodeBytes[2]; - - do { - - length = max(HCI_MAX_EVT_RECV_LENGTH,CmdLength); - length += pConfig->pHCIProps->HeadRoom + pConfig->pHCIProps->TailRoom; - length += pConfig->pHCIProps->IOBlockPad; - - pBuffer = (u8 *)A_MALLOC(length); - if (NULL == pBuffer) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: Failed to allocate bt buffer \n")); - status = A_NO_MEMORY; - break; - } - - /* get the opcodes to check the command complete event */ - opCodeBytes[0] = pHCICommand[HCI_CMD_OPCODE_BYTE_LOW_OFFSET]; - opCodeBytes[1] = pHCICommand[HCI_CMD_OPCODE_BYTE_HI_OFFSET]; - - /* copy HCI command */ - memcpy(pBuffer + pConfig->pHCIProps->HeadRoom,pHCICommand,CmdLength); - /* send command */ - status = SendHCICommand(pConfig, - pBuffer + pConfig->pHCIProps->HeadRoom, - CmdLength); - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: Failed to send HCI Command (%d) \n", status)); - AR_DEBUG_PRINTBUF(pHCICommand,CmdLength,"HCI Bridge Failed HCI Command"); - break; - } - - /* reuse buffer to capture command complete event */ - A_MEMZERO(pBuffer,length); - status = RecvHCIEvent(pConfig,pBuffer,&length); - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: HCI event recv failed \n")); - AR_DEBUG_PRINTBUF(pHCICommand,CmdLength,"HCI Bridge Failed HCI Command"); - break; - } - - pTemp = pBuffer + pConfig->pHCIProps->HeadRoom; - if (pTemp[0] == HCI_CMD_COMPLETE_EVENT_CODE) { - if ((pTemp[HCI_EVENT_OPCODE_BYTE_LOW] == opCodeBytes[0]) && - (pTemp[HCI_EVENT_OPCODE_BYTE_HI] == opCodeBytes[1])) { - commandComplete = true; - } - } - - if (!commandComplete) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: Unexpected HCI event : %d \n",pTemp[0])); - AR_DEBUG_PRINTBUF(pTemp,pTemp[1],"Unexpected HCI event"); - status = A_ECOMM; - break; - } - - if (ppEventBuffer != NULL) { - /* caller wants to look at the event */ - *ppEventBuffer = pTemp; - if (ppBufferToFree == NULL) { - status = A_EINVAL; - break; - } - /* caller must free the buffer */ - *ppBufferToFree = pBuffer; - pBuffer = NULL; - } - - } while (false); - - if (pBuffer != NULL) { - kfree(pBuffer); - } - - return status; -} - -static int AR3KConfigureHCIBaud(struct ar3k_config_info *pConfig) -{ - int status = 0; - u8 hciBaudChangeCommand[] = {0x0c,0xfc,0x2,0,0}; - u16 baudVal; - u8 *pEvent = NULL; - u8 *pBufferToFree = NULL; - - do { - - if (pConfig->Flags & AR3K_CONFIG_FLAG_SET_AR3K_BAUD) { - baudVal = (u16)(pConfig->AR3KBaudRate / 100); - hciBaudChangeCommand[3] = (u8)baudVal; - hciBaudChangeCommand[4] = (u8)(baudVal >> 8); - - status = SendHCICommandWaitCommandComplete(pConfig, - hciBaudChangeCommand, - sizeof(hciBaudChangeCommand), - &pEvent, - &pBufferToFree); - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: Baud rate change failed! \n")); - break; - } - - if (pEvent[BAUD_CHANGE_COMMAND_STATUS_OFFSET] != 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("AR3K Config: Baud change command event status failed: %d \n", - pEvent[BAUD_CHANGE_COMMAND_STATUS_OFFSET])); - status = A_ECOMM; - break; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, - ("AR3K Config: Baud Changed to %d \n",pConfig->AR3KBaudRate)); - } - - if (pConfig->Flags & AR3K_CONFIG_FLAG_AR3K_BAUD_CHANGE_DELAY) { - /* some versions of AR3K do not switch baud immediately, up to 300MS */ - A_MDELAY(325); - } - - if (pConfig->Flags & AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP) { - /* Tell target to change UART baud rate for AR6K */ - status = HCI_TransportSetBaudRate(pConfig->pHCIDev, pConfig->AR3KBaudRate); - - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("AR3K Config: failed to set scale and step values: %d \n", status)); - break; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_ANY, - ("AR3K Config: Baud changed to %d for AR6K\n", pConfig->AR3KBaudRate)); - } - - } while (false); - - if (pBufferToFree != NULL) { - kfree(pBufferToFree); - } - - return status; -} - -static int AR3KExitMinBoot(struct ar3k_config_info *pConfig) -{ - int status; - char exitMinBootCmd[] = {0x25,0xFC,0x0c,0x03,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00}; - u8 *pEvent = NULL; - u8 *pBufferToFree = NULL; - - status = SendHCICommandWaitCommandComplete(pConfig, - exitMinBootCmd, - sizeof(exitMinBootCmd), - &pEvent, - &pBufferToFree); - - if (!status) { - if (pEvent[EXIT_MIN_BOOT_COMMAND_STATUS_OFFSET] != 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("AR3K Config: MinBoot exit command event status failed: %d \n", - pEvent[EXIT_MIN_BOOT_COMMAND_STATUS_OFFSET])); - status = A_ECOMM; - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, - ("AR3K Config: MinBoot Exit Command Complete (Success) \n")); - A_MDELAY(1); - } - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: MinBoot Exit Failed! \n")); - } - - if (pBufferToFree != NULL) { - kfree(pBufferToFree); - } - - return status; -} - -static int AR3KConfigureSendHCIReset(struct ar3k_config_info *pConfig) -{ - int status = 0; - u8 hciResetCommand[] = {0x03,0x0c,0x0}; - u8 *pEvent = NULL; - u8 *pBufferToFree = NULL; - - status = SendHCICommandWaitCommandComplete( pConfig, - hciResetCommand, - sizeof(hciResetCommand), - &pEvent, - &pBufferToFree ); - - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: HCI reset failed! \n")); - } - - if (pBufferToFree != NULL) { - kfree(pBufferToFree); - } - - return status; -} - -static int AR3KEnableTLPM(struct ar3k_config_info *pConfig) -{ - int status; - /* AR3K vendor specific command for Host Wakeup Config */ - char hostWakeupConfig[] = {0x31,0xFC,0x18, - 0x02,0x00,0x00,0x00, - 0x01,0x00,0x00,0x00, - TLPM_DEFAULT_IDLE_TIMEOUT_LSB,TLPM_DEFAULT_IDLE_TIMEOUT_MSB,0x00,0x00, //idle timeout in ms - 0x00,0x00,0x00,0x00, - TLPM_DEFAULT_WAKEUP_TIMEOUT_MS,0x00,0x00,0x00, //wakeup timeout in ms - 0x00,0x00,0x00,0x00}; - /* AR3K vendor specific command for Target Wakeup Config */ - char targetWakeupConfig[] = {0x31,0xFC,0x18, - 0x04,0x00,0x00,0x00, - 0x01,0x00,0x00,0x00, - TLPM_DEFAULT_IDLE_TIMEOUT_LSB,TLPM_DEFAULT_IDLE_TIMEOUT_MSB,0x00,0x00, //idle timeout in ms - 0x00,0x00,0x00,0x00, - TLPM_DEFAULT_WAKEUP_TIMEOUT_MS,0x00,0x00,0x00, //wakeup timeout in ms - 0x00,0x00,0x00,0x00}; - /* AR3K vendor specific command for Host Wakeup Enable */ - char hostWakeupEnable[] = {0x31,0xFC,0x4, - 0x01,0x00,0x00,0x00}; - /* AR3K vendor specific command for Target Wakeup Enable */ - char targetWakeupEnable[] = {0x31,0xFC,0x4, - 0x06,0x00,0x00,0x00}; - /* AR3K vendor specific command for Sleep Enable */ - char sleepEnable[] = {0x4,0xFC,0x1, - 0x1}; - u8 *pEvent = NULL; - u8 *pBufferToFree = NULL; - - if (0 != pConfig->IdleTimeout) { - u8 idle_lsb = pConfig->IdleTimeout & 0xFF; - u8 idle_msb = (pConfig->IdleTimeout & 0xFF00) >> 8; - hostWakeupConfig[11] = targetWakeupConfig[11] = idle_lsb; - hostWakeupConfig[12] = targetWakeupConfig[12] = idle_msb; - } - - if (0 != pConfig->WakeupTimeout) { - hostWakeupConfig[19] = targetWakeupConfig[19] = (pConfig->WakeupTimeout & 0xFF); - } - - status = SendHCICommandWaitCommandComplete(pConfig, - hostWakeupConfig, - sizeof(hostWakeupConfig), - &pEvent, - &pBufferToFree); - if (pBufferToFree != NULL) { - kfree(pBufferToFree); - } - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HostWakeup Config Failed! \n")); - return status; - } - - pEvent = NULL; - pBufferToFree = NULL; - status = SendHCICommandWaitCommandComplete(pConfig, - targetWakeupConfig, - sizeof(targetWakeupConfig), - &pEvent, - &pBufferToFree); - if (pBufferToFree != NULL) { - kfree(pBufferToFree); - } - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Target Wakeup Config Failed! \n")); - return status; - } - - pEvent = NULL; - pBufferToFree = NULL; - status = SendHCICommandWaitCommandComplete(pConfig, - hostWakeupEnable, - sizeof(hostWakeupEnable), - &pEvent, - &pBufferToFree); - if (pBufferToFree != NULL) { - kfree(pBufferToFree); - } - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HostWakeup Enable Failed! \n")); - return status; - } - - pEvent = NULL; - pBufferToFree = NULL; - status = SendHCICommandWaitCommandComplete(pConfig, - targetWakeupEnable, - sizeof(targetWakeupEnable), - &pEvent, - &pBufferToFree); - if (pBufferToFree != NULL) { - kfree(pBufferToFree); - } - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Target Wakeup Enable Failed! \n")); - return status; - } - - pEvent = NULL; - pBufferToFree = NULL; - status = SendHCICommandWaitCommandComplete(pConfig, - sleepEnable, - sizeof(sleepEnable), - &pEvent, - &pBufferToFree); - if (pBufferToFree != NULL) { - kfree(pBufferToFree); - } - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Sleep Enable Failed! \n")); - } - - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: Enable TLPM Completed (status = %d) \n",status)); - - return status; -} - -int AR3KConfigure(struct ar3k_config_info *pConfig) -{ - int status = 0; - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR3K Config: Configuring AR3K ...\n")); - - do { - - if ((pConfig->pHCIDev == NULL) || (pConfig->pHCIProps == NULL) || (pConfig->pHIFDevice == NULL)) { - status = A_EINVAL; - break; - } - - /* disable asynchronous recv while we issue commands and receive events synchronously */ - status = HCI_TransportEnableDisableAsyncRecv(pConfig->pHCIDev,false); - if (status) { - break; - } - - if (pConfig->Flags & AR3K_CONFIG_FLAG_FORCE_MINBOOT_EXIT) { - status = AR3KExitMinBoot(pConfig); - if (status) { - break; - } - } - - - /* Load patching and PST file if available*/ - if (0 != AthPSInitialize(pConfig)) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Patch Download Failed!\n")); - } - - /* Send HCI reset to make PS tags take effect*/ - AR3KConfigureSendHCIReset(pConfig); - - if (pConfig->Flags & - (AR3K_CONFIG_FLAG_SET_AR3K_BAUD | AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP)) { - status = AR3KConfigureHCIBaud(pConfig); - if (status) { - break; - } - } - - - - if (pConfig->PwrMgmtEnabled) { - /* the delay is required after the previous HCI reset before further - * HCI commands can be issued - */ - A_MDELAY(200); - AR3KEnableTLPM(pConfig); - } - - /* re-enable asynchronous recv */ - status = HCI_TransportEnableDisableAsyncRecv(pConfig->pHCIDev,true); - if (status) { - break; - } - - - } while (false); - - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR3K Config: Configuration Complete (status = %d) \n",status)); - - return status; -} - -int AR3KConfigureExit(void *config) -{ - int status = 0; - struct ar3k_config_info *pConfig = (struct ar3k_config_info *)config; - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR3K Config: Cleaning up AR3K ...\n")); - - do { - - if ((pConfig->pHCIDev == NULL) || (pConfig->pHCIProps == NULL) || (pConfig->pHIFDevice == NULL)) { - status = A_EINVAL; - break; - } - - /* disable asynchronous recv while we issue commands and receive events synchronously */ - status = HCI_TransportEnableDisableAsyncRecv(pConfig->pHCIDev,false); - if (status) { - break; - } - - if (pConfig->Flags & - (AR3K_CONFIG_FLAG_SET_AR3K_BAUD | AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP)) { - status = AR3KConfigureHCIBaud(pConfig); - if (status) { - break; - } - } - - /* re-enable asynchronous recv */ - status = HCI_TransportEnableDisableAsyncRecv(pConfig->pHCIDev,true); - if (status) { - break; - } - - - } while (false); - - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR3K Config: Cleanup Complete (status = %d) \n",status)); - - return status; -} - diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c deleted file mode 100644 index 282ceac..0000000 --- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.c +++ /dev/null @@ -1,572 +0,0 @@ -/* - * Copyright (c) 2004-2010 Atheros Communications Inc. - * All rights reserved. - * - * This file implements the Atheros PS and patch downloaded for HCI UART Transport driver. - * This file can be used for HCI SDIO transport implementation for AR6002 with HCI_TRANSPORT_SDIO - * defined. - * - * - * ar3kcpsconfig.c - * - * - * - * The software source and binaries included in this development package are - * licensed, not sold. You, or your company, received the package under one - * or more license agreements. The rights granted to you are specifically - * listed in these license agreement(s). All other rights remain with Atheros - * Communications, Inc., its subsidiaries, or the respective owner including - * those listed on the included copyright notices.. Distribution of any - * portion of this package must be in strict compliance with the license - * agreement(s) terms. - * - * - * - */ - - - -#include "ar3kpsconfig.h" -#ifndef HCI_TRANSPORT_SDIO -#include "hci_ath.h" -#include "hci_uart.h" -#endif /* #ifndef HCI_TRANSPORT_SDIO */ - -#define MAX_FW_PATH_LEN 50 -#define MAX_BDADDR_FORMAT_LENGTH 30 - -/* - * Structure used to send HCI packet, hci packet length and device info - * together as parameter to PSThread. - */ -typedef struct { - - struct ps_cmd_packet *HciCmdList; - u32 num_packets; - struct ar3k_config_info *dev; -}HciCommandListParam; - -int SendHCICommandWaitCommandComplete(struct ar3k_config_info *pConfig, - u8 *pHCICommand, - int CmdLength, - u8 **ppEventBuffer, - u8 **ppBufferToFree); - -u32 Rom_Version; -u32 Build_Version; -extern bool BDADDR; - -int getDeviceType(struct ar3k_config_info *pConfig, u32 *code); -int ReadVersionInfo(struct ar3k_config_info *pConfig); -#ifndef HCI_TRANSPORT_SDIO - -DECLARE_WAIT_QUEUE_HEAD(PsCompleteEvent); -DECLARE_WAIT_QUEUE_HEAD(HciEvent); -u8 *HciEventpacket; -rwlock_t syncLock; -wait_queue_t Eventwait; - -int PSHciWritepacket(struct hci_dev*,u8* Data, u32 len); -extern char *bdaddr; -#endif /* HCI_TRANSPORT_SDIO */ - -int write_bdaddr(struct ar3k_config_info *pConfig,u8 *bdaddr,int type); - -int PSSendOps(void *arg); - -#ifdef BT_PS_DEBUG -void Hci_log(u8 * log_string,u8 *data,u32 len) -{ - int i; - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s : ",log_string)); - for (i = 0; i < len; i++) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("0x%02x ", data[i])); - } - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("\n...................................\n")); -} -#else -#define Hci_log(string,data,len) -#endif /* BT_PS_DEBUG */ - - - - -int AthPSInitialize(struct ar3k_config_info *hdev) -{ - int status = 0; - if(hdev == NULL) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Invalid Device handle received\n")); - return A_ERROR; - } - -#ifndef HCI_TRANSPORT_SDIO - DECLARE_WAITQUEUE(wait, current); -#endif /* HCI_TRANSPORT_SDIO */ - - -#ifdef HCI_TRANSPORT_SDIO - status = PSSendOps((void*)hdev); -#else - if(InitPSState(hdev) == -1) { - return A_ERROR; - } - allow_signal(SIGKILL); - add_wait_queue(&PsCompleteEvent,&wait); - set_current_state(TASK_INTERRUPTIBLE); - if(!kernel_thread(PSSendOps,(void*)hdev,CLONE_FS|CLONE_FILES|CLONE_SIGHAND|SIGCHLD)) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Kthread Failed\n")); - remove_wait_queue(&PsCompleteEvent,&wait); - return A_ERROR; - } - wait_event_interruptible(PsCompleteEvent,(PSTagMode == false)); - set_current_state(TASK_RUNNING); - remove_wait_queue(&PsCompleteEvent,&wait); - -#endif /* HCI_TRANSPORT_SDIO */ - - - return status; - -} - -int PSSendOps(void *arg) -{ - int i; - int status = 0; - struct ps_cmd_packet *HciCmdList; /* List storing the commands */ - const struct firmware* firmware; - u32 numCmds; - u8 *event; - u8 *bufferToFree; - struct hci_dev *device; - u8 *buffer; - u32 len; - u32 DevType; - u8 *PsFileName; - u8 *patchFileName; - u8 *path = NULL; - u8 *config_path = NULL; - u8 config_bdaddr[MAX_BDADDR_FORMAT_LENGTH]; - struct ar3k_config_info *hdev = (struct ar3k_config_info*)arg; - struct device *firmwareDev = NULL; - status = 0; - HciCmdList = NULL; -#ifdef HCI_TRANSPORT_SDIO - device = hdev->pBtStackHCIDev; - firmwareDev = device->parent; -#else - device = hdev; - firmwareDev = &device->dev; - AthEnableSyncCommandOp(true); -#endif /* HCI_TRANSPORT_SDIO */ - /* First verify if the controller is an FPGA or ASIC, so depending on the device type the PS file to be written will be different. - */ - - path =(u8 *)A_MALLOC(MAX_FW_PATH_LEN); - if(path == NULL) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Malloc failed to allocate %d bytes for path\n", MAX_FW_PATH_LEN)); - goto complete; - } - config_path = (u8 *) A_MALLOC(MAX_FW_PATH_LEN); - if(config_path == NULL) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Malloc failed to allocate %d bytes for config_path\n", MAX_FW_PATH_LEN)); - goto complete; - } - - if(A_ERROR == getDeviceType(hdev,&DevType)) { - status = 1; - goto complete; - } - if(A_ERROR == ReadVersionInfo(hdev)) { - status = 1; - goto complete; - } - - patchFileName = PATCH_FILE; - snprintf(path, MAX_FW_PATH_LEN, "%s/%xcoex/",CONFIG_PATH,Rom_Version); - if(DevType){ - if(DevType == 0xdeadc0de){ - PsFileName = PS_ASIC_FILE; - } else{ - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" FPGA Test Image : %x %x \n",Rom_Version,Build_Version)); - if((Rom_Version == 0x99999999) && (Build_Version == 1)){ - - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("FPGA Test Image : Skipping Patch File load\n")); - patchFileName = NULL; - } - PsFileName = PS_FPGA_FILE; - } - } - else{ - PsFileName = PS_ASIC_FILE; - } - - snprintf(config_path, MAX_FW_PATH_LEN, "%s%s",path,PsFileName); - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%x: FPGA/ASIC PS File Name %s\n", DevType,config_path)); - /* Read the PS file to a dynamically allocated buffer */ - if(A_REQUEST_FIRMWARE(&firmware,config_path,firmwareDev) < 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: firmware file open error\n", __FUNCTION__ )); - status = 1; - goto complete; - - } - if(NULL == firmware || firmware->size == 0) { - status = 1; - goto complete; - } - buffer = (u8 *)A_MALLOC(firmware->size); - if(buffer != NULL) { - /* Copy the read file to a local Dynamic buffer */ - memcpy(buffer,firmware->data,firmware->size); - len = firmware->size; - A_RELEASE_FIRMWARE(firmware); - /* Parse the PS buffer to a global variable */ - status = AthDoParsePS(buffer,len); - kfree(buffer); - } else { - A_RELEASE_FIRMWARE(firmware); - } - - - /* Read the patch file to a dynamically allocated buffer */ - if(patchFileName != NULL) - snprintf(config_path, - MAX_FW_PATH_LEN, "%s%s",path,patchFileName); - else { - status = 0; - } - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Patch File Name %s\n", config_path)); - if((patchFileName == NULL) || (A_REQUEST_FIRMWARE(&firmware,config_path,firmwareDev) < 0)) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: firmware file open error\n", __FUNCTION__ )); - /* - * It is not necessary that Patch file be available, continue with PS Operations if. - * failed. - */ - status = 0; - - } else { - if(NULL == firmware || firmware->size == 0) { - status = 0; - } else { - buffer = (u8 *)A_MALLOC(firmware->size); - if(buffer != NULL) { - /* Copy the read file to a local Dynamic buffer */ - memcpy(buffer,firmware->data,firmware->size); - len = firmware->size; - A_RELEASE_FIRMWARE(firmware); - /* parse and store the Patch file contents to a global variables */ - status = AthDoParsePatch(buffer,len); - kfree(buffer); - } else { - A_RELEASE_FIRMWARE(firmware); - } - } - } - - /* Create an HCI command list from the parsed PS and patch information */ - AthCreateCommandList(&HciCmdList,&numCmds); - - /* Form the parameter for PSSendOps() API */ - - - /* - * First Send the CRC packet, - * We have to continue with the PS operations only if the CRC packet has been replied with - * a Command complete event with status Error. - */ - - if(SendHCICommandWaitCommandComplete - (hdev, - HciCmdList[0].Hcipacket, - HciCmdList[0].packetLen, - &event, - &bufferToFree) == 0) { - if(ReadPSEvent(event) == 0) { /* Exit if the status is success */ - if(bufferToFree != NULL) { - kfree(bufferToFree); - } - -#ifndef HCI_TRANSPORT_SDIO - if(bdaddr && bdaddr[0] !='\0') { - write_bdaddr(hdev,bdaddr,BDADDR_TYPE_STRING); - } -#endif - status = 1; - goto complete; - } - if(bufferToFree != NULL) { - kfree(bufferToFree); - } - } else { - status = 0; - goto complete; - } - - for(i = 1; i <numCmds; i++) { - - if(SendHCICommandWaitCommandComplete - (hdev, - HciCmdList[i].Hcipacket, - HciCmdList[i].packetLen, - &event, - &bufferToFree) == 0) { - if(ReadPSEvent(event) != 0) { /* Exit if the status is success */ - if(bufferToFree != NULL) { - kfree(bufferToFree); - } - status = 1; - goto complete; - } - if(bufferToFree != NULL) { - kfree(bufferToFree); - } - } else { - status = 0; - goto complete; - } - } -#ifdef HCI_TRANSPORT_SDIO - if(BDADDR == false) - if(hdev->bdaddr[0] !=0x00 || - hdev->bdaddr[1] !=0x00 || - hdev->bdaddr[2] !=0x00 || - hdev->bdaddr[3] !=0x00 || - hdev->bdaddr[4] !=0x00 || - hdev->bdaddr[5] !=0x00) - write_bdaddr(hdev,hdev->bdaddr,BDADDR_TYPE_HEX); - -#ifndef HCI_TRANSPORT_SDIO - - if(bdaddr && bdaddr[0] != '\0') { - write_bdaddr(hdev,bdaddr,BDADDR_TYPE_STRING); - } else -#endif /* HCI_TRANSPORT_SDIO */ - /* Write BDADDR Read from OTP here */ - - - -#endif - - { - /* Read Contents of BDADDR file if user has not provided any option */ - snprintf(config_path,MAX_FW_PATH_LEN, "%s%s",path,BDADDR_FILE); - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Patch File Name %s\n", config_path)); - if(A_REQUEST_FIRMWARE(&firmware,config_path,firmwareDev) < 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: firmware file open error\n", __FUNCTION__ )); - status = 1; - goto complete; - } - if(NULL == firmware || firmware->size == 0) { - status = 1; - goto complete; - } - len = min_t(size_t, firmware->size, MAX_BDADDR_FORMAT_LENGTH - 1); - memcpy(config_bdaddr, firmware->data, len); - config_bdaddr[len] = '\0'; - write_bdaddr(hdev,config_bdaddr,BDADDR_TYPE_STRING); - A_RELEASE_FIRMWARE(firmware); - } -complete: -#ifndef HCI_TRANSPORT_SDIO - AthEnableSyncCommandOp(false); - PSTagMode = false; - wake_up_interruptible(&PsCompleteEvent); -#endif /* HCI_TRANSPORT_SDIO */ - if(NULL != HciCmdList) { - AthFreeCommandList(&HciCmdList,numCmds); - } - if(path) { - kfree(path); - } - if(config_path) { - kfree(config_path); - } - return status; -} -#ifndef HCI_TRANSPORT_SDIO -/* - * This API is used to send the HCI command to controller and return - * with a HCI Command Complete event. - * For HCI SDIO transport, this will be internally defined. - */ -int SendHCICommandWaitCommandComplete(struct ar3k_config_info *pConfig, - u8 *pHCICommand, - int CmdLength, - u8 **ppEventBuffer, - u8 **ppBufferToFree) -{ - if(CmdLength == 0) { - return A_ERROR; - } - Hci_log("COM Write -->",pHCICommand,CmdLength); - PSAcked = false; - if(PSHciWritepacket(pConfig,pHCICommand,CmdLength) == 0) { - /* If the controller is not available, return Error */ - return A_ERROR; - } - //add_timer(&psCmdTimer); - wait_event_interruptible(HciEvent,(PSAcked == true)); - if(NULL != HciEventpacket) { - *ppEventBuffer = HciEventpacket; - *ppBufferToFree = HciEventpacket; - } else { - /* Did not get an event from controller. return error */ - *ppBufferToFree = NULL; - return A_ERROR; - } - - return 0; -} -#endif /* HCI_TRANSPORT_SDIO */ - -int ReadPSEvent(u8* Data){ - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" PS Event %x %x %x\n",Data[4],Data[5],Data[3])); - - if(Data[4] == 0xFC && Data[5] == 0x00) - { - switch(Data[3]){ - case 0x0B: - return 0; - break; - case 0x0C: - /* Change Baudrate */ - return 0; - break; - case 0x04: - return 0; - break; - case 0x1E: - Rom_Version = Data[9]; - Rom_Version = ((Rom_Version << 8) |Data[8]); - Rom_Version = ((Rom_Version << 8) |Data[7]); - Rom_Version = ((Rom_Version << 8) |Data[6]); - - Build_Version = Data[13]; - Build_Version = ((Build_Version << 8) |Data[12]); - Build_Version = ((Build_Version << 8) |Data[11]); - Build_Version = ((Build_Version << 8) |Data[10]); - return 0; - break; - - - } - } - - return A_ERROR; -} -int str2ba(unsigned char *str_bdaddr,unsigned char *bdaddr) -{ - unsigned char bdbyte[3]; - unsigned char *str_byte = str_bdaddr; - int i,j; - unsigned char colon_present = 0; - - if(NULL != strstr(str_bdaddr,":")) { - colon_present = 1; - } - - - bdbyte[2] = '\0'; - - for( i = 0,j = 5; i < 6; i++, j--) { - bdbyte[0] = str_byte[0]; - bdbyte[1] = str_byte[1]; - bdaddr[j] = A_STRTOL(bdbyte,NULL,16); - if(colon_present == 1) { - str_byte+=3; - } else { - str_byte+=2; - } - } - return 0; -} - -int write_bdaddr(struct ar3k_config_info *pConfig,u8 *bdaddr,int type) -{ - u8 bdaddr_cmd[] = { 0x0B, 0xFC, 0x0A, 0x01, 0x01, - 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - - u8 *event; - u8 *bufferToFree = NULL; - int result = A_ERROR; - int inc,outc; - - if (type == BDADDR_TYPE_STRING) - str2ba(bdaddr,&bdaddr_cmd[7]); - else { - /* Bdaddr has to be sent as LAP first */ - for(inc = 5 ,outc = 7; inc >=0; inc--, outc++) - bdaddr_cmd[outc] = bdaddr[inc]; - } - - if(0 == SendHCICommandWaitCommandComplete(pConfig,bdaddr_cmd, - sizeof(bdaddr_cmd), - &event,&bufferToFree)) { - - if(event[4] == 0xFC && event[5] == 0x00){ - if(event[3] == 0x0B){ - result = 0; - } - } - - } - if(bufferToFree != NULL) { - kfree(bufferToFree); - } - return result; - -} -int ReadVersionInfo(struct ar3k_config_info *pConfig) -{ - u8 hciCommand[] = {0x1E,0xfc,0x00}; - u8 *event; - u8 *bufferToFree = NULL; - int result = A_ERROR; - if(0 == SendHCICommandWaitCommandComplete(pConfig,hciCommand,sizeof(hciCommand),&event,&bufferToFree)) { - result = ReadPSEvent(event); - - } - if(bufferToFree != NULL) { - kfree(bufferToFree); - } - return result; -} -int getDeviceType(struct ar3k_config_info *pConfig, u32 *code) -{ - u8 hciCommand[] = {0x05,0xfc,0x05,0x00,0x00,0x00,0x00,0x04}; - u8 *event; - u8 *bufferToFree = NULL; - u32 reg; - int result = A_ERROR; - *code = 0; - hciCommand[3] = (u8)(FPGA_REGISTER & 0xFF); - hciCommand[4] = (u8)((FPGA_REGISTER >> 8) & 0xFF); - hciCommand[5] = (u8)((FPGA_REGISTER >> 16) & 0xFF); - hciCommand[6] = (u8)((FPGA_REGISTER >> 24) & 0xFF); - if(0 == SendHCICommandWaitCommandComplete(pConfig,hciCommand,sizeof(hciCommand),&event,&bufferToFree)) { - - if(event[4] == 0xFC && event[5] == 0x00){ - switch(event[3]){ - case 0x05: - reg = event[9]; - reg = ((reg << 8) |event[8]); - reg = ((reg << 8) |event[7]); - reg = ((reg << 8) |event[6]); - *code = reg; - result = 0; - - break; - case 0x06: - //Sleep(500); - break; - } - } - - } - if(bufferToFree != NULL) { - kfree(bufferToFree); - } - return result; -} - - diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.h b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.h deleted file mode 100644 index d443513..0000000 --- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsconfig.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2004-2010 Atheros Communications Inc. - * All rights reserved. - * - * This file defines the symbols exported by Atheros PS and patch download module. - * define the constant HCI_TRANSPORT_SDIO if the module is being used for HCI SDIO transport. - * defined. - * - * - * ar3kcpsconfig.h - * - * - * - * The software source and binaries included in this development package are - * licensed, not sold. You, or your company, received the package under one - * or more license agreements. The rights granted to you are specifically - * listed in these license agreement(s). All other rights remain with Atheros - * Communications, Inc., its subsidiaries, or the respective owner including - * those listed on the included copyright notices.. Distribution of any - * portion of this package must be in strict compliance with the license - * agreement(s) terms. - * - * - * - */ - - - -#ifndef __AR3KPSCONFIG_H -#define __AR3KPSCONFIG_H - -/* - * Define the flag HCI_TRANSPORT_SDIO and undefine HCI_TRANSPORT_UART if the transport being used is SDIO. - */ -#undef HCI_TRANSPORT_UART - -#include <linux/fs.h> -#include <linux/errno.h> -#include <linux/signal.h> - - -#include <linux/ioctl.h> -#include <linux/firmware.h> - - -#include <net/bluetooth/bluetooth.h> -#include <net/bluetooth/hci_core.h> - -#include "ar3kpsparser.h" - -#define FPGA_REGISTER 0x4FFC -#define BDADDR_TYPE_STRING 0 -#define BDADDR_TYPE_HEX 1 -#define CONFIG_PATH "ar3k" - -#define PS_ASIC_FILE "PS_ASIC.pst" -#define PS_FPGA_FILE "PS_FPGA.pst" - -#define PATCH_FILE "RamPatch.txt" -#define BDADDR_FILE "ar3kbdaddr.pst" - -#define ROM_VER_AR3001_3_1_0 30000 -#define ROM_VER_AR3001_3_1_1 30101 - - -#ifndef HCI_TRANSPORT_SDIO -#define struct ar3k_config_info struct hci_dev -extern wait_queue_head_t HciEvent; -extern wait_queue_t Eventwait; -extern u8 *HciEventpacket; -#endif /* #ifndef HCI_TRANSPORT_SDIO */ - -int AthPSInitialize(struct ar3k_config_info *hdev); -int ReadPSEvent(u8* Data); -#endif /* __AR3KPSCONFIG_H */ diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c deleted file mode 100644 index b99a11a..0000000 --- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.c +++ /dev/null @@ -1,969 +0,0 @@ -/* - * Copyright (c) 2004-2010 Atheros Communications Inc. - * All rights reserved. - * - * This file implements the Atheros PS and patch parser. - * It implements APIs to parse data buffer with patch and PS information and convert it to HCI commands. - * - * - * - * ar3kpsparser.c - * - * - * - * The software source and binaries included in this development package are - * licensed, not sold. You, or your company, received the package under one - * or more license agreements. The rights granted to you are specifically - * listed in these license agreement(s). All other rights remain with Atheros - * Communications, Inc., its subsidiaries, or the respective owner including - * those listed on the included copyright notices.. Distribution of any - * portion of this package must be in strict compliance with the license - * agreement(s) terms. - * - * - * - */ - - -#include "ar3kpsparser.h" - -#include <linux/ctype.h> -#include <linux/kernel.h> - -#define BD_ADDR_SIZE 6 -#define WRITE_PATCH 8 -#define ENABLE_PATCH 11 -#define PS_RESET 2 -#define PS_WRITE 1 -#define PS_VERIFY_CRC 9 -#define CHANGE_BDADDR 15 - -#define HCI_COMMAND_HEADER 7 - -#define HCI_EVENT_SIZE 7 - -#define WRITE_PATCH_COMMAND_STATUS_OFFSET 5 - -#define PS_RAM_SIZE 2048 - -#define RAM_PS_REGION (1<<0) -#define RAM_PATCH_REGION (1<<1) -#define RAMPS_MAX_PS_DATA_PER_TAG 20000 -#define MAX_RADIO_CFG_TABLE_SIZE 244 -#define RAMPS_MAX_PS_TAGS_PER_FILE 50 - -#define PS_MAX_LEN 500 -#define LINE_SIZE_MAX (PS_MAX_LEN *2) - -/* Constant values used by parser */ -#define BYTES_OF_PS_DATA_PER_LINE 16 -#define RAMPS_MAX_PS_DATA_PER_TAG 20000 - - -/* Number pf PS/Patch entries in an HCI packet */ -#define MAX_BYTE_LENGTH 244 - -#define SKIP_BLANKS(str) while (*str == ' ') str++ - -enum MinBootFileFormatE -{ - MB_FILEFORMAT_RADIOTBL, - MB_FILEFORMAT_PATCH, - MB_FILEFORMAT_COEXCONFIG -}; - -enum RamPsSection -{ - RAM_PS_SECTION, - RAM_PATCH_SECTION, - RAM_DYN_MEM_SECTION -}; - -enum eType { - eHex, - edecimal -}; - - -typedef struct tPsTagEntry -{ - u32 TagId; - u32 TagLen; - u8 *TagData; -} tPsTagEntry, *tpPsTagEntry; - -typedef struct tRamPatch -{ - u16 Len; - u8 *Data; -} tRamPatch, *ptRamPatch; - - - -struct st_ps_data_format { - enum eType eDataType; - bool bIsArray; -}; - -struct st_read_status { - unsigned uTagID; - unsigned uSection; - unsigned uLineCount; - unsigned uCharCount; - unsigned uByteCount; -}; - - -/* Stores the number of PS Tags */ -static u32 Tag_Count = 0; - -/* Stores the number of patch commands */ -static u32 Patch_Count = 0; -static u32 Total_tag_lenght = 0; -bool BDADDR = false; -u32 StartTagId; - -tPsTagEntry PsTagEntry[RAMPS_MAX_PS_TAGS_PER_FILE]; -tRamPatch RamPatch[MAX_NUM_PATCH_ENTRY]; - - -int AthParseFilesUnified(u8 *srcbuffer,u32 srclen, int FileFormat); -char AthReadChar(u8 *buffer, u32 len,u32 *pos); -char *AthGetLine(char *buffer, int maxlen, u8 *srcbuffer,u32 len,u32 *pos); -static int AthPSCreateHCICommand(u8 Opcode, u32 Param1,struct ps_cmd_packet *PSPatchPacket,u32 *index); - -/* Function to reads the next character from the input buffer */ -char AthReadChar(u8 *buffer, u32 len,u32 *pos) -{ - char Ch; - if(buffer == NULL || *pos >=len ) - { - return '\0'; - } else { - Ch = buffer[*pos]; - (*pos)++; - return Ch; - } -} -/* PS parser helper function */ -unsigned int uGetInputDataFormat(char *pCharLine, struct st_ps_data_format *pstFormat) -{ - if(pCharLine[0] != '[') { - pstFormat->eDataType = eHex; - pstFormat->bIsArray = true; - return 0; - } - switch(pCharLine[1]) { - case 'H': - case 'h': - if(pCharLine[2]==':') { - if((pCharLine[3]== 'a') || (pCharLine[3]== 'A')) { - if(pCharLine[4] == ']') { - pstFormat->eDataType = eHex; - pstFormat->bIsArray = true; - pCharLine += 5; - return 0; - } - else { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format\n")); //[H:A - return 1; - } - } - if((pCharLine[3]== 'S') || (pCharLine[3]== 's')) { - if(pCharLine[4] == ']') { - pstFormat->eDataType = eHex; - pstFormat->bIsArray = false; - pCharLine += 5; - return 0; - } - else { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format\n")); //[H:A - return 1; - } - } - else if(pCharLine[3] == ']') { //[H:] - pstFormat->eDataType = eHex; - pstFormat->bIsArray = true; - pCharLine += 4; - return 0; - } - else { //[H: - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format\n")); - return 1; - } - } - else if(pCharLine[2]==']') { //[H] - pstFormat->eDataType = eHex; - pstFormat->bIsArray = true; - pCharLine += 3; - return 0; - } - else { //[H - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format\n")); - return 1; - } - break; - - case 'A': - case 'a': - if(pCharLine[2]==':') { - if((pCharLine[3]== 'h') || (pCharLine[3]== 'H')) { - if(pCharLine[4] == ']') { - pstFormat->eDataType = eHex; - pstFormat->bIsArray = true; - pCharLine += 5; - return 0; - } - else { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 1\n")); //[A:H - return 1; - } - } - else if(pCharLine[3]== ']') { //[A:] - pstFormat->eDataType = eHex; - pstFormat->bIsArray = true; - pCharLine += 4; - return 0; - } - else { //[A: - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 2\n")); - return 1; - } - } - else if(pCharLine[2]==']') { //[H] - pstFormat->eDataType = eHex; - pstFormat->bIsArray = true; - pCharLine += 3; - return 0; - } - else { //[H - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 3\n")); - return 1; - } - break; - - case 'S': - case 's': - if(pCharLine[2]==':') { - if((pCharLine[3]== 'h') || (pCharLine[3]== 'H')) { - if(pCharLine[4] == ']') { - pstFormat->eDataType = eHex; - pstFormat->bIsArray = true; - pCharLine += 5; - return 0; - } - else { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 5\n")); //[A:H - return 1; - } - } - else if(pCharLine[3]== ']') { //[A:] - pstFormat->eDataType = eHex; - pstFormat->bIsArray = true; - pCharLine += 4; - return 0; - } - else { //[A: - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 6\n")); - return 1; - } - } - else if(pCharLine[2]==']') { //[H] - pstFormat->eDataType = eHex; - pstFormat->bIsArray = true; - pCharLine += 3; - return 0; - } - else { //[H - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 7\n")); - return 1; - } - break; - - default: - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Illegal Data format 8\n")); - return 1; - } -} - -unsigned int uReadDataInSection(char *pCharLine, struct st_ps_data_format stPS_DataFormat) -{ - char *pTokenPtr = pCharLine; - - if(pTokenPtr[0] == '[') { - while(pTokenPtr[0] != ']' && pTokenPtr[0] != '\0') { - pTokenPtr++; - } - if(pTokenPtr[0] == '\0') { - return (0x0FFF); - } - pTokenPtr++; - - - } - if(stPS_DataFormat.eDataType == eHex) { - if(stPS_DataFormat.bIsArray == true) { - //Not implemented - return (0x0FFF); - } - else { - return (A_STRTOL(pTokenPtr, NULL, 16)); - } - } - else { - //Not implemented - return (0x0FFF); - } -} -int AthParseFilesUnified(u8 *srcbuffer,u32 srclen, int FileFormat) -{ - char *Buffer; - char *pCharLine; - u8 TagCount; - u16 ByteCount; - u8 ParseSection=RAM_PS_SECTION; - u32 pos; - - - - int uReadCount; - struct st_ps_data_format stPS_DataFormat; - struct st_read_status stReadStatus = {0, 0, 0,0}; - pos = 0; - Buffer = NULL; - - if (srcbuffer == NULL || srclen == 0) - { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Could not open .\n")); - return A_ERROR; - } - TagCount = 0; - ByteCount = 0; - Buffer = A_MALLOC(LINE_SIZE_MAX + 1); - if(NULL == Buffer) { - return A_ERROR; - } - if (FileFormat == MB_FILEFORMAT_PATCH) - { - int LineRead = 0; - while((pCharLine = AthGetLine(Buffer, LINE_SIZE_MAX, srcbuffer,srclen,&pos)) != NULL) - { - - SKIP_BLANKS(pCharLine); - - // Comment line or empty line - if ((pCharLine[0] == '/') && (pCharLine[1] == '/')) - { - continue; - } - - if ((pCharLine[0] == '#')) { - if (stReadStatus.uSection != 0) - { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("error\n")); - if(Buffer != NULL) { - kfree(Buffer); - } - return A_ERROR; - } - else { - stReadStatus.uSection = 1; - continue; - } - } - if ((pCharLine[0] == '/') && (pCharLine[1] == '*')) - { - pCharLine+=2; - SKIP_BLANKS(pCharLine); - - if(!strncmp(pCharLine,"PA",2)||!strncmp(pCharLine,"Pa",2)||!strncmp(pCharLine,"pa",2)) - ParseSection=RAM_PATCH_SECTION; - - if(!strncmp(pCharLine,"DY",2)||!strncmp(pCharLine,"Dy",2)||!strncmp(pCharLine,"dy",2)) - ParseSection=RAM_DYN_MEM_SECTION; - - if(!strncmp(pCharLine,"PS",2)||!strncmp(pCharLine,"Ps",2)||!strncmp(pCharLine,"ps",2)) - ParseSection=RAM_PS_SECTION; - - LineRead = 0; - stReadStatus.uSection = 0; - - continue; - } - - switch(ParseSection) - { - case RAM_PS_SECTION: - { - if (stReadStatus.uSection == 1) //TagID - { - SKIP_BLANKS(pCharLine); - if(uGetInputDataFormat(pCharLine, &stPS_DataFormat)) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("uGetInputDataFormat fail\n")); - if(Buffer != NULL) { - kfree(Buffer); - } - return A_ERROR; - } - //pCharLine +=5; - PsTagEntry[TagCount].TagId = uReadDataInSection(pCharLine, stPS_DataFormat); - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" TAG ID %d \n",PsTagEntry[TagCount].TagId)); - - //AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("tag # %x\n", PsTagEntry[TagCount].TagId); - if (TagCount == 0) - { - StartTagId = PsTagEntry[TagCount].TagId; - } - stReadStatus.uSection = 2; - } - else if (stReadStatus.uSection == 2) //TagLength - { - - if(uGetInputDataFormat(pCharLine, &stPS_DataFormat)) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("uGetInputDataFormat fail \n")); - if(Buffer != NULL) { - kfree(Buffer); - } - return A_ERROR; - } - //pCharLine +=5; - ByteCount = uReadDataInSection(pCharLine, stPS_DataFormat); - - //AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("tag length %x\n", ByteCount)); - if (ByteCount > LINE_SIZE_MAX/2) - { - if(Buffer != NULL) { - kfree(Buffer); - } - return A_ERROR; - } - PsTagEntry[TagCount].TagLen = ByteCount; - PsTagEntry[TagCount].TagData = (u8 *)A_MALLOC(ByteCount); - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" TAG Length %d Tag Index %d \n",PsTagEntry[TagCount].TagLen,TagCount)); - stReadStatus.uSection = 3; - stReadStatus.uLineCount = 0; - } - else if( stReadStatus.uSection == 3) { //Data - - if(stReadStatus.uLineCount == 0) { - if(uGetInputDataFormat(pCharLine,&stPS_DataFormat)) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("uGetInputDataFormat Fail\n")); - if(Buffer != NULL) { - kfree(Buffer); - } - return A_ERROR; - } - //pCharLine +=5; - } - SKIP_BLANKS(pCharLine); - stReadStatus.uCharCount = 0; - if(pCharLine[stReadStatus.uCharCount] == '[') { - while(pCharLine[stReadStatus.uCharCount] != ']' && pCharLine[stReadStatus.uCharCount] != '\0' ) { - stReadStatus.uCharCount++; - } - if(pCharLine[stReadStatus.uCharCount] == ']' ) { - stReadStatus.uCharCount++; - } else { - stReadStatus.uCharCount = 0; - } - } - uReadCount = (ByteCount > BYTES_OF_PS_DATA_PER_LINE)? BYTES_OF_PS_DATA_PER_LINE: ByteCount; - //AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" ")); - if((stPS_DataFormat.eDataType == eHex) && stPS_DataFormat.bIsArray == true) { - while(uReadCount > 0) { - PsTagEntry[TagCount].TagData[stReadStatus.uByteCount] = - (u8)(hex_to_bin(pCharLine[stReadStatus.uCharCount]) << 4) - | (u8)(hex_to_bin(pCharLine[stReadStatus.uCharCount + 1])); - - PsTagEntry[TagCount].TagData[stReadStatus.uByteCount+1] = - (u8)(hex_to_bin(pCharLine[stReadStatus.uCharCount + 3]) << 4) - | (u8)(hex_to_bin(pCharLine[stReadStatus.uCharCount + 4])); - - stReadStatus.uCharCount += 6; // read two bytes, plus a space; - stReadStatus.uByteCount += 2; - uReadCount -= 2; - } - if(ByteCount > BYTES_OF_PS_DATA_PER_LINE) { - ByteCount -= BYTES_OF_PS_DATA_PER_LINE; - } - else { - ByteCount = 0; - } - } - else { - //to be implemented - } - - stReadStatus.uLineCount++; - - if(ByteCount == 0) { - stReadStatus.uSection = 0; - stReadStatus.uCharCount = 0; - stReadStatus.uLineCount = 0; - stReadStatus.uByteCount = 0; - } - else { - stReadStatus.uCharCount = 0; - } - - if((stReadStatus.uSection == 0)&&(++TagCount == RAMPS_MAX_PS_TAGS_PER_FILE)) - { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("\n Buffer over flow PS File too big!!!")); - if(Buffer != NULL) { - kfree(Buffer); - } - return A_ERROR; - //Sleep (3000); - //exit(1); - } - - } - } - - break; - default: - { - if(Buffer != NULL) { - kfree(Buffer); - } - return A_ERROR; - } - break; - } - LineRead++; - } - Tag_Count = TagCount; - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Number of Tags %d\n", Tag_Count)); - } - - - if (TagCount > RAMPS_MAX_PS_TAGS_PER_FILE) - { - - if(Buffer != NULL) { - kfree(Buffer); - } - return A_ERROR; - } - - if(Buffer != NULL) { - kfree(Buffer); - } - return 0; - -} - - - -/********************/ - - -int GetNextTwoChar(u8 *srcbuffer,u32 len, u32 *pos, char *buffer) -{ - unsigned char ch; - - ch = AthReadChar(srcbuffer,len,pos); - if(ch != '\0' && isxdigit(ch)) { - buffer[0] = ch; - } else - { - return A_ERROR; - } - ch = AthReadChar(srcbuffer,len,pos); - if(ch != '\0' && isxdigit(ch)) { - buffer[1] = ch; - } else - { - return A_ERROR; - } - return 0; -} - -int AthDoParsePatch(u8 *patchbuffer, u32 patchlen) -{ - - char Byte[3]; - char Line[MAX_BYTE_LENGTH + 1]; - int ByteCount,ByteCount_Org; - int count; - int i,j,k; - int data; - u32 filepos; - Byte[2] = '\0'; - j = 0; - filepos = 0; - Patch_Count = 0; - - while(NULL != AthGetLine(Line,MAX_BYTE_LENGTH,patchbuffer,patchlen,&filepos)) { - if(strlen(Line) <= 1 || !isxdigit(Line[0])) { - continue; - } else { - break; - } - } - ByteCount = A_STRTOL(Line, NULL, 16); - ByteCount_Org = ByteCount; - - while(ByteCount > MAX_BYTE_LENGTH){ - - /* Handle case when the number of patch buffer is more than the 20K */ - if(MAX_NUM_PATCH_ENTRY == Patch_Count) { - for(i = 0; i < Patch_Count; i++) { - kfree(RamPatch[i].Data); - } - return A_ERROR; - } - RamPatch[Patch_Count].Len= MAX_BYTE_LENGTH; - RamPatch[Patch_Count].Data = (u8 *)A_MALLOC(MAX_BYTE_LENGTH); - Patch_Count ++; - - - ByteCount= ByteCount - MAX_BYTE_LENGTH; - } - - RamPatch[Patch_Count].Len= (ByteCount & 0xFF); - if(ByteCount != 0) { - RamPatch[Patch_Count].Data = (u8 *)A_MALLOC(ByteCount); - Patch_Count ++; - } - count = 0; - while(ByteCount_Org > MAX_BYTE_LENGTH){ - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" Index [%d]\n",j)); - for (i = 0,k=0; i < MAX_BYTE_LENGTH*2; i += 2,k++,count +=2) { - if(GetNextTwoChar(patchbuffer,patchlen,&filepos,Byte) == A_ERROR) { - return A_ERROR; - } - data = A_STRTOUL(&Byte[0], NULL, 16); - RamPatch[j].Data[k] = (data & 0xFF); - - - } - j++; - ByteCount_Org = ByteCount_Org - MAX_BYTE_LENGTH; - } - if(j == 0){ - j++; - } - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" Index [%d]\n",j)); - for (k=0; k < ByteCount_Org; i += 2,k++,count+=2) { - if(GetNextTwoChar(patchbuffer,patchlen,&filepos,Byte) == A_ERROR) { - return A_ERROR; - } - data = A_STRTOUL(Byte, NULL, 16); - RamPatch[j].Data[k] = (data & 0xFF); - - - } - return 0; -} - - -/********************/ -int AthDoParsePS(u8 *srcbuffer, u32 srclen) -{ - int status; - int i; - bool BDADDR_Present = false; - - Tag_Count = 0; - - Total_tag_lenght = 0; - BDADDR = false; - - - status = A_ERROR; - - if(NULL != srcbuffer && srclen != 0) - { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("File Open Operation Successful\n")); - - status = AthParseFilesUnified(srcbuffer,srclen,MB_FILEFORMAT_PATCH); - } - - - - if(Tag_Count == 0){ - Total_tag_lenght = 10; - - } - else{ - for(i=0; i<Tag_Count; i++){ - if(PsTagEntry[i].TagId == 1){ - BDADDR_Present = true; - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BD ADDR is present in Patch File \r\n")); - - } - if(PsTagEntry[i].TagLen % 2 == 1){ - Total_tag_lenght = Total_tag_lenght + PsTagEntry[i].TagLen + 1; - } - else{ - Total_tag_lenght = Total_tag_lenght + PsTagEntry[i].TagLen; - } - - } - } - - if(Tag_Count > 0 && !BDADDR_Present){ - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BD ADDR is not present adding 10 extra bytes \r\n")); - Total_tag_lenght=Total_tag_lenght + 10; - } - Total_tag_lenght = Total_tag_lenght+ 10 + (Tag_Count*4); - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("** Total Length %d\n",Total_tag_lenght)); - - - return status; -} -char *AthGetLine(char *buffer, int maxlen, u8 *srcbuffer,u32 len,u32 *pos) -{ - - int count; - static short flag; - char CharRead; - count = 0; - flag = A_ERROR; - - do - { - CharRead = AthReadChar(srcbuffer,len,pos); - if( CharRead == '\0' ) { - buffer[count+1] = '\0'; - if(count == 0) { - return NULL; - } - else { - return buffer; - } - } - - if(CharRead == 13) { - } else if(CharRead == 10) { - buffer[count] ='\0'; - flag = A_ERROR; - return buffer; - }else { - buffer[count++] = CharRead; - } - - } - while(count < maxlen-1 && CharRead != '\0'); - buffer[count] = '\0'; - - return buffer; -} - -static void LoadHeader(u8 *HCI_PS_Command,u8 opcode,int length,int index){ - - HCI_PS_Command[0]= 0x0B; - HCI_PS_Command[1]= 0xFC; - HCI_PS_Command[2]= length + 4; - HCI_PS_Command[3]= opcode; - HCI_PS_Command[4]= (index & 0xFF); - HCI_PS_Command[5]= ((index>>8) & 0xFF); - HCI_PS_Command[6]= length; -} - -///////////////////////// -// -int AthCreateCommandList(struct ps_cmd_packet **HciPacketList, u32 *numPackets) -{ - - u8 count; - u32 NumcmdEntry = 0; - - u32 Crc = 0; - *numPackets = 0; - - - if(Patch_Count > 0) - Crc |= RAM_PATCH_REGION; - if(Tag_Count > 0) - Crc |= RAM_PS_REGION; - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("PS Thread Started CRC %x Patch Count %d Tag Count %d \n",Crc,Patch_Count,Tag_Count)); - - if(Patch_Count || Tag_Count ){ - NumcmdEntry+=(2 + Patch_Count + Tag_Count); /* CRC Packet + PS Reset Packet + Patch List + PS List*/ - if(Patch_Count > 0) { - NumcmdEntry++; /* Patch Enable Command */ - } - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Num Cmd Entries %d Size %d \r\n",NumcmdEntry,(u32)sizeof(struct ps_cmd_packet) * NumcmdEntry)); - (*HciPacketList) = A_MALLOC(sizeof(struct ps_cmd_packet) * NumcmdEntry); - if(NULL == *HciPacketList) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("memory allocation failed \r\n")); - } - AthPSCreateHCICommand(PS_VERIFY_CRC,Crc,*HciPacketList,numPackets); - if(Patch_Count > 0){ - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("*** Write Patch**** \r\n")); - AthPSCreateHCICommand(WRITE_PATCH,Patch_Count,*HciPacketList,numPackets); - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("*** Enable Patch**** \r\n")); - AthPSCreateHCICommand(ENABLE_PATCH,0,*HciPacketList,numPackets); - } - - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("*** PS Reset**** %d[0x%x] \r\n",PS_RAM_SIZE,PS_RAM_SIZE)); - AthPSCreateHCICommand(PS_RESET,PS_RAM_SIZE,*HciPacketList,numPackets); - if(Tag_Count > 0){ - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("*** PS Write**** \r\n")); - AthPSCreateHCICommand(PS_WRITE,Tag_Count,*HciPacketList,numPackets); - } - } - if(!BDADDR){ - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BD ADDR not present \r\n")); - - } - for(count = 0; count < Patch_Count; count++) { - - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Freeing Patch Buffer %d \r\n",count)); - kfree(RamPatch[count].Data); - } - - for(count = 0; count < Tag_Count; count++) { - - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Freeing PS Buffer %d \r\n",count)); - kfree(PsTagEntry[count].TagData); - } - -/* - * SDIO Transport uses synchronous mode of data transfer - * So, AthPSOperations() call returns only after receiving the - * command complete event. - */ - return *numPackets; -} - - -//////////////////////// - -///////////// -static int AthPSCreateHCICommand(u8 Opcode, u32 Param1,struct ps_cmd_packet *PSPatchPacket,u32 *index) -{ - u8 *HCI_PS_Command; - u32 Length; - int i,j; - - switch(Opcode) - { - case WRITE_PATCH: - - - for(i=0;i< Param1;i++){ - - HCI_PS_Command = (u8 *) A_MALLOC(RamPatch[i].Len+HCI_COMMAND_HEADER); - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Allocated Buffer Size %d\n",RamPatch[i].Len+HCI_COMMAND_HEADER)); - if(HCI_PS_Command == NULL){ - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MALLOC Failed\r\n")); - return A_ERROR; - } - memset (HCI_PS_Command, 0, RamPatch[i].Len+HCI_COMMAND_HEADER); - LoadHeader(HCI_PS_Command,Opcode,RamPatch[i].Len,i); - for(j=0;j<RamPatch[i].Len;j++){ - HCI_PS_Command[HCI_COMMAND_HEADER+j]=RamPatch[i].Data[j]; - } - PSPatchPacket[*index].Hcipacket = HCI_PS_Command; - PSPatchPacket[*index].packetLen = RamPatch[i].Len+HCI_COMMAND_HEADER; - (*index)++; - - - } - - break; - - case ENABLE_PATCH: - - - Length = 0; - i= 0; - HCI_PS_Command = (u8 *) A_MALLOC(Length+HCI_COMMAND_HEADER); - if(HCI_PS_Command == NULL){ - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MALLOC Failed\r\n")); - return A_ERROR; - } - - memset (HCI_PS_Command, 0, Length+HCI_COMMAND_HEADER); - LoadHeader(HCI_PS_Command,Opcode,Length,i); - PSPatchPacket[*index].Hcipacket = HCI_PS_Command; - PSPatchPacket[*index].packetLen = Length+HCI_COMMAND_HEADER; - (*index)++; - - break; - - case PS_RESET: - Length = 0x06; - i=0; - HCI_PS_Command = (u8 *) A_MALLOC(Length+HCI_COMMAND_HEADER); - if(HCI_PS_Command == NULL){ - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MALLOC Failed\r\n")); - return A_ERROR; - } - memset (HCI_PS_Command, 0, Length+HCI_COMMAND_HEADER); - LoadHeader(HCI_PS_Command,Opcode,Length,i); - HCI_PS_Command[7]= 0x00; - HCI_PS_Command[Length+HCI_COMMAND_HEADER -2]= (Param1 & 0xFF); - HCI_PS_Command[Length+HCI_COMMAND_HEADER -1]= ((Param1 >> 8) & 0xFF); - PSPatchPacket[*index].Hcipacket = HCI_PS_Command; - PSPatchPacket[*index].packetLen = Length+HCI_COMMAND_HEADER; - (*index)++; - - break; - - case PS_WRITE: - for(i=0;i< Param1;i++){ - if(PsTagEntry[i].TagId ==1) - BDADDR = true; - - HCI_PS_Command = (u8 *) A_MALLOC(PsTagEntry[i].TagLen+HCI_COMMAND_HEADER); - if(HCI_PS_Command == NULL){ - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MALLOC Failed\r\n")); - return A_ERROR; - } - - memset (HCI_PS_Command, 0, PsTagEntry[i].TagLen+HCI_COMMAND_HEADER); - LoadHeader(HCI_PS_Command,Opcode,PsTagEntry[i].TagLen,PsTagEntry[i].TagId); - - for(j=0;j<PsTagEntry[i].TagLen;j++){ - HCI_PS_Command[HCI_COMMAND_HEADER+j]=PsTagEntry[i].TagData[j]; - } - - PSPatchPacket[*index].Hcipacket = HCI_PS_Command; - PSPatchPacket[*index].packetLen = PsTagEntry[i].TagLen+HCI_COMMAND_HEADER; - (*index)++; - - } - - break; - - - case PS_VERIFY_CRC: - Length = 0x0; - - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("VALUE of CRC:%d At index %d\r\n",Param1,*index)); - - HCI_PS_Command = (u8 *) A_MALLOC(Length+HCI_COMMAND_HEADER); - if(HCI_PS_Command == NULL){ - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("MALLOC Failed\r\n")); - return A_ERROR; - } - memset (HCI_PS_Command, 0, Length+HCI_COMMAND_HEADER); - LoadHeader(HCI_PS_Command,Opcode,Length,Param1); - - PSPatchPacket[*index].Hcipacket = HCI_PS_Command; - PSPatchPacket[*index].packetLen = Length+HCI_COMMAND_HEADER; - (*index)++; - - break; - - case CHANGE_BDADDR: - break; - } - return 0; -} -int AthFreeCommandList(struct ps_cmd_packet **HciPacketList, u32 numPackets) -{ - int i; - if(*HciPacketList == NULL) { - return A_ERROR; - } - for(i = 0; i < numPackets;i++) { - kfree((*HciPacketList)[i].Hcipacket); - } - kfree(*HciPacketList); - return 0; -} diff --git a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h b/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h deleted file mode 100644 index 4e0f2f7..0000000 --- a/drivers/staging/ath6kl/miscdrv/ar3kps/ar3kpsparser.h +++ /dev/null @@ -1,113 +0,0 @@ -//------------------------------------------------------------------------------ -// -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// Permission to use, copy, modify, and/or distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -// -// -//------------------------------------------------------------------------------ -// -// This file is the include file for Atheros PS and patch parser. -// It implements APIs to parse data buffer with patch and PS information and convert it to HCI commands. -// - -#ifndef __AR3KPSPARSER_H -#define __AR3KPSPARSER_H - - - - -#include <linux/fs.h> -#include <linux/slab.h> -#include "athdefs.h" -#ifdef HCI_TRANSPORT_SDIO -#include "a_config.h" -#include "a_osapi.h" -#define ATH_MODULE_NAME misc -#include "a_debug.h" -#include "common_drv.h" -#include "hci_transport_api.h" -#include "ar3kconfig.h" -#else -#ifndef A_PRINTF -#define A_PRINTF(args...) printk(KERN_ALERT args) -#endif /* A_PRINTF */ -#include "debug_linux.h" - -/* Helper data type declaration */ - -#define ATH_DEBUG_ERR (1 << 0) -#define ATH_DEBUG_WARN (1 << 1) -#define ATH_DEBUG_INFO (1 << 2) - - - -#define false 0 -#define true 1 - -#ifndef A_MALLOC -#define A_MALLOC(size) kmalloc((size),GFP_KERNEL) -#endif /* A_MALLOC */ -#endif /* HCI_TRANSPORT_UART */ - -/* String manipulation APIs */ -#ifndef A_STRTOUL -#define A_STRTOUL simple_strtoul -#endif /* A_STRTOL */ - -#ifndef A_STRTOL -#define A_STRTOL simple_strtol -#endif /* A_STRTOL */ - - -/* The maximum number of bytes possible in a patch entry */ -#define MAX_PATCH_SIZE 20000 - -/* Maximum HCI packets that will be formed from the Patch file */ -#define MAX_NUM_PATCH_ENTRY (MAX_PATCH_SIZE/MAX_BYTE_LENGTH) + 1 - - - - - - - -struct ps_cmd_packet -{ - u8 *Hcipacket; - int packetLen; -}; - -/* Parses a Patch information buffer and store it in global structure */ -int AthDoParsePatch(u8 *, u32 ); - -/* parses a PS information buffer and stores it in a global structure */ -int AthDoParsePS(u8 *, u32 ); - -/* - * Uses the output of Both AthDoParsePS and AthDoParsePatch APIs to form HCI command array with - * all the PS and patch commands. - * The list will have the below mentioned commands in order. - * CRC command packet - * Download patch command(s) - * Enable patch Command - * PS Reset Command - * PS Tag Command(s) - * - */ -int AthCreateCommandList(struct ps_cmd_packet **, u32 *); - -/* Cleanup the dynamically allicated HCI command list */ -int AthFreeCommandList(struct ps_cmd_packet **HciPacketList, u32 numPackets); -#endif /* __AR3KPSPARSER_H */ diff --git a/drivers/staging/ath6kl/miscdrv/common_drv.c b/drivers/staging/ath6kl/miscdrv/common_drv.c deleted file mode 100644 index 1ce539a..0000000 --- a/drivers/staging/ath6kl/miscdrv/common_drv.c +++ /dev/null @@ -1,910 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="common_drv.c" company="Atheros"> -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Author(s): ="Atheros" -//============================================================================== - -#include "a_config.h" -#include "athdefs.h" - -#include "hw/mbox_host_reg.h" -#include "gpio_reg.h" -#include "hw/rtc_reg.h" -#include "hw/mbox_reg.h" -#include "hw/apb_map.h" - -#include "a_osapi.h" -#include "targaddrs.h" -#include "hif.h" -#include "htc_api.h" -#include "wmi.h" -#include "bmi.h" -#include "bmi_msg.h" -#include "common_drv.h" -#define ATH_MODULE_NAME misc -#include "a_debug.h" -#include "ar6000_diag.h" - -static ATH_DEBUG_MODULE_DBG_INFO *g_pModuleInfoHead = NULL; -static A_MUTEX_T g_ModuleListLock; -static bool g_ModuleDebugInit = false; - -#ifdef ATH_DEBUG_MODULE - -ATH_DEBUG_INSTANTIATE_MODULE_VAR(misc, - "misc", - "Common and misc APIs", - ATH_DEBUG_MASK_DEFAULTS, - 0, - NULL); - -#endif - -#define HOST_INTEREST_ITEM_ADDRESS(target, item) \ - ((((target) == TARGET_TYPE_AR6002) ? AR6002_HOST_INTEREST_ITEM_ADDRESS(item) : \ - (((target) == TARGET_TYPE_AR6003) ? AR6003_HOST_INTEREST_ITEM_ADDRESS(item) : 0))) - - -#define AR6001_LOCAL_COUNT_ADDRESS 0x0c014080 -#define AR6002_LOCAL_COUNT_ADDRESS 0x00018080 -#define AR6003_LOCAL_COUNT_ADDRESS 0x00018080 -#define CPU_DBG_SEL_ADDRESS 0x00000483 -#define CPU_DBG_ADDRESS 0x00000484 - -static u8 custDataAR6002[AR6002_CUST_DATA_SIZE]; -static u8 custDataAR6003[AR6003_CUST_DATA_SIZE]; - -/* Compile the 4BYTE version of the window register setup routine, - * This mitigates host interconnect issues with non-4byte aligned bus requests, some - * interconnects use bus adapters that impose strict limitations. - * Since diag window access is not intended for performance critical operations, the 4byte mode should - * be satisfactory even though it generates 4X the bus activity. */ - -#ifdef USE_4BYTE_REGISTER_ACCESS - - /* set the window address register (using 4-byte register access ). */ -int ar6000_SetAddressWindowRegister(struct hif_device *hifDevice, u32 RegisterAddr, u32 Address) -{ - int status; - u8 addrValue[4]; - s32 i; - - /* write bytes 1,2,3 of the register to set the upper address bytes, the LSB is written - * last to initiate the access cycle */ - - for (i = 1; i <= 3; i++) { - /* fill the buffer with the address byte value we want to hit 4 times*/ - addrValue[0] = ((u8 *)&Address)[i]; - addrValue[1] = addrValue[0]; - addrValue[2] = addrValue[0]; - addrValue[3] = addrValue[0]; - - /* hit each byte of the register address with a 4-byte write operation to the same address, - * this is a harmless operation */ - status = HIFReadWrite(hifDevice, - RegisterAddr+i, - addrValue, - 4, - HIF_WR_SYNC_BYTE_FIX, - NULL); - if (status) { - break; - } - } - - if (status) { - AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write initial bytes of 0x%x to window reg: 0x%X \n", - Address, RegisterAddr)); - return status; - } - - /* write the address register again, this time write the whole 4-byte value. - * The effect here is that the LSB write causes the cycle to start, the extra - * 3 byte write to bytes 1,2,3 has no effect since we are writing the same values again */ - status = HIFReadWrite(hifDevice, - RegisterAddr, - (u8 *)(&Address), - 4, - HIF_WR_SYNC_BYTE_INC, - NULL); - - if (status) { - AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write 0x%x to window reg: 0x%X \n", - Address, RegisterAddr)); - return status; - } - - return 0; - - - -} - - -#else - - /* set the window address register */ -int ar6000_SetAddressWindowRegister(struct hif_device *hifDevice, u32 RegisterAddr, u32 Address) -{ - int status; - - /* write bytes 1,2,3 of the register to set the upper address bytes, the LSB is written - * last to initiate the access cycle */ - status = HIFReadWrite(hifDevice, - RegisterAddr+1, /* write upper 3 bytes */ - ((u8 *)(&Address))+1, - sizeof(u32)-1, - HIF_WR_SYNC_BYTE_INC, - NULL); - - if (status) { - AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write initial bytes of 0x%x to window reg: 0x%X \n", - RegisterAddr, Address)); - return status; - } - - /* write the LSB of the register, this initiates the operation */ - status = HIFReadWrite(hifDevice, - RegisterAddr, - (u8 *)(&Address), - sizeof(u8), - HIF_WR_SYNC_BYTE_INC, - NULL); - - if (status) { - AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write 0x%x to window reg: 0x%X \n", - RegisterAddr, Address)); - return status; - } - - return 0; -} - -#endif - -/* - * Read from the AR6000 through its diagnostic window. - * No cooperation from the Target is required for this. - */ -int -ar6000_ReadRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data) -{ - int status; - - /* set window register to start read cycle */ - status = ar6000_SetAddressWindowRegister(hifDevice, - WINDOW_READ_ADDR_ADDRESS, - *address); - - if (status) { - return status; - } - - /* read the data */ - status = HIFReadWrite(hifDevice, - WINDOW_DATA_ADDRESS, - (u8 *)data, - sizeof(u32), - HIF_RD_SYNC_BYTE_INC, - NULL); - if (status) { - AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot read from WINDOW_DATA_ADDRESS\n")); - return status; - } - - return status; -} - - -/* - * Write to the AR6000 through its diagnostic window. - * No cooperation from the Target is required for this. - */ -int -ar6000_WriteRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data) -{ - int status; - - /* set write data */ - status = HIFReadWrite(hifDevice, - WINDOW_DATA_ADDRESS, - (u8 *)data, - sizeof(u32), - HIF_WR_SYNC_BYTE_INC, - NULL); - if (status) { - AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write 0x%x to WINDOW_DATA_ADDRESS\n", *data)); - return status; - } - - /* set window register, which starts the write cycle */ - return ar6000_SetAddressWindowRegister(hifDevice, - WINDOW_WRITE_ADDR_ADDRESS, - *address); - } - -int -ar6000_ReadDataDiag(struct hif_device *hifDevice, u32 address, - u8 *data, u32 length) -{ - u32 count; - int status = 0; - - for (count = 0; count < length; count += 4, address += 4) { - if ((status = ar6000_ReadRegDiag(hifDevice, &address, - (u32 *)&data[count])) != 0) - { - break; - } - } - - return status; -} - -int -ar6000_WriteDataDiag(struct hif_device *hifDevice, u32 address, - u8 *data, u32 length) -{ - u32 count; - int status = 0; - - for (count = 0; count < length; count += 4, address += 4) { - if ((status = ar6000_WriteRegDiag(hifDevice, &address, - (u32 *)&data[count])) != 0) - { - break; - } - } - - return status; -} - -int -ar6k_ReadTargetRegister(struct hif_device *hifDevice, int regsel, u32 *regval) -{ - int status; - u8 vals[4]; - u8 register_selection[4]; - - register_selection[0] = register_selection[1] = register_selection[2] = register_selection[3] = (regsel & 0xff); - status = HIFReadWrite(hifDevice, - CPU_DBG_SEL_ADDRESS, - register_selection, - 4, - HIF_WR_SYNC_BYTE_FIX, - NULL); - - if (status) { - AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write CPU_DBG_SEL (%d)\n", regsel)); - return status; - } - - status = HIFReadWrite(hifDevice, - CPU_DBG_ADDRESS, - (u8 *)vals, - sizeof(vals), - HIF_RD_SYNC_BYTE_INC, - NULL); - if (status) { - AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot read from CPU_DBG_ADDRESS\n")); - return status; - } - - *regval = vals[0]<<0 | vals[1]<<8 | vals[2]<<16 | vals[3]<<24; - - return status; -} - -void -ar6k_FetchTargetRegs(struct hif_device *hifDevice, u32 *targregs) -{ - int i; - u32 val; - - for (i=0; i<AR6003_FETCH_TARG_REGS_COUNT; i++) { - val=0xffffffff; - (void)ar6k_ReadTargetRegister(hifDevice, i, &val); - targregs[i] = val; - } -} - -#if 0 -static int -_do_write_diag(struct hif_device *hifDevice, u32 addr, u32 value) -{ - int status; - - status = ar6000_WriteRegDiag(hifDevice, &addr, &value); - if (status) - { - AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot force Target to execute ROM!\n")); - } - - return status; -} -#endif - - -/* - * Delay up to wait_msecs millisecs to allow Target to enter BMI phase, - * which is a good sign that it's alive and well. This is used after - * explicitly forcing the Target to reset. - * - * The wait_msecs time should be sufficiently long to cover any reasonable - * boot-time delay. For instance, AR6001 firmware allow one second for a - * low frequency crystal to settle before it calibrates the refclk frequency. - * - * TBD: Might want to add special handling for AR6K_OPTION_BMI_DISABLE. - */ -#if 0 -static int -_delay_until_target_alive(struct hif_device *hifDevice, s32 wait_msecs, u32 TargetType) -{ - s32 actual_wait; - s32 i; - u32 address; - - actual_wait = 0; - - /* Hardcode the address of LOCAL_COUNT_ADDRESS based on the target type */ - if (TargetType == TARGET_TYPE_AR6002) { - address = AR6002_LOCAL_COUNT_ADDRESS; - } else if (TargetType == TARGET_TYPE_AR6003) { - address = AR6003_LOCAL_COUNT_ADDRESS; - } else { - A_ASSERT(0); - } - address += 0x10; - for (i=0; actual_wait < wait_msecs; i++) { - u32 data; - - A_MDELAY(100); - actual_wait += 100; - - data = 0; - if (ar6000_ReadRegDiag(hifDevice, &address, &data) != 0) { - return A_ERROR; - } - - if (data != 0) { - /* No need to wait longer -- we have a BMI credit */ - return 0; - } - } - return A_ERROR; /* timed out */ -} -#endif - -#define AR6001_RESET_CONTROL_ADDRESS 0x0C000000 -#define AR6002_RESET_CONTROL_ADDRESS 0x00004000 -#define AR6003_RESET_CONTROL_ADDRESS 0x00004000 -/* reset device */ -int ar6000_reset_device(struct hif_device *hifDevice, u32 TargetType, bool waitForCompletion, bool coldReset) -{ - int status = 0; - u32 address; - u32 data; - - do { -// Workaround BEGIN - // address = RESET_CONTROL_ADDRESS; - - if (coldReset) { - data = RESET_CONTROL_COLD_RST_MASK; - } - else { - data = RESET_CONTROL_MBOX_RST_MASK; - } - - /* Hardcode the address of RESET_CONTROL_ADDRESS based on the target type */ - if (TargetType == TARGET_TYPE_AR6002) { - address = AR6002_RESET_CONTROL_ADDRESS; - } else if (TargetType == TARGET_TYPE_AR6003) { - address = AR6003_RESET_CONTROL_ADDRESS; - } else { - A_ASSERT(0); - } - - - status = ar6000_WriteRegDiag(hifDevice, &address, &data); - - if (status) { - break; - } - - if (!waitForCompletion) { - break; - } - -#if 0 - /* Up to 2 second delay to allow things to settle down */ - (void)_delay_until_target_alive(hifDevice, 2000, TargetType); - - /* - * Read back the RESET CAUSE register to ensure that the cold reset - * went through. - */ - - // address = RESET_CAUSE_ADDRESS; - /* Hardcode the address of RESET_CAUSE_ADDRESS based on the target type */ - if (TargetType == TARGET_TYPE_AR6002) { - address = 0x000040C0; - } else if (TargetType == TARGET_TYPE_AR6003) { - address = 0x000040C0; - } else { - A_ASSERT(0); - } - - data = 0; - status = ar6000_ReadRegDiag(hifDevice, &address, &data); - - if (status) { - break; - } - - AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Reset Cause readback: 0x%X \n",data)); - data &= RESET_CAUSE_LAST_MASK; - if (data != 2) { - AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Unable to cold reset the target \n")); - } -#endif -// Workaroud END - - } while (false); - - if (status) { - AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Failed to reset target \n")); - } - - return 0; -} - -/* This should be called in BMI phase after firmware is downloaded */ -void -ar6000_copy_cust_data_from_target(struct hif_device *hifDevice, u32 TargetType) -{ - u32 eepHeaderAddr; - u8 AR6003CustDataShadow[AR6003_CUST_DATA_SIZE+4]; - s32 i; - - if (BMIReadMemory(hifDevice, - HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_board_data), - (u8 *)&eepHeaderAddr, - 4)!= 0) - { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMIReadMemory for reading board data address failed \n")); - return; - } - - if (TargetType == TARGET_TYPE_AR6003) { - eepHeaderAddr += 36; /* AR6003 customer data section offset is 37 */ - - for (i=0; i<AR6003_CUST_DATA_SIZE+4; i+=4){ - if (BMIReadSOCRegister(hifDevice, eepHeaderAddr, (u32 *)&AR6003CustDataShadow[i])!= 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMIReadSOCRegister () failed \n")); - return ; - } - eepHeaderAddr +=4; - } - - memcpy(custDataAR6003, AR6003CustDataShadow+1, AR6003_CUST_DATA_SIZE); - } - - if (TargetType == TARGET_TYPE_AR6002) { - eepHeaderAddr += 64; /* AR6002 customer data sectioin offset is 64 */ - - for (i=0; i<AR6002_CUST_DATA_SIZE; i+=4){ - if (BMIReadSOCRegister(hifDevice, eepHeaderAddr, (u32 *)&custDataAR6002[i])!= 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMIReadSOCRegister () failed \n")); - return ; - } - eepHeaderAddr +=4; - } - } - - return; -} - -/* This is the function to call when need to use the cust data */ -u8 *ar6000_get_cust_data_buffer(u32 TargetType) -{ - if (TargetType == TARGET_TYPE_AR6003) - return custDataAR6003; - - if (TargetType == TARGET_TYPE_AR6002) - return custDataAR6002; - - return NULL; -} - -#define REG_DUMP_COUNT_AR6001 38 /* WORDs, derived from AR600x_regdump.h */ -#define REG_DUMP_COUNT_AR6002 60 -#define REG_DUMP_COUNT_AR6003 60 -#define REGISTER_DUMP_LEN_MAX 60 -#if REG_DUMP_COUNT_AR6001 > REGISTER_DUMP_LEN_MAX -#error "REG_DUMP_COUNT_AR6001 too large" -#endif -#if REG_DUMP_COUNT_AR6002 > REGISTER_DUMP_LEN_MAX -#error "REG_DUMP_COUNT_AR6002 too large" -#endif -#if REG_DUMP_COUNT_AR6003 > REGISTER_DUMP_LEN_MAX -#error "REG_DUMP_COUNT_AR6003 too large" -#endif - - -void ar6000_dump_target_assert_info(struct hif_device *hifDevice, u32 TargetType) -{ - u32 address; - u32 regDumpArea = 0; - int status; - u32 regDumpValues[REGISTER_DUMP_LEN_MAX]; - u32 regDumpCount = 0; - u32 i; - - do { - - /* the reg dump pointer is copied to the host interest area */ - address = HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_failure_state); - address = TARG_VTOP(TargetType, address); - - if (TargetType == TARGET_TYPE_AR6002) { - regDumpCount = REG_DUMP_COUNT_AR6002; - } else if (TargetType == TARGET_TYPE_AR6003) { - regDumpCount = REG_DUMP_COUNT_AR6003; - } else { - A_ASSERT(0); - } - - /* read RAM location through diagnostic window */ - status = ar6000_ReadRegDiag(hifDevice, &address, ®DumpArea); - - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Failed to get ptr to register dump area \n")); - break; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Location of register dump data: 0x%X \n",regDumpArea)); - - if (regDumpArea == 0) { - /* no reg dump */ - break; - } - - regDumpArea = TARG_VTOP(TargetType, regDumpArea); - - /* fetch register dump data */ - status = ar6000_ReadDataDiag(hifDevice, - regDumpArea, - (u8 *)®DumpValues[0], - regDumpCount * (sizeof(u32))); - - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Failed to get register dump \n")); - break; - } - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR6K: Register Dump: \n")); - - for (i = 0; i < regDumpCount; i++) { - //ATHR_DISPLAY_MSG (_T(" %d : 0x%8.8X \n"), i, regDumpValues[i]); - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" %d : 0x%8.8X \n",i, regDumpValues[i])); - -#ifdef UNDER_CE - /* - * For Every logPrintf() Open the File so that in case of Crashes - * We will have until the Last Message Flushed on to the File - * So use logPrintf Sparingly..!! - */ - tgtassertPrintf (ATH_DEBUG_TRC," %d: 0x%8.8X \n",i, regDumpValues[i]); -#endif - } - - } while (false); - -} - -/* set HTC/Mbox operational parameters, this can only be called when the target is in the - * BMI phase */ -int ar6000_set_htc_params(struct hif_device *hifDevice, - u32 TargetType, - u32 MboxIsrYieldValue, - u8 HtcControlBuffers) -{ - int status; - u32 blocksizes[HTC_MAILBOX_NUM_MAX]; - - do { - /* get the block sizes */ - status = HIFConfigureDevice(hifDevice, HIF_DEVICE_GET_MBOX_BLOCK_SIZE, - blocksizes, sizeof(blocksizes)); - - if (status) { - AR_DEBUG_PRINTF(ATH_LOG_ERR,("Failed to get block size info from HIF layer...\n")); - break; - } - /* note: we actually get the block size for mailbox 1, for SDIO the block - * size on mailbox 0 is artificially set to 1 */ - /* must be a power of 2 */ - A_ASSERT((blocksizes[1] & (blocksizes[1] - 1)) == 0); - - if (HtcControlBuffers != 0) { - /* set override for number of control buffers to use */ - blocksizes[1] |= ((u32)HtcControlBuffers) << 16; - } - - /* set the host interest area for the block size */ - status = BMIWriteMemory(hifDevice, - HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_mbox_io_block_sz), - (u8 *)&blocksizes[1], - 4); - - if (status) { - AR_DEBUG_PRINTF(ATH_LOG_ERR,("BMIWriteMemory for IO block size failed \n")); - break; - } - - AR_DEBUG_PRINTF(ATH_LOG_INF,("Block Size Set: %d (target address:0x%X)\n", - blocksizes[1], HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_mbox_io_block_sz))); - - if (MboxIsrYieldValue != 0) { - /* set the host interest area for the mbox ISR yield limit */ - status = BMIWriteMemory(hifDevice, - HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_mbox_isr_yield_limit), - (u8 *)&MboxIsrYieldValue, - 4); - - if (status) { - AR_DEBUG_PRINTF(ATH_LOG_ERR,("BMIWriteMemory for yield limit failed \n")); - break; - } - } - - } while (false); - - return status; -} - -void DebugDumpBytes(u8 *buffer, u16 length, char *pDescription) -{ - char stream[60]; - char byteOffsetStr[10]; - u32 i; - u16 offset, count, byteOffset; - - A_PRINTF("<---------Dumping %d Bytes : %s ------>\n", length, pDescription); - - count = 0; - offset = 0; - byteOffset = 0; - for(i = 0; i < length; i++) { - A_SPRINTF(stream + offset, "%2.2X ", buffer[i]); - count ++; - offset += 3; - - if(count == 16) { - count = 0; - offset = 0; - A_SPRINTF(byteOffsetStr,"%4.4X",byteOffset); - A_PRINTF("[%s]: %s\n", byteOffsetStr, stream); - A_MEMZERO(stream, 60); - byteOffset += 16; - } - } - - if(offset != 0) { - A_SPRINTF(byteOffsetStr,"%4.4X",byteOffset); - A_PRINTF("[%s]: %s\n", byteOffsetStr, stream); - } - - A_PRINTF("<------------------------------------------------->\n"); -} - -void a_dump_module_debug_info(ATH_DEBUG_MODULE_DBG_INFO *pInfo) -{ - int i; - struct ath_debug_mask_description *pDesc; - - if (pInfo == NULL) { - return; - } - - pDesc = pInfo->pMaskDescriptions; - - A_PRINTF("========================================================\n\n"); - A_PRINTF("Module Debug Info => Name : %s \n", pInfo->ModuleName); - A_PRINTF(" => Descr. : %s \n", pInfo->ModuleDescription); - A_PRINTF("\n Current mask => 0x%8.8X \n", pInfo->CurrentMask); - A_PRINTF("\n Avail. Debug Masks :\n\n"); - - for (i = 0; i < pInfo->MaxDescriptions; i++,pDesc++) { - A_PRINTF(" => 0x%8.8X -- %s \n", pDesc->Mask, pDesc->Description); - } - - if (0 == i) { - A_PRINTF(" => * none defined * \n"); - } - - A_PRINTF("\n Standard Debug Masks :\n\n"); - /* print standard masks */ - A_PRINTF(" => 0x%8.8X -- Errors \n", ATH_DEBUG_ERR); - A_PRINTF(" => 0x%8.8X -- Warnings \n", ATH_DEBUG_WARN); - A_PRINTF(" => 0x%8.8X -- Informational \n", ATH_DEBUG_INFO); - A_PRINTF(" => 0x%8.8X -- Tracing \n", ATH_DEBUG_TRC); - A_PRINTF("\n========================================================\n"); - -} - - -static ATH_DEBUG_MODULE_DBG_INFO *FindModule(char *module_name) -{ - ATH_DEBUG_MODULE_DBG_INFO *pInfo = g_pModuleInfoHead; - - if (!g_ModuleDebugInit) { - return NULL; - } - - while (pInfo != NULL) { - /* TODO: need to use something other than strlen */ - if (memcmp(pInfo->ModuleName,module_name,strlen(module_name)) == 0) { - break; - } - pInfo = pInfo->pNext; - } - - return pInfo; -} - - -void a_register_module_debug_info(ATH_DEBUG_MODULE_DBG_INFO *pInfo) -{ - if (!g_ModuleDebugInit) { - return; - } - - A_MUTEX_LOCK(&g_ModuleListLock); - - if (!(pInfo->Flags & ATH_DEBUG_INFO_FLAGS_REGISTERED)) { - if (g_pModuleInfoHead == NULL) { - g_pModuleInfoHead = pInfo; - } else { - pInfo->pNext = g_pModuleInfoHead; - g_pModuleInfoHead = pInfo; - } - pInfo->Flags |= ATH_DEBUG_INFO_FLAGS_REGISTERED; - } - - A_MUTEX_UNLOCK(&g_ModuleListLock); -} - -void a_dump_module_debug_info_by_name(char *module_name) -{ - ATH_DEBUG_MODULE_DBG_INFO *pInfo = g_pModuleInfoHead; - - if (!g_ModuleDebugInit) { - return; - } - - if (memcmp(module_name,"all",3) == 0) { - /* dump all */ - while (pInfo != NULL) { - a_dump_module_debug_info(pInfo); - pInfo = pInfo->pNext; - } - return; - } - - pInfo = FindModule(module_name); - - if (pInfo != NULL) { - a_dump_module_debug_info(pInfo); - } - -} - -int a_get_module_mask(char *module_name, u32 *pMask) -{ - ATH_DEBUG_MODULE_DBG_INFO *pInfo = FindModule(module_name); - - if (NULL == pInfo) { - return A_ERROR; - } - - *pMask = pInfo->CurrentMask; - return 0; -} - -int a_set_module_mask(char *module_name, u32 Mask) -{ - ATH_DEBUG_MODULE_DBG_INFO *pInfo = FindModule(module_name); - - if (NULL == pInfo) { - return A_ERROR; - } - - pInfo->CurrentMask = Mask; - A_PRINTF("Module %s, new mask: 0x%8.8X \n",module_name,pInfo->CurrentMask); - return 0; -} - - -void a_module_debug_support_init(void) -{ - if (g_ModuleDebugInit) { - return; - } - A_MUTEX_INIT(&g_ModuleListLock); - g_pModuleInfoHead = NULL; - g_ModuleDebugInit = true; - A_REGISTER_MODULE_DEBUG_INFO(misc); -} - -void a_module_debug_support_cleanup(void) -{ - ATH_DEBUG_MODULE_DBG_INFO *pInfo = g_pModuleInfoHead; - ATH_DEBUG_MODULE_DBG_INFO *pCur; - - if (!g_ModuleDebugInit) { - return; - } - - g_ModuleDebugInit = false; - - A_MUTEX_LOCK(&g_ModuleListLock); - - while (pInfo != NULL) { - pCur = pInfo; - pInfo = pInfo->pNext; - pCur->pNext = NULL; - /* clear registered flag */ - pCur->Flags &= ~ATH_DEBUG_INFO_FLAGS_REGISTERED; - } - - A_MUTEX_UNLOCK(&g_ModuleListLock); - - A_MUTEX_DELETE(&g_ModuleListLock); - g_pModuleInfoHead = NULL; -} - - /* can only be called during bmi init stage */ -int ar6000_set_hci_bridge_flags(struct hif_device *hifDevice, - u32 TargetType, - u32 Flags) -{ - int status = 0; - - do { - - if (TargetType != TARGET_TYPE_AR6003) { - AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("Target Type:%d, does not support HCI bridging! \n", - TargetType)); - break; - } - - /* set hci bridge flags */ - status = BMIWriteMemory(hifDevice, - HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_hci_bridge_flags), - (u8 *)&Flags, - 4); - - - } while (false); - - return status; -} - diff --git a/drivers/staging/ath6kl/miscdrv/credit_dist.c b/drivers/staging/ath6kl/miscdrv/credit_dist.c deleted file mode 100644 index c777e98..0000000 --- a/drivers/staging/ath6kl/miscdrv/credit_dist.c +++ /dev/null @@ -1,417 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="credit_dist.c" company="Atheros"> -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Author(s): ="Atheros" -//============================================================================== - -#include "a_config.h" -#include "athdefs.h" -#include "a_osapi.h" -#define ATH_MODULE_NAME misc -#include "a_debug.h" -#include "htc_api.h" -#include "common_drv.h" - -/********* CREDIT DISTRIBUTION FUNCTIONS ******************************************/ - -#define NO_VO_SERVICE 1 /* currently WMI only uses 3 data streams, so we leave VO service inactive */ -#define CONFIG_GIVE_LOW_PRIORITY_STREAMS_MIN_CREDITS 1 - -#ifdef NO_VO_SERVICE -#define DATA_SVCS_USED 3 -#else -#define DATA_SVCS_USED 4 -#endif - -static void RedistributeCredits(struct common_credit_state_info *pCredInfo, - struct htc_endpoint_credit_dist *pEPDistList); - -static void SeekCredits(struct common_credit_state_info *pCredInfo, - struct htc_endpoint_credit_dist *pEPDistList); - -/* reduce an ep's credits back to a set limit */ -static INLINE void ReduceCredits(struct common_credit_state_info *pCredInfo, - struct htc_endpoint_credit_dist *pEpDist, - int Limit) -{ - int credits; - - /* set the new limit */ - pEpDist->TxCreditsAssigned = Limit; - - if (pEpDist->TxCredits <= Limit) { - return; - } - - /* figure out how much to take away */ - credits = pEpDist->TxCredits - Limit; - /* take them away */ - pEpDist->TxCredits -= credits; - pCredInfo->CurrentFreeCredits += credits; -} - -/* give an endpoint some credits from the free credit pool */ -#define GiveCredits(pCredInfo,pEpDist,credits) \ -{ \ - (pEpDist)->TxCredits += (credits); \ - (pEpDist)->TxCreditsAssigned += (credits); \ - (pCredInfo)->CurrentFreeCredits -= (credits); \ -} - - -/* default credit init callback. - * This function is called in the context of HTCStart() to setup initial (application-specific) - * credit distributions */ -static void ar6000_credit_init(void *Context, - struct htc_endpoint_credit_dist *pEPList, - int TotalCredits) -{ - struct htc_endpoint_credit_dist *pCurEpDist; - int count; - struct common_credit_state_info *pCredInfo = (struct common_credit_state_info *)Context; - - pCredInfo->CurrentFreeCredits = TotalCredits; - pCredInfo->TotalAvailableCredits = TotalCredits; - - pCurEpDist = pEPList; - - /* run through the list and initialize */ - while (pCurEpDist != NULL) { - - /* set minimums for each endpoint */ - pCurEpDist->TxCreditsMin = pCurEpDist->TxCreditsPerMaxMsg; - -#ifdef CONFIG_GIVE_LOW_PRIORITY_STREAMS_MIN_CREDITS - - if (TotalCredits > 4) - { - if ((pCurEpDist->ServiceID == WMI_DATA_BK_SVC) || (pCurEpDist->ServiceID == WMI_DATA_BE_SVC)){ - /* assign at least min credits to lower than VO priority services */ - GiveCredits(pCredInfo,pCurEpDist,pCurEpDist->TxCreditsMin); - /* force active */ - SET_EP_ACTIVE(pCurEpDist); - } - } - -#endif - - if (pCurEpDist->ServiceID == WMI_CONTROL_SVC) { - /* give control service some credits */ - GiveCredits(pCredInfo,pCurEpDist,pCurEpDist->TxCreditsMin); - /* control service is always marked active, it never goes inactive EVER */ - SET_EP_ACTIVE(pCurEpDist); - } else if (pCurEpDist->ServiceID == WMI_DATA_BK_SVC) { - /* this is the lowest priority data endpoint, save this off for easy access */ - pCredInfo->pLowestPriEpDist = pCurEpDist; - } - - /* Streams have to be created (explicit | implicit)for all kinds - * of traffic. BE endpoints are also inactive in the beginning. - * When BE traffic starts it creates implicit streams that - * redistributes credits. - */ - - /* note, all other endpoints have minimums set but are initially given NO credits. - * Credits will be distributed as traffic activity demands */ - pCurEpDist = pCurEpDist->pNext; - } - - if (pCredInfo->CurrentFreeCredits <= 0) { - AR_DEBUG_PRINTF(ATH_LOG_INF, ("Not enough credits (%d) to do credit distributions \n", TotalCredits)); - A_ASSERT(false); - return; - } - - /* reset list */ - pCurEpDist = pEPList; - /* now run through the list and set max operating credit limits for everyone */ - while (pCurEpDist != NULL) { - if (pCurEpDist->ServiceID == WMI_CONTROL_SVC) { - /* control service max is just 1 max message */ - pCurEpDist->TxCreditsNorm = pCurEpDist->TxCreditsPerMaxMsg; - } else { - /* for the remaining data endpoints, we assume that each TxCreditsPerMaxMsg are - * the same. - * We use a simple calculation here, we take the remaining credits and - * determine how many max messages this can cover and then set each endpoint's - * normal value equal to 3/4 this amount. - * */ - count = (pCredInfo->CurrentFreeCredits/pCurEpDist->TxCreditsPerMaxMsg) * pCurEpDist->TxCreditsPerMaxMsg; - count = (count * 3) >> 2; - count = max(count,pCurEpDist->TxCreditsPerMaxMsg); - /* set normal */ - pCurEpDist->TxCreditsNorm = count; - - } - pCurEpDist = pCurEpDist->pNext; - } - -} - - -/* default credit distribution callback - * This callback is invoked whenever endpoints require credit distributions. - * A lock is held while this function is invoked, this function shall NOT block. - * The pEPDistList is a list of distribution structures in prioritized order as - * defined by the call to the HTCSetCreditDistribution() api. - * - */ -static void ar6000_credit_distribute(void *Context, - struct htc_endpoint_credit_dist *pEPDistList, - HTC_CREDIT_DIST_REASON Reason) -{ - struct htc_endpoint_credit_dist *pCurEpDist; - struct common_credit_state_info *pCredInfo = (struct common_credit_state_info *)Context; - - switch (Reason) { - case HTC_CREDIT_DIST_SEND_COMPLETE : - pCurEpDist = pEPDistList; - /* we are given the start of the endpoint distribution list. - * There may be one or more endpoints to service. - * Run through the list and distribute credits */ - while (pCurEpDist != NULL) { - - if (pCurEpDist->TxCreditsToDist > 0) { - /* return the credits back to the endpoint */ - pCurEpDist->TxCredits += pCurEpDist->TxCreditsToDist; - /* always zero out when we are done */ - pCurEpDist->TxCreditsToDist = 0; - - if (pCurEpDist->TxCredits > pCurEpDist->TxCreditsAssigned) { - /* reduce to the assigned limit, previous credit reductions - * could have caused the limit to change */ - ReduceCredits(pCredInfo, pCurEpDist, pCurEpDist->TxCreditsAssigned); - } - - if (pCurEpDist->TxCredits > pCurEpDist->TxCreditsNorm) { - /* oversubscribed endpoints need to reduce back to normal */ - ReduceCredits(pCredInfo, pCurEpDist, pCurEpDist->TxCreditsNorm); - } - - if (!IS_EP_ACTIVE(pCurEpDist)) { - /* endpoint is inactive, now check for messages waiting for credits */ - if (pCurEpDist->TxQueueDepth == 0) { - /* EP is inactive and there are no pending messages, - * reduce credits back to zero to recover credits */ - ReduceCredits(pCredInfo, pCurEpDist, 0); - } - } - } - - pCurEpDist = pCurEpDist->pNext; - } - - break; - - case HTC_CREDIT_DIST_ACTIVITY_CHANGE : - RedistributeCredits(pCredInfo,pEPDistList); - break; - case HTC_CREDIT_DIST_SEEK_CREDITS : - SeekCredits(pCredInfo,pEPDistList); - break; - case HTC_DUMP_CREDIT_STATE : - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Credit Distribution, total : %d, free : %d\n", - pCredInfo->TotalAvailableCredits, pCredInfo->CurrentFreeCredits)); - break; - default: - break; - - } - - /* sanity checks done after each distribution action */ - A_ASSERT(pCredInfo->CurrentFreeCredits <= pCredInfo->TotalAvailableCredits); - A_ASSERT(pCredInfo->CurrentFreeCredits >= 0); - -} - -/* redistribute credits based on activity change */ -static void RedistributeCredits(struct common_credit_state_info *pCredInfo, - struct htc_endpoint_credit_dist *pEPDistList) -{ - struct htc_endpoint_credit_dist *pCurEpDist = pEPDistList; - - /* walk through the list and remove credits from inactive endpoints */ - while (pCurEpDist != NULL) { - -#ifdef CONFIG_GIVE_LOW_PRIORITY_STREAMS_MIN_CREDITS - - if ((pCurEpDist->ServiceID == WMI_DATA_BK_SVC) || (pCurEpDist->ServiceID == WMI_DATA_BE_SVC)) { - /* force low priority streams to always be active to retain their minimum credit distribution */ - SET_EP_ACTIVE(pCurEpDist); - } -#endif - - if (pCurEpDist->ServiceID != WMI_CONTROL_SVC) { - if (!IS_EP_ACTIVE(pCurEpDist)) { - if (pCurEpDist->TxQueueDepth == 0) { - /* EP is inactive and there are no pending messages, reduce credits back to zero */ - ReduceCredits(pCredInfo, pCurEpDist, 0); - } else { - /* we cannot zero the credits assigned to this EP, but to keep - * the credits available for these leftover packets, reduce to - * a minimum */ - ReduceCredits(pCredInfo, pCurEpDist, pCurEpDist->TxCreditsMin); - } - } - } - - /* NOTE in the active case, we do not need to do anything further, - * when an EP goes active and needs credits, HTC will call into - * our distribution function using a reason code of HTC_CREDIT_DIST_SEEK_CREDITS */ - - pCurEpDist = pCurEpDist->pNext; - } - -} - -/* HTC has an endpoint that needs credits, pEPDist is the endpoint in question */ -static void SeekCredits(struct common_credit_state_info *pCredInfo, - struct htc_endpoint_credit_dist *pEPDist) -{ - struct htc_endpoint_credit_dist *pCurEpDist; - int credits = 0; - int need; - - do { - - if (pEPDist->ServiceID == WMI_CONTROL_SVC) { - /* we never oversubscribe on the control service, this is not - * a high performance path and the target never holds onto control - * credits for too long */ - break; - } - -#ifdef CONFIG_GIVE_LOW_PRIORITY_STREAMS_MIN_CREDITS - if (pEPDist->ServiceID == WMI_DATA_VI_SVC) { - if ((pEPDist->TxCreditsAssigned >= pEPDist->TxCreditsNorm)) { - /* limit VI service from oversubscribing */ - break; - } - } - - if (pEPDist->ServiceID == WMI_DATA_VO_SVC) { - if ((pEPDist->TxCreditsAssigned >= pEPDist->TxCreditsNorm)) { - /* limit VO service from oversubscribing */ - break; - } - } -#else - if (pEPDist->ServiceID == WMI_DATA_VI_SVC) { - if ((pEPDist->TxCreditsAssigned >= pEPDist->TxCreditsNorm) || - (pCredInfo->CurrentFreeCredits <= pEPDist->TxCreditsPerMaxMsg)) { - /* limit VI service from oversubscribing */ - /* at least one free credit will not be used by VI */ - break; - } - } - - if (pEPDist->ServiceID == WMI_DATA_VO_SVC) { - if ((pEPDist->TxCreditsAssigned >= pEPDist->TxCreditsNorm) || - (pCredInfo->CurrentFreeCredits <= pEPDist->TxCreditsPerMaxMsg)) { - /* limit VO service from oversubscribing */ - /* at least one free credit will not be used by VO */ - break; - } - } -#endif - - /* for all other services, we follow a simple algorithm of - * 1. checking the free pool for credits - * 2. checking lower priority endpoints for credits to take */ - - /* give what we can */ - credits = min(pCredInfo->CurrentFreeCredits,pEPDist->TxCreditsSeek); - - if (credits >= pEPDist->TxCreditsSeek) { - /* we found some to fulfill the seek request */ - break; - } - - /* we don't have enough in the free pool, try taking away from lower priority services - * - * The rule for taking away credits: - * 1. Only take from lower priority endpoints - * 2. Only take what is allocated above the minimum (never starve an endpoint completely) - * 3. Only take what you need. - * - * */ - - /* starting at the lowest priority */ - pCurEpDist = pCredInfo->pLowestPriEpDist; - - /* work backwards until we hit the endpoint again */ - while (pCurEpDist != pEPDist) { - /* calculate how many we need so far */ - need = pEPDist->TxCreditsSeek - pCredInfo->CurrentFreeCredits; - - if ((pCurEpDist->TxCreditsAssigned - need) >= pCurEpDist->TxCreditsMin) { - /* the current one has been allocated more than it's minimum and it - * has enough credits assigned above it's minimum to fulfill our need - * try to take away just enough to fulfill our need */ - ReduceCredits(pCredInfo, - pCurEpDist, - pCurEpDist->TxCreditsAssigned - need); - - if (pCredInfo->CurrentFreeCredits >= pEPDist->TxCreditsSeek) { - /* we have enough */ - break; - } - } - - pCurEpDist = pCurEpDist->pPrev; - } - - /* return what we can get */ - credits = min(pCredInfo->CurrentFreeCredits,pEPDist->TxCreditsSeek); - - } while (false); - - /* did we find some credits? */ - if (credits) { - /* give what we can */ - GiveCredits(pCredInfo, pEPDist, credits); - } - -} - -/* initialize and setup credit distribution */ -int ar6000_setup_credit_dist(HTC_HANDLE HTCHandle, struct common_credit_state_info *pCredInfo) -{ - HTC_SERVICE_ID servicepriority[5]; - - A_MEMZERO(pCredInfo,sizeof(struct common_credit_state_info)); - - servicepriority[0] = WMI_CONTROL_SVC; /* highest */ - servicepriority[1] = WMI_DATA_VO_SVC; - servicepriority[2] = WMI_DATA_VI_SVC; - servicepriority[3] = WMI_DATA_BE_SVC; - servicepriority[4] = WMI_DATA_BK_SVC; /* lowest */ - - /* set callbacks and priority list */ - HTCSetCreditDistribution(HTCHandle, - pCredInfo, - ar6000_credit_distribute, - ar6000_credit_init, - servicepriority, - 5); - - return 0; -} - diff --git a/drivers/staging/ath6kl/miscdrv/miscdrv.h b/drivers/staging/ath6kl/miscdrv/miscdrv.h deleted file mode 100644 index 41be567..0000000 --- a/drivers/staging/ath6kl/miscdrv/miscdrv.h +++ /dev/null @@ -1,42 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="miscdrv.h" company="Atheros"> -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Author(s): ="Atheros" -//============================================================================== -#ifndef _MISCDRV_H -#define _MISCDRV_H - - -#define HOST_INTEREST_ITEM_ADDRESS(target, item) \ - AR6002_HOST_INTEREST_ITEM_ADDRESS(item) - -u32 ar6kRev2Array[][128] = { - {0xFFFF, 0xFFFF}, // No Patches - }; - -#define CFG_REV2_ITEMS 0 // no patches so far -#define AR6K_RESET_ADDR 0x4000 -#define AR6K_RESET_VAL 0x100 - -#define EEPROM_SZ 768 -#define EEPROM_WAIT_LIMIT 4 - -#endif - diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c deleted file mode 100644 index 32ee39a..0000000 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ /dev/null @@ -1,6267 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2004-2010 Atheros Communications Inc. -// All rights reserved. -// -// -// -// 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. -// -// -// -// Author(s): ="Atheros" -//------------------------------------------------------------------------------ - -/* - * This driver is a pseudo ethernet driver to access the Atheros AR6000 - * WLAN Device - */ - -#include "ar6000_drv.h" -#include "cfg80211.h" -#include "htc.h" -#include "wmi_filter_linux.h" -#include "epping_test.h" -#include "wlan_config.h" -#include "ar3kconfig.h" -#include "ar6k_pal.h" -#include "AR6002/addrs.h" - - -/* LINUX_HACK_FUDGE_FACTOR -- this is used to provide a workaround for linux behavior. When - * the meta data was added to the header it was found that linux did not correctly provide - * enough headroom. However when more headroom was requested beyond what was truly needed - * Linux gave the requested headroom. Therefore to get the necessary headroom from Linux - * the driver requests more than is needed by the amount = LINUX_HACK_FUDGE_FACTOR */ -#define LINUX_HACK_FUDGE_FACTOR 16 -#define BDATA_BDADDR_OFFSET 28 - -u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; -u8 null_mac[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; - -#ifdef DEBUG - -#define ATH_DEBUG_DBG_LOG ATH_DEBUG_MAKE_MODULE_MASK(0) -#define ATH_DEBUG_WLAN_CONNECT ATH_DEBUG_MAKE_MODULE_MASK(1) -#define ATH_DEBUG_WLAN_SCAN ATH_DEBUG_MAKE_MODULE_MASK(2) -#define ATH_DEBUG_WLAN_TX ATH_DEBUG_MAKE_MODULE_MASK(3) -#define ATH_DEBUG_WLAN_RX ATH_DEBUG_MAKE_MODULE_MASK(4) -#define ATH_DEBUG_HTC_RAW ATH_DEBUG_MAKE_MODULE_MASK(5) -#define ATH_DEBUG_HCI_BRIDGE ATH_DEBUG_MAKE_MODULE_MASK(6) - -static struct ath_debug_mask_description driver_debug_desc[] = { - { ATH_DEBUG_DBG_LOG , "Target Debug Logs"}, - { ATH_DEBUG_WLAN_CONNECT , "WLAN connect"}, - { ATH_DEBUG_WLAN_SCAN , "WLAN scan"}, - { ATH_DEBUG_WLAN_TX , "WLAN Tx"}, - { ATH_DEBUG_WLAN_RX , "WLAN Rx"}, - { ATH_DEBUG_HTC_RAW , "HTC Raw IF tracing"}, - { ATH_DEBUG_HCI_BRIDGE , "HCI Bridge Setup"}, - { ATH_DEBUG_HCI_RECV , "HCI Recv tracing"}, - { ATH_DEBUG_HCI_DUMP , "HCI Packet dumps"}, -}; - -ATH_DEBUG_INSTANTIATE_MODULE_VAR(driver, - "driver", - "Linux Driver Interface", - ATH_DEBUG_MASK_DEFAULTS | ATH_DEBUG_WLAN_SCAN | - ATH_DEBUG_HCI_BRIDGE, - ATH_DEBUG_DESCRIPTION_COUNT(driver_debug_desc), - driver_debug_desc); - -#endif - - -#define IS_MAC_NULL(mac) (mac[0]==0 && mac[1]==0 && mac[2]==0 && mac[3]==0 && mac[4]==0 && mac[5]==0) -#define IS_MAC_BCAST(mac) (*mac==0xff) - -#define DESCRIPTION "Driver to access the Atheros AR600x Device, version " __stringify(__VER_MAJOR_) "." __stringify(__VER_MINOR_) "." __stringify(__VER_PATCH_) "." __stringify(__BUILD_NUMBER_) - -MODULE_AUTHOR("Atheros Communications, Inc."); -MODULE_DESCRIPTION(DESCRIPTION); -MODULE_LICENSE("Dual BSD/GPL"); - -#ifndef REORG_APTC_HEURISTICS -#undef ADAPTIVE_POWER_THROUGHPUT_CONTROL -#endif /* REORG_APTC_HEURISTICS */ - -#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL -#define APTC_TRAFFIC_SAMPLING_INTERVAL 100 /* msec */ -#define APTC_UPPER_THROUGHPUT_THRESHOLD 3000 /* Kbps */ -#define APTC_LOWER_THROUGHPUT_THRESHOLD 2000 /* Kbps */ - -typedef struct aptc_traffic_record { - bool timerScheduled; - struct timeval samplingTS; - unsigned long bytesReceived; - unsigned long bytesTransmitted; -} APTC_TRAFFIC_RECORD; - -A_TIMER aptcTimer; -APTC_TRAFFIC_RECORD aptcTR; -#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */ - -#ifdef EXPORT_HCI_BRIDGE_INTERFACE -// callbacks registered by HCI transport driver -struct hci_transport_callbacks ar6kHciTransCallbacks = { NULL }; -#endif - -unsigned int processDot11Hdr = 0; - -char ifname[IFNAMSIZ] = {0,}; - -int wlaninitmode = WLAN_INIT_MODE_DEFAULT; -static bool bypasswmi; -unsigned int debuglevel = 0; -int tspecCompliance = ATHEROS_COMPLIANCE; -unsigned int busspeedlow = 0; -unsigned int onebitmode = 0; -unsigned int skipflash = 0; -unsigned int wmitimeout = 2; -unsigned int wlanNodeCaching = 1; -unsigned int enableuartprint = ENABLEUARTPRINT_DEFAULT; -unsigned int logWmiRawMsgs = 0; -unsigned int enabletimerwar = 0; -unsigned int num_device = 1; -unsigned int regscanmode; -unsigned int fwmode = 1; -unsigned int mbox_yield_limit = 99; -unsigned int enablerssicompensation = 0; -int reduce_credit_dribble = 1 + HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_ONE_HALF; -int allow_trace_signal = 0; -#ifdef CONFIG_HOST_TCMD_SUPPORT -unsigned int testmode =0; -#endif - -unsigned int irqprocmode = HIF_DEVICE_IRQ_SYNC_ONLY;//HIF_DEVICE_IRQ_ASYNC_SYNC; -unsigned int panic_on_assert = 1; -unsigned int nohifscattersupport = NOHIFSCATTERSUPPORT_DEFAULT; - -unsigned int setuphci = SETUPHCI_DEFAULT; -unsigned int loghci = 0; -unsigned int setupbtdev = SETUPBTDEV_DEFAULT; -#ifndef EXPORT_HCI_BRIDGE_INTERFACE -unsigned int ar3khcibaud = AR3KHCIBAUD_DEFAULT; -unsigned int hciuartscale = HCIUARTSCALE_DEFAULT; -unsigned int hciuartstep = HCIUARTSTEP_DEFAULT; -#endif -unsigned int csumOffload=0; -unsigned int csumOffloadTest=0; -unsigned int eppingtest=0; -unsigned int mac_addr_method; -unsigned int firmware_bridge; - -module_param_string(ifname, ifname, sizeof(ifname), 0644); -module_param(wlaninitmode, int, 0644); -module_param(bypasswmi, bool, 0644); -module_param(debuglevel, uint, 0644); -module_param(tspecCompliance, int, 0644); -module_param(onebitmode, uint, 0644); -module_param(busspeedlow, uint, 0644); -module_param(skipflash, uint, 0644); -module_param(wmitimeout, uint, 0644); -module_param(wlanNodeCaching, uint, 0644); -module_param(logWmiRawMsgs, uint, 0644); -module_param(enableuartprint, uint, 0644); -module_param(enabletimerwar, uint, 0644); -module_param(fwmode, uint, 0644); -module_param(mbox_yield_limit, uint, 0644); -module_param(reduce_credit_dribble, int, 0644); -module_param(allow_trace_signal, int, 0644); -module_param(enablerssicompensation, uint, 0644); -module_param(processDot11Hdr, uint, 0644); -module_param(csumOffload, uint, 0644); -#ifdef CONFIG_HOST_TCMD_SUPPORT -module_param(testmode, uint, 0644); -#endif -module_param(irqprocmode, uint, 0644); -module_param(nohifscattersupport, uint, 0644); -module_param(panic_on_assert, uint, 0644); -module_param(setuphci, uint, 0644); -module_param(loghci, uint, 0644); -module_param(setupbtdev, uint, 0644); -#ifndef EXPORT_HCI_BRIDGE_INTERFACE -module_param(ar3khcibaud, uint, 0644); -module_param(hciuartscale, uint, 0644); -module_param(hciuartstep, uint, 0644); -#endif -module_param(eppingtest, uint, 0644); - -/* in 2.6.10 and later this is now a pointer to a uint */ -unsigned int _mboxnum = HTC_MAILBOX_NUM_MAX; -#define mboxnum &_mboxnum - -#ifdef DEBUG -u32 g_dbg_flags = DBG_DEFAULTS; -unsigned int debugflags = 0; -int debugdriver = 0; -unsigned int debughtc = 0; -unsigned int debugbmi = 0; -unsigned int debughif = 0; -unsigned int txcreditsavailable[HTC_MAILBOX_NUM_MAX] = {0}; -unsigned int txcreditsconsumed[HTC_MAILBOX_NUM_MAX] = {0}; -unsigned int txcreditintrenable[HTC_MAILBOX_NUM_MAX] = {0}; -unsigned int txcreditintrenableaggregate[HTC_MAILBOX_NUM_MAX] = {0}; -module_param(debugflags, uint, 0644); -module_param(debugdriver, int, 0644); -module_param(debughtc, uint, 0644); -module_param(debugbmi, uint, 0644); -module_param(debughif, uint, 0644); -module_param_array(txcreditsavailable, uint, mboxnum, 0644); -module_param_array(txcreditsconsumed, uint, mboxnum, 0644); -module_param_array(txcreditintrenable, uint, mboxnum, 0644); -module_param_array(txcreditintrenableaggregate, uint, mboxnum, 0644); - -#endif /* DEBUG */ - -unsigned int resetok = 1; -unsigned int tx_attempt[HTC_MAILBOX_NUM_MAX] = {0}; -unsigned int tx_post[HTC_MAILBOX_NUM_MAX] = {0}; -unsigned int tx_complete[HTC_MAILBOX_NUM_MAX] = {0}; -unsigned int hifBusRequestNumMax = 40; -unsigned int war23838_disabled = 0; -#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL -unsigned int enableAPTCHeuristics = 1; -#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */ -module_param_array(tx_attempt, uint, mboxnum, 0644); -module_param_array(tx_post, uint, mboxnum, 0644); -module_param_array(tx_complete, uint, mboxnum, 0644); -module_param(hifBusRequestNumMax, uint, 0644); -module_param(war23838_disabled, uint, 0644); -module_param(resetok, uint, 0644); -#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL -module_param(enableAPTCHeuristics, uint, 0644); -#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */ - -#ifdef BLOCK_TX_PATH_FLAG -int blocktx = 0; -module_param(blocktx, int, 0644); -#endif /* BLOCK_TX_PATH_FLAG */ - -typedef struct user_rssi_compensation_t { - u16 customerID; - union { - u16 a_enable; - u16 bg_enable; - u16 enable; - }; - s16 bg_param_a; - s16 bg_param_b; - s16 a_param_a; - s16 a_param_b; - u32 reserved; -} USER_RSSI_CPENSATION; - -static USER_RSSI_CPENSATION rssi_compensation_param; - -static s16 rssi_compensation_table[96]; - -int reconnect_flag = 0; -static ar6k_pal_config_t ar6k_pal_config_g; - -/* Function declarations */ -static int ar6000_init_module(void); -static void ar6000_cleanup_module(void); - -int ar6000_init(struct net_device *dev); -static int ar6000_open(struct net_device *dev); -static int ar6000_close(struct net_device *dev); -static void ar6000_init_control_info(struct ar6_softc *ar); -static int ar6000_data_tx(struct sk_buff *skb, struct net_device *dev); - -void ar6000_destroy(struct net_device *dev, unsigned int unregister); -static void ar6000_detect_error(unsigned long ptr); -static void ar6000_set_multicast_list(struct net_device *dev); -static struct net_device_stats *ar6000_get_stats(struct net_device *dev); - -static void disconnect_timer_handler(unsigned long ptr); - -void read_rssi_compensation_param(struct ar6_softc *ar); - -/* - * HTC service connection handlers - */ -static int ar6000_avail_ev(void *context, void *hif_handle); - -static int ar6000_unavail_ev(void *context, void *hif_handle); - -int ar6000_configure_target(struct ar6_softc *ar); - -static void ar6000_target_failure(void *Instance, int Status); - -static void ar6000_rx(void *Context, struct htc_packet *pPacket); - -static void ar6000_rx_refill(void *Context,HTC_ENDPOINT_ID Endpoint); - -static void ar6000_tx_complete(void *Context, struct htc_packet_queue *pPackets); - -static HTC_SEND_FULL_ACTION ar6000_tx_queue_full(void *Context, struct htc_packet *pPacket); - -static void ar6000_alloc_netbufs(A_NETBUF_QUEUE_T *q, u16 num); -static void ar6000_deliver_frames_to_nw_stack(void * dev, void *osbuf); -//static void ar6000_deliver_frames_to_bt_stack(void * dev, void *osbuf); - -static struct htc_packet *ar6000_alloc_amsdu_rxbuf(void *Context, HTC_ENDPOINT_ID Endpoint, int Length); - -static void ar6000_refill_amsdu_rxbufs(struct ar6_softc *ar, int Count); - -static void ar6000_cleanup_amsdu_rxbufs(struct ar6_softc *ar); - -static ssize_t -ar6000_sysfs_bmi_read(struct file *fp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t pos, size_t count); - -static ssize_t -ar6000_sysfs_bmi_write(struct file *fp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t pos, size_t count); - -static int -ar6000_sysfs_bmi_init(struct ar6_softc *ar); - -void ar6k_cleanup_hci_pal(struct ar6_softc *ar); - -static void -ar6000_sysfs_bmi_deinit(struct ar6_softc *ar); - -int -ar6000_sysfs_bmi_get_config(struct ar6_softc *ar, u32 mode); - -/* - * Static variables - */ - -struct net_device *ar6000_devices[MAX_AR6000]; -static int is_netdev_registered; -DECLARE_WAIT_QUEUE_HEAD(arEvent); -static void ar6000_cookie_init(struct ar6_softc *ar); -static void ar6000_cookie_cleanup(struct ar6_softc *ar); -static void ar6000_free_cookie(struct ar6_softc *ar, struct ar_cookie * cookie); -static struct ar_cookie *ar6000_alloc_cookie(struct ar6_softc *ar); - -static int ar6000_reinstall_keys(struct ar6_softc *ar,u8 key_op_ctrl); - -#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT -struct net_device *arApNetDev; -#endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */ - -static struct ar_cookie s_ar_cookie_mem[MAX_COOKIE_NUM]; - -#define HOST_INTEREST_ITEM_ADDRESS(ar, item) \ - (((ar)->arTargetType == TARGET_TYPE_AR6002) ? AR6002_HOST_INTEREST_ITEM_ADDRESS(item) : \ - (((ar)->arTargetType == TARGET_TYPE_AR6003) ? AR6003_HOST_INTEREST_ITEM_ADDRESS(item) : 0)) - - -static struct net_device_ops ar6000_netdev_ops = { - .ndo_init = NULL, - .ndo_open = ar6000_open, - .ndo_stop = ar6000_close, - .ndo_get_stats = ar6000_get_stats, - .ndo_start_xmit = ar6000_data_tx, - .ndo_set_multicast_list = ar6000_set_multicast_list, -}; - -/* Debug log support */ - -/* - * Flag to govern whether the debug logs should be parsed in the kernel - * or reported to the application. - */ -#define REPORT_DEBUG_LOGS_TO_APP - -int -ar6000_set_host_app_area(struct ar6_softc *ar) -{ - u32 address, data; - struct host_app_area_s host_app_area; - - /* Fetch the address of the host_app_area_s instance in the host interest area */ - address = TARG_VTOP(ar->arTargetType, HOST_INTEREST_ITEM_ADDRESS(ar, hi_app_host_interest)); - if (ar6000_ReadRegDiag(ar->arHifDevice, &address, &data) != 0) { - return A_ERROR; - } - address = TARG_VTOP(ar->arTargetType, data); - host_app_area.wmi_protocol_ver = WMI_PROTOCOL_VERSION; - if (ar6000_WriteDataDiag(ar->arHifDevice, address, - (u8 *)&host_app_area, - sizeof(struct host_app_area_s)) != 0) - { - return A_ERROR; - } - - return 0; -} - -u32 dbglog_get_debug_hdr_ptr(struct ar6_softc *ar) -{ - u32 param; - u32 address; - int status; - - address = TARG_VTOP(ar->arTargetType, HOST_INTEREST_ITEM_ADDRESS(ar, hi_dbglog_hdr)); - if ((status = ar6000_ReadDataDiag(ar->arHifDevice, address, - (u8 *)¶m, 4)) != 0) - { - param = 0; - } - - return param; -} - -/* - * The dbglog module has been initialized. Its ok to access the relevant - * data stuctures over the diagnostic window. - */ -void -ar6000_dbglog_init_done(struct ar6_softc *ar) -{ - ar->dbglog_init_done = true; -} - -u32 dbglog_get_debug_fragment(s8 *datap, u32 len, u32 limit) -{ - s32 *buffer; - u32 count; - u32 numargs; - u32 length; - u32 fraglen; - - count = fraglen = 0; - buffer = (s32 *)datap; - length = (limit >> 2); - - if (len <= limit) { - fraglen = len; - } else { - while (count < length) { - numargs = DBGLOG_GET_NUMARGS(buffer[count]); - fraglen = (count << 2); - count += numargs + 1; - } - } - - return fraglen; -} - -void -dbglog_parse_debug_logs(s8 *datap, u32 len) -{ - s32 *buffer; - u32 count; - u32 timestamp; - u32 debugid; - u32 moduleid; - u32 numargs; - u32 length; - - count = 0; - buffer = (s32 *)datap; - length = (len >> 2); - while (count < length) { - debugid = DBGLOG_GET_DBGID(buffer[count]); - moduleid = DBGLOG_GET_MODULEID(buffer[count]); - numargs = DBGLOG_GET_NUMARGS(buffer[count]); - timestamp = DBGLOG_GET_TIMESTAMP(buffer[count]); - switch (numargs) { - case 0: - AR_DEBUG_PRINTF(ATH_DEBUG_DBG_LOG,("%d %d (%d)\n", moduleid, debugid, timestamp)); - break; - - case 1: - AR_DEBUG_PRINTF(ATH_DEBUG_DBG_LOG,("%d %d (%d): 0x%x\n", moduleid, debugid, - timestamp, buffer[count+1])); - break; - - case 2: - AR_DEBUG_PRINTF(ATH_DEBUG_DBG_LOG,("%d %d (%d): 0x%x, 0x%x\n", moduleid, debugid, - timestamp, buffer[count+1], buffer[count+2])); - break; - - default: - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Invalid args: %d\n", numargs)); - } - count += numargs + 1; - } -} - -int -ar6000_dbglog_get_debug_logs(struct ar6_softc *ar) -{ - u32 data[8]; /* Should be able to accommodate struct dbglog_buf_s */ - u32 address; - u32 length; - u32 dropped; - u32 firstbuf; - u32 debug_hdr_ptr; - - if (!ar->dbglog_init_done) return A_ERROR; - - - AR6000_SPIN_LOCK(&ar->arLock, 0); - - if (ar->dbgLogFetchInProgress) { - AR6000_SPIN_UNLOCK(&ar->arLock, 0); - return A_EBUSY; - } - - /* block out others */ - ar->dbgLogFetchInProgress = true; - - AR6000_SPIN_UNLOCK(&ar->arLock, 0); - - debug_hdr_ptr = dbglog_get_debug_hdr_ptr(ar); - printk("debug_hdr_ptr: 0x%x\n", debug_hdr_ptr); - - /* Get the contents of the ring buffer */ - if (debug_hdr_ptr) { - address = TARG_VTOP(ar->arTargetType, debug_hdr_ptr); - length = 4 /* sizeof(dbuf) */ + 4 /* sizeof(dropped) */; - A_MEMZERO(data, sizeof(data)); - ar6000_ReadDataDiag(ar->arHifDevice, address, (u8 *)data, length); - address = TARG_VTOP(ar->arTargetType, data[0] /* dbuf */); - firstbuf = address; - dropped = data[1]; /* dropped */ - length = 4 /* sizeof(next) */ + 4 /* sizeof(buffer) */ + 4 /* sizeof(bufsize) */ + 4 /* sizeof(length) */ + 4 /* sizeof(count) */ + 4 /* sizeof(free) */; - A_MEMZERO(data, sizeof(data)); - ar6000_ReadDataDiag(ar->arHifDevice, address, (u8 *)&data, length); - - do { - address = TARG_VTOP(ar->arTargetType, data[1] /* buffer*/); - length = data[3]; /* length */ - if ((length) && (length <= data[2] /* bufsize*/)) { - /* Rewind the index if it is about to overrun the buffer */ - if (ar->log_cnt > (DBGLOG_HOST_LOG_BUFFER_SIZE - length)) { - ar->log_cnt = 0; - } - if(0 != ar6000_ReadDataDiag(ar->arHifDevice, address, - (u8 *)&ar->log_buffer[ar->log_cnt], length)) - { - break; - } - ar6000_dbglog_event(ar, dropped, (s8 *)&ar->log_buffer[ar->log_cnt], length); - ar->log_cnt += length; - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_DBG_LOG,("Length: %d (Total size: %d)\n", - data[3], data[2])); - } - - address = TARG_VTOP(ar->arTargetType, data[0] /* next */); - length = 4 /* sizeof(next) */ + 4 /* sizeof(buffer) */ + 4 /* sizeof(bufsize) */ + 4 /* sizeof(length) */ + 4 /* sizeof(count) */ + 4 /* sizeof(free) */; - A_MEMZERO(data, sizeof(data)); - if(0 != ar6000_ReadDataDiag(ar->arHifDevice, address, - (u8 *)&data, length)) - { - break; - } - - } while (address != firstbuf); - } - - ar->dbgLogFetchInProgress = false; - - return 0; -} - -void -ar6000_dbglog_event(struct ar6_softc *ar, u32 dropped, - s8 *buffer, u32 length) -{ -#ifdef REPORT_DEBUG_LOGS_TO_APP - #define MAX_WIRELESS_EVENT_SIZE 252 - /* - * Break it up into chunks of MAX_WIRELESS_EVENT_SIZE bytes of messages. - * There seems to be a limitation on the length of message that could be - * transmitted to the user app via this mechanism. - */ - u32 send, sent; - - sent = 0; - send = dbglog_get_debug_fragment(&buffer[sent], length - sent, - MAX_WIRELESS_EVENT_SIZE); - while (send) { - sent += send; - send = dbglog_get_debug_fragment(&buffer[sent], length - sent, - MAX_WIRELESS_EVENT_SIZE); - } -#else - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Dropped logs: 0x%x\nDebug info length: %d\n", - dropped, length)); - - /* Interpret the debug logs */ - dbglog_parse_debug_logs((s8 *)buffer, length); -#endif /* REPORT_DEBUG_LOGS_TO_APP */ -} - - -static int __init -ar6000_init_module(void) -{ - static int probed = 0; - int r; - OSDRV_CALLBACKS osdrvCallbacks; - - a_module_debug_support_init(); - -#ifdef DEBUG - /* check for debug mask overrides */ - if (debughtc != 0) { - ATH_DEBUG_SET_DEBUG_MASK(htc,debughtc); - } - if (debugbmi != 0) { - ATH_DEBUG_SET_DEBUG_MASK(bmi,debugbmi); - } - if (debughif != 0) { - ATH_DEBUG_SET_DEBUG_MASK(hif,debughif); - } - if (debugdriver != 0) { - ATH_DEBUG_SET_DEBUG_MASK(driver,debugdriver); - } - -#endif - - A_REGISTER_MODULE_DEBUG_INFO(driver); - - A_MEMZERO(&osdrvCallbacks,sizeof(osdrvCallbacks)); - osdrvCallbacks.deviceInsertedHandler = ar6000_avail_ev; - osdrvCallbacks.deviceRemovedHandler = ar6000_unavail_ev; -#ifdef CONFIG_PM - osdrvCallbacks.deviceSuspendHandler = ar6000_suspend_ev; - osdrvCallbacks.deviceResumeHandler = ar6000_resume_ev; - osdrvCallbacks.devicePowerChangeHandler = ar6000_power_change_ev; -#endif - -#ifdef DEBUG - /* Set the debug flags if specified at load time */ - if(debugflags != 0) - { - g_dbg_flags = debugflags; - } -#endif - - if (probed) { - return -ENODEV; - } - probed++; - -#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL - memset(&aptcTR, 0, sizeof(APTC_TRAFFIC_RECORD)); -#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */ - - r = HIFInit(&osdrvCallbacks); - if (r) - return r; - - return 0; -} - -static void __exit -ar6000_cleanup_module(void) -{ - int i = 0; - struct net_device *ar6000_netdev; - -#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL - /* Delete the Adaptive Power Control timer */ - if (timer_pending(&aptcTimer)) { - del_timer_sync(&aptcTimer); - } -#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */ - - for (i=0; i < MAX_AR6000; i++) { - if (ar6000_devices[i] != NULL) { - ar6000_netdev = ar6000_devices[i]; - ar6000_devices[i] = NULL; - ar6000_destroy(ar6000_netdev, 1); - } - } - - HIFShutDownDevice(NULL); - - a_module_debug_support_cleanup(); - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("ar6000_cleanup: success\n")); -} - -#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL -void -aptcTimerHandler(unsigned long arg) -{ - u32 numbytes; - u32 throughput; - struct ar6_softc *ar; - int status; - - ar = (struct ar6_softc *)arg; - A_ASSERT(ar != NULL); - A_ASSERT(!timer_pending(&aptcTimer)); - - AR6000_SPIN_LOCK(&ar->arLock, 0); - - /* Get the number of bytes transferred */ - numbytes = aptcTR.bytesTransmitted + aptcTR.bytesReceived; - aptcTR.bytesTransmitted = aptcTR.bytesReceived = 0; - - /* Calculate and decide based on throughput thresholds */ - throughput = ((numbytes * 8)/APTC_TRAFFIC_SAMPLING_INTERVAL); /* Kbps */ - if (throughput < APTC_LOWER_THROUGHPUT_THRESHOLD) { - /* Enable Sleep and delete the timer */ - A_ASSERT(ar->arWmiReady == true); - AR6000_SPIN_UNLOCK(&ar->arLock, 0); - status = wmi_powermode_cmd(ar->arWmi, REC_POWER); - AR6000_SPIN_LOCK(&ar->arLock, 0); - A_ASSERT(status == 0); - aptcTR.timerScheduled = false; - } else { - A_TIMEOUT_MS(&aptcTimer, APTC_TRAFFIC_SAMPLING_INTERVAL, 0); - } - - AR6000_SPIN_UNLOCK(&ar->arLock, 0); -} -#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */ - -static void -ar6000_alloc_netbufs(A_NETBUF_QUEUE_T *q, u16 num) -{ - void * osbuf; - - while(num) { - if((osbuf = A_NETBUF_ALLOC(AR6000_BUFFER_SIZE))) { - A_NETBUF_ENQUEUE(q, osbuf); - } else { - break; - } - num--; - } - - if(num) { - A_PRINTF("%s(), allocation of netbuf failed", __func__); - } -} - -static struct bin_attribute bmi_attr = { - .attr = {.name = "bmi", .mode = 0600}, - .read = ar6000_sysfs_bmi_read, - .write = ar6000_sysfs_bmi_write, -}; - -static ssize_t -ar6000_sysfs_bmi_read(struct file *fp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t pos, size_t count) -{ - int index; - struct ar6_softc *ar; - struct hif_device_os_device_info *osDevInfo; - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Read %d bytes\n", (u32)count)); - for (index=0; index < MAX_AR6000; index++) { - ar = (struct ar6_softc *)ar6k_priv(ar6000_devices[index]); - osDevInfo = &ar->osDevInfo; - if (kobj == (&(((struct device *)osDevInfo->pOSDevice)->kobj))) { - break; - } - } - - if (index == MAX_AR6000) return 0; - - if ((BMIRawRead(ar->arHifDevice, (u8*)buf, count, true)) != 0) { - return 0; - } - - return count; -} - -static ssize_t -ar6000_sysfs_bmi_write(struct file *fp, struct kobject *kobj, - struct bin_attribute *bin_attr, - char *buf, loff_t pos, size_t count) -{ - int index; - struct ar6_softc *ar; - struct hif_device_os_device_info *osDevInfo; - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Write %d bytes\n", (u32)count)); - for (index=0; index < MAX_AR6000; index++) { - ar = (struct ar6_softc *)ar6k_priv(ar6000_devices[index]); - osDevInfo = &ar->osDevInfo; - if (kobj == (&(((struct device *)osDevInfo->pOSDevice)->kobj))) { - break; - } - } - - if (index == MAX_AR6000) return 0; - - if ((BMIRawWrite(ar->arHifDevice, (u8*)buf, count)) != 0) { - return 0; - } - - return count; -} - -static int -ar6000_sysfs_bmi_init(struct ar6_softc *ar) -{ - int status; - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Creating sysfs entry\n")); - A_MEMZERO(&ar->osDevInfo, sizeof(struct hif_device_os_device_info)); - - /* Get the underlying OS device */ - status = HIFConfigureDevice(ar->arHifDevice, - HIF_DEVICE_GET_OS_DEVICE, - &ar->osDevInfo, - sizeof(struct hif_device_os_device_info)); - - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI: Failed to get OS device info from HIF\n")); - return A_ERROR; - } - - /* Create a bmi entry in the sysfs filesystem */ - if ((sysfs_create_bin_file(&(((struct device *)ar->osDevInfo.pOSDevice)->kobj), &bmi_attr)) < 0) - { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMI: Failed to create entry for bmi in sysfs filesystem\n")); - return A_ERROR; - } - - return 0; -} - -static void -ar6000_sysfs_bmi_deinit(struct ar6_softc *ar) -{ - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Deleting sysfs entry\n")); - - sysfs_remove_bin_file(&(((struct device *)ar->osDevInfo.pOSDevice)->kobj), &bmi_attr); -} - -#define bmifn(fn) do { \ - if ((fn) < 0) { \ - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__)); \ - return A_ERROR; \ - } \ -} while(0) - -#ifdef SOFTMAC_FILE_USED -#define AR6002_MAC_ADDRESS_OFFSET 0x0A -#define AR6003_MAC_ADDRESS_OFFSET 0x16 -static -void calculate_crc(u32 TargetType, u8 *eeprom_data) -{ - u16 *ptr_crc; - u16 *ptr16_eeprom; - u16 checksum; - u32 i; - u32 eeprom_size; - - if (TargetType == TARGET_TYPE_AR6001) - { - eeprom_size = 512; - ptr_crc = (u16 *)eeprom_data; - } - else if (TargetType == TARGET_TYPE_AR6003) - { - eeprom_size = 1024; - ptr_crc = (u16 *)((u8 *)eeprom_data + 0x04); - } - else - { - eeprom_size = 768; - ptr_crc = (u16 *)((u8 *)eeprom_data + 0x04); - } - - - // Clear the crc - *ptr_crc = 0; - - // Recalculate new CRC - checksum = 0; - ptr16_eeprom = (u16 *)eeprom_data; - for (i = 0;i < eeprom_size; i += 2) - { - checksum = checksum ^ (*ptr16_eeprom); - ptr16_eeprom++; - } - checksum = 0xFFFF ^ checksum; - *ptr_crc = checksum; -} - -static void -ar6000_softmac_update(struct ar6_softc *ar, u8 *eeprom_data, size_t size) -{ - const char *source = "random generated"; - const struct firmware *softmac_entry; - u8 *ptr_mac; - switch (ar->arTargetType) { - case TARGET_TYPE_AR6002: - ptr_mac = (u8 *)((u8 *)eeprom_data + AR6002_MAC_ADDRESS_OFFSET); - break; - case TARGET_TYPE_AR6003: - ptr_mac = (u8 *)((u8 *)eeprom_data + AR6003_MAC_ADDRESS_OFFSET); - break; - default: - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Invalid Target Type\n")); - return; - } - printk(KERN_DEBUG "MAC from EEPROM %pM\n", ptr_mac); - - /* create a random MAC in case we cannot read file from system */ - ptr_mac[0] = 0; - ptr_mac[1] = 0x03; - ptr_mac[2] = 0x7F; - ptr_mac[3] = random32() & 0xff; - ptr_mac[4] = random32() & 0xff; - ptr_mac[5] = random32() & 0xff; - if ((A_REQUEST_FIRMWARE(&softmac_entry, "softmac", ((struct device *)ar->osDevInfo.pOSDevice))) == 0) - { - char *macbuf = A_MALLOC_NOWAIT(softmac_entry->size+1); - if (macbuf) { - unsigned int softmac[6]; - memcpy(macbuf, softmac_entry->data, softmac_entry->size); - macbuf[softmac_entry->size] = '\0'; - if (sscanf(macbuf, "%02x:%02x:%02x:%02x:%02x:%02x", - &softmac[0], &softmac[1], &softmac[2], - &softmac[3], &softmac[4], &softmac[5])==6) { - int i; - for (i=0; i<6; ++i) { - ptr_mac[i] = softmac[i] & 0xff; - } - source = "softmac file"; - } - kfree(macbuf); - } - A_RELEASE_FIRMWARE(softmac_entry); - } - printk(KERN_DEBUG "MAC from %s %pM\n", source, ptr_mac); - calculate_crc(ar->arTargetType, eeprom_data); -} -#endif /* SOFTMAC_FILE_USED */ - -static int -ar6000_transfer_bin_file(struct ar6_softc *ar, AR6K_BIN_FILE file, u32 address, bool compressed) -{ - int status; - 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) { - filename = AR6003_REV2_OTP_FILE; - } else if (ar->arVersion.target_ver == AR6003_REV3_VERSION) { - filename = AR6003_REV3_OTP_FILE; - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver)); - return A_ERROR; - } - 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) { - filename = AR6003_REV2_FIRMWARE_FILE; - } else if (ar->arVersion.target_ver == AR6003_REV3_VERSION) { - filename = AR6003_REV3_FIRMWARE_FILE; - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver)); - return A_ERROR; - } - - if (eppingtest) { - bypasswmi = true; - if (ar->arVersion.target_ver == AR6003_REV1_VERSION) { - filename = AR6003_REV1_EPPING_FIRMWARE_FILE; - } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) { - filename = AR6003_REV2_EPPING_FIRMWARE_FILE; - } else if (ar->arVersion.target_ver == AR6003_REV3_VERSION) { - filename = AR6003_REV3_EPPING_FIRMWARE_FILE; - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("eppingtest : unsupported firmware revision: %d\n", - ar->arVersion.target_ver)); - return A_ERROR; - } - compressed = false; - } - -#ifdef CONFIG_HOST_TCMD_SUPPORT - if(testmode) { - if (ar->arVersion.target_ver == AR6003_REV1_VERSION) { - filename = AR6003_REV1_TCMD_FIRMWARE_FILE; - } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) { - filename = AR6003_REV2_TCMD_FIRMWARE_FILE; - } else if (ar->arVersion.target_ver == AR6003_REV3_VERSION) { - filename = AR6003_REV3_TCMD_FIRMWARE_FILE; - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver)); - return A_ERROR; - } - compressed = false; - } -#endif -#ifdef HTC_RAW_INTERFACE - if (!eppingtest && bypasswmi) { - if (ar->arVersion.target_ver == AR6003_REV1_VERSION) { - filename = AR6003_REV1_ART_FIRMWARE_FILE; - } else if (ar->arVersion.target_ver == AR6003_REV2_VERSION) { - filename = AR6003_REV2_ART_FIRMWARE_FILE; - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver)); - return A_ERROR; - } - compressed = false; - } -#endif - 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) { - filename = AR6003_REV2_PATCH_FILE; - } else if (ar->arVersion.target_ver == AR6003_REV3_VERSION) { - filename = AR6003_REV3_PATCH_FILE; - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver)); - return A_ERROR; - } - 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) { - filename = AR6003_REV2_BOARD_DATA_FILE; - } else if (ar->arVersion.target_ver == AR6003_REV3_VERSION) { - filename = AR6003_REV3_BOARD_DATA_FILE; - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown firmware revision: %d\n", ar->arVersion.target_ver)); - return A_ERROR; - } - break; - - default: - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown file type: %d\n", file)); - return A_ERROR; - } - - 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 && *buf_len) { - ar6000_softmac_update(ar, *buf, *buf_len); - } -#endif - - - fw_entry_size = *buf_len; - - /* Load extended board data for AR6003 */ - if ((file==AR6K_BOARD_DATA_FILE) && *buf) { - u32 board_ext_address; - u32 board_ext_data_size; - u32 board_data_size; - - board_ext_data_size = (((ar)->arTargetType == TARGET_TYPE_AR6002) ? AR6002_BOARD_EXT_DATA_SZ : \ - (((ar)->arTargetType == TARGET_TYPE_AR6003) ? AR6003_BOARD_EXT_DATA_SZ : 0)); - - board_data_size = (((ar)->arTargetType == TARGET_TYPE_AR6002) ? AR6002_BOARD_DATA_SZ : \ - (((ar)->arTargetType == TARGET_TYPE_AR6003) ? AR6003_BOARD_DATA_SZ : 0)); - - /* Determine where in Target RAM to write Board Data */ - bmifn(BMIReadMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_ext_data), (u8 *)&board_ext_address, 4)); - 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) && (*buf_len == (board_data_size + board_ext_data_size))) { - u32 param; - - 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__)); - return A_ERROR; - } - - /* Record the fact that extended board Data IS initialized */ - param = (board_ext_data_size << 16) | 1; - bmifn(BMIWriteMemory(ar->arHifDevice, - HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_ext_data_config), - (unsigned char *)¶m, 4)); - } - fw_entry_size = board_data_size; - } - - if (compressed) { - status = BMIFastDownload(ar->arHifDevice, address, *buf, fw_entry_size); - } else { - status = BMIWriteMemory(ar->arHifDevice, address, *buf, fw_entry_size); - } - - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI operation failed: %d\n", __LINE__)); - return A_ERROR; - } - - return 0; -} - -int -ar6000_update_bdaddr(struct ar6_softc *ar) -{ - - if (setupbtdev != 0) { - u32 address; - - if (BMIReadMemory(ar->arHifDevice, - HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_data), (u8 *)&address, 4) != 0) - { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for hi_board_data failed\n")); - return A_ERROR; - } - - if (BMIReadMemory(ar->arHifDevice, address + BDATA_BDADDR_OFFSET, (u8 *)ar->bdaddr, 6) != 0) - { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for BD address failed\n")); - return A_ERROR; - } - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BDADDR 0x%x:0x%x:0x%x:0x%x:0x%x:0x%x\n", ar->bdaddr[0], - ar->bdaddr[1], ar->bdaddr[2], ar->bdaddr[3], - ar->bdaddr[4], ar->bdaddr[5])); - } - -return 0; -} - -int -ar6000_sysfs_bmi_get_config(struct ar6_softc *ar, u32 mode) -{ - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("BMI: Requesting device specific configuration\n")); - - if (mode == WLAN_INIT_MODE_UDEV) { - char version[16]; - const struct firmware *fw_entry; - - /* Get config using udev through a script in user space */ - sprintf(version, "%2.2x", ar->arVersion.target_ver); - if ((A_REQUEST_FIRMWARE(&fw_entry, version, ((struct device *)ar->osDevInfo.pOSDevice))) != 0) - { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI: Failure to get configuration for target version: %s\n", version)); - return A_ERROR; - } - - A_RELEASE_FIRMWARE(fw_entry); - } else { - /* The config is contained within the driver itself */ - int status; - u32 param, options, sleep, address; - - /* Temporarily disable system sleep */ - address = MBOX_BASE_ADDRESS + LOCAL_SCRATCH_ADDRESS; - bmifn(BMIReadSOCRegister(ar->arHifDevice, address, ¶m)); - options = param; - param |= AR6K_OPTION_SLEEP_DISABLE; - bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param)); - - address = RTC_BASE_ADDRESS + SYSTEM_SLEEP_ADDRESS; - bmifn(BMIReadSOCRegister(ar->arHifDevice, address, ¶m)); - sleep = param; - param |= WLAN_SYSTEM_SLEEP_DISABLE_SET(1); - bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param)); - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("old options: %d, old sleep: %d\n", options, sleep)); - - if (ar->arTargetType == TARGET_TYPE_AR6003) { - /* Program analog PLL register */ - bmifn(BMIWriteSOCRegister(ar->arHifDevice, ANALOG_INTF_BASE_ADDRESS + 0x284, 0xF9104001)); - /* Run at 80/88MHz by default */ - param = CPU_CLOCK_STANDARD_SET(1); - } else { - /* Run at 40/44MHz by default */ - param = CPU_CLOCK_STANDARD_SET(0); - } - address = RTC_BASE_ADDRESS + CPU_CLOCK_ADDRESS; - bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param)); - - param = 0; - if (ar->arTargetType == TARGET_TYPE_AR6002) { - bmifn(BMIReadMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_ext_clk_detected), (u8 *)¶m, 4)); - } - - /* LPO_CAL.ENABLE = 1 if no external clk is detected */ - if (param != 1) { - address = RTC_BASE_ADDRESS + LPO_CAL_ADDRESS; - param = LPO_CAL_ENABLE_SET(1); - bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param)); - } - - /* Venus2.0: Lower SDIO pad drive strength, - * temporary WAR to avoid SDIO CRC error */ - if (ar->arVersion.target_ver == AR6003_REV2_VERSION) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("AR6K: Temporary WAR to avoid SDIO CRC error\n")); - param = 0x20; - address = GPIO_BASE_ADDRESS + GPIO_PIN10_ADDRESS; - bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param)); - - address = GPIO_BASE_ADDRESS + GPIO_PIN11_ADDRESS; - bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param)); - - address = GPIO_BASE_ADDRESS + GPIO_PIN12_ADDRESS; - bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param)); - - address = GPIO_BASE_ADDRESS + GPIO_PIN13_ADDRESS; - bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param)); - } - -#ifdef FORCE_INTERNAL_CLOCK - /* Ignore external clock, if any, and force use of internal clock */ - if (ar->arTargetType == TARGET_TYPE_AR6003) { - /* hi_ext_clk_detected = 0 */ - param = 0; - bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_ext_clk_detected), (u8 *)¶m, 4)); - - /* CLOCK_CONTROL &= ~LF_CLK32 */ - address = RTC_BASE_ADDRESS + CLOCK_CONTROL_ADDRESS; - bmifn(BMIReadSOCRegister(ar->arHifDevice, address, ¶m)); - param &= (~CLOCK_CONTROL_LF_CLK32_SET(1)); - bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param)); - } -#endif /* FORCE_INTERNAL_CLOCK */ - - /* Transfer Board Data from Target EEPROM to Target RAM */ - if (ar->arTargetType == TARGET_TYPE_AR6003) { - /* Determine where in Target RAM to write Board Data */ - bmifn(BMIReadMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_data), (u8 *)&address, 4)); - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("Board Data download address: 0x%x\n", address)); - - /* Write EEPROM data to Target RAM */ - if ((ar6000_transfer_bin_file(ar, AR6K_BOARD_DATA_FILE, address, false)) != 0) { - return A_ERROR; - } - - /* Record the fact that Board Data IS initialized */ - param = 1; - bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_data_initialized), (u8 *)¶m, 4)); - - /* Transfer One time Programmable data */ - AR6K_APP_LOAD_ADDRESS(address, ar->arVersion.target_ver); - if (ar->arVersion.target_ver == AR6003_REV3_VERSION) - address = 0x1234; - status = ar6000_transfer_bin_file(ar, AR6K_OTP_FILE, address, true); - if (status == 0) { - /* Execute the OTP code */ - param = 0; - AR6K_APP_START_OVERRIDE_ADDRESS(address, ar->arVersion.target_ver); - bmifn(BMIExecute(ar->arHifDevice, address, ¶m)); - } else if (status != A_ENOENT) { - return A_ERROR; - } - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Programming of board data for chip %d not supported\n", ar->arTargetType)); - return A_ERROR; - } - - /* Download Target firmware */ - AR6K_APP_LOAD_ADDRESS(address, ar->arVersion.target_ver); - if (ar->arVersion.target_ver == AR6003_REV3_VERSION) - address = 0x1234; - if ((ar6000_transfer_bin_file(ar, AR6K_FIRMWARE_FILE, address, true)) != 0) { - return A_ERROR; - } - - /* Set starting address for firmware */ - AR6K_APP_START_OVERRIDE_ADDRESS(address, ar->arVersion.target_ver); - bmifn(BMISetAppStart(ar->arHifDevice, address)); - - if(ar->arTargetType == TARGET_TYPE_AR6003) { - AR6K_DATASET_PATCH_ADDRESS(address, ar->arVersion.target_ver); - if ((ar6000_transfer_bin_file(ar, AR6K_PATCH_FILE, - address, false)) != 0) - return A_ERROR; - param = address; - bmifn(BMIWriteMemory(ar->arHifDevice, - HOST_INTEREST_ITEM_ADDRESS(ar, hi_dset_list_head), - (unsigned char *)¶m, 4)); - } - - /* Restore system sleep */ - address = RTC_BASE_ADDRESS + SYSTEM_SLEEP_ADDRESS; - bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, sleep)); - - address = MBOX_BASE_ADDRESS + LOCAL_SCRATCH_ADDRESS; - param = options | 0x20; - bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param)); - - if (ar->arTargetType == TARGET_TYPE_AR6003) { - /* Configure GPIO AR6003 UART */ -#ifndef CONFIG_AR600x_DEBUG_UART_TX_PIN -#define CONFIG_AR600x_DEBUG_UART_TX_PIN 8 -#endif - param = CONFIG_AR600x_DEBUG_UART_TX_PIN; - bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_dbg_uart_txpin), (u8 *)¶m, 4)); - -#if (CONFIG_AR600x_DEBUG_UART_TX_PIN == 23) - { - address = GPIO_BASE_ADDRESS + CLOCK_GPIO_ADDRESS; - bmifn(BMIReadSOCRegister(ar->arHifDevice, address, ¶m)); - param |= CLOCK_GPIO_BT_CLK_OUT_EN_SET(1); - bmifn(BMIWriteSOCRegister(ar->arHifDevice, address, param)); - } -#endif - - /* Configure GPIO for BT Reset */ -#ifdef ATH6KL_CONFIG_GPIO_BT_RESET -#define CONFIG_AR600x_BT_RESET_PIN 0x16 - param = CONFIG_AR600x_BT_RESET_PIN; - bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_hci_uart_support_pins), (u8 *)¶m, 4)); -#endif /* ATH6KL_CONFIG_GPIO_BT_RESET */ - - /* Configure UART flow control polarity */ -#ifndef CONFIG_ATH6KL_BT_UART_FC_POLARITY -#define CONFIG_ATH6KL_BT_UART_FC_POLARITY 0 -#endif - -#if (CONFIG_ATH6KL_BT_UART_FC_POLARITY == 1) - if (ar->arVersion.target_ver == AR6003_REV2_VERSION) { - param = ((CONFIG_ATH6KL_BT_UART_FC_POLARITY << 1) & 0x2); - bmifn(BMIWriteMemory(ar->arHifDevice, HOST_INTEREST_ITEM_ADDRESS(ar, hi_hci_uart_pwr_mgmt_params), (u8 *)¶m, 4)); - } -#endif /* CONFIG_ATH6KL_BT_UART_FC_POLARITY */ - } - -#ifdef HTC_RAW_INTERFACE - if (!eppingtest && bypasswmi) { - /* Don't run BMIDone for ART mode and force resetok=0 */ - resetok = 0; - msleep(1000); - } -#endif /* HTC_RAW_INTERFACE */ - } - - return 0; -} - -int -ar6000_configure_target(struct ar6_softc *ar) -{ - u32 param; - if (enableuartprint) { - param = 1; - if (BMIWriteMemory(ar->arHifDevice, - HOST_INTEREST_ITEM_ADDRESS(ar, hi_serial_enable), - (u8 *)¶m, - 4)!= 0) - { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for enableuartprint failed \n")); - return A_ERROR; - } - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Serial console prints enabled\n")); - } - - /* Tell target which HTC version it is used*/ - param = HTC_PROTOCOL_VERSION; - if (BMIWriteMemory(ar->arHifDevice, - HOST_INTEREST_ITEM_ADDRESS(ar, hi_app_host_interest), - (u8 *)¶m, - 4)!= 0) - { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for htc version failed \n")); - return A_ERROR; - } - -#ifdef CONFIG_HOST_TCMD_SUPPORT - if(testmode) { - ar->arTargetMode = AR6000_TCMD_MODE; - }else { - ar->arTargetMode = AR6000_WLAN_MODE; - } -#endif - if (enabletimerwar) { - u32 param; - - if (BMIReadMemory(ar->arHifDevice, - HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag), - (u8 *)¶m, - 4)!= 0) - { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for enabletimerwar failed \n")); - return A_ERROR; - } - - param |= HI_OPTION_TIMER_WAR; - - if (BMIWriteMemory(ar->arHifDevice, - HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag), - (u8 *)¶m, - 4) != 0) - { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for enabletimerwar failed \n")); - return A_ERROR; - } - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Timer WAR enabled\n")); - } - - /* set the firmware mode to STA/IBSS/AP */ - { - u32 param; - - if (BMIReadMemory(ar->arHifDevice, - HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag), - (u8 *)¶m, - 4)!= 0) - { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for setting fwmode failed \n")); - return A_ERROR; - } - - param |= (num_device << HI_OPTION_NUM_DEV_SHIFT); - param |= (fwmode << HI_OPTION_FW_MODE_SHIFT); - param |= (mac_addr_method << HI_OPTION_MAC_ADDR_METHOD_SHIFT); - param |= (firmware_bridge << HI_OPTION_FW_BRIDGE_SHIFT); - - - if (BMIWriteMemory(ar->arHifDevice, - HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag), - (u8 *)¶m, - 4) != 0) - { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for setting fwmode failed \n")); - return A_ERROR; - } - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Firmware mode set\n")); - } - -#ifdef ATH6KL_DISABLE_TARGET_DBGLOGS - { - u32 param; - - if (BMIReadMemory(ar->arHifDevice, - HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag), - (u8 *)¶m, - 4)!= 0) - { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIReadMemory for disabling debug logs failed\n")); - return A_ERROR; - } - - param |= HI_OPTION_DISABLE_DBGLOG; - - if (BMIWriteMemory(ar->arHifDevice, - HOST_INTEREST_ITEM_ADDRESS(ar, hi_option_flag), - (u8 *)¶m, - 4) != 0) - { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMIWriteMemory for HI_OPTION_DISABLE_DBGLOG\n")); - return A_ERROR; - } - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("Firmware mode set\n")); - } -#endif /* ATH6KL_DISABLE_TARGET_DBGLOGS */ - - /* - * Hardcode the address use for the extended board data - * Ideally this should be pre-allocate by the OS at boot time - * But since it is a new feature and board data is loaded - * at init time, we have to workaround this from host. - * It is difficult to patch the firmware boot code, - * but possible in theory. - */ - - if (ar->arTargetType == TARGET_TYPE_AR6003) { - u32 ramReservedSz; - if (ar->arVersion.target_ver == AR6003_REV2_VERSION) { - param = AR6003_REV2_BOARD_EXT_DATA_ADDRESS; - ramReservedSz = AR6003_REV2_RAM_RESERVE_SIZE; - } else { - param = AR6003_REV3_BOARD_EXT_DATA_ADDRESS; - ramReservedSz = AR6003_REV3_RAM_RESERVE_SIZE; - } - if (BMIWriteMemory(ar->arHifDevice, - HOST_INTEREST_ITEM_ADDRESS(ar, hi_board_ext_data), - (u8 *)¶m, 4) != 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("BMIWriteMemory for " - "hi_board_ext_data failed\n")); - return A_ERROR; - } - if (BMIWriteMemory(ar->arHifDevice, - HOST_INTEREST_ITEM_ADDRESS(ar, - hi_end_RAM_reserve_sz), - (u8 *)&ramReservedSz, 4) != 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR , - ("BMIWriteMemory for " - "hi_end_RAM_reserve_sz failed\n")); - return A_ERROR; - } - } - - /* since BMIInit is called in the driver layer, we have to set the block - * size here for the target */ - - if (ar6000_set_htc_params(ar->arHifDevice, ar->arTargetType, - mbox_yield_limit, 0)) { - /* use default number of control buffers */ - return A_ERROR; - } - - if (setupbtdev != 0) { - if (ar6000_set_hci_bridge_flags(ar->arHifDevice, - ar->arTargetType, - setupbtdev)) { - return A_ERROR; - } - } - return 0; -} - -static void -init_netdev(struct net_device *dev, char *name) -{ - dev->netdev_ops = &ar6000_netdev_ops; - dev->watchdog_timeo = AR6000_TX_TIMEOUT; - - /* - * We need the OS to provide us with more headroom in order to - * perform dix to 802.3, WMI header encap, and the HTC header - */ - if (processDot11Hdr) { - dev->hard_header_len = sizeof(struct ieee80211_qosframe) + sizeof(ATH_LLC_SNAP_HDR) + sizeof(WMI_DATA_HDR) + HTC_HEADER_LEN + WMI_MAX_TX_META_SZ + LINUX_HACK_FUDGE_FACTOR; - } else { - dev->hard_header_len = ETH_HLEN + sizeof(ATH_LLC_SNAP_HDR) + - sizeof(WMI_DATA_HDR) + HTC_HEADER_LEN + WMI_MAX_TX_META_SZ + LINUX_HACK_FUDGE_FACTOR; - } - - if (name[0]) - { - strcpy(dev->name, name); - } - -#ifdef CONFIG_CHECKSUM_OFFLOAD - if(csumOffload){ - dev->features |= NETIF_F_IP_CSUM; /*advertise kernel capability to do TCP/UDP CSUM offload for IPV4*/ - } -#endif - - return; -} - -static int __ath6kl_init_netdev(struct net_device *dev) -{ - int r; - - rtnl_lock(); - r = ar6000_init(dev); - rtnl_unlock(); - - if (r) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: ar6000_init\n")); - return r; - } - - return 0; -} - -#ifdef HTC_RAW_INTERFACE -static int ath6kl_init_netdev_wmi(struct net_device *dev) -{ - if (!eppingtest && bypasswmi) - return 0; - - return __ath6kl_init_netdev(dev); -} -#else -static int ath6kl_init_netdev_wmi(struct net_device *dev) -{ - return __ath6kl_init_netdev(dev); -} -#endif - -static int ath6kl_init_netdev(struct ar6_softc *ar) -{ - int r; - - r = ar6000_sysfs_bmi_get_config(ar, wlaninitmode); - if (r) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("ar6000_avail: " - "ar6000_sysfs_bmi_get_config failed\n")); - return r; - } - - return ath6kl_init_netdev_wmi(ar->arNetDev); -} - -/* - * HTC Event handlers - */ -static int -ar6000_avail_ev(void *context, void *hif_handle) -{ - int i; - struct net_device *dev; - void *ar_netif; - struct ar6_softc *ar; - int device_index = 0; - struct htc_init_info htcInfo; - struct wireless_dev *wdev; - int r = 0; - struct hif_device_os_device_info osDevInfo; - - memset(&osDevInfo, 0, sizeof(osDevInfo)); - if (HIFConfigureDevice(hif_handle, HIF_DEVICE_GET_OS_DEVICE, - &osDevInfo, sizeof(osDevInfo))) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s: Failed to get OS device instance\n", __func__)); - return A_ERROR; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("ar6000_available\n")); - - for (i=0; i < MAX_AR6000; i++) { - if (ar6000_devices[i] == NULL) { - break; - } - } - - if (i == MAX_AR6000) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_available: max devices reached\n")); - return A_ERROR; - } - - /* Save this. It gives a bit better readability especially since */ - /* we use another local "i" variable below. */ - device_index = i; - - wdev = ar6k_cfg80211_init(osDevInfo.pOSDevice); - if (IS_ERR(wdev)) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ar6k_cfg80211_init failed\n", __func__)); - return A_ERROR; - } - ar_netif = wdev_priv(wdev); - - if (ar_netif == NULL) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Can't allocate ar6k priv memory\n", __func__)); - return A_ERROR; - } - - A_MEMZERO(ar_netif, sizeof(struct ar6_softc)); - ar = (struct ar6_softc *)ar_netif; - - ar->wdev = wdev; - wdev->iftype = NL80211_IFTYPE_STATION; - - dev = alloc_netdev_mq(0, "wlan%d", ether_setup, 1); - if (!dev) { - printk(KERN_CRIT "AR6K: no memory for network device instance\n"); - ar6k_cfg80211_deinit(ar); - return A_ERROR; - } - - dev->ieee80211_ptr = wdev; - SET_NETDEV_DEV(dev, wiphy_dev(wdev->wiphy)); - wdev->netdev = dev; - ar->arNetworkType = INFRA_NETWORK; - ar->smeState = SME_DISCONNECTED; - ar->arAutoAuthStage = AUTH_IDLE; - - init_netdev(dev, ifname); - - - ar->arNetDev = dev; - ar->arHifDevice = hif_handle; - ar->arWlanState = WLAN_ENABLED; - ar->arDeviceIndex = device_index; - - ar->arWlanPowerState = WLAN_POWER_STATE_ON; - ar->arWlanOff = false; /* We are in ON state */ -#ifdef CONFIG_PM - ar->arWowState = WLAN_WOW_STATE_NONE; - ar->arBTOff = true; /* BT chip assumed to be OFF */ - ar->arBTSharing = WLAN_CONFIG_BT_SHARING; - ar->arWlanOffConfig = WLAN_CONFIG_WLAN_OFF; - ar->arSuspendConfig = WLAN_CONFIG_PM_SUSPEND; - ar->arWow2Config = WLAN_CONFIG_PM_WOW2; -#endif /* CONFIG_PM */ - - A_INIT_TIMER(&ar->arHBChallengeResp.timer, ar6000_detect_error, dev); - ar->arHBChallengeResp.seqNum = 0; - ar->arHBChallengeResp.outstanding = false; - ar->arHBChallengeResp.missCnt = 0; - ar->arHBChallengeResp.frequency = AR6000_HB_CHALLENGE_RESP_FREQ_DEFAULT; - ar->arHBChallengeResp.missThres = AR6000_HB_CHALLENGE_RESP_MISS_THRES_DEFAULT; - - ar6000_init_control_info(ar); - init_waitqueue_head(&arEvent); - sema_init(&ar->arSem, 1); - ar->bIsDestroyProgress = false; - - INIT_HTC_PACKET_QUEUE(&ar->amsdu_rx_buffer_queue); - -#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL - A_INIT_TIMER(&aptcTimer, aptcTimerHandler, ar); -#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */ - - A_INIT_TIMER(&ar->disconnect_timer, disconnect_timer_handler, dev); - - BMIInit(); - - ar6000_sysfs_bmi_init(ar); - - { - struct bmi_target_info targ_info; - - r = BMIGetTargetInfo(ar->arHifDevice, &targ_info); - if (r) - goto avail_ev_failed; - - ar->arVersion.target_ver = targ_info.target_ver; - ar->arTargetType = targ_info.target_type; - wdev->wiphy->hw_version = targ_info.target_ver; - } - - r = ar6000_configure_target(ar); - if (r) - goto avail_ev_failed; - - A_MEMZERO(&htcInfo,sizeof(htcInfo)); - htcInfo.pContext = ar; - htcInfo.TargetFailure = ar6000_target_failure; - - ar->arHtcTarget = HTCCreate(ar->arHifDevice,&htcInfo); - - if (!ar->arHtcTarget) { - r = -ENOMEM; - goto avail_ev_failed; - } - - spin_lock_init(&ar->arLock); - -#ifdef WAPI_ENABLE - ar->arWapiEnable = 0; -#endif - - - if(csumOffload){ - /*if external frame work is also needed, change and use an extended rxMetaVerion*/ - ar->rxMetaVersion=WMI_META_VERSION_2; - } - - ar->aggr_cntxt = aggr_init(ar6000_alloc_netbufs); - if (!ar->aggr_cntxt) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() Failed to initialize aggr.\n", __func__)); - r = -ENOMEM; - goto avail_ev_failed; - } - - aggr_register_rx_dispatcher(ar->aggr_cntxt, (void *)dev, ar6000_deliver_frames_to_nw_stack); - - HIFClaimDevice(ar->arHifDevice, ar); - - /* We only register the device in the global list if we succeed. */ - /* If the device is in the global list, it will be destroyed */ - /* when the module is unloaded. */ - ar6000_devices[device_index] = dev; - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("BMI enabled: %d\n", wlaninitmode)); - if ((wlaninitmode == WLAN_INIT_MODE_UDEV) || - (wlaninitmode == WLAN_INIT_MODE_DRV)) { - r = ath6kl_init_netdev(ar); - if (r) - goto avail_ev_failed; - } - - /* This runs the init function if registered */ - r = register_netdev(dev); - if (r) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: register_netdev failed\n")); - ar6000_destroy(dev, 0); - return r; - } - - is_netdev_registered = 1; - -#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT - arApNetDev = NULL; -#endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */ - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("ar6000_avail: name=%s hifdevice=0x%lx, dev=0x%lx (%d), ar=0x%lx\n", - dev->name, (unsigned long)ar->arHifDevice, (unsigned long)dev, device_index, - (unsigned long)ar)); - -avail_ev_failed : - if (r) - ar6000_sysfs_bmi_deinit(ar); - - return r; -} - -static void ar6000_target_failure(void *Instance, int Status) -{ - struct ar6_softc *ar = (struct ar6_softc *)Instance; - WMI_TARGET_ERROR_REPORT_EVENT errEvent; - static bool sip = false; - - if (Status != 0) { - - printk(KERN_ERR "ar6000_target_failure: target asserted \n"); - - if (timer_pending(&ar->arHBChallengeResp.timer)) { - A_UNTIMEOUT(&ar->arHBChallengeResp.timer); - } - - /* try dumping target assertion information (if any) */ - ar6000_dump_target_assert_info(ar->arHifDevice,ar->arTargetType); - - /* - * Fetch the logs from the target via the diagnostic - * window. - */ - ar6000_dbglog_get_debug_logs(ar); - - /* Report the error only once */ - if (!sip) { - sip = true; - errEvent.errorVal = WMI_TARGET_COM_ERR | - WMI_TARGET_FATAL_ERR; - } - } -} - -static int -ar6000_unavail_ev(void *context, void *hif_handle) -{ - struct ar6_softc *ar = (struct ar6_softc *)context; - /* NULL out it's entry in the global list */ - ar6000_devices[ar->arDeviceIndex] = NULL; - ar6000_destroy(ar->arNetDev, 1); - - return 0; -} - -void -ar6000_restart_endpoint(struct net_device *dev) -{ - int status = 0; - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - - BMIInit(); - do { - if ( (status=ar6000_configure_target(ar))!= 0) - break; - if ( (status=ar6000_sysfs_bmi_get_config(ar, wlaninitmode)) != 0) - { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_avail: ar6000_sysfs_bmi_get_config failed\n")); - break; - } - rtnl_lock(); - status = (ar6000_init(dev)==0) ? 0 : A_ERROR; - rtnl_unlock(); - - if (status) { - break; - } - if (ar->arSsidLen && ar->arWlanState == WLAN_ENABLED) { - ar6000_connect_to_ap(ar); - } - } while (0); - - if (status== 0) { - return; - } - - ar6000_devices[ar->arDeviceIndex] = NULL; - ar6000_destroy(ar->arNetDev, 1); -} - -void -ar6000_stop_endpoint(struct net_device *dev, bool keepprofile, bool getdbglogs) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - - /* Stop the transmit queues */ - netif_stop_queue(dev); - - /* Disable the target and the interrupts associated with it */ - if (ar->arWmiReady == true) - { - if (!bypasswmi) - { - bool disconnectIssued; - - disconnectIssued = (ar->arConnected) || (ar->arConnectPending); - ar6000_disconnect(ar); - if (!keepprofile) { - ar6000_init_profile_info(ar); - } - - A_UNTIMEOUT(&ar->disconnect_timer); - - if (getdbglogs) { - ar6000_dbglog_get_debug_logs(ar); - } - - ar->arWmiReady = false; - wmi_shutdown(ar->arWmi); - ar->arWmiEnabled = false; - ar->arWmi = NULL; - /* - * After wmi_shudown all WMI events will be dropped. - * We need to cleanup the buffers allocated in AP mode - * and give disconnect notification to stack, which usually - * happens in the disconnect_event. - * Simulate the disconnect_event by calling the function directly. - * Sometimes disconnect_event will be received when the debug logs - * are collected. - */ - if (disconnectIssued) { - if(ar->arNetworkType & AP_NETWORK) { - ar6000_disconnect_event(ar, DISCONNECT_CMD, bcast_mac, 0, NULL, 0); - } else { - ar6000_disconnect_event(ar, DISCONNECT_CMD, ar->arBssid, 0, NULL, 0); - } - } - ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT; - ar->user_key_ctrl = 0; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("%s(): WMI stopped\n", __func__)); - } - else - { - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("%s(): WMI not ready 0x%lx 0x%lx\n", - __func__, (unsigned long) ar, (unsigned long) ar->arWmi)); - - /* Shut down WMI if we have started it */ - if(ar->arWmiEnabled == true) - { - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("%s(): Shut down WMI\n", __func__)); - wmi_shutdown(ar->arWmi); - ar->arWmiEnabled = false; - ar->arWmi = NULL; - } - } - - if (ar->arHtcTarget != NULL) { -#ifdef EXPORT_HCI_BRIDGE_INTERFACE - if (NULL != ar6kHciTransCallbacks.cleanupTransport) { - ar6kHciTransCallbacks.cleanupTransport(NULL); - } -#else - // FIXME: workaround to reset BT's UART baud rate to default - if (NULL != ar->exitCallback) { - struct ar3k_config_info ar3kconfig; - int status; - - A_MEMZERO(&ar3kconfig,sizeof(ar3kconfig)); - ar6000_set_default_ar3kconfig(ar, (void *)&ar3kconfig); - status = ar->exitCallback(&ar3kconfig); - if (0 != status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to reset AR3K baud rate! \n")); - } - } - // END workaround - if (setuphci) - ar6000_cleanup_hci(ar); -#endif - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,(" Shutting down HTC .... \n")); - /* stop HTC */ - HTCStop(ar->arHtcTarget); - } - - if (resetok) { - /* try to reset the device if we can - * The driver may have been configure NOT to reset the target during - * a debug session */ - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,(" Attempting to reset target on instance destroy.... \n")); - if (ar->arHifDevice != NULL) { - bool coldReset = (ar->arTargetType == TARGET_TYPE_AR6003) ? true: false; - ar6000_reset_device(ar->arHifDevice, ar->arTargetType, true, coldReset); - } - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,(" Host does not want target reset. \n")); - } - /* Done with cookies */ - ar6000_cookie_cleanup(ar); - - /* cleanup any allocated AMSDU buffers */ - ar6000_cleanup_amsdu_rxbufs(ar); -} -/* - * We need to differentiate between the surprise and planned removal of the - * device because of the following consideration: - * - In case of surprise removal, the hcd already frees up the pending - * for the device and hence there is no need to unregister the function - * driver inorder to get these requests. For planned removal, the function - * driver has to explicitly unregister itself to have the hcd return all the - * pending requests before the data structures for the devices are freed up. - * Note that as per the current implementation, the function driver will - * end up releasing all the devices since there is no API to selectively - * release a particular device. - * - Certain commands issued to the target can be skipped for surprise - * removal since they will anyway not go through. - */ -void -ar6000_destroy(struct net_device *dev, unsigned int unregister) -{ - struct ar6_softc *ar; - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("+ar6000_destroy \n")); - - if((dev == NULL) || ((ar = ar6k_priv(dev)) == NULL)) - { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s(): Failed to get device structure.\n", __func__)); - return; - } - - ar->bIsDestroyProgress = true; - - if (down_interruptible(&ar->arSem)) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s(): down_interruptible failed \n", __func__)); - return; - } - - if (ar->arWlanPowerState != WLAN_POWER_STATE_CUT_PWR) { - /* only stop endpoint if we are not stop it in suspend_ev */ - ar6000_stop_endpoint(dev, false, true); - } - - ar->arWlanState = WLAN_DISABLED; - if (ar->arHtcTarget != NULL) { - /* destroy HTC */ - HTCDestroy(ar->arHtcTarget); - } - if (ar->arHifDevice != NULL) { - /*release the device so we do not get called back on remove incase we - * we're explicity destroyed by module unload */ - HIFReleaseDevice(ar->arHifDevice); - HIFShutDownDevice(ar->arHifDevice); - } - aggr_module_destroy(ar->aggr_cntxt); - - /* Done with cookies */ - ar6000_cookie_cleanup(ar); - - /* cleanup any allocated AMSDU buffers */ - ar6000_cleanup_amsdu_rxbufs(ar); - - ar6000_sysfs_bmi_deinit(ar); - - /* Cleanup BMI */ - BMICleanup(); - - /* Clear the tx counters */ - memset(tx_attempt, 0, sizeof(tx_attempt)); - memset(tx_post, 0, sizeof(tx_post)); - memset(tx_complete, 0, sizeof(tx_complete)); - -#ifdef HTC_RAW_INTERFACE - if (ar->arRawHtc) { - kfree(ar->arRawHtc); - ar->arRawHtc = NULL; - } -#endif - /* Free up the device data structure */ - if (unregister && is_netdev_registered) { - unregister_netdev(dev); - is_netdev_registered = 0; - } - free_netdev(dev); - - ar6k_cfg80211_deinit(ar); - -#ifdef CONFIG_AP_VIRTUL_ADAPTER_SUPPORT - 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")); -} - -static void disconnect_timer_handler(unsigned long ptr) -{ - struct net_device *dev = (struct net_device *)ptr; - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - - A_UNTIMEOUT(&ar->disconnect_timer); - - ar6000_init_profile_info(ar); - ar6000_disconnect(ar); -} - -static void ar6000_detect_error(unsigned long ptr) -{ - struct net_device *dev = (struct net_device *)ptr; - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - WMI_TARGET_ERROR_REPORT_EVENT errEvent; - - AR6000_SPIN_LOCK(&ar->arLock, 0); - - if (ar->arHBChallengeResp.outstanding) { - ar->arHBChallengeResp.missCnt++; - } else { - ar->arHBChallengeResp.missCnt = 0; - } - - if (ar->arHBChallengeResp.missCnt > ar->arHBChallengeResp.missThres) { - /* Send Error Detect event to the application layer and do not reschedule the error detection module timer */ - ar->arHBChallengeResp.missCnt = 0; - ar->arHBChallengeResp.seqNum = 0; - errEvent.errorVal = WMI_TARGET_COM_ERR | WMI_TARGET_FATAL_ERR; - AR6000_SPIN_UNLOCK(&ar->arLock, 0); - return; - } - - /* Generate the sequence number for the next challenge */ - ar->arHBChallengeResp.seqNum++; - ar->arHBChallengeResp.outstanding = true; - - AR6000_SPIN_UNLOCK(&ar->arLock, 0); - - /* Send the challenge on the control channel */ - if (wmi_get_challenge_resp_cmd(ar->arWmi, ar->arHBChallengeResp.seqNum, DRV_HB_CHALLENGE) != 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to send heart beat challenge\n")); - } - - - /* Reschedule the timer for the next challenge */ - A_TIMEOUT_MS(&ar->arHBChallengeResp.timer, ar->arHBChallengeResp.frequency * 1000, 0); -} - -void ar6000_init_profile_info(struct ar6_softc *ar) -{ - ar->arSsidLen = 0; - A_MEMZERO(ar->arSsid, sizeof(ar->arSsid)); - - switch(fwmode) { - case HI_OPTION_FW_MODE_IBSS: - ar->arNetworkType = ar->arNextMode = ADHOC_NETWORK; - break; - case HI_OPTION_FW_MODE_BSS_STA: - ar->arNetworkType = ar->arNextMode = INFRA_NETWORK; - break; - case HI_OPTION_FW_MODE_AP: - ar->arNetworkType = ar->arNextMode = AP_NETWORK; - break; - } - - ar->arDot11AuthMode = OPEN_AUTH; - ar->arAuthMode = NONE_AUTH; - ar->arPairwiseCrypto = NONE_CRYPT; - ar->arPairwiseCryptoLen = 0; - ar->arGroupCrypto = NONE_CRYPT; - ar->arGroupCryptoLen = 0; - A_MEMZERO(ar->arWepKeyList, sizeof(ar->arWepKeyList)); - A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid)); - A_MEMZERO(ar->arBssid, sizeof(ar->arBssid)); - ar->arBssChannel = 0; -} - -static void -ar6000_init_control_info(struct ar6_softc *ar) -{ - ar->arWmiEnabled = false; - ar6000_init_profile_info(ar); - ar->arDefTxKeyIndex = 0; - A_MEMZERO(ar->arWepKeyList, sizeof(ar->arWepKeyList)); - ar->arChannelHint = 0; - ar->arListenIntervalT = A_DEFAULT_LISTEN_INTERVAL; - ar->arListenIntervalB = 0; - ar->arVersion.host_ver = AR6K_SW_VERSION; - ar->arRssi = 0; - ar->arTxPwr = 0; - ar->arTxPwrSet = false; - ar->arSkipScan = 0; - ar->arBeaconInterval = 0; - ar->arBitRate = 0; - ar->arMaxRetries = 0; - ar->arWmmEnabled = true; - ar->intra_bss = 1; - ar->scan_triggered = 0; - A_MEMZERO(&ar->scParams, sizeof(ar->scParams)); - ar->scParams.shortScanRatio = WMI_SHORTSCANRATIO_DEFAULT; - ar->scParams.scanCtrlFlags = DEFAULT_SCAN_CTRL_FLAGS; - - /* Initialize the AP mode state info */ - { - u8 ctr; - A_MEMZERO((u8 *)ar->sta_list, AP_MAX_NUM_STA * sizeof(sta_t)); - - /* init the Mutexes */ - A_MUTEX_INIT(&ar->mcastpsqLock); - - /* Init the PS queues */ - for (ctr=0; ctr < AP_MAX_NUM_STA ; ctr++) { - A_MUTEX_INIT(&ar->sta_list[ctr].psqLock); - A_NETBUF_QUEUE_INIT(&ar->sta_list[ctr].psq); - } - - ar->ap_profile_flag = 0; - A_NETBUF_QUEUE_INIT(&ar->mcastpsq); - - memcpy(ar->ap_country_code, DEF_AP_COUNTRY_CODE, 3); - ar->ap_wmode = DEF_AP_WMODE_G; - ar->ap_dtim_period = DEF_AP_DTIM; - ar->ap_beacon_interval = DEF_BEACON_INTERVAL; - } -} - -static int -ar6000_open(struct net_device *dev) -{ - unsigned long flags; - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - - spin_lock_irqsave(&ar->arLock, flags); - - if(ar->arWlanState == WLAN_DISABLED) { - ar->arWlanState = WLAN_ENABLED; - } - - if( ar->arConnected || bypasswmi) { - netif_carrier_on(dev); - /* Wake up the queues */ - netif_wake_queue(dev); - } - else - netif_carrier_off(dev); - - spin_unlock_irqrestore(&ar->arLock, flags); - return 0; -} - -static int -ar6000_close(struct net_device *dev) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - netif_stop_queue(dev); - - ar6000_disconnect(ar); - - if(ar->arWmiReady == true) { - if (wmi_scanparams_cmd(ar->arWmi, 0xFFFF, 0, - 0, 0, 0, 0, 0, 0, 0, 0) != 0) { - return -EIO; - } - ar->arWlanState = WLAN_DISABLED; - } - ar6k_cfg80211_scanComplete_event(ar, A_ECANCELED); - - return 0; -} - -/* connect to a service */ -static int ar6000_connectservice(struct ar6_softc *ar, - struct htc_service_connect_req *pConnect, - char *pDesc) -{ - int status; - struct htc_service_connect_resp response; - - do { - - A_MEMZERO(&response,sizeof(response)); - - status = HTCConnectService(ar->arHtcTarget, - pConnect, - &response); - - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" Failed to connect to %s service status:%d \n", - pDesc, status)); - break; - } - switch (pConnect->ServiceID) { - case WMI_CONTROL_SVC : - if (ar->arWmiEnabled) { - /* set control endpoint for WMI use */ - wmi_set_control_ep(ar->arWmi, response.Endpoint); - } - /* save EP for fast lookup */ - ar->arControlEp = response.Endpoint; - break; - case WMI_DATA_BE_SVC : - arSetAc2EndpointIDMap(ar, WMM_AC_BE, response.Endpoint); - break; - case WMI_DATA_BK_SVC : - arSetAc2EndpointIDMap(ar, WMM_AC_BK, response.Endpoint); - break; - case WMI_DATA_VI_SVC : - arSetAc2EndpointIDMap(ar, WMM_AC_VI, response.Endpoint); - break; - case WMI_DATA_VO_SVC : - arSetAc2EndpointIDMap(ar, WMM_AC_VO, response.Endpoint); - break; - default: - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ServiceID not mapped %d\n", pConnect->ServiceID)); - status = A_EINVAL; - break; - } - - } while (false); - - return status; -} - -void ar6000_TxDataCleanup(struct ar6_softc *ar) -{ - /* flush all the data (non-control) streams - * we only flush packets that are tagged as data, we leave any control packets that - * were in the TX queues alone */ - HTCFlushEndpoint(ar->arHtcTarget, - arAc2EndpointID(ar, WMM_AC_BE), - AR6K_DATA_PKT_TAG); - HTCFlushEndpoint(ar->arHtcTarget, - arAc2EndpointID(ar, WMM_AC_BK), - AR6K_DATA_PKT_TAG); - HTCFlushEndpoint(ar->arHtcTarget, - arAc2EndpointID(ar, WMM_AC_VI), - AR6K_DATA_PKT_TAG); - HTCFlushEndpoint(ar->arHtcTarget, - arAc2EndpointID(ar, WMM_AC_VO), - AR6K_DATA_PKT_TAG); -} - -HTC_ENDPOINT_ID -ar6000_ac2_endpoint_id ( void * devt, u8 ac) -{ - struct ar6_softc *ar = (struct ar6_softc *) devt; - return(arAc2EndpointID(ar, ac)); -} - -u8 ar6000_endpoint_id2_ac(void * devt, HTC_ENDPOINT_ID ep ) -{ - struct ar6_softc *ar = (struct ar6_softc *) devt; - return(arEndpoint2Ac(ar, ep )); -} - -#if defined(CONFIG_ATH6KL_ENABLE_COEXISTENCE) -static int ath6kl_config_btcoex_params(struct ar6_softc *ar) -{ - int r; - WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD sbcb_cmd; - WMI_SET_BTCOEX_FE_ANT_CMD sbfa_cmd; - - /* Configure the type of BT collocated with WLAN */ - memset(&sbcb_cmd, 0, sizeof(WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD)); - sbcb_cmd.btcoexCoLocatedBTdev = ATH6KL_BT_DEV; - - r = wmi_set_btcoex_colocated_bt_dev_cmd(ar->arWmi, &sbcb_cmd); - - if (r) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("Unable to set collocated BT type\n")); - return r; - } - - /* Configure the type of BT collocated with WLAN */ - memset(&sbfa_cmd, 0, sizeof(WMI_SET_BTCOEX_FE_ANT_CMD)); - - sbfa_cmd.btcoexFeAntType = ATH6KL_BT_ANTENNA; - - r = wmi_set_btcoex_fe_ant_cmd(ar->arWmi, &sbfa_cmd); - if (r) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("Unable to set fornt end antenna configuration\n")); - return r; - } - - return 0; -} -#else -static int ath6kl_config_btcoex_params(struct ar6_softc *ar) -{ - return 0; -} -#endif /* CONFIG_ATH6KL_ENABLE_COEXISTENCE */ - -/* - * This function applies WLAN specific configuration defined in wlan_config.h - */ -int ar6000_target_config_wlan_params(struct ar6_softc *ar) -{ - int status = 0; - -#ifdef CONFIG_HOST_TCMD_SUPPORT - if (ar->arTargetMode != AR6000_WLAN_MODE) { - return 0; - } -#endif /* CONFIG_HOST_TCMD_SUPPORT */ - - /* - * configure the device for rx dot11 header rules 0,0 are the default values - * therefore this command can be skipped if the inputs are 0,FALSE,FALSE.Required - * if checksum offload is needed. Set RxMetaVersion to 2 - */ - if ((wmi_set_rx_frame_format_cmd(ar->arWmi,ar->rxMetaVersion, processDot11Hdr, processDot11Hdr)) != 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set the rx frame format.\n")); - status = A_ERROR; - } - - status = ath6kl_config_btcoex_params(ar); - if (status) - return status; - -#if WLAN_CONFIG_IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN - if ((wmi_pmparams_cmd(ar->arWmi, 0, 1, 0, 0, 1, IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN)) != 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set power save fail event policy\n")); - status = A_ERROR; - } -#endif - -#if WLAN_CONFIG_DONOT_IGNORE_BARKER_IN_ERP - if ((wmi_set_lpreamble_cmd(ar->arWmi, 0, WMI_DONOT_IGNORE_BARKER_IN_ERP)) != 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set barker preamble policy\n")); - status = A_ERROR; - } -#endif - - if ((wmi_set_keepalive_cmd(ar->arWmi, WLAN_CONFIG_KEEP_ALIVE_INTERVAL)) != 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set keep alive interval\n")); - status = A_ERROR; - } - -#if WLAN_CONFIG_DISABLE_11N - { - WMI_SET_HT_CAP_CMD htCap; - - memset(&htCap, 0, sizeof(WMI_SET_HT_CAP_CMD)); - htCap.band = 0; - if ((wmi_set_ht_cap_cmd(ar->arWmi, &htCap)) != 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set ht capabilities \n")); - status = A_ERROR; - } - - htCap.band = 1; - if ((wmi_set_ht_cap_cmd(ar->arWmi, &htCap)) != 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set ht capabilities \n")); - status = A_ERROR; - } - } -#endif /* WLAN_CONFIG_DISABLE_11N */ - -#ifdef ATH6K_CONFIG_OTA_MODE - if ((wmi_powermode_cmd(ar->arWmi, MAX_PERF_POWER)) != 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set power mode \n")); - status = A_ERROR; - } -#endif - - if ((wmi_disctimeout_cmd(ar->arWmi, WLAN_CONFIG_DISCONNECT_TIMEOUT)) != 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set disconnect timeout \n")); - status = A_ERROR; - } - -#if WLAN_CONFIG_DISABLE_TX_BURSTING - if ((wmi_set_wmm_txop(ar->arWmi, WMI_TXOP_DISABLED)) != 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set txop bursting \n")); - status = A_ERROR; - } -#endif - - return status; -} - -/* This function does one time initialization for the lifetime of the device */ -int ar6000_init(struct net_device *dev) -{ - struct ar6_softc *ar; - int status; - s32 timeleft; - s16 i; - int ret = 0; - - if((ar = ar6k_priv(dev)) == NULL) - { - return -EIO; - } - - if (wlaninitmode == WLAN_INIT_MODE_USR || wlaninitmode == WLAN_INIT_MODE_DRV) { - - ar6000_update_bdaddr(ar); - - if (enablerssicompensation) { - ar6000_copy_cust_data_from_target(ar->arHifDevice, ar->arTargetType); - read_rssi_compensation_param(ar); - for (i=-95; i<=0; i++) { - rssi_compensation_table[0-i] = rssi_compensation_calc(ar,i); - } - } - } - - dev_hold(dev); - rtnl_unlock(); - - /* Do we need to finish the BMI phase */ - if ((wlaninitmode == WLAN_INIT_MODE_USR || wlaninitmode == WLAN_INIT_MODE_DRV) && - (BMIDone(ar->arHifDevice) != 0)) - { - ret = -EIO; - goto ar6000_init_done; - } - - if (!bypasswmi) - { -#if 0 /* TBDXXX */ - if (ar->arVersion.host_ver != ar->arVersion.target_ver) { - A_PRINTF("WARNING: Host version 0x%x does not match Target " - " version 0x%x!\n", - ar->arVersion.host_ver, ar->arVersion.target_ver); - } -#endif - - /* Indicate that WMI is enabled (although not ready yet) */ - ar->arWmiEnabled = true; - if ((ar->arWmi = wmi_init((void *) ar)) == NULL) - { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() Failed to initialize WMI.\n", __func__)); - ret = -EIO; - goto ar6000_init_done; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() Got WMI @ 0x%lx.\n", __func__, - (unsigned long) ar->arWmi)); - } - - do { - struct htc_service_connect_req connect; - - /* the reason we have to wait for the target here is that the driver layer - * has to init BMI in order to set the host block size, - */ - status = HTCWaitTarget(ar->arHtcTarget); - - if (status) { - break; - } - - A_MEMZERO(&connect,sizeof(connect)); - /* meta data is unused for now */ - connect.pMetaData = NULL; - connect.MetaDataLength = 0; - /* these fields are the same for all service endpoints */ - connect.EpCallbacks.pContext = ar; - connect.EpCallbacks.EpTxCompleteMultiple = ar6000_tx_complete; - connect.EpCallbacks.EpRecv = ar6000_rx; - connect.EpCallbacks.EpRecvRefill = ar6000_rx_refill; - connect.EpCallbacks.EpSendFull = ar6000_tx_queue_full; - /* set the max queue depth so that our ar6000_tx_queue_full handler gets called. - * Linux has the peculiarity of not providing flow control between the - * NIC and the network stack. There is no API to indicate that a TX packet - * was sent which could provide some back pressure to the network stack. - * Under linux you would have to wait till the network stack consumed all sk_buffs - * before any back-flow kicked in. Which isn't very friendly. - * So we have to manage this ourselves */ - connect.MaxSendQueueDepth = MAX_DEFAULT_SEND_QUEUE_DEPTH; - connect.EpCallbacks.RecvRefillWaterMark = AR6000_MAX_RX_BUFFERS / 4; /* set to 25 % */ - if (0 == connect.EpCallbacks.RecvRefillWaterMark) { - connect.EpCallbacks.RecvRefillWaterMark++; - } - /* connect to control service */ - connect.ServiceID = WMI_CONTROL_SVC; - status = ar6000_connectservice(ar, - &connect, - "WMI CONTROL"); - if (status) { - break; - } - - connect.LocalConnectionFlags |= HTC_LOCAL_CONN_FLAGS_ENABLE_SEND_BUNDLE_PADDING; - /* limit the HTC message size on the send path, although we can receive A-MSDU frames of - * 4K, we will only send ethernet-sized (802.3) frames on the send path. */ - connect.MaxSendMsgSize = WMI_MAX_TX_DATA_FRAME_LENGTH; - - /* to reduce the amount of committed memory for larger A_MSDU frames, use the recv-alloc threshold - * mechanism for larger packets */ - connect.EpCallbacks.RecvAllocThreshold = AR6000_BUFFER_SIZE; - connect.EpCallbacks.EpRecvAllocThresh = ar6000_alloc_amsdu_rxbuf; - - /* for the remaining data services set the connection flag to reduce dribbling, - * if configured to do so */ - if (reduce_credit_dribble) { - connect.ConnectionFlags |= HTC_CONNECT_FLAGS_REDUCE_CREDIT_DRIBBLE; - /* the credit dribble trigger threshold is (reduce_credit_dribble - 1) for a value - * of 0-3 */ - connect.ConnectionFlags &= ~HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_MASK; - connect.ConnectionFlags |= - ((u16)reduce_credit_dribble - 1) & HTC_CONNECT_FLAGS_THRESHOLD_LEVEL_MASK; - } - /* connect to best-effort service */ - connect.ServiceID = WMI_DATA_BE_SVC; - - status = ar6000_connectservice(ar, - &connect, - "WMI DATA BE"); - if (status) { - break; - } - - /* connect to back-ground - * map this to WMI LOW_PRI */ - connect.ServiceID = WMI_DATA_BK_SVC; - status = ar6000_connectservice(ar, - &connect, - "WMI DATA BK"); - if (status) { - break; - } - - /* connect to Video service, map this to - * to HI PRI */ - connect.ServiceID = WMI_DATA_VI_SVC; - status = ar6000_connectservice(ar, - &connect, - "WMI DATA VI"); - if (status) { - break; - } - - /* connect to VO service, this is currently not - * mapped to a WMI priority stream due to historical reasons. - * WMI originally defined 3 priorities over 3 mailboxes - * We can change this when WMI is reworked so that priorities are not - * dependent on mailboxes */ - connect.ServiceID = WMI_DATA_VO_SVC; - status = ar6000_connectservice(ar, - &connect, - "WMI DATA VO"); - if (status) { - break; - } - - A_ASSERT(arAc2EndpointID(ar,WMM_AC_BE) != 0); - A_ASSERT(arAc2EndpointID(ar,WMM_AC_BK) != 0); - A_ASSERT(arAc2EndpointID(ar,WMM_AC_VI) != 0); - A_ASSERT(arAc2EndpointID(ar,WMM_AC_VO) != 0); - - /* setup access class priority mappings */ - ar->arAcStreamPriMap[WMM_AC_BK] = 0; /* lowest */ - ar->arAcStreamPriMap[WMM_AC_BE] = 1; /* */ - ar->arAcStreamPriMap[WMM_AC_VI] = 2; /* */ - ar->arAcStreamPriMap[WMM_AC_VO] = 3; /* highest */ - -#ifdef EXPORT_HCI_BRIDGE_INTERFACE - if (setuphci && (NULL != ar6kHciTransCallbacks.setupTransport)) { - struct hci_transport_misc_handles hciHandles; - - hciHandles.netDevice = ar->arNetDev; - hciHandles.hifDevice = ar->arHifDevice; - hciHandles.htcHandle = ar->arHtcTarget; - status = (int)(ar6kHciTransCallbacks.setupTransport(&hciHandles)); - } -#else - if (setuphci) { - /* setup HCI */ - status = ar6000_setup_hci(ar); - } -#endif - - } while (false); - - if (status) { - ret = -EIO; - goto ar6000_init_done; - } - - if (regscanmode) { - u32 param; - - if (BMIReadMemory(ar->arHifDevice, - HOST_INTEREST_ITEM_ADDRESS(ar, - hi_option_flag), - (u8 *)¶m, - 4) != 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("BMIReadMemory forsetting " - "regscanmode failed\n")); - return A_ERROR; - } - - if (regscanmode == 1) - param |= HI_OPTION_SKIP_REG_SCAN; - else if (regscanmode == 2) - param |= HI_OPTION_INIT_REG_SCAN; - - if (BMIWriteMemory(ar->arHifDevice, - HOST_INTEREST_ITEM_ADDRESS(ar, - hi_option_flag), - (u8 *)¶m, - 4) != 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("BMIWriteMemory forsetting " - "regscanmode failed\n")); - return A_ERROR; - } - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("Regulatory scan mode set\n")); - } - - /* - * give our connected endpoints some buffers - */ - - ar6000_rx_refill(ar, ar->arControlEp); - ar6000_rx_refill(ar, arAc2EndpointID(ar,WMM_AC_BE)); - - /* - * We will post the receive buffers only for SPE or endpoint ping testing so we are - * making it conditional on the 'bypasswmi' flag. - */ - if (bypasswmi) { - ar6000_rx_refill(ar,arAc2EndpointID(ar,WMM_AC_BK)); - ar6000_rx_refill(ar,arAc2EndpointID(ar,WMM_AC_VI)); - ar6000_rx_refill(ar,arAc2EndpointID(ar,WMM_AC_VO)); - } - - /* allocate some buffers that handle larger AMSDU frames */ - ar6000_refill_amsdu_rxbufs(ar,AR6000_MAX_AMSDU_RX_BUFFERS); - - /* setup credit distribution */ - ar6000_setup_credit_dist(ar->arHtcTarget, &ar->arCreditStateInfo); - - /* Since cookies are used for HTC transports, they should be */ - /* initialized prior to enabling HTC. */ - ar6000_cookie_init(ar); - - /* start HTC */ - status = HTCStart(ar->arHtcTarget); - - if (status) { - if (ar->arWmiEnabled == true) { - wmi_shutdown(ar->arWmi); - ar->arWmiEnabled = false; - ar->arWmi = NULL; - } - ar6000_cookie_cleanup(ar); - ret = -EIO; - goto ar6000_init_done; - } - - if (!bypasswmi) { - /* Wait for Wmi event to be ready */ - timeleft = wait_event_interruptible_timeout(arEvent, - (ar->arWmiReady == true), wmitimeout * HZ); - - if (ar->arVersion.abi_ver != AR6K_ABI_VERSION) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ABI Version mismatch: Host(0x%x), Target(0x%x)\n", AR6K_ABI_VERSION, ar->arVersion.abi_ver)); -#ifndef ATH6K_SKIP_ABI_VERSION_CHECK - ret = -EIO; - goto ar6000_init_done; -#endif /* ATH6K_SKIP_ABI_VERSION_CHECK */ - } - - if(!timeleft || signal_pending(current)) - { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("WMI is not ready or wait was interrupted\n")); - ret = -EIO; - goto ar6000_init_done; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() WMI is ready\n", __func__)); - - /* Communicate the wmi protocol verision to the target */ - if ((ar6000_set_host_app_area(ar)) != 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to set the host app area\n")); - } - ar6000_target_config_wlan_params(ar); - } - - ar->arNumDataEndPts = 1; - - if (bypasswmi) { - /* for tests like endpoint ping, the MAC address needs to be non-zero otherwise - * the data path through a raw socket is disabled */ - dev->dev_addr[0] = 0x00; - dev->dev_addr[1] = 0x01; - dev->dev_addr[2] = 0x02; - dev->dev_addr[3] = 0xAA; - dev->dev_addr[4] = 0xBB; - dev->dev_addr[5] = 0xCC; - } - -ar6000_init_done: - rtnl_lock(); - dev_put(dev); - - return ret; -} - - -void -ar6000_bitrate_rx(void *devt, s32 rateKbps) -{ - struct ar6_softc *ar = (struct ar6_softc *)devt; - - ar->arBitRate = rateKbps; - wake_up(&arEvent); -} - -void -ar6000_ratemask_rx(void *devt, u32 ratemask) -{ - struct ar6_softc *ar = (struct ar6_softc *)devt; - - ar->arRateMask = ratemask; - wake_up(&arEvent); -} - -void -ar6000_txPwr_rx(void *devt, u8 txPwr) -{ - struct ar6_softc *ar = (struct ar6_softc *)devt; - - ar->arTxPwr = txPwr; - wake_up(&arEvent); -} - - -void -ar6000_channelList_rx(void *devt, s8 numChan, u16 *chanList) -{ - struct ar6_softc *ar = (struct ar6_softc *)devt; - - memcpy(ar->arChannelList, chanList, numChan * sizeof (u16)); - ar->arNumChannels = numChan; - - wake_up(&arEvent); -} - -u8 ar6000_ibss_map_epid(struct sk_buff *skb, struct net_device *dev, u32 *mapNo) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - u8 *datap; - ATH_MAC_HDR *macHdr; - u32 i, eptMap; - - (*mapNo) = 0; - datap = A_NETBUF_DATA(skb); - macHdr = (ATH_MAC_HDR *)(datap + sizeof(WMI_DATA_HDR)); - if (IEEE80211_IS_MULTICAST(macHdr->dstMac)) { - return ENDPOINT_2; - } - - eptMap = -1; - for (i = 0; i < ar->arNodeNum; i ++) { - if (IEEE80211_ADDR_EQ(macHdr->dstMac, ar->arNodeMap[i].macAddress)) { - (*mapNo) = i + 1; - ar->arNodeMap[i].txPending ++; - return ar->arNodeMap[i].epId; - } - - if ((eptMap == -1) && !ar->arNodeMap[i].txPending) { - eptMap = i; - } - } - - if (eptMap == -1) { - eptMap = ar->arNodeNum; - ar->arNodeNum ++; - A_ASSERT(ar->arNodeNum <= MAX_NODE_NUM); - } - - memcpy(ar->arNodeMap[eptMap].macAddress, macHdr->dstMac, IEEE80211_ADDR_LEN); - - for (i = ENDPOINT_2; i <= ENDPOINT_5; i ++) { - if (!ar->arTxPending[i]) { - ar->arNodeMap[eptMap].epId = i; - break; - } - // No free endpoint is available, start redistribution on the inuse endpoints. - if (i == ENDPOINT_5) { - ar->arNodeMap[eptMap].epId = ar->arNexEpId; - ar->arNexEpId ++; - if (ar->arNexEpId > ENDPOINT_5) { - ar->arNexEpId = ENDPOINT_2; - } - } - } - - (*mapNo) = eptMap + 1; - ar->arNodeMap[eptMap].txPending ++; - - return ar->arNodeMap[eptMap].epId; -} - -#ifdef DEBUG -static void ar6000_dump_skb(struct sk_buff *skb) -{ - u_char *ch; - for (ch = A_NETBUF_DATA(skb); - (unsigned long)ch < ((unsigned long)A_NETBUF_DATA(skb) + - A_NETBUF_LEN(skb)); ch++) - { - AR_DEBUG_PRINTF(ATH_DEBUG_WARN,("%2.2x ", *ch)); - } - AR_DEBUG_PRINTF(ATH_DEBUG_WARN,("\n")); -} -#endif - -#ifdef HTC_TEST_SEND_PKTS -static void DoHTCSendPktsTest(struct ar6_softc *ar, int MapNo, HTC_ENDPOINT_ID eid, struct sk_buff *skb); -#endif - -static int -ar6000_data_tx(struct sk_buff *skb, struct net_device *dev) -{ -#define AC_NOT_MAPPED 99 - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - u8 ac = AC_NOT_MAPPED; - HTC_ENDPOINT_ID eid = ENDPOINT_UNUSED; - u32 mapNo = 0; - int len; - struct ar_cookie *cookie; - bool checkAdHocPsMapping = false,bMoreData = false; - HTC_TX_TAG htc_tag = AR6K_DATA_PKT_TAG; - u8 dot11Hdr = processDot11Hdr; -#ifdef CONFIG_PM - if (ar->arWowState != WLAN_WOW_STATE_NONE) { - A_NETBUF_FREE(skb); - return 0; - } -#endif /* CONFIG_PM */ - - AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("ar6000_data_tx start - skb=0x%lx, data=0x%lx, len=0x%x\n", - (unsigned long)skb, (unsigned long)A_NETBUF_DATA(skb), - A_NETBUF_LEN(skb))); - - /* If target is not associated */ - if( (!ar->arConnected && !bypasswmi) -#ifdef CONFIG_HOST_TCMD_SUPPORT - /* TCMD doesn't support any data, free the buf and return */ - || (ar->arTargetMode == AR6000_TCMD_MODE) -#endif - ) { - A_NETBUF_FREE(skb); - return 0; - } - - do { - - if (ar->arWmiReady == false && bypasswmi == 0) { - break; - } - -#ifdef BLOCK_TX_PATH_FLAG - if (blocktx) { - break; - } -#endif /* BLOCK_TX_PATH_FLAG */ - - /* AP mode Power save processing */ - /* If the dst STA is in sleep state, queue the pkt in its PS queue */ - - if (ar->arNetworkType == AP_NETWORK) { - ATH_MAC_HDR *datap = (ATH_MAC_HDR *)A_NETBUF_DATA(skb); - sta_t *conn = NULL; - - /* If the dstMac is a Multicast address & atleast one of the - * associated STA is in PS mode, then queue the pkt to the - * mcastq - */ - if (IEEE80211_IS_MULTICAST(datap->dstMac)) { - u8 ctr=0; - bool qMcast=false; - - - for (ctr=0; ctr<AP_MAX_NUM_STA; ctr++) { - if (STA_IS_PWR_SLEEP((&ar->sta_list[ctr]))) { - qMcast = true; - } - } - if(qMcast) { - - /* If this transmit is not because of a Dtim Expiry q it */ - if (ar->DTIMExpired == false) { - bool isMcastqEmpty = false; - - A_MUTEX_LOCK(&ar->mcastpsqLock); - isMcastqEmpty = A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq); - A_NETBUF_ENQUEUE(&ar->mcastpsq, skb); - A_MUTEX_UNLOCK(&ar->mcastpsqLock); - - /* If this is the first Mcast pkt getting queued - * indicate to the target to set the BitmapControl LSB - * of the TIM IE. - */ - if (isMcastqEmpty) { - wmi_set_pvb_cmd(ar->arWmi, MCAST_AID, 1); - } - return 0; - } else { - /* This transmit is because of Dtim expiry. Determine if - * MoreData bit has to be set. - */ - A_MUTEX_LOCK(&ar->mcastpsqLock); - if(!A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq)) { - bMoreData = true; - } - A_MUTEX_UNLOCK(&ar->mcastpsqLock); - } - } - } else { - conn = ieee80211_find_conn(ar, datap->dstMac); - if (conn) { - if (STA_IS_PWR_SLEEP(conn)) { - /* If this transmit is not because of a PsPoll q it*/ - if (!STA_IS_PS_POLLED(conn)) { - bool isPsqEmpty = false; - /* Queue the frames if the STA is sleeping */ - A_MUTEX_LOCK(&conn->psqLock); - isPsqEmpty = A_NETBUF_QUEUE_EMPTY(&conn->psq); - A_NETBUF_ENQUEUE(&conn->psq, skb); - A_MUTEX_UNLOCK(&conn->psqLock); - - /* If this is the first pkt getting queued - * for this STA, update the PVB for this STA - */ - if (isPsqEmpty) { - wmi_set_pvb_cmd(ar->arWmi, conn->aid, 1); - } - - return 0; - } else { - /* This tx is because of a PsPoll. Determine if - * MoreData bit has to be set - */ - A_MUTEX_LOCK(&conn->psqLock); - if (!A_NETBUF_QUEUE_EMPTY(&conn->psq)) { - bMoreData = true; - } - A_MUTEX_UNLOCK(&conn->psqLock); - } - } - } else { - - /* non existent STA. drop the frame */ - A_NETBUF_FREE(skb); - return 0; - } - } - } - - if (ar->arWmiEnabled) { - u8 csumStart=0; - u8 csumDest=0; - u8 csum=skb->ip_summed; - if(csumOffload && (csum==CHECKSUM_PARTIAL)){ - csumStart = (skb->head + skb->csum_start - skb_network_header(skb) + - sizeof(ATH_LLC_SNAP_HDR)); - csumDest=skb->csum_offset+csumStart; - } - if (A_NETBUF_HEADROOM(skb) < dev->hard_header_len - LINUX_HACK_FUDGE_FACTOR) { - struct sk_buff *newbuf; - - /* - * We really should have gotten enough headroom but sometimes - * we still get packets with not enough headroom. Copy the packet. - */ - len = A_NETBUF_LEN(skb); - newbuf = A_NETBUF_ALLOC(len); - if (newbuf == NULL) { - break; - } - A_NETBUF_PUT(newbuf, len); - memcpy(A_NETBUF_DATA(newbuf), A_NETBUF_DATA(skb), len); - A_NETBUF_FREE(skb); - skb = newbuf; - /* fall through and assemble header */ - } - - if (dot11Hdr) { - if (wmi_dot11_hdr_add(ar->arWmi,skb,ar->arNetworkType) != 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_data_tx-wmi_dot11_hdr_add failed\n")); - break; - } - } else { - if (wmi_dix_2_dot3(ar->arWmi, skb) != 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_data_tx - wmi_dix_2_dot3 failed\n")); - break; - } - } - if(csumOffload && (csum ==CHECKSUM_PARTIAL)){ - WMI_TX_META_V2 metaV2; - metaV2.csumStart =csumStart; - metaV2.csumDest = csumDest; - metaV2.csumFlags = 0x1;/*instruct target to calculate checksum*/ - if (wmi_data_hdr_add(ar->arWmi, skb, DATA_MSGTYPE, bMoreData, dot11Hdr, - WMI_META_VERSION_2,&metaV2) != 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_data_tx - wmi_data_hdr_add failed\n")); - break; - } - - } - else - { - if (wmi_data_hdr_add(ar->arWmi, skb, DATA_MSGTYPE, bMoreData, dot11Hdr,0,NULL) != 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_data_tx - wmi_data_hdr_add failed\n")); - break; - } - } - - - if ((ar->arNetworkType == ADHOC_NETWORK) && - ar->arIbssPsEnable && ar->arConnected) { - /* flag to check adhoc mapping once we take the lock below: */ - checkAdHocPsMapping = true; - - } else { - /* get the stream mapping */ - ac = wmi_implicit_create_pstream(ar->arWmi, skb, 0, ar->arWmmEnabled); - } - - } else { - EPPING_HEADER *eppingHdr; - - eppingHdr = A_NETBUF_DATA(skb); - - if (IS_EPPING_PACKET(eppingHdr)) { - /* the stream ID is mapped to an access class */ - ac = eppingHdr->StreamNo_h; - /* some EPPING packets cannot be dropped no matter what access class it was - * sent on. We can change the packet tag to guarantee it will not get dropped */ - if (IS_EPING_PACKET_NO_DROP(eppingHdr)) { - htc_tag = AR6K_CONTROL_PKT_TAG; - } - - if (ac == HCI_TRANSPORT_STREAM_NUM) { - /* pass this to HCI */ -#ifndef EXPORT_HCI_BRIDGE_INTERFACE - if (!hci_test_send(ar,skb)) { - return 0; - } -#endif - /* set AC to discard this skb */ - ac = AC_NOT_MAPPED; - } else { - /* a quirk of linux, the payload of the frame is 32-bit aligned and thus the addition - * of the HTC header will mis-align the start of the HTC frame, so we add some - * padding which will be stripped off in the target */ - if (EPPING_ALIGNMENT_PAD > 0) { - A_NETBUF_PUSH(skb, EPPING_ALIGNMENT_PAD); - } - } - - } else { - /* not a ping packet, drop it */ - ac = AC_NOT_MAPPED; - } - } - - } while (false); - - /* did we succeed ? */ - if ((ac == AC_NOT_MAPPED) && !checkAdHocPsMapping) { - /* cleanup and exit */ - A_NETBUF_FREE(skb); - AR6000_STAT_INC(ar, tx_dropped); - AR6000_STAT_INC(ar, tx_aborted_errors); - return 0; - } - - cookie = NULL; - - /* take the lock to protect driver data */ - AR6000_SPIN_LOCK(&ar->arLock, 0); - - do { - - if (checkAdHocPsMapping) { - eid = ar6000_ibss_map_epid(skb, dev, &mapNo); - }else { - eid = arAc2EndpointID (ar, ac); - } - /* validate that the endpoint is connected */ - if (eid == 0 || eid == ENDPOINT_UNUSED ) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" eid %d is NOT mapped!\n", eid)); - break; - } - /* allocate resource for this packet */ - cookie = ar6000_alloc_cookie(ar); - - if (cookie != NULL) { - /* update counts while the lock is held */ - ar->arTxPending[eid]++; - ar->arTotalTxDataPending++; - } - - } while (false); - - AR6000_SPIN_UNLOCK(&ar->arLock, 0); - - if (cookie != NULL) { - cookie->arc_bp[0] = (unsigned long)skb; - cookie->arc_bp[1] = mapNo; - SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt, - cookie, - A_NETBUF_DATA(skb), - A_NETBUF_LEN(skb), - eid, - htc_tag); - -#ifdef DEBUG - if (debugdriver >= 3) { - ar6000_dump_skb(skb); - } -#endif -#ifdef HTC_TEST_SEND_PKTS - DoHTCSendPktsTest(ar,mapNo,eid,skb); -#endif - /* HTC interface is asynchronous, if this fails, cleanup will happen in - * the ar6000_tx_complete callback */ - HTCSendPkt(ar->arHtcTarget, &cookie->HtcPkt); - } else { - /* no packet to send, cleanup */ - A_NETBUF_FREE(skb); - AR6000_STAT_INC(ar, tx_dropped); - AR6000_STAT_INC(ar, tx_aborted_errors); - } - - return 0; -} - -int -ar6000_acl_data_tx(struct sk_buff *skb, struct net_device *dev) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - struct ar_cookie *cookie; - HTC_ENDPOINT_ID eid = ENDPOINT_UNUSED; - - cookie = NULL; - AR6000_SPIN_LOCK(&ar->arLock, 0); - - /* For now we send ACL on BE endpoint: We can also have a dedicated EP */ - eid = arAc2EndpointID (ar, 0); - /* allocate resource for this packet */ - cookie = ar6000_alloc_cookie(ar); - - if (cookie != NULL) { - /* update counts while the lock is held */ - ar->arTxPending[eid]++; - ar->arTotalTxDataPending++; - } - - - AR6000_SPIN_UNLOCK(&ar->arLock, 0); - - if (cookie != NULL) { - cookie->arc_bp[0] = (unsigned long)skb; - cookie->arc_bp[1] = 0; - SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt, - cookie, - A_NETBUF_DATA(skb), - A_NETBUF_LEN(skb), - eid, - AR6K_DATA_PKT_TAG); - - /* HTC interface is asynchronous, if this fails, cleanup will happen in - * the ar6000_tx_complete callback */ - HTCSendPkt(ar->arHtcTarget, &cookie->HtcPkt); - } else { - /* no packet to send, cleanup */ - A_NETBUF_FREE(skb); - AR6000_STAT_INC(ar, tx_dropped); - AR6000_STAT_INC(ar, tx_aborted_errors); - } - return 0; -} - - -#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL -static void -tvsub(register struct timeval *out, register struct timeval *in) -{ - if((out->tv_usec -= in->tv_usec) < 0) { - out->tv_sec--; - out->tv_usec += 1000000; - } - out->tv_sec -= in->tv_sec; -} - -void -applyAPTCHeuristics(struct ar6_softc *ar) -{ - u32 duration; - u32 numbytes; - u32 throughput; - struct timeval ts; - int status; - - AR6000_SPIN_LOCK(&ar->arLock, 0); - - if ((enableAPTCHeuristics) && (!aptcTR.timerScheduled)) { - do_gettimeofday(&ts); - tvsub(&ts, &aptcTR.samplingTS); - duration = ts.tv_sec * 1000 + ts.tv_usec / 1000; /* ms */ - numbytes = aptcTR.bytesTransmitted + aptcTR.bytesReceived; - - if (duration > APTC_TRAFFIC_SAMPLING_INTERVAL) { - /* Initialize the time stamp and byte count */ - aptcTR.bytesTransmitted = aptcTR.bytesReceived = 0; - do_gettimeofday(&aptcTR.samplingTS); - - /* Calculate and decide based on throughput thresholds */ - throughput = ((numbytes * 8) / duration); - if (throughput > APTC_UPPER_THROUGHPUT_THRESHOLD) { - /* Disable Sleep and schedule a timer */ - A_ASSERT(ar->arWmiReady == true); - AR6000_SPIN_UNLOCK(&ar->arLock, 0); - status = wmi_powermode_cmd(ar->arWmi, MAX_PERF_POWER); - AR6000_SPIN_LOCK(&ar->arLock, 0); - A_TIMEOUT_MS(&aptcTimer, APTC_TRAFFIC_SAMPLING_INTERVAL, 0); - aptcTR.timerScheduled = true; - } - } - } - - AR6000_SPIN_UNLOCK(&ar->arLock, 0); -} -#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */ - -static HTC_SEND_FULL_ACTION ar6000_tx_queue_full(void *Context, struct htc_packet *pPacket) -{ - struct ar6_softc *ar = (struct ar6_softc *)Context; - HTC_SEND_FULL_ACTION action = HTC_SEND_FULL_KEEP; - bool stopNet = false; - HTC_ENDPOINT_ID Endpoint = HTC_GET_ENDPOINT_FROM_PKT(pPacket); - - do { - - if (bypasswmi) { - int accessClass; - - if (HTC_GET_TAG_FROM_PKT(pPacket) == AR6K_CONTROL_PKT_TAG) { - /* don't drop special control packets */ - break; - } - - accessClass = arEndpoint2Ac(ar,Endpoint); - /* for endpoint ping testing drop Best Effort and Background */ - if ((accessClass == WMM_AC_BE) || (accessClass == WMM_AC_BK)) { - action = HTC_SEND_FULL_DROP; - stopNet = false; - } else { - /* keep but stop the netqueues */ - stopNet = true; - } - break; - } - - if (Endpoint == ar->arControlEp) { - /* under normal WMI if this is getting full, then something is running rampant - * the host should not be exhausting the WMI queue with too many commands - * the only exception to this is during testing using endpointping */ - AR6000_SPIN_LOCK(&ar->arLock, 0); - /* set flag to handle subsequent messages */ - ar->arWMIControlEpFull = true; - AR6000_SPIN_UNLOCK(&ar->arLock, 0); - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("WMI Control Endpoint is FULL!!! \n")); - /* no need to stop the network */ - stopNet = false; - break; - } - - /* if we get here, we are dealing with data endpoints getting full */ - - if (HTC_GET_TAG_FROM_PKT(pPacket) == AR6K_CONTROL_PKT_TAG) { - /* don't drop control packets issued on ANY data endpoint */ - break; - } - - if (ar->arNetworkType == ADHOC_NETWORK) { - /* in adhoc mode, we cannot differentiate traffic priorities so there is no need to - * continue, however we should stop the network */ - stopNet = true; - break; - } - /* the last MAX_HI_COOKIE_NUM "batch" of cookies are reserved for the highest - * active stream */ - if (ar->arAcStreamPriMap[arEndpoint2Ac(ar,Endpoint)] < ar->arHiAcStreamActivePri && - ar->arCookieCount <= MAX_HI_COOKIE_NUM) { - /* this stream's priority is less than the highest active priority, we - * give preference to the highest priority stream by directing - * HTC to drop the packet that overflowed */ - action = HTC_SEND_FULL_DROP; - /* since we are dropping packets, no need to stop the network */ - stopNet = false; - break; - } - - } while (false); - - if (stopNet) { - AR6000_SPIN_LOCK(&ar->arLock, 0); - ar->arNetQueueStopped = true; - AR6000_SPIN_UNLOCK(&ar->arLock, 0); - /* one of the data endpoints queues is getting full..need to stop network stack - * the queue will resume in ar6000_tx_complete() */ - netif_stop_queue(ar->arNetDev); - } - - return action; -} - - -static void -ar6000_tx_complete(void *Context, struct htc_packet_queue *pPacketQueue) -{ - struct ar6_softc *ar = (struct ar6_softc *)Context; - u32 mapNo = 0; - int status; - struct ar_cookie * ar_cookie; - HTC_ENDPOINT_ID eid; - bool wakeEvent = false; - struct sk_buff_head skb_queue; - struct htc_packet *pPacket; - struct sk_buff *pktSkb; - bool flushing = false; - - skb_queue_head_init(&skb_queue); - - /* lock the driver as we update internal state */ - AR6000_SPIN_LOCK(&ar->arLock, 0); - - /* reap completed packets */ - while (!HTC_QUEUE_EMPTY(pPacketQueue)) { - - pPacket = HTC_PACKET_DEQUEUE(pPacketQueue); - - ar_cookie = (struct ar_cookie *)pPacket->pPktContext; - A_ASSERT(ar_cookie); - - status = pPacket->Status; - pktSkb = (struct sk_buff *)ar_cookie->arc_bp[0]; - eid = pPacket->Endpoint; - mapNo = ar_cookie->arc_bp[1]; - - A_ASSERT(pktSkb); - A_ASSERT(pPacket->pBuffer == A_NETBUF_DATA(pktSkb)); - - /* add this to the list, use faster non-lock API */ - __skb_queue_tail(&skb_queue,pktSkb); - - if (!status) { - A_ASSERT(pPacket->ActualLength == A_NETBUF_LEN(pktSkb)); - } - - AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("ar6000_tx_complete skb=0x%lx data=0x%lx len=0x%x eid=%d ", - (unsigned long)pktSkb, (unsigned long)pPacket->pBuffer, - pPacket->ActualLength, - eid)); - - ar->arTxPending[eid]--; - - if ((eid != ar->arControlEp) || bypasswmi) { - ar->arTotalTxDataPending--; - } - - if (eid == ar->arControlEp) - { - if (ar->arWMIControlEpFull) { - /* since this packet completed, the WMI EP is no longer full */ - ar->arWMIControlEpFull = false; - } - - if (ar->arTxPending[eid] == 0) { - wakeEvent = true; - } - } - - if (status) { - if (status == A_ECANCELED) { - /* a packet was flushed */ - flushing = true; - } - AR6000_STAT_INC(ar, tx_errors); - if (status != A_NO_RESOURCE) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s() -TX ERROR, status: 0x%x\n", __func__, - status)); - } - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("OK\n")); - flushing = false; - AR6000_STAT_INC(ar, tx_packets); - ar->arNetStats.tx_bytes += A_NETBUF_LEN(pktSkb); -#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL - aptcTR.bytesTransmitted += a_netbuf_to_len(pktSkb); - applyAPTCHeuristics(ar); -#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */ - } - - // TODO this needs to be looked at - if ((ar->arNetworkType == ADHOC_NETWORK) && ar->arIbssPsEnable - && (eid != ar->arControlEp) && mapNo) - { - mapNo --; - ar->arNodeMap[mapNo].txPending --; - - if (!ar->arNodeMap[mapNo].txPending && (mapNo == (ar->arNodeNum - 1))) { - u32 i; - for (i = ar->arNodeNum; i > 0; i --) { - if (!ar->arNodeMap[i - 1].txPending) { - A_MEMZERO(&ar->arNodeMap[i - 1], sizeof(struct ar_node_mapping)); - ar->arNodeNum --; - } else { - break; - } - } - } - } - - ar6000_free_cookie(ar, ar_cookie); - - if (ar->arNetQueueStopped) { - ar->arNetQueueStopped = false; - } - } - - AR6000_SPIN_UNLOCK(&ar->arLock, 0); - - /* lock is released, we can freely call other kernel APIs */ - - /* free all skbs in our local list */ - while (!skb_queue_empty(&skb_queue)) { - /* use non-lock version */ - pktSkb = __skb_dequeue(&skb_queue); - A_NETBUF_FREE(pktSkb); - } - - if ((ar->arConnected == true) || bypasswmi) { - if (!flushing) { - /* don't wake the queue if we are flushing, other wise it will just - * keep queueing packets, which will keep failing */ - netif_wake_queue(ar->arNetDev); - } - } - - if (wakeEvent) { - wake_up(&arEvent); - } - -} - -sta_t * -ieee80211_find_conn(struct ar6_softc *ar, u8 *node_addr) -{ - sta_t *conn = NULL; - u8 i, max_conn; - - switch(ar->arNetworkType) { - case AP_NETWORK: - max_conn = AP_MAX_NUM_STA; - break; - default: - max_conn=0; - break; - } - - for (i = 0; i < max_conn; i++) { - if (IEEE80211_ADDR_EQ(node_addr, ar->sta_list[i].mac)) { - conn = &ar->sta_list[i]; - break; - } - } - - return conn; -} - -sta_t *ieee80211_find_conn_for_aid(struct ar6_softc *ar, u8 aid) -{ - sta_t *conn = NULL; - u8 ctr; - - for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) { - if (ar->sta_list[ctr].aid == aid) { - conn = &ar->sta_list[ctr]; - break; - } - } - return conn; -} - -/* - * Receive event handler. This is called by HTC when a packet is received - */ -int pktcount; -static void -ar6000_rx(void *Context, struct htc_packet *pPacket) -{ - struct ar6_softc *ar = (struct ar6_softc *)Context; - struct sk_buff *skb = (struct sk_buff *)pPacket->pPktContext; - int minHdrLen; - u8 containsDot11Hdr = 0; - int status = pPacket->Status; - HTC_ENDPOINT_ID ept = pPacket->Endpoint; - - A_ASSERT((status) || - (pPacket->pBuffer == (A_NETBUF_DATA(skb) + HTC_HEADER_LEN))); - - AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_RX,("ar6000_rx ar=0x%lx eid=%d, skb=0x%lx, data=0x%lx, len=0x%x status:%d", - (unsigned long)ar, ept, (unsigned long)skb, (unsigned long)pPacket->pBuffer, - pPacket->ActualLength, status)); - if (status) { - if (status != A_ECANCELED) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("RX ERR (%d) \n",status)); - } - } - - /* take lock to protect buffer counts - * and adaptive power throughput state */ - AR6000_SPIN_LOCK(&ar->arLock, 0); - - if (!status) { - AR6000_STAT_INC(ar, rx_packets); - ar->arNetStats.rx_bytes += pPacket->ActualLength; -#ifdef ADAPTIVE_POWER_THROUGHPUT_CONTROL - aptcTR.bytesReceived += a_netbuf_to_len(skb); - applyAPTCHeuristics(ar); -#endif /* ADAPTIVE_POWER_THROUGHPUT_CONTROL */ - - A_NETBUF_PUT(skb, pPacket->ActualLength + HTC_HEADER_LEN); - A_NETBUF_PULL(skb, HTC_HEADER_LEN); - -#ifdef DEBUG - if (debugdriver >= 2) { - ar6000_dump_skb(skb); - } -#endif /* DEBUG */ - } - - AR6000_SPIN_UNLOCK(&ar->arLock, 0); - - skb->dev = ar->arNetDev; - if (status) { - AR6000_STAT_INC(ar, rx_errors); - A_NETBUF_FREE(skb); - } else if (ar->arWmiEnabled == true) { - if (ept == ar->arControlEp) { - /* - * this is a wmi control msg - */ -#ifdef CONFIG_PM - ar6000_check_wow_status(ar, skb, true); -#endif /* CONFIG_PM */ - wmi_control_rx(ar->arWmi, skb); - } else { - WMI_DATA_HDR *dhdr = (WMI_DATA_HDR *)A_NETBUF_DATA(skb); - bool is_amsdu; - u8 tid; - - /* - * This check can be removed if after a while we do not - * see the warning. For now we leave it to ensure - * we drop these frames accordingly in case the - * target generates them for some reason. These - * were used for an internal PAL but that's not - * used or supported anymore. These frames should - * not come up from the target. - */ - if (WARN_ON(WMI_DATA_HDR_GET_DATA_TYPE(dhdr) == - WMI_DATA_HDR_DATA_TYPE_ACL)) { - AR6000_STAT_INC(ar, rx_errors); - A_NETBUF_FREE(skb); - return; - } - -#ifdef CONFIG_PM - ar6000_check_wow_status(ar, NULL, false); -#endif /* CONFIG_PM */ - /* - * this is a wmi data packet - */ - // NWF - - if (processDot11Hdr) { - minHdrLen = sizeof(WMI_DATA_HDR) + sizeof(struct ieee80211_frame) + sizeof(ATH_LLC_SNAP_HDR); - } else { - minHdrLen = sizeof (WMI_DATA_HDR) + sizeof(ATH_MAC_HDR) + - sizeof(ATH_LLC_SNAP_HDR); - } - - /* In the case of AP mode we may receive NULL data frames - * that do not have LLC hdr. They are 16 bytes in size. - * Allow these frames in the AP mode. - * ACL data frames don't follow ethernet frame bounds for - * min length - */ - if (ar->arNetworkType != AP_NETWORK && - ((pPacket->ActualLength < minHdrLen) || - (pPacket->ActualLength > AR6000_MAX_RX_MESSAGE_SIZE))) - { - /* - * packet is too short or too long - */ - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("TOO SHORT or TOO LONG\n")); - AR6000_STAT_INC(ar, rx_errors); - AR6000_STAT_INC(ar, rx_length_errors); - A_NETBUF_FREE(skb); - } else { - u16 seq_no; - u8 meta_type; - -#if 0 - /* Access RSSI values here */ - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("RSSI %d\n", - ((WMI_DATA_HDR *) A_NETBUF_DATA(skb))->rssi)); -#endif - /* Get the Power save state of the STA */ - if (ar->arNetworkType == AP_NETWORK) { - sta_t *conn = NULL; - u8 psState=0,prevPsState; - ATH_MAC_HDR *datap=NULL; - u16 offset; - - meta_type = WMI_DATA_HDR_GET_META(dhdr); - - psState = (((WMI_DATA_HDR *)A_NETBUF_DATA(skb))->info - >> WMI_DATA_HDR_PS_SHIFT) & WMI_DATA_HDR_PS_MASK; - - offset = sizeof(WMI_DATA_HDR); - - switch (meta_type) { - case 0: - break; - case WMI_META_VERSION_1: - offset += sizeof(WMI_RX_META_V1); - break; - case WMI_META_VERSION_2: - offset += sizeof(WMI_RX_META_V2); - break; - default: - break; - } - - datap = (ATH_MAC_HDR *)(A_NETBUF_DATA(skb)+offset); - conn = ieee80211_find_conn(ar, datap->srcMac); - - if (conn) { - /* if there is a change in PS state of the STA, - * take appropriate steps. - * 1. If Sleep-->Awake, flush the psq for the STA - * Clear the PVB for the STA. - * 2. If Awake-->Sleep, Starting queueing frames - * the STA. - */ - prevPsState = STA_IS_PWR_SLEEP(conn); - if (psState) { - STA_SET_PWR_SLEEP(conn); - } else { - STA_CLR_PWR_SLEEP(conn); - } - - if (prevPsState ^ STA_IS_PWR_SLEEP(conn)) { - - if (!STA_IS_PWR_SLEEP(conn)) { - - A_MUTEX_LOCK(&conn->psqLock); - while (!A_NETBUF_QUEUE_EMPTY(&conn->psq)) { - struct sk_buff *skb=NULL; - - skb = A_NETBUF_DEQUEUE(&conn->psq); - A_MUTEX_UNLOCK(&conn->psqLock); - ar6000_data_tx(skb,ar->arNetDev); - A_MUTEX_LOCK(&conn->psqLock); - } - A_MUTEX_UNLOCK(&conn->psqLock); - /* Clear the PVB for this STA */ - wmi_set_pvb_cmd(ar->arWmi, conn->aid, 0); - } - } - } else { - /* This frame is from a STA that is not associated*/ - A_ASSERT(false); - } - - /* Drop NULL data frames here */ - if((pPacket->ActualLength < minHdrLen) || - (pPacket->ActualLength > AR6000_MAX_RX_MESSAGE_SIZE)) { - A_NETBUF_FREE(skb); - goto rx_done; - } - } - - is_amsdu = WMI_DATA_HDR_IS_AMSDU(dhdr) ? true : false; - tid = WMI_DATA_HDR_GET_UP(dhdr); - seq_no = WMI_DATA_HDR_GET_SEQNO(dhdr); - meta_type = WMI_DATA_HDR_GET_META(dhdr); - containsDot11Hdr = WMI_DATA_HDR_GET_DOT11(dhdr); - - wmi_data_hdr_remove(ar->arWmi, skb); - - switch (meta_type) { - case WMI_META_VERSION_1: - { - WMI_RX_META_V1 *pMeta = (WMI_RX_META_V1 *)A_NETBUF_DATA(skb); - A_PRINTF("META %d %d %d %d %x\n", pMeta->status, pMeta->rix, pMeta->rssi, pMeta->channel, pMeta->flags); - A_NETBUF_PULL((void*)skb, sizeof(WMI_RX_META_V1)); - break; - } - case WMI_META_VERSION_2: - { - WMI_RX_META_V2 *pMeta = (WMI_RX_META_V2 *)A_NETBUF_DATA(skb); - if(pMeta->csumFlags & 0x1){ - skb->ip_summed=CHECKSUM_COMPLETE; - skb->csum=(pMeta->csum); - } - A_NETBUF_PULL((void*)skb, sizeof(WMI_RX_META_V2)); - break; - } - default: - break; - } - - A_ASSERT(status == 0); - - /* NWF: print the 802.11 hdr bytes */ - if(containsDot11Hdr) { - status = wmi_dot11_hdr_remove(ar->arWmi,skb); - } else if(!is_amsdu) { - status = wmi_dot3_2_dix(skb); - } - - if (status) { - /* Drop frames that could not be processed (lack of memory, etc.) */ - A_NETBUF_FREE(skb); - goto rx_done; - } - - if ((ar->arNetDev->flags & IFF_UP) == IFF_UP) { - if (ar->arNetworkType == AP_NETWORK) { - struct sk_buff *skb1 = NULL; - ATH_MAC_HDR *datap; - - datap = (ATH_MAC_HDR *)A_NETBUF_DATA(skb); - if (IEEE80211_IS_MULTICAST(datap->dstMac)) { - /* Bcast/Mcast frames should be sent to the OS - * stack as well as on the air. - */ - skb1 = skb_copy(skb,GFP_ATOMIC); - } else { - /* Search for a connected STA with dstMac as - * the Mac address. If found send the frame to - * it on the air else send the frame up the - * stack - */ - sta_t *conn = NULL; - conn = ieee80211_find_conn(ar, datap->dstMac); - - if (conn && ar->intra_bss) { - skb1 = skb; - skb = NULL; - } else if(conn && !ar->intra_bss) { - A_NETBUF_FREE(skb); - skb = NULL; - } - } - if (skb1) { - ar6000_data_tx(skb1, ar->arNetDev); - } - } - } - aggr_process_recv_frm(ar->aggr_cntxt, tid, seq_no, is_amsdu, (void **)&skb); - ar6000_deliver_frames_to_nw_stack((void *) ar->arNetDev, (void *)skb); - } - } - } else { - if (EPPING_ALIGNMENT_PAD > 0) { - A_NETBUF_PULL(skb, EPPING_ALIGNMENT_PAD); - } - ar6000_deliver_frames_to_nw_stack((void *)ar->arNetDev, (void *)skb); - } - -rx_done: - - return; -} - -static void -ar6000_deliver_frames_to_nw_stack(void *dev, void *osbuf) -{ - struct sk_buff *skb = (struct sk_buff *)osbuf; - - if(skb) { - skb->dev = dev; - if ((skb->dev->flags & IFF_UP) == IFF_UP) { -#ifdef CONFIG_PM - ar6000_check_wow_status((struct ar6_softc *)ar6k_priv(dev), skb, false); -#endif /* CONFIG_PM */ - skb->protocol = eth_type_trans(skb, skb->dev); - /* - * If this routine is called on a ISR (Hard IRQ) or DSR (Soft IRQ) - * or tasklet use the netif_rx to deliver the packet to the stack - * netif_rx will queue the packet onto the receive queue and mark - * the softirq thread has a pending action to complete. Kernel will - * schedule the softIrq kernel thread after processing the DSR. - * - * If this routine is called on a process context, use netif_rx_ni - * which will schedle the softIrq kernel thread after queuing the packet. - */ - if (in_interrupt()) { - netif_rx(skb); - } else { - netif_rx_ni(skb); - } - } else { - A_NETBUF_FREE(skb); - } - } -} - -#if 0 -static void -ar6000_deliver_frames_to_bt_stack(void *dev, void *osbuf) -{ - struct sk_buff *skb = (struct sk_buff *)osbuf; - - if(skb) { - skb->dev = dev; - if ((skb->dev->flags & IFF_UP) == IFF_UP) { - skb->protocol = htons(ETH_P_CONTROL); - netif_rx(skb); - } else { - A_NETBUF_FREE(skb); - } - } -} -#endif - -static void -ar6000_rx_refill(void *Context, HTC_ENDPOINT_ID Endpoint) -{ - struct ar6_softc *ar = (struct ar6_softc *)Context; - void *osBuf; - int RxBuffers; - int buffersToRefill; - struct htc_packet *pPacket; - struct htc_packet_queue queue; - - buffersToRefill = (int)AR6000_MAX_RX_BUFFERS - - HTCGetNumRecvBuffers(ar->arHtcTarget, Endpoint); - - if (buffersToRefill <= 0) { - /* fast return, nothing to fill */ - return; - } - - INIT_HTC_PACKET_QUEUE(&queue); - - AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_RX,("ar6000_rx_refill: providing htc with %d buffers at eid=%d\n", - buffersToRefill, Endpoint)); - - for (RxBuffers = 0; RxBuffers < buffersToRefill; RxBuffers++) { - osBuf = A_NETBUF_ALLOC(AR6000_BUFFER_SIZE); - if (NULL == osBuf) { - break; - } - /* the HTC packet wrapper is at the head of the reserved area - * in the skb */ - pPacket = (struct htc_packet *)(A_NETBUF_HEAD(osBuf)); - /* set re-fill info */ - SET_HTC_PACKET_INFO_RX_REFILL(pPacket,osBuf,A_NETBUF_DATA(osBuf),AR6000_BUFFER_SIZE,Endpoint); - /* add to queue */ - HTC_PACKET_ENQUEUE(&queue,pPacket); - } - - if (!HTC_QUEUE_EMPTY(&queue)) { - /* add packets */ - HTCAddReceivePktMultiple(ar->arHtcTarget, &queue); - } - -} - - /* clean up our amsdu buffer list */ -static void ar6000_cleanup_amsdu_rxbufs(struct ar6_softc *ar) -{ - struct htc_packet *pPacket; - void *osBuf; - - /* empty AMSDU buffer queue and free OS bufs */ - while (true) { - - AR6000_SPIN_LOCK(&ar->arLock, 0); - pPacket = HTC_PACKET_DEQUEUE(&ar->amsdu_rx_buffer_queue); - AR6000_SPIN_UNLOCK(&ar->arLock, 0); - - if (NULL == pPacket) { - break; - } - - osBuf = pPacket->pPktContext; - if (NULL == osBuf) { - A_ASSERT(false); - break; - } - - A_NETBUF_FREE(osBuf); - } - -} - - - /* refill the amsdu buffer list */ -static void ar6000_refill_amsdu_rxbufs(struct ar6_softc *ar, int Count) -{ - struct htc_packet *pPacket; - void *osBuf; - - while (Count > 0) { - osBuf = A_NETBUF_ALLOC(AR6000_AMSDU_BUFFER_SIZE); - if (NULL == osBuf) { - break; - } - /* the HTC packet wrapper is at the head of the reserved area - * in the skb */ - pPacket = (struct htc_packet *)(A_NETBUF_HEAD(osBuf)); - /* set re-fill info */ - SET_HTC_PACKET_INFO_RX_REFILL(pPacket,osBuf,A_NETBUF_DATA(osBuf),AR6000_AMSDU_BUFFER_SIZE,0); - - AR6000_SPIN_LOCK(&ar->arLock, 0); - /* put it in the list */ - HTC_PACKET_ENQUEUE(&ar->amsdu_rx_buffer_queue,pPacket); - AR6000_SPIN_UNLOCK(&ar->arLock, 0); - Count--; - } - -} - - /* callback to allocate a large receive buffer for a pending packet. This function is called when - * an HTC packet arrives whose length exceeds a threshold value - * - * We use a pre-allocated list of buffers of maximum AMSDU size (4K). Under linux it is more optimal to - * keep the allocation size the same to optimize cached-slab allocations. - * - * */ -static struct htc_packet *ar6000_alloc_amsdu_rxbuf(void *Context, HTC_ENDPOINT_ID Endpoint, int Length) -{ - struct htc_packet *pPacket = NULL; - struct ar6_softc *ar = (struct ar6_softc *)Context; - int refillCount = 0; - - AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_RX,("ar6000_alloc_amsdu_rxbuf: eid=%d, Length:%d\n",Endpoint,Length)); - - do { - - if (Length <= AR6000_BUFFER_SIZE) { - /* shouldn't be getting called on normal sized packets */ - A_ASSERT(false); - break; - } - - if (Length > AR6000_AMSDU_BUFFER_SIZE) { - A_ASSERT(false); - break; - } - - AR6000_SPIN_LOCK(&ar->arLock, 0); - /* allocate a packet from the list */ - pPacket = HTC_PACKET_DEQUEUE(&ar->amsdu_rx_buffer_queue); - /* see if we need to refill again */ - refillCount = AR6000_MAX_AMSDU_RX_BUFFERS - HTC_PACKET_QUEUE_DEPTH(&ar->amsdu_rx_buffer_queue); - AR6000_SPIN_UNLOCK(&ar->arLock, 0); - - if (NULL == pPacket) { - break; - } - /* set actual endpoint ID */ - pPacket->Endpoint = Endpoint; - - } while (false); - - if (refillCount >= AR6000_AMSDU_REFILL_THRESHOLD) { - ar6000_refill_amsdu_rxbufs(ar,refillCount); - } - - return pPacket; -} - -static void -ar6000_set_multicast_list(struct net_device *dev) -{ - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000: Multicast filter not supported\n")); -} - -static struct net_device_stats * -ar6000_get_stats(struct net_device *dev) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - return &ar->arNetStats; -} - -void -ar6000_ready_event(void *devt, u8 *datap, u8 phyCap, u32 sw_ver, u32 abi_ver) -{ - struct ar6_softc *ar = (struct ar6_softc *)devt; - struct net_device *dev = ar->arNetDev; - - memcpy(dev->dev_addr, datap, AR6000_ETH_ADDR_LEN); - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("mac address = %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", - dev->dev_addr[0], dev->dev_addr[1], - dev->dev_addr[2], dev->dev_addr[3], - dev->dev_addr[4], dev->dev_addr[5])); - - ar->arPhyCapability = phyCap; - 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); -} - -void ar6000_install_static_wep_keys(struct ar6_softc *ar) -{ - u8 index; - u8 keyUsage; - - for (index = WMI_MIN_KEY_INDEX; index <= WMI_MAX_KEY_INDEX; index++) { - if (ar->arWepKeyList[index].arKeyLen) { - keyUsage = GROUP_USAGE; - if (index == ar->arDefTxKeyIndex) { - keyUsage |= TX_USAGE; - } - wmi_addKey_cmd(ar->arWmi, - index, - WEP_CRYPT, - keyUsage, - ar->arWepKeyList[index].arKeyLen, - NULL, - ar->arWepKeyList[index].arKey, KEY_OP_INIT_VAL, NULL, - NO_SYNC_WMIFLAG); - } - } -} - -void -add_new_sta(struct ar6_softc *ar, u8 *mac, u16 aid, u8 *wpaie, - u8 ielen, u8 keymgmt, u8 ucipher, u8 auth) -{ - u8 free_slot=aid-1; - - memcpy(ar->sta_list[free_slot].mac, mac, ATH_MAC_LEN); - memcpy(ar->sta_list[free_slot].wpa_ie, wpaie, ielen); - ar->sta_list[free_slot].aid = aid; - ar->sta_list[free_slot].keymgmt = keymgmt; - ar->sta_list[free_slot].ucipher = ucipher; - ar->sta_list[free_slot].auth = auth; - ar->sta_list_index = ar->sta_list_index | (1 << free_slot); - ar->arAPStats.sta[free_slot].aid = aid; -} - -void -ar6000_connect_event(struct ar6_softc *ar, u16 channel, u8 *bssid, - u16 listenInterval, u16 beaconInterval, - NETWORK_TYPE networkType, u8 beaconIeLen, - u8 assocReqLen, u8 assocRespLen, - u8 *assocInfo) -{ - union iwreq_data wrqu; - int i, beacon_ie_pos, assoc_resp_ie_pos, assoc_req_ie_pos; - static const char *tag1 = "ASSOCINFO(ReqIEs="; - static const char *tag2 = "ASSOCRESPIE="; - static const char *beaconIetag = "BEACONIE="; - char buf[WMI_CONTROL_MSG_MAX_LEN * 2 + strlen(tag1) + 1]; - char *pos; - u8 key_op_ctrl; - unsigned long flags; - struct ieee80211req_key *ik; - CRYPTO_TYPE keyType = NONE_CRYPT; - - if(ar->arNetworkType & AP_NETWORK) { - struct net_device *dev = ar->arNetDev; - if(memcmp(dev->dev_addr, bssid, ATH_MAC_LEN)==0) { - ar->arACS = channel; - ik = &ar->ap_mode_bkey; - - switch(ar->arAuthMode) { - case NONE_AUTH: - if(ar->arPairwiseCrypto == WEP_CRYPT) { - ar6000_install_static_wep_keys(ar); - } -#ifdef WAPI_ENABLE - else if(ar->arPairwiseCrypto == WAPI_CRYPT) { - ap_set_wapi_key(ar, ik); - } -#endif - break; - case WPA_PSK_AUTH: - case WPA2_PSK_AUTH: - case (WPA_PSK_AUTH|WPA2_PSK_AUTH): - switch (ik->ik_type) { - case IEEE80211_CIPHER_TKIP: - keyType = TKIP_CRYPT; - break; - case IEEE80211_CIPHER_AES_CCM: - keyType = AES_CRYPT; - break; - default: - goto skip_key; - } - wmi_addKey_cmd(ar->arWmi, ik->ik_keyix, keyType, GROUP_USAGE, - ik->ik_keylen, (u8 *)&ik->ik_keyrsc, - ik->ik_keydata, KEY_OP_INIT_VAL, ik->ik_macaddr, - SYNC_BOTH_WMIFLAG); - - break; - } -skip_key: - ar->arConnected = true; - return; - } - - A_PRINTF("NEW STA %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x \n " - " AID=%d \n", bssid[0], bssid[1], bssid[2], - bssid[3], bssid[4], bssid[5], channel); - switch ((listenInterval>>8)&0xFF) { - case OPEN_AUTH: - A_PRINTF("AUTH: OPEN\n"); - break; - case SHARED_AUTH: - A_PRINTF("AUTH: SHARED\n"); - break; - default: - A_PRINTF("AUTH: Unknown\n"); - break; - } - switch (listenInterval&0xFF) { - case WPA_PSK_AUTH: - A_PRINTF("KeyMgmt: WPA-PSK\n"); - break; - case WPA2_PSK_AUTH: - A_PRINTF("KeyMgmt: WPA2-PSK\n"); - break; - default: - A_PRINTF("KeyMgmt: NONE\n"); - break; - } - switch (beaconInterval) { - case AES_CRYPT: - A_PRINTF("Cipher: AES\n"); - break; - case TKIP_CRYPT: - A_PRINTF("Cipher: TKIP\n"); - break; - case WEP_CRYPT: - A_PRINTF("Cipher: WEP\n"); - break; -#ifdef WAPI_ENABLE - case WAPI_CRYPT: - A_PRINTF("Cipher: WAPI\n"); - break; -#endif - default: - A_PRINTF("Cipher: NONE\n"); - break; - } - - add_new_sta(ar, bssid, channel /*aid*/, - assocInfo /* WPA IE */, assocRespLen /* IE len */, - listenInterval&0xFF /* Keymgmt */, beaconInterval /* cipher */, - (listenInterval>>8)&0xFF /* auth alg */); - - /* Send event to application */ - A_MEMZERO(&wrqu, sizeof(wrqu)); - memcpy(wrqu.addr.sa_data, bssid, ATH_MAC_LEN); - wireless_send_event(ar->arNetDev, IWEVREGISTERED, &wrqu, NULL); - /* In case the queue is stopped when we switch modes, this will - * wake it up - */ - netif_wake_queue(ar->arNetDev); - return; - } - - ar6k_cfg80211_connect_event(ar, channel, bssid, - listenInterval, beaconInterval, - networkType, beaconIeLen, - assocReqLen, assocRespLen, - assocInfo); - - memcpy(ar->arBssid, bssid, sizeof(ar->arBssid)); - ar->arBssChannel = channel; - - A_PRINTF("AR6000 connected event on freq %d ", channel); - A_PRINTF("with bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x " - " listenInterval=%d, beaconInterval = %d, beaconIeLen = %d assocReqLen=%d" - " assocRespLen =%d\n", - bssid[0], bssid[1], bssid[2], - bssid[3], bssid[4], bssid[5], - listenInterval, beaconInterval, - beaconIeLen, assocReqLen, assocRespLen); - if (networkType & ADHOC_NETWORK) { - if (networkType & ADHOC_CREATOR) { - A_PRINTF("Network: Adhoc (Creator)\n"); - } else { - A_PRINTF("Network: Adhoc (Joiner)\n"); - } - } else { - A_PRINTF("Network: Infrastructure\n"); - } - - if ((ar->arNetworkType == INFRA_NETWORK)) { - wmi_listeninterval_cmd(ar->arWmi, ar->arListenIntervalT, ar->arListenIntervalB); - } - - if (beaconIeLen && (sizeof(buf) > (9 + beaconIeLen * 2))) { - AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nBeaconIEs= ")); - - beacon_ie_pos = 0; - A_MEMZERO(buf, sizeof(buf)); - sprintf(buf, "%s", beaconIetag); - pos = buf + 9; - for (i = beacon_ie_pos; i < beacon_ie_pos + beaconIeLen; i++) { - AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("%2.2x ", assocInfo[i])); - sprintf(pos, "%2.2x", assocInfo[i]); - pos += 2; - } - AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n")); - - A_MEMZERO(&wrqu, sizeof(wrqu)); - wrqu.data.length = strlen(buf); - wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf); - } - - if (assocRespLen && (sizeof(buf) > (12 + (assocRespLen * 2)))) - { - assoc_resp_ie_pos = beaconIeLen + assocReqLen + - sizeof(u16) + /* capinfo*/ - sizeof(u16) + /* status Code */ - sizeof(u16) ; /* associd */ - A_MEMZERO(buf, sizeof(buf)); - sprintf(buf, "%s", tag2); - pos = buf + 12; - AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nAssocRespIEs= ")); - /* - * The Association Response Frame w.o. the WLAN header is delivered to - * the host, so skip over to the IEs - */ - for (i = assoc_resp_ie_pos; i < assoc_resp_ie_pos + assocRespLen - 6; i++) - { - AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("%2.2x ", assocInfo[i])); - sprintf(pos, "%2.2x", assocInfo[i]); - pos += 2; - } - AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n")); - - A_MEMZERO(&wrqu, sizeof(wrqu)); - wrqu.data.length = strlen(buf); - wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf); - } - - if (assocReqLen && (sizeof(buf) > (17 + (assocReqLen * 2)))) { - /* - * assoc Request includes capability and listen interval. Skip these. - */ - assoc_req_ie_pos = beaconIeLen + - sizeof(u16) + /* capinfo*/ - sizeof(u16); /* listen interval */ - - A_MEMZERO(buf, sizeof(buf)); - sprintf(buf, "%s", tag1); - pos = buf + 17; - AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("AssocReqIEs= ")); - for (i = assoc_req_ie_pos; i < assoc_req_ie_pos + assocReqLen - 4; i++) { - AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("%2.2x ", assocInfo[i])); - sprintf(pos, "%2.2x", assocInfo[i]); - pos += 2; - } - AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n")); - - A_MEMZERO(&wrqu, sizeof(wrqu)); - wrqu.data.length = strlen(buf); - wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf); - } - - if (ar->user_savedkeys_stat == USER_SAVEDKEYS_STAT_RUN && - ar->user_saved_keys.keyOk == true) - { - key_op_ctrl = KEY_OP_VALID_MASK & ~KEY_OP_INIT_TSC; - - if (ar->user_key_ctrl & AR6000_USER_SETKEYS_RSC_UNCHANGED) { - key_op_ctrl &= ~KEY_OP_INIT_RSC; - } else { - key_op_ctrl |= KEY_OP_INIT_RSC; - } - ar6000_reinstall_keys(ar, key_op_ctrl); - } - - netif_wake_queue(ar->arNetDev); - - /* Update connect & link status atomically */ - spin_lock_irqsave(&ar->arLock, flags); - ar->arConnected = true; - ar->arConnectPending = false; - netif_carrier_on(ar->arNetDev); - spin_unlock_irqrestore(&ar->arLock, flags); - /* reset the rx aggr state */ - aggr_reset_state(ar->aggr_cntxt); - reconnect_flag = 0; - - A_MEMZERO(&wrqu, sizeof(wrqu)); - memcpy(wrqu.addr.sa_data, bssid, IEEE80211_ADDR_LEN); - wrqu.addr.sa_family = ARPHRD_ETHER; - wireless_send_event(ar->arNetDev, SIOCGIWAP, &wrqu, NULL); - if ((ar->arNetworkType == ADHOC_NETWORK) && ar->arIbssPsEnable) { - A_MEMZERO(ar->arNodeMap, sizeof(ar->arNodeMap)); - ar->arNodeNum = 0; - ar->arNexEpId = ENDPOINT_2; - } - if (!ar->arUserBssFilter) { - wmi_bssfilter_cmd(ar->arWmi, NONE_BSS_FILTER, 0); - } - -} - -void ar6000_set_numdataendpts(struct ar6_softc *ar, u32 num) -{ - A_ASSERT(num <= (HTC_MAILBOX_NUM_MAX - 1)); - ar->arNumDataEndPts = num; -} - -void -sta_cleanup(struct ar6_softc *ar, u8 i) -{ - struct sk_buff *skb; - - /* empty the queued pkts in the PS queue if any */ - A_MUTEX_LOCK(&ar->sta_list[i].psqLock); - while (!A_NETBUF_QUEUE_EMPTY(&ar->sta_list[i].psq)) { - skb = A_NETBUF_DEQUEUE(&ar->sta_list[i].psq); - A_NETBUF_FREE(skb); - } - A_MUTEX_UNLOCK(&ar->sta_list[i].psqLock); - - /* Zero out the state fields */ - A_MEMZERO(&ar->arAPStats.sta[ar->sta_list[i].aid-1], sizeof(WMI_PER_STA_STAT)); - A_MEMZERO(&ar->sta_list[i].mac, ATH_MAC_LEN); - A_MEMZERO(&ar->sta_list[i].wpa_ie, IEEE80211_MAX_IE); - ar->sta_list[i].aid = 0; - ar->sta_list[i].flags = 0; - - ar->sta_list_index = ar->sta_list_index & ~(1 << i); - -} - -u8 remove_sta(struct ar6_softc *ar, u8 *mac, u16 reason) -{ - u8 i, removed=0; - - if(IS_MAC_NULL(mac)) { - return removed; - } - - if(IS_MAC_BCAST(mac)) { - A_PRINTF("DEL ALL STA\n"); - for(i=0; i < AP_MAX_NUM_STA; i++) { - if(!IS_MAC_NULL(ar->sta_list[i].mac)) { - sta_cleanup(ar, i); - removed = 1; - } - } - } else { - for(i=0; i < AP_MAX_NUM_STA; i++) { - if(memcmp(ar->sta_list[i].mac, mac, ATH_MAC_LEN)==0) { - A_PRINTF("DEL STA %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x " - " aid=%d REASON=%d\n", mac[0], mac[1], mac[2], - mac[3], mac[4], mac[5], ar->sta_list[i].aid, reason); - - sta_cleanup(ar, i); - removed = 1; - break; - } - } - } - return removed; -} - -void -ar6000_disconnect_event(struct ar6_softc *ar, u8 reason, u8 *bssid, - u8 assocRespLen, u8 *assocInfo, u16 protocolReasonStatus) -{ - u8 i; - unsigned long flags; - union iwreq_data wrqu; - - if(ar->arNetworkType & AP_NETWORK) { - union iwreq_data wrqu; - struct sk_buff *skb; - - if(!remove_sta(ar, bssid, protocolReasonStatus)) { - return; - } - - /* If there are no more associated STAs, empty the mcast PS q */ - if (ar->sta_list_index == 0) { - A_MUTEX_LOCK(&ar->mcastpsqLock); - while (!A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq)) { - skb = A_NETBUF_DEQUEUE(&ar->mcastpsq); - A_NETBUF_FREE(skb); - } - A_MUTEX_UNLOCK(&ar->mcastpsqLock); - - /* Clear the LSB of the BitMapCtl field of the TIM IE */ - if (ar->arWmiReady) { - wmi_set_pvb_cmd(ar->arWmi, MCAST_AID, 0); - } - } - - if(!IS_MAC_BCAST(bssid)) { - /* Send event to application */ - A_MEMZERO(&wrqu, sizeof(wrqu)); - memcpy(wrqu.addr.sa_data, bssid, ATH_MAC_LEN); - wireless_send_event(ar->arNetDev, IWEVEXPIRED, &wrqu, NULL); - } - - ar->arConnected = false; - return; - } - - ar6k_cfg80211_disconnect_event(ar, reason, bssid, - assocRespLen, assocInfo, - protocolReasonStatus); - - /* Send disconnect event to supplicant */ - A_MEMZERO(&wrqu, sizeof(wrqu)); - wrqu.addr.sa_family = ARPHRD_ETHER; - wireless_send_event(ar->arNetDev, SIOCGIWAP, &wrqu, NULL); - - /* it is necessary to clear the host-side rx aggregation state */ - aggr_reset_state(ar->aggr_cntxt); - - A_UNTIMEOUT(&ar->disconnect_timer); - - A_PRINTF("AR6000 disconnected"); - if (bssid[0] || bssid[1] || bssid[2] || bssid[3] || bssid[4] || bssid[5]) { - A_PRINTF(" from %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ", - bssid[0], bssid[1], bssid[2], bssid[3], bssid[4], bssid[5]); - } - - AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nDisconnect Reason is %d", reason)); - AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nProtocol Reason/Status Code is %d", protocolReasonStatus)); - AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\nAssocResp Frame = %s", - assocRespLen ? " " : "NULL")); - for (i = 0; i < assocRespLen; i++) { - if (!(i % 0x10)) { - AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n")); - } - AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("%2.2x ", assocInfo[i])); - } - AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n")); - /* - * If the event is due to disconnect cmd from the host, only they the target - * would stop trying to connect. Under any other condition, target would - * keep trying to connect. - * - */ - if( reason == DISCONNECT_CMD) - { - if ((!ar->arUserBssFilter) && (ar->arWmiReady)) { - wmi_bssfilter_cmd(ar->arWmi, NONE_BSS_FILTER, 0); - } - } else { - ar->arConnectPending = true; - if (((reason == ASSOC_FAILED) && (protocolReasonStatus == 0x11)) || - ((reason == ASSOC_FAILED) && (protocolReasonStatus == 0x0) && (reconnect_flag == 1))) { - ar->arConnected = true; - return; - } - } - - if ((reason == NO_NETWORK_AVAIL) && (ar->arWmiReady)) - { - bss_t *pWmiSsidnode = NULL; - - /* remove the current associated bssid node */ - wmi_free_node (ar->arWmi, bssid); - - /* - * In case any other same SSID nodes are present - * remove it, since those nodes also not available now - */ - do - { - /* - * Find the nodes based on SSID and remove it - * NOTE :: This case will not work out for Hidden-SSID - */ - pWmiSsidnode = wmi_find_Ssidnode (ar->arWmi, ar->arSsid, ar->arSsidLen, false, true); - - if (pWmiSsidnode) - { - wmi_free_node (ar->arWmi, pWmiSsidnode->ni_macaddr); - } - - } while (pWmiSsidnode); - } - - /* Update connect & link status atomically */ - spin_lock_irqsave(&ar->arLock, flags); - ar->arConnected = false; - netif_carrier_off(ar->arNetDev); - spin_unlock_irqrestore(&ar->arLock, flags); - - if( (reason != CSERV_DISCONNECT) || (reconnect_flag != 1) ) { - reconnect_flag = 0; - } - - if (reason != CSERV_DISCONNECT) - { - ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT; - ar->user_key_ctrl = 0; - } - - netif_stop_queue(ar->arNetDev); - A_MEMZERO(ar->arBssid, sizeof(ar->arBssid)); - ar->arBssChannel = 0; - ar->arBeaconInterval = 0; - - ar6000_TxDataCleanup(ar); -} - -void -ar6000_regDomain_event(struct ar6_softc *ar, u32 regCode) -{ - A_PRINTF("AR6000 Reg Code = 0x%x\n", regCode); - ar->arRegCode = regCode; -} - -void -ar6000_aggr_rcv_addba_req_evt(struct ar6_softc *ar, WMI_ADDBA_REQ_EVENT *evt) -{ - if(evt->status == 0) { - aggr_recv_addba_req_evt(ar->aggr_cntxt, evt->tid, evt->st_seq_no, evt->win_sz); - } -} - -void -ar6000_aggr_rcv_addba_resp_evt(struct ar6_softc *ar, WMI_ADDBA_RESP_EVENT *evt) -{ - A_PRINTF("ADDBA RESP. tid %d status %d, sz %d\n", evt->tid, evt->status, evt->amsdu_sz); - if(evt->status == 0) { - } -} - -void -ar6000_aggr_rcv_delba_req_evt(struct ar6_softc *ar, WMI_DELBA_EVENT *evt) -{ - aggr_recv_delba_req_evt(ar->aggr_cntxt, evt->tid); -} - -void register_pal_cb(ar6k_pal_config_t *palConfig_p) -{ - ar6k_pal_config_g = *palConfig_p; -} - -void -ar6000_hci_event_rcv_evt(struct ar6_softc *ar, WMI_HCI_EVENT *cmd) -{ - void *osbuf = NULL; - s8 i; - u8 size, *buf; - int ret = 0; - - size = cmd->evt_buf_sz + 4; - osbuf = A_NETBUF_ALLOC(size); - if (osbuf == NULL) { - ret = A_NO_MEMORY; - A_PRINTF("Error in allocating netbuf \n"); - return; - } - - A_NETBUF_PUT(osbuf, size); - buf = (u8 *)A_NETBUF_DATA(osbuf); - /* First 2-bytes carry HCI event/ACL data type - * the next 2 are free - */ - *((short *)buf) = WMI_HCI_EVENT_EVENTID; - buf += sizeof(int); - memcpy(buf, cmd->buf, cmd->evt_buf_sz); - - ar6000_deliver_frames_to_nw_stack(ar->arNetDev, osbuf); - if(loghci) { - A_PRINTF_LOG("HCI Event From PAL <-- \n"); - for(i = 0; i < cmd->evt_buf_sz; i++) { - A_PRINTF_LOG("0x%02x ", cmd->buf[i]); - if((i % 10) == 0) { - A_PRINTF_LOG("\n"); - } - } - A_PRINTF_LOG("\n"); - A_PRINTF_LOG("==================================\n"); - } -} - -void -ar6000_neighborReport_event(struct ar6_softc *ar, int numAps, WMI_NEIGHBOR_INFO *info) -{ -#if WIRELESS_EXT >= 18 - struct iw_pmkid_cand *pmkcand; -#else /* WIRELESS_EXT >= 18 */ - static const char *tag = "PRE-AUTH"; - char buf[128]; -#endif /* WIRELESS_EXT >= 18 */ - - union iwreq_data wrqu; - int i; - - AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,("AR6000 Neighbor Report Event\n")); - for (i=0; i < numAps; info++, i++) { - AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,("bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ", - info->bssid[0], info->bssid[1], info->bssid[2], - info->bssid[3], info->bssid[4], info->bssid[5])); - if (info->bssFlags & WMI_PREAUTH_CAPABLE_BSS) { - AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,("preauth-cap")); - } - if (info->bssFlags & WMI_PMKID_VALID_BSS) { - AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,(" pmkid-valid\n")); - continue; /* we skip bss if the pmkid is already valid */ - } - AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,("\n")); - A_MEMZERO(&wrqu, sizeof(wrqu)); -#if WIRELESS_EXT >= 18 - pmkcand = A_MALLOC_NOWAIT(sizeof(struct iw_pmkid_cand)); - A_MEMZERO(pmkcand, sizeof(struct iw_pmkid_cand)); - pmkcand->index = i; - pmkcand->flags = info->bssFlags; - memcpy(pmkcand->bssid.sa_data, info->bssid, ATH_MAC_LEN); - wrqu.data.length = sizeof(struct iw_pmkid_cand); - wireless_send_event(ar->arNetDev, IWEVPMKIDCAND, &wrqu, (char *)pmkcand); - kfree(pmkcand); -#else /* WIRELESS_EXT >= 18 */ - snprintf(buf, sizeof(buf), "%s%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x", - tag, - info->bssid[0], info->bssid[1], info->bssid[2], - info->bssid[3], info->bssid[4], info->bssid[5], - i, info->bssFlags); - wrqu.data.length = strlen(buf); - wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf); -#endif /* WIRELESS_EXT >= 18 */ - } -} - -void -ar6000_tkip_micerr_event(struct ar6_softc *ar, u8 keyid, bool ismcast) -{ - static const char *tag = "MLME-MICHAELMICFAILURE.indication"; - char buf[128]; - union iwreq_data wrqu; - - /* - * For AP case, keyid will have aid of STA which sent pkt with - * MIC error. Use this aid to get MAC & send it to hostapd. - */ - if (ar->arNetworkType == AP_NETWORK) { - sta_t *s = ieee80211_find_conn_for_aid(ar, (keyid >> 2)); - if(!s){ - A_PRINTF("AP TKIP MIC error received from Invalid aid / STA not found =%d\n", keyid); - return; - } - A_PRINTF("AP TKIP MIC error received from aid=%d\n", keyid); - snprintf(buf,sizeof(buf), "%s addr=%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x", - tag, s->mac[0],s->mac[1],s->mac[2],s->mac[3],s->mac[4],s->mac[5]); - } else { - - ar6k_cfg80211_tkip_micerr_event(ar, keyid, ismcast); - - A_PRINTF("AR6000 TKIP MIC error received for keyid %d %scast\n", - keyid & 0x3, ismcast ? "multi": "uni"); - snprintf(buf, sizeof(buf), "%s(keyid=%d %sicast)", tag, keyid & 0x3, - ismcast ? "mult" : "un"); - } - - memset(&wrqu, 0, sizeof(wrqu)); - wrqu.data.length = strlen(buf); - wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf); -} - -void -ar6000_scanComplete_event(struct ar6_softc *ar, int status) -{ - - ar6k_cfg80211_scanComplete_event(ar, status); - - if (!ar->arUserBssFilter) { - wmi_bssfilter_cmd(ar->arWmi, NONE_BSS_FILTER, 0); - } - if (ar->scan_triggered) { - if (status== 0) { - union iwreq_data wrqu; - A_MEMZERO(&wrqu, sizeof(wrqu)); - wireless_send_event(ar->arNetDev, SIOCGIWSCAN, &wrqu, NULL); - } - ar->scan_triggered = 0; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN,( "AR6000 scan complete: %d\n", status)); -} - -void -ar6000_targetStats_event(struct ar6_softc *ar, u8 *ptr, u32 len) -{ - u8 ac; - - if(ar->arNetworkType == AP_NETWORK) { - WMI_AP_MODE_STAT *p = (WMI_AP_MODE_STAT *)ptr; - WMI_AP_MODE_STAT *ap = &ar->arAPStats; - - if (len < sizeof(*p)) { - return; - } - - for(ac=0;ac<AP_MAX_NUM_STA;ac++) { - ap->sta[ac].tx_bytes += p->sta[ac].tx_bytes; - ap->sta[ac].tx_pkts += p->sta[ac].tx_pkts; - ap->sta[ac].tx_error += p->sta[ac].tx_error; - ap->sta[ac].tx_discard += p->sta[ac].tx_discard; - ap->sta[ac].rx_bytes += p->sta[ac].rx_bytes; - ap->sta[ac].rx_pkts += p->sta[ac].rx_pkts; - ap->sta[ac].rx_error += p->sta[ac].rx_error; - ap->sta[ac].rx_discard += p->sta[ac].rx_discard; - } - - } else { - WMI_TARGET_STATS *pTarget = (WMI_TARGET_STATS *)ptr; - TARGET_STATS *pStats = &ar->arTargetStats; - - if (len < sizeof(*pTarget)) { - return; - } - - // Update the RSSI of the connected bss. - if (ar->arConnected) { - bss_t *pConnBss = NULL; - - pConnBss = wmi_find_node(ar->arWmi,ar->arBssid); - if (pConnBss) - { - pConnBss->ni_rssi = pTarget->cservStats.cs_aveBeacon_rssi; - pConnBss->ni_snr = pTarget->cservStats.cs_aveBeacon_snr; - wmi_node_return(ar->arWmi, pConnBss); - } - } - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR6000 updating target stats\n")); - pStats->tx_packets += pTarget->txrxStats.tx_stats.tx_packets; - pStats->tx_bytes += pTarget->txrxStats.tx_stats.tx_bytes; - pStats->tx_unicast_pkts += pTarget->txrxStats.tx_stats.tx_unicast_pkts; - pStats->tx_unicast_bytes += pTarget->txrxStats.tx_stats.tx_unicast_bytes; - pStats->tx_multicast_pkts += pTarget->txrxStats.tx_stats.tx_multicast_pkts; - pStats->tx_multicast_bytes += pTarget->txrxStats.tx_stats.tx_multicast_bytes; - pStats->tx_broadcast_pkts += pTarget->txrxStats.tx_stats.tx_broadcast_pkts; - pStats->tx_broadcast_bytes += pTarget->txrxStats.tx_stats.tx_broadcast_bytes; - pStats->tx_rts_success_cnt += pTarget->txrxStats.tx_stats.tx_rts_success_cnt; - for(ac = 0; ac < WMM_NUM_AC; ac++) - pStats->tx_packet_per_ac[ac] += pTarget->txrxStats.tx_stats.tx_packet_per_ac[ac]; - pStats->tx_errors += pTarget->txrxStats.tx_stats.tx_errors; - pStats->tx_failed_cnt += pTarget->txrxStats.tx_stats.tx_failed_cnt; - pStats->tx_retry_cnt += pTarget->txrxStats.tx_stats.tx_retry_cnt; - pStats->tx_mult_retry_cnt += pTarget->txrxStats.tx_stats.tx_mult_retry_cnt; - pStats->tx_rts_fail_cnt += pTarget->txrxStats.tx_stats.tx_rts_fail_cnt; - pStats->tx_unicast_rate = wmi_get_rate(pTarget->txrxStats.tx_stats.tx_unicast_rate); - - pStats->rx_packets += pTarget->txrxStats.rx_stats.rx_packets; - pStats->rx_bytes += pTarget->txrxStats.rx_stats.rx_bytes; - pStats->rx_unicast_pkts += pTarget->txrxStats.rx_stats.rx_unicast_pkts; - pStats->rx_unicast_bytes += pTarget->txrxStats.rx_stats.rx_unicast_bytes; - pStats->rx_multicast_pkts += pTarget->txrxStats.rx_stats.rx_multicast_pkts; - pStats->rx_multicast_bytes += pTarget->txrxStats.rx_stats.rx_multicast_bytes; - pStats->rx_broadcast_pkts += pTarget->txrxStats.rx_stats.rx_broadcast_pkts; - pStats->rx_broadcast_bytes += pTarget->txrxStats.rx_stats.rx_broadcast_bytes; - pStats->rx_fragment_pkt += pTarget->txrxStats.rx_stats.rx_fragment_pkt; - pStats->rx_errors += pTarget->txrxStats.rx_stats.rx_errors; - pStats->rx_crcerr += pTarget->txrxStats.rx_stats.rx_crcerr; - pStats->rx_key_cache_miss += pTarget->txrxStats.rx_stats.rx_key_cache_miss; - pStats->rx_decrypt_err += pTarget->txrxStats.rx_stats.rx_decrypt_err; - pStats->rx_duplicate_frames += pTarget->txrxStats.rx_stats.rx_duplicate_frames; - pStats->rx_unicast_rate = wmi_get_rate(pTarget->txrxStats.rx_stats.rx_unicast_rate); - - - pStats->tkip_local_mic_failure - += pTarget->txrxStats.tkipCcmpStats.tkip_local_mic_failure; - pStats->tkip_counter_measures_invoked - += pTarget->txrxStats.tkipCcmpStats.tkip_counter_measures_invoked; - pStats->tkip_replays += pTarget->txrxStats.tkipCcmpStats.tkip_replays; - pStats->tkip_format_errors += pTarget->txrxStats.tkipCcmpStats.tkip_format_errors; - pStats->ccmp_format_errors += pTarget->txrxStats.tkipCcmpStats.ccmp_format_errors; - pStats->ccmp_replays += pTarget->txrxStats.tkipCcmpStats.ccmp_replays; - - pStats->power_save_failure_cnt += pTarget->pmStats.power_save_failure_cnt; - pStats->noise_floor_calibation = pTarget->noise_floor_calibation; - - pStats->cs_bmiss_cnt += pTarget->cservStats.cs_bmiss_cnt; - pStats->cs_lowRssi_cnt += pTarget->cservStats.cs_lowRssi_cnt; - pStats->cs_connect_cnt += pTarget->cservStats.cs_connect_cnt; - pStats->cs_disconnect_cnt += pTarget->cservStats.cs_disconnect_cnt; - pStats->cs_aveBeacon_snr = pTarget->cservStats.cs_aveBeacon_snr; - pStats->cs_aveBeacon_rssi = pTarget->cservStats.cs_aveBeacon_rssi; - - if (enablerssicompensation) { - pStats->cs_aveBeacon_rssi = - rssi_compensation_calc(ar, pStats->cs_aveBeacon_rssi); - } - pStats->cs_lastRoam_msec = pTarget->cservStats.cs_lastRoam_msec; - pStats->cs_snr = pTarget->cservStats.cs_snr; - pStats->cs_rssi = pTarget->cservStats.cs_rssi; - - pStats->lq_val = pTarget->lqVal; - - pStats->wow_num_pkts_dropped += pTarget->wowStats.wow_num_pkts_dropped; - pStats->wow_num_host_pkt_wakeups += pTarget->wowStats.wow_num_host_pkt_wakeups; - pStats->wow_num_host_event_wakeups += pTarget->wowStats.wow_num_host_event_wakeups; - pStats->wow_num_events_discarded += pTarget->wowStats.wow_num_events_discarded; - pStats->arp_received += pTarget->arpStats.arp_received; - pStats->arp_matched += pTarget->arpStats.arp_matched; - pStats->arp_replied += pTarget->arpStats.arp_replied; - - if (ar->statsUpdatePending) { - ar->statsUpdatePending = false; - wake_up(&arEvent); - } - } -} - -void -ar6000_rssiThreshold_event(struct ar6_softc *ar, WMI_RSSI_THRESHOLD_VAL newThreshold, s16 rssi) -{ - USER_RSSI_THOLD userRssiThold; - - rssi = rssi + SIGNAL_QUALITY_NOISE_FLOOR; - - if (enablerssicompensation) { - rssi = rssi_compensation_calc(ar, rssi); - } - - /* Send an event to the app */ - userRssiThold.tag = ar->rssi_map[newThreshold].tag; - userRssiThold.rssi = rssi; - A_PRINTF("rssi Threshold range = %d tag = %d rssi = %d\n", newThreshold, - userRssiThold.tag, userRssiThold.rssi); -} - - -void -ar6000_hbChallengeResp_event(struct ar6_softc *ar, u32 cookie, u32 source) -{ - if (source != APP_HB_CHALLENGE) { - /* This would ignore the replys that come in after their due time */ - if (cookie == ar->arHBChallengeResp.seqNum) { - ar->arHBChallengeResp.outstanding = false; - } - } -} - - -void -ar6000_reportError_event(struct ar6_softc *ar, WMI_TARGET_ERROR_VAL errorVal) -{ - static const char * const errString[] = { - [WMI_TARGET_PM_ERR_FAIL] "WMI_TARGET_PM_ERR_FAIL", - [WMI_TARGET_KEY_NOT_FOUND] "WMI_TARGET_KEY_NOT_FOUND", - [WMI_TARGET_DECRYPTION_ERR] "WMI_TARGET_DECRYPTION_ERR", - [WMI_TARGET_BMISS] "WMI_TARGET_BMISS", - [WMI_PSDISABLE_NODE_JOIN] "WMI_PSDISABLE_NODE_JOIN" - }; - - A_PRINTF("AR6000 Error on Target. Error = 0x%x\n", errorVal); - - /* One error is reported at a time, and errorval is a bitmask */ - if(errorVal & (errorVal - 1)) - return; - - A_PRINTF("AR6000 Error type = "); - switch(errorVal) - { - case WMI_TARGET_PM_ERR_FAIL: - case WMI_TARGET_KEY_NOT_FOUND: - case WMI_TARGET_DECRYPTION_ERR: - case WMI_TARGET_BMISS: - case WMI_PSDISABLE_NODE_JOIN: - A_PRINTF("%s\n", errString[errorVal]); - break; - default: - A_PRINTF("INVALID\n"); - break; - } - -} - - -void -ar6000_cac_event(struct ar6_softc *ar, u8 ac, u8 cacIndication, - u8 statusCode, u8 *tspecSuggestion) -{ - WMM_TSPEC_IE *tspecIe; - - /* - * This is the TSPEC IE suggestion from AP. - * Suggestion provided by AP under some error - * cases, could be helpful for the host app. - * Check documentation. - */ - tspecIe = (WMM_TSPEC_IE *)tspecSuggestion; - - /* - * What do we do, if we get TSPEC rejection? One thought - * that comes to mind is implictly delete the pstream... - */ - A_PRINTF("AR6000 CAC notification. " - "AC = %d, cacIndication = 0x%x, statusCode = 0x%x\n", - ac, cacIndication, statusCode); -} - -void -ar6000_channel_change_event(struct ar6_softc *ar, u16 oldChannel, - u16 newChannel) -{ - A_PRINTF("Channel Change notification\nOld Channel: %d, New Channel: %d\n", - oldChannel, newChannel); -} - -#define AR6000_PRINT_BSSID(_pBss) do { \ - A_PRINTF("%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ",\ - (_pBss)[0],(_pBss)[1],(_pBss)[2],(_pBss)[3],\ - (_pBss)[4],(_pBss)[5]); \ -} while(0) - -void -ar6000_roam_tbl_event(struct ar6_softc *ar, WMI_TARGET_ROAM_TBL *pTbl) -{ - u8 i; - - A_PRINTF("ROAM TABLE NO OF ENTRIES is %d ROAM MODE is %d\n", - pTbl->numEntries, pTbl->roamMode); - for (i= 0; i < pTbl->numEntries; i++) { - A_PRINTF("[%d]bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x ", i, - pTbl->bssRoamInfo[i].bssid[0], pTbl->bssRoamInfo[i].bssid[1], - pTbl->bssRoamInfo[i].bssid[2], - pTbl->bssRoamInfo[i].bssid[3], - pTbl->bssRoamInfo[i].bssid[4], - pTbl->bssRoamInfo[i].bssid[5]); - A_PRINTF("RSSI %d RSSIDT %d LAST RSSI %d UTIL %d ROAM_UTIL %d" - " BIAS %d\n", - pTbl->bssRoamInfo[i].rssi, - pTbl->bssRoamInfo[i].rssidt, - pTbl->bssRoamInfo[i].last_rssi, - pTbl->bssRoamInfo[i].util, - pTbl->bssRoamInfo[i].roam_util, - pTbl->bssRoamInfo[i].bias); - } -} - -void -ar6000_wow_list_event(struct ar6_softc *ar, u8 num_filters, WMI_GET_WOW_LIST_REPLY *wow_reply) -{ - u8 i,j; - - /*Each event now contains exactly one filter, see bug 26613*/ - A_PRINTF("WOW pattern %d of %d patterns\n", wow_reply->this_filter_num, wow_reply->num_filters); - A_PRINTF("wow mode = %s host mode = %s\n", - (wow_reply->wow_mode == 0? "disabled":"enabled"), - (wow_reply->host_mode == 1 ? "awake":"asleep")); - - - /*If there are no patterns, the reply will only contain generic - WoW information. Pattern information will exist only if there are - patterns present. Bug 26716*/ - - /* If this event contains pattern information, display it*/ - if (wow_reply->this_filter_num) { - i=0; - A_PRINTF("id=%d size=%d offset=%d\n", - wow_reply->wow_filters[i].wow_filter_id, - wow_reply->wow_filters[i].wow_filter_size, - wow_reply->wow_filters[i].wow_filter_offset); - A_PRINTF("wow pattern = "); - for (j=0; j< wow_reply->wow_filters[i].wow_filter_size; j++) { - A_PRINTF("%2.2x",wow_reply->wow_filters[i].wow_filter_pattern[j]); - } - - A_PRINTF("\nwow mask = "); - for (j=0; j< wow_reply->wow_filters[i].wow_filter_size; j++) { - A_PRINTF("%2.2x",wow_reply->wow_filters[i].wow_filter_mask[j]); - } - A_PRINTF("\n"); - } -} - -/* - * Report the Roaming related data collected on the target - */ -void -ar6000_display_roam_time(WMI_TARGET_ROAM_TIME *p) -{ - A_PRINTF("Disconnect Data : BSSID: "); - AR6000_PRINT_BSSID(p->disassoc_bssid); - A_PRINTF(" RSSI %d DISASSOC Time %d NO_TXRX_TIME %d\n", - p->disassoc_bss_rssi,p->disassoc_time, - p->no_txrx_time); - A_PRINTF("Connect Data: BSSID: "); - AR6000_PRINT_BSSID(p->assoc_bssid); - A_PRINTF(" RSSI %d ASSOC Time %d TXRX_TIME %d\n", - p->assoc_bss_rssi,p->assoc_time, - p->allow_txrx_time); -} - -void -ar6000_roam_data_event(struct ar6_softc *ar, WMI_TARGET_ROAM_DATA *p) -{ - switch (p->roamDataType) { - case ROAM_DATA_TIME: - ar6000_display_roam_time(&p->u.roamTime); - break; - default: - break; - } -} - -void -ar6000_bssInfo_event_rx(struct ar6_softc *ar, u8 *datap, int len) -{ - struct sk_buff *skb; - WMI_BSS_INFO_HDR *bih = (WMI_BSS_INFO_HDR *)datap; - - - if (!ar->arMgmtFilter) { - return; - } - if (((ar->arMgmtFilter & IEEE80211_FILTER_TYPE_BEACON) && - (bih->frameType != BEACON_FTYPE)) || - ((ar->arMgmtFilter & IEEE80211_FILTER_TYPE_PROBE_RESP) && - (bih->frameType != PROBERESP_FTYPE))) - { - return; - } - - if ((skb = A_NETBUF_ALLOC_RAW(len)) != NULL) { - - A_NETBUF_PUT(skb, len); - memcpy(A_NETBUF_DATA(skb), datap, len); - skb->dev = ar->arNetDev; - memcpy(skb_mac_header(skb), A_NETBUF_DATA(skb), 6); - skb->ip_summed = CHECKSUM_NONE; - skb->pkt_type = PACKET_OTHERHOST; - skb->protocol = __constant_htons(0x0019); - netif_rx(skb); - } -} - -u32 wmiSendCmdNum; - -int -ar6000_control_tx(void *devt, void *osbuf, HTC_ENDPOINT_ID eid) -{ - struct ar6_softc *ar = (struct ar6_softc *)devt; - int status = 0; - struct ar_cookie *cookie = NULL; - int i; -#ifdef CONFIG_PM - if (ar->arWowState != WLAN_WOW_STATE_NONE) { - A_NETBUF_FREE(osbuf); - return A_EACCES; - } -#endif /* CONFIG_PM */ - /* take lock to protect ar6000_alloc_cookie() */ - AR6000_SPIN_LOCK(&ar->arLock, 0); - - do { - - AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX,("ar_contrstatus = ol_tx: skb=0x%lx, len=0x%x eid =%d\n", - (unsigned long)osbuf, A_NETBUF_LEN(osbuf), eid)); - - if (ar->arWMIControlEpFull && (eid == ar->arControlEp)) { - /* control endpoint is full, don't allocate resources, we - * are just going to drop this packet */ - cookie = NULL; - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,(" WMI Control EP full, dropping packet : 0x%lX, len:%d \n", - (unsigned long)osbuf, A_NETBUF_LEN(osbuf))); - } else { - cookie = ar6000_alloc_cookie(ar); - } - - if (cookie == NULL) { - status = A_NO_MEMORY; - break; - } - - if(logWmiRawMsgs) { - A_PRINTF("WMI cmd send, msgNo %d :", wmiSendCmdNum); - for(i = 0; i < a_netbuf_to_len(osbuf); i++) - A_PRINTF("%x ", ((u8 *)a_netbuf_to_data(osbuf))[i]); - A_PRINTF("\n"); - } - - wmiSendCmdNum++; - - } while (false); - - if (cookie != NULL) { - /* got a structure to send it out on */ - ar->arTxPending[eid]++; - - if (eid != ar->arControlEp) { - ar->arTotalTxDataPending++; - } - } - - AR6000_SPIN_UNLOCK(&ar->arLock, 0); - - if (cookie != NULL) { - cookie->arc_bp[0] = (unsigned long)osbuf; - cookie->arc_bp[1] = 0; - SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt, - cookie, - A_NETBUF_DATA(osbuf), - A_NETBUF_LEN(osbuf), - eid, - AR6K_CONTROL_PKT_TAG); - /* this interface is asynchronous, if there is an error, cleanup will happen in the - * TX completion callback */ - HTCSendPkt(ar->arHtcTarget, &cookie->HtcPkt); - status = 0; - } - - if (status) { - A_NETBUF_FREE(osbuf); - } - return status; -} - -/* indicate tx activity or inactivity on a WMI stream */ -void ar6000_indicate_tx_activity(void *devt, u8 TrafficClass, bool Active) -{ - struct ar6_softc *ar = (struct ar6_softc *)devt; - HTC_ENDPOINT_ID eid ; - int i; - - if (ar->arWmiEnabled) { - eid = arAc2EndpointID(ar, TrafficClass); - - AR6000_SPIN_LOCK(&ar->arLock, 0); - - ar->arAcStreamActive[TrafficClass] = Active; - - if (Active) { - /* when a stream goes active, keep track of the active stream with the highest priority */ - - if (ar->arAcStreamPriMap[TrafficClass] > ar->arHiAcStreamActivePri) { - /* set the new highest active priority */ - ar->arHiAcStreamActivePri = ar->arAcStreamPriMap[TrafficClass]; - } - - } else { - /* when a stream goes inactive, we may have to search for the next active stream - * that is the highest priority */ - - if (ar->arHiAcStreamActivePri == ar->arAcStreamPriMap[TrafficClass]) { - - /* the highest priority stream just went inactive */ - - /* reset and search for the "next" highest "active" priority stream */ - ar->arHiAcStreamActivePri = 0; - for (i = 0; i < WMM_NUM_AC; i++) { - if (ar->arAcStreamActive[i]) { - if (ar->arAcStreamPriMap[i] > ar->arHiAcStreamActivePri) { - /* set the new highest active priority */ - ar->arHiAcStreamActivePri = ar->arAcStreamPriMap[i]; - } - } - } - } - } - - AR6000_SPIN_UNLOCK(&ar->arLock, 0); - - } else { - /* for mbox ping testing, the traffic class is mapped directly as a stream ID, - * see handling of AR6000_XIOCTL_TRAFFIC_ACTIVITY_CHANGE in ioctl.c - * convert the stream ID to a endpoint */ - eid = arAc2EndpointID(ar, TrafficClass); - } - - /* notify HTC, this may cause credit distribution changes */ - - HTCIndicateActivityChange(ar->arHtcTarget, - eid, - Active); - -} - -void -ar6000_btcoex_config_event(struct ar6_softc *ar, u8 *ptr, u32 len) -{ - - WMI_BTCOEX_CONFIG_EVENT *pBtcoexConfig = (WMI_BTCOEX_CONFIG_EVENT *)ptr; - WMI_BTCOEX_CONFIG_EVENT *pArbtcoexConfig =&ar->arBtcoexConfig; - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR6000 BTCOEX CONFIG EVENT \n")); - - A_PRINTF("received config event\n"); - pArbtcoexConfig->btProfileType = pBtcoexConfig->btProfileType; - pArbtcoexConfig->linkId = pBtcoexConfig->linkId; - - switch (pBtcoexConfig->btProfileType) { - case WMI_BTCOEX_BT_PROFILE_SCO: - memcpy(&pArbtcoexConfig->info.scoConfigCmd, &pBtcoexConfig->info.scoConfigCmd, - sizeof(WMI_SET_BTCOEX_SCO_CONFIG_CMD)); - break; - case WMI_BTCOEX_BT_PROFILE_A2DP: - memcpy(&pArbtcoexConfig->info.a2dpConfigCmd, &pBtcoexConfig->info.a2dpConfigCmd, - sizeof(WMI_SET_BTCOEX_A2DP_CONFIG_CMD)); - break; - case WMI_BTCOEX_BT_PROFILE_ACLCOEX: - memcpy(&pArbtcoexConfig->info.aclcoexConfig, &pBtcoexConfig->info.aclcoexConfig, - sizeof(WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD)); - break; - case WMI_BTCOEX_BT_PROFILE_INQUIRY_PAGE: - memcpy(&pArbtcoexConfig->info.btinquiryPageConfigCmd, &pBtcoexConfig->info.btinquiryPageConfigCmd, - sizeof(WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD)); - break; - } - if (ar->statsUpdatePending) { - ar->statsUpdatePending = false; - wake_up(&arEvent); - } -} - -void -ar6000_btcoex_stats_event(struct ar6_softc *ar, u8 *ptr, u32 len) -{ - WMI_BTCOEX_STATS_EVENT *pBtcoexStats = (WMI_BTCOEX_STATS_EVENT *)ptr; - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR6000 BTCOEX CONFIG EVENT \n")); - - memcpy(&ar->arBtcoexStats, pBtcoexStats, sizeof(WMI_BTCOEX_STATS_EVENT)); - - if (ar->statsUpdatePending) { - ar->statsUpdatePending = false; - wake_up(&arEvent); - } - -} -module_init(ar6000_init_module); -module_exit(ar6000_cleanup_module); - -/* Init cookie queue */ -static void -ar6000_cookie_init(struct ar6_softc *ar) -{ - u32 i; - - ar->arCookieList = NULL; - ar->arCookieCount = 0; - - A_MEMZERO(s_ar_cookie_mem, sizeof(s_ar_cookie_mem)); - - for (i = 0; i < MAX_COOKIE_NUM; i++) { - ar6000_free_cookie(ar, &s_ar_cookie_mem[i]); - } -} - -/* cleanup cookie queue */ -static void -ar6000_cookie_cleanup(struct ar6_softc *ar) -{ - /* It is gone .... */ - ar->arCookieList = NULL; - ar->arCookieCount = 0; -} - -/* Init cookie queue */ -static void -ar6000_free_cookie(struct ar6_softc *ar, struct ar_cookie * cookie) -{ - /* Insert first */ - A_ASSERT(ar != NULL); - A_ASSERT(cookie != NULL); - - cookie->arc_list_next = ar->arCookieList; - ar->arCookieList = cookie; - ar->arCookieCount++; -} - -/* cleanup cookie queue */ -static struct ar_cookie * -ar6000_alloc_cookie(struct ar6_softc *ar) -{ - struct ar_cookie *cookie; - - cookie = ar->arCookieList; - if(cookie != NULL) - { - ar->arCookieList = cookie->arc_list_next; - ar->arCookieCount--; - } - - return cookie; -} - -void -ar6000_tx_retry_err_event(void *devt) -{ - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Tx retries reach maximum!\n")); -} - -void -ar6000_snrThresholdEvent_rx(void *devt, WMI_SNR_THRESHOLD_VAL newThreshold, u8 snr) -{ - WMI_SNR_THRESHOLD_EVENT event; - - event.range = newThreshold; - event.snr = snr; -} - -void -ar6000_lqThresholdEvent_rx(void *devt, WMI_LQ_THRESHOLD_VAL newThreshold, u8 lq) -{ - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("lq threshold range %d, lq %d\n", newThreshold, lq)); -} - - - -u32 a_copy_to_user(void *to, const void *from, u32 n) -{ - return(copy_to_user(to, from, n)); -} - -u32 a_copy_from_user(void *to, const void *from, u32 n) -{ - return(copy_from_user(to, from, n)); -} - - -int -ar6000_get_driver_cfg(struct net_device *dev, - u16 cfgParam, - void *result) -{ - - int ret = 0; - - switch(cfgParam) - { - case AR6000_DRIVER_CFG_GET_WLANNODECACHING: - *((u32 *)result) = wlanNodeCaching; - break; - case AR6000_DRIVER_CFG_LOG_RAW_WMI_MSGS: - *((u32 *)result) = logWmiRawMsgs; - break; - default: - ret = EINVAL; - break; - } - - return ret; -} - -void -ar6000_keepalive_rx(void *devt, u8 configured) -{ - struct ar6_softc *ar = (struct ar6_softc *)devt; - - ar->arKeepaliveConfigured = configured; - wake_up(&arEvent); -} - -void -ar6000_pmkid_list_event(void *devt, u8 numPMKID, WMI_PMKID *pmkidList, - u8 *bssidList) -{ - u8 i, j; - - A_PRINTF("Number of Cached PMKIDs is %d\n", numPMKID); - - for (i = 0; i < numPMKID; i++) { - A_PRINTF("\nBSSID %d ", i); - for (j = 0; j < ATH_MAC_LEN; j++) { - A_PRINTF("%2.2x", bssidList[j]); - } - bssidList += (ATH_MAC_LEN + WMI_PMKID_LEN); - A_PRINTF("\nPMKID %d ", i); - for (j = 0; j < WMI_PMKID_LEN; j++) { - A_PRINTF("%2.2x", pmkidList->pmkid[j]); - } - pmkidList = (WMI_PMKID *)((u8 *)pmkidList + ATH_MAC_LEN + - WMI_PMKID_LEN); - } -} - -void ar6000_pspoll_event(struct ar6_softc *ar,u8 aid) -{ - sta_t *conn=NULL; - bool isPsqEmpty = false; - - conn = ieee80211_find_conn_for_aid(ar, aid); - - /* If the PS q for this STA is not empty, dequeue and send a pkt from - * the head of the q. Also update the More data bit in the WMI_DATA_HDR - * if there are more pkts for this STA in the PS q. If there are no more - * pkts for this STA, update the PVB for this STA. - */ - A_MUTEX_LOCK(&conn->psqLock); - isPsqEmpty = A_NETBUF_QUEUE_EMPTY(&conn->psq); - A_MUTEX_UNLOCK(&conn->psqLock); - - if (isPsqEmpty) { - /* TODO:No buffered pkts for this STA. Send out a NULL data frame */ - } else { - struct sk_buff *skb = NULL; - - A_MUTEX_LOCK(&conn->psqLock); - skb = A_NETBUF_DEQUEUE(&conn->psq); - A_MUTEX_UNLOCK(&conn->psqLock); - /* Set the STA flag to PSPolled, so that the frame will go out */ - STA_SET_PS_POLLED(conn); - ar6000_data_tx(skb, ar->arNetDev); - STA_CLR_PS_POLLED(conn); - - /* Clear the PVB for this STA if the queue has become empty */ - A_MUTEX_LOCK(&conn->psqLock); - isPsqEmpty = A_NETBUF_QUEUE_EMPTY(&conn->psq); - A_MUTEX_UNLOCK(&conn->psqLock); - - if (isPsqEmpty) { - wmi_set_pvb_cmd(ar->arWmi, conn->aid, 0); - } - } -} - -void ar6000_dtimexpiry_event(struct ar6_softc *ar) -{ - bool isMcastQueued = false; - struct sk_buff *skb = NULL; - - /* If there are no associated STAs, ignore the DTIM expiry event. - * There can be potential race conditions where the last associated - * STA may disconnect & before the host could clear the 'Indicate DTIM' - * request to the firmware, the firmware would have just indicated a DTIM - * expiry event. The race is between 'clear DTIM expiry cmd' going - * from the host to the firmware & the DTIM expiry event happening from - * the firmware to the host. - */ - if (ar->sta_list_index == 0) { - return; - } - - A_MUTEX_LOCK(&ar->mcastpsqLock); - isMcastQueued = A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq); - A_MUTEX_UNLOCK(&ar->mcastpsqLock); - - A_ASSERT(isMcastQueued == false); - - /* Flush the mcast psq to the target */ - /* Set the STA flag to DTIMExpired, so that the frame will go out */ - ar->DTIMExpired = true; - - A_MUTEX_LOCK(&ar->mcastpsqLock); - while (!A_NETBUF_QUEUE_EMPTY(&ar->mcastpsq)) { - skb = A_NETBUF_DEQUEUE(&ar->mcastpsq); - A_MUTEX_UNLOCK(&ar->mcastpsqLock); - - ar6000_data_tx(skb, ar->arNetDev); - - A_MUTEX_LOCK(&ar->mcastpsqLock); - } - A_MUTEX_UNLOCK(&ar->mcastpsqLock); - - /* Reset the DTIMExpired flag back to 0 */ - ar->DTIMExpired = false; - - /* Clear the LSB of the BitMapCtl field of the TIM IE */ - wmi_set_pvb_cmd(ar->arWmi, MCAST_AID, 0); -} - -void -read_rssi_compensation_param(struct ar6_softc *ar) -{ - u8 *cust_data_ptr; - -//#define RSSICOMPENSATION_PRINT - -#ifdef RSSICOMPENSATION_PRINT - s16 i; - cust_data_ptr = ar6000_get_cust_data_buffer(ar->arTargetType); - for (i=0; i<16; i++) { - A_PRINTF("cust_data_%d = %x \n", i, *(u8 *)cust_data_ptr); - cust_data_ptr += 1; - } -#endif - - cust_data_ptr = ar6000_get_cust_data_buffer(ar->arTargetType); - - rssi_compensation_param.customerID = *(u16 *)cust_data_ptr & 0xffff; - rssi_compensation_param.enable = *(u16 *)(cust_data_ptr+2) & 0xffff; - rssi_compensation_param.bg_param_a = *(u16 *)(cust_data_ptr+4) & 0xffff; - rssi_compensation_param.bg_param_b = *(u16 *)(cust_data_ptr+6) & 0xffff; - rssi_compensation_param.a_param_a = *(u16 *)(cust_data_ptr+8) & 0xffff; - rssi_compensation_param.a_param_b = *(u16 *)(cust_data_ptr+10) &0xffff; - rssi_compensation_param.reserved = *(u32 *)(cust_data_ptr+12); - -#ifdef RSSICOMPENSATION_PRINT - A_PRINTF("customerID = 0x%x \n", rssi_compensation_param.customerID); - A_PRINTF("enable = 0x%x \n", rssi_compensation_param.enable); - A_PRINTF("bg_param_a = 0x%x and %d \n", rssi_compensation_param.bg_param_a, rssi_compensation_param.bg_param_a); - A_PRINTF("bg_param_b = 0x%x and %d \n", rssi_compensation_param.bg_param_b, rssi_compensation_param.bg_param_b); - A_PRINTF("a_param_a = 0x%x and %d \n", rssi_compensation_param.a_param_a, rssi_compensation_param.a_param_a); - A_PRINTF("a_param_b = 0x%x and %d \n", rssi_compensation_param.a_param_b, rssi_compensation_param.a_param_b); - A_PRINTF("Last 4 bytes = 0x%x \n", rssi_compensation_param.reserved); -#endif - - if (rssi_compensation_param.enable != 0x1) { - rssi_compensation_param.enable = 0; - } - - return; -} - -s32 rssi_compensation_calc_tcmd(u32 freq, s32 rssi, u32 totalPkt) -{ - - if (freq > 5000) - { - if (rssi_compensation_param.enable) - { - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11a\n")); - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before compensation = %d, totalPkt = %d\n", rssi,totalPkt)); - rssi = rssi * rssi_compensation_param.a_param_a + totalPkt * rssi_compensation_param.a_param_b; - rssi = (rssi-50) /100; - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after compensation = %d\n", rssi)); - } - } - else - { - if (rssi_compensation_param.enable) - { - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11bg\n")); - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before compensation = %d, totalPkt = %d\n", rssi,totalPkt)); - rssi = rssi * rssi_compensation_param.bg_param_a + totalPkt * rssi_compensation_param.bg_param_b; - rssi = (rssi-50) /100; - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after compensation = %d\n", rssi)); - } - } - - return rssi; -} - -s16 rssi_compensation_calc(struct ar6_softc *ar, s16 rssi) -{ - if (ar->arBssChannel > 5000) - { - if (rssi_compensation_param.enable) - { - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11a\n")); - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before compensation = %d\n", rssi)); - rssi = rssi * rssi_compensation_param.a_param_a + rssi_compensation_param.a_param_b; - rssi = (rssi-50) /100; - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after compensation = %d\n", rssi)); - } - } - else - { - if (rssi_compensation_param.enable) - { - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11bg\n")); - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before compensation = %d\n", rssi)); - rssi = rssi * rssi_compensation_param.bg_param_a + rssi_compensation_param.bg_param_b; - rssi = (rssi-50) /100; - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after compensation = %d\n", rssi)); - } - } - - return rssi; -} - -s16 rssi_compensation_reverse_calc(struct ar6_softc *ar, s16 rssi, bool Above) -{ - s16 i; - - if (ar->arBssChannel > 5000) - { - if (rssi_compensation_param.enable) - { - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11a\n")); - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before rev compensation = %d\n", rssi)); - rssi = rssi * 100; - rssi = (rssi - rssi_compensation_param.a_param_b) / rssi_compensation_param.a_param_a; - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after rev compensation = %d\n", rssi)); - } - } - else - { - if (rssi_compensation_param.enable) - { - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, (">>> 11bg\n")); - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi before rev compensation = %d\n", rssi)); - - if (Above) { - for (i=95; i>=0; i--) { - if (rssi <= rssi_compensation_table[i]) { - rssi = 0 - i; - break; - } - } - } else { - for (i=0; i<=95; i++) { - if (rssi >= rssi_compensation_table[i]) { - rssi = 0 - i; - break; - } - } - } - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("rssi after rev compensation = %d\n", rssi)); - } - } - - return rssi; -} - -#ifdef WAPI_ENABLE -void ap_wapi_rekey_event(struct ar6_softc *ar, u8 type, u8 *mac) -{ - union iwreq_data wrqu; - char buf[20]; - - A_MEMZERO(buf, sizeof(buf)); - - strcpy(buf, "WAPI_REKEY"); - buf[10] = type; - memcpy(&buf[11], mac, ATH_MAC_LEN); - - A_MEMZERO(&wrqu, sizeof(wrqu)); - wrqu.data.length = 10+1+ATH_MAC_LEN; - wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf); - - A_PRINTF("WAPI REKEY - %d - %02x:%02x\n", type, mac[4], mac[5]); -} -#endif - -static int -ar6000_reinstall_keys(struct ar6_softc *ar, u8 key_op_ctrl) -{ - int status = 0; - struct ieee80211req_key *uik = &ar->user_saved_keys.ucast_ik; - struct ieee80211req_key *bik = &ar->user_saved_keys.bcast_ik; - CRYPTO_TYPE keyType = ar->user_saved_keys.keyType; - - if (IEEE80211_CIPHER_CCKM_KRK != uik->ik_type) { - if (NONE_CRYPT == keyType) { - goto _reinstall_keys_out; - } - - if (uik->ik_keylen) { - status = wmi_addKey_cmd(ar->arWmi, uik->ik_keyix, - ar->user_saved_keys.keyType, PAIRWISE_USAGE, - uik->ik_keylen, (u8 *)&uik->ik_keyrsc, - uik->ik_keydata, key_op_ctrl, uik->ik_macaddr, SYNC_BEFORE_WMIFLAG); - } - - } else { - status = wmi_add_krk_cmd(ar->arWmi, uik->ik_keydata); - } - - if (IEEE80211_CIPHER_CCKM_KRK != bik->ik_type) { - if (NONE_CRYPT == keyType) { - goto _reinstall_keys_out; - } - - if (bik->ik_keylen) { - status = wmi_addKey_cmd(ar->arWmi, bik->ik_keyix, - ar->user_saved_keys.keyType, GROUP_USAGE, - bik->ik_keylen, (u8 *)&bik->ik_keyrsc, - bik->ik_keydata, key_op_ctrl, bik->ik_macaddr, NO_SYNC_WMIFLAG); - } - } else { - status = wmi_add_krk_cmd(ar->arWmi, bik->ik_keydata); - } - -_reinstall_keys_out: - ar->user_savedkeys_stat = USER_SAVEDKEYS_STAT_INIT; - ar->user_key_ctrl = 0; - - return status; -} - - -void -ar6000_dset_open_req( - void *context, - u32 id, - u32 targHandle, - u32 targReplyFn, - u32 targReplyArg) -{ -} - -void -ar6000_dset_close( - void *context, - u32 access_cookie) -{ - return; -} - -void -ar6000_dset_data_req( - void *context, - u32 accessCookie, - u32 offset, - u32 length, - u32 targBuf, - u32 targReplyFn, - u32 targReplyArg) -{ -} - -int -ar6000_ap_mode_profile_commit(struct ar6_softc *ar) -{ - WMI_CONNECT_CMD p; - unsigned long flags; - - /* No change in AP's profile configuration */ - if(ar->ap_profile_flag==0) { - A_PRINTF("COMMIT: No change in profile!!!\n"); - return -ENODATA; - } - - if(!ar->arSsidLen) { - A_PRINTF("SSID not set!!!\n"); - return -ECHRNG; - } - - switch(ar->arAuthMode) { - case NONE_AUTH: - if((ar->arPairwiseCrypto != NONE_CRYPT) && -#ifdef WAPI_ENABLE - (ar->arPairwiseCrypto != WAPI_CRYPT) && -#endif - (ar->arPairwiseCrypto != WEP_CRYPT)) { - A_PRINTF("Cipher not supported in AP mode Open auth\n"); - return -EOPNOTSUPP; - } - break; - case WPA_PSK_AUTH: - case WPA2_PSK_AUTH: - case (WPA_PSK_AUTH|WPA2_PSK_AUTH): - break; - default: - A_PRINTF("This key mgmt type not supported in AP mode\n"); - return -EOPNOTSUPP; - } - - /* Update the arNetworkType */ - ar->arNetworkType = ar->arNextMode; - - A_MEMZERO(&p,sizeof(p)); - p.ssidLength = ar->arSsidLen; - memcpy(p.ssid,ar->arSsid,p.ssidLength); - p.channel = ar->arChannelHint; - p.networkType = ar->arNetworkType; - - p.dot11AuthMode = ar->arDot11AuthMode; - p.authMode = ar->arAuthMode; - p.pairwiseCryptoType = ar->arPairwiseCrypto; - p.pairwiseCryptoLen = ar->arPairwiseCryptoLen; - p.groupCryptoType = ar->arGroupCrypto; - p.groupCryptoLen = ar->arGroupCryptoLen; - p.ctrl_flags = ar->arConnectCtrlFlags; - - wmi_ap_profile_commit(ar->arWmi, &p); - spin_lock_irqsave(&ar->arLock, flags); - ar->arConnected = true; - netif_carrier_on(ar->arNetDev); - spin_unlock_irqrestore(&ar->arLock, flags); - ar->ap_profile_flag = 0; - return 0; -} - -int -ar6000_connect_to_ap(struct ar6_softc *ar) -{ - /* The ssid length check prevents second "essid off" from the user, - to be treated as a connect cmd. The second "essid off" is ignored. - */ - if((ar->arWmiReady == true) && (ar->arSsidLen > 0) && ar->arNetworkType!=AP_NETWORK) - { - int status; - if((ADHOC_NETWORK != ar->arNetworkType) && - (NONE_AUTH==ar->arAuthMode) && - (WEP_CRYPT==ar->arPairwiseCrypto)) { - ar6000_install_static_wep_keys(ar); - } - - if (!ar->arUserBssFilter) { - if (wmi_bssfilter_cmd(ar->arWmi, ALL_BSS_FILTER, 0) != 0) { - return -EIO; - } - } -#ifdef WAPI_ENABLE - if (ar->arWapiEnable) { - ar->arPairwiseCrypto = WAPI_CRYPT; - ar->arPairwiseCryptoLen = 0; - ar->arGroupCrypto = WAPI_CRYPT; - ar->arGroupCryptoLen = 0; - ar->arAuthMode = NONE_AUTH; - ar->arConnectCtrlFlags |= CONNECT_IGNORE_WPAx_GROUP_CIPHER; - } -#endif - AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("Connect called with authmode %d dot11 auth %d"\ - " PW crypto %d PW crypto Len %d GRP crypto %d"\ - " GRP crypto Len %d\n", - ar->arAuthMode, ar->arDot11AuthMode, - ar->arPairwiseCrypto, ar->arPairwiseCryptoLen, - ar->arGroupCrypto, ar->arGroupCryptoLen)); - reconnect_flag = 0; - /* Set the listen interval into 1000TUs or more. This value will be indicated to Ap in the conn. - later set it back locally at the STA to 100/1000 TUs depending on the power mode */ - if ((ar->arNetworkType == INFRA_NETWORK)) { - wmi_listeninterval_cmd(ar->arWmi, max(ar->arListenIntervalT, (u16)A_MAX_WOW_LISTEN_INTERVAL), 0); - } - status = wmi_connect_cmd(ar->arWmi, ar->arNetworkType, - ar->arDot11AuthMode, ar->arAuthMode, - ar->arPairwiseCrypto, ar->arPairwiseCryptoLen, - ar->arGroupCrypto,ar->arGroupCryptoLen, - ar->arSsidLen, ar->arSsid, - ar->arReqBssid, ar->arChannelHint, - ar->arConnectCtrlFlags); - if (status) { - wmi_listeninterval_cmd(ar->arWmi, ar->arListenIntervalT, ar->arListenIntervalB); - if (!ar->arUserBssFilter) { - wmi_bssfilter_cmd(ar->arWmi, NONE_BSS_FILTER, 0); - } - return status; - } - - if ((!(ar->arConnectCtrlFlags & CONNECT_DO_WPA_OFFLOAD)) && - ((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode))) - { - A_TIMEOUT_MS(&ar->disconnect_timer, A_DISCONNECT_TIMER_INTERVAL, 0); - } - - ar->arConnectCtrlFlags &= ~CONNECT_DO_WPA_OFFLOAD; - - ar->arConnectPending = true; - return status; - } - return A_ERROR; -} - -int -ar6000_disconnect(struct ar6_softc *ar) -{ - if ((ar->arConnected == true) || (ar->arConnectPending == true)) { - wmi_disconnect_cmd(ar->arWmi); - /* - * Disconnect cmd is issued, clear connectPending. - * arConnected will be cleard in disconnect_event notification. - */ - ar->arConnectPending = false; - } - - return 0; -} - -int -ar6000_ap_mode_get_wpa_ie(struct ar6_softc *ar, struct ieee80211req_wpaie *wpaie) -{ - sta_t *conn = NULL; - conn = ieee80211_find_conn(ar, wpaie->wpa_macaddr); - - A_MEMZERO(wpaie->wpa_ie, IEEE80211_MAX_IE); - A_MEMZERO(wpaie->rsn_ie, IEEE80211_MAX_IE); - - if(conn) { - memcpy(wpaie->wpa_ie, conn->wpa_ie, IEEE80211_MAX_IE); - } - - return 0; -} - -int -is_iwioctl_allowed(u8 mode, u16 cmd) -{ - if(cmd >= SIOCSIWCOMMIT && cmd <= SIOCGIWPOWER) { - cmd -= SIOCSIWCOMMIT; - if(sioctl_filter[cmd] == 0xFF) return 0; - if(sioctl_filter[cmd] & mode) return 0; - } else if(cmd >= SIOCIWFIRSTPRIV && cmd <= (SIOCIWFIRSTPRIV+30)) { - cmd -= SIOCIWFIRSTPRIV; - if(pioctl_filter[cmd] == 0xFF) return 0; - if(pioctl_filter[cmd] & mode) return 0; - } else { - return A_ERROR; - } - return A_ENOTSUP; -} - -int -is_xioctl_allowed(u8 mode, int cmd) -{ - if(sizeof(xioctl_filter)-1 < cmd) { - A_PRINTF("Filter for this cmd=%d not defined\n",cmd); - return 0; - } - if(xioctl_filter[cmd] == 0xFF) return 0; - if(xioctl_filter[cmd] & mode) return 0; - return A_ERROR; -} - -#ifdef WAPI_ENABLE -int -ap_set_wapi_key(struct ar6_softc *ar, void *ikey) -{ - struct ieee80211req_key *ik = (struct ieee80211req_key *)ikey; - KEY_USAGE keyUsage = 0; - int status; - - if (memcmp(ik->ik_macaddr, bcast_mac, IEEE80211_ADDR_LEN) == 0) { - keyUsage = GROUP_USAGE; - } else { - keyUsage = PAIRWISE_USAGE; - } - A_PRINTF("WAPI_KEY: Type:%d ix:%d mac:%02x:%02x len:%d\n", - keyUsage, ik->ik_keyix, ik->ik_macaddr[4], ik->ik_macaddr[5], - ik->ik_keylen); - - status = wmi_addKey_cmd(ar->arWmi, ik->ik_keyix, WAPI_CRYPT, keyUsage, - ik->ik_keylen, (u8 *)&ik->ik_keyrsc, - ik->ik_keydata, KEY_OP_INIT_VAL, ik->ik_macaddr, - SYNC_BOTH_WMIFLAG); - - if (0 != status) { - return -EIO; - } - return 0; -} -#endif - -void ar6000_peer_event( - void *context, - u8 eventCode, - u8 *macAddr) -{ - u8 pos; - - for (pos=0;pos<6;pos++) - printk("%02x: ",*(macAddr+pos)); - printk("\n"); -} - -#ifdef HTC_TEST_SEND_PKTS -#define HTC_TEST_DUPLICATE 8 -static void DoHTCSendPktsTest(struct ar6_softc *ar, int MapNo, HTC_ENDPOINT_ID eid, struct sk_buff *dupskb) -{ - struct ar_cookie *cookie; - struct ar_cookie *cookieArray[HTC_TEST_DUPLICATE]; - struct sk_buff *new_skb; - int i; - int pkts = 0; - struct htc_packet_queue pktQueue; - EPPING_HEADER *eppingHdr; - - eppingHdr = A_NETBUF_DATA(dupskb); - - if (eppingHdr->Cmd_h == EPPING_CMD_NO_ECHO) { - /* skip test if this is already a tx perf test */ - return; - } - - for (i = 0; i < HTC_TEST_DUPLICATE; i++,pkts++) { - AR6000_SPIN_LOCK(&ar->arLock, 0); - cookie = ar6000_alloc_cookie(ar); - if (cookie != NULL) { - ar->arTxPending[eid]++; - ar->arTotalTxDataPending++; - } - - AR6000_SPIN_UNLOCK(&ar->arLock, 0); - - if (NULL == cookie) { - break; - } - - new_skb = A_NETBUF_ALLOC(A_NETBUF_LEN(dupskb)); - - if (new_skb == NULL) { - AR6000_SPIN_LOCK(&ar->arLock, 0); - ar6000_free_cookie(ar,cookie); - AR6000_SPIN_UNLOCK(&ar->arLock, 0); - break; - } - - A_NETBUF_PUT_DATA(new_skb, A_NETBUF_DATA(dupskb), A_NETBUF_LEN(dupskb)); - cookie->arc_bp[0] = (unsigned long)new_skb; - cookie->arc_bp[1] = MapNo; - SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt, - cookie, - A_NETBUF_DATA(new_skb), - A_NETBUF_LEN(new_skb), - eid, - AR6K_DATA_PKT_TAG); - - cookieArray[i] = cookie; - - { - EPPING_HEADER *pHdr = (EPPING_HEADER *)A_NETBUF_DATA(new_skb); - pHdr->Cmd_h = EPPING_CMD_NO_ECHO; /* do not echo the packet */ - } - } - - if (pkts == 0) { - return; - } - - INIT_HTC_PACKET_QUEUE(&pktQueue); - - for (i = 0; i < pkts; i++) { - HTC_PACKET_ENQUEUE(&pktQueue,&cookieArray[i]->HtcPkt); - } - - HTCSendPktsMultiple(ar->arHtcTarget, &pktQueue); - -} -#endif - -#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT -/* - * Add support for adding and removing a virtual adapter for soft AP. - * Some OS requires different adapters names for station and soft AP mode. - * To support these requirement, create and destroy a netdevice instance - * when the AP mode is operational. A full fledged support for virual device - * is not implemented. Rather a virtual interface is created and is linked - * with the existing physical device instance during the operation of the - * AP mode. - */ - -int ar6000_start_ap_interface(struct ar6_softc *ar) -{ - struct ar_virtual_interface *arApDev; - - /* Change net_device to point to AP instance */ - arApDev = (struct ar_virtual_interface *)ar->arApDev; - ar->arNetDev = arApDev->arNetDev; - - return 0; -} - -int ar6000_stop_ap_interface(struct ar6_softc *ar) -{ - struct ar_virtual_interface *arApDev; - - /* Change net_device to point to sta instance */ - arApDev = (struct ar_virtual_interface *)ar->arApDev; - if (arApDev) { - ar->arNetDev = arApDev->arStaNetDev; - } - - return 0; -} - - -int ar6000_create_ap_interface(struct ar6_softc *ar, char *ap_ifname) -{ - struct net_device *dev; - struct ar_virtual_interface *arApDev; - - dev = alloc_etherdev(sizeof(struct ar_virtual_interface)); - if (dev == NULL) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_create_ap_interface: can't alloc etherdev\n")); - return A_ERROR; - } - - ether_setup(dev); - init_netdev(dev, ap_ifname); - dev->priv_flags &= ~IFF_TX_SKB_SHARING; - - if (register_netdev(dev)) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_create_ap_interface: register_netdev failed\n")); - return A_ERROR; - } - - arApDev = netdev_priv(dev); - arApDev->arDev = ar; - arApDev->arNetDev = dev; - arApDev->arStaNetDev = ar->arNetDev; - - ar->arApDev = arApDev; - arApNetDev = dev; - - /* Copy the MAC address */ - memcpy(dev->dev_addr, ar->arNetDev->dev_addr, AR6000_ETH_ADDR_LEN); - - return 0; -} - -int ar6000_add_ap_interface(struct ar6_softc *ar, char *ap_ifname) -{ - /* Interface already added, need not proceed further */ - if (ar->arApDev != NULL) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("ar6000_add_ap_interface: interface already present \n")); - return 0; - } - - if (ar6000_create_ap_interface(ar, ap_ifname) != 0) { - return A_ERROR; - } - - A_PRINTF("Add AP interface %s \n",ap_ifname); - - return ar6000_start_ap_interface(ar); -} - -int ar6000_remove_ap_interface(struct ar6_softc *ar) -{ - if (arApNetDev) { - ar6000_stop_ap_interface(ar); - - unregister_netdev(arApNetDev); - free_netdev(apApNetDev); - - A_PRINTF("Remove AP interface\n"); - } - ar->arApDev = NULL; - arApNetDev = NULL; - - - return 0; -} -#endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */ - - -#ifdef EXPORT_HCI_BRIDGE_INTERFACE -EXPORT_SYMBOL(setupbtdev); -#endif diff --git a/drivers/staging/ath6kl/os/linux/ar6000_pm.c b/drivers/staging/ath6kl/os/linux/ar6000_pm.c deleted file mode 100644 index 1e0ace8..0000000 --- a/drivers/staging/ath6kl/os/linux/ar6000_pm.c +++ /dev/null @@ -1,626 +0,0 @@ -/* - * - * Copyright (c) 2004-2010 Atheros Communications Inc. - * All rights reserved. - * - * -// -// 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. -// -// - * - */ - -/* - * Implementation of system power management - */ - -#include "ar6000_drv.h" -#include <linux/inetdevice.h> -#include <linux/platform_device.h> -#include "wlan_config.h" - -#define WOW_ENABLE_MAX_INTERVAL 0 -#define WOW_SET_SCAN_PARAMS 0 - -extern unsigned int wmitimeout; -extern wait_queue_head_t arEvent; - -#undef ATH_MODULE_NAME -#define ATH_MODULE_NAME pm -#define ATH_DEBUG_PM ATH_DEBUG_MAKE_MODULE_MASK(0) - -#ifdef DEBUG -static struct ath_debug_mask_description pm_debug_desc[] = { - { ATH_DEBUG_PM , "System power management"}, -}; - -ATH_DEBUG_INSTANTIATE_MODULE_VAR(pm, - "pm", - "System Power Management", - ATH_DEBUG_MASK_DEFAULTS | ATH_DEBUG_PM, - ATH_DEBUG_DESCRIPTION_COUNT(pm_debug_desc), - pm_debug_desc); - -#endif /* DEBUG */ - -int ar6000_exit_cut_power_state(struct ar6_softc *ar); - -#ifdef CONFIG_PM -static void ar6k_send_asleep_event_to_app(struct ar6_softc *ar, bool asleep) -{ - char buf[128]; - union iwreq_data wrqu; - - snprintf(buf, sizeof(buf), "HOST_ASLEEP=%s", asleep ? "asleep" : "awake"); - A_MEMZERO(&wrqu, sizeof(wrqu)); - wrqu.data.length = strlen(buf); - wireless_send_event(ar->arNetDev, IWEVCUSTOM, &wrqu, buf); -} - -static void ar6000_wow_resume(struct ar6_softc *ar) -{ - if (ar->arWowState!= WLAN_WOW_STATE_NONE) { - u16 fg_start_period = (ar->scParams.fg_start_period==0) ? 1 : ar->scParams.fg_start_period; - u16 bg_period = (ar->scParams.bg_period==0) ? 60 : ar->scParams.bg_period; - WMI_SET_HOST_SLEEP_MODE_CMD hostSleepMode = {true, false}; - ar->arWowState = WLAN_WOW_STATE_NONE; - if (wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode)!= 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to setup restore host awake\n")); - } -#if WOW_SET_SCAN_PARAMS - wmi_scanparams_cmd(ar->arWmi, fg_start_period, - ar->scParams.fg_end_period, - bg_period, - ar->scParams.minact_chdwell_time, - ar->scParams.maxact_chdwell_time, - ar->scParams.pas_chdwell_time, - ar->scParams.shortScanRatio, - ar->scParams.scanCtrlFlags, - ar->scParams.max_dfsch_act_time, - ar->scParams.maxact_scan_per_ssid); -#else - (void)fg_start_period; - (void)bg_period; -#endif - - -#if WOW_ENABLE_MAX_INTERVAL /* we don't do it if the power consumption is already good enough. */ - if (wmi_listeninterval_cmd(ar->arWmi, ar->arListenIntervalT, ar->arListenIntervalB) == 0) { - } -#endif - ar6k_send_asleep_event_to_app(ar, false); - AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Resume WoW successfully\n")); - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("WoW does not invoked. skip resume")); - } - ar->arWlanPowerState = WLAN_POWER_STATE_ON; -} - -static void ar6000_wow_suspend(struct ar6_softc *ar) -{ -#define WOW_LIST_ID 1 - if (ar->arNetworkType != AP_NETWORK) { - /* Setup WoW for unicast & Arp request for our own IP - disable background scan. Set listen interval into 1000 TUs - Enable keepliave for 110 seconds - */ - struct in_ifaddr **ifap = NULL; - struct in_ifaddr *ifa = NULL; - struct in_device *in_dev; - u8 macMask[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - int status; - WMI_ADD_WOW_PATTERN_CMD addWowCmd = { .filter = { 0 } }; - WMI_DEL_WOW_PATTERN_CMD delWowCmd; - WMI_SET_HOST_SLEEP_MODE_CMD hostSleepMode = {false, true}; - WMI_SET_WOW_MODE_CMD wowMode = { .enable_wow = true, - .hostReqDelay = 500 };/*500 ms delay*/ - - if (ar->arWowState!= WLAN_WOW_STATE_NONE) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("System already go into wow mode!\n")); - return; - } - - ar6000_TxDataCleanup(ar); /* IMPORTANT, otherwise there will be 11mA after listen interval as 1000*/ - -#if WOW_ENABLE_MAX_INTERVAL /* we don't do it if the power consumption is already good enough. */ - if (wmi_listeninterval_cmd(ar->arWmi, A_MAX_WOW_LISTEN_INTERVAL, 0) == 0) { - } -#endif - -#if WOW_SET_SCAN_PARAMS - status = wmi_scanparams_cmd(ar->arWmi, 0xFFFF, 0, 0xFFFF, 0, 0, 0, 0, 0, 0, 0); -#endif - /* clear up our WoW pattern first */ - delWowCmd.filter_list_id = WOW_LIST_ID; - delWowCmd.filter_id = 0; - wmi_del_wow_pattern_cmd(ar->arWmi, &delWowCmd); - - /* setup unicast packet pattern for WoW */ - if (ar->arNetDev->dev_addr[1]) { - addWowCmd.filter_list_id = WOW_LIST_ID; - addWowCmd.filter_size = 6; /* MAC address */ - addWowCmd.filter_offset = 0; - status = wmi_add_wow_pattern_cmd(ar->arWmi, &addWowCmd, ar->arNetDev->dev_addr, macMask, addWowCmd.filter_size); - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to add WoW pattern\n")); - } - } - /* setup ARP request for our own IP */ - if ((in_dev = __in_dev_get_rtnl(ar->arNetDev)) != NULL) { - for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; ifap = &ifa->ifa_next) { - if (!strcmp(ar->arNetDev->name, ifa->ifa_label)) { - break; /* found */ - } - } - } - if (ifa && ifa->ifa_local) { - WMI_SET_IP_CMD ipCmd; - memset(&ipCmd, 0, sizeof(ipCmd)); - ipCmd.ips[0] = ifa->ifa_local; - status = wmi_set_ip_cmd(ar->arWmi, &ipCmd); - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to setup IP for ARP agent\n")); - } - } - -#ifndef ATH6K_CONFIG_OTA_MODE - wmi_powermode_cmd(ar->arWmi, REC_POWER); -#endif - - status = wmi_set_wow_mode_cmd(ar->arWmi, &wowMode); - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to enable wow mode\n")); - } - ar6k_send_asleep_event_to_app(ar, true); - - status = wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode); - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to set host asleep\n")); - } - - ar->arWowState = WLAN_WOW_STATE_SUSPENDING; - if (ar->arTxPending[ar->arControlEp]) { - u32 timeleft = wait_event_interruptible_timeout(arEvent, - ar->arTxPending[ar->arControlEp] == 0, wmitimeout * HZ); - if (!timeleft || signal_pending(current)) { - /* what can I do? wow resume at once */ - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to setup WoW. Pending wmi control data %d\n", ar->arTxPending[ar->arControlEp])); - } - } - - status = hifWaitForPendingRecv(ar->arHifDevice); - - ar->arWowState = WLAN_WOW_STATE_SUSPENDED; - ar->arWlanPowerState = WLAN_POWER_STATE_WOW; - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Not allowed to go to WOW at this moment.\n")); - } -} - -int ar6000_suspend_ev(void *context) -{ - int status = 0; - struct ar6_softc *ar = (struct ar6_softc *)context; - s16 pmmode = ar->arSuspendConfig; -wow_not_connected: - switch (pmmode) { - case WLAN_SUSPEND_WOW: - if (ar->arWmiReady && ar->arWlanState==WLAN_ENABLED && ar->arConnected) { - ar6000_wow_suspend(ar); - AR_DEBUG_PRINTF(ATH_DEBUG_PM,("%s:Suspend for wow mode %d\n", __func__, ar->arWlanPowerState)); - } else { - pmmode = ar->arWow2Config; - goto wow_not_connected; - } - break; - case WLAN_SUSPEND_CUT_PWR: - /* fall through */ - case WLAN_SUSPEND_CUT_PWR_IF_BT_OFF: - /* fall through */ - case WLAN_SUSPEND_DEEP_SLEEP: - /* fall through */ - default: - status = ar6000_update_wlan_pwr_state(ar, WLAN_DISABLED, true); - if (ar->arWlanPowerState==WLAN_POWER_STATE_ON || - ar->arWlanPowerState==WLAN_POWER_STATE_WOW) { - AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Strange suspend state for not wow mode %d", ar->arWlanPowerState)); - } - AR_DEBUG_PRINTF(ATH_DEBUG_PM,("%s:Suspend for %d mode pwr %d status %d\n", __func__, pmmode, ar->arWlanPowerState, status)); - status = (ar->arWlanPowerState == WLAN_POWER_STATE_CUT_PWR) ? 0 : A_EBUSY; - break; - } - - ar->scan_triggered = 0; - return status; -} - -int ar6000_resume_ev(void *context) -{ - struct ar6_softc *ar = (struct ar6_softc *)context; - u16 powerState = ar->arWlanPowerState; - - AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: enter previous state %d wowState %d\n", __func__, powerState, ar->arWowState)); - switch (powerState) { - case WLAN_POWER_STATE_WOW: - ar6000_wow_resume(ar); - break; - case WLAN_POWER_STATE_CUT_PWR: - /* fall through */ - case WLAN_POWER_STATE_DEEP_SLEEP: - ar6000_update_wlan_pwr_state(ar, WLAN_ENABLED, true); - AR_DEBUG_PRINTF(ATH_DEBUG_PM,("%s:Resume for %d mode pwr %d\n", __func__, powerState, ar->arWlanPowerState)); - break; - case WLAN_POWER_STATE_ON: - break; - default: - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Strange SDIO bus power mode!!\n")); - break; - } - return 0; -} - -void ar6000_check_wow_status(struct ar6_softc *ar, struct sk_buff *skb, bool isEvent) -{ - if (ar->arWowState!=WLAN_WOW_STATE_NONE) { - if (ar->arWowState==WLAN_WOW_STATE_SUSPENDING) { - AR_DEBUG_PRINTF(ATH_DEBUG_PM,("\n%s: Received IRQ while we are wow suspending!!!\n\n", __func__)); - return; - } - /* Wow resume from irq interrupt */ - AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: WoW resume from irq thread status %d\n", __func__, ar->arWlanPowerState)); - ar6000_wow_resume(ar); - } -} - -int ar6000_power_change_ev(void *context, u32 config) -{ - struct ar6_softc *ar = (struct ar6_softc *)context; - int status = 0; - - AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: power change event callback %d \n", __func__, config)); - switch (config) { - case HIF_DEVICE_POWER_UP: - ar6000_restart_endpoint(ar->arNetDev); - status = 0; - break; - case HIF_DEVICE_POWER_DOWN: - case HIF_DEVICE_POWER_CUT: - status = 0; - break; - } - return status; -} - -#endif /* CONFIG_PM */ - -int -ar6000_setup_cut_power_state(struct ar6_softc *ar, AR6000_WLAN_STATE state) -{ - int status = 0; - HIF_DEVICE_POWER_CHANGE_TYPE config; - - AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: Cut power %d %d \n", __func__,state, ar->arWlanPowerState)); -#ifdef CONFIG_PM - AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Wlan OFF %d BT OFf %d \n", ar->arWlanOff, ar->arBTOff)); -#endif - do { - if (state == WLAN_ENABLED) { - /* Not in cut power state.. exit */ - if (ar->arWlanPowerState != WLAN_POWER_STATE_CUT_PWR) { - break; - } - - /* Change the state to ON */ - ar->arWlanPowerState = WLAN_POWER_STATE_ON; - - - /* Indicate POWER_UP to HIF */ - config = HIF_DEVICE_POWER_UP; - status = HIFConfigureDevice(ar->arHifDevice, - HIF_DEVICE_POWER_STATE_CHANGE, - &config, - sizeof(HIF_DEVICE_POWER_CHANGE_TYPE)); - - if (status == A_PENDING) { - } else if (status == 0) { - ar6000_restart_endpoint(ar->arNetDev); - status = 0; - } - } else if (state == WLAN_DISABLED) { - - - /* Already in cut power state.. exit */ - if (ar->arWlanPowerState == WLAN_POWER_STATE_CUT_PWR) { - break; - } - ar6000_stop_endpoint(ar->arNetDev, true, false); - - config = HIF_DEVICE_POWER_CUT; - status = HIFConfigureDevice(ar->arHifDevice, - HIF_DEVICE_POWER_STATE_CHANGE, - &config, - sizeof(HIF_DEVICE_POWER_CHANGE_TYPE)); - - ar->arWlanPowerState = WLAN_POWER_STATE_CUT_PWR; - } - } while (0); - - return status; -} - -int -ar6000_setup_deep_sleep_state(struct ar6_softc *ar, AR6000_WLAN_STATE state) -{ - int status = 0; - - AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("%s: Deep sleep %d %d \n", __func__,state, ar->arWlanPowerState)); -#ifdef CONFIG_PM - AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Wlan OFF %d BT OFf %d \n", ar->arWlanOff, ar->arBTOff)); -#endif - do { - WMI_SET_HOST_SLEEP_MODE_CMD hostSleepMode; - - if (state == WLAN_ENABLED) { - u16 fg_start_period; - - /* Not in deep sleep state.. exit */ - if (ar->arWlanPowerState != WLAN_POWER_STATE_DEEP_SLEEP) { - if (ar->arWlanPowerState != WLAN_POWER_STATE_ON) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Strange state when we resume from deep sleep %d\n", ar->arWlanPowerState)); - } - break; - } - - fg_start_period = (ar->scParams.fg_start_period==0) ? 1 : ar->scParams.fg_start_period; - hostSleepMode.awake = true; - hostSleepMode.asleep = false; - - if ((status=wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode)) != 0) { - break; - } - - /* Change the state to ON */ - ar->arWlanPowerState = WLAN_POWER_STATE_ON; - - /* Enable foreground scanning */ - if ((status=wmi_scanparams_cmd(ar->arWmi, fg_start_period, - ar->scParams.fg_end_period, - ar->scParams.bg_period, - ar->scParams.minact_chdwell_time, - ar->scParams.maxact_chdwell_time, - ar->scParams.pas_chdwell_time, - ar->scParams.shortScanRatio, - ar->scParams.scanCtrlFlags, - ar->scParams.max_dfsch_act_time, - ar->scParams.maxact_scan_per_ssid)) != 0) - { - break; - } - - if (ar->arNetworkType != AP_NETWORK) - { - if (ar->arSsidLen) { - if (ar6000_connect_to_ap(ar) != 0) { - /* no need to report error if connection failed */ - break; - } - } - } - } else if (state == WLAN_DISABLED){ - WMI_SET_WOW_MODE_CMD wowMode = { .enable_wow = false }; - - /* Already in deep sleep state.. exit */ - if (ar->arWlanPowerState != WLAN_POWER_STATE_ON) { - if (ar->arWlanPowerState != WLAN_POWER_STATE_DEEP_SLEEP) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Strange state when we suspend for deep sleep %d\n", ar->arWlanPowerState)); - } - break; - } - - if (ar->arNetworkType != AP_NETWORK) - { - /* Disconnect from the AP and disable foreground scanning */ - AR6000_SPIN_LOCK(&ar->arLock, 0); - if (ar->arConnected == true || ar->arConnectPending == true) { - AR6000_SPIN_UNLOCK(&ar->arLock, 0); - wmi_disconnect_cmd(ar->arWmi); - } else { - AR6000_SPIN_UNLOCK(&ar->arLock, 0); - } - } - - ar->scan_triggered = 0; - - if ((status=wmi_scanparams_cmd(ar->arWmi, 0xFFFF, 0, 0, 0, 0, 0, 0, 0, 0, 0)) != 0) { - break; - } - - /* make sure we disable wow for deep sleep */ - if ((status=wmi_set_wow_mode_cmd(ar->arWmi, &wowMode))!= 0) - { - break; - } - - ar6000_TxDataCleanup(ar); -#ifndef ATH6K_CONFIG_OTA_MODE - wmi_powermode_cmd(ar->arWmi, REC_POWER); -#endif - - hostSleepMode.awake = false; - hostSleepMode.asleep = true; - if ((status=wmi_set_host_sleep_mode_cmd(ar->arWmi, &hostSleepMode))!= 0) { - break; - } - if (ar->arTxPending[ar->arControlEp]) { - u32 timeleft = wait_event_interruptible_timeout(arEvent, - ar->arTxPending[ar->arControlEp] == 0, wmitimeout * HZ); - if (!timeleft || signal_pending(current)) { - status = A_ERROR; - break; - } - } - status = hifWaitForPendingRecv(ar->arHifDevice); - - ar->arWlanPowerState = WLAN_POWER_STATE_DEEP_SLEEP; - } - } while (0); - - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to enter/exit deep sleep %d\n", state)); - } - - return status; -} - -int -ar6000_update_wlan_pwr_state(struct ar6_softc *ar, AR6000_WLAN_STATE state, bool pmEvent) -{ - int status = 0; - u16 powerState, oldPowerState; - AR6000_WLAN_STATE oldstate = ar->arWlanState; - bool wlanOff = ar->arWlanOff; -#ifdef CONFIG_PM - bool btOff = ar->arBTOff; -#endif /* CONFIG_PM */ - - if ((state!=WLAN_DISABLED && state!=WLAN_ENABLED)) { - return A_ERROR; - } - - if (ar->bIsDestroyProgress) { - return A_EBUSY; - } - - if (down_interruptible(&ar->arSem)) { - return A_ERROR; - } - - if (ar->bIsDestroyProgress) { - up(&ar->arSem); - return A_EBUSY; - } - - ar->arWlanState = wlanOff ? WLAN_DISABLED : state; - oldPowerState = ar->arWlanPowerState; - if (state == WLAN_ENABLED) { - powerState = ar->arWlanPowerState; - AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("WLAN PWR set to ENABLE^^\n")); - if (!wlanOff) { - if (powerState == WLAN_POWER_STATE_DEEP_SLEEP) { - status = ar6000_setup_deep_sleep_state(ar, WLAN_ENABLED); - } else if (powerState == WLAN_POWER_STATE_CUT_PWR) { - status = ar6000_setup_cut_power_state(ar, WLAN_ENABLED); - } - } -#ifdef CONFIG_PM - else if (pmEvent && wlanOff) { - bool allowCutPwr = ((!ar->arBTSharing) || btOff); - if ((powerState==WLAN_POWER_STATE_CUT_PWR) && (!allowCutPwr)) { - /* Come out of cut power */ - ar6000_setup_cut_power_state(ar, WLAN_ENABLED); - status = ar6000_setup_deep_sleep_state(ar, WLAN_DISABLED); - } - } -#endif /* CONFIG_PM */ - } else if (state == WLAN_DISABLED) { - AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("WLAN PWR set to DISABLED~\n")); - powerState = WLAN_POWER_STATE_DEEP_SLEEP; -#ifdef CONFIG_PM - if (pmEvent) { /* disable due to suspend */ - bool suspendCutPwr = (ar->arSuspendConfig == WLAN_SUSPEND_CUT_PWR || - (ar->arSuspendConfig == WLAN_SUSPEND_WOW && - ar->arWow2Config==WLAN_SUSPEND_CUT_PWR)); - bool suspendCutIfBtOff = ((ar->arSuspendConfig == - WLAN_SUSPEND_CUT_PWR_IF_BT_OFF || - (ar->arSuspendConfig == WLAN_SUSPEND_WOW && - ar->arWow2Config==WLAN_SUSPEND_CUT_PWR_IF_BT_OFF)) && - (!ar->arBTSharing || btOff)); - if ((suspendCutPwr) || - (suspendCutIfBtOff) || - (ar->arWlanState==WLAN_POWER_STATE_CUT_PWR)) - { - powerState = WLAN_POWER_STATE_CUT_PWR; - } - } else { - if ((wlanOff) && - (ar->arWlanOffConfig == WLAN_OFF_CUT_PWR) && - (!ar->arBTSharing || btOff)) - { - /* For BT clock sharing designs, CUT_POWER depend on BT state */ - powerState = WLAN_POWER_STATE_CUT_PWR; - } - } -#endif /* CONFIG_PM */ - - if (powerState == WLAN_POWER_STATE_DEEP_SLEEP) { - if (ar->arWlanPowerState == WLAN_POWER_STATE_CUT_PWR) { - AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("Load firmware before set to deep sleep\n")); - ar6000_setup_cut_power_state(ar, WLAN_ENABLED); - } - status = ar6000_setup_deep_sleep_state(ar, WLAN_DISABLED); - } else if (powerState == WLAN_POWER_STATE_CUT_PWR) { - status = ar6000_setup_cut_power_state(ar, WLAN_DISABLED); - } - - } - - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Fail to setup WLAN state %d\n", ar->arWlanState)); - ar->arWlanState = oldstate; - } else if (status == 0) { - WMI_REPORT_SLEEP_STATE_EVENT wmiSleepEvent, *pSleepEvent = NULL; - if ((ar->arWlanPowerState == WLAN_POWER_STATE_ON) && (oldPowerState != WLAN_POWER_STATE_ON)) { - wmiSleepEvent.sleepState = WMI_REPORT_SLEEP_STATUS_IS_AWAKE; - pSleepEvent = &wmiSleepEvent; - } else if ((ar->arWlanPowerState != WLAN_POWER_STATE_ON) && (oldPowerState == WLAN_POWER_STATE_ON)) { - wmiSleepEvent.sleepState = WMI_REPORT_SLEEP_STATUS_IS_DEEP_SLEEP; - pSleepEvent = &wmiSleepEvent; - } - if (pSleepEvent) { - AR_DEBUG_PRINTF(ATH_DEBUG_PM, ("SENT WLAN Sleep Event %d\n", wmiSleepEvent.sleepState)); - } - } - up(&ar->arSem); - return status; -} - -int -ar6000_set_bt_hw_state(struct ar6_softc *ar, u32 enable) -{ -#ifdef CONFIG_PM - bool off = (enable == 0); - int status; - if (ar->arBTOff == off) { - return 0; - } - ar->arBTOff = off; - status = ar6000_update_wlan_pwr_state(ar, ar->arWlanOff ? WLAN_DISABLED : WLAN_ENABLED, false); - return status; -#else - return 0; -#endif -} - -int -ar6000_set_wlan_state(struct ar6_softc *ar, AR6000_WLAN_STATE state) -{ - int status; - bool off = (state == WLAN_DISABLED); - if (ar->arWlanOff == off) { - return 0; - } - ar->arWlanOff = off; - status = ar6000_update_wlan_pwr_state(ar, state, false); - return status; -} diff --git a/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c b/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c deleted file mode 100644 index ae7c1dd..0000000 --- a/drivers/staging/ath6kl/os/linux/ar6000_raw_if.c +++ /dev/null @@ -1,455 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2004-2010 Atheros Communications Inc. -// All rights reserved. -// -// -// -// 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. -// -// -// -// Author(s): ="Atheros" -//------------------------------------------------------------------------------ - -#include "ar6000_drv.h" - -#ifdef HTC_RAW_INTERFACE - -static void -ar6000_htc_raw_read_cb(void *Context, struct htc_packet *pPacket) -{ - struct ar6_softc *ar = (struct ar6_softc *)Context; - raw_htc_buffer *busy; - HTC_RAW_STREAM_ID streamID; - AR_RAW_HTC_T *arRaw = ar->arRawHtc; - - busy = (raw_htc_buffer *)pPacket->pPktContext; - A_ASSERT(busy != NULL); - - if (pPacket->Status == A_ECANCELED) { - /* - * HTC provides A_ECANCELED status when it doesn't want to be refilled - * (probably due to a shutdown) - */ - return; - } - - streamID = arEndpoint2RawStreamID(ar,pPacket->Endpoint); - A_ASSERT(streamID != HTC_RAW_STREAM_NOT_MAPPED); - -#ifdef CF - if (down_trylock(&arRaw->raw_htc_read_sem[streamID])) { -#else - if (down_interruptible(&arRaw->raw_htc_read_sem[streamID])) { -#endif /* CF */ - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to down the semaphore\n")); - } - - A_ASSERT((pPacket->Status != 0) || - (pPacket->pBuffer == (busy->data + HTC_HEADER_LEN))); - - busy->length = pPacket->ActualLength + HTC_HEADER_LEN; - busy->currPtr = HTC_HEADER_LEN; - arRaw->read_buffer_available[streamID] = true; - //AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("raw read cb: 0x%X 0x%X \n", busy->currPtr,busy->length); - up(&arRaw->raw_htc_read_sem[streamID]); - - /* Signal the waiting process */ - AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("Waking up the StreamID(%d) read process\n", streamID)); - wake_up_interruptible(&arRaw->raw_htc_read_queue[streamID]); -} - -static void -ar6000_htc_raw_write_cb(void *Context, struct htc_packet *pPacket) -{ - struct ar6_softc *ar = (struct ar6_softc *)Context; - raw_htc_buffer *free; - HTC_RAW_STREAM_ID streamID; - AR_RAW_HTC_T *arRaw = ar->arRawHtc; - - free = (raw_htc_buffer *)pPacket->pPktContext; - A_ASSERT(free != NULL); - - if (pPacket->Status == A_ECANCELED) { - /* - * HTC provides A_ECANCELED status when it doesn't want to be refilled - * (probably due to a shutdown) - */ - return; - } - - streamID = arEndpoint2RawStreamID(ar,pPacket->Endpoint); - A_ASSERT(streamID != HTC_RAW_STREAM_NOT_MAPPED); - -#ifdef CF - if (down_trylock(&arRaw->raw_htc_write_sem[streamID])) { -#else - if (down_interruptible(&arRaw->raw_htc_write_sem[streamID])) { -#endif - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Unable to down the semaphore\n")); - } - - A_ASSERT(pPacket->pBuffer == (free->data + HTC_HEADER_LEN)); - - free->length = 0; - arRaw->write_buffer_available[streamID] = true; - up(&arRaw->raw_htc_write_sem[streamID]); - - /* Signal the waiting process */ - AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("Waking up the StreamID(%d) write process\n", streamID)); - wake_up_interruptible(&arRaw->raw_htc_write_queue[streamID]); -} - -/* connect to a service */ -static int ar6000_connect_raw_service(struct ar6_softc *ar, - HTC_RAW_STREAM_ID StreamID) -{ - int status; - struct htc_service_connect_resp response; - u8 streamNo; - struct htc_service_connect_req connect; - - do { - - A_MEMZERO(&connect,sizeof(connect)); - /* pass the stream ID as meta data to the RAW streams service */ - streamNo = (u8)StreamID; - connect.pMetaData = &streamNo; - connect.MetaDataLength = sizeof(u8); - /* these fields are the same for all endpoints */ - connect.EpCallbacks.pContext = ar; - connect.EpCallbacks.EpTxComplete = ar6000_htc_raw_write_cb; - connect.EpCallbacks.EpRecv = ar6000_htc_raw_read_cb; - /* simple interface, we don't need these optional callbacks */ - connect.EpCallbacks.EpRecvRefill = NULL; - connect.EpCallbacks.EpSendFull = NULL; - connect.MaxSendQueueDepth = RAW_HTC_WRITE_BUFFERS_NUM; - - /* connect to the raw streams service, we may be able to get 1 or more - * connections, depending on WHAT is running on the target */ - connect.ServiceID = HTC_RAW_STREAMS_SVC; - - A_MEMZERO(&response,sizeof(response)); - - /* try to connect to the raw stream, it is okay if this fails with - * status HTC_SERVICE_NO_MORE_EP */ - status = HTCConnectService(ar->arHtcTarget, - &connect, - &response); - - if (status) { - if (response.ConnectRespCode == HTC_SERVICE_NO_MORE_EP) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HTC RAW , No more streams allowed \n")); - status = 0; - } - break; - } - - /* set endpoint mapping for the RAW HTC streams */ - arSetRawStream2EndpointIDMap(ar,StreamID,response.Endpoint); - - AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("HTC RAW : stream ID: %d, endpoint: %d\n", - StreamID, arRawStream2EndpointID(ar,StreamID))); - - } while (false); - - return status; -} - -int ar6000_htc_raw_open(struct ar6_softc *ar) -{ - int status; - int streamID, endPt, count2; - raw_htc_buffer *buffer; - HTC_SERVICE_ID servicepriority; - AR_RAW_HTC_T *arRaw = ar->arRawHtc; - if (!arRaw) { - arRaw = ar->arRawHtc = A_MALLOC(sizeof(AR_RAW_HTC_T)); - if (arRaw) { - A_MEMZERO(arRaw, sizeof(AR_RAW_HTC_T)); - } - } - A_ASSERT(ar->arHtcTarget != NULL); - if (!arRaw) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Faile to allocate memory for HTC RAW interface\n")); - return -ENOMEM; - } - /* wait for target */ - status = HTCWaitTarget(ar->arHtcTarget); - - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("HTCWaitTarget failed (%d)\n", status)); - return -ENODEV; - } - - for (endPt = 0; endPt < ENDPOINT_MAX; endPt++) { - arRaw->arEp2RawMapping[endPt] = HTC_RAW_STREAM_NOT_MAPPED; - } - - for (streamID = HTC_RAW_STREAM_0; streamID < HTC_RAW_STREAM_NUM_MAX; streamID++) { - /* Initialize the data structures */ - sema_init(&arRaw->raw_htc_read_sem[streamID], 1); - sema_init(&arRaw->raw_htc_write_sem[streamID], 1); - init_waitqueue_head(&arRaw->raw_htc_read_queue[streamID]); - init_waitqueue_head(&arRaw->raw_htc_write_queue[streamID]); - - /* try to connect to the raw service */ - status = ar6000_connect_raw_service(ar,streamID); - - if (status) { - break; - } - - if (arRawStream2EndpointID(ar,streamID) == 0) { - break; - } - - for (count2 = 0; count2 < RAW_HTC_READ_BUFFERS_NUM; count2 ++) { - /* Initialize the receive buffers */ - buffer = &arRaw->raw_htc_write_buffer[streamID][count2]; - memset(buffer, 0, sizeof(raw_htc_buffer)); - buffer = &arRaw->raw_htc_read_buffer[streamID][count2]; - memset(buffer, 0, sizeof(raw_htc_buffer)); - - SET_HTC_PACKET_INFO_RX_REFILL(&buffer->HTCPacket, - buffer, - buffer->data, - HTC_RAW_BUFFER_SIZE, - arRawStream2EndpointID(ar,streamID)); - - /* Queue buffers to HTC for receive */ - if ((status = HTCAddReceivePkt(ar->arHtcTarget, &buffer->HTCPacket)) != 0) - { - BMIInit(); - return -EIO; - } - } - - for (count2 = 0; count2 < RAW_HTC_WRITE_BUFFERS_NUM; count2 ++) { - /* Initialize the receive buffers */ - buffer = &arRaw->raw_htc_write_buffer[streamID][count2]; - memset(buffer, 0, sizeof(raw_htc_buffer)); - } - - arRaw->read_buffer_available[streamID] = false; - arRaw->write_buffer_available[streamID] = true; - } - - if (status) { - return -EIO; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("HTC RAW, number of streams the target supports: %d \n", streamID)); - - servicepriority = HTC_RAW_STREAMS_SVC; /* only 1 */ - - /* set callbacks and priority list */ - HTCSetCreditDistribution(ar->arHtcTarget, - ar, - NULL, /* use default */ - NULL, /* use default */ - &servicepriority, - 1); - - /* Start the HTC component */ - if ((status = HTCStart(ar->arHtcTarget)) != 0) { - BMIInit(); - return -EIO; - } - - (ar)->arRawIfInit = true; - - return 0; -} - -int ar6000_htc_raw_close(struct ar6_softc *ar) -{ - A_PRINTF("ar6000_htc_raw_close called \n"); - HTCStop(ar->arHtcTarget); - - /* reset the device */ - ar6000_reset_device(ar->arHifDevice, ar->arTargetType, true, false); - /* Initialize the BMI component */ - BMIInit(); - - return 0; -} - -raw_htc_buffer * -get_filled_buffer(struct ar6_softc *ar, HTC_RAW_STREAM_ID StreamID) -{ - int count; - raw_htc_buffer *busy; - AR_RAW_HTC_T *arRaw = ar->arRawHtc; - - /* Check for data */ - for (count = 0; count < RAW_HTC_READ_BUFFERS_NUM; count ++) { - busy = &arRaw->raw_htc_read_buffer[StreamID][count]; - if (busy->length) { - break; - } - } - if (busy->length) { - arRaw->read_buffer_available[StreamID] = true; - } else { - arRaw->read_buffer_available[StreamID] = false; - } - - return busy; -} - -ssize_t ar6000_htc_raw_read(struct ar6_softc *ar, HTC_RAW_STREAM_ID StreamID, - char __user *buffer, size_t length) -{ - int readPtr; - raw_htc_buffer *busy; - AR_RAW_HTC_T *arRaw = ar->arRawHtc; - - if (arRawStream2EndpointID(ar,StreamID) == 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("StreamID(%d) not connected! \n", StreamID)); - return -EFAULT; - } - - if (down_interruptible(&arRaw->raw_htc_read_sem[StreamID])) { - return -ERESTARTSYS; - } - - busy = get_filled_buffer(ar,StreamID); - while (!arRaw->read_buffer_available[StreamID]) { - up(&arRaw->raw_htc_read_sem[StreamID]); - - /* Wait for the data */ - AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("Sleeping StreamID(%d) read process\n", StreamID)); - if (wait_event_interruptible(arRaw->raw_htc_read_queue[StreamID], - arRaw->read_buffer_available[StreamID])) - { - return -EINTR; - } - if (down_interruptible(&arRaw->raw_htc_read_sem[StreamID])) { - return -ERESTARTSYS; - } - busy = get_filled_buffer(ar,StreamID); - } - - /* Read the data */ - readPtr = busy->currPtr; - if (length > busy->length - HTC_HEADER_LEN) { - length = busy->length - HTC_HEADER_LEN; - } - if (copy_to_user(buffer, &busy->data[readPtr], length)) { - up(&arRaw->raw_htc_read_sem[StreamID]); - return -EFAULT; - } - - busy->currPtr += length; - - if (busy->currPtr == busy->length) - { - busy->currPtr = 0; - busy->length = 0; - HTC_PACKET_RESET_RX(&busy->HTCPacket); - //AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("raw read ioctl: ep for packet:%d \n", busy->HTCPacket.Endpoint)); - HTCAddReceivePkt(ar->arHtcTarget, &busy->HTCPacket); - } - arRaw->read_buffer_available[StreamID] = false; - up(&arRaw->raw_htc_read_sem[StreamID]); - - return length; -} - -static raw_htc_buffer * -get_free_buffer(struct ar6_softc *ar, HTC_ENDPOINT_ID StreamID) -{ - int count; - raw_htc_buffer *free; - AR_RAW_HTC_T *arRaw = ar->arRawHtc; - - free = NULL; - for (count = 0; count < RAW_HTC_WRITE_BUFFERS_NUM; count ++) { - free = &arRaw->raw_htc_write_buffer[StreamID][count]; - if (free->length == 0) { - break; - } - } - if (!free->length) { - arRaw->write_buffer_available[StreamID] = true; - } else { - arRaw->write_buffer_available[StreamID] = false; - } - - return free; -} - -ssize_t ar6000_htc_raw_write(struct ar6_softc *ar, HTC_RAW_STREAM_ID StreamID, - char __user *buffer, size_t length) -{ - int writePtr; - raw_htc_buffer *free; - AR_RAW_HTC_T *arRaw = ar->arRawHtc; - if (arRawStream2EndpointID(ar,StreamID) == 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("StreamID(%d) not connected! \n", StreamID)); - return -EFAULT; - } - - if (down_interruptible(&arRaw->raw_htc_write_sem[StreamID])) { - return -ERESTARTSYS; - } - - /* Search for a free buffer */ - free = get_free_buffer(ar,StreamID); - - /* Check if there is space to write else wait */ - while (!arRaw->write_buffer_available[StreamID]) { - up(&arRaw->raw_htc_write_sem[StreamID]); - - /* Wait for buffer to become free */ - AR_DEBUG_PRINTF(ATH_DEBUG_HTC_RAW,("Sleeping StreamID(%d) write process\n", StreamID)); - if (wait_event_interruptible(arRaw->raw_htc_write_queue[StreamID], - arRaw->write_buffer_available[StreamID])) - { - return -EINTR; - } - if (down_interruptible(&arRaw->raw_htc_write_sem[StreamID])) { - return -ERESTARTSYS; - } - free = get_free_buffer(ar,StreamID); - } - - /* Send the data */ - writePtr = HTC_HEADER_LEN; - if (length > (HTC_RAW_BUFFER_SIZE - HTC_HEADER_LEN)) { - length = HTC_RAW_BUFFER_SIZE - HTC_HEADER_LEN; - } - - if (copy_from_user(&free->data[writePtr], buffer, length)) { - up(&arRaw->raw_htc_read_sem[StreamID]); - return -EFAULT; - } - - free->length = length; - - SET_HTC_PACKET_INFO_TX(&free->HTCPacket, - free, - &free->data[writePtr], - length, - arRawStream2EndpointID(ar,StreamID), - AR6K_DATA_PKT_TAG); - - HTCSendPkt(ar->arHtcTarget,&free->HTCPacket); - - arRaw->write_buffer_available[StreamID] = false; - up(&arRaw->raw_htc_write_sem[StreamID]); - - return length; -} -#endif /* HTC_RAW_INTERFACE */ diff --git a/drivers/staging/ath6kl/os/linux/cfg80211.c b/drivers/staging/ath6kl/os/linux/cfg80211.c deleted file mode 100644 index 5fdda4a..0000000 --- a/drivers/staging/ath6kl/os/linux/cfg80211.c +++ /dev/null @@ -1,1892 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2004-2010 Atheros Communications Inc. -// All rights reserved. -// -// -// -// 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. -// -// -// -// Author(s): ="Atheros" -//------------------------------------------------------------------------------ - -#include <linux/wireless.h> -#include <linux/ieee80211.h> -#include <net/cfg80211.h> -#include <net/netlink.h> - -#include "ar6000_drv.h" - - -extern A_WAITQUEUE_HEAD arEvent; -extern unsigned int wmitimeout; -extern int reconnect_flag; - - -#define RATETAB_ENT(_rate, _rateid, _flags) { \ - .bitrate = (_rate), \ - .flags = (_flags), \ - .hw_value = (_rateid), \ -} - -#define CHAN2G(_channel, _freq, _flags) { \ - .band = IEEE80211_BAND_2GHZ, \ - .hw_value = (_channel), \ - .center_freq = (_freq), \ - .flags = (_flags), \ - .max_antenna_gain = 0, \ - .max_power = 30, \ -} - -#define CHAN5G(_channel, _flags) { \ - .band = IEEE80211_BAND_5GHZ, \ - .hw_value = (_channel), \ - .center_freq = 5000 + (5 * (_channel)), \ - .flags = (_flags), \ - .max_antenna_gain = 0, \ - .max_power = 30, \ -} - -static struct -ieee80211_rate ar6k_rates[] = { - RATETAB_ENT(10, 0x1, 0), - RATETAB_ENT(20, 0x2, 0), - RATETAB_ENT(55, 0x4, 0), - RATETAB_ENT(110, 0x8, 0), - RATETAB_ENT(60, 0x10, 0), - RATETAB_ENT(90, 0x20, 0), - RATETAB_ENT(120, 0x40, 0), - RATETAB_ENT(180, 0x80, 0), - RATETAB_ENT(240, 0x100, 0), - RATETAB_ENT(360, 0x200, 0), - RATETAB_ENT(480, 0x400, 0), - RATETAB_ENT(540, 0x800, 0), -}; - -#define ar6k_a_rates (ar6k_rates + 4) -#define ar6k_a_rates_size 8 -#define ar6k_g_rates (ar6k_rates + 0) -#define ar6k_g_rates_size 12 - -static struct -ieee80211_channel ar6k_2ghz_channels[] = { - CHAN2G(1, 2412, 0), - CHAN2G(2, 2417, 0), - CHAN2G(3, 2422, 0), - CHAN2G(4, 2427, 0), - CHAN2G(5, 2432, 0), - CHAN2G(6, 2437, 0), - CHAN2G(7, 2442, 0), - CHAN2G(8, 2447, 0), - CHAN2G(9, 2452, 0), - CHAN2G(10, 2457, 0), - CHAN2G(11, 2462, 0), - CHAN2G(12, 2467, 0), - CHAN2G(13, 2472, 0), - CHAN2G(14, 2484, 0), -}; - -static struct -ieee80211_channel ar6k_5ghz_a_channels[] = { - CHAN5G(34, 0), CHAN5G(36, 0), - CHAN5G(38, 0), CHAN5G(40, 0), - CHAN5G(42, 0), CHAN5G(44, 0), - CHAN5G(46, 0), CHAN5G(48, 0), - CHAN5G(52, 0), CHAN5G(56, 0), - CHAN5G(60, 0), CHAN5G(64, 0), - CHAN5G(100, 0), CHAN5G(104, 0), - CHAN5G(108, 0), CHAN5G(112, 0), - CHAN5G(116, 0), CHAN5G(120, 0), - CHAN5G(124, 0), CHAN5G(128, 0), - CHAN5G(132, 0), CHAN5G(136, 0), - CHAN5G(140, 0), CHAN5G(149, 0), - CHAN5G(153, 0), CHAN5G(157, 0), - CHAN5G(161, 0), CHAN5G(165, 0), - CHAN5G(184, 0), CHAN5G(188, 0), - CHAN5G(192, 0), CHAN5G(196, 0), - CHAN5G(200, 0), CHAN5G(204, 0), - CHAN5G(208, 0), CHAN5G(212, 0), - CHAN5G(216, 0), -}; - -static struct -ieee80211_supported_band ar6k_band_2ghz = { - .n_channels = ARRAY_SIZE(ar6k_2ghz_channels), - .channels = ar6k_2ghz_channels, - .n_bitrates = ar6k_g_rates_size, - .bitrates = ar6k_g_rates, -}; - -static struct -ieee80211_supported_band ar6k_band_5ghz = { - .n_channels = ARRAY_SIZE(ar6k_5ghz_a_channels), - .channels = ar6k_5ghz_a_channels, - .n_bitrates = ar6k_a_rates_size, - .bitrates = ar6k_a_rates, -}; - -static int -ar6k_set_wpa_version(struct ar6_softc *ar, enum nl80211_wpa_versions wpa_version) -{ - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: %u\n", __func__, wpa_version)); - - if (!wpa_version) { - ar->arAuthMode = NONE_AUTH; - } else if (wpa_version & NL80211_WPA_VERSION_1) { - ar->arAuthMode = WPA_AUTH; - } else if (wpa_version & NL80211_WPA_VERSION_2) { - ar->arAuthMode = WPA2_AUTH; - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("%s: %u not spported\n", __func__, wpa_version)); - return -ENOTSUPP; - } - - return 0; -} - -static int -ar6k_set_auth_type(struct ar6_softc *ar, enum nl80211_auth_type auth_type) -{ - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: 0x%x\n", __func__, auth_type)); - - switch (auth_type) { - case NL80211_AUTHTYPE_OPEN_SYSTEM: - ar->arDot11AuthMode = OPEN_AUTH; - break; - case NL80211_AUTHTYPE_SHARED_KEY: - ar->arDot11AuthMode = SHARED_AUTH; - break; - case NL80211_AUTHTYPE_NETWORK_EAP: - ar->arDot11AuthMode = LEAP_AUTH; - break; - - case NL80211_AUTHTYPE_AUTOMATIC: - ar->arDot11AuthMode = OPEN_AUTH; - ar->arAutoAuthStage = AUTH_OPEN_IN_PROGRESS; - break; - - default: - ar->arDot11AuthMode = OPEN_AUTH; - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, - ("%s: 0x%x not spported\n", __func__, auth_type)); - return -ENOTSUPP; - } - - return 0; -} - -static int -ar6k_set_cipher(struct ar6_softc *ar, u32 cipher, bool ucast) -{ - u8 *ar_cipher = ucast ? &ar->arPairwiseCrypto : - &ar->arGroupCrypto; - u8 *ar_cipher_len = ucast ? &ar->arPairwiseCryptoLen : - &ar->arGroupCryptoLen; - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, - ("%s: cipher 0x%x, ucast %u\n", __func__, cipher, ucast)); - - switch (cipher) { - case 0: - case IW_AUTH_CIPHER_NONE: - *ar_cipher = NONE_CRYPT; - *ar_cipher_len = 0; - break; - case WLAN_CIPHER_SUITE_WEP40: - *ar_cipher = WEP_CRYPT; - *ar_cipher_len = 5; - break; - case WLAN_CIPHER_SUITE_WEP104: - *ar_cipher = WEP_CRYPT; - *ar_cipher_len = 13; - break; - case WLAN_CIPHER_SUITE_TKIP: - *ar_cipher = TKIP_CRYPT; - *ar_cipher_len = 0; - break; - case WLAN_CIPHER_SUITE_CCMP: - *ar_cipher = AES_CRYPT; - *ar_cipher_len = 0; - break; - default: - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("%s: cipher 0x%x not supported\n", __func__, cipher)); - return -ENOTSUPP; - } - - return 0; -} - -static void -ar6k_set_key_mgmt(struct ar6_softc *ar, u32 key_mgmt) -{ - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: 0x%x\n", __func__, key_mgmt)); - - if (WLAN_AKM_SUITE_PSK == key_mgmt) { - if (WPA_AUTH == ar->arAuthMode) { - ar->arAuthMode = WPA_PSK_AUTH; - } else if (WPA2_AUTH == ar->arAuthMode) { - ar->arAuthMode = WPA2_PSK_AUTH; - } - } else if (WLAN_AKM_SUITE_8021X != key_mgmt) { - ar->arAuthMode = NONE_AUTH; - } -} - -static int -ar6k_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, - struct cfg80211_connect_params *sme) -{ - struct ar6_softc *ar = ar6k_priv(dev); - int status; - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__)); - ar->smeState = SME_CONNECTING; - - if(ar->arWmiReady == false) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready yet\n", __func__)); - return -EIO; - } - - if(ar->arWlanState == WLAN_DISABLED) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__)); - return -EIO; - } - - if(ar->bIsDestroyProgress) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: destroy in progress\n", __func__)); - return -EBUSY; - } - - if(!sme->ssid_len || IEEE80211_MAX_SSID_LEN < sme->ssid_len) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ssid invalid\n", __func__)); - return -EINVAL; - } - - if(ar->arSkipScan == true && - ((sme->channel && sme->channel->center_freq == 0) || - (sme->bssid && !sme->bssid[0] && !sme->bssid[1] && !sme->bssid[2] && - !sme->bssid[3] && !sme->bssid[4] && !sme->bssid[5]))) - { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s:SkipScan: channel or bssid invalid\n", __func__)); - return -EINVAL; - } - - if(down_interruptible(&ar->arSem)) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, couldn't get access\n", __func__)); - return -ERESTARTSYS; - } - - if(ar->bIsDestroyProgress) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, destroy in progress\n", __func__)); - up(&ar->arSem); - return -EBUSY; - } - - if(ar->arTxPending[wmi_get_control_ep(ar->arWmi)]) { - /* - * sleep until the command queue drains - */ - wait_event_interruptible_timeout(arEvent, - ar->arTxPending[wmi_get_control_ep(ar->arWmi)] == 0, wmitimeout * HZ); - if (signal_pending(current)) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: cmd queue drain timeout\n", __func__)); - up(&ar->arSem); - return -EINTR; - } - } - - if(ar->arConnected == true && - ar->arSsidLen == sme->ssid_len && - !memcmp(ar->arSsid, sme->ssid, ar->arSsidLen)) { - reconnect_flag = true; - status = wmi_reconnect_cmd(ar->arWmi, - ar->arReqBssid, - ar->arChannelHint); - - up(&ar->arSem); - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_reconnect_cmd failed\n", __func__)); - return -EIO; - } - return 0; - } else if(ar->arSsidLen == sme->ssid_len && - !memcmp(ar->arSsid, sme->ssid, ar->arSsidLen)) { - ar6000_disconnect(ar); - } - - A_MEMZERO(ar->arSsid, sizeof(ar->arSsid)); - ar->arSsidLen = sme->ssid_len; - memcpy(ar->arSsid, sme->ssid, sme->ssid_len); - - if(sme->channel){ - ar->arChannelHint = sme->channel->center_freq; - } - - A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid)); - if(sme->bssid){ - if(memcmp(&sme->bssid, bcast_mac, AR6000_ETH_ADDR_LEN)) { - memcpy(ar->arReqBssid, sme->bssid, sizeof(ar->arReqBssid)); - } - } - - ar6k_set_wpa_version(ar, sme->crypto.wpa_versions); - ar6k_set_auth_type(ar, sme->auth_type); - - if(sme->crypto.n_ciphers_pairwise) { - ar6k_set_cipher(ar, sme->crypto.ciphers_pairwise[0], true); - } else { - ar6k_set_cipher(ar, IW_AUTH_CIPHER_NONE, true); - } - ar6k_set_cipher(ar, sme->crypto.cipher_group, false); - - if(sme->crypto.n_akm_suites) { - ar6k_set_key_mgmt(ar, sme->crypto.akm_suites[0]); - } - - if((sme->key_len) && - (NONE_AUTH == ar->arAuthMode) && - (WEP_CRYPT == ar->arPairwiseCrypto)) { - struct ar_key *key = NULL; - - if(sme->key_idx < WMI_MIN_KEY_INDEX || sme->key_idx > WMI_MAX_KEY_INDEX) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("%s: key index %d out of bounds\n", __func__, sme->key_idx)); - up(&ar->arSem); - return -ENOENT; - } - - key = &ar->keys[sme->key_idx]; - key->key_len = sme->key_len; - memcpy(key->key, sme->key, key->key_len); - key->cipher = ar->arPairwiseCrypto; - ar->arDefTxKeyIndex = sme->key_idx; - - wmi_addKey_cmd(ar->arWmi, sme->key_idx, - ar->arPairwiseCrypto, - GROUP_USAGE | TX_USAGE, - key->key_len, - NULL, - key->key, KEY_OP_INIT_VAL, NULL, - NO_SYNC_WMIFLAG); - } - - if (!ar->arUserBssFilter) { - if (wmi_bssfilter_cmd(ar->arWmi, ALL_BSS_FILTER, 0) != 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Couldn't set bss filtering\n", __func__)); - up(&ar->arSem); - return -EIO; - } - } - - ar->arNetworkType = ar->arNextMode; - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Connect called with authmode %d dot11 auth %d"\ - " PW crypto %d PW crypto Len %d GRP crypto %d"\ - " GRP crypto Len %d channel hint %u\n", - __func__, ar->arAuthMode, ar->arDot11AuthMode, - ar->arPairwiseCrypto, ar->arPairwiseCryptoLen, - ar->arGroupCrypto, ar->arGroupCryptoLen, ar->arChannelHint)); - - reconnect_flag = 0; - status = wmi_connect_cmd(ar->arWmi, ar->arNetworkType, - ar->arDot11AuthMode, ar->arAuthMode, - ar->arPairwiseCrypto, ar->arPairwiseCryptoLen, - ar->arGroupCrypto,ar->arGroupCryptoLen, - ar->arSsidLen, ar->arSsid, - ar->arReqBssid, ar->arChannelHint, - ar->arConnectCtrlFlags); - - up(&ar->arSem); - - if (A_EINVAL == status) { - A_MEMZERO(ar->arSsid, sizeof(ar->arSsid)); - ar->arSsidLen = 0; - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Invalid request\n", __func__)); - return -ENOENT; - } else if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_connect_cmd failed\n", __func__)); - return -EIO; - } - - if ((!(ar->arConnectCtrlFlags & CONNECT_DO_WPA_OFFLOAD)) && - ((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode))) - { - A_TIMEOUT_MS(&ar->disconnect_timer, A_DISCONNECT_TIMER_INTERVAL, 0); - } - - ar->arConnectCtrlFlags &= ~CONNECT_DO_WPA_OFFLOAD; - ar->arConnectPending = true; - - return 0; -} - -void -ar6k_cfg80211_connect_event(struct ar6_softc *ar, u16 channel, - u8 *bssid, u16 listenInterval, - u16 beaconInterval,NETWORK_TYPE networkType, - u8 beaconIeLen, u8 assocReqLen, - u8 assocRespLen, u8 *assocInfo) -{ - u16 size = 0; - u16 capability = 0; - struct cfg80211_bss *bss = NULL; - struct ieee80211_mgmt *mgmt = NULL; - struct ieee80211_channel *ibss_channel = NULL; - s32 signal = 50 * 100; - u8 ie_buf_len = 0; - unsigned char ie_buf[256]; - unsigned char *ptr_ie_buf = ie_buf; - unsigned char *ieeemgmtbuf = NULL; - u8 source_mac[ATH_MAC_LEN]; - - u8 assocReqIeOffset = sizeof(u16) + /* capinfo*/ - sizeof(u16); /* listen interval */ - u8 assocRespIeOffset = sizeof(u16) + /* capinfo*/ - sizeof(u16) + /* status Code */ - sizeof(u16); /* associd */ - u8 *assocReqIe = assocInfo + beaconIeLen + assocReqIeOffset; - u8 *assocRespIe = assocInfo + beaconIeLen + assocReqLen + assocRespIeOffset; - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__)); - - assocReqLen -= assocReqIeOffset; - assocRespLen -= assocRespIeOffset; - - ar->arAutoAuthStage = AUTH_IDLE; - - if((ADHOC_NETWORK & networkType)) { - if(NL80211_IFTYPE_ADHOC != ar->wdev->iftype) { - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, - ("%s: ath6k not in ibss mode\n", __func__)); - return; - } - } - - if((INFRA_NETWORK & networkType)) { - if(NL80211_IFTYPE_STATION != ar->wdev->iftype) { - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, - ("%s: ath6k not in station mode\n", __func__)); - return; - } - } - - /* Before informing the join/connect event, make sure that - * bss entry is present in scan list, if it not present - * construct and insert into scan list, otherwise that - * event will be dropped on the way by cfg80211, due to - * this keys will not be plumbed in case of WEP and - * application will not be aware of join/connect status. */ - bss = cfg80211_get_bss(ar->wdev->wiphy, NULL, bssid, - ar->wdev->ssid, ar->wdev->ssid_len, - ((ADHOC_NETWORK & networkType) ? WLAN_CAPABILITY_IBSS : WLAN_CAPABILITY_ESS), - ((ADHOC_NETWORK & networkType) ? WLAN_CAPABILITY_IBSS : WLAN_CAPABILITY_ESS)); - - /* - * Earlier we were updating the cfg about bss by making a beacon frame - * only if the entry for bss is not there. This can have some issue if - * ROAM event is generated and a heavy traffic is ongoing. The ROAM - * event is handled through a work queue and by the time it really gets - * handled, BSS would have been aged out. So it is better to update the - * cfg about BSS irrespective of its entry being present right now or - * not. - */ - - if (ADHOC_NETWORK & networkType) { - /* construct 802.11 mgmt beacon */ - if(ptr_ie_buf) { - *ptr_ie_buf++ = WLAN_EID_SSID; - *ptr_ie_buf++ = ar->arSsidLen; - memcpy(ptr_ie_buf, ar->arSsid, ar->arSsidLen); - ptr_ie_buf +=ar->arSsidLen; - - *ptr_ie_buf++ = WLAN_EID_IBSS_PARAMS; - *ptr_ie_buf++ = 2; /* length */ - *ptr_ie_buf++ = 0; /* ATIM window */ - *ptr_ie_buf++ = 0; /* ATIM window */ - - /* TODO: update ibss params and include supported rates, - * DS param set, extened support rates, wmm. */ - - ie_buf_len = ptr_ie_buf - ie_buf; - } - - capability |= IEEE80211_CAPINFO_IBSS; - if(WEP_CRYPT == ar->arPairwiseCrypto) { - capability |= IEEE80211_CAPINFO_PRIVACY; - } - memcpy(source_mac, ar->arNetDev->dev_addr, ATH_MAC_LEN); - ptr_ie_buf = ie_buf; - } else { - capability = *(u16 *)(&assocInfo[beaconIeLen]); - memcpy(source_mac, bssid, ATH_MAC_LEN); - ptr_ie_buf = assocReqIe; - ie_buf_len = assocReqLen; - } - - size = offsetof(struct ieee80211_mgmt, u) - + sizeof(mgmt->u.beacon) - + ie_buf_len; - - ieeemgmtbuf = A_MALLOC_NOWAIT(size); - if(!ieeemgmtbuf) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("%s: ieeeMgmtbuf alloc error\n", __func__)); - cfg80211_put_bss(bss); - return; - } - - A_MEMZERO(ieeemgmtbuf, size); - mgmt = (struct ieee80211_mgmt *)ieeemgmtbuf; - mgmt->frame_control = (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON); - memcpy(mgmt->da, bcast_mac, ATH_MAC_LEN); - memcpy(mgmt->sa, source_mac, ATH_MAC_LEN); - memcpy(mgmt->bssid, bssid, ATH_MAC_LEN); - mgmt->u.beacon.beacon_int = beaconInterval; - mgmt->u.beacon.capab_info = capability; - memcpy(mgmt->u.beacon.variable, ptr_ie_buf, ie_buf_len); - - ibss_channel = ieee80211_get_channel(ar->wdev->wiphy, (int)channel); - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, - ("%s: inform bss with bssid %pM channel %d beaconInterval %d " - "capability 0x%x\n", __func__, mgmt->bssid, - ibss_channel->hw_value, beaconInterval, capability)); - - bss = cfg80211_inform_bss_frame(ar->wdev->wiphy, - ibss_channel, mgmt, - le16_to_cpu(size), - signal, GFP_KERNEL); - kfree(ieeemgmtbuf); - cfg80211_put_bss(bss); - - if((ADHOC_NETWORK & networkType)) { - cfg80211_ibss_joined(ar->arNetDev, bssid, GFP_KERNEL); - return; - } - - if (false == ar->arConnected) { - /* inform connect result to cfg80211 */ - ar->smeState = SME_DISCONNECTED; - cfg80211_connect_result(ar->arNetDev, bssid, - assocReqIe, assocReqLen, - assocRespIe, assocRespLen, - WLAN_STATUS_SUCCESS, GFP_KERNEL); - } else { - /* inform roam event to cfg80211 */ - cfg80211_roamed(ar->arNetDev, ibss_channel, bssid, - assocReqIe, assocReqLen, - assocRespIe, assocRespLen, - GFP_KERNEL); - } -} - -static int -ar6k_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, - u16 reason_code) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: reason=%u\n", __func__, reason_code)); - - if(ar->arWmiReady == false) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__)); - return -EIO; - } - - if(ar->arWlanState == WLAN_DISABLED) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__)); - return -EIO; - } - - if(ar->bIsDestroyProgress) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, destroy in progress\n", __func__)); - return -EBUSY; - } - - if(down_interruptible(&ar->arSem)) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, couldn't get access\n", __func__)); - return -ERESTARTSYS; - } - - reconnect_flag = 0; - ar6000_disconnect(ar); - A_MEMZERO(ar->arSsid, sizeof(ar->arSsid)); - ar->arSsidLen = 0; - - if (ar->arSkipScan == false) { - A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid)); - } - - up(&ar->arSem); - - return 0; -} - -void -ar6k_cfg80211_disconnect_event(struct ar6_softc *ar, u8 reason, - u8 *bssid, u8 assocRespLen, - u8 *assocInfo, u16 protocolReasonStatus) -{ - - u16 status; - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: reason=%u\n", __func__, reason)); - - if (ar->scan_request) { - cfg80211_scan_done(ar->scan_request, true); - ar->scan_request = NULL; - } - if((ADHOC_NETWORK & ar->arNetworkType)) { - if(NL80211_IFTYPE_ADHOC != ar->wdev->iftype) { - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, - ("%s: ath6k not in ibss mode\n", __func__)); - return; - } - A_MEMZERO(bssid, ETH_ALEN); - cfg80211_ibss_joined(ar->arNetDev, bssid, GFP_KERNEL); - return; - } - - if((INFRA_NETWORK & ar->arNetworkType)) { - if(NL80211_IFTYPE_STATION != ar->wdev->iftype) { - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, - ("%s: ath6k not in station mode\n", __func__)); - return; - } - } - - if(true == ar->arConnectPending) { - if(NO_NETWORK_AVAIL == reason) { - /* connect cmd failed */ - wmi_disconnect_cmd(ar->arWmi); - } else if (reason == DISCONNECT_CMD) { - if (ar->arAutoAuthStage) { - /* - * If the current auth algorithm is open try shared - * and make autoAuthStage idle. We do not make it - * leap for now being. - */ - if (ar->arDot11AuthMode == OPEN_AUTH) { - struct ar_key *key = NULL; - key = &ar->keys[ar->arDefTxKeyIndex]; - if (down_interruptible(&ar->arSem)) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, couldn't get access\n", __func__)); - return; - } - - - ar->arDot11AuthMode = SHARED_AUTH; - ar->arAutoAuthStage = AUTH_IDLE; - - wmi_addKey_cmd(ar->arWmi, ar->arDefTxKeyIndex, - ar->arPairwiseCrypto, - GROUP_USAGE | TX_USAGE, - key->key_len, - NULL, - key->key, KEY_OP_INIT_VAL, NULL, - NO_SYNC_WMIFLAG); - - status = wmi_connect_cmd(ar->arWmi, - ar->arNetworkType, - ar->arDot11AuthMode, - ar->arAuthMode, - ar->arPairwiseCrypto, - ar->arPairwiseCryptoLen, - ar->arGroupCrypto, - ar->arGroupCryptoLen, - ar->arSsidLen, - ar->arSsid, - ar->arReqBssid, - ar->arChannelHint, - ar->arConnectCtrlFlags); - up(&ar->arSem); - - } else if (ar->arDot11AuthMode == SHARED_AUTH) { - /* should not reach here */ - } - } else { - ar->arConnectPending = false; - if (ar->smeState == SME_CONNECTING) { - cfg80211_connect_result(ar->arNetDev, bssid, - NULL, 0, - NULL, 0, - WLAN_STATUS_UNSPECIFIED_FAILURE, - GFP_KERNEL); - } else { - cfg80211_disconnected(ar->arNetDev, - reason, - NULL, 0, - GFP_KERNEL); - } - ar->smeState = SME_DISCONNECTED; - } - } - } else { - if (reason != DISCONNECT_CMD) - wmi_disconnect_cmd(ar->arWmi); - } -} - -void -ar6k_cfg80211_scan_node(void *arg, bss_t *ni) -{ - struct wiphy *wiphy = (struct wiphy *)arg; - u16 size; - unsigned char *ieeemgmtbuf = NULL; - struct ieee80211_mgmt *mgmt; - struct ieee80211_channel *channel; - struct ieee80211_supported_band *band; - struct ieee80211_common_ie *cie; - s32 signal; - int freq; - - cie = &ni->ni_cie; - -#define CHAN_IS_11A(x) (!((x >= 2412) && (x <= 2484))) - if(CHAN_IS_11A(cie->ie_chan)) { - /* 11a */ - band = wiphy->bands[IEEE80211_BAND_5GHZ]; - } else if((cie->ie_erp) || (cie->ie_xrates)) { - /* 11g */ - band = wiphy->bands[IEEE80211_BAND_2GHZ]; - } else { - /* 11b */ - band = wiphy->bands[IEEE80211_BAND_2GHZ]; - } - - size = ni->ni_framelen + offsetof(struct ieee80211_mgmt, u); - ieeemgmtbuf = A_MALLOC_NOWAIT(size); - if(!ieeemgmtbuf) - { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ieeeMgmtbuf alloc error\n", __func__)); - return; - } - - /* Note: - TODO: Update target to include 802.11 mac header while sending bss info. - Target removes 802.11 mac header while sending the bss info to host, - cfg80211 needs it, for time being just filling the da, sa and bssid fields alone. - */ - mgmt = (struct ieee80211_mgmt *)ieeemgmtbuf; - memcpy(mgmt->da, bcast_mac, ATH_MAC_LEN); - memcpy(mgmt->sa, ni->ni_macaddr, ATH_MAC_LEN); - memcpy(mgmt->bssid, ni->ni_macaddr, ATH_MAC_LEN); - memcpy(ieeemgmtbuf + offsetof(struct ieee80211_mgmt, u), - ni->ni_buf, ni->ni_framelen); - - freq = cie->ie_chan; - channel = ieee80211_get_channel(wiphy, freq); - signal = ni->ni_snr * 100; - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, - ("%s: bssid %pM channel %d freq %d size %d\n", __func__, - mgmt->bssid, channel->hw_value, freq, size)); - cfg80211_inform_bss_frame(wiphy, channel, mgmt, - le16_to_cpu(size), - signal, GFP_KERNEL); - - kfree (ieeemgmtbuf); -} - -static int -ar6k_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, - struct cfg80211_scan_request *request) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev); - int ret = 0; - u32 forceFgScan = 0; - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__)); - - if(ar->arWmiReady == false) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__)); - return -EIO; - } - - if(ar->arWlanState == WLAN_DISABLED) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__)); - return -EIO; - } - - if (!ar->arUserBssFilter) { - if (wmi_bssfilter_cmd(ar->arWmi, - (ar->arConnected ? ALL_BUT_BSS_FILTER : ALL_BSS_FILTER), - 0) != 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Couldn't set bss filtering\n", __func__)); - return -EIO; - } - } - - if(request->n_ssids && - request->ssids[0].ssid_len) { - u8 i; - - if(request->n_ssids > (MAX_PROBED_SSID_INDEX - 1)) { - request->n_ssids = MAX_PROBED_SSID_INDEX - 1; - } - - for (i = 0; i < request->n_ssids; i++) { - wmi_probedSsid_cmd(ar->arWmi, i+1, SPECIFIC_SSID_FLAG, - request->ssids[i].ssid_len, - request->ssids[i].ssid); - } - } - - if(ar->arConnected) { - forceFgScan = 1; - } - - if(wmi_startscan_cmd(ar->arWmi, WMI_LONG_SCAN, forceFgScan, false, \ - 0, 0, 0, NULL) != 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_startscan_cmd failed\n", __func__)); - ret = -EIO; - } - - ar->scan_request = request; - - return ret; -} - -void -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) - return; - - if ((status == A_ECANCELED) || (status == A_EBUSY)) { - cfg80211_scan_done(ar->scan_request, true); - goto out; - } - - /* 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); - } - } - -out: - ar->scan_request = NULL; -} - -static int -ar6k_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, - u8 key_index, bool pairwise, const u8 *mac_addr, - struct key_params *params) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev); - struct ar_key *key = NULL; - u8 key_usage; - u8 key_type; - int status = 0; - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s:\n", __func__)); - - if(ar->arWmiReady == false) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__)); - return -EIO; - } - - if(ar->arWlanState == WLAN_DISABLED) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__)); - return -EIO; - } - - if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) { - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, - ("%s: key index %d out of bounds\n", __func__, key_index)); - return -ENOENT; - } - - key = &ar->keys[key_index]; - A_MEMZERO(key, sizeof(struct ar_key)); - - if(!mac_addr || is_broadcast_ether_addr(mac_addr)) { - key_usage = GROUP_USAGE; - } else { - key_usage = PAIRWISE_USAGE; - } - - if(params) { - if(params->key_len > WLAN_MAX_KEY_LEN || - params->seq_len > IW_ENCODE_SEQ_MAX_SIZE) - return -EINVAL; - - key->key_len = params->key_len; - memcpy(key->key, params->key, key->key_len); - key->seq_len = params->seq_len; - memcpy(key->seq, params->seq, key->seq_len); - key->cipher = params->cipher; - } - - switch (key->cipher) { - case WLAN_CIPHER_SUITE_WEP40: - case WLAN_CIPHER_SUITE_WEP104: - key_type = WEP_CRYPT; - break; - - case WLAN_CIPHER_SUITE_TKIP: - key_type = TKIP_CRYPT; - break; - - case WLAN_CIPHER_SUITE_CCMP: - key_type = AES_CRYPT; - break; - - default: - return -ENOTSUPP; - } - - if (((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode)) && - (GROUP_USAGE & key_usage)) - { - A_UNTIMEOUT(&ar->disconnect_timer); - } - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, - ("%s: index %d, key_len %d, key_type 0x%x,"\ - " key_usage 0x%x, seq_len %d\n", - __func__, key_index, key->key_len, key_type, - key_usage, key->seq_len)); - - ar->arDefTxKeyIndex = key_index; - status = wmi_addKey_cmd(ar->arWmi, ar->arDefTxKeyIndex, key_type, key_usage, - key->key_len, key->seq, key->key, KEY_OP_INIT_VAL, - (u8 *)mac_addr, SYNC_BOTH_WMIFLAG); - - - if (status) { - return -EIO; - } - - return 0; -} - -static int -ar6k_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev, - u8 key_index, bool pairwise, const u8 *mac_addr) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev); - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index)); - - if(ar->arWmiReady == false) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__)); - return -EIO; - } - - if(ar->arWlanState == WLAN_DISABLED) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__)); - return -EIO; - } - - if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) { - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, - ("%s: key index %d out of bounds\n", __func__, key_index)); - return -ENOENT; - } - - if(!ar->keys[key_index].key_len) { - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d is empty\n", __func__, key_index)); - return 0; - } - - ar->keys[key_index].key_len = 0; - - return wmi_deleteKey_cmd(ar->arWmi, key_index); -} - - -static int -ar6k_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, - u8 key_index, bool pairwise, const u8 *mac_addr, - void *cookie, - void (*callback)(void *cookie, struct key_params*)) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev); - struct ar_key *key = NULL; - struct key_params params; - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index)); - - if(ar->arWmiReady == false) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__)); - return -EIO; - } - - if(ar->arWlanState == WLAN_DISABLED) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__)); - return -EIO; - } - - if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) { - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, - ("%s: key index %d out of bounds\n", __func__, key_index)); - return -ENOENT; - } - - key = &ar->keys[key_index]; - A_MEMZERO(¶ms, sizeof(params)); - params.cipher = key->cipher; - params.key_len = key->key_len; - params.seq_len = key->seq_len; - params.seq = key->seq; - params.key = key->key; - - callback(cookie, ¶ms); - - return key->key_len ? 0 : -ENOENT; -} - - -static int -ar6k_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev, - u8 key_index, bool unicast, bool multicast) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev); - struct ar_key *key = NULL; - int status = 0; - u8 key_usage; - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index)); - - if(ar->arWmiReady == false) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__)); - return -EIO; - } - - if(ar->arWlanState == WLAN_DISABLED) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__)); - return -EIO; - } - - if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) { - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, - ("%s: key index %d out of bounds\n", - __func__, key_index)); - return -ENOENT; - } - - if(!ar->keys[key_index].key_len) { - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: invalid key index %d\n", - __func__, key_index)); - return -EINVAL; - } - - ar->arDefTxKeyIndex = key_index; - key = &ar->keys[ar->arDefTxKeyIndex]; - key_usage = GROUP_USAGE; - if (WEP_CRYPT == ar->arPairwiseCrypto) { - key_usage |= TX_USAGE; - } - - status = wmi_addKey_cmd(ar->arWmi, ar->arDefTxKeyIndex, - ar->arPairwiseCrypto, key_usage, - key->key_len, key->seq, key->key, KEY_OP_INIT_VAL, - NULL, SYNC_BOTH_WMIFLAG); - if (status) { - return -EIO; - } - - return 0; -} - -static int -ar6k_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *ndev, - u8 key_index) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(ndev); - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index)); - - if(ar->arWmiReady == false) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__)); - return -EIO; - } - - if(ar->arWlanState == WLAN_DISABLED) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__)); - return -EIO; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: not supported\n", __func__)); - return -ENOTSUPP; -} - -void -ar6k_cfg80211_tkip_micerr_event(struct ar6_softc *ar, u8 keyid, bool ismcast) -{ - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, - ("%s: keyid %d, ismcast %d\n", __func__, keyid, ismcast)); - - cfg80211_michael_mic_failure(ar->arNetDev, ar->arBssid, - (ismcast ? NL80211_KEYTYPE_GROUP : NL80211_KEYTYPE_PAIRWISE), - keyid, NULL, GFP_KERNEL); -} - -static int -ar6k_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed) -{ - struct ar6_softc *ar = (struct ar6_softc *)wiphy_priv(wiphy); - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: changed 0x%x\n", __func__, changed)); - - if(ar->arWmiReady == false) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__)); - return -EIO; - } - - if(ar->arWlanState == WLAN_DISABLED) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__)); - return -EIO; - } - - if (changed & WIPHY_PARAM_RTS_THRESHOLD) { - if (wmi_set_rts_cmd(ar->arWmi,wiphy->rts_threshold) != 0){ - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_set_rts_cmd failed\n", __func__)); - return -EIO; - } - } - - return 0; -} - -static int -ar6k_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev, - const u8 *peer, - const struct cfg80211_bitrate_mask *mask) -{ - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Setting rates: Not supported\n")); - return -EIO; -} - -/* The type nl80211_tx_power_setting replaces the following data type from 2.6.36 onwards */ -static int -ar6k_cfg80211_set_txpower(struct wiphy *wiphy, enum nl80211_tx_power_setting type, int dbm) -{ - struct ar6_softc *ar = (struct ar6_softc *)wiphy_priv(wiphy); - u8 ar_dbm; - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type 0x%x, dbm %d\n", __func__, type, dbm)); - - if(ar->arWmiReady == false) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__)); - return -EIO; - } - - if(ar->arWlanState == WLAN_DISABLED) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__)); - return -EIO; - } - - ar->arTxPwrSet = false; - switch(type) { - case NL80211_TX_POWER_AUTOMATIC: - return 0; - case NL80211_TX_POWER_LIMITED: - ar->arTxPwr = ar_dbm = dbm; - ar->arTxPwrSet = true; - break; - default: - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type 0x%x not supported\n", __func__, type)); - return -EOPNOTSUPP; - } - - wmi_set_txPwr_cmd(ar->arWmi, ar_dbm); - - return 0; -} - -static int -ar6k_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm) -{ - struct ar6_softc *ar = (struct ar6_softc *)wiphy_priv(wiphy); - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__)); - - if(ar->arWmiReady == false) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__)); - return -EIO; - } - - if(ar->arWlanState == WLAN_DISABLED) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__)); - return -EIO; - } - - if((ar->arConnected == true)) { - ar->arTxPwr = 0; - - if(wmi_get_txPwr_cmd(ar->arWmi) != 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_get_txPwr_cmd failed\n", __func__)); - return -EIO; - } - - wait_event_interruptible_timeout(arEvent, ar->arTxPwr != 0, 5 * HZ); - - if(signal_pending(current)) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Target did not respond\n", __func__)); - return -EINTR; - } - } - - *dbm = ar->arTxPwr; - return 0; -} - -static int -ar6k_cfg80211_set_power_mgmt(struct wiphy *wiphy, - struct net_device *dev, - bool pmgmt, int timeout) -{ - struct ar6_softc *ar = ar6k_priv(dev); - WMI_POWER_MODE_CMD pwrMode; - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: pmgmt %d, timeout %d\n", __func__, pmgmt, timeout)); - - if(ar->arWmiReady == false) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__)); - return -EIO; - } - - if(ar->arWlanState == WLAN_DISABLED) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__)); - return -EIO; - } - - if(pmgmt) { - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Max Perf\n", __func__)); - pwrMode.powerMode = REC_POWER; - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Rec Power\n", __func__)); - pwrMode.powerMode = MAX_PERF_POWER; - } - - if(wmi_powermode_cmd(ar->arWmi, pwrMode.powerMode) != 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_powermode_cmd failed\n", __func__)); - return -EIO; - } - - return 0; -} - -static struct net_device * -ar6k_cfg80211_add_virtual_intf(struct wiphy *wiphy, char *name, - enum nl80211_iftype type, u32 *flags, - struct vif_params *params) -{ - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: not supported\n", __func__)); - - /* Multiple virtual interface is not supported. - * The default interface supports STA and IBSS type - */ - return ERR_PTR(-EOPNOTSUPP); -} - -static int -ar6k_cfg80211_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev) -{ - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: not supported\n", __func__)); - - /* Multiple virtual interface is not supported. - * The default interface supports STA and IBSS type - */ - return -EOPNOTSUPP; -} - -static int -ar6k_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev, - enum nl80211_iftype type, u32 *flags, - struct vif_params *params) -{ - struct ar6_softc *ar = ar6k_priv(ndev); - struct wireless_dev *wdev = ar->wdev; - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type %u\n", __func__, type)); - - if(ar->arWmiReady == false) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__)); - return -EIO; - } - - if(ar->arWlanState == WLAN_DISABLED) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__)); - return -EIO; - } - - switch (type) { - case NL80211_IFTYPE_STATION: - ar->arNextMode = INFRA_NETWORK; - break; - case NL80211_IFTYPE_ADHOC: - ar->arNextMode = ADHOC_NETWORK; - break; - default: - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: type %u\n", __func__, type)); - return -EOPNOTSUPP; - } - - wdev->iftype = type; - - return 0; -} - -static int -ar6k_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, - struct cfg80211_ibss_params *ibss_param) -{ - struct ar6_softc *ar = ar6k_priv(dev); - int status; - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__)); - - if(ar->arWmiReady == false) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__)); - return -EIO; - } - - if(ar->arWlanState == WLAN_DISABLED) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__)); - return -EIO; - } - - if(!ibss_param->ssid_len || IEEE80211_MAX_SSID_LEN < ibss_param->ssid_len) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ssid invalid\n", __func__)); - return -EINVAL; - } - - ar->arSsidLen = ibss_param->ssid_len; - memcpy(ar->arSsid, ibss_param->ssid, ar->arSsidLen); - - if(ibss_param->channel) { - ar->arChannelHint = ibss_param->channel->center_freq; - } - - if(ibss_param->channel_fixed) { - /* TODO: channel_fixed: The channel should be fixed, do not search for - * IBSSs to join on other channels. Target firmware does not support this - * feature, needs to be updated.*/ - } - - A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid)); - if(ibss_param->bssid) { - if(memcmp(&ibss_param->bssid, bcast_mac, AR6000_ETH_ADDR_LEN)) { - memcpy(ar->arReqBssid, ibss_param->bssid, sizeof(ar->arReqBssid)); - } - } - - ar6k_set_wpa_version(ar, 0); - ar6k_set_auth_type(ar, NL80211_AUTHTYPE_OPEN_SYSTEM); - - if(ibss_param->privacy) { - ar6k_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, true); - ar6k_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, false); - } else { - ar6k_set_cipher(ar, IW_AUTH_CIPHER_NONE, true); - ar6k_set_cipher(ar, IW_AUTH_CIPHER_NONE, false); - } - - ar->arNetworkType = ar->arNextMode; - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Connect called with authmode %d dot11 auth %d"\ - " PW crypto %d PW crypto Len %d GRP crypto %d"\ - " GRP crypto Len %d channel hint %u\n", - __func__, ar->arAuthMode, ar->arDot11AuthMode, - ar->arPairwiseCrypto, ar->arPairwiseCryptoLen, - ar->arGroupCrypto, ar->arGroupCryptoLen, ar->arChannelHint)); - - status = wmi_connect_cmd(ar->arWmi, ar->arNetworkType, - ar->arDot11AuthMode, ar->arAuthMode, - ar->arPairwiseCrypto, ar->arPairwiseCryptoLen, - ar->arGroupCrypto,ar->arGroupCryptoLen, - ar->arSsidLen, ar->arSsid, - ar->arReqBssid, ar->arChannelHint, - ar->arConnectCtrlFlags); - ar->arConnectPending = true; - - return 0; -} - -static int -ar6k_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) -{ - struct ar6_softc *ar = (struct ar6_softc *)ar6k_priv(dev); - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__)); - - if(ar->arWmiReady == false) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__)); - return -EIO; - } - - if(ar->arWlanState == WLAN_DISABLED) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__)); - return -EIO; - } - - ar6000_disconnect(ar); - A_MEMZERO(ar->arSsid, sizeof(ar->arSsid)); - ar->arSsidLen = 0; - - 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[] = { - WLAN_CIPHER_SUITE_WEP40, - WLAN_CIPHER_SUITE_WEP104, - WLAN_CIPHER_SUITE_TKIP, - WLAN_CIPHER_SUITE_CCMP, -}; - -bool is_rate_legacy(s32 rate) -{ - static const s32 legacy[] = { 1000, 2000, 5500, 11000, - 6000, 9000, 12000, 18000, 24000, - 36000, 48000, 54000 }; - u8 i; - - for (i = 0; i < ARRAY_SIZE(legacy); i++) { - if (rate == legacy[i]) - return true; - } - - return false; -} - -bool is_rate_ht20(s32 rate, u8 *mcs, bool *sgi) -{ - static const s32 ht20[] = { 6500, 13000, 19500, 26000, 39000, - 52000, 58500, 65000, 72200 }; - u8 i; - - for (i = 0; i < ARRAY_SIZE(ht20); i++) { - if (rate == ht20[i]) { - if (i == ARRAY_SIZE(ht20) - 1) - /* last rate uses sgi */ - *sgi = true; - else - *sgi = false; - - *mcs = i; - return true; - } - } - return false; -} - -bool is_rate_ht40(s32 rate, u8 *mcs, bool *sgi) -{ - static const s32 ht40[] = { 13500, 27000, 40500, 54000, - 81000, 108000, 121500, 135000, - 150000 }; - u8 i; - - for (i = 0; i < ARRAY_SIZE(ht40); i++) { - if (rate == ht40[i]) { - if (i == ARRAY_SIZE(ht40) - 1) - /* last rate uses sgi */ - *sgi = true; - else - *sgi = false; - - *mcs = i; - return true; - } - } - - return false; -} - -static int ar6k_get_station(struct wiphy *wiphy, struct net_device *dev, - u8 *mac, struct station_info *sinfo) -{ - struct ar6_softc *ar = ar6k_priv(dev); - long left; - bool sgi; - s32 rate; - int ret; - u8 mcs; - - if (memcmp(mac, ar->arBssid, ETH_ALEN) != 0) - return -ENOENT; - - if (down_interruptible(&ar->arSem)) - return -EBUSY; - - ar->statsUpdatePending = true; - - ret = wmi_get_stats_cmd(ar->arWmi); - - if (ret != 0) { - up(&ar->arSem); - return -EIO; - } - - left = wait_event_interruptible_timeout(arEvent, - ar->statsUpdatePending == false, - wmitimeout * HZ); - - up(&ar->arSem); - - if (left == 0) - return -ETIMEDOUT; - else if (left < 0) - return left; - - if (ar->arTargetStats.rx_bytes) { - sinfo->rx_bytes = ar->arTargetStats.rx_bytes; - sinfo->filled |= STATION_INFO_RX_BYTES; - sinfo->rx_packets = ar->arTargetStats.rx_packets; - sinfo->filled |= STATION_INFO_RX_PACKETS; - } - - if (ar->arTargetStats.tx_bytes) { - sinfo->tx_bytes = ar->arTargetStats.tx_bytes; - sinfo->filled |= STATION_INFO_TX_BYTES; - sinfo->tx_packets = ar->arTargetStats.tx_packets; - sinfo->filled |= STATION_INFO_TX_PACKETS; - } - - sinfo->signal = ar->arTargetStats.cs_rssi; - sinfo->filled |= STATION_INFO_SIGNAL; - - rate = ar->arTargetStats.tx_unicast_rate; - - if (is_rate_legacy(rate)) { - sinfo->txrate.legacy = rate / 100; - } else if (is_rate_ht20(rate, &mcs, &sgi)) { - if (sgi) { - sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; - sinfo->txrate.mcs = mcs - 1; - } else { - sinfo->txrate.mcs = mcs; - } - - sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS; - } else if (is_rate_ht40(rate, &mcs, &sgi)) { - if (sgi) { - sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI; - sinfo->txrate.mcs = mcs - 1; - } else { - sinfo->txrate.mcs = mcs; - } - - sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH; - sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS; - } else { - WARN(1, "invalid rate: %d", rate); - return 0; - } - - sinfo->filled |= STATION_INFO_TX_BITRATE; - - 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, - .add_virtual_intf = ar6k_cfg80211_add_virtual_intf, - .del_virtual_intf = ar6k_cfg80211_del_virtual_intf, - .scan = ar6k_cfg80211_scan, - .connect = ar6k_cfg80211_connect, - .disconnect = ar6k_cfg80211_disconnect, - .add_key = ar6k_cfg80211_add_key, - .get_key = ar6k_cfg80211_get_key, - .del_key = ar6k_cfg80211_del_key, - .set_default_key = ar6k_cfg80211_set_default_key, - .set_default_mgmt_key = ar6k_cfg80211_set_default_mgmt_key, - .set_wiphy_params = ar6k_cfg80211_set_wiphy_params, - .set_bitrate_mask = ar6k_cfg80211_set_bitrate_mask, - .set_tx_power = ar6k_cfg80211_set_txpower, - .get_tx_power = ar6k_cfg80211_get_txpower, - .set_power_mgmt = ar6k_cfg80211_set_power_mgmt, - .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 * -ar6k_cfg80211_init(struct device *dev) -{ - int ret = 0; - struct wireless_dev *wdev; - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__)); - - wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); - if(!wdev) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("%s: Couldn't allocate wireless device\n", __func__)); - return ERR_PTR(-ENOMEM); - } - - /* create a new wiphy for use with cfg80211 */ - wdev->wiphy = wiphy_new(&ar6k_cfg80211_ops, sizeof(struct ar6_softc)); - if(!wdev->wiphy) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("%s: Couldn't allocate wiphy device\n", __func__)); - kfree(wdev); - return ERR_PTR(-ENOMEM); - } - - /* set device pointer for wiphy */ - set_wiphy_dev(wdev->wiphy, dev); - - wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | - BIT(NL80211_IFTYPE_ADHOC); - /* max num of ssids that can be probed during scanning */ - wdev->wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX; - wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &ar6k_band_2ghz; - wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &ar6k_band_5ghz; - wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; - - wdev->wiphy->cipher_suites = cipher_suites; - wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites); - - ret = wiphy_register(wdev->wiphy); - if(ret < 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, - ("%s: Couldn't register wiphy device\n", __func__)); - wiphy_free(wdev->wiphy); - return ERR_PTR(ret); - } - - return wdev; -} - -void -ar6k_cfg80211_deinit(struct ar6_softc *ar) -{ - struct wireless_dev *wdev = ar->wdev; - - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__)); - - if(ar->scan_request) { - cfg80211_scan_done(ar->scan_request, true); - ar->scan_request = NULL; - } - - if(!wdev) - return; - - wiphy_unregister(wdev->wiphy); - wiphy_free(wdev->wiphy); - kfree(wdev); -} - - - - - - - diff --git a/drivers/staging/ath6kl/os/linux/export_hci_transport.c b/drivers/staging/ath6kl/os/linux/export_hci_transport.c deleted file mode 100644 index 430998e..0000000 --- a/drivers/staging/ath6kl/os/linux/export_hci_transport.c +++ /dev/null @@ -1,124 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// HCI bridge implementation -// -// Author(s): ="Atheros" -//============================================================================== -#include <a_config.h> -#include <athdefs.h> -#include "a_osapi.h" -#include "htc_api.h" -#include "a_drv.h" -#include "hif.h" -#include "common_drv.h" -#include "a_debug.h" -#include "hci_transport_api.h" - -#include "AR6002/hw4.0/hw/apb_athr_wlan_map.h" -#include "AR6002/hw4.0/hw/uart_reg.h" -#include "AR6002/hw4.0/hw/rtc_wlan_reg.h" - -HCI_TRANSPORT_HANDLE (*_HCI_TransportAttach)(void *HTCHandle, struct hci_transport_config_info *pInfo); -void (*_HCI_TransportDetach)(HCI_TRANSPORT_HANDLE HciTrans); -int (*_HCI_TransportAddReceivePkts)(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet_queue *pQueue); -int (*_HCI_TransportSendPkt)(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet *pPacket, bool Synchronous); -void (*_HCI_TransportStop)(HCI_TRANSPORT_HANDLE HciTrans); -int (*_HCI_TransportStart)(HCI_TRANSPORT_HANDLE HciTrans); -int (*_HCI_TransportEnableDisableAsyncRecv)(HCI_TRANSPORT_HANDLE HciTrans, bool Enable); -int (*_HCI_TransportRecvHCIEventSync)(HCI_TRANSPORT_HANDLE HciTrans, - struct htc_packet *pPacket, - int MaxPollMS); -int (*_HCI_TransportSetBaudRate)(HCI_TRANSPORT_HANDLE HciTrans, u32 Baud); -int (*_HCI_TransportEnablePowerMgmt)(HCI_TRANSPORT_HANDLE HciTrans, bool Enable); - -extern struct hci_transport_callbacks ar6kHciTransCallbacks; - -int ar6000_register_hci_transport(struct hci_transport_callbacks *hciTransCallbacks) -{ - ar6kHciTransCallbacks = *hciTransCallbacks; - - _HCI_TransportAttach = HCI_TransportAttach; - _HCI_TransportDetach = HCI_TransportDetach; - _HCI_TransportAddReceivePkts = HCI_TransportAddReceivePkts; - _HCI_TransportSendPkt = HCI_TransportSendPkt; - _HCI_TransportStop = HCI_TransportStop; - _HCI_TransportStart = HCI_TransportStart; - _HCI_TransportEnableDisableAsyncRecv = HCI_TransportEnableDisableAsyncRecv; - _HCI_TransportRecvHCIEventSync = HCI_TransportRecvHCIEventSync; - _HCI_TransportSetBaudRate = HCI_TransportSetBaudRate; - _HCI_TransportEnablePowerMgmt = HCI_TransportEnablePowerMgmt; - - return 0; -} - -int -ar6000_get_hif_dev(struct hif_device *device, void *config) -{ - int status; - - status = HIFConfigureDevice(device, - HIF_DEVICE_GET_OS_DEVICE, - (struct hif_device_os_device_info *)config, - sizeof(struct hif_device_os_device_info)); - return status; -} - -int ar6000_set_uart_config(struct hif_device *hifDevice, - u32 scale, - u32 step) -{ - u32 regAddress; - u32 regVal; - int status; - - regAddress = WLAN_UART_BASE_ADDRESS | UART_CLKDIV_ADDRESS; - regVal = ((u32)scale << 16) | step; - /* change the HCI UART scale/step values through the diagnostic window */ - status = ar6000_WriteRegDiag(hifDevice, ®Address, ®Val); - - return status; -} - -int ar6000_get_core_clock_config(struct hif_device *hifDevice, u32 *data) -{ - u32 regAddress; - int status; - - regAddress = WLAN_RTC_BASE_ADDRESS | WLAN_CPU_CLOCK_ADDRESS; - /* read CPU clock settings*/ - status = ar6000_ReadRegDiag(hifDevice, ®Address, data); - - return status; -} - -EXPORT_SYMBOL(ar6000_register_hci_transport); -EXPORT_SYMBOL(ar6000_get_hif_dev); -EXPORT_SYMBOL(ar6000_set_uart_config); -EXPORT_SYMBOL(ar6000_get_core_clock_config); -EXPORT_SYMBOL(_HCI_TransportAttach); -EXPORT_SYMBOL(_HCI_TransportDetach); -EXPORT_SYMBOL(_HCI_TransportAddReceivePkts); -EXPORT_SYMBOL(_HCI_TransportSendPkt); -EXPORT_SYMBOL(_HCI_TransportStop); -EXPORT_SYMBOL(_HCI_TransportStart); -EXPORT_SYMBOL(_HCI_TransportEnableDisableAsyncRecv); -EXPORT_SYMBOL(_HCI_TransportRecvHCIEventSync); -EXPORT_SYMBOL(_HCI_TransportSetBaudRate); -EXPORT_SYMBOL(_HCI_TransportEnablePowerMgmt); diff --git a/drivers/staging/ath6kl/os/linux/hci_bridge.c b/drivers/staging/ath6kl/os/linux/hci_bridge.c deleted file mode 100644 index 6087edc..0000000 --- a/drivers/staging/ath6kl/os/linux/hci_bridge.c +++ /dev/null @@ -1,1141 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// HCI bridge implementation -// -// Author(s): ="Atheros" -//============================================================================== - -#ifdef EXPORT_HCI_BRIDGE_INTERFACE -#include <linux/etherdevice.h> -#include <a_config.h> -#include <athdefs.h> -#include "a_osapi.h" -#include "htc_api.h" -#include "wmi.h" -#include "a_drv.h" -#include "hif.h" -#include "common_drv.h" -#include "a_debug.h" -#define ATH_DEBUG_HCI_BRIDGE ATH_DEBUG_MAKE_MODULE_MASK(6) -#define ATH_DEBUG_HCI_RECV ATH_DEBUG_MAKE_MODULE_MASK(7) -#define ATH_DEBUG_HCI_SEND ATH_DEBUG_MAKE_MODULE_MASK(8) -#define ATH_DEBUG_HCI_DUMP ATH_DEBUG_MAKE_MODULE_MASK(9) -#else -#include "ar6000_drv.h" -#endif /* EXPORT_HCI_BRIDGE_INTERFACE */ - -#ifdef ATH_AR6K_ENABLE_GMBOX -#ifdef EXPORT_HCI_BRIDGE_INTERFACE -#include "export_hci_transport.h" -#else -#include "hci_transport_api.h" -#endif -#include "epping_test.h" -#include "gmboxif.h" -#include "ar3kconfig.h" -#include <net/bluetooth/bluetooth.h> -#include <net/bluetooth/hci_core.h> - - /* only build on newer kernels which have BT configured */ -#if defined(CONFIG_BT_MODULE) || defined(CONFIG_BT) -#define CONFIG_BLUEZ_HCI_BRIDGE -#endif - -#ifdef EXPORT_HCI_BRIDGE_INTERFACE -unsigned int ar3khcibaud = 0; -unsigned int hciuartscale = 0; -unsigned int hciuartstep = 0; - -module_param(ar3khcibaud, int, 0644); -module_param(hciuartscale, int, 0644); -module_param(hciuartstep, int, 0644); -#else -extern unsigned int ar3khcibaud; -extern unsigned int hciuartscale; -extern unsigned int hciuartstep; -#endif /* EXPORT_HCI_BRIDGE_INTERFACE */ - -struct ar6k_hci_bridge_info { - void *pHCIDev; /* HCI bridge device */ - struct hci_transport_properties HCIProps; /* HCI bridge props */ - struct hci_dev *pBtStackHCIDev; /* BT Stack HCI dev */ - bool HciNormalMode; /* Actual HCI mode enabled (non-TEST)*/ - bool HciRegistered; /* HCI device registered with stack */ - struct htc_packet_queue HTCPacketStructHead; - u8 *pHTCStructAlloc; - spinlock_t BridgeLock; -#ifdef EXPORT_HCI_BRIDGE_INTERFACE - struct hci_transport_misc_handles HCITransHdl; -#else - struct ar6_softc *ar; -#endif /* EXPORT_HCI_BRIDGE_INTERFACE */ -}; - -#define MAX_ACL_RECV_BUFS 16 -#define MAX_EVT_RECV_BUFS 8 -#define MAX_HCI_WRITE_QUEUE_DEPTH 32 -#define MAX_ACL_RECV_LENGTH 1200 -#define MAX_EVT_RECV_LENGTH 257 -#define TX_PACKET_RSV_OFFSET 32 -#define NUM_HTC_PACKET_STRUCTS ((MAX_ACL_RECV_BUFS + MAX_EVT_RECV_BUFS + MAX_HCI_WRITE_QUEUE_DEPTH) * 2) - -#define HCI_GET_OP_CODE(p) (((u16)((p)[1])) << 8) | ((u16)((p)[0])) - -extern unsigned int setupbtdev; -struct ar3k_config_info ar3kconfig; - -#ifdef EXPORT_HCI_BRIDGE_INTERFACE -struct ar6k_hci_bridge_info *g_pHcidevInfo; -#endif - -static int bt_setup_hci(struct ar6k_hci_bridge_info *pHcidevInfo); -static void bt_cleanup_hci(struct ar6k_hci_bridge_info *pHcidevInfo); -static int bt_register_hci(struct ar6k_hci_bridge_info *pHcidevInfo); -static bool bt_indicate_recv(struct ar6k_hci_bridge_info *pHcidevInfo, - HCI_TRANSPORT_PACKET_TYPE Type, - struct sk_buff *skb); -static struct sk_buff *bt_alloc_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, int Length); -static void bt_free_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, struct sk_buff *skb); - -#ifdef EXPORT_HCI_BRIDGE_INTERFACE -int ar6000_setup_hci(void *ar); -void ar6000_cleanup_hci(void *ar); -int hci_test_send(void *ar, struct sk_buff *skb); -#else -int ar6000_setup_hci(struct ar6_softc *ar); -void ar6000_cleanup_hci(struct ar6_softc *ar); -/* HCI bridge testing */ -int hci_test_send(struct ar6_softc *ar, struct sk_buff *skb); -#endif /* EXPORT_HCI_BRIDGE_INTERFACE */ - -#define LOCK_BRIDGE(dev) spin_lock_bh(&(dev)->BridgeLock) -#define UNLOCK_BRIDGE(dev) spin_unlock_bh(&(dev)->BridgeLock) - -static inline void FreeBtOsBuf(struct ar6k_hci_bridge_info *pHcidevInfo, void *osbuf) -{ - if (pHcidevInfo->HciNormalMode) { - bt_free_buffer(pHcidevInfo, (struct sk_buff *)osbuf); - } else { - /* in test mode, these are just ordinary netbuf allocations */ - A_NETBUF_FREE(osbuf); - } -} - -static void FreeHTCStruct(struct ar6k_hci_bridge_info *pHcidevInfo, struct htc_packet *pPacket) -{ - LOCK_BRIDGE(pHcidevInfo); - HTC_PACKET_ENQUEUE(&pHcidevInfo->HTCPacketStructHead,pPacket); - UNLOCK_BRIDGE(pHcidevInfo); -} - -static struct htc_packet * AllocHTCStruct(struct ar6k_hci_bridge_info *pHcidevInfo) -{ - struct htc_packet *pPacket = NULL; - LOCK_BRIDGE(pHcidevInfo); - pPacket = HTC_PACKET_DEQUEUE(&pHcidevInfo->HTCPacketStructHead); - UNLOCK_BRIDGE(pHcidevInfo); - return pPacket; -} - -#define BLOCK_ROUND_UP_PWR2(x, align) (((int) (x) + ((align)-1)) & ~((align)-1)) - -static void RefillRecvBuffers(struct ar6k_hci_bridge_info *pHcidevInfo, - HCI_TRANSPORT_PACKET_TYPE Type, - int NumBuffers) -{ - int length, i; - void *osBuf = NULL; - struct htc_packet_queue queue; - struct htc_packet *pPacket; - - INIT_HTC_PACKET_QUEUE(&queue); - - if (Type == HCI_ACL_TYPE) { - if (pHcidevInfo->HciNormalMode) { - length = HCI_MAX_FRAME_SIZE; - } else { - length = MAX_ACL_RECV_LENGTH; - } - } else { - length = MAX_EVT_RECV_LENGTH; - } - - /* add on transport head and tail room */ - length += pHcidevInfo->HCIProps.HeadRoom + pHcidevInfo->HCIProps.TailRoom; - /* round up to the required I/O padding */ - length = BLOCK_ROUND_UP_PWR2(length,pHcidevInfo->HCIProps.IOBlockPad); - - for (i = 0; i < NumBuffers; i++) { - - if (pHcidevInfo->HciNormalMode) { - osBuf = bt_alloc_buffer(pHcidevInfo,length); - } else { - osBuf = A_NETBUF_ALLOC(length); - } - - if (NULL == osBuf) { - break; - } - - pPacket = AllocHTCStruct(pHcidevInfo); - if (NULL == pPacket) { - FreeBtOsBuf(pHcidevInfo,osBuf); - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to alloc HTC struct \n")); - break; - } - - SET_HTC_PACKET_INFO_RX_REFILL(pPacket,osBuf,A_NETBUF_DATA(osBuf),length,Type); - /* add to queue */ - HTC_PACKET_ENQUEUE(&queue,pPacket); - } - - if (i > 0) { - HCI_TransportAddReceivePkts(pHcidevInfo->pHCIDev, &queue); - } -} - -#define HOST_INTEREST_ITEM_ADDRESS(ar, item) \ - (((ar)->arTargetType == TARGET_TYPE_AR6002) ? AR6002_HOST_INTEREST_ITEM_ADDRESS(item) : \ - (((ar)->arTargetType == TARGET_TYPE_AR6003) ? AR6003_HOST_INTEREST_ITEM_ADDRESS(item) : 0)) -static int ar6000_hci_transport_ready(HCI_TRANSPORT_HANDLE HCIHandle, - struct hci_transport_properties *pProps, - void *pContext) -{ - struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext; - int status; - u32 address, hci_uart_pwr_mgmt_params; -// struct ar3k_config_info ar3kconfig; - - pHcidevInfo->pHCIDev = HCIHandle; - - memcpy(&pHcidevInfo->HCIProps,pProps,sizeof(*pProps)); - - AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE,("HCI ready (hci:0x%lX, headroom:%d, tailroom:%d blockpad:%d) \n", - (unsigned long)HCIHandle, - pHcidevInfo->HCIProps.HeadRoom, - pHcidevInfo->HCIProps.TailRoom, - pHcidevInfo->HCIProps.IOBlockPad)); - -#ifdef EXPORT_HCI_BRIDGE_INTERFACE - A_ASSERT((pProps->HeadRoom + pProps->TailRoom) <= (struct net_device *)(pHcidevInfo->HCITransHdl.netDevice)->hard_header_len); -#else - A_ASSERT((pProps->HeadRoom + pProps->TailRoom) <= pHcidevInfo->ar->arNetDev->hard_header_len); -#endif - - /* provide buffers */ - RefillRecvBuffers(pHcidevInfo, HCI_ACL_TYPE, MAX_ACL_RECV_BUFS); - RefillRecvBuffers(pHcidevInfo, HCI_EVENT_TYPE, MAX_EVT_RECV_BUFS); - - do { - /* start transport */ - status = HCI_TransportStart(pHcidevInfo->pHCIDev); - - if (status) { - break; - } - - if (!pHcidevInfo->HciNormalMode) { - /* in test mode, no need to go any further */ - break; - } - - // The delay is required when AR6K is driving the BT reset line - // where time is needed after the BT chip is out of reset (HCI_TransportStart) - // and before the first HCI command is issued (AR3KConfigure) - // FIXME - // The delay should be configurable and be only applied when AR6K driving the BT - // reset line. This could be done by some module parameter or based on some HW config - // info. For now apply 100ms delay blindly - A_MDELAY(100); - - A_MEMZERO(&ar3kconfig,sizeof(ar3kconfig)); - ar3kconfig.pHCIDev = pHcidevInfo->pHCIDev; - ar3kconfig.pHCIProps = &pHcidevInfo->HCIProps; -#ifdef EXPORT_HCI_BRIDGE_INTERFACE - ar3kconfig.pHIFDevice = (struct hif_device *)(pHcidevInfo->HCITransHdl.hifDevice); -#else - ar3kconfig.pHIFDevice = pHcidevInfo->ar->arHifDevice; -#endif - ar3kconfig.pBtStackHCIDev = pHcidevInfo->pBtStackHCIDev; - - if (ar3khcibaud != 0) { - /* user wants ar3k baud rate change */ - ar3kconfig.Flags |= AR3K_CONFIG_FLAG_SET_AR3K_BAUD; - ar3kconfig.Flags |= AR3K_CONFIG_FLAG_AR3K_BAUD_CHANGE_DELAY; - ar3kconfig.AR3KBaudRate = ar3khcibaud; - } - - if ((hciuartscale != 0) || (hciuartstep != 0)) { - /* user wants to tune HCI bridge UART scale/step values */ - ar3kconfig.AR6KScale = (u16)hciuartscale; - ar3kconfig.AR6KStep = (u16)hciuartstep; - ar3kconfig.Flags |= AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP; - } - - /* Fetch the address of the hi_hci_uart_pwr_mgmt_params instance in the host interest area */ - address = TARG_VTOP(pHcidevInfo->ar->arTargetType, - HOST_INTEREST_ITEM_ADDRESS(pHcidevInfo->ar, hi_hci_uart_pwr_mgmt_params)); - status = ar6000_ReadRegDiag(pHcidevInfo->ar->arHifDevice, &address, &hci_uart_pwr_mgmt_params); - if (0 == status) { - ar3kconfig.PwrMgmtEnabled = (hci_uart_pwr_mgmt_params & 0x1); - ar3kconfig.IdleTimeout = (hci_uart_pwr_mgmt_params & 0xFFFF0000) >> 16; - ar3kconfig.WakeupTimeout = (hci_uart_pwr_mgmt_params & 0xFF00) >> 8; - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to read hci_uart_pwr_mgmt_params! \n")); - } - /* configure the AR3K device */ - memcpy(ar3kconfig.bdaddr,pHcidevInfo->ar->bdaddr,6); - status = AR3KConfigure(&ar3kconfig); - if (status) { - break; - } - - /* Make sure both AR6K and AR3K have power management enabled */ - if (ar3kconfig.PwrMgmtEnabled) { - status = HCI_TransportEnablePowerMgmt(pHcidevInfo->pHCIDev, true); - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to enable TLPM for AR6K! \n")); - } - } - - status = bt_register_hci(pHcidevInfo); - - } while (false); - - return status; -} - -static void ar6000_hci_transport_failure(void *pContext, int Status) -{ - struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext; - - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: transport failure! \n")); - - if (pHcidevInfo->HciNormalMode) { - /* TODO .. */ - } -} - -static void ar6000_hci_transport_removed(void *pContext) -{ - struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext; - - AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: transport removed. \n")); - - A_ASSERT(pHcidevInfo->pHCIDev != NULL); - - HCI_TransportDetach(pHcidevInfo->pHCIDev); - bt_cleanup_hci(pHcidevInfo); - pHcidevInfo->pHCIDev = NULL; -} - -static void ar6000_hci_send_complete(void *pContext, struct htc_packet *pPacket) -{ - struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext; - void *osbuf = pPacket->pPktContext; - A_ASSERT(osbuf != NULL); - A_ASSERT(pHcidevInfo != NULL); - - if (pPacket->Status) { - if ((pPacket->Status != A_ECANCELED) && (pPacket->Status != A_NO_RESOURCE)) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: Send Packet Failed: %d \n",pPacket->Status)); - } - } - - FreeHTCStruct(pHcidevInfo,pPacket); - FreeBtOsBuf(pHcidevInfo,osbuf); - -} - -static void ar6000_hci_pkt_recv(void *pContext, struct htc_packet *pPacket) -{ - struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext; - struct sk_buff *skb; - - A_ASSERT(pHcidevInfo != NULL); - skb = (struct sk_buff *)pPacket->pPktContext; - A_ASSERT(skb != NULL); - - do { - - if (pPacket->Status) { - break; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_HCI_RECV, - ("HCI Bridge, packet received type : %d len:%d \n", - HCI_GET_PACKET_TYPE(pPacket),pPacket->ActualLength)); - - /* set the actual buffer position in the os buffer, HTC recv buffers posted to HCI are set - * to fill the front of the buffer */ - A_NETBUF_PUT(skb,pPacket->ActualLength + pHcidevInfo->HCIProps.HeadRoom); - A_NETBUF_PULL(skb,pHcidevInfo->HCIProps.HeadRoom); - - if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_HCI_DUMP)) { - AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("<<< Recv HCI %s packet len:%d \n", - (HCI_GET_PACKET_TYPE(pPacket) == HCI_EVENT_TYPE) ? "EVENT" : "ACL", - skb->len)); - AR_DEBUG_PRINTBUF(skb->data, skb->len,"BT HCI RECV Packet Dump"); - } - - if (pHcidevInfo->HciNormalMode) { - /* indicate the packet */ - if (bt_indicate_recv(pHcidevInfo,HCI_GET_PACKET_TYPE(pPacket),skb)) { - /* bt stack accepted the packet */ - skb = NULL; - } - break; - } - - /* for testing, indicate packet to the network stack */ -#ifdef EXPORT_HCI_BRIDGE_INTERFACE - skb->dev = (struct net_device *)(pHcidevInfo->HCITransHdl.netDevice); - if ((((struct net_device *)pHcidevInfo->HCITransHdl.netDevice)->flags & IFF_UP) == IFF_UP) { - skb->protocol = eth_type_trans(skb, (struct net_device *)(pHcidevInfo->HCITransHdl.netDevice)); -#else - skb->dev = pHcidevInfo->ar->arNetDev; - if ((pHcidevInfo->ar->arNetDev->flags & IFF_UP) == IFF_UP) { - skb->protocol = eth_type_trans(skb, pHcidevInfo->ar->arNetDev); -#endif - netif_rx(skb); - skb = NULL; - } - - } while (false); - - FreeHTCStruct(pHcidevInfo,pPacket); - - if (skb != NULL) { - /* packet was not accepted, free it */ - FreeBtOsBuf(pHcidevInfo,skb); - } - -} - -static void ar6000_hci_pkt_refill(void *pContext, HCI_TRANSPORT_PACKET_TYPE Type, int BuffersAvailable) -{ - struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext; - int refillCount; - - if (Type == HCI_ACL_TYPE) { - refillCount = MAX_ACL_RECV_BUFS - BuffersAvailable; - } else { - refillCount = MAX_EVT_RECV_BUFS - BuffersAvailable; - } - - if (refillCount > 0) { - RefillRecvBuffers(pHcidevInfo,Type,refillCount); - } - -} - -static HCI_SEND_FULL_ACTION ar6000_hci_pkt_send_full(void *pContext, struct htc_packet *pPacket) -{ - struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)pContext; - HCI_SEND_FULL_ACTION action = HCI_SEND_FULL_KEEP; - - if (!pHcidevInfo->HciNormalMode) { - /* for epping testing, check packet tag, some epping packets are - * special and cannot be dropped */ - if (HTC_GET_TAG_FROM_PKT(pPacket) == AR6K_DATA_PKT_TAG) { - action = HCI_SEND_FULL_DROP; - } - } - - return action; -} - -#ifdef EXPORT_HCI_BRIDGE_INTERFACE -int ar6000_setup_hci(void *ar) -#else -int ar6000_setup_hci(struct ar6_softc *ar) -#endif -{ - struct hci_transport_config_info config; - int status = 0; - int i; - struct htc_packet *pPacket; - struct ar6k_hci_bridge_info *pHcidevInfo; - - - do { - - pHcidevInfo = (struct ar6k_hci_bridge_info *)A_MALLOC(sizeof(struct ar6k_hci_bridge_info)); - - if (NULL == pHcidevInfo) { - status = A_NO_MEMORY; - break; - } - - A_MEMZERO(pHcidevInfo, sizeof(struct ar6k_hci_bridge_info)); -#ifdef EXPORT_HCI_BRIDGE_INTERFACE - g_pHcidevInfo = pHcidevInfo; - pHcidevInfo->HCITransHdl = *(struct hci_transport_misc_handles *)ar; -#else - ar->hcidev_info = pHcidevInfo; - pHcidevInfo->ar = ar; -#endif - spin_lock_init(&pHcidevInfo->BridgeLock); - INIT_HTC_PACKET_QUEUE(&pHcidevInfo->HTCPacketStructHead); - - ar->exitCallback = AR3KConfigureExit; - - status = bt_setup_hci(pHcidevInfo); - if (status) { - break; - } - - if (pHcidevInfo->HciNormalMode) { - AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: running in normal mode... \n")); - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: running in test mode... \n")); - } - - pHcidevInfo->pHTCStructAlloc = (u8 *)A_MALLOC((sizeof(struct htc_packet)) * NUM_HTC_PACKET_STRUCTS); - - if (NULL == pHcidevInfo->pHTCStructAlloc) { - status = A_NO_MEMORY; - break; - } - - pPacket = (struct htc_packet *)pHcidevInfo->pHTCStructAlloc; - for (i = 0; i < NUM_HTC_PACKET_STRUCTS; i++,pPacket++) { - FreeHTCStruct(pHcidevInfo,pPacket); - } - - A_MEMZERO(&config,sizeof(struct hci_transport_config_info)); - config.ACLRecvBufferWaterMark = MAX_ACL_RECV_BUFS / 2; - config.EventRecvBufferWaterMark = MAX_EVT_RECV_BUFS / 2; - config.MaxSendQueueDepth = MAX_HCI_WRITE_QUEUE_DEPTH; - config.pContext = pHcidevInfo; - config.TransportFailure = ar6000_hci_transport_failure; - config.TransportReady = ar6000_hci_transport_ready; - config.TransportRemoved = ar6000_hci_transport_removed; - config.pHCISendComplete = ar6000_hci_send_complete; - config.pHCIPktRecv = ar6000_hci_pkt_recv; - config.pHCIPktRecvRefill = ar6000_hci_pkt_refill; - config.pHCISendFull = ar6000_hci_pkt_send_full; - -#ifdef EXPORT_HCI_BRIDGE_INTERFACE - pHcidevInfo->pHCIDev = HCI_TransportAttach(pHcidevInfo->HCITransHdl.htcHandle, &config); -#else - pHcidevInfo->pHCIDev = HCI_TransportAttach(ar->arHtcTarget, &config); -#endif - - if (NULL == pHcidevInfo->pHCIDev) { - status = A_ERROR; - } - - } while (false); - - if (status) { - if (pHcidevInfo != NULL) { - if (NULL == pHcidevInfo->pHCIDev) { - /* GMBOX may not be present in older chips */ - /* just return success */ - status = 0; - } - } - ar6000_cleanup_hci(ar); - } - - return status; -} - -#ifdef EXPORT_HCI_BRIDGE_INTERFACE -void ar6000_cleanup_hci(void *ar) -#else -void ar6000_cleanup_hci(struct ar6_softc *ar) -#endif -{ -#ifdef EXPORT_HCI_BRIDGE_INTERFACE - struct ar6k_hci_bridge_info *pHcidevInfo = g_pHcidevInfo; -#else - struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)ar->hcidev_info; -#endif - - if (pHcidevInfo != NULL) { - bt_cleanup_hci(pHcidevInfo); - - if (pHcidevInfo->pHCIDev != NULL) { - HCI_TransportStop(pHcidevInfo->pHCIDev); - HCI_TransportDetach(pHcidevInfo->pHCIDev); - pHcidevInfo->pHCIDev = NULL; - } - - if (pHcidevInfo->pHTCStructAlloc != NULL) { - kfree(pHcidevInfo->pHTCStructAlloc); - pHcidevInfo->pHTCStructAlloc = NULL; - } - - kfree(pHcidevInfo); -#ifndef EXPORT_HCI_BRIDGE_INTERFACE - ar->hcidev_info = NULL; -#endif - } - - -} - -#ifdef EXPORT_HCI_BRIDGE_INTERFACE -int hci_test_send(void *ar, struct sk_buff *skb) -#else -int hci_test_send(struct ar6_softc *ar, struct sk_buff *skb) -#endif -{ - int status = 0; - int length; - EPPING_HEADER *pHeader; - struct htc_packet *pPacket; - HTC_TX_TAG htc_tag = AR6K_DATA_PKT_TAG; -#ifdef EXPORT_HCI_BRIDGE_INTERFACE - struct ar6k_hci_bridge_info *pHcidevInfo = g_pHcidevInfo; -#else - struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)ar->hcidev_info; -#endif - - do { - - if (NULL == pHcidevInfo) { - status = A_ERROR; - break; - } - - if (NULL == pHcidevInfo->pHCIDev) { - status = A_ERROR; - break; - } - - if (pHcidevInfo->HciNormalMode) { - /* this interface cannot run when normal WMI is running */ - status = A_ERROR; - break; - } - - pHeader = (EPPING_HEADER *)A_NETBUF_DATA(skb); - - if (!IS_EPPING_PACKET(pHeader)) { - status = A_EINVAL; - break; - } - - if (IS_EPING_PACKET_NO_DROP(pHeader)) { - htc_tag = AR6K_CONTROL_PKT_TAG; - } - - length = sizeof(EPPING_HEADER) + pHeader->DataLength; - - pPacket = AllocHTCStruct(pHcidevInfo); - if (NULL == pPacket) { - status = A_NO_MEMORY; - break; - } - - SET_HTC_PACKET_INFO_TX(pPacket, - skb, - A_NETBUF_DATA(skb), - length, - HCI_ACL_TYPE, /* send every thing out as ACL */ - htc_tag); - - HCI_TransportSendPkt(pHcidevInfo->pHCIDev,pPacket,false); - pPacket = NULL; - - } while (false); - - return status; -} - -void ar6000_set_default_ar3kconfig(struct ar6_softc *ar, void *ar3kconfig) -{ - struct ar6k_hci_bridge_info *pHcidevInfo = (struct ar6k_hci_bridge_info *)ar->hcidev_info; - struct ar3k_config_info *config = (struct ar3k_config_info *)ar3kconfig; - - config->pHCIDev = pHcidevInfo->pHCIDev; - config->pHCIProps = &pHcidevInfo->HCIProps; - config->pHIFDevice = ar->arHifDevice; - config->pBtStackHCIDev = pHcidevInfo->pBtStackHCIDev; - config->Flags |= AR3K_CONFIG_FLAG_SET_AR3K_BAUD; - config->AR3KBaudRate = 115200; -} - -#ifdef CONFIG_BLUEZ_HCI_BRIDGE -/*** BT Stack Entrypoints *******/ - -/* - * bt_open - open a handle to the device -*/ -static int bt_open(struct hci_dev *hdev) -{ - - AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_open - enter - x\n")); - set_bit(HCI_RUNNING, &hdev->flags); - set_bit(HCI_UP, &hdev->flags); - set_bit(HCI_INIT, &hdev->flags); - return 0; -} - -/* - * bt_close - close handle to the device -*/ -static int bt_close(struct hci_dev *hdev) -{ - AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_close - enter\n")); - clear_bit(HCI_RUNNING, &hdev->flags); - return 0; -} - -/* - * bt_send_frame - send data frames -*/ -static int bt_send_frame(struct sk_buff *skb) -{ - struct hci_dev *hdev = (struct hci_dev *)skb->dev; - HCI_TRANSPORT_PACKET_TYPE type; - struct ar6k_hci_bridge_info *pHcidevInfo; - struct htc_packet *pPacket; - int status = 0; - struct sk_buff *txSkb = NULL; - - if (!hdev) { - AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("HCI Bridge: bt_send_frame - no device\n")); - return -ENODEV; - } - - if (!test_bit(HCI_RUNNING, &hdev->flags)) { - AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_send_frame - not open\n")); - return -EBUSY; - } - - pHcidevInfo = (struct ar6k_hci_bridge_info *)hdev->driver_data; - A_ASSERT(pHcidevInfo != NULL); - - AR_DEBUG_PRINTF(ATH_DEBUG_HCI_SEND, ("+bt_send_frame type: %d \n",bt_cb(skb)->pkt_type)); - type = HCI_COMMAND_TYPE; - - switch (bt_cb(skb)->pkt_type) { - case HCI_COMMAND_PKT: - type = HCI_COMMAND_TYPE; - hdev->stat.cmd_tx++; - break; - - case HCI_ACLDATA_PKT: - type = HCI_ACL_TYPE; - hdev->stat.acl_tx++; - break; - - case HCI_SCODATA_PKT: - /* we don't support SCO over the bridge */ - kfree_skb(skb); - return 0; - default: - A_ASSERT(false); - kfree_skb(skb); - return 0; - } - - if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_HCI_DUMP)) { - AR_DEBUG_PRINTF(ATH_DEBUG_ANY,(">>> Send HCI %s packet len: %d\n", - (type == HCI_COMMAND_TYPE) ? "COMMAND" : "ACL", - skb->len)); - if (type == HCI_COMMAND_TYPE) { - u16 opcode = HCI_GET_OP_CODE(skb->data); - AR_DEBUG_PRINTF(ATH_DEBUG_ANY,(" HCI Command: OGF:0x%X OCF:0x%X \r\n", - opcode >> 10, opcode & 0x3FF)); - } - AR_DEBUG_PRINTBUF(skb->data,skb->len,"BT HCI SEND Packet Dump"); - } - - do { - - txSkb = bt_skb_alloc(TX_PACKET_RSV_OFFSET + pHcidevInfo->HCIProps.HeadRoom + - pHcidevInfo->HCIProps.TailRoom + skb->len, - GFP_ATOMIC); - - if (txSkb == NULL) { - status = A_NO_MEMORY; - break; - } - - bt_cb(txSkb)->pkt_type = bt_cb(skb)->pkt_type; - txSkb->dev = (void *)pHcidevInfo->pBtStackHCIDev; - skb_reserve(txSkb, TX_PACKET_RSV_OFFSET + pHcidevInfo->HCIProps.HeadRoom); - memcpy(txSkb->data, skb->data, skb->len); - skb_put(txSkb,skb->len); - - pPacket = AllocHTCStruct(pHcidevInfo); - if (NULL == pPacket) { - status = A_NO_MEMORY; - break; - } - - /* HCI packet length here doesn't include the 1-byte transport header which - * will be handled by the HCI transport layer. Enough headroom has already - * been reserved above for the transport header - */ - SET_HTC_PACKET_INFO_TX(pPacket, - txSkb, - txSkb->data, - txSkb->len, - type, - AR6K_CONTROL_PKT_TAG); /* HCI packets cannot be dropped */ - - AR_DEBUG_PRINTF(ATH_DEBUG_HCI_SEND, ("HCI Bridge: bt_send_frame skb:0x%lX \n",(unsigned long)txSkb)); - AR_DEBUG_PRINTF(ATH_DEBUG_HCI_SEND, ("HCI Bridge: type:%d, Total Length:%d Bytes \n", - type, txSkb->len)); - - status = HCI_TransportSendPkt(pHcidevInfo->pHCIDev,pPacket,false); - pPacket = NULL; - txSkb = NULL; - - } while (false); - - if (txSkb != NULL) { - kfree_skb(txSkb); - } - - kfree_skb(skb); - - AR_DEBUG_PRINTF(ATH_DEBUG_HCI_SEND, ("-bt_send_frame \n")); - return 0; -} - -/* - * bt_ioctl - ioctl processing -*/ -static int bt_ioctl(struct hci_dev *hdev, unsigned int cmd, unsigned long arg) -{ - AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_ioctl - enter\n")); - return -ENOIOCTLCMD; -} - -/* - * bt_flush - flush outstandingbpackets -*/ -static int bt_flush(struct hci_dev *hdev) -{ - struct ar6k_hci_bridge_info *pHcidevInfo; - - AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_flush - enter\n")); - - pHcidevInfo = (struct ar6k_hci_bridge_info *)hdev->driver_data; - - /* TODO??? */ - - return 0; -} - - -/* - * bt_destruct - -*/ -static void bt_destruct(struct hci_dev *hdev) -{ - AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_destruct - enter\n")); - /* nothing to do here */ -} - -static int bt_setup_hci(struct ar6k_hci_bridge_info *pHcidevInfo) -{ - int status = 0; - struct hci_dev *pHciDev = NULL; - struct hif_device_os_device_info osDevInfo; - - if (!setupbtdev) { - return 0; - } - - do { - - A_MEMZERO(&osDevInfo,sizeof(osDevInfo)); - /* get the underlying OS device */ -#ifdef EXPORT_HCI_BRIDGE_INTERFACE - status = ar6000_get_hif_dev((struct hif_device *)(pHcidevInfo->HCITransHdl.hifDevice), - &osDevInfo); -#else - status = HIFConfigureDevice(pHcidevInfo->ar->arHifDevice, - HIF_DEVICE_GET_OS_DEVICE, - &osDevInfo, - sizeof(osDevInfo)); -#endif - - if (status) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to OS device info from HIF\n")); - break; - } - - /* allocate a BT HCI struct for this device */ - pHciDev = hci_alloc_dev(); - if (NULL == pHciDev) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge - failed to allocate bt struct \n")); - status = A_NO_MEMORY; - break; - } - /* save the device, we'll register this later */ - pHcidevInfo->pBtStackHCIDev = pHciDev; - SET_HCIDEV_DEV(pHciDev,osDevInfo.pOSDevice); - SET_HCI_BUS_TYPE(pHciDev, HCI_VIRTUAL, HCI_BREDR); - pHciDev->driver_data = pHcidevInfo; - pHciDev->open = bt_open; - pHciDev->close = bt_close; - pHciDev->send = bt_send_frame; - pHciDev->ioctl = bt_ioctl; - pHciDev->flush = bt_flush; - pHciDev->destruct = bt_destruct; - pHciDev->owner = THIS_MODULE; - /* driver is running in normal BT mode */ - pHcidevInfo->HciNormalMode = true; - - } while (false); - - if (status) { - bt_cleanup_hci(pHcidevInfo); - } - - return status; -} - -static void bt_cleanup_hci(struct ar6k_hci_bridge_info *pHcidevInfo) -{ - int err; - - if (pHcidevInfo->HciRegistered) { - pHcidevInfo->HciRegistered = false; - clear_bit(HCI_RUNNING, &pHcidevInfo->pBtStackHCIDev->flags); - clear_bit(HCI_UP, &pHcidevInfo->pBtStackHCIDev->flags); - clear_bit(HCI_INIT, &pHcidevInfo->pBtStackHCIDev->flags); - A_ASSERT(pHcidevInfo->pBtStackHCIDev != NULL); - /* unregister */ - if ((err = hci_unregister_dev(pHcidevInfo->pBtStackHCIDev)) < 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to unregister with bluetooth %d\n",err)); - } - } - - kfree(pHcidevInfo->pBtStackHCIDev); - pHcidevInfo->pBtStackHCIDev = NULL; -} - -static int bt_register_hci(struct ar6k_hci_bridge_info *pHcidevInfo) -{ - int err; - int status = 0; - - do { - AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: registering HCI... \n")); - A_ASSERT(pHcidevInfo->pBtStackHCIDev != NULL); - /* mark that we are registered */ - pHcidevInfo->HciRegistered = true; - if ((err = hci_register_dev(pHcidevInfo->pBtStackHCIDev)) < 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: failed to register with bluetooth %d\n",err)); - pHcidevInfo->HciRegistered = false; - status = A_ERROR; - break; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_HCI_BRIDGE, ("HCI Bridge: HCI registered \n")); - - } while (false); - - return status; -} - -static bool bt_indicate_recv(struct ar6k_hci_bridge_info *pHcidevInfo, - HCI_TRANSPORT_PACKET_TYPE Type, - struct sk_buff *skb) -{ - u8 btType; - int len; - bool success = false; - BT_HCI_EVENT_HEADER *pEvent; - - do { - - if (!test_bit(HCI_RUNNING, &pHcidevInfo->pBtStackHCIDev->flags)) { - AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("HCI Bridge: bt_indicate_recv - not running\n")); - break; - } - - switch (Type) { - case HCI_ACL_TYPE: - btType = HCI_ACLDATA_PKT; - break; - case HCI_EVENT_TYPE: - btType = HCI_EVENT_PKT; - break; - default: - btType = 0; - A_ASSERT(false); - break; - } - - if (0 == btType) { - break; - } - - /* set the final type */ - bt_cb(skb)->pkt_type = btType; - /* set dev */ - skb->dev = (void *)pHcidevInfo->pBtStackHCIDev; - len = skb->len; - - if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_HCI_RECV)) { - if (bt_cb(skb)->pkt_type == HCI_EVENT_PKT) { - pEvent = (BT_HCI_EVENT_HEADER *)skb->data; - AR_DEBUG_PRINTF(ATH_DEBUG_HCI_RECV, ("BT HCI EventCode: %d, len:%d \n", - pEvent->EventCode, pEvent->ParamLength)); - } - } - - /* pass receive packet up the stack */ - if (hci_recv_frame(skb) != 0) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("HCI Bridge: hci_recv_frame failed \n")); - break; - } else { - AR_DEBUG_PRINTF(ATH_DEBUG_HCI_RECV, - ("HCI Bridge: Indicated RCV of type:%d, Length:%d \n",btType,len)); - } - - success = true; - - } while (false); - - return success; -} - -static struct sk_buff* bt_alloc_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, int Length) -{ - struct sk_buff *skb; - /* in normal HCI mode we need to alloc from the bt core APIs */ - skb = bt_skb_alloc(Length, GFP_ATOMIC); - if (NULL == skb) { - AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Failed to alloc bt sk_buff \n")); - } - return skb; -} - -static void bt_free_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, struct sk_buff *skb) -{ - kfree_skb(skb); -} - -#else // { CONFIG_BLUEZ_HCI_BRIDGE - - /* stubs when we only want to test the HCI bridging Interface without the HT stack */ -static int bt_setup_hci(struct ar6k_hci_bridge_info *pHcidevInfo) -{ - return 0; -} -static void bt_cleanup_hci(struct ar6k_hci_bridge_info *pHcidevInfo) -{ - -} -static int bt_register_hci(struct ar6k_hci_bridge_info *pHcidevInfo) -{ - A_ASSERT(false); - return A_ERROR; -} - -static bool bt_indicate_recv(struct ar6k_hci_bridge_info *pHcidevInfo, - HCI_TRANSPORT_PACKET_TYPE Type, - struct sk_buff *skb) -{ - A_ASSERT(false); - return false; -} - -static struct sk_buff* bt_alloc_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, int Length) -{ - A_ASSERT(false); - return NULL; -} -static void bt_free_buffer(struct ar6k_hci_bridge_info *pHcidevInfo, struct sk_buff *skb) -{ - A_ASSERT(false); -} - -#endif // } CONFIG_BLUEZ_HCI_BRIDGE - -#else // { ATH_AR6K_ENABLE_GMBOX - - /* stubs when GMBOX support is not needed */ - -#ifdef EXPORT_HCI_BRIDGE_INTERFACE -int ar6000_setup_hci(void *ar) -#else -int ar6000_setup_hci(struct ar6_softc *ar) -#endif -{ - return 0; -} - -#ifdef EXPORT_HCI_BRIDGE_INTERFACE -void ar6000_cleanup_hci(void *ar) -#else -void ar6000_cleanup_hci(struct ar6_softc *ar) -#endif -{ - return; -} - -#ifndef EXPORT_HCI_BRIDGE_INTERFACE -void ar6000_set_default_ar3kconfig(struct ar6_softc *ar, void *ar3kconfig) -{ - return; -} -#endif - -#ifdef EXPORT_HCI_BRIDGE_INTERFACE -int hci_test_send(void *ar, struct sk_buff *skb) -#else -int hci_test_send(struct ar6_softc *ar, struct sk_buff *skb) -#endif -{ - return -EOPNOTSUPP; -} - -#endif // } ATH_AR6K_ENABLE_GMBOX - - -#ifdef EXPORT_HCI_BRIDGE_INTERFACE -static int __init -hcibridge_init_module(void) -{ - int status; - struct hci_transport_callbacks hciTransCallbacks; - - hciTransCallbacks.setupTransport = ar6000_setup_hci; - hciTransCallbacks.cleanupTransport = ar6000_cleanup_hci; - - status = ar6000_register_hci_transport(&hciTransCallbacks); - if (status) - return -ENODEV; - - return 0; -} - -static void __exit -hcibridge_cleanup_module(void) -{ -} - -module_init(hcibridge_init_module); -module_exit(hcibridge_cleanup_module); -MODULE_LICENSE("Dual BSD/GPL"); -#endif diff --git a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h b/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h deleted file mode 100644 index 80cef77..0000000 --- a/drivers/staging/ath6kl/os/linux/include/ar6000_drv.h +++ /dev/null @@ -1,776 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2004-2010 Atheros Communications Inc. -// All rights reserved. -// -// -// -// 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. -// -// -// -// Author(s): ="Atheros" -//------------------------------------------------------------------------------ - -#ifndef _AR6000_H_ -#define _AR6000_H_ - -#include <linux/init.h> -#include <linux/sched.h> -#include <linux/spinlock.h> -#include <linux/if_ether.h> -#include <linux/etherdevice.h> -#include <net/iw_handler.h> -#include <linux/if_arp.h> -#include <linux/ip.h> -#include <linux/wireless.h> -#include <net/cfg80211.h> -#include <linux/module.h> -#include <asm/io.h> - -#include <a_config.h> -#include <athdefs.h> -#include "a_osapi.h" -#include "htc_api.h" -#include "wmi.h" -#include "a_drv.h" -#include "bmi.h" -#include <ieee80211.h> -#include <ieee80211_ioctl.h> -#include <wlan_api.h> -#include <wmi_api.h> -#include "pkt_log.h" -#include "aggr_recv_api.h" -#include <host_version.h> -#include <linux/rtnetlink.h> -#include <linux/moduleparam.h> -#include "ar6000_api.h" -#ifdef CONFIG_HOST_TCMD_SUPPORT -#include <testcmd.h> -#endif -#include <linux/firmware.h> - -#include "targaddrs.h" -#include "dbglog_api.h" -#include "ar6000_diag.h" -#include "common_drv.h" -#include "roaming.h" -#include "hci_transport_api.h" -#define ATH_MODULE_NAME driver -#include "a_debug.h" -#include "hw/apb_map.h" -#include "hw/rtc_reg.h" -#include "hw/mbox_reg.h" -#include "gpio_reg.h" - -#define ATH_DEBUG_DBG_LOG ATH_DEBUG_MAKE_MODULE_MASK(0) -#define ATH_DEBUG_WLAN_CONNECT ATH_DEBUG_MAKE_MODULE_MASK(1) -#define ATH_DEBUG_WLAN_SCAN ATH_DEBUG_MAKE_MODULE_MASK(2) -#define ATH_DEBUG_WLAN_TX ATH_DEBUG_MAKE_MODULE_MASK(3) -#define ATH_DEBUG_WLAN_RX ATH_DEBUG_MAKE_MODULE_MASK(4) -#define ATH_DEBUG_HTC_RAW ATH_DEBUG_MAKE_MODULE_MASK(5) -#define ATH_DEBUG_HCI_BRIDGE ATH_DEBUG_MAKE_MODULE_MASK(6) -#define ATH_DEBUG_HCI_RECV ATH_DEBUG_MAKE_MODULE_MASK(7) -#define ATH_DEBUG_HCI_SEND ATH_DEBUG_MAKE_MODULE_MASK(8) -#define ATH_DEBUG_HCI_DUMP ATH_DEBUG_MAKE_MODULE_MASK(9) - -#ifndef __dev_put -#define __dev_put(dev) dev_put(dev) -#endif - - -#define USER_SAVEDKEYS_STAT_INIT 0 -#define USER_SAVEDKEYS_STAT_RUN 1 - -// TODO this needs to move into the AR_SOFTC struct -struct USER_SAVEDKEYS { - struct ieee80211req_key ucast_ik; - struct ieee80211req_key bcast_ik; - CRYPTO_TYPE keyType; - bool keyOk; -}; - -#define DBG_INFO 0x00000001 -#define DBG_ERROR 0x00000002 -#define DBG_WARNING 0x00000004 -#define DBG_SDIO 0x00000008 -#define DBG_HIF 0x00000010 -#define DBG_HTC 0x00000020 -#define DBG_WMI 0x00000040 -#define DBG_WMI2 0x00000080 -#define DBG_DRIVER 0x00000100 - -#define DBG_DEFAULTS (DBG_ERROR|DBG_WARNING) - - -int ar6000_ReadRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data); -int ar6000_WriteRegDiag(struct hif_device *hifDevice, u32 *address, u32 *data); - -#ifdef __cplusplus -extern "C" { -#endif - -#define MAX_AR6000 1 -#define AR6000_MAX_RX_BUFFERS 16 -#define AR6000_BUFFER_SIZE 1664 -#define AR6000_MAX_AMSDU_RX_BUFFERS 4 -#define AR6000_AMSDU_REFILL_THRESHOLD 3 -#define AR6000_AMSDU_BUFFER_SIZE (WMI_MAX_AMSDU_RX_DATA_FRAME_LENGTH + 128) -#define AR6000_MAX_RX_MESSAGE_SIZE (max(WMI_MAX_NORMAL_RX_DATA_FRAME_LENGTH,WMI_MAX_AMSDU_RX_DATA_FRAME_LENGTH)) - -#define AR6000_TX_TIMEOUT 10 -#define AR6000_ETH_ADDR_LEN 6 -#define AR6000_MAX_ENDPOINTS 4 -#define MAX_NODE_NUM 15 -/* MAX_HI_COOKIE_NUM are reserved for high priority traffic */ -#define MAX_DEF_COOKIE_NUM 180 -#define MAX_HI_COOKIE_NUM 18 /* 10% of MAX_COOKIE_NUM */ -#define MAX_COOKIE_NUM (MAX_DEF_COOKIE_NUM + MAX_HI_COOKIE_NUM) - -/* MAX_DEFAULT_SEND_QUEUE_DEPTH is used to set the default queue depth for the - * WMM send queues. If a queue exceeds this depth htc will query back to the - * OS specific layer by calling EpSendFull(). This gives the OS layer the - * opportunity to drop the packet if desired. Therefore changing - * MAX_DEFAULT_SEND_QUEUE_DEPTH does not affect resource utilization but - * does impact the threshold used to identify if a packet should be - * dropped. */ -#define MAX_DEFAULT_SEND_QUEUE_DEPTH (MAX_DEF_COOKIE_NUM / WMM_NUM_AC) - -#define AR6000_HB_CHALLENGE_RESP_FREQ_DEFAULT 1 -#define AR6000_HB_CHALLENGE_RESP_MISS_THRES_DEFAULT 1 -#define A_DISCONNECT_TIMER_INTERVAL 10 * 1000 -#define A_DEFAULT_LISTEN_INTERVAL 100 -#define A_MAX_WOW_LISTEN_INTERVAL 1000 - -enum { - DRV_HB_CHALLENGE = 0, - APP_HB_CHALLENGE -}; - -enum { - WLAN_INIT_MODE_NONE = 0, - WLAN_INIT_MODE_USR, - WLAN_INIT_MODE_UDEV, - WLAN_INIT_MODE_DRV -}; - -/* Suspend - configuration */ -enum { - WLAN_SUSPEND_CUT_PWR = 0, - WLAN_SUSPEND_DEEP_SLEEP, - WLAN_SUSPEND_WOW, - WLAN_SUSPEND_CUT_PWR_IF_BT_OFF -}; - -/* WiFi OFF - configuration */ -enum { - WLAN_OFF_CUT_PWR = 0, - WLAN_OFF_DEEP_SLEEP, -}; - -/* WLAN low power state */ -enum { - WLAN_POWER_STATE_ON = 0, - WLAN_POWER_STATE_CUT_PWR = 1, - WLAN_POWER_STATE_DEEP_SLEEP, - WLAN_POWER_STATE_WOW -}; - -/* WLAN WoW State */ -enum { - WLAN_WOW_STATE_NONE = 0, - WLAN_WOW_STATE_SUSPENDED, - WLAN_WOW_STATE_SUSPENDING -}; - - -typedef enum _AR6K_BIN_FILE { - AR6K_OTP_FILE, - AR6K_FIRMWARE_FILE, - AR6K_PATCH_FILE, - AR6K_BOARD_DATA_FILE, -} AR6K_BIN_FILE; - -#ifdef SETUPHCI_ENABLED -#define SETUPHCI_DEFAULT 1 -#else -#define SETUPHCI_DEFAULT 0 -#endif /* SETUPHCI_ENABLED */ - -#ifdef SETUPBTDEV_ENABLED -#define SETUPBTDEV_DEFAULT 1 -#else -#define SETUPBTDEV_DEFAULT 0 -#endif /* SETUPBTDEV_ENABLED */ - -#ifdef ENABLEUARTPRINT_SET -#define ENABLEUARTPRINT_DEFAULT 1 -#else -#define ENABLEUARTPRINT_DEFAULT 0 -#endif /* ENABLEARTPRINT_SET */ - -#ifdef ATH6KL_CONFIG_HIF_VIRTUAL_SCATTER -#define NOHIFSCATTERSUPPORT_DEFAULT 1 -#else /* ATH6KL_CONFIG_HIF_VIRTUAL_SCATTER */ -#define NOHIFSCATTERSUPPORT_DEFAULT 0 -#endif /* ATH6KL_CONFIG_HIF_VIRTUAL_SCATTER */ - - -#if defined(CONFIG_ATH6KL_ENABLE_COEXISTENCE) - -#ifdef CONFIG_AR600x_BT_QCOM -#define ATH6KL_BT_DEV 1 -#elif defined(CONFIG_AR600x_BT_CSR) -#define ATH6KL_BT_DEV 2 -#else -#define ATH6KL_BT_DEV 3 -#endif - -#ifdef CONFIG_AR600x_DUAL_ANTENNA -#define ATH6KL_BT_ANTENNA 2 -#else -#define ATH6KL_BT_ANTENNA 1 -#endif - -#endif /* CONFIG_ATH6KL_ENABLE_COEXISTENCE */ - -#ifdef AR600x_BT_AR3001 -#define AR3KHCIBAUD_DEFAULT 3000000 -#define HCIUARTSCALE_DEFAULT 1 -#define HCIUARTSTEP_DEFAULT 8937 -#else -#define AR3KHCIBAUD_DEFAULT 0 -#define HCIUARTSCALE_DEFAULT 0 -#define HCIUARTSTEP_DEFAULT 0 -#endif /* AR600x_BT_AR3001 */ - -#define WLAN_INIT_MODE_DEFAULT WLAN_INIT_MODE_DRV - -#define AR6K_PATCH_DOWNLOAD_ADDRESS(_param, _ver) do { \ - if ((_ver) == AR6003_REV1_VERSION) { \ - (_param) = AR6003_REV1_PATCH_DOWNLOAD_ADDRESS; \ - } else if ((_ver) == AR6003_REV2_VERSION) { \ - (_param) = AR6003_REV2_PATCH_DOWNLOAD_ADDRESS; \ - } else { \ - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown Version: %d\n", _ver)); \ - A_ASSERT(0); \ - } \ -} while (0) - -#define AR6K_DATA_DOWNLOAD_ADDRESS(_param, _ver) do { \ - if ((_ver) == AR6003_REV1_VERSION) { \ - (_param) = AR6003_REV1_DATA_DOWNLOAD_ADDRESS; \ - } else if ((_ver) == AR6003_REV2_VERSION) { \ - (_param) = AR6003_REV2_DATA_DOWNLOAD_ADDRESS; \ - } else { \ - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown Version: %d\n", _ver)); \ - A_ASSERT(0); \ - } \ -} while (0) - -#define AR6K_DATASET_PATCH_ADDRESS(_param, _ver) do { \ - if ((_ver) == AR6003_REV2_VERSION) { \ - (_param) = AR6003_REV2_DATASET_PATCH_ADDRESS; \ - } else if ((_ver) == AR6003_REV3_VERSION) { \ - (_param) = AR6003_REV3_DATASET_PATCH_ADDRESS; \ - } else { \ - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown Version: %d\n", _ver)); \ - A_ASSERT(0); \ - } \ -} while (0) - -#define AR6K_APP_LOAD_ADDRESS(_param, _ver) do { \ - if ((_ver) == AR6003_REV2_VERSION) { \ - (_param) = AR6003_REV2_APP_LOAD_ADDRESS; \ - } else if ((_ver) == AR6003_REV3_VERSION) { \ - (_param) = AR6003_REV3_APP_LOAD_ADDRESS; \ - } else { \ - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown Version: %d\n", _ver)); \ - A_ASSERT(0); \ - } \ -} while (0) - -#define AR6K_APP_START_OVERRIDE_ADDRESS(_param, _ver) do { \ - if ((_ver) == AR6003_REV2_VERSION) { \ - (_param) = AR6003_REV2_APP_START_OVERRIDE; \ - } else if ((_ver) == AR6003_REV3_VERSION) { \ - (_param) = AR6003_REV3_APP_START_OVERRIDE; \ - } else { \ - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unknown Version: %d\n", _ver)); \ - A_ASSERT(0); \ - } \ -} while (0) - -/* AR6003 1.0 definitions */ -#define AR6003_REV1_VERSION 0x300002ba -#define AR6003_REV1_DATA_DOWNLOAD_ADDRESS AR6003_REV1_OTP_DATA_ADDRESS -#define AR6003_REV1_PATCH_DOWNLOAD_ADDRESS 0x57ea6c -#define AR6003_REV1_OTP_FILE "ath6k/AR6003/hw1.0/otp.bin.z77" -#define AR6003_REV1_FIRMWARE_FILE "ath6k/AR6003/hw1.0/athwlan.bin.z77" -#define AR6003_REV1_TCMD_FIRMWARE_FILE "ath6k/AR6003/hw1.0/athtcmd_ram.bin" -#define AR6003_REV1_ART_FIRMWARE_FILE "ath6k/AR6003/hw1.0/device.bin" -#define AR6003_REV1_PATCH_FILE "ath6k/AR6003/hw1.0/data.patch.bin" -#define AR6003_REV1_EPPING_FIRMWARE_FILE "ath6k/AR6003/hw1.0/endpointping.bin" -#ifdef CONFIG_AR600x_SD31_XXX -#define AR6003_REV1_BOARD_DATA_FILE "ath6k/AR6003/hw1.0/bdata.SD31.bin" -#elif defined(CONFIG_AR600x_SD32_XXX) -#define AR6003_REV1_BOARD_DATA_FILE "ath6k/AR6003/hw1.0/bdata.SD32.bin" -#elif defined(CONFIG_AR600x_WB31_XXX) -#define AR6003_REV1_BOARD_DATA_FILE "ath6k/AR6003/hw1.0/bdata.WB31.bin" -#else -#define AR6003_REV1_BOARD_DATA_FILE "ath6k/AR6003/hw1.0/bdata.CUSTOM.bin" -#endif /* Board Data File */ - -/* AR6003 2.0 definitions */ -#define AR6003_REV2_VERSION 0x30000384 -#define AR6003_REV2_DATA_DOWNLOAD_ADDRESS AR6003_REV2_OTP_DATA_ADDRESS -#define AR6003_REV2_PATCH_DOWNLOAD_ADDRESS 0x57e910 -#define AR6003_REV2_OTP_FILE "ath6k/AR6003/hw2.0/otp.bin.z77" -#define AR6003_REV2_FIRMWARE_FILE "ath6k/AR6003/hw2.0/athwlan.bin.z77" -#define AR6003_REV2_TCMD_FIRMWARE_FILE "ath6k/AR6003/hw2.0/athtcmd_ram.bin" -#define AR6003_REV2_ART_FIRMWARE_FILE "ath6k/AR6003/hw2.0/device.bin" -#define AR6003_REV2_PATCH_FILE "ath6k/AR6003/hw2.0/data.patch.bin" -#define AR6003_REV2_EPPING_FIRMWARE_FILE "ath6k/AR6003/hw2.0/endpointping.bin" -#ifdef CONFIG_AR600x_SD31_XXX -#define AR6003_REV2_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.SD31.bin" -#elif defined(CONFIG_AR600x_SD32_XXX) -#define AR6003_REV2_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.SD32.bin" -#elif defined(CONFIG_AR600x_WB31_XXX) -#define AR6003_REV2_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.WB31.bin" -#else -#define AR6003_REV2_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.CUSTOM.bin" -#endif /* Board Data File */ - -/* AR6003 3.0 definitions */ -#define AR6003_REV3_VERSION 0x30000582 -#define AR6003_REV3_OTP_FILE "ath6k/AR6003/hw2.1.1/otp.bin" -#define AR6003_REV3_FIRMWARE_FILE "ath6k/AR6003/hw2.1.1/athwlan.bin" -#define AR6003_REV3_TCMD_FIRMWARE_FILE "ath6k/AR6003/hw2.1.1/athtcmd_ram.bin" -#define AR6003_REV3_ART_FIRMWARE_FILE "ath6k/AR6003/hw2.1.1/device.bin" -#define AR6003_REV3_PATCH_FILE "ath6k/AR6003/hw2.1.1/data.patch.bin" -#define AR6003_REV3_EPPING_FIRMWARE_FILE "ath6k/AR6003/hw2.1.1/endpointping.bin" -#ifdef CONFIG_AR600x_SD31_XXX -#define AR6003_REV3_BOARD_DATA_FILE "ath6k/AR6003/hw2.1.1/bdata.SD31.bin" -#elif defined(CONFIG_AR600x_SD32_XXX) -#define AR6003_REV3_BOARD_DATA_FILE "ath6k/AR6003/hw2.1.1/bdata.SD32.bin" -#elif defined(CONFIG_AR600x_WB31_XXX) -#define AR6003_REV3_BOARD_DATA_FILE "ath6k/AR6003/hw2.1.1/bdata.WB31.bin" -#else -#define AR6003_REV3_BOARD_DATA_FILE "ath6k/AR6003/hw2.1.1/bdata.CUSTOM.bin" -#endif /* Board Data File */ - - -/* Power states */ -enum { - WLAN_PWR_CTRL_UP = 0, - WLAN_PWR_CTRL_CUT_PWR, - WLAN_PWR_CTRL_DEEP_SLEEP, - WLAN_PWR_CTRL_WOW, - WLAN_PWR_CTRL_DEEP_SLEEP_DISABLED -}; - -/* HTC RAW streams */ -typedef enum _HTC_RAW_STREAM_ID { - HTC_RAW_STREAM_NOT_MAPPED = -1, - HTC_RAW_STREAM_0 = 0, - HTC_RAW_STREAM_1 = 1, - HTC_RAW_STREAM_2 = 2, - HTC_RAW_STREAM_3 = 3, - HTC_RAW_STREAM_NUM_MAX -} HTC_RAW_STREAM_ID; - -#define RAW_HTC_READ_BUFFERS_NUM 4 -#define RAW_HTC_WRITE_BUFFERS_NUM 4 - -#define HTC_RAW_BUFFER_SIZE 1664 - -typedef struct { - int currPtr; - int length; - unsigned char data[HTC_RAW_BUFFER_SIZE]; - struct htc_packet HTCPacket; -} raw_htc_buffer; - -#ifdef CONFIG_HOST_TCMD_SUPPORT -/* - * add TCMD_MODE besides wmi and bypasswmi - * in TCMD_MODE, only few TCMD releated wmi commands - * counld be hanlder - */ -enum { - AR6000_WMI_MODE = 0, - AR6000_BYPASS_MODE, - AR6000_TCMD_MODE, - AR6000_WLAN_MODE -}; -#endif /* CONFIG_HOST_TCMD_SUPPORT */ - -struct ar_wep_key { - u8 arKeyIndex; - u8 arKeyLen; - u8 arKey[64]; -} ; - -struct ar_key { - u8 key[WLAN_MAX_KEY_LEN]; - u8 key_len; - u8 seq[IW_ENCODE_SEQ_MAX_SIZE]; - u8 seq_len; - u32 cipher; -}; - -enum { - SME_DISCONNECTED, - SME_CONNECTING, - SME_CONNECTED -}; - -struct ar_node_mapping { - u8 macAddress[6]; - u8 epId; - u8 txPending; -}; - -struct ar_cookie { - unsigned long arc_bp[2]; /* Must be first field */ - struct htc_packet HtcPkt; /* HTC packet wrapper */ - struct ar_cookie *arc_list_next; -}; - -struct ar_hb_chlng_resp { - A_TIMER timer; - u32 frequency; - u32 seqNum; - bool outstanding; - u8 missCnt; - u8 missThres; -}; - -/* Per STA data, used in AP mode */ -/*TODO: All this should move to OS independent dir */ - -#define STA_PWR_MGMT_MASK 0x1 -#define STA_PWR_MGMT_SHIFT 0x0 -#define STA_PWR_MGMT_AWAKE 0x0 -#define STA_PWR_MGMT_SLEEP 0x1 - -#define STA_SET_PWR_SLEEP(sta) (sta->flags |= (STA_PWR_MGMT_MASK << STA_PWR_MGMT_SHIFT)) -#define STA_CLR_PWR_SLEEP(sta) (sta->flags &= ~(STA_PWR_MGMT_MASK << STA_PWR_MGMT_SHIFT)) -#define STA_IS_PWR_SLEEP(sta) ((sta->flags >> STA_PWR_MGMT_SHIFT) & STA_PWR_MGMT_MASK) - -#define STA_PS_POLLED_MASK 0x1 -#define STA_PS_POLLED_SHIFT 0x1 -#define STA_SET_PS_POLLED(sta) (sta->flags |= (STA_PS_POLLED_MASK << STA_PS_POLLED_SHIFT)) -#define STA_CLR_PS_POLLED(sta) (sta->flags &= ~(STA_PS_POLLED_MASK << STA_PS_POLLED_SHIFT)) -#define STA_IS_PS_POLLED(sta) (sta->flags & (STA_PS_POLLED_MASK << STA_PS_POLLED_SHIFT)) - -typedef struct { - u16 flags; - u8 mac[ATH_MAC_LEN]; - u8 aid; - u8 keymgmt; - u8 ucipher; - u8 auth; - u8 wpa_ie[IEEE80211_MAX_IE]; - A_NETBUF_QUEUE_T psq; /* power save q */ - A_MUTEX_T psqLock; -} sta_t; - -typedef struct ar6_raw_htc { - HTC_ENDPOINT_ID arRaw2EpMapping[HTC_RAW_STREAM_NUM_MAX]; - HTC_RAW_STREAM_ID arEp2RawMapping[ENDPOINT_MAX]; - struct semaphore raw_htc_read_sem[HTC_RAW_STREAM_NUM_MAX]; - struct semaphore raw_htc_write_sem[HTC_RAW_STREAM_NUM_MAX]; - wait_queue_head_t raw_htc_read_queue[HTC_RAW_STREAM_NUM_MAX]; - wait_queue_head_t raw_htc_write_queue[HTC_RAW_STREAM_NUM_MAX]; - raw_htc_buffer raw_htc_read_buffer[HTC_RAW_STREAM_NUM_MAX][RAW_HTC_READ_BUFFERS_NUM]; - raw_htc_buffer raw_htc_write_buffer[HTC_RAW_STREAM_NUM_MAX][RAW_HTC_WRITE_BUFFERS_NUM]; - bool write_buffer_available[HTC_RAW_STREAM_NUM_MAX]; - bool read_buffer_available[HTC_RAW_STREAM_NUM_MAX]; -} AR_RAW_HTC_T; - -struct ar6_softc { - struct net_device *arNetDev; /* net_device pointer */ - void *arWmi; - int arTxPending[ENDPOINT_MAX]; - int arTotalTxDataPending; - u8 arNumDataEndPts; - bool arWmiEnabled; - bool arWmiReady; - bool arConnected; - HTC_HANDLE arHtcTarget; - void *arHifDevice; - spinlock_t arLock; - struct semaphore arSem; - int arSsidLen; - u_char arSsid[32]; - u8 arNextMode; - u8 arNetworkType; - u8 arDot11AuthMode; - u8 arAuthMode; - u8 arPairwiseCrypto; - u8 arPairwiseCryptoLen; - u8 arGroupCrypto; - u8 arGroupCryptoLen; - u8 arDefTxKeyIndex; - struct ar_wep_key arWepKeyList[WMI_MAX_KEY_INDEX + 1]; - u8 arBssid[6]; - u8 arReqBssid[6]; - u16 arChannelHint; - u16 arBssChannel; - u16 arListenIntervalB; - u16 arListenIntervalT; - struct ar6000_version arVersion; - u32 arTargetType; - s8 arRssi; - u8 arTxPwr; - bool arTxPwrSet; - s32 arBitRate; - struct net_device_stats arNetStats; - struct iw_statistics arIwStats; - s8 arNumChannels; - u16 arChannelList[32]; - u32 arRegCode; - bool statsUpdatePending; - TARGET_STATS arTargetStats; - s8 arMaxRetries; - u8 arPhyCapability; -#ifdef CONFIG_HOST_TCMD_SUPPORT - u32 arTargetMode; - void *tcmd_rx_report; - int tcmd_rx_report_len; -#endif - AR6000_WLAN_STATE arWlanState; - struct ar_node_mapping arNodeMap[MAX_NODE_NUM]; - u8 arIbssPsEnable; - u8 arNodeNum; - u8 arNexEpId; - struct ar_cookie *arCookieList; - u32 arCookieCount; - u32 arRateMask; - u8 arSkipScan; - u16 arBeaconInterval; - bool arConnectPending; - bool arWmmEnabled; - struct ar_hb_chlng_resp arHBChallengeResp; - u8 arKeepaliveConfigured; - u32 arMgmtFilter; - HTC_ENDPOINT_ID arAc2EpMapping[WMM_NUM_AC]; - bool arAcStreamActive[WMM_NUM_AC]; - u8 arAcStreamPriMap[WMM_NUM_AC]; - u8 arHiAcStreamActivePri; - u8 arEp2AcMapping[ENDPOINT_MAX]; - HTC_ENDPOINT_ID arControlEp; -#ifdef HTC_RAW_INTERFACE - AR_RAW_HTC_T *arRawHtc; -#endif - bool arNetQueueStopped; - bool arRawIfInit; - int arDeviceIndex; - struct common_credit_state_info arCreditStateInfo; - bool arWMIControlEpFull; - bool dbgLogFetchInProgress; - u8 log_buffer[DBGLOG_HOST_LOG_BUFFER_SIZE]; - u32 log_cnt; - u32 dbglog_init_done; - u32 arConnectCtrlFlags; - s32 user_savedkeys_stat; - u32 user_key_ctrl; - struct USER_SAVEDKEYS user_saved_keys; - USER_RSSI_THOLD rssi_map[12]; - u8 arUserBssFilter; - u16 ap_profile_flag; /* AP mode */ - WMI_AP_ACL g_acl; /* AP mode */ - sta_t sta_list[AP_MAX_NUM_STA]; /* AP mode */ - u8 sta_list_index; /* AP mode */ - struct ieee80211req_key ap_mode_bkey; /* AP mode */ - A_NETBUF_QUEUE_T mcastpsq; /* power save q for Mcast frames */ - A_MUTEX_T mcastpsqLock; - bool DTIMExpired; /* flag to indicate DTIM expired */ - u8 intra_bss; /* enable/disable intra bss data forward */ - void *aggr_cntxt; -#ifndef EXPORT_HCI_BRIDGE_INTERFACE - void *hcidev_info; -#endif - WMI_AP_MODE_STAT arAPStats; - u8 ap_hidden_ssid; - u8 ap_country_code[3]; - u8 ap_wmode; - u8 ap_dtim_period; - u16 ap_beacon_interval; - u16 arRTS; - u16 arACS; /* AP mode - Auto Channel Selection */ - struct htc_packet_queue amsdu_rx_buffer_queue; - bool bIsDestroyProgress; /* flag to indicate ar6k destroy is in progress */ - A_TIMER disconnect_timer; - u8 rxMetaVersion; -#ifdef WAPI_ENABLE - u8 arWapiEnable; -#endif - WMI_BTCOEX_CONFIG_EVENT arBtcoexConfig; - WMI_BTCOEX_STATS_EVENT arBtcoexStats; - s32 (*exitCallback)(void *config); /* generic callback at AR6K exit */ - struct hif_device_os_device_info osDevInfo; - struct wireless_dev *wdev; - struct cfg80211_scan_request *scan_request; - struct ar_key keys[WMI_MAX_KEY_INDEX + 1]; - u32 smeState; - u16 arWlanPowerState; - bool arWlanOff; -#ifdef CONFIG_PM - u16 arWowState; - bool arBTOff; - bool arBTSharing; - u16 arSuspendConfig; - u16 arWlanOffConfig; - u16 arWow2Config; -#endif - u8 scan_triggered; - WMI_SCAN_PARAMS_CMD scParams; -#define AR_MCAST_FILTER_MAC_ADDR_SIZE 4 - u8 mcast_filters[MAC_MAX_FILTERS_PER_LIST][AR_MCAST_FILTER_MAC_ADDR_SIZE]; - u8 bdaddr[6]; - bool scanSpecificSsid; -#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT - 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 -struct ar_virtual_interface { - struct net_device *arNetDev; /* net_device pointer */ - struct ar6_softc *arDev; /* ar device pointer */ - struct net_device *arStaNetDev; /* net_device pointer */ -}; -#endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */ - -static inline void *ar6k_priv(struct net_device *dev) -{ - return (wdev_priv(dev->ieee80211_ptr)); -} - -#define SET_HCI_BUS_TYPE(pHciDev, __bus, __type) do { \ - (pHciDev)->bus = (__bus); \ - (pHciDev)->dev_type = (__type); \ -} while(0) - -#define GET_INODE_FROM_FILEP(filp) \ - (filp)->f_path.dentry->d_inode - -#define arAc2EndpointID(ar,ac) (ar)->arAc2EpMapping[(ac)] -#define arSetAc2EndpointIDMap(ar,ac,ep) \ -{ (ar)->arAc2EpMapping[(ac)] = (ep); \ - (ar)->arEp2AcMapping[(ep)] = (ac); } -#define arEndpoint2Ac(ar,ep) (ar)->arEp2AcMapping[(ep)] - -#define arRawIfEnabled(ar) (ar)->arRawIfInit -#define arRawStream2EndpointID(ar,raw) (ar)->arRawHtc->arRaw2EpMapping[(raw)] -#define arSetRawStream2EndpointIDMap(ar,raw,ep) \ -{ (ar)->arRawHtc->arRaw2EpMapping[(raw)] = (ep); \ - (ar)->arRawHtc->arEp2RawMapping[(ep)] = (raw); } -#define arEndpoint2RawStreamID(ar,ep) (ar)->arRawHtc->arEp2RawMapping[(ep)] - -struct ar_giwscan_param { - char *current_ev; - char *end_buf; - u32 bytes_needed; - struct iw_request_info *info; -}; - -#define AR6000_STAT_INC(ar, stat) (ar->arNetStats.stat++) - -#define AR6000_SPIN_LOCK(lock, param) do { \ - if (irqs_disabled()) { \ - AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("IRQs disabled:AR6000_LOCK\n")); \ - } \ - spin_lock_bh(lock); \ -} while (0) - -#define AR6000_SPIN_UNLOCK(lock, param) do { \ - if (irqs_disabled()) { \ - AR_DEBUG_PRINTF(ATH_DEBUG_TRC,("IRQs disabled: AR6000_UNLOCK\n")); \ - } \ - spin_unlock_bh(lock); \ -} while (0) - -void ar6000_init_profile_info(struct ar6_softc *ar); -void ar6000_install_static_wep_keys(struct ar6_softc *ar); -int ar6000_init(struct net_device *dev); -int ar6000_dbglog_get_debug_logs(struct ar6_softc *ar); -void ar6000_TxDataCleanup(struct ar6_softc *ar); -int ar6000_acl_data_tx(struct sk_buff *skb, struct net_device *dev); -void ar6000_restart_endpoint(struct net_device *dev); -void ar6000_stop_endpoint(struct net_device *dev, bool keepprofile, bool getdbglogs); - -#ifdef HTC_RAW_INTERFACE - -#ifndef __user -#define __user -#endif - -int ar6000_htc_raw_open(struct ar6_softc *ar); -int ar6000_htc_raw_close(struct ar6_softc *ar); -ssize_t ar6000_htc_raw_read(struct ar6_softc *ar, - HTC_RAW_STREAM_ID StreamID, - char __user *buffer, size_t count); -ssize_t ar6000_htc_raw_write(struct ar6_softc *ar, - HTC_RAW_STREAM_ID StreamID, - char __user *buffer, size_t count); - -#endif /* HTC_RAW_INTERFACE */ - -/* AP mode */ -/*TODO: These routines should be moved to a file that is common across OS */ -sta_t * -ieee80211_find_conn(struct ar6_softc *ar, u8 *node_addr); - -sta_t * -ieee80211_find_conn_for_aid(struct ar6_softc *ar, u8 aid); - -u8 remove_sta(struct ar6_softc *ar, u8 *mac, u16 reason); - -/* HCI support */ - -#ifndef EXPORT_HCI_BRIDGE_INTERFACE -int ar6000_setup_hci(struct ar6_softc *ar); -void ar6000_cleanup_hci(struct ar6_softc *ar); -void ar6000_set_default_ar3kconfig(struct ar6_softc *ar, void *ar3kconfig); - -/* HCI bridge testing */ -int hci_test_send(struct ar6_softc *ar, struct sk_buff *skb); -#endif - -ATH_DEBUG_DECLARE_EXTERN(htc); -ATH_DEBUG_DECLARE_EXTERN(wmi); -ATH_DEBUG_DECLARE_EXTERN(bmi); -ATH_DEBUG_DECLARE_EXTERN(hif); -ATH_DEBUG_DECLARE_EXTERN(wlan); -ATH_DEBUG_DECLARE_EXTERN(misc); - -extern u8 bcast_mac[]; -extern u8 null_mac[]; - -#ifdef __cplusplus -} -#endif - -#endif /* _AR6000_H_ */ diff --git a/drivers/staging/ath6kl/os/linux/include/ar6k_pal.h b/drivers/staging/ath6kl/os/linux/include/ar6k_pal.h deleted file mode 100644 index 39e0873..0000000 --- a/drivers/staging/ath6kl/os/linux/include/ar6k_pal.h +++ /dev/null @@ -1,36 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved. -// -// The software source and binaries included in this development package are -// licensed, not sold. You, or your company, received the package under one -// or more license agreements. The rights granted to you are specifically -// listed in these license agreement(s). All other rights remain with Atheros -// Communications, Inc., its subsidiaries, or the respective owner including -// those listed on the included copyright notices. Distribution of any -// portion of this package must be in strict compliance with the license -// agreement(s) terms. -// </copyright> -// -// <summary> -// PAL driver for AR6003 -// </summary> -// -//------------------------------------------------------------------------------ -//============================================================================== -// Author(s): ="Atheros" -//============================================================================== -#ifndef _AR6K_PAL_H_ -#define _AR6K_PAL_H_ -#define HCI_GET_OP_CODE(p) (((u16)((p)[1])) << 8) | ((u16)((p)[0])) - -/* transmit packet reserve offset */ -#define TX_PACKET_RSV_OFFSET 32 -/* pal specific config structure */ -typedef bool (*ar6k_pal_recv_pkt_t)(void *pHciPalInfo, void *skb); -typedef struct ar6k_pal_config_s -{ - ar6k_pal_recv_pkt_t fpar6k_pal_recv_pkt; -}ar6k_pal_config_t; - -void register_pal_cb(ar6k_pal_config_t *palConfig_p); -#endif /* _AR6K_PAL_H_ */ diff --git a/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h b/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h deleted file mode 100644 index 184dbdb..0000000 --- a/drivers/staging/ath6kl/os/linux/include/ar6xapi_linux.h +++ /dev/null @@ -1,190 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2004-2010 Atheros Communications Inc. -// All rights reserved. -// -// -// -// 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. -// -// -// -// Author(s): ="Atheros" -//------------------------------------------------------------------------------ - -#ifndef _AR6XAPI_LINUX_H -#define _AR6XAPI_LINUX_H -#ifdef __cplusplus -extern "C" { -#endif - -struct ar6_softc; - -void ar6000_ready_event(void *devt, u8 *datap, u8 phyCap, - u32 sw_ver, u32 abi_ver); -int ar6000_control_tx(void *devt, void *osbuf, HTC_ENDPOINT_ID eid); -void ar6000_connect_event(struct ar6_softc *ar, u16 channel, - u8 *bssid, u16 listenInterval, - u16 beaconInterval, NETWORK_TYPE networkType, - u8 beaconIeLen, u8 assocReqLen, - u8 assocRespLen,u8 *assocInfo); -void ar6000_disconnect_event(struct ar6_softc *ar, u8 reason, - u8 *bssid, u8 assocRespLen, - u8 *assocInfo, u16 protocolReasonStatus); -void ar6000_tkip_micerr_event(struct ar6_softc *ar, u8 keyid, - bool ismcast); -void ar6000_bitrate_rx(void *devt, s32 rateKbps); -void ar6000_channelList_rx(void *devt, s8 numChan, u16 *chanList); -void ar6000_regDomain_event(struct ar6_softc *ar, u32 regCode); -void ar6000_txPwr_rx(void *devt, u8 txPwr); -void ar6000_keepalive_rx(void *devt, u8 configured); -void ar6000_neighborReport_event(struct ar6_softc *ar, int numAps, - WMI_NEIGHBOR_INFO *info); -void ar6000_set_numdataendpts(struct ar6_softc *ar, u32 num); -void ar6000_scanComplete_event(struct ar6_softc *ar, int status); -void ar6000_targetStats_event(struct ar6_softc *ar, u8 *ptr, u32 len); -void ar6000_rssiThreshold_event(struct ar6_softc *ar, - WMI_RSSI_THRESHOLD_VAL newThreshold, - s16 rssi); -void ar6000_reportError_event(struct ar6_softc *, WMI_TARGET_ERROR_VAL errorVal); -void ar6000_cac_event(struct ar6_softc *ar, u8 ac, u8 cac_indication, - u8 statusCode, u8 *tspecSuggestion); -void ar6000_channel_change_event(struct ar6_softc *ar, u16 oldChannel, u16 newChannel); -void ar6000_hbChallengeResp_event(struct ar6_softc *, u32 cookie, u32 source); -void -ar6000_roam_tbl_event(struct ar6_softc *ar, WMI_TARGET_ROAM_TBL *pTbl); - -void -ar6000_roam_data_event(struct ar6_softc *ar, WMI_TARGET_ROAM_DATA *p); - -void -ar6000_wow_list_event(struct ar6_softc *ar, u8 num_filters, - WMI_GET_WOW_LIST_REPLY *wow_reply); - -void ar6000_pmkid_list_event(void *devt, u8 numPMKID, - WMI_PMKID *pmkidList, u8 *bssidList); - -void ar6000_gpio_intr_rx(u32 intr_mask, u32 input_values); -void ar6000_gpio_data_rx(u32 reg_id, u32 value); -void ar6000_gpio_ack_rx(void); - -s32 rssi_compensation_calc_tcmd(u32 freq, s32 rssi, u32 totalPkt); -s16 rssi_compensation_calc(struct ar6_softc *ar, s16 rssi); -s16 rssi_compensation_reverse_calc(struct ar6_softc *ar, s16 rssi, bool Above); - -void ar6000_dbglog_init_done(struct ar6_softc *ar); - -#ifdef CONFIG_HOST_TCMD_SUPPORT -void ar6000_tcmd_rx_report_event(void *devt, u8 *results, int len); -#endif - -void ar6000_tx_retry_err_event(void *devt); - -void ar6000_snrThresholdEvent_rx(void *devt, - WMI_SNR_THRESHOLD_VAL newThreshold, - u8 snr); - -void ar6000_lqThresholdEvent_rx(void *devt, WMI_LQ_THRESHOLD_VAL range, u8 lqVal); - - -void ar6000_ratemask_rx(void *devt, u32 ratemask); - -int ar6000_get_driver_cfg(struct net_device *dev, - u16 cfgParam, - void *result); -void ar6000_bssInfo_event_rx(struct ar6_softc *ar, u8 *data, int len); - -void ar6000_dbglog_event(struct ar6_softc *ar, u32 dropped, - s8 *buffer, u32 length); - -int ar6000_dbglog_get_debug_logs(struct ar6_softc *ar); - -void ar6000_peer_event(void *devt, u8 eventCode, u8 *bssid); - -void ar6000_indicate_tx_activity(void *devt, u8 trafficClass, bool Active); -HTC_ENDPOINT_ID ar6000_ac2_endpoint_id ( void * devt, u8 ac); -u8 ar6000_endpoint_id2_ac (void * devt, HTC_ENDPOINT_ID ep ); - -void ar6000_btcoex_config_event(struct ar6_softc *ar, u8 *ptr, u32 len); - -void ar6000_btcoex_stats_event(struct ar6_softc *ar, u8 *ptr, u32 len) ; - -void ar6000_dset_open_req(void *devt, - u32 id, - u32 targ_handle, - u32 targ_reply_fn, - u32 targ_reply_arg); -void ar6000_dset_close(void *devt, u32 access_cookie); -void ar6000_dset_data_req(void *devt, - u32 access_cookie, - u32 offset, - u32 length, - u32 targ_buf, - u32 targ_reply_fn, - u32 targ_reply_arg); - - -#if defined(CONFIG_TARGET_PROFILE_SUPPORT) -void prof_count_rx(unsigned int addr, unsigned int count); -#endif - -u32 ar6000_getnodeAge (void); - -u32 ar6000_getclkfreq (void); - -int ar6000_ap_mode_profile_commit(struct ar6_softc *ar); - -struct ieee80211req_wpaie; -int -ar6000_ap_mode_get_wpa_ie(struct ar6_softc *ar, struct ieee80211req_wpaie *wpaie); - -int is_iwioctl_allowed(u8 mode, u16 cmd); - -int is_xioctl_allowed(u8 mode, int cmd); - -void ar6000_pspoll_event(struct ar6_softc *ar,u8 aid); - -void ar6000_dtimexpiry_event(struct ar6_softc *ar); - -void ar6000_aggr_rcv_addba_req_evt(struct ar6_softc *ar, WMI_ADDBA_REQ_EVENT *cmd); -void ar6000_aggr_rcv_addba_resp_evt(struct ar6_softc *ar, WMI_ADDBA_RESP_EVENT *cmd); -void ar6000_aggr_rcv_delba_req_evt(struct ar6_softc *ar, WMI_DELBA_EVENT *cmd); -void ar6000_hci_event_rcv_evt(struct ar6_softc *ar, WMI_HCI_EVENT *cmd); - -#ifdef WAPI_ENABLE -int ap_set_wapi_key(struct ar6_softc *ar, void *ik); -void ap_wapi_rekey_event(struct ar6_softc *ar, u8 type, u8 *mac); -#endif - -int ar6000_connect_to_ap(struct ar6_softc *ar); -int ar6000_disconnect(struct ar6_softc *ar); -int ar6000_update_wlan_pwr_state(struct ar6_softc *ar, AR6000_WLAN_STATE state, bool suspending); -int ar6000_set_wlan_state(struct ar6_softc *ar, AR6000_WLAN_STATE state); -int ar6000_set_bt_hw_state(struct ar6_softc *ar, u32 state); - -#ifdef CONFIG_PM -int ar6000_suspend_ev(void *context); -int ar6000_resume_ev(void *context); -int ar6000_power_change_ev(void *context, u32 config); -void ar6000_check_wow_status(struct ar6_softc *ar, struct sk_buff *skb, bool isEvent); -#endif - -#ifdef CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT -int ar6000_add_ap_interface(struct ar6_softc *ar, char *ifname); -int ar6000_remove_ap_interface(struct ar6_softc *ar); -#endif /* CONFIG_AP_VIRTUAL_ADAPTER_SUPPORT */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h b/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h deleted file mode 100644 index 3d5f01d..0000000 --- a/drivers/staging/ath6kl/os/linux/include/athdrv_linux.h +++ /dev/null @@ -1,1217 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2004-2010 Atheros Communications Inc. -// All rights reserved. -// -// -// -// 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. -// -// -// -// Author(s): ="Atheros" -//------------------------------------------------------------------------------ - -#ifndef _ATHDRV_LINUX_H -#define _ATHDRV_LINUX_H - -#ifdef __cplusplus -extern "C" { -#endif - - -/* - * There are two types of ioctl's here: Standard ioctls and - * eXtended ioctls. All extended ioctls (XIOCTL) are multiplexed - * off of the single ioctl command, AR6000_IOCTL_EXTENDED. The - * arguments for every XIOCTL starts with a 32-bit command word - * that is used to select which extended ioctl is in use. After - * the command word are command-specific arguments. - */ - -/* Linux standard Wireless Extensions, private ioctl interfaces */ -#define IEEE80211_IOCTL_SETPARAM (SIOCIWFIRSTPRIV+0) -#define IEEE80211_IOCTL_SETKEY (SIOCIWFIRSTPRIV+1) -#define IEEE80211_IOCTL_DELKEY (SIOCIWFIRSTPRIV+2) -#define IEEE80211_IOCTL_SETMLME (SIOCIWFIRSTPRIV+3) -#define IEEE80211_IOCTL_ADDPMKID (SIOCIWFIRSTPRIV+4) -#define IEEE80211_IOCTL_SETOPTIE (SIOCIWFIRSTPRIV+5) -//#define IEEE80211_IOCTL_GETPARAM (SIOCIWFIRSTPRIV+6) -//#define IEEE80211_IOCTL_SETWMMPARAMS (SIOCIWFIRSTPRIV+7) -//#define IEEE80211_IOCTL_GETWMMPARAMS (SIOCIWFIRSTPRIV+8) -//#define IEEE80211_IOCTL_GETOPTIE (SIOCIWFIRSTPRIV+9) -//#define IEEE80211_IOCTL_SETAUTHALG (SIOCIWFIRSTPRIV+10) -#define IEEE80211_IOCTL_LASTONE (SIOCIWFIRSTPRIV+10) - - - -/* ====WMI Ioctls==== */ -/* - * - * Many ioctls simply provide WMI services to application code: - * an application makes such an ioctl call with a set of arguments - * that are packaged into the corresponding WMI message, and sent - * to the Target. - */ - -#define AR6000_IOCTL_WMI_GETREV (SIOCIWFIRSTPRIV+11) -/* - * arguments: - * ar6000_version *revision - */ - -#define AR6000_IOCTL_WMI_SETPWR (SIOCIWFIRSTPRIV+12) -/* - * arguments: - * WMI_POWER_MODE_CMD pwrModeCmd (see include/wmi.h) - * uses: WMI_SET_POWER_MODE_CMDID - */ - -#define AR6000_IOCTL_WMI_SETSCAN (SIOCIWFIRSTPRIV+13) -/* - * arguments: - * WMI_SCAN_PARAMS_CMD scanParams (see include/wmi.h) - * uses: WMI_SET_SCAN_PARAMS_CMDID - */ - -#define AR6000_IOCTL_WMI_SETLISTENINT (SIOCIWFIRSTPRIV+14) -/* - * arguments: - * UINT32 listenInterval - * uses: WMI_SET_LISTEN_INT_CMDID - */ - -#define AR6000_IOCTL_WMI_SETBSSFILTER (SIOCIWFIRSTPRIV+15) -/* - * arguments: - * WMI_BSS_FILTER filter (see include/wmi.h) - * uses: WMI_SET_BSS_FILTER_CMDID - */ - -#define AR6000_IOCTL_WMI_SET_CHANNELPARAMS (SIOCIWFIRSTPRIV+16) -/* - * arguments: - * WMI_CHANNEL_PARAMS_CMD chParams - * uses: WMI_SET_CHANNEL_PARAMS_CMDID - */ - -#define AR6000_IOCTL_WMI_SET_PROBEDSSID (SIOCIWFIRSTPRIV+17) -/* - * arguments: - * WMI_PROBED_SSID_CMD probedSsids (see include/wmi.h) - * uses: WMI_SETPROBED_SSID_CMDID - */ - -#define AR6000_IOCTL_WMI_SET_PMPARAMS (SIOCIWFIRSTPRIV+18) -/* - * arguments: - * WMI_POWER_PARAMS_CMD powerParams (see include/wmi.h) - * uses: WMI_SET_POWER_PARAMS_CMDID - */ - -#define AR6000_IOCTL_WMI_SET_BADAP (SIOCIWFIRSTPRIV+19) -/* - * arguments: - * WMI_ADD_BAD_AP_CMD badAPs (see include/wmi.h) - * uses: WMI_ADD_BAD_AP_CMDID - */ - -#define AR6000_IOCTL_WMI_GET_QOS_QUEUE (SIOCIWFIRSTPRIV+20) -/* - * arguments: - * ar6000_queuereq queueRequest (see below) - */ - -#define AR6000_IOCTL_WMI_CREATE_QOS (SIOCIWFIRSTPRIV+21) -/* - * arguments: - * WMI_CREATE_PSTREAM createPstreamCmd (see include/wmi.h) - * uses: WMI_CREATE_PSTREAM_CMDID - */ - -#define AR6000_IOCTL_WMI_DELETE_QOS (SIOCIWFIRSTPRIV+22) -/* - * arguments: - * WMI_DELETE_PSTREAM_CMD deletePstreamCmd (see include/wmi.h) - * uses: WMI_DELETE_PSTREAM_CMDID - */ - -#define AR6000_IOCTL_WMI_SET_SNRTHRESHOLD (SIOCIWFIRSTPRIV+23) -/* - * arguments: - * WMI_SNR_THRESHOLD_PARAMS_CMD thresholdParams (see include/wmi.h) - * uses: WMI_SNR_THRESHOLD_PARAMS_CMDID - */ - -#define AR6000_IOCTL_WMI_SET_ERROR_REPORT_BITMASK (SIOCIWFIRSTPRIV+24) -/* - * arguments: - * WMI_TARGET_ERROR_REPORT_BITMASK errorReportBitMask (see include/wmi.h) - * uses: WMI_TARGET_ERROR_REPORT_BITMASK_CMDID - */ - -#define AR6000_IOCTL_WMI_GET_TARGET_STATS (SIOCIWFIRSTPRIV+25) -/* - * arguments: - * TARGET_STATS *targetStats (see below) - * uses: WMI_GET_STATISTICS_CMDID - */ - -#define AR6000_IOCTL_WMI_SET_ASSOC_INFO (SIOCIWFIRSTPRIV+26) -/* - * arguments: - * WMI_SET_ASSOC_INFO_CMD setAssocInfoCmd - * uses: WMI_SET_ASSOC_INFO_CMDID - */ - -#define AR6000_IOCTL_WMI_SET_ACCESS_PARAMS (SIOCIWFIRSTPRIV+27) -/* - * arguments: - * WMI_SET_ACCESS_PARAMS_CMD setAccessParams (see include/wmi.h) - * uses: WMI_SET_ACCESS_PARAMS_CMDID - */ - -#define AR6000_IOCTL_WMI_SET_BMISS_TIME (SIOCIWFIRSTPRIV+28) -/* - * arguments: - * UINT32 beaconMissTime - * uses: WMI_SET_BMISS_TIME_CMDID - */ - -#define AR6000_IOCTL_WMI_SET_DISC_TIMEOUT (SIOCIWFIRSTPRIV+29) -/* - * arguments: - * WMI_DISC_TIMEOUT_CMD disconnectTimeoutCmd (see include/wmi.h) - * uses: WMI_SET_DISC_TIMEOUT_CMDID - */ - -#define AR6000_IOCTL_WMI_SET_IBSS_PM_CAPS (SIOCIWFIRSTPRIV+30) -/* - * arguments: - * WMI_IBSS_PM_CAPS_CMD ibssPowerMgmtCapsCmd - * uses: WMI_SET_IBSS_PM_CAPS_CMDID - */ - -/* - * There is a very small space available for driver-private - * wireless ioctls. In order to circumvent this limitation, - * we multiplex a bunch of ioctls (XIOCTLs) on top of a - * single AR6000_IOCTL_EXTENDED ioctl. - */ -#define AR6000_IOCTL_EXTENDED (SIOCIWFIRSTPRIV+31) - - -/* ====BMI Extended Ioctls==== */ - -#define AR6000_XIOCTL_BMI_DONE 1 -/* - * arguments: - * UINT32 cmd (AR6000_XIOCTL_BMI_DONE) - * uses: BMI_DONE - */ - -#define AR6000_XIOCTL_BMI_READ_MEMORY 2 -/* - * arguments: - * union { - * struct { - * UINT32 cmd (AR6000_XIOCTL_BMI_READ_MEMORY) - * UINT32 address - * UINT32 length - * } - * char results[length] - * } - * uses: BMI_READ_MEMORY - */ - -#define AR6000_XIOCTL_BMI_WRITE_MEMORY 3 -/* - * arguments: - * UINT32 cmd (AR6000_XIOCTL_BMI_WRITE_MEMORY) - * UINT32 address - * UINT32 length - * char data[length] - * uses: BMI_WRITE_MEMORY - */ - -#define AR6000_XIOCTL_BMI_EXECUTE 4 -/* - * arguments: - * UINT32 cmd (AR6000_XIOCTL_BMI_EXECUTE) - * UINT32 TargetAddress - * UINT32 parameter - * uses: BMI_EXECUTE - */ - -#define AR6000_XIOCTL_BMI_SET_APP_START 5 -/* - * arguments: - * UINT32 cmd (AR6000_XIOCTL_BMI_SET_APP_START) - * UINT32 TargetAddress - * uses: BMI_SET_APP_START - */ - -#define AR6000_XIOCTL_BMI_READ_SOC_REGISTER 6 -/* - * arguments: - * union { - * struct { - * UINT32 cmd (AR6000_XIOCTL_BMI_READ_SOC_REGISTER) - * UINT32 TargetAddress, 32-bit aligned - * } - * UINT32 result - * } - * uses: BMI_READ_SOC_REGISTER - */ - -#define AR6000_XIOCTL_BMI_WRITE_SOC_REGISTER 7 -/* - * arguments: - * struct { - * UINT32 cmd (AR6000_XIOCTL_BMI_WRITE_SOC_REGISTER) - * UINT32 TargetAddress, 32-bit aligned - * UINT32 newValue - * } - * uses: BMI_WRITE_SOC_REGISTER - */ - -#define AR6000_XIOCTL_BMI_TEST 8 -/* - * arguments: - * UINT32 cmd (AR6000_XIOCTL_BMI_TEST) - * UINT32 address - * UINT32 length - * UINT32 count - */ - - - -/* Historical Host-side DataSet support */ -#define AR6000_XIOCTL_UNUSED9 9 -#define AR6000_XIOCTL_UNUSED10 10 -#define AR6000_XIOCTL_UNUSED11 11 - -/* ====Misc Extended Ioctls==== */ - -#define AR6000_XIOCTL_FORCE_TARGET_RESET 12 -/* - * arguments: - * UINT32 cmd (AR6000_XIOCTL_FORCE_TARGET_RESET) - */ - - -#ifdef HTC_RAW_INTERFACE -/* HTC Raw Interface Ioctls */ -#define AR6000_XIOCTL_HTC_RAW_OPEN 13 -/* - * arguments: - * UINT32 cmd (AR6000_XIOCTL_HTC_RAW_OPEN) - */ - -#define AR6000_XIOCTL_HTC_RAW_CLOSE 14 -/* - * arguments: - * UINT32 cmd (AR6000_XIOCTL_HTC_RAW_CLOSE) - */ - -#define AR6000_XIOCTL_HTC_RAW_READ 15 -/* - * arguments: - * union { - * struct { - * UINT32 cmd (AR6000_XIOCTL_HTC_RAW_READ) - * UINT32 mailboxID - * UINT32 length - * } - * results[length] - * } - */ - -#define AR6000_XIOCTL_HTC_RAW_WRITE 16 -/* - * arguments: - * UINT32 cmd (AR6000_XIOCTL_HTC_RAW_WRITE) - * UINT32 mailboxID - * UINT32 length - * char buffer[length] - */ -#endif /* HTC_RAW_INTERFACE */ - -#define AR6000_XIOCTL_CHECK_TARGET_READY 17 -/* - * arguments: - * UINT32 cmd (AR6000_XIOCTL_CHECK_TARGET_READY) - */ - - - -/* ====GPIO (General Purpose I/O) Extended Ioctls==== */ - -#define AR6000_XIOCTL_GPIO_OUTPUT_SET 18 -/* - * arguments: - * UINT32 cmd (AR6000_XIOCTL_GPIO_OUTPUT_SET) - * ar6000_gpio_output_set_cmd_s (see below) - * uses: WMIX_GPIO_OUTPUT_SET_CMDID - */ - -#define AR6000_XIOCTL_GPIO_INPUT_GET 19 -/* - * arguments: - * UINT32 cmd (AR6000_XIOCTL_GPIO_INPUT_GET) - * uses: WMIX_GPIO_INPUT_GET_CMDID - */ - -#define AR6000_XIOCTL_GPIO_REGISTER_SET 20 -/* - * arguments: - * UINT32 cmd (AR6000_XIOCTL_GPIO_REGISTER_SET) - * ar6000_gpio_register_cmd_s (see below) - * uses: WMIX_GPIO_REGISTER_SET_CMDID - */ - -#define AR6000_XIOCTL_GPIO_REGISTER_GET 21 -/* - * arguments: - * UINT32 cmd (AR6000_XIOCTL_GPIO_REGISTER_GET) - * ar6000_gpio_register_cmd_s (see below) - * uses: WMIX_GPIO_REGISTER_GET_CMDID - */ - -#define AR6000_XIOCTL_GPIO_INTR_ACK 22 -/* - * arguments: - * UINT32 cmd (AR6000_XIOCTL_GPIO_INTR_ACK) - * ar6000_cpio_intr_ack_cmd_s (see below) - * uses: WMIX_GPIO_INTR_ACK_CMDID - */ - -#define AR6000_XIOCTL_GPIO_INTR_WAIT 23 -/* - * arguments: - * UINT32 cmd (AR6000_XIOCTL_GPIO_INTR_WAIT) - */ - - - -/* ====more wireless commands==== */ - -#define AR6000_XIOCTL_SET_ADHOC_BSSID 24 -/* - * arguments: - * UINT32 cmd (AR6000_XIOCTL_SET_ADHOC_BSSID) - * WMI_SET_ADHOC_BSSID_CMD setAdHocBssidCmd (see include/wmi.h) - */ - -#define AR6000_XIOCTL_SET_OPT_MODE 25 -/* - * arguments: - * UINT32 cmd (AR6000_XIOCTL_SET_OPT_MODE) - * WMI_SET_OPT_MODE_CMD setOptModeCmd (see include/wmi.h) - * uses: WMI_SET_OPT_MODE_CMDID - */ - -#define AR6000_XIOCTL_OPT_SEND_FRAME 26 -/* - * arguments: - * UINT32 cmd (AR6000_XIOCTL_OPT_SEND_FRAME) - * WMI_OPT_TX_FRAME_CMD optTxFrameCmd (see include/wmi.h) - * uses: WMI_OPT_TX_FRAME_CMDID - */ - -#define AR6000_XIOCTL_SET_BEACON_INTVAL 27 -/* - * arguments: - * UINT32 cmd (AR6000_XIOCTL_SET_BEACON_INTVAL) - * WMI_BEACON_INT_CMD beaconIntCmd (see include/wmi.h) - * uses: WMI_SET_BEACON_INT_CMDID - */ - - -#define IEEE80211_IOCTL_SETAUTHALG 28 - - -#define AR6000_XIOCTL_SET_VOICE_PKT_SIZE 29 -/* - * arguments: - * UINT32 cmd (AR6000_XIOCTL_SET_VOICE_PKT_SIZE) - * WMI_SET_VOICE_PKT_SIZE_CMD setVoicePktSizeCmd (see include/wmi.h) - * uses: WMI_SET_VOICE_PKT_SIZE_CMDID - */ - - -#define AR6000_XIOCTL_SET_MAX_SP 30 -/* - * arguments: - * UINT32 cmd (AR6000_XIOCTL_SET_MAX_SP) - * WMI_SET_MAX_SP_LEN_CMD maxSPLen(see include/wmi.h) - * uses: WMI_SET_MAX_SP_LEN_CMDID - */ - -#define AR6000_XIOCTL_WMI_GET_ROAM_TBL 31 - -#define AR6000_XIOCTL_WMI_SET_ROAM_CTRL 32 - -#define AR6000_XIOCTRL_WMI_SET_POWERSAVE_TIMERS 33 - - -/* - * arguments: - * UINT32 cmd (AR6000_XIOCTRL_WMI_SET_POWERSAVE_TIMERS) - * WMI_SET_POWERSAVE_TIMERS_CMD powerSaveTimers(see include/wmi.h) - * WMI_SET_POWERSAVE_TIMERS_CMDID - */ - -#define AR6000_XIOCTRL_WMI_GET_POWER_MODE 34 -/* - * arguments: - * UINT32 cmd (AR6000_XIOCTRL_WMI_GET_POWER_MODE) - */ - -#define AR6000_XIOCTRL_WMI_SET_WLAN_STATE 35 -typedef enum { - WLAN_DISABLED, - WLAN_ENABLED -} AR6000_WLAN_STATE; -/* - * arguments: - * enable/disable - */ - -#define AR6000_XIOCTL_WMI_GET_ROAM_DATA 36 - -#define AR6000_XIOCTL_WMI_SETRETRYLIMITS 37 -/* - * arguments: - * WMI_SET_RETRY_LIMITS_CMD ibssSetRetryLimitsCmd - * uses: WMI_SET_RETRY_LIMITS_CMDID - */ - -#ifdef CONFIG_HOST_TCMD_SUPPORT -/* ====extended commands for radio test ==== */ - -#define AR6000_XIOCTL_TCMD_CONT_TX 38 -/* - * arguments: - * UINT32 cmd (AR6000_XIOCTL_TCMD_CONT_TX) - * WMI_TCMD_CONT_TX_CMD contTxCmd (see include/wmi.h) - * uses: WMI_TCMD_CONT_TX_CMDID - */ - -#define AR6000_XIOCTL_TCMD_CONT_RX 39 -/* - * arguments: - * UINT32 cmd (AR6000_XIOCTL_TCMD_CONT_RX) - * WMI_TCMD_CONT_RX_CMD rxCmd (see include/wmi.h) - * uses: WMI_TCMD_CONT_RX_CMDID - */ - -#define AR6000_XIOCTL_TCMD_PM 40 -/* - * arguments: - * UINT32 cmd (AR6000_XIOCTL_TCMD_PM) - * WMI_TCMD_PM_CMD pmCmd (see include/wmi.h) - * uses: WMI_TCMD_PM_CMDID - */ - -#endif /* CONFIG_HOST_TCMD_SUPPORT */ - -#define AR6000_XIOCTL_WMI_STARTSCAN 41 -/* - * arguments: - * UINT32 cmd (AR6000_XIOCTL_WMI_STARTSCAN) - * UINT8 scanType - * UINT8 scanConnected - * u32 forceFgScan - * uses: WMI_START_SCAN_CMDID - */ - -#define AR6000_XIOCTL_WMI_SETFIXRATES 42 - -#define AR6000_XIOCTL_WMI_GETFIXRATES 43 - - -#define AR6000_XIOCTL_WMI_SET_RSSITHRESHOLD 44 -/* - * arguments: - * WMI_RSSI_THRESHOLD_PARAMS_CMD thresholdParams (see include/wmi.h) - * uses: WMI_RSSI_THRESHOLD_PARAMS_CMDID - */ - -#define AR6000_XIOCTL_WMI_CLR_RSSISNR 45 -/* - * arguments: - * WMI_CLR_RSSISNR_CMD thresholdParams (see include/wmi.h) - * uses: WMI_CLR_RSSISNR_CMDID - */ - -#define AR6000_XIOCTL_WMI_SET_LQTHRESHOLD 46 -/* - * arguments: - * WMI_LQ_THRESHOLD_PARAMS_CMD thresholdParams (see include/wmi.h) - * uses: WMI_LQ_THRESHOLD_PARAMS_CMDID - */ - -#define AR6000_XIOCTL_WMI_SET_RTS 47 -/* - * arguments: - * WMI_SET_RTS_MODE_CMD (see include/wmi.h) - * uses: WMI_SET_RTS_MODE_CMDID - */ - -#define AR6000_XIOCTL_WMI_SET_LPREAMBLE 48 - -#define AR6000_XIOCTL_WMI_SET_AUTHMODE 49 -/* - * arguments: - * UINT32 cmd (AR6000_XIOCTL_WMI_SET_AUTHMODE) - * UINT8 mode - * uses: WMI_SET_RECONNECT_AUTH_MODE_CMDID - */ - -#define AR6000_XIOCTL_WMI_SET_REASSOCMODE 50 - -/* - * arguments: - * UINT32 cmd (AR6000_XIOCTL_WMI_SET_WMM) - * UINT8 mode - * uses: WMI_SET_WMM_CMDID - */ -#define AR6000_XIOCTL_WMI_SET_WMM 51 - -/* - * arguments: - * UINT32 cmd (AR6000_XIOCTL_WMI_SET_HB_CHALLENGE_RESP_PARAMS) - * UINT32 frequency - * UINT8 threshold - */ -#define AR6000_XIOCTL_WMI_SET_HB_CHALLENGE_RESP_PARAMS 52 - -/* - * arguments: - * UINT32 cmd (AR6000_XIOCTL_WMI_GET_HB_CHALLENGE_RESP) - * UINT32 cookie - */ -#define AR6000_XIOCTL_WMI_GET_HB_CHALLENGE_RESP 53 - -/* - * arguments: - * UINT32 cmd (AR6000_XIOCTL_WMI_GET_RD) - * UINT32 regDomain - */ -#define AR6000_XIOCTL_WMI_GET_RD 54 - -#define AR6000_XIOCTL_DIAG_READ 55 - -#define AR6000_XIOCTL_DIAG_WRITE 56 - -/* - * arguments cmd (AR6000_XIOCTL_SET_TXOP) - * WMI_TXOP_CFG txopEnable - */ -#define AR6000_XIOCTL_WMI_SET_TXOP 57 - -/* - * arguments: - * UINT32 cmd (AR6000_XIOCTL_USER_SETKEYS) - * UINT32 keyOpCtrl - * uses struct ar6000_user_setkeys_info - */ -#define AR6000_XIOCTL_USER_SETKEYS 58 - -#define AR6000_XIOCTL_WMI_SET_KEEPALIVE 59 -/* - * arguments: - * UINT8 cmd (AR6000_XIOCTL_WMI_SET_KEEPALIVE) - * UINT8 keepaliveInterval - * uses: WMI_SET_KEEPALIVE_CMDID - */ - -#define AR6000_XIOCTL_WMI_GET_KEEPALIVE 60 -/* - * arguments: - * UINT8 cmd (AR6000_XIOCTL_WMI_GET_KEEPALIVE) - * UINT8 keepaliveInterval - * u32 configured - * uses: WMI_GET_KEEPALIVE_CMDID - */ - -/* ====ROM Patching Extended Ioctls==== */ - -#define AR6000_XIOCTL_BMI_ROMPATCH_INSTALL 61 -/* - * arguments: - * union { - * struct { - * UINT32 cmd (AR6000_XIOCTL_BMI_ROMPATCH_INSTALL) - * UINT32 ROM Address - * UINT32 RAM Address - * UINT32 number of bytes - * UINT32 activate? (0 or 1) - * } - * u32 resulting rompatch ID - * } - * uses: BMI_ROMPATCH_INSTALL - */ - -#define AR6000_XIOCTL_BMI_ROMPATCH_UNINSTALL 62 -/* - * arguments: - * struct { - * UINT32 cmd (AR6000_XIOCTL_BMI_ROMPATCH_UNINSTALL) - * UINT32 rompatch ID - * } - * uses: BMI_ROMPATCH_UNINSTALL - */ - -#define AR6000_XIOCTL_BMI_ROMPATCH_ACTIVATE 63 -/* - * arguments: - * struct { - * UINT32 cmd (AR6000_XIOCTL_BMI_ROMPATCH_ACTIVATE) - * UINT32 rompatch count - * UINT32 rompatch IDs[rompatch count] - * } - * uses: BMI_ROMPATCH_ACTIVATE - */ - -#define AR6000_XIOCTL_BMI_ROMPATCH_DEACTIVATE 64 -/* - * arguments: - * struct { - * UINT32 cmd (AR6000_XIOCTL_BMI_ROMPATCH_DEACTIVATE) - * UINT32 rompatch count - * UINT32 rompatch IDs[rompatch count] - * } - * uses: BMI_ROMPATCH_DEACTIVATE - */ - -#define AR6000_XIOCTL_WMI_SET_APPIE 65 -/* - * arguments: - * struct { - * UINT32 cmd (AR6000_XIOCTL_WMI_SET_APPIE) - * UINT32 app_frmtype; - * UINT32 app_buflen; - * UINT8 app_buf[]; - * } - */ -#define AR6000_XIOCTL_WMI_SET_MGMT_FRM_RX_FILTER 66 -/* - * arguments: - * u32 filter_type; - */ - -#define AR6000_XIOCTL_DBGLOG_CFG_MODULE 67 - -#define AR6000_XIOCTL_DBGLOG_GET_DEBUG_LOGS 68 - -#define AR6000_XIOCTL_WMI_SET_WSC_STATUS 70 -/* - * arguments: - * u32 wsc_status; - * (WSC_REG_INACTIVE or WSC_REG_ACTIVE) - */ - -/* - * arguments: - * struct { - * u8 streamType; - * u8 status; - * } - * uses: WMI_SET_BT_STATUS_CMDID - */ -#define AR6000_XIOCTL_WMI_SET_BT_STATUS 71 - -/* - * arguments: - * struct { - * u8 paramType; - * union { - * u8 noSCOPkts; - * BT_PARAMS_A2DP a2dpParams; - * BT_COEX_REGS regs; - * }; - * } - * uses: WMI_SET_BT_PARAM_CMDID - */ -#define AR6000_XIOCTL_WMI_SET_BT_PARAMS 72 - -#define AR6000_XIOCTL_WMI_SET_HOST_SLEEP_MODE 73 -#define AR6000_XIOCTL_WMI_SET_WOW_MODE 74 -#define AR6000_XIOCTL_WMI_GET_WOW_LIST 75 -#define AR6000_XIOCTL_WMI_ADD_WOW_PATTERN 76 -#define AR6000_XIOCTL_WMI_DEL_WOW_PATTERN 77 - - - -#define AR6000_XIOCTL_TARGET_INFO 78 -/* - * arguments: - * UINT32 cmd (AR6000_XIOCTL_TARGET_INFO) - * u32 TargetVersion (returned) - * u32 TargetType (returned) - * (See also bmi_msg.h target_ver and target_type) - */ - -#define AR6000_XIOCTL_DUMP_HTC_CREDIT_STATE 79 -/* - * arguments: - * none - */ - -#define AR6000_XIOCTL_TRAFFIC_ACTIVITY_CHANGE 80 -/* - * This ioctl is used to emulate traffic activity - * timeouts. Activity/inactivity will trigger the driver - * to re-balance credits. - * - * arguments: - * ar6000_traffic_activity_change - */ - -#define AR6000_XIOCTL_WMI_SET_CONNECT_CTRL_FLAGS 81 -/* - * This ioctl is used to set the connect control flags - * - * arguments: - * u32 connectCtrlFlags - */ - -#define AR6000_XIOCTL_WMI_SET_AKMP_PARAMS 82 -/* - * This IOCTL sets any Authentication,Key Management and Protection - * related parameters. This is used along with the information set in - * Connect Command. - * Currently this enables Multiple PMKIDs to an AP. - * - * arguments: - * struct { - * u32 akmpInfo; - * } - * uses: WMI_SET_AKMP_PARAMS_CMD - */ - -#define AR6000_XIOCTL_WMI_GET_PMKID_LIST 83 - -#define AR6000_XIOCTL_WMI_SET_PMKID_LIST 84 -/* - * This IOCTL is used to set a list of PMKIDs. This list of - * PMKIDs is used in the [Re]AssocReq Frame. This list is used - * only if the MultiPMKID option is enabled via the - * AR6000_XIOCTL_WMI_SET_AKMP_PARAMS IOCTL. - * - * arguments: - * struct { - * u32 numPMKID; - * WMI_PMKID pmkidList[WMI_MAX_PMKID_CACHE]; - * } - * uses: WMI_SET_PMKIDLIST_CMD - */ - -#define AR6000_XIOCTL_WMI_SET_PARAMS 85 -#define AR6000_XIOCTL_WMI_SET_MCAST_FILTER 86 -#define AR6000_XIOCTL_WMI_DEL_MCAST_FILTER 87 - - -/* Historical DSETPATCH support for INI patches */ -#define AR6000_XIOCTL_UNUSED90 90 - - -/* Support LZ-compressed firmware download */ -#define AR6000_XIOCTL_BMI_LZ_STREAM_START 91 -/* - * arguments: - * UINT32 cmd (AR6000_XIOCTL_BMI_LZ_STREAM_START) - * UINT32 address - * uses: BMI_LZ_STREAM_START - */ - -#define AR6000_XIOCTL_BMI_LZ_DATA 92 -/* - * arguments: - * UINT32 cmd (AR6000_XIOCTL_BMI_LZ_DATA) - * UINT32 length - * char data[length] - * uses: BMI_LZ_DATA - */ - -#define AR6000_XIOCTL_PROF_CFG 93 -/* - * arguments: - * u32 period - * u32 nbins - */ - -#define AR6000_XIOCTL_PROF_ADDR_SET 94 -/* - * arguments: - * u32 Target address - */ - -#define AR6000_XIOCTL_PROF_START 95 - -#define AR6000_XIOCTL_PROF_STOP 96 - -#define AR6000_XIOCTL_PROF_COUNT_GET 97 - -#define AR6000_XIOCTL_WMI_ABORT_SCAN 98 - -/* - * AP mode - */ -#define AR6000_XIOCTL_AP_GET_STA_LIST 99 - -#define AR6000_XIOCTL_AP_HIDDEN_SSID 100 - -#define AR6000_XIOCTL_AP_SET_NUM_STA 101 - -#define AR6000_XIOCTL_AP_SET_ACL_MAC 102 - -#define AR6000_XIOCTL_AP_GET_ACL_LIST 103 - -#define AR6000_XIOCTL_AP_COMMIT_CONFIG 104 - -#define IEEE80211_IOCTL_GETWPAIE 105 - -#define AR6000_XIOCTL_AP_CONN_INACT_TIME 106 - -#define AR6000_XIOCTL_AP_PROT_SCAN_TIME 107 - -#define AR6000_XIOCTL_AP_SET_COUNTRY 108 - -#define AR6000_XIOCTL_AP_SET_DTIM 109 - - - - -#define AR6000_XIOCTL_WMI_TARGET_EVENT_REPORT 110 - -#define AR6000_XIOCTL_SET_IP 111 - -#define AR6000_XIOCTL_AP_SET_ACL_POLICY 112 - -#define AR6000_XIOCTL_AP_INTRA_BSS_COMM 113 - -#define AR6000_XIOCTL_DUMP_MODULE_DEBUG_INFO 114 - -#define AR6000_XIOCTL_MODULE_DEBUG_SET_MASK 115 - -#define AR6000_XIOCTL_MODULE_DEBUG_GET_MASK 116 - -#define AR6000_XIOCTL_DUMP_RCV_AGGR_STATS 117 - -#define AR6000_XIOCTL_SET_HT_CAP 118 - -#define AR6000_XIOCTL_SET_HT_OP 119 - -#define AR6000_XIOCTL_AP_GET_STAT 120 - -#define AR6000_XIOCTL_SET_TX_SELECT_RATES 121 - -#define AR6000_XIOCTL_SETUP_AGGR 122 - -#define AR6000_XIOCTL_ALLOW_AGGR 123 - -#define AR6000_XIOCTL_AP_GET_HIDDEN_SSID 124 - -#define AR6000_XIOCTL_AP_GET_COUNTRY 125 - -#define AR6000_XIOCTL_AP_GET_WMODE 126 - -#define AR6000_XIOCTL_AP_GET_DTIM 127 - -#define AR6000_XIOCTL_AP_GET_BINTVL 128 - -#define AR6000_XIOCTL_AP_GET_RTS 129 - -#define AR6000_XIOCTL_DELE_AGGR 130 - -#define AR6000_XIOCTL_FETCH_TARGET_REGS 131 - -#define AR6000_XIOCTL_HCI_CMD 132 - -#define AR6000_XIOCTL_ACL_DATA 133 /* used to be used for PAL */ - -#define AR6000_XIOCTL_WLAN_CONN_PRECEDENCE 134 - -#define AR6000_XIOCTL_AP_SET_11BG_RATESET 135 - -/* - * arguments: - * WMI_AP_PS_CMD apPsCmd - * uses: WMI_AP_PS_CMDID - */ - -#define AR6000_XIOCTL_WMI_SET_AP_PS 136 - -#define AR6000_XIOCTL_WMI_MCAST_FILTER 137 - -#define AR6000_XIOCTL_WMI_SET_BTCOEX_FE_ANT 138 - -#define AR6000_XIOCTL_WMI_SET_BTCOEX_COLOCATED_BT_DEV 139 - -#define AR6000_XIOCTL_WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG 140 - -#define AR6000_XIOCTL_WMI_SET_BTCOEX_SCO_CONFIG 141 - -#define AR6000_XIOCTL_WMI_SET_BTCOEX_A2DP_CONFIG 142 - -#define AR6000_XIOCTL_WMI_SET_BTCOEX_ACLCOEX_CONFIG 143 - -#define AR6000_XIOCTL_WMI_SET_BTCOEX_DEBUG 144 - -#define AR6000_XIOCTL_WMI_SET_BT_OPERATING_STATUS 145 - -#define AR6000_XIOCTL_WMI_GET_BTCOEX_CONFIG 146 - -#define AR6000_XIOCTL_WMI_GET_BTCOEX_STATS 147 -/* - * arguments: - * UINT32 cmd (AR6000_XIOCTL_WMI_SET_QOS_SUPP) - * UINT8 mode - * uses: WMI_SET_QOS_SUPP_CMDID - */ -#define AR6000_XIOCTL_WMI_SET_QOS_SUPP 148 - -#define AR6000_XIOCTL_GET_WLAN_SLEEP_STATE 149 - -#define AR6000_XIOCTL_SET_BT_HW_POWER_STATE 150 - -#define AR6000_XIOCTL_GET_BT_HW_POWER_STATE 151 - -#define AR6000_XIOCTL_ADD_AP_INTERFACE 152 - -#define AR6000_XIOCTL_REMOVE_AP_INTERFACE 153 - -#define AR6000_XIOCTL_WMI_SET_TX_SGI_PARAM 154 - -#define AR6000_XIOCTL_WMI_SET_EXCESS_TX_RETRY_THRES 161 - -/* used by AR6000_IOCTL_WMI_GETREV */ -struct ar6000_version { - u32 host_ver; - u32 target_ver; - u32 wlan_ver; - u32 abi_ver; -}; - -/* used by AR6000_IOCTL_WMI_GET_QOS_QUEUE */ -struct ar6000_queuereq { - u8 trafficClass; - u16 activeTsids; -}; - -/* used by AR6000_IOCTL_WMI_GET_TARGET_STATS */ -typedef struct targetStats_t { - u64 tx_packets; - u64 tx_bytes; - u64 tx_unicast_pkts; - u64 tx_unicast_bytes; - u64 tx_multicast_pkts; - u64 tx_multicast_bytes; - u64 tx_broadcast_pkts; - u64 tx_broadcast_bytes; - u64 tx_rts_success_cnt; - u64 tx_packet_per_ac[4]; - - u64 tx_errors; - u64 tx_failed_cnt; - u64 tx_retry_cnt; - u64 tx_mult_retry_cnt; - u64 tx_rts_fail_cnt; - - u64 rx_packets; - u64 rx_bytes; - u64 rx_unicast_pkts; - u64 rx_unicast_bytes; - u64 rx_multicast_pkts; - u64 rx_multicast_bytes; - u64 rx_broadcast_pkts; - u64 rx_broadcast_bytes; - u64 rx_fragment_pkt; - - u64 rx_errors; - u64 rx_crcerr; - u64 rx_key_cache_miss; - u64 rx_decrypt_err; - u64 rx_duplicate_frames; - - u64 tkip_local_mic_failure; - u64 tkip_counter_measures_invoked; - u64 tkip_replays; - u64 tkip_format_errors; - u64 ccmp_format_errors; - u64 ccmp_replays; - - u64 power_save_failure_cnt; - - u64 cs_bmiss_cnt; - u64 cs_lowRssi_cnt; - u64 cs_connect_cnt; - u64 cs_disconnect_cnt; - - s32 tx_unicast_rate; - s32 rx_unicast_rate; - - u32 lq_val; - - u32 wow_num_pkts_dropped; - u16 wow_num_events_discarded; - - s16 noise_floor_calibation; - s16 cs_rssi; - s16 cs_aveBeacon_rssi; - u8 cs_aveBeacon_snr; - u8 cs_lastRoam_msec; - u8 cs_snr; - - u8 wow_num_host_pkt_wakeups; - u8 wow_num_host_event_wakeups; - - u32 arp_received; - u32 arp_matched; - u32 arp_replied; -}TARGET_STATS; - -typedef struct targetStats_cmd_t { - TARGET_STATS targetStats; - int clearStats; -} TARGET_STATS_CMD; - -/* used by AR6000_XIOCTL_USER_SETKEYS */ - -/* - * Setting this bit to 1 doesnot initialize the RSC on the firmware - */ -#define AR6000_XIOCTL_USER_SETKEYS_RSC_CTRL 1 -#define AR6000_USER_SETKEYS_RSC_UNCHANGED 0x00000002 - -struct ar6000_user_setkeys_info { - u32 keyOpCtrl; /* Bit Map of Key Mgmt Ctrl Flags */ -}; /* XXX: unused !? */ - -/* used by AR6000_XIOCTL_GPIO_OUTPUT_SET */ -struct ar6000_gpio_output_set_cmd_s { - u32 set_mask; - u32 clear_mask; - u32 enable_mask; - u32 disable_mask; -}; - -/* - * used by AR6000_XIOCTL_GPIO_REGISTER_GET and AR6000_XIOCTL_GPIO_REGISTER_SET - */ -struct ar6000_gpio_register_cmd_s { - u32 gpioreg_id; - u32 value; -}; - -/* used by AR6000_XIOCTL_GPIO_INTR_ACK */ -struct ar6000_gpio_intr_ack_cmd_s { - u32 ack_mask; -}; - -/* used by AR6000_XIOCTL_GPIO_INTR_WAIT */ -struct ar6000_gpio_intr_wait_cmd_s { - u32 intr_mask; - u32 input_values; -}; - -/* used by the AR6000_XIOCTL_DBGLOG_CFG_MODULE */ -typedef struct ar6000_dbglog_module_config_s { - u32 valid; - u16 mmask; - u16 tsr; - u32 rep; - u16 size; -} DBGLOG_MODULE_CONFIG; - -typedef struct user_rssi_thold_t { - s16 tag; - s16 rssi; -} USER_RSSI_THOLD; - -typedef struct user_rssi_params_t { - u8 weight; - u32 pollTime; - USER_RSSI_THOLD tholds[12]; -} USER_RSSI_PARAMS; - -typedef struct ar6000_get_btcoex_config_cmd_t{ - u32 btProfileType; - u32 linkId; - }AR6000_GET_BTCOEX_CONFIG_CMD; - -typedef struct ar6000_btcoex_config_t { - AR6000_GET_BTCOEX_CONFIG_CMD configCmd; - u32 *configEvent; -} AR6000_BTCOEX_CONFIG; - -typedef struct ar6000_btcoex_stats_t { - u32 *statsEvent; - }AR6000_BTCOEX_STATS; -/* - * Host driver may have some config parameters. Typically, these - * config params are one time config parameters. These could - * correspond to any of the underlying modules. Host driver exposes - * an api for the underlying modules to get this config. - */ -#define AR6000_DRIVER_CFG_BASE 0x8000 - -/* Should driver perform wlan node caching? */ -#define AR6000_DRIVER_CFG_GET_WLANNODECACHING 0x8001 -/*Should we log raw WMI msgs */ -#define AR6000_DRIVER_CFG_LOG_RAW_WMI_MSGS 0x8002 - -/* used by AR6000_XIOCTL_DIAG_READ & AR6000_XIOCTL_DIAG_WRITE */ -struct ar6000_diag_window_cmd_s { - unsigned int addr; - unsigned int value; -}; - - -struct ar6000_traffic_activity_change { - u32 StreamID; /* stream ID to indicate activity change */ - u32 Active; /* active (1) or inactive (0) */ -}; - -/* Used with AR6000_XIOCTL_PROF_COUNT_GET */ -struct prof_count_s { - u32 addr; /* bin start address */ - u32 count; /* hit count */ -}; - - -/* used by AR6000_XIOCTL_MODULE_DEBUG_SET_MASK */ -/* AR6000_XIOCTL_MODULE_DEBUG_GET_MASK */ -/* AR6000_XIOCTL_DUMP_MODULE_DEBUG_INFO */ -struct drv_debug_module_s { - char modulename[128]; /* name of module */ - u32 mask; /* new mask to set .. or .. current mask */ -}; - - -/* All HCI related rx events are sent up to the host app - * via a wmi event id. It can contain ACL data or HCI event, - * based on which it will be de-multiplexed. - */ -typedef enum { - PAL_HCI_EVENT = 0, - PAL_HCI_RX_DATA, -} WMI_PAL_EVENT_INFO; - - -#ifdef __cplusplus -} -#endif -#endif diff --git a/drivers/staging/ath6kl/os/linux/include/cfg80211.h b/drivers/staging/ath6kl/os/linux/include/cfg80211.h deleted file mode 100644 index d525320..0000000 --- a/drivers/staging/ath6kl/os/linux/include/cfg80211.h +++ /dev/null @@ -1,61 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2004-2010 Atheros Communications Inc. -// All rights reserved. -// -// -// -// 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. -// -// -// -// Author(s): ="Atheros" -//------------------------------------------------------------------------------ - -#ifndef _AR6K_CFG80211_H_ -#define _AR6K_CFG80211_H_ - -struct wireless_dev *ar6k_cfg80211_init(struct device *dev); -void ar6k_cfg80211_deinit(struct ar6_softc *ar); - -void ar6k_cfg80211_scanComplete_event(struct ar6_softc *ar, int status); - -void ar6k_cfg80211_connect_event(struct ar6_softc *ar, u16 channel, - u8 *bssid, u16 listenInterval, - u16 beaconInterval,NETWORK_TYPE networkType, - u8 beaconIeLen, u8 assocReqLen, - u8 assocRespLen, u8 *assocInfo); - -void ar6k_cfg80211_disconnect_event(struct ar6_softc *ar, u8 reason, - u8 *bssid, u8 assocRespLen, - u8 *assocInfo, u16 protocolReasonStatus); - -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_ */ - - - - - - diff --git a/drivers/staging/ath6kl/os/linux/include/config_linux.h b/drivers/staging/ath6kl/os/linux/include/config_linux.h deleted file mode 100644 index dbbe1a0..0000000 --- a/drivers/staging/ath6kl/os/linux/include/config_linux.h +++ /dev/null @@ -1,51 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2004-2010 Atheros Communications Inc. -// All rights reserved. -// -// -// -// 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. -// -// -// -// Author(s): ="Atheros" -//------------------------------------------------------------------------------ - -#ifndef _CONFIG_LINUX_H_ -#define _CONFIG_LINUX_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Host side Test Command support - */ -#define CONFIG_HOST_TCMD_SUPPORT - -#define USE_4BYTE_REGISTER_ACCESS - -/* Host-side support for Target-side profiling */ -#undef CONFIG_TARGET_PROFILE_SUPPORT - -/* IP/TCP checksum offload */ -/* Checksum offload is currently not supported for 64 bit platforms */ -#ifndef __LP64__ -#define CONFIG_CHECKSUM_OFFLOAD -#endif /* __LP64__ */ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/drivers/staging/ath6kl/os/linux/include/debug_linux.h b/drivers/staging/ath6kl/os/linux/include/debug_linux.h deleted file mode 100644 index b8dba52..0000000 --- a/drivers/staging/ath6kl/os/linux/include/debug_linux.h +++ /dev/null @@ -1,50 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2004-2010 Atheros Communications Inc. -// All rights reserved. -// -// -// -// 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. -// -// -// -// Author(s): ="Atheros" -//------------------------------------------------------------------------------ - -#ifndef _DEBUG_LINUX_H_ -#define _DEBUG_LINUX_H_ - - /* macro to remove parens */ -#define ATH_PRINTX_ARG(arg...) arg - -#ifdef DEBUG - /* NOTE: the AR_DEBUG_PRINTF macro is defined here to handle special handling of variable arg macros - * which may be compiler dependent. */ -#define AR_DEBUG_PRINTF(mask, args) do { \ - if (GET_ATH_MODULE_DEBUG_VAR_MASK(ATH_MODULE_NAME) & (mask)) { \ - A_LOGGER(mask, ATH_MODULE_NAME, ATH_PRINTX_ARG args); \ - } \ -} while (0) -#else - /* on non-debug builds, keep in error and warning messages in the driver, all other - * message tracing will get compiled out */ -#define AR_DEBUG_PRINTF(mask, args) \ - if ((mask) & (ATH_DEBUG_ERR | ATH_DEBUG_WARN)) { A_PRINTF(ATH_PRINTX_ARG args); } - -#endif - - /* compile specific macro to get the function name string */ -#define _A_FUNCNAME_ __func__ - - -#endif /* _DEBUG_LINUX_H_ */ diff --git a/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h b/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h deleted file mode 100644 index 74f9861..0000000 --- a/drivers/staging/ath6kl/os/linux/include/export_hci_transport.h +++ /dev/null @@ -1,76 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2009-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// HCI bridge implementation -// -// Author(s): ="Atheros" -//============================================================================== - -#include "hci_transport_api.h" -#include "common_drv.h" - -extern HCI_TRANSPORT_HANDLE (*_HCI_TransportAttach)(void *HTCHandle, struct hci_transport_config_info *pInfo); -extern void (*_HCI_TransportDetach)(HCI_TRANSPORT_HANDLE HciTrans); -extern int (*_HCI_TransportAddReceivePkts)(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet_queue *pQueue); -extern int (*_HCI_TransportSendPkt)(HCI_TRANSPORT_HANDLE HciTrans, struct htc_packet *pPacket, bool Synchronous); -extern void (*_HCI_TransportStop)(HCI_TRANSPORT_HANDLE HciTrans); -extern int (*_HCI_TransportStart)(HCI_TRANSPORT_HANDLE HciTrans); -extern int (*_HCI_TransportEnableDisableAsyncRecv)(HCI_TRANSPORT_HANDLE HciTrans, bool Enable); -extern int (*_HCI_TransportRecvHCIEventSync)(HCI_TRANSPORT_HANDLE HciTrans, - struct htc_packet *pPacket, - int MaxPollMS); -extern int (*_HCI_TransportSetBaudRate)(HCI_TRANSPORT_HANDLE HciTrans, u32 Baud); -extern int (*_HCI_TransportEnablePowerMgmt)(HCI_TRANSPORT_HANDLE HciTrans, bool Enable); - - -#define HCI_TransportAttach(HTCHandle, pInfo) \ - _HCI_TransportAttach((HTCHandle), (pInfo)) -#define HCI_TransportDetach(HciTrans) \ - _HCI_TransportDetach(HciTrans) -#define HCI_TransportAddReceivePkts(HciTrans, pQueue) \ - _HCI_TransportAddReceivePkts((HciTrans), (pQueue)) -#define HCI_TransportSendPkt(HciTrans, pPacket, Synchronous) \ - _HCI_TransportSendPkt((HciTrans), (pPacket), (Synchronous)) -#define HCI_TransportStop(HciTrans) \ - _HCI_TransportStop((HciTrans)) -#define HCI_TransportStart(HciTrans) \ - _HCI_TransportStart((HciTrans)) -#define HCI_TransportEnableDisableAsyncRecv(HciTrans, Enable) \ - _HCI_TransportEnableDisableAsyncRecv((HciTrans), (Enable)) -#define HCI_TransportRecvHCIEventSync(HciTrans, pPacket, MaxPollMS) \ - _HCI_TransportRecvHCIEventSync((HciTrans), (pPacket), (MaxPollMS)) -#define HCI_TransportSetBaudRate(HciTrans, Baud) \ - _HCI_TransportSetBaudRate((HciTrans), (Baud)) -#define HCI_TransportEnablePowerMgmt(HciTrans, Enable) \ - _HCI_TransportEnablePowerMgmt((HciTrans), (Enable)) - - -extern int ar6000_register_hci_transport(struct hci_transport_callbacks *hciTransCallbacks); - -extern int ar6000_get_hif_dev(struct hif_device *device, void *config); - -extern int ar6000_set_uart_config(struct hif_device *hifDevice, u32 scale, u32 step); - -/* get core clock register settings - * data: 0 - 40/44MHz - * 1 - 80/88MHz - * where (5G band/2.4G band) - * assume 2.4G band for now - */ -extern int ar6000_get_core_clock_config(struct hif_device *hifDevice, u32 *data); diff --git a/drivers/staging/ath6kl/os/linux/include/ieee80211_ioctl.h b/drivers/staging/ath6kl/os/linux/include/ieee80211_ioctl.h deleted file mode 100644 index e6e96de..0000000 --- a/drivers/staging/ath6kl/os/linux/include/ieee80211_ioctl.h +++ /dev/null @@ -1,177 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2004-2010 Atheros Communications Inc. -// All rights reserved. -// -// -// -// 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. -// -// -// -// Author(s): ="Atheros" -//------------------------------------------------------------------------------ - -#ifndef _IEEE80211_IOCTL_H_ -#define _IEEE80211_IOCTL_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Extracted from the MADWIFI net80211/ieee80211_ioctl.h - */ - -/* - * WPA/RSN get/set key request. Specify the key/cipher - * type and whether the key is to be used for sending and/or - * receiving. The key index should be set only when working - * with global keys (use IEEE80211_KEYIX_NONE for ``no index''). - * Otherwise a unicast/pairwise key is specified by the bssid - * (on a station) or mac address (on an ap). They key length - * must include any MIC key data; otherwise it should be no - more than IEEE80211_KEYBUF_SIZE. - */ -struct ieee80211req_key { - u_int8_t ik_type; /* key/cipher type */ - u_int8_t ik_pad; - u_int16_t ik_keyix; /* key index */ - u_int8_t ik_keylen; /* key length in bytes */ - u_int8_t ik_flags; -#define IEEE80211_KEY_XMIT 0x01 -#define IEEE80211_KEY_RECV 0x02 -#define IEEE80211_KEY_DEFAULT 0x80 /* default xmit key */ - u_int8_t ik_macaddr[IEEE80211_ADDR_LEN]; - u_int64_t ik_keyrsc; /* key receive sequence counter */ - u_int64_t ik_keytsc; /* key transmit sequence counter */ - u_int8_t ik_keydata[IEEE80211_KEYBUF_SIZE+IEEE80211_MICBUF_SIZE]; -}; -/* - * Delete a key either by index or address. Set the index - * to IEEE80211_KEYIX_NONE when deleting a unicast key. - */ -struct ieee80211req_del_key { - u_int8_t idk_keyix; /* key index */ - u_int8_t idk_macaddr[IEEE80211_ADDR_LEN]; -}; -/* - * MLME state manipulation request. IEEE80211_MLME_ASSOC - * only makes sense when operating as a station. The other - * requests can be used when operating as a station or an - * ap (to effect a station). - */ -struct ieee80211req_mlme { - u_int8_t im_op; /* operation to perform */ -#define IEEE80211_MLME_ASSOC 1 /* associate station */ -#define IEEE80211_MLME_DISASSOC 2 /* disassociate station */ -#define IEEE80211_MLME_DEAUTH 3 /* deauthenticate station */ -#define IEEE80211_MLME_AUTHORIZE 4 /* authorize station */ -#define IEEE80211_MLME_UNAUTHORIZE 5 /* unauthorize station */ - u_int16_t im_reason; /* 802.11 reason code */ - u_int8_t im_macaddr[IEEE80211_ADDR_LEN]; -}; - -struct ieee80211req_addpmkid { - u_int8_t pi_bssid[IEEE80211_ADDR_LEN]; - u_int8_t pi_enable; - u_int8_t pi_pmkid[16]; -}; - -#define AUTH_ALG_OPEN_SYSTEM 0x01 -#define AUTH_ALG_SHARED_KEY 0x02 -#define AUTH_ALG_LEAP 0x04 - -struct ieee80211req_authalg { - u_int8_t auth_alg; -}; - -/* - * Request to add an IE to a Management Frame - */ -enum{ - IEEE80211_APPIE_FRAME_BEACON = 0, - IEEE80211_APPIE_FRAME_PROBE_REQ = 1, - IEEE80211_APPIE_FRAME_PROBE_RESP = 2, - IEEE80211_APPIE_FRAME_ASSOC_REQ = 3, - IEEE80211_APPIE_FRAME_ASSOC_RESP = 4, - IEEE80211_APPIE_NUM_OF_FRAME = 5 -}; - -/* - * The Maximum length of the IE that can be added to a Management frame - */ -#define IEEE80211_APPIE_FRAME_MAX_LEN 200 - -struct ieee80211req_getset_appiebuf { - u_int32_t app_frmtype; /* management frame type for which buffer is added */ - u_int32_t app_buflen; /*application supplied buffer length */ - u_int8_t app_buf[]; -}; - -/* - * The following definitions are used by an application to set filter - * for receiving management frames - */ -enum { - IEEE80211_FILTER_TYPE_BEACON = 0x1, - IEEE80211_FILTER_TYPE_PROBE_REQ = 0x2, - IEEE80211_FILTER_TYPE_PROBE_RESP = 0x4, - IEEE80211_FILTER_TYPE_ASSOC_REQ = 0x8, - IEEE80211_FILTER_TYPE_ASSOC_RESP = 0x10, - IEEE80211_FILTER_TYPE_AUTH = 0x20, - IEEE80211_FILTER_TYPE_DEAUTH = 0x40, - IEEE80211_FILTER_TYPE_DISASSOC = 0x80, - IEEE80211_FILTER_TYPE_ALL = 0xFF /* used to check the valid filter bits */ -}; - -struct ieee80211req_set_filter { - u_int32_t app_filterype; /* management frame filter type */ -}; - -enum { - IEEE80211_PARAM_AUTHMODE = 3, /* Authentication Mode */ - IEEE80211_PARAM_MCASTCIPHER = 5, - IEEE80211_PARAM_MCASTKEYLEN = 6, /* multicast key length */ - IEEE80211_PARAM_UCASTCIPHER = 8, - IEEE80211_PARAM_UCASTKEYLEN = 9, /* unicast key length */ - IEEE80211_PARAM_WPA = 10, /* WPA mode (0,1,2) */ - IEEE80211_PARAM_ROAMING = 12, /* roaming mode */ - IEEE80211_PARAM_PRIVACY = 13, /* privacy invoked */ - IEEE80211_PARAM_COUNTERMEASURES = 14, /* WPA/TKIP countermeasures */ - IEEE80211_PARAM_DROPUNENCRYPTED = 15, /* discard unencrypted frames */ - IEEE80211_PARAM_WAPI = 16, /* WAPI policy from wapid */ -}; - -/* - * Values for IEEE80211_PARAM_WPA - */ -#define WPA_MODE_WPA1 1 -#define WPA_MODE_WPA2 2 -#define WPA_MODE_AUTO 3 -#define WPA_MODE_NONE 4 - -struct ieee80211req_wpaie { - u_int8_t wpa_macaddr[IEEE80211_ADDR_LEN]; - u_int8_t wpa_ie[IEEE80211_MAX_IE]; - u_int8_t rsn_ie[IEEE80211_MAX_IE]; -}; - -#ifndef IW_ENCODE_ALG_PMK -#define IW_ENCODE_ALG_PMK 4 -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* _IEEE80211_IOCTL_H_ */ diff --git a/drivers/staging/ath6kl/os/linux/include/osapi_linux.h b/drivers/staging/ath6kl/os/linux/include/osapi_linux.h deleted file mode 100644 index 41f4373..0000000 --- a/drivers/staging/ath6kl/os/linux/include/osapi_linux.h +++ /dev/null @@ -1,339 +0,0 @@ -//------------------------------------------------------------------------------ -// This file contains the definitions of the basic atheros data types. -// It is used to map the data types in atheros files to a platform specific -// type. -// Copyright (c) 2004-2010 Atheros Communications Inc. -// All rights reserved. -// -// -// -// 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. -// -// -// -// Author(s): ="Atheros" -//------------------------------------------------------------------------------ - -#ifndef _OSAPI_LINUX_H_ -#define _OSAPI_LINUX_H_ - -#ifdef __KERNEL__ - -#include <linux/types.h> -#include <linux/kernel.h> -#include <linux/string.h> -#include <linux/skbuff.h> -#include <linux/netdevice.h> -#include <linux/jiffies.h> -#include <linux/timer.h> -#include <linux/delay.h> -#include <linux/wait.h> -#include <linux/semaphore.h> -#include <linux/cache.h> - -#ifdef __GNUC__ -#define __ATTRIB_PACK __attribute__ ((packed)) -#define __ATTRIB_PRINTF __attribute__ ((format (printf, 1, 2))) -#define __ATTRIB_NORETURN __attribute__ ((noreturn)) -#ifndef INLINE -#define INLINE __inline__ -#endif -#else /* Not GCC */ -#define __ATTRIB_PACK -#define __ATTRIB_PRINTF -#define __ATTRIB_NORETURN -#ifndef INLINE -#define INLINE __inline -#endif -#endif /* End __GNUC__ */ - -#define PREPACK -#define POSTPACK __ATTRIB_PACK - -/* - * Endianes macros - */ -#define A_BE2CPU8(x) ntohb(x) -#define A_BE2CPU16(x) ntohs(x) -#define A_BE2CPU32(x) ntohl(x) - -#define A_LE2CPU8(x) (x) -#define A_LE2CPU16(x) (x) -#define A_LE2CPU32(x) (x) - -#define A_CPU2BE8(x) htonb(x) -#define A_CPU2BE16(x) htons(x) -#define A_CPU2BE32(x) htonl(x) - -#define A_MEMZERO(addr, len) memset(addr, 0, len) -#define A_MALLOC(size) kmalloc((size), GFP_KERNEL) -#define A_MALLOC_NOWAIT(size) kmalloc((size), GFP_ATOMIC) - -#define A_LOGGER(mask, mod, args...) printk(KERN_ALERT args) -#define A_PRINTF(args...) printk(KERN_ALERT args) - -#define A_PRINTF_LOG(args...) printk(args) -#define A_SPRINTF(buf, args...) sprintf (buf, args) - -/* Mutual Exclusion */ -typedef spinlock_t A_MUTEX_T; -#define A_MUTEX_INIT(mutex) spin_lock_init(mutex) -#define A_MUTEX_LOCK(mutex) spin_lock_bh(mutex) -#define A_MUTEX_UNLOCK(mutex) spin_unlock_bh(mutex) -#define A_IS_MUTEX_VALID(mutex) true /* okay to return true, since A_MUTEX_DELETE does nothing */ -#define A_MUTEX_DELETE(mutex) /* spin locks are not kernel resources so nothing to free.. */ - -/* Get current time in ms adding a constant offset (in ms) */ -#define A_GET_MS(offset) \ - (((jiffies / HZ) * 1000) + (offset)) - -/* - * Timer Functions - */ -#define A_MDELAY(msecs) mdelay(msecs) -typedef struct timer_list A_TIMER; - -#define A_INIT_TIMER(pTimer, pFunction, pArg) do { \ - init_timer(pTimer); \ - (pTimer)->function = (pFunction); \ - (pTimer)->data = (unsigned long)(pArg); \ -} while (0) - -/* - * Start a Timer that elapses after 'periodMSec' milli-seconds - * Support is provided for a one-shot timer. The 'repeatFlag' is - * ignored. - */ -#define A_TIMEOUT_MS(pTimer, periodMSec, repeatFlag) do { \ - if (repeatFlag) { \ - printk("\n" __FILE__ ":%d: Timer Repeat requested\n",__LINE__); \ - panic("Timer Repeat"); \ - } \ - mod_timer((pTimer), jiffies + HZ * (periodMSec) / 1000); \ -} while (0) - -/* - * Cancel the Timer. - */ -#define A_UNTIMEOUT(pTimer) do { \ - del_timer((pTimer)); \ -} while (0) - -#define A_DELETE_TIMER(pTimer) do { \ -} while (0) - -/* - * Wait Queue related functions - */ -typedef wait_queue_head_t A_WAITQUEUE_HEAD; -#define A_INIT_WAITQUEUE_HEAD(head) init_waitqueue_head(head) -#ifndef wait_event_interruptible_timeout -#define __wait_event_interruptible_timeout(wq, condition, ret) \ -do { \ - wait_queue_t __wait; \ - init_waitqueue_entry(&__wait, current); \ - \ - add_wait_queue(&wq, &__wait); \ - for (;;) { \ - set_current_state(TASK_INTERRUPTIBLE); \ - if (condition) \ - break; \ - if (!signal_pending(current)) { \ - ret = schedule_timeout(ret); \ - if (!ret) \ - break; \ - continue; \ - } \ - ret = -ERESTARTSYS; \ - break; \ - } \ - current->state = TASK_RUNNING; \ - remove_wait_queue(&wq, &__wait); \ -} while (0) - -#define wait_event_interruptible_timeout(wq, condition, timeout) \ -({ \ - long __ret = timeout; \ - if (!(condition)) \ - __wait_event_interruptible_timeout(wq, condition, __ret); \ - __ret; \ -}) -#endif /* wait_event_interruptible_timeout */ - -#define A_WAIT_EVENT_INTERRUPTIBLE_TIMEOUT(head, condition, timeout) do { \ - wait_event_interruptible_timeout(head, condition, timeout); \ -} while (0) - -#define A_WAKE_UP(head) wake_up(head) - -#ifdef DEBUG -extern unsigned int panic_on_assert; -#define A_ASSERT(expr) \ - if (!(expr)) { \ - printk(KERN_ALERT"Debug Assert Caught, File %s, Line: %d, Test:%s \n",__FILE__, __LINE__,#expr); \ - if (panic_on_assert) panic(#expr); \ - } -#else -#define A_ASSERT(expr) -#endif /* DEBUG */ - -#define A_REQUEST_FIRMWARE(_ppf, _pfile, _dev) request_firmware(_ppf, _pfile, _dev) -#define A_RELEASE_FIRMWARE(_pf) release_firmware(_pf) - -/* - * Initialization of the network buffer subsystem - */ -#define A_NETBUF_INIT() - -/* - * Network buffer queue support - */ -typedef struct sk_buff_head A_NETBUF_QUEUE_T; - -#define A_NETBUF_QUEUE_INIT(q) \ - a_netbuf_queue_init(q) - -#define A_NETBUF_ENQUEUE(q, pkt) \ - a_netbuf_enqueue((q), (pkt)) -#define A_NETBUF_PREQUEUE(q, pkt) \ - a_netbuf_prequeue((q), (pkt)) -#define A_NETBUF_DEQUEUE(q) \ - (a_netbuf_dequeue(q)) -#define A_NETBUF_QUEUE_SIZE(q) \ - a_netbuf_queue_size(q) -#define A_NETBUF_QUEUE_EMPTY(q) \ - (a_netbuf_queue_empty(q) ? true : false) - -/* - * Network buffer support - */ -#define A_NETBUF_ALLOC(size) \ - a_netbuf_alloc(size) -#define A_NETBUF_ALLOC_RAW(size) \ - a_netbuf_alloc_raw(size) -#define A_NETBUF_FREE(bufPtr) \ - a_netbuf_free(bufPtr) -#define A_NETBUF_DATA(bufPtr) \ - a_netbuf_to_data(bufPtr) -#define A_NETBUF_LEN(bufPtr) \ - a_netbuf_to_len(bufPtr) -#define A_NETBUF_PUSH(bufPtr, len) \ - a_netbuf_push(bufPtr, len) -#define A_NETBUF_PUT(bufPtr, len) \ - a_netbuf_put(bufPtr, len) -#define A_NETBUF_TRIM(bufPtr,len) \ - a_netbuf_trim(bufPtr, len) -#define A_NETBUF_PULL(bufPtr, len) \ - a_netbuf_pull(bufPtr, len) -#define A_NETBUF_HEADROOM(bufPtr)\ - a_netbuf_headroom(bufPtr) -#define A_NETBUF_SETLEN(bufPtr,len) \ - a_netbuf_setlen(bufPtr, len) - -/* Add data to end of a buffer */ -#define A_NETBUF_PUT_DATA(bufPtr, srcPtr, len) \ - a_netbuf_put_data(bufPtr, srcPtr, len) - -/* Add data to start of the buffer */ -#define A_NETBUF_PUSH_DATA(bufPtr, srcPtr, len) \ - a_netbuf_push_data(bufPtr, srcPtr, len) - -/* Remove data at start of the buffer */ -#define A_NETBUF_PULL_DATA(bufPtr, dstPtr, len) \ - a_netbuf_pull_data(bufPtr, dstPtr, len) - -/* Remove data from the end of the buffer */ -#define A_NETBUF_TRIM_DATA(bufPtr, dstPtr, len) \ - a_netbuf_trim_data(bufPtr, dstPtr, len) - -/* View data as "size" contiguous bytes of type "t" */ -#define A_NETBUF_VIEW_DATA(bufPtr, t, size) \ - (t )( ((struct skbuf *)(bufPtr))->data) - -/* return the beginning of the headroom for the buffer */ -#define A_NETBUF_HEAD(bufPtr) \ - ((((struct sk_buff *)(bufPtr))->head)) - -/* - * OS specific network buffer access routines - */ -void *a_netbuf_alloc(int size); -void *a_netbuf_alloc_raw(int size); -void a_netbuf_free(void *bufPtr); -void *a_netbuf_to_data(void *bufPtr); -u32 a_netbuf_to_len(void *bufPtr); -int a_netbuf_push(void *bufPtr, s32 len); -int a_netbuf_push_data(void *bufPtr, char *srcPtr, s32 len); -int a_netbuf_put(void *bufPtr, s32 len); -int a_netbuf_put_data(void *bufPtr, char *srcPtr, s32 len); -int a_netbuf_pull(void *bufPtr, s32 len); -int a_netbuf_pull_data(void *bufPtr, char *dstPtr, s32 len); -int a_netbuf_trim(void *bufPtr, s32 len); -int a_netbuf_trim_data(void *bufPtr, char *dstPtr, s32 len); -int a_netbuf_setlen(void *bufPtr, s32 len); -s32 a_netbuf_headroom(void *bufPtr); -void a_netbuf_enqueue(A_NETBUF_QUEUE_T *q, void *pkt); -void a_netbuf_prequeue(A_NETBUF_QUEUE_T *q, void *pkt); -void *a_netbuf_dequeue(A_NETBUF_QUEUE_T *q); -int a_netbuf_queue_size(A_NETBUF_QUEUE_T *q); -int a_netbuf_queue_empty(A_NETBUF_QUEUE_T *q); -int a_netbuf_queue_empty(A_NETBUF_QUEUE_T *q); -void a_netbuf_queue_init(A_NETBUF_QUEUE_T *q); - -/* - * Kernel v.s User space functions - */ -u32 a_copy_to_user(void *to, const void *from, u32 n); -u32 a_copy_from_user(void *to, const void *from, u32 n); - -/* In linux, WLAN Rx and Tx run in different contexts, so no need to check - * for any commands/data queued for WLAN */ -#define A_CHECK_DRV_TX() - -#define A_GET_CACHE_LINE_BYTES() L1_CACHE_BYTES - -#define A_CACHE_LINE_PAD 128 - -static inline void *A_ALIGN_TO_CACHE_LINE(void *ptr) { - return (void *)L1_CACHE_ALIGN((unsigned long)ptr); -} - -#else /* __KERNEL__ */ - -#ifdef __GNUC__ -#define __ATTRIB_PACK __attribute__ ((packed)) -#define __ATTRIB_PRINTF __attribute__ ((format (printf, 1, 2))) -#define __ATTRIB_NORETURN __attribute__ ((noreturn)) -#ifndef INLINE -#define INLINE __inline__ -#endif -#else /* Not GCC */ -#define __ATTRIB_PACK -#define __ATTRIB_PRINTF -#define __ATTRIB_NORETURN -#ifndef INLINE -#define INLINE __inline -#endif -#endif /* End __GNUC__ */ - -#define PREPACK -#define POSTPACK __ATTRIB_PACK - -#define A_MEMZERO(addr, len) memset((addr), 0, (len)) -#define A_MALLOC(size) malloc(size) - -#include <err.h> - -#endif /* __KERNEL__ */ - -#endif /* _OSAPI_LINUX_H_ */ diff --git a/drivers/staging/ath6kl/os/linux/include/wlan_config.h b/drivers/staging/ath6kl/os/linux/include/wlan_config.h deleted file mode 100644 index c1fe0c6..0000000 --- a/drivers/staging/ath6kl/os/linux/include/wlan_config.h +++ /dev/null @@ -1,108 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// Permission to use, copy, modify, and/or distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// This file contains the tunable configuration items for the WLAN module -// -// Author(s): ="Atheros" -//============================================================================== -#ifndef _HOST_WLAN_CONFIG_H_ -#define _HOST_WLAN_CONFIG_H_ - -/* Include definitions here that can be used to tune the WLAN module behavior. - * Different customers can tune the behavior as per their needs, here. - */ - -/* This configuration item when defined will consider the barker preamble - * mentioned in the ERP IE of the beacons from the AP to determine the short - * preamble support sent in the (Re)Assoc request frames. - */ -#define WLAN_CONFIG_DONOT_IGNORE_BARKER_IN_ERP 0 - -/* This config item when defined will not send the power module state transition - * failure events that happen during scan, to the host. - */ -#define WLAN_CONFIG_IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN 0 - -/* - * This configuration item enable/disable keepalive support. - * Keepalive support: In the absence of any data traffic to AP, null - * frames will be sent to the AP at periodic interval, to keep the association - * active. This configuration item defines the periodic interval. - * Use value of zero to disable keepalive support - * Default: 60 seconds - */ -#define WLAN_CONFIG_KEEP_ALIVE_INTERVAL 60 - -/* - * This configuration item sets the value of disconnect timeout - * Firmware delays sending the disconnec event to the host for this - * timeout after is gets disconnected from the current AP. - * If the firmware successly roams within the disconnect timeout - * it sends a new connect event - */ -#define WLAN_CONFIG_DISCONNECT_TIMEOUT 10 - -/* - * This configuration item disables 11n support. - * 0 - Enable - * 1 - Disable - */ -#define WLAN_CONFIG_DISABLE_11N 0 - -/* - * This configuration item enable BT clock sharing support - * 1 - Enable - * 0 - Disable (Default) - */ -#define WLAN_CONFIG_BT_SHARING 0 - -/* - * This configuration item sets WIFI OFF policy - * 0 - CUT_POWER - * 1 - DEEP_SLEEP (Default) - */ -#define WLAN_CONFIG_WLAN_OFF 1 - -/* - * This configuration item sets suspend policy - * 0 - CUT_POWER (Default) - * 1 - DEEP_SLEEP - * 2 - WoW - * 3 - CUT_POWER if BT OFF (clock sharing designs only) - */ -#define WLAN_CONFIG_PM_SUSPEND 0 - -/* - * This configuration item sets suspend policy to use if PM_SUSPEND is - * set to WoW and device is not connected at the time of suspend - * 0 - CUT_POWER (Default) - * 1 - DEEP_SLEEP - * 2 - WoW - * 3 - CUT_POWER if BT OFF (clock sharing designs only) - */ -#define WLAN_CONFIG_PM_WOW2 0 - -/* - * This configuration item enables/disables transmit bursting - * 0 - Enable tx Bursting (default) - * 1 - Disable tx bursting - */ -#define WLAN_CONFIG_DISABLE_TX_BURSTING 0 - -#endif /* _HOST_WLAN_CONFIG_H_ */ diff --git a/drivers/staging/ath6kl/os/linux/include/wmi_filter_linux.h b/drivers/staging/ath6kl/os/linux/include/wmi_filter_linux.h deleted file mode 100644 index 1eb6f82..0000000 --- a/drivers/staging/ath6kl/os/linux/include/wmi_filter_linux.h +++ /dev/null @@ -1,300 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2004-2010 Atheros Communications Inc. -// All rights reserved. -// -// -// -// 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. -// -// -// -// Author(s): ="Atheros" -//------------------------------------------------------------------------------ - -#ifndef _WMI_FILTER_LINUX_H_ -#define _WMI_FILTER_LINUX_H_ - -/* - * sioctl_filter - Standard ioctl - * pioctl_filter - Priv ioctl - * xioctl_filter - eXtended ioctl - * - * ---- Possible values for the WMI filter --------------- - * (0) - Block this cmd always (or) not implemented - * (INFRA_NETWORK) - Allow this cmd only in STA mode - * (ADHOC_NETWORK) - Allow this cmd only in IBSS mode - * (AP_NETWORK) - Allow this cmd only in AP mode - * (INFRA_NETWORK | ADHOC_NETWORK) - Block this cmd in AP mode - * (ADHOC_NETWORK | AP_NETWORK) - Block this cmd in STA mode - * (INFRA_NETWORK | AP_NETWORK) - Block this cmd in IBSS mode - * (INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK)- allow only when mode is set - * (0xFF) - Allow this cmd always irrespective of mode - */ - -u8 sioctl_filter[] = { -(AP_NETWORK), /* SIOCSIWCOMMIT 0x8B00 */ -(0xFF), /* SIOCGIWNAME 0x8B01 */ -(0), /* SIOCSIWNWID 0x8B02 */ -(0), /* SIOCGIWNWID 0x8B03 */ -(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCSIWFREQ 0x8B04 */ -(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCGIWFREQ 0x8B05 */ -(0xFF), /* SIOCSIWMODE 0x8B06 */ -(0xFF), /* SIOCGIWMODE 0x8B07 */ -(0), /* SIOCSIWSENS 0x8B08 */ -(0), /* SIOCGIWSENS 0x8B09 */ -(0), /* SIOCSIWRANGE 0x8B0A */ -(0xFF), /* SIOCGIWRANGE 0x8B0B */ -(0), /* SIOCSIWPRIV 0x8B0C */ -(0), /* SIOCGIWPRIV 0x8B0D */ -(0), /* SIOCSIWSTATS 0x8B0E */ -(0), /* SIOCGIWSTATS 0x8B0F */ -(0), /* SIOCSIWSPY 0x8B10 */ -(0), /* SIOCGIWSPY 0x8B11 */ -(0), /* SIOCSIWTHRSPY 0x8B12 */ -(0), /* SIOCGIWTHRSPY 0x8B13 */ -(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCSIWAP 0x8B14 */ -(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCGIWAP 0x8B15 */ -#if (WIRELESS_EXT >= 18) -(INFRA_NETWORK | ADHOC_NETWORK), /* SIOCSIWMLME 0X8B16 */ -#else -(0), /* Dummy 0 */ -#endif /* WIRELESS_EXT */ -(0), /* SIOCGIWAPLIST 0x8B17 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* SIOCSIWSCAN 0x8B18 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* SIOCGIWSCAN 0x8B19 */ -(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCSIWESSID 0x8B1A */ -(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCGIWESSID 0x8B1B */ -(0), /* SIOCSIWNICKN 0x8B1C */ -(0), /* SIOCGIWNICKN 0x8B1D */ -(0), /* Dummy 0 */ -(0), /* Dummy 0 */ -(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCSIWRATE 0x8B20 */ -(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCGIWRATE 0x8B21 */ -(0), /* SIOCSIWRTS 0x8B22 */ -(0), /* SIOCGIWRTS 0x8B23 */ -(0), /* SIOCSIWFRAG 0x8B24 */ -(0), /* SIOCGIWFRAG 0x8B25 */ -(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCSIWTXPOW 0x8B26 */ -(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCGIWTXPOW 0x8B27 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* SIOCSIWRETRY 0x8B28 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* SIOCGIWRETRY 0x8B29 */ -(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCSIWENCODE 0x8B2A */ -(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCGIWENCODE 0x8B2B */ -(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCSIWPOWER 0x8B2C */ -(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* SIOCGIWPOWER 0x8B2D */ -}; - - - -u8 pioctl_filter[] = { -(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* IEEE80211_IOCTL_SETPARAM (SIOCIWFIRSTPRIV+0) */ -(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* IEEE80211_IOCTL_SETKEY (SIOCIWFIRSTPRIV+1) */ -(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* IEEE80211_IOCTL_DELKEY (SIOCIWFIRSTPRIV+2) */ -(AP_NETWORK), /* IEEE80211_IOCTL_SETMLME (SIOCIWFIRSTPRIV+3) */ -(INFRA_NETWORK), /* IEEE80211_IOCTL_ADDPMKID (SIOCIWFIRSTPRIV+4) */ -(0), /* IEEE80211_IOCTL_SETOPTIE (SIOCIWFIRSTPRIV+5) */ -(0), /* (SIOCIWFIRSTPRIV+6) */ -(0), /* (SIOCIWFIRSTPRIV+7) */ -(0), /* (SIOCIWFIRSTPRIV+8) */ -(0), /* (SIOCIWFIRSTPRIV+9) */ -(0), /* IEEE80211_IOCTL_LASTONE (SIOCIWFIRSTPRIV+10) */ -(0xFF), /* AR6000_IOCTL_WMI_GETREV (SIOCIWFIRSTPRIV+11) */ -(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_IOCTL_WMI_SETPWR (SIOCIWFIRSTPRIV+12) */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SETSCAN (SIOCIWFIRSTPRIV+13) */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SETLISTENINT (SIOCIWFIRSTPRIV+14) */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SETBSSFILTER (SIOCIWFIRSTPRIV+15) */ -(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_IOCTL_WMI_SET_CHANNELPARAMS (SIOCIWFIRSTPRIV+16) */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_PROBEDSSID (SIOCIWFIRSTPRIV+17) */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_PMPARAMS (SIOCIWFIRSTPRIV+18) */ -(INFRA_NETWORK), /* AR6000_IOCTL_WMI_SET_BADAP (SIOCIWFIRSTPRIV+19) */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_GET_QOS_QUEUE (SIOCIWFIRSTPRIV+20) */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_CREATE_QOS (SIOCIWFIRSTPRIV+21) */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_DELETE_QOS (SIOCIWFIRSTPRIV+22) */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_SNRTHRESHOLD (SIOCIWFIRSTPRIV+23) */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_ERROR_REPORT_BITMASK (SIOCIWFIRSTPRIV+24)*/ -(0xFF), /* AR6000_IOCTL_WMI_GET_TARGET_STATS (SIOCIWFIRSTPRIV+25) */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_ASSOC_INFO (SIOCIWFIRSTPRIV+26) */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_ACCESS_PARAMS (SIOCIWFIRSTPRIV+27) */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_BMISS_TIME (SIOCIWFIRSTPRIV+28) */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_DISC_TIMEOUT (SIOCIWFIRSTPRIV+29) */ -(ADHOC_NETWORK), /* AR6000_IOCTL_WMI_SET_IBSS_PM_CAPS (SIOCIWFIRSTPRIV+30) */ -}; - - - -u8 xioctl_filter[] = { -(0xFF), /* Dummy 0 */ -(0xFF), /* AR6000_XIOCTL_BMI_DONE 1 */ -(0xFF), /* AR6000_XIOCTL_BMI_READ_MEMORY 2 */ -(0xFF), /* AR6000_XIOCTL_BMI_WRITE_MEMORY 3 */ -(0xFF), /* AR6000_XIOCTL_BMI_EXECUTE 4 */ -(0xFF), /* AR6000_XIOCTL_BMI_SET_APP_START 5 */ -(0xFF), /* AR6000_XIOCTL_BMI_READ_SOC_REGISTER 6 */ -(0xFF), /* AR6000_XIOCTL_BMI_WRITE_SOC_REGISTER 7 */ -(0xFF), /* AR6000_XIOCTL_BMI_TEST 8 */ -(0xFF), /* AR6000_XIOCTL_UNUSED9 9 */ -(0xFF), /* AR6000_XIOCTL_UNUSED10 10 */ -(0xFF), /* AR6000_XIOCTL_UNUSED11 11 */ -(0xFF), /* AR6000_XIOCTL_FORCE_TARGET_RESET 12 */ -(0xFF), /* AR6000_XIOCTL_HTC_RAW_OPEN 13 */ -(0xFF), /* AR6000_XIOCTL_HTC_RAW_CLOSE 14 */ -(0xFF), /* AR6000_XIOCTL_HTC_RAW_READ 15 */ -(0xFF), /* AR6000_XIOCTL_HTC_RAW_WRITE 16 */ -(0xFF), /* AR6000_XIOCTL_CHECK_TARGET_READY 17 */ -(0xFF), /* AR6000_XIOCTL_GPIO_OUTPUT_SET 18 */ -(0xFF), /* AR6000_XIOCTL_GPIO_INPUT_GET 19 */ -(0xFF), /* AR6000_XIOCTL_GPIO_REGISTER_SET 20 */ -(0xFF), /* AR6000_XIOCTL_GPIO_REGISTER_GET 21 */ -(0xFF), /* AR6000_XIOCTL_GPIO_INTR_ACK 22 */ -(0xFF), /* AR6000_XIOCTL_GPIO_INTR_WAIT 23 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_SET_ADHOC_BSSID 24 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_SET_OPT_MODE 25 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_OPT_SEND_FRAME 26 */ -(ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTL_SET_BEACON_INTVAL 27 */ -(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* IEEE80211_IOCTL_SETAUTHALG 28 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_SET_VOICE_PKT_SIZE 29 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_SET_MAX_SP 30 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_GET_ROAM_TBL 31 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_ROAM_CTRL 32 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTRL_WMI_SET_POWERSAVE_TIMERS 33 */ -(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTRL_WMI_GET_POWER_MODE 34 */ -(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTRL_WMI_SET_WLAN_STATE 35 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_GET_ROAM_DATA 36 */ -(0xFF), /* AR6000_XIOCTL_WMI_SETRETRYLIMITS 37 */ -(0xFF), /* AR6000_XIOCTL_TCMD_CONT_TX 38 */ -(0xFF), /* AR6000_XIOCTL_TCMD_CONT_RX 39 */ -(0xFF), /* AR6000_XIOCTL_TCMD_PM 40 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_STARTSCAN 41 */ -(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTL_WMI_SETFIXRATES 42 */ -(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTL_WMI_GETFIXRATES 43 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_RSSITHRESHOLD 44 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_CLR_RSSISNR 45 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_LQTHRESHOLD 46 */ -(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTL_WMI_SET_RTS 47 */ -(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTL_WMI_SET_LPREAMBLE 48 */ -(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTL_WMI_SET_AUTHMODE 49 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_REASSOCMODE 50 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_WMM 51 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_HB_CHALLENGE_RESP_PARAMS 52 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_GET_HB_CHALLENGE_RESP 53 */ -(INFRA_NETWORK | ADHOC_NETWORK | AP_NETWORK), /* AR6000_XIOCTL_WMI_GET_RD 54 */ -(0xFF), /* AR6000_XIOCTL_DIAG_READ 55 */ -(0xFF), /* AR6000_XIOCTL_DIAG_WRITE 56 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_TXOP 57 */ -(INFRA_NETWORK), /* AR6000_XIOCTL_USER_SETKEYS 58 */ -(INFRA_NETWORK), /* AR6000_XIOCTL_WMI_SET_KEEPALIVE 59 */ -(INFRA_NETWORK), /* AR6000_XIOCTL_WMI_GET_KEEPALIVE 60 */ -(0xFF), /* AR6000_XIOCTL_BMI_ROMPATCH_INSTALL 61 */ -(0xFF), /* AR6000_XIOCTL_BMI_ROMPATCH_UNINSTALL 62 */ -(0xFF), /* AR6000_XIOCTL_BMI_ROMPATCH_ACTIVATE 63 */ -(0xFF), /* AR6000_XIOCTL_BMI_ROMPATCH_DEACTIVATE 64 */ -(0xFF), /* AR6000_XIOCTL_WMI_SET_APPIE 65 */ -(0xFF), /* AR6000_XIOCTL_WMI_SET_MGMT_FRM_RX_FILTER 66 */ -(0xFF), /* AR6000_XIOCTL_DBGLOG_CFG_MODULE 67 */ -(0xFF), /* AR6000_XIOCTL_DBGLOG_GET_DEBUG_LOGS 68 */ -(0xFF), /* Dummy 69 */ -(0xFF), /* AR6000_XIOCTL_WMI_SET_WSC_STATUS 70 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BT_STATUS 71 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BT_PARAMS 72 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_HOST_SLEEP_MODE 73 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_WOW_MODE 74 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_GET_WOW_LIST 75 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_ADD_WOW_PATTERN 76 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_DEL_WOW_PATTERN 77 */ -(0xFF), /* AR6000_XIOCTL_TARGET_INFO 78 */ -(0xFF), /* AR6000_XIOCTL_DUMP_HTC_CREDIT_STATE 79 */ -(0xFF), /* AR6000_XIOCTL_TRAFFIC_ACTIVITY_CHANGE 80 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_CONNECT_CTRL_FLAGS 81 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_AKMP_PARAMS 82 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_GET_PMKID_LIST 83 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_PMKID_LIST 84 */ -(0xFF), /* Dummy 85 */ -(0xFF), /* Dummy 86 */ -(0xFF), /* Dummy 87 */ -(0xFF), /* Dummy 88 */ -(0xFF), /* Dummy 89 */ -(0xFF), /* AR6000_XIOCTL_UNUSED90 90 */ -(0xFF), /* AR6000_XIOCTL_BMI_LZ_STREAM_START 91 */ -(0xFF), /* AR6000_XIOCTL_BMI_LZ_DATA 92 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_PROF_CFG 93 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_PROF_ADDR_SET 94 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_PROF_START 95 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_PROF_STOP 96 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_PROF_COUNT_GET 97 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_ABORT_SCAN 98 */ -(AP_NETWORK), /* AR6000_XIOCTL_AP_GET_STA_LIST 99 */ -(AP_NETWORK), /* AR6000_XIOCTL_AP_HIDDEN_SSID 100 */ -(AP_NETWORK), /* AR6000_XIOCTL_AP_SET_NUM_STA 101 */ -(AP_NETWORK), /* AR6000_XIOCTL_AP_SET_ACL_MAC 102 */ -(AP_NETWORK), /* AR6000_XIOCTL_AP_GET_ACL_LIST 103 */ -(AP_NETWORK), /* AR6000_XIOCTL_AP_COMMIT_CONFIG 104 */ -(AP_NETWORK), /* IEEE80211_IOCTL_GETWPAIE 105 */ -(AP_NETWORK), /* AR6000_XIOCTL_AP_CONN_INACT_TIME 106 */ -(AP_NETWORK), /* AR6000_XIOCTL_AP_PROT_SCAN_TIME 107 */ -(AP_NETWORK), /* AR6000_XIOCTL_WMI_SET_COUNTRY 108 */ -(AP_NETWORK), /* AR6000_XIOCTL_AP_SET_DTIM 109 */ -(0xFF), /* AR6000_XIOCTL_WMI_TARGET_EVENT_REPORT 110 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_SET_IP 111 */ -(AP_NETWORK), /* AR6000_XIOCTL_AP_SET_ACL_POLICY 112 */ -(AP_NETWORK), /* AR6000_XIOCTL_AP_INTRA_BSS_COMM 113 */ -(0xFF), /* AR6000_XIOCTL_DUMP_MODULE_DEBUG_INFO 114 */ -(0xFF), /* AR6000_XIOCTL_MODULE_DEBUG_SET_MASK 115 */ -(0xFF), /* AR6000_XIOCTL_MODULE_DEBUG_GET_MASK 116 */ -(0xFF), /* AR6000_XIOCTL_DUMP_RCV_AGGR_STATS 117 */ -(0xFF), /* AR6000_XIOCTL_SET_HT_CAP 118 */ -(0xFF), /* AR6000_XIOCTL_SET_HT_OP 119 */ -(AP_NETWORK), /* AR6000_XIOCTL_AP_GET_STAT 120 */ -(0xFF), /* AR6000_XIOCTL_SET_TX_SELECT_RATES 121 */ -(0xFF), /* AR6000_XIOCTL_SETUP_AGGR 122 */ -(0xFF), /* AR6000_XIOCTL_ALLOW_AGGR 123 */ -(AP_NETWORK), /* AR6000_XIOCTL_AP_GET_HIDDEN_SSID 124 */ -(AP_NETWORK), /* AR6000_XIOCTL_AP_GET_COUNTRY 125 */ -(AP_NETWORK), /* AR6000_XIOCTL_AP_GET_WMODE 126 */ -(AP_NETWORK), /* AR6000_XIOCTL_AP_GET_DTIM 127 */ -(AP_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_AP_GET_BINTVL 128 */ -(0xFF), /* AR6000_XIOCTL_AP_GET_RTS 129 */ -(0xFF), /* AR6000_XIOCTL_DELE_AGGR 130 */ -(0xFF), /* AR6000_XIOCTL_FETCH_TARGET_REGS 131 */ -(0xFF), /* AR6000_XIOCTL_HCI_CMD 132 */ -(0xFF), /* AR6000_XIOCTL_ACL_DATA(used to be used for PAL) 133 */ -(0xFF), /* AR6000_XIOCTL_WLAN_CONN_PRECEDENCE 134 */ -(AP_NETWORK), /* AR6000_XIOCTL_AP_SET_11BG_RATESET 135 */ -(0xFF), -(0xFF), -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BTCOEX_FE_ANT 138 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BTCOEX_COLOCATED_BT_DEV 139 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG 140 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BTCOEX_SCO_CONFIG 141 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BTCOEX_A2DP_CONFIG 142 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BTCOEX_ACLCOEX_CONFIG 143 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BTCOEX_DEBUG 144 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_BT_OPERATING_STATUS 145 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_GET_BTCOEX_CONFIG 146 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_GET_BTCOEX_GET_STATS 147 */ -(0xFF), /* AR6000_XIOCTL_WMI_SET_QOS_SUPP 148 */ -(0xFF), /* AR6000_XIOCTL_GET_WLAN_SLEEP_STATE 149 */ -(0xFF), /* AR6000_XIOCTL_SET_BT_HW_POWER_STATE 150 */ -(0xFF), /* AR6000_XIOCTL_GET_BT_HW_POWER_STATE 151 */ -(0xFF), /* AR6000_XIOCTL_ADD_AP_INTERFACE 152 */ -(0xFF), /* AR6000_XIOCTL_REMOVE_AP_INTERFACE 153 */ -(0xFF), /* AR6000_XIOCTL_WMI_SET_TX_SGI_PARAM 154 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_WPA_OFFLOAD_STATE 155 */ -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_PASSPHRASE 156 */ -(0xFF), -(0xFF), -(0xFF), -(0xFF), -(INFRA_NETWORK | ADHOC_NETWORK), /* AR6000_XIOCTL_WMI_SET_EXCESS_TX_RETRY_THRES 161 */ -}; - -#endif /*_WMI_FILTER_LINUX_H_*/ diff --git a/drivers/staging/ath6kl/os/linux/netbuf.c b/drivers/staging/ath6kl/os/linux/netbuf.c deleted file mode 100644 index 963a2fb..0000000 --- a/drivers/staging/ath6kl/os/linux/netbuf.c +++ /dev/null @@ -1,231 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2004-2010 Atheros Communications Inc. -// All rights reserved. -// -// -// -// 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. -// -// -// -// Author(s): ="Atheros" -//------------------------------------------------------------------------------ -#include <a_config.h> -#include "athdefs.h" -#include "a_osapi.h" -#include "htc_packet.h" - -#define AR6000_DATA_OFFSET 64 - -void a_netbuf_enqueue(A_NETBUF_QUEUE_T *q, void *pkt) -{ - skb_queue_tail((struct sk_buff_head *) q, (struct sk_buff *) pkt); -} - -void a_netbuf_prequeue(A_NETBUF_QUEUE_T *q, void *pkt) -{ - skb_queue_head((struct sk_buff_head *) q, (struct sk_buff *) pkt); -} - -void *a_netbuf_dequeue(A_NETBUF_QUEUE_T *q) -{ - return((void *) skb_dequeue((struct sk_buff_head *) q)); -} - -int a_netbuf_queue_size(A_NETBUF_QUEUE_T *q) -{ - return(skb_queue_len((struct sk_buff_head *) q)); -} - -int a_netbuf_queue_empty(A_NETBUF_QUEUE_T *q) -{ - return(skb_queue_empty((struct sk_buff_head *) q)); -} - -void a_netbuf_queue_init(A_NETBUF_QUEUE_T *q) -{ - skb_queue_head_init((struct sk_buff_head *) q); -} - -void * -a_netbuf_alloc(int size) -{ - struct sk_buff *skb; - size += 2 * (A_GET_CACHE_LINE_BYTES()); /* add some cacheline space at front and back of buffer */ - skb = dev_alloc_skb(AR6000_DATA_OFFSET + sizeof(struct htc_packet) + size); - skb_reserve(skb, AR6000_DATA_OFFSET + sizeof(struct htc_packet) + A_GET_CACHE_LINE_BYTES()); - return ((void *)skb); -} - -/* - * Allocate an SKB w.o. any encapsulation requirement. - */ -void * -a_netbuf_alloc_raw(int size) -{ - struct sk_buff *skb; - - skb = dev_alloc_skb(size); - - return ((void *)skb); -} - -void -a_netbuf_free(void *bufPtr) -{ - struct sk_buff *skb = (struct sk_buff *)bufPtr; - - dev_kfree_skb(skb); -} - -u32 a_netbuf_to_len(void *bufPtr) -{ - return (((struct sk_buff *)bufPtr)->len); -} - -void * -a_netbuf_to_data(void *bufPtr) -{ - return (((struct sk_buff *)bufPtr)->data); -} - -/* - * Add len # of bytes to the beginning of the network buffer - * pointed to by bufPtr - */ -int -a_netbuf_push(void *bufPtr, s32 len) -{ - skb_push((struct sk_buff *)bufPtr, len); - - return 0; -} - -/* - * Add len # of bytes to the beginning of the network buffer - * pointed to by bufPtr and also fill with data - */ -int -a_netbuf_push_data(void *bufPtr, char *srcPtr, s32 len) -{ - skb_push((struct sk_buff *) bufPtr, len); - memcpy(((struct sk_buff *)bufPtr)->data, srcPtr, len); - - return 0; -} - -/* - * Add len # of bytes to the end of the network buffer - * pointed to by bufPtr - */ -int -a_netbuf_put(void *bufPtr, s32 len) -{ - skb_put((struct sk_buff *)bufPtr, len); - - return 0; -} - -/* - * Add len # of bytes to the end of the network buffer - * pointed to by bufPtr and also fill with data - */ -int -a_netbuf_put_data(void *bufPtr, char *srcPtr, s32 len) -{ - char *start = (char*)(((struct sk_buff *)bufPtr)->data + - ((struct sk_buff *)bufPtr)->len); - skb_put((struct sk_buff *)bufPtr, len); - memcpy(start, srcPtr, len); - - return 0; -} - - -/* - * Trim the network buffer pointed to by bufPtr to len # of bytes - */ -int -a_netbuf_setlen(void *bufPtr, s32 len) -{ - skb_trim((struct sk_buff *)bufPtr, len); - - return 0; -} - -/* - * Chop of len # of bytes from the end of the buffer. - */ -int -a_netbuf_trim(void *bufPtr, s32 len) -{ - skb_trim((struct sk_buff *)bufPtr, ((struct sk_buff *)bufPtr)->len - len); - - return 0; -} - -/* - * Chop of len # of bytes from the end of the buffer and return the data. - */ -int -a_netbuf_trim_data(void *bufPtr, char *dstPtr, s32 len) -{ - char *start = (char*)(((struct sk_buff *)bufPtr)->data + - (((struct sk_buff *)bufPtr)->len - len)); - - memcpy(dstPtr, start, len); - skb_trim((struct sk_buff *)bufPtr, ((struct sk_buff *)bufPtr)->len - len); - - return 0; -} - - -/* - * Returns the number of bytes available to a a_netbuf_push() - */ -s32 a_netbuf_headroom(void *bufPtr) -{ - return (skb_headroom((struct sk_buff *)bufPtr)); -} - -/* - * Removes specified number of bytes from the beginning of the buffer - */ -int -a_netbuf_pull(void *bufPtr, s32 len) -{ - skb_pull((struct sk_buff *)bufPtr, len); - - return 0; -} - -/* - * Removes specified number of bytes from the beginning of the buffer - * and return the data - */ -int -a_netbuf_pull_data(void *bufPtr, char *dstPtr, s32 len) -{ - memcpy(dstPtr, ((struct sk_buff *)bufPtr)->data, len); - skb_pull((struct sk_buff *)bufPtr, len); - - return 0; -} - -#ifdef EXPORT_HCI_BRIDGE_INTERFACE -EXPORT_SYMBOL(a_netbuf_to_data); -EXPORT_SYMBOL(a_netbuf_put); -EXPORT_SYMBOL(a_netbuf_pull); -EXPORT_SYMBOL(a_netbuf_alloc); -EXPORT_SYMBOL(a_netbuf_free); -#endif diff --git a/drivers/staging/ath6kl/reorder/aggr_rx_internal.h b/drivers/staging/ath6kl/reorder/aggr_rx_internal.h deleted file mode 100644 index 1112596..0000000 --- a/drivers/staging/ath6kl/reorder/aggr_rx_internal.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * - * Copyright (c) 2004-2010 Atheros Communications Inc. - * All rights reserved. - * - * -// -// 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 __AGGR_RX_INTERNAL_H__ -#define __AGGR_RX_INTERNAL_H__ - -#include "a_osapi.h" -#include "aggr_recv_api.h" - -#define AGGR_WIN_IDX(x, y) ((x) % (y)) -#define AGGR_INCR_IDX(x, y) AGGR_WIN_IDX(((x)+1), (y)) -#define AGGR_DCRM_IDX(x, y) AGGR_WIN_IDX(((x)-1), (y)) -#define IEEE80211_MAX_SEQ_NO 0xFFF -#define IEEE80211_NEXT_SEQ_NO(x) (((x) + 1) & IEEE80211_MAX_SEQ_NO) - - -#define NUM_OF_TIDS 8 -#define AGGR_SZ_DEFAULT 8 - -#define AGGR_WIN_SZ_MIN 2 -#define AGGR_WIN_SZ_MAX 8 -/* TID Window sz is double of what is negotiated. Derive TID_WINDOW_SZ from win_sz, per tid */ -#define TID_WINDOW_SZ(_x) ((_x) << 1) - -#define AGGR_NUM_OF_FREE_NETBUFS 16 - -#define AGGR_GET_RXTID_STATS(_p, _x) (&(_p->stat[(_x)])) -#define AGGR_GET_RXTID(_p, _x) (&(_p->RxTid[(_x)])) - -/* Hold q is a function of win_sz, which is negotiated per tid */ -#define HOLD_Q_SZ(_x) (TID_WINDOW_SZ((_x))*sizeof(struct osbuf_hold_q)) -/* AGGR_RX_TIMEOUT value is important as a (too) small value can cause frames to be - * delivered out of order and a (too) large value can cause undesirable latency in - * certain situations. */ -#define AGGR_RX_TIMEOUT 400 /* Timeout(in ms) for delivery of frames, if they are stuck */ - -typedef enum { - ALL_SEQNO = 0, - CONTIGUOUS_SEQNO = 1, -}DELIVERY_ORDER; - -struct osbuf_hold_q { - void *osbuf; - bool is_amsdu; - u16 seq_no; -}; - - -#if 0 -/* XXX: unused ? */ -struct window_snapshot { - u16 seqno_st; - u16 seqno_end; -}; -#endif - -struct rxtid { - bool aggr; /* is it ON or OFF */ - bool progress; /* true when frames have arrived after a timer start */ - bool timerMon; /* true if the timer started for the sake of this TID */ - u16 win_sz; /* negotiated window size */ - u16 seq_next; /* Next seq no, in current window */ - u32 hold_q_sz; /* Num of frames that can be held in hold q */ - struct osbuf_hold_q *hold_q; /* Hold q for re-order */ -#if 0 - struct window_snapshot old_win; /* Sliding window snapshot - for timeout */ -#endif - A_NETBUF_QUEUE_T q; /* q head for enqueuing frames for dispatch */ - A_MUTEX_T lock; -}; - -struct rxtid_stats { - u32 num_into_aggr; /* hitting at the input of this module */ - u32 num_dups; /* duplicate */ - u32 num_oow; /* out of window */ - u32 num_mpdu; /* single payload 802.3/802.11 frame */ - u32 num_amsdu; /* AMSDU */ - u32 num_delivered; /* frames delivered to IP stack */ - u32 num_timeouts; /* num of timeouts, during which frames delivered */ - u32 num_hole; /* frame not present, when window moved over */ - u32 num_bar; /* num of resets of seq_num, via BAR */ -}; - -struct aggr_info { - u8 aggr_sz; /* config value of aggregation size */ - u8 timerScheduled; - A_TIMER timer; /* timer for returning held up pkts in re-order que */ - void *dev; /* dev handle */ - RX_CALLBACK rx_fn; /* callback function to return frames; to upper layer */ - struct rxtid RxTid[NUM_OF_TIDS]; /* Per tid window */ - ALLOC_NETBUFS netbuf_allocator; /* OS netbuf alloc fn */ - A_NETBUF_QUEUE_T freeQ; /* pre-allocated buffers - for A_MSDU slicing */ - struct rxtid_stats stat[NUM_OF_TIDS]; /* Tid based statistics */ - PACKET_LOG pkt_log; /* Log info of the packets */ -}; - -#endif /* __AGGR_RX_INTERNAL_H__ */ diff --git a/drivers/staging/ath6kl/reorder/rcv_aggr.c b/drivers/staging/ath6kl/reorder/rcv_aggr.c deleted file mode 100644 index 9b1509e..0000000 --- a/drivers/staging/ath6kl/reorder/rcv_aggr.c +++ /dev/null @@ -1,661 +0,0 @@ -/* - * - * Copyright (c) 2010 Atheros Communications Inc. - * All rights reserved. - * - * -// -// 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 <a_config.h> -#include <athdefs.h> -#include <a_osapi.h> -#include <a_debug.h> -#include "pkt_log.h" -#include "aggr_recv_api.h" -#include "aggr_rx_internal.h" -#include "wmi.h" - -extern int -wmi_dot3_2_dix(void *osbuf); - -static void -aggr_slice_amsdu(struct aggr_info *p_aggr, struct rxtid *rxtid, void **osbuf); - -static void -aggr_timeout(unsigned long arg); - -static void -aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, u16 seq_no, u8 order); - -static void -aggr_dispatch_frames(struct aggr_info *p_aggr, A_NETBUF_QUEUE_T *q); - -static void * -aggr_get_osbuf(struct aggr_info *p_aggr); - -void * -aggr_init(ALLOC_NETBUFS netbuf_allocator) -{ - struct aggr_info *p_aggr = NULL; - struct rxtid *rxtid; - u8 i; - int status = 0; - - A_PRINTF("In aggr_init..\n"); - - do { - p_aggr = A_MALLOC(sizeof(struct aggr_info)); - if(!p_aggr) { - A_PRINTF("Failed to allocate memory for aggr_node\n"); - status = A_ERROR; - break; - } - - /* Init timer and data structures */ - A_MEMZERO(p_aggr, sizeof(struct aggr_info)); - p_aggr->aggr_sz = AGGR_SZ_DEFAULT; - A_INIT_TIMER(&p_aggr->timer, aggr_timeout, p_aggr); - p_aggr->timerScheduled = false; - A_NETBUF_QUEUE_INIT(&p_aggr->freeQ); - - p_aggr->netbuf_allocator = netbuf_allocator; - p_aggr->netbuf_allocator(&p_aggr->freeQ, AGGR_NUM_OF_FREE_NETBUFS); - - for(i = 0; i < NUM_OF_TIDS; i++) { - rxtid = AGGR_GET_RXTID(p_aggr, i); - rxtid->aggr = false; - rxtid->progress = false; - rxtid->timerMon = false; - A_NETBUF_QUEUE_INIT(&rxtid->q); - A_MUTEX_INIT(&rxtid->lock); - } - }while(false); - - A_PRINTF("going out of aggr_init..status %s\n", - (status == 0) ? "OK":"Error"); - - if (status) { - /* Cleanup */ - aggr_module_destroy(p_aggr); - } - return ((status == 0) ? p_aggr : NULL); -} - -/* utility function to clear rx hold_q for a tid */ -static void -aggr_delete_tid_state(struct aggr_info *p_aggr, u8 tid) -{ - struct rxtid *rxtid; - struct rxtid_stats *stats; - - A_ASSERT(tid < NUM_OF_TIDS && p_aggr); - - rxtid = AGGR_GET_RXTID(p_aggr, tid); - stats = AGGR_GET_RXTID_STATS(p_aggr, tid); - - if(rxtid->aggr) { - aggr_deque_frms(p_aggr, tid, 0, ALL_SEQNO); - } - - rxtid->aggr = false; - rxtid->progress = false; - rxtid->timerMon = false; - rxtid->win_sz = 0; - rxtid->seq_next = 0; - rxtid->hold_q_sz = 0; - - if(rxtid->hold_q) { - kfree(rxtid->hold_q); - rxtid->hold_q = NULL; - } - - A_MEMZERO(stats, sizeof(struct rxtid_stats)); -} - -void -aggr_module_destroy(void *cntxt) -{ - struct aggr_info *p_aggr = (struct aggr_info *)cntxt; - struct rxtid *rxtid; - u8 i, k; - A_PRINTF("%s(): aggr = %p\n",_A_FUNCNAME_, p_aggr); - A_ASSERT(p_aggr); - - if(p_aggr) { - if(p_aggr->timerScheduled) { - A_UNTIMEOUT(&p_aggr->timer); - p_aggr->timerScheduled = false; - } - - for(i = 0; i < NUM_OF_TIDS; i++) { - rxtid = AGGR_GET_RXTID(p_aggr, i); - /* Free the hold q contents and hold_q*/ - if(rxtid->hold_q) { - for(k = 0; k< rxtid->hold_q_sz; k++) { - if(rxtid->hold_q[k].osbuf) { - A_NETBUF_FREE(rxtid->hold_q[k].osbuf); - } - } - kfree(rxtid->hold_q); - } - /* Free the dispatch q contents*/ - while(A_NETBUF_QUEUE_SIZE(&rxtid->q)) { - A_NETBUF_FREE(A_NETBUF_DEQUEUE(&rxtid->q)); - } - if (A_IS_MUTEX_VALID(&rxtid->lock)) { - A_MUTEX_DELETE(&rxtid->lock); - } - } - /* free the freeQ and its contents*/ - while(A_NETBUF_QUEUE_SIZE(&p_aggr->freeQ)) { - A_NETBUF_FREE(A_NETBUF_DEQUEUE(&p_aggr->freeQ)); - } - kfree(p_aggr); - } - A_PRINTF("out aggr_module_destroy\n"); -} - - -void -aggr_register_rx_dispatcher(void *cntxt, void * dev, RX_CALLBACK fn) -{ - struct aggr_info *p_aggr = (struct aggr_info *)cntxt; - - A_ASSERT(p_aggr && fn && dev); - - p_aggr->rx_fn = fn; - p_aggr->dev = dev; -} - - -void -aggr_process_bar(void *cntxt, u8 tid, u16 seq_no) -{ - struct aggr_info *p_aggr = (struct aggr_info *)cntxt; - struct rxtid_stats *stats; - - A_ASSERT(p_aggr); - stats = AGGR_GET_RXTID_STATS(p_aggr, tid); - stats->num_bar++; - - aggr_deque_frms(p_aggr, tid, seq_no, ALL_SEQNO); -} - - -void -aggr_recv_addba_req_evt(void *cntxt, u8 tid, u16 seq_no, u8 win_sz) -{ - struct aggr_info *p_aggr = (struct aggr_info *)cntxt; - struct rxtid *rxtid; - struct rxtid_stats *stats; - - A_ASSERT(p_aggr); - rxtid = AGGR_GET_RXTID(p_aggr, tid); - stats = AGGR_GET_RXTID_STATS(p_aggr, tid); - - A_PRINTF("%s(): win_sz = %d aggr %d\n", _A_FUNCNAME_, win_sz, rxtid->aggr); - if(win_sz < AGGR_WIN_SZ_MIN || win_sz > AGGR_WIN_SZ_MAX) { - A_PRINTF("win_sz %d, tid %d\n", win_sz, tid); - } - - if(rxtid->aggr) { - /* Just go and deliver all the frames up from this - * queue, as if we got DELBA and re-initialize the queue - */ - aggr_delete_tid_state(p_aggr, tid); - } - - rxtid->seq_next = seq_no; - /* create these queues, only upon receiving of ADDBA for a - * tid, reducing memory requirement - */ - rxtid->hold_q = A_MALLOC(HOLD_Q_SZ(win_sz)); - if((rxtid->hold_q == NULL)) { - A_PRINTF("Failed to allocate memory, tid = %d\n", tid); - A_ASSERT(0); - } - A_MEMZERO(rxtid->hold_q, HOLD_Q_SZ(win_sz)); - - /* Update rxtid for the window sz */ - rxtid->win_sz = win_sz; - /* hold_q_sz inicates the depth of holding q - which is - * a factor of win_sz. Compute once, as it will be used often - */ - rxtid->hold_q_sz = TID_WINDOW_SZ(win_sz); - /* There should be no frames on q - even when second ADDBA comes in. - * If aggr was previously ON on this tid, we would have cleaned up - * the q - */ - if(A_NETBUF_QUEUE_SIZE(&rxtid->q) != 0) { - A_PRINTF("ERROR: Frames still on queue ?\n"); - A_ASSERT(0); - } - - rxtid->aggr = true; -} - -void -aggr_recv_delba_req_evt(void *cntxt, u8 tid) -{ - struct aggr_info *p_aggr = (struct aggr_info *)cntxt; - struct rxtid *rxtid; - - A_ASSERT(p_aggr); - A_PRINTF("%s(): tid %d\n", _A_FUNCNAME_, tid); - - rxtid = AGGR_GET_RXTID(p_aggr, tid); - - if(rxtid->aggr) { - aggr_delete_tid_state(p_aggr, tid); - } -} - -static void -aggr_deque_frms(struct aggr_info *p_aggr, u8 tid, u16 seq_no, u8 order) -{ - struct rxtid *rxtid; - struct osbuf_hold_q *node; - u16 idx, idx_end, seq_end; - struct rxtid_stats *stats; - - A_ASSERT(p_aggr); - rxtid = AGGR_GET_RXTID(p_aggr, tid); - stats = AGGR_GET_RXTID_STATS(p_aggr, tid); - - /* idx is absolute location for first frame */ - idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz); - - /* idx_end is typically the last possible frame in the window, - * but changes to 'the' seq_no, when BAR comes. If seq_no - * is non-zero, we will go up to that and stop. - * Note: last seq no in current window will occupy the same - * index position as index that is just previous to start. - * An imp point : if win_sz is 7, for seq_no space of 4095, - * then, there would be holes when sequence wrap around occurs. - * Target should judiciously choose the win_sz, based on - * this condition. For 4095, (TID_WINDOW_SZ = 2 x win_sz - * 2, 4, 8, 16 win_sz works fine). - * We must deque from "idx" to "idx_end", including both. - */ - seq_end = (seq_no) ? seq_no : rxtid->seq_next; - idx_end = AGGR_WIN_IDX(seq_end, rxtid->hold_q_sz); - - /* Critical section begins */ - A_MUTEX_LOCK(&rxtid->lock); - do { - - node = &rxtid->hold_q[idx]; - - if((order == CONTIGUOUS_SEQNO) && (!node->osbuf)) - break; - - /* chain frames and deliver frames bcos: - * 1. either the frames are in order and window is contiguous, OR - * 2. we need to deque frames, irrespective of holes - */ - if(node->osbuf) { - if(node->is_amsdu) { - aggr_slice_amsdu(p_aggr, rxtid, &node->osbuf); - } else { - A_NETBUF_ENQUEUE(&rxtid->q, node->osbuf); - } - node->osbuf = NULL; - } else { - stats->num_hole++; - } - - /* window is moving */ - rxtid->seq_next = IEEE80211_NEXT_SEQ_NO(rxtid->seq_next); - idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz); - } while(idx != idx_end); - /* Critical section ends */ - A_MUTEX_UNLOCK(&rxtid->lock); - - stats->num_delivered += A_NETBUF_QUEUE_SIZE(&rxtid->q); - aggr_dispatch_frames(p_aggr, &rxtid->q); -} - -static void * -aggr_get_osbuf(struct aggr_info *p_aggr) -{ - void *buf = NULL; - - /* Starving for buffers? get more from OS - * check for low netbuffers( < 1/4 AGGR_NUM_OF_FREE_NETBUFS) : - * re-allocate bufs if so - * allocate a free buf from freeQ - */ - if (A_NETBUF_QUEUE_SIZE(&p_aggr->freeQ) < (AGGR_NUM_OF_FREE_NETBUFS >> 2)) { - p_aggr->netbuf_allocator(&p_aggr->freeQ, AGGR_NUM_OF_FREE_NETBUFS); - } - - if (A_NETBUF_QUEUE_SIZE(&p_aggr->freeQ)) { - buf = A_NETBUF_DEQUEUE(&p_aggr->freeQ); - } - - return buf; -} - - -static void -aggr_slice_amsdu(struct aggr_info *p_aggr, struct rxtid *rxtid, void **osbuf) -{ - void *new_buf; - u16 frame_8023_len, payload_8023_len, mac_hdr_len, amsdu_len; - u8 *framep; - - /* Frame format at this point: - * [DIX hdr | 802.3 | 802.3 | ... | 802.3] - * - * Strip the DIX header. - * Iterate through the osbuf and do: - * grab a free netbuf from freeQ - * find the start and end of a frame - * copy it to netbuf(Vista can do better here) - * convert all msdu's(802.3) frames to upper layer format - os routine - * -for now lets convert from 802.3 to dix - * enque this to dispatch q of tid - * repeat - * free the osbuf - to OS. It's been sliced. - */ - - mac_hdr_len = sizeof(ATH_MAC_HDR); - framep = A_NETBUF_DATA(*osbuf) + mac_hdr_len; - amsdu_len = A_NETBUF_LEN(*osbuf) - mac_hdr_len; - - while(amsdu_len > mac_hdr_len) { - /* Begin of a 802.3 frame */ - payload_8023_len = A_BE2CPU16(((ATH_MAC_HDR *)framep)->typeOrLen); -#define MAX_MSDU_SUBFRAME_PAYLOAD_LEN 1508 -#define MIN_MSDU_SUBFRAME_PAYLOAD_LEN 46 - if(payload_8023_len < MIN_MSDU_SUBFRAME_PAYLOAD_LEN || payload_8023_len > MAX_MSDU_SUBFRAME_PAYLOAD_LEN) { - A_PRINTF("802.3 AMSDU frame bound check failed. len %d\n", payload_8023_len); - break; - } - frame_8023_len = payload_8023_len + mac_hdr_len; - new_buf = aggr_get_osbuf(p_aggr); - if(new_buf == NULL) { - A_PRINTF("No buffer available \n"); - break; - } - - memcpy(A_NETBUF_DATA(new_buf), framep, frame_8023_len); - A_NETBUF_PUT(new_buf, frame_8023_len); - if (wmi_dot3_2_dix(new_buf) != 0) { - A_PRINTF("dot3_2_dix err..\n"); - A_NETBUF_FREE(new_buf); - break; - } - - A_NETBUF_ENQUEUE(&rxtid->q, new_buf); - - /* Is this the last subframe within this aggregate ? */ - if ((amsdu_len - frame_8023_len) == 0) { - break; - } - - /* Add the length of A-MSDU subframe padding bytes - - * Round to nearest word. - */ - frame_8023_len = ((frame_8023_len + 3) & ~3); - - framep += frame_8023_len; - amsdu_len -= frame_8023_len; - } - - A_NETBUF_FREE(*osbuf); - *osbuf = NULL; -} - -void -aggr_process_recv_frm(void *cntxt, u8 tid, u16 seq_no, bool is_amsdu, void **osbuf) -{ - struct aggr_info *p_aggr = (struct aggr_info *)cntxt; - struct rxtid *rxtid; - struct rxtid_stats *stats; - u16 idx, st, cur, end; - u16 *log_idx; - struct osbuf_hold_q *node; - PACKET_LOG *log; - - A_ASSERT(p_aggr); - A_ASSERT(tid < NUM_OF_TIDS); - - rxtid = AGGR_GET_RXTID(p_aggr, tid); - stats = AGGR_GET_RXTID_STATS(p_aggr, tid); - - stats->num_into_aggr++; - - if(!rxtid->aggr) { - if(is_amsdu) { - aggr_slice_amsdu(p_aggr, rxtid, osbuf); - stats->num_amsdu++; - aggr_dispatch_frames(p_aggr, &rxtid->q); - } - return; - } - - /* Check the incoming sequence no, if it's in the window */ - st = rxtid->seq_next; - cur = seq_no; - end = (st + rxtid->hold_q_sz-1) & IEEE80211_MAX_SEQ_NO; - /* Log the pkt info for future analysis */ - log = &p_aggr->pkt_log; - log_idx = &log->last_idx; - log->info[*log_idx].cur = cur; - log->info[*log_idx].st = st; - log->info[*log_idx].end = end; - *log_idx = IEEE80211_NEXT_SEQ_NO(*log_idx); - - if(((st < end) && (cur < st || cur > end)) || - ((st > end) && (cur > end) && (cur < st))) { - /* the cur frame is outside the window. Since we know - * our target would not do this without reason it must - * be assumed that the window has moved for some valid reason. - * Therefore, we dequeue all frames and start fresh. - */ - u16 extended_end; - - extended_end = (end + rxtid->hold_q_sz-1) & IEEE80211_MAX_SEQ_NO; - - if(((end < extended_end) && (cur < end || cur > extended_end)) || - ((end > extended_end) && (cur > extended_end) && (cur < end))) { - // dequeue all frames in queue and shift window to new frame - aggr_deque_frms(p_aggr, tid, 0, ALL_SEQNO); - //set window start so that new frame is last frame in window - if(cur >= rxtid->hold_q_sz-1) { - rxtid->seq_next = cur - (rxtid->hold_q_sz-1); - }else{ - rxtid->seq_next = IEEE80211_MAX_SEQ_NO - (rxtid->hold_q_sz-2 - cur); - } - } else { - // dequeue only those frames that are outside the new shifted window - if(cur >= rxtid->hold_q_sz-1) { - st = cur - (rxtid->hold_q_sz-1); - }else{ - st = IEEE80211_MAX_SEQ_NO - (rxtid->hold_q_sz-2 - cur); - } - - aggr_deque_frms(p_aggr, tid, st, ALL_SEQNO); - } - - stats->num_oow++; - } - - idx = AGGR_WIN_IDX(seq_no, rxtid->hold_q_sz); - - /*enque the frame, in hold_q */ - node = &rxtid->hold_q[idx]; - - A_MUTEX_LOCK(&rxtid->lock); - if(node->osbuf) { - /* Is the cur frame duplicate or something beyond our - * window(hold_q -> which is 2x, already)? - * 1. Duplicate is easy - drop incoming frame. - * 2. Not falling in current sliding window. - * 2a. is the frame_seq_no preceding current tid_seq_no? - * -> drop the frame. perhaps sender did not get our ACK. - * this is taken care of above. - * 2b. is the frame_seq_no beyond window(st, TID_WINDOW_SZ); - * -> Taken care of it above, by moving window forward. - * - */ - A_NETBUF_FREE(node->osbuf); - stats->num_dups++; - } - - node->osbuf = *osbuf; - node->is_amsdu = is_amsdu; - node->seq_no = seq_no; - if(node->is_amsdu) { - stats->num_amsdu++; - } else { - stats->num_mpdu++; - } - A_MUTEX_UNLOCK(&rxtid->lock); - - *osbuf = NULL; - aggr_deque_frms(p_aggr, tid, 0, CONTIGUOUS_SEQNO); - - if(p_aggr->timerScheduled) { - rxtid->progress = true; - }else{ - for(idx=0 ; idx<rxtid->hold_q_sz ; idx++) { - if(rxtid->hold_q[idx].osbuf) { - /* there is a frame in the queue and no timer so - * start a timer to ensure that the frame doesn't remain - * stuck forever. */ - p_aggr->timerScheduled = true; - A_TIMEOUT_MS(&p_aggr->timer, AGGR_RX_TIMEOUT, 0); - rxtid->progress = false; - rxtid->timerMon = true; - break; - } - } - } -} - -/* - * aggr_reset_state -- Called when it is deemed necessary to clear the aggregate - * hold Q state. Examples include when a Connect event or disconnect event is - * received. - */ -void -aggr_reset_state(void *cntxt) -{ - u8 tid; - struct aggr_info *p_aggr = (struct aggr_info *)cntxt; - - A_ASSERT(p_aggr); - - for(tid=0 ; tid<NUM_OF_TIDS ; tid++) { - aggr_delete_tid_state(p_aggr, tid); - } -} - - -static void -aggr_timeout(unsigned long arg) -{ - u8 i,j; - struct aggr_info *p_aggr = (struct aggr_info *)arg; - struct rxtid *rxtid; - struct rxtid_stats *stats; - /* - * If the q for which the timer was originally started has - * not progressed then it is necessary to dequeue all the - * contained frames so that they are not held forever. - */ - for(i = 0; i < NUM_OF_TIDS; i++) { - rxtid = AGGR_GET_RXTID(p_aggr, i); - stats = AGGR_GET_RXTID_STATS(p_aggr, i); - - if(rxtid->aggr == false || - rxtid->timerMon == false || - rxtid->progress == true) { - continue; - } - // dequeue all frames in for this tid - stats->num_timeouts++; - A_PRINTF("TO: st %d end %d\n", rxtid->seq_next, ((rxtid->seq_next + rxtid->hold_q_sz-1) & IEEE80211_MAX_SEQ_NO)); - aggr_deque_frms(p_aggr, i, 0, ALL_SEQNO); - } - - p_aggr->timerScheduled = false; - // determine whether a new timer should be started. - for(i = 0; i < NUM_OF_TIDS; i++) { - rxtid = AGGR_GET_RXTID(p_aggr, i); - - if(rxtid->aggr == true && rxtid->hold_q) { - for(j = 0 ; j < rxtid->hold_q_sz ; j++) - { - if(rxtid->hold_q[j].osbuf) - { - p_aggr->timerScheduled = true; - rxtid->timerMon = true; - rxtid->progress = false; - break; - } - } - - if(j >= rxtid->hold_q_sz) { - rxtid->timerMon = false; - } - } - } - - if(p_aggr->timerScheduled) { - /* Rearm the timer*/ - A_TIMEOUT_MS(&p_aggr->timer, AGGR_RX_TIMEOUT, 0); - } - -} - -static void -aggr_dispatch_frames(struct aggr_info *p_aggr, A_NETBUF_QUEUE_T *q) -{ - void *osbuf; - - while((osbuf = A_NETBUF_DEQUEUE(q))) { - p_aggr->rx_fn(p_aggr->dev, osbuf); - } -} - -void -aggr_dump_stats(void *cntxt, PACKET_LOG **log_buf) -{ - struct aggr_info *p_aggr = (struct aggr_info *)cntxt; - struct rxtid *rxtid; - struct rxtid_stats *stats; - u8 i; - - *log_buf = &p_aggr->pkt_log; - A_PRINTF("\n\n================================================\n"); - A_PRINTF("tid: num_into_aggr, dups, oow, mpdu, amsdu, delivered, timeouts, holes, bar, seq_next\n"); - for(i = 0; i < NUM_OF_TIDS; i++) { - stats = AGGR_GET_RXTID_STATS(p_aggr, i); - rxtid = AGGR_GET_RXTID(p_aggr, i); - A_PRINTF("%d: %d %d %d %d %d %d %d %d %d : %d\n", i, stats->num_into_aggr, stats->num_dups, - stats->num_oow, stats->num_mpdu, - stats->num_amsdu, stats->num_delivered, stats->num_timeouts, - stats->num_hole, stats->num_bar, - rxtid->seq_next); - } - A_PRINTF("================================================\n\n"); - -} diff --git a/drivers/staging/ath6kl/wlan/include/ieee80211.h b/drivers/staging/ath6kl/wlan/include/ieee80211.h deleted file mode 100644 index cf47d06..0000000 --- a/drivers/staging/ath6kl/wlan/include/ieee80211.h +++ /dev/null @@ -1,397 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="ieee80211.h" company="Atheros"> -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Author(s): ="Atheros" -//============================================================================== -#ifndef _NET80211_IEEE80211_H_ -#define _NET80211_IEEE80211_H_ - -/* - * 802.11 protocol definitions. - */ -#define IEEE80211_WEP_KEYLEN 5 /* 40bit */ -#define IEEE80211_WEP_IVLEN 3 /* 24bit */ -#define IEEE80211_WEP_KIDLEN 1 /* 1 octet */ -#define IEEE80211_WEP_CRCLEN 4 /* CRC-32 */ -#define IEEE80211_WEP_NKID 4 /* number of key ids */ - -/* - * 802.11i defines an extended IV for use with non-WEP ciphers. - * When the EXTIV bit is set in the key id byte an additional - * 4 bytes immediately follow the IV for TKIP. For CCMP the - * EXTIV bit is likewise set but the 8 bytes represent the - * CCMP header rather than IV+extended-IV. - */ -#define IEEE80211_WEP_EXTIV 0x20 -#define IEEE80211_WEP_EXTIVLEN 4 /* extended IV length */ -#define IEEE80211_WEP_MICLEN 8 /* trailing MIC */ - -#define IEEE80211_CRC_LEN 4 - -#ifdef WAPI_ENABLE -#define IEEE80211_WAPI_EXTIVLEN 10 /* extended IV length */ -#endif /* WAPI ENABLE */ - - -#define IEEE80211_ADDR_LEN 6 /* size of 802.11 address */ -/* is 802.11 address multicast/broadcast? */ -#define IEEE80211_IS_MULTICAST(_a) (*(_a) & 0x01) -#define IEEE80211_IS_BROADCAST(_a) (*(_a) == 0xFF) -#define WEP_HEADER (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN) -#define WEP_TRAILER IEEE80211_WEP_CRCLEN -#define CCMP_HEADER (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + \ - IEEE80211_WEP_EXTIVLEN) -#define CCMP_TRAILER IEEE80211_WEP_MICLEN -#define TKIP_HEADER (IEEE80211_WEP_IVLEN + IEEE80211_WEP_KIDLEN + \ - IEEE80211_WEP_EXTIVLEN) -#define TKIP_TRAILER IEEE80211_WEP_CRCLEN -#define TKIP_MICLEN IEEE80211_WEP_MICLEN - - -#define IEEE80211_ADDR_EQ(addr1, addr2) \ - (memcmp(addr1, addr2, IEEE80211_ADDR_LEN) == 0) - -#define IEEE80211_ADDR_COPY(dst,src) memcpy(dst,src,IEEE80211_ADDR_LEN) - -#define IEEE80211_KEYBUF_SIZE 16 -#define IEEE80211_MICBUF_SIZE (8+8) /* space for both tx and rx */ - -/* - * NB: these values are ordered carefully; there are lots of - * of implications in any reordering. In particular beware - * that 4 is not used to avoid conflicting with IEEE80211_F_PRIVACY. - */ -#define IEEE80211_CIPHER_WEP 0 -#define IEEE80211_CIPHER_TKIP 1 -#define IEEE80211_CIPHER_AES_OCB 2 -#define IEEE80211_CIPHER_AES_CCM 3 -#define IEEE80211_CIPHER_CKIP 5 -#define IEEE80211_CIPHER_CCKM_KRK 6 -#define IEEE80211_CIPHER_NONE 7 /* pseudo value */ - -#define IEEE80211_CIPHER_MAX (IEEE80211_CIPHER_NONE+1) - -#define IEEE80211_IS_VALID_WEP_CIPHER_LEN(len) \ - (((len) == 5) || ((len) == 13) || ((len) == 16)) - - - -/* - * generic definitions for IEEE 802.11 frames - */ -PREPACK struct ieee80211_frame { - u8 i_fc[2]; - u8 i_dur[2]; - u8 i_addr1[IEEE80211_ADDR_LEN]; - u8 i_addr2[IEEE80211_ADDR_LEN]; - u8 i_addr3[IEEE80211_ADDR_LEN]; - u8 i_seq[2]; - /* possibly followed by addr4[IEEE80211_ADDR_LEN]; */ - /* see below */ -} POSTPACK; - -PREPACK struct ieee80211_qosframe { - u8 i_fc[2]; - u8 i_dur[2]; - u8 i_addr1[IEEE80211_ADDR_LEN]; - u8 i_addr2[IEEE80211_ADDR_LEN]; - u8 i_addr3[IEEE80211_ADDR_LEN]; - u8 i_seq[2]; - u8 i_qos[2]; -} POSTPACK; - -#define IEEE80211_FC0_VERSION_MASK 0x03 -#define IEEE80211_FC0_VERSION_SHIFT 0 -#define IEEE80211_FC0_VERSION_0 0x00 -#define IEEE80211_FC0_TYPE_MASK 0x0c -#define IEEE80211_FC0_TYPE_SHIFT 2 -#define IEEE80211_FC0_TYPE_MGT 0x00 -#define IEEE80211_FC0_TYPE_CTL 0x04 -#define IEEE80211_FC0_TYPE_DATA 0x08 - -#define IEEE80211_FC0_SUBTYPE_MASK 0xf0 -#define IEEE80211_FC0_SUBTYPE_SHIFT 4 -/* for TYPE_MGT */ -#define IEEE80211_FC0_SUBTYPE_ASSOC_REQ 0x00 -#define IEEE80211_FC0_SUBTYPE_ASSOC_RESP 0x10 -#define IEEE80211_FC0_SUBTYPE_REASSOC_REQ 0x20 -#define IEEE80211_FC0_SUBTYPE_REASSOC_RESP 0x30 -#define IEEE80211_FC0_SUBTYPE_PROBE_REQ 0x40 -#define IEEE80211_FC0_SUBTYPE_PROBE_RESP 0x50 -#define IEEE80211_FC0_SUBTYPE_BEACON 0x80 -#define IEEE80211_FC0_SUBTYPE_ATIM 0x90 -#define IEEE80211_FC0_SUBTYPE_DISASSOC 0xa0 -#define IEEE80211_FC0_SUBTYPE_AUTH 0xb0 -#define IEEE80211_FC0_SUBTYPE_DEAUTH 0xc0 -/* for TYPE_CTL */ -#define IEEE80211_FC0_SUBTYPE_PS_POLL 0xa0 -#define IEEE80211_FC0_SUBTYPE_RTS 0xb0 -#define IEEE80211_FC0_SUBTYPE_CTS 0xc0 -#define IEEE80211_FC0_SUBTYPE_ACK 0xd0 -#define IEEE80211_FC0_SUBTYPE_CF_END 0xe0 -#define IEEE80211_FC0_SUBTYPE_CF_END_ACK 0xf0 -/* for TYPE_DATA (bit combination) */ -#define IEEE80211_FC0_SUBTYPE_DATA 0x00 -#define IEEE80211_FC0_SUBTYPE_CF_ACK 0x10 -#define IEEE80211_FC0_SUBTYPE_CF_POLL 0x20 -#define IEEE80211_FC0_SUBTYPE_CF_ACPL 0x30 -#define IEEE80211_FC0_SUBTYPE_NODATA 0x40 -#define IEEE80211_FC0_SUBTYPE_CFACK 0x50 -#define IEEE80211_FC0_SUBTYPE_CFPOLL 0x60 -#define IEEE80211_FC0_SUBTYPE_CF_ACK_CF_ACK 0x70 -#define IEEE80211_FC0_SUBTYPE_QOS 0x80 -#define IEEE80211_FC0_SUBTYPE_QOS_NULL 0xc0 - -#define IEEE80211_FC1_DIR_MASK 0x03 -#define IEEE80211_FC1_DIR_NODS 0x00 /* STA->STA */ -#define IEEE80211_FC1_DIR_TODS 0x01 /* STA->AP */ -#define IEEE80211_FC1_DIR_FROMDS 0x02 /* AP ->STA */ -#define IEEE80211_FC1_DIR_DSTODS 0x03 /* AP ->AP */ - -#define IEEE80211_FC1_MORE_FRAG 0x04 -#define IEEE80211_FC1_RETRY 0x08 -#define IEEE80211_FC1_PWR_MGT 0x10 -#define IEEE80211_FC1_MORE_DATA 0x20 -#define IEEE80211_FC1_WEP 0x40 -#define IEEE80211_FC1_ORDER 0x80 - -#define IEEE80211_SEQ_FRAG_MASK 0x000f -#define IEEE80211_SEQ_FRAG_SHIFT 0 -#define IEEE80211_SEQ_SEQ_MASK 0xfff0 -#define IEEE80211_SEQ_SEQ_SHIFT 4 - -#define IEEE80211_NWID_LEN 32 - -/* - * 802.11 rate set. - */ -#define IEEE80211_RATE_SIZE 8 /* 802.11 standard */ -#define IEEE80211_RATE_MAXSIZE 15 /* max rates we'll handle */ - -#define WMM_NUM_AC 4 /* 4 AC categories */ - -#define WMM_PARAM_ACI_M 0x60 /* Mask for ACI field */ -#define WMM_PARAM_ACI_S 5 /* Shift for ACI field */ -#define WMM_PARAM_ACM_M 0x10 /* Mask for ACM bit */ -#define WMM_PARAM_ACM_S 4 /* Shift for ACM bit */ -#define WMM_PARAM_AIFSN_M 0x0f /* Mask for aifsn field */ -#define WMM_PARAM_LOGCWMIN_M 0x0f /* Mask for CwMin field (in log) */ -#define WMM_PARAM_LOGCWMAX_M 0xf0 /* Mask for CwMax field (in log) */ -#define WMM_PARAM_LOGCWMAX_S 4 /* Shift for CwMax field */ - -#define WMM_AC_TO_TID(_ac) ( \ - ((_ac) == WMM_AC_VO) ? 6 : \ - ((_ac) == WMM_AC_VI) ? 5 : \ - ((_ac) == WMM_AC_BK) ? 1 : \ - 0) - -#define TID_TO_WMM_AC(_tid) ( \ - ((_tid) < 1) ? WMM_AC_BE : \ - ((_tid) < 3) ? WMM_AC_BK : \ - ((_tid) < 6) ? WMM_AC_VI : \ - WMM_AC_VO) -/* - * Management information element payloads. - */ - -enum { - IEEE80211_ELEMID_SSID = 0, - IEEE80211_ELEMID_RATES = 1, - IEEE80211_ELEMID_FHPARMS = 2, - IEEE80211_ELEMID_DSPARMS = 3, - IEEE80211_ELEMID_CFPARMS = 4, - IEEE80211_ELEMID_TIM = 5, - IEEE80211_ELEMID_IBSSPARMS = 6, - IEEE80211_ELEMID_COUNTRY = 7, - IEEE80211_ELEMID_CHALLENGE = 16, - /* 17-31 reserved for challenge text extension */ - IEEE80211_ELEMID_PWRCNSTR = 32, - IEEE80211_ELEMID_PWRCAP = 33, - IEEE80211_ELEMID_TPCREQ = 34, - IEEE80211_ELEMID_TPCREP = 35, - IEEE80211_ELEMID_SUPPCHAN = 36, - IEEE80211_ELEMID_CHANSWITCH = 37, - IEEE80211_ELEMID_MEASREQ = 38, - IEEE80211_ELEMID_MEASREP = 39, - IEEE80211_ELEMID_QUIET = 40, - IEEE80211_ELEMID_IBSSDFS = 41, - IEEE80211_ELEMID_ERP = 42, - IEEE80211_ELEMID_HTCAP_ANA = 45, /* Address ANA, and non-ANA story, for interop. CL#171733 */ - IEEE80211_ELEMID_RSN = 48, - IEEE80211_ELEMID_XRATES = 50, - IEEE80211_ELEMID_HTINFO_ANA = 61, -#ifdef WAPI_ENABLE - IEEE80211_ELEMID_WAPI = 68, -#endif - IEEE80211_ELEMID_TPC = 150, - IEEE80211_ELEMID_CCKM = 156, - IEEE80211_ELEMID_VENDOR = 221, /* vendor private */ -}; - -#define ATH_OUI 0x7f0300 /* Atheros OUI */ -#define ATH_OUI_TYPE 0x01 -#define ATH_OUI_SUBTYPE 0x01 -#define ATH_OUI_VERSION 0x00 - -#define WPA_OUI 0xf25000 -#define WPA_OUI_TYPE 0x01 -#define WPA_VERSION 1 /* current supported version */ - -#define WPA_CSE_NULL 0x00 -#define WPA_CSE_WEP40 0x01 -#define WPA_CSE_TKIP 0x02 -#define WPA_CSE_CCMP 0x04 -#define WPA_CSE_WEP104 0x05 - -#define WPA_ASE_NONE 0x00 -#define WPA_ASE_8021X_UNSPEC 0x01 -#define WPA_ASE_8021X_PSK 0x02 - -#define RSN_OUI 0xac0f00 -#define RSN_VERSION 1 /* current supported version */ - -#define RSN_CSE_NULL 0x00 -#define RSN_CSE_WEP40 0x01 -#define RSN_CSE_TKIP 0x02 -#define RSN_CSE_WRAP 0x03 -#define RSN_CSE_CCMP 0x04 -#define RSN_CSE_WEP104 0x05 - -#define RSN_ASE_NONE 0x00 -#define RSN_ASE_8021X_UNSPEC 0x01 -#define RSN_ASE_8021X_PSK 0x02 - -#define RSN_CAP_PREAUTH 0x01 - -#define WMM_OUI 0xf25000 -#define WMM_OUI_TYPE 0x02 -#define WMM_INFO_OUI_SUBTYPE 0x00 -#define WMM_PARAM_OUI_SUBTYPE 0x01 -#define WMM_VERSION 1 - -/* WMM stream classes */ -#define WMM_NUM_AC 4 -#define WMM_AC_BE 0 /* best effort */ -#define WMM_AC_BK 1 /* background */ -#define WMM_AC_VI 2 /* video */ -#define WMM_AC_VO 3 /* voice */ - -/* TSPEC related */ -#define ACTION_CATEGORY_CODE_TSPEC 17 -#define ACTION_CODE_TSPEC_ADDTS 0 -#define ACTION_CODE_TSPEC_ADDTS_RESP 1 -#define ACTION_CODE_TSPEC_DELTS 2 - -typedef enum { - TSPEC_STATUS_CODE_ADMISSION_ACCEPTED = 0, - TSPEC_STATUS_CODE_ADDTS_INVALID_PARAMS = 0x1, - TSPEC_STATUS_CODE_ADDTS_REQUEST_REFUSED = 0x3, - TSPEC_STATUS_CODE_UNSPECIFIED_QOS_RELATED_FAILURE = 0xC8, - TSPEC_STATUS_CODE_REQUESTED_REFUSED_POLICY_CONFIGURATION = 0xC9, - TSPEC_STATUS_CODE_INSUFFCIENT_BANDWIDTH = 0xCA, - TSPEC_STATUS_CODE_INVALID_PARAMS = 0xCB, - TSPEC_STATUS_CODE_DELTS_SENT = 0x30, - TSPEC_STATUS_CODE_DELTS_RECV = 0x31, -} TSPEC_STATUS_CODE; - -#define TSPEC_TSID_MASK 0xF -#define TSPEC_TSID_S 1 - -/* - * WMM/802.11e Tspec Element - */ -typedef PREPACK struct wmm_tspec_ie_t { - u8 elementId; - u8 len; - u8 oui[3]; - u8 ouiType; - u8 ouiSubType; - u8 version; - u16 tsInfo_info; - u8 tsInfo_reserved; - u16 nominalMSDU; - u16 maxMSDU; - u32 minServiceInt; - u32 maxServiceInt; - u32 inactivityInt; - u32 suspensionInt; - u32 serviceStartTime; - u32 minDataRate; - u32 meanDataRate; - u32 peakDataRate; - u32 maxBurstSize; - u32 delayBound; - u32 minPhyRate; - u16 sba; - u16 mediumTime; -} POSTPACK WMM_TSPEC_IE; - - -/* - * BEACON management packets - * - * octet timestamp[8] - * octet beacon interval[2] - * octet capability information[2] - * information element - * octet elemid - * octet length - * octet information[length] - */ - -#define IEEE80211_BEACON_INTERVAL(beacon) \ - ((beacon)[8] | ((beacon)[9] << 8)) -#define IEEE80211_BEACON_CAPABILITY(beacon) \ - ((beacon)[10] | ((beacon)[11] << 8)) - -#define IEEE80211_CAPINFO_ESS 0x0001 -#define IEEE80211_CAPINFO_IBSS 0x0002 -#define IEEE80211_CAPINFO_CF_POLLABLE 0x0004 -#define IEEE80211_CAPINFO_CF_POLLREQ 0x0008 -#define IEEE80211_CAPINFO_PRIVACY 0x0010 -#define IEEE80211_CAPINFO_SHORT_PREAMBLE 0x0020 -#define IEEE80211_CAPINFO_PBCC 0x0040 -#define IEEE80211_CAPINFO_CHNL_AGILITY 0x0080 -/* bits 8-9 are reserved */ -#define IEEE80211_CAPINFO_SHORT_SLOTTIME 0x0400 -#define IEEE80211_CAPINFO_APSD 0x0800 -/* bit 12 is reserved */ -#define IEEE80211_CAPINFO_DSSSOFDM 0x2000 -/* bits 14-15 are reserved */ - -/* - * Authentication Modes - */ - -enum ieee80211_authmode { - IEEE80211_AUTH_NONE = 0, - IEEE80211_AUTH_OPEN = 1, - IEEE80211_AUTH_SHARED = 2, - IEEE80211_AUTH_8021X = 3, - IEEE80211_AUTH_AUTO = 4, /* auto-select/accept */ - /* NB: these are used only for ioctls */ - IEEE80211_AUTH_WPA = 5, /* WPA/RSN w/ 802.1x */ - IEEE80211_AUTH_WPA_PSK = 6, /* WPA/RSN w/ PSK */ - IEEE80211_AUTH_WPA_CCKM = 7, /* WPA/RSN IE w/ CCKM */ -}; - -#define IEEE80211_PS_MAX_QUEUE 50 /*Maximum no of buffers that can be queues for PS*/ - -#endif /* _NET80211_IEEE80211_H_ */ diff --git a/drivers/staging/ath6kl/wlan/include/ieee80211_node.h b/drivers/staging/ath6kl/wlan/include/ieee80211_node.h deleted file mode 100644 index 1cb0167..0000000 --- a/drivers/staging/ath6kl/wlan/include/ieee80211_node.h +++ /dev/null @@ -1,93 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="ieee80211_node.h" company="Atheros"> -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// Author(s): ="Atheros" -//============================================================================== -#ifndef _IEEE80211_NODE_H_ -#define _IEEE80211_NODE_H_ - -/* - * Node locking definitions. - */ -#define IEEE80211_NODE_LOCK_INIT(_nt) A_MUTEX_INIT(&(_nt)->nt_nodelock) -#define IEEE80211_NODE_LOCK_DESTROY(_nt) if (A_IS_MUTEX_VALID(&(_nt)->nt_nodelock)) { \ - A_MUTEX_DELETE(&(_nt)->nt_nodelock); } - -#define IEEE80211_NODE_LOCK(_nt) A_MUTEX_LOCK(&(_nt)->nt_nodelock) -#define IEEE80211_NODE_UNLOCK(_nt) A_MUTEX_UNLOCK(&(_nt)->nt_nodelock) -#define IEEE80211_NODE_LOCK_BH(_nt) A_MUTEX_LOCK(&(_nt)->nt_nodelock) -#define IEEE80211_NODE_UNLOCK_BH(_nt) A_MUTEX_UNLOCK(&(_nt)->nt_nodelock) -#define IEEE80211_NODE_LOCK_ASSERT(_nt) - -/* - * Node reference counting definitions. - * - * ieee80211_node_initref initialize the reference count to 1 - * ieee80211_node_incref add a reference - * ieee80211_node_decref remove a reference - * ieee80211_node_dectestref remove a reference and return 1 if this - * is the last reference, otherwise 0 - * ieee80211_node_refcnt reference count for printing (only) - */ -#define ieee80211_node_initref(_ni) ((_ni)->ni_refcnt = 1) -#define ieee80211_node_incref(_ni) ((_ni)->ni_refcnt++) -#define ieee80211_node_decref(_ni) ((_ni)->ni_refcnt--) -#define ieee80211_node_dectestref(_ni) (((_ni)->ni_refcnt--) == 1) -#define ieee80211_node_refcnt(_ni) ((_ni)->ni_refcnt) - -#define IEEE80211_NODE_HASHSIZE 32 -/* simple hash is enough for variation of macaddr */ -#define IEEE80211_NODE_HASH(addr) \ - (((const u8 *)(addr))[IEEE80211_ADDR_LEN - 1] % \ - IEEE80211_NODE_HASHSIZE) - -/* - * Table of ieee80211_node instances. Each ieee80211com - * has at least one for holding the scan candidates. - * When operating as an access point or in ibss mode there - * is a second table for associated stations or neighbors. - */ -struct ieee80211_node_table { - void *nt_wmip; /* back reference */ - A_MUTEX_T nt_nodelock; /* on node table */ - struct bss *nt_node_first; /* information of all nodes */ - struct bss *nt_node_last; /* information of all nodes */ - struct bss *nt_hash[IEEE80211_NODE_HASHSIZE]; - const char *nt_name; /* for debugging */ - u32 nt_scangen; /* gen# for timeout scan */ -#ifdef THREAD_X - A_TIMER nt_inact_timer; - u8 isTimerArmed; /* is the node timer armed */ -#endif - u32 nt_nodeAge; /* node aging time */ -#ifdef OS_ROAM_MANAGEMENT - u32 nt_si_gen; /* gen# for scan indication*/ -#endif -}; - -#ifdef THREAD_X -#define WLAN_NODE_INACT_TIMEOUT_MSEC 20000 -#else -#define WLAN_NODE_INACT_TIMEOUT_MSEC 120000 -#endif - -#define WLAN_NODE_INACT_CNT 4 - -#endif /* _IEEE80211_NODE_H_ */ diff --git a/drivers/staging/ath6kl/wlan/src/wlan_node.c b/drivers/staging/ath6kl/wlan/src/wlan_node.c deleted file mode 100644 index 0fe5f4b..0000000 --- a/drivers/staging/ath6kl/wlan/src/wlan_node.c +++ /dev/null @@ -1,636 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="wlan_node.c" company="Atheros"> -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// IEEE 802.11 node handling support. -// -// Author(s): ="Atheros" -//============================================================================== -#include <a_config.h> -#include <athdefs.h> -#include <a_osapi.h> -#define ATH_MODULE_NAME wlan -#include <a_debug.h> -#include "htc.h" -#include "htc_api.h" -#include <wmi.h> -#include <ieee80211.h> -#include <wlan_api.h> -#include <wmi_api.h> -#include <ieee80211_node.h> - -#define ATH_DEBUG_WLAN ATH_DEBUG_MAKE_MODULE_MASK(0) - -#ifdef ATH_DEBUG_MODULE - -static struct ath_debug_mask_description wlan_debug_desc[] = { - { ATH_DEBUG_WLAN , "General WLAN Node Tracing"}, -}; - -ATH_DEBUG_INSTANTIATE_MODULE_VAR(wlan, - "wlan", - "WLAN Node Management", - ATH_DEBUG_MASK_DEFAULTS, - ATH_DEBUG_DESCRIPTION_COUNT(wlan_debug_desc), - wlan_debug_desc); - -#endif - -#ifdef THREAD_X -static void wlan_node_timeout(unsigned long arg); -#endif - -static bss_t * _ieee80211_find_node (struct ieee80211_node_table *nt, - const u8 *macaddr); - -bss_t * -wlan_node_alloc(struct ieee80211_node_table *nt, int wh_size) -{ - bss_t *ni; - - ni = A_MALLOC_NOWAIT(sizeof(bss_t)); - - if (ni != NULL) { - if (wh_size) - { - ni->ni_buf = A_MALLOC_NOWAIT(wh_size); - if (ni->ni_buf == NULL) { - kfree(ni); - ni = NULL; - return ni; - } - } - } else { - return ni; - } - - /* Make sure our lists are clean */ - ni->ni_list_next = NULL; - ni->ni_list_prev = NULL; - ni->ni_hash_next = NULL; - ni->ni_hash_prev = NULL; - - // - // ni_scangen never initialized before and during suspend/resume of winmobile, - // that some junk has been stored in this, due to this scan list didn't properly updated - // - ni->ni_scangen = 0; - -#ifdef OS_ROAM_MANAGEMENT - ni->ni_si_gen = 0; -#endif - - return ni; -} - -void -wlan_node_free(bss_t *ni) -{ - if (ni->ni_buf != NULL) { - kfree(ni->ni_buf); - } - kfree(ni); -} - -void -wlan_setup_node(struct ieee80211_node_table *nt, bss_t *ni, - const u8 *macaddr) -{ - int hash; - u32 timeoutValue = 0; - - memcpy(ni->ni_macaddr, macaddr, IEEE80211_ADDR_LEN); - hash = IEEE80211_NODE_HASH (macaddr); - ieee80211_node_initref (ni); /* mark referenced */ - - timeoutValue = nt->nt_nodeAge; - - ni->ni_tstamp = A_GET_MS (0); - ni->ni_actcnt = WLAN_NODE_INACT_CNT; - - IEEE80211_NODE_LOCK_BH(nt); - - /* Insert at the end of the node list */ - ni->ni_list_next = NULL; - ni->ni_list_prev = nt->nt_node_last; - if(nt->nt_node_last != NULL) - { - nt->nt_node_last->ni_list_next = ni; - } - nt->nt_node_last = ni; - if(nt->nt_node_first == NULL) - { - nt->nt_node_first = ni; - } - - /* Insert into the hash list i.e. the bucket */ - if((ni->ni_hash_next = nt->nt_hash[hash]) != NULL) - { - nt->nt_hash[hash]->ni_hash_prev = ni; - } - ni->ni_hash_prev = NULL; - nt->nt_hash[hash] = ni; - -#ifdef THREAD_X - if (!nt->isTimerArmed) { - A_TIMEOUT_MS(&nt->nt_inact_timer, timeoutValue, 0); - nt->isTimerArmed = true; - } -#endif - - IEEE80211_NODE_UNLOCK_BH(nt); -} - -static bss_t * -_ieee80211_find_node(struct ieee80211_node_table *nt, - const u8 *macaddr) -{ - bss_t *ni; - int hash; - - IEEE80211_NODE_LOCK_ASSERT(nt); - - hash = IEEE80211_NODE_HASH(macaddr); - for(ni = nt->nt_hash[hash]; ni; ni = ni->ni_hash_next) { - if (IEEE80211_ADDR_EQ(ni->ni_macaddr, macaddr)) { - ieee80211_node_incref(ni); /* mark referenced */ - return ni; - } - } - return NULL; -} - -bss_t * -wlan_find_node(struct ieee80211_node_table *nt, const u8 *macaddr) -{ - bss_t *ni; - - IEEE80211_NODE_LOCK(nt); - ni = _ieee80211_find_node(nt, macaddr); - IEEE80211_NODE_UNLOCK(nt); - return ni; -} - -/* - * Reclaim a node. If this is the last reference count then - * do the normal free work. Otherwise remove it from the node - * table and mark it gone by clearing the back-reference. - */ -void -wlan_node_reclaim(struct ieee80211_node_table *nt, bss_t *ni) -{ - IEEE80211_NODE_LOCK(nt); - - if(ni->ni_list_prev == NULL) - { - /* First in list so fix the list head */ - nt->nt_node_first = ni->ni_list_next; - } - else - { - ni->ni_list_prev->ni_list_next = ni->ni_list_next; - } - - if(ni->ni_list_next == NULL) - { - /* Last in list so fix list tail */ - nt->nt_node_last = ni->ni_list_prev; - } - else - { - ni->ni_list_next->ni_list_prev = ni->ni_list_prev; - } - - if(ni->ni_hash_prev == NULL) - { - /* First in list so fix the list head */ - int hash; - hash = IEEE80211_NODE_HASH(ni->ni_macaddr); - nt->nt_hash[hash] = ni->ni_hash_next; - } - else - { - ni->ni_hash_prev->ni_hash_next = ni->ni_hash_next; - } - - if(ni->ni_hash_next != NULL) - { - ni->ni_hash_next->ni_hash_prev = ni->ni_hash_prev; - } - wlan_node_free(ni); - - IEEE80211_NODE_UNLOCK(nt); -} - -static void -wlan_node_dec_free(bss_t *ni) -{ - if (ieee80211_node_dectestref(ni)) { - wlan_node_free(ni); - } -} - -void -wlan_free_allnodes(struct ieee80211_node_table *nt) -{ - bss_t *ni; - - while ((ni = nt->nt_node_first) != NULL) { - wlan_node_reclaim(nt, ni); - } -} - -void -wlan_iterate_nodes(struct ieee80211_node_table *nt, wlan_node_iter_func *f, - void *arg) -{ - bss_t *ni; - u32 gen; - - gen = ++nt->nt_scangen; - - IEEE80211_NODE_LOCK(nt); - for (ni = nt->nt_node_first; ni; ni = ni->ni_list_next) { - if (ni->ni_scangen != gen) { - ni->ni_scangen = gen; - (void) ieee80211_node_incref(ni); - (*f)(arg, ni); - wlan_node_dec_free(ni); - } - } - IEEE80211_NODE_UNLOCK(nt); -} - -/* - * Node table support. - */ -void -wlan_node_table_init(void *wmip, struct ieee80211_node_table *nt) -{ - int i; - - AR_DEBUG_PRINTF(ATH_DEBUG_WLAN, ("node table = 0x%lx\n", (unsigned long)nt)); - IEEE80211_NODE_LOCK_INIT(nt); - - A_REGISTER_MODULE_DEBUG_INFO(wlan); - - nt->nt_node_first = nt->nt_node_last = NULL; - for(i = 0; i < IEEE80211_NODE_HASHSIZE; i++) - { - nt->nt_hash[i] = NULL; - } - -#ifdef THREAD_X - A_INIT_TIMER(&nt->nt_inact_timer, wlan_node_timeout, nt); - nt->isTimerArmed = false; -#endif - nt->nt_wmip = wmip; - nt->nt_nodeAge = WLAN_NODE_INACT_TIMEOUT_MSEC; - - // - // nt_scangen never initialized before and during suspend/resume of winmobile, - // that some junk has been stored in this, due to this scan list didn't properly updated - // - nt->nt_scangen = 0; - -#ifdef OS_ROAM_MANAGEMENT - nt->nt_si_gen = 0; -#endif -} - -void -wlan_set_nodeage(struct ieee80211_node_table *nt, u32 nodeAge) -{ - nt->nt_nodeAge = nodeAge; - return; -} -void -wlan_refresh_inactive_nodes (struct ieee80211_node_table *nt) -{ -#ifdef THREAD_X - bss_t *bss, *nextBss; - u8 myBssid[IEEE80211_ADDR_LEN], reArmTimer = false; - - wmi_get_current_bssid(nt->nt_wmip, myBssid); - - bss = nt->nt_node_first; - while (bss != NULL) - { - nextBss = bss->ni_list_next; - if (memcmp(myBssid, bss->ni_macaddr, sizeof(myBssid)) != 0) - { - /* - * free up all but the current bss - if set - */ - wlan_node_reclaim(nt, bss); - - } - bss = nextBss; - } -#else - bss_t *bss, *nextBss; - u8 myBssid[IEEE80211_ADDR_LEN]; - u32 timeoutValue = 0; - u32 now = A_GET_MS(0); - timeoutValue = nt->nt_nodeAge; - - wmi_get_current_bssid(nt->nt_wmip, myBssid); - - bss = nt->nt_node_first; - while (bss != NULL) - { - nextBss = bss->ni_list_next; - if (memcmp(myBssid, bss->ni_macaddr, sizeof(myBssid)) != 0) - { - - if (((now - bss->ni_tstamp) > timeoutValue) || --bss->ni_actcnt == 0) - { - /* - * free up all but the current bss - if set - */ - wlan_node_reclaim(nt, bss); - } - } - bss = nextBss; - } -#endif -} - -#ifdef THREAD_X -static void -wlan_node_timeout (unsigned long arg) -{ - struct ieee80211_node_table *nt = (struct ieee80211_node_table *)arg; - bss_t *bss, *nextBss; - u8 myBssid[IEEE80211_ADDR_LEN], reArmTimer = false; - u32 timeoutValue = 0; - u32 now = A_GET_MS(0); - - timeoutValue = nt->nt_nodeAge; - - wmi_get_current_bssid(nt->nt_wmip, myBssid); - - bss = nt->nt_node_first; - while (bss != NULL) - { - nextBss = bss->ni_list_next; - if (memcmp(myBssid, bss->ni_macaddr, sizeof(myBssid)) != 0) - { - - if ((now - bss->ni_tstamp) > timeoutValue) - { - /* - * free up all but the current bss - if set - */ - wlan_node_reclaim(nt, bss); - } - else - { - /* - * Re-arm timer, only when we have a bss other than - * current bss AND it is not aged-out. - */ - reArmTimer = true; - } - } - bss = nextBss; - } - - if (reArmTimer) - A_TIMEOUT_MS (&nt->nt_inact_timer, timeoutValue, 0); - - nt->isTimerArmed = reArmTimer; -} -#endif - -void -wlan_node_table_cleanup(struct ieee80211_node_table *nt) -{ -#ifdef THREAD_X - A_UNTIMEOUT(&nt->nt_inact_timer); - A_DELETE_TIMER(&nt->nt_inact_timer); -#endif - wlan_free_allnodes(nt); - IEEE80211_NODE_LOCK_DESTROY(nt); -} - -bss_t * -wlan_find_Ssidnode (struct ieee80211_node_table *nt, u8 *pSsid, - u32 ssidLength, bool bIsWPA2, bool bMatchSSID) -{ - bss_t *ni = NULL; - u8 *pIESsid = NULL; - - IEEE80211_NODE_LOCK (nt); - - for (ni = nt->nt_node_first; ni; ni = ni->ni_list_next) { - pIESsid = ni->ni_cie.ie_ssid; - if (pIESsid[1] <= 32) { - - // Step 1 : Check SSID - if (0x00 == memcmp (pSsid, &pIESsid[2], ssidLength)) { - - // - // Step 2.1 : Check MatchSSID is true, if so, return Matched SSID - // Profile, otherwise check whether WPA2 or WPA - // - if (true == bMatchSSID) { - ieee80211_node_incref (ni); /* mark referenced */ - IEEE80211_NODE_UNLOCK (nt); - return ni; - } - - // Step 2 : if SSID matches, check WPA or WPA2 - if (true == bIsWPA2 && NULL != ni->ni_cie.ie_rsn) { - ieee80211_node_incref (ni); /* mark referenced */ - IEEE80211_NODE_UNLOCK (nt); - return ni; - } - if (false == bIsWPA2 && NULL != ni->ni_cie.ie_wpa) { - ieee80211_node_incref(ni); /* mark referenced */ - IEEE80211_NODE_UNLOCK (nt); - return ni; - } - } - } - } - - IEEE80211_NODE_UNLOCK (nt); - - return NULL; -} - -void -wlan_node_return (struct ieee80211_node_table *nt, bss_t *ni) -{ - IEEE80211_NODE_LOCK (nt); - wlan_node_dec_free (ni); - IEEE80211_NODE_UNLOCK (nt); -} - -void -wlan_node_remove_core (struct ieee80211_node_table *nt, bss_t *ni) -{ - if(ni->ni_list_prev == NULL) - { - /* First in list so fix the list head */ - nt->nt_node_first = ni->ni_list_next; - } - else - { - ni->ni_list_prev->ni_list_next = ni->ni_list_next; - } - - if(ni->ni_list_next == NULL) - { - /* Last in list so fix list tail */ - nt->nt_node_last = ni->ni_list_prev; - } - else - { - ni->ni_list_next->ni_list_prev = ni->ni_list_prev; - } - - if(ni->ni_hash_prev == NULL) - { - /* First in list so fix the list head */ - int hash; - hash = IEEE80211_NODE_HASH(ni->ni_macaddr); - nt->nt_hash[hash] = ni->ni_hash_next; - } - else - { - ni->ni_hash_prev->ni_hash_next = ni->ni_hash_next; - } - - if(ni->ni_hash_next != NULL) - { - ni->ni_hash_next->ni_hash_prev = ni->ni_hash_prev; - } -} - -bss_t * -wlan_node_remove(struct ieee80211_node_table *nt, u8 *bssid) -{ - bss_t *bss, *nextBss; - - IEEE80211_NODE_LOCK(nt); - - bss = nt->nt_node_first; - - while (bss != NULL) - { - nextBss = bss->ni_list_next; - - if (memcmp(bssid, bss->ni_macaddr, 6) == 0) - { - wlan_node_remove_core (nt, bss); - IEEE80211_NODE_UNLOCK(nt); - return bss; - } - - bss = nextBss; - } - - IEEE80211_NODE_UNLOCK(nt); - return NULL; -} - -bss_t * -wlan_find_matching_Ssidnode (struct ieee80211_node_table *nt, u8 *pSsid, - u32 ssidLength, u32 dot11AuthMode, u32 authMode, - u32 pairwiseCryptoType, u32 grpwiseCryptoTyp) -{ - bss_t *ni = NULL; - bss_t *best_ni = NULL; - u8 *pIESsid = NULL; - - IEEE80211_NODE_LOCK (nt); - - for (ni = nt->nt_node_first; ni; ni = ni->ni_list_next) { - pIESsid = ni->ni_cie.ie_ssid; - if (pIESsid[1] <= 32) { - - // Step 1 : Check SSID - if (0x00 == memcmp (pSsid, &pIESsid[2], ssidLength)) { - - if (ni->ni_cie.ie_capInfo & 0x10) - { - - if ((NULL != ni->ni_cie.ie_rsn) && (WPA2_PSK_AUTH == authMode)) - { - /* WPA2 */ - if (NULL == best_ni) - { - best_ni = ni; - } - else if (ni->ni_rssi > best_ni->ni_rssi) - { - best_ni = ni; - } - } - else if ((NULL != ni->ni_cie.ie_wpa) && (WPA_PSK_AUTH == authMode)) - { - /* WPA */ - if (NULL == best_ni) - { - best_ni = ni; - } - else if (ni->ni_rssi > best_ni->ni_rssi) - { - best_ni = ni; - } - } - else if (WEP_CRYPT == pairwiseCryptoType) - { - /* WEP */ - if (NULL == best_ni) - { - best_ni = ni; - } - else if (ni->ni_rssi > best_ni->ni_rssi) - { - best_ni = ni; - } - } - } - else - { - /* open AP */ - if ((OPEN_AUTH == authMode) && (NONE_CRYPT == pairwiseCryptoType)) - { - if (NULL == best_ni) - { - best_ni = ni; - } - else if (ni->ni_rssi > best_ni->ni_rssi) - { - best_ni = ni; - } - } - } - } - } - } - - IEEE80211_NODE_UNLOCK (nt); - - return best_ni; -} - diff --git a/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c b/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c deleted file mode 100644 index 07b8313..0000000 --- a/drivers/staging/ath6kl/wlan/src/wlan_recv_beacon.c +++ /dev/null @@ -1,199 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="wlan_recv_beacon.c" company="Atheros"> -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// 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. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// IEEE 802.11 input handling. -// -// Author(s): ="Atheros" -//============================================================================== - -#include "a_config.h" -#include "athdefs.h" -#include "a_osapi.h" -#include <wmi.h> -#include <ieee80211.h> -#include <wlan_api.h> - -#define IEEE80211_VERIFY_LENGTH(_len, _minlen) do { \ - if ((_len) < (_minlen)) { \ - return A_EINVAL; \ - } \ -} while (0) - -#define IEEE80211_VERIFY_ELEMENT(__elem, __maxlen) do { \ - if ((__elem) == NULL) { \ - return A_EINVAL; \ - } \ - if ((__elem)[1] > (__maxlen)) { \ - return A_EINVAL; \ - } \ -} while (0) - - -/* unaligned little endian access */ -#define LE_READ_2(p) \ - ((u16) \ - ((((u8 *)(p))[0] ) | (((u8 *)(p))[1] << 8))) - -#define LE_READ_4(p) \ - ((u32) \ - ((((u8 *)(p))[0] ) | (((u8 *)(p))[1] << 8) | \ - (((u8 *)(p))[2] << 16) | (((u8 *)(p))[3] << 24))) - - -static int __inline -iswpaoui(const u8 *frm) -{ - return frm[1] > 3 && LE_READ_4(frm+2) == ((WPA_OUI_TYPE<<24)|WPA_OUI); -} - -static int __inline -iswmmoui(const u8 *frm) -{ - return frm[1] > 3 && LE_READ_4(frm+2) == ((WMM_OUI_TYPE<<24)|WMM_OUI); -} - -/* unused functions for now */ -#if 0 -static int __inline -iswmmparam(const u8 *frm) -{ - return frm[1] > 5 && frm[6] == WMM_PARAM_OUI_SUBTYPE; -} - -static int __inline -iswmminfo(const u8 *frm) -{ - return frm[1] > 5 && frm[6] == WMM_INFO_OUI_SUBTYPE; -} -#endif - -static int __inline -isatherosoui(const u8 *frm) -{ - return frm[1] > 3 && LE_READ_4(frm+2) == ((ATH_OUI_TYPE<<24)|ATH_OUI); -} - -static int __inline -iswscoui(const u8 *frm) -{ - return frm[1] > 3 && LE_READ_4(frm+2) == ((0x04<<24)|WPA_OUI); -} - -int -wlan_parse_beacon(u8 *buf, int framelen, struct ieee80211_common_ie *cie) -{ - u8 *frm, *efrm; - u8 elemid_ssid = false; - - frm = buf; - efrm = (u8 *) (frm + framelen); - - /* - * beacon/probe response frame format - * [8] time stamp - * [2] beacon interval - * [2] capability information - * [tlv] ssid - * [tlv] supported rates - * [tlv] country information - * [tlv] parameter set (FH/DS) - * [tlv] erp information - * [tlv] extended supported rates - * [tlv] WMM - * [tlv] WPA or RSN - * [tlv] Atheros Advanced Capabilities - */ - IEEE80211_VERIFY_LENGTH(efrm - frm, 12); - A_MEMZERO(cie, sizeof(*cie)); - - cie->ie_tstamp = frm; frm += 8; - cie->ie_beaconInt = A_LE2CPU16(*(u16 *)frm); frm += 2; - cie->ie_capInfo = A_LE2CPU16(*(u16 *)frm); frm += 2; - cie->ie_chan = 0; - - while (frm < efrm) { - switch (*frm) { - case IEEE80211_ELEMID_SSID: - if (!elemid_ssid) { - cie->ie_ssid = frm; - elemid_ssid = true; - } - break; - case IEEE80211_ELEMID_RATES: - cie->ie_rates = frm; - break; - case IEEE80211_ELEMID_COUNTRY: - cie->ie_country = frm; - break; - case IEEE80211_ELEMID_FHPARMS: - break; - case IEEE80211_ELEMID_DSPARMS: - cie->ie_chan = frm[2]; - break; - case IEEE80211_ELEMID_TIM: - cie->ie_tim = frm; - break; - case IEEE80211_ELEMID_IBSSPARMS: - break; - case IEEE80211_ELEMID_XRATES: - cie->ie_xrates = frm; - break; - case IEEE80211_ELEMID_ERP: - if (frm[1] != 1) { - //A_PRINTF("Discarding ERP Element - Bad Len\n"); - return A_EINVAL; - } - cie->ie_erp = frm[2]; - break; - case IEEE80211_ELEMID_RSN: - cie->ie_rsn = frm; - break; - case IEEE80211_ELEMID_HTCAP_ANA: - cie->ie_htcap = frm; - break; - case IEEE80211_ELEMID_HTINFO_ANA: - cie->ie_htop = frm; - break; -#ifdef WAPI_ENABLE - case IEEE80211_ELEMID_WAPI: - cie->ie_wapi = frm; - break; -#endif - case IEEE80211_ELEMID_VENDOR: - if (iswpaoui(frm)) { - cie->ie_wpa = frm; - } else if (iswmmoui(frm)) { - cie->ie_wmm = frm; - } else if (isatherosoui(frm)) { - cie->ie_ath = frm; - } else if(iswscoui(frm)) { - cie->ie_wsc = frm; - } - break; - default: - break; - } - frm += frm[1] + 2; - } - IEEE80211_VERIFY_ELEMENT(cie->ie_rates, IEEE80211_RATE_MAXSIZE); - IEEE80211_VERIFY_ELEMENT(cie->ie_ssid, IEEE80211_NWID_LEN); - - return 0; -} diff --git a/drivers/staging/ath6kl/wlan/src/wlan_utils.c b/drivers/staging/ath6kl/wlan/src/wlan_utils.c deleted file mode 100644 index bc91599..0000000 --- a/drivers/staging/ath6kl/wlan/src/wlan_utils.c +++ /dev/null @@ -1,58 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="wlan_utils.c" company="Atheros"> -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// Permission to use, copy, modify, and/or distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// This module implements frequently used wlan utilies -// -// Author(s): ="Atheros" -//============================================================================== -#include <a_config.h> -#include <athdefs.h> -#include <a_osapi.h> - -/* - * converts ieee channel number to frequency - */ -u16 wlan_ieee2freq(int chan) -{ - if (chan == 14) { - return 2484; - } - if (chan < 14) { /* 0-13 */ - return (2407 + (chan*5)); - } - if (chan < 27) { /* 15-26 */ - return (2512 + ((chan-15)*20)); - } - return (5000 + (chan*5)); -} - -/* - * Converts MHz frequency to IEEE channel number. - */ -u32 wlan_freq2ieee(u16 freq) -{ - if (freq == 2484) - return 14; - if (freq < 2484) - return (freq - 2407) / 5; - if (freq < 5000) - return 15 + ((freq - 2512) / 20); - return (freq - 5000) / 5; -} diff --git a/drivers/staging/ath6kl/wmi/wmi.c b/drivers/staging/ath6kl/wmi/wmi.c deleted file mode 100644 index c7b5e5c..0000000 --- a/drivers/staging/ath6kl/wmi/wmi.c +++ /dev/null @@ -1,6444 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// Permission to use, copy, modify, and/or distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// This module implements the hardware independent layer of the -// Wireless Module Interface (WMI) protocol. -// -// Author(s): ="Atheros" -//============================================================================== - -#include <a_config.h> -#include <athdefs.h> -#include <a_osapi.h> -#include "htc.h" -#include "htc_api.h" -#include "wmi.h" -#include <wlan_api.h> -#include <wmi_api.h> -#include <ieee80211.h> -#include <ieee80211_node.h> -#include "dset_api.h" -#include "wmi_host.h" -#include "a_drv.h" -#include "a_drv_api.h" -#define ATH_MODULE_NAME wmi -#include "a_debug.h" -#include "dbglog_api.h" -#include "roaming.h" -#include "cfg80211.h" - -#define ATH_DEBUG_WMI ATH_DEBUG_MAKE_MODULE_MASK(0) - -#ifdef ATH_DEBUG_MODULE - -static struct ath_debug_mask_description wmi_debug_desc[] = { - { ATH_DEBUG_WMI , "General WMI Tracing"}, -}; - -ATH_DEBUG_INSTANTIATE_MODULE_VAR(wmi, - "wmi", - "Wireless Module Interface", - ATH_DEBUG_MASK_DEFAULTS, - ATH_DEBUG_DESCRIPTION_COUNT(wmi_debug_desc), - wmi_debug_desc); - -#endif - -#ifndef REXOS -#define DBGARG _A_FUNCNAME_ -#define DBGFMT "%s() : " -#define DBG_WMI ATH_DEBUG_WMI -#define DBG_ERROR ATH_DEBUG_ERR -#define DBG_WMI2 ATH_DEBUG_WMI -#define A_DPRINTF AR_DEBUG_PRINTF -#endif - -static int wmi_ready_event_rx(struct wmi_t *wmip, u8 *datap, int len); - -static int wmi_connect_event_rx(struct wmi_t *wmip, u8 *datap, - int len); -static int wmi_disconnect_event_rx(struct wmi_t *wmip, u8 *datap, - int len); - -static int wmi_tkip_micerr_event_rx(struct wmi_t *wmip, u8 *datap, - int len); -static int wmi_bssInfo_event_rx(struct wmi_t *wmip, u8 *datap, - int len); -static int wmi_opt_frame_event_rx(struct wmi_t *wmip, u8 *datap, - int len); -static int wmi_pstream_timeout_event_rx(struct wmi_t *wmip, u8 *datap, - int len); -static int wmi_sync_point(struct wmi_t *wmip); - -static int wmi_bitrate_reply_rx(struct wmi_t *wmip, u8 *datap, - int len); -static int wmi_ratemask_reply_rx(struct wmi_t *wmip, u8 *datap, - int len); -static int wmi_channelList_reply_rx(struct wmi_t *wmip, u8 *datap, - int len); -static int wmi_regDomain_event_rx(struct wmi_t *wmip, u8 *datap, - int len); -static int wmi_txPwr_reply_rx(struct wmi_t *wmip, u8 *datap, int len); -static int wmi_neighborReport_event_rx(struct wmi_t *wmip, u8 *datap, - int len); - -static int wmi_dset_open_req_rx(struct wmi_t *wmip, u8 *datap, - int len); -#ifdef CONFIG_HOST_DSET_SUPPORT -static int wmi_dset_close_rx(struct wmi_t *wmip, u8 *datap, int len); -static int wmi_dset_data_req_rx(struct wmi_t *wmip, u8 *datap, - int len); -#endif /* CONFIG_HOST_DSET_SUPPORT */ - - -static int wmi_scanComplete_rx(struct wmi_t *wmip, u8 *datap, - int len); -static int wmi_errorEvent_rx(struct wmi_t *wmip, u8 *datap, int len); -static int wmi_statsEvent_rx(struct wmi_t *wmip, u8 *datap, int len); -static int wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len); -static int wmi_hbChallengeResp_rx(struct wmi_t *wmip, u8 *datap, int len); -static int wmi_reportErrorEvent_rx(struct wmi_t *wmip, u8 *datap, int len); -static int wmi_cac_event_rx(struct wmi_t *wmip, u8 *datap, int len); -static int wmi_channel_change_event_rx(struct wmi_t *wmip, u8 *datap, int len); -static int wmi_roam_tbl_event_rx(struct wmi_t *wmip, u8 *datap, - int len); -static int wmi_roam_data_event_rx(struct wmi_t *wmip, u8 *datap, - int len); -static int wmi_get_wow_list_event_rx(struct wmi_t *wmip, u8 *datap, - int len); -static int -wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, u8 *datap, u32 len); - -static int -wmi_set_params_event_rx(struct wmi_t *wmip, u8 *datap, u32 len); - - -#ifdef CONFIG_HOST_TCMD_SUPPORT -static int -wmi_tcmd_test_report_rx(struct wmi_t *wmip, u8 *datap, int len); -#endif - -static int -wmi_txRetryErrEvent_rx(struct wmi_t *wmip, u8 *datap, int len); - -static int -wmi_snrThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len); - -static int -wmi_lqThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len); - -static bool -wmi_is_bitrate_index_valid(struct wmi_t *wmip, s32 rateIndex); - -static int -wmi_aplistEvent_rx(struct wmi_t *wmip, u8 *datap, int len); - -static int -wmi_dbglog_event_rx(struct wmi_t *wmip, u8 *datap, int len); - -static int wmi_keepalive_reply_rx(struct wmi_t *wmip, u8 *datap, int len); - -int wmi_cmd_send_xtnd(struct wmi_t *wmip, void *osbuf, WMIX_COMMAND_ID cmdId, - WMI_SYNC_FLAG syncflag); - -u8 ar6000_get_upper_threshold(s16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, u32 size); -u8 ar6000_get_lower_threshold(s16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, u32 size); - -void wmi_cache_configure_rssithreshold(struct wmi_t *wmip, WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd); -void wmi_cache_configure_snrthreshold(struct wmi_t *wmip, WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd); -static int wmi_send_rssi_threshold_params(struct wmi_t *wmip, - WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd); -static int wmi_send_snr_threshold_params(struct wmi_t *wmip, - WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd); -#if defined(CONFIG_TARGET_PROFILE_SUPPORT) -static int -wmi_prof_count_rx(struct wmi_t *wmip, u8 *datap, int len); -#endif /* CONFIG_TARGET_PROFILE_SUPPORT */ - -static int wmi_pspoll_event_rx(struct wmi_t *wmip, u8 *datap, - int len); -static int wmi_dtimexpiry_event_rx(struct wmi_t *wmip, u8 *datap, - int len); - -static int wmi_peer_node_event_rx (struct wmi_t *wmip, u8 *datap, - int len); -static int wmi_addba_req_event_rx(struct wmi_t *, u8 *, int); -static int wmi_addba_resp_event_rx(struct wmi_t *, u8 *, int); -static int wmi_delba_req_event_rx(struct wmi_t *, u8 *, int); -static int wmi_btcoex_config_event_rx(struct wmi_t *wmip, u8 *datap, int len); -static int wmi_btcoex_stats_event_rx(struct wmi_t *wmip, u8 *datap, int len); -static int wmi_hci_event_rx(struct wmi_t *, u8 *, int); - -#ifdef WAPI_ENABLE -static int wmi_wapi_rekey_event_rx(struct wmi_t *wmip, u8 *datap, - int len); -#endif - -#if defined(UNDER_CE) -#if defined(NDIS51_MINIPORT) -unsigned int processDot11Hdr = 0; -#else -unsigned int processDot11Hdr = 1; -#endif -#else -extern unsigned int processDot11Hdr; -#endif - -int wps_enable; -static const s32 wmi_rateTable[][2] = { - //{W/O SGI, with SGI} - {1000, 1000}, - {2000, 2000}, - {5500, 5500}, - {11000, 11000}, - {6000, 6000}, - {9000, 9000}, - {12000, 12000}, - {18000, 18000}, - {24000, 24000}, - {36000, 36000}, - {48000, 48000}, - {54000, 54000}, - {6500, 7200}, - {13000, 14400}, - {19500, 21700}, - {26000, 28900}, - {39000, 43300}, - {52000, 57800}, - {58500, 65000}, - {65000, 72200}, - {13500, 15000}, - {27000, 30000}, - {40500, 45000}, - {54000, 60000}, - {81000, 90000}, - {108000, 120000}, - {121500, 135000}, - {135000, 150000}, - {0, 0}}; - -#define MODE_A_SUPPORT_RATE_START ((s32) 4) -#define MODE_A_SUPPORT_RATE_STOP ((s32) 11) - -#define MODE_GONLY_SUPPORT_RATE_START MODE_A_SUPPORT_RATE_START -#define MODE_GONLY_SUPPORT_RATE_STOP MODE_A_SUPPORT_RATE_STOP - -#define MODE_B_SUPPORT_RATE_START ((s32) 0) -#define MODE_B_SUPPORT_RATE_STOP ((s32) 3) - -#define MODE_G_SUPPORT_RATE_START ((s32) 0) -#define MODE_G_SUPPORT_RATE_STOP ((s32) 11) - -#define MODE_GHT20_SUPPORT_RATE_START ((s32) 0) -#define MODE_GHT20_SUPPORT_RATE_STOP ((s32) 19) - -#define MAX_NUMBER_OF_SUPPORT_RATES (MODE_GHT20_SUPPORT_RATE_STOP + 1) - -/* 802.1d to AC mapping. Refer pg 57 of WMM-test-plan-v1.2 */ -const u8 up_to_ac[]= { - WMM_AC_BE, - WMM_AC_BK, - WMM_AC_BK, - WMM_AC_BE, - WMM_AC_VI, - WMM_AC_VI, - WMM_AC_VO, - WMM_AC_VO, - }; - -/* This stuff is used when we want a simple layer-3 visibility */ -typedef PREPACK struct _iphdr { - u8 ip_ver_hdrlen; /* version and hdr length */ - u8 ip_tos; /* type of service */ - u16 ip_len; /* total length */ - u16 ip_id; /* identification */ - s16 ip_off; /* fragment offset field */ -#define IP_DF 0x4000 /* dont fragment flag */ -#define IP_MF 0x2000 /* more fragments flag */ -#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ - u8 ip_ttl; /* time to live */ - u8 ip_p; /* protocol */ - u16 ip_sum; /* checksum */ - u8 ip_src[4]; /* source and dest address */ - u8 ip_dst[4]; -} POSTPACK iphdr; - -static s16 rssi_event_value = 0; -static s16 snr_event_value = 0; - -bool is_probe_ssid = false; - -void * -wmi_init(void *devt) -{ - struct wmi_t *wmip; - - A_REGISTER_MODULE_DEBUG_INFO(wmi); - - wmip = A_MALLOC (sizeof(struct wmi_t)); - if (wmip == NULL) { - return (NULL); - } - A_MEMZERO(wmip, sizeof(struct wmi_t )); -#ifdef THREAD_X - INIT_WMI_LOCK(wmip); -#else - A_MUTEX_INIT(&wmip->wmi_lock); -#endif - wmip->wmi_devt = devt; - wlan_node_table_init(wmip, &wmip->wmi_scan_table); - wmi_qos_state_init(wmip); - - wmip->wmi_powerMode = REC_POWER; - wmip->wmi_phyMode = WMI_11G_MODE; - - wmip->wmi_pair_crypto_type = NONE_CRYPT; - wmip->wmi_grp_crypto_type = NONE_CRYPT; - - wmip->wmi_ht_allowed[A_BAND_24GHZ] = 1; - wmip->wmi_ht_allowed[A_BAND_5GHZ] = 1; - - return (wmip); -} - -void -wmi_qos_state_init(struct wmi_t *wmip) -{ - u8 i; - - if (wmip == NULL) { - return; - } - LOCK_WMI(wmip); - - /* Initialize QoS States */ - wmip->wmi_numQoSStream = 0; - - wmip->wmi_fatPipeExists = 0; - - for (i=0; i < WMM_NUM_AC; i++) { - wmip->wmi_streamExistsForAC[i]=0; - } - - UNLOCK_WMI(wmip); - - A_WMI_SET_NUMDATAENDPTS(wmip->wmi_devt, 1); -} - -void -wmi_set_control_ep(struct wmi_t * wmip, HTC_ENDPOINT_ID eid) -{ - A_ASSERT( eid != ENDPOINT_UNUSED); - wmip->wmi_endpoint_id = eid; -} - -HTC_ENDPOINT_ID -wmi_get_control_ep(struct wmi_t * wmip) -{ - return(wmip->wmi_endpoint_id); -} - -void -wmi_shutdown(struct wmi_t *wmip) -{ - if (wmip != NULL) { - wlan_node_table_cleanup(&wmip->wmi_scan_table); - if (A_IS_MUTEX_VALID(&wmip->wmi_lock)) { -#ifdef THREAD_X - DELETE_WMI_LOCK(&wmip); -#else - A_MUTEX_DELETE(&wmip->wmi_lock); -#endif - } - kfree(wmip); - } -} - -/* - * performs DIX to 802.3 encapsulation for transmit packets. - * uses passed in buffer. Returns buffer or NULL if failed. - * Assumes the entire DIX header is contigous and that there is - * enough room in the buffer for a 802.3 mac header and LLC+SNAP headers. - */ -int -wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf) -{ - u8 *datap; - u16 typeorlen; - ATH_MAC_HDR macHdr; - ATH_LLC_SNAP_HDR *llcHdr; - - A_ASSERT(osbuf != NULL); - - if (A_NETBUF_HEADROOM(osbuf) < - (sizeof(ATH_LLC_SNAP_HDR) + sizeof(WMI_DATA_HDR))) - { - return A_NO_MEMORY; - } - - datap = A_NETBUF_DATA(osbuf); - - typeorlen = *(u16 *)(datap + ATH_MAC_LEN + ATH_MAC_LEN); - - if (!IS_ETHERTYPE(A_BE2CPU16(typeorlen))) { - /* - * packet is already in 802.3 format - return success - */ - A_DPRINTF(DBG_WMI, (DBGFMT "packet already 802.3\n", DBGARG)); - return (0); - } - - /* - * Save mac fields and length to be inserted later - */ - memcpy(macHdr.dstMac, datap, ATH_MAC_LEN); - memcpy(macHdr.srcMac, datap + ATH_MAC_LEN, ATH_MAC_LEN); - macHdr.typeOrLen = A_CPU2BE16(A_NETBUF_LEN(osbuf) - sizeof(ATH_MAC_HDR) + - sizeof(ATH_LLC_SNAP_HDR)); - - /* - * Make room for LLC+SNAP headers - */ - if (A_NETBUF_PUSH(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != 0) { - return A_NO_MEMORY; - } - datap = A_NETBUF_DATA(osbuf); - - memcpy(datap, &macHdr, sizeof (ATH_MAC_HDR)); - - llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(ATH_MAC_HDR)); - llcHdr->dsap = 0xAA; - llcHdr->ssap = 0xAA; - llcHdr->cntl = 0x03; - llcHdr->orgCode[0] = 0x0; - llcHdr->orgCode[1] = 0x0; - llcHdr->orgCode[2] = 0x0; - llcHdr->etherType = typeorlen; - - return (0); -} - -int wmi_meta_add(struct wmi_t *wmip, void *osbuf, u8 *pVersion,void *pTxMetaS) -{ - switch(*pVersion){ - case 0: - return (0); - case WMI_META_VERSION_1: - { - WMI_TX_META_V1 *pV1= NULL; - A_ASSERT(osbuf != NULL); - if (A_NETBUF_PUSH(osbuf, WMI_MAX_TX_META_SZ) != 0) { - return A_NO_MEMORY; - } - - pV1 = (WMI_TX_META_V1 *)A_NETBUF_DATA(osbuf); - /* the pktID is used in conjunction with txComplete messages - * allowing the target to notify which tx requests have been - * completed and how. */ - pV1->pktID = 0; - /* the ratePolicyID allows the host to specify which rate policy - * to use for transmitting this packet. 0 means use default behavior. */ - pV1->ratePolicyID = 0; - A_ASSERT(pVersion != NULL); - /* the version must be used to populate the meta field of the WMI_DATA_HDR */ - *pVersion = WMI_META_VERSION_1; - return (0); - } - case WMI_META_VERSION_2: - { - WMI_TX_META_V2 *pV2 ; - A_ASSERT(osbuf != NULL); - if (A_NETBUF_PUSH(osbuf, WMI_MAX_TX_META_SZ) != 0) { - return A_NO_MEMORY; - } - pV2 = (WMI_TX_META_V2 *)A_NETBUF_DATA(osbuf); - memcpy(pV2,(WMI_TX_META_V2 *)pTxMetaS,sizeof(WMI_TX_META_V2)); - return (0); - } - default: - return (0); - } -} - -/* Adds a WMI data header */ -int -wmi_data_hdr_add(struct wmi_t *wmip, void *osbuf, u8 msgType, bool bMoreData, - WMI_DATA_HDR_DATA_TYPE data_type,u8 metaVersion, void *pTxMetaS) -{ - WMI_DATA_HDR *dtHdr; -// u8 metaVersion = 0; - int status; - - A_ASSERT(osbuf != NULL); - - /* adds the meta data field after the wmi data hdr. If metaVersion - * is returns 0 then no meta field was added. */ - if ((status = wmi_meta_add(wmip, osbuf, &metaVersion,pTxMetaS)) != 0) { - return status; - } - - if (A_NETBUF_PUSH(osbuf, sizeof(WMI_DATA_HDR)) != 0) { - return A_NO_MEMORY; - } - - dtHdr = (WMI_DATA_HDR *)A_NETBUF_DATA(osbuf); - A_MEMZERO(dtHdr, sizeof(WMI_DATA_HDR)); - - WMI_DATA_HDR_SET_MSG_TYPE(dtHdr, msgType); - WMI_DATA_HDR_SET_DATA_TYPE(dtHdr, data_type); - - if (bMoreData) { - WMI_DATA_HDR_SET_MORE_BIT(dtHdr); - } - - WMI_DATA_HDR_SET_META(dtHdr, metaVersion); - - dtHdr->info3 = 0; - - return (0); -} - - -u8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, u32 layer2Priority, bool wmmEnabled) -{ - u8 *datap; - u8 trafficClass = WMM_AC_BE; - u16 ipType = IP_ETHERTYPE; - WMI_DATA_HDR *dtHdr; - u8 streamExists = 0; - u8 userPriority; - u32 hdrsize, metasize; - ATH_LLC_SNAP_HDR *llcHdr; - - WMI_CREATE_PSTREAM_CMD cmd; - - A_ASSERT(osbuf != NULL); - - // - // Initialize header size - // - hdrsize = 0; - - datap = A_NETBUF_DATA(osbuf); - dtHdr = (WMI_DATA_HDR *)datap; - metasize = (WMI_DATA_HDR_GET_META(dtHdr))? WMI_MAX_TX_META_SZ : 0; - - if (!wmmEnabled) - { - /* If WMM is disabled all traffic goes as BE traffic */ - userPriority = 0; - } - else - { - if (processDot11Hdr) - { - hdrsize = A_ROUND_UP(sizeof(struct ieee80211_qosframe),sizeof(u32)); - llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(WMI_DATA_HDR) + metasize + - hdrsize); - - - } - else - { - llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(WMI_DATA_HDR) + metasize + - sizeof(ATH_MAC_HDR)); - } - - if (llcHdr->etherType == A_CPU2BE16(ipType)) - { - /* Extract the endpoint info from the TOS field in the IP header */ - - userPriority = wmi_determine_userPriority (((u8 *)llcHdr) + sizeof(ATH_LLC_SNAP_HDR),layer2Priority); - } - else - { - userPriority = layer2Priority & 0x7; - } - } - - - /* workaround for WMM S5 */ - if ((WMM_AC_VI == wmip->wmi_traffic_class) && ((5 == userPriority) || (4 == userPriority))) - { - userPriority = 1; - } - - trafficClass = convert_userPriority_to_trafficClass(userPriority); - - WMI_DATA_HDR_SET_UP(dtHdr, userPriority); - /* lower 3-bits are 802.1d priority */ - //dtHdr->info |= (userPriority & WMI_DATA_HDR_UP_MASK) << WMI_DATA_HDR_UP_SHIFT; - - LOCK_WMI(wmip); - streamExists = wmip->wmi_fatPipeExists; - UNLOCK_WMI(wmip); - - if (!(streamExists & (1 << trafficClass))) - { - - A_MEMZERO(&cmd, sizeof(cmd)); - cmd.trafficClass = trafficClass; - cmd.userPriority = userPriority; - cmd.inactivityInt = WMI_IMPLICIT_PSTREAM_INACTIVITY_INT; - /* Implicit streams are created with TSID 0xFF */ - - cmd.tsid = WMI_IMPLICIT_PSTREAM; - wmi_create_pstream_cmd(wmip, &cmd); - } - - return trafficClass; -} - -int -wmi_dot11_hdr_add (struct wmi_t *wmip, void *osbuf, NETWORK_TYPE mode) -{ - u8 *datap; - u16 typeorlen; - ATH_MAC_HDR macHdr; - ATH_LLC_SNAP_HDR *llcHdr; - struct ieee80211_frame *wh; - u32 hdrsize; - - A_ASSERT(osbuf != NULL); - - if (A_NETBUF_HEADROOM(osbuf) < - (sizeof(struct ieee80211_qosframe) + sizeof(ATH_LLC_SNAP_HDR) + sizeof(WMI_DATA_HDR))) - { - return A_NO_MEMORY; - } - - datap = A_NETBUF_DATA(osbuf); - - typeorlen = *(u16 *)(datap + ATH_MAC_LEN + ATH_MAC_LEN); - - if (!IS_ETHERTYPE(A_BE2CPU16(typeorlen))) { -/* - * packet is already in 802.3 format - return success - */ - A_DPRINTF(DBG_WMI, (DBGFMT "packet already 802.3\n", DBGARG)); - goto AddDot11Hdr; - } - - /* - * Save mac fields and length to be inserted later - */ - memcpy(macHdr.dstMac, datap, ATH_MAC_LEN); - memcpy(macHdr.srcMac, datap + ATH_MAC_LEN, ATH_MAC_LEN); - macHdr.typeOrLen = A_CPU2BE16(A_NETBUF_LEN(osbuf) - sizeof(ATH_MAC_HDR) + - sizeof(ATH_LLC_SNAP_HDR)); - - // Remove the Ethernet hdr - A_NETBUF_PULL(osbuf, sizeof(ATH_MAC_HDR)); - /* - * Make room for LLC+SNAP headers - */ - if (A_NETBUF_PUSH(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != 0) { - return A_NO_MEMORY; - } - datap = A_NETBUF_DATA(osbuf); - - llcHdr = (ATH_LLC_SNAP_HDR *)(datap); - llcHdr->dsap = 0xAA; - llcHdr->ssap = 0xAA; - llcHdr->cntl = 0x03; - llcHdr->orgCode[0] = 0x0; - llcHdr->orgCode[1] = 0x0; - llcHdr->orgCode[2] = 0x0; - llcHdr->etherType = typeorlen; - -AddDot11Hdr: - /* Make room for 802.11 hdr */ - if (wmip->wmi_is_wmm_enabled) - { - hdrsize = A_ROUND_UP(sizeof(struct ieee80211_qosframe),sizeof(u32)); - if (A_NETBUF_PUSH(osbuf, hdrsize) != 0) - { - return A_NO_MEMORY; - } - wh = (struct ieee80211_frame *) A_NETBUF_DATA(osbuf); - wh->i_fc[0] = IEEE80211_FC0_SUBTYPE_QOS; - } - else - { - hdrsize = A_ROUND_UP(sizeof(struct ieee80211_frame),sizeof(u32)); - if (A_NETBUF_PUSH(osbuf, hdrsize) != 0) - { - return A_NO_MEMORY; - } - wh = (struct ieee80211_frame *) A_NETBUF_DATA(osbuf); - wh->i_fc[0] = IEEE80211_FC0_SUBTYPE_DATA; - } - /* Setup the SA & DA */ - IEEE80211_ADDR_COPY(wh->i_addr2, macHdr.srcMac); - - if (mode == INFRA_NETWORK) { - IEEE80211_ADDR_COPY(wh->i_addr3, macHdr.dstMac); - } - else if (mode == ADHOC_NETWORK) { - IEEE80211_ADDR_COPY(wh->i_addr1, macHdr.dstMac); - } - - return (0); -} - -int -wmi_dot11_hdr_remove(struct wmi_t *wmip, void *osbuf) -{ - u8 *datap; - struct ieee80211_frame *pwh,wh; - u8 type,subtype; - ATH_LLC_SNAP_HDR *llcHdr; - ATH_MAC_HDR macHdr; - u32 hdrsize; - - A_ASSERT(osbuf != NULL); - datap = A_NETBUF_DATA(osbuf); - - pwh = (struct ieee80211_frame *)datap; - type = pwh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; - subtype = pwh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; - - memcpy((u8 *)&wh, datap, sizeof(struct ieee80211_frame)); - - /* strip off the 802.11 hdr*/ - if (subtype == IEEE80211_FC0_SUBTYPE_QOS) { - hdrsize = A_ROUND_UP(sizeof(struct ieee80211_qosframe),sizeof(u32)); - A_NETBUF_PULL(osbuf, hdrsize); - } else if (subtype == IEEE80211_FC0_SUBTYPE_DATA) { - A_NETBUF_PULL(osbuf, sizeof(struct ieee80211_frame)); - } - - datap = A_NETBUF_DATA(osbuf); - llcHdr = (ATH_LLC_SNAP_HDR *)(datap); - - macHdr.typeOrLen = llcHdr->etherType; - A_MEMZERO(macHdr.dstMac, sizeof(macHdr.dstMac)); - A_MEMZERO(macHdr.srcMac, sizeof(macHdr.srcMac)); - - switch (wh.i_fc[1] & IEEE80211_FC1_DIR_MASK) { - case IEEE80211_FC1_DIR_NODS: - IEEE80211_ADDR_COPY(macHdr.dstMac, wh.i_addr1); - IEEE80211_ADDR_COPY(macHdr.srcMac, wh.i_addr2); - break; - case IEEE80211_FC1_DIR_TODS: - IEEE80211_ADDR_COPY(macHdr.dstMac, wh.i_addr3); - IEEE80211_ADDR_COPY(macHdr.srcMac, wh.i_addr2); - break; - case IEEE80211_FC1_DIR_FROMDS: - IEEE80211_ADDR_COPY(macHdr.dstMac, wh.i_addr1); - IEEE80211_ADDR_COPY(macHdr.srcMac, wh.i_addr3); - break; - case IEEE80211_FC1_DIR_DSTODS: - break; - } - - // Remove the LLC Hdr. - A_NETBUF_PULL(osbuf, sizeof(ATH_LLC_SNAP_HDR)); - - // Insert the ATH MAC hdr. - - A_NETBUF_PUSH(osbuf, sizeof(ATH_MAC_HDR)); - datap = A_NETBUF_DATA(osbuf); - - memcpy (datap, &macHdr, sizeof(ATH_MAC_HDR)); - - return 0; -} - -/* - * performs 802.3 to DIX encapsulation for received packets. - * Assumes the entire 802.3 header is contigous. - */ -int -wmi_dot3_2_dix(void *osbuf) -{ - u8 *datap; - ATH_MAC_HDR macHdr; - ATH_LLC_SNAP_HDR *llcHdr; - - A_ASSERT(osbuf != NULL); - datap = A_NETBUF_DATA(osbuf); - - memcpy(&macHdr, datap, sizeof(ATH_MAC_HDR)); - llcHdr = (ATH_LLC_SNAP_HDR *)(datap + sizeof(ATH_MAC_HDR)); - macHdr.typeOrLen = llcHdr->etherType; - - if (A_NETBUF_PULL(osbuf, sizeof(ATH_LLC_SNAP_HDR)) != 0) { - return A_NO_MEMORY; - } - - datap = A_NETBUF_DATA(osbuf); - - memcpy(datap, &macHdr, sizeof (ATH_MAC_HDR)); - - return (0); -} - -/* - * Removes a WMI data header - */ -int -wmi_data_hdr_remove(struct wmi_t *wmip, void *osbuf) -{ - A_ASSERT(osbuf != NULL); - - return (A_NETBUF_PULL(osbuf, sizeof(WMI_DATA_HDR))); -} - -void -wmi_iterate_nodes(struct wmi_t *wmip, wlan_node_iter_func *f, void *arg) -{ - wlan_iterate_nodes(&wmip->wmi_scan_table, f, arg); -} - -/* - * WMI Extended Event received from Target. - */ -int -wmi_control_rx_xtnd(struct wmi_t *wmip, void *osbuf) -{ - WMIX_CMD_HDR *cmd; - u16 id; - u8 *datap; - u32 len; - int status = 0; - - if (A_NETBUF_LEN(osbuf) < sizeof(WMIX_CMD_HDR)) { - A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 1\n", DBGARG)); - wmip->wmi_stats.cmd_len_err++; - return A_ERROR; - } - - cmd = (WMIX_CMD_HDR *)A_NETBUF_DATA(osbuf); - id = cmd->commandId; - - if (A_NETBUF_PULL(osbuf, sizeof(WMIX_CMD_HDR)) != 0) { - A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 2\n", DBGARG)); - wmip->wmi_stats.cmd_len_err++; - return A_ERROR; - } - - datap = A_NETBUF_DATA(osbuf); - len = A_NETBUF_LEN(osbuf); - - switch (id) { - case (WMIX_DSETOPENREQ_EVENTID): - status = wmi_dset_open_req_rx(wmip, datap, len); - break; -#ifdef CONFIG_HOST_DSET_SUPPORT - case (WMIX_DSETCLOSE_EVENTID): - status = wmi_dset_close_rx(wmip, datap, len); - break; - case (WMIX_DSETDATAREQ_EVENTID): - status = wmi_dset_data_req_rx(wmip, datap, len); - break; -#endif /* CONFIG_HOST_DSET_SUPPORT */ - case (WMIX_HB_CHALLENGE_RESP_EVENTID): - wmi_hbChallengeResp_rx(wmip, datap, len); - break; - case (WMIX_DBGLOG_EVENTID): - wmi_dbglog_event_rx(wmip, datap, len); - break; -#if defined(CONFIG_TARGET_PROFILE_SUPPORT) - case (WMIX_PROF_COUNT_EVENTID): - wmi_prof_count_rx(wmip, datap, len); - break; -#endif /* CONFIG_TARGET_PROFILE_SUPPORT */ - default: - A_DPRINTF(DBG_WMI|DBG_ERROR, - (DBGFMT "Unknown id 0x%x\n", DBGARG, id)); - wmip->wmi_stats.cmd_id_err++; - status = A_ERROR; - break; - } - - return status; -} - -/* - * Control Path - */ -u32 cmdRecvNum; - -int -wmi_control_rx(struct wmi_t *wmip, void *osbuf) -{ - WMI_CMD_HDR *cmd; - u16 id; - u8 *datap; - u32 len, i, loggingReq; - int status = 0; - - A_ASSERT(osbuf != NULL); - if (A_NETBUF_LEN(osbuf) < sizeof(WMI_CMD_HDR)) { - A_NETBUF_FREE(osbuf); - A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 1\n", DBGARG)); - wmip->wmi_stats.cmd_len_err++; - return A_ERROR; - } - - cmd = (WMI_CMD_HDR *)A_NETBUF_DATA(osbuf); - id = cmd->commandId; - - if (A_NETBUF_PULL(osbuf, sizeof(WMI_CMD_HDR)) != 0) { - A_NETBUF_FREE(osbuf); - A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 2\n", DBGARG)); - wmip->wmi_stats.cmd_len_err++; - return A_ERROR; - } - - datap = A_NETBUF_DATA(osbuf); - len = A_NETBUF_LEN(osbuf); - - loggingReq = 0; - - ar6000_get_driver_cfg(wmip->wmi_devt, - AR6000_DRIVER_CFG_LOG_RAW_WMI_MSGS, - &loggingReq); - - if(loggingReq) { - AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("WMI %d \n",id)); - AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("WMI recv, MsgNo %d : ", cmdRecvNum)); - for(i = 0; i < len; i++) - AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("%x ", datap[i])); - AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("\n")); - } - - LOCK_WMI(wmip); - cmdRecvNum++; - UNLOCK_WMI(wmip); - - switch (id) { - case (WMI_GET_BITRATE_CMDID): - A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_BITRATE_CMDID\n", DBGARG)); - status = wmi_bitrate_reply_rx(wmip, datap, len); - break; - case (WMI_GET_CHANNEL_LIST_CMDID): - A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_CHANNEL_LIST_CMDID\n", DBGARG)); - status = wmi_channelList_reply_rx(wmip, datap, len); - break; - case (WMI_GET_TX_PWR_CMDID): - A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_TX_PWR_CMDID\n", DBGARG)); - status = wmi_txPwr_reply_rx(wmip, datap, len); - break; - case (WMI_READY_EVENTID): - A_DPRINTF(DBG_WMI, (DBGFMT "WMI_READY_EVENTID\n", DBGARG)); - status = wmi_ready_event_rx(wmip, datap, len); - A_WMI_DBGLOG_INIT_DONE(wmip->wmi_devt); - break; - case (WMI_CONNECT_EVENTID): - A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CONNECT_EVENTID\n", DBGARG)); - status = wmi_connect_event_rx(wmip, datap, len); - break; - case (WMI_DISCONNECT_EVENTID): - A_DPRINTF(DBG_WMI, (DBGFMT "WMI_DISCONNECT_EVENTID\n", DBGARG)); - status = wmi_disconnect_event_rx(wmip, datap, len); - break; - case (WMI_PEER_NODE_EVENTID): - A_DPRINTF (DBG_WMI, (DBGFMT "WMI_PEER_NODE_EVENTID\n", DBGARG)); - status = wmi_peer_node_event_rx(wmip, datap, len); - break; - case (WMI_TKIP_MICERR_EVENTID): - A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TKIP_MICERR_EVENTID\n", DBGARG)); - status = wmi_tkip_micerr_event_rx(wmip, datap, len); - break; - case (WMI_BSSINFO_EVENTID): - A_DPRINTF(DBG_WMI, (DBGFMT "WMI_BSSINFO_EVENTID\n", DBGARG)); - { - /* - * convert WMI_BSS_INFO_HDR2 to WMI_BSS_INFO_HDR - * Take a local copy of the WMI_BSS_INFO_HDR2 from the wmi buffer - * and reconstruct the WMI_BSS_INFO_HDR in its place - */ - WMI_BSS_INFO_HDR2 bih2; - WMI_BSS_INFO_HDR *bih; - memcpy(&bih2, datap, sizeof(WMI_BSS_INFO_HDR2)); - - A_NETBUF_PUSH(osbuf, 4); - datap = A_NETBUF_DATA(osbuf); - len = A_NETBUF_LEN(osbuf); - bih = (WMI_BSS_INFO_HDR *)datap; - - bih->channel = bih2.channel; - bih->frameType = bih2.frameType; - bih->snr = bih2.snr; - bih->rssi = bih2.snr - 95; - bih->ieMask = bih2.ieMask; - memcpy(bih->bssid, bih2.bssid, ATH_MAC_LEN); - - status = wmi_bssInfo_event_rx(wmip, datap, len); - } - break; - case (WMI_REGDOMAIN_EVENTID): - A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REGDOMAIN_EVENTID\n", DBGARG)); - status = wmi_regDomain_event_rx(wmip, datap, len); - break; - case (WMI_PSTREAM_TIMEOUT_EVENTID): - A_DPRINTF(DBG_WMI, (DBGFMT "WMI_PSTREAM_TIMEOUT_EVENTID\n", DBGARG)); - status = wmi_pstream_timeout_event_rx(wmip, datap, len); - break; - case (WMI_NEIGHBOR_REPORT_EVENTID): - A_DPRINTF(DBG_WMI, (DBGFMT "WMI_NEIGHBOR_REPORT_EVENTID\n", DBGARG)); - status = wmi_neighborReport_event_rx(wmip, datap, len); - break; - case (WMI_SCAN_COMPLETE_EVENTID): - A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SCAN_COMPLETE_EVENTID\n", DBGARG)); - status = wmi_scanComplete_rx(wmip, datap, len); - break; - case (WMI_CMDERROR_EVENTID): - A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CMDERROR_EVENTID\n", DBGARG)); - status = wmi_errorEvent_rx(wmip, datap, len); - break; - case (WMI_REPORT_STATISTICS_EVENTID): - A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REPORT_STATISTICS_EVENTID\n", DBGARG)); - status = wmi_statsEvent_rx(wmip, datap, len); - break; - case (WMI_RSSI_THRESHOLD_EVENTID): - A_DPRINTF(DBG_WMI, (DBGFMT "WMI_RSSI_THRESHOLD_EVENTID\n", DBGARG)); - status = wmi_rssiThresholdEvent_rx(wmip, datap, len); - break; - case (WMI_ERROR_REPORT_EVENTID): - A_DPRINTF(DBG_WMI, (DBGFMT "WMI_ERROR_REPORT_EVENTID\n", DBGARG)); - status = wmi_reportErrorEvent_rx(wmip, datap, len); - break; - case (WMI_OPT_RX_FRAME_EVENTID): - A_DPRINTF(DBG_WMI, (DBGFMT "WMI_OPT_RX_FRAME_EVENTID\n", DBGARG)); - status = wmi_opt_frame_event_rx(wmip, datap, len); - break; - case (WMI_REPORT_ROAM_TBL_EVENTID): - A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REPORT_ROAM_TBL_EVENTID\n", DBGARG)); - status = wmi_roam_tbl_event_rx(wmip, datap, len); - break; - case (WMI_EXTENSION_EVENTID): - A_DPRINTF(DBG_WMI, (DBGFMT "WMI_EXTENSION_EVENTID\n", DBGARG)); - status = wmi_control_rx_xtnd(wmip, osbuf); - break; - case (WMI_CAC_EVENTID): - A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CAC_EVENTID\n", DBGARG)); - status = wmi_cac_event_rx(wmip, datap, len); - break; - case (WMI_CHANNEL_CHANGE_EVENTID): - A_DPRINTF(DBG_WMI, (DBGFMT "WMI_CHANNEL_CHANGE_EVENTID\n", DBGARG)); - status = wmi_channel_change_event_rx(wmip, datap, len); - break; - case (WMI_REPORT_ROAM_DATA_EVENTID): - A_DPRINTF(DBG_WMI, (DBGFMT "WMI_REPORT_ROAM_DATA_EVENTID\n", DBGARG)); - status = wmi_roam_data_event_rx(wmip, datap, len); - break; -#ifdef CONFIG_HOST_TCMD_SUPPORT - case (WMI_TEST_EVENTID): - A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TEST_EVENTID\n", DBGARG)); - status = wmi_tcmd_test_report_rx(wmip, datap, len); - break; -#endif - case (WMI_GET_FIXRATES_CMDID): - A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_FIXRATES_CMDID\n", DBGARG)); - status = wmi_ratemask_reply_rx(wmip, datap, len); - break; - case (WMI_TX_RETRY_ERR_EVENTID): - A_DPRINTF(DBG_WMI, (DBGFMT "WMI_TX_RETRY_ERR_EVENTID\n", DBGARG)); - status = wmi_txRetryErrEvent_rx(wmip, datap, len); - break; - case (WMI_SNR_THRESHOLD_EVENTID): - A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SNR_THRESHOLD_EVENTID\n", DBGARG)); - status = wmi_snrThresholdEvent_rx(wmip, datap, len); - break; - case (WMI_LQ_THRESHOLD_EVENTID): - A_DPRINTF(DBG_WMI, (DBGFMT "WMI_LQ_THRESHOLD_EVENTID\n", DBGARG)); - status = wmi_lqThresholdEvent_rx(wmip, datap, len); - break; - case (WMI_APLIST_EVENTID): - AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Received APLIST Event\n")); - status = wmi_aplistEvent_rx(wmip, datap, len); - break; - case (WMI_GET_KEEPALIVE_CMDID): - A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_KEEPALIVE_CMDID\n", DBGARG)); - status = wmi_keepalive_reply_rx(wmip, datap, len); - break; - case (WMI_GET_WOW_LIST_EVENTID): - status = wmi_get_wow_list_event_rx(wmip, datap, len); - break; - case (WMI_GET_PMKID_LIST_EVENTID): - A_DPRINTF(DBG_WMI, (DBGFMT "WMI_GET_PMKID_LIST Event\n", DBGARG)); - status = wmi_get_pmkid_list_event_rx(wmip, datap, len); - break; - case (WMI_PSPOLL_EVENTID): - A_DPRINTF(DBG_WMI, (DBGFMT "WMI_PSPOLL_EVENT\n", DBGARG)); - status = wmi_pspoll_event_rx(wmip, datap, len); - break; - case (WMI_DTIMEXPIRY_EVENTID): - A_DPRINTF(DBG_WMI, (DBGFMT "WMI_DTIMEXPIRY_EVENT\n", DBGARG)); - status = wmi_dtimexpiry_event_rx(wmip, datap, len); - break; - case (WMI_SET_PARAMS_REPLY_EVENTID): - A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SET_PARAMS_REPLY Event\n", DBGARG)); - status = wmi_set_params_event_rx(wmip, datap, len); - break; - case (WMI_ADDBA_REQ_EVENTID): - status = wmi_addba_req_event_rx(wmip, datap, len); - break; - case (WMI_ADDBA_RESP_EVENTID): - status = wmi_addba_resp_event_rx(wmip, datap, len); - break; - case (WMI_DELBA_REQ_EVENTID): - status = wmi_delba_req_event_rx(wmip, datap, len); - break; - case (WMI_REPORT_BTCOEX_CONFIG_EVENTID): - A_DPRINTF(DBG_WMI, (DBGFMT "WMI_BTCOEX_CONFIG_EVENTID", DBGARG)); - status = wmi_btcoex_config_event_rx(wmip, datap, len); - break; - case (WMI_REPORT_BTCOEX_STATS_EVENTID): - A_DPRINTF(DBG_WMI, (DBGFMT "WMI_BTCOEX_STATS_EVENTID", DBGARG)); - status = wmi_btcoex_stats_event_rx(wmip, datap, len); - break; - case (WMI_TX_COMPLETE_EVENTID): - { - int index; - TX_COMPLETE_MSG_V1 *pV1; - WMI_TX_COMPLETE_EVENT *pEv = (WMI_TX_COMPLETE_EVENT *)datap; - A_PRINTF("comp: %d %d %d\n", pEv->numMessages, pEv->msgLen, pEv->msgType); - - for(index = 0 ; index < pEv->numMessages ; index++) { - pV1 = (TX_COMPLETE_MSG_V1 *)(datap + sizeof(WMI_TX_COMPLETE_EVENT) + index*sizeof(TX_COMPLETE_MSG_V1)); - A_PRINTF("msg: %d %d %d %d\n", pV1->status, pV1->pktID, pV1->rateIdx, pV1->ackFailures); - } - } - break; - case (WMI_HCI_EVENT_EVENTID): - status = wmi_hci_event_rx(wmip, datap, len); - break; -#ifdef WAPI_ENABLE - case (WMI_WAPI_REKEY_EVENTID): - A_DPRINTF(DBG_WMI, (DBGFMT "WMI_WAPI_REKEY_EVENTID", DBGARG)); - status = wmi_wapi_rekey_event_rx(wmip, datap, len); - break; -#endif - default: - A_DPRINTF(DBG_WMI|DBG_ERROR, - (DBGFMT "Unknown id 0x%x\n", DBGARG, id)); - wmip->wmi_stats.cmd_id_err++; - status = A_ERROR; - break; - } - - A_NETBUF_FREE(osbuf); - - return status; -} - -/* Send a "simple" wmi command -- one with no arguments */ -static int -wmi_simple_cmd(struct wmi_t *wmip, WMI_COMMAND_ID cmdid) -{ - void *osbuf; - - osbuf = A_NETBUF_ALLOC(0); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - return (wmi_cmd_send(wmip, osbuf, cmdid, NO_SYNC_WMIFLAG)); -} - -/* Send a "simple" extended wmi command -- one with no arguments. - Enabling this command only if GPIO or profiling support is enabled. - This is to suppress warnings on some platforms */ -#if defined(CONFIG_TARGET_PROFILE_SUPPORT) -static int -wmi_simple_cmd_xtnd(struct wmi_t *wmip, WMIX_COMMAND_ID cmdid) -{ - void *osbuf; - - osbuf = A_NETBUF_ALLOC(0); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - return (wmi_cmd_send_xtnd(wmip, osbuf, cmdid, NO_SYNC_WMIFLAG)); -} -#endif - -static int -wmi_ready_event_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - WMI_READY_EVENT *ev = (WMI_READY_EVENT *)datap; - - if (len < sizeof(WMI_READY_EVENT)) { - return A_EINVAL; - } - A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); - wmip->wmi_ready = true; - A_WMI_READY_EVENT(wmip->wmi_devt, ev->macaddr, ev->phyCapability, - ev->sw_version, ev->abi_version); - - return 0; -} - -#define LE_READ_4(p) \ - ((u32) \ - ((((u8 *)(p))[0] ) | (((u8 *)(p))[1] << 8) | \ - (((u8 *)(p))[2] << 16) | (((u8 *)(p))[3] << 24))) - -static int __inline -iswmmoui(const u8 *frm) -{ - return frm[1] > 3 && LE_READ_4(frm+2) == ((WMM_OUI_TYPE<<24)|WMM_OUI); -} - -static int __inline -iswmmparam(const u8 *frm) -{ - return frm[1] > 5 && frm[6] == WMM_PARAM_OUI_SUBTYPE; -} - - -static int -wmi_connect_event_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - WMI_CONNECT_EVENT *ev; - u8 *pie,*peie; - - if (len < sizeof(WMI_CONNECT_EVENT)) - { - return A_EINVAL; - } - ev = (WMI_CONNECT_EVENT *)datap; - - A_DPRINTF(DBG_WMI, - (DBGFMT "freq %d bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n", - DBGARG, ev->channel, - ev->bssid[0], ev->bssid[1], ev->bssid[2], - ev->bssid[3], ev->bssid[4], ev->bssid[5])); - - memcpy(wmip->wmi_bssid, ev->bssid, ATH_MAC_LEN); - - /* initialize pointer to start of assoc rsp IEs */ - pie = ev->assocInfo + ev->beaconIeLen + ev->assocReqLen + - sizeof(u16) + /* capinfo*/ - sizeof(u16) + /* status Code */ - sizeof(u16) ; /* associd */ - - /* initialize pointer to end of assoc rsp IEs */ - peie = ev->assocInfo + ev->beaconIeLen + ev->assocReqLen + ev->assocRespLen; - - while (pie < peie) - { - switch (*pie) - { - case IEEE80211_ELEMID_VENDOR: - if (iswmmoui(pie)) - { - if(iswmmparam (pie)) - { - wmip->wmi_is_wmm_enabled = true; - } - } - break; - } - - if (wmip->wmi_is_wmm_enabled) - { - break; - } - pie += pie[1] + 2; - } - - A_WMI_CONNECT_EVENT(wmip->wmi_devt, ev->channel, ev->bssid, - ev->listenInterval, ev->beaconInterval, - (NETWORK_TYPE) ev->networkType, ev->beaconIeLen, - ev->assocReqLen, ev->assocRespLen, - ev->assocInfo); - - return 0; -} - -static int -wmi_regDomain_event_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - WMI_REG_DOMAIN_EVENT *ev; - - if (len < sizeof(*ev)) { - return A_EINVAL; - } - ev = (WMI_REG_DOMAIN_EVENT *)datap; - - A_WMI_REGDOMAIN_EVENT(wmip->wmi_devt, ev->regDomain); - - return 0; -} - -static int -wmi_neighborReport_event_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - WMI_NEIGHBOR_REPORT_EVENT *ev; - int numAps; - - if (len < sizeof(*ev)) { - return A_EINVAL; - } - ev = (WMI_NEIGHBOR_REPORT_EVENT *)datap; - numAps = ev->numberOfAps; - - if (len < (int)(sizeof(*ev) + ((numAps - 1) * sizeof(WMI_NEIGHBOR_INFO)))) { - return A_EINVAL; - } - - A_WMI_NEIGHBORREPORT_EVENT(wmip->wmi_devt, numAps, ev->neighbor); - - return 0; -} - -static int -wmi_disconnect_event_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - WMI_DISCONNECT_EVENT *ev; - wmip->wmi_traffic_class = 100; - - if (len < sizeof(WMI_DISCONNECT_EVENT)) { - return A_EINVAL; - } - A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); - - ev = (WMI_DISCONNECT_EVENT *)datap; - - A_MEMZERO(wmip->wmi_bssid, sizeof(wmip->wmi_bssid)); - - wmip->wmi_is_wmm_enabled = false; - wmip->wmi_pair_crypto_type = NONE_CRYPT; - wmip->wmi_grp_crypto_type = NONE_CRYPT; - - A_WMI_DISCONNECT_EVENT(wmip->wmi_devt, ev->disconnectReason, ev->bssid, - ev->assocRespLen, ev->assocInfo, ev->protocolReasonStatus); - - return 0; -} - -static int -wmi_peer_node_event_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - WMI_PEER_NODE_EVENT *ev; - - if (len < sizeof(WMI_PEER_NODE_EVENT)) { - return A_EINVAL; - } - ev = (WMI_PEER_NODE_EVENT *)datap; - if (ev->eventCode == PEER_NODE_JOIN_EVENT) { - A_DPRINTF (DBG_WMI, (DBGFMT "Joined node with Macaddr: ", DBGARG)); - } else if(ev->eventCode == PEER_NODE_LEAVE_EVENT) { - A_DPRINTF (DBG_WMI, (DBGFMT "left node with Macaddr: ", DBGARG)); - } - - A_WMI_PEER_EVENT (wmip->wmi_devt, ev->eventCode, ev->peerMacAddr); - - return 0; -} - -static int -wmi_tkip_micerr_event_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - WMI_TKIP_MICERR_EVENT *ev; - - if (len < sizeof(*ev)) { - return A_EINVAL; - } - A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); - - ev = (WMI_TKIP_MICERR_EVENT *)datap; - A_WMI_TKIP_MICERR_EVENT(wmip->wmi_devt, ev->keyid, ev->ismcast); - - return 0; -} - -static int -wmi_bssInfo_event_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - bss_t *bss = NULL; - WMI_BSS_INFO_HDR *bih; - u8 *buf; - u32 nodeCachingAllowed = 1; - u8 cached_ssid_len = 0; - u8 cached_ssid_buf[IEEE80211_NWID_LEN] = {0}; - u8 beacon_ssid_len = 0; - - if (len <= sizeof(WMI_BSS_INFO_HDR)) { - return A_EINVAL; - } - - bih = (WMI_BSS_INFO_HDR *)datap; - bss = wlan_find_node(&wmip->wmi_scan_table, bih->bssid); - - if (bih->rssi > 0) { - if (NULL == bss) - return 0; //no node found in the table, just drop the node with incorrect RSSI - else - bih->rssi = bss->ni_rssi; //Adjust RSSI in datap in case it is used in A_WMI_BSSINFO_EVENT_RX - } - - A_WMI_BSSINFO_EVENT_RX(wmip->wmi_devt, datap, len); - /* What is driver config for wlan node caching? */ - if(ar6000_get_driver_cfg(wmip->wmi_devt, - AR6000_DRIVER_CFG_GET_WLANNODECACHING, - &nodeCachingAllowed) != 0) { - wmi_node_return(wmip, bss); - return A_EINVAL; - } - - if(!nodeCachingAllowed) { - wmi_node_return(wmip, bss); - return 0; - } - - buf = datap + sizeof(WMI_BSS_INFO_HDR); - len -= sizeof(WMI_BSS_INFO_HDR); - - A_DPRINTF(DBG_WMI2, (DBGFMT "bssInfo event - ch %u, rssi %02x, " - "bssid \"%pM\"\n", DBGARG, bih->channel, - (unsigned char) bih->rssi, bih->bssid)); - - if(wps_enable && (bih->frameType == PROBERESP_FTYPE) ) { - wmi_node_return(wmip, bss); - return 0; - } - - if (bss != NULL) { - /* - * Free up the node. Not the most efficient process given - * we are about to allocate a new node but it is simple and should be - * adequate. - */ - - /* In case of hidden AP, beacon will not have ssid, - * but a directed probe response will have it, - * so cache the probe-resp-ssid if already present. */ - if ((true == is_probe_ssid) && (BEACON_FTYPE == bih->frameType)) - { - u8 *ie_ssid; - - ie_ssid = bss->ni_cie.ie_ssid; - if(ie_ssid && (ie_ssid[1] <= IEEE80211_NWID_LEN) && (ie_ssid[2] != 0)) - { - cached_ssid_len = ie_ssid[1]; - memcpy(cached_ssid_buf, ie_ssid + 2, cached_ssid_len); - } - } - - /* - * Use the current average rssi of associated AP base on assumpiton - * 1. Most os with GUI will update RSSI by wmi_get_stats_cmd() periodically - * 2. wmi_get_stats_cmd(..) will be called when calling wmi_startscan_cmd(...) - * The average value of RSSI give end-user better feeling for instance value of scan result - * It also sync up RSSI info in GUI between scan result and RSSI signal icon - */ - if (IEEE80211_ADDR_EQ(wmip->wmi_bssid, bih->bssid)) { - bih->rssi = bss->ni_rssi; - bih->snr = bss->ni_snr; - } - - wlan_node_reclaim(&wmip->wmi_scan_table, bss); - } - - /* beacon/probe response frame format - * [8] time stamp - * [2] beacon interval - * [2] capability information - * [tlv] ssid */ - beacon_ssid_len = buf[SSID_IE_LEN_INDEX]; - - /* If ssid is cached for this hidden AP, then change buffer len accordingly. */ - if ((true == is_probe_ssid) && (BEACON_FTYPE == bih->frameType) && - (0 != cached_ssid_len) && - (0 == beacon_ssid_len || (cached_ssid_len > beacon_ssid_len && 0 == buf[SSID_IE_LEN_INDEX + 1]))) - { - len += (cached_ssid_len - beacon_ssid_len); - } - - bss = wlan_node_alloc(&wmip->wmi_scan_table, len); - if (bss == NULL) { - return A_NO_MEMORY; - } - - bss->ni_snr = bih->snr; - bss->ni_rssi = bih->rssi; - A_ASSERT(bss->ni_buf != NULL); - - /* In case of hidden AP, beacon will not have ssid, - * but a directed probe response will have it, - * so place the cached-ssid(probe-resp) in the bssinfo. */ - if ((true == is_probe_ssid) && (BEACON_FTYPE == bih->frameType) && - (0 != cached_ssid_len) && - (0 == beacon_ssid_len || (beacon_ssid_len && 0 == buf[SSID_IE_LEN_INDEX + 1]))) - { - u8 *ni_buf = bss->ni_buf; - int buf_len = len; - - /* copy the first 14 bytes such as - * time-stamp(8), beacon-interval(2), cap-info(2), ssid-id(1), ssid-len(1). */ - memcpy(ni_buf, buf, SSID_IE_LEN_INDEX + 1); - - ni_buf[SSID_IE_LEN_INDEX] = cached_ssid_len; - ni_buf += (SSID_IE_LEN_INDEX + 1); - - buf += (SSID_IE_LEN_INDEX + 1); - buf_len -= (SSID_IE_LEN_INDEX + 1); - - /* copy the cached ssid */ - memcpy(ni_buf, cached_ssid_buf, cached_ssid_len); - ni_buf += cached_ssid_len; - - buf += beacon_ssid_len; - buf_len -= beacon_ssid_len; - - if (cached_ssid_len > beacon_ssid_len) - buf_len -= (cached_ssid_len - beacon_ssid_len); - - /* now copy the rest of bytes */ - memcpy(ni_buf, buf, buf_len); - } - else - memcpy(bss->ni_buf, buf, len); - - bss->ni_framelen = len; - if (wlan_parse_beacon(bss->ni_buf, len, &bss->ni_cie) != 0) { - wlan_node_free(bss); - return A_EINVAL; - } - - /* - * Update the frequency in ie_chan, overwriting of channel number - * which is done in wlan_parse_beacon - */ - bss->ni_cie.ie_chan = bih->channel; - wlan_setup_node(&wmip->wmi_scan_table, bss, bih->bssid); - - return 0; -} - -static int -wmi_opt_frame_event_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - bss_t *bss; - WMI_OPT_RX_INFO_HDR *bih; - u8 *buf; - - if (len <= sizeof(WMI_OPT_RX_INFO_HDR)) { - return A_EINVAL; - } - - bih = (WMI_OPT_RX_INFO_HDR *)datap; - buf = datap + sizeof(WMI_OPT_RX_INFO_HDR); - len -= sizeof(WMI_OPT_RX_INFO_HDR); - - A_DPRINTF(DBG_WMI2, (DBGFMT "opt frame event %2.2x:%2.2x\n", DBGARG, - bih->bssid[4], bih->bssid[5])); - - bss = wlan_find_node(&wmip->wmi_scan_table, bih->bssid); - if (bss != NULL) { - /* - * Free up the node. Not the most efficient process given - * we are about to allocate a new node but it is simple and should be - * adequate. - */ - wlan_node_reclaim(&wmip->wmi_scan_table, bss); - } - - bss = wlan_node_alloc(&wmip->wmi_scan_table, len); - if (bss == NULL) { - return A_NO_MEMORY; - } - - bss->ni_snr = bih->snr; - bss->ni_cie.ie_chan = bih->channel; - A_ASSERT(bss->ni_buf != NULL); - memcpy(bss->ni_buf, buf, len); - wlan_setup_node(&wmip->wmi_scan_table, bss, bih->bssid); - - return 0; -} - - /* This event indicates inactivity timeout of a fatpipe(pstream) - * at the target - */ -static int -wmi_pstream_timeout_event_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - WMI_PSTREAM_TIMEOUT_EVENT *ev; - - if (len < sizeof(WMI_PSTREAM_TIMEOUT_EVENT)) { - return A_EINVAL; - } - - A_DPRINTF(DBG_WMI, (DBGFMT "wmi_pstream_timeout_event_rx\n", DBGARG)); - - ev = (WMI_PSTREAM_TIMEOUT_EVENT *)datap; - - /* When the pstream (fat pipe == AC) timesout, it means there were no - * thinStreams within this pstream & it got implicitly created due to - * data flow on this AC. We start the inactivity timer only for - * implicitly created pstream. Just reset the host state. - */ - /* Set the activeTsids for this AC to 0 */ - LOCK_WMI(wmip); - wmip->wmi_streamExistsForAC[ev->trafficClass]=0; - wmip->wmi_fatPipeExists &= ~(1 << ev->trafficClass); - UNLOCK_WMI(wmip); - - /*Indicate inactivity to driver layer for this fatpipe (pstream)*/ - A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt, ev->trafficClass); - - return 0; -} - -static int -wmi_bitrate_reply_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - WMI_BIT_RATE_REPLY *reply; - s32 rate; - u32 sgi,index; - /* 54149: - * WMI_BIT_RATE_CMD structure is changed to WMI_BIT_RATE_REPLY. - * since there is difference in the length and to avoid returning - * error value. - */ - if (len < sizeof(WMI_BIT_RATE_REPLY)) { - return A_EINVAL; - } - reply = (WMI_BIT_RATE_REPLY *)datap; - A_DPRINTF(DBG_WMI, - (DBGFMT "Enter - rateindex %d\n", DBGARG, reply->rateIndex)); - - if (reply->rateIndex == (s8) RATE_AUTO) { - rate = RATE_AUTO; - } else { - // the SGI state is stored as the MSb of the rateIndex - index = reply->rateIndex & 0x7f; - sgi = (reply->rateIndex & 0x80)? 1:0; - rate = wmi_rateTable[index][sgi]; - } - - A_WMI_BITRATE_RX(wmip->wmi_devt, rate); - return 0; -} - -static int -wmi_ratemask_reply_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - WMI_FIX_RATES_REPLY *reply; - - if (len < sizeof(WMI_FIX_RATES_REPLY)) { - return A_EINVAL; - } - reply = (WMI_FIX_RATES_REPLY *)datap; - A_DPRINTF(DBG_WMI, - (DBGFMT "Enter - fixed rate mask %x\n", DBGARG, reply->fixRateMask)); - - A_WMI_RATEMASK_RX(wmip->wmi_devt, reply->fixRateMask); - - return 0; -} - -static int -wmi_channelList_reply_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - WMI_CHANNEL_LIST_REPLY *reply; - - if (len < sizeof(WMI_CHANNEL_LIST_REPLY)) { - return A_EINVAL; - } - reply = (WMI_CHANNEL_LIST_REPLY *)datap; - A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); - - A_WMI_CHANNELLIST_RX(wmip->wmi_devt, reply->numChannels, - reply->channelList); - - return 0; -} - -static int -wmi_txPwr_reply_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - WMI_TX_PWR_REPLY *reply; - - if (len < sizeof(*reply)) { - return A_EINVAL; - } - reply = (WMI_TX_PWR_REPLY *)datap; - A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); - - A_WMI_TXPWR_RX(wmip->wmi_devt, reply->dbM); - - return 0; -} -static int -wmi_keepalive_reply_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - WMI_GET_KEEPALIVE_CMD *reply; - - if (len < sizeof(*reply)) { - return A_EINVAL; - } - reply = (WMI_GET_KEEPALIVE_CMD *)datap; - A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); - - A_WMI_KEEPALIVE_RX(wmip->wmi_devt, reply->configured); - - return 0; -} - - -static int -wmi_dset_open_req_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - WMIX_DSETOPENREQ_EVENT *dsetopenreq; - - if (len < sizeof(WMIX_DSETOPENREQ_EVENT)) { - return A_EINVAL; - } - dsetopenreq = (WMIX_DSETOPENREQ_EVENT *)datap; - A_DPRINTF(DBG_WMI, - (DBGFMT "Enter - dset_id=0x%x\n", DBGARG, dsetopenreq->dset_id)); - A_WMI_DSET_OPEN_REQ(wmip->wmi_devt, - dsetopenreq->dset_id, - dsetopenreq->targ_dset_handle, - dsetopenreq->targ_reply_fn, - dsetopenreq->targ_reply_arg); - - return 0; -} - -#ifdef CONFIG_HOST_DSET_SUPPORT -static int -wmi_dset_close_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - WMIX_DSETCLOSE_EVENT *dsetclose; - - if (len < sizeof(WMIX_DSETCLOSE_EVENT)) { - return A_EINVAL; - } - A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); - - dsetclose = (WMIX_DSETCLOSE_EVENT *)datap; - A_WMI_DSET_CLOSE(wmip->wmi_devt, dsetclose->access_cookie); - - return 0; -} - -static int -wmi_dset_data_req_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - WMIX_DSETDATAREQ_EVENT *dsetdatareq; - - if (len < sizeof(WMIX_DSETDATAREQ_EVENT)) { - return A_EINVAL; - } - A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); - - dsetdatareq = (WMIX_DSETDATAREQ_EVENT *)datap; - A_WMI_DSET_DATA_REQ(wmip->wmi_devt, - dsetdatareq->access_cookie, - dsetdatareq->offset, - dsetdatareq->length, - dsetdatareq->targ_buf, - dsetdatareq->targ_reply_fn, - dsetdatareq->targ_reply_arg); - - return 0; -} -#endif /* CONFIG_HOST_DSET_SUPPORT */ - -static int -wmi_scanComplete_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - WMI_SCAN_COMPLETE_EVENT *ev; - - ev = (WMI_SCAN_COMPLETE_EVENT *)datap; - if ((int)ev->status == 0) { - wlan_refresh_inactive_nodes(&wmip->wmi_scan_table); - } - A_WMI_SCANCOMPLETE_EVENT(wmip->wmi_devt, (int) ev->status); - is_probe_ssid = false; - - return 0; -} - -/* - * Target is reporting a programming error. This is for - * developer aid only. Target only checks a few common violations - * and it is responsibility of host to do all error checking. - * Behavior of target after wmi error event is undefined. - * A reset is recommended. - */ -static int -wmi_errorEvent_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - WMI_CMD_ERROR_EVENT *ev; - - ev = (WMI_CMD_ERROR_EVENT *)datap; - AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Programming Error: cmd=%d ", ev->commandId)); - switch (ev->errorCode) { - case (INVALID_PARAM): - AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Illegal Parameter\n")); - break; - case (ILLEGAL_STATE): - AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Illegal State\n")); - break; - case (INTERNAL_ERROR): - AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Internal Error\n")); - break; - } - - return 0; -} - - -static int -wmi_statsEvent_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); - - A_WMI_TARGETSTATS_EVENT(wmip->wmi_devt, datap, len); - - return 0; -} - -static int -wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - WMI_RSSI_THRESHOLD_EVENT *reply; - WMI_RSSI_THRESHOLD_VAL newThreshold; - WMI_RSSI_THRESHOLD_PARAMS_CMD cmd; - SQ_THRESHOLD_PARAMS *sq_thresh = - &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_RSSI]; - u8 upper_rssi_threshold, lower_rssi_threshold; - s16 rssi; - - if (len < sizeof(*reply)) { - return A_EINVAL; - } - reply = (WMI_RSSI_THRESHOLD_EVENT *)datap; - A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); - newThreshold = (WMI_RSSI_THRESHOLD_VAL) reply->range; - rssi = reply->rssi; - - /* - * Identify the threshold breached and communicate that to the app. After - * that install a new set of thresholds based on the signal quality - * reported by the target - */ - if (newThreshold) { - /* Upper threshold breached */ - if (rssi < sq_thresh->upper_threshold[0]) { - A_DPRINTF(DBG_WMI, (DBGFMT "Spurious upper RSSI threshold event: " - " %d\n", DBGARG, rssi)); - } else if ((rssi < sq_thresh->upper_threshold[1]) && - (rssi >= sq_thresh->upper_threshold[0])) - { - newThreshold = WMI_RSSI_THRESHOLD1_ABOVE; - } else if ((rssi < sq_thresh->upper_threshold[2]) && - (rssi >= sq_thresh->upper_threshold[1])) - { - newThreshold = WMI_RSSI_THRESHOLD2_ABOVE; - } else if ((rssi < sq_thresh->upper_threshold[3]) && - (rssi >= sq_thresh->upper_threshold[2])) - { - newThreshold = WMI_RSSI_THRESHOLD3_ABOVE; - } else if ((rssi < sq_thresh->upper_threshold[4]) && - (rssi >= sq_thresh->upper_threshold[3])) - { - newThreshold = WMI_RSSI_THRESHOLD4_ABOVE; - } else if ((rssi < sq_thresh->upper_threshold[5]) && - (rssi >= sq_thresh->upper_threshold[4])) - { - newThreshold = WMI_RSSI_THRESHOLD5_ABOVE; - } else if (rssi >= sq_thresh->upper_threshold[5]) { - newThreshold = WMI_RSSI_THRESHOLD6_ABOVE; - } - } else { - /* Lower threshold breached */ - if (rssi > sq_thresh->lower_threshold[0]) { - A_DPRINTF(DBG_WMI, (DBGFMT "Spurious lower RSSI threshold event: " - "%d %d\n", DBGARG, rssi, sq_thresh->lower_threshold[0])); - } else if ((rssi > sq_thresh->lower_threshold[1]) && - (rssi <= sq_thresh->lower_threshold[0])) - { - newThreshold = WMI_RSSI_THRESHOLD6_BELOW; - } else if ((rssi > sq_thresh->lower_threshold[2]) && - (rssi <= sq_thresh->lower_threshold[1])) - { - newThreshold = WMI_RSSI_THRESHOLD5_BELOW; - } else if ((rssi > sq_thresh->lower_threshold[3]) && - (rssi <= sq_thresh->lower_threshold[2])) - { - newThreshold = WMI_RSSI_THRESHOLD4_BELOW; - } else if ((rssi > sq_thresh->lower_threshold[4]) && - (rssi <= sq_thresh->lower_threshold[3])) - { - newThreshold = WMI_RSSI_THRESHOLD3_BELOW; - } else if ((rssi > sq_thresh->lower_threshold[5]) && - (rssi <= sq_thresh->lower_threshold[4])) - { - newThreshold = WMI_RSSI_THRESHOLD2_BELOW; - } else if (rssi <= sq_thresh->lower_threshold[5]) { - newThreshold = WMI_RSSI_THRESHOLD1_BELOW; - } - } - /* Calculate and install the next set of thresholds */ - lower_rssi_threshold = ar6000_get_lower_threshold(rssi, sq_thresh, - sq_thresh->lower_threshold_valid_count); - upper_rssi_threshold = ar6000_get_upper_threshold(rssi, sq_thresh, - sq_thresh->upper_threshold_valid_count); - /* Issue a wmi command to install the thresholds */ - cmd.thresholdAbove1_Val = upper_rssi_threshold; - cmd.thresholdBelow1_Val = lower_rssi_threshold; - cmd.weight = sq_thresh->weight; - cmd.pollTime = sq_thresh->polling_interval; - - rssi_event_value = rssi; - - if (wmi_send_rssi_threshold_params(wmip, &cmd) != 0) { - A_DPRINTF(DBG_WMI, (DBGFMT "Unable to configure the RSSI thresholds\n", - DBGARG)); - } - - A_WMI_RSSI_THRESHOLD_EVENT(wmip->wmi_devt, newThreshold, reply->rssi); - - return 0; -} - - -static int -wmi_reportErrorEvent_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - WMI_TARGET_ERROR_REPORT_EVENT *reply; - - if (len < sizeof(*reply)) { - return A_EINVAL; - } - reply = (WMI_TARGET_ERROR_REPORT_EVENT *)datap; - A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); - - A_WMI_REPORT_ERROR_EVENT(wmip->wmi_devt, (WMI_TARGET_ERROR_VAL) reply->errorVal); - - return 0; -} - -static int -wmi_cac_event_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - WMI_CAC_EVENT *reply; - WMM_TSPEC_IE *tspec_ie; - u16 activeTsids; - - if (len < sizeof(*reply)) { - return A_EINVAL; - } - reply = (WMI_CAC_EVENT *)datap; - - A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); - - if ((reply->cac_indication == CAC_INDICATION_ADMISSION_RESP) && - (reply->statusCode != TSPEC_STATUS_CODE_ADMISSION_ACCEPTED)) { - tspec_ie = (WMM_TSPEC_IE *) &(reply->tspecSuggestion); - - wmi_delete_pstream_cmd(wmip, reply->ac, - (tspec_ie->tsInfo_info >> TSPEC_TSID_S) & TSPEC_TSID_MASK); - } - else if (reply->cac_indication == CAC_INDICATION_NO_RESP) { - u8 i; - - /* following assumes that there is only one outstanding ADDTS request - when this event is received */ - LOCK_WMI(wmip); - activeTsids = wmip->wmi_streamExistsForAC[reply->ac]; - UNLOCK_WMI(wmip); - - for (i = 0; i < sizeof(activeTsids) * 8; i++) { - if ((activeTsids >> i) & 1) { - break; - } - } - if (i < (sizeof(activeTsids) * 8)) { - wmi_delete_pstream_cmd(wmip, reply->ac, i); - } - } - /* - * Ev#72990: Clear active tsids and Add missing handling - * for delete qos stream from AP - */ - else if (reply->cac_indication == CAC_INDICATION_DELETE) { - u8 tsid = 0; - - tspec_ie = (WMM_TSPEC_IE *) &(reply->tspecSuggestion); - tsid= ((tspec_ie->tsInfo_info >> TSPEC_TSID_S) & TSPEC_TSID_MASK); - LOCK_WMI(wmip); - wmip->wmi_streamExistsForAC[reply->ac] &= ~(1<<tsid); - activeTsids = wmip->wmi_streamExistsForAC[reply->ac]; - UNLOCK_WMI(wmip); - - - /* Indicate stream inactivity to driver layer only if all tsids - * within this AC are deleted. - */ - if (!activeTsids) { - A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt, reply->ac); - wmip->wmi_fatPipeExists &= ~(1 << reply->ac); - } - } - - A_WMI_CAC_EVENT(wmip->wmi_devt, reply->ac, - reply->cac_indication, reply->statusCode, - reply->tspecSuggestion); - - return 0; -} - -static int -wmi_channel_change_event_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - WMI_CHANNEL_CHANGE_EVENT *reply; - - if (len < sizeof(*reply)) { - return A_EINVAL; - } - reply = (WMI_CHANNEL_CHANGE_EVENT *)datap; - A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); - - A_WMI_CHANNEL_CHANGE_EVENT(wmip->wmi_devt, reply->oldChannel, - reply->newChannel); - - return 0; -} - -static int -wmi_hbChallengeResp_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - WMIX_HB_CHALLENGE_RESP_EVENT *reply; - - if (len < sizeof(*reply)) { - return A_EINVAL; - } - reply = (WMIX_HB_CHALLENGE_RESP_EVENT *)datap; - A_DPRINTF(DBG_WMI, (DBGFMT "wmi: challenge response event\n", DBGARG)); - - A_WMI_HBCHALLENGERESP_EVENT(wmip->wmi_devt, reply->cookie, reply->source); - - return 0; -} - -static int -wmi_roam_tbl_event_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - WMI_TARGET_ROAM_TBL *reply; - - if (len < sizeof(*reply)) { - return A_EINVAL; - } - reply = (WMI_TARGET_ROAM_TBL *)datap; - A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); - - A_WMI_ROAM_TABLE_EVENT(wmip->wmi_devt, reply); - - return 0; -} - -static int -wmi_roam_data_event_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - WMI_TARGET_ROAM_DATA *reply; - - if (len < sizeof(*reply)) { - return A_EINVAL; - } - reply = (WMI_TARGET_ROAM_DATA *)datap; - A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); - - A_WMI_ROAM_DATA_EVENT(wmip->wmi_devt, reply); - - return 0; -} - -static int -wmi_txRetryErrEvent_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - if (len < sizeof(WMI_TX_RETRY_ERR_EVENT)) { - return A_EINVAL; - } - A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); - - A_WMI_TX_RETRY_ERR_EVENT(wmip->wmi_devt); - - return 0; -} - -static int -wmi_snrThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - WMI_SNR_THRESHOLD_EVENT *reply; - SQ_THRESHOLD_PARAMS *sq_thresh = - &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_SNR]; - WMI_SNR_THRESHOLD_VAL newThreshold; - WMI_SNR_THRESHOLD_PARAMS_CMD cmd; - u8 upper_snr_threshold, lower_snr_threshold; - s16 snr; - - if (len < sizeof(*reply)) { - return A_EINVAL; - } - reply = (WMI_SNR_THRESHOLD_EVENT *)datap; - A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); - - newThreshold = (WMI_SNR_THRESHOLD_VAL) reply->range; - snr = reply->snr; - /* - * Identify the threshold breached and communicate that to the app. After - * that install a new set of thresholds based on the signal quality - * reported by the target - */ - if (newThreshold) { - /* Upper threshold breached */ - if (snr < sq_thresh->upper_threshold[0]) { - A_DPRINTF(DBG_WMI, (DBGFMT "Spurious upper SNR threshold event: " - "%d\n", DBGARG, snr)); - } else if ((snr < sq_thresh->upper_threshold[1]) && - (snr >= sq_thresh->upper_threshold[0])) - { - newThreshold = WMI_SNR_THRESHOLD1_ABOVE; - } else if ((snr < sq_thresh->upper_threshold[2]) && - (snr >= sq_thresh->upper_threshold[1])) - { - newThreshold = WMI_SNR_THRESHOLD2_ABOVE; - } else if ((snr < sq_thresh->upper_threshold[3]) && - (snr >= sq_thresh->upper_threshold[2])) - { - newThreshold = WMI_SNR_THRESHOLD3_ABOVE; - } else if (snr >= sq_thresh->upper_threshold[3]) { - newThreshold = WMI_SNR_THRESHOLD4_ABOVE; - } - } else { - /* Lower threshold breached */ - if (snr > sq_thresh->lower_threshold[0]) { - A_DPRINTF(DBG_WMI, (DBGFMT "Spurious lower SNR threshold event: " - "%d %d\n", DBGARG, snr, sq_thresh->lower_threshold[0])); - } else if ((snr > sq_thresh->lower_threshold[1]) && - (snr <= sq_thresh->lower_threshold[0])) - { - newThreshold = WMI_SNR_THRESHOLD4_BELOW; - } else if ((snr > sq_thresh->lower_threshold[2]) && - (snr <= sq_thresh->lower_threshold[1])) - { - newThreshold = WMI_SNR_THRESHOLD3_BELOW; - } else if ((snr > sq_thresh->lower_threshold[3]) && - (snr <= sq_thresh->lower_threshold[2])) - { - newThreshold = WMI_SNR_THRESHOLD2_BELOW; - } else if (snr <= sq_thresh->lower_threshold[3]) { - newThreshold = WMI_SNR_THRESHOLD1_BELOW; - } - } - - /* Calculate and install the next set of thresholds */ - lower_snr_threshold = ar6000_get_lower_threshold(snr, sq_thresh, - sq_thresh->lower_threshold_valid_count); - upper_snr_threshold = ar6000_get_upper_threshold(snr, sq_thresh, - sq_thresh->upper_threshold_valid_count); - - /* Issue a wmi command to install the thresholds */ - cmd.thresholdAbove1_Val = upper_snr_threshold; - cmd.thresholdBelow1_Val = lower_snr_threshold; - cmd.weight = sq_thresh->weight; - cmd.pollTime = sq_thresh->polling_interval; - - A_DPRINTF(DBG_WMI, (DBGFMT "snr: %d, threshold: %d, lower: %d, upper: %d\n" - ,DBGARG, snr, newThreshold, lower_snr_threshold, - upper_snr_threshold)); - - snr_event_value = snr; - - if (wmi_send_snr_threshold_params(wmip, &cmd) != 0) { - A_DPRINTF(DBG_WMI, (DBGFMT "Unable to configure the SNR thresholds\n", - DBGARG)); - } - A_WMI_SNR_THRESHOLD_EVENT_RX(wmip->wmi_devt, newThreshold, reply->snr); - - return 0; -} - -static int -wmi_lqThresholdEvent_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - WMI_LQ_THRESHOLD_EVENT *reply; - - if (len < sizeof(*reply)) { - return A_EINVAL; - } - reply = (WMI_LQ_THRESHOLD_EVENT *)datap; - A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); - - A_WMI_LQ_THRESHOLD_EVENT_RX(wmip->wmi_devt, - (WMI_LQ_THRESHOLD_VAL) reply->range, - reply->lq); - - return 0; -} - -static int -wmi_aplistEvent_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - u16 ap_info_entry_size; - WMI_APLIST_EVENT *ev = (WMI_APLIST_EVENT *)datap; - WMI_AP_INFO_V1 *ap_info_v1; - u8 i; - - if (len < sizeof(WMI_APLIST_EVENT)) { - return A_EINVAL; - } - - if (ev->apListVer == APLIST_VER1) { - ap_info_entry_size = sizeof(WMI_AP_INFO_V1); - ap_info_v1 = (WMI_AP_INFO_V1 *)ev->apList; - } else { - return A_EINVAL; - } - - AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("Number of APs in APLIST Event is %d\n", ev->numAP)); - if (len < (int)(sizeof(WMI_APLIST_EVENT) + - (ev->numAP - 1) * ap_info_entry_size)) - { - return A_EINVAL; - } - - /* - * AP List Ver1 Contents - */ - for (i = 0; i < ev->numAP; i++) { - AR_DEBUG_PRINTF(ATH_DEBUG_WMI, ("AP#%d BSSID %2.2x %2.2x %2.2x %2.2x %2.2x %2.2x "\ - "Channel %d\n", i, - ap_info_v1->bssid[0], ap_info_v1->bssid[1], - ap_info_v1->bssid[2], ap_info_v1->bssid[3], - ap_info_v1->bssid[4], ap_info_v1->bssid[5], - ap_info_v1->channel)); - ap_info_v1++; - } - return 0; -} - -static int -wmi_dbglog_event_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - u32 dropped; - - dropped = *((u32 *)datap); - datap += sizeof(dropped); - len -= sizeof(dropped); - A_WMI_DBGLOG_EVENT(wmip->wmi_devt, dropped, (s8 *)datap, len); - return 0; -} - -/* - * Called to send a wmi command. Command specific data is already built - * on osbuf and current osbuf->data points to it. - */ -int -wmi_cmd_send(struct wmi_t *wmip, void *osbuf, WMI_COMMAND_ID cmdId, - WMI_SYNC_FLAG syncflag) -{ - int status; -#define IS_OPT_TX_CMD(cmdId) ((cmdId == WMI_OPT_TX_FRAME_CMDID)) - WMI_CMD_HDR *cHdr; - HTC_ENDPOINT_ID eid = wmip->wmi_endpoint_id; - - A_ASSERT(osbuf != NULL); - - if (syncflag >= END_WMIFLAG) { - A_NETBUF_FREE(osbuf); - return A_EINVAL; - } - - if ((syncflag == SYNC_BEFORE_WMIFLAG) || (syncflag == SYNC_BOTH_WMIFLAG)) { - /* - * We want to make sure all data currently queued is transmitted before - * the cmd execution. Establish a new sync point. - */ - wmi_sync_point(wmip); - } - - if (A_NETBUF_PUSH(osbuf, sizeof(WMI_CMD_HDR)) != 0) { - A_NETBUF_FREE(osbuf); - return A_NO_MEMORY; - } - - cHdr = (WMI_CMD_HDR *)A_NETBUF_DATA(osbuf); - cHdr->commandId = (u16) cmdId; - cHdr->info1 = 0; // added for virtual interface - - /* - * Only for OPT_TX_CMD, use BE endpoint. - */ - if (IS_OPT_TX_CMD(cmdId)) { - if ((status=wmi_data_hdr_add(wmip, osbuf, OPT_MSGTYPE, false, false,0,NULL)) != 0) { - A_NETBUF_FREE(osbuf); - return status; - } - eid = A_WMI_Ac2EndpointID(wmip->wmi_devt, WMM_AC_BE); - } - A_WMI_CONTROL_TX(wmip->wmi_devt, osbuf, eid); - - if ((syncflag == SYNC_AFTER_WMIFLAG) || (syncflag == SYNC_BOTH_WMIFLAG)) { - /* - * We want to make sure all new data queued waits for the command to - * execute. Establish a new sync point. - */ - wmi_sync_point(wmip); - } - return (0); -#undef IS_OPT_TX_CMD -} - -int -wmi_cmd_send_xtnd(struct wmi_t *wmip, void *osbuf, WMIX_COMMAND_ID cmdId, - WMI_SYNC_FLAG syncflag) -{ - WMIX_CMD_HDR *cHdr; - - if (A_NETBUF_PUSH(osbuf, sizeof(WMIX_CMD_HDR)) != 0) { - A_NETBUF_FREE(osbuf); - return A_NO_MEMORY; - } - - cHdr = (WMIX_CMD_HDR *)A_NETBUF_DATA(osbuf); - cHdr->commandId = (u32) cmdId; - - return wmi_cmd_send(wmip, osbuf, WMI_EXTENSION_CMDID, syncflag); -} - -int -wmi_connect_cmd(struct wmi_t *wmip, NETWORK_TYPE netType, - DOT11_AUTH_MODE dot11AuthMode, AUTH_MODE authMode, - CRYPTO_TYPE pairwiseCrypto, u8 pairwiseCryptoLen, - CRYPTO_TYPE groupCrypto, u8 groupCryptoLen, - int ssidLength, u8 *ssid, - u8 *bssid, u16 channel, u32 ctrl_flags) -{ - void *osbuf; - WMI_CONNECT_CMD *cc; - wmip->wmi_traffic_class = 100; - - if ((pairwiseCrypto == NONE_CRYPT) && (groupCrypto != NONE_CRYPT)) { - return A_EINVAL; - } - if ((pairwiseCrypto != NONE_CRYPT) && (groupCrypto == NONE_CRYPT)) { - return A_EINVAL; - } - - osbuf = A_NETBUF_ALLOC(sizeof(WMI_CONNECT_CMD)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(WMI_CONNECT_CMD)); - - cc = (WMI_CONNECT_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cc, sizeof(*cc)); - - if (ssidLength) - { - memcpy(cc->ssid, ssid, ssidLength); - } - - cc->ssidLength = ssidLength; - cc->networkType = netType; - cc->dot11AuthMode = dot11AuthMode; - cc->authMode = authMode; - cc->pairwiseCryptoType = pairwiseCrypto; - cc->pairwiseCryptoLen = pairwiseCryptoLen; - cc->groupCryptoType = groupCrypto; - cc->groupCryptoLen = groupCryptoLen; - cc->channel = channel; - cc->ctrl_flags = ctrl_flags; - - if (bssid != NULL) { - memcpy(cc->bssid, bssid, ATH_MAC_LEN); - } - - wmip->wmi_pair_crypto_type = pairwiseCrypto; - wmip->wmi_grp_crypto_type = groupCrypto; - - return (wmi_cmd_send(wmip, osbuf, WMI_CONNECT_CMDID, NO_SYNC_WMIFLAG)); -} - -int -wmi_reconnect_cmd(struct wmi_t *wmip, u8 *bssid, u16 channel) -{ - void *osbuf; - WMI_RECONNECT_CMD *cc; - wmip->wmi_traffic_class = 100; - - osbuf = A_NETBUF_ALLOC(sizeof(WMI_RECONNECT_CMD)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(WMI_RECONNECT_CMD)); - - cc = (WMI_RECONNECT_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cc, sizeof(*cc)); - - cc->channel = channel; - - if (bssid != NULL) { - memcpy(cc->bssid, bssid, ATH_MAC_LEN); - } - - return (wmi_cmd_send(wmip, osbuf, WMI_RECONNECT_CMDID, NO_SYNC_WMIFLAG)); -} - -int -wmi_disconnect_cmd(struct wmi_t *wmip) -{ - int status; - wmip->wmi_traffic_class = 100; - - /* Bug fix for 24817(elevator bug) - the disconnect command does not - need to do a SYNC before.*/ - status = wmi_simple_cmd(wmip, WMI_DISCONNECT_CMDID); - - return status; -} - -int -wmi_startscan_cmd(struct wmi_t *wmip, WMI_SCAN_TYPE scanType, - u32 forceFgScan, u32 isLegacy, - u32 homeDwellTime, u32 forceScanInterval, - s8 numChan, u16 *channelList) -{ - void *osbuf; - WMI_START_SCAN_CMD *sc; - s8 size; - - size = sizeof (*sc); - - if ((scanType != WMI_LONG_SCAN) && (scanType != WMI_SHORT_SCAN)) { - return A_EINVAL; - } - - if (numChan) { - if (numChan > WMI_MAX_CHANNELS) { - return A_EINVAL; - } - size += sizeof(u16) * (numChan - 1); - } - - osbuf = A_NETBUF_ALLOC(size); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, size); - - sc = (WMI_START_SCAN_CMD *)(A_NETBUF_DATA(osbuf)); - sc->scanType = scanType; - sc->forceFgScan = forceFgScan; - sc->isLegacy = isLegacy; - sc->homeDwellTime = homeDwellTime; - sc->forceScanInterval = forceScanInterval; - sc->numChannels = numChan; - if (numChan) { - memcpy(sc->channelList, channelList, numChan * sizeof(u16)); - } - - return (wmi_cmd_send(wmip, osbuf, WMI_START_SCAN_CMDID, NO_SYNC_WMIFLAG)); -} - -int -wmi_scanparams_cmd(struct wmi_t *wmip, u16 fg_start_sec, - u16 fg_end_sec, u16 bg_sec, - u16 minact_chdw_msec, u16 maxact_chdw_msec, - u16 pas_chdw_msec, - u8 shScanRatio, u8 scanCtrlFlags, - u32 max_dfsch_act_time, u16 maxact_scan_per_ssid) -{ - void *osbuf; - WMI_SCAN_PARAMS_CMD *sc; - - osbuf = A_NETBUF_ALLOC(sizeof(*sc)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*sc)); - - sc = (WMI_SCAN_PARAMS_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(sc, sizeof(*sc)); - sc->fg_start_period = fg_start_sec; - sc->fg_end_period = fg_end_sec; - sc->bg_period = bg_sec; - sc->minact_chdwell_time = minact_chdw_msec; - sc->maxact_chdwell_time = maxact_chdw_msec; - sc->pas_chdwell_time = pas_chdw_msec; - sc->shortScanRatio = shScanRatio; - sc->scanCtrlFlags = scanCtrlFlags; - sc->max_dfsch_act_time = max_dfsch_act_time; - sc->maxact_scan_per_ssid = maxact_scan_per_ssid; - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_SCAN_PARAMS_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_bssfilter_cmd(struct wmi_t *wmip, u8 filter, u32 ieMask) -{ - void *osbuf; - WMI_BSS_FILTER_CMD *cmd; - - if (filter >= LAST_BSS_FILTER) { - return A_EINVAL; - } - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_BSS_FILTER_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - cmd->bssFilter = filter; - cmd->ieMask = ieMask; - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_BSS_FILTER_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_probedSsid_cmd(struct wmi_t *wmip, u8 index, u8 flag, - u8 ssidLength, u8 *ssid) -{ - void *osbuf; - WMI_PROBED_SSID_CMD *cmd; - - if (index > MAX_PROBED_SSID_INDEX) { - return A_EINVAL; - } - if (ssidLength > sizeof(cmd->ssid)) { - return A_EINVAL; - } - if ((flag & (DISABLE_SSID_FLAG | ANY_SSID_FLAG)) && (ssidLength > 0)) { - return A_EINVAL; - } - if ((flag & SPECIFIC_SSID_FLAG) && !ssidLength) { - return A_EINVAL; - } - - if (flag & SPECIFIC_SSID_FLAG) { - is_probe_ssid = true; - } - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_PROBED_SSID_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - cmd->entryIndex = index; - cmd->flag = flag; - cmd->ssidLength = ssidLength; - memcpy(cmd->ssid, ssid, ssidLength); - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_PROBED_SSID_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_listeninterval_cmd(struct wmi_t *wmip, u16 listenInterval, u16 listenBeacons) -{ - void *osbuf; - WMI_LISTEN_INT_CMD *cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_LISTEN_INT_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - cmd->listenInterval = listenInterval; - cmd->numBeacons = listenBeacons; - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_LISTEN_INT_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_bmisstime_cmd(struct wmi_t *wmip, u16 bmissTime, u16 bmissBeacons) -{ - void *osbuf; - WMI_BMISS_TIME_CMD *cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_BMISS_TIME_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - cmd->bmissTime = bmissTime; - cmd->numBeacons = bmissBeacons; - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_BMISS_TIME_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_associnfo_cmd(struct wmi_t *wmip, u8 ieType, - u8 ieLen, u8 *ieInfo) -{ - void *osbuf; - WMI_SET_ASSOC_INFO_CMD *cmd; - u16 cmdLen; - - cmdLen = sizeof(*cmd) + ieLen - 1; - osbuf = A_NETBUF_ALLOC(cmdLen); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, cmdLen); - - cmd = (WMI_SET_ASSOC_INFO_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, cmdLen); - cmd->ieType = ieType; - cmd->bufferSize = ieLen; - memcpy(cmd->assocInfo, ieInfo, ieLen); - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_ASSOC_INFO_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_powermode_cmd(struct wmi_t *wmip, u8 powerMode) -{ - void *osbuf; - WMI_POWER_MODE_CMD *cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_POWER_MODE_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - cmd->powerMode = powerMode; - wmip->wmi_powerMode = powerMode; - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWER_MODE_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_ibsspmcaps_cmd(struct wmi_t *wmip, u8 pmEnable, u8 ttl, - u16 atim_windows, u16 timeout_value) -{ - void *osbuf; - WMI_IBSS_PM_CAPS_CMD *cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_IBSS_PM_CAPS_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - cmd->power_saving = pmEnable; - cmd->ttl = ttl; - cmd->atim_windows = atim_windows; - cmd->timeout_value = timeout_value; - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_IBSS_PM_CAPS_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_apps_cmd(struct wmi_t *wmip, u8 psType, u32 idle_time, - u32 ps_period, u8 sleep_period) -{ - void *osbuf; - WMI_AP_PS_CMD *cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_AP_PS_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - cmd->psType = psType; - cmd->idle_time = idle_time; - cmd->ps_period = ps_period; - cmd->sleep_period = sleep_period; - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_AP_PS_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_pmparams_cmd(struct wmi_t *wmip, u16 idlePeriod, - u16 psPollNum, u16 dtimPolicy, - u16 tx_wakeup_policy, u16 num_tx_to_wakeup, - u16 ps_fail_event_policy) -{ - void *osbuf; - WMI_POWER_PARAMS_CMD *pm; - - osbuf = A_NETBUF_ALLOC(sizeof(*pm)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*pm)); - - pm = (WMI_POWER_PARAMS_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(pm, sizeof(*pm)); - pm->idle_period = idlePeriod; - pm->pspoll_number = psPollNum; - pm->dtim_policy = dtimPolicy; - pm->tx_wakeup_policy = tx_wakeup_policy; - pm->num_tx_to_wakeup = num_tx_to_wakeup; - pm->ps_fail_event_policy = ps_fail_event_policy; - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWER_PARAMS_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_disctimeout_cmd(struct wmi_t *wmip, u8 timeout) -{ - void *osbuf; - WMI_DISC_TIMEOUT_CMD *cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_DISC_TIMEOUT_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - cmd->disconnectTimeout = timeout; - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_DISC_TIMEOUT_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_addKey_cmd(struct wmi_t *wmip, u8 keyIndex, CRYPTO_TYPE keyType, - u8 keyUsage, u8 keyLength, u8 *keyRSC, - u8 *keyMaterial, u8 key_op_ctrl, u8 *macAddr, - WMI_SYNC_FLAG sync_flag) -{ - void *osbuf; - WMI_ADD_CIPHER_KEY_CMD *cmd; - - if ((keyIndex > WMI_MAX_KEY_INDEX) || (keyLength > WMI_MAX_KEY_LEN) || - (keyMaterial == NULL)) - { - return A_EINVAL; - } - - if ((WEP_CRYPT != keyType) && (NULL == keyRSC)) { - return A_EINVAL; - } - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_ADD_CIPHER_KEY_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - cmd->keyIndex = keyIndex; - cmd->keyType = keyType; - cmd->keyUsage = keyUsage; - cmd->keyLength = keyLength; - memcpy(cmd->key, keyMaterial, keyLength); -#ifdef WAPI_ENABLE - if (NULL != keyRSC && key_op_ctrl != KEY_OP_INIT_WAPIPN) { -#else - if (NULL != keyRSC) { -#endif // WAPI_ENABLE - memcpy(cmd->keyRSC, keyRSC, sizeof(cmd->keyRSC)); - } - cmd->key_op_ctrl = key_op_ctrl; - - if(macAddr) { - memcpy(cmd->key_macaddr,macAddr,IEEE80211_ADDR_LEN); - } - - return (wmi_cmd_send(wmip, osbuf, WMI_ADD_CIPHER_KEY_CMDID, sync_flag)); -} - -int -wmi_add_krk_cmd(struct wmi_t *wmip, u8 *krk) -{ - void *osbuf; - WMI_ADD_KRK_CMD *cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_ADD_KRK_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - memcpy(cmd->krk, krk, WMI_KRK_LEN); - - return (wmi_cmd_send(wmip, osbuf, WMI_ADD_KRK_CMDID, NO_SYNC_WMIFLAG)); -} - -int -wmi_delete_krk_cmd(struct wmi_t *wmip) -{ - return wmi_simple_cmd(wmip, WMI_DELETE_KRK_CMDID); -} - -int -wmi_deleteKey_cmd(struct wmi_t *wmip, u8 keyIndex) -{ - void *osbuf; - WMI_DELETE_CIPHER_KEY_CMD *cmd; - - if (keyIndex > WMI_MAX_KEY_INDEX) { - return A_EINVAL; - } - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_DELETE_CIPHER_KEY_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - cmd->keyIndex = keyIndex; - - return (wmi_cmd_send(wmip, osbuf, WMI_DELETE_CIPHER_KEY_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_setPmkid_cmd(struct wmi_t *wmip, u8 *bssid, u8 *pmkId, - bool set) -{ - void *osbuf; - WMI_SET_PMKID_CMD *cmd; - - if (bssid == NULL) { - return A_EINVAL; - } - - if ((set == true) && (pmkId == NULL)) { - return A_EINVAL; - } - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_SET_PMKID_CMD *)(A_NETBUF_DATA(osbuf)); - memcpy(cmd->bssid, bssid, sizeof(cmd->bssid)); - if (set == true) { - memcpy(cmd->pmkid, pmkId, sizeof(cmd->pmkid)); - cmd->enable = PMKID_ENABLE; - } else { - A_MEMZERO(cmd->pmkid, sizeof(cmd->pmkid)); - cmd->enable = PMKID_DISABLE; - } - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMKID_CMDID, NO_SYNC_WMIFLAG)); -} - -int -wmi_set_tkip_countermeasures_cmd(struct wmi_t *wmip, bool en) -{ - void *osbuf; - WMI_SET_TKIP_COUNTERMEASURES_CMD *cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_SET_TKIP_COUNTERMEASURES_CMD *)(A_NETBUF_DATA(osbuf)); - cmd->cm_en = (en == true)? WMI_TKIP_CM_ENABLE : WMI_TKIP_CM_DISABLE; - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_TKIP_COUNTERMEASURES_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_set_akmp_params_cmd(struct wmi_t *wmip, - WMI_SET_AKMP_PARAMS_CMD *akmpParams) -{ - void *osbuf; - WMI_SET_AKMP_PARAMS_CMD *cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - cmd = (WMI_SET_AKMP_PARAMS_CMD *)(A_NETBUF_DATA(osbuf)); - cmd->akmpInfo = akmpParams->akmpInfo; - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_AKMP_PARAMS_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_set_pmkid_list_cmd(struct wmi_t *wmip, - WMI_SET_PMKID_LIST_CMD *pmkInfo) -{ - void *osbuf; - WMI_SET_PMKID_LIST_CMD *cmd; - u16 cmdLen; - u8 i; - - cmdLen = sizeof(pmkInfo->numPMKID) + - pmkInfo->numPMKID * sizeof(WMI_PMKID); - - osbuf = A_NETBUF_ALLOC(cmdLen); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, cmdLen); - cmd = (WMI_SET_PMKID_LIST_CMD *)(A_NETBUF_DATA(osbuf)); - cmd->numPMKID = pmkInfo->numPMKID; - - for (i = 0; i < cmd->numPMKID; i++) { - memcpy(&cmd->pmkidList[i], &pmkInfo->pmkidList[i], - WMI_PMKID_LEN); - } - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMKID_LIST_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_get_pmkid_list_cmd(struct wmi_t *wmip) -{ - return wmi_simple_cmd(wmip, WMI_GET_PMKID_LIST_CMDID); -} - -int -wmi_dataSync_send(struct wmi_t *wmip, void *osbuf, HTC_ENDPOINT_ID eid) -{ - WMI_DATA_HDR *dtHdr; - - A_ASSERT( eid != wmip->wmi_endpoint_id); - A_ASSERT(osbuf != NULL); - - if (A_NETBUF_PUSH(osbuf, sizeof(WMI_DATA_HDR)) != 0) { - return A_NO_MEMORY; - } - - dtHdr = (WMI_DATA_HDR *)A_NETBUF_DATA(osbuf); - dtHdr->info = - (SYNC_MSGTYPE & WMI_DATA_HDR_MSG_TYPE_MASK) << WMI_DATA_HDR_MSG_TYPE_SHIFT; - - dtHdr->info3 = 0; - A_DPRINTF(DBG_WMI, (DBGFMT "Enter - eid %d\n", DBGARG, eid)); - - return (A_WMI_CONTROL_TX(wmip->wmi_devt, osbuf, eid)); -} - -typedef struct _WMI_DATA_SYNC_BUFS { - u8 trafficClass; - void *osbuf; -}WMI_DATA_SYNC_BUFS; - -static int -wmi_sync_point(struct wmi_t *wmip) -{ - void *cmd_osbuf; - WMI_SYNC_CMD *cmd; - WMI_DATA_SYNC_BUFS dataSyncBufs[WMM_NUM_AC]; - u8 i,numPriStreams=0; - int status = 0; - - A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); - - memset(dataSyncBufs,0,sizeof(dataSyncBufs)); - - /* lock out while we walk through the priority list and assemble our local array */ - LOCK_WMI(wmip); - - for (i=0; i < WMM_NUM_AC ; i++) { - if (wmip->wmi_fatPipeExists & (1 << i)) { - numPriStreams++; - dataSyncBufs[numPriStreams-1].trafficClass = i; - } - } - - UNLOCK_WMI(wmip); - - /* dataSyncBufs is now filled with entries (starting at index 0) containing valid streamIDs */ - - do { - /* - * We allocate all network buffers needed so we will be able to - * send all required frames. - */ - cmd_osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (cmd_osbuf == NULL) { - status = A_NO_MEMORY; - break; - } - - A_NETBUF_PUT(cmd_osbuf, sizeof(*cmd)); - - cmd = (WMI_SYNC_CMD *)(A_NETBUF_DATA(cmd_osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - - /* In the SYNC cmd sent on the control Ep, send a bitmap of the data - * eps on which the Data Sync will be sent - */ - cmd->dataSyncMap = wmip->wmi_fatPipeExists; - - for (i=0; i < numPriStreams ; i++) { - dataSyncBufs[i].osbuf = A_NETBUF_ALLOC(0); - if (dataSyncBufs[i].osbuf == NULL) { - status = A_NO_MEMORY; - break; - } - } //end for - - /* if Buffer allocation for any of the dataSync fails, then do not - * send the Synchronize cmd on the control ep - */ - if (status) { - break; - } - - /* - * Send sync cmd followed by sync data messages on all endpoints being - * used - */ - status = wmi_cmd_send(wmip, cmd_osbuf, WMI_SYNCHRONIZE_CMDID, - NO_SYNC_WMIFLAG); - - if (status) { - break; - } - /* cmd buffer sent, we no longer own it */ - cmd_osbuf = NULL; - - for(i=0; i < numPriStreams; i++) { - A_ASSERT(dataSyncBufs[i].osbuf != NULL); - status = wmi_dataSync_send(wmip, - dataSyncBufs[i].osbuf, - A_WMI_Ac2EndpointID(wmip->wmi_devt, - dataSyncBufs[i]. - trafficClass) - ); - - if (status) { - break; - } - /* we don't own this buffer anymore, NULL it out of the array so it - * won't get cleaned up */ - dataSyncBufs[i].osbuf = NULL; - } //end for - - } while(false); - - /* free up any resources left over (possibly due to an error) */ - - if (cmd_osbuf != NULL) { - A_NETBUF_FREE(cmd_osbuf); - } - - for (i = 0; i < numPriStreams; i++) { - if (dataSyncBufs[i].osbuf != NULL) { - A_NETBUF_FREE(dataSyncBufs[i].osbuf); - } - } - - return (status); -} - -int -wmi_create_pstream_cmd(struct wmi_t *wmip, WMI_CREATE_PSTREAM_CMD *params) -{ - void *osbuf; - WMI_CREATE_PSTREAM_CMD *cmd; - u8 fatPipeExistsForAC=0; - s32 minimalPHY = 0; - s32 nominalPHY = 0; - - /* Validate all the parameters. */ - if( !((params->userPriority < 8) && - (params->userPriority <= 0x7) && - (convert_userPriority_to_trafficClass(params->userPriority) == params->trafficClass) && - (params->trafficDirection == UPLINK_TRAFFIC || - params->trafficDirection == DNLINK_TRAFFIC || - params->trafficDirection == BIDIR_TRAFFIC) && - (params->trafficType == TRAFFIC_TYPE_APERIODIC || - params->trafficType == TRAFFIC_TYPE_PERIODIC ) && - (params->voicePSCapability == DISABLE_FOR_THIS_AC || - params->voicePSCapability == ENABLE_FOR_THIS_AC || - params->voicePSCapability == ENABLE_FOR_ALL_AC) && - (params->tsid == WMI_IMPLICIT_PSTREAM || params->tsid <= WMI_MAX_THINSTREAM)) ) - { - return A_EINVAL; - } - - // - // check nominal PHY rate is >= minimalPHY, so that DUT - // can allow TSRS IE - // - - // get the physical rate - minimalPHY = ((params->minPhyRate / 1000)/1000); // unit of bps - - // check minimal phy < nominal phy rate - // - if (params->nominalPHY >= minimalPHY) - { - nominalPHY = (params->nominalPHY * 1000)/500; // unit of 500 kbps - A_DPRINTF(DBG_WMI, - (DBGFMT "TSRS IE Enabled::MinPhy %x->NominalPhy ===> %x\n", DBGARG, - minimalPHY, nominalPHY)); - - params->nominalPHY = nominalPHY; - } - else - { - params->nominalPHY = 0; - } - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - A_DPRINTF(DBG_WMI, - (DBGFMT "Sending create_pstream_cmd: ac=%d tsid:%d\n", DBGARG, - params->trafficClass, params->tsid)); - - cmd = (WMI_CREATE_PSTREAM_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - memcpy(cmd, params, sizeof(*cmd)); - - /* this is an implicitly created Fat pipe */ - if ((u32)params->tsid == (u32)WMI_IMPLICIT_PSTREAM) { - LOCK_WMI(wmip); - fatPipeExistsForAC = (wmip->wmi_fatPipeExists & (1 << params->trafficClass)); - wmip->wmi_fatPipeExists |= (1<<params->trafficClass); - UNLOCK_WMI(wmip); - } else { - /* this is an explicitly created thin stream within a fat pipe */ - LOCK_WMI(wmip); - fatPipeExistsForAC = (wmip->wmi_fatPipeExists & (1 << params->trafficClass)); - wmip->wmi_streamExistsForAC[params->trafficClass] |= (1<<params->tsid); - /* if a thinstream becomes active, the fat pipe automatically - * becomes active - */ - wmip->wmi_fatPipeExists |= (1<<params->trafficClass); - UNLOCK_WMI(wmip); - } - - /* Indicate activty change to driver layer only if this is the - * first TSID to get created in this AC explicitly or an implicit - * fat pipe is getting created. - */ - if (!fatPipeExistsForAC) { - A_WMI_STREAM_TX_ACTIVE(wmip->wmi_devt, params->trafficClass); - } - - /* mike: should be SYNC_BEFORE_WMIFLAG */ - return (wmi_cmd_send(wmip, osbuf, WMI_CREATE_PSTREAM_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_delete_pstream_cmd(struct wmi_t *wmip, u8 trafficClass, u8 tsid) -{ - void *osbuf; - WMI_DELETE_PSTREAM_CMD *cmd; - int status; - u16 activeTsids=0; - - /* validate the parameters */ - if (trafficClass > 3) { - A_DPRINTF(DBG_WMI, (DBGFMT "Invalid trafficClass: %d\n", DBGARG, trafficClass)); - return A_EINVAL; - } - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_DELETE_PSTREAM_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - - cmd->trafficClass = trafficClass; - cmd->tsid = tsid; - - LOCK_WMI(wmip); - activeTsids = wmip->wmi_streamExistsForAC[trafficClass]; - UNLOCK_WMI(wmip); - - /* Check if the tsid was created & exists */ - if (!(activeTsids & (1<<tsid))) { - - A_NETBUF_FREE(osbuf); - A_DPRINTF(DBG_WMI, - (DBGFMT "TSID %d does'nt exist for trafficClass: %d\n", DBGARG, tsid, trafficClass)); - /* TODO: return a more appropriate err code */ - return A_ERROR; - } - - A_DPRINTF(DBG_WMI, - (DBGFMT "Sending delete_pstream_cmd: trafficClass: %d tsid=%d\n", DBGARG, trafficClass, tsid)); - - status = (wmi_cmd_send(wmip, osbuf, WMI_DELETE_PSTREAM_CMDID, - SYNC_BEFORE_WMIFLAG)); - - LOCK_WMI(wmip); - wmip->wmi_streamExistsForAC[trafficClass] &= ~(1<<tsid); - activeTsids = wmip->wmi_streamExistsForAC[trafficClass]; - UNLOCK_WMI(wmip); - - - /* Indicate stream inactivity to driver layer only if all tsids - * within this AC are deleted. - */ - if(!activeTsids) { - A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt, trafficClass); - wmip->wmi_fatPipeExists &= ~(1<<trafficClass); - } - - return status; -} - -int -wmi_set_framerate_cmd(struct wmi_t *wmip, u8 bEnable, u8 type, u8 subType, u16 rateMask) -{ - void *osbuf; - WMI_FRAME_RATES_CMD *cmd; - u8 frameType; - - A_DPRINTF(DBG_WMI, - (DBGFMT " type %02X, subType %02X, rateMask %04x\n", DBGARG, type, subType, rateMask)); - - if((type != IEEE80211_FRAME_TYPE_MGT && type != IEEE80211_FRAME_TYPE_CTL) || - (subType > 15)){ - - return A_EINVAL; - } - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_FRAME_RATES_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - - frameType = (u8)((subType << 4) | type); - - cmd->bEnableMask = bEnable; - cmd->frameType = frameType; - cmd->frameRateMask = rateMask; - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_FRAMERATES_CMDID, NO_SYNC_WMIFLAG)); -} - -/* - * used to set the bit rate. rate is in Kbps. If rate == -1 - * then auto selection is used. - */ -int -wmi_set_bitrate_cmd(struct wmi_t *wmip, s32 dataRate, s32 mgmtRate, s32 ctlRate) -{ - void *osbuf; - WMI_BIT_RATE_CMD *cmd; - s8 drix, mrix, crix, ret_val; - - if (dataRate != -1) { - ret_val = wmi_validate_bitrate(wmip, dataRate, &drix); - if(ret_val == A_EINVAL){ - return A_EINVAL; - } - } else { - drix = -1; - } - - if (mgmtRate != -1) { - ret_val = wmi_validate_bitrate(wmip, mgmtRate, &mrix); - if(ret_val == A_EINVAL){ - return A_EINVAL; - } - } else { - mrix = -1; - } - if (ctlRate != -1) { - ret_val = wmi_validate_bitrate(wmip, ctlRate, &crix); - if(ret_val == A_EINVAL){ - return A_EINVAL; - } - } else { - crix = -1; - } - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_BIT_RATE_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - - cmd->rateIndex = drix; - cmd->mgmtRateIndex = mrix; - cmd->ctlRateIndex = crix; - - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_BITRATE_CMDID, NO_SYNC_WMIFLAG)); -} - -int -wmi_get_bitrate_cmd(struct wmi_t *wmip) -{ - return wmi_simple_cmd(wmip, WMI_GET_BITRATE_CMDID); -} - -/* - * Returns true iff the given rate index is legal in the current PHY mode. - */ -bool -wmi_is_bitrate_index_valid(struct wmi_t *wmip, s32 rateIndex) -{ - WMI_PHY_MODE phyMode = (WMI_PHY_MODE) wmip->wmi_phyMode; - bool isValid = true; - switch(phyMode) { - case WMI_11A_MODE: - if (wmip->wmi_ht_allowed[A_BAND_5GHZ]){ - if ((rateIndex < MODE_A_SUPPORT_RATE_START) || (rateIndex > MODE_GHT20_SUPPORT_RATE_STOP)) { - isValid = false; - } - } else { - if ((rateIndex < MODE_A_SUPPORT_RATE_START) || (rateIndex > MODE_A_SUPPORT_RATE_STOP)) { - isValid = false; - } - } - break; - - case WMI_11B_MODE: - if ((rateIndex < MODE_B_SUPPORT_RATE_START) || (rateIndex > MODE_B_SUPPORT_RATE_STOP)) { - isValid = false; - } - break; - - case WMI_11GONLY_MODE: - if (wmip->wmi_ht_allowed[A_BAND_24GHZ]){ - if ((rateIndex < MODE_GONLY_SUPPORT_RATE_START) || (rateIndex > MODE_GHT20_SUPPORT_RATE_STOP)) { - isValid = false; - } - } else { - if ((rateIndex < MODE_GONLY_SUPPORT_RATE_START) || (rateIndex > MODE_GONLY_SUPPORT_RATE_STOP)) { - isValid = false; - } - } - break; - - case WMI_11G_MODE: - case WMI_11AG_MODE: - if (wmip->wmi_ht_allowed[A_BAND_24GHZ]){ - if ((rateIndex < MODE_G_SUPPORT_RATE_START) || (rateIndex > MODE_GHT20_SUPPORT_RATE_STOP)) { - isValid = false; - } - } else { - if ((rateIndex < MODE_G_SUPPORT_RATE_START) || (rateIndex > MODE_G_SUPPORT_RATE_STOP)) { - isValid = false; - } - } - break; - default: - A_ASSERT(false); - break; - } - - return isValid; -} - -s8 wmi_validate_bitrate(struct wmi_t *wmip, s32 rate, s8 *rate_idx) -{ - s8 i; - - for (i=0;;i++) - { - if (wmi_rateTable[(u32) i][0] == 0) { - return A_EINVAL; - } - if (wmi_rateTable[(u32) i][0] == rate) { - break; - } - } - - if(wmi_is_bitrate_index_valid(wmip, (s32) i) != true) { - return A_EINVAL; - } - - *rate_idx = i; - return 0; -} - -int -wmi_set_fixrates_cmd(struct wmi_t *wmip, u32 fixRatesMask) -{ - void *osbuf; - WMI_FIX_RATES_CMD *cmd; -#if 0 - s32 rateIndex; -/* This check does not work for AR6003 as the HT modes are enabled only when - * the STA is connected to a HT_BSS and is not based only on channel. It is - * safe to skip this check however because rate control will only use rates - * that are permitted by the valid rate mask and the fix rate mask. Meaning - * the fix rate mask is not sufficient by itself to cause an invalid rate - * to be used. */ - /* Make sure all rates in the mask are valid in the current PHY mode */ - for(rateIndex = 0; rateIndex < MAX_NUMBER_OF_SUPPORT_RATES; rateIndex++) { - if((1 << rateIndex) & (u32)fixRatesMask) { - if(wmi_is_bitrate_index_valid(wmip, rateIndex) != true) { - A_DPRINTF(DBG_WMI, (DBGFMT "Set Fix Rates command failed: Given rate is illegal in current PHY mode\n", DBGARG)); - return A_EINVAL; - } - } - } -#endif - - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_FIX_RATES_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - - cmd->fixRateMask = fixRatesMask; - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_FIXRATES_CMDID, NO_SYNC_WMIFLAG)); -} - -int -wmi_get_ratemask_cmd(struct wmi_t *wmip) -{ - return wmi_simple_cmd(wmip, WMI_GET_FIXRATES_CMDID); -} - -int -wmi_get_channelList_cmd(struct wmi_t *wmip) -{ - return wmi_simple_cmd(wmip, WMI_GET_CHANNEL_LIST_CMDID); -} - -/* - * used to generate a wmi sey channel Parameters cmd. - * mode should always be specified and corresponds to the phy mode of the - * wlan. - * numChan should alway sbe specified. If zero indicates that all available - * channels should be used. - * channelList is an array of channel frequencies (in Mhz) which the radio - * should limit its operation to. It should be NULL if numChan == 0. Size of - * array should correspond to numChan entries. - */ -int -wmi_set_channelParams_cmd(struct wmi_t *wmip, u8 scanParam, - WMI_PHY_MODE mode, s8 numChan, - u16 *channelList) -{ - void *osbuf; - WMI_CHANNEL_PARAMS_CMD *cmd; - s8 size; - - size = sizeof (*cmd); - - if (numChan) { - if (numChan > WMI_MAX_CHANNELS) { - return A_EINVAL; - } - size += sizeof(u16) * (numChan - 1); - } - - osbuf = A_NETBUF_ALLOC(size); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, size); - - cmd = (WMI_CHANNEL_PARAMS_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, size); - - wmip->wmi_phyMode = mode; - cmd->scanParam = scanParam; - cmd->phyMode = mode; - cmd->numChannels = numChan; - memcpy(cmd->channelList, channelList, numChan * sizeof(u16)); - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_CHANNEL_PARAMS_CMDID, - NO_SYNC_WMIFLAG)); -} - -void -wmi_cache_configure_rssithreshold(struct wmi_t *wmip, WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd) -{ - SQ_THRESHOLD_PARAMS *sq_thresh = - &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_RSSI]; - /* - * Parse the command and store the threshold values here. The checks - * for valid values can be put here - */ - sq_thresh->weight = rssiCmd->weight; - sq_thresh->polling_interval = rssiCmd->pollTime; - - sq_thresh->upper_threshold[0] = rssiCmd->thresholdAbove1_Val - SIGNAL_QUALITY_NOISE_FLOOR; - sq_thresh->upper_threshold[1] = rssiCmd->thresholdAbove2_Val - SIGNAL_QUALITY_NOISE_FLOOR; - sq_thresh->upper_threshold[2] = rssiCmd->thresholdAbove3_Val - SIGNAL_QUALITY_NOISE_FLOOR; - sq_thresh->upper_threshold[3] = rssiCmd->thresholdAbove4_Val - SIGNAL_QUALITY_NOISE_FLOOR; - sq_thresh->upper_threshold[4] = rssiCmd->thresholdAbove5_Val - SIGNAL_QUALITY_NOISE_FLOOR; - sq_thresh->upper_threshold[5] = rssiCmd->thresholdAbove6_Val - SIGNAL_QUALITY_NOISE_FLOOR; - sq_thresh->upper_threshold_valid_count = 6; - - /* List sorted in descending order */ - sq_thresh->lower_threshold[0] = rssiCmd->thresholdBelow6_Val - SIGNAL_QUALITY_NOISE_FLOOR; - sq_thresh->lower_threshold[1] = rssiCmd->thresholdBelow5_Val - SIGNAL_QUALITY_NOISE_FLOOR; - sq_thresh->lower_threshold[2] = rssiCmd->thresholdBelow4_Val - SIGNAL_QUALITY_NOISE_FLOOR; - sq_thresh->lower_threshold[3] = rssiCmd->thresholdBelow3_Val - SIGNAL_QUALITY_NOISE_FLOOR; - sq_thresh->lower_threshold[4] = rssiCmd->thresholdBelow2_Val - SIGNAL_QUALITY_NOISE_FLOOR; - sq_thresh->lower_threshold[5] = rssiCmd->thresholdBelow1_Val - SIGNAL_QUALITY_NOISE_FLOOR; - sq_thresh->lower_threshold_valid_count = 6; - - if (!rssi_event_value) { - /* - * Configuring the thresholds to their extremes allows the host to get an - * event from the target which is used for the configuring the correct - * thresholds - */ - rssiCmd->thresholdAbove1_Val = sq_thresh->upper_threshold[0]; - rssiCmd->thresholdBelow1_Val = sq_thresh->lower_threshold[0]; - } else { - /* - * In case the user issues multiple times of rssi_threshold_setting, - * we should not use the extreames anymore, the target does not expect that. - */ - rssiCmd->thresholdAbove1_Val = ar6000_get_upper_threshold(rssi_event_value, sq_thresh, - sq_thresh->upper_threshold_valid_count); - rssiCmd->thresholdBelow1_Val = ar6000_get_lower_threshold(rssi_event_value, sq_thresh, - sq_thresh->lower_threshold_valid_count); -} -} - -int -wmi_set_rssi_threshold_params(struct wmi_t *wmip, - WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd) -{ - - /* Check these values are in ascending order */ - if( rssiCmd->thresholdAbove6_Val <= rssiCmd->thresholdAbove5_Val || - rssiCmd->thresholdAbove5_Val <= rssiCmd->thresholdAbove4_Val || - rssiCmd->thresholdAbove4_Val <= rssiCmd->thresholdAbove3_Val || - rssiCmd->thresholdAbove3_Val <= rssiCmd->thresholdAbove2_Val || - rssiCmd->thresholdAbove2_Val <= rssiCmd->thresholdAbove1_Val || - rssiCmd->thresholdBelow6_Val <= rssiCmd->thresholdBelow5_Val || - rssiCmd->thresholdBelow5_Val <= rssiCmd->thresholdBelow4_Val || - rssiCmd->thresholdBelow4_Val <= rssiCmd->thresholdBelow3_Val || - rssiCmd->thresholdBelow3_Val <= rssiCmd->thresholdBelow2_Val || - rssiCmd->thresholdBelow2_Val <= rssiCmd->thresholdBelow1_Val) - { - return A_EINVAL; - } - - wmi_cache_configure_rssithreshold(wmip, rssiCmd); - - return (wmi_send_rssi_threshold_params(wmip, rssiCmd)); -} - -int -wmi_set_ip_cmd(struct wmi_t *wmip, WMI_SET_IP_CMD *ipCmd) -{ - void *osbuf; - WMI_SET_IP_CMD *cmd; - - /* Multicast address are not valid */ - if((*((u8 *)&ipCmd->ips[0]) >= 0xE0) || - (*((u8 *)&ipCmd->ips[1]) >= 0xE0)) { - return A_EINVAL; - } - - osbuf = A_NETBUF_ALLOC(sizeof(WMI_SET_IP_CMD)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(WMI_SET_IP_CMD)); - cmd = (WMI_SET_IP_CMD *)(A_NETBUF_DATA(osbuf)); - memcpy(cmd, ipCmd, sizeof(WMI_SET_IP_CMD)); - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_IP_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_set_host_sleep_mode_cmd(struct wmi_t *wmip, - WMI_SET_HOST_SLEEP_MODE_CMD *hostModeCmd) -{ - void *osbuf; - s8 size; - WMI_SET_HOST_SLEEP_MODE_CMD *cmd; - u16 activeTsids=0; - u8 streamExists=0; - u8 i; - - if( hostModeCmd->awake == hostModeCmd->asleep) { - return A_EINVAL; - } - - size = sizeof (*cmd); - - osbuf = A_NETBUF_ALLOC(size); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, size); - - cmd = (WMI_SET_HOST_SLEEP_MODE_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, size); - memcpy(cmd, hostModeCmd, sizeof(WMI_SET_HOST_SLEEP_MODE_CMD)); - - if(hostModeCmd->asleep) { - /* - * Relinquish credits from all implicitly created pstreams since when we - * go to sleep. If user created explicit thinstreams exists with in a - * fatpipe leave them intact for the user to delete - */ - LOCK_WMI(wmip); - streamExists = wmip->wmi_fatPipeExists; - UNLOCK_WMI(wmip); - - for(i=0;i< WMM_NUM_AC;i++) { - if (streamExists & (1<<i)) { - LOCK_WMI(wmip); - activeTsids = wmip->wmi_streamExistsForAC[i]; - UNLOCK_WMI(wmip); - /* If there are no user created thin streams delete the fatpipe */ - if(!activeTsids) { - streamExists &= ~(1<<i); - /*Indicate inactivity to drv layer for this fatpipe(pstream)*/ - A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt,i); - } - } - } - - /* Update the fatpipes that exists*/ - LOCK_WMI(wmip); - wmip->wmi_fatPipeExists = streamExists; - UNLOCK_WMI(wmip); - } - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_HOST_SLEEP_MODE_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_set_wow_mode_cmd(struct wmi_t *wmip, - WMI_SET_WOW_MODE_CMD *wowModeCmd) -{ - void *osbuf; - s8 size; - WMI_SET_WOW_MODE_CMD *cmd; - - size = sizeof (*cmd); - - osbuf = A_NETBUF_ALLOC(size); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, size); - - cmd = (WMI_SET_WOW_MODE_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, size); - memcpy(cmd, wowModeCmd, sizeof(WMI_SET_WOW_MODE_CMD)); - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_WOW_MODE_CMDID, - NO_SYNC_WMIFLAG)); - -} - -int -wmi_get_wow_list_cmd(struct wmi_t *wmip, - WMI_GET_WOW_LIST_CMD *wowListCmd) -{ - void *osbuf; - s8 size; - WMI_GET_WOW_LIST_CMD *cmd; - - size = sizeof (*cmd); - - osbuf = A_NETBUF_ALLOC(size); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, size); - - cmd = (WMI_GET_WOW_LIST_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, size); - memcpy(cmd, wowListCmd, sizeof(WMI_GET_WOW_LIST_CMD)); - - return (wmi_cmd_send(wmip, osbuf, WMI_GET_WOW_LIST_CMDID, - NO_SYNC_WMIFLAG)); - -} - -static int -wmi_get_wow_list_event_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - WMI_GET_WOW_LIST_REPLY *reply; - - if (len < sizeof(WMI_GET_WOW_LIST_REPLY)) { - return A_EINVAL; - } - reply = (WMI_GET_WOW_LIST_REPLY *)datap; - - A_WMI_WOW_LIST_EVENT(wmip->wmi_devt, reply->num_filters, - reply); - - return 0; -} - -int wmi_add_wow_pattern_cmd(struct wmi_t *wmip, - WMI_ADD_WOW_PATTERN_CMD *addWowCmd, - u8 *pattern, u8 *mask, - u8 pattern_size) -{ - void *osbuf; - s8 size; - WMI_ADD_WOW_PATTERN_CMD *cmd; - u8 *filter_mask = NULL; - - size = sizeof (*cmd); - - size += ((2 * addWowCmd->filter_size)* sizeof(u8)); - osbuf = A_NETBUF_ALLOC(size); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, size); - - cmd = (WMI_ADD_WOW_PATTERN_CMD *)(A_NETBUF_DATA(osbuf)); - cmd->filter_list_id = addWowCmd->filter_list_id; - cmd->filter_offset = addWowCmd->filter_offset; - cmd->filter_size = addWowCmd->filter_size; - - memcpy(cmd->filter, pattern, addWowCmd->filter_size); - - filter_mask = (u8 *)(cmd->filter + cmd->filter_size); - memcpy(filter_mask, mask, addWowCmd->filter_size); - - - return (wmi_cmd_send(wmip, osbuf, WMI_ADD_WOW_PATTERN_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_del_wow_pattern_cmd(struct wmi_t *wmip, - WMI_DEL_WOW_PATTERN_CMD *delWowCmd) -{ - void *osbuf; - s8 size; - WMI_DEL_WOW_PATTERN_CMD *cmd; - - size = sizeof (*cmd); - - osbuf = A_NETBUF_ALLOC(size); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, size); - - cmd = (WMI_DEL_WOW_PATTERN_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, size); - memcpy(cmd, delWowCmd, sizeof(WMI_DEL_WOW_PATTERN_CMD)); - - return (wmi_cmd_send(wmip, osbuf, WMI_DEL_WOW_PATTERN_CMDID, - NO_SYNC_WMIFLAG)); - -} - -void -wmi_cache_configure_snrthreshold(struct wmi_t *wmip, WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd) -{ - SQ_THRESHOLD_PARAMS *sq_thresh = - &wmip->wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_SNR]; - /* - * Parse the command and store the threshold values here. The checks - * for valid values can be put here - */ - sq_thresh->weight = snrCmd->weight; - sq_thresh->polling_interval = snrCmd->pollTime; - - sq_thresh->upper_threshold[0] = snrCmd->thresholdAbove1_Val; - sq_thresh->upper_threshold[1] = snrCmd->thresholdAbove2_Val; - sq_thresh->upper_threshold[2] = snrCmd->thresholdAbove3_Val; - sq_thresh->upper_threshold[3] = snrCmd->thresholdAbove4_Val; - sq_thresh->upper_threshold_valid_count = 4; - - /* List sorted in descending order */ - sq_thresh->lower_threshold[0] = snrCmd->thresholdBelow4_Val; - sq_thresh->lower_threshold[1] = snrCmd->thresholdBelow3_Val; - sq_thresh->lower_threshold[2] = snrCmd->thresholdBelow2_Val; - sq_thresh->lower_threshold[3] = snrCmd->thresholdBelow1_Val; - sq_thresh->lower_threshold_valid_count = 4; - - if (!snr_event_value) { - /* - * Configuring the thresholds to their extremes allows the host to get an - * event from the target which is used for the configuring the correct - * thresholds - */ - snrCmd->thresholdAbove1_Val = (u8)sq_thresh->upper_threshold[0]; - snrCmd->thresholdBelow1_Val = (u8)sq_thresh->lower_threshold[0]; - } else { - /* - * In case the user issues multiple times of snr_threshold_setting, - * we should not use the extreames anymore, the target does not expect that. - */ - snrCmd->thresholdAbove1_Val = ar6000_get_upper_threshold(snr_event_value, sq_thresh, - sq_thresh->upper_threshold_valid_count); - snrCmd->thresholdBelow1_Val = ar6000_get_lower_threshold(snr_event_value, sq_thresh, - sq_thresh->lower_threshold_valid_count); - } - -} -int -wmi_set_snr_threshold_params(struct wmi_t *wmip, - WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd) -{ - if( snrCmd->thresholdAbove4_Val <= snrCmd->thresholdAbove3_Val || - snrCmd->thresholdAbove3_Val <= snrCmd->thresholdAbove2_Val || - snrCmd->thresholdAbove2_Val <= snrCmd->thresholdAbove1_Val || - snrCmd->thresholdBelow4_Val <= snrCmd->thresholdBelow3_Val || - snrCmd->thresholdBelow3_Val <= snrCmd->thresholdBelow2_Val || - snrCmd->thresholdBelow2_Val <= snrCmd->thresholdBelow1_Val) - { - return A_EINVAL; - } - wmi_cache_configure_snrthreshold(wmip, snrCmd); - return (wmi_send_snr_threshold_params(wmip, snrCmd)); -} - -int -wmi_clr_rssi_snr(struct wmi_t *wmip) -{ - void *osbuf; - - osbuf = A_NETBUF_ALLOC(sizeof(int)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - return (wmi_cmd_send(wmip, osbuf, WMI_CLR_RSSI_SNR_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_set_lq_threshold_params(struct wmi_t *wmip, - WMI_LQ_THRESHOLD_PARAMS_CMD *lqCmd) -{ - void *osbuf; - s8 size; - WMI_LQ_THRESHOLD_PARAMS_CMD *cmd; - /* These values are in ascending order */ - if( lqCmd->thresholdAbove4_Val <= lqCmd->thresholdAbove3_Val || - lqCmd->thresholdAbove3_Val <= lqCmd->thresholdAbove2_Val || - lqCmd->thresholdAbove2_Val <= lqCmd->thresholdAbove1_Val || - lqCmd->thresholdBelow4_Val <= lqCmd->thresholdBelow3_Val || - lqCmd->thresholdBelow3_Val <= lqCmd->thresholdBelow2_Val || - lqCmd->thresholdBelow2_Val <= lqCmd->thresholdBelow1_Val ) { - - return A_EINVAL; - } - - size = sizeof (*cmd); - - osbuf = A_NETBUF_ALLOC(size); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, size); - - cmd = (WMI_LQ_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, size); - memcpy(cmd, lqCmd, sizeof(WMI_LQ_THRESHOLD_PARAMS_CMD)); - - return (wmi_cmd_send(wmip, osbuf, WMI_LQ_THRESHOLD_PARAMS_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_set_error_report_bitmask(struct wmi_t *wmip, u32 mask) -{ - void *osbuf; - s8 size; - WMI_TARGET_ERROR_REPORT_BITMASK *cmd; - - size = sizeof (*cmd); - - osbuf = A_NETBUF_ALLOC(size); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, size); - - cmd = (WMI_TARGET_ERROR_REPORT_BITMASK *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, size); - - cmd->bitmask = mask; - - return (wmi_cmd_send(wmip, osbuf, WMI_TARGET_ERROR_REPORT_BITMASK_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_get_challenge_resp_cmd(struct wmi_t *wmip, u32 cookie, u32 source) -{ - void *osbuf; - WMIX_HB_CHALLENGE_RESP_CMD *cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMIX_HB_CHALLENGE_RESP_CMD *)(A_NETBUF_DATA(osbuf)); - cmd->cookie = cookie; - cmd->source = source; - - return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_HB_CHALLENGE_RESP_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_config_debug_module_cmd(struct wmi_t *wmip, u16 mmask, - u16 tsr, bool rep, u16 size, - u32 valid) -{ - void *osbuf; - WMIX_DBGLOG_CFG_MODULE_CMD *cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMIX_DBGLOG_CFG_MODULE_CMD *)(A_NETBUF_DATA(osbuf)); - cmd->config.cfgmmask = mmask; - cmd->config.cfgtsr = tsr; - cmd->config.cfgrep = rep; - cmd->config.cfgsize = size; - cmd->config.cfgvalid = valid; - - return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DBGLOG_CFG_MODULE_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_get_stats_cmd(struct wmi_t *wmip) -{ - return wmi_simple_cmd(wmip, WMI_GET_STATISTICS_CMDID); -} - -int -wmi_addBadAp_cmd(struct wmi_t *wmip, u8 apIndex, u8 *bssid) -{ - void *osbuf; - WMI_ADD_BAD_AP_CMD *cmd; - - if ((bssid == NULL) || (apIndex > WMI_MAX_BAD_AP_INDEX)) { - return A_EINVAL; - } - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_ADD_BAD_AP_CMD *)(A_NETBUF_DATA(osbuf)); - cmd->badApIndex = apIndex; - memcpy(cmd->bssid, bssid, sizeof(cmd->bssid)); - - return (wmi_cmd_send(wmip, osbuf, WMI_ADD_BAD_AP_CMDID, SYNC_BEFORE_WMIFLAG)); -} - -int -wmi_deleteBadAp_cmd(struct wmi_t *wmip, u8 apIndex) -{ - void *osbuf; - WMI_DELETE_BAD_AP_CMD *cmd; - - if (apIndex > WMI_MAX_BAD_AP_INDEX) { - return A_EINVAL; - } - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_DELETE_BAD_AP_CMD *)(A_NETBUF_DATA(osbuf)); - cmd->badApIndex = apIndex; - - return (wmi_cmd_send(wmip, osbuf, WMI_DELETE_BAD_AP_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_abort_scan_cmd(struct wmi_t *wmip) -{ - return wmi_simple_cmd(wmip, WMI_ABORT_SCAN_CMDID); -} - -int -wmi_set_txPwr_cmd(struct wmi_t *wmip, u8 dbM) -{ - void *osbuf; - WMI_SET_TX_PWR_CMD *cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_SET_TX_PWR_CMD *)(A_NETBUF_DATA(osbuf)); - cmd->dbM = dbM; - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_TX_PWR_CMDID, NO_SYNC_WMIFLAG)); -} - -int -wmi_get_txPwr_cmd(struct wmi_t *wmip) -{ - return wmi_simple_cmd(wmip, WMI_GET_TX_PWR_CMDID); -} - -u16 wmi_get_mapped_qos_queue(struct wmi_t *wmip, u8 trafficClass) -{ - u16 activeTsids=0; - - LOCK_WMI(wmip); - activeTsids = wmip->wmi_streamExistsForAC[trafficClass]; - UNLOCK_WMI(wmip); - - return activeTsids; -} - -int -wmi_get_roam_tbl_cmd(struct wmi_t *wmip) -{ - return wmi_simple_cmd(wmip, WMI_GET_ROAM_TBL_CMDID); -} - -int -wmi_get_roam_data_cmd(struct wmi_t *wmip, u8 roamDataType) -{ - void *osbuf; - u32 size = sizeof(u8); - WMI_TARGET_ROAM_DATA *cmd; - - osbuf = A_NETBUF_ALLOC(size); /* no payload */ - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, size); - - cmd = (WMI_TARGET_ROAM_DATA *)(A_NETBUF_DATA(osbuf)); - cmd->roamDataType = roamDataType; - - return (wmi_cmd_send(wmip, osbuf, WMI_GET_ROAM_DATA_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_set_roam_ctrl_cmd(struct wmi_t *wmip, WMI_SET_ROAM_CTRL_CMD *p, - u8 size) -{ - void *osbuf; - WMI_SET_ROAM_CTRL_CMD *cmd; - - osbuf = A_NETBUF_ALLOC(size); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, size); - - cmd = (WMI_SET_ROAM_CTRL_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, size); - - memcpy(cmd, p, size); - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_ROAM_CTRL_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_set_powersave_timers_cmd(struct wmi_t *wmip, - WMI_POWERSAVE_TIMERS_POLICY_CMD *pCmd, - u8 size) -{ - void *osbuf; - WMI_POWERSAVE_TIMERS_POLICY_CMD *cmd; - - /* These timers can't be zero */ - if(!pCmd->psPollTimeout || !pCmd->triggerTimeout || - !(pCmd->apsdTimPolicy == IGNORE_TIM_ALL_QUEUES_APSD || - pCmd->apsdTimPolicy == PROCESS_TIM_ALL_QUEUES_APSD) || - !(pCmd->simulatedAPSDTimPolicy == IGNORE_TIM_SIMULATED_APSD || - pCmd->simulatedAPSDTimPolicy == PROCESS_TIM_SIMULATED_APSD)) - return A_EINVAL; - - osbuf = A_NETBUF_ALLOC(size); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, size); - - cmd = (WMI_POWERSAVE_TIMERS_POLICY_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, size); - - memcpy(cmd, pCmd, size); - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_POWERSAVE_TIMERS_POLICY_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_set_access_params_cmd(struct wmi_t *wmip, u8 ac, u16 txop, u8 eCWmin, - u8 eCWmax, u8 aifsn) -{ - void *osbuf; - WMI_SET_ACCESS_PARAMS_CMD *cmd; - - if ((eCWmin > WMI_MAX_CW_ACPARAM) || (eCWmax > WMI_MAX_CW_ACPARAM) || - (aifsn > WMI_MAX_AIFSN_ACPARAM) || (ac >= WMM_NUM_AC)) - { - return A_EINVAL; - } - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_SET_ACCESS_PARAMS_CMD *)(A_NETBUF_DATA(osbuf)); - cmd->txop = txop; - cmd->eCWmin = eCWmin; - cmd->eCWmax = eCWmax; - cmd->aifsn = aifsn; - cmd->ac = ac; - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_ACCESS_PARAMS_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_set_retry_limits_cmd(struct wmi_t *wmip, u8 frameType, - u8 trafficClass, u8 maxRetries, - u8 enableNotify) -{ - void *osbuf; - WMI_SET_RETRY_LIMITS_CMD *cmd; - - if ((frameType != MGMT_FRAMETYPE) && (frameType != CONTROL_FRAMETYPE) && - (frameType != DATA_FRAMETYPE)) - { - return A_EINVAL; - } - - if (maxRetries > WMI_MAX_RETRIES) { - return A_EINVAL; - } - - if (frameType != DATA_FRAMETYPE) { - trafficClass = 0; - } - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_SET_RETRY_LIMITS_CMD *)(A_NETBUF_DATA(osbuf)); - cmd->frameType = frameType; - cmd->trafficClass = trafficClass; - cmd->maxRetries = maxRetries; - cmd->enableNotify = enableNotify; - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_RETRY_LIMITS_CMDID, - NO_SYNC_WMIFLAG)); -} - -void -wmi_get_current_bssid(struct wmi_t *wmip, u8 *bssid) -{ - if (bssid != NULL) { - memcpy(bssid, wmip->wmi_bssid, ATH_MAC_LEN); - } -} - -int -wmi_set_opt_mode_cmd(struct wmi_t *wmip, u8 optMode) -{ - void *osbuf; - WMI_SET_OPT_MODE_CMD *cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_SET_OPT_MODE_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - cmd->optMode = optMode; - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_OPT_MODE_CMDID, - SYNC_BOTH_WMIFLAG)); -} - -int -wmi_opt_tx_frame_cmd(struct wmi_t *wmip, - u8 frmType, - u8 *dstMacAddr, - u8 *bssid, - u16 optIEDataLen, - u8 *optIEData) -{ - void *osbuf; - WMI_OPT_TX_FRAME_CMD *cmd; - osbuf = A_NETBUF_ALLOC(optIEDataLen + sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, (optIEDataLen + sizeof(*cmd))); - - cmd = (WMI_OPT_TX_FRAME_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, (optIEDataLen + sizeof(*cmd)-1)); - - cmd->frmType = frmType; - cmd->optIEDataLen = optIEDataLen; - //cmd->optIEData = (u8 *)((int)cmd + sizeof(*cmd)); - memcpy(cmd->bssid, bssid, sizeof(cmd->bssid)); - memcpy(cmd->dstAddr, dstMacAddr, sizeof(cmd->dstAddr)); - memcpy(&cmd->optIEData[0], optIEData, optIEDataLen); - - return (wmi_cmd_send(wmip, osbuf, WMI_OPT_TX_FRAME_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_set_adhoc_bconIntvl_cmd(struct wmi_t *wmip, u16 intvl) -{ - void *osbuf; - WMI_BEACON_INT_CMD *cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_BEACON_INT_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - cmd->beaconInterval = intvl; - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_BEACON_INT_CMDID, - NO_SYNC_WMIFLAG)); -} - - -int -wmi_set_voice_pkt_size_cmd(struct wmi_t *wmip, u16 voicePktSize) -{ - void *osbuf; - WMI_SET_VOICE_PKT_SIZE_CMD *cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_SET_VOICE_PKT_SIZE_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - cmd->voicePktSize = voicePktSize; - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_VOICE_PKT_SIZE_CMDID, - NO_SYNC_WMIFLAG)); -} - - -int -wmi_set_max_sp_len_cmd(struct wmi_t *wmip, u8 maxSPLen) -{ - void *osbuf; - WMI_SET_MAX_SP_LEN_CMD *cmd; - - /* maxSPLen is a two-bit value. If user trys to set anything - * other than this, then its invalid - */ - if(maxSPLen & ~0x03) - return A_EINVAL; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_SET_MAX_SP_LEN_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - cmd->maxSPLen = maxSPLen; - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_MAX_SP_LEN_CMDID, - NO_SYNC_WMIFLAG)); -} - -u8 wmi_determine_userPriority( - u8 *pkt, - u32 layer2Pri) -{ - u8 ipPri; - iphdr *ipHdr = (iphdr *)pkt; - - /* Determine IPTOS priority */ - /* - * IP Tos format : - * (Refer Pg 57 WMM-test-plan-v1.2) - * IP-TOS - 8bits - * : DSCP(6-bits) ECN(2-bits) - * : DSCP - P2 P1 P0 X X X - * where (P2 P1 P0) form 802.1D - */ - ipPri = ipHdr->ip_tos >> 5; - ipPri &= 0x7; - - if ((layer2Pri & 0x7) > ipPri) - return ((u8)layer2Pri & 0x7); - else - return ipPri; -} - -u8 convert_userPriority_to_trafficClass(u8 userPriority) -{ - return (up_to_ac[userPriority & 0x7]); -} - -u8 wmi_get_power_mode_cmd(struct wmi_t *wmip) -{ - return wmip->wmi_powerMode; -} - -int -wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, int tspecCompliance) -{ - int ret = 0; - -#define TSPEC_SUSPENSION_INTERVAL_ATHEROS_DEF (~0) -#define TSPEC_SERVICE_START_TIME_ATHEROS_DEF 0 -#define TSPEC_MAX_BURST_SIZE_ATHEROS_DEF 0 -#define TSPEC_DELAY_BOUND_ATHEROS_DEF 0 -#define TSPEC_MEDIUM_TIME_ATHEROS_DEF 0 -#define TSPEC_SBA_ATHEROS_DEF 0x2000 /* factor is 1 */ - - /* Verify TSPEC params for ATHEROS compliance */ - if(tspecCompliance == ATHEROS_COMPLIANCE) { - if ((pCmd->suspensionInt != TSPEC_SUSPENSION_INTERVAL_ATHEROS_DEF) || - (pCmd->serviceStartTime != TSPEC_SERVICE_START_TIME_ATHEROS_DEF) || - (pCmd->minDataRate != pCmd->meanDataRate) || - (pCmd->minDataRate != pCmd->peakDataRate) || - (pCmd->maxBurstSize != TSPEC_MAX_BURST_SIZE_ATHEROS_DEF) || - (pCmd->delayBound != TSPEC_DELAY_BOUND_ATHEROS_DEF) || - (pCmd->sba != TSPEC_SBA_ATHEROS_DEF) || - (pCmd->mediumTime != TSPEC_MEDIUM_TIME_ATHEROS_DEF)) { - - A_DPRINTF(DBG_WMI, (DBGFMT "Invalid TSPEC params\n", DBGARG)); - //A_PRINTF("%s: Invalid TSPEC params\n", __func__); - ret = A_EINVAL; - } - } - - return ret; -} - -#ifdef CONFIG_HOST_TCMD_SUPPORT -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); - - return 0; -} - -#endif /* CONFIG_HOST_TCMD_SUPPORT*/ - -int -wmi_set_authmode_cmd(struct wmi_t *wmip, u8 mode) -{ - void *osbuf; - WMI_SET_AUTH_MODE_CMD *cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_SET_AUTH_MODE_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - cmd->mode = mode; - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_AUTH_MODE_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_set_reassocmode_cmd(struct wmi_t *wmip, u8 mode) -{ - void *osbuf; - WMI_SET_REASSOC_MODE_CMD *cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_SET_REASSOC_MODE_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - cmd->mode = mode; - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_REASSOC_MODE_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_set_lpreamble_cmd(struct wmi_t *wmip, u8 status, u8 preamblePolicy) -{ - void *osbuf; - WMI_SET_LPREAMBLE_CMD *cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_SET_LPREAMBLE_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - cmd->status = status; - cmd->preamblePolicy = preamblePolicy; - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_LPREAMBLE_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_set_rts_cmd(struct wmi_t *wmip, u16 threshold) -{ - void *osbuf; - WMI_SET_RTS_CMD *cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_SET_RTS_CMD*)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - cmd->threshold = threshold; - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_RTS_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_set_wmm_cmd(struct wmi_t *wmip, WMI_WMM_STATUS status) -{ - void *osbuf; - WMI_SET_WMM_CMD *cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_SET_WMM_CMD*)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - cmd->status = status; - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_WMM_CMDID, - NO_SYNC_WMIFLAG)); - -} - -int -wmi_set_qos_supp_cmd(struct wmi_t *wmip, u8 status) -{ - void *osbuf; - WMI_SET_QOS_SUPP_CMD *cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_SET_QOS_SUPP_CMD*)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - cmd->status = status; - return (wmi_cmd_send(wmip, osbuf, WMI_SET_QOS_SUPP_CMDID, - NO_SYNC_WMIFLAG)); -} - - -int -wmi_set_wmm_txop(struct wmi_t *wmip, WMI_TXOP_CFG cfg) -{ - void *osbuf; - WMI_SET_WMM_TXOP_CMD *cmd; - - if( !((cfg == WMI_TXOP_DISABLED) || (cfg == WMI_TXOP_ENABLED)) ) - return A_EINVAL; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_SET_WMM_TXOP_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - cmd->txopEnable = cfg; - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_WMM_TXOP_CMDID, - NO_SYNC_WMIFLAG)); - -} - -int -wmi_set_country(struct wmi_t *wmip, u8 *countryCode) -{ - void *osbuf; - WMI_AP_SET_COUNTRY_CMD *cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_AP_SET_COUNTRY_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - memcpy(cmd->countryCode,countryCode,3); - - return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_COUNTRY_CMDID, - NO_SYNC_WMIFLAG)); -} - -#ifdef CONFIG_HOST_TCMD_SUPPORT -/* WMI layer doesn't need to know the data type of the test cmd. - This would be beneficial for customers like Qualcomm, who might - have different test command requirements from different manufacturers - */ -int -wmi_test_cmd(struct wmi_t *wmip, u8 *buf, u32 len) -{ - void *osbuf; - char *data; - - A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); - - osbuf= A_NETBUF_ALLOC(len); - if(osbuf == NULL) - { - return A_NO_MEMORY; - } - A_NETBUF_PUT(osbuf, len); - data = A_NETBUF_DATA(osbuf); - memcpy(data, buf, len); - - return(wmi_cmd_send(wmip, osbuf, WMI_TEST_CMDID, - NO_SYNC_WMIFLAG)); -} - -#endif - -int -wmi_set_bt_status_cmd(struct wmi_t *wmip, u8 streamType, u8 status) -{ - void *osbuf; - WMI_SET_BT_STATUS_CMD *cmd; - - AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("Enter - streamType=%d, status=%d\n", streamType, status)); - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_SET_BT_STATUS_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - cmd->streamType = streamType; - cmd->status = status; - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_BT_STATUS_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_set_bt_params_cmd(struct wmi_t *wmip, WMI_SET_BT_PARAMS_CMD* cmd) -{ - void *osbuf; - WMI_SET_BT_PARAMS_CMD* alloc_cmd; - - AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("cmd params is %d\n", cmd->paramType)); - - if (cmd->paramType == BT_PARAM_SCO) { - AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("sco params %d %d %d %d %d %d %d %d %d %d %d %d\n", cmd->info.scoParams.numScoCyclesForceTrigger, - cmd->info.scoParams.dataResponseTimeout, - cmd->info.scoParams.stompScoRules, - cmd->info.scoParams.scoOptFlags, - cmd->info.scoParams.stompDutyCyleVal, - cmd->info.scoParams.stompDutyCyleMaxVal, - cmd->info.scoParams.psPollLatencyFraction, - cmd->info.scoParams.noSCOSlots, - cmd->info.scoParams.noIdleSlots, - cmd->info.scoParams.scoOptOffRssi, - cmd->info.scoParams.scoOptOnRssi, - cmd->info.scoParams.scoOptRtsCount)); - } - else if (cmd->paramType == BT_PARAM_A2DP) { - AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("A2DP params %d %d %d %d %d %d %d %d\n", cmd->info.a2dpParams.a2dpWlanUsageLimit, - cmd->info.a2dpParams.a2dpBurstCntMin, - cmd->info.a2dpParams.a2dpDataRespTimeout, - cmd->info.a2dpParams.a2dpOptFlags, - cmd->info.a2dpParams.isCoLocatedBtRoleMaster, - cmd->info.a2dpParams.a2dpOptOffRssi, - cmd->info.a2dpParams.a2dpOptOnRssi, - cmd->info.a2dpParams.a2dpOptRtsCount)); - } - else if (cmd->paramType == BT_PARAM_ANTENNA_CONFIG) { - AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("Ant config %d\n", cmd->info.antType)); - } - else if (cmd->paramType == BT_PARAM_COLOCATED_BT_DEVICE) { - AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("co-located BT %d\n", cmd->info.coLocatedBtDev)); - } - else if (cmd->paramType == BT_PARAM_ACLCOEX) { - AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("ACL params %d %d %d\n", cmd->info.aclCoexParams.aclWlanMediumUsageTime, - cmd->info.aclCoexParams.aclBtMediumUsageTime, - cmd->info.aclCoexParams.aclDataRespTimeout)); - } - else if (cmd->paramType == BT_PARAM_11A_SEPARATE_ANT) { - A_DPRINTF(DBG_WMI, (DBGFMT "11A ant\n", DBGARG)); - } - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - alloc_cmd = (WMI_SET_BT_PARAMS_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(alloc_cmd, sizeof(*cmd)); - memcpy(alloc_cmd, cmd, sizeof(*cmd)); - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_BT_PARAMS_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_set_btcoex_fe_ant_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_FE_ANT_CMD * cmd) -{ - void *osbuf; - WMI_SET_BTCOEX_FE_ANT_CMD *alloc_cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - alloc_cmd = (WMI_SET_BTCOEX_FE_ANT_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(alloc_cmd, sizeof(*cmd)); - memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_FE_ANT_CMD)); - return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_FE_ANT_CMDID, - NO_SYNC_WMIFLAG)); - -} - - -int -wmi_set_btcoex_colocated_bt_dev_cmd(struct wmi_t *wmip, - WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD * cmd) -{ - void *osbuf; - WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD *alloc_cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - alloc_cmd = (WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(alloc_cmd, sizeof(*cmd)); - memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD)); - A_PRINTF("colocated bt = %d\n", alloc_cmd->btcoexCoLocatedBTdev); - return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMDID, - NO_SYNC_WMIFLAG)); - -} - -int -wmi_set_btcoex_btinquiry_page_config_cmd(struct wmi_t *wmip, - WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD* cmd) -{ - void *osbuf; - WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD *alloc_cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - alloc_cmd = (WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(alloc_cmd, sizeof(*cmd)); - memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD)); - return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMDID, - NO_SYNC_WMIFLAG)); - -} - -int -wmi_set_btcoex_sco_config_cmd(struct wmi_t *wmip, - WMI_SET_BTCOEX_SCO_CONFIG_CMD * cmd) -{ - void *osbuf; - WMI_SET_BTCOEX_SCO_CONFIG_CMD *alloc_cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - alloc_cmd = (WMI_SET_BTCOEX_SCO_CONFIG_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(alloc_cmd, sizeof(*cmd)); - memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_SCO_CONFIG_CMD)); - return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_SCO_CONFIG_CMDID , - NO_SYNC_WMIFLAG)); - -} - -int -wmi_set_btcoex_a2dp_config_cmd(struct wmi_t *wmip, - WMI_SET_BTCOEX_A2DP_CONFIG_CMD * cmd) -{ - void *osbuf; - WMI_SET_BTCOEX_A2DP_CONFIG_CMD *alloc_cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - alloc_cmd = (WMI_SET_BTCOEX_A2DP_CONFIG_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(alloc_cmd, sizeof(*cmd)); - memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_A2DP_CONFIG_CMD)); - return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_A2DP_CONFIG_CMDID , - NO_SYNC_WMIFLAG)); - -} - -int -wmi_set_btcoex_aclcoex_config_cmd(struct wmi_t *wmip, - WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD * cmd) -{ - void *osbuf; - WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD *alloc_cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - alloc_cmd = (WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(alloc_cmd, sizeof(*cmd)); - memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD)); - return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMDID , - NO_SYNC_WMIFLAG)); - -} - -int -wmi_set_btcoex_debug_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_DEBUG_CMD * cmd) -{ - void *osbuf; - WMI_SET_BTCOEX_DEBUG_CMD *alloc_cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - alloc_cmd = (WMI_SET_BTCOEX_DEBUG_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(alloc_cmd, sizeof(*cmd)); - memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_DEBUG_CMD)); - return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_DEBUG_CMDID , - NO_SYNC_WMIFLAG)); - -} - -int -wmi_set_btcoex_bt_operating_status_cmd(struct wmi_t * wmip, - WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD * cmd) -{ - void *osbuf; - WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD *alloc_cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - alloc_cmd = (WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(alloc_cmd, sizeof(*cmd)); - memcpy(alloc_cmd,cmd,sizeof(WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD)); - return (wmi_cmd_send(wmip, osbuf, WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID , - NO_SYNC_WMIFLAG)); - -} - -int -wmi_get_btcoex_config_cmd(struct wmi_t * wmip, WMI_GET_BTCOEX_CONFIG_CMD * cmd) -{ - void *osbuf; - WMI_GET_BTCOEX_CONFIG_CMD *alloc_cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - alloc_cmd = (WMI_GET_BTCOEX_CONFIG_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(alloc_cmd, sizeof(*cmd)); - memcpy(alloc_cmd,cmd,sizeof(WMI_GET_BTCOEX_CONFIG_CMD)); - return (wmi_cmd_send(wmip, osbuf, WMI_GET_BTCOEX_CONFIG_CMDID , - NO_SYNC_WMIFLAG)); - -} - -int -wmi_get_btcoex_stats_cmd(struct wmi_t *wmip) -{ - - return wmi_simple_cmd(wmip, WMI_GET_BTCOEX_STATS_CMDID); - -} - -int -wmi_get_keepalive_configured(struct wmi_t *wmip) -{ - void *osbuf; - WMI_GET_KEEPALIVE_CMD *cmd; - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - cmd = (WMI_GET_KEEPALIVE_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - return (wmi_cmd_send(wmip, osbuf, WMI_GET_KEEPALIVE_CMDID, - NO_SYNC_WMIFLAG)); -} - -u8 wmi_get_keepalive_cmd(struct wmi_t *wmip) -{ - return wmip->wmi_keepaliveInterval; -} - -int -wmi_set_keepalive_cmd(struct wmi_t *wmip, u8 keepaliveInterval) -{ - void *osbuf; - WMI_SET_KEEPALIVE_CMD *cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_SET_KEEPALIVE_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - cmd->keepaliveInterval = keepaliveInterval; - wmip->wmi_keepaliveInterval = keepaliveInterval; - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_KEEPALIVE_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_set_params_cmd(struct wmi_t *wmip, u32 opcode, u32 length, char *buffer) -{ - void *osbuf; - WMI_SET_PARAMS_CMD *cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd) + length); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd) + length); - - cmd = (WMI_SET_PARAMS_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - cmd->opcode = opcode; - cmd->length = length; - memcpy(cmd->buffer, buffer, length); - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_PARAMS_CMDID, - NO_SYNC_WMIFLAG)); -} - - -int -wmi_set_mcast_filter_cmd(struct wmi_t *wmip, u8 dot1, u8 dot2, u8 dot3, u8 dot4) -{ - void *osbuf; - WMI_SET_MCAST_FILTER_CMD *cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_SET_MCAST_FILTER_CMD *)(A_NETBUF_DATA(osbuf)); - cmd->multicast_mac[0] = 0x01; - cmd->multicast_mac[1] = 0x00; - cmd->multicast_mac[2] = 0x5e; - cmd->multicast_mac[3] = dot2&0x7F; - cmd->multicast_mac[4] = dot3; - cmd->multicast_mac[5] = dot4; - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_MCAST_FILTER_CMDID, - NO_SYNC_WMIFLAG)); -} - - -int -wmi_del_mcast_filter_cmd(struct wmi_t *wmip, u8 dot1, u8 dot2, u8 dot3, u8 dot4) -{ - void *osbuf; - WMI_SET_MCAST_FILTER_CMD *cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_SET_MCAST_FILTER_CMD *)(A_NETBUF_DATA(osbuf)); - cmd->multicast_mac[0] = 0x01; - cmd->multicast_mac[1] = 0x00; - cmd->multicast_mac[2] = 0x5e; - cmd->multicast_mac[3] = dot2&0x7F; - cmd->multicast_mac[4] = dot3; - cmd->multicast_mac[5] = dot4; - - return (wmi_cmd_send(wmip, osbuf, WMI_DEL_MCAST_FILTER_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_mcast_filter_cmd(struct wmi_t *wmip, u8 enable) -{ - void *osbuf; - WMI_MCAST_FILTER_CMD *cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_MCAST_FILTER_CMD *)(A_NETBUF_DATA(osbuf)); - cmd->enable = enable; - - return (wmi_cmd_send(wmip, osbuf, WMI_MCAST_FILTER_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_set_appie_cmd(struct wmi_t *wmip, u8 mgmtFrmType, u8 ieLen, - u8 *ieInfo) -{ - void *osbuf; - WMI_SET_APPIE_CMD *cmd; - u16 cmdLen; - - cmdLen = sizeof(*cmd) + ieLen - 1; - osbuf = A_NETBUF_ALLOC(cmdLen); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, cmdLen); - - cmd = (WMI_SET_APPIE_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, cmdLen); - - cmd->mgmtFrmType = mgmtFrmType; - cmd->ieLen = ieLen; - memcpy(cmd->ieInfo, ieInfo, ieLen); - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_APPIE_CMDID, NO_SYNC_WMIFLAG)); -} - -int -wmi_set_halparam_cmd(struct wmi_t *wmip, u8 *cmd, u16 dataLen) -{ - void *osbuf; - u8 *data; - - osbuf = A_NETBUF_ALLOC(dataLen); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, dataLen); - - data = A_NETBUF_DATA(osbuf); - - memcpy(data, cmd, dataLen); - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_WHALPARAM_CMDID, NO_SYNC_WMIFLAG)); -} - -s32 wmi_get_rate(s8 rateindex) -{ - if (rateindex == RATE_AUTO) { - return 0; - } else { - return(wmi_rateTable[(u32) rateindex][0]); - } -} - -void -wmi_node_return (struct wmi_t *wmip, bss_t *bss) -{ - if (NULL != bss) - { - wlan_node_return (&wmip->wmi_scan_table, bss); - } -} - -void -wmi_set_nodeage(struct wmi_t *wmip, u32 nodeAge) -{ - wlan_set_nodeage(&wmip->wmi_scan_table,nodeAge); -} - -bss_t * -wmi_find_Ssidnode (struct wmi_t *wmip, u8 *pSsid, - u32 ssidLength, bool bIsWPA2, bool bMatchSSID) -{ - bss_t *node = NULL; - node = wlan_find_Ssidnode (&wmip->wmi_scan_table, pSsid, - ssidLength, bIsWPA2, bMatchSSID); - return node; -} - - -#ifdef THREAD_X -void -wmi_refresh_scan_table (struct wmi_t *wmip) -{ - wlan_refresh_inactive_nodes (&wmip->wmi_scan_table); -} -#endif - -void -wmi_free_allnodes(struct wmi_t *wmip) -{ - wlan_free_allnodes(&wmip->wmi_scan_table); -} - -bss_t * -wmi_find_node(struct wmi_t *wmip, const u8 *macaddr) -{ - bss_t *ni=NULL; - ni=wlan_find_node(&wmip->wmi_scan_table,macaddr); - return ni; -} - -void -wmi_free_node(struct wmi_t *wmip, const u8 *macaddr) -{ - bss_t *ni=NULL; - - ni=wlan_find_node(&wmip->wmi_scan_table,macaddr); - if (ni != NULL) { - wlan_node_reclaim(&wmip->wmi_scan_table, ni); - } - - return; -} - -int -wmi_dset_open_reply(struct wmi_t *wmip, - u32 status, - u32 access_cookie, - u32 dset_size, - u32 dset_version, - u32 targ_handle, - u32 targ_reply_fn, - u32 targ_reply_arg) -{ - void *osbuf; - WMIX_DSETOPEN_REPLY_CMD *open_reply; - - A_DPRINTF(DBG_WMI, (DBGFMT "Enter - wmip=0x%lx\n", DBGARG, (unsigned long)wmip)); - - osbuf = A_NETBUF_ALLOC(sizeof(*open_reply)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*open_reply)); - open_reply = (WMIX_DSETOPEN_REPLY_CMD *)(A_NETBUF_DATA(osbuf)); - - open_reply->status = status; - open_reply->targ_dset_handle = targ_handle; - open_reply->targ_reply_fn = targ_reply_fn; - open_reply->targ_reply_arg = targ_reply_arg; - open_reply->access_cookie = access_cookie; - open_reply->size = dset_size; - open_reply->version = dset_version; - - return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DSETOPEN_REPLY_CMDID, - NO_SYNC_WMIFLAG)); -} - -static int -wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, u8 *datap, u32 len) -{ - WMI_PMKID_LIST_REPLY *reply; - u32 expected_len; - - if (len < sizeof(WMI_PMKID_LIST_REPLY)) { - return A_EINVAL; - } - reply = (WMI_PMKID_LIST_REPLY *)datap; - expected_len = sizeof(reply->numPMKID) + reply->numPMKID * WMI_PMKID_LEN; - - if (len < expected_len) { - return A_EINVAL; - } - - A_WMI_PMKID_LIST_EVENT(wmip->wmi_devt, reply->numPMKID, - reply->pmkidList, reply->bssidList[0]); - - return 0; -} - - -static int -wmi_set_params_event_rx(struct wmi_t *wmip, u8 *datap, u32 len) -{ - WMI_SET_PARAMS_REPLY *reply; - - if (len < sizeof(WMI_SET_PARAMS_REPLY)) { - return A_EINVAL; - } - reply = (WMI_SET_PARAMS_REPLY *)datap; - - if (0 == reply->status) - { - - } - else - { - - } - - return 0; -} - - -#ifdef CONFIG_HOST_DSET_SUPPORT -int -wmi_dset_data_reply(struct wmi_t *wmip, - u32 status, - u8 *user_buf, - u32 length, - u32 targ_buf, - u32 targ_reply_fn, - u32 targ_reply_arg) -{ - void *osbuf; - WMIX_DSETDATA_REPLY_CMD *data_reply; - u32 size; - - size = sizeof(*data_reply) + length; - - if (size <= length) { - return A_ERROR; - } - - A_DPRINTF(DBG_WMI, - (DBGFMT "Enter - length=%d status=%d\n", DBGARG, length, status)); - - osbuf = A_NETBUF_ALLOC(size); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - A_NETBUF_PUT(osbuf, size); - data_reply = (WMIX_DSETDATA_REPLY_CMD *)(A_NETBUF_DATA(osbuf)); - - data_reply->status = status; - data_reply->targ_buf = targ_buf; - data_reply->targ_reply_fn = targ_reply_fn; - data_reply->targ_reply_arg = targ_reply_arg; - data_reply->length = length; - - if (status == 0) { - if (a_copy_from_user(data_reply->buf, user_buf, length)) { - A_NETBUF_FREE(osbuf); - return A_ERROR; - } - } - - return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_DSETDATA_REPLY_CMDID, - NO_SYNC_WMIFLAG)); -} -#endif /* CONFIG_HOST_DSET_SUPPORT */ - -int -wmi_set_wsc_status_cmd(struct wmi_t *wmip, u32 status) -{ - void *osbuf; - char *cmd; - - wps_enable = status; - - osbuf = a_netbuf_alloc(sizeof(1)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - a_netbuf_put(osbuf, sizeof(1)); - - cmd = (char *)(a_netbuf_to_data(osbuf)); - - A_MEMZERO(cmd, sizeof(*cmd)); - cmd[0] = (status?1:0); - return (wmi_cmd_send(wmip, osbuf, WMI_SET_WSC_STATUS_CMDID, - NO_SYNC_WMIFLAG)); -} - -#if defined(CONFIG_TARGET_PROFILE_SUPPORT) -int -wmi_prof_cfg_cmd(struct wmi_t *wmip, - u32 period, - u32 nbins) -{ - void *osbuf; - WMIX_PROF_CFG_CMD *cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMIX_PROF_CFG_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - cmd->period = period; - cmd->nbins = nbins; - - return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_PROF_CFG_CMDID, NO_SYNC_WMIFLAG)); -} - -int -wmi_prof_addr_set_cmd(struct wmi_t *wmip, u32 addr) -{ - void *osbuf; - WMIX_PROF_ADDR_SET_CMD *cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMIX_PROF_ADDR_SET_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - cmd->addr = addr; - - return (wmi_cmd_send_xtnd(wmip, osbuf, WMIX_PROF_ADDR_SET_CMDID, NO_SYNC_WMIFLAG)); -} - -int -wmi_prof_start_cmd(struct wmi_t *wmip) -{ - return wmi_simple_cmd_xtnd(wmip, WMIX_PROF_START_CMDID); -} - -int -wmi_prof_stop_cmd(struct wmi_t *wmip) -{ - return wmi_simple_cmd_xtnd(wmip, WMIX_PROF_STOP_CMDID); -} - -int -wmi_prof_count_get_cmd(struct wmi_t *wmip) -{ - return wmi_simple_cmd_xtnd(wmip, WMIX_PROF_COUNT_GET_CMDID); -} - -/* Called to handle WMIX_PROF_CONT_EVENTID */ -static int -wmi_prof_count_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - WMIX_PROF_COUNT_EVENT *prof_data = (WMIX_PROF_COUNT_EVENT *)datap; - - A_DPRINTF(DBG_WMI, - (DBGFMT "Enter - addr=0x%x count=%d\n", DBGARG, - prof_data->addr, prof_data->count)); - - A_WMI_PROF_COUNT_RX(prof_data->addr, prof_data->count); - - return 0; -} -#endif /* CONFIG_TARGET_PROFILE_SUPPORT */ - -#ifdef OS_ROAM_MANAGEMENT - -#define ETHERNET_MAC_ADDRESS_LENGTH 6 - -void -wmi_scan_indication (struct wmi_t *wmip) -{ - struct ieee80211_node_table *nt; - u32 gen; - u32 size; - u32 bsssize; - bss_t *bss; - u32 numbss; - PNDIS_802_11_BSSID_SCAN_INFO psi; - PBYTE pie; - NDIS_802_11_FIXED_IEs *pFixed; - NDIS_802_11_VARIABLE_IEs *pVar; - u32 RateSize; - - struct ar6kScanIndication - { - NDIS_802_11_STATUS_INDICATION ind; - NDIS_802_11_BSSID_SCAN_INFO_LIST slist; - } *pAr6kScanIndEvent; - - nt = &wmip->wmi_scan_table; - - ++nt->nt_si_gen; - - - gen = nt->nt_si_gen; - - size = offsetof(struct ar6kScanIndication, slist) + - offsetof(NDIS_802_11_BSSID_SCAN_INFO_LIST, BssidScanInfo); - - numbss = 0; - - IEEE80211_NODE_LOCK(nt); - - //calc size - for (bss = nt->nt_node_first; bss; bss = bss->ni_list_next) { - if (bss->ni_si_gen != gen) { - bsssize = offsetof(NDIS_802_11_BSSID_SCAN_INFO, Bssid) + offsetof(NDIS_WLAN_BSSID_EX, IEs); - bsssize = bsssize + sizeof(NDIS_802_11_FIXED_IEs); - -#ifdef SUPPORT_WPA2 - if (bss->ni_cie.ie_rsn) { - bsssize = bsssize + bss->ni_cie.ie_rsn[1] + 2; - } -#endif - if (bss->ni_cie.ie_wpa) { - bsssize = bsssize + bss->ni_cie.ie_wpa[1] + 2; - } - - // bsssize must be a multiple of 4 to maintain alignment. - bsssize = (bsssize + 3) & ~3; - - size += bsssize; - - numbss++; - } - } - - if (0 == numbss) - { -// RETAILMSG(1, (L"AR6K: scan indication: 0 bss\n")); - ar6000_scan_indication (wmip->wmi_devt, NULL, 0); - IEEE80211_NODE_UNLOCK (nt); - return; - } - - pAr6kScanIndEvent = A_MALLOC(size); - - if (NULL == pAr6kScanIndEvent) - { - IEEE80211_NODE_UNLOCK(nt); - return; - } - - A_MEMZERO(pAr6kScanIndEvent, size); - - //copy data - pAr6kScanIndEvent->ind.StatusType = Ndis802_11StatusType_BssidScanInfoList; - pAr6kScanIndEvent->slist.Version = 1; - pAr6kScanIndEvent->slist.NumItems = numbss; - - psi = &pAr6kScanIndEvent->slist.BssidScanInfo[0]; - - for (bss = nt->nt_node_first; bss; bss = bss->ni_list_next) { - if (bss->ni_si_gen != gen) { - - bss->ni_si_gen = gen; - - //Set scan time - psi->ScanTime = bss->ni_tstamp - WLAN_NODE_INACT_TIMEOUT_MSEC; - - // Copy data to bssid_ex - bsssize = offsetof(NDIS_WLAN_BSSID_EX, IEs); - bsssize = bsssize + sizeof(NDIS_802_11_FIXED_IEs); - -#ifdef SUPPORT_WPA2 - if (bss->ni_cie.ie_rsn) { - bsssize = bsssize + bss->ni_cie.ie_rsn[1] + 2; - } -#endif - if (bss->ni_cie.ie_wpa) { - bsssize = bsssize + bss->ni_cie.ie_wpa[1] + 2; - } - - // bsssize must be a multiple of 4 to maintain alignment. - bsssize = (bsssize + 3) & ~3; - - psi->Bssid.Length = bsssize; - - memcpy (psi->Bssid.MacAddress, bss->ni_macaddr, ETHERNET_MAC_ADDRESS_LENGTH); - - -//if (((bss->ni_macaddr[3] == 0xCE) && (bss->ni_macaddr[4] == 0xF0) && (bss->ni_macaddr[5] == 0xE7)) || -// ((bss->ni_macaddr[3] == 0x03) && (bss->ni_macaddr[4] == 0xE2) && (bss->ni_macaddr[5] == 0x70))) -// RETAILMSG (1, (L"%x\n",bss->ni_macaddr[5])); - - psi->Bssid.Ssid.SsidLength = 0; - pie = bss->ni_cie.ie_ssid; - - if (pie) { - // Format of SSID IE is: - // Type (1 octet) - // Length (1 octet) - // SSID (Length octets) - // - // Validation of the IE should have occurred within WMI. - // - if (pie[1] <= 32) { - psi->Bssid.Ssid.SsidLength = pie[1]; - memcpy(psi->Bssid.Ssid.Ssid, &pie[2], psi->Bssid.Ssid.SsidLength); - } - } - psi->Bssid.Privacy = (bss->ni_cie.ie_capInfo & 0x10) ? 1 : 0; - - //Post the RSSI value relative to the Standard Noise floor value. - psi->Bssid.Rssi = bss->ni_rssi; - - if (bss->ni_cie.ie_chan >= 2412 && bss->ni_cie.ie_chan <= 2484) { - - if (bss->ni_cie.ie_rates && bss->ni_cie.ie_xrates) { - psi->Bssid.NetworkTypeInUse = Ndis802_11OFDM24; - } - else { - psi->Bssid.NetworkTypeInUse = Ndis802_11DS; - } - } - else { - psi->Bssid.NetworkTypeInUse = Ndis802_11OFDM5; - } - - psi->Bssid.Configuration.Length = sizeof(psi->Bssid.Configuration); - psi->Bssid.Configuration.BeaconPeriod = bss->ni_cie.ie_beaconInt; // Units are Kmicroseconds (1024 us) - psi->Bssid.Configuration.ATIMWindow = 0; - psi->Bssid.Configuration.DSConfig = bss->ni_cie.ie_chan * 1000; - psi->Bssid.InfrastructureMode = ((bss->ni_cie.ie_capInfo & 0x03) == 0x01 ) ? Ndis802_11Infrastructure : Ndis802_11IBSS; - - RateSize = 0; - pie = bss->ni_cie.ie_rates; - if (pie) { - RateSize = (pie[1] < NDIS_802_11_LENGTH_RATES_EX) ? pie[1] : NDIS_802_11_LENGTH_RATES_EX; - memcpy(psi->Bssid.SupportedRates, &pie[2], RateSize); - } - pie = bss->ni_cie.ie_xrates; - if (pie && RateSize < NDIS_802_11_LENGTH_RATES_EX) { - memcpy(psi->Bssid.SupportedRates + RateSize, &pie[2], - (pie[1] < (NDIS_802_11_LENGTH_RATES_EX - RateSize)) ? pie[1] : (NDIS_802_11_LENGTH_RATES_EX - RateSize)); - } - - // Copy the fixed IEs - psi->Bssid.IELength = sizeof(NDIS_802_11_FIXED_IEs); - - pFixed = (NDIS_802_11_FIXED_IEs *)psi->Bssid.IEs; - memcpy(pFixed->Timestamp, bss->ni_cie.ie_tstamp, sizeof(pFixed->Timestamp)); - pFixed->BeaconInterval = bss->ni_cie.ie_beaconInt; - pFixed->Capabilities = bss->ni_cie.ie_capInfo; - - // Copy selected variable IEs - - pVar = (NDIS_802_11_VARIABLE_IEs *)((PBYTE)pFixed + sizeof(NDIS_802_11_FIXED_IEs)); - -#ifdef SUPPORT_WPA2 - // Copy the WPAv2 IE - if (bss->ni_cie.ie_rsn) { - pie = bss->ni_cie.ie_rsn; - psi->Bssid.IELength += pie[1] + 2; - memcpy(pVar, pie, pie[1] + 2); - pVar = (NDIS_802_11_VARIABLE_IEs *)((PBYTE)pVar + pie[1] + 2); - } -#endif - // Copy the WPAv1 IE - if (bss->ni_cie.ie_wpa) { - pie = bss->ni_cie.ie_wpa; - psi->Bssid.IELength += pie[1] + 2; - memcpy(pVar, pie, pie[1] + 2); - pVar = (NDIS_802_11_VARIABLE_IEs *)((PBYTE)pVar + pie[1] + 2); - } - - // Advance buffer pointer - psi = (PNDIS_802_11_BSSID_SCAN_INFO)((BYTE*)psi + bsssize + FIELD_OFFSET(NDIS_802_11_BSSID_SCAN_INFO, Bssid)); - } - } - - IEEE80211_NODE_UNLOCK(nt); - -// wmi_free_allnodes(wmip); - -// RETAILMSG(1, (L"AR6K: scan indication: %u bss\n", numbss)); - - ar6000_scan_indication (wmip->wmi_devt, pAr6kScanIndEvent, size); - - kfree(pAr6kScanIndEvent); -} -#endif - -u8 ar6000_get_upper_threshold(s16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, - u32 size) -{ - u32 index; - u8 threshold = (u8)sq_thresh->upper_threshold[size - 1]; - - /* The list is already in sorted order. Get the next lower value */ - for (index = 0; index < size; index ++) { - if (rssi < sq_thresh->upper_threshold[index]) { - threshold = (u8)sq_thresh->upper_threshold[index]; - break; - } - } - - return threshold; -} - -u8 ar6000_get_lower_threshold(s16 rssi, SQ_THRESHOLD_PARAMS *sq_thresh, - u32 size) -{ - u32 index; - u8 threshold = (u8)sq_thresh->lower_threshold[size - 1]; - - /* The list is already in sorted order. Get the next lower value */ - for (index = 0; index < size; index ++) { - if (rssi > sq_thresh->lower_threshold[index]) { - threshold = (u8)sq_thresh->lower_threshold[index]; - break; - } - } - - return threshold; -} -static int -wmi_send_rssi_threshold_params(struct wmi_t *wmip, - WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd) -{ - void *osbuf; - s8 size; - WMI_RSSI_THRESHOLD_PARAMS_CMD *cmd; - - size = sizeof (*cmd); - - osbuf = A_NETBUF_ALLOC(size); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, size); - - cmd = (WMI_RSSI_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, size); - memcpy(cmd, rssiCmd, sizeof(WMI_RSSI_THRESHOLD_PARAMS_CMD)); - - return (wmi_cmd_send(wmip, osbuf, WMI_RSSI_THRESHOLD_PARAMS_CMDID, - NO_SYNC_WMIFLAG)); -} -static int -wmi_send_snr_threshold_params(struct wmi_t *wmip, - WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd) -{ - void *osbuf; - s8 size; - WMI_SNR_THRESHOLD_PARAMS_CMD *cmd; - - size = sizeof (*cmd); - - osbuf = A_NETBUF_ALLOC(size); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, size); - cmd = (WMI_SNR_THRESHOLD_PARAMS_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, size); - memcpy(cmd, snrCmd, sizeof(WMI_SNR_THRESHOLD_PARAMS_CMD)); - - return (wmi_cmd_send(wmip, osbuf, WMI_SNR_THRESHOLD_PARAMS_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_set_target_event_report_cmd(struct wmi_t *wmip, WMI_SET_TARGET_EVENT_REPORT_CMD* cmd) -{ - void *osbuf; - WMI_SET_TARGET_EVENT_REPORT_CMD* alloc_cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - alloc_cmd = (WMI_SET_TARGET_EVENT_REPORT_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(alloc_cmd, sizeof(*cmd)); - memcpy(alloc_cmd, cmd, sizeof(*cmd)); - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_TARGET_EVENT_REPORT_CMDID, - NO_SYNC_WMIFLAG)); -} - -bss_t *wmi_rm_current_bss (struct wmi_t *wmip, u8 *id) -{ - wmi_get_current_bssid (wmip, id); - return wlan_node_remove (&wmip->wmi_scan_table, id); -} - -int wmi_add_current_bss (struct wmi_t *wmip, u8 *id, bss_t *bss) -{ - wlan_setup_node (&wmip->wmi_scan_table, bss, id); - return 0; -} - -static int -wmi_addba_req_event_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - WMI_ADDBA_REQ_EVENT *cmd = (WMI_ADDBA_REQ_EVENT *)datap; - - A_WMI_AGGR_RECV_ADDBA_REQ_EVT(wmip->wmi_devt, cmd); - - return 0; -} - - -static int -wmi_addba_resp_event_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - WMI_ADDBA_RESP_EVENT *cmd = (WMI_ADDBA_RESP_EVENT *)datap; - - A_WMI_AGGR_RECV_ADDBA_RESP_EVT(wmip->wmi_devt, cmd); - - return 0; -} - -static int -wmi_delba_req_event_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - WMI_DELBA_EVENT *cmd = (WMI_DELBA_EVENT *)datap; - - A_WMI_AGGR_RECV_DELBA_REQ_EVT(wmip->wmi_devt, cmd); - - return 0; -} - -int -wmi_btcoex_config_event_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); - - A_WMI_BTCOEX_CONFIG_EVENT(wmip->wmi_devt, datap, len); - - return 0; -} - - -int -wmi_btcoex_stats_event_rx(struct wmi_t * wmip,u8 *datap,int len) -{ - A_DPRINTF(DBG_WMI, (DBGFMT "Enter\n", DBGARG)); - - A_WMI_BTCOEX_STATS_EVENT(wmip->wmi_devt, datap, len); - - return 0; - -} - -static int -wmi_hci_event_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - WMI_HCI_EVENT *cmd = (WMI_HCI_EVENT *)datap; - A_WMI_HCI_EVENT_EVT(wmip->wmi_devt, cmd); - - return 0; -} - -//////////////////////////////////////////////////////////////////////////////// -//// //// -//// AP mode functions //// -//// //// -//////////////////////////////////////////////////////////////////////////////// -/* - * IOCTL: AR6000_XIOCTL_AP_COMMIT_CONFIG - * - * When AR6K in AP mode, This command will be called after - * changing ssid, channel etc. It will pass the profile to - * target with a flag which will indicate which parameter changed, - * also if this flag is 0, there was no change in parametes, so - * commit cmd will not be sent to target. Without calling this IOCTL - * the changes will not take effect. - */ -int -wmi_ap_profile_commit(struct wmi_t *wmip, WMI_CONNECT_CMD *p) -{ - void *osbuf; - WMI_CONNECT_CMD *cm; - - osbuf = A_NETBUF_ALLOC(sizeof(*cm)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cm)); - cm = (WMI_CONNECT_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cm, sizeof(*cm)); - - memcpy(cm,p,sizeof(*cm)); - - return (wmi_cmd_send(wmip, osbuf, WMI_AP_CONFIG_COMMIT_CMDID, NO_SYNC_WMIFLAG)); -} - -/* - * IOCTL: AR6000_XIOCTL_AP_HIDDEN_SSID - * - * This command will be used to enable/disable hidden ssid functioanlity of - * beacon. If it is enabled, ssid will be NULL in beacon. - */ -int -wmi_ap_set_hidden_ssid(struct wmi_t *wmip, u8 hidden_ssid) -{ - void *osbuf; - WMI_AP_HIDDEN_SSID_CMD *hs; - - osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_HIDDEN_SSID_CMD)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(WMI_AP_HIDDEN_SSID_CMD)); - hs = (WMI_AP_HIDDEN_SSID_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(hs, sizeof(*hs)); - - hs->hidden_ssid = hidden_ssid; - - A_DPRINTF(DBG_WMI, (DBGFMT "AR6000_XIOCTL_AP_HIDDEN_SSID %d\n", DBGARG , hidden_ssid)); - return (wmi_cmd_send(wmip, osbuf, WMI_AP_HIDDEN_SSID_CMDID, NO_SYNC_WMIFLAG)); -} - -/* - * IOCTL: AR6000_XIOCTL_AP_SET_MAX_NUM_STA - * - * This command is used to limit max num of STA that can connect - * with this AP. This value should not exceed AP_MAX_NUM_STA (this - * is max num of STA supported by AP). Value was already validated - * in ioctl.c - */ -int -wmi_ap_set_num_sta(struct wmi_t *wmip, u8 num_sta) -{ - void *osbuf; - WMI_AP_SET_NUM_STA_CMD *ns; - - osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_NUM_STA_CMD)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_NUM_STA_CMD)); - ns = (WMI_AP_SET_NUM_STA_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(ns, sizeof(*ns)); - - ns->num_sta = num_sta; - - A_DPRINTF(DBG_WMI, (DBGFMT "AR6000_XIOCTL_AP_SET_MAX_NUM_STA %d\n", DBGARG , num_sta)); - return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_NUM_STA_CMDID, NO_SYNC_WMIFLAG)); -} - -/* - * IOCTL: AR6000_XIOCTL_AP_SET_ACL_MAC - * - * This command is used to send list of mac of STAs which will - * be allowed to connect with this AP. When this list is empty - * firware will allow all STAs till the count reaches AP_MAX_NUM_STA. - */ -int -wmi_ap_acl_mac_list(struct wmi_t *wmip, WMI_AP_ACL_MAC_CMD *acl) -{ - void *osbuf; - WMI_AP_ACL_MAC_CMD *a; - - osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_ACL_MAC_CMD)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(WMI_AP_ACL_MAC_CMD)); - a = (WMI_AP_ACL_MAC_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(a, sizeof(*a)); - memcpy(a,acl,sizeof(*acl)); - - return (wmi_cmd_send(wmip, osbuf, WMI_AP_ACL_MAC_LIST_CMDID, NO_SYNC_WMIFLAG)); -} - -/* - * IOCTL: AR6000_XIOCTL_AP_SET_MLME - * - * This command is used to send list of mac of STAs which will - * be allowed to connect with this AP. When this list is empty - * firware will allow all STAs till the count reaches AP_MAX_NUM_STA. - */ -int -wmi_ap_set_mlme(struct wmi_t *wmip, u8 cmd, u8 *mac, u16 reason) -{ - void *osbuf; - WMI_AP_SET_MLME_CMD *mlme; - - osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_MLME_CMD)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_MLME_CMD)); - mlme = (WMI_AP_SET_MLME_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(mlme, sizeof(*mlme)); - - mlme->cmd = cmd; - memcpy(mlme->mac, mac, ATH_MAC_LEN); - mlme->reason = reason; - - return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_MLME_CMDID, NO_SYNC_WMIFLAG)); -} - -static int -wmi_pspoll_event_rx(struct wmi_t *wmip, u8 *datap, int len) -{ - WMI_PSPOLL_EVENT *ev; - - if (len < sizeof(WMI_PSPOLL_EVENT)) { - return A_EINVAL; - } - ev = (WMI_PSPOLL_EVENT *)datap; - - A_WMI_PSPOLL_EVENT(wmip->wmi_devt, ev->aid); - return 0; -} - -static int -wmi_dtimexpiry_event_rx(struct wmi_t *wmip, u8 *datap,int len) -{ - A_WMI_DTIMEXPIRY_EVENT(wmip->wmi_devt); - return 0; -} - -#ifdef WAPI_ENABLE -static int -wmi_wapi_rekey_event_rx(struct wmi_t *wmip, u8 *datap,int len) -{ - u8 *ev; - - if (len < 7) { - return A_EINVAL; - } - ev = (u8 *)datap; - - A_WMI_WAPI_REKEY_EVENT(wmip->wmi_devt, *ev, &ev[1]); - return 0; -} -#endif - -int -wmi_set_pvb_cmd(struct wmi_t *wmip, u16 aid, bool flag) -{ - WMI_AP_SET_PVB_CMD *cmd; - void *osbuf = NULL; - - osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_PVB_CMD)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_PVB_CMD)); - cmd = (WMI_AP_SET_PVB_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - - cmd->aid = aid; - cmd->flag = flag; - - return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_PVB_CMDID, NO_SYNC_WMIFLAG)); -} - -int -wmi_ap_conn_inact_time(struct wmi_t *wmip, u32 period) -{ - WMI_AP_CONN_INACT_CMD *cmd; - void *osbuf = NULL; - - osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_CONN_INACT_CMD)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(WMI_AP_CONN_INACT_CMD)); - cmd = (WMI_AP_CONN_INACT_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - - cmd->period = period; - - return (wmi_cmd_send(wmip, osbuf, WMI_AP_CONN_INACT_CMDID, NO_SYNC_WMIFLAG)); -} - -int -wmi_ap_bgscan_time(struct wmi_t *wmip, u32 period, u32 dwell) -{ - WMI_AP_PROT_SCAN_TIME_CMD *cmd; - void *osbuf = NULL; - - osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_PROT_SCAN_TIME_CMD)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(WMI_AP_PROT_SCAN_TIME_CMD)); - cmd = (WMI_AP_PROT_SCAN_TIME_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - - cmd->period_min = period; - cmd->dwell_ms = dwell; - - return (wmi_cmd_send(wmip, osbuf, WMI_AP_PROT_SCAN_TIME_CMDID, NO_SYNC_WMIFLAG)); -} - -int -wmi_ap_set_dtim(struct wmi_t *wmip, u8 dtim) -{ - WMI_AP_SET_DTIM_CMD *cmd; - void *osbuf = NULL; - - osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_DTIM_CMD)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_DTIM_CMD)); - cmd = (WMI_AP_SET_DTIM_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - - cmd->dtim = dtim; - - return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_DTIM_CMDID, NO_SYNC_WMIFLAG)); -} - -/* - * IOCTL: AR6000_XIOCTL_AP_SET_ACL_POLICY - * - * This command is used to set ACL policay. While changing policy, if you - * want to retain the existing MAC addresses in the ACL list, policy should be - * OR with AP_ACL_RETAIN_LIST_MASK, else the existing list will be cleared. - * If there is no chage in policy, the list will be intact. - */ -int -wmi_ap_set_acl_policy(struct wmi_t *wmip, u8 policy) -{ - void *osbuf; - WMI_AP_ACL_POLICY_CMD *po; - - osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_ACL_POLICY_CMD)); - if (osbuf == NULL) { - return A_NO_MEMORY; -} - - A_NETBUF_PUT(osbuf, sizeof(WMI_AP_ACL_POLICY_CMD)); - po = (WMI_AP_ACL_POLICY_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(po, sizeof(*po)); - - po->policy = policy; - - return (wmi_cmd_send(wmip, osbuf, WMI_AP_ACL_POLICY_CMDID, NO_SYNC_WMIFLAG)); -} - -int -wmi_ap_set_rateset(struct wmi_t *wmip, u8 rateset) -{ - void *osbuf; - WMI_AP_SET_11BG_RATESET_CMD *rs; - - osbuf = A_NETBUF_ALLOC(sizeof(WMI_AP_SET_11BG_RATESET_CMD)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(WMI_AP_SET_11BG_RATESET_CMD)); - rs = (WMI_AP_SET_11BG_RATESET_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(rs, sizeof(*rs)); - - rs->rateset = rateset; - - return (wmi_cmd_send(wmip, osbuf, WMI_AP_SET_11BG_RATESET_CMDID, NO_SYNC_WMIFLAG)); -} - -int -wmi_set_ht_cap_cmd(struct wmi_t *wmip, WMI_SET_HT_CAP_CMD *cmd) -{ - void *osbuf; - WMI_SET_HT_CAP_CMD *htCap; - u8 band; - - osbuf = A_NETBUF_ALLOC(sizeof(*htCap)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*htCap)); - - band = (cmd->band)? A_BAND_5GHZ : A_BAND_24GHZ; - wmip->wmi_ht_allowed[band] = (cmd->enable)? 1:0; - - htCap = (WMI_SET_HT_CAP_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(htCap, sizeof(*htCap)); - memcpy(htCap, cmd, sizeof(*htCap)); - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_HT_CAP_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_set_ht_op_cmd(struct wmi_t *wmip, u8 sta_chan_width) -{ - void *osbuf; - WMI_SET_HT_OP_CMD *htInfo; - - osbuf = A_NETBUF_ALLOC(sizeof(*htInfo)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*htInfo)); - - htInfo = (WMI_SET_HT_OP_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(htInfo, sizeof(*htInfo)); - htInfo->sta_chan_width = sta_chan_width; - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_HT_OP_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_set_tx_select_rates_cmd(struct wmi_t *wmip, u32 *pMaskArray) -{ - void *osbuf; - WMI_SET_TX_SELECT_RATES_CMD *pData; - - osbuf = A_NETBUF_ALLOC(sizeof(*pData)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*pData)); - - pData = (WMI_SET_TX_SELECT_RATES_CMD *)(A_NETBUF_DATA(osbuf)); - memcpy(pData, pMaskArray, sizeof(*pData)); - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_TX_SELECT_RATES_CMDID, - NO_SYNC_WMIFLAG)); -} - - -int -wmi_send_hci_cmd(struct wmi_t *wmip, u8 *buf, u16 sz) -{ - void *osbuf; - WMI_HCI_CMD *cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd) + sz); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd) + sz); - cmd = (WMI_HCI_CMD *)(A_NETBUF_DATA(osbuf)); - - cmd->cmd_buf_sz = sz; - memcpy(cmd->buf, buf, sz); - return (wmi_cmd_send(wmip, osbuf, WMI_HCI_CMD_CMDID, NO_SYNC_WMIFLAG)); -} - -int -wmi_allow_aggr_cmd(struct wmi_t *wmip, u16 tx_tidmask, u16 rx_tidmask) -{ - void *osbuf; - WMI_ALLOW_AGGR_CMD *cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_ALLOW_AGGR_CMD *)(A_NETBUF_DATA(osbuf)); - cmd->tx_allow_aggr = tx_tidmask; - cmd->rx_allow_aggr = rx_tidmask; - - return (wmi_cmd_send(wmip, osbuf, WMI_ALLOW_AGGR_CMDID, NO_SYNC_WMIFLAG)); -} - -int -wmi_setup_aggr_cmd(struct wmi_t *wmip, u8 tid) -{ - void *osbuf; - WMI_ADDBA_REQ_CMD *cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_ADDBA_REQ_CMD *)(A_NETBUF_DATA(osbuf)); - cmd->tid = tid; - - return (wmi_cmd_send(wmip, osbuf, WMI_ADDBA_REQ_CMDID, NO_SYNC_WMIFLAG)); -} - -int -wmi_delete_aggr_cmd(struct wmi_t *wmip, u8 tid, bool uplink) -{ - void *osbuf; - WMI_DELBA_REQ_CMD *cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_DELBA_REQ_CMD *)(A_NETBUF_DATA(osbuf)); - cmd->tid = tid; - cmd->is_sender_initiator = uplink; /* uplink =1 - uplink direction, 0=downlink direction */ - - /* Delete the local aggr state, on host */ - return (wmi_cmd_send(wmip, osbuf, WMI_DELBA_REQ_CMDID, NO_SYNC_WMIFLAG)); -} - -int -wmi_set_rx_frame_format_cmd(struct wmi_t *wmip, u8 rxMetaVersion, - bool rxDot11Hdr, bool defragOnHost) -{ - void *osbuf; - WMI_RX_FRAME_FORMAT_CMD *cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_RX_FRAME_FORMAT_CMD *)(A_NETBUF_DATA(osbuf)); - cmd->dot11Hdr = (rxDot11Hdr==true)? 1:0; - cmd->defragOnHost = (defragOnHost==true)? 1:0; - cmd->metaVersion = rxMetaVersion; /* */ - - /* Delete the local aggr state, on host */ - return (wmi_cmd_send(wmip, osbuf, WMI_RX_FRAME_FORMAT_CMDID, NO_SYNC_WMIFLAG)); -} - - -int -wmi_set_thin_mode_cmd(struct wmi_t *wmip, bool bThinMode) -{ - void *osbuf; - WMI_SET_THIN_MODE_CMD *cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_SET_THIN_MODE_CMD *)(A_NETBUF_DATA(osbuf)); - cmd->enable = (bThinMode==true)? 1:0; - - /* Delete the local aggr state, on host */ - return (wmi_cmd_send(wmip, osbuf, WMI_SET_THIN_MODE_CMDID, NO_SYNC_WMIFLAG)); -} - - -int -wmi_set_wlan_conn_precedence_cmd(struct wmi_t *wmip, BT_WLAN_CONN_PRECEDENCE precedence) -{ - void *osbuf; - WMI_SET_BT_WLAN_CONN_PRECEDENCE *cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_SET_BT_WLAN_CONN_PRECEDENCE *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - cmd->precedence = precedence; - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_BT_WLAN_CONN_PRECEDENCE_CMDID, - NO_SYNC_WMIFLAG)); -} - -int -wmi_set_pmk_cmd(struct wmi_t *wmip, u8 *pmk) -{ - void *osbuf; - WMI_SET_PMK_CMD *p; - - osbuf = A_NETBUF_ALLOC(sizeof(WMI_SET_PMK_CMD)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(WMI_SET_PMK_CMD)); - - p = (WMI_SET_PMK_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(p, sizeof(*p)); - - memcpy(p->pmk, pmk, WMI_PMK_LEN); - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMK_CMDID, NO_SYNC_WMIFLAG)); -} - -int -wmi_set_excess_tx_retry_thres_cmd(struct wmi_t *wmip, WMI_SET_EXCESS_TX_RETRY_THRES_CMD *cmd) -{ - void *osbuf; - WMI_SET_EXCESS_TX_RETRY_THRES_CMD *p; - - osbuf = A_NETBUF_ALLOC(sizeof(WMI_SET_EXCESS_TX_RETRY_THRES_CMD)); - if (osbuf == NULL) { - return A_NO_MEMORY; - } - - A_NETBUF_PUT(osbuf, sizeof(WMI_SET_EXCESS_TX_RETRY_THRES_CMD)); - - p = (WMI_SET_EXCESS_TX_RETRY_THRES_CMD *)(A_NETBUF_DATA(osbuf)); - memset(p, 0, sizeof(*p)); - - p->threshold = cmd->threshold; - - return (wmi_cmd_send(wmip, osbuf, WMI_SET_EXCESS_TX_RETRY_THRES_CMDID, NO_SYNC_WMIFLAG)); -} - -int -wmi_SGI_cmd(struct wmi_t *wmip, u32 sgiMask, u8 sgiPERThreshold) -{ - void *osbuf; - WMI_SET_TX_SGI_PARAM_CMD *cmd; - - osbuf = A_NETBUF_ALLOC(sizeof(*cmd)); - if (osbuf == NULL) { - return A_NO_MEMORY ; - } - - A_NETBUF_PUT(osbuf, sizeof(*cmd)); - - cmd = (WMI_SET_TX_SGI_PARAM_CMD *)(A_NETBUF_DATA(osbuf)); - A_MEMZERO(cmd, sizeof(*cmd)); - cmd->sgiMask = sgiMask; - cmd->sgiPERThreshold = sgiPERThreshold; - return (wmi_cmd_send(wmip, osbuf, WMI_SET_TX_SGI_PARAM_CMDID, - NO_SYNC_WMIFLAG)); -} - -bss_t * -wmi_find_matching_Ssidnode (struct wmi_t *wmip, u8 *pSsid, - u32 ssidLength, - u32 dot11AuthMode, u32 authMode, - u32 pairwiseCryptoType, u32 grpwiseCryptoTyp) -{ - bss_t *node = NULL; - node = wlan_find_matching_Ssidnode (&wmip->wmi_scan_table, pSsid, - ssidLength, dot11AuthMode, authMode, pairwiseCryptoType, grpwiseCryptoTyp); - - return node; -} - -u16 wmi_ieee2freq (int chan) -{ - u16 freq = 0; - freq = wlan_ieee2freq (chan); - return freq; - -} - -u32 wmi_freq2ieee (u16 freq) -{ - u16 chan = 0; - chan = wlan_freq2ieee (freq); - return chan; -} diff --git a/drivers/staging/ath6kl/wmi/wmi_host.h b/drivers/staging/ath6kl/wmi/wmi_host.h deleted file mode 100644 index 53e4f08..0000000 --- a/drivers/staging/ath6kl/wmi/wmi_host.h +++ /dev/null @@ -1,102 +0,0 @@ -//------------------------------------------------------------------------------ -// <copyright file="wmi_host.h" company="Atheros"> -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved. -// -// -// Permission to use, copy, modify, and/or distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -// -// -//------------------------------------------------------------------------------ -//============================================================================== -// This file contains local definitios for the wmi host module. -// -// Author(s): ="Atheros" -//============================================================================== -#ifndef _WMI_HOST_H_ -#define _WMI_HOST_H_ - -#include "roaming.h" -#ifdef __cplusplus -extern "C" { -#endif - -struct wmi_stats { - u32 cmd_len_err; - u32 cmd_id_err; -}; - -#define SSID_IE_LEN_INDEX 13 - -/* Host side link management data structures */ -#define SIGNAL_QUALITY_THRESHOLD_LEVELS 6 -#define SIGNAL_QUALITY_UPPER_THRESHOLD_LEVELS SIGNAL_QUALITY_THRESHOLD_LEVELS -#define SIGNAL_QUALITY_LOWER_THRESHOLD_LEVELS SIGNAL_QUALITY_THRESHOLD_LEVELS -typedef struct sq_threshold_params_s { - s16 upper_threshold[SIGNAL_QUALITY_UPPER_THRESHOLD_LEVELS]; - s16 lower_threshold[SIGNAL_QUALITY_LOWER_THRESHOLD_LEVELS]; - u32 upper_threshold_valid_count; - u32 lower_threshold_valid_count; - u32 polling_interval; - u8 weight; - u8 last_rssi; //normally you would expect this to be bss specific but we keep only one instance because its only valid when the device is in a connected state. Not sure if it belongs to host or target. - u8 last_rssi_poll_event; //Not sure if it belongs to host or target -} SQ_THRESHOLD_PARAMS; - -/* - * These constants are used with A_WLAN_BAND_SET. - */ -#define A_BAND_24GHZ 0 -#define A_BAND_5GHZ 1 -#define A_NUM_BANDS 2 - -struct wmi_t { - bool wmi_ready; - bool wmi_numQoSStream; - u16 wmi_streamExistsForAC[WMM_NUM_AC]; - u8 wmi_fatPipeExists; - void *wmi_devt; - struct wmi_stats wmi_stats; - struct ieee80211_node_table wmi_scan_table; - u8 wmi_bssid[ATH_MAC_LEN]; - u8 wmi_powerMode; - u8 wmi_phyMode; - u8 wmi_keepaliveInterval; -#ifdef THREAD_X - A_CSECT_T wmi_lock; -#else - A_MUTEX_T wmi_lock; -#endif - HTC_ENDPOINT_ID wmi_endpoint_id; - SQ_THRESHOLD_PARAMS wmi_SqThresholdParams[SIGNAL_QUALITY_METRICS_NUM_MAX]; - CRYPTO_TYPE wmi_pair_crypto_type; - CRYPTO_TYPE wmi_grp_crypto_type; - bool wmi_is_wmm_enabled; - u8 wmi_ht_allowed[A_NUM_BANDS]; - u8 wmi_traffic_class; -}; - -#ifdef THREAD_X -#define INIT_WMI_LOCK(w) A_CSECT_INIT(&(w)->wmi_lock) -#define LOCK_WMI(w) A_CSECT_ENTER(&(w)->wmi_lock); -#define UNLOCK_WMI(w) A_CSECT_LEAVE(&(w)->wmi_lock); -#define DELETE_WMI_LOCK(w) A_CSECT_DELETE(&(w)->wmi_lock); -#else -#define LOCK_WMI(w) A_MUTEX_LOCK(&(w)->wmi_lock); -#define UNLOCK_WMI(w) A_MUTEX_UNLOCK(&(w)->wmi_lock); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* _WMI_HOST_H_ */ diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index 867dbf1..6f8a75d 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -34,7 +34,7 @@ static int bcm_char_open(struct inode *inode, struct file * filp) /* Store the Adapter structure */ filp->private_data = pTarang; - /*Start Queuing the control response Packets*/ + /* Start Queuing the control response Packets */ atomic_inc(&Adapter->ApplicationRunning); nonseekable_open(inode, filp); @@ -84,7 +84,7 @@ static int bcm_char_release(struct inode *inode, struct file *filp) up(&Adapter->RxAppControlQueuelock); - /*Stop Queuing the control response Packets*/ + /* Stop Queuing the control response Packets */ atomic_dec(&Adapter->ApplicationRunning); kfree(pTarang); @@ -100,8 +100,8 @@ static ssize_t bcm_char_read(struct file *filp, char __user *buf, size_t size, PPER_TARANG_DATA pTarang = filp->private_data; PMINI_ADAPTER Adapter = pTarang->Adapter; struct sk_buff *Packet = NULL; - ssize_t PktLen = 0; - int wait_ret_val = 0; + ssize_t PktLen = 0; + int wait_ret_val = 0; unsigned long ret = 0; wait_ret_val = wait_event_interruptible(Adapter->process_read_wait_queue, @@ -157,1942 +157,1811 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) { PPER_TARANG_DATA pTarang = filp->private_data; void __user *argp = (void __user *)arg; - PMINI_ADAPTER Adapter = pTarang->Adapter; - INT Status = STATUS_FAILURE; + PMINI_ADAPTER Adapter = pTarang->Adapter; + INT Status = STATUS_FAILURE; int timeout = 0; - IOCTL_BUFFER IoBuffer; + IOCTL_BUFFER IoBuffer; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Parameters Passed to control IOCTL cmd=0x%X arg=0x%lX", cmd, arg); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Parameters Passed to control IOCTL cmd=0x%X arg=0x%lX", cmd, arg); - if(_IOC_TYPE(cmd) != BCM_IOCTL) + if (_IOC_TYPE(cmd) != BCM_IOCTL) return -EFAULT; - if(_IOC_DIR(cmd) & _IOC_READ) + if (_IOC_DIR(cmd) & _IOC_READ) Status = !access_ok(VERIFY_WRITE, argp, _IOC_SIZE(cmd)); else if (_IOC_DIR(cmd) & _IOC_WRITE) - Status = !access_ok(VERIFY_READ, argp, _IOC_SIZE(cmd)); + Status = !access_ok(VERIFY_READ, argp, _IOC_SIZE(cmd)); else if (_IOC_NONE == (_IOC_DIR(cmd) & _IOC_NONE)) - Status = STATUS_SUCCESS; + Status = STATUS_SUCCESS; - if(Status) + if (Status) return -EFAULT; - if(Adapter->device_removed) - { + if (Adapter->device_removed) return -EFAULT; - } - if(FALSE == Adapter->fw_download_done) - { - switch (cmd) - { - case IOCTL_MAC_ADDR_REQ: - case IOCTL_LINK_REQ: - case IOCTL_CM_REQUEST: - case IOCTL_SS_INFO_REQ: - case IOCTL_SEND_CONTROL_MESSAGE: - case IOCTL_IDLE_REQ: - case IOCTL_BCM_GPIO_SET_REQUEST: - case IOCTL_BCM_GPIO_STATUS_REQUEST: - return -EACCES; - default: - break; + if (FALSE == Adapter->fw_download_done) { + switch (cmd) { + case IOCTL_MAC_ADDR_REQ: + case IOCTL_LINK_REQ: + case IOCTL_CM_REQUEST: + case IOCTL_SS_INFO_REQ: + case IOCTL_SEND_CONTROL_MESSAGE: + case IOCTL_IDLE_REQ: + case IOCTL_BCM_GPIO_SET_REQUEST: + case IOCTL_BCM_GPIO_STATUS_REQUEST: + return -EACCES; + default: + break; } } Status = vendorextnIoctl(Adapter, cmd, arg); - if(Status != CONTINUE_COMMON_PATH ) - return Status; - - switch(cmd){ - // Rdms for Swin Idle... - case IOCTL_BCM_REGISTER_READ_PRIVATE: - { - RDM_BUFFER sRdmBuffer = {0}; - PCHAR temp_buff; - UINT Bufflen; + if (Status != CONTINUE_COMMON_PATH) + return Status; + + switch (cmd) { + /* Rdms for Swin Idle... */ + case IOCTL_BCM_REGISTER_READ_PRIVATE: { + RDM_BUFFER sRdmBuffer = {0}; + PCHAR temp_buff; + UINT Bufflen; + + /* Copy Ioctl Buffer structure */ + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; - /* Copy Ioctl Buffer structure */ - if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) - return -EFAULT; + if (IoBuffer.InputLength > sizeof(sRdmBuffer)) + return -EINVAL; - if (IoBuffer.InputLength > sizeof(sRdmBuffer)) - return -EINVAL; + if (copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) + return -EFAULT; - if(copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) - return -EFAULT; + /* FIXME: need to restrict BuffLen */ + Bufflen = IoBuffer.OutputLength + (4 - IoBuffer.OutputLength%4)%4; + temp_buff = kmalloc(Bufflen, GFP_KERNEL); + if (!temp_buff) + return -ENOMEM; - /* FIXME: need to restrict BuffLen */ - Bufflen = IoBuffer.OutputLength + (4 - IoBuffer.OutputLength%4)%4; - temp_buff = kmalloc(Bufflen, GFP_KERNEL); - if(!temp_buff) - return -ENOMEM; + Status = rdmalt(Adapter, (UINT)sRdmBuffer.Register, + (PUINT)temp_buff, Bufflen); + if (Status == STATUS_SUCCESS) { + if (copy_to_user(IoBuffer.OutputBuffer, temp_buff, IoBuffer.OutputLength)) + Status = -EFAULT; + } - Status = rdmalt(Adapter, (UINT)sRdmBuffer.Register, - (PUINT)temp_buff, Bufflen); - if(Status == STATUS_SUCCESS) - { - if(copy_to_user(IoBuffer.OutputBuffer, temp_buff, IoBuffer.OutputLength)) - Status = -EFAULT; - } + kfree(temp_buff); + break; + } - kfree(temp_buff); - break; - } - case IOCTL_BCM_REGISTER_WRITE_PRIVATE: - { - WRM_BUFFER sWrmBuffer = {0}; - UINT uiTempVar=0; - /* Copy Ioctl Buffer structure */ + case IOCTL_BCM_REGISTER_WRITE_PRIVATE: { + WRM_BUFFER sWrmBuffer = {0}; + UINT uiTempVar = 0; + /* Copy Ioctl Buffer structure */ - if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) - return -EFAULT; + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; - if (IoBuffer.InputLength > sizeof(sWrmBuffer)) - return -EINVAL; + if (IoBuffer.InputLength > sizeof(sWrmBuffer)) + return -EINVAL; - /* Get WrmBuffer structure */ - if(copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) - return -EFAULT; + /* Get WrmBuffer structure */ + if (copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) + return -EFAULT; - uiTempVar = sWrmBuffer.Register & EEPROM_REJECT_MASK; - if(!((Adapter->pstargetparams->m_u32Customize) & VSG_MODE) && - ((uiTempVar == EEPROM_REJECT_REG_1)|| + uiTempVar = sWrmBuffer.Register & EEPROM_REJECT_MASK; + if (!((Adapter->pstargetparams->m_u32Customize) & VSG_MODE) && + ((uiTempVar == EEPROM_REJECT_REG_1) || (uiTempVar == EEPROM_REJECT_REG_2) || (uiTempVar == EEPROM_REJECT_REG_3) || - (uiTempVar == EEPROM_REJECT_REG_4))) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "EEPROM Access Denied, not in VSG Mode\n"); - return -EFAULT; - } - Status = wrmalt(Adapter, (UINT)sWrmBuffer.Register, - (PUINT)sWrmBuffer.Data, sizeof(ULONG)); - if(Status == STATUS_SUCCESS) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"WRM Done\n"); - } - else - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM Failed\n"); - Status = -EFAULT; - } - break; + (uiTempVar == EEPROM_REJECT_REG_4))) { + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "EEPROM Access Denied, not in VSG Mode\n"); + return -EFAULT; } - case IOCTL_BCM_REGISTER_READ: - case IOCTL_BCM_EEPROM_REGISTER_READ: - { - RDM_BUFFER sRdmBuffer = {0}; - PCHAR temp_buff = NULL; - UINT uiTempVar = 0; - if((Adapter->IdleMode == TRUE) || - (Adapter->bShutStatus ==TRUE) || - (Adapter->bPreparingForLowPowerMode ==TRUE)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device in Idle Mode, Blocking Rdms\n"); - return -EACCES; - } - /* Copy Ioctl Buffer structure */ - if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) - return -EFAULT; + Status = wrmalt(Adapter, (UINT)sWrmBuffer.Register, + (PUINT)sWrmBuffer.Data, sizeof(ULONG)); - if (IoBuffer.InputLength > sizeof(sRdmBuffer)) - return -EINVAL; + if (Status == STATUS_SUCCESS) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM Done\n"); + } else { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM Failed\n"); + Status = -EFAULT; + } + break; + } - if(copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) - return -EFAULT; + case IOCTL_BCM_REGISTER_READ: + case IOCTL_BCM_EEPROM_REGISTER_READ: { + RDM_BUFFER sRdmBuffer = {0}; + PCHAR temp_buff = NULL; + UINT uiTempVar = 0; + if ((Adapter->IdleMode == TRUE) || + (Adapter->bShutStatus == TRUE) || + (Adapter->bPreparingForLowPowerMode == TRUE)) { + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device in Idle Mode, Blocking Rdms\n"); + return -EACCES; + } - /* FIXME: don't trust user supplied length */ - temp_buff = kmalloc(IoBuffer.OutputLength, GFP_KERNEL); - if(!temp_buff) - return STATUS_FAILURE; + /* Copy Ioctl Buffer structure */ + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; - if((((ULONG)sRdmBuffer.Register & 0x0F000000) != 0x0F000000) || - ((ULONG)sRdmBuffer.Register & 0x3)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "RDM Done On invalid Address : %x Access Denied.\n", - (int)sRdmBuffer.Register); - return -EINVAL; - } + if (IoBuffer.InputLength > sizeof(sRdmBuffer)) + return -EINVAL; + + if (copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) + return -EFAULT; - uiTempVar = sRdmBuffer.Register & EEPROM_REJECT_MASK; - Status = rdmaltWithLock(Adapter, (UINT)sRdmBuffer.Register, - (PUINT)temp_buff, IoBuffer.OutputLength); - if(Status == STATUS_SUCCESS) - if(copy_to_user(IoBuffer.OutputBuffer, temp_buff, IoBuffer.OutputLength)) - Status = -EFAULT; + /* FIXME: don't trust user supplied length */ + temp_buff = kmalloc(IoBuffer.OutputLength, GFP_KERNEL); + if (!temp_buff) + return STATUS_FAILURE; + + if ((((ULONG)sRdmBuffer.Register & 0x0F000000) != 0x0F000000) || + ((ULONG)sRdmBuffer.Register & 0x3)) { + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "RDM Done On invalid Address : %x Access Denied.\n", + (int)sRdmBuffer.Register); kfree(temp_buff); - break; + return -EINVAL; } - case IOCTL_BCM_REGISTER_WRITE: - case IOCTL_BCM_EEPROM_REGISTER_WRITE: - { - WRM_BUFFER sWrmBuffer = {0}; - UINT uiTempVar=0; - if((Adapter->IdleMode == TRUE) || - (Adapter->bShutStatus ==TRUE) || - (Adapter->bPreparingForLowPowerMode ==TRUE)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device in Idle Mode, Blocking Wrms\n"); - return -EACCES; - } - /* Copy Ioctl Buffer structure */ - if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) - return -EFAULT; + uiTempVar = sRdmBuffer.Register & EEPROM_REJECT_MASK; + Status = rdmaltWithLock(Adapter, (UINT)sRdmBuffer.Register, (PUINT)temp_buff, IoBuffer.OutputLength); - if (IoBuffer.InputLength > sizeof(sWrmBuffer)) - return -EINVAL; + if (Status == STATUS_SUCCESS) + if (copy_to_user(IoBuffer.OutputBuffer, temp_buff, IoBuffer.OutputLength)) + Status = -EFAULT; - /* Get WrmBuffer structure */ - if(copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) - return -EFAULT; + kfree(temp_buff); + break; + } + case IOCTL_BCM_REGISTER_WRITE: + case IOCTL_BCM_EEPROM_REGISTER_WRITE: { + WRM_BUFFER sWrmBuffer = {0}; + UINT uiTempVar = 0; + if ((Adapter->IdleMode == TRUE) || + (Adapter->bShutStatus == TRUE) || + (Adapter->bPreparingForLowPowerMode == TRUE)) { + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device in Idle Mode, Blocking Wrms\n"); + return -EACCES; + } - if( (((ULONG)sWrmBuffer.Register & 0x0F000000) != 0x0F000000) || - ((ULONG)sWrmBuffer.Register & 0x3) ) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "WRM Done On invalid Address : %x Access Denied.\n", - (int)sWrmBuffer.Register); - return -EINVAL; - } + /* Copy Ioctl Buffer structure */ + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; + + if (IoBuffer.InputLength > sizeof(sWrmBuffer)) + return -EINVAL; + + /* Get WrmBuffer structure */ + if (copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) + return -EFAULT; - uiTempVar = sWrmBuffer.Register & EEPROM_REJECT_MASK; - if(!((Adapter->pstargetparams->m_u32Customize) & VSG_MODE) && - ((uiTempVar == EEPROM_REJECT_REG_1)|| + if ((((ULONG)sWrmBuffer.Register & 0x0F000000) != 0x0F000000) || + ((ULONG)sWrmBuffer.Register & 0x3)) { + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "WRM Done On invalid Address : %x Access Denied.\n", (int)sWrmBuffer.Register); + return -EINVAL; + } + + uiTempVar = sWrmBuffer.Register & EEPROM_REJECT_MASK; + if (!((Adapter->pstargetparams->m_u32Customize) & VSG_MODE) && + ((uiTempVar == EEPROM_REJECT_REG_1) || (uiTempVar == EEPROM_REJECT_REG_2) || (uiTempVar == EEPROM_REJECT_REG_3) || (uiTempVar == EEPROM_REJECT_REG_4)) && - (cmd == IOCTL_BCM_REGISTER_WRITE)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "EEPROM Access Denied, not in VSG Mode\n"); + (cmd == IOCTL_BCM_REGISTER_WRITE)) { + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "EEPROM Access Denied, not in VSG Mode\n"); return -EFAULT; - } + } - Status = wrmaltWithLock(Adapter, (UINT)sWrmBuffer.Register, - (PUINT)sWrmBuffer.Data, sWrmBuffer.Length); - if(Status == STATUS_SUCCESS) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, OSAL_DBG, DBG_LVL_ALL, "WRM Done\n"); - } - else - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM Failed\n"); - Status = -EFAULT; - } + Status = wrmaltWithLock(Adapter, (UINT)sWrmBuffer.Register, + (PUINT)sWrmBuffer.Data, sWrmBuffer.Length); + + if (Status == STATUS_SUCCESS) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, OSAL_DBG, DBG_LVL_ALL, "WRM Done\n"); + } else { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM Failed\n"); + Status = -EFAULT; + } + break; + } + case IOCTL_BCM_GPIO_SET_REQUEST: { + UCHAR ucResetValue[4]; + UINT value = 0; + UINT uiBit = 0; + UINT uiOperation = 0; + + GPIO_INFO gpio_info = {0}; + if ((Adapter->IdleMode == TRUE) || + (Adapter->bShutStatus == TRUE) || + (Adapter->bPreparingForLowPowerMode == TRUE)) { + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "GPIO Can't be set/clear in Low power Mode"); + return -EACCES; + } + + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; + + if (IoBuffer.InputLength > sizeof(gpio_info)) + return -EINVAL; + + if (copy_from_user(&gpio_info, IoBuffer.InputBuffer, IoBuffer.InputLength)) + return -EFAULT; + + uiBit = gpio_info.uiGpioNumber; + uiOperation = gpio_info.uiGpioValue; + value = (1<<uiBit); + + if (IsReqGpioIsLedInNVM(Adapter, value) == FALSE) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Sorry, Requested GPIO<0x%X> is not correspond to LED !!!", value); + Status = -EINVAL; break; } - case IOCTL_BCM_GPIO_SET_REQUEST: - { - UCHAR ucResetValue[4]; - UINT value =0; - UINT uiBit = 0; - UINT uiOperation = 0; - - GPIO_INFO gpio_info = {0}; - if((Adapter->IdleMode == TRUE) || - (Adapter->bShutStatus ==TRUE) || - (Adapter->bPreparingForLowPowerMode ==TRUE)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"GPIO Can't be set/clear in Low power Mode"); - return -EACCES; - } - if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) - return -EFAULT; - if (IoBuffer.InputLength > sizeof(gpio_info)) - return -EINVAL; - if(copy_from_user(&gpio_info, IoBuffer.InputBuffer, IoBuffer.InputLength)) - return -EFAULT; - uiBit = gpio_info.uiGpioNumber; - uiOperation = gpio_info.uiGpioValue; - value= (1<<uiBit); + /* Set - setting 1 */ + if (uiOperation) { + /* Set the gpio output register */ + Status = wrmaltWithLock(Adapter, BCM_GPIO_OUTPUT_SET_REG, (PUINT)(&value), sizeof(UINT)); - if(IsReqGpioIsLedInNVM(Adapter,value) ==FALSE) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Sorry, Requested GPIO<0x%X> is not correspond to LED !!!",value); - Status = -EINVAL; + if (Status == STATUS_SUCCESS) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Set the GPIO bit\n"); + } else { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Failed to set the %dth GPIO\n", uiBit); break; } + } else { + /* Set the gpio output register */ + Status = wrmaltWithLock(Adapter, BCM_GPIO_OUTPUT_CLR_REG, (PUINT)(&value), sizeof(UINT)); + + if (Status == STATUS_SUCCESS) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Set the GPIO bit\n"); + } else { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Failed to clear the %dth GPIO\n", uiBit); + break; + } + } + Status = rdmaltWithLock(Adapter, (UINT)GPIO_MODE_REGISTER, (PUINT)ucResetValue, sizeof(UINT)); - if(uiOperation)//Set - setting 1 - { - //Set the gpio output register - Status = wrmaltWithLock(Adapter,BCM_GPIO_OUTPUT_SET_REG , - (PUINT)(&value), sizeof(UINT)); - if(Status == STATUS_SUCCESS) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Set the GPIO bit\n"); - } - else - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Failed to set the %dth GPIO \n",uiBit); - break; - } - } - else//Unset - setting 0 - { - //Set the gpio output register - Status = wrmaltWithLock(Adapter,BCM_GPIO_OUTPUT_CLR_REG , - (PUINT)(&value), sizeof(UINT)); - if(Status == STATUS_SUCCESS) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Set the GPIO bit\n"); - } - else - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Failed to clear the %dth GPIO \n",uiBit); - break; - } - } + if (STATUS_SUCCESS != Status) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, + "GPIO_MODE_REGISTER read failed"); + break; + } - Status = rdmaltWithLock(Adapter, (UINT)GPIO_MODE_REGISTER, - (PUINT)ucResetValue, sizeof(UINT)); - if (STATUS_SUCCESS != Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"GPIO_MODE_REGISTER read failed"); - break; - } - //Set the gpio mode register to output - *(UINT*)ucResetValue |= (1<<uiBit); - Status = wrmaltWithLock(Adapter,GPIO_MODE_REGISTER , + /* Set the gpio mode register to output */ + *(UINT *)ucResetValue |= (1<<uiBit); + Status = wrmaltWithLock(Adapter, GPIO_MODE_REGISTER, (PUINT)ucResetValue, sizeof(UINT)); - if(Status == STATUS_SUCCESS) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Set the GPIO to output Mode\n"); - } - else - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Failed to put GPIO in Output Mode\n"); - break; - } + + if (Status == STATUS_SUCCESS) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Set the GPIO to output Mode\n"); + } else { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Failed to put GPIO in Output Mode\n"); + break; } - break; - case BCM_LED_THREAD_STATE_CHANGE_REQ: - { - USER_THREAD_REQ threadReq = { 0 }; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"User made LED thread InActive"); - - if((Adapter->IdleMode == TRUE) || - (Adapter->bShutStatus ==TRUE) || - (Adapter->bPreparingForLowPowerMode ==TRUE)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"GPIO Can't be set/clear in Low power Mode"); - Status = -EACCES; - break; - } + } + break; - if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) - return -EFAULT; + case BCM_LED_THREAD_STATE_CHANGE_REQ: { + USER_THREAD_REQ threadReq = {0}; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "User made LED thread InActive"); - if (IoBuffer.InputLength > sizeof(threadReq)) - return -EINVAL; + if ((Adapter->IdleMode == TRUE) || + (Adapter->bShutStatus == TRUE) || + (Adapter->bPreparingForLowPowerMode == TRUE)) { - if (copy_from_user(&threadReq, IoBuffer.InputBuffer, IoBuffer.InputLength)) - return -EFAULT; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "GPIO Can't be set/clear in Low power Mode"); + Status = -EACCES; + break; + } - //if LED thread is running(Actively or Inactively) set it state to make inactive - if(Adapter->LEDInfo.led_thread_running) - { - if(threadReq.ThreadState == LED_THREAD_ACTIVATION_REQ) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Activating thread req"); - Adapter->DriverState = LED_THREAD_ACTIVE; - } - else - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"DeActivating Thread req....."); - Adapter->DriverState = LED_THREAD_INACTIVE; - } + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; - //signal thread. - wake_up(&Adapter->LEDInfo.notify_led_event); + if (IoBuffer.InputLength > sizeof(threadReq)) + return -EINVAL; + + if (copy_from_user(&threadReq, IoBuffer.InputBuffer, IoBuffer.InputLength)) + return -EFAULT; + /* if LED thread is running(Actively or Inactively) set it state to make inactive */ + if (Adapter->LEDInfo.led_thread_running) { + if (threadReq.ThreadState == LED_THREAD_ACTIVATION_REQ) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Activating thread req"); + Adapter->DriverState = LED_THREAD_ACTIVE; + } else { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "DeActivating Thread req....."); + Adapter->DriverState = LED_THREAD_INACTIVE; } + + /* signal thread. */ + wake_up(&Adapter->LEDInfo.notify_led_event); } - break; - case IOCTL_BCM_GPIO_STATUS_REQUEST: - { - ULONG uiBit = 0; - UCHAR ucRead[4]; - GPIO_INFO gpio_info = {0}; - if((Adapter->IdleMode == TRUE) || - (Adapter->bShutStatus ==TRUE) || - (Adapter->bPreparingForLowPowerMode ==TRUE)) - return -EACCES; - if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) - return -EFAULT; - if (IoBuffer.InputLength > sizeof(gpio_info)) - return -EINVAL; - if(copy_from_user(&gpio_info, IoBuffer.InputBuffer, IoBuffer.InputLength)) - return -EFAULT; - uiBit = gpio_info.uiGpioNumber; - //Set the gpio output register - Status = rdmaltWithLock(Adapter, (UINT)GPIO_PIN_STATE_REGISTER, - (PUINT)ucRead, sizeof(UINT)); - if(Status != STATUS_SUCCESS) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "RDM Failed\n"); - return Status; - } + } + break; - } - break; - case IOCTL_BCM_GPIO_MULTI_REQUEST: - { - UCHAR ucResetValue[4]; - GPIO_MULTI_INFO gpio_multi_info[MAX_IDX]; - PGPIO_MULTI_INFO pgpio_multi_info = (PGPIO_MULTI_INFO)gpio_multi_info; - - memset( pgpio_multi_info, 0, MAX_IDX * sizeof( GPIO_MULTI_INFO)); - - if((Adapter->IdleMode == TRUE) || - (Adapter->bShutStatus ==TRUE) || - (Adapter->bPreparingForLowPowerMode ==TRUE)) - return -EINVAL; - if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) - return -EFAULT; - if (IoBuffer.InputLength > sizeof(gpio_multi_info)) - return -EINVAL; - if (copy_from_user(&gpio_multi_info, IoBuffer.InputBuffer, IoBuffer.InputLength)) - return -EFAULT; + case IOCTL_BCM_GPIO_STATUS_REQUEST: { + ULONG uiBit = 0; + UCHAR ucRead[4]; + GPIO_INFO gpio_info = {0}; - if(IsReqGpioIsLedInNVM(Adapter,pgpio_multi_info[WIMAX_IDX].uiGPIOMask)== FALSE) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Sorry, Requested GPIO<0x%X> is not correspond to NVM LED bit map<0x%X>!!!",pgpio_multi_info[WIMAX_IDX].uiGPIOMask,Adapter->gpioBitMap); - Status = -EINVAL; - break; - } + if ((Adapter->IdleMode == TRUE) || + (Adapter->bShutStatus == TRUE) || + (Adapter->bPreparingForLowPowerMode == TRUE)) + return -EACCES; - /* Set the gpio output register */ + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; - if( ( pgpio_multi_info[WIMAX_IDX].uiGPIOMask) & - ( pgpio_multi_info[WIMAX_IDX].uiGPIOCommand)) - { - /* Set 1's in GPIO OUTPUT REGISTER */ - *(UINT*) ucResetValue = pgpio_multi_info[WIMAX_IDX].uiGPIOMask & - pgpio_multi_info[WIMAX_IDX].uiGPIOCommand & - pgpio_multi_info[WIMAX_IDX].uiGPIOValue; + if (IoBuffer.InputLength > sizeof(gpio_info)) + return -EINVAL; - if( *(UINT*) ucResetValue) - Status = wrmaltWithLock( Adapter, BCM_GPIO_OUTPUT_SET_REG , (PUINT) ucResetValue, sizeof(ULONG)); + if (copy_from_user(&gpio_info, IoBuffer.InputBuffer, IoBuffer.InputLength)) + return -EFAULT; - if( Status != STATUS_SUCCESS) - { - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0,"WRM to BCM_GPIO_OUTPUT_SET_REG Failed."); - return Status; - } + uiBit = gpio_info.uiGpioNumber; - /* Clear to 0's in GPIO OUTPUT REGISTER */ - *(UINT*) ucResetValue = (pgpio_multi_info[WIMAX_IDX].uiGPIOMask & - pgpio_multi_info[WIMAX_IDX].uiGPIOCommand & - ( ~( pgpio_multi_info[WIMAX_IDX].uiGPIOValue))); + /* Set the gpio output register */ + Status = rdmaltWithLock(Adapter, (UINT)GPIO_PIN_STATE_REGISTER, + (PUINT)ucRead, sizeof(UINT)); - if( *(UINT*) ucResetValue) - Status = wrmaltWithLock( Adapter, BCM_GPIO_OUTPUT_CLR_REG , (PUINT) ucResetValue, sizeof(ULONG)); + if (Status != STATUS_SUCCESS) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "RDM Failed\n"); + return Status; + } + } + break; - if( Status != STATUS_SUCCESS) - { - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0,"WRM to BCM_GPIO_OUTPUT_CLR_REG Failed." ); - return Status; - } - } + case IOCTL_BCM_GPIO_MULTI_REQUEST: { + UCHAR ucResetValue[4]; + GPIO_MULTI_INFO gpio_multi_info[MAX_IDX]; + PGPIO_MULTI_INFO pgpio_multi_info = (PGPIO_MULTI_INFO)gpio_multi_info; - if( pgpio_multi_info[WIMAX_IDX].uiGPIOMask) - { - Status = rdmaltWithLock(Adapter, (UINT)GPIO_PIN_STATE_REGISTER, (PUINT)ucResetValue, sizeof(UINT)); + memset(pgpio_multi_info, 0, MAX_IDX * sizeof(GPIO_MULTI_INFO)); - if(Status != STATUS_SUCCESS) - { - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0,"RDM to GPIO_PIN_STATE_REGISTER Failed."); - return Status; - } + if ((Adapter->IdleMode == TRUE) || + (Adapter->bShutStatus == TRUE) || + (Adapter->bPreparingForLowPowerMode == TRUE)) + return -EINVAL; - pgpio_multi_info[WIMAX_IDX].uiGPIOValue = ( *(UINT*)ucResetValue & - pgpio_multi_info[WIMAX_IDX].uiGPIOMask); - } + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; - Status = copy_to_user(IoBuffer.OutputBuffer, &gpio_multi_info, IoBuffer.OutputLength); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying Content to IOBufer for user space err:%d",Status); - break; - } - } + if (IoBuffer.InputLength > sizeof(gpio_multi_info)) + return -EINVAL; + + if (copy_from_user(&gpio_multi_info, IoBuffer.InputBuffer, IoBuffer.InputLength)) + return -EFAULT; + + if (IsReqGpioIsLedInNVM(Adapter, pgpio_multi_info[WIMAX_IDX].uiGPIOMask) == FALSE) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, + "Sorry, Requested GPIO<0x%X> is not correspond to NVM LED bit map<0x%X>!!!", + pgpio_multi_info[WIMAX_IDX].uiGPIOMask, Adapter->gpioBitMap); + Status = -EINVAL; break; - case IOCTL_BCM_GPIO_MODE_REQUEST: - { - UCHAR ucResetValue[4]; - GPIO_MULTI_MODE gpio_multi_mode[MAX_IDX]; - PGPIO_MULTI_MODE pgpio_multi_mode = ( PGPIO_MULTI_MODE) gpio_multi_mode; + } - if((Adapter->IdleMode == TRUE) || - (Adapter->bShutStatus ==TRUE) || - (Adapter->bPreparingForLowPowerMode ==TRUE)) - return -EINVAL; + /* Set the gpio output register */ + if ((pgpio_multi_info[WIMAX_IDX].uiGPIOMask) & + (pgpio_multi_info[WIMAX_IDX].uiGPIOCommand)) { + /* Set 1's in GPIO OUTPUT REGISTER */ + *(UINT *)ucResetValue = pgpio_multi_info[WIMAX_IDX].uiGPIOMask & + pgpio_multi_info[WIMAX_IDX].uiGPIOCommand & + pgpio_multi_info[WIMAX_IDX].uiGPIOValue; - if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) - return -EFAULT; - if (IoBuffer.InputLength > sizeof(gpio_multi_mode)) - return -EINVAL; - if (copy_from_user(&gpio_multi_mode, IoBuffer.InputBuffer, IoBuffer.InputLength)) - return -EFAULT; + if (*(UINT *) ucResetValue) + Status = wrmaltWithLock(Adapter, BCM_GPIO_OUTPUT_SET_REG, + (PUINT)ucResetValue, sizeof(ULONG)); - Status = rdmaltWithLock( Adapter, ( UINT) GPIO_MODE_REGISTER, ( PUINT) ucResetValue, sizeof( UINT)); - if( STATUS_SUCCESS != Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Read of GPIO_MODE_REGISTER failed"); + if (Status != STATUS_SUCCESS) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "WRM to BCM_GPIO_OUTPUT_SET_REG Failed."); return Status; } - //Validating the request - if(IsReqGpioIsLedInNVM(Adapter,pgpio_multi_mode[WIMAX_IDX].uiGPIOMask)== FALSE) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Sorry, Requested GPIO<0x%X> is not correspond to NVM LED bit map<0x%X>!!!",pgpio_multi_mode[WIMAX_IDX].uiGPIOMask,Adapter->gpioBitMap); - Status = -EINVAL; - break; - } + /* Clear to 0's in GPIO OUTPUT REGISTER */ + *(UINT *)ucResetValue = (pgpio_multi_info[WIMAX_IDX].uiGPIOMask & + pgpio_multi_info[WIMAX_IDX].uiGPIOCommand & + (~(pgpio_multi_info[WIMAX_IDX].uiGPIOValue))); - if( pgpio_multi_mode[WIMAX_IDX].uiGPIOMask) - { - /* write all OUT's (1's) */ - *( UINT*) ucResetValue |= ( pgpio_multi_mode[WIMAX_IDX].uiGPIOMode & - pgpio_multi_mode[WIMAX_IDX].uiGPIOMask); - /* write all IN's (0's) */ - *( UINT*) ucResetValue &= ~( ( ~pgpio_multi_mode[WIMAX_IDX].uiGPIOMode) & - pgpio_multi_mode[WIMAX_IDX].uiGPIOMask); - - /* Currently implemented return the modes of all GPIO's - * else needs to bit AND with mask - * */ - pgpio_multi_mode[WIMAX_IDX].uiGPIOMode = *(UINT*)ucResetValue; - - Status = wrmaltWithLock( Adapter, GPIO_MODE_REGISTER , ( PUINT) ucResetValue, sizeof( ULONG)); - if( Status == STATUS_SUCCESS) - { - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM to GPIO_MODE_REGISTER Done"); - } - else - { - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0,"WRM to GPIO_MODE_REGISTER Failed"); - Status = -EFAULT; - break; - } - } - else /* if uiGPIOMask is 0 then return mode register configuration */ - { - pgpio_multi_mode[WIMAX_IDX].uiGPIOMode = *( UINT*) ucResetValue; + if (*(UINT *) ucResetValue) + Status = wrmaltWithLock(Adapter, BCM_GPIO_OUTPUT_CLR_REG, (PUINT)ucResetValue, sizeof(ULONG)); + + if (Status != STATUS_SUCCESS) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "WRM to BCM_GPIO_OUTPUT_CLR_REG Failed."); + return Status; } - Status = copy_to_user(IoBuffer.OutputBuffer, &gpio_multi_mode, IoBuffer.OutputLength); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying Content to IOBufer for user space err:%d",Status); - break; + } + + if (pgpio_multi_info[WIMAX_IDX].uiGPIOMask) { + Status = rdmaltWithLock(Adapter, (UINT)GPIO_PIN_STATE_REGISTER, (PUINT)ucResetValue, sizeof(UINT)); + + if (Status != STATUS_SUCCESS) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "RDM to GPIO_PIN_STATE_REGISTER Failed."); + return Status; } + + pgpio_multi_info[WIMAX_IDX].uiGPIOValue = (*(UINT *)ucResetValue & + pgpio_multi_info[WIMAX_IDX].uiGPIOMask); } - break; - case IOCTL_MAC_ADDR_REQ: - case IOCTL_LINK_REQ: - case IOCTL_CM_REQUEST: - case IOCTL_SS_INFO_REQ: - case IOCTL_SEND_CONTROL_MESSAGE: - case IOCTL_IDLE_REQ: - { - PVOID pvBuffer=NULL; + Status = copy_to_user(IoBuffer.OutputBuffer, &gpio_multi_info, IoBuffer.OutputLength); + if (Status) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, + "Failed while copying Content to IOBufer for user space err:%d", Status); + break; + } + } + break; - /* Copy Ioctl Buffer structure */ - if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) - return -EFAULT; + case IOCTL_BCM_GPIO_MODE_REQUEST: { + UCHAR ucResetValue[4]; + GPIO_MULTI_MODE gpio_multi_mode[MAX_IDX]; + PGPIO_MULTI_MODE pgpio_multi_mode = (PGPIO_MULTI_MODE)gpio_multi_mode; - /* FIXME: don't accept any length from user */ - pvBuffer = kmalloc(IoBuffer.InputLength, GFP_KERNEL); - if(!pvBuffer) - return -ENOMEM; + if ((Adapter->IdleMode == TRUE) || + (Adapter->bShutStatus == TRUE) || + (Adapter->bPreparingForLowPowerMode == TRUE)) + return -EINVAL; + + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; - if(copy_from_user(pvBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) - { + if (IoBuffer.InputLength > sizeof(gpio_multi_mode)) + return -EINVAL; + + if (copy_from_user(&gpio_multi_mode, IoBuffer.InputBuffer, IoBuffer.InputLength)) + return -EFAULT; + + Status = rdmaltWithLock(Adapter, (UINT)GPIO_MODE_REGISTER, (PUINT)ucResetValue, sizeof(UINT)); + + if (STATUS_SUCCESS != Status) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read of GPIO_MODE_REGISTER failed"); + return Status; + } + + /* Validating the request */ + if (IsReqGpioIsLedInNVM(Adapter, pgpio_multi_mode[WIMAX_IDX].uiGPIOMask) == FALSE) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, + "Sorry, Requested GPIO<0x%X> is not correspond to NVM LED bit map<0x%X>!!!", + pgpio_multi_mode[WIMAX_IDX].uiGPIOMask, Adapter->gpioBitMap); + Status = -EINVAL; + break; + } + + if (pgpio_multi_mode[WIMAX_IDX].uiGPIOMask) { + /* write all OUT's (1's) */ + *(UINT *) ucResetValue |= (pgpio_multi_mode[WIMAX_IDX].uiGPIOMode & + pgpio_multi_mode[WIMAX_IDX].uiGPIOMask); + + /* write all IN's (0's) */ + *(UINT *) ucResetValue &= ~((~pgpio_multi_mode[WIMAX_IDX].uiGPIOMode) & + pgpio_multi_mode[WIMAX_IDX].uiGPIOMask); + + /* Currently implemented return the modes of all GPIO's + * else needs to bit AND with mask + */ + pgpio_multi_mode[WIMAX_IDX].uiGPIOMode = *(UINT *)ucResetValue; + + Status = wrmaltWithLock(Adapter, GPIO_MODE_REGISTER, (PUINT)ucResetValue, sizeof(ULONG)); + if (Status == STATUS_SUCCESS) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, + "WRM to GPIO_MODE_REGISTER Done"); + } else { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, + "WRM to GPIO_MODE_REGISTER Failed"); Status = -EFAULT; - kfree(pvBuffer); break; } + } else { +/* if uiGPIOMask is 0 then return mode register configuration */ + pgpio_multi_mode[WIMAX_IDX].uiGPIOMode = *(UINT *)ucResetValue; + } - down(&Adapter->LowPowerModeSync); - Status = wait_event_interruptible_timeout(Adapter->lowpower_mode_wait_queue, - !Adapter->bPreparingForLowPowerMode, - (1 * HZ)); - if(Status == -ERESTARTSYS) - goto cntrlEnd; - - if(Adapter->bPreparingForLowPowerMode) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Preparing Idle Mode is still True - Hence Rejecting control message\n"); - Status = STATUS_FAILURE ; - goto cntrlEnd ; - } - Status = CopyBufferToControlPacket(Adapter, (PVOID)pvBuffer); - cntrlEnd: - up(&Adapter->LowPowerModeSync); + Status = copy_to_user(IoBuffer.OutputBuffer, &gpio_multi_mode, IoBuffer.OutputLength); + if (Status) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, + "Failed while copying Content to IOBufer for user space err:%d", Status); + break; + } + } + break; + + case IOCTL_MAC_ADDR_REQ: + case IOCTL_LINK_REQ: + case IOCTL_CM_REQUEST: + case IOCTL_SS_INFO_REQ: + case IOCTL_SEND_CONTROL_MESSAGE: + case IOCTL_IDLE_REQ: { + PVOID pvBuffer = NULL; + + /* Copy Ioctl Buffer structure */ + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; + + /* FIXME: don't accept any length from user */ + pvBuffer = kmalloc(IoBuffer.InputLength, GFP_KERNEL); + if (!pvBuffer) + return -ENOMEM; + + if (copy_from_user(pvBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) { + Status = -EFAULT; kfree(pvBuffer); break; } - case IOCTL_BCM_BUFFER_DOWNLOAD_START: - { - INT NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock) ; - if(NVMAccess) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " IOCTL_BCM_CHIP_RESET not allowed as EEPROM Read/Write is in progress\n"); - return -EACCES; - } - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Starting the firmware download PID =0x%x!!!!\n", current->pid); - if(!down_trylock(&Adapter->fw_download_sema)) - { - Adapter->bBinDownloaded=FALSE; - Adapter->fw_download_process_pid=current->pid; - Adapter->bCfgDownloaded=FALSE; - Adapter->fw_download_done=FALSE; - netif_carrier_off(Adapter->dev); - netif_stop_queue(Adapter->dev); - Status = reset_card_proc(Adapter); - if(Status) - { - pr_err(PFX "%s: reset_card_proc Failed!\n", Adapter->dev->name); - up(&Adapter->fw_download_sema); - up(&Adapter->NVMRdmWrmLock); - break; - } - mdelay(10); - } - else - { - Status = -EBUSY; + down(&Adapter->LowPowerModeSync); + Status = wait_event_interruptible_timeout(Adapter->lowpower_mode_wait_queue, + !Adapter->bPreparingForLowPowerMode, + (1 * HZ)); + if (Status == -ERESTARTSYS) + goto cntrlEnd; + if (Adapter->bPreparingForLowPowerMode) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, + "Preparing Idle Mode is still True - Hence Rejecting control message\n"); + Status = STATUS_FAILURE; + goto cntrlEnd; + } + Status = CopyBufferToControlPacket(Adapter, (PVOID)pvBuffer); + +cntrlEnd: + up(&Adapter->LowPowerModeSync); + kfree(pvBuffer); + break; + } + + case IOCTL_BCM_BUFFER_DOWNLOAD_START: { + INT NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock); + if (NVMAccess) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, + "IOCTL_BCM_CHIP_RESET not allowed as EEPROM Read/Write is in progress\n"); + return -EACCES; + } + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, + "Starting the firmware download PID =0x%x!!!!\n", current->pid); + + if (!down_trylock(&Adapter->fw_download_sema)) { + Adapter->bBinDownloaded = FALSE; + Adapter->fw_download_process_pid = current->pid; + Adapter->bCfgDownloaded = FALSE; + Adapter->fw_download_done = FALSE; + netif_carrier_off(Adapter->dev); + netif_stop_queue(Adapter->dev); + Status = reset_card_proc(Adapter); + if (Status) { + pr_err(PFX "%s: reset_card_proc Failed!\n", Adapter->dev->name); + up(&Adapter->fw_download_sema); + up(&Adapter->NVMRdmWrmLock); + break; } - up(&Adapter->NVMRdmWrmLock); - break; + mdelay(10); + } else { + Status = -EBUSY; } - case IOCTL_BCM_BUFFER_DOWNLOAD: - { - FIRMWARE_INFO *psFwInfo = NULL; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Starting the firmware download PID =0x%x!!!!\n", current->pid); - do{ - if(!down_trylock(&Adapter->fw_download_sema)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Invalid way to download buffer. Use Start and then call this!!!\n"); - Status=-EINVAL; - break; - } - /* Copy Ioctl Buffer structure */ - if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) - return -EFAULT; + up(&Adapter->NVMRdmWrmLock); + break; + } + + case IOCTL_BCM_BUFFER_DOWNLOAD: { + FIRMWARE_INFO *psFwInfo = NULL; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Starting the firmware download PID =0x%x!!!!\n", current->pid); + do { + if (!down_trylock(&Adapter->fw_download_sema)) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, + "Invalid way to download buffer. Use Start and then call this!!!\n"); + Status = -EINVAL; + break; + } - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Length for FW DLD is : %lx\n", - IoBuffer.InputLength); + /* Copy Ioctl Buffer structure */ + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; - if (IoBuffer.InputLength > sizeof(FIRMWARE_INFO)) - return -EINVAL; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, + "Length for FW DLD is : %lx\n", IoBuffer.InputLength); - psFwInfo = kmalloc(sizeof(*psFwInfo), GFP_KERNEL); - if(!psFwInfo) - return -ENOMEM; + if (IoBuffer.InputLength > sizeof(FIRMWARE_INFO)) + return -EINVAL; - if(copy_from_user(psFwInfo, IoBuffer.InputBuffer, IoBuffer.InputLength)) - return -EFAULT; + psFwInfo = kmalloc(sizeof(*psFwInfo), GFP_KERNEL); + if (!psFwInfo) + return -ENOMEM; - if(!psFwInfo->pvMappedFirmwareAddress || - (psFwInfo->u32FirmwareLength == 0)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Something else is wrong %lu\n", - psFwInfo->u32FirmwareLength); - Status = -EINVAL; - break; - } - Status = bcm_ioctl_fw_download(Adapter, psFwInfo); - if(Status != STATUS_SUCCESS) - { - if(psFwInfo->u32StartingAddress==CONFIG_BEGIN_ADDR) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "IOCTL: Configuration File Upload Failed\n"); - } - else - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "IOCTL: Firmware File Upload Failed\n"); - } - //up(&Adapter->fw_download_sema); + if (copy_from_user(psFwInfo, IoBuffer.InputBuffer, IoBuffer.InputLength)) + return -EFAULT; - if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) - { - Adapter->DriverState = DRIVER_INIT; - Adapter->LEDInfo.bLedInitDone = FALSE; - wake_up(&Adapter->LEDInfo.notify_led_event); - } - } - break ; - }while(0); + if (!psFwInfo->pvMappedFirmwareAddress || + (psFwInfo->u32FirmwareLength == 0)) { - if(Status != STATUS_SUCCESS) - up(&Adapter->fw_download_sema); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, OSAL_DBG, DBG_LVL_ALL, "IOCTL: Firmware File Uploaded\n"); - kfree(psFwInfo); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Something else is wrong %lu\n", + psFwInfo->u32FirmwareLength); + Status = -EINVAL; break; } - case IOCTL_BCM_BUFFER_DOWNLOAD_STOP: - { - INT NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock); - if(NVMAccess) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, " FW download blocked as EEPROM Read/Write is in progress\n"); - up(&Adapter->fw_download_sema); - return -EACCES; - } - if(down_trylock(&Adapter->fw_download_sema)) - { - Adapter->bBinDownloaded=TRUE; - Adapter->bCfgDownloaded=TRUE; - atomic_set(&Adapter->CurrNumFreeTxDesc, 0); - - Adapter->CurrNumRecvDescs=0; - Adapter->downloadDDR = 0; - - //setting the Mips to Run - Status = run_card_proc(Adapter); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Firm Download Failed\n"); - up(&Adapter->fw_download_sema); - up(&Adapter->NVMRdmWrmLock); - break; - } + + Status = bcm_ioctl_fw_download(Adapter, psFwInfo); + + if (Status != STATUS_SUCCESS) { + if (psFwInfo->u32StartingAddress == CONFIG_BEGIN_ADDR) + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "IOCTL: Configuration File Upload Failed\n"); else - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Firm Download Over...\n"); - mdelay(10); - /* Wait for MailBox Interrupt */ - if(StartInterruptUrb((PS_INTERFACE_ADAPTER)Adapter->pvInterfaceAdapter)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Unable to send interrupt...\n"); - } - timeout = 5*HZ; - Adapter->waiting_to_fw_download_done = FALSE; - wait_event_timeout(Adapter->ioctl_fw_dnld_wait_queue, - Adapter->waiting_to_fw_download_done, timeout); - Adapter->fw_download_process_pid=INVALID_PID; - Adapter->fw_download_done=TRUE; - atomic_set(&Adapter->CurrNumFreeTxDesc, 0); - Adapter->CurrNumRecvDescs = 0; - Adapter->PrevNumRecvDescs = 0; - atomic_set(&Adapter->cntrlpktCnt,0); - Adapter->LinkUpStatus = 0; - Adapter->LinkStatus = 0; - - if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) - { - Adapter->DriverState = FW_DOWNLOAD_DONE; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "IOCTL: Firmware File Upload Failed\n"); + + /* up(&Adapter->fw_download_sema); */ + + if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) { + Adapter->DriverState = DRIVER_INIT; + Adapter->LEDInfo.bLedInitDone = FALSE; wake_up(&Adapter->LEDInfo.notify_led_event); } + } + break; - if(!timeout) - { - Status = -ENODEV; - } + } while (0); + + if (Status != STATUS_SUCCESS) + up(&Adapter->fw_download_sema); + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, OSAL_DBG, DBG_LVL_ALL, "IOCTL: Firmware File Uploaded\n"); + kfree(psFwInfo); + break; + } + + case IOCTL_BCM_BUFFER_DOWNLOAD_STOP: { + INT NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock); + + if (NVMAccess) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, + "FW download blocked as EEPROM Read/Write is in progress\n"); + up(&Adapter->fw_download_sema); + return -EACCES; + } + + if (down_trylock(&Adapter->fw_download_sema)) { + Adapter->bBinDownloaded = TRUE; + Adapter->bCfgDownloaded = TRUE; + atomic_set(&Adapter->CurrNumFreeTxDesc, 0); + Adapter->CurrNumRecvDescs = 0; + Adapter->downloadDDR = 0; + + /* setting the Mips to Run */ + Status = run_card_proc(Adapter); + + if (Status) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Firm Download Failed\n"); + up(&Adapter->fw_download_sema); + up(&Adapter->NVMRdmWrmLock); + break; + } else { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, + DBG_LVL_ALL, "Firm Download Over...\n"); } - else - { - Status = -EINVAL; + + mdelay(10); + + /* Wait for MailBox Interrupt */ + if (StartInterruptUrb((PS_INTERFACE_ADAPTER)Adapter->pvInterfaceAdapter)) + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Unable to send interrupt...\n"); + + timeout = 5*HZ; + Adapter->waiting_to_fw_download_done = FALSE; + wait_event_timeout(Adapter->ioctl_fw_dnld_wait_queue, + Adapter->waiting_to_fw_download_done, timeout); + Adapter->fw_download_process_pid = INVALID_PID; + Adapter->fw_download_done = TRUE; + atomic_set(&Adapter->CurrNumFreeTxDesc, 0); + Adapter->CurrNumRecvDescs = 0; + Adapter->PrevNumRecvDescs = 0; + atomic_set(&Adapter->cntrlpktCnt, 0); + Adapter->LinkUpStatus = 0; + Adapter->LinkStatus = 0; + + if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) { + Adapter->DriverState = FW_DOWNLOAD_DONE; + wake_up(&Adapter->LEDInfo.notify_led_event); } - up(&Adapter->fw_download_sema); - up(&Adapter->NVMRdmWrmLock); - break; + + if (!timeout) + Status = -ENODEV; + } else { + Status = -EINVAL; } - case IOCTL_BE_BUCKET_SIZE: - Status = 0; - if (get_user(Adapter->BEBucketSize, (unsigned long __user *)arg)) - Status = -EFAULT; - break; - case IOCTL_RTPS_BUCKET_SIZE: - Status = 0; - if (get_user(Adapter->rtPSBucketSize, (unsigned long __user *)arg)) + up(&Adapter->fw_download_sema); + up(&Adapter->NVMRdmWrmLock); + break; + } + + case IOCTL_BE_BUCKET_SIZE: + Status = 0; + if (get_user(Adapter->BEBucketSize, (unsigned long __user *)arg)) + Status = -EFAULT; + break; + + case IOCTL_RTPS_BUCKET_SIZE: + Status = 0; + if (get_user(Adapter->rtPSBucketSize, (unsigned long __user *)arg)) + Status = -EFAULT; + break; + + case IOCTL_CHIP_RESET: { + INT NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock); + if (NVMAccess) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, " IOCTL_BCM_CHIP_RESET not allowed as EEPROM Read/Write is in progress\n"); + return -EACCES; + } + + down(&Adapter->RxAppControlQueuelock); + Status = reset_card_proc(Adapter); + flushAllAppQ(); + up(&Adapter->RxAppControlQueuelock); + up(&Adapter->NVMRdmWrmLock); + ResetCounters(Adapter); + break; + } + + case IOCTL_QOS_THRESHOLD: { + USHORT uiLoopIndex; + + Status = 0; + for (uiLoopIndex = 0; uiLoopIndex < NO_OF_QUEUES; uiLoopIndex++) { + if (get_user(Adapter->PackInfo[uiLoopIndex].uiThreshold, + (unsigned long __user *)arg)) { Status = -EFAULT; - break; - case IOCTL_CHIP_RESET: - { - INT NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock); - if(NVMAccess) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, " IOCTL_BCM_CHIP_RESET not allowed as EEPROM Read/Write is in progress\n"); - return -EACCES; + break; } - down(&Adapter->RxAppControlQueuelock); - Status = reset_card_proc(Adapter); - flushAllAppQ(); - up(&Adapter->RxAppControlQueuelock); - up(&Adapter->NVMRdmWrmLock); - ResetCounters(Adapter); - break; } - case IOCTL_QOS_THRESHOLD: - { - USHORT uiLoopIndex; + break; + } - Status = 0; - for (uiLoopIndex = 0; uiLoopIndex < NO_OF_QUEUES; uiLoopIndex++) { - if (get_user(Adapter->PackInfo[uiLoopIndex].uiThreshold, - (unsigned long __user *)arg)) { - Status = -EFAULT; - break; - } - } - break; + case IOCTL_DUMP_PACKET_INFO: + DumpPackInfo(Adapter); + DumpPhsRules(&Adapter->stBCMPhsContext); + Status = STATUS_SUCCESS; + break; + + case IOCTL_GET_PACK_INFO: + if (copy_to_user(argp, &Adapter->PackInfo, sizeof(PacketInfo)*NO_OF_QUEUES)) + return -EFAULT; + Status = STATUS_SUCCESS; + break; + + case IOCTL_BCM_SWITCH_TRANSFER_MODE: { + UINT uiData = 0; + if (copy_from_user(&uiData, argp, sizeof(UINT))) + return -EFAULT; + + if (uiData) { + /* Allow All Packets */ + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_SWITCH_TRANSFER_MODE: ETH_PACKET_TUNNELING_MODE\n"); + Adapter->TransferMode = ETH_PACKET_TUNNELING_MODE; + } else { + /* Allow IP only Packets */ + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_SWITCH_TRANSFER_MODE: IP_PACKET_ONLY_MODE\n"); + Adapter->TransferMode = IP_PACKET_ONLY_MODE; } + Status = STATUS_SUCCESS; + break; + } - case IOCTL_DUMP_PACKET_INFO: + case IOCTL_BCM_GET_DRIVER_VERSION: { + /* Copy Ioctl Buffer structure */ + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; - DumpPackInfo(Adapter); - DumpPhsRules(&Adapter->stBCMPhsContext); - Status = STATUS_SUCCESS; - break; + if (copy_to_user(IoBuffer.OutputBuffer, VER_FILEVERSION_STR, IoBuffer.OutputLength)) + return -EFAULT; + Status = STATUS_SUCCESS; + break; + } - case IOCTL_GET_PACK_INFO: - if(copy_to_user(argp, &Adapter->PackInfo, sizeof(PacketInfo)*NO_OF_QUEUES)) - return -EFAULT; - Status = STATUS_SUCCESS; + case IOCTL_BCM_GET_CURRENT_STATUS: { + LINK_STATE link_state; + + /* Copy Ioctl Buffer structure */ + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "copy_from_user failed..\n"); + Status = -EFAULT; break; - case IOCTL_BCM_SWITCH_TRANSFER_MODE: - { - UINT uiData = 0; - if(copy_from_user(&uiData, argp, sizeof(UINT))) - return -EFAULT; + } - if(uiData) /* Allow All Packets */ - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_SWITCH_TRANSFER_MODE: ETH_PACKET_TUNNELING_MODE\n"); - Adapter->TransferMode = ETH_PACKET_TUNNELING_MODE; - } - else /* Allow IP only Packets */ - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_SWITCH_TRANSFER_MODE: IP_PACKET_ONLY_MODE\n"); - Adapter->TransferMode = IP_PACKET_ONLY_MODE; - } - Status = STATUS_SUCCESS; + if (IoBuffer.OutputLength != sizeof(link_state)) { + Status = -EINVAL; break; } - case IOCTL_BCM_GET_DRIVER_VERSION: - { - /* Copy Ioctl Buffer structure */ - if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) - return -EFAULT; + memset(&link_state, 0, sizeof(link_state)); + link_state.bIdleMode = Adapter->IdleMode; + link_state.bShutdownMode = Adapter->bShutStatus; + link_state.ucLinkStatus = Adapter->LinkStatus; - if(copy_to_user(IoBuffer.OutputBuffer, VER_FILEVERSION_STR, IoBuffer.OutputLength)) - return -EFAULT; - Status = STATUS_SUCCESS; + if (copy_to_user(IoBuffer.OutputBuffer, &link_state, min_t(size_t, sizeof(link_state), IoBuffer.OutputLength))) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy_to_user Failed..\n"); + Status = -EFAULT; break; } - case IOCTL_BCM_GET_CURRENT_STATUS: - { - LINK_STATE link_state; + Status = STATUS_SUCCESS; + break; + } - /* Copy Ioctl Buffer structure */ - if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copy_from_user failed..\n"); - Status = -EFAULT; - break; - } - if (IoBuffer.OutputLength != sizeof(link_state)) { - Status = -EINVAL; - break; - } + case IOCTL_BCM_SET_MAC_TRACING: { + UINT tracing_flag; - memset(&link_state, 0, sizeof(link_state)); - link_state.bIdleMode = Adapter->IdleMode; - link_state.bShutdownMode = Adapter->bShutStatus; - link_state.ucLinkStatus = Adapter->LinkStatus; + /* copy ioctl Buffer structure */ + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; - if (copy_to_user(IoBuffer.OutputBuffer, &link_state, - min_t(size_t, sizeof(link_state), IoBuffer.OutputLength))) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy_to_user Failed..\n"); - Status = -EFAULT; - break; - } - Status = STATUS_SUCCESS; - break; + if (copy_from_user(&tracing_flag, IoBuffer.InputBuffer, sizeof(UINT))) + return -EFAULT; + + if (tracing_flag) + Adapter->pTarangs->MacTracingEnabled = TRUE; + else + Adapter->pTarangs->MacTracingEnabled = FALSE; + break; + } + + case IOCTL_BCM_GET_DSX_INDICATION: { + ULONG ulSFId = 0; + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; + + if (IoBuffer.OutputLength < sizeof(stLocalSFAddIndicationAlt)) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, + "Mismatch req: %lx needed is =0x%zx!!!", + IoBuffer.OutputLength, sizeof(stLocalSFAddIndicationAlt)); + return -EINVAL; } - case IOCTL_BCM_SET_MAC_TRACING: - { - UINT tracing_flag; - - /* copy ioctl Buffer structure */ - if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) - return -EFAULT; - - if(copy_from_user(&tracing_flag,IoBuffer.InputBuffer,sizeof(UINT))) - return -EFAULT; - - if (tracing_flag) - Adapter->pTarangs->MacTracingEnabled = TRUE; - else - Adapter->pTarangs->MacTracingEnabled = FALSE; - break; - } - case IOCTL_BCM_GET_DSX_INDICATION: - { - ULONG ulSFId=0; - if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) - return -EFAULT; - if(IoBuffer.OutputLength < sizeof(stLocalSFAddIndicationAlt)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, - "Mismatch req: %lx needed is =0x%zx!!!", - IoBuffer.OutputLength, sizeof(stLocalSFAddIndicationAlt)); - return -EINVAL; - } + if (copy_from_user(&ulSFId, IoBuffer.InputBuffer, sizeof(ulSFId))) + return -EFAULT; - if(copy_from_user(&ulSFId, IoBuffer.InputBuffer, sizeof(ulSFId))) - return -EFAULT; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Get DSX Data SF ID is =%lx\n", ulSFId); + get_dsx_sf_data_to_application(Adapter, ulSFId, IoBuffer.OutputBuffer); + Status = STATUS_SUCCESS; + } + break; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Get DSX Data SF ID is =%lx\n", ulSFId ); - get_dsx_sf_data_to_application(Adapter, ulSFId, IoBuffer.OutputBuffer); - Status=STATUS_SUCCESS; + case IOCTL_BCM_GET_HOST_MIBS: { + PVOID temp_buff; + + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; + + if (IoBuffer.OutputLength != sizeof(S_MIBS_HOST_STATS_MIBS)) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, + "Length Check failed %lu %zd\n", + IoBuffer.OutputLength, sizeof(S_MIBS_HOST_STATS_MIBS)); + return -EINVAL; } - break; - case IOCTL_BCM_GET_HOST_MIBS: - { - PVOID temp_buff; - if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) - return -EFAULT; + /* FIXME: HOST_STATS are too big for kmalloc (122048)! */ + temp_buff = kzalloc(sizeof(S_MIBS_HOST_STATS_MIBS), GFP_KERNEL); + if (!temp_buff) + return STATUS_FAILURE; - if(IoBuffer.OutputLength != sizeof(S_MIBS_HOST_STATS_MIBS)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, - "Length Check failed %lu %zd\n", - IoBuffer.OutputLength, sizeof(S_MIBS_HOST_STATS_MIBS)); - return -EINVAL; - } + Status = ProcessGetHostMibs(Adapter, temp_buff); + GetDroppedAppCntrlPktMibs(temp_buff, pTarang); - /* FIXME: HOST_STATS are too big for kmalloc (122048)! */ - temp_buff = kzalloc(sizeof(S_MIBS_HOST_STATS_MIBS), GFP_KERNEL); - if(!temp_buff) - return STATUS_FAILURE; + if (Status != STATUS_FAILURE) + if (copy_to_user(IoBuffer.OutputBuffer, temp_buff, sizeof(S_MIBS_HOST_STATS_MIBS))) + Status = -EFAULT; - Status = ProcessGetHostMibs(Adapter, temp_buff); - GetDroppedAppCntrlPktMibs(temp_buff, pTarang); + kfree(temp_buff); + break; + } - if (Status != STATUS_FAILURE) - if(copy_to_user(IoBuffer.OutputBuffer, temp_buff, sizeof(S_MIBS_HOST_STATS_MIBS))) - Status = -EFAULT; + case IOCTL_BCM_WAKE_UP_DEVICE_FROM_IDLE: + if ((FALSE == Adapter->bTriedToWakeUpFromlowPowerMode) && (TRUE == Adapter->IdleMode)) { + Adapter->usIdleModePattern = ABORT_IDLE_MODE; + Adapter->bWakeUpDevice = TRUE; + wake_up(&Adapter->process_rx_cntrlpkt); + } - kfree(temp_buff); + Status = STATUS_SUCCESS; + break; + + case IOCTL_BCM_BULK_WRM: { + PBULKWRM_BUFFER pBulkBuffer; + UINT uiTempVar = 0; + PCHAR pvBuffer = NULL; + + if ((Adapter->IdleMode == TRUE) || + (Adapter->bShutStatus == TRUE) || + (Adapter->bPreparingForLowPowerMode == TRUE)) { + + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "Device in Idle/Shutdown Mode, Blocking Wrms\n"); + Status = -EACCES; break; } - case IOCTL_BCM_WAKE_UP_DEVICE_FROM_IDLE: - if((FALSE == Adapter->bTriedToWakeUpFromlowPowerMode) && (TRUE==Adapter->IdleMode)) - { - Adapter->usIdleModePattern = ABORT_IDLE_MODE; - Adapter->bWakeUpDevice = TRUE; - wake_up(&Adapter->process_rx_cntrlpkt); - } - Status = STATUS_SUCCESS; - break; + /* Copy Ioctl Buffer structure */ + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; - case IOCTL_BCM_BULK_WRM: - { - PBULKWRM_BUFFER pBulkBuffer; - UINT uiTempVar=0; - PCHAR pvBuffer = NULL; - - if((Adapter->IdleMode == TRUE) || - (Adapter->bShutStatus ==TRUE) || - (Adapter->bPreparingForLowPowerMode ==TRUE)) - { - BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "Device in Idle/Shutdown Mode, Blocking Wrms\n"); - Status = -EACCES; - break; - } + /* FIXME: restrict length */ + pvBuffer = kmalloc(IoBuffer.InputLength, GFP_KERNEL); + if (!pvBuffer) + return -ENOMEM; - /* Copy Ioctl Buffer structure */ - if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) - return -EFAULT; + /* Get WrmBuffer structure */ + if (copy_from_user(pvBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) { + kfree(pvBuffer); + Status = -EFAULT; + break; + } - /* FIXME: restrict length */ - pvBuffer = kmalloc(IoBuffer.InputLength, GFP_KERNEL); - if(!pvBuffer) - return -ENOMEM; - - /* Get WrmBuffer structure */ - if(copy_from_user(pvBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) - { - kfree(pvBuffer); - Status = -EFAULT; - break; - } + pBulkBuffer = (PBULKWRM_BUFFER)pvBuffer; - pBulkBuffer = (PBULKWRM_BUFFER)pvBuffer; + if (((ULONG)pBulkBuffer->Register & 0x0F000000) != 0x0F000000 || + ((ULONG)pBulkBuffer->Register & 0x3)) { + kfree(pvBuffer); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "WRM Done On invalid Address : %x Access Denied.\n", (int)pBulkBuffer->Register); + Status = -EINVAL; + break; + } - if(((ULONG)pBulkBuffer->Register & 0x0F000000) != 0x0F000000 || - ((ULONG)pBulkBuffer->Register & 0x3)) - { - kfree(pvBuffer); - BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0,"WRM Done On invalid Address : %x Access Denied.\n",(int)pBulkBuffer->Register); - Status = -EINVAL; - break; - } + uiTempVar = pBulkBuffer->Register & EEPROM_REJECT_MASK; + if (!((Adapter->pstargetparams->m_u32Customize)&VSG_MODE) && + ((uiTempVar == EEPROM_REJECT_REG_1) || + (uiTempVar == EEPROM_REJECT_REG_2) || + (uiTempVar == EEPROM_REJECT_REG_3) || + (uiTempVar == EEPROM_REJECT_REG_4)) && + (cmd == IOCTL_BCM_REGISTER_WRITE)) { + kfree(pvBuffer); + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "EEPROM Access Denied, not in VSG Mode\n"); + Status = -EFAULT; + break; + } - uiTempVar = pBulkBuffer->Register & EEPROM_REJECT_MASK; - if(!((Adapter->pstargetparams->m_u32Customize)&VSG_MODE) - && ((uiTempVar == EEPROM_REJECT_REG_1)|| - (uiTempVar == EEPROM_REJECT_REG_2) || - (uiTempVar == EEPROM_REJECT_REG_3) || - (uiTempVar == EEPROM_REJECT_REG_4)) && - (cmd == IOCTL_BCM_REGISTER_WRITE)) - { - kfree(pvBuffer); - BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0,"EEPROM Access Denied, not in VSG Mode\n"); - Status = -EFAULT; - break; - } + if (pBulkBuffer->SwapEndian == FALSE) + Status = wrmWithLock(Adapter, (UINT)pBulkBuffer->Register, (PCHAR)pBulkBuffer->Values, IoBuffer.InputLength - 2*sizeof(ULONG)); + else + Status = wrmaltWithLock(Adapter, (UINT)pBulkBuffer->Register, (PUINT)pBulkBuffer->Values, IoBuffer.InputLength - 2*sizeof(ULONG)); - if(pBulkBuffer->SwapEndian == FALSE) - Status = wrmWithLock(Adapter, (UINT)pBulkBuffer->Register, (PCHAR)pBulkBuffer->Values, IoBuffer.InputLength - 2*sizeof(ULONG)); - else - Status = wrmaltWithLock(Adapter, (UINT)pBulkBuffer->Register, (PUINT)pBulkBuffer->Values, IoBuffer.InputLength - 2*sizeof(ULONG)); + if (Status != STATUS_SUCCESS) + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "WRM Failed\n"); - if(Status != STATUS_SUCCESS) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "WRM Failed\n"); - } + kfree(pvBuffer); + break; + } - kfree(pvBuffer); - break; - } + case IOCTL_BCM_GET_NVM_SIZE: + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; - case IOCTL_BCM_GET_NVM_SIZE: - if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + if (Adapter->eNVMType == NVM_EEPROM || Adapter->eNVMType == NVM_FLASH) { + if (copy_to_user(IoBuffer.OutputBuffer, &Adapter->uiNVMDSDSize, sizeof(UINT))) return -EFAULT; + } - if(Adapter->eNVMType == NVM_EEPROM || Adapter->eNVMType == NVM_FLASH ) { - if(copy_to_user(IoBuffer.OutputBuffer, &Adapter->uiNVMDSDSize, sizeof(UINT))) - return -EFAULT; - } - Status = STATUS_SUCCESS ; - break; + Status = STATUS_SUCCESS; + break; - case IOCTL_BCM_CAL_INIT : + case IOCTL_BCM_CAL_INIT: { + UINT uiSectorSize = 0 ; + if (Adapter->eNVMType == NVM_FLASH) { + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; - { - UINT uiSectorSize = 0 ; - if(Adapter->eNVMType == NVM_FLASH) - { - if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) - return -EFAULT; + if (copy_from_user(&uiSectorSize, IoBuffer.InputBuffer, sizeof(UINT))) + return -EFAULT; - if (copy_from_user(&uiSectorSize, IoBuffer.InputBuffer, sizeof(UINT))) + if ((uiSectorSize < MIN_SECTOR_SIZE) || (uiSectorSize > MAX_SECTOR_SIZE)) { + if (copy_to_user(IoBuffer.OutputBuffer, &Adapter->uiSectorSize, + sizeof(UINT))) + return -EFAULT; + } else { + if (IsFlash2x(Adapter)) { + if (copy_to_user(IoBuffer.OutputBuffer, &Adapter->uiSectorSize, sizeof(UINT))) return -EFAULT; - - if((uiSectorSize < MIN_SECTOR_SIZE) || (uiSectorSize > MAX_SECTOR_SIZE)) - { - if (copy_to_user(IoBuffer.OutputBuffer, &Adapter->uiSectorSize, - sizeof(UINT))) - return -EFAULT; - } - else - { - if(IsFlash2x(Adapter)) - { - if (copy_to_user(IoBuffer.OutputBuffer, - &Adapter->uiSectorSize , - sizeof(UINT))) - return -EFAULT; - } - else - { - if((TRUE == Adapter->bShutStatus) || - (TRUE == Adapter->IdleMode)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Device is in Idle/Shutdown Mode\n"); - return -EACCES; - } - - Adapter->uiSectorSize = uiSectorSize ; - BcmUpdateSectorSize(Adapter,Adapter->uiSectorSize); - } + } else { + if ((TRUE == Adapter->bShutStatus) || (TRUE == Adapter->IdleMode)) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device is in Idle/Shutdown Mode\n"); + return -EACCES; } - Status = STATUS_SUCCESS ; - } - else - { - Status = STATUS_FAILURE; + + Adapter->uiSectorSize = uiSectorSize; + BcmUpdateSectorSize(Adapter, Adapter->uiSectorSize); } } - break; - case IOCTL_BCM_SET_DEBUG : -#ifdef DEBUG - { - USER_BCM_DBG_STATE sUserDebugState; - -// BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "Entered the ioctl %x \n", IOCTL_BCM_SET_DEBUG ); + Status = STATUS_SUCCESS; + } else { + Status = STATUS_FAILURE; + } + } + break; - BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "In SET_DEBUG ioctl\n"); - if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) - return -EFAULT; + case IOCTL_BCM_SET_DEBUG: +#ifdef DEBUG + { + USER_BCM_DBG_STATE sUserDebugState; - if (copy_from_user(&sUserDebugState, IoBuffer.InputBuffer, sizeof(USER_BCM_DBG_STATE))) - return -EFAULT; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "In SET_DEBUG ioctl\n"); + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; + if (copy_from_user(&sUserDebugState, IoBuffer.InputBuffer, sizeof(USER_BCM_DBG_STATE))) + return -EFAULT; - BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "IOCTL_BCM_SET_DEBUG: OnOff=%d Type = 0x%x ", + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "IOCTL_BCM_SET_DEBUG: OnOff=%d Type = 0x%x ", sUserDebugState.OnOff, sUserDebugState.Type); - //sUserDebugState.Subtype <<= 1; - sUserDebugState.Subtype = 1 << sUserDebugState.Subtype; - BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "actual Subtype=0x%x\n", sUserDebugState.Subtype); - - // Update new 'DebugState' in the Adapter - Adapter->stDebugState.type |= sUserDebugState.Type; - /* Subtype: A bitmap of 32 bits for Subtype per Type. - * Valid indexes in 'subtype' array: 1,2,4,8 - * corresponding to valid Type values. Hence we can use the 'Type' field - * as the index value, ignoring the array entries 0,3,5,6,7 ! - */ - if (sUserDebugState.OnOff) - Adapter->stDebugState.subtype[sUserDebugState.Type] |= sUserDebugState.Subtype; - else - Adapter->stDebugState.subtype[sUserDebugState.Type] &= ~sUserDebugState.Subtype; - - BCM_SHOW_DEBUG_BITMAP(Adapter); + /* sUserDebugState.Subtype <<= 1; */ + sUserDebugState.Subtype = 1 << sUserDebugState.Subtype; + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "actual Subtype=0x%x\n", sUserDebugState.Subtype); + + /* Update new 'DebugState' in the Adapter */ + Adapter->stDebugState.type |= sUserDebugState.Type; + /* Subtype: A bitmap of 32 bits for Subtype per Type. + * Valid indexes in 'subtype' array: 1,2,4,8 + * corresponding to valid Type values. Hence we can use the 'Type' field + * as the index value, ignoring the array entries 0,3,5,6,7 ! + */ + if (sUserDebugState.OnOff) + Adapter->stDebugState.subtype[sUserDebugState.Type] |= sUserDebugState.Subtype; + else + Adapter->stDebugState.subtype[sUserDebugState.Type] &= ~sUserDebugState.Subtype; - } + BCM_SHOW_DEBUG_BITMAP(Adapter); + } #endif + break; + + case IOCTL_BCM_NVM_READ: + case IOCTL_BCM_NVM_WRITE: { + NVM_READWRITE stNVMReadWrite; + PUCHAR pReadData = NULL; + ULONG ulDSDMagicNumInUsrBuff = 0; + struct timeval tv0, tv1; + memset(&tv0, 0, sizeof(struct timeval)); + memset(&tv1, 0, sizeof(struct timeval)); + if ((Adapter->eNVMType == NVM_FLASH) && (Adapter->uiFlashLayoutMajorVersion == 0)) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "The Flash Control Section is Corrupted. Hence Rejection on NVM Read/Write\n"); + Status = -EFAULT; break; - case IOCTL_BCM_NVM_READ: - case IOCTL_BCM_NVM_WRITE: - { - NVM_READWRITE stNVMReadWrite; - PUCHAR pReadData = NULL; - ULONG ulDSDMagicNumInUsrBuff = 0; - struct timeval tv0, tv1; - memset(&tv0,0,sizeof(struct timeval)); - memset(&tv1,0,sizeof(struct timeval)); - if((Adapter->eNVMType == NVM_FLASH) && (Adapter->uiFlashLayoutMajorVersion == 0)) - { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,"The Flash Control Section is Corrupted. Hence Rejection on NVM Read/Write\n"); - Status = -EFAULT; - break; - } + } - if(IsFlash2x(Adapter)) - { - if((Adapter->eActiveDSD != DSD0) && - (Adapter->eActiveDSD != DSD1) && - (Adapter->eActiveDSD != DSD2)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"No DSD is active..hence NVM Command is blocked"); - return STATUS_FAILURE ; - } - } + if (IsFlash2x(Adapter)) { + if ((Adapter->eActiveDSD != DSD0) && + (Adapter->eActiveDSD != DSD1) && + (Adapter->eActiveDSD != DSD2)) { - /* Copy Ioctl Buffer structure */ + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "No DSD is active..hence NVM Command is blocked"); + return STATUS_FAILURE ; + } + } - if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) - return -EFAULT; + /* Copy Ioctl Buffer structure */ + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; - if(copy_from_user(&stNVMReadWrite, - (IOCTL_BCM_NVM_READ == cmd) ? IoBuffer.OutputBuffer : IoBuffer.InputBuffer, - sizeof(NVM_READWRITE))) - return -EFAULT; + if (copy_from_user(&stNVMReadWrite, + (IOCTL_BCM_NVM_READ == cmd) ? IoBuffer.OutputBuffer : IoBuffer.InputBuffer, + sizeof(NVM_READWRITE))) + return -EFAULT; - // - // Deny the access if the offset crosses the cal area limit. - // - if((stNVMReadWrite.uiOffset + stNVMReadWrite.uiNumBytes) > Adapter->uiNVMDSDSize) - { - //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Can't allow access beyond NVM Size: 0x%x 0x%x\n", stNVMReadWrite.uiOffset , -// stNVMReadWrite.uiNumBytes); - Status = STATUS_FAILURE; - break; - } + /* + * Deny the access if the offset crosses the cal area limit. + */ - pReadData = kzalloc(stNVMReadWrite.uiNumBytes, GFP_KERNEL); - if(!pReadData) - return -ENOMEM; + if ((stNVMReadWrite.uiOffset + stNVMReadWrite.uiNumBytes) > Adapter->uiNVMDSDSize) { + /* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Can't allow access beyond NVM Size: 0x%x 0x%x\n", stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes); */ + Status = STATUS_FAILURE; + break; + } - if(copy_from_user(pReadData, stNVMReadWrite.pBuffer, - stNVMReadWrite.uiNumBytes)) - { - Status = -EFAULT; - kfree(pReadData); - break; - } + pReadData = kzalloc(stNVMReadWrite.uiNumBytes, GFP_KERNEL); + if (!pReadData) + return -ENOMEM; - do_gettimeofday(&tv0); - if(IOCTL_BCM_NVM_READ == cmd) - { - down(&Adapter->NVMRdmWrmLock); + if (copy_from_user(pReadData, stNVMReadWrite.pBuffer, stNVMReadWrite.uiNumBytes)) { + Status = -EFAULT; + kfree(pReadData); + break; + } - if((Adapter->IdleMode == TRUE) || - (Adapter->bShutStatus ==TRUE) || - (Adapter->bPreparingForLowPowerMode ==TRUE)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n"); - up(&Adapter->NVMRdmWrmLock); - kfree(pReadData); - return -EACCES; - } + do_gettimeofday(&tv0); + if (IOCTL_BCM_NVM_READ == cmd) { + down(&Adapter->NVMRdmWrmLock); - Status = BeceemNVMRead(Adapter, (PUINT)pReadData, - stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes); - - up(&Adapter->NVMRdmWrmLock); - - if(Status != STATUS_SUCCESS) - { - kfree(pReadData); - return Status; - } - if(copy_to_user(stNVMReadWrite.pBuffer,pReadData, stNVMReadWrite.uiNumBytes)) - { - kfree(pReadData); - Status = -EFAULT; - } - } - else - { + if ((Adapter->IdleMode == TRUE) || + (Adapter->bShutStatus == TRUE) || + (Adapter->bPreparingForLowPowerMode == TRUE)) { - down(&Adapter->NVMRdmWrmLock); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Device is in Idle/Shutdown Mode\n"); + up(&Adapter->NVMRdmWrmLock); + kfree(pReadData); + return -EACCES; + } - if((Adapter->IdleMode == TRUE) || - (Adapter->bShutStatus ==TRUE) || - (Adapter->bPreparingForLowPowerMode ==TRUE)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n"); - up(&Adapter->NVMRdmWrmLock); - kfree(pReadData); - return -EACCES; - } + Status = BeceemNVMRead(Adapter, (PUINT)pReadData, stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes); + up(&Adapter->NVMRdmWrmLock); - Adapter->bHeaderChangeAllowed = TRUE ; - if(IsFlash2x(Adapter)) - { - /* - New Requirement:- - DSD section updation will be allowed in two case:- - 1. if DSD sig is present in DSD header means dongle is ok and updation is fruitfull - 2. if point 1 failes then user buff should have DSD sig. this point ensures that if dongle is - corrupted then user space program first modify the DSD header with valid DSD sig so - that this as well as further write may be worthwhile. - - This restriction has been put assuming that if DSD sig is corrupted, DSD - data won't be considered valid. - - - */ - Status = BcmFlash2xCorruptSig(Adapter,Adapter->eActiveDSD); - if(Status != STATUS_SUCCESS) - { - if(( (stNVMReadWrite.uiOffset + stNVMReadWrite.uiNumBytes) != Adapter->uiNVMDSDSize ) || - (stNVMReadWrite.uiNumBytes < SIGNATURE_SIZE)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"DSD Sig is present neither in Flash nor User provided Input.."); - up(&Adapter->NVMRdmWrmLock); - kfree(pReadData); - return Status; - } - - ulDSDMagicNumInUsrBuff = ntohl(*(PUINT)(pReadData + stNVMReadWrite.uiNumBytes - SIGNATURE_SIZE)); - if(ulDSDMagicNumInUsrBuff != DSD_IMAGE_MAGIC_NUMBER) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"DSD Sig is present neither in Flash nor User provided Input.."); - up(&Adapter->NVMRdmWrmLock); - kfree(pReadData); - return Status; - } - } - } - Status = BeceemNVMWrite(Adapter, (PUINT )pReadData, - stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes, stNVMReadWrite.bVerify); - if(IsFlash2x(Adapter)) - BcmFlash2xWriteSig(Adapter,Adapter->eActiveDSD); + if (Status != STATUS_SUCCESS) { + kfree(pReadData); + return Status; + } + + if (copy_to_user(stNVMReadWrite.pBuffer, pReadData, stNVMReadWrite.uiNumBytes)) { + kfree(pReadData); + Status = -EFAULT; + } + } else { + down(&Adapter->NVMRdmWrmLock); - Adapter->bHeaderChangeAllowed = FALSE ; + if ((Adapter->IdleMode == TRUE) || + (Adapter->bShutStatus == TRUE) || + (Adapter->bPreparingForLowPowerMode == TRUE)) { - up(&Adapter->NVMRdmWrmLock); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Device is in Idle/Shutdown Mode\n"); + up(&Adapter->NVMRdmWrmLock); + kfree(pReadData); + return -EACCES; + } + Adapter->bHeaderChangeAllowed = TRUE; + if (IsFlash2x(Adapter)) { + /* + * New Requirement:- + * DSD section updation will be allowed in two case:- + * 1. if DSD sig is present in DSD header means dongle is ok and updation is fruitfull + * 2. if point 1 failes then user buff should have DSD sig. this point ensures that if dongle is + * corrupted then user space program first modify the DSD header with valid DSD sig so + * that this as well as further write may be worthwhile. + * + * This restriction has been put assuming that if DSD sig is corrupted, DSD + * data won't be considered valid. + */ - if(Status != STATUS_SUCCESS) - { + Status = BcmFlash2xCorruptSig(Adapter, Adapter->eActiveDSD); + if (Status != STATUS_SUCCESS) { + if (((stNVMReadWrite.uiOffset + stNVMReadWrite.uiNumBytes) != Adapter->uiNVMDSDSize) || + (stNVMReadWrite.uiNumBytes < SIGNATURE_SIZE)) { + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "DSD Sig is present neither in Flash nor User provided Input.."); + up(&Adapter->NVMRdmWrmLock); + kfree(pReadData); + return Status; + } + + ulDSDMagicNumInUsrBuff = ntohl(*(PUINT)(pReadData + stNVMReadWrite.uiNumBytes - SIGNATURE_SIZE)); + if (ulDSDMagicNumInUsrBuff != DSD_IMAGE_MAGIC_NUMBER) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "DSD Sig is present neither in Flash nor User provided Input.."); + up(&Adapter->NVMRdmWrmLock); kfree(pReadData); return Status; } } - do_gettimeofday(&tv1); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " timetaken by Write/read :%ld msec\n",(tv1.tv_sec - tv0.tv_sec)*1000 +(tv1.tv_usec - tv0.tv_usec)/1000); + } + + Status = BeceemNVMWrite(Adapter, (PUINT)pReadData, stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes, stNVMReadWrite.bVerify); + if (IsFlash2x(Adapter)) + BcmFlash2xWriteSig(Adapter, Adapter->eActiveDSD); + Adapter->bHeaderChangeAllowed = FALSE; + + up(&Adapter->NVMRdmWrmLock); + if (Status != STATUS_SUCCESS) { kfree(pReadData); - Status = STATUS_SUCCESS; + return Status; } - break; - case IOCTL_BCM_FLASH2X_SECTION_READ : - { - - FLASH2X_READWRITE sFlash2xRead = {0}; - PUCHAR pReadBuff = NULL ; - UINT NOB = 0; - UINT BuffSize = 0; - UINT ReadBytes = 0; - UINT ReadOffset = 0; - void __user *OutPutBuff; - - if(IsFlash2x(Adapter) != TRUE) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map"); - return -EINVAL; - } + } - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_FLASH2X_SECTION_READ Called"); - if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) - return -EFAULT; + do_gettimeofday(&tv1); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " timetaken by Write/read :%ld msec\n", (tv1.tv_sec - tv0.tv_sec)*1000 + (tv1.tv_usec - tv0.tv_usec)/1000); - //Reading FLASH 2.x READ structure - if (copy_from_user(&sFlash2xRead, IoBuffer.InputBuffer,sizeof(FLASH2X_READWRITE))) - return -EFAULT; + kfree(pReadData); + Status = STATUS_SUCCESS; + } + break; + + case IOCTL_BCM_FLASH2X_SECTION_READ: { + FLASH2X_READWRITE sFlash2xRead = {0}; + PUCHAR pReadBuff = NULL ; + UINT NOB = 0; + UINT BuffSize = 0; + UINT ReadBytes = 0; + UINT ReadOffset = 0; + void __user *OutPutBuff; + + if (IsFlash2x(Adapter) != TRUE) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Does not have 2.x map"); + return -EINVAL; + } + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_FLASH2X_SECTION_READ Called"); + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.Section :%x" ,sFlash2xRead.Section); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.offset :%x" ,sFlash2xRead.offset); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.numOfBytes :%x" ,sFlash2xRead.numOfBytes); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.bVerify :%x\n" ,sFlash2xRead.bVerify); + /* Reading FLASH 2.x READ structure */ + if (copy_from_user(&sFlash2xRead, IoBuffer.InputBuffer, sizeof(FLASH2X_READWRITE))) + return -EFAULT; - //This was internal to driver for raw read. now it has ben exposed to user space app. - if(validateFlash2xReadWrite(Adapter,&sFlash2xRead) == FALSE) - return STATUS_FAILURE ; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "\nsFlash2xRead.Section :%x", sFlash2xRead.Section); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "\nsFlash2xRead.offset :%x", sFlash2xRead.offset); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "\nsFlash2xRead.numOfBytes :%x", sFlash2xRead.numOfBytes); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "\nsFlash2xRead.bVerify :%x\n", sFlash2xRead.bVerify); - NOB = sFlash2xRead.numOfBytes; - if(NOB > Adapter->uiSectorSize ) - BuffSize = Adapter->uiSectorSize; - else - BuffSize = NOB ; + /* This was internal to driver for raw read. now it has ben exposed to user space app. */ + if (validateFlash2xReadWrite(Adapter, &sFlash2xRead) == FALSE) + return STATUS_FAILURE; - ReadOffset = sFlash2xRead.offset ; - OutPutBuff = IoBuffer.OutputBuffer; + NOB = sFlash2xRead.numOfBytes; + if (NOB > Adapter->uiSectorSize) + BuffSize = Adapter->uiSectorSize; + else + BuffSize = NOB; + ReadOffset = sFlash2xRead.offset ; + OutPutBuff = IoBuffer.OutputBuffer; + pReadBuff = (PCHAR)kzalloc(BuffSize , GFP_KERNEL); - pReadBuff = (PCHAR)kzalloc(BuffSize , GFP_KERNEL); - if(pReadBuff == NULL) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed for Flash 2.x Read Structure"); - return -ENOMEM; - } - down(&Adapter->NVMRdmWrmLock); - - if((Adapter->IdleMode == TRUE) || - (Adapter->bShutStatus ==TRUE) || - (Adapter->bPreparingForLowPowerMode ==TRUE)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n"); - up(&Adapter->NVMRdmWrmLock); - kfree(pReadBuff); - return -EACCES; - } + if (pReadBuff == NULL) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed for Flash 2.x Read Structure"); + return -ENOMEM; + } + down(&Adapter->NVMRdmWrmLock); - while(NOB) - { + if ((Adapter->IdleMode == TRUE) || + (Adapter->bShutStatus == TRUE) || + (Adapter->bPreparingForLowPowerMode == TRUE)) { - if(NOB > Adapter->uiSectorSize ) - ReadBytes = Adapter->uiSectorSize; - else - ReadBytes = NOB; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Device is in Idle/Shutdown Mode\n"); + up(&Adapter->NVMRdmWrmLock); + kfree(pReadBuff); + return -EACCES; + } + while (NOB) { + if (NOB > Adapter->uiSectorSize) + ReadBytes = Adapter->uiSectorSize; + else + ReadBytes = NOB; - //Reading the data from Flash 2.x + /* Reading the data from Flash 2.x */ + Status = BcmFlash2xBulkRead(Adapter, (PUINT)pReadBuff, sFlash2xRead.Section, ReadOffset, ReadBytes); + if (Status) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Flash 2x read err with Status :%d", Status); + break; + } - Status = BcmFlash2xBulkRead(Adapter,(PUINT)pReadBuff,sFlash2xRead.Section,ReadOffset,ReadBytes); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Flash 2x read err with Status :%d", Status); - break ; - } + BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, pReadBuff, ReadBytes); - BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,pReadBuff, ReadBytes); - - Status = copy_to_user(OutPutBuff, pReadBuff,ReadBytes); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Copy to use failed with status :%d", Status); - break; - } - NOB = NOB - ReadBytes; - if(NOB) - { - ReadOffset = ReadOffset + ReadBytes ; - OutPutBuff = OutPutBuff + ReadBytes ; - } + Status = copy_to_user(OutPutBuff, pReadBuff, ReadBytes); + if (Status) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Copy to use failed with status :%d", Status); + break; + } + NOB = NOB - ReadBytes; + if (NOB) { + ReadOffset = ReadOffset + ReadBytes; + OutPutBuff = OutPutBuff + ReadBytes ; + } + } - } - up(&Adapter->NVMRdmWrmLock); - kfree(pReadBuff); - - } - break ; - case IOCTL_BCM_FLASH2X_SECTION_WRITE : - { - FLASH2X_READWRITE sFlash2xWrite = {0}; - PUCHAR pWriteBuff; - void __user *InputAddr; - UINT NOB = 0; - UINT BuffSize = 0; - UINT WriteOffset = 0; - UINT WriteBytes = 0; - - if(IsFlash2x(Adapter) != TRUE) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map"); - return -EINVAL; - } + up(&Adapter->NVMRdmWrmLock); + kfree(pReadBuff); + } + break; + + case IOCTL_BCM_FLASH2X_SECTION_WRITE: { + FLASH2X_READWRITE sFlash2xWrite = {0}; + PUCHAR pWriteBuff; + void __user *InputAddr; + UINT NOB = 0; + UINT BuffSize = 0; + UINT WriteOffset = 0; + UINT WriteBytes = 0; + + if (IsFlash2x(Adapter) != TRUE) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Does not have 2.x map"); + return -EINVAL; + } - //First make this False so that we can enable the Sector Permission Check in BeceemFlashBulkWrite - Adapter->bAllDSDWriteAllow = FALSE; + /* First make this False so that we can enable the Sector Permission Check in BeceemFlashBulkWrite */ + Adapter->bAllDSDWriteAllow = FALSE; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_FLASH2X_SECTION_WRITE Called"); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " IOCTL_BCM_FLASH2X_SECTION_WRITE Called"); - if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) - return -EFAULT; + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; - //Reading FLASH 2.x READ structure - if (copy_from_user(&sFlash2xWrite, IoBuffer.InputBuffer, sizeof(FLASH2X_READWRITE))) - return -EFAULT; + /* Reading FLASH 2.x READ structure */ + if (copy_from_user(&sFlash2xWrite, IoBuffer.InputBuffer, sizeof(FLASH2X_READWRITE))) + return -EFAULT; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.Section :%x" ,sFlash2xWrite.Section); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.offset :%d" ,sFlash2xWrite.offset); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.numOfBytes :%x" ,sFlash2xWrite.numOfBytes); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.bVerify :%x\n" ,sFlash2xWrite.bVerify); - if((sFlash2xWrite.Section != VSA0) && (sFlash2xWrite.Section != VSA1) && - (sFlash2xWrite.Section != VSA2) ) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Only VSA write is allowed"); - return -EINVAL; - } + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "\nsFlash2xRead.Section :%x", sFlash2xWrite.Section); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "\nsFlash2xRead.offset :%d", sFlash2xWrite.offset); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "\nsFlash2xRead.numOfBytes :%x", sFlash2xWrite.numOfBytes); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "\nsFlash2xRead.bVerify :%x\n", sFlash2xWrite.bVerify); - if(validateFlash2xReadWrite(Adapter,&sFlash2xWrite) == FALSE) - return STATUS_FAILURE ; + if ((sFlash2xWrite.Section != VSA0) && (sFlash2xWrite.Section != VSA1) && (sFlash2xWrite.Section != VSA2)) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Only VSA write is allowed"); + return -EINVAL; + } - InputAddr = sFlash2xWrite.pDataBuff; - WriteOffset = sFlash2xWrite.offset ; - NOB = sFlash2xWrite.numOfBytes; + if (validateFlash2xReadWrite(Adapter, &sFlash2xWrite) == FALSE) + return STATUS_FAILURE; - if(NOB > Adapter->uiSectorSize ) - BuffSize = Adapter->uiSectorSize; - else - BuffSize = NOB ; + InputAddr = sFlash2xWrite.pDataBuff; + WriteOffset = sFlash2xWrite.offset; + NOB = sFlash2xWrite.numOfBytes; + + if (NOB > Adapter->uiSectorSize) + BuffSize = Adapter->uiSectorSize; + else + BuffSize = NOB ; + + pWriteBuff = kmalloc(BuffSize, GFP_KERNEL); - pWriteBuff = kmalloc(BuffSize, GFP_KERNEL); - if(pWriteBuff == NULL) - return -ENOMEM; + if (pWriteBuff == NULL) + return -ENOMEM; + /* extracting the remainder of the given offset. */ + WriteBytes = Adapter->uiSectorSize; + if (WriteOffset % Adapter->uiSectorSize) + WriteBytes = Adapter->uiSectorSize - (WriteOffset % Adapter->uiSectorSize); + + if (NOB < WriteBytes) + WriteBytes = NOB; + + down(&Adapter->NVMRdmWrmLock); + + if ((Adapter->IdleMode == TRUE) || + (Adapter->bShutStatus == TRUE) || + (Adapter->bPreparingForLowPowerMode == TRUE)) { + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Device is in Idle/Shutdown Mode\n"); + up(&Adapter->NVMRdmWrmLock); + kfree(pWriteBuff); + return -EACCES; + } - //extracting the remainder of the given offset. - WriteBytes = Adapter->uiSectorSize ; - if(WriteOffset % Adapter->uiSectorSize) - WriteBytes =Adapter->uiSectorSize - (WriteOffset % Adapter->uiSectorSize); - if(NOB < WriteBytes) + BcmFlash2xCorruptSig(Adapter, sFlash2xWrite.Section); + do { + Status = copy_from_user(pWriteBuff, InputAddr, WriteBytes); + if (Status) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy to user failed with status :%d", Status); + break; + } + BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, pWriteBuff, WriteBytes); + + /* Writing the data from Flash 2.x */ + Status = BcmFlash2xBulkWrite(Adapter, (PUINT)pWriteBuff, sFlash2xWrite.Section, WriteOffset, WriteBytes, sFlash2xWrite.bVerify); + + if (Status) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash 2x read err with Status :%d", Status); + break; + } + + NOB = NOB - WriteBytes; + if (NOB) { + WriteOffset = WriteOffset + WriteBytes; + InputAddr = InputAddr + WriteBytes; + if (NOB > Adapter->uiSectorSize) + WriteBytes = Adapter->uiSectorSize; + else WriteBytes = NOB; + } + } while (NOB > 0); - down(&Adapter->NVMRdmWrmLock); + BcmFlash2xWriteSig(Adapter, sFlash2xWrite.Section); + up(&Adapter->NVMRdmWrmLock); + kfree(pWriteBuff); + } + break; - if((Adapter->IdleMode == TRUE) || - (Adapter->bShutStatus ==TRUE) || - (Adapter->bPreparingForLowPowerMode ==TRUE)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n"); - up(&Adapter->NVMRdmWrmLock); - kfree(pWriteBuff); - return -EACCES; - } + case IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP: { + PFLASH2X_BITMAP psFlash2xBitMap; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP Called"); - BcmFlash2xCorruptSig(Adapter,sFlash2xWrite.Section); - do - { - Status = copy_from_user(pWriteBuff,InputAddr,WriteBytes); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Copy to user failed with status :%d", Status); - break ; - } - BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,pWriteBuff,WriteBytes); - //Writing the data from Flash 2.x - Status = BcmFlash2xBulkWrite(Adapter,(PUINT)pWriteBuff,sFlash2xWrite.Section,WriteOffset,WriteBytes,sFlash2xWrite.bVerify); - - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash 2x read err with Status :%d", Status); - break ; - } + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; - NOB = NOB - WriteBytes; - if(NOB) - { - WriteOffset = WriteOffset + WriteBytes ; - InputAddr = InputAddr + WriteBytes ; - if(NOB > Adapter->uiSectorSize ) - WriteBytes = Adapter->uiSectorSize; - else - WriteBytes = NOB; - } + if (IoBuffer.OutputLength != sizeof(FLASH2X_BITMAP)) + return -EINVAL; + psFlash2xBitMap = kzalloc(sizeof(FLASH2X_BITMAP), GFP_KERNEL); + if (psFlash2xBitMap == NULL) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory is not available"); + return -ENOMEM; + } - } while(NOB > 0); - BcmFlash2xWriteSig(Adapter,sFlash2xWrite.Section); - up(&Adapter->NVMRdmWrmLock); - kfree(pWriteBuff); - } - break ; - case IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP : - { + /* Reading the Flash Sectio Bit map */ + down(&Adapter->NVMRdmWrmLock); - PFLASH2X_BITMAP psFlash2xBitMap; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP Called"); + if ((Adapter->IdleMode == TRUE) || + (Adapter->bShutStatus == TRUE) || + (Adapter->bPreparingForLowPowerMode == TRUE)) { - if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) - return -EFAULT; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Device is in Idle/Shutdown Mode\n"); + up(&Adapter->NVMRdmWrmLock); + kfree(psFlash2xBitMap); + return -EACCES; + } - if(IoBuffer.OutputLength != sizeof(FLASH2X_BITMAP)) - return -EINVAL; + BcmGetFlash2xSectionalBitMap(Adapter, psFlash2xBitMap); + up(&Adapter->NVMRdmWrmLock); + if (copy_to_user(IoBuffer.OutputBuffer, psFlash2xBitMap, sizeof(FLASH2X_BITMAP))) + Status = -EFAULT; - psFlash2xBitMap = kzalloc(sizeof(FLASH2X_BITMAP), GFP_KERNEL); - if(psFlash2xBitMap == NULL) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory is not available"); - return -ENOMEM ; - } - //Reading the Flash Sectio Bit map - down(&Adapter->NVMRdmWrmLock); - - if((Adapter->IdleMode == TRUE) || - (Adapter->bShutStatus ==TRUE) || - (Adapter->bPreparingForLowPowerMode ==TRUE)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n"); - up(&Adapter->NVMRdmWrmLock); - kfree(psFlash2xBitMap); - return -EACCES; - } + kfree(psFlash2xBitMap); + } + break; - BcmGetFlash2xSectionalBitMap(Adapter, psFlash2xBitMap); - up(&Adapter->NVMRdmWrmLock); - if (copy_to_user(IoBuffer.OutputBuffer, psFlash2xBitMap, sizeof(FLASH2X_BITMAP))) - Status = -EFAULT; - - kfree(psFlash2xBitMap); - } - break ; - case IOCTL_BCM_SET_ACTIVE_SECTION : - { - FLASH2X_SECTION_VAL eFlash2xSectionVal = 0; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_SET_ACTIVE_SECTION Called"); - - if(IsFlash2x(Adapter) != TRUE) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map"); - return -EINVAL; - } + case IOCTL_BCM_SET_ACTIVE_SECTION: { + FLASH2X_SECTION_VAL eFlash2xSectionVal = 0; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_SET_ACTIVE_SECTION Called"); - Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed"); - return Status; - } + if (IsFlash2x(Adapter) != TRUE) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Does not have 2.x map"); + return -EINVAL; + } - Status = copy_from_user(&eFlash2xSectionVal,IoBuffer.InputBuffer, sizeof(INT)); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of flash section val failed"); - return Status; - } + Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)); + if (Status) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed"); + return Status; + } - down(&Adapter->NVMRdmWrmLock); + Status = copy_from_user(&eFlash2xSectionVal, IoBuffer.InputBuffer, sizeof(INT)); + if (Status) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of flash section val failed"); + return Status; + } - if((Adapter->IdleMode == TRUE) || - (Adapter->bShutStatus ==TRUE) || - (Adapter->bPreparingForLowPowerMode ==TRUE)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n"); - up(&Adapter->NVMRdmWrmLock); - return -EACCES; - } + down(&Adapter->NVMRdmWrmLock); - Status = BcmSetActiveSection(Adapter,eFlash2xSectionVal); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed to make it's priority Highest. Status %d", Status); - } - up(&Adapter->NVMRdmWrmLock); - } - break ; - case IOCTL_BCM_IDENTIFY_ACTIVE_SECTION : - { - //Right Now we are taking care of only DSD - Adapter->bAllDSDWriteAllow = FALSE ; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"IOCTL_BCM_IDENTIFY_ACTIVE_SECTION called"); - - Status = STATUS_SUCCESS ; - } - break ; - case IOCTL_BCM_COPY_SECTION : - { - FLASH2X_COPY_SECTION sCopySectStrut = {0}; - Status = STATUS_SUCCESS; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_COPY_SECTION Called"); - - Adapter->bAllDSDWriteAllow = FALSE ; - if(IsFlash2x(Adapter) != TRUE) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map"); - return -EINVAL; - } + if ((Adapter->IdleMode == TRUE) || + (Adapter->bShutStatus == TRUE) || + (Adapter->bPreparingForLowPowerMode == TRUE)) { - Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed Status :%d", Status); - return Status; - } + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Device is in Idle/Shutdown Mode\n"); + up(&Adapter->NVMRdmWrmLock); + return -EACCES; + } - Status = copy_from_user(&sCopySectStrut, IoBuffer.InputBuffer, sizeof(FLASH2X_COPY_SECTION)); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of Copy_Section_Struct failed with Status :%d", Status); - return Status; - } - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Source SEction :%x", sCopySectStrut.SrcSection); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Destination SEction :%x", sCopySectStrut.DstSection); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "offset :%x", sCopySectStrut.offset); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "NOB :%x", sCopySectStrut.numOfBytes); + Status = BcmSetActiveSection(Adapter, eFlash2xSectionVal); + if (Status) + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Failed to make it's priority Highest. Status %d", Status); + up(&Adapter->NVMRdmWrmLock); + } + break; - if(IsSectionExistInFlash(Adapter,sCopySectStrut.SrcSection) == FALSE) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Source Section<%x> does not exixt in Flash ", sCopySectStrut.SrcSection); - return -EINVAL; - } + case IOCTL_BCM_IDENTIFY_ACTIVE_SECTION: { + /* Right Now we are taking care of only DSD */ + Adapter->bAllDSDWriteAllow = FALSE; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_IDENTIFY_ACTIVE_SECTION called"); + Status = STATUS_SUCCESS; + } + break; - if(IsSectionExistInFlash(Adapter,sCopySectStrut.DstSection) == FALSE) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Destinatio Section<%x> does not exixt in Flash ", sCopySectStrut.DstSection); - return -EINVAL; - } + case IOCTL_BCM_COPY_SECTION: { + FLASH2X_COPY_SECTION sCopySectStrut = {0}; + Status = STATUS_SUCCESS; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_COPY_SECTION Called"); - if(sCopySectStrut.SrcSection == sCopySectStrut.DstSection) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Source and Destination section should be different"); - return -EINVAL; - } + Adapter->bAllDSDWriteAllow = FALSE; + if (IsFlash2x(Adapter) != TRUE) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Does not have 2.x map"); + return -EINVAL; + } - down(&Adapter->NVMRdmWrmLock); + Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)); + if (Status) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed Status :%d", Status); + return Status; + } - if((Adapter->IdleMode == TRUE) || - (Adapter->bShutStatus ==TRUE) || - (Adapter->bPreparingForLowPowerMode ==TRUE)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n"); - up(&Adapter->NVMRdmWrmLock); - return -EACCES; - } + Status = copy_from_user(&sCopySectStrut, IoBuffer.InputBuffer, sizeof(FLASH2X_COPY_SECTION)); + if (Status) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of Copy_Section_Struct failed with Status :%d", Status); + return Status; + } - if(sCopySectStrut.SrcSection == ISO_IMAGE1 || sCopySectStrut.SrcSection == ISO_IMAGE2) - { - if(IsNonCDLessDevice(Adapter)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Device is Non-CDLess hence won't have ISO !!"); - Status = -EINVAL ; - } - else if(sCopySectStrut.numOfBytes == 0) - { - Status = BcmCopyISO(Adapter,sCopySectStrut); - } - else - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Partial Copy of ISO section is not Allowed.."); - Status = STATUS_FAILURE ; - } - up(&Adapter->NVMRdmWrmLock); - return Status; - } + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Source SEction :%x", sCopySectStrut.SrcSection); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Destination SEction :%x", sCopySectStrut.DstSection); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "offset :%x", sCopySectStrut.offset); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "NOB :%x", sCopySectStrut.numOfBytes); - Status = BcmCopySection(Adapter, sCopySectStrut.SrcSection, - sCopySectStrut.DstSection,sCopySectStrut.offset,sCopySectStrut.numOfBytes); - up(&Adapter->NVMRdmWrmLock); - } - break ; - case IOCTL_BCM_GET_FLASH_CS_INFO : - { - Status = STATUS_SUCCESS; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " IOCTL_BCM_GET_FLASH_CS_INFO Called"); - - Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed"); - break; - } - if(Adapter->eNVMType != NVM_FLASH) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Connected device does not have flash"); - Status = -EINVAL; - break; - } - if(IsFlash2x(Adapter) == TRUE) - { + if (IsSectionExistInFlash(Adapter, sCopySectStrut.SrcSection) == FALSE) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Source Section<%x> does not exixt in Flash ", sCopySectStrut.SrcSection); + return -EINVAL; + } - if(IoBuffer.OutputLength < sizeof(FLASH2X_CS_INFO)) - return -EINVAL; + if (IsSectionExistInFlash(Adapter, sCopySectStrut.DstSection) == FALSE) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Destinatio Section<%x> does not exixt in Flash ", sCopySectStrut.DstSection); + return -EINVAL; + } - if (copy_to_user(IoBuffer.OutputBuffer, Adapter->psFlash2xCSInfo, sizeof(FLASH2X_CS_INFO))) - return -EFAULT; - } - else - { - if(IoBuffer.OutputLength < sizeof(FLASH_CS_INFO)) - return -EINVAL; + if (sCopySectStrut.SrcSection == sCopySectStrut.DstSection) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Source and Destination section should be different"); + return -EINVAL; + } - if (copy_to_user(IoBuffer.OutputBuffer, Adapter->psFlashCSInfo, sizeof(FLASH_CS_INFO))) - return -EFAULT; + down(&Adapter->NVMRdmWrmLock); - } - } - break ; - case IOCTL_BCM_SELECT_DSD : - { - UINT SectOfset = 0; - FLASH2X_SECTION_VAL eFlash2xSectionVal; - eFlash2xSectionVal = NO_SECTION_VAL ; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " IOCTL_BCM_SELECT_DSD Called"); - - if(IsFlash2x(Adapter) != TRUE) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map"); - return -EINVAL; - } + if ((Adapter->IdleMode == TRUE) || + (Adapter->bShutStatus == TRUE) || + (Adapter->bPreparingForLowPowerMode == TRUE)) { - Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed"); - return Status; - } - Status = copy_from_user(&eFlash2xSectionVal, IoBuffer.InputBuffer, sizeof(INT)); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of flash section val failed"); - return Status; - } + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Device is in Idle/Shutdown Mode\n"); + up(&Adapter->NVMRdmWrmLock); + return -EACCES; + } - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Read Section :%d", eFlash2xSectionVal); - if((eFlash2xSectionVal != DSD0) && - (eFlash2xSectionVal != DSD1) && - (eFlash2xSectionVal != DSD2) ) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Passed section<%x> is not DSD section", eFlash2xSectionVal); - return STATUS_FAILURE ; - } + if (sCopySectStrut.SrcSection == ISO_IMAGE1 || sCopySectStrut.SrcSection == ISO_IMAGE2) { + if (IsNonCDLessDevice(Adapter)) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device is Non-CDLess hence won't have ISO !!"); + Status = -EINVAL; + } else if (sCopySectStrut.numOfBytes == 0) { + Status = BcmCopyISO(Adapter, sCopySectStrut); + } else { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Partial Copy of ISO section is not Allowed.."); + Status = STATUS_FAILURE; + } + up(&Adapter->NVMRdmWrmLock); + return Status; + } - SectOfset= BcmGetSectionValStartOffset(Adapter,eFlash2xSectionVal); - if(SectOfset == INVALID_OFFSET) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Provided Section val <%d> does not exixt in Flash 2.x", eFlash2xSectionVal); - return -EINVAL; - } + Status = BcmCopySection(Adapter, sCopySectStrut.SrcSection, + sCopySectStrut.DstSection, sCopySectStrut.offset, sCopySectStrut.numOfBytes); + up(&Adapter->NVMRdmWrmLock); + } + break; - Adapter->bAllDSDWriteAllow = TRUE ; - - Adapter->ulFlashCalStart = SectOfset ; - Adapter->eActiveDSD = eFlash2xSectionVal; - } - Status = STATUS_SUCCESS ; - break; - - case IOCTL_BCM_NVM_RAW_READ : - { - - NVM_READWRITE stNVMRead; - INT NOB ; - INT BuffSize ; - INT ReadOffset = 0; - UINT ReadBytes = 0 ; - PUCHAR pReadBuff; - void __user *OutPutBuff; - - if(Adapter->eNVMType != NVM_FLASH) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"NVM TYPE is not Flash "); - return -EINVAL ; - } + case IOCTL_BCM_GET_FLASH_CS_INFO: { + Status = STATUS_SUCCESS; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " IOCTL_BCM_GET_FLASH_CS_INFO Called"); - /* Copy Ioctl Buffer structure */ - if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copy_from_user 1 failed\n"); - Status = -EFAULT; - break; - } + Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)); + if (Status) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed"); + break; + } - if(copy_from_user(&stNVMRead, IoBuffer.OutputBuffer,sizeof(NVM_READWRITE))) - return -EFAULT; + if (Adapter->eNVMType != NVM_FLASH) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Connected device does not have flash"); + Status = -EINVAL; + break; + } - NOB = stNVMRead.uiNumBytes; - //In Raw-Read max Buff size : 64MB + if (IsFlash2x(Adapter) == TRUE) { + if (IoBuffer.OutputLength < sizeof(FLASH2X_CS_INFO)) + return -EINVAL; - if(NOB > DEFAULT_BUFF_SIZE) - BuffSize = DEFAULT_BUFF_SIZE; - else - BuffSize = NOB ; + if (copy_to_user(IoBuffer.OutputBuffer, Adapter->psFlash2xCSInfo, sizeof(FLASH2X_CS_INFO))) + return -EFAULT; + } else { + if (IoBuffer.OutputLength < sizeof(FLASH_CS_INFO)) + return -EINVAL; - ReadOffset = stNVMRead.uiOffset; - OutPutBuff = stNVMRead.pBuffer; + if (copy_to_user(IoBuffer.OutputBuffer, Adapter->psFlashCSInfo, sizeof(FLASH_CS_INFO))) + return -EFAULT; + } + } + break; - pReadBuff = kzalloc(BuffSize , GFP_KERNEL); - if(pReadBuff == NULL) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed for Flash 2.x Read Structure"); - Status = -ENOMEM; - break; - } - down(&Adapter->NVMRdmWrmLock); - - if((Adapter->IdleMode == TRUE) || - (Adapter->bShutStatus ==TRUE) || - (Adapter->bPreparingForLowPowerMode ==TRUE)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n"); - kfree(pReadBuff); - up(&Adapter->NVMRdmWrmLock); - return -EACCES; - } + case IOCTL_BCM_SELECT_DSD: { + UINT SectOfset = 0; + FLASH2X_SECTION_VAL eFlash2xSectionVal; + eFlash2xSectionVal = NO_SECTION_VAL; + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_SELECT_DSD Called"); - Adapter->bFlashRawRead = TRUE ; - while(NOB) - { - if(NOB > DEFAULT_BUFF_SIZE ) - ReadBytes = DEFAULT_BUFF_SIZE; - else - ReadBytes = NOB; - - //Reading the data from Flash 2.x - Status = BeceemNVMRead(Adapter,(PUINT)pReadBuff,ReadOffset,ReadBytes); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash 2x read err with Status :%d", Status); - break; - } + if (IsFlash2x(Adapter) != TRUE) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash Does not have 2.x map"); + return -EINVAL; + } - BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,pReadBuff,ReadBytes); - - Status = copy_to_user(OutPutBuff, pReadBuff,ReadBytes); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Copy to use failed with status :%d", Status); - break; - } - NOB = NOB - ReadBytes; - if(NOB) - { - ReadOffset = ReadOffset + ReadBytes ; - OutPutBuff = OutPutBuff + ReadBytes ; - } + Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)); + if (Status) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed"); + return Status; + } + Status = copy_from_user(&eFlash2xSectionVal, IoBuffer.InputBuffer, sizeof(INT)); + if (Status) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of flash section val failed"); + return Status; + } - } - Adapter->bFlashRawRead = FALSE ; - up(&Adapter->NVMRdmWrmLock); - kfree(pReadBuff); - break ; - } - - case IOCTL_BCM_CNTRLMSG_MASK: - { - ULONG RxCntrlMsgBitMask = 0 ; - - /* Copy Ioctl Buffer structure */ - Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"copy of Ioctl buffer is failed from user space"); - Status = -EFAULT; - break; - } + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Read Section :%d", eFlash2xSectionVal); + if ((eFlash2xSectionVal != DSD0) && + (eFlash2xSectionVal != DSD1) && + (eFlash2xSectionVal != DSD2)) { - if (IoBuffer.InputLength != sizeof(unsigned long)) { - Status = -EINVAL; - break; - } + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Passed section<%x> is not DSD section", eFlash2xSectionVal); + return STATUS_FAILURE; + } - Status = copy_from_user(&RxCntrlMsgBitMask, IoBuffer.InputBuffer, IoBuffer.InputLength); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"copy of control bit mask failed from user space"); - Status = -EFAULT; - break; - } - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\n Got user defined cntrl msg bit mask :%lx", RxCntrlMsgBitMask); - pTarang->RxCntrlMsgBitMask = RxCntrlMsgBitMask ; - } - break; - case IOCTL_BCM_GET_DEVICE_DRIVER_INFO: - { - DEVICE_DRIVER_INFO DevInfo; - - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Called IOCTL_BCM_GET_DEVICE_DRIVER_INFO\n"); - - DevInfo.MaxRDMBufferSize = BUFFER_4K; - DevInfo.u32DSDStartOffset = EEPROM_CALPARAM_START; - DevInfo.u32RxAlignmentCorrection = 0; - DevInfo.u32NVMType = Adapter->eNVMType; - DevInfo.u32InterfaceType = BCM_USB; - - if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) - return -EFAULT; + SectOfset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectionVal); + if (SectOfset == INVALID_OFFSET) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Provided Section val <%d> does not exixt in Flash 2.x", eFlash2xSectionVal); + return -EINVAL; + } - if(IoBuffer.OutputLength < sizeof(DevInfo)) - return -EINVAL; + Adapter->bAllDSDWriteAllow = TRUE; + Adapter->ulFlashCalStart = SectOfset; + Adapter->eActiveDSD = eFlash2xSectionVal; + } + Status = STATUS_SUCCESS; + break; + + case IOCTL_BCM_NVM_RAW_READ: { + NVM_READWRITE stNVMRead; + INT NOB ; + INT BuffSize ; + INT ReadOffset = 0; + UINT ReadBytes = 0 ; + PUCHAR pReadBuff; + void __user *OutPutBuff; + + if (Adapter->eNVMType != NVM_FLASH) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "NVM TYPE is not Flash"); + return -EINVAL; + } - if (copy_to_user(IoBuffer.OutputBuffer, &DevInfo, sizeof(DevInfo))) - return -EFAULT; - } - break ; + /* Copy Ioctl Buffer structure */ + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "copy_from_user 1 failed\n"); + Status = -EFAULT; + break; + } - case IOCTL_BCM_TIME_SINCE_NET_ENTRY: - { - ST_TIME_ELAPSED stTimeElapsedSinceNetEntry = {0}; + if (copy_from_user(&stNVMRead, IoBuffer.OutputBuffer, sizeof(NVM_READWRITE))) + return -EFAULT; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"IOCTL_BCM_TIME_SINCE_NET_ENTRY called"); + NOB = stNVMRead.uiNumBytes; + /* In Raw-Read max Buff size : 64MB */ - if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) - return -EFAULT; + if (NOB > DEFAULT_BUFF_SIZE) + BuffSize = DEFAULT_BUFF_SIZE; + else + BuffSize = NOB; - if(IoBuffer.OutputLength < sizeof(ST_TIME_ELAPSED)) - return -EINVAL; + ReadOffset = stNVMRead.uiOffset; + OutPutBuff = stNVMRead.pBuffer; - stTimeElapsedSinceNetEntry.ul64TimeElapsedSinceNetEntry = get_seconds() - Adapter->liTimeSinceLastNetEntry; + pReadBuff = kzalloc(BuffSize , GFP_KERNEL); + if (pReadBuff == NULL) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Memory allocation failed for Flash 2.x Read Structure"); + Status = -ENOMEM; + break; + } + down(&Adapter->NVMRdmWrmLock); - if (copy_to_user(IoBuffer.OutputBuffer, &stTimeElapsedSinceNetEntry, sizeof(ST_TIME_ELAPSED))) - return -EFAULT; + if ((Adapter->IdleMode == TRUE) || + (Adapter->bShutStatus == TRUE) || + (Adapter->bPreparingForLowPowerMode == TRUE)) { + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Device is in Idle/Shutdown Mode\n"); + kfree(pReadBuff); + up(&Adapter->NVMRdmWrmLock); + return -EACCES; + } + + Adapter->bFlashRawRead = TRUE; + + while (NOB) { + if (NOB > DEFAULT_BUFF_SIZE) + ReadBytes = DEFAULT_BUFF_SIZE; + else + ReadBytes = NOB; + + /* Reading the data from Flash 2.x */ + Status = BeceemNVMRead(Adapter, (PUINT)pReadBuff, ReadOffset, ReadBytes); + if (Status) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Flash 2x read err with Status :%d", Status); + break; + } + + BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, pReadBuff, ReadBytes); + Status = copy_to_user(OutPutBuff, pReadBuff, ReadBytes); + if (Status) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy to use failed with status :%d", Status); + break; + } + NOB = NOB - ReadBytes; + if (NOB) { + ReadOffset = ReadOffset + ReadBytes; + OutPutBuff = OutPutBuff + ReadBytes; } + } + Adapter->bFlashRawRead = FALSE; + up(&Adapter->NVMRdmWrmLock); + kfree(pReadBuff); + break; + } + + case IOCTL_BCM_CNTRLMSG_MASK: { + ULONG RxCntrlMsgBitMask = 0; + + /* Copy Ioctl Buffer structure */ + Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)); + if (Status) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "copy of Ioctl buffer is failed from user space"); + Status = -EFAULT; break; + } - case IOCTL_CLOSE_NOTIFICATION: - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"IOCTL_CLOSE_NOTIFICATION"); + if (IoBuffer.InputLength != sizeof(unsigned long)) { + Status = -EINVAL; break; + } - default: - pr_info(DRV_NAME ": unknown ioctl cmd=%#x\n", cmd); - Status = STATUS_FAILURE; + Status = copy_from_user(&RxCntrlMsgBitMask, IoBuffer.InputBuffer, IoBuffer.InputLength); + if (Status) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "copy of control bit mask failed from user space"); + Status = -EFAULT; break; + } + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "\n Got user defined cntrl msg bit mask :%lx", RxCntrlMsgBitMask); + pTarang->RxCntrlMsgBitMask = RxCntrlMsgBitMask; + } + break; + + case IOCTL_BCM_GET_DEVICE_DRIVER_INFO: { + DEVICE_DRIVER_INFO DevInfo; + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Called IOCTL_BCM_GET_DEVICE_DRIVER_INFO\n"); + + DevInfo.MaxRDMBufferSize = BUFFER_4K; + DevInfo.u32DSDStartOffset = EEPROM_CALPARAM_START; + DevInfo.u32RxAlignmentCorrection = 0; + DevInfo.u32NVMType = Adapter->eNVMType; + DevInfo.u32InterfaceType = BCM_USB; + + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; + + if (IoBuffer.OutputLength < sizeof(DevInfo)) + return -EINVAL; + + if (copy_to_user(IoBuffer.OutputBuffer, &DevInfo, sizeof(DevInfo))) + return -EFAULT; + } + break; + + case IOCTL_BCM_TIME_SINCE_NET_ENTRY: { + ST_TIME_ELAPSED stTimeElapsedSinceNetEntry = {0}; + + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_TIME_SINCE_NET_ENTRY called"); + + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; + + if (IoBuffer.OutputLength < sizeof(ST_TIME_ELAPSED)) + return -EINVAL; + + stTimeElapsedSinceNetEntry.ul64TimeElapsedSinceNetEntry = get_seconds() - Adapter->liTimeSinceLastNetEntry; + + if (copy_to_user(IoBuffer.OutputBuffer, &stTimeElapsedSinceNetEntry, sizeof(ST_TIME_ELAPSED))) + return -EFAULT; + } + break; + + case IOCTL_CLOSE_NOTIFICATION: + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_CLOSE_NOTIFICATION"); + break; + + default: + pr_info(DRV_NAME ": unknown ioctl cmd=%#x\n", cmd); + Status = STATUS_FAILURE; + break; } return Status; } @@ -2107,8 +1976,6 @@ static const struct file_operations bcm_fops = { .llseek = no_llseek, }; -extern struct class *bcm_class; - int register_control_device_interface(PMINI_ADAPTER Adapter) { @@ -2122,8 +1989,8 @@ int register_control_device_interface(PMINI_ADAPTER Adapter) } Adapter->pstCreatedClassDevice = device_create(bcm_class, NULL, - MKDEV(Adapter->major, 0), - Adapter, DEV_NAME); + MKDEV(Adapter->major, 0), + Adapter, DEV_NAME); if (IS_ERR(Adapter->pstCreatedClassDevice)) { pr_err(DRV_NAME ": class device create failed\n"); @@ -2141,3 +2008,4 @@ void unregister_control_device_interface(PMINI_ADAPTER Adapter) unregister_chrdev(Adapter->major, DEV_NAME); } } + diff --git a/drivers/staging/bcm/Macros.h b/drivers/staging/bcm/Macros.h index 916bebb..46ed99c 100644 --- a/drivers/staging/bcm/Macros.h +++ b/drivers/staging/bcm/Macros.h @@ -1,17 +1,17 @@ /************************************* -* Macros.h +* Macros.h **************************************/ -#ifndef __MACROS_H__ +#ifndef __MACROS_H__ #define __MACROS_H__ -#define TX_TIMER_PERIOD 10 //10 msec +#define TX_TIMER_PERIOD 10 /*10 msec*/ #define MAX_CLASSIFIERS 100 -//#define MAX_CLASSIFIERS_PER_SF 20 +/* #define MAX_CLASSIFIERS_PER_SF 20 */ #define MAX_TARGET_DSX_BUFFERS 24 -#define MAX_CNTRL_PKTS 100 -#define MAX_DATA_PKTS 200 -#define MAX_ETH_SIZE 1536 +#define MAX_CNTRL_PKTS 100 +#define MAX_DATA_PKTS 200 +#define MAX_ETH_SIZE 1536 #define MAX_CNTL_PKT_SIZE 2048 #define MTU_SIZE 1400 @@ -20,102 +20,102 @@ #define MAC_ADDR_REGISTER 0xbf60d000 -///////////Quality of Service/////////////////////////// -#define NO_OF_QUEUES 17 -#define HiPriority NO_OF_QUEUES-1 -#define LowPriority 0 -#define BE 2 -#define rtPS 4 -#define ERTPS 5 -#define UGS 6 - -#define BE_BUCKET_SIZE 1024*1024*100 //32kb -#define rtPS_BUCKET_SIZE 1024*1024*100 //8kb -#define MAX_ALLOWED_RATE 1024*1024*100 -#define TX_PACKET_THRESHOLD 10 -#define XSECONDS 1*HZ -#define DSC_ACTIVATE_REQUEST 248 -#define QUEUE_DEPTH_OFFSET 0x1fc01000 -#define MAX_DEVICE_DESC_SIZE 2040 -#define MAX_CTRL_QUEUE_LEN 100 -#define MAX_APP_QUEUE_LEN 200 -#define MAX_LATENCY_ALLOWED 0xFFFFFFFF -#define DEFAULT_UG_INTERVAL 250 -#define DEFAULT_UGI_FACTOR 4 - -#define DEFAULT_PERSFCOUNT 60 -#define MAX_CONNECTIONS 10 -#define MAX_CLASS_NAME_LENGTH 32 - -#define ETH_LENGTH_OF_ADDRESS 6 -#define MAX_MULTICAST_ADDRESSES 32 -#define IP_LENGTH_OF_ADDRESS 4 - -#define IP_PACKET_ONLY_MODE 0 -#define ETH_PACKET_TUNNELING_MODE 1 - -////////////Link Request////////////// -#define SET_MAC_ADDRESS_REQUEST 0 -#define SYNC_UP_REQUEST 1 -#define SYNCED_UP 2 -#define LINK_UP_REQUEST 3 -#define LINK_CONNECTED 4 -#define SYNC_UP_NOTIFICATION 2 -#define LINK_UP_NOTIFICATION 4 +/* Quality of Service */ +#define NO_OF_QUEUES 17 +#define HiPriority (NO_OF_QUEUES-1) +#define LowPriority 0 +#define BE 2 +#define rtPS 4 +#define ERTPS 5 +#define UGS 6 + +#define BE_BUCKET_SIZE (1024*1024*100) /* 32kb */ +#define rtPS_BUCKET_SIZE (1024*1024*100) /* 8kb */ +#define MAX_ALLOWED_RATE (1024*1024*100) +#define TX_PACKET_THRESHOLD 10 +#define XSECONDS (1*HZ) +#define DSC_ACTIVATE_REQUEST 248 +#define QUEUE_DEPTH_OFFSET 0x1fc01000 +#define MAX_DEVICE_DESC_SIZE 2040 +#define MAX_CTRL_QUEUE_LEN 100 +#define MAX_APP_QUEUE_LEN 200 +#define MAX_LATENCY_ALLOWED 0xFFFFFFFF +#define DEFAULT_UG_INTERVAL 250 +#define DEFAULT_UGI_FACTOR 4 + +#define DEFAULT_PERSFCOUNT 60 +#define MAX_CONNECTIONS 10 +#define MAX_CLASS_NAME_LENGTH 32 + +#define ETH_LENGTH_OF_ADDRESS 6 +#define MAX_MULTICAST_ADDRESSES 32 +#define IP_LENGTH_OF_ADDRESS 4 + +#define IP_PACKET_ONLY_MODE 0 +#define ETH_PACKET_TUNNELING_MODE 1 + +/* Link Request */ +#define SET_MAC_ADDRESS_REQUEST 0 +#define SYNC_UP_REQUEST 1 +#define SYNCED_UP 2 +#define LINK_UP_REQUEST 3 +#define LINK_CONNECTED 4 +#define SYNC_UP_NOTIFICATION 2 +#define LINK_UP_NOTIFICATION 4 #define LINK_NET_ENTRY 0x0002 -#define HMC_STATUS 0x0004 +#define HMC_STATUS 0x0004 #define LINK_UP_CONTROL_REQ 0x83 #define STATS_POINTER_REQ_STATUS 0x86 #define NETWORK_ENTRY_REQ_PAYLOAD 198 -#define LINK_DOWN_REQ_PAYLOAD 226 +#define LINK_DOWN_REQ_PAYLOAD 226 #define SYNC_UP_REQ_PAYLOAD 228 -#define STATISTICS_POINTER_REQ 237 +#define STATISTICS_POINTER_REQ 237 #define LINK_UP_REQ_PAYLOAD 245 #define LINK_UP_ACK 246 #define STATS_MSG_SIZE 4 #define INDEX_TO_DATA 4 -#define GO_TO_IDLE_MODE_PAYLOAD 210 -#define COME_UP_FROM_IDLE_MODE_PAYLOAD 211 -#define IDLE_MODE_SF_UPDATE_MSG 187 +#define GO_TO_IDLE_MODE_PAYLOAD 210 +#define COME_UP_FROM_IDLE_MODE_PAYLOAD 211 +#define IDLE_MODE_SF_UPDATE_MSG 187 -#define SKB_RESERVE_ETHERNET_HEADER 16 -#define SKB_RESERVE_PHS_BYTES 32 +#define SKB_RESERVE_ETHERNET_HEADER 16 +#define SKB_RESERVE_PHS_BYTES 32 -#define IP_PACKET_ONLY_MODE 0 -#define ETH_PACKET_TUNNELING_MODE 1 +#define IP_PACKET_ONLY_MODE 0 +#define ETH_PACKET_TUNNELING_MODE 1 -#define ETH_CS_802_3 1 -#define ETH_CS_802_1Q_VLAN 3 -#define IPV4_CS 1 -#define IPV6_CS 2 -#define ETH_CS_MASK 0x3f +#define ETH_CS_802_3 1 +#define ETH_CS_802_1Q_VLAN 3 +#define IPV4_CS 1 +#define IPV6_CS 2 +#define ETH_CS_MASK 0x3f /** \brief Validity bit maps for TLVs in packet classification rule */ -#define PKT_CLASSIFICATION_USER_PRIORITY_VALID 0 -#define PKT_CLASSIFICATION_VLANID_VALID 1 +#define PKT_CLASSIFICATION_USER_PRIORITY_VALID 0 +#define PKT_CLASSIFICATION_VLANID_VALID 1 #ifndef MIN -#define MIN(_a, _b) ((_a) < (_b)? (_a): (_b)) +#define MIN(_a, _b) ((_a) < (_b) ? (_a) : (_b)) #endif /*Leader related terms */ -#define LEADER_STATUS 0x00 -#define LEADER_STATUS_TCP_ACK 0x1 -#define LEADER_SIZE sizeof(LEADER) -#define MAC_ADDR_REQ_SIZE sizeof(PACKETTOSEND) -#define SS_INFO_REQ_SIZE sizeof(PACKETTOSEND) -#define CM_REQUEST_SIZE LEADER_SIZE + sizeof(stLocalSFChangeRequest) -#define IDLE_REQ_SIZE sizeof(PACKETTOSEND) +#define LEADER_STATUS 0x00 +#define LEADER_STATUS_TCP_ACK 0x1 +#define LEADER_SIZE sizeof(LEADER) +#define MAC_ADDR_REQ_SIZE sizeof(PACKETTOSEND) +#define SS_INFO_REQ_SIZE sizeof(PACKETTOSEND) +#define CM_REQUEST_SIZE (LEADER_SIZE + sizeof(stLocalSFChangeRequest)) +#define IDLE_REQ_SIZE sizeof(PACKETTOSEND) -#define MAX_TRANSFER_CTRL_BYTE_USB 2 * 1024 +#define MAX_TRANSFER_CTRL_BYTE_USB (2*1024) #define GET_MAILBOX1_REG_REQUEST 0x87 #define GET_MAILBOX1_REG_RESPONSE 0x67 @@ -124,40 +124,40 @@ #define TRANSMIT_NETWORK_DATA 0x00 #define RECEIVED_NETWORK_DATA 0x20 -#define CM_RESPONSES 0xA0 -#define STATUS_RSP 0xA1 -#define LINK_CONTROL_RESP 0xA2 -#define IDLE_MODE_STATUS 0xA3 -#define STATS_POINTER_RESP 0xA6 -#define MGMT_MSG_INFO_SW_STATUS 0xA7 -#define AUTH_SS_HOST_MSG 0xA8 - -#define CM_DSA_ACK_PAYLOAD 247 -#define CM_DSC_ACK_PAYLOAD 248 -#define CM_DSD_ACK_PAYLOAD 249 -#define CM_DSDEACTVATE 250 -#define TOTAL_MASKED_ADDRESS_IN_BYTES 32 - -#define MAC_REQ 0 -#define LINK_RESP 1 -#define RSSI_INDICATION 2 - -#define SS_INFO 4 -#define STATISTICS_INFO 5 -#define CM_INDICATION 6 -#define PARAM_RESP 7 -#define BUFFER_1K 1024 -#define BUFFER_2K BUFFER_1K*2 -#define BUFFER_4K BUFFER_2K*2 -#define BUFFER_8K BUFFER_4K*2 -#define BUFFER_16K BUFFER_8K*2 -#define DOWNLINK_DIR 0 -#define UPLINK_DIR 1 - -#define BCM_SIGNATURE "BECEEM" - - -#define GPIO_OUTPUT_REGISTER 0x0F00003C +#define CM_RESPONSES 0xA0 +#define STATUS_RSP 0xA1 +#define LINK_CONTROL_RESP 0xA2 +#define IDLE_MODE_STATUS 0xA3 +#define STATS_POINTER_RESP 0xA6 +#define MGMT_MSG_INFO_SW_STATUS 0xA7 +#define AUTH_SS_HOST_MSG 0xA8 + +#define CM_DSA_ACK_PAYLOAD 247 +#define CM_DSC_ACK_PAYLOAD 248 +#define CM_DSD_ACK_PAYLOAD 249 +#define CM_DSDEACTVATE 250 +#define TOTAL_MASKED_ADDRESS_IN_BYTES 32 + +#define MAC_REQ 0 +#define LINK_RESP 1 +#define RSSI_INDICATION 2 + +#define SS_INFO 4 +#define STATISTICS_INFO 5 +#define CM_INDICATION 6 +#define PARAM_RESP 7 +#define BUFFER_1K 1024 +#define BUFFER_2K (BUFFER_1K*2) +#define BUFFER_4K (BUFFER_2K*2) +#define BUFFER_8K (BUFFER_4K*2) +#define BUFFER_16K (BUFFER_8K*2) +#define DOWNLINK_DIR 0 +#define UPLINK_DIR 1 + +#define BCM_SIGNATURE "BECEEM" + + +#define GPIO_OUTPUT_REGISTER 0x0F00003C #define BCM_GPIO_OUTPUT_SET_REG 0x0F000040 #define BCM_GPIO_OUTPUT_CLR_REG 0x0F000044 #define GPIO_MODE_REGISTER 0x0F000034 @@ -165,44 +165,43 @@ typedef struct _LINK_STATE { - UCHAR ucLinkStatus; - UCHAR bIdleMode; - UCHAR bShutdownMode; -}LINK_STATE, *PLINK_STATE; + UCHAR ucLinkStatus; + UCHAR bIdleMode; + UCHAR bShutdownMode; +} LINK_STATE, *PLINK_STATE; enum enLinkStatus { - WAIT_FOR_SYNC = 1, - PHY_SYNC_ACHIVED = 2, - LINKUP_IN_PROGRESS = 3, - LINKUP_DONE = 4, - 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 + WAIT_FOR_SYNC = 1, + PHY_SYNC_ACHIVED = 2, + LINKUP_IN_PROGRESS = 3, + LINKUP_DONE = 4, + 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 }; -typedef enum _E_PHS_DSC_ACTION -{ - eAddPHSRule=0, +typedef enum _E_PHS_DSC_ACTION { + eAddPHSRule = 0, eSetPHSRule, eDeletePHSRule, eDeleteAllPHSRules -}E_PHS_DSC_ACTION; +} E_PHS_DSC_ACTION; -#define CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ 0x89 // Host to Mac -#define CM_CONTROL_NEWDSX_MULTICLASSIFIER_RESP 0xA9 // Mac to Host -#define MASK_DISABLE_HEADER_SUPPRESSION 0x10 //0b000010000 -#define MINIMUM_PENDING_DESCRIPTORS 5 +#define CM_CONTROL_NEWDSX_MULTICLASSIFIER_REQ 0x89 /* Host to Mac */ +#define CM_CONTROL_NEWDSX_MULTICLASSIFIER_RESP 0xA9 /* Mac to Host */ +#define MASK_DISABLE_HEADER_SUPPRESSION 0x10 /* 0b000010000 */ +#define MINIMUM_PENDING_DESCRIPTORS 5 #define SHUTDOWN_HOSTINITIATED_REQUESTPAYLOAD 0xCC #define SHUTDOWN_ACK_FROM_DRIVER 0x1 #define SHUTDOWN_NACK_FROM_DRIVER 0x2 -#define LINK_SYNC_UP_SUBTYPE 0x0001 -#define LINK_SYNC_DOWN_SUBTYPE 0x0001 +#define LINK_SYNC_UP_SUBTYPE 0x0001 +#define LINK_SYNC_DOWN_SUBTYPE 0x0001 @@ -226,9 +225,9 @@ typedef enum _E_PHS_DSC_ACTION #define MAX_PENDING_CTRL_PACKET (MAX_CTRL_QUEUE_LEN-10) -#define WIMAX_MAX_MTU (MTU_SIZE + ETH_HLEN) +#define WIMAX_MAX_MTU (MTU_SIZE + ETH_HLEN) #define AUTO_LINKUP_ENABLE 0x2 -#define AUTO_SYNC_DISABLE 0x1 +#define AUTO_SYNC_DISABLE 0x1 #define AUTO_FIRM_DOWNLOAD 0x1 #define SETTLE_DOWN_TIME 50 @@ -242,9 +241,9 @@ typedef enum _E_PHS_DSC_ACTION #define TARGET_CAN_NOT_GO_TO_IDLE_MODE 3 #define IDLE_MODE_PAYLOAD_LENGTH 8 -#define IP_HEADER(Buffer) ((IPHeaderFormat*)(Buffer)) -#define IPV4 4 -#define IP_VERSION(byte) (((byte&0xF0)>>4)) +#define IP_HEADER(Buffer) ((IPHeaderFormat *)(Buffer)) +#define IPV4 4 +#define IP_VERSION(byte) (((byte&0xF0)>>4)) #define SET_MAC_ADDRESS 193 #define SET_MAC_ADDRESS_RESPONSE 236 @@ -263,15 +262,15 @@ typedef enum _E_PHS_DSC_ACTION #define INVALID_QUEUE_INDEX NO_OF_QUEUES -#define INVALID_PID (pid_t)-1 -#define DDR_80_MHZ 0 -#define DDR_100_MHZ 1 -#define DDR_120_MHZ 2 // Additional Frequency for T3LP -#define DDR_133_MHZ 3 -#define DDR_140_MHZ 4 // Not Used (Reserved for future) -#define DDR_160_MHZ 5 // Additional Frequency for T3LP -#define DDR_180_MHZ 6 // Not Used (Reserved for future) -#define DDR_200_MHZ 7 // Not Used (Reserved for future) +#define INVALID_PID ((pid_t)-1) +#define DDR_80_MHZ 0 +#define DDR_100_MHZ 1 +#define DDR_120_MHZ 2 /* Additional Frequency for T3LP */ +#define DDR_133_MHZ 3 +#define DDR_140_MHZ 4 /* Not Used (Reserved for future) */ +#define DDR_160_MHZ 5 /* Additional Frequency for T3LP */ +#define DDR_180_MHZ 6 /* Not Used (Reserved for future) */ +#define DDR_200_MHZ 7 /* Not Used (Reserved for future) */ #define MIPS_200_MHZ 0 #define MIPS_160_MHZ 1 @@ -291,27 +290,27 @@ typedef enum _E_PHS_DSC_ACTION #define EEPROM_REJECT_REG_3 0x0f003008 #define EEPROM_REJECT_REG_4 0x0f003020 #define EEPROM_REJECT_MASK 0x0fffffff -#define VSG_MODE 0x3 +#define VSG_MODE 0x3 /* Idle Mode Related Registers */ #define DEBUG_INTERRUPT_GENERATOR_REGISTOR 0x0F00007C -#define SW_ABORT_IDLEMODE_LOC 0x0FF01FFC +#define SW_ABORT_IDLEMODE_LOC 0x0FF01FFC -#define SW_ABORT_IDLEMODE_PATTERN 0xd0ea1d1e -#define DEVICE_INT_OUT_EP_REG0 0x0F011870 -#define DEVICE_INT_OUT_EP_REG1 0x0F011874 +#define SW_ABORT_IDLEMODE_PATTERN 0xd0ea1d1e +#define DEVICE_INT_OUT_EP_REG0 0x0F011870 +#define DEVICE_INT_OUT_EP_REG1 0x0F011874 #define BIN_FILE "/lib/firmware/macxvi200.bin" #define CFG_FILE "/lib/firmware/macxvi.cfg" #define SF_MAX_ALLOWED_PACKETS_TO_BACKUP 128 -#define MIN_VAL(x,y) ((x)<(y)?(x):(y)) +#define MIN_VAL(x, y) ((x) < (y) ? (x) : (y)) #define MAC_ADDRESS_SIZE 6 #define EEPROM_COMMAND_Q_REG 0x0F003018 #define EEPROM_READ_DATA_Q_REG 0x0F003020 -#define CHIP_ID_REG 0x0F000000 -#define GPIO_MODE_REG 0x0F000034 -#define GPIO_OUTPUT_REG 0x0F00003C -#define WIMAX_MAX_ALLOWED_RATE 1024*1024*50 +#define CHIP_ID_REG 0x0F000000 +#define GPIO_MODE_REG 0x0F000034 +#define GPIO_OUTPUT_REG 0x0F00003C +#define WIMAX_MAX_ALLOWED_RATE (1024*1024*50) #define T3 0xbece0300 #define TARGET_SFID_TXDESC_MAP_LOC 0xBFFFF400 @@ -319,31 +318,29 @@ typedef enum _E_PHS_DSC_ACTION #define RWM_READ 0 #define RWM_WRITE 1 -#define T3LPB 0xbece3300 -#define BCS220_2 0xbece3311 -#define BCS220_2BC 0xBECE3310 -#define BCS250_BC 0xbece3301 -#define BCS220_3 0xbece3321 +#define T3LPB 0xbece3300 +#define BCS220_2 0xbece3311 +#define BCS220_2BC 0xBECE3310 +#define BCS250_BC 0xbece3301 +#define BCS220_3 0xbece3321 -#define HPM_CONFIG_LDO145 0x0F000D54 -#define HPM_CONFIG_MSW 0x0F000D58 +#define HPM_CONFIG_LDO145 0x0F000D54 +#define HPM_CONFIG_MSW 0x0F000D58 #define T3B 0xbece0310 -typedef enum eNVM_TYPE -{ +typedef enum eNVM_TYPE { NVM_AUTODETECT = 0, NVM_EEPROM, NVM_FLASH, NVM_UNKNOWN -}NVM_TYPE; +} NVM_TYPE; -typedef enum ePMU_MODES -{ +typedef enum ePMU_MODES { HYBRID_MODE_7C = 0, INTERNAL_MODE_6 = 1, HYBRID_MODE_6 = 2 -}PMU_MODE; +} PMU_MODE; #define MAX_RDM_WRM_RETIRES 1 @@ -360,4 +357,4 @@ enum eAbortPattern { #define SKB_CB_LATENCY_OFFSET 1 #define SKB_CB_TCPACK_OFFSET 2 -#endif //__MACROS_H__ +#endif /* __MACROS_H__ */ diff --git a/drivers/staging/bcm/headers.h b/drivers/staging/bcm/headers.h index 947d063..da47db8 100644 --- a/drivers/staging/bcm/headers.h +++ b/drivers/staging/bcm/headers.h @@ -74,4 +74,6 @@ #define DRV_VERSION VER_FILEVERSION_STR #define PFX DRV_NAME " " +extern struct class *bcm_class; + #endif diff --git a/drivers/staging/bcm/nvm.c b/drivers/staging/bcm/nvm.c index 4da5b7b..3de0daf 100644 --- a/drivers/staging/bcm/nvm.c +++ b/drivers/staging/bcm/nvm.c @@ -4013,7 +4013,8 @@ INT BcmCopyISO(PMINI_ADAPTER Adapter, FLASH2X_COPY_SECTION sCopySectStrut) if(uiTotalDataToCopy < ISOLength) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Source ISO Section does not have valid signature"); - return STATUS_FAILURE; + Status = STATUS_FAILURE; + goto out; } uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage2Part1End) - @@ -4026,7 +4027,8 @@ INT BcmCopyISO(PMINI_ADAPTER Adapter, FLASH2X_COPY_SECTION sCopySectStrut) if(uiTotalDataToCopy < ISOLength) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Dest ISO Section does not have enough section size"); - return STATUS_FAILURE; + Status = STATUS_FAILURE; + goto out; } uiTotalDataToCopy = ISOLength; @@ -4143,7 +4145,8 @@ INT BcmCopyISO(PMINI_ADAPTER Adapter, FLASH2X_COPY_SECTION sCopySectStrut) if(uiTotalDataToCopy < ISOLength) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Source ISO Section does not have valid signature"); - return STATUS_FAILURE; + Status = STATUS_FAILURE; + goto out; } uiTotalDataToCopy =(Adapter->psFlash2xCSInfo->OffsetISOImage1Part1End) - @@ -4156,7 +4159,8 @@ INT BcmCopyISO(PMINI_ADAPTER Adapter, FLASH2X_COPY_SECTION sCopySectStrut) if(uiTotalDataToCopy < ISOLength) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"error as Dest ISO Section does not have enough section size"); - return STATUS_FAILURE; + Status = STATUS_FAILURE; + goto out; } uiTotalDataToCopy = ISOLength; @@ -4257,6 +4261,7 @@ INT BcmCopyISO(PMINI_ADAPTER Adapter, FLASH2X_COPY_SECTION sCopySectStrut) } +out: kfree(Buff); return Status; diff --git a/drivers/staging/brcm80211/Kconfig b/drivers/staging/brcm80211/Kconfig index 379cf16..59e9c85 100644 --- a/drivers/staging/brcm80211/Kconfig +++ b/drivers/staging/brcm80211/Kconfig @@ -7,10 +7,12 @@ config BRCMSMAC default n depends on PCI depends on WLAN && MAC80211 - depends on X86 || MIPS + depends on BCMA=n select BRCMUTIL select FW_LOADER select CRC_CCITT + select CRC8 + select CORDIC ---help--- This module adds support for PCIe wireless adapters based on Broadcom IEEE802.11n SoftMAC chipsets. If you choose to build a module, it'll @@ -21,11 +23,8 @@ config BRCMFMAC default n depends on MMC depends on WLAN && CFG80211 - depends on X86 || MIPS select BRCMUTIL select FW_LOADER - select WIRELESS_EXT - select WEXT_PRIV ---help--- This module adds support for embedded wireless adapters based on Broadcom IEEE802.11n FullMAC chipsets. This driver uses the kernel's diff --git a/drivers/staging/brcm80211/Makefile b/drivers/staging/brcm80211/Makefile index 8b01f5e..f41c047 100644 --- a/drivers/staging/brcm80211/Makefile +++ b/drivers/staging/brcm80211/Makefile @@ -16,7 +16,6 @@ # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # common flags -subdir-ccflags-y := -DBCMDMA32 subdir-ccflags-$(CONFIG_BRCMDBG) += -DBCMDBG obj-$(CONFIG_BRCMUTIL) += brcmutil/ diff --git a/drivers/staging/brcm80211/TODO b/drivers/staging/brcm80211/TODO index e2e2ef9..7f68762 100644 --- a/drivers/staging/brcm80211/TODO +++ b/drivers/staging/brcm80211/TODO @@ -4,10 +4,6 @@ Bugs ==== - none known at this moment -brcmfmac -===================== -- ASSERTS deprecated in mainline, replace by warning + error handling - brcm80211 info page ===================== http://linuxwireless.org/en/users/Drivers/brcm80211 diff --git a/drivers/staging/brcm80211/brcmfmac/Makefile b/drivers/staging/brcm80211/brcmfmac/Makefile index da3c805..826a2ba 100644 --- a/drivers/staging/brcm80211/brcmfmac/Makefile +++ b/drivers/staging/brcm80211/brcmfmac/Makefile @@ -15,11 +15,6 @@ # OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -ccflags-y := \ - -DBRCMF_FIRSTREAD=64 \ - -DBRCMF_SDALIGN=64 \ - -DMAX_HDR_READ=64 - ccflags-$(CONFIG_BRCMDBG) += -DSHOW_EVENTS ccflags-y += \ diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh.c index f4e72ed..8448b8b 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh.c @@ -21,6 +21,9 @@ #include <linux/pci_ids.h> #include <linux/sched.h> #include <linux/completion.h> +#include <linux/mmc/sdio.h> +#include <linux/mmc/sdio_func.h> +#include <linux/mmc/card.h> #include <defs.h> #include <brcm_hw_ids.h> @@ -29,35 +32,11 @@ #include <soc.h> #include "dhd.h" #include "dhd_bus.h" +#include "dhd_dbg.h" #include "sdio_host.h" #define SDIOH_API_ACCESS_RETRY_LIMIT 2 -#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 */ @@ -65,220 +44,205 @@ #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 */ - bool regfail; /* Save status of last - 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 */ -static struct brcmf_sdio_card *l_card; - -const uint brcmf_sdio_msglevel = BRCMF_SD_ERROR_VAL; - -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); +/* IOVar table */ +enum { + IOV_MSGLEVEL = 1, + IOV_DEVREG, + IOV_HCIREGS, + IOV_RXCHAIN +}; -int brcmf_sdio_remove(struct device *dev); -EXPORT_SYMBOL(brcmf_sdio_remove); +const struct brcmu_iovar sdioh_iovars[] = { + {"sd_devreg", IOV_DEVREG, 0, IOVT_BUFFER, sizeof(struct brcmf_sdreg)} + , + {"sd_rxchain", IOV_RXCHAIN, 0, IOVT_BOOL, 0} + , + {NULL, 0, 0, 0, 0} +}; -struct brcmf_sdio_card* -brcmf_sdcard_attach(void *cfghdl, u32 *regsva, uint irq) +int +brcmf_sdcard_iovar_op(struct brcmf_sdio_dev *sdiodev, const char *name, + void *params, int plen, void *arg, int len, bool set) { - struct brcmf_sdio_card *card; - - card = kzalloc(sizeof(struct brcmf_sdio_card), GFP_ATOMIC); - if (card == NULL) { - BRCMF_SD_ERROR(("sdcard_attach: out of memory")); - return NULL; + const struct brcmu_iovar *vi = NULL; + int bcmerror = 0; + int val_size; + s32 int_val = 0; + bool bool_val; + u32 actionid; + + if (name == NULL || len < 0) + return -EINVAL; + + /* Set does not take qualifiers */ + if (set && (params || plen)) + return -EINVAL; + + /* Get must have return space;*/ + if (!set && !(arg && len)) + return -EINVAL; + + brcmf_dbg(TRACE, "Enter (%s %s)\n", set ? "set" : "get", name); + + vi = brcmu_iovar_lookup(sdioh_iovars, name); + if (vi == NULL) { + bcmerror = -ENOTSUPP; + goto exit; } - /* save the handler locally */ - l_card = card; + bcmerror = brcmu_iovar_lencheck(vi, arg, len, set); + if (bcmerror != 0) + goto exit; - card->sdioh = brcmf_sdioh_attach(cfghdl, irq); - if (!card->sdioh) { - brcmf_sdcard_detach(card); - return NULL; + /* Set up params so get and set can share the convenience variables */ + if (params == NULL) { + params = arg; + plen = len; } - card->init_success = true; - - *regsva = SI_ENUM_BASE; - - /* Report the BAR, to fix if needed */ - card->sbwad = SI_ENUM_BASE; - return card; -} + if (vi->type == IOVT_VOID) + val_size = 0; + else if (vi->type == IOVT_BUFFER) + val_size = len; + else + val_size = sizeof(int); + + if (plen >= (int)sizeof(int_val)) + memcpy(&int_val, params, sizeof(int_val)); + + bool_val = (int_val != 0) ? true : false; + + actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid); + switch (actionid) { + case IOV_GVAL(IOV_RXCHAIN): + int_val = false; + memcpy(arg, &int_val, val_size); + break; + + case IOV_GVAL(IOV_DEVREG): + { + struct brcmf_sdreg *sd_ptr = + (struct brcmf_sdreg *) params; + u8 data = 0; + + if (brcmf_sdioh_request_byte(sdiodev, SDIOH_READ, + sd_ptr->func, sd_ptr->offset, &data)) { + bcmerror = -EIO; + break; + } + + int_val = (int)data; + memcpy(arg, &int_val, sizeof(int_val)); + break; + } -int brcmf_sdcard_detach(struct brcmf_sdio_card *card) -{ - if (card != NULL) { - if (card->sdioh) { - brcmf_sdioh_detach(card->sdioh); - card->sdioh = NULL; + case IOV_SVAL(IOV_DEVREG): + { + struct brcmf_sdreg *sd_ptr = + (struct brcmf_sdreg *) params; + u8 data = (u8) sd_ptr->value; + + if (brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE, + sd_ptr->func, sd_ptr->offset, &data)) { + bcmerror = -EIO; + break; + } + break; } - kfree(card); + + default: + bcmerror = -ENOTSUPP; + break; } +exit: - l_card = NULL; - return 0; + return bcmerror; } -int -brcmf_sdcard_iovar_op(struct brcmf_sdio_card *card, const char *name, - void *params, int plen, void *arg, int len, bool set) +static void brcmf_sdioh_irqhandler(struct sdio_func *func) { - return brcmf_sdioh_iovar_op(card->sdioh, name, params, plen, arg, - len, set); -} + struct brcmf_sdio_dev *sdiodev = dev_get_drvdata(&func->card->dev); -int brcmf_sdcard_intr_enable(struct brcmf_sdio_card *card) -{ - return brcmf_sdioh_interrupt_set(card->sdioh, true); -} + brcmf_dbg(TRACE, "***IRQHandler\n"); -int brcmf_sdcard_intr_disable(struct brcmf_sdio_card *card) -{ - return brcmf_sdioh_interrupt_set(card->sdioh, false); + sdio_release_host(func); + + brcmf_sdbrcm_isr(sdiodev->bus); + + sdio_claim_host(func); } -int brcmf_sdcard_intr_reg(struct brcmf_sdio_card *card, - void (*fn)(void *), void *argh) +int brcmf_sdcard_intr_reg(struct brcmf_sdio_dev *sdiodev) { - return brcmf_sdioh_interrupt_register(card->sdioh, fn, argh); + brcmf_dbg(TRACE, "Entering\n"); + + sdio_claim_host(sdiodev->func[1]); + sdio_claim_irq(sdiodev->func[1], brcmf_sdioh_irqhandler); + sdio_release_host(sdiodev->func[1]); + + return 0; } -int brcmf_sdcard_intr_dereg(struct brcmf_sdio_card *card) +int brcmf_sdcard_intr_dereg(struct brcmf_sdio_dev *sdiodev) { - return brcmf_sdioh_interrupt_deregister(card->sdioh); + brcmf_dbg(TRACE, "Entering\n"); + + sdio_claim_host(sdiodev->func[1]); + sdio_release_irq(sdiodev->func[1]); + sdio_release_host(sdiodev->func[1]); + + return 0; } -u8 brcmf_sdcard_cfg_read(struct brcmf_sdio_card *card, uint fnc_num, u32 addr, +u8 brcmf_sdcard_cfg_read(struct brcmf_sdio_dev *sdiodev, uint fnc_num, u32 addr, int *err) { int status; s32 retry = 0; u8 data = 0; - if (!card) - card = l_card; - do { if (retry) /* wait for 1 ms till bus get settled down */ udelay(1000); - status = - brcmf_sdioh_cfg_read(card->sdioh, fnc_num, addr, - (u8 *) &data); + status = brcmf_sdioh_request_byte(sdiodev, SDIOH_READ, fnc_num, + addr, (u8 *) &data); } while (status != 0 && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT)); if (err) *err = status; - BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u8data = 0x%x\n", - __func__, fnc_num, addr, data)); + brcmf_dbg(INFO, "fun = %d, addr = 0x%x, u8data = 0x%x\n", + fnc_num, addr, data); return data; } void -brcmf_sdcard_cfg_write(struct brcmf_sdio_card *card, uint fnc_num, u32 addr, +brcmf_sdcard_cfg_write(struct brcmf_sdio_dev *sdiodev, uint fnc_num, u32 addr, u8 data, int *err) { int status; s32 retry = 0; - if (!card) - card = l_card; - do { if (retry) /* wait for 1 ms till bus get settled down */ udelay(1000); - status = - brcmf_sdioh_cfg_write(card->sdioh, fnc_num, addr, - (u8 *) &data); + status = brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE, fnc_num, + addr, (u8 *) &data); } while (status != 0 && (retry++ < SDIOH_API_ACCESS_RETRY_LIMIT)); if (err) *err = status; - BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u8data = 0x%x\n", - __func__, fnc_num, addr, data)); -} - -u32 brcmf_sdcard_cfg_read_word(struct brcmf_sdio_card *card, uint fnc_num, - u32 addr, int *err) -{ - int status; - u32 data = 0; - - if (!card) - card = l_card; - - status = brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL, - SDIOH_READ, fnc_num, addr, &data, 4); - - if (err) - *err = status; - - BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u32data = 0x%x\n", - __func__, fnc_num, addr, data)); - - return data; -} - -void -brcmf_sdcard_cfg_write_word(struct brcmf_sdio_card *card, uint fnc_num, - u32 addr, u32 data, int *err) -{ - int status; - - if (!card) - card = l_card; - - status = - brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL, - SDIOH_WRITE, fnc_num, addr, &data, 4); - - if (err) - *err = status; - - BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, u32data = 0x%x\n", - __func__, fnc_num, addr, data)); + brcmf_dbg(INFO, "fun = %d, addr = 0x%x, u8data = 0x%x\n", + fnc_num, addr, data); } -int brcmf_sdcard_cis_read(struct brcmf_sdio_card *card, uint func, u8 * cis, +int brcmf_sdcard_cis_read(struct brcmf_sdio_dev *sdiodev, uint func, u8 * cis, uint length) { int status; @@ -288,17 +252,14 @@ int brcmf_sdcard_cis_read(struct brcmf_sdio_card *card, uint func, u8 * cis, bool ascii = func & ~0xf; func &= 0x7; - if (!card) - card = l_card; - - status = brcmf_sdioh_cis_read(card->sdioh, func, cis, length); + status = brcmf_sdioh_cis_read(sdiodev, 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) { - BRCMF_SD_ERROR(("%s: out of memory\n", __func__)); + brcmf_dbg(ERROR, "out of memory\n"); return -ENOMEM; } memcpy(tmp_buf, cis, length); @@ -315,18 +276,18 @@ int brcmf_sdcard_cis_read(struct brcmf_sdio_card *card, uint func, u8 * cis, } static int -brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_card *card, u32 address) +brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address) { int err = 0; - brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW, + brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW, (address >> 8) & SBSDIO_SBADDRLOW_MASK, &err); if (!err) - brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, + brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRMID, (address >> 16) & SBSDIO_SBADDRMID_MASK, &err); if (!err) - brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, + brcmf_sdcard_cfg_write(sdiodev, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRHIGH, (address >> 24) & SBSDIO_SBADDRHIGH_MASK, &err); @@ -334,34 +295,31 @@ brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_card *card, u32 address) return err; } -u32 brcmf_sdcard_reg_read(struct brcmf_sdio_card *card, u32 addr, uint size) +u32 brcmf_sdcard_reg_read(struct brcmf_sdio_dev *sdiodev, u32 addr, uint size) { int status; u32 word = 0; uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK; - BRCMF_SD_INFO(("%s:fun = 1, addr = 0x%x, ", __func__, addr)); - - if (!card) - card = l_card; + brcmf_dbg(INFO, "fun = 1, addr = 0x%x\n", addr); - if (bar0 != card->sbwad) { - if (brcmf_sdcard_set_sbaddr_window(card, bar0)) + if (bar0 != sdiodev->sbwad) { + if (brcmf_sdcard_set_sbaddr_window(sdiodev, bar0)) return 0xFFFFFFFF; - card->sbwad = bar0; + sdiodev->sbwad = bar0; } addr &= SBSDIO_SB_OFT_ADDR_MASK; if (size == 4) addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; - status = brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL, + status = brcmf_sdioh_request_word(sdiodev, SDIOH_CMD_TYPE_NORMAL, SDIOH_READ, SDIO_FUNC_1, addr, &word, size); - card->regfail = (status != 0); + sdiodev->regfail = (status != 0); - BRCMF_SD_INFO(("u32data = 0x%x\n", word)); + brcmf_dbg(INFO, "u32data = 0x%x\n", word); /* if ok, return appropriately masked word */ if (status == 0) { @@ -373,66 +331,59 @@ u32 brcmf_sdcard_reg_read(struct brcmf_sdio_card *card, u32 addr, uint size) case sizeof(u32): return word; default: - card->regfail = true; + sdiodev->regfail = true; } } /* otherwise, bad sdio access or invalid size */ - BRCMF_SD_ERROR(("%s: error reading addr 0x%04x size %d\n", __func__, - addr, size)); + brcmf_dbg(ERROR, "error reading addr 0x%04x size %d\n", addr, size); return 0xFFFFFFFF; } -u32 brcmf_sdcard_reg_write(struct brcmf_sdio_card *card, u32 addr, uint size, +u32 brcmf_sdcard_reg_write(struct brcmf_sdio_dev *sdiodev, u32 addr, uint size, u32 data) { int status; uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK; int err = 0; - BRCMF_SD_INFO(("%s:fun = 1, addr = 0x%x, uint%ddata = 0x%x\n", - __func__, addr, size * 8, data)); - - if (!card) - card = l_card; + brcmf_dbg(INFO, "fun = 1, addr = 0x%x, uint%ddata = 0x%x\n", + addr, size * 8, data); - if (bar0 != card->sbwad) { - err = brcmf_sdcard_set_sbaddr_window(card, bar0); + if (bar0 != sdiodev->sbwad) { + err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0); if (err) return err; - card->sbwad = bar0; + sdiodev->sbwad = bar0; } addr &= SBSDIO_SB_OFT_ADDR_MASK; if (size == 4) addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; status = - brcmf_sdioh_request_word(card->sdioh, SDIOH_CMD_TYPE_NORMAL, + brcmf_sdioh_request_word(sdiodev, SDIOH_CMD_TYPE_NORMAL, SDIOH_WRITE, SDIO_FUNC_1, addr, &data, size); - card->regfail = (status != 0); + sdiodev->regfail = (status != 0); if (status == 0) return 0; - BRCMF_SD_ERROR(("%s: error writing 0x%08x to addr 0x%04x size %d\n", - __func__, data, addr, size)); + brcmf_dbg(ERROR, "error writing 0x%08x to addr 0x%04x size %d\n", + data, addr, size); return 0xFFFFFFFF; } -bool brcmf_sdcard_regfail(struct brcmf_sdio_card *card) +bool brcmf_sdcard_regfail(struct brcmf_sdio_dev *sdiodev) { - return card->regfail; + return sdiodev->regfail; } int -brcmf_sdcard_recv_buf(struct brcmf_sdio_card *card, u32 addr, uint fn, +brcmf_sdcard_recv_buf(struct brcmf_sdio_dev *sdiodev, 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) + u8 *buf, uint nbytes, struct sk_buff *pkt) { int status; uint incr_fix; @@ -440,19 +391,18 @@ brcmf_sdcard_recv_buf(struct brcmf_sdio_card *card, u32 addr, uint fn, uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK; int err = 0; - BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n", - __func__, fn, addr, nbytes)); + brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n", fn, addr, nbytes); /* Async not implemented yet */ if (flags & SDIO_REQ_ASYNC) return -ENOTSUPP; - if (bar0 != card->sbwad) { - err = brcmf_sdcard_set_sbaddr_window(card, bar0); + if (bar0 != sdiodev->sbwad) { + err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0); if (err) return err; - card->sbwad = bar0; + sdiodev->sbwad = bar0; } addr &= SBSDIO_SB_OFT_ADDR_MASK; @@ -462,37 +412,33 @@ brcmf_sdcard_recv_buf(struct brcmf_sdio_card *card, u32 addr, uint fn, if (width == 4) addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; - status = brcmf_sdioh_request_buffer(card->sdioh, SDIOH_DATA_PIO, + status = brcmf_sdioh_request_buffer(sdiodev, SDIOH_DATA_PIO, incr_fix, SDIOH_READ, fn, addr, width, nbytes, buf, pkt); return status; } 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) +brcmf_sdcard_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, + uint flags, u8 *buf, uint nbytes, struct sk_buff *pkt) { uint incr_fix; uint width; uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK; int err = 0; - BRCMF_SD_INFO(("%s:fun = %d, addr = 0x%x, size = %d\n", - __func__, fn, addr, nbytes)); + brcmf_dbg(INFO, "fun = %d, addr = 0x%x, size = %d\n", fn, addr, nbytes); /* Async not implemented yet */ if (flags & SDIO_REQ_ASYNC) return -ENOTSUPP; - if (bar0 != card->sbwad) { - err = brcmf_sdcard_set_sbaddr_window(card, bar0); + if (bar0 != sdiodev->sbwad) { + err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0); if (err) return err; - card->sbwad = bar0; + sdiodev->sbwad = bar0; } addr &= SBSDIO_SB_OFT_ADDR_MASK; @@ -502,129 +448,86 @@ brcmf_sdcard_send_buf(struct brcmf_sdio_card *card, u32 addr, uint fn, if (width == 4) addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; - return brcmf_sdioh_request_buffer(card->sdioh, SDIOH_DATA_PIO, + return brcmf_sdioh_request_buffer(sdiodev, SDIOH_DATA_PIO, incr_fix, SDIOH_WRITE, fn, addr, width, nbytes, buf, pkt); } -int brcmf_sdcard_rwdata(struct brcmf_sdio_card *card, uint rw, u32 addr, +int brcmf_sdcard_rwdata(struct brcmf_sdio_dev *sdiodev, uint rw, u32 addr, u8 *buf, uint nbytes) { addr &= SBSDIO_SB_OFT_ADDR_MASK; addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; - return brcmf_sdioh_request_buffer(card->sdioh, SDIOH_DATA_PIO, + return brcmf_sdioh_request_buffer(sdiodev, SDIOH_DATA_PIO, SDIOH_DATA_INC, (rw ? SDIOH_WRITE : SDIOH_READ), SDIO_FUNC_1, addr, 4, nbytes, buf, NULL); } -int brcmf_sdcard_abort(struct brcmf_sdio_card *card, uint fn) +int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn) { - return brcmf_sdioh_abort(card->sdioh, fn); -} + char t_func = (char)fn; + brcmf_dbg(TRACE, "Enter\n"); -int brcmf_sdcard_query_device(struct brcmf_sdio_card *card) -{ - card->vendevid = (PCI_VENDOR_ID_BROADCOM << 16) | 0; - return card->vendevid; + /* issue abort cmd52 command through F0 */ + brcmf_sdioh_request_byte(sdiodev, SDIOH_WRITE, SDIO_FUNC_0, + SDIO_CCCR_ABORT, &t_func); + + brcmf_dbg(TRACE, "Exit\n"); + return 0; } -u32 brcmf_sdcard_cur_sbwad(struct brcmf_sdio_card *card) +u32 brcmf_sdcard_cur_sbwad(struct brcmf_sdio_dev *sdiodev) { - if (!card) - card = l_card; - - return card->sbwad; + return sdiodev->sbwad; } -int brcmf_sdio_probe(struct device *dev) +int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev) { - 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; + int ret = 0; - card = brcmf_sdcard_attach((void *)0, ®s, irq); - if (!card) { - SDLX_MSG(("%s: attach failed\n", __func__)); - goto err; - } + ret = brcmf_sdioh_attach(sdiodev); + if (ret) + goto out; - sdhc->card = card; - sdhc->oob_irq = irq; - sdhc->oob_flags = irq_flags; - sdhc->oob_irq_registered = false; /* to make sure.. */ + regs = SI_ENUM_BASE; - /* 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); + /* Report the BAR, to fix if needed */ + sdiodev->sbwad = SI_ENUM_BASE; /* 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; + sdiodev->bus = brcmf_sdbrcm_probe(0, 0, 0, 0, regs, sdiodev); + if (!sdiodev->bus) { + brcmf_dbg(ERROR, "device attach failed\n"); + ret = -ENODEV; + goto out; } - return 0; +out: + if (ret) + brcmf_sdio_remove(sdiodev); - /* error handling */ -err: - if (sdhc) { - if (sdhc->card) - brcmf_sdcard_detach(sdhc->card); - kfree(sdhc); - } - - return -ENODEV; + return ret; } +EXPORT_SYMBOL(brcmf_sdio_probe); -int brcmf_sdio_remove(struct device *dev) +int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev) { - struct sdio_hc *sdhc, *prev; - - 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; + if (sdiodev->bus) { + brcmf_sdbrcm_disconnect(sdiodev->bus); + sdiodev->bus = NULL; } - /* release SDIO Host Controller info */ - kfree(sdhc); + brcmf_sdioh_detach(sdiodev); + + sdiodev->sbwad = 0; + return 0; } +EXPORT_SYMBOL(brcmf_sdio_remove); -int brcmf_sdio_register(struct brcmf_sdioh_driver *driver) +int brcmf_sdio_register(void) { - drvinfo = *driver; - - SDLX_MSG(("Linux Kernel SDIO/MMC Driver\n")); return brcmf_sdio_function_init(); } @@ -633,10 +536,10 @@ void brcmf_sdio_unregister(void) brcmf_sdio_function_cleanup(); } -void brcmf_sdio_wdtmr_enable(bool enable) +void brcmf_sdio_wdtmr_enable(struct brcmf_sdio_dev *sdiodev, bool enable) { if (enable) - brcmf_sdbrcm_wd_timer(sdhcinfo->ch, brcmf_watchdog_ms); + brcmf_sdbrcm_wd_timer(sdiodev->bus, brcmf_watchdog_ms); else - brcmf_sdbrcm_wd_timer(sdhcinfo->ch, 0); + brcmf_sdbrcm_wd_timer(sdiodev->bus, 0); } diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c index 38bd9ba..a15765b 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -34,95 +34,13 @@ #include "dhd_dbg.h" #include "wl_cfg80211.h" -#define BLOCK_SIZE_64 64 -#define BLOCK_SIZE_512 512 -#define BLOCK_SIZE_4318 64 -#define BLOCK_SIZE_4328 512 - -/* private bus modes */ -#define SDIOH_MODE_SD4 2 - -#define CLIENT_INTR 0x100 /* Get rid of this! */ - -#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 #define DMA_ALIGN_MASK 0x03 -#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) */ - -/* 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 */ - -#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 - -struct sdos_info { - struct sdioh_info *sd; - spinlock_t lock; -}; -static void brcmf_sdioh_irqhandler(struct sdio_func *func); -static void brcmf_sdioh_irqhandler_f2(struct sdio_func *func); -static int brcmf_sdioh_get_cisaddr(struct sdioh_info *sd, u32 regaddr); +static int brcmf_sdioh_get_cisaddr(struct brcmf_sdio_dev *sdiodev, u32 regaddr); static int brcmf_ops_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id); static void brcmf_ops_sdio_remove(struct sdio_func *func); @@ -134,94 +52,84 @@ static int brcmf_sdio_resume(struct device *dev); uint sd_f2_blocksize = 512; /* Default blocksize */ -uint sd_msglevel = 0x01; - -/* module param defaults */ -static int clockoverride; - -module_param(clockoverride, int, 0644); -MODULE_PARM_DESC(clockoverride, "SDIO card clock override"); - -struct brcmf_sdmmc_instance *gInstance; - -struct device sdmmc_dev; - /* devices we support, null terminated */ static const struct sdio_device_id brcmf_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 */ }, }; -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static const struct dev_pm_ops brcmf_sdio_pm_ops = { .suspend = brcmf_sdio_suspend, .resume = brcmf_sdio_resume, }; -#endif /* CONFIG_PM */ +#endif /* CONFIG_PM_SLEEP */ static struct sdio_driver brcmf_sdmmc_driver = { .probe = brcmf_ops_sdio_probe, .remove = brcmf_ops_sdio_remove, .name = "brcmfmac", .id_table = brcmf_sdmmc_ids, -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP .drv = { .pm = &brcmf_sdio_pm_ops, }, -#endif /* CONFIG_PM */ +#endif /* CONFIG_PM_SLEEP */ }; MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids); -BRCMF_PM_RESUME_WAIT_INIT(sdioh_request_byte_wait); -BRCMF_PM_RESUME_WAIT_INIT(sdioh_request_word_wait); -BRCMF_PM_RESUME_WAIT_INIT(sdioh_request_packet_wait); -BRCMF_PM_RESUME_WAIT_INIT(sdioh_request_buffer_wait); +#ifdef CONFIG_PM_SLEEP +DECLARE_WAIT_QUEUE_HEAD(sdioh_request_byte_wait); +DECLARE_WAIT_QUEUE_HEAD(sdioh_request_word_wait); +DECLARE_WAIT_QUEUE_HEAD(sdioh_request_packet_wait); +DECLARE_WAIT_QUEUE_HEAD(sdioh_request_buffer_wait); +#define BRCMF_PM_RESUME_WAIT(a, b) do { \ + int retry = 0; \ + while (atomic_read(&b->suspend) && retry++ != 30) { \ + wait_event_timeout(a, false, HZ/100); \ + } \ + } while (0) +#define BRCMF_PM_RESUME_RETURN_ERROR(a, b) \ + do { if (atomic_read(&b->suspend)) return a; } while (0) +#else +#define BRCMF_PM_RESUME_WAIT(a, b) +#define BRCMF_PM_RESUME_RETURN_ERROR(a, b) +#endif /* CONFIG_PM_SLEEP */ static int -brcmf_sdioh_card_regread(struct sdioh_info *sd, int func, u32 regaddr, +brcmf_sdioh_card_regread(struct brcmf_sdio_dev *sdiodev, int func, u32 regaddr, int regsize, u32 *data); -static int brcmf_sdioh_enablefuncs(struct sdioh_info *sd) +static int brcmf_sdioh_enablefuncs(struct brcmf_sdio_dev *sdiodev) { int err_ret; u32 fbraddr; u8 func; - sd_trace(("%s\n", __func__)); + brcmf_dbg(TRACE, "\n"); /* Get the Card's common CIS address */ - sd->com_cis_ptr = brcmf_sdioh_get_cisaddr(sd, SDIO_CCCR_CIS); - sd->func_cis_ptr[0] = sd->com_cis_ptr; - sd_info(("%s: Card's Common CIS Ptr = 0x%x\n", __func__, - sd->com_cis_ptr)); + sdiodev->func_cis_ptr[0] = brcmf_sdioh_get_cisaddr(sdiodev, + SDIO_CCCR_CIS); + brcmf_dbg(INFO, "Card's Common CIS Ptr = 0x%x\n", + sdiodev->func_cis_ptr[0]); /* Get the Card's function CIS (for each function) */ for (fbraddr = SDIO_FBR_BASE(1), func = 1; - func <= sd->num_funcs; func++, fbraddr += SDIOD_FBR_SIZE) { - sd->func_cis_ptr[func] = - brcmf_sdioh_get_cisaddr(sd, SDIO_FBR_CIS + fbraddr); - sd_info(("%s: Function %d CIS Ptr = 0x%x\n", __func__, func, - sd->func_cis_ptr[func])); + func <= sdiodev->num_funcs; func++, fbraddr += SDIOD_FBR_SIZE) { + sdiodev->func_cis_ptr[func] = + brcmf_sdioh_get_cisaddr(sdiodev, SDIO_FBR_CIS + fbraddr); + brcmf_dbg(INFO, "Function %d CIS Ptr = 0x%x\n", + func, sdiodev->func_cis_ptr[func]); } - sd->func_cis_ptr[0] = sd->com_cis_ptr; - sd_info(("%s: Card's Common CIS Ptr = 0x%x\n", __func__, - sd->com_cis_ptr)); - /* Enable Function 1 */ - sdio_claim_host(gInstance->func[1]); - err_ret = sdio_enable_func(gInstance->func[1]); - sdio_release_host(gInstance->func[1]); - if (err_ret) { - sd_err(("brcmf_sdioh_enablefuncs: Failed to enable F1 " - "Err: 0x%08x\n", err_ret)); - } + sdio_claim_host(sdiodev->func[1]); + err_ret = sdio_enable_func(sdiodev->func[1]); + sdio_release_host(sdiodev->func[1]); + if (err_ret) + brcmf_dbg(ERROR, "Failed to enable F1 Err: 0x%08x\n", err_ret); return false; } @@ -229,375 +137,64 @@ static int brcmf_sdioh_enablefuncs(struct sdioh_info *sd) /* * Public entry points & extern's */ -struct sdioh_info *brcmf_sdioh_attach(void *bar0, uint irq) -{ - struct sdioh_info *sd; - int err_ret; - - sd_trace(("%s\n", __func__)); - - if (gInstance == NULL) { - sd_err(("%s: SDIO Device not present\n", __func__)); - return NULL; - } - - sd = kzalloc(sizeof(struct sdioh_info), GFP_ATOMIC); - if (sd == NULL) { - sd_err(("sdioh_attach: out of memory\n")); - return NULL; - } - if (brcmf_sdioh_osinit(sd) != 0) { - sd_err(("%s:sdioh_sdmmc_osinit() failed\n", __func__)); - kfree(sd); - return NULL; - } - - sd->num_funcs = 2; - sd->use_client_ints = true; - sd->client_block_size[0] = 64; - - gInstance->sd = sd; - - /* Claim host controller */ - sdio_claim_host(gInstance->func[1]); - - sd->client_block_size[1] = 64; - err_ret = sdio_set_block_size(gInstance->func[1], 64); - if (err_ret) - sd_err(("brcmf_sdioh_attach: Failed to set F1 blocksize\n")); - - /* Release host controller F1 */ - sdio_release_host(gInstance->func[1]); - - if (gInstance->func[2]) { - /* Claim host controller F2 */ - sdio_claim_host(gInstance->func[2]); - - sd->client_block_size[2] = sd_f2_blocksize; - err_ret = - sdio_set_block_size(gInstance->func[2], sd_f2_blocksize); - if (err_ret) - sd_err(("brcmf_sdioh_attach: Failed to set F2 blocksize" - " to %d\n", sd_f2_blocksize)); - - /* Release host controller F2 */ - sdio_release_host(gInstance->func[2]); - } - - brcmf_sdioh_enablefuncs(sd); - - sd_trace(("%s: Done\n", __func__)); - return sd; -} - -extern int brcmf_sdioh_detach(struct sdioh_info *sd) +int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev) { - sd_trace(("%s\n", __func__)); - - if (sd) { - - /* Disable Function 2 */ - sdio_claim_host(gInstance->func[2]); - sdio_disable_func(gInstance->func[2]); - sdio_release_host(gInstance->func[2]); + int err_ret = 0; - /* Disable Function 1 */ - sdio_claim_host(gInstance->func[1]); - sdio_disable_func(gInstance->func[1]); - sdio_release_host(gInstance->func[1]); + brcmf_dbg(TRACE, "\n"); - /* deregister irq */ - brcmf_sdioh_osfree(sd); + sdiodev->num_funcs = 2; - kfree(sd); - } - return 0; -} - -/* Configure callback to client when we receive client interrupt */ -extern int -brcmf_sdioh_interrupt_register(struct sdioh_info *sd, void (*fn)(void *), - void *argh) -{ - sd_trace(("%s: Entering\n", __func__)); - if (fn == NULL) { - sd_err(("%s: interrupt handler is NULL, not registering\n", - __func__)); - return -EINVAL; + sdio_claim_host(sdiodev->func[1]); + err_ret = sdio_set_block_size(sdiodev->func[1], 64); + sdio_release_host(sdiodev->func[1]); + if (err_ret) { + brcmf_dbg(ERROR, "Failed to set F1 blocksize\n"); + goto out; } - sd->intr_handler = fn; - sd->intr_handler_arg = argh; - sd->intr_handler_valid = true; - - /* register and unmask irq */ - if (gInstance->func[2]) { - sdio_claim_host(gInstance->func[2]); - sdio_claim_irq(gInstance->func[2], brcmf_sdioh_irqhandler_f2); - sdio_release_host(gInstance->func[2]); + sdio_claim_host(sdiodev->func[2]); + err_ret = sdio_set_block_size(sdiodev->func[2], sd_f2_blocksize); + sdio_release_host(sdiodev->func[2]); + if (err_ret) { + brcmf_dbg(ERROR, "Failed to set F2 blocksize to %d\n", + sd_f2_blocksize); + goto out; } - if (gInstance->func[1]) { - sdio_claim_host(gInstance->func[1]); - sdio_claim_irq(gInstance->func[1], brcmf_sdioh_irqhandler); - sdio_release_host(gInstance->func[1]); - } + brcmf_sdioh_enablefuncs(sdiodev); - return 0; +out: + brcmf_dbg(TRACE, "Done\n"); + return err_ret; } -extern int brcmf_sdioh_interrupt_deregister(struct sdioh_info *sd) +void brcmf_sdioh_detach(struct brcmf_sdio_dev *sdiodev) { - sd_trace(("%s: Entering\n", __func__)); + brcmf_dbg(TRACE, "\n"); - if (gInstance->func[1]) { - /* register and unmask irq */ - sdio_claim_host(gInstance->func[1]); - sdio_release_irq(gInstance->func[1]); - sdio_release_host(gInstance->func[1]); - } + /* Disable Function 2 */ + sdio_claim_host(sdiodev->func[2]); + sdio_disable_func(sdiodev->func[2]); + sdio_release_host(sdiodev->func[2]); - if (gInstance->func[2]) { - /* Claim host controller F2 */ - sdio_claim_host(gInstance->func[2]); - sdio_release_irq(gInstance->func[2]); - /* Release host controller F2 */ - sdio_release_host(gInstance->func[2]); - } - - sd->intr_handler_valid = false; - sd->intr_handler = NULL; - sd->intr_handler_arg = NULL; + /* Disable Function 1 */ + sdio_claim_host(sdiodev->func[1]); + sdio_disable_func(sdiodev->func[1]); + sdio_release_host(sdiodev->func[1]); - return 0; } -/* IOVar table */ -enum { - IOV_MSGLEVEL = 1, - IOV_BLOCKSIZE, - IOV_USEINTS, - IOV_NUMINTS, - IOV_DEVREG, - IOV_HCIREGS, - IOV_RXCHAIN -}; - -const struct brcmu_iovar sdioh_iovars[] = { - {"sd_msglevel", IOV_MSGLEVEL, 0, IOVT_UINT32, 0}, - {"sd_blocksize", IOV_BLOCKSIZE, 0, IOVT_UINT32, 0},/* ((fn << 16) | - size) */ - {"sd_ints", IOV_USEINTS, 0, IOVT_BOOL, 0}, - {"sd_numints", IOV_NUMINTS, 0, IOVT_UINT32, 0}, - {"sd_devreg", IOV_DEVREG, 0, IOVT_BUFFER, sizeof(struct brcmf_sdreg)} - , - {"sd_rxchain", IOV_RXCHAIN, 0, IOVT_BOOL, 0} - , - {NULL, 0, 0, 0, 0} -}; - -int -brcmf_sdioh_iovar_op(struct sdioh_info *si, const char *name, - void *params, int plen, void *arg, int len, bool set) -{ - const struct brcmu_iovar *vi = NULL; - int bcmerror = 0; - int val_size; - s32 int_val = 0; - bool bool_val; - u32 actionid; - - if (name == NULL || len <= 0) - return -EINVAL; - - /* Set does not take qualifiers */ - if (set && (params || plen)) - return -EINVAL; - - /* Get must have return space;*/ - if (!set && !(arg && len)) - return -EINVAL; - - sd_trace(("%s: Enter (%s %s)\n", __func__, (set ? "set" : "get"), - name)); - - vi = brcmu_iovar_lookup(sdioh_iovars, name); - if (vi == NULL) { - bcmerror = -ENOTSUPP; - goto exit; - } - - bcmerror = brcmu_iovar_lencheck(vi, arg, len, set); - if (bcmerror != 0) - goto exit; - - /* Set up params so get and set can share the convenience variables */ - if (params == NULL) { - params = arg; - plen = len; - } - - if (vi->type == IOVT_VOID) - val_size = 0; - else if (vi->type == IOVT_BUFFER) - val_size = len; - else - val_size = sizeof(int); - - if (plen >= (int)sizeof(int_val)) - memcpy(&int_val, params, sizeof(int_val)); - - bool_val = (int_val != 0) ? true : false; - - actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid); - switch (actionid) { - case IOV_GVAL(IOV_MSGLEVEL): - int_val = (s32) sd_msglevel; - memcpy(arg, &int_val, val_size); - break; - - case IOV_SVAL(IOV_MSGLEVEL): - sd_msglevel = int_val; - break; - - case IOV_GVAL(IOV_BLOCKSIZE): - if ((u32) int_val > si->num_funcs) { - bcmerror = -EINVAL; - break; - } - int_val = (s32) si->client_block_size[int_val]; - memcpy(arg, &int_val, val_size); - break; - - case IOV_SVAL(IOV_BLOCKSIZE): - { - uint func = ((u32) int_val >> 16); - uint blksize = (u16) int_val; - uint maxsize; - - if (func > si->num_funcs) { - bcmerror = -EINVAL; - break; - } - - switch (func) { - case 0: - maxsize = 32; - break; - case 1: - maxsize = BLOCK_SIZE_4318; - break; - case 2: - maxsize = BLOCK_SIZE_4328; - break; - default: - maxsize = 0; - } - if (blksize > maxsize) { - bcmerror = -EINVAL; - break; - } - if (!blksize) - blksize = maxsize; - - /* Now set it */ - si->client_block_size[func] = blksize; - - break; - } - - case IOV_GVAL(IOV_RXCHAIN): - int_val = false; - memcpy(arg, &int_val, val_size); - break; - - case IOV_GVAL(IOV_USEINTS): - int_val = (s32) si->use_client_ints; - memcpy(arg, &int_val, val_size); - break; - - case IOV_SVAL(IOV_USEINTS): - si->use_client_ints = (bool) int_val; - if (si->use_client_ints) - si->intmask |= CLIENT_INTR; - else - si->intmask &= ~CLIENT_INTR; - - break; - - case IOV_GVAL(IOV_NUMINTS): - int_val = (s32) si->intrcount; - memcpy(arg, &int_val, val_size); - break; - - case IOV_GVAL(IOV_DEVREG): - { - struct brcmf_sdreg *sd_ptr = - (struct brcmf_sdreg *) params; - u8 data = 0; - - if (brcmf_sdioh_cfg_read - (si, sd_ptr->func, sd_ptr->offset, &data)) { - bcmerror = -EIO; - break; - } - - int_val = (int)data; - memcpy(arg, &int_val, sizeof(int_val)); - break; - } - - case IOV_SVAL(IOV_DEVREG): - { - struct brcmf_sdreg *sd_ptr = - (struct brcmf_sdreg *) params; - u8 data = (u8) sd_ptr->value; - - if (brcmf_sdioh_cfg_write - (si, sd_ptr->func, sd_ptr->offset, &data)) { - bcmerror = -EIO; - break; - } - break; - } - - default: - bcmerror = -ENOTSUPP; - break; - } -exit: - - return bcmerror; -} - -extern int -brcmf_sdioh_cfg_read(struct sdioh_info *sd, uint fnc_num, u32 addr, u8 *data) -{ - int status; - /* No lock needed since brcmf_sdioh_request_byte does locking */ - status = brcmf_sdioh_request_byte(sd, SDIOH_READ, fnc_num, addr, data); - return status; -} - -extern int -brcmf_sdioh_cfg_write(struct sdioh_info *sd, uint fnc_num, u32 addr, u8 *data) -{ - /* No lock needed since brcmf_sdioh_request_byte does locking */ - int status; - status = brcmf_sdioh_request_byte(sd, SDIOH_WRITE, fnc_num, addr, data); - return status; -} - -static int brcmf_sdioh_get_cisaddr(struct sdioh_info *sd, u32 regaddr) +static int brcmf_sdioh_get_cisaddr(struct brcmf_sdio_dev *sdiodev, u32 regaddr) { /* read 24 bits and return valid 17 bit addr */ int i; u32 scratch, regdata; u8 *ptr = (u8 *)&scratch; for (i = 0; i < 3; i++) { - if ((brcmf_sdioh_card_regread(sd, 0, regaddr, 1, ®data)) != - SUCCESS) - sd_err(("%s: Can't read!\n", __func__)); + if ((brcmf_sdioh_card_regread(sdiodev, 0, regaddr, 1, + ®data)) != SUCCESS) + brcmf_dbg(ERROR, "Can't read!\n"); *ptr++ = (u8) regdata; regaddr++; @@ -610,29 +207,29 @@ static int brcmf_sdioh_get_cisaddr(struct sdioh_info *sd, u32 regaddr) } extern int -brcmf_sdioh_cis_read(struct sdioh_info *sd, uint func, u8 *cisd, u32 length) +brcmf_sdioh_cis_read(struct brcmf_sdio_dev *sdiodev, uint func, + u8 *cisd, u32 length) { u32 count; int offset; u32 foo; u8 *cis = cisd; - sd_trace(("%s: Func = %d\n", __func__, func)); + brcmf_dbg(TRACE, "Func = %d\n", func); - if (!sd->func_cis_ptr[func]) { + if (!sdiodev->func_cis_ptr[func]) { memset(cis, 0, length); - sd_err(("%s: no func_cis_ptr[%d]\n", __func__, func)); + brcmf_dbg(ERROR, "no func_cis_ptr[%d]\n", func); return -ENOTSUPP; } - sd_err(("%s: func_cis_ptr[%d]=0x%04x\n", __func__, func, - sd->func_cis_ptr[func])); + brcmf_dbg(ERROR, "func_cis_ptr[%d]=0x%04x\n", + func, sdiodev->func_cis_ptr[func]); for (count = 0; count < length; count++) { - offset = sd->func_cis_ptr[func] + count; - if (brcmf_sdioh_card_regread(sd, 0, offset, 1, &foo) < 0) { - sd_err(("%s: regread failed: Can't read CIS\n", - __func__)); + offset = sdiodev->func_cis_ptr[func] + count; + if (brcmf_sdioh_card_regread(sdiodev, 0, offset, 1, &foo) < 0) { + brcmf_dbg(ERROR, "regread failed: Can't read CIS\n"); return -EIO; } @@ -644,16 +241,15 @@ brcmf_sdioh_cis_read(struct sdioh_info *sd, uint func, u8 *cisd, u32 length) } extern int -brcmf_sdioh_request_byte(struct sdioh_info *sd, uint rw, uint func, +brcmf_sdioh_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw, uint func, uint regaddr, u8 *byte) { int err_ret; - sd_info(("%s: rw=%d, func=%d, addr=0x%05x\n", __func__, rw, func, - regaddr)); + brcmf_dbg(INFO, "rw=%d, func=%d, addr=0x%05x\n", rw, func, regaddr); - BRCMF_PM_RESUME_WAIT(sdioh_request_byte_wait); - BRCMF_PM_RESUME_RETURN_ERROR(-EIO); + BRCMF_PM_RESUME_WAIT(sdioh_request_byte_wait, sdiodev); + BRCMF_PM_RESUME_RETURN_ERROR(-EIO, sdiodev); if (rw) { /* CMD52 Write */ if (func == 0) { /* Can only directly write to some F0 registers. @@ -661,144 +257,139 @@ brcmf_sdioh_request_byte(struct sdioh_info *sd, uint rw, uint func, * as a special case. */ if (regaddr == SDIO_CCCR_IOEx) { - if (gInstance->func[2]) { - sdio_claim_host(gInstance->func[2]); + if (sdiodev->func[2]) { + sdio_claim_host(sdiodev->func[2]); if (*byte & SDIO_FUNC_ENABLE_2) { /* Enable Function 2 */ err_ret = sdio_enable_func - (gInstance->func[2]); + (sdiodev->func[2]); if (err_ret) - sd_err(("request_byte: " - "enable F2 " - "failed:%d\n", - err_ret)); + brcmf_dbg(ERROR, + "enable F2 failed:%d\n", + err_ret); } else { /* Disable Function 2 */ err_ret = sdio_disable_func - (gInstance->func[2]); + (sdiodev->func[2]); if (err_ret) - sd_err(("request_byte: " - "Disab F2 " - "failed:%d\n", - err_ret)); + brcmf_dbg(ERROR, + "Disable F2 failed:%d\n", + err_ret); } - sdio_release_host(gInstance->func[2]); + sdio_release_host(sdiodev->func[2]); } } /* to allow abort command through F1 */ else if (regaddr == SDIO_CCCR_ABORT) { - sdio_claim_host(gInstance->func[func]); + sdio_claim_host(sdiodev->func[func]); /* * this sdio_f0_writeb() can be replaced * with another api * depending upon MMC driver change. * As of this time, this is temporaray one */ - sdio_writeb(gInstance->func[func], *byte, + sdio_writeb(sdiodev->func[func], *byte, regaddr, &err_ret); - sdio_release_host(gInstance->func[func]); + sdio_release_host(sdiodev->func[func]); } else if (regaddr < 0xF0) { - sd_err(("brcmf: F0 Wr:0x%02x: write " - "disallowed\n", regaddr)); + brcmf_dbg(ERROR, "F0 Wr:0x%02x: write disallowed\n", + regaddr); } else { /* Claim host controller, perform F0 write, and release */ - sdio_claim_host(gInstance->func[func]); - sdio_f0_writeb(gInstance->func[func], *byte, + sdio_claim_host(sdiodev->func[func]); + sdio_f0_writeb(sdiodev->func[func], *byte, regaddr, &err_ret); - sdio_release_host(gInstance->func[func]); + sdio_release_host(sdiodev->func[func]); } } else { /* Claim host controller, perform Fn write, and release */ - sdio_claim_host(gInstance->func[func]); - sdio_writeb(gInstance->func[func], *byte, regaddr, + sdio_claim_host(sdiodev->func[func]); + sdio_writeb(sdiodev->func[func], *byte, regaddr, &err_ret); - sdio_release_host(gInstance->func[func]); + sdio_release_host(sdiodev->func[func]); } } else { /* CMD52 Read */ /* Claim host controller, perform Fn read, and release */ - sdio_claim_host(gInstance->func[func]); + sdio_claim_host(sdiodev->func[func]); if (func == 0) { *byte = - sdio_f0_readb(gInstance->func[func], regaddr, + sdio_f0_readb(sdiodev->func[func], regaddr, &err_ret); } else { *byte = - sdio_readb(gInstance->func[func], regaddr, + sdio_readb(sdiodev->func[func], regaddr, &err_ret); } - sdio_release_host(gInstance->func[func]); + sdio_release_host(sdiodev->func[func]); } if (err_ret) - sd_err(("brcmf: Failed to %s byte F%d:@0x%05x=%02x, " - "Err: %d\n", rw ? "Write" : "Read", func, regaddr, - *byte, err_ret)); + brcmf_dbg(ERROR, "Failed to %s byte F%d:@0x%05x=%02x, Err: %d\n", + rw ? "write" : "read", func, regaddr, *byte, err_ret); return err_ret; } extern int -brcmf_sdioh_request_word(struct sdioh_info *sd, uint cmd_type, uint rw, +brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev, uint cmd_type, uint rw, uint func, uint addr, u32 *word, uint nbytes) { int err_ret = -EIO; if (func == 0) { - sd_err(("%s: Only CMD52 allowed to F0.\n", __func__)); + brcmf_dbg(ERROR, "Only CMD52 allowed to F0\n"); return -EINVAL; } - sd_info(("%s: cmd_type=%d, rw=%d, func=%d, addr=0x%05x, nbytes=%d\n", - __func__, cmd_type, rw, func, addr, nbytes)); + brcmf_dbg(INFO, "cmd_type=%d, rw=%d, func=%d, addr=0x%05x, nbytes=%d\n", + cmd_type, rw, func, addr, nbytes); - BRCMF_PM_RESUME_WAIT(sdioh_request_word_wait); - BRCMF_PM_RESUME_RETURN_ERROR(-EIO); + BRCMF_PM_RESUME_WAIT(sdioh_request_word_wait, sdiodev); + BRCMF_PM_RESUME_RETURN_ERROR(-EIO, sdiodev); /* Claim host controller */ - sdio_claim_host(gInstance->func[func]); + sdio_claim_host(sdiodev->func[func]); if (rw) { /* CMD52 Write */ - if (nbytes == 4) { - sdio_writel(gInstance->func[func], *word, addr, + if (nbytes == 4) + sdio_writel(sdiodev->func[func], *word, addr, &err_ret); - } else if (nbytes == 2) { - sdio_writew(gInstance->func[func], (*word & 0xFFFF), + else if (nbytes == 2) + sdio_writew(sdiodev->func[func], (*word & 0xFFFF), addr, &err_ret); - } else { - sd_err(("%s: Invalid nbytes: %d\n", __func__, nbytes)); - } + else + brcmf_dbg(ERROR, "Invalid nbytes: %d\n", nbytes); } else { /* CMD52 Read */ - if (nbytes == 4) { + if (nbytes == 4) *word = - sdio_readl(gInstance->func[func], addr, &err_ret); - } else if (nbytes == 2) { + sdio_readl(sdiodev->func[func], addr, &err_ret); + else if (nbytes == 2) *word = - sdio_readw(gInstance->func[func], addr, + sdio_readw(sdiodev->func[func], addr, &err_ret) & 0xFFFF; - } else { - sd_err(("%s: Invalid nbytes: %d\n", __func__, nbytes)); - } + else + brcmf_dbg(ERROR, "Invalid nbytes: %d\n", nbytes); } /* Release host controller */ - sdio_release_host(gInstance->func[func]); + sdio_release_host(sdiodev->func[func]); - if (err_ret) { - sd_err(("brcmf: Failed to %s word, Err: 0x%08x\n", - rw ? "Write" : "Read", err_ret)); - } + if (err_ret) + brcmf_dbg(ERROR, "Failed to %s word, Err: 0x%08x\n", + rw ? "write" : "read", err_ret); return err_ret; } static int -brcmf_sdioh_request_packet(struct sdioh_info *sd, uint fix_inc, uint write, - uint func, uint addr, struct sk_buff *pkt) +brcmf_sdioh_request_packet(struct brcmf_sdio_dev *sdiodev, uint fix_inc, + uint write, uint func, uint addr, + struct sk_buff *pkt) { bool fifo = (fix_inc == SDIOH_DATA_FIX); u32 SGCount = 0; @@ -806,46 +397,44 @@ brcmf_sdioh_request_packet(struct sdioh_info *sd, uint fix_inc, uint write, struct sk_buff *pnext; - sd_trace(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); - BRCMF_PM_RESUME_WAIT(sdioh_request_packet_wait); - BRCMF_PM_RESUME_RETURN_ERROR(-EIO); + BRCMF_PM_RESUME_WAIT(sdioh_request_packet_wait, sdiodev); + BRCMF_PM_RESUME_RETURN_ERROR(-EIO, sdiodev); /* Claim host controller */ - sdio_claim_host(gInstance->func[func]); + sdio_claim_host(sdiodev->func[func]); for (pnext = pkt; pnext; pnext = pnext->next) { uint pkt_len = pnext->len; pkt_len += 3; pkt_len &= 0xFFFFFFFC; if ((write) && (!fifo)) { - err_ret = sdio_memcpy_toio(gInstance->func[func], addr, + err_ret = sdio_memcpy_toio(sdiodev->func[func], addr, ((u8 *) (pnext->data)), pkt_len); } else if (write) { - err_ret = sdio_memcpy_toio(gInstance->func[func], addr, + err_ret = sdio_memcpy_toio(sdiodev->func[func], addr, ((u8 *) (pnext->data)), pkt_len); } else if (fifo) { - err_ret = sdio_readsb(gInstance->func[func], + err_ret = sdio_readsb(sdiodev->func[func], ((u8 *) (pnext->data)), addr, pkt_len); } else { - err_ret = sdio_memcpy_fromio(gInstance->func[func], + err_ret = sdio_memcpy_fromio(sdiodev->func[func], ((u8 *) (pnext->data)), addr, pkt_len); } if (err_ret) { - sd_err(("%s: %s FAILED %p[%d], addr=0x%05x, pkt_len=%d," - "ERR=0x%08x\n", __func__, - (write) ? "TX" : "RX", - pnext, SGCount, addr, pkt_len, err_ret)); + brcmf_dbg(ERROR, "%s FAILED %p[%d], addr=0x%05x, pkt_len=%d, ERR=0x%08x\n", + write ? "TX" : "RX", pnext, SGCount, addr, + pkt_len, err_ret); } else { - sd_trace(("%s: %s xfr'd %p[%d], addr=0x%05x, len=%d\n", - __func__, - (write) ? "TX" : "RX", - pnext, SGCount, addr, pkt_len)); + brcmf_dbg(TRACE, "%s xfr'd %p[%d], addr=0x%05x, len=%d\n", + write ? "TX" : "RX", pnext, SGCount, addr, + pkt_len); } if (!fifo) @@ -855,9 +444,9 @@ brcmf_sdioh_request_packet(struct sdioh_info *sd, uint fix_inc, uint write, } /* Release host controller */ - sdio_release_host(gInstance->func[func]); + sdio_release_host(sdiodev->func[func]); - sd_trace(("%s: Exit\n", __func__)); + brcmf_dbg(TRACE, "Exit\n"); return err_ret; } @@ -877,25 +466,26 @@ brcmf_sdioh_request_packet(struct sdioh_info *sd, uint fix_inc, uint write, * */ extern int -brcmf_sdioh_request_buffer(struct sdioh_info *sd, uint pio_dma, uint fix_inc, - uint write, uint func, uint addr, uint reg_width, - uint buflen_u, u8 *buffer, struct sk_buff *pkt) +brcmf_sdioh_request_buffer(struct brcmf_sdio_dev *sdiodev, uint pio_dma, + uint fix_inc, uint write, uint func, uint addr, + uint reg_width, uint buflen_u, u8 *buffer, + struct sk_buff *pkt) { int Status; struct sk_buff *mypkt = NULL; - sd_trace(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); - BRCMF_PM_RESUME_WAIT(sdioh_request_buffer_wait); - BRCMF_PM_RESUME_RETURN_ERROR(-EIO); + BRCMF_PM_RESUME_WAIT(sdioh_request_buffer_wait, sdiodev); + BRCMF_PM_RESUME_RETURN_ERROR(-EIO, sdiodev); /* Case 1: we don't have a packet. */ if (pkt == NULL) { - sd_data(("%s: Creating new %s Packet, len=%d\n", - __func__, write ? "TX" : "RX", buflen_u)); + brcmf_dbg(DATA, "Creating new %s Packet, len=%d\n", + write ? "TX" : "RX", buflen_u); mypkt = brcmu_pkt_buf_get_skb(buflen_u); if (!mypkt) { - sd_err(("%s: brcmu_pkt_buf_get_skb failed: len %d\n", - __func__, buflen_u)); + brcmf_dbg(ERROR, "brcmu_pkt_buf_get_skb failed: len %d\n", + buflen_u); return -EIO; } @@ -903,8 +493,8 @@ brcmf_sdioh_request_buffer(struct sdioh_info *sd, uint pio_dma, uint fix_inc, if (write) memcpy(mypkt->data, buffer, buflen_u); - Status = brcmf_sdioh_request_packet(sd, fix_inc, write, func, - addr, mypkt); + Status = brcmf_sdioh_request_packet(sdiodev, fix_inc, write, + func, addr, mypkt); /* For a read, copy the packet data back to the buffer. */ if (!write) @@ -916,12 +506,12 @@ brcmf_sdioh_request_buffer(struct sdioh_info *sd, uint pio_dma, uint fix_inc, * Case 2: We have a packet, but it is unaligned. * In this case, we cannot have a chain (pkt->next == NULL) */ - sd_data(("%s: Creating aligned %s Packet, len=%d\n", - __func__, write ? "TX" : "RX", pkt->len)); + brcmf_dbg(DATA, "Creating aligned %s Packet, len=%d\n", + write ? "TX" : "RX", pkt->len); mypkt = brcmu_pkt_buf_get_skb(pkt->len); if (!mypkt) { - sd_err(("%s: brcmu_pkt_buf_get_skb failed: len %d\n", - __func__, pkt->len)); + brcmf_dbg(ERROR, "brcmu_pkt_buf_get_skb failed: len %d\n", + pkt->len); return -EIO; } @@ -929,8 +519,8 @@ brcmf_sdioh_request_buffer(struct sdioh_info *sd, uint pio_dma, uint fix_inc, if (write) memcpy(mypkt->data, pkt->data, pkt->len); - Status = brcmf_sdioh_request_packet(sd, fix_inc, write, func, - addr, mypkt); + Status = brcmf_sdioh_request_packet(sdiodev, fix_inc, write, + func, addr, mypkt); /* For a read, copy the packet data back to the buffer. */ if (!write) @@ -939,128 +529,76 @@ brcmf_sdioh_request_buffer(struct sdioh_info *sd, uint pio_dma, uint fix_inc, brcmu_pkt_buf_free_skb(mypkt); } else { /* case 3: We have a packet and it is aligned. */ - sd_data(("%s: Aligned %s Packet, direct DMA\n", - __func__, write ? "Tx" : "Rx")); - Status = brcmf_sdioh_request_packet(sd, fix_inc, write, func, - addr, pkt); + brcmf_dbg(DATA, "Aligned %s Packet, direct DMA\n", + write ? "Tx" : "Rx"); + Status = brcmf_sdioh_request_packet(sdiodev, fix_inc, write, + func, addr, pkt); } return Status; } -/* this function performs "abort" for both of host & device */ -extern int brcmf_sdioh_abort(struct sdioh_info *sd, uint func) -{ - char t_func = (char)func; - sd_trace(("%s: Enter\n", __func__)); - - /* issue abort cmd52 command through F0 */ - brcmf_sdioh_request_byte(sd, SDIOH_WRITE, SDIO_FUNC_0, SDIO_CCCR_ABORT, - &t_func); - - sd_trace(("%s: Exit\n", __func__)); - return 0; -} - -/* Disable device interrupt */ -void brcmf_sdioh_dev_intr_off(struct sdioh_info *sd) -{ - sd_trace(("%s: %d\n", __func__, sd->use_client_ints)); - sd->intmask &= ~CLIENT_INTR; -} - -/* Enable device interrupt */ -void brcmf_sdioh_dev_intr_on(struct sdioh_info *sd) -{ - sd_trace(("%s: %d\n", __func__, sd->use_client_ints)); - sd->intmask |= CLIENT_INTR; -} - /* Read client card reg */ int -brcmf_sdioh_card_regread(struct sdioh_info *sd, int func, u32 regaddr, +brcmf_sdioh_card_regread(struct brcmf_sdio_dev *sdiodev, int func, u32 regaddr, int regsize, u32 *data) { if ((func == 0) || (regsize == 1)) { u8 temp = 0; - brcmf_sdioh_request_byte(sd, SDIOH_READ, func, regaddr, &temp); + brcmf_sdioh_request_byte(sdiodev, SDIOH_READ, func, regaddr, + &temp); *data = temp; *data &= 0xff; - sd_data(("%s: byte read data=0x%02x\n", __func__, *data)); + brcmf_dbg(DATA, "byte read data=0x%02x\n", *data); } else { - brcmf_sdioh_request_word(sd, 0, SDIOH_READ, func, regaddr, data, - regsize); + brcmf_sdioh_request_word(sdiodev, 0, SDIOH_READ, func, regaddr, + data, regsize); if (regsize == 2) *data &= 0xffff; - sd_data(("%s: word read data=0x%08x\n", __func__, *data)); + brcmf_dbg(DATA, "word read data=0x%08x\n", *data); } return SUCCESS; } -static void brcmf_sdioh_irqhandler(struct sdio_func *func) -{ - struct sdioh_info *sd; - - sd_trace(("brcmf: ***IRQHandler\n")); - sd = gInstance->sd; - - sdio_release_host(gInstance->func[0]); - - if (sd->use_client_ints) { - sd->intrcount++; - (sd->intr_handler) (sd->intr_handler_arg); - } else { - sd_err(("brcmf: ***IRQHandler\n")); - - sd_err(("%s: Not ready for intr: enabled %d, handler %p\n", - __func__, sd->client_intr_enabled, sd->intr_handler)); - } - - sdio_claim_host(gInstance->func[0]); -} - -/* interrupt handler for F2 (dummy handler) */ -static void brcmf_sdioh_irqhandler_f2(struct sdio_func *func) -{ - struct sdioh_info *sd; - - sd_trace(("brcmf: ***IRQHandlerF2\n")); - - sd = gInstance->sd; -} - static int brcmf_ops_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) { int ret = 0; - static struct sdio_func sdio_func_0; - sd_trace(("sdio_probe: %s Enter\n", __func__)); - sd_trace(("sdio_probe: 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)); + struct brcmf_sdio_dev *sdiodev; + brcmf_dbg(TRACE, "Enter\n"); + brcmf_dbg(TRACE, "func->class=%x\n", func->class); + brcmf_dbg(TRACE, "sdio_vendor: 0x%04x\n", func->vendor); + brcmf_dbg(TRACE, "sdio_device: 0x%04x\n", func->device); + brcmf_dbg(TRACE, "Function#: 0x%04x\n", func->num); if (func->num == 1) { - 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 brcmf_sdio_probe...\n")); - ret = brcmf_sdio_probe(&sdmmc_dev); + if (dev_get_drvdata(&func->card->dev)) { + brcmf_dbg(ERROR, "card private drvdata occupied\n"); + return -ENXIO; } - } + sdiodev = kzalloc(sizeof(struct brcmf_sdio_dev), GFP_KERNEL); + if (!sdiodev) + return -ENOMEM; + sdiodev->func[0] = func->card->sdio_func[0]; + sdiodev->func[1] = func; + dev_set_drvdata(&func->card->dev, sdiodev); - gInstance->func[func->num] = func; + atomic_set(&sdiodev->suspend, false); + } if (func->num == 2) { + sdiodev = dev_get_drvdata(&func->card->dev); + if ((!sdiodev) || (sdiodev->func[1]->card != func->card)) + return -ENODEV; + sdiodev->func[2] = func; + brcmf_cfg80211_sdio_func(func); - sd_trace(("F2 found, calling brcmf_sdio_probe...\n")); - ret = brcmf_sdio_probe(&sdmmc_dev); + brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_probe...\n"); + ret = brcmf_sdio_probe(sdiodev); } return ret; @@ -1068,102 +606,65 @@ static int brcmf_ops_sdio_probe(struct sdio_func *func, static void brcmf_ops_sdio_remove(struct sdio_func *func) { - sd_trace(("%s Enter\n", __func__)); - sd_info(("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)); + struct brcmf_sdio_dev *sdiodev; + brcmf_dbg(TRACE, "Enter\n"); + brcmf_dbg(INFO, "func->class=%x\n", func->class); + brcmf_dbg(INFO, "sdio_vendor: 0x%04x\n", func->vendor); + brcmf_dbg(INFO, "sdio_device: 0x%04x\n", func->device); + brcmf_dbg(INFO, "Function#: 0x%04x\n", func->num); if (func->num == 2) { - sd_trace(("F2 found, calling brcmf_sdio_remove...\n")); - brcmf_sdio_remove(&sdmmc_dev); + sdiodev = dev_get_drvdata(&func->card->dev); + brcmf_dbg(TRACE, "F2 found, calling brcmf_sdio_remove...\n"); + brcmf_sdio_remove(sdiodev); + dev_set_drvdata(&func->card->dev, NULL); + kfree(sdiodev); } } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static int brcmf_sdio_suspend(struct device *dev) { mmc_pm_flag_t sdio_flags; + struct brcmf_sdio_dev *sdiodev; + struct sdio_func *func = dev_to_sdio_func(dev); int ret = 0; - sd_trace(("%s\n", __func__)); + brcmf_dbg(TRACE, "\n"); + + sdiodev = dev_get_drvdata(&func->card->dev); + + atomic_set(&sdiodev->suspend, true); - sdio_flags = sdio_get_host_pm_caps(gInstance->func[1]); + sdio_flags = sdio_get_host_pm_caps(sdiodev->func[1]); if (!(sdio_flags & MMC_PM_KEEP_POWER)) { - sd_err(("Host can't keep power while suspended\n")); + brcmf_dbg(ERROR, "Host can't keep power while suspended\n"); return -EINVAL; } - ret = sdio_set_host_pm_flags(gInstance->func[1], MMC_PM_KEEP_POWER); + ret = sdio_set_host_pm_flags(sdiodev->func[1], MMC_PM_KEEP_POWER); if (ret) { - sd_err(("Failed to set pm_flags\n")); + brcmf_dbg(ERROR, "Failed to set pm_flags\n"); return ret; } - brcmf_sdio_wdtmr_enable(false); + brcmf_sdio_wdtmr_enable(sdiodev, false); return ret; } static int brcmf_sdio_resume(struct device *dev) { - brcmf_sdio_wdtmr_enable(true); - return 0; -} -#endif /* CONFIG_PM */ - -int brcmf_sdioh_osinit(struct sdioh_info *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 brcmf_sdioh_osfree(struct sdioh_info *sd) -{ - struct sdos_info *sdos; - - sdos = (struct sdos_info *)sd->sdos_info; - kfree(sdos); -} - -/* Interrupt enable/disable */ -int brcmf_sdioh_interrupt_set(struct sdioh_info *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; - - if (enable && !(sd->intr_handler && sd->intr_handler_arg)) { - sd_err(("%s: no handler registered, will not enable\n", - __func__)); - return -EINVAL; - } - - /* Ensure atomicity for enable/disable calls */ - spin_lock_irqsave(&sdos->lock, flags); - - sd->client_intr_enabled = enable; - if (enable) - brcmf_sdioh_dev_intr_on(sd); - else - brcmf_sdioh_dev_intr_off(sd); - - spin_unlock_irqrestore(&sdos->lock, flags); + struct brcmf_sdio_dev *sdiodev; + struct sdio_func *func = dev_to_sdio_func(dev); + sdiodev = dev_get_drvdata(&func->card->dev); + brcmf_sdio_wdtmr_enable(sdiodev, true); + atomic_set(&sdiodev->suspend, false); return 0; } +#endif /* CONFIG_PM_SLEEP */ /* * module init @@ -1171,13 +672,8 @@ int brcmf_sdioh_interrupt_set(struct sdioh_info *sd, bool enable) int brcmf_sdio_function_init(void) { int error = 0; - sd_trace(("brcmf_sdio_function_init: %s Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); - gInstance = kzalloc(sizeof(struct brcmf_sdmmc_instance), GFP_KERNEL); - if (!gInstance) - return -ENOMEM; - - memset(&sdmmc_dev, 0, sizeof(sdmmc_dev)); error = sdio_register_driver(&brcmf_sdmmc_driver); return error; @@ -1188,9 +684,7 @@ int brcmf_sdio_function_init(void) */ void brcmf_sdio_function_cleanup(void) { - sd_trace(("%s Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); sdio_unregister_driver(&brcmf_sdmmc_driver); - - kfree(gInstance); } diff --git a/drivers/staging/brcm80211/brcmfmac/dhd.h b/drivers/staging/brcm80211/brcmfmac/dhd.h index 82bf04d..ee09c17 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd.h +++ b/drivers/staging/brcm80211/brcmfmac/dhd.h @@ -117,11 +117,16 @@ #define BRCMF_SCAN_RESULTS_ABORTED 3 #define BRCMF_SCAN_RESULTS_NO_MEM 4 -#define WL_SOFT_KEY (1 << 0) /* Indicates this key is using soft encrypt */ -#define BRCMF_PRIMARY_KEY (1 << 1) /* primary (ie tx) key */ -#define WL_KF_RES_4 (1 << 4) /* Reserved for backward compat */ -#define WL_KF_RES_5 (1 << 5) /* Reserved for backward compat */ -#define WL_IBSS_PEER_GROUP_KEY (1 << 6) /* Indicates a group key for a IBSS PEER */ +/* Indicates this key is using soft encrypt */ +#define WL_SOFT_KEY (1 << 0) +/* primary (ie tx) key */ +#define BRCMF_PRIMARY_KEY (1 << 1) +/* Reserved for backward compat */ +#define WL_KF_RES_4 (1 << 4) +/* Reserved for backward compat */ +#define WL_KF_RES_5 (1 << 5) +/* Indicates a group key for a IBSS PEER */ +#define WL_IBSS_PEER_GROUP_KEY (1 << 6) /* For supporting multiple interfaces */ #define BRCMF_MAX_IFS 16 @@ -333,13 +338,18 @@ enum brcmf_bus_state { * that indicates which bits within the pattern should be matched. */ struct brcmf_pkt_filter_pattern { - u32 offset; /* Offset within received packet to start pattern matching. - * Offset '0' is the first byte of the ethernet header. - */ - u32 size_bytes; /* Size of the pattern. Bitmask must be the same size. */ - u8 mask_and_pattern[1]; /* Variable length mask and pattern data. mask starts - * at offset 0. Pattern immediately follows mask. - */ + /* + * Offset within received packet to start pattern matching. + * Offset '0' is the first byte of the ethernet header. + */ + u32 offset; + /* Size of the pattern. Bitmask must be the same size.*/ + u32 size_bytes; + /* + * Variable length mask and pattern data. mask starts at offset 0. + * Pattern immediately follows mask. + */ + u8 mask_and_pattern[1]; }; /* IOVAR "pkt_filter_add" parameter. Used to install packet filters. */ @@ -373,10 +383,10 @@ struct brcmf_bss_info { u8 SSID_len; u8 SSID[32]; struct { - uint count; /* # rates in this set */ - u8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */ + uint count; /* # rates in this set */ + u8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */ } rateset; /* supported rates */ - chanspec_t chanspec; /* chanspec for bss */ + u16 chanspec; /* chanspec for bss */ u16 atim_window; /* units are Kusec */ u8 dtim_period; /* DTIM period */ s16 RSSI; /* receive signal strength (in dBm) */ @@ -409,7 +419,7 @@ struct brcmf_scan_params { * DOT11_BSSTYPE_ANY/INFRASTRUCTURE/INDEPENDENT */ u8 scan_type; /* flags, 0 use default */ - s32 nprobes; /* -1 use default, number of probes per channel */ + s32 nprobes; /* -1 use default, number of probes per channel */ s32 active_time; /* -1 use default, dwell time per channel for * active scanning */ @@ -460,14 +470,16 @@ struct brcmf_scan_results { /* used for association with a specific BSSID and chanspec list */ struct brcmf_assoc_params { - u8 bssid[ETH_ALEN]; /* 00:00:00:00:00:00: broadcast scan */ - s32 chanspec_num; /* 0: all available channels, - * otherwise count of chanspecs in chanspec_list - */ - chanspec_t chanspec_list[1]; /* list of chanspecs */ + /* 00:00:00:00:00:00: broadcast scan */ + u8 bssid[ETH_ALEN]; + /* 0: all available channels, otherwise count of chanspecs in + * chanspec_list */ + s32 chanspec_num; + /* list of chanspecs */ + u16 chanspec_list[1]; }; #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \ - (sizeof(struct brcmf_assoc_params) - sizeof(chanspec_t)) + (sizeof(struct brcmf_assoc_params) - sizeof(u16)) /* used for join with or without a specific bssid and channel list */ struct brcmf_join_params { @@ -495,8 +507,8 @@ struct brcmf_wsec_key { u32 len; /* key length */ u8 data[WLAN_MAX_KEY_LEN]; /* key data */ u32 pad_1[18]; - u32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */ - u32 flags; /* misc flags */ + u32 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */ + u32 flags; /* misc flags */ u32 pad_2[2]; int pad_3; int iv_initialized; /* has IV been initialized already? */ @@ -558,32 +570,45 @@ struct brcmf_pub { /* Dongle media info */ bool iswl; /* Dongle-resident driver is wl */ unsigned long drv_version; /* Version of dongle-resident driver */ - u8 mac[ETH_ALEN]; /* MAC address obtained from dongle */ + u8 mac[ETH_ALEN]; /* MAC address obtained from dongle */ struct dngl_stats dstats; /* Stats for dongle-based data */ /* Additional stats for the bus level */ - unsigned long tx_packets; /* Data packets sent to dongle */ - unsigned long tx_multicast; /* Multicast data packets sent to dongle */ - unsigned long tx_errors; /* Errors in sending data to dongle */ - unsigned long tx_ctlpkts; /* Control packets sent to dongle */ - unsigned long tx_ctlerrs; /* Errors sending control frames to dongle */ - unsigned long rx_packets; /* Packets sent up the network interface */ - unsigned long rx_multicast; /* Multicast packets sent up the network - interface */ - unsigned long rx_errors; /* Errors processing rx data packets */ - unsigned long rx_ctlpkts; /* Control frames processed from dongle */ - unsigned long rx_ctlerrs; /* Errors in processing rx control frames */ - unsigned long rx_dropped; /* Packets dropped locally (no memory) */ - unsigned long rx_flushed; /* Packets flushed due to - unscheduled sendup thread */ - unsigned long wd_dpc_sched; /* Number of times dpc scheduled by - watchdog timer */ - - unsigned long rx_readahead_cnt; /* Number of packets where header read-ahead - was used. */ - unsigned long tx_realloc; /* Number of tx packets we had to realloc for - headroom */ - unsigned long fc_packets; /* Number of flow control pkts recvd */ + + /* Data packets sent to dongle */ + unsigned long tx_packets; + /* Multicast data packets sent to dongle */ + unsigned long tx_multicast; + /* Errors in sending data to dongle */ + unsigned long tx_errors; + /* Control packets sent to dongle */ + unsigned long tx_ctlpkts; + /* Errors sending control frames to dongle */ + unsigned long tx_ctlerrs; + /* Packets sent up the network interface */ + unsigned long rx_packets; + /* Multicast packets sent up the network interface */ + unsigned long rx_multicast; + /* Errors processing rx data packets */ + unsigned long rx_errors; + /* Control frames processed from dongle */ + unsigned long rx_ctlpkts; + + /* Errors in processing rx control frames */ + unsigned long rx_ctlerrs; + /* Packets dropped locally (no memory) */ + unsigned long rx_dropped; + /* Packets flushed due to unscheduled sendup thread */ + unsigned long rx_flushed; + /* Number of times dpc scheduled by watchdog timer */ + unsigned long wd_dpc_sched; + + /* Number of packets where header read-ahead was used. */ + unsigned long rx_readahead_cnt; + /* Number of tx packets we had to realloc for headroom */ + unsigned long tx_realloc; + /* Number of flow control pkts recvd */ + unsigned long fc_packets; /* Last error return */ int bcmerror; @@ -614,67 +639,15 @@ struct brcmf_if_event { u8 bssidx; }; -struct brcmf_timeout { - u32 limit; /* Expiration time (usec) */ - u32 increment; /* Current expiration increment (usec) */ - u32 elapsed; /* Current elapsed time (usec) */ - u32 tick; /* O/S tick time (usec) */ -}; - struct bcmevent_name { uint event; const char *name; }; -#if defined(CONFIG_PM_SLEEP) -extern atomic_t brcmf_mmc_suspend; -#define BRCMF_PM_RESUME_WAIT_INIT(a) DECLARE_WAIT_QUEUE_HEAD(a); -#define _BRCMF_PM_RESUME_WAIT(a, b) do { \ - int retry = 0; \ - while (atomic_read(&brcmf_mmc_suspend) && retry++ != b) { \ - wait_event_timeout(a, false, HZ/100); \ - } \ - } while (0) -#define BRCMF_PM_RESUME_WAIT(a) _BRCMF_PM_RESUME_WAIT(a, 30) -#define BRCMF_PM_RESUME_RETURN_ERROR(a) \ - do { if (atomic_read(&brcmf_mmc_suspend)) return a; } while (0) - -#define BRCMF_SPINWAIT_SLEEP_INIT(a) DECLARE_WAIT_QUEUE_HEAD(a); -#define BRCMF_SPINWAIT_SLEEP(a, exp, us) do { \ - uint countdown = (us) + 9999; \ - while ((exp) && (countdown >= 10000)) { \ - wait_event_timeout(a, false, HZ/100); \ - countdown -= 10000; \ - } \ - } while (0) - -#else - -#define BRCMF_PM_RESUME_WAIT_INIT(a) -#define BRCMF_PM_RESUME_WAIT(a) -#define BRCMF_PM_RESUME_RETURN_ERROR(a) - -#define BRCMF_SPINWAIT_SLEEP_INIT(a) -#define BRCMF_SPINWAIT_SLEEP(a, exp, us) do { \ - uint countdown = (us) + 9; \ - while ((exp) && (countdown >= 10)) { \ - udelay(10); \ - countdown -= 10; \ - } \ - } while (0) - -#endif /* defined(CONFIG_PM_SLEEP) */ - /* * Insmod parameters for debug/test */ -/* Use interrupts */ -extern uint brcmf_intr; - -/* Use polling */ -extern uint brcmf_poll; - /* ARP offload agent mode */ extern uint brcmf_arp_mode; @@ -696,25 +669,9 @@ extern uint brcmf_roam; /* Roaming mode control */ extern uint brcmf_radio_up; -/* Initial idletime ticks (may be -1 for immediate idle, 0 for no idle) */ -extern int brcmf_idletime; -#define BRCMF_IDLETIME_TICKS 1 - -/* SDIO Drive Strength */ -extern uint brcmf_sdiod_drive_strength; - /* Override to force tx queueing all the time */ extern uint brcmf_force_tx_queueing; -#ifdef SDTEST -/* Echo packet generator (SDIO), pkts/s */ -extern uint brcmf_pktgen; - -/* Echo packet len (0 => sawtooth, max 1800) */ -extern uint brcmf_pktgen_len; -#define BRCMF_MAX_PKTGEN_LEN 1800 -#endif - extern const struct bcmevent_name bcmevent_names[]; extern const int bcmevent_names_size; @@ -792,18 +749,10 @@ extern int brcmf_proto_cdc_query_ioctl(struct brcmf_pub *drvr, int ifidx, /* OS independent layer functions */ extern int brcmf_os_proto_block(struct brcmf_pub *drvr); extern int brcmf_os_proto_unblock(struct brcmf_pub *drvr); -extern int brcmf_os_ioctl_resp_wait(struct brcmf_pub *drvr, uint *condition, - bool *pending); -extern int brcmf_os_ioctl_resp_wake(struct brcmf_pub *drvr); -extern unsigned int brcmf_os_get_ioctl_resp_timeout(void); -extern void brcmf_os_set_ioctl_resp_timeout(unsigned int timeout_msec); #ifdef BCMDBG extern int brcmf_write_to_file(struct brcmf_pub *drvr, u8 *buf, int size); #endif /* BCMDBG */ -extern void brcmf_timeout_start(struct brcmf_timeout *tmo, uint usec); -extern int brcmf_timeout_expired(struct brcmf_timeout *tmo); - extern int brcmf_ifname2idx(struct brcmf_info *drvr_priv, char *name); extern int brcmf_c_host_event(struct brcmf_info *drvr_priv, int *idx, void *pktdata, struct brcmf_event_msg *, @@ -811,8 +760,9 @@ extern int brcmf_c_host_event(struct brcmf_info *drvr_priv, int *idx, extern void brcmf_c_init(void); -extern int brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx, void *handle, - char *name, u8 *mac_addr, u32 flags, u8 bssidx); +extern int brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx, + struct net_device *net, char *name, u8 *mac_addr, + u32 flags, u8 bssidx); extern void brcmf_del_if(struct brcmf_info *drvr_priv, int ifidx); /* Send packet to dongle via data channel */ @@ -865,34 +815,6 @@ struct brcmf_c_ioctl { #define BRCMF_BTA_VAL 0x1000 #define BRCMF_ISCAN_VAL 0x2000 -#ifdef SDTEST -/* For pktgen iovar */ -struct brcmf_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 */ -}; - -/* Version in case structure changes */ -#define BRCMF_PKTGEN_VERSION 2 - -/* Type of test packets to use */ -#define BRCMF_PKTGEN_ECHO 1 /* Send echo requests */ -#define BRCMF_PKTGEN_SEND 2 /* Send discard packets */ -#define BRCMF_PKTGEN_RXBURST 3 /* Request dongle send N packets */ -#define BRCMF_PKTGEN_RECV 4 /* Continuous rx from continuous - tx dongle */ -#endif /* SDTEST */ - /* Enter idle immediately (no timeout) */ #define BRCMF_IDLE_IMMEDIATE (-1) diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_bus.h b/drivers/staging/brcm80211/brcmfmac/dhd_bus.h index 653cf0d..24f578a 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_bus.h +++ b/drivers/staging/brcm80211/brcmfmac/dhd_bus.h @@ -18,12 +18,7 @@ #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 +#define BRCMF_SDALIGN (1 << 6) /* * Exported from brcmf bus module (brcmf_usb, brcmf_sdio) diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c b/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c index 345acab..1ac8057 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c @@ -104,7 +104,7 @@ static int brcmf_proto_cdc_msg(struct brcmf_pub *drvr) int len = le32_to_cpu(prot->msg.len) + sizeof(struct brcmf_proto_cdc_ioctl); - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); /* NOTE : cdc->msg.len holds the desired length of the buffer to be * returned. Only up to CDC_MAX_MSG_SIZE of this buffer area @@ -123,7 +123,7 @@ static int brcmf_proto_cdc_cmplt(struct brcmf_pub *drvr, u32 id, u32 len) int ret; struct brcmf_proto *prot = drvr->prot; - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); do { ret = brcmf_sdbrcm_bus_rxctl(drvr->bus, @@ -146,8 +146,8 @@ brcmf_proto_cdc_query_ioctl(struct brcmf_pub *drvr, int ifidx, uint cmd, int ret = 0, retries = 0; u32 id, flags = 0; - BRCMF_TRACE(("%s: Enter\n", __func__)); - BRCMF_CTL(("%s: cmd %d len %d\n", __func__, cmd, len)); + brcmf_dbg(TRACE, "Enter\n"); + brcmf_dbg(CTL, "cmd %d len %d\n", cmd, len); /* Respond "bcmerror" and "bcmerrorstr" with local cache */ if (cmd == BRCMF_C_GET_VAR && buf) { @@ -174,8 +174,8 @@ brcmf_proto_cdc_query_ioctl(struct brcmf_pub *drvr, int ifidx, uint cmd, ret = brcmf_proto_cdc_msg(drvr); if (ret < 0) { - BRCMF_ERROR(("brcmf_proto_cdc_query_ioctl: brcmf_proto_cdc_msg " - "failed w/status %d\n", ret)); + brcmf_dbg(ERROR, "brcmf_proto_cdc_msg failed w/status %d\n", + ret); goto done; } @@ -191,9 +191,8 @@ retry: if ((id < prot->reqid) && (++retries < RETRIES)) goto retry; if (id != prot->reqid) { - BRCMF_ERROR(("%s: %s: unexpected request id %d (expected %d)\n", - brcmf_ifname(drvr, ifidx), __func__, id, - prot->reqid)); + brcmf_dbg(ERROR, "%s: unexpected request id %d (expected %d)\n", + brcmf_ifname(drvr, ifidx), id, prot->reqid); ret = -EINVAL; goto done; } @@ -227,8 +226,8 @@ int brcmf_proto_cdc_set_ioctl(struct brcmf_pub *drvr, int ifidx, uint cmd, int ret = 0; u32 flags, id; - BRCMF_TRACE(("%s: Enter\n", __func__)); - BRCMF_CTL(("%s: cmd %d len %d\n", __func__, cmd, len)); + brcmf_dbg(TRACE, "Enter\n"); + brcmf_dbg(CTL, "cmd %d len %d\n", cmd, len); memset(msg, 0, sizeof(struct brcmf_proto_cdc_ioctl)); @@ -253,9 +252,8 @@ int brcmf_proto_cdc_set_ioctl(struct brcmf_pub *drvr, int ifidx, uint cmd, id = (flags & CDCF_IOC_ID_MASK) >> CDCF_IOC_ID_SHIFT; if (id != prot->reqid) { - BRCMF_ERROR(("%s: %s: unexpected request id %d (expected %d)\n", - brcmf_ifname(drvr, ifidx), __func__, id, - prot->reqid)); + brcmf_dbg(ERROR, "%s: unexpected request id %d (expected %d)\n", + brcmf_ifname(drvr, ifidx), id, prot->reqid); ret = -EINVAL; goto done; } @@ -279,25 +277,23 @@ brcmf_proto_ioctl(struct brcmf_pub *drvr, int ifidx, struct brcmf_ioctl *ioc, int ret = -1; if (drvr->busstate == BRCMF_BUS_DOWN) { - BRCMF_ERROR(("%s : bus is down. we have nothing to do\n", - __func__)); + brcmf_dbg(ERROR, "bus is down. we have nothing to do.\n"); return ret; } brcmf_os_proto_block(drvr); - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); if (len > BRCMF_C_IOCTL_MAXLEN) goto done; if (prot->pending == true) { - 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)); + brcmf_dbg(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)); + brcmf_dbg(TRACE, "iovar cmd=%s\n", (char *)buf); goto done; } @@ -358,7 +354,7 @@ void brcmf_proto_hdrpush(struct brcmf_pub *drvr, int ifidx, { struct brcmf_proto_bdc_header *h; - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); /* Push BDC header used to convey priority for buses that don't */ @@ -381,13 +377,13 @@ int brcmf_proto_hdrpull(struct brcmf_pub *drvr, int *ifidx, { struct brcmf_proto_bdc_header *h; - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); /* Pop BDC header used to convey priority for buses that don't */ if (pktbuf->len < BDC_HEADER_LEN) { - BRCMF_ERROR(("%s: rx data too short (%d < %d)\n", __func__, - pktbuf->len, BDC_HEADER_LEN)); + brcmf_dbg(ERROR, "rx data too short (%d < %d)\n", + pktbuf->len, BDC_HEADER_LEN); return -EBADE; } @@ -395,22 +391,20 @@ int brcmf_proto_hdrpull(struct brcmf_pub *drvr, int *ifidx, *ifidx = BDC_GET_IF_IDX(h); if (*ifidx >= BRCMF_MAX_IFS) { - BRCMF_ERROR(("%s: rx data ifnum out of range (%d)\n", - __func__, *ifidx)); + brcmf_dbg(ERROR, "rx data ifnum out of range (%d)\n", *ifidx); return -EBADE; } if (((h->flags & BDC_FLAG_VER_MASK) >> BDC_FLAG_VER_SHIFT) != BDC_PROTO_VER) { - BRCMF_ERROR(("%s: non-BDC packet received, flags 0x%x\n", - brcmf_ifname(drvr, *ifidx), h->flags)); + brcmf_dbg(ERROR, "%s: non-BDC packet received, flags 0x%x\n", + brcmf_ifname(drvr, *ifidx), h->flags); return -EBADE; } if (h->flags & BDC_FLAG_SUM_GOOD) { - BRCMF_INFO(("%s: BDC packet received with good rx-csum, " - "flags 0x%x\n", - brcmf_ifname(drvr, *ifidx), h->flags)); + brcmf_dbg(INFO, "%s: BDC packet received with good rx-csum, flags 0x%x\n", + brcmf_ifname(drvr, *ifidx), h->flags); PKTSETSUMGOOD(pktbuf, true); } @@ -427,13 +421,13 @@ int brcmf_proto_attach(struct brcmf_pub *drvr) cdc = kzalloc(sizeof(struct brcmf_proto), GFP_ATOMIC); if (!cdc) { - BRCMF_ERROR(("%s: kmalloc failed\n", __func__)); + brcmf_dbg(ERROR, "kmalloc failed\n"); goto fail; } /* ensure that the msg buf directly follows the cdc msg struct */ if ((unsigned long)(&cdc->msg + 1) != (unsigned long)cdc->buf) { - BRCMF_ERROR(("struct brcmf_proto is not correctly defined\n")); + brcmf_dbg(ERROR, "struct brcmf_proto is not correctly defined\n"); goto fail; } @@ -472,7 +466,7 @@ int brcmf_proto_init(struct brcmf_pub *drvr) int ret = 0; char buf[128]; - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); brcmf_os_proto_block(drvr); diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_common.c b/drivers/staging/brcm80211/brcmfmac/dhd_common.c index fdec468..059289a 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_common.c @@ -55,7 +55,6 @@ enum { IOV_LOGCAL, IOV_LOGSTAMP, IOV_GPIOOB, - IOV_IOCTLTIMEOUT, IOV_LAST }; @@ -76,8 +75,6 @@ const struct brcmu_iovar brcmf_iovars[] = { , {"gpioob", IOV_GPIOOB, 0, IOVT_UINT32, 0} , - {"ioctl_timeout", IOV_IOCTLTIMEOUT, 0, IOVT_UINT32, 0} - , {NULL, 0, 0, 0, 0} }; @@ -175,7 +172,7 @@ brcmf_c_doiovar(struct brcmf_pub *drvr, const struct brcmu_iovar *vi, int bcmerror = 0; s32 int_val = 0; - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); bcmerror = brcmu_iovar_lencheck(vi, arg, len, IOV_ISSET(actionid)); if (bcmerror != 0) @@ -227,21 +224,6 @@ brcmf_c_doiovar(struct brcmf_pub *drvr, const struct brcmu_iovar *vi, brcmf_bus_clearcounts(drvr); break; - case IOV_GVAL(IOV_IOCTLTIMEOUT):{ - int_val = (s32) brcmf_os_get_ioctl_resp_timeout(); - memcpy(arg, &int_val, sizeof(int_val)); - break; - } - - case IOV_SVAL(IOV_IOCTLTIMEOUT):{ - if (int_val <= 0) - bcmerror = -EINVAL; - else - brcmf_os_set_ioctl_resp_timeout((unsigned int) - int_val); - break; - } - default: bcmerror = -ENOTSUPP; break; @@ -284,18 +266,17 @@ bool brcmf_c_prec_enq(struct brcmf_pub *drvr, struct pktq *q, /* Evict packet according to discard policy */ p = discard_oldest ? brcmu_pktq_pdeq(q, eprec) : brcmu_pktq_pdeq_tail(q, eprec); - if (p == NULL) { - BRCMF_ERROR(("%s: brcmu_pktq_penq() failed, oldest %d.", - __func__, discard_oldest)); - } + if (p == NULL) + brcmf_dbg(ERROR, "brcmu_pktq_penq() failed, oldest %d\n", + discard_oldest); + brcmu_pkt_buf_free_skb(p); } /* Enqueue */ p = brcmu_pktq_penq(q, prec, pkt); - if (p == NULL) { - BRCMF_ERROR(("%s: brcmu_pktq_penq() failed.", __func__)); - } + if (p == NULL) + brcmf_dbg(ERROR, "brcmu_pktq_penq() failed\n"); return p != NULL; } @@ -309,9 +290,9 @@ brcmf_c_iovar_op(struct brcmf_pub *drvr, const char *name, const struct brcmu_iovar *vi = NULL; u32 actionid; - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); - if (name == NULL || len <= 0) + if (name == NULL || len < 0) return -EINVAL; /* Set does not take qualifiers */ @@ -328,8 +309,8 @@ brcmf_c_iovar_op(struct brcmf_pub *drvr, const char *name, goto exit; } - BRCMF_CTL(("%s: %s %s, len %d plen %d\n", __func__, - name, (set ? "set" : "get"), len, plen)); + brcmf_dbg(CTL, "%s %s, len %d plen %d\n", + name, set ? "set" : "get", len, plen); /* set up 'params' pointer in case this is a set command so that * the convenience int and bool code can be common to set and get @@ -361,7 +342,7 @@ int brcmf_c_ioctl(struct brcmf_pub *drvr, struct brcmf_c_ioctl *ioc, void *buf, { int bcmerror = 0; - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); if (!buf) return -EINVAL; @@ -517,9 +498,9 @@ brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data) event_name = event_names[i].event_name; } - BRCMF_EVENT(("EVENT: %s, event ID = %d\n", event_name, event_type)); - BRCMF_EVENT(("flags 0x%04x, status %d, reason %d, auth_type %d" - " MAC %s\n", flags, status, reason, auth_type, eabuf)); + brcmf_dbg(EVENT, "EVENT: %s, event ID = %d\n", event_name, event_type); + brcmf_dbg(EVENT, "flags 0x%04x, status %d, reason %d, auth_type %d MAC %s\n", + flags, status, reason, auth_type, eabuf); if (flags & BRCMF_EVENT_MSG_LINK) link = true; @@ -532,36 +513,34 @@ brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data) case BRCMF_E_START: case BRCMF_E_DEAUTH: case BRCMF_E_DISASSOC: - BRCMF_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf)); + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", event_name, eabuf); break; case BRCMF_E_ASSOC_IND: case BRCMF_E_REASSOC_IND: - BRCMF_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf)); + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", event_name, eabuf); break; case BRCMF_E_ASSOC: case BRCMF_E_REASSOC: - if (status == BRCMF_E_STATUS_SUCCESS) { - BRCMF_EVENT(("MACEVENT: %s, MAC %s, SUCCESS\n", - event_name, eabuf)); - } else if (status == BRCMF_E_STATUS_TIMEOUT) { - BRCMF_EVENT(("MACEVENT: %s, MAC %s, TIMEOUT\n", - event_name, eabuf)); - } else if (status == BRCMF_E_STATUS_FAIL) { - BRCMF_EVENT(("MACEVENT: %s, MAC %s, FAILURE," - " reason %d\n", event_name, eabuf, - (int)reason)); - } else { - BRCMF_EVENT(("MACEVENT: %s, MAC %s, unexpected status " - "%d\n", event_name, eabuf, (int)status)); - } + if (status == BRCMF_E_STATUS_SUCCESS) + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, SUCCESS\n", + event_name, eabuf); + else if (status == BRCMF_E_STATUS_TIMEOUT) + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, TIMEOUT\n", + event_name, eabuf); + else if (status == BRCMF_E_STATUS_FAIL) + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, FAILURE, reason %d\n", + event_name, eabuf, (int)reason); + else + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, unexpected status %d\n", + event_name, eabuf, (int)status); break; case BRCMF_E_DEAUTH_IND: case BRCMF_E_DISASSOC_IND: - BRCMF_EVENT(("MACEVENT: %s, MAC %s, reason %d\n", event_name, - eabuf, (int)reason)); + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, reason %d\n", + event_name, eabuf, (int)reason); break; case BRCMF_E_AUTH: @@ -574,19 +553,18 @@ brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data) sprintf(err_msg, "AUTH unknown: %d", (int)auth_type); auth_str = err_msg; } - if (event_type == BRCMF_E_AUTH_IND) { - BRCMF_EVENT(("MACEVENT: %s, MAC %s, %s\n", event_name, - eabuf, auth_str)); - } else if (status == BRCMF_E_STATUS_SUCCESS) { - BRCMF_EVENT(("MACEVENT: %s, MAC %s, %s, SUCCESS\n", - event_name, eabuf, auth_str)); - } else if (status == BRCMF_E_STATUS_TIMEOUT) { - BRCMF_EVENT(("MACEVENT: %s, MAC %s, %s, TIMEOUT\n", - event_name, eabuf, auth_str)); - } else if (status == BRCMF_E_STATUS_FAIL) { - BRCMF_EVENT(("MACEVENT: %s, MAC %s, %s, FAILURE, " - "reason %d\n", - event_name, eabuf, auth_str, (int)reason)); + if (event_type == BRCMF_E_AUTH_IND) + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s\n", + event_name, eabuf, auth_str); + else if (status == BRCMF_E_STATUS_SUCCESS) + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s, SUCCESS\n", + event_name, eabuf, auth_str); + else if (status == BRCMF_E_STATUS_TIMEOUT) + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s, TIMEOUT\n", + event_name, eabuf, auth_str); + else if (status == BRCMF_E_STATUS_FAIL) { + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, %s, FAILURE, reason %d\n", + event_name, eabuf, auth_str, (int)reason); } break; @@ -594,66 +572,64 @@ brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data) case BRCMF_E_JOIN: case BRCMF_E_ROAM: case BRCMF_E_SET_SSID: - if (status == BRCMF_E_STATUS_SUCCESS) { - BRCMF_EVENT(("MACEVENT: %s, MAC %s\n", event_name, - eabuf)); - } else if (status == BRCMF_E_STATUS_FAIL) { - BRCMF_EVENT(("MACEVENT: %s, failed\n", event_name)); - } else if (status == BRCMF_E_STATUS_NO_NETWORKS) { - BRCMF_EVENT(("MACEVENT: %s, no networks found\n", - event_name)); - } else { - BRCMF_EVENT(("MACEVENT: %s, unexpected status %d\n", - event_name, (int)status)); - } + if (status == BRCMF_E_STATUS_SUCCESS) + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", + event_name, eabuf); + else if (status == BRCMF_E_STATUS_FAIL) + brcmf_dbg(EVENT, "MACEVENT: %s, failed\n", event_name); + else if (status == BRCMF_E_STATUS_NO_NETWORKS) + brcmf_dbg(EVENT, "MACEVENT: %s, no networks found\n", + event_name); + else + brcmf_dbg(EVENT, "MACEVENT: %s, unexpected status %d\n", + event_name, (int)status); break; case BRCMF_E_BEACON_RX: - if (status == BRCMF_E_STATUS_SUCCESS) { - BRCMF_EVENT(("MACEVENT: %s, SUCCESS\n", event_name)); - } else if (status == BRCMF_E_STATUS_FAIL) { - BRCMF_EVENT(("MACEVENT: %s, FAIL\n", event_name)); - } else { - BRCMF_EVENT(("MACEVENT: %s, status %d\n", event_name, - status)); - } + if (status == BRCMF_E_STATUS_SUCCESS) + brcmf_dbg(EVENT, "MACEVENT: %s, SUCCESS\n", event_name); + else if (status == BRCMF_E_STATUS_FAIL) + brcmf_dbg(EVENT, "MACEVENT: %s, FAIL\n", event_name); + else + brcmf_dbg(EVENT, "MACEVENT: %s, status %d\n", + event_name, status); break; case BRCMF_E_LINK: - BRCMF_EVENT(("MACEVENT: %s %s\n", event_name, - link ? "UP" : "DOWN")); + brcmf_dbg(EVENT, "MACEVENT: %s %s\n", + event_name, link ? "UP" : "DOWN"); break; case BRCMF_E_MIC_ERROR: - BRCMF_EVENT(("MACEVENT: %s, MAC %s, Group %d, Flush %d\n", - event_name, eabuf, group, flush_txq)); + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s, Group %d, Flush %d\n", + event_name, eabuf, group, flush_txq); break; case BRCMF_E_ICV_ERROR: case BRCMF_E_UNICAST_DECODE_ERROR: case BRCMF_E_MULTICAST_DECODE_ERROR: - BRCMF_EVENT(("MACEVENT: %s, MAC %s\n", event_name, eabuf)); + brcmf_dbg(EVENT, "MACEVENT: %s, MAC %s\n", event_name, eabuf); break; case BRCMF_E_TXFAIL: - BRCMF_EVENT(("MACEVENT: %s, RA %s\n", event_name, eabuf)); + brcmf_dbg(EVENT, "MACEVENT: %s, RA %s\n", event_name, eabuf); break; case BRCMF_E_SCAN_COMPLETE: case BRCMF_E_PMKID_CACHE: - BRCMF_EVENT(("MACEVENT: %s\n", event_name)); + brcmf_dbg(EVENT, "MACEVENT: %s\n", event_name); break; case BRCMF_E_PFN_NET_FOUND: case BRCMF_E_PFN_NET_LOST: case BRCMF_E_PFN_SCAN_COMPLETE: - BRCMF_EVENT(("PNOEVENT: %s\n", event_name)); + brcmf_dbg(EVENT, "PNOEVENT: %s\n", event_name); break; case BRCMF_E_PSK_SUP: case BRCMF_E_PRUNE: - BRCMF_EVENT(("MACEVENT: %s, status %d, reason %d\n", - event_name, (int)status, (int)reason)); + brcmf_dbg(EVENT, "MACEVENT: %s, status %d, reason %d\n", + event_name, (int)status, (int)reason); break; case BRCMF_E_TRACE: @@ -667,11 +643,9 @@ brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data) memcpy(&hdr, buf, sizeof(struct msgtrace_hdr)); if (hdr.version != MSGTRACE_VERSION) { - BRCMF_ERROR( - ("\nMACEVENT: %s [unsupported version --> " - "brcmf version:%d dongle version:%d]\n", - event_name, MSGTRACE_VERSION, hdr.version) - ); + brcmf_dbg(ERROR, "MACEVENT: %s [unsupported version --> brcmf version:%d dongle version:%d]\n", + event_name, + MSGTRACE_VERSION, hdr.version); /* Reset datalen to avoid display below */ datalen = 0; break; @@ -682,20 +656,15 @@ brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data) + be16_to_cpu(hdr.len)) = '\0'; if (be32_to_cpu(hdr.discarded_bytes) - || be32_to_cpu(hdr.discarded_printf)) { - BRCMF_ERROR( - ("\nWLC_E_TRACE: [Discarded traces in dongle -->" - "discarded_bytes %d discarded_printf %d]\n", - be32_to_cpu(hdr.discarded_bytes), - be32_to_cpu(hdr.discarded_printf))); - } + || be32_to_cpu(hdr.discarded_printf)) + brcmf_dbg(ERROR, "WLC_E_TRACE: [Discarded traces in dongle --> discarded_bytes %d discarded_printf %d]\n", + be32_to_cpu(hdr.discarded_bytes), + be32_to_cpu(hdr.discarded_printf)); nblost = be32_to_cpu(hdr.seqnum) - seqnum_prev - 1; - if (nblost > 0) { - BRCMF_ERROR( - ("\nWLC_E_TRACE: [Event lost --> seqnum %d nblost %d\n", - be32_to_cpu(hdr.seqnum), nblost)); - } + if (nblost > 0) + brcmf_dbg(ERROR, "WLC_E_TRACE: [Event lost --> seqnum %d nblost %d\n", + be32_to_cpu(hdr.seqnum), nblost); seqnum_prev = be32_to_cpu(hdr.seqnum); /* Display the trace buffer. Advance from \n to \n to @@ -716,24 +685,24 @@ brcmf_c_show_host_event(struct brcmf_event_msg *event, void *event_data) break; case BRCMF_E_RSSI: - BRCMF_EVENT(("MACEVENT: %s %d\n", event_name, - be32_to_cpu(*((int *)event_data)))); + brcmf_dbg(EVENT, "MACEVENT: %s %d\n", + event_name, be32_to_cpu(*((int *)event_data))); break; default: - BRCMF_EVENT(("MACEVENT: %s %d, MAC %s, status %d, reason %d, " - "auth %d\n", event_name, event_type, eabuf, - (int)status, (int)reason, (int)auth_type)); + brcmf_dbg(EVENT, "MACEVENT: %s %d, MAC %s, status %d, reason %d, auth %d\n", + event_name, event_type, eabuf, + (int)status, (int)reason, (int)auth_type); break; } /* show any appended data */ if (datalen) { buf = (unsigned char *) event_data; - BRCMF_EVENT((" data (%d) : ", datalen)); + brcmf_dbg(EVENT, " data (%d) : ", datalen); for (i = 0; i < datalen; i++) - BRCMF_EVENT((" 0x%02x ", *buf++)); - BRCMF_EVENT(("\n")); + brcmf_dbg(EVENT, " 0x%02x ", *buf++); + brcmf_dbg(EVENT, "\n"); } } #endif /* SHOW_EVENTS */ @@ -750,14 +719,14 @@ brcmf_c_host_event(struct brcmf_info *drvr_priv, int *ifidx, void *pktdata, int evlen; if (memcmp(BRCM_OUI, &pvt_data->hdr.oui[0], DOT11_OUI_LEN)) { - BRCMF_ERROR(("%s: mismatched OUI, bailing\n", __func__)); + brcmf_dbg(ERROR, "mismatched OUI, bailing\n"); return -EBADE; } /* BRCM event pkt may be unaligned - use xxx_ua to load user_subtype. */ if (get_unaligned_be16(&pvt_data->hdr.usr_subtype) != BCMILCP_BCM_SUBTYPE_EVENT) { - BRCMF_ERROR(("%s: mismatched subtype, bailing\n", __func__)); + brcmf_dbg(ERROR, "mismatched subtype, bailing\n"); return -EBADE; } @@ -778,7 +747,7 @@ brcmf_c_host_event(struct brcmf_info *drvr_priv, int *ifidx, void *pktdata, { struct brcmf_if_event *ifevent = (struct brcmf_if_event *) event_data; - BRCMF_TRACE(("%s: if event\n", __func__)); + brcmf_dbg(TRACE, "if event\n"); if (ifevent->ifidx > 0 && ifevent->ifidx < BRCMF_MAX_IFS) { @@ -791,9 +760,8 @@ brcmf_c_host_event(struct brcmf_info *drvr_priv, int *ifidx, void *pktdata, else brcmf_del_if(drvr_priv, ifevent->ifidx); } else { - BRCMF_ERROR(("%s: Invalid ifidx %d for %s\n", - __func__, ifevent->ifidx, - event->ifname)); + brcmf_dbg(ERROR, "Invalid ifidx %d for %s\n", + ifevent->ifidx, event->ifname); } } /* send up the if event: btamp user needs it */ @@ -810,16 +778,16 @@ brcmf_c_host_event(struct brcmf_info *drvr_priv, int *ifidx, void *pktdata, /* Fall through: this should get _everything_ */ *ifidx = brcmf_ifname2idx(drvr_priv, event->ifname); - BRCMF_TRACE(("%s: MAC event %d, flags %x, status %x\n", - __func__, type, flags, status)); + brcmf_dbg(TRACE, "MAC event %d, flags %x, status %x\n", + type, flags, status); /* put it back to BRCMF_E_NDIS_LINK */ if (type == BRCMF_E_NDIS_LINK) { u32 temp; temp = get_unaligned_be32(&event->event_type); - BRCMF_TRACE(("Converted to WLC_E_LINK type %d\n", - temp)); + brcmf_dbg(TRACE, "Converted to WLC_E_LINK type %d\n", + temp); temp = be32_to_cpu(BRCMF_E_NDIS_LINK); memcpy((void *)(&pvt_data->msg.event_type), &temp, @@ -840,19 +808,22 @@ static int brcmf_c_pattern_atoh(char *src, char *dst) { int i; if (strncmp(src, "0x", 2) != 0 && strncmp(src, "0X", 2) != 0) { - BRCMF_ERROR(("Mask invalid format. Needs to start with 0x\n")); - return -1; + brcmf_dbg(ERROR, "Mask invalid format. Needs to start with 0x\n"); + return -EINVAL; } src = src + 2; /* Skip past 0x */ if (strlen(src) % 2 != 0) { - BRCMF_ERROR(("Mask invalid format. Length must be even.\n")); - return -1; + brcmf_dbg(ERROR, "Mask invalid format. Length must be even.\n"); + return -EINVAL; } for (i = 0; *src != '\0'; i++) { + unsigned long res; char num[3]; strncpy(num, src, 2); num[2] = '\0'; - dst[i] = (u8) simple_strtoul(num, NULL, 16); + if (kstrtoul(num, 16, &res)) + return -EINVAL; + dst[i] = (u8)res; src += 2; } return i; @@ -862,6 +833,7 @@ void brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg, int enable, int master_mode) { + unsigned long res; char *argv[8]; int i = 0; const char *str; @@ -875,7 +847,7 @@ brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg, int enable, arg_save = kmalloc(strlen(arg) + 1, GFP_ATOMIC); if (!arg_save) { - BRCMF_ERROR(("%s: kmalloc failed\n", __func__)); + brcmf_dbg(ERROR, "kmalloc failed\n"); goto fail; } arg_org = arg_save; @@ -885,7 +857,7 @@ brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg, int enable, i = 0; if (NULL == argv[i]) { - BRCMF_ERROR(("No args provided\n")); + brcmf_dbg(ERROR, "No args provided\n"); goto fail; } @@ -898,7 +870,9 @@ brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg, int enable, pkt_filterp = (struct brcmf_pkt_filter_enable *) (buf + str_len + 1); /* Parse packet filter id. */ - enable_parm.id = simple_strtoul(argv[i], NULL, 0); + enable_parm.id = 0; + if (!kstrtoul(argv[i], 0, &res)) + enable_parm.id = (u32)res; /* Parse enable/disable value. */ enable_parm.enable = enable; @@ -910,11 +884,10 @@ brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg, int enable, rc = brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_VAR, buf, buf_len); rc = rc >= 0 ? 0 : rc; if (rc) - BRCMF_TRACE(("%s: failed to add pktfilter %s, retcode = %d\n", - __func__, arg, rc)); + brcmf_dbg(TRACE, "failed to add pktfilter %s, retcode = %d\n", + arg, rc); else - BRCMF_TRACE(("%s: successfully added pktfilter %s\n", - __func__, arg)); + brcmf_dbg(TRACE, "successfully added pktfilter %s\n", arg); /* Contorl the master mode */ brcmu_mkiovar("pkt_filter_mode", (char *)&master_mode, 4, buf, @@ -923,8 +896,8 @@ brcmf_c_pktfilter_offload_enable(struct brcmf_pub *drvr, char *arg, int enable, sizeof(buf)); rc = rc >= 0 ? 0 : rc; if (rc) - BRCMF_TRACE(("%s: failed to add pktfilter %s, retcode = %d\n", - __func__, arg, rc)); + brcmf_dbg(TRACE, "failed to add pktfilter %s, retcode = %d\n", + arg, rc); fail: kfree(arg_org); @@ -935,6 +908,7 @@ void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg) const char *str; struct brcmf_pkt_filter pkt_filter; struct brcmf_pkt_filter *pkt_filterp; + unsigned long res; int buf_len; int str_len; int rc; @@ -944,9 +918,9 @@ void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg) int i = 0; char *arg_save = 0, *arg_org = 0; - arg_save = kmalloc(strlen(arg) + 1, GFP_ATOMIC); + arg_save = kstrdup(arg, GFP_ATOMIC); if (!arg_save) { - BRCMF_ERROR(("%s: kmalloc failed\n", __func__)); + brcmf_dbg(ERROR, "kmalloc failed\n"); goto fail; } @@ -954,19 +928,17 @@ void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg) buf = kmalloc(PKTFILTER_BUF_SIZE, GFP_ATOMIC); if (!buf) { - BRCMF_ERROR(("%s: kmalloc failed\n", __func__)); + brcmf_dbg(ERROR, "kmalloc failed\n"); goto fail; } - strcpy(arg_save, arg); - argv[i] = strsep(&arg_save, " "); while (argv[i++]) argv[i] = strsep(&arg_save, " "); i = 0; if (NULL == argv[i]) { - BRCMF_ERROR(("No args provided\n")); + brcmf_dbg(ERROR, "No args provided\n"); goto fail; } @@ -978,34 +950,42 @@ void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg) pkt_filterp = (struct brcmf_pkt_filter *) (buf + str_len + 1); /* Parse packet filter id. */ - pkt_filter.id = simple_strtoul(argv[i], NULL, 0); + pkt_filter.id = 0; + if (!kstrtoul(argv[i], 0, &res)) + pkt_filter.id = (u32)res; if (NULL == argv[++i]) { - BRCMF_ERROR(("Polarity not provided\n")); + brcmf_dbg(ERROR, "Polarity not provided\n"); goto fail; } /* Parse filter polarity. */ - pkt_filter.negate_match = simple_strtoul(argv[i], NULL, 0); + pkt_filter.negate_match = 0; + if (!kstrtoul(argv[i], 0, &res)) + pkt_filter.negate_match = (u32)res; if (NULL == argv[++i]) { - BRCMF_ERROR(("Filter type not provided\n")); + brcmf_dbg(ERROR, "Filter type not provided\n"); goto fail; } /* Parse filter type. */ - pkt_filter.type = simple_strtoul(argv[i], NULL, 0); + pkt_filter.type = 0; + if (!kstrtoul(argv[i], 0, &res)) + pkt_filter.type = (u32)res; if (NULL == argv[++i]) { - BRCMF_ERROR(("Offset not provided\n")); + brcmf_dbg(ERROR, "Offset not provided\n"); goto fail; } /* Parse pattern filter offset. */ - pkt_filter.u.pattern.offset = simple_strtoul(argv[i], NULL, 0); + pkt_filter.u.pattern.offset = 0; + if (!kstrtoul(argv[i], 0, &res)) + pkt_filter.u.pattern.offset = (u32)res; if (NULL == argv[++i]) { - BRCMF_ERROR(("Bitmask not provided\n")); + brcmf_dbg(ERROR, "Bitmask not provided\n"); goto fail; } @@ -1015,7 +995,7 @@ void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg) (argv[i], (char *)pkt_filterp->u.pattern.mask_and_pattern); if (NULL == argv[++i]) { - BRCMF_ERROR(("Pattern not provided\n")); + brcmf_dbg(ERROR, "Pattern not provided\n"); goto fail; } @@ -1026,7 +1006,7 @@ void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg) mask_and_pattern[mask_size]); if (mask_size != pattern_size) { - BRCMF_ERROR(("Mask and pattern not the same size\n")); + brcmf_dbg(ERROR, "Mask and pattern not the same size\n"); goto fail; } @@ -1047,11 +1027,10 @@ void brcmf_c_pktfilter_offload_set(struct brcmf_pub *drvr, char *arg) rc = rc >= 0 ? 0 : rc; if (rc) - BRCMF_TRACE(("%s: failed to add pktfilter %s, retcode = %d\n", - __func__, arg, rc)); + brcmf_dbg(TRACE, "failed to add pktfilter %s, retcode = %d\n", + arg, rc); else - BRCMF_TRACE(("%s: successfully added pktfilter %s\n", - __func__, arg)); + brcmf_dbg(TRACE, "successfully added pktfilter %s\n", arg); fail: kfree(arg_org); @@ -1069,11 +1048,11 @@ void brcmf_c_arp_offload_set(struct brcmf_pub *drvr, int arp_mode) iovbuf, sizeof(iovbuf)); retcode = retcode >= 0 ? 0 : retcode; if (retcode) - BRCMF_TRACE(("%s: failed to set ARP offload mode to 0x%x, " - "retcode = %d\n", __func__, arp_mode, retcode)); + brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, retcode = %d\n", + arp_mode, retcode); else - BRCMF_TRACE(("%s: successfully set ARP offload mode to 0x%x\n", - __func__, arp_mode)); + brcmf_dbg(TRACE, "successfully set ARP offload mode to 0x%x\n", + arp_mode); } void brcmf_c_arp_offload_enable(struct brcmf_pub *drvr, int arp_enable) @@ -1086,11 +1065,11 @@ void brcmf_c_arp_offload_enable(struct brcmf_pub *drvr, int arp_enable) iovbuf, sizeof(iovbuf)); retcode = retcode >= 0 ? 0 : retcode; if (retcode) - BRCMF_TRACE(("%s: failed to enabe ARP offload to %d, " - "retcode = %d\n", __func__, arp_enable, retcode)); + brcmf_dbg(TRACE, "failed to enable ARP offload to %d, retcode = %d\n", + arp_enable, retcode); else - BRCMF_TRACE(("%s: successfully enabed ARP offload to %d\n", - __func__, arp_enable)); + brcmf_dbg(TRACE, "successfully enabled ARP offload to %d\n", + arp_enable); } int brcmf_c_preinit_ioctls(struct brcmf_pub *drvr) @@ -1099,7 +1078,6 @@ int brcmf_c_preinit_ioctls(struct brcmf_pub *drvr) "event_msgs" + '\0' + bitvec */ uint up = 0; char buf[128], *ptr; - uint power_mode = PM_FAST; u32 dongle_align = BRCMF_SDALIGN; u32 glom = 0; uint bcn_timeout = 3; @@ -1112,11 +1090,9 @@ int brcmf_c_preinit_ioctls(struct brcmf_pub *drvr) /* Set Country code */ if (drvr->country_code[0] != 0) { if (brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_COUNTRY, - drvr->country_code, - sizeof(drvr->country_code)) < 0) { - BRCMF_ERROR(("%s: country code setting failed\n", - __func__)); - } + drvr->country_code, + sizeof(drvr->country_code)) < 0) + brcmf_dbg(ERROR, "country code setting failed\n"); } /* query for 'ver' to get version info from firmware */ @@ -1126,11 +1102,7 @@ int brcmf_c_preinit_ioctls(struct brcmf_pub *drvr) brcmf_proto_cdc_query_ioctl(drvr, 0, BRCMF_C_GET_VAR, buf, sizeof(buf)); strsep(&ptr, "\n"); /* Print fw version info */ - BRCMF_ERROR(("Firmware version = %s\n", buf)); - - /* Set PowerSave mode */ - brcmf_proto_cdc_set_ioctl(drvr, 0, BRCMF_C_SET_PM, (char *)&power_mode, - sizeof(power_mode)); + brcmf_dbg(ERROR, "Firmware version = %s\n", buf); /* Match Host and Dongle rx alignment */ brcmu_mkiovar("bus:txglomalign", (char *)&dongle_align, 4, iovbuf, diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_dbg.h b/drivers/staging/brcm80211/brcmfmac/dhd_dbg.h index 5be4d7a..7467922 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_dbg.h +++ b/drivers/staging/brcm80211/brcmfmac/dhd_dbg.h @@ -19,25 +19,21 @@ #if defined(BCMDBG) -#define BRCMF_ERROR(args) \ - do {if ((brcmf_msg_level & BRCMF_ERROR_VAL) && (net_ratelimit())) \ - printk args; } while (0) -#define BRCMF_TRACE(args) do {if (brcmf_msg_level & BRCMF_TRACE_VAL) \ - printk args; } while (0) -#define BRCMF_INFO(args) do {if (brcmf_msg_level & BRCMF_INFO_VAL) \ - printk args; } while (0) -#define BRCMF_DATA(args) do {if (brcmf_msg_level & BRCMF_DATA_VAL) \ - printk args; } while (0) -#define BRCMF_CTL(args) do {if (brcmf_msg_level & BRCMF_CTL_VAL) \ - printk args; } while (0) -#define BRCMF_TIMER(args) do {if (brcmf_msg_level & BRCMF_TIMER_VAL) \ - printk args; } while (0) -#define BRCMF_INTR(args) do {if (brcmf_msg_level & BRCMF_INTR_VAL) \ - printk args; } while (0) -#define BRCMF_GLOM(args) do {if (brcmf_msg_level & BRCMF_GLOM_VAL) \ - printk args; } while (0) -#define BRCMF_EVENT(args) do {if (brcmf_msg_level & BRCMF_EVENT_VAL) \ - printk args; } while (0) +#define brcmf_dbg(level, fmt, ...) \ +do { \ + if (BRCMF_ERROR_VAL == BRCMF_##level##_VAL) { \ + if (brcmf_msg_level & BRCMF_##level##_VAL) { \ + if (net_ratelimit()) \ + printk(KERN_DEBUG "%s: " fmt, \ + __func__, ##__VA_ARGS__); \ + } \ + } else { \ + if (brcmf_msg_level & BRCMF_##level##_VAL) { \ + printk(KERN_DEBUG "%s: " fmt, \ + __func__, ##__VA_ARGS__); \ + } \ + } \ +} while (0) #define BRCMF_DATA_ON() (brcmf_msg_level & BRCMF_DATA_VAL) #define BRCMF_CTL_ON() (brcmf_msg_level & BRCMF_CTL_VAL) @@ -47,20 +43,12 @@ #else /* (defined BCMDBG) || (defined BCMDBG) */ -#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 brcmf_dbg(level, fmt, ...) no_printk(fmt, ##__VA_ARGS__) #define BRCMF_DATA_ON() 0 #define BRCMF_CTL_ON() 0 #define BRCMF_HDRS_ON() 0 -#define BRCMF_BYTES_ON() 0 +#define BRCMF_BYTES_ON() 0 #define BRCMF_GLOM_ON() 0 #endif /* defined(BCMDBG) */ diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c index 05dada9..46f75b7 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c @@ -28,8 +28,9 @@ #include <linux/fcntl.h> #include <linux/fs.h> #include <linux/uaccess.h> -#include <linux/interrupt.h> #include <linux/hardirq.h> +#include <linux/mutex.h> +#include <linux/wait.h> #include <net/cfg80211.h> #include <defs.h> #include <brcmu_utils.h> @@ -42,11 +43,6 @@ #include "wl_cfg80211.h" #include "bcmchip.h" -#if defined(CONFIG_PM_SLEEP) -#include <linux/suspend.h> -atomic_t brcmf_mmc_suspend; -#endif /* defined(CONFIG_PM_SLEEP) */ - MODULE_AUTHOR("Broadcom Corporation"); MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN fullmac driver."); MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN fullmac cards"); @@ -75,12 +71,11 @@ struct brcmf_info { /* OS/stack specifics */ struct brcmf_if *iflist[BRCMF_MAX_IFS]; - struct semaphore proto_sem; - wait_queue_head_t ioctl_resp_wait; + struct mutex proto_block; /* Thread to issue ioctl for multicast */ struct task_struct *sysioc_tsk; - struct semaphore sysioc_sem; + wait_queue_head_t sysioc_waitq; bool set_multicast; bool set_macaddress; u8 macvalue[ETH_ALEN]; @@ -115,8 +110,6 @@ module_param(brcmf_pkt_filter_init, uint, 0); uint brcmf_master_mode = true; module_param(brcmf_master_mode, uint, 0); -module_param(brcmf_dongle_memsize, int, 0); - /* Contorl fw roaming */ uint brcmf_roam = 1; @@ -127,105 +120,12 @@ uint brcmf_radio_up = 1; char iface_name[IFNAMSIZ] = "wlan"; module_param_string(iface_name, iface_name, IFNAMSIZ, 0); -/* The following are specific to the SDIO dongle */ - -/* IOCTL response timeout */ -int brcmf_ioctl_timeout_msec = IOCTL_RESP_TIMEOUT; - -/* Idle timeout for backplane clock */ -int brcmf_idletime = BRCMF_IDLETIME_TICKS; -module_param(brcmf_idletime, int, 0); - -/* Use polling */ -uint brcmf_poll; -module_param(brcmf_poll, uint, 0); - -/* Use interrupts */ -uint brcmf_intr = true; -module_param(brcmf_intr, uint, 0); - -/* SDIO Drive Strength (in milliamps) */ -uint brcmf_sdiod_drive_strength = 6; -module_param(brcmf_sdiod_drive_strength, uint, 0); - -/* Tx/Rx bounds */ -module_param(brcmf_txbound, uint, 0); -module_param(brcmf_rxbound, uint, 0); - -#ifdef SDTEST -/* Echo packet generator (pkts/s) */ -uint brcmf_pktgen; -module_param(brcmf_pktgen, uint, 0); - -/* Echo packet len (0 => sawtooth, max 2040) */ -uint brcmf_pktgen_len; -module_param(brcmf_pktgen_len, uint, 0); -#endif - static int brcmf_toe_get(struct brcmf_info *drvr_priv, int idx, u32 *toe_ol); static int brcmf_toe_set(struct brcmf_info *drvr_priv, int idx, u32 toe_ol); -static int brcmf_host_event(struct brcmf_info *drvr_priv, int *ifidx, void *pktdata, - struct brcmf_event_msg *event_ptr, +static int brcmf_host_event(struct brcmf_info *drvr_priv, int *ifidx, + void *pktdata, struct brcmf_event_msg *event_ptr, void **data_ptr); -/* - * Generalized timeout mechanism. Uses spin sleep with exponential - * back-off until - * the sleep time reaches one jiffy, then switches over to task delay. Usage: - * - * brcmf_timeout_start(&tmo, usec); - * while (!brcmf_timeout_expired(&tmo)) - * if (poll_something()) - * break; - * if (brcmf_timeout_expired(&tmo)) - * fatal(); - */ - -void brcmf_timeout_start(struct brcmf_timeout *tmo, uint usec) -{ - tmo->limit = usec; - tmo->increment = 0; - tmo->elapsed = 0; - tmo->tick = 1000000 / HZ; -} - -int brcmf_timeout_expired(struct brcmf_timeout *tmo) -{ - /* Does nothing the first call */ - if (tmo->increment == 0) { - tmo->increment = 1; - return 0; - } - - if (tmo->elapsed >= tmo->limit) - return 1; - - /* Add the delay that's about to take place */ - tmo->elapsed += tmo->increment; - - if (tmo->increment < tmo->tick) { - udelay(tmo->increment); - tmo->increment *= 2; - if (tmo->increment > tmo->tick) - tmo->increment = tmo->tick; - } else { - wait_queue_head_t delay_wait; - DECLARE_WAITQUEUE(wait, current); - int pending; - init_waitqueue_head(&delay_wait); - add_wait_queue(&delay_wait, &wait); - set_current_state(TASK_INTERRUPTIBLE); - schedule_timeout(1); - pending = signal_pending(current); - remove_wait_queue(&delay_wait, &wait); - set_current_state(TASK_RUNNING); - if (pending) - return 1; /* Interrupted */ - } - - return 0; -} - static int brcmf_net2idx(struct brcmf_info *drvr_priv, struct net_device *net) { int i = 0; @@ -251,7 +151,7 @@ int brcmf_ifname2idx(struct brcmf_info *drvr_priv, char *name) && !strncmp(drvr_priv->iflist[i]->name, name, IFNAMSIZ)) break; - BRCMF_TRACE(("%s: return idx %d for \"%s\"\n", __func__, i, name)); + brcmf_dbg(TRACE, "return idx %d for \"%s\"\n", i, name); return i; /* default - the primary interface */ } @@ -261,12 +161,12 @@ char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx) struct brcmf_info *drvr_priv = drvr->info; if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) { - BRCMF_ERROR(("%s: ifidx %d out of range\n", __func__, ifidx)); + brcmf_dbg(ERROR, "ifidx %d out of range\n", ifidx); return "<if_bad>"; } if (drvr_priv->iflist[ifidx] == NULL) { - BRCMF_ERROR(("%s: null i/f %d\n", __func__, ifidx)); + brcmf_dbg(ERROR, "null i/f %d\n", ifidx); return "<if_null>"; } @@ -298,8 +198,8 @@ static void _brcmf_set_multicast_list(struct brcmf_info *drvr_priv, int ifidx) buflen = sizeof("mcast_list") + sizeof(cnt) + (cnt * ETH_ALEN); bufp = buf = kmalloc(buflen, GFP_ATOMIC); if (!bufp) { - BRCMF_ERROR(("%s: out of memory for mcast_list, cnt %d\n", - brcmf_ifname(&drvr_priv->pub, ifidx), cnt)); + brcmf_dbg(ERROR, "%s: out of memory for mcast_list, cnt %d\n", + brcmf_ifname(&drvr_priv->pub, ifidx), cnt); return; } @@ -326,8 +226,8 @@ static void _brcmf_set_multicast_list(struct brcmf_info *drvr_priv, int ifidx) ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len); if (ret < 0) { - BRCMF_ERROR(("%s: set mcast_list failed, cnt %d\n", - brcmf_ifname(&drvr_priv->pub, ifidx), cnt)); + brcmf_dbg(ERROR, "%s: set mcast_list failed, cnt %d\n", + brcmf_ifname(&drvr_priv->pub, ifidx), cnt); allmulti = cnt ? true : allmulti; } @@ -341,18 +241,17 @@ static void _brcmf_set_multicast_list(struct brcmf_info *drvr_priv, int ifidx) buflen = sizeof("allmulti") + sizeof(allmulti); buf = kmalloc(buflen, GFP_ATOMIC); if (!buf) { - BRCMF_ERROR(("%s: out of memory for allmulti\n", - brcmf_ifname(&drvr_priv->pub, ifidx))); + brcmf_dbg(ERROR, "%s: out of memory for allmulti\n", + brcmf_ifname(&drvr_priv->pub, ifidx)); return; } allmulti = cpu_to_le32(allmulti); if (!brcmu_mkiovar ("allmulti", (void *)&allmulti, sizeof(allmulti), buf, buflen)) { - BRCMF_ERROR(("%s: mkiovar failed for allmulti, datalen %d " - "buflen %u\n", - brcmf_ifname(&drvr_priv->pub, ifidx), - (int)sizeof(allmulti), buflen)); + brcmf_dbg(ERROR, "%s: mkiovar failed for allmulti, datalen %d buflen %u\n", + brcmf_ifname(&drvr_priv->pub, ifidx), + (int)sizeof(allmulti), buflen); kfree(buf); return; } @@ -365,9 +264,9 @@ static void _brcmf_set_multicast_list(struct brcmf_info *drvr_priv, int ifidx) ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len); if (ret < 0) { - BRCMF_ERROR(("%s: set allmulti %d failed\n", - brcmf_ifname(&drvr_priv->pub, ifidx), - le32_to_cpu(allmulti))); + brcmf_dbg(ERROR, "%s: set allmulti %d failed\n", + brcmf_ifname(&drvr_priv->pub, ifidx), + le32_to_cpu(allmulti)); } kfree(buf); @@ -386,23 +285,23 @@ static void _brcmf_set_multicast_list(struct brcmf_info *drvr_priv, int ifidx) ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len); if (ret < 0) { - BRCMF_ERROR(("%s: set promisc %d failed\n", - brcmf_ifname(&drvr_priv->pub, ifidx), - le32_to_cpu(allmulti))); + brcmf_dbg(ERROR, "%s: set promisc %d failed\n", + brcmf_ifname(&drvr_priv->pub, ifidx), + le32_to_cpu(allmulti)); } } -static int _brcmf_set_mac_address(struct brcmf_info *drvr_priv, int ifidx, u8 *addr) +static int +_brcmf_set_mac_address(struct brcmf_info *drvr_priv, int ifidx, u8 *addr) { char buf[32]; struct brcmf_ioctl ioc; int ret; - BRCMF_TRACE(("%s enter\n", __func__)); - if (!brcmu_mkiovar - ("cur_etheraddr", (char *)addr, ETH_ALEN, buf, 32)) { - BRCMF_ERROR(("%s: mkiovar failed for cur_etheraddr\n", - brcmf_ifname(&drvr_priv->pub, ifidx))); + brcmf_dbg(TRACE, "enter\n"); + if (!brcmu_mkiovar("cur_etheraddr", (char *)addr, ETH_ALEN, buf, 32)) { + brcmf_dbg(ERROR, "%s: mkiovar failed for cur_etheraddr\n", + brcmf_ifname(&drvr_priv->pub, ifidx)); return -1; } memset(&ioc, 0, sizeof(ioc)); @@ -412,18 +311,17 @@ static int _brcmf_set_mac_address(struct brcmf_info *drvr_priv, int ifidx, u8 *a ioc.set = true; ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len); - if (ret < 0) { - BRCMF_ERROR(("%s: set cur_etheraddr failed\n", - brcmf_ifname(&drvr_priv->pub, ifidx))); - } else { + if (ret < 0) + brcmf_dbg(ERROR, "%s: set cur_etheraddr failed\n", + brcmf_ifname(&drvr_priv->pub, ifidx)); + else memcpy(drvr_priv->iflist[ifidx]->net->dev_addr, addr, ETH_ALEN); - } return ret; } #ifdef SOFTAP -extern struct net_device *ap_net_dev; +static struct net_device *ap_net_dev; #endif /* Virtual interfaces only ((ifp && ifp->info && ifp->idx == true) */ @@ -434,7 +332,7 @@ static void brcmf_op_if(struct brcmf_if *ifp) drvr_priv = ifp->info; - BRCMF_TRACE(("%s: idx %d, state %d\n", __func__, ifp->idx, ifp->state)); + brcmf_dbg(TRACE, "idx %d, state %d\n", ifp->idx, ifp->state); switch (ifp->state) { case BRCMF_E_IF_ADD: @@ -443,9 +341,8 @@ static void brcmf_op_if(struct brcmf_if *ifp) * in case we missed the BRCMF_E_IF_DEL event. */ if (ifp->net != NULL) { - BRCMF_ERROR(("%s: ERROR: netdev:%s already exists, " - "try free & unregister\n", - __func__, ifp->net->name)); + brcmf_dbg(ERROR, "ERROR: netdev:%s already exists, try free & unregister\n", + ifp->net->name); netif_stop_queue(ifp->net); unregister_netdev(ifp->net); free_netdev(ifp->net); @@ -453,23 +350,23 @@ static void brcmf_op_if(struct brcmf_if *ifp) /* Allocate etherdev, including space for private structure */ ifp->net = alloc_etherdev(sizeof(drvr_priv)); if (!ifp->net) { - BRCMF_ERROR(("%s: OOM - alloc_etherdev\n", __func__)); + brcmf_dbg(ERROR, "OOM - alloc_etherdev\n"); ret = -ENOMEM; } if (ret == 0) { strcpy(ifp->net->name, ifp->name); - memcpy(netdev_priv(ifp->net), &drvr_priv, sizeof(drvr_priv)); + memcpy(netdev_priv(ifp->net), &drvr_priv, + sizeof(drvr_priv)); err = brcmf_net_attach(&drvr_priv->pub, ifp->idx); if (err != 0) { - BRCMF_ERROR(("%s: brcmf_net_attach failed, " - "err %d\n", - __func__, err)); + brcmf_dbg(ERROR, "brcmf_net_attach failed, err %d\n", + err); ret = -EOPNOTSUPP; } else { #ifdef SOFTAP /* semaphore that the soft AP CODE waits on */ - extern struct semaphore ap_eth_sema; + struct semaphore ap_eth_sema; /* save ptr to wl0.1 netdev for use in wl_iw.c */ @@ -478,17 +375,15 @@ static void brcmf_op_if(struct brcmf_if *ifp) wl0.1 is ready */ up(&ap_eth_sema); #endif - BRCMF_TRACE(("\n ==== pid:%x, net_device for " - "if:%s created ===\n\n", - current->pid, ifp->net->name)); + brcmf_dbg(TRACE, " ==== pid:%x, net_device for if:%s created ===\n", + current->pid, ifp->net->name); ifp->state = 0; } } break; case BRCMF_E_IF_DEL: if (ifp->net != NULL) { - BRCMF_TRACE(("\n%s: got 'WLC_E_IF_DEL' state\n", - __func__)); + brcmf_dbg(TRACE, "got 'WLC_E_IF_DEL' state\n"); netif_stop_queue(ifp->net); unregister_netdev(ifp->net); ret = BRCMF_DEL_IF; /* Make sure the free_netdev() @@ -496,7 +391,7 @@ static void brcmf_op_if(struct brcmf_if *ifp) } break; default: - BRCMF_ERROR(("%s: bad op %d\n", __func__, ifp->state)); + brcmf_dbg(ERROR, "bad op %d\n", ifp->state); break; } @@ -521,12 +416,20 @@ static int _brcmf_sysioc_thread(void *data) #ifdef SOFTAP bool in_ap = false; #endif - + DECLARE_WAITQUEUE(wait, current); allow_signal(SIGTERM); - while (down_interruptible(&drvr_priv->sysioc_sem) == 0) { + add_wait_queue(&drvr_priv->sysioc_waitq, &wait); + while (1) { + prepare_to_wait(&drvr_priv->sysioc_waitq, &wait, + TASK_INTERRUPTIBLE); + + /* wait for event */ + schedule(); + if (kthread_should_stop()) break; + for (i = 0; i < BRCMF_MAX_IFS; i++) { struct brcmf_if *ifentry = drvr_priv->iflist[i]; if (ifentry) { @@ -537,26 +440,21 @@ static int _brcmf_sysioc_thread(void *data) brcmf_op_if(ifentry); #ifdef SOFTAP if (drvr_priv->iflist[i] == NULL) { - BRCMF_TRACE(("\n\n %s: interface %d " - "removed!\n", __func__, - i)); + brcmf_dbg(TRACE, "interface %d removed!\n", + i); continue; } if (in_ap && drvr_priv->set_macaddress) { - BRCMF_TRACE(("attempt to set MAC for" - " %s in AP Mode," - " blocked.\n", - ifentry->net->name)); + brcmf_dbg(TRACE, "attempt to set MAC for %s in AP Mode, blocked.\n", + ifentry->net->name); drvr_priv->set_macaddress = false; continue; } if (in_ap && drvr_priv->set_multicast) { - BRCMF_TRACE(("attempt to set MULTICAST " - "list for %s in AP Mode, " - "blocked.\n", - ifentry->net->name)); + brcmf_dbg(TRACE, "attempt to set MULTICAST list for %s in AP Mode, blocked.\n", + ifentry->net->name); drvr_priv->set_multicast = false; continue; } @@ -573,6 +471,7 @@ static int _brcmf_sysioc_thread(void *data) } } } + finish_wait(&drvr_priv->sysioc_waitq, &wait); return 0; } @@ -590,8 +489,7 @@ static int brcmf_netdev_set_mac_address(struct net_device *dev, void *addr) memcpy(&drvr_priv->macvalue, sa->sa_data, ETH_ALEN); drvr_priv->set_macaddress = true; - up(&drvr_priv->sysioc_sem); - + wake_up(&drvr_priv->sysioc_waitq); return ret; } @@ -605,7 +503,7 @@ static void brcmf_netdev_set_multicast_list(struct net_device *dev) return; drvr_priv->set_multicast = true; - up(&drvr_priv->sysioc_sem); + wake_up(&drvr_priv->sysioc_waitq); } int brcmf_sendpkt(struct brcmf_pub *drvr, int ifidx, struct sk_buff *pktbuf) @@ -640,20 +538,19 @@ static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *net) struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(net); int ifidx; - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); /* Reject if down */ if (!drvr_priv->pub.up || (drvr_priv->pub.busstate == BRCMF_BUS_DOWN)) { - BRCMF_ERROR(("%s: xmit rejected pub.up=%d busstate=%d\n", - __func__, drvr_priv->pub.up, - drvr_priv->pub.busstate)); + brcmf_dbg(ERROR, "xmit rejected pub.up=%d busstate=%d\n", + drvr_priv->pub.up, drvr_priv->pub.busstate); netif_stop_queue(net); return -ENODEV; } ifidx = brcmf_net2idx(drvr_priv, net); if (ifidx == BRCMF_BAD_IF) { - BRCMF_ERROR(("%s: bad ifidx %d\n", __func__, ifidx)); + brcmf_dbg(ERROR, "bad ifidx %d\n", ifidx); netif_stop_queue(net); return -ENODEV; } @@ -662,15 +559,15 @@ static int brcmf_netdev_start_xmit(struct sk_buff *skb, struct net_device *net) if (skb_headroom(skb) < drvr_priv->pub.hdrlen) { struct sk_buff *skb2; - BRCMF_INFO(("%s: insufficient headroom\n", - brcmf_ifname(&drvr_priv->pub, ifidx))); + brcmf_dbg(INFO, "%s: insufficient headroom\n", + brcmf_ifname(&drvr_priv->pub, ifidx)); drvr_priv->pub.tx_realloc++; skb2 = skb_realloc_headroom(skb, drvr_priv->pub.hdrlen); dev_kfree_skb(skb); skb = skb2; if (skb == NULL) { - BRCMF_ERROR(("%s: skb_realloc_headroom failed\n", - brcmf_ifname(&drvr_priv->pub, ifidx))); + brcmf_dbg(ERROR, "%s: skb_realloc_headroom failed\n", + brcmf_ifname(&drvr_priv->pub, ifidx)); ret = -ENOMEM; goto done; } @@ -693,7 +590,7 @@ void brcmf_txflowcontrol(struct brcmf_pub *drvr, int ifidx, bool state) struct net_device *net; struct brcmf_info *drvr_priv = drvr->info; - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); drvr->txoff = state; net = drvr_priv->iflist[ifidx]->net; @@ -715,7 +612,7 @@ void brcmf_rx_frame(struct brcmf_pub *drvr, int ifidx, struct sk_buff *skb, struct brcmf_if *ifp; struct brcmf_event_msg event; - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); save_pktbuf = skb; @@ -771,9 +668,9 @@ void brcmf_rx_frame(struct brcmf_pub *drvr, int ifidx, struct sk_buff *skb, drvr->dstats.rx_bytes += skb->len; drvr->rx_packets++; /* Local count */ - if (in_interrupt()) { + if (in_interrupt()) netif_rx(skb); - } else { + else /* If the receive is not processed inside an ISR, * the softirqd must be woken explicitly to service * the NET_RX_SOFTIRQ. In 2.6 kernels, this is handled @@ -781,7 +678,6 @@ void brcmf_rx_frame(struct brcmf_pub *drvr, int ifidx, struct sk_buff *skb, * to do it manually. */ netif_rx_ni(skb); - } } } @@ -808,7 +704,7 @@ static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *net) struct brcmf_if *ifp; int ifidx; - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); ifidx = brcmf_net2idx(drvr_priv, net); if (ifidx == BRCMF_BAD_IF) @@ -816,10 +712,9 @@ static struct net_device_stats *brcmf_netdev_get_stats(struct net_device *net) ifp = drvr_priv->iflist[ifidx]; - if (drvr_priv->pub.up) { + if (drvr_priv->pub.up) /* Use the protocol to get dongle stats */ brcmf_proto_dstats(&drvr_priv->pub); - } /* Copy dongle stats to net device stats */ ifp->stats.rx_packets = drvr_priv->pub.dstats.rx_packets; @@ -855,13 +750,13 @@ static int brcmf_toe_get(struct brcmf_info *drvr_priv, int ifidx, u32 *toe_ol) if (ret < 0) { /* Check for older dongle image that doesn't support toe_ol */ if (ret == -EIO) { - BRCMF_ERROR(("%s: toe not supported by device\n", - brcmf_ifname(&drvr_priv->pub, ifidx))); + brcmf_dbg(ERROR, "%s: toe not supported by device\n", + brcmf_ifname(&drvr_priv->pub, ifidx)); return -EOPNOTSUPP; } - BRCMF_INFO(("%s: could not get toe_ol: ret=%d\n", - brcmf_ifname(&drvr_priv->pub, ifidx), ret)); + brcmf_dbg(INFO, "%s: could not get toe_ol: ret=%d\n", + brcmf_ifname(&drvr_priv->pub, ifidx), ret); return ret; } @@ -891,8 +786,8 @@ static int brcmf_toe_set(struct brcmf_info *drvr_priv, int ifidx, u32 toe_ol) ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len); if (ret < 0) { - BRCMF_ERROR(("%s: could not set toe_ol: ret=%d\n", - brcmf_ifname(&drvr_priv->pub, ifidx), ret)); + brcmf_dbg(ERROR, "%s: could not set toe_ol: ret=%d\n", + brcmf_ifname(&drvr_priv->pub, ifidx), ret); return ret; } @@ -905,8 +800,8 @@ static int brcmf_toe_set(struct brcmf_info *drvr_priv, int ifidx, u32 toe_ol) ret = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, &ioc, ioc.buf, ioc.len); if (ret < 0) { - BRCMF_ERROR(("%s: could not set toe: ret=%d\n", - brcmf_ifname(&drvr_priv->pub, ifidx), ret)); + brcmf_dbg(ERROR, "%s: could not set toe: ret=%d\n", + brcmf_ifname(&drvr_priv->pub, ifidx), ret); return ret; } @@ -938,7 +833,7 @@ static int brcmf_ethtool(struct brcmf_info *drvr_priv, void *uaddr) u32 toe_cmpnt, csum_dir; int ret; - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); /* all ethtool calls start with a cmd word */ if (copy_from_user(&cmd, uaddr, sizeof(u32))) @@ -964,7 +859,7 @@ static int brcmf_ethtool(struct brcmf_info *drvr_priv, void *uaddr) /* otherwise, require dongle to be up */ else if (!drvr_priv->pub.up) { - BRCMF_ERROR(("%s: dongle is not up\n", __func__)); + brcmf_dbg(ERROR, "dongle is not up\n"); return -ENODEV; } @@ -977,8 +872,8 @@ static int brcmf_ethtool(struct brcmf_info *drvr_priv, void *uaddr) sprintf(info.version, "%lu", drvr_priv->pub.drv_version); if (copy_to_user(uaddr, &info, sizeof(info))) return -EFAULT; - BRCMF_CTL(("%s: given %*s, returning %s\n", __func__, - (int)sizeof(drvname), drvname, info.driver)); + brcmf_dbg(CTL, "given %*s, returning %s\n", + (int)sizeof(drvname), drvname, info.driver); break; /* Get toe offload components from dongle */ @@ -1053,13 +948,13 @@ static int brcmf_netdev_ioctl_entry(struct net_device *net, struct ifreq *ifr, bool is_set_key_cmd; ifidx = brcmf_net2idx(drvr_priv, net); - BRCMF_TRACE(("%s: ifidx %d, cmd 0x%04x\n", __func__, ifidx, cmd)); + brcmf_dbg(TRACE, "ifidx %d, cmd 0x%04x\n", ifidx, cmd); if (ifidx == BRCMF_BAD_IF) return -1; if (cmd == SIOCETHTOOL) - return brcmf_ethtool(drvr_priv, (void *)ifr->ifr_data); + return brcmf_ethtool(drvr_priv, ifr->ifr_data); if (cmd != SIOCDEVPRIVATE) return -EOPNOTSUPP; @@ -1108,7 +1003,8 @@ static int brcmf_netdev_ioctl_entry(struct net_device *net, struct ifreq *ifr, /* check for local brcmf ioctl and handle it */ if (driver == BRCMF_IOCTL_MAGIC) { - bcmerror = brcmf_c_ioctl((void *)&drvr_priv->pub, &ioc, buf, buflen); + bcmerror = brcmf_c_ioctl((void *)&drvr_priv->pub, &ioc, + buf, buflen); if (bcmerror) drvr_priv->pub.bcmerror = bcmerror; goto done; @@ -1116,7 +1012,7 @@ static int brcmf_netdev_ioctl_entry(struct net_device *net, struct ifreq *ifr, /* send to dongle (must be up, and wl) */ if ((drvr_priv->pub.busstate != BRCMF_BUS_DATA)) { - BRCMF_ERROR(("%s DONGLE_DOWN,__func__\n", __func__)); + brcmf_dbg(ERROR, "DONGLE_DOWN\n"); bcmerror = -EIO; goto done; } @@ -1138,9 +1034,8 @@ static int brcmf_netdev_ioctl_entry(struct net_device *net, struct ifreq *ifr, if (is_set_key_cmd) brcmf_netdev_wait_pend8021x(net); - bcmerror = - brcmf_proto_ioctl(&drvr_priv->pub, ifidx, (struct brcmf_ioctl *)&ioc, - buf, buflen); + bcmerror = brcmf_proto_ioctl(&drvr_priv->pub, ifidx, + (struct brcmf_ioctl *)&ioc, buf, buflen); done: if (!bcmerror && buf && ioc.buf) { @@ -1158,10 +1053,9 @@ done: static int brcmf_netdev_stop(struct net_device *net) { -#if !defined(IGNORE_ETH0_DOWN) struct brcmf_info *drvr_priv = *(struct brcmf_info **) netdev_priv(net); - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); brcmf_cfg80211_down(); if (drvr_priv->pub.up == 0) return 0; @@ -1169,10 +1063,6 @@ static int brcmf_netdev_stop(struct net_device *net) /* Set state and stop OS transmissions */ drvr_priv->pub.up = 0; netif_stop_queue(net); -#else - BRCMF_ERROR(("BYPASS %s:due to BRCM compilation: under investigation\n", - __func__)); -#endif /* !defined(IGNORE_ETH0_DOWN) */ return 0; } @@ -1184,15 +1074,14 @@ static int brcmf_netdev_open(struct net_device *net) int ifidx = brcmf_net2idx(drvr_priv, net); s32 ret = 0; - BRCMF_TRACE(("%s: ifidx %d\n", __func__, ifidx)); + brcmf_dbg(TRACE, "ifidx %d\n", ifidx); if (ifidx == 0) { /* do it only for primary eth0 */ /* try to bring up bus */ ret = brcmf_bus_start(&drvr_priv->pub); if (ret != 0) { - BRCMF_ERROR(("%s: failed with code %d\n", - __func__, ret)); + brcmf_dbg(ERROR, "failed with code %d\n", ret); return -1; } atomic_set(&drvr_priv->pend_8021x_cnt, 0); @@ -1212,8 +1101,7 @@ static int brcmf_netdev_open(struct net_device *net) netif_start_queue(net); drvr_priv->pub.up = 1; if (unlikely(brcmf_cfg80211_up())) { - BRCMF_ERROR(("%s: failed to bring up cfg80211\n", - __func__)); + brcmf_dbg(ERROR, "failed to bring up cfg80211\n"); return -1; } @@ -1221,18 +1109,18 @@ static int brcmf_netdev_open(struct net_device *net) } int -brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx, void *handle, char *name, - u8 *mac_addr, u32 flags, u8 bssidx) +brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx, struct net_device *net, + char *name, u8 *mac_addr, u32 flags, u8 bssidx) { struct brcmf_if *ifp; - BRCMF_TRACE(("%s: idx %d, handle->%p\n", __func__, ifidx, handle)); + brcmf_dbg(TRACE, "idx %d, handle->%p\n", ifidx, net); ifp = drvr_priv->iflist[ifidx]; if (!ifp) { ifp = kmalloc(sizeof(struct brcmf_if), GFP_ATOMIC); if (!ifp) { - BRCMF_ERROR(("%s: OOM - struct brcmf_if\n", __func__)); + brcmf_dbg(ERROR, "OOM - struct brcmf_if\n"); return -ENOMEM; } } @@ -1244,12 +1132,12 @@ brcmf_add_if(struct brcmf_info *drvr_priv, int ifidx, void *handle, char *name, if (mac_addr != NULL) memcpy(&ifp->mac_addr, mac_addr, ETH_ALEN); - if (handle == NULL) { + if (net == NULL) { ifp->state = BRCMF_E_IF_ADD; ifp->idx = ifidx; - up(&drvr_priv->sysioc_sem); + wake_up(&drvr_priv->sysioc_waitq); } else - ifp->net = (struct net_device *)handle; + ifp->net = net; return 0; } @@ -1258,17 +1146,17 @@ void brcmf_del_if(struct brcmf_info *drvr_priv, int ifidx) { struct brcmf_if *ifp; - BRCMF_TRACE(("%s: idx %d\n", __func__, ifidx)); + brcmf_dbg(TRACE, "idx %d\n", ifidx); ifp = drvr_priv->iflist[ifidx]; if (!ifp) { - BRCMF_ERROR(("%s: Null interface\n", __func__)); + brcmf_dbg(ERROR, "Null interface\n"); return; } ifp->state = BRCMF_E_IF_DEL; ifp->idx = ifidx; - up(&drvr_priv->sysioc_sem); + wake_up(&drvr_priv->sysioc_waitq); } struct brcmf_pub *brcmf_attach(struct brcmf_bus *bus, uint bus_hdrlen) @@ -1276,19 +1164,19 @@ struct brcmf_pub *brcmf_attach(struct brcmf_bus *bus, uint bus_hdrlen) struct brcmf_info *drvr_priv = NULL; struct net_device *net; - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); /* Allocate etherdev, including space for private structure */ net = alloc_etherdev(sizeof(drvr_priv)); if (!net) { - BRCMF_ERROR(("%s: OOM - alloc_etherdev\n", __func__)); + brcmf_dbg(ERROR, "OOM - alloc_etherdev\n"); goto fail; } /* Allocate primary brcmf_info */ drvr_priv = kzalloc(sizeof(struct brcmf_info), GFP_ATOMIC); if (!drvr_priv) { - BRCMF_ERROR(("%s: OOM - alloc brcmf_info\n", __func__)); + brcmf_dbg(ERROR, "OOM - alloc brcmf_info\n"); goto fail; } @@ -1309,14 +1197,12 @@ struct brcmf_pub *brcmf_attach(struct brcmf_bus *bus, uint bus_hdrlen) strcat(net->name, "%d"); } - if (brcmf_add_if(drvr_priv, 0, (void *)net, net->name, NULL, 0, 0) == + if (brcmf_add_if(drvr_priv, 0, net, net->name, NULL, 0, 0) == BRCMF_BAD_IF) goto fail; net->netdev_ops = NULL; - sema_init(&drvr_priv->proto_sem, 1); - /* Initialize other structure content */ - init_waitqueue_head(&drvr_priv->ioctl_resp_wait); + mutex_init(&drvr_priv->proto_block); /* Link to info module */ drvr_priv->pub.info = drvr_priv; @@ -1327,20 +1213,20 @@ struct brcmf_pub *brcmf_attach(struct brcmf_bus *bus, uint bus_hdrlen) /* Attach and link in the protocol */ if (brcmf_proto_attach(&drvr_priv->pub) != 0) { - BRCMF_ERROR(("brcmf_prot_attach failed\n")); + brcmf_dbg(ERROR, "brcmf_prot_attach failed\n"); goto fail; } /* Attach and link in the cfg80211 */ if (unlikely(brcmf_cfg80211_attach(net, &drvr_priv->pub))) { - BRCMF_ERROR(("wl_cfg80211_attach failed\n")); + brcmf_dbg(ERROR, "wl_cfg80211_attach failed\n"); goto fail; } if (brcmf_sysioc) { - sema_init(&drvr_priv->sysioc_sem, 0); - drvr_priv->sysioc_tsk = kthread_run(_brcmf_sysioc_thread, drvr_priv, - "_brcmf_sysioc"); + init_waitqueue_head(&drvr_priv->sysioc_waitq); + drvr_priv->sysioc_tsk = kthread_run(_brcmf_sysioc_thread, + drvr_priv, "_brcmf_sysioc"); if (IS_ERR(drvr_priv->sysioc_tsk)) { printk(KERN_WARNING "_brcmf_sysioc thread failed to start\n"); @@ -1354,9 +1240,6 @@ struct brcmf_pub *brcmf_attach(struct brcmf_bus *bus, uint bus_hdrlen) */ memcpy(netdev_priv(net), &drvr_priv, sizeof(drvr_priv)); -#if defined(CONFIG_PM_SLEEP) - atomic_set(&brcmf_mmc_suspend, false); -#endif /* defined(CONFIG_PM_SLEEP) */ return &drvr_priv->pub; fail: @@ -1375,19 +1258,18 @@ int brcmf_bus_start(struct brcmf_pub *drvr) /* Room for "event_msgs" + '\0' + bitvec */ char iovbuf[BRCMF_EVENTING_MASK_LEN + 12]; - BRCMF_TRACE(("%s:\n", __func__)); + brcmf_dbg(TRACE, "\n"); /* Bring up the bus */ ret = brcmf_sdbrcm_bus_init(&drvr_priv->pub, true); if (ret != 0) { - BRCMF_ERROR(("%s, brcmf_sdbrcm_bus_init failed %d\n", __func__, - ret)); + brcmf_dbg(ERROR, "brcmf_sdbrcm_bus_init failed %d\n", ret); return ret; } /* If bus is not ready, can't come up */ if (drvr_priv->pub.busstate != BRCMF_BUS_DATA) { - BRCMF_ERROR(("%s failed bus is not ready\n", __func__)); + brcmf_dbg(ERROR, "failed bus is not ready\n"); return -ENODEV; } @@ -1447,7 +1329,7 @@ int brcmf_net_attach(struct brcmf_pub *drvr, int ifidx) u8 temp_addr[ETH_ALEN] = { 0x00, 0x90, 0x4c, 0x11, 0x22, 0x33}; - BRCMF_TRACE(("%s: ifidx %d\n", __func__, ifidx)); + brcmf_dbg(TRACE, "ifidx %d\n", ifidx); net = drvr_priv->iflist[ifidx]->net; net->netdev_ops = &brcmf_netdev_ops_pri; @@ -1462,7 +1344,7 @@ int brcmf_net_attach(struct brcmf_pub *drvr, int ifidx) } if (ifidx == 1) { - BRCMF_TRACE(("%s ACCESS POINT MAC:\n", __func__)); + brcmf_dbg(TRACE, "ACCESS POINT MAC:\n"); /* ACCESSPOINT INTERFACE CASE */ temp_addr[0] |= 0X02; /* set bit 2 , - Locally Administered address */ @@ -1477,12 +1359,11 @@ int brcmf_net_attach(struct brcmf_pub *drvr, int ifidx) memcpy(net->dev_addr, temp_addr, ETH_ALEN); if (register_netdev(net) != 0) { - BRCMF_ERROR(("%s: couldn't register the net device\n", - __func__)); + brcmf_dbg(ERROR, "couldn't register the net device\n"); goto fail; } - BRCMF_INFO(("%s: Broadcom Dongle Host Driver\n", net->name)); + brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", net->name); return 0; @@ -1495,7 +1376,7 @@ static void brcmf_bus_detach(struct brcmf_pub *drvr) { struct brcmf_info *drvr_priv; - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); if (drvr) { drvr_priv = drvr->info; @@ -1513,7 +1394,7 @@ void brcmf_detach(struct brcmf_pub *drvr) { struct brcmf_info *drvr_priv; - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); if (drvr) { drvr_priv = drvr->info; @@ -1553,7 +1434,7 @@ void brcmf_detach(struct brcmf_pub *drvr) static void __exit brcmf_module_cleanup(void) { - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); brcmf_bus_unregister(); } @@ -1562,12 +1443,12 @@ static int __init brcmf_module_init(void) { int error; - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); error = brcmf_bus_register(); if (error) { - BRCMF_ERROR(("%s: brcmf_bus_register failed\n", __func__)); + brcmf_dbg(ERROR, "brcmf_bus_register failed\n"); goto failed; } return 0; @@ -1584,7 +1465,7 @@ int brcmf_os_proto_block(struct brcmf_pub *drvr) struct brcmf_info *drvr_priv = drvr->info; if (drvr_priv) { - down(&drvr_priv->proto_sem); + mutex_lock(&drvr_priv->proto_block); return 1; } return 0; @@ -1595,61 +1476,16 @@ int brcmf_os_proto_unblock(struct brcmf_pub *drvr) struct brcmf_info *drvr_priv = drvr->info; if (drvr_priv) { - up(&drvr_priv->proto_sem); + mutex_unlock(&drvr_priv->proto_block); return 1; } return 0; } -unsigned int brcmf_os_get_ioctl_resp_timeout(void) -{ - return (unsigned int)brcmf_ioctl_timeout_msec; -} - -void brcmf_os_set_ioctl_resp_timeout(unsigned int timeout_msec) -{ - brcmf_ioctl_timeout_msec = (int)timeout_msec; -} - -int brcmf_os_ioctl_resp_wait(struct brcmf_pub *drvr, uint *condition, - bool *pending) -{ - struct brcmf_info *drvr_priv = drvr->info; - DECLARE_WAITQUEUE(wait, current); - int timeout = brcmf_ioctl_timeout_msec; - - /* Convert timeout in millsecond to jiffies */ - timeout = timeout * HZ / 1000; - - /* Wait until control frame is available */ - add_wait_queue(&drvr_priv->ioctl_resp_wait, &wait); - set_current_state(TASK_INTERRUPTIBLE); - - while (!(*condition) && (!signal_pending(current) && timeout)) - timeout = schedule_timeout(timeout); - - if (signal_pending(current)) - *pending = true; - - set_current_state(TASK_RUNNING); - remove_wait_queue(&drvr_priv->ioctl_resp_wait, &wait); - - return timeout; -} - -int brcmf_os_ioctl_resp_wake(struct brcmf_pub *drvr) -{ - struct brcmf_info *drvr_priv = drvr->info; - - if (waitqueue_active(&drvr_priv->ioctl_resp_wait)) - wake_up_interruptible(&drvr_priv->ioctl_resp_wait); - - return 0; -} - -static int brcmf_host_event(struct brcmf_info *drvr_priv, int *ifidx, void *pktdata, - struct brcmf_event_msg *event, void **data) +static int brcmf_host_event(struct brcmf_info *drvr_priv, int *ifidx, + void *pktdata, struct brcmf_event_msg *event, + void **data) { int bcmerror = 0; @@ -1714,7 +1550,7 @@ int brcmf_write_to_file(struct brcmf_pub *drvr, u8 *buf, int size) /* open file to write */ fp = filp_open("/tmp/mem_dump", O_WRONLY | O_CREAT, 0640); if (!fp) { - BRCMF_ERROR(("%s: open file error\n", __func__)); + brcmf_dbg(ERROR, "open file error\n"); ret = -1; goto exit; } diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_proto.h b/drivers/staging/brcm80211/brcmfmac/dhd_proto.h index ff788b3..2ce5fea 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_proto.h +++ b/drivers/staging/brcm80211/brcmfmac/dhd_proto.h @@ -17,13 +17,8 @@ #ifndef _BRCMF_PROTO_H_ #define _BRCMF_PROTO_H_ -#ifndef IOCTL_RESP_TIMEOUT #define IOCTL_RESP_TIMEOUT 2000 /* In milli second */ -#endif - -#ifndef IOCTL_CHIP_ACTIVE_TIMEOUT #define IOCTL_CHIP_ACTIVE_TIMEOUT 10 /* In milli second */ -#endif /* * Exported from the brcmf protocol module (brcmf_cdc) diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c index 7fa95b6..c1647eb 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c @@ -24,6 +24,7 @@ #include <linux/sched.h> #include <linux/mmc/sdio.h> #include <linux/mmc/sdio_func.h> +#include <linux/mmc/card.h> #include <linux/semaphore.h> #include <linux/firmware.h> #include <asm/unaligned.h> @@ -34,56 +35,9 @@ #include <soc.h> #include "sdio_host.h" -/* register access macros */ -#ifndef __BIG_ENDIAN -#ifndef __mips__ -#define R_REG(r, typ) \ - brcmf_sdcard_reg_read(NULL, (r), sizeof(typ)) -#else /* __mips__ */ -#define R_REG(r, typ) \ - ({ \ - __typeof(*(r)) __osl_v; \ - __asm__ __volatile__("sync"); \ - __osl_v = brcmf_sdcard_reg_read(NULL, (r),\ - sizeof(typ)); \ - __asm__ __volatile__("sync"); \ - __osl_v; \ - }) -#endif /* __mips__ */ - -#else /* __BIG_ENDIAN */ -#define R_REG(r, typ) \ - brcmf_sdcard_reg_read(NULL, (r), sizeof(typ)) -#endif /* __BIG_ENDIAN */ - -#define OR_REG(r, v, typ) \ - brcmf_sdcard_reg_write(NULL, (r), sizeof(typ), R_REG(r, typ) | (v)) - #ifdef BCMDBG /* ARM trap handling */ - -/* Trap types defined by ARM (see arminc.h) */ - -#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 - struct brcmf_trap { u32 type; u32 epc; @@ -126,8 +80,8 @@ struct rte_console { * (at risk of conflicting with * the real UART). vcons_out is currently unused. */ - volatile uint vcons_in; - volatile uint vcons_out; + uint vcons_in; + uint vcons_out; /* Output (logging) buffer * Console output is written to a ring buffer log_buf at index log_idx. @@ -176,57 +130,67 @@ struct rte_console { #define MAX_DATA_BUF (32 * 1024) /* Must be large enough to hold biggest possible glom */ -#ifndef BRCMF_FIRSTREAD -#define BRCMF_FIRSTREAD 32 -#endif +#define BRCMF_FIRSTREAD (1 << 6) -#if !ISPOWEROF2(BRCMF_FIRSTREAD) -#error BRCMF_FIRSTREAD is not a power of 2! -#endif /* SBSDIO_DEVICE_CTL */ -#define SBSDIO_DEVCTL_SETBUSY 0x01 /* 1: device will assert busy signal when - * receiving CMD53 - */ -#define SBSDIO_DEVCTL_SPI_INTR_SYNC 0x02 /* 1: assertion of sdio interrupt is - * synchronous to the sdio clock - */ -#define SBSDIO_DEVCTL_CA_INT_ONLY 0x04 /* 1: mask all interrupts to host - * except the chipActive (rev 8) - */ -#define SBSDIO_DEVCTL_PADS_ISO 0x08 /* 1: isolate internal sdio signals, put - * external pads in tri-state; requires - * sdio bus power cycle to clear (rev 9) - */ -#define SBSDIO_DEVCTL_SB_RST_CTL 0x30 /* Force SD->SB reset mapping (rev 11) */ -#define SBSDIO_DEVCTL_RST_CORECTL 0x00 /* Determined by CoreControl bit */ -#define SBSDIO_DEVCTL_RST_BPRESET 0x10 /* Force backplane reset */ -#define SBSDIO_DEVCTL_RST_NOBPRESET 0x20 /* Force no backplane reset */ + +/* 1: device will assert busy signal when receiving CMD53 */ +#define SBSDIO_DEVCTL_SETBUSY 0x01 +/* 1: assertion of sdio interrupt is synchronous to the sdio clock */ +#define SBSDIO_DEVCTL_SPI_INTR_SYNC 0x02 +/* 1: mask all interrupts to host except the chipActive (rev 8) */ +#define SBSDIO_DEVCTL_CA_INT_ONLY 0x04 +/* 1: isolate internal sdio signals, put external pads in tri-state; requires + * sdio bus power cycle to clear (rev 9) */ +#define SBSDIO_DEVCTL_PADS_ISO 0x08 +/* Force SD->SB reset mapping (rev 11) */ +#define SBSDIO_DEVCTL_SB_RST_CTL 0x30 +/* Determined by CoreControl bit */ +#define SBSDIO_DEVCTL_RST_CORECTL 0x00 +/* Force backplane reset */ +#define SBSDIO_DEVCTL_RST_BPRESET 0x10 +/* Force no backplane reset */ +#define SBSDIO_DEVCTL_RST_NOBPRESET 0x20 /* SBSDIO_FUNC1_CHIPCLKCSR */ -#define SBSDIO_FORCE_ALP 0x01 /* Force ALP request to backplane */ -#define SBSDIO_FORCE_HT 0x02 /* Force HT request to backplane */ -#define SBSDIO_FORCE_ILP 0x04 /* Force ILP request to backplane */ -#define SBSDIO_ALP_AVAIL_REQ 0x08 /* Make ALP ready (power up xtal) */ -#define SBSDIO_HT_AVAIL_REQ 0x10 /* Make HT ready (power up PLL) */ -#define SBSDIO_FORCE_HW_CLKREQ_OFF 0x20 /* Squelch clock requests from HW */ -#define SBSDIO_ALP_AVAIL 0x40 /* Status: ALP is ready */ -#define SBSDIO_HT_AVAIL 0x80 /* Status: HT is ready */ - -#define SBSDIO_AVBITS (SBSDIO_HT_AVAIL | SBSDIO_ALP_AVAIL) -#define SBSDIO_ALPAV(regval) ((regval) & SBSDIO_AVBITS) -#define SBSDIO_HTAV(regval) (((regval) & SBSDIO_AVBITS) == SBSDIO_AVBITS) -#define SBSDIO_ALPONLY(regval) (SBSDIO_ALPAV(regval) && !SBSDIO_HTAV(regval)) -#define SBSDIO_CLKAV(regval, alponly) (SBSDIO_ALPAV(regval) && \ - (alponly ? 1 : SBSDIO_HTAV(regval))) + +/* Force ALP request to backplane */ +#define SBSDIO_FORCE_ALP 0x01 +/* Force HT request to backplane */ +#define SBSDIO_FORCE_HT 0x02 +/* Force ILP request to backplane */ +#define SBSDIO_FORCE_ILP 0x04 +/* Make ALP ready (power up xtal) */ +#define SBSDIO_ALP_AVAIL_REQ 0x08 +/* Make HT ready (power up PLL) */ +#define SBSDIO_HT_AVAIL_REQ 0x10 +/* Squelch clock requests from HW */ +#define SBSDIO_FORCE_HW_CLKREQ_OFF 0x20 +/* Status: ALP is ready */ +#define SBSDIO_ALP_AVAIL 0x40 +/* Status: HT is ready */ +#define SBSDIO_HT_AVAIL 0x80 + +#define SBSDIO_AVBITS (SBSDIO_HT_AVAIL | SBSDIO_ALP_AVAIL) +#define SBSDIO_ALPAV(regval) ((regval) & SBSDIO_AVBITS) +#define SBSDIO_HTAV(regval) (((regval) & SBSDIO_AVBITS) == SBSDIO_AVBITS) +#define SBSDIO_ALPONLY(regval) (SBSDIO_ALPAV(regval) && !SBSDIO_HTAV(regval)) + +#define SBSDIO_CLKAV(regval, alponly) \ + (SBSDIO_ALPAV(regval) && (alponly ? 1 : SBSDIO_HTAV(regval))) + /* direct(mapped) cis space */ -#define SBSDIO_CIS_BASE_COMMON 0x1000 /* MAPPED common CIS address */ -#define SBSDIO_CIS_SIZE_LIMIT 0x200 /* maximum bytes in one CIS */ -#define SBSDIO_CIS_OFT_ADDR_MASK 0x1FFFF /* cis offset addr is < 17 bits */ -#define SBSDIO_CIS_MANFID_TUPLE_LEN 6 /* manfid tuple length, include tuple, - * link bytes - */ +/* MAPPED common CIS address */ +#define SBSDIO_CIS_BASE_COMMON 0x1000 +/* maximum bytes in one CIS */ +#define SBSDIO_CIS_SIZE_LIMIT 0x200 +/* cis offset addr is < 17 bits */ +#define SBSDIO_CIS_OFT_ADDR_MASK 0x1FFFF + +/* manfid tuple length, include tuple, link bytes */ +#define SBSDIO_CIS_MANFID_TUPLE_LEN 6 /* intstatus */ #define I_SMB_SW0 (1 << 0) /* To SB Mail S/W interrupt 0 */ @@ -282,11 +246,7 @@ struct rte_console { /* Total length of frame header for dongle protocol */ #define SDPCM_HDRLEN (SDPCM_FRAMETAG_LEN + SDPCM_SWHEADER_LEN) -#ifdef SDTEST -#define SDPCM_RESERVE (SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + BRCMF_SDALIGN) -#else #define SDPCM_RESERVE (SDPCM_HDRLEN + BRCMF_SDALIGN) -#endif /* * Software allocation of To SB Mailbox resources @@ -397,13 +357,7 @@ struct rte_console { /* Space for header read, limit for data packets */ -#ifndef MAX_HDR_READ -#define MAX_HDR_READ 32 -#endif -#if !ISPOWEROF2(MAX_HDR_READ) -#error MAX_HDR_READ is not a power of 2! -#endif - +#define MAX_HDR_READ (1 << 6) #define MAX_RX_DATASZ 2048 /* Maximum milliseconds to wait for F2 to come up */ @@ -414,10 +368,8 @@ struct rte_console { * for HT availability, it could take a couple hundred ms more, so * max out at a 1 second (1000000us). */ -#if (PMU_MAX_TRANSITION_DLY <= 1000000) #undef PMU_MAX_TRANSITION_DLY #define PMU_MAX_TRANSITION_DLY 1000000 -#endif /* Value for ChipClockCSR during initial setup */ #define BRCMF_INIT_CLKCTL1 (SBSDIO_FORCE_HW_CLKREQ_OFF | \ @@ -433,12 +385,18 @@ struct rte_console { #define SBIM_RJ 0x02000000 /* reject (sonics >= 2.3) */ /* sbtmstatelow */ -#define SBTML_RESET 0x0001 /* reset */ -#define SBTML_REJ_MASK 0x0006 /* reject field */ -#define SBTML_REJ 0x0002 /* reject */ -#define SBTML_TMPREJ 0x0004 /* temporary reject, for error recovery */ -#define SBTML_SICF_SHIFT 16 /* Shift to locate the SI control flags in sbtml */ +/* reset */ +#define SBTML_RESET 0x0001 +/* reject field */ +#define SBTML_REJ_MASK 0x0006 +/* reject */ +#define SBTML_REJ 0x0002 +/* temporary reject, for error recovery */ +#define SBTML_TMPREJ 0x0004 + +/* Shift to locate the SI control flags in sbtml */ +#define SBTML_SICF_SHIFT 16 /* sbtmstatehigh */ #define SBTMH_SERR 0x0001 /* serror */ @@ -446,7 +404,8 @@ struct rte_console { #define SBTMH_BUSY 0x0004 /* busy */ #define SBTMH_TO 0x0020 /* timeout (sonics >= 2.3) */ -#define SBTMH_SISF_SHIFT 16 /* Shift to locate the SI status flags in sbtmh */ +/* Shift to locate the SI status flags in sbtmh */ +#define SBTMH_SISF_SHIFT 16 /* sbidlow */ #define SBIDL_INIT 0x80 /* initiator */ @@ -456,7 +415,8 @@ struct rte_console { #define SBIDH_RCE_MASK 0x7000 /* revision code extension field */ #define SBIDH_RCE_SHIFT 8 #define SBCOREREV(sbidh) \ - ((((sbidh) & SBIDH_RCE_MASK) >> SBIDH_RCE_SHIFT) | ((sbidh) & SBIDH_RC_MASK)) + ((((sbidh) & SBIDH_RCE_MASK) >> SBIDH_RCE_SHIFT) | \ + ((sbidh) & SBIDH_RC_MASK)) #define SBIDH_CC_MASK 0x8ff0 /* core code */ #define SBIDH_CC_SHIFT 4 #define SBIDH_VC_MASK 0xffff0000 /* vendor code */ @@ -469,13 +429,12 @@ struct rte_console { (((prio) == PRIO_8021D_NONE || (prio) == PRIO_8021D_BE) ? \ ((prio^2)) : (prio)) -BRCMF_SPINWAIT_SLEEP_INIT(sdioh_spinwait_sleep); - /* * Core reg address translation. * Both macro's returns a 32 bits byte address on the backplane bus. */ -#define CORE_CC_REG(base, field) (base + offsetof(chipcregs_t, field)) +#define CORE_CC_REG(base, field) \ + (base + offsetof(struct chipcregs, field)) #define CORE_BUS_REG(base, field) \ (base + offsetof(struct sdpcmd_regs, field)) #define CORE_SB(base, field) \ @@ -614,7 +573,7 @@ struct chip_info { struct brcmf_bus { struct brcmf_pub *drvr; - struct brcmf_sdio_card *card; /* Handle for sdio card calls */ + struct brcmf_sdio_dev *sdiodev; /* sdio device handler */ struct chip_info *ci; /* Chip info struct */ char *vars; /* Variables (from CIS and/or other) */ uint varsz; /* Size of variables buffer */ @@ -622,14 +581,11 @@ struct brcmf_bus { u32 ramsize; /* Size of RAM in SOCRAM (bytes) */ u32 orig_ramsize; /* Size of RAM in SOCRAM (bytes) */ - u32 bus; /* gSPI or SDIO bus */ u32 hostintmask; /* Copy of Host Interrupt Mask */ u32 intstatus; /* Intstatus bits (events) pending */ bool dpc_sched; /* Indicates DPC schedule (intrpt rcvd) */ bool fcstate; /* State of dongle flow-control */ - u16 cl_devid; /* cached devid for brcmf_sdio_probe_attach() */ - uint blocksize; /* Block size of SDIO transfers */ uint roundup; /* Max roundup limit */ @@ -660,7 +616,6 @@ struct brcmf_bus { bool intr; /* Use interrupts */ bool poll; /* Use polling */ bool ipend; /* Device interrupt is pending */ - bool intdis; /* Interrupts disabled by isr */ uint intrcount; /* Count of device interrupt callbacks */ uint lastintrs; /* Count as of last watchdog timer */ uint spurious; /* Count of spurious interrupts */ @@ -689,30 +644,6 @@ struct brcmf_bus { /* Field to decide if rx of control frames happen in rxbuf or lb-pool */ bool usebufpool; -#ifdef SDTEST - /* external loopback */ - bool ext_loop; - u8 loopid; - - /* pktgen configuration */ - uint pktgen_freq; /* Ticks between bursts */ - uint pktgen_count; /* Packets to send each burst */ - uint pktgen_print; /* Bursts between count displays */ - uint pktgen_total; /* Stop after this many */ - uint pktgen_minlen; /* Minimum packet data len */ - uint pktgen_maxlen; /* Maximum packet data len */ - uint pktgen_mode; /* Configured mode: tx, rx, or echo */ - uint pktgen_stop; /* Number of tx failures causing stop */ - - /* active pktgen fields */ - uint pktgen_tick; /* Tick counter for bursts */ - uint pktgen_ptick; /* Burst counter for printing */ - uint pktgen_sent; /* Number of test packets generated */ - uint pktgen_rcvd; /* Number of test packets received */ - uint pktgen_fail; /* Number of failed send attempts */ - u16 pktgen_len; /* Length of next packet to send */ -#endif /* SDTEST */ - /* Some additional counters */ uint tx_sderrs; /* Count of tx attempts with sd errors */ uint fcqueued; /* Tx packets that got queued */ @@ -739,6 +670,7 @@ struct brcmf_bus { spinlock_t txqlock; wait_queue_head_t ctrl_wait; + wait_queue_head_t ioctl_resp_wait; struct timer_list timer; struct completion watchdog_wait; @@ -805,8 +737,6 @@ struct sbconfig { #define CLK_PENDING 2 /* Not used yet */ #define CLK_AVAIL 3 -#define BRCMF_NOPMU(brcmf) (false) - #ifdef BCMDBG static int qcount[NUMPRIO]; static int tx_packets[NUMPRIO]; @@ -837,20 +767,38 @@ module_param(brcmf_console_ms, uint, 0); /* Tx/Rx bounds */ uint brcmf_txbound; uint brcmf_rxbound; +module_param(brcmf_txbound, uint, 0); +module_param(brcmf_rxbound, uint, 0); uint brcmf_txminmax; +int brcmf_idletime = 1; +module_param(brcmf_idletime, int, 0); + +/* SDIO Drive Strength (in milliamps) */ +uint brcmf_sdiod_drive_strength = 6; +module_param(brcmf_sdiod_drive_strength, uint, 0); + +/* Use polling */ +uint brcmf_poll; +module_param(brcmf_poll, uint, 0); + +/* Use interrupts */ +uint brcmf_intr = true; +module_param(brcmf_intr, uint, 0); + +/* IOCTL response timeout */ +static int brcmf_ioctl_timeout_msec = IOCTL_RESP_TIMEOUT; + /* override the RAM size if possible */ #define DONGLE_MIN_MEMSIZE (128 * 1024) int brcmf_dongle_memsize; +module_param(brcmf_dongle_memsize, int, 0); static bool brcmf_alignctl; -static bool sd1idle; - static bool retrydata; #define RETRYCHAN(chan) (((chan) == SDPCM_EVENT_CHANNEL) || retrydata) -static const uint watermark = 8; static const uint firstread = BRCMF_FIRSTREAD; /* Retry count for register access failures */ @@ -891,13 +839,14 @@ r_sdreg32(struct brcmf_bus *bus, u32 *regvar, u32 reg_offset, u32 *retryvar) { *retryvar = 0; do { - *regvar = R_REG(bus->ci->buscorebase + reg_offset, u32); - } while (brcmf_sdcard_regfail(bus->card) && + *regvar = brcmf_sdcard_reg_read(bus->sdiodev, + bus->ci->buscorebase + reg_offset, sizeof(u32)); + } while (brcmf_sdcard_regfail(bus->sdiodev) && (++(*retryvar) <= retry_limit)); if (*retryvar) { bus->regfails += (*retryvar-1); if (*retryvar > retry_limit) { - BRCMF_ERROR(("FAILED READ %Xh\n", reg_offset)); + brcmf_dbg(ERROR, "FAILED READ %Xh\n", reg_offset); *regvar = 0; } } @@ -908,29 +857,23 @@ w_sdreg32(struct brcmf_bus *bus, u32 regval, u32 reg_offset, u32 *retryvar) { *retryvar = 0; do { - brcmf_sdcard_reg_write(NULL, bus->ci->buscorebase + reg_offset, + brcmf_sdcard_reg_write(bus->sdiodev, + bus->ci->buscorebase + reg_offset, sizeof(u32), regval); - } while (brcmf_sdcard_regfail(bus->card) && + } while (brcmf_sdcard_regfail(bus->sdiodev) && (++(*retryvar) <= retry_limit)); if (*retryvar) { bus->regfails += (*retryvar-1); if (*retryvar > retry_limit) - BRCMF_ERROR(("FAILED REGISTER WRITE" - " %Xh\n", reg_offset)); + brcmf_dbg(ERROR, "FAILED REGISTER WRITE %Xh\n", + reg_offset); } } -#define BRCMF_BUS SDIO_BUS - #define PKT_AVAILABLE() (intstatus & I_HMB_FRAME_IND) #define HOSTINTMASK (I_HMB_SW_MASK | I_CHIPACTIVE) -#ifdef SDTEST -static void brcmf_sdbrcm_checkdied(struct brcmf_bus *bus, void *pkt, uint seq); -static void brcmf_sdbrcm_sdtest_set(struct brcmf_bus *bus, bool start); -#endif - #ifdef BCMDBG static int brcmf_sdbrcm_bus_console_in(struct brcmf_pub *drvr, unsigned char *msg, uint msglen); @@ -941,12 +884,10 @@ static int brcmf_sdbrcm_download_state(struct brcmf_bus *bus, bool enter); static void brcmf_sdbrcm_release(struct brcmf_bus *bus); static void brcmf_sdbrcm_release_malloc(struct brcmf_bus *bus); -static void brcmf_sdbrcm_disconnect(void *ptr); static bool brcmf_sdbrcm_chipmatch(u16 chipid); -static bool brcmf_sdbrcm_probe_attach(struct brcmf_bus *bus, void *card, - u32 regsva, u16 devid); -static bool brcmf_sdbrcm_probe_malloc(struct brcmf_bus *bus, void *card); -static bool brcmf_sdbrcm_probe_init(struct brcmf_bus *bus, void *card); +static bool brcmf_sdbrcm_probe_attach(struct brcmf_bus *bus, u32 regsva); +static bool brcmf_sdbrcm_probe_malloc(struct brcmf_bus *bus); +static bool brcmf_sdbrcm_probe_init(struct brcmf_bus *bus); static void brcmf_sdbrcm_release_dongle(struct brcmf_bus *bus); static uint brcmf_process_nvram_vars(char *varbuf, uint len); @@ -954,24 +895,21 @@ static uint brcmf_process_nvram_vars(char *varbuf, uint len); static void brcmf_sdbrcm_setmemsize(struct brcmf_bus *bus, int mem_size); static int brcmf_sdbrcm_send_buf(struct brcmf_bus *bus, 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); + struct sk_buff *pkt); -static bool brcmf_sdbrcm_download_firmware(struct brcmf_bus *bus, void *card); +static bool brcmf_sdbrcm_download_firmware(struct brcmf_bus *bus); static int _brcmf_sdbrcm_download_firmware(struct brcmf_bus *bus); static int brcmf_sdbrcm_download_code_file(struct brcmf_bus *bus); static int brcmf_sdbrcm_download_nvram(struct brcmf_bus *bus); static void -brcmf_sdbrcm_chip_disablecore(struct brcmf_sdio_card *card, u32 corebase); +brcmf_sdbrcm_chip_disablecore(struct brcmf_sdio_dev *sdiodev, u32 corebase); static int brcmf_sdbrcm_chip_attach(struct brcmf_bus *bus, u32 regs); static void -brcmf_sdbrcm_chip_resetcore(struct brcmf_sdio_card *card, u32 corebase); +brcmf_sdbrcm_chip_resetcore(struct brcmf_sdio_dev *sdiodev, u32 corebase); static void brcmf_sdbrcm_sdiod_drive_strength_init(struct brcmf_bus *bus, u32 drivestrength); @@ -986,13 +924,16 @@ static void brcmf_sdbrcm_sched_dpc(struct brcmf_bus *bus); static void brcmf_sdbrcm_sdlock(struct brcmf_bus *bus); static void brcmf_sdbrcm_sdunlock(struct brcmf_bus *bus); static int brcmf_sdbrcm_get_image(char *buf, int len, struct brcmf_bus *bus); +static int brcmf_sdbrcm_ioctl_resp_wait(struct brcmf_bus *bus, uint *condition, + bool *pending); +static int brcmf_sdbrcm_ioctl_resp_wake(struct brcmf_bus *bus); /* Packet free applicable unconditionally for sdio and sdspi. * Conditional if bufpool was present for gspi bus. */ static void brcmf_sdbrcm_pktfree2(struct brcmf_bus *bus, struct sk_buff *pkt) { - if ((bus->bus != SPI_BUS) || bus->usebufpool) + if (bus->usebufpool) brcmu_pkt_buf_free_skb(pkt); } @@ -1000,8 +941,8 @@ static void brcmf_sdbrcm_setmemsize(struct brcmf_bus *bus, int mem_size) { s32 min_size = DONGLE_MIN_MEMSIZE; /* Restrict the memsize to user specified limit */ - BRCMF_ERROR(("user: Restrict the dongle ram size to %d, min %d\n", - brcmf_dongle_memsize, min_size)); + brcmf_dbg(ERROR, "user: Restrict the dongle ram size to %d, min %d\n", + brcmf_dongle_memsize, min_size); if ((brcmf_dongle_memsize > min_size) && (brcmf_dongle_memsize < (s32) bus->orig_ramsize)) bus->ramsize = brcmf_dongle_memsize; @@ -1010,14 +951,15 @@ static void brcmf_sdbrcm_setmemsize(struct brcmf_bus *bus, int mem_size) static int brcmf_sdbrcm_set_siaddr_window(struct brcmf_bus *bus, u32 address) { int err = 0; - brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRLOW, - (address >> 8) & SBSDIO_SBADDRLOW_MASK, &err); + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, + SBSDIO_FUNC1_SBADDRLOW, + (address >> 8) & SBSDIO_SBADDRLOW_MASK, &err); if (!err) - brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_1, + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRMID, (address >> 16) & SBSDIO_SBADDRMID_MASK, &err); if (!err) - brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_1, + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, SBSDIO_FUNC1_SBADDRHIGH, (address >> 24) & SBSDIO_SBADDRHIGH_MASK, &err); @@ -1029,12 +971,11 @@ static int brcmf_sdbrcm_htclk(struct brcmf_bus *bus, bool on, bool pendok) { int err; u8 clkctl, clkreq, devctl; - struct brcmf_sdio_card *card; + unsigned long timeout; - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); clkctl = 0; - card = bus->card; if (on) { /* Request HT Avail */ @@ -1045,11 +986,10 @@ static int brcmf_sdbrcm_htclk(struct brcmf_bus *bus, bool on, bool pendok) && (bus->ci->chiprev == 0)) clkreq |= SBSDIO_FORCE_ALP; - brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, clkreq, &err); if (err) { - BRCMF_ERROR(("%s: HT Avail request error: %d\n", - __func__, err)); + brcmf_dbg(ERROR, "HT Avail request error: %d\n", err); return -EBADE; } @@ -1062,74 +1002,73 @@ static int brcmf_sdbrcm_htclk(struct brcmf_bus *bus, bool on, bool pendok) } /* Check current status */ - clkctl = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1, + clkctl = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err); if (err) { - BRCMF_ERROR(("%s: HT Avail read error: %d\n", - __func__, err)); + brcmf_dbg(ERROR, "HT Avail read error: %d\n", err); return -EBADE; } /* Go to pending and await interrupt if appropriate */ if (!SBSDIO_CLKAV(clkctl, bus->alp_only) && pendok) { /* Allow only clock-available interrupt */ - devctl = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1, + devctl = brcmf_sdcard_cfg_read(bus->sdiodev, + SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err); if (err) { - BRCMF_ERROR(("%s: Devctl error setting CA:" - " %d\n", __func__, err)); + brcmf_dbg(ERROR, "Devctl error setting CA: %d\n", + err); return -EBADE; } devctl |= SBSDIO_DEVCTL_CA_INT_ONLY; - brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, devctl, &err); - BRCMF_INFO(("CLKCTL: set PENDING\n")); + brcmf_dbg(INFO, "CLKCTL: set PENDING\n"); bus->clkstate = CLK_PENDING; return 0; } else if (bus->clkstate == CLK_PENDING) { /* Cancel CA-only interrupt filter */ devctl = - brcmf_sdcard_cfg_read(card, SDIO_FUNC_1, + brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err); devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; - brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, devctl, &err); } /* Otherwise, wait here (polling) for HT Avail */ - if (!SBSDIO_CLKAV(clkctl, bus->alp_only)) { - BRCMF_SPINWAIT_SLEEP(sdioh_spinwait_sleep, - ((clkctl = - brcmf_sdcard_cfg_read(card, SDIO_FUNC_1, - SBSDIO_FUNC1_CHIPCLKCSR, - &err)), - !SBSDIO_CLKAV(clkctl, bus->alp_only)), - PMU_MAX_TRANSITION_DLY); + timeout = jiffies + + msecs_to_jiffies(PMU_MAX_TRANSITION_DLY/1000); + while (!SBSDIO_CLKAV(clkctl, bus->alp_only)) { + clkctl = brcmf_sdcard_cfg_read(bus->sdiodev, + SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, + &err); + if (time_after(jiffies, timeout)) + break; + else + usleep_range(5000, 10000); } if (err) { - BRCMF_ERROR(("%s: HT Avail request error: %d\n", - __func__, err)); + brcmf_dbg(ERROR, "HT Avail request error: %d\n", err); return -EBADE; } if (!SBSDIO_CLKAV(clkctl, bus->alp_only)) { - BRCMF_ERROR(("%s: HT Avail timeout (%d): " - "clkctl 0x%02x\n", __func__, - PMU_MAX_TRANSITION_DLY, clkctl)); + brcmf_dbg(ERROR, "HT Avail timeout (%d): clkctl 0x%02x\n", + PMU_MAX_TRANSITION_DLY, clkctl); return -EBADE; } /* Mark clock available */ bus->clkstate = CLK_AVAIL; - BRCMF_INFO(("CLKCTL: turned ON\n")); + brcmf_dbg(INFO, "CLKCTL: turned ON\n"); #if defined(BCMDBG) if (bus->alp_only != true) { - if (SBSDIO_ALPONLY(clkctl)) { - BRCMF_ERROR(("%s: HT Clock should be on.\n", - __func__)); - } + if (SBSDIO_ALPONLY(clkctl)) + brcmf_dbg(ERROR, "HT Clock should be on\n"); } #endif /* defined (BCMDBG) */ @@ -1139,20 +1078,21 @@ static int brcmf_sdbrcm_htclk(struct brcmf_bus *bus, bool on, bool pendok) if (bus->clkstate == CLK_PENDING) { /* Cancel CA-only interrupt filter */ - devctl = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1, + devctl = brcmf_sdcard_cfg_read(bus->sdiodev, + SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err); devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; - brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, devctl, &err); } bus->clkstate = CLK_SDONLY; - brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, clkreq, &err); - BRCMF_INFO(("CLKCTL: turned OFF\n")); + brcmf_dbg(INFO, "CLKCTL: turned OFF\n"); if (err) { - BRCMF_ERROR(("%s: Failed access turning clock off:" - " %d\n", __func__, err)); + brcmf_dbg(ERROR, "Failed access turning clock off: %d\n", + err); return -EBADE; } } @@ -1162,7 +1102,7 @@ static int brcmf_sdbrcm_htclk(struct brcmf_bus *bus, bool on, bool pendok) /* Change idle/active SD state */ static int brcmf_sdbrcm_sdclk(struct brcmf_bus *bus, bool on) { - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); if (on) bus->clkstate = CLK_SDONLY; @@ -1179,7 +1119,7 @@ static int brcmf_sdbrcm_clkctl(struct brcmf_bus *bus, uint target, bool pendok) uint oldstate = bus->clkstate; #endif /* BCMDBG */ - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); /* Early exit if we're already there */ if (bus->clkstate == target) { @@ -1208,8 +1148,8 @@ static int brcmf_sdbrcm_clkctl(struct brcmf_bus *bus, uint target, bool pendok) else if (bus->clkstate == CLK_AVAIL) brcmf_sdbrcm_htclk(bus, false, false); else - BRCMF_ERROR(("brcmf_sdbrcm_clkctl: request for %d -> %d" - "\n", bus->clkstate, target)); + brcmf_dbg(ERROR, "request for %d -> %d\n", + bus->clkstate, target); brcmf_sdbrcm_wd_timer(bus, brcmf_watchdog_ms); break; @@ -1223,8 +1163,7 @@ static int brcmf_sdbrcm_clkctl(struct brcmf_bus *bus, uint target, bool pendok) break; } #ifdef BCMDBG - BRCMF_INFO(("brcmf_sdbrcm_clkctl: %d -> %d\n", - oldstate, bus->clkstate)); + brcmf_dbg(INFO, "%d -> %d\n", oldstate, bus->clkstate); #endif /* BCMDBG */ return 0; @@ -1232,12 +1171,11 @@ static int brcmf_sdbrcm_clkctl(struct brcmf_bus *bus, uint target, bool pendok) int brcmf_sdbrcm_bussleep(struct brcmf_bus *bus, bool sleep) { - struct brcmf_sdio_card *card = bus->card; uint retries = 0; - BRCMF_INFO(("brcmf_sdbrcm_bussleep: request %s (currently %s)\n", - (sleep ? "SLEEP" : "WAKE"), - (bus->sleeping ? "SLEEP" : "WAKE"))); + brcmf_dbg(INFO, "request %s (currently %s)\n", + sleep ? "SLEEP" : "WAKE", + bus->sleeping ? "SLEEP" : "WAKE"); /* Done if we're already in the requested state */ if (sleep == bus->sleeping) @@ -1249,9 +1187,6 @@ int brcmf_sdbrcm_bussleep(struct brcmf_bus *bus, bool sleep) if (bus->dpc_sched || bus->rxskip || pktq_len(&bus->txq)) return -EBUSY; - /* Disable SDIO interrupts (no longer interested) */ - brcmf_sdcard_intr_disable(bus->card); - /* Make sure the controller has the bus up */ brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); @@ -1259,20 +1194,18 @@ int brcmf_sdbrcm_bussleep(struct brcmf_bus *bus, bool sleep) w_sdreg32(bus, SMB_USE_OOB, offsetof(struct sdpcmd_regs, tosbmailbox), &retries); if (retries > retry_limit) - BRCMF_ERROR(("CANNOT SIGNAL CHIP, " - "WILL NOT WAKE UP!!\n")); + brcmf_dbg(ERROR, "CANNOT SIGNAL CHIP, WILL NOT WAKE UP!!\n"); /* Turn off our contribution to the HT clock request */ brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false); - brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, SBSDIO_FORCE_HW_CLKREQ_OFF, NULL); /* Isolate the bus */ - if (bus->ci->chip != BCM4329_CHIP_ID - && bus->ci->chip != BCM4319_CHIP_ID) { - brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, + if (bus->ci->chip != BCM4329_CHIP_ID) { + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, SBSDIO_DEVCTL_PADS_ISO, NULL); } @@ -1283,14 +1216,14 @@ int brcmf_sdbrcm_bussleep(struct brcmf_bus *bus, bool sleep) } else { /* Waking up: bus power up is ok, set local state */ - brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); /* Force pad isolation off if possible (in case power never toggled) */ if ((bus->ci->buscoretype == PCMCIA_CORE_ID) && (bus->ci->buscorerev >= 10)) - brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, 0, NULL); /* Make sure the controller has the bus up */ @@ -1305,19 +1238,13 @@ int brcmf_sdbrcm_bussleep(struct brcmf_bus *bus, bool sleep) &retries); if (retries > retry_limit) - BRCMF_ERROR(("CANNOT SIGNAL CHIP TO CLEAR OOB!!\n")); + brcmf_dbg(ERROR, "CANNOT SIGNAL CHIP TO CLEAR OOB!!\n"); /* Make sure we have SD bus access */ brcmf_sdbrcm_clkctl(bus, CLK_SDONLY, false); /* Change state */ bus->sleeping = false; - - /* Enable interrupts again */ - if (bus->intr && (bus->drvr->busstate == BRCMF_BUS_DATA)) { - bus->intdis = false; - brcmf_sdcard_intr_enable(bus->card); - } } return 0; @@ -1331,21 +1258,18 @@ int brcmf_sdbrcm_bussleep(struct brcmf_bus *bus, bool sleep) /* Writes a HW/SW header into the packet and sends it. */ /* Assumes: (a) header space already there, (b) caller holds lock */ -static int brcmf_sdbrcm_txpkt(struct brcmf_bus *bus, struct sk_buff *pkt, uint chan, - bool free_pkt) +static int brcmf_sdbrcm_txpkt(struct brcmf_bus *bus, struct sk_buff *pkt, + uint chan, bool free_pkt) { int ret; u8 *frame; u16 len, pad = 0; u32 swheader; uint retries = 0; - struct brcmf_sdio_card *card; struct sk_buff *new; int i; - BRCMF_TRACE(("%s: Enter\n", __func__)); - - card = bus->card; + brcmf_dbg(TRACE, "Enter\n"); if (bus->drvr->dongle_reset) { ret = -EPERM; @@ -1358,14 +1282,13 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_bus *bus, struct sk_buff *pkt, uint c pad = ((unsigned long)frame % BRCMF_SDALIGN); if (pad) { if (skb_headroom(pkt) < pad) { - BRCMF_INFO(("%s: insufficient headroom %d for %d pad\n", - __func__, skb_headroom(pkt), pad)); + brcmf_dbg(INFO, "insufficient headroom %d for %d pad\n", + skb_headroom(pkt), pad); bus->drvr->tx_realloc++; new = brcmu_pkt_buf_get_skb(pkt->len + BRCMF_SDALIGN); if (!new) { - BRCMF_ERROR(("%s: couldn't allocate new " - "%d-byte packet\n", __func__, - pkt->len + BRCMF_SDALIGN)); + brcmf_dbg(ERROR, "couldn't allocate new %d-byte packet\n", + pkt->len + BRCMF_SDALIGN); ret = -ENOMEM; goto done; } @@ -1427,34 +1350,36 @@ static int brcmf_sdbrcm_txpkt(struct brcmf_bus *bus, struct sk_buff *pkt, uint c } /* Some controllers have trouble with odd bytes -- round to even */ - if (forcealign && (len & (ALIGNMENT - 1))) { + if (forcealign && (len & (ALIGNMENT - 1))) len = roundup(len, ALIGNMENT); - } do { - ret = brcmf_sdbrcm_send_buf(bus, brcmf_sdcard_cur_sbwad(card), - SDIO_FUNC_2, F2SYNC, frame, len, pkt, NULL, NULL); + ret = brcmf_sdbrcm_send_buf(bus, + brcmf_sdcard_cur_sbwad(bus->sdiodev), + SDIO_FUNC_2, F2SYNC, frame, len, pkt); bus->f2txdata++; if (ret < 0) { /* On failure, abort the command and terminate the frame */ - BRCMF_INFO(("%s: sdio error %d, abort command and " - "terminate frame.\n", __func__, ret)); + brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n", + ret); bus->tx_sderrs++; - brcmf_sdcard_abort(card, SDIO_FUNC_2); - brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, + brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2); + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM, NULL); bus->f1regdata++; for (i = 0; i < 3; i++) { u8 hi, lo; - hi = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1, + hi = brcmf_sdcard_cfg_read(bus->sdiodev, + SDIO_FUNC_1, SBSDIO_FUNC1_WFRAMEBCHI, NULL); - lo = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1, + lo = brcmf_sdcard_cfg_read(bus->sdiodev, + SDIO_FUNC_1, SBSDIO_FUNC1_WFRAMEBCLO, NULL); bus->f1regdata += 2; @@ -1486,24 +1411,10 @@ int brcmf_sdbrcm_bus_txdata(struct brcmf_bus *bus, struct sk_buff *pkt) int ret = -EBADE; uint datalen, prec; - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); datalen = pkt->len; -#ifdef SDTEST - /* Push the test header if doing loopback */ - if (bus->ext_loop) { - u8 *data; - skb_push(pkt, SDPCM_TEST_HDRLEN); - data = pkt->data; - *data++ = SDPCM_TEST_ECHOREQ; - *data++ = (u8) bus->loopid++; - *data++ = (datalen >> 0); - *data++ = (datalen >> 8); - datalen += SDPCM_TEST_HDRLEN; - } -#endif /* SDTEST */ - /* Add space for the header */ skb_push(pkt, SDPCM_HDRLEN); /* precondition: IS_ALIGNED((unsigned long)(pkt->data), 2) */ @@ -1516,17 +1427,18 @@ int brcmf_sdbrcm_bus_txdata(struct brcmf_bus *bus, struct sk_buff *pkt) || bus->dpc_sched || (!DATAOK(bus)) || (bus->flowcontrol & NBITVAL(prec)) || (bus->clkstate != CLK_AVAIL)) { - BRCMF_TRACE(("%s: deferring pktq len %d\n", __func__, - pktq_len(&bus->txq))); + brcmf_dbg(TRACE, "deferring pktq len %d\n", + pktq_len(&bus->txq)); bus->fcqueued++; /* Priority based enq */ spin_lock_bh(&bus->txqlock); - if (brcmf_c_prec_enq(bus->drvr, &bus->txq, pkt, prec) == false) { + if (brcmf_c_prec_enq(bus->drvr, &bus->txq, pkt, prec) == + false) { skb_pull(pkt, SDPCM_HDRLEN); brcmf_txcomplete(bus->drvr, pkt, false); brcmu_pkt_buf_free_skb(pkt); - BRCMF_ERROR(("%s: out of bus->txq !!!\n", __func__)); + brcmf_dbg(ERROR, "out of bus->txq !!!\n"); ret = -ENOSR; } else { ret = 0; @@ -1554,14 +1466,8 @@ int brcmf_sdbrcm_bus_txdata(struct brcmf_bus *bus, struct sk_buff *pkt) /* Make sure back plane ht clk is on, no pending allowed */ brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, true); -#ifndef SDTEST - BRCMF_TRACE(("%s: calling txpkt\n", __func__)); + brcmf_dbg(TRACE, "calling txpkt\n"); ret = brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, true); -#else - ret = brcmf_sdbrcm_txpkt(bus, pkt, - (bus->ext_loop ? SDPCM_TEST_CHANNEL : - SDPCM_DATA_CHANNEL), true); -#endif if (ret) bus->drvr->tx_errors++; else @@ -1591,7 +1497,7 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_bus *bus, uint maxframes) struct brcmf_pub *drvr = bus->drvr; - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); tx_prec_map = ~bus->flowcontrol; @@ -1606,13 +1512,7 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_bus *bus, uint maxframes) spin_unlock_bh(&bus->txqlock); datalen = pkt->len - SDPCM_HDRLEN; -#ifndef SDTEST ret = brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, true); -#else - ret = brcmf_sdbrcm_txpkt(bus, pkt, - (bus->ext_loop ? SDPCM_TEST_CHANNEL : - SDPCM_DATA_CHANNEL), true); -#endif if (ret) bus->drvr->tx_errors++; else @@ -1625,7 +1525,7 @@ static uint brcmf_sdbrcm_sendfromq(struct brcmf_bus *bus, uint maxframes) offsetof(struct sdpcmd_regs, intstatus), &retries); bus->f2txdata++; - if (brcmf_sdcard_regfail(bus->card)) + if (brcmf_sdcard_regfail(bus->sdiodev)) break; if (intstatus & bus->hostintmask) bus->ipend = true; @@ -1647,12 +1547,11 @@ brcmf_sdbrcm_bus_txctl(struct brcmf_bus *bus, unsigned char *msg, uint msglen) u16 len; u32 swheader; uint retries = 0; - struct brcmf_sdio_card *card = bus->card; u8 doff = 0; int ret = -1; int i; - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); if (bus->drvr->dongle_reset) return -EIO; @@ -1711,9 +1610,8 @@ brcmf_sdbrcm_bus_txctl(struct brcmf_bus *bus, unsigned char *msg, uint msglen) put_unaligned_le32(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader)); if (!DATAOK(bus)) { - BRCMF_INFO(("%s: No bus credit bus->tx_max %d," - " bus->tx_seq %d\n", __func__, - bus->tx_max, bus->tx_seq)); + brcmf_dbg(INFO, "No bus credit bus->tx_max %d, bus->tx_seq %d\n", + bus->tx_max, bus->tx_seq); bus->ctrl_frame_stat = true; /* Send from dpc */ bus->ctrl_frame_buf = frame; @@ -1722,11 +1620,10 @@ brcmf_sdbrcm_bus_txctl(struct brcmf_bus *bus, unsigned char *msg, uint msglen) brcmf_sdbrcm_wait_for_event(bus, &bus->ctrl_frame_stat); if (bus->ctrl_frame_stat == false) { - BRCMF_INFO(("%s: ctrl_frame_stat == false\n", - __func__)); + brcmf_dbg(INFO, "ctrl_frame_stat == false\n"); ret = 0; } else { - BRCMF_INFO(("%s: ctrl_frame_stat == true\n", __func__)); + brcmf_dbg(INFO, "ctrl_frame_stat == true\n"); ret = -1; } } @@ -1747,31 +1644,32 @@ brcmf_sdbrcm_bus_txctl(struct brcmf_bus *bus, unsigned char *msg, uint msglen) do { bus->ctrl_frame_stat = false; ret = brcmf_sdbrcm_send_buf(bus, - brcmf_sdcard_cur_sbwad(card), SDIO_FUNC_2, - F2SYNC, frame, len, NULL, NULL, NULL); + brcmf_sdcard_cur_sbwad(bus->sdiodev), + SDIO_FUNC_2, + F2SYNC, frame, len, NULL); if (ret < 0) { /* On failure, abort the command and terminate the frame */ - BRCMF_INFO(("%s: sdio error %d, abort command " - "and terminate frame.\n", - __func__, ret)); + brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n", + ret); bus->tx_sderrs++; - brcmf_sdcard_abort(card, SDIO_FUNC_2); + brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2); - brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, + brcmf_sdcard_cfg_write(bus->sdiodev, + SDIO_FUNC_1, SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM, NULL); bus->f1regdata++; for (i = 0; i < 3; i++) { u8 hi, lo; - hi = brcmf_sdcard_cfg_read(card, + hi = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, SBSDIO_FUNC1_WFRAMEBCHI, NULL); - lo = brcmf_sdcard_cfg_read(card, + lo = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, SBSDIO_FUNC1_WFRAMEBCLO, NULL); @@ -1781,10 +1679,10 @@ brcmf_sdbrcm_bus_txctl(struct brcmf_bus *bus, unsigned char *msg, uint msglen) } } - if (ret == 0) { + if (ret == 0) bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; - } + } while ((ret < 0) && retries++ < TXRETRIES); } @@ -1803,19 +1701,20 @@ brcmf_sdbrcm_bus_txctl(struct brcmf_bus *bus, unsigned char *msg, uint msglen) return ret ? -EIO : 0; } -int brcmf_sdbrcm_bus_rxctl(struct brcmf_bus *bus, unsigned char *msg, uint msglen) +int +brcmf_sdbrcm_bus_rxctl(struct brcmf_bus *bus, unsigned char *msg, uint msglen) { int timeleft; uint rxlen = 0; bool pending; - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); if (bus->drvr->dongle_reset) return -EIO; /* Wait until control frame is available */ - timeleft = brcmf_os_ioctl_resp_wait(bus->drvr, &bus->rxlen, &pending); + timeleft = brcmf_sdbrcm_ioctl_resp_wait(bus, &bus->rxlen, &pending); brcmf_sdbrcm_sdlock(bus); rxlen = bus->rxlen; @@ -1824,20 +1723,20 @@ int brcmf_sdbrcm_bus_rxctl(struct brcmf_bus *bus, unsigned char *msg, uint msgle brcmf_sdbrcm_sdunlock(bus); if (rxlen) { - BRCMF_CTL(("%s: resumed on rxctl frame, got %d expected %d\n", - __func__, rxlen, msglen)); + brcmf_dbg(CTL, "resumed on rxctl frame, got %d expected %d\n", + rxlen, msglen); } else if (timeleft == 0) { - BRCMF_ERROR(("%s: resumed on timeout\n", __func__)); + brcmf_dbg(ERROR, "resumed on timeout\n"); #ifdef BCMDBG brcmf_sdbrcm_sdlock(bus); brcmf_sdbrcm_checkdied(bus, NULL, 0); brcmf_sdbrcm_sdunlock(bus); #endif /* BCMDBG */ } else if (pending == true) { - BRCMF_CTL(("%s: cancelled\n", __func__)); + brcmf_dbg(CTL, "cancelled\n"); return -ERESTARTSYS; } else { - BRCMF_CTL(("%s: resumed for unknown reason?\n", __func__)); + brcmf_dbg(CTL, "resumed for unknown reason?\n"); #ifdef BCMDBG brcmf_sdbrcm_sdlock(bus); brcmf_sdbrcm_checkdied(bus, NULL, 0); @@ -1875,20 +1774,14 @@ enum { IOV_ALIGNCTL, IOV_SDALIGN, IOV_DEVRESET, - IOV_CPU, -#ifdef SDTEST - IOV_PKTGEN, - IOV_EXTLOOP, -#endif /* SDTEST */ - IOV_SPROM, IOV_TXBOUND, IOV_RXBOUND, IOV_TXMINMAX, IOV_IDLETIME, IOV_IDLECLOCK, - IOV_SD1IDLE, IOV_SLEEP, IOV_WDTICK, + IOV_IOCTLTIMEOUT, IOV_VARS }; @@ -1898,7 +1791,6 @@ const struct brcmu_iovar brcmf_sdio_iovars[] = { {"pollrate", IOV_POLLRATE, 0, IOVT_UINT32, 0}, {"idletime", IOV_IDLETIME, 0, IOVT_INT32, 0}, {"idleclock", IOV_IDLECLOCK, 0, IOVT_INT32, 0}, - {"sd1idle", IOV_SD1IDLE, 0, IOVT_BOOL, 0}, {"membytes", IOV_MEMBYTES, 0, IOVT_BUFFER, 2 * sizeof(int)}, {"memsize", IOV_MEMSIZE, 0, IOVT_UINT32, 0}, {"download", IOV_DOWNLOAD, 0, IOVT_BOOL, 0}, @@ -1910,6 +1802,7 @@ const struct brcmu_iovar brcmf_sdio_iovars[] = { {"sdalign", IOV_SDALIGN, 0, IOVT_BOOL, 0}, {"devreset", IOV_DEVRESET, 0, IOVT_BOOL, 0}, {"wdtick", IOV_WDTICK, 0, IOVT_UINT32, 0}, + {"ioctl_timeout", IOV_IOCTLTIMEOUT, 0, IOVT_UINT32, 0}, #ifdef BCMDBG {"cons", IOV_CONS, 0, IOVT_BUFFER, 0} , @@ -1929,17 +1822,9 @@ const struct brcmu_iovar brcmf_sdio_iovars[] = { , {"txminmax", IOV_TXMINMAX, 0, IOVT_UINT32, 0} , - {"cpu", IOV_CPU, 0, IOVT_BOOL, 0} - , {"checkdied", IOV_CHECKDIED, 0, IOVT_BUFFER, 0} , #endif /* BCMDBG */ -#ifdef SDTEST - {"extloop", IOV_EXTLOOP, 0, IOVT_BOOL, 0} - , - {"pktgen", IOV_PKTGEN, 0, IOVT_BUFFER, sizeof(struct brcmf_pktgen)} - , -#endif /* SDTEST */ {NULL, 0, 0, 0, 0} }; @@ -2033,19 +1918,6 @@ void brcmf_sdbrcm_bus_dump(struct brcmf_pub *drvr, struct brcmu_strbuf *strbuf) brcmu_bprintf(strbuf, "\n\n"); } -#ifdef SDTEST - if (bus->pktgen_count) { - brcmu_bprintf(strbuf, "pktgen config and count:\n"); - brcmu_bprintf(strbuf, - "freq %d count %d print %d total %d min %d len %d\n", - bus->pktgen_freq, bus->pktgen_count, - bus->pktgen_print, bus->pktgen_total, - bus->pktgen_minlen, bus->pktgen_maxlen); - brcmu_bprintf(strbuf, "send attempts %d rcvd %d fail %d\n", - bus->pktgen_sent, bus->pktgen_rcvd, - bus->pktgen_fail); - } -#endif /* SDTEST */ #ifdef BCMDBG brcmu_bprintf(strbuf, "dpc_sched %d host interrupt%spending\n", bus->dpc_sched, " not "); @@ -2070,62 +1942,6 @@ void brcmf_bus_clearcounts(struct brcmf_pub *drvr) bus->f2rxhdrs = bus->f2rxdata = bus->f2txdata = bus->f1regdata = 0; } -#ifdef SDTEST -static int brcmf_sdbrcm_pktgen_get(struct brcmf_bus *bus, u8 *arg) -{ - struct brcmf_pktgen pktgen; - - pktgen.version = BRCMF_PKTGEN_VERSION; - pktgen.freq = bus->pktgen_freq; - pktgen.count = bus->pktgen_count; - pktgen.print = bus->pktgen_print; - pktgen.total = bus->pktgen_total; - pktgen.minlen = bus->pktgen_minlen; - pktgen.maxlen = bus->pktgen_maxlen; - pktgen.numsent = bus->pktgen_sent; - pktgen.numrcvd = bus->pktgen_rcvd; - pktgen.numfail = bus->pktgen_fail; - pktgen.mode = bus->pktgen_mode; - pktgen.stop = bus->pktgen_stop; - - memcpy(arg, &pktgen, sizeof(pktgen)); - - return 0; -} - -static int brcmf_sdbrcm_pktgen_set(struct brcmf_bus *bus, u8 *arg) -{ - struct brcmf_pktgen pktgen; - uint oldcnt, oldmode; - - memcpy(&pktgen, arg, sizeof(pktgen)); - if (pktgen.version != BRCMF_PKTGEN_VERSION) - return -EINVAL; - - oldcnt = bus->pktgen_count; - oldmode = bus->pktgen_mode; - - bus->pktgen_freq = pktgen.freq; - bus->pktgen_count = pktgen.count; - bus->pktgen_print = pktgen.print; - bus->pktgen_total = pktgen.total; - bus->pktgen_minlen = pktgen.minlen; - bus->pktgen_maxlen = pktgen.maxlen; - bus->pktgen_mode = pktgen.mode; - bus->pktgen_stop = pktgen.stop; - - bus->pktgen_tick = bus->pktgen_ptick = 0; - bus->pktgen_len = max(bus->pktgen_len, bus->pktgen_minlen); - bus->pktgen_len = min(bus->pktgen_len, bus->pktgen_maxlen); - - /* Clear counts for a new pktgen (mode change, or was stopped) */ - if (bus->pktgen_count && (!oldcnt || oldmode != bus->pktgen_mode)) - bus->pktgen_sent = bus->pktgen_rcvd = bus->pktgen_fail = 0; - - return 0; -} -#endif /* SDTEST */ - static int brcmf_sdbrcm_membytes(struct brcmf_bus *bus, bool write, u32 address, u8 *data, uint size) @@ -2144,20 +1960,19 @@ brcmf_sdbrcm_membytes(struct brcmf_bus *bus, bool write, u32 address, u8 *data, /* Set the backplane window to include the start address */ bcmerror = brcmf_sdbrcm_set_siaddr_window(bus, address); if (bcmerror) { - BRCMF_ERROR(("%s: window change failed\n", __func__)); + brcmf_dbg(ERROR, "window change failed\n"); goto xfer_done; } /* Do the transfer(s) */ while (size) { - BRCMF_INFO(("%s: %s %d bytes at offset 0x%08x in window" - " 0x%08x\n", __func__, (write ? "write" : "read"), - dsize, sdaddr, (address & SBSDIO_SBWINDOW_MASK))); - bcmerror = - brcmf_sdcard_rwdata(bus->card, write, sdaddr, data, dsize); + brcmf_dbg(INFO, "%s %d bytes at offset 0x%08x in window 0x%08x\n", + write ? "write" : "read", dsize, + sdaddr, address & SBSDIO_SBWINDOW_MASK); + bcmerror = brcmf_sdcard_rwdata(bus->sdiodev, write, + sdaddr, data, dsize); if (bcmerror) { - BRCMF_ERROR(("%s: membytes transfer failed\n", - __func__)); + brcmf_dbg(ERROR, "membytes transfer failed\n"); break; } @@ -2168,8 +1983,7 @@ brcmf_sdbrcm_membytes(struct brcmf_bus *bus, bool write, u32 address, u8 *data, address += dsize; bcmerror = brcmf_sdbrcm_set_siaddr_window(bus, address); if (bcmerror) { - BRCMF_ERROR(("%s: window change failed\n", - __func__)); + brcmf_dbg(ERROR, "window change failed\n"); break; } sdaddr = 0; @@ -2180,16 +1994,17 @@ brcmf_sdbrcm_membytes(struct brcmf_bus *bus, bool write, u32 address, u8 *data, xfer_done: /* Return the window to backplane enumeration space for core access */ if (brcmf_sdbrcm_set_siaddr_window(bus, - brcmf_sdcard_cur_sbwad(bus->card))) { - BRCMF_ERROR(("%s: FAILED to set window back to 0x%x\n", - __func__, brcmf_sdcard_cur_sbwad(bus->card))); - } + brcmf_sdcard_cur_sbwad( + bus->sdiodev))) + brcmf_dbg(ERROR, "FAILED to set window back to 0x%x\n", + brcmf_sdcard_cur_sbwad(bus->sdiodev)); return bcmerror; } #ifdef BCMDBG -static int brcmf_sdbrcm_readshared(struct brcmf_bus *bus, struct sdpcm_shared *sh) +static int +brcmf_sdbrcm_readshared(struct brcmf_bus *bus, struct sdpcm_shared *sh) { u32 addr; int rv; @@ -2203,15 +2018,15 @@ static int brcmf_sdbrcm_readshared(struct brcmf_bus *bus, struct sdpcm_shared *s addr = le32_to_cpu(addr); - BRCMF_INFO(("sdpcm_shared address 0x%08X\n", addr)); + brcmf_dbg(INFO, "sdpcm_shared address 0x%08X\n", addr); /* * Check if addr is valid. * NVRAM length at the end of memory should have been overwritten. */ if (addr == 0 || ((~addr >> 16) & 0xffff) == (addr & 0xffff)) { - BRCMF_ERROR(("%s: address (0x%08x) of sdpcm_shared invalid\n", - __func__, addr)); + brcmf_dbg(ERROR, "address (0x%08x) of sdpcm_shared invalid\n", + addr); return -EBADE; } @@ -2231,10 +2046,9 @@ static int brcmf_sdbrcm_readshared(struct brcmf_bus *bus, struct sdpcm_shared *s sh->msgtrace_addr = le32_to_cpu(sh->msgtrace_addr); if ((sh->flags & SDPCM_SHARED_VERSION_MASK) != SDPCM_SHARED_VERSION) { - BRCMF_ERROR(("%s: sdpcm_shared version %d in brcmf " - "is different than sdpcm_shared version %d in dongle\n", - __func__, SDPCM_SHARED_VERSION, - sh->flags & SDPCM_SHARED_VERSION_MASK)); + brcmf_dbg(ERROR, "sdpcm_shared version %d in brcmf is different than sdpcm_shared version %d in dongle\n", + SDPCM_SHARED_VERSION, + sh->flags & SDPCM_SHARED_VERSION_MASK); return -EBADE; } @@ -2252,7 +2066,7 @@ static int brcmf_sdbrcm_checkdied(struct brcmf_bus *bus, u8 *data, uint size) struct sdpcm_shared sdpcm_shared; struct brcmu_strbuf strbuf; - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); if (data == NULL) { /* @@ -2262,8 +2076,7 @@ static int brcmf_sdbrcm_checkdied(struct brcmf_bus *bus, u8 *data, uint size) size = msize; mbuffer = data = kmalloc(msize, GFP_ATOMIC); if (mbuffer == NULL) { - BRCMF_ERROR(("%s: kmalloc(%d) failed\n", __func__, - msize)); + brcmf_dbg(ERROR, "kmalloc(%d) failed\n", msize); bcmerror = -ENOMEM; goto done; } @@ -2271,7 +2084,7 @@ static int brcmf_sdbrcm_checkdied(struct brcmf_bus *bus, u8 *data, uint size) str = kmalloc(maxstrlen, GFP_ATOMIC); if (str == NULL) { - BRCMF_ERROR(("%s: kmalloc(%d) failed\n", __func__, maxstrlen)); + brcmf_dbg(ERROR, "kmalloc(%d) failed\n", maxstrlen); bcmerror = -ENOMEM; goto done; } @@ -2286,13 +2099,12 @@ static int brcmf_sdbrcm_checkdied(struct brcmf_bus *bus, u8 *data, uint size) "msgtrace address : 0x%08X\nconsole address : 0x%08X\n", sdpcm_shared.msgtrace_addr, sdpcm_shared.console_addr); - if ((sdpcm_shared.flags & SDPCM_SHARED_ASSERT_BUILT) == 0) { + if ((sdpcm_shared.flags & SDPCM_SHARED_ASSERT_BUILT) == 0) /* NOTE: Misspelled assert is intentional - DO NOT FIX. * (Avoids conflict with real asserts for programmatic * parsing of output.) */ brcmu_bprintf(&strbuf, "Assrt not built in dongle\n"); - } if ((sdpcm_shared.flags & (SDPCM_SHARED_ASSERT | SDPCM_SHARED_TRAP)) == 0) { @@ -2354,13 +2166,13 @@ static int brcmf_sdbrcm_checkdied(struct brcmf_bus *bus, u8 *data, uint size) } if (sdpcm_shared.flags & (SDPCM_SHARED_ASSERT | SDPCM_SHARED_TRAP)) - BRCMF_ERROR(("%s: %s\n", __func__, strbuf.origbuf)); + brcmf_dbg(ERROR, "%s\n", strbuf.origbuf); #ifdef BCMDBG - if (sdpcm_shared.flags & SDPCM_SHARED_TRAP) { + if (sdpcm_shared.flags & SDPCM_SHARED_TRAP) /* Mem dump to a file on device */ brcmf_sdbrcm_mem_dump(bus); - } + #endif /* BCMDBG */ done: @@ -2382,7 +2194,7 @@ static int brcmf_sdbrcm_mem_dump(struct brcmf_bus *bus) size = bus->ramsize; buf = kmalloc(size, GFP_ATOMIC); if (!buf) { - BRCMF_ERROR(("%s: Out of memory (%d bytes)\n", __func__, size)); + brcmf_dbg(ERROR, "Out of memory (%d bytes)\n", size); return -1; } @@ -2394,7 +2206,7 @@ static int brcmf_sdbrcm_mem_dump(struct brcmf_bus *bus) ret = brcmf_sdbrcm_membytes(bus, false, start, databuf, read_size); if (ret) { - BRCMF_ERROR(("%s: Error membytes %d\n", __func__, ret)); + brcmf_dbg(ERROR, "Error membytes %d\n", ret); kfree(buf); return -1; } @@ -2409,7 +2221,7 @@ static int brcmf_sdbrcm_mem_dump(struct brcmf_bus *bus) /* free buf before return !!! */ if (brcmf_write_to_file(bus->drvr, buf, bus->ramsize)) { - BRCMF_ERROR(("%s: Error writing to files\n", __func__)); + brcmf_dbg(ERROR, "Error writing to files\n"); return -1; } @@ -2500,7 +2312,7 @@ int brcmf_sdbrcm_downloadvars(struct brcmf_bus *bus, void *arg, int len) { int bcmerror = 0; - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); /* Basic sanity checks */ if (bus->drvr->up) { @@ -2529,18 +2341,17 @@ err: return bcmerror; } -static int -brcmf_sdbrcm_doiovar(struct brcmf_bus *bus, const struct brcmu_iovar *vi, u32 actionid, - const char *name, void *params, int plen, void *arg, int len, - int val_size) +static int brcmf_sdbrcm_doiovar(struct brcmf_bus *bus, + const struct brcmu_iovar *vi, u32 actionid, + const char *name, void *params, int plen, + void *arg, int len, int val_size) { int bcmerror = 0; s32 int_val = 0; bool bool_val = 0; - BRCMF_TRACE(("%s: Enter, action %d name %s params %p plen %d arg %p " - "len %d val_size %d\n", __func__, actionid, name, params, - plen, arg, len, val_size)); + brcmf_dbg(TRACE, "Enter, action %d name %s params %p plen %d arg %p len %d val_size %d\n", + actionid, name, params, plen, arg, len, val_size); bcmerror = brcmu_iovar_lencheck(vi, arg, len, IOV_ISSET(actionid)); if (bcmerror != 0) @@ -2586,16 +2397,6 @@ brcmf_sdbrcm_doiovar(struct brcmf_bus *bus, const struct brcmu_iovar *vi, u32 ac case IOV_SVAL(IOV_INTR): bus->intr = bool_val; - bus->intdis = false; - if (bus->drvr->up) { - BRCMF_INTR(("%s: %s SDIO interrupts\n", __func__, - bus->intr ? "enable" : "disable")); - if (bus->intr) { - brcmf_sdcard_intr_enable(bus->card); - } else { - brcmf_sdcard_intr_disable(bus->card); - } - } break; case IOV_GVAL(IOV_POLLRATE): @@ -2629,15 +2430,6 @@ brcmf_sdbrcm_doiovar(struct brcmf_bus *bus, const struct brcmu_iovar *vi, u32 ac bus->idleclock = int_val; break; - case IOV_GVAL(IOV_SD1IDLE): - int_val = (s32) sd1idle; - memcpy(arg, &int_val, val_size); - break; - - case IOV_SVAL(IOV_SD1IDLE): - sd1idle = bool_val; - break; - case IOV_SVAL(IOV_MEMBYTES): case IOV_GVAL(IOV_MEMBYTES): { @@ -2655,25 +2447,22 @@ brcmf_sdbrcm_doiovar(struct brcmf_bus *bus, const struct brcmu_iovar *vi, u32 ac /* Do some validation */ dsize = set ? plen - (2 * sizeof(int)) : len; if (dsize < size) { - BRCMF_ERROR(("%s: error on %s membytes, addr " - "0x%08x size %d dsize %d\n", - __func__, (set ? "set" : "get"), - address, size, dsize)); + brcmf_dbg(ERROR, "error on %s membytes, addr 0x%08x size %d dsize %d\n", + set ? "set" : "get", + address, size, dsize); bcmerror = -EINVAL; break; } - BRCMF_INFO(("%s: Request to %s %d bytes at address " - "0x%08x\n", __func__, - (set ? "write" : "read"), size, address)); + brcmf_dbg(INFO, "Request to %s %d bytes at address 0x%08x\n", + set ? "write" : "read", size, address); /* If we know about SOCRAM, check for a fit */ if ((bus->orig_ramsize) && ((address > bus->orig_ramsize) || (address + size > bus->orig_ramsize))) { - BRCMF_ERROR(("%s: ramsize 0x%08x doesn't have" - " %d bytes at 0x%08x\n", __func__, - bus->orig_ramsize, size, address)); + brcmf_dbg(ERROR, "ramsize 0x%08x doesn't have %d bytes at 0x%08x\n", + bus->orig_ramsize, size, address); bcmerror = -EINVAL; break; } @@ -2784,9 +2573,9 @@ brcmf_sdbrcm_doiovar(struct brcmf_bus *bus, const struct brcmu_iovar *vi, u32 ac addr = bus->ci->buscorebase + sd_ptr->offset; size = sd_ptr->func; - int_val = (s32) brcmf_sdcard_reg_read(bus->card, addr, - size); - if (brcmf_sdcard_regfail(bus->card)) + int_val = (s32) brcmf_sdcard_reg_read(bus->sdiodev, + addr, size); + if (brcmf_sdcard_regfail(bus->sdiodev)) bcmerror = -EIO; memcpy(arg, &int_val, sizeof(s32)); break; @@ -2801,9 +2590,9 @@ brcmf_sdbrcm_doiovar(struct brcmf_bus *bus, const struct brcmu_iovar *vi, u32 ac addr = bus->ci->buscorebase + sd_ptr->offset; size = sd_ptr->func; - brcmf_sdcard_reg_write(bus->card, addr, size, + brcmf_sdcard_reg_write(bus->sdiodev, addr, size, sd_ptr->value); - if (brcmf_sdcard_regfail(bus->card)) + if (brcmf_sdcard_regfail(bus->sdiodev)) bcmerror = -EIO; break; } @@ -2819,9 +2608,9 @@ brcmf_sdbrcm_doiovar(struct brcmf_bus *bus, const struct brcmu_iovar *vi, u32 ac addr = SI_ENUM_BASE + sdreg.offset; size = sdreg.func; - int_val = (s32) brcmf_sdcard_reg_read(bus->card, addr, - size); - if (brcmf_sdcard_regfail(bus->card)) + int_val = (s32) brcmf_sdcard_reg_read(bus->sdiodev, + addr, size); + if (brcmf_sdcard_regfail(bus->sdiodev)) bcmerror = -EIO; memcpy(arg, &int_val, sizeof(s32)); break; @@ -2836,9 +2625,9 @@ brcmf_sdbrcm_doiovar(struct brcmf_bus *bus, const struct brcmu_iovar *vi, u32 ac addr = SI_ENUM_BASE + sdreg.offset; size = sdreg.func; - brcmf_sdcard_reg_write(bus->card, addr, size, + brcmf_sdcard_reg_write(bus->sdiodev, addr, size, sdreg.value); - if (brcmf_sdcard_regfail(bus->card)) + if (brcmf_sdcard_regfail(bus->sdiodev)) bcmerror = -EIO; break; } @@ -2848,15 +2637,15 @@ brcmf_sdbrcm_doiovar(struct brcmf_bus *bus, const struct brcmu_iovar *vi, u32 ac *(char *)arg = 0; strcat(arg, "\nFunc 0\n"); - brcmf_sdcard_cis_read(bus->card, 0x10, + brcmf_sdcard_cis_read(bus->sdiodev, 0x10, (u8 *) arg + strlen(arg), SBSDIO_CIS_SIZE_LIMIT); strcat(arg, "\nFunc 1\n"); - brcmf_sdcard_cis_read(bus->card, 0x11, + brcmf_sdcard_cis_read(bus->sdiodev, 0x11, (u8 *) arg + strlen(arg), SBSDIO_CIS_SIZE_LIMIT); strcat(arg, "\nFunc 2\n"); - brcmf_sdcard_cis_read(bus->card, 0x12, + brcmf_sdcard_cis_read(bus->sdiodev, 0x12, (u8 *) arg + strlen(arg), SBSDIO_CIS_SIZE_LIMIT); break; @@ -2899,37 +2688,17 @@ brcmf_sdbrcm_doiovar(struct brcmf_bus *bus, const struct brcmu_iovar *vi, u32 ac break; #endif /* BCMDBG */ -#ifdef SDTEST - case IOV_GVAL(IOV_EXTLOOP): - int_val = (s32) bus->ext_loop; - memcpy(arg, &int_val, val_size); - break; - - case IOV_SVAL(IOV_EXTLOOP): - bus->ext_loop = bool_val; - break; - - case IOV_GVAL(IOV_PKTGEN): - bcmerror = brcmf_sdbrcm_pktgen_get(bus, arg); - break; - - case IOV_SVAL(IOV_PKTGEN): - bcmerror = brcmf_sdbrcm_pktgen_set(bus, arg); - break; -#endif /* SDTEST */ - case IOV_SVAL(IOV_DEVRESET): - BRCMF_TRACE(("%s: Called set IOV_DEVRESET=%d dongle_reset=%d " - "busstate=%d\n", - __func__, bool_val, bus->drvr->dongle_reset, - bus->drvr->busstate)); + brcmf_dbg(TRACE, "Called set IOV_DEVRESET=%d dongle_reset=%d busstate=%d\n", + bool_val, bus->drvr->dongle_reset, + bus->drvr->busstate); brcmf_bus_devreset(bus->drvr, (u8) bool_val); break; case IOV_GVAL(IOV_DEVRESET): - BRCMF_TRACE(("%s: Called get IOV_DEVRESET\n", __func__)); + brcmf_dbg(TRACE, "Called get IOV_DEVRESET\n"); /* Get its status */ int_val = (bool) bus->drvr->dongle_reset; @@ -2950,6 +2719,20 @@ brcmf_sdbrcm_doiovar(struct brcmf_bus *bus, const struct brcmu_iovar *vi, u32 ac brcmf_sdbrcm_wd_timer(bus, (uint) int_val); break; + case IOV_GVAL(IOV_IOCTLTIMEOUT):{ + int_val = brcmf_ioctl_timeout_msec; + memcpy(arg, &int_val, sizeof(int_val)); + break; + } + + case IOV_SVAL(IOV_IOCTLTIMEOUT):{ + if (int_val <= 0) + bcmerror = -EINVAL; + else + brcmf_ioctl_timeout_msec = int_val; + break; + } + default: bcmerror = -ENOTSUPP; break; @@ -2997,7 +2780,7 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_bus *bus) brcmf_sdbrcm_membytes(bus, true, varaddr, vbuffer, varsize); #ifdef BCMDBG /* Verify NVRAM bytes */ - BRCMF_INFO(("Compare NVRAM dl & ul; varsize=%d\n", varsize)); + brcmf_dbg(INFO, "Compare NVRAM dl & ul; varsize=%d\n", varsize); nvram_ularray = kmalloc(varsize, GFP_ATOMIC); if (!nvram_ularray) return -ENOMEM; @@ -3010,17 +2793,14 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_bus *bus) brcmf_sdbrcm_membytes(bus, false, varaddr, nvram_ularray, varsize); if (bcmerror) { - BRCMF_ERROR(("%s: error %d on reading %d nvram bytes" - " at 0x%08x\n", __func__, bcmerror, - varsize, varaddr)); + brcmf_dbg(ERROR, "error %d on reading %d nvram bytes at 0x%08x\n", + bcmerror, varsize, varaddr); } /* Compare the org NVRAM with the one read from RAM */ - if (memcmp(vbuffer, nvram_ularray, varsize)) { - BRCMF_ERROR(("%s: Downloaded NVRAM image is " - "corrupted.\n", __func__)); - } else - BRCMF_ERROR(("%s: Download/Upload/Compare of" - " NVRAM ok.\n", __func__)); + if (memcmp(vbuffer, nvram_ularray, varsize)) + brcmf_dbg(ERROR, "Downloaded NVRAM image is corrupted\n"); + else + brcmf_dbg(ERROR, "Download/Upload/Compare of NVRAM ok\n"); kfree(nvram_ularray); #endif /* BCMDBG */ @@ -3029,9 +2809,10 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_bus *bus) } /* adjust to the user specified RAM */ - BRCMF_INFO(("Physical memory size: %d, usable memory size: %d\n", - bus->orig_ramsize, bus->ramsize)); - BRCMF_INFO(("Vars are at %d, orig varsize is %d\n", varaddr, varsize)); + brcmf_dbg(INFO, "Physical memory size: %d, usable memory size: %d\n", + bus->orig_ramsize, bus->ramsize); + brcmf_dbg(INFO, "Vars are at %d, orig varsize is %d\n", + varaddr, varsize); varsize = ((bus->orig_ramsize - 4) - varaddr); /* @@ -3047,8 +2828,8 @@ static int brcmf_sdbrcm_write_vars(struct brcmf_bus *bus) varsizew = cpu_to_le32(varsizew); } - BRCMF_INFO(("New varsize is %d, length token=0x%08x\n", varsize, - varsizew)); + brcmf_dbg(INFO, "New varsize is %d, length token=0x%08x\n", + varsize, varsizew); /* Write the length token to the last word */ bcmerror = brcmf_sdbrcm_membytes(bus, true, (bus->orig_ramsize - 4), @@ -3069,9 +2850,10 @@ static int brcmf_sdbrcm_download_state(struct brcmf_bus *bus, bool enter) if (enter) { bus->alp_only = true; - brcmf_sdbrcm_chip_disablecore(bus->card, bus->ci->armcorebase); + brcmf_sdbrcm_chip_disablecore(bus->sdiodev, + bus->ci->armcorebase); - brcmf_sdbrcm_chip_resetcore(bus->card, bus->ci->ramcorebase); + brcmf_sdbrcm_chip_resetcore(bus->sdiodev, bus->ci->ramcorebase); /* Clear the top bit of memory */ if (bus->ramsize) { @@ -3080,27 +2862,26 @@ static int brcmf_sdbrcm_download_state(struct brcmf_bus *bus, bool enter) (u8 *)&zeros, 4); } } else { - regdata = brcmf_sdcard_reg_read(bus->card, + regdata = brcmf_sdcard_reg_read(bus->sdiodev, CORE_SB(bus->ci->ramcorebase, sbtmstatelow), 4); regdata &= (SBTML_RESET | SBTML_REJ_MASK | (SICF_CLOCK_EN << SBTML_SICF_SHIFT)); if ((SICF_CLOCK_EN << SBTML_SICF_SHIFT) != regdata) { - BRCMF_ERROR(("%s: SOCRAM core is down after reset?\n", - __func__)); + brcmf_dbg(ERROR, "SOCRAM core is down after reset?\n"); bcmerror = -EBADE; goto fail; } bcmerror = brcmf_sdbrcm_write_vars(bus); if (bcmerror) { - BRCMF_ERROR(("%s: no vars written to RAM\n", __func__)); + brcmf_dbg(ERROR, "no vars written to RAM\n"); bcmerror = 0; } w_sdreg32(bus, 0xFFFFFFFF, offsetof(struct sdpcmd_regs, intstatus), &retries); - brcmf_sdbrcm_chip_resetcore(bus->card, bus->ci->armcorebase); + brcmf_sdbrcm_chip_resetcore(bus->sdiodev, bus->ci->armcorebase); /* Allow HT Clock now that the ARM is running. */ bus->alp_only = false; @@ -3121,9 +2902,9 @@ brcmf_sdbrcm_bus_iovar_op(struct brcmf_pub *drvr, const char *name, int val_size; u32 actionid; - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); - if (name == NULL || len <= 0) + if (name == NULL || len < 0) return -EINVAL; /* Set does not take qualifiers */ @@ -3144,26 +2925,8 @@ brcmf_sdbrcm_bus_iovar_op(struct brcmf_pub *drvr, const char *name, /* Turn on clock in case SD command needs backplane */ brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); - bcmerror = brcmf_sdcard_iovar_op(bus->card, name, params, plen, - arg, len, set); - - /* Similar check for blocksize change */ - if (set && strcmp(name, "sd_blocksize") == 0) { - s32 fnum = 2; - if (brcmf_sdcard_iovar_op - (bus->card, "sd_blocksize", &fnum, sizeof(s32), - &bus->blocksize, sizeof(s32), - false) != 0) { - bus->blocksize = 0; - BRCMF_ERROR(("%s: fail on %s get\n", __func__, - "sd_blocksize")); - } else { - BRCMF_INFO(("%s: noted sd_blocksize update," - " value now %d\n", __func__, - bus->blocksize)); - } - } - bus->roundup = min(max_roundup, bus->blocksize); + bcmerror = brcmf_sdcard_iovar_op(bus->sdiodev, name, params, + plen, arg, len, set); if (bus->idletime == BRCMF_IDLE_IMMEDIATE && !bus->dpc_sched) { @@ -3175,8 +2938,8 @@ brcmf_sdbrcm_bus_iovar_op(struct brcmf_pub *drvr, const char *name, goto exit; } - BRCMF_CTL(("%s: %s %s, len %d plen %d\n", __func__, - name, (set ? "set" : "get"), len, plen)); + brcmf_dbg(CTL, "%s %s, len %d plen %d\n", + name, set ? "set" : "get", len, plen); /* set up 'params' pointer in case this is a set command so that * the convenience int and bool code can be common to set and get @@ -3209,7 +2972,7 @@ void brcmf_sdbrcm_bus_stop(struct brcmf_bus *bus, bool enforce_mutex) uint retries; int err; - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); if (enforce_mutex) brcmf_sdbrcm_sdlock(bus); @@ -3241,22 +3004,19 @@ void brcmf_sdbrcm_bus_stop(struct brcmf_bus *bus, bool enforce_mutex) bus->drvr->busstate = BRCMF_BUS_DOWN; /* Force clocks on backplane to be sure F2 interrupt propagates */ - saveclk = brcmf_sdcard_cfg_read(bus->card, SDIO_FUNC_1, + saveclk = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err); if (!err) { - brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_1, + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, (saveclk | SBSDIO_FORCE_HT), &err); } - if (err) { - BRCMF_ERROR(("%s: Failed to force clock for F2: err %d\n", - __func__, err)); - } + if (err) + brcmf_dbg(ERROR, "Failed to force clock for F2: err %d\n", err); /* Turn off the bus (F2), free any pending packets */ - BRCMF_INTR(("%s: disable SDIO interrupts\n", __func__)); - brcmf_sdcard_intr_disable(bus->card); - brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_0, SDIO_CCCR_IOEx, + brcmf_dbg(INTR, "disable SDIO interrupts\n"); + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_0, SDIO_CCCR_IOEx, SDIO_FUNC_ENABLE_1, NULL); /* Clear any pending interrupts now that F2 is disabled */ @@ -3280,7 +3040,7 @@ void brcmf_sdbrcm_bus_stop(struct brcmf_bus *bus, bool enforce_mutex) /* Clear rx control and wake any waiters */ bus->rxlen = 0; - brcmf_os_ioctl_resp_wake(bus->drvr); + brcmf_sdbrcm_ioctl_resp_wake(bus); /* Reset some F2 state stuff */ bus->rxskip = false; @@ -3293,17 +3053,17 @@ void brcmf_sdbrcm_bus_stop(struct brcmf_bus *bus, bool enforce_mutex) int brcmf_sdbrcm_bus_init(struct brcmf_pub *drvr, bool enforce_mutex) { struct brcmf_bus *bus = drvr->bus; - struct brcmf_timeout tmo; + unsigned long timeout; uint retries = 0; u8 ready, enable; int err, ret = 0; u8 saveclk; - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); /* try to download image and nvram to the dongle */ if (drvr->busstate == BRCMF_BUS_DOWN) { - if (!(brcmf_sdbrcm_download_firmware(bus, bus->card))) + if (!(brcmf_sdbrcm_download_firmware(bus))) return -1; } @@ -3324,16 +3084,15 @@ int brcmf_sdbrcm_bus_init(struct brcmf_pub *drvr, bool enforce_mutex) /* Force clocks on backplane to be sure F2 interrupt propagates */ saveclk = - brcmf_sdcard_cfg_read(bus->card, SDIO_FUNC_1, + brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err); if (!err) { - brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_1, + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, (saveclk | SBSDIO_FORCE_HT), &err); } if (err) { - BRCMF_ERROR(("%s: Failed to force clock for F2: err %d\n", - __func__, err)); + brcmf_dbg(ERROR, "Failed to force clock for F2: err %d\n", err); goto exit; } @@ -3342,19 +3101,22 @@ int brcmf_sdbrcm_bus_init(struct brcmf_pub *drvr, bool enforce_mutex) offsetof(struct sdpcmd_regs, tosbmailboxdata), &retries); enable = (SDIO_FUNC_ENABLE_1 | SDIO_FUNC_ENABLE_2); - brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_0, SDIO_CCCR_IOEx, enable, - NULL); - - /* Give the dongle some time to do its thing and set IOR2 */ - brcmf_timeout_start(&tmo, BRCMF_WAIT_F2RDY * 1000); + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_0, SDIO_CCCR_IOEx, + enable, NULL); + timeout = jiffies + msecs_to_jiffies(BRCMF_WAIT_F2RDY); ready = 0; - while (ready != enable && !brcmf_timeout_expired(&tmo)) - ready = brcmf_sdcard_cfg_read(bus->card, SDIO_FUNC_0, + while (enable != ready) { + ready = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_0, SDIO_CCCR_IORx, NULL); + if (time_after(jiffies, timeout)) + break; + else if (time_after(jiffies, timeout - BRCMF_WAIT_F2RDY + 50)) + /* prevent busy waiting if it takes too long */ + msleep_interruptible(20); + } - BRCMF_INFO(("%s: enable 0x%02x, ready 0x%02x (waited %uus)\n", - __func__, enable, ready, tmo.elapsed)); + brcmf_dbg(INFO, "enable 0x%02x, ready 0x%02x\n", enable, ready); /* If F2 successfully enabled, set core and enable interrupts */ if (ready == enable) { @@ -3363,48 +3125,23 @@ int brcmf_sdbrcm_bus_init(struct brcmf_pub *drvr, bool enforce_mutex) w_sdreg32(bus, bus->hostintmask, offsetof(struct sdpcmd_regs, hostintmask), &retries); - brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_1, SBSDIO_WATERMARK, - (u8) watermark, &err); + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, + SBSDIO_WATERMARK, 8, &err); /* Set bus state according to enable result */ drvr->busstate = BRCMF_BUS_DATA; - - bus->intdis = false; - if (bus->intr) { - BRCMF_INTR(("%s: enable SDIO device interrupts\n", - __func__)); - brcmf_sdcard_intr_enable(bus->card); - } else { - BRCMF_INTR(("%s: disable SDIO interrupts\n", __func__)); - brcmf_sdcard_intr_disable(bus->card); - } - } else { /* Disable F2 again */ enable = SDIO_FUNC_ENABLE_1; - brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_0, SDIO_CCCR_IOEx, - enable, NULL); + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_0, + SDIO_CCCR_IOEx, enable, NULL); } /* Restore previous clock setting */ - brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, - saveclk, &err); - -#if defined(OOB_INTR_ONLY) - /* Host registration for OOB interrupt */ - if (brcmf_sdio_register_oob_intr(bus->dhd)) { - brcmf_sdbrcm_wd_timer(bus, 0); - BRCMF_ERROR(("%s Host failed to resgister for OOB\n", - __func__)); - ret = -ENODEV; - goto exit; - } - - /* Enable oob at firmware */ - brcmf_sdbrcm_enable_oob_intr(bus, true); -#endif /* defined(OOB_INTR_ONLY) */ + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, saveclk, &err); /* If we didn't come up, turn off backplane clock */ if (drvr->busstate != BRCMF_BUS_DATA) @@ -3419,28 +3156,28 @@ exit: static void brcmf_sdbrcm_rxfail(struct brcmf_bus *bus, bool abort, bool rtx) { - struct brcmf_sdio_card *card = bus->card; uint retries = 0; u16 lastrbc; u8 hi, lo; int err; - BRCMF_ERROR(("%s: %sterminate frame%s\n", __func__, - (abort ? "abort command, " : ""), - (rtx ? ", send NAK" : ""))); + brcmf_dbg(ERROR, "%sterminate frame%s\n", + abort ? "abort command, " : "", + rtx ? ", send NAK" : ""); if (abort) - brcmf_sdcard_abort(card, SDIO_FUNC_2); + brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2); - brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, SBSDIO_FUNC1_FRAMECTRL, + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, + SBSDIO_FUNC1_FRAMECTRL, SFC_RF_TERM, &err); bus->f1regdata++; /* Wait until the packet has been flushed (device/FIFO stable) */ for (lastrbc = retries = 0xffff; retries > 0; retries--) { - hi = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1, + hi = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, SBSDIO_FUNC1_RFRAMEBCHI, NULL); - lo = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1, + lo = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, SBSDIO_FUNC1_RFRAMEBCLO, NULL); bus->f1regdata += 2; @@ -3448,20 +3185,16 @@ static void brcmf_sdbrcm_rxfail(struct brcmf_bus *bus, bool abort, bool rtx) break; if ((hi > (lastrbc >> 8)) && (lo > (lastrbc & 0x00ff))) { - BRCMF_ERROR(("%s: count growing: last 0x%04x now " - "0x%04x\n", - __func__, lastrbc, ((hi << 8) + lo))); + brcmf_dbg(ERROR, "count growing: last 0x%04x now 0x%04x\n", + lastrbc, (hi << 8) + lo); } lastrbc = (hi << 8) + lo; } - if (!retries) { - BRCMF_ERROR(("%s: count never zeroed: last 0x%04x\n", - __func__, lastrbc)); - } else { - BRCMF_INFO(("%s: flush took %d iterations\n", __func__, - (0xffff - retries))); - } + if (!retries) + brcmf_dbg(ERROR, "count never zeroed: last 0x%04x\n", lastrbc); + else + brcmf_dbg(INFO, "flush took %d iterations\n", 0xffff - retries); if (rtx) { bus->rxrtx++; @@ -3477,23 +3210,18 @@ static void brcmf_sdbrcm_rxfail(struct brcmf_bus *bus, bool abort, bool rtx) bus->nextlen = 0; /* If we can't reach the device, signal failure */ - if (err || brcmf_sdcard_regfail(card)) + if (err || brcmf_sdcard_regfail(bus->sdiodev)) bus->drvr->busstate = BRCMF_BUS_DOWN; } static void brcmf_sdbrcm_read_control(struct brcmf_bus *bus, u8 *hdr, uint len, uint doff) { - struct brcmf_sdio_card *card = bus->card; uint rdlen, pad; int sdret; - BRCMF_TRACE(("%s: Enter\n", __func__)); - - /* Control data already received in aligned rxctl */ - if ((bus->bus == SPI_BUS) && (!bus->usebufpool)) - goto gotpkt; + brcmf_dbg(TRACE, "Enter\n"); /* Set rxctl for frame (w/optional alignment) */ bus->rxctl = bus->rxbuf; @@ -3510,12 +3238,6 @@ brcmf_sdbrcm_read_control(struct brcmf_bus *bus, u8 *hdr, uint len, uint doff) if (len <= firstread) goto gotpkt; - /* Copy the full data pkt in gSPI case and process ioctl. */ - if (bus->bus == SPI_BUS) { - memcpy(bus->rxctl, hdr, len); - goto gotpkt; - } - /* Raise rdlen to next SDIO block to avoid tail command */ rdlen = len - firstread; if (bus->roundup && bus->blocksize && (rdlen > bus->blocksize)) { @@ -3533,17 +3255,16 @@ brcmf_sdbrcm_read_control(struct brcmf_bus *bus, u8 *hdr, uint len, uint doff) /* Drop if the read is too big or it exceeds our maximum */ if ((rdlen + firstread) > bus->drvr->maxctl) { - BRCMF_ERROR(("%s: %d-byte control read exceeds %d-byte" - " buffer\n", __func__, rdlen, bus->drvr->maxctl)); + brcmf_dbg(ERROR, "%d-byte control read exceeds %d-byte buffer\n", + rdlen, bus->drvr->maxctl); bus->drvr->rx_errors++; brcmf_sdbrcm_rxfail(bus, false, false); goto done; } if ((len - doff) > bus->drvr->maxctl) { - BRCMF_ERROR(("%s: %d-byte ctl frame (%d-byte ctl data) exceeds " - "%d-byte limit\n", - __func__, len, (len - doff), bus->drvr->maxctl)); + brcmf_dbg(ERROR, "%d-byte ctl frame (%d-byte ctl data) exceeds %d-byte limit\n", + len, len - doff, bus->drvr->maxctl); bus->drvr->rx_errors++; bus->rx_toolong++; brcmf_sdbrcm_rxfail(bus, false, false); @@ -3551,16 +3272,17 @@ brcmf_sdbrcm_read_control(struct brcmf_bus *bus, u8 *hdr, uint len, uint doff) } /* Read remainder of frame body into the rxctl buffer */ - sdret = brcmf_sdcard_recv_buf(card, brcmf_sdcard_cur_sbwad(card), + sdret = brcmf_sdcard_recv_buf(bus->sdiodev, + brcmf_sdcard_cur_sbwad(bus->sdiodev), SDIO_FUNC_2, F2SYNC, (bus->rxctl + firstread), rdlen, - NULL, NULL, NULL); + NULL); bus->f2rxdata++; /* Control frame failures need retransmission */ if (sdret < 0) { - BRCMF_ERROR(("%s: read %d control bytes failed: %d\n", - __func__, rdlen, sdret)); + brcmf_dbg(ERROR, "read %d control bytes failed: %d\n", + rdlen, sdret); bus->rxc_errors++; brcmf_sdbrcm_rxfail(bus, true, true); goto done; @@ -3581,7 +3303,7 @@ gotpkt: done: /* Awake any waiters */ - brcmf_os_ioctl_resp_wake(bus->drvr); + brcmf_sdbrcm_ioctl_resp_wake(bus); } static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) @@ -3602,8 +3324,7 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) /* If packets, issue read(s) and send up packet chain */ /* Return sequence numbers consumed? */ - BRCMF_TRACE(("brcmf_sdbrcm_rxglom: start: glomd %p glom %p\n", - bus->glomd, bus->glom)); + brcmf_dbg(TRACE, "start: glomd %p glom %p\n", bus->glomd, bus->glom); /* If there's a descriptor, generate the packet chain */ if (bus->glomd) { @@ -3611,9 +3332,8 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) dlen = (u16) (bus->glomd->len); dptr = bus->glomd->data; if (!dlen || (dlen & 1)) { - BRCMF_ERROR(("%s: bad glomd len(%d)," - " ignore descriptor\n", - __func__, dlen)); + brcmf_dbg(ERROR, "bad glomd len(%d), ignore descriptor\n", + dlen); dlen = 0; } @@ -3624,15 +3344,14 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) dptr += sizeof(u16); if ((sublen < SDPCM_HDRLEN) || ((num == 0) && (sublen < (2 * SDPCM_HDRLEN)))) { - BRCMF_ERROR(("%s: descriptor len %d bad: %d\n", - __func__, num, sublen)); + brcmf_dbg(ERROR, "descriptor len %d bad: %d\n", + num, sublen); pnext = NULL; break; } if (sublen % BRCMF_SDALIGN) { - BRCMF_ERROR(("%s: sublen %d not multiple of" - " %d\n", __func__, sublen, - BRCMF_SDALIGN)); + brcmf_dbg(ERROR, "sublen %d not multiple of %d\n", + sublen, BRCMF_SDALIGN); usechain = false; } totlen += sublen; @@ -3648,9 +3367,8 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) /* Allocate/chain packet for next subframe */ pnext = brcmu_pkt_buf_get_skb(sublen + BRCMF_SDALIGN); if (pnext == NULL) { - BRCMF_ERROR(("%s: bcm_pkt_buf_get_skb failed, " - "num %d len %d\n", __func__, - num, sublen)); + brcmf_dbg(ERROR, "bcm_pkt_buf_get_skb failed, num %d len %d\n", + num, sublen); break; } if (!pfirst) { @@ -3667,15 +3385,12 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) /* If all allocations succeeded, save packet chain in bus structure */ if (pnext) { - BRCMF_GLOM(("%s: allocated %d-byte packet chain for %d " - "subframes\n", __func__, totlen, num)); + brcmf_dbg(GLOM, "allocated %d-byte packet chain for %d subframes\n", + totlen, num); if (BRCMF_GLOM_ON() && bus->nextlen) { if (totlen != bus->nextlen) { - BRCMF_GLOM(("%s: glomdesc mismatch: " - "nextlen %d glomdesc %d " - "rxseq %d\n", __func__, - bus->nextlen, - totlen, rxseq)); + brcmf_dbg(GLOM, "glomdesc mismatch: nextlen %d glomdesc %d rxseq %d\n", + bus->nextlen, totlen, rxseq); } } bus->glom = pfirst; @@ -3697,12 +3412,11 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) or had one from before */ if (bus->glom) { if (BRCMF_GLOM_ON()) { - BRCMF_GLOM(("%s: try superframe read, packet chain:\n", - __func__)); + brcmf_dbg(GLOM, "try superframe read, packet chain:\n"); for (pnext = bus->glom; pnext; pnext = pnext->next) { - BRCMF_GLOM((" %p: %p len 0x%04x (%d)\n", - pnext, (u8 *) (pnext->data), - pnext->len, pnext->len)); + brcmf_dbg(GLOM, " %p: %p len 0x%04x (%d)\n", + pnext, (u8 *) (pnext->data), + pnext->len, pnext->len); } } @@ -3714,37 +3428,36 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) * packet and and copy into the chain. */ if (usechain) { - errcode = brcmf_sdcard_recv_buf(bus->card, - brcmf_sdcard_cur_sbwad(bus->card), + errcode = brcmf_sdcard_recv_buf(bus->sdiodev, + brcmf_sdcard_cur_sbwad(bus->sdiodev), SDIO_FUNC_2, F2SYNC, (u8 *) pfirst->data, dlen, - pfirst, NULL, NULL); + pfirst); } else if (bus->dataptr) { - errcode = brcmf_sdcard_recv_buf(bus->card, - brcmf_sdcard_cur_sbwad(bus->card), + errcode = brcmf_sdcard_recv_buf(bus->sdiodev, + brcmf_sdcard_cur_sbwad(bus->sdiodev), SDIO_FUNC_2, F2SYNC, bus->dataptr, dlen, - NULL, NULL, NULL); + NULL); sublen = (u16) brcmu_pktfrombuf(pfirst, 0, dlen, bus->dataptr); if (sublen != dlen) { - BRCMF_ERROR(("%s: FAILED TO COPY, dlen %d " - "sublen %d\n", - __func__, dlen, sublen)); + brcmf_dbg(ERROR, "FAILED TO COPY, dlen %d sublen %d\n", + dlen, sublen); errcode = -1; } pnext = NULL; } else { - BRCMF_ERROR(("COULDN'T ALLOC %d-BYTE GLOM, " - "FORCE FAILURE\n", dlen)); + brcmf_dbg(ERROR, "COULDN'T ALLOC %d-BYTE GLOM, FORCE FAILURE\n", + dlen); errcode = -1; } bus->f2rxdata++; /* On failure, kill the superframe, allow a couple retries */ if (errcode < 0) { - BRCMF_ERROR(("%s: glom read of %d bytes failed: %d\n", - __func__, dlen, errcode)); + brcmf_dbg(ERROR, "glom read of %d bytes failed: %d\n", + dlen, errcode); bus->drvr->rx_errors++; if (bus->glomerr++ < 3) { @@ -3775,8 +3488,8 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]); bus->nextlen = dptr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET]; if ((bus->nextlen << 4) > MAX_RX_DATASZ) { - BRCMF_INFO(("%s: nextlen too large (%d) seq %d\n", - __func__, bus->nextlen, seq)); + brcmf_dbg(INFO, "nextlen too large (%d) seq %d\n", + bus->nextlen, seq); bus->nextlen = 0; } doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); @@ -3784,48 +3497,42 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) errcode = 0; if ((u16)~(sublen ^ check)) { - BRCMF_ERROR(("%s (superframe): HW hdr error: len/check " - "0x%04x/0x%04x\n", __func__, sublen, - check)); + brcmf_dbg(ERROR, "(superframe): HW hdr error: len/check 0x%04x/0x%04x\n", + sublen, check); errcode = -1; } else if (roundup(sublen, bus->blocksize) != dlen) { - BRCMF_ERROR(("%s (superframe): len 0x%04x, rounded " - "0x%04x, expect 0x%04x\n", - __func__, sublen, - roundup(sublen, bus->blocksize), dlen)); + brcmf_dbg(ERROR, "(superframe): len 0x%04x, rounded 0x%04x, expect 0x%04x\n", + sublen, roundup(sublen, bus->blocksize), + dlen); errcode = -1; } else if (SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]) != SDPCM_GLOM_CHANNEL) { - BRCMF_ERROR(("%s (superframe): bad channel %d\n", - __func__, - SDPCM_PACKET_CHANNEL(&dptr - [SDPCM_FRAMETAG_LEN]))); + brcmf_dbg(ERROR, "(superframe): bad channel %d\n", + SDPCM_PACKET_CHANNEL( + &dptr[SDPCM_FRAMETAG_LEN])); errcode = -1; } else if (SDPCM_GLOMDESC(&dptr[SDPCM_FRAMETAG_LEN])) { - BRCMF_ERROR(("%s (superframe): got 2nd descriptor?\n", - __func__)); + brcmf_dbg(ERROR, "(superframe): got 2nd descriptor?\n"); errcode = -1; } else if ((doff < SDPCM_HDRLEN) || (doff > (pfirst->len - SDPCM_HDRLEN))) { - BRCMF_ERROR(("%s (superframe): Bad data offset %d: " - "HW %d pkt %d min %d\n", - __func__, doff, sublen, - pfirst->len, SDPCM_HDRLEN)); + brcmf_dbg(ERROR, "(superframe): Bad data offset %d: HW %d pkt %d min %d\n", + doff, sublen, pfirst->len, SDPCM_HDRLEN); errcode = -1; } /* Check sequence number of superframe SW header */ if (rxseq != seq) { - BRCMF_INFO(("%s: (superframe) rx_seq %d, expected %d\n", - __func__, seq, rxseq)); + brcmf_dbg(INFO, "(superframe) rx_seq %d, expected %d\n", + seq, rxseq); bus->rx_badseq++; rxseq = seq; } /* Check window for sanity */ if ((u8) (txmax - bus->tx_seq) > 0x40) { - BRCMF_ERROR(("%s: unlikely tx max %d with tx_seq %d\n", - __func__, txmax, bus->tx_seq)); + brcmf_dbg(ERROR, "unlikely tx max %d with tx_seq %d\n", + txmax, bus->tx_seq); txmax = bus->tx_seq + 2; } bus->tx_max = txmax; @@ -3852,25 +3559,21 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) #endif if ((u16)~(sublen ^ check)) { - BRCMF_ERROR(("%s (subframe %d): HW hdr error: " - "len/check 0x%04x/0x%04x\n", - __func__, num, sublen, check)); + brcmf_dbg(ERROR, "(subframe %d): HW hdr error: len/check 0x%04x/0x%04x\n", + num, sublen, check); errcode = -1; } else if ((sublen > dlen) || (sublen < SDPCM_HDRLEN)) { - BRCMF_ERROR(("%s (subframe %d): length mismatch" - ": len 0x%04x, expect 0x%04x\n", - __func__, num, sublen, dlen)); + brcmf_dbg(ERROR, "(subframe %d): length mismatch: len 0x%04x, expect 0x%04x\n", + num, sublen, dlen); errcode = -1; } else if ((chan != SDPCM_DATA_CHANNEL) && (chan != SDPCM_EVENT_CHANNEL)) { - BRCMF_ERROR(("%s (subframe %d): bad channel" - " %d\n", __func__, num, chan)); + brcmf_dbg(ERROR, "(subframe %d): bad channel %d\n", + num, chan); errcode = -1; } else if ((doff < SDPCM_HDRLEN) || (doff > sublen)) { - BRCMF_ERROR(("%s (subframe %d): Bad data offset" - " %d: HW %d min %d\n", - __func__, num, doff, sublen, - SDPCM_HDRLEN)); + brcmf_dbg(ERROR, "(subframe %d): Bad data offset %d: HW %d min %d\n", + num, doff, sublen, SDPCM_HDRLEN); errcode = -1; } } @@ -3908,17 +3611,16 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]); doff = SDPCM_DOFFSET_VALUE(&dptr[SDPCM_FRAMETAG_LEN]); - BRCMF_GLOM(("%s: Get subframe %d, %p(%p/%d), sublen %d " - "chan %d seq %d\n", - __func__, num, pfirst, pfirst->data, - pfirst->len, sublen, chan, seq)); + brcmf_dbg(GLOM, "Get subframe %d, %p(%p/%d), sublen %d chan %d seq %d\n", + num, pfirst, pfirst->data, + pfirst->len, sublen, chan, seq); /* precondition: chan == SDPCM_DATA_CHANNEL || chan == SDPCM_EVENT_CHANNEL */ if (rxseq != seq) { - BRCMF_GLOM(("%s: rx_seq %d, expected %d\n", - __func__, seq, rxseq)); + brcmf_dbg(GLOM, "rx_seq %d, expected %d\n", + seq, rxseq); bus->rx_badseq++; rxseq = seq; } @@ -3935,23 +3637,22 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) if (pfirst->len == 0) { brcmu_pkt_buf_free_skb(pfirst); - if (plast) { + if (plast) plast->next = pnext; - } else { + else save_pfirst = pnext; - } + continue; - } else if (brcmf_proto_hdrpull(bus->drvr, &ifidx, pfirst) - != 0) { - BRCMF_ERROR(("%s: rx protocol error\n", - __func__)); + } else if (brcmf_proto_hdrpull(bus->drvr, &ifidx, + pfirst) != 0) { + brcmf_dbg(ERROR, "rx protocol error\n"); bus->drvr->rx_errors++; brcmu_pkt_buf_free_skb(pfirst); - if (plast) { + if (plast) plast->next = pnext; - } else { + else save_pfirst = pnext; - } + continue; } @@ -3963,11 +3664,10 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) #ifdef BCMDBG if (BRCMF_GLOM_ON()) { - BRCMF_GLOM(("%s subframe %d to stack, %p" - "(%p/%d) nxt/lnk %p/%p\n", - __func__, num, pfirst, pfirst->data, - pfirst->len, pfirst->next, - pfirst->prev)); + brcmf_dbg(GLOM, "subframe %d to stack, %p (%p/%d) nxt/lnk %p/%p\n", + num, pfirst, pfirst->data, + pfirst->len, pfirst->next, + pfirst->prev); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, pfirst->data, min_t(int, pfirst->len, 32)); @@ -3990,8 +3690,6 @@ static u8 brcmf_sdbrcm_rxglom(struct brcmf_bus *bus, u8 rxseq) static uint brcmf_sdbrcm_readframes(struct brcmf_bus *bus, uint maxframes, bool *finished) { - struct brcmf_sdio_card *card = bus->card; - u16 len, check; /* Extracted hardware header fields */ u8 chan, seq, doff; /* Extracted software header fields */ u8 fcbits; /* Extracted fcbits from software header */ @@ -4009,19 +3707,7 @@ brcmf_sdbrcm_readframes(struct brcmf_bus *bus, uint maxframes, bool *finished) int ifidx = 0; uint rxcount = 0; /* Total frames read */ -#if defined(BCMDBG) || defined(SDTEST) - bool sdtest = false; /* To limit message spew from test mode */ -#endif - - BRCMF_TRACE(("%s: Enter\n", __func__)); - -#ifdef SDTEST - /* Allow pktgen to override maxframes */ - if (bus->pktgen_count && (bus->pktgen_mode == BRCMF_PKTGEN_RECV)) { - maxframes = bus->pktgen_count; - sdtest = true; - } -#endif + brcmf_dbg(TRACE, "Enter\n"); /* Not finished unless we encounter no more frames indication */ *finished = false; @@ -4033,10 +3719,10 @@ brcmf_sdbrcm_readframes(struct brcmf_bus *bus, uint maxframes, bool *finished) /* Handle glomming separately */ if (bus->glom || bus->glomd) { u8 cnt; - BRCMF_GLOM(("%s: calling rxglom: glomd %p, glom %p\n", - __func__, bus->glomd, bus->glom)); + brcmf_dbg(GLOM, "calling rxglom: glomd %p, glom %p\n", + bus->glomd, bus->glom); cnt = brcmf_sdbrcm_rxglom(bus, rxseq); - BRCMF_GLOM(("%s: rxglom returned %d\n", __func__, cnt)); + brcmf_dbg(GLOM, "rxglom returned %d\n", cnt); rxseq += cnt - 1; rxleft = (rxleft > cnt) ? (rxleft - cnt) : 1; continue; @@ -4047,26 +3733,22 @@ brcmf_sdbrcm_readframes(struct brcmf_bus *bus, uint maxframes, bool *finished) u16 nextlen = bus->nextlen; bus->nextlen = 0; - if (bus->bus == SPI_BUS) { - rdlen = len = nextlen; - } else { - rdlen = len = nextlen << 4; - - /* Pad read to blocksize for efficiency */ - if (bus->roundup && bus->blocksize - && (rdlen > bus->blocksize)) { - pad = - bus->blocksize - - (rdlen % bus->blocksize); - if ((pad <= bus->roundup) - && (pad < bus->blocksize) - && ((rdlen + pad + firstread) < - MAX_RX_DATASZ)) - rdlen += pad; - } else if (rdlen % BRCMF_SDALIGN) { - rdlen += - BRCMF_SDALIGN - (rdlen % BRCMF_SDALIGN); - } + rdlen = len = nextlen << 4; + + /* Pad read to blocksize for efficiency */ + if (bus->roundup && bus->blocksize + && (rdlen > bus->blocksize)) { + pad = + bus->blocksize - + (rdlen % bus->blocksize); + if ((pad <= bus->roundup) + && (pad < bus->blocksize) + && ((rdlen + pad + firstread) < + MAX_RX_DATASZ)) + rdlen += pad; + } else if (rdlen % BRCMF_SDALIGN) { + rdlen += BRCMF_SDALIGN - + (rdlen % BRCMF_SDALIGN); } /* We use bus->rxctl buffer in WinXP for initial @@ -4082,82 +3764,32 @@ brcmf_sdbrcm_readframes(struct brcmf_bus *bus, uint maxframes, bool *finished) /* Allocate a packet buffer */ pkt = brcmu_pkt_buf_get_skb(rdlen + BRCMF_SDALIGN); if (!pkt) { - if (bus->bus == SPI_BUS) { - bus->usebufpool = false; - bus->rxctl = bus->rxbuf; - if (brcmf_alignctl) { - bus->rxctl += firstread; - pad = ((unsigned long)bus->rxctl % - BRCMF_SDALIGN); - if (pad) - bus->rxctl += - (BRCMF_SDALIGN - pad); - bus->rxctl -= firstread; - } - rxbuf = bus->rxctl; - /* Read the entire frame */ - sdret = brcmf_sdcard_recv_buf(card, - brcmf_sdcard_cur_sbwad(card), - SDIO_FUNC_2, F2SYNC, - rxbuf, rdlen, - NULL, NULL, NULL); - bus->f2rxdata++; - - /* Control frame failures need - retransmission */ - if (sdret < 0) { - BRCMF_ERROR(("%s: read %d " - "control bytes " - "failed: %d\n", - __func__, - rdlen, sdret)); - /* dhd.rx_ctlerrs is higher */ - bus->rxc_errors++; - brcmf_sdbrcm_rxfail(bus, true, - (bus->bus == - SPI_BUS) ? false - : true); - continue; - } - } else { - /* Give up on data, - request rtx of events */ - BRCMF_ERROR(("%s (nextlen): " - "brcmu_pkt_buf_get_skb " - "failed:" - " len %d rdlen %d expected" - " rxseq %d\n", __func__, - len, rdlen, rxseq)); - continue; - } + /* Give up on data, request rtx of events */ + brcmf_dbg(ERROR, "(nextlen): brcmu_pkt_buf_get_skb failed: len %d rdlen %d expected rxseq %d\n", + len, rdlen, rxseq); + continue; } else { - if (bus->bus == SPI_BUS) - bus->usebufpool = true; - PKTALIGN(pkt, rdlen, BRCMF_SDALIGN); rxbuf = (u8 *) (pkt->data); /* Read the entire frame */ - sdret = brcmf_sdcard_recv_buf(card, - brcmf_sdcard_cur_sbwad(card), + sdret = brcmf_sdcard_recv_buf(bus->sdiodev, + brcmf_sdcard_cur_sbwad( + bus->sdiodev), SDIO_FUNC_2, F2SYNC, rxbuf, rdlen, - pkt, NULL, NULL); + pkt); bus->f2rxdata++; if (sdret < 0) { - BRCMF_ERROR(("%s (nextlen): read %d" - " bytes failed: %d\n", - __func__, rdlen, sdret)); + brcmf_dbg(ERROR, "(nextlen): read %d bytes failed: %d\n", + rdlen, sdret); brcmu_pkt_buf_free_skb(pkt); bus->drvr->rx_errors++; /* Force retry w/normal header read. * Don't attempt NAK for * gSPI */ - brcmf_sdbrcm_rxfail(bus, true, - (bus->bus == - SPI_BUS) ? false : - true); + brcmf_sdbrcm_rxfail(bus, true, true); continue; } } @@ -4171,18 +3803,15 @@ brcmf_sdbrcm_readframes(struct brcmf_bus *bus, uint maxframes, bool *finished) /* All zeros means readahead info was bad */ if (!(len | check)) { - BRCMF_INFO(("%s (nextlen): read zeros in HW " - "header???\n", __func__)); + brcmf_dbg(INFO, "(nextlen): read zeros in HW header???\n"); brcmf_sdbrcm_pktfree2(bus, pkt); continue; } /* Validate check bytes */ if ((u16)~(len ^ check)) { - BRCMF_ERROR(("%s (nextlen): HW hdr error:" - " nextlen/len/check" - " 0x%04x/0x%04x/0x%04x\n", - __func__, nextlen, len, check)); + brcmf_dbg(ERROR, "(nextlen): HW hdr error: nextlen/len/check 0x%04x/0x%04x/0x%04x\n", + nextlen, len, check); bus->rx_badhdr++; brcmf_sdbrcm_rxfail(bus, false, false); brcmf_sdbrcm_pktfree2(bus, pkt); @@ -4191,8 +3820,8 @@ brcmf_sdbrcm_readframes(struct brcmf_bus *bus, uint maxframes, bool *finished) /* Validate frame length */ if (len < SDPCM_HDRLEN) { - BRCMF_ERROR(("%s (nextlen): HW hdr length " - "invalid: %d\n", __func__, len)); + brcmf_dbg(ERROR, "(nextlen): HW hdr length invalid: %d\n", + len); brcmf_sdbrcm_pktfree2(bus, pkt); continue; } @@ -4202,13 +3831,10 @@ brcmf_sdbrcm_readframes(struct brcmf_bus *bus, uint maxframes, bool *finished) if (len_consistent) { /* Mismatch, force retry w/normal header (may be >4K) */ - BRCMF_ERROR(("%s (nextlen): mismatch, " - "nextlen %d len %d rnd %d; " - "expected rxseq %d\n", - __func__, nextlen, - len, roundup(len, 16), rxseq)); - brcmf_sdbrcm_rxfail(bus, true, - bus->bus != SPI_BUS); + brcmf_dbg(ERROR, "(nextlen): mismatch, nextlen %d len %d rnd %d; expected rxseq %d\n", + nextlen, len, roundup(len, 16), + rxseq); + brcmf_sdbrcm_rxfail(bus, true, true); brcmf_sdbrcm_pktfree2(bus, pkt); continue; } @@ -4227,9 +3853,8 @@ brcmf_sdbrcm_readframes(struct brcmf_bus *bus, uint maxframes, bool *finished) bus->rxhdr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET]; if ((bus->nextlen << 4) > MAX_RX_DATASZ) { - BRCMF_INFO(("%s (nextlen): got frame w/nextlen" - " too large (%d), seq %d\n", - __func__, bus->nextlen, seq)); + brcmf_dbg(INFO, "(nextlen): got frame w/nextlen too large (%d), seq %d\n", + bus->nextlen, seq); bus->nextlen = 0; } @@ -4252,17 +3877,16 @@ brcmf_sdbrcm_readframes(struct brcmf_bus *bus, uint maxframes, bool *finished) /* Check and update sequence number */ if (rxseq != seq) { - BRCMF_INFO(("%s (nextlen): rx_seq %d, expected " - "%d\n", __func__, seq, rxseq)); + brcmf_dbg(INFO, "(nextlen): rx_seq %d, expected %d\n", + seq, rxseq); bus->rx_badseq++; rxseq = seq; } /* Check window for sanity */ if ((u8) (txmax - bus->tx_seq) > 0x40) { - BRCMF_ERROR(("%s: got unlikely tx max %d with " - "tx_seq %d\n", - __func__, txmax, bus->tx_seq)); + brcmf_dbg(ERROR, "got unlikely tx max %d with tx_seq %d\n", + txmax, bus->tx_seq); txmax = bus->tx_seq + 2; } bus->tx_max = txmax; @@ -4280,34 +3904,19 @@ brcmf_sdbrcm_readframes(struct brcmf_bus *bus, uint maxframes, bool *finished) #endif if (chan == SDPCM_CONTROL_CHANNEL) { - if (bus->bus == SPI_BUS) { - brcmf_sdbrcm_read_control(bus, rxbuf, - len, doff); - } else { - BRCMF_ERROR(("%s (nextlen): readahead" - " on control packet %d?\n", - __func__, seq)); - /* Force retry w/normal header read */ - bus->nextlen = 0; - brcmf_sdbrcm_rxfail(bus, false, true); - } + brcmf_dbg(ERROR, "(nextlen): readahead on control packet %d?\n", + seq); + /* Force retry w/normal header read */ + bus->nextlen = 0; + brcmf_sdbrcm_rxfail(bus, false, true); brcmf_sdbrcm_pktfree2(bus, pkt); continue; } - if ((bus->bus == SPI_BUS) && !bus->usebufpool) { - BRCMF_ERROR(("Received %d bytes on %d channel." - " Running out of " "rx pktbuf's or" - " not yet malloced.\n", - len, chan)); - continue; - } - /* Validate data offset */ if ((doff < SDPCM_HDRLEN) || (doff > len)) { - BRCMF_ERROR(("%s (nextlen): bad data offset %d:" - " HW len %d min %d\n", __func__, - doff, len, SDPCM_HDRLEN)); + brcmf_dbg(ERROR, "(nextlen): bad data offset %d: HW len %d min %d\n", + doff, len, SDPCM_HDRLEN); brcmf_sdbrcm_rxfail(bus, false, false); brcmf_sdbrcm_pktfree2(bus, pkt); continue; @@ -4316,20 +3925,16 @@ brcmf_sdbrcm_readframes(struct brcmf_bus *bus, uint maxframes, bool *finished) /* All done with this one -- now deliver the packet */ goto deliver; } - /* gSPI frames should not be handled in fractions */ - if (bus->bus == SPI_BUS) - break; /* Read frame header (hardware and software) */ - sdret = brcmf_sdcard_recv_buf(card, - brcmf_sdcard_cur_sbwad(card), + sdret = brcmf_sdcard_recv_buf(bus->sdiodev, + brcmf_sdcard_cur_sbwad(bus->sdiodev), SDIO_FUNC_2, F2SYNC, bus->rxhdr, firstread, - NULL, NULL, NULL); + NULL); bus->f2rxhdrs++; if (sdret < 0) { - BRCMF_ERROR(("%s: RXHEADER FAILED: %d\n", __func__, - sdret)); + brcmf_dbg(ERROR, "RXHEADER FAILED: %d\n", sdret); bus->rx_hdrfail++; brcmf_sdbrcm_rxfail(bus, true, true); continue; @@ -4354,8 +3959,8 @@ brcmf_sdbrcm_readframes(struct brcmf_bus *bus, uint maxframes, bool *finished) /* Validate check bytes */ if ((u16) ~(len ^ check)) { - BRCMF_ERROR(("%s: HW hdr err: len/check " - "0x%04x/0x%04x\n", __func__, len, check)); + brcmf_dbg(ERROR, "HW hdr err: len/check 0x%04x/0x%04x\n", + len, check); bus->rx_badhdr++; brcmf_sdbrcm_rxfail(bus, false, false); continue; @@ -4363,8 +3968,7 @@ brcmf_sdbrcm_readframes(struct brcmf_bus *bus, uint maxframes, bool *finished) /* Validate frame length */ if (len < SDPCM_HDRLEN) { - BRCMF_ERROR(("%s: HW hdr length invalid: %d\n", - __func__, len)); + brcmf_dbg(ERROR, "HW hdr length invalid: %d\n", len); continue; } @@ -4376,9 +3980,8 @@ brcmf_sdbrcm_readframes(struct brcmf_bus *bus, uint maxframes, bool *finished) /* Validate data offset */ if ((doff < SDPCM_HDRLEN) || (doff > len)) { - BRCMF_ERROR(("%s: Bad data offset %d: HW len %d," - " min %d seq %d\n", __func__, doff, - len, SDPCM_HDRLEN, seq)); + brcmf_dbg(ERROR, "Bad data offset %d: HW len %d, min %d seq %d\n", + doff, len, SDPCM_HDRLEN, seq); bus->rx_badhdr++; brcmf_sdbrcm_rxfail(bus, false, false); continue; @@ -4388,9 +3991,8 @@ brcmf_sdbrcm_readframes(struct brcmf_bus *bus, uint maxframes, bool *finished) bus->nextlen = bus->rxhdr[SDPCM_FRAMETAG_LEN + SDPCM_NEXTLEN_OFFSET]; if ((bus->nextlen << 4) > MAX_RX_DATASZ) { - BRCMF_INFO(("%s (nextlen): got frame w/nextlen too" - " large (%d), seq %d\n", - __func__, bus->nextlen, seq)); + brcmf_dbg(INFO, "(nextlen): got frame w/nextlen too large (%d), seq %d\n", + bus->nextlen, seq); bus->nextlen = 0; } @@ -4410,16 +4012,15 @@ brcmf_sdbrcm_readframes(struct brcmf_bus *bus, uint maxframes, bool *finished) /* Check and update sequence number */ if (rxseq != seq) { - BRCMF_INFO(("%s: rx_seq %d, expected %d\n", __func__, - seq, rxseq)); + brcmf_dbg(INFO, "rx_seq %d, expected %d\n", seq, rxseq); bus->rx_badseq++; rxseq = seq; } /* Check window for sanity */ if ((u8) (txmax - bus->tx_seq) > 0x40) { - BRCMF_ERROR(("%s: unlikely tx max %d with tx_seq %d\n", - __func__, txmax, bus->tx_seq)); + brcmf_dbg(ERROR, "unlikely tx max %d with tx_seq %d\n", + txmax, bus->tx_seq); txmax = bus->tx_seq + 2; } bus->tx_max = txmax; @@ -4454,8 +4055,8 @@ brcmf_sdbrcm_readframes(struct brcmf_bus *bus, uint maxframes, bool *finished) if ((rdlen + firstread) > MAX_RX_DATASZ) { /* Too long -- skip this frame */ - BRCMF_ERROR(("%s: too long: len %d rdlen %d\n", - __func__, len, rdlen)); + brcmf_dbg(ERROR, "too long: len %d rdlen %d\n", + len, rdlen); bus->drvr->rx_errors++; bus->rx_toolong++; brcmf_sdbrcm_rxfail(bus, false, false); @@ -4465,9 +4066,8 @@ brcmf_sdbrcm_readframes(struct brcmf_bus *bus, uint maxframes, bool *finished) pkt = brcmu_pkt_buf_get_skb(rdlen + firstread + BRCMF_SDALIGN); if (!pkt) { /* Give up on data, request rtx of events */ - BRCMF_ERROR(("%s: brcmu_pkt_buf_get_skb failed:" - " rdlen %d chan %d\n", __func__, rdlen, - chan)); + brcmf_dbg(ERROR, "brcmu_pkt_buf_get_skb failed: rdlen %d chan %d\n", + rdlen, chan); bus->drvr->rx_dropped++; brcmf_sdbrcm_rxfail(bus, false, RETRYCHAN(chan)); continue; @@ -4478,18 +4078,17 @@ brcmf_sdbrcm_readframes(struct brcmf_bus *bus, uint maxframes, bool *finished) PKTALIGN(pkt, rdlen, BRCMF_SDALIGN); /* Read the remaining frame data */ - sdret = brcmf_sdcard_recv_buf(card, - brcmf_sdcard_cur_sbwad(card), + sdret = brcmf_sdcard_recv_buf(bus->sdiodev, + brcmf_sdcard_cur_sbwad(bus->sdiodev), SDIO_FUNC_2, F2SYNC, ((u8 *) (pkt->data)), - rdlen, pkt, NULL, NULL); + rdlen, pkt); bus->f2rxdata++; if (sdret < 0) { - BRCMF_ERROR(("%s: read %d %s bytes failed: %d\n", - __func__, rdlen, - ((chan == SDPCM_EVENT_CHANNEL) ? "event" - : ((chan == SDPCM_DATA_CHANNEL) ? "data" - : "test")), sdret)); + brcmf_dbg(ERROR, "read %d %s bytes failed: %d\n", rdlen, + ((chan == SDPCM_EVENT_CHANNEL) ? "event" + : ((chan == SDPCM_DATA_CHANNEL) ? "data" + : "test")), sdret); brcmu_pkt_buf_free_skb(pkt); bus->drvr->rx_errors++; brcmf_sdbrcm_rxfail(bus, true, RETRYCHAN(chan)); @@ -4512,8 +4111,8 @@ deliver: /* Save superframe descriptor and allocate packet frame */ if (chan == SDPCM_GLOM_CHANNEL) { if (SDPCM_GLOMDESC(&bus->rxhdr[SDPCM_FRAMETAG_LEN])) { - BRCMF_GLOM(("%s: glom descriptor, %d bytes:\n", - __func__, len)); + brcmf_dbg(GLOM, "glom descriptor, %d bytes:\n", + len); #ifdef BCMDBG if (BRCMF_GLOM_ON()) { printk(KERN_DEBUG "Glom Data:\n"); @@ -4526,8 +4125,8 @@ deliver: skb_pull(pkt, SDPCM_HDRLEN); bus->glomd = pkt; } else { - BRCMF_ERROR(("%s: glom superframe w/o " - "descriptor!\n", __func__)); + brcmf_dbg(ERROR, "%s: glom superframe w/o " + "descriptor!\n", __func__); brcmf_sdbrcm_rxfail(bus, false, false); } continue; @@ -4537,19 +4136,11 @@ deliver: __skb_trim(pkt, len); skb_pull(pkt, doff); -#ifdef SDTEST - /* Test channel packets are processed separately */ - if (chan == SDPCM_TEST_CHANNEL) { - brcmf_sdbrcm_checkdied(bus, pkt, seq); - continue; - } -#endif /* SDTEST */ - if (pkt->len == 0) { brcmu_pkt_buf_free_skb(pkt); continue; } else if (brcmf_proto_hdrpull(bus->drvr, &ifidx, pkt) != 0) { - BRCMF_ERROR(("%s: rx protocol error\n", __func__)); + brcmf_dbg(ERROR, "rx protocol error\n"); brcmu_pkt_buf_free_skb(pkt); bus->drvr->rx_errors++; continue; @@ -4563,12 +4154,12 @@ deliver: rxcount = maxframes - rxleft; #ifdef BCMDBG /* Message if we hit the limit */ - if (!rxleft && !sdtest) - BRCMF_DATA(("%s: hit rx limit of %d frames\n", __func__, - maxframes)); + if (!rxleft) + brcmf_dbg(DATA, "hit rx limit of %d frames\n", + maxframes); else #endif /* BCMDBG */ - BRCMF_DATA(("%s: processed %d frames\n", __func__, rxcount)); + brcmf_dbg(DATA, "processed %d frames\n", rxcount); /* Back off rxseq if awaiting rtx, update rx_seq */ if (bus->rxskip) rxseq--; @@ -4584,7 +4175,7 @@ static u32 brcmf_sdbrcm_hostmail(struct brcmf_bus *bus) u8 fcbits; uint retries = 0; - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); /* Read mailbox data and ack that we did so */ r_sdreg32(bus, &hmb_data, @@ -4597,10 +4188,10 @@ static u32 brcmf_sdbrcm_hostmail(struct brcmf_bus *bus) /* Dongle recomposed rx frames, accept them again */ if (hmb_data & HMB_DATA_NAKHANDLED) { - BRCMF_INFO(("Dongle reports NAK handled, expect rtx of %d\n", - bus->rx_seq)); + brcmf_dbg(INFO, "Dongle reports NAK handled, expect rtx of %d\n", + bus->rx_seq); if (!bus->rxskip) - BRCMF_ERROR(("%s: unexpected NAKHANDLED!\n", __func__)); + brcmf_dbg(ERROR, "unexpected NAKHANDLED!\n"); bus->rxskip = false; intstatus |= I_HMB_FRAME_IND; @@ -4614,12 +4205,12 @@ static u32 brcmf_sdbrcm_hostmail(struct brcmf_bus *bus) (hmb_data & HMB_DATA_VERSION_MASK) >> HMB_DATA_VERSION_SHIFT; if (bus->sdpcm_ver != SDPCM_PROT_VERSION) - BRCMF_ERROR(("Version mismatch, dongle reports %d, " - "expecting %d\n", - bus->sdpcm_ver, SDPCM_PROT_VERSION)); + brcmf_dbg(ERROR, "Version mismatch, dongle reports %d, " + "expecting %d\n", + bus->sdpcm_ver, SDPCM_PROT_VERSION); else - BRCMF_INFO(("Dongle ready, protocol version %d\n", - bus->sdpcm_ver)); + brcmf_dbg(INFO, "Dongle ready, protocol version %d\n", + bus->sdpcm_ver); } /* @@ -4646,17 +4237,15 @@ static u32 brcmf_sdbrcm_hostmail(struct brcmf_bus *bus) HMB_DATA_NAKHANDLED | HMB_DATA_FC | HMB_DATA_FWREADY | - HMB_DATA_FCDATA_MASK | HMB_DATA_VERSION_MASK)) { - BRCMF_ERROR(("Unknown mailbox data content: 0x%02x\n", - hmb_data)); - } + HMB_DATA_FCDATA_MASK | HMB_DATA_VERSION_MASK)) + brcmf_dbg(ERROR, "Unknown mailbox data content: 0x%02x\n", + hmb_data); return intstatus; } static bool brcmf_sdbrcm_dpc(struct brcmf_bus *bus) { - struct brcmf_sdio_card *card = bus->card; u32 intstatus, newstatus = 0; uint retries = 0; uint rxlimit = brcmf_rxbound; /* Rx frames to read before resched */ @@ -4665,7 +4254,7 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_bus *bus) bool rxdone = true; /* Flag for no more read data */ bool resched = false; /* Flag indicating resched wanted */ - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); /* Start with leftover status bits */ intstatus = bus->intstatus; @@ -4679,41 +4268,41 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_bus *bus) #ifdef BCMDBG /* Check for inconsistent device control */ - devctl = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1, + devctl = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err); if (err) { - BRCMF_ERROR(("%s: error reading DEVCTL: %d\n", - __func__, err)); + brcmf_dbg(ERROR, "error reading DEVCTL: %d\n", err); bus->drvr->busstate = BRCMF_BUS_DOWN; } #endif /* BCMDBG */ /* Read CSR, if clock on switch to AVAIL, else ignore */ - clkctl = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1, + clkctl = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err); if (err) { - BRCMF_ERROR(("%s: error reading CSR: %d\n", __func__, - err)); + brcmf_dbg(ERROR, "error reading CSR: %d\n", + err); bus->drvr->busstate = BRCMF_BUS_DOWN; } - BRCMF_INFO(("DPC: PENDING, devctl 0x%02x clkctl 0x%02x\n", - devctl, clkctl)); + brcmf_dbg(INFO, "DPC: PENDING, devctl 0x%02x clkctl 0x%02x\n", + devctl, clkctl); if (SBSDIO_HTAV(clkctl)) { - devctl = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1, + devctl = brcmf_sdcard_cfg_read(bus->sdiodev, + SDIO_FUNC_1, SBSDIO_DEVICE_CTL, &err); if (err) { - BRCMF_ERROR(("%s: error reading DEVCTL: %d\n", - __func__, err)); + brcmf_dbg(ERROR, "error reading DEVCTL: %d\n", + err); bus->drvr->busstate = BRCMF_BUS_DOWN; } devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY; - brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, SBSDIO_DEVICE_CTL, devctl, &err); if (err) { - BRCMF_ERROR(("%s: error writing DEVCTL: %d\n", - __func__, err)); + brcmf_dbg(ERROR, "error writing DEVCTL: %d\n", + err); bus->drvr->busstate = BRCMF_BUS_DOWN; } bus->clkstate = CLK_AVAIL; @@ -4735,7 +4324,7 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_bus *bus) r_sdreg32(bus, &newstatus, offsetof(struct sdpcmd_regs, intstatus), &retries); bus->f1regdata++; - if (brcmf_sdcard_regfail(bus->card)) + if (brcmf_sdcard_regfail(bus->sdiodev)) newstatus = 0; newstatus &= bus->hostintmask; bus->fcstate = !!(newstatus & I_HMB_FC_STATE); @@ -4776,23 +4365,23 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_bus *bus) /* Generally don't ask for these, can get CRC errors... */ if (intstatus & I_WR_OOSYNC) { - BRCMF_ERROR(("Dongle reports WR_OOSYNC\n")); + brcmf_dbg(ERROR, "Dongle reports WR_OOSYNC\n"); intstatus &= ~I_WR_OOSYNC; } if (intstatus & I_RD_OOSYNC) { - BRCMF_ERROR(("Dongle reports RD_OOSYNC\n")); + brcmf_dbg(ERROR, "Dongle reports RD_OOSYNC\n"); intstatus &= ~I_RD_OOSYNC; } if (intstatus & I_SBINT) { - BRCMF_ERROR(("Dongle reports SBINT\n")); + brcmf_dbg(ERROR, "Dongle reports SBINT\n"); intstatus &= ~I_SBINT; } /* Would be active due to wake-wlan in gSPI */ if (intstatus & I_CHIPACTIVE) { - BRCMF_INFO(("Dongle reports CHIPACTIVE\n")); + brcmf_dbg(INFO, "Dongle reports CHIPACTIVE\n"); intstatus &= ~I_CHIPACTIVE; } @@ -4812,45 +4401,37 @@ static bool brcmf_sdbrcm_dpc(struct brcmf_bus *bus) bus->intstatus = intstatus; clkwait: - /* Re-enable interrupts to detect new device events (mailbox, rx frame) - * or clock availability. (Allows tx loop to check ipend if desired.) - * (Unless register access seems hosed, as we may not be able to ACK...) - */ - if (bus->intr && bus->intdis && !brcmf_sdcard_regfail(card)) { - BRCMF_INTR(("%s: enable SDIO interrupts, rxdone %d" - " framecnt %d\n", __func__, rxdone, framecnt)); - bus->intdis = false; - brcmf_sdcard_intr_enable(card); - } - if (DATAOK(bus) && bus->ctrl_frame_stat && (bus->clkstate == CLK_AVAIL)) { int ret, i; - ret = brcmf_sdbrcm_send_buf(bus, brcmf_sdcard_cur_sbwad(card), + ret = brcmf_sdbrcm_send_buf(bus, + brcmf_sdcard_cur_sbwad(bus->sdiodev), SDIO_FUNC_2, F2SYNC, (u8 *) bus->ctrl_frame_buf, - (u32) bus->ctrl_frame_len, NULL, NULL, NULL); + (u32) bus->ctrl_frame_len, NULL); if (ret < 0) { /* On failure, abort the command and terminate the frame */ - BRCMF_INFO(("%s: sdio error %d, abort command and " - "terminate frame.\n", __func__, ret)); + brcmf_dbg(INFO, "sdio error %d, abort command and terminate frame\n", + ret); bus->tx_sderrs++; - brcmf_sdcard_abort(card, SDIO_FUNC_2); + brcmf_sdcard_abort(bus->sdiodev, SDIO_FUNC_2); - brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, SBSDIO_FUNC1_FRAMECTRL, SFC_WF_TERM, NULL); bus->f1regdata++; for (i = 0; i < 3; i++) { u8 hi, lo; - hi = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1, + hi = brcmf_sdcard_cfg_read(bus->sdiodev, + SDIO_FUNC_1, SBSDIO_FUNC1_WFRAMEBCHI, NULL); - lo = brcmf_sdcard_cfg_read(card, SDIO_FUNC_1, + lo = brcmf_sdcard_cfg_read(bus->sdiodev, + SDIO_FUNC_1, SBSDIO_FUNC1_WFRAMEBCLO, NULL); bus->f1regdata += 2; @@ -4862,7 +4443,7 @@ clkwait: if (ret == 0) bus->tx_seq = (bus->tx_seq + 1) % SDPCM_SEQUENCE_WRAP; - BRCMF_INFO(("Return_dpc value is : %d\n", ret)); + brcmf_dbg(INFO, "Return_dpc value is : %d\n", ret); bus->ctrl_frame_stat = false; brcmf_sdbrcm_wait_event_wakeup(bus); } @@ -4880,15 +4461,13 @@ clkwait: /* On failed register access, all bets are off: no resched or interrupts */ if ((bus->drvr->busstate == BRCMF_BUS_DOWN) || - brcmf_sdcard_regfail(card)) { - BRCMF_ERROR(("%s: failed backplane access over SDIO, halting " - "operation %d\n", __func__, - brcmf_sdcard_regfail(card))); + brcmf_sdcard_regfail(bus->sdiodev)) { + brcmf_dbg(ERROR, "failed backplane access over SDIO, halting operation %d\n", + brcmf_sdcard_regfail(bus->sdiodev)); bus->drvr->busstate = BRCMF_BUS_DOWN; bus->intstatus = 0; } else if (bus->clkstate == CLK_PENDING) { - BRCMF_INFO(("%s: rescheduled due to CLK_PENDING awaiting " - "I_CHIPACTIVE interrupt\n", __func__)); + brcmf_dbg(INFO, "rescheduled due to CLK_PENDING awaiting I_CHIPACTIVE interrupt\n"); resched = true; } else if (bus->intstatus || bus->ipend || (!bus->fcstate && brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) @@ -4913,19 +4492,16 @@ clkwait: void brcmf_sdbrcm_isr(void *arg) { struct brcmf_bus *bus = (struct brcmf_bus *) arg; - struct brcmf_sdio_card *card; - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); if (!bus) { - BRCMF_ERROR(("%s : bus is null pointer , exit\n", __func__)); + brcmf_dbg(ERROR, "bus is null pointer, exiting\n"); return; } - card = bus->card; if (bus->drvr->busstate == BRCMF_BUS_DOWN) { - BRCMF_ERROR(("%s : bus is down. we have nothing to do\n", - __func__)); + brcmf_dbg(ERROR, "bus is down. we have nothing to do\n"); return; } /* Count the interrupt call */ @@ -4934,297 +4510,23 @@ void brcmf_sdbrcm_isr(void *arg) /* Shouldn't get this interrupt if we're sleeping? */ if (bus->sleeping) { - BRCMF_ERROR(("INTERRUPT WHILE SLEEPING??\n")); + brcmf_dbg(ERROR, "INTERRUPT WHILE SLEEPING??\n"); return; } /* Disable additional interrupts (is this needed now)? */ - if (bus->intr) - BRCMF_INTR(("%s: disable SDIO interrupts\n", __func__)); - else - BRCMF_ERROR(("brcmf_sdbrcm_isr() w/o interrupt configured!\n")); - - brcmf_sdcard_intr_disable(card); - bus->intdis = true; + if (!bus->intr) + brcmf_dbg(ERROR, "isr w/o interrupt configured!\n"); -#if defined(SDIO_ISR_THREAD) - BRCMF_TRACE(("Calling brcmf_sdbrcm_dpc() from %s\n", __func__)); - while (brcmf_sdbrcm_dpc(bus)) - ; -#else bus->dpc_sched = true; brcmf_sdbrcm_sched_dpc(bus); -#endif - -} - -#ifdef SDTEST -static void brcmf_sdbrcm_pktgen_init(struct brcmf_bus *bus) -{ - /* Default to specified length, or full range */ - if (brcmf_pktgen_len) { - bus->pktgen_maxlen = min(brcmf_pktgen_len, - BRCMF_MAX_PKTGEN_LEN); - bus->pktgen_minlen = bus->pktgen_maxlen; - } else { - bus->pktgen_maxlen = BRCMF_MAX_PKTGEN_LEN; - bus->pktgen_minlen = 0; - } - bus->pktgen_len = (u16) bus->pktgen_minlen; - - /* Default to per-watchdog burst with 10s print time */ - bus->pktgen_freq = 1; - bus->pktgen_print = 10000 / brcmf_watchdog_ms; - bus->pktgen_count = (brcmf_pktgen * brcmf_watchdog_ms + 999) / 1000; - - /* Default to echo mode */ - bus->pktgen_mode = BRCMF_PKTGEN_ECHO; - bus->pktgen_stop = 1; -} - -static void brcmf_sdbrcm_pktgen(struct brcmf_bus *bus) -{ - struct sk_buff *pkt; - u8 *data; - uint pktcount; - uint fillbyte; - u16 len; - - /* Display current count if appropriate */ - if (bus->pktgen_print && (++bus->pktgen_ptick >= bus->pktgen_print)) { - bus->pktgen_ptick = 0; - printk(KERN_DEBUG "%s: send attempts %d rcvd %d\n", - __func__, bus->pktgen_sent, bus->pktgen_rcvd); - } - - /* For recv mode, just make sure dongle has started sending */ - if (bus->pktgen_mode == BRCMF_PKTGEN_RECV) { - if (!bus->pktgen_rcvd) - brcmf_sdbrcm_sdtest_set(bus, true); - return; - } - - /* Otherwise, generate or request the specified number of packets */ - for (pktcount = 0; pktcount < bus->pktgen_count; pktcount++) { - /* Stop if total has been reached */ - if (bus->pktgen_total - && (bus->pktgen_sent >= bus->pktgen_total)) { - bus->pktgen_count = 0; - break; - } - - /* Allocate an appropriate-sized packet */ - len = bus->pktgen_len; - pkt = brcmu_pkt_buf_get_skb( - len + SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + BRCMF_SDALIGN, - true); - if (!pkt) { - BRCMF_ERROR(("%s: brcmu_pkt_buf_get_skb failed!\n", - __func__)); - break; - } - PKTALIGN(pkt, (len + SDPCM_HDRLEN + SDPCM_TEST_HDRLEN), - BRCMF_SDALIGN); - data = (u8 *) (pkt->data) + SDPCM_HDRLEN; - - /* Write test header cmd and extra based on mode */ - switch (bus->pktgen_mode) { - case BRCMF_PKTGEN_ECHO: - *data++ = SDPCM_TEST_ECHOREQ; - *data++ = (u8) bus->pktgen_sent; - break; - - case BRCMF_PKTGEN_SEND: - *data++ = SDPCM_TEST_DISCARD; - *data++ = (u8) bus->pktgen_sent; - break; - - case BRCMF_PKTGEN_RXBURST: - *data++ = SDPCM_TEST_BURST; - *data++ = (u8) bus->pktgen_count; - break; - - default: - BRCMF_ERROR(("Unrecognized pktgen mode %d\n", - bus->pktgen_mode)); - brcmu_pkt_buf_free_skb(pkt, true); - bus->pktgen_count = 0; - return; - } - - /* Write test header length field */ - *data++ = (len >> 0); - *data++ = (len >> 8); - - /* Then fill in the remainder -- N/A for burst, - but who cares... */ - for (fillbyte = 0; fillbyte < len; fillbyte++) - *data++ = - SDPCM_TEST_FILL(fillbyte, (u8) bus->pktgen_sent); - -#ifdef BCMDBG - if (BRCMF_BYTES_ON() && BRCMF_DATA_ON()) { - data = (u8 *) (pkt->data) + SDPCM_HDRLEN; - printk(KERN_DEBUG "brcmf_sdbrcm_pktgen: Tx Data:\n"); - print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, data, - pkt->len - SDPCM_HDRLEN); - } -#endif - - /* Send it */ - if (brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_TEST_CHANNEL, true)) { - bus->pktgen_fail++; - if (bus->pktgen_stop - && bus->pktgen_stop == bus->pktgen_fail) - bus->pktgen_count = 0; - } - bus->pktgen_sent++; - - /* Bump length if not fixed, wrap at max */ - if (++bus->pktgen_len > bus->pktgen_maxlen) - bus->pktgen_len = (u16) bus->pktgen_minlen; - - /* Special case for burst mode: just send one request! */ - if (bus->pktgen_mode == BRCMF_PKTGEN_RXBURST) - break; - } -} - -static void brcmf_sdbrcm_sdtest_set(struct brcmf_bus *bus, bool start) -{ - struct sk_buff *pkt; - u8 *data; - - /* Allocate the packet */ - pkt = brcmu_pkt_buf_get_skb(SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + - BRCMF_SDALIGN, true); - if (!pkt) { - BRCMF_ERROR(("%s: brcmu_pkt_buf_get_skb failed!\n", __func__)); - return; - } - PKTALIGN(pkt, (SDPCM_HDRLEN + SDPCM_TEST_HDRLEN), BRCMF_SDALIGN); - data = (u8 *) (pkt->data) + SDPCM_HDRLEN; - - /* Fill in the test header */ - *data++ = SDPCM_TEST_SEND; - *data++ = start; - *data++ = (bus->pktgen_maxlen >> 0); - *data++ = (bus->pktgen_maxlen >> 8); - - /* Send it */ - if (brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_TEST_CHANNEL, true)) - bus->pktgen_fail++; -} - -static void -brcmf_sdbrcm_checkdied(struct brcmf_bus *bus, struct sk_buff *pkt, uint seq) -{ - u8 *data; - uint pktlen; - - u8 cmd; - u8 extra; - u16 len; - u16 offset; - - /* Check for min length */ - pktlen = pkt->len; - if (pktlen < SDPCM_TEST_HDRLEN) { - BRCMF_ERROR(("brcmf_sdbrcm_checkdied: toss runt frame, pktlen " - "%d\n", pktlen)); - brcmu_pkt_buf_free_skb(pkt, false); - return; - } - - /* Extract header fields */ - data = pkt->data; - cmd = *data++; - extra = *data++; - len = *data++; - len += *data++ << 8; - - /* Check length for relevant commands */ - if (cmd == SDPCM_TEST_DISCARD || cmd == SDPCM_TEST_ECHOREQ - || cmd == SDPCM_TEST_ECHORSP) { - if (pktlen != len + SDPCM_TEST_HDRLEN) { - BRCMF_ERROR(("brcmf_sdbrcm_checkdied: frame length " - "mismatch, pktlen %d seq %d" - " cmd %d extra %d len %d\n", - pktlen, seq, cmd, extra, len)); - brcmu_pkt_buf_free_skb(pkt, false); - return; - } - } - - /* Process as per command */ - switch (cmd) { - case SDPCM_TEST_ECHOREQ: - /* Rx->Tx turnaround ok (even on NDIS w/current - implementation) */ - *(u8 *) (pkt->data) = SDPCM_TEST_ECHORSP; - if (brcmf_sdbrcm_txpkt(bus, pkt, SDPCM_TEST_CHANNEL, true) == 0) - bus->pktgen_sent++; - else { - bus->pktgen_fail++; - brcmu_pkt_buf_free_skb(pkt, false); - } - bus->pktgen_rcvd++; - break; - - case SDPCM_TEST_ECHORSP: - if (bus->ext_loop) { - brcmu_pkt_buf_free_skb(pkt, false); - bus->pktgen_rcvd++; - break; - } - - for (offset = 0; offset < len; offset++, data++) { - if (*data != SDPCM_TEST_FILL(offset, extra)) { - BRCMF_ERROR(("brcmf_sdbrcm_checkdied: echo" - " data mismatch: " - "offset %d (len %d) " - "expect 0x%02x rcvd 0x%02x\n", - offset, len, - SDPCM_TEST_FILL(offset, extra), - *data)); - break; - } - } - brcmu_pkt_buf_free_skb(pkt, false); - bus->pktgen_rcvd++; - break; - - case SDPCM_TEST_DISCARD: - brcmu_pkt_buf_free_skb(pkt, false); - bus->pktgen_rcvd++; - break; - - case SDPCM_TEST_BURST: - case SDPCM_TEST_SEND: - default: - BRCMF_INFO(("brcmf_sdbrcm_checkdied: unsupported or unknown " - "command, pktlen %d seq %d" " cmd %d extra %d" - " len %d\n", pktlen, seq, cmd, extra, len)); - brcmu_pkt_buf_free_skb(pkt, false); - break; - } - - /* For recv mode, stop at limie (and tell dongle to stop sending) */ - if (bus->pktgen_mode == BRCMF_PKTGEN_RECV) { - if (bus->pktgen_total - && (bus->pktgen_rcvd >= bus->pktgen_total)) { - bus->pktgen_count = 0; - brcmf_sdbrcm_sdtest_set(bus, false); - } - } } -#endif /* SDTEST */ extern bool brcmf_sdbrcm_bus_watchdog(struct brcmf_pub *drvr) { struct brcmf_bus *bus; - BRCMF_TIMER(("%s: Enter\n", __func__)); + brcmf_dbg(TIMER, "Enter\n"); bus = drvr->bus; @@ -5249,7 +4551,7 @@ extern bool brcmf_sdbrcm_bus_watchdog(struct brcmf_pub *drvr) if (!bus->dpc_sched) { u8 devpend; - devpend = brcmf_sdcard_cfg_read(bus->card, + devpend = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_0, SDIO_CCCR_INTx, NULL); intstatus = @@ -5262,8 +4564,6 @@ extern bool brcmf_sdbrcm_bus_watchdog(struct brcmf_pub *drvr) if (intstatus) { bus->pollcnt++; bus->ipend = true; - if (bus->intr) - brcmf_sdcard_intr_disable(bus->card); bus->dpc_sched = true; brcmf_sdbrcm_sched_dpc(bus); @@ -5289,16 +4589,6 @@ extern bool brcmf_sdbrcm_bus_watchdog(struct brcmf_pub *drvr) } #endif /* BCMDBG */ -#ifdef SDTEST - /* Generate packets if configured */ - if (bus->pktgen_count && (++bus->pktgen_tick >= bus->pktgen_freq)) { - /* Make sure backplane clock is on */ - brcmf_sdbrcm_clkctl(bus, CLK_AVAIL, false); - bus->pktgen_tick = 0; - brcmf_sdbrcm_pktgen(bus); - } -#endif - /* On idle timeout clear activity flag and/or turn off clock */ if ((bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) { if (++bus->idlecount >= bus->idletime) { @@ -5385,18 +4675,13 @@ done: static bool brcmf_sdbrcm_chipmatch(u16 chipid) { - if (chipid == BCM4325_CHIP_ID) - return true; if (chipid == BCM4329_CHIP_ID) return true; - if (chipid == BCM4319_CHIP_ID) - return true; return false; } -static void *brcmf_sdbrcm_probe(u16 venid, u16 devid, u16 bus_no, - u16 slot, u16 func, uint bustype, u32 regsva, - void *card) +void *brcmf_sdbrcm_probe(u16 bus_no, u16 slot, u16 func, uint bustype, + u32 regsva, struct brcmf_sdio_dev *sdiodev) { int ret; struct brcmf_bus *bus; @@ -5412,7 +4697,6 @@ static void *brcmf_sdbrcm_probe(u16 venid, u16 devid, u16 bus_no, brcmf_txbound = BRCMF_TXBOUND; brcmf_rxbound = BRCMF_RXBOUND; brcmf_alignctl = true; - sd1idle = true; brcmf_readahead = true; retrydata = false; brcmf_dongle_memsize = 0; @@ -5422,79 +4706,32 @@ static void *brcmf_sdbrcm_probe(u16 venid, u16 devid, u16 bus_no, brcmf_c_init(); - BRCMF_TRACE(("%s: Enter\n", __func__)); - BRCMF_INFO(("%s: venid 0x%04x devid 0x%04x\n", __func__, venid, devid)); + brcmf_dbg(TRACE, "Enter\n"); /* We make an assumption about address window mappings: * regsva == SI_ENUM_BASE*/ - /* SDIO car passes venid and devid based on CIS parsing -- but - * low-power start - * means early parse could fail, so here we should get either an ID - * we recognize OR (-1) indicating we must request power first. - */ - /* Check the Vendor ID */ - switch (venid) { - case 0x0000: - case PCI_VENDOR_ID_BROADCOM: - break; - default: - BRCMF_ERROR(("%s: unknown vendor: 0x%04x\n", __func__, venid)); - return NULL; - } - - /* Check the Device ID and make sure it's one that we support */ - switch (devid) { - case BCM4325_D11DUAL_ID: /* 4325 802.11a/g id */ - case BCM4325_D11G_ID: /* 4325 802.11g 2.4Ghz band id */ - case BCM4325_D11A_ID: /* 4325 802.11a 5Ghz band id */ - BRCMF_INFO(("%s: found 4325 Dongle\n", __func__)); - break; - case BCM4329_D11NDUAL_ID: /* 4329 802.11n dualband device */ - case BCM4329_D11N2G_ID: /* 4329 802.11n 2.4G device */ - case BCM4329_D11N5G_ID: /* 4329 802.11n 5G device */ - case 0x4329: - BRCMF_INFO(("%s: found 4329 Dongle\n", __func__)); - break; - case BCM4319_D11N_ID: /* 4319 802.11n id */ - case BCM4319_D11N2G_ID: /* 4319 802.11n2g id */ - case BCM4319_D11N5G_ID: /* 4319 802.11n5g id */ - BRCMF_INFO(("%s: found 4319 Dongle\n", __func__)); - break; - case 0: - BRCMF_INFO(("%s: allow device id 0, will check chip" - " internals\n", __func__)); - break; - - default: - BRCMF_ERROR(("%s: skipping 0x%04x/0x%04x, not a dongle\n", - __func__, venid, devid)); - return NULL; - } - /* Allocate private bus interface state */ bus = kzalloc(sizeof(struct brcmf_bus), GFP_ATOMIC); if (!bus) { - BRCMF_ERROR(("%s: kmalloc of struct dhd_bus failed\n", - __func__)); + brcmf_dbg(ERROR, "kmalloc of struct dhd_bus failed\n"); goto fail; } - bus->card = card; - bus->cl_devid = (u16) devid; - bus->bus = BRCMF_BUS; + bus->sdiodev = sdiodev; + sdiodev->bus = bus; bus->tx_seq = SDPCM_SEQUENCE_WRAP - 1; bus->usebufpool = false; /* Use bufpool if allocated, else use locally malloced rxbuf */ /* attempt to attach to the dongle */ - if (!(brcmf_sdbrcm_probe_attach(bus, card, regsva, devid))) { - BRCMF_ERROR(("%s: brcmf_sdbrcm_probe_attach failed\n", - __func__)); + if (!(brcmf_sdbrcm_probe_attach(bus, regsva))) { + brcmf_dbg(ERROR, "brcmf_sdbrcm_probe_attach failed\n"); goto fail; } spin_lock_init(&bus->txqlock); init_waitqueue_head(&bus->ctrl_wait); + init_waitqueue_head(&bus->ioctl_resp_wait); /* Set up the watchdog timer */ init_timer(&bus->timer); @@ -5543,48 +4780,43 @@ static void *brcmf_sdbrcm_probe(u16 venid, u16 devid, u16 bus_no, /* Attach to the brcmf/OS/network interface */ bus->drvr = brcmf_attach(bus, SDPCM_RESERVE); if (!bus->drvr) { - BRCMF_ERROR(("%s: brcmf_attach failed\n", __func__)); + brcmf_dbg(ERROR, "brcmf_attach failed\n"); goto fail; } /* Allocate buffers */ - if (!(brcmf_sdbrcm_probe_malloc(bus, card))) { - BRCMF_ERROR(("%s: brcmf_sdbrcm_probe_malloc failed\n", - __func__)); + if (!(brcmf_sdbrcm_probe_malloc(bus))) { + brcmf_dbg(ERROR, "brcmf_sdbrcm_probe_malloc failed\n"); goto fail; } - if (!(brcmf_sdbrcm_probe_init(bus, card))) { - BRCMF_ERROR(("%s: brcmf_sdbrcm_probe_init failed\n", __func__)); + if (!(brcmf_sdbrcm_probe_init(bus))) { + brcmf_dbg(ERROR, "brcmf_sdbrcm_probe_init failed\n"); goto fail; } /* Register interrupt callback, but mask it (not operational yet). */ - BRCMF_INTR(("%s: disable SDIO interrupts (not interested yet)\n", - __func__)); - brcmf_sdcard_intr_disable(card); - ret = brcmf_sdcard_intr_reg(card, brcmf_sdbrcm_isr, bus); + brcmf_dbg(INTR, "disable SDIO interrupts (not interested yet)\n"); + ret = brcmf_sdcard_intr_reg(bus->sdiodev); if (ret != 0) { - BRCMF_ERROR(("%s: FAILED: sdcard_intr_reg returned %d\n", - __func__, ret)); + brcmf_dbg(ERROR, "FAILED: sdcard_intr_reg returned %d\n", ret); goto fail; } - BRCMF_INTR(("%s: registered SDIO interrupt function ok\n", __func__)); + brcmf_dbg(INTR, "registered SDIO interrupt function ok\n"); - BRCMF_INFO(("%s: completed!!\n", __func__)); + brcmf_dbg(INFO, "completed!!\n"); /* if firmware path present try to download and bring up bus */ ret = brcmf_bus_start(bus->drvr); if (ret != 0) { if (ret == -ENOLINK) { - BRCMF_ERROR(("%s: dongle is not responding\n", - __func__)); + brcmf_dbg(ERROR, "dongle is not responding\n"); goto fail; } } /* Ok, have the per-port tell the stack we're open for business */ if (brcmf_net_attach(bus->drvr, 0) != 0) { - BRCMF_ERROR(("%s: Net attach failed!!\n", __func__)); + brcmf_dbg(ERROR, "Net attach failed!!\n"); goto fail; } @@ -5596,22 +4828,22 @@ fail: } static bool -brcmf_sdbrcm_probe_attach(struct brcmf_bus *bus, void *card, u32 regsva, - u16 devid) +brcmf_sdbrcm_probe_attach(struct brcmf_bus *bus, u32 regsva) { u8 clkctl = 0; int err = 0; + int reg_addr; + u32 reg_val; bus->alp_only = true; /* Return the window to backplane enumeration space for core access */ if (brcmf_sdbrcm_set_siaddr_window(bus, SI_ENUM_BASE)) - BRCMF_ERROR(("%s: FAILED to return to SI_ENUM_BASE\n", - __func__)); + brcmf_dbg(ERROR, "FAILED to return to SI_ENUM_BASE\n"); #ifdef BCMDBG printk(KERN_DEBUG "F1 signature read @0x18000000=0x%4x\n", - brcmf_sdcard_reg_read(bus->card, SI_ENUM_BASE, 4)); + brcmf_sdcard_reg_read(bus->sdiodev, SI_ENUM_BASE, 4)); #endif /* BCMDBG */ @@ -5620,56 +4852,53 @@ brcmf_sdbrcm_probe_attach(struct brcmf_bus *bus, void *card, u32 regsva, * programs PLL control regs */ - brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, - BRCMF_INIT_CLKCTL1, &err); + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, + BRCMF_INIT_CLKCTL1, &err); if (!err) clkctl = - brcmf_sdcard_cfg_read(card, SDIO_FUNC_1, + brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, &err); if (err || ((clkctl & ~SBSDIO_AVBITS) != BRCMF_INIT_CLKCTL1)) { - BRCMF_ERROR(("brcmf_sdbrcm_probe: ChipClkCSR access: err %d" - " wrote 0x%02x read 0x%02x\n", - err, BRCMF_INIT_CLKCTL1, clkctl)); + brcmf_dbg(ERROR, "ChipClkCSR access: err %d wrote 0x%02x read 0x%02x\n", + err, BRCMF_INIT_CLKCTL1, clkctl); goto fail; } if (brcmf_sdbrcm_chip_attach(bus, regsva)) { - BRCMF_ERROR(("%s: brcmf_sdbrcm_chip_attach failed!\n", - __func__)); + brcmf_dbg(ERROR, "brcmf_sdbrcm_chip_attach failed!\n"); goto fail; } if (!brcmf_sdbrcm_chipmatch((u16) bus->ci->chip)) { - BRCMF_ERROR(("%s: unsupported chip: 0x%04x\n", - __func__, bus->ci->chip)); + brcmf_dbg(ERROR, "unsupported chip: 0x%04x\n", bus->ci->chip); goto fail; } brcmf_sdbrcm_sdiod_drive_strength_init(bus, brcmf_sdiod_drive_strength); /* Get info on the ARM and SOCRAM cores... */ - if (!BRCMF_NOPMU(bus)) { - brcmf_sdcard_reg_read(bus->card, - CORE_SB(bus->ci->armcorebase, sbidhigh), 4); - bus->orig_ramsize = bus->ci->ramsize; - if (!(bus->orig_ramsize)) { - BRCMF_ERROR(("%s: failed to find SOCRAM memory!\n", - __func__)); - goto fail; - } - bus->ramsize = bus->orig_ramsize; - if (brcmf_dongle_memsize) - brcmf_sdbrcm_setmemsize(bus, brcmf_dongle_memsize); - - BRCMF_ERROR(("DHD: dongle ram size is set to %d(orig %d)\n", - bus->ramsize, bus->orig_ramsize)); + brcmf_sdcard_reg_read(bus->sdiodev, + CORE_SB(bus->ci->armcorebase, sbidhigh), 4); + bus->orig_ramsize = bus->ci->ramsize; + if (!(bus->orig_ramsize)) { + brcmf_dbg(ERROR, "failed to find SOCRAM memory!\n"); + goto fail; } + bus->ramsize = bus->orig_ramsize; + if (brcmf_dongle_memsize) + brcmf_sdbrcm_setmemsize(bus, brcmf_dongle_memsize); + + brcmf_dbg(ERROR, "DHD: dongle ram size is set to %d(orig %d)\n", + bus->ramsize, bus->orig_ramsize); /* Set core control so an SDIO reset does a backplane reset */ - OR_REG(bus->ci->buscorebase + offsetof(struct sdpcmd_regs, - corecontrol), - CC_BPRESEN, u32); + reg_addr = bus->ci->buscorebase + + offsetof(struct sdpcmd_regs, corecontrol); + reg_val = brcmf_sdcard_reg_read(bus->sdiodev, reg_addr, sizeof(u32)); + brcmf_sdcard_reg_write(bus->sdiodev, reg_addr, sizeof(u32), + reg_val | CC_BPRESEN); brcmu_pktq_init(&bus->txq, (PRIOMASK + 1), TXQLEN); @@ -5689,9 +4918,9 @@ fail: return false; } -static bool brcmf_sdbrcm_probe_malloc(struct brcmf_bus *bus, void *card) +static bool brcmf_sdbrcm_probe_malloc(struct brcmf_bus *bus) { - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); if (bus->drvr->maxctl) { bus->rxblen = @@ -5699,8 +4928,8 @@ static bool brcmf_sdbrcm_probe_malloc(struct brcmf_bus *bus, void *card) ALIGNMENT) + BRCMF_SDALIGN; bus->rxbuf = kmalloc(bus->rxblen, GFP_ATOMIC); if (!(bus->rxbuf)) { - BRCMF_ERROR(("%s: kmalloc of %d-byte rxbuf failed\n", - __func__, bus->rxblen)); + brcmf_dbg(ERROR, "kmalloc of %d-byte rxbuf failed\n", + bus->rxblen); goto fail; } } @@ -5708,8 +4937,8 @@ static bool brcmf_sdbrcm_probe_malloc(struct brcmf_bus *bus, void *card) /* Allocate buffer to receive glomed packet */ bus->databuf = kmalloc(MAX_DATA_BUF, GFP_ATOMIC); if (!(bus->databuf)) { - BRCMF_ERROR(("%s: kmalloc of %d-byte databuf failed\n", - __func__, MAX_DATA_BUF)); + brcmf_dbg(ERROR, "kmalloc of %d-byte databuf failed\n", + MAX_DATA_BUF); /* release rxbuf which was already located as above */ if (!bus->rxblen) kfree(bus->rxbuf); @@ -5729,18 +4958,12 @@ fail: return false; } -static bool brcmf_sdbrcm_probe_init(struct brcmf_bus *bus, void *card) +static bool brcmf_sdbrcm_probe_init(struct brcmf_bus *bus) { - s32 fnum; - - BRCMF_TRACE(("%s: Enter\n", __func__)); - -#ifdef SDTEST - brcmf_sdbrcm_pktgen_init(bus); -#endif /* SDTEST */ + brcmf_dbg(TRACE, "Enter\n"); /* Disable F2 to clear any intermediate frame state on the dongle */ - brcmf_sdcard_cfg_write(card, SDIO_FUNC_0, SDIO_CCCR_IOEx, + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_0, SDIO_CCCR_IOEx, SDIO_FUNC_ENABLE_1, NULL); bus->drvr->busstate = BRCMF_BUS_DOWN; @@ -5748,8 +4971,8 @@ static bool brcmf_sdbrcm_probe_init(struct brcmf_bus *bus, void *card) bus->rxflow = false; /* Done with backplane-dependent accesses, can drop clock... */ - brcmf_sdcard_cfg_write(card, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, 0, - NULL); + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); /* ...and initialize clock/power states */ bus->clkstate = CLK_SDONLY; @@ -5757,35 +4980,26 @@ static bool brcmf_sdbrcm_probe_init(struct brcmf_bus *bus, void *card) bus->idleclock = BRCMF_IDLE_ACTIVE; /* Query the F2 block size, set roundup accordingly */ - fnum = 2; - if (brcmf_sdcard_iovar_op(card, "sd_blocksize", &fnum, sizeof(s32), - &bus->blocksize, sizeof(s32), false) != 0) { - bus->blocksize = 0; - BRCMF_ERROR(("%s: fail on %s get\n", __func__, "sd_blocksize")); - } else { - BRCMF_INFO(("%s: Initial value for %s is %d\n", - __func__, "sd_blocksize", bus->blocksize)); - } + bus->blocksize = bus->sdiodev->func[2]->cur_blksize; bus->roundup = min(max_roundup, bus->blocksize); /* Query if bus module supports packet chaining, default to use if supported */ - if (brcmf_sdcard_iovar_op(card, "sd_rxchain", NULL, 0, + if (brcmf_sdcard_iovar_op(bus->sdiodev, "sd_rxchain", NULL, 0, &bus->sd_rxchain, sizeof(s32), - false) != 0) { + false) != 0) bus->sd_rxchain = false; - } else { - BRCMF_INFO(("%s: bus module (through sdiocard API) %s" - " chaining\n", __func__, bus->sd_rxchain - ? "supports" : "does not support")); - } + else + brcmf_dbg(INFO, "bus module (through sdiocard API) %s chaining\n", + bus->sd_rxchain ? "supports" : "does not support"); + bus->use_rxchain = (bool) bus->sd_rxchain; return true; } static bool -brcmf_sdbrcm_download_firmware(struct brcmf_bus *bus, void *card) +brcmf_sdbrcm_download_firmware(struct brcmf_bus *bus) { bool ret; @@ -5802,12 +5016,11 @@ brcmf_sdbrcm_download_firmware(struct brcmf_bus *bus, void *card) /* Detach and free everything */ static void brcmf_sdbrcm_release(struct brcmf_bus *bus) { - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); if (bus) { /* De-register interrupt handler */ - brcmf_sdcard_intr_disable(bus->card); - brcmf_sdcard_intr_dereg(bus->card); + brcmf_sdcard_intr_dereg(bus->sdiodev); if (bus->drvr) { brcmf_detach(bus->drvr); @@ -5820,12 +5033,12 @@ static void brcmf_sdbrcm_release(struct brcmf_bus *bus) kfree(bus); } - BRCMF_TRACE(("%s: Disconnected\n", __func__)); + brcmf_dbg(TRACE, "Disconnected\n"); } static void brcmf_sdbrcm_release_malloc(struct brcmf_bus *bus) { - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); if (bus->drvr && bus->drvr->dongle_reset) return; @@ -5840,7 +5053,7 @@ static void brcmf_sdbrcm_release_malloc(struct brcmf_bus *bus) static void brcmf_sdbrcm_release_dongle(struct brcmf_bus *bus) { - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); if (bus->drvr && bus->drvr->dongle_reset) return; @@ -5854,35 +5067,24 @@ static void brcmf_sdbrcm_release_dongle(struct brcmf_bus *bus) bus->vars = NULL; } - BRCMF_TRACE(("%s: Disconnected\n", __func__)); + brcmf_dbg(TRACE, "Disconnected\n"); } -static void brcmf_sdbrcm_disconnect(void *ptr) +void brcmf_sdbrcm_disconnect(void *ptr) { struct brcmf_bus *bus = (struct brcmf_bus *)ptr; - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); - if (bus) { + if (bus) brcmf_sdbrcm_release(bus); - } - BRCMF_TRACE(("%s: Disconnected\n", __func__)); + brcmf_dbg(TRACE, "Disconnected\n"); } -/* Register/Unregister functions are called by the main DHD entry - * point (e.g. module insertion) to link with the bus driver, in - * order to look for or await the device. - */ - -static struct brcmf_sdioh_driver brcmf_sdio = { - brcmf_sdbrcm_probe, - brcmf_sdbrcm_disconnect -}; - int brcmf_bus_register(void) { - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); /* Sanity check on the module parameters */ do { @@ -5895,16 +5097,16 @@ int brcmf_bus_register(void) && brcmf_deferred_tx) break; - BRCMF_ERROR(("Invalid module parameters.\n")); + brcmf_dbg(ERROR, "Invalid module parameters.\n"); return -EINVAL; } while (0); - return brcmf_sdio_register(&brcmf_sdio); + return brcmf_sdio_register(); } void brcmf_bus_unregister(void) { - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); brcmf_sdio_unregister(); } @@ -5916,22 +5118,21 @@ static int brcmf_sdbrcm_download_code_file(struct brcmf_bus *bus) u8 *memblock = NULL, *memptr; int ret; - BRCMF_INFO(("%s: Enter\n", __func__)); + brcmf_dbg(INFO, "Enter\n"); bus->fw_name = BCM4329_FW_NAME; ret = request_firmware(&bus->firmware, bus->fw_name, - &gInstance->func[2]->dev); + &bus->sdiodev->func[2]->dev); if (ret) { - BRCMF_ERROR(("%s: Fail to request firmware %d\n", - __func__, ret)); + brcmf_dbg(ERROR, "Fail to request firmware %d\n", ret); return ret; } bus->fw_ptr = 0; memptr = memblock = kmalloc(MEMBLOCK + BRCMF_SDALIGN, GFP_ATOMIC); if (memblock == NULL) { - BRCMF_ERROR(("%s: Failed to allocate memory %d bytes\n", - __func__, MEMBLOCK)); + brcmf_dbg(ERROR, "Failed to allocate memory %d bytes\n", + MEMBLOCK); ret = -ENOMEM; goto err; } @@ -5944,9 +5145,8 @@ static int brcmf_sdbrcm_download_code_file(struct brcmf_bus *bus) brcmf_sdbrcm_get_image((char *)memptr, MEMBLOCK, bus))) { ret = brcmf_sdbrcm_membytes(bus, true, offset, memptr, len); if (ret) { - BRCMF_ERROR(("%s: error %d on writing %d membytes at " - "0x%08x\n", __func__, ret, MEMBLOCK, - offset)); + brcmf_dbg(ERROR, "error %d on writing %d membytes at 0x%08x\n", + ret, MEMBLOCK, offset); goto err; } @@ -6022,17 +5222,17 @@ static int brcmf_sdbrcm_download_nvram(struct brcmf_bus *bus) bus->nv_name = BCM4329_NV_NAME; ret = request_firmware(&bus->firmware, bus->nv_name, - &gInstance->func[2]->dev); + &bus->sdiodev->func[2]->dev); if (ret) { - BRCMF_ERROR(("%s: Fail to request nvram %d\n", __func__, ret)); + brcmf_dbg(ERROR, "Fail to request nvram %d\n", ret); return ret; } bus->fw_ptr = 0; memblock = kmalloc(MEMBLOCK, GFP_ATOMIC); if (memblock == NULL) { - BRCMF_ERROR(("%s: Failed to allocate memory %d bytes\n", - __func__, MEMBLOCK)); + brcmf_dbg(ERROR, "Failed to allocate memory %d bytes\n", + MEMBLOCK); ret = -ENOMEM; goto err; } @@ -6048,11 +5248,9 @@ static int brcmf_sdbrcm_download_nvram(struct brcmf_bus *bus) if (len) ret = brcmf_sdbrcm_downloadvars(bus, memblock, len + 1); if (ret) - BRCMF_ERROR(("%s: error downloading vars: %d\n", - __func__, ret)); + brcmf_dbg(ERROR, "error downloading vars: %d\n", ret); } else { - BRCMF_ERROR(("%s: error reading nvram file: %d\n", - __func__, len)); + brcmf_dbg(ERROR, "error reading nvram file: %d\n", len); ret = -EIO; } @@ -6071,28 +5269,23 @@ static int _brcmf_sdbrcm_download_firmware(struct brcmf_bus *bus) /* Keep arm in reset */ if (brcmf_sdbrcm_download_state(bus, true)) { - BRCMF_ERROR(("%s: error placing ARM core in reset\n", - __func__)); + brcmf_dbg(ERROR, "error placing ARM core in reset\n"); goto err; } /* External image takes precedence if specified */ if (brcmf_sdbrcm_download_code_file(bus)) { - BRCMF_ERROR(("%s: dongle image file download failed\n", - __func__)); + brcmf_dbg(ERROR, "dongle image file download failed\n"); goto err; } /* External nvram takes precedence if specified */ - if (brcmf_sdbrcm_download_nvram(bus)) { - BRCMF_ERROR(("%s: dongle nvram file download failed\n", - __func__)); - } + if (brcmf_sdbrcm_download_nvram(bus)) + brcmf_dbg(ERROR, "dongle nvram file download failed\n"); /* Take arm out of reset */ if (brcmf_sdbrcm_download_state(bus, false)) { - BRCMF_ERROR(("%s: error getting out of ARM core reset\n", - __func__)); + brcmf_dbg(ERROR, "error getting out of ARM core reset\n"); goto err; } @@ -6105,14 +5298,10 @@ err: static int brcmf_sdbrcm_send_buf(struct brcmf_bus *bus, 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) + u8 *buf, uint nbytes, struct sk_buff *pkt) { return brcmf_sdcard_send_buf - (bus->card, addr, fn, flags, buf, nbytes, pkt, complete, - handle); + (bus->sdiodev, addr, fn, flags, buf, nbytes, pkt); } int brcmf_bus_devreset(struct brcmf_pub *drvr, u8 flag) @@ -6137,40 +5326,36 @@ int brcmf_bus_devreset(struct brcmf_pub *drvr, u8 flag) bus->drvr->dongle_reset = true; bus->drvr->up = false; - BRCMF_TRACE(("%s: WLAN OFF DONE\n", __func__)); + brcmf_dbg(TRACE, "WLAN OFF DONE\n"); /* App can now remove power from device */ } else bcmerror = -EIO; } else { /* App must have restored power to device before calling */ - BRCMF_TRACE(("\n\n%s: == WLAN ON ==\n", __func__)); + brcmf_dbg(TRACE, " == WLAN ON ==\n"); if (bus->drvr->dongle_reset) { /* Turn on WLAN */ /* Attempt to re-attach & download */ - if (brcmf_sdbrcm_probe_attach(bus, bus->card, - SI_ENUM_BASE, - bus->cl_devid)) { + if (brcmf_sdbrcm_probe_attach(bus, SI_ENUM_BASE)) { /* Attempt to download binary to the dongle */ - if (brcmf_sdbrcm_probe_init(bus, bus->card)) { + if (brcmf_sdbrcm_probe_init(bus)) { /* Re-init bus, enable F2 transfer */ brcmf_sdbrcm_bus_init(bus->drvr, false); bus->drvr->dongle_reset = false; bus->drvr->up = true; - BRCMF_TRACE(("%s: WLAN ON DONE\n", - __func__)); + brcmf_dbg(TRACE, "WLAN ON DONE\n"); } else bcmerror = -EIO; } else bcmerror = -EIO; } else { bcmerror = -EISCONN; - BRCMF_ERROR(("%s: Set DEVRESET=false invoked when" - " device is on\n", __func__)); + brcmf_dbg(ERROR, "Set DEVRESET=false invoked when device is on\n"); bcmerror = -EIO; } brcmf_sdbrcm_wd_timer(bus, brcmf_watchdog_ms); @@ -6179,7 +5364,7 @@ int brcmf_bus_devreset(struct brcmf_pub *drvr, u8 flag) } static int -brcmf_sdbrcm_chip_recognition(struct brcmf_sdio_card *card, +brcmf_sdbrcm_chip_recognition(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, u32 regs) { u32 regdata; @@ -6191,13 +5376,12 @@ brcmf_sdbrcm_chip_recognition(struct brcmf_sdio_card *card, * other ways of recognition should be added here. */ ci->cccorebase = regs; - regdata = brcmf_sdcard_reg_read(card, + regdata = brcmf_sdcard_reg_read(sdiodev, CORE_CC_REG(ci->cccorebase, chipid), 4); ci->chip = regdata & CID_ID_MASK; ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT; - BRCMF_INFO(("%s: chipid=0x%x chiprev=%d\n", - __func__, ci->chip, ci->chiprev)); + brcmf_dbg(INFO, "chipid=0x%x chiprev=%d\n", ci->chip, ci->chiprev); /* Address of cores for new chips should be added here */ switch (ci->chip) { @@ -6208,110 +5392,108 @@ brcmf_sdbrcm_chip_recognition(struct brcmf_sdio_card *card, ci->ramsize = BCM4329_RAMSIZE; break; default: - BRCMF_ERROR(("%s: chipid 0x%x is not supported\n", - __func__, ci->chip)); + brcmf_dbg(ERROR, "chipid 0x%x is not supported\n", ci->chip); return -ENODEV; } - regdata = brcmf_sdcard_reg_read(card, + regdata = brcmf_sdcard_reg_read(sdiodev, CORE_SB(ci->cccorebase, sbidhigh), 4); ci->ccrev = SBCOREREV(regdata); - regdata = brcmf_sdcard_reg_read(card, + regdata = brcmf_sdcard_reg_read(sdiodev, CORE_CC_REG(ci->cccorebase, pmucapabilities), 4); ci->pmurev = regdata & PCAP_REV_MASK; - regdata = brcmf_sdcard_reg_read(card, + regdata = brcmf_sdcard_reg_read(sdiodev, CORE_SB(ci->buscorebase, sbidhigh), 4); ci->buscorerev = SBCOREREV(regdata); ci->buscoretype = (regdata & SBIDH_CC_MASK) >> SBIDH_CC_SHIFT; - BRCMF_INFO(("%s: ccrev=%d, pmurev=%d, buscore rev/type=%d/0x%x\n", - __func__, ci->ccrev, ci->pmurev, - ci->buscorerev, ci->buscoretype)); + brcmf_dbg(INFO, "ccrev=%d, pmurev=%d, buscore rev/type=%d/0x%x\n", + ci->ccrev, ci->pmurev, ci->buscorerev, ci->buscoretype); /* get chipcommon capabilites */ - ci->cccaps = brcmf_sdcard_reg_read(card, + ci->cccaps = brcmf_sdcard_reg_read(sdiodev, CORE_CC_REG(ci->cccorebase, capabilities), 4); return 0; } static void -brcmf_sdbrcm_chip_disablecore(struct brcmf_sdio_card *card, u32 corebase) +brcmf_sdbrcm_chip_disablecore(struct brcmf_sdio_dev *sdiodev, u32 corebase) { u32 regdata; - regdata = brcmf_sdcard_reg_read(card, + regdata = brcmf_sdcard_reg_read(sdiodev, CORE_SB(corebase, sbtmstatelow), 4); if (regdata & SBTML_RESET) return; - regdata = brcmf_sdcard_reg_read(card, + regdata = brcmf_sdcard_reg_read(sdiodev, CORE_SB(corebase, sbtmstatelow), 4); if ((regdata & (SICF_CLOCK_EN << SBTML_SICF_SHIFT)) != 0) { /* * set target reject and spin until busy is clear * (preserve core-specific bits) */ - regdata = brcmf_sdcard_reg_read(card, + regdata = brcmf_sdcard_reg_read(sdiodev, CORE_SB(corebase, sbtmstatelow), 4); - brcmf_sdcard_reg_write(card, CORE_SB(corebase, sbtmstatelow), 4, - regdata | SBTML_REJ); + brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow), + 4, regdata | SBTML_REJ); - regdata = brcmf_sdcard_reg_read(card, + regdata = brcmf_sdcard_reg_read(sdiodev, CORE_SB(corebase, sbtmstatelow), 4); udelay(1); - SPINWAIT((brcmf_sdcard_reg_read(card, + SPINWAIT((brcmf_sdcard_reg_read(sdiodev, CORE_SB(corebase, sbtmstatehigh), 4) & SBTMH_BUSY), 100000); - regdata = brcmf_sdcard_reg_read(card, + regdata = brcmf_sdcard_reg_read(sdiodev, CORE_SB(corebase, sbtmstatehigh), 4); if (regdata & SBTMH_BUSY) - BRCMF_ERROR(("%s: ARM core still busy\n", __func__)); + brcmf_dbg(ERROR, "ARM core still busy\n"); - regdata = brcmf_sdcard_reg_read(card, + regdata = brcmf_sdcard_reg_read(sdiodev, CORE_SB(corebase, sbidlow), 4); if (regdata & SBIDL_INIT) { - regdata = brcmf_sdcard_reg_read(card, + regdata = brcmf_sdcard_reg_read(sdiodev, CORE_SB(corebase, sbimstate), 4) | SBIM_RJ; - brcmf_sdcard_reg_write(card, + brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbimstate), 4, regdata); - regdata = brcmf_sdcard_reg_read(card, + regdata = brcmf_sdcard_reg_read(sdiodev, CORE_SB(corebase, sbimstate), 4); udelay(1); - SPINWAIT((brcmf_sdcard_reg_read(card, + SPINWAIT((brcmf_sdcard_reg_read(sdiodev, CORE_SB(corebase, sbimstate), 4) & SBIM_BY), 100000); } /* set reset and reject while enabling the clocks */ - brcmf_sdcard_reg_write(card, + brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow), 4, (((SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) | SBTML_REJ | SBTML_RESET)); - regdata = brcmf_sdcard_reg_read(card, + regdata = brcmf_sdcard_reg_read(sdiodev, CORE_SB(corebase, sbtmstatelow), 4); udelay(10); /* clear the initiator reject bit */ - regdata = brcmf_sdcard_reg_read(card, + regdata = brcmf_sdcard_reg_read(sdiodev, CORE_SB(corebase, sbidlow), 4); if (regdata & SBIDL_INIT) { - regdata = brcmf_sdcard_reg_read(card, + regdata = brcmf_sdcard_reg_read(sdiodev, CORE_SB(corebase, sbimstate), 4) & ~SBIM_RJ; - brcmf_sdcard_reg_write(card, + brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbimstate), 4, regdata); } } /* leave reset and reject asserted */ - brcmf_sdcard_reg_write(card, CORE_SB(corebase, sbtmstatelow), 4, + brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow), 4, (SBTML_REJ | SBTML_RESET)); udelay(1); } @@ -6323,62 +5505,60 @@ brcmf_sdbrcm_chip_attach(struct brcmf_bus *bus, u32 regs) int err; u8 clkval, clkset; - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); /* alloc chip_info_t */ - ci = kmalloc(sizeof(struct chip_info), GFP_ATOMIC); + ci = kzalloc(sizeof(struct chip_info), GFP_ATOMIC); if (NULL == ci) { - BRCMF_ERROR(("%s: malloc failed!\n", __func__)); + brcmf_dbg(ERROR, "malloc failed!\n"); return -ENOMEM; } - memset((unsigned char *)ci, 0, sizeof(struct chip_info)); - /* bus/core/clk setup for register access */ /* Try forcing SDIO core to do ALPAvail request only */ clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ; - brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, - clkset, &err); + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err); if (err) { - BRCMF_ERROR(("%s: error writing for HT off\n", __func__)); + brcmf_dbg(ERROR, "error writing for HT off\n"); goto fail; } /* If register supported, wait for ALPAvail and then force ALP */ /* This may take up to 15 milliseconds */ - clkval = brcmf_sdcard_cfg_read(bus->card, SDIO_FUNC_1, + clkval = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, NULL); if ((clkval & ~SBSDIO_AVBITS) == clkset) { SPINWAIT(((clkval = - brcmf_sdcard_cfg_read(bus->card, SDIO_FUNC_1, + brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, NULL)), !SBSDIO_ALPAV(clkval)), PMU_MAX_TRANSITION_DLY); if (!SBSDIO_ALPAV(clkval)) { - BRCMF_ERROR(("%s: timeout on ALPAV wait," - " clkval 0x%02x\n", __func__, clkval)); + brcmf_dbg(ERROR, "timeout on ALPAV wait, clkval 0x%02x\n", + clkval); err = -EBUSY; goto fail; } clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP; - brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_1, + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err); udelay(65); } else { - BRCMF_ERROR(("%s: ChipClkCSR access: wrote 0x%02x" - " read 0x%02x\n", __func__, clkset, clkval)); + brcmf_dbg(ERROR, "ChipClkCSR access: wrote 0x%02x read 0x%02x\n", + clkset, clkval); err = -EACCES; goto fail; } /* Also, disable the extra SDIO pull-ups */ - brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_1, SBSDIO_FUNC1_SDIOPULLUP, - 0, NULL); + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, + SBSDIO_FUNC1_SDIOPULLUP, 0, NULL); - err = brcmf_sdbrcm_chip_recognition(bus->card, ci, regs); + err = brcmf_sdbrcm_chip_recognition(bus->sdiodev, ci, regs); if (err) goto fail; @@ -6386,24 +5566,24 @@ brcmf_sdbrcm_chip_attach(struct brcmf_bus *bus, u32 regs) * Make sure any on-chip ARM is off (in case strapping is wrong), * or downloaded code was already running. */ - brcmf_sdbrcm_chip_disablecore(bus->card, ci->armcorebase); + brcmf_sdbrcm_chip_disablecore(bus->sdiodev, ci->armcorebase); - brcmf_sdcard_reg_write(bus->card, + brcmf_sdcard_reg_write(bus->sdiodev, CORE_CC_REG(ci->cccorebase, gpiopullup), 4, 0); - brcmf_sdcard_reg_write(bus->card, + brcmf_sdcard_reg_write(bus->sdiodev, CORE_CC_REG(ci->cccorebase, gpiopulldown), 4, 0); /* Disable F2 to clear any intermediate frame state on the dongle */ - brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_0, SDIO_CCCR_IOEx, + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_0, SDIO_CCCR_IOEx, SDIO_FUNC_ENABLE_1, NULL); /* WAR: cmd52 backplane read so core HW will drop ALPReq */ - clkval = brcmf_sdcard_cfg_read(bus->card, SDIO_FUNC_1, + clkval = brcmf_sdcard_cfg_read(bus->sdiodev, SDIO_FUNC_1, 0, NULL); /* Done with backplane-dependent accesses, can drop clock... */ - brcmf_sdcard_cfg_write(bus->card, SDIO_FUNC_1, SBSDIO_FUNC1_CHIPCLKCSR, - 0, NULL); + brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, + SBSDIO_FUNC1_CHIPCLKCSR, 0, NULL); bus->ci = ci; return 0; @@ -6414,7 +5594,7 @@ fail: } static void -brcmf_sdbrcm_chip_resetcore(struct brcmf_sdio_card *card, u32 corebase) +brcmf_sdbrcm_chip_resetcore(struct brcmf_sdio_dev *sdiodev, u32 corebase) { u32 regdata; @@ -6422,37 +5602,38 @@ brcmf_sdbrcm_chip_resetcore(struct brcmf_sdio_card *card, u32 corebase) * Must do the disable sequence first to work for * arbitrary current core state. */ - brcmf_sdbrcm_chip_disablecore(card, corebase); + brcmf_sdbrcm_chip_disablecore(sdiodev, corebase); /* * Now do the initialization sequence. * set reset while enabling the clock and * forcing them on throughout the core */ - brcmf_sdcard_reg_write(card, CORE_SB(corebase, sbtmstatelow), 4, + brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow), 4, ((SICF_FGC | SICF_CLOCK_EN) << SBTML_SICF_SHIFT) | SBTML_RESET); udelay(1); - regdata = brcmf_sdcard_reg_read(card, CORE_SB(corebase, sbtmstatehigh), - 4); + regdata = brcmf_sdcard_reg_read(sdiodev, + CORE_SB(corebase, sbtmstatehigh), 4); if (regdata & SBTMH_SERR) - brcmf_sdcard_reg_write(card, CORE_SB(corebase, sbtmstatehigh), - 4, 0); + brcmf_sdcard_reg_write(sdiodev, + CORE_SB(corebase, sbtmstatehigh), 4, 0); - regdata = brcmf_sdcard_reg_read(card, CORE_SB(corebase, sbimstate), 4); + regdata = brcmf_sdcard_reg_read(sdiodev, + CORE_SB(corebase, sbimstate), 4); if (regdata & (SBIM_IBE | SBIM_TO)) - brcmf_sdcard_reg_write(card, CORE_SB(corebase, sbimstate), 4, + brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbimstate), 4, regdata & ~(SBIM_IBE | SBIM_TO)); /* clear reset and allow it to propagate throughout the core */ - brcmf_sdcard_reg_write(card, CORE_SB(corebase, sbtmstatelow), 4, + brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow), 4, (SICF_FGC << SBTML_SICF_SHIFT) | (SICF_CLOCK_EN << SBTML_SICF_SHIFT)); udelay(1); /* leave clock enabled */ - brcmf_sdcard_reg_write(card, CORE_SB(corebase, sbtmstatelow), 4, + brcmf_sdcard_reg_write(sdiodev, CORE_SB(corebase, sbtmstatelow), 4, (SICF_CLOCK_EN << SBTML_SICF_SHIFT)); udelay(1); } @@ -6499,8 +5680,8 @@ static const struct sdiod_drive_str sdiod_drive_strength_tab3[] = { #define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu)) -static void -brcmf_sdbrcm_sdiod_drive_strength_init(struct brcmf_bus *bus, u32 drivestrength) { +static void brcmf_sdbrcm_sdiod_drive_strength_init(struct brcmf_bus *bus, + u32 drivestrength) { struct sdiod_drive_str *str_tab = NULL; u32 str_mask = 0; u32 str_shift = 0; @@ -6527,10 +5708,9 @@ brcmf_sdbrcm_sdiod_drive_strength_init(struct brcmf_bus *bus, u32 drivestrength) str_shift = 11; break; default: - BRCMF_ERROR(("No SDIO Drive strength init" - "done for chip %s rev %d pmurev %d\n", - brcmu_chipname(bus->ci->chip, chn, 8), - bus->ci->chiprev, bus->ci->pmurev)); + brcmf_dbg(ERROR, "No SDIO Drive strength init done for chip %s rev %d pmurev %d\n", + brcmu_chipname(bus->ci->chip, chn, 8), + bus->ci->chiprev, bus->ci->pmurev); break; } @@ -6546,27 +5726,27 @@ brcmf_sdbrcm_sdiod_drive_strength_init(struct brcmf_bus *bus, u32 drivestrength) } } - brcmf_sdcard_reg_write(bus->card, + brcmf_sdcard_reg_write(bus->sdiodev, CORE_CC_REG(bus->ci->cccorebase, chipcontrol_addr), 4, 1); - cc_data_temp = brcmf_sdcard_reg_read(bus->card, + cc_data_temp = brcmf_sdcard_reg_read(bus->sdiodev, CORE_CC_REG(bus->ci->cccorebase, chipcontrol_addr), 4); cc_data_temp &= ~str_mask; drivestrength_sel <<= str_shift; cc_data_temp |= drivestrength_sel; - brcmf_sdcard_reg_write(bus->card, + brcmf_sdcard_reg_write(bus->sdiodev, CORE_CC_REG(bus->ci->cccorebase, chipcontrol_addr), 4, cc_data_temp); - BRCMF_INFO(("SDIO: %dmA drive strength selected, " - "set to 0x%08x\n", drivestrength, cc_data_temp)); + brcmf_dbg(INFO, "SDIO: %dmA drive strength selected, set to 0x%08x\n", + drivestrength, cc_data_temp); } } static void brcmf_sdbrcm_chip_detach(struct brcmf_bus *bus) { - BRCMF_TRACE(("%s: Enter\n", __func__)); + brcmf_dbg(TRACE, "Enter\n"); kfree(bus->ci); bus->ci = NULL; @@ -6770,3 +5950,33 @@ static int brcmf_sdbrcm_get_image(char *buf, int len, struct brcmf_bus *bus) MODULE_FIRMWARE(BCM4329_FW_NAME); MODULE_FIRMWARE(BCM4329_NV_NAME); + +static int brcmf_sdbrcm_ioctl_resp_wait(struct brcmf_bus *bus, uint *condition, + bool *pending) +{ + DECLARE_WAITQUEUE(wait, current); + int timeout = msecs_to_jiffies(brcmf_ioctl_timeout_msec); + + /* Wait until control frame is available */ + add_wait_queue(&bus->ioctl_resp_wait, &wait); + set_current_state(TASK_INTERRUPTIBLE); + + while (!(*condition) && (!signal_pending(current) && timeout)) + timeout = schedule_timeout(timeout); + + if (signal_pending(current)) + *pending = true; + + set_current_state(TASK_RUNNING); + remove_wait_queue(&bus->ioctl_resp_wait, &wait); + + return timeout; +} + +static int brcmf_sdbrcm_ioctl_resp_wake(struct brcmf_bus *bus) +{ + if (waitqueue_active(&bus->ioctl_resp_wait)) + wake_up_interruptible(&bus->ioctl_resp_wait); + + return 0; +} diff --git a/drivers/staging/brcm80211/brcmfmac/sdio_host.h b/drivers/staging/brcm80211/brcmfmac/sdio_host.h index d345472..03ae16a 100644 --- a/drivers/staging/brcm80211/brcmfmac/sdio_host.h +++ b/drivers/staging/brcm80211/brcmfmac/sdio_host.h @@ -18,7 +18,6 @@ #define _BRCM_SDH_H_ #include <linux/skbuff.h> -extern const uint brcmf_sdio_msglevel; #define SDIO_FUNC_0 0 #define SDIO_FUNC_1 1 @@ -41,46 +40,71 @@ extern const uint brcmf_sdio_msglevel; /* Maximum number of I/O funcs */ #define SDIOD_MAX_IOFUNCS 7 -#define SBSDIO_NUM_FUNCTION 3 /* as of sdiod rev 0, supports 3 functions */ +/* as of sdiod rev 0, supports 3 functions */ +#define SBSDIO_NUM_FUNCTION 3 /* 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 */ + +/* sprom command and status */ +#define SBSDIO_SPROM_CS 0x10000 +/* sprom info register */ +#define SBSDIO_SPROM_INFO 0x10001 +/* sprom indirect access data byte 0 */ +#define SBSDIO_SPROM_DATA_LOW 0x10002 +/* sprom indirect access data byte 1 */ +#define SBSDIO_SPROM_DATA_HIGH 0x10003 +/* sprom indirect access addr byte 0 */ +#define SBSDIO_SPROM_ADDR_LOW 0x10004 +/* sprom indirect access addr byte 0 */ +#define SBSDIO_SPROM_ADDR_HIGH 0x10005 +/* xtal_pu (gpio) output */ +#define SBSDIO_CHIP_CTRL_DATA 0x10006 +/* xtal_pu (gpio) enable */ +#define SBSDIO_CHIP_CTRL_EN 0x10007 +/* rev < 7, watermark for sdio device */ +#define SBSDIO_WATERMARK 0x10008 +/* control busy signal generation */ +#define SBSDIO_DEVICE_CTL 0x10009 + +/* SB Address Window Low (b15) */ +#define SBSDIO_FUNC1_SBADDRLOW 0x1000A +/* SB Address Window Mid (b23:b16) */ +#define SBSDIO_FUNC1_SBADDRMID 0x1000B +/* SB Address Window High (b31:b24) */ +#define SBSDIO_FUNC1_SBADDRHIGH 0x1000C +/* Frame Control (frame term/abort) */ +#define SBSDIO_FUNC1_FRAMECTRL 0x1000D +/* ChipClockCSR (ALP/HT ctl/status) */ +#define SBSDIO_FUNC1_CHIPCLKCSR 0x1000E +/* SdioPullUp (on cmd, d0-d2) */ +#define SBSDIO_FUNC1_SDIOPULLUP 0x1000F +/* Write Frame Byte Count Low */ +#define SBSDIO_FUNC1_WFRAMEBCLO 0x10019 +/* Write Frame Byte Count High */ +#define SBSDIO_FUNC1_WFRAMEBCHI 0x1001A +/* Read Frame Byte Count Low */ +#define SBSDIO_FUNC1_RFRAMEBCLO 0x1001B +/* Read Frame Byte Count High */ +#define SBSDIO_FUNC1_RFRAMEBCHI 0x1001C #define SBSDIO_FUNC1_MISC_REG_START 0x10000 /* f1 misc register start */ #define SBSDIO_FUNC1_MISC_REG_LIMIT 0x1001C /* f1 misc register end */ /* function 1 OCP space */ -#define SBSDIO_SB_OFT_ADDR_MASK 0x07FFF /* sb offset addr is <= 15 bits, 32k */ + +/* sb offset addr is <= 15 bits, 32k */ +#define SBSDIO_SB_OFT_ADDR_MASK 0x07FFF #define SBSDIO_SB_OFT_ADDR_LIMIT 0x08000 -#define SBSDIO_SB_ACCESS_2_4B_FLAG 0x08000 /* with b15, maps to 32-bit SB access */ +/* with b15, maps to 32-bit SB access */ +#define SBSDIO_SB_ACCESS_2_4B_FLAG 0x08000 -/* 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 */ +/* Address bits from SBADDR regs */ +#define SBSDIO_SBWINDOW_MASK 0xffff8000 #define SDIOH_READ 0 /* Read request */ #define SDIOH_WRITE 1 /* Write request */ @@ -92,68 +116,27 @@ extern const uint brcmf_sdio_msglevel; #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; +struct brcmf_sdio_dev { + struct sdio_func *func[SDIO_MAX_FUNCS]; + u8 num_funcs; /* Supported funcs on client */ u32 func_cis_ptr[SDIOD_MAX_IOFUNCS]; - uint max_dma_len; - uint max_dma_descriptors; /* DMA Descriptors supported by this controller. */ - /* SDDMA_DESCRIPTOR SGList[32]; *//* Scatter/Gather DMA List */ + u32 sbwad; /* Save backplane window address */ + bool regfail; /* status of last reg_r/w call */ + void *bus; + atomic_t suspend; /* suspend flag */ }; -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); +brcmf_sdcard_intr_reg(struct brcmf_sdio_dev *sdiodev); -extern int brcmf_sdcard_intr_dereg(struct brcmf_sdio_card *card); +extern int brcmf_sdcard_intr_dereg(struct brcmf_sdio_dev *sdiodev); /* Access SDIO address space (e.g. CCCR) using CMD52 (single-byte interface). * fn: function number @@ -161,20 +144,11 @@ extern int brcmf_sdcard_intr_dereg(struct brcmf_sdio_card *card); * 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, +extern u8 brcmf_sdcard_cfg_read(struct brcmf_sdio_dev *sdiodev, uint func, u32 addr, int *err); -extern void brcmf_sdcard_cfg_write(struct brcmf_sdio_card *card, uint func, +extern void brcmf_sdcard_cfg_write(struct brcmf_sdio_dev *sdiodev, 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 @@ -182,7 +156,7 @@ extern void brcmf_sdcard_cfg_write_word(struct brcmf_sdio_card *card, * 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, +extern int brcmf_sdcard_cis_read(struct brcmf_sdio_dev *sdiodev, uint func, u8 *cis, uint length); /* Synchronous access to device (client) core registers via CMD53 to F1. @@ -191,14 +165,14 @@ extern int brcmf_sdcard_cis_read(struct brcmf_sdio_card *card, uint func, * data: data for register write */ extern u32 -brcmf_sdcard_reg_read(struct brcmf_sdio_card *card, u32 addr, uint size); +brcmf_sdcard_reg_read(struct brcmf_sdio_dev *sdiodev, u32 addr, uint size); extern u32 -brcmf_sdcard_reg_write(struct brcmf_sdio_card *card, u32 addr, uint size, +brcmf_sdcard_reg_write(struct brcmf_sdio_dev *sdiodev, u32 addr, uint size, u32 data); /* Indicate if last reg read/write failed */ -extern bool brcmf_sdcard_regfail(struct brcmf_sdio_card *card); +extern bool brcmf_sdcard_regfail(struct brcmf_sdio_dev *sdiodev); /* Buffer transfer to/from device (client) core via cmd53. * fn: function number @@ -213,22 +187,20 @@ extern bool brcmf_sdcard_regfail(struct brcmf_sdio_card *card); * 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); +brcmf_sdcard_send_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, + uint flags, u8 *buf, uint nbytes, struct sk_buff *pkt); extern int -brcmf_sdcard_recv_buf(struct brcmf_sdio_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); +brcmf_sdcard_recv_buf(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn, + uint flags, u8 *buf, uint nbytes, struct sk_buff *pkt); /* Flags bits */ -#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) */ + +/* Four-byte target (backplane) width (vs. two-byte) */ +#define SDIO_REQ_4BYTE 0x1 +/* Fixed address (FIFO) (vs. incrementing address) */ +#define SDIO_REQ_FIXED 0x2 +/* Async request (vs. sync request) */ +#define SDIO_REQ_ASYNC 0x4 /* Pending (non-error) return code */ #define BCME_PENDING 1 @@ -240,108 +212,64 @@ brcmf_sdcard_recv_buf(struct brcmf_sdio_card *card, u32 addr, uint fn, * 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); +extern int brcmf_sdcard_rwdata(struct brcmf_sdio_dev *sdiodev, uint rw, + u32 addr, u8 *buf, uint nbytes); /* Issue an abort to the specified function */ -extern int brcmf_sdcard_abort(struct brcmf_sdio_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); +extern int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn); /* 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; +extern int brcmf_sdcard_iovar_op(struct brcmf_sdio_dev *sdiodev, + const char *name, void *params, int plen, + void *arg, int len, bool set); /* platform specific/high level functions */ extern int brcmf_sdio_function_init(void); -extern int brcmf_sdio_register(struct brcmf_sdioh_driver *driver); +extern int brcmf_sdio_register(void); 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); +extern int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev); +extern int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev); /* 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); +extern u32 brcmf_sdcard_cur_sbwad(struct brcmf_sdio_dev *sdiodev); /* 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); +extern int brcmf_sdioh_attach(struct brcmf_sdio_dev *sdiodev); +extern void brcmf_sdioh_detach(struct brcmf_sdio_dev *sdiodev); /* read or write one byte using cmd52 */ -extern int -brcmf_sdioh_request_byte(struct sdioh_info *si, uint rw, uint fnc, uint addr, - u8 *byte); +extern int brcmf_sdioh_request_byte(struct brcmf_sdio_dev *sdiodev, uint rw, + uint fnc, uint addr, u8 *byte); /* read or write 2/4 bytes using cmd53 */ extern int -brcmf_sdioh_request_word(struct sdioh_info *si, uint cmd_type, +brcmf_sdioh_request_word(struct brcmf_sdio_dev *sdiodev, 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, +brcmf_sdioh_request_buffer(struct brcmf_sdio_dev *sdiodev, 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); +extern int brcmf_sdioh_cis_read(struct brcmf_sdio_dev *sdiodev, uint fuc, + u8 *cis, u32 length); /* Watchdog timer interface for pm ops */ -extern void brcmf_sdio_wdtmr_enable(bool enable); - -extern uint sd_msglevel; /* Debug message level */ +extern void brcmf_sdio_wdtmr_enable(struct brcmf_sdio_dev *sdiodev, + bool enable); -extern struct brcmf_sdmmc_instance *gInstance; +extern uint sd_f2_blocksize; +extern void *brcmf_sdbrcm_probe(u16 bus_no, u16 slot, u16 func, uint bustype, + u32 regsva, struct brcmf_sdio_dev *sdiodev); +extern void brcmf_sdbrcm_disconnect(void *ptr); +extern void brcmf_sdbrcm_isr(void *arg); #endif /* _BRCM_SDH_H_ */ diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c index 821206d..9010ce7 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c @@ -20,8 +20,8 @@ #include <linux/kthread.h> #include <linux/netdevice.h> #include <linux/sched.h> +#include <linux/bitops.h> #include <linux/etherdevice.h> -#include <linux/wireless.h> #include <linux/ieee80211.h> #include <linux/mmc/sdio_func.h> #include <linux/uaccess.h> @@ -118,7 +118,7 @@ static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el); static struct brcmf_cfg80211_event_q * brcmf_deq_event(struct brcmf_cfg80211_priv *cfg_priv); static s32 brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 type, - const struct brcmf_event_msg *msg, void *data); + const struct brcmf_event_msg *msg); static void brcmf_put_event(struct brcmf_cfg80211_event_q *e); static void brcmf_wakeup_event(struct brcmf_cfg80211_priv *cfg_priv); static s32 brcmf_notify_connect_status(struct brcmf_cfg80211_priv *cfg_priv, @@ -135,11 +135,11 @@ static s32 brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv, void *data); static s32 brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv, struct net_device *ndev, - const struct brcmf_event_msg *e, void *data, + const struct brcmf_event_msg *e, bool completed); static s32 brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv, struct net_device *ndev, - const struct brcmf_event_msg *e, void *data); + const struct brcmf_event_msg *e); static s32 brcmf_notify_mic_status(struct brcmf_cfg80211_priv *cfg_priv, struct net_device *ndev, const struct brcmf_event_msg *e, void *data); @@ -216,8 +216,8 @@ static s32 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *dev, /* ** key indianess swap utilities */ -static void swap_key_from_BE(struct brcmf_wsec_key *key); -static void swap_key_to_BE(struct brcmf_wsec_key *key); +static void convert_key_from_CPU(struct brcmf_wsec_key *key); +static void convert_key_to_CPU(struct brcmf_wsec_key *key); /* ** brcmf_cfg80211_priv memory init/deinit utilities @@ -295,11 +295,6 @@ static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_priv *cfg_priv); static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_priv *cfg_priv); /* -* find most significant bit set -*/ -static __used u32 brcmf_find_msb(u16 bit16); - -/* * update pmklist to dongle */ static __used s32 brcmf_update_pmklist(struct net_device *dev, @@ -510,7 +505,7 @@ static const u32 __wl_cipher_suites[] = { WLAN_CIPHER_SUITE_AES_CMAC, }; -static void swap_key_from_BE(struct brcmf_wsec_key *key) +static void convert_key_from_CPU(struct brcmf_wsec_key *key) { key->index = cpu_to_le32(key->index); key->len = cpu_to_le32(key->len); @@ -521,7 +516,7 @@ static void swap_key_from_BE(struct brcmf_wsec_key *key) key->iv_initialized = cpu_to_le32(key->iv_initialized); } -static void swap_key_to_BE(struct brcmf_wsec_key *key) +static void convert_key_to_CPU(struct brcmf_wsec_key *key) { key->index = le32_to_cpu(key->index); key->len = le32_to_cpu(key->len); @@ -677,12 +672,12 @@ brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan, err = brcmf_dev_iovar_setbuf(iscan->dev, "iscan", params, params_size, iscan->ioctl_buf, BRCMF_C_IOCTL_SMLEN); if (unlikely(err)) { - if (err == -EBUSY) { + if (err == -EBUSY) WL_INFO("system busy : iscan canceled\n"); - } else { + else WL_ERR("error (%d)\n", err); - } } + kfree(params); return err; } @@ -709,10 +704,14 @@ static s32 brcmf_do_iscan(struct brcmf_cfg80211_priv *cfg_priv) } brcmf_set_mpc(ndev, 0); cfg_priv->iscan_kickstart = true; - brcmf_run_iscan(iscan, &ssid, BRCMF_SCAN_ACTION_START); + err = brcmf_run_iscan(iscan, &ssid, BRCMF_SCAN_ACTION_START); + if (err) { + brcmf_set_mpc(ndev, 1); + cfg_priv->iscan_kickstart = false; + return err; + } mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000); iscan->timer_on = 1; - return err; } @@ -790,12 +789,12 @@ __brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, err = brcmf_dev_ioctl(ndev, BRCMF_C_SCAN, &sr->ssid, sizeof(sr->ssid)); if (err) { - if (err == -EBUSY) { - WL_INFO("system busy : scan for \"%s\" canceled\n", - sr->ssid.SSID); - } else { + if (err == -EBUSY) + WL_INFO("system busy : scan for \"%s\" " + "canceled\n", sr->ssid.SSID); + else WL_ERR("WLC_SCAN error (%d)\n", err); - } + brcmf_set_mpc(ndev, 1); goto scan_out; } @@ -1049,6 +1048,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, } else { memcpy(join_params.params.bssid, ether_bcast, ETH_ALEN); } + brcmf_update_prof(cfg_priv, NULL, &join_params.params.bssid, WL_PROF_BSSID); @@ -1093,7 +1093,8 @@ done: return err; } -static s32 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) +static s32 +brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev) { struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); s32 err = 0; @@ -1108,8 +1109,8 @@ static s32 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev return err; } -static s32 -brcmf_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme) +static s32 brcmf_set_wpa_version(struct net_device *dev, + struct cfg80211_connect_params *sme) { struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(dev); struct brcmf_cfg80211_security *sec; @@ -1173,7 +1174,8 @@ brcmf_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme) } static s32 -brcmf_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme) +brcmf_set_set_cipher(struct net_device *dev, + struct cfg80211_connect_params *sme) { struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(dev); struct brcmf_cfg80211_security *sec; @@ -1338,7 +1340,7 @@ brcmf_set_set_sharedkey(struct net_device *dev, WL_CONN("key length (%d) key index (%d) algo (%d)\n", key.len, key.index, key.algo); WL_CONN("key \"%s\"\n", key.data); - swap_key_from_BE(&key); + convert_key_from_CPU(&key); err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY, &key, sizeof(key)); if (unlikely(err)) { @@ -1420,28 +1422,20 @@ brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, goto done; } - brcmf_update_prof(cfg_priv, NULL, sme->bssid, WL_PROF_BSSID); - /* - ** Join with specific BSSID and cached SSID - ** If SSID is zero join based on BSSID only - */ memset(&join_params, 0, sizeof(join_params)); join_params_size = sizeof(join_params.ssid); - join_params.ssid.SSID_len = min(sizeof(join_params.ssid.SSID), sme->ssid_len); + join_params.ssid.SSID_len = + min(sizeof(join_params.ssid.SSID), sme->ssid_len); memcpy(&join_params.ssid.SSID, sme->ssid, join_params.ssid.SSID_len); join_params.ssid.SSID_len = cpu_to_le32(join_params.ssid.SSID_len); brcmf_update_prof(cfg_priv, NULL, &join_params.ssid, WL_PROF_SSID); - if (sme->bssid) - memcpy(join_params.params.bssid, sme->bssid, ETH_ALEN); - else - memcpy(join_params.params.bssid, ether_bcast, ETH_ALEN); + memcpy(join_params.params.bssid, ether_bcast, ETH_ALEN); - if (join_params.ssid.SSID_len < IEEE80211_MAX_SSID_LEN) { + if (join_params.ssid.SSID_len < IEEE80211_MAX_SSID_LEN) WL_CONN("ssid \"%s\", len (%d)\n", join_params.ssid.SSID, join_params.ssid.SSID_len); - } brcmf_ch_to_chanspec(cfg_priv->channel, &join_params, &join_params_size); @@ -1519,7 +1513,8 @@ brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, /* Make sure radio is off or on as far as software is concerned */ disable = WL_RADIO_SW_DISABLE << 16; disable = cpu_to_le32(disable); - err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_RADIO, &disable, sizeof(disable)); + err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_RADIO, &disable, + sizeof(disable)); if (unlikely(err)) WL_ERR("WLC_SET_RADIO error (%d)\n", err); @@ -1613,7 +1608,7 @@ brcmf_add_keyext(struct wiphy *wiphy, struct net_device *dev, /* check for key index change */ if (key.len == 0) { /* key delete */ - swap_key_from_BE(&key); + convert_key_from_CPU(&key); err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY, &key, sizeof(key)); if (unlikely(err)) { WL_ERR("key delete error (%d)\n", err); @@ -1671,7 +1666,7 @@ brcmf_add_keyext(struct wiphy *wiphy, struct net_device *dev, WL_ERR("Invalid cipher (0x%x)\n", params->cipher); return -EINVAL; } - swap_key_from_BE(&key); + convert_key_from_CPU(&key); brcmf_netdev_wait_pend8021x(dev); err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY, &key, sizeof(key)); @@ -1746,7 +1741,7 @@ brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, } /* Set the new key/index */ - swap_key_from_BE(&key); + convert_key_from_CPU(&key); err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY, &key, sizeof(key)); if (unlikely(err)) { WL_ERR("WLC_SET_KEY error (%d)\n", err); @@ -1796,7 +1791,7 @@ brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev, WL_CONN("key index (%d)\n", key_idx); /* Set the new key/index */ - swap_key_from_BE(&key); + convert_key_from_CPU(&key); err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY, &key, sizeof(key)); if (unlikely(err)) { if (err == -EINVAL) { @@ -1860,7 +1855,7 @@ brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev, memset(&key, 0, sizeof(key)); key.index = key_idx; - swap_key_to_BE(&key); + convert_key_to_CPU(&key); memset(¶ms, 0, sizeof(params)); params.key_len = (u8) min_t(u8, WLAN_MAX_KEY_LEN, key.len); memcpy(params.key, key.data, params.key_len); @@ -1954,9 +1949,9 @@ brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, scb_val.val = 0; err = brcmf_dev_ioctl(dev, BRCMF_C_GET_RSSI, &scb_val, sizeof(struct brcmf_scb_val)); - if (unlikely(err)) { + if (unlikely(err)) WL_ERR("Could not get rssi (%d)\n", err); - } + rssi = le32_to_cpu(scb_val.val); sinfo->filled |= STATION_INFO_SIGNAL; sinfo->signal = rssi; @@ -1974,9 +1969,24 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, { s32 pm; s32 err = 0; + struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); WL_TRACE("Enter\n"); - CHECK_SYS_UP(); + + /* + * Powersave enable/disable request is coming from the + * cfg80211 even before the interface is up. In that + * scenario, driver will be storing the power save + * preference in cfg_priv struct to apply this to + * FW later while initializing the dongle + */ + cfg_priv->pwr_save = enabled; + if (!test_bit(WL_STATUS_READY, &cfg_priv->status)) { + + WL_INFO("Device is not ready," + "storing the value in cfg_priv struct\n"); + goto done; + } pm = enabled ? PM_FAST : PM_OFF; pm = cpu_to_le32(pm); @@ -1989,43 +1999,17 @@ brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, else WL_ERR("error (%d)\n", err); } +done: WL_TRACE("Exit\n"); return err; } -static __used u32 brcmf_find_msb(u16 bit16) -{ - u32 ret = 0; - - if (bit16 & 0xff00) { - ret += 8; - bit16 >>= 8; - } - - if (bit16 & 0xf0) { - ret += 4; - bit16 >>= 4; - } - - if (bit16 & 0xc) { - ret += 2; - bit16 >>= 2; - } - - if (bit16 & 2) - ret += bit16 & 2; - else if (bit16) - ret += bit16; - - return ret; -} - static s32 brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev, const u8 *addr, const struct cfg80211_bitrate_mask *mask) { - struct wl_rateset rateset; + struct brcm_rateset rateset; s32 rate; s32 val; s32 err_bg; @@ -2047,9 +2031,10 @@ brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev, rateset.count = le32_to_cpu(rateset.count); - legacy = brcmf_find_msb(mask->control[IEEE80211_BAND_2GHZ].legacy); + legacy = ffs(mask->control[IEEE80211_BAND_2GHZ].legacy & 0xFFFF); if (!legacy) - legacy = brcmf_find_msb(mask->control[IEEE80211_BAND_5GHZ].legacy); + legacy = ffs(mask->control[IEEE80211_BAND_5GHZ].legacy & + 0xFFFF); val = wl_g_rates[legacy - 1].bitrate * 100000; @@ -2090,10 +2075,6 @@ static s32 brcmf_cfg80211_resume(struct wiphy *wiphy) */ WL_TRACE("Enter\n"); -#if defined(CONFIG_PM_SLEEP) - atomic_set(&brcmf_mmc_suspend, false); -#endif /* defined(CONFIG_PM_SLEEP) */ - if (test_bit(WL_STATUS_READY, &cfg_priv->status)) brcmf_invoke_iscan(wiphy_to_cfg(wiphy)); @@ -2155,10 +2136,6 @@ static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy, brcmf_set_mpc(ndev, 1); } -#if defined(CONFIG_PM_SLEEP) - atomic_set(&brcmf_mmc_suspend, true); -#endif /* defined(CONFIG_PM_SLEEP) */ - WL_TRACE("Exit\n"); return 0; @@ -2190,7 +2167,7 @@ brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_pmksa *pmksa) { struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); - struct _pmkid_list *pmkids = &cfg_priv->pmk_list->pmkids; + struct pmkid_list *pmkids = &cfg_priv->pmk_list->pmkids; s32 err = 0; int i; @@ -2224,7 +2201,7 @@ brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev, struct cfg80211_pmksa *pmksa) { struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy); - struct _pmkid_list pmkid; + struct pmkid_list pmkid; s32 err = 0; int i; @@ -2247,7 +2224,7 @@ brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev, if ((cfg_priv->pmk_list->pmkids.npmkid > 0) && (i < cfg_priv->pmk_list->pmkids.npmkid)) { memset(&cfg_priv->pmk_list->pmkids.pmkid[i], 0, - sizeof(pmkid_t)); + sizeof(struct pmkid)); for (; i < (cfg_priv->pmk_list->pmkids.npmkid - 1); i++) { memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].BSSID, &cfg_priv->pmk_list->pmkids.pmkid[i + 1].BSSID, @@ -2360,14 +2337,10 @@ static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface, wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; wdev->wiphy->cipher_suites = __wl_cipher_suites; wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites); -#ifndef WL_POWERSAVE_DISABLED wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power * save mode * by default */ -#else - wdev->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT; -#endif /* !WL_POWERSAVE_DISABLED */ err = wiphy_register(wdev->wiphy); if (unlikely(err < 0)) { WL_ERR("Couldn not register wiphy device (%d)\n", err); @@ -2623,7 +2596,7 @@ brcmf_notify_connect_status(struct brcmf_cfg80211_priv *cfg_priv, clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status); set_bit(WL_STATUS_CONNECTED, &cfg_priv->status); } else - brcmf_bss_connect_done(cfg_priv, ndev, e, data, true); + brcmf_bss_connect_done(cfg_priv, ndev, e, true); } else if (brcmf_is_linkdown(cfg_priv, e)) { WL_CONN("Linkdown\n"); if (brcmf_is_ibssmode(cfg_priv)) { @@ -2632,7 +2605,7 @@ brcmf_notify_connect_status(struct brcmf_cfg80211_priv *cfg_priv, &cfg_priv->status)) brcmf_link_down(cfg_priv); } else { - brcmf_bss_connect_done(cfg_priv, ndev, e, data, false); + brcmf_bss_connect_done(cfg_priv, ndev, e, false); if (test_and_clear_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) { cfg80211_disconnected(ndev, 0, NULL, 0, @@ -2645,7 +2618,7 @@ brcmf_notify_connect_status(struct brcmf_cfg80211_priv *cfg_priv, if (brcmf_is_ibssmode(cfg_priv)) clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status); else - brcmf_bss_connect_done(cfg_priv, ndev, e, data, false); + brcmf_bss_connect_done(cfg_priv, ndev, e, false); } return err; @@ -2662,9 +2635,9 @@ brcmf_notify_roaming_status(struct brcmf_cfg80211_priv *cfg_priv, if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) { if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) - brcmf_bss_roaming_done(cfg_priv, ndev, e, data); + brcmf_bss_roaming_done(cfg_priv, ndev, e); else - brcmf_bss_connect_done(cfg_priv, ndev, e, data, true); + brcmf_bss_connect_done(cfg_priv, ndev, e, true); } return err; @@ -2780,7 +2753,7 @@ static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv) static void brcmf_ch_to_chanspec(int ch, struct brcmf_join_params *join_params, size_t *join_params_size) { - chanspec_t chanspec = 0; + u16 chanspec = 0; if (ch != 0) { join_params->params.chanspec_num = 1; @@ -2795,7 +2768,7 @@ static void brcmf_ch_to_chanspec(int ch, struct brcmf_join_params *join_params, chanspec |= WL_CHANSPEC_CTL_SB_NONE; *join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE + - join_params->params.chanspec_num * sizeof(chanspec_t); + join_params->params.chanspec_num * sizeof(u16); join_params->params.chanspec_list[0] &= WL_CHANSPEC_CHAN_MASK; join_params->params.chanspec_list[0] |= chanspec; @@ -2875,9 +2848,14 @@ update_bss_info_out: static s32 brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv, struct net_device *ndev, - const struct brcmf_event_msg *e, void *data) + const struct brcmf_event_msg *e) { struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv); + struct wiphy *wiphy = cfg_to_wiphy(cfg_priv); + struct brcmf_channel_info channel; + struct ieee80211_channel *notify_channel; + struct ieee80211_supported_band *band; + u32 freq; s32 err = 0; WL_TRACE("Enter\n"); @@ -2886,7 +2864,21 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv, brcmf_update_prof(cfg_priv, NULL, &e->addr, WL_PROF_BSSID); brcmf_update_bss_info(cfg_priv); - cfg80211_roamed(ndev, NULL, + brcmf_dev_ioctl(ndev, BRCMF_C_GET_CHANNEL, &channel, sizeof(channel)); + + channel.target_channel = le32_to_cpu(channel.target_channel); + WL_CONN("Roamed to channel %d\n", channel.target_channel); + + if (channel.target_channel <= CH_MAX_2G_CHANNEL) + band = wiphy->bands[IEEE80211_BAND_2GHZ]; + else + band = wiphy->bands[IEEE80211_BAND_5GHZ]; + + freq = ieee80211_channel_to_frequency(channel.target_channel, + band->band); + notify_channel = ieee80211_get_channel(wiphy, freq); + + cfg80211_roamed(ndev, notify_channel, (u8 *)brcmf_read_prof(cfg_priv, WL_PROF_BSSID), conn_info->req_ie, conn_info->req_ie_len, conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL); @@ -2900,7 +2892,7 @@ brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv, static s32 brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv, struct net_device *ndev, const struct brcmf_event_msg *e, - void *data, bool completed) + bool completed) { struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv); s32 err = 0; @@ -3134,7 +3126,7 @@ static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv *cfg_priv) static s32 brcmf_create_event_handler(struct brcmf_cfg80211_priv *cfg_priv) { - sema_init(&cfg_priv->event_sync, 0); + init_waitqueue_head(&cfg_priv->event_waitq); cfg_priv->event_tsk = kthread_run(brcmf_event_handler, cfg_priv, "wl_event_handler"); if (IS_ERR(cfg_priv->event_tsk)) { @@ -3157,12 +3149,24 @@ static void brcmf_destroy_event_handler(struct brcmf_cfg80211_priv *cfg_priv) static void brcmf_term_iscan(struct brcmf_cfg80211_priv *cfg_priv) { struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv); + struct brcmf_ssid ssid; if (cfg_priv->iscan_on && iscan->tsk) { iscan->state = WL_ISCAN_STATE_IDLE; send_sig(SIGTERM, iscan->tsk, 1); + + /* + * The iscan task may want to acquire the rtnl_lock + * so release it here upon stopping the task. + */ + rtnl_unlock(); kthread_stop(iscan->tsk); + rtnl_lock(); iscan->tsk = NULL; + + /* Abort iscan running in FW */ + memset(&ssid, 0, sizeof(ssid)); + brcmf_run_iscan(iscan, &ssid, WL_SCAN_ACTION_ABORT); } } @@ -3191,7 +3195,7 @@ static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan) { if (likely(iscan->state != WL_ISCAN_STATE_IDLE)) { WL_SCAN("wake up iscan\n"); - up(&iscan->sync); + wake_up(&iscan->waitq); return 0; } @@ -3229,6 +3233,7 @@ brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status, WL_SCAN("results->count = %d\n", results->count); WL_SCAN("results->buflen = %d\n", results->buflen); *status = le32_to_cpu(list_buf->status); + WL_SCAN("status = %d\n", *status); *bss_list = results; return err; @@ -3296,13 +3301,19 @@ static s32 brcmf_iscan_thread(void *data) (struct brcmf_cfg80211_iscan_ctrl *)data; struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan); struct brcmf_cfg80211_iscan_eloop *el = &iscan->el; + DECLARE_WAITQUEUE(wait, current); u32 status; int err = 0; sched_setscheduler(current, SCHED_FIFO, ¶m); allow_signal(SIGTERM); status = BRCMF_SCAN_RESULTS_PARTIAL; - while (likely(!down_interruptible(&iscan->sync))) { + add_wait_queue(&iscan->waitq, &wait); + while (1) { + prepare_to_wait(&iscan->waitq, &wait, TASK_INTERRUPTIBLE); + + schedule(); + if (kthread_should_stop()) break; if (iscan->timer_on) { @@ -3319,6 +3330,7 @@ static s32 brcmf_iscan_thread(void *data) rtnl_unlock(); el->handler[status](cfg_priv); } + finish_wait(&iscan->waitq, &wait); if (iscan->timer_on) { del_timer_sync(&iscan->timer); iscan->timer_on = 0; @@ -3343,11 +3355,10 @@ static void brcmf_iscan_timer(unsigned long data) static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_priv *cfg_priv) { struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv); - int err = 0; if (cfg_priv->iscan_on && !iscan->tsk) { iscan->state = WL_ISCAN_STATE_IDLE; - sema_init(&iscan->sync, 0); + init_waitqueue_head(&iscan->waitq); iscan->tsk = kthread_run(brcmf_iscan_thread, iscan, "wl_iscan"); if (IS_ERR(iscan->tsk)) { WL_ERR("Could not create iscan thread\n"); @@ -3356,7 +3367,7 @@ static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_priv *cfg_priv) } } - return err; + return 0; } static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el) @@ -3376,20 +3387,14 @@ static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv) if (cfg_priv->iscan_on) { iscan->dev = cfg_to_ndev(cfg_priv); - iscan->state = WL_ISCAN_STATE_IDLE; brcmf_init_iscan_eloop(&iscan->el); iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS; init_timer(&iscan->timer); iscan->timer.data = (unsigned long) iscan; iscan->timer.function = brcmf_iscan_timer; - sema_init(&iscan->sync, 0); - iscan->tsk = kthread_run(brcmf_iscan_thread, iscan, "wl_iscan"); - if (IS_ERR(iscan->tsk)) { - WL_ERR("Could not create iscan thread\n"); - iscan->tsk = NULL; - return -ENOMEM; - } - iscan->data = cfg_priv; + err = brcmf_invoke_iscan(cfg_priv); + if (!err) + iscan->data = cfg_priv; } return err; @@ -3397,14 +3402,13 @@ static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv) static s32 wl_init_priv(struct brcmf_cfg80211_priv *cfg_priv) { - struct wiphy *wiphy = cfg_to_wiphy(cfg_priv); s32 err = 0; cfg_priv->scan_request = NULL; - cfg_priv->pwr_save = !!(wiphy->flags & WIPHY_FLAG_PS_ON_BY_DEFAULT); + cfg_priv->pwr_save = true; cfg_priv->iscan_on = true; /* iscan on & off switch. we enable iscan per default */ - cfg_priv->roam_on = false; /* roam on & off switch. + cfg_priv->roam_on = true; /* roam on & off switch. we enable roam per default */ cfg_priv->iscan_kickstart = false; @@ -3500,7 +3504,7 @@ void brcmf_cfg80211_detach(void) static void brcmf_wakeup_event(struct brcmf_cfg80211_priv *cfg_priv) { - up(&cfg_priv->event_sync); + wake_up(&cfg_priv->event_waitq); } static s32 brcmf_event_handler(void *data) @@ -3509,27 +3513,39 @@ static s32 brcmf_event_handler(void *data) (struct brcmf_cfg80211_priv *)data; struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 }; struct brcmf_cfg80211_event_q *e; + DECLARE_WAITQUEUE(wait, current); sched_setscheduler(current, SCHED_FIFO, ¶m); allow_signal(SIGTERM); - while (likely(!down_interruptible(&cfg_priv->event_sync))) { + add_wait_queue(&cfg_priv->event_waitq, &wait); + while (1) { + prepare_to_wait(&cfg_priv->event_waitq, &wait, + TASK_INTERRUPTIBLE); + + schedule(); + if (kthread_should_stop()) break; + e = brcmf_deq_event(cfg_priv); if (unlikely(!e)) { WL_ERR("event queue empty...\n"); - BUG(); + continue; } - WL_INFO("event type (%d)\n", e->etype); - if (cfg_priv->el.handler[e->etype]) { - cfg_priv->el.handler[e->etype](cfg_priv, - cfg_to_ndev(cfg_priv), - &e->emsg, e->edata); - } else { - WL_INFO("Unknown Event (%d): ignoring\n", e->etype); - } - brcmf_put_event(e); - } + + do { + WL_INFO("event type (%d)\n", e->etype); + if (cfg_priv->el.handler[e->etype]) + cfg_priv->el.handler[e->etype](cfg_priv, + cfg_to_ndev(cfg_priv), + &e->emsg, e->edata); + else + WL_INFO("Unknown Event (%d): ignoring\n", + e->etype); + brcmf_put_event(e); + } while ((e = brcmf_deq_event(cfg_priv))); + } + finish_wait(&cfg_priv->event_waitq, &wait); WL_INFO("was terminated\n"); return 0; } @@ -3541,7 +3557,7 @@ brcmf_cfg80211_event(struct net_device *ndev, u32 event_type = be32_to_cpu(e->event_type); struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev); - if (likely(!brcmf_enq_event(cfg_priv, event_type, e, data))) + if (likely(!brcmf_enq_event(cfg_priv, event_type, e))) brcmf_wakeup_event(cfg_priv); } @@ -3591,7 +3607,7 @@ static struct brcmf_cfg80211_event_q *brcmf_deq_event( static s32 brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 event, - const struct brcmf_event_msg *msg, void *data) + const struct brcmf_event_msg *msg) { struct brcmf_cfg80211_event_q *e; s32 err = 0; @@ -3818,6 +3834,7 @@ s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv, bool need_lock) { struct net_device *ndev; struct wireless_dev *wdev; + s32 power_mode; s32 err = 0; if (cfg_priv->dongle_up) @@ -3834,6 +3851,16 @@ s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv, bool need_lock) err = brcmf_dongle_eventmsg(ndev); if (unlikely(err)) goto default_conf_out; + + power_mode = cfg_priv->pwr_save ? PM_FAST : PM_OFF; + power_mode = cpu_to_le32(power_mode); + err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_PM, + &power_mode, sizeof(power_mode)); + if (err) + goto default_conf_out; + WL_INFO("power save set to %s\n", + (power_mode ? "enabled" : "disabled")); + err = brcmf_dongle_roam(ndev, (cfg_priv->roam_on ? 0 : 1), WL_BEACON_TIMEOUT); if (unlikely(err)) diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h index f26d087..0542bac 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h +++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h @@ -249,7 +249,7 @@ struct brcmf_cfg80211_iscan_ctrl { u32 timer_on; s32 state; struct task_struct *tsk; - struct semaphore sync; + wait_queue_head_t waitq; struct brcmf_cfg80211_iscan_eloop el; void *data; s8 ioctl_buf[BRCMF_C_IOCTL_SMLEN]; @@ -272,8 +272,8 @@ struct brcmf_cfg80211_assoc_ielen { /* wpa2 pmk list */ struct brcmf_cfg80211_pmk_list { - pmkid_list_t pmkids; - pmkid_t foo[MAXPMKID - 1]; + struct pmkid_list pmkids; + struct pmkid foo[MAXPMKID - 1]; }; /* dongle private data of cfg80211 interface */ @@ -295,13 +295,12 @@ struct brcmf_cfg80211_priv { cfg80211 layer */ struct brcmf_cfg80211_ie ie; /* information element object for internal purpose */ - struct semaphore event_sync; /* for synchronization of main event - thread */ 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 */ + wait_queue_head_t event_waitq; /* wait queue for main event handling */ unsigned long status; /* current dongle status */ void *pub; u32 channel; /* current channel */ @@ -318,7 +317,7 @@ struct brcmf_cfg80211_priv { u8 *ioctl_buf; /* ioctl buffer */ u8 *extra_buf; /* maily to grab assoc information */ struct dentry *debugfsdir; - u8 ci[0] __attribute__ ((__aligned__(NETDEV_ALIGN))); + u8 ci[0] __aligned(NETDEV_ALIGN); }; #define cfg_to_wiphy(w) (w->wdev->wiphy) @@ -341,7 +340,8 @@ static inline struct brcmf_bss_info *next_bss(struct brcmf_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)) + for (__i = 0; __i < list->count && __i < WL_AP_MAX; __i++, \ + bss = next_bss(list, bss)) extern s32 brcmf_cfg80211_attach(struct net_device *ndev, void *data); extern void brcmf_cfg80211_detach(void); diff --git a/drivers/staging/brcm80211/brcmsmac/Makefile b/drivers/staging/brcm80211/brcmsmac/Makefile index 1ea3e0c..eee2fe3 100644 --- a/drivers/staging/brcm80211/brcmsmac/Makefile +++ b/drivers/staging/brcm80211/brcmsmac/Makefile @@ -16,13 +16,6 @@ # CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ccflags-y := \ - -DWLC_HIGH \ - -DWLC_LOW \ - -DSTA \ - -DWME \ - -DWL11N \ - -DDBAND \ - -DBCMNVRAMR \ -Idrivers/staging/brcm80211/brcmsmac \ -Idrivers/staging/brcm80211/brcmsmac/phy \ -Idrivers/staging/brcm80211/include @@ -33,7 +26,6 @@ BRCMSMAC_OFILES := \ alloc.o \ ampdu.o \ antsel.o \ - bmac.o \ channel.o \ main.o \ phy_shim.o \ diff --git a/drivers/staging/brcm80211/brcmsmac/aiutils.c b/drivers/staging/brcm80211/brcmsmac/aiutils.c index a25901e..62186b7 100644 --- a/drivers/staging/brcm80211/brcmsmac/aiutils.c +++ b/drivers/staging/brcm80211/brcmsmac/aiutils.c @@ -12,7 +12,10 @@ * 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 contents: support functions for PCI/PCIe */ + #include <linux/delay.h> #include <linux/pci.h> @@ -20,6 +23,7 @@ #include <chipcommon.h> #include <brcmu_utils.h> #include <brcm_hw_ids.h> +#include <soc.h> #include "types.h" #include "pub.h" #include "pmu.h" @@ -28,48 +32,68 @@ #include "aiutils.h" /* slow_clk_ctl */ -#define SCC_SS_MASK 0x00000007 /* slow clock source mask */ -#define SCC_SS_LPO 0x00000000 /* source of slow clock is LPO */ -#define SCC_SS_XTAL 0x00000001 /* source of slow clock is crystal */ -#define SCC_SS_PCI 0x00000002 /* source of slow clock is PCI */ -#define SCC_LF 0x00000200 /* LPOFreqSel, 1: 160Khz, 0: 32KHz */ -#define SCC_LP 0x00000400 /* LPOPowerDown, 1: LPO is disabled, - * 0: LPO is enabled - */ -#define SCC_FS 0x00000800 /* ForceSlowClk, 1: sb/cores running on slow clock, - * 0: power logic control - */ -#define SCC_IP 0x00001000 /* IgnorePllOffReq, 1/0: power logic ignores/honors - * PLL clock disable requests from core - */ -#define SCC_XC 0x00002000 /* XtalControlEn, 1/0: power logic does/doesn't - * disable crystal when appropriate - */ -#define SCC_XP 0x00004000 /* XtalPU (RO), 1/0: crystal running/disabled */ -#define SCC_CD_MASK 0xffff0000 /* ClockDivider (SlowClk = 1/(4+divisor)) */ + /* slow clock source mask */ +#define SCC_SS_MASK 0x00000007 + /* source of slow clock is LPO */ +#define SCC_SS_LPO 0x00000000 + /* source of slow clock is crystal */ +#define SCC_SS_XTAL 0x00000001 + /* source of slow clock is PCI */ +#define SCC_SS_PCI 0x00000002 + /* LPOFreqSel, 1: 160Khz, 0: 32KHz */ +#define SCC_LF 0x00000200 + /* LPOPowerDown, 1: LPO is disabled, 0: LPO is enabled */ +#define SCC_LP 0x00000400 + /* ForceSlowClk, 1: sb/cores running on slow clock, 0: power logic control */ +#define SCC_FS 0x00000800 + /* IgnorePllOffReq, 1/0: + * power logic ignores/honors PLL clock disable requests from core + */ +#define SCC_IP 0x00001000 + /* XtalControlEn, 1/0: + * power logic does/doesn't disable crystal when appropriate + */ +#define SCC_XC 0x00002000 + /* XtalPU (RO), 1/0: crystal running/disabled */ +#define SCC_XP 0x00004000 + /* ClockDivider (SlowClk = 1/(4+divisor)) */ +#define SCC_CD_MASK 0xffff0000 #define SCC_CD_SHIFT 16 /* system_clk_ctl */ -#define SYCC_IE 0x00000001 /* ILPen: Enable Idle Low Power */ -#define SYCC_AE 0x00000002 /* ALPen: Enable Active Low Power */ -#define SYCC_FP 0x00000004 /* ForcePLLOn */ -#define SYCC_AR 0x00000008 /* Force ALP (or HT if ALPen is not set */ -#define SYCC_HR 0x00000010 /* Force HT */ -#define SYCC_CD_MASK 0xffff0000 /* ClkDiv (ILP = 1/(4 * (divisor + 1)) */ + /* ILPen: Enable Idle Low Power */ +#define SYCC_IE 0x00000001 + /* ALPen: Enable Active Low Power */ +#define SYCC_AE 0x00000002 + /* ForcePLLOn */ +#define SYCC_FP 0x00000004 + /* Force ALP (or HT if ALPen is not set */ +#define SYCC_AR 0x00000008 + /* Force HT */ +#define SYCC_HR 0x00000010 + /* ClkDiv (ILP = 1/(4 * (divisor + 1)) */ +#define SYCC_CD_MASK 0xffff0000 #define SYCC_CD_SHIFT 16 #define CST4329_SPROM_OTP_SEL_MASK 0x00000003 -#define CST4329_DEFCIS_SEL 0 /* OTP is powered up, use def. CIS, no SPROM */ -#define CST4329_SPROM_SEL 1 /* OTP is powered up, SPROM is present */ -#define CST4329_OTP_SEL 2 /* OTP is powered up, no SPROM */ -#define CST4329_OTP_PWRDN 3 /* OTP is powered down, SPROM is present */ + /* OTP is powered up, use def. CIS, no SPROM */ +#define CST4329_DEFCIS_SEL 0 + /* OTP is powered up, SPROM is present */ +#define CST4329_SPROM_SEL 1 + /* OTP is powered up, no SPROM */ +#define CST4329_OTP_SEL 2 + /* OTP is powered down, SPROM is present */ +#define CST4329_OTP_PWRDN 3 + #define CST4329_SPI_SDIO_MODE_MASK 0x00000004 #define CST4329_SPI_SDIO_MODE_SHIFT 2 /* 43224 chip-specific ChipControl register bits */ #define CCTRL43224_GPIO_TOGGLE 0x8000 -#define CCTRL_43224A0_12MA_LED_DRIVE 0x00F000F0 /* 12 mA drive strength */ -#define CCTRL_43224B0_12MA_LED_DRIVE 0xF0 /* 12 mA drive strength for later 43224s */ + /* 12 mA drive strength */ +#define CCTRL_43224A0_12MA_LED_DRIVE 0x00F000F0 + /* 12 mA drive strength for later 43224s */ +#define CCTRL_43224B0_12MA_LED_DRIVE 0xF0 /* 43236 Chip specific ChipStatus register bits */ #define CST43236_SFLASH_MASK 0x00000040 @@ -78,29 +102,44 @@ #define CST43236_BP_CLK 0x00000200 /* 120/96Mbps */ #define CST43236_BOOT_MASK 0x00001800 #define CST43236_BOOT_SHIFT 11 -#define CST43236_BOOT_FROM_SRAM 0 /* boot from SRAM, ARM in reset */ -#define CST43236_BOOT_FROM_ROM 1 /* boot from ROM */ -#define CST43236_BOOT_FROM_FLASH 2 /* boot from FLASH */ +#define CST43236_BOOT_FROM_SRAM 0 /* boot from SRAM, ARM in reset */ +#define CST43236_BOOT_FROM_ROM 1 /* boot from ROM */ +#define CST43236_BOOT_FROM_FLASH 2 /* boot from FLASH */ #define CST43236_BOOT_FROM_INVALID 3 /* 4331 chip-specific ChipControl register bits */ -#define CCTRL4331_BT_COEXIST (1<<0) /* 0 disable */ -#define CCTRL4331_SECI (1<<1) /* 0 SECI is disabled (JATG functional) */ -#define CCTRL4331_EXT_LNA (1<<2) /* 0 disable */ -#define CCTRL4331_SPROM_GPIO13_15 (1<<3) /* sprom/gpio13-15 mux */ -#define CCTRL4331_EXTPA_EN (1<<4) /* 0 ext pa disable, 1 ext pa enabled */ -#define CCTRL4331_GPIOCLK_ON_SPROMCS (1<<5) /* set drive out GPIO_CLK on sprom_cs pin */ -#define CCTRL4331_PCIE_MDIO_ON_SPROMCS (1<<6) /* use sprom_cs pin as PCIE mdio interface */ -#define CCTRL4331_EXTPA_ON_GPIO2_5 (1<<7) /* aband extpa will be at gpio2/5 and sprom_dout */ -#define CCTRL4331_OVR_PIPEAUXCLKEN (1<<8) /* override core control on pipe_AuxClkEnable */ -#define CCTRL4331_OVR_PIPEAUXPWRDOWN (1<<9) /* override core control on pipe_AuxPowerDown */ -#define CCTRL4331_PCIE_AUXCLKEN (1<<10) /* pcie_auxclkenable */ -#define CCTRL4331_PCIE_PIPE_PLLDOWN (1<<11) /* pcie_pipe_pllpowerdown */ -#define CCTRL4331_BT_SHD0_ON_GPIO4 (1<<16) /* enable bt_shd0 at gpio4 */ -#define CCTRL4331_BT_SHD1_ON_GPIO5 (1<<17) /* enable bt_shd1 at gpio5 */ + /* 0 disable */ +#define CCTRL4331_BT_COEXIST (1<<0) + /* 0 SECI is disabled (JTAG functional) */ +#define CCTRL4331_SECI (1<<1) + /* 0 disable */ +#define CCTRL4331_EXT_LNA (1<<2) + /* sprom/gpio13-15 mux */ +#define CCTRL4331_SPROM_GPIO13_15 (1<<3) + /* 0 ext pa disable, 1 ext pa enabled */ +#define CCTRL4331_EXTPA_EN (1<<4) + /* set drive out GPIO_CLK on sprom_cs pin */ +#define CCTRL4331_GPIOCLK_ON_SPROMCS (1<<5) + /* use sprom_cs pin as PCIE mdio interface */ +#define CCTRL4331_PCIE_MDIO_ON_SPROMCS (1<<6) + /* aband extpa will be at gpio2/5 and sprom_dout */ +#define CCTRL4331_EXTPA_ON_GPIO2_5 (1<<7) + /* override core control on pipe_AuxClkEnable */ +#define CCTRL4331_OVR_PIPEAUXCLKEN (1<<8) + /* override core control on pipe_AuxPowerDown */ +#define CCTRL4331_OVR_PIPEAUXPWRDOWN (1<<9) + /* pcie_auxclkenable */ +#define CCTRL4331_PCIE_AUXCLKEN (1<<10) + /* pcie_pipe_pllpowerdown */ +#define CCTRL4331_PCIE_PIPE_PLLDOWN (1<<11) + /* enable bt_shd0 at gpio4 */ +#define CCTRL4331_BT_SHD0_ON_GPIO4 (1<<16) + /* enable bt_shd1 at gpio5 */ +#define CCTRL4331_BT_SHD1_ON_GPIO5 (1<<17) /* 4331 Chip specific ChipStatus register bits */ -#define CST4331_XTAL_FREQ 0x00000001 /* crystal frequency 20/40Mhz */ + /* crystal frequency 20/40Mhz */ +#define CST4331_XTAL_FREQ 0x00000001 #define CST4331_SPROM_PRESENT 0x00000002 #define CST4331_OTP_PRESENT 0x00000004 #define CST4331_LDO_RF 0x00000008 @@ -110,19 +149,26 @@ #define CST4319_SPI_CPULESSUSB 0x00000001 #define CST4319_SPI_CLK_POL 0x00000002 #define CST4319_SPI_CLK_PH 0x00000008 -#define CST4319_SPROM_OTP_SEL_MASK 0x000000c0 /* gpio [7:6], SDIO CIS selection */ + /* gpio [7:6], SDIO CIS selection */ +#define CST4319_SPROM_OTP_SEL_MASK 0x000000c0 #define CST4319_SPROM_OTP_SEL_SHIFT 6 -#define CST4319_DEFCIS_SEL 0x00000000 /* use default CIS, OTP is powered up */ -#define CST4319_SPROM_SEL 0x00000040 /* use SPROM, OTP is powered up */ -#define CST4319_OTP_SEL 0x00000080 /* use OTP, OTP is powered up */ -#define CST4319_OTP_PWRDN 0x000000c0 /* use SPROM, OTP is powered down */ -#define CST4319_SDIO_USB_MODE 0x00000100 /* gpio [8], sdio/usb mode */ + /* use default CIS, OTP is powered up */ +#define CST4319_DEFCIS_SEL 0x00000000 + /* use SPROM, OTP is powered up */ +#define CST4319_SPROM_SEL 0x00000040 + /* use OTP, OTP is powered up */ +#define CST4319_OTP_SEL 0x00000080 + /* use SPROM, OTP is powered down */ +#define CST4319_OTP_PWRDN 0x000000c0 + /* gpio [8], sdio/usb mode */ +#define CST4319_SDIO_USB_MODE 0x00000100 #define CST4319_REMAP_SEL_MASK 0x00000600 #define CST4319_ILPDIV_EN 0x00000800 #define CST4319_XTAL_PD_POL 0x00001000 #define CST4319_LPO_SEL 0x00002000 #define CST4319_RES_INIT_MODE 0x0000c000 -#define CST4319_PALDO_EXTPNP 0x00010000 /* PALDO is configured with external PNP */ + /* PALDO is configured with external PNP */ +#define CST4319_PALDO_EXTPNP 0x00010000 #define CST4319_CBUCK_MODE_MASK 0x00060000 #define CST4319_CBUCK_MODE_BURST 0x00020000 #define CST4319_CBUCK_MODE_LPBURST 0x00060000 @@ -153,7 +199,8 @@ #define CST4313_SPROM_OTP_SEL_SHIFT 0 /* 4313 Chip specific ChipControl register bits */ -#define CCTRL_4313_12MA_LED_DRIVE 0x00000007 /* 12 mA drive strengh for later 4313 */ + /* 12 mA drive strengh for later 4313 */ +#define CCTRL_4313_12MA_LED_DRIVE 0x00000007 #define BCM47162_DMP() ((sih->chip == BCM47162_CHIP_ID) && \ (sih->chiprev == 0) && \ @@ -227,9 +274,12 @@ #define SD_SG32 0x00000008 #define SD_SZ_ALIGN 0x00000fff -#define PCI_CFG_GPIO_SCS 0x10 /* PCI config space bit 4 for 4306c0 slow clock source */ -#define PCI_CFG_GPIO_XTAL 0x40 /* PCI config space GPIO 14 for Xtal power-up */ -#define PCI_CFG_GPIO_PLL 0x80 /* PCI config space GPIO 15 for PLL power-down */ +/* PCI config space bit 4 for 4306c0 slow clock source */ +#define PCI_CFG_GPIO_SCS 0x10 +/* PCI config space GPIO 14 for Xtal power-up */ +#define PCI_CFG_GPIO_XTAL 0x40 +/* PCI config space GPIO 15 for PLL power-down */ +#define PCI_CFG_GPIO_PLL 0x80 /* power control defines */ #define PLL_DELAY 150 /* us pll on delay */ @@ -387,10 +437,10 @@ get_erom_ent(struct si_pub *sih, u32 **eromptr, u32 mask, u32 match) } SI_VMSG(("%s: Returning ent 0x%08x\n", __func__, ent)); - if (inv + nom) { + if (inv + nom) SI_VMSG((" after %d invalid and %d non-matching entries\n", inv, nom)); - } + return ent; } @@ -434,41 +484,24 @@ static void ai_hwfixup(struct si_info *sii) } /* parse the enumeration rom to identify all cores */ -void ai_scan(struct si_pub *sih, void *regs) +void ai_scan(struct si_pub *sih, struct chipcregs *cc) { struct si_info *sii = SI_INFO(sih); - chipcregs_t *cc = (chipcregs_t *) regs; u32 erombase, *eromptr, *eromlim; + void *regs = cc; erombase = R_REG(&cc->eromptr); - switch (sih->bustype) { - case SI_BUS: - eromptr = (u32 *) REG_MAP(erombase, SI_CORE_SIZE); - break; - - case PCI_BUS: - /* Set wrappers address */ - sii->curwrap = (void *)((unsigned long)regs + SI_CORE_SIZE); - - /* Now point the window at the erom */ - pci_write_config_dword(sii->pbus, PCI_BAR0_WIN, erombase); - eromptr = regs; - break; - - case SPI_BUS: - case SDIO_BUS: - eromptr = (u32 *)(unsigned long)erombase; - break; + /* Set wrappers address */ + sii->curwrap = (void *)((unsigned long)cc + SI_CORE_SIZE); - default: - SI_ERROR(("Don't know how to do AXI enumertion on bus %d\n", - sih->bustype)); - return; - } + /* Now point the window at the erom */ + pci_write_config_dword(sii->pbus, PCI_BAR0_WIN, erombase); + eromptr = regs; eromlim = eromptr + (ER_REMAPCONTROL / sizeof(u32)); - SI_VMSG(("ai_scan: regs = 0x%p, erombase = 0x%08x, eromptr = 0x%p, eromlim = 0x%p\n", regs, erombase, eromptr, eromlim)); + SI_VMSG(("ai_scan: regs = 0x%p, erombase = 0x%08x, eromptr = 0x%p, " + "eromlim = 0x%p\n", regs, erombase, eromptr, eromlim)); while (eromptr < eromlim) { u32 cia, cib, cid, mfg, crev, nmw, nsw, nmp, nsp; u32 mpd, asd, addrl, addrh, sizel, sizeh; @@ -502,7 +535,9 @@ void ai_scan(struct si_pub *sih, void *regs) nmp = (cib & CIB_NMP_MASK) >> CIB_NMP_SHIFT; nsp = (cib & CIB_NSP_MASK) >> CIB_NSP_SHIFT; - SI_VMSG(("Found component 0x%04x/0x%04x rev %d at erom addr 0x%p, with nmw = %d, " "nsw = %d, nmp = %d & nsp = %d\n", mfg, cid, crev, base, nmw, nsw, nmp, nsp)); + SI_VMSG(("Found component 0x%04x/0x%04x rev %d at erom addr " + "0x%p, with nmw = %d, nsw = %d, nmp = %d & nsp = %d\n", + mfg, cid, crev, base, nmw, nsw, nmp, nsp)); if (((mfg == MFGID_ARM) && (cid == DEF_AI_COMP)) || (nsp == 0)) continue; @@ -511,9 +546,8 @@ void ai_scan(struct si_pub *sih, void *regs) if (cid == OOB_ROUTER_CORE_ID) { asd = get_asd(sih, &eromptr, 0, 0, AD_ST_SLAVE, &addrl, &addrh, &sizel, &sizeh); - if (asd != 0) { + if (asd != 0) sii->oob_router = addrl; - } } continue; } @@ -527,7 +561,8 @@ void ai_scan(struct si_pub *sih, void *regs) for (i = 0; i < nmp; i++) { mpd = get_erom_ent(sih, &eromptr, ER_VALID, ER_VALID); if ((mpd & ER_TAG) != ER_MP) { - SI_ERROR(("Not enough MP entries for component 0x%x\n", cid)); + SI_ERROR(("Not enough MP entries for " + "component 0x%x\n", cid)); goto error; } SI_VMSG((" Master port %d, mp: %d id: %d\n", i, @@ -550,7 +585,8 @@ void ai_scan(struct si_pub *sih, void *regs) br = true; else if ((addrh != 0) || (sizeh != 0) || (sizel != SI_CORE_SIZE)) { - SI_ERROR(("First Slave ASD for core 0x%04x malformed " "(0x%08x)\n", cid, asd)); + SI_ERROR(("First Slave ASD for core 0x%04x " + "malformed (0x%08x)\n", cid, asd)); goto error; } } @@ -634,55 +670,29 @@ void ai_scan(struct si_pub *sih, void *regs) return; } -/* This function changes the logical "focus" to the indicated core. - * Return the current core's virtual address. +/* + * This function changes the logical "focus" to the indicated core. + * Return the current core's virtual address. Since each core starts with the + * same set of registers (BIST, clock control, etc), the returned address + * contains the first register of this 'common' register block (not to be + * confused with 'common core'). */ void *ai_setcoreidx(struct si_pub *sih, uint coreidx) { struct si_info *sii = SI_INFO(sih); u32 addr = sii->coresba[coreidx]; u32 wrap = sii->wrapba[coreidx]; - void *regs; if (coreidx >= sii->numcores) return NULL; - switch (sih->bustype) { - case SI_BUS: - /* map new one */ - if (!sii->regs[coreidx]) { - sii->regs[coreidx] = REG_MAP(addr, SI_CORE_SIZE); - } - sii->curmap = regs = sii->regs[coreidx]; - if (!sii->wrappers[coreidx]) { - sii->wrappers[coreidx] = REG_MAP(wrap, SI_CORE_SIZE); - } - sii->curwrap = sii->wrappers[coreidx]; - break; - - case PCI_BUS: - /* point bar0 window */ - pci_write_config_dword(sii->pbus, PCI_BAR0_WIN, addr); - regs = sii->curmap; - /* point bar0 2nd 4KB window */ - pci_write_config_dword(sii->pbus, PCI_BAR0_WIN2, wrap); - break; - - case SPI_BUS: - case SDIO_BUS: - sii->curmap = regs = (void *)(unsigned long)addr; - sii->curwrap = (void *)(unsigned long)wrap; - break; - - default: - regs = NULL; - break; - } - - sii->curmap = regs; + /* point bar0 window */ + pci_write_config_dword(sii->pbus, PCI_BAR0_WIN, addr); + /* point bar0 2nd 4KB window */ + pci_write_config_dword(sii->pbus, PCI_BAR0_WIN2, wrap); sii->curidx = coreidx; - return regs; + return sii->curmap; } /* Return the number of address spaces in current core */ @@ -705,7 +715,8 @@ u32 ai_addrspace(struct si_pub *sih, uint asidx) else if (asidx == 1) return sii->coresba2[cidx]; else { - SI_ERROR(("%s: Need to parse the erom again to find addr space %d\n", __func__, asidx)); + SI_ERROR(("%s: Need to parse the erom again to find addr " + "space %d\n", __func__, asidx)); return 0; } } @@ -724,7 +735,8 @@ u32 ai_addrspacesize(struct si_pub *sih, uint asidx) else if (asidx == 1) return sii->coresba2_size[cidx]; else { - SI_ERROR(("%s: Need to parse the erom again to find addr space %d\n", __func__, asidx)); + SI_ERROR(("%s: Need to parse the erom again to find addr " + "space %d\n", __func__, asidx)); return 0; } } @@ -736,7 +748,8 @@ uint ai_flag(struct si_pub *sih) sii = SI_INFO(sih); if (BCM47162_DMP()) { - SI_ERROR(("%s: Attempting to read MIPS DMP registers on 47162a0", __func__)); + SI_ERROR(("%s: Attempting to read MIPS DMP registers " + "on 47162a0", __func__)); return sii->curidx; } ai = sii->curwrap; @@ -834,7 +847,8 @@ u32 ai_core_sflags(struct si_pub *sih, u32 mask, u32 val) sii = SI_INFO(sih); if (BCM47162_DMP()) { - SI_ERROR(("%s: Accessing MIPS DMP register (iostatus) on 47162a0", __func__)); + SI_ERROR(("%s: Accessing MIPS DMP register (iostatus) " + "on 47162a0", __func__)); return 0; } @@ -851,11 +865,10 @@ u32 ai_core_sflags(struct si_pub *sih, u32 mask, u32 val) /* *************** from siutils.c ************** */ /* local prototypes */ static struct si_info *ai_doattach(struct si_info *sii, void *regs, - uint bustype, void *sdh, char **vars, - uint *varsz); -static bool ai_buscore_prep(struct si_info *sii, uint bustype); -static bool ai_buscore_setup(struct si_info *sii, chipcregs_t *cc, uint bustype, - u32 savewin, uint *origidx, void *regs); + struct pci_dev *sdh, + char **vars, uint *varsz); +static bool ai_buscore_prep(struct si_info *sii); +static bool ai_buscore_setup(struct si_info *sii, u32 savewin, uint *origidx); static void ai_nvram_process(struct si_info *sii, char *pvars); /* dev path concatenation util */ @@ -864,20 +877,16 @@ static char *ai_devpathvar(struct si_pub *sih, char *var, int len, static bool _ai_clkctl_cc(struct si_info *sii, uint mode); static bool ai_ispcie(struct si_info *sii); -/* global variable to indicate reservation/release of gpio's */ -static u32 ai_gpioreservation; - /* * Allocate a si handle. * devid - pci device id (used to determine chip#) * osh - opaque OS handle * regs - virtual address of initial core registers - * bustype - pci/sb/sdio/etc * vars - pointer to a pointer area for "environment" variables * varsz - pointer to int to return the size of the vars */ -struct si_pub *ai_attach(void *regs, uint bustype, - void *sdh, char **vars, uint *varsz) +struct si_pub * +ai_attach(void *regs, struct pci_dev *sdh, char **vars, uint *varsz) { struct si_info *sii; @@ -888,8 +897,7 @@ struct si_pub *ai_attach(void *regs, uint bustype, return NULL; } - if (ai_doattach(sii, regs, bustype, sdh, vars, varsz) == - NULL) { + if (ai_doattach(sii, regs, sdh, vars, varsz) == NULL) { kfree(sii); return NULL; } @@ -902,20 +910,21 @@ struct si_pub *ai_attach(void *regs, uint bustype, /* global kernel resource */ static struct si_info ksii; -static bool ai_buscore_prep(struct si_info *sii, uint bustype) +static bool ai_buscore_prep(struct si_info *sii) { /* kludge to enable the clock on the 4306 which lacks a slowclock */ - if (bustype == PCI_BUS && !ai_ispcie(sii)) + if (!ai_ispcie(sii)) ai_clkctl_xtal(&sii->pub, XTAL | PLL, ON); return true; } -static bool ai_buscore_setup(struct si_info *sii, chipcregs_t *cc, uint bustype, - u32 savewin, uint *origidx, void *regs) +static bool +ai_buscore_setup(struct si_info *sii, u32 savewin, uint *origidx) { bool pci, pcie; uint i; uint pciidx, pcieidx, pcirev, pcierev; + struct chipcregs *cc; cc = ai_setcoreidx(&sii->pub, SI_CC_IDX); @@ -959,21 +968,19 @@ static bool ai_buscore_setup(struct si_info *sii, chipcregs_t *cc, uint bustype, SI_VMSG(("CORE[%d]: id 0x%x rev %d base 0x%x regs 0x%p\n", i, cid, crev, sii->coresba[i], sii->regs[i])); - if (bustype == PCI_BUS) { - if (cid == PCI_CORE_ID) { - pciidx = i; - pcirev = crev; - pci = true; - } else if (cid == PCIE_CORE_ID) { - pcieidx = i; - pcierev = crev; - pcie = true; - } + if (cid == PCI_CORE_ID) { + pciidx = i; + pcirev = crev; + pci = true; + } else if (cid == PCIE_CORE_ID) { + pcieidx = i; + pcierev = crev; + pcie = true; } /* find the core idx before entering this func. */ if ((savewin && (savewin == sii->coresba[i])) || - (regs == sii->regs[i])) + (cc == sii->regs[i])) *origidx = i; } @@ -997,21 +1004,18 @@ static bool ai_buscore_setup(struct si_info *sii, chipcregs_t *cc, uint bustype, sii->pub.buscoretype, sii->pub.buscorerev)); /* fixup necessary chip/core configurations */ - if (sii->pub.bustype == PCI_BUS) { - if (SI_FAST(sii)) { - if (!sii->pch) { - sii->pch = (void *)pcicore_init( - &sii->pub, sii->pbus, - (void *)PCIEREGS(sii)); - if (sii->pch == NULL) - return false; - } - } - if (ai_pci_fixcfg(&sii->pub)) { - SI_ERROR(("si_doattach: si_pci_fixcfg failed\n")); - return false; + if (SI_FAST(sii)) { + if (!sii->pch) { + sii->pch = pcicore_init(&sii->pub, sii->pbus, + (void *)PCIEREGS(sii)); + if (sii->pch == NULL) + return false; } } + if (ai_pci_fixcfg(&sii->pub)) { + SI_ERROR(("si_doattach: si_pci_fixcfg failed\n")); + return false; + } /* return to the original core */ ai_setcoreidx(&sii->pub, *origidx); @@ -1019,62 +1023,45 @@ static bool ai_buscore_setup(struct si_info *sii, chipcregs_t *cc, uint bustype, return true; } +/* + * get boardtype and boardrev + */ static __used void ai_nvram_process(struct si_info *sii, char *pvars) { uint w = 0; - /* get boardtype and boardrev */ - switch (sii->pub.bustype) { - case PCI_BUS: - /* do a pci config read to get subsystem id and subvendor id */ - pci_read_config_dword(sii->pbus, PCI_SUBSYSTEM_VENDOR_ID, &w); - /* Let nvram variables override subsystem Vend/ID */ - sii->pub.boardvendor = (u16)ai_getdevpathintvar(&sii->pub, - "boardvendor"); - if (sii->pub.boardvendor == 0) - sii->pub.boardvendor = w & 0xffff; - else - SI_ERROR(("Overriding boardvendor: 0x%x instead of " - "0x%x\n", sii->pub.boardvendor, w & 0xffff)); - sii->pub.boardtype = (u16)ai_getdevpathintvar(&sii->pub, - "boardtype"); - if (sii->pub.boardtype == 0) - sii->pub.boardtype = (w >> 16) & 0xffff; - else - SI_ERROR(("Overriding boardtype: 0x%x instead of 0x%x\n" - , sii->pub.boardtype, (w >> 16) & 0xffff)); - break; - - sii->pub.boardvendor = getintvar(pvars, "manfid"); - sii->pub.boardtype = getintvar(pvars, "prodid"); - break; + /* do a pci config read to get subsystem id and subvendor id */ + pci_read_config_dword(sii->pbus, PCI_SUBSYSTEM_VENDOR_ID, &w); + /* Let nvram variables override subsystem Vend/ID */ + sii->pub.boardvendor = (u16)ai_getdevpathintvar(&sii->pub, + "boardvendor"); + if (sii->pub.boardvendor == 0) + sii->pub.boardvendor = w & 0xffff; + else + SI_ERROR(("Overriding boardvendor: 0x%x instead of " + "0x%x\n", sii->pub.boardvendor, w & 0xffff)); - case SI_BUS: - case JTAG_BUS: - sii->pub.boardvendor = PCI_VENDOR_ID_BROADCOM; - sii->pub.boardtype = getintvar(pvars, "prodid"); - if (pvars == NULL || (sii->pub.boardtype == 0)) { - sii->pub.boardtype = getintvar(NULL, "boardtype"); - if (sii->pub.boardtype == 0) - sii->pub.boardtype = 0xffff; - } - break; - } + sii->pub.boardtype = (u16)ai_getdevpathintvar(&sii->pub, + "boardtype"); + if (sii->pub.boardtype == 0) + sii->pub.boardtype = (w >> 16) & 0xffff; + else + SI_ERROR(("Overriding boardtype: 0x%x instead of 0x%x\n" + , sii->pub.boardtype, (w >> 16) & 0xffff)); - if (sii->pub.boardtype == 0) { + if (sii->pub.boardtype == 0) SI_ERROR(("si_doattach: unknown board type\n")); - } sii->pub.boardflags = getintvar(pvars, "boardflags"); } static struct si_info *ai_doattach(struct si_info *sii, - void *regs, uint bustype, void *pbus, - char **vars, uint *varsz) + void *regs, struct pci_dev *pbus, + char **vars, uint *varsz) { struct si_pub *sih = &sii->pub; u32 w, savewin; - chipcregs_t *cc; + struct chipcregs *cc; char *pvars = NULL; uint socitype; uint origidx; @@ -1088,35 +1075,18 @@ static struct si_info *ai_doattach(struct si_info *sii, sii->curmap = regs; sii->pbus = pbus; - /* check to see if we are a si core mimic'ing a pci core */ - if (bustype == PCI_BUS) { - pci_read_config_dword(sii->pbus, PCI_SPROM_CONTROL, &w); - if (w == 0xffffffff) { - SI_ERROR(("%s: incoming bus is PCI but it's a lie, " - " switching to SI devid:0x%x\n", - __func__, devid)); - bustype = SI_BUS; - } - } - /* find Chipcommon address */ - if (bustype == PCI_BUS) { - pci_read_config_dword(sii->pbus, PCI_BAR0_WIN, &savewin); - if (!GOODCOREADDR(savewin, SI_ENUM_BASE)) - savewin = SI_ENUM_BASE; - pci_write_config_dword(sii->pbus, PCI_BAR0_WIN, - SI_ENUM_BASE); - cc = (chipcregs_t *) regs; - } else { - cc = (chipcregs_t *) REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE); - } + pci_read_config_dword(sii->pbus, PCI_BAR0_WIN, &savewin); + if (!GOODCOREADDR(savewin, SI_ENUM_BASE)) + savewin = SI_ENUM_BASE; - sih->bustype = bustype; + pci_write_config_dword(sii->pbus, PCI_BAR0_WIN, + SI_ENUM_BASE); + cc = (struct chipcregs *) regs; /* bus/core/clk setup for register access */ - if (!ai_buscore_prep(sii, bustype)) { - SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n", - bustype)); + if (!ai_buscore_prep(sii)) { + SI_ERROR(("si_doattach: si_core_clk_prep failed\n")); return NULL; } @@ -1140,7 +1110,7 @@ static struct si_info *ai_doattach(struct si_info *sii, if (socitype == SOCI_AI) { SI_MSG(("Found chip type AI (0x%08x)\n", w)); /* pass chipc address instead of original core base */ - ai_scan(&sii->pub, (void *)cc); + ai_scan(&sii->pub, cc); } else { SI_ERROR(("Found chip of unknown type (0x%08x)\n", w)); return NULL; @@ -1152,14 +1122,13 @@ static struct si_info *ai_doattach(struct si_info *sii, } /* bus/core/clk setup */ origidx = SI_CC_IDX; - if (!ai_buscore_setup(sii, cc, bustype, savewin, &origidx, regs)) { + if (!ai_buscore_setup(sii, savewin, &origidx)) { SI_ERROR(("si_doattach: si_buscore_setup failed\n")); goto exit; } /* Init nvram from sprom/otp if they exist */ - if (srom_var_init - (&sii->pub, bustype, regs, vars, varsz)) { + if (srom_var_init(&sii->pub, cc, vars, varsz)) { SI_ERROR(("si_doattach: srom_var_init failed: bad srom\n")); goto exit; } @@ -1167,7 +1136,7 @@ static struct si_info *ai_doattach(struct si_info *sii, ai_nvram_process(sii, pvars); /* === NVRAM, clock is ready === */ - cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0); + cc = (struct chipcregs *) ai_setcore(sih, CC_CORE_ID, 0); W_REG(&cc->gpiopullup, 0); W_REG(&cc->gpiopulldown, 0); ai_setcoreidx(sih, origidx); @@ -1190,11 +1159,11 @@ static struct si_info *ai_doattach(struct si_info *sii, w = getintvar(pvars, "leddc"); if (w == 0) w = DEFAULT_GPIOTIMERVAL; - ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, gpiotimerval), ~0, w); + ai_corereg(sih, SI_CC_IDX, offsetof(struct chipcregs, gpiotimerval), + ~0, w); - if (PCIE(sii)) { + if (PCIE(sii)) pcicore_attach(sii->pch, pvars, SI_DOATTACH); - } if (sih->chip == BCM43224_CHIP_ID) { /* @@ -1204,7 +1173,7 @@ static struct si_info *ai_doattach(struct si_info *sii, if (sih->chiprev == 0) { SI_MSG(("Applying 43224A0 WARs\n")); ai_corereg(sih, SI_CC_IDX, - offsetof(chipcregs_t, chipcontrol), + offsetof(struct chipcregs, chipcontrol), CCTRL43224_GPIO_TOGGLE, CCTRL43224_GPIO_TOGGLE); si_pmu_chipcontrol(sih, 0, CCTRL_43224A0_12MA_LED_DRIVE, @@ -1228,12 +1197,11 @@ static struct si_info *ai_doattach(struct si_info *sii, } return sii; + exit: - if (sih->bustype == PCI_BUS) { - if (sii->pch) - pcicore_deinit(sii->pch); - sii->pch = NULL; - } + if (sii->pch) + pcicore_deinit(sii->pch); + sii->pch = NULL; return NULL; } @@ -1242,7 +1210,6 @@ static struct si_info *ai_doattach(struct si_info *sii, void ai_detach(struct si_pub *sih) { struct si_info *sii; - uint idx; struct si_pub *si_local = NULL; memcpy(&si_local, &sih, sizeof(struct si_pub **)); @@ -1252,18 +1219,9 @@ void ai_detach(struct si_pub *sih) if (sii == NULL) return; - if (sih->bustype == SI_BUS) - for (idx = 0; idx < SI_MAXCORES; idx++) - if (sii->regs[idx]) { - iounmap(sii->regs[idx]); - sii->regs[idx] = NULL; - } - - if (sih->bustype == PCI_BUS) { - if (sii->pch) - pcicore_deinit(sii->pch); - sii->pch = NULL; - } + if (sii->pch) + pcicore_deinit(sii->pch); + sii->pch = NULL; if (sii != &ksii) kfree(sii); @@ -1279,9 +1237,9 @@ ai_register_intr_callback(struct si_pub *sih, void *intrsoff_fn, sii = SI_INFO(sih); sii->intr_arg = intr_arg; - sii->intrsoff_fn = (si_intrsoff_t) intrsoff_fn; - sii->intrsrestore_fn = (si_intrsrestore_t) intrsrestore_fn; - sii->intrsenabled_fn = (si_intrsenabled_t) intrsenabled_fn; + sii->intrsoff_fn = (u32 (*)(void *)) intrsoff_fn; + sii->intrsrestore_fn = (void (*) (void *, u32)) intrsrestore_fn; + sii->intrsenabled_fn = (bool (*)(void *)) intrsenabled_fn; /* save current core id. when this function called, the current core * must be the core which provides driver functions(il, et, wl, etc.) */ @@ -1371,9 +1329,9 @@ void *ai_switch_core(struct si_pub *sih, uint coreid, uint *origidx, */ *origidx = coreid; if (coreid == CC_CORE_ID) - return (void *)CCREGS_FAST(sii); + return CCREGS_FAST(sii); else if (coreid == sih->buscoretype) - return (void *)PCIEREGS(sii); + return PCIEREGS(sii); } INTR_OFF(sii, *intr_val); *origidx = sii->curidx; @@ -1428,43 +1386,29 @@ uint ai_corereg(struct si_pub *sih, uint coreidx, uint regoff, uint mask, if (coreidx >= SI_MAXCORES) return 0; - if (sih->bustype == SI_BUS) { - /* If internal bus, we can always get at everything */ + /* + * If pci/pcie, we can get at pci/pcie regs + * and on newer cores to chipc + */ + if ((sii->coreid[coreidx] == CC_CORE_ID) && SI_FAST(sii)) { + /* Chipc registers are mapped at 12KB */ fast = true; - /* map if does not exist */ - if (!sii->regs[coreidx]) { - sii->regs[coreidx] = REG_MAP(sii->coresba[coreidx], - SI_CORE_SIZE); - } - r = (u32 *) ((unsigned char *) sii->regs[coreidx] + regoff); - } else if (sih->bustype == PCI_BUS) { + r = (u32 *)((char *)sii->curmap + + PCI_16KB0_CCREGS_OFFSET + regoff); + } else if (sii->pub.buscoreidx == coreidx) { /* - * If pci/pcie, we can get at pci/pcie regs - * and on newer cores to chipc + * pci registers are at either in the last 2KB of + * an 8KB window or, in pcie and pci rev 13 at 8KB */ - if ((sii->coreid[coreidx] == CC_CORE_ID) && SI_FAST(sii)) { - /* Chipc registers are mapped at 12KB */ - - fast = true; - r = (u32 *) ((char *)sii->curmap + - PCI_16KB0_CCREGS_OFFSET + regoff); - } else if (sii->pub.buscoreidx == coreidx) { - /* - * pci registers are at either in the last 2KB of - * an 8KB window or, in pcie and pci rev 13 at 8KB - */ - fast = true; - if (SI_FAST(sii)) - r = (u32 *) ((char *)sii->curmap + - PCI_16KB0_PCIREGS_OFFSET + - regoff); - else - r = (u32 *) ((char *)sii->curmap + - ((regoff >= SBCONFIGOFF) ? - PCI_BAR0_PCISBR_OFFSET : - PCI_BAR0_PCIREGS_OFFSET) + - regoff); - } + fast = true; + if (SI_FAST(sii)) + r = (u32 *)((char *)sii->curmap + + PCI_16KB0_PCIREGS_OFFSET + regoff); + else + r = (u32 *)((char *)sii->curmap + + ((regoff >= SBCONFIGOFF) ? + PCI_BAR0_PCISBR_OFFSET : + PCI_BAR0_PCIREGS_OFFSET) + regoff); } if (!fast) { @@ -1556,19 +1500,17 @@ void ai_core_reset(struct si_pub *sih, u32 bits, u32 resetbits) /* return the slow clock source - LPO, XTAL, or PCI */ static uint ai_slowclk_src(struct si_info *sii) { - chipcregs_t *cc; + struct chipcregs *cc; u32 val; if (sii->pub.ccrev < 6) { - if (sii->pub.bustype == PCI_BUS) { - pci_read_config_dword(sii->pbus, PCI_GPIO_OUT, - &val); - if (val & PCI_CFG_GPIO_SCS) - return SCC_SS_PCI; - } + pci_read_config_dword(sii->pbus, PCI_GPIO_OUT, + &val); + if (val & PCI_CFG_GPIO_SCS) + return SCC_SS_PCI; return SCC_SS_XTAL; } else if (sii->pub.ccrev < 10) { - cc = (chipcregs_t *) ai_setcoreidx(&sii->pub, sii->curidx); + cc = (struct chipcregs *) ai_setcoreidx(&sii->pub, sii->curidx); return R_REG(&cc->slow_clk_ctl) & SCC_SS_MASK; } else /* Insta-clock */ return SCC_SS_XTAL; @@ -1578,7 +1520,8 @@ static uint ai_slowclk_src(struct si_info *sii) * return the ILP (slowclock) min or max frequency * precondition: we've established the chip has dynamic clk control */ -static uint ai_slowclk_freq(struct si_info *sii, bool max_freq, chipcregs_t *cc) +static uint +ai_slowclk_freq(struct si_info *sii, bool max_freq, struct chipcregs *cc) { u32 slowclk; uint div; @@ -1612,9 +1555,8 @@ static uint ai_slowclk_freq(struct si_info *sii, bool max_freq, chipcregs_t *cc) return 0; } -static void ai_clkctl_setdelay(struct si_info *sii, void *chipcregs) +static void ai_clkctl_setdelay(struct si_info *sii, struct chipcregs *cc) { - chipcregs_t *cc = (chipcregs_t *) chipcregs; uint slowmaxfreq, pll_delay, slowclk; uint pll_on_delay, fref_sel_delay; @@ -1646,7 +1588,7 @@ void ai_clkctl_init(struct si_pub *sih) { struct si_info *sii; uint origidx = 0; - chipcregs_t *cc; + struct chipcregs *cc; bool fast; if (!CCCTL_ENAB(sih)) @@ -1656,11 +1598,11 @@ void ai_clkctl_init(struct si_pub *sih) fast = SI_FAST(sii); if (!fast) { origidx = sii->curidx; - cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0); + cc = (struct chipcregs *) ai_setcore(sih, CC_CORE_ID, 0); if (cc == NULL) return; } else { - cc = (chipcregs_t *) CCREGS_FAST(sii); + cc = (struct chipcregs *) CCREGS_FAST(sii); if (cc == NULL) return; } @@ -1670,7 +1612,7 @@ void ai_clkctl_init(struct si_pub *sih) SET_REG(&cc->system_clk_ctl, SYCC_CD_MASK, (ILP_DIV_1MHZ << SYCC_CD_SHIFT)); - ai_clkctl_setdelay(sii, (void *)cc); + ai_clkctl_setdelay(sii, cc); if (!fast) ai_setcoreidx(sih, origidx); @@ -1684,7 +1626,7 @@ u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih) { struct si_info *sii; uint origidx = 0; - chipcregs_t *cc; + struct chipcregs *cc; uint slowminfreq; u16 fpdelay; uint intr_val = 0; @@ -1706,11 +1648,11 @@ u16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih) if (!fast) { origidx = sii->curidx; INTR_OFF(sii, intr_val); - cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0); + cc = (struct chipcregs *) ai_setcore(sih, CC_CORE_ID, 0); if (cc == NULL) goto done; } else { - cc = (chipcregs_t *) CCREGS_FAST(sii); + cc = (struct chipcregs *) CCREGS_FAST(sii); if (cc == NULL) goto done; } @@ -1735,63 +1677,56 @@ int ai_clkctl_xtal(struct si_pub *sih, uint what, bool on) sii = SI_INFO(sih); - switch (sih->bustype) { - - case PCI_BUS: - /* pcie core doesn't have any mapping to control the xtal pu */ - if (PCIE(sii)) - return -1; + /* pcie core doesn't have any mapping to control the xtal pu */ + if (PCIE(sii)) + return -1; - pci_read_config_dword(sii->pbus, PCI_GPIO_IN, &in); - pci_read_config_dword(sii->pbus, PCI_GPIO_OUT, &out); - pci_read_config_dword(sii->pbus, PCI_GPIO_OUTEN, &outen); + pci_read_config_dword(sii->pbus, PCI_GPIO_IN, &in); + pci_read_config_dword(sii->pbus, PCI_GPIO_OUT, &out); + pci_read_config_dword(sii->pbus, PCI_GPIO_OUTEN, &outen); - /* - * Avoid glitching the clock if GPRS is already using it. - * We can't actually read the state of the PLLPD so we infer it - * by the value of XTAL_PU which *is* readable via gpioin. - */ - if (on && (in & PCI_CFG_GPIO_XTAL)) - return 0; + /* + * Avoid glitching the clock if GPRS is already using it. + * We can't actually read the state of the PLLPD so we infer it + * by the value of XTAL_PU which *is* readable via gpioin. + */ + if (on && (in & PCI_CFG_GPIO_XTAL)) + return 0; - if (what & XTAL) - outen |= PCI_CFG_GPIO_XTAL; - if (what & PLL) - outen |= PCI_CFG_GPIO_PLL; - - if (on) { - /* turn primary xtal on */ - if (what & XTAL) { - out |= PCI_CFG_GPIO_XTAL; - if (what & PLL) - out |= PCI_CFG_GPIO_PLL; - pci_write_config_dword(sii->pbus, - PCI_GPIO_OUT, out); - pci_write_config_dword(sii->pbus, - PCI_GPIO_OUTEN, outen); - udelay(XTAL_ON_DELAY); - } + if (what & XTAL) + outen |= PCI_CFG_GPIO_XTAL; + if (what & PLL) + outen |= PCI_CFG_GPIO_PLL; - /* turn pll on */ - if (what & PLL) { - out &= ~PCI_CFG_GPIO_PLL; - pci_write_config_dword(sii->pbus, - PCI_GPIO_OUT, out); - mdelay(2); - } - } else { - if (what & XTAL) - out &= ~PCI_CFG_GPIO_XTAL; + if (on) { + /* turn primary xtal on */ + if (what & XTAL) { + out |= PCI_CFG_GPIO_XTAL; if (what & PLL) out |= PCI_CFG_GPIO_PLL; pci_write_config_dword(sii->pbus, PCI_GPIO_OUT, out); pci_write_config_dword(sii->pbus, PCI_GPIO_OUTEN, outen); + udelay(XTAL_ON_DELAY); } - default: - return -1; + /* turn pll on */ + if (what & PLL) { + out &= ~PCI_CFG_GPIO_PLL; + pci_write_config_dword(sii->pbus, + PCI_GPIO_OUT, out); + mdelay(2); + } + } else { + if (what & XTAL) + out &= ~PCI_CFG_GPIO_XTAL; + if (what & PLL) + out |= PCI_CFG_GPIO_PLL; + pci_write_config_dword(sii->pbus, + PCI_GPIO_OUT, out); + pci_write_config_dword(sii->pbus, + PCI_GPIO_OUTEN, outen); } return 0; @@ -1825,7 +1760,7 @@ bool ai_clkctl_cc(struct si_pub *sih, uint mode) static bool _ai_clkctl_cc(struct si_info *sii, uint mode) { uint origidx = 0; - chipcregs_t *cc; + struct chipcregs *cc; u32 scc; uint intr_val = 0; bool fast = SI_FAST(sii); @@ -1837,15 +1772,9 @@ static bool _ai_clkctl_cc(struct si_info *sii, uint mode) if (!fast) { INTR_OFF(sii, intr_val); origidx = sii->curidx; - - if ((sii->pub.bustype == SI_BUS) && - ai_setcore(&sii->pub, MIPS33_CORE_ID, 0) && - (ai_corerev(&sii->pub) <= 7) && (sii->pub.ccrev >= 10)) - goto done; - - cc = (chipcregs_t *) ai_setcore(&sii->pub, CC_CORE_ID, 0); + cc = (struct chipcregs *) ai_setcore(&sii->pub, CC_CORE_ID, 0); } else { - cc = (chipcregs_t *) CCREGS_FAST(sii); + cc = (struct chipcregs *) CCREGS_FAST(sii); if (cc == NULL) goto done; } @@ -1913,7 +1842,7 @@ static bool _ai_clkctl_cc(struct si_info *sii, uint mode) return mode == CLK_FAST; } -/* Build device path. Support SI, PCI, and JTAG for now. */ +/* Build device path */ int ai_devpath(struct si_pub *sih, char *path, int size) { int slen; @@ -1921,22 +1850,9 @@ int ai_devpath(struct si_pub *sih, char *path, int size) if (!path || size <= 0) return -1; - switch (sih->bustype) { - case SI_BUS: - case JTAG_BUS: - slen = snprintf(path, (size_t) size, "sb/%u/", ai_coreidx(sih)); - break; - case PCI_BUS: - slen = snprintf(path, (size_t) size, "pci/%u/%u/", - ((struct pci_dev *)((SI_INFO(sih))->pbus))->bus->number, - PCI_SLOT( - ((struct pci_dev *)((SI_INFO(sih))->pbus))->devfn)); - break; - - default: - slen = -1; - break; - } + slen = snprintf(path, (size_t) size, "pci/%u/%u/", + (((SI_INFO(sih))->pbus))->bus->number, + PCI_SLOT(((struct pci_dev *)((SI_INFO(sih))->pbus))->devfn)); if (slen < 0 || slen >= size) { path[0] = '\0'; @@ -1959,15 +1875,11 @@ char *ai_getdevpathvar(struct si_pub *sih, const char *name) /* Get a variable, but only if it has a devpath prefix */ int ai_getdevpathintvar(struct si_pub *sih, const char *name) { -#if defined(BCMBUSTYPE) && (BCMBUSTYPE == SI_BUS) - return getintvar(NULL, name); -#else char varname[SI_DEVPATH_BUFSZ + 32]; ai_devpathvar(sih, varname, sizeof(varname), name); return getintvar(NULL, varname); -#endif } char *ai_getnvramflvar(struct si_pub *sih, const char *name) @@ -2005,9 +1917,6 @@ static bool ai_ispcie(struct si_info *sii) { u8 cap_ptr; - if (sii->pub.bustype != PCI_BUS) - return false; - cap_ptr = pcicore_find_pci_capability(sii->pbus, PCI_CAP_ID_EXP, NULL, NULL); @@ -2032,10 +1941,6 @@ void ai_pci_up(struct si_pub *sih) sii = SI_INFO(sih); - /* if not pci bus, we're done */ - if (sih->bustype != PCI_BUS) - return; - if (PCI_FORCEHT(sii)) _ai_clkctl_cc(sii, CLK_FAST); @@ -2061,10 +1966,6 @@ void ai_pci_down(struct si_pub *sih) sii = SI_INFO(sih); - /* if not pci bus, we're done */ - if (sih->bustype != PCI_BUS) - return; - /* release FORCEHT since chip is going to "down" state */ if (PCI_FORCEHT(sii)) _ai_clkctl_cc(sii, CLK_DYNAMIC); @@ -2079,15 +1980,12 @@ void ai_pci_down(struct si_pub *sih) void ai_pci_setup(struct si_pub *sih, uint coremask) { struct si_info *sii; - void *regs = NULL; + struct sbpciregs *regs = NULL; u32 siflag = 0, w; uint idx = 0; sii = SI_INFO(sih); - if (sii->pub.bustype != PCI_BUS) - return; - if (PCI(sii)) { /* get current core index */ idx = sii->curidx; @@ -2129,7 +2027,6 @@ int ai_pci_fixcfg(struct si_pub *sih) { uint origidx; void *regs = NULL; - struct si_info *sii = SI_INFO(sih); /* Fixup PI in SROM shadow area to enable the correct PCI core access */ @@ -2138,7 +2035,10 @@ int ai_pci_fixcfg(struct si_pub *sih) /* check 'pi' is correct and fix it if not */ regs = ai_setcore(&sii->pub, sii->pub.buscoretype, 0); - pcicore_fixcfg(sii->pch, regs); + if (sii->pub.buscoretype == PCIE_CORE_ID) + pcicore_fixcfg_pcie(sii->pch, (struct sbpcieregs *)regs); + else if (sii->pub.buscoretype == PCI_CORE_ID) + pcicore_fixcfg_pci(sii->pch, (struct sbpciregs *)regs); /* restore the original index */ ai_setcoreidx(&sii->pub, origidx); @@ -2152,47 +2052,34 @@ u32 ai_gpiocontrol(struct si_pub *sih, u32 mask, u32 val, u8 priority) { uint regoff; - regoff = 0; - - /* gpios could be shared on router platforms - * ignore reservation if it's high priority (e.g., test apps) - */ - if ((priority != GPIO_HI_PRIORITY) && - (sih->bustype == SI_BUS) && (val || mask)) { - mask = priority ? (ai_gpioreservation & mask) : - ((ai_gpioreservation | mask) & ~(ai_gpioreservation)); - val &= mask; - } - - regoff = offsetof(chipcregs_t, gpiocontrol); + regoff = offsetof(struct chipcregs, gpiocontrol); return ai_corereg(sih, SI_CC_IDX, regoff, mask, val); } void ai_chipcontrl_epa4331(struct si_pub *sih, bool on) { struct si_info *sii; - chipcregs_t *cc; + struct chipcregs *cc; uint origidx; u32 val; sii = SI_INFO(sih); origidx = ai_coreidx(sih); - cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0); + cc = (struct chipcregs *) ai_setcore(sih, CC_CORE_ID, 0); val = R_REG(&cc->chipcontrol); if (on) { - if (sih->chippkg == 9 || sih->chippkg == 0xb) { + if (sih->chippkg == 9 || sih->chippkg == 0xb) /* Ext PA Controls for 4331 12x9 Package */ W_REG(&cc->chipcontrol, val | (CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_ON_GPIO2_5)); - } else { + else /* Ext PA Controls for 4331 12x12 Package */ W_REG(&cc->chipcontrol, val | (CCTRL4331_EXTPA_EN)); - } } else { val &= ~(CCTRL4331_EXTPA_EN | CCTRL4331_EXTPA_ON_GPIO2_5); W_REG(&cc->chipcontrol, val); @@ -2205,13 +2092,13 @@ void ai_chipcontrl_epa4331(struct si_pub *sih, bool on) void ai_epa_4313war(struct si_pub *sih) { struct si_info *sii; - chipcregs_t *cc; + struct chipcregs *cc; uint origidx; sii = SI_INFO(sih); origidx = ai_coreidx(sih); - cc = (chipcregs_t *) ai_setcore(sih, CC_CORE_ID, 0); + cc = ai_setcore(sih, CC_CORE_ID, 0); /* EPA Fix */ W_REG(&cc->gpiocontrol, @@ -2228,13 +2115,10 @@ bool ai_deviceremoved(struct si_pub *sih) sii = SI_INFO(sih); - switch (sih->bustype) { - case PCI_BUS: - pci_read_config_dword(sii->pbus, PCI_VENDOR_ID, &w); - if ((w & 0xFFFF) != PCI_VENDOR_ID_BROADCOM) - return true; - break; - } + pci_read_config_dword(sii->pbus, PCI_VENDOR_ID, &w); + if ((w & 0xFFFF) != PCI_VENDOR_ID_BROADCOM) + return true; + return false; } @@ -2243,7 +2127,7 @@ bool ai_is_sprom_available(struct si_pub *sih) if (sih->ccrev >= 31) { struct si_info *sii; uint origidx; - chipcregs_t *cc; + struct chipcregs *cc; u32 sromctrl; if ((sih->cccaps & CC_CAP_SROM) == 0) diff --git a/drivers/staging/brcm80211/brcmsmac/aiutils.h b/drivers/staging/brcm80211/brcmsmac/aiutils.h index e245c27..5dee80f 100644 --- a/drivers/staging/brcm80211/brcmsmac/aiutils.h +++ b/drivers/staging/brcm80211/brcmsmac/aiutils.h @@ -30,17 +30,9 @@ #define SI_PCI_MEM_SZ (64 * 1024 * 1024) /* Host Mode sb2pcitranslation1 (64 MB) */ #define SI_PCI_CFG 0x0c000000 -/* Byteswapped Physical SDRAM */ -#define SI_SDRAM_SWAPPED 0x10000000 /* Region 2 for sdram (512 MB) */ #define SI_SDRAM_R2 0x80000000 -#ifdef SI_ENUM_BASE_VARIABLE -#define SI_ENUM_BASE (sii->pub.si_enum_base) -#else -#define SI_ENUM_BASE 0x18000000 /* Enumeration space base */ -#endif /* SI_ENUM_BASE_VARIABLE */ - /* Wrapper space base */ #define SI_WRAP_BASE 0x18100000 /* each core gets 4Kbytes for registers */ @@ -242,16 +234,23 @@ #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 */ + /* SDIO || gSPI */ +#define CST4330_CHIPMODE_SDIOD(cs) (((cs) & 0x7) < 6) + /* USB || USBDA */ +#define CST4330_CHIPMODE_USB20D(cs) (((cs) & 0x7) >= 6) + /* SDIO */ +#define CST4330_CHIPMODE_SDIO(cs) (((cs) & 0x4) == 0) + /* gSPI */ +#define CST4330_CHIPMODE_GSPI(cs) (((cs) & 0x6) == 4) + /* USB packet-oriented */ +#define CST4330_CHIPMODE_USB(cs) (((cs) & 0x7) == 6) + /* USB Direct Access */ +#define CST4330_CHIPMODE_USBDA(cs) (((cs) & 0x7) == 7) #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 */ + /* takes priority over OTP if both set */ +#define CST4330_SPROM_PRESENT 0x00000080 #define CST4330_ILPDIV_EN 0x00000100 #define CST4330_LPO_SEL 0x00000200 #define CST4330_RES_INIT_MODE_SHIFT 10 @@ -323,10 +322,8 @@ #define ILP_DIV_5MHZ 0 /* ILP = 5 MHz */ #define ILP_DIV_1MHZ 4 /* ILP = 1 MHz */ -#define PCI(si) (((si)->pub.bustype == PCI_BUS) && \ - ((si)->pub.buscoretype == PCI_CORE_ID)) -#define PCIE(si) (((si)->pub.bustype == PCI_BUS) && \ - ((si)->pub.buscoretype == PCIE_CORE_ID)) +#define PCI(si) ((si)->pub.buscoretype == PCI_CORE_ID) +#define PCIE(si) ((si)->pub.buscoretype == PCIE_CORE_ID) #define PCI_FORCEHT(si) \ (PCIE(si) && (si->pub.chip == BCM4716_CHIP_ID)) @@ -334,17 +331,14 @@ #define DEFAULT_GPIO_ONTIME 10 /* Default: 10% on */ #define DEFAULT_GPIO_OFFTIME 90 /* Default: 10% on */ -#ifndef DEFAULT_GPIOTIMERVAL #define DEFAULT_GPIOTIMERVAL \ ((DEFAULT_GPIO_ONTIME << GPIO_ONTIME_SHIFT) | DEFAULT_GPIO_OFFTIME) -#endif /* * Data structure to export all chip specific common variables * public (read-only) portion of aiutils handle returned by si_attach() */ struct si_pub { - uint bustype; /* SI_BUS, PCI_BUS */ uint buscoretype; /* PCI_CORE_ID, PCIE_CORE_ID, PCMCIA_CORE_ID */ uint buscorerev; /* buscore rev */ uint buscoreidx; /* buscore index */ @@ -410,22 +404,11 @@ struct si_pub { #define SI_PCIUP 3 /* PMU clock/power control */ -#if defined(BCMPMUCTL) -#define PMUCTL_ENAB(sih) (BCMPMUCTL) -#else #define PMUCTL_ENAB(sih) ((sih)->cccaps & CC_CAP_PMU) -#endif /* chipcommon clock/power control (exclusive with PMU's) */ -#if defined(BCMPMUCTL) && BCMPMUCTL -#define CCCTL_ENAB(sih) (0) -#define CCPLL_ENAB(sih) (0) -#else #define CCCTL_ENAB(sih) ((sih)->cccaps & CC_CAP_PWR_CTL) #define CCPLL_ENAB(sih) ((sih)->cccaps & CC_CAP_PLL_MASK) -#endif - -typedef void (*gpio_handler_t) (u32 stat, void *arg); /* External PA enable mask */ #define GPIO_CTRL_EPA_EN_MASK 0x40 @@ -444,14 +427,12 @@ typedef void (*gpio_handler_t) (u32 stat, void *arg); #define IS_SIM(chippkg) \ ((chippkg == HDLSIM_PKG_ID) || (chippkg == HWSIM_PKG_ID)) -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); +struct pci_dev; struct gpioh_item { void *arg; bool level; - gpio_handler_t handler; + void (*handler) (u32 stat, void *arg); u32 event; struct gpioh_item *next; }; @@ -459,14 +440,16 @@ struct gpioh_item { /* misc si info needed by some of the routines */ struct si_info { struct si_pub pub; /* back plane public state (must be first) */ - void *pbus; /* handle to bus (pci/sdio/..) */ + struct pci_dev *pbus; /* handle to pci bus */ uint dev_coreid; /* the core provides driver functions */ void *intr_arg; /* interrupt callback function arg */ - si_intrsoff_t intrsoff_fn; /* turns chip interrupts off */ - si_intrsrestore_t intrsrestore_fn; /* restore chip interrupts */ - si_intrsenabled_t intrsenabled_fn; /* check if interrupts are enabled */ + u32 (*intrsoff_fn) (void *intr_arg); /* turns chip interrupts off */ + /* restore chip interrupts */ + void (*intrsrestore_fn) (void *intr_arg, u32 arg); + /* check if interrupts are enabled */ + bool (*intrsenabled_fn) (void *intr_arg); - void *pch; /* PCI/E core handle */ + struct pcicore_info *pch; /* PCI/E core handle */ char *vars; uint varsz; @@ -493,15 +476,12 @@ struct si_info { }; /* AMBA Interconnect exported externs */ -extern void ai_scan(struct si_pub *sih, void *regs); - 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); @@ -515,9 +495,8 @@ extern u32 ai_addrspacesize(struct si_pub *sih, uint asidx); extern void ai_write_wrap_reg(struct si_pub *sih, u32 offset, u32 val); /* === exported functions === */ -extern struct si_pub *ai_attach(void *regs, uint bustype, - void *sdh, char **vars, uint *varsz); - +extern struct si_pub *ai_attach(void *regs, struct pci_dev *sdh, char **vars, + uint *varsz); extern void ai_detach(struct si_pub *sih); extern bool ai_pci_war16165(struct si_pub *sih); diff --git a/drivers/staging/brcm80211/brcmsmac/alloc.c b/drivers/staging/brcm80211/brcmsmac/alloc.c index 7f8dd7b..7dc2875 100644 --- a/drivers/staging/brcm80211/brcmsmac/alloc.c +++ b/drivers/staging/brcm80211/brcmsmac/alloc.c @@ -161,11 +161,10 @@ struct brcms_c_info *brcms_c_attach_malloc(uint unit, uint *err, uint devid) } else { int i; - for (i = 1; i < MAXBANDS; i++) { + for (i = 1; i < MAXBANDS; i++) wlc->hw->bandstate[i] = (struct brcms_hw_band *) ((unsigned long)wlc->hw->bandstate[0] + (sizeof(struct brcms_hw_band) * i)); - } } wlc->modulecb = @@ -196,11 +195,10 @@ struct brcms_c_info *brcms_c_attach_malloc(uint unit, uint *err, uint devid) goto fail; } else { int i; - for (i = 1; i < BRCMS_DEFAULT_KEYS; i++) { + for (i = 1; i < BRCMS_DEFAULT_KEYS; i++) wlc->wsec_def_keys[i] = (struct wsec_key *) ((unsigned long)wlc->wsec_def_keys[0] + (sizeof(struct wsec_key) * i)); - } } wlc->protection = kzalloc(sizeof(struct brcms_protection), @@ -224,11 +222,10 @@ struct brcms_c_info *brcms_c_attach_malloc(uint unit, uint *err, uint devid) } else { int i; - for (i = 1; i < MAXBANDS; i++) { + for (i = 1; i < MAXBANDS; i++) wlc->bandstate[i] = (struct brcms_band *) ((unsigned long)wlc->bandstate[0] + (sizeof(struct brcms_band)*i)); - } } wlc->corestate = kzalloc(sizeof(struct brcms_core), GFP_ATOMIC); diff --git a/drivers/staging/brcm80211/brcmsmac/ampdu.c b/drivers/staging/brcm80211/brcmsmac/ampdu.c index fcaf61e..6fc1591 100644 --- a/drivers/staging/brcm80211/brcmsmac/ampdu.c +++ b/drivers/staging/brcm80211/brcmsmac/ampdu.c @@ -22,19 +22,32 @@ #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 */ -#define AMPDU_TX_BA_MAX_WSIZE 64 /* max Tx ba window size (in pdu) */ -#define AMPDU_TX_BA_DEF_WSIZE 64 /* default Tx ba window size (in pdu) */ -#define AMPDU_RX_BA_DEF_WSIZE 64 /* max Rx ba window size (in pdu) */ -#define AMPDU_RX_BA_MAX_WSIZE 64 /* default Rx ba window size (in pdu) */ -#define AMPDU_MAX_DUR 5 /* max dur of tx ampdu (in msec) */ -#define AMPDU_DEF_RETRY_LIMIT 5 /* default tx retry limit */ -#define AMPDU_DEF_RR_RETRY_LIMIT 2 /* default tx retry limit at reg rate */ -#define AMPDU_DEF_TXPKT_WEIGHT 2 /* default weight of ampdu in txfifo */ -#define AMPDU_DEF_FFPLD_RSVD 2048 /* default ffpld reserved bytes */ -#define AMPDU_INI_FREE 10 /* # of inis to be freed on detach */ -#define AMPDU_SCB_MAX_RELEASE 20 /* max # of mpdus released at a time */ +/* max number of mpdus in an ampdu */ +#define AMPDU_MAX_MPDU 32 +/* max number of mpdus in an ampdu to a legacy */ +#define AMPDU_NUM_MPDU_LEGACY 16 +/* max Tx ba window size (in pdu) */ +#define AMPDU_TX_BA_MAX_WSIZE 64 +/* default Tx ba window size (in pdu) */ +#define AMPDU_TX_BA_DEF_WSIZE 64 +/* default Rx ba window size (in pdu) */ +#define AMPDU_RX_BA_DEF_WSIZE 64 +/* max Rx ba window size (in pdu) */ +#define AMPDU_RX_BA_MAX_WSIZE 64 +/* max dur of tx ampdu (in msec) */ +#define AMPDU_MAX_DUR 5 +/* default tx retry limit */ +#define AMPDU_DEF_RETRY_LIMIT 5 +/* default tx retry limit at reg rate */ +#define AMPDU_DEF_RR_RETRY_LIMIT 2 +/* default weight of ampdu in txfifo */ +#define AMPDU_DEF_TXPKT_WEIGHT 2 +/* default ffpld reserved bytes */ +#define AMPDU_DEF_FFPLD_RSVD 2048 +/* # of inis to be freed on detach */ +#define AMPDU_INI_FREE 10 +/* max # of mpdus released at a time */ +#define AMPDU_SCB_MAX_RELEASE 20 #define NUM_FFPLD_FIFO 4 /* number of fifo concerned by pre-loading */ #define FFPLD_TX_MAX_UNFL 200 /* default value of the average number of ampdu @@ -59,44 +72,68 @@ * some counters might be redundant with the ones in wlc or ampdu structures. * This allows to maintain a specific state independently of * how often and/or when the wlc counters are updated. + * + * ampdu_pld_size: number of bytes to be pre-loaded + * mcs2ampdu_table: per-mcs max # of mpdus in an ampdu + * prev_txfunfl: num of underflows last read from the HW macstats counter + * accum_txfunfl: num of underflows since we modified pld params + * accum_txampdu: num of tx ampdu since we modified pld params + * prev_txampdu: previous reading of tx ampdu + * dmaxferrate: estimated dma avg xfer rate in kbits/sec */ 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 */ - u32 accum_txfunfl; /* num of underflows since we modified pld params */ - 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 */ + u16 ampdu_pld_size; + u8 mcs2ampdu_table[FFPLD_MAX_MCS + 1]; + u16 prev_txfunfl; + u32 accum_txfunfl; + u32 accum_txampdu; + u32 prev_txampdu; + u32 dmaxferrate; }; -/* AMPDU module specific state */ +/* AMPDU module specific state + * + * wlc: pointer to main wlc structure + * scb_handle: scb cubby handle to retrieve data from scb + * ini_enable: per-tid initiator enable/disable of ampdu + * ba_tx_wsize: Tx ba window size (in pdu) + * ba_rx_wsize: Rx ba window size (in pdu) + * retry_limit: mpdu transmit retry limit + * rr_retry_limit: mpdu transmit retry limit at regular rate + * retry_limit_tid: per-tid mpdu transmit retry limit + * rr_retry_limit_tid: per-tid mpdu transmit retry limit at regular rate + * mpdu_density: min mpdu spacing (0-7) ==> 2^(x-1)/8 usec + * max_pdu: max pdus allowed in ampdu + * dur: max duration of an ampdu (in msec) + * txpkt_weight: weight of ampdu in txfifo; reduces rate lag + * rx_factor: maximum rx ampdu factor (0-3) ==> 2^(13+x) bytes + * ffpld_rsvd: number of bytes to reserve for preload + * max_txlen: max size of ampdu per mcs, bw and sgi + * mfbr: enable multiple fallback rate + * tx_max_funl: underflows should be kept such that + * (tx_max_funfl*underflows) < tx frames + * fifo_tb: table of fifo infos + */ struct ampdu_info { - 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) */ - u8 ba_rx_wsize; /* Rx ba window size (in pdu) */ - u8 retry_limit; /* mpdu transmit retry limit */ - u8 rr_retry_limit; /* mpdu transmit retry limit at regular rate */ - u8 retry_limit_tid[AMPDU_MAX_SCB_TID]; /* per-tid mpdu transmit retry limit */ - /* per-tid mpdu transmit retry limit at regular rate */ + struct brcms_c_info *wlc; + int scb_handle; + u8 ini_enable[AMPDU_MAX_SCB_TID]; + u8 ba_tx_wsize; + u8 ba_rx_wsize; + u8 retry_limit; + u8 rr_retry_limit; + u8 retry_limit_tid[AMPDU_MAX_SCB_TID]; u8 rr_retry_limit_tid[AMPDU_MAX_SCB_TID]; - u8 mpdu_density; /* min mpdu spacing (0-7) ==> 2^(x-1)/8 usec */ - s8 max_pdu; /* max pdus allowed in ampdu */ - u8 dur; /* max duration of an ampdu (in msec) */ - u8 txpkt_weight; /* weight of ampdu in txfifo; reduces rate lag */ - u8 rx_factor; /* maximum rx ampdu factor (0-3) ==> 2^(13+x) bytes */ - u32 ffpld_rsvd; /* number of bytes to reserve for preload */ - u32 max_txlen[MCS_TABLE_SIZE][2][2]; /* max size of ampdu per mcs, bw and sgi */ - void *ini_free[AMPDU_INI_FREE]; /* array of ini's to be freed on detach */ - bool mfbr; /* enable multiple fallback rate */ - u32 tx_max_funl; /* underflows should be kept such that - * (tx_max_funfl*underflows) < tx frames - */ - /* table of fifo infos */ + u8 mpdu_density; + s8 max_pdu; + u8 dur; + u8 txpkt_weight; + u8 rx_factor; + u32 ffpld_rsvd; + u32 max_txlen[MCS_TABLE_SIZE][2][2]; + bool mfbr; + u32 tx_max_funl; struct brcms_fifo_info fifo_tb[NUM_FFPLD_FIFO]; - }; /* used for flushing ampdu packets */ @@ -163,7 +200,10 @@ struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc) ampdu->txpkt_weight = AMPDU_DEF_TXPKT_WEIGHT; ampdu->ffpld_rsvd = AMPDU_DEF_FFPLD_RSVD; - /* bump max ampdu rcv size to 64k for all 11n devices except 4321A0 and 4321A1 */ + /* + * bump max ampdu rcv size to 64k for all 11n + * devices except 4321A0 and 4321A1 + */ if (BRCMS_ISNPHY(wlc->band) && NREV_LT(wlc->band->phyrev, 2)) ampdu->rx_factor = IEEE80211_HT_MAX_AMPDU_32K; else @@ -189,17 +229,6 @@ struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc) void brcms_c_ampdu_detach(struct ampdu_info *ampdu) { - int i; - - if (!ampdu) - return; - - /* free all ini's which were to be freed on callbacks which were never called */ - for (i = 0; i < AMPDU_INI_FREE; i++) { - kfree(ampdu->ini_free[i]); - } - - brcms_c_module_unregister(ampdu->wlc->pub, "ampdu", ampdu); kfree(ampdu); } @@ -221,7 +250,8 @@ static void brcms_c_scb_ampdu_update_config(struct ampdu_info *ampdu, if (ampdu->max_pdu != AUTO) scb_ampdu->max_pdu = (u8) ampdu->max_pdu; - scb_ampdu->release = min_t(u8, scb_ampdu->max_pdu, AMPDU_SCB_MAX_RELEASE); + scb_ampdu->release = min_t(u8, scb_ampdu->max_pdu, + AMPDU_SCB_MAX_RELEASE); if (scb_ampdu->max_rx_ampdu_bytes) scb_ampdu->release = min_t(u8, scb_ampdu->release, @@ -317,13 +347,13 @@ static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int fid) txunfl_ratio = current_ampdu_cnt / fifo->accum_txfunfl; if (txunfl_ratio > ampdu->tx_max_funl) { - if (current_ampdu_cnt >= FFPLD_MAX_AMPDU_CNT) { + if (current_ampdu_cnt >= FFPLD_MAX_AMPDU_CNT) fifo->accum_txfunfl = 0; - } + return 0; } - max_mpdu = - min_t(u8, fifo->mcs2ampdu_table[FFPLD_MAX_MCS], AMPDU_NUM_MPDU_LEGACY); + max_mpdu = min_t(u8, fifo->mcs2ampdu_table[FFPLD_MAX_MCS], + AMPDU_NUM_MPDU_LEGACY); /* In case max value max_pdu is already lower than the fifo depth, there is nothing more we can do. @@ -345,11 +375,12 @@ static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int fid) brcms_c_scb_ampdu_update_config_all(ampdu); /* - compute a new dma xfer rate for max_mpdu @ max mcs. - This is the minimum dma rate that - can achieve no underflow condition for the current mpdu size. + * compute a new dma xfer rate for max_mpdu @ max mcs. + * This is the minimum dma rate that can achieve no + * underflow condition for the current mpdu size. + * + * note : we divide/multiply by 100 to avoid integer overflows */ - /* note : we divide/multiply by 100 to avoid integer overflows */ fifo->dmaxferrate = (((phy_rate / 100) * (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size)) @@ -388,8 +419,8 @@ static void brcms_c_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f) /* recompute the dma rate */ /* note : we divide/multiply by 100 to avoid integer overflows */ - max_mpdu = - min_t(u8, fifo->mcs2ampdu_table[FFPLD_MAX_MCS], AMPDU_NUM_MPDU_LEGACY); + max_mpdu = min_t(u8, fifo->mcs2ampdu_table[FFPLD_MAX_MCS], + AMPDU_NUM_MPDU_LEGACY); phy_rate = MCS_RATE(FFPLD_MAX_MCS, true, false); dma_rate = (((phy_rate / 100) * @@ -460,8 +491,8 @@ brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi, struct scb_ampdu_tid_ini *ini; u8 mcs = 0; bool use_rts = false, use_cts = false; - ratespec_t rspec = 0, rspec_fallback = 0; - ratespec_t rts_rspec = 0, rts_rspec_fallback = 0; + u32 rspec = 0, rspec_fallback = 0; + u32 rts_rspec = 0, rts_rspec_fallback = 0; u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ; struct ieee80211_rts *rts; u8 rr_retry_limit; @@ -486,10 +517,9 @@ brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi, /* Let pressure continue to build ... */ qlen = pktq_plen(&qi->q, prec); if (ini->tx_in_transit > 0 && - qlen < min(scb_ampdu->max_pdu, ini->ba_wsize)) { + qlen < min(scb_ampdu->max_pdu, ini->ba_wsize)) /* Collect multiple MPDU's to be sent in the next AMPDU */ return -EBUSY; - } /* at this point we intend to transmit an AMPDU */ rr_retry_limit = ampdu->rr_retry_limit_tid[tid]; @@ -665,13 +695,16 @@ brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi, break; } - if (count == scb_ampdu->max_pdu) { + if (count == scb_ampdu->max_pdu) break; - } - /* check to see if the next pkt is a candidate for aggregation */ + /* + * check to see if the next pkt is + * a candidate for aggregation + */ p = pktq_ppeek(&qi->q, prec); - tx_info = IEEE80211_SKB_CB(p); /* tx_info must be checked with current p */ + /* tx_info must be checked with current p */ + tx_info = IEEE80211_SKB_CB(p); if (p) { if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && @@ -686,7 +719,10 @@ brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi, continue; } - /* check if there are enough descriptors available */ + /* + * check if there are enough + * descriptors available + */ if (TXAVAIL(wlc, fifo) <= (seg_cnt + 1)) { wiphy_err(wiphy, "%s: No fifo space " "!!\n", __func__); @@ -797,10 +833,10 @@ brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi, /* inform rate_sel if it this is a rate probe pkt */ frameid = le16_to_cpu(txh->TxFrameID); - if (frameid & TXFID_RATE_PROBE_MASK) { + if (frameid & TXFID_RATE_PROBE_MASK) wiphy_err(wiphy, "%s: XXX what to do with " "TXFID_RATE_PROBE_MASK!?\n", __func__); - } + for (i = 0; i < count; i++) brcms_c_txfifo(wlc, fifo, pkt[i], i == (count - 1), ampdu->txpkt_weight); @@ -833,9 +869,8 @@ brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, while (((s1 = R_REG(&wlc->regs->frmtxstatus)) & TXS_V) == 0) { udelay(1); status_delay++; - if (status_delay > 10) { + if (status_delay > 10) return; /* error condition */ - } } s2 = R_REG(&wlc->regs->frmtxstatus2); @@ -923,9 +958,8 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, supr_status = txs->status & TX_STATUS_SUPR_MASK; if (txs->status & TX_STATUS_ACK_RCV) { - if (TX_STATUS_SUPR_UF == supr_status) { + if (TX_STATUS_SUPR_UF == supr_status) update_rate = false; - } WARN_ON(!(txs->status & TX_STATUS_INTERMEDIATE)); start_seq = txs->sequence >> SEQNUM_SHIFT; @@ -967,15 +1001,17 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, supr_status == TX_STATUS_SUPR_EXPTIME) { retry = false; } else if (supr_status == TX_STATUS_SUPR_EXPTIME) { - /* TX underflow : try tuning pre-loading or ampdu size */ + /* TX underflow: + * try tuning pre-loading or ampdu size + */ } else if (supr_status == TX_STATUS_SUPR_FRAG) { - /* if there were underflows, but pre-loading is not active, - notify rate adaptation. + /* + * if there were underflows, but pre-loading + * is not active, notify rate adaptation. */ if (brcms_c_ffpld_check_txfunfl(wlc, - prio2fifo[tid]) > 0) { + prio2fifo[tid]) > 0) tx_error = true; - } } } else if (txs->phyerr) { update_rate = false; @@ -1019,7 +1055,10 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, ini->tx_in_transit--; ini->txretry[index] = 0; - /* ampdu_ack_len: number of acked aggregated frames */ + /* + * ampdu_ack_len: + * number of acked aggregated frames + */ /* ampdu_len: number of aggregated frames */ brcms_c_ampdu_rate_status(wlc, tx_info, txs, mcs); @@ -1044,11 +1083,14 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, if (retry && (txrate[0].count < (int)retry_limit)) { ini->txretry[index]++; ini->tx_in_transit--; - /* Use high prededence for retransmit to give some punch */ + /* + * Use high prededence for retransmit to + * give some punch + */ /* 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)); + BRCMS_PRIO_TO_HI_PREC(tid)); } else { /* Retry timeout */ ini->tx_in_transit--; @@ -1156,7 +1198,10 @@ void brcms_c_ampdu_shm_upd(struct ampdu_info *ampdu) { struct brcms_c_info *wlc = ampdu->wlc; - /* Extend ucode internal watchdog timer to match larger received frames */ + /* + * Extend ucode internal watchdog timer to + * match larger received frames + */ if ((ampdu->rx_factor & IEEE80211_HT_AMPDU_PARM_FACTOR) == IEEE80211_HT_MAX_AMPDU_64K) { brcms_c_write_shm(wlc, M_MIMO_MAXSYM, MIMO_MAXSYM_MAX); @@ -1211,9 +1256,8 @@ void brcms_c_ampdu_flush(struct brcms_c_info *wlc, ampdu_pars.sta = sta; ampdu_pars.tid = tid; - for (prec = 0; prec < pq->num_prec; prec++) { + for (prec = 0; prec < pq->num_prec; prec++) brcmu_pktq_pflush(pq, prec, true, cb_del_ampdu_pkt, (void *)&du_pars); - } brcms_c_inval_dma_pkts(wlc->hw, sta, dma_cb_fn_ampdu); } diff --git a/drivers/staging/brcm80211/brcmsmac/antsel.c b/drivers/staging/brcm80211/brcmsmac/antsel.c index c4e76c0..23e0453 100644 --- a/drivers/staging/brcm80211/brcmsmac/antsel.c +++ b/drivers/staging/brcm80211/brcmsmac/antsel.c @@ -18,7 +18,6 @@ #include <net/mac80211.h> #include "types.h" -#include "bmac.h" #include "main.h" #include "phy_shim.h" #include "antsel.h" @@ -111,17 +110,16 @@ struct antsel_info *brcms_c_antsel_attach(struct brcms_c_info *wlc) if (((u16) getintvar(asi->pub->vars, "aa2g") == 7) || ((u16) getintvar(asi->pub->vars, "aa5g") == 7)) { asi->antsel_avail = true; - } else - if (((u16) getintvar(asi->pub->vars, "aa2g") == - 3) - || ((u16) getintvar(asi->pub->vars, "aa5g") - == 3)) { + } else if ( + (u16) getintvar(asi->pub->vars, "aa2g") == 3 || + (u16) getintvar(asi->pub->vars, "aa5g") == 3) { asi->antsel_avail = false; } else { asi->antsel_avail = false; wiphy_err(wlc->wiphy, "antsel_attach: 2o3 " "board cfg invalid\n"); } + break; default: break; @@ -261,7 +259,10 @@ static u8 brcms_c_antsel_id2antcfg(struct antsel_info *asi, u8 id) return antcfg; } -/* boardlevel antenna selection: convert ant_cfg to mimo_antsel (ucode interface) */ +/* + * boardlevel antenna selection: + * convert ant_cfg to mimo_antsel (ucode interface) + */ static u16 brcms_c_antsel_antcfg2antsel(struct antsel_info *asi, u8 ant_cfg) { u8 idx = BRCMS_ANTIDX_11N(BRCMS_ANTSEL_11N(ant_cfg)); @@ -295,7 +296,10 @@ static int brcms_c_antsel_cfgupd(struct antsel_info *asi, ant_cfg = antsel->ant_config[ANT_SELCFG_TX_DEF]; 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 */ + /* + * Update driver stats for currently selected + * default tx/rx antenna config + */ asi->antcfg_cur.ant_config[ANT_SELCFG_TX_DEF] = ant_cfg; /* 2) Update RX antconfig for all frames that are not unicast data @@ -304,7 +308,10 @@ static int brcms_c_antsel_cfgupd(struct antsel_info *asi, ant_cfg = antsel->ant_config[ANT_SELCFG_RX_DEF]; 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 */ + /* + * Update driver stats for currently selected + * default tx/rx antenna config + */ asi->antcfg_cur.ant_config[ANT_SELCFG_RX_DEF] = ant_cfg; return 0; diff --git a/drivers/staging/brcm80211/brcmsmac/bmac.c b/drivers/staging/brcm80211/brcmsmac/bmac.c deleted file mode 100644 index b25c517..0000000 --- a/drivers/staging/brcm80211/brcmsmac/bmac.c +++ /dev/null @@ -1,3593 +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/pci.h> -#include <net/mac80211.h> - -#include <brcm_hw_ids.h> -#include <aiutils.h> -#include <chipcommon.h> -#include "types.h" -#include "rate.h" -#include "phy/phy_hal.h" -#include "channel.h" -#include "main.h" -#include "ucode_loader.h" -#include "mac80211_if.h" -#include "bmac.h" - -#define TIMER_INTERVAL_WATCHDOG_BMAC 1000 /* watchdog timer, in unit of ms */ - -#define SYNTHPU_DLY_APHY_US 3700 /* a phy synthpu_dly time in us */ -#define SYNTHPU_DLY_BPHY_US 1050 /* b/g phy synthpu_dly time in us, default */ -#define SYNTHPU_DLY_NPHY_US 2048 /* n phy REV3 synthpu_dly time in us, default */ -#define SYNTHPU_DLY_LPPHY_US 300 /* lpphy synthpu_dly time in us */ - -#define SYNTHPU_DLY_PHY_US_QT 100 /* QT synthpu_dly time in us */ - -#ifndef BMAC_DUP_TO_REMOVE - -#define ANTCNT 10 /* vanilla M_MAX_ANTCNT value */ - -#endif /* BMAC_DUP_TO_REMOVE */ - -#define DMAREG(wlc_hw, direction, fifonum) \ - ((direction == DMA_TX) ? \ - (void *)&(wlc_hw->regs->fifo64regs[fifonum].dmaxmt) : \ - (void *)&(wlc_hw->regs->fifo64regs[fifonum].dmarcv)) - -#define APHY_SLOT_TIME 9 -#define BPHY_SLOT_TIME 20 - -/* - * The following table lists the buffer memory allocated to xmt fifos in HW. - * the size is in units of 256bytes(one block), total size is HW dependent - * ucode has default fifo partition, sw can overwrite if necessary - * - * This is documented in twiki under the topic UcodeTxFifo. Please ensure - * the twiki is updated before making changes. - */ - -#define XMTFIFOTBL_STARTREV 20 /* Starting corerev for the fifo size table */ - -static u16 xmtfifo_sz[][NFIFO] = { - {20, 192, 192, 21, 17, 5}, /* corerev 20: 5120, 49152, 49152, 5376, 4352, 1280 */ - {9, 58, 22, 14, 14, 5}, /* corerev 21: 2304, 14848, 5632, 3584, 3584, 1280 */ - {20, 192, 192, 21, 17, 5}, /* corerev 22: 5120, 49152, 49152, 5376, 4352, 1280 */ - {20, 192, 192, 21, 17, 5}, /* corerev 23: 5120, 49152, 49152, 5376, 4352, 1280 */ - {9, 58, 22, 14, 14, 5}, /* corerev 24: 2304, 14848, 5632, 3584, 3584, 1280 */ -}; - -static void brcms_b_clkctl_clk(struct brcms_hardware *wlc, uint mode); -static void brcms_b_coreinit(struct brcms_c_info *wlc); - -/* used by wlc_wakeucode_init() */ -static void brcms_c_write_inits(struct brcms_hardware *wlc_hw, - const struct d11init *inits); -static void brcms_ucode_write(struct brcms_hardware *wlc_hw, const u32 ucode[], - const uint nbytes); -static void brcms_ucode_download(struct brcms_hardware *wlc); -static void brcms_c_ucode_txant_set(struct brcms_hardware *wlc_hw); - -/* used by brcms_c_dpc() */ -static bool brcms_b_dotxstatus(struct brcms_hardware *wlc, - struct tx_status *txs, u32 s2); -static bool brcms_b_txstatus(struct brcms_hardware *wlc, bool bound, - bool *fatal); -static bool brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound); - -/* used by brcms_c_down() */ -static void brcms_c_flushqueues(struct brcms_c_info *wlc); - -static void brcms_c_write_mhf(struct brcms_hardware *wlc_hw, u16 *mhfs); -static void brcms_c_mctrl_reset(struct brcms_hardware *wlc_hw); -static void brcms_b_corerev_fifofixup(struct brcms_hardware *wlc_hw); -static bool brcms_b_tx_fifo_suspended(struct brcms_hardware *wlc_hw, - uint tx_fifo); -static void brcms_b_tx_fifo_suspend(struct brcms_hardware *wlc_hw, - uint tx_fifo); -static void brcms_b_tx_fifo_resume(struct brcms_hardware *wlc_hw, - uint tx_fifo); - -/* Low Level Prototypes */ -static int brcms_b_bandtype(struct brcms_hardware *wlc_hw); -static void brcms_b_info_init(struct brcms_hardware *wlc_hw); -static void brcms_b_xtal(struct brcms_hardware *wlc_hw, bool want); -static u16 brcms_b_read_objmem(struct brcms_hardware *wlc_hw, uint offset, - u32 sel); -static void brcms_b_write_objmem(struct brcms_hardware *wlc_hw, uint offset, - u16 v, u32 sel); -static void brcms_b_core_phy_clk(struct brcms_hardware *wlc_hw, bool clk); -static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme); -static void brcms_b_detach_dmapio(struct brcms_hardware *wlc_hw); -static void brcms_c_ucode_bsinit(struct brcms_hardware *wlc_hw); -static bool brcms_c_validboardtype(struct brcms_hardware *wlc); -static bool brcms_c_isgoodchip(struct brcms_hardware *wlc_hw); -static bool brcms_b_validate_chip_access(struct brcms_hardware *wlc_hw); -static char *brcms_c_get_macaddr(struct brcms_hardware *wlc_hw); -static void brcms_c_mhfdef(struct brcms_c_info *wlc, u16 *mhfs, u16 mhf2_init); -static void brcms_c_mctrl_write(struct brcms_hardware *wlc_hw); -static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool want, - mbool flags); -static void brcms_c_ucode_mute_override_set(struct brcms_hardware *wlc_hw); -static void brcms_c_ucode_mute_override_clear(struct brcms_hardware *wlc_hw); -static u32 brcms_c_wlintrsoff(struct brcms_c_info *wlc); -static void brcms_c_wlintrsrestore(struct brcms_c_info *wlc, u32 macintmask); -static void brcms_c_gpio_init(struct brcms_c_info *wlc); -static void brcms_c_write_hw_bcntemplate0(struct brcms_hardware *wlc_hw, - void *bcn, int len); -static void brcms_c_write_hw_bcntemplate1(struct brcms_hardware *wlc_hw, - void *bcn, int len); -static void brcms_b_bsinit(struct brcms_c_info *wlc, chanspec_t chanspec); -static u32 brcms_c_setband_inact(struct brcms_c_info *wlc, uint bandunit); -static void brcms_b_setband(struct brcms_hardware *wlc_hw, uint bandunit, - chanspec_t chanspec); -static void brcms_b_update_slot_timing(struct brcms_hardware *wlc_hw, - bool shortslot); -static void brcms_upd_ofdm_pctl1_table(struct brcms_hardware *wlc_hw); -static u16 brcms_b_ofdm_ratetable_offset(struct brcms_hardware *wlc_hw, - u8 rate); - -/* === Low Level functions === */ - -void brcms_b_set_shortslot(struct brcms_hardware *wlc_hw, bool shortslot) -{ - wlc_hw->shortslot = shortslot; - - if (BAND_2G(brcms_b_bandtype(wlc_hw)) && wlc_hw->up) { - brcms_c_suspend_mac_and_wait(wlc_hw->wlc); - brcms_b_update_slot_timing(wlc_hw, shortslot); - brcms_c_enable_mac(wlc_hw->wlc); - } -} - -/* - * Update the slot timing for standard 11b/g (20us slots) - * or shortslot 11g (9us slots) - * The PSM needs to be suspended for this call. - */ -static void brcms_b_update_slot_timing(struct brcms_hardware *wlc_hw, - bool shortslot) -{ - d11regs_t *regs; - - regs = wlc_hw->regs; - - if (shortslot) { - /* 11g short slot: 11a timing */ - W_REG(®s->ifs_slot, 0x0207); /* APHY_SLOT_TIME */ - brcms_b_write_shm(wlc_hw, M_DOT11_SLOT, APHY_SLOT_TIME); - } else { - /* 11g long slot: 11b timing */ - W_REG(®s->ifs_slot, 0x0212); /* BPHY_SLOT_TIME */ - brcms_b_write_shm(wlc_hw, M_DOT11_SLOT, BPHY_SLOT_TIME); - } -} - -static void brcms_c_ucode_bsinit(struct brcms_hardware *wlc_hw) -{ - struct wiphy *wiphy = wlc_hw->wlc->wiphy; - - /* init microcode host flags */ - brcms_c_write_mhf(wlc_hw, wlc_hw->band->mhfs); - - /* do band-specific ucode IHR, SHM, and SCR inits */ - if (D11REV_IS(wlc_hw->corerev, 23)) { - if (BRCMS_ISNPHY(wlc_hw->band)) { - brcms_c_write_inits(wlc_hw, d11n0bsinitvals16); - } else { - wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev" - " %d\n", __func__, wlc_hw->unit, - wlc_hw->corerev); - } - } else { - if (D11REV_IS(wlc_hw->corerev, 24)) { - if (BRCMS_ISLCNPHY(wlc_hw->band)) { - brcms_c_write_inits(wlc_hw, - d11lcn0bsinitvals24); - } else - wiphy_err(wiphy, "%s: wl%d: unsupported phy in" - " core rev %d\n", __func__, - wlc_hw->unit, wlc_hw->corerev); - } else { - wiphy_err(wiphy, "%s: wl%d: unsupported corerev %d\n", - __func__, wlc_hw->unit, wlc_hw->corerev); - } - } -} - -/* switch to new band but leave it inactive */ -static u32 brcms_c_setband_inact(struct brcms_c_info *wlc, - uint bandunit) -{ - struct brcms_hardware *wlc_hw = wlc->hw; - u32 macintmask; - - BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit); - - WARN_ON((R_REG(&wlc_hw->regs->maccontrol) & MCTL_EN_MAC) != 0); - - /* disable interrupts */ - macintmask = brcms_intrsoff(wlc->wl); - - /* radio off */ - wlc_phy_switch_radio(wlc_hw->band->pi, OFF); - - brcms_b_core_phy_clk(wlc_hw, OFF); - - brcms_c_setxband(wlc_hw, bandunit); - - return macintmask; -} - -/* Process received frames */ -/* - * Return true if more frames need to be processed. false otherwise. - * Param 'bound' indicates max. # frames to process before break out. - */ -static bool -brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound) -{ - struct sk_buff *p; - struct sk_buff *head = NULL; - struct sk_buff *tail = NULL; - uint n = 0; - uint bound_limit = bound ? wlc_hw->wlc->pub->tunables->rxbnd : -1; - struct brcms_d11rxhdr *wlc_rxhdr = NULL; - - BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); - /* gather received frames */ - while ((p = dma_rx(wlc_hw->di[fifo]))) { - - if (!tail) - head = tail = p; - else { - tail->prev = p; - tail = p; - } - - /* !give others some time to run! */ - if (++n >= bound_limit) - break; - } - - /* post more rbufs */ - dma_rxfill(wlc_hw->di[fifo]); - - /* process each frame */ - while ((p = head) != NULL) { - head = head->prev; - p->prev = NULL; - - wlc_rxhdr = (struct brcms_d11rxhdr *) p->data; - - /* compute the RSSI from d11rxhdr and record it in wlc_rxd11hr */ - wlc_phy_rssi_compute(wlc_hw->band->pi, wlc_rxhdr); - - brcms_c_recv(wlc_hw->wlc, p); - } - - return n >= bound_limit; -} - -/* second-level interrupt processing - * Return true if another dpc needs to be re-scheduled. false otherwise. - * Param 'bounded' indicates if applicable loops should be bounded. - */ -bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded) -{ - u32 macintstatus; - struct brcms_hardware *wlc_hw = wlc->hw; - d11regs_t *regs = wlc_hw->regs; - bool fatal = false; - struct wiphy *wiphy = wlc->wiphy; - - if (DEVICEREMOVED(wlc)) { - wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, - __func__); - brcms_down(wlc->wl); - return false; - } - - /* grab and clear the saved software intstatus bits */ - macintstatus = wlc->macintstatus; - wlc->macintstatus = 0; - - BCMMSG(wlc->wiphy, "wl%d: macintstatus 0x%x\n", - wlc_hw->unit, macintstatus); - - WARN_ON(macintstatus & MI_PRQ); /* PRQ Interrupt in non-MBSS */ - - /* BCN template is available */ - /* ZZZ: Use AP_ACTIVE ? */ - if (AP_ENAB(wlc->pub) && (!APSTA_ENAB(wlc->pub)) - && (macintstatus & MI_BCNTPL)) { - brcms_c_update_beacon(wlc); - } - - /* tx status */ - if (macintstatus & MI_TFS) { - if (brcms_b_txstatus(wlc->hw, bounded, &fatal)) - wlc->macintstatus |= MI_TFS; - if (fatal) { - wiphy_err(wiphy, "MI_TFS: fatal\n"); - goto fatal; - } - } - - if (macintstatus & (MI_TBTT | MI_DTIM_TBTT)) - brcms_c_tbtt(wlc); - - /* ATIM window end */ - if (macintstatus & MI_ATIMWINEND) { - BCMMSG(wlc->wiphy, "end of ATIM window\n"); - OR_REG(®s->maccommand, wlc->qvalid); - wlc->qvalid = 0; - } - - /* received data or control frame, MI_DMAINT is indication of RX_FIFO interrupt */ - if (macintstatus & MI_DMAINT) - if (brcms_b_recv(wlc_hw, RX_FIFO, bounded)) - wlc->macintstatus |= MI_DMAINT; - - /* TX FIFO suspend/flush completion */ - if (macintstatus & MI_TXSTOP) - brcms_b_tx_fifo_suspended(wlc_hw, TX_DATA_FIFO); - - /* noise sample collected */ - if (macintstatus & MI_BG_NOISE) { - wlc_phy_noise_sample_intr(wlc_hw->band->pi); - } - - if (macintstatus & MI_GP0) { - wiphy_err(wiphy, "wl%d: PSM microcode watchdog fired at %d " - "(seconds). Resetting.\n", wlc_hw->unit, wlc_hw->now); - - printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n", - __func__, wlc_hw->sih->chip, - wlc_hw->sih->chiprev); - /* big hammer */ - brcms_init(wlc->wl); - } - - /* gptimer timeout */ - if (macintstatus & MI_TO) { - W_REG(®s->gptimer, 0); - } - - if (macintstatus & MI_RFDISABLE) { - BCMMSG(wlc->wiphy, "wl%d: BMAC Detected a change on the" - " RF Disable Input\n", wlc_hw->unit); - brcms_rfkill_set_hw_state(wlc->wl); - } - - /* send any enq'd tx packets. Just makes sure to jump start tx */ - if (!pktq_empty(&wlc->pkt_queue->q)) - brcms_c_send_q(wlc); - - /* it isn't done and needs to be resched if macintstatus is non-zero */ - return wlc->macintstatus != 0; - - fatal: - brcms_init(wlc->wl); - return wlc->macintstatus != 0; -} - -/* common low-level watchdog code */ -void brcms_b_watchdog(void *arg) -{ - struct brcms_c_info *wlc = (struct brcms_c_info *) arg; - struct brcms_hardware *wlc_hw = wlc->hw; - - BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit); - - if (!wlc_hw->up) - return; - - /* increment second count */ - wlc_hw->now++; - - /* Check for FIFO error interrupts */ - brcms_b_fifoerrors(wlc_hw); - - /* make sure RX dma has buffers */ - dma_rxfill(wlc->hw->di[RX_FIFO]); - - wlc_phy_watchdog(wlc_hw->band->pi); -} - -void -brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, chanspec_t chanspec, - bool mute, struct txpwr_limits *txpwr) -{ - uint bandunit; - - BCMMSG(wlc_hw->wlc->wiphy, "wl%d: 0x%x\n", wlc_hw->unit, chanspec); - - wlc_hw->chanspec = chanspec; - - /* Switch bands if necessary */ - if (NBANDS_HW(wlc_hw) > 1) { - bandunit = CHSPEC_BANDUNIT(chanspec); - if (wlc_hw->band->bandunit != bandunit) { - /* brcms_b_setband disables other bandunit, - * use light band switch if not up yet - */ - if (wlc_hw->up) { - wlc_phy_chanspec_radio_set(wlc_hw-> - bandstate[bandunit]-> - pi, chanspec); - brcms_b_setband(wlc_hw, bandunit, chanspec); - } else { - brcms_c_setxband(wlc_hw, bandunit); - } - } - } - - wlc_phy_initcal_enable(wlc_hw->band->pi, !mute); - - if (!wlc_hw->up) { - if (wlc_hw->clk) - wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr, - chanspec); - wlc_phy_chanspec_radio_set(wlc_hw->band->pi, chanspec); - } else { - wlc_phy_chanspec_set(wlc_hw->band->pi, chanspec); - wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr, chanspec); - - /* Update muting of the channel */ - brcms_b_mute(wlc_hw, mute, 0); - } -} - -int brcms_b_state_get(struct brcms_hardware *wlc_hw, - struct brcms_b_state *state) -{ - state->machwcap = wlc_hw->machwcap; - - return 0; -} - -static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme) -{ - uint i; - char name[8]; - /* ucode host flag 2 needed for pio mode, independent of band and fifo */ - u16 pio_mhf2 = 0; - struct brcms_hardware *wlc_hw = wlc->hw; - uint unit = wlc_hw->unit; - struct brcms_tunables *tune = wlc->pub->tunables; - struct wiphy *wiphy = wlc->wiphy; - - /* name and offsets for dma_attach */ - snprintf(name, sizeof(name), "wl%d", unit); - - if (wlc_hw->di[0] == 0) { /* Init FIFOs */ - uint addrwidth; - int dma_attach_err = 0; - /* Find out the DMA addressing capability and let OS know - * All the channels within one DMA core have 'common-minimum' same - * capability - */ - addrwidth = - dma_addrwidth(wlc_hw->sih, DMAREG(wlc_hw, DMA_TX, 0)); - - if (!wl_alloc_dma_resources(wlc_hw->wlc->wl, addrwidth)) { - wiphy_err(wiphy, "wl%d: wlc_attach: alloc_dma_" - "resources failed\n", unit); - return false; - } - - /* - * FIFO 0 - * TX: TX_AC_BK_FIFO (TX AC Background data packets) - * RX: RX_FIFO (RX data packets) - */ - wlc_hw->di[0] = dma_attach(name, wlc_hw->sih, - (wme ? DMAREG(wlc_hw, DMA_TX, 0) : - NULL), DMAREG(wlc_hw, DMA_RX, 0), - (wme ? tune->ntxd : 0), tune->nrxd, - tune->rxbufsz, -1, tune->nrxbufpost, - BRCMS_HWRXOFF, &brcm_msg_level); - dma_attach_err |= (NULL == wlc_hw->di[0]); - - /* - * FIFO 1 - * TX: TX_AC_BE_FIFO (TX AC Best-Effort data packets) - * (legacy) TX_DATA_FIFO (TX data packets) - * RX: UNUSED - */ - wlc_hw->di[1] = dma_attach(name, wlc_hw->sih, - DMAREG(wlc_hw, DMA_TX, 1), NULL, - tune->ntxd, 0, 0, -1, 0, 0, - &brcm_msg_level); - dma_attach_err |= (NULL == wlc_hw->di[1]); - - /* - * FIFO 2 - * TX: TX_AC_VI_FIFO (TX AC Video data packets) - * RX: UNUSED - */ - wlc_hw->di[2] = dma_attach(name, wlc_hw->sih, - DMAREG(wlc_hw, DMA_TX, 2), NULL, - tune->ntxd, 0, 0, -1, 0, 0, - &brcm_msg_level); - dma_attach_err |= (NULL == wlc_hw->di[2]); - /* - * FIFO 3 - * TX: TX_AC_VO_FIFO (TX AC Voice data packets) - * (legacy) TX_CTL_FIFO (TX control & mgmt packets) - */ - wlc_hw->di[3] = dma_attach(name, wlc_hw->sih, - DMAREG(wlc_hw, DMA_TX, 3), - NULL, tune->ntxd, 0, 0, -1, - 0, 0, &brcm_msg_level); - dma_attach_err |= (NULL == wlc_hw->di[3]); -/* Cleaner to leave this as if with AP defined */ - - if (dma_attach_err) { - wiphy_err(wiphy, "wl%d: wlc_attach: dma_attach failed" - "\n", unit); - return false; - } - - /* get pointer to dma engine tx flow control variable */ - for (i = 0; i < NFIFO; i++) - if (wlc_hw->di[i]) - wlc_hw->txavail[i] = - (uint *) dma_getvar(wlc_hw->di[i], - "&txavail"); - } - - /* initial ucode host flags */ - brcms_c_mhfdef(wlc, wlc_hw->band->mhfs, pio_mhf2); - - return true; -} - -static void brcms_b_detach_dmapio(struct brcms_hardware *wlc_hw) -{ - uint j; - - for (j = 0; j < NFIFO; j++) { - if (wlc_hw->di[j]) { - dma_detach(wlc_hw->di[j]); - wlc_hw->di[j] = NULL; - } - } -} - -/* low level attach - * run backplane attach, init nvram - * run phy attach - * initialize software state for each core and band - * put the whole chip in reset(driver down state), no clock - */ -int brcms_b_attach(struct brcms_c_info *wlc, u16 vendor, u16 device, uint unit, - bool piomode, void *regsva, uint bustype, void *btparam) -{ - struct brcms_hardware *wlc_hw; - d11regs_t *regs; - char *macaddr = NULL; - char *vars; - uint err = 0; - uint j; - bool wme = false; - struct shared_phy_params sha_params; - struct wiphy *wiphy = wlc->wiphy; - - BCMMSG(wlc->wiphy, "wl%d: vendor 0x%x device 0x%x\n", unit, vendor, - device); - - wme = true; - - wlc_hw = wlc->hw; - wlc_hw->wlc = wlc; - wlc_hw->unit = unit; - wlc_hw->band = wlc_hw->bandstate[0]; - wlc_hw->_piomode = piomode; - - /* populate struct brcms_hardware with default values */ - brcms_b_info_init(wlc_hw); - - /* - * Do the hardware portion of the attach. - * Also initialize software state that depends on the particular hardware - * we are running. - */ - wlc_hw->sih = ai_attach(regsva, bustype, btparam, - &wlc_hw->vars, &wlc_hw->vars_size); - if (wlc_hw->sih == NULL) { - wiphy_err(wiphy, "wl%d: brcms_b_attach: si_attach failed\n", - unit); - err = 11; - goto fail; - } - vars = wlc_hw->vars; - - /* - * Get vendid/devid nvram overwrites, which could be different - * than those the BIOS recognizes for devices on PCMCIA_BUS, - * SDIO_BUS, and SROMless devices on PCI_BUS. - */ -#ifdef BCMBUSTYPE - bustype = BCMBUSTYPE; -#endif - if (bustype != SI_BUS) { - char *var; - - var = getvar(vars, "vendid"); - if (var) { - vendor = (u16) simple_strtoul(var, NULL, 0); - wiphy_err(wiphy, "Overriding vendor id = 0x%x\n", - vendor); - } - var = getvar(vars, "devid"); - if (var) { - u16 devid = (u16) simple_strtoul(var, NULL, 0); - if (devid != 0xffff) { - device = devid; - wiphy_err(wiphy, "Overriding device id = 0x%x" - "\n", device); - } - } - - /* verify again the device is supported */ - if (!brcms_c_chipmatch(vendor, device)) { - wiphy_err(wiphy, "wl%d: brcms_b_attach: Unsupported " - "vendor/device (0x%x/0x%x)\n", - unit, vendor, device); - err = 12; - goto fail; - } - } - - wlc_hw->vendorid = vendor; - wlc_hw->deviceid = device; - - /* set bar0 window to point at D11 core */ - wlc_hw->regs = (d11regs_t *) ai_setcore(wlc_hw->sih, D11_CORE_ID, 0); - wlc_hw->corerev = ai_corerev(wlc_hw->sih); - - regs = wlc_hw->regs; - - wlc->regs = wlc_hw->regs; - - /* validate chip, chiprev and corerev */ - if (!brcms_c_isgoodchip(wlc_hw)) { - err = 13; - goto fail; - } - - /* initialize power control registers */ - ai_clkctl_init(wlc_hw->sih); - - /* request fastclock and force fastclock for the rest of attach - * bring the d11 core out of reset. - * For PMU chips, the first wlc_clkctl_clk is no-op since core-clk is still false; - * But it will be called again inside wlc_corereset, after d11 is out of reset. - */ - brcms_b_clkctl_clk(wlc_hw, CLK_FAST); - brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS); - - if (!brcms_b_validate_chip_access(wlc_hw)) { - wiphy_err(wiphy, "wl%d: brcms_b_attach: validate_chip_access " - "failed\n", unit); - err = 14; - goto fail; - } - - /* get the board rev, used just below */ - j = getintvar(vars, "boardrev"); - /* promote srom boardrev of 0xFF to 1 */ - if (j == BOARDREV_PROMOTABLE) - j = BOARDREV_PROMOTED; - wlc_hw->boardrev = (u16) j; - if (!brcms_c_validboardtype(wlc_hw)) { - wiphy_err(wiphy, "wl%d: brcms_b_attach: Unsupported Broadcom " - "board type (0x%x)" " or revision level (0x%x)\n", - unit, wlc_hw->sih->boardtype, wlc_hw->boardrev); - err = 15; - goto fail; - } - wlc_hw->sromrev = (u8) getintvar(vars, "sromrev"); - wlc_hw->boardflags = (u32) getintvar(vars, "boardflags"); - wlc_hw->boardflags2 = (u32) getintvar(vars, "boardflags2"); - - if (wlc_hw->boardflags & BFL_NOPLLDOWN) - brcms_b_pllreq(wlc_hw, true, BRCMS_PLLREQ_SHARED); - - if ((wlc_hw->sih->bustype == PCI_BUS) - && (ai_pci_war16165(wlc_hw->sih))) - wlc->war16165 = true; - - /* check device id(srom, nvram etc.) to set bands */ - if (wlc_hw->deviceid == BCM43224_D11N_ID || - wlc_hw->deviceid == BCM43224_D11N_ID_VEN1) { - /* Dualband boards */ - wlc_hw->_nbands = 2; - } else - wlc_hw->_nbands = 1; - - if ((wlc_hw->sih->chip == BCM43225_CHIP_ID)) - wlc_hw->_nbands = 1; - - /* BMAC_NOTE: remove init of pub values when brcms_c_attach() - * unconditionally does the init of these values - */ - wlc->vendorid = wlc_hw->vendorid; - wlc->deviceid = wlc_hw->deviceid; - wlc->pub->sih = wlc_hw->sih; - wlc->pub->corerev = wlc_hw->corerev; - wlc->pub->sromrev = wlc_hw->sromrev; - wlc->pub->boardrev = wlc_hw->boardrev; - wlc->pub->boardflags = wlc_hw->boardflags; - wlc->pub->boardflags2 = wlc_hw->boardflags2; - wlc->pub->_nbands = wlc_hw->_nbands; - - wlc_hw->physhim = wlc_phy_shim_attach(wlc_hw, wlc->wl, wlc); - - if (wlc_hw->physhim == NULL) { - wiphy_err(wiphy, "wl%d: brcms_b_attach: wlc_phy_shim_attach " - "failed\n", unit); - err = 25; - goto fail; - } - - /* pass all the parameters to wlc_phy_shared_attach in one struct */ - sha_params.sih = wlc_hw->sih; - sha_params.physhim = wlc_hw->physhim; - sha_params.unit = unit; - sha_params.corerev = wlc_hw->corerev; - sha_params.vars = vars; - sha_params.vid = wlc_hw->vendorid; - sha_params.did = wlc_hw->deviceid; - sha_params.chip = wlc_hw->sih->chip; - sha_params.chiprev = wlc_hw->sih->chiprev; - sha_params.chippkg = wlc_hw->sih->chippkg; - sha_params.sromrev = wlc_hw->sromrev; - sha_params.boardtype = wlc_hw->sih->boardtype; - sha_params.boardrev = wlc_hw->boardrev; - sha_params.boardvendor = wlc_hw->sih->boardvendor; - sha_params.boardflags = wlc_hw->boardflags; - sha_params.boardflags2 = wlc_hw->boardflags2; - sha_params.bustype = wlc_hw->sih->bustype; - sha_params.buscorerev = wlc_hw->sih->buscorerev; - - /* alloc and save pointer to shared phy state area */ - wlc_hw->phy_sh = wlc_phy_shared_attach(&sha_params); - if (!wlc_hw->phy_sh) { - err = 16; - goto fail; - } - - /* initialize software state for each core and band */ - for (j = 0; j < NBANDS_HW(wlc_hw); j++) { - /* - * band0 is always 2.4Ghz - * band1, if present, is 5Ghz - */ - - /* So if this is a single band 11a card, use band 1 */ - if (IS_SINGLEBAND_5G(wlc_hw->deviceid)) - j = BAND_5G_INDEX; - - brcms_c_setxband(wlc_hw, j); - - wlc_hw->band->bandunit = j; - wlc_hw->band->bandtype = j ? BRCM_BAND_5G : BRCM_BAND_2G; - wlc->band->bandunit = j; - wlc->band->bandtype = j ? BRCM_BAND_5G : BRCM_BAND_2G; - wlc->core->coreidx = ai_coreidx(wlc_hw->sih); - - wlc_hw->machwcap = R_REG(®s->machwcap); - wlc_hw->machwcap_backup = wlc_hw->machwcap; - - /* init tx fifo size */ - wlc_hw->xmtfifo_sz = - xmtfifo_sz[(wlc_hw->corerev - XMTFIFOTBL_STARTREV)]; - - /* Get a phy for this band */ - wlc_hw->band->pi = wlc_phy_attach(wlc_hw->phy_sh, - (void *)regs, brcms_b_bandtype(wlc_hw), vars, - wlc->wiphy); - if (wlc_hw->band->pi == NULL) { - wiphy_err(wiphy, "wl%d: brcms_b_attach: wlc_phy_" - "attach failed\n", unit); - err = 17; - goto fail; - } - - wlc_phy_machwcap_set(wlc_hw->band->pi, wlc_hw->machwcap); - - wlc_phy_get_phyversion(wlc_hw->band->pi, &wlc_hw->band->phytype, - &wlc_hw->band->phyrev, - &wlc_hw->band->radioid, - &wlc_hw->band->radiorev); - wlc_hw->band->abgphy_encore = - wlc_phy_get_encore(wlc_hw->band->pi); - wlc->band->abgphy_encore = wlc_phy_get_encore(wlc_hw->band->pi); - wlc_hw->band->core_flags = - wlc_phy_get_coreflags(wlc_hw->band->pi); - - /* verify good phy_type & supported phy revision */ - if (BRCMS_ISNPHY(wlc_hw->band)) { - if (NCONF_HAS(wlc_hw->band->phyrev)) - goto good_phy; - else - goto bad_phy; - } else if (BRCMS_ISLCNPHY(wlc_hw->band)) { - if (LCNCONF_HAS(wlc_hw->band->phyrev)) - goto good_phy; - else - goto bad_phy; - } else { - bad_phy: - wiphy_err(wiphy, "wl%d: brcms_b_attach: unsupported " - "phy type/rev (%d/%d)\n", unit, - wlc_hw->band->phytype, wlc_hw->band->phyrev); - err = 18; - goto fail; - } - - good_phy: - /* BMAC_NOTE: wlc->band->pi should not be set below and should be done in the - * high level attach. However we can not make that change until all low level access - * is changed to wlc_hw->band->pi. Instead do the wlc->band->pi init below, keeping - * wlc_hw->band->pi as well for incremental update of low level fns, and cut over - * low only init when all fns updated. - */ - wlc->band->pi = wlc_hw->band->pi; - wlc->band->phytype = wlc_hw->band->phytype; - wlc->band->phyrev = wlc_hw->band->phyrev; - wlc->band->radioid = wlc_hw->band->radioid; - wlc->band->radiorev = wlc_hw->band->radiorev; - - /* default contention windows size limits */ - wlc_hw->band->CWmin = APHY_CWMIN; - wlc_hw->band->CWmax = PHY_CWMAX; - - if (!brcms_b_attach_dmapio(wlc, j, wme)) { - err = 19; - goto fail; - } - } - - /* disable core to match driver "down" state */ - brcms_c_coredisable(wlc_hw); - - /* Match driver "down" state */ - if (wlc_hw->sih->bustype == PCI_BUS) - ai_pci_down(wlc_hw->sih); - - /* register sb interrupt callback functions */ - ai_register_intr_callback(wlc_hw->sih, (void *)brcms_c_wlintrsoff, - (void *)brcms_c_wlintrsrestore, NULL, wlc); - - /* turn off pll and xtal to match driver "down" state */ - brcms_b_xtal(wlc_hw, OFF); - - /* ********************************************************************* - * The hardware is in the DOWN state at this point. D11 core - * or cores are in reset with clocks off, and the board PLLs - * are off if possible. - * - * Beyond this point, wlc->sbclk == false and chip registers - * should not be touched. - ********************************************************************* - */ - - /* init etheraddr state variables */ - macaddr = brcms_c_get_macaddr(wlc_hw); - if (macaddr == NULL) { - wiphy_err(wiphy, "wl%d: brcms_b_attach: macaddr not found\n", - unit); - err = 21; - goto fail; - } - brcmu_ether_atoe(macaddr, wlc_hw->etheraddr); - if (is_broadcast_ether_addr(wlc_hw->etheraddr) || - is_zero_ether_addr(wlc_hw->etheraddr)) { - wiphy_err(wiphy, "wl%d: brcms_b_attach: bad macaddr %s\n", - unit, macaddr); - err = 22; - goto fail; - } - - BCMMSG(wlc->wiphy, - "deviceid 0x%x nbands %d board 0x%x macaddr: %s\n", - wlc_hw->deviceid, wlc_hw->_nbands, - wlc_hw->sih->boardtype, macaddr); - - return err; - - fail: - wiphy_err(wiphy, "wl%d: brcms_b_attach: failed with err %d\n", unit, - err); - return err; -} - -/* - * Initialize brcms_c_info default values ... - * may get overrides later in this function - * BMAC_NOTES, move low out and resolve the dangling ones - */ -static void brcms_b_info_init(struct brcms_hardware *wlc_hw) -{ - struct brcms_c_info *wlc = wlc_hw->wlc; - - /* set default sw macintmask value */ - wlc->defmacintmask = DEF_MACINTMASK; - - /* various 802.11g modes */ - wlc_hw->shortslot = false; - - wlc_hw->SFBL = RETRY_SHORT_FB; - wlc_hw->LFBL = RETRY_LONG_FB; - - /* default mac retry limits */ - wlc_hw->SRL = RETRY_SHORT_DEF; - wlc_hw->LRL = RETRY_LONG_DEF; - wlc_hw->chanspec = CH20MHZ_CHSPEC(1); -} - -/* - * low level detach - */ -int brcms_b_detach(struct brcms_c_info *wlc) -{ - uint i; - struct brcms_hw_band *band; - struct brcms_hardware *wlc_hw = wlc->hw; - int callbacks; - - callbacks = 0; - - if (wlc_hw->sih) { - /* detach interrupt sync mechanism since interrupt is disabled and per-port - * interrupt object may has been freed. this must be done before sb core switch - */ - ai_deregister_intr_callback(wlc_hw->sih); - - if (wlc_hw->sih->bustype == PCI_BUS) - ai_pci_sleep(wlc_hw->sih); - } - - brcms_b_detach_dmapio(wlc_hw); - - band = wlc_hw->band; - for (i = 0; i < NBANDS_HW(wlc_hw); i++) { - if (band->pi) { - /* Detach this band's phy */ - wlc_phy_detach(band->pi); - band->pi = NULL; - } - band = wlc_hw->bandstate[OTHERBANDUNIT(wlc)]; - } - - /* Free shared phy state */ - kfree(wlc_hw->phy_sh); - - wlc_phy_shim_detach(wlc_hw->physhim); - - /* free vars */ - kfree(wlc_hw->vars); - wlc_hw->vars = NULL; - - if (wlc_hw->sih) { - ai_detach(wlc_hw->sih); - wlc_hw->sih = NULL; - } - - return callbacks; - -} - -void brcms_b_reset(struct brcms_hardware *wlc_hw) -{ - BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); - - /* reset the core */ - if (!DEVICEREMOVED(wlc_hw->wlc)) - brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS); - - /* purge the dma rings */ - brcms_c_flushqueues(wlc_hw->wlc); - - brcms_c_reset_bmac_done(wlc_hw->wlc); -} - -void -brcms_b_init(struct brcms_hardware *wlc_hw, chanspec_t chanspec, - bool mute) { - u32 macintmask; - bool fastclk; - struct brcms_c_info *wlc = wlc_hw->wlc; - - BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); - - /* request FAST clock if not on */ - fastclk = wlc_hw->forcefastclk; - if (!fastclk) - brcms_b_clkctl_clk(wlc_hw, CLK_FAST); - - /* disable interrupts */ - macintmask = brcms_intrsoff(wlc->wl); - - /* set up the specified band and chanspec */ - brcms_c_setxband(wlc_hw, CHSPEC_BANDUNIT(chanspec)); - wlc_phy_chanspec_radio_set(wlc_hw->band->pi, chanspec); - - /* do one-time phy inits and calibration */ - wlc_phy_cal_init(wlc_hw->band->pi); - - /* core-specific initialization */ - brcms_b_coreinit(wlc); - - /* suspend the tx fifos and mute the phy for preism cac time */ - if (mute) - brcms_b_mute(wlc_hw, ON, PHY_MUTE_FOR_PREISM); - - /* band-specific inits */ - brcms_b_bsinit(wlc, chanspec); - - /* restore macintmask */ - brcms_intrsrestore(wlc->wl, macintmask); - - /* seed wake_override with BRCMS_WAKE_OVERRIDE_MACSUSPEND since the mac - * is suspended and brcms_c_enable_mac() will clear this override bit. - */ - mboolset(wlc_hw->wake_override, BRCMS_WAKE_OVERRIDE_MACSUSPEND); - - /* - * initialize mac_suspend_depth to 1 to match ucode initial suspended state - */ - wlc_hw->mac_suspend_depth = 1; - - /* restore the clk */ - if (!fastclk) - brcms_b_clkctl_clk(wlc_hw, CLK_DYNAMIC); -} - -int brcms_b_up_prep(struct brcms_hardware *wlc_hw) -{ - uint coremask; - - BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); - - /* - * Enable pll and xtal, initialize the power control registers, - * and force fastclock for the remainder of brcms_c_up(). - */ - brcms_b_xtal(wlc_hw, ON); - ai_clkctl_init(wlc_hw->sih); - brcms_b_clkctl_clk(wlc_hw, CLK_FAST); - - /* - * Configure pci/pcmcia here instead of in brcms_c_attach() - * to allow mfg hotswap: down, hotswap (chip power cycle), up. - */ - coremask = (1 << wlc_hw->wlc->core->coreidx); - - if (wlc_hw->sih->bustype == PCI_BUS) - ai_pci_setup(wlc_hw->sih, coremask); - - /* - * Need to read the hwradio status here to cover the case where the system - * is loaded with the hw radio disabled. We do not want to bring the driver up in this case. - */ - if (brcms_b_radio_read_hwdisabled(wlc_hw)) { - /* put SB PCI in down state again */ - if (wlc_hw->sih->bustype == PCI_BUS) - ai_pci_down(wlc_hw->sih); - brcms_b_xtal(wlc_hw, OFF); - return -ENOMEDIUM; - } - - if (wlc_hw->sih->bustype == PCI_BUS) - ai_pci_up(wlc_hw->sih); - - /* reset the d11 core */ - brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS); - - return 0; -} - -int brcms_b_up_finish(struct brcms_hardware *wlc_hw) -{ - BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); - - wlc_hw->up = true; - wlc_phy_hw_state_upd(wlc_hw->band->pi, true); - - /* FULLY enable dynamic power control and d11 core interrupt */ - brcms_b_clkctl_clk(wlc_hw, CLK_DYNAMIC); - brcms_intrson(wlc_hw->wlc->wl); - return 0; -} - -int brcms_b_bmac_down_prep(struct brcms_hardware *wlc_hw) -{ - bool dev_gone; - uint callbacks = 0; - - BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); - - if (!wlc_hw->up) - return callbacks; - - dev_gone = DEVICEREMOVED(wlc_hw->wlc); - - /* disable interrupts */ - if (dev_gone) - wlc_hw->wlc->macintmask = 0; - else { - /* now disable interrupts */ - brcms_intrsoff(wlc_hw->wlc->wl); - - /* ensure we're running on the pll clock again */ - brcms_b_clkctl_clk(wlc_hw, CLK_FAST); - } - /* down phy at the last of this stage */ - callbacks += wlc_phy_down(wlc_hw->band->pi); - - return callbacks; -} - -int brcms_b_down_finish(struct brcms_hardware *wlc_hw) -{ - uint callbacks = 0; - bool dev_gone; - - BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); - - if (!wlc_hw->up) - return callbacks; - - wlc_hw->up = false; - wlc_phy_hw_state_upd(wlc_hw->band->pi, false); - - dev_gone = DEVICEREMOVED(wlc_hw->wlc); - - if (dev_gone) { - wlc_hw->sbclk = false; - wlc_hw->clk = false; - wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false); - - /* reclaim any posted packets */ - brcms_c_flushqueues(wlc_hw->wlc); - } else { - - /* Reset and disable the core */ - if (ai_iscoreup(wlc_hw->sih)) { - if (R_REG(&wlc_hw->regs->maccontrol) & - MCTL_EN_MAC) - brcms_c_suspend_mac_and_wait(wlc_hw->wlc); - callbacks += brcms_reset(wlc_hw->wlc->wl); - brcms_c_coredisable(wlc_hw); - } - - /* turn off primary xtal and pll */ - if (!wlc_hw->noreset) { - if (wlc_hw->sih->bustype == PCI_BUS) - ai_pci_down(wlc_hw->sih); - brcms_b_xtal(wlc_hw, OFF); - } - } - - return callbacks; -} - -void brcms_b_wait_for_wake(struct brcms_hardware *wlc_hw) -{ - /* delay before first read of ucode state */ - udelay(40); - - /* wait until ucode is no longer asleep */ - SPINWAIT((brcms_b_read_shm(wlc_hw, M_UCODE_DBGST) == - DBGST_ASLEEP), wlc_hw->wlc->fastpwrup_dly); -} - -void brcms_b_hw_etheraddr(struct brcms_hardware *wlc_hw, u8 *ea) -{ - memcpy(ea, wlc_hw->etheraddr, ETH_ALEN); -} - -static int brcms_b_bandtype(struct brcms_hardware *wlc_hw) -{ - return wlc_hw->band->bandtype; -} - -/* control chip clock to save power, enable dynamic clock or force fast clock */ -static void brcms_b_clkctl_clk(struct brcms_hardware *wlc_hw, uint mode) -{ - if (PMUCTL_ENAB(wlc_hw->sih)) { - /* new chips with PMU, CCS_FORCEHT will distribute the HT clock on backplane, - * but mac core will still run on ALP(not HT) when it enters powersave mode, - * which means the FCA bit may not be set. - * should wakeup mac if driver wants it to run on HT. - */ - - if (wlc_hw->clk) { - if (mode == CLK_FAST) { - OR_REG(&wlc_hw->regs->clk_ctl_st, - CCS_FORCEHT); - - udelay(64); - - SPINWAIT(((R_REG - (&wlc_hw->regs-> - clk_ctl_st) & CCS_HTAVAIL) == 0), - PMU_MAX_TRANSITION_DLY); - WARN_ON(!(R_REG - (&wlc_hw->regs-> - clk_ctl_st) & CCS_HTAVAIL)); - } else { - if ((wlc_hw->sih->pmurev == 0) && - (R_REG - (&wlc_hw->regs-> - clk_ctl_st) & (CCS_FORCEHT | CCS_HTAREQ))) - SPINWAIT(((R_REG - (&wlc_hw->regs-> - clk_ctl_st) & CCS_HTAVAIL) - == 0), - PMU_MAX_TRANSITION_DLY); - AND_REG(&wlc_hw->regs->clk_ctl_st, - ~CCS_FORCEHT); - } - } - wlc_hw->forcefastclk = (mode == CLK_FAST); - } else { - - /* old chips w/o PMU, force HT through cc, - * then use FCA to verify mac is running fast clock - */ - - wlc_hw->forcefastclk = ai_clkctl_cc(wlc_hw->sih, mode); - - /* check fast clock is available (if core is not in reset) */ - if (wlc_hw->forcefastclk && wlc_hw->clk) - WARN_ON(!(ai_core_sflags(wlc_hw->sih, 0, 0) & - SISF_FCLKA)); - - /* keep the ucode wake bit on if forcefastclk is on - * since we do not want ucode to put us back to slow clock - * when it dozes for PM mode. - * Code below matches the wake override bit with current forcefastclk state - * Only setting bit in wake_override instead of waking ucode immediately - * since old code (wlc.c 1.4499) had this behavior. Older code set - * wlc->forcefastclk but only had the wake happen if the wakup_ucode work - * (protected by an up check) was executed just below. - */ - if (wlc_hw->forcefastclk) - mboolset(wlc_hw->wake_override, - BRCMS_WAKE_OVERRIDE_FORCEFAST); - else - mboolclr(wlc_hw->wake_override, - BRCMS_WAKE_OVERRIDE_FORCEFAST); - } -} - -/* set initial host flags value */ -static void -brcms_c_mhfdef(struct brcms_c_info *wlc, u16 *mhfs, u16 mhf2_init) -{ - struct brcms_hardware *wlc_hw = wlc->hw; - - memset(mhfs, 0, MHFMAX * sizeof(u16)); - - mhfs[MHF2] |= mhf2_init; - - /* prohibit use of slowclock on multifunction boards */ - if (wlc_hw->boardflags & BFL_NOPLLDOWN) - mhfs[MHF1] |= MHF1_FORCEFASTCLK; - - if (BRCMS_ISNPHY(wlc_hw->band) && NREV_LT(wlc_hw->band->phyrev, 2)) { - mhfs[MHF2] |= MHF2_NPHY40MHZ_WAR; - mhfs[MHF1] |= MHF1_IQSWAP_WAR; - } -} - -/* set or clear ucode host flag bits - * it has an optimization for no-change write - * it only writes through shared memory when the core has clock; - * pre-CLK changes should use wlc_write_mhf to get around the optimization - * - * - * bands values are: BRCM_BAND_AUTO <--- Current band only - * BRCM_BAND_5G <--- 5G band only - * BRCM_BAND_2G <--- 2G band only - * BRCM_BAND_ALL <--- All bands - */ -void -brcms_b_mhf(struct brcms_hardware *wlc_hw, u8 idx, u16 mask, u16 val, - int bands) -{ - u16 save; - u16 addr[MHFMAX] = { - M_HOST_FLAGS1, M_HOST_FLAGS2, M_HOST_FLAGS3, M_HOST_FLAGS4, - M_HOST_FLAGS5 - }; - struct brcms_hw_band *band; - - if ((val & ~mask) || idx >= MHFMAX) - return; /* error condition */ - - switch (bands) { - /* Current band only or all bands, - * then set the band to current band - */ - case BRCM_BAND_AUTO: - case BRCM_BAND_ALL: - band = wlc_hw->band; - break; - case BRCM_BAND_5G: - band = wlc_hw->bandstate[BAND_5G_INDEX]; - break; - case BRCM_BAND_2G: - band = wlc_hw->bandstate[BAND_2G_INDEX]; - break; - default: - band = NULL; /* error condition */ - } - - if (band) { - save = band->mhfs[idx]; - band->mhfs[idx] = (band->mhfs[idx] & ~mask) | val; - - /* optimization: only write through if changed, and - * changed band is the current band - */ - if (wlc_hw->clk && (band->mhfs[idx] != save) - && (band == wlc_hw->band)) - brcms_b_write_shm(wlc_hw, addr[idx], - (u16) band->mhfs[idx]); - } - - if (bands == BRCM_BAND_ALL) { - wlc_hw->bandstate[0]->mhfs[idx] = - (wlc_hw->bandstate[0]->mhfs[idx] & ~mask) | val; - wlc_hw->bandstate[1]->mhfs[idx] = - (wlc_hw->bandstate[1]->mhfs[idx] & ~mask) | val; - } -} - -u16 brcms_b_mhf_get(struct brcms_hardware *wlc_hw, u8 idx, int bands) -{ - struct brcms_hw_band *band; - - if (idx >= MHFMAX) - return 0; /* error condition */ - switch (bands) { - case BRCM_BAND_AUTO: - band = wlc_hw->band; - break; - case BRCM_BAND_5G: - band = wlc_hw->bandstate[BAND_5G_INDEX]; - break; - case BRCM_BAND_2G: - band = wlc_hw->bandstate[BAND_2G_INDEX]; - break; - default: - band = NULL; /* error condition */ - } - - if (!band) - return 0; - - return band->mhfs[idx]; -} - -static void brcms_c_write_mhf(struct brcms_hardware *wlc_hw, u16 *mhfs) -{ - u8 idx; - u16 addr[] = { - M_HOST_FLAGS1, M_HOST_FLAGS2, M_HOST_FLAGS3, M_HOST_FLAGS4, - M_HOST_FLAGS5 - }; - - for (idx = 0; idx < MHFMAX; idx++) { - brcms_b_write_shm(wlc_hw, addr[idx], mhfs[idx]); - } -} - -/* set the maccontrol register to desired reset state and - * initialize the sw cache of the register - */ -static void brcms_c_mctrl_reset(struct brcms_hardware *wlc_hw) -{ - /* IHR accesses are always enabled, PSM disabled, HPS off and WAKE on */ - wlc_hw->maccontrol = 0; - wlc_hw->suspended_fifos = 0; - wlc_hw->wake_override = 0; - wlc_hw->mute_override = 0; - brcms_b_mctrl(wlc_hw, ~0, MCTL_IHR_EN | MCTL_WAKE); -} - -/* set or clear maccontrol bits */ -void brcms_b_mctrl(struct brcms_hardware *wlc_hw, u32 mask, u32 val) -{ - u32 maccontrol; - u32 new_maccontrol; - - if (val & ~mask) - return; /* error condition */ - maccontrol = wlc_hw->maccontrol; - new_maccontrol = (maccontrol & ~mask) | val; - - /* if the new maccontrol value is the same as the old, nothing to do */ - if (new_maccontrol == maccontrol) - return; - - /* something changed, cache the new value */ - wlc_hw->maccontrol = new_maccontrol; - - /* write the new values with overrides applied */ - brcms_c_mctrl_write(wlc_hw); -} - -/* write the software state of maccontrol and overrides to the maccontrol register */ -static void brcms_c_mctrl_write(struct brcms_hardware *wlc_hw) -{ - u32 maccontrol = wlc_hw->maccontrol; - - /* OR in the wake bit if overridden */ - if (wlc_hw->wake_override) - maccontrol |= MCTL_WAKE; - - /* set AP and INFRA bits for mute if needed */ - if (wlc_hw->mute_override) { - maccontrol &= ~(MCTL_AP); - maccontrol |= MCTL_INFRA; - } - - W_REG(&wlc_hw->regs->maccontrol, maccontrol); -} - -void brcms_c_ucode_wake_override_set(struct brcms_hardware *wlc_hw, - u32 override_bit) -{ - if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE)) { - mboolset(wlc_hw->wake_override, override_bit); - return; - } - - mboolset(wlc_hw->wake_override, override_bit); - - brcms_c_mctrl_write(wlc_hw); - brcms_b_wait_for_wake(wlc_hw); - - return; -} - -void brcms_c_ucode_wake_override_clear(struct brcms_hardware *wlc_hw, - u32 override_bit) -{ - mboolclr(wlc_hw->wake_override, override_bit); - - if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE)) - return; - - brcms_c_mctrl_write(wlc_hw); - - return; -} - -/* When driver needs ucode to stop beaconing, it has to make sure that - * MCTL_AP is clear and MCTL_INFRA is set - * Mode MCTL_AP MCTL_INFRA - * AP 1 1 - * STA 0 1 <--- This will ensure no beacons - * IBSS 0 0 - */ -static void brcms_c_ucode_mute_override_set(struct brcms_hardware *wlc_hw) -{ - wlc_hw->mute_override = 1; - - /* if maccontrol already has AP == 0 and INFRA == 1 without this - * override, then there is no change to write - */ - if ((wlc_hw->maccontrol & (MCTL_AP | MCTL_INFRA)) == MCTL_INFRA) - return; - - brcms_c_mctrl_write(wlc_hw); - - return; -} - -/* Clear the override on AP and INFRA bits */ -static void brcms_c_ucode_mute_override_clear(struct brcms_hardware *wlc_hw) -{ - if (wlc_hw->mute_override == 0) - return; - - wlc_hw->mute_override = 0; - - /* if maccontrol already has AP == 0 and INFRA == 1 without this - * override, then there is no change to write - */ - if ((wlc_hw->maccontrol & (MCTL_AP | MCTL_INFRA)) == MCTL_INFRA) - return; - - brcms_c_mctrl_write(wlc_hw); -} - -/* - * Write a MAC address to the given match reg offset in the RXE match engine. - */ -void -brcms_b_set_addrmatch(struct brcms_hardware *wlc_hw, int match_reg_offset, - const u8 *addr) -{ - d11regs_t *regs; - u16 mac_l; - u16 mac_m; - u16 mac_h; - - BCMMSG(wlc_hw->wlc->wiphy, "wl%d: brcms_b_set_addrmatch\n", - wlc_hw->unit); - - regs = wlc_hw->regs; - mac_l = addr[0] | (addr[1] << 8); - mac_m = addr[2] | (addr[3] << 8); - mac_h = addr[4] | (addr[5] << 8); - - /* enter the MAC addr into the RXE match registers */ - W_REG(®s->rcm_ctl, RCM_INC_DATA | match_reg_offset); - W_REG(®s->rcm_mat_data, mac_l); - W_REG(®s->rcm_mat_data, mac_m); - W_REG(®s->rcm_mat_data, mac_h); - -} - -void -brcms_b_write_template_ram(struct brcms_hardware *wlc_hw, int offset, int len, - void *buf) -{ - d11regs_t *regs; - u32 word; - bool be_bit; - BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); - - regs = wlc_hw->regs; - W_REG(®s->tplatewrptr, offset); - - /* if MCTL_BIGEND bit set in mac control register, - * the chip swaps data in fifo, as well as data in - * template ram - */ - be_bit = (R_REG(®s->maccontrol) & MCTL_BIGEND) != 0; - - while (len > 0) { - memcpy(&word, buf, sizeof(u32)); - - if (be_bit) - word = cpu_to_be32(word); - else - word = cpu_to_le32(word); - - W_REG(®s->tplatewrdata, word); - - buf = (u8 *) buf + sizeof(u32); - len -= sizeof(u32); - } -} - -void brcms_b_set_cwmin(struct brcms_hardware *wlc_hw, u16 newmin) -{ - wlc_hw->band->CWmin = newmin; - - W_REG(&wlc_hw->regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_CWMIN); - (void)R_REG(&wlc_hw->regs->objaddr); - W_REG(&wlc_hw->regs->objdata, newmin); -} - -void brcms_b_set_cwmax(struct brcms_hardware *wlc_hw, u16 newmax) -{ - wlc_hw->band->CWmax = newmax; - - W_REG(&wlc_hw->regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_CWMAX); - (void)R_REG(&wlc_hw->regs->objaddr); - W_REG(&wlc_hw->regs->objdata, newmax); -} - -void brcms_b_bw_set(struct brcms_hardware *wlc_hw, u16 bw) -{ - bool fastclk; - - /* request FAST clock if not on */ - fastclk = wlc_hw->forcefastclk; - if (!fastclk) - brcms_b_clkctl_clk(wlc_hw, CLK_FAST); - - wlc_phy_bw_state_set(wlc_hw->band->pi, bw); - - brcms_b_phy_reset(wlc_hw); - wlc_phy_init(wlc_hw->band->pi, wlc_phy_chanspec_get(wlc_hw->band->pi)); - - /* restore the clk */ - if (!fastclk) - brcms_b_clkctl_clk(wlc_hw, CLK_DYNAMIC); -} - -static void -brcms_c_write_hw_bcntemplate0(struct brcms_hardware *wlc_hw, void *bcn, - int len) -{ - d11regs_t *regs = wlc_hw->regs; - - brcms_b_write_template_ram(wlc_hw, T_BCN0_TPL_BASE, (len + 3) & ~3, - bcn); - /* write beacon length to SCR */ - brcms_b_write_shm(wlc_hw, M_BCN0_FRM_BYTESZ, (u16) len); - /* mark beacon0 valid */ - OR_REG(®s->maccommand, MCMD_BCN0VLD); -} - -static void -brcms_c_write_hw_bcntemplate1(struct brcms_hardware *wlc_hw, void *bcn, - int len) -{ - d11regs_t *regs = wlc_hw->regs; - - brcms_b_write_template_ram(wlc_hw, T_BCN1_TPL_BASE, (len + 3) & ~3, - bcn); - /* write beacon length to SCR */ - brcms_b_write_shm(wlc_hw, M_BCN1_FRM_BYTESZ, (u16) len); - /* mark beacon1 valid */ - OR_REG(®s->maccommand, MCMD_BCN1VLD); -} - -/* mac is assumed to be suspended at this point */ -void -brcms_b_write_hw_bcntemplates(struct brcms_hardware *wlc_hw, void *bcn, - int len, bool both) -{ - d11regs_t *regs = wlc_hw->regs; - - if (both) { - brcms_c_write_hw_bcntemplate0(wlc_hw, bcn, len); - brcms_c_write_hw_bcntemplate1(wlc_hw, bcn, len); - } else { - /* bcn 0 */ - if (!(R_REG(®s->maccommand) & MCMD_BCN0VLD)) - brcms_c_write_hw_bcntemplate0(wlc_hw, bcn, len); - /* bcn 1 */ - else if (! - (R_REG(®s->maccommand) & MCMD_BCN1VLD)) - brcms_c_write_hw_bcntemplate1(wlc_hw, bcn, len); - } -} - -static void brcms_b_upd_synthpu(struct brcms_hardware *wlc_hw) -{ - u16 v; - struct brcms_c_info *wlc = wlc_hw->wlc; - /* update SYNTHPU_DLY */ - - if (BRCMS_ISLCNPHY(wlc->band)) { - v = SYNTHPU_DLY_LPPHY_US; - } else if (BRCMS_ISNPHY(wlc->band) && (NREV_GE(wlc->band->phyrev, 3))) { - v = SYNTHPU_DLY_NPHY_US; - } else { - v = SYNTHPU_DLY_BPHY_US; - } - - brcms_b_write_shm(wlc_hw, M_SYNTHPU_DLY, v); -} - -/* band-specific init */ -static void -brcms_b_bsinit(struct brcms_c_info *wlc, chanspec_t chanspec) -{ - struct brcms_hardware *wlc_hw = wlc->hw; - - BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit, - wlc_hw->band->bandunit); - - brcms_c_ucode_bsinit(wlc_hw); - - wlc_phy_init(wlc_hw->band->pi, chanspec); - - brcms_c_ucode_txant_set(wlc_hw); - - /* cwmin is band-specific, update hardware with value for current band */ - brcms_b_set_cwmin(wlc_hw, wlc_hw->band->CWmin); - brcms_b_set_cwmax(wlc_hw, wlc_hw->band->CWmax); - - brcms_b_update_slot_timing(wlc_hw, - BAND_5G(wlc_hw->band-> - bandtype) ? true : wlc_hw-> - shortslot); - - /* write phytype and phyvers */ - brcms_b_write_shm(wlc_hw, M_PHYTYPE, (u16) wlc_hw->band->phytype); - brcms_b_write_shm(wlc_hw, M_PHYVER, (u16) wlc_hw->band->phyrev); - - /* initialize the txphyctl1 rate table since shmem is shared between bands */ - brcms_upd_ofdm_pctl1_table(wlc_hw); - - brcms_b_upd_synthpu(wlc_hw); -} - -static void brcms_b_core_phy_clk(struct brcms_hardware *wlc_hw, bool clk) -{ - BCMMSG(wlc_hw->wlc->wiphy, "wl%d: clk %d\n", wlc_hw->unit, clk); - - wlc_hw->phyclk = clk; - - if (OFF == clk) { /* clear gmode bit, put phy into reset */ - - ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC | SICF_GMODE), - (SICF_PRST | SICF_FGC)); - udelay(1); - ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC), SICF_PRST); - udelay(1); - - } else { /* take phy out of reset */ - - ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC), SICF_FGC); - udelay(1); - ai_core_cflags(wlc_hw->sih, (SICF_FGC), 0); - udelay(1); - - } -} - -/* Perform a soft reset of the PHY PLL */ -void brcms_b_core_phypll_reset(struct brcms_hardware *wlc_hw) -{ - BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); - - ai_corereg(wlc_hw->sih, SI_CC_IDX, - offsetof(chipcregs_t, chipcontrol_addr), ~0, 0); - udelay(1); - ai_corereg(wlc_hw->sih, SI_CC_IDX, - offsetof(chipcregs_t, chipcontrol_data), 0x4, 0); - udelay(1); - ai_corereg(wlc_hw->sih, SI_CC_IDX, - offsetof(chipcregs_t, chipcontrol_data), 0x4, 4); - udelay(1); - ai_corereg(wlc_hw->sih, SI_CC_IDX, - offsetof(chipcregs_t, chipcontrol_data), 0x4, 0); - udelay(1); -} - -/* light way to turn on phy clock without reset for NPHY only - * refer to brcms_b_core_phy_clk for full version - */ -void brcms_b_phyclk_fgc(struct brcms_hardware *wlc_hw, bool clk) -{ - /* support(necessary for NPHY and HYPHY) only */ - if (!BRCMS_ISNPHY(wlc_hw->band)) - return; - - if (ON == clk) - ai_core_cflags(wlc_hw->sih, SICF_FGC, SICF_FGC); - else - ai_core_cflags(wlc_hw->sih, SICF_FGC, 0); - -} - -void brcms_b_macphyclk_set(struct brcms_hardware *wlc_hw, bool clk) -{ - if (ON == clk) - ai_core_cflags(wlc_hw->sih, SICF_MPCLKE, SICF_MPCLKE); - else - ai_core_cflags(wlc_hw->sih, SICF_MPCLKE, 0); -} - -void brcms_b_phy_reset(struct brcms_hardware *wlc_hw) -{ - struct brcms_phy_pub *pih = wlc_hw->band->pi; - u32 phy_bw_clkbits; - bool phy_in_reset = false; - - BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); - - if (pih == NULL) - return; - - phy_bw_clkbits = wlc_phy_clk_bwbits(wlc_hw->band->pi); - - /* Specific reset sequence required for NPHY rev 3 and 4 */ - if (BRCMS_ISNPHY(wlc_hw->band) && NREV_GE(wlc_hw->band->phyrev, 3) && - NREV_LE(wlc_hw->band->phyrev, 4)) { - /* Set the PHY bandwidth */ - ai_core_cflags(wlc_hw->sih, SICF_BWMASK, phy_bw_clkbits); - - udelay(1); - - /* Perform a soft reset of the PHY PLL */ - brcms_b_core_phypll_reset(wlc_hw); - - /* reset the PHY */ - ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_PCLKE), - (SICF_PRST | SICF_PCLKE)); - phy_in_reset = true; - } else { - - ai_core_cflags(wlc_hw->sih, - (SICF_PRST | SICF_PCLKE | SICF_BWMASK), - (SICF_PRST | SICF_PCLKE | phy_bw_clkbits)); - } - - udelay(2); - brcms_b_core_phy_clk(wlc_hw, ON); - - if (pih) - wlc_phy_anacore(pih, ON); -} - -/* switch to and initialize new band */ -static void -brcms_b_setband(struct brcms_hardware *wlc_hw, uint bandunit, - chanspec_t chanspec) { - struct brcms_c_info *wlc = wlc_hw->wlc; - u32 macintmask; - - /* Enable the d11 core before accessing it */ - if (!ai_iscoreup(wlc_hw->sih)) { - ai_core_reset(wlc_hw->sih, 0, 0); - brcms_c_mctrl_reset(wlc_hw); - } - - macintmask = brcms_c_setband_inact(wlc, bandunit); - - if (!wlc_hw->up) - return; - - brcms_b_core_phy_clk(wlc_hw, ON); - - /* band-specific initializations */ - brcms_b_bsinit(wlc, chanspec); - - /* - * If there are any pending software interrupt bits, - * then replace these with a harmless nonzero value - * so brcms_c_dpc() will re-enable interrupts when done. - */ - if (wlc->macintstatus) - wlc->macintstatus = MI_DMAINT; - - /* restore macintmask */ - brcms_intrsrestore(wlc->wl, macintmask); - - /* ucode should still be suspended.. */ - WARN_ON((R_REG(&wlc_hw->regs->maccontrol) & MCTL_EN_MAC) != 0); -} - -/* low-level band switch utility routine */ -void brcms_c_setxband(struct brcms_hardware *wlc_hw, - uint bandunit) -{ - BCMMSG(wlc_hw->wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit, - bandunit); - - wlc_hw->band = wlc_hw->bandstate[bandunit]; - - /* BMAC_NOTE: until we eliminate need for wlc->band refs in low level code */ - wlc_hw->wlc->band = wlc_hw->wlc->bandstate[bandunit]; - - /* set gmode core flag */ - if (wlc_hw->sbclk && !wlc_hw->noreset) { - ai_core_cflags(wlc_hw->sih, SICF_GMODE, - ((bandunit == 0) ? SICF_GMODE : 0)); - } -} - -static bool brcms_c_isgoodchip(struct brcms_hardware *wlc_hw) -{ - - /* reject unsupported corerev */ - if (!VALID_COREREV(wlc_hw->corerev)) { - wiphy_err(wlc_hw->wlc->wiphy, "unsupported core rev %d\n", - wlc_hw->corerev); - return false; - } - - return true; -} - -/* Validate some board info parameters */ -static bool brcms_c_validboardtype(struct brcms_hardware *wlc_hw) -{ - uint boardrev = wlc_hw->boardrev; - - /* 4 bits each for board type, major, minor, and tiny version */ - uint brt = (boardrev & 0xf000) >> 12; - uint b0 = (boardrev & 0xf00) >> 8; - uint b1 = (boardrev & 0xf0) >> 4; - uint b2 = boardrev & 0xf; - - /* voards from other vendors are always considered valid */ - if (wlc_hw->sih->boardvendor != PCI_VENDOR_ID_BROADCOM) - return true; - - /* do some boardrev sanity checks when boardvendor is Broadcom */ - if (boardrev == 0) - return false; - - if (boardrev <= 0xff) - return true; - - if ((brt > 2) || (brt == 0) || (b0 > 9) || (b0 == 0) || (b1 > 9) - || (b2 > 9)) - return false; - - return true; -} - -static char *brcms_c_get_macaddr(struct brcms_hardware *wlc_hw) -{ - const char *varname = "macaddr"; - char *macaddr; - - /* If macaddr exists, use it (Sromrev4, CIS, ...). */ - macaddr = getvar(wlc_hw->vars, varname); - if (macaddr != NULL) - return macaddr; - - if (NBANDS_HW(wlc_hw) > 1) - varname = "et1macaddr"; - else - varname = "il0macaddr"; - - macaddr = getvar(wlc_hw->vars, varname); - if (macaddr == NULL) { - wiphy_err(wlc_hw->wlc->wiphy, "wl%d: wlc_get_macaddr: macaddr " - "getvar(%s) not found\n", wlc_hw->unit, varname); - } - - return macaddr; -} - -/* - * Return true if radio is disabled, otherwise false. - * hw radio disable signal is an external pin, users activate it asynchronously - * this function could be called when driver is down and w/o clock - * it operates on different registers depending on corerev and boardflag. - */ -bool brcms_b_radio_read_hwdisabled(struct brcms_hardware *wlc_hw) -{ - bool v, clk, xtal; - u32 resetbits = 0, flags = 0; - - xtal = wlc_hw->sbclk; - if (!xtal) - brcms_b_xtal(wlc_hw, ON); - - /* may need to take core out of reset first */ - clk = wlc_hw->clk; - if (!clk) { - /* - * mac no longer enables phyclk automatically when driver - * accesses phyreg throughput mac. This can be skipped since - * only mac reg is accessed below - */ - flags |= SICF_PCLKE; - - /* AI chip doesn't restore bar0win2 on hibernation/resume, need sw fixup */ - if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) || - (wlc_hw->sih->chip == BCM43225_CHIP_ID)) - wlc_hw->regs = - (d11regs_t *) ai_setcore(wlc_hw->sih, D11_CORE_ID, - 0); - ai_core_reset(wlc_hw->sih, flags, resetbits); - brcms_c_mctrl_reset(wlc_hw); - } - - v = ((R_REG(&wlc_hw->regs->phydebug) & PDBG_RFD) != 0); - - /* put core back into reset */ - if (!clk) - ai_core_disable(wlc_hw->sih, 0); - - if (!xtal) - brcms_b_xtal(wlc_hw, OFF); - - return v; -} - -/* Initialize just the hardware when coming out of POR or S3/S5 system states */ -void brcms_b_hw_up(struct brcms_hardware *wlc_hw) -{ - if (wlc_hw->wlc->pub->hw_up) - return; - - BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); - - /* - * Enable pll and xtal, initialize the power control registers, - * and force fastclock for the remainder of brcms_c_up(). - */ - brcms_b_xtal(wlc_hw, ON); - ai_clkctl_init(wlc_hw->sih); - brcms_b_clkctl_clk(wlc_hw, CLK_FAST); - - if (wlc_hw->sih->bustype == PCI_BUS) { - ai_pci_fixcfg(wlc_hw->sih); - - /* AI chip doesn't restore bar0win2 on hibernation/resume, need sw fixup */ - if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) || - (wlc_hw->sih->chip == BCM43225_CHIP_ID)) - wlc_hw->regs = - (d11regs_t *) ai_setcore(wlc_hw->sih, D11_CORE_ID, - 0); - } - - /* Inform phy that a POR reset has occurred so it does a complete phy init */ - wlc_phy_por_inform(wlc_hw->band->pi); - - wlc_hw->ucode_loaded = false; - wlc_hw->wlc->pub->hw_up = true; - - if ((wlc_hw->boardflags & BFL_FEM) - && (wlc_hw->sih->chip == BCM4313_CHIP_ID)) { - if (! - (wlc_hw->boardrev >= 0x1250 - && (wlc_hw->boardflags & BFL_FEM_BT))) - ai_epa_4313war(wlc_hw->sih); - } -} - -static bool wlc_dma_rxreset(struct brcms_hardware *wlc_hw, uint fifo) -{ - struct dma_pub *di = wlc_hw->di[fifo]; - return dma_rxreset(di); -} - -/* d11 core reset - * ensure fask clock during reset - * reset dma - * reset d11(out of reset) - * reset phy(out of reset) - * clear software macintstatus for fresh new start - * one testing hack wlc_hw->noreset will bypass the d11/phy reset - */ -void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags) -{ - d11regs_t *regs; - uint i; - bool fastclk; - u32 resetbits = 0; - - if (flags == BRCMS_USE_COREFLAGS) - flags = (wlc_hw->band->pi ? wlc_hw->band->core_flags : 0); - - BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); - - regs = wlc_hw->regs; - - /* request FAST clock if not on */ - fastclk = wlc_hw->forcefastclk; - if (!fastclk) - brcms_b_clkctl_clk(wlc_hw, CLK_FAST); - - /* reset the dma engines except first time thru */ - if (ai_iscoreup(wlc_hw->sih)) { - for (i = 0; i < NFIFO; i++) - if ((wlc_hw->di[i]) && (!dma_txreset(wlc_hw->di[i]))) { - wiphy_err(wlc_hw->wlc->wiphy, "wl%d: %s: " - "dma_txreset[%d]: cannot stop dma\n", - wlc_hw->unit, __func__, i); - } - - if ((wlc_hw->di[RX_FIFO]) - && (!wlc_dma_rxreset(wlc_hw, RX_FIFO))) { - wiphy_err(wlc_hw->wlc->wiphy, "wl%d: %s: dma_rxreset" - "[%d]: cannot stop dma\n", - wlc_hw->unit, __func__, RX_FIFO); - } - } - /* if noreset, just stop the psm and return */ - if (wlc_hw->noreset) { - wlc_hw->wlc->macintstatus = 0; /* skip wl_dpc after down */ - brcms_b_mctrl(wlc_hw, MCTL_PSM_RUN | MCTL_EN_MAC, 0); - return; - } - - /* - * mac no longer enables phyclk automatically when driver accesses - * phyreg throughput mac, AND phy_reset is skipped at early stage when - * band->pi is invalid. need to enable PHY CLK - */ - flags |= SICF_PCLKE; - - /* reset the core - * In chips with PMU, the fastclk request goes through d11 core reg 0x1e0, which - * is cleared by the core_reset. have to re-request it. - * This adds some delay and we can optimize it by also requesting fastclk through - * chipcommon during this period if necessary. But that has to work coordinate - * with other driver like mips/arm since they may touch chipcommon as well. - */ - wlc_hw->clk = false; - ai_core_reset(wlc_hw->sih, flags, resetbits); - wlc_hw->clk = true; - if (wlc_hw->band && wlc_hw->band->pi) - wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, true); - - brcms_c_mctrl_reset(wlc_hw); - - if (PMUCTL_ENAB(wlc_hw->sih)) - brcms_b_clkctl_clk(wlc_hw, CLK_FAST); - - brcms_b_phy_reset(wlc_hw); - - /* turn on PHY_PLL */ - brcms_b_core_phypll_ctl(wlc_hw, true); - - /* clear sw intstatus */ - wlc_hw->wlc->macintstatus = 0; - - /* restore the clk setting */ - if (!fastclk) - brcms_b_clkctl_clk(wlc_hw, CLK_DYNAMIC); -} - -/* txfifo sizes needs to be modified(increased) since the newer cores - * have more memory. - */ -static void brcms_b_corerev_fifofixup(struct brcms_hardware *wlc_hw) -{ - d11regs_t *regs = wlc_hw->regs; - u16 fifo_nu; - u16 txfifo_startblk = TXFIFO_START_BLK, txfifo_endblk; - u16 txfifo_def, txfifo_def1; - u16 txfifo_cmd; - - /* tx fifos start at TXFIFO_START_BLK from the Base address */ - txfifo_startblk = TXFIFO_START_BLK; - - /* sequence of operations: reset fifo, set fifo size, reset fifo */ - for (fifo_nu = 0; fifo_nu < NFIFO; fifo_nu++) { - - txfifo_endblk = txfifo_startblk + wlc_hw->xmtfifo_sz[fifo_nu]; - txfifo_def = (txfifo_startblk & 0xff) | - (((txfifo_endblk - 1) & 0xff) << TXFIFO_FIFOTOP_SHIFT); - txfifo_def1 = ((txfifo_startblk >> 8) & 0x1) | - ((((txfifo_endblk - - 1) >> 8) & 0x1) << TXFIFO_FIFOTOP_SHIFT); - txfifo_cmd = - TXFIFOCMD_RESET_MASK | (fifo_nu << TXFIFOCMD_FIFOSEL_SHIFT); - - W_REG(®s->xmtfifocmd, txfifo_cmd); - W_REG(®s->xmtfifodef, txfifo_def); - W_REG(®s->xmtfifodef1, txfifo_def1); - - W_REG(®s->xmtfifocmd, txfifo_cmd); - - txfifo_startblk += wlc_hw->xmtfifo_sz[fifo_nu]; - } - /* - * need to propagate to shm location to be in sync since ucode/hw won't - * do this - */ - brcms_b_write_shm(wlc_hw, M_FIFOSIZE0, - wlc_hw->xmtfifo_sz[TX_AC_BE_FIFO]); - brcms_b_write_shm(wlc_hw, M_FIFOSIZE1, - wlc_hw->xmtfifo_sz[TX_AC_VI_FIFO]); - brcms_b_write_shm(wlc_hw, M_FIFOSIZE2, - ((wlc_hw->xmtfifo_sz[TX_AC_VO_FIFO] << 8) | wlc_hw-> - xmtfifo_sz[TX_AC_BK_FIFO])); - brcms_b_write_shm(wlc_hw, M_FIFOSIZE3, - ((wlc_hw->xmtfifo_sz[TX_ATIM_FIFO] << 8) | wlc_hw-> - xmtfifo_sz[TX_BCMC_FIFO])); -} - -/* d11 core init - * reset PSM - * download ucode/PCM - * let ucode run to suspended - * download ucode inits - * config other core registers - * init dma - */ -static void brcms_b_coreinit(struct brcms_c_info *wlc) -{ - struct brcms_hardware *wlc_hw = wlc->hw; - d11regs_t *regs; - u32 sflags; - uint bcnint_us; - uint i = 0; - bool fifosz_fixup = false; - int err = 0; - u16 buf[NFIFO]; - struct wiphy *wiphy = wlc->wiphy; - - regs = wlc_hw->regs; - - BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit); - - /* reset PSM */ - brcms_b_mctrl(wlc_hw, ~0, (MCTL_IHR_EN | MCTL_PSM_JMP_0 | MCTL_WAKE)); - - brcms_ucode_download(wlc_hw); - /* - * FIFOSZ fixup. driver wants to controls the fifo allocation. - */ - fifosz_fixup = true; - - /* let the PSM run to the suspended state, set mode to BSS STA */ - W_REG(®s->macintstatus, -1); - brcms_b_mctrl(wlc_hw, ~0, - (MCTL_IHR_EN | MCTL_INFRA | MCTL_PSM_RUN | MCTL_WAKE)); - - /* wait for ucode to self-suspend after auto-init */ - SPINWAIT(((R_REG(®s->macintstatus) & MI_MACSSPNDD) == 0), - 1000 * 1000); - if ((R_REG(®s->macintstatus) & MI_MACSSPNDD) == 0) - wiphy_err(wiphy, "wl%d: wlc_coreinit: ucode did not self-" - "suspend!\n", wlc_hw->unit); - - brcms_c_gpio_init(wlc); - - sflags = ai_core_sflags(wlc_hw->sih, 0, 0); - - if (D11REV_IS(wlc_hw->corerev, 23)) { - if (BRCMS_ISNPHY(wlc_hw->band)) - brcms_c_write_inits(wlc_hw, d11n0initvals16); - else - wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev" - " %d\n", __func__, wlc_hw->unit, - wlc_hw->corerev); - } else if (D11REV_IS(wlc_hw->corerev, 24)) { - if (BRCMS_ISLCNPHY(wlc_hw->band)) { - brcms_c_write_inits(wlc_hw, d11lcn0initvals24); - } else { - wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev" - " %d\n", __func__, wlc_hw->unit, - wlc_hw->corerev); - } - } else { - wiphy_err(wiphy, "%s: wl%d: unsupported corerev %d\n", - __func__, wlc_hw->unit, wlc_hw->corerev); - } - - /* For old ucode, txfifo sizes needs to be modified(increased) */ - if (fifosz_fixup == true) { - brcms_b_corerev_fifofixup(wlc_hw); - } - - /* check txfifo allocations match between ucode and driver */ - buf[TX_AC_BE_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE0); - if (buf[TX_AC_BE_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_BE_FIFO]) { - i = TX_AC_BE_FIFO; - err = -1; - } - buf[TX_AC_VI_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE1); - if (buf[TX_AC_VI_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_VI_FIFO]) { - i = TX_AC_VI_FIFO; - err = -1; - } - buf[TX_AC_BK_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE2); - buf[TX_AC_VO_FIFO] = (buf[TX_AC_BK_FIFO] >> 8) & 0xff; - buf[TX_AC_BK_FIFO] &= 0xff; - if (buf[TX_AC_BK_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_BK_FIFO]) { - i = TX_AC_BK_FIFO; - err = -1; - } - if (buf[TX_AC_VO_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_VO_FIFO]) { - i = TX_AC_VO_FIFO; - err = -1; - } - buf[TX_BCMC_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE3); - buf[TX_ATIM_FIFO] = (buf[TX_BCMC_FIFO] >> 8) & 0xff; - buf[TX_BCMC_FIFO] &= 0xff; - if (buf[TX_BCMC_FIFO] != wlc_hw->xmtfifo_sz[TX_BCMC_FIFO]) { - i = TX_BCMC_FIFO; - err = -1; - } - if (buf[TX_ATIM_FIFO] != wlc_hw->xmtfifo_sz[TX_ATIM_FIFO]) { - i = TX_ATIM_FIFO; - err = -1; - } - if (err != 0) { - wiphy_err(wiphy, "wlc_coreinit: txfifo mismatch: ucode size %d" - " driver size %d index %d\n", buf[i], - wlc_hw->xmtfifo_sz[i], i); - } - - /* make sure we can still talk to the mac */ - WARN_ON(R_REG(®s->maccontrol) == 0xffffffff); - - /* band-specific inits done by wlc_bsinit() */ - - /* Set up frame burst size and antenna swap threshold init values */ - brcms_b_write_shm(wlc_hw, M_MBURST_SIZE, MAXTXFRAMEBURST); - brcms_b_write_shm(wlc_hw, M_MAX_ANTCNT, ANTCNT); - - /* enable one rx interrupt per received frame */ - W_REG(®s->intrcvlazy[0], (1 << IRL_FC_SHIFT)); - - /* set the station mode (BSS STA) */ - brcms_b_mctrl(wlc_hw, - (MCTL_INFRA | MCTL_DISCARD_PMQ | MCTL_AP), - (MCTL_INFRA | MCTL_DISCARD_PMQ)); - - /* set up Beacon interval */ - bcnint_us = 0x8000 << 10; - W_REG(®s->tsf_cfprep, (bcnint_us << CFPREP_CBI_SHIFT)); - W_REG(®s->tsf_cfpstart, bcnint_us); - W_REG(®s->macintstatus, MI_GP1); - - /* write interrupt mask */ - W_REG(®s->intctrlregs[RX_FIFO].intmask, DEF_RXINTMASK); - - /* allow the MAC to control the PHY clock (dynamic on/off) */ - brcms_b_macphyclk_set(wlc_hw, ON); - - /* program dynamic clock control fast powerup delay register */ - wlc->fastpwrup_dly = ai_clkctl_fast_pwrup_delay(wlc_hw->sih); - W_REG(®s->scc_fastpwrup_dly, wlc->fastpwrup_dly); - - /* tell the ucode the corerev */ - brcms_b_write_shm(wlc_hw, M_MACHW_VER, (u16) wlc_hw->corerev); - - /* tell the ucode MAC capabilities */ - brcms_b_write_shm(wlc_hw, M_MACHW_CAP_L, - (u16) (wlc_hw->machwcap & 0xffff)); - brcms_b_write_shm(wlc_hw, M_MACHW_CAP_H, - (u16) ((wlc_hw-> - machwcap >> 16) & 0xffff)); - - /* write retry limits to SCR, this done after PSM init */ - W_REG(®s->objaddr, OBJADDR_SCR_SEL | S_DOT11_SRC_LMT); - (void)R_REG(®s->objaddr); - W_REG(®s->objdata, wlc_hw->SRL); - W_REG(®s->objaddr, OBJADDR_SCR_SEL | S_DOT11_LRC_LMT); - (void)R_REG(®s->objaddr); - W_REG(®s->objdata, wlc_hw->LRL); - - /* write rate fallback retry limits */ - brcms_b_write_shm(wlc_hw, M_SFRMTXCNTFBRTHSD, wlc_hw->SFBL); - brcms_b_write_shm(wlc_hw, M_LFRMTXCNTFBRTHSD, wlc_hw->LFBL); - - AND_REG(®s->ifs_ctl, 0x0FFF); - W_REG(®s->ifs_aifsn, EDCF_AIFSN_MIN); - - /* dma initializations */ - wlc->txpend16165war = 0; - - /* init the tx dma engines */ - for (i = 0; i < NFIFO; i++) { - if (wlc_hw->di[i]) - dma_txinit(wlc_hw->di[i]); - } - - /* init the rx dma engine(s) and post receive buffers */ - dma_rxinit(wlc_hw->di[RX_FIFO]); - dma_rxfill(wlc_hw->di[RX_FIFO]); -} - -/* This function is used for changing the tsf frac register - * If spur avoidance mode is off, the mac freq will be 80/120/160Mhz - * If spur avoidance mode is on1, the mac freq will be 82/123/164Mhz - * If spur avoidance mode is on2, the mac freq will be 84/126/168Mhz - * HTPHY Formula is 2^26/freq(MHz) e.g. - * For spuron2 - 126MHz -> 2^26/126 = 532610.0 - * - 532610 = 0x82082 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x2082 - * For spuron: 123MHz -> 2^26/123 = 545600.5 - * - 545601 = 0x85341 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x5341 - * For spur off: 120MHz -> 2^26/120 = 559240.5 - * - 559241 = 0x88889 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x8889 - */ - -void brcms_b_switch_macfreq(struct brcms_hardware *wlc_hw, u8 spurmode) -{ - d11regs_t *regs; - regs = wlc_hw->regs; - - if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) || - (wlc_hw->sih->chip == BCM43225_CHIP_ID)) { - if (spurmode == WL_SPURAVOID_ON2) { /* 126Mhz */ - W_REG(®s->tsf_clk_frac_l, 0x2082); - W_REG(®s->tsf_clk_frac_h, 0x8); - } else if (spurmode == WL_SPURAVOID_ON1) { /* 123Mhz */ - W_REG(®s->tsf_clk_frac_l, 0x5341); - W_REG(®s->tsf_clk_frac_h, 0x8); - } else { /* 120Mhz */ - W_REG(®s->tsf_clk_frac_l, 0x8889); - W_REG(®s->tsf_clk_frac_h, 0x8); - } - } else if (BRCMS_ISLCNPHY(wlc_hw->band)) { - if (spurmode == WL_SPURAVOID_ON1) { /* 82Mhz */ - W_REG(®s->tsf_clk_frac_l, 0x7CE0); - W_REG(®s->tsf_clk_frac_h, 0xC); - } else { /* 80Mhz */ - W_REG(®s->tsf_clk_frac_l, 0xCCCD); - W_REG(®s->tsf_clk_frac_h, 0xC); - } - } -} - -/* Initialize GPIOs that are controlled by D11 core */ -static void brcms_c_gpio_init(struct brcms_c_info *wlc) -{ - struct brcms_hardware *wlc_hw = wlc->hw; - d11regs_t *regs; - u32 gc, gm; - - regs = wlc_hw->regs; - - /* use GPIO select 0 to get all gpio signals from the gpio out reg */ - brcms_b_mctrl(wlc_hw, MCTL_GPOUT_SEL_MASK, 0); - - /* - * Common GPIO setup: - * G0 = LED 0 = WLAN Activity - * G1 = LED 1 = WLAN 2.4 GHz Radio State - * G2 = LED 2 = WLAN 5 GHz Radio State - * G4 = radio disable input (HI enabled, LO disabled) - */ - - gc = gm = 0; - - /* Allocate GPIOs for mimo antenna diversity feature */ - if (wlc_hw->antsel_type == ANTSEL_2x3) { - /* Enable antenna diversity, use 2x3 mode */ - brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN, - MHF3_ANTSEL_EN, BRCM_BAND_ALL); - brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE, - MHF3_ANTSEL_MODE, BRCM_BAND_ALL); - - /* init superswitch control */ - wlc_phy_antsel_init(wlc_hw->band->pi, false); - - } else if (wlc_hw->antsel_type == ANTSEL_2x4) { - gm |= gc |= (BOARD_GPIO_12 | BOARD_GPIO_13); - /* - * The board itself is powered by these GPIOs - * (when not sending pattern) so set them high - */ - OR_REG(®s->psm_gpio_oe, - (BOARD_GPIO_12 | BOARD_GPIO_13)); - OR_REG(®s->psm_gpio_out, - (BOARD_GPIO_12 | BOARD_GPIO_13)); - - /* Enable antenna diversity, use 2x4 mode */ - brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN, - MHF3_ANTSEL_EN, BRCM_BAND_ALL); - brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE, 0, - BRCM_BAND_ALL); - - /* Configure the desired clock to be 4Mhz */ - brcms_b_write_shm(wlc_hw, M_ANTSEL_CLKDIV, - ANTSEL_CLKDIV_4MHZ); - } - - /* gpio 9 controls the PA. ucode is responsible for wiggling out and oe */ - if (wlc_hw->boardflags & BFL_PACTRL) - gm |= gc |= BOARD_GPIO_PACTRL; - - /* apply to gpiocontrol register */ - ai_gpiocontrol(wlc_hw->sih, gm, gc, GPIO_DRV_PRIORITY); -} - -static void brcms_ucode_download(struct brcms_hardware *wlc_hw) -{ - struct brcms_c_info *wlc; - wlc = wlc_hw->wlc; - - if (wlc_hw->ucode_loaded) - return; - - if (D11REV_IS(wlc_hw->corerev, 23)) { - if (BRCMS_ISNPHY(wlc_hw->band)) { - brcms_ucode_write(wlc_hw, bcm43xx_16_mimo, - bcm43xx_16_mimosz); - wlc_hw->ucode_loaded = true; - } else - wiphy_err(wlc->wiphy, "%s: wl%d: unsupported phy in " - "corerev %d\n", - __func__, wlc_hw->unit, wlc_hw->corerev); - } else if (D11REV_IS(wlc_hw->corerev, 24)) { - if (BRCMS_ISLCNPHY(wlc_hw->band)) { - brcms_ucode_write(wlc_hw, bcm43xx_24_lcn, - bcm43xx_24_lcnsz); - wlc_hw->ucode_loaded = true; - } else { - wiphy_err(wlc->wiphy, "%s: wl%d: unsupported phy in " - "corerev %d\n", - __func__, wlc_hw->unit, wlc_hw->corerev); - } - } -} - -static void brcms_ucode_write(struct brcms_hardware *wlc_hw, const u32 ucode[], - const uint nbytes) { - d11regs_t *regs = wlc_hw->regs; - uint i; - uint count; - - BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); - - count = (nbytes / sizeof(u32)); - - W_REG(®s->objaddr, (OBJADDR_AUTO_INC | OBJADDR_UCM_SEL)); - (void)R_REG(®s->objaddr); - for (i = 0; i < count; i++) - W_REG(®s->objdata, ucode[i]); -} - -static void brcms_c_write_inits(struct brcms_hardware *wlc_hw, - const struct d11init *inits) -{ - int i; - volatile u8 *base; - - BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); - - base = (volatile u8 *)wlc_hw->regs; - - for (i = 0; inits[i].addr != 0xffff; i++) { - if (inits[i].size == 2) - W_REG((u16 *)(base + inits[i].addr), - inits[i].value); - else if (inits[i].size == 4) - W_REG((u32 *)(base + inits[i].addr), - inits[i].value); - } -} - -static void brcms_c_ucode_txant_set(struct brcms_hardware *wlc_hw) -{ - u16 phyctl; - u16 phytxant = wlc_hw->bmac_phytxant; - u16 mask = PHY_TXC_ANT_MASK; - - /* set the Probe Response frame phy control word */ - phyctl = brcms_b_read_shm(wlc_hw, M_CTXPRS_BLK + C_CTX_PCTLWD_POS); - phyctl = (phyctl & ~mask) | phytxant; - brcms_b_write_shm(wlc_hw, M_CTXPRS_BLK + C_CTX_PCTLWD_POS, phyctl); - - /* set the Response (ACK/CTS) frame phy control word */ - phyctl = brcms_b_read_shm(wlc_hw, M_RSP_PCTLWD); - phyctl = (phyctl & ~mask) | phytxant; - brcms_b_write_shm(wlc_hw, M_RSP_PCTLWD, phyctl); -} - -void brcms_b_txant_set(struct brcms_hardware *wlc_hw, u16 phytxant) -{ - /* update sw state */ - wlc_hw->bmac_phytxant = phytxant; - - /* push to ucode if up */ - if (!wlc_hw->up) - return; - brcms_c_ucode_txant_set(wlc_hw); - -} - -u16 brcms_b_get_txant(struct brcms_hardware *wlc_hw) -{ - return (u16) wlc_hw->wlc->stf->txant; -} - -void brcms_b_antsel_type_set(struct brcms_hardware *wlc_hw, u8 antsel_type) -{ - wlc_hw->antsel_type = antsel_type; - - /* Update the antsel type for phy module to use */ - wlc_phy_antsel_type_set(wlc_hw->band->pi, antsel_type); -} - -void brcms_b_fifoerrors(struct brcms_hardware *wlc_hw) -{ - bool fatal = false; - uint unit; - uint intstatus, idx; - d11regs_t *regs = wlc_hw->regs; - struct wiphy *wiphy = wlc_hw->wlc->wiphy; - - unit = wlc_hw->unit; - - for (idx = 0; idx < NFIFO; idx++) { - /* read intstatus register and ignore any non-error bits */ - intstatus = - R_REG(®s->intctrlregs[idx].intstatus) & I_ERRORS; - if (!intstatus) - continue; - - BCMMSG(wlc_hw->wlc->wiphy, "wl%d: intstatus%d 0x%x\n", - unit, idx, intstatus); - - if (intstatus & I_RO) { - wiphy_err(wiphy, "wl%d: fifo %d: receive fifo " - "overflow\n", unit, idx); - fatal = true; - } - - if (intstatus & I_PC) { - wiphy_err(wiphy, "wl%d: fifo %d: descriptor error\n", - unit, idx); - fatal = true; - } - - if (intstatus & I_PD) { - wiphy_err(wiphy, "wl%d: fifo %d: data error\n", unit, - idx); - fatal = true; - } - - if (intstatus & I_DE) { - wiphy_err(wiphy, "wl%d: fifo %d: descriptor protocol " - "error\n", unit, idx); - fatal = true; - } - - if (intstatus & I_RU) { - wiphy_err(wiphy, "wl%d: fifo %d: receive descriptor " - "underflow\n", idx, unit); - } - - if (intstatus & I_XU) { - wiphy_err(wiphy, "wl%d: fifo %d: transmit fifo " - "underflow\n", idx, unit); - fatal = true; - } - - if (fatal) { - brcms_c_fatal_error(wlc_hw->wlc); /* big hammer */ - break; - } else - W_REG(®s->intctrlregs[idx].intstatus, - intstatus); - } -} - -void brcms_c_intrson(struct brcms_c_info *wlc) -{ - struct brcms_hardware *wlc_hw = wlc->hw; - wlc->macintmask = wlc->defmacintmask; - W_REG(&wlc_hw->regs->macintmask, wlc->macintmask); -} - -/* callback for siutils.c, which has only wlc handler, no wl - * they both check up, not only because there is no need to off/restore d11 interrupt - * but also because per-port code may require sync with valid interrupt. - */ - -static u32 brcms_c_wlintrsoff(struct brcms_c_info *wlc) -{ - if (!wlc->hw->up) - return 0; - - return brcms_intrsoff(wlc->wl); -} - -static void brcms_c_wlintrsrestore(struct brcms_c_info *wlc, u32 macintmask) -{ - if (!wlc->hw->up) - return; - - brcms_intrsrestore(wlc->wl, macintmask); -} - -u32 brcms_c_intrsoff(struct brcms_c_info *wlc) -{ - struct brcms_hardware *wlc_hw = wlc->hw; - u32 macintmask; - - if (!wlc_hw->clk) - return 0; - - macintmask = wlc->macintmask; /* isr can still happen */ - - W_REG(&wlc_hw->regs->macintmask, 0); - (void)R_REG(&wlc_hw->regs->macintmask); /* sync readback */ - udelay(1); /* ensure int line is no longer driven */ - wlc->macintmask = 0; - - /* return previous macintmask; resolve race between us and our isr */ - return wlc->macintstatus ? 0 : macintmask; -} - -void brcms_c_intrsrestore(struct brcms_c_info *wlc, u32 macintmask) -{ - struct brcms_hardware *wlc_hw = wlc->hw; - if (!wlc_hw->clk) - return; - - wlc->macintmask = macintmask; - W_REG(&wlc_hw->regs->macintmask, wlc->macintmask); -} - -static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool on, mbool flags) -{ - u8 null_ether_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; - - if (on) { - /* suspend tx fifos */ - brcms_b_tx_fifo_suspend(wlc_hw, TX_DATA_FIFO); - brcms_b_tx_fifo_suspend(wlc_hw, TX_CTL_FIFO); - brcms_b_tx_fifo_suspend(wlc_hw, TX_AC_BK_FIFO); - brcms_b_tx_fifo_suspend(wlc_hw, TX_AC_VI_FIFO); - - /* zero the address match register so we do not send ACKs */ - brcms_b_set_addrmatch(wlc_hw, RCM_MAC_OFFSET, - null_ether_addr); - } else { - /* resume tx fifos */ - if (!wlc_hw->wlc->tx_suspended) { - brcms_b_tx_fifo_resume(wlc_hw, TX_DATA_FIFO); - } - brcms_b_tx_fifo_resume(wlc_hw, TX_CTL_FIFO); - brcms_b_tx_fifo_resume(wlc_hw, TX_AC_BK_FIFO); - brcms_b_tx_fifo_resume(wlc_hw, TX_AC_VI_FIFO); - - /* Restore address */ - brcms_b_set_addrmatch(wlc_hw, RCM_MAC_OFFSET, - wlc_hw->etheraddr); - } - - wlc_phy_mute_upd(wlc_hw->band->pi, on, flags); - - if (on) - brcms_c_ucode_mute_override_set(wlc_hw); - else - brcms_c_ucode_mute_override_clear(wlc_hw); -} - -int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo, - uint *blocks) -{ - if (fifo >= NFIFO) - return -EINVAL; - - *blocks = wlc_hw->xmtfifo_sz[fifo]; - - return 0; -} - -/* brcms_b_tx_fifo_suspended: - * Check the MAC's tx suspend status for a tx fifo. - * - * When the MAC acknowledges a tx suspend, it indicates that no more - * packets will be transmitted out the radio. This is independent of - * DMA channel suspension---the DMA may have finished suspending, or may still - * be pulling data into a tx fifo, by the time the MAC acks the suspend - * request. - */ -static bool brcms_b_tx_fifo_suspended(struct brcms_hardware *wlc_hw, - uint tx_fifo) -{ - /* check that a suspend has been requested and is no longer pending */ - - /* - * for DMA mode, the suspend request is set in xmtcontrol of the DMA engine, - * and the tx fifo suspend at the lower end of the MAC is acknowledged in the - * chnstatus register. - * The tx fifo suspend completion is independent of the DMA suspend completion and - * may be acked before or after the DMA is suspended. - */ - if (dma_txsuspended(wlc_hw->di[tx_fifo]) && - (R_REG(&wlc_hw->regs->chnstatus) & - (1 << tx_fifo)) == 0) - return true; - - return false; -} - -static void brcms_b_tx_fifo_suspend(struct brcms_hardware *wlc_hw, - uint tx_fifo) -{ - u8 fifo = 1 << tx_fifo; - - /* Two clients of this code, 11h Quiet period and scanning. */ - - /* only suspend if not already suspended */ - if ((wlc_hw->suspended_fifos & fifo) == fifo) - return; - - /* force the core awake only if not already */ - if (wlc_hw->suspended_fifos == 0) - brcms_c_ucode_wake_override_set(wlc_hw, - BRCMS_WAKE_OVERRIDE_TXFIFO); - - wlc_hw->suspended_fifos |= fifo; - - if (wlc_hw->di[tx_fifo]) { - /* Suspending AMPDU transmissions in the middle can cause underflow - * which may result in mismatch between ucode and driver - * so suspend the mac before suspending the FIFO - */ - if (BRCMS_PHY_11N_CAP(wlc_hw->band)) - brcms_c_suspend_mac_and_wait(wlc_hw->wlc); - - dma_txsuspend(wlc_hw->di[tx_fifo]); - - if (BRCMS_PHY_11N_CAP(wlc_hw->band)) - brcms_c_enable_mac(wlc_hw->wlc); - } -} - -static void brcms_b_tx_fifo_resume(struct brcms_hardware *wlc_hw, - uint tx_fifo) -{ - /* BMAC_NOTE: BRCMS_TX_FIFO_ENAB is done in brcms_c_dpc() for DMA case - * but need to be done here for PIO otherwise the watchdog will catch - * the inconsistency and fire - */ - /* Two clients of this code, 11h Quiet period and scanning. */ - if (wlc_hw->di[tx_fifo]) - dma_txresume(wlc_hw->di[tx_fifo]); - - /* allow core to sleep again */ - if (wlc_hw->suspended_fifos == 0) - return; - else { - wlc_hw->suspended_fifos &= ~(1 << tx_fifo); - if (wlc_hw->suspended_fifos == 0) - brcms_c_ucode_wake_override_clear(wlc_hw, - BRCMS_WAKE_OVERRIDE_TXFIFO); - } -} - -/* - * Read and clear macintmask and macintstatus and intstatus registers. - * This routine should be called with interrupts off - * Return: - * -1 if DEVICEREMOVED(wlc) evaluates to true; - * 0 if the interrupt is not for us, or we are in some special cases; - * device interrupt status bits otherwise. - */ -static inline u32 wlc_intstatus(struct brcms_c_info *wlc, bool in_isr) -{ - struct brcms_hardware *wlc_hw = wlc->hw; - d11regs_t *regs = wlc_hw->regs; - u32 macintstatus; - - /* macintstatus includes a DMA interrupt summary bit */ - macintstatus = R_REG(®s->macintstatus); - - BCMMSG(wlc->wiphy, "wl%d: macintstatus: 0x%x\n", wlc_hw->unit, - macintstatus); - - /* detect cardbus removed, in power down(suspend) and in reset */ - if (DEVICEREMOVED(wlc)) - return -1; - - /* DEVICEREMOVED succeeds even when the core is still resetting, - * handle that case here. - */ - if (macintstatus == 0xffffffff) - return 0; - - /* defer unsolicited interrupts */ - macintstatus &= (in_isr ? wlc->macintmask : wlc->defmacintmask); - - /* if not for us */ - if (macintstatus == 0) - return 0; - - /* interrupts are already turned off for CFE build - * Caution: For CFE Turning off the interrupts again has some undesired - * consequences - */ - /* turn off the interrupts */ - W_REG(®s->macintmask, 0); - (void)R_REG(®s->macintmask); /* sync readback */ - wlc->macintmask = 0; - - /* clear device interrupts */ - W_REG(®s->macintstatus, macintstatus); - - /* MI_DMAINT is indication of non-zero intstatus */ - if (macintstatus & MI_DMAINT) { - /* - * only fifo interrupt enabled is I_RI in - * RX_FIFO. If MI_DMAINT is set, assume it - * is set and clear the interrupt. - */ - W_REG(®s->intctrlregs[RX_FIFO].intstatus, - DEF_RXINTMASK); - } - - return macintstatus; -} - -/* Update wlc->macintstatus and wlc->intstatus[]. */ -/* Return true if they are updated successfully. false otherwise */ -bool brcms_c_intrsupd(struct brcms_c_info *wlc) -{ - u32 macintstatus; - - /* read and clear macintstatus and intstatus registers */ - macintstatus = wlc_intstatus(wlc, false); - - /* device is removed */ - if (macintstatus == 0xffffffff) - return false; - - /* update interrupt status in software */ - wlc->macintstatus |= macintstatus; - - return true; -} - -/* - * First-level interrupt processing. - * Return true if this was our interrupt, false otherwise. - * *wantdpc will be set to true if further brcms_c_dpc() processing is required, - * false otherwise. - */ -bool brcms_c_isr(struct brcms_c_info *wlc, bool *wantdpc) -{ - struct brcms_hardware *wlc_hw = wlc->hw; - u32 macintstatus; - - *wantdpc = false; - - if (!wlc_hw->up || !wlc->macintmask) - return false; - - /* read and clear macintstatus and intstatus registers */ - macintstatus = wlc_intstatus(wlc, true); - - if (macintstatus == 0xffffffff) - wiphy_err(wlc->wiphy, "DEVICEREMOVED detected in the ISR code" - " path\n"); - - /* it is not for us */ - if (macintstatus == 0) - return false; - - *wantdpc = true; - - /* save interrupt status bits */ - wlc->macintstatus = macintstatus; - - return true; - -} - -static bool -brcms_b_dotxstatus(struct brcms_hardware *wlc_hw, struct tx_status *txs, - u32 s2) -{ - /* discard intermediate indications for ucode with one legitimate case: - * e.g. if "useRTS" is set. ucode did a successful rts/cts exchange, but the subsequent - * tx of DATA failed. so it will start rts/cts from the beginning (resetting the rts - * transmission count) - */ - if (!(txs->status & TX_STATUS_AMPDU) - && (txs->status & TX_STATUS_INTERMEDIATE)) { - return false; - } - - return brcms_c_dotxstatus(wlc_hw->wlc, txs, s2); -} - -/* process tx completion events in BMAC - * Return true if more tx status need to be processed. false otherwise. - */ -static bool -brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal) -{ - bool morepending = false; - struct brcms_c_info *wlc = wlc_hw->wlc; - d11regs_t *regs; - struct tx_status txstatus, *txs; - u32 s1, s2; - uint n = 0; - /* - * Param 'max_tx_num' indicates max. # tx status to process before - * break out. - */ - uint max_tx_num = bound ? wlc->pub->tunables->txsbnd : -1; - - BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit); - - txs = &txstatus; - regs = wlc_hw->regs; - while (!(*fatal) - && (s1 = R_REG(®s->frmtxstatus)) & TXS_V) { - - if (s1 == 0xffffffff) { - wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", - wlc_hw->unit, __func__); - return morepending; - } - - s2 = R_REG(®s->frmtxstatus2); - - txs->status = s1 & TXS_STATUS_MASK; - txs->frameid = (s1 & TXS_FID_MASK) >> TXS_FID_SHIFT; - txs->sequence = s2 & TXS_SEQ_MASK; - txs->phyerr = (s2 & TXS_PTX_MASK) >> TXS_PTX_SHIFT; - txs->lasttxtime = 0; - - *fatal = brcms_b_dotxstatus(wlc_hw, txs, s2); - - /* !give others some time to run! */ - if (++n >= max_tx_num) - break; - } - - if (*fatal) - return 0; - - if (n >= max_tx_num) - morepending = true; - - if (!pktq_empty(&wlc->pkt_queue->q)) - brcms_c_send_q(wlc); - - return morepending; -} - -void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc) -{ - struct brcms_hardware *wlc_hw = wlc->hw; - d11regs_t *regs = wlc_hw->regs; - u32 mc, mi; - struct wiphy *wiphy = wlc->wiphy; - - BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit, - wlc_hw->band->bandunit); - - /* - * Track overlapping suspend requests - */ - wlc_hw->mac_suspend_depth++; - if (wlc_hw->mac_suspend_depth > 1) - return; - - /* force the core awake */ - brcms_c_ucode_wake_override_set(wlc_hw, BRCMS_WAKE_OVERRIDE_MACSUSPEND); - - mc = R_REG(®s->maccontrol); - - if (mc == 0xffffffff) { - wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, - __func__); - brcms_down(wlc->wl); - return; - } - WARN_ON(mc & MCTL_PSM_JMP_0); - WARN_ON(!(mc & MCTL_PSM_RUN)); - WARN_ON(!(mc & MCTL_EN_MAC)); - - mi = R_REG(®s->macintstatus); - if (mi == 0xffffffff) { - wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, - __func__); - brcms_down(wlc->wl); - return; - } - WARN_ON(mi & MI_MACSSPNDD); - - brcms_b_mctrl(wlc_hw, MCTL_EN_MAC, 0); - - SPINWAIT(!(R_REG(®s->macintstatus) & MI_MACSSPNDD), - BRCMS_MAX_MAC_SUSPEND); - - if (!(R_REG(®s->macintstatus) & MI_MACSSPNDD)) { - wiphy_err(wiphy, "wl%d: wlc_suspend_mac_and_wait: waited %d uS" - " and MI_MACSSPNDD is still not on.\n", - wlc_hw->unit, BRCMS_MAX_MAC_SUSPEND); - wiphy_err(wiphy, "wl%d: psmdebug 0x%08x, phydebug 0x%08x, " - "psm_brc 0x%04x\n", wlc_hw->unit, - R_REG(®s->psmdebug), - R_REG(®s->phydebug), - R_REG(®s->psm_brc)); - } - - mc = R_REG(®s->maccontrol); - if (mc == 0xffffffff) { - wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, - __func__); - brcms_down(wlc->wl); - return; - } - WARN_ON(mc & MCTL_PSM_JMP_0); - WARN_ON(!(mc & MCTL_PSM_RUN)); - WARN_ON(mc & MCTL_EN_MAC); -} - -void brcms_c_enable_mac(struct brcms_c_info *wlc) -{ - struct brcms_hardware *wlc_hw = wlc->hw; - d11regs_t *regs = wlc_hw->regs; - u32 mc, mi; - - BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit, - wlc->band->bandunit); - - /* - * Track overlapping suspend requests - */ - wlc_hw->mac_suspend_depth--; - if (wlc_hw->mac_suspend_depth > 0) - return; - - mc = R_REG(®s->maccontrol); - WARN_ON(mc & MCTL_PSM_JMP_0); - WARN_ON(mc & MCTL_EN_MAC); - WARN_ON(!(mc & MCTL_PSM_RUN)); - - brcms_b_mctrl(wlc_hw, MCTL_EN_MAC, MCTL_EN_MAC); - W_REG(®s->macintstatus, MI_MACSSPNDD); - - mc = R_REG(®s->maccontrol); - WARN_ON(mc & MCTL_PSM_JMP_0); - WARN_ON(!(mc & MCTL_EN_MAC)); - WARN_ON(!(mc & MCTL_PSM_RUN)); - - mi = R_REG(®s->macintstatus); - WARN_ON(mi & MI_MACSSPNDD); - - brcms_c_ucode_wake_override_clear(wlc_hw, - BRCMS_WAKE_OVERRIDE_MACSUSPEND); -} - -static void brcms_upd_ofdm_pctl1_table(struct brcms_hardware *wlc_hw) -{ - u8 rate; - u8 rates[8] = { - BRCM_RATE_6M, BRCM_RATE_9M, BRCM_RATE_12M, BRCM_RATE_18M, - BRCM_RATE_24M, BRCM_RATE_36M, BRCM_RATE_48M, BRCM_RATE_54M - }; - u16 entry_ptr; - u16 pctl1; - uint i; - - if (!BRCMS_PHY_11N_CAP(wlc_hw->band)) - return; - - /* walk the phy rate table and update the entries */ - for (i = 0; i < ARRAY_SIZE(rates); i++) { - rate = rates[i]; - - entry_ptr = brcms_b_ofdm_ratetable_offset(wlc_hw, rate); - - /* read the SHM Rate Table entry OFDM PCTL1 values */ - pctl1 = - brcms_b_read_shm(wlc_hw, entry_ptr + M_RT_OFDM_PCTL1_POS); - - /* modify the value */ - pctl1 &= ~PHY_TXC1_MODE_MASK; - pctl1 |= (wlc_hw->hw_stf_ss_opmode << PHY_TXC1_MODE_SHIFT); - - /* Update the SHM Rate Table entry OFDM PCTL1 values */ - brcms_b_write_shm(wlc_hw, entry_ptr + M_RT_OFDM_PCTL1_POS, - pctl1); - } -} - -static u16 brcms_b_ofdm_ratetable_offset(struct brcms_hardware *wlc_hw, - u8 rate) -{ - uint i; - u8 plcp_rate = 0; - struct plcp_signal_rate_lookup { - u8 rate; - u8 signal_rate; - }; - /* OFDM RATE sub-field of PLCP SIGNAL field, per 802.11 sec 17.3.4.1 */ - const struct plcp_signal_rate_lookup rate_lookup[] = { - {BRCM_RATE_6M, 0xB}, - {BRCM_RATE_9M, 0xF}, - {BRCM_RATE_12M, 0xA}, - {BRCM_RATE_18M, 0xE}, - {BRCM_RATE_24M, 0x9}, - {BRCM_RATE_36M, 0xD}, - {BRCM_RATE_48M, 0x8}, - {BRCM_RATE_54M, 0xC} - }; - - for (i = 0; i < ARRAY_SIZE(rate_lookup); i++) { - if (rate == rate_lookup[i].rate) { - plcp_rate = rate_lookup[i].signal_rate; - break; - } - } - - /* Find the SHM pointer to the rate table entry by looking in the - * Direct-map Table - */ - return 2 * brcms_b_read_shm(wlc_hw, M_RT_DIRMAP_A + (plcp_rate * 2)); -} - -void brcms_b_band_stf_ss_set(struct brcms_hardware *wlc_hw, u8 stf_mode) -{ - wlc_hw->hw_stf_ss_opmode = stf_mode; - - if (wlc_hw->clk) - brcms_upd_ofdm_pctl1_table(wlc_hw); -} - -void -brcms_b_read_tsf(struct brcms_hardware *wlc_hw, u32 *tsf_l_ptr, - u32 *tsf_h_ptr) -{ - d11regs_t *regs = wlc_hw->regs; - - /* read the tsf timer low, then high to get an atomic read */ - *tsf_l_ptr = R_REG(®s->tsf_timerlow); - *tsf_h_ptr = R_REG(®s->tsf_timerhigh); - - return; -} - -static bool brcms_b_validate_chip_access(struct brcms_hardware *wlc_hw) -{ - d11regs_t *regs; - u32 w, val; - struct wiphy *wiphy = wlc_hw->wlc->wiphy; - - BCMMSG(wiphy, "wl%d\n", wlc_hw->unit); - - regs = wlc_hw->regs; - - /* Validate dchip register access */ - - W_REG(®s->objaddr, OBJADDR_SHM_SEL | 0); - (void)R_REG(®s->objaddr); - w = R_REG(®s->objdata); - - /* Can we write and read back a 32bit register? */ - W_REG(®s->objaddr, OBJADDR_SHM_SEL | 0); - (void)R_REG(®s->objaddr); - W_REG(®s->objdata, (u32) 0xaa5555aa); - - W_REG(®s->objaddr, OBJADDR_SHM_SEL | 0); - (void)R_REG(®s->objaddr); - val = R_REG(®s->objdata); - if (val != (u32) 0xaa5555aa) { - wiphy_err(wiphy, "wl%d: validate_chip_access: SHM = 0x%x, " - "expected 0xaa5555aa\n", wlc_hw->unit, val); - return false; - } - - W_REG(®s->objaddr, OBJADDR_SHM_SEL | 0); - (void)R_REG(®s->objaddr); - W_REG(®s->objdata, (u32) 0x55aaaa55); - - W_REG(®s->objaddr, OBJADDR_SHM_SEL | 0); - (void)R_REG(®s->objaddr); - val = R_REG(®s->objdata); - if (val != (u32) 0x55aaaa55) { - wiphy_err(wiphy, "wl%d: validate_chip_access: SHM = 0x%x, " - "expected 0x55aaaa55\n", wlc_hw->unit, val); - return false; - } - - W_REG(®s->objaddr, OBJADDR_SHM_SEL | 0); - (void)R_REG(®s->objaddr); - W_REG(®s->objdata, w); - - /* clear CFPStart */ - W_REG(®s->tsf_cfpstart, 0); - - w = R_REG(®s->maccontrol); - if ((w != (MCTL_IHR_EN | MCTL_WAKE)) && - (w != (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE))) { - wiphy_err(wiphy, "wl%d: validate_chip_access: maccontrol = " - "0x%x, expected 0x%x or 0x%x\n", wlc_hw->unit, w, - (MCTL_IHR_EN | MCTL_WAKE), - (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE)); - return false; - } - - return true; -} - -#define PHYPLL_WAIT_US 100000 - -void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on) -{ - d11regs_t *regs; - u32 tmp; - - BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); - - tmp = 0; - regs = wlc_hw->regs; - - if (on) { - if ((wlc_hw->sih->chip == BCM4313_CHIP_ID)) { - OR_REG(®s->clk_ctl_st, - (CCS_ERSRC_REQ_HT | CCS_ERSRC_REQ_D11PLL | - CCS_ERSRC_REQ_PHYPLL)); - SPINWAIT((R_REG(®s->clk_ctl_st) & - (CCS_ERSRC_AVAIL_HT)) != (CCS_ERSRC_AVAIL_HT), - PHYPLL_WAIT_US); - - tmp = R_REG(®s->clk_ctl_st); - if ((tmp & (CCS_ERSRC_AVAIL_HT)) != - (CCS_ERSRC_AVAIL_HT)) { - wiphy_err(wlc_hw->wlc->wiphy, "%s: turn on PHY" - " PLL failed\n", __func__); - } - } else { - OR_REG(®s->clk_ctl_st, - (CCS_ERSRC_REQ_D11PLL | CCS_ERSRC_REQ_PHYPLL)); - SPINWAIT((R_REG(®s->clk_ctl_st) & - (CCS_ERSRC_AVAIL_D11PLL | - CCS_ERSRC_AVAIL_PHYPLL)) != - (CCS_ERSRC_AVAIL_D11PLL | - CCS_ERSRC_AVAIL_PHYPLL), PHYPLL_WAIT_US); - - tmp = R_REG(®s->clk_ctl_st); - if ((tmp & - (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL)) - != - (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL)) { - wiphy_err(wlc_hw->wlc->wiphy, "%s: turn on " - "PHY PLL failed\n", __func__); - } - } - } else { - /* Since the PLL may be shared, other cores can still be requesting it; - * so we'll deassert the request but not wait for status to comply. - */ - AND_REG(®s->clk_ctl_st, ~CCS_ERSRC_REQ_PHYPLL); - tmp = R_REG(®s->clk_ctl_st); - } -} - -void brcms_c_coredisable(struct brcms_hardware *wlc_hw) -{ - bool dev_gone; - - BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); - - dev_gone = DEVICEREMOVED(wlc_hw->wlc); - - if (dev_gone) - return; - - if (wlc_hw->noreset) - return; - - /* radio off */ - wlc_phy_switch_radio(wlc_hw->band->pi, OFF); - - /* turn off analog core */ - wlc_phy_anacore(wlc_hw->band->pi, OFF); - - /* turn off PHYPLL to save power */ - brcms_b_core_phypll_ctl(wlc_hw, false); - - /* No need to set wlc->pub->radio_active = OFF - * because this function needs down capability and - * radio_active is designed for BCMNODOWN. - */ - - /* remove gpio controls */ - if (wlc_hw->ucode_dbgsel) - ai_gpiocontrol(wlc_hw->sih, ~0, 0, GPIO_DRV_PRIORITY); - - wlc_hw->clk = false; - ai_core_disable(wlc_hw->sih, 0); - wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false); -} - -/* power both the pll and external oscillator on/off */ -static void brcms_b_xtal(struct brcms_hardware *wlc_hw, bool want) -{ - BCMMSG(wlc_hw->wlc->wiphy, "wl%d: want %d\n", wlc_hw->unit, want); - - /* dont power down if plldown is false or we must poll hw radio disable */ - if (!want && wlc_hw->pllreq) - return; - - if (wlc_hw->sih) - ai_clkctl_xtal(wlc_hw->sih, XTAL | PLL, want); - - wlc_hw->sbclk = want; - if (!wlc_hw->sbclk) { - wlc_hw->clk = false; - if (wlc_hw->band && wlc_hw->band->pi) - wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false); - } -} - -static void brcms_c_flushqueues(struct brcms_c_info *wlc) -{ - struct brcms_hardware *wlc_hw = wlc->hw; - uint i; - - wlc->txpend16165war = 0; - - /* free any posted tx packets */ - for (i = 0; i < NFIFO; i++) - if (wlc_hw->di[i]) { - dma_txreclaim(wlc_hw->di[i], DMA_RANGE_ALL); - TXPKTPENDCLR(wlc, i); - BCMMSG(wlc->wiphy, "pktpend fifo %d clrd\n", i); - } - - /* free any posted rx packets */ - dma_rxreclaim(wlc_hw->di[RX_FIFO]); -} - -u16 brcms_b_read_shm(struct brcms_hardware *wlc_hw, uint offset) -{ - return brcms_b_read_objmem(wlc_hw, offset, OBJADDR_SHM_SEL); -} - -void brcms_b_write_shm(struct brcms_hardware *wlc_hw, uint offset, u16 v) -{ - brcms_b_write_objmem(wlc_hw, offset, v, OBJADDR_SHM_SEL); -} - -static u16 -brcms_b_read_objmem(struct brcms_hardware *wlc_hw, uint offset, u32 sel) -{ - d11regs_t *regs = wlc_hw->regs; - volatile u16 *objdata_lo = (volatile u16 *)®s->objdata; - volatile u16 *objdata_hi = objdata_lo + 1; - u16 v; - - W_REG(®s->objaddr, sel | (offset >> 2)); - (void)R_REG(®s->objaddr); - if (offset & 2) { - v = R_REG(objdata_hi); - } else { - v = R_REG(objdata_lo); - } - - return v; -} - -static void -brcms_b_write_objmem(struct brcms_hardware *wlc_hw, uint offset, u16 v, - u32 sel) -{ - d11regs_t *regs = wlc_hw->regs; - volatile u16 *objdata_lo = (volatile u16 *)®s->objdata; - volatile u16 *objdata_hi = objdata_lo + 1; - - W_REG(®s->objaddr, sel | (offset >> 2)); - (void)R_REG(®s->objaddr); - if (offset & 2) { - W_REG(objdata_hi, v); - } else { - W_REG(objdata_lo, v); - } -} - -/* Copy a buffer to shared memory of specified type . - * SHM 'offset' needs to be an even address and - * Buffer length 'len' must be an even number of bytes - * 'sel' selects the type of memory - */ -void -brcms_b_copyto_objmem(struct brcms_hardware *wlc_hw, uint offset, - const void *buf, int len, u32 sel) -{ - u16 v; - const u8 *p = (const u8 *)buf; - int i; - - if (len <= 0 || (offset & 1) || (len & 1)) - return; - - for (i = 0; i < len; i += 2) { - v = p[i] | (p[i + 1] << 8); - brcms_b_write_objmem(wlc_hw, offset + i, v, sel); - } -} - -/* Copy a piece of shared memory of specified type to a buffer . - * SHM 'offset' needs to be an even address and - * Buffer length 'len' must be an even number of bytes - * 'sel' selects the type of memory - */ -void -brcms_b_copyfrom_objmem(struct brcms_hardware *wlc_hw, uint offset, void *buf, - int len, u32 sel) -{ - u16 v; - u8 *p = (u8 *) buf; - int i; - - if (len <= 0 || (offset & 1) || (len & 1)) - return; - - for (i = 0; i < len; i += 2) { - v = brcms_b_read_objmem(wlc_hw, offset + i, sel); - p[i] = v & 0xFF; - p[i + 1] = (v >> 8) & 0xFF; - } -} - -void brcms_b_copyfrom_vars(struct brcms_hardware *wlc_hw, char **buf, - uint *len) -{ - BCMMSG(wlc_hw->wlc->wiphy, "nvram vars totlen=%d\n", - wlc_hw->vars_size); - - *buf = wlc_hw->vars; - *len = wlc_hw->vars_size; -} - -void brcms_b_retrylimit_upd(struct brcms_hardware *wlc_hw, u16 SRL, u16 LRL) -{ - wlc_hw->SRL = SRL; - wlc_hw->LRL = LRL; - - /* write retry limit to SCR, shouldn't need to suspend */ - if (wlc_hw->up) { - W_REG(&wlc_hw->regs->objaddr, - OBJADDR_SCR_SEL | S_DOT11_SRC_LMT); - (void)R_REG(&wlc_hw->regs->objaddr); - W_REG(&wlc_hw->regs->objdata, wlc_hw->SRL); - W_REG(&wlc_hw->regs->objaddr, - OBJADDR_SCR_SEL | S_DOT11_LRC_LMT); - (void)R_REG(&wlc_hw->regs->objaddr); - W_REG(&wlc_hw->regs->objdata, wlc_hw->LRL); - } -} - -void brcms_b_pllreq(struct brcms_hardware *wlc_hw, bool set, mbool req_bit) -{ - if (set) { - if (mboolisset(wlc_hw->pllreq, req_bit)) - return; - - mboolset(wlc_hw->pllreq, req_bit); - - if (mboolisset(wlc_hw->pllreq, BRCMS_PLLREQ_FLIP)) { - if (!wlc_hw->sbclk) { - brcms_b_xtal(wlc_hw, ON); - } - } - } else { - if (!mboolisset(wlc_hw->pllreq, req_bit)) - return; - - mboolclr(wlc_hw->pllreq, req_bit); - - if (mboolisset(wlc_hw->pllreq, BRCMS_PLLREQ_FLIP)) { - if (wlc_hw->sbclk) { - brcms_b_xtal(wlc_hw, OFF); - } - } - } - - return; -} - -u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate) -{ - u16 table_ptr; - u8 phy_rate, index; - - /* get the phy specific rate encoding for the PLCP SIGNAL field */ - if (IS_OFDM(rate)) - table_ptr = M_RT_DIRMAP_A; - else - table_ptr = M_RT_DIRMAP_B; - - /* for a given rate, the LS-nibble of the PLCP SIGNAL field is - * the index into the rate table. - */ - phy_rate = rate_info[rate] & BRCMS_RATE_MASK; - index = phy_rate & 0xf; - - /* Find the SHM pointer to the rate table entry by looking in the - * Direct-map Table - */ - return 2 * brcms_b_read_shm(wlc_hw, table_ptr + (index * 2)); -} - -void brcms_b_antsel_set(struct brcms_hardware *wlc_hw, u32 antsel_avail) -{ - wlc_hw->antsel_avail = antsel_avail; -} diff --git a/drivers/staging/brcm80211/brcmsmac/bmac.h b/drivers/staging/brcm80211/brcmsmac/bmac.h deleted file mode 100644 index 3c9ad4f..0000000 --- a/drivers/staging/brcm80211/brcmsmac/bmac.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -#ifndef _BRCM_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_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/channel.c b/drivers/staging/brcm80211/brcmsmac/channel.c index f59693e..89d8fa7 100644 --- a/drivers/staging/brcm80211/brcmsmac/channel.c +++ b/drivers/staging/brcm80211/brcmsmac/channel.c @@ -20,7 +20,6 @@ #include <defs.h> #include "pub.h" #include "phy/phy_hal.h" -#include "bmac.h" #include "main.h" #include "stf.h" #include "channel.h" @@ -31,10 +30,14 @@ #define VALID_CHANNEL20(wlc, val) brcms_c_valid_channel20((wlc)->cmi, val) struct brcms_cm_band { - u8 locale_flags; /* struct locale_info flags */ - chanvec_t valid_channels; /* List of valid channels in the country */ - const chanvec_t *restricted_channels; /* List of restricted use channels */ - const chanvec_t *radar_channels; /* List of radar sensitive channels */ + /* struct locale_info flags */ + u8 locale_flags; + /* List of valid channels in the country */ + struct brcms_chanvec valid_channels; + /* List of restricted use channels */ + const struct brcms_chanvec *restricted_channels; + /* List of radar sensitive channels */ + const struct brcms_chanvec *radar_channels; u8 PAD[8]; }; @@ -50,7 +53,8 @@ struct brcms_cm_info { /* per-band state (one per phy/radio) */ struct brcms_cm_band bandstate[MAXBANDS]; /* quiet channels currently for radar sensitivity or 11h support */ - chanvec_t quiet_channels; /* channels on which we cannot transmit */ + /* channels on which we cannot transmit */ + struct brcms_chanvec quiet_channels; }; static int brcms_c_channels_init(struct brcms_cm_info *wlc_cm, @@ -79,7 +83,7 @@ brcms_c_countrycode_map(struct brcms_cm_info *wlc_cm, static void brcms_c_channels_commit(struct brcms_cm_info *wlc_cm); static void brcms_c_quiet_channels_reset(struct brcms_cm_info *wlc_cm); static bool brcms_c_quiet_chanspec(struct brcms_cm_info *wlc_cm, - chanspec_t chspec); + u16 chspec); static bool brcms_c_valid_channel20_db(struct brcms_cm_info *wlc_cm, uint val); static bool brcms_c_valid_channel20_in_band(struct brcms_cm_info *wlc_cm, uint bandunit, uint val); @@ -89,7 +93,7 @@ static const struct country_info * brcms_c_country_lookup(struct brcms_c_info *wlc, const char *ccode); static void brcms_c_locale_get_channels(const struct locale_info *locale, - chanvec_t *valid_channels); + struct brcms_chanvec *valid_channels); static const struct locale_info *brcms_c_get_locale_2g(u8 locale_idx); static const struct locale_info *brcms_c_get_locale_5g(u8 locale_idx); static bool brcms_c_japan(struct brcms_c_info *wlc); @@ -97,15 +101,12 @@ static bool brcms_c_japan_ccode(const char *ccode); static void brcms_c_channel_min_txpower_limits_with_local_constraint( struct brcms_cm_info *wlc_cm, struct txpwr_limits *txpwr, u8 local_constraint_qdbm); -static void brcms_c_locale_add_channels(chanvec_t *target, - const chanvec_t *channels); +static void brcms_c_locale_add_channels(struct brcms_chanvec *target, + const struct brcms_chanvec *channels); static const struct locale_mimo_info *brcms_c_get_mimo_2g(u8 locale_idx); static const struct locale_mimo_info *brcms_c_get_mimo_5g(u8 locale_idx); /* QDB() macro takes a dB value and converts to a quarter dB value */ -#ifdef QDB -#undef QDB -#endif #define QDB(n) ((n) * BRCMS_TXPWR_DB_FACTOR) /* Regulatory Matrix Spreadsheet (CLM) MIMO v3.7.9 */ @@ -115,7 +116,7 @@ static const struct locale_mimo_info *brcms_c_get_mimo_5g(u8 locale_idx); */ /* No channels */ -static const chanvec_t chanvec_none = { +static const struct brcms_chanvec chanvec_none = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -123,7 +124,7 @@ static const chanvec_t chanvec_none = { }; /* All 2.4 GHz HW channels */ -const chanvec_t chanvec_all_2G = { +const struct brcms_chanvec chanvec_all_2G = { {0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -131,7 +132,7 @@ const chanvec_t chanvec_all_2G = { }; /* All 5 GHz HW channels */ -const chanvec_t chanvec_all_5G = { +const struct brcms_chanvec chanvec_all_5G = { {0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x11, 0x11, 0x01, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x20, 0x22, 0x22, 0x00, 0x00, 0x11, @@ -145,10 +146,11 @@ const chanvec_t chanvec_all_5G = { /* No radar */ #define radar_set_none chanvec_none -static const chanvec_t radar_set1 = { /* Channels 52 - 64, 100 - 140 */ - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, /* 52 - 60 */ - 0x01, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x11, /* 64, 100 - 124 */ - 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 128 - 140 */ +/* Channels 52 - 64, 100 - 140 */ +static const struct brcms_chanvec radar_set1 = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, /* 52 - 60 */ + 0x01, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x11, /* 64, 100 - 124 */ + 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 128 - 140 */ 0x00, 0x00, 0x00, 0x00} }; @@ -159,7 +161,7 @@ static const chanvec_t radar_set1 = { /* Channels 52 - 64, 100 - 140 */ #define restricted_set_none chanvec_none /* Channels 34, 38, 42, 46 */ -static const chanvec_t restricted_set_japan_legacy = { +static const struct brcms_chanvec restricted_set_japan_legacy = { {0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -167,7 +169,7 @@ static const chanvec_t restricted_set_japan_legacy = { }; /* Channels 12, 13 */ -static const chanvec_t restricted_set_2g_short = { +static const struct brcms_chanvec restricted_set_2g_short = { {0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -175,7 +177,7 @@ static const chanvec_t restricted_set_2g_short = { }; /* Channel 165 */ -static const chanvec_t restricted_chan_165 = { +static const struct brcms_chanvec restricted_chan_165 = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, @@ -183,7 +185,7 @@ static const chanvec_t restricted_chan_165 = { }; /* Channels 36 - 48 & 149 - 165 */ -static const chanvec_t restricted_low_hi = { +static const struct brcms_chanvec restricted_low_hi = { {0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x22, 0x22, 0x00, 0x00, 0x00, @@ -191,7 +193,7 @@ static const chanvec_t restricted_low_hi = { }; /* Channels 12 - 14 */ -static const chanvec_t restricted_set_12_13_14 = { +static const struct brcms_chanvec restricted_set_12_13_14 = { {0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -215,15 +217,19 @@ static const chanvec_t restricted_set_12_13_14 = { #define LOCALE_CHAN_52_140_ALL (1<<14) #define LOCALE_SET_5G_HIGH4 (1<<15) /* 184-216 */ -#define LOCALE_CHAN_36_64 (LOCALE_SET_5G_LOW1 | LOCALE_SET_5G_LOW2 | LOCALE_SET_5G_LOW3) -#define LOCALE_CHAN_52_64 (LOCALE_SET_5G_LOW2 | LOCALE_SET_5G_LOW3) -#define LOCALE_CHAN_100_124 (LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2) -#define LOCALE_CHAN_100_140 \ - (LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2 | LOCALE_SET_5G_MID3 | LOCALE_SET_5G_HIGH1) -#define LOCALE_CHAN_149_165 (LOCALE_SET_5G_HIGH2 | LOCALE_SET_5G_HIGH3) -#define LOCALE_CHAN_184_216 LOCALE_SET_5G_HIGH4 +#define LOCALE_CHAN_36_64 (LOCALE_SET_5G_LOW1 | \ + LOCALE_SET_5G_LOW2 | \ + LOCALE_SET_5G_LOW3) +#define LOCALE_CHAN_52_64 (LOCALE_SET_5G_LOW2 | LOCALE_SET_5G_LOW3) +#define LOCALE_CHAN_100_124 (LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2) +#define LOCALE_CHAN_100_140 (LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2 | \ + LOCALE_SET_5G_MID3 | LOCALE_SET_5G_HIGH1) +#define LOCALE_CHAN_149_165 (LOCALE_SET_5G_HIGH2 | LOCALE_SET_5G_HIGH3) +#define LOCALE_CHAN_184_216 LOCALE_SET_5G_HIGH4 -#define LOCALE_CHAN_01_14 (LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13 | LOCALE_CHAN_14) +#define LOCALE_CHAN_01_14 (LOCALE_CHAN_01_11 | \ + LOCALE_CHAN_12_13 | \ + LOCALE_CHAN_14) #define LOCALE_RADAR_SET_NONE 0 #define LOCALE_RADAR_SET_1 1 @@ -240,12 +246,12 @@ static const chanvec_t restricted_set_12_13_14 = { /* global memory to provide working buffer for expanded locale */ -static const chanvec_t *g_table_radar_set[] = { +static const struct brcms_chanvec *g_table_radar_set[] = { &chanvec_none, &radar_set1 }; -static const chanvec_t *g_table_restricted_chan[] = { +static const struct brcms_chanvec *g_table_restricted_chan[] = { &chanvec_none, /* restricted_set_none */ &restricted_set_2g_short, &restricted_chan_165, @@ -257,119 +263,119 @@ static const chanvec_t *g_table_restricted_chan[] = { &restricted_set_12_13_14 }; -static const chanvec_t locale_2g_01_11 = { +static const struct brcms_chanvec locale_2g_01_11 = { {0xfe, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }; -static const chanvec_t locale_2g_12_13 = { +static const struct brcms_chanvec locale_2g_12_13 = { {0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }; -static const chanvec_t locale_2g_14 = { +static const struct brcms_chanvec locale_2g_14 = { {0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }; -static const chanvec_t locale_5g_LOW_JP1 = { +static const struct brcms_chanvec locale_5g_LOW_JP1 = { {0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }; -static const chanvec_t locale_5g_LOW_JP2 = { +static const struct brcms_chanvec locale_5g_LOW_JP2 = { {0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }; -static const chanvec_t locale_5g_LOW1 = { +static const struct brcms_chanvec locale_5g_LOW1 = { {0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }; -static const chanvec_t locale_5g_LOW2 = { +static const struct brcms_chanvec locale_5g_LOW2 = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }; -static const chanvec_t locale_5g_LOW3 = { +static const struct brcms_chanvec locale_5g_LOW3 = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }; -static const chanvec_t locale_5g_MID1 = { +static const struct brcms_chanvec locale_5g_MID1 = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }; -static const chanvec_t locale_5g_MID2 = { +static const struct brcms_chanvec locale_5g_MID2 = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }; -static const chanvec_t locale_5g_MID3 = { +static const struct brcms_chanvec locale_5g_MID3 = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }; -static const chanvec_t locale_5g_HIGH1 = { +static const struct brcms_chanvec locale_5g_HIGH1 = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }; -static const chanvec_t locale_5g_HIGH2 = { +static const struct brcms_chanvec locale_5g_HIGH2 = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x22, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }; -static const chanvec_t locale_5g_HIGH3 = { +static const struct brcms_chanvec locale_5g_HIGH3 = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }; -static const chanvec_t locale_5g_52_140_ALL = { +static const struct brcms_chanvec locale_5g_52_140_ALL = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }; -static const chanvec_t locale_5g_HIGH4 = { +static const struct brcms_chanvec locale_5g_HIGH4 = { {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x11} }; -static const chanvec_t *g_table_locale_base[] = { +static const struct brcms_chanvec *g_table_locale_base[] = { &locale_2g_01_11, &locale_2g_12_13, &locale_2g_14, @@ -388,27 +394,25 @@ static const chanvec_t *g_table_locale_base[] = { &locale_5g_HIGH4 }; -static void brcms_c_locale_add_channels(chanvec_t *target, - const chanvec_t *channels) +static void brcms_c_locale_add_channels(struct brcms_chanvec *target, + const struct brcms_chanvec *channels) { u8 i; - for (i = 0; i < sizeof(chanvec_t); i++) { + for (i = 0; i < sizeof(struct brcms_chanvec); i++) target->vec[i] |= channels->vec[i]; - } } static void brcms_c_locale_get_channels(const struct locale_info *locale, - chanvec_t *channels) + struct brcms_chanvec *channels) { u8 i; - memset(channels, 0, sizeof(chanvec_t)); + memset(channels, 0, sizeof(struct brcms_chanvec)); for (i = 0; i < ARRAY_SIZE(g_table_locale_base); i++) { - if (locale->valid_channels & (1 << i)) { + if (locale->valid_channels & (1 << i)) brcms_c_locale_add_channels(channels, g_table_locale_base[i]); - } } } @@ -482,22 +486,14 @@ static const struct locale_mimo_info *g_mimo_5g_table[] = { &locale_11n }; -#ifdef LC -#undef LC -#endif #define LC(id) LOCALE_MIMO_IDX_ ## id -#ifdef LC_2G -#undef LC_2G -#endif #define LC_2G(id) LOCALE_2G_IDX_ ## id -#ifdef LC_5G -#undef LC_5G -#endif #define LC_5G(id) LOCALE_5G_IDX_ ## id -#define LOCALES(band2, band5, mimo2, mimo5) {LC_2G(band2), LC_5G(band5), LC(mimo2), LC(mimo5)} +#define LOCALES(band2, band5, mimo2, mimo5) \ + {LC_2G(band2), LC_5G(band5), LC(mimo2), LC(mimo5)} static const struct { char abbrev[BRCM_CNTRY_BUF_SZ]; /* country abbreviation */ @@ -586,33 +582,33 @@ struct chan20_info chan20_info[] = { static const struct locale_info *brcms_c_get_locale_2g(u8 locale_idx) { - if (locale_idx >= ARRAY_SIZE(g_locale_2g_table)) { + if (locale_idx >= ARRAY_SIZE(g_locale_2g_table)) return NULL; /* error condition */ - } + return g_locale_2g_table[locale_idx]; } static const struct locale_info *brcms_c_get_locale_5g(u8 locale_idx) { - if (locale_idx >= ARRAY_SIZE(g_locale_5g_table)) { + if (locale_idx >= ARRAY_SIZE(g_locale_5g_table)) return NULL; /* error condition */ - } + return g_locale_5g_table[locale_idx]; } static const struct locale_mimo_info *brcms_c_get_mimo_2g(u8 locale_idx) { - if (locale_idx >= ARRAY_SIZE(g_mimo_2g_table)) { + if (locale_idx >= ARRAY_SIZE(g_mimo_2g_table)) return NULL; - } + return g_mimo_2g_table[locale_idx]; } static const struct locale_mimo_info *brcms_c_get_mimo_5g(u8 locale_idx) { - if (locale_idx >= ARRAY_SIZE(g_mimo_5g_table)) { + if (locale_idx >= ARRAY_SIZE(g_mimo_5g_table)) return NULL; - } + return g_mimo_5g_table[locale_idx]; } @@ -638,11 +634,13 @@ struct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc) /* store the country code for passing up as a regulatory hint */ ccode = getvar(wlc->pub->vars, "ccode"); - if (ccode) { + if (ccode) strncpy(wlc->pub->srom_ccode, ccode, BRCM_CNTRY_BUF_SZ - 1); - } - /* internal country information which must match regulatory constraints in firmware */ + /* + * internal country information which must match + * regulatory constraints in firmware + */ memset(country_abbrev, 0, BRCM_CNTRY_BUF_SZ); strncpy(country_abbrev, "X2", sizeof(country_abbrev) - 1); country = brcms_c_country_lookup(wlc, country_abbrev); @@ -670,8 +668,10 @@ brcms_c_channel_locale_flags_in_band(struct brcms_cm_info *wlc_cm, return wlc_cm->bandstate[bandunit].locale_flags; } -/* set the driver's current country and regulatory information using a country code - * as the source. Lookup built in country information found with the country code. +/* + * set the driver's current country and regulatory information using + * a country code as the source. Lookup built in country information + * found with the country code. */ static int brcms_c_set_countrycode(struct brcms_cm_info *wlc_cm, const char *ccode) @@ -694,7 +694,10 @@ brcms_c_set_countrycode_rev(struct brcms_cm_info *wlc_cm, * otherwise use the ccode and regrev directly */ if (regrev == -1) { - /* map the country code to a built-in country code, regrev, and country_info */ + /* + * map the country code to a built-in country + * code, regrev, and country_info + */ country = brcms_c_countrycode_map(wlc_cm, ccode, mapped_ccode, &mapped_regrev); @@ -715,8 +718,10 @@ brcms_c_set_countrycode_rev(struct brcms_cm_info *wlc_cm, return 0; } -/* set the driver's current country and regulatory information using a country code - * as the source. Look up built in country information found with the country code. +/* + * set the driver's current country and regulatory information + * using a country code as the source. Look up built in country + * information found with the country code. */ static void brcms_c_set_country_common(struct brcms_cm_info *wlc_cm, @@ -755,11 +760,10 @@ brcms_c_set_country_common(struct brcms_cm_info *wlc_cm, brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]); /* set or restore gmode as required by regulatory */ locale = brcms_c_get_locale_2g(country->locale_2G); - if (locale && (locale->flags & BRCMS_NO_OFDM)) { + if (locale && (locale->flags & BRCMS_NO_OFDM)) brcms_c_set_gmode(wlc, GMODE_LEGACY_B, false); - } else { + else brcms_c_set_gmode(wlc, wlc->protection->gmode_user, false); - } brcms_c_channels_init(wlc_cm, country); @@ -776,7 +780,10 @@ brcms_c_country_lookup(struct brcms_c_info *wlc, const char *ccode) char mapped_ccode[BRCM_CNTRY_BUF_SZ]; uint mapped_regrev; - /* map the country code to a built-in country code, regrev, and country_info struct */ + /* + * map the country code to a built-in country code, regrev, and + * country_info struct + */ country = brcms_c_countrycode_map(wlc->cmi, ccode, mapped_ccode, &mapped_regrev); @@ -849,16 +856,18 @@ brcms_c_country_lookup_direct(const char *ccode, uint regrev) /* Should just return 0 for single locale driver. */ /* Keep it this way in case we add more locales. (for now anyway) */ - /* all other country def arrays are for regrev == 0, so if regrev is non-zero, fail */ + /* + * all other country def arrays are for regrev == 0, so if + * regrev is non-zero, fail + */ if (regrev > 0) return NULL; /* find matched table entry from country code */ size = ARRAY_SIZE(cntry_locales); for (i = 0; i < size; i++) { - if (strcmp(ccode, cntry_locales[i].abbrev) == 0) { + if (strcmp(ccode, cntry_locales[i].abbrev) == 0) return &cntry_locales[i].country; - } } return NULL; } @@ -871,7 +880,7 @@ brcms_c_channels_init(struct brcms_cm_info *wlc_cm, uint i, j; struct brcms_band *band; const struct locale_info *li; - chanvec_t sup_chan; + struct brcms_chanvec sup_chan; const struct locale_mimo_info *li_mimo; band = wlc->band; @@ -895,15 +904,16 @@ brcms_c_channels_init(struct brcms_cm_info *wlc_cm, wlc_cm->bandstate[band->bandunit].radar_channels = g_table_radar_set[li->radar_channels]; - /* set the channel availability, - * masking out the channels that may not be supported on this phy + /* + * set the channel availability, masking out the channels + * that may not be supported on this phy. */ wlc_phy_chanspec_band_validch(band->pi, band->bandtype, &sup_chan); brcms_c_locale_get_channels(li, &wlc_cm->bandstate[band->bandunit]. valid_channels); - for (j = 0; j < sizeof(chanvec_t); j++) + for (j = 0; j < sizeof(struct brcms_chanvec); j++) wlc_cm->bandstate[band->bandunit].valid_channels. vec[j] &= sup_chan.vec[j]; } @@ -925,36 +935,43 @@ static void brcms_c_channels_commit(struct brcms_cm_info *wlc_cm) /* search for the existence of any valid channel */ for (chan = 0; chan < MAXCHANNEL; chan++) { - if (VALID_CHANNEL20_DB(wlc, chan)) { + if (VALID_CHANNEL20_DB(wlc, chan)) break; - } } if (chan == MAXCHANNEL) chan = INVCHANNEL; - /* based on the channel search above, set or clear WL_RADIO_COUNTRY_DISABLE */ + /* + * based on the channel search above, set or + * clear WL_RADIO_COUNTRY_DISABLE. + */ if (chan == INVCHANNEL) { - /* country/locale with no valid channels, set the radio disable bit */ + /* + * country/locale with no valid channels, set + * the radio disable bit + */ mboolset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); wiphy_err(wlc->wiphy, "wl%d: %s: no valid channel for \"%s\" " "nbands %d bandlocked %d\n", wlc->pub->unit, __func__, wlc_cm->country_abbrev, NBANDS(wlc), wlc->bandlocked); - } else - if (mboolisset(wlc->pub->radio_disabled, - WL_RADIO_COUNTRY_DISABLE)) { - /* country/locale with valid channel, clear the radio disable bit */ + } else if (mboolisset(wlc->pub->radio_disabled, + WL_RADIO_COUNTRY_DISABLE)) { + /* + * country/locale with valid channel, clear + * the radio disable bit + */ mboolclr(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); } - /* Now that the country abbreviation is set, if the radio supports 2G, then - * set channel 14 restrictions based on the new locale. + /* + * Now that the country abbreviation is set, if the radio supports 2G, + * then set channel 14 restrictions based on the new locale. */ - if (NBANDS(wlc) > 1 || BAND_2G(wlc->band->bandtype)) { + if (NBANDS(wlc) > 1 || BAND_2G(wlc->band->bandtype)) wlc_phy_chanspec_ch14_widefilter_set(wlc->band->pi, brcms_c_japan(wlc) ? true : false); - } if (wlc->pub->up && chan != INVCHANNEL) { brcms_c_channel_reg_limits(wlc_cm, wlc->chanspec, &txpwr); @@ -964,15 +981,18 @@ static void brcms_c_channels_commit(struct brcms_cm_info *wlc_cm) } } -/* reset the quiet channels vector to the union of the restricted and radar channel sets */ +/* + * reset the quiet channels vector to the union + * of the restricted and radar channel sets + */ static void brcms_c_quiet_channels_reset(struct brcms_cm_info *wlc_cm) { struct brcms_c_info *wlc = wlc_cm->wlc; uint i, j; struct brcms_band *band; - const chanvec_t *chanvec; + const struct brcms_chanvec *chanvec; - memset(&wlc_cm->quiet_channels, 0, sizeof(chanvec_t)); + memset(&wlc_cm->quiet_channels, 0, sizeof(struct brcms_chanvec)); band = wlc->band; for (i = 0; i < NBANDS(wlc); @@ -980,25 +1000,21 @@ static void brcms_c_quiet_channels_reset(struct brcms_cm_info *wlc_cm) /* initialize quiet channels for restricted channels */ chanvec = wlc_cm->bandstate[band->bandunit].restricted_channels; - for (j = 0; j < sizeof(chanvec_t); j++) + for (j = 0; j < sizeof(struct brcms_chanvec); j++) wlc_cm->quiet_channels.vec[j] |= chanvec->vec[j]; } } static bool -brcms_c_quiet_chanspec(struct brcms_cm_info *wlc_cm, chanspec_t chspec) +brcms_c_quiet_chanspec(struct brcms_cm_info *wlc_cm, u16 chspec) { return N_ENAB(wlc_cm->wlc->pub) && CHSPEC_IS40(chspec) ? - (isset - (wlc_cm->quiet_channels.vec, - LOWER_20_SB(CHSPEC_CHANNEL(chspec))) - || isset(wlc_cm->quiet_channels.vec, - UPPER_20_SB(CHSPEC_CHANNEL(chspec)))) : isset(wlc_cm-> - quiet_channels. - vec, - CHSPEC_CHANNEL - (chspec)); + (isset(wlc_cm->quiet_channels.vec, + LOWER_20_SB(CHSPEC_CHANNEL(chspec))) || + isset(wlc_cm->quiet_channels.vec, + UPPER_20_SB(CHSPEC_CHANNEL(chspec)))) : + isset(wlc_cm->quiet_channels.vec, CHSPEC_CHANNEL(chspec)); } /* Is the channel valid for the current locale? (but don't consider channels not @@ -1039,50 +1055,42 @@ brcms_c_channel_min_txpower_limits_with_local_constraint( int j; /* CCK Rates */ - for (j = 0; j < WL_TX_POWER_CCK_NUM; j++) { + for (j = 0; j < WL_TX_POWER_CCK_NUM; j++) txpwr->cck[j] = min(txpwr->cck[j], local_constraint_qdbm); - } /* 20 MHz Legacy OFDM SISO */ - for (j = 0; j < WL_TX_POWER_OFDM_NUM; j++) { + for (j = 0; j < WL_TX_POWER_OFDM_NUM; j++) txpwr->ofdm[j] = min(txpwr->ofdm[j], local_constraint_qdbm); - } /* 20 MHz Legacy OFDM CDD */ - for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++) { + for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++) txpwr->ofdm_cdd[j] = min(txpwr->ofdm_cdd[j], local_constraint_qdbm); - } /* 40 MHz Legacy OFDM SISO */ - for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++) { + for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++) txpwr->ofdm_40_siso[j] = min(txpwr->ofdm_40_siso[j], local_constraint_qdbm); - } /* 40 MHz Legacy OFDM CDD */ - for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++) { + for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++) txpwr->ofdm_40_cdd[j] = min(txpwr->ofdm_40_cdd[j], local_constraint_qdbm); - } /* 20MHz MCS 0-7 SISO */ - for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) { + for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) txpwr->mcs_20_siso[j] = min(txpwr->mcs_20_siso[j], local_constraint_qdbm); - } /* 20MHz MCS 0-7 CDD */ - for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) { + for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) txpwr->mcs_20_cdd[j] = min(txpwr->mcs_20_cdd[j], local_constraint_qdbm); - } /* 20MHz MCS 0-7 STBC */ - for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) { + for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) txpwr->mcs_20_stbc[j] = min(txpwr->mcs_20_stbc[j], local_constraint_qdbm); - } /* 20MHz MCS 8-15 MIMO */ for (j = 0; j < BRCMS_NUM_RATES_MCS_2_STREAM; j++) @@ -1090,22 +1098,19 @@ brcms_c_channel_min_txpower_limits_with_local_constraint( min(txpwr->mcs_20_mimo[j], local_constraint_qdbm); /* 40MHz MCS 0-7 SISO */ - for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) { + for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) txpwr->mcs_40_siso[j] = min(txpwr->mcs_40_siso[j], local_constraint_qdbm); - } /* 40MHz MCS 0-7 CDD */ - for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) { + for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) txpwr->mcs_40_cdd[j] = min(txpwr->mcs_40_cdd[j], local_constraint_qdbm); - } /* 40MHz MCS 0-7 STBC */ - for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) { + for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) txpwr->mcs_40_stbc[j] = min(txpwr->mcs_40_stbc[j], local_constraint_qdbm); - } /* 40MHz MCS 8-15 MIMO */ for (j = 0; j < BRCMS_NUM_RATES_MCS_2_STREAM; j++) @@ -1118,7 +1123,7 @@ brcms_c_channel_min_txpower_limits_with_local_constraint( } void -brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, chanspec_t chanspec, +brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, u16 chanspec, u8 local_constraint_qdbm) { struct brcms_c_info *wlc = wlc_cm->wlc; @@ -1126,8 +1131,9 @@ brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, chanspec_t chanspec, brcms_c_channel_reg_limits(wlc_cm, chanspec, &txpwr); - brcms_c_channel_min_txpower_limits_with_local_constraint(wlc_cm, &txpwr, - local_constraint_qdbm); + brcms_c_channel_min_txpower_limits_with_local_constraint( + wlc_cm, &txpwr, local_constraint_qdbm + ); brcms_b_set_chanspec(wlc->hw, chanspec, (brcms_c_quiet_chanspec(wlc_cm, chanspec) != 0), @@ -1142,112 +1148,100 @@ static void wlc_phy_txpower_limits_dump(struct txpwr_limits *txpwr) char fraction[4][4] = { " ", ".25", ".5 ", ".75" }; sprintf(buf, "CCK "); - for (i = 0; i < BRCMS_NUM_RATES_CCK; i++) { + for (i = 0; i < BRCMS_NUM_RATES_CCK; i++) sprintf(buf[strlen(buf)], " %2d%s", txpwr->cck[i] / BRCMS_TXPWR_DB_FACTOR, fraction[txpwr->cck[i] % BRCMS_TXPWR_DB_FACTOR]); - } printk(KERN_DEBUG "%s\n", buf); sprintf(buf, "20 MHz OFDM SISO "); - for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) { + for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) sprintf(buf[strlen(buf)], " %2d%s", txpwr->ofdm[i] / BRCMS_TXPWR_DB_FACTOR, fraction[txpwr->ofdm[i] % BRCMS_TXPWR_DB_FACTOR]); - } printk(KERN_DEBUG "%s\n", buf); sprintf(buf, "20 MHz OFDM CDD "); - for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) { + for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) sprintf(buf[strlen(buf)], " %2d%s", txpwr->ofdm_cdd[i] / BRCMS_TXPWR_DB_FACTOR, fraction[txpwr->ofdm_cdd[i] % BRCMS_TXPWR_DB_FACTOR]); - } printk(KERN_DEBUG "%s\n", buf); sprintf(buf, "40 MHz OFDM SISO "); - for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) { + for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) sprintf(buf[strlen(buf)], " %2d%s", txpwr->ofdm_40_siso[i] / BRCMS_TXPWR_DB_FACTOR, fraction[txpwr->ofdm_40_siso[i] % BRCMS_TXPWR_DB_FACTOR]); - } printk(KERN_DEBUG "%s\n", buf); sprintf(buf, "40 MHz OFDM CDD "); - for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) { + for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) sprintf(buf[strlen(buf)], " %2d%s", txpwr->ofdm_40_cdd[i] / BRCMS_TXPWR_DB_FACTOR, fraction[txpwr->ofdm_40_cdd[i] % BRCMS_TXPWR_DB_FACTOR]); - } printk(KERN_DEBUG "%s\n", buf); sprintf(buf, "20 MHz MCS0-7 SISO "); - for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) { + for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) sprintf(buf[strlen(buf)], " %2d%s", txpwr->mcs_20_siso[i] / BRCMS_TXPWR_DB_FACTOR, fraction[txpwr->mcs_20_siso[i] % BRCMS_TXPWR_DB_FACTOR]); - } printk(KERN_DEBUG "%s\n", buf); sprintf(buf, "20 MHz MCS0-7 CDD "); - for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) { + for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) sprintf(buf[strlen(buf)], " %2d%s", txpwr->mcs_20_cdd[i] / BRCMS_TXPWR_DB_FACTOR, fraction[txpwr->mcs_20_cdd[i] % BRCMS_TXPWR_DB_FACTOR]); - } printk(KERN_DEBUG "%s\n", buf); sprintf(buf, "20 MHz MCS0-7 STBC "); - for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) { + for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) sprintf(buf[strlen(buf)], " %2d%s", txpwr->mcs_20_stbc[i] / BRCMS_TXPWR_DB_FACTOR, fraction[txpwr->mcs_20_stbc[i] % BRCMS_TXPWR_DB_FACTOR]); - } printk(KERN_DEBUG "%s\n", buf); sprintf(buf, "20 MHz MCS8-15 SDM "); - for (i = 0; i < BRCMS_NUM_RATES_MCS_2_STREAM; i++) { + for (i = 0; i < BRCMS_NUM_RATES_MCS_2_STREAM; i++) sprintf(buf[strlen(buf)], " %2d%s", txpwr->mcs_20_mimo[i] / BRCMS_TXPWR_DB_FACTOR, fraction[txpwr->mcs_20_mimo[i] % BRCMS_TXPWR_DB_FACTOR]); - } printk(KERN_DEBUG "%s\n", buf); sprintf(buf, "40 MHz MCS0-7 SISO "); - for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) { + for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) sprintf(buf[strlen(buf)], " %2d%s", txpwr->mcs_40_siso[i] / BRCMS_TXPWR_DB_FACTOR, fraction[txpwr->mcs_40_siso[i] % BRCMS_TXPWR_DB_FACTOR]); - } printk(KERN_DEBUG "%s\n", buf); sprintf(buf, "40 MHz MCS0-7 CDD "); - for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) { + for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) sprintf(buf[strlen(buf)], " %2d%s", txpwr->mcs_40_cdd[i] / BRCMS_TXPWR_DB_FACTOR, fraction[txpwr->mcs_40_cdd[i] % BRCMS_TXPWR_DB_FACTOR]); - } printk(KERN_DEBUG "%s\n", buf); sprintf(buf, "40 MHz MCS0-7 STBC "); - for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) { + for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) sprintf(buf[strlen(buf)], " %2d%s", txpwr->mcs_40_stbc[i] / BRCMS_TXPWR_DB_FACTOR, fraction[txpwr->mcs_40_stbc[i] % BRCMS_TXPWR_DB_FACTOR]); - } printk(KERN_DEBUG "%s\n", buf); sprintf(buf, "40 MHz MCS8-15 SDM "); - for (i = 0; i < BRCMS_NUM_RATES_MCS_2_STREAM; i++) { + for (i = 0; i < BRCMS_NUM_RATES_MCS_2_STREAM; i++) sprintf(buf[strlen(buf)], " %2d%s", txpwr->mcs_40_mimo[i] / BRCMS_TXPWR_DB_FACTOR, fraction[txpwr->mcs_40_mimo[i] % @@ -1262,7 +1256,7 @@ static void wlc_phy_txpower_limits_dump(struct txpwr_limits *txpwr) #endif /* POWER_DBG */ void -brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, chanspec_t chanspec, +brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, u16 chanspec, struct txpwr_limits *txpwr) { struct brcms_c_info *wlc = wlc_cm->wlc; @@ -1273,8 +1267,8 @@ brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, chanspec_t chanspec, const struct country_info *country; struct brcms_band *band; const struct locale_info *li; - int conducted_max; - int conducted_ofdm_max; + int conducted_max = BRCMS_TXPWR_MAX; + int conducted_ofdm_max = BRCMS_TXPWR_MAX; const struct locale_mimo_info *li_mimo; int maxpwr20, maxpwr40; int maxpwr_idx; @@ -1326,12 +1320,10 @@ brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, chanspec_t chanspec, } /* OFDM txpwr limits for 2.4G or 5G bands */ - if (BAND_2G(band->bandtype)) { + if (BAND_2G(band->bandtype)) maxpwr = li->maxpwr[CHANNEL_POWER_IDX_2G_OFDM(chan)]; - - } else { + else maxpwr = li->maxpwr[CHANNEL_POWER_IDX_5G(chan)]; - } maxpwr = maxpwr - delta; maxpwr = max(maxpwr, 0); @@ -1345,10 +1337,12 @@ brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, chanspec_t chanspec, txpwr->ofdm[i] = (u8) maxpwr; for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) { - /* OFDM 40 MHz SISO has the same power as the corresponding MCS0-7 rate unless - * overriden by the locale specific code. We set this value to 0 as a - * flag (presumably 0 dBm isn't a possibility) and then copy the MCS0-7 value - * to the 40 MHz value if it wasn't explicitly set. + /* + * OFDM 40 MHz SISO has the same power as the corresponding + * MCS0-7 rate unless overriden by the locale specific code. + * We set this value to 0 as a flag (presumably 0 dBm isn't + * a possibility) and then copy the MCS0-7 value to the 40 MHz + * value if it wasn't explicitly set. */ txpwr->ofdm_40_siso[i] = 0; @@ -1382,8 +1376,9 @@ brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, chanspec_t chanspec, /* Fill in the MCS 0-7 (SISO) rates */ for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) { - /* 20 MHz has the same power as the corresponding OFDM rate unless - * overriden by the locale specific code. + /* + * 20 MHz has the same power as the corresponding OFDM rate + * unless overriden by the locale specific code. */ txpwr->mcs_20_siso[i] = txpwr->ofdm[i]; txpwr->mcs_40_siso[i] = 0; @@ -1395,15 +1390,17 @@ brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, chanspec_t chanspec, txpwr->mcs_40_cdd[i] = (u8) maxpwr40; } - /* These locales have SISO expressed in the table and override CDD later */ + /* + * These locales have SISO expressed in the + * table and override CDD later + */ if (li_mimo == &locale_bn) { if (li_mimo == &locale_bn) { maxpwr20 = QDB(16); maxpwr40 = 0; - if (chan >= 3 && chan <= 11) { + if (chan >= 3 && chan <= 11) maxpwr40 = QDB(16); - } } for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) { @@ -1437,10 +1434,10 @@ brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, chanspec_t chanspec, } } - /* Copy the 40 MHZ MCS 0-7 CDD value to the 40 MHZ MCS 0-7 SISO value if it wasn't - * provided explicitly. + /* + * Copy the 40 MHZ MCS 0-7 CDD value to the 40 MHZ MCS 0-7 SISO + * value if it wasn't provided explicitly. */ - for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) { if (txpwr->mcs_40_siso[i] == 0) txpwr->mcs_40_siso[i] = txpwr->mcs_40_cdd[i]; @@ -1456,8 +1453,9 @@ brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, chanspec_t chanspec, } } - /* Copy the 20 and 40 MHz MCS0-7 CDD values to the corresponding STBC values if they weren't - * provided explicitly. + /* + * Copy the 20 and 40 MHz MCS0-7 CDD values to the corresponding + * STBC values if they weren't provided explicitly. */ for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) { if (txpwr->mcs_20_stbc[i] == 0) @@ -1487,11 +1485,12 @@ static bool brcms_c_japan_ccode(const char *ccode) } /* - * Validate the chanspec for this locale, for 40MHZ we need to also check that the sidebands - * are valid 20MZH channels in this locale and they are also a legal HT combination + * Validate the chanspec for this locale, for 40MHZ we need to also + * check that the sidebands are valid 20MZH channels in this locale + * and they are also a legal HT combination */ static bool -brcms_c_valid_chanspec_ext(struct brcms_cm_info *wlc_cm, chanspec_t chspec, +brcms_c_valid_chanspec_ext(struct brcms_cm_info *wlc_cm, u16 chspec, bool dualband) { struct brcms_c_info *wlc = wlc_cm->wlc; @@ -1516,8 +1515,9 @@ brcms_c_valid_chanspec_ext(struct brcms_cm_info *wlc_cm, chanspec_t chspec, return VALID_CHANNEL20(wlc_cm->wlc, channel); } #ifdef SUPPORT_40MHZ - /* We know we are now checking a 40MHZ channel, so we should only be here - * for NPHYS + /* + * We know we are now checking a 40MHZ channel, so we should + * only be here for NPHYS */ if (BRCMS_ISNPHY(wlc->band) || BRCMS_ISSSLPNPHY(wlc->band)) { u8 upper_sideband = 0, idx; @@ -1553,7 +1553,7 @@ brcms_c_valid_chanspec_ext(struct brcms_cm_info *wlc_cm, chanspec_t chspec, return false; } -bool brcms_c_valid_chanspec_db(struct brcms_cm_info *wlc_cm, chanspec_t chspec) +bool brcms_c_valid_chanspec_db(struct brcms_cm_info *wlc_cm, u16 chspec) { return brcms_c_valid_chanspec_ext(wlc_cm, chspec, true); } diff --git a/drivers/staging/brcm80211/brcmsmac/channel.h b/drivers/staging/brcm80211/brcmsmac/channel.h index d22f2f5..3e85844 100644 --- a/drivers/staging/brcm80211/brcmsmac/channel.h +++ b/drivers/staging/brcm80211/brcmsmac/channel.h @@ -40,12 +40,14 @@ */ /* macro to get 2.4 GHz channel group index for tx power */ -#define CHANNEL_POWER_IDX_2G_CCK(c) (((c) < 2) ? 0 : (((c) < 11) ? 1 : 2)) /* cck index */ -#define CHANNEL_POWER_IDX_2G_OFDM(c) (((c) < 2) ? 3 : (((c) < 11) ? 4 : 5)) /* ofdm index */ +#define CHANNEL_POWER_IDX_2G_CCK(c) (((c) < 2) ? 0 : (((c) < 11) ? 1 : 2)) +#define CHANNEL_POWER_IDX_2G_OFDM(c) (((c) < 2) ? 3 : (((c) < 11) ? 4 : 5)) /* macro to get 5 GHz channel group index for tx power */ -#define CHANNEL_POWER_IDX_5G(c) \ - (((c) < 52) ? 0 : (((c) < 62) ? 1 : (((c) < 100) ? 2 : (((c) < 149) ? 3 : 4)))) +#define CHANNEL_POWER_IDX_5G(c) (((c) < 52) ? 0 : \ + (((c) < 62) ? 1 : \ + (((c) < 100) ? 2 : \ + (((c) < 149) ? 3 : 4)))) /* max of BAND_5G_PWR_LVLS and 6 for 2.4 GHz */ #define BRCMS_MAXPWR_TBL_SIZE 6 @@ -67,9 +69,8 @@ struct locale_info { 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 - */ + /* Country IE advertised max tx pwr in dBm per sub-band */ + s8 pub_maxpwr[BAND_5G_PWR_LVLS]; u8 flags; }; @@ -98,8 +99,8 @@ struct locale_mimo_info { u8 flags; }; -extern const chanvec_t chanvec_all_2G; -extern const chanvec_t chanvec_all_5G; +extern const struct brcms_chanvec chanvec_all_2G; +extern const struct brcms_chanvec chanvec_all_5G; /* * Country names and abbreviations with locale defined from ISO 3166 @@ -120,13 +121,13 @@ extern u8 brcms_c_channel_locale_flags_in_band(struct brcms_cm_info *wlc_cm, uint bandunit); extern bool brcms_c_valid_chanspec_db(struct brcms_cm_info *wlc_cm, - chanspec_t chspec); + u16 chspec); extern void brcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, - chanspec_t chanspec, + u16 chanspec, struct txpwr_limits *txpwr); extern void brcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, - chanspec_t chanspec, + u16 chanspec, u8 local_constraint_qdbm); #endif /* _WLC_CHANNEL_H */ diff --git a/drivers/staging/brcm80211/brcmsmac/d11.h b/drivers/staging/brcm80211/brcmsmac/d11.h index e7ff0e6..f0c3f5a 100644 --- a/drivers/staging/brcm80211/brcmsmac/d11.h +++ b/drivers/staging/brcm80211/brcmsmac/d11.h @@ -29,11 +29,11 @@ #define RX_FIFO 0 /* data and ctl frames */ #define RX_TXSTATUS_FIFO 3 /* RX fifo for tx status packages */ -/* TX FIFO numbers using WME Access Classes */ -#define TX_AC_BK_FIFO 0 /* Access Category Background TX FIFO */ -#define TX_AC_BE_FIFO 1 /* Access Category Best-Effort TX FIFO */ -#define TX_AC_VI_FIFO 2 /* Access Class Video TX FIFO */ -#define TX_AC_VO_FIFO 3 /* Access Class Voice TX FIFO */ +/* TX FIFO numbers using WME Access Category */ +#define TX_AC_BK_FIFO 0 /* Background TX FIFO */ +#define TX_AC_BE_FIFO 1 /* Best-Effort TX FIFO */ +#define TX_AC_VI_FIFO 2 /* Video TX FIFO */ +#define TX_AC_VO_FIFO 3 /* Voice TX FIFO */ #define TX_BCMC_FIFO 4 /* Broadcast/Multicast TX FIFO */ #define TX_ATIM_FIFO 5 /* TX fifo for ATIM window info */ @@ -47,11 +47,7 @@ #define TX_DATA_FIFO TX_AC_BE_FIFO #define TX_CTL_FIFO TX_AC_VO_FIFO -#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; @@ -73,8 +69,8 @@ struct pio2regs { /* a pair of pio channels(tx and rx) */ struct pio2regp { - pio2regs_t tx; - pio2regs_t rx; + struct pio2regs tx; + struct pio2regs rx; }; /* 4byte-wide pio register set per channel(xmt or rcv) */ @@ -85,8 +81,8 @@ struct pio4regs { /* a pair of pio channels(tx and rx) */ struct pio4regp { - pio4regs_t tx; - pio4regs_t rx; + struct pio4regs tx; + struct pio4regs rx; }; /* read: 32-bit register that can be read as 32-bit or as 2 16-bit @@ -101,10 +97,10 @@ union pmqreg { }; struct fifo64 { - dma64regs_t dmaxmt; /* dma tx */ - pio4regs_t piotx; /* pio tx */ - dma64regs_t dmarcv; /* dma rx */ - pio4regs_t piorx; /* pio rx */ + struct dma64regs dmaxmt; /* dma tx */ + struct pio4regs piotx; /* pio tx */ + struct dma64regs dmarcv; /* dma rx */ + struct pio4regs piorx; /* pio rx */ }; /* @@ -120,7 +116,7 @@ struct d11regs { u32 usectimer; /* 0x1c *//* for corerev >= 26 */ /* Interrupt Control *//* 0x20 */ - intctrlregs_t intctrlregs[8]; + struct intctrlregs intctrlregs[8]; u32 PAD[40]; /* 0x60 - 0xFC */ @@ -139,7 +135,7 @@ struct d11regs { u32 PAD[2]; /* 0x138 - 0x13C */ /* PMQ registers */ - pmqreg_t pmqreg; /* 0x140 */ + union pmqreg pmqreg; /* 0x140 */ u32 pmqpatl; /* 0x144 */ u32 pmqpath; /* 0x148 */ u32 PAD; /* 0x14C */ @@ -179,10 +175,10 @@ struct d11regs { u32 PAD[5]; /* 0x1ec - 0x1fc */ /* 0x200-0x37F dma/pio registers */ - fifo64_t fifo64regs[6]; + struct fifo64 fifo64regs[6]; /* FIFO diagnostic port access */ - dma32diag_t dmafifo; /* 0x380 - 0x38C */ + struct dma32diag dmafifo; /* 0x380 - 0x38C */ u32 aggfifocnt; /* 0x390 */ u32 aggfifodata; /* 0x394 */ @@ -457,7 +453,7 @@ struct d11regs { #define IRL_FC_MASK 0xff000000 /* frame count */ #define IRL_FC_SHIFT 24 /* frame count */ -/* maccontrol register */ +/*== maccontrol register ==*/ #define MCTL_GMODE (1U << 31) #define MCTL_DISCARD_PMQ (1 << 30) #define MCTL_WAKE (1 << 26) @@ -481,75 +477,119 @@ struct d11regs { #define MCTL_PSM_RUN (1 << 1) #define MCTL_EN_MAC (1 << 0) -/* maccommand register */ +/*== maccommand register ==*/ #define MCMD_BCN0VLD (1 << 0) #define MCMD_BCN1VLD (1 << 1) #define MCMD_DIRFRMQVAL (1 << 2) #define MCMD_CCA (1 << 3) #define MCMD_BG_NOISE (1 << 4) #define MCMD_SKIP_SHMINIT (1 << 5) /* only used for simulation */ -#define MCMD_SAMPLECOLL MCMD_SKIP_SHMINIT /* reuse for sample collect */ - -/* macintstatus/macintmask */ -#define MI_MACSSPNDD (1 << 0) /* MAC has gracefully suspended */ -#define MI_BCNTPL (1 << 1) /* beacon template available */ -#define MI_TBTT (1 << 2) /* TBTT indication */ -#define MI_BCNSUCCESS (1 << 3) /* beacon successfully tx'd */ -#define MI_BCNCANCLD (1 << 4) /* beacon canceled (IBSS) */ -#define MI_ATIMWINEND (1 << 5) /* end of ATIM-window (IBSS) */ -#define MI_PMQ (1 << 6) /* PMQ entries available */ -#define MI_NSPECGEN_0 (1 << 7) /* non-specific gen-stat bits that are set by PSM */ -#define MI_NSPECGEN_1 (1 << 8) /* non-specific gen-stat bits that are set by PSM */ -#define MI_MACTXERR (1 << 9) /* MAC level Tx error */ -#define MI_NSPECGEN_3 (1 << 10) /* non-specific gen-stat bits that are set by PSM */ -#define MI_PHYTXERR (1 << 11) /* PHY Tx error */ -#define MI_PME (1 << 12) /* Power Management Event */ -#define MI_GP0 (1 << 13) /* General-purpose timer0 */ -#define MI_GP1 (1 << 14) /* General-purpose timer1 */ -#define MI_DMAINT (1 << 15) /* (ORed) DMA-interrupts */ -#define MI_TXSTOP (1 << 16) /* MAC has completed a TX FIFO Suspend/Flush */ -#define MI_CCA (1 << 17) /* MAC has completed a CCA measurement */ -#define MI_BG_NOISE (1 << 18) /* MAC has collected background noise samples */ -#define MI_DTIM_TBTT (1 << 19) /* MBSS DTIM TBTT indication */ -#define MI_PRQ (1 << 20) /* Probe response queue needs attention */ -#define MI_PWRUP (1 << 21) /* Radio/PHY has been powered back up. */ +#define MCMD_SAMPLECOLL MCMD_SKIP_SHMINIT /* reuse for sample collect */ + +/*== macintstatus/macintmask ==*/ +/* gracefully suspended */ +#define MI_MACSSPNDD (1 << 0) +/* beacon template available */ +#define MI_BCNTPL (1 << 1) +/* TBTT indication */ +#define MI_TBTT (1 << 2) +/* beacon successfully tx'd */ +#define MI_BCNSUCCESS (1 << 3) +/* beacon canceled (IBSS) */ +#define MI_BCNCANCLD (1 << 4) +/* end of ATIM-window (IBSS) */ +#define MI_ATIMWINEND (1 << 5) +/* PMQ entries available */ +#define MI_PMQ (1 << 6) +/* non-specific gen-stat bits that are set by PSM */ +#define MI_NSPECGEN_0 (1 << 7) +/* non-specific gen-stat bits that are set by PSM */ +#define MI_NSPECGEN_1 (1 << 8) +/* MAC level Tx error */ +#define MI_MACTXERR (1 << 9) +/* non-specific gen-stat bits that are set by PSM */ +#define MI_NSPECGEN_3 (1 << 10) +/* PHY Tx error */ +#define MI_PHYTXERR (1 << 11) +/* Power Management Event */ +#define MI_PME (1 << 12) +/* General-purpose timer0 */ +#define MI_GP0 (1 << 13) +/* General-purpose timer1 */ +#define MI_GP1 (1 << 14) +/* (ORed) DMA-interrupts */ +#define MI_DMAINT (1 << 15) +/* MAC has completed a TX FIFO Suspend/Flush */ +#define MI_TXSTOP (1 << 16) +/* MAC has completed a CCA measurement */ +#define MI_CCA (1 << 17) +/* MAC has collected background noise samples */ +#define MI_BG_NOISE (1 << 18) +/* MBSS DTIM TBTT indication */ +#define MI_DTIM_TBTT (1 << 19) +/* Probe response queue needs attention */ +#define MI_PRQ (1 << 20) +/* Radio/PHY has been powered back up. */ +#define MI_PWRUP (1 << 21) #define MI_RESERVED3 (1 << 22) #define MI_RESERVED2 (1 << 23) #define MI_RESERVED1 (1 << 25) /* MAC detected change on RF Disable input*/ #define MI_RFDISABLE (1 << 28) -#define MI_TFS (1 << 29) /* MAC has completed a TX */ -#define MI_PHYCHANGED (1 << 30) /* A phy status change wrt G mode */ -#define MI_TO (1U << 31) /* general purpose timeout */ +/* MAC has completed a TX */ +#define MI_TFS (1 << 29) +/* A phy status change wrt G mode */ +#define MI_PHYCHANGED (1 << 30) +/* general purpose timeout */ +#define MI_TO (1U << 31) /* Mac capabilities registers */ -/* machwcap */ +/*== machwcap ==*/ #define MCAP_TKIPMIC 0x80000000 /* TKIP MIC hardware present */ -/* pmqhost data */ -#define PMQH_DATA_MASK 0xffff0000 /* data entry of head pmq entry */ -#define PMQH_BSSCFG 0x00100000 /* PM entry for BSS config */ -#define PMQH_PMOFF 0x00010000 /* PM Mode OFF: power save off */ -#define PMQH_PMON 0x00020000 /* PM Mode ON: power save on */ -#define PMQH_DASAT 0x00040000 /* Dis-associated or De-authenticated */ -#define PMQH_ATIMFAIL 0x00080000 /* ATIM not acknowledged */ -#define PMQH_DEL_ENTRY 0x00000001 /* delete head entry */ -#define PMQH_DEL_MULT 0x00000002 /* delete head entry to cur read pointer -1 */ -#define PMQH_OFLO 0x00000004 /* pmq overflow indication */ -#define PMQH_NOT_EMPTY 0x00000008 /* entries are present in pmq */ - -/* phydebug */ -#define PDBG_CRS (1 << 0) /* phy is asserting carrier sense */ -#define PDBG_TXA (1 << 1) /* phy is taking xmit byte from mac this cycle */ -#define PDBG_TXF (1 << 2) /* mac is instructing the phy to transmit a frame */ -#define PDBG_TXE (1 << 3) /* phy is signalling a transmit Error to the mac */ -#define PDBG_RXF (1 << 4) /* phy detected the end of a valid frame preamble */ -#define PDBG_RXS (1 << 5) /* phy detected the end of a valid PLCP header */ -#define PDBG_RXFRG (1 << 6) /* rx start not asserted */ -#define PDBG_RXV (1 << 7) /* mac is taking receive byte from phy this cycle */ -#define PDBG_RFD (1 << 16) /* RF portion of the radio is disabled */ - -/* objaddr register */ +/*== pmqhost data ==*/ +/* data entry of head pmq entry */ +#define PMQH_DATA_MASK 0xffff0000 +/* PM entry for BSS config */ +#define PMQH_BSSCFG 0x00100000 +/* PM Mode OFF: power save off */ +#define PMQH_PMOFF 0x00010000 +/* PM Mode ON: power save on */ +#define PMQH_PMON 0x00020000 +/* Dis-associated or De-authenticated */ +#define PMQH_DASAT 0x00040000 +/* ATIM not acknowledged */ +#define PMQH_ATIMFAIL 0x00080000 +/* delete head entry */ +#define PMQH_DEL_ENTRY 0x00000001 +/* delete head entry to cur read pointer -1 */ +#define PMQH_DEL_MULT 0x00000002 +/* pmq overflow indication */ +#define PMQH_OFLO 0x00000004 +/* entries are present in pmq */ +#define PMQH_NOT_EMPTY 0x00000008 + +/*== phydebug ==*/ +/* phy is asserting carrier sense */ +#define PDBG_CRS (1 << 0) +/* phy is taking xmit byte from mac this cycle */ +#define PDBG_TXA (1 << 1) +/* mac is instructing the phy to transmit a frame */ +#define PDBG_TXF (1 << 2) +/* phy is signalling a transmit Error to the mac */ +#define PDBG_TXE (1 << 3) +/* phy detected the end of a valid frame preamble */ +#define PDBG_RXF (1 << 4) +/* phy detected the end of a valid PLCP header */ +#define PDBG_RXS (1 << 5) +/* rx start not asserted */ +#define PDBG_RXFRG (1 << 6) +/* mac is taking receive byte from phy this cycle */ +#define PDBG_RXV (1 << 7) +/* RF portion of the radio is disabled */ +#define PDBG_RFD (1 << 16) + +/*== objaddr register ==*/ #define OBJADDR_SEL_MASK 0x000F0000 #define OBJADDR_UCM_SEL 0x00000000 #define OBJADDR_SHM_SEL 0x00010000 @@ -564,20 +604,20 @@ struct d11regs { #define WEP_PCMADDR 0x07d4 #define WEP_PCMDATA 0x07d6 -/* frmtxstatus */ +/*== frmtxstatus ==*/ #define TXS_V (1 << 0) /* valid bit */ #define TXS_STATUS_MASK 0xffff #define TXS_FID_MASK 0xffff0000 #define TXS_FID_SHIFT 16 -/* frmtxstatus2 */ +/*== frmtxstatus2 ==*/ #define TXS_SEQ_MASK 0xffff #define TXS_PTX_MASK 0xff0000 #define TXS_PTX_SHIFT 16 #define TXS_MU_MASK 0x01000000 #define TXS_MU_SHIFT 24 -/* clk_ctl_st */ +/*== clk_ctl_st ==*/ #define CCS_ERSRC_REQ_D11PLL 0x00000100 /* d11 core pll request */ #define CCS_ERSRC_REQ_PHYPLL 0x00000200 /* PHY pll request */ #define CCS_ERSRC_AVAIL_D11PLL 0x01000000 /* d11 core pll available */ @@ -602,22 +642,27 @@ struct d11regs { #define TXFIFO_SIZE_UNIT 256 /* one unit corresponds to 256 bytes */ #define MBSS16_TEMPLMEM_MINBLKS 65 /* one unit corresponds to 256 bytes */ -/* phy versions, PhyVersion:Revision field */ -#define PV_AV_MASK 0xf000 /* analog block version */ -#define PV_AV_SHIFT 12 /* analog block version bitfield offset */ -#define PV_PT_MASK 0x0f00 /* phy type */ -#define PV_PT_SHIFT 8 /* phy type bitfield offset */ -#define PV_PV_MASK 0x000f /* phy version */ +/*== phy versions (PhyVersion:Revision field) ==*/ +/* analog block version */ +#define PV_AV_MASK 0xf000 +/* analog block version bitfield offset */ +#define PV_AV_SHIFT 12 +/* phy type */ +#define PV_PT_MASK 0x0f00 +/* phy type bitfield offset */ +#define PV_PT_SHIFT 8 +/* phy version */ +#define PV_PV_MASK 0x000f #define PHY_TYPE(v) ((v & PV_PT_MASK) >> PV_PT_SHIFT) -/* phy types, PhyVersion:PhyType field */ +/*== phy types (PhyVersion:PhyType field) ==*/ #define PHY_TYPE_N 4 /* N-Phy value */ #define PHY_TYPE_SSN 6 /* SSLPN-Phy value */ #define PHY_TYPE_LCN 8 /* LCN-Phy value */ #define PHY_TYPE_LCNXN 9 /* LCNXN-Phy value */ #define PHY_TYPE_NULL 0xf /* Invalid Phy value */ -/* analog types, PhyVersion:AnalogType field */ +/*== analog types (PhyVersion:AnalogType field) ==*/ #define ANA_11N_013 5 /* 802.11a PLCP header def */ @@ -693,9 +738,10 @@ struct cck_phy_hdr { #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 - * padding added in the ucode. +/* + * 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 padding added in the ucode. */ #define D11_PHY_HDR_LEN 6 @@ -745,14 +791,17 @@ struct d11txh { #define FT_HT 2 #define FT_N 3 -/* Position of MPDU inside A-MPDU; indicated with bits 10:9 of MacTxControlLow */ +/* + * Position of MPDU inside A-MPDU; indicated with bits 10:9 + * of MacTxControlLow + */ #define TXC_AMPDU_SHIFT 9 /* shift for ampdu settings */ #define TXC_AMPDU_NONE 0 /* Regular MPDU, not an A-MPDU */ #define TXC_AMPDU_FIRST 1 /* first MPDU of an A-MPDU */ #define TXC_AMPDU_MIDDLE 2 /* intermediate MPDU of an A-MPDU */ #define TXC_AMPDU_LAST 3 /* last (or single) MPDU of an A-MPDU */ -/* MacTxControlLow */ +/*== MacTxControlLow ==*/ #define TXC_AMIC 0x8000 #define TXC_SENDCTS 0x0800 #define TXC_AMPDU_MASK 0x0600 @@ -766,18 +815,25 @@ struct d11txh { #define TXC_LONGFRAME 0x0002 #define TXC_IMMEDACK 0x0001 -/* MacTxControlHigh */ -#define TXC_PREAMBLE_RTS_FB_SHORT 0x8000 /* RTS fallback preamble type 1 = SHORT 0 = LONG */ -#define TXC_PREAMBLE_RTS_MAIN_SHORT 0x4000 /* RTS main rate preamble type 1 = SHORT 0 = LONG */ -#define TXC_PREAMBLE_DATA_FB_SHORT 0x2000 /* Main fallback rate preamble type - * 1 = SHORT for OFDM/GF for MIMO - * 0 = LONG for CCK/MM for MIMO - */ +/*== MacTxControlHigh ==*/ +/* RTS fallback preamble type 1 = SHORT 0 = LONG */ +#define TXC_PREAMBLE_RTS_FB_SHORT 0x8000 +/* RTS main rate preamble type 1 = SHORT 0 = LONG */ +#define TXC_PREAMBLE_RTS_MAIN_SHORT 0x4000 +/* + * Main fallback rate preamble type + * 1 = SHORT for OFDM/GF for MIMO + * 0 = LONG for CCK/MM for MIMO + */ +#define TXC_PREAMBLE_DATA_FB_SHORT 0x2000 + /* TXC_PREAMBLE_DATA_MAIN is in PhyTxControl bit 5 */ -#define TXC_AMPDU_FBR 0x1000 /* use fallback rate for this AMPDU */ +/* use fallback rate for this AMPDU */ +#define TXC_AMPDU_FBR 0x1000 #define TXC_SECKEY_MASK 0x0FF0 #define TXC_SECKEY_SHIFT 4 -#define TXC_ALT_TXPWR 0x0008 /* Use alternate txpwr defined at loc. M_ALT_TXPWR_IDX */ +/* Use alternate txpwr defined at loc. M_ALT_TXPWR_IDX */ +#define TXC_ALT_TXPWR 0x0008 #define TXC_SECTYPE_MASK 0x0007 #define TXC_SECTYPE_SHIFT 0 @@ -817,7 +873,7 @@ struct d11txh { #define PHY_TXC1_MODE_SDM 3 /* PhyTxControl for HTphy that are different from Mimophy */ -#define PHY_TXC_HTANT_MASK 0x3fC0 /* bit 6, 7, 8, 9, 10, 11, 12, 13 */ +#define PHY_TXC_HTANT_MASK 0x3fC0 /* bits 6-13 */ /* XtraFrameTypes */ #define XFTS_RTS_FT_SHIFT 2 @@ -862,23 +918,23 @@ struct tx_status { #define TX_STATUS_RTS_RTX_MASK 0x0F00 #define TX_STATUS_RTS_RTX_SHIFT 8 #define TX_STATUS_MASK 0x00FE -#define TX_STATUS_PMINDCTD (1 << 7) /* PM mode indicated to AP */ -#define TX_STATUS_INTERMEDIATE (1 << 6) /* intermediate or 1st ampdu pkg */ -#define TX_STATUS_AMPDU (1 << 5) /* AMPDU status */ -#define TX_STATUS_SUPR_MASK 0x1C /* suppress status bits (4:2) */ +#define TX_STATUS_PMINDCTD (1 << 7) /* PM mode indicated to AP */ +#define TX_STATUS_INTERMEDIATE (1 << 6) /* intermediate or 1st ampdu pkg */ +#define TX_STATUS_AMPDU (1 << 5) /* AMPDU status */ +#define TX_STATUS_SUPR_MASK 0x1C /* suppress status bits (4:2) */ #define TX_STATUS_SUPR_SHIFT 2 -#define TX_STATUS_ACK_RCV (1 << 1) /* ACK received */ -#define TX_STATUS_VALID (1 << 0) /* Tx status valid */ +#define TX_STATUS_ACK_RCV (1 << 1) /* ACK received */ +#define TX_STATUS_VALID (1 << 0) /* Tx status valid */ #define TX_STATUS_NO_ACK 0 /* suppress status reason codes */ -#define TX_STATUS_SUPR_PMQ (1 << 2) /* PMQ entry */ -#define TX_STATUS_SUPR_FLUSH (2 << 2) /* flush request */ -#define TX_STATUS_SUPR_FRAG (3 << 2) /* previous frag failure */ -#define TX_STATUS_SUPR_TBTT (3 << 2) /* SHARED: Probe response supr for TBTT */ -#define TX_STATUS_SUPR_BADCH (4 << 2) /* channel mismatch */ -#define TX_STATUS_SUPR_EXPTIME (5 << 2) /* lifetime expiry */ -#define TX_STATUS_SUPR_UF (6 << 2) /* underflow */ +#define TX_STATUS_SUPR_PMQ (1 << 2) /* PMQ entry */ +#define TX_STATUS_SUPR_FLUSH (2 << 2) /* flush request */ +#define TX_STATUS_SUPR_FRAG (3 << 2) /* previous frag failure */ +#define TX_STATUS_SUPR_TBTT (3 << 2) /* SHARED: Probe resp supr for TBTT */ +#define TX_STATUS_SUPR_BADCH (4 << 2) /* channel mismatch */ +#define TX_STATUS_SUPR_EXPTIME (5 << 2) /* lifetime expiry */ +#define TX_STATUS_SUPR_UF (6 << 2) /* underflow */ /* Unexpected tx status for rate update */ #define TX_STATUS_UNEXP(status) \ @@ -939,8 +995,8 @@ struct tx_status { #define ADDR_BMP_RA (1 << 0) /* Receiver Address (RA) */ #define ADDR_BMP_TA (1 << 1) /* Transmitter Address (TA) */ #define ADDR_BMP_BSSID (1 << 2) /* BSSID */ -#define ADDR_BMP_AP (1 << 3) /* Infra-BSS Access Point (AP) */ -#define ADDR_BMP_STA (1 << 4) /* Infra-BSS Station (STA) */ +#define ADDR_BMP_AP (1 << 3) /* Infra-BSS Access Point */ +#define ADDR_BMP_STA (1 << 4) /* Infra-BSS Station */ #define ADDR_BMP_RESERVED1 (1 << 5) #define ADDR_BMP_RESERVED2 (1 << 6) #define ADDR_BMP_RESERVED3 (1 << 7) @@ -1012,9 +1068,10 @@ struct tx_status { #define T_BCN0_TPL_BASE (0x34 * 2) #define T_PRS_TPL_BASE (0x134 * 2) #define T_BCN1_TPL_BASE (0x234 * 2) -#define T_TX_FIFO_TXRAM_BASE (T_ACTS_TPL_BASE + (TXFIFO_START_BLK * TXFIFO_SIZE_UNIT)) +#define T_TX_FIFO_TXRAM_BASE (T_ACTS_TPL_BASE + \ + (TXFIFO_START_BLK * TXFIFO_SIZE_UNIT)) -#define T_BA_TPL_BASE T_QNULL_TPL_BASE /* template area for BA */ +#define T_BA_TPL_BASE T_QNULL_TPL_BASE /* template area for BA */ #define T_RAM_ACCESS_SZ 4 /* template ram is 4 byte access only */ @@ -1207,14 +1264,18 @@ struct tx_status { #define WATCHDOG_8TU_MAX 10 /* Manufacturing Test Variables */ -#define M_PKTENG_CTRL (0x6c * 2) /* PER test mode */ -#define M_PKTENG_IFS (0x6d * 2) /* IFS for TX mode */ -#define M_PKTENG_FRMCNT_LO (0x6e * 2) /* Lower word of tx frmcnt/rx lostcnt */ -#define M_PKTENG_FRMCNT_HI (0x6f * 2) /* Upper word of tx frmcnt/rx lostcnt */ +/* PER test mode */ +#define M_PKTENG_CTRL (0x6c * 2) +/* IFS for TX mode */ +#define M_PKTENG_IFS (0x6d * 2) +/* Lower word of tx frmcnt/rx lostcnt */ +#define M_PKTENG_FRMCNT_LO (0x6e * 2) +/* Upper word of tx frmcnt/rx lostcnt */ +#define M_PKTENG_FRMCNT_HI (0x6f * 2) /* Index variation in vbat ripple */ -#define M_LCN_PWR_IDX_MAX (0x67 * 2) /* highest index read by ucode */ -#define M_LCN_PWR_IDX_MIN (0x66 * 2) /* lowest index read by ucode */ +#define M_LCN_PWR_IDX_MAX (0x67 * 2) /* highest index read by ucode */ +#define M_LCN_PWR_IDX_MIN (0x66 * 2) /* lowest index read by ucode */ /* M_PKTENG_CTRL bit definitions */ #define M_PKTENG_MODE_TX 0x0001 @@ -1223,11 +1284,14 @@ struct tx_status { #define M_PKTENG_MODE_RX 0x0002 #define M_PKTENG_MODE_RX_WITH_ACK 0x0402 #define M_PKTENG_MODE_MASK 0x0003 -#define M_PKTENG_FRMCNT_VLD 0x0100 /* TX frames indicated in the frmcnt reg */ +/* TX frames indicated in the frmcnt reg */ +#define M_PKTENG_FRMCNT_VLD 0x0100 /* Sample Collect parameters (bitmap and type) */ -#define M_SMPL_COL_BMP (0x37d * 2) /* Trigger bitmap for sample collect */ -#define M_SMPL_COL_CTL (0x3b2 * 2) /* Sample collect type */ +/* Trigger bitmap for sample collect */ +#define M_SMPL_COL_BMP (0x37d * 2) +/* Sample collect type */ +#define M_SMPL_COL_CTL (0x3b2 * 2) #define ANTSEL_CLKDIV_4MHZ 6 #define MIMO_ANTSEL_BUSY 0x4000 /* bit 14 (busy) */ @@ -1259,27 +1323,37 @@ struct shm_acparams { #define MHF5 4 /* Hostflag 5 index */ /* Flags in M_HOST_FLAGS */ -#define MHF1_ANTDIV 0x0001 /* Enable ucode antenna diversity help */ -#define MHF1_EDCF 0x0100 /* Enable EDCF access control */ +/* Enable ucode antenna diversity help */ +#define MHF1_ANTDIV 0x0001 +/* Enable EDCF access control */ +#define MHF1_EDCF 0x0100 #define MHF1_IQSWAP_WAR 0x0200 -#define MHF1_FORCEFASTCLK 0x0400 /* Disable Slow clock request, for corerev < 11 */ +/* Disable Slow clock request, for corerev < 11 */ +#define MHF1_FORCEFASTCLK 0x0400 /* Flags in M_HOST_FLAGS2 */ -#define MHF2_PCISLOWCLKWAR 0x0008 /* PR16165WAR : Enable ucode PCI slow clock WAR */ -#define MHF2_TXBCMC_NOW 0x0040 /* Flush BCMC FIFO immediately */ -#define MHF2_HWPWRCTL 0x0080 /* Enable ucode/hw power control */ +/* PR16165WAR : Enable ucode PCI slow clock WAR */ +#define MHF2_PCISLOWCLKWAR 0x0008 +/* Flush BCMC FIFO immediately */ +#define MHF2_TXBCMC_NOW 0x0040 +/* Enable ucode/hw power control */ +#define MHF2_HWPWRCTL 0x0080 #define MHF2_NPHY40MHZ_WAR 0x0800 /* Flags in M_HOST_FLAGS3 */ -#define MHF3_ANTSEL_EN 0x0001 /* enabled mimo antenna selection */ -#define MHF3_ANTSEL_MODE 0x0002 /* antenna selection mode: 0: 2x3, 1: 2x4 */ +/* enabled mimo antenna selection */ +#define MHF3_ANTSEL_EN 0x0001 +/* antenna selection mode: 0: 2x3, 1: 2x4 */ +#define MHF3_ANTSEL_MODE 0x0002 #define MHF3_RESERVED1 0x0004 #define MHF3_RESERVED2 0x0008 #define MHF3_NPHY_MLADV_WAR 0x0010 /* 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 */ +/* force bphy Tx on core 0 (board level WAR) */ +#define MHF4_BPHY_TXCORE0 0x0080 +/* for 4313A0 FEM boards */ +#define MHF4_EXTPA_ENABLE 0x4000 /* Flags in M_HOST_FLAGS5 */ #define MHF5_4313_GPIOCTRL 0x0001 @@ -1292,52 +1366,87 @@ struct shm_acparams { #define M_PHY_NOISE (0x037 * 2) #define PHY_NOISE_MASK 0x00ff -/* Receive Frame Data Header for 802.11b DCF-only frames */ +/* + * Receive Frame Data Header for 802.11b DCF-only frames + * + * RxFrameSize: Actual byte length of the frame data received + * PAD: padding (not used) + * PhyRxStatus_0: PhyRxStatus 15:0 + * PhyRxStatus_1: PhyRxStatus 31:16 + * PhyRxStatus_2: PhyRxStatus 47:32 + * PhyRxStatus_3: PhyRxStatus 63:48 + * PhyRxStatus_4: PhyRxStatus 79:64 + * PhyRxStatus_5: PhyRxStatus 95:80 + * RxStatus1: MAC Rx Status + * RxStatus2: extended MAC Rx status + * RxTSFTime: RxTSFTime time of first MAC symbol + M_PHY_PLCPRX_DLY + * RxChan: gain code, channel radio code, and phy type + */ struct d11rxhdr { - u16 RxFrameSize; /* Actual byte length of the frame data received */ + u16 RxFrameSize; u16 PAD; - u16 PhyRxStatus_0; /* PhyRxStatus 15:0 */ - u16 PhyRxStatus_1; /* PhyRxStatus 31:16 */ - u16 PhyRxStatus_2; /* PhyRxStatus 47:32 */ - u16 PhyRxStatus_3; /* PhyRxStatus 63:48 */ - u16 PhyRxStatus_4; /* PhyRxStatus 79:64 */ - u16 PhyRxStatus_5; /* PhyRxStatus 95:80 */ - u16 RxStatus1; /* MAC Rx Status */ - 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 */ + u16 PhyRxStatus_0; + u16 PhyRxStatus_1; + u16 PhyRxStatus_2; + u16 PhyRxStatus_3; + u16 PhyRxStatus_4; + u16 PhyRxStatus_5; + u16 RxStatus1; + u16 RxStatus2; + u16 RxTSFTime; + u16 RxChan; } __packed; #define RXHDR_LEN 24 /* sizeof struct d11rxhdr */ #define FRAMELEN(h) ((h)->RxFrameSize) +/* + * rxhdr: received frame header data + * tsf_l: TSF_L reading + * rssi: computed instanteneous rssi in BMAC + * rxpwr0: obsoleted, place holder for legacy ROM code. use rxpwr[] + * rxpwr1: obsoleted, place holder for legacy ROM code. use rxpwr[] + * do_rssi_ma: do per-pkt sampling for per-antenna ma in HIGH + * rxpwr: rssi for supported antennas + */ 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 */ + u32 tsf_l; + s8 rssi; + s8 rxpwr0; + s8 rxpwr1; + s8 do_rssi_ma; + s8 rxpwr[WL_RSSI_ANT_MAX]; } __packed; /* PhyRxStatus_0: */ -#define PRXS0_FT_MASK 0x0003 /* NPHY only: CCK, OFDM, preN, N */ -#define PRXS0_CLIP_MASK 0x000C /* NPHY only: clip count adjustment steps by AGC */ +/* NPHY only: CCK, OFDM, preN, N */ +#define PRXS0_FT_MASK 0x0003 +/* NPHY only: clip count adjustment steps by AGC */ +#define PRXS0_CLIP_MASK 0x000C #define PRXS0_CLIP_SHIFT 2 -#define PRXS0_UNSRATE 0x0010 /* PHY received a frame with unsupported rate */ -#define PRXS0_RXANT_UPSUBBAND 0x0020 /* GPHY: rx ant, NPHY: upper sideband */ -#define PRXS0_LCRS 0x0040 /* CCK frame only: lost crs during cck frame reception */ -#define PRXS0_SHORTH 0x0080 /* Short Preamble */ -#define PRXS0_PLCPFV 0x0100 /* PLCP violation */ -#define PRXS0_PLCPHCF 0x0200 /* PLCP header integrity check failed */ -#define PRXS0_GAIN_CTL 0x4000 /* legacy PHY gain control */ -#define PRXS0_ANTSEL_MASK 0xF000 /* NPHY: Antennas used for received frame, bitmask */ +/* PHY received a frame with unsupported rate */ +#define PRXS0_UNSRATE 0x0010 +/* GPHY: rx ant, NPHY: upper sideband */ +#define PRXS0_RXANT_UPSUBBAND 0x0020 +/* CCK frame only: lost crs during cck frame reception */ +#define PRXS0_LCRS 0x0040 +/* Short Preamble */ +#define PRXS0_SHORTH 0x0080 +/* PLCP violation */ +#define PRXS0_PLCPFV 0x0100 +/* PLCP header integrity check failed */ +#define PRXS0_PLCPHCF 0x0200 +/* legacy PHY gain control */ +#define PRXS0_GAIN_CTL 0x4000 +/* NPHY: Antennas used for received frame, bitmask */ +#define PRXS0_ANTSEL_MASK 0xF000 #define PRXS0_ANTSEL_SHIFT 0x12 /* subfield PRXS0_FT_MASK */ #define PRXS0_CCK 0x0000 -#define PRXS0_OFDM 0x0001 /* valid only for G phy, use rxh->RxChan for A phy */ +/* valid only for G phy, use rxh->RxChan for A phy */ +#define PRXS0_OFDM 0x0001 #define PRXS0_PREN 0x0002 #define PRXS0_STDN 0x0003 @@ -1364,35 +1473,51 @@ struct brcms_d11rxhdr { #define PRXS0_UNUSED 0xF000 /* unused and not defined; set to 0 */ /* htphy PhyRxStatus_1: */ -#define PRXS1_HTPHY_CORE_MASK 0x000F /* core enables for {3..0}, 0=disabled, 1=enabled */ -#define PRXS1_HTPHY_ANTCFG_MASK 0x00F0 /* antenna configation */ -#define PRXS1_HTPHY_MMPLCPLenL_MASK 0xFF00 /* Mixmode PLCP Length low byte mask */ +/* core enables for {3..0}, 0=disabled, 1=enabled */ +#define PRXS1_HTPHY_CORE_MASK 0x000F +/* antenna configation */ +#define PRXS1_HTPHY_ANTCFG_MASK 0x00F0 +/* Mixmode PLCP Length low byte mask */ +#define PRXS1_HTPHY_MMPLCPLenL_MASK 0xFF00 /* htphy PhyRxStatus_2: */ -#define PRXS2_HTPHY_MMPLCPLenH_MASK 0x000F /* Mixmode PLCP Length high byte maskw */ -#define PRXS2_HTPHY_MMPLCH_RATE_MASK 0x00F0 /* Mixmode PLCP rate mask */ -#define PRXS2_HTPHY_RXPWR_ANT0 0xFF00 /* Rx power on core 0 */ +/* Mixmode PLCP Length high byte maskw */ +#define PRXS2_HTPHY_MMPLCPLenH_MASK 0x000F +/* Mixmode PLCP rate mask */ +#define PRXS2_HTPHY_MMPLCH_RATE_MASK 0x00F0 +/* Rx power on core 0 */ +#define PRXS2_HTPHY_RXPWR_ANT0 0xFF00 /* htphy PhyRxStatus_3: */ -#define PRXS3_HTPHY_RXPWR_ANT1 0x00FF /* Rx power on core 1 */ -#define PRXS3_HTPHY_RXPWR_ANT2 0xFF00 /* Rx power on core 2 */ +/* Rx power on core 1 */ +#define PRXS3_HTPHY_RXPWR_ANT1 0x00FF +/* Rx power on core 2 */ +#define PRXS3_HTPHY_RXPWR_ANT2 0xFF00 /* htphy PhyRxStatus_4: */ -#define PRXS4_HTPHY_RXPWR_ANT3 0x00FF /* Rx power on core 3 */ -#define PRXS4_HTPHY_CFO 0xFF00 /* Coarse frequency offset */ +/* Rx power on core 3 */ +#define PRXS4_HTPHY_RXPWR_ANT3 0x00FF +/* Coarse frequency offset */ +#define PRXS4_HTPHY_CFO 0xFF00 /* htphy PhyRxStatus_5: */ -#define PRXS5_HTPHY_FFO 0x00FF /* Fine frequency offset */ -#define PRXS5_HTPHY_AR 0xFF00 /* Advance Retard */ +/* Fine frequency offset */ +#define PRXS5_HTPHY_FFO 0x00FF +/* Advance Retard */ +#define PRXS5_HTPHY_AR 0xFF00 -#define HTPHY_MMPLCPLen(rxs) ((((rxs)->PhyRxStatus_1 & PRXS1_HTPHY_MMPLCPLenL_MASK) >> 8) | \ +#define HTPHY_MMPLCPLen(rxs) \ + ((((rxs)->PhyRxStatus_1 & PRXS1_HTPHY_MMPLCPLenL_MASK) >> 8) | \ (((rxs)->PhyRxStatus_2 & PRXS2_HTPHY_MMPLCPLenH_MASK) << 8)) /* Get Rx power on core 0 */ -#define HTPHY_RXPWR_ANT0(rxs) ((((rxs)->PhyRxStatus_2) & PRXS2_HTPHY_RXPWR_ANT0) >> 8) +#define HTPHY_RXPWR_ANT0(rxs) \ + ((((rxs)->PhyRxStatus_2) & PRXS2_HTPHY_RXPWR_ANT0) >> 8) /* Get Rx power on core 1 */ -#define HTPHY_RXPWR_ANT1(rxs) (((rxs)->PhyRxStatus_3) & PRXS3_HTPHY_RXPWR_ANT1) +#define HTPHY_RXPWR_ANT1(rxs) \ + (((rxs)->PhyRxStatus_3) & PRXS3_HTPHY_RXPWR_ANT1) /* Get Rx power on core 2 */ -#define HTPHY_RXPWR_ANT2(rxs) ((((rxs)->PhyRxStatus_3) & PRXS3_HTPHY_RXPWR_ANT2) >> 8) +#define HTPHY_RXPWR_ANT2(rxs) \ + ((((rxs)->PhyRxStatus_3) & PRXS3_HTPHY_RXPWR_ANT2) >> 8) /* ucode RxStatus1: */ #define RXS_BCNSENT 0x8000 @@ -1400,7 +1525,8 @@ struct brcms_d11rxhdr { #define RXS_SECKINDX_SHIFT 5 #define RXS_DECERR (1 << 4) #define RXS_DECATMPT (1 << 3) -#define RXS_PBPRES (1 << 2) /* PAD bytes to make IP data 4 bytes aligned */ +/* PAD bytes to make IP data 4 bytes aligned */ +#define RXS_PBPRES (1 << 2) #define RXS_RESPFRAMETX (1 << 1) #define RXS_FCSERR (1 << 0) @@ -1433,16 +1559,17 @@ struct brcms_d11rxhdr { #define M_PSM_SOFT_REGS 0x0 #define M_BOM_REV_MAJOR (M_PSM_SOFT_REGS + 0x0) #define M_BOM_REV_MINOR (M_PSM_SOFT_REGS + 0x2) -#define M_UCODE_DBGST (M_PSM_SOFT_REGS + 0x40) /* ucode debug status code */ -#define M_UCODE_MACSTAT (M_PSM_SOFT_REGS + 0xE0) /* macstat counters */ +#define M_UCODE_DBGST (M_PSM_SOFT_REGS + 0x40) /* ucode debug status code */ +#define M_UCODE_MACSTAT (M_PSM_SOFT_REGS + 0xE0) /* macstat counters */ -#define M_AGING_THRSH (0x3e * 2) /* max time waiting for medium before tx */ -#define M_MBURST_SIZE (0x40 * 2) /* max frames in a frameburst */ -#define M_MBURST_TXOP (0x41 * 2) /* max frameburst TXOP in unit of us */ -#define M_SYNTHPU_DLY (0x4a * 2) /* pre-wakeup for synthpu, default: 500 */ +#define M_AGING_THRSH (0x3e * 2) /* max time waiting for medium before tx */ +#define M_MBURST_SIZE (0x40 * 2) /* max frames in a frameburst */ +#define M_MBURST_TXOP (0x41 * 2) /* max frameburst TXOP in unit of us */ +#define M_SYNTHPU_DLY (0x4a * 2) /* pre-wakeup for synthpu, default: 500 */ #define M_PRETBTT (0x4b * 2) -#define M_ALT_TXPWR_IDX (M_PSM_SOFT_REGS + (0x3b * 2)) /* offset to the target txpwr */ +/* offset to the target txpwr */ +#define M_ALT_TXPWR_IDX (M_PSM_SOFT_REGS + (0x3b * 2)) #define M_PHY_TX_FLT_PTR (M_PSM_SOFT_REGS + (0x3d * 2)) #define M_CTS_DURATION (M_PSM_SOFT_REGS + (0x5c * 2)) #define M_LP_RCCAL_OVR (M_PSM_SOFT_REGS + (0x6b * 2)) @@ -1451,11 +1578,16 @@ struct brcms_d11rxhdr { #define M_RXSTATS_BLK_PTR (M_PSM_SOFT_REGS + (0x65 * 2)) /* ucode debug status codes */ -#define DBGST_INACTIVE 0 /* not valid really */ -#define DBGST_INIT 1 /* after zeroing SHM, before suspending at init */ -#define DBGST_ACTIVE 2 /* "normal" state */ -#define DBGST_SUSPENDED 3 /* suspended */ -#define DBGST_ASLEEP 4 /* asleep (PS mode) */ +/* not valid really */ +#define DBGST_INACTIVE 0 +/* after zeroing SHM, before suspending at init */ +#define DBGST_INIT 1 +/* "normal" state */ +#define DBGST_ACTIVE 2 +/* suspended */ +#define DBGST_SUSPENDED 3 +/* asleep (PS mode) */ +#define DBGST_ASLEEP 4 /* Scratch Reg defs */ enum _ePsmScratchPadRegDefinitions { @@ -1463,66 +1595,66 @@ enum _ePsmScratchPadRegDefinitions { S_RSV1, S_RSV2, - /* scratch registers for Dot11-contants */ - S_DOT11_CWMIN, /* CW-minimum 0x03 */ - S_DOT11_CWMAX, /* CW-maximum 0x04 */ - S_DOT11_CWCUR, /* CW-current 0x05 */ - S_DOT11_SRC_LMT, /* short retry count limit 0x06 */ - S_DOT11_LRC_LMT, /* long retry count limit 0x07 */ - S_DOT11_DTIMCOUNT, /* DTIM-count 0x08 */ - - /* Tx-side scratch registers */ - S_SEQ_NUM, /* hardware sequence number reg 0x09 */ - S_SEQ_NUM_FRAG, /* seq-num for frags (Set at the start os MSDU 0x0A */ - S_FRMRETX_CNT, /* frame retx count 0x0B */ - S_SSRC, /* Station short retry count 0x0C */ - S_SLRC, /* Station long retry count 0x0D */ - S_EXP_RSP, /* Expected response frame 0x0E */ - S_OLD_BREM, /* Remaining backoff ctr 0x0F */ - S_OLD_CWWIN, /* saved-off CW-cur 0x10 */ - S_TXECTL, /* TXE-Ctl word constructed in scr-pad 0x11 */ - S_CTXTST, /* frm type-subtype as read from Tx-descr 0x12 */ - - /* Rx-side scratch registers */ - S_RXTST, /* Type and subtype in Rxframe 0x13 */ + /* offset 0x03: scratch registers for Dot11-contants */ + S_DOT11_CWMIN, /* CW-minimum */ + S_DOT11_CWMAX, /* CW-maximum */ + S_DOT11_CWCUR, /* CW-current */ + S_DOT11_SRC_LMT, /* short retry count limit */ + S_DOT11_LRC_LMT, /* long retry count limit */ + S_DOT11_DTIMCOUNT, /* DTIM-count */ + + /* offset 0x09: Tx-side scratch registers */ + S_SEQ_NUM, /* hardware sequence number reg */ + S_SEQ_NUM_FRAG, /* seq num for frags (at the start of MSDU) */ + S_FRMRETX_CNT, /* frame retx count */ + S_SSRC, /* Station short retry count */ + S_SLRC, /* Station long retry count */ + S_EXP_RSP, /* Expected response frame */ + S_OLD_BREM, /* Remaining backoff ctr */ + S_OLD_CWWIN, /* saved-off CW-cur */ + S_TXECTL, /* TXE-Ctl word constructed in scr-pad */ + S_CTXTST, /* frm type-subtype as read from Tx-descr */ + + /* offset 0x13: Rx-side scratch registers */ + S_RXTST, /* Type and subtype in Rxframe */ /* Global state register */ - S_STREG, /* state storage actual bit maps below 0x14 */ - - S_TXPWR_SUM, /* Tx power control: accumulator 0x15 */ - S_TXPWR_ITER, /* Tx power control: iteration 0x16 */ - S_RX_FRMTYPE, /* Rate and PHY type for frames 0x17 */ - S_THIS_AGG, /* Size of this AGG (A-MSDU) 0x18 */ - - S_KEYINDX, /* 0x19 */ - S_RXFRMLEN, /* Receive MPDU length in bytes 0x1A */ - - /* Receive TSF time stored in SCR */ - S_RXTSFTMRVAL_WD3, /* TSF value at the start of rx 0x1B */ - S_RXTSFTMRVAL_WD2, /* TSF value at the start of rx 0x1C */ - S_RXTSFTMRVAL_WD1, /* TSF value at the start of rx 0x1D */ - S_RXTSFTMRVAL_WD0, /* TSF value at the start of rx 0x1E */ - S_RXSSN, /* Received start seq number for A-MPDU BA 0x1F */ - S_RXQOSFLD, /* Rx-QoS field (if present) 0x20 */ - - /* Scratch pad regs used in microcode as temp storage */ - S_TMP0, /* stmp0 0x21 */ - S_TMP1, /* stmp1 0x22 */ - S_TMP2, /* stmp2 0x23 */ - S_TMP3, /* stmp3 0x24 */ - S_TMP4, /* stmp4 0x25 */ - S_TMP5, /* stmp5 0x26 */ - S_PRQPENALTY_CTR, /* Probe response queue penalty counter 0x27 */ - S_ANTCNT, /* unsuccessful attempts on current ant. 0x28 */ - S_SYMBOL, /* flag for possible symbol ctl frames 0x29 */ - S_RXTP, /* rx frame type 0x2A */ - S_STREG2, /* extra state storage 0x2B */ - S_STREG3, /* even more extra state storage 0x2C */ - S_STREG4, /* ... 0x2D */ - S_STREG5, /* remember to initialize it to zero 0x2E */ + S_STREG, /* state storage actual bit maps below */ + + S_TXPWR_SUM, /* Tx power control: accumulator */ + S_TXPWR_ITER, /* Tx power control: iteration */ + S_RX_FRMTYPE, /* Rate and PHY type for frames */ + S_THIS_AGG, /* Size of this AGG (A-MSDU) */ + + S_KEYINDX, + S_RXFRMLEN, /* Receive MPDU length in bytes */ + + /* offset 0x1B: Receive TSF time stored in SCR */ + S_RXTSFTMRVAL_WD3, /* TSF value at the start of rx */ + S_RXTSFTMRVAL_WD2, /* TSF value at the start of rx */ + S_RXTSFTMRVAL_WD1, /* TSF value at the start of rx */ + S_RXTSFTMRVAL_WD0, /* TSF value at the start of rx */ + S_RXSSN, /* Received start seq number for A-MPDU BA */ + S_RXQOSFLD, /* Rx-QoS field (if present) */ + + /* offset 0x21: Scratch pad regs used in microcode as temp storage */ + S_TMP0, /* stmp0 */ + S_TMP1, /* stmp1 */ + S_TMP2, /* stmp2 */ + S_TMP3, /* stmp3 */ + S_TMP4, /* stmp4 */ + S_TMP5, /* stmp5 */ + S_PRQPENALTY_CTR, /* Probe response queue penalty counter */ + S_ANTCNT, /* unsuccessful attempts on current ant. */ + S_SYMBOL, /* flag for possible symbol ctl frames */ + S_RXTP, /* rx frame type */ + S_STREG2, /* extra state storage */ + S_STREG3, /* even more extra state storage */ + S_STREG4, /* ... */ + S_STREG5, /* remember to initialize it to zero */ S_ADJPWR_IDX, - S_CUR_PTR, /* Temp pointer for A-MPDU re-Tx SHM table 0x32 */ + S_CUR_PTR, /* Temp pointer for A-MPDU re-Tx SHM table */ S_REVID4, /* 0x33 */ S_INDX, /* 0x34 */ S_ADDR0, /* 0x35 */ @@ -1532,9 +1664,9 @@ enum _ePsmScratchPadRegDefinitions { S_ADDR4, /* 0x39 */ S_ADDR5, /* 0x3A */ S_TMP6, /* 0x3B */ - S_KEYINDX_BU, /* Backup for Key index 0x3C */ - S_MFGTEST_TMP0, /* Temp register used for RX test calculations 0x3D */ - S_RXESN, /* Received end sequence number for A-MPDU BA 0x3E */ + S_KEYINDX_BU, /* Backup for Key index */ + S_MFGTEST_TMP0, /* Temp regs used for RX test calculations */ + S_RXESN, /* Received end sequence number for A-MPDU BA */ S_STREG6, /* 0x3F */ }; @@ -1628,7 +1760,8 @@ struct macstat { #define SISF_FCLKA 0x0004 /* FastClkAvailable */ #define SISF_DB_PHY 0x0008 /* Dualband phy */ -/* === End of MAC reg, Beginning of PHY(b/a/g/n) reg, radio and LPPHY regs are separated === */ +/* === End of MAC reg, Beginning of PHY(b/a/g/n) reg === */ +/* radio and LPPHY regs are separated */ #define BPHY_REG_OFT_BASE 0x0 /* offsets for indirect access to bphy registers */ diff --git a/drivers/staging/brcm80211/brcmsmac/dma.c b/drivers/staging/brcm80211/brcmsmac/dma.c index ea17671..42446cd 100644 --- a/drivers/staging/brcm80211/brcmsmac/dma.c +++ b/drivers/staging/brcm80211/brcmsmac/dma.c @@ -18,17 +18,14 @@ #include <linux/delay.h> #include <linux/pci.h> -#if defined(__mips__) -#include <asm/addrspace.h> -#endif - #include <brcmu_utils.h> #include <aiutils.h> #include "types.h" #include "dma.h" /* - * Each descriptor ring must be 8kB aligned, and fit within a contiguous 8kB physical address. + * Each descriptor ring must be 8kB aligned, and fit within a + * contiguous 8kB physical address. */ #define D64RINGALIGN_BITS 13 #define D64MAXRINGSZ (1 << D64RINGALIGN_BITS) @@ -69,21 +66,32 @@ #define D64_XS1_XE_COREE 0x50000000 /* core error */ /* receive channel control */ -#define D64_RC_RE 0x00000001 /* receive enable */ -#define D64_RC_RO_MASK 0x000000fe /* receive frame offset */ +/* receive enable */ +#define D64_RC_RE 0x00000001 +/* receive frame offset */ +#define D64_RC_RO_MASK 0x000000fe #define D64_RC_RO_SHIFT 1 -#define D64_RC_FM 0x00000100 /* direct fifo receive (pio) mode */ -#define D64_RC_SH 0x00000200 /* separate rx header descriptor enable */ -#define D64_RC_OC 0x00000400 /* overflow continue */ -#define D64_RC_PD 0x00000800 /* parity check disable */ -#define D64_RC_AE 0x00030000 /* address extension bits */ +/* direct fifo receive (pio) mode */ +#define D64_RC_FM 0x00000100 +/* separate rx header descriptor enable */ +#define D64_RC_SH 0x00000200 +/* overflow continue */ +#define D64_RC_OC 0x00000400 +/* parity check disable */ +#define D64_RC_PD 0x00000800 +/* address extension bits */ +#define D64_RC_AE 0x00030000 #define D64_RC_AE_SHIFT 16 /* flags for dma controller */ -#define DMA_CTRL_PEN (1 << 0) /* partity enable */ -#define DMA_CTRL_ROC (1 << 1) /* rx overflow continue */ -#define DMA_CTRL_RXMULTI (1 << 2) /* allow rx scatter to multiple descriptors */ -#define DMA_CTRL_UNFRAMED (1 << 3) /* Unframed Rx/Tx data */ +/* partity enable */ +#define DMA_CTRL_PEN (1 << 0) +/* rx overflow continue */ +#define DMA_CTRL_ROC (1 << 1) +/* allow rx scatter to multiple descriptors */ +#define DMA_CTRL_RXMULTI (1 << 2) +/* Unframed Rx/Tx data */ +#define DMA_CTRL_UNFRAMED (1 << 3) /* receive descriptor table pointer */ #define D64_RP_LD_MASK 0x00000fff /* last valid descriptor */ @@ -131,10 +139,13 @@ #define D64_CTRL1_SOF ((u32)1 << 31) /* start of frame */ /* descriptor control flags 2 */ -#define D64_CTRL2_BC_MASK 0x00007fff /* buffer byte count. real data len must <= 16KB */ -#define D64_CTRL2_AE 0x00030000 /* address extension bits */ +/* buffer byte count. real data len must <= 16KB */ +#define D64_CTRL2_BC_MASK 0x00007fff +/* address extension bits */ +#define D64_CTRL2_AE 0x00030000 #define D64_CTRL2_AE_SHIFT 16 -#define D64_CTRL2_PARITY 0x00040000 /* parity bit */ +/* parity bit */ +#define D64_CTRL2_PARITY 0x00040000 /* control flags in the range [27:20] are core-specific and not defined here */ #define D64_CTRL_CORE_MASK 0x0ff00000 @@ -144,15 +155,16 @@ #define D64_RX_FRM_STS_DSCRCNT 0x0f000000 /* no. of descriptors used - 1 */ #define D64_RX_FRM_STS_DATATYPE 0xf0000000 /* core-dependent data type */ -#define DMADDRWIDTH_30 30 /* 30-bit addressing capability */ -#define DMADDRWIDTH_32 32 /* 32-bit addressing capability */ -#define DMADDRWIDTH_63 63 /* 64-bit addressing capability */ -#define DMADDRWIDTH_64 64 /* 64-bit addressing capability */ +#define DMA64_DD_PARITY(dd) \ + parity32((dd)->addrlow ^ (dd)->addrhigh ^ (dd)->ctrl1 ^ (dd)->ctrl2) -/* packet headroom necessary to accommodate the largest header in the system, (i.e TXOFF). - * By doing, we avoid the need to allocate an extra buffer for the header when bridging to WL. - * There is a compile time check in wlc.c which ensure that this value is at least as big - * as TXOFF. This value is used in dma_rxfill (dma.c). +/* + * packet headroom necessary to accommodate the largest header + * in the system, (i.e TXOFF). By doing, we avoid the need to + * allocate an extra buffer for the header when bridging to WL. + * There is a compile time check in wlc.c which ensure that this + * value is at least as big as TXOFF. This value is used in + * dma_rxfill(). */ #define BCMEXTRAHDROOM 172 @@ -180,51 +192,29 @@ #define DMA_NONE(args) -typedef unsigned long dmaaddr_t; -#define PHYSADDRHI(_pa) (0) -#define PHYSADDRHISET(_pa, _val) -#define PHYSADDRLO(_pa) ((_pa)) -#define PHYSADDRLOSET(_pa, _val) \ - do { \ - (_pa) = (_val); \ - } while (0) - #define d64txregs dregs.d64_u.txregs_64 #define d64rxregs dregs.d64_u.rxregs_64 #define txd64 dregs.d64_u.txd_64 #define rxd64 dregs.d64_u.rxd_64 -/* default dma message level (if input msg_level pointer is null in dma_attach()) */ +/* + * default dma message level (if input msg_level + * pointer is null in dma_attach()) + */ static uint dma_msg_level; #define MAXNAMEL 8 /* 8 char names */ #define DI_INFO(dmah) ((dma_info_t *)dmah) -#define R_SM(r) (*(r)) -#define W_SM(r, v) (*(r) = (v)) - -/* One physical DMA segment */ -struct dma_seg { - dmaaddr_t addr; - u32 length; -}; - -struct dma_seg_map { - void *oshdmah; /* Opaque handle for OSL to store its information */ - uint origsize; /* Size of the virtual packet */ - uint nsegs; - struct dma_seg segs[MAX_DMA_SEGS]; -}; - /* * DMA Descriptor * Descriptors are only read by the hardware, never written back. */ struct dma64desc { - u32 ctrl1; /* misc control bits & bufcount */ - u32 ctrl2; /* buffer count and address extension */ - u32 addrlow; /* memory address of the date buffer, bits 31:0 */ + u32 ctrl1; /* misc control bits & bufcount */ + u32 ctrl2; /* buffer count and address extension */ + u32 addrlow; /* memory address of the date buffer, bits 31:0 */ u32 addrhigh; /* memory address of the date buffer, bits 63:32 */ }; @@ -234,15 +224,17 @@ struct dma_info { uint *msg_level; /* message level pointer */ char name[MAXNAMEL]; /* callers name for diag msgs */ - void *pbus; /* bus handle */ + struct pci_dev *pbus; /* bus handle */ - bool dma64; /* this dma engine is operating in 64-bit mode */ - bool addrext; /* this dma engine supports DmaExtendedAddrChanges */ + bool dma64; /* this dma engine is operating in 64-bit mode */ + bool addrext; /* this dma engine supports DmaExtendedAddrChanges */ union { struct { - dma64regs_t *txregs_64; /* 64-bit dma tx engine registers */ - dma64regs_t *rxregs_64; /* 64-bit dma rx engine registers */ + /* 64-bit dma tx engine registers */ + struct dma64regs *txregs_64; + /* 64-bit dma rx engine registers */ + struct dma64regs *rxregs_64; /* pointer to dma64 tx descriptor ring */ struct dma64desc *txd_64; /* pointer to dma64 rx descriptor ring */ @@ -255,56 +247,61 @@ struct dma_info { u16 ntxd; /* # tx descriptors tunable */ u16 txin; /* index of next descriptor to reclaim */ u16 txout; /* index of next descriptor to post */ - void **txp; /* pointer to parallel array of pointers to packets */ - struct dma_seg_map *txp_dmah; /* DMA MAP meta-data handle */ - dmaaddr_t txdpa; /* Aligned physical address of descriptor ring */ - dmaaddr_t txdpaorig; /* Original physical address of descriptor ring */ + /* pointer to parallel array of pointers to packets */ + struct sk_buff **txp; + /* Aligned physical address of descriptor ring */ + dma_addr_t txdpa; + /* Original physical address of descriptor ring */ + dma_addr_t txdpaorig; u16 txdalign; /* #bytes added to alloc'd mem to align txd */ u32 txdalloc; /* #bytes allocated for the ring */ u32 xmtptrbase; /* When using unaligned descriptors, the ptr register - * is not just an index, it needs all 13 bits to be - * an offset from the addr register. - */ + * is not just an index, it needs all 13 bits to be + * an offset from the addr register. + */ - u16 nrxd; /* # rx descriptors tunable */ - u16 rxin; /* index of next descriptor to reclaim */ - u16 rxout; /* index of next descriptor to post */ - void **rxp; /* pointer to parallel array of pointers to packets */ - struct dma_seg_map *rxp_dmah; /* DMA MAP meta-data handle */ - dmaaddr_t rxdpa; /* Aligned physical address of descriptor ring */ - dmaaddr_t rxdpaorig; /* Original physical address of descriptor ring */ + u16 nrxd; /* # rx descriptors tunable */ + u16 rxin; /* index of next descriptor to reclaim */ + u16 rxout; /* index of next descriptor to post */ + /* pointer to parallel array of pointers to packets */ + struct sk_buff **rxp; + /* Aligned physical address of descriptor ring */ + dma_addr_t rxdpa; + /* Original physical address of descriptor ring */ + dma_addr_t rxdpaorig; u16 rxdalign; /* #bytes added to alloc'd mem to align rxd */ u32 rxdalloc; /* #bytes allocated for the ring */ u32 rcvptrbase; /* Base for ptr reg when using unaligned descriptors */ /* tunables */ - unsigned int rxbufsize; /* rx buffer size in bytes, - * not including the extra headroom + unsigned int rxbufsize; /* rx buffer size in bytes, not including + * the extra headroom */ - uint rxextrahdrroom; /* extra rx headroom, reverseved to assist upper stack - * e.g. some rx pkt buffers will be bridged to tx side - * without byte copying. The extra headroom needs to be - * large enough to fit txheader needs. - * Some dongle driver may not need it. + uint rxextrahdrroom; /* extra rx headroom, reverseved to assist upper + * stack, e.g. some rx pkt buffers will be + * bridged to tx side without byte copying. + * The extra headroom needs to be large enough + * to fit txheader needs. Some dongle driver may + * not need it. */ uint nrxpost; /* # rx buffers to keep posted */ unsigned int rxoffset; /* rxcontrol offset */ - uint ddoffsetlow; /* add to get dma address of descriptor ring, low 32 bits */ - uint ddoffsethigh; /* high 32 bits */ - uint dataoffsetlow; /* add to get dma address of data buffer, low 32 bits */ - uint dataoffsethigh; /* high 32 bits */ - bool aligndesc_4k; /* descriptor base need to be aligned or not */ + /* add to get dma address of descriptor ring, low 32 bits */ + uint ddoffsetlow; + /* high 32 bits */ + uint ddoffsethigh; + /* add to get dma address of data buffer, low 32 bits */ + uint dataoffsetlow; + /* high 32 bits */ + uint dataoffsethigh; + /* descriptor base need to be aligned or not */ + bool aligndesc_4k; }; -/* DMA Scatter-gather list is supported. Note this is limited to TX direction only */ -#ifdef BCMDMASGLISTOSL -#define DMASGLIST_ENAB true -#else -#define DMASGLIST_ENAB false -#endif /* BCMDMASGLISTOSL */ - /* descriptor bumping macros */ -#define XXD(x, n) ((x) & ((n) - 1)) /* faster than %, but n must be power of 2 */ +/* faster than %, but n must be power of 2 */ +#define XXD(x, n) ((x) & ((n) - 1)) + #define TXD(x) XXD((x), di->ntxd) #define RXD(x) XXD((x), di->nrxd) #define NEXTTXD(i) TXD((i) + 1) @@ -329,110 +326,24 @@ struct dma_info { static bool _dma_isaddrext(struct dma_info *di); static bool _dma_descriptor_align(struct dma_info *di); static bool _dma_alloc(struct dma_info *di, uint direction); -static void _dma_detach(struct dma_info *di); static void _dma_ddtable_init(struct dma_info *di, uint direction, - dmaaddr_t pa); -static void _dma_rxinit(struct dma_info *di); -static void *_dma_rx(struct dma_info *di); -static bool _dma_rxfill(struct dma_info *di); -static void _dma_rxreclaim(struct dma_info *di); + dma_addr_t pa); static void _dma_rxenable(struct dma_info *di); -static void *_dma_getnextrxp(struct dma_info *di, bool forceall); -static void _dma_rx_param_get(struct dma_info *di, u16 *rxoffset, - u16 *rxbufsize); - -static void _dma_txblock(struct dma_info *di); -static void _dma_txunblock(struct dma_info *di); -static uint _dma_txactive(struct dma_info *di); -static uint _dma_rxactive(struct dma_info *di); -static uint _dma_txpending(struct dma_info *di); -static uint _dma_txcommitted(struct dma_info *di); - -static void *_dma_peeknexttxp(struct dma_info *di); -static void *_dma_peeknextrxp(struct dma_info *di); -static unsigned long _dma_getvar(struct dma_info *di, const char *name); -static void _dma_counterreset(struct dma_info *di); -static void _dma_fifoloopbackenable(struct dma_info *di); +static struct sk_buff *_dma_getnextrxp(struct dma_info *di, bool forceall); static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags); static u8 dma_align_sizetobits(uint size); static void *dma_ringalloc(struct dma_info *di, u32 boundary, uint size, u16 *alignbits, uint *alloced, - dmaaddr_t *descpa); + dma_addr_t *descpa); /* Prototypes for 64-bit routines */ static bool dma64_alloc(struct dma_info *di, uint direction); -static bool dma64_txreset(struct dma_info *di); -static bool dma64_rxreset(struct dma_info *di); -static bool dma64_txsuspendedidle(struct dma_info *di); -static int dma64_txfast(struct dma_info *di, struct sk_buff *p0, bool commit); -static int dma64_txunframed(struct dma_info *di, void *p0, uint len, - bool commit); -static void *dma64_getpos(struct dma_info *di, bool direction); -static void *dma64_getnexttxp(struct dma_info *di, enum txd_range range); -static void *dma64_getnextrxp(struct dma_info *di, bool forceall); -static void dma64_txrotate(struct dma_info *di); - +static struct sk_buff *dma64_getnextrxp(struct dma_info *di, bool forceall); static bool dma64_rxidle(struct dma_info *di); -static void dma64_txinit(struct dma_info *di); -static bool dma64_txenabled(struct dma_info *di); -static void dma64_txsuspend(struct dma_info *di); -static void dma64_txresume(struct dma_info *di); -static bool dma64_txsuspended(struct dma_info *di); -static void dma64_txreclaim(struct dma_info *di, enum txd_range range); -static bool dma64_txstopped(struct dma_info *di); -static bool dma64_rxstopped(struct dma_info *di); -static bool dma64_rxenabled(struct dma_info *di); -static bool _dma64_addrext(dma64regs_t *dma64regs); +static bool _dma64_addrext(struct dma64regs *dma64regs); static inline u32 parity32(u32 data); -const struct di_fcn_s dma64proc = { - (di_detach_t) _dma_detach, - (di_txinit_t) dma64_txinit, - (di_txreset_t) dma64_txreset, - (di_txenabled_t) dma64_txenabled, - (di_txsuspend_t) dma64_txsuspend, - (di_txresume_t) dma64_txresume, - (di_txsuspended_t) dma64_txsuspended, - (di_txsuspendedidle_t) dma64_txsuspendedidle, - (di_txfast_t) dma64_txfast, - (di_txunframed_t) dma64_txunframed, - (di_getpos_t) dma64_getpos, - (di_txstopped_t) dma64_txstopped, - (di_txreclaim_t) dma64_txreclaim, - (di_getnexttxp_t) dma64_getnexttxp, - (di_peeknexttxp_t) _dma_peeknexttxp, - (di_txblock_t) _dma_txblock, - (di_txunblock_t) _dma_txunblock, - (di_txactive_t) _dma_txactive, - (di_txrotate_t) dma64_txrotate, - - (di_rxinit_t) _dma_rxinit, - (di_rxreset_t) dma64_rxreset, - (di_rxidle_t) dma64_rxidle, - (di_rxstopped_t) dma64_rxstopped, - (di_rxenable_t) _dma_rxenable, - (di_rxenabled_t) dma64_rxenabled, - (di_rx_t) _dma_rx, - (di_rxfill_t) _dma_rxfill, - (di_rxreclaim_t) _dma_rxreclaim, - (di_getnextrxp_t) _dma_getnextrxp, - (di_peeknextrxp_t) _dma_peeknextrxp, - (di_rxparam_get_t) _dma_rx_param_get, - - (di_fifoloopbackenable_t) _dma_fifoloopbackenable, - (di_getvar_t) _dma_getvar, - (di_counterreset_t) _dma_counterreset, - (di_ctrlflags_t) _dma_ctrlflags, - NULL, - NULL, - NULL, - (di_rxactive_t) _dma_rxactive, - (di_txpending_t) _dma_txpending, - (di_txcommitted_t) _dma_txcommitted, - 39 -}; - struct dma_pub *dma_attach(char *name, struct si_pub *sih, void *dmaregstx, void *dmaregsrx, uint ntxd, uint nrxd, uint rxbufsize, int rxextheadroom, @@ -456,17 +367,15 @@ struct dma_pub *dma_attach(char *name, struct si_pub *sih, di->dma64 = ((ai_core_sflags(sih, 0, 0) & SISF_DMA64) == SISF_DMA64); /* init dma reg pointer */ - di->d64txregs = (dma64regs_t *) dmaregstx; - di->d64rxregs = (dma64regs_t *) dmaregsrx; - di->dma.di_fn = (const struct di_fcn_s *)&dma64proc; - - /* Default flags (which can be changed by the driver calling dma_ctrlflags - * before enable): For backwards compatibility both Rx Overflow Continue - * and Parity are DISABLED. - * supports it. + di->d64txregs = (struct dma64regs *) dmaregstx; + di->d64rxregs = (struct dma64regs *) dmaregsrx; + + /* + * Default flags (which can be changed by the driver calling + * dma_ctrlflags before enable): For backwards compatibility + * both Rx Overflow Continue and Parity are DISABLED. */ - di->dma.di_fn->ctrlflags(&di->dma, DMA_CTRL_ROC | DMA_CTRL_PEN, - 0); + _dma_ctrlflags(di, DMA_CTRL_ROC | DMA_CTRL_PEN, 0); DMA_TRACE(("%s: dma_attach: %s flags 0x%x ntxd %d nrxd %d " "rxbufsize %d rxextheadroom %d nrxpost %d rxoffset %d " @@ -497,23 +406,18 @@ struct dma_pub *dma_attach(char *name, struct si_pub *sih, /* * figure out the DMA physical address offset for dd and data - * PCI/PCIE: they map silicon backplace address to zero based memory, need offset - * Other bus: use zero - * SI_BUS BIGENDIAN kludge: use sdram swapped region for data buffer, not descriptor + * PCI/PCIE: they map silicon backplace address to zero + * based memory, need offset + * Other bus: use zero SI_BUS BIGENDIAN kludge: use sdram + * swapped region for data buffer, not descriptor */ di->ddoffsetlow = 0; di->dataoffsetlow = 0; - /* for pci bus, add offset */ - if (sih->bustype == PCI_BUS) { - /* pcie with DMA64 */ - di->ddoffsetlow = 0; - di->ddoffsethigh = SI_PCIE_DMA_H32; - di->dataoffsetlow = di->ddoffsetlow; - di->dataoffsethigh = di->ddoffsethigh; - } -#if defined(__mips__) && defined(IL_BIGENDIAN) - di->dataoffsetlow = di->dataoffsetlow + SI_SDRAM_SWAPPED; -#endif /* defined(__mips__) && defined(IL_BIGENDIAN) */ + /* add offset for pcie with DMA64 bus */ + di->ddoffsetlow = 0; + di->ddoffsethigh = SI_PCIE_DMA_H32; + di->dataoffsetlow = di->ddoffsetlow; + di->dataoffsethigh = di->ddoffsethigh; /* WAR64450 : DMACtl.Addr ext fields are not supported in SDIOD core. */ if ((ai_coreid(sih) == SDIOD_CORE_ID) && ((ai_corerev(sih) > 0) && (ai_corerev(sih) <= 2))) @@ -524,16 +428,16 @@ struct dma_pub *dma_attach(char *name, struct si_pub *sih, else di->addrext = _dma_isaddrext(di); - /* does the descriptors need to be aligned and if yes, on 4K/8K or not */ + /* does the descriptor need to be aligned and if yes, on 4K/8K or not */ di->aligndesc_4k = _dma_descriptor_align(di); if (di->aligndesc_4k) { di->dmadesc_align = D64RINGALIGN_BITS; - if ((ntxd < D64MAXDD / 2) && (nrxd < D64MAXDD / 2)) { + if ((ntxd < D64MAXDD / 2) && (nrxd < D64MAXDD / 2)) /* for smaller dd table, HW relax alignment reqmnt */ di->dmadesc_align = D64RINGALIGN_BITS - 1; - } - } else + } else { di->dmadesc_align = 4; /* 16 byte alignment */ + } DMA_NONE(("DMA descriptor align_needed %d, align %d\n", di->aligndesc_4k, di->dmadesc_align)); @@ -543,7 +447,8 @@ struct dma_pub *dma_attach(char *name, struct si_pub *sih, size = ntxd * sizeof(void *); di->txp = kzalloc(size, GFP_ATOMIC); if (di->txp == NULL) { - DMA_ERROR(("%s: dma_attach: out of tx memory\n", di->name)); + DMA_ERROR(("%s: dma_attach: out of tx memory\n", + di->name)); goto fail; } } @@ -553,57 +458,52 @@ struct dma_pub *dma_attach(char *name, struct si_pub *sih, size = nrxd * sizeof(void *); di->rxp = kzalloc(size, GFP_ATOMIC); if (di->rxp == NULL) { - DMA_ERROR(("%s: dma_attach: out of rx memory\n", di->name)); + DMA_ERROR(("%s: dma_attach: out of rx memory\n", + di->name)); goto fail; } } - /* allocate transmit descriptor ring, only need ntxd descriptors but it must be aligned */ + /* + * allocate transmit descriptor ring, only need ntxd descriptors + * but it must be aligned + */ if (ntxd) { if (!_dma_alloc(di, DMA_TX)) goto fail; } - /* allocate receive descriptor ring, only need nrxd descriptors but it must be aligned */ + /* + * allocate receive descriptor ring, only need nrxd descriptors + * but it must be aligned + */ if (nrxd) { if (!_dma_alloc(di, DMA_RX)) goto fail; } if ((di->ddoffsetlow != 0) && !di->addrext) { - if (PHYSADDRLO(di->txdpa) > SI_PCI_DMA_SZ) { - DMA_ERROR(("%s: dma_attach: txdpa 0x%x: addrext not supported\n", di->name, (u32) PHYSADDRLO(di->txdpa))); + if (di->txdpa > SI_PCI_DMA_SZ) { + DMA_ERROR(("%s: dma_attach: txdpa 0x%x: addrext not " + "supported\n", di->name, (u32)di->txdpa)); goto fail; } - if (PHYSADDRLO(di->rxdpa) > SI_PCI_DMA_SZ) { - DMA_ERROR(("%s: dma_attach: rxdpa 0x%x: addrext not supported\n", di->name, (u32) PHYSADDRLO(di->rxdpa))); + if (di->rxdpa > SI_PCI_DMA_SZ) { + DMA_ERROR(("%s: dma_attach: rxdpa 0x%x: addrext not " + "supported\n", di->name, (u32)di->rxdpa)); goto fail; } } - DMA_TRACE(("ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x dataoffsethigh " "0x%x addrext %d\n", di->ddoffsetlow, di->ddoffsethigh, di->dataoffsetlow, di->dataoffsethigh, di->addrext)); - - /* allocate DMA mapping vectors */ - if (DMASGLIST_ENAB) { - if (ntxd) { - size = ntxd * sizeof(struct dma_seg_map); - di->txp_dmah = kzalloc(size, GFP_ATOMIC); - if (di->txp_dmah == NULL) - goto fail; - } - - if (nrxd) { - size = nrxd * sizeof(struct dma_seg_map); - di->rxp_dmah = kzalloc(size, GFP_ATOMIC); - if (di->rxp_dmah == NULL) - goto fail; - } - } + DMA_TRACE(("ddoffsetlow 0x%x ddoffsethigh 0x%x dataoffsetlow 0x%x " + "dataoffsethigh " "0x%x addrext %d\n", di->ddoffsetlow, + di->ddoffsethigh, di->dataoffsetlow, di->dataoffsethigh, + di->addrext)); return (struct dma_pub *) di; fail: - _dma_detach(di); + dma_detach((struct dma_pub *)di); return NULL; } @@ -619,48 +519,35 @@ static inline u32 parity32(u32 data) return data & 1; } -#define DMA64_DD_PARITY(dd) parity32((dd)->addrlow ^ (dd)->addrhigh ^ (dd)->ctrl1 ^ (dd)->ctrl2) - static inline void dma64_dd_upd(struct dma_info *di, struct dma64desc *ddring, - dmaaddr_t pa, uint outidx, u32 *flags, u32 bufcount) + dma_addr_t pa, uint outidx, u32 *flags, u32 bufcount) { u32 ctrl2 = bufcount & D64_CTRL2_BC_MASK; /* PCI bus with big(>1G) physical address, use address extension */ -#if defined(__mips__) && defined(IL_BIGENDIAN) - if ((di->dataoffsetlow == SI_SDRAM_SWAPPED) - || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) { -#else - if ((di->dataoffsetlow == 0) || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) { -#endif /* defined(__mips__) && defined(IL_BIGENDIAN) */ - - W_SM(&ddring[outidx].addrlow, - BUS_SWAP32(PHYSADDRLO(pa) + di->dataoffsetlow)); - W_SM(&ddring[outidx].addrhigh, - BUS_SWAP32(PHYSADDRHI(pa) + di->dataoffsethigh)); - W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags)); - W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2)); + if ((di->dataoffsetlow == 0) || !(pa & PCI32ADDR_HIGH)) { + ddring[outidx].addrlow = cpu_to_le32(pa + di->dataoffsetlow); + ddring[outidx].addrhigh = cpu_to_le32(di->dataoffsethigh); + ddring[outidx].ctrl1 = cpu_to_le32(*flags); + ddring[outidx].ctrl2 = cpu_to_le32(ctrl2); } else { /* address extension for 32-bit PCI */ u32 ae; - ae = (PHYSADDRLO(pa) & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; - PHYSADDRLO(pa) &= ~PCI32ADDR_HIGH; + ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; + pa &= ~PCI32ADDR_HIGH; ctrl2 |= (ae << D64_CTRL2_AE_SHIFT) & D64_CTRL2_AE; - W_SM(&ddring[outidx].addrlow, - BUS_SWAP32(PHYSADDRLO(pa) + di->dataoffsetlow)); - W_SM(&ddring[outidx].addrhigh, - BUS_SWAP32(0 + di->dataoffsethigh)); - W_SM(&ddring[outidx].ctrl1, BUS_SWAP32(*flags)); - W_SM(&ddring[outidx].ctrl2, BUS_SWAP32(ctrl2)); + ddring[outidx].addrlow = cpu_to_le32(pa + di->dataoffsetlow); + ddring[outidx].addrhigh = cpu_to_le32(di->dataoffsethigh); + ddring[outidx].ctrl1 = cpu_to_le32(*flags); + ddring[outidx].ctrl2 = cpu_to_le32(ctrl2); } if (di->dma.dmactrlflags & DMA_CTRL_PEN) { - if (DMA64_DD_PARITY(&ddring[outidx])) { - W_SM(&ddring[outidx].ctrl2, - BUS_SWAP32(ctrl2 | D64_CTRL2_PARITY)); - } + if (DMA64_DD_PARITY(&ddring[outidx])) + ddring[outidx].ctrl2 = + cpu_to_le32(ctrl2 | D64_CTRL2_PARITY); } } @@ -670,7 +557,7 @@ static bool _dma_alloc(struct dma_info *di, uint direction) } void *dma_alloc_consistent(struct pci_dev *pdev, uint size, u16 align_bits, - uint *alloced, unsigned long *pap) + uint *alloced, dma_addr_t *pap) { if (align_bits) { u16 align = (1 << align_bits); @@ -678,12 +565,13 @@ void *dma_alloc_consistent(struct pci_dev *pdev, uint size, u16 align_bits, size += align; *alloced = size; } - return pci_alloc_consistent(pdev, size, (dma_addr_t *) pap); + return pci_alloc_consistent(pdev, size, pap); } /* !! may be called with core in reset */ -static void _dma_detach(struct dma_info *di) +void dma_detach(struct dma_pub *pub) { + struct dma_info *di = (struct dma_info *)pub; DMA_TRACE(("%s: dma_detach\n", di->name)); @@ -701,12 +589,6 @@ static void _dma_detach(struct dma_info *di) kfree(di->txp); kfree(di->rxp); - /* free tx packet DMA handles */ - kfree(di->txp_dmah); - - /* free rx packet DMA handles */ - kfree(di->rxp_dmah); - /* free our private info structure */ kfree(di); @@ -731,87 +613,76 @@ static bool _dma_descriptor_align(struct dma_info *di) return true; } -/* return true if this dma engine supports DmaExtendedAddrChanges, otherwise false */ +/* + * return true if this dma engine supports DmaExtendedAddrChanges, + * otherwise false + */ static bool _dma_isaddrext(struct dma_info *di) { /* DMA64 supports full 32- or 64-bit operation. AE is always valid */ /* not all tx or rx channel are available */ if (di->d64txregs != NULL) { - if (!_dma64_addrext(di->d64txregs)) { + if (!_dma64_addrext(di->d64txregs)) DMA_ERROR(("%s: _dma_isaddrext: DMA64 tx doesn't have " "AE set\n", di->name)); - } return true; } else if (di->d64rxregs != NULL) { - if (!_dma64_addrext(di->d64rxregs)) { + if (!_dma64_addrext(di->d64rxregs)) DMA_ERROR(("%s: _dma_isaddrext: DMA64 rx doesn't have " "AE set\n", di->name)); - } return true; } + return false; } /* initialize descriptor table base address */ -static void _dma_ddtable_init(struct dma_info *di, uint direction, dmaaddr_t pa) +static void +_dma_ddtable_init(struct dma_info *di, uint direction, dma_addr_t pa) { if (!di->aligndesc_4k) { if (direction == DMA_TX) - di->xmtptrbase = PHYSADDRLO(pa); + di->xmtptrbase = pa; else - di->rcvptrbase = PHYSADDRLO(pa); + di->rcvptrbase = pa; } if ((di->ddoffsetlow == 0) - || !(PHYSADDRLO(pa) & PCI32ADDR_HIGH)) { + || !(pa & PCI32ADDR_HIGH)) { if (direction == DMA_TX) { - W_REG(&di->d64txregs->addrlow, - (PHYSADDRLO(pa) + di->ddoffsetlow)); - W_REG(&di->d64txregs->addrhigh, - (PHYSADDRHI(pa) + di->ddoffsethigh)); + W_REG(&di->d64txregs->addrlow, pa + di->ddoffsetlow); + W_REG(&di->d64txregs->addrhigh, di->ddoffsethigh); } else { - W_REG(&di->d64rxregs->addrlow, - (PHYSADDRLO(pa) + di->ddoffsetlow)); - W_REG(&di->d64rxregs->addrhigh, - (PHYSADDRHI(pa) + di->ddoffsethigh)); + W_REG(&di->d64rxregs->addrlow, pa + di->ddoffsetlow); + W_REG(&di->d64rxregs->addrhigh, di->ddoffsethigh); } } else { /* DMA64 32bits address extension */ u32 ae; /* shift the high bit(s) from pa to ae */ - ae = (PHYSADDRLO(pa) & PCI32ADDR_HIGH) >> - PCI32ADDR_HIGH_SHIFT; - PHYSADDRLO(pa) &= ~PCI32ADDR_HIGH; + ae = (pa & PCI32ADDR_HIGH) >> PCI32ADDR_HIGH_SHIFT; + pa &= ~PCI32ADDR_HIGH; if (direction == DMA_TX) { - W_REG(&di->d64txregs->addrlow, - (PHYSADDRLO(pa) + di->ddoffsetlow)); - W_REG(&di->d64txregs->addrhigh, - di->ddoffsethigh); + W_REG(&di->d64txregs->addrlow, pa + di->ddoffsetlow); + W_REG(&di->d64txregs->addrhigh, di->ddoffsethigh); SET_REG(&di->d64txregs->control, D64_XC_AE, (ae << D64_XC_AE_SHIFT)); } else { - W_REG(&di->d64rxregs->addrlow, - (PHYSADDRLO(pa) + di->ddoffsetlow)); - W_REG(&di->d64rxregs->addrhigh, - di->ddoffsethigh); + W_REG(&di->d64rxregs->addrlow, pa + di->ddoffsetlow); + W_REG(&di->d64rxregs->addrhigh, di->ddoffsethigh); SET_REG(&di->d64rxregs->control, D64_RC_AE, (ae << D64_RC_AE_SHIFT)); } } } -static void _dma_fifoloopbackenable(struct dma_info *di) +void dma_rxinit(struct dma_pub *pub) { - DMA_TRACE(("%s: dma_fifoloopbackenable\n", di->name)); - - OR_REG(&di->d64txregs->control, D64_XC_LE); -} + struct dma_info *di = (struct dma_info *)pub; -static void _dma_rxinit(struct dma_info *di) -{ DMA_TRACE(("%s: dma_rxinit\n", di->name)); if (di->nrxd == 0) @@ -820,8 +691,7 @@ static void _dma_rxinit(struct dma_info *di) di->rxin = di->rxout = 0; /* clear rx descriptor ring */ - memset((void *)di->rxd64, '\0', - (di->nrxd * sizeof(struct dma64desc))); + memset(di->rxd64, '\0', di->nrxd * sizeof(struct dma64desc)); /* DMA engine with out alignment requirement requires table to be inited * before enabling the engine @@ -856,25 +726,19 @@ static void _dma_rxenable(struct dma_info *di) ((di->rxoffset << D64_RC_RO_SHIFT) | control)); } -static void -_dma_rx_param_get(struct dma_info *di, u16 *rxoffset, u16 *rxbufsize) -{ - /* the normal values fit into 16 bits */ - *rxoffset = (u16) di->rxoffset; - *rxbufsize = (u16) di->rxbufsize; -} - -/* !! rx entry routine +/* + * !! rx entry routine * returns a pointer to the next frame received, or NULL if there are no more - * if DMA_CTRL_RXMULTI is defined, DMA scattering(multiple buffers) is supported - * with pkts chain + * if DMA_CTRL_RXMULTI is defined, DMA scattering(multiple buffers) is + * supported with pkts chain * otherwise, it's treated as giant pkt and will be tossed. - * The DMA scattering starts with normal DMA header, followed by first buffer data. - * After it reaches the max size of buffer, the data continues in next DMA descriptor - * buffer WITHOUT DMA header + * The DMA scattering starts with normal DMA header, followed by first + * buffer data. After it reaches the max size of buffer, the data continues + * in next DMA descriptor buffer WITHOUT DMA header */ -static void *_dma_rx(struct dma_info *di) +struct sk_buff *dma_rx(struct dma_pub *pub) { + struct dma_info *di = (struct dma_info *)pub; struct sk_buff *p, *head, *tail; uint len; uint pkt_len; @@ -914,7 +778,7 @@ static void *_dma_rx(struct dma_info *di) D64_RS0_CD_MASK) - di->rcvptrbase) & D64_RS0_CD_MASK, struct dma64desc); - DMA_ERROR(("_dma_rx, rxin %d rxout %d, hw_curr %d\n", + DMA_ERROR(("dma_rx, rxin %d rxout %d, hw_curr %d\n", di->rxin, di->rxout, cur)); } #endif /* BCMDBG */ @@ -931,19 +795,21 @@ static void *_dma_rx(struct dma_info *di) return head; } -/* post receive buffers - * return false is refill failed completely and ring is empty - * this will stall the rx dma and user might want to call rxfill again asap - * This unlikely happens on memory-rich NIC, but often on memory-constrained dongle +/* + * post receive buffers + * return false is refill failed completely and ring is empty this will stall + * the rx dma and user might want to call rxfill again asap. This unlikely + * happens on memory-rich NIC, but often on memory-constrained dongle */ -static bool _dma_rxfill(struct dma_info *di) +bool dma_rxfill(struct dma_pub *pub) { + struct dma_info *di = (struct dma_info *)pub; struct sk_buff *p; u16 rxin, rxout; u32 flags = 0; uint n; uint i; - dmaaddr_t pa; + dma_addr_t pa; uint extra_offset = 0; bool ring_empty; @@ -966,10 +832,10 @@ static bool _dma_rxfill(struct dma_info *di) extra_offset = di->rxextrahdrroom; for (i = 0; i < n; i++) { - /* the di->rxbufsize doesn't include the extra headroom, we need to add it to the - size to be allocated + /* + * the di->rxbufsize doesn't include the extra headroom, + * we need to add it to the size to be allocated */ - p = brcmu_pkt_buf_get_skb(di->rxbufsize + extra_offset); if (p == NULL) { @@ -992,10 +858,6 @@ static bool _dma_rxfill(struct dma_info *di) */ *(u32 *) (p->data) = 0; - if (DMASGLIST_ENAB) - memset(&di->rxp_dmah[rxout], 0, - sizeof(struct dma_seg_map)); - pa = pci_map_single(di->pbus, p->data, di->rxbufsize, PCI_DMA_FROMDEVICE); @@ -1021,49 +883,10 @@ static bool _dma_rxfill(struct dma_info *di) return ring_empty; } -/* like getnexttxp but no reclaim */ -static void *_dma_peeknexttxp(struct dma_info *di) +void dma_rxreclaim(struct dma_pub *pub) { - uint end, i; - - if (di->ntxd == 0) - return NULL; - - end = - B2I(((R_REG(&di->d64txregs->status0) & - D64_XS0_CD_MASK) - di->xmtptrbase) & D64_XS0_CD_MASK, - struct dma64desc); - - for (i = di->txin; i != end; i = NEXTTXD(i)) - if (di->txp[i]) - return di->txp[i]; - - return NULL; -} - -/* like getnextrxp but not take off the ring */ -static void *_dma_peeknextrxp(struct dma_info *di) -{ - uint end, i; - - if (di->nrxd == 0) - return NULL; - - end = - B2I(((R_REG(&di->d64rxregs->status0) & - D64_RS0_CD_MASK) - di->rcvptrbase) & D64_RS0_CD_MASK, - struct dma64desc); - - for (i = di->rxin; i != end; i = NEXTRXD(i)) - if (di->rxp[i]) - return di->rxp[i]; - - return NULL; -} - -static void _dma_rxreclaim(struct dma_info *di) -{ - void *p; + struct dma_info *di = (struct dma_info *)pub; + struct sk_buff *p; DMA_TRACE(("%s: dma_rxreclaim\n", di->name)); @@ -1071,7 +894,7 @@ static void _dma_rxreclaim(struct dma_info *di) brcmu_pkt_buf_free_skb(p); } -static void *_dma_getnextrxp(struct dma_info *di, bool forceall) +static struct sk_buff *_dma_getnextrxp(struct dma_info *di, bool forceall) { if (di->nrxd == 0) return NULL; @@ -1079,57 +902,12 @@ static void *_dma_getnextrxp(struct dma_info *di, bool forceall) return dma64_getnextrxp(di, forceall); } -static void _dma_txblock(struct dma_info *di) -{ - di->dma.txavail = 0; -} - -static void _dma_txunblock(struct dma_info *di) -{ - di->dma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; -} - -static uint _dma_txactive(struct dma_info *di) +void dma_counterreset(struct dma_pub *pub) { - return NTXDACTIVE(di->txin, di->txout); -} - -static uint _dma_txpending(struct dma_info *di) -{ - uint curr; - - curr = - B2I(((R_REG(&di->d64txregs->status0) & - D64_XS0_CD_MASK) - di->xmtptrbase) & D64_XS0_CD_MASK, - struct dma64desc); - - return NTXDACTIVE(curr, di->txout); -} - -static uint _dma_txcommitted(struct dma_info *di) -{ - uint ptr; - uint txin = di->txin; - - if (txin == di->txout) - return 0; - - ptr = B2I(R_REG(&di->d64txregs->ptr), struct dma64desc); - - return NTXDACTIVE(di->txin, ptr); -} - -static uint _dma_rxactive(struct dma_info *di) -{ - return NRXDACTIVE(di->rxin, di->rxout); -} - -static void _dma_counterreset(struct dma_info *di) -{ - /* reset all software counter */ - di->dma.rxgiants = 0; - di->dma.rxnobuf = 0; - di->dma.txnobuf = 0; + /* reset all software counters */ + pub->rxgiants = 0; + pub->rxnobuf = 0; + pub->txnobuf = 0; } static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags) @@ -1151,16 +929,15 @@ static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags) control = R_REG(&di->d64txregs->control); W_REG(&di->d64txregs->control, control | D64_XC_PD); - if (R_REG(&di->d64txregs->control) & D64_XC_PD) { + if (R_REG(&di->d64txregs->control) & D64_XC_PD) /* We *can* disable it so it is supported, * restore control register */ W_REG(&di->d64txregs->control, control); - } else { + else /* Not supported, don't allow it to be enabled */ dmactrlflags &= ~DMA_CTRL_PEN; - } } di->dma.dmactrlflags = dmactrlflags; @@ -1169,8 +946,10 @@ static uint _dma_ctrlflags(struct dma_info *di, uint mask, uint flags) } /* get the address of the var in order to change later */ -static unsigned long _dma_getvar(struct dma_info *di, const char *name) +unsigned long dma_getvar(struct dma_pub *pub, const char *name) { + struct dma_info *di = (struct dma_info *)pub; + if (!strcmp(name, "&txavail")) return (unsigned long)&(di->dma.txavail); return 0; @@ -1180,9 +959,8 @@ static u8 dma_align_sizetobits(uint size) { u8 bitpos = 0; - while (size >>= 1) { + while (size >>= 1) bitpos++; - } return bitpos; } @@ -1194,7 +972,7 @@ u8 dma_align_sizetobits(uint size) */ static void *dma_ringalloc(struct dma_info *di, u32 boundary, uint size, u16 *alignbits, uint *alloced, - dmaaddr_t *descpa) + dma_addr_t *descpa) { void *va; u32 desc_strtaddr; @@ -1218,8 +996,9 @@ static void *dma_ringalloc(struct dma_info *di, u32 boundary, uint size, /* 64-bit DMA functions */ -static void dma64_txinit(struct dma_info *di) +void dma_txinit(struct dma_pub *pub) { + struct dma_info *di = (struct dma_info *)pub; u32 control = D64_XC_XE; DMA_TRACE(("%s: dma_txinit\n", di->name)); @@ -1231,7 +1010,7 @@ static void dma64_txinit(struct dma_info *di) di->dma.txavail = di->ntxd - 1; /* clear tx descriptor ring */ - memset((void *)di->txd64, '\0', (di->ntxd * sizeof(struct dma64desc))); + memset(di->txd64, '\0', (di->ntxd * sizeof(struct dma64desc))); /* DMA engine with out alignment requirement requires table to be inited * before enabling the engine @@ -1250,17 +1029,10 @@ static void dma64_txinit(struct dma_info *di) _dma_ddtable_init(di, DMA_TX, di->txdpa); } -static bool dma64_txenabled(struct dma_info *di) +void dma_txsuspend(struct dma_pub *pub) { - u32 xc; - - /* If the chip is dead, it is not enabled :-) */ - xc = R_REG(&di->d64txregs->control); - return (xc != 0xffffffff) && (xc & D64_XC_XE); -} + struct dma_info *di = (struct dma_info *)pub; -static void dma64_txsuspend(struct dma_info *di) -{ DMA_TRACE(("%s: dma_txsuspend\n", di->name)); if (di->ntxd == 0) @@ -1269,8 +1041,10 @@ static void dma64_txsuspend(struct dma_info *di) OR_REG(&di->d64txregs->control, D64_XC_SE); } -static void dma64_txresume(struct dma_info *di) +void dma_txresume(struct dma_pub *pub) { + struct dma_info *di = (struct dma_info *)pub; + DMA_TRACE(("%s: dma_txresume\n", di->name)); if (di->ntxd == 0) @@ -1279,16 +1053,19 @@ static void dma64_txresume(struct dma_info *di) AND_REG(&di->d64txregs->control, ~D64_XC_SE); } -static bool dma64_txsuspended(struct dma_info *di) +bool dma_txsuspended(struct dma_pub *pub) { + struct dma_info *di = (struct dma_info *)pub; + return (di->ntxd == 0) || ((R_REG(&di->d64txregs->control) & D64_XC_SE) == D64_XC_SE); } -static void dma64_txreclaim(struct dma_info *di, enum txd_range range) +void dma_txreclaim(struct dma_pub *pub, enum txd_range range) { - void *p; + struct dma_info *di = (struct dma_info *)pub; + struct sk_buff *p; DMA_TRACE(("%s: dma_txreclaim %s\n", di->name, (range == DMA_RANGE_ALL) ? "all" : @@ -1299,25 +1076,13 @@ static void dma64_txreclaim(struct dma_info *di, enum txd_range range) if (di->txin == di->txout) return; - while ((p = dma64_getnexttxp(di, range))) { + while ((p = dma_getnexttxp(pub, range))) { /* For unframed data, we don't have any packets to free */ if (!(di->dma.dmactrlflags & DMA_CTRL_UNFRAMED)) brcmu_pkt_buf_free_skb(p); } } -static bool dma64_txstopped(struct dma_info *di) -{ - return ((R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK) == - D64_XS0_XS_STOPPED); -} - -static bool dma64_rxstopped(struct dma_info *di) -{ - return ((R_REG(&di->d64rxregs->status0) & D64_RS0_RS_MASK) == - D64_RS0_RS_STOPPED); -} - static bool dma64_alloc(struct dma_info *di, uint direction) { u16 size; @@ -1337,39 +1102,38 @@ static bool dma64_alloc(struct dma_info *di, uint direction) va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits, &alloced, &di->txdpaorig); if (va == NULL) { - DMA_ERROR(("%s: dma64_alloc: DMA_ALLOC_CONSISTENT(ntxd) failed\n", di->name)); + DMA_ERROR(("%s: dma64_alloc: DMA_ALLOC_CONSISTENT(ntxd)" + " failed\n", di->name)); return false; } align = (1 << align_bits); di->txd64 = (struct dma64desc *) roundup((unsigned long)va, align); di->txdalign = (uint) ((s8 *)di->txd64 - (s8 *) va); - PHYSADDRLOSET(di->txdpa, - PHYSADDRLO(di->txdpaorig) + di->txdalign); - PHYSADDRHISET(di->txdpa, PHYSADDRHI(di->txdpaorig)); + di->txdpa = di->txdpaorig + di->txdalign; di->txdalloc = alloced; } else { va = dma_ringalloc(di, D64RINGALIGN, size, &align_bits, &alloced, &di->rxdpaorig); if (va == NULL) { - DMA_ERROR(("%s: dma64_alloc: DMA_ALLOC_CONSISTENT(nrxd) failed\n", di->name)); + DMA_ERROR(("%s: dma64_alloc: DMA_ALLOC_CONSISTENT(nrxd)" + " failed\n", di->name)); return false; } align = (1 << align_bits); di->rxd64 = (struct dma64desc *) roundup((unsigned long)va, align); di->rxdalign = (uint) ((s8 *)di->rxd64 - (s8 *) va); - PHYSADDRLOSET(di->rxdpa, - PHYSADDRLO(di->rxdpaorig) + di->rxdalign); - PHYSADDRHISET(di->rxdpa, PHYSADDRHI(di->rxdpaorig)); + di->rxdpa = di->rxdpaorig + di->rxdalign; di->rxdalloc = alloced; } return true; } -static bool dma64_txreset(struct dma_info *di) +bool dma_txreset(struct dma_pub *pub) { + struct dma_info *di = (struct dma_info *)pub; u32 status; if (di->ntxd == 0) @@ -1404,8 +1168,9 @@ static bool dma64_rxidle(struct dma_info *di) (R_REG(&di->d64rxregs->ptr) & D64_RS0_CD_MASK)); } -static bool dma64_rxreset(struct dma_info *di) +bool dma_rxreset(struct dma_pub *pub) { + struct dma_info *di = (struct dma_info *)pub; u32 status; if (di->nrxd == 0) @@ -1419,132 +1184,21 @@ static bool dma64_rxreset(struct dma_info *di) return status == D64_RS0_RS_DISABLED; } -static bool dma64_rxenabled(struct dma_info *di) -{ - u32 rc; - - rc = R_REG(&di->d64rxregs->control); - return (rc != 0xffffffff) && (rc & D64_RC_RE); -} - -static bool dma64_txsuspendedidle(struct dma_info *di) -{ - - if (di->ntxd == 0) - return true; - - if (!(R_REG(&di->d64txregs->control) & D64_XC_SE)) - return 0; - - if ((R_REG(&di->d64txregs->status0) & D64_XS0_XS_MASK) == - D64_XS0_XS_IDLE) - return 1; - - return 0; -} - -/* Useful when sending unframed data. This allows us to get a progress report from the DMA. - * We return a pointer to the beginning of the DATA buffer of the current descriptor. - * If DMA is idle, we return NULL. - */ -static void *dma64_getpos(struct dma_info *di, bool direction) -{ - void *va; - bool idle; - u32 cd_offset; - - if (direction == DMA_TX) { - cd_offset = - R_REG(&di->d64txregs->status0) & D64_XS0_CD_MASK; - idle = !NTXDACTIVE(di->txin, di->txout); - va = di->txp[B2I(cd_offset, struct dma64desc)]; - } else { - cd_offset = - R_REG(&di->d64rxregs->status0) & D64_XS0_CD_MASK; - idle = !NRXDACTIVE(di->rxin, di->rxout); - va = di->rxp[B2I(cd_offset, struct dma64desc)]; - } - - /* If DMA is IDLE, return NULL */ - if (idle) { - DMA_TRACE(("%s: DMA idle, return NULL\n", __func__)); - va = NULL; - } - - return va; -} - -/* TX of unframed data - * - * Adds a DMA ring descriptor for the data pointed to by "buf". - * This is for DMA of a buffer of data and is unlike other dma TX functions - * that take a pointer to a "packet" - * Each call to this is results in a single descriptor being added for "len" bytes of - * data starting at "buf", it doesn't handle chained buffers. - */ -static int -dma64_txunframed(struct dma_info *di, void *buf, uint len, bool commit) -{ - u16 txout; - u32 flags = 0; - dmaaddr_t pa; /* phys addr */ - - txout = di->txout; - - /* return nonzero if out of tx descriptors */ - if (NEXTTXD(txout) == di->txin) - goto outoftxd; - - if (len == 0) - return 0; - - pa = pci_map_single(di->pbus, buf, len, PCI_DMA_TODEVICE); - - flags = (D64_CTRL1_SOF | D64_CTRL1_IOC | D64_CTRL1_EOF); - - if (txout == (di->ntxd - 1)) - flags |= D64_CTRL1_EOT; - - dma64_dd_upd(di, di->txd64, pa, txout, &flags, len); - - /* save the buffer pointer - used by dma_getpos */ - di->txp[txout] = buf; - - txout = NEXTTXD(txout); - /* bump the tx descriptor index */ - di->txout = txout; - - /* kick the chip */ - if (commit) { - W_REG(&di->d64txregs->ptr, - di->xmtptrbase + I2B(txout, struct dma64desc)); - } - - /* tx flow control */ - di->dma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; - - return 0; - - outoftxd: - DMA_ERROR(("%s: %s: out of txds !!!\n", di->name, __func__)); - di->dma.txavail = 0; - di->dma.txnobuf++; - return -1; -} - -/* !! tx entry routine +/* + * !! tx entry routine * WARNING: call must check the return value for error. - * the error(toss frames) could be fatal and cause many subsequent hard to debug problems + * the error(toss frames) could be fatal and cause many subsequent hard + * to debug problems */ -static int dma64_txfast(struct dma_info *di, struct sk_buff *p0, - bool commit) +int dma_txfast(struct dma_pub *pub, struct sk_buff *p0, bool commit) { + struct dma_info *di = (struct dma_info *)pub; struct sk_buff *p, *next; unsigned char *data; uint len; u16 txout; u32 flags = 0; - dmaaddr_t pa; + dma_addr_t pa; DMA_TRACE(("%s: dma_txfast\n", di->name)); @@ -1555,9 +1209,6 @@ static int dma64_txfast(struct dma_info *di, struct sk_buff *p0, * allocating and initializing transmit descriptor entries. */ for (p = p0; p; p = next) { - uint nsegs, j; - struct dma_seg_map *map; - data = p->data; len = p->len; next = p->next; @@ -1570,59 +1221,31 @@ static int dma64_txfast(struct dma_info *di, struct sk_buff *p0, continue; /* get physical address of buffer start */ - if (DMASGLIST_ENAB) - memset(&di->txp_dmah[txout], 0, - sizeof(struct dma_seg_map)); - pa = pci_map_single(di->pbus, data, len, PCI_DMA_TODEVICE); - if (DMASGLIST_ENAB) { - map = &di->txp_dmah[txout]; - - /* See if all the segments can be accounted for */ - if (map->nsegs > - (uint) (di->ntxd - NTXDACTIVE(di->txin, di->txout) - - 1)) - goto outoftxd; - - nsegs = map->nsegs; - } else - nsegs = 1; - - for (j = 1; j <= nsegs; j++) { - flags = 0; - if (p == p0 && j == 1) - flags |= D64_CTRL1_SOF; + flags = 0; + if (p == p0) + flags |= D64_CTRL1_SOF; - /* With a DMA segment list, Descriptor table is filled - * using the segment list instead of looping over - * buffers in multi-chain DMA. Therefore, EOF for SGLIST is when - * end of segment list is reached. - */ - if ((!DMASGLIST_ENAB && next == NULL) || - (DMASGLIST_ENAB && j == nsegs)) - flags |= (D64_CTRL1_IOC | D64_CTRL1_EOF); - if (txout == (di->ntxd - 1)) - flags |= D64_CTRL1_EOT; - - if (DMASGLIST_ENAB) { - len = map->segs[j - 1].length; - pa = map->segs[j - 1].addr; - } - dma64_dd_upd(di, di->txd64, pa, txout, &flags, len); + /* With a DMA segment list, Descriptor table is filled + * using the segment list instead of looping over + * buffers in multi-chain DMA. Therefore, EOF for SGLIST + * is when end of segment list is reached. + */ + if (next == NULL) + flags |= (D64_CTRL1_IOC | D64_CTRL1_EOF); + if (txout == (di->ntxd - 1)) + flags |= D64_CTRL1_EOT; - txout = NEXTTXD(txout); - } + dma64_dd_upd(di, di->txd64, pa, txout, &flags, len); - /* See above. No need to loop over individual buffers */ - if (DMASGLIST_ENAB) - break; + txout = NEXTTXD(txout); } /* if last txd eof not set, fix it */ if (!(flags & D64_CTRL1_EOF)) - W_SM(&di->txd64[PREVTXD(txout)].ctrl1, - BUS_SWAP32(flags | D64_CTRL1_IOC | D64_CTRL1_EOF)); + di->txd64[PREVTXD(txout)].ctrl1 = + cpu_to_le32(flags | D64_CTRL1_IOC | D64_CTRL1_EOF); /* save the packet */ di->txp[PREVTXD(txout)] = p0; @@ -1658,11 +1281,12 @@ static int dma64_txfast(struct dma_info *di, struct sk_buff *p0, * If range is DMA_RANGE_ALL, reclaim all txd(s) posted to the ring and * return associated packet regardless of the value of hardware pointers. */ -static void *dma64_getnexttxp(struct dma_info *di, enum txd_range range) +struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range) { + struct dma_info *di = (struct dma_info *)pub; u16 start, end, i; u16 active_desc; - void *txp; + struct sk_buff *txp; DMA_TRACE(("%s: dma_getnexttxp %s\n", di->name, (range == DMA_RANGE_ALL) ? "all" : @@ -1679,7 +1303,7 @@ static void *dma64_getnexttxp(struct dma_info *di, enum txd_range range) if (range == DMA_RANGE_ALL) end = di->txout; else { - dma64regs_t *dregs = di->d64txregs; + struct dma64regs *dregs = di->d64txregs; end = (u16) (B2I(((R_REG(&dregs->status0) & D64_XS0_CD_MASK) - @@ -1702,37 +1326,20 @@ static void *dma64_getnexttxp(struct dma_info *di, enum txd_range range) goto bogus; for (i = start; i != end && !txp; i = NEXTTXD(i)) { - dmaaddr_t pa; - struct dma_seg_map *map = NULL; - uint size, j, nsegs; - - PHYSADDRLOSET(pa, - (BUS_SWAP32(R_SM(&di->txd64[i].addrlow)) - - di->dataoffsetlow)); - PHYSADDRHISET(pa, - (BUS_SWAP32(R_SM(&di->txd64[i].addrhigh)) - - di->dataoffsethigh)); - - if (DMASGLIST_ENAB) { - map = &di->txp_dmah[i]; - size = map->origsize; - nsegs = map->nsegs; - } else { - size = - (BUS_SWAP32(R_SM(&di->txd64[i].ctrl2)) & - D64_CTRL2_BC_MASK); - nsegs = 1; - } + dma_addr_t pa; + uint size; - for (j = nsegs; j > 0; j--) { - W_SM(&di->txd64[i].addrlow, 0xdeadbeef); - W_SM(&di->txd64[i].addrhigh, 0xdeadbeef); + pa = cpu_to_le32(di->txd64[i].addrlow) - di->dataoffsetlow; - txp = di->txp[i]; - di->txp[i] = NULL; - if (j > 1) - i = NEXTTXD(i); - } + size = + (cpu_to_le32(di->txd64[i].ctrl2) & + D64_CTRL2_BC_MASK); + + di->txd64[i].addrlow = 0xdeadbeef; + di->txd64[i].addrhigh = 0xdeadbeef; + + txp = di->txp[i]; + di->txp[i] = NULL; pci_unmap_single(di->pbus, pa, size, PCI_DMA_TODEVICE); } @@ -1745,15 +1352,16 @@ static void *dma64_getnexttxp(struct dma_info *di, enum txd_range range) return txp; bogus: - DMA_NONE(("dma_getnexttxp: bogus curr: start %d end %d txout %d force %d\n", start, end, di->txout, forceall)); + DMA_NONE(("dma_getnexttxp: bogus curr: start %d end %d txout %d " + "force %d\n", start, end, di->txout, forceall)); return NULL; } -static void *dma64_getnextrxp(struct dma_info *di, bool forceall) +static struct sk_buff *dma64_getnextrxp(struct dma_info *di, bool forceall) { uint i, curr; - void *rxp; - dmaaddr_t pa; + struct sk_buff *rxp; + dma_addr_t pa; i = di->rxin; @@ -1773,25 +1381,20 @@ static void *dma64_getnextrxp(struct dma_info *di, bool forceall) rxp = di->rxp[i]; di->rxp[i] = NULL; - PHYSADDRLOSET(pa, - (BUS_SWAP32(R_SM(&di->rxd64[i].addrlow)) - - di->dataoffsetlow)); - PHYSADDRHISET(pa, - (BUS_SWAP32(R_SM(&di->rxd64[i].addrhigh)) - - di->dataoffsethigh)); + pa = cpu_to_le32(di->rxd64[i].addrlow) - di->dataoffsetlow; /* clear this packet from the descriptor ring */ pci_unmap_single(di->pbus, pa, di->rxbufsize, PCI_DMA_FROMDEVICE); - W_SM(&di->rxd64[i].addrlow, 0xdeadbeef); - W_SM(&di->rxd64[i].addrhigh, 0xdeadbeef); + di->rxd64[i].addrlow = 0xdeadbeef; + di->rxd64[i].addrhigh = 0xdeadbeef; di->rxin = NEXTRXD(i); return rxp; } -static bool _dma64_addrext(dma64regs_t *dma64regs) +static bool _dma64_addrext(struct dma64regs *dma64regs) { u32 w; OR_REG(&dma64regs->control, D64_XC_AE); @@ -1801,97 +1404,6 @@ static bool _dma64_addrext(dma64regs_t *dma64regs) } /* - * Rotate all active tx dma ring entries "forward" by (ActiveDescriptor - txin). - */ -static void dma64_txrotate(struct dma_info *di) -{ - u16 ad; - uint nactive; - uint rot; - u16 old, new; - u32 w; - u16 first, last; - - nactive = _dma_txactive(di); - ad = (u16) (B2I((((R_REG(&di->d64txregs->status1) & - D64_XS1_AD_MASK) - di->xmtptrbase) & - D64_XS1_AD_MASK), struct dma64desc)); - rot = TXD(ad - di->txin); - - /* full-ring case is a lot harder - don't worry about this */ - if (rot >= (di->ntxd - nactive)) { - DMA_ERROR(("%s: dma_txrotate: ring full - punt\n", di->name)); - return; - } - - first = di->txin; - last = PREVTXD(di->txout); - - /* move entries starting at last and moving backwards to first */ - for (old = last; old != PREVTXD(first); old = PREVTXD(old)) { - new = TXD(old + rot); - - /* - * Move the tx dma descriptor. - * EOT is set only in the last entry in the ring. - */ - w = BUS_SWAP32(R_SM(&di->txd64[old].ctrl1)) & ~D64_CTRL1_EOT; - if (new == (di->ntxd - 1)) - w |= D64_CTRL1_EOT; - W_SM(&di->txd64[new].ctrl1, BUS_SWAP32(w)); - - w = BUS_SWAP32(R_SM(&di->txd64[old].ctrl2)); - W_SM(&di->txd64[new].ctrl2, BUS_SWAP32(w)); - - W_SM(&di->txd64[new].addrlow, R_SM(&di->txd64[old].addrlow)); - W_SM(&di->txd64[new].addrhigh, R_SM(&di->txd64[old].addrhigh)); - - /* zap the old tx dma descriptor address field */ - W_SM(&di->txd64[old].addrlow, BUS_SWAP32(0xdeadbeef)); - W_SM(&di->txd64[old].addrhigh, BUS_SWAP32(0xdeadbeef)); - - /* move the corresponding txp[] entry */ - di->txp[new] = di->txp[old]; - - /* Move the map */ - if (DMASGLIST_ENAB) { - memcpy(&di->txp_dmah[new], &di->txp_dmah[old], - sizeof(struct dma_seg_map)); - memset(&di->txp_dmah[old], 0, - sizeof(struct dma_seg_map)); - } - - di->txp[old] = NULL; - } - - /* update txin and txout */ - di->txin = ad; - di->txout = TXD(di->txout + rot); - di->dma.txavail = di->ntxd - NTXDACTIVE(di->txin, di->txout) - 1; - - /* kick the chip */ - W_REG(&di->d64txregs->ptr, - di->xmtptrbase + I2B(di->txout, struct dma64desc)); -} - -uint dma_addrwidth(struct si_pub *sih, void *dmaregs) -{ - /* Perform 64-bit checks only if we want to advertise 64-bit (> 32bit) capability) */ - /* DMA engine is 64-bit capable */ - if ((ai_core_sflags(sih, 0, 0) & SISF_DMA64) == SISF_DMA64) { - /* backplane are 64-bit capable */ - if (ai_backplane64(sih)) - /* If bus is System Backplane or PCIE then we can access 64-bits */ - if ((sih->bustype == SI_BUS) || - ((sih->bustype == PCI_BUS) && - (sih->buscoretype == PCIE_CORE_ID))) - return DMADDRWIDTH_64; - } - /* DMA hardware not supported by this driver*/ - return DMADDRWIDTH_64; -} - -/* * Mac80211 initiated actions sometimes require packets in the DMA queue to be * modified. The modified portion of the packet is not under control of the DMA * engine. This function calls a caller-supplied function for each packet in diff --git a/drivers/staging/brcm80211/brcmsmac/dma.h b/drivers/staging/brcm80211/brcmsmac/dma.h index 9c8b9a6..2ce5963 100644 --- a/drivers/staging/brcm80211/brcmsmac/dma.h +++ b/drivers/staging/brcm80211/brcmsmac/dma.h @@ -17,6 +17,7 @@ #ifndef _BRCM_DMA_H_ #define _BRCM_DMA_H_ +#include <linux/delay.h> #include "types.h" /* forward structure declarations */ /* DMA structure: @@ -38,12 +39,12 @@ struct dma32diag { /* diag access */ /* 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 */ + u32 control; /* enable, et al */ + u32 ptr; /* last descriptor posted to chip */ + u32 addrlow; /* desc ring base address low 32-bits (8K aligned) */ + u32 addrhigh; /* desc ring base address bits 63:32 (8K aligned) */ + u32 status0; /* current descriptor, xmt state */ + u32 status1; /* active descriptor, xmt error */ }; /* map/unmap direction */ @@ -58,110 +59,11 @@ enum txd_range { DMA_RANGE_TRANSFERED }; -/* dma function type */ -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 dma_pub *dmah, void *p, uint len, - bool commit); -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 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 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 dma_pub *dmah, struct brcmu_strbuf *b, - bool dumpring); -typedef char *(*di_dumprx_t) (struct dma_pub *dmah, struct brcmu_strbuf *b, - bool dumpring); -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 */ -struct di_fcn_s { - di_detach_t detach; - di_txinit_t txinit; - di_txreset_t txreset; - di_txenabled_t txenabled; - di_txsuspend_t txsuspend; - di_txresume_t txresume; - di_txsuspended_t txsuspended; - di_txsuspendedidle_t txsuspendedidle; - di_txfast_t txfast; - di_txunframed_t txunframed; - di_getpos_t getpos; - di_txstopped_t txstopped; - di_txreclaim_t txreclaim; - di_getnexttxp_t getnexttxp; - di_peeknexttxp_t peeknexttxp; - di_txblock_t txblock; - di_txunblock_t txunblock; - di_txactive_t txactive; - di_txrotate_t txrotate; - - di_rxinit_t rxinit; - di_rxreset_t rxreset; - di_rxidle_t rxidle; - di_rxstopped_t rxstopped; - di_rxenable_t rxenable; - di_rxenabled_t rxenabled; - di_rx_t rx; - di_rxfill_t rxfill; - di_rxreclaim_t rxreclaim; - di_getnextrxp_t getnextrxp; - di_peeknextrxp_t peeknextrxp; - di_rxparam_get_t rxparam_get; - - di_fifoloopbackenable_t fifoloopbackenable; - di_getvar_t d_getvar; - di_counterreset_t counterreset; - di_ctrlflags_t ctrlflags; - di_dump_t dump; - di_dumptx_t dumptx; - di_dumprx_t dumprx; - di_rxactive_t rxactive; - di_txpending_t txpending; - di_txcommitted_t txcommitted; - uint endnum; -}; - /* * Exported data structure (read-only) */ /* export structure */ struct dma_pub { - const struct di_fcn_s *di_fn; /* DMA function pointers */ uint txavail; /* # free tx descriptors */ uint dmactrlflags; /* dma control flags */ @@ -177,74 +79,42 @@ extern struct dma_pub *dma_attach(char *name, struct si_pub *sih, uint nrxd, uint rxbufsize, int rxextheadroom, uint nrxpost, uint rxoffset, uint *msg_level); -extern const struct di_fcn_s dma64proc; - -#define dma_detach(di) (dma64proc.detach(di)) -#define dma_txreset(di) (dma64proc.txreset(di)) -#define dma_rxreset(di) (dma64proc.rxreset(di)) -#define dma_rxidle(di) (dma64proc.rxidle(di)) -#define dma_txinit(di) (dma64proc.txinit(di)) -#define dma_txenabled(di) (dma64proc.txenabled(di)) -#define dma_rxinit(di) (dma64proc.rxinit(di)) -#define dma_txsuspend(di) (dma64proc.txsuspend(di)) -#define dma_txresume(di) (dma64proc.txresume(di)) -#define dma_txsuspended(di) (dma64proc.txsuspended(di)) -#define dma_txsuspendedidle(di) (dma64proc.txsuspendedidle(di)) -#define dma_txfast(di, p, commit) (dma64proc.txfast(di, p, commit)) -#define dma_txunframed(di, p, l, commit)(dma64proc.txunframed(di, p, l, commit)) -#define dma_getpos(di, dir) (dma64proc.getpos(di, dir)) -#define dma_fifoloopbackenable(di) (dma64proc.fifoloopbackenable(di)) -#define dma_txstopped(di) (dma64proc.txstopped(di)) -#define dma_rxstopped(di) (dma64proc.rxstopped(di)) -#define dma_rxenable(di) (dma64proc.rxenable(di)) -#define dma_rxenabled(di) (dma64proc.rxenabled(di)) -#define dma_rx(di) (dma64proc.rx(di)) -#define dma_rxfill(di) (dma64proc.rxfill(di)) -#define dma_txreclaim(di, range) (dma64proc.txreclaim(di, range)) -#define dma_rxreclaim(di) (dma64proc.rxreclaim(di)) -#define dma_getvar(di, name) (dma64proc.d_getvar(di, name)) -#define dma_getnexttxp(di, range) (dma64proc.getnexttxp(di, range)) -#define dma_getnextrxp(di, forceall) (dma64proc.getnextrxp(di, forceall)) -#define dma_peeknexttxp(di) (dma64proc.peeknexttxp(di)) -#define dma_peeknextrxp(di) (dma64proc.peeknextrxp(di)) -#define dma_rxparam_get(di, off, bufs) (dma64proc.rxparam_get(di, off, bufs)) - -#define dma_txblock(di) (dma64proc.txblock(di)) -#define dma_txunblock(di) (dma64proc.txunblock(di)) -#define dma_txactive(di) (dma64proc.txactive(di)) -#define dma_rxactive(di) (dma64proc.rxactive(di)) -#define dma_txrotate(di) (dma64proc.txrotate(di)) -#define dma_counterreset(di) (dma64proc.counterreset(di)) -#define dma_ctrlflags(di, mask, flags) (dma64proc.ctrlflags((di), (mask), (flags))) -#define dma_txpending(di) (dma64proc.txpending(di)) -#define dma_txcommitted(di) (dma64proc.txcommitted(di)) - - -/* return addresswidth allowed - * This needs to be done after SB attach but before dma attach. - * 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(struct si_pub *sih, void *dmaregs); +void dma_rxinit(struct dma_pub *pub); +struct sk_buff *dma_rx(struct dma_pub *pub); +bool dma_rxfill(struct dma_pub *pub); +bool dma_rxreset(struct dma_pub *pub); +bool dma_txreset(struct dma_pub *pub); +void dma_txinit(struct dma_pub *pub); +int dma_txfast(struct dma_pub *pub, struct sk_buff *p0, bool commit); +void dma_txsuspend(struct dma_pub *pub); +bool dma_txsuspended(struct dma_pub *pub); +void dma_txresume(struct dma_pub *pub); +void dma_txreclaim(struct dma_pub *pub, enum txd_range range); +void dma_rxreclaim(struct dma_pub *pub); +void dma_detach(struct dma_pub *pub); +unsigned long dma_getvar(struct dma_pub *pub, const char *name); +struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range); +void dma_counterreset(struct dma_pub *pub); + void dma_walk_packets(struct dma_pub *dmah, void (*callback_fnc) (void *pkt, void *arg_a), void *arg_a); /* - * DMA(Bug) on some chips seems to declare that the packet is ready, but the - * packet length is not updated yet (by DMA) on the expected time. + * DMA(Bug) on bcm47xx chips seems to declare that the packet is ready, but + * the packet length is not updated yet (by DMA) on the expected time. * Workaround is to hold processor till DMA updates the length, and stay off * the bus to allow DMA update the length in buffer */ static inline void dma_spin_for_len(uint len, struct sk_buff *head) { -#if defined(__mips__) +#if defined(CONFIG_BCM47XX) if (!len) { while (!(len = *(u16 *) KSEG1ADDR(head->data))) udelay(1); *(u16 *) (head->data) = cpu_to_le16((u16) len); } -#endif /* defined(__mips__) */ +#endif /* defined(CONFIG_BCM47XX) */ } #endif /* _BRCM_DMA_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/mac80211_if.c b/drivers/staging/brcm80211/brcmsmac/mac80211_if.c index d6de44e..01829db 100644 --- a/drivers/staging/brcm80211/brcmsmac/mac80211_if.c +++ b/drivers/staging/brcm80211/brcmsmac/mac80211_if.c @@ -61,8 +61,6 @@ static void _brcms_timer(struct brcms_timer *t); static int ieee_hw_init(struct ieee80211_hw *hw); static int ieee_hw_rate_init(struct ieee80211_hw *hw); -static int wl_linux_watchdog(void *ctx); - /* Flags we support */ #define MAC_FILTERS (FIF_PROMISC_IN_BSS | \ FIF_ALLMULTI | \ @@ -85,7 +83,8 @@ static int __devinit brcms_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent); static void brcms_remove(struct pci_dev *pdev); static void brcms_free(struct brcms_info *wl); -static void brcms_set_basic_rate(struct wl_rateset *rs, u16 rate, bool is_br); +static void brcms_set_basic_rate(struct brcm_rateset *rs, u16 rate, + bool is_br); MODULE_AUTHOR("Broadcom Corporation"); MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver."); @@ -94,11 +93,10 @@ MODULE_LICENSE("Dual BSD/GPL"); /* recognized PCI IDs */ static DEFINE_PCI_DEVICE_TABLE(brcms_pci_id_table) = { - {PCI_VENDOR_ID_BROADCOM, 0x4357, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* 43225 2G */ - {PCI_VENDOR_ID_BROADCOM, 0x4353, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* 43224 DUAL */ - {PCI_VENDOR_ID_BROADCOM, 0x4727, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* 4313 DUAL */ - /* 43224 Ven */ - {PCI_VENDOR_ID_BROADCOM, 0x0576, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) }, /* 43225 2G */ + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4353) }, /* 43224 DUAL */ + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) }, /* 4313 DUAL */ + { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x0576) }, /* 43224 Ven */ {0} }; @@ -107,8 +105,6 @@ MODULE_DEVICE_TABLE(pci, brcms_pci_id_table); #ifdef BCMDBG static int msglevel = 0xdeadbeef; module_param(msglevel, int, 0); -static int phymsglevel = 0xdeadbeef; -module_param(phymsglevel, int, 0); #endif /* BCMDBG */ #define HW_TO_WL(hw) (hw->priv) @@ -216,10 +212,10 @@ brcms_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) err = brcms_up(wl); UNLOCK(wl); - if (err != 0) { + if (err != 0) wiphy_err(hw->wiphy, "%s: brcms_up() returned %d\n", __func__, err); - } + return err; } @@ -306,9 +302,9 @@ static int brcms_ops_config(struct ieee80211_hw *hw, u32 changed) "\n", __func__, conf->power_level * 4, new_int); } - if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { + if (changed & IEEE80211_CONF_CHANGE_CHANNEL) err = ieee_set_channel(hw, conf->channel, conf->channel_type); - } + if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) { if (brcms_c_set (wl->wlc, BRCM_SET_SRL, @@ -377,7 +373,7 @@ brcms_ops_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_supported_band *bi; u32 br_mask, i; u16 rate; - struct wl_rateset rs; + struct brcm_rateset rs; int error; /* retrieve the current rates */ @@ -419,32 +415,36 @@ brcms_ops_bss_info_changed(struct ieee80211_hw *hw, info->bssid); UNLOCK(wl); } - if (changed & BSS_CHANGED_BEACON) { + if (changed & BSS_CHANGED_BEACON) /* Beacon data changed, retrieve new beacon (beaconing modes) */ wiphy_err(wiphy, "%s: beacon changed\n", __func__); - } + if (changed & BSS_CHANGED_BEACON_ENABLED) { /* Beaconing should be enabled/disabled (beaconing modes) */ wiphy_err(wiphy, "%s: Beacon enabled: %s\n", __func__, info->enable_beacon ? "true" : "false"); } + if (changed & BSS_CHANGED_CQM) { /* Connection quality monitor config changed */ wiphy_err(wiphy, "%s: cqm change: threshold %d, hys %d " " (implement)\n", __func__, info->cqm_rssi_thold, info->cqm_rssi_hyst); } + if (changed & BSS_CHANGED_IBSS) { /* IBSS join status changed */ wiphy_err(wiphy, "%s: IBSS joined: %s (implement)\n", __func__, info->ibss_joined ? "true" : "false"); } + if (changed & BSS_CHANGED_ARP_FILTER) { /* Hardware ARP filter address list or state changed */ wiphy_err(wiphy, "%s: arp filtering: enabled %s, count %d" " (implement)\n", __func__, info->arp_filter_enabled ? "true" : "false", info->arp_addr_cnt); } + if (changed & BSS_CHANGED_QOS) { /* * QoS for this association was enabled/disabled. @@ -602,7 +602,10 @@ brcms_ops_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT; - /* minstrel_ht initiates addBA on our behalf by calling ieee80211_start_tx_ba_session() */ + /* + * minstrel_ht initiates addBA on our behalf by calling + * ieee80211_start_tx_ba_session() + */ return 0; } @@ -640,7 +643,10 @@ brcms_ops_ampdu_action(struct ieee80211_hw *hw, tid); return -EINVAL; } - /* Future improvement: Use the starting sequence number provided ... */ + /* + * Future improvement: + * Use the starting sequence number provided ... + */ *ssn = 0; ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); break; @@ -744,21 +750,19 @@ static int brcms_set_hint(struct brcms_info *wl, char *abbrev) * is called in brcms_pci_probe() context, therefore no locking required. */ static struct brcms_info *brcms_attach(u16 vendor, u16 device, - unsigned long regs, - uint bustype, void *btparam, uint irq) + resource_size_t regs, + struct pci_dev *btparam, uint irq) { struct brcms_info *wl = NULL; int unit, err; - unsigned long base_addr; struct ieee80211_hw *hw; u8 perm[ETH_ALEN]; unit = n_adapters_found; err = 0; - if (unit < 0) { + if (unit < 0) return NULL; - } /* allocate private info */ hw = pci_get_drvdata(btparam); /* btparam == pdev */ @@ -773,19 +777,7 @@ static struct brcms_info *brcms_attach(u16 vendor, u16 device, /* setup the bottom half handler */ tasklet_init(&wl->tasklet, brcms_dpc, (unsigned long) wl); - - - base_addr = regs; - - if (bustype == PCI_BUS || bustype == RPC_BUS) { - /* Do nothing */ - } else { - bustype = PCI_BUS; - BCMMSG(wl->wiphy, "force to PCI\n"); - } - wl->bcm_bustype = bustype; - - wl->regsva = ioremap_nocache(base_addr, PCI_BAR0_WINSZ); + wl->regsva = ioremap_nocache(regs, PCI_BAR0_WINSZ); if (wl->regsva == NULL) { wiphy_err(wl->wiphy, "wl%d: ioremap() failed\n", unit); goto fail; @@ -794,17 +786,17 @@ static struct brcms_info *brcms_attach(u16 vendor, u16 device, spin_lock_init(&wl->isr_lock); /* prepare ucode */ - if (brcms_request_fw(wl, (struct pci_dev *)btparam) < 0) { + if (brcms_request_fw(wl, btparam) < 0) { wiphy_err(wl->wiphy, "%s: Failed to find firmware usually in " "%s\n", KBUILD_MODNAME, "/lib/firmware/brcm"); brcms_release_fw(wl); - brcms_remove((struct pci_dev *)btparam); + brcms_remove(btparam); return NULL; } /* common load-time initialization */ - wl->wlc = brcms_c_attach((void *)wl, vendor, device, unit, false, - wl->regsva, wl->bcm_bustype, btparam, &err); + wl->wlc = brcms_c_attach(wl, vendor, device, unit, false, + wl->regsva, btparam, &err); brcms_release_fw(wl); if (!wl->wlc) { wiphy_err(wl->wiphy, "%s: attach() failed with code %d\n", @@ -815,10 +807,9 @@ static struct brcms_info *brcms_attach(u16 vendor, u16 device, wl->pub->ieee_hw = hw; - if (brcms_c_set_par(wl->wlc, IOV_MPC, 0) < 0) { + if (brcms_c_set_par(wl->wlc, IOV_MPC, 0) < 0) wiphy_err(wl->wiphy, "wl%d: Error setting MPC variable to 0\n", unit); - } /* register our interrupt handler */ if (request_irq(irq, brcms_isr, IRQF_SHARED, KBUILD_MODNAME, wl)) { @@ -828,7 +819,7 @@ static struct brcms_info *brcms_attach(u16 vendor, u16 device, wl->irq = irq; /* register module */ - brcms_c_module_register(wl->pub, "linux", wl, wl_linux_watchdog, NULL); + brcms_c_module_register(wl->pub, "linux", wl, NULL); if (ieee_hw_init(hw)) { wiphy_err(wl->wiphy, "wl%d: %s: ieee_hw_init failed!\n", unit, @@ -842,19 +833,17 @@ static struct brcms_info *brcms_attach(u16 vendor, u16 device, SET_IEEE80211_PERM_ADDR(hw, perm); err = ieee80211_register_hw(hw); - if (err) { + if (err) wiphy_err(wl->wiphy, "%s: ieee80211_register_hw failed, status" "%d\n", __func__, err); - } if (wl->pub->srom_ccode[0]) err = brcms_set_hint(wl, wl->pub->srom_ccode); else err = brcms_set_hint(wl, "US"); - if (err) { + if (err) wiphy_err(wl->wiphy, "%s: regulatory_hint failed, status %d\n", __func__, err); - } n_adapters_found++; return wl; @@ -975,6 +964,10 @@ static struct ieee80211_channel brcms_5ghz_nphy_chantable[] = { .hw_value = (rate100m / 5), \ } +/* + * The rate table is used for both 2.4G and 5G rates. The + * latter being a subset as it does not support CCK rates. + */ static struct ieee80211_rate legacy_ratetable[] = { RATE(10, 0), RATE(20, IEEE80211_RATE_SHORT_PREAMBLE), @@ -1016,11 +1009,13 @@ static struct ieee80211_supported_band brcms_band_5GHz_nphy = { .band = IEEE80211_BAND_5GHZ, .channels = brcms_5ghz_nphy_chantable, .n_channels = ARRAY_SIZE(brcms_5ghz_nphy_chantable), - .bitrates = legacy_ratetable + 4, - .n_bitrates = ARRAY_SIZE(legacy_ratetable) - 4, + .bitrates = legacy_ratetable + BRCMS_LEGACY_5G_RATE_OFFSET, + .n_bitrates = ARRAY_SIZE(legacy_ratetable) - + BRCMS_LEGACY_5G_RATE_OFFSET, .ht_cap = { - /* use IEEE80211_HT_CAP_* from include/linux/ieee80211.h */ - .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT, /* No 40 mhz yet */ + .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 | + IEEE80211_HT_CAP_SGI_40 | + IEEE80211_HT_CAP_40MHZ_INTOLERANT, /* No 40 mhz yet */ .ht_supported = true, .ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K, .ampdu_density = AMPDU_DEF_MPDU_DENSITY, @@ -1063,12 +1058,11 @@ static int ieee_hw_rate_init(struct ieee80211_hw *hw) /* Assume all bands use the same phy. True for 11n devices. */ if (NBANDS_PUB(wl->pub) > 1) { has_5g++; - if (phy_list[0] == 'n' || phy_list[0] == 'c') { + if (phy_list[0] == 'n' || phy_list[0] == 'c') hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &brcms_band_5GHz_nphy; - } else { + else return -EPERM; - } } return 0; } @@ -1087,7 +1081,8 @@ static int ieee_hw_init(struct ieee80211_hw *hw) hw->queues = N_TX_QUEUES; hw->max_rates = 2; /* Primary rate and 1 fallback rate */ - hw->channel_change_time = 7 * 1000; /* channel change time is dependent on chip and band */ + /* channel change time is dependent on chip and band */ + hw->channel_change_time = 7 * 1000; hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); hw->rate_control_algorithm = "minstrel_ht"; @@ -1149,7 +1144,7 @@ brcms_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) memset(hw->priv, 0, sizeof(*wl)); wl = brcms_attach(pdev->vendor, pdev->device, - pci_resource_start(pdev, 0), PCI_BUS, pdev, + pci_resource_start(pdev, 0), pdev, pdev->irq); if (!wl) { @@ -1285,8 +1280,6 @@ static int __init brcms_module_init(void) #ifdef BCMDBG if (msglevel != 0xdeadbeef) brcm_msg_level = msglevel; - if (phymsglevel != 0xdeadbeef) - phyhal_msg_level = phymsglevel; #endif /* BCMDBG */ error = pci_register_driver(&brcms_pci_driver); @@ -1336,9 +1329,8 @@ static void brcms_free(struct brcms_info *wl) /* kill dpc */ tasklet_kill(&wl->tasklet); - if (wl->pub) { + if (wl->pub) brcms_c_module_unregister(wl->pub, "linux", wl); - } /* free common resources */ if (wl->wlc) { @@ -1363,18 +1355,18 @@ static void brcms_free(struct brcms_info *wl) } /* - * unregister_netdev() calls get_stats() which may read chip registers - * so we cannot unmap the chip registers until after calling unregister_netdev() . + * unregister_netdev() calls get_stats() which may read chip + * registers so we cannot unmap the chip registers until + * after calling unregister_netdev() . */ - if (wl->regsva && wl->bcm_bustype != SDIO_BUS && - wl->bcm_bustype != JTAG_BUS) { + if (wl->regsva) iounmap((void *)wl->regsva); - } + wl->regsva = NULL; } /* flags the given rate in rateset as requested */ -static void brcms_set_basic_rate(struct wl_rateset *rs, u16 rate, bool is_br) +static void brcms_set_basic_rate(struct brcm_rateset *rs, u16 rate, bool is_br) { u32 i; @@ -1437,14 +1429,6 @@ void brcms_intrson(struct brcms_info *wl) INT_UNLOCK(wl, flags); } -/* - * precondition: perimeter lock has been acquired - */ -bool wl_alloc_dma_resources(struct brcms_info *wl, uint addrwidth) -{ - return true; -} - u32 brcms_intrsoff(struct brcms_info *wl) { unsigned long flags; @@ -1557,10 +1541,9 @@ static void brcms_dpc(unsigned long data) /* re-schedule dpc */ if (wl->resched) tasklet_schedule(&wl->tasklet); - else { + else /* re-enable interrupts */ brcms_intrson(wl); - } done: UNLOCK(wl); @@ -1635,7 +1618,8 @@ struct brcms_timer *brcms_init_timer(struct brcms_info *wl, return t; } -/* BMAC_NOTE: Add timer adds only the kernel timer since it's going to be more accurate +/* + * adds only the kernel timer since it's going to be more accurate * as well as it's easier to make it periodic * * precondition: perimeter lock has been acquired @@ -1644,10 +1628,10 @@ void brcms_add_timer(struct brcms_info *wl, struct brcms_timer *t, uint ms, int periodic) { #ifdef BCMDBG - if (t->set) { + if (t->set) wiphy_err(wl->wiphy, "%s: Already set. Name: %s, per %d\n", __func__, t->name, periodic); - } + #endif t->ms = ms; t->periodic = (bool) periodic; @@ -1667,9 +1651,9 @@ bool brcms_del_timer(struct brcms_info *wl, struct brcms_timer *t) { if (t->set) { t->set = false; - if (!del_timer(&t->timer)) { + if (!del_timer(&t->timer)) return false; - } + atomic_dec(&wl->callbacks); } @@ -1711,16 +1695,6 @@ void brcms_free_timer(struct brcms_info *wl, struct brcms_timer *t) } -/* - * runs in software irq context - * - * precondition: perimeter lock is not acquired - */ -static int wl_linux_watchdog(void *ctx) -{ - return 0; -} - struct firmware_hdr { u32 offset; u32 len; @@ -1744,15 +1718,17 @@ int brcms_ucode_init_buf(struct brcms_info *wl, void **pbuf, u32 idx) hdr = (struct firmware_hdr *)wl->fw.fw_hdr[i]->data; for (entry = 0; entry < wl->fw.hdr_num_entries[i]; entry++, hdr++) { - if (hdr->idx == idx) { - pdata = wl->fw.fw_bin[i]->data + hdr->offset; - *pbuf = kmalloc(hdr->len, GFP_ATOMIC); + u32 len = le32_to_cpu(hdr->len); + if (le32_to_cpu(hdr->idx) == idx) { + pdata = wl->fw.fw_bin[i]->data + + le32_to_cpu(hdr->offset); + *pbuf = kmalloc(len, GFP_ATOMIC); if (*pbuf == NULL) { wiphy_err(wl->wiphy, "fail to alloc %d" - " bytes\n", hdr->len); + " bytes\n", len); goto fail; } - memcpy(*pbuf, pdata, hdr->len); + memcpy(*pbuf, pdata, len); return 0; } } @@ -1777,14 +1753,15 @@ int brcms_ucode_init_uint(struct brcms_info *wl, u32 *data, u32 idx) hdr = (struct firmware_hdr *)wl->fw.fw_hdr[i]->data; for (entry = 0; entry < wl->fw.hdr_num_entries[i]; entry++, hdr++) { - if (hdr->idx == idx) { - pdata = wl->fw.fw_bin[i]->data + hdr->offset; - if (hdr->len != 4) { + if (le32_to_cpu(hdr->idx) == idx) { + pdata = wl->fw.fw_bin[i]->data + + le32_to_cpu(hdr->offset); + if (le32_to_cpu(hdr->len) != 4) { wiphy_err(wl->wiphy, "ERROR: fw hdr len\n"); return -ENOMSG; } - *data = *((u32 *) pdata); + *data = le32_to_cpu(*((u32 *) pdata)); return 0; } } @@ -1804,7 +1781,7 @@ static int brcms_request_fw(struct brcms_info *wl, struct pci_dev *pdev) char fw_name[100]; int i; - memset((void *)&wl->fw, 0, sizeof(struct brcms_firmware)); + memset(&wl->fw, 0, sizeof(struct brcms_firmware)); for (i = 0; i < MAX_FW_IMAGES; i++) { if (brcms_firmwares[i] == NULL) break; @@ -1890,7 +1867,8 @@ int brcms_check_firmwares(struct brcms_info *wl) ucode_hdr = (struct firmware_hdr *)fw_hdr->data; for (entry = 0; entry < wl->fw.hdr_num_entries[i] && !rc; entry++, ucode_hdr++) { - if (ucode_hdr->offset + ucode_hdr->len > + if (le32_to_cpu(ucode_hdr->offset) + + le32_to_cpu(ucode_hdr->len) > fw->size) { wiphy_err(wl->wiphy, "%s: conflicting bin/hdr\n", diff --git a/drivers/staging/brcm80211/brcmsmac/mac80211_if.h b/drivers/staging/brcm80211/brcmsmac/mac80211_if.h index 40e3d37..1d52803 100644 --- a/drivers/staging/brcm80211/brcmsmac/mac80211_if.h +++ b/drivers/staging/brcm80211/brcmsmac/mac80211_if.h @@ -20,14 +20,15 @@ #include <linux/timer.h> #include <linux/interrupt.h> +/* + * Starting index for 5G rates in the + * legacy rate table. + */ +#define BRCMS_LEGACY_5G_RATE_OFFSET 4 + /* softmac ioctl definitions */ #define BRCMS_SET_SHORTSLOT_OVERRIDE 146 - -/* BMAC Note: High-only driver is no longer working in softirq context as it needs to block and - * 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 brcms_timer { struct timer_list timer; struct brcms_info *wl; @@ -57,7 +58,7 @@ struct brcms_firmware { struct brcms_info { struct brcms_pub *pub; /* pointer to public wlc state */ - void *wlc; /* pointer to private common os-independent data */ + struct brcms_c_info *wlc; /* pointer to private common data */ u32 magic; int irq; @@ -65,8 +66,7 @@ struct brcms_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 */ + /* regsva for unmap in brcms_free() */ void *regsva; /* opaque chip registers virtual address */ /* timer related fields */ @@ -75,9 +75,6 @@ struct brcms_info { 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 brcms_firmware fw; struct wiphy *wiphy; }; @@ -92,7 +89,6 @@ 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); /* timer functions */ diff --git a/drivers/staging/brcm80211/brcmsmac/main.c b/drivers/staging/brcm80211/brcmsmac/main.c index 1763c45..3aa0309 100644 --- a/drivers/staging/brcm80211/brcmsmac/main.c +++ b/drivers/staging/brcm80211/brcmsmac/main.c @@ -15,22 +15,24 @@ */ #include <linux/pci_ids.h> +#include <linux/if_ether.h> #include <net/mac80211.h> - #include <brcm_hw_ids.h> #include <aiutils.h> +#include <chipcommon.h> #include "rate.h" #include "scb.h" #include "phy/phy_hal.h" #include "channel.h" -#include "bmac.h" #include "antsel.h" #include "stf.h" #include "ampdu.h" #include "alloc.h" #include "mac80211_if.h" +#include "ucode_loader.h" #include "main.h" + /* * WPA(2) definitions */ @@ -51,8 +53,10 @@ */ #define SSID_FMT_BUF_LEN ((4 * IEEE80211_MAX_SSID_LEN) + 1) -#define TIMER_INTERVAL_WATCHDOG 1000 /* watchdog timer, in unit of ms */ -#define TIMER_INTERVAL_RADIOCHK 800 /* radio monitor timer, in unit of ms */ +/* watchdog timer, in unit of ms */ +#define TIMER_INTERVAL_WATCHDOG 1000 +/* radio monitor timer, in unit of ms */ +#define TIMER_INTERVAL_RADIOCHK 800 /* Max MPC timeout, in unit of watchdog */ #ifndef BRCMS_MPC_MAX_DELAYCNT @@ -63,12 +67,16 @@ #define BRCMS_MPC_MIN_DELAYCNT 1 #define BRCMS_MPC_THRESHOLD 3 /* MPC count threshold level */ -#define BEACON_INTERVAL_DEFAULT 100 /* beacon interval, in unit of 1024TU */ -#define DTIM_INTERVAL_DEFAULT 3 /* DTIM interval, in unit of beacon interval */ +/* beacon interval, in unit of 1024TU */ +#define BEACON_INTERVAL_DEFAULT 100 +/* DTIM interval, in unit of beacon interval */ +#define DTIM_INTERVAL_DEFAULT 3 /* Scale down delays to accommodate QT slow speed */ -#define BEACON_INTERVAL_DEF_QT 20 /* beacon interval, in unit of 1024TU */ -#define DTIM_INTERVAL_DEF_QT 1 /* DTIM interval, in unit of beacon interval */ +/* beacon interval, in unit of 1024TU */ +#define BEACON_INTERVAL_DEF_QT 20 +/* DTIM interval, in unit of beacon interval */ +#define DTIM_INTERVAL_DEF_QT 1 #define TBTT_ALIGN_LEEWAY_US 100 /* min leeway before first TBTT in us */ @@ -161,34 +169,31 @@ #define AC_VO 3 /* - * driver maintains internal 'tick'(wlc->pub->now) which increments in 1s OS timer(soft - * watchdog) it is not a wall clock and won't increment when driver is in "down" state - * this low resolution driver tick can be used for maintenance tasks such as phy - * calibration and scb update + * driver maintains internal 'tick'(wlc->pub->now) which increments in 1s + * OS timer(soft watchdog) it is not a wall clock and won't increment when + * driver is in "down" state this low resolution driver tick can be used + * for maintenance tasks such as phy calibration and scb update */ -/* To inform the ucode of the last mcast frame posted so that it can clear moredata bit */ +/* + * To inform the ucode of the last mcast frame posted + * so that it can clear moredata bit + */ #define BCMCFID(wlc, fid) brcms_b_write_shm((wlc)->hw, M_BCMC_FID, (fid)) -#define BRCMS_WAR16165(wlc) (wlc->pub->sih->bustype == PCI_BUS && \ - (!AP_ENAB(wlc->pub)) && (wlc->war16165)) - -/* debug/trace */ -uint brcm_msg_level = -#if defined(BCMDBG) - LOG_ERROR_VAL; -#else - 0; -#endif /* BCMDBG */ +#define BRCMS_WAR16165(wlc) ((!AP_ENAB(wlc->pub)) && (wlc->war16165)) /* Find basic rate for a given rate */ -#define BRCMS_BASIC_RATE(wlc, rspec) (IS_MCS(rspec) ? \ - (wlc)->band->basic_rate[mcs_table[rspec & RSPEC_RATE_MASK].leg_ofdm] : \ - (wlc)->band->basic_rate[rspec & RSPEC_RATE_MASK]) +#define BRCMS_BASIC_RATE(wlc, rspec) \ + (IS_MCS(rspec) \ + ? (wlc)->band->basic_rate[mcs_table[rspec & RSPEC_RATE_MASK].leg_ofdm] \ + : (wlc)->band->basic_rate[rspec & RSPEC_RATE_MASK]) -#define FRAMETYPE(r, mimoframe) (IS_MCS(r) ? mimoframe : (IS_CCK(r) ? FT_CCK : FT_OFDM)) +#define FRAMETYPE(r, mimoframe) \ + (IS_MCS(r) ? mimoframe : (IS_CCK(r) ? FT_CCK : FT_OFDM)) -#define RFDISABLE_DEFAULT 10000000 /* rfdisable delay timer 500 ms, runs of ALP clock */ +/* rfdisable delay timer 500 ms, runs of ALP clock */ +#define RFDISABLE_DEFAULT 10000000 #define BRCMS_TEMPSENSE_PERIOD 10 /* 10 second timeout */ @@ -196,26 +201,11 @@ uint brcm_msg_level = #define EPI_VERSION_NUM 0x054b0b00 -#ifdef BCMDBG -/* pointer to most recently allocated wl/wlc */ -static struct brcms_c_info *wlc_info_dbg = (struct brcms_c_info *) (NULL); -#endif - -const u8 prio2fifo[NUMPRIO] = { - TX_AC_BE_FIFO, /* 0 BE AC_BE Best Effort */ - TX_AC_BK_FIFO, /* 1 BK AC_BK Background */ - TX_AC_BK_FIFO, /* 2 -- AC_BK Background */ - TX_AC_BE_FIFO, /* 3 EE AC_BE Best Effort */ - TX_AC_VI_FIFO, /* 4 CL AC_VI Video */ - TX_AC_VI_FIFO, /* 5 VI AC_VI Video */ - TX_AC_VO_FIFO, /* 6 VO AC_VO Voice */ - TX_AC_VO_FIFO /* 7 NC AC_VO Voice */ -}; - /* precedences numbers for wlc queues. These are twice as may levels as * 802.1D priorities. * Odd numbers are used for HI priority traffic at same precedence levels - * These constants are used ONLY by wlc_prio2prec_map. Do not use them elsewhere. + * These constants are used ONLY by wlc_prio2prec_map. Do not use them + * elsewhere. */ #define _BRCMS_PREC_NONE 0 /* None = - */ #define _BRCMS_PREC_BK 2 /* BK - Background */ @@ -238,58 +228,158 @@ const u8 prio2fifo[NUMPRIO] = { #define MBSS_PRB_ENAB(cfg) 0 #define SOFTBCN_ENAB(pub) (0) -/* 802.1D Priority to precedence queue mapping */ -const u8 wlc_prio2prec_map[] = { - _BRCMS_PREC_BE, /* 0 BE - Best-effort */ - _BRCMS_PREC_BK, /* 1 BK - Background */ - _BRCMS_PREC_NONE, /* 2 None = - */ - _BRCMS_PREC_EE, /* 3 EE - Excellent-effort */ - _BRCMS_PREC_CL, /* 4 CL - Controlled Load */ - _BRCMS_PREC_VI, /* 5 Vi - Video */ - _BRCMS_PREC_VO, /* 6 Vo - Voice */ - _BRCMS_PREC_NC, /* 7 NC - Network Control */ -}; +#define SYNTHPU_DLY_APHY_US 3700 /* a phy synthpu_dly time in us */ +#define SYNTHPU_DLY_BPHY_US 1050 /* b/g phy synthpu_dly time in us */ +#define SYNTHPU_DLY_NPHY_US 2048 /* n phy REV3 synthpu_dly time in us */ +#define SYNTHPU_DLY_LPPHY_US 300 /* lpphy synthpu_dly time in us */ + +#define SYNTHPU_DLY_PHY_US_QT 100 /* QT synthpu_dly time in us */ + +#define ANTCNT 10 /* vanilla M_MAX_ANTCNT value */ + +#define DMAREG(wlc_hw, direction, fifonum) \ + ((direction == DMA_TX) ? \ + &(wlc_hw->regs->fifo64regs[fifonum].dmaxmt) : \ + &(wlc_hw->regs->fifo64regs[fifonum].dmarcv)) + +#define APHY_SLOT_TIME 9 +#define BPHY_SLOT_TIME 20 + +/* + * The following table lists the buffer memory allocated to xmt fifos in HW. + * the size is in units of 256bytes(one block), total size is HW dependent + * ucode has default fifo partition, sw can overwrite if necessary + * + * This is documented in twiki under the topic UcodeTxFifo. Please ensure + * the twiki is updated before making changes. + */ + +/* Starting corerev for the fifo size table */ +#define XMTFIFOTBL_STARTREV 20 /* Check if a particular BSS config is AP or STA */ #define BSSCFG_AP(cfg) (0) #define BSSCFG_STA(cfg) (1) #define BSSCFG_IBSS(cfg) (!(cfg)->BSS) -/* As above for all non-NULL BSS configs */ +/* iterate through all valid bsscfg entries */ #define FOREACH_BSS(wlc, idx, cfg) \ - for (idx = 0; (int) idx < BRCMS_MAXBSSCFG; idx++) \ - if ((cfg = (wlc)->bsscfg[idx])) - -/* TX FIFO number to WME/802.1E Access Category */ -const u8 wme_fifo2ac[] = { AC_BK, AC_BE, AC_VI, AC_VO, AC_BE, AC_BE }; - -/* WME/802.1E Access Category to TX FIFO number */ -static const u8 wme_ac2fifo[] = { 1, 0, 2, 3 }; - -static bool in_send_q; + for (idx = 0; (int) idx < BRCMS_MAXBSSCFG; idx++) { \ + cfg = (wlc)->bsscfg[idx]; \ + if (!cfg) \ + continue; +/* close marker for iterator code block */ +#define END_FOREACH_BSS() } /* Shared memory location index for various AC params */ #define wme_shmemacindex(ac) wme_ac2fifo[ac] -#ifdef BCMDBG -static const char * const fifo_names[] = { - "AC_BK", "AC_BE", "AC_VI", "AC_VO", "BCMC", "ATIM" }; -#else -static const char fifo_names[6][0]; -#endif - -static const u8 acbitmap2maxprio[] = { - PRIO_8021D_BE, PRIO_8021D_BE, PRIO_8021D_BK, PRIO_8021D_BK, - PRIO_8021D_VI, PRIO_8021D_VI, PRIO_8021D_VI, PRIO_8021D_VI, - PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, - PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO -}; - /* currently the best mechanism for determining SIFS is the band in use */ #define SIFS(band) ((band)->bandtype == BRCM_BAND_5G ? APHY_SIFS_TIME : \ BPHY_SIFS_TIME); +/* 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 */ +}; + /* local prototypes */ +static void brcms_b_clkctl_clk(struct brcms_hardware *wlc, uint mode); + +/* used by wlc_wakeucode_init() */ +static void brcms_c_write_inits(struct brcms_hardware *wlc_hw, + const struct d11init *inits); +static void brcms_ucode_write(struct brcms_hardware *wlc_hw, const u32 ucode[], + const uint nbytes); +static void brcms_ucode_download(struct brcms_hardware *wlc); +static void brcms_c_ucode_txant_set(struct brcms_hardware *wlc_hw); + +/* used by brcms_c_down() */ +static void brcms_c_flushqueues(struct brcms_c_info *wlc); + +static void brcms_c_write_mhf(struct brcms_hardware *wlc_hw, u16 *mhfs); +static void brcms_c_mctrl_reset(struct brcms_hardware *wlc_hw); +static void brcms_b_corerev_fifofixup(struct brcms_hardware *wlc_hw); +static bool brcms_b_tx_fifo_suspended(struct brcms_hardware *wlc_hw, + uint tx_fifo); +static void brcms_b_tx_fifo_resume(struct brcms_hardware *wlc_hw, + uint tx_fifo); + +/* Low Level Prototypes */ + +struct brcms_b_state; + +static int brcms_b_attach(struct brcms_c_info *wlc, u16 vendor, u16 device, + uint unit, bool piomode, void *regsva, + struct pci_dev *btparam); + +/* up/down, reset, clk */ +static void brcms_b_reset(struct brcms_hardware *wlc_hw); +static int brcms_b_state_get(struct brcms_hardware *wlc_hw, + struct brcms_b_state *state); +static void brcms_b_copyfrom_vars(struct brcms_hardware *wlc_hw, char **buf, + uint *len); + +static void brcms_b_hw_etheraddr(struct brcms_hardware *wlc_hw, + u8 *ea); + +static bool brcms_b_radio_read_hwdisabled(struct brcms_hardware *wlc_hw); +static void brcms_b_wait_for_wake(struct brcms_hardware *wlc_hw); + +static void brcms_b_set_addrmatch(struct brcms_hardware *wlc_hw, + int match_reg_offset, + const u8 *addr); +static void brcms_b_set_cwmin(struct brcms_hardware *wlc_hw, u16 newmin); +static void brcms_b_set_cwmax(struct brcms_hardware *wlc_hw, u16 newmax); + +static void brcms_b_retrylimit_upd(struct brcms_hardware *wlc_hw, u16 SRL, + u16 LRL); + +static void brcms_b_fifoerrors(struct brcms_hardware *wlc_hw); + +static void brcms_b_pllreq(struct brcms_hardware *wlc_hw, bool set, + u32 req_bit); +static void brcms_b_antsel_set(struct brcms_hardware *wlc_hw, + u32 antsel_avail); +static int brcms_b_bandtype(struct brcms_hardware *wlc_hw); +static void brcms_b_info_init(struct brcms_hardware *wlc_hw); +static void brcms_b_xtal(struct brcms_hardware *wlc_hw, bool want); +static u16 brcms_b_read_objmem(struct brcms_hardware *wlc_hw, uint offset, + u32 sel); +static void brcms_b_write_objmem(struct brcms_hardware *wlc_hw, uint offset, + u16 v, u32 sel); +static void brcms_b_core_phy_clk(struct brcms_hardware *wlc_hw, bool clk); +static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme); +static void brcms_b_detach_dmapio(struct brcms_hardware *wlc_hw); +static void brcms_c_ucode_bsinit(struct brcms_hardware *wlc_hw); +static bool brcms_c_validboardtype(struct brcms_hardware *wlc); +static bool brcms_c_isgoodchip(struct brcms_hardware *wlc_hw); +static bool brcms_b_validate_chip_access(struct brcms_hardware *wlc_hw); +static char *brcms_c_get_macaddr(struct brcms_hardware *wlc_hw); +static void brcms_c_mhfdef(struct brcms_c_info *wlc, u16 *mhfs, u16 mhf2_init); +static void brcms_c_mctrl_write(struct brcms_hardware *wlc_hw); +static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool want, u32 flags); +static void brcms_c_ucode_mute_override_set(struct brcms_hardware *wlc_hw); +static void brcms_c_ucode_mute_override_clear(struct brcms_hardware *wlc_hw); +static u32 brcms_c_wlintrsoff(struct brcms_c_info *wlc); +static void brcms_c_wlintrsrestore(struct brcms_c_info *wlc, u32 macintmask); +static void brcms_c_gpio_init(struct brcms_c_info *wlc); +static void brcms_c_write_hw_bcntemplate0(struct brcms_hardware *wlc_hw, + u16 bcn[], int len); +static void brcms_c_write_hw_bcntemplate1(struct brcms_hardware *wlc_hw, + u16 bcn[], int len); +static void brcms_b_bsinit(struct brcms_c_info *wlc, u16 chanspec); +static u32 brcms_c_setband_inact(struct brcms_c_info *wlc, uint bandunit); +static void brcms_b_setband(struct brcms_hardware *wlc_hw, uint bandunit, + u16 chanspec); +static void brcms_b_update_slot_timing(struct brcms_hardware *wlc_hw, + bool shortslot); +static void brcms_upd_ofdm_pctl1_table(struct brcms_hardware *wlc_hw); +static u16 brcms_b_ofdm_ratetable_offset(struct brcms_hardware *wlc_hw, + u8 rate); + static u16 brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, struct sk_buff *p, @@ -297,17 +387,18 @@ static u16 brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, uint nfrags, uint queue, uint next_frag_len, struct wsec_key *key, - ratespec_t rspec_override); + u32 rspec_override); static void brcms_c_bss_default_init(struct brcms_c_info *wlc); static void brcms_c_ucode_mac_upd(struct brcms_c_info *wlc); -static ratespec_t mac80211_wlc_set_nrate(struct brcms_c_info *wlc, +static u32 mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band, u32 int_val); static void brcms_c_tx_prec_map_init(struct brcms_c_info *wlc); static void brcms_c_watchdog(void *arg); static void brcms_c_watchdog_by_timer(void *arg); static u16 brcms_c_rate_shm_offset(struct brcms_c_info *wlc, u8 rate); -static int brcms_c_set_rateset(struct brcms_c_info *wlc, wlc_rateset_t *rs_arg); +static int brcms_c_set_rateset(struct brcms_c_info *wlc, + struct brcms_c_rateset *rs_arg); static u8 brcms_c_local_constraint_qdbm(struct brcms_c_info *wlc); /* send and receive */ @@ -318,27 +409,27 @@ static void brcms_c_txflowcontrol_signal(struct brcms_c_info *wlc, struct brcms_txq_info *qi, bool on, int prio); static void brcms_c_txflowcontrol_reset(struct brcms_c_info *wlc); -static void brcms_c_compute_cck_plcp(struct brcms_c_info *wlc, ratespec_t rate, +static void brcms_c_compute_cck_plcp(struct brcms_c_info *wlc, u32 rate, uint length, u8 *plcp); -static void brcms_c_compute_ofdm_plcp(ratespec_t rate, uint length, u8 *plcp); -static void brcms_c_compute_mimo_plcp(ratespec_t rate, uint length, u8 *plcp); -static u16 brcms_c_compute_frame_dur(struct brcms_c_info *wlc, ratespec_t rate, +static void brcms_c_compute_ofdm_plcp(u32 rate, uint length, u8 *plcp); +static void brcms_c_compute_mimo_plcp(u32 rate, uint length, u8 *plcp); +static u16 brcms_c_compute_frame_dur(struct brcms_c_info *wlc, u32 rate, u8 preamble_type, uint next_frag_len); static u64 brcms_c_recover_tsf64(struct brcms_c_info *wlc, struct brcms_d11rxhdr *rxh); static void brcms_c_recvctl(struct brcms_c_info *wlc, struct d11rxhdr *rxh, struct sk_buff *p); -static uint brcms_c_calc_frame_len(struct brcms_c_info *wlc, ratespec_t rate, +static uint brcms_c_calc_frame_len(struct brcms_c_info *wlc, u32 rate, u8 preamble_type, uint dur); -static uint brcms_c_calc_ack_time(struct brcms_c_info *wlc, ratespec_t rate, +static uint brcms_c_calc_ack_time(struct brcms_c_info *wlc, u32 rate, u8 preamble_type); -static uint brcms_c_calc_cts_time(struct brcms_c_info *wlc, ratespec_t rate, +static uint brcms_c_calc_cts_time(struct brcms_c_info *wlc, u32 rate, u8 preamble_type); /* interrupt, up/down, band */ static void brcms_c_setband(struct brcms_c_info *wlc, uint bandunit); -static chanspec_t brcms_c_init_chanspec(struct brcms_c_info *wlc); +static u16 brcms_c_init_chanspec(struct brcms_c_info *wlc); static void brcms_c_bandinit_ordered(struct brcms_c_info *wlc, - chanspec_t chanspec); + u16 chanspec); static void brcms_c_bsinit(struct brcms_c_info *wlc); static int brcms_c_duty_cycle_set(struct brcms_c_info *wlc, int duty_cycle, bool isOFDM, bool writeToShm); @@ -349,7 +440,7 @@ static void brcms_c_radio_enable(struct brcms_c_info *wlc); static void brcms_c_radio_upd(struct brcms_c_info *wlc); /* scan, association, BSS */ -static uint brcms_c_calc_ba_time(struct brcms_c_info *wlc, ratespec_t rate, +static uint brcms_c_calc_ba_time(struct brcms_c_info *wlc, u32 rate, u8 preamble_type); static void brcms_c_update_mimo_band_bwcap(struct brcms_c_info *wlc, u8 bwcap); static void brcms_c_ht_update_sgi_rx(struct brcms_c_info *wlc, int val); @@ -366,8 +457,2542 @@ static uint brcms_c_down_del_timer(struct brcms_c_info *wlc); static void brcms_c_ofdm_rateset_war(struct brcms_c_info *wlc); static int _brcms_c_ioctl(struct brcms_c_info *wlc, int cmd, void *arg, int len, struct brcms_c_if *wlcif); +static void brcms_c_write_hw_bcntemplates(struct brcms_c_info *wlc, u16 bcn[], + int len, bool both); + +const u8 prio2fifo[NUMPRIO] = { + TX_AC_BE_FIFO, /* 0 BE AC_BE Best Effort */ + TX_AC_BK_FIFO, /* 1 BK AC_BK Background */ + TX_AC_BK_FIFO, /* 2 -- AC_BK Background */ + TX_AC_BE_FIFO, /* 3 EE AC_BE Best Effort */ + TX_AC_VI_FIFO, /* 4 CL AC_VI Video */ + TX_AC_VI_FIFO, /* 5 VI AC_VI Video */ + TX_AC_VO_FIFO, /* 6 VO AC_VO Voice */ + TX_AC_VO_FIFO /* 7 NC AC_VO Voice */ +}; + +/* debug/trace */ +uint brcm_msg_level = +#if defined(BCMDBG) + LOG_ERROR_VAL; +#else + 0; +#endif /* BCMDBG */ + +/* TX FIFO number to WME/802.1E Access Category */ +const u8 wme_fifo2ac[] = { AC_BK, AC_BE, AC_VI, AC_VO, AC_BE, AC_BE }; + +/* WME/802.1E Access Category to TX FIFO number */ +static const u8 wme_ac2fifo[] = { 1, 0, 2, 3 }; + +static bool in_send_q; + +/* 802.1D Priority to precedence queue mapping */ +const u8 wlc_prio2prec_map[] = { + _BRCMS_PREC_BE, /* 0 BE - Best-effort */ + _BRCMS_PREC_BK, /* 1 BK - Background */ + _BRCMS_PREC_NONE, /* 2 None = - */ + _BRCMS_PREC_EE, /* 3 EE - Excellent-effort */ + _BRCMS_PREC_CL, /* 4 CL - Controlled Load */ + _BRCMS_PREC_VI, /* 5 Vi - Video */ + _BRCMS_PREC_VO, /* 6 Vo - Voice */ + _BRCMS_PREC_NC, /* 7 NC - Network Control */ +}; + +static u16 xmtfifo_sz[][NFIFO] = { + /* corerev 20: 5120, 49152, 49152, 5376, 4352, 1280 */ + {20, 192, 192, 21, 17, 5}, + /* corerev 21: 2304, 14848, 5632, 3584, 3584, 1280 */ + {9, 58, 22, 14, 14, 5}, + /* corerev 22: 5120, 49152, 49152, 5376, 4352, 1280 */ + {20, 192, 192, 21, 17, 5}, + /* corerev 23: 5120, 49152, 49152, 5376, 4352, 1280 */ + {20, 192, 192, 21, 17, 5}, + /* corerev 24: 2304, 14848, 5632, 3584, 3584, 1280 */ + {9, 58, 22, 14, 14, 5}, +}; + +static const u8 acbitmap2maxprio[] = { + PRIO_8021D_BE, PRIO_8021D_BE, PRIO_8021D_BK, PRIO_8021D_BK, + PRIO_8021D_VI, PRIO_8021D_VI, PRIO_8021D_VI, PRIO_8021D_VI, + PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, + PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO, PRIO_8021D_VO +}; + +#ifdef BCMDBG +static const char * const fifo_names[] = { + "AC_BK", "AC_BE", "AC_VI", "AC_VO", "BCMC", "ATIM" }; +#else +static const char fifo_names[6][0]; +#endif + +#ifdef BCMDBG +/* pointer to most recently allocated wl/wlc */ +static struct brcms_c_info *wlc_info_dbg = (struct brcms_c_info *) (NULL); +#endif + +/* + * Update the slot timing for standard 11b/g (20us slots) + * or shortslot 11g (9us slots) + * The PSM needs to be suspended for this call. + */ +static void brcms_b_update_slot_timing(struct brcms_hardware *wlc_hw, + bool shortslot) +{ + struct d11regs *regs; + + regs = wlc_hw->regs; + + if (shortslot) { + /* 11g short slot: 11a timing */ + W_REG(®s->ifs_slot, 0x0207); /* APHY_SLOT_TIME */ + brcms_b_write_shm(wlc_hw, M_DOT11_SLOT, APHY_SLOT_TIME); + } else { + /* 11g long slot: 11b timing */ + W_REG(®s->ifs_slot, 0x0212); /* BPHY_SLOT_TIME */ + brcms_b_write_shm(wlc_hw, M_DOT11_SLOT, BPHY_SLOT_TIME); + } +} + +static void brcms_c_ucode_bsinit(struct brcms_hardware *wlc_hw) +{ + struct wiphy *wiphy = wlc_hw->wlc->wiphy; + + /* init microcode host flags */ + brcms_c_write_mhf(wlc_hw, wlc_hw->band->mhfs); + + /* do band-specific ucode IHR, SHM, and SCR inits */ + if (D11REV_IS(wlc_hw->corerev, 23)) { + if (BRCMS_ISNPHY(wlc_hw->band)) + brcms_c_write_inits(wlc_hw, d11n0bsinitvals16); + else + wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev" + " %d\n", __func__, wlc_hw->unit, + wlc_hw->corerev); + } else { + if (D11REV_IS(wlc_hw->corerev, 24)) { + if (BRCMS_ISLCNPHY(wlc_hw->band)) + brcms_c_write_inits(wlc_hw, + d11lcn0bsinitvals24); + else + wiphy_err(wiphy, "%s: wl%d: unsupported phy in" + " core rev %d\n", __func__, + wlc_hw->unit, wlc_hw->corerev); + } else { + wiphy_err(wiphy, "%s: wl%d: unsupported corerev %d\n", + __func__, wlc_hw->unit, wlc_hw->corerev); + } + } +} + +/* switch to new band but leave it inactive */ +static u32 brcms_c_setband_inact(struct brcms_c_info *wlc, uint bandunit) +{ + struct brcms_hardware *wlc_hw = wlc->hw; + u32 macintmask; + + BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit); + + WARN_ON((R_REG(&wlc_hw->regs->maccontrol) & MCTL_EN_MAC) != 0); + + /* disable interrupts */ + macintmask = brcms_intrsoff(wlc->wl); + + /* radio off */ + wlc_phy_switch_radio(wlc_hw->band->pi, OFF); + + brcms_b_core_phy_clk(wlc_hw, OFF); + + brcms_c_setxband(wlc_hw, bandunit); + + return macintmask; +} + +/* Process received frames */ +/* + * Return true if more frames need to be processed. false otherwise. + * Param 'bound' indicates max. # frames to process before break out. + */ +static bool +brcms_b_recv(struct brcms_hardware *wlc_hw, uint fifo, bool bound) +{ + struct sk_buff *p; + struct sk_buff *head = NULL; + struct sk_buff *tail = NULL; + uint n = 0; + uint bound_limit = bound ? wlc_hw->wlc->pub->tunables->rxbnd : -1; + struct brcms_d11rxhdr *wlc_rxhdr = NULL; + + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); + /* gather received frames */ + while ((p = dma_rx(wlc_hw->di[fifo]))) { + + if (!tail) + head = tail = p; + else { + tail->prev = p; + tail = p; + } + + /* !give others some time to run! */ + if (++n >= bound_limit) + break; + } + + /* post more rbufs */ + dma_rxfill(wlc_hw->di[fifo]); + + /* process each frame */ + while ((p = head) != NULL) { + head = head->prev; + p->prev = NULL; + + wlc_rxhdr = (struct brcms_d11rxhdr *) p->data; + + /* + * compute the RSSI from d11rxhdr and record it in wlc_rxd11hr + */ + wlc_phy_rssi_compute(wlc_hw->band->pi, wlc_rxhdr); + + brcms_c_recv(wlc_hw->wlc, p); + } + + return n >= bound_limit; +} + +static bool +brcms_b_dotxstatus(struct brcms_hardware *wlc_hw, struct tx_status *txs, + u32 s2) +{ + /* discard intermediate indications for ucode with one legitimate case: + * e.g. if "useRTS" is set. ucode did a successful rts/cts exchange, + * but the subsequent tx of DATA failed. so it will start rts/cts from + * the beginning (resetting the rts transmission count) + */ + if (!(txs->status & TX_STATUS_AMPDU) + && (txs->status & TX_STATUS_INTERMEDIATE)) + return false; + + return brcms_c_dotxstatus(wlc_hw->wlc, txs, s2); +} + +/* process tx completion events in BMAC + * Return true if more tx status need to be processed. false otherwise. + */ +static bool +brcms_b_txstatus(struct brcms_hardware *wlc_hw, bool bound, bool *fatal) +{ + bool morepending = false; + struct brcms_c_info *wlc = wlc_hw->wlc; + struct d11regs *regs; + struct tx_status txstatus, *txs; + u32 s1, s2; + uint n = 0; + /* + * Param 'max_tx_num' indicates max. # tx status to process before + * break out. + */ + uint max_tx_num = bound ? wlc->pub->tunables->txsbnd : -1; + + BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit); + + txs = &txstatus; + regs = wlc_hw->regs; + while (!(*fatal) + && (s1 = R_REG(®s->frmtxstatus)) & TXS_V) { + + if (s1 == 0xffffffff) { + wiphy_err(wlc->wiphy, "wl%d: %s: dead chip\n", + wlc_hw->unit, __func__); + return morepending; + } + + s2 = R_REG(®s->frmtxstatus2); + + txs->status = s1 & TXS_STATUS_MASK; + txs->frameid = (s1 & TXS_FID_MASK) >> TXS_FID_SHIFT; + txs->sequence = s2 & TXS_SEQ_MASK; + txs->phyerr = (s2 & TXS_PTX_MASK) >> TXS_PTX_SHIFT; + txs->lasttxtime = 0; + + *fatal = brcms_b_dotxstatus(wlc_hw, txs, s2); + + /* !give others some time to run! */ + if (++n >= max_tx_num) + break; + } + + if (*fatal) + return 0; + + if (n >= max_tx_num) + morepending = true; + + if (!pktq_empty(&wlc->pkt_queue->q)) + brcms_c_send_q(wlc); + + return morepending; +} + +/* second-level interrupt processing + * Return true if another dpc needs to be re-scheduled. false otherwise. + * Param 'bounded' indicates if applicable loops should be bounded. + */ +bool brcms_c_dpc(struct brcms_c_info *wlc, bool bounded) +{ + u32 macintstatus; + struct brcms_hardware *wlc_hw = wlc->hw; + struct d11regs *regs = wlc_hw->regs; + bool fatal = false; + struct wiphy *wiphy = wlc->wiphy; + + if (DEVICEREMOVED(wlc)) { + wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, + __func__); + brcms_down(wlc->wl); + return false; + } + + /* grab and clear the saved software intstatus bits */ + macintstatus = wlc->macintstatus; + wlc->macintstatus = 0; + + BCMMSG(wlc->wiphy, "wl%d: macintstatus 0x%x\n", + wlc_hw->unit, macintstatus); + + WARN_ON(macintstatus & MI_PRQ); /* PRQ Interrupt in non-MBSS */ + + /* BCN template is available */ + /* ZZZ: Use AP_ACTIVE ? */ + if (AP_ENAB(wlc->pub) && (!APSTA_ENAB(wlc->pub)) + && (macintstatus & MI_BCNTPL)) + brcms_c_update_beacon(wlc); + + /* tx status */ + if (macintstatus & MI_TFS) { + if (brcms_b_txstatus(wlc->hw, bounded, &fatal)) + wlc->macintstatus |= MI_TFS; + if (fatal) { + wiphy_err(wiphy, "MI_TFS: fatal\n"); + goto fatal; + } + } + + if (macintstatus & (MI_TBTT | MI_DTIM_TBTT)) + brcms_c_tbtt(wlc); + + /* ATIM window end */ + if (macintstatus & MI_ATIMWINEND) { + BCMMSG(wlc->wiphy, "end of ATIM window\n"); + OR_REG(®s->maccommand, wlc->qvalid); + wlc->qvalid = 0; + } + + /* + * received data or control frame, MI_DMAINT is + * indication of RX_FIFO interrupt + */ + if (macintstatus & MI_DMAINT) + if (brcms_b_recv(wlc_hw, RX_FIFO, bounded)) + wlc->macintstatus |= MI_DMAINT; + + /* TX FIFO suspend/flush completion */ + if (macintstatus & MI_TXSTOP) + brcms_b_tx_fifo_suspended(wlc_hw, TX_DATA_FIFO); + + /* noise sample collected */ + if (macintstatus & MI_BG_NOISE) + wlc_phy_noise_sample_intr(wlc_hw->band->pi); + + if (macintstatus & MI_GP0) { + wiphy_err(wiphy, "wl%d: PSM microcode watchdog fired at %d " + "(seconds). Resetting.\n", wlc_hw->unit, wlc_hw->now); + + printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n", + __func__, wlc_hw->sih->chip, + wlc_hw->sih->chiprev); + /* big hammer */ + brcms_init(wlc->wl); + } + + /* gptimer timeout */ + if (macintstatus & MI_TO) + W_REG(®s->gptimer, 0); + + if (macintstatus & MI_RFDISABLE) { + BCMMSG(wlc->wiphy, "wl%d: BMAC Detected a change on the" + " RF Disable Input\n", wlc_hw->unit); + brcms_rfkill_set_hw_state(wlc->wl); + } + + /* send any enq'd tx packets. Just makes sure to jump start tx */ + if (!pktq_empty(&wlc->pkt_queue->q)) + brcms_c_send_q(wlc); + + /* it isn't done and needs to be resched if macintstatus is non-zero */ + return wlc->macintstatus != 0; + + fatal: + brcms_init(wlc->wl); + return wlc->macintstatus != 0; +} + +int brcms_b_state_get(struct brcms_hardware *wlc_hw, + struct brcms_b_state *state) +{ + state->machwcap = wlc_hw->machwcap; + + return 0; +} + +static bool brcms_b_attach_dmapio(struct brcms_c_info *wlc, uint j, bool wme) +{ + uint i; + char name[8]; + /* + * ucode host flag 2 needed for pio mode, independent of band and fifo + */ + u16 pio_mhf2 = 0; + struct brcms_hardware *wlc_hw = wlc->hw; + uint unit = wlc_hw->unit; + struct brcms_tunables *tune = wlc->pub->tunables; + struct wiphy *wiphy = wlc->wiphy; + + /* name and offsets for dma_attach */ + snprintf(name, sizeof(name), "wl%d", unit); + + if (wlc_hw->di[0] == 0) { /* Init FIFOs */ + int dma_attach_err = 0; + + /* + * FIFO 0 + * TX: TX_AC_BK_FIFO (TX AC Background data packets) + * RX: RX_FIFO (RX data packets) + */ + wlc_hw->di[0] = dma_attach(name, wlc_hw->sih, + (wme ? DMAREG(wlc_hw, DMA_TX, 0) : + NULL), DMAREG(wlc_hw, DMA_RX, 0), + (wme ? tune->ntxd : 0), tune->nrxd, + tune->rxbufsz, -1, tune->nrxbufpost, + BRCMS_HWRXOFF, &brcm_msg_level); + dma_attach_err |= (NULL == wlc_hw->di[0]); + + /* + * FIFO 1 + * TX: TX_AC_BE_FIFO (TX AC Best-Effort data packets) + * (legacy) TX_DATA_FIFO (TX data packets) + * RX: UNUSED + */ + wlc_hw->di[1] = dma_attach(name, wlc_hw->sih, + DMAREG(wlc_hw, DMA_TX, 1), NULL, + tune->ntxd, 0, 0, -1, 0, 0, + &brcm_msg_level); + dma_attach_err |= (NULL == wlc_hw->di[1]); + + /* + * FIFO 2 + * TX: TX_AC_VI_FIFO (TX AC Video data packets) + * RX: UNUSED + */ + wlc_hw->di[2] = dma_attach(name, wlc_hw->sih, + DMAREG(wlc_hw, DMA_TX, 2), NULL, + tune->ntxd, 0, 0, -1, 0, 0, + &brcm_msg_level); + dma_attach_err |= (NULL == wlc_hw->di[2]); + /* + * FIFO 3 + * TX: TX_AC_VO_FIFO (TX AC Voice data packets) + * (legacy) TX_CTL_FIFO (TX control & mgmt packets) + */ + wlc_hw->di[3] = dma_attach(name, wlc_hw->sih, + DMAREG(wlc_hw, DMA_TX, 3), + NULL, tune->ntxd, 0, 0, -1, + 0, 0, &brcm_msg_level); + dma_attach_err |= (NULL == wlc_hw->di[3]); +/* Cleaner to leave this as if with AP defined */ + + if (dma_attach_err) { + wiphy_err(wiphy, "wl%d: wlc_attach: dma_attach failed" + "\n", unit); + return false; + } + + /* get pointer to dma engine tx flow control variable */ + for (i = 0; i < NFIFO; i++) + if (wlc_hw->di[i]) + wlc_hw->txavail[i] = + (uint *) dma_getvar(wlc_hw->di[i], + "&txavail"); + } + + /* initial ucode host flags */ + brcms_c_mhfdef(wlc, wlc_hw->band->mhfs, pio_mhf2); + + return true; +} + +static void brcms_b_detach_dmapio(struct brcms_hardware *wlc_hw) +{ + uint j; + + for (j = 0; j < NFIFO; j++) { + if (wlc_hw->di[j]) { + dma_detach(wlc_hw->di[j]); + wlc_hw->di[j] = NULL; + } + } +} + +/* + * Initialize brcms_c_info default values ... + * may get overrides later in this function + * BMAC_NOTES, move low out and resolve the dangling ones + */ +static void brcms_b_info_init(struct brcms_hardware *wlc_hw) +{ + struct brcms_c_info *wlc = wlc_hw->wlc; + + /* set default sw macintmask value */ + wlc->defmacintmask = DEF_MACINTMASK; + + /* various 802.11g modes */ + wlc_hw->shortslot = false; + + wlc_hw->SFBL = RETRY_SHORT_FB; + wlc_hw->LFBL = RETRY_LONG_FB; + + /* default mac retry limits */ + wlc_hw->SRL = RETRY_SHORT_DEF; + wlc_hw->LRL = RETRY_LONG_DEF; + wlc_hw->chanspec = CH20MHZ_CHSPEC(1); +} + +void brcms_b_wait_for_wake(struct brcms_hardware *wlc_hw) +{ + /* delay before first read of ucode state */ + udelay(40); + + /* wait until ucode is no longer asleep */ + SPINWAIT((brcms_b_read_shm(wlc_hw, M_UCODE_DBGST) == + DBGST_ASLEEP), wlc_hw->wlc->fastpwrup_dly); +} + +void brcms_b_hw_etheraddr(struct brcms_hardware *wlc_hw, u8 *ea) +{ + memcpy(ea, wlc_hw->etheraddr, ETH_ALEN); +} + +static int brcms_b_bandtype(struct brcms_hardware *wlc_hw) +{ + return wlc_hw->band->bandtype; +} + +/* control chip clock to save power, enable dynamic clock or force fast clock */ +static void brcms_b_clkctl_clk(struct brcms_hardware *wlc_hw, uint mode) +{ + if (PMUCTL_ENAB(wlc_hw->sih)) { + /* new chips with PMU, CCS_FORCEHT will distribute the HT clock + * on backplane, but mac core will still run on ALP(not HT) when + * it enters powersave mode, which means the FCA bit may not be + * set. Should wakeup mac if driver wants it to run on HT. + */ + + if (wlc_hw->clk) { + if (mode == CLK_FAST) { + OR_REG(&wlc_hw->regs->clk_ctl_st, + CCS_FORCEHT); + + udelay(64); + + SPINWAIT(((R_REG + (&wlc_hw->regs-> + clk_ctl_st) & CCS_HTAVAIL) == 0), + PMU_MAX_TRANSITION_DLY); + WARN_ON(!(R_REG + (&wlc_hw->regs-> + clk_ctl_st) & CCS_HTAVAIL)); + } else { + if ((wlc_hw->sih->pmurev == 0) && + (R_REG + (&wlc_hw->regs-> + clk_ctl_st) & (CCS_FORCEHT | CCS_HTAREQ))) + SPINWAIT(((R_REG + (&wlc_hw->regs-> + clk_ctl_st) & CCS_HTAVAIL) + == 0), + PMU_MAX_TRANSITION_DLY); + AND_REG(&wlc_hw->regs->clk_ctl_st, + ~CCS_FORCEHT); + } + } + wlc_hw->forcefastclk = (mode == CLK_FAST); + } else { + + /* old chips w/o PMU, force HT through cc, + * then use FCA to verify mac is running fast clock + */ + + wlc_hw->forcefastclk = ai_clkctl_cc(wlc_hw->sih, mode); + + /* check fast clock is available (if core is not in reset) */ + if (wlc_hw->forcefastclk && wlc_hw->clk) + WARN_ON(!(ai_core_sflags(wlc_hw->sih, 0, 0) & + SISF_FCLKA)); + + /* + * keep the ucode wake bit on if forcefastclk is on since we + * do not want ucode to put us back to slow clock when it dozes + * for PM mode. Code below matches the wake override bit with + * current forcefastclk state. Only setting bit in wake_override + * instead of waking ucode immediately since old code had this + * behavior. Older code set wlc->forcefastclk but only had the + * wake happen if the wakup_ucode work (protected by an up + * check) was executed just below. + */ + if (wlc_hw->forcefastclk) + mboolset(wlc_hw->wake_override, + BRCMS_WAKE_OVERRIDE_FORCEFAST); + else + mboolclr(wlc_hw->wake_override, + BRCMS_WAKE_OVERRIDE_FORCEFAST); + } +} + +/* set initial host flags value */ +static void +brcms_c_mhfdef(struct brcms_c_info *wlc, u16 *mhfs, u16 mhf2_init) +{ + struct brcms_hardware *wlc_hw = wlc->hw; + + memset(mhfs, 0, MHFMAX * sizeof(u16)); + + mhfs[MHF2] |= mhf2_init; + + /* prohibit use of slowclock on multifunction boards */ + if (wlc_hw->boardflags & BFL_NOPLLDOWN) + mhfs[MHF1] |= MHF1_FORCEFASTCLK; + + if (BRCMS_ISNPHY(wlc_hw->band) && NREV_LT(wlc_hw->band->phyrev, 2)) { + mhfs[MHF2] |= MHF2_NPHY40MHZ_WAR; + mhfs[MHF1] |= MHF1_IQSWAP_WAR; + } +} + +/* set or clear ucode host flag bits + * it has an optimization for no-change write + * it only writes through shared memory when the core has clock; + * pre-CLK changes should use wlc_write_mhf to get around the optimization + * + * + * bands values are: BRCM_BAND_AUTO <--- Current band only + * BRCM_BAND_5G <--- 5G band only + * BRCM_BAND_2G <--- 2G band only + * BRCM_BAND_ALL <--- All bands + */ +void +brcms_b_mhf(struct brcms_hardware *wlc_hw, u8 idx, u16 mask, u16 val, + int bands) +{ + u16 save; + u16 addr[MHFMAX] = { + M_HOST_FLAGS1, M_HOST_FLAGS2, M_HOST_FLAGS3, M_HOST_FLAGS4, + M_HOST_FLAGS5 + }; + struct brcms_hw_band *band; + + if ((val & ~mask) || idx >= MHFMAX) + return; /* error condition */ + + switch (bands) { + /* Current band only or all bands, + * then set the band to current band + */ + case BRCM_BAND_AUTO: + case BRCM_BAND_ALL: + band = wlc_hw->band; + break; + case BRCM_BAND_5G: + band = wlc_hw->bandstate[BAND_5G_INDEX]; + break; + case BRCM_BAND_2G: + band = wlc_hw->bandstate[BAND_2G_INDEX]; + break; + default: + band = NULL; /* error condition */ + } + + if (band) { + save = band->mhfs[idx]; + band->mhfs[idx] = (band->mhfs[idx] & ~mask) | val; + + /* optimization: only write through if changed, and + * changed band is the current band + */ + if (wlc_hw->clk && (band->mhfs[idx] != save) + && (band == wlc_hw->band)) + brcms_b_write_shm(wlc_hw, addr[idx], + (u16) band->mhfs[idx]); + } + + if (bands == BRCM_BAND_ALL) { + wlc_hw->bandstate[0]->mhfs[idx] = + (wlc_hw->bandstate[0]->mhfs[idx] & ~mask) | val; + wlc_hw->bandstate[1]->mhfs[idx] = + (wlc_hw->bandstate[1]->mhfs[idx] & ~mask) | val; + } +} + +static void brcms_c_write_mhf(struct brcms_hardware *wlc_hw, u16 *mhfs) +{ + u8 idx; + u16 addr[] = { + M_HOST_FLAGS1, M_HOST_FLAGS2, M_HOST_FLAGS3, M_HOST_FLAGS4, + M_HOST_FLAGS5 + }; + + for (idx = 0; idx < MHFMAX; idx++) + brcms_b_write_shm(wlc_hw, addr[idx], mhfs[idx]); +} + +/* set the maccontrol register to desired reset state and + * initialize the sw cache of the register + */ +static void brcms_c_mctrl_reset(struct brcms_hardware *wlc_hw) +{ + /* IHR accesses are always enabled, PSM disabled, HPS off and WAKE on */ + wlc_hw->maccontrol = 0; + wlc_hw->suspended_fifos = 0; + wlc_hw->wake_override = 0; + wlc_hw->mute_override = 0; + brcms_b_mctrl(wlc_hw, ~0, MCTL_IHR_EN | MCTL_WAKE); +} + +/* set or clear maccontrol bits */ +void brcms_b_mctrl(struct brcms_hardware *wlc_hw, u32 mask, u32 val) +{ + u32 maccontrol; + u32 new_maccontrol; + + if (val & ~mask) + return; /* error condition */ + maccontrol = wlc_hw->maccontrol; + new_maccontrol = (maccontrol & ~mask) | val; + + /* if the new maccontrol value is the same as the old, nothing to do */ + if (new_maccontrol == maccontrol) + return; + + /* something changed, cache the new value */ + wlc_hw->maccontrol = new_maccontrol; + + /* write the new values with overrides applied */ + brcms_c_mctrl_write(wlc_hw); +} + +/* + * write the software state of maccontrol and + * overrides to the maccontrol register + */ +static void brcms_c_mctrl_write(struct brcms_hardware *wlc_hw) +{ + u32 maccontrol = wlc_hw->maccontrol; + + /* OR in the wake bit if overridden */ + if (wlc_hw->wake_override) + maccontrol |= MCTL_WAKE; + + /* set AP and INFRA bits for mute if needed */ + if (wlc_hw->mute_override) { + maccontrol &= ~(MCTL_AP); + maccontrol |= MCTL_INFRA; + } + + W_REG(&wlc_hw->regs->maccontrol, maccontrol); +} + +void brcms_c_ucode_wake_override_set(struct brcms_hardware *wlc_hw, + u32 override_bit) +{ + if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE)) { + mboolset(wlc_hw->wake_override, override_bit); + return; + } + + mboolset(wlc_hw->wake_override, override_bit); + + brcms_c_mctrl_write(wlc_hw); + brcms_b_wait_for_wake(wlc_hw); + + return; +} + +void brcms_c_ucode_wake_override_clear(struct brcms_hardware *wlc_hw, + u32 override_bit) +{ + mboolclr(wlc_hw->wake_override, override_bit); + + if (wlc_hw->wake_override || (wlc_hw->maccontrol & MCTL_WAKE)) + return; + + brcms_c_mctrl_write(wlc_hw); + + return; +} + +/* When driver needs ucode to stop beaconing, it has to make sure that + * MCTL_AP is clear and MCTL_INFRA is set + * Mode MCTL_AP MCTL_INFRA + * AP 1 1 + * STA 0 1 <--- This will ensure no beacons + * IBSS 0 0 + */ +static void brcms_c_ucode_mute_override_set(struct brcms_hardware *wlc_hw) +{ + wlc_hw->mute_override = 1; + + /* if maccontrol already has AP == 0 and INFRA == 1 without this + * override, then there is no change to write + */ + if ((wlc_hw->maccontrol & (MCTL_AP | MCTL_INFRA)) == MCTL_INFRA) + return; + + brcms_c_mctrl_write(wlc_hw); + + return; +} + +/* Clear the override on AP and INFRA bits */ +static void brcms_c_ucode_mute_override_clear(struct brcms_hardware *wlc_hw) +{ + if (wlc_hw->mute_override == 0) + return; + + wlc_hw->mute_override = 0; + + /* if maccontrol already has AP == 0 and INFRA == 1 without this + * override, then there is no change to write + */ + if ((wlc_hw->maccontrol & (MCTL_AP | MCTL_INFRA)) == MCTL_INFRA) + return; + + brcms_c_mctrl_write(wlc_hw); +} + +/* + * Write a MAC address to the given match reg offset in the RXE match engine. + */ +void +brcms_b_set_addrmatch(struct brcms_hardware *wlc_hw, int match_reg_offset, + const u8 *addr) +{ + struct d11regs *regs; + u16 mac_l; + u16 mac_m; + u16 mac_h; + + BCMMSG(wlc_hw->wlc->wiphy, "wl%d: brcms_b_set_addrmatch\n", + wlc_hw->unit); + + regs = wlc_hw->regs; + mac_l = addr[0] | (addr[1] << 8); + mac_m = addr[2] | (addr[3] << 8); + mac_h = addr[4] | (addr[5] << 8); + + /* enter the MAC addr into the RXE match registers */ + W_REG(®s->rcm_ctl, RCM_INC_DATA | match_reg_offset); + W_REG(®s->rcm_mat_data, mac_l); + W_REG(®s->rcm_mat_data, mac_m); + W_REG(®s->rcm_mat_data, mac_h); + +} + +void +brcms_b_write_template_ram(struct brcms_hardware *wlc_hw, int offset, int len, + void *buf) +{ + struct d11regs *regs; + u32 word; + bool be_bit; + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); + + regs = wlc_hw->regs; + W_REG(®s->tplatewrptr, offset); + + /* if MCTL_BIGEND bit set in mac control register, + * the chip swaps data in fifo, as well as data in + * template ram + */ + be_bit = (R_REG(®s->maccontrol) & MCTL_BIGEND) != 0; + + while (len > 0) { + memcpy(&word, buf, sizeof(u32)); + + if (be_bit) + word = cpu_to_be32(word); + else + word = cpu_to_le32(word); + + W_REG(®s->tplatewrdata, word); + + buf = (u8 *) buf + sizeof(u32); + len -= sizeof(u32); + } +} + +void brcms_b_set_cwmin(struct brcms_hardware *wlc_hw, u16 newmin) +{ + wlc_hw->band->CWmin = newmin; + + W_REG(&wlc_hw->regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_CWMIN); + (void)R_REG(&wlc_hw->regs->objaddr); + W_REG(&wlc_hw->regs->objdata, newmin); +} + +void brcms_b_set_cwmax(struct brcms_hardware *wlc_hw, u16 newmax) +{ + wlc_hw->band->CWmax = newmax; + + W_REG(&wlc_hw->regs->objaddr, OBJADDR_SCR_SEL | S_DOT11_CWMAX); + (void)R_REG(&wlc_hw->regs->objaddr); + W_REG(&wlc_hw->regs->objdata, newmax); +} + +void brcms_b_bw_set(struct brcms_hardware *wlc_hw, u16 bw) +{ + bool fastclk; + + /* request FAST clock if not on */ + fastclk = wlc_hw->forcefastclk; + if (!fastclk) + brcms_b_clkctl_clk(wlc_hw, CLK_FAST); + + wlc_phy_bw_state_set(wlc_hw->band->pi, bw); + + brcms_b_phy_reset(wlc_hw); + wlc_phy_init(wlc_hw->band->pi, wlc_phy_chanspec_get(wlc_hw->band->pi)); + + /* restore the clk */ + if (!fastclk) + brcms_b_clkctl_clk(wlc_hw, CLK_DYNAMIC); +} + +static void +brcms_c_write_hw_bcntemplate0(struct brcms_hardware *wlc_hw, u16 bcn[], + int len) +{ + struct d11regs *regs = wlc_hw->regs; + + brcms_b_write_template_ram(wlc_hw, T_BCN0_TPL_BASE, (len + 3) & ~3, + bcn); + /* write beacon length to SCR */ + brcms_b_write_shm(wlc_hw, M_BCN0_FRM_BYTESZ, (u16) len); + /* mark beacon0 valid */ + OR_REG(®s->maccommand, MCMD_BCN0VLD); +} + +static void +brcms_c_write_hw_bcntemplate1(struct brcms_hardware *wlc_hw, u16 bcn[], + int len) +{ + struct d11regs *regs = wlc_hw->regs; + + brcms_b_write_template_ram(wlc_hw, T_BCN1_TPL_BASE, (len + 3) & ~3, + bcn); + /* write beacon length to SCR */ + brcms_b_write_shm(wlc_hw, M_BCN1_FRM_BYTESZ, (u16) len); + /* mark beacon1 valid */ + OR_REG(®s->maccommand, MCMD_BCN1VLD); +} + +static void brcms_b_upd_synthpu(struct brcms_hardware *wlc_hw) +{ + u16 v; + struct brcms_c_info *wlc = wlc_hw->wlc; + /* update SYNTHPU_DLY */ + + if (BRCMS_ISLCNPHY(wlc->band)) + v = SYNTHPU_DLY_LPPHY_US; + else if (BRCMS_ISNPHY(wlc->band) && (NREV_GE(wlc->band->phyrev, 3))) + v = SYNTHPU_DLY_NPHY_US; + else + v = SYNTHPU_DLY_BPHY_US; + + brcms_b_write_shm(wlc_hw, M_SYNTHPU_DLY, v); +} + +/* band-specific init */ +static void brcms_b_bsinit(struct brcms_c_info *wlc, u16 chanspec) +{ + struct brcms_hardware *wlc_hw = wlc->hw; + + BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit, + wlc_hw->band->bandunit); + + brcms_c_ucode_bsinit(wlc_hw); + + wlc_phy_init(wlc_hw->band->pi, chanspec); + + brcms_c_ucode_txant_set(wlc_hw); + + /* + * cwmin is band-specific, update hardware + * with value for current band + */ + brcms_b_set_cwmin(wlc_hw, wlc_hw->band->CWmin); + brcms_b_set_cwmax(wlc_hw, wlc_hw->band->CWmax); + + brcms_b_update_slot_timing(wlc_hw, + BAND_5G(wlc_hw->band-> + bandtype) ? true : wlc_hw-> + shortslot); + + /* write phytype and phyvers */ + brcms_b_write_shm(wlc_hw, M_PHYTYPE, (u16) wlc_hw->band->phytype); + brcms_b_write_shm(wlc_hw, M_PHYVER, (u16) wlc_hw->band->phyrev); + + /* + * initialize the txphyctl1 rate table since + * shmem is shared between bands + */ + brcms_upd_ofdm_pctl1_table(wlc_hw); + + brcms_b_upd_synthpu(wlc_hw); +} + +static void brcms_b_core_phy_clk(struct brcms_hardware *wlc_hw, bool clk) +{ + BCMMSG(wlc_hw->wlc->wiphy, "wl%d: clk %d\n", wlc_hw->unit, clk); + + wlc_hw->phyclk = clk; + + if (OFF == clk) { /* clear gmode bit, put phy into reset */ + + ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC | SICF_GMODE), + (SICF_PRST | SICF_FGC)); + udelay(1); + ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC), SICF_PRST); + udelay(1); + + } else { /* take phy out of reset */ + + ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_FGC), SICF_FGC); + udelay(1); + ai_core_cflags(wlc_hw->sih, (SICF_FGC), 0); + udelay(1); + + } +} + +/* Perform a soft reset of the PHY PLL */ +void brcms_b_core_phypll_reset(struct brcms_hardware *wlc_hw) +{ + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); + + ai_corereg(wlc_hw->sih, SI_CC_IDX, + offsetof(struct chipcregs, chipcontrol_addr), ~0, 0); + udelay(1); + ai_corereg(wlc_hw->sih, SI_CC_IDX, + offsetof(struct chipcregs, chipcontrol_data), 0x4, 0); + udelay(1); + ai_corereg(wlc_hw->sih, SI_CC_IDX, + offsetof(struct chipcregs, chipcontrol_data), 0x4, 4); + udelay(1); + ai_corereg(wlc_hw->sih, SI_CC_IDX, + offsetof(struct chipcregs, chipcontrol_data), 0x4, 0); + udelay(1); +} + +/* light way to turn on phy clock without reset for NPHY only + * refer to brcms_b_core_phy_clk for full version + */ +void brcms_b_phyclk_fgc(struct brcms_hardware *wlc_hw, bool clk) +{ + /* support(necessary for NPHY and HYPHY) only */ + if (!BRCMS_ISNPHY(wlc_hw->band)) + return; + + if (ON == clk) + ai_core_cflags(wlc_hw->sih, SICF_FGC, SICF_FGC); + else + ai_core_cflags(wlc_hw->sih, SICF_FGC, 0); + +} + +void brcms_b_macphyclk_set(struct brcms_hardware *wlc_hw, bool clk) +{ + if (ON == clk) + ai_core_cflags(wlc_hw->sih, SICF_MPCLKE, SICF_MPCLKE); + else + ai_core_cflags(wlc_hw->sih, SICF_MPCLKE, 0); +} + +void brcms_b_phy_reset(struct brcms_hardware *wlc_hw) +{ + struct brcms_phy_pub *pih = wlc_hw->band->pi; + u32 phy_bw_clkbits; + bool phy_in_reset = false; + + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); + + if (pih == NULL) + return; + + phy_bw_clkbits = wlc_phy_clk_bwbits(wlc_hw->band->pi); + + /* Specific reset sequence required for NPHY rev 3 and 4 */ + if (BRCMS_ISNPHY(wlc_hw->band) && NREV_GE(wlc_hw->band->phyrev, 3) && + NREV_LE(wlc_hw->band->phyrev, 4)) { + /* Set the PHY bandwidth */ + ai_core_cflags(wlc_hw->sih, SICF_BWMASK, phy_bw_clkbits); + + udelay(1); + + /* Perform a soft reset of the PHY PLL */ + brcms_b_core_phypll_reset(wlc_hw); + + /* reset the PHY */ + ai_core_cflags(wlc_hw->sih, (SICF_PRST | SICF_PCLKE), + (SICF_PRST | SICF_PCLKE)); + phy_in_reset = true; + } else { + ai_core_cflags(wlc_hw->sih, + (SICF_PRST | SICF_PCLKE | SICF_BWMASK), + (SICF_PRST | SICF_PCLKE | phy_bw_clkbits)); + } + + udelay(2); + brcms_b_core_phy_clk(wlc_hw, ON); + + if (pih) + wlc_phy_anacore(pih, ON); +} + +/* switch to and initialize new band */ +static void brcms_b_setband(struct brcms_hardware *wlc_hw, uint bandunit, + u16 chanspec) { + struct brcms_c_info *wlc = wlc_hw->wlc; + u32 macintmask; + + /* Enable the d11 core before accessing it */ + if (!ai_iscoreup(wlc_hw->sih)) { + ai_core_reset(wlc_hw->sih, 0, 0); + brcms_c_mctrl_reset(wlc_hw); + } + + macintmask = brcms_c_setband_inact(wlc, bandunit); + + if (!wlc_hw->up) + return; + + brcms_b_core_phy_clk(wlc_hw, ON); + + /* band-specific initializations */ + brcms_b_bsinit(wlc, chanspec); + + /* + * If there are any pending software interrupt bits, + * then replace these with a harmless nonzero value + * so brcms_c_dpc() will re-enable interrupts when done. + */ + if (wlc->macintstatus) + wlc->macintstatus = MI_DMAINT; + + /* restore macintmask */ + brcms_intrsrestore(wlc->wl, macintmask); + + /* ucode should still be suspended.. */ + WARN_ON((R_REG(&wlc_hw->regs->maccontrol) & MCTL_EN_MAC) != 0); +} + +/* low-level band switch utility routine */ +void brcms_c_setxband(struct brcms_hardware *wlc_hw, uint bandunit) +{ + BCMMSG(wlc_hw->wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit, + bandunit); + + wlc_hw->band = wlc_hw->bandstate[bandunit]; + + /* + * BMAC_NOTE: + * until we eliminate need for wlc->band refs in low level code + */ + wlc_hw->wlc->band = wlc_hw->wlc->bandstate[bandunit]; + + /* set gmode core flag */ + if (wlc_hw->sbclk && !wlc_hw->noreset) + ai_core_cflags(wlc_hw->sih, SICF_GMODE, + ((bandunit == 0) ? SICF_GMODE : 0)); +} + +static bool brcms_c_isgoodchip(struct brcms_hardware *wlc_hw) +{ + + /* reject unsupported corerev */ + if (!VALID_COREREV(wlc_hw->corerev)) { + wiphy_err(wlc_hw->wlc->wiphy, "unsupported core rev %d\n", + wlc_hw->corerev); + return false; + } + + return true; +} + +/* Validate some board info parameters */ +static bool brcms_c_validboardtype(struct brcms_hardware *wlc_hw) +{ + uint boardrev = wlc_hw->boardrev; + + /* 4 bits each for board type, major, minor, and tiny version */ + uint brt = (boardrev & 0xf000) >> 12; + uint b0 = (boardrev & 0xf00) >> 8; + uint b1 = (boardrev & 0xf0) >> 4; + uint b2 = boardrev & 0xf; + + /* voards from other vendors are always considered valid */ + if (wlc_hw->sih->boardvendor != PCI_VENDOR_ID_BROADCOM) + return true; + + /* do some boardrev sanity checks when boardvendor is Broadcom */ + if (boardrev == 0) + return false; + + if (boardrev <= 0xff) + return true; + + if ((brt > 2) || (brt == 0) || (b0 > 9) || (b0 == 0) || (b1 > 9) + || (b2 > 9)) + return false; + + return true; +} + +static char *brcms_c_get_macaddr(struct brcms_hardware *wlc_hw) +{ + const char *varname = "macaddr"; + char *macaddr; + + /* If macaddr exists, use it (Sromrev4, CIS, ...). */ + macaddr = getvar(wlc_hw->vars, varname); + if (macaddr != NULL) + return macaddr; + + if (NBANDS_HW(wlc_hw) > 1) + varname = "et1macaddr"; + else + varname = "il0macaddr"; + + macaddr = getvar(wlc_hw->vars, varname); + if (macaddr == NULL) + wiphy_err(wlc_hw->wlc->wiphy, "wl%d: wlc_get_macaddr: macaddr " + "getvar(%s) not found\n", wlc_hw->unit, varname); + + return macaddr; +} + +/* + * Return true if radio is disabled, otherwise false. + * hw radio disable signal is an external pin, users activate it asynchronously + * this function could be called when driver is down and w/o clock + * it operates on different registers depending on corerev and boardflag. + */ +bool brcms_b_radio_read_hwdisabled(struct brcms_hardware *wlc_hw) +{ + bool v, clk, xtal; + u32 resetbits = 0, flags = 0; + + xtal = wlc_hw->sbclk; + if (!xtal) + brcms_b_xtal(wlc_hw, ON); + + /* may need to take core out of reset first */ + clk = wlc_hw->clk; + if (!clk) { + /* + * mac no longer enables phyclk automatically when driver + * accesses phyreg throughput mac. This can be skipped since + * only mac reg is accessed below + */ + flags |= SICF_PCLKE; + + /* + * AI chip doesn't restore bar0win2 on + * hibernation/resume, need sw fixup + */ + if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) || + (wlc_hw->sih->chip == BCM43225_CHIP_ID)) + wlc_hw->regs = (struct d11regs *) + ai_setcore(wlc_hw->sih, D11_CORE_ID, 0); + ai_core_reset(wlc_hw->sih, flags, resetbits); + brcms_c_mctrl_reset(wlc_hw); + } + + v = ((R_REG(&wlc_hw->regs->phydebug) & PDBG_RFD) != 0); + + /* put core back into reset */ + if (!clk) + ai_core_disable(wlc_hw->sih, 0); + + if (!xtal) + brcms_b_xtal(wlc_hw, OFF); + + return v; +} + +static bool wlc_dma_rxreset(struct brcms_hardware *wlc_hw, uint fifo) +{ + struct dma_pub *di = wlc_hw->di[fifo]; + return dma_rxreset(di); +} + +/* d11 core reset + * ensure fask clock during reset + * reset dma + * reset d11(out of reset) + * reset phy(out of reset) + * clear software macintstatus for fresh new start + * one testing hack wlc_hw->noreset will bypass the d11/phy reset + */ +void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags) +{ + struct d11regs *regs; + uint i; + bool fastclk; + u32 resetbits = 0; -/* conditions under which the PM bit should be set in outgoing frames and STAY_AWAKE is meaningful + if (flags == BRCMS_USE_COREFLAGS) + flags = (wlc_hw->band->pi ? wlc_hw->band->core_flags : 0); + + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); + + regs = wlc_hw->regs; + + /* request FAST clock if not on */ + fastclk = wlc_hw->forcefastclk; + if (!fastclk) + brcms_b_clkctl_clk(wlc_hw, CLK_FAST); + + /* reset the dma engines except first time thru */ + if (ai_iscoreup(wlc_hw->sih)) { + for (i = 0; i < NFIFO; i++) + if ((wlc_hw->di[i]) && (!dma_txreset(wlc_hw->di[i]))) + wiphy_err(wlc_hw->wlc->wiphy, "wl%d: %s: " + "dma_txreset[%d]: cannot stop dma\n", + wlc_hw->unit, __func__, i); + + if ((wlc_hw->di[RX_FIFO]) + && (!wlc_dma_rxreset(wlc_hw, RX_FIFO))) + wiphy_err(wlc_hw->wlc->wiphy, "wl%d: %s: dma_rxreset" + "[%d]: cannot stop dma\n", + wlc_hw->unit, __func__, RX_FIFO); + } + /* if noreset, just stop the psm and return */ + if (wlc_hw->noreset) { + wlc_hw->wlc->macintstatus = 0; /* skip wl_dpc after down */ + brcms_b_mctrl(wlc_hw, MCTL_PSM_RUN | MCTL_EN_MAC, 0); + return; + } + + /* + * mac no longer enables phyclk automatically when driver accesses + * phyreg throughput mac, AND phy_reset is skipped at early stage when + * band->pi is invalid. need to enable PHY CLK + */ + flags |= SICF_PCLKE; + + /* + * reset the core + * In chips with PMU, the fastclk request goes through d11 core + * reg 0x1e0, which is cleared by the core_reset. have to re-request it. + * + * This adds some delay and we can optimize it by also requesting + * fastclk through chipcommon during this period if necessary. But + * that has to work coordinate with other driver like mips/arm since + * they may touch chipcommon as well. + */ + wlc_hw->clk = false; + ai_core_reset(wlc_hw->sih, flags, resetbits); + wlc_hw->clk = true; + if (wlc_hw->band && wlc_hw->band->pi) + wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, true); + + brcms_c_mctrl_reset(wlc_hw); + + if (PMUCTL_ENAB(wlc_hw->sih)) + brcms_b_clkctl_clk(wlc_hw, CLK_FAST); + + brcms_b_phy_reset(wlc_hw); + + /* turn on PHY_PLL */ + brcms_b_core_phypll_ctl(wlc_hw, true); + + /* clear sw intstatus */ + wlc_hw->wlc->macintstatus = 0; + + /* restore the clk setting */ + if (!fastclk) + brcms_b_clkctl_clk(wlc_hw, CLK_DYNAMIC); +} + +/* txfifo sizes needs to be modified(increased) since the newer cores + * have more memory. + */ +static void brcms_b_corerev_fifofixup(struct brcms_hardware *wlc_hw) +{ + struct d11regs *regs = wlc_hw->regs; + u16 fifo_nu; + u16 txfifo_startblk = TXFIFO_START_BLK, txfifo_endblk; + u16 txfifo_def, txfifo_def1; + u16 txfifo_cmd; + + /* tx fifos start at TXFIFO_START_BLK from the Base address */ + txfifo_startblk = TXFIFO_START_BLK; + + /* sequence of operations: reset fifo, set fifo size, reset fifo */ + for (fifo_nu = 0; fifo_nu < NFIFO; fifo_nu++) { + + txfifo_endblk = txfifo_startblk + wlc_hw->xmtfifo_sz[fifo_nu]; + txfifo_def = (txfifo_startblk & 0xff) | + (((txfifo_endblk - 1) & 0xff) << TXFIFO_FIFOTOP_SHIFT); + txfifo_def1 = ((txfifo_startblk >> 8) & 0x1) | + ((((txfifo_endblk - + 1) >> 8) & 0x1) << TXFIFO_FIFOTOP_SHIFT); + txfifo_cmd = + TXFIFOCMD_RESET_MASK | (fifo_nu << TXFIFOCMD_FIFOSEL_SHIFT); + + W_REG(®s->xmtfifocmd, txfifo_cmd); + W_REG(®s->xmtfifodef, txfifo_def); + W_REG(®s->xmtfifodef1, txfifo_def1); + + W_REG(®s->xmtfifocmd, txfifo_cmd); + + txfifo_startblk += wlc_hw->xmtfifo_sz[fifo_nu]; + } + /* + * need to propagate to shm location to be in sync since ucode/hw won't + * do this + */ + brcms_b_write_shm(wlc_hw, M_FIFOSIZE0, + wlc_hw->xmtfifo_sz[TX_AC_BE_FIFO]); + brcms_b_write_shm(wlc_hw, M_FIFOSIZE1, + wlc_hw->xmtfifo_sz[TX_AC_VI_FIFO]); + brcms_b_write_shm(wlc_hw, M_FIFOSIZE2, + ((wlc_hw->xmtfifo_sz[TX_AC_VO_FIFO] << 8) | wlc_hw-> + xmtfifo_sz[TX_AC_BK_FIFO])); + brcms_b_write_shm(wlc_hw, M_FIFOSIZE3, + ((wlc_hw->xmtfifo_sz[TX_ATIM_FIFO] << 8) | wlc_hw-> + xmtfifo_sz[TX_BCMC_FIFO])); +} + +/* This function is used for changing the tsf frac register + * If spur avoidance mode is off, the mac freq will be 80/120/160Mhz + * If spur avoidance mode is on1, the mac freq will be 82/123/164Mhz + * If spur avoidance mode is on2, the mac freq will be 84/126/168Mhz + * HTPHY Formula is 2^26/freq(MHz) e.g. + * For spuron2 - 126MHz -> 2^26/126 = 532610.0 + * - 532610 = 0x82082 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x2082 + * For spuron: 123MHz -> 2^26/123 = 545600.5 + * - 545601 = 0x85341 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x5341 + * For spur off: 120MHz -> 2^26/120 = 559240.5 + * - 559241 = 0x88889 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x8889 + */ + +void brcms_b_switch_macfreq(struct brcms_hardware *wlc_hw, u8 spurmode) +{ + struct d11regs *regs; + regs = wlc_hw->regs; + + if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) || + (wlc_hw->sih->chip == BCM43225_CHIP_ID)) { + if (spurmode == WL_SPURAVOID_ON2) { /* 126Mhz */ + W_REG(®s->tsf_clk_frac_l, 0x2082); + W_REG(®s->tsf_clk_frac_h, 0x8); + } else if (spurmode == WL_SPURAVOID_ON1) { /* 123Mhz */ + W_REG(®s->tsf_clk_frac_l, 0x5341); + W_REG(®s->tsf_clk_frac_h, 0x8); + } else { /* 120Mhz */ + W_REG(®s->tsf_clk_frac_l, 0x8889); + W_REG(®s->tsf_clk_frac_h, 0x8); + } + } else if (BRCMS_ISLCNPHY(wlc_hw->band)) { + if (spurmode == WL_SPURAVOID_ON1) { /* 82Mhz */ + W_REG(®s->tsf_clk_frac_l, 0x7CE0); + W_REG(®s->tsf_clk_frac_h, 0xC); + } else { /* 80Mhz */ + W_REG(®s->tsf_clk_frac_l, 0xCCCD); + W_REG(®s->tsf_clk_frac_h, 0xC); + } + } +} + +/* Initialize GPIOs that are controlled by D11 core */ +static void brcms_c_gpio_init(struct brcms_c_info *wlc) +{ + struct brcms_hardware *wlc_hw = wlc->hw; + struct d11regs *regs; + u32 gc, gm; + + regs = wlc_hw->regs; + + /* use GPIO select 0 to get all gpio signals from the gpio out reg */ + brcms_b_mctrl(wlc_hw, MCTL_GPOUT_SEL_MASK, 0); + + /* + * Common GPIO setup: + * G0 = LED 0 = WLAN Activity + * G1 = LED 1 = WLAN 2.4 GHz Radio State + * G2 = LED 2 = WLAN 5 GHz Radio State + * G4 = radio disable input (HI enabled, LO disabled) + */ + + gc = gm = 0; + + /* Allocate GPIOs for mimo antenna diversity feature */ + if (wlc_hw->antsel_type == ANTSEL_2x3) { + /* Enable antenna diversity, use 2x3 mode */ + brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN, + MHF3_ANTSEL_EN, BRCM_BAND_ALL); + brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE, + MHF3_ANTSEL_MODE, BRCM_BAND_ALL); + + /* init superswitch control */ + wlc_phy_antsel_init(wlc_hw->band->pi, false); + + } else if (wlc_hw->antsel_type == ANTSEL_2x4) { + gm |= gc |= (BOARD_GPIO_12 | BOARD_GPIO_13); + /* + * The board itself is powered by these GPIOs + * (when not sending pattern) so set them high + */ + OR_REG(®s->psm_gpio_oe, + (BOARD_GPIO_12 | BOARD_GPIO_13)); + OR_REG(®s->psm_gpio_out, + (BOARD_GPIO_12 | BOARD_GPIO_13)); + + /* Enable antenna diversity, use 2x4 mode */ + brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_EN, + MHF3_ANTSEL_EN, BRCM_BAND_ALL); + brcms_b_mhf(wlc_hw, MHF3, MHF3_ANTSEL_MODE, 0, + BRCM_BAND_ALL); + + /* Configure the desired clock to be 4Mhz */ + brcms_b_write_shm(wlc_hw, M_ANTSEL_CLKDIV, + ANTSEL_CLKDIV_4MHZ); + } + + /* + * gpio 9 controls the PA. ucode is responsible + * for wiggling out and oe + */ + if (wlc_hw->boardflags & BFL_PACTRL) + gm |= gc |= BOARD_GPIO_PACTRL; + + /* apply to gpiocontrol register */ + ai_gpiocontrol(wlc_hw->sih, gm, gc, GPIO_DRV_PRIORITY); +} + +static void brcms_ucode_download(struct brcms_hardware *wlc_hw) +{ + struct brcms_c_info *wlc; + wlc = wlc_hw->wlc; + + if (wlc_hw->ucode_loaded) + return; + + if (D11REV_IS(wlc_hw->corerev, 23)) { + if (BRCMS_ISNPHY(wlc_hw->band)) { + brcms_ucode_write(wlc_hw, bcm43xx_16_mimo, + bcm43xx_16_mimosz); + wlc_hw->ucode_loaded = true; + } else + wiphy_err(wlc->wiphy, "%s: wl%d: unsupported phy in " + "corerev %d\n", + __func__, wlc_hw->unit, wlc_hw->corerev); + } else if (D11REV_IS(wlc_hw->corerev, 24)) { + if (BRCMS_ISLCNPHY(wlc_hw->band)) { + brcms_ucode_write(wlc_hw, bcm43xx_24_lcn, + bcm43xx_24_lcnsz); + wlc_hw->ucode_loaded = true; + } else { + wiphy_err(wlc->wiphy, "%s: wl%d: unsupported phy in " + "corerev %d\n", + __func__, wlc_hw->unit, wlc_hw->corerev); + } + } +} + +static void brcms_ucode_write(struct brcms_hardware *wlc_hw, const u32 ucode[], + const uint nbytes) { + struct d11regs *regs = wlc_hw->regs; + uint i; + uint count; + + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); + + count = (nbytes / sizeof(u32)); + + W_REG(®s->objaddr, (OBJADDR_AUTO_INC | OBJADDR_UCM_SEL)); + (void)R_REG(®s->objaddr); + for (i = 0; i < count; i++) + W_REG(®s->objdata, le32_to_cpu(ucode[i])); + +} + +static void brcms_c_write_inits(struct brcms_hardware *wlc_hw, + const struct d11init *inits) +{ + int i; + u8 *base; + u8 *addr; + u16 size; + u32 value; + + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); + + base = (u8 *)wlc_hw->regs; + + for (i = 0; inits[i].addr != 0xffff; i++) { + size = le16_to_cpu(inits[i].size); + addr = base + le16_to_cpu(inits[i].addr); + value = le32_to_cpu(inits[i].value); + if (size == 2) + W_REG((u16 *)addr, value); + else if (size == 4) + W_REG((u32 *)addr, value); + else + break; + } +} + +static void brcms_c_ucode_txant_set(struct brcms_hardware *wlc_hw) +{ + u16 phyctl; + u16 phytxant = wlc_hw->bmac_phytxant; + u16 mask = PHY_TXC_ANT_MASK; + + /* set the Probe Response frame phy control word */ + phyctl = brcms_b_read_shm(wlc_hw, M_CTXPRS_BLK + C_CTX_PCTLWD_POS); + phyctl = (phyctl & ~mask) | phytxant; + brcms_b_write_shm(wlc_hw, M_CTXPRS_BLK + C_CTX_PCTLWD_POS, phyctl); + + /* set the Response (ACK/CTS) frame phy control word */ + phyctl = brcms_b_read_shm(wlc_hw, M_RSP_PCTLWD); + phyctl = (phyctl & ~mask) | phytxant; + brcms_b_write_shm(wlc_hw, M_RSP_PCTLWD, phyctl); +} + +void brcms_b_txant_set(struct brcms_hardware *wlc_hw, u16 phytxant) +{ + /* update sw state */ + wlc_hw->bmac_phytxant = phytxant; + + /* push to ucode if up */ + if (!wlc_hw->up) + return; + brcms_c_ucode_txant_set(wlc_hw); + +} + +u16 brcms_b_get_txant(struct brcms_hardware *wlc_hw) +{ + return (u16) wlc_hw->wlc->stf->txant; +} + +void brcms_b_antsel_type_set(struct brcms_hardware *wlc_hw, u8 antsel_type) +{ + wlc_hw->antsel_type = antsel_type; + + /* Update the antsel type for phy module to use */ + wlc_phy_antsel_type_set(wlc_hw->band->pi, antsel_type); +} + +void brcms_b_fifoerrors(struct brcms_hardware *wlc_hw) +{ + bool fatal = false; + uint unit; + uint intstatus, idx; + struct d11regs *regs = wlc_hw->regs; + struct wiphy *wiphy = wlc_hw->wlc->wiphy; + + unit = wlc_hw->unit; + + for (idx = 0; idx < NFIFO; idx++) { + /* read intstatus register and ignore any non-error bits */ + intstatus = + R_REG(®s->intctrlregs[idx].intstatus) & I_ERRORS; + if (!intstatus) + continue; + + BCMMSG(wlc_hw->wlc->wiphy, "wl%d: intstatus%d 0x%x\n", + unit, idx, intstatus); + + if (intstatus & I_RO) { + wiphy_err(wiphy, "wl%d: fifo %d: receive fifo " + "overflow\n", unit, idx); + fatal = true; + } + + if (intstatus & I_PC) { + wiphy_err(wiphy, "wl%d: fifo %d: descriptor error\n", + unit, idx); + fatal = true; + } + + if (intstatus & I_PD) { + wiphy_err(wiphy, "wl%d: fifo %d: data error\n", unit, + idx); + fatal = true; + } + + if (intstatus & I_DE) { + wiphy_err(wiphy, "wl%d: fifo %d: descriptor protocol " + "error\n", unit, idx); + fatal = true; + } + + if (intstatus & I_RU) + wiphy_err(wiphy, "wl%d: fifo %d: receive descriptor " + "underflow\n", idx, unit); + + if (intstatus & I_XU) { + wiphy_err(wiphy, "wl%d: fifo %d: transmit fifo " + "underflow\n", idx, unit); + fatal = true; + } + + if (fatal) { + brcms_c_fatal_error(wlc_hw->wlc); /* big hammer */ + break; + } else + W_REG(®s->intctrlregs[idx].intstatus, + intstatus); + } +} + +void brcms_c_intrson(struct brcms_c_info *wlc) +{ + struct brcms_hardware *wlc_hw = wlc->hw; + wlc->macintmask = wlc->defmacintmask; + W_REG(&wlc_hw->regs->macintmask, wlc->macintmask); +} + +/* + * callback for siutils.c, which has only wlc handler, no wl they both check + * up, not only because there is no need to off/restore d11 interrupt but also + * because per-port code may require sync with valid interrupt. + */ +static u32 brcms_c_wlintrsoff(struct brcms_c_info *wlc) +{ + if (!wlc->hw->up) + return 0; + + return brcms_intrsoff(wlc->wl); +} + +static void brcms_c_wlintrsrestore(struct brcms_c_info *wlc, u32 macintmask) +{ + if (!wlc->hw->up) + return; + + brcms_intrsrestore(wlc->wl, macintmask); +} + +u32 brcms_c_intrsoff(struct brcms_c_info *wlc) +{ + struct brcms_hardware *wlc_hw = wlc->hw; + u32 macintmask; + + if (!wlc_hw->clk) + return 0; + + macintmask = wlc->macintmask; /* isr can still happen */ + + W_REG(&wlc_hw->regs->macintmask, 0); + (void)R_REG(&wlc_hw->regs->macintmask); /* sync readback */ + udelay(1); /* ensure int line is no longer driven */ + wlc->macintmask = 0; + + /* return previous macintmask; resolve race between us and our isr */ + return wlc->macintstatus ? 0 : macintmask; +} + +void brcms_c_intrsrestore(struct brcms_c_info *wlc, u32 macintmask) +{ + struct brcms_hardware *wlc_hw = wlc->hw; + if (!wlc_hw->clk) + return; + + wlc->macintmask = macintmask; + W_REG(&wlc_hw->regs->macintmask, wlc->macintmask); +} + +static void brcms_b_tx_fifo_suspend(struct brcms_hardware *wlc_hw, + uint tx_fifo) +{ + u8 fifo = 1 << tx_fifo; + + /* Two clients of this code, 11h Quiet period and scanning. */ + + /* only suspend if not already suspended */ + if ((wlc_hw->suspended_fifos & fifo) == fifo) + return; + + /* force the core awake only if not already */ + if (wlc_hw->suspended_fifos == 0) + brcms_c_ucode_wake_override_set(wlc_hw, + BRCMS_WAKE_OVERRIDE_TXFIFO); + + wlc_hw->suspended_fifos |= fifo; + + if (wlc_hw->di[tx_fifo]) { + /* + * Suspending AMPDU transmissions in the middle can cause + * underflow which may result in mismatch between ucode and + * driver so suspend the mac before suspending the FIFO + */ + if (BRCMS_PHY_11N_CAP(wlc_hw->band)) + brcms_c_suspend_mac_and_wait(wlc_hw->wlc); + + dma_txsuspend(wlc_hw->di[tx_fifo]); + + if (BRCMS_PHY_11N_CAP(wlc_hw->band)) + brcms_c_enable_mac(wlc_hw->wlc); + } +} + +static void brcms_b_mute(struct brcms_hardware *wlc_hw, bool on, u32 flags) +{ + u8 null_ether_addr[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; + + if (on) { + /* suspend tx fifos */ + brcms_b_tx_fifo_suspend(wlc_hw, TX_DATA_FIFO); + brcms_b_tx_fifo_suspend(wlc_hw, TX_CTL_FIFO); + brcms_b_tx_fifo_suspend(wlc_hw, TX_AC_BK_FIFO); + brcms_b_tx_fifo_suspend(wlc_hw, TX_AC_VI_FIFO); + + /* zero the address match register so we do not send ACKs */ + brcms_b_set_addrmatch(wlc_hw, RCM_MAC_OFFSET, + null_ether_addr); + } else { + /* resume tx fifos */ + if (!wlc_hw->wlc->tx_suspended) + brcms_b_tx_fifo_resume(wlc_hw, TX_DATA_FIFO); + + brcms_b_tx_fifo_resume(wlc_hw, TX_CTL_FIFO); + brcms_b_tx_fifo_resume(wlc_hw, TX_AC_BK_FIFO); + brcms_b_tx_fifo_resume(wlc_hw, TX_AC_VI_FIFO); + + /* Restore address */ + brcms_b_set_addrmatch(wlc_hw, RCM_MAC_OFFSET, + wlc_hw->etheraddr); + } + + wlc_phy_mute_upd(wlc_hw->band->pi, on, flags); + + if (on) + brcms_c_ucode_mute_override_set(wlc_hw); + else + brcms_c_ucode_mute_override_clear(wlc_hw); +} + +/* brcms_b_tx_fifo_suspended: + * Check the MAC's tx suspend status for a tx fifo. + * + * When the MAC acknowledges a tx suspend, it indicates that no more + * packets will be transmitted out the radio. This is independent of + * DMA channel suspension---the DMA may have finished suspending, or may still + * be pulling data into a tx fifo, by the time the MAC acks the suspend + * request. + */ +static bool brcms_b_tx_fifo_suspended(struct brcms_hardware *wlc_hw, + uint tx_fifo) +{ + /* check that a suspend has been requested and is no longer pending */ + + /* + * for DMA mode, the suspend request is set in xmtcontrol of the DMA + * engine, and the tx fifo suspend at the lower end of the MAC is + * acknowledged in the chnstatus register. + * + * The tx fifo suspend completion is independent of the DMA suspend + * completion and may be acked before or after the DMA is suspended. + */ + if (dma_txsuspended(wlc_hw->di[tx_fifo]) && + (R_REG(&wlc_hw->regs->chnstatus) & + (1 << tx_fifo)) == 0) + return true; + + return false; +} + +static void brcms_b_tx_fifo_resume(struct brcms_hardware *wlc_hw, + uint tx_fifo) +{ + /* BMAC_NOTE: BRCMS_TX_FIFO_ENAB is done in brcms_c_dpc() for DMA case + * but need to be done here for PIO otherwise the watchdog will catch + * the inconsistency and fire + */ + /* Two clients of this code, 11h Quiet period and scanning. */ + if (wlc_hw->di[tx_fifo]) + dma_txresume(wlc_hw->di[tx_fifo]); + + /* allow core to sleep again */ + if (wlc_hw->suspended_fifos == 0) + return; + else { + wlc_hw->suspended_fifos &= ~(1 << tx_fifo); + if (wlc_hw->suspended_fifos == 0) + brcms_c_ucode_wake_override_clear(wlc_hw, + BRCMS_WAKE_OVERRIDE_TXFIFO); + } +} + +/* + * Read and clear macintmask and macintstatus and intstatus registers. + * This routine should be called with interrupts off + * Return: + * -1 if DEVICEREMOVED(wlc) evaluates to true; + * 0 if the interrupt is not for us, or we are in some special cases; + * device interrupt status bits otherwise. + */ +static inline u32 wlc_intstatus(struct brcms_c_info *wlc, bool in_isr) +{ + struct brcms_hardware *wlc_hw = wlc->hw; + struct d11regs *regs = wlc_hw->regs; + u32 macintstatus; + + /* macintstatus includes a DMA interrupt summary bit */ + macintstatus = R_REG(®s->macintstatus); + + BCMMSG(wlc->wiphy, "wl%d: macintstatus: 0x%x\n", wlc_hw->unit, + macintstatus); + + /* detect cardbus removed, in power down(suspend) and in reset */ + if (DEVICEREMOVED(wlc)) + return -1; + + /* DEVICEREMOVED succeeds even when the core is still resetting, + * handle that case here. + */ + if (macintstatus == 0xffffffff) + return 0; + + /* defer unsolicited interrupts */ + macintstatus &= (in_isr ? wlc->macintmask : wlc->defmacintmask); + + /* if not for us */ + if (macintstatus == 0) + return 0; + + /* interrupts are already turned off for CFE build + * Caution: For CFE Turning off the interrupts again has some undesired + * consequences + */ + /* turn off the interrupts */ + W_REG(®s->macintmask, 0); + (void)R_REG(®s->macintmask); /* sync readback */ + wlc->macintmask = 0; + + /* clear device interrupts */ + W_REG(®s->macintstatus, macintstatus); + + /* MI_DMAINT is indication of non-zero intstatus */ + if (macintstatus & MI_DMAINT) + /* + * only fifo interrupt enabled is I_RI in + * RX_FIFO. If MI_DMAINT is set, assume it + * is set and clear the interrupt. + */ + W_REG(®s->intctrlregs[RX_FIFO].intstatus, + DEF_RXINTMASK); + + return macintstatus; +} + +/* Update wlc->macintstatus and wlc->intstatus[]. */ +/* Return true if they are updated successfully. false otherwise */ +bool brcms_c_intrsupd(struct brcms_c_info *wlc) +{ + u32 macintstatus; + + /* read and clear macintstatus and intstatus registers */ + macintstatus = wlc_intstatus(wlc, false); + + /* device is removed */ + if (macintstatus == 0xffffffff) + return false; + + /* update interrupt status in software */ + wlc->macintstatus |= macintstatus; + + return true; +} + +/* + * First-level interrupt processing. + * Return true if this was our interrupt, false otherwise. + * *wantdpc will be set to true if further brcms_c_dpc() processing is required, + * false otherwise. + */ +bool brcms_c_isr(struct brcms_c_info *wlc, bool *wantdpc) +{ + struct brcms_hardware *wlc_hw = wlc->hw; + u32 macintstatus; + + *wantdpc = false; + + if (!wlc_hw->up || !wlc->macintmask) + return false; + + /* read and clear macintstatus and intstatus registers */ + macintstatus = wlc_intstatus(wlc, true); + + if (macintstatus == 0xffffffff) + wiphy_err(wlc->wiphy, "DEVICEREMOVED detected in the ISR code" + " path\n"); + + /* it is not for us */ + if (macintstatus == 0) + return false; + + *wantdpc = true; + + /* save interrupt status bits */ + wlc->macintstatus = macintstatus; + + return true; + +} + +void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc) +{ + struct brcms_hardware *wlc_hw = wlc->hw; + struct d11regs *regs = wlc_hw->regs; + u32 mc, mi; + struct wiphy *wiphy = wlc->wiphy; + + BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit, + wlc_hw->band->bandunit); + + /* + * Track overlapping suspend requests + */ + wlc_hw->mac_suspend_depth++; + if (wlc_hw->mac_suspend_depth > 1) + return; + + /* force the core awake */ + brcms_c_ucode_wake_override_set(wlc_hw, BRCMS_WAKE_OVERRIDE_MACSUSPEND); + + mc = R_REG(®s->maccontrol); + + if (mc == 0xffffffff) { + wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, + __func__); + brcms_down(wlc->wl); + return; + } + WARN_ON(mc & MCTL_PSM_JMP_0); + WARN_ON(!(mc & MCTL_PSM_RUN)); + WARN_ON(!(mc & MCTL_EN_MAC)); + + mi = R_REG(®s->macintstatus); + if (mi == 0xffffffff) { + wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, + __func__); + brcms_down(wlc->wl); + return; + } + WARN_ON(mi & MI_MACSSPNDD); + + brcms_b_mctrl(wlc_hw, MCTL_EN_MAC, 0); + + SPINWAIT(!(R_REG(®s->macintstatus) & MI_MACSSPNDD), + BRCMS_MAX_MAC_SUSPEND); + + if (!(R_REG(®s->macintstatus) & MI_MACSSPNDD)) { + wiphy_err(wiphy, "wl%d: wlc_suspend_mac_and_wait: waited %d uS" + " and MI_MACSSPNDD is still not on.\n", + wlc_hw->unit, BRCMS_MAX_MAC_SUSPEND); + wiphy_err(wiphy, "wl%d: psmdebug 0x%08x, phydebug 0x%08x, " + "psm_brc 0x%04x\n", wlc_hw->unit, + R_REG(®s->psmdebug), + R_REG(®s->phydebug), + R_REG(®s->psm_brc)); + } + + mc = R_REG(®s->maccontrol); + if (mc == 0xffffffff) { + wiphy_err(wiphy, "wl%d: %s: dead chip\n", wlc_hw->unit, + __func__); + brcms_down(wlc->wl); + return; + } + WARN_ON(mc & MCTL_PSM_JMP_0); + WARN_ON(!(mc & MCTL_PSM_RUN)); + WARN_ON(mc & MCTL_EN_MAC); +} + +void brcms_c_enable_mac(struct brcms_c_info *wlc) +{ + struct brcms_hardware *wlc_hw = wlc->hw; + struct d11regs *regs = wlc_hw->regs; + u32 mc, mi; + + BCMMSG(wlc->wiphy, "wl%d: bandunit %d\n", wlc_hw->unit, + wlc->band->bandunit); + + /* + * Track overlapping suspend requests + */ + wlc_hw->mac_suspend_depth--; + if (wlc_hw->mac_suspend_depth > 0) + return; + + mc = R_REG(®s->maccontrol); + WARN_ON(mc & MCTL_PSM_JMP_0); + WARN_ON(mc & MCTL_EN_MAC); + WARN_ON(!(mc & MCTL_PSM_RUN)); + + brcms_b_mctrl(wlc_hw, MCTL_EN_MAC, MCTL_EN_MAC); + W_REG(®s->macintstatus, MI_MACSSPNDD); + + mc = R_REG(®s->maccontrol); + WARN_ON(mc & MCTL_PSM_JMP_0); + WARN_ON(!(mc & MCTL_EN_MAC)); + WARN_ON(!(mc & MCTL_PSM_RUN)); + + mi = R_REG(®s->macintstatus); + WARN_ON(mi & MI_MACSSPNDD); + + brcms_c_ucode_wake_override_clear(wlc_hw, + BRCMS_WAKE_OVERRIDE_MACSUSPEND); +} + +static void brcms_upd_ofdm_pctl1_table(struct brcms_hardware *wlc_hw) +{ + u8 rate; + u8 rates[8] = { + BRCM_RATE_6M, BRCM_RATE_9M, BRCM_RATE_12M, BRCM_RATE_18M, + BRCM_RATE_24M, BRCM_RATE_36M, BRCM_RATE_48M, BRCM_RATE_54M + }; + u16 entry_ptr; + u16 pctl1; + uint i; + + if (!BRCMS_PHY_11N_CAP(wlc_hw->band)) + return; + + /* walk the phy rate table and update the entries */ + for (i = 0; i < ARRAY_SIZE(rates); i++) { + rate = rates[i]; + + entry_ptr = brcms_b_ofdm_ratetable_offset(wlc_hw, rate); + + /* read the SHM Rate Table entry OFDM PCTL1 values */ + pctl1 = + brcms_b_read_shm(wlc_hw, entry_ptr + M_RT_OFDM_PCTL1_POS); + + /* modify the value */ + pctl1 &= ~PHY_TXC1_MODE_MASK; + pctl1 |= (wlc_hw->hw_stf_ss_opmode << PHY_TXC1_MODE_SHIFT); + + /* Update the SHM Rate Table entry OFDM PCTL1 values */ + brcms_b_write_shm(wlc_hw, entry_ptr + M_RT_OFDM_PCTL1_POS, + pctl1); + } +} + +static u16 brcms_b_ofdm_ratetable_offset(struct brcms_hardware *wlc_hw, + u8 rate) +{ + uint i; + u8 plcp_rate = 0; + struct plcp_signal_rate_lookup { + u8 rate; + u8 signal_rate; + }; + /* OFDM RATE sub-field of PLCP SIGNAL field, per 802.11 sec 17.3.4.1 */ + const struct plcp_signal_rate_lookup rate_lookup[] = { + {BRCM_RATE_6M, 0xB}, + {BRCM_RATE_9M, 0xF}, + {BRCM_RATE_12M, 0xA}, + {BRCM_RATE_18M, 0xE}, + {BRCM_RATE_24M, 0x9}, + {BRCM_RATE_36M, 0xD}, + {BRCM_RATE_48M, 0x8}, + {BRCM_RATE_54M, 0xC} + }; + + for (i = 0; i < ARRAY_SIZE(rate_lookup); i++) { + if (rate == rate_lookup[i].rate) { + plcp_rate = rate_lookup[i].signal_rate; + break; + } + } + + /* Find the SHM pointer to the rate table entry by looking in the + * Direct-map Table + */ + return 2 * brcms_b_read_shm(wlc_hw, M_RT_DIRMAP_A + (plcp_rate * 2)); +} + +void brcms_b_band_stf_ss_set(struct brcms_hardware *wlc_hw, u8 stf_mode) +{ + wlc_hw->hw_stf_ss_opmode = stf_mode; + + if (wlc_hw->clk) + brcms_upd_ofdm_pctl1_table(wlc_hw); +} + +static bool brcms_b_validate_chip_access(struct brcms_hardware *wlc_hw) +{ + struct d11regs *regs; + u32 w, val; + struct wiphy *wiphy = wlc_hw->wlc->wiphy; + + BCMMSG(wiphy, "wl%d\n", wlc_hw->unit); + + regs = wlc_hw->regs; + + /* Validate dchip register access */ + + W_REG(®s->objaddr, OBJADDR_SHM_SEL | 0); + (void)R_REG(®s->objaddr); + w = R_REG(®s->objdata); + + /* Can we write and read back a 32bit register? */ + W_REG(®s->objaddr, OBJADDR_SHM_SEL | 0); + (void)R_REG(®s->objaddr); + W_REG(®s->objdata, (u32) 0xaa5555aa); + + W_REG(®s->objaddr, OBJADDR_SHM_SEL | 0); + (void)R_REG(®s->objaddr); + val = R_REG(®s->objdata); + if (val != (u32) 0xaa5555aa) { + wiphy_err(wiphy, "wl%d: validate_chip_access: SHM = 0x%x, " + "expected 0xaa5555aa\n", wlc_hw->unit, val); + return false; + } + + W_REG(®s->objaddr, OBJADDR_SHM_SEL | 0); + (void)R_REG(®s->objaddr); + W_REG(®s->objdata, (u32) 0x55aaaa55); + + W_REG(®s->objaddr, OBJADDR_SHM_SEL | 0); + (void)R_REG(®s->objaddr); + val = R_REG(®s->objdata); + if (val != (u32) 0x55aaaa55) { + wiphy_err(wiphy, "wl%d: validate_chip_access: SHM = 0x%x, " + "expected 0x55aaaa55\n", wlc_hw->unit, val); + return false; + } + + W_REG(®s->objaddr, OBJADDR_SHM_SEL | 0); + (void)R_REG(®s->objaddr); + W_REG(®s->objdata, w); + + /* clear CFPStart */ + W_REG(®s->tsf_cfpstart, 0); + + w = R_REG(®s->maccontrol); + if ((w != (MCTL_IHR_EN | MCTL_WAKE)) && + (w != (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE))) { + wiphy_err(wiphy, "wl%d: validate_chip_access: maccontrol = " + "0x%x, expected 0x%x or 0x%x\n", wlc_hw->unit, w, + (MCTL_IHR_EN | MCTL_WAKE), + (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE)); + return false; + } + + return true; +} + +#define PHYPLL_WAIT_US 100000 + +void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on) +{ + struct d11regs *regs; + u32 tmp; + + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); + + tmp = 0; + regs = wlc_hw->regs; + + if (on) { + if ((wlc_hw->sih->chip == BCM4313_CHIP_ID)) { + OR_REG(®s->clk_ctl_st, + (CCS_ERSRC_REQ_HT | CCS_ERSRC_REQ_D11PLL | + CCS_ERSRC_REQ_PHYPLL)); + SPINWAIT((R_REG(®s->clk_ctl_st) & + (CCS_ERSRC_AVAIL_HT)) != (CCS_ERSRC_AVAIL_HT), + PHYPLL_WAIT_US); + + tmp = R_REG(®s->clk_ctl_st); + if ((tmp & (CCS_ERSRC_AVAIL_HT)) != + (CCS_ERSRC_AVAIL_HT)) + wiphy_err(wlc_hw->wlc->wiphy, "%s: turn on PHY" + " PLL failed\n", __func__); + } else { + OR_REG(®s->clk_ctl_st, + (CCS_ERSRC_REQ_D11PLL | CCS_ERSRC_REQ_PHYPLL)); + SPINWAIT((R_REG(®s->clk_ctl_st) & + (CCS_ERSRC_AVAIL_D11PLL | + CCS_ERSRC_AVAIL_PHYPLL)) != + (CCS_ERSRC_AVAIL_D11PLL | + CCS_ERSRC_AVAIL_PHYPLL), PHYPLL_WAIT_US); + + tmp = R_REG(®s->clk_ctl_st); + if ((tmp & + (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL)) + != + (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL)) + wiphy_err(wlc_hw->wlc->wiphy, "%s: turn on " + "PHY PLL failed\n", __func__); + } + } else { + /* + * Since the PLL may be shared, other cores can still + * be requesting it; so we'll deassert the request but + * not wait for status to comply. + */ + AND_REG(®s->clk_ctl_st, ~CCS_ERSRC_REQ_PHYPLL); + tmp = R_REG(®s->clk_ctl_st); + } +} + +void brcms_c_coredisable(struct brcms_hardware *wlc_hw) +{ + bool dev_gone; + + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); + + dev_gone = DEVICEREMOVED(wlc_hw->wlc); + + if (dev_gone) + return; + + if (wlc_hw->noreset) + return; + + /* radio off */ + wlc_phy_switch_radio(wlc_hw->band->pi, OFF); + + /* turn off analog core */ + wlc_phy_anacore(wlc_hw->band->pi, OFF); + + /* turn off PHYPLL to save power */ + brcms_b_core_phypll_ctl(wlc_hw, false); + + /* No need to set wlc->pub->radio_active = OFF + * because this function needs down capability and + * radio_active is designed for BCMNODOWN. + */ + + /* remove gpio controls */ + if (wlc_hw->ucode_dbgsel) + ai_gpiocontrol(wlc_hw->sih, ~0, 0, GPIO_DRV_PRIORITY); + + wlc_hw->clk = false; + ai_core_disable(wlc_hw->sih, 0); + wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false); +} + +/* power both the pll and external oscillator on/off */ +static void brcms_b_xtal(struct brcms_hardware *wlc_hw, bool want) +{ + BCMMSG(wlc_hw->wlc->wiphy, "wl%d: want %d\n", wlc_hw->unit, want); + + /* + * dont power down if plldown is false or + * we must poll hw radio disable + */ + if (!want && wlc_hw->pllreq) + return; + + if (wlc_hw->sih) + ai_clkctl_xtal(wlc_hw->sih, XTAL | PLL, want); + + wlc_hw->sbclk = want; + if (!wlc_hw->sbclk) { + wlc_hw->clk = false; + if (wlc_hw->band && wlc_hw->band->pi) + wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false); + } +} + +static void brcms_c_flushqueues(struct brcms_c_info *wlc) +{ + struct brcms_hardware *wlc_hw = wlc->hw; + uint i; + + wlc->txpend16165war = 0; + + /* free any posted tx packets */ + for (i = 0; i < NFIFO; i++) + if (wlc_hw->di[i]) { + dma_txreclaim(wlc_hw->di[i], DMA_RANGE_ALL); + TXPKTPENDCLR(wlc, i); + BCMMSG(wlc->wiphy, "pktpend fifo %d clrd\n", i); + } + + /* free any posted rx packets */ + dma_rxreclaim(wlc_hw->di[RX_FIFO]); +} + +u16 brcms_b_read_shm(struct brcms_hardware *wlc_hw, uint offset) +{ + return brcms_b_read_objmem(wlc_hw, offset, OBJADDR_SHM_SEL); +} + +void brcms_b_write_shm(struct brcms_hardware *wlc_hw, uint offset, u16 v) +{ + brcms_b_write_objmem(wlc_hw, offset, v, OBJADDR_SHM_SEL); +} + +static u16 +brcms_b_read_objmem(struct brcms_hardware *wlc_hw, uint offset, u32 sel) +{ + struct d11regs *regs = wlc_hw->regs; + u16 *objdata_lo = (u16 *)®s->objdata; + u16 *objdata_hi = objdata_lo + 1; + u16 v; + + W_REG(®s->objaddr, sel | (offset >> 2)); + (void)R_REG(®s->objaddr); + if (offset & 2) + v = R_REG(objdata_hi); + else + v = R_REG(objdata_lo); + + return v; +} + +static void +brcms_b_write_objmem(struct brcms_hardware *wlc_hw, uint offset, u16 v, + u32 sel) +{ + struct d11regs *regs = wlc_hw->regs; + u16 *objdata_lo = (u16 *)®s->objdata; + u16 *objdata_hi = objdata_lo + 1; + + W_REG(®s->objaddr, sel | (offset >> 2)); + (void)R_REG(®s->objaddr); + if (offset & 2) + W_REG(objdata_hi, v); + else + W_REG(objdata_lo, v); +} + +/* Copy a buffer to shared memory of specified type . + * SHM 'offset' needs to be an even address and + * Buffer length 'len' must be an even number of bytes + * 'sel' selects the type of memory + */ +void +brcms_b_copyto_objmem(struct brcms_hardware *wlc_hw, uint offset, + const void *buf, int len, u32 sel) +{ + u16 v; + const u8 *p = (const u8 *)buf; + int i; + + if (len <= 0 || (offset & 1) || (len & 1)) + return; + + for (i = 0; i < len; i += 2) { + v = p[i] | (p[i + 1] << 8); + brcms_b_write_objmem(wlc_hw, offset + i, v, sel); + } +} + +/* Copy a piece of shared memory of specified type to a buffer . + * SHM 'offset' needs to be an even address and + * Buffer length 'len' must be an even number of bytes + * 'sel' selects the type of memory + */ +void +brcms_b_copyfrom_objmem(struct brcms_hardware *wlc_hw, uint offset, void *buf, + int len, u32 sel) +{ + u16 v; + u8 *p = (u8 *) buf; + int i; + + if (len <= 0 || (offset & 1) || (len & 1)) + return; + + for (i = 0; i < len; i += 2) { + v = brcms_b_read_objmem(wlc_hw, offset + i, sel); + p[i] = v & 0xFF; + p[i + 1] = (v >> 8) & 0xFF; + } +} + +void brcms_b_copyfrom_vars(struct brcms_hardware *wlc_hw, char **buf, + uint *len) +{ + BCMMSG(wlc_hw->wlc->wiphy, "nvram vars totlen=%d\n", + wlc_hw->vars_size); + + *buf = wlc_hw->vars; + *len = wlc_hw->vars_size; +} + +void brcms_b_retrylimit_upd(struct brcms_hardware *wlc_hw, u16 SRL, u16 LRL) +{ + wlc_hw->SRL = SRL; + wlc_hw->LRL = LRL; + + /* write retry limit to SCR, shouldn't need to suspend */ + if (wlc_hw->up) { + W_REG(&wlc_hw->regs->objaddr, + OBJADDR_SCR_SEL | S_DOT11_SRC_LMT); + (void)R_REG(&wlc_hw->regs->objaddr); + W_REG(&wlc_hw->regs->objdata, wlc_hw->SRL); + W_REG(&wlc_hw->regs->objaddr, + OBJADDR_SCR_SEL | S_DOT11_LRC_LMT); + (void)R_REG(&wlc_hw->regs->objaddr); + W_REG(&wlc_hw->regs->objdata, wlc_hw->LRL); + } +} + +void brcms_b_pllreq(struct brcms_hardware *wlc_hw, bool set, u32 req_bit) +{ + if (set) { + if (mboolisset(wlc_hw->pllreq, req_bit)) + return; + + mboolset(wlc_hw->pllreq, req_bit); + + if (mboolisset(wlc_hw->pllreq, BRCMS_PLLREQ_FLIP)) { + if (!wlc_hw->sbclk) + brcms_b_xtal(wlc_hw, ON); + } + } else { + if (!mboolisset(wlc_hw->pllreq, req_bit)) + return; + + mboolclr(wlc_hw->pllreq, req_bit); + + if (mboolisset(wlc_hw->pllreq, BRCMS_PLLREQ_FLIP)) { + if (wlc_hw->sbclk) + brcms_b_xtal(wlc_hw, OFF); + } + } + + return; +} + +void brcms_b_antsel_set(struct brcms_hardware *wlc_hw, u32 antsel_avail) +{ + wlc_hw->antsel_avail = antsel_avail; +} + +/* + * conditions under which the PM bit should be set in outgoing frames + * and STAY_AWAKE is meaningful */ bool brcms_c_ps_allowed(struct brcms_c_info *wlc) { @@ -400,6 +3025,20 @@ bool brcms_c_ps_allowed(struct brcms_c_info *wlc) return true; } +void brcms_b_reset(struct brcms_hardware *wlc_hw) +{ + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); + + /* reset the core */ + if (!DEVICEREMOVED(wlc_hw->wlc)) + brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS); + + /* purge the dma rings */ + brcms_c_flushqueues(wlc_hw->wlc); + + brcms_c_reset_bmac_done(wlc_hw->wlc); +} + void brcms_c_reset(struct brcms_c_info *wlc) { BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); @@ -426,9 +3065,9 @@ void brcms_c_fatal_error(struct brcms_c_info *wlc) * if other configurations are in conflict (bandlocked, 11n mode disabled, * invalid channel for current country, etc.) */ -static chanspec_t brcms_c_init_chanspec(struct brcms_c_info *wlc) +static u16 brcms_c_init_chanspec(struct brcms_c_info *wlc) { - chanspec_t chanspec = + u16 chanspec = 1 | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE | WL_CHANSPEC_BAND_2G; @@ -445,10 +3084,245 @@ static void brcms_c_init_scb(struct brcms_c_info *wlc, struct scb *scb) scb->seqnum[i] = 0; } +/* d11 core init + * reset PSM + * download ucode/PCM + * let ucode run to suspended + * download ucode inits + * config other core registers + * init dma + */ +static void brcms_b_coreinit(struct brcms_c_info *wlc) +{ + struct brcms_hardware *wlc_hw = wlc->hw; + struct d11regs *regs; + u32 sflags; + uint bcnint_us; + uint i = 0; + bool fifosz_fixup = false; + int err = 0; + u16 buf[NFIFO]; + struct wiphy *wiphy = wlc->wiphy; + + regs = wlc_hw->regs; + + BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit); + + /* reset PSM */ + brcms_b_mctrl(wlc_hw, ~0, (MCTL_IHR_EN | MCTL_PSM_JMP_0 | MCTL_WAKE)); + + brcms_ucode_download(wlc_hw); + /* + * FIFOSZ fixup. driver wants to controls the fifo allocation. + */ + fifosz_fixup = true; + + /* let the PSM run to the suspended state, set mode to BSS STA */ + W_REG(®s->macintstatus, -1); + brcms_b_mctrl(wlc_hw, ~0, + (MCTL_IHR_EN | MCTL_INFRA | MCTL_PSM_RUN | MCTL_WAKE)); + + /* wait for ucode to self-suspend after auto-init */ + SPINWAIT(((R_REG(®s->macintstatus) & MI_MACSSPNDD) == 0), + 1000 * 1000); + if ((R_REG(®s->macintstatus) & MI_MACSSPNDD) == 0) + wiphy_err(wiphy, "wl%d: wlc_coreinit: ucode did not self-" + "suspend!\n", wlc_hw->unit); + + brcms_c_gpio_init(wlc); + + sflags = ai_core_sflags(wlc_hw->sih, 0, 0); + + if (D11REV_IS(wlc_hw->corerev, 23)) { + if (BRCMS_ISNPHY(wlc_hw->band)) + brcms_c_write_inits(wlc_hw, d11n0initvals16); + else + wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev" + " %d\n", __func__, wlc_hw->unit, + wlc_hw->corerev); + } else if (D11REV_IS(wlc_hw->corerev, 24)) { + if (BRCMS_ISLCNPHY(wlc_hw->band)) + brcms_c_write_inits(wlc_hw, d11lcn0initvals24); + else + wiphy_err(wiphy, "%s: wl%d: unsupported phy in corerev" + " %d\n", __func__, wlc_hw->unit, + wlc_hw->corerev); + } else { + wiphy_err(wiphy, "%s: wl%d: unsupported corerev %d\n", + __func__, wlc_hw->unit, wlc_hw->corerev); + } + + /* For old ucode, txfifo sizes needs to be modified(increased) */ + if (fifosz_fixup == true) + brcms_b_corerev_fifofixup(wlc_hw); + + /* check txfifo allocations match between ucode and driver */ + buf[TX_AC_BE_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE0); + if (buf[TX_AC_BE_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_BE_FIFO]) { + i = TX_AC_BE_FIFO; + err = -1; + } + buf[TX_AC_VI_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE1); + if (buf[TX_AC_VI_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_VI_FIFO]) { + i = TX_AC_VI_FIFO; + err = -1; + } + buf[TX_AC_BK_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE2); + buf[TX_AC_VO_FIFO] = (buf[TX_AC_BK_FIFO] >> 8) & 0xff; + buf[TX_AC_BK_FIFO] &= 0xff; + if (buf[TX_AC_BK_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_BK_FIFO]) { + i = TX_AC_BK_FIFO; + err = -1; + } + if (buf[TX_AC_VO_FIFO] != wlc_hw->xmtfifo_sz[TX_AC_VO_FIFO]) { + i = TX_AC_VO_FIFO; + err = -1; + } + buf[TX_BCMC_FIFO] = brcms_b_read_shm(wlc_hw, M_FIFOSIZE3); + buf[TX_ATIM_FIFO] = (buf[TX_BCMC_FIFO] >> 8) & 0xff; + buf[TX_BCMC_FIFO] &= 0xff; + if (buf[TX_BCMC_FIFO] != wlc_hw->xmtfifo_sz[TX_BCMC_FIFO]) { + i = TX_BCMC_FIFO; + err = -1; + } + if (buf[TX_ATIM_FIFO] != wlc_hw->xmtfifo_sz[TX_ATIM_FIFO]) { + i = TX_ATIM_FIFO; + err = -1; + } + if (err != 0) + wiphy_err(wiphy, "wlc_coreinit: txfifo mismatch: ucode size %d" + " driver size %d index %d\n", buf[i], + wlc_hw->xmtfifo_sz[i], i); + + /* make sure we can still talk to the mac */ + WARN_ON(R_REG(®s->maccontrol) == 0xffffffff); + + /* band-specific inits done by wlc_bsinit() */ + + /* Set up frame burst size and antenna swap threshold init values */ + brcms_b_write_shm(wlc_hw, M_MBURST_SIZE, MAXTXFRAMEBURST); + brcms_b_write_shm(wlc_hw, M_MAX_ANTCNT, ANTCNT); + + /* enable one rx interrupt per received frame */ + W_REG(®s->intrcvlazy[0], (1 << IRL_FC_SHIFT)); + + /* set the station mode (BSS STA) */ + brcms_b_mctrl(wlc_hw, + (MCTL_INFRA | MCTL_DISCARD_PMQ | MCTL_AP), + (MCTL_INFRA | MCTL_DISCARD_PMQ)); + + /* set up Beacon interval */ + bcnint_us = 0x8000 << 10; + W_REG(®s->tsf_cfprep, (bcnint_us << CFPREP_CBI_SHIFT)); + W_REG(®s->tsf_cfpstart, bcnint_us); + W_REG(®s->macintstatus, MI_GP1); + + /* write interrupt mask */ + W_REG(®s->intctrlregs[RX_FIFO].intmask, DEF_RXINTMASK); + + /* allow the MAC to control the PHY clock (dynamic on/off) */ + brcms_b_macphyclk_set(wlc_hw, ON); + + /* program dynamic clock control fast powerup delay register */ + wlc->fastpwrup_dly = ai_clkctl_fast_pwrup_delay(wlc_hw->sih); + W_REG(®s->scc_fastpwrup_dly, wlc->fastpwrup_dly); + + /* tell the ucode the corerev */ + brcms_b_write_shm(wlc_hw, M_MACHW_VER, (u16) wlc_hw->corerev); + + /* tell the ucode MAC capabilities */ + brcms_b_write_shm(wlc_hw, M_MACHW_CAP_L, + (u16) (wlc_hw->machwcap & 0xffff)); + brcms_b_write_shm(wlc_hw, M_MACHW_CAP_H, + (u16) ((wlc_hw-> + machwcap >> 16) & 0xffff)); + + /* write retry limits to SCR, this done after PSM init */ + W_REG(®s->objaddr, OBJADDR_SCR_SEL | S_DOT11_SRC_LMT); + (void)R_REG(®s->objaddr); + W_REG(®s->objdata, wlc_hw->SRL); + W_REG(®s->objaddr, OBJADDR_SCR_SEL | S_DOT11_LRC_LMT); + (void)R_REG(®s->objaddr); + W_REG(®s->objdata, wlc_hw->LRL); + + /* write rate fallback retry limits */ + brcms_b_write_shm(wlc_hw, M_SFRMTXCNTFBRTHSD, wlc_hw->SFBL); + brcms_b_write_shm(wlc_hw, M_LFRMTXCNTFBRTHSD, wlc_hw->LFBL); + + AND_REG(®s->ifs_ctl, 0x0FFF); + W_REG(®s->ifs_aifsn, EDCF_AIFSN_MIN); + + /* dma initializations */ + wlc->txpend16165war = 0; + + /* init the tx dma engines */ + for (i = 0; i < NFIFO; i++) { + if (wlc_hw->di[i]) + dma_txinit(wlc_hw->di[i]); + } + + /* init the rx dma engine(s) and post receive buffers */ + dma_rxinit(wlc_hw->di[RX_FIFO]); + dma_rxfill(wlc_hw->di[RX_FIFO]); +} + +void +brcms_b_init(struct brcms_hardware *wlc_hw, u16 chanspec, + bool mute) { + u32 macintmask; + bool fastclk; + struct brcms_c_info *wlc = wlc_hw->wlc; + + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); + + /* request FAST clock if not on */ + fastclk = wlc_hw->forcefastclk; + if (!fastclk) + brcms_b_clkctl_clk(wlc_hw, CLK_FAST); + + /* disable interrupts */ + macintmask = brcms_intrsoff(wlc->wl); + + /* set up the specified band and chanspec */ + brcms_c_setxband(wlc_hw, CHSPEC_BANDUNIT(chanspec)); + wlc_phy_chanspec_radio_set(wlc_hw->band->pi, chanspec); + + /* do one-time phy inits and calibration */ + wlc_phy_cal_init(wlc_hw->band->pi); + + /* core-specific initialization */ + brcms_b_coreinit(wlc); + + /* suspend the tx fifos and mute the phy for preism cac time */ + if (mute) + brcms_b_mute(wlc_hw, ON, PHY_MUTE_FOR_PREISM); + + /* band-specific inits */ + brcms_b_bsinit(wlc, chanspec); + + /* restore macintmask */ + brcms_intrsrestore(wlc->wl, macintmask); + + /* seed wake_override with BRCMS_WAKE_OVERRIDE_MACSUSPEND since the mac + * is suspended and brcms_c_enable_mac() will clear this override bit. + */ + mboolset(wlc_hw->wake_override, BRCMS_WAKE_OVERRIDE_MACSUSPEND); + + /* + * initialize mac_suspend_depth to 1 to match ucode + * initial suspended state + */ + wlc_hw->mac_suspend_depth = 1; + + /* restore the clk */ + if (!fastclk) + brcms_b_clkctl_clk(wlc_hw, CLK_DYNAMIC); +} + void brcms_c_init(struct brcms_c_info *wlc) { - d11regs_t *regs; - chanspec_t chanspec; + struct d11regs *regs; + u16 chanspec; int i; struct brcms_bss_cfg *bsscfg; bool mute = false; @@ -457,8 +3331,10 @@ void brcms_c_init(struct brcms_c_info *wlc) regs = wlc->regs; - /* This will happen if a big-hammer was executed. In that case, we want to go back - * to the channel that we were on and not new channel + /* + * This will happen if a big-hammer was executed. In + * that case, we want to go back to the channel that + * we were on and not new channel */ if (wlc->pub->associated) chanspec = wlc->home_chanspec; @@ -474,14 +3350,14 @@ void brcms_c_init(struct brcms_c_info *wlc) brcms_c_reprate_init(wlc); /* write ethernet address to core */ - FOREACH_BSS(wlc, i, bsscfg) { + FOREACH_BSS(wlc, i, bsscfg) brcms_c_set_mac(bsscfg); brcms_c_set_bssid(bsscfg); - } + END_FOREACH_BSS() /* Update tsf_cfprep if associated and up */ if (wlc->pub->associated) { - FOREACH_BSS(wlc, i, bsscfg) { + FOREACH_BSS(wlc, i, bsscfg) if (bsscfg->up) { u32 bi; @@ -499,7 +3375,7 @@ void brcms_c_init(struct brcms_c_info *wlc) break; } - } + END_FOREACH_BSS() } brcms_c_bandinit_ordered(wlc, chanspec); @@ -518,7 +3394,10 @@ void brcms_c_init(struct brcms_c_info *wlc) brcms_c_duty_cycle_set(wlc, wlc->tx_duty_cycle_ofdm, true, true); brcms_c_duty_cycle_set(wlc, wlc->tx_duty_cycle_cck, false, true); - /* Update some shared memory locations related to max AMPDU size allowed to received */ + /* + * Update some shared memory locations related to + * max AMPDU size allowed to received + */ brcms_c_ampdu_shm_upd(wlc->ampdu); /* band-specific inits */ @@ -563,10 +3442,9 @@ void brcms_c_init(struct brcms_c_info *wlc) /* Uninitialized; read from HW */ int ac; - for (ac = 0; ac < AC_COUNT; ac++) { + for (ac = 0; ac < AC_COUNT; ac++) wlc->wme_retries[ac] = brcms_c_read_shm(wlc, M_AC_TXLMT_ADDR(ac)); - } } } @@ -590,9 +3468,11 @@ void brcms_c_mac_promisc(struct brcms_c_info *wlc) { u32 promisc_bits = 0; - /* promiscuous mode just sets MCTL_PROMISC - * Note: APs get all BSS traffic without the need to set the MCTL_PROMISC bit - * since all BSS data traffic is directed at the AP + /* + * promiscuous mode just sets MCTL_PROMISC + * Note: APs get all BSS traffic without the need to set + * the MCTL_PROMISC bit since all BSS data traffic is + * directed at the AP */ if (PROMISC_ENAB(wlc->pub) && !AP_ENAB(wlc->pub)) promisc_bits |= MCTL_PROMISC; @@ -641,10 +3521,9 @@ int brcms_c_set_mac(struct brcms_bss_cfg *cfg) int err = 0; struct brcms_c_info *wlc = cfg->wlc; - if (cfg == wlc->cfg) { + if (cfg == wlc->cfg) /* enter the MAC addr into the RXE match registers */ brcms_c_set_addrmatch(wlc, RCM_MAC_OFFSET, cfg->cur_etheraddr); - } brcms_c_ampdu_macaddr_upd(wlc); @@ -659,14 +3538,19 @@ void brcms_c_set_bssid(struct brcms_bss_cfg *cfg) struct brcms_c_info *wlc = cfg->wlc; /* if primary config, we need to update BSSID in RXE match registers */ - if (cfg == wlc->cfg) { + if (cfg == wlc->cfg) brcms_c_set_addrmatch(wlc, RCM_BSSID_OFFSET, cfg->BSSID); +} + +void brcms_b_set_shortslot(struct brcms_hardware *wlc_hw, bool shortslot) +{ + wlc_hw->shortslot = shortslot; + + if (BAND_2G(brcms_b_bandtype(wlc_hw)) && wlc_hw->up) { + brcms_c_suspend_mac_and_wait(wlc_hw->wlc); + brcms_b_update_slot_timing(wlc_hw, shortslot); + brcms_c_enable_mac(wlc_hw->wlc); } -#ifdef SUPPORT_HWKEYS - else if (BSSCFG_STA(cfg) && cfg->BSS) { - brcms_c_rcmta_add_bssid(wlc, cfg); - } -#endif } /* @@ -688,7 +3572,7 @@ void brcms_c_switch_shortslot(struct brcms_c_info *wlc, bool shortslot) wlc->shortslot = shortslot; /* update the capability based on current shortslot mode */ - FOREACH_BSS(wlc, idx, cfg) { + FOREACH_BSS(wlc, idx, cfg) if (!cfg->associated) continue; cfg->current_bss->capability &= @@ -696,7 +3580,7 @@ void brcms_c_switch_shortslot(struct brcms_c_info *wlc, bool shortslot) if (wlc->shortslot) cfg->current_bss->capability |= WLAN_CAPABILITY_SHORT_SLOT_TIME; - } + END_FOREACH_BSS() brcms_b_set_shortslot(wlc->hw, shortslot); } @@ -728,8 +3612,11 @@ static u8 brcms_c_local_constraint_qdbm(struct brcms_c_info *wlc) return local; } -/* propagate home chanspec to all bsscfgs in case bsscfg->current_bss->chanspec is referenced */ -void brcms_c_set_home_chanspec(struct brcms_c_info *wlc, chanspec_t chanspec) +/* + * propagate home chanspec to all bsscfgs in + * case bsscfg->current_bss->chanspec is referenced + */ +void brcms_c_set_home_chanspec(struct brcms_c_info *wlc, u16 chanspec) { if (wlc->home_chanspec != chanspec) { int idx; @@ -737,18 +3624,19 @@ void brcms_c_set_home_chanspec(struct brcms_c_info *wlc, chanspec_t chanspec) wlc->home_chanspec = chanspec; - FOREACH_BSS(wlc, idx, cfg) { + FOREACH_BSS(wlc, idx, cfg) if (!cfg->associated) continue; cfg->current_bss->chanspec = chanspec; - } + END_FOREACH_BSS() + } } static void brcms_c_set_phy_chanspec(struct brcms_c_info *wlc, - chanspec_t chanspec) + u16 chanspec) { /* Save our copy of the chanspec */ wlc->chanspec = chanspec; @@ -767,11 +3655,55 @@ static void brcms_c_set_phy_chanspec(struct brcms_c_info *wlc, } -void brcms_c_set_chanspec(struct brcms_c_info *wlc, chanspec_t chanspec) +void +brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, u16 chanspec, + bool mute, struct txpwr_limits *txpwr) +{ + uint bandunit; + + BCMMSG(wlc_hw->wlc->wiphy, "wl%d: 0x%x\n", wlc_hw->unit, chanspec); + + wlc_hw->chanspec = chanspec; + + /* Switch bands if necessary */ + if (NBANDS_HW(wlc_hw) > 1) { + bandunit = CHSPEC_BANDUNIT(chanspec); + if (wlc_hw->band->bandunit != bandunit) { + /* brcms_b_setband disables other bandunit, + * use light band switch if not up yet + */ + if (wlc_hw->up) { + wlc_phy_chanspec_radio_set(wlc_hw-> + bandstate[bandunit]-> + pi, chanspec); + brcms_b_setband(wlc_hw, bandunit, chanspec); + } else { + brcms_c_setxband(wlc_hw, bandunit); + } + } + } + + wlc_phy_initcal_enable(wlc_hw->band->pi, !mute); + + if (!wlc_hw->up) { + if (wlc_hw->clk) + wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr, + chanspec); + wlc_phy_chanspec_radio_set(wlc_hw->band->pi, chanspec); + } else { + wlc_phy_chanspec_set(wlc_hw->band->pi, chanspec); + wlc_phy_txpower_limit_set(wlc_hw->band->pi, txpwr, chanspec); + + /* Update muting of the channel */ + brcms_b_mute(wlc_hw, mute, 0); + } +} + +void brcms_c_set_chanspec(struct brcms_c_info *wlc, u16 chanspec) { uint bandunit; bool switchband = false; - chanspec_t old_chanspec = wlc->chanspec; + u16 old_chanspec = wlc->chanspec; if (!brcms_c_valid_chanspec_db(wlc->cmi, chanspec)) { wiphy_err(wlc->wiphy, "wl%d: %s: Bad channel %d\n", @@ -823,10 +3755,10 @@ void brcms_c_set_chanspec(struct brcms_c_info *wlc, chanspec_t chanspec) brcms_c_ucode_mac_upd(wlc); } -ratespec_t brcms_c_lowest_basic_rspec(struct brcms_c_info *wlc, - wlc_rateset_t *rs) +u32 brcms_c_lowest_basic_rspec(struct brcms_c_info *wlc, + struct brcms_c_rateset *rs) { - ratespec_t lowest_basic_rspec; + u32 lowest_basic_rspec; uint i; /* Use the lowest basic rate */ @@ -837,23 +3769,25 @@ ratespec_t brcms_c_lowest_basic_rspec(struct brcms_c_info *wlc, break; } } -#if NCONF - /* pick siso/cdd as default for OFDM (note no basic rate MCSs are supported yet) */ - if (IS_OFDM(lowest_basic_rspec)) { + + /* + * pick siso/cdd as default for OFDM (note no basic + * rate MCSs are supported yet) + */ + if (IS_OFDM(lowest_basic_rspec)) lowest_basic_rspec |= (wlc->stf->ss_opmode << RSPEC_STF_SHIFT); - } -#endif return lowest_basic_rspec; } -/* This function changes the phytxctl for beacon based on current beacon ratespec AND txant - * setting as per this table: +/* + * This function changes the phytxctl for beacon based on current + * beacon ratespec AND txant setting as per this table: * ratespec CCK ant = wlc->stf->txant * OFDM ant = 3 */ void brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info *wlc, - ratespec_t bcn_rspec) + u32 bcn_rspec) { u16 phyctl; u16 phytxant = wlc->stf->phytxant; @@ -868,9 +3802,11 @@ void brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info *wlc, brcms_c_write_shm(wlc, M_BCN_PCTLWD, phyctl); } -/* centralized protection config change function to simplify debugging, no consistency checking - * this should be called only on changes to avoid overhead in periodic function -*/ +/* + * centralized protection config change function to simplify debugging, no + * consistency checking this should be called only on changes to avoid overhead + * in periodic function + */ void brcms_c_protection_upd(struct brcms_c_info *wlc, uint idx, int val) { BCMMSG(wlc->wiphy, "idx %d, val %d\n", idx, val); @@ -957,16 +3893,18 @@ static void brcms_c_ucode_mac_upd(struct brcms_c_info *wlc) */ if (wlc->home_chanspec == BRCMS_BAND_PI_RADIO_CHANSPEC) { if (wlc->pub->associated) { - /* BMAC_NOTE: This is something that should be fixed in ucode inits. - * I think that the ucode inits set up the bcn templates and shm values - * with a bogus beacon. This should not be done in the inits. If ucode needs - * to set up a beacon for testing, the test routines should write it down, - * not expect the inits to populate a bogus beacon. + /* + * BMAC_NOTE: This is something that should be fixed + * in ucode inits. I think that the ucode inits set + * up the bcn templates and shm values with a bogus + * beacon. This should not be done in the inits. If + * ucode needs to set up a beacon for testing, the + * test routines should write it down, not expect the + * inits to populate a bogus beacon. */ - if (BRCMS_PHY_11N_CAP(wlc->band)) { + if (BRCMS_PHY_11N_CAP(wlc->band)) brcms_c_write_shm(wlc, M_BCN_TXTSF_OFFSET, wlc->band->bcntsfoff); - } } } else { /* disable an active IBSS if we are not on the home channel */ @@ -978,16 +3916,16 @@ static void brcms_c_ucode_mac_upd(struct brcms_c_info *wlc) } static void brcms_c_bandinit_ordered(struct brcms_c_info *wlc, - chanspec_t chanspec) + u16 chanspec) { - wlc_rateset_t default_rateset; + struct brcms_c_rateset default_rateset; uint parkband; uint i, band_order[2]; BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); /* - * We might have been bandlocked during down and the chip power-cycled (hibernate). - * figure out the right band to park on + * We might have been bandlocked during down and the chip + * power-cycled (hibernate). Figure out the right band to park on */ if (wlc->bandlocked || NBANDS(wlc) == 1) { /* updated in brcms_c_bandlock() */ @@ -1064,7 +4002,10 @@ static void brcms_c_setband(struct brcms_c_info *wlc, brcms_c_bsinit(wlc); } -/* Initialize a WME Parameter Info Element with default STA parameters from WMM Spec, Table 12 */ +/* + * Initialize a WME Parameter Info Element with default + * STA parameters from WMM Spec, Table 12 + */ void brcms_c_wme_initparams_sta(struct brcms_c_info *wlc, struct wme_param_ie *pe) { @@ -1288,11 +4229,6 @@ void brcms_c_info_init(struct brcms_c_info *wlc, int unit) /* WME QoS mode is Auto by default */ wlc->pub->_wme = AUTO; - -#ifdef BCMSDIODEV_ENABLED - wlc->pub->_priofc = true; /* enable priority flow control for sdio dongle */ -#endif - wlc->pub->_ampdu = AMPDU_AGG_HOST; wlc->pub->bcmerror = 0; wlc->pub->_coex = ON; @@ -1303,7 +4239,7 @@ void brcms_c_info_init(struct brcms_c_info *wlc, int unit) static bool brcms_c_state_bmac_sync(struct brcms_c_info *wlc) { - struct brcms_b_state state_bmac; + struct brcms_b_state state_bmac = {0}; if (brcms_b_state_get(wlc->hw, &state_bmac) != 0) return false; @@ -1347,19 +4283,366 @@ static uint brcms_c_attach_module(struct brcms_c_info *wlc) return err; } -struct brcms_pub *brcms_c_pub(void *wlc) +struct brcms_pub *brcms_c_pub(struct brcms_c_info *wlc) { - return ((struct brcms_c_info *) wlc)->pub; + return wlc->pub; } #define CHIP_SUPPORTS_11N(wlc) 1 +/* low level attach + * run backplane attach, init nvram + * run phy attach + * initialize software state for each core and band + * put the whole chip in reset(driver down state), no clock + */ +int brcms_b_attach(struct brcms_c_info *wlc, u16 vendor, u16 device, uint unit, + bool piomode, void *regsva, struct pci_dev *btparam) +{ + struct brcms_hardware *wlc_hw; + struct d11regs *regs; + char *macaddr = NULL; + char *vars; + uint err = 0; + uint j; + bool wme = false; + struct shared_phy_params sha_params; + struct wiphy *wiphy = wlc->wiphy; + char *var; + unsigned long res; + + BCMMSG(wlc->wiphy, "wl%d: vendor 0x%x device 0x%x\n", unit, vendor, + device); + + wme = true; + + wlc_hw = wlc->hw; + wlc_hw->wlc = wlc; + wlc_hw->unit = unit; + wlc_hw->band = wlc_hw->bandstate[0]; + wlc_hw->_piomode = piomode; + + /* populate struct brcms_hardware with default values */ + brcms_b_info_init(wlc_hw); + + /* + * Do the hardware portion of the attach. Also initialize software + * state that depends on the particular hardware we are running. + */ + wlc_hw->sih = ai_attach(regsva, btparam, + &wlc_hw->vars, &wlc_hw->vars_size); + if (wlc_hw->sih == NULL) { + wiphy_err(wiphy, "wl%d: brcms_b_attach: si_attach failed\n", + unit); + err = 11; + goto fail; + } + vars = wlc_hw->vars; + + /* + * Get vendid/devid nvram overwrites, which could be different + * than those the BIOS recognizes for devices on PCMCIA_BUS, + * SDIO_BUS, and SROMless devices on PCI_BUS. + */ + var = getvar(vars, "vendid"); + if (var && !kstrtoul(var, 0, &res)) { + vendor = (u16)res; + wiphy_err(wiphy, "Overriding vendor id = 0x%x\n", + vendor); + } + var = getvar(vars, "devid"); + if (var && !kstrtoul(var, 0, &res)) { + u16 devid = (u16)res; + if (devid != 0xffff) { + device = devid; + wiphy_err(wiphy, "Overriding device id = 0x%x" + "\n", device); + } + } + + /* verify again the device is supported */ + if (!brcms_c_chipmatch(vendor, device)) { + wiphy_err(wiphy, "wl%d: brcms_b_attach: Unsupported " + "vendor/device (0x%x/0x%x)\n", + unit, vendor, device); + err = 12; + goto fail; + } + + wlc_hw->vendorid = vendor; + wlc_hw->deviceid = device; + + /* set bar0 window to point at D11 core */ + wlc_hw->regs = (struct d11regs *) ai_setcore(wlc_hw->sih, D11_CORE_ID, + 0); + wlc_hw->corerev = ai_corerev(wlc_hw->sih); + + regs = wlc_hw->regs; + + wlc->regs = wlc_hw->regs; + + /* validate chip, chiprev and corerev */ + if (!brcms_c_isgoodchip(wlc_hw)) { + err = 13; + goto fail; + } + + /* initialize power control registers */ + ai_clkctl_init(wlc_hw->sih); + + /* request fastclock and force fastclock for the rest of attach + * bring the d11 core out of reset. + * For PMU chips, the first wlc_clkctl_clk is no-op since core-clk + * is still false; But it will be called again inside wlc_corereset, + * after d11 is out of reset. + */ + brcms_b_clkctl_clk(wlc_hw, CLK_FAST); + brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS); + + if (!brcms_b_validate_chip_access(wlc_hw)) { + wiphy_err(wiphy, "wl%d: brcms_b_attach: validate_chip_access " + "failed\n", unit); + err = 14; + goto fail; + } + + /* get the board rev, used just below */ + j = getintvar(vars, "boardrev"); + /* promote srom boardrev of 0xFF to 1 */ + if (j == BOARDREV_PROMOTABLE) + j = BOARDREV_PROMOTED; + wlc_hw->boardrev = (u16) j; + if (!brcms_c_validboardtype(wlc_hw)) { + wiphy_err(wiphy, "wl%d: brcms_b_attach: Unsupported Broadcom " + "board type (0x%x)" " or revision level (0x%x)\n", + unit, wlc_hw->sih->boardtype, wlc_hw->boardrev); + err = 15; + goto fail; + } + wlc_hw->sromrev = (u8) getintvar(vars, "sromrev"); + wlc_hw->boardflags = (u32) getintvar(vars, "boardflags"); + wlc_hw->boardflags2 = (u32) getintvar(vars, "boardflags2"); + + if (wlc_hw->boardflags & BFL_NOPLLDOWN) + brcms_b_pllreq(wlc_hw, true, BRCMS_PLLREQ_SHARED); + + if (ai_pci_war16165(wlc_hw->sih)) + wlc->war16165 = true; + + /* check device id(srom, nvram etc.) to set bands */ + if (wlc_hw->deviceid == BCM43224_D11N_ID || + wlc_hw->deviceid == BCM43224_D11N_ID_VEN1) + /* Dualband boards */ + wlc_hw->_nbands = 2; + else + wlc_hw->_nbands = 1; + + if ((wlc_hw->sih->chip == BCM43225_CHIP_ID)) + wlc_hw->_nbands = 1; + + /* BMAC_NOTE: remove init of pub values when brcms_c_attach() + * unconditionally does the init of these values + */ + wlc->vendorid = wlc_hw->vendorid; + wlc->deviceid = wlc_hw->deviceid; + wlc->pub->sih = wlc_hw->sih; + wlc->pub->corerev = wlc_hw->corerev; + wlc->pub->sromrev = wlc_hw->sromrev; + wlc->pub->boardrev = wlc_hw->boardrev; + wlc->pub->boardflags = wlc_hw->boardflags; + wlc->pub->boardflags2 = wlc_hw->boardflags2; + wlc->pub->_nbands = wlc_hw->_nbands; + + wlc_hw->physhim = wlc_phy_shim_attach(wlc_hw, wlc->wl, wlc); + + if (wlc_hw->physhim == NULL) { + wiphy_err(wiphy, "wl%d: brcms_b_attach: wlc_phy_shim_attach " + "failed\n", unit); + err = 25; + goto fail; + } + + /* pass all the parameters to wlc_phy_shared_attach in one struct */ + sha_params.sih = wlc_hw->sih; + sha_params.physhim = wlc_hw->physhim; + sha_params.unit = unit; + sha_params.corerev = wlc_hw->corerev; + sha_params.vars = vars; + sha_params.vid = wlc_hw->vendorid; + sha_params.did = wlc_hw->deviceid; + sha_params.chip = wlc_hw->sih->chip; + sha_params.chiprev = wlc_hw->sih->chiprev; + sha_params.chippkg = wlc_hw->sih->chippkg; + sha_params.sromrev = wlc_hw->sromrev; + sha_params.boardtype = wlc_hw->sih->boardtype; + sha_params.boardrev = wlc_hw->boardrev; + sha_params.boardvendor = wlc_hw->sih->boardvendor; + sha_params.boardflags = wlc_hw->boardflags; + sha_params.boardflags2 = wlc_hw->boardflags2; + sha_params.buscorerev = wlc_hw->sih->buscorerev; + + /* alloc and save pointer to shared phy state area */ + wlc_hw->phy_sh = wlc_phy_shared_attach(&sha_params); + if (!wlc_hw->phy_sh) { + err = 16; + goto fail; + } + + /* initialize software state for each core and band */ + for (j = 0; j < NBANDS_HW(wlc_hw); j++) { + /* + * band0 is always 2.4Ghz + * band1, if present, is 5Ghz + */ + + /* So if this is a single band 11a card, use band 1 */ + if (IS_SINGLEBAND_5G(wlc_hw->deviceid)) + j = BAND_5G_INDEX; + + brcms_c_setxband(wlc_hw, j); + + wlc_hw->band->bandunit = j; + wlc_hw->band->bandtype = j ? BRCM_BAND_5G : BRCM_BAND_2G; + wlc->band->bandunit = j; + wlc->band->bandtype = j ? BRCM_BAND_5G : BRCM_BAND_2G; + wlc->core->coreidx = ai_coreidx(wlc_hw->sih); + + wlc_hw->machwcap = R_REG(®s->machwcap); + wlc_hw->machwcap_backup = wlc_hw->machwcap; + + /* init tx fifo size */ + wlc_hw->xmtfifo_sz = + xmtfifo_sz[(wlc_hw->corerev - XMTFIFOTBL_STARTREV)]; + + /* Get a phy for this band */ + wlc_hw->band->pi = + wlc_phy_attach(wlc_hw->phy_sh, regs, + brcms_b_bandtype(wlc_hw), vars, + wlc->wiphy); + if (wlc_hw->band->pi == NULL) { + wiphy_err(wiphy, "wl%d: brcms_b_attach: wlc_phy_" + "attach failed\n", unit); + err = 17; + goto fail; + } + + wlc_phy_machwcap_set(wlc_hw->band->pi, wlc_hw->machwcap); + + wlc_phy_get_phyversion(wlc_hw->band->pi, &wlc_hw->band->phytype, + &wlc_hw->band->phyrev, + &wlc_hw->band->radioid, + &wlc_hw->band->radiorev); + wlc_hw->band->abgphy_encore = + wlc_phy_get_encore(wlc_hw->band->pi); + wlc->band->abgphy_encore = wlc_phy_get_encore(wlc_hw->band->pi); + wlc_hw->band->core_flags = + wlc_phy_get_coreflags(wlc_hw->band->pi); + + /* verify good phy_type & supported phy revision */ + if (BRCMS_ISNPHY(wlc_hw->band)) { + if (NCONF_HAS(wlc_hw->band->phyrev)) + goto good_phy; + else + goto bad_phy; + } else if (BRCMS_ISLCNPHY(wlc_hw->band)) { + if (LCNCONF_HAS(wlc_hw->band->phyrev)) + goto good_phy; + else + goto bad_phy; + } else { + bad_phy: + wiphy_err(wiphy, "wl%d: brcms_b_attach: unsupported " + "phy type/rev (%d/%d)\n", unit, + wlc_hw->band->phytype, wlc_hw->band->phyrev); + err = 18; + goto fail; + } + + good_phy: + /* + * BMAC_NOTE: wlc->band->pi should not be set below and should + * be done in the high level attach. However we can not make + * that change until all low level access is changed to + * wlc_hw->band->pi. Instead do the wlc->band->pi init below, + * keeping wlc_hw->band->pi as well for incremental update of + * low level fns, and cut over low only init when all fns + * updated. + */ + wlc->band->pi = wlc_hw->band->pi; + wlc->band->phytype = wlc_hw->band->phytype; + wlc->band->phyrev = wlc_hw->band->phyrev; + wlc->band->radioid = wlc_hw->band->radioid; + wlc->band->radiorev = wlc_hw->band->radiorev; + + /* default contention windows size limits */ + wlc_hw->band->CWmin = APHY_CWMIN; + wlc_hw->band->CWmax = PHY_CWMAX; + + if (!brcms_b_attach_dmapio(wlc, j, wme)) { + err = 19; + goto fail; + } + } + + /* disable core to match driver "down" state */ + brcms_c_coredisable(wlc_hw); + + /* Match driver "down" state */ + ai_pci_down(wlc_hw->sih); + + /* register sb interrupt callback functions */ + ai_register_intr_callback(wlc_hw->sih, (void *)brcms_c_wlintrsoff, + (void *)brcms_c_wlintrsrestore, NULL, wlc); + + /* turn off pll and xtal to match driver "down" state */ + brcms_b_xtal(wlc_hw, OFF); + + /* ******************************************************************* + * The hardware is in the DOWN state at this point. D11 core + * or cores are in reset with clocks off, and the board PLLs + * are off if possible. + * + * Beyond this point, wlc->sbclk == false and chip registers + * should not be touched. + ********************************************************************* + */ + + /* init etheraddr state variables */ + macaddr = brcms_c_get_macaddr(wlc_hw); + if (macaddr == NULL) { + wiphy_err(wiphy, "wl%d: brcms_b_attach: macaddr not found\n", + unit); + err = 21; + goto fail; + } + if (!mac_pton(macaddr, wlc_hw->etheraddr) || + is_broadcast_ether_addr(wlc_hw->etheraddr) || + is_zero_ether_addr(wlc_hw->etheraddr)) { + wiphy_err(wiphy, "wl%d: brcms_b_attach: bad macaddr %s\n", + unit, macaddr); + err = 22; + goto fail; + } + + BCMMSG(wlc->wiphy, + "deviceid 0x%x nbands %d board 0x%x macaddr: %s\n", + wlc_hw->deviceid, wlc_hw->_nbands, + wlc_hw->sih->boardtype, macaddr); + + return err; + + fail: + wiphy_err(wiphy, "wl%d: brcms_b_attach: failed with err %d\n", unit, + err); + return err; +} + /* * The common driver entry routine. Error codes should be unique */ -void *brcms_c_attach(struct brcms_info *wl, u16 vendor, u16 device, uint unit, - bool piomode, void *regsva, uint bustype, void *btparam, - uint *perr) +struct brcms_c_info * +brcms_c_attach(struct brcms_info *wl, u16 vendor, u16 device, uint unit, + bool piomode, void *regsva, struct pci_dev *btparam, uint *perr) { struct brcms_c_info *wlc; uint err = 0; @@ -1399,12 +4682,14 @@ void *brcms_c_attach(struct brcms_info *wl, u16 vendor, u16 device, uint unit, * inside, no more in rest of the attach) */ err = brcms_b_attach(wlc, vendor, device, unit, piomode, regsva, - bustype, btparam); + btparam); if (err) goto fail; - /* for some states, due to different info pointer(e,g, wlc, wlc_hw) or master/slave split, - * HIGH driver(both monolithic and HIGH_ONLY) needs to sync states FROM BMAC portion driver + /* + * for some states, due to different info pointer(e,g, wlc, wlc_hw) or + * master/slave split, HIGH driver(both monolithic and HIGH_ONLY) needs + * to sync states FROM BMAC portion driver */ if (!brcms_c_state_bmac_sync(wlc)) { err = 20; @@ -1492,7 +4777,10 @@ void *brcms_c_attach(struct brcms_info *wl, u16 vendor, u16 device, uint unit, (bool) N_ENAB(wlc->pub)); } - /* update antenna config due to wlc->stf->txant/txchain/ant_rx_ovr change */ + /* + * update antenna config due to + * wlc->stf->txant/txchain/ant_rx_ovr change + */ brcms_c_stf_phy_txant_upd(wlc); /* attach each modules */ @@ -1592,7 +4880,7 @@ void *brcms_c_attach(struct brcms_info *wl, u16 vendor, u16 device, uint unit, if (perr) *perr = 0; - return (void *)wlc; + return wlc; fail: wiphy_err(wl->wiphy, "wl%d: %s: failed with err %d\n", @@ -1620,14 +4908,17 @@ static void brcms_c_attach_antgain_init(struct brcms_c_info *wlc) } else { s8 gain, fract; /* Older sroms specified gain in whole dbm only. In order - * be able to specify qdbm granularity and remain backward compatible - * the whole dbms are now encoded in only low 6 bits and remaining qdbms - * are encoded in the hi 2 bits. 6 bit signed number ranges from - * -32 - 31. Examples: 0x1 = 1 db, + * be able to specify qdbm granularity and remain backward + * compatible the whole dbms are now encoded in only + * low 6 bits and remaining qdbms are encoded in the hi 2 bits. + * 6 bit signed number ranges from -32 - 31. + * + * Examples: + * 0x1 = 1 db, * 0xc1 = 1.75 db (1 + 3 quarters), * 0x3f = -1 (-1 + 0 quarters), - * 0x7f = -.75 (-1 in low 6 bits + 1 quarters in hi 2 bits) = -3 qdbm. - * 0xbf = -.50 (-1 in low 6 bits + 2 quarters in hi 2 bits) = -2 qdbm. + * 0x7f = -.75 (-1 + 1 quarters) = -3 qdbm. + * 0xbf = -.50 (-1 + 2 quarters) = -2 qdbm. */ gain = wlc->band->antgain & 0x3f; gain <<= 2; /* Sign extend */ @@ -1707,6 +4998,58 @@ static void brcms_c_detach_module(struct brcms_c_info *wlc) } /* + * low level detach + */ +int brcms_b_detach(struct brcms_c_info *wlc) +{ + uint i; + struct brcms_hw_band *band; + struct brcms_hardware *wlc_hw = wlc->hw; + int callbacks; + + callbacks = 0; + + if (wlc_hw->sih) { + /* + * detach interrupt sync mechanism since interrupt is disabled + * and per-port interrupt object may has been freed. this must + * be done before sb core switch + */ + ai_deregister_intr_callback(wlc_hw->sih); + ai_pci_sleep(wlc_hw->sih); + } + + brcms_b_detach_dmapio(wlc_hw); + + band = wlc_hw->band; + for (i = 0; i < NBANDS_HW(wlc_hw); i++) { + if (band->pi) { + /* Detach this band's phy */ + wlc_phy_detach(band->pi); + band->pi = NULL; + } + band = wlc_hw->bandstate[OTHERBANDUNIT(wlc)]; + } + + /* Free shared phy state */ + kfree(wlc_hw->phy_sh); + + wlc_phy_shim_detach(wlc_hw->physhim); + + /* free vars */ + kfree(wlc_hw->vars); + wlc_hw->vars = NULL; + + if (wlc_hw->sih) { + ai_detach(wlc_hw->sih); + wlc_hw->sih = NULL; + } + + return callbacks; + +} + +/* * Return a count of the number of driver callbacks still pending. * * General policy is that brcms_c_detach can only dealloc/free software states. @@ -1765,14 +5108,16 @@ static void brcms_c_radio_hwdisable_upd(struct brcms_c_info *wlc) if (wlc->pub->wlfeatureflag & WL_SWFL_NOHWRADIO || wlc->pub->hw_off) return; - if (brcms_b_radio_read_hwdisabled(wlc->hw)) { + if (brcms_b_radio_read_hwdisabled(wlc->hw)) mboolset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE); - } else { + else mboolclr(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE); - } } -/* return true if Minimum Power Consumption should be entered, false otherwise */ +/* + * return true if Minimum Power Consumption should + * be entered, false otherwise + */ bool brcms_c_is_non_delay_mpc(struct brcms_c_info *wlc) { return false; @@ -1804,9 +5149,10 @@ void brcms_c_radio_mpc_upd(struct brcms_c_info *wlc) } /* - * sync ismpc logic with WL_RADIO_MPC_DISABLE bit in wlc->pub->radio_disabled - * to go ON, always call radio_upd synchronously - * to go OFF, postpone radio_upd to later when context is safe(e.g. watchdog) + * sync ismpc logic with WL_RADIO_MPC_DISABLE bit in + * wlc->pub->radio_disabled to go ON, always call radio_upd + * synchronously to go OFF, postpone radio_upd to later when + * context is safe(e.g. watchdog) */ radio_state = (mboolisset(wlc->pub->radio_disabled, WL_RADIO_MPC_DISABLE) ? OFF : @@ -1824,14 +5170,16 @@ void brcms_c_radio_mpc_upd(struct brcms_c_info *wlc) wlc->mpc_dlycnt = BRCMS_MPC_MIN_DELAYCNT; wlc->mpc_dur += OSL_SYSUPTIME() - wlc->mpc_laston_ts; } - /* Below logic is meant to capture the transition from mpc off to mpc on for reasons - * other than wlc->mpc_delay_off keeping the mpc off. In that case reset - * wlc->mpc_delay_off to wlc->mpc_dlycnt, so that we restart the countdown of mpc_delay_off + /* + * Below logic is meant to capture the transition from mpc off + * to mpc on for reasons other than wlc->mpc_delay_off keeping + * the mpc off. In that case reset wlc->mpc_delay_off to + * wlc->mpc_dlycnt, so that we restart the countdown of mpc_delay_off */ if ((wlc->prev_non_delay_mpc == false) && - (brcms_c_is_non_delay_mpc(wlc) == true) && wlc->mpc_delay_off) { + (brcms_c_is_non_delay_mpc(wlc) == true) && wlc->mpc_delay_off) wlc->mpc_delay_off = wlc->mpc_dlycnt; - } + wlc->prev_non_delay_mpc = brcms_c_is_non_delay_mpc(wlc); } @@ -1841,18 +5189,19 @@ void brcms_c_radio_mpc_upd(struct brcms_c_info *wlc) */ static void brcms_c_radio_upd(struct brcms_c_info *wlc) { - if (wlc->pub->radio_disabled) { + if (wlc->pub->radio_disabled) brcms_c_radio_disable(wlc); - } else { + else brcms_c_radio_enable(wlc); - } } /* maintain LED behavior in down state */ static void brcms_c_down_led_upd(struct brcms_c_info *wlc) { - /* maintain LEDs while in down state, turn on sbclk if not available yet */ - /* turn on sbclk if necessary */ + /* + * maintain LEDs while in down state, turn on sbclk if + * not available yet. Turn on sbclk if necessary + */ if (!AP_ENAB(wlc->pub)) { brcms_c_pllreq(wlc, true, BRCMS_PLLREQ_FLIP); @@ -1865,7 +5214,8 @@ bool brcms_c_check_radio_disabled(struct brcms_c_info *wlc) { brcms_c_radio_hwdisable_upd(wlc); - return mboolisset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE) ? true : false; + return mboolisset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE) ? + true : false; } void brcms_c_radio_disable(struct brcms_c_info *wlc) @@ -1933,6 +5283,29 @@ bool brcms_c_radio_monitor_stop(struct brcms_c_info *wlc) return brcms_del_timer(wlc->wl, wlc->radio_timer); } +/* common low-level watchdog code */ +void brcms_b_watchdog(void *arg) +{ + struct brcms_c_info *wlc = (struct brcms_c_info *) arg; + struct brcms_hardware *wlc_hw = wlc->hw; + + BCMMSG(wlc->wiphy, "wl%d\n", wlc_hw->unit); + + if (!wlc_hw->up) + return; + + /* increment second count */ + wlc_hw->now++; + + /* Check for FIFO error interrupts */ + brcms_b_fifoerrors(wlc_hw); + + /* make sure RX dma has buffers */ + dma_rxfill(wlc->hw->di[RX_FIFO]); + + wlc_phy_watchdog(wlc_hw->band->pi); +} + static void brcms_c_watchdog_by_timer(void *arg) { brcms_c_watchdog(arg); @@ -1982,25 +5355,20 @@ static void brcms_c_watchdog(void *arg) brcms_b_watchdog(wlc); - /* occasionally sample mac stat counters to detect 16-bit counter wrap */ + /* + * occasionally sample mac stat counters to + * detect 16-bit counter wrap + */ if ((wlc->pub->now % SW_TIMER_MAC_STAT_UPD) == 0) brcms_c_statsupd(wlc); /* Manage TKIP countermeasures timers */ - FOREACH_BSS(wlc, i, cfg) { - if (cfg->tk_cm_dt) { + FOREACH_BSS(wlc, i, cfg) + if (cfg->tk_cm_dt) cfg->tk_cm_dt--; - } - if (cfg->tk_cm_bt) { + if (cfg->tk_cm_bt) cfg->tk_cm_bt--; - } - } - - /* Call any registered watchdog handlers */ - for (i = 0; i < BRCMS_MAXMODULES; i++) { - if (wlc->modulecb[i].watchdog_fn) - wlc->modulecb[i].watchdog_fn(wlc->modulecb[i].hdl); - } + END_FOREACH_BSS() if (BRCMS_ISNPHY(wlc->band) && !wlc->pub->tempsense_disable && ((wlc->pub->now - wlc->tempsense_lasttime) >= @@ -2010,6 +5378,106 @@ static void brcms_c_watchdog(void *arg) } } +/* Initialize just the hardware when coming out of POR or S3/S5 system states */ +void brcms_b_hw_up(struct brcms_hardware *wlc_hw) +{ + if (wlc_hw->wlc->pub->hw_up) + return; + + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); + + /* + * Enable pll and xtal, initialize the power control registers, + * and force fastclock for the remainder of brcms_c_up(). + */ + brcms_b_xtal(wlc_hw, ON); + ai_clkctl_init(wlc_hw->sih); + brcms_b_clkctl_clk(wlc_hw, CLK_FAST); + + ai_pci_fixcfg(wlc_hw->sih); + + /* + * AI chip doesn't restore bar0win2 on + * hibernation/resume, need sw fixup + */ + if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) || + (wlc_hw->sih->chip == BCM43225_CHIP_ID)) + wlc_hw->regs = (struct d11regs *) + ai_setcore(wlc_hw->sih, D11_CORE_ID, 0); + + /* + * Inform phy that a POR reset has occurred so + * it does a complete phy init + */ + wlc_phy_por_inform(wlc_hw->band->pi); + + wlc_hw->ucode_loaded = false; + wlc_hw->wlc->pub->hw_up = true; + + if ((wlc_hw->boardflags & BFL_FEM) + && (wlc_hw->sih->chip == BCM4313_CHIP_ID)) { + if (! + (wlc_hw->boardrev >= 0x1250 + && (wlc_hw->boardflags & BFL_FEM_BT))) + ai_epa_4313war(wlc_hw->sih); + } +} + +int brcms_b_up_prep(struct brcms_hardware *wlc_hw) +{ + uint coremask; + + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); + + /* + * Enable pll and xtal, initialize the power control registers, + * and force fastclock for the remainder of brcms_c_up(). + */ + brcms_b_xtal(wlc_hw, ON); + ai_clkctl_init(wlc_hw->sih); + brcms_b_clkctl_clk(wlc_hw, CLK_FAST); + + /* + * Configure pci/pcmcia here instead of in brcms_c_attach() + * to allow mfg hotswap: down, hotswap (chip power cycle), up. + */ + coremask = (1 << wlc_hw->wlc->core->coreidx); + + ai_pci_setup(wlc_hw->sih, coremask); + + /* + * Need to read the hwradio status here to cover the case where the + * system is loaded with the hw radio disabled. We do not want to + * bring the driver up in this case. + */ + if (brcms_b_radio_read_hwdisabled(wlc_hw)) { + /* put SB PCI in down state again */ + ai_pci_down(wlc_hw->sih); + brcms_b_xtal(wlc_hw, OFF); + return -ENOMEDIUM; + } + + ai_pci_up(wlc_hw->sih); + + /* reset the d11 core */ + brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS); + + return 0; +} + +int brcms_b_up_finish(struct brcms_hardware *wlc_hw) +{ + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); + + wlc_hw->up = true; + wlc_phy_hw_state_upd(wlc_hw->band->pi, true); + + /* FULLY enable dynamic power control and d11 core interrupt */ + brcms_b_clkctl_clk(wlc_hw, CLK_DYNAMIC); + brcms_intrson(wlc_hw->wlc->wl); + return 0; +} + /* make interface operational */ int brcms_c_up(struct brcms_c_info *wlc) { @@ -2027,20 +5495,20 @@ int brcms_c_up(struct brcms_c_info *wlc) if ((wlc->pub->boardflags & BFL_FEM) && (wlc->pub->sih->chip == BCM4313_CHIP_ID)) { if (wlc->pub->boardrev >= 0x1250 - && (wlc->pub->boardflags & BFL_FEM_BT)) { + && (wlc->pub->boardflags & BFL_FEM_BT)) brcms_c_mhf(wlc, MHF5, MHF5_4313_GPIOCTRL, MHF5_4313_GPIOCTRL, BRCM_BAND_ALL); - } else { + else brcms_c_mhf(wlc, MHF4, MHF4_EXTPA_ENABLE, MHF4_EXTPA_ENABLE, BRCM_BAND_ALL); - } } /* - * Need to read the hwradio status here to cover the case where the system - * is loaded with the hw radio disabled. We do not want to bring the driver up in this case. - * if radio is disabled, abort up, lower power, start radio timer and return 0(for NDIS) - * don't call radio_update to avoid looping brcms_c_up. + * Need to read the hwradio status here to cover the case where the + * system is loaded with the hw radio disabled. We do not want to bring + * the driver up in this case. If radio is disabled, abort up, lower + * power, start radio timer and return 0(for NDIS) don't call + * radio_update to avoid looping brcms_c_up. * * brcms_b_up_prep() returns either 0 or -BCME_RADIOOFF only */ @@ -2054,7 +5522,7 @@ int brcms_c_up(struct brcms_c_info *wlc) mboolset(wlc->pub->radio_disabled, WL_RADIO_HW_DISABLE); - FOREACH_BSS(wlc, idx, bsscfg) { + FOREACH_BSS(wlc, idx, bsscfg) if (!BSSCFG_STA(bsscfg) || !bsscfg->enable || !bsscfg->BSS) continue; @@ -2062,7 +5530,7 @@ int brcms_c_up(struct brcms_c_info *wlc) ": rfdisable -> " "bsscfg_disable()\n", wlc->pub->unit, idx); - } + END_FOREACH_BSS() } } } @@ -2078,11 +5546,10 @@ int brcms_c_up(struct brcms_c_info *wlc) brcms_c_radio_monitor_stop(wlc); /* Set EDCF hostflags */ - if (EDCF_ENAB(wlc->pub)) { + if (EDCF_ENAB(wlc->pub)) brcms_c_mhf(wlc, MHF1, MHF1_EDCF, MHF1_EDCF, BRCM_BAND_ALL); - } else { + else brcms_c_mhf(wlc, MHF1, MHF1_EDCF, 0, BRCM_BAND_ALL); - } if (BRCMS_WAR16165(wlc)) brcms_c_mhf(wlc, MHF2, MHF2_PCISLOWCLKWAR, MHF2_PCISLOWCLKWAR, @@ -2119,14 +5586,18 @@ int brcms_c_up(struct brcms_c_info *wlc) return 0; } -/* Initialize the base precedence map for dequeueing from txq based on WME settings */ +/* + * Initialize the base precedence map for dequeueing + * from txq based on WME settings + */ static void brcms_c_tx_prec_map_init(struct brcms_c_info *wlc) { wlc->tx_prec_map = BRCMS_PREC_BMP_ALL; memset(wlc->fifo2prec_map, 0, NFIFO * sizeof(u16)); - /* For non-WME, both fifos have overlapping MAXPRIO. So just disable all precedences - * if either is full. + /* + * For non-WME, both fifos have overlapping MAXPRIO. So just + * disable all precedences if either is full. */ if (!EDCF_ENAB(wlc->pub)) { wlc->fifo2prec_map[TX_DATA_FIFO] = BRCMS_PREC_BMP_ALL; @@ -2146,6 +5617,77 @@ static uint brcms_c_down_del_timer(struct brcms_c_info *wlc) return callbacks; } +int brcms_b_bmac_down_prep(struct brcms_hardware *wlc_hw) +{ + bool dev_gone; + uint callbacks = 0; + + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); + + if (!wlc_hw->up) + return callbacks; + + dev_gone = DEVICEREMOVED(wlc_hw->wlc); + + /* disable interrupts */ + if (dev_gone) + wlc_hw->wlc->macintmask = 0; + else { + /* now disable interrupts */ + brcms_intrsoff(wlc_hw->wlc->wl); + + /* ensure we're running on the pll clock again */ + brcms_b_clkctl_clk(wlc_hw, CLK_FAST); + } + /* down phy at the last of this stage */ + callbacks += wlc_phy_down(wlc_hw->band->pi); + + return callbacks; +} + +int brcms_b_down_finish(struct brcms_hardware *wlc_hw) +{ + uint callbacks = 0; + bool dev_gone; + + BCMMSG(wlc_hw->wlc->wiphy, "wl%d\n", wlc_hw->unit); + + if (!wlc_hw->up) + return callbacks; + + wlc_hw->up = false; + wlc_phy_hw_state_upd(wlc_hw->band->pi, false); + + dev_gone = DEVICEREMOVED(wlc_hw->wlc); + + if (dev_gone) { + wlc_hw->sbclk = false; + wlc_hw->clk = false; + wlc_phy_hw_clk_state_upd(wlc_hw->band->pi, false); + + /* reclaim any posted packets */ + brcms_c_flushqueues(wlc_hw->wlc); + } else { + + /* Reset and disable the core */ + if (ai_iscoreup(wlc_hw->sih)) { + if (R_REG(&wlc_hw->regs->maccontrol) & + MCTL_EN_MAC) + brcms_c_suspend_mac_and_wait(wlc_hw->wlc); + callbacks += brcms_reset(wlc_hw->wlc->wl); + brcms_c_coredisable(wlc_hw); + } + + /* turn off primary xtal and pll */ + if (!wlc_hw->noreset) { + ai_pci_down(wlc_hw->sih); + brcms_b_xtal(wlc_hw, OFF); + } + } + + return callbacks; +} + /* * Mark the interface nonoperational, stop the software mechanisms, * disable the hardware, free any transient buffer state. @@ -2201,9 +5743,8 @@ uint brcms_c_down(struct brcms_c_info *wlc) brcms_c_txflowcontrol_reset(wlc); /* flush tx queues */ - for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) { + for (qi = wlc->tx_queues; qi != NULL; qi = qi->next) brcmu_pktq_flush(&qi->q, true, NULL, NULL); - } callbacks += brcms_b_down_finish(wlc->hw); @@ -2219,17 +5760,18 @@ int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config) { int ret = 0; uint i; - wlc_rateset_t rs; + struct brcms_c_rateset rs; /* Default to 54g Auto */ /* Advertise and use shortslot (-1/0/1 Auto/Off/On) */ s8 shortslot = BRCMS_SHORTSLOT_AUTO; - bool shortslot_restrict = false; /* Restrict association to stations that support shortslot - */ + bool shortslot_restrict = false; /* Restrict association to stations + * that support shortslot + */ bool ofdm_basic = false; /* Make 6, 12, and 24 basic rates */ /* Advertise and use short preambles (-1/0/1 Auto/Off/On) */ int preamble = BRCMS_PLCP_LONG; - bool preamble_restrict = false; /* Restrict association to stations that support short - * preambles + bool preamble_restrict = false; /* Restrict association to stations + * that support short preambles */ struct brcms_band *band; @@ -2258,10 +5800,10 @@ int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config) brcms_c_protection_upd(wlc, BRCMS_PROT_G_USER, gmode); /* Clear supported rates filter */ - memset(&wlc->sup_rates_override, 0, sizeof(wlc_rateset_t)); + memset(&wlc->sup_rates_override, 0, sizeof(struct brcms_c_rateset)); /* Clear rateset override */ - memset(&rs, 0, sizeof(wlc_rateset_t)); + memset(&rs, 0, sizeof(struct brcms_c_rateset)); switch (gmode) { case GMODE_LEGACY_B: @@ -2287,7 +5829,8 @@ int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config) break; case GMODE_PERFORMANCE: - if (AP_ENAB(wlc->pub)) /* Put all rates into the Supported Rates element */ + if (AP_ENAB(wlc->pub)) + /* Put all rates into the Supported Rates element */ brcms_c_rateset_copy(&cck_ofdm_rates, &wlc->sup_rates_override); @@ -2315,21 +5858,19 @@ int brcms_c_set_gmode(struct brcms_c_info *wlc, u8 gmode, bool config) band->rspec_override = 0; brcms_c_reprate_init(wlc); } - if (band->mrspec_override && !IS_CCK(band->mrspec_override)) { + if (band->mrspec_override && !IS_CCK(band->mrspec_override)) band->mrspec_override = 0; - } } band->gmode = gmode; wlc->shortslot_override = shortslot; - if (AP_ENAB(wlc->pub)) { + if (AP_ENAB(wlc->pub)) /* wlc->ap->shortslot_restrict = shortslot_restrict; */ wlc->PLCPHdr_override = (preamble != BRCMS_PLCP_LONG) ? BRCMS_PLCP_SHORT : BRCMS_PLCP_AUTO; - } if ((AP_ENAB(wlc->pub) && preamble != BRCMS_PLCP_LONG) || preamble == BRCMS_PLCP_SHORT) @@ -2446,12 +5987,13 @@ int brcms_c_set_nmode(struct brcms_c_info *wlc, s32 nmode) return err; } -static int brcms_c_set_rateset(struct brcms_c_info *wlc, wlc_rateset_t *rs_arg) +static int +brcms_c_set_rateset(struct brcms_c_info *wlc, struct brcms_c_rateset *rs_arg) { - wlc_rateset_t rs, new; + struct brcms_c_rateset rs, new; uint bandunit; - memcpy(&rs, rs_arg, sizeof(wlc_rateset_t)); + memcpy(&rs, rs_arg, sizeof(struct brcms_c_rateset)); /* check for bad count value */ if ((rs.count == 0) || (rs.count > BRCMS_NUMRATES)) @@ -2459,7 +6001,7 @@ static int brcms_c_set_rateset(struct brcms_c_info *wlc, wlc_rateset_t *rs_arg) /* try the current band */ bandunit = wlc->band->bandunit; - memcpy(&new, &rs, sizeof(wlc_rateset_t)); + memcpy(&new, &rs, sizeof(struct brcms_c_rateset)); if (brcms_c_rate_hwrs_filter_sort_validate (&new, &wlc->bandstate[bandunit]->hw_rateset, true, wlc->stf->txstreams)) @@ -2468,7 +6010,7 @@ static int brcms_c_set_rateset(struct brcms_c_info *wlc, wlc_rateset_t *rs_arg) /* try the other band */ if (IS_MBAND_UNLOCKED(wlc)) { bandunit = OTHERBANDUNIT(wlc); - memcpy(&new, &rs, sizeof(wlc_rateset_t)); + memcpy(&new, &rs, sizeof(struct brcms_c_rateset)); if (brcms_c_rate_hwrs_filter_sort_validate(&new, &wlc-> bandstate[bandunit]-> @@ -2481,9 +6023,10 @@ static int brcms_c_set_rateset(struct brcms_c_info *wlc, wlc_rateset_t *rs_arg) good: /* apply new rateset */ - memcpy(&wlc->default_bss->rateset, &new, sizeof(wlc_rateset_t)); + memcpy(&wlc->default_bss->rateset, &new, + sizeof(struct brcms_c_rateset)); memcpy(&wlc->bandstate[bandunit]->defrateset, &new, - sizeof(wlc_rateset_t)); + sizeof(struct brcms_c_rateset)); return 0; } @@ -2555,9 +6098,12 @@ _brcms_c_ioctl(struct brcms_c_info *wlc, int cmd, void *arg, int len, /* default argument is generic integer */ pval = arg ? (int *)arg : NULL; - /* This will prevent the misaligned access */ + /* + * This will prevent misaligned access. The (void *) cast prevents a + * memcpy alignment issue on e.g. Sparc64 platforms. + */ if (pval && (u32) len >= sizeof(val)) - memcpy(&val, pval, sizeof(val)); + memcpy((void *)&val, (void *)pval, sizeof(val)); else val = 0; @@ -2575,7 +6121,7 @@ _brcms_c_ioctl(struct brcms_c_info *wlc, int cmd, void *arg, int len, switch (cmd) { case BRCM_SET_CHANNEL:{ - chanspec_t chspec = CH20MHZ_CHSPEC(val); + u16 chspec = CH20MHZ_CHSPEC(val); if (val < 0 || val > MAXCHANNEL) { bcmerror = -EINVAL; @@ -2615,9 +6161,9 @@ _brcms_c_ioctl(struct brcms_c_info *wlc, int cmd, void *arg, int len, brcms_b_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL); - for (ac = 0; ac < AC_COUNT; ac++) { + for (ac = 0; ac < AC_COUNT; ac++) BRCMS_WME_RETRY_SHORT_SET(wlc, ac, wlc->SRL); - } + brcms_c_wme_retries_write(wlc); } else bcmerror = -EINVAL; @@ -2630,17 +6176,18 @@ _brcms_c_ioctl(struct brcms_c_info *wlc, int cmd, void *arg, int len, brcms_b_retrylimit_upd(wlc->hw, wlc->SRL, wlc->LRL); - for (ac = 0; ac < AC_COUNT; ac++) { + for (ac = 0; ac < AC_COUNT; ac++) BRCMS_WME_RETRY_LONG_SET(wlc, ac, wlc->LRL); - } + brcms_c_wme_retries_write(wlc); } else bcmerror = -EINVAL; break; case BRCM_GET_CURR_RATESET:{ - wl_rateset_t *ret_rs = (wl_rateset_t *) arg; - wlc_rateset_t *rs; + struct brcm_rateset *ret_rs = + (struct brcm_rateset *) arg; + struct brcms_c_rateset *rs; if (wlc->pub->associated) rs = ¤t_bss->rateset; @@ -2659,8 +6206,9 @@ _brcms_c_ioctl(struct brcms_c_info *wlc, int cmd, void *arg, int len, } case BRCM_SET_RATESET:{ - wlc_rateset_t rs; - wl_rateset_t *in_rs = (wl_rateset_t *) arg; + struct brcms_c_rateset rs; + struct brcm_rateset *in_rs = + (struct brcm_rateset *) arg; if (len < (int)(in_rs->count + sizeof(in_rs->count))) { bcmerror = -EOVERFLOW; @@ -2672,7 +6220,7 @@ _brcms_c_ioctl(struct brcms_c_info *wlc, int cmd, void *arg, int len, break; } - memset(&rs, 0, sizeof(wlc_rateset_t)); + memset(&rs, 0, sizeof(struct brcms_c_rateset)); /* Copy only legacy rateset section */ rs.count = in_rs->count; @@ -2680,14 +6228,13 @@ _brcms_c_ioctl(struct brcms_c_info *wlc, int cmd, void *arg, int len, /* merge rateset coming in with the current mcsset */ if (N_ENAB(wlc->pub)) { + struct brcms_bss_info *mcsset_bss; if (bsscfg->associated) - memcpy(rs.mcs, - ¤t_bss->rateset.mcs[0], - MCSSET_LEN); + mcsset_bss = current_bss; else - memcpy(rs.mcs, - &wlc->default_bss->rateset.mcs[0], - MCSSET_LEN); + mcsset_bss = wlc->default_bss; + memcpy(rs.mcs, &mcsset_bss->rateset.mcs[0], + MCSSET_LEN); } bcmerror = brcms_c_set_rateset(wlc, &rs); @@ -2748,13 +6295,12 @@ _brcms_c_ioctl(struct brcms_c_info *wlc, int cmd, void *arg, int len, } else { /* driver is down, so just update the brcms_c_info * value */ - if (wlc->shortslot_override == BRCMS_SHORTSLOT_AUTO) { + if (wlc->shortslot_override == BRCMS_SHORTSLOT_AUTO) wlc->shortslot = false; - } else { + else wlc->shortslot = (wlc->shortslot_override == BRCMS_SHORTSLOT_ON); - } } break; @@ -2772,8 +6318,8 @@ _brcms_c_ioctl(struct brcms_c_info *wlc, int cmd, void *arg, int len, * register watchdog and down handlers. */ int brcms_c_module_register(struct brcms_pub *pub, - const char *name, void *hdl, - watchdog_fn_t w_fn, down_fn_t d_fn) + const char *name, struct brcms_info *hdl, + int (*d_fn)(void *handle)) { struct brcms_c_info *wlc = (struct brcms_c_info *) pub->wlc; int i; @@ -2784,7 +6330,6 @@ int brcms_c_module_register(struct brcms_pub *pub, strncpy(wlc->modulecb[i].name, name, sizeof(wlc->modulecb[i].name) - 1); wlc->modulecb[i].hdl = hdl; - wlc->modulecb[i].watchdog_fn = w_fn; wlc->modulecb[i].down_fn = d_fn; return 0; } @@ -2794,8 +6339,8 @@ int brcms_c_module_register(struct brcms_pub *pub, } /* unregister module callbacks */ -int -brcms_c_module_unregister(struct brcms_pub *pub, const char *name, void *hdl) +int brcms_c_module_unregister(struct brcms_pub *pub, const char *name, + struct brcms_info *hdl) { struct brcms_c_info *wlc = (struct brcms_c_info *) pub->wlc; int i; @@ -2815,7 +6360,10 @@ brcms_c_module_unregister(struct brcms_pub *pub, const char *name, void *hdl) return -ENODATA; } -/* Write WME tunable parameters for retransmit/max rate from wlc struct to ucode */ +/* + * Write WME tunable parameters for retransmit/max rate + * from wlc struct to ucode + */ static void brcms_c_wme_retries_write(struct brcms_c_info *wlc) { int ac; @@ -2824,10 +6372,9 @@ static void brcms_c_wme_retries_write(struct brcms_c_info *wlc) if (!wlc->clk) return; - for (ac = 0; ac < AC_COUNT; ac++) { + for (ac = 0; ac < AC_COUNT; ac++) brcms_c_write_shm(wlc, M_AC_TXLMT_ADDR(ac), wlc->wme_retries[ac]); - } } #ifdef BCMDBG @@ -2929,9 +6476,8 @@ void brcms_c_statsupd(struct brcms_c_info *wlc) /* merge counters from dma module */ for (i = 0; i < NFIFO; i++) { - if (wlc->hw->di[i]) { + if (wlc->hw->di[i]) dma_counterreset(wlc->hw->di[i]); - } } } @@ -3082,6 +6628,29 @@ void brcms_c_print_rxh(struct d11rxhdr *rxh) } #endif /* defined(BCMDBG) */ +u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate) +{ + u16 table_ptr; + u8 phy_rate, index; + + /* get the phy specific rate encoding for the PLCP SIGNAL field */ + if (IS_OFDM(rate)) + table_ptr = M_RT_DIRMAP_A; + else + table_ptr = M_RT_DIRMAP_B; + + /* for a given rate, the LS-nibble of the PLCP SIGNAL field is + * the index into the rate table. + */ + phy_rate = rate_info[rate] & BRCMS_RATE_MASK; + index = phy_rate & 0xf; + + /* Find the SHM pointer to the rate table entry by looking in the + * Direct-map Table + */ + return 2 * brcms_b_read_shm(wlc_hw, table_ptr + (index * 2)); +} + static u16 brcms_c_rate_shm_offset(struct brcms_c_info *wlc, u8 rate) { return brcms_b_rate_shm_offset(wlc->hw, rate); @@ -3098,8 +6667,8 @@ static u16 brcms_c_rate_shm_offset(struct brcms_c_info *wlc, u8 rate) * * Returns true if packet consumed (queued), false if not. */ -bool -brcms_c_prec_enq(struct brcms_c_info *wlc, struct pktq *q, void *pkt, int prec) +bool brcms_c_prec_enq(struct brcms_c_info *wlc, struct pktq *q, + struct sk_buff *pkt, int prec) { return brcms_c_prec_enq_head(wlc, q, pkt, prec, false); } @@ -3151,10 +6720,9 @@ brcms_c_prec_enq_head(struct brcms_c_info *wlc, struct pktq *q, return true; } -void brcms_c_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu, - uint prec) +void brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb, + struct sk_buff *sdu, uint prec) { - struct brcms_c_info *wlc = (struct brcms_c_info *) ctx; struct brcms_txq_info *qi = wlc->pkt_queue; /* Check me */ struct pktq *q = &qi->q; int prio; @@ -3174,20 +6742,20 @@ void brcms_c_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu, brcmu_pkt_buf_free_skb(sdu); } - /* Check if flow control needs to be turned on after enqueuing the packet - * Don't turn on flow control if EDCF is enabled. Driver would make the decision on what - * to drop instead of relying on stack to make the right decision + /* + * Check if flow control needs to be turned on after enqueuing the + * packet. Don't turn on flow control if EDCF is enabled. Driver + * would make the decision on what to drop instead of relying on + * stack to make the right decision */ if (!EDCF_ENAB(wlc->pub) || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL)) { - if (pktq_len(q) >= wlc->pub->tunables->datahiwat) { + if (pktq_len(q) >= wlc->pub->tunables->datahiwat) brcms_c_txflowcontrol(wlc, qi, ON, ALLPRIO); - } } else if (wlc->pub->_priofc) { if (pktq_plen(q, wlc_prio2prec_map[prio]) >= - wlc->pub->tunables->datahiwat) { + wlc->pub->tunables->datahiwat) brcms_c_txflowcontrol(wlc, qi, ON, prio); - } } } @@ -3197,20 +6765,21 @@ brcms_c_sendpkt_mac80211(struct brcms_c_info *wlc, struct sk_buff *sdu, { u8 prio; uint fifo; - void *pkt; struct scb *scb = &global_scb; struct ieee80211_hdr *d11_header = (struct ieee80211_hdr *)(sdu->data); - /* 802.11 standard requires management traffic to go at highest priority */ + /* + * 802.11 standard requires management traffic + * to go at highest priority + */ prio = ieee80211_is_data(d11_header->frame_control) ? sdu->priority : MAXPRIO; fifo = prio2fifo[prio]; - pkt = sdu; if (unlikely (brcms_c_d11hdrs_mac80211( - wlc, hw, pkt, scb, 0, 1, fifo, 0, NULL, 0))) + wlc, hw, sdu, scb, 0, 1, fifo, 0, NULL, 0))) return -EINVAL; - brcms_c_txq_enq(wlc, scb, pkt, BRCMS_PRIO_TO_PREC(prio)); + brcms_c_txq_enq(wlc, scb, sdu, BRCMS_PRIO_TO_PREC(prio)); brcms_c_send_q(wlc); return 0; } @@ -3244,17 +6813,18 @@ void brcms_c_send_q(struct brcms_c_info *wlc) count = 1; err = brcms_c_prep_pdu(wlc, pkt[0], &fifo); if (!err) { - for (i = 0; i < count; i++) { + for (i = 0; i < count; i++) brcms_c_txfifo(wlc, fifo, pkt[i], true, 1); - } } } if (err == -EBUSY) { brcmu_pktq_penq_head(q, prec, pkt[0]); - /* If send failed due to any other reason than a change in - * HW FIFO condition, quit. Otherwise, read the new prec_map! + /* + * If send failed due to any other reason than a + * change in HW FIFO condition, quit. Otherwise, + * read the new prec_map! */ if (prec_map == wlc->tx_prec_map) break; @@ -3262,21 +6832,22 @@ void brcms_c_send_q(struct brcms_c_info *wlc) } } - /* Check if flow control needs to be turned off after sending the packet */ + /* + * Check if flow control needs to be turned off after + * sending the packet + */ if (!EDCF_ENAB(wlc->pub) || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL)) { if (brcms_c_txflowcontrol_prio_isset(wlc, qi, ALLPRIO) - && (pktq_len(q) < wlc->pub->tunables->datahiwat / 2)) { + && (pktq_len(q) < wlc->pub->tunables->datahiwat / 2)) brcms_c_txflowcontrol(wlc, qi, OFF, ALLPRIO); - } } else if (wlc->pub->_priofc) { int prio; for (prio = MAXPRIO; prio >= 0; prio--) { if (brcms_c_txflowcontrol_prio_isset(wlc, qi, prio) && (pktq_plen(q, wlc_prio2prec_map[prio]) < - wlc->pub->tunables->datahiwat / 2)) { + wlc->pub->tunables->datahiwat / 2)) brcms_c_txflowcontrol(wlc, qi, OFF, prio); - } } } in_send_q = false; @@ -3312,20 +6883,19 @@ brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p, txh = (struct d11txh *) (p->data); - /* When a BC/MC frame is being committed to the BCMC fifo via DMA (NOT PIO), update - * ucode or BSS info as appropriate. + /* When a BC/MC frame is being committed to the BCMC fifo + * via DMA (NOT PIO), update ucode or BSS info as appropriate. */ - if (fifo == TX_BCMC_FIFO) { + if (fifo == TX_BCMC_FIFO) frameid = le16_to_cpu(txh->TxFrameID); - } - if (BRCMS_WAR16165(wlc)) brcms_c_war16165(wlc, true); - /* Bump up pending count for if not using rpc. If rpc is used, this will be handled - * in brcms_b_txfifo() + /* + * Bump up pending count for if not using rpc. If rpc is + * used, this will be handled in brcms_b_txfifo() */ if (commit) { TXPKTPENDINC(wlc, fifo, txpktpend); @@ -3337,48 +6907,49 @@ brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, struct sk_buff *p, if (frameid != INVALIDFID) BCMCFID(wlc, frameid); - if (dma_txfast(wlc->hw->di[fifo], p, commit) < 0) { + if (dma_txfast(wlc->hw->di[fifo], p, commit) < 0) wiphy_err(wlc->wiphy, "txfifo: fatal, toss frames !!!\n"); - } } void -brcms_c_compute_plcp(struct brcms_c_info *wlc, ratespec_t rspec, +brcms_c_compute_plcp(struct brcms_c_info *wlc, u32 rspec, uint length, u8 *plcp) { - if (IS_MCS(rspec)) { + if (IS_MCS(rspec)) brcms_c_compute_mimo_plcp(rspec, length, plcp); - } else if (IS_OFDM(rspec)) { + else if (IS_OFDM(rspec)) brcms_c_compute_ofdm_plcp(rspec, length, plcp); - } else { + else brcms_c_compute_cck_plcp(wlc, rspec, length, plcp); - } return; } /* Rate: 802.11 rate code, length: PSDU length in octets */ -static void brcms_c_compute_mimo_plcp(ratespec_t rspec, uint length, u8 *plcp) +static void brcms_c_compute_mimo_plcp(u32 rspec, uint length, u8 *plcp) { u8 mcs = (u8) (rspec & RSPEC_RATE_MASK); plcp[0] = mcs; if (RSPEC_IS40MHZ(rspec) || (mcs == 32)) plcp[0] |= MIMO_PLCP_40MHZ; BRCMS_SET_MIMO_PLCP_LEN(plcp, length); - plcp[3] = RSPEC_MIMOPLCP3(rspec); /* rspec already holds this byte */ - plcp[3] |= 0x7; /* set smoothing, not sounding ppdu & reserved */ - plcp[4] = 0; /* number of extension spatial streams bit 0 & 1 */ + plcp[3] = RSPEC_MIMOPLCP3(rspec); /* rspec already holds this byte */ + plcp[3] |= 0x7; /* set smoothing, not sounding ppdu & reserved */ + plcp[4] = 0; /* number of extension spatial streams bit 0 & 1 */ plcp[5] = 0; } /* Rate: 802.11 rate code, length: PSDU length in octets */ static void -brcms_c_compute_ofdm_plcp(ratespec_t rspec, u32 length, u8 *plcp) +brcms_c_compute_ofdm_plcp(u32 rspec, u32 length, u8 *plcp) { u8 rate_signal; u32 tmp = 0; int rate = RSPEC2RATE(rspec); - /* encode rate per 802.11a-1999 sec 17.3.4.1, with lsb transmitted first */ + /* + * encode rate per 802.11a-1999 sec 17.3.4.1, with lsb + * transmitted first + */ rate_signal = rate_info[rate] & BRCMS_RATE_MASK; memset(plcp, 0, D11_PHY_HDR_LEN); D11A_PHY_HDR_SRATE((struct ofdm_phy_hdr *) plcp, rate_signal); @@ -3426,8 +6997,9 @@ static void brcms_c_cck_plcp_set(struct brcms_c_info *wlc, int rate_500, break; default: - wiphy_err(wlc->wiphy, "brcms_c_cck_plcp_set: unsupported rate %d" - "\n", rate_500); + wiphy_err(wlc->wiphy, + "brcms_c_cck_plcp_set: unsupported rate %d\n", + rate_500); rate_500 = BRCM_RATE_1M; usec = length << 3; break; @@ -3445,7 +7017,7 @@ static void brcms_c_cck_plcp_set(struct brcms_c_info *wlc, int rate_500, } /* Rate: 802.11 rate code, length: PSDU length in octets */ -static void brcms_c_compute_cck_plcp(struct brcms_c_info *wlc, ratespec_t rspec, +static void brcms_c_compute_cck_plcp(struct brcms_c_info *wlc, u32 rspec, uint length, u8 *plcp) { int rate = RSPEC2RATE(rspec); @@ -3464,7 +7036,7 @@ static void brcms_c_compute_cck_plcp(struct brcms_c_info *wlc, ratespec_t rspec, * preamble_type use short/GF or long/MM PLCP header */ static u16 -brcms_c_compute_frame_dur(struct brcms_c_info *wlc, ratespec_t rate, +brcms_c_compute_frame_dur(struct brcms_c_info *wlc, u32 rate, u8 preamble_type, uint next_frag_len) { u16 dur, sifs; @@ -3499,20 +7071,22 @@ brcms_c_compute_frame_dur(struct brcms_c_info *wlc, ratespec_t rate, */ u16 brcms_c_compute_rtscts_dur(struct brcms_c_info *wlc, bool cts_only, - ratespec_t rts_rate, - ratespec_t frame_rate, u8 rts_preamble_type, + u32 rts_rate, + u32 frame_rate, u8 rts_preamble_type, u8 frame_preamble_type, uint frame_len, bool ba) { u16 dur, sifs; sifs = SIFS(wlc->band); - if (!cts_only) { /* RTS/CTS */ + if (!cts_only) { + /* RTS/CTS */ dur = 3 * sifs; dur += (u16) brcms_c_calc_cts_time(wlc, rts_rate, rts_preamble_type); - } else { /* CTS-TO-SELF */ + } else { + /* CTS-TO-SELF */ dur = 2 * sifs; } @@ -3530,7 +7104,7 @@ brcms_c_compute_rtscts_dur(struct brcms_c_info *wlc, bool cts_only, return dur; } -u16 brcms_c_phytxctl1_calc(struct brcms_c_info *wlc, ratespec_t rspec) +u16 brcms_c_phytxctl1_calc(struct brcms_c_info *wlc, u32 rspec) { u16 phyctl1 = 0; u16 bw; @@ -3556,8 +7130,11 @@ u16 brcms_c_phytxctl1_calc(struct brcms_c_info *wlc, ratespec_t rspec) phyctl1 |= (mcs_table[mcs].tx_phy_ctl3 << 8); } else if (IS_CCK(rspec) && !BRCMS_ISLCNPHY(wlc->band) && !BRCMS_ISSSLPNPHY(wlc->band)) { - /* In CCK mode LPPHY overloads OFDM Modulation bits with CCK Data Rate */ - /* Eventually MIMOPHY would also be converted to this format */ + /* + * In CCK mode LPPHY overloads OFDM Modulation bits with CCK + * Data Rate. Eventually MIMOPHY would also be converted to + * this format + */ /* 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps */ phyctl1 = (bw | (RSPEC_STF(rspec) << PHY_TXC1_MODE_SHIFT)); } else { /* legacy OFDM/CCK */ @@ -3577,38 +7154,38 @@ u16 brcms_c_phytxctl1_calc(struct brcms_c_info *wlc, ratespec_t rspec) return phyctl1; } -ratespec_t -brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc, ratespec_t rspec, +u32 +brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc, u32 rspec, bool use_rspec, u16 mimo_ctlchbw) { - ratespec_t rts_rspec = 0; + u32 rts_rspec = 0; - if (use_rspec) { + if (use_rspec) /* use frame rate as rts rate */ rts_rspec = rspec; - - } else if (wlc->band->gmode && wlc->protection->_g && !IS_CCK(rspec)) { + else if (wlc->band->gmode && wlc->protection->_g && !IS_CCK(rspec)) /* Use 11Mbps as the g protection RTS target rate and fallback. * Use the BRCMS_BASIC_RATE() lookup to find the best basic rate * under the target in case 11 Mbps is not Basic. - * 6 and 9 Mbps are not usually selected by rate selection, but even - * if the OFDM rate we are protecting is 6 or 9 Mbps, 11 is more robust. + * 6 and 9 Mbps are not usually selected by rate selection, but + * even if the OFDM rate we are protecting is 6 or 9 Mbps, 11 + * is more robust. */ rts_rspec = BRCMS_BASIC_RATE(wlc, BRCM_RATE_11M); - } else { + else /* calculate RTS rate and fallback rate based on the frame rate * RTS must be sent at a basic rate since it is a * control frame, sec 9.6 of 802.11 spec */ rts_rspec = BRCMS_BASIC_RATE(wlc, rspec); - } if (BRCMS_PHY_11N_CAP(wlc->band)) { /* set rts txbw to correct side band */ rts_rspec &= ~RSPEC_BW_MASK; - /* if rspec/rspec_fallback is 40MHz, then send RTS on both 20MHz channel - * (DUP), otherwise send RTS on control channel + /* + * if rspec/rspec_fallback is 40MHz, then send RTS on both + * 20MHz channel (DUP), otherwise send RTS on control channel */ if (RSPEC_IS40MHZ(rspec) && !IS_CCK(rts_rspec)) rts_rspec |= (PHY_TXC1_BW_40MHZ_DUP << RSPEC_BW_SHIFT); @@ -3637,7 +7214,7 @@ static u16 brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, struct sk_buff *p, struct scb *scb, uint frag, uint nfrags, uint queue, uint next_frag_len, - struct wsec_key *key, ratespec_t rspec_override) + struct wsec_key *key, u32 rspec_override) { struct ieee80211_hdr *h; struct d11txh *txh; @@ -3645,7 +7222,7 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, int len, phylen, rts_phylen; u16 mch, phyctl, xfts, mainrates; u16 seq = 0, mcl = 0, status = 0, frameid = 0; - ratespec_t rspec[2] = { BRCM_RATE_1M, BRCM_RATE_1M }, rts_rspec[2] = { + u32 rspec[2] = { BRCM_RATE_1M, BRCM_RATE_1M }, rts_rspec[2] = { BRCM_RATE_1M, BRCM_RATE_1M}; bool use_rts = false; bool use_cts = false; @@ -3685,9 +7262,8 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, * the packet itself, thus phylen = packet length + ICV_LEN + FCS_LEN * in this case */ - if (key) { + if (key) phylen += key->icv_len; - } /* Get tx_info */ tx_info = IEEE80211_SKB_CB(p); @@ -3708,9 +7284,8 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, frameid = bcmc_fid_generate(wlc, NULL, txh); } else { /* Increment the counter for first fragment */ - if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) { + if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) SCB_SEQNUM(scb, p->priority)++; - } /* extract fragment number from frame first */ seq = le16_to_cpu(seq) & FRAGNUM_MASK; @@ -3730,10 +7305,12 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, txrate[0] = tx_info->control.rates; txrate[1] = txrate[0] + 1; - /* if rate control algorithm didn't give us a fallback rate, use the primary rate */ - if (txrate[1]->idx < 0) { + /* + * if rate control algorithm didn't give us a fallback + * rate, use the primary rate + */ + if (txrate[1]->idx < 0) txrate[1] = txrate[0]; - } for (k = 0; k < hw->max_rates; k++) { is_mcs[k] = @@ -3755,8 +7332,11 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, } else { rate_val[k] = txrate[k]->idx; } - /* Currently only support same setting for primay and fallback rates. - * Unify flags for each rate into a single value for the frame + + /* + * Currently only support same setting for primay and + * fallback rates. Unify flags for each rate into a + * single value for the frame */ use_rts |= txrate[k]-> @@ -3770,7 +7350,11 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, rspec[k] = mac80211_wlc_set_nrate(wlc, wlc->band, rate_val[k]); - /* (1) RATE: determine and validate primary rate and fallback rates */ + /* + * (1) RATE: + * determine and validate primary rate + * and fallback rates + */ if (!RSPEC_ACTIVE(rspec[k])) { rspec[k] = BRCM_RATE_1M; } else { @@ -3786,7 +7370,10 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, if (N_ENAB(wlc->pub)) { for (k = 0; k < hw->max_rates; k++) { - /* apply siso/cdd to single stream mcs's or ofdm if rspec is auto selected */ + /* + * apply siso/cdd to single stream mcs's or ofdm + * if rspec is auto selected + */ if (((IS_MCS(rspec[k]) && IS_SINGLE_STREAM(rspec[k] & RSPEC_RATE_MASK)) || IS_OFDM(rspec[k])) @@ -3799,17 +7386,20 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, && BRCMS_STF_SS_STBC_TX(wlc, scb)) { u8 stc; - stc = 1; /* Nss for single stream is always 1 */ - rspec[k] |= - (PHY_TXC1_MODE_STBC << - RSPEC_STF_SHIFT) | (stc << - RSPEC_STC_SHIFT); + /* Nss for single stream is always 1 */ + stc = 1; + rspec[k] |= (PHY_TXC1_MODE_STBC << + RSPEC_STF_SHIFT) | + (stc << RSPEC_STC_SHIFT); } else rspec[k] |= (phyctl1_stf << RSPEC_STF_SHIFT); } - /* Is the phy configured to use 40MHZ frames? If so then pick the desired txbw */ + /* + * Is the phy configured to use 40MHZ frames? If + * so then pick the desired txbw + */ if (CHSPEC_WLC_BW(wlc->chanspec) == BRCMS_40_MHZ) { /* default txbw is 20in40 SB */ mimo_ctlchbw = mimo_txbw = @@ -3818,7 +7408,8 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, if (IS_MCS(rspec[k])) { /* mcs 32 must be 40b/w DUP */ - if ((rspec[k] & RSPEC_RATE_MASK) == 32) { + if ((rspec[k] & RSPEC_RATE_MASK) + == 32) { mimo_txbw = PHY_TXC1_BW_40MHZ_DUP; /* use override */ @@ -3830,18 +7421,19 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, } else if (IS_OFDM(rspec[k])) { if (wlc->ofdm_40txbw != AUTO) mimo_txbw = wlc->ofdm_40txbw; - } else { - if (wlc->cck_40txbw != AUTO) - mimo_txbw = wlc->cck_40txbw; + } else if (wlc->cck_40txbw != AUTO) { + mimo_txbw = wlc->cck_40txbw; } } else { - /* mcs32 is 40 b/w only. - * This is possible for probe packets on a STA during SCAN + /* + * mcs32 is 40 b/w only. + * This is possible for probe packets on + * a STA during SCAN */ - if ((rspec[k] & RSPEC_RATE_MASK) == 32) { + if ((rspec[k] & RSPEC_RATE_MASK) == 32) /* mcs 0 */ rspec[k] = RSPEC_MIMORATE; - } + mimo_txbw = PHY_TXC1_BW_20MHZ; } @@ -3852,16 +7444,8 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, else rspec[k] |= (mimo_ctlchbw << RSPEC_BW_SHIFT); - /* Set Short GI */ -#ifdef NOSGIYET - if (IS_MCS(rspec[k]) - && (txrate[k]->flags & IEEE80211_TX_RC_SHORT_GI)) - rspec[k] |= RSPEC_SHORT_GI; - else if (!(txrate[k]->flags & IEEE80211_TX_RC_SHORT_GI)) - rspec[k] &= ~RSPEC_SHORT_GI; -#else + /* Disable short GI, not supported yet */ rspec[k] &= ~RSPEC_SHORT_GI; -#endif mimo_preamble_type = BRCMS_MM_PREAMBLE; if (txrate[k]->flags & IEEE80211_TX_RC_GREEN_FIELD) @@ -3877,12 +7461,14 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, if (IS_MCS(rspec[k])) { preamble_type[k] = mimo_preamble_type; - /* if SGI is selected, then forced mm for single stream */ + /* + * if SGI is selected, then forced mm + * for single stream + */ if ((rspec[k] & RSPEC_SHORT_GI) && IS_SINGLE_STREAM(rspec[k] & - RSPEC_RATE_MASK)) { + RSPEC_RATE_MASK)) preamble_type[k] = BRCMS_MM_PREAMBLE; - } } /* should be better conditionalized */ @@ -4002,12 +7588,14 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, /* TxFrameID */ txh->TxFrameID = cpu_to_le16(frameid); - /* TxStatus, Note the case of recreating the first frag of a suppressed frame - * then we may need to reset the retry cnt's via the status reg + /* + * TxStatus, Note the case of recreating the first frag of a suppressed + * frame then we may need to reset the retry cnt's via the status reg */ txh->TxStatus = cpu_to_le16(status); - /* extra fields for ucode AMPDU aggregation, the new fields are added to + /* + * extra fields for ucode AMPDU aggregation, the new fields are added to * the END of previous structure so that it's compatible in driver. */ txh->MaxNMpdus = cpu_to_le16(0); @@ -4110,16 +7698,22 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, #ifdef SUPPORT_40MHZ /* add null delimiter count */ - if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && IS_MCS(rspec)) { + if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && IS_MCS(rspec)) txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] = brcm_c_ampdu_null_delim_cnt(wlc->ampdu, scb, rspec, phylen); - } + #endif - /* Now that RTS/RTS FB preamble types are updated, write the final value */ + /* + * Now that RTS/RTS FB preamble types are updated, write + * the final value + */ txh->MacTxControlHigh = cpu_to_le16(mch); - /* MainRates (both the rts and frag plcp rates have been calculated now) */ + /* + * MainRates (both the rts and frag plcp rates have + * been calculated now) + */ txh->MainRates = cpu_to_le16(mainrates); /* XtraFrameTypes */ @@ -4159,9 +7753,9 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, } /* - * For mcs frames, if mixedmode(overloaded with long preamble) is going to be set, - * fill in non-zero MModeLen and/or MModeFbrLen - * it will be unnecessary if they are separated + * For mcs frames, if mixedmode(overloaded with long preamble) + * is going to be set, fill in non-zero MModeLen and/or + * MModeFbrLen it will be unnecessary if they are separated */ if (IS_MCS(rspec[0]) && (preamble_type[0] == BRCMS_MM_PREAMBLE)) { @@ -4183,7 +7777,7 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, uint frag_dur, dur, dur_fallback; /* WME: Update TXOP threshold */ - if ((!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) && (frag == 0)) { + if (!(tx_info->flags & IEEE80211_TX_CTL_AMPDU) && frag == 0) { frag_dur = brcms_c_calc_frame_time(wlc, rspec[0], preamble_type[0], phylen); @@ -4220,40 +7814,44 @@ brcms_c_d11hdrs_mac80211(struct brcms_c_info *wlc, struct ieee80211_hw *hw, } /* NEED to set TxFesTimeNormal (hard) */ txh->TxFesTimeNormal = cpu_to_le16((u16) dur); - /* NEED to set fallback rate version of TxFesTimeNormal (hard) */ + /* + * NEED to set fallback rate version of + * TxFesTimeNormal (hard) + */ txh->TxFesTimeFallback = cpu_to_le16((u16) dur_fallback); - /* update txop byte threshold (txop minus intraframe overhead) */ + /* + * update txop byte threshold (txop minus intraframe + * overhead) + */ if (wlc->edcf_txop[ac] >= (dur - frag_dur)) { - { - uint newfragthresh; - + uint newfragthresh; + + newfragthresh = + brcms_c_calc_frame_len(wlc, + rspec[0], preamble_type[0], + (wlc->edcf_txop[ac] - + (dur - frag_dur))); + /* range bound the fragthreshold */ + if (newfragthresh < DOT11_MIN_FRAG_LEN) newfragthresh = - brcms_c_calc_frame_len(wlc, - rspec[0], preamble_type[0], - (wlc->edcf_txop[ac] - - (dur - frag_dur))); - /* range bound the fragthreshold */ - if (newfragthresh < DOT11_MIN_FRAG_LEN) - newfragthresh = - DOT11_MIN_FRAG_LEN; - else if (newfragthresh > - wlc->usr_fragthresh) - newfragthresh = - wlc->usr_fragthresh; - /* update the fragthresh and do txc update */ - if (wlc->fragthresh[queue] != - (u16) newfragthresh) { - wlc->fragthresh[queue] = - (u16) newfragthresh; - } - } - } else + DOT11_MIN_FRAG_LEN; + else if (newfragthresh > + wlc->usr_fragthresh) + newfragthresh = + wlc->usr_fragthresh; + /* update the fragthresh and do txc update */ + if (wlc->fragthresh[queue] != + (u16) newfragthresh) + wlc->fragthresh[queue] = + (u16) newfragthresh; + } else { wiphy_err(wlc->wiphy, "wl%d: %s txop invalid " "for rate %d\n", wlc->pub->unit, fifo_names[queue], RSPEC2RATE(rspec[0])); + } if (dur > wlc->edcf_txop[ac]) wiphy_err(wlc->wiphy, "wl%d: %s: %s txop " @@ -4272,10 +7870,12 @@ void brcms_c_tbtt(struct brcms_c_info *wlc) { struct brcms_bss_cfg *cfg = wlc->cfg; - if (!cfg->BSS) { - /* DirFrmQ is now valid...defer setting until end of ATIM window */ + if (!cfg->BSS) + /* + * DirFrmQ is now valid...defer setting until end + * of ATIM window + */ wlc->qvalid |= MCMD_DIRFRMQVAL; - } } static void brcms_c_war16165(struct brcms_c_info *wlc, bool tx) @@ -4309,12 +7909,13 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs, u32 frm_tx2) struct ieee80211_tx_rate *txrate; int i; - (void)(frm_tx2); /* Compiler reference to avoid unused variable warning */ + /* Compiler reference to avoid unused variable warning */ + (void)(frm_tx2); /* discard intermediate indications for ucode with one legitimate case: - * e.g. if "useRTS" is set. ucode did a successful rts/cts exchange, but the subsequent - * tx of DATA failed. so it will start rts/cts from the beginning (resetting the rts - * transmission count) + * e.g. if "useRTS" is set. ucode did a successful rts/cts exchange, + * but the subsequent tx of DATA failed. so it will start rts/cts + * from the beginning (resetting the rts transmission count) */ if (!(txs->status & TX_STATUS_AMPDU) && (txs->status & TX_STATUS_INTERMEDIATE)) { @@ -4406,13 +8007,22 @@ brcms_c_dotxstatus(struct brcms_c_info *wlc, struct tx_status *txs, u32 frm_tx2) ieee80211_tx_info_clear_status(tx_info); if ((tx_frame_count > fbl) && (txrate[1].idx >= 0)) { - /* rate selection requested a fallback rate and we used it */ + /* + * rate selection requested a fallback rate + * and we used it + */ txrate[0].count = fbl; txrate[1].count = tx_frame_count - fbl; } else { - /* rate selection did not request fallback rate, or we didn't need it */ + /* + * rate selection did not request fallback rate, or + * we didn't need it + */ txrate[0].count = tx_frame_count; - /* rc80211_minstrel.c:minstrel_tx_status() expects unused rates to be marked with idx = -1 */ + /* + * rc80211_minstrel.c:minstrel_tx_status() expects + * unused rates to be marked with idx = -1 + */ txrate[1].idx = -1; txrate[1].count = 0; } @@ -4466,9 +8076,8 @@ brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo, s8 txpktpend) /* Clear MHF2_TXBCMC_NOW flag if BCMC fifo has drained */ if (AP_ENAB(wlc->pub) && - !TXPKTPENDGET(wlc, TX_BCMC_FIFO)) { + !TXPKTPENDGET(wlc, TX_BCMC_FIFO)) brcms_c_mhf(wlc, MHF2, MHF2_TXBCMC_NOW, 0, BRCM_BAND_AUTO); - } /* figure out which bsscfg is being worked on... */ } @@ -4487,6 +8096,19 @@ void brcms_c_bcn_li_upd(struct brcms_c_info *wlc) (wlc->bcn_li_dtim << 8) | wlc->bcn_li_bcn); } +void +brcms_b_read_tsf(struct brcms_hardware *wlc_hw, u32 *tsf_l_ptr, + u32 *tsf_h_ptr) +{ + struct d11regs *regs = wlc_hw->regs; + + /* read the tsf timer low, then high to get an atomic read */ + *tsf_l_ptr = R_REG(®s->tsf_timerlow); + *tsf_h_ptr = R_REG(®s->tsf_timerhigh); + + return; +} + /* * recover 64bit TSF value from the 16bit TSF value in the rx header * given the assumption that the TSF passed in header is within 65ms @@ -4533,7 +8155,7 @@ prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh, struct brcms_d11rxhdr *wlc_rxh = (struct brcms_d11rxhdr *) rxh; int preamble; int channel; - ratespec_t rspec; + u32 rspec; unsigned char *plcp; /* fill in TSF and flag its presence */ @@ -4552,11 +8174,12 @@ prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh, rx_status->freq = ieee80211_dsss_chan_to_freq(channel); } - rx_status->signal = wlc_rxh->rssi; /* signal */ + rx_status->signal = wlc_rxh->rssi; /* noise */ /* qual */ - rx_status->antenna = (rxh->PhyRxStatus_0 & PRXS0_RXANT_UPSUBBAND) ? 1 : 0; /* ant */ + rx_status->antenna = + (rxh->PhyRxStatus_0 & PRXS0_RXANT_UPSUBBAND) ? 1 : 0; plcp = p->data; @@ -4608,6 +8231,14 @@ prep_mac80211_status(struct brcms_c_info *wlc, struct d11rxhdr *rxh, wiphy_err(wlc->wiphy, "%s: Unknown rate\n", __func__); } + /* + * For 5GHz, we should decrease the index as it is + * a subset of the 2.4G rates. See bitrates field + * of brcms_band_5GHz_nphy (in mac80211_if.c). + */ + if (rx_status->band == IEEE80211_BAND_5GHZ) + rx_status->rate_idx -= BRCMS_LEGACY_5G_RATE_OFFSET; + /* Determine short preamble and rate_idx */ preamble = 0; if (IS_CCK(rspec)) { @@ -4714,9 +8345,8 @@ void brcms_c_recv(struct brcms_c_info *wlc, struct sk_buff *p) } /* check received pkt has at least frame control field */ - if (len < D11_PHY_HDR_LEN + sizeof(h->frame_control)) { + if (len < D11_PHY_HDR_LEN + sizeof(h->frame_control)) goto toss; - } is_amsdu = rxh->RxStatus2 & RXS_AMSDU_MASK; @@ -4758,7 +8388,7 @@ void brcms_c_recv(struct brcms_c_info *wlc, struct sk_buff *p) * len = 3(nsyms + nstream + 3) - 3 */ u16 -brcms_c_calc_lsig_len(struct brcms_c_info *wlc, ratespec_t ratespec, +brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec, uint mac_len) { uint nsyms, len = 0, kNdps; @@ -4771,14 +8401,16 @@ brcms_c_calc_lsig_len(struct brcms_c_info *wlc, ratespec_t ratespec, /* MCS_TXS(mcs) returns num tx streams - 1 */ int tot_streams = (MCS_TXS(mcs) + 1) + RSPEC_STC(ratespec); - /* the payload duration calculation matches that of regular ofdm */ + /* + * the payload duration calculation matches that + * of regular ofdm + */ /* 1000Ndbps = kbps * 4 */ kNdps = MCS_RATE(mcs, RSPEC_IS40MHZ(ratespec), RSPEC_ISSGI(ratespec)) * 4; if (RSPEC_STC(ratespec) == 0) - /* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */ nsyms = CEIL((APHY_SERVICE_NBITS + 8 * mac_len + APHY_TAIL_NBITS) * 1000, kNdps); @@ -4789,17 +8421,24 @@ brcms_c_calc_lsig_len(struct brcms_c_info *wlc, ratespec_t ratespec, CEIL((APHY_SERVICE_NBITS + 8 * mac_len + APHY_TAIL_NBITS) * 1000, 2 * kNdps); - nsyms += (tot_streams + 3); /* (+3) account for HT-SIG(2) and HT-STF(1) */ - /* 3 bytes/symbol @ legacy 6Mbps rate */ - len = (3 * nsyms) - 3; /* (-3) excluding service bits and tail bits */ + /* (+3) account for HT-SIG(2) and HT-STF(1) */ + nsyms += (tot_streams + 3); + /* + * 3 bytes/symbol @ legacy 6Mbps rate + * (-3) excluding service bits and tail bits + */ + len = (3 * nsyms) - 3; } return (u16) len; } -/* calculate frame duration of a given rate and length, return time in usec unit */ +/* + * calculate frame duration of a given rate and length, return + * time in usec unit + */ uint -brcms_c_calc_frame_time(struct brcms_c_info *wlc, ratespec_t ratespec, +brcms_c_calc_frame_time(struct brcms_c_info *wlc, u32 ratespec, u8 preamble_type, uint mac_len) { uint nsyms, dur = 0, Ndps, kNdps; @@ -4827,7 +8466,6 @@ brcms_c_calc_frame_time(struct brcms_c_info *wlc, ratespec_t ratespec, RSPEC_ISSGI(ratespec)) * 4; if (RSPEC_STC(ratespec) == 0) - /* NSyms = CEILING((SERVICE + 8*NBytes + TAIL) / Ndbps) */ nsyms = CEIL((APHY_SERVICE_NBITS + 8 * mac_len + APHY_TAIL_NBITS) * 1000, kNdps); @@ -4854,7 +8492,10 @@ brcms_c_calc_frame_time(struct brcms_c_info *wlc, ratespec_t ratespec, if (BAND_2G(wlc->band->bandtype)) dur += DOT11_OFDM_SIGNAL_EXTENSION; } else { - /* calc # bits * 2 so factor of 2 in rate (1/2 mbps) will divide out */ + /* + * calc # bits * 2 so factor of 2 in rate (1/2 mbps) + * will divide out + */ mac_len = mac_len * 8 * 2; /* calc ceiling of bits/rate = microseconds of air time */ dur = (mac_len + rate - 1) / rate; @@ -4868,7 +8509,7 @@ brcms_c_calc_frame_time(struct brcms_c_info *wlc, ratespec_t ratespec, /* The opposite of brcms_c_calc_frame_time */ static uint -brcms_c_calc_frame_len(struct brcms_c_info *wlc, ratespec_t ratespec, +brcms_c_calc_frame_len(struct brcms_c_info *wlc, u32 ratespec, u8 preamble_type, uint dur) { uint nsyms, mac_len, Ndps, kNdps; @@ -4914,13 +8555,15 @@ brcms_c_calc_frame_len(struct brcms_c_info *wlc, ratespec_t ratespec, } static uint -brcms_c_calc_ba_time(struct brcms_c_info *wlc, ratespec_t rspec, +brcms_c_calc_ba_time(struct brcms_c_info *wlc, u32 rspec, u8 preamble_type) { BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, " "preamble_type %d\n", wlc->pub->unit, rspec, preamble_type); - /* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that is less than - * or equal to the rate of the immediately previous frame in the FES + /* + * Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that + * is less than or equal to the rate of the immediately previous + * frame in the FES */ rspec = BRCMS_BASIC_RATE(wlc, rspec); /* BA len == 32 == 16(ctl hdr) + 4(ba len) + 8(bitmap) + 4(fcs) */ @@ -4930,15 +8573,17 @@ brcms_c_calc_ba_time(struct brcms_c_info *wlc, ratespec_t rspec, } static uint -brcms_c_calc_ack_time(struct brcms_c_info *wlc, ratespec_t rspec, +brcms_c_calc_ack_time(struct brcms_c_info *wlc, u32 rspec, u8 preamble_type) { uint dur = 0; BCMMSG(wlc->wiphy, "wl%d: rspec 0x%x, preamble_type %d\n", wlc->pub->unit, rspec, preamble_type); - /* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that is less than - * or equal to the rate of the immediately previous frame in the FES + /* + * Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that + * is less than or equal to the rate of the immediately previous + * frame in the FES */ rspec = BRCMS_BASIC_RATE(wlc, rspec); /* ACK frame len == 14 == 2(fc) + 2(dur) + 6(ra) + 4(fcs) */ @@ -4949,7 +8594,7 @@ brcms_c_calc_ack_time(struct brcms_c_info *wlc, ratespec_t rspec, } static uint -brcms_c_calc_cts_time(struct brcms_c_info *wlc, ratespec_t rspec, +brcms_c_calc_cts_time(struct brcms_c_info *wlc, u32 rspec, u8 preamble_type) { BCMMSG(wlc->wiphy, "wl%d: ratespec 0x%x, preamble_type %d\n", @@ -4958,7 +8603,8 @@ brcms_c_calc_cts_time(struct brcms_c_info *wlc, ratespec_t rspec, } /* derive wlc->band->basic_rate[] table from 'rateset' */ -void brcms_c_rate_lookup_init(struct brcms_c_info *wlc, wlc_rateset_t *rateset) +void brcms_c_rate_lookup_init(struct brcms_c_info *wlc, + struct brcms_c_rateset *rateset) { u8 rate; u8 mandatory; @@ -5032,7 +8678,10 @@ void brcms_c_rate_lookup_init(struct brcms_c_info *wlc, wlc_rateset_t *rateset) continue; if (IS_OFDM(rate)) { - /* In 11g and 11a, the OFDM mandatory rates are 6, 12, and 24 Mbps */ + /* + * In 11g and 11a, the OFDM mandatory rates + * are 6, 12, and 24 Mbps + */ if (rate >= BRCM_RATE_24M) mandatory = BRCM_RATE_24M; else if (rate >= BRCM_RATE_12M) @@ -5040,7 +8689,7 @@ void brcms_c_rate_lookup_init(struct brcms_c_info *wlc, wlc_rateset_t *rateset) else mandatory = BRCM_RATE_6M; } else { - /* In 11b, all the CCK rates are mandatory 1 - 11 Mbps */ + /* In 11b, all CCK rates are mandatory 1 - 11 Mbps */ mandatory = rate; } @@ -5082,9 +8731,10 @@ static void brcms_c_write_rate_shm(struct brcms_c_info *wlc, u8 rate, brcms_c_write_shm(wlc, (basic_table + index * 2), basic_ptr); } -static const wlc_rateset_t *brcms_c_rateset_get_hwrs(struct brcms_c_info *wlc) +static const struct brcms_c_rateset * +brcms_c_rateset_get_hwrs(struct brcms_c_info *wlc) { - const wlc_rateset_t *rs_dflt; + const struct brcms_c_rateset *rs_dflt; if (BRCMS_PHY_11N_CAP(wlc->band)) { if (BAND_5G(wlc->band->bandtype)) @@ -5101,8 +8751,8 @@ static const wlc_rateset_t *brcms_c_rateset_get_hwrs(struct brcms_c_info *wlc) void brcms_c_set_ratetable(struct brcms_c_info *wlc) { - const wlc_rateset_t *rs_dflt; - wlc_rateset_t rs; + const struct brcms_c_rateset *rs_dflt; + struct brcms_c_rateset rs; u8 rate, basic_rate; uint i; @@ -5119,12 +8769,11 @@ void brcms_c_set_ratetable(struct brcms_c_info *wlc) * which a response ACK/CTS should be sent. */ basic_rate = BRCMS_BASIC_RATE(wlc, rate); - if (basic_rate == 0) { + if (basic_rate == 0) /* This should only happen if we are using a * restricted rateset. */ basic_rate = rs.rates[0] & BRCMS_RATE_MASK; - } brcms_c_write_rate_shm(wlc, rate, basic_rate); } @@ -5134,20 +8783,19 @@ void brcms_c_set_ratetable(struct brcms_c_info *wlc) * Return true if the specified rate is supported by the specified band. * BRCM_BAND_AUTO indicates the current band. */ -bool brcms_c_valid_rate(struct brcms_c_info *wlc, ratespec_t rspec, int band, +bool brcms_c_valid_rate(struct brcms_c_info *wlc, u32 rspec, int band, bool verbose) { - wlc_rateset_t *hw_rateset; + struct brcms_c_rateset *hw_rateset; uint i; - if ((band == BRCM_BAND_AUTO) || (band == wlc->band->bandtype)) { + if ((band == BRCM_BAND_AUTO) || (band == wlc->band->bandtype)) hw_rateset = &wlc->band->hw_rateset; - } else if (NBANDS(wlc) > 1) { + else if (NBANDS(wlc) > 1) hw_rateset = &wlc->bandstate[OTHERBANDUNIT(wlc)]->hw_rateset; - } else { + else /* other band specified and we are a single band device */ return false; - } /* check if this is a mimo rate */ if (IS_MCS(rspec)) { @@ -5161,10 +8809,9 @@ bool brcms_c_valid_rate(struct brcms_c_info *wlc, ratespec_t rspec, int band, if (hw_rateset->rates[i] == RSPEC2RATE(rspec)) return true; error: - if (verbose) { + if (verbose) wiphy_err(wlc->wiphy, "wl%d: valid_rate: rate spec 0x%x " "not in hw_rateset\n", wlc->pub->unit, rspec); - } return false; } @@ -5195,8 +8842,8 @@ static void brcms_c_update_mimo_band_bwcap(struct brcms_c_info *wlc, u8 bwcap) void brcms_c_mod_prb_rsp_rate_table(struct brcms_c_info *wlc, uint frame_len) { - const wlc_rateset_t *rs_dflt; - wlc_rateset_t rs; + const struct brcms_c_rateset *rs_dflt; + struct brcms_c_rateset rs; u8 rate; u16 entry_ptr; u8 plcp[D11_PHY_HDR_LEN]; @@ -5210,7 +8857,10 @@ void brcms_c_mod_prb_rsp_rate_table(struct brcms_c_info *wlc, uint frame_len) brcms_c_rateset_copy(rs_dflt, &rs); brcms_c_rateset_mcs_upd(&rs, wlc->stf->txstreams); - /* walk the phy rate table and update MAC core SHM basic rate table entries */ + /* + * walk the phy rate table and update MAC core SHM + * basic rate table entries + */ for (i = 0; i < rs.count; i++) { rate = rs.rates[i] & BRCMS_RATE_MASK; @@ -5219,7 +8869,10 @@ void brcms_c_mod_prb_rsp_rate_table(struct brcms_c_info *wlc, uint frame_len) /* Calculate the Probe Response PLCP for the given rate */ brcms_c_compute_plcp(wlc, rate, frame_len, plcp); - /* Calculate the duration of the Probe Response frame plus SIFS for the MAC */ + /* + * Calculate the duration of the Probe Response + * frame plus SIFS for the MAC + */ dur = (u16) brcms_c_calc_frame_time(wlc, rate, BRCMS_LONG_PREAMBLE, frame_len); dur += sifs; @@ -5242,12 +8895,12 @@ void brcms_c_mod_prb_rsp_rate_table(struct brcms_c_info *wlc, uint frame_len) * * *len on input contains the max length of the packet available. * - * The *len value is set to the number of bytes in buf used, and starts with the PLCP - * and included up to, but not including, the 4 byte FCS. + * The *len value is set to the number of bytes in buf used, and starts + * with the PLCP and included up to, but not including, the 4 byte FCS. */ static void brcms_c_bcn_prb_template(struct brcms_c_info *wlc, u16 type, - ratespec_t bcn_rspec, + u32 bcn_rspec, struct brcms_bss_cfg *cfg, u16 *buf, int *len) { static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255}; @@ -5259,23 +8912,27 @@ brcms_c_bcn_prb_template(struct brcms_c_info *wlc, u16 type, hdr_len = DOT11_MAC_HDR_LEN; else hdr_len = D11_PHY_HDR_LEN + DOT11_MAC_HDR_LEN; - body_len = *len - hdr_len; /* calc buffer size provided for frame body */ - *len = hdr_len + body_len; /* return actual size */ + /* calc buffer size provided for frame body */ + body_len = *len - hdr_len; + /* return actual size */ + *len = hdr_len + body_len; /* format PHY and MAC headers */ memset((char *)buf, 0, hdr_len); plcp = (struct cck_phy_hdr *) buf; - /* PLCP for Probe Response frames are filled in from core's rate table */ - if (type == IEEE80211_STYPE_BEACON && !MBSS_BCN_ENAB(cfg)) { + /* + * PLCP for Probe Response frames are filled in from + * core's rate table + */ + if (type == IEEE80211_STYPE_BEACON && !MBSS_BCN_ENAB(cfg)) /* fill in PLCP */ brcms_c_compute_plcp(wlc, bcn_rspec, (DOT11_MAC_HDR_LEN + body_len + FCS_LEN), (u8 *) plcp); - } /* "Regular" and 16 MBSS but not for 4 MBSS */ /* Update the phytxctl for the beacon based on the rspec */ if (!SOFTBCN_ENAB(cfg)) @@ -5306,10 +8963,32 @@ int brcms_c_get_header_len() return TXOFF; } -/* Update a beacon for a particular BSS - * For MBSS, this updates the software template and sets "latest" to the index of the - * template updated. - * Otherwise, it updates the hardware template. +/* mac is assumed to be suspended at this point */ +void +brcms_b_write_hw_bcntemplates(struct brcms_hardware *wlc_hw, u16 bcn[], + int len, bool both) +{ + struct d11regs *regs = wlc_hw->regs; + + if (both) { + brcms_c_write_hw_bcntemplate0(wlc_hw, bcn, len); + brcms_c_write_hw_bcntemplate1(wlc_hw, bcn, len); + } else { + /* bcn 0 */ + if (!(R_REG(®s->maccommand) & MCMD_BCN0VLD)) + brcms_c_write_hw_bcntemplate0(wlc_hw, bcn, len); + /* bcn 1 */ + else if (! + (R_REG(®s->maccommand) & MCMD_BCN1VLD)) + brcms_c_write_hw_bcntemplate1(wlc_hw, bcn, len); + } +} + +/* + * Update a beacon for a particular BSS + * For MBSS, this updates the software template and sets "latest" to + * the index of the template updated. Otherwise, it updates the hardware + * template. */ void brcms_c_bss_update_beacon(struct brcms_c_info *wlc, struct brcms_bss_cfg *cfg) @@ -5319,24 +8998,24 @@ void brcms_c_bss_update_beacon(struct brcms_c_info *wlc, /* Clear the soft intmask */ wlc->defmacintmask &= ~MI_BCNTPL; - if (!cfg->up) { /* Only allow updates on an UP bss */ + if (!cfg->up) + /* Only allow updates on an UP bss */ return; - } /* Optimize: Some of if/else could be combined */ if (!MBSS_BCN_ENAB(cfg) && HWBCN_ENAB(cfg)) { /* Hardware beaconing for this config */ u16 bcn[BCN_TMPL_LEN / 2]; u32 both_valid = MCMD_BCN0VLD | MCMD_BCN1VLD; - d11regs_t *regs = wlc->regs; + struct d11regs *regs = wlc->regs; /* Check if both templates are in use, if so sched. an interrupt * that will call back into this routine */ - if ((R_REG(®s->maccommand) & both_valid) == both_valid) { + if ((R_REG(®s->maccommand) & both_valid) == both_valid) /* clear any previous status */ W_REG(®s->macintstatus, MI_BCNTPL); - } + /* Check that after scheduling the interrupt both of the * templates are still busy. if not clear the int. & remask */ @@ -5363,10 +9042,10 @@ void brcms_c_update_beacon(struct brcms_c_info *wlc) struct brcms_bss_cfg *bsscfg; /* update AP or IBSS beacons */ - FOREACH_BSS(wlc, idx, bsscfg) { + FOREACH_BSS(wlc, idx, bsscfg) if (bsscfg->up && (BSSCFG_AP(bsscfg) || !bsscfg->BSS)) brcms_c_bss_update_beacon(wlc, bsscfg); - } + END_FOREACH_BSS() } /* Write ssid into shared memory */ @@ -5392,10 +9071,10 @@ void brcms_c_update_probe_resp(struct brcms_c_info *wlc, bool suspend) struct brcms_bss_cfg *bsscfg; /* update AP or IBSS probe responses */ - FOREACH_BSS(wlc, idx, bsscfg) { + FOREACH_BSS(wlc, idx, bsscfg) if (bsscfg->up && (BSSCFG_AP(bsscfg) || !bsscfg->BSS)) brcms_c_bss_update_probe_resp(wlc, bsscfg, suspend); - } + END_FOREACH_BSS() } void @@ -5406,7 +9085,10 @@ brcms_c_bss_update_probe_resp(struct brcms_c_info *wlc, u16 prb_resp[BCN_TMPL_LEN / 2]; int len = BCN_TMPL_LEN; - /* write the probe response to hardware, or save in the config structure */ + /* + * write the probe response to hardware, or save in + * the config structure + */ if (!MBSS_PRB_ENAB(cfg)) { /* create the probe response template */ @@ -5427,17 +9109,18 @@ brcms_c_bss_update_probe_resp(struct brcms_c_info *wlc, brcms_c_shm_ssid_upd(wlc, cfg); /* - * Write PLCP headers and durations for probe response frames at all rates. - * Use the actual frame length covered by the PLCP header for the call to - * brcms_c_mod_prb_rsp_rate_table() by subtracting the PLCP len - * and adding the FCS. + * Write PLCP headers and durations for probe response frames + * at all rates. Use the actual frame length covered by the + * PLCP header for the call to brcms_c_mod_prb_rsp_rate_table() + * by subtracting the PLCP len and adding the FCS. */ len += (-D11_PHY_HDR_LEN + FCS_LEN); brcms_c_mod_prb_rsp_rate_table(wlc, (u16) len); if (suspend) brcms_c_enable_mac(wlc); - } else { /* Generating probe resp in sw; update local template */ + } else { + /* Generating probe resp in sw; update local template */ /* error: No software probe response support without MBSS */ } } @@ -5476,9 +9159,9 @@ void brcms_c_reprate_init(struct brcms_c_info *wlc) int i; struct brcms_bss_cfg *bsscfg; - FOREACH_BSS(wlc, i, bsscfg) { + FOREACH_BSS(wlc, i, bsscfg) brcms_c_bsscfg_reprate_init(bsscfg); - } + END_FOREACH_BSS() } /* per bsscfg init tx reported rate mechanism */ @@ -5488,7 +9171,7 @@ void brcms_c_bsscfg_reprate_init(struct brcms_bss_cfg *bsscfg) memset((char *)bsscfg->txrspec, 0, sizeof(bsscfg->txrspec)); } -void brcms_default_rateset(struct brcms_c_info *wlc, wlc_rateset_t *rs) +void brcms_default_rateset(struct brcms_c_info *wlc, struct brcms_c_rateset *rs) { brcms_c_rateset_default(rs, NULL, wlc->band->phytype, wlc->band->bandtype, false, BRCMS_RATE_MASK_FULL, @@ -5499,7 +9182,7 @@ void brcms_default_rateset(struct brcms_c_info *wlc, wlc_rateset_t *rs) static void brcms_c_bss_default_init(struct brcms_c_info *wlc) { - chanspec_t chanspec; + u16 chanspec; struct brcms_band *band; struct brcms_bss_info *bi = wlc->default_bss; @@ -5529,22 +9212,21 @@ static void brcms_c_bss_default_init(struct brcms_c_info *wlc) bi->flags |= BRCMS_BSS_HT; } -static ratespec_t +static u32 mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band, u32 int_val) { u8 stf = (int_val & NRATE_STF_MASK) >> NRATE_STF_SHIFT; u8 rate = int_val & NRATE_RATE_MASK; - ratespec_t rspec; + u32 rspec; bool ismcs = ((int_val & NRATE_MCS_INUSE) == NRATE_MCS_INUSE); bool issgi = ((int_val & NRATE_SGI_MASK) >> NRATE_SGI_SHIFT); bool override_mcs_only = ((int_val & NRATE_OVERRIDE_MCS_ONLY) == NRATE_OVERRIDE_MCS_ONLY); int bcmerror = 0; - if (!ismcs) { - return (ratespec_t) rate; - } + if (!ismcs) + return (u32) rate; /* validate the combination of rate/mcs/stf is allowed */ if (N_ENAB(wlc->pub) && ismcs) { @@ -5576,7 +9258,10 @@ mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band, stf = PHY_TXC1_MODE_SDM; } } else { - /* MCS 0-7 may use SISO, CDD, and for phy_rev >= 3 STBC */ + /* + * MCS 0-7 may use SISO, CDD, and for + * phy_rev >= 3 STBC + */ if ((stf > PHY_TXC1_MODE_STBC) || (!BRCMS_STBC_CAP_PHY(wlc) && (stf == PHY_TXC1_MODE_STBC))) { @@ -5635,9 +9320,8 @@ mac80211_wlc_set_nrate(struct brcms_c_info *wlc, struct brcms_band *cur_band, rspec |= RSPEC_SHORT_GI; if ((rate != 0) - && !brcms_c_valid_rate(wlc, rspec, cur_band->bandtype, true)) { + && !brcms_c_valid_rate(wlc, rspec, cur_band->bandtype, true)) return rate; - } return rspec; done: @@ -5714,6 +9398,17 @@ void brcms_c_mhf(struct brcms_c_info *wlc, u8 idx, u16 mask, u16 val, int bands) brcms_b_mhf(wlc->hw, idx, mask, val, bands); } +int brcms_b_xmtfifo_sz_get(struct brcms_hardware *wlc_hw, uint fifo, + uint *blocks) +{ + if (fifo >= NFIFO) + return -EINVAL; + + *blocks = wlc_hw->xmtfifo_sz[fifo]; + + return 0; +} + int brcms_c_xmtfifo_sz_get(struct brcms_c_info *wlc, uint fifo, uint *blocks) { return brcms_b_xmtfifo_sz_get(wlc->hw, fifo, blocks); @@ -5725,8 +9420,8 @@ void brcms_c_write_template_ram(struct brcms_c_info *wlc, int offset, int len, brcms_b_write_template_ram(wlc->hw, offset, len, buf); } -void brcms_c_write_hw_bcntemplates(struct brcms_c_info *wlc, void *bcn, int len, - bool both) +void brcms_c_write_hw_bcntemplates(struct brcms_c_info *wlc, u16 bcn[], int len, + bool both) { brcms_b_write_hw_bcntemplates(wlc->hw, bcn, len, both); } @@ -5740,7 +9435,7 @@ brcms_c_set_addrmatch(struct brcms_c_info *wlc, int match_reg_offset, memcpy(wlc->cfg->BSSID, addr, ETH_ALEN); } -void brcms_c_pllreq(struct brcms_c_info *wlc, bool set, mbool req_bit) +void brcms_c_pllreq(struct brcms_c_info *wlc, bool set, u32 req_bit) { brcms_b_pllreq(wlc->hw, set, req_bit); } @@ -5757,11 +9452,10 @@ brcms_c_txflowcontrol_prio_isset(struct brcms_c_info *wlc, { uint prio_mask; - if (prio == ALLPRIO) { + if (prio == ALLPRIO) prio_mask = TXQ_STOP_FOR_PRIOFC_MASK; - } else { + else prio_mask = NBITVAL(prio); - } return (q->stopped & prio_mask) == prio_mask; } @@ -5776,11 +9470,10 @@ void brcms_c_txflowcontrol(struct brcms_c_info *wlc, BCMMSG(wlc->wiphy, "flow control kicks in\n"); - if (prio == ALLPRIO) { + if (prio == ALLPRIO) prio_bits = TXQ_STOP_FOR_PRIOFC_MASK; - } else { + else prio_bits = NBITVAL(prio); - } cur_bits = qi->stopped & prio_bits; @@ -5788,23 +9481,22 @@ void brcms_c_txflowcontrol(struct brcms_c_info *wlc, * Otherwise update the bit and continue */ if (on) { - if (cur_bits == prio_bits) { + if (cur_bits == prio_bits) return; - } + mboolset(qi->stopped, prio_bits); } else { - if (cur_bits == 0) { + if (cur_bits == 0) return; - } + mboolclr(qi->stopped, prio_bits); } /* If there is a flow control override we will not change the external * flow control state. */ - if (qi->stopped & ~TXQ_STOP_FOR_PRIOFC_MASK) { + if (qi->stopped & ~TXQ_STOP_FOR_PRIOFC_MASK) return; - } brcms_c_txflowcontrol_signal(wlc, qi, on, prio); } @@ -5826,9 +9518,8 @@ brcms_c_txflowcontrol_override(struct brcms_c_info *wlc, /* if there was a previous override bit on, then setting this * makes no difference. */ - if (prev_override) { + if (prev_override) return; - } brcms_c_txflowcontrol_signal(wlc, qi, ON, ALLPRIO); } else { @@ -5837,9 +9528,8 @@ brcms_c_txflowcontrol_override(struct brcms_c_info *wlc, * flow control if it was the only bit set. For any other * override setting, just return */ - if (prev_override != override) { + if (prev_override != override) return; - } if (qi->stopped == 0) { brcms_c_txflowcontrol_signal(wlc, qi, OFF, ALLPRIO); @@ -5871,15 +9561,7 @@ static void brcms_c_txflowcontrol_signal(struct brcms_c_info *wlc, struct brcms_txq_info *qi, bool on, int prio) { -#ifdef NON_FUNCTIONAL - /* wlcif_list is never filled so this function is not functional */ - struct brcms_c_if *wlcif; - - for (wlcif = wlc->wlcif_list; wlcif != NULL; wlcif = wlcif->next) { - if (wlcif->qi == qi && wlcif->flags & BRCMS_IF_LINKED) - brcms_txflowcontrol(wlc->wl, wlcif->wlif, on, prio); - } -#endif + /* wlcif_list is never filled so this function is not functional yet */ } static struct brcms_txq_info *brcms_c_txq_alloc(struct brcms_c_info *wlc) @@ -5983,9 +9665,8 @@ void brcms_c_wait_for_tx_completion(struct brcms_c_info *wlc, bool drop) /* wait for queue and DMA fifos to run dry */ while (!pktq_empty(&wlc->pkt_queue->q) || - TXPKTPENDTOT(wlc) > 0) { + TXPKTPENDTOT(wlc) > 0) brcms_msleep(wlc->wl, 1); - } } int brcms_c_set_par(struct brcms_c_info *wlc, enum wlc_par_id par_id, @@ -6093,10 +9774,11 @@ char *getvar(char *vars, const char *name) int getintvar(char *vars, const char *name) { char *val; + unsigned long res; val = getvar(vars, name); - if (val == NULL) - return 0; + if (val && !kstrtoul(val, 0, &res)) + return res; - return simple_strtoul(val, NULL, 0); + return 0; } diff --git a/drivers/staging/brcm80211/brcmsmac/main.h b/drivers/staging/brcm80211/brcmsmac/main.h index f204b1f..433e6a9 100644 --- a/drivers/staging/brcm80211/brcmsmac/main.h +++ b/drivers/staging/brcm80211/brcmsmac/main.h @@ -49,8 +49,7 @@ /* uS: 83mS is max packet time (64KB ampdu @ 6Mbps) */ #define BRCMS_MAX_MAC_SUSPEND 83000 -/* Probe Response timeout - responses for probe requests older that this are tossed, zero to disable - */ +/* responses for probe requests older that this are tossed, zero to disable */ #define BRCMS_PRB_RESP_TIMEOUT 0 /* Disable probe response timeout */ /* transmit buffer max headroom for protocol headers */ @@ -123,7 +122,9 @@ #define BOARDREV_PROMOTABLE 0xFF /* from */ #define BOARDREV_PROMOTED 1 /* to */ -/* if wpa is in use then portopen is true when the group key is plumbed otherwise it is always true +/* + * if wpa is in use then portopen is true when the + * group key is plumbed otherwise it is always true */ #define WSEC_ENABLED(wsec) ((wsec) & (WEP_ENABLED | TKIP_ENABLED | AES_ENABLED)) #define BRCMS_SW_KEYS(wlc, bsscfg) ((((wlc)->wsec_swkeys) || \ @@ -163,13 +164,13 @@ extern const u8 prio2fifo[]; #define RETRY_SHORT_DEF 7 /* Default Short retry Limit */ #define RETRY_SHORT_MAX 255 /* Maximum Short retry Limit */ #define RETRY_LONG_DEF 4 /* Default Long retry count */ -#define RETRY_SHORT_FB 3 /* Short retry count for fallback rate */ -#define RETRY_LONG_FB 2 /* Long retry count for fallback rate */ +#define RETRY_SHORT_FB 3 /* Short count for fallback rate */ +#define RETRY_LONG_FB 2 /* Long count for fallback rate */ #define MAXTXPKTS 6 /* max # pkts pending */ /* frameburst */ -#define MAXTXFRAMEBURST 8 /* vanilla xpress mode: max frames/burst */ +#define MAXTXFRAMEBURST 8 /* vanilla xpress mode: max frames/burst */ #define MAXFRAMEBURST_TXOP 10000 /* Frameburst TXOP in usec */ /* Per-AC retry limit register definitions; uses defs.h bitfield macros */ @@ -228,11 +229,12 @@ extern const u8 prio2fifo[]; /* * Detect Card removed. - * Even checking an sbconfig register read will not false trigger when the core is in reset. - * it breaks CF address mechanism. Accessing gphy phyversion will cause SB error if aphy - * is in reset on 4306B0-DB. Need a simple accessible reg with fixed 0/1 pattern - * (some platforms return all 0). - * If clocks are present, call the sb routine which will figure out if the device is removed. + * Even checking an sbconfig register read will not false trigger when the core + * is in reset it breaks CF address mechanism. Accessing gphy phyversion will + * cause SB error if aphy is in reset on 4306B0-DB. Need a simple accessible + * reg with fixed 0/1 pattern (some platforms return all 0). + * If clocks are present, call the sb routine which will figure out if the + * device is removed. */ #define DEVICEREMOVED(wlc) \ ((wlc->hw->clk) ? \ @@ -242,52 +244,87 @@ extern const u8 prio2fifo[]; #define BRCMS_UNIT(wlc) ((wlc)->pub->unit) +#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) + +/* + * 802.11 protection information + * + * _g: use g spec protection, driver internal. + * g_override: override for use of g spec protection. + * gmode_user: user config gmode, operating band->gmode is different. + * overlap: Overlap BSS/IBSS protection for both 11g and 11n. + * nmode_user: user config nmode, operating pub->nmode is different. + * n_cfg: use OFDM protection on MIMO frames. + * n_cfg_override: override for use of N protection. + * nongf: non-GF present protection. + * nongf_override: override for use of GF protection. + * n_pam_override: override for preamble: MM or GF. + * n_obss: indicated OBSS Non-HT STA present. +*/ struct brcms_protection { - bool _g; /* use g spec protection, driver internal */ - s8 g_override; /* override for use of g spec protection */ - u8 gmode_user; /* user config gmode, operating band->gmode is different */ - s8 overlap; /* Overlap BSS/IBSS protection for both 11g and 11n */ - s8 nmode_user; /* user config nmode, operating pub->nmode is different */ - s8 n_cfg; /* use OFDM protection on MIMO frames */ - s8 n_cfg_override; /* override for use of N protection */ - bool nongf; /* non-GF present protection */ - s8 nongf_override; /* override for use of GF protection */ - s8 n_pam_override; /* override for preamble: MM or GF */ - bool n_obss; /* indicated OBSS Non-HT STA present */ + bool _g; + s8 g_override; + u8 gmode_user; + s8 overlap; + s8 nmode_user; + s8 n_cfg; + s8 n_cfg_override; + bool nongf; + s8 nongf_override; + s8 n_pam_override; + bool n_obss; }; -/* anything affects the single/dual streams/antenna operation */ +/* + * anything affecting the single/dual streams/antenna operation + * + * hw_txchain: HW txchain bitmap cfg. + * txchain: txchain bitmap being used. + * txstreams: number of txchains being used. + * hw_rxchain: HW rxchain bitmap cfg. + * rxchain: rxchain bitmap being used. + * rxstreams: number of rxchains being used. + * ant_rx_ovr: rx antenna override. + * txant: userTx antenna setting. + * phytxant: phyTx antenna setting in txheader. + * ss_opmode: singlestream Operational mode, 0:siso; 1:cdd. + * ss_algosel_auto: if true, use wlc->stf->ss_algo_channel; + * else use wlc->band->stf->ss_mode_band. + * ss_algo_channel: ss based on per-channel algo: 0: SISO, 1: CDD 2: STBC. + * no_cddstbc: stf override, 1: no CDD (or STBC) allowed. + * rxchain_restore_delay: delay time to restore default rxchain. + * ldpc: AUTO/ON/OFF ldpc cap supported. + * txcore[MAX_STREAMS_SUPPORTED + 1]: bitmap of selected core for each Nsts. + * spatial_policy: + */ struct brcms_stf { - u8 hw_txchain; /* HW txchain bitmap cfg */ - u8 txchain; /* txchain bitmap being used */ - u8 txstreams; /* number of txchains being used */ - - u8 hw_rxchain; /* HW rxchain bitmap cfg */ - u8 rxchain; /* rxchain bitmap being used */ - u8 rxstreams; /* number of rxchains being used */ - - u8 ant_rx_ovr; /* rx antenna override */ - s8 txant; /* userTx antenna setting */ - u16 phytxant; /* phyTx antenna setting in txheader */ - - u8 ss_opmode; /* singlestream Operational mode, 0:siso; 1:cdd */ - bool ss_algosel_auto; /* if true, use wlc->stf->ss_algo_channel; */ - /* else use wlc->band->stf->ss_mode_band; */ - u16 ss_algo_channel; /* ss based on per-channel algo: 0: SISO, 1: CDD 2: STBC */ - u8 no_cddstbc; /* stf override, 1: no CDD (or STBC) allowed */ - - u8 rxchain_restore_delay; /* delay time to restore default rxchain */ - - s8 ldpc; /* AUTO/ON/OFF ldpc cap supported */ - u8 txcore[MAX_STREAMS_SUPPORTED + 1]; /* bitmap of selected core for each Nsts */ + u8 hw_txchain; + u8 txchain; + u8 txstreams; + u8 hw_rxchain; + u8 rxchain; + u8 rxstreams; + u8 ant_rx_ovr; + s8 txant; + u16 phytxant; + u8 ss_opmode; + bool ss_algosel_auto; + u16 ss_algo_channel; + u8 no_cddstbc; + u8 rxchain_restore_delay; + s8 ldpc; + u8 txcore[MAX_STREAMS_SUPPORTED + 1]; s8 spatial_policy; }; #define BRCMS_STF_SS_STBC_TX(wlc, scb) \ - (((wlc)->stf->txstreams > 1) && (((wlc)->band->band_stf_stbc_tx == ON) || \ - (SCB_STBC_CAP((scb)) && \ - (wlc)->band->band_stf_stbc_tx == AUTO && \ - isset(&((wlc)->stf->ss_algo_channel), PHY_TXC1_MODE_STBC)))) + (((wlc)->stf->txstreams > 1) && (((wlc)->band->band_stf_stbc_tx == ON) \ + || (SCB_STBC_CAP((scb)) && (wlc)->band->band_stf_stbc_tx == AUTO && \ + isset(&((wlc)->stf->ss_algo_channel), PHY_TXC1_MODE_STBC)))) #define BRCMS_STBC_CAP_PHY(wlc) (BRCMS_ISNPHY(wlc->band) && \ NREV_GE(wlc->band->phyrev, 3)) @@ -306,9 +343,12 @@ struct brcms_stf { #define BRCMS_BSS_HT 0x0020 /* BSS is HT (MIMO) capable */ /* Flags used in brcms_c_txq_info.stopped */ -#define TXQ_STOP_FOR_PRIOFC_MASK 0x000000FF /* per prio flow control bits */ -#define TXQ_STOP_FOR_PKT_DRAIN 0x00000100 /* stop txq enqueue for packet drain */ -#define TXQ_STOP_FOR_AMPDU_FLOW_CNTRL 0x00000200 /* stop txq enqueue for ampdu flow control */ +/* per prio flow control bits */ +#define TXQ_STOP_FOR_PRIOFC_MASK 0x000000FF +/* stop txq enqueue for packet drain */ +#define TXQ_STOP_FOR_PKT_DRAIN 0x00000100 +/* stop txq enqueue for ampdu flow control */ +#define TXQ_STOP_FOR_AMPDU_FLOW_CNTRL 0x00000200 #define BRCMS_HT_WEP_RESTRICT 0x01 /* restrict HT with WEP */ #define BRCMS_HT_TKIP_RESTRICT 0x02 /* restrict HT with TKIP */ @@ -316,8 +356,8 @@ struct brcms_stf { /* Maximum # of keys that wl driver supports in S/W. * Keys supported in H/W is less than or equal to WSEC_MAX_KEYS. */ -#define WSEC_MAX_KEYS 54 /* Max # of keys (50 + 4 default keys) */ -#define BRCMS_DEFAULT_KEYS 4 /* Default # of keys */ +#define WSEC_MAX_KEYS 54 /* Max # of keys (50 + 4 default keys) */ +#define BRCMS_DEFAULT_KEYS 4 /* Default # of keys */ /* * Max # of keys currently supported: @@ -341,14 +381,14 @@ struct wsec_key { u8 ea[ETH_ALEN]; /* per station */ u8 idx; /* key index in wsec_keys array */ u8 id; /* key ID [0-3] */ - u8 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */ - u8 rcmta; /* rcmta entry index, same as idx by default */ - u16 flags; /* misc flags */ - u8 algo_hw; /* cache for hw register */ - u8 aes_mode; /* cache for hw register */ - s8 iv_len; /* IV length */ - s8 icv_len; /* ICV length */ - u32 len; /* key length..don't move this var */ + u8 algo; /* CRYPTO_ALGO_AES_CCM, CRYPTO_ALGO_WEP128, etc */ + u8 rcmta; /* rcmta entry index, same as idx by default */ + u16 flags; /* misc flags */ + u8 algo_hw; /* cache for hw register */ + u8 aes_mode; /* cache for hw register */ + s8 iv_len; /* IV length */ + s8 icv_len; /* ICV length */ + u32 len; /* key length..don't move this var */ /* data is 4byte aligned */ u8 data[WLAN_MAX_KEY_LEN]; /* key data */ struct wsec_iv rxiv[BRCMS_NUMRXIVS]; /* Rx IV (one per TID) */ @@ -386,27 +426,29 @@ struct brcms_band { struct scb *hwrs_scb; /* permanent scb for hw rateset */ - wlc_rateset_t defrateset; /* band-specific copy of default_bss.rateset */ + /* band-specific copy of default_bss.rateset */ + struct brcms_c_rateset defrateset; - ratespec_t rspec_override; /* 802.11 rate override */ - ratespec_t mrspec_override; /* multicast rate override */ + u32 rspec_override; /* 802.11 rate override */ + u32 mrspec_override; /* multicast rate override */ u8 band_stf_ss_mode; /* Configured STF type, 0:siso; 1:cdd */ s8 band_stf_stbc_tx; /* STBC TX 0:off; 1:force on; -1:auto */ - wlc_rateset_t hw_rateset; /* rates supported by chip (phy-specific) */ + /* rates supported by chip (phy-specific) */ + struct brcms_c_rateset hw_rateset; u8 basic_rate[BRCM_MAXRATE + 1]; /* basic rates indexed by rate */ bool mimo_cap_40; /* 40 MHz cap enabled on this band */ s8 antgain; /* antenna gain from srom */ - u16 CWmin; /* The minimum size of contention window, in unit of aSlotTime */ - u16 CWmax; /* The maximum size of contention window, in unit of aSlotTime */ + u16 CWmin; /* minimum size of contention window, in unit of aSlotTime */ + u16 CWmax; /* maximum size of contention window, in unit of aSlotTime */ u16 bcntsfoff; /* beacon tsf offset */ }; -/* tx completion callback takes 3 args */ -typedef void (*pkcb_fn_t) (struct brcms_c_info *wlc, uint txstatus, void *arg); - struct pkt_cb { - pkcb_fn_t fn; /* function to call when tx frame completes */ + /* function to call when tx frame completes */ + /* tx completion callback takes 3 args */ + void (*fn)(struct brcms_c_info *wlc, uint txstatus, void *arg); + void *arg; /* void arg for fn */ u8 nextidx; /* index of next call back if threading */ bool entered; /* recursion check */ @@ -414,24 +456,39 @@ struct pkt_cb { /* module control blocks */ struct modulecb { - char name[32]; /* module name : NULL indicates empty array member */ - const struct brcmu_iovar *iovars; /* iovar table */ - void *hdl; /* handle passed when handler 'doiovar' is called */ - watchdog_fn_t watchdog_fn; /* watchdog handler */ - iovar_fn_t iovar_fn; /* iovar handler */ - down_fn_t down_fn; /* down handler. Note: the int returned - * by the down function is a count of the - * number of timers that could not be - * freed. - */ -}; + /* module name : NULL indicates empty array member */ + char name[32]; + /* iovar table */ + const struct brcmu_iovar *iovars; + /* handle passed when handler 'doiovar' is called */ + struct brcms_info *hdl; + + /* IOVar handler + * + * handle - a pointer value registered with the function + * vi - iovar_info that was looked up + * actionid - action ID, calculated by IOV_GVAL() and IOV_SVAL() + * based on varid. + * name - the actual iovar name + * params/plen - parameters and length for a get, input only. + * arg/len - buffer and length for value to be set or retrieved, + * input or output. + * vsize - value size, valid for integer type only. + * wlcif - interface context (brcms_c_if pointer) + * + * All pointers may point into the same buffer. + */ + int (*iovar_fn)(void *handle, const struct brcmu_iovar *vi, + u32 actionid, const char *name, void *params, + uint plen, void *arg, int alen, int vsize, + struct brcms_c_if *wlcif); + + int (*down_fn)(void *handle); /* down handler. Note: the int returned + * by the down function is a count of the + * number of timers that could not be + * freed. + */ -/* dump control blocks */ -struct dumpcb_s { - const char *name; /* dump name */ - dump_fn_t dump_fn; /* 'wl dump' handler */ - void *dump_fn_arg; - struct dumpcb_s *next; }; struct edcf_acparam { @@ -453,11 +510,11 @@ struct wme_param_ie { /* virtual interface */ struct brcms_c_if { struct brcms_c_if *next; - u8 type; /* BSS or WDS */ - u8 index; /* assigned in wl_add_if(), index of the wlif if any, - * not necessarily corresponding to bsscfg._idx or - * AID2PVBMAP(scb). - */ + u8 type; /* BSS or WDS */ + u8 index; /* assigned in wl_add_if(), index of the wlif if any, + * not necessarily corresponding to bsscfg._idx or + * AID2PVBMAP(scb). + */ u8 flags; /* flags for the interface */ struct brcms_if *wlif; /* pointer to wlif */ struct brcms_txq_info *qi; /* pointer to associated tx queue */ @@ -513,9 +570,9 @@ struct brcms_hardware { struct si_pub *sih; /* SI handle (cookie for siutils calls) */ char *vars; /* "environment" name=value */ uint vars_size; /* size of vars, free vars on detach */ - d11regs_t *regs; /* pointer to device registers */ - void *physhim; /* phy shim layer handler */ - void *phy_sh; /* pointer to shared phy state */ + struct d11regs *regs; /* pointer to device registers */ + struct phy_shim_info *physhim; /* phy shim layer handler */ + struct shared_phy *phy_sh; /* pointer to shared phy state */ struct brcms_hw_band *band;/* pointer to active per-band state */ /* band state per phy/radio */ struct brcms_hw_band *bandstate[MAXBANDS]; @@ -529,22 +586,22 @@ struct brcms_hardware { bool up; /* d11 hardware up and running */ uint now; /* # elapsed seconds */ uint _nbands; /* # bands supported */ - chanspec_t chanspec; /* bmac chanspec shadow */ + u16 chanspec; /* bmac chanspec shadow */ uint *txavail[NFIFO]; /* # tx descriptors available */ u16 *xmtfifo_sz; /* fifo size in 256B for each xmt fifo */ - mbool pllreq; /* pll requests to keep PLL on */ + u32 pllreq; /* pll requests to keep PLL on */ u8 suspended_fifos; /* Which TX fifo to remain awake for */ u32 maccontrol; /* Cached value of maccontrol */ uint mac_suspend_depth; /* current depth of mac_suspend levels */ - u32 wake_override; /* Various conditions to force MAC to WAKE mode */ + u32 wake_override; /* bit flags to force MAC to WAKE mode */ u32 mute_override; /* Prevent ucode from sending beacons */ u8 etheraddr[ETH_ALEN]; /* currently configured ethernet address */ u32 led_gpio_mask; /* LED GPIO Mask */ bool noreset; /* true= do not reset hw, used by WLC_OUT */ - bool forcefastclk; /* true if the h/w is forcing the use of fast clk */ + bool forcefastclk; /* true if h/w is forcing to use fast clk */ bool clk; /* core is out of reset and has clock */ bool sbclk; /* sb has clock */ struct bmac_pmq *bmac_pmq; /* bmac PM states derived from ucode PMQ */ @@ -578,194 +635,267 @@ struct brcms_txq_info { }; /* - * Principal common (os-independent) software data structure. + * Principal common driver data structure. + * + * pub: pointer to driver public state. + * wl: pointer to specific private state. + * regs: pointer to device registers. + * hw: HW related state. + * clkreq_override: setting for clkreq for PCIE : Auto, 0, 1. + * fastpwrup_dly: time in us needed to bring up d11 fast clock. + * macintstatus: bit channel between isr and dpc. + * macintmask: sw runtime master macintmask value. + * defmacintmask: default "on" macintmask value. + * device_present: (removable) device is present. + * clk: core is out of reset and has clock. + * core: pointer to active io core. + * band: pointer to active per-band state. + * corestate: per-core state (one per hw core). + * bandstate: per-band state (one per phy/radio). + * war16165: PCI slow clock 16165 war flag. + * tx_suspended: data fifos need to remain suspended. + * txpend16165war: PCI slow clock 16165 war flag. + * qvalid: DirFrmQValid and BcMcFrmQValid. + * txpwr_local_max: regulatory local txpwr max. + * txpwr_local_constraint: local power contraint in dB. + * ampdu: ampdu module handler. + * asi: antsel module handler. + * cmi: channel manager module handler. + * vars_size: size of vars, free vars on detach. + * vendorid: PCI vendor id. + * deviceid: PCI device id. + * ucode_rev: microcode revision. + * machwcap: MAC capabilities, BMAC shadow. + * perm_etheraddr: original sprom local ethernet address. + * bandlocked: disable auto multi-band switching. + * bandinit_pending: track band init in auto band. + * radio_monitor: radio timer is running. + * going_down: down path intermediate variable. + * mpc: enable minimum power consumption. + * mpc_dlycnt: # of watchdog cnt before turn disable radio. + * mpc_offcnt: # of watchdog cnt that radio is disabled. + * mpc_delay_off: delay radio disable by # of watchdog cnt. + * prev_non_delay_mpc: prev state brcms_c_is_non_delay_mpc. + * wdtimer: timer for watchdog routine. + * radio_timer: timer for hw radio button monitor routine. + * monitor: monitor (MPDU sniffing) mode. + * bcnmisc_ibss: bcns promisc mode override for IBSS. + * bcnmisc_scan: bcns promisc mode override for scan. + * bcnmisc_monitor: bcns promisc mode override for monitor. + * _rifs: enable per-packet rifs. + * sgi_tx: sgi tx. + * bcn_li_bcn: beacon listen interval in # beacons. + * bcn_li_dtim: beacon listen interval in # dtims. + * WDarmed: watchdog timer is armed. + * WDlast: last time wlc_watchdog() was called. + * wme_dp: AC bitmap. Discard (oldest first) policy per AC. + * edcf_txop[AC_COUNT]: current txop for each ac. + * wme_param_ie: on STA contains parameters in use locally, and on AP + * contains parameters advertised + * wme_retries: per-AC retry limits. + * tx_prec_map: Precedence map based on HW FIFO space. + * fifo2prec_map[NFIFO]: pointer to fifo2_prec map based on WME. + * bsscfg: set of BSS configurations, idx 0 is default and always valid. + * cfg: the primary bsscfg (can be AP or STA). + * tx_queues: common TX Queue list. + * wsec_keys[WSEC_MAX_KEYS]: dynamic key storage. + * wsec_def_keys[BRCMS_DEFAULT_KEYS]: default key storage. + * wsec_swkeys: indicates that all keys should be treated as + * sw keys (used for debugging). + * modulecb: + * mimoft: SIGN or 11N. + * cck_40txbw: 11N, cck tx b/w override when in 40MHZ mode. + * ofdm_40txbw: 11N, ofdm tx b/w override when in 40MHZ mode. + * mimo_40txbw: 11N, mimo tx b/w override when in 40MHZ mode. + * ht_cap: HT CAP IE being advertised by this node. + * default_bss: configured BSS parameters. + * mc_fid_counter: BC/MC FIFO frame ID counter. + * country_default: saved country for leaving 802.11d auto-country mode. + * autocountry_default: initial country for 802.11d auto-country mode. + * prb_resp_timeout: do not send prb resp if request older + * than this, 0 = disable. + * sup_rates_override: use only these rates in 11g supported rates if specified. + * home_chanspec: shared home chanspec. + * chanspec: target operational channel. + * usr_fragthresh: user configured fragmentation threshold. + * fragthresh[NFIFO]: per-fifo fragmentation thresholds. + * RTSThresh: 802.11 dot11RTSThreshold. + * SRL: 802.11 dot11ShortRetryLimit. + * LRL: 802.11 dot11LongRetryLimit. + * SFBL: Short Frame Rate Fallback Limit. + * LFBL: Long Frame Rate Fallback Limit. + * shortslot: currently using 11g ShortSlot timing. + * shortslot_override: 11g ShortSlot override. + * include_legacy_erp: include Legacy ERP info elt ID 47 as well as g ID 42. + * PLCPHdr_override: 802.11b Preamble Type override. + * stf: + * bcn_rspec: save bcn ratespec purpose. + * tempsense_lasttime; + * tx_duty_cycle_ofdm: maximum allowed duty cycle for OFDM. + * tx_duty_cycle_cck: maximum allowed duty cycle for CCK. + * next_bsscfg_ID; + * pkt_queue: txq for transmit packets. + * mpc_dur: total time (ms) in mpc mode except for the portion since + * radio is turned off last time. + * mpc_laston_ts: timestamp (ms) when radio is turned off last time. + * wiphy: */ struct brcms_c_info { - struct brcms_pub *pub; /* pointer to wlc public state */ - struct brcms_info *wl; /* pointer to os-specific private state */ - d11regs_t *regs; /* pointer to device registers */ - - /* HW related state used primarily by BMAC */ + struct brcms_pub *pub; + struct brcms_info *wl; + struct d11regs *regs; struct brcms_hardware *hw; /* clock */ - int clkreq_override; /* setting for clkreq for PCIE : Auto, 0, 1 */ - u16 fastpwrup_dly; /* time in us needed to bring up d11 fast clock */ + int clkreq_override; + u16 fastpwrup_dly; /* interrupt */ - u32 macintstatus; /* bit channel between isr and dpc */ - u32 macintmask; /* sw runtime master macintmask value */ - u32 defmacintmask; /* default "on" macintmask value */ + u32 macintstatus; + u32 macintmask; + u32 defmacintmask; /* up and down */ - bool device_present; /* (removable) device is present */ + bool device_present; - bool clk; /* core is out of reset and has clock */ + bool clk; /* multiband */ - struct brcms_core *core; /* pointer to active io core */ - struct brcms_band *band; /* pointer to active per-band state */ - struct brcms_core *corestate; /* per-core state (one per hw core) */ - /* per-band state (one per phy/radio): */ + struct brcms_core *core; + struct brcms_band *band; + struct brcms_core *corestate; struct brcms_band *bandstate[MAXBANDS]; - bool war16165; /* PCI slow clock 16165 war flag */ + bool war16165; - bool tx_suspended; /* data fifos need to remain suspended */ + bool tx_suspended; uint txpend16165war; /* packet queue */ - uint qvalid; /* DirFrmQValid and BcMcFrmQValid */ + uint qvalid; /* Regulatory power limits */ - s8 txpwr_local_max; /* regulatory local txpwr max */ - u8 txpwr_local_constraint; /* local power contraint in dB */ + s8 txpwr_local_max; + u8 txpwr_local_constraint; - struct ampdu_info *ampdu; /* ampdu module handler */ - struct antsel_info *asi; /* antsel module handler */ - struct brcms_cm_info *cmi; /* channel manager module handler */ + struct ampdu_info *ampdu; + struct antsel_info *asi; + struct brcms_cm_info *cmi; - uint vars_size; /* size of vars, free vars on detach */ + uint vars_size; - u16 vendorid; /* PCI vendor id */ - u16 deviceid; /* PCI device id */ - uint ucode_rev; /* microcode revision */ + u16 vendorid; + u16 deviceid; + uint ucode_rev; - u32 machwcap; /* MAC capabilities, BMAC shadow */ + u32 machwcap; - u8 perm_etheraddr[ETH_ALEN]; /* original sprom local ethernet address */ + u8 perm_etheraddr[ETH_ALEN]; - bool bandlocked; /* disable auto multi-band switching */ - bool bandinit_pending; /* track band init in auto band */ + bool bandlocked; + bool bandinit_pending; - bool radio_monitor; /* radio timer is running */ - bool going_down; /* down path intermediate variable */ + bool radio_monitor; + bool going_down; - bool mpc; /* enable minimum power consumption */ - u8 mpc_dlycnt; /* # of watchdog cnt before turn disable radio */ - u8 mpc_offcnt; /* # of watchdog cnt that radio is disabled */ - u8 mpc_delay_off; /* delay radio disable by # of watchdog cnt */ - u8 prev_non_delay_mpc; /* prev state brcms_c_is_non_delay_mpc */ + bool mpc; + u8 mpc_dlycnt; + u8 mpc_offcnt; + u8 mpc_delay_off; + u8 prev_non_delay_mpc; - /* timer for watchdog routine */ struct brcms_timer *wdtimer; - /* timer for hw radio button monitor routine */ struct brcms_timer *radio_timer; /* promiscuous */ - bool monitor; /* monitor (MPDU sniffing) mode */ - bool bcnmisc_ibss; /* bcns promisc mode override for IBSS */ - bool bcnmisc_scan; /* bcns promisc mode override for scan */ - bool bcnmisc_monitor; /* bcns promisc mode override for monitor */ + bool monitor; + bool bcnmisc_ibss; + bool bcnmisc_scan; + bool bcnmisc_monitor; /* driver feature */ - bool _rifs; /* enable per-packet rifs */ - s8 sgi_tx; /* sgi tx */ + bool _rifs; + s8 sgi_tx; /* AP-STA synchronization, power save */ - u8 bcn_li_bcn; /* beacon listen interval in # beacons */ - u8 bcn_li_dtim; /* beacon listen interval in # dtims */ + u8 bcn_li_bcn; + u8 bcn_li_dtim; - bool WDarmed; /* watchdog timer is armed */ - u32 WDlast; /* last time wlc_watchdog() was called */ + bool WDarmed; + u32 WDlast; /* WME */ - ac_bitmap_t wme_dp; /* Discard (oldest first) policy per AC */ - u16 edcf_txop[AC_COUNT]; /* current txop for each ac */ + u8 wme_dp; + u16 edcf_txop[AC_COUNT]; - /* - * WME parameter info element, which on STA contains parameters in use - * locally, and on AP contains parameters advertised to STA in beacons - * and assoc responses. - */ struct wme_param_ie wme_param_ie; - u16 wme_retries[AC_COUNT]; /* per-AC retry limits */ + u16 wme_retries[AC_COUNT]; + u16 tx_prec_map; + u16 fifo2prec_map[NFIFO]; - u16 tx_prec_map; /* Precedence map based on HW FIFO space */ - u16 fifo2prec_map[NFIFO]; /* pointer to fifo2_prec map based on WME */ - - /* - * BSS Configurations set of BSS configurations, idx 0 is default and - * always valid - */ struct brcms_bss_cfg *bsscfg[BRCMS_MAXBSSCFG]; - struct brcms_bss_cfg *cfg; /* the primary bsscfg (can be AP or STA) */ + struct brcms_bss_cfg *cfg; /* tx queue */ - struct brcms_txq_info *tx_queues; /* common TX Queue list */ + struct brcms_txq_info *tx_queues; /* security */ - struct wsec_key *wsec_keys[WSEC_MAX_KEYS]; /* dynamic key storage */ - /* default key storage */ + struct wsec_key *wsec_keys[WSEC_MAX_KEYS]; struct wsec_key *wsec_def_keys[BRCMS_DEFAULT_KEYS]; - bool wsec_swkeys; /* indicates that all keys should be - * treated as sw keys (used for debugging) - */ + bool wsec_swkeys; struct modulecb *modulecb; - u8 mimoft; /* SIGN or 11N */ - s8 cck_40txbw; /* 11N, cck tx b/w override when in 40MHZ mode */ - s8 ofdm_40txbw; /* 11N, ofdm tx b/w override when in 40MHZ mode */ - s8 mimo_40txbw; /* 11N, mimo tx b/w override when in 40MHZ mode */ - /* HT CAP IE being advertised by this node: */ + u8 mimoft; + s8 cck_40txbw; + s8 ofdm_40txbw; + s8 mimo_40txbw; struct ieee80211_ht_cap ht_cap; - struct brcms_bss_info *default_bss; /* configured BSS parameters */ + struct brcms_bss_info *default_bss; - u16 mc_fid_counter; /* BC/MC FIFO frame ID counter */ + u16 mc_fid_counter; - /* saved country for leaving 802.11d auto-country mode */ char country_default[BRCM_CNTRY_BUF_SZ]; - /* initial country for 802.11d auto-country mode */ char autocountry_default[BRCM_CNTRY_BUF_SZ]; - u16 prb_resp_timeout; /* do not send prb resp if request older than this, - * 0 = disable - */ - - wlc_rateset_t sup_rates_override; /* use only these rates in 11g supported rates if - * specifed - */ + u16 prb_resp_timeout; + struct brcms_c_rateset sup_rates_override; - chanspec_t home_chanspec; /* shared home chanspec */ + u16 home_chanspec; /* PHY parameters */ - chanspec_t chanspec; /* target operational channel */ - u16 usr_fragthresh; /* user configured fragmentation threshold */ - u16 fragthresh[NFIFO]; /* per-fifo fragmentation thresholds */ - u16 RTSThresh; /* 802.11 dot11RTSThreshold */ - u16 SRL; /* 802.11 dot11ShortRetryLimit */ - u16 LRL; /* 802.11 dot11LongRetryLimit */ - u16 SFBL; /* Short Frame Rate Fallback Limit */ - u16 LFBL; /* Long Frame Rate Fallback Limit */ + u16 chanspec; + u16 usr_fragthresh; + u16 fragthresh[NFIFO]; + u16 RTSThresh; + u16 SRL; + u16 LRL; + u16 SFBL; + u16 LFBL; /* network config */ - bool shortslot; /* currently using 11g ShortSlot timing */ - s8 shortslot_override; /* 11g ShortSlot override */ - bool include_legacy_erp; /* include Legacy ERP info elt ID 47 as well as g ID 42 */ + bool shortslot; + s8 shortslot_override; + bool include_legacy_erp; struct brcms_protection *protection; - s8 PLCPHdr_override; /* 802.11b Preamble Type override */ + s8 PLCPHdr_override; struct brcms_stf *stf; - ratespec_t bcn_rspec; /* save bcn ratespec purpose */ + u32 bcn_rspec; uint tempsense_lasttime; - u16 tx_duty_cycle_ofdm; /* maximum allowed duty cycle for OFDM */ - u16 tx_duty_cycle_cck; /* maximum allowed duty cycle for CCK */ + u16 tx_duty_cycle_ofdm; + u16 tx_duty_cycle_cck; u16 next_bsscfg_ID; - struct brcms_txq_info *pkt_queue; /* txq for transmit packets */ - u32 mpc_dur; /* total time (ms) in mpc mode except for the - * portion since radio is turned off last time - */ - u32 mpc_laston_ts; /* timestamp (ms) when radio is turned off last - * time - */ + struct brcms_txq_info *pkt_queue; + u32 mpc_dur; + u32 mpc_laston_ts; struct wiphy *wiphy; }; @@ -782,88 +912,136 @@ struct antsel_info { struct brcms_antselcfg antcfg_cur; /* current antenna config (auto) */ }; -/* BSS configuration state */ +/* + * BSS configuration state + * + * wlc: wlc to which this bsscfg belongs to. + * up: is this configuration up operational + * enable: is this configuration enabled + * associated: is BSS in ASSOCIATED state + * BSS: infraustructure or adhoc + * dtim_programmed: + * SSID_len: the length of SSID + * SSID: SSID string + * bcmc_scb: one bcmc_scb per band + * _idx: the index of this bsscfg, assigned at wlc_bsscfg_alloc() + * + * MAC filter + * ---------- + * nmac: # of entries on maclist array + * macmode: allow/deny stations on maclist array + * maclist: list of source MAC addrs to match + + * security + * -------- + * wsec: wireless security bitvec + * auth: 802.11 authentication: Open, Shared Key, WPA + * openshared: try Open auth first, then Shared Key + * wsec_restrict: drop unencrypted packets if wsec is enabled + * eap_restrict: restrict data until 802.1X auth succeeds + * WPA_auth: WPA authenticated key management + * wpa2_preauth: default is true, wpa_cap sets value + * wsec_portopen: indicates keys are plumbed + * wpa_none_txiv: global txiv for WPA_NONE, tkip and aes + * wsec_index: 0-3: default tx key, -1: not set + * bss_def_keys: default key storage + * + * TKIP countermeasures + * -------------------- + * tkip_countermeasures: flags TKIP no-assoc period + * tk_cm_dt: detect timer + * tk_cm_bt: blocking timer + * tk_cm_bt_tmstmp: Timestamp when TKIP BT is activated + * tk_cm_activate: activate countermeasures after EAPOL-Key sent + * + * BSSID: BSSID (associated) + * cur_etheraddr: h/w address + * bcmc_fid: the last BCMC FID queued to TX_BCMC_FIFO + * bcmc_fid_shm: the last BCMC FID written to shared mem + * flags: BSSCFG flags; see below + * bcn: AP beacon + * bcn_len: AP beacon length + * ar_disassoc: disassociated in associated recreation + * auth_atmptd: auth type (open/shared) attempted + * + * pmkid_cand: PMKID candidate list + * npmkid_cand: num PMKID candidates + * pmkid: PMKID cache + * npmkid: num cached PMKIDs + * current_bss: BSS parms in ASSOCIATED state + * + * PM states + * --------- + * PMawakebcn: bcn recvd during current waking state + * PMpending: waiting for tx status with PM indicated set + * priorPMstate: Detecting PM state transitions + * PSpoll: flags there is an outstanding PS-Poll frame + * + * rcmta: BSSID entry in RCMTA, use the wsec key to manage the RCMTA entries. + * + * ID: 'unique' ID of this bsscfg, assigned at bsscfg allocation + * + * txrspecidx: index into tx rate circular buffer + * txrspec: circular buffer of prev MPDUs tx rates + */ struct brcms_bss_cfg { - struct brcms_c_info *wlc; /* wlc to which this bsscfg belongs to. */ - bool up; /* is this configuration up operational */ - bool enable; /* is this configuration enabled */ - bool associated; /* is BSS in ASSOCIATED state */ - bool BSS; /* infraustructure or adhac */ + struct brcms_c_info *wlc; + bool up; + bool enable; + bool associated; + bool BSS; bool dtim_programmed; - - u8 SSID_len; /* the length of SSID */ - u8 SSID[IEEE80211_MAX_SSID_LEN]; /* SSID string */ - struct scb *bcmc_scb[MAXBANDS]; /* one bcmc_scb per band */ - s8 _idx; /* the index of this bsscfg, - * assigned at wlc_bsscfg_alloc() - */ - /* MAC filter */ - uint nmac; /* # of entries on maclist array */ - int macmode; /* allow/deny stations on maclist array */ - struct ether_addr *maclist; /* list of source MAC addrs to match */ - - /* security */ - u32 wsec; /* wireless security bitvec */ - s16 auth; /* 802.11 authentication: Open, Shared Key, WPA */ - s16 openshared; /* try Open auth first, then Shared Key */ - bool wsec_restrict; /* drop unencrypted packets if wsec is enabled */ - bool eap_restrict; /* restrict data until 802.1X auth succeeds */ - u16 WPA_auth; /* WPA: authenticated key management */ - bool wpa2_preauth; /* default is true, wpa_cap sets value */ - bool wsec_portopen; /* indicates keys are plumbed */ - /* global txiv for WPA_NONE, tkip and aes */ + u8 SSID_len; + u8 SSID[IEEE80211_MAX_SSID_LEN]; + struct scb *bcmc_scb[MAXBANDS]; + s8 _idx; + uint nmac; + int macmode; + struct ether_addr *maclist; + u32 wsec; + s16 auth; + s16 openshared; + bool wsec_restrict; + bool eap_restrict; + u16 WPA_auth; + bool wpa2_preauth; + bool wsec_portopen; struct wsec_iv wpa_none_txiv; - int wsec_index; /* 0-3: default tx key, -1: not set */ - /* default key storage: */ + int wsec_index; struct wsec_key *bss_def_keys[BRCMS_DEFAULT_KEYS]; - - /* TKIP countermeasures */ - bool tkip_countermeasures; /* flags TKIP no-assoc period */ - u32 tk_cm_dt; /* detect timer */ - u32 tk_cm_bt; /* blocking timer */ - u32 tk_cm_bt_tmstmp; /* Timestamp when TKIP BT is activated */ - bool tk_cm_activate; /* activate countermeasures after EAPOL-Key sent */ - - u8 BSSID[ETH_ALEN]; /* BSSID (associated) */ - u8 cur_etheraddr[ETH_ALEN]; /* h/w address */ - u16 bcmc_fid; /* the last BCMC FID queued to TX_BCMC_FIFO */ - u16 bcmc_fid_shm; /* the last BCMC FID written to shared mem */ - - u32 flags; /* BSSCFG flags; see below */ - - u8 *bcn; /* AP beacon */ - uint bcn_len; /* AP beacon length */ - bool ar_disassoc; /* disassociated in associated recreation */ - - int auth_atmptd; /* auth type (open/shared) attempted */ - - pmkid_cand_t pmkid_cand[MAXPMKID]; /* PMKID candidate list */ - uint npmkid_cand; /* num PMKID candidates */ - pmkid_t pmkid[MAXPMKID]; /* PMKID cache */ - uint npmkid; /* num cached PMKIDs */ - - struct brcms_bss_info *current_bss; /* BSS parms in ASSOCIATED state */ - - /* PM states */ - bool PMawakebcn; /* bcn recvd during current waking state */ - bool PMpending; /* waiting for tx status with PM indicated set */ - bool priorPMstate; /* Detecting PM state transitions */ - bool PSpoll; /* whether there is an outstanding PS-Poll frame */ - - /* BSSID entry in RCMTA, use the wsec key management infrastructure to - * manage the RCMTA entries. - */ + bool tkip_countermeasures; + u32 tk_cm_dt; + u32 tk_cm_bt; + u32 tk_cm_bt_tmstmp; + bool tk_cm_activate; + u8 BSSID[ETH_ALEN]; + u8 cur_etheraddr[ETH_ALEN]; + u16 bcmc_fid; + u16 bcmc_fid_shm; + u32 flags; + u8 *bcn; + uint bcn_len; + bool ar_disassoc; + int auth_atmptd; + struct pmkid_cand pmkid_cand[MAXPMKID]; + uint npmkid_cand; + struct pmkid pmkid[MAXPMKID]; + uint npmkid; + struct brcms_bss_info *current_bss; + bool PMawakebcn; + bool PMpending; + bool priorPMstate; + bool PSpoll; struct wsec_key *rcmta; - - /* 'unique' ID of this bsscfg, assigned at bsscfg allocation */ u16 ID; - - uint txrspecidx; /* index into tx rate circular buffer */ - ratespec_t txrspec[NTXRATE][2]; /* circular buffer of prev MPDUs tx rates */ + uint txrspecidx; + u32 txrspec[NTXRATE][2]; }; -#define CHANNEL_BANDUNIT(wlc, ch) (((ch) <= CH_MAX_2G_CHANNEL) ? BAND_2G_INDEX : BAND_5G_INDEX) -#define OTHERBANDUNIT(wlc) ((uint)((wlc)->band->bandunit ? BAND_2G_INDEX : BAND_5G_INDEX)) +#define CHANNEL_BANDUNIT(wlc, ch) \ + (((ch) <= CH_MAX_2G_CHANNEL) ? BAND_2G_INDEX : BAND_5G_INDEX) +#define OTHERBANDUNIT(wlc) \ + ((uint)((wlc)->band->bandunit ? BAND_2G_INDEX : BAND_5G_INDEX)) #define IS_MBAND_UNLOCKED(wlc) \ ((NBANDS(wlc) > 1) && !(wlc)->bandlocked) @@ -871,14 +1049,15 @@ struct brcms_bss_cfg { #define BRCMS_BAND_PI_RADIO_CHANSPEC wlc_phy_chanspec_get(wlc->band->pi) /* sum the individual fifo tx pending packet counts */ -#define TXPKTPENDTOT(wlc) ((wlc)->core->txpktpend[0] + (wlc)->core->txpktpend[1] + \ - (wlc)->core->txpktpend[2] + (wlc)->core->txpktpend[3]) -#define TXPKTPENDGET(wlc, fifo) ((wlc)->core->txpktpend[(fifo)]) -#define TXPKTPENDINC(wlc, fifo, val) ((wlc)->core->txpktpend[(fifo)] += (val)) -#define TXPKTPENDDEC(wlc, fifo, val) ((wlc)->core->txpktpend[(fifo)] -= (val)) -#define TXPKTPENDCLR(wlc, fifo) ((wlc)->core->txpktpend[(fifo)] = 0) -#define TXAVAIL(wlc, fifo) (*(wlc)->core->txavail[(fifo)]) -#define GETNEXTTXP(wlc, _queue) \ +#define TXPKTPENDTOT(wlc) \ + ((wlc)->core->txpktpend[0] + (wlc)->core->txpktpend[1] + \ + (wlc)->core->txpktpend[2] + (wlc)->core->txpktpend[3]) +#define TXPKTPENDGET(wlc, fifo) ((wlc)->core->txpktpend[(fifo)]) +#define TXPKTPENDINC(wlc, fifo, val) ((wlc)->core->txpktpend[(fifo)] += (val)) +#define TXPKTPENDDEC(wlc, fifo, val) ((wlc)->core->txpktpend[(fifo)] -= (val)) +#define TXPKTPENDCLR(wlc, fifo) ((wlc)->core->txpktpend[(fifo)] = 0) +#define TXAVAIL(wlc, fifo) (*(wlc)->core->txavail[(fifo)]) +#define GETNEXTTXP(wlc, _queue) \ dma_getnexttxp((wlc)->hw->di[(_queue)], DMA_RANGE_TRANSMITTED) #define BRCMS_IS_MATCH_SSID(wlc, ssid1, ssid2, len1, len2) \ @@ -894,17 +1073,15 @@ extern void brcms_c_txfifo(struct brcms_c_info *wlc, uint fifo, bool commit, s8 txpktpend); extern void brcms_c_txfifo_complete(struct brcms_c_info *wlc, uint fifo, s8 txpktpend); -extern void brcms_c_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu, - uint prec); +extern void brcms_c_txq_enq(struct brcms_c_info *wlc, struct scb *scb, + struct sk_buff *sdu, uint prec); extern void brcms_c_info_init(struct brcms_c_info *wlc, int unit); extern void brcms_c_print_txstatus(struct tx_status *txs); extern int brcms_c_xmtfifo_sz_get(struct brcms_c_info *wlc, uint fifo, uint *blocks); extern void brcms_c_write_template_ram(struct brcms_c_info *wlc, int offset, int len, void *buf); -extern void brcms_c_write_hw_bcntemplates(struct brcms_c_info *wlc, void *bcn, - int len, bool both); -extern void brcms_c_pllreq(struct brcms_c_info *wlc, bool set, mbool req_bit); +extern void brcms_c_pllreq(struct brcms_c_info *wlc, bool set, u32 req_bit); extern void brcms_c_reset_bmac_done(struct brcms_c_info *wlc); #if defined(BCMDBG) @@ -917,7 +1094,7 @@ extern void brcms_c_print_txdesc(struct d11txh *txh); extern void brcms_c_setxband(struct brcms_hardware *wlc_hw, uint bandunit); extern void brcms_c_coredisable(struct brcms_hardware *wlc_hw); -extern bool brcms_c_valid_rate(struct brcms_c_info *wlc, ratespec_t rate, +extern bool brcms_c_valid_rate(struct brcms_c_info *wlc, u32 rate, int band, bool verbose); extern void brcms_c_ap_upd(struct brcms_c_info *wlc); @@ -943,14 +1120,14 @@ extern void brcms_c_send_q(struct brcms_c_info *wlc); extern int brcms_c_prep_pdu(struct brcms_c_info *wlc, struct sk_buff *pdu, uint *fifo); -extern u16 brcms_c_calc_lsig_len(struct brcms_c_info *wlc, ratespec_t ratespec, +extern u16 brcms_c_calc_lsig_len(struct brcms_c_info *wlc, u32 ratespec, uint mac_len); -extern ratespec_t brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc, - ratespec_t rspec, +extern u32 brcms_c_rspec_to_rts_rspec(struct brcms_c_info *wlc, + u32 rspec, bool use_rspec, u16 mimo_ctlchbw); extern u16 brcms_c_compute_rtscts_dur(struct brcms_c_info *wlc, bool cts_only, - ratespec_t rts_rate, - ratespec_t frame_rate, + u32 rts_rate, + u32 frame_rate, u8 rts_preamble_type, u8 frame_preamble_type, uint frame_len, bool ba); @@ -980,19 +1157,17 @@ extern void brcms_c_bss_update_probe_resp(struct brcms_c_info *wlc, extern bool brcms_c_ismpc(struct brcms_c_info *wlc); extern bool brcms_c_is_non_delay_mpc(struct brcms_c_info *wlc); extern void brcms_c_radio_mpc_upd(struct brcms_c_info *wlc); -extern bool brcms_c_prec_enq(struct brcms_c_info *wlc, struct pktq *q, - void *pkt, int prec); extern bool brcms_c_prec_enq_head(struct brcms_c_info *wlc, struct pktq *q, struct sk_buff *pkt, int prec, bool head); -extern u16 brcms_c_phytxctl1_calc(struct brcms_c_info *wlc, ratespec_t rspec); -extern void brcms_c_compute_plcp(struct brcms_c_info *wlc, ratespec_t rate, +extern u16 brcms_c_phytxctl1_calc(struct brcms_c_info *wlc, u32 rspec); +extern void brcms_c_compute_plcp(struct brcms_c_info *wlc, u32 rate, uint length, u8 *plcp); extern uint brcms_c_calc_frame_time(struct brcms_c_info *wlc, - ratespec_t ratespec, + u32 ratespec, u8 preamble_type, uint mac_len); extern void brcms_c_set_chanspec(struct brcms_c_info *wlc, - chanspec_t chanspec); + u16 chanspec); extern bool brcms_c_timers_init(struct brcms_c_info *wlc, int unit); @@ -1008,18 +1183,61 @@ extern void brcms_c_edcf_setparams(struct brcms_c_info *wlc, bool suspend); extern void brcms_c_set_ratetable(struct brcms_c_info *wlc); extern int brcms_c_set_mac(struct brcms_bss_cfg *cfg); extern void brcms_c_beacon_phytxctl_txant_upd(struct brcms_c_info *wlc, - ratespec_t bcn_rate); + u32 bcn_rate); extern void brcms_c_mod_prb_rsp_rate_table(struct brcms_c_info *wlc, uint frame_len); -extern ratespec_t brcms_c_lowest_basic_rspec(struct brcms_c_info *wlc, - wlc_rateset_t *rs); +extern u32 brcms_c_lowest_basic_rspec(struct brcms_c_info *wlc, + struct brcms_c_rateset *rs); extern void brcms_c_radio_disable(struct brcms_c_info *wlc); extern void brcms_c_bcn_li_upd(struct brcms_c_info *wlc); extern void brcms_c_set_home_chanspec(struct brcms_c_info *wlc, - chanspec_t chanspec); + u16 chanspec); extern bool brcms_c_ps_allowed(struct brcms_c_info *wlc); extern bool brcms_c_stay_awake(struct brcms_c_info *wlc); extern void brcms_c_wme_initparams_sta(struct brcms_c_info *wlc, struct wme_param_ie *pe); +extern void brcms_b_antsel_type_set(struct brcms_hardware *wlc_hw, + u8 antsel_type); + +/* chanspec, ucode interface */ +extern void brcms_b_set_chanspec(struct brcms_hardware *wlc_hw, + u16 chanspec, + bool mute, struct txpwr_limits *txpwr); + +extern void brcms_b_write_shm(struct brcms_hardware *wlc_hw, uint offset, + u16 v); +extern u16 brcms_b_read_shm(struct brcms_hardware *wlc_hw, uint offset); + +extern void brcms_b_mhf(struct brcms_hardware *wlc_hw, u8 idx, u16 mask, + u16 val, int bands); + +extern void brcms_b_corereset(struct brcms_hardware *wlc_hw, u32 flags); + +extern void brcms_b_mctrl(struct brcms_hardware *wlc_hw, u32 mask, u32 val); + +extern void brcms_b_phy_reset(struct brcms_hardware *wlc_hw); +extern void brcms_b_bw_set(struct brcms_hardware *wlc_hw, u16 bw); +extern void brcms_b_core_phypll_reset(struct brcms_hardware *wlc_hw); +extern void brcms_c_ucode_wake_override_set(struct brcms_hardware *wlc_hw, + u32 override_bit); +extern void brcms_c_ucode_wake_override_clear(struct brcms_hardware *wlc_hw, + u32 override_bit); +extern void brcms_b_write_template_ram(struct brcms_hardware *wlc_hw, + int offset, int len, void *buf); +extern u16 brcms_b_rate_shm_offset(struct brcms_hardware *wlc_hw, u8 rate); +extern void brcms_b_copyto_objmem(struct brcms_hardware *wlc_hw, + uint offset, const void *buf, int len, + u32 sel); +extern void brcms_b_copyfrom_objmem(struct brcms_hardware *wlc_hw, uint offset, + void *buf, int len, u32 sel); +extern void brcms_b_switch_macfreq(struct brcms_hardware *wlc_hw, u8 spurmode); +extern u16 brcms_b_get_txant(struct brcms_hardware *wlc_hw); +extern void brcms_b_phyclk_fgc(struct brcms_hardware *wlc_hw, bool clk); +extern void brcms_b_macphyclk_set(struct brcms_hardware *wlc_hw, bool clk); +extern void brcms_b_core_phypll_ctl(struct brcms_hardware *wlc_hw, bool on); +extern void brcms_b_txant_set(struct brcms_hardware *wlc_hw, u16 phytxant); +extern void brcms_b_band_stf_ss_set(struct brcms_hardware *wlc_hw, + u8 stf_mode); + #endif /* _BRCM_MAIN_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/nicpci.c b/drivers/staging/brcm80211/brcmsmac/nicpci.c index 3d71c59..2d46e70 100644 --- a/drivers/staging/brcm80211/brcmsmac/nicpci.c +++ b/drivers/staging/brcm80211/brcmsmac/nicpci.c @@ -213,9 +213,7 @@ struct pcicore_info { /* debug/trace */ #define PCI_ERROR(args) -#define PCIE_PUB(sih) \ - (((sih)->bustype == PCI_BUS) && \ - ((sih)->buscoretype == PCIE_CORE_ID)) +#define PCIE_PUB(sih) ((sih)->buscoretype == PCIE_CORE_ID) /* routines to access mdio slave device registers */ static bool pcie_mdiosetblock(struct pcicore_info *pi, uint blk); @@ -247,7 +245,8 @@ static void pcie_war_pci_setup(struct pcicore_info *pi); /* Initialize the PCI core. * It's caller's responsibility to make sure that this is done only once */ -void *pcicore_init(struct si_pub *sih, void *pdev, void *regs) +struct pcicore_info *pcicore_init(struct si_pub *sih, struct pci_dev *pdev, + void *regs) { struct pcicore_info *pi; @@ -273,7 +272,7 @@ void *pcicore_init(struct si_pub *sih, void *pdev, void *regs) return pi; } -void pcicore_deinit(void *pch) +void pcicore_deinit(struct pcicore_info *pch) { kfree(pch); } @@ -281,7 +280,7 @@ void pcicore_deinit(void *pch) /* return cap_offset if requested capability exists in the PCI config space */ /* Note that it's caller's responsibility to make sure it's a pci bus */ u8 -pcicore_find_pci_capability(void *dev, u8 req_cap_id, +pcicore_find_pci_capability(struct pci_dev *dev, u8 req_cap_id, unsigned char *buf, u32 *buflen) { u8 cap_id; @@ -399,6 +398,7 @@ static bool pcie_mdiosetblock(struct pcicore_info *pi, uint blk) while (i < pcie_serdes_spinwait) { if (R_REG(&pcieregs->mdiocontrol) & MDIOCTL_ACCESS_DONE) break; + udelay(1000); i++; } @@ -485,9 +485,8 @@ pcie_mdiowrite(struct pcicore_info *pi, uint physmedia, uint regaddr, uint val) } /* ***** Support functions ***** */ -static u8 pcie_clkreq(void *pch, u32 mask, u32 val) +static u8 pcie_clkreq(struct pcicore_info *pi, u32 mask, u32 val) { - struct pcicore_info *pi = pch; u32 reg_val; u8 offset; @@ -537,30 +536,30 @@ static void pcie_clkreq_upd(struct pcicore_info *pi, uint state) switch (state) { case SI_DOATTACH: if (PCIE_ASPM(sih)) - pcie_clkreq((void *)pi, 1, 0); + pcie_clkreq(pi, 1, 0); break; case SI_PCIDOWN: if (sih->buscorerev == 6) { /* turn on serdes PLL down */ ai_corereg(sih, SI_CC_IDX, - offsetof(chipcregs_t, chipcontrol_addr), + offsetof(struct chipcregs, chipcontrol_addr), ~0, 0); ai_corereg(sih, SI_CC_IDX, - offsetof(chipcregs_t, chipcontrol_data), + offsetof(struct chipcregs, chipcontrol_data), ~0x40, 0); } else if (pi->pcie_pr42767) { - pcie_clkreq((void *)pi, 1, 1); + pcie_clkreq(pi, 1, 1); } break; case SI_PCIUP: if (sih->buscorerev == 6) { /* turn off serdes PLL down */ ai_corereg(sih, SI_CC_IDX, - offsetof(chipcregs_t, chipcontrol_addr), + offsetof(struct chipcregs, chipcontrol_addr), ~0, 0); ai_corereg(sih, SI_CC_IDX, - offsetof(chipcregs_t, chipcontrol_data), + offsetof(struct chipcregs, chipcontrol_data), ~0x40, 0x40); } else if (PCIE_ASPM(sih)) { /* disable clkreq */ - pcie_clkreq((void *)pi, 1, 0); + pcie_clkreq(pi, 1, 0); } break; } @@ -674,7 +673,7 @@ static void pcie_war_noplldown(struct pcicore_info *pi) u16 *reg16; /* turn off serdes PLL down */ - ai_corereg(pi->sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol), + ai_corereg(pi->sih, SI_CC_IDX, offsetof(struct chipcregs, chipcontrol), CHIPCTRL_4321_PLL_DOWN, CHIPCTRL_4321_PLL_DOWN); /* clear srom shadow backdoor */ @@ -730,9 +729,8 @@ static void pcie_war_pci_setup(struct pcicore_info *pi) } /* ***** Functions called during driver state changes ***** */ -void pcicore_attach(void *pch, char *pvars, int state) +void pcicore_attach(struct pcicore_info *pi, char *pvars, int state) { - struct pcicore_info *pi = pch; struct si_pub *sih = pi->sih; /* Determine if this board needs override */ @@ -754,20 +752,16 @@ void pcicore_attach(void *pch, char *pvars, int state) } -void pcicore_hwup(void *pch) +void pcicore_hwup(struct pcicore_info *pi) { - struct pcicore_info *pi = pch; - if (!pi || !PCIE_PUB(pi->sih)) return; pcie_war_pci_setup(pi); } -void pcicore_up(void *pch, int state) +void pcicore_up(struct pcicore_info *pi, int state) { - struct pcicore_info *pi = pch; - if (!pi || !PCIE_PUB(pi->sih)) return; @@ -780,9 +774,8 @@ void pcicore_up(void *pch, int state) /* When the device is going to enter D3 state * (or the system is going to enter S3/S4 states) */ -void pcicore_sleep(void *pch) +void pcicore_sleep(struct pcicore_info *pi) { - struct pcicore_info *pi = pch; u32 w; if (!pi || !PCIE_ASPM(pi->sih)) @@ -795,10 +788,8 @@ void pcicore_sleep(void *pch) pi->pcie_pr42767 = false; } -void pcicore_down(void *pch, int state) +void pcicore_down(struct pcicore_info *pi, int state) { - struct pcicore_info *pi = pch; - if (!pi || !PCIE_PUB(pi->sih)) return; @@ -809,20 +800,12 @@ void pcicore_down(void *pch, int state) } /* precondition: current core is sii->buscoretype */ -void pcicore_fixcfg(void *pch, void *regs) +static void pcicore_fixcfg(struct pcicore_info *pi, u16 *reg16) { - struct pcicore_info *pi = pch; struct si_info *sii = SI_INFO(pi->sih); - struct sbpciregs *pciregs = regs; - struct sbpcieregs *pcieregs = regs; - u16 val16, *reg16 = NULL; + u16 val16; uint pciidx; - /* check 'pi' is correct and fix it if not */ - if (sii->pub.buscoretype == PCIE_CORE_ID) - reg16 = &pcieregs->sprom[SRSH_PI_OFFSET]; - else if (sii->pub.buscoretype == PCI_CORE_ID) - reg16 = &pciregs->sprom[SRSH_PI_OFFSET]; pciidx = ai_coreidx(&sii->pub); val16 = R_REG(reg16); if (((val16 & SRSH_PI_MASK) >> SRSH_PI_SHIFT) != (u16)pciidx) { @@ -832,11 +815,19 @@ void pcicore_fixcfg(void *pch, void *regs) } } +void pcicore_fixcfg_pci(struct pcicore_info *pi, struct sbpciregs *pciregs) +{ + pcicore_fixcfg(pi, &pciregs->sprom[SRSH_PI_OFFSET]); +} + +void pcicore_fixcfg_pcie(struct pcicore_info *pi, struct sbpcieregs *pcieregs) +{ + pcicore_fixcfg(pi, &pcieregs->sprom[SRSH_PI_OFFSET]); +} + /* precondition: current core is pci core */ -void pcicore_pci_setup(void *pch, void *regs) +void pcicore_pci_setup(struct pcicore_info *pi, struct sbpciregs *pciregs) { - struct pcicore_info *pi = pch; - struct sbpciregs *pciregs = regs; u32 w; OR_REG(&pciregs->sbtopci2, SBTOPCI_PREF | SBTOPCI_BURST); diff --git a/drivers/staging/brcm80211/brcmsmac/nicpci.h b/drivers/staging/brcm80211/brcmsmac/nicpci.h index f71f842..3082db0 100644 --- a/drivers/staging/brcm80211/brcmsmac/nicpci.h +++ b/drivers/staging/brcm80211/brcmsmac/nicpci.h @@ -70,16 +70,24 @@ #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); +struct sbpciregs; +struct sbpcieregs; + +extern struct pcicore_info *pcicore_init(struct si_pub *sih, + struct pci_dev *pdev, void *regs); +extern void pcicore_deinit(struct pcicore_info *pch); +extern void pcicore_attach(struct pcicore_info *pch, char *pvars, int state); +extern void pcicore_hwup(struct pcicore_info *pch); +extern void pcicore_up(struct pcicore_info *pch, int state); +extern void pcicore_sleep(struct pcicore_info *pch); +extern void pcicore_down(struct pcicore_info *pch, int state); +extern u8 pcicore_find_pci_capability(struct pci_dev *dev, u8 req_cap_id, + unsigned char *buf, u32 *buflen); +extern void pcicore_fixcfg_pci(struct pcicore_info *pch, + struct sbpciregs *pciregs); +extern void pcicore_fixcfg_pcie(struct pcicore_info *pch, + struct sbpcieregs *pciregs); +extern void pcicore_pci_setup(struct pcicore_info *pch, + struct sbpciregs *pciregs); #endif /* _BRCM_NICPCI_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/otp.c b/drivers/staging/brcm80211/brcmsmac/otp.c index 4a70180..1e0093c 100644 --- a/drivers/staging/brcm80211/brcmsmac/otp.c +++ b/drivers/staging/brcm80211/brcmsmac/otp.c @@ -25,10 +25,14 @@ #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 */ +/* h/w subregion is programmed */ +#define OTPS_GUP_HW 0x00000100 +/* s/w subregion is programmed */ +#define OTPS_GUP_SW 0x00000200 +/* chipid/pkgopt subregion is programmed */ +#define OTPS_GUP_CI 0x00000400 +/* fuse subregion is programmed */ +#define OTPS_GUP_FUSE 0x00000800 /* Fields in otpprog in rev >= 21 */ #define OTPP_COL_MASK 0x000000ff @@ -60,23 +64,15 @@ #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; + int (*size)(struct otpinfo *oi); + u16 (*read_bit)(struct otpinfo *oi, struct chipcregs *cc, uint off); + struct otpinfo *(*init)(struct si_pub *sih); + int (*read_region)(struct otpinfo *oi, int region, u16 *data, + uint *wlen); + int (*nvread)(struct otpinfo *oi, char *data, uint *len); + int (*status)(struct otpinfo *oi); }; struct otpinfo { @@ -152,31 +148,24 @@ static struct otpinfo otpinfo; #define OTP4315_SWREG_SZ 178 /* 178 bytes */ #define OTP_SZ_FU_144 (144/8) /* 144 bits */ -static int ipxotp_status(void *oh) +static int ipxotp_status(struct otpinfo *oi) { - struct otpinfo *oi = (struct otpinfo *) oh; return (int)(oi->status); } /* Return size in bytes */ -static int ipxotp_size(void *oh) +static int ipxotp_size(struct otpinfo *oi) { - struct otpinfo *oi = (struct otpinfo *) oh; return (int)oi->wsize * 2; } -static u16 ipxotp_otpr(void *oh, chipcregs_t *cc, uint wn) +static u16 ipxotp_otpr(struct otpinfo *oi, struct chipcregs *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) +static u16 ipxotp_read_bit(struct otpinfo *oi, struct chipcregs *cc, uint off) { - struct otpinfo *oi = (struct otpinfo *) oh; uint k, row, col; u32 otpp, st; @@ -193,19 +182,20 @@ static u16 ipxotp_read_bit(void *oh, chipcregs_t *cc, uint off) ((st = R_REG(&cc->otpprog)) & OTPP_START_BUSY) && (k < OTPP_TRIES); k++) ; - if (k >= OTPP_TRIES) { + if (k >= OTPP_TRIES) return 0xffff; - } - if (st & OTPP_READERR) { + + 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 +/* + * 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) { @@ -226,17 +216,23 @@ static int ipxotp_max_rgnsz(struct si_pub *sih, int osizew) return ret; } -static void _ipxotp_init(struct otpinfo *oi, chipcregs_t *cc) +static void _ipxotp_init(struct otpinfo *oi, struct chipcregs *cc) { uint k; u32 otpp, st; - /* record word offset of General Use Region for various chipcommon revs */ + /* + * 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 */ + /* + * 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 @@ -254,9 +250,8 @@ static void _ipxotp_init(struct otpinfo *oi, chipcregs_t *cc) ((st = R_REG(&cc->otpprog)) & OTPP_START_BUSY) && (k < OTPP_TRIES); k++) ; - if (k >= OTPP_TRIES) { + if (k >= OTPP_TRIES) return; - } /* Read OTP lock bits and subregion programmed indication bits */ oi->status = R_REG(&cc->otpstatus); @@ -272,8 +267,9 @@ static void _ipxotp_init(struct otpinfo *oi, chipcregs_t *cc) } /* - * 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. + * 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; @@ -297,10 +293,10 @@ static void _ipxotp_init(struct otpinfo *oi, chipcregs_t *cc) oi->flim = oi->wsize; } -static void *ipxotp_init(struct si_pub *sih) +static struct otpinfo *ipxotp_init(struct si_pub *sih) { uint idx; - chipcregs_t *cc; + struct chipcregs *cc; struct otpinfo *oi; /* Make sure we're running IPX OTP */ @@ -352,14 +348,14 @@ static void *ipxotp_init(struct si_pub *sih) ai_setcoreidx(sih, idx); - return (void *)oi; + return oi; } -static int ipxotp_read_region(void *oh, int region, u16 *data, uint *wlen) +static int +ipxotp_read_region(struct otpinfo *oi, int region, u16 *data, uint *wlen) { - struct otpinfo *oi = (struct otpinfo *) oh; uint idx; - chipcregs_t *cc; + struct chipcregs *cc; uint base, i, sz; /* Validate region selection */ @@ -433,27 +429,27 @@ static int ipxotp_read_region(void *oh, int region, u16 *data, uint *wlen) /* Read the data */ for (i = 0; i < sz; i++) - data[i] = ipxotp_otpr(oh, cc, base + i); + data[i] = ipxotp_otpr(oi, cc, base + i); ai_setcoreidx(oi->sih, idx); *wlen = sz; return 0; } -static int ipxotp_nvread(void *oh, char *data, uint *len) +static int ipxotp_nvread(struct otpinfo *oi, 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, + (int (*)(struct otpinfo *)) ipxotp_size, + (u16 (*)(struct otpinfo *, struct chipcregs *, uint)) ipxotp_read_bit, - (otp_init_t) ipxotp_init, - (otp_read_region_t) ipxotp_read_region, - (otp_nvread_t) ipxotp_nvread, + (struct otpinfo *(*)(struct si_pub *)) ipxotp_init, + (int (*)(struct otpinfo *, int, u16 *, uint *)) ipxotp_read_region, + (int (*)(struct otpinfo *, char *, uint *)) ipxotp_nvread, - (otp_status_t) ipxotp_status + (int (*)(struct otpinfo *)) ipxotp_status }; /* @@ -465,34 +461,29 @@ static struct otp_fn_s ipxotp_fn = { * otp_nvread() */ -int otp_status(void *oh) +int otp_status(struct otpinfo *oi) { - struct otpinfo *oi = (struct otpinfo *) oh; - - return oi->fn->status(oh); + return oi->fn->status(oi); } -int otp_size(void *oh) +int otp_size(struct otpinfo *oi) { - struct otpinfo *oi = (struct otpinfo *) oh; - - return oi->fn->size(oh); + return oi->fn->size(oi); } -u16 otp_read_bit(void *oh, uint offset) +u16 otp_read_bit(struct otpinfo *oi, 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); + struct chipcregs *cc = ai_setcoreidx(oi->sih, SI_CC_IDX); + u16 readBit = (u16) oi->fn->read_bit(oi, cc, offset); ai_setcoreidx(oi->sih, idx); return readBit; } -void *otp_init(struct si_pub *sih) +struct otpinfo *otp_init(struct si_pub *sih) { struct otpinfo *oi; - void *ret = NULL; + struct otpinfo *ret = NULL; oi = &otpinfo; memset(oi, 0, sizeof(struct otpinfo)); @@ -502,9 +493,8 @@ void *otp_init(struct si_pub *sih) if (OTPTYPE_IPX(oi->ccrev)) oi->fn = &ipxotp_fn; - if (oi->fn == NULL) { + if (oi->fn == NULL) return NULL; - } oi->sih = sih; @@ -514,9 +504,8 @@ void *otp_init(struct si_pub *sih) } int -otp_read_region(struct si_pub *sih, int region, u16 *data, - uint *wlen) { - void *oh; +otp_read_region(struct si_pub *sih, int region, u16 *data, uint *wlen) { + struct otpinfo *oi; int err = 0; if (ai_is_otp_disabled(sih)) { @@ -524,22 +513,19 @@ otp_read_region(struct si_pub *sih, int region, u16 *data, goto out; } - oh = otp_init(sih); - if (oh == NULL) { + oi = otp_init(sih); + if (oi == NULL) { err = -EBADE; goto out; } - err = (((struct otpinfo *) oh)->fn->read_region) - (oh, region, data, wlen); + err = ((oi)->fn->read_region)(oi, region, data, wlen); out: return err; } -int otp_nvread(void *oh, char *data, uint *len) +int otp_nvread(struct otpinfo *oi, char *data, uint *len) { - struct otpinfo *oi = (struct otpinfo *) oh; - - return oi->fn->nvread(oh, data, len); + return oi->fn->nvread(oi, data, len); } diff --git a/drivers/staging/brcm80211/brcmsmac/otp.h b/drivers/staging/brcm80211/brcmsmac/otp.h index f6d3a56..938100e 100644 --- a/drivers/staging/brcm80211/brcmsmac/otp.h +++ b/drivers/staging/brcm80211/brcmsmac/otp.h @@ -24,7 +24,8 @@ #define OTP_SW_RGN 2 #define OTP_CI_RGN 4 #define OTP_FUSE_RGN 8 -#define OTP_ALL_RGN 0xf /* From h/w region to end of OTP including checksum */ +/* From h/w region to end of OTP including checksum */ +#define OTP_ALL_RGN 0xf /* OTP Size */ #define OTP_SZ_MAX (6144/8) /* maximum bytes in one CIS */ @@ -35,13 +36,15 @@ /* OTP usage */ #define OTP4325_FM_DISABLED_OFFSET 188 +struct otpinfo; + /* Exported functions */ -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(struct si_pub *sih); +extern int otp_status(struct otpinfo *oi); +extern int otp_size(struct otpinfo *oi); +extern u16 otp_read_bit(struct otpinfo *oi, uint offset); +extern struct otpinfo *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); +extern int otp_nvread(struct otpinfo *oi, char *data, uint *len); #endif /* _BRCM_OTP_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/phy/phy_cmn.c b/drivers/staging/brcm80211/brcmsmac/phy/phy_cmn.c index 17012fb..3955d6e 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/phy_cmn.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/phy_cmn.c @@ -27,8 +27,6 @@ #include "phy_lcn.h" #include "phyreg_n.h" -u32 phyhal_msg_level = PHYHAL_ERROR; - struct chan_info_basic { u16 chan; u16 freq; @@ -119,31 +117,7 @@ const u8 ofdm_rate_lookup[] = { BRCM_RATE_9M }; -#define PHY_WREG_LIMIT 24 - -static void wlc_set_phy_uninitted(struct brcms_phy *pi); -static u32 wlc_phy_get_radio_ver(struct brcms_phy *pi); -static void wlc_phy_timercb_phycal(void *arg); - -static bool wlc_phy_noise_calc_phy(struct brcms_phy *pi, u32 *cmplx_pwr, - s8 *pwr_ant); - -static void wlc_phy_cal_perical_mphase_schedule(struct brcms_phy *pi, - uint delay); - -static void wlc_phy_noise_cb(struct brcms_phy *pi, u8 channel, s8 noise_dbm); -static void wlc_phy_noise_sample_request(struct brcms_phy_pub *pih, u8 reason, - u8 ch); - -static void wlc_phy_txpower_reg_limit_calc(struct brcms_phy *pi, - struct txpwr_limits *tp, chanspec_t); -static bool wlc_phy_cal_txpower_recalc_sw(struct brcms_phy *pi); - -static s8 wlc_user_txpwr_antport_to_rfport(struct brcms_phy *pi, uint chan, - u32 band, u8 rate); -static void wlc_phy_upd_env_txpwr_rate_limits(struct brcms_phy *pi, u32 band); -static s8 wlc_phy_env_measure_vbat(struct brcms_phy *pi); -static s8 wlc_phy_env_measure_temperature(struct brcms_phy *pi); +#define PHY_WREG_LIMIT 24 char *phy_getvar(struct brcms_phy *pi, const char *name) { @@ -172,12 +146,13 @@ char *phy_getvar(struct brcms_phy *pi, const char *name) int phy_getintvar(struct brcms_phy *pi, const char *name) { char *val; + unsigned long res; val = PHY_GETVAR(pi, name); - if (val == NULL) - return 0; + if (val && !kstrtoul(val, 0, &res)) + return res; - return simple_strtoul(val, NULL, 0); + return 0; } void wlc_phyreg_enter(struct brcms_phy_pub *pih) @@ -203,7 +178,7 @@ void wlc_radioreg_enter(struct brcms_phy_pub *pih) void wlc_radioreg_exit(struct brcms_phy_pub *pih) { struct brcms_phy *pi = (struct brcms_phy *) pih; - volatile u16 dummy; + u16 dummy; dummy = R_REG(&pi->regs->phyversion); pi->phy_wreg = 0; @@ -217,9 +192,6 @@ u16 read_radio_reg(struct brcms_phy *pi, u16 addr) if ((addr == RADIO_IDCODE)) return 0xffff; - if (NORADIO_ENAB(pi->pubpi)) - return NORADIO_IDCODE & 0xffff; - switch (pi->pubpi.phy_type) { case PHY_TYPE_N: CASECHECK(PHYTYPE, PHY_TYPE_N); @@ -262,9 +234,6 @@ u16 read_radio_reg(struct brcms_phy *pi, u16 addr) void write_radio_reg(struct brcms_phy *pi, u16 addr, u16 val) { - if (NORADIO_ENAB(pi->pubpi)) - return; - if ((D11REV_GE(pi->sh->corerev, 24)) || (D11REV_IS(pi->sh->corerev, 22) && (pi->pubpi.phy_type != PHY_TYPE_SSN))) { @@ -276,11 +245,9 @@ void write_radio_reg(struct brcms_phy *pi, u16 addr, u16 val) W_REG(&pi->regs->phy4wdatalo, val); } - if (pi->sh->bustype == PCI_BUS) { - if (++pi->phy_wreg >= pi->phy_wreg_limit) { - (void)R_REG(&pi->regs->maccontrol); - pi->phy_wreg = 0; - } + if (++pi->phy_wreg >= pi->phy_wreg_limit) { + (void)R_REG(&pi->regs->maccontrol); + pi->phy_wreg = 0; } } @@ -288,9 +255,6 @@ static u32 read_radio_id(struct brcms_phy *pi) { u32 id; - if (NORADIO_ENAB(pi->pubpi)) - return NORADIO_IDCODE; - if (D11REV_GE(pi->sh->corerev, 24)) { u32 b0, b1, b2; @@ -316,9 +280,6 @@ void and_radio_reg(struct brcms_phy *pi, u16 addr, u16 val) { u16 rval; - if (NORADIO_ENAB(pi->pubpi)) - return; - rval = read_radio_reg(pi, addr); write_radio_reg(pi, addr, (rval & val)); } @@ -327,9 +288,6 @@ void or_radio_reg(struct brcms_phy *pi, u16 addr, u16 val) { u16 rval; - if (NORADIO_ENAB(pi->pubpi)) - return; - rval = read_radio_reg(pi, addr); write_radio_reg(pi, addr, (rval | val)); } @@ -338,9 +296,6 @@ void xor_radio_reg(struct brcms_phy *pi, u16 addr, u16 mask) { u16 rval; - if (NORADIO_ENAB(pi->pubpi)) - return; - rval = read_radio_reg(pi, addr); write_radio_reg(pi, addr, (rval ^ mask)); } @@ -349,9 +304,6 @@ void mod_radio_reg(struct brcms_phy *pi, u16 addr, u16 mask, u16 val) { u16 rval; - if (NORADIO_ENAB(pi->pubpi)) - return; - rval = read_radio_reg(pi, addr); write_radio_reg(pi, addr, (rval & ~mask) | (val & mask)); } @@ -363,7 +315,7 @@ void write_phy_channel_reg(struct brcms_phy *pi, uint val) u16 read_phy_reg(struct brcms_phy *pi, u16 addr) { - d11regs_t *regs; + struct d11regs *regs; regs = pi->regs; @@ -375,11 +327,11 @@ u16 read_phy_reg(struct brcms_phy *pi, u16 addr) void write_phy_reg(struct brcms_phy *pi, u16 addr, u16 val) { - d11regs_t *regs; + struct d11regs *regs; regs = pi->regs; -#ifdef __mips__ +#ifdef CONFIG_BCM47XX W_REG_FLUSH(®s->phyregaddr, addr); W_REG(®s->phyregdata, val); if (addr == 0x72) @@ -387,18 +339,16 @@ void write_phy_reg(struct brcms_phy *pi, u16 addr, u16 val) #else W_REG((u32 *)(®s->phyregaddr), addr | (val << 16)); - if (pi->sh->bustype == PCI_BUS) { - if (++pi->phy_wreg >= pi->phy_wreg_limit) { - pi->phy_wreg = 0; - (void)R_REG(®s->phyversion); - } + if (++pi->phy_wreg >= pi->phy_wreg_limit) { + pi->phy_wreg = 0; + (void)R_REG(®s->phyversion); } #endif } void and_phy_reg(struct brcms_phy *pi, u16 addr, u16 val) { - d11regs_t *regs; + struct d11regs *regs; regs = pi->regs; @@ -410,7 +360,7 @@ void and_phy_reg(struct brcms_phy *pi, u16 addr, u16 val) void or_phy_reg(struct brcms_phy *pi, u16 addr, u16 val) { - d11regs_t *regs; + struct d11regs *regs; regs = pi->regs; @@ -422,7 +372,7 @@ void or_phy_reg(struct brcms_phy *pi, u16 addr, u16 val) void mod_phy_reg(struct brcms_phy *pi, u16 addr, u16 mask, u16 val) { - d11regs_t *regs; + struct d11regs *regs; regs = pi->regs; @@ -464,9 +414,8 @@ static void wlc_set_phy_uninitted(struct brcms_phy *pi) } pi->radiopwr = 0xffff; for (i = 0; i < STATIC_NUM_RF; i++) { - for (j = 0; j < STATIC_NUM_BB; j++) { + for (j = 0; j < STATIC_NUM_BB; j++) pi->stats_11b_txpower[i][j] = -1; - } } } @@ -475,9 +424,8 @@ struct shared_phy *wlc_phy_shared_attach(struct shared_phy_params *shp) struct shared_phy *sh; sh = kzalloc(sizeof(struct shared_phy), GFP_ATOMIC); - if (sh == NULL) { + if (sh == NULL) return NULL; - } sh->sih = shp->sih; sh->physhim = shp->physhim; @@ -495,7 +443,6 @@ struct shared_phy *wlc_phy_shared_attach(struct shared_phy_params *shp) sh->boardvendor = shp->boardvendor; sh->boardflags = shp->boardflags; sh->boardflags2 = shp->boardflags2; - sh->bustype = shp->bustype; sh->buscorerev = shp->buscorerev; sh->fast_timer = PHY_SW_TIMER_FAST; @@ -507,8 +454,39 @@ struct shared_phy *wlc_phy_shared_attach(struct shared_phy_params *shp) return sh; } +static void wlc_phy_timercb_phycal(struct brcms_phy *pi) +{ + uint delay = 5; + + if (PHY_PERICAL_MPHASE_PENDING(pi)) { + if (!pi->sh->up) { + wlc_phy_cal_perical_mphase_reset(pi); + return; + } + + if (SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi)) { + + delay = 1000; + wlc_phy_cal_perical_mphase_restart(pi); + } else + wlc_phy_cal_perical_nphy_run(pi, PHY_PERICAL_AUTO); + wlapi_add_timer(pi->sh->physhim, pi->phycal_timer, delay, 0); + return; + } + +} + +static u32 wlc_phy_get_radio_ver(struct brcms_phy *pi) +{ + u32 ver; + + ver = read_radio_id(pi); + + return ver; +} + struct brcms_phy_pub * -wlc_phy_attach(struct shared_phy *sh, void *regs, int bandtype, +wlc_phy_attach(struct shared_phy *sh, struct d11regs *regs, int bandtype, char *vars, struct wiphy *wiphy) { struct brcms_phy *pi; @@ -523,25 +501,22 @@ wlc_phy_attach(struct shared_phy *sh, void *regs, int bandtype, sflags = ai_core_sflags(sh->sih, 0, 0); if (BAND_5G(bandtype)) { - if ((sflags & (SISF_5G_PHY | SISF_DB_PHY)) == 0) { + if ((sflags & (SISF_5G_PHY | SISF_DB_PHY)) == 0) return NULL; - } } pi = sh->phy_head; if ((sflags & SISF_DB_PHY) && pi) { - wlapi_bmac_corereset(pi->sh->physhim, pi->pubpi.coreflags); pi->refcnt++; return &pi->pubpi_ro; } pi = kzalloc(sizeof(struct brcms_phy), GFP_ATOMIC); - if (pi == NULL) { + if (pi == NULL) return NULL; - } pi->wiphy = wiphy; - pi->regs = (d11regs_t *) regs; + pi->regs = regs; pi->sh = sh; pi->phy_init_por = true; pi->phy_wreg_limit = PHY_WREG_LIMIT; @@ -554,10 +529,8 @@ wlc_phy_attach(struct shared_phy *sh, void *regs, int bandtype, pi->phycal_tempdelta = 0; - if (BAND_2G(bandtype) && (sflags & SISF_2G_PHY)) { - + if (BAND_2G(bandtype) && (sflags & SISF_2G_PHY)) pi->pubpi.coreflags = SICF_GMODE; - } wlapi_bmac_corereset(pi->sh->physhim, pi->pubpi.coreflags); phyversion = R_REG(&pi->regs->phyversion); @@ -572,28 +545,25 @@ wlc_phy_attach(struct shared_phy *sh, void *regs, int bandtype, pi->pubpi.phy_corenum = PHY_CORE_NUM_2; pi->pubpi.ana_rev = (phyversion & PV_AV_MASK) >> PV_AV_SHIFT; - if (!VALID_PHYTYPE(pi->pubpi.phy_type)) { + if (!VALID_PHYTYPE(pi->pubpi.phy_type)) goto err; - } + if (BAND_5G(bandtype)) { - if (!ISNPHY(pi)) { - goto err; - } - } else { - if (!ISNPHY(pi) && !ISLCNPHY(pi)) { + if (!ISNPHY(pi)) goto err; - } + } else if (!ISNPHY(pi) && !ISLCNPHY(pi)) { + goto err; } wlc_phy_anacore((struct brcms_phy_pub *) pi, ON); idcode = wlc_phy_get_radio_ver(pi); pi->pubpi.radioid = - (idcode & IDCODE_ID_MASK) >> IDCODE_ID_SHIFT; + (idcode & IDCODE_ID_MASK) >> IDCODE_ID_SHIFT; pi->pubpi.radiorev = - (idcode & IDCODE_REV_MASK) >> IDCODE_REV_SHIFT; + (idcode & IDCODE_REV_MASK) >> IDCODE_REV_SHIFT; pi->pubpi.radiover = - (idcode & IDCODE_VER_MASK) >> IDCODE_VER_SHIFT; + (idcode & IDCODE_VER_MASK) >> IDCODE_VER_SHIFT; if (!VALID_RADIO(pi, pi->pubpi.radioid)) goto err; @@ -603,7 +573,7 @@ wlc_phy_attach(struct shared_phy *sh, void *regs, int bandtype, pi->bw = WL_CHANSPEC_BW_20; pi->radio_chanspec = - BAND_2G(bandtype) ? CH20MHZ_CHSPEC(1) : CH20MHZ_CHSPEC(36); + BAND_2G(bandtype) ? CH20MHZ_CHSPEC(1) : CH20MHZ_CHSPEC(36); pi->rxiq_samps = PHY_NOISE_SAMPLE_LOG_NUM_NPHY; pi->rxiq_antsel = ANT_RX_DIV_DEF; @@ -625,7 +595,7 @@ wlc_phy_attach(struct shared_phy *sh, void *regs, int bandtype, pi->phy_txcore_disable_temp = PHY_CHAIN_TX_DISABLE_TEMP; pi->phy_txcore_enable_temp = - PHY_CHAIN_TX_DISABLE_TEMP - PHY_HYSTERESIS_DELTATEMP; + PHY_CHAIN_TX_DISABLE_TEMP - PHY_HYSTERESIS_DELTATEMP; pi->phy_tempsense_offset = 0; pi->phy_txcore_heatedup = false; @@ -648,11 +618,10 @@ wlc_phy_attach(struct shared_phy *sh, void *regs, int bandtype, if (ISNPHY(pi)) { pi->phycal_timer = wlapi_init_timer(pi->sh->physhim, - wlc_phy_timercb_phycal, - pi, "phycal"); - if (!pi->phycal_timer) { + wlc_phy_timercb_phycal, + pi, "phycal"); + if (!pi->phycal_timer) goto err; - } if (!wlc_phy_attach_nphy(pi)) goto err; @@ -661,8 +630,6 @@ wlc_phy_attach(struct shared_phy *sh, void *regs, int bandtype, if (!wlc_phy_attach_lcnphy(pi)) goto err; - } else { - } pi->refcnt++; @@ -675,7 +642,7 @@ wlc_phy_attach(struct shared_phy *sh, void *regs, int bandtype, return &pi->pubpi_ro; - err: +err: kfree(pi); return NULL; } @@ -685,9 +652,8 @@ void wlc_phy_detach(struct brcms_phy_pub *pih) struct brcms_phy *pi = (struct brcms_phy *) pih; if (pih) { - if (--pi->refcnt) { + if (--pi->refcnt) return; - } if (pi->phycal_timer) { wlapi_free_timer(pi->sh->physhim, pi->phycal_timer); @@ -700,7 +666,7 @@ void wlc_phy_detach(struct brcms_phy_pub *pih) pi->sh->phy_head->next = NULL; if (pi->pi_fptr.detach) - (pi->pi_fptr.detach) (pi); + (pi->pi_fptr.detach)(pi); kfree(pi); } @@ -731,29 +697,6 @@ u32 wlc_phy_get_coreflags(struct brcms_phy_pub *pih) return pi->pubpi.coreflags; } -static void wlc_phy_timercb_phycal(void *arg) -{ - struct brcms_phy *pi = (struct brcms_phy *) arg; - uint delay = 5; - - if (PHY_PERICAL_MPHASE_PENDING(pi)) { - if (!pi->sh->up) { - wlc_phy_cal_perical_mphase_reset(pi); - return; - } - - if (SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi)) { - - delay = 1000; - wlc_phy_cal_perical_mphase_restart(pi); - } else - wlc_phy_cal_perical_nphy_run(pi, PHY_PERICAL_AUTO); - wlapi_add_timer(pi->sh->physhim, pi->phycal_timer, delay, 0); - return; - } - -} - void wlc_phy_anacore(struct brcms_phy_pub *pih, bool on) { struct brcms_phy *pi = (struct brcms_phy *) pih; @@ -862,10 +805,10 @@ void wlc_phy_hw_state_upd(struct brcms_phy_pub *pih, bool newstate) pi->sh->up = newstate; } -void wlc_phy_init(struct brcms_phy_pub *pih, chanspec_t chanspec) +void wlc_phy_init(struct brcms_phy_pub *pih, u16 chanspec) { u32 mc; - initfn_t phy_init = NULL; + void (*phy_init)(struct brcms_phy *) = NULL; struct brcms_phy *pi = (struct brcms_phy *) pih; if (pi->init_in_progress) @@ -879,9 +822,8 @@ void wlc_phy_init(struct brcms_phy_pub *pih, chanspec_t chanspec) if (WARN(mc & MCTL_EN_MAC, "HW error MAC running on init")) return; - if (!(pi->measure_hold & PHY_HOLD_FOR_SCAN)) { + if (!(pi->measure_hold & PHY_HOLD_FOR_SCAN)) pi->measure_hold |= PHY_HOLD_FOR_NOT_ASSOC; - } if (WARN(!(ai_core_sflags(pi->sh->sih, 0, 0) & SISF_FCLKA), "HW error SISF_FCLKA\n")) @@ -889,9 +831,8 @@ void wlc_phy_init(struct brcms_phy_pub *pih, chanspec_t chanspec) phy_init = pi->pi_fptr.init; - if (phy_init == NULL) { + if (phy_init == NULL) return; - } wlc_phy_anacore(pih, ON); @@ -903,7 +844,7 @@ void wlc_phy_init(struct brcms_phy_pub *pih, chanspec_t chanspec) wlc_phy_switch_radio((struct brcms_phy_pub *) pi, ON); - (*phy_init) (pi); + (*phy_init)(pi); pi->phy_init_por = false; @@ -921,7 +862,7 @@ void wlc_phy_init(struct brcms_phy_pub *pih, chanspec_t chanspec) void wlc_phy_cal_init(struct brcms_phy_pub *pih) { struct brcms_phy *pi = (struct brcms_phy *) pih; - initfn_t cal_init = NULL; + void (*cal_init)(struct brcms_phy *) = NULL; if (WARN((R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC) != 0, "HW error: MAC enabled during phy cal\n")) @@ -930,7 +871,7 @@ void wlc_phy_cal_init(struct brcms_phy_pub *pih) if (!pi->initialized) { cal_init = pi->pi_fptr.calinit; if (cal_init) - (*cal_init) (pi); + (*cal_init)(pi); pi->initialized = true; } @@ -951,15 +892,6 @@ int wlc_phy_down(struct brcms_phy_pub *pih) return callbacks; } -static u32 wlc_phy_get_radio_ver(struct brcms_phy *pi) -{ - u32 ver; - - ver = read_radio_id(pi); - - return ver; -} - void wlc_phy_table_addr(struct brcms_phy *pi, uint tbl_id, uint tbl_offset, u16 tblAddr, u16 tblDataHi, u16 tblDataLo) @@ -990,11 +922,9 @@ void wlc_phy_table_data_write(struct brcms_phy *pi, uint width, u32 val) } if (width == 32) { - write_phy_reg(pi, pi->tbl_data_hi, (u16) (val >> 16)); write_phy_reg(pi, pi->tbl_data_lo, (u16) val); } else { - write_phy_reg(pi, pi->tbl_data_lo, (u16) val); } } @@ -1025,15 +955,12 @@ wlc_phy_write_table(struct brcms_phy *pi, const struct phytbl_info *ptbl_info, } if (tbl_width == 32) { - write_phy_reg(pi, tblDataHi, (u16) (ptbl_32b[idx] >> 16)); write_phy_reg(pi, tblDataLo, (u16) ptbl_32b[idx]); } else if (tbl_width == 16) { - write_phy_reg(pi, tblDataLo, ptbl_16b[idx]); } else { - write_phy_reg(pi, tblDataLo, ptbl_8b[idx]); } } @@ -1064,14 +991,11 @@ wlc_phy_read_table(struct brcms_phy *pi, const struct phytbl_info *ptbl_info, } if (tbl_width == 32) { - ptbl_32b[idx] = read_phy_reg(pi, tblDataLo); ptbl_32b[idx] |= (read_phy_reg(pi, tblDataHi) << 16); } else if (tbl_width == 16) { - ptbl_16b[idx] = read_phy_reg(pi, tblDataLo); } else { - ptbl_8b[idx] = (u8) read_phy_reg(pi, tblDataLo); } } @@ -1084,10 +1008,9 @@ wlc_phy_init_radio_regs_allbands(struct brcms_phy *pi, uint i = 0; do { - if (radioregs[i].do_init) { + if (radioregs[i].do_init) write_radio_reg(pi, radioregs[i].address, (u16) radioregs[i].init); - } i++; } while (radioregs[i].address != 0xffff); @@ -1131,8 +1054,8 @@ wlc_phy_init_radio_regs(struct brcms_phy *pi, struct radio_regs *radioregs, void wlc_phy_do_dummy_tx(struct brcms_phy *pi, bool ofdm, bool pa_on) { -#define DUMMY_PKT_LEN 20 - d11regs_t *regs = pi->regs; +#define DUMMY_PKT_LEN 20 + struct d11regs *regs = pi->regs; int i, count; u8 ofdmpkt[DUMMY_PKT_LEN] = { 0xcc, 0x01, 0x02, 0x00, 0x00, 0x00, 0xd4, 0x00, 0x00, 0x00, @@ -1156,9 +1079,8 @@ void wlc_phy_do_dummy_tx(struct brcms_phy *pi, bool ofdm, bool pa_on) W_REG(®s->wepctl, 0); W_REG(®s->txe_phyctl, (ofdm ? 1 : 0) | PHY_TXC_ANT_0); - if (ISNPHY(pi) || ISLCNPHY(pi)) { + if (ISNPHY(pi) || ISLCNPHY(pi)) W_REG(®s->txe_phyctl1, 0x1A02); - } W_REG(®s->txe_wm_0, 0); W_REG(®s->txe_wm_1, 0); @@ -1185,16 +1107,14 @@ void wlc_phy_do_dummy_tx(struct brcms_phy *pi, bool ofdm, bool pa_on) i = 0; count = ofdm ? 30 : 250; while ((i++ < count) - && (R_REG(®s->txe_status) & (1 << 7))) { + && (R_REG(®s->txe_status) & (1 << 7))) udelay(10); - } i = 0; while ((i++ < 10) - && ((R_REG(®s->txe_status) & (1 << 10)) == 0)) { + && ((R_REG(®s->txe_status) & (1 << 10)) == 0)) udelay(10); - } i = 0; @@ -1207,28 +1127,26 @@ void wlc_phy_do_dummy_tx(struct brcms_phy *pi, bool ofdm, bool pa_on) } } -void wlc_phy_hold_upd(struct brcms_phy_pub *pih, mbool id, bool set) +void wlc_phy_hold_upd(struct brcms_phy_pub *pih, u32 id, bool set) { struct brcms_phy *pi = (struct brcms_phy *) pih; - if (set) { + if (set) mboolset(pi->measure_hold, id); - } else { + else mboolclr(pi->measure_hold, id); - } return; } -void wlc_phy_mute_upd(struct brcms_phy_pub *pih, bool mute, mbool flags) +void wlc_phy_mute_upd(struct brcms_phy_pub *pih, bool mute, u32 flags) { struct brcms_phy *pi = (struct brcms_phy *) pih; - if (mute) { + if (mute) mboolset(pi->measure_hold, PHY_HOLD_FOR_MUTE); - } else { + else mboolclr(pi->measure_hold, PHY_HOLD_FOR_MUTE); - } if (!mute && (flags & PHY_MUTE_FOR_PREISM)) pi->nphy_perical_last = pi->sh->now - pi->sh->glacial_timer; @@ -1258,9 +1176,6 @@ void wlc_phy_switch_radio(struct brcms_phy_pub *pih, bool on) { struct brcms_phy *pi = (struct brcms_phy *) pih; - if (NORADIO_ENAB(pi->pubpi)) - return; - { uint mc; @@ -1269,7 +1184,6 @@ void wlc_phy_switch_radio(struct brcms_phy_pub *pih, bool on) if (ISNPHY(pi)) { wlc_phy_switch_radio_nphy(pi, on); - } else if (ISLCNPHY(pi)) { if (on) { and_phy_reg(pi, 0x44c, @@ -1311,26 +1225,25 @@ void wlc_phy_bw_state_set(struct brcms_phy_pub *ppi, u16 bw) pi->bw = bw; } -void wlc_phy_chanspec_radio_set(struct brcms_phy_pub *ppi, chanspec_t newch) +void wlc_phy_chanspec_radio_set(struct brcms_phy_pub *ppi, u16 newch) { struct brcms_phy *pi = (struct brcms_phy *) ppi; pi->radio_chanspec = newch; } -chanspec_t wlc_phy_chanspec_get(struct brcms_phy_pub *ppi) +u16 wlc_phy_chanspec_get(struct brcms_phy_pub *ppi) { struct brcms_phy *pi = (struct brcms_phy *) ppi; return pi->radio_chanspec; } -void wlc_phy_chanspec_set(struct brcms_phy_pub *ppi, chanspec_t chanspec) +void wlc_phy_chanspec_set(struct brcms_phy_pub *ppi, u16 chanspec) { struct brcms_phy *pi = (struct brcms_phy *) ppi; u16 m_cur_channel; - chansetfn_t chanspec_set = NULL; - + void (*chanspec_set)(struct brcms_phy *, u16) = NULL; m_cur_channel = CHSPEC_CHANNEL(chanspec); if (CHSPEC_IS5G(chanspec)) m_cur_channel |= D11_CURCHANNEL_5G; @@ -1340,7 +1253,7 @@ void wlc_phy_chanspec_set(struct brcms_phy_pub *ppi, chanspec_t chanspec) chanspec_set = pi->pi_fptr.chanset; if (chanspec_set) - (*chanspec_set) (pi, chanspec); + (*chanspec_set)(pi, chanspec); } @@ -1360,17 +1273,16 @@ int wlc_phy_chanspec_freq2bandrange_lpssn(uint freq) return range; } -int wlc_phy_chanspec_bandrange_get(struct brcms_phy *pi, chanspec_t chanspec) +int wlc_phy_chanspec_bandrange_get(struct brcms_phy *pi, u16 chanspec) { int range = -1; uint channel = CHSPEC_CHANNEL(chanspec); uint freq = wlc_phy_channel2freq(channel); - if (ISNPHY(pi)) { + if (ISNPHY(pi)) range = wlc_phy_get_chan_freq_range_nphy(pi, channel); - } else if (ISLCNPHY(pi)) { + else if (ISLCNPHY(pi)) range = wlc_phy_chanspec_freq2bandrange_lpssn(freq); - } return range; } @@ -1396,13 +1308,13 @@ int wlc_phy_channel2freq(uint channel) void wlc_phy_chanspec_band_validch(struct brcms_phy_pub *ppi, uint band, - chanvec_t *channels) + struct brcms_chanvec *channels) { struct brcms_phy *pi = (struct brcms_phy *) ppi; uint i; uint channel; - memset(channels, 0, sizeof(chanvec_t)); + memset(channels, 0, sizeof(struct brcms_chanvec)); for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) { channel = chan_info_all[i].chan; @@ -1417,12 +1329,12 @@ wlc_phy_chanspec_band_validch(struct brcms_phy_pub *ppi, uint band, } } -chanspec_t wlc_phy_chanspec_band_firstch(struct brcms_phy_pub *ppi, uint band) +u16 wlc_phy_chanspec_band_firstch(struct brcms_phy_pub *ppi, uint band) { struct brcms_phy *pi = (struct brcms_phy *) ppi; uint i; uint channel; - chanspec_t chspec; + u16 chspec; for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) { channel = chan_info_all[i].chan; @@ -1440,9 +1352,8 @@ chanspec_t wlc_phy_chanspec_band_firstch(struct brcms_phy_pub *ppi, uint band) continue; channel = UPPER_20_SB(channel); - chspec = - channel | WL_CHANSPEC_BW_40 | - WL_CHANSPEC_CTL_SB_LOWER; + chspec = channel | WL_CHANSPEC_BW_40 | + WL_CHANSPEC_CTL_SB_LOWER; if (band == BRCM_BAND_2G) chspec |= WL_CHANSPEC_BAND_2G; else @@ -1459,7 +1370,7 @@ chanspec_t wlc_phy_chanspec_band_firstch(struct brcms_phy_pub *ppi, uint band) return chspec; } - return (chanspec_t) INVCHANSPEC; + return (u16) INVCHANSPEC; } int wlc_phy_txpower_get(struct brcms_phy_pub *ppi, uint *qdbm, bool *override) @@ -1539,10 +1450,8 @@ int wlc_phy_txpower_set(struct brcms_phy_pub *ppi, uint qdbm, bool override) if (!SCAN_INPROG_PHY(pi)) { bool suspend; - suspend = - (0 == - (R_REG(&pi->regs->maccontrol) & - MCTL_EN_MAC)); + suspend = (0 == (R_REG(&pi->regs->maccontrol) & + MCTL_EN_MAC)); if (!suspend) wlapi_suspend_mac_and_wait(pi->sh->physhim); @@ -1584,9 +1493,8 @@ wlc_phy_txpower_sromlimit(struct brcms_phy_pub *ppi, uint channel, u8 *min_pwr, txp_rate_idx = TXP_FIRST_OFDM; for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) { - if (channel == chan_info_all[i].chan) { + if (channel == chan_info_all[i].chan) break; - } } if (pi->hwtxpwr) { @@ -1620,7 +1528,8 @@ wlc_phy_txpower_sromlimit_max_get(struct brcms_phy_pub *ppi, uint chan, pactrl = 0; max_num_rate = ISNPHY(pi) ? TXP_NUM_RATES : - ISLCNPHY(pi) ? (TXP_LAST_SISO_MCS_20 + 1) : (TXP_LAST_OFDM + 1); + ISLCNPHY(pi) ? (TXP_LAST_SISO_MCS_20 + + 1) : (TXP_LAST_OFDM + 1); for (rate = 0; rate < max_num_rate; rate++) { @@ -1659,6 +1568,46 @@ u8 wlc_phy_txpower_get_target_max(struct brcms_phy_pub *ppi) return pi->tx_power_max; } +static s8 wlc_phy_env_measure_vbat(struct brcms_phy *pi) +{ + if (ISLCNPHY(pi)) + return wlc_lcnphy_vbatsense(pi, 0); + else + return 0; +} + +static s8 wlc_phy_env_measure_temperature(struct brcms_phy *pi) +{ + if (ISLCNPHY(pi)) + return wlc_lcnphy_tempsense_degree(pi, 0); + else + return 0; +} + +static void wlc_phy_upd_env_txpwr_rate_limits(struct brcms_phy *pi, u32 band) +{ + u8 i; + s8 temp, vbat; + + for (i = 0; i < TXP_NUM_RATES; i++) + pi->txpwr_env_limit[i] = BRCMS_TXPWR_MAX; + + vbat = wlc_phy_env_measure_vbat(pi); + temp = wlc_phy_env_measure_temperature(pi); + +} + +static s8 +wlc_user_txpwr_antport_to_rfport(struct brcms_phy *pi, uint chan, u32 band, + u8 rate) +{ + s8 offset = 0; + + if (!pi->user_txpwr_at_rfport) + return offset; + return offset; +} + void wlc_phy_txpower_recalc_target(struct brcms_phy *pi) { u8 maxtxpwr, mintxpwr, rate, pactrl; @@ -1669,9 +1618,9 @@ void wlc_phy_txpower_recalc_target(struct brcms_phy *pi) u8 tx_pwr_max_rate_ind = 0; u8 max_num_rate; u8 start_rate = 0; - chanspec_t chspec; + u16 chspec; u32 band = CHSPEC2BAND(pi->radio_chanspec); - initfn_t txpwr_recalc_fn = NULL; + void (*txpwr_recalc_fn)(struct brcms_phy *) = NULL; chspec = pi->radio_chanspec; if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_NONE) @@ -1690,8 +1639,8 @@ void wlc_phy_txpower_recalc_target(struct brcms_phy *pi) for (i = TXP_FIRST_SISO_MCS_20; i <= TXP_LAST_SISO_MCS_20; i++) { pi->tx_srom_max_rate_2g[i - 8] = - pi->tx_srom_max_2g - - ((offset_mcs & 0xf) * 2); + pi->tx_srom_max_2g - + ((offset_mcs & 0xf) * 2); offset_mcs >>= 4; } } else { @@ -1699,19 +1648,16 @@ void wlc_phy_txpower_recalc_target(struct brcms_phy *pi) for (i = TXP_FIRST_SISO_MCS_20; i <= TXP_LAST_SISO_MCS_20; i++) { pi->tx_srom_max_rate_2g[i - 8] = - pi->tx_srom_max_2g - - ((offset_mcs & 0xf) * 2); + pi->tx_srom_max_2g - + ((offset_mcs & 0xf) * 2); offset_mcs >>= 4; } } } -#if WL11N + max_num_rate = ((ISNPHY(pi)) ? (TXP_NUM_RATES) : ((ISLCNPHY(pi)) ? (TXP_LAST_SISO_MCS_20 + 1) : (TXP_LAST_OFDM + 1))); -#else - max_num_rate = ((ISNPHY(pi)) ? (TXP_NUM_RATES) : (TXP_LAST_OFDM + 1)); -#endif wlc_phy_upd_env_txpwr_rate_limits(pi, band); @@ -1719,11 +1665,12 @@ void wlc_phy_txpower_recalc_target(struct brcms_phy *pi) tx_pwr_target[rate] = pi->tx_user_target[rate]; - if (pi->user_txpwr_at_rfport) { + if (pi->user_txpwr_at_rfport) tx_pwr_target[rate] += - wlc_user_txpwr_antport_to_rfport(pi, target_chan, - band, rate); - } + wlc_user_txpwr_antport_to_rfport(pi, + target_chan, + band, + rate); { @@ -1734,7 +1681,7 @@ void wlc_phy_txpower_recalc_target(struct brcms_phy *pi) maxtxpwr = min(maxtxpwr, pi->txpwr_limit[rate]); maxtxpwr = - (maxtxpwr > pactrl) ? (maxtxpwr - pactrl) : 0; + (maxtxpwr > pactrl) ? (maxtxpwr - pactrl) : 0; maxtxpwr = (maxtxpwr > 6) ? (maxtxpwr - 6) : 0; @@ -1747,7 +1694,7 @@ void wlc_phy_txpower_recalc_target(struct brcms_phy *pi) } tx_pwr_target[rate] = - min(tx_pwr_target[rate], pi->txpwr_env_limit[rate]); + min(tx_pwr_target[rate], pi->txpwr_env_limit[rate]); if (tx_pwr_target[rate] > tx_pwr_max) tx_pwr_max_rate_ind = rate; @@ -1764,23 +1711,22 @@ void wlc_phy_txpower_recalc_target(struct brcms_phy *pi) pi->tx_power_target[rate] = tx_pwr_target[rate]; - if (!pi->hwpwrctrl || ISNPHY(pi)) { + if (!pi->hwpwrctrl || ISNPHY(pi)) pi->tx_power_offset[rate] = - pi->tx_power_max - pi->tx_power_target[rate]; - } else { + pi->tx_power_max - pi->tx_power_target[rate]; + else pi->tx_power_offset[rate] = - pi->tx_power_target[rate] - pi->tx_power_min; - } + pi->tx_power_target[rate] - pi->tx_power_min; } txpwr_recalc_fn = pi->pi_fptr.txpwrrecalc; if (txpwr_recalc_fn) - (*txpwr_recalc_fn) (pi); + (*txpwr_recalc_fn)(pi); } void wlc_phy_txpower_reg_limit_calc(struct brcms_phy *pi, struct txpwr_limits *txpwr, - chanspec_t chanspec) + u16 chanspec) { u8 tmp_txpwr_limit[2 * BRCMS_NUM_RATES_OFDM]; u8 *txpwr_ptr1 = NULL, *txpwr_ptr2 = NULL; @@ -1815,7 +1761,7 @@ wlc_phy_txpower_reg_limit_calc(struct brcms_phy *pi, struct txpwr_limits *txpwr, txpwr_ptr1 = txpwr->mcs_40_siso; txpwr_ptr2 = txpwr->ofdm_40_siso; rate_start_index = - WL_TX_POWER_OFDM40_SISO_FIRST; + WL_TX_POWER_OFDM40_SISO_FIRST; break; case 3: @@ -1825,18 +1771,21 @@ wlc_phy_txpower_reg_limit_calc(struct brcms_phy *pi, struct txpwr_limits *txpwr, break; } - for (rate2 = 0; rate2 < BRCMS_NUM_RATES_OFDM; rate2++) { + for (rate2 = 0; rate2 < BRCMS_NUM_RATES_OFDM; + rate2++) { tmp_txpwr_limit[rate2] = 0; tmp_txpwr_limit[BRCMS_NUM_RATES_OFDM + rate2] = - txpwr_ptr1[rate2]; + txpwr_ptr1[rate2]; } - wlc_phy_mcs_to_ofdm_powers_nphy(tmp_txpwr_limit, 0, - BRCMS_NUM_RATES_OFDM - 1, BRCMS_NUM_RATES_OFDM); + wlc_phy_mcs_to_ofdm_powers_nphy( + tmp_txpwr_limit, 0, + BRCMS_NUM_RATES_OFDM - + 1, BRCMS_NUM_RATES_OFDM); for (rate1 = rate_start_index, rate2 = 0; rate2 < BRCMS_NUM_RATES_OFDM; rate1++, rate2++) pi->txpwr_limit[rate1] = - min(txpwr_ptr2[rate2], - tmp_txpwr_limit[rate2]); + min(txpwr_ptr2[rate2], + tmp_txpwr_limit[rate2]); } for (k = 0; k < 4; k++) { @@ -1866,19 +1815,22 @@ wlc_phy_txpower_reg_limit_calc(struct brcms_phy *pi, struct txpwr_limits *txpwr, rate_start_index = WL_TX_POWER_MCS40_CDD_FIRST; break; } - for (rate2 = 0; rate2 < BRCMS_NUM_RATES_OFDM; rate2++) { + for (rate2 = 0; rate2 < BRCMS_NUM_RATES_OFDM; + rate2++) { tmp_txpwr_limit[rate2] = 0; tmp_txpwr_limit[BRCMS_NUM_RATES_OFDM + rate2] = - txpwr_ptr1[rate2]; + txpwr_ptr1[rate2]; } - wlc_phy_ofdm_to_mcs_powers_nphy(tmp_txpwr_limit, 0, - BRCMS_NUM_RATES_OFDM - 1, BRCMS_NUM_RATES_OFDM); + wlc_phy_ofdm_to_mcs_powers_nphy( + tmp_txpwr_limit, 0, + BRCMS_NUM_RATES_OFDM - + 1, BRCMS_NUM_RATES_OFDM); for (rate1 = rate_start_index, rate2 = 0; rate2 < BRCMS_NUM_RATES_MCS_1_STREAM; rate1++, rate2++) pi->txpwr_limit[rate1] = - min(txpwr_ptr2[rate2], - tmp_txpwr_limit[rate2]); + min(txpwr_ptr2[rate2], + tmp_txpwr_limit[rate2]); } for (k = 0; k < 2; k++) { @@ -1922,10 +1874,10 @@ wlc_phy_txpower_reg_limit_calc(struct brcms_phy *pi, struct txpwr_limits *txpwr, pi->txpwr_limit[WL_TX_POWER_MCS_32] = txpwr->mcs32; pi->txpwr_limit[WL_TX_POWER_MCS40_CDD_FIRST] = - min(pi->txpwr_limit[WL_TX_POWER_MCS40_CDD_FIRST], - pi->txpwr_limit[WL_TX_POWER_MCS_32]); + min(pi->txpwr_limit[WL_TX_POWER_MCS40_CDD_FIRST], + pi->txpwr_limit[WL_TX_POWER_MCS_32]); pi->txpwr_limit[WL_TX_POWER_MCS_32] = - pi->txpwr_limit[WL_TX_POWER_MCS40_CDD_FIRST]; + pi->txpwr_limit[WL_TX_POWER_MCS40_CDD_FIRST]; } } @@ -1975,7 +1927,7 @@ void wlc_phy_runbist_config(struct brcms_phy_pub *ppi, bool start_end) void wlc_phy_txpower_limit_set(struct brcms_phy_pub *ppi, struct txpwr_limits *txpwr, - chanspec_t chanspec) + u16 chanspec) { struct brcms_phy *pi = (struct brcms_phy *) ppi; @@ -2016,9 +1968,8 @@ void wlc_phy_bf_preempt_enable(struct brcms_phy_pub *pih, bool bf_preempt) void wlc_phy_txpower_update_shm(struct brcms_phy *pi) { int j; - if (ISNPHY(pi)) { + if (ISNPHY(pi)) return; - } if (!pi->sh->clk) return; @@ -2040,9 +1991,9 @@ void wlc_phy_txpower_update_shm(struct brcms_phy *pi) const u8 ucode_ofdm_rates[] = { 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c }; - offset = wlapi_bmac_rate_shm_offset(pi->sh->physhim, - ucode_ofdm_rates[j - - TXP_FIRST_OFDM]); + offset = wlapi_bmac_rate_shm_offset( + pi->sh->physhim, + ucode_ofdm_rates[j - TXP_FIRST_OFDM]); wlapi_bmac_write_shm(pi->sh->physhim, offset + 6, pi->tx_power_offset[j]); wlapi_bmac_write_shm(pi->sh->physhim, offset + 14, @@ -2056,11 +2007,11 @@ void wlc_phy_txpower_update_shm(struct brcms_phy *pi) for (i = TXP_FIRST_OFDM; i <= TXP_LAST_OFDM; i++) pi->tx_power_offset[i] = - (u8) roundup(pi->tx_power_offset[i], 8); + (u8) roundup(pi->tx_power_offset[i], 8); wlapi_bmac_write_shm(pi->sh->physhim, M_OFDM_OFFSET, - (u16) ((pi-> - tx_power_offset[TXP_FIRST_OFDM] - + 7) >> 3)); + (u16) + ((pi->tx_power_offset[TXP_FIRST_OFDM] + + 7) >> 3)); } } @@ -2068,48 +2019,38 @@ bool wlc_phy_txpower_hw_ctrl_get(struct brcms_phy_pub *ppi) { struct brcms_phy *pi = (struct brcms_phy *) ppi; - if (ISNPHY(pi)) { + if (ISNPHY(pi)) return pi->nphy_txpwrctrl; - } else { + else return pi->hwpwrctrl; - } } void wlc_phy_txpower_hw_ctrl_set(struct brcms_phy_pub *ppi, bool hwpwrctrl) { struct brcms_phy *pi = (struct brcms_phy *) ppi; - bool cur_hwpwrctrl = pi->hwpwrctrl; bool suspend; - if (!pi->hwpwrctrl_capable) { + if (!pi->hwpwrctrl_capable) return; - } pi->hwpwrctrl = hwpwrctrl; pi->nphy_txpwrctrl = hwpwrctrl; pi->txpwrctrl = hwpwrctrl; if (ISNPHY(pi)) { - suspend = - (0 == - (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); + suspend = (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); if (!suspend) wlapi_suspend_mac_and_wait(pi->sh->physhim); wlc_phy_txpwrctrl_enable_nphy(pi, pi->nphy_txpwrctrl); - if (pi->nphy_txpwrctrl == PHY_TPC_HW_OFF) { + if (pi->nphy_txpwrctrl == PHY_TPC_HW_OFF) wlc_phy_txpwr_fixpower_nphy(pi); - } else { - + else mod_phy_reg(pi, 0x1e7, (0x7f << 0), pi->saved_txpwr_idx); - } if (!suspend) wlapi_enable_mac(pi->sh->physhim); - } else if (hwpwrctrl != cur_hwpwrctrl) { - - return; } } @@ -2125,8 +2066,6 @@ void wlc_phy_txpower_ipa_upd(struct brcms_phy *pi) } } -static u32 wlc_phy_txpower_est_power_nphy(struct brcms_phy *pi); - static u32 wlc_phy_txpower_est_power_nphy(struct brcms_phy *pi) { s16 tx0_status, tx1_status; @@ -2137,42 +2076,31 @@ static u32 wlc_phy_txpower_est_power_nphy(struct brcms_phy *pi) estPower1 = read_phy_reg(pi, 0x118); estPower2 = read_phy_reg(pi, 0x119); - if ((estPower1 & (0x1 << 8)) - == (0x1 << 8)) { - pwr0 = (u8) (estPower1 & (0xff << 0)) - >> 0; - } else { + if ((estPower1 & (0x1 << 8)) == (0x1 << 8)) + pwr0 = (u8) (estPower1 & (0xff << 0)) >> 0; + else pwr0 = 0x80; - } - if ((estPower2 & (0x1 << 8)) - == (0x1 << 8)) { - pwr1 = (u8) (estPower2 & (0xff << 0)) - >> 0; - } else { + if ((estPower2 & (0x1 << 8)) == (0x1 << 8)) + pwr1 = (u8) (estPower2 & (0xff << 0)) >> 0; + else pwr1 = 0x80; - } tx0_status = read_phy_reg(pi, 0x1ed); tx1_status = read_phy_reg(pi, 0x1ee); - if ((tx0_status & (0x1 << 15)) - == (0x1 << 15)) { - adj_pwr0 = (u8) (tx0_status & (0xff << 0)) - >> 0; - } else { + if ((tx0_status & (0x1 << 15)) == (0x1 << 15)) + adj_pwr0 = (u8) (tx0_status & (0xff << 0)) >> 0; + else adj_pwr0 = 0x80; - } - if ((tx1_status & (0x1 << 15)) - == (0x1 << 15)) { - adj_pwr1 = (u8) (tx1_status & (0xff << 0)) - >> 0; - } else { + if ((tx1_status & (0x1 << 15)) == (0x1 << 15)) + adj_pwr1 = (u8) (tx1_status & (0xff << 0)) >> 0; + else adj_pwr1 = 0x80; - } - est_pwr = - (u32) ((pwr0 << 24) | (pwr1 << 16) | (adj_pwr0 << 8) | adj_pwr1); + est_pwr = (u32) ((pwr0 << 24) | (pwr1 << 16) | (adj_pwr0 << 8) | + adj_pwr1); + return est_pwr; } @@ -2193,7 +2121,7 @@ wlc_phy_txpower_get_current(struct brcms_phy_pub *ppi, struct tx_power *power, power->flags |= (WL_TX_POWER_F_MIMO); if (pi->nphy_txpwrctrl == PHY_TPC_HW_ON) power->flags |= - (WL_TX_POWER_F_ENABLED | WL_TX_POWER_F_HW); + (WL_TX_POWER_F_ENABLED | WL_TX_POWER_F_HW); } else if (ISLCNPHY(pi)) { power->rf_cores = 1; power->flags |= (WL_TX_POWER_F_SISO); @@ -2256,16 +2184,18 @@ wlc_phy_txpower_get_current(struct brcms_phy_pub *ppi, struct tx_power *power, power->tx_power_max[1] = pi->tx_power_max; power->tx_power_max_rate_ind[0] = - pi->tx_power_max_rate_ind; + pi->tx_power_max_rate_ind; power->tx_power_max_rate_ind[1] = - pi->tx_power_max_rate_ind; + pi->tx_power_max_rate_ind; if (wlc_phy_tpc_isenabled_lcnphy(pi)) power->flags |= - (WL_TX_POWER_F_HW | WL_TX_POWER_F_ENABLED); + (WL_TX_POWER_F_HW | + WL_TX_POWER_F_ENABLED); else power->flags &= - ~(WL_TX_POWER_F_HW | WL_TX_POWER_F_ENABLED); + ~(WL_TX_POWER_F_HW | + WL_TX_POWER_F_ENABLED); wlc_lcnphy_get_tssi(pi, (s8 *) &power->est_Pout[0], (s8 *) &power->est_Pout_cck); @@ -2304,16 +2234,13 @@ void wlc_phy_ant_rxdiv_set(struct brcms_phy_pub *ppi, u8 val) BRCM_BAND_ALL); } - if (ISNPHY(pi)) { - + if (ISNPHY(pi)) return; - } if (!pi->sh->clk) return; - suspend = - (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); + suspend = (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); if (!suspend) wlapi_suspend_mac_and_wait(pi->sh->physhim); @@ -2357,10 +2284,127 @@ wlc_phy_noise_calc_phy(struct brcms_phy *pi, u32 *cmplx_pwr, s8 *pwr_ant) pwr_ant[i] = cmplx_pwr_dbm[i]; } pi->nphy_noise_index = - MODINC_POW2(pi->nphy_noise_index, PHY_NOISE_WINDOW_SZ); + MODINC_POW2(pi->nphy_noise_index, PHY_NOISE_WINDOW_SZ); return true; } +static void wlc_phy_noise_cb(struct brcms_phy *pi, u8 channel, s8 noise_dbm) +{ + if (!pi->phynoise_state) + return; + + if (pi->phynoise_state & PHY_NOISE_STATE_MON) { + if (pi->phynoise_chan_watchdog == channel) { + pi->sh->phy_noise_window[pi->sh->phy_noise_index] = + noise_dbm; + pi->sh->phy_noise_index = + MODINC(pi->sh->phy_noise_index, MA_WINDOW_SZ); + } + pi->phynoise_state &= ~PHY_NOISE_STATE_MON; + } + + if (pi->phynoise_state & PHY_NOISE_STATE_EXTERNAL) + pi->phynoise_state &= ~PHY_NOISE_STATE_EXTERNAL; + +} + +static s8 wlc_phy_noise_read_shmem(struct brcms_phy *pi) +{ + u32 cmplx_pwr[PHY_CORE_MAX]; + s8 noise_dbm_ant[PHY_CORE_MAX]; + u16 lo, hi; + u32 cmplx_pwr_tot = 0; + s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY; + u8 idx, core; + + memset((u8 *) cmplx_pwr, 0, sizeof(cmplx_pwr)); + memset((u8 *) noise_dbm_ant, 0, sizeof(noise_dbm_ant)); + + for (idx = 0, core = 0; core < pi->pubpi.phy_corenum; idx += 2, + core++) { + lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP(idx)); + hi = wlapi_bmac_read_shm(pi->sh->physhim, + M_PWRIND_MAP(idx + 1)); + cmplx_pwr[core] = (hi << 16) + lo; + cmplx_pwr_tot += cmplx_pwr[core]; + if (cmplx_pwr[core] == 0) + noise_dbm_ant[core] = PHY_NOISE_FIXED_VAL_NPHY; + else + cmplx_pwr[core] >>= PHY_NOISE_SAMPLE_LOG_NUM_UCODE; + } + + if (cmplx_pwr_tot != 0) + wlc_phy_noise_calc_phy(pi, cmplx_pwr, noise_dbm_ant); + + for (core = 0; core < pi->pubpi.phy_corenum; core++) { + pi->nphy_noise_win[core][pi->nphy_noise_index] = + noise_dbm_ant[core]; + + if (noise_dbm_ant[core] > noise_dbm) + noise_dbm = noise_dbm_ant[core]; + } + pi->nphy_noise_index = + MODINC_POW2(pi->nphy_noise_index, PHY_NOISE_WINDOW_SZ); + + return noise_dbm; + +} + +void wlc_phy_noise_sample_intr(struct brcms_phy_pub *pih) +{ + struct brcms_phy *pi = (struct brcms_phy *) pih; + u16 jssi_aux; + u8 channel = 0; + s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY; + + if (ISLCNPHY(pi)) { + u32 cmplx_pwr, cmplx_pwr0, cmplx_pwr1; + u16 lo, hi; + s32 pwr_offset_dB, gain_dB; + u16 status_0, status_1; + + jssi_aux = wlapi_bmac_read_shm(pi->sh->physhim, M_JSSI_AUX); + channel = jssi_aux & D11_CURCHANNEL_MAX; + + lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP0); + hi = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP1); + cmplx_pwr0 = (hi << 16) + lo; + + lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP2); + hi = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP3); + cmplx_pwr1 = (hi << 16) + lo; + cmplx_pwr = (cmplx_pwr0 + cmplx_pwr1) >> 6; + + status_0 = 0x44; + status_1 = wlapi_bmac_read_shm(pi->sh->physhim, M_JSSI_0); + if ((cmplx_pwr > 0 && cmplx_pwr < 500) + && ((status_1 & 0xc000) == 0x4000)) { + + wlc_phy_compute_dB(&cmplx_pwr, &noise_dbm, + pi->pubpi.phy_corenum); + pwr_offset_dB = (read_phy_reg(pi, 0x434) & 0xFF); + if (pwr_offset_dB > 127) + pwr_offset_dB -= 256; + + noise_dbm += (s8) (pwr_offset_dB - 30); + + gain_dB = (status_0 & 0x1ff); + noise_dbm -= (s8) (gain_dB); + } else { + noise_dbm = PHY_NOISE_FIXED_VAL_LCNPHY; + } + } else if (ISNPHY(pi)) { + + jssi_aux = wlapi_bmac_read_shm(pi->sh->physhim, M_JSSI_AUX); + channel = jssi_aux & D11_CURCHANNEL_MAX; + + noise_dbm = wlc_phy_noise_read_shmem(pi); + } + + wlc_phy_noise_cb(pi, channel, noise_dbm); + +} + static void wlc_phy_noise_sample_request(struct brcms_phy_pub *pih, u8 reason, u8 ch) { @@ -2369,20 +2413,13 @@ wlc_phy_noise_sample_request(struct brcms_phy_pub *pih, u8 reason, u8 ch) bool sampling_in_progress = (pi->phynoise_state != 0); bool wait_for_intr = true; - if (NORADIO_ENAB(pi->pubpi)) { - return; - } - switch (reason) { case PHY_NOISE_SAMPLE_MON: - pi->phynoise_chan_watchdog = ch; pi->phynoise_state |= PHY_NOISE_STATE_MON; - break; case PHY_NOISE_SAMPLE_EXTERNAL: - pi->phynoise_state |= PHY_NOISE_STATE_EXTERNAL; break; @@ -2398,15 +2435,13 @@ wlc_phy_noise_sample_request(struct brcms_phy_pub *pih, u8 reason, u8 ch) if (pi->phy_fixed_noise) { if (ISNPHY(pi)) { pi->nphy_noise_win[WL_ANT_IDX_1][pi->nphy_noise_index] = - PHY_NOISE_FIXED_VAL_NPHY; + PHY_NOISE_FIXED_VAL_NPHY; pi->nphy_noise_win[WL_ANT_IDX_2][pi->nphy_noise_index] = - PHY_NOISE_FIXED_VAL_NPHY; + PHY_NOISE_FIXED_VAL_NPHY; pi->nphy_noise_index = MODINC_POW2(pi->nphy_noise_index, PHY_NOISE_WINDOW_SZ); - noise_dbm = PHY_NOISE_FIXED_VAL_NPHY; } else { - noise_dbm = PHY_NOISE_FIXED_VAL; } @@ -2469,15 +2504,14 @@ wlc_phy_noise_sample_request(struct brcms_phy_pub *pih, u8 reason, u8 ch) wlapi_enable_mac(pi->sh->physhim); for (i = 0; i < pi->pubpi.phy_corenum; i++) - cmplx_pwr[i] = - (est[i].i_pwr + - est[i].q_pwr) >> log_num_samps; + cmplx_pwr[i] = (est[i].i_pwr + est[i].q_pwr) >> + log_num_samps; wlc_phy_noise_calc_phy(pi, cmplx_pwr, noise_dbm_ant); for (i = 0; i < pi->pubpi.phy_corenum; i++) { pi->nphy_noise_win[i][pi->nphy_noise_index] = - noise_dbm_ant[i]; + noise_dbm_ant[i]; if (noise_dbm_ant[i] > noise_dbm) noise_dbm = noise_dbm_ant[i]; @@ -2489,7 +2523,7 @@ wlc_phy_noise_sample_request(struct brcms_phy_pub *pih, u8 reason, u8 ch) } } - done: +done: if (!wait_for_intr) wlc_phy_noise_cb(pi, ch, noise_dbm); @@ -2505,123 +2539,6 @@ void wlc_phy_noise_sample_request_external(struct brcms_phy_pub *pih) wlc_phy_noise_sample_request(pih, PHY_NOISE_SAMPLE_EXTERNAL, channel); } -static void wlc_phy_noise_cb(struct brcms_phy *pi, u8 channel, s8 noise_dbm) -{ - if (!pi->phynoise_state) - return; - - if (pi->phynoise_state & PHY_NOISE_STATE_MON) { - if (pi->phynoise_chan_watchdog == channel) { - pi->sh->phy_noise_window[pi->sh->phy_noise_index] = - noise_dbm; - pi->sh->phy_noise_index = - MODINC(pi->sh->phy_noise_index, MA_WINDOW_SZ); - } - pi->phynoise_state &= ~PHY_NOISE_STATE_MON; - } - - if (pi->phynoise_state & PHY_NOISE_STATE_EXTERNAL) { - pi->phynoise_state &= ~PHY_NOISE_STATE_EXTERNAL; - } - -} - -static s8 wlc_phy_noise_read_shmem(struct brcms_phy *pi) -{ - u32 cmplx_pwr[PHY_CORE_MAX]; - s8 noise_dbm_ant[PHY_CORE_MAX]; - u16 lo, hi; - u32 cmplx_pwr_tot = 0; - s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY; - u8 idx, core; - - memset((u8 *) cmplx_pwr, 0, sizeof(cmplx_pwr)); - memset((u8 *) noise_dbm_ant, 0, sizeof(noise_dbm_ant)); - - for (idx = 0, core = 0; core < pi->pubpi.phy_corenum; idx += 2, core++) { - lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP(idx)); - hi = wlapi_bmac_read_shm(pi->sh->physhim, - M_PWRIND_MAP(idx + 1)); - cmplx_pwr[core] = (hi << 16) + lo; - cmplx_pwr_tot += cmplx_pwr[core]; - if (cmplx_pwr[core] == 0) { - noise_dbm_ant[core] = PHY_NOISE_FIXED_VAL_NPHY; - } else - cmplx_pwr[core] >>= PHY_NOISE_SAMPLE_LOG_NUM_UCODE; - } - - if (cmplx_pwr_tot != 0) - wlc_phy_noise_calc_phy(pi, cmplx_pwr, noise_dbm_ant); - - for (core = 0; core < pi->pubpi.phy_corenum; core++) { - pi->nphy_noise_win[core][pi->nphy_noise_index] = - noise_dbm_ant[core]; - - if (noise_dbm_ant[core] > noise_dbm) - noise_dbm = noise_dbm_ant[core]; - } - pi->nphy_noise_index = - MODINC_POW2(pi->nphy_noise_index, PHY_NOISE_WINDOW_SZ); - - return noise_dbm; - -} - -void wlc_phy_noise_sample_intr(struct brcms_phy_pub *pih) -{ - struct brcms_phy *pi = (struct brcms_phy *) pih; - u16 jssi_aux; - u8 channel = 0; - s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY; - - if (ISLCNPHY(pi)) { - u32 cmplx_pwr, cmplx_pwr0, cmplx_pwr1; - u16 lo, hi; - s32 pwr_offset_dB, gain_dB; - u16 status_0, status_1; - - jssi_aux = wlapi_bmac_read_shm(pi->sh->physhim, M_JSSI_AUX); - channel = jssi_aux & D11_CURCHANNEL_MAX; - - lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP0); - hi = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP1); - cmplx_pwr0 = (hi << 16) + lo; - - lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP2); - hi = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP3); - cmplx_pwr1 = (hi << 16) + lo; - cmplx_pwr = (cmplx_pwr0 + cmplx_pwr1) >> 6; - - status_0 = 0x44; - status_1 = wlapi_bmac_read_shm(pi->sh->physhim, M_JSSI_0); - if ((cmplx_pwr > 0 && cmplx_pwr < 500) - && ((status_1 & 0xc000) == 0x4000)) { - - wlc_phy_compute_dB(&cmplx_pwr, &noise_dbm, - pi->pubpi.phy_corenum); - pwr_offset_dB = (read_phy_reg(pi, 0x434) & 0xFF); - if (pwr_offset_dB > 127) - pwr_offset_dB -= 256; - - noise_dbm += (s8) (pwr_offset_dB - 30); - - gain_dB = (status_0 & 0x1ff); - noise_dbm -= (s8) (gain_dB); - } else { - noise_dbm = PHY_NOISE_FIXED_VAL_LCNPHY; - } - } else if (ISNPHY(pi)) { - - jssi_aux = wlapi_bmac_read_shm(pi->sh->physhim, M_JSSI_AUX); - channel = jssi_aux & D11_CURCHANNEL_MAX; - - noise_dbm = wlc_phy_noise_read_shmem(pi); - } - - wlc_phy_noise_cb(pi, channel, noise_dbm); - -} - s8 lcnphy_gain_index_offset_for_pkt_rssi[] = { 8, 8, @@ -2678,19 +2595,14 @@ void wlc_phy_compute_dB(u32 *cmplx_pwr, s8 *p_cmplx_pwr_dB, u8 core) } } -void wlc_phy_rssi_compute(struct brcms_phy_pub *pih, void *ctx) +void wlc_phy_rssi_compute(struct brcms_phy_pub *pih, + struct brcms_d11rxhdr *wlc_rxhdr) { - struct brcms_d11rxhdr *wlc_rxhdr = (struct brcms_d11rxhdr *) ctx; struct d11rxhdr *rxh = &wlc_rxhdr->rxhdr; int rssi = le16_to_cpu(rxh->PhyRxStatus_1) & PRXS1_JSSI_MASK; uint radioid = pih->radioid; struct brcms_phy *pi = (struct brcms_phy *) pih; - if (NORADIO_ENAB(pi->pubpi)) { - rssi = BRCMS_RSSI_INVALID; - goto end; - } - if ((pi->sh->corerev >= 11) && !(le16_to_cpu(rxh->RxStatus2) & RXS_PHYRXST_VALID)) { rssi = BRCMS_RSSI_INVALID; @@ -2715,7 +2627,6 @@ void wlc_phy_rssi_compute(struct brcms_phy_pub *pih, void *ctx) } if (ISLCNPHY(pi)) { - if (rssi > 127) rssi -= 256; } else if (radioid == BCM2055_ID || radioid == BCM2056_ID @@ -2723,7 +2634,7 @@ void wlc_phy_rssi_compute(struct brcms_phy_pub *pih, void *ctx) rssi = wlc_phy_rssi_compute_nphy(pi, wlc_rxhdr); } - end: +end: wlc_rxhdr->rssi = (s8) rssi; } @@ -2757,28 +2668,22 @@ void wlc_phy_watchdog(struct brcms_phy_pub *pih) if (!pi->watchdog_override) return; - if (!(SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi))) { + if (!(SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi))) wlc_phy_noise_sample_request((struct brcms_phy_pub *) pi, PHY_NOISE_SAMPLE_MON, CHSPEC_CHANNEL(pi-> radio_chanspec)); - } - if (pi->phynoise_state && (pi->sh->now - pi->phynoise_now) > 5) { + if (pi->phynoise_state && (pi->sh->now - pi->phynoise_now) > 5) pi->phynoise_state = 0; - } if ((!pi->phycal_txpower) || ((pi->sh->now - pi->phycal_txpower) >= pi->sh->fast_timer)) { - if (!SCAN_INPROG_PHY(pi) && wlc_phy_cal_txpower_recalc_sw(pi)) { + if (!SCAN_INPROG_PHY(pi) && wlc_phy_cal_txpower_recalc_sw(pi)) pi->phycal_txpower = pi->sh->now; - } } - if (NORADIO_ENAB(pi->pubpi)) - return; - if ((SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi) || ASSOC_INPROG_PHY(pi))) return; @@ -2800,8 +2705,9 @@ void wlc_phy_watchdog(struct brcms_phy_pub *pih) ((pi->sh->now - pi->phy_lastcal) >= pi->sh->glacial_timer)) { if (!(SCAN_RM_IN_PROGRESS(pi) || ASSOC_INPROG_PHY(pi))) - wlc_lcnphy_calib_modes(pi, - LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL); + wlc_lcnphy_calib_modes( + pi, + LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL); if (! (SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi) || ASSOC_INPROG_PHY(pi) @@ -2819,13 +2725,12 @@ void wlc_phy_BSSinit(struct brcms_phy_pub *pih, bool bonlyap, int rssi) uint i; uint k; - for (i = 0; i < MA_WINDOW_SZ; i++) { + for (i = 0; i < MA_WINDOW_SZ; i++) pi->sh->phy_noise_window[i] = (s8) (rssi & 0xff); - } if (ISLCNPHY(pi)) { for (i = 0; i < MA_WINDOW_SZ; i++) pi->sh->phy_noise_window[i] = - PHY_NOISE_FIXED_VAL_LCNPHY; + PHY_NOISE_FIXED_VAL_LCNPHY; } pi->sh->phy_noise_index = 0; @@ -2848,69 +2753,6 @@ wlc_phy_papd_decode_epsilon(u32 epsilon, s32 *eps_real, s32 *eps_imag) *eps_real -= 0x2000; } -static const fixed AtanTbl[] = { - 2949120, - 1740967, - 919879, - 466945, - 234379, - 117304, - 58666, - 29335, - 14668, - 7334, - 3667, - 1833, - 917, - 458, - 229, - 115, - 57, - 29 -}; - -void wlc_phy_cordic(fixed theta, cs32 *val) -{ - fixed angle, valtmp; - unsigned iter; - int signx = 1; - int signtheta; - - val[0].i = CORDIC_AG; - val[0].q = 0; - angle = 0; - - signtheta = (theta < 0) ? -1 : 1; - theta = - ((theta + FIXED(180) * signtheta) % FIXED(360)) - - FIXED(180) * signtheta; - - if (FLOAT(theta) > 90) { - theta -= FIXED(180); - signx = -1; - } else if (FLOAT(theta) < -90) { - theta += FIXED(180); - signx = -1; - } - - for (iter = 0; iter < CORDIC_NI; iter++) { - if (theta > angle) { - valtmp = val[0].i - (val[0].q >> iter); - val[0].q = (val[0].i >> iter) + val[0].q; - val[0].i = valtmp; - angle += AtanTbl[iter]; - } else { - valtmp = val[0].i + (val[0].q >> iter); - val[0].q = -(val[0].i >> iter) + val[0].q; - val[0].i = valtmp; - angle -= AtanTbl[iter]; - } - } - - val[0].i = val[0].i * signx; - val[0].q = val[0].q * signx; -} - void wlc_phy_cal_perical_mphase_reset(struct brcms_phy *pi) { wlapi_del_timer(pi->sh->physhim, pi->phycal_timer); @@ -2954,11 +2796,12 @@ void wlc_phy_cal_perical(struct brcms_phy_pub *pih, u8 reason) case PHY_PERICAL_PHYINIT: if (pi->nphy_perical == PHY_PERICAL_MPHASE) { - if (PHY_PERICAL_MPHASE_PENDING(pi)) { + if (PHY_PERICAL_MPHASE_PENDING(pi)) wlc_phy_cal_perical_mphase_reset(pi); - } - wlc_phy_cal_perical_mphase_schedule(pi, - PHY_PERICAL_INIT_DELAY); + + wlc_phy_cal_perical_mphase_schedule( + pi, + PHY_PERICAL_INIT_DELAY); } break; @@ -2966,17 +2809,16 @@ void wlc_phy_cal_perical(struct brcms_phy_pub *pih, u8 reason) case PHY_PERICAL_START_IBSS: case PHY_PERICAL_UP_BSS: if ((pi->nphy_perical == PHY_PERICAL_MPHASE) && - PHY_PERICAL_MPHASE_PENDING(pi)) { + PHY_PERICAL_MPHASE_PENDING(pi)) wlc_phy_cal_perical_mphase_reset(pi); - } pi->first_cal_after_assoc = true; pi->cal_type_override = PHY_PERICAL_FULL; - if (pi->phycal_tempdelta) { + if (pi->phycal_tempdelta) pi->nphy_lastcal_temp = wlc_phy_tempsense_nphy(pi); - } + wlc_phy_cal_perical_nphy_run(pi, PHY_PERICAL_FULL); break; @@ -2984,26 +2826,24 @@ void wlc_phy_cal_perical(struct brcms_phy_pub *pih, u8 reason) if (pi->phycal_tempdelta) { nphy_currtemp = wlc_phy_tempsense_nphy(pi); delta_temp = - (nphy_currtemp > pi->nphy_lastcal_temp) ? - nphy_currtemp - pi->nphy_lastcal_temp : - pi->nphy_lastcal_temp - nphy_currtemp; + (nphy_currtemp > pi->nphy_lastcal_temp) ? + nphy_currtemp - pi->nphy_lastcal_temp : + pi->nphy_lastcal_temp - nphy_currtemp; if ((delta_temp < (s16) pi->phycal_tempdelta) && (pi->nphy_txiqlocal_chanspec == - pi->radio_chanspec)) { + pi->radio_chanspec)) do_periodic_cal = false; - } else { + else pi->nphy_lastcal_temp = nphy_currtemp; - } } if (do_periodic_cal) { - if (pi->nphy_perical == PHY_PERICAL_MPHASE) { - if (!PHY_PERICAL_MPHASE_PENDING(pi)) - wlc_phy_cal_perical_mphase_schedule(pi, - PHY_PERICAL_WDOG_DELAY); + wlc_phy_cal_perical_mphase_schedule( + pi, + PHY_PERICAL_WDOG_DELAY); } else if (pi->nphy_perical == PHY_PERICAL_SPHASE) wlc_phy_cal_perical_nphy_run(pi, PHY_PERICAL_AUTO); @@ -3049,9 +2889,9 @@ void wlc_phy_stf_chain_set(struct brcms_phy_pub *pih, u8 txchain, u8 rxchain) pi->sh->phytxchain = txchain; - if (ISNPHY(pi)) { + if (ISNPHY(pi)) wlc_phy_rxcore_setstate_nphy(pih, rxchain); - } + pi->pubpi.phy_corenum = (u8) PHY_BITSCNT(pi->sh->phyrxchain); } @@ -3095,17 +2935,17 @@ u8 wlc_phy_stf_chain_active_get(struct brcms_phy_pub *pih) return active_bitmap; } -s8 wlc_phy_stf_ssmode_get(struct brcms_phy_pub *pih, chanspec_t chanspec) +s8 wlc_phy_stf_ssmode_get(struct brcms_phy_pub *pih, u16 chanspec) { struct brcms_phy *pi = (struct brcms_phy *) pih; u8 siso_mcs_id, cdd_mcs_id; siso_mcs_id = - (CHSPEC_IS40(chanspec)) ? TXP_FIRST_MCS_40_SISO : - TXP_FIRST_MCS_20_SISO; + (CHSPEC_IS40(chanspec)) ? TXP_FIRST_MCS_40_SISO : + TXP_FIRST_MCS_20_SISO; cdd_mcs_id = - (CHSPEC_IS40(chanspec)) ? TXP_FIRST_MCS_40_CDD : - TXP_FIRST_MCS_20_CDD; + (CHSPEC_IS40(chanspec)) ? TXP_FIRST_MCS_40_CDD : + TXP_FIRST_MCS_20_CDD; if (pi->tx_power_target[siso_mcs_id] > (pi->tx_power_target[cdd_mcs_id] + 12)) @@ -3133,12 +2973,13 @@ void wlc_lcnphy_epa_switch(struct brcms_phy *pi, bool mode) } ai_corereg(pi->sh->sih, SI_CC_IDX, - offsetof(chipcregs_t, gpiocontrol), ~0x0, - 0x0); + offsetof(struct chipcregs, gpiocontrol), + ~0x0, 0x0); ai_corereg(pi->sh->sih, SI_CC_IDX, - offsetof(chipcregs_t, gpioout), 0x40, 0x40); + offsetof(struct chipcregs, gpioout), 0x40, + 0x40); ai_corereg(pi->sh->sih, SI_CC_IDX, - offsetof(chipcregs_t, gpioouten), 0x40, + offsetof(struct chipcregs, gpioouten), 0x40, 0x40); } else { mod_phy_reg(pi, 0x44c, (0x1 << 2), (0) << 2); @@ -3146,56 +2987,18 @@ void wlc_lcnphy_epa_switch(struct brcms_phy *pi, bool mode) mod_phy_reg(pi, 0x44d, (0x1 << 2), (0) << 2); ai_corereg(pi->sh->sih, SI_CC_IDX, - offsetof(chipcregs_t, gpioout), 0x40, 0x00); + offsetof(struct chipcregs, gpioout), 0x40, + 0x00); ai_corereg(pi->sh->sih, SI_CC_IDX, - offsetof(chipcregs_t, gpioouten), 0x40, 0x0); + offsetof(struct chipcregs, gpioouten), 0x40, + 0x0); ai_corereg(pi->sh->sih, SI_CC_IDX, - offsetof(chipcregs_t, gpiocontrol), ~0x0, - 0x40); + offsetof(struct chipcregs, gpiocontrol), + ~0x0, 0x40); } } } -static s8 -wlc_user_txpwr_antport_to_rfport(struct brcms_phy *pi, uint chan, u32 band, - u8 rate) -{ - s8 offset = 0; - - if (!pi->user_txpwr_at_rfport) - return offset; - return offset; -} - -static s8 wlc_phy_env_measure_vbat(struct brcms_phy *pi) -{ - if (ISLCNPHY(pi)) - return wlc_lcnphy_vbatsense(pi, 0); - else - return 0; -} - -static s8 wlc_phy_env_measure_temperature(struct brcms_phy *pi) -{ - if (ISLCNPHY(pi)) - return wlc_lcnphy_tempsense_degree(pi, 0); - else - return 0; -} - -static void wlc_phy_upd_env_txpwr_rate_limits(struct brcms_phy *pi, u32 band) -{ - u8 i; - s8 temp, vbat; - - for (i = 0; i < TXP_NUM_RATES; i++) - pi->txpwr_env_limit[i] = BRCMS_TXPWR_MAX; - - vbat = wlc_phy_env_measure_vbat(pi); - temp = wlc_phy_env_measure_temperature(pi); - -} - void wlc_phy_ldpc_override_set(struct brcms_phy_pub *ppi, bool ldpc) { return; @@ -3208,7 +3011,7 @@ wlc_phy_get_pwrdet_offsets(struct brcms_phy *pi, s8 *cckoffset, s8 *ofdmoffset) *ofdmoffset = 0; } -s8 wlc_phy_upd_rssi_offset(struct brcms_phy *pi, s8 rssi, chanspec_t chanspec) +s8 wlc_phy_upd_rssi_offset(struct brcms_phy *pi, s8 rssi, u16 chanspec) { return rssi; diff --git a/drivers/staging/brcm80211/brcmsmac/phy/phy_hal.h b/drivers/staging/brcm80211/brcmsmac/phy/phy_hal.h index e27d9e9..1dbfaa3 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/phy_hal.h +++ b/drivers/staging/brcm80211/brcmsmac/phy/phy_hal.h @@ -103,6 +103,9 @@ #define BRCMS_RSSI_INVALID 0 /* invalid RSSI value */ +struct d11regs; +struct phy_shim_info; + struct txpwr_limits { u8 cck[BRCMS_NUM_RATES_CCK]; u8 ofdm[BRCMS_NUM_RATES_OFDM]; @@ -126,40 +129,43 @@ struct txpwr_limits { 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 */ + u16 chanspec; /* txpwr report for this channel */ + u16 local_chanspec; /* channel on which we are associated */ + u8 local_max; /* local max according to the AP */ + u8 local_constraint; /* local constraint according to the AP */ + s8 antgain[2]; /* Ant gain for each band - from SROM */ + u8 rf_cores; /* count of RF Cores being reported */ + u8 est_Pout[4]; /* Latest tx power out estimate per RF chain */ + u8 est_Pout_act[4]; /* Latest tx power out estimate per RF chain + * without adjustment */ + u8 est_Pout_cck; /* Latest CCK tx power out estimate */ + u8 tx_power_max[4]; /* Maximum target power among all rates */ + /* Index of the rate with the max target power */ + u8 tx_power_max_rate_ind[4]; + /* User limit */ + u8 user_limit[WL_TX_POWER_RATES]; + /* Regulatory power limit */ + u8 reg_limit[WL_TX_POWER_RATES]; + /* Max power board can support (SROM) */ + u8 board_limit[WL_TX_POWER_RATES]; + /* Latest target power */ + u8 target[WL_TX_POWER_RATES]; }; struct tx_inst_power { - u8 txpwr_est_Pout[2]; /* Latest estimate for 2.4 and 5 Ghz */ - u8 txpwr_est_Pout_gofdm; /* Pwr estimate for 2.4 OFDM */ + 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 { +struct brcms_chanvec { u8 vec[MAXCHANNEL / NBBY]; }; struct shared_phy_params { struct si_pub *sih; - void *physhim; + struct phy_shim_info *physhim; uint unit; uint corerev; - uint bustype; uint buscorerev; char *vars; u16 vid; @@ -177,8 +183,10 @@ struct shared_phy_params { 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 struct brcms_phy_pub *wlc_phy_attach(struct shared_phy *sh, + struct d11regs *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, @@ -189,7 +197,7 @@ 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_init(struct brcms_phy_pub *ppi, u16 chanspec); extern void wlc_phy_watchdog(struct brcms_phy_pub *ppi); extern int wlc_phy_down(struct brcms_phy_pub *ppi); extern u32 wlc_phy_clk_bwbits(struct brcms_phy_pub *pih); @@ -197,14 +205,15 @@ 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); + u16 chanspec); +extern u16 wlc_phy_chanspec_get(struct brcms_phy_pub *ppi); extern void wlc_phy_chanspec_radio_set(struct brcms_phy_pub *ppi, - chanspec_t newch); + u16 newch); extern u16 wlc_phy_bw_state_get(struct brcms_phy_pub *ppi); extern void wlc_phy_bw_state_set(struct brcms_phy_pub *ppi, u16 bw); -extern void wlc_phy_rssi_compute(struct brcms_phy_pub *pih, void *ctx); +extern void wlc_phy_rssi_compute(struct brcms_phy_pub *pih, + struct brcms_d11rxhdr *wlc_rxhdr); 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); @@ -220,9 +229,9 @@ 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); + struct brcms_chanvec *channels); +extern u16 wlc_phy_chanspec_band_firstch(struct brcms_phy_pub *ppi, + uint band); extern void wlc_phy_txpower_sromlimit(struct brcms_phy_pub *ppi, uint chan, u8 *_min_, u8 *_max_, int rate); @@ -232,7 +241,7 @@ 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); + u16 chanspec); extern int wlc_phy_txpower_get(struct brcms_phy_pub *ppi, uint *qdbm, bool *override); extern int wlc_phy_txpower_set(struct brcms_phy_pub *ppi, uint qdbm, @@ -254,7 +263,7 @@ 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); + u16 chanspec); extern void wlc_phy_ldpc_override_set(struct brcms_phy_pub *ppi, bool val); extern void wlc_phy_cal_perical(struct brcms_phy_pub *ppi, u8 reason); @@ -264,8 +273,8 @@ 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_hold_upd(struct brcms_phy_pub *ppi, u32 id, bool val); +extern void wlc_phy_mute_upd(struct brcms_phy_pub *ppi, bool val, u32 flags); extern void wlc_phy_antsel_type_set(struct brcms_phy_pub *ppi, u8 antsel_type); @@ -289,6 +298,6 @@ 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); + u8 mcs_offset); extern s8 wlc_phy_get_tx_power_offset(struct brcms_phy_pub *ppi, u8 tbl_offset); -#endif /* _BRCM_PHY_HAL_H_ */ +#endif /* _BRCM_PHY_HAL_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/phy/phy_int.h b/drivers/staging/brcm80211/brcmsmac/phy/phy_int.h index a01b01c..a06e719 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/phy_int.h +++ b/drivers/staging/brcm80211/brcmsmac/phy/phy_int.h @@ -23,43 +23,23 @@ #define PHY_VERSION { 1, 82, 8, 0 } -#define PHYHAL_ERROR 0x0001 -#define PHYHAL_TRACE 0x0002 -#define PHYHAL_INFORM 0x0004 - -extern u32 phyhal_msg_level; - -#define PHY_INFORM_ON() (phyhal_msg_level & PHYHAL_INFORM) -#define PHY_THERMAL_ON() (phyhal_msg_level & PHYHAL_THERMAL) -#define PHY_CAL_ON() (phyhal_msg_level & PHYHAL_CAL) - -#ifdef BOARD_TYPE -#define BOARDTYPE(_type) BOARD_TYPE -#else -#define BOARDTYPE(_type) _type -#endif - #define LCNXN_BASEREV 16 +struct phy_shim_info; + 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 */ + /* TSSI positive slope, 1: positive, 0: negative */ + u8 tssipos; + /* Ext PA gain-type: full-gain: 0, pa-lite: 1, no_pa: 2 */ + u8 extpagain; + /* support 32 combinations of different Pdet dynamic ranges */ + u8 pdetrange; + /* TR switch isolation */ + u8 triso; + /* antswctrl lookup table configuration: 32 possible choices */ + u8 antswctrllut; }; -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) (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) @@ -203,7 +183,9 @@ typedef void (*detachfn_t) (struct brcms_phy *); #define PHY_PERICAL_WDOG_DELAY 5 #define MPHASE_TXCAL_NUMCMDS 2 -#define PHY_PERICAL_MPHASE_PENDING(pi) (pi->mphase_cal_phase_id > MPHASE_CAL_STATE_IDLE) + +#define PHY_PERICAL_MPHASE_PENDING(pi) \ + (pi->mphase_cal_phase_id > MPHASE_CAL_STATE_IDLE) enum { MPHASE_CAL_STATE_IDLE = 0, @@ -248,7 +230,9 @@ enum phy_cal_mode { #define CORDIC_AG 39797 #define CORDIC_NI 18 #define FIXED(X) ((s32)((X) << 16)) -#define FLOAT(X) (((X) >= 0) ? ((((X) >> 15) + 1) >> 1) : -((((-(X)) >> 15) + 1) >> 1)) + +#define FLOAT(X) \ + (((X) >= 0) ? ((((X) >> 15) + 1) >> 1) : -((((-(X)) >> 15) + 1) >> 1)) #define PHY_CHAIN_TX_DISABLE_TEMP 115 #define PHY_HYSTERESIS_DELTATEMP 5 @@ -256,36 +240,46 @@ enum phy_cal_mode { #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, \ - (value) << phy_type##_##reg_name##_##field##_##SHIFT); + mod_phy_reg(pi, phy_type##_##reg_name, \ + phy_type##_##reg_name##_##field##_MASK, \ + (value) << phy_type##_##reg_name##_##field##_##SHIFT) + #define READ_PHY_REG(pi, phy_type, reg_name, field) \ - ((read_phy_reg(pi, phy_type##_##reg_name) & phy_type##_##reg_name##_##field##_##MASK)\ - >> phy_type##_##reg_name##_##field##_##SHIFT) + ((read_phy_reg(pi, phy_type##_##reg_name) & \ + phy_type##_##reg_name##_##field##_##MASK) \ + >> phy_type##_##reg_name##_##field##_##SHIFT) #define VALID_PHYTYPE(phytype) (((uint)phytype == PHY_TYPE_N) || \ ((uint)phytype == PHY_TYPE_LCN)) -#define VALID_N_RADIO(radioid) ((radioid == BCM2055_ID) || (radioid == BCM2056_ID) || \ - (radioid == BCM2057_ID)) +#define VALID_N_RADIO(radioid) ((radioid == BCM2055_ID) || \ + (radioid == BCM2056_ID) || \ + (radioid == BCM2057_ID)) + #define VALID_LCN_RADIO(radioid) (radioid == BCM2064_ID) -#define VALID_RADIO(pi, radioid) (\ - (ISNPHY(pi) ? VALID_N_RADIO(radioid) : false) || \ - (ISLCNPHY(pi) ? VALID_LCN_RADIO(radioid) : false)) +#define VALID_RADIO(pi, radioid) ( \ + (ISNPHY(pi) ? VALID_N_RADIO(radioid) : false) || \ + (ISLCNPHY(pi) ? VALID_LCN_RADIO(radioid) : false)) + +#define SCAN_INPROG_PHY(pi) \ + (mboolisset(pi->measure_hold, PHY_HOLD_FOR_SCAN)) -#define SCAN_INPROG_PHY(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_SCAN)) -#define RM_INPROG_PHY(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_RM)) -#define PLT_INPROG_PHY(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_PLT)) -#define ASSOC_INPROG_PHY(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_ASSOC)) -#define SCAN_RM_IN_PROGRESS(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_SCAN | PHY_HOLD_FOR_RM)) -#define PHY_MUTED(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_MUTE)) -#define PUB_NOT_ASSOC(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_NOT_ASSOC)) +#define RM_INPROG_PHY(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_RM)) -#if defined(EXT_CBALL) -#define NORADIO_ENAB(pub) ((pub).radioid == NORADIO_ID) -#else -#define NORADIO_ENAB(pub) 0 -#endif +#define PLT_INPROG_PHY(pi) (mboolisset(pi->measure_hold, PHY_HOLD_FOR_PLT)) + +#define ASSOC_INPROG_PHY(pi) \ + (mboolisset(pi->measure_hold, PHY_HOLD_FOR_ASSOC)) + +#define SCAN_RM_IN_PROGRESS(pi) \ + (mboolisset(pi->measure_hold, PHY_HOLD_FOR_SCAN | PHY_HOLD_FOR_RM)) + +#define PHY_MUTED(pi) \ + (mboolisset(pi->measure_hold, PHY_HOLD_FOR_MUTE)) + +#define PUB_NOT_ASSOC(pi) \ + (mboolisset(pi->measure_hold, PHY_HOLD_FOR_NOT_ASSOC)) #define PHY_LTRN_LIST_LEN 64 extern u16 ltrn_list[PHY_LTRN_LIST_LEN]; @@ -532,7 +526,7 @@ struct shared_phy { struct brcms_phy *phy_head; uint unit; struct si_pub *sih; - void *physhim; + struct phy_shim_info *physhim; uint corerev; u32 machwcap; bool up; @@ -549,7 +543,6 @@ struct shared_phy { uint boardvendor; u32 boardflags; u32 boardflags2; - uint bustype; uint buscorerev; uint fast_timer; uint slow_timer; @@ -579,32 +572,31 @@ struct brcms_phy_pub { }; struct phy_func_ptr { - initfn_t init; - initfn_t calinit; - chansetfn_t chanset; - initfn_t txpwrrecalc; - longtrnfn_t longtrn; - txiqccgetfn_t txiqccget; - txiqccsetfn_t txiqccset; - txloccgetfn_t txloccget; - radioloftgetfn_t radioloftget; - initfn_t carrsuppr; - rxsigpwrfn_t rxsigpwr; - detachfn_t detach; + void (*init)(struct brcms_phy *); + void (*calinit)(struct brcms_phy *); + void (*chanset)(struct brcms_phy *, u16 chanspec); + void (*txpwrrecalc)(struct brcms_phy *); + int (*longtrn)(struct brcms_phy *, int); + void (*txiqccget)(struct brcms_phy *, u16 *, u16 *); + void (*txiqccset)(struct brcms_phy *, u16, u16); + u16 (*txloccget)(struct brcms_phy *); + void (*radioloftget)(struct brcms_phy *, u8 *, u8 *, u8 *, u8 *); + void (*carrsuppr)(struct brcms_phy *); + s32 (*rxsigpwr)(struct brcms_phy *, s32); + void (*detach)(struct brcms_phy *); }; struct brcms_phy { struct brcms_phy_pub pubpi_ro; struct shared_phy *sh; struct phy_func_ptr pi_fptr; - void *pi_ptr; union { struct brcms_phy_lcnphy *pi_lcnphy; } u; bool user_txpwr_at_rfport; - d11regs_t *regs; + struct d11regs *regs; struct brcms_phy *next; char *vars; struct brcms_phy_pub pubpi; @@ -613,7 +605,7 @@ struct brcms_phy { bool phytest_on; bool ofdm_rateset_war; bool bf_preempt_4306; - chanspec_t radio_chanspec; + u16 radio_chanspec; u8 antsel_type; u16 bw; u8 txpwr_percent; @@ -629,7 +621,7 @@ struct brcms_phy { int phynoise_chan_watchdog; bool phynoise_polling; bool disable_percal; - mbool measure_hold; + u32 measure_hold; s16 txpa_2g[PWRTBL_NUM_COEFF]; s16 txpa_2g_low_temp[PWRTBL_NUM_COEFF]; @@ -723,7 +715,7 @@ struct brcms_phy { u16 mintxbias; u16 mintxmag; struct lo_complex_abgphy_info gphy_locomp_iq - [STATIC_NUM_RF][STATIC_NUM_BB]; + [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; @@ -840,11 +832,11 @@ struct brcms_phy { u8 mphase_txcal_cmdidx; u8 mphase_txcal_numcmds; u16 mphase_txcal_bestcoeffs[11]; - chanspec_t nphy_txiqlocal_chanspec; - chanspec_t nphy_iqcal_chanspec_2G; - chanspec_t nphy_iqcal_chanspec_5G; - chanspec_t nphy_rssical_chanspec_2G; - chanspec_t nphy_rssical_chanspec_5G; + u16 nphy_txiqlocal_chanspec; + u16 nphy_iqcal_chanspec_2G; + u16 nphy_iqcal_chanspec_5G; + u16 nphy_rssical_chanspec_2G; + u16 nphy_rssical_chanspec_5G; struct wlapi_timer *phycal_timer; bool use_int_tx_iqlo_cal_nphy; bool internal_tx_iqlo_cal_tapoff_intpa_nphy; @@ -937,9 +929,9 @@ struct brcms_phy { struct wiphy *wiphy; }; -struct _cs32 { - fixed q; - fixed i; +struct cs32 { + s32 q; + s32 i; }; struct radio_regs { @@ -966,26 +958,29 @@ struct lcnphy_radio_regs { 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[]; + regs_RX_2056[]; extern struct radio_regs regs_SYN_2056_A1[], regs_TX_2056_A1[], - regs_RX_2056_A1[]; + regs_RX_2056_A1[]; extern struct radio_regs regs_SYN_2056_rev5[], regs_TX_2056_rev5[], - regs_RX_2056_rev5[]; + regs_RX_2056_rev5[]; extern struct radio_regs regs_SYN_2056_rev6[], regs_TX_2056_rev6[], - regs_RX_2056_rev6[]; + regs_RX_2056_rev6[]; extern struct radio_regs regs_SYN_2056_rev7[], regs_TX_2056_rev7[], - regs_RX_2056_rev7[]; + regs_RX_2056_rev7[]; extern struct radio_regs regs_SYN_2056_rev8[], regs_TX_2056_rev8[], - regs_RX_2056_rev8[]; + regs_RX_2056_rev8[]; + extern struct radio_20xx_regs regs_2057_rev4[], regs_2057_rev5[], - regs_2057_rev5v1[]; + regs_2057_rev5v1[]; extern struct radio_20xx_regs regs_2057_rev7[], regs_2057_rev8[]; 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) + +#define PHY_GETVAR(pi, name) phy_getvar(pi, name) +#define PHY_GETINTVAR(pi, name) phy_getintvar(pi, name) extern u16 read_phy_reg(struct brcms_phy *pi, u16 addr); extern void write_phy_reg(struct brcms_phy *pi, u16 addr, u16 val); @@ -1022,7 +1017,6 @@ extern void wlc_phy_table_data_write(struct brcms_phy *pi, uint width, u32 val); 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); @@ -1053,14 +1047,14 @@ 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(struct brcms_phy *pi, - chanspec_t chanspec); + u16 chanspec); extern void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi, - chanspec_t chanspec); + u16 chanspec); extern void wlc_phy_chanspec_set_fixup_lcnphy(struct brcms_phy *pi, - chanspec_t chanspec); + u16 chanspec); extern int wlc_phy_channel2freq(uint channel); extern int wlc_phy_chanspec_freq2bandrange_lpssn(uint); -extern int wlc_phy_chanspec_bandrange_get(struct brcms_phy *, chanspec_t); +extern int wlc_phy_chanspec_bandrange_get(struct brcms_phy *, u16 chanspec); 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); @@ -1142,13 +1136,17 @@ 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) -#define wlc_phy_read_table_nphy(pi, pti) wlc_phy_read_table(pi, pti, 0x72, \ - 0x74, 0x73) -#define wlc_nphy_table_addr(pi, id, off) wlc_phy_table_addr((pi), (id), (off), \ - 0x72, 0x74, 0x73) -#define wlc_nphy_table_data_write(pi, w, v) wlc_phy_table_data_write((pi), (w), (v)) +#define wlc_phy_write_table_nphy(pi, pti) \ + wlc_phy_write_table(pi, pti, 0x72, 0x74, 0x73) + +#define wlc_phy_read_table_nphy(pi, pti) \ + wlc_phy_read_table(pi, pti, 0x72, 0x74, 0x73) + +#define wlc_nphy_table_addr(pi, id, off) \ + wlc_phy_table_addr((pi), (id), (off), 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(struct brcms_phy *pi, u32, u32 l, u32 o, u32 w, void *d); @@ -1160,7 +1158,7 @@ extern void wlc_phy_table_write_nphy(struct brcms_phy *pi, u32, u32, u32, (pi->ipa5g_on && CHSPEC_IS5G(pi->radio_chanspec))) #define BRCMS_PHY_WAR_PR51571(pi) \ - if (((pi)->sh->bustype == PCI_BUS) && NREV_LT((pi)->pubpi.phy_rev, 3)) \ + if (NREV_LT((pi)->pubpi.phy_rev, 3)) \ (void)R_REG(&(pi)->regs->maccontrol) extern void wlc_phy_cal_perical_nphy_run(struct brcms_phy *pi, u8 caltype); @@ -1229,7 +1227,7 @@ extern void wlc_phy_nphy_tkip_rifs_war(struct brcms_phy *pi, u8 rifs); void wlc_phy_get_pwrdet_offsets(struct brcms_phy *pi, s8 *cckoffset, s8 *ofdmoffset); extern s8 wlc_phy_upd_rssi_offset(struct brcms_phy *pi, s8 rssi, - chanspec_t chanspec); + u16 chanspec); extern bool wlc_phy_n_txpower_ipa_ison(struct brcms_phy *pih); #endif /* _BRCM_PHY_INT_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/phy/phy_lcn.c b/drivers/staging/brcm80211/brcmsmac/phy/phy_lcn.c index 6a3fbe6..941b7fa 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/phy_lcn.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/phy_lcn.c @@ -15,6 +15,7 @@ */ #include <linux/delay.h> +#include <linux/cordic.h> #include <pmu.h> #include <d11.h> @@ -79,15 +80,15 @@ #define wlc_lcnphy_enable_tx_gain_override(pi) \ wlc_lcnphy_set_tx_gain_override(pi, true) -#define wlc_lcnphy_disable_tx_gain_override(pi) \ +#define wlc_lcnphy_disable_tx_gain_override(pi) \ wlc_lcnphy_set_tx_gain_override(pi, false) #define wlc_lcnphy_iqcal_active(pi) \ (read_phy_reg((pi), 0x451) & \ - ((0x1 << 15) | (0x1 << 14))) + ((0x1 << 15) | (0x1 << 14))) #define txpwrctrl_off(pi) (0x7 != ((read_phy_reg(pi, 0x4a4) & 0xE000) >> 13)) -#define wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi) \ +#define wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi) \ (pi->temppwrctrl_capable) #define wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi) \ (pi->hwpwrctrl_capable) @@ -132,12 +133,12 @@ #define LCNPHY_ACI_DETECT_TIMEOUT 2 #define LCNPHY_ACI_START_DELAY 0 -#define wlc_lcnphy_tx_gain_override_enabled(pi) \ +#define wlc_lcnphy_tx_gain_override_enabled(pi) \ (0 != (read_phy_reg((pi), 0x43b) & (0x1 << 6))) #define wlc_lcnphy_total_tx_frames(pi) \ - wlapi_bmac_read_shm((pi)->sh->physhim, \ - M_UCODE_MACSTAT + offsetof(struct macstat, txallfrm)) + wlapi_bmac_read_shm((pi)->sh->physhim, M_UCODE_MACSTAT + \ + offsetof(struct macstat, txallfrm)) struct lcnphy_txgains { u16 gm_gain; @@ -198,7 +199,7 @@ static const iqcal_gain_params_lcnphy *tbl_iqcal_gainparams_lcnphy[1] = { static const u16 iqcal_gainparams_numgains_lcnphy[1] = { sizeof(tbl_iqcal_gainparams_lcnphy_2G) / - sizeof(*tbl_iqcal_gainparams_lcnphy_2G), + sizeof(*tbl_iqcal_gainparams_lcnphy_2G), }; static const struct lcnphy_sfo_cfg lcnphy_sfo_cfg[] = { @@ -920,108 +921,50 @@ u16 LCNPHY_txdigfiltcoeffs_ofdm[LCNPHY_NUM_TX_DIG_FILTERS_OFDM] #define wlc_lcnphy_set_start_tx_pwr_idx(pi, idx) \ mod_phy_reg(pi, 0x4a4, \ - (0x1ff << 0), \ - (u16)(idx) << 0) + (0x1ff << 0), \ + (u16)(idx) << 0) #define wlc_lcnphy_set_tx_pwr_npt(pi, npt) \ mod_phy_reg(pi, 0x4a5, \ - (0x7 << 8), \ - (u16)(npt) << 8) + (0x7 << 8), \ + (u16)(npt) << 8) #define wlc_lcnphy_get_tx_pwr_ctrl(pi) \ (read_phy_reg((pi), 0x4a4) & \ - ((0x1 << 15) | \ - (0x1 << 14) | \ - (0x1 << 13))) + ((0x1 << 15) | \ + (0x1 << 14) | \ + (0x1 << 13))) #define wlc_lcnphy_get_tx_pwr_npt(pi) \ ((read_phy_reg(pi, 0x4a5) & \ - (0x7 << 8)) >> \ - 8) + (0x7 << 8)) >> \ + 8) #define wlc_lcnphy_get_current_tx_pwr_idx_if_pwrctrl_on(pi) \ (read_phy_reg(pi, 0x473) & 0x1ff) #define wlc_lcnphy_get_target_tx_pwr(pi) \ ((read_phy_reg(pi, 0x4a7) & \ - (0xff << 0)) >> \ - 0) + (0xff << 0)) >> \ + 0) #define wlc_lcnphy_set_target_tx_pwr(pi, target) \ mod_phy_reg(pi, 0x4a7, \ - (0xff << 0), \ - (u16)(target) << 0) + (0xff << 0), \ + (u16)(target) << 0) -#define wlc_radio_2064_rcal_done(pi) (0 != (read_radio_reg(pi, RADIO_2064_REG05C) & 0x20)) -#define tempsense_done(pi) (0x8000 == (read_phy_reg(pi, 0x476) & 0x8000)) +#define wlc_radio_2064_rcal_done(pi) \ + (0 != (read_radio_reg(pi, RADIO_2064_REG05C) & 0x20)) + +#define tempsense_done(pi) \ + (0x8000 == (read_phy_reg(pi, 0x476) & 0x8000)) + +#define LCNPHY_IQLOCC_READ(val) \ + ((u8)(-(s8)(((val) & 0xf0) >> 4) + (s8)((val) & 0x0f))) -#define LCNPHY_IQLOCC_READ(val) ((u8)(-(s8)(((val) & 0xf0) >> 4) + (s8)((val) & 0x0f))) #define FIXED_TXPWR 78 #define LCNPHY_TEMPSENSE(val) ((s16)((val > 255) ? (val - 512) : val)) -static u32 wlc_lcnphy_qdiv_roundup(u32 divident, u32 divisor, - u8 precision); -static void wlc_lcnphy_set_rx_gain_by_distribution(struct brcms_phy *pi, - u16 ext_lna, u16 trsw, - u16 biq2, u16 biq1, - u16 tia, u16 lna2, - u16 lna1); -static void wlc_lcnphy_clear_tx_power_offsets(struct brcms_phy *pi); -static void wlc_lcnphy_set_pa_gain(struct brcms_phy *pi, u16 gain); -static void wlc_lcnphy_set_trsw_override(struct brcms_phy *pi, bool tx, - bool rx); -static void wlc_lcnphy_set_bbmult(struct brcms_phy *pi, u8 m0); -static u8 wlc_lcnphy_get_bbmult(struct brcms_phy *pi); -static void wlc_lcnphy_get_tx_gain(struct brcms_phy *pi, - struct lcnphy_txgains *gains); -static void wlc_lcnphy_set_tx_gain_override(struct brcms_phy *pi, bool bEnable); -static void wlc_lcnphy_toggle_afe_pwdn(struct brcms_phy *pi); -static void wlc_lcnphy_rx_gain_override_enable(struct brcms_phy *pi, - bool enable); -static void wlc_lcnphy_set_tx_gain(struct brcms_phy *pi, - struct lcnphy_txgains *target_gains); -static bool wlc_lcnphy_rx_iq_est(struct brcms_phy *pi, u16 num_samps, - u8 wait_time, struct lcnphy_iq_est *iq_est); -static bool wlc_lcnphy_calc_rx_iq_comp(struct brcms_phy *pi, u16 num_samps); -static u16 wlc_lcnphy_get_pa_gain(struct brcms_phy *pi); -static void wlc_lcnphy_afe_clk_init(struct brcms_phy *pi, u8 mode); -static void wlc_lcnphy_tx_pwr_ctrl_init(struct brcms_phy_pub *ppi); -static void wlc_lcnphy_radio_2064_channel_tune_4313(struct brcms_phy *pi, - u8 channel); - -static void wlc_lcnphy_load_tx_gain_table(struct brcms_phy *pi, - const struct lcnphy_tx_gain_tbl_entry *g); - -static void wlc_lcnphy_samp_cap(struct brcms_phy *pi, int clip_detect_algo, - u16 thresh, s16 *ptr, int mode); -static int wlc_lcnphy_calc_floor(s16 coeff, int type); -static void wlc_lcnphy_tx_iqlo_loopback(struct brcms_phy *pi, - u16 *values_to_save); -static void wlc_lcnphy_tx_iqlo_loopback_cleanup(struct brcms_phy *pi, - u16 *values_to_save); -static void wlc_lcnphy_set_cc(struct brcms_phy *pi, int cal_type, s16 coeff_x, - s16 coeff_y); -static struct lcnphy_unsign16_struct wlc_lcnphy_get_cc(struct brcms_phy *pi, - int cal_type); -static void wlc_lcnphy_a1(struct brcms_phy *pi, int cal_type, - int num_levels, int step_size_lg2); -static void wlc_lcnphy_tx_iqlo_soft_cal_full(struct brcms_phy *pi); - -static void wlc_lcnphy_set_chanspec_tweaks(struct brcms_phy *pi, - chanspec_t chanspec); -static void wlc_lcnphy_agc_temp_init(struct brcms_phy *pi); -static void wlc_lcnphy_temp_adj(struct brcms_phy *pi); -static void wlc_lcnphy_clear_papd_comptable(struct brcms_phy *pi); -static void wlc_lcnphy_baseband_init(struct brcms_phy *pi); -static void wlc_lcnphy_radio_init(struct brcms_phy *pi); -static void wlc_lcnphy_rc_cal(struct brcms_phy *pi); -static void wlc_lcnphy_rcal(struct brcms_phy *pi); -static void wlc_lcnphy_txrx_spur_avoidance_mode(struct brcms_phy *pi, - bool enable); -static int wlc_lcnphy_load_tx_iir_filter(struct brcms_phy *pi, bool is_ofdm, - s16 filt_type); -static void wlc_lcnphy_set_rx_iq_comp(struct brcms_phy *pi, u16 a, u16 b); - void wlc_lcnphy_write_table(struct brcms_phy *pi, const struct phytbl_info *pti) { wlc_phy_write_table(pi, pti, 0x455, 0x457, 0x456); @@ -1034,7 +977,7 @@ void wlc_lcnphy_read_table(struct brcms_phy *pi, struct phytbl_info *pti) static void wlc_lcnphy_common_read_table(struct brcms_phy *pi, u32 tbl_id, - const void *tbl_ptr, u32 tbl_len, + const u16 *tbl_ptr, u32 tbl_len, u32 tbl_width, u32 tbl_offset) { struct phytbl_info tab; @@ -1048,7 +991,7 @@ wlc_lcnphy_common_read_table(struct brcms_phy *pi, u32 tbl_id, static void wlc_lcnphy_common_write_table(struct brcms_phy *pi, u32 tbl_id, - const void *tbl_ptr, u32 tbl_len, + const u16 *tbl_ptr, u32 tbl_len, u32 tbl_width, u32 tbl_offset) { @@ -1092,12 +1035,12 @@ static int wlc_lcnphy_calc_floor(s16 coeff_x, int type) int k; k = 0; if (type == 0) { - if (coeff_x < 0) { + if (coeff_x < 0) k = (coeff_x - 1) / 2; - } else { + else k = coeff_x / 2; - } } + if (type == 1) { if ((coeff_x + 1) < 0) k = (coeff_x) / 2; @@ -1107,20 +1050,269 @@ static int wlc_lcnphy_calc_floor(s16 coeff_x, int type) return k; } -s8 wlc_lcnphy_get_current_tx_pwr_idx(struct brcms_phy *pi) +static void +wlc_lcnphy_get_tx_gain(struct brcms_phy *pi, struct lcnphy_txgains *gains) { - s8 index; + u16 dac_gain; + + dac_gain = read_phy_reg(pi, 0x439) >> 0; + gains->dac_gain = (dac_gain & 0x380) >> 7; + + { + u16 rfgain0, rfgain1; + + rfgain0 = (read_phy_reg(pi, 0x4b5) & (0xffff << 0)) >> 0; + rfgain1 = (read_phy_reg(pi, 0x4fb) & (0x7fff << 0)) >> 0; + + gains->gm_gain = rfgain0 & 0xff; + gains->pga_gain = (rfgain0 >> 8) & 0xff; + gains->pad_gain = rfgain1 & 0xff; + } +} + + +static void wlc_lcnphy_set_dac_gain(struct brcms_phy *pi, u16 dac_gain) +{ + u16 dac_ctrl; + + dac_ctrl = (read_phy_reg(pi, 0x439) >> 0); + dac_ctrl = dac_ctrl & 0xc7f; + dac_ctrl = dac_ctrl | (dac_gain << 7); + mod_phy_reg(pi, 0x439, (0xfff << 0), (dac_ctrl) << 0); + +} + +static void wlc_lcnphy_set_tx_gain_override(struct brcms_phy *pi, bool bEnable) +{ + u16 bit = bEnable ? 1 : 0; + + mod_phy_reg(pi, 0x4b0, (0x1 << 7), bit << 7); + + mod_phy_reg(pi, 0x4b0, (0x1 << 14), bit << 14); + + mod_phy_reg(pi, 0x43b, (0x1 << 6), bit << 6); +} + +static void +wlc_lcnphy_rx_gain_override_enable(struct brcms_phy *pi, bool enable) +{ + u16 ebit = enable ? 1 : 0; + + mod_phy_reg(pi, 0x4b0, (0x1 << 8), ebit << 8); + + mod_phy_reg(pi, 0x44c, (0x1 << 0), ebit << 0); + + if (LCNREV_LT(pi->pubpi.phy_rev, 2)) { + mod_phy_reg(pi, 0x44c, (0x1 << 4), ebit << 4); + mod_phy_reg(pi, 0x44c, (0x1 << 6), ebit << 6); + mod_phy_reg(pi, 0x4b0, (0x1 << 5), ebit << 5); + mod_phy_reg(pi, 0x4b0, (0x1 << 6), ebit << 6); + } else { + mod_phy_reg(pi, 0x4b0, (0x1 << 12), ebit << 12); + mod_phy_reg(pi, 0x4b0, (0x1 << 13), ebit << 13); + mod_phy_reg(pi, 0x4b0, (0x1 << 5), ebit << 5); + } + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + mod_phy_reg(pi, 0x4b0, (0x1 << 10), ebit << 10); + mod_phy_reg(pi, 0x4e5, (0x1 << 3), ebit << 3); + } +} + +static void +wlc_lcnphy_set_rx_gain_by_distribution(struct brcms_phy *pi, + u16 trsw, + u16 ext_lna, + u16 biq2, + u16 biq1, + u16 tia, u16 lna2, u16 lna1) +{ + u16 gain0_15, gain16_19; + + gain16_19 = biq2 & 0xf; + gain0_15 = ((biq1 & 0xf) << 12) | + ((tia & 0xf) << 8) | + ((lna2 & 0x3) << 6) | + ((lna2 & + 0x3) << 4) | ((lna1 & 0x3) << 2) | ((lna1 & 0x3) << 0); + + mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0); + mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0); + mod_phy_reg(pi, 0x4b1, (0x3 << 11), lna1 << 11); + + if (LCNREV_LT(pi->pubpi.phy_rev, 2)) { + mod_phy_reg(pi, 0x4b1, (0x1 << 9), ext_lna << 9); + mod_phy_reg(pi, 0x4b1, (0x1 << 10), ext_lna << 10); + } else { + mod_phy_reg(pi, 0x4b1, (0x1 << 10), 0 << 10); + + mod_phy_reg(pi, 0x4b1, (0x1 << 15), 0 << 15); + + mod_phy_reg(pi, 0x4b1, (0x1 << 9), ext_lna << 9); + } + + mod_phy_reg(pi, 0x44d, (0x1 << 0), (!trsw) << 0); + +} + +static void wlc_lcnphy_set_trsw_override(struct brcms_phy *pi, bool tx, bool rx) +{ + + mod_phy_reg(pi, 0x44d, + (0x1 << 1) | + (0x1 << 0), (tx ? (0x1 << 1) : 0) | (rx ? (0x1 << 0) : 0)); + + or_phy_reg(pi, 0x44c, (0x1 << 1) | (0x1 << 0)); +} + +static void wlc_lcnphy_clear_trsw_override(struct brcms_phy *pi) +{ + + and_phy_reg(pi, 0x44c, (u16) ~((0x1 << 1) | (0x1 << 0))); +} + +static void wlc_lcnphy_set_rx_iq_comp(struct brcms_phy *pi, u16 a, u16 b) +{ + mod_phy_reg(pi, 0x645, (0x3ff << 0), (a) << 0); + + mod_phy_reg(pi, 0x646, (0x3ff << 0), (b) << 0); + + mod_phy_reg(pi, 0x647, (0x3ff << 0), (a) << 0); + + mod_phy_reg(pi, 0x648, (0x3ff << 0), (b) << 0); + + mod_phy_reg(pi, 0x649, (0x3ff << 0), (a) << 0); + + mod_phy_reg(pi, 0x64a, (0x3ff << 0), (b) << 0); + +} + +static bool +wlc_lcnphy_rx_iq_est(struct brcms_phy *pi, + u16 num_samps, + u8 wait_time, struct lcnphy_iq_est *iq_est) +{ + int wait_count = 0; + bool result = true; + u8 phybw40; + phybw40 = CHSPEC_IS40(pi->radio_chanspec); + + mod_phy_reg(pi, 0x6da, (0x1 << 5), (1) << 5); + + mod_phy_reg(pi, 0x410, (0x1 << 3), (0) << 3); + + mod_phy_reg(pi, 0x482, (0xffff << 0), (num_samps) << 0); + + mod_phy_reg(pi, 0x481, (0xff << 0), ((u16) wait_time) << 0); + + mod_phy_reg(pi, 0x481, (0x1 << 8), (0) << 8); + + mod_phy_reg(pi, 0x481, (0x1 << 9), (1) << 9); + + while (read_phy_reg(pi, 0x481) & (0x1 << 9)) { + + if (wait_count > (10 * 500)) { + result = false; + goto cleanup; + } + udelay(100); + wait_count++; + } + + iq_est->iq_prod = ((u32) read_phy_reg(pi, 0x483) << 16) | + (u32) read_phy_reg(pi, 0x484); + iq_est->i_pwr = ((u32) read_phy_reg(pi, 0x485) << 16) | + (u32) read_phy_reg(pi, 0x486); + iq_est->q_pwr = ((u32) read_phy_reg(pi, 0x487) << 16) | + (u32) read_phy_reg(pi, 0x488); + +cleanup: + mod_phy_reg(pi, 0x410, (0x1 << 3), (1) << 3); + + mod_phy_reg(pi, 0x6da, (0x1 << 5), (0) << 5); + + return result; +} + +static bool wlc_lcnphy_calc_rx_iq_comp(struct brcms_phy *pi, u16 num_samps) +{ +#define LCNPHY_MIN_RXIQ_PWR 2 + bool result; + u16 a0_new, b0_new; + struct lcnphy_iq_est iq_est = { 0, 0, 0 }; + s32 a, b, temp; + s16 iq_nbits, qq_nbits, arsh, brsh; + s32 iq; + u32 ii, qq; struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; - if (txpwrctrl_off(pi)) - index = pi_lcn->lcnphy_current_index; - else if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi)) - index = - (s8) (wlc_lcnphy_get_current_tx_pwr_idx_if_pwrctrl_on(pi) - / 2); - else - index = pi_lcn->lcnphy_current_index; - return index; + a0_new = ((read_phy_reg(pi, 0x645) & (0x3ff << 0)) >> 0); + b0_new = ((read_phy_reg(pi, 0x646) & (0x3ff << 0)) >> 0); + mod_phy_reg(pi, 0x6d1, (0x1 << 2), (0) << 2); + + mod_phy_reg(pi, 0x64b, (0x1 << 6), (1) << 6); + + wlc_lcnphy_set_rx_iq_comp(pi, 0, 0); + + result = wlc_lcnphy_rx_iq_est(pi, num_samps, 32, &iq_est); + if (!result) + goto cleanup; + + iq = (s32) iq_est.iq_prod; + ii = iq_est.i_pwr; + qq = iq_est.q_pwr; + + if ((ii + qq) < LCNPHY_MIN_RXIQ_PWR) { + result = false; + goto cleanup; + } + + iq_nbits = wlc_phy_nbits(iq); + qq_nbits = wlc_phy_nbits(qq); + + arsh = 10 - (30 - iq_nbits); + if (arsh >= 0) { + a = (-(iq << (30 - iq_nbits)) + (ii >> (1 + arsh))); + temp = (s32) (ii >> arsh); + if (temp == 0) + return false; + } else { + a = (-(iq << (30 - iq_nbits)) + (ii << (-1 - arsh))); + temp = (s32) (ii << -arsh); + if (temp == 0) + return false; + } + a /= temp; + brsh = qq_nbits - 31 + 20; + if (brsh >= 0) { + b = (qq << (31 - qq_nbits)); + temp = (s32) (ii >> brsh); + if (temp == 0) + return false; + } else { + b = (qq << (31 - qq_nbits)); + temp = (s32) (ii << -brsh); + if (temp == 0) + return false; + } + b /= temp; + b -= a * a; + b = (s32) int_sqrt((unsigned long) b); + b -= (1 << 10); + a0_new = (u16) (a & 0x3ff); + b0_new = (u16) (b & 0x3ff); +cleanup: + + wlc_lcnphy_set_rx_iq_comp(pi, a0_new, b0_new); + + mod_phy_reg(pi, 0x64b, (0x1 << 0), (1) << 0); + + mod_phy_reg(pi, 0x64b, (0x1 << 3), (1) << 3); + + pi_lcn->lcnphy_cal_results.rxiqcal_coeff_a0 = a0_new; + pi_lcn->lcnphy_cal_results.rxiqcal_coeff_b0 = b0_new; + + return result; } static u32 wlc_lcnphy_measure_digital_power(struct brcms_phy *pi, u16 nsamples) @@ -1132,6 +1324,187 @@ static u32 wlc_lcnphy_measure_digital_power(struct brcms_phy *pi, u16 nsamples) return (iq_est.i_pwr + iq_est.q_pwr) / nsamples; } +static bool +wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi, + const struct lcnphy_rx_iqcomp *iqcomp, + int iqcomp_sz, bool tx_switch, bool rx_switch, int module, + int tx_gain_idx) +{ + struct lcnphy_txgains old_gains; + u16 tx_pwr_ctrl; + u8 tx_gain_index_old = 0; + bool result = false, tx_gain_override_old = false; + u16 i, Core1TxControl_old, RFOverride0_old, + RFOverrideVal0_old, rfoverride2_old, rfoverride2val_old, + rfoverride3_old, rfoverride3val_old, rfoverride4_old, + rfoverride4val_old, afectrlovr_old, afectrlovrval_old; + int tia_gain; + u32 received_power, rx_pwr_threshold; + u16 old_sslpnCalibClkEnCtrl, old_sslpnRxFeClkEnCtrl; + u16 values_to_save[11]; + s16 *ptr; + struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; + + ptr = kmalloc(sizeof(s16) * 131, GFP_ATOMIC); + if (NULL == ptr) + return false; + if (module == 2) { + while (iqcomp_sz--) { + if (iqcomp[iqcomp_sz].chan == + CHSPEC_CHANNEL(pi->radio_chanspec)) { + wlc_lcnphy_set_rx_iq_comp(pi, + (u16) + iqcomp[iqcomp_sz].a, + (u16) + iqcomp[iqcomp_sz].b); + result = true; + break; + } + } + goto cal_done; + } + + if (module == 1) { + + tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); + wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF); + + for (i = 0; i < 11; i++) + values_to_save[i] = + read_radio_reg(pi, rxiq_cal_rf_reg[i]); + Core1TxControl_old = read_phy_reg(pi, 0x631); + + or_phy_reg(pi, 0x631, 0x0015); + + RFOverride0_old = read_phy_reg(pi, 0x44c); + RFOverrideVal0_old = read_phy_reg(pi, 0x44d); + rfoverride2_old = read_phy_reg(pi, 0x4b0); + rfoverride2val_old = read_phy_reg(pi, 0x4b1); + rfoverride3_old = read_phy_reg(pi, 0x4f9); + rfoverride3val_old = read_phy_reg(pi, 0x4fa); + rfoverride4_old = read_phy_reg(pi, 0x938); + rfoverride4val_old = read_phy_reg(pi, 0x939); + afectrlovr_old = read_phy_reg(pi, 0x43b); + afectrlovrval_old = read_phy_reg(pi, 0x43c); + old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da); + old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db); + + tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi); + if (tx_gain_override_old) { + wlc_lcnphy_get_tx_gain(pi, &old_gains); + tx_gain_index_old = pi_lcn->lcnphy_current_index; + } + + wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx); + + mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0); + mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0); + + mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1); + mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1); + + write_radio_reg(pi, RADIO_2064_REG116, 0x06); + write_radio_reg(pi, RADIO_2064_REG12C, 0x07); + write_radio_reg(pi, RADIO_2064_REG06A, 0xd3); + write_radio_reg(pi, RADIO_2064_REG098, 0x03); + write_radio_reg(pi, RADIO_2064_REG00B, 0x7); + mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4); + write_radio_reg(pi, RADIO_2064_REG01D, 0x01); + write_radio_reg(pi, RADIO_2064_REG114, 0x01); + write_radio_reg(pi, RADIO_2064_REG02E, 0x10); + write_radio_reg(pi, RADIO_2064_REG12A, 0x08); + + mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0); + mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0); + mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1); + mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1); + mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2); + mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2); + mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3); + mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3); + mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5); + mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5); + + mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0); + mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0); + + wlc_lcnphy_start_tx_tone(pi, 2000, 120, 0); + write_phy_reg(pi, 0x6da, 0xffff); + or_phy_reg(pi, 0x6db, 0x3); + wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch); + wlc_lcnphy_rx_gain_override_enable(pi, true); + + tia_gain = 8; + rx_pwr_threshold = 950; + while (tia_gain > 0) { + tia_gain -= 1; + wlc_lcnphy_set_rx_gain_by_distribution(pi, + 0, 0, 2, 2, + (u16) + tia_gain, 1, 0); + udelay(500); + + received_power = + wlc_lcnphy_measure_digital_power(pi, 2000); + if (received_power < rx_pwr_threshold) + break; + } + result = wlc_lcnphy_calc_rx_iq_comp(pi, 0xffff); + + wlc_lcnphy_stop_tx_tone(pi); + + write_phy_reg(pi, 0x631, Core1TxControl_old); + + write_phy_reg(pi, 0x44c, RFOverrideVal0_old); + write_phy_reg(pi, 0x44d, RFOverrideVal0_old); + write_phy_reg(pi, 0x4b0, rfoverride2_old); + write_phy_reg(pi, 0x4b1, rfoverride2val_old); + write_phy_reg(pi, 0x4f9, rfoverride3_old); + write_phy_reg(pi, 0x4fa, rfoverride3val_old); + write_phy_reg(pi, 0x938, rfoverride4_old); + write_phy_reg(pi, 0x939, rfoverride4val_old); + write_phy_reg(pi, 0x43b, afectrlovr_old); + write_phy_reg(pi, 0x43c, afectrlovrval_old); + write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl); + write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl); + + wlc_lcnphy_clear_trsw_override(pi); + + mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2); + + for (i = 0; i < 11; i++) + write_radio_reg(pi, rxiq_cal_rf_reg[i], + values_to_save[i]); + + if (tx_gain_override_old) + wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old); + else + wlc_lcnphy_disable_tx_gain_override(pi); + + wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl); + wlc_lcnphy_rx_gain_override_enable(pi, false); + } + +cal_done: + kfree(ptr); + return result; +} + +s8 wlc_lcnphy_get_current_tx_pwr_idx(struct brcms_phy *pi) +{ + s8 index; + struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; + + if (txpwrctrl_off(pi)) + index = pi_lcn->lcnphy_current_index; + else if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi)) + index = (s8) (wlc_lcnphy_get_current_tx_pwr_idx_if_pwrctrl_on( + pi) / 2); + else + index = pi_lcn->lcnphy_current_index; + return index; +} + void wlc_lcnphy_crsuprs(struct brcms_phy *pi, int channel) { u16 afectrlovr, afectrlovrval; @@ -1200,7 +1573,296 @@ wlc_lcnphy_txrx_spur_avoidance_mode(struct brcms_phy *pi, bool enable) wlapi_switch_macfreq(pi->sh->physhim, enable); } -void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi, chanspec_t chanspec) +static void +wlc_lcnphy_set_chanspec_tweaks(struct brcms_phy *pi, u16 chanspec) +{ + u8 channel = CHSPEC_CHANNEL(chanspec); + struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; + + if (channel == 14) + mod_phy_reg(pi, 0x448, (0x3 << 8), (2) << 8); + else + mod_phy_reg(pi, 0x448, (0x3 << 8), (1) << 8); + + pi_lcn->lcnphy_bandedge_corr = 2; + if (channel == 1) + pi_lcn->lcnphy_bandedge_corr = 4; + + if (channel == 1 || channel == 2 || channel == 3 || + channel == 4 || channel == 9 || + channel == 10 || channel == 11 || channel == 12) { + si_pmu_pllcontrol(pi->sh->sih, 0x2, 0xffffffff, 0x03000c04); + si_pmu_pllcontrol(pi->sh->sih, 0x3, 0xffffff, 0x0); + si_pmu_pllcontrol(pi->sh->sih, 0x4, 0xffffffff, 0x200005c0); + + si_pmu_pllupd(pi->sh->sih); + write_phy_reg(pi, 0x942, 0); + wlc_lcnphy_txrx_spur_avoidance_mode(pi, false); + pi_lcn->lcnphy_spurmod = 0; + mod_phy_reg(pi, 0x424, (0xff << 8), (0x1b) << 8); + + write_phy_reg(pi, 0x425, 0x5907); + } else { + si_pmu_pllcontrol(pi->sh->sih, 0x2, 0xffffffff, 0x03140c04); + si_pmu_pllcontrol(pi->sh->sih, 0x3, 0xffffff, 0x333333); + si_pmu_pllcontrol(pi->sh->sih, 0x4, 0xffffffff, 0x202c2820); + + si_pmu_pllupd(pi->sh->sih); + write_phy_reg(pi, 0x942, 0); + wlc_lcnphy_txrx_spur_avoidance_mode(pi, true); + + pi_lcn->lcnphy_spurmod = 0; + mod_phy_reg(pi, 0x424, (0xff << 8), (0x1f) << 8); + + write_phy_reg(pi, 0x425, 0x590a); + } + + or_phy_reg(pi, 0x44a, 0x44); + write_phy_reg(pi, 0x44a, 0x80); +} + +static void +wlc_lcnphy_radio_2064_channel_tune_4313(struct brcms_phy *pi, u8 channel) +{ + uint i; + const struct chan_info_2064_lcnphy *ci; + u8 rfpll_doubler = 0; + u8 pll_pwrup, pll_pwrup_ovr; + s32 qFxtal, qFref, qFvco, qFcal; + u8 d15, d16, f16, e44, e45; + u32 div_int, div_frac, fvco3, fpfd, fref3, fcal_div; + u16 loop_bw, d30, setCount; + + ci = &chan_info_2064_lcnphy[0]; + rfpll_doubler = 1; + + mod_radio_reg(pi, RADIO_2064_REG09D, 0x4, 0x1 << 2); + + write_radio_reg(pi, RADIO_2064_REG09E, 0xf); + if (!rfpll_doubler) { + loop_bw = PLL_2064_LOOP_BW; + d30 = PLL_2064_D30; + } else { + loop_bw = PLL_2064_LOOP_BW_DOUBLER; + d30 = PLL_2064_D30_DOUBLER; + } + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + for (i = 0; i < ARRAY_SIZE(chan_info_2064_lcnphy); i++) + if (chan_info_2064_lcnphy[i].chan == channel) + break; + + if (i >= ARRAY_SIZE(chan_info_2064_lcnphy)) + return; + + ci = &chan_info_2064_lcnphy[i]; + } + + write_radio_reg(pi, RADIO_2064_REG02A, ci->logen_buftune); + + mod_radio_reg(pi, RADIO_2064_REG030, 0x3, ci->logen_rccr_tx); + + mod_radio_reg(pi, RADIO_2064_REG091, 0x3, ci->txrf_mix_tune_ctrl); + + mod_radio_reg(pi, RADIO_2064_REG038, 0xf, ci->pa_input_tune_g); + + mod_radio_reg(pi, RADIO_2064_REG030, 0x3 << 2, + (ci->logen_rccr_rx) << 2); + + mod_radio_reg(pi, RADIO_2064_REG05E, 0xf, ci->pa_rxrf_lna1_freq_tune); + + mod_radio_reg(pi, RADIO_2064_REG05E, (0xf) << 4, + (ci->pa_rxrf_lna2_freq_tune) << 4); + + write_radio_reg(pi, RADIO_2064_REG06C, ci->rxrf_rxrf_spare1); + + pll_pwrup = (u8) read_radio_reg(pi, RADIO_2064_REG044); + pll_pwrup_ovr = (u8) read_radio_reg(pi, RADIO_2064_REG12B); + + or_radio_reg(pi, RADIO_2064_REG044, 0x07); + + or_radio_reg(pi, RADIO_2064_REG12B, (0x07) << 1); + e44 = 0; + e45 = 0; + + fpfd = rfpll_doubler ? (pi->xtalfreq << 1) : (pi->xtalfreq); + if (pi->xtalfreq > 26000000) + e44 = 1; + if (pi->xtalfreq > 52000000) + e45 = 1; + if (e44 == 0) + fcal_div = 1; + else if (e45 == 0) + fcal_div = 2; + else + fcal_div = 4; + fvco3 = (ci->freq * 3); + fref3 = 2 * fpfd; + + qFxtal = wlc_lcnphy_qdiv_roundup(pi->xtalfreq, PLL_2064_MHZ, 16); + qFref = wlc_lcnphy_qdiv_roundup(fpfd, PLL_2064_MHZ, 16); + qFcal = pi->xtalfreq * fcal_div / PLL_2064_MHZ; + qFvco = wlc_lcnphy_qdiv_roundup(fvco3, 2, 16); + + write_radio_reg(pi, RADIO_2064_REG04F, 0x02); + + d15 = (pi->xtalfreq * fcal_div * 4 / 5) / PLL_2064_MHZ - 1; + write_radio_reg(pi, RADIO_2064_REG052, (0x07 & (d15 >> 2))); + write_radio_reg(pi, RADIO_2064_REG053, (d15 & 0x3) << 5); + + d16 = (qFcal * 8 / (d15 + 1)) - 1; + write_radio_reg(pi, RADIO_2064_REG051, d16); + + f16 = ((d16 + 1) * (d15 + 1)) / qFcal; + setCount = f16 * 3 * (ci->freq) / 32 - 1; + mod_radio_reg(pi, RADIO_2064_REG053, (0x0f << 0), + (u8) (setCount >> 8)); + + or_radio_reg(pi, RADIO_2064_REG053, 0x10); + write_radio_reg(pi, RADIO_2064_REG054, (u8) (setCount & 0xff)); + + div_int = ((fvco3 * (PLL_2064_MHZ >> 4)) / fref3) << 4; + + div_frac = ((fvco3 * (PLL_2064_MHZ >> 4)) % fref3) << 4; + while (div_frac >= fref3) { + div_int++; + div_frac -= fref3; + } + div_frac = wlc_lcnphy_qdiv_roundup(div_frac, fref3, 20); + + mod_radio_reg(pi, RADIO_2064_REG045, (0x1f << 0), + (u8) (div_int >> 4)); + mod_radio_reg(pi, RADIO_2064_REG046, (0x1f << 4), + (u8) (div_int << 4)); + mod_radio_reg(pi, RADIO_2064_REG046, (0x0f << 0), + (u8) (div_frac >> 16)); + write_radio_reg(pi, RADIO_2064_REG047, (u8) (div_frac >> 8) & 0xff); + write_radio_reg(pi, RADIO_2064_REG048, (u8) div_frac & 0xff); + + write_radio_reg(pi, RADIO_2064_REG040, 0xfb); + + write_radio_reg(pi, RADIO_2064_REG041, 0x9A); + write_radio_reg(pi, RADIO_2064_REG042, 0xA3); + write_radio_reg(pi, RADIO_2064_REG043, 0x0C); + + { + u8 h29, h23, c28, d29, h28_ten, e30, h30_ten, cp_current; + u16 c29, c38, c30, g30, d28; + c29 = loop_bw; + d29 = 200; + c38 = 1250; + h29 = d29 / c29; + h23 = 1; + c28 = 30; + d28 = (((PLL_2064_HIGH_END_KVCO - PLL_2064_LOW_END_KVCO) * + (fvco3 / 2 - PLL_2064_LOW_END_VCO)) / + (PLL_2064_HIGH_END_VCO - PLL_2064_LOW_END_VCO)) + + PLL_2064_LOW_END_KVCO; + h28_ten = (d28 * 10) / c28; + c30 = 2640; + e30 = (d30 - 680) / 490; + g30 = 680 + (e30 * 490); + h30_ten = (g30 * 10) / c30; + cp_current = ((c38 * h29 * h23 * 100) / h28_ten) / h30_ten; + mod_radio_reg(pi, RADIO_2064_REG03C, 0x3f, cp_current); + } + if (channel >= 1 && channel <= 5) + write_radio_reg(pi, RADIO_2064_REG03C, 0x8); + else + write_radio_reg(pi, RADIO_2064_REG03C, 0x7); + write_radio_reg(pi, RADIO_2064_REG03D, 0x3); + + mod_radio_reg(pi, RADIO_2064_REG044, 0x0c, 0x0c); + udelay(1); + + wlc_2064_vco_cal(pi); + + write_radio_reg(pi, RADIO_2064_REG044, pll_pwrup); + write_radio_reg(pi, RADIO_2064_REG12B, pll_pwrup_ovr); + if (LCNREV_IS(pi->pubpi.phy_rev, 1)) { + write_radio_reg(pi, RADIO_2064_REG038, 3); + write_radio_reg(pi, RADIO_2064_REG091, 7); + } +} + +static int +wlc_lcnphy_load_tx_iir_filter(struct brcms_phy *pi, bool is_ofdm, s16 filt_type) +{ + s16 filt_index = -1; + int j; + + u16 addr[] = { + 0x910, + 0x91e, + 0x91f, + 0x924, + 0x925, + 0x926, + 0x920, + 0x921, + 0x927, + 0x928, + 0x929, + 0x922, + 0x923, + 0x930, + 0x931, + 0x932 + }; + + u16 addr_ofdm[] = { + 0x90f, + 0x900, + 0x901, + 0x906, + 0x907, + 0x908, + 0x902, + 0x903, + 0x909, + 0x90a, + 0x90b, + 0x904, + 0x905, + 0x90c, + 0x90d, + 0x90e + }; + + if (!is_ofdm) { + for (j = 0; j < LCNPHY_NUM_TX_DIG_FILTERS_CCK; j++) { + if (filt_type == LCNPHY_txdigfiltcoeffs_cck[j][0]) { + filt_index = (s16) j; + break; + } + } + + if (filt_index != -1) { + for (j = 0; j < LCNPHY_NUM_DIG_FILT_COEFFS; j++) + write_phy_reg(pi, addr[j], + LCNPHY_txdigfiltcoeffs_cck + [filt_index][j + 1]); + } + } else { + for (j = 0; j < LCNPHY_NUM_TX_DIG_FILTERS_OFDM; j++) { + if (filt_type == LCNPHY_txdigfiltcoeffs_ofdm[j][0]) { + filt_index = (s16) j; + break; + } + } + + if (filt_index != -1) { + for (j = 0; j < LCNPHY_NUM_DIG_FILT_COEFFS; j++) + write_phy_reg(pi, addr_ofdm[j], + LCNPHY_txdigfiltcoeffs_ofdm + [filt_index][j + 1]); + } + } + + return (filt_index != -1) ? 0 : -1; +} + +void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi, u16 chanspec) { u8 channel = CHSPEC_CHANNEL(chanspec); @@ -1211,10 +1873,8 @@ void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi, chanspec_t chanspec) or_phy_reg(pi, 0x44a, 0x44); write_phy_reg(pi, 0x44a, 0x80); - if (!NORADIO_ENAB(pi->pubpi)) { - wlc_lcnphy_radio_2064_channel_tune_4313(pi, channel); - udelay(1000); - } + wlc_lcnphy_radio_2064_channel_tune_4313(pi, channel); + udelay(1000); wlc_lcnphy_toggle_afe_pwdn(pi); @@ -1237,35 +1897,13 @@ void wlc_phy_chanspec_set_lcnphy(struct brcms_phy *pi, chanspec_t chanspec) } -static void wlc_lcnphy_set_dac_gain(struct brcms_phy *pi, u16 dac_gain) -{ - u16 dac_ctrl; - - dac_ctrl = (read_phy_reg(pi, 0x439) >> 0); - dac_ctrl = dac_ctrl & 0xc7f; - dac_ctrl = dac_ctrl | (dac_gain << 7); - mod_phy_reg(pi, 0x439, (0xfff << 0), (dac_ctrl) << 0); - -} - -static void wlc_lcnphy_set_tx_gain_override(struct brcms_phy *pi, bool bEnable) -{ - u16 bit = bEnable ? 1 : 0; - - mod_phy_reg(pi, 0x4b0, (0x1 << 7), bit << 7); - - mod_phy_reg(pi, 0x4b0, (0x1 << 14), bit << 14); - - mod_phy_reg(pi, 0x43b, (0x1 << 6), bit << 6); -} - static u16 wlc_lcnphy_get_pa_gain(struct brcms_phy *pi) { u16 pa_gain; pa_gain = (read_phy_reg(pi, 0x4fb) & LCNPHY_txgainctrlovrval1_pagain_ovr_val1_MASK) >> - LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT; + LCNPHY_txgainctrlovrval1_pagain_ovr_val1_SHIFT; return pa_gain; } @@ -1275,18 +1913,22 @@ static void wlc_lcnphy_set_tx_gain(struct brcms_phy *pi, { u16 pa_gain = wlc_lcnphy_get_pa_gain(pi); - mod_phy_reg(pi, 0x4b5, - (0xffff << 0), - ((target_gains->gm_gain) | (target_gains->pga_gain << 8)) << - 0); + mod_phy_reg( + pi, 0x4b5, + (0xffff << 0), + ((target_gains->gm_gain) | + (target_gains->pga_gain << 8)) << + 0); mod_phy_reg(pi, 0x4fb, (0x7fff << 0), ((target_gains->pad_gain) | (pa_gain << 8)) << 0); - mod_phy_reg(pi, 0x4fc, - (0xffff << 0), - ((target_gains->gm_gain) | (target_gains->pga_gain << 8)) << - 0); + mod_phy_reg( + pi, 0x4fc, + (0xffff << 0), + ((target_gains->gm_gain) | + (target_gains->pga_gain << 8)) << + 0); mod_phy_reg(pi, 0x4fd, (0x7fff << 0), ((target_gains->pad_gain) | (pa_gain << 8)) << 0); @@ -1404,8 +2046,8 @@ static void wlc_lcnphy_pwrctrl_rssiparams(struct brcms_phy *pi) u16 auxpga_vmid, auxpga_vmid_temp, auxpga_gain_temp; struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; - auxpga_vmid = - (2 << 8) | (pi_lcn->lcnphy_rssi_vc << 4) | pi_lcn->lcnphy_rssi_vf; + auxpga_vmid = (2 << 8) | + (pi_lcn->lcnphy_rssi_vc << 4) | pi_lcn->lcnphy_rssi_vf; auxpga_vmid_temp = (2 << 8) | (8 << 4) | 4; auxpga_gain_temp = 2; @@ -1531,10 +2173,9 @@ static void wlc_lcnphy_tssi_setup(struct brcms_phy *pi) mod_radio_reg(pi, RADIO_2064_REG005, 0x8, 1 << 3); - if (!wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) { + if (!wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) mod_phy_reg(pi, 0x4d7, (0x1 << 3) | (0x7 << 12), 0 << 3 | 2 << 12); - } rfseq = wlc_lcnphy_rfseq_tbl_adc_pwrup(pi); tab.tbl_id = LCNPHY_TBL_ID_RFSEQ; @@ -1601,7 +2242,7 @@ void wlc_lcnphy_txpower_recalc_target(struct brcms_phy *pi) { struct phytbl_info tab; u32 rate_table[BRCMS_NUM_RATES_CCK + BRCMS_NUM_RATES_OFDM + - BRCMS_NUM_RATES_MCS_1_STREAM]; + BRCMS_NUM_RATES_MCS_1_STREAM]; uint i, j; if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) return; @@ -1694,34 +2335,28 @@ static s8 wlc_lcnphy_tempcompensated_txpwrctrl(struct brcms_phy *pi) index = FIXED_TXPWR; - if (NORADIO_ENAB(pi->pubpi)) + if (pi_lcn->lcnphy_tempsense_slope == 0) return index; - if (pi_lcn->lcnphy_tempsense_slope == 0) { - return index; - } temp = (u16) wlc_lcnphy_tempsense(pi, 0); meas_temp = LCNPHY_TEMPSENSE(temp); - if (pi->tx_power_min != 0) { + if (pi->tx_power_min != 0) delta_brd = (pi_lcn->lcnphy_measPower - pi->tx_power_min); - } else { + else delta_brd = 0; - } manp = LCNPHY_TEMPSENSE(pi_lcn->lcnphy_rawtempsense); temp_diff = manp - meas_temp; if (temp_diff < 0) { - neg = 1; - temp_diff = -temp_diff; } delta_temp = (s8) wlc_lcnphy_qdiv_roundup((u32) (temp_diff * 192), - (u32) (pi_lcn-> - lcnphy_tempsense_slope - * 10), 0); + (u32) (pi_lcn-> + lcnphy_tempsense_slope + * 10), 0); if (neg) delta_temp = -delta_temp; @@ -1735,14 +2370,15 @@ static s8 wlc_lcnphy_tempcompensated_txpwrctrl(struct brcms_phy *pi) if (LCNREV_IS(pi->pubpi.phy_rev, 1)) tempcorrx = 4; new_index = - index + delta_brd + delta_temp - pi_lcn->lcnphy_bandedge_corr; + index + delta_brd + delta_temp - pi_lcn->lcnphy_bandedge_corr; new_index += tempcorrx; if (LCNREV_IS(pi->pubpi.phy_rev, 1)) index = 127; - if (new_index < 0 || new_index > 126) { + + if (new_index < 0 || new_index > 126) return index; - } + return new_index; } @@ -1792,7 +2428,7 @@ void wlc_lcnphy_set_tx_pwr_ctrl(struct brcms_phy *pi, u16 mode) mod_radio_reg(pi, RADIO_2064_REG11F, 0x4, 0); pi_lcn->lcnphy_tssi_tx_cnt = - wlc_lcnphy_total_tx_frames(pi); + wlc_lcnphy_total_tx_frames(pi); wlc_lcnphy_disable_tx_gain_override(pi); pi_lcn->lcnphy_tx_power_idx_override = -1; @@ -1805,11 +2441,105 @@ void wlc_lcnphy_set_tx_pwr_ctrl(struct brcms_phy *pi, u16 mode) index = wlc_lcnphy_tempcompensated_txpwrctrl(pi); wlc_lcnphy_set_tx_pwr_soft_ctrl(pi, index); pi_lcn->lcnphy_current_index = (s8) - ((read_phy_reg(pi, 0x4a9) & 0xFF) / 2); + ((read_phy_reg(pi, + 0x4a9) & + 0xFF) / 2); } } } +static void +wlc_lcnphy_tx_iqlo_loopback(struct brcms_phy *pi, u16 *values_to_save) +{ + u16 vmid; + int i; + for (i = 0; i < 20; i++) + values_to_save[i] = + read_radio_reg(pi, iqlo_loopback_rf_regs[i]); + + mod_phy_reg(pi, 0x44c, (0x1 << 12), 1 << 12); + mod_phy_reg(pi, 0x44d, (0x1 << 14), 1 << 14); + + mod_phy_reg(pi, 0x44c, (0x1 << 11), 1 << 11); + mod_phy_reg(pi, 0x44d, (0x1 << 13), 0 << 13); + + mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1); + mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1); + + mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0); + mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0); + + if (LCNREV_IS(pi->pubpi.phy_rev, 2)) + and_radio_reg(pi, RADIO_2064_REG03A, 0xFD); + else + and_radio_reg(pi, RADIO_2064_REG03A, 0xF9); + or_radio_reg(pi, RADIO_2064_REG11A, 0x1); + + or_radio_reg(pi, RADIO_2064_REG036, 0x01); + or_radio_reg(pi, RADIO_2064_REG11A, 0x18); + udelay(20); + + if (LCNREV_IS(pi->pubpi.phy_rev, 2)) { + if (CHSPEC_IS5G(pi->radio_chanspec)) + mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0); + else + or_radio_reg(pi, RADIO_2064_REG03A, 1); + } else { + if (CHSPEC_IS5G(pi->radio_chanspec)) + mod_radio_reg(pi, RADIO_2064_REG03A, 3, 1); + else + or_radio_reg(pi, RADIO_2064_REG03A, 0x3); + } + + udelay(20); + + write_radio_reg(pi, RADIO_2064_REG025, 0xF); + if (LCNREV_IS(pi->pubpi.phy_rev, 2)) { + if (CHSPEC_IS5G(pi->radio_chanspec)) + mod_radio_reg(pi, RADIO_2064_REG028, 0xF, 0x4); + else + mod_radio_reg(pi, RADIO_2064_REG028, 0xF, 0x6); + } else { + if (CHSPEC_IS5G(pi->radio_chanspec)) + mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, 0x4 << 1); + else + mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, 0x6 << 1); + } + + udelay(20); + + write_radio_reg(pi, RADIO_2064_REG005, 0x8); + or_radio_reg(pi, RADIO_2064_REG112, 0x80); + udelay(20); + + or_radio_reg(pi, RADIO_2064_REG0FF, 0x10); + or_radio_reg(pi, RADIO_2064_REG11F, 0x44); + udelay(20); + + or_radio_reg(pi, RADIO_2064_REG00B, 0x7); + or_radio_reg(pi, RADIO_2064_REG113, 0x10); + udelay(20); + + write_radio_reg(pi, RADIO_2064_REG007, 0x1); + udelay(20); + + vmid = 0x2A6; + mod_radio_reg(pi, RADIO_2064_REG0FC, 0x3 << 0, (vmid >> 8) & 0x3); + write_radio_reg(pi, RADIO_2064_REG0FD, (vmid & 0xff)); + or_radio_reg(pi, RADIO_2064_REG11F, 0x44); + udelay(20); + + or_radio_reg(pi, RADIO_2064_REG0FF, 0x10); + udelay(20); + write_radio_reg(pi, RADIO_2064_REG012, 0x02); + or_radio_reg(pi, RADIO_2064_REG112, 0x06); + write_radio_reg(pi, RADIO_2064_REG036, 0x11); + write_radio_reg(pi, RADIO_2064_REG059, 0xcc); + write_radio_reg(pi, RADIO_2064_REG05C, 0x2e); + write_radio_reg(pi, RADIO_2064_REG078, 0xd7); + write_radio_reg(pi, RADIO_2064_REG092, 0x15); +} + static bool wlc_lcnphy_iqcal_wait(struct brcms_phy *pi) { uint delay_count = 0; @@ -1826,6 +2556,20 @@ static bool wlc_lcnphy_iqcal_wait(struct brcms_phy *pi) } static void +wlc_lcnphy_tx_iqlo_loopback_cleanup(struct brcms_phy *pi, u16 *values_to_save) +{ + int i; + + and_phy_reg(pi, 0x44c, 0x0 >> 11); + + and_phy_reg(pi, 0x43b, 0xC); + + for (i = 0; i < 20; i++) + write_radio_reg(pi, iqlo_loopback_rf_regs[i], + values_to_save[i]); +} + +static void wlc_lcnphy_tx_iqlo_cal(struct brcms_phy *pi, struct lcnphy_txgains *target_gains, enum lcnphy_cal_mode cal_mode, bool keep_tone) @@ -1837,20 +2581,23 @@ wlc_lcnphy_tx_iqlo_cal(struct brcms_phy *pi, int j; u16 ncorr_override[5]; u16 syst_coeffs[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 - }; + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}; u16 commands_fullcal[] = { - 0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234 }; + 0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234 + }; u16 commands_recal[] = { - 0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234 }; + 0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234 + }; u16 command_nums_fullcal[] = { - 0x7a97, 0x7a97, 0x7a97, 0x7a87, 0x7a87, 0x7b97 }; + 0x7a97, 0x7a97, 0x7a97, 0x7a87, 0x7a87, 0x7b97 + }; u16 command_nums_recal[] = { - 0x7a97, 0x7a97, 0x7a97, 0x7a87, 0x7a87, 0x7b97 }; + 0x7a97, 0x7a97, 0x7a97, 0x7a87, 0x7a87, 0x7b97 + }; u16 *command_nums = command_nums_fullcal; u16 *start_coeffs = NULL, *cal_cmds = NULL, cal_type, diq_start; @@ -1862,13 +2609,9 @@ wlc_lcnphy_tx_iqlo_cal(struct brcms_phy *pi, u16 *values_to_save; struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; - if (NORADIO_ENAB(pi->pubpi)) - return; - values_to_save = kmalloc(sizeof(u16) * 20, GFP_ATOMIC); - if (NULL == values_to_save) { + if (NULL == values_to_save) return; - } save_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db); save_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da); @@ -1927,7 +2670,7 @@ wlc_lcnphy_tx_iqlo_cal(struct brcms_phy *pi, } hash = (target_gains->gm_gain << 8) | - (target_gains->pga_gain << 4) | (target_gains->pad_gain); + (target_gains->pga_gain << 4) | (target_gains->pad_gain); band_idx = (CHSPEC_IS5G(pi->radio_chanspec) ? 1 : 0); @@ -1936,11 +2679,11 @@ wlc_lcnphy_tx_iqlo_cal(struct brcms_phy *pi, for (j = 0; j < iqcal_gainparams_numgains_lcnphy[band_idx]; j++) { if (hash == tbl_iqcal_gainparams_lcnphy[band_idx][j][0]) { cal_gains.gm_gain = - tbl_iqcal_gainparams_lcnphy[band_idx][j][1]; + tbl_iqcal_gainparams_lcnphy[band_idx][j][1]; cal_gains.pga_gain = - tbl_iqcal_gainparams_lcnphy[band_idx][j][2]; + tbl_iqcal_gainparams_lcnphy[band_idx][j][2]; cal_gains.pad_gain = - tbl_iqcal_gainparams_lcnphy[band_idx][j][3]; + tbl_iqcal_gainparams_lcnphy[band_idx][j][3]; memcpy(ncorr_override, &tbl_iqcal_gainparams_lcnphy[band_idx][j][3], sizeof(ncorr_override)); @@ -1954,14 +2697,14 @@ wlc_lcnphy_tx_iqlo_cal(struct brcms_phy *pi, write_phy_reg(pi, 0x93d, 0xc0); wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL, - (const void *) lcnphy_iqcal_loft_gainladder, ARRAY_SIZE(lcnphy_iqcal_loft_gainladder), 16, 0); wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL, - (const void *)lcnphy_iqcal_ir_gainladder, - ARRAY_SIZE(lcnphy_iqcal_ir_gainladder), 16, + lcnphy_iqcal_ir_gainladder, + ARRAY_SIZE( + lcnphy_iqcal_ir_gainladder), 16, 32); if (pi->phy_tx_tone_freq) { @@ -1985,13 +2728,12 @@ wlc_lcnphy_tx_iqlo_cal(struct brcms_phy *pi, command_num = command_nums[i]; if (ncorr_override[cal_type]) command_num = - ncorr_override[cal_type] << 8 | (command_num & - 0xff); + ncorr_override[cal_type] << 8 | (command_num & + 0xff); write_phy_reg(pi, 0x452, command_num); if ((cal_type == 3) || (cal_type == 4)) { - wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL, &diq_start, 1, 16, 69); @@ -2001,10 +2743,8 @@ wlc_lcnphy_tx_iqlo_cal(struct brcms_phy *pi, write_phy_reg(pi, 0x451, cal_cmds[i]); - if (!wlc_lcnphy_iqcal_wait(pi)) { - + if (!wlc_lcnphy_iqcal_wait(pi)) goto cleanup; - } wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL, best_coeffs, @@ -2013,16 +2753,15 @@ wlc_lcnphy_tx_iqlo_cal(struct brcms_phy *pi, best_coeffs, ARRAY_SIZE(best_coeffs), 16, 64); - if ((cal_type == 3) || (cal_type == 4)) { + if ((cal_type == 3) || (cal_type == 4)) wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL, &diq_start, 1, 16, 69); - } wlc_lcnphy_common_read_table(pi, LCNPHY_TBL_ID_IQLOCAL, pi_lcn->lcnphy_cal_results. txiqlocal_bestcoeffs, ARRAY_SIZE(pi_lcn-> - lcnphy_cal_results. - txiqlocal_bestcoeffs), + lcnphy_cal_results. + txiqlocal_bestcoeffs), 16, 96); } @@ -2030,7 +2769,7 @@ wlc_lcnphy_tx_iqlo_cal(struct brcms_phy *pi, pi_lcn->lcnphy_cal_results. txiqlocal_bestcoeffs, ARRAY_SIZE(pi_lcn->lcnphy_cal_results. - txiqlocal_bestcoeffs), 16, 96); + txiqlocal_bestcoeffs), 16, 96); pi_lcn->lcnphy_cal_results.txiqlocal_bestcoeffs_valid = true; wlc_lcnphy_common_write_table(pi, LCNPHY_TBL_ID_IQLOCAL, @@ -2041,7 +2780,7 @@ wlc_lcnphy_tx_iqlo_cal(struct brcms_phy *pi, &pi_lcn->lcnphy_cal_results. txiqlocal_bestcoeffs[5], 2, 16, 85); - cleanup: +cleanup: wlc_lcnphy_tx_iqlo_loopback_cleanup(pi, values_to_save); kfree(values_to_save); @@ -2071,14 +2810,14 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi) u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); u16 SAVE_lpfgain = read_radio_reg(pi, RADIO_2064_REG112); u16 SAVE_jtag_bb_afe_switch = - read_radio_reg(pi, RADIO_2064_REG007) & 1; + read_radio_reg(pi, RADIO_2064_REG007) & 1; u16 SAVE_jtag_auxpga = read_radio_reg(pi, RADIO_2064_REG0FF) & 0x10; u16 SAVE_iqadc_aux_en = read_radio_reg(pi, RADIO_2064_REG11F) & 4; idleTssi = read_phy_reg(pi, 0x4ab); suspend = - (0 == - (R_REG(&((struct brcms_phy *) pi)->regs->maccontrol) & - MCTL_EN_MAC)); + (0 == + (R_REG(&((struct brcms_phy *) pi)->regs->maccontrol) & + MCTL_EN_MAC)); if (!suspend) wlapi_suspend_mac_and_wait(pi->sh->physhim); wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF); @@ -2136,7 +2875,7 @@ static void wlc_lcnphy_vbat_temp_sense_setup(struct brcms_phy *pi, u8 mode) struct phytbl_info tab; u32 val; u8 save_reg007, save_reg0FF, save_reg11F, save_reg005, save_reg025, - save_reg112; + save_reg112; u16 values_to_save[14]; s8 index; int i; @@ -2152,8 +2891,7 @@ static void wlc_lcnphy_vbat_temp_sense_setup(struct brcms_phy *pi, u8 mode) for (i = 0; i < 14; i++) values_to_save[i] = read_phy_reg(pi, tempsense_phy_regs[i]); - suspend = - (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); + suspend = (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); if (!suspend) wlapi_suspend_mac_and_wait(pi->sh->physhim); save_txpwrCtrlEn = read_radio_reg(pi, 0x4a4); @@ -2236,7 +2974,7 @@ static void wlc_lcnphy_vbat_temp_sense_setup(struct brcms_phy *pi, u8 mode) auxpga_gain = 2; } auxpga_vmid = - (u16) ((2 << 8) | (auxpga_vmidcourse << 4) | auxpga_vmidfine); + (u16) ((2 << 8) | (auxpga_vmidcourse << 4) | auxpga_vmidfine); mod_phy_reg(pi, 0x4d8, (0x1 << 0), (1) << 0); mod_phy_reg(pi, 0x4d8, (0x3ff << 2), (auxpga_vmid) << 2); @@ -2280,17 +3018,10 @@ static void wlc_lcnphy_tx_pwr_ctrl_init(struct brcms_phy_pub *ppi) struct brcms_phy *pi = (struct brcms_phy *) ppi; suspend = - (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); + (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); if (!suspend) wlapi_suspend_mac_and_wait(pi->sh->physhim); - if (NORADIO_ENAB(pi->pubpi)) { - wlc_lcnphy_set_bbmult(pi, 0x30); - if (!suspend) - wlapi_enable_mac(pi->sh->physhim); - return; - } - if (!pi->hwpwrctrl_capable) { if (CHSPEC_IS2G(pi->radio_chanspec)) { tx_gains.gm_gain = 4; @@ -2382,26 +3113,6 @@ wlc_lcnphy_get_radio_loft(struct brcms_phy *pi, *fq0 = LCNPHY_IQLOCC_READ(read_radio_reg(pi, RADIO_2064_REG08C)); } -static void -wlc_lcnphy_get_tx_gain(struct brcms_phy *pi, struct lcnphy_txgains *gains) -{ - u16 dac_gain; - - dac_gain = read_phy_reg(pi, 0x439) >> 0; - gains->dac_gain = (dac_gain & 0x380) >> 7; - - { - u16 rfgain0, rfgain1; - - rfgain0 = (read_phy_reg(pi, 0x4b5) & (0xffff << 0)) >> 0; - rfgain1 = (read_phy_reg(pi, 0x4fb) & (0x7fff << 0)) >> 0; - - gains->gm_gain = rfgain0 & 0xff; - gains->pga_gain = (rfgain0 >> 8) & 0xff; - gains->pad_gain = rfgain1 & 0xff; - } -} - void wlc_lcnphy_set_tx_iqcc(struct brcms_phy *pi, u16 a, u16 b) { struct phytbl_info tab; @@ -2489,16 +3200,6 @@ void wlc_lcnphy_set_tx_pwr_by_index(struct brcms_phy *pi, int index) } } -static void wlc_lcnphy_set_trsw_override(struct brcms_phy *pi, bool tx, bool rx) -{ - - mod_phy_reg(pi, 0x44d, - (0x1 << 1) | - (0x1 << 0), (tx ? (0x1 << 1) : 0) | (rx ? (0x1 << 0) : 0)); - - or_phy_reg(pi, 0x44c, (0x1 << 1) | (0x1 << 0)); -} - static void wlc_lcnphy_clear_papd_comptable(struct brcms_phy *pi) { u32 j; @@ -2518,67 +3219,6 @@ static void wlc_lcnphy_clear_papd_comptable(struct brcms_phy *pi) return; } -static void -wlc_lcnphy_set_rx_gain_by_distribution(struct brcms_phy *pi, - u16 trsw, - u16 ext_lna, - u16 biq2, - u16 biq1, - u16 tia, u16 lna2, u16 lna1) -{ - u16 gain0_15, gain16_19; - - gain16_19 = biq2 & 0xf; - gain0_15 = ((biq1 & 0xf) << 12) | - ((tia & 0xf) << 8) | - ((lna2 & 0x3) << 6) | - ((lna2 & 0x3) << 4) | ((lna1 & 0x3) << 2) | ((lna1 & 0x3) << 0); - - mod_phy_reg(pi, 0x4b6, (0xffff << 0), gain0_15 << 0); - mod_phy_reg(pi, 0x4b7, (0xf << 0), gain16_19 << 0); - mod_phy_reg(pi, 0x4b1, (0x3 << 11), lna1 << 11); - - if (LCNREV_LT(pi->pubpi.phy_rev, 2)) { - mod_phy_reg(pi, 0x4b1, (0x1 << 9), ext_lna << 9); - mod_phy_reg(pi, 0x4b1, (0x1 << 10), ext_lna << 10); - } else { - mod_phy_reg(pi, 0x4b1, (0x1 << 10), 0 << 10); - - mod_phy_reg(pi, 0x4b1, (0x1 << 15), 0 << 15); - - mod_phy_reg(pi, 0x4b1, (0x1 << 9), ext_lna << 9); - } - - mod_phy_reg(pi, 0x44d, (0x1 << 0), (!trsw) << 0); - -} - -static void -wlc_lcnphy_rx_gain_override_enable(struct brcms_phy *pi, bool enable) -{ - u16 ebit = enable ? 1 : 0; - - mod_phy_reg(pi, 0x4b0, (0x1 << 8), ebit << 8); - - mod_phy_reg(pi, 0x44c, (0x1 << 0), ebit << 0); - - if (LCNREV_LT(pi->pubpi.phy_rev, 2)) { - mod_phy_reg(pi, 0x44c, (0x1 << 4), ebit << 4); - mod_phy_reg(pi, 0x44c, (0x1 << 6), ebit << 6); - mod_phy_reg(pi, 0x4b0, (0x1 << 5), ebit << 5); - mod_phy_reg(pi, 0x4b0, (0x1 << 6), ebit << 6); - } else { - mod_phy_reg(pi, 0x4b0, (0x1 << 12), ebit << 12); - mod_phy_reg(pi, 0x4b0, (0x1 << 13), ebit << 13); - mod_phy_reg(pi, 0x4b0, (0x1 << 5), ebit << 5); - } - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - mod_phy_reg(pi, 0x4b0, (0x1 << 10), ebit << 10); - mod_phy_reg(pi, 0x4e5, (0x1 << 3), ebit << 3); - } -} - void wlc_lcnphy_tx_pu(struct brcms_phy *pi, bool bEnable) { if (!bEnable) { @@ -2589,9 +3229,9 @@ void wlc_lcnphy_tx_pu(struct brcms_phy *pi, bool bEnable) and_phy_reg(pi, 0x44c, ~(u16) ((0x1 << 3) | - (0x1 << 5) | - (0x1 << 12) | - (0x1 << 0) | (0x1 << 1) | (0x1 << 2))); + (0x1 << 5) | + (0x1 << 12) | + (0x1 << 0) | (0x1 << 1) | (0x1 << 2))); and_phy_reg(pi, 0x44d, ~(u16) ((0x1 << 3) | (0x1 << 5) | (0x1 << 14))); @@ -2701,7 +3341,8 @@ void wlc_lcnphy_deaf_mode(struct brcms_phy *pi, bool mode) mod_phy_reg((pi), 0x410, (0x1 << 6) | (0x1 << 5), - ((CHSPEC_IS2G(pi->radio_chanspec)) ? (!mode) : 0) << + ((CHSPEC_IS2G( + pi->radio_chanspec)) ? (!mode) : 0) << 6 | (!mode) << 5); mod_phy_reg(pi, 0x410, (0x1 << 7), (mode) << 7); } @@ -2714,8 +3355,8 @@ wlc_lcnphy_start_tx_tone(struct brcms_phy *pi, s32 f_kHz, u16 max_val, u8 phy_bw; u16 num_samps, t, k; u32 bw; - fixed theta = 0, rot = 0; - cs32 tone_samp; + s32 theta = 0, rot = 0; + struct cordic_iq tone_samp; u32 data_buf[64]; u16 i_samp, q_samp; struct phytbl_info tab; @@ -2743,12 +3384,12 @@ wlc_lcnphy_start_tx_tone(struct brcms_phy *pi, s32 f_kHz, u16 max_val, } else num_samps = 2; - rot = FIXED((f_kHz * 36) / phy_bw) / 100; + rot = ((f_kHz * 36) / phy_bw) / 100; theta = 0; for (t = 0; t < num_samps; t++) { - wlc_phy_cordic(theta, &tone_samp); + tone_samp = cordic_calc_iq(theta); theta += rot; @@ -2802,10 +3443,359 @@ void wlc_lcnphy_stop_tx_tone(struct brcms_phy *pi) wlc_lcnphy_deaf_mode(pi, false); } -static void wlc_lcnphy_clear_trsw_override(struct brcms_phy *pi) +static void +wlc_lcnphy_set_cc(struct brcms_phy *pi, int cal_type, s16 coeff_x, s16 coeff_y) { + u16 di0dq0; + u16 x, y, data_rf; + int k; + switch (cal_type) { + case 0: + wlc_lcnphy_set_tx_iqcc(pi, coeff_x, coeff_y); + break; + case 2: + di0dq0 = (coeff_x & 0xff) << 8 | (coeff_y & 0xff); + wlc_lcnphy_set_tx_locc(pi, di0dq0); + break; + case 3: + k = wlc_lcnphy_calc_floor(coeff_x, 0); + y = 8 + k; + k = wlc_lcnphy_calc_floor(coeff_x, 1); + x = 8 - k; + data_rf = (x * 16 + y); + write_radio_reg(pi, RADIO_2064_REG089, data_rf); + k = wlc_lcnphy_calc_floor(coeff_y, 0); + y = 8 + k; + k = wlc_lcnphy_calc_floor(coeff_y, 1); + x = 8 - k; + data_rf = (x * 16 + y); + write_radio_reg(pi, RADIO_2064_REG08A, data_rf); + break; + case 4: + k = wlc_lcnphy_calc_floor(coeff_x, 0); + y = 8 + k; + k = wlc_lcnphy_calc_floor(coeff_x, 1); + x = 8 - k; + data_rf = (x * 16 + y); + write_radio_reg(pi, RADIO_2064_REG08B, data_rf); + k = wlc_lcnphy_calc_floor(coeff_y, 0); + y = 8 + k; + k = wlc_lcnphy_calc_floor(coeff_y, 1); + x = 8 - k; + data_rf = (x * 16 + y); + write_radio_reg(pi, RADIO_2064_REG08C, data_rf); + break; + } +} - and_phy_reg(pi, 0x44c, (u16) ~((0x1 << 1) | (0x1 << 0))); +static struct lcnphy_unsign16_struct +wlc_lcnphy_get_cc(struct brcms_phy *pi, int cal_type) +{ + u16 a, b, didq; + u8 di0, dq0, ei, eq, fi, fq; + struct lcnphy_unsign16_struct cc; + cc.re = 0; + cc.im = 0; + switch (cal_type) { + case 0: + wlc_lcnphy_get_tx_iqcc(pi, &a, &b); + cc.re = a; + cc.im = b; + break; + case 2: + didq = wlc_lcnphy_get_tx_locc(pi); + di0 = (((didq & 0xff00) << 16) >> 24); + dq0 = (((didq & 0x00ff) << 24) >> 24); + cc.re = (u16) di0; + cc.im = (u16) dq0; + break; + case 3: + wlc_lcnphy_get_radio_loft(pi, &ei, &eq, &fi, &fq); + cc.re = (u16) ei; + cc.im = (u16) eq; + break; + case 4: + wlc_lcnphy_get_radio_loft(pi, &ei, &eq, &fi, &fq); + cc.re = (u16) fi; + cc.im = (u16) fq; + break; + } + return cc; +} + +static void +wlc_lcnphy_samp_cap(struct brcms_phy *pi, int clip_detect_algo, u16 thresh, + s16 *ptr, int mode) +{ + u32 curval1, curval2, stpptr, curptr, strptr, val; + u16 sslpnCalibClkEnCtrl, timer; + u16 old_sslpnCalibClkEnCtrl; + s16 imag, real; + struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; + + timer = 0; + old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da); + + curval1 = R_REG(&pi->regs->psm_corectlsts); + ptr[130] = 0; + W_REG(&pi->regs->psm_corectlsts, ((1 << 6) | curval1)); + + W_REG(&pi->regs->smpl_clct_strptr, 0x7E00); + W_REG(&pi->regs->smpl_clct_stpptr, 0x8000); + udelay(20); + curval2 = R_REG(&pi->regs->psm_phy_hdr_param); + W_REG(&pi->regs->psm_phy_hdr_param, curval2 | 0x30); + + write_phy_reg(pi, 0x555, 0x0); + write_phy_reg(pi, 0x5a6, 0x5); + + write_phy_reg(pi, 0x5a2, (u16) (mode | mode << 6)); + write_phy_reg(pi, 0x5cf, 3); + write_phy_reg(pi, 0x5a5, 0x3); + write_phy_reg(pi, 0x583, 0x0); + write_phy_reg(pi, 0x584, 0x0); + write_phy_reg(pi, 0x585, 0x0fff); + write_phy_reg(pi, 0x586, 0x0000); + + write_phy_reg(pi, 0x580, 0x4501); + + sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da); + write_phy_reg(pi, 0x6da, (u32) (sslpnCalibClkEnCtrl | 0x2008)); + stpptr = R_REG(&pi->regs->smpl_clct_stpptr); + curptr = R_REG(&pi->regs->smpl_clct_curptr); + do { + udelay(10); + curptr = R_REG(&pi->regs->smpl_clct_curptr); + timer++; + } while ((curptr != stpptr) && (timer < 500)); + + W_REG(&pi->regs->psm_phy_hdr_param, 0x2); + strptr = 0x7E00; + W_REG(&pi->regs->tplatewrptr, strptr); + while (strptr < 0x8000) { + val = R_REG(&pi->regs->tplatewrdata); + imag = ((val >> 16) & 0x3ff); + real = ((val) & 0x3ff); + if (imag > 511) + imag -= 1024; + + if (real > 511) + real -= 1024; + + if (pi_lcn->lcnphy_iqcal_swp_dis) + ptr[(strptr - 0x7E00) / 4] = real; + else + ptr[(strptr - 0x7E00) / 4] = imag; + + if (clip_detect_algo) { + if (imag > thresh || imag < -thresh) { + strptr = 0x8000; + ptr[130] = 1; + } + } + + strptr += 4; + } + + write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl); + W_REG(&pi->regs->psm_phy_hdr_param, curval2); + W_REG(&pi->regs->psm_corectlsts, curval1); +} + +static void +wlc_lcnphy_a1(struct brcms_phy *pi, int cal_type, int num_levels, + int step_size_lg2) +{ + const struct lcnphy_spb_tone *phy_c1; + struct lcnphy_spb_tone phy_c2; + struct lcnphy_unsign16_struct phy_c3; + int phy_c4, phy_c5, k, l, j, phy_c6; + u16 phy_c7, phy_c8, phy_c9; + s16 phy_c10, phy_c11, phy_c12, phy_c13, phy_c14, phy_c15, phy_c16; + s16 *ptr, phy_c17; + s32 phy_c18, phy_c19; + u32 phy_c20, phy_c21; + bool phy_c22, phy_c23, phy_c24, phy_c25; + u16 phy_c26, phy_c27; + u16 phy_c28, phy_c29, phy_c30; + u16 phy_c31; + u16 *phy_c32; + phy_c21 = 0; + phy_c10 = phy_c13 = phy_c14 = phy_c8 = 0; + ptr = kmalloc(sizeof(s16) * 131, GFP_ATOMIC); + if (NULL == ptr) + return; + + phy_c32 = kmalloc(sizeof(u16) * 20, GFP_ATOMIC); + if (NULL == phy_c32) { + kfree(ptr); + return; + } + phy_c26 = read_phy_reg(pi, 0x6da); + phy_c27 = read_phy_reg(pi, 0x6db); + phy_c31 = read_radio_reg(pi, RADIO_2064_REG026); + write_phy_reg(pi, 0x93d, 0xC0); + + wlc_lcnphy_start_tx_tone(pi, 3750, 88, 0); + write_phy_reg(pi, 0x6da, 0xffff); + or_phy_reg(pi, 0x6db, 0x3); + + wlc_lcnphy_tx_iqlo_loopback(pi, phy_c32); + udelay(500); + phy_c28 = read_phy_reg(pi, 0x938); + phy_c29 = read_phy_reg(pi, 0x4d7); + phy_c30 = read_phy_reg(pi, 0x4d8); + or_phy_reg(pi, 0x938, 0x1 << 2); + or_phy_reg(pi, 0x4d7, 0x1 << 2); + or_phy_reg(pi, 0x4d7, 0x1 << 3); + mod_phy_reg(pi, 0x4d7, (0x7 << 12), 0x2 << 12); + or_phy_reg(pi, 0x4d8, 1 << 0); + or_phy_reg(pi, 0x4d8, 1 << 1); + mod_phy_reg(pi, 0x4d8, (0x3ff << 2), 0x23A << 2); + mod_phy_reg(pi, 0x4d8, (0x7 << 12), 0x7 << 12); + phy_c1 = &lcnphy_spb_tone_3750[0]; + phy_c4 = 32; + + if (num_levels == 0) { + if (cal_type != 0) + num_levels = 4; + else + num_levels = 9; + } + if (step_size_lg2 == 0) { + if (cal_type != 0) + step_size_lg2 = 3; + else + step_size_lg2 = 8; + } + + phy_c7 = (1 << step_size_lg2); + phy_c3 = wlc_lcnphy_get_cc(pi, cal_type); + phy_c15 = (s16) phy_c3.re; + phy_c16 = (s16) phy_c3.im; + if (cal_type == 2) { + if (phy_c3.re > 127) + phy_c15 = phy_c3.re - 256; + if (phy_c3.im > 127) + phy_c16 = phy_c3.im - 256; + } + wlc_lcnphy_set_cc(pi, cal_type, phy_c15, phy_c16); + udelay(20); + for (phy_c8 = 0; phy_c7 != 0 && phy_c8 < num_levels; phy_c8++) { + phy_c23 = 1; + phy_c22 = 0; + switch (cal_type) { + case 0: + phy_c10 = 511; + break; + case 2: + phy_c10 = 127; + break; + case 3: + phy_c10 = 15; + break; + case 4: + phy_c10 = 15; + break; + } + + phy_c9 = read_phy_reg(pi, 0x93d); + phy_c9 = 2 * phy_c9; + phy_c24 = 0; + phy_c5 = 7; + phy_c25 = 1; + while (1) { + write_radio_reg(pi, RADIO_2064_REG026, + (phy_c5 & 0x7) | ((phy_c5 & 0x7) << 4)); + udelay(50); + phy_c22 = 0; + ptr[130] = 0; + wlc_lcnphy_samp_cap(pi, 1, phy_c9, &ptr[0], 2); + if (ptr[130] == 1) + phy_c22 = 1; + if (phy_c22) + phy_c5 -= 1; + if ((phy_c22 != phy_c24) && (!phy_c25)) + break; + if (!phy_c22) + phy_c5 += 1; + if (phy_c5 <= 0 || phy_c5 >= 7) + break; + phy_c24 = phy_c22; + phy_c25 = 0; + } + + if (phy_c5 < 0) + phy_c5 = 0; + else if (phy_c5 > 7) + phy_c5 = 7; + + for (k = -phy_c7; k <= phy_c7; k += phy_c7) { + for (l = -phy_c7; l <= phy_c7; l += phy_c7) { + phy_c11 = phy_c15 + k; + phy_c12 = phy_c16 + l; + + if (phy_c11 < -phy_c10) + phy_c11 = -phy_c10; + else if (phy_c11 > phy_c10) + phy_c11 = phy_c10; + if (phy_c12 < -phy_c10) + phy_c12 = -phy_c10; + else if (phy_c12 > phy_c10) + phy_c12 = phy_c10; + wlc_lcnphy_set_cc(pi, cal_type, phy_c11, + phy_c12); + udelay(20); + wlc_lcnphy_samp_cap(pi, 0, 0, ptr, 2); + + phy_c18 = 0; + phy_c19 = 0; + for (j = 0; j < 128; j++) { + if (cal_type != 0) + phy_c6 = j % phy_c4; + else + phy_c6 = (2 * j) % phy_c4; + + phy_c2.re = phy_c1[phy_c6].re; + phy_c2.im = phy_c1[phy_c6].im; + phy_c17 = ptr[j]; + phy_c18 = phy_c18 + phy_c17 * phy_c2.re; + phy_c19 = phy_c19 + phy_c17 * phy_c2.im; + } + + phy_c18 = phy_c18 >> 10; + phy_c19 = phy_c19 >> 10; + phy_c20 = ((phy_c18 * phy_c18) + + (phy_c19 * phy_c19)); + + if (phy_c23 || phy_c20 < phy_c21) { + phy_c21 = phy_c20; + phy_c13 = phy_c11; + phy_c14 = phy_c12; + } + phy_c23 = 0; + } + } + phy_c23 = 1; + phy_c15 = phy_c13; + phy_c16 = phy_c14; + phy_c7 = phy_c7 >> 1; + wlc_lcnphy_set_cc(pi, cal_type, phy_c15, phy_c16); + udelay(20); + } + goto cleanup; +cleanup: + wlc_lcnphy_tx_iqlo_loopback_cleanup(pi, phy_c32); + wlc_lcnphy_stop_tx_tone(pi); + write_phy_reg(pi, 0x6da, phy_c26); + write_phy_reg(pi, 0x6db, phy_c27); + write_phy_reg(pi, 0x938, phy_c28); + write_phy_reg(pi, 0x4d7, phy_c29); + write_phy_reg(pi, 0x4d8, phy_c30); + write_radio_reg(pi, RADIO_2064_REG026, phy_c31); + + kfree(phy_c32); + kfree(ptr); } void wlc_lcnphy_get_tx_iqcc(struct brcms_phy *pi, u16 *a, u16 *b) @@ -2824,6 +3814,28 @@ void wlc_lcnphy_get_tx_iqcc(struct brcms_phy *pi, u16 *a, u16 *b) *b = iqcc[1]; } +static void wlc_lcnphy_tx_iqlo_soft_cal_full(struct brcms_phy *pi) +{ + struct lcnphy_unsign16_struct iqcc0, locc2, locc3, locc4; + + wlc_lcnphy_set_cc(pi, 0, 0, 0); + wlc_lcnphy_set_cc(pi, 2, 0, 0); + wlc_lcnphy_set_cc(pi, 3, 0, 0); + wlc_lcnphy_set_cc(pi, 4, 0, 0); + + wlc_lcnphy_a1(pi, 4, 0, 0); + wlc_lcnphy_a1(pi, 3, 0, 0); + wlc_lcnphy_a1(pi, 2, 3, 2); + wlc_lcnphy_a1(pi, 0, 5, 8); + wlc_lcnphy_a1(pi, 2, 2, 1); + wlc_lcnphy_a1(pi, 0, 4, 3); + + iqcc0 = wlc_lcnphy_get_cc(pi, 0); + locc2 = wlc_lcnphy_get_cc(pi, 2); + locc3 = wlc_lcnphy_get_cc(pi, 3); + locc4 = wlc_lcnphy_get_cc(pi, 4); +} + u16 wlc_lcnphy_get_tx_locc(struct brcms_phy *pi) { struct phytbl_info tab; @@ -2878,7 +3890,6 @@ static void wlc_lcnphy_txpwrtbl_iqlo_cal(struct brcms_phy *pi) lcnphy_recal ? LCNPHY_CAL_RECAL : LCNPHY_CAL_FULL), false); } else { - wlc_lcnphy_tx_iqlo_soft_cal_full(pi); } @@ -2905,10 +3916,8 @@ static void wlc_lcnphy_txpwrtbl_iqlo_cal(struct brcms_phy *pi) wlc_lcnphy_tx_iqlo_cal(pi, &target_gains, LCNPHY_CAL_FULL, false); } else { - wlc_lcnphy_tx_iqlo_soft_cal_full(pi); } - } wlc_lcnphy_get_tx_iqcc(pi, &a, &b); @@ -2927,7 +3936,7 @@ static void wlc_lcnphy_txpwrtbl_iqlo_cal(struct brcms_phy *pi) wlc_lcnphy_read_table(pi, &tab); val = (val & 0xfff00000) | - ((u32) (a & 0x3FF) << 10) | (b & 0x3ff); + ((u32) (a & 0x3FF) << 10) | (b & 0x3ff); wlc_lcnphy_write_table(pi, &tab); val = didq; @@ -2959,13 +3968,10 @@ s16 wlc_lcnphy_tempsense_new(struct brcms_phy *pi, bool mode) s16 avg = 0; bool suspend = 0; - if (NORADIO_ENAB(pi->pubpi)) - return -1; - if (mode == 1) { suspend = - (0 == - (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); + (0 == + (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); if (!suspend) wlapi_suspend_mac_and_wait(pi->sh->physhim); wlc_lcnphy_vbat_temp_sense_setup(pi, TEMPSENSE); @@ -3006,13 +4012,10 @@ u16 wlc_lcnphy_tempsense(struct brcms_phy *pi, bool mode) u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; - if (NORADIO_ENAB(pi->pubpi)) - return -1; - if (mode == 1) { suspend = - (0 == - (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); + (0 == + (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); if (!suspend) wlapi_suspend_mac_and_wait(pi->sh->physhim); wlc_lcnphy_vbat_temp_sense_setup(pi, TEMPSENSE); @@ -3063,8 +4066,9 @@ s8 wlc_lcnphy_tempsense_degree(struct brcms_phy *pi, bool mode) { s32 degree = wlc_lcnphy_tempsense_new(pi, mode); degree = - ((degree << 10) + LCN_TEMPSENSE_OFFSET + (LCN_TEMPSENSE_DEN >> 1)) - / LCN_TEMPSENSE_DEN; + ((degree << + 10) + LCN_TEMPSENSE_OFFSET + (LCN_TEMPSENSE_DEN >> 1)) + / LCN_TEMPSENSE_DEN; return (s8) degree; } @@ -3074,13 +4078,10 @@ s8 wlc_lcnphy_vbatsense(struct brcms_phy *pi, bool mode) s32 avg = 0; bool suspend = 0; - if (NORADIO_ENAB(pi->pubpi)) - return -1; - if (mode == 1) { suspend = - (0 == - (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); + (0 == + (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); if (!suspend) wlapi_suspend_mac_and_wait(pi->sh->physhim); wlc_lcnphy_vbat_temp_sense_setup(pi, VBATSENSE); @@ -3093,9 +4094,8 @@ s8 wlc_lcnphy_vbatsense(struct brcms_phy *pi, bool mode) else avg = (s32) vbatsenseval; - avg = - (avg * LCN_VBAT_SCALE_NOM + - (LCN_VBAT_SCALE_DEN >> 1)) / LCN_VBAT_SCALE_DEN; + avg = (avg * LCN_VBAT_SCALE_NOM + + (LCN_VBAT_SCALE_DEN >> 1)) / LCN_VBAT_SCALE_DEN; if (mode == 1) { if (!suspend) @@ -3118,312 +4118,8 @@ static void wlc_lcnphy_afe_clk_init(struct brcms_phy *pi, u8 mode) wlc_lcnphy_toggle_afe_pwdn(pi); } -static bool -wlc_lcnphy_rx_iq_est(struct brcms_phy *pi, - u16 num_samps, - u8 wait_time, struct lcnphy_iq_est *iq_est) -{ - int wait_count = 0; - bool result = true; - u8 phybw40; - phybw40 = CHSPEC_IS40(pi->radio_chanspec); - - mod_phy_reg(pi, 0x6da, (0x1 << 5), (1) << 5); - - mod_phy_reg(pi, 0x410, (0x1 << 3), (0) << 3); - - mod_phy_reg(pi, 0x482, (0xffff << 0), (num_samps) << 0); - - mod_phy_reg(pi, 0x481, (0xff << 0), ((u16) wait_time) << 0); - - mod_phy_reg(pi, 0x481, (0x1 << 8), (0) << 8); - - mod_phy_reg(pi, 0x481, (0x1 << 9), (1) << 9); - - while (read_phy_reg(pi, 0x481) & (0x1 << 9)) { - - if (wait_count > (10 * 500)) { - result = false; - goto cleanup; - } - udelay(100); - wait_count++; - } - - iq_est->iq_prod = ((u32) read_phy_reg(pi, 0x483) << 16) | - (u32) read_phy_reg(pi, 0x484); - iq_est->i_pwr = ((u32) read_phy_reg(pi, 0x485) << 16) | - (u32) read_phy_reg(pi, 0x486); - iq_est->q_pwr = ((u32) read_phy_reg(pi, 0x487) << 16) | - (u32) read_phy_reg(pi, 0x488); - - cleanup: - mod_phy_reg(pi, 0x410, (0x1 << 3), (1) << 3); - - mod_phy_reg(pi, 0x6da, (0x1 << 5), (0) << 5); - - return result; -} - -static bool wlc_lcnphy_calc_rx_iq_comp(struct brcms_phy *pi, u16 num_samps) -{ -#define LCNPHY_MIN_RXIQ_PWR 2 - bool result; - u16 a0_new, b0_new; - struct lcnphy_iq_est iq_est = { 0, 0, 0 }; - s32 a, b, temp; - s16 iq_nbits, qq_nbits, arsh, brsh; - s32 iq; - u32 ii, qq; - struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; - - a0_new = ((read_phy_reg(pi, 0x645) & (0x3ff << 0)) >> 0); - b0_new = ((read_phy_reg(pi, 0x646) & (0x3ff << 0)) >> 0); - mod_phy_reg(pi, 0x6d1, (0x1 << 2), (0) << 2); - - mod_phy_reg(pi, 0x64b, (0x1 << 6), (1) << 6); - - wlc_lcnphy_set_rx_iq_comp(pi, 0, 0); - - result = wlc_lcnphy_rx_iq_est(pi, num_samps, 32, &iq_est); - if (!result) - goto cleanup; - - iq = (s32) iq_est.iq_prod; - ii = iq_est.i_pwr; - qq = iq_est.q_pwr; - - if ((ii + qq) < LCNPHY_MIN_RXIQ_PWR) { - result = false; - goto cleanup; - } - - iq_nbits = wlc_phy_nbits(iq); - qq_nbits = wlc_phy_nbits(qq); - - arsh = 10 - (30 - iq_nbits); - if (arsh >= 0) { - a = (-(iq << (30 - iq_nbits)) + (ii >> (1 + arsh))); - temp = (s32) (ii >> arsh); - if (temp == 0) { - return false; - } - } else { - a = (-(iq << (30 - iq_nbits)) + (ii << (-1 - arsh))); - temp = (s32) (ii << -arsh); - if (temp == 0) { - return false; - } - } - a /= temp; - brsh = qq_nbits - 31 + 20; - if (brsh >= 0) { - b = (qq << (31 - qq_nbits)); - temp = (s32) (ii >> brsh); - if (temp == 0) { - return false; - } - } else { - b = (qq << (31 - qq_nbits)); - temp = (s32) (ii << -brsh); - if (temp == 0) { - return false; - } - } - b /= temp; - b -= a * a; - b = (s32) int_sqrt((unsigned long) b); - b -= (1 << 10); - a0_new = (u16) (a & 0x3ff); - b0_new = (u16) (b & 0x3ff); - cleanup: - - wlc_lcnphy_set_rx_iq_comp(pi, a0_new, b0_new); - - mod_phy_reg(pi, 0x64b, (0x1 << 0), (1) << 0); - - mod_phy_reg(pi, 0x64b, (0x1 << 3), (1) << 3); - - pi_lcn->lcnphy_cal_results.rxiqcal_coeff_a0 = a0_new; - pi_lcn->lcnphy_cal_results.rxiqcal_coeff_b0 = b0_new; - - return result; -} - -static bool -wlc_lcnphy_rx_iq_cal(struct brcms_phy *pi, - const struct lcnphy_rx_iqcomp *iqcomp, - int iqcomp_sz, bool tx_switch, bool rx_switch, int module, - int tx_gain_idx) -{ - struct lcnphy_txgains old_gains; - u16 tx_pwr_ctrl; - u8 tx_gain_index_old = 0; - bool result = false, tx_gain_override_old = false; - u16 i, Core1TxControl_old, RFOverride0_old, - RFOverrideVal0_old, rfoverride2_old, rfoverride2val_old, - rfoverride3_old, rfoverride3val_old, rfoverride4_old, - rfoverride4val_old, afectrlovr_old, afectrlovrval_old; - int tia_gain; - u32 received_power, rx_pwr_threshold; - u16 old_sslpnCalibClkEnCtrl, old_sslpnRxFeClkEnCtrl; - u16 values_to_save[11]; - s16 *ptr; - struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; - - ptr = kmalloc(sizeof(s16) * 131, GFP_ATOMIC); - if (NULL == ptr) { - return false; - } - if (module == 2) { - while (iqcomp_sz--) { - if (iqcomp[iqcomp_sz].chan == - CHSPEC_CHANNEL(pi->radio_chanspec)) { - - wlc_lcnphy_set_rx_iq_comp(pi, - (u16) - iqcomp[iqcomp_sz].a, - (u16) - iqcomp[iqcomp_sz].b); - result = true; - break; - } - } - goto cal_done; - } - - if (module == 1) { - - tx_pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); - wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF); - - for (i = 0; i < 11; i++) { - values_to_save[i] = - read_radio_reg(pi, rxiq_cal_rf_reg[i]); - } - Core1TxControl_old = read_phy_reg(pi, 0x631); - - or_phy_reg(pi, 0x631, 0x0015); - - RFOverride0_old = read_phy_reg(pi, 0x44c); - RFOverrideVal0_old = read_phy_reg(pi, 0x44d); - rfoverride2_old = read_phy_reg(pi, 0x4b0); - rfoverride2val_old = read_phy_reg(pi, 0x4b1); - rfoverride3_old = read_phy_reg(pi, 0x4f9); - rfoverride3val_old = read_phy_reg(pi, 0x4fa); - rfoverride4_old = read_phy_reg(pi, 0x938); - rfoverride4val_old = read_phy_reg(pi, 0x939); - afectrlovr_old = read_phy_reg(pi, 0x43b); - afectrlovrval_old = read_phy_reg(pi, 0x43c); - old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da); - old_sslpnRxFeClkEnCtrl = read_phy_reg(pi, 0x6db); - - tx_gain_override_old = wlc_lcnphy_tx_gain_override_enabled(pi); - if (tx_gain_override_old) { - wlc_lcnphy_get_tx_gain(pi, &old_gains); - tx_gain_index_old = pi_lcn->lcnphy_current_index; - } - - wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_idx); - - mod_phy_reg(pi, 0x4f9, (0x1 << 0), 1 << 0); - mod_phy_reg(pi, 0x4fa, (0x1 << 0), 0 << 0); - - mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1); - mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1); - - write_radio_reg(pi, RADIO_2064_REG116, 0x06); - write_radio_reg(pi, RADIO_2064_REG12C, 0x07); - write_radio_reg(pi, RADIO_2064_REG06A, 0xd3); - write_radio_reg(pi, RADIO_2064_REG098, 0x03); - write_radio_reg(pi, RADIO_2064_REG00B, 0x7); - mod_radio_reg(pi, RADIO_2064_REG113, 1 << 4, 1 << 4); - write_radio_reg(pi, RADIO_2064_REG01D, 0x01); - write_radio_reg(pi, RADIO_2064_REG114, 0x01); - write_radio_reg(pi, RADIO_2064_REG02E, 0x10); - write_radio_reg(pi, RADIO_2064_REG12A, 0x08); - - mod_phy_reg(pi, 0x938, (0x1 << 0), 1 << 0); - mod_phy_reg(pi, 0x939, (0x1 << 0), 0 << 0); - mod_phy_reg(pi, 0x938, (0x1 << 1), 1 << 1); - mod_phy_reg(pi, 0x939, (0x1 << 1), 1 << 1); - mod_phy_reg(pi, 0x938, (0x1 << 2), 1 << 2); - mod_phy_reg(pi, 0x939, (0x1 << 2), 1 << 2); - mod_phy_reg(pi, 0x938, (0x1 << 3), 1 << 3); - mod_phy_reg(pi, 0x939, (0x1 << 3), 1 << 3); - mod_phy_reg(pi, 0x938, (0x1 << 5), 1 << 5); - mod_phy_reg(pi, 0x939, (0x1 << 5), 0 << 5); - - mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0); - mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0); - - wlc_lcnphy_start_tx_tone(pi, 2000, 120, 0); - write_phy_reg(pi, 0x6da, 0xffff); - or_phy_reg(pi, 0x6db, 0x3); - wlc_lcnphy_set_trsw_override(pi, tx_switch, rx_switch); - wlc_lcnphy_rx_gain_override_enable(pi, true); - - tia_gain = 8; - rx_pwr_threshold = 950; - while (tia_gain > 0) { - tia_gain -= 1; - wlc_lcnphy_set_rx_gain_by_distribution(pi, - 0, 0, 2, 2, - (u16) - tia_gain, 1, 0); - udelay(500); - - received_power = - wlc_lcnphy_measure_digital_power(pi, 2000); - if (received_power < rx_pwr_threshold) - break; - } - result = wlc_lcnphy_calc_rx_iq_comp(pi, 0xffff); - - wlc_lcnphy_stop_tx_tone(pi); - - write_phy_reg(pi, 0x631, Core1TxControl_old); - - write_phy_reg(pi, 0x44c, RFOverrideVal0_old); - write_phy_reg(pi, 0x44d, RFOverrideVal0_old); - write_phy_reg(pi, 0x4b0, rfoverride2_old); - write_phy_reg(pi, 0x4b1, rfoverride2val_old); - write_phy_reg(pi, 0x4f9, rfoverride3_old); - write_phy_reg(pi, 0x4fa, rfoverride3val_old); - write_phy_reg(pi, 0x938, rfoverride4_old); - write_phy_reg(pi, 0x939, rfoverride4val_old); - write_phy_reg(pi, 0x43b, afectrlovr_old); - write_phy_reg(pi, 0x43c, afectrlovrval_old); - write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl); - write_phy_reg(pi, 0x6db, old_sslpnRxFeClkEnCtrl); - - wlc_lcnphy_clear_trsw_override(pi); - - mod_phy_reg(pi, 0x44c, (0x1 << 2), 0 << 2); - - for (i = 0; i < 11; i++) { - write_radio_reg(pi, rxiq_cal_rf_reg[i], - values_to_save[i]); - } - - if (tx_gain_override_old) { - wlc_lcnphy_set_tx_pwr_by_index(pi, tx_gain_index_old); - } else - wlc_lcnphy_disable_tx_gain_override(pi); - wlc_lcnphy_set_tx_pwr_ctrl(pi, tx_pwr_ctrl); - - wlc_lcnphy_rx_gain_override_enable(pi, false); - } - - cal_done: - kfree(ptr); - return result; -} - static void wlc_lcnphy_temp_adj(struct brcms_phy *pi) { - if (NORADIO_ENAB(pi->pubpi)) - return; } static void wlc_lcnphy_glacial_timer_based_cal(struct brcms_phy *pi) @@ -3433,7 +4129,7 @@ static void wlc_lcnphy_glacial_timer_based_cal(struct brcms_phy *pi) u16 SAVE_pwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; suspend = - (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); + (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); if (!suspend) wlapi_suspend_mac_and_wait(pi->sh->physhim); wlc_lcnphy_deaf_mode(pi, true); @@ -3463,24 +4159,21 @@ static void wlc_lcnphy_periodic_cal(struct brcms_phy *pi) s32 tssi, pwr, maxtargetpwr, mintargetpwr; struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; - if (NORADIO_ENAB(pi->pubpi)) - return; - pi->phy_lastcal = pi->sh->now; pi->phy_forcecal = false; full_cal = - (pi_lcn->lcnphy_full_cal_channel != - CHSPEC_CHANNEL(pi->radio_chanspec)); + (pi_lcn->lcnphy_full_cal_channel != + CHSPEC_CHANNEL(pi->radio_chanspec)); pi_lcn->lcnphy_full_cal_channel = CHSPEC_CHANNEL(pi->radio_chanspec); index = pi_lcn->lcnphy_current_index; suspend = - (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); + (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); if (!suspend) { - wlapi_bmac_write_shm(pi->sh->physhim, M_CTS_DURATION, 10000); wlapi_suspend_mac_and_wait(pi->sh->physhim); } + wlc_lcnphy_deaf_mode(pi, true); wlc_lcnphy_txpwrtbl_iqlo_cal(pi); @@ -3531,7 +4224,6 @@ void wlc_lcnphy_calib_modes(struct brcms_phy *pi, uint mode) switch (mode) { case PHY_PERICAL_CHAN: - break; case PHY_FULLCAL: wlc_lcnphy_periodic_cal(pi); @@ -3558,7 +4250,7 @@ void wlc_lcnphy_calib_modes(struct brcms_phy *pi, uint mode) case LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL: if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) wlc_lcnphy_tx_power_adjustment( - (struct brcms_phy_pub *) pi); + (struct brcms_phy_pub *) pi); break; } } @@ -3571,7 +4263,7 @@ void wlc_lcnphy_get_tssi(struct brcms_phy *pi, s8 *ofdm_pwr, s8 *cck_pwr) if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi) && (status & (0x1 << 15))) { *ofdm_pwr = (s8) (((read_phy_reg(pi, 0x4ab) & (0x1ff << 0)) - >> 0) >> 1); + >> 0) >> 1); if (wlc_phy_tpc_isenabled_lcnphy(pi)) cck_offset = pi->tx_power_offset[TXP_FIRST_CCK]; @@ -3591,59 +4283,6 @@ void wlc_phy_cal_init_lcnphy(struct brcms_phy *pi) } -static void -wlc_lcnphy_set_chanspec_tweaks(struct brcms_phy *pi, chanspec_t chanspec) -{ - u8 channel = CHSPEC_CHANNEL(chanspec); - struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; - - if (NORADIO_ENAB(pi->pubpi)) - return; - - if (channel == 14) { - mod_phy_reg(pi, 0x448, (0x3 << 8), (2) << 8); - - } else { - mod_phy_reg(pi, 0x448, (0x3 << 8), (1) << 8); - - } - pi_lcn->lcnphy_bandedge_corr = 2; - if (channel == 1) - pi_lcn->lcnphy_bandedge_corr = 4; - - if (channel == 1 || channel == 2 || channel == 3 || - channel == 4 || channel == 9 || - channel == 10 || channel == 11 || channel == 12) { - si_pmu_pllcontrol(pi->sh->sih, 0x2, 0xffffffff, 0x03000c04); - si_pmu_pllcontrol(pi->sh->sih, 0x3, 0xffffff, 0x0); - si_pmu_pllcontrol(pi->sh->sih, 0x4, 0xffffffff, 0x200005c0); - - si_pmu_pllupd(pi->sh->sih); - write_phy_reg(pi, 0x942, 0); - wlc_lcnphy_txrx_spur_avoidance_mode(pi, false); - pi_lcn->lcnphy_spurmod = 0; - mod_phy_reg(pi, 0x424, (0xff << 8), (0x1b) << 8); - - write_phy_reg(pi, 0x425, 0x5907); - } else { - si_pmu_pllcontrol(pi->sh->sih, 0x2, 0xffffffff, 0x03140c04); - si_pmu_pllcontrol(pi->sh->sih, 0x3, 0xffffff, 0x333333); - si_pmu_pllcontrol(pi->sh->sih, 0x4, 0xffffffff, 0x202c2820); - - si_pmu_pllupd(pi->sh->sih); - write_phy_reg(pi, 0x942, 0); - wlc_lcnphy_txrx_spur_avoidance_mode(pi, true); - - pi_lcn->lcnphy_spurmod = 0; - mod_phy_reg(pi, 0x424, (0xff << 8), (0x1f) << 8); - - write_phy_reg(pi, 0x425, 0x590a); - } - - or_phy_reg(pi, 0x44a, 0x44); - write_phy_reg(pi, 0x44a, 0x80); -} - void wlc_lcnphy_tx_power_adjustment(struct brcms_phy_pub *ppi) { s8 index; @@ -3651,570 +4290,21 @@ void wlc_lcnphy_tx_power_adjustment(struct brcms_phy_pub *ppi) struct brcms_phy *pi = (struct brcms_phy *) ppi; struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); - if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi) && SAVE_txpwrctrl) { + if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi) && + SAVE_txpwrctrl) { index = wlc_lcnphy_tempcompensated_txpwrctrl(pi); index2 = (u16) (index * 2); mod_phy_reg(pi, 0x4a9, (0x1ff << 0), (index2) << 0); - pi_lcn->lcnphy_current_index = (s8) - ((read_phy_reg(pi, 0x4a9) & 0xFF) / 2); - } -} - -static void wlc_lcnphy_set_rx_iq_comp(struct brcms_phy *pi, u16 a, u16 b) -{ - mod_phy_reg(pi, 0x645, (0x3ff << 0), (a) << 0); - - mod_phy_reg(pi, 0x646, (0x3ff << 0), (b) << 0); - - mod_phy_reg(pi, 0x647, (0x3ff << 0), (a) << 0); - - mod_phy_reg(pi, 0x648, (0x3ff << 0), (b) << 0); - - mod_phy_reg(pi, 0x649, (0x3ff << 0), (a) << 0); - - mod_phy_reg(pi, 0x64a, (0x3ff << 0), (b) << 0); - -} - -void wlc_phy_init_lcnphy(struct brcms_phy *pi) -{ - u8 phybw40; - struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; - phybw40 = CHSPEC_IS40(pi->radio_chanspec); - - pi_lcn->lcnphy_cal_counter = 0; - pi_lcn->lcnphy_cal_temper = pi_lcn->lcnphy_rawtempsense; - - or_phy_reg(pi, 0x44a, 0x80); - and_phy_reg(pi, 0x44a, 0x7f); - - wlc_lcnphy_afe_clk_init(pi, AFE_CLK_INIT_MODE_TXRX2X); - - write_phy_reg(pi, 0x60a, 160); - - write_phy_reg(pi, 0x46a, 25); - - wlc_lcnphy_baseband_init(pi); - - wlc_lcnphy_radio_init(pi); - - if (CHSPEC_IS2G(pi->radio_chanspec)) - wlc_lcnphy_tx_pwr_ctrl_init((struct brcms_phy_pub *) pi); - - wlc_phy_chanspec_set((struct brcms_phy_pub *) pi, pi->radio_chanspec); - - si_pmu_regcontrol(pi->sh->sih, 0, 0xf, 0x9); - - si_pmu_chipcontrol(pi->sh->sih, 0, 0xffffffff, 0x03CDDDDD); - - if ((pi->sh->boardflags & BFL_FEM) - && wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) - wlc_lcnphy_set_tx_pwr_by_index(pi, FIXED_TXPWR); - - wlc_lcnphy_agc_temp_init(pi); - - wlc_lcnphy_temp_adj(pi); - - mod_phy_reg(pi, 0x448, (0x1 << 14), (1) << 14); - - udelay(100); - mod_phy_reg(pi, 0x448, (0x1 << 14), (0) << 14); - - wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_HW); - pi_lcn->lcnphy_noise_samples = LCNPHY_NOISE_SAMPLES_DEFAULT; - wlc_lcnphy_calib_modes(pi, PHY_PERICAL_PHYINIT); -} - -static void -wlc_lcnphy_tx_iqlo_loopback(struct brcms_phy *pi, u16 *values_to_save) -{ - u16 vmid; - int i; - for (i = 0; i < 20; i++) { - values_to_save[i] = - read_radio_reg(pi, iqlo_loopback_rf_regs[i]); - } - - mod_phy_reg(pi, 0x44c, (0x1 << 12), 1 << 12); - mod_phy_reg(pi, 0x44d, (0x1 << 14), 1 << 14); - - mod_phy_reg(pi, 0x44c, (0x1 << 11), 1 << 11); - mod_phy_reg(pi, 0x44d, (0x1 << 13), 0 << 13); - - mod_phy_reg(pi, 0x43b, (0x1 << 1), 1 << 1); - mod_phy_reg(pi, 0x43c, (0x1 << 1), 0 << 1); - - mod_phy_reg(pi, 0x43b, (0x1 << 0), 1 << 0); - mod_phy_reg(pi, 0x43c, (0x1 << 0), 0 << 0); - - if (LCNREV_IS(pi->pubpi.phy_rev, 2)) - and_radio_reg(pi, RADIO_2064_REG03A, 0xFD); - else - and_radio_reg(pi, RADIO_2064_REG03A, 0xF9); - or_radio_reg(pi, RADIO_2064_REG11A, 0x1); - - or_radio_reg(pi, RADIO_2064_REG036, 0x01); - or_radio_reg(pi, RADIO_2064_REG11A, 0x18); - udelay(20); - - if (LCNREV_IS(pi->pubpi.phy_rev, 2)) { - if (CHSPEC_IS5G(pi->radio_chanspec)) - mod_radio_reg(pi, RADIO_2064_REG03A, 1, 0); - else - or_radio_reg(pi, RADIO_2064_REG03A, 1); - } else { - if (CHSPEC_IS5G(pi->radio_chanspec)) - mod_radio_reg(pi, RADIO_2064_REG03A, 3, 1); - else - or_radio_reg(pi, RADIO_2064_REG03A, 0x3); - } - - udelay(20); - - write_radio_reg(pi, RADIO_2064_REG025, 0xF); - if (LCNREV_IS(pi->pubpi.phy_rev, 2)) { - if (CHSPEC_IS5G(pi->radio_chanspec)) - mod_radio_reg(pi, RADIO_2064_REG028, 0xF, 0x4); - else - mod_radio_reg(pi, RADIO_2064_REG028, 0xF, 0x6); - } else { - if (CHSPEC_IS5G(pi->radio_chanspec)) - mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, 0x4 << 1); - else - mod_radio_reg(pi, RADIO_2064_REG028, 0x1e, 0x6 << 1); - } - - udelay(20); - - write_radio_reg(pi, RADIO_2064_REG005, 0x8); - or_radio_reg(pi, RADIO_2064_REG112, 0x80); - udelay(20); - - or_radio_reg(pi, RADIO_2064_REG0FF, 0x10); - or_radio_reg(pi, RADIO_2064_REG11F, 0x44); - udelay(20); - - or_radio_reg(pi, RADIO_2064_REG00B, 0x7); - or_radio_reg(pi, RADIO_2064_REG113, 0x10); - udelay(20); - - write_radio_reg(pi, RADIO_2064_REG007, 0x1); - udelay(20); - - vmid = 0x2A6; - mod_radio_reg(pi, RADIO_2064_REG0FC, 0x3 << 0, (vmid >> 8) & 0x3); - write_radio_reg(pi, RADIO_2064_REG0FD, (vmid & 0xff)); - or_radio_reg(pi, RADIO_2064_REG11F, 0x44); - udelay(20); - - or_radio_reg(pi, RADIO_2064_REG0FF, 0x10); - udelay(20); - write_radio_reg(pi, RADIO_2064_REG012, 0x02); - or_radio_reg(pi, RADIO_2064_REG112, 0x06); - write_radio_reg(pi, RADIO_2064_REG036, 0x11); - write_radio_reg(pi, RADIO_2064_REG059, 0xcc); - write_radio_reg(pi, RADIO_2064_REG05C, 0x2e); - write_radio_reg(pi, RADIO_2064_REG078, 0xd7); - write_radio_reg(pi, RADIO_2064_REG092, 0x15); -} - -static void -wlc_lcnphy_samp_cap(struct brcms_phy *pi, int clip_detect_algo, u16 thresh, - s16 *ptr, int mode) -{ - u32 curval1, curval2, stpptr, curptr, strptr, val; - u16 sslpnCalibClkEnCtrl, timer; - u16 old_sslpnCalibClkEnCtrl; - s16 imag, real; - struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; - - timer = 0; - old_sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da); - - curval1 = R_REG(&pi->regs->psm_corectlsts); - ptr[130] = 0; - W_REG(&pi->regs->psm_corectlsts, ((1 << 6) | curval1)); - - W_REG(&pi->regs->smpl_clct_strptr, 0x7E00); - W_REG(&pi->regs->smpl_clct_stpptr, 0x8000); - udelay(20); - curval2 = R_REG(&pi->regs->psm_phy_hdr_param); - W_REG(&pi->regs->psm_phy_hdr_param, curval2 | 0x30); - - write_phy_reg(pi, 0x555, 0x0); - write_phy_reg(pi, 0x5a6, 0x5); - - write_phy_reg(pi, 0x5a2, (u16) (mode | mode << 6)); - write_phy_reg(pi, 0x5cf, 3); - write_phy_reg(pi, 0x5a5, 0x3); - write_phy_reg(pi, 0x583, 0x0); - write_phy_reg(pi, 0x584, 0x0); - write_phy_reg(pi, 0x585, 0x0fff); - write_phy_reg(pi, 0x586, 0x0000); - - write_phy_reg(pi, 0x580, 0x4501); - - sslpnCalibClkEnCtrl = read_phy_reg(pi, 0x6da); - write_phy_reg(pi, 0x6da, (u32) (sslpnCalibClkEnCtrl | 0x2008)); - stpptr = R_REG(&pi->regs->smpl_clct_stpptr); - curptr = R_REG(&pi->regs->smpl_clct_curptr); - do { - udelay(10); - curptr = R_REG(&pi->regs->smpl_clct_curptr); - timer++; - } while ((curptr != stpptr) && (timer < 500)); - - W_REG(&pi->regs->psm_phy_hdr_param, 0x2); - strptr = 0x7E00; - W_REG(&pi->regs->tplatewrptr, strptr); - while (strptr < 0x8000) { - val = R_REG(&pi->regs->tplatewrdata); - imag = ((val >> 16) & 0x3ff); - real = ((val) & 0x3ff); - if (imag > 511) { - imag -= 1024; - } - if (real > 511) { - real -= 1024; - } - if (pi_lcn->lcnphy_iqcal_swp_dis) - ptr[(strptr - 0x7E00) / 4] = real; - else - ptr[(strptr - 0x7E00) / 4] = imag; - if (clip_detect_algo) { - if (imag > thresh || imag < -thresh) { - strptr = 0x8000; - ptr[130] = 1; - } - } - strptr += 4; - } - - write_phy_reg(pi, 0x6da, old_sslpnCalibClkEnCtrl); - W_REG(&pi->regs->psm_phy_hdr_param, curval2); - W_REG(&pi->regs->psm_corectlsts, curval1); -} - -static void wlc_lcnphy_tx_iqlo_soft_cal_full(struct brcms_phy *pi) -{ - struct lcnphy_unsign16_struct iqcc0, locc2, locc3, locc4; - - wlc_lcnphy_set_cc(pi, 0, 0, 0); - wlc_lcnphy_set_cc(pi, 2, 0, 0); - wlc_lcnphy_set_cc(pi, 3, 0, 0); - wlc_lcnphy_set_cc(pi, 4, 0, 0); - - wlc_lcnphy_a1(pi, 4, 0, 0); - wlc_lcnphy_a1(pi, 3, 0, 0); - wlc_lcnphy_a1(pi, 2, 3, 2); - wlc_lcnphy_a1(pi, 0, 5, 8); - wlc_lcnphy_a1(pi, 2, 2, 1); - wlc_lcnphy_a1(pi, 0, 4, 3); - - iqcc0 = wlc_lcnphy_get_cc(pi, 0); - locc2 = wlc_lcnphy_get_cc(pi, 2); - locc3 = wlc_lcnphy_get_cc(pi, 3); - locc4 = wlc_lcnphy_get_cc(pi, 4); -} - -static void -wlc_lcnphy_set_cc(struct brcms_phy *pi, int cal_type, s16 coeff_x, s16 coeff_y) -{ - u16 di0dq0; - u16 x, y, data_rf; - int k; - switch (cal_type) { - case 0: - wlc_lcnphy_set_tx_iqcc(pi, coeff_x, coeff_y); - break; - case 2: - di0dq0 = (coeff_x & 0xff) << 8 | (coeff_y & 0xff); - wlc_lcnphy_set_tx_locc(pi, di0dq0); - break; - case 3: - k = wlc_lcnphy_calc_floor(coeff_x, 0); - y = 8 + k; - k = wlc_lcnphy_calc_floor(coeff_x, 1); - x = 8 - k; - data_rf = (x * 16 + y); - write_radio_reg(pi, RADIO_2064_REG089, data_rf); - k = wlc_lcnphy_calc_floor(coeff_y, 0); - y = 8 + k; - k = wlc_lcnphy_calc_floor(coeff_y, 1); - x = 8 - k; - data_rf = (x * 16 + y); - write_radio_reg(pi, RADIO_2064_REG08A, data_rf); - break; - case 4: - k = wlc_lcnphy_calc_floor(coeff_x, 0); - y = 8 + k; - k = wlc_lcnphy_calc_floor(coeff_x, 1); - x = 8 - k; - data_rf = (x * 16 + y); - write_radio_reg(pi, RADIO_2064_REG08B, data_rf); - k = wlc_lcnphy_calc_floor(coeff_y, 0); - y = 8 + k; - k = wlc_lcnphy_calc_floor(coeff_y, 1); - x = 8 - k; - data_rf = (x * 16 + y); - write_radio_reg(pi, RADIO_2064_REG08C, data_rf); - break; - } -} - -static struct lcnphy_unsign16_struct -wlc_lcnphy_get_cc(struct brcms_phy *pi, int cal_type) -{ - u16 a, b, didq; - u8 di0, dq0, ei, eq, fi, fq; - struct lcnphy_unsign16_struct cc; - cc.re = 0; - cc.im = 0; - switch (cal_type) { - case 0: - wlc_lcnphy_get_tx_iqcc(pi, &a, &b); - cc.re = a; - cc.im = b; - break; - case 2: - didq = wlc_lcnphy_get_tx_locc(pi); - di0 = (((didq & 0xff00) << 16) >> 24); - dq0 = (((didq & 0x00ff) << 24) >> 24); - cc.re = (u16) di0; - cc.im = (u16) dq0; - break; - case 3: - wlc_lcnphy_get_radio_loft(pi, &ei, &eq, &fi, &fq); - cc.re = (u16) ei; - cc.im = (u16) eq; - break; - case 4: - wlc_lcnphy_get_radio_loft(pi, &ei, &eq, &fi, &fq); - cc.re = (u16) fi; - cc.im = (u16) fq; - break; - } - return cc; -} - -static void -wlc_lcnphy_a1(struct brcms_phy *pi, int cal_type, int num_levels, - int step_size_lg2) -{ - const struct lcnphy_spb_tone *phy_c1; - struct lcnphy_spb_tone phy_c2; - struct lcnphy_unsign16_struct phy_c3; - int phy_c4, phy_c5, k, l, j, phy_c6; - u16 phy_c7, phy_c8, phy_c9; - s16 phy_c10, phy_c11, phy_c12, phy_c13, phy_c14, phy_c15, phy_c16; - s16 *ptr, phy_c17; - s32 phy_c18, phy_c19; - u32 phy_c20, phy_c21; - bool phy_c22, phy_c23, phy_c24, phy_c25; - u16 phy_c26, phy_c27; - u16 phy_c28, phy_c29, phy_c30; - u16 phy_c31; - u16 *phy_c32; - phy_c21 = 0; - phy_c10 = phy_c13 = phy_c14 = phy_c8 = 0; - ptr = kmalloc(sizeof(s16) * 131, GFP_ATOMIC); - if (NULL == ptr) { - return; - } - - phy_c32 = kmalloc(sizeof(u16) * 20, GFP_ATOMIC); - if (NULL == phy_c32) { - kfree(ptr); - return; - } - phy_c26 = read_phy_reg(pi, 0x6da); - phy_c27 = read_phy_reg(pi, 0x6db); - phy_c31 = read_radio_reg(pi, RADIO_2064_REG026); - write_phy_reg(pi, 0x93d, 0xC0); - - wlc_lcnphy_start_tx_tone(pi, 3750, 88, 0); - write_phy_reg(pi, 0x6da, 0xffff); - or_phy_reg(pi, 0x6db, 0x3); - - wlc_lcnphy_tx_iqlo_loopback(pi, phy_c32); - udelay(500); - phy_c28 = read_phy_reg(pi, 0x938); - phy_c29 = read_phy_reg(pi, 0x4d7); - phy_c30 = read_phy_reg(pi, 0x4d8); - or_phy_reg(pi, 0x938, 0x1 << 2); - or_phy_reg(pi, 0x4d7, 0x1 << 2); - or_phy_reg(pi, 0x4d7, 0x1 << 3); - mod_phy_reg(pi, 0x4d7, (0x7 << 12), 0x2 << 12); - or_phy_reg(pi, 0x4d8, 1 << 0); - or_phy_reg(pi, 0x4d8, 1 << 1); - mod_phy_reg(pi, 0x4d8, (0x3ff << 2), 0x23A << 2); - mod_phy_reg(pi, 0x4d8, (0x7 << 12), 0x7 << 12); - phy_c1 = &lcnphy_spb_tone_3750[0]; - phy_c4 = 32; - - if (num_levels == 0) { - if (cal_type != 0) { - num_levels = 4; - } else { - num_levels = 9; - } - } - if (step_size_lg2 == 0) { - if (cal_type != 0) { - step_size_lg2 = 3; - } else { - step_size_lg2 = 8; - } - } - - phy_c7 = (1 << step_size_lg2); - phy_c3 = wlc_lcnphy_get_cc(pi, cal_type); - phy_c15 = (s16) phy_c3.re; - phy_c16 = (s16) phy_c3.im; - if (cal_type == 2) { - if (phy_c3.re > 127) - phy_c15 = phy_c3.re - 256; - if (phy_c3.im > 127) - phy_c16 = phy_c3.im - 256; - } - wlc_lcnphy_set_cc(pi, cal_type, phy_c15, phy_c16); - udelay(20); - for (phy_c8 = 0; phy_c7 != 0 && phy_c8 < num_levels; phy_c8++) { - phy_c23 = 1; - phy_c22 = 0; - switch (cal_type) { - case 0: - phy_c10 = 511; - break; - case 2: - phy_c10 = 127; - break; - case 3: - phy_c10 = 15; - break; - case 4: - phy_c10 = 15; - break; - } - - phy_c9 = read_phy_reg(pi, 0x93d); - phy_c9 = 2 * phy_c9; - phy_c24 = 0; - phy_c5 = 7; - phy_c25 = 1; - while (1) { - write_radio_reg(pi, RADIO_2064_REG026, - (phy_c5 & 0x7) | ((phy_c5 & 0x7) << 4)); - udelay(50); - phy_c22 = 0; - ptr[130] = 0; - wlc_lcnphy_samp_cap(pi, 1, phy_c9, &ptr[0], 2); - if (ptr[130] == 1) - phy_c22 = 1; - if (phy_c22) - phy_c5 -= 1; - if ((phy_c22 != phy_c24) && (!phy_c25)) - break; - if (!phy_c22) - phy_c5 += 1; - if (phy_c5 <= 0 || phy_c5 >= 7) - break; - phy_c24 = phy_c22; - phy_c25 = 0; - } - - if (phy_c5 < 0) - phy_c5 = 0; - else if (phy_c5 > 7) - phy_c5 = 7; - - for (k = -phy_c7; k <= phy_c7; k += phy_c7) { - for (l = -phy_c7; l <= phy_c7; l += phy_c7) { - phy_c11 = phy_c15 + k; - phy_c12 = phy_c16 + l; - - if (phy_c11 < -phy_c10) - phy_c11 = -phy_c10; - else if (phy_c11 > phy_c10) - phy_c11 = phy_c10; - if (phy_c12 < -phy_c10) - phy_c12 = -phy_c10; - else if (phy_c12 > phy_c10) - phy_c12 = phy_c10; - wlc_lcnphy_set_cc(pi, cal_type, phy_c11, - phy_c12); - udelay(20); - wlc_lcnphy_samp_cap(pi, 0, 0, ptr, 2); - - phy_c18 = 0; - phy_c19 = 0; - for (j = 0; j < 128; j++) { - if (cal_type != 0) { - phy_c6 = j % phy_c4; - } else { - phy_c6 = (2 * j) % phy_c4; - } - phy_c2.re = phy_c1[phy_c6].re; - phy_c2.im = phy_c1[phy_c6].im; - phy_c17 = ptr[j]; - phy_c18 = phy_c18 + phy_c17 * phy_c2.re; - phy_c19 = phy_c19 + phy_c17 * phy_c2.im; - } - - phy_c18 = phy_c18 >> 10; - phy_c19 = phy_c19 >> 10; - phy_c20 = - ((phy_c18 * phy_c18) + (phy_c19 * phy_c19)); - - if (phy_c23 || phy_c20 < phy_c21) { - phy_c21 = phy_c20; - phy_c13 = phy_c11; - phy_c14 = phy_c12; - } - phy_c23 = 0; - } - } - phy_c23 = 1; - phy_c15 = phy_c13; - phy_c16 = phy_c14; - phy_c7 = phy_c7 >> 1; - wlc_lcnphy_set_cc(pi, cal_type, phy_c15, phy_c16); - udelay(20); - } - goto cleanup; - cleanup: - wlc_lcnphy_tx_iqlo_loopback_cleanup(pi, phy_c32); - wlc_lcnphy_stop_tx_tone(pi); - write_phy_reg(pi, 0x6da, phy_c26); - write_phy_reg(pi, 0x6db, phy_c27); - write_phy_reg(pi, 0x938, phy_c28); - write_phy_reg(pi, 0x4d7, phy_c29); - write_phy_reg(pi, 0x4d8, phy_c30); - write_radio_reg(pi, RADIO_2064_REG026, phy_c31); - - kfree(phy_c32); - kfree(ptr); -} - -static void -wlc_lcnphy_tx_iqlo_loopback_cleanup(struct brcms_phy *pi, u16 *values_to_save) -{ - int i; - - and_phy_reg(pi, 0x44c, 0x0 >> 11); - - and_phy_reg(pi, 0x43b, 0xC); - - for (i = 0; i < 20; i++) { - write_radio_reg(pi, iqlo_loopback_rf_regs[i], - values_to_save[i]); + pi_lcn->lcnphy_current_index = + (s8)((read_phy_reg(pi, 0x4a9) & 0xFF) / 2); } } static void wlc_lcnphy_load_tx_gain_table(struct brcms_phy *pi, - const struct lcnphy_tx_gain_tbl_entry *gain_table) { + const struct lcnphy_tx_gain_tbl_entry *gain_table) +{ u32 j; struct phytbl_info tab; u32 val; @@ -4297,6 +4387,172 @@ static void wlc_lcnphy_load_rfpower(struct brcms_phy *pi) } } +static void wlc_lcnphy_bu_tweaks(struct brcms_phy *pi) +{ + or_phy_reg(pi, 0x805, 0x1); + + mod_phy_reg(pi, 0x42f, (0x7 << 0), (0x3) << 0); + + mod_phy_reg(pi, 0x030, (0x7 << 0), (0x3) << 0); + + write_phy_reg(pi, 0x414, 0x1e10); + write_phy_reg(pi, 0x415, 0x0640); + + mod_phy_reg(pi, 0x4df, (0xff << 8), -9 << 8); + + or_phy_reg(pi, 0x44a, 0x44); + write_phy_reg(pi, 0x44a, 0x80); + mod_phy_reg(pi, 0x434, (0xff << 0), (0xFD) << 0); + + mod_phy_reg(pi, 0x420, (0xff << 0), (16) << 0); + + if (!(pi->sh->boardrev < 0x1204)) + mod_radio_reg(pi, RADIO_2064_REG09B, 0xF0, 0xF0); + + write_phy_reg(pi, 0x7d6, 0x0902); + mod_phy_reg(pi, 0x429, (0xf << 0), (0x9) << 0); + + mod_phy_reg(pi, 0x429, (0x3f << 4), (0xe) << 4); + + if (LCNREV_IS(pi->pubpi.phy_rev, 1)) { + mod_phy_reg(pi, 0x423, (0xff << 0), (0x46) << 0); + + mod_phy_reg(pi, 0x411, (0xff << 0), (1) << 0); + + mod_phy_reg(pi, 0x434, (0xff << 0), (0xFF) << 0); + + mod_phy_reg(pi, 0x656, (0xf << 0), (2) << 0); + + mod_phy_reg(pi, 0x44d, (0x1 << 2), (1) << 2); + + mod_radio_reg(pi, RADIO_2064_REG0F7, 0x4, 0x4); + mod_radio_reg(pi, RADIO_2064_REG0F1, 0x3, 0); + mod_radio_reg(pi, RADIO_2064_REG0F2, 0xF8, 0x90); + mod_radio_reg(pi, RADIO_2064_REG0F3, 0x3, 0x2); + mod_radio_reg(pi, RADIO_2064_REG0F3, 0xf0, 0xa0); + + mod_radio_reg(pi, RADIO_2064_REG11F, 0x2, 0x2); + + wlc_lcnphy_clear_tx_power_offsets(pi); + mod_phy_reg(pi, 0x4d0, (0x1ff << 6), (10) << 6); + + } +} + +static void wlc_lcnphy_rcal(struct brcms_phy *pi) +{ + u8 rcal_value; + + and_radio_reg(pi, RADIO_2064_REG05B, 0xfD); + + or_radio_reg(pi, RADIO_2064_REG004, 0x40); + or_radio_reg(pi, RADIO_2064_REG120, 0x10); + + or_radio_reg(pi, RADIO_2064_REG078, 0x80); + or_radio_reg(pi, RADIO_2064_REG129, 0x02); + + or_radio_reg(pi, RADIO_2064_REG057, 0x01); + + or_radio_reg(pi, RADIO_2064_REG05B, 0x02); + mdelay(5); + SPINWAIT(!wlc_radio_2064_rcal_done(pi), 10 * 1000 * 1000); + + if (wlc_radio_2064_rcal_done(pi)) { + rcal_value = (u8) read_radio_reg(pi, RADIO_2064_REG05C); + rcal_value = rcal_value & 0x1f; + } + + and_radio_reg(pi, RADIO_2064_REG05B, 0xfD); + + and_radio_reg(pi, RADIO_2064_REG057, 0xFE); +} + +static void wlc_lcnphy_rc_cal(struct brcms_phy *pi) +{ + u8 dflt_rc_cal_val; + u16 flt_val; + + dflt_rc_cal_val = 7; + if (LCNREV_IS(pi->pubpi.phy_rev, 1)) + dflt_rc_cal_val = 11; + flt_val = + (dflt_rc_cal_val << 10) | (dflt_rc_cal_val << 5) | + (dflt_rc_cal_val); + write_phy_reg(pi, 0x933, flt_val); + write_phy_reg(pi, 0x934, flt_val); + write_phy_reg(pi, 0x935, flt_val); + write_phy_reg(pi, 0x936, flt_val); + write_phy_reg(pi, 0x937, (flt_val & 0x1FF)); + + return; +} + +static void wlc_radio_2064_init(struct brcms_phy *pi) +{ + u32 i; + struct lcnphy_radio_regs *lcnphyregs = NULL; + + lcnphyregs = lcnphy_radio_regs_2064; + + for (i = 0; lcnphyregs[i].address != 0xffff; i++) + if (CHSPEC_IS5G(pi->radio_chanspec) && lcnphyregs[i].do_init_a) + write_radio_reg(pi, + ((lcnphyregs[i].address & 0x3fff) | + RADIO_DEFAULT_CORE), + (u16) lcnphyregs[i].init_a); + else if (lcnphyregs[i].do_init_g) + write_radio_reg(pi, + ((lcnphyregs[i].address & 0x3fff) | + RADIO_DEFAULT_CORE), + (u16) lcnphyregs[i].init_g); + + write_radio_reg(pi, RADIO_2064_REG032, 0x62); + write_radio_reg(pi, RADIO_2064_REG033, 0x19); + + write_radio_reg(pi, RADIO_2064_REG090, 0x10); + + write_radio_reg(pi, RADIO_2064_REG010, 0x00); + + if (LCNREV_IS(pi->pubpi.phy_rev, 1)) { + + write_radio_reg(pi, RADIO_2064_REG060, 0x7f); + write_radio_reg(pi, RADIO_2064_REG061, 0x72); + write_radio_reg(pi, RADIO_2064_REG062, 0x7f); + } + + write_radio_reg(pi, RADIO_2064_REG01D, 0x02); + write_radio_reg(pi, RADIO_2064_REG01E, 0x06); + + mod_phy_reg(pi, 0x4ea, (0x7 << 0), 0 << 0); + + mod_phy_reg(pi, 0x4ea, (0x7 << 3), 1 << 3); + + mod_phy_reg(pi, 0x4ea, (0x7 << 6), 2 << 6); + + mod_phy_reg(pi, 0x4ea, (0x7 << 9), 3 << 9); + + mod_phy_reg(pi, 0x4ea, (0x7 << 12), 4 << 12); + + write_phy_reg(pi, 0x4ea, 0x4688); + + mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0); + + mod_phy_reg(pi, 0x4eb, (0x7 << 6), 0 << 6); + + mod_phy_reg(pi, 0x46a, (0xffff << 0), 25 << 0); + + wlc_lcnphy_set_tx_locc(pi, 0); + + wlc_lcnphy_rcal(pi); + + wlc_lcnphy_rc_cal(pi); +} + +static void wlc_lcnphy_radio_init(struct brcms_phy *pi) +{ + wlc_radio_2064_init(pi); +} + static void wlc_lcnphy_tbl_init(struct brcms_phy *pi) { uint idx; @@ -4306,9 +4562,8 @@ static void wlc_lcnphy_tbl_init(struct brcms_phy *pi) phybw40 = CHSPEC_IS40(pi->radio_chanspec); - for (idx = 0; idx < dot11lcnphytbl_info_sz_rev0; idx++) { + for (idx = 0; idx < dot11lcnphytbl_info_sz_rev0; idx++) wlc_lcnphy_write_table(pi, &dot11lcnphytbl_info_rev0[idx]); - } if (pi->sh->boardflags & BFL_FEM_BT) { tab.tbl_id = LCNPHY_TBL_ID_RFSEQ; @@ -4339,39 +4594,35 @@ static void wlc_lcnphy_tbl_init(struct brcms_phy *pi) if (CHSPEC_IS2G(pi->radio_chanspec)) { if (pi->sh->boardflags & BFL_FEM) - wlc_lcnphy_load_tx_gain_table(pi, - dot11lcnphy_2GHz_extPA_gaintable_rev0); + wlc_lcnphy_load_tx_gain_table( + pi, + dot11lcnphy_2GHz_extPA_gaintable_rev0); else - wlc_lcnphy_load_tx_gain_table(pi, - dot11lcnphy_2GHz_gaintable_rev0); + wlc_lcnphy_load_tx_gain_table( + pi, + dot11lcnphy_2GHz_gaintable_rev0); } if (LCNREV_IS(pi->pubpi.phy_rev, 2)) { + const struct phytbl_info *tb; + int l; + if (CHSPEC_IS2G(pi->radio_chanspec)) { - for (idx = 0; - idx < dot11lcnphytbl_rx_gain_info_2G_rev2_sz; - idx++) - if (pi->sh->boardflags & BFL_EXTLNA) - wlc_lcnphy_write_table(pi, - &dot11lcnphytbl_rx_gain_info_extlna_2G_rev2 - [idx]); - else - wlc_lcnphy_write_table(pi, - &dot11lcnphytbl_rx_gain_info_2G_rev2 - [idx]); + l = dot11lcnphytbl_rx_gain_info_2G_rev2_sz; + if (pi->sh->boardflags & BFL_EXTLNA) + tb = dot11lcnphytbl_rx_gain_info_extlna_2G_rev2; + else + tb = dot11lcnphytbl_rx_gain_info_2G_rev2; } else { - for (idx = 0; - idx < dot11lcnphytbl_rx_gain_info_5G_rev2_sz; - idx++) - if (pi->sh->boardflags & BFL_EXTLNA_5GHz) - wlc_lcnphy_write_table(pi, - &dot11lcnphytbl_rx_gain_info_extlna_5G_rev2 - [idx]); - else - wlc_lcnphy_write_table(pi, - &dot11lcnphytbl_rx_gain_info_5G_rev2 - [idx]); + l = dot11lcnphytbl_rx_gain_info_5G_rev2_sz; + if (pi->sh->boardflags & BFL_EXTLNA_5GHz) + tb = dot11lcnphytbl_rx_gain_info_extlna_5G_rev2; + else + tb = dot11lcnphytbl_rx_gain_info_5G_rev2; } + + for (idx = 0; idx < l; idx++) + wlc_lcnphy_write_table(pi, &tb[idx]); } if ((pi->sh->boardflags & BFL_FEM) @@ -4379,11 +4630,13 @@ static void wlc_lcnphy_tbl_init(struct brcms_phy *pi) wlc_lcnphy_write_table(pi, &dot11lcn_sw_ctrl_tbl_info_4313_epa); else if (pi->sh->boardflags & BFL_FEM_BT) { if (pi->sh->boardrev < 0x1250) - wlc_lcnphy_write_table(pi, - &dot11lcn_sw_ctrl_tbl_info_4313_bt_epa); + wlc_lcnphy_write_table( + pi, + &dot11lcn_sw_ctrl_tbl_info_4313_bt_epa); else - wlc_lcnphy_write_table(pi, - &dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250); + wlc_lcnphy_write_table( + pi, + &dot11lcn_sw_ctrl_tbl_info_4313_bt_epa_p250); } else wlc_lcnphy_write_table(pi, &dot11lcn_sw_ctrl_tbl_info_4313); @@ -4420,9 +4673,8 @@ static void wlc_lcnphy_rev0_baseband_init(struct brcms_phy *pi) if (0) { afectrl1 = 0; afectrl1 = (u16) ((pi_lcn->lcnphy_rssi_vf) | - (pi_lcn->lcnphy_rssi_vc << 4) | (pi_lcn-> - lcnphy_rssi_gs - << 10)); + (pi_lcn->lcnphy_rssi_vc << 4) | + (pi_lcn->lcnphy_rssi_gs << 10)); write_phy_reg(pi, 0x43e, afectrl1); } @@ -4443,7 +4695,6 @@ static void wlc_lcnphy_rev2_baseband_init(struct brcms_phy *pi) { if (CHSPEC_IS5G(pi->radio_chanspec)) { mod_phy_reg(pi, 0x416, (0xff << 0), 80 << 0); - mod_phy_reg(pi, 0x416, (0xff << 8), 80 << 8); } } @@ -4455,9 +4706,6 @@ static void wlc_lcnphy_agc_temp_init(struct brcms_phy *pi) u32 tableBuffer[2]; struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; - if (NORADIO_ENAB(pi->pubpi)) - return; - temp = (s16) read_phy_reg(pi, 0x4df); pi_lcn->lcnphy_ofdmgainidxtableoffset = (temp & (0xff << 0)) >> 0; @@ -4484,18 +4732,15 @@ static void wlc_lcnphy_agc_temp_init(struct brcms_phy *pi) tableBuffer[1] -= 128; pi_lcn->lcnphy_tr_T_gain_val = tableBuffer[1]; - temp = (s16) (read_phy_reg(pi, 0x434) - & (0xff << 0)); + temp = (s16) (read_phy_reg(pi, 0x434) & (0xff << 0)); if (temp > 127) temp -= 256; pi_lcn->lcnphy_input_pwr_offset_db = (s8) temp; - pi_lcn->lcnphy_Med_Low_Gain_db = (read_phy_reg(pi, 0x424) - & (0xff << 8)) - >> 8; - pi_lcn->lcnphy_Very_Low_Gain_db = (read_phy_reg(pi, 0x425) - & (0xff << 0)) - >> 0; + pi_lcn->lcnphy_Med_Low_Gain_db = + (read_phy_reg(pi, 0x424) & (0xff << 8)) >> 8; + pi_lcn->lcnphy_Very_Low_Gain_db = + (read_phy_reg(pi, 0x425) & (0xff << 0)) >> 0; tab.tbl_ptr = tableBuffer; tab.tbl_len = 2; @@ -4509,61 +4754,6 @@ static void wlc_lcnphy_agc_temp_init(struct brcms_phy *pi) } -static void wlc_lcnphy_bu_tweaks(struct brcms_phy *pi) -{ - if (NORADIO_ENAB(pi->pubpi)) - return; - - or_phy_reg(pi, 0x805, 0x1); - - mod_phy_reg(pi, 0x42f, (0x7 << 0), (0x3) << 0); - - mod_phy_reg(pi, 0x030, (0x7 << 0), (0x3) << 0); - - write_phy_reg(pi, 0x414, 0x1e10); - write_phy_reg(pi, 0x415, 0x0640); - - mod_phy_reg(pi, 0x4df, (0xff << 8), -9 << 8); - - or_phy_reg(pi, 0x44a, 0x44); - write_phy_reg(pi, 0x44a, 0x80); - mod_phy_reg(pi, 0x434, (0xff << 0), (0xFD) << 0); - - mod_phy_reg(pi, 0x420, (0xff << 0), (16) << 0); - - if (!(pi->sh->boardrev < 0x1204)) - mod_radio_reg(pi, RADIO_2064_REG09B, 0xF0, 0xF0); - - write_phy_reg(pi, 0x7d6, 0x0902); - mod_phy_reg(pi, 0x429, (0xf << 0), (0x9) << 0); - - mod_phy_reg(pi, 0x429, (0x3f << 4), (0xe) << 4); - - if (LCNREV_IS(pi->pubpi.phy_rev, 1)) { - mod_phy_reg(pi, 0x423, (0xff << 0), (0x46) << 0); - - mod_phy_reg(pi, 0x411, (0xff << 0), (1) << 0); - - mod_phy_reg(pi, 0x434, (0xff << 0), (0xFF) << 0); - - mod_phy_reg(pi, 0x656, (0xf << 0), (2) << 0); - - mod_phy_reg(pi, 0x44d, (0x1 << 2), (1) << 2); - - mod_radio_reg(pi, RADIO_2064_REG0F7, 0x4, 0x4); - mod_radio_reg(pi, RADIO_2064_REG0F1, 0x3, 0); - mod_radio_reg(pi, RADIO_2064_REG0F2, 0xF8, 0x90); - mod_radio_reg(pi, RADIO_2064_REG0F3, 0x3, 0x2); - mod_radio_reg(pi, RADIO_2064_REG0F3, 0xf0, 0xa0); - - mod_radio_reg(pi, RADIO_2064_REG11F, 0x2, 0x2); - - wlc_lcnphy_clear_tx_power_offsets(pi); - mod_phy_reg(pi, 0x4d0, (0x1ff << 6), (10) << 6); - - } -} - static void wlc_lcnphy_baseband_init(struct brcms_phy *pi) { @@ -4574,127 +4764,53 @@ static void wlc_lcnphy_baseband_init(struct brcms_phy *pi) wlc_lcnphy_bu_tweaks(pi); } -static void wlc_radio_2064_init(struct brcms_phy *pi) +void wlc_phy_init_lcnphy(struct brcms_phy *pi) { - u32 i; - struct lcnphy_radio_regs *lcnphyregs = NULL; - - lcnphyregs = lcnphy_radio_regs_2064; - - for (i = 0; lcnphyregs[i].address != 0xffff; i++) - if (CHSPEC_IS5G(pi->radio_chanspec) && lcnphyregs[i].do_init_a) - write_radio_reg(pi, - ((lcnphyregs[i].address & 0x3fff) | - RADIO_DEFAULT_CORE), - (u16) lcnphyregs[i].init_a); - else if (lcnphyregs[i].do_init_g) - write_radio_reg(pi, - ((lcnphyregs[i].address & 0x3fff) | - RADIO_DEFAULT_CORE), - (u16) lcnphyregs[i].init_g); - - write_radio_reg(pi, RADIO_2064_REG032, 0x62); - write_radio_reg(pi, RADIO_2064_REG033, 0x19); - - write_radio_reg(pi, RADIO_2064_REG090, 0x10); - - write_radio_reg(pi, RADIO_2064_REG010, 0x00); - - if (LCNREV_IS(pi->pubpi.phy_rev, 1)) { - - write_radio_reg(pi, RADIO_2064_REG060, 0x7f); - write_radio_reg(pi, RADIO_2064_REG061, 0x72); - write_radio_reg(pi, RADIO_2064_REG062, 0x7f); - } - - write_radio_reg(pi, RADIO_2064_REG01D, 0x02); - write_radio_reg(pi, RADIO_2064_REG01E, 0x06); - - mod_phy_reg(pi, 0x4ea, (0x7 << 0), 0 << 0); - - mod_phy_reg(pi, 0x4ea, (0x7 << 3), 1 << 3); - - mod_phy_reg(pi, 0x4ea, (0x7 << 6), 2 << 6); - - mod_phy_reg(pi, 0x4ea, (0x7 << 9), 3 << 9); - - mod_phy_reg(pi, 0x4ea, (0x7 << 12), 4 << 12); - - write_phy_reg(pi, 0x4ea, 0x4688); - - mod_phy_reg(pi, 0x4eb, (0x7 << 0), 2 << 0); - - mod_phy_reg(pi, 0x4eb, (0x7 << 6), 0 << 6); - - mod_phy_reg(pi, 0x46a, (0xffff << 0), 25 << 0); - - wlc_lcnphy_set_tx_locc(pi, 0); - - wlc_lcnphy_rcal(pi); + u8 phybw40; + struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; + phybw40 = CHSPEC_IS40(pi->radio_chanspec); - wlc_lcnphy_rc_cal(pi); -} + pi_lcn->lcnphy_cal_counter = 0; + pi_lcn->lcnphy_cal_temper = pi_lcn->lcnphy_rawtempsense; -static void wlc_lcnphy_radio_init(struct brcms_phy *pi) -{ - if (NORADIO_ENAB(pi->pubpi)) - return; + or_phy_reg(pi, 0x44a, 0x80); + and_phy_reg(pi, 0x44a, 0x7f); - wlc_radio_2064_init(pi); -} + wlc_lcnphy_afe_clk_init(pi, AFE_CLK_INIT_MODE_TXRX2X); -static void wlc_lcnphy_rcal(struct brcms_phy *pi) -{ - u8 rcal_value; + write_phy_reg(pi, 0x60a, 160); - if (NORADIO_ENAB(pi->pubpi)) - return; + write_phy_reg(pi, 0x46a, 25); - and_radio_reg(pi, RADIO_2064_REG05B, 0xfD); + wlc_lcnphy_baseband_init(pi); - or_radio_reg(pi, RADIO_2064_REG004, 0x40); - or_radio_reg(pi, RADIO_2064_REG120, 0x10); + wlc_lcnphy_radio_init(pi); - or_radio_reg(pi, RADIO_2064_REG078, 0x80); - or_radio_reg(pi, RADIO_2064_REG129, 0x02); + if (CHSPEC_IS2G(pi->radio_chanspec)) + wlc_lcnphy_tx_pwr_ctrl_init((struct brcms_phy_pub *) pi); - or_radio_reg(pi, RADIO_2064_REG057, 0x01); + wlc_phy_chanspec_set((struct brcms_phy_pub *) pi, pi->radio_chanspec); - or_radio_reg(pi, RADIO_2064_REG05B, 0x02); - mdelay(5); - SPINWAIT(!wlc_radio_2064_rcal_done(pi), 10 * 1000 * 1000); + si_pmu_regcontrol(pi->sh->sih, 0, 0xf, 0x9); - if (wlc_radio_2064_rcal_done(pi)) { - rcal_value = (u8) read_radio_reg(pi, RADIO_2064_REG05C); - rcal_value = rcal_value & 0x1f; - } + si_pmu_chipcontrol(pi->sh->sih, 0, 0xffffffff, 0x03CDDDDD); - and_radio_reg(pi, RADIO_2064_REG05B, 0xfD); + if ((pi->sh->boardflags & BFL_FEM) + && wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) + wlc_lcnphy_set_tx_pwr_by_index(pi, FIXED_TXPWR); - and_radio_reg(pi, RADIO_2064_REG057, 0xFE); -} + wlc_lcnphy_agc_temp_init(pi); -static void wlc_lcnphy_rc_cal(struct brcms_phy *pi) -{ - u8 dflt_rc_cal_val; - u16 flt_val; + wlc_lcnphy_temp_adj(pi); - if (NORADIO_ENAB(pi->pubpi)) - return; + mod_phy_reg(pi, 0x448, (0x1 << 14), (1) << 14); - dflt_rc_cal_val = 7; - if (LCNREV_IS(pi->pubpi.phy_rev, 1)) - dflt_rc_cal_val = 11; - flt_val = - (dflt_rc_cal_val << 10) | (dflt_rc_cal_val << 5) | - (dflt_rc_cal_val); - write_phy_reg(pi, 0x933, flt_val); - write_phy_reg(pi, 0x934, flt_val); - write_phy_reg(pi, 0x935, flt_val); - write_phy_reg(pi, 0x936, flt_val); - write_phy_reg(pi, 0x937, (flt_val & 0x1FF)); + udelay(100); + mod_phy_reg(pi, 0x448, (0x1 << 14), (0) << 14); - return; + wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_HW); + pi_lcn->lcnphy_noise_samples = LCNPHY_NOISE_SAMPLES_DEFAULT; + wlc_lcnphy_calib_modes(pi, PHY_PERICAL_PHYINIT); } static bool wlc_phy_txpwr_srom_read_lcnphy(struct brcms_phy *pi) @@ -4708,10 +4824,10 @@ static bool wlc_phy_txpwr_srom_read_lcnphy(struct brcms_phy *pi) u32 offset_ofdm, offset_mcs; pi_lcn->lcnphy_tr_isolation_mid = - (u8) PHY_GETINTVAR(pi, "triso2g"); + (u8) PHY_GETINTVAR(pi, "triso2g"); pi_lcn->lcnphy_rx_power_offset = - (u8) PHY_GETINTVAR(pi, "rxpo2g"); + (u8) PHY_GETINTVAR(pi, "rxpo2g"); pi->txpa_2g[0] = (s16) PHY_GETINTVAR(pi, "pa0b0"); pi->txpa_2g[1] = (s16) PHY_GETINTVAR(pi, "pa0b1"); @@ -4727,11 +4843,11 @@ static bool wlc_phy_txpwr_srom_read_lcnphy(struct brcms_phy *pi) pi_lcn->lcnphy_rssi_gs_lowtemp = pi_lcn->lcnphy_rssi_gs; pi_lcn->lcnphy_rssi_vf_hightemp = - pi_lcn->lcnphy_rssi_vf; + pi_lcn->lcnphy_rssi_vf; pi_lcn->lcnphy_rssi_vc_hightemp = - pi_lcn->lcnphy_rssi_vc; + pi_lcn->lcnphy_rssi_vc; pi_lcn->lcnphy_rssi_gs_hightemp = - pi_lcn->lcnphy_rssi_gs; + pi_lcn->lcnphy_rssi_gs; } txpwr = (s8) PHY_GETINTVAR(pi, "maxp2ga0"); @@ -4747,15 +4863,16 @@ static bool wlc_phy_txpwr_srom_read_lcnphy(struct brcms_phy *pi) uint max_pwr_chan = txpwr; for (i = TXP_FIRST_CCK; i <= TXP_LAST_CCK; i++) { - pi->tx_srom_max_rate_2g[i] = max_pwr_chan - - ((cckpo & 0xf) * 2); + pi->tx_srom_max_rate_2g[i] = + max_pwr_chan - ((cckpo & 0xf) * 2); cckpo >>= 4; } offset_ofdm = (u32) PHY_GETINTVAR(pi, "ofdm2gpo"); for (i = TXP_FIRST_OFDM; i <= TXP_LAST_OFDM; i++) { - pi->tx_srom_max_rate_2g[i] = max_pwr_chan - - ((offset_ofdm & 0xf) * 2); + pi->tx_srom_max_rate_2g[i] = + max_pwr_chan - + ((offset_ofdm & 0xf) * 2); offset_ofdm >>= 4; } } else { @@ -4763,57 +4880,55 @@ static bool wlc_phy_txpwr_srom_read_lcnphy(struct brcms_phy *pi) opo = (u8) PHY_GETINTVAR(pi, "opo"); - for (i = TXP_FIRST_CCK; i <= TXP_LAST_CCK; i++) { + for (i = TXP_FIRST_CCK; i <= TXP_LAST_CCK; i++) pi->tx_srom_max_rate_2g[i] = txpwr; - } offset_ofdm = (u32) PHY_GETINTVAR(pi, "ofdm2gpo"); for (i = TXP_FIRST_OFDM; i <= TXP_LAST_OFDM; i++) { pi->tx_srom_max_rate_2g[i] = txpwr - - ((offset_ofdm & 0xf) * 2); + ((offset_ofdm & 0xf) * 2); offset_ofdm >>= 4; } offset_mcs = - ((u16) PHY_GETINTVAR(pi, "mcs2gpo1") << 16) | - (u16) PHY_GETINTVAR(pi, "mcs2gpo0"); + ((u16) PHY_GETINTVAR(pi, "mcs2gpo1") << 16) | + (u16) PHY_GETINTVAR(pi, "mcs2gpo0"); pi_lcn->lcnphy_mcs20_po = offset_mcs; for (i = TXP_FIRST_SISO_MCS_20; i <= TXP_LAST_SISO_MCS_20; i++) { pi->tx_srom_max_rate_2g[i] = - txpwr - ((offset_mcs & 0xf) * 2); + txpwr - ((offset_mcs & 0xf) * 2); offset_mcs >>= 4; } } pi_lcn->lcnphy_rawtempsense = - (u16) PHY_GETINTVAR(pi, "rawtempsense"); + (u16) PHY_GETINTVAR(pi, "rawtempsense"); pi_lcn->lcnphy_measPower = - (u8) PHY_GETINTVAR(pi, "measpower"); + (u8) PHY_GETINTVAR(pi, "measpower"); pi_lcn->lcnphy_tempsense_slope = - (u8) PHY_GETINTVAR(pi, "tempsense_slope"); + (u8) PHY_GETINTVAR(pi, "tempsense_slope"); pi_lcn->lcnphy_hw_iqcal_en = - (bool) PHY_GETINTVAR(pi, "hw_iqcal_en"); + (bool) PHY_GETINTVAR(pi, "hw_iqcal_en"); pi_lcn->lcnphy_iqcal_swp_dis = - (bool) PHY_GETINTVAR(pi, "iqcal_swp_dis"); + (bool) PHY_GETINTVAR(pi, "iqcal_swp_dis"); pi_lcn->lcnphy_tempcorrx = - (u8) PHY_GETINTVAR(pi, "tempcorrx"); + (u8) PHY_GETINTVAR(pi, "tempcorrx"); pi_lcn->lcnphy_tempsense_option = - (u8) PHY_GETINTVAR(pi, "tempsense_option"); + (u8) PHY_GETINTVAR(pi, "tempsense_option"); pi_lcn->lcnphy_freqoffset_corr = - (u8) PHY_GETINTVAR(pi, "freqoffset_corr"); + (u8) PHY_GETINTVAR(pi, "freqoffset_corr"); if ((u8) getintvar(pi->vars, "aa2g") > 1) wlc_phy_ant_rxdiv_set((struct brcms_phy_pub *) pi, (u8) getintvar(pi->vars, - "aa2g")); + "aa2g")); } pi_lcn->lcnphy_cck_dig_filt_type = -1; if (PHY_GETVAR(pi, "cckdigfilttype")) { s16 temp; temp = (s16) PHY_GETINTVAR(pi, "cckdigfilttype"); - if (temp >= 0) { + if (temp >= 0) pi_lcn->lcnphy_cck_dig_filt_type = temp; - } } return true; @@ -4834,172 +4949,6 @@ void wlc_2064_vco_cal(struct brcms_phy *pi) mod_radio_reg(pi, RADIO_2064_REG057, 1 << 3, 0); } -static void -wlc_lcnphy_radio_2064_channel_tune_4313(struct brcms_phy *pi, u8 channel) -{ - uint i; - const struct chan_info_2064_lcnphy *ci; - u8 rfpll_doubler = 0; - u8 pll_pwrup, pll_pwrup_ovr; - fixed qFxtal, qFref, qFvco, qFcal; - u8 d15, d16, f16, e44, e45; - u32 div_int, div_frac, fvco3, fpfd, fref3, fcal_div; - u16 loop_bw, d30, setCount; - if (NORADIO_ENAB(pi->pubpi)) - return; - ci = &chan_info_2064_lcnphy[0]; - rfpll_doubler = 1; - - mod_radio_reg(pi, RADIO_2064_REG09D, 0x4, 0x1 << 2); - - write_radio_reg(pi, RADIO_2064_REG09E, 0xf); - if (!rfpll_doubler) { - loop_bw = PLL_2064_LOOP_BW; - d30 = PLL_2064_D30; - } else { - loop_bw = PLL_2064_LOOP_BW_DOUBLER; - d30 = PLL_2064_D30_DOUBLER; - } - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - for (i = 0; i < ARRAY_SIZE(chan_info_2064_lcnphy); i++) - if (chan_info_2064_lcnphy[i].chan == channel) - break; - - if (i >= ARRAY_SIZE(chan_info_2064_lcnphy)) { - return; - } - - ci = &chan_info_2064_lcnphy[i]; - } - - write_radio_reg(pi, RADIO_2064_REG02A, ci->logen_buftune); - - mod_radio_reg(pi, RADIO_2064_REG030, 0x3, ci->logen_rccr_tx); - - mod_radio_reg(pi, RADIO_2064_REG091, 0x3, ci->txrf_mix_tune_ctrl); - - mod_radio_reg(pi, RADIO_2064_REG038, 0xf, ci->pa_input_tune_g); - - mod_radio_reg(pi, RADIO_2064_REG030, 0x3 << 2, - (ci->logen_rccr_rx) << 2); - - mod_radio_reg(pi, RADIO_2064_REG05E, 0xf, ci->pa_rxrf_lna1_freq_tune); - - mod_radio_reg(pi, RADIO_2064_REG05E, (0xf) << 4, - (ci->pa_rxrf_lna2_freq_tune) << 4); - - write_radio_reg(pi, RADIO_2064_REG06C, ci->rxrf_rxrf_spare1); - - pll_pwrup = (u8) read_radio_reg(pi, RADIO_2064_REG044); - pll_pwrup_ovr = (u8) read_radio_reg(pi, RADIO_2064_REG12B); - - or_radio_reg(pi, RADIO_2064_REG044, 0x07); - - or_radio_reg(pi, RADIO_2064_REG12B, (0x07) << 1); - e44 = 0; - e45 = 0; - - fpfd = rfpll_doubler ? (pi->xtalfreq << 1) : (pi->xtalfreq); - if (pi->xtalfreq > 26000000) - e44 = 1; - if (pi->xtalfreq > 52000000) - e45 = 1; - if (e44 == 0) - fcal_div = 1; - else if (e45 == 0) - fcal_div = 2; - else - fcal_div = 4; - fvco3 = (ci->freq * 3); - fref3 = 2 * fpfd; - - qFxtal = wlc_lcnphy_qdiv_roundup(pi->xtalfreq, PLL_2064_MHZ, 16); - qFref = wlc_lcnphy_qdiv_roundup(fpfd, PLL_2064_MHZ, 16); - qFcal = pi->xtalfreq * fcal_div / PLL_2064_MHZ; - qFvco = wlc_lcnphy_qdiv_roundup(fvco3, 2, 16); - - write_radio_reg(pi, RADIO_2064_REG04F, 0x02); - - d15 = (pi->xtalfreq * fcal_div * 4 / 5) / PLL_2064_MHZ - 1; - write_radio_reg(pi, RADIO_2064_REG052, (0x07 & (d15 >> 2))); - write_radio_reg(pi, RADIO_2064_REG053, (d15 & 0x3) << 5); - - d16 = (qFcal * 8 / (d15 + 1)) - 1; - write_radio_reg(pi, RADIO_2064_REG051, d16); - - f16 = ((d16 + 1) * (d15 + 1)) / qFcal; - setCount = f16 * 3 * (ci->freq) / 32 - 1; - mod_radio_reg(pi, RADIO_2064_REG053, (0x0f << 0), - (u8) (setCount >> 8)); - - or_radio_reg(pi, RADIO_2064_REG053, 0x10); - write_radio_reg(pi, RADIO_2064_REG054, (u8) (setCount & 0xff)); - - div_int = ((fvco3 * (PLL_2064_MHZ >> 4)) / fref3) << 4; - - div_frac = ((fvco3 * (PLL_2064_MHZ >> 4)) % fref3) << 4; - while (div_frac >= fref3) { - div_int++; - div_frac -= fref3; - } - div_frac = wlc_lcnphy_qdiv_roundup(div_frac, fref3, 20); - - mod_radio_reg(pi, RADIO_2064_REG045, (0x1f << 0), - (u8) (div_int >> 4)); - mod_radio_reg(pi, RADIO_2064_REG046, (0x1f << 4), - (u8) (div_int << 4)); - mod_radio_reg(pi, RADIO_2064_REG046, (0x0f << 0), - (u8) (div_frac >> 16)); - write_radio_reg(pi, RADIO_2064_REG047, (u8) (div_frac >> 8) & 0xff); - write_radio_reg(pi, RADIO_2064_REG048, (u8) div_frac & 0xff); - - write_radio_reg(pi, RADIO_2064_REG040, 0xfb); - - write_radio_reg(pi, RADIO_2064_REG041, 0x9A); - write_radio_reg(pi, RADIO_2064_REG042, 0xA3); - write_radio_reg(pi, RADIO_2064_REG043, 0x0C); - - { - u8 h29, h23, c28, d29, h28_ten, e30, h30_ten, cp_current; - u16 c29, c38, c30, g30, d28; - c29 = loop_bw; - d29 = 200; - c38 = 1250; - h29 = d29 / c29; - h23 = 1; - c28 = 30; - d28 = (((PLL_2064_HIGH_END_KVCO - PLL_2064_LOW_END_KVCO) * - (fvco3 / 2 - PLL_2064_LOW_END_VCO)) / - (PLL_2064_HIGH_END_VCO - PLL_2064_LOW_END_VCO)) - + PLL_2064_LOW_END_KVCO; - h28_ten = (d28 * 10) / c28; - c30 = 2640; - e30 = (d30 - 680) / 490; - g30 = 680 + (e30 * 490); - h30_ten = (g30 * 10) / c30; - cp_current = ((c38 * h29 * h23 * 100) / h28_ten) / h30_ten; - mod_radio_reg(pi, RADIO_2064_REG03C, 0x3f, cp_current); - } - if (channel >= 1 && channel <= 5) - write_radio_reg(pi, RADIO_2064_REG03C, 0x8); - else - write_radio_reg(pi, RADIO_2064_REG03C, 0x7); - write_radio_reg(pi, RADIO_2064_REG03D, 0x3); - - mod_radio_reg(pi, RADIO_2064_REG044, 0x0c, 0x0c); - udelay(1); - - wlc_2064_vco_cal(pi); - - write_radio_reg(pi, RADIO_2064_REG044, pll_pwrup); - write_radio_reg(pi, RADIO_2064_REG12B, pll_pwrup_ovr); - if (LCNREV_IS(pi->pubpi.phy_rev, 1)) { - write_radio_reg(pi, RADIO_2064_REG038, 3); - write_radio_reg(pi, RADIO_2064_REG091, 7); - } -} - bool wlc_phy_tpc_isenabled_lcnphy(struct brcms_phy *pi) { if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) @@ -5015,14 +4964,11 @@ void wlc_phy_txpower_recalc_target_lcnphy(struct brcms_phy *pi) if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi)) { wlc_lcnphy_calib_modes(pi, LCNPHY_PERICAL_TEMPBASED_TXPWRCTRL); } else if (wlc_lcnphy_tssi_based_pwr_ctrl_enabled(pi)) { - pwr_ctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); wlc_lcnphy_set_tx_pwr_ctrl(pi, LCNPHY_TX_PWR_CTRL_OFF); wlc_lcnphy_txpower_recalc_target(pi); - wlc_lcnphy_set_tx_pwr_ctrl(pi, pwr_ctrl); - } else - return; + } } void wlc_phy_detach_lcnphy(struct brcms_phy *pi) @@ -5035,13 +4981,12 @@ bool wlc_phy_attach_lcnphy(struct brcms_phy *pi) struct brcms_phy_lcnphy *pi_lcn; pi->u.pi_lcnphy = kzalloc(sizeof(struct brcms_phy_lcnphy), GFP_ATOMIC); - if (pi->u.pi_lcnphy == NULL) { + if (pi->u.pi_lcnphy == NULL) return false; - } pi_lcn = pi->u.pi_lcnphy; - if ((0 == (pi->sh->boardflags & BFL_NOPA)) && !NORADIO_ENAB(pi->pubpi)) { + if (0 == (pi->sh->boardflags & BFL_NOPA)) { pi->hwpwrctrl = true; pi->hwpwrctrl_capable = true; } @@ -5062,7 +5007,8 @@ bool wlc_phy_attach_lcnphy(struct brcms_phy *pi) if (!wlc_phy_txpwr_srom_read_lcnphy(pi)) return false; - if ((pi->sh->boardflags & BFL_FEM) && (LCNREV_IS(pi->pubpi.phy_rev, 1))) { + if ((pi->sh->boardflags & BFL_FEM) && + (LCNREV_IS(pi->pubpi.phy_rev, 1))) { if (pi_lcn->lcnphy_tempsense_option == 3) { pi->hwpwrctrl = true; pi->hwpwrctrl_capable = true; @@ -5090,8 +5036,8 @@ static void wlc_lcnphy_set_rx_gain(struct brcms_phy *pi, u32 gain) biq1 = (u16) (gain >> 16) & 0xf; gain0_15 = (u16) ((lna1 & 0x3) | ((lna1 & 0x3) << 2) | - ((lna2 & 0x3) << 4) | ((lna2 & 0x3) << 6) | - ((tia & 0xf) << 8) | ((biq0 & 0xf) << 12)); + ((lna2 & 0x3) << 4) | ((lna2 & 0x3) << 6) | + ((tia & 0xf) << 8) | ((biq0 & 0xf) << 12)); gain16_19 = biq1; mod_phy_reg(pi, 0x44d, (0x1 << 0), trsw << 0); @@ -5126,18 +5072,19 @@ static u32 wlc_lcnphy_get_receive_power(struct brcms_phy *pi, s32 *gain_index) lcnphy_23bitgaincode_table [*gain_index]); received_power = - wlc_lcnphy_measure_digital_power(pi, - pi_lcn-> - lcnphy_noise_samples); + wlc_lcnphy_measure_digital_power( + pi, + pi_lcn-> + lcnphy_noise_samples); (*gain_index)++; } (*gain_index)--; } else { wlc_lcnphy_set_rx_gain(pi, gain_code); received_power = - wlc_lcnphy_measure_digital_power(pi, - pi_lcn-> - lcnphy_noise_samples); + wlc_lcnphy_measure_digital_power(pi, + pi_lcn-> + lcnphy_noise_samples); } return received_power; @@ -5188,7 +5135,7 @@ s32 wlc_lcnphy_rx_signal_power(struct brcms_phy *pi, s32 gain_index) input_power_db = input_power_offset_db - desired_gain; input_power_db = - input_power_db + lcnphy_gain_index_offset_for_rssi[gain_index]; + input_power_db + lcnphy_gain_index_offset_for_rssi[gain_index]; freq = wlc_phy_channel2freq(CHSPEC_CHANNEL(pi->radio_chanspec)); if ((freq > 2427) && (freq <= 2467)) @@ -5196,99 +5143,21 @@ s32 wlc_lcnphy_rx_signal_power(struct brcms_phy *pi, s32 gain_index) temperature = pi_lcn->lcnphy_lastsensed_temperature; - if ((temperature - 15) < -30) { - input_power_db = - input_power_db + (((temperature - 10 - 25) * 286) >> 12) - - 7; - } else if ((temperature - 15) < 4) { + if ((temperature - 15) < -30) input_power_db = - input_power_db + (((temperature - 10 - 25) * 286) >> 12) - - 3; - } else { + input_power_db + + (((temperature - 10 - 25) * 286) >> 12) - + 7; + else if ((temperature - 15) < 4) input_power_db = - input_power_db + (((temperature - 10 - 25) * 286) >> 12); - } + input_power_db + + (((temperature - 10 - 25) * 286) >> 12) - + 3; + else + input_power_db = input_power_db + + (((temperature - 10 - 25) * 286) >> 12); wlc_lcnphy_rx_gain_override_enable(pi, 0); return input_power_db; } - -static int -wlc_lcnphy_load_tx_iir_filter(struct brcms_phy *pi, bool is_ofdm, s16 filt_type) -{ - s16 filt_index = -1; - int j; - - u16 addr[] = { - 0x910, - 0x91e, - 0x91f, - 0x924, - 0x925, - 0x926, - 0x920, - 0x921, - 0x927, - 0x928, - 0x929, - 0x922, - 0x923, - 0x930, - 0x931, - 0x932 - }; - - u16 addr_ofdm[] = { - 0x90f, - 0x900, - 0x901, - 0x906, - 0x907, - 0x908, - 0x902, - 0x903, - 0x909, - 0x90a, - 0x90b, - 0x904, - 0x905, - 0x90c, - 0x90d, - 0x90e - }; - - if (!is_ofdm) { - for (j = 0; j < LCNPHY_NUM_TX_DIG_FILTERS_CCK; j++) { - if (filt_type == LCNPHY_txdigfiltcoeffs_cck[j][0]) { - filt_index = (s16) j; - break; - } - } - - if (filt_index != -1) { - for (j = 0; j < LCNPHY_NUM_DIG_FILT_COEFFS; j++) { - write_phy_reg(pi, addr[j], - LCNPHY_txdigfiltcoeffs_cck - [filt_index][j + 1]); - } - } - } else { - for (j = 0; j < LCNPHY_NUM_TX_DIG_FILTERS_OFDM; j++) { - if (filt_type == LCNPHY_txdigfiltcoeffs_ofdm[j][0]) { - filt_index = (s16) j; - break; - } - } - - if (filt_index != -1) { - for (j = 0; j < LCNPHY_NUM_DIG_FILT_COEFFS; j++) { - write_phy_reg(pi, addr_ofdm[j], - LCNPHY_txdigfiltcoeffs_ofdm - [filt_index][j + 1]); - } - } - } - - return (filt_index != -1) ? 0 : -1; -} diff --git a/drivers/staging/brcm80211/brcmsmac/phy/phy_n.c b/drivers/staging/brcm80211/brcmsmac/phy/phy_n.c index f8e4192..cdf6185 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/phy_n.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/phy_n.c @@ -15,6 +15,7 @@ */ #include <linux/delay.h> +#include <linux/cordic.h> #include <brcm_hw_ids.h> #include <aiutils.h> @@ -28,27 +29,42 @@ #include "phyreg_n.h" #include "phytbl_n.h" -#define READ_RADIO_REG2(pi, radio_type, jspace, core, reg_name) \ - read_radio_reg(pi, radio_type##_##jspace##_##reg_name | \ - ((core == PHY_CORE_0) ? radio_type##_##jspace##0 : radio_type##_##jspace##1)) -#define WRITE_RADIO_REG2(pi, radio_type, jspace, core, reg_name, value) \ +#define READ_RADIO_REG2(pi, radio_type, jspace, core, reg_name) \ + read_radio_reg(pi, radio_type##_##jspace##_##reg_name | \ + ((core == PHY_CORE_0) ? \ + radio_type##_##jspace##0 : \ + radio_type##_##jspace##1)) + +#define WRITE_RADIO_REG2(pi, radio_type, jspace, core, reg_name, value) \ write_radio_reg(pi, radio_type##_##jspace##_##reg_name | \ - ((core == PHY_CORE_0) ? radio_type##_##jspace##0 : radio_type##_##jspace##1), value); -#define WRITE_RADIO_SYN(pi, radio_type, reg_name, value) \ - write_radio_reg(pi, radio_type##_##SYN##_##reg_name, value); - -#define READ_RADIO_REG3(pi, radio_type, jspace, core, reg_name) \ - read_radio_reg(pi, ((core == PHY_CORE_0) ? radio_type##_##jspace##0##_##reg_name : \ - radio_type##_##jspace##1##_##reg_name)); -#define WRITE_RADIO_REG3(pi, radio_type, jspace, core, reg_name, value) \ - write_radio_reg(pi, ((core == PHY_CORE_0) ? radio_type##_##jspace##0##_##reg_name : \ - radio_type##_##jspace##1##_##reg_name), value); -#define READ_RADIO_REG4(pi, radio_type, jspace, core, reg_name) \ - read_radio_reg(pi, ((core == PHY_CORE_0) ? radio_type##_##reg_name##_##jspace##0 : \ - radio_type##_##reg_name##_##jspace##1)); -#define WRITE_RADIO_REG4(pi, radio_type, jspace, core, reg_name, value) \ - write_radio_reg(pi, ((core == PHY_CORE_0) ? radio_type##_##reg_name##_##jspace##0 : \ - radio_type##_##reg_name##_##jspace##1), value); + ((core == PHY_CORE_0) ? \ + radio_type##_##jspace##0 : \ + radio_type##_##jspace##1), value) + +#define WRITE_RADIO_SYN(pi, radio_type, reg_name, value) \ + write_radio_reg(pi, radio_type##_##SYN##_##reg_name, value) + +#define READ_RADIO_REG3(pi, radio_type, jspace, core, reg_name) \ + read_radio_reg(pi, ((core == PHY_CORE_0) ? \ + radio_type##_##jspace##0##_##reg_name : \ + radio_type##_##jspace##1##_##reg_name)) + +#define WRITE_RADIO_REG3(pi, radio_type, jspace, core, reg_name, value) \ + write_radio_reg(pi, ((core == PHY_CORE_0) ? \ + radio_type##_##jspace##0##_##reg_name : \ + radio_type##_##jspace##1##_##reg_name), \ + value) + +#define READ_RADIO_REG4(pi, radio_type, jspace, core, reg_name) \ + read_radio_reg(pi, ((core == PHY_CORE_0) ? \ + radio_type##_##reg_name##_##jspace##0 : \ + radio_type##_##reg_name##_##jspace##1)) + +#define WRITE_RADIO_REG4(pi, radio_type, jspace, core, reg_name, value) \ + write_radio_reg(pi, ((core == PHY_CORE_0) ? \ + radio_type##_##reg_name##_##jspace##0 : \ + radio_type##_##reg_name##_##jspace##1), \ + value) #define NPHY_ACI_MAX_UNDETECT_WINDOW_SZ 40 #define NPHY_ACI_CHANNEL_DELTA 5 @@ -103,9 +119,11 @@ #define NPHY_CALSANITY_RSSI_NB_MAX_POS 9 #define NPHY_CALSANITY_RSSI_NB_MAX_NEG -9 #define NPHY_CALSANITY_RSSI_W1_MAX_POS 12 -#define NPHY_CALSANITY_RSSI_W1_MAX_NEG (NPHY_RSSICAL_W1_TARGET - NPHY_RSSICAL_MAXREAD) +#define NPHY_CALSANITY_RSSI_W1_MAX_NEG (NPHY_RSSICAL_W1_TARGET - \ + NPHY_RSSICAL_MAXREAD) #define NPHY_CALSANITY_RSSI_W2_MAX_POS NPHY_CALSANITY_RSSI_W1_MAX_POS -#define NPHY_CALSANITY_RSSI_W2_MAX_NEG (NPHY_RSSICAL_W2_TARGET - NPHY_RSSICAL_MAXREAD) +#define NPHY_CALSANITY_RSSI_W2_MAX_NEG (NPHY_RSSICAL_W2_TARGET - \ + NPHY_RSSICAL_MAXREAD) #define NPHY_RSSI_SXT(x) ((s8) (-((x) & 0x20) + ((x) & 0x1f))) #define NPHY_RSSI_NB_VIOL(x) (((x) > NPHY_CALSANITY_RSSI_NB_MAX_POS) || \ ((x) < NPHY_CALSANITY_RSSI_NB_MAX_NEG)) @@ -124,11 +142,11 @@ #define NPHY_PAPD_COMP_OFF 0 #define NPHY_PAPD_COMP_ON 1 -#define NPHY_SROM_TEMPSHIFT 32 -#define NPHY_SROM_MAXTEMPOFFSET 16 -#define NPHY_SROM_MINTEMPOFFSET -16 +#define NPHY_SROM_TEMPSHIFT 32 +#define NPHY_SROM_MAXTEMPOFFSET 16 +#define NPHY_SROM_MINTEMPOFFSET -16 -#define NPHY_CAL_MAXTEMPDELTA 64 +#define NPHY_CAL_MAXTEMPDELTA 64 #define NPHY_NOISEVAR_TBLLEN40 256 #define NPHY_NOISEVAR_TBLLEN20 128 @@ -138,8 +156,24 @@ #define NPHY_ADJUSTED_MINCRSPOWER 0x1e /* 5357 Chip specific ChipControl register bits */ -#define CCTRL5357_EXTPA (1<<14) /* extPA in ChipControl 1, bit 14 */ -#define CCTRL5357_ANT_MUX_2o3 (1<<15) /* 2o3 in ChipControl 1, bit 15 */ +#define CCTRL5357_EXTPA (1<<14) /* extPA in ChipControl 1, bit 14 */ +#define CCTRL5357_ANT_MUX_2o3 (1<<15) /* 2o3 in ChipControl 1, bit 15 */ + +#define NPHY_CAL_TSSISAMPS 64 +#define NPHY_TEST_TONE_FREQ_40MHz 4000 +#define NPHY_TEST_TONE_FREQ_20MHz 2500 + +#define MAX_205x_RCAL_WAITLOOPS 10000 + +#define NPHY_RXCAL_TONEAMP 181 +#define NPHY_RXCAL_TONEFREQ_40MHz 4000 +#define NPHY_RXCAL_TONEFREQ_20MHz 2000 + +#define TXFILT_SHAPING_OFDM20 0 +#define TXFILT_SHAPING_OFDM40 1 +#define TXFILT_SHAPING_CCK 2 +#define TXFILT_DEFAULT_OFDM20 3 +#define TXFILT_DEFAULT_OFDM40 4 struct nphy_iqcal_params { u16 txlpf; @@ -184,44 +218,42 @@ struct nphy_ipa_txrxgain { #define NPHY_IPA_RXCAL_MAXGAININDEX (6 - 1) -struct nphy_ipa_txrxgain nphy_ipa_rxcal_gaintbl_5GHz[] = { {0, 0, 0, 0, 0, 100}, -{0, 0, 0, 0, 0, 50}, -{0, 0, 0, 0, 0, -1}, -{0, 0, 0, 3, 0, -1}, -{0, 0, 3, 3, 0, -1}, -{0, 2, 3, 3, 0, -1} +struct nphy_ipa_txrxgain nphy_ipa_rxcal_gaintbl_5GHz[] = { + {0, 0, 0, 0, 0, 100}, + {0, 0, 0, 0, 0, 50}, + {0, 0, 0, 0, 0, -1}, + {0, 0, 0, 3, 0, -1}, + {0, 0, 3, 3, 0, -1}, + {0, 2, 3, 3, 0, -1} }; -struct nphy_ipa_txrxgain nphy_ipa_rxcal_gaintbl_2GHz[] = { {0, 0, 0, 0, 0, 128}, -{0, 0, 0, 0, 0, 70}, -{0, 0, 0, 0, 0, 20}, -{0, 0, 0, 3, 0, 20}, -{0, 0, 3, 3, 0, 20}, -{0, 2, 3, 3, 0, 20} +struct nphy_ipa_txrxgain nphy_ipa_rxcal_gaintbl_2GHz[] = { + {0, 0, 0, 0, 0, 128}, + {0, 0, 0, 0, 0, 70}, + {0, 0, 0, 0, 0, 20}, + {0, 0, 0, 3, 0, 20}, + {0, 0, 3, 3, 0, 20}, + {0, 2, 3, 3, 0, 20} }; struct nphy_ipa_txrxgain nphy_ipa_rxcal_gaintbl_5GHz_rev7[] = { -{0, 0, 0, 0, 0, 100}, -{0, 0, 0, 0, 0, 50}, -{0, 0, 0, 0, 0, -1}, -{0, 0, 0, 3, 0, -1}, -{0, 0, 3, 3, 0, -1}, -{0, 0, 5, 3, 0, -1} + {0, 0, 0, 0, 0, 100}, + {0, 0, 0, 0, 0, 50}, + {0, 0, 0, 0, 0, -1}, + {0, 0, 0, 3, 0, -1}, + {0, 0, 3, 3, 0, -1}, + {0, 0, 5, 3, 0, -1} }; struct nphy_ipa_txrxgain nphy_ipa_rxcal_gaintbl_2GHz_rev7[] = { -{0, 0, 0, 0, 0, 10}, -{0, 0, 0, 1, 0, 10}, -{0, 0, 1, 2, 0, 10}, -{0, 0, 1, 3, 0, 10}, -{0, 0, 4, 3, 0, 10}, -{0, 0, 6, 3, 0, 10} + {0, 0, 0, 0, 0, 10}, + {0, 0, 0, 1, 0, 10}, + {0, 0, 1, 2, 0, 10}, + {0, 0, 1, 3, 0, 10}, + {0, 0, 4, 3, 0, 10}, + {0, 0, 6, 3, 0, 10} }; -#define NPHY_RXCAL_TONEAMP 181 -#define NPHY_RXCAL_TONEFREQ_40MHz 4000 -#define NPHY_RXCAL_TONEFREQ_20MHz 2000 - enum { NPHY_RXCAL_GAIN_INIT = 0, NPHY_RXCAL_GAIN_UP, @@ -230,15 +262,9 @@ enum { #define wlc_phy_get_papd_nphy(pi) \ (read_phy_reg((pi), 0x1e7) & \ - ((0x1 << 15) | \ - (0x1 << 14) | \ - (0x1 << 13))) - -#define TXFILT_SHAPING_OFDM20 0 -#define TXFILT_SHAPING_OFDM40 1 -#define TXFILT_SHAPING_CCK 2 -#define TXFILT_DEFAULT_OFDM20 3 -#define TXFILT_DEFAULT_OFDM40 4 + ((0x1 << 15) | \ + (0x1 << 14) | \ + (0x1 << 13))) u16 NPHY_IPA_REV4_txdigi_filtcoeffs[][NPHY_NUM_DIG_FILT_COEFFS] = { {-377, 137, -407, 208, -1527, 956, 93, 186, 93, @@ -13290,27 +13316,27 @@ static s32 nphy_lnagain_est1[] = { -224, 23242 }; static const u16 tbl_iqcal_gainparams_nphy[2][NPHY_IQCAL_NUMGAINS][8] = { { - {0x000, 0, 0, 2, 0x69, 0x69, 0x69, 0x69}, - {0x700, 7, 0, 0, 0x69, 0x69, 0x69, 0x69}, - {0x710, 7, 1, 0, 0x68, 0x68, 0x68, 0x68}, - {0x720, 7, 2, 0, 0x67, 0x67, 0x67, 0x67}, - {0x730, 7, 3, 0, 0x66, 0x66, 0x66, 0x66}, - {0x740, 7, 4, 0, 0x65, 0x65, 0x65, 0x65}, - {0x741, 7, 4, 1, 0x65, 0x65, 0x65, 0x65}, - {0x742, 7, 4, 2, 0x65, 0x65, 0x65, 0x65}, - {0x743, 7, 4, 3, 0x65, 0x65, 0x65, 0x65} - }, - { - {0x000, 7, 0, 0, 0x79, 0x79, 0x79, 0x79}, - {0x700, 7, 0, 0, 0x79, 0x79, 0x79, 0x79}, - {0x710, 7, 1, 0, 0x79, 0x79, 0x79, 0x79}, - {0x720, 7, 2, 0, 0x78, 0x78, 0x78, 0x78}, - {0x730, 7, 3, 0, 0x78, 0x78, 0x78, 0x78}, - {0x740, 7, 4, 0, 0x78, 0x78, 0x78, 0x78}, - {0x741, 7, 4, 1, 0x78, 0x78, 0x78, 0x78}, - {0x742, 7, 4, 2, 0x78, 0x78, 0x78, 0x78}, - {0x743, 7, 4, 3, 0x78, 0x78, 0x78, 0x78} - } + {0x000, 0, 0, 2, 0x69, 0x69, 0x69, 0x69}, + {0x700, 7, 0, 0, 0x69, 0x69, 0x69, 0x69}, + {0x710, 7, 1, 0, 0x68, 0x68, 0x68, 0x68}, + {0x720, 7, 2, 0, 0x67, 0x67, 0x67, 0x67}, + {0x730, 7, 3, 0, 0x66, 0x66, 0x66, 0x66}, + {0x740, 7, 4, 0, 0x65, 0x65, 0x65, 0x65}, + {0x741, 7, 4, 1, 0x65, 0x65, 0x65, 0x65}, + {0x742, 7, 4, 2, 0x65, 0x65, 0x65, 0x65}, + {0x743, 7, 4, 3, 0x65, 0x65, 0x65, 0x65} + }, + { + {0x000, 7, 0, 0, 0x79, 0x79, 0x79, 0x79}, + {0x700, 7, 0, 0, 0x79, 0x79, 0x79, 0x79}, + {0x710, 7, 1, 0, 0x79, 0x79, 0x79, 0x79}, + {0x720, 7, 2, 0, 0x78, 0x78, 0x78, 0x78}, + {0x730, 7, 3, 0, 0x78, 0x78, 0x78, 0x78}, + {0x740, 7, 4, 0, 0x78, 0x78, 0x78, 0x78}, + {0x741, 7, 4, 1, 0x78, 0x78, 0x78, 0x78}, + {0x742, 7, 4, 2, 0x78, 0x78, 0x78, 0x78}, + {0x743, 7, 4, 3, 0x78, 0x78, 0x78, 0x78} + } }; static const u32 nphy_tpc_txgain[] = { @@ -14081,118 +14107,11 @@ static u32 nphy_tpc_5GHz_txgain_HiPwrEPA[] = { static u8 ant_sw_ctrl_tbl_rev8_2o3[] = { 0x14, 0x18 }; static u8 ant_sw_ctrl_tbl_rev8[] = { 0x4, 0x8, 0x4, 0x8, 0x11, 0x12 }; static u8 ant_sw_ctrl_tbl_rev8_2057v7_core0[] = { - 0x09, 0x0a, 0x15, 0x16, 0x09, 0x0a }; + 0x09, 0x0a, 0x15, 0x16, 0x09, 0x0a +}; static u8 ant_sw_ctrl_tbl_rev8_2057v7_core1[] = { - 0x09, 0x0a, 0x09, 0x0a, 0x15, 0x16 }; - -static bool wlc_phy_chan2freq_nphy(struct brcms_phy *pi, uint channel, int *f, - struct chan_info_nphy_radio2057 **t0, - struct chan_info_nphy_radio205x **t1, - struct chan_info_nphy_radio2057_rev5 **t2, - struct chan_info_nphy_2055 **t3); -static void wlc_phy_chanspec_nphy_setup(struct brcms_phy *pi, chanspec_t chans, - const struct nphy_sfo_cfg *c); - -static void wlc_phy_adjust_rx_analpfbw_nphy(struct brcms_phy *pi, - u16 reduction_factr); -static void wlc_phy_adjust_min_noisevar_nphy(struct brcms_phy *pi, - int ntones, int *, u32 *buf); -static void wlc_phy_adjust_crsminpwr_nphy(struct brcms_phy *pi, u8 minpwr); -static void wlc_phy_txlpfbw_nphy(struct brcms_phy *pi); -static void wlc_phy_spurwar_nphy(struct brcms_phy *pi); - -static void wlc_phy_radio_preinit_2055(struct brcms_phy *pi); -static void wlc_phy_radio_init_2055(struct brcms_phy *pi); -static void wlc_phy_radio_postinit_2055(struct brcms_phy *pi); -static void wlc_phy_radio_preinit_205x(struct brcms_phy *pi); -static void wlc_phy_radio_init_2056(struct brcms_phy *pi); -static void wlc_phy_radio_postinit_2056(struct brcms_phy *pi); -static void wlc_phy_radio_init_2057(struct brcms_phy *pi); -static void wlc_phy_radio_postinit_2057(struct brcms_phy *pi); -static void wlc_phy_workarounds_nphy(struct brcms_phy *pi); -static void wlc_phy_workarounds_nphy_gainctrl(struct brcms_phy *pi); -static void wlc_phy_workarounds_nphy_gainctrl_2057_rev5(struct brcms_phy *pi); -static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(struct brcms_phy *pi); -static void wlc_phy_adjust_lnagaintbl_nphy(struct brcms_phy *pi); - -static void wlc_phy_restore_rssical_nphy(struct brcms_phy *pi); -static void wlc_phy_reapply_txcal_coeffs_nphy(struct brcms_phy *pi); -static void wlc_phy_tx_iq_war_nphy(struct brcms_phy *pi); -static int wlc_phy_cal_rxiq_nphy_rev3(struct brcms_phy *pi, - struct nphy_txgains tg, u8 type, bool d); -static void wlc_phy_rxcal_gainctrl_nphy_rev5(struct brcms_phy *pi, u8 rxcore, - u16 *rg, u8 type); -static void wlc_phy_update_mimoconfig_nphy(struct brcms_phy *pi, s32 preamble); -static void wlc_phy_savecal_nphy(struct brcms_phy *pi); -static void wlc_phy_restorecal_nphy(struct brcms_phy *pi); -static void wlc_phy_resetcca_nphy(struct brcms_phy *pi); - -static void wlc_phy_txpwrctrl_config_nphy(struct brcms_phy *pi); -static void wlc_phy_internal_cal_txgain_nphy(struct brcms_phy *pi); -static void wlc_phy_precal_txgain_nphy(struct brcms_phy *pi); -static void wlc_phy_update_txcal_ladder_nphy(struct brcms_phy *pi, u16 core); - -static void wlc_phy_extpa_set_tx_digi_filts_nphy(struct brcms_phy *pi); -static void wlc_phy_ipa_set_tx_digi_filts_nphy(struct brcms_phy *pi); -static void wlc_phy_ipa_restore_tx_digi_filts_nphy(struct brcms_phy *pi); -static u16 wlc_phy_ipa_get_bbmult_nphy(struct brcms_phy *pi); -static void wlc_phy_ipa_set_bbmult_nphy(struct brcms_phy *pi, u8 m0, u8 m1); -static u32 *wlc_phy_get_ipa_gaintbl_nphy(struct brcms_phy *pi); - -static void wlc_phy_a1_nphy(struct brcms_phy *pi, u8 core, u32 winsz, u32, - u32 e); -static u8 wlc_phy_a3_nphy(struct brcms_phy *pi, u8 start_gain, u8 core); -static void wlc_phy_a2_nphy(struct brcms_phy *pi, struct nphy_ipa_txcalgains *, - enum phy_cal_mode, u8); -static void wlc_phy_papd_cal_cleanup_nphy(struct brcms_phy *pi, - struct nphy_papd_restore_state *state); -static void wlc_phy_papd_cal_setup_nphy(struct brcms_phy *pi, - struct nphy_papd_restore_state *state, u8); - -static void wlc_phy_clip_det_nphy(struct brcms_phy *pi, u8 write, u16 *vals); - -static void wlc_phy_set_rfseq_nphy(struct brcms_phy *pi, u8 cmd, u8 *evts, - u8 *dlys, u8 len); - -static u16 wlc_phy_read_lpf_bw_ctl_nphy(struct brcms_phy *pi, u16 offset); - -static void -wlc_phy_rfctrl_override_nphy_rev7(struct brcms_phy *pi, u16 field, u16 value, - u8 core_mask, u8 off, - u8 override_id); - -static void wlc_phy_rssi_cal_nphy_rev2(struct brcms_phy *pi, u8 rssi_type); -static void wlc_phy_rssi_cal_nphy_rev3(struct brcms_phy *pi); - -static bool wlc_phy_txpwr_srom_read_nphy(struct brcms_phy *pi); -static void wlc_phy_txpwr_nphy_srom_convert(u8 *srom_max, - u16 *pwr_offset, - u8 tmp_max_pwr, u8 rate_start, - u8 rate_end); - -static void wlc_phy_txpwr_limit_to_tbl_nphy(struct brcms_phy *pi); -static void wlc_phy_txpwrctrl_coeff_setup_nphy(struct brcms_phy *pi); -static void wlc_phy_txpwrctrl_idle_tssi_nphy(struct brcms_phy *pi); -static void wlc_phy_txpwrctrl_pwr_setup_nphy(struct brcms_phy *pi); - -static bool wlc_phy_txpwr_ison_nphy(struct brcms_phy *pi); -static u8 wlc_phy_txpwr_idx_cur_get_nphy(struct brcms_phy *pi, u8 core); -static void wlc_phy_txpwr_idx_cur_set_nphy(struct brcms_phy *pi, u8 idx0, - u8 idx1); -static void wlc_phy_a4(struct brcms_phy *pi, bool full_cal); - -static u16 wlc_phy_radio205x_rcal(struct brcms_phy *pi); - -static u16 wlc_phy_radio2057_rccal(struct brcms_phy *pi); - -static u16 wlc_phy_gen_load_samples_nphy(struct brcms_phy *pi, u32 f_kHz, - u16 max_val, - u8 dac_test_mode); -static void wlc_phy_loadsampletable_nphy(struct brcms_phy *pi, cs32 *tone_buf, - u16 num_samps); -static void wlc_phy_runsamples_nphy(struct brcms_phy *pi, u16 n, u16 lps, - u16 wait, u8 iq, u8 dac_test_mode, - bool modify_bbmult); + 0x09, 0x0a, 0x09, 0x0a, 0x15, 0x16 +}; bool wlc_phy_bist_check_phy(struct brcms_phy_pub *pih) { @@ -14209,9 +14128,8 @@ bool wlc_phy_bist_check_phy(struct brcms_phy_pub *pih) phybist4 = read_phy_reg(pi, 0x156); if ((phybist0 == 0) && (phybist1 == 0x4000) && (phybist2 == 0x1fe0) && - (phybist3 == 0) && (phybist4 == 0)) { + (phybist3 == 0) && (phybist4 == 0)) return true; - } return false; } @@ -14230,18 +14148,7 @@ static void wlc_phy_bphy_init_nphy(struct brcms_phy *pi) val -= 0x0202; } - if (NORADIO_ENAB(pi->pubpi)) { - - write_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_PHYCRSTH, 0x3206); - - write_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_RSSI_TRESH, 0x281e); - - or_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_LNA_GAIN_RANGE, 0x1a); - - } else { - - write_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_STEP, 0x668); - } + write_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_STEP, 0x668); } void @@ -14307,7 +14214,8 @@ static void wlc_phy_tbl_init_nphy(struct brcms_phy *pi) if (NREV_GE(pi->pubpi.phy_rev, 7)) { antswctrllut = CHSPEC_IS2G(pi->radio_chanspec) ? - pi->srom_fem2g.antswctrllut : pi->srom_fem5g.antswctrllut; + pi->srom_fem2g.antswctrllut : pi->srom_fem5g. + antswctrllut; switch (antswctrllut) { case 0: @@ -14316,20 +14224,20 @@ static void wlc_phy_tbl_init_nphy(struct brcms_phy *pi) case 1: - if (pi->aa2g == 7) { + if (pi->aa2g == 7) + wlc_phy_table_write_nphy( + pi, + NPHY_TBL_ID_ANTSWCTRLLUT, + 2, 0x21, 8, + &ant_sw_ctrl_tbl_rev8_2o3[0]); + else + wlc_phy_table_write_nphy( + pi, + NPHY_TBL_ID_ANTSWCTRLLUT, + 2, 0x21, 8, + &ant_sw_ctrl_tbl_rev8 + [0]); - wlc_phy_table_write_nphy(pi, - NPHY_TBL_ID_ANTSWCTRLLUT, - 2, 0x21, 8, - &ant_sw_ctrl_tbl_rev8_2o3 - [0]); - } else { - wlc_phy_table_write_nphy(pi, - NPHY_TBL_ID_ANTSWCTRLLUT, - 2, 0x21, 8, - &ant_sw_ctrl_tbl_rev8 - [0]); - } wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, 2, 0x25, 8, &ant_sw_ctrl_tbl_rev8[2]); @@ -14340,31 +14248,31 @@ static void wlc_phy_tbl_init_nphy(struct brcms_phy *pi) case 2: - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, - 2, 0x1, 8, - &ant_sw_ctrl_tbl_rev8_2057v7_core0 - [0]); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, - 2, 0x5, 8, - &ant_sw_ctrl_tbl_rev8_2057v7_core0 - [2]); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, - 2, 0x9, 8, - &ant_sw_ctrl_tbl_rev8_2057v7_core0 - [4]); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, - 2, 0x21, 8, - &ant_sw_ctrl_tbl_rev8_2057v7_core1 - [0]); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, - 2, 0x25, 8, - &ant_sw_ctrl_tbl_rev8_2057v7_core1 - [2]); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_ANTSWCTRLLUT, - 2, 0x29, 8, - &ant_sw_ctrl_tbl_rev8_2057v7_core1 - [4]); + wlc_phy_table_write_nphy( + pi, NPHY_TBL_ID_ANTSWCTRLLUT, + 2, 0x1, 8, + &ant_sw_ctrl_tbl_rev8_2057v7_core0[0]); + wlc_phy_table_write_nphy( + pi, NPHY_TBL_ID_ANTSWCTRLLUT, + 2, 0x5, 8, + &ant_sw_ctrl_tbl_rev8_2057v7_core0[2]); + wlc_phy_table_write_nphy( + pi, NPHY_TBL_ID_ANTSWCTRLLUT, + 2, 0x9, 8, + &ant_sw_ctrl_tbl_rev8_2057v7_core0[4]); + + wlc_phy_table_write_nphy( + pi, NPHY_TBL_ID_ANTSWCTRLLUT, + 2, 0x21, 8, + &ant_sw_ctrl_tbl_rev8_2057v7_core1[0]); + wlc_phy_table_write_nphy( + pi, NPHY_TBL_ID_ANTSWCTRLLUT, + 2, 0x25, 8, + &ant_sw_ctrl_tbl_rev8_2057v7_core1[2]); + wlc_phy_table_write_nphy( + pi, NPHY_TBL_ID_ANTSWCTRLLUT, + 2, 0x29, 8, + &ant_sw_ctrl_tbl_rev8_2057v7_core1[4]); break; default: @@ -14375,45 +14283,49 @@ static void wlc_phy_tbl_init_nphy(struct brcms_phy *pi) for (idx = 0; idx < mimophytbl_info_sz_rev3_volatile; idx++) { if (idx == ANT_SWCTRL_TBL_REV3_IDX) { - antswctrllut = CHSPEC_IS2G(pi->radio_chanspec) ? - pi->srom_fem2g.antswctrllut : pi-> - srom_fem5g.antswctrllut; + antswctrllut = + CHSPEC_IS2G(pi->radio_chanspec) ? + pi->srom_fem2g.antswctrllut : + pi->srom_fem5g.antswctrllut; switch (antswctrllut) { case 0: - wlc_phy_write_table_nphy(pi, - &mimophytbl_info_rev3_volatile - [idx]); + wlc_phy_write_table_nphy( + pi, + &mimophytbl_info_rev3_volatile + [idx]); break; case 1: - wlc_phy_write_table_nphy(pi, - &mimophytbl_info_rev3_volatile1 - [idx]); + wlc_phy_write_table_nphy( + pi, + &mimophytbl_info_rev3_volatile1 + [idx]); break; case 2: - wlc_phy_write_table_nphy(pi, - &mimophytbl_info_rev3_volatile2 - [idx]); + wlc_phy_write_table_nphy( + pi, + &mimophytbl_info_rev3_volatile2 + [idx]); break; case 3: - wlc_phy_write_table_nphy(pi, - &mimophytbl_info_rev3_volatile3 - [idx]); + wlc_phy_write_table_nphy( + pi, + &mimophytbl_info_rev3_volatile3 + [idx]); break; default: break; } } else { - wlc_phy_write_table_nphy(pi, - &mimophytbl_info_rev3_volatile - [idx]); + wlc_phy_write_table_nphy( + pi, + &mimophytbl_info_rev3_volatile[idx]); } } } else { - for (idx = 0; idx < mimophytbl_info_sz_rev0_volatile; idx++) { + for (idx = 0; idx < mimophytbl_info_sz_rev0_volatile; idx++) wlc_phy_write_table_nphy(pi, &mimophytbl_info_rev0_volatile [idx]); - } } } @@ -14440,32 +14352,306 @@ void wlc_phy_nphy_tkip_rifs_war(struct brcms_phy *pi, u8 rifs) wlc_phy_write_txmacreg_nphy(pi, holdoff, delay); - if (pi && pi->sh && (pi->sh->_rifs_phy != rifs)) { + if (pi && pi->sh && (pi->sh->_rifs_phy != rifs)) pi->sh->_rifs_phy = rifs; +} + +static void wlc_phy_txpwrctrl_config_nphy(struct brcms_phy *pi) +{ + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + pi->nphy_txpwrctrl = PHY_TPC_HW_ON; + pi->phy_5g_pwrgain = true; + return; + } + + pi->nphy_txpwrctrl = PHY_TPC_HW_OFF; + pi->phy_5g_pwrgain = false; + + if ((pi->sh->boardflags2 & BFL2_TXPWRCTRL_EN) && + NREV_GE(pi->pubpi.phy_rev, 2) && (pi->sh->sromrev >= 4)) + pi->nphy_txpwrctrl = PHY_TPC_HW_ON; + else if ((pi->sh->sromrev >= 4) + && (pi->sh->boardflags2 & BFL2_5G_PWRGAIN)) + pi->phy_5g_pwrgain = true; +} + +static void wlc_phy_txpwr_srom_read_ppr_nphy(struct brcms_phy *pi) +{ + u16 bw40po, cddpo, stbcpo, bwduppo; + uint band_num; + + if (pi->sh->sromrev >= 9) + return; + + bw40po = (u16) PHY_GETINTVAR(pi, "bw40po"); + pi->bw402gpo = bw40po & 0xf; + pi->bw405gpo = (bw40po & 0xf0) >> 4; + pi->bw405glpo = (bw40po & 0xf00) >> 8; + pi->bw405ghpo = (bw40po & 0xf000) >> 12; + + cddpo = (u16) PHY_GETINTVAR(pi, "cddpo"); + pi->cdd2gpo = cddpo & 0xf; + pi->cdd5gpo = (cddpo & 0xf0) >> 4; + pi->cdd5glpo = (cddpo & 0xf00) >> 8; + pi->cdd5ghpo = (cddpo & 0xf000) >> 12; + + stbcpo = (u16) PHY_GETINTVAR(pi, "stbcpo"); + pi->stbc2gpo = stbcpo & 0xf; + pi->stbc5gpo = (stbcpo & 0xf0) >> 4; + pi->stbc5glpo = (stbcpo & 0xf00) >> 8; + pi->stbc5ghpo = (stbcpo & 0xf000) >> 12; + + bwduppo = (u16) PHY_GETINTVAR(pi, "bwduppo"); + pi->bwdup2gpo = bwduppo & 0xf; + pi->bwdup5gpo = (bwduppo & 0xf0) >> 4; + pi->bwdup5glpo = (bwduppo & 0xf00) >> 8; + pi->bwdup5ghpo = (bwduppo & 0xf000) >> 12; + + for (band_num = 0; band_num < (CH_2G_GROUP + CH_5G_GROUP); + band_num++) { + switch (band_num) { + case 0: + + pi->nphy_txpid2g[PHY_CORE_0] = + (u8) PHY_GETINTVAR(pi, "txpid2ga0"); + pi->nphy_txpid2g[PHY_CORE_1] = + (u8) PHY_GETINTVAR(pi, "txpid2ga1"); + pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_2g = + (s8) PHY_GETINTVAR(pi, "maxp2ga0"); + pi->nphy_pwrctrl_info[PHY_CORE_1].max_pwr_2g = + (s8) PHY_GETINTVAR(pi, "maxp2ga1"); + pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_a1 = + (s16) PHY_GETINTVAR(pi, "pa2gw0a0"); + pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_a1 = + (s16) PHY_GETINTVAR(pi, "pa2gw0a1"); + pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_b0 = + (s16) PHY_GETINTVAR(pi, "pa2gw1a0"); + pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_b0 = + (s16) PHY_GETINTVAR(pi, "pa2gw1a1"); + pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_b1 = + (s16) PHY_GETINTVAR(pi, "pa2gw2a0"); + pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_b1 = + (s16) PHY_GETINTVAR(pi, "pa2gw2a1"); + pi->nphy_pwrctrl_info[PHY_CORE_0].idle_targ_2g = + (s8) PHY_GETINTVAR(pi, "itt2ga0"); + pi->nphy_pwrctrl_info[PHY_CORE_1].idle_targ_2g = + (s8) PHY_GETINTVAR(pi, "itt2ga1"); + + pi->cck2gpo = (u16) PHY_GETINTVAR(pi, "cck2gpo"); + + pi->ofdm2gpo = (u32) PHY_GETINTVAR(pi, "ofdm2gpo"); + + pi->mcs2gpo[0] = (u16) PHY_GETINTVAR(pi, "mcs2gpo0"); + pi->mcs2gpo[1] = (u16) PHY_GETINTVAR(pi, "mcs2gpo1"); + pi->mcs2gpo[2] = (u16) PHY_GETINTVAR(pi, "mcs2gpo2"); + pi->mcs2gpo[3] = (u16) PHY_GETINTVAR(pi, "mcs2gpo3"); + pi->mcs2gpo[4] = (u16) PHY_GETINTVAR(pi, "mcs2gpo4"); + pi->mcs2gpo[5] = (u16) PHY_GETINTVAR(pi, "mcs2gpo5"); + pi->mcs2gpo[6] = (u16) PHY_GETINTVAR(pi, "mcs2gpo6"); + pi->mcs2gpo[7] = (u16) PHY_GETINTVAR(pi, "mcs2gpo7"); + break; + case 1: + + pi->nphy_txpid5g[PHY_CORE_0] = + (u8) PHY_GETINTVAR(pi, "txpid5ga0"); + pi->nphy_txpid5g[PHY_CORE_1] = + (u8) PHY_GETINTVAR(pi, "txpid5ga1"); + pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_5gm = + (s8) PHY_GETINTVAR(pi, "maxp5ga0"); + pi->nphy_pwrctrl_info[PHY_CORE_1].max_pwr_5gm = + (s8) PHY_GETINTVAR(pi, "maxp5ga1"); + pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_a1 = + (s16) PHY_GETINTVAR(pi, "pa5gw0a0"); + pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_a1 = + (s16) PHY_GETINTVAR(pi, "pa5gw0a1"); + pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_b0 = + (s16) PHY_GETINTVAR(pi, "pa5gw1a0"); + pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_b0 = + (s16) PHY_GETINTVAR(pi, "pa5gw1a1"); + pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_b1 = + (s16) PHY_GETINTVAR(pi, "pa5gw2a0"); + pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_b1 = + (s16) PHY_GETINTVAR(pi, "pa5gw2a1"); + pi->nphy_pwrctrl_info[PHY_CORE_0].idle_targ_5gm = + (s8) PHY_GETINTVAR(pi, "itt5ga0"); + pi->nphy_pwrctrl_info[PHY_CORE_1].idle_targ_5gm = + (s8) PHY_GETINTVAR(pi, "itt5ga1"); + + pi->ofdm5gpo = (u32) PHY_GETINTVAR(pi, "ofdm5gpo"); + + pi->mcs5gpo[0] = (u16) PHY_GETINTVAR(pi, "mcs5gpo0"); + pi->mcs5gpo[1] = (u16) PHY_GETINTVAR(pi, "mcs5gpo1"); + pi->mcs5gpo[2] = (u16) PHY_GETINTVAR(pi, "mcs5gpo2"); + pi->mcs5gpo[3] = (u16) PHY_GETINTVAR(pi, "mcs5gpo3"); + pi->mcs5gpo[4] = (u16) PHY_GETINTVAR(pi, "mcs5gpo4"); + pi->mcs5gpo[5] = (u16) PHY_GETINTVAR(pi, "mcs5gpo5"); + pi->mcs5gpo[6] = (u16) PHY_GETINTVAR(pi, "mcs5gpo6"); + pi->mcs5gpo[7] = (u16) PHY_GETINTVAR(pi, "mcs5gpo7"); + break; + case 2: + + pi->nphy_txpid5gl[0] = + (u8) PHY_GETINTVAR(pi, "txpid5gla0"); + pi->nphy_txpid5gl[1] = + (u8) PHY_GETINTVAR(pi, "txpid5gla1"); + pi->nphy_pwrctrl_info[0].max_pwr_5gl = + (s8) PHY_GETINTVAR(pi, "maxp5gla0"); + pi->nphy_pwrctrl_info[1].max_pwr_5gl = + (s8) PHY_GETINTVAR(pi, "maxp5gla1"); + pi->nphy_pwrctrl_info[0].pwrdet_5gl_a1 = + (s16) PHY_GETINTVAR(pi, "pa5glw0a0"); + pi->nphy_pwrctrl_info[1].pwrdet_5gl_a1 = + (s16) PHY_GETINTVAR(pi, "pa5glw0a1"); + pi->nphy_pwrctrl_info[0].pwrdet_5gl_b0 = + (s16) PHY_GETINTVAR(pi, "pa5glw1a0"); + pi->nphy_pwrctrl_info[1].pwrdet_5gl_b0 = + (s16) PHY_GETINTVAR(pi, "pa5glw1a1"); + pi->nphy_pwrctrl_info[0].pwrdet_5gl_b1 = + (s16) PHY_GETINTVAR(pi, "pa5glw2a0"); + pi->nphy_pwrctrl_info[1].pwrdet_5gl_b1 = + (s16) PHY_GETINTVAR(pi, "pa5glw2a1"); + pi->nphy_pwrctrl_info[0].idle_targ_5gl = 0; + pi->nphy_pwrctrl_info[1].idle_targ_5gl = 0; + + pi->ofdm5glpo = (u32) PHY_GETINTVAR(pi, "ofdm5glpo"); + + pi->mcs5glpo[0] = + (u16) PHY_GETINTVAR(pi, "mcs5glpo0"); + pi->mcs5glpo[1] = + (u16) PHY_GETINTVAR(pi, "mcs5glpo1"); + pi->mcs5glpo[2] = + (u16) PHY_GETINTVAR(pi, "mcs5glpo2"); + pi->mcs5glpo[3] = + (u16) PHY_GETINTVAR(pi, "mcs5glpo3"); + pi->mcs5glpo[4] = + (u16) PHY_GETINTVAR(pi, "mcs5glpo4"); + pi->mcs5glpo[5] = + (u16) PHY_GETINTVAR(pi, "mcs5glpo5"); + pi->mcs5glpo[6] = + (u16) PHY_GETINTVAR(pi, "mcs5glpo6"); + pi->mcs5glpo[7] = + (u16) PHY_GETINTVAR(pi, "mcs5glpo7"); + break; + case 3: + + pi->nphy_txpid5gh[0] = + (u8) PHY_GETINTVAR(pi, "txpid5gha0"); + pi->nphy_txpid5gh[1] = + (u8) PHY_GETINTVAR(pi, "txpid5gha1"); + pi->nphy_pwrctrl_info[0].max_pwr_5gh = + (s8) PHY_GETINTVAR(pi, "maxp5gha0"); + pi->nphy_pwrctrl_info[1].max_pwr_5gh = + (s8) PHY_GETINTVAR(pi, "maxp5gha1"); + pi->nphy_pwrctrl_info[0].pwrdet_5gh_a1 = + (s16) PHY_GETINTVAR(pi, "pa5ghw0a0"); + pi->nphy_pwrctrl_info[1].pwrdet_5gh_a1 = + (s16) PHY_GETINTVAR(pi, "pa5ghw0a1"); + pi->nphy_pwrctrl_info[0].pwrdet_5gh_b0 = + (s16) PHY_GETINTVAR(pi, "pa5ghw1a0"); + pi->nphy_pwrctrl_info[1].pwrdet_5gh_b0 = + (s16) PHY_GETINTVAR(pi, "pa5ghw1a1"); + pi->nphy_pwrctrl_info[0].pwrdet_5gh_b1 = + (s16) PHY_GETINTVAR(pi, "pa5ghw2a0"); + pi->nphy_pwrctrl_info[1].pwrdet_5gh_b1 = + (s16) PHY_GETINTVAR(pi, "pa5ghw2a1"); + pi->nphy_pwrctrl_info[0].idle_targ_5gh = 0; + pi->nphy_pwrctrl_info[1].idle_targ_5gh = 0; + + pi->ofdm5ghpo = (u32) PHY_GETINTVAR(pi, "ofdm5ghpo"); + + pi->mcs5ghpo[0] = + (u16) PHY_GETINTVAR(pi, "mcs5ghpo0"); + pi->mcs5ghpo[1] = + (u16) PHY_GETINTVAR(pi, "mcs5ghpo1"); + pi->mcs5ghpo[2] = + (u16) PHY_GETINTVAR(pi, "mcs5ghpo2"); + pi->mcs5ghpo[3] = + (u16) PHY_GETINTVAR(pi, "mcs5ghpo3"); + pi->mcs5ghpo[4] = + (u16) PHY_GETINTVAR(pi, "mcs5ghpo4"); + pi->mcs5ghpo[5] = + (u16) PHY_GETINTVAR(pi, "mcs5ghpo5"); + pi->mcs5ghpo[6] = + (u16) PHY_GETINTVAR(pi, "mcs5ghpo6"); + pi->mcs5ghpo[7] = + (u16) PHY_GETINTVAR(pi, "mcs5ghpo7"); + break; + } } + + wlc_phy_txpwr_apply_nphy(pi); +} + +static bool wlc_phy_txpwr_srom_read_nphy(struct brcms_phy *pi) +{ + + pi->antswitch = (u8) PHY_GETINTVAR(pi, "antswitch"); + pi->aa2g = (u8) PHY_GETINTVAR(pi, "aa2g"); + pi->aa5g = (u8) PHY_GETINTVAR(pi, "aa5g"); + + pi->srom_fem2g.tssipos = (u8) PHY_GETINTVAR(pi, "tssipos2g"); + pi->srom_fem2g.extpagain = (u8) PHY_GETINTVAR(pi, "extpagain2g"); + pi->srom_fem2g.pdetrange = (u8) PHY_GETINTVAR(pi, "pdetrange2g"); + pi->srom_fem2g.triso = (u8) PHY_GETINTVAR(pi, "triso2g"); + pi->srom_fem2g.antswctrllut = (u8) PHY_GETINTVAR(pi, "antswctl2g"); + + pi->srom_fem5g.tssipos = (u8) PHY_GETINTVAR(pi, "tssipos5g"); + pi->srom_fem5g.extpagain = (u8) PHY_GETINTVAR(pi, "extpagain5g"); + pi->srom_fem5g.pdetrange = (u8) PHY_GETINTVAR(pi, "pdetrange5g"); + pi->srom_fem5g.triso = (u8) PHY_GETINTVAR(pi, "triso5g"); + if (PHY_GETVAR(pi, "antswctl5g")) + pi->srom_fem5g.antswctrllut = + (u8) PHY_GETINTVAR(pi, "antswctl5g"); + else + pi->srom_fem5g.antswctrllut = + (u8) PHY_GETINTVAR(pi, "antswctl2g"); + + wlc_phy_txpower_ipa_upd(pi); + + pi->phy_txcore_disable_temp = (s16) PHY_GETINTVAR(pi, "tempthresh"); + if (pi->phy_txcore_disable_temp == 0) + pi->phy_txcore_disable_temp = PHY_CHAIN_TX_DISABLE_TEMP; + + pi->phy_tempsense_offset = (s8) PHY_GETINTVAR(pi, "tempoffset"); + if (pi->phy_tempsense_offset != 0) { + if (pi->phy_tempsense_offset > + (NPHY_SROM_TEMPSHIFT + NPHY_SROM_MAXTEMPOFFSET)) + pi->phy_tempsense_offset = NPHY_SROM_MAXTEMPOFFSET; + else if (pi->phy_tempsense_offset < (NPHY_SROM_TEMPSHIFT + + NPHY_SROM_MINTEMPOFFSET)) + pi->phy_tempsense_offset = NPHY_SROM_MINTEMPOFFSET; + else + pi->phy_tempsense_offset -= NPHY_SROM_TEMPSHIFT; + } + + pi->phy_txcore_enable_temp = + pi->phy_txcore_disable_temp - PHY_HYSTERESIS_DELTATEMP; + + pi->phycal_tempdelta = (u8) PHY_GETINTVAR(pi, "phycal_tempdelta"); + if (pi->phycal_tempdelta > NPHY_CAL_MAXTEMPDELTA) + pi->phycal_tempdelta = 0; + + wlc_phy_txpwr_srom_read_ppr_nphy(pi); + + return true; } bool wlc_phy_attach_nphy(struct brcms_phy *pi) { uint i; - if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 6)) { + if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 6)) pi->phyhang_avoid = true; - } if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) { - pi->nphy_gband_spurwar_en = true; - - if (pi->sh->boardflags2 & BFL2_SPUR_WAR) { + if (pi->sh->boardflags2 & BFL2_SPUR_WAR) pi->nphy_aband_spurwar_en = true; - } } if (NREV_GE(pi->pubpi.phy_rev, 6) && NREV_LT(pi->pubpi.phy_rev, 7)) { - - if (pi->sh->boardflags2 & BFL2_2G_SPUR_WAR) { + if (pi->sh->boardflags2 & BFL2_2G_SPUR_WAR) pi->nphy_gband_spurwar2_en = true; - } } pi->n_preamble_override = AUTO; @@ -14485,9 +14671,8 @@ bool wlc_phy_attach_nphy(struct brcms_phy *pi) pi->nphy_elna_gain_config = false; pi->radio_is_on = false; - for (i = 0; i < pi->pubpi.phy_corenum; i++) { + for (i = 0; i < pi->pubpi.phy_corenum; i++) pi->nphy_txpwrindex[i].index = AUTO; - } wlc_phy_txpwrctrl_config_nphy(pi); if (pi->nphy_txpwrctrl == PHY_TPC_HW_ON) @@ -14504,751 +14689,1405 @@ bool wlc_phy_attach_nphy(struct brcms_phy *pi) return true; } -static void wlc_phy_txpwrctrl_config_nphy(struct brcms_phy *pi) +static s32 get_rf_pwr_offset(struct brcms_phy *pi, s16 pga_gn, s16 pad_gn) { + s32 rfpwr_offset = 0; - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - pi->nphy_txpwrctrl = PHY_TPC_HW_ON; - pi->phy_5g_pwrgain = true; - return; - } - - pi->nphy_txpwrctrl = PHY_TPC_HW_OFF; - pi->phy_5g_pwrgain = false; - - if ((pi->sh->boardflags2 & BFL2_TXPWRCTRL_EN) && - NREV_GE(pi->pubpi.phy_rev, 2) && (pi->sh->sromrev >= 4)) - pi->nphy_txpwrctrl = PHY_TPC_HW_ON; - else if ((pi->sh->sromrev >= 4) - && (pi->sh->boardflags2 & BFL2_5G_PWRGAIN)) - pi->phy_5g_pwrgain = true; + if (CHSPEC_IS2G(pi->radio_chanspec)) { + if ((pi->pubpi.radiorev == 3) || + (pi->pubpi.radiorev == 4) || + (pi->pubpi.radiorev == 6)) + rfpwr_offset = (s16) + nphy_papd_padgain_dlt_2g_2057rev3n4 + [pad_gn]; + else if (pi->pubpi.radiorev == 5) + rfpwr_offset = (s16) + nphy_papd_padgain_dlt_2g_2057rev5 + [pad_gn]; + else if ((pi->pubpi.radiorev == 7) + || (pi->pubpi.radiorev == + 8)) + rfpwr_offset = (s16) + nphy_papd_padgain_dlt_2g_2057rev7 + [pad_gn]; + } else { + if ((pi->pubpi.radiorev == 3) || + (pi->pubpi.radiorev == 4) || + (pi->pubpi.radiorev == 6)) + rfpwr_offset = (s16) + nphy_papd_pgagain_dlt_5g_2057 + [pga_gn]; + else if ((pi->pubpi.radiorev == 7) + || (pi->pubpi.radiorev == + 8)) + rfpwr_offset = (s16) + nphy_papd_pgagain_dlt_5g_2057rev7 + [pga_gn]; + } + return rfpwr_offset; } -void wlc_phy_init_nphy(struct brcms_phy *pi) +static void wlc_phy_update_mimoconfig_nphy(struct brcms_phy *pi, s32 preamble) { + bool gf_preamble = false; u16 val; - u16 clip1_ths[2]; - struct nphy_txgains target_gain; - u8 tx_pwr_ctrl_state; - bool do_nphy_cal = false; - uint core; - uint origidx, intr_val; - d11regs_t *regs; - u32 d11_clk_ctl_st; - - core = 0; - if (!(pi->measure_hold & PHY_HOLD_FOR_SCAN)) { - pi->measure_hold |= PHY_HOLD_FOR_NOT_ASSOC; - } + if (preamble == BRCMS_N_PREAMBLE_GF) + gf_preamble = true; - if ((ISNPHY(pi)) && (NREV_GE(pi->pubpi.phy_rev, 5)) && - ((pi->sh->chippkg == BCM4717_PKG_ID) || - (pi->sh->chippkg == BCM4718_PKG_ID))) { - if ((pi->sh->boardflags & BFL_EXTLNA) && - (CHSPEC_IS2G(pi->radio_chanspec))) { - ai_corereg(pi->sh->sih, SI_CC_IDX, - offsetof(chipcregs_t, chipcontrol), 0x40, - 0x40); - } - } + val = read_phy_reg(pi, 0xed); - if ((pi->nphy_gband_spurwar2_en) && CHSPEC_IS2G(pi->radio_chanspec) && - CHSPEC_IS40(pi->radio_chanspec)) { + val |= RX_GF_MM_AUTO; + val &= ~RX_GF_OR_MM; + if (gf_preamble) + val |= RX_GF_OR_MM; - regs = (d11regs_t *) ai_switch_core(pi->sh->sih, D11_CORE_ID, - &origidx, &intr_val); - d11_clk_ctl_st = R_REG(®s->clk_ctl_st); - AND_REG(®s->clk_ctl_st, - ~(CCS_FORCEHT | CCS_HTAREQ)); + write_phy_reg(pi, 0xed, val); +} - W_REG(®s->clk_ctl_st, d11_clk_ctl_st); +static void wlc_phy_ipa_set_tx_digi_filts_nphy(struct brcms_phy *pi) +{ + int j, type; + u16 addr_offset[] = { 0x186, 0x195, 0x2c5}; - ai_restore_core(pi->sh->sih, origidx, intr_val); + for (type = 0; type < 3; type++) { + for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) + write_phy_reg(pi, addr_offset[type] + j, + NPHY_IPA_REV4_txdigi_filtcoeffs[type][j]); } - pi->use_int_tx_iqlo_cal_nphy = - (PHY_IPA(pi) || - (NREV_GE(pi->pubpi.phy_rev, 7) || - (NREV_GE(pi->pubpi.phy_rev, 5) - && pi->sh->boardflags2 & BFL2_INTERNDET_TXIQCAL))); - - pi->internal_tx_iqlo_cal_tapoff_intpa_nphy = false; - - pi->nphy_deaf_count = 0; - - wlc_phy_tbl_init_nphy(pi); - - pi->nphy_crsminpwr_adjusted = false; - pi->nphy_noisevars_adjusted = false; - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - write_phy_reg(pi, 0xe7, 0); - write_phy_reg(pi, 0xec, 0); - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - write_phy_reg(pi, 0x342, 0); - write_phy_reg(pi, 0x343, 0); - write_phy_reg(pi, 0x346, 0); - write_phy_reg(pi, 0x347, 0); - } - write_phy_reg(pi, 0xe5, 0); - write_phy_reg(pi, 0xe6, 0); + if (IS40MHZ(pi)) { + for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) + write_phy_reg(pi, 0x186 + j, + NPHY_IPA_REV4_txdigi_filtcoeffs[3][j]); } else { - write_phy_reg(pi, 0xec, 0); - } + if (CHSPEC_IS5G(pi->radio_chanspec)) { + for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) + write_phy_reg(pi, 0x186 + j, + NPHY_IPA_REV4_txdigi_filtcoeffs[5][j]); + } - write_phy_reg(pi, 0x91, 0); - write_phy_reg(pi, 0x92, 0); - if (NREV_LT(pi->pubpi.phy_rev, 6)) { - write_phy_reg(pi, 0x93, 0); - write_phy_reg(pi, 0x94, 0); + if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) { + for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) + write_phy_reg(pi, 0x2c5 + j, + NPHY_IPA_REV4_txdigi_filtcoeffs[6][j]); + } } +} - and_phy_reg(pi, 0xa1, ~3); +static void wlc_phy_ipa_restore_tx_digi_filts_nphy(struct brcms_phy *pi) +{ + int j; - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - write_phy_reg(pi, 0x8f, 0); - write_phy_reg(pi, 0xa5, 0); + if (IS40MHZ(pi)) { + for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) + write_phy_reg(pi, 0x195 + j, + NPHY_IPA_REV4_txdigi_filtcoeffs[4][j]); } else { - write_phy_reg(pi, 0xa5, 0); + for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) + write_phy_reg(pi, 0x186 + j, + NPHY_IPA_REV4_txdigi_filtcoeffs[3][j]); } +} - if (NREV_IS(pi->pubpi.phy_rev, 2)) - mod_phy_reg(pi, 0xdc, 0x00ff, 0x3b); - else if (NREV_LT(pi->pubpi.phy_rev, 2)) - mod_phy_reg(pi, 0xdc, 0x00ff, 0x40); - - write_phy_reg(pi, 0x203, 32); - write_phy_reg(pi, 0x201, 32); - - if (pi->sh->boardflags2 & BFL2_SKWRKFEM_BRD) - write_phy_reg(pi, 0x20d, 160); - else - write_phy_reg(pi, 0x20d, 184); - - write_phy_reg(pi, 0x13a, 200); - - write_phy_reg(pi, 0x70, 80); - - write_phy_reg(pi, 0x1ff, 48); +static void +wlc_phy_set_rfseq_nphy(struct brcms_phy *pi, u8 cmd, u8 *events, u8 *dlys, + u8 len) +{ + u32 t1_offset, t2_offset; + u8 ctr; + u8 end_event = + NREV_GE(pi->pubpi.phy_rev, + 3) ? NPHY_REV3_RFSEQ_CMD_END : NPHY_RFSEQ_CMD_END; + u8 end_dly = 1; - if (NREV_LT(pi->pubpi.phy_rev, 8)) { - wlc_phy_update_mimoconfig_nphy(pi, pi->n_preamble_override); - } + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, true); - wlc_phy_stf_chain_upd_nphy(pi); + t1_offset = cmd << 4; + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, len, t1_offset, 8, + events); + t2_offset = t1_offset + 0x080; + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, len, t2_offset, 8, + dlys); - if (NREV_LT(pi->pubpi.phy_rev, 2)) { - write_phy_reg(pi, 0x180, 0xaa8); - write_phy_reg(pi, 0x181, 0x9a4); + for (ctr = len; ctr < 16; ctr++) { + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, + t1_offset + ctr, 8, &end_event); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, + t2_offset + ctr, 8, &end_dly); } - if (PHY_IPA(pi)) { - for (core = 0; core < pi->pubpi.phy_corenum; core++) { - - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 : - 0x29b, (0x1 << 0), (1) << 0); - - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x298 : - 0x29c, (0x1ff << 7), - (pi->nphy_papd_epsilon_offset[core]) << 7); + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, false); +} - } +static u16 wlc_phy_read_lpf_bw_ctl_nphy(struct brcms_phy *pi, u16 offset) +{ + u16 lpf_bw_ctl_val = 0; + u16 rx2tx_lpf_rc_lut_offset = 0; - wlc_phy_ipa_set_tx_digi_filts_nphy(pi); + if (offset == 0) { + if (CHSPEC_IS40(pi->radio_chanspec)) + rx2tx_lpf_rc_lut_offset = 0x159; + else + rx2tx_lpf_rc_lut_offset = 0x154; } else { - - if (NREV_GE(pi->pubpi.phy_rev, 5)) { - wlc_phy_extpa_set_tx_digi_filts_nphy(pi); - } + rx2tx_lpf_rc_lut_offset = offset; } + wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, + (u32) rx2tx_lpf_rc_lut_offset, 16, + &lpf_bw_ctl_val); - wlc_phy_workarounds_nphy(pi); - - wlapi_bmac_phyclk_fgc(pi->sh->physhim, ON); - - val = read_phy_reg(pi, 0x01); - write_phy_reg(pi, 0x01, val | BBCFG_RESETCCA); - write_phy_reg(pi, 0x01, val & (~BBCFG_RESETCCA)); - wlapi_bmac_phyclk_fgc(pi->sh->physhim, OFF); - - wlapi_bmac_macphyclk_set(pi->sh->physhim, ON); - - wlc_phy_pa_override_nphy(pi, OFF); - wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX); - wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX); - wlc_phy_pa_override_nphy(pi, ON); + lpf_bw_ctl_val = lpf_bw_ctl_val & 0x7; - wlc_phy_classifier_nphy(pi, 0, 0); - wlc_phy_clip_det_nphy(pi, 0, clip1_ths); + return lpf_bw_ctl_val; +} - if (CHSPEC_IS2G(pi->radio_chanspec)) - wlc_phy_bphy_init_nphy(pi); +static void +wlc_phy_rfctrl_override_nphy_rev7(struct brcms_phy *pi, u16 field, u16 value, + u8 core_mask, u8 off, u8 override_id) +{ + u8 core_num; + u16 addr = 0, en_addr = 0, val_addr = 0, en_mask = 0, val_mask = 0; + u8 val_shift = 0; - tx_pwr_ctrl_state = pi->nphy_txpwrctrl; - wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF); + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + en_mask = field; + for (core_num = 0; core_num < 2; core_num++) { + if (override_id == NPHY_REV7_RFCTRLOVERRIDE_ID0) { - wlc_phy_txpwr_fixpower_nphy(pi); + switch (field) { + case (0x1 << 2): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x7a : + 0x7d; + val_mask = (0x1 << 1); + val_shift = 1; + break; + case (0x1 << 3): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x7a : + 0x7d; + val_mask = (0x1 << 2); + val_shift = 2; + break; + case (0x1 << 4): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x7a : + 0x7d; + val_mask = (0x1 << 4); + val_shift = 4; + break; + case (0x1 << 5): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x7a : + 0x7d; + val_mask = (0x1 << 5); + val_shift = 5; + break; + case (0x1 << 6): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x7a : + 0x7d; + val_mask = (0x1 << 6); + val_shift = 6; + break; + case (0x1 << 7): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x7a : + 0x7d; + val_mask = (0x1 << 7); + val_shift = 7; + break; + case (0x1 << 10): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0xf8 : + 0xfa; + val_mask = (0x7 << 4); + val_shift = 4; + break; + case (0x1 << 11): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x7b : + 0x7e; + val_mask = (0xffff << 0); + val_shift = 0; + break; + case (0x1 << 12): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x7c : + 0x7f; + val_mask = (0xffff << 0); + val_shift = 0; + break; + case (0x3 << 13): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x348 : + 0x349; + val_mask = (0xff << 0); + val_shift = 0; + break; + case (0x1 << 13): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x348 : + 0x349; + val_mask = (0xf << 0); + val_shift = 0; + break; + default: + addr = 0xffff; + break; + } + } else if (override_id == + NPHY_REV7_RFCTRLOVERRIDE_ID1) { - wlc_phy_txpwrctrl_idle_tssi_nphy(pi); + switch (field) { + case (0x1 << 1): + en_addr = (core_num == 0) ? 0x342 : + 0x343; + val_addr = (core_num == 0) ? 0x340 : + 0x341; + val_mask = (0x1 << 1); + val_shift = 1; + break; + case (0x1 << 3): + en_addr = (core_num == 0) ? 0x342 : + 0x343; + val_addr = (core_num == 0) ? 0x340 : + 0x341; + val_mask = (0x1 << 3); + val_shift = 3; + break; + case (0x1 << 5): + en_addr = (core_num == 0) ? 0x342 : + 0x343; + val_addr = (core_num == 0) ? 0x340 : + 0x341; + val_mask = (0x1 << 5); + val_shift = 5; + break; + case (0x1 << 4): + en_addr = (core_num == 0) ? 0x342 : + 0x343; + val_addr = (core_num == 0) ? 0x340 : + 0x341; + val_mask = (0x1 << 4); + val_shift = 4; + break; + case (0x1 << 2): - wlc_phy_txpwrctrl_pwr_setup_nphy(pi); + en_addr = (core_num == 0) ? 0x342 : + 0x343; + val_addr = (core_num == 0) ? 0x340 : + 0x341; + val_mask = (0x1 << 2); + val_shift = 2; + break; + case (0x1 << 7): - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - u32 *tx_pwrctrl_tbl = NULL; - u16 idx; - s16 pga_gn = 0; - s16 pad_gn = 0; - s32 rfpwr_offset = 0; + en_addr = (core_num == 0) ? 0x342 : + 0x343; + val_addr = (core_num == 0) ? 0x340 : + 0x341; + val_mask = (0x7 << 8); + val_shift = 8; + break; + case (0x1 << 11): + en_addr = (core_num == 0) ? 0x342 : + 0x343; + val_addr = (core_num == 0) ? 0x340 : + 0x341; + val_mask = (0x1 << 14); + val_shift = 14; + break; + case (0x1 << 10): + en_addr = (core_num == 0) ? 0x342 : + 0x343; + val_addr = (core_num == 0) ? 0x340 : + 0x341; + val_mask = (0x1 << 13); + val_shift = 13; + break; + case (0x1 << 9): + en_addr = (core_num == 0) ? 0x342 : + 0x343; + val_addr = (core_num == 0) ? 0x340 : + 0x341; + val_mask = (0x1 << 12); + val_shift = 12; + break; + case (0x1 << 8): + en_addr = (core_num == 0) ? 0x342 : + 0x343; + val_addr = (core_num == 0) ? 0x340 : + 0x341; + val_mask = (0x1 << 11); + val_shift = 11; + break; + case (0x1 << 6): + en_addr = (core_num == 0) ? 0x342 : + 0x343; + val_addr = (core_num == 0) ? 0x340 : + 0x341; + val_mask = (0x1 << 6); + val_shift = 6; + break; + case (0x1 << 0): + en_addr = (core_num == 0) ? 0x342 : + 0x343; + val_addr = (core_num == 0) ? 0x340 : + 0x341; + val_mask = (0x1 << 0); + val_shift = 0; + break; + default: + addr = 0xffff; + break; + } + } else if (override_id == + NPHY_REV7_RFCTRLOVERRIDE_ID2) { - if (PHY_IPA(pi)) { - tx_pwrctrl_tbl = wlc_phy_get_ipa_gaintbl_nphy(pi); - } else { - if (CHSPEC_IS5G(pi->radio_chanspec)) { - if (NREV_IS(pi->pubpi.phy_rev, 3)) { - tx_pwrctrl_tbl = - nphy_tpc_5GHz_txgain_rev3; - } else if (NREV_IS(pi->pubpi.phy_rev, 4)) { - tx_pwrctrl_tbl = - (pi->srom_fem5g.extpagain == 3) ? - nphy_tpc_5GHz_txgain_HiPwrEPA : - nphy_tpc_5GHz_txgain_rev4; - } else { - tx_pwrctrl_tbl = - nphy_tpc_5GHz_txgain_rev5; + switch (field) { + case (0x1 << 3): + en_addr = (core_num == 0) ? 0x346 : + 0x347; + val_addr = (core_num == 0) ? 0x344 : + 0x345; + val_mask = (0x1 << 3); + val_shift = 3; + break; + case (0x1 << 1): + en_addr = (core_num == 0) ? 0x346 : + 0x347; + val_addr = (core_num == 0) ? 0x344 : + 0x345; + val_mask = (0x1 << 1); + val_shift = 1; + break; + case (0x1 << 0): + en_addr = (core_num == 0) ? 0x346 : + 0x347; + val_addr = (core_num == 0) ? 0x344 : + 0x345; + val_mask = (0x1 << 0); + val_shift = 0; + break; + case (0x1 << 2): + en_addr = (core_num == 0) ? 0x346 : + 0x347; + val_addr = (core_num == 0) ? 0x344 : + 0x345; + val_mask = (0x1 << 2); + val_shift = 2; + break; + case (0x1 << 4): + en_addr = (core_num == 0) ? 0x346 : + 0x347; + val_addr = (core_num == 0) ? 0x344 : + 0x345; + val_mask = (0x1 << 4); + val_shift = 4; + break; + default: + addr = 0xffff; + break; } + } + if (off) { + and_phy_reg(pi, en_addr, ~en_mask); + and_phy_reg(pi, val_addr, ~val_mask); } else { - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - if (pi->pubpi.radiorev == 5) { - tx_pwrctrl_tbl = - nphy_tpc_txgain_epa_2057rev5; - } else if (pi->pubpi.radiorev == 3) { - tx_pwrctrl_tbl = - nphy_tpc_txgain_epa_2057rev3; - } - } else { - if (NREV_GE(pi->pubpi.phy_rev, 5) && - (pi->srom_fem2g.extpagain == 3)) { - tx_pwrctrl_tbl = - nphy_tpc_txgain_HiPwrEPA; - } else { - tx_pwrctrl_tbl = - nphy_tpc_txgain_rev3; - } + if ((core_mask == 0) + || (core_mask & (1 << core_num))) { + or_phy_reg(pi, en_addr, en_mask); + + if (addr != 0xffff) + mod_phy_reg(pi, val_addr, + val_mask, + (value << + val_shift)); } } } + } +} - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 128, - 192, 32, tx_pwrctrl_tbl); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 128, - 192, 32, tx_pwrctrl_tbl); - - pi->nphy_gmval = (u16) ((*tx_pwrctrl_tbl >> 16) & 0x7000); +static void wlc_phy_adjust_lnagaintbl_nphy(struct brcms_phy *pi) +{ + uint core; + int ctr; + s16 gain_delta[2]; + u8 curr_channel; + u16 minmax_gain[2]; + u16 regval[4]; - if (NREV_GE(pi->pubpi.phy_rev, 7)) { + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, true); - for (idx = 0; idx < 128; idx++) { - pga_gn = (tx_pwrctrl_tbl[idx] >> 24) & 0xf; - pad_gn = (tx_pwrctrl_tbl[idx] >> 19) & 0x1f; + if (pi->nphy_gain_boost) { + if ((CHSPEC_IS2G(pi->radio_chanspec))) { - if (CHSPEC_IS2G(pi->radio_chanspec)) { - if ((pi->pubpi.radiorev == 3) || - (pi->pubpi.radiorev == 4) || - (pi->pubpi.radiorev == 6)) { - rfpwr_offset = (s16) - nphy_papd_padgain_dlt_2g_2057rev3n4 - [pad_gn]; - } else if (pi->pubpi.radiorev == 5) { - rfpwr_offset = (s16) - nphy_papd_padgain_dlt_2g_2057rev5 - [pad_gn]; - } else if ((pi->pubpi.radiorev == 7) - || (pi->pubpi.radiorev == - 8)) { - rfpwr_offset = (s16) - nphy_papd_padgain_dlt_2g_2057rev7 - [pad_gn]; - } - } else { - if ((pi->pubpi.radiorev == 3) || - (pi->pubpi.radiorev == 4) || - (pi->pubpi.radiorev == 6)) { - rfpwr_offset = (s16) - nphy_papd_pgagain_dlt_5g_2057 - [pga_gn]; - } else if ((pi->pubpi.radiorev == 7) - || (pi->pubpi.radiorev == - 8)) { - rfpwr_offset = (s16) - nphy_papd_pgagain_dlt_5g_2057rev7 - [pga_gn]; - } - } - wlc_phy_table_write_nphy(pi, - NPHY_TBL_ID_CORE1TXPWRCTL, - 1, 576 + idx, 32, - &rfpwr_offset); - wlc_phy_table_write_nphy(pi, - NPHY_TBL_ID_CORE2TXPWRCTL, - 1, 576 + idx, 32, - &rfpwr_offset); - } + gain_delta[0] = 6; + gain_delta[1] = 6; } else { - for (idx = 0; idx < 128; idx++) { - pga_gn = (tx_pwrctrl_tbl[idx] >> 24) & 0xf; - if (CHSPEC_IS2G(pi->radio_chanspec)) { - rfpwr_offset = (s16) - nphy_papd_pga_gain_delta_ipa_2g - [pga_gn]; - } else { - rfpwr_offset = (s16) - nphy_papd_pga_gain_delta_ipa_5g - [pga_gn]; - } - - wlc_phy_table_write_nphy(pi, - NPHY_TBL_ID_CORE1TXPWRCTL, - 1, 576 + idx, 32, - &rfpwr_offset); - wlc_phy_table_write_nphy(pi, - NPHY_TBL_ID_CORE2TXPWRCTL, - 1, 576 + idx, 32, - &rfpwr_offset); - } - + curr_channel = CHSPEC_CHANNEL(pi->radio_chanspec); + gain_delta[0] = + (s16) + PHY_HW_ROUND(((nphy_lnagain_est0[0] * + curr_channel) + + nphy_lnagain_est0[1]), 13); + gain_delta[1] = + (s16) + PHY_HW_ROUND(((nphy_lnagain_est1[0] * + curr_channel) + + nphy_lnagain_est1[1]), 13); } } else { - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 128, - 192, 32, nphy_tpc_txgain); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 128, - 192, 32, nphy_tpc_txgain); + gain_delta[0] = 0; + gain_delta[1] = 0; } - if (pi->sh->phyrxchain != 0x3) { - wlc_phy_rxcore_setstate_nphy((struct brcms_phy_pub *) pi, - pi->sh->phyrxchain); + for (core = 0; core < pi->pubpi.phy_corenum; core++) { + if (pi->nphy_elna_gain_config) { + + regval[0] = nphy_def_lnagains[2] + gain_delta[core]; + regval[1] = nphy_def_lnagains[3] + gain_delta[core]; + regval[2] = nphy_def_lnagains[3] + gain_delta[core]; + regval[3] = nphy_def_lnagains[3] + gain_delta[core]; + } else { + for (ctr = 0; ctr < 4; ctr++) + regval[ctr] = + nphy_def_lnagains[ctr] + + gain_delta[core]; + } + wlc_phy_table_write_nphy(pi, core, 4, 8, 16, regval); + + minmax_gain[core] = + (u16) (nphy_def_lnagains[2] + gain_delta[core] + 4); } - if (PHY_PERICAL_MPHASE_PENDING(pi)) { - wlc_phy_cal_perical_mphase_restart(pi); + mod_phy_reg(pi, 0x1e, (0xff << 0), (minmax_gain[0] << 0)); + mod_phy_reg(pi, 0x34, (0xff << 0), (minmax_gain[1] << 0)); + + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, false); +} + +static void +wlc_phy_war_force_trsw_to_R_cliplo_nphy(struct brcms_phy *pi, u8 core) +{ + if (core == PHY_CORE_0) { + write_phy_reg(pi, 0x38, 0x4); + if (CHSPEC_IS2G(pi->radio_chanspec)) + write_phy_reg(pi, 0x37, 0x0060); + else + write_phy_reg(pi, 0x37, 0x1080); + } else if (core == PHY_CORE_1) { + write_phy_reg(pi, 0x2ae, 0x4); + if (CHSPEC_IS2G(pi->radio_chanspec)) + write_phy_reg(pi, 0x2ad, 0x0060); + else + write_phy_reg(pi, 0x2ad, 0x1080); } +} - if (!NORADIO_ENAB(pi->pubpi)) { - bool do_rssi_cal = false; +static void wlc_phy_war_txchain_upd_nphy(struct brcms_phy *pi, u8 txchain) +{ + u8 txchain0, txchain1; - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - do_rssi_cal = (CHSPEC_IS2G(pi->radio_chanspec)) ? - (pi->nphy_rssical_chanspec_2G == 0) : - (pi->nphy_rssical_chanspec_5G == 0); + txchain0 = txchain & 0x1; + txchain1 = (txchain & 0x2) >> 1; + if (!txchain0) + wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_0); - if (do_rssi_cal) { - wlc_phy_rssi_cal_nphy(pi); - } else { - wlc_phy_restore_rssical_nphy(pi); - } - } else { - wlc_phy_rssi_cal_nphy(pi); - } + if (!txchain1) + wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_1); +} - if (!SCAN_RM_IN_PROGRESS(pi)) { - do_nphy_cal = (CHSPEC_IS2G(pi->radio_chanspec)) ? - (pi->nphy_iqcal_chanspec_2G == 0) : - (pi->nphy_iqcal_chanspec_5G == 0); - } +static void wlc_phy_workarounds_nphy_gainctrl_2057_rev5(struct brcms_phy *pi) +{ + s8 lna1_gain_db[] = { 8, 13, 17, 22 }; + s8 lna2_gain_db[] = { -2, 7, 11, 15 }; + s8 tia_gain_db[] = { -4, -1, 2, 5, 5, 5, 5, 5, 5, 5 }; + s8 tia_gainbits[] = { + 0x0, 0x01, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 }; - if (!pi->do_initcal) - do_nphy_cal = false; + mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13)); + mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13)); - if (do_nphy_cal) { + mod_phy_reg(pi, 0x289, (0xff << 0), (0x46 << 0)); - target_gain = wlc_phy_get_tx_gain_nphy(pi); + mod_phy_reg(pi, 0x283, (0xff << 0), (0x3c << 0)); + mod_phy_reg(pi, 0x280, (0xff << 0), (0x3c << 0)); - if (pi->antsel_type == ANTSEL_2x3) - wlc_phy_antsel_init((struct brcms_phy_pub *) pi, - true); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x8, 8, + lna1_gain_db); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x8, 8, + lna1_gain_db); - if (pi->nphy_perical != PHY_PERICAL_MPHASE) { - wlc_phy_rssi_cal_nphy(pi); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x10, 8, + lna2_gain_db); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x10, 8, + lna2_gain_db); - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - pi->nphy_cal_orig_pwr_idx[0] = - pi->nphy_txpwrindex[PHY_CORE_0]. - index_internal; - pi->nphy_cal_orig_pwr_idx[1] = - pi->nphy_txpwrindex[PHY_CORE_1]. - index_internal; - - wlc_phy_precal_txgain_nphy(pi); - target_gain = - wlc_phy_get_tx_gain_nphy(pi); - } + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 10, 0x20, 8, + tia_gain_db); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 10, 0x20, 8, + tia_gain_db); - if (wlc_phy_cal_txiqlo_nphy - (pi, target_gain, true, false) == 0) { - if (wlc_phy_cal_rxiq_nphy - (pi, target_gain, 2, - false) == 0) { - wlc_phy_savecal_nphy(pi); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 10, 0x20, 8, + tia_gainbits); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 10, 0x20, 8, + tia_gainbits); - } - } - } else if (pi->mphase_cal_phase_id == - MPHASE_CAL_STATE_IDLE) { + write_phy_reg(pi, 0x37, 0x74); + write_phy_reg(pi, 0x2ad, 0x74); + write_phy_reg(pi, 0x38, 0x18); + write_phy_reg(pi, 0x2ae, 0x18); - wlc_phy_cal_perical((struct brcms_phy_pub *) pi, - PHY_PERICAL_PHYINIT); - } - } else { - wlc_phy_restorecal_nphy(pi); - } - } + write_phy_reg(pi, 0x2b, 0xe8); + write_phy_reg(pi, 0x41, 0xe8); - wlc_phy_txpwrctrl_coeff_setup_nphy(pi); + if (CHSPEC_IS20(pi->radio_chanspec)) { - wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state); + mod_phy_reg(pi, 0x300, (0x3f << 0), (0x12 << 0)); + mod_phy_reg(pi, 0x301, (0x3f << 0), (0x12 << 0)); + } else { - wlc_phy_nphy_tkip_rifs_war(pi, pi->sh->_rifs_phy); + mod_phy_reg(pi, 0x300, (0x3f << 0), (0x10 << 0)); + mod_phy_reg(pi, 0x301, (0x3f << 0), (0x10 << 0)); + } +} - if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LE(pi->pubpi.phy_rev, 6)) +static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(struct brcms_phy *pi) +{ + u16 currband; + s8 lna1G_gain_db_rev7[] = { 9, 14, 19, 24 }; + s8 *lna1_gain_db = NULL; + s8 *lna1_gain_db_2 = NULL; + s8 *lna2_gain_db = NULL; + s8 tiaA_gain_db_rev7[] = { -9, -6, -3, 0, 3, 3, 3, 3, 3, 3 }; + s8 *tia_gain_db; + s8 tiaA_gainbits_rev7[] = { 0, 1, 2, 3, 4, 4, 4, 4, 4, 4 }; + s8 *tia_gainbits; + u16 rfseqA_init_gain_rev7[] = { 0x624f, 0x624f }; + u16 *rfseq_init_gain; + u16 init_gaincode; + u16 clip1hi_gaincode; + u16 clip1md_gaincode = 0; + u16 clip1md_gaincode_B; + u16 clip1lo_gaincode; + u16 clip1lo_gaincode_B; + u8 crsminl_th = 0; + u8 crsminu_th; + u16 nbclip_th = 0; + u8 w1clip_th; + u16 freq; + s8 nvar_baseline_offset0 = 0, nvar_baseline_offset1 = 0; + u8 chg_nbclip_th = 0; - write_phy_reg(pi, 0x70, 50); + mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13)); + mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13)); - wlc_phy_txlpfbw_nphy(pi); + currband = read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand; + if (currband == 0) { - wlc_phy_spurwar_nphy(pi); + lna1_gain_db = lna1G_gain_db_rev7; -} + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 8, 8, + lna1_gain_db); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 8, 8, + lna1_gain_db); -static void wlc_phy_update_mimoconfig_nphy(struct brcms_phy *pi, s32 preamble) -{ - bool gf_preamble = false; - u16 val; + mod_phy_reg(pi, 0x283, (0xff << 0), (0x40 << 0)); - if (preamble == BRCMS_N_PREAMBLE_GF) - gf_preamble = true; + if (CHSPEC_IS40(pi->radio_chanspec)) { + mod_phy_reg(pi, 0x280, (0xff << 0), (0x3e << 0)); + mod_phy_reg(pi, 0x283, (0xff << 0), (0x3e << 0)); + } - val = read_phy_reg(pi, 0xed); + mod_phy_reg(pi, 0x289, (0xff << 0), (0x46 << 0)); - val |= RX_GF_MM_AUTO; - val &= ~RX_GF_OR_MM; - if (gf_preamble) - val |= RX_GF_OR_MM; + if (CHSPEC_IS20(pi->radio_chanspec)) { + mod_phy_reg(pi, 0x300, (0x3f << 0), (13 << 0)); + mod_phy_reg(pi, 0x301, (0x3f << 0), (13 << 0)); + } + } else { - write_phy_reg(pi, 0xed, val); -} + init_gaincode = 0x9e; + clip1hi_gaincode = 0x9e; + clip1md_gaincode_B = 0x24; + clip1lo_gaincode = 0x8a; + clip1lo_gaincode_B = 8; + rfseq_init_gain = rfseqA_init_gain_rev7; -static void wlc_phy_resetcca_nphy(struct brcms_phy *pi) -{ - u16 val; + tia_gain_db = tiaA_gain_db_rev7; + tia_gainbits = tiaA_gainbits_rev7; - wlapi_bmac_phyclk_fgc(pi->sh->physhim, ON); + freq = CHAN5G_FREQ(CHSPEC_CHANNEL(pi->radio_chanspec)); + if (CHSPEC_IS20(pi->radio_chanspec)) { - val = read_phy_reg(pi, 0x01); - write_phy_reg(pi, 0x01, val | BBCFG_RESETCCA); - udelay(1); - write_phy_reg(pi, 0x01, val & (~BBCFG_RESETCCA)); + w1clip_th = 25; + clip1md_gaincode = 0x82; - wlapi_bmac_phyclk_fgc(pi->sh->physhim, OFF); + if ((freq <= 5080) || (freq == 5825)) { - wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX); -} + s8 lna1A_gain_db_rev7[] = { 11, 16, 20, 24 }; + s8 lna1A_gain_db_2_rev7[] = { + 11, 17, 22, 25}; + s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 }; -void wlc_phy_pa_override_nphy(struct brcms_phy *pi, bool en) -{ - u16 rfctrlintc_override_val; + crsminu_th = 0x3e; + lna1_gain_db = lna1A_gain_db_rev7; + lna1_gain_db_2 = lna1A_gain_db_2_rev7; + lna2_gain_db = lna2A_gain_db_rev7; + } else if ((freq >= 5500) && (freq <= 5700)) { - if (!en) { + s8 lna1A_gain_db_rev7[] = { 11, 17, 21, 25 }; + s8 lna1A_gain_db_2_rev7[] = { + 12, 18, 22, 26}; + s8 lna2A_gain_db_rev7[] = { 1, 8, 12, 16 }; - pi->rfctrlIntc1_save = read_phy_reg(pi, 0x91); - pi->rfctrlIntc2_save = read_phy_reg(pi, 0x92); + crsminu_th = 0x45; + clip1md_gaincode_B = 0x14; + nbclip_th = 0xff; + chg_nbclip_th = 1; + lna1_gain_db = lna1A_gain_db_rev7; + lna1_gain_db_2 = lna1A_gain_db_2_rev7; + lna2_gain_db = lna2A_gain_db_rev7; + } else { - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - rfctrlintc_override_val = 0x1480; - } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { - rfctrlintc_override_val = - CHSPEC_IS5G(pi->radio_chanspec) ? 0x600 : 0x480; + s8 lna1A_gain_db_rev7[] = { 12, 18, 22, 26 }; + s8 lna1A_gain_db_2_rev7[] = { + 12, 18, 22, 26}; + s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 }; + + crsminu_th = 0x41; + lna1_gain_db = lna1A_gain_db_rev7; + lna1_gain_db_2 = lna1A_gain_db_2_rev7; + lna2_gain_db = lna2A_gain_db_rev7; + } + + if (freq <= 4920) { + nvar_baseline_offset0 = 5; + nvar_baseline_offset1 = 5; + } else if ((freq > 4920) && (freq <= 5320)) { + nvar_baseline_offset0 = 3; + nvar_baseline_offset1 = 5; + } else if ((freq > 5320) && (freq <= 5700)) { + nvar_baseline_offset0 = 3; + nvar_baseline_offset1 = 2; + } else { + nvar_baseline_offset0 = 4; + nvar_baseline_offset1 = 0; + } } else { - rfctrlintc_override_val = - CHSPEC_IS5G(pi->radio_chanspec) ? 0x180 : 0x120; + + crsminu_th = 0x3a; + crsminl_th = 0x3a; + w1clip_th = 20; + + if ((freq >= 4920) && (freq <= 5320)) { + nvar_baseline_offset0 = 4; + nvar_baseline_offset1 = 5; + } else if ((freq > 5320) && (freq <= 5550)) { + nvar_baseline_offset0 = 4; + nvar_baseline_offset1 = 2; + } else { + nvar_baseline_offset0 = 5; + nvar_baseline_offset1 = 3; + } } - write_phy_reg(pi, 0x91, rfctrlintc_override_val); - write_phy_reg(pi, 0x92, rfctrlintc_override_val); - } else { + write_phy_reg(pi, 0x20, init_gaincode); + write_phy_reg(pi, 0x2a7, init_gaincode); - write_phy_reg(pi, 0x91, pi->rfctrlIntc1_save); - write_phy_reg(pi, 0x92, pi->rfctrlIntc2_save); - } + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, + pi->pubpi.phy_corenum, 0x106, 16, + rfseq_init_gain); -} + write_phy_reg(pi, 0x22, clip1hi_gaincode); + write_phy_reg(pi, 0x2a9, clip1hi_gaincode); -void wlc_phy_stf_chain_upd_nphy(struct brcms_phy *pi) -{ + write_phy_reg(pi, 0x36, clip1md_gaincode_B); + write_phy_reg(pi, 0x2ac, clip1md_gaincode_B); - u16 txrx_chain = - (NPHY_RfseqCoreActv_TxRxChain0 | NPHY_RfseqCoreActv_TxRxChain1); - bool CoreActv_override = false; + write_phy_reg(pi, 0x37, clip1lo_gaincode); + write_phy_reg(pi, 0x2ad, clip1lo_gaincode); + write_phy_reg(pi, 0x38, clip1lo_gaincode_B); + write_phy_reg(pi, 0x2ae, clip1lo_gaincode_B); - if (pi->nphy_txrx_chain == BRCMS_N_TXRX_CHAIN0) { - txrx_chain = NPHY_RfseqCoreActv_TxRxChain0; - CoreActv_override = true; + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 10, 0x20, 8, + tia_gain_db); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 10, 0x20, 8, + tia_gain_db); - if (NREV_LE(pi->pubpi.phy_rev, 2)) { - and_phy_reg(pi, 0xa0, ~0x20); - } - } else if (pi->nphy_txrx_chain == BRCMS_N_TXRX_CHAIN1) { - txrx_chain = NPHY_RfseqCoreActv_TxRxChain1; - CoreActv_override = true; + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 10, 0x20, 8, + tia_gainbits); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 10, 0x20, 8, + tia_gainbits); - if (NREV_LE(pi->pubpi.phy_rev, 2)) { - or_phy_reg(pi, 0xa0, 0x20); + mod_phy_reg(pi, 0x283, (0xff << 0), (crsminu_th << 0)); + + if (chg_nbclip_th == 1) { + write_phy_reg(pi, 0x2b, nbclip_th); + write_phy_reg(pi, 0x41, nbclip_th); } - } - mod_phy_reg(pi, 0xa2, ((0xf << 0) | (0xf << 4)), txrx_chain); + mod_phy_reg(pi, 0x300, (0x3f << 0), (w1clip_th << 0)); + mod_phy_reg(pi, 0x301, (0x3f << 0), (w1clip_th << 0)); - if (CoreActv_override) { + mod_phy_reg(pi, 0x2e4, + (0x3f << 0), (nvar_baseline_offset0 << 0)); - pi->nphy_perical = PHY_PERICAL_DISABLE; - or_phy_reg(pi, 0xa1, NPHY_RfseqMode_CoreActv_override); - } else { - pi->nphy_perical = PHY_PERICAL_MPHASE; - and_phy_reg(pi, 0xa1, ~NPHY_RfseqMode_CoreActv_override); + mod_phy_reg(pi, 0x2e4, + (0x3f << 6), (nvar_baseline_offset1 << 6)); + + if (CHSPEC_IS20(pi->radio_chanspec)) { + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 8, 8, + lna1_gain_db); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 8, 8, + lna1_gain_db_2); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x10, + 8, lna2_gain_db); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x10, + 8, lna2_gain_db); + + write_phy_reg(pi, 0x24, clip1md_gaincode); + write_phy_reg(pi, 0x2ab, clip1md_gaincode); + } else { + mod_phy_reg(pi, 0x280, (0xff << 0), (crsminl_th << 0)); + } } } -void wlc_phy_rxcore_setstate_nphy(struct brcms_phy_pub *pih, u8 rxcore_bitmask) +static void wlc_phy_workarounds_nphy_gainctrl(struct brcms_phy *pi) { - u16 regval; - u16 tbl_buf[16]; - uint i; - struct brcms_phy *pi = (struct brcms_phy *) pih; - u16 tbl_opcode; - bool suspend; + u16 w1th, hpf_code, currband; + int ctr; + u8 rfseq_updategainu_events[] = { + NPHY_RFSEQ_CMD_RX_GAIN, + NPHY_RFSEQ_CMD_CLR_HIQ_DIS, + NPHY_RFSEQ_CMD_SET_HPF_BW + }; + u8 rfseq_updategainu_dlys[] = { 10, 30, 1 }; + s8 lna1G_gain_db[] = { 7, 11, 16, 23 }; + s8 lna1G_gain_db_rev4[] = { 8, 12, 17, 25 }; + s8 lna1G_gain_db_rev5[] = { 9, 13, 18, 26 }; + s8 lna1G_gain_db_rev6[] = { 8, 13, 18, 25 }; + s8 lna1G_gain_db_rev6_224B0[] = { 10, 14, 19, 27 }; + s8 lna1A_gain_db[] = { 7, 11, 17, 23 }; + s8 lna1A_gain_db_rev4[] = { 8, 12, 18, 23 }; + s8 lna1A_gain_db_rev5[] = { 6, 10, 16, 21 }; + s8 lna1A_gain_db_rev6[] = { 6, 10, 16, 21 }; + s8 *lna1_gain_db = NULL; + s8 lna2G_gain_db[] = { -5, 6, 10, 14 }; + s8 lna2G_gain_db_rev5[] = { -3, 7, 11, 16 }; + s8 lna2G_gain_db_rev6[] = { -5, 6, 10, 14 }; + s8 lna2G_gain_db_rev6_224B0[] = { -5, 6, 10, 15 }; + s8 lna2A_gain_db[] = { -6, 2, 6, 10 }; + s8 lna2A_gain_db_rev4[] = { -5, 2, 6, 10 }; + s8 lna2A_gain_db_rev5[] = { -7, 0, 4, 8 }; + s8 lna2A_gain_db_rev6[] = { -7, 0, 4, 8 }; + s8 *lna2_gain_db = NULL; + s8 tiaG_gain_db[] = { + 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A }; + s8 tiaA_gain_db[] = { + 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13 }; + s8 tiaA_gain_db_rev4[] = { + 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d }; + s8 tiaA_gain_db_rev5[] = { + 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d }; + s8 tiaA_gain_db_rev6[] = { + 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d }; + s8 *tia_gain_db; + s8 tiaG_gainbits[] = { + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 }; + s8 tiaA_gainbits[] = { + 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06 }; + s8 tiaA_gainbits_rev4[] = { + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 }; + s8 tiaA_gainbits_rev5[] = { + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 }; + s8 tiaA_gainbits_rev6[] = { + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 }; + s8 *tia_gainbits; + s8 lpf_gain_db[] = { 0x00, 0x06, 0x0c, 0x12, 0x12, 0x12 }; + s8 lpf_gainbits[] = { 0x00, 0x01, 0x02, 0x03, 0x03, 0x03 }; + u16 rfseqG_init_gain[] = { 0x613f, 0x613f, 0x613f, 0x613f }; + u16 rfseqG_init_gain_rev4[] = { 0x513f, 0x513f, 0x513f, 0x513f }; + u16 rfseqG_init_gain_rev5[] = { 0x413f, 0x413f, 0x413f, 0x413f }; + u16 rfseqG_init_gain_rev5_elna[] = { + 0x013f, 0x013f, 0x013f, 0x013f }; + u16 rfseqG_init_gain_rev6[] = { 0x513f, 0x513f }; + u16 rfseqG_init_gain_rev6_224B0[] = { 0x413f, 0x413f }; + u16 rfseqG_init_gain_rev6_elna[] = { 0x113f, 0x113f }; + u16 rfseqA_init_gain[] = { 0x516f, 0x516f, 0x516f, 0x516f }; + u16 rfseqA_init_gain_rev4[] = { 0x614f, 0x614f, 0x614f, 0x614f }; + u16 rfseqA_init_gain_rev4_elna[] = { + 0x314f, 0x314f, 0x314f, 0x314f }; + u16 rfseqA_init_gain_rev5[] = { 0x714f, 0x714f, 0x714f, 0x714f }; + u16 rfseqA_init_gain_rev6[] = { 0x714f, 0x714f }; + u16 *rfseq_init_gain; + u16 initG_gaincode = 0x627e; + u16 initG_gaincode_rev4 = 0x527e; + u16 initG_gaincode_rev5 = 0x427e; + u16 initG_gaincode_rev5_elna = 0x027e; + u16 initG_gaincode_rev6 = 0x527e; + u16 initG_gaincode_rev6_224B0 = 0x427e; + u16 initG_gaincode_rev6_elna = 0x127e; + u16 initA_gaincode = 0x52de; + u16 initA_gaincode_rev4 = 0x629e; + u16 initA_gaincode_rev4_elna = 0x329e; + u16 initA_gaincode_rev5 = 0x729e; + u16 initA_gaincode_rev6 = 0x729e; + u16 init_gaincode; + u16 clip1hiG_gaincode = 0x107e; + u16 clip1hiG_gaincode_rev4 = 0x007e; + u16 clip1hiG_gaincode_rev5 = 0x1076; + u16 clip1hiG_gaincode_rev6 = 0x007e; + u16 clip1hiA_gaincode = 0x00de; + u16 clip1hiA_gaincode_rev4 = 0x029e; + u16 clip1hiA_gaincode_rev5 = 0x029e; + u16 clip1hiA_gaincode_rev6 = 0x029e; + u16 clip1hi_gaincode; + u16 clip1mdG_gaincode = 0x0066; + u16 clip1mdA_gaincode = 0x00ca; + u16 clip1mdA_gaincode_rev4 = 0x1084; + u16 clip1mdA_gaincode_rev5 = 0x2084; + u16 clip1mdA_gaincode_rev6 = 0x2084; + u16 clip1md_gaincode = 0; + u16 clip1loG_gaincode = 0x0074; + u16 clip1loG_gaincode_rev5[] = { + 0x0062, 0x0064, 0x006a, 0x106a, 0x106c, 0x1074, 0x107c, 0x207c + }; + u16 clip1loG_gaincode_rev6[] = { + 0x106a, 0x106c, 0x1074, 0x107c, 0x007e, 0x107e, 0x207e, 0x307e + }; + u16 clip1loG_gaincode_rev6_224B0 = 0x1074; + u16 clip1loA_gaincode = 0x00cc; + u16 clip1loA_gaincode_rev4 = 0x0086; + u16 clip1loA_gaincode_rev5 = 0x2086; + u16 clip1loA_gaincode_rev6 = 0x2086; + u16 clip1lo_gaincode; + u8 crsminG_th = 0x18; + u8 crsminG_th_rev5 = 0x18; + u8 crsminG_th_rev6 = 0x18; + u8 crsminA_th = 0x1e; + u8 crsminA_th_rev4 = 0x24; + u8 crsminA_th_rev5 = 0x24; + u8 crsminA_th_rev6 = 0x24; + u8 crsmin_th; + u8 crsminlG_th = 0x18; + u8 crsminlG_th_rev5 = 0x18; + u8 crsminlG_th_rev6 = 0x18; + u8 crsminlA_th = 0x1e; + u8 crsminlA_th_rev4 = 0x24; + u8 crsminlA_th_rev5 = 0x24; + u8 crsminlA_th_rev6 = 0x24; + u8 crsminl_th = 0; + u8 crsminuG_th = 0x18; + u8 crsminuG_th_rev5 = 0x18; + u8 crsminuG_th_rev6 = 0x18; + u8 crsminuA_th = 0x1e; + u8 crsminuA_th_rev4 = 0x24; + u8 crsminuA_th_rev5 = 0x24; + u8 crsminuA_th_rev6 = 0x24; + u8 crsminuA_th_rev6_224B0 = 0x2d; + u8 crsminu_th; + u16 nbclipG_th = 0x20d; + u16 nbclipG_th_rev4 = 0x1a1; + u16 nbclipG_th_rev5 = 0x1d0; + u16 nbclipG_th_rev6 = 0x1d0; + u16 nbclipA_th = 0x1a1; + u16 nbclipA_th_rev4 = 0x107; + u16 nbclipA_th_rev5 = 0x0a9; + u16 nbclipA_th_rev6 = 0x0f0; + u16 nbclip_th = 0; + u8 w1clipG_th = 5; + u8 w1clipG_th_rev5 = 9; + u8 w1clipG_th_rev6 = 5; + u8 w1clipA_th = 25, w1clip_th; + u8 rssi_gain_default = 0x50; + u8 rssiG_gain_rev6_224B0 = 0x50; + u8 rssiA_gain_rev5 = 0x90; + u8 rssiA_gain_rev6 = 0x90; + u8 rssi_gain; + u16 regval[21]; + u8 triso; - pi->sh->phyrxchain = rxcore_bitmask; + triso = (CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.triso : + pi->srom_fem2g.triso; - if (!pi->sh->clk) - return; + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + if (pi->pubpi.radiorev == 5) { + wlc_phy_workarounds_nphy_gainctrl_2057_rev5(pi); + } else if (pi->pubpi.radiorev == 7) { + wlc_phy_workarounds_nphy_gainctrl_2057_rev6(pi); - suspend = - (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); - if (!suspend) - wlapi_suspend_mac_and_wait(pi->sh->physhim); + mod_phy_reg(pi, 0x283, (0xff << 0), (0x44 << 0)); + mod_phy_reg(pi, 0x280, (0xff << 0), (0x44 << 0)); - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, true); + } else if ((pi->pubpi.radiorev == 3) + || (pi->pubpi.radiorev == 8)) { + wlc_phy_workarounds_nphy_gainctrl_2057_rev6(pi); - regval = read_phy_reg(pi, 0xa2); - regval &= ~(0xf << 4); - regval |= ((u16) (rxcore_bitmask & 0x3)) << 4; - write_phy_reg(pi, 0xa2, regval); + if (pi->pubpi.radiorev == 8) { + mod_phy_reg(pi, 0x283, + (0xff << 0), (0x44 << 0)); + mod_phy_reg(pi, 0x280, + (0xff << 0), (0x44 << 0)); + } + } else { + wlc_phy_workarounds_nphy_gainctrl_2057_rev6(pi); + } + } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { - if ((rxcore_bitmask & 0x3) != 0x3) { + mod_phy_reg(pi, 0xa0, (0x1 << 6), (1 << 6)); - write_phy_reg(pi, 0x20e, 1); + mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13)); + mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13)); - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - if (pi->rx2tx_biasentry == -1) { - wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, - ARRAY_SIZE(tbl_buf), 80, - 16, tbl_buf); + currband = + read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand; + if (currband == 0) { + if (NREV_GE(pi->pubpi.phy_rev, 6)) { + if (pi->pubpi.radiorev == 11) { + lna1_gain_db = lna1G_gain_db_rev6_224B0; + lna2_gain_db = lna2G_gain_db_rev6_224B0; + rfseq_init_gain = + rfseqG_init_gain_rev6_224B0; + init_gaincode = + initG_gaincode_rev6_224B0; + clip1hi_gaincode = + clip1hiG_gaincode_rev6; + clip1lo_gaincode = + clip1loG_gaincode_rev6_224B0; + nbclip_th = nbclipG_th_rev6; + w1clip_th = w1clipG_th_rev6; + crsmin_th = crsminG_th_rev6; + crsminl_th = crsminlG_th_rev6; + crsminu_th = crsminuG_th_rev6; + rssi_gain = rssiG_gain_rev6_224B0; + } else { + lna1_gain_db = lna1G_gain_db_rev6; + lna2_gain_db = lna2G_gain_db_rev6; + if (pi->sh->boardflags & BFL_EXTLNA) { - for (i = 0; i < ARRAY_SIZE(tbl_buf); i++) { - if (tbl_buf[i] == - NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS) { + rfseq_init_gain = + rfseqG_init_gain_rev6_elna; + init_gaincode = + initG_gaincode_rev6_elna; + } else { + rfseq_init_gain = + rfseqG_init_gain_rev6; + init_gaincode = + initG_gaincode_rev6; + } + clip1hi_gaincode = + clip1hiG_gaincode_rev6; + switch (triso) { + case 0: + clip1lo_gaincode = + clip1loG_gaincode_rev6 + [0]; + break; + case 1: + clip1lo_gaincode = + clip1loG_gaincode_rev6 + [1]; + break; + case 2: + clip1lo_gaincode = + clip1loG_gaincode_rev6 + [2]; + break; + case 3: + default: - pi->rx2tx_biasentry = (u8) i; - tbl_opcode = - NPHY_REV3_RFSEQ_CMD_NOP; - wlc_phy_table_write_nphy(pi, - NPHY_TBL_ID_RFSEQ, - 1, i, - 16, - &tbl_opcode); + clip1lo_gaincode = + clip1loG_gaincode_rev6 + [3]; break; - } else if (tbl_buf[i] == - NPHY_REV3_RFSEQ_CMD_END) { + case 4: + clip1lo_gaincode = + clip1loG_gaincode_rev6 + [4]; + break; + case 5: + clip1lo_gaincode = + clip1loG_gaincode_rev6 + [5]; + break; + case 6: + clip1lo_gaincode = + clip1loG_gaincode_rev6 + [6]; + break; + case 7: + clip1lo_gaincode = + clip1loG_gaincode_rev6 + [7]; break; } + nbclip_th = nbclipG_th_rev6; + w1clip_th = w1clipG_th_rev6; + crsmin_th = crsminG_th_rev6; + crsminl_th = crsminlG_th_rev6; + crsminu_th = crsminuG_th_rev6; + rssi_gain = rssi_gain_default; + } + } else if (NREV_IS(pi->pubpi.phy_rev, 5)) { + lna1_gain_db = lna1G_gain_db_rev5; + lna2_gain_db = lna2G_gain_db_rev5; + if (pi->sh->boardflags & BFL_EXTLNA) { + + rfseq_init_gain = + rfseqG_init_gain_rev5_elna; + init_gaincode = + initG_gaincode_rev5_elna; + } else { + rfseq_init_gain = rfseqG_init_gain_rev5; + init_gaincode = initG_gaincode_rev5; + } + clip1hi_gaincode = clip1hiG_gaincode_rev5; + switch (triso) { + case 0: + clip1lo_gaincode = + clip1loG_gaincode_rev5[0]; + break; + case 1: + clip1lo_gaincode = + clip1loG_gaincode_rev5[1]; + break; + case 2: + clip1lo_gaincode = + clip1loG_gaincode_rev5[2]; + break; + case 3: + + clip1lo_gaincode = + clip1loG_gaincode_rev5[3]; + break; + case 4: + clip1lo_gaincode = + clip1loG_gaincode_rev5[4]; + break; + case 5: + clip1lo_gaincode = + clip1loG_gaincode_rev5[5]; + break; + case 6: + clip1lo_gaincode = + clip1loG_gaincode_rev5[6]; + break; + case 7: + clip1lo_gaincode = + clip1loG_gaincode_rev5[7]; + break; + default: + clip1lo_gaincode = + clip1loG_gaincode_rev5[3]; + break; } + nbclip_th = nbclipG_th_rev5; + w1clip_th = w1clipG_th_rev5; + crsmin_th = crsminG_th_rev5; + crsminl_th = crsminlG_th_rev5; + crsminu_th = crsminuG_th_rev5; + rssi_gain = rssi_gain_default; + } else if (NREV_IS(pi->pubpi.phy_rev, 4)) { + lna1_gain_db = lna1G_gain_db_rev4; + lna2_gain_db = lna2G_gain_db; + rfseq_init_gain = rfseqG_init_gain_rev4; + init_gaincode = initG_gaincode_rev4; + clip1hi_gaincode = clip1hiG_gaincode_rev4; + clip1lo_gaincode = clip1loG_gaincode; + nbclip_th = nbclipG_th_rev4; + w1clip_th = w1clipG_th; + crsmin_th = crsminG_th; + crsminl_th = crsminlG_th; + crsminu_th = crsminuG_th; + rssi_gain = rssi_gain_default; + } else { + lna1_gain_db = lna1G_gain_db; + lna2_gain_db = lna2G_gain_db; + rfseq_init_gain = rfseqG_init_gain; + init_gaincode = initG_gaincode; + clip1hi_gaincode = clip1hiG_gaincode; + clip1lo_gaincode = clip1loG_gaincode; + nbclip_th = nbclipG_th; + w1clip_th = w1clipG_th; + crsmin_th = crsminG_th; + crsminl_th = crsminlG_th; + crsminu_th = crsminuG_th; + rssi_gain = rssi_gain_default; } - } - } else { + tia_gain_db = tiaG_gain_db; + tia_gainbits = tiaG_gainbits; + clip1md_gaincode = clip1mdG_gaincode; + } else { + if (NREV_GE(pi->pubpi.phy_rev, 6)) { + lna1_gain_db = lna1A_gain_db_rev6; + lna2_gain_db = lna2A_gain_db_rev6; + tia_gain_db = tiaA_gain_db_rev6; + tia_gainbits = tiaA_gainbits_rev6; + rfseq_init_gain = rfseqA_init_gain_rev6; + init_gaincode = initA_gaincode_rev6; + clip1hi_gaincode = clip1hiA_gaincode_rev6; + clip1md_gaincode = clip1mdA_gaincode_rev6; + clip1lo_gaincode = clip1loA_gaincode_rev6; + crsmin_th = crsminA_th_rev6; + crsminl_th = crsminlA_th_rev6; + if ((pi->pubpi.radiorev == 11) && + (CHSPEC_IS40(pi->radio_chanspec) == 0)) + crsminu_th = crsminuA_th_rev6_224B0; + else + crsminu_th = crsminuA_th_rev6; - write_phy_reg(pi, 0x20e, 30); + nbclip_th = nbclipA_th_rev6; + rssi_gain = rssiA_gain_rev6; + } else if (NREV_IS(pi->pubpi.phy_rev, 5)) { + lna1_gain_db = lna1A_gain_db_rev5; + lna2_gain_db = lna2A_gain_db_rev5; + tia_gain_db = tiaA_gain_db_rev5; + tia_gainbits = tiaA_gainbits_rev5; + rfseq_init_gain = rfseqA_init_gain_rev5; + init_gaincode = initA_gaincode_rev5; + clip1hi_gaincode = clip1hiA_gaincode_rev5; + clip1md_gaincode = clip1mdA_gaincode_rev5; + clip1lo_gaincode = clip1loA_gaincode_rev5; + crsmin_th = crsminA_th_rev5; + crsminl_th = crsminlA_th_rev5; + crsminu_th = crsminuA_th_rev5; + nbclip_th = nbclipA_th_rev5; + rssi_gain = rssiA_gain_rev5; + } else if (NREV_IS(pi->pubpi.phy_rev, 4)) { + lna1_gain_db = lna1A_gain_db_rev4; + lna2_gain_db = lna2A_gain_db_rev4; + tia_gain_db = tiaA_gain_db_rev4; + tia_gainbits = tiaA_gainbits_rev4; + if (pi->sh->boardflags & BFL_EXTLNA_5GHz) { - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - if (pi->rx2tx_biasentry != -1) { - tbl_opcode = NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS; - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, - 1, pi->rx2tx_biasentry, - 16, &tbl_opcode); - pi->rx2tx_biasentry = -1; + rfseq_init_gain = + rfseqA_init_gain_rev4_elna; + init_gaincode = + initA_gaincode_rev4_elna; + } else { + rfseq_init_gain = rfseqA_init_gain_rev4; + init_gaincode = initA_gaincode_rev4; + } + clip1hi_gaincode = clip1hiA_gaincode_rev4; + clip1md_gaincode = clip1mdA_gaincode_rev4; + clip1lo_gaincode = clip1loA_gaincode_rev4; + crsmin_th = crsminA_th_rev4; + crsminl_th = crsminlA_th_rev4; + crsminu_th = crsminuA_th_rev4; + nbclip_th = nbclipA_th_rev4; + rssi_gain = rssi_gain_default; + } else { + lna1_gain_db = lna1A_gain_db; + lna2_gain_db = lna2A_gain_db; + tia_gain_db = tiaA_gain_db; + tia_gainbits = tiaA_gainbits; + rfseq_init_gain = rfseqA_init_gain; + init_gaincode = initA_gaincode; + clip1hi_gaincode = clip1hiA_gaincode; + clip1md_gaincode = clip1mdA_gaincode; + clip1lo_gaincode = clip1loA_gaincode; + crsmin_th = crsminA_th; + crsminl_th = crsminlA_th; + crsminu_th = crsminuA_th; + nbclip_th = nbclipA_th; + rssi_gain = rssi_gain_default; } + w1clip_th = w1clipA_th; } - } - wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX); + write_radio_reg(pi, + (RADIO_2056_RX_BIASPOLE_LNAG1_IDAC | + RADIO_2056_RX0), 0x17); + write_radio_reg(pi, + (RADIO_2056_RX_BIASPOLE_LNAG1_IDAC | + RADIO_2056_RX1), 0x17); - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, false); + write_radio_reg(pi, (RADIO_2056_RX_LNAG2_IDAC | RADIO_2056_RX0), + 0xf0); + write_radio_reg(pi, (RADIO_2056_RX_LNAG2_IDAC | RADIO_2056_RX1), + 0xf0); - if (!suspend) - wlapi_enable_mac(pi->sh->physhim); -} + write_radio_reg(pi, (RADIO_2056_RX_RSSI_POLE | RADIO_2056_RX0), + 0x0); + write_radio_reg(pi, (RADIO_2056_RX_RSSI_POLE | RADIO_2056_RX1), + 0x0); -u8 wlc_phy_rxcore_getstate_nphy(struct brcms_phy_pub *pih) -{ - u16 regval, rxen_bits; - struct brcms_phy *pi = (struct brcms_phy *) pih; + write_radio_reg(pi, (RADIO_2056_RX_RSSI_GAIN | RADIO_2056_RX0), + rssi_gain); + write_radio_reg(pi, (RADIO_2056_RX_RSSI_GAIN | RADIO_2056_RX1), + rssi_gain); - regval = read_phy_reg(pi, 0xa2); - rxen_bits = (regval >> 4) & 0xf; + write_radio_reg(pi, + (RADIO_2056_RX_BIASPOLE_LNAA1_IDAC | + RADIO_2056_RX0), 0x17); + write_radio_reg(pi, + (RADIO_2056_RX_BIASPOLE_LNAA1_IDAC | + RADIO_2056_RX1), 0x17); - return (u8) rxen_bits; -} + write_radio_reg(pi, (RADIO_2056_RX_LNAA2_IDAC | RADIO_2056_RX0), + 0xFF); + write_radio_reg(pi, (RADIO_2056_RX_LNAA2_IDAC | RADIO_2056_RX1), + 0xFF); -bool wlc_phy_n_txpower_ipa_ison(struct brcms_phy *pi) -{ - return PHY_IPA(pi); -} + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 8, + 8, lna1_gain_db); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 8, + 8, lna1_gain_db); -static void wlc_phy_txpwr_limit_to_tbl_nphy(struct brcms_phy *pi) -{ - u8 idx, idx2, i, delta_ind; + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x10, + 8, lna2_gain_db); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x10, + 8, lna2_gain_db); - for (idx = TXP_FIRST_CCK; idx <= TXP_LAST_CCK; idx++) { - pi->adj_pwr_tbl_nphy[idx] = pi->tx_power_offset[idx]; - } + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 10, 0x20, + 8, tia_gain_db); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 10, 0x20, + 8, tia_gain_db); - for (i = 0; i < 4; i++) { - idx2 = 0; + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 10, 0x20, + 8, tia_gainbits); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 10, 0x20, + 8, tia_gainbits); - delta_ind = 0; + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 6, 0x40, + 8, &lpf_gain_db); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 6, 0x40, + 8, &lpf_gain_db); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 6, 0x40, + 8, &lpf_gainbits); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 6, 0x40, + 8, &lpf_gainbits); - switch (i) { - case 0: + write_phy_reg(pi, 0x20, init_gaincode); + write_phy_reg(pi, 0x2a7, init_gaincode); - if (CHSPEC_IS40(pi->radio_chanspec) - && NPHY_IS_SROM_REINTERPRET) { - idx = TXP_FIRST_MCS_40_SISO; - } else { - idx = (CHSPEC_IS40(pi->radio_chanspec)) ? - TXP_FIRST_OFDM_40_SISO : TXP_FIRST_OFDM; - delta_ind = 1; - } - break; + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, + pi->pubpi.phy_corenum, 0x106, 16, + rfseq_init_gain); - case 1: + write_phy_reg(pi, 0x22, clip1hi_gaincode); + write_phy_reg(pi, 0x2a9, clip1hi_gaincode); - idx = (CHSPEC_IS40(pi->radio_chanspec)) ? - TXP_FIRST_MCS_40_CDD : TXP_FIRST_MCS_20_CDD; - break; + write_phy_reg(pi, 0x24, clip1md_gaincode); + write_phy_reg(pi, 0x2ab, clip1md_gaincode); - case 2: + write_phy_reg(pi, 0x37, clip1lo_gaincode); + write_phy_reg(pi, 0x2ad, clip1lo_gaincode); - idx = (CHSPEC_IS40(pi->radio_chanspec)) ? - TXP_FIRST_MCS_40_STBC : TXP_FIRST_MCS_20_STBC; - break; + mod_phy_reg(pi, 0x27d, (0xff << 0), (crsmin_th << 0)); + mod_phy_reg(pi, 0x280, (0xff << 0), (crsminl_th << 0)); + mod_phy_reg(pi, 0x283, (0xff << 0), (crsminu_th << 0)); - case 3: + write_phy_reg(pi, 0x2b, nbclip_th); + write_phy_reg(pi, 0x41, nbclip_th); - idx = (CHSPEC_IS40(pi->radio_chanspec)) ? - TXP_FIRST_MCS_40_SDM : TXP_FIRST_MCS_20_SDM; - break; + mod_phy_reg(pi, 0x27, (0x3f << 0), (w1clip_th << 0)); + mod_phy_reg(pi, 0x3d, (0x3f << 0), (w1clip_th << 0)); + + write_phy_reg(pi, 0x150, 0x809c); + + } else { + + mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13)); + mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13)); + + write_phy_reg(pi, 0x2b, 0x84); + write_phy_reg(pi, 0x41, 0x84); + + if (CHSPEC_IS20(pi->radio_chanspec)) { + write_phy_reg(pi, 0x6b, 0x2b); + write_phy_reg(pi, 0x6c, 0x2b); + write_phy_reg(pi, 0x6d, 0x9); + write_phy_reg(pi, 0x6e, 0x9); } - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx]; - idx = idx + delta_ind; - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx]; - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx]; - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx++]; + w1th = NPHY_RSSICAL_W1_TARGET - 4; + mod_phy_reg(pi, 0x27, (0x3f << 0), (w1th << 0)); + mod_phy_reg(pi, 0x3d, (0x3f << 0), (w1th << 0)); - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx++]; - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx]; - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx]; - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx++]; + if (CHSPEC_IS20(pi->radio_chanspec)) { + mod_phy_reg(pi, 0x1c, (0x1f << 0), (0x1 << 0)); + mod_phy_reg(pi, 0x32, (0x1f << 0), (0x1 << 0)); - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx++]; - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx]; - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx]; - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx++]; + mod_phy_reg(pi, 0x1d, (0x1f << 0), (0x1 << 0)); + mod_phy_reg(pi, 0x33, (0x1f << 0), (0x1 << 0)); + } - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx]; - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx++]; - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx]; - idx = idx + 1 - delta_ind; - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx]; + write_phy_reg(pi, 0x150, 0x809c); - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx]; - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx]; - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx]; - pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = - pi->tx_power_offset[idx]; - } -} + if (pi->nphy_gain_boost) + if ((CHSPEC_IS2G(pi->radio_chanspec)) && + (CHSPEC_IS40(pi->radio_chanspec))) + hpf_code = 4; + else + hpf_code = 5; + else if (CHSPEC_IS40(pi->radio_chanspec)) + hpf_code = 6; + else + hpf_code = 7; -void wlc_phy_cal_init_nphy(struct brcms_phy *pi) -{ -} + mod_phy_reg(pi, 0x20, (0x1f << 7), (hpf_code << 7)); + mod_phy_reg(pi, 0x36, (0x1f << 7), (hpf_code << 7)); -static void -wlc_phy_war_force_trsw_to_R_cliplo_nphy(struct brcms_phy *pi, u8 core) -{ - if (core == PHY_CORE_0) { - write_phy_reg(pi, 0x38, 0x4); - if (CHSPEC_IS2G(pi->radio_chanspec)) { - write_phy_reg(pi, 0x37, 0x0060); - } else { - write_phy_reg(pi, 0x37, 0x1080); + for (ctr = 0; ctr < 4; ctr++) + regval[ctr] = (hpf_code << 8) | 0x7c; + wlc_phy_table_write_nphy(pi, 7, 4, 0x106, 16, regval); + + wlc_phy_adjust_lnagaintbl_nphy(pi); + + if (pi->nphy_elna_gain_config) { + regval[0] = 0; + regval[1] = 1; + regval[2] = 1; + regval[3] = 1; + wlc_phy_table_write_nphy(pi, 2, 4, 8, 16, regval); + wlc_phy_table_write_nphy(pi, 3, 4, 8, 16, regval); + + for (ctr = 0; ctr < 4; ctr++) + regval[ctr] = (hpf_code << 8) | 0x74; + wlc_phy_table_write_nphy(pi, 7, 4, 0x106, 16, regval); } - } else if (core == PHY_CORE_1) { - write_phy_reg(pi, 0x2ae, 0x4); - if (CHSPEC_IS2G(pi->radio_chanspec)) { - write_phy_reg(pi, 0x2ad, 0x0060); - } else { - write_phy_reg(pi, 0x2ad, 0x1080); + + if (NREV_IS(pi->pubpi.phy_rev, 2)) { + for (ctr = 0; ctr < 21; ctr++) + regval[ctr] = 3 * ctr; + wlc_phy_table_write_nphy(pi, 0, 21, 32, 16, regval); + wlc_phy_table_write_nphy(pi, 1, 21, 32, 16, regval); + + for (ctr = 0; ctr < 21; ctr++) + regval[ctr] = (u16) ctr; + wlc_phy_table_write_nphy(pi, 2, 21, 32, 16, regval); + wlc_phy_table_write_nphy(pi, 3, 21, 32, 16, regval); } - } -} -static void wlc_phy_war_txchain_upd_nphy(struct brcms_phy *pi, u8 txchain) -{ - u8 txchain0, txchain1; + wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_UPDATEGAINU, + rfseq_updategainu_events, + rfseq_updategainu_dlys, + sizeof(rfseq_updategainu_events) / + sizeof(rfseq_updategainu_events[0])); - txchain0 = txchain & 0x1; - txchain1 = (txchain & 0x2) >> 1; - if (!txchain0) { - wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_0); - } + mod_phy_reg(pi, 0x153, (0xff << 8), (90 << 8)); - if (!txchain1) { - wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_1); + if (CHSPEC_IS2G(pi->radio_chanspec)) + mod_phy_reg(pi, + (NPHY_TO_BPHY_OFF + BPHY_OPTIONAL_MODES), + 0x7f, 0x4); } } @@ -15362,11 +16201,10 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) u16 freq; int coreNum; - if (CHSPEC_IS5G(pi->radio_chanspec)) { + if (CHSPEC_IS5G(pi->radio_chanspec)) wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_cck_en, 0); - } else { + else wlc_phy_classifier_nphy(pi, NPHY_ClassifierCtrl_cck_en, 1); - } if (pi->phyhang_avoid) wlc_phy_stay_in_carriersearch_nphy(pi, true); @@ -15401,9 +16239,8 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) write_phy_reg(pi, 0x240, 0x1b0); } - if (NREV_GE(pi->pubpi.phy_rev, 8)) { + if (NREV_GE(pi->pubpi.phy_rev, 8)) mod_phy_reg(pi, 0xbd, (0xff << 0), (114 << 0)); - } wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x00, 16, &dac_control); @@ -15422,7 +16259,7 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x16e, 16, rfseq_rx2tx_dacbufpu_rev7); - if (PHY_IPA(pi)) { + if (PHY_IPA(pi)) wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX, rfseq_rx2tx_events_rev3_ipa, rfseq_rx2tx_dlys_rev3_ipa, @@ -15431,7 +16268,6 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) sizeof (rfseq_rx2tx_events_rev3_ipa [0])); - } mod_phy_reg(pi, 0x299, (0x3 << 14), (0x1 << 14)); mod_phy_reg(pi, 0x29d, (0x3 << 14), (0x1 << 14)); @@ -15448,11 +16284,13 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) || (pi->pubpi.radiorev == 8)) { rccal_bcap_val = - read_radio_reg(pi, - RADIO_2057_RCCAL_BCAP_VAL); + read_radio_reg( + pi, + RADIO_2057_RCCAL_BCAP_VAL); rccal_scap_val = - read_radio_reg(pi, - RADIO_2057_RCCAL_SCAP_VAL); + read_radio_reg( + pi, + RADIO_2057_RCCAL_SCAP_VAL); rccal_tx20_11b_bcap = rccal_bcap_val; rccal_tx20_11b_scap = rccal_scap_val; @@ -15497,11 +16335,13 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) tx_lpf_bw_ofdm_40mhz = 3; rccal_bcap_val = - read_radio_reg(pi, - RADIO_2057_RCCAL_BCAP_VAL); + read_radio_reg( + pi, + RADIO_2057_RCCAL_BCAP_VAL); rccal_scap_val = - read_radio_reg(pi, - RADIO_2057_RCCAL_SCAP_VAL); + read_radio_reg( + pi, + RADIO_2057_RCCAL_SCAP_VAL); rccal_tx20_11b_bcap = rccal_bcap_val; rccal_tx20_11b_scap = rccal_scap_val; @@ -15517,70 +16357,83 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) if (rccal_ovrd) { - rx2tx_lpf_rc_lut_tx20_11b = (rccal_tx20_11b_bcap << 8) | - (rccal_tx20_11b_scap << 3) | tx_lpf_bw_11b; - rx2tx_lpf_rc_lut_tx20_11n = (rccal_tx20_11n_bcap << 8) | - (rccal_tx20_11n_scap << 3) | tx_lpf_bw_ofdm_20mhz; - rx2tx_lpf_rc_lut_tx40_11n = (rccal_tx40_11n_bcap << 8) | - (rccal_tx40_11n_scap << 3) | tx_lpf_bw_ofdm_40mhz; + rx2tx_lpf_rc_lut_tx20_11b = + (rccal_tx20_11b_bcap << 8) | + (rccal_tx20_11b_scap << 3) | + tx_lpf_bw_11b; + rx2tx_lpf_rc_lut_tx20_11n = + (rccal_tx20_11n_bcap << 8) | + (rccal_tx20_11n_scap << 3) | + tx_lpf_bw_ofdm_20mhz; + rx2tx_lpf_rc_lut_tx40_11n = + (rccal_tx40_11n_bcap << 8) | + (rccal_tx40_11n_scap << 3) | + tx_lpf_bw_ofdm_40mhz; for (coreNum = 0; coreNum <= 1; coreNum++) { - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, - 1, - 0x152 + coreNum * 0x10, - 16, - &rx2tx_lpf_rc_lut_tx20_11b); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, - 1, - 0x153 + coreNum * 0x10, - 16, - &rx2tx_lpf_rc_lut_tx20_11n); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, - 1, - 0x154 + coreNum * 0x10, - 16, - &rx2tx_lpf_rc_lut_tx20_11n); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, - 1, - 0x155 + coreNum * 0x10, - 16, - &rx2tx_lpf_rc_lut_tx40_11n); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, - 1, - 0x156 + coreNum * 0x10, - 16, - &rx2tx_lpf_rc_lut_tx40_11n); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, - 1, - 0x157 + coreNum * 0x10, - 16, - &rx2tx_lpf_rc_lut_tx40_11n); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, - 1, - 0x158 + coreNum * 0x10, - 16, - &rx2tx_lpf_rc_lut_tx40_11n); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, - 1, - 0x159 + coreNum * 0x10, - 16, - &rx2tx_lpf_rc_lut_tx40_11n); + wlc_phy_table_write_nphy( + pi, NPHY_TBL_ID_RFSEQ, + 1, + 0x152 + coreNum * 0x10, + 16, + &rx2tx_lpf_rc_lut_tx20_11b); + wlc_phy_table_write_nphy( + pi, NPHY_TBL_ID_RFSEQ, + 1, + 0x153 + coreNum * 0x10, + 16, + &rx2tx_lpf_rc_lut_tx20_11n); + wlc_phy_table_write_nphy( + pi, NPHY_TBL_ID_RFSEQ, + 1, + 0x154 + coreNum * 0x10, + 16, + &rx2tx_lpf_rc_lut_tx20_11n); + wlc_phy_table_write_nphy( + pi, NPHY_TBL_ID_RFSEQ, + 1, + 0x155 + coreNum * 0x10, + 16, + &rx2tx_lpf_rc_lut_tx40_11n); + wlc_phy_table_write_nphy( + pi, NPHY_TBL_ID_RFSEQ, + 1, + 0x156 + coreNum * 0x10, + 16, + &rx2tx_lpf_rc_lut_tx40_11n); + wlc_phy_table_write_nphy( + pi, NPHY_TBL_ID_RFSEQ, + 1, + 0x157 + coreNum * 0x10, + 16, + &rx2tx_lpf_rc_lut_tx40_11n); + wlc_phy_table_write_nphy( + pi, NPHY_TBL_ID_RFSEQ, + 1, + 0x158 + coreNum * 0x10, + 16, + &rx2tx_lpf_rc_lut_tx40_11n); + wlc_phy_table_write_nphy( + pi, NPHY_TBL_ID_RFSEQ, + 1, + 0x159 + coreNum * 0x10, + 16, + &rx2tx_lpf_rc_lut_tx40_11n); } - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), - 1, 0x3, 0, - NPHY_REV7_RFCTRLOVERRIDE_ID2); + wlc_phy_rfctrl_override_nphy_rev7( + pi, (0x1 << 4), + 1, 0x3, 0, + NPHY_REV7_RFCTRLOVERRIDE_ID2); } - if (!NORADIO_ENAB(pi->pubpi)) { - write_phy_reg(pi, 0x32f, 0x3); - } + write_phy_reg(pi, 0x32f, 0x3); - if ((pi->pubpi.radiorev == 4) || (pi->pubpi.radiorev == 6)) { - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), - 1, 0x3, 0, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - } + if ((pi->pubpi.radiorev == 4) || (pi->pubpi.radiorev == 6)) + wlc_phy_rfctrl_override_nphy_rev7( + pi, (0x1 << 2), + 1, 0x3, 0, + NPHY_REV7_RFCTRLOVERRIDE_ID0); if ((pi->pubpi.radiorev == 3) || (pi->pubpi.radiorev == 4) || (pi->pubpi.radiorev == 6)) { @@ -15635,17 +16488,16 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) if (CHSPEC_IS2G(pi->radio_chanspec)) { if ((pi->pubpi.radiorev == 3) || (pi->pubpi.radiorev == 4) - || (pi->pubpi.radiorev == 6)) { - + || (pi->pubpi.radiorev == 6)) txgm_idac_bleed = 0x7f; - } for (coreNum = 0; coreNum <= 1; coreNum++) { if (txgm_idac_bleed != 0) - WRITE_RADIO_REG4(pi, RADIO_2057, - CORE, coreNum, - TXGM_IDAC_BLEED, - txgm_idac_bleed); + WRITE_RADIO_REG4( + pi, RADIO_2057, + CORE, coreNum, + TXGM_IDAC_BLEED, + txgm_idac_bleed); } if (pi->pubpi.radiorev == 5) { @@ -15660,18 +16512,20 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) CORE, coreNum, IPA2G_IMAIN, 0x1f); - WRITE_RADIO_REG4(pi, RADIO_2057, - CORE, coreNum, - IPA2G_BIAS_FILTER, - 0xee); + WRITE_RADIO_REG4( + pi, RADIO_2057, + CORE, coreNum, + IPA2G_BIAS_FILTER, + 0xee); WRITE_RADIO_REG4(pi, RADIO_2057, CORE, coreNum, PAD2G_IDACS, 0x8a); - WRITE_RADIO_REG4(pi, RADIO_2057, - CORE, coreNum, - PAD_BIAS_FILTER_BWS, - 0x3e); + WRITE_RADIO_REG4( + pi, RADIO_2057, + CORE, coreNum, + PAD_BIAS_FILTER_BWS, + 0x3e); } } else if ((pi->pubpi.radiorev == 7) @@ -15700,9 +16554,8 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) } } else { - freq = - CHAN5G_FREQ(CHSPEC_CHANNEL - (pi->radio_chanspec)); + freq = CHAN5G_FREQ(CHSPEC_CHANNEL( + pi->radio_chanspec)); if (((freq >= 5180) && (freq <= 5230)) || ((freq >= 5745) && (freq <= 5805))) { WRITE_RADIO_REG4(pi, RADIO_2057, CORE, @@ -15809,12 +16662,12 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) wlc_phy_workarounds_nphy_gainctrl(pi); pdetrange = - (CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g. - pdetrange : pi->srom_fem2g.pdetrange; + (CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g. + pdetrange : pi->srom_fem2g.pdetrange; if (pdetrange == 0) { chan_freq_range = - wlc_phy_get_chan_freq_range_nphy(pi, 0); + wlc_phy_get_chan_freq_range_nphy(pi, 0); if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) { aux_adc_vmid_rev7_core0[3] = 0x70; aux_adc_vmid_rev7_core1[3] = 0x70; @@ -15842,15 +16695,15 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) if (chan_freq_range == WL_CHAN_FREQ_RANGE_2G) { aux_adc_vmid_rev7_core0[3] = - 0x8c; + 0x8c; aux_adc_vmid_rev7_core1[3] = - 0x8c; + 0x8c; aux_adc_gain_rev7[3] = 0; } else { aux_adc_vmid_rev7_core0[3] = - 0x96; + 0x96; aux_adc_vmid_rev7_core1[3] = - 0x96; + 0x96; aux_adc_gain_rev7[3] = 0; } } @@ -15918,7 +16771,7 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) sizeof(rfseq_tx2rx_events_rev3) / sizeof(rfseq_tx2rx_events_rev3[0])); - if (PHY_IPA(pi)) { + if (PHY_IPA(pi)) wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX, rfseq_rx2tx_events_rev3_ipa, rfseq_rx2tx_dlys_rev3_ipa, @@ -15927,7 +16780,6 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) sizeof (rfseq_rx2tx_events_rev3_ipa [0])); - } if ((pi->sh->hw_phyrxchain != 0x3) && (pi->sh->hw_phyrxchain != pi->sh->hw_phytxchain)) { @@ -15936,22 +16788,21 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) rfseq_rx2tx_dlys_rev3[5] = 59; rfseq_rx2tx_dlys_rev3[6] = 1; rfseq_rx2tx_events_rev3[7] = - NPHY_REV3_RFSEQ_CMD_END; + NPHY_REV3_RFSEQ_CMD_END; } - wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX, - rfseq_rx2tx_events_rev3, - rfseq_rx2tx_dlys_rev3, - sizeof(rfseq_rx2tx_events_rev3) / - sizeof(rfseq_rx2tx_events_rev3 - [0])); + wlc_phy_set_rfseq_nphy( + pi, NPHY_RFSEQ_RX2TX, + rfseq_rx2tx_events_rev3, + rfseq_rx2tx_dlys_rev3, + sizeof(rfseq_rx2tx_events_rev3) / + sizeof(rfseq_rx2tx_events_rev3[0])); } - if (CHSPEC_IS2G(pi->radio_chanspec)) { + if (CHSPEC_IS2G(pi->radio_chanspec)) write_phy_reg(pi, 0x6a, 0x2); - } else { + else write_phy_reg(pi, 0x6a, 0x9c40); - } mod_phy_reg(pi, 0x294, (0xf << 8), (7 << 8)); @@ -15978,8 +16829,8 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) &dac_control); pdetrange = - (CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g. - pdetrange : pi->srom_fem2g.pdetrange; + (CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g. + pdetrange : pi->srom_fem2g.pdetrange; if (pdetrange == 0) { if (NREV_GE(pi->pubpi.phy_rev, 4)) { @@ -15990,7 +16841,7 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) aux_adc_gain = aux_adc_gain_rev3; } chan_freq_range = - wlc_phy_get_chan_freq_range_nphy(pi, 0); + wlc_phy_get_chan_freq_range_nphy(pi, 0); if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) { switch (chan_freq_range) { case WL_CHAN_FREQ_RANGE_5GL: @@ -16033,7 +16884,7 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) if (NREV_GE(pi->pubpi.phy_rev, 6)) { chan_freq_range = - wlc_phy_get_chan_freq_range_nphy(pi, 0); + wlc_phy_get_chan_freq_range_nphy(pi, 0); if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) { bcm_adc_vmid[3] = 0x8e; bcm_adc_gain[3] = 0x03; @@ -16056,14 +16907,16 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) 0x1c, 16, bcm_adc_gain); } else if (pdetrange == 3) { chan_freq_range = - wlc_phy_get_chan_freq_range_nphy(pi, 0); + wlc_phy_get_chan_freq_range_nphy(pi, 0); if ((NREV_GE(pi->pubpi.phy_rev, 4)) && (chan_freq_range == WL_CHAN_FREQ_RANGE_2G)) { u16 auxadc_vmid[] = { - 0xa2, 0xb4, 0xb4, 0x270 }; + 0xa2, 0xb4, 0xb4, 0x270 + }; u16 auxadc_gain[] = { - 0x02, 0x02, 0x02, 0x00 }; + 0x02, 0x02, 0x02, 0x00 + }; wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 4, @@ -16084,7 +16937,7 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) u16 Vmid[2], Av[2]; chan_freq_range = - wlc_phy_get_chan_freq_range_nphy(pi, 0); + wlc_phy_get_chan_freq_range_nphy(pi, 0); if (chan_freq_range != WL_CHAN_FREQ_RANGE_2G) { Vmid[0] = (pdetrange == 4) ? 0x8e : 0x89; Vmid[1] = (pdetrange == 4) ? 0x96 : 0x89; @@ -16155,8 +17008,8 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) 0x0); triso = - (CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g. - triso : pi->srom_fem2g.triso; + (CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g. + triso : pi->srom_fem2g.triso; if (triso == 7) { wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_0); wlc_phy_war_force_trsw_to_R_cliplo_nphy(pi, PHY_CORE_1); @@ -16212,11 +17065,10 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) if (NREV_GE(pi->pubpi.phy_rev, 6)) { - if (pi->sh->boardflags2 & BFL2_SINGLEANT_CCK) { + if (pi->sh->boardflags2 & BFL2_SINGLEANT_CCK) wlapi_bmac_mhf(pi->sh->physhim, MHF4, - MHF4_BPHY_TXCORE0, - MHF4_BPHY_TXCORE0, BRCM_BAND_ALL); - } + MHF4_BPHY_TXCORE0, + MHF4_BPHY_TXCORE0, BRCM_BAND_ALL); } } else { @@ -16314,1121 +17166,2719 @@ static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) write_phy_reg(pi, 0x194, 0x0); } - if (NREV_IS(pi->pubpi.phy_rev, 2)) { + if (NREV_IS(pi->pubpi.phy_rev, 2)) mod_phy_reg(pi, 0x221, NPHY_FORCESIG_DECODEGATEDCLKS, NPHY_FORCESIG_DECODEGATEDCLKS); - } } if (pi->phyhang_avoid) wlc_phy_stay_in_carriersearch_nphy(pi, false); } -static void wlc_phy_workarounds_nphy_gainctrl(struct brcms_phy *pi) +static void wlc_phy_extpa_set_tx_digi_filts_nphy(struct brcms_phy *pi) { - u16 w1th, hpf_code, currband; - int ctr; - u8 rfseq_updategainu_events[] = { - NPHY_RFSEQ_CMD_RX_GAIN, - NPHY_RFSEQ_CMD_CLR_HIQ_DIS, - NPHY_RFSEQ_CMD_SET_HPF_BW - }; - u8 rfseq_updategainu_dlys[] = { 10, 30, 1 }; - s8 lna1G_gain_db[] = { 7, 11, 16, 23 }; - s8 lna1G_gain_db_rev4[] = { 8, 12, 17, 25 }; - s8 lna1G_gain_db_rev5[] = { 9, 13, 18, 26 }; - s8 lna1G_gain_db_rev6[] = { 8, 13, 18, 25 }; - s8 lna1G_gain_db_rev6_224B0[] = { 10, 14, 19, 27 }; - s8 lna1A_gain_db[] = { 7, 11, 17, 23 }; - s8 lna1A_gain_db_rev4[] = { 8, 12, 18, 23 }; - s8 lna1A_gain_db_rev5[] = { 6, 10, 16, 21 }; - s8 lna1A_gain_db_rev6[] = { 6, 10, 16, 21 }; - s8 *lna1_gain_db = NULL; - s8 lna2G_gain_db[] = { -5, 6, 10, 14 }; - s8 lna2G_gain_db_rev5[] = { -3, 7, 11, 16 }; - s8 lna2G_gain_db_rev6[] = { -5, 6, 10, 14 }; - s8 lna2G_gain_db_rev6_224B0[] = { -5, 6, 10, 15 }; - s8 lna2A_gain_db[] = { -6, 2, 6, 10 }; - s8 lna2A_gain_db_rev4[] = { -5, 2, 6, 10 }; - s8 lna2A_gain_db_rev5[] = { -7, 0, 4, 8 }; - s8 lna2A_gain_db_rev6[] = { -7, 0, 4, 8 }; - s8 *lna2_gain_db = NULL; - s8 tiaG_gain_db[] = { - 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A }; - s8 tiaA_gain_db[] = { - 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13 }; - s8 tiaA_gain_db_rev4[] = { - 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d }; - s8 tiaA_gain_db_rev5[] = { - 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d }; - s8 tiaA_gain_db_rev6[] = { - 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d }; - s8 *tia_gain_db; - s8 tiaG_gainbits[] = { - 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 }; - s8 tiaA_gainbits[] = { - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06 }; - s8 tiaA_gainbits_rev4[] = { - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 }; - s8 tiaA_gainbits_rev5[] = { - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 }; - s8 tiaA_gainbits_rev6[] = { - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 }; - s8 *tia_gainbits; - s8 lpf_gain_db[] = { 0x00, 0x06, 0x0c, 0x12, 0x12, 0x12 }; - s8 lpf_gainbits[] = { 0x00, 0x01, 0x02, 0x03, 0x03, 0x03 }; - u16 rfseqG_init_gain[] = { 0x613f, 0x613f, 0x613f, 0x613f }; - u16 rfseqG_init_gain_rev4[] = { 0x513f, 0x513f, 0x513f, 0x513f }; - u16 rfseqG_init_gain_rev5[] = { 0x413f, 0x413f, 0x413f, 0x413f }; - u16 rfseqG_init_gain_rev5_elna[] = { - 0x013f, 0x013f, 0x013f, 0x013f }; - u16 rfseqG_init_gain_rev6[] = { 0x513f, 0x513f }; - u16 rfseqG_init_gain_rev6_224B0[] = { 0x413f, 0x413f }; - u16 rfseqG_init_gain_rev6_elna[] = { 0x113f, 0x113f }; - u16 rfseqA_init_gain[] = { 0x516f, 0x516f, 0x516f, 0x516f }; - u16 rfseqA_init_gain_rev4[] = { 0x614f, 0x614f, 0x614f, 0x614f }; - u16 rfseqA_init_gain_rev4_elna[] = { - 0x314f, 0x314f, 0x314f, 0x314f }; - u16 rfseqA_init_gain_rev5[] = { 0x714f, 0x714f, 0x714f, 0x714f }; - u16 rfseqA_init_gain_rev6[] = { 0x714f, 0x714f }; - u16 *rfseq_init_gain; - u16 initG_gaincode = 0x627e; - u16 initG_gaincode_rev4 = 0x527e; - u16 initG_gaincode_rev5 = 0x427e; - u16 initG_gaincode_rev5_elna = 0x027e; - u16 initG_gaincode_rev6 = 0x527e; - u16 initG_gaincode_rev6_224B0 = 0x427e; - u16 initG_gaincode_rev6_elna = 0x127e; - u16 initA_gaincode = 0x52de; - u16 initA_gaincode_rev4 = 0x629e; - u16 initA_gaincode_rev4_elna = 0x329e; - u16 initA_gaincode_rev5 = 0x729e; - u16 initA_gaincode_rev6 = 0x729e; - u16 init_gaincode; - u16 clip1hiG_gaincode = 0x107e; - u16 clip1hiG_gaincode_rev4 = 0x007e; - u16 clip1hiG_gaincode_rev5 = 0x1076; - u16 clip1hiG_gaincode_rev6 = 0x007e; - u16 clip1hiA_gaincode = 0x00de; - u16 clip1hiA_gaincode_rev4 = 0x029e; - u16 clip1hiA_gaincode_rev5 = 0x029e; - u16 clip1hiA_gaincode_rev6 = 0x029e; - u16 clip1hi_gaincode; - u16 clip1mdG_gaincode = 0x0066; - u16 clip1mdA_gaincode = 0x00ca; - u16 clip1mdA_gaincode_rev4 = 0x1084; - u16 clip1mdA_gaincode_rev5 = 0x2084; - u16 clip1mdA_gaincode_rev6 = 0x2084; - u16 clip1md_gaincode = 0; - u16 clip1loG_gaincode = 0x0074; - u16 clip1loG_gaincode_rev5[] = { - 0x0062, 0x0064, 0x006a, 0x106a, 0x106c, 0x1074, 0x107c, 0x207c - }; - u16 clip1loG_gaincode_rev6[] = { - 0x106a, 0x106c, 0x1074, 0x107c, 0x007e, 0x107e, 0x207e, 0x307e - }; - u16 clip1loG_gaincode_rev6_224B0 = 0x1074; - u16 clip1loA_gaincode = 0x00cc; - u16 clip1loA_gaincode_rev4 = 0x0086; - u16 clip1loA_gaincode_rev5 = 0x2086; - u16 clip1loA_gaincode_rev6 = 0x2086; - u16 clip1lo_gaincode; - u8 crsminG_th = 0x18; - u8 crsminG_th_rev5 = 0x18; - u8 crsminG_th_rev6 = 0x18; - u8 crsminA_th = 0x1e; - u8 crsminA_th_rev4 = 0x24; - u8 crsminA_th_rev5 = 0x24; - u8 crsminA_th_rev6 = 0x24; - u8 crsmin_th; - u8 crsminlG_th = 0x18; - u8 crsminlG_th_rev5 = 0x18; - u8 crsminlG_th_rev6 = 0x18; - u8 crsminlA_th = 0x1e; - u8 crsminlA_th_rev4 = 0x24; - u8 crsminlA_th_rev5 = 0x24; - u8 crsminlA_th_rev6 = 0x24; - u8 crsminl_th = 0; - u8 crsminuG_th = 0x18; - u8 crsminuG_th_rev5 = 0x18; - u8 crsminuG_th_rev6 = 0x18; - u8 crsminuA_th = 0x1e; - u8 crsminuA_th_rev4 = 0x24; - u8 crsminuA_th_rev5 = 0x24; - u8 crsminuA_th_rev6 = 0x24; - u8 crsminuA_th_rev6_224B0 = 0x2d; - u8 crsminu_th; - u16 nbclipG_th = 0x20d; - u16 nbclipG_th_rev4 = 0x1a1; - u16 nbclipG_th_rev5 = 0x1d0; - u16 nbclipG_th_rev6 = 0x1d0; - u16 nbclipA_th = 0x1a1; - u16 nbclipA_th_rev4 = 0x107; - u16 nbclipA_th_rev5 = 0x0a9; - u16 nbclipA_th_rev6 = 0x0f0; - u16 nbclip_th = 0; - u8 w1clipG_th = 5; - u8 w1clipG_th_rev5 = 9; - u8 w1clipG_th_rev6 = 5; - u8 w1clipA_th = 25, w1clip_th; - u8 rssi_gain_default = 0x50; - u8 rssiG_gain_rev6_224B0 = 0x50; - u8 rssiA_gain_rev5 = 0x90; - u8 rssiA_gain_rev6 = 0x90; - u8 rssi_gain; - u16 regval[21]; - u8 triso; + int j, type = 2; + u16 addr_offset = 0x2c5; - triso = (CHSPEC_IS5G(pi->radio_chanspec)) ? pi->srom_fem5g.triso : - pi->srom_fem2g.triso; + for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) + write_phy_reg(pi, addr_offset + j, + NPHY_IPA_REV4_txdigi_filtcoeffs[type][j]); +} + +static void wlc_phy_clip_det_nphy(struct brcms_phy *pi, u8 write, u16 *vals) +{ + + if (write == 0) { + vals[0] = read_phy_reg(pi, 0x2c); + vals[1] = read_phy_reg(pi, 0x42); + } else { + write_phy_reg(pi, 0x2c, vals[0]); + write_phy_reg(pi, 0x42, vals[1]); + } +} + +static void wlc_phy_ipa_internal_tssi_setup_nphy(struct brcms_phy *pi) +{ + u8 core; if (NREV_GE(pi->pubpi.phy_rev, 7)) { - if (pi->pubpi.radiorev == 5) { + for (core = 0; core < pi->pubpi.phy_corenum; core++) { + if (CHSPEC_IS2G(pi->radio_chanspec)) { + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TX_SSI_MASTER, 0x5); + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TX_SSI_MUX, 0xe); - wlc_phy_workarounds_nphy_gainctrl_2057_rev5(pi); - } else if (pi->pubpi.radiorev == 7) { - wlc_phy_workarounds_nphy_gainctrl_2057_rev6(pi); + if (pi->pubpi.radiorev != 5) + WRITE_RADIO_REG3(pi, RADIO_2057, TX, + core, TSSIA, 0); - mod_phy_reg(pi, 0x283, (0xff << 0), (0x44 << 0)); - mod_phy_reg(pi, 0x280, (0xff << 0), (0x44 << 0)); + if (!NREV_IS(pi->pubpi.phy_rev, 7)) + WRITE_RADIO_REG3(pi, RADIO_2057, TX, + core, TSSIG, 0x1); + else + WRITE_RADIO_REG3(pi, RADIO_2057, TX, + core, TSSIG, 0x31); + } else { + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TX_SSI_MASTER, 0x9); + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TX_SSI_MUX, 0xc); + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TSSIG, 0); - } else if ((pi->pubpi.radiorev == 3) - || (pi->pubpi.radiorev == 8)) { - wlc_phy_workarounds_nphy_gainctrl_2057_rev6(pi); + if (pi->pubpi.radiorev != 5) { + if (!NREV_IS(pi->pubpi.phy_rev, 7)) + WRITE_RADIO_REG3(pi, RADIO_2057, + TX, core, + TSSIA, 0x1); + else + WRITE_RADIO_REG3(pi, RADIO_2057, + TX, core, + TSSIA, 0x31); + } + } + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_VCM_HG, + 0); + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_IDAC, + 0); + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_VCM, + 0x3); + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_MISC1, + 0x0); + } + } else { + WRITE_RADIO_SYN(pi, RADIO_2056, RESERVED_ADDR31, + (CHSPEC_IS2G(pi->radio_chanspec)) ? 0x128 : + 0x80); + WRITE_RADIO_SYN(pi, RADIO_2056, RESERVED_ADDR30, 0x0); + WRITE_RADIO_SYN(pi, RADIO_2056, GPIO_MASTER1, 0x29); - if (pi->pubpi.radiorev == 8) { - mod_phy_reg(pi, 0x283, - (0xff << 0), (0x44 << 0)); - mod_phy_reg(pi, 0x280, - (0xff << 0), (0x44 << 0)); + for (core = 0; core < pi->pubpi.phy_corenum; core++) { + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, IQCAL_VCM_HG, + 0x0); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, IQCAL_IDAC, + 0x0); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_VCM, + 0x3); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TX_AMP_DET, + 0x0); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_MISC1, + 0x8); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_MISC2, + 0x0); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_MISC3, + 0x0); + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + TX_SSI_MASTER, 0x5); + + if (pi->pubpi.radiorev != 5) + WRITE_RADIO_REG2(pi, RADIO_2056, TX, + core, TSSIA, 0x0); + if (NREV_GE(pi->pubpi.phy_rev, 5)) + WRITE_RADIO_REG2(pi, RADIO_2056, TX, + core, TSSIG, 0x31); + else + WRITE_RADIO_REG2(pi, RADIO_2056, TX, + core, TSSIG, 0x11); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + TX_SSI_MUX, 0xe); + } else { + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + TX_SSI_MASTER, 0x9); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + TSSIA, 0x31); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + TSSIG, 0x0); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + TX_SSI_MUX, 0xc); } - } else { - wlc_phy_workarounds_nphy_gainctrl_2057_rev6(pi); } - } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { + } +} - mod_phy_reg(pi, 0xa0, (0x1 << 6), (1 << 6)); +static void +wlc_phy_rfctrl_override_nphy(struct brcms_phy *pi, u16 field, u16 value, + u8 core_mask, u8 off) +{ + u8 core_num; + u16 addr = 0, mask = 0, en_addr = 0, val_addr = 0, en_mask = + 0, val_mask = 0; + u8 shift = 0, val_shift = 0; - mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13)); - mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13)); + if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) { - currband = - read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand; - if (currband == 0) { - if (NREV_GE(pi->pubpi.phy_rev, 6)) { - if (pi->pubpi.radiorev == 11) { - lna1_gain_db = lna1G_gain_db_rev6_224B0; - lna2_gain_db = lna2G_gain_db_rev6_224B0; - rfseq_init_gain = - rfseqG_init_gain_rev6_224B0; - init_gaincode = - initG_gaincode_rev6_224B0; - clip1hi_gaincode = - clip1hiG_gaincode_rev6; - clip1lo_gaincode = - clip1loG_gaincode_rev6_224B0; - nbclip_th = nbclipG_th_rev6; - w1clip_th = w1clipG_th_rev6; - crsmin_th = crsminG_th_rev6; - crsminl_th = crsminlG_th_rev6; - crsminu_th = crsminuG_th_rev6; - rssi_gain = rssiG_gain_rev6_224B0; - } else { - lna1_gain_db = lna1G_gain_db_rev6; - lna2_gain_db = lna2G_gain_db_rev6; - if (pi->sh->boardflags & BFL_EXTLNA) { + en_mask = field; + for (core_num = 0; core_num < 2; core_num++) { - rfseq_init_gain = - rfseqG_init_gain_rev6_elna; - init_gaincode = - initG_gaincode_rev6_elna; - } else { - rfseq_init_gain = - rfseqG_init_gain_rev6; - init_gaincode = - initG_gaincode_rev6; - } - clip1hi_gaincode = - clip1hiG_gaincode_rev6; - switch (triso) { - case 0: - clip1lo_gaincode = - clip1loG_gaincode_rev6[0]; - break; - case 1: - clip1lo_gaincode = - clip1loG_gaincode_rev6[1]; - break; - case 2: - clip1lo_gaincode = - clip1loG_gaincode_rev6[2]; - break; - case 3: - default: + switch (field) { + case (0x1 << 1): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x7a : 0x7d; + val_mask = (0x1 << 0); + val_shift = 0; + break; + case (0x1 << 2): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x7a : 0x7d; + val_mask = (0x1 << 1); + val_shift = 1; + break; + case (0x1 << 3): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x7a : 0x7d; + val_mask = (0x1 << 2); + val_shift = 2; + break; + case (0x1 << 4): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x7a : 0x7d; + val_mask = (0x1 << 4); + val_shift = 4; + break; + case (0x1 << 5): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x7a : 0x7d; + val_mask = (0x1 << 5); + val_shift = 5; + break; + case (0x1 << 6): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x7a : 0x7d; + val_mask = (0x1 << 6); + val_shift = 6; + break; + case (0x1 << 7): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x7a : 0x7d; + val_mask = (0x1 << 7); + val_shift = 7; + break; + case (0x1 << 8): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x7a : 0x7d; + val_mask = (0x7 << 8); + val_shift = 8; + break; + case (0x1 << 11): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x7a : 0x7d; + val_mask = (0x7 << 13); + val_shift = 13; + break; - clip1lo_gaincode = - clip1loG_gaincode_rev6[3]; - break; - case 4: - clip1lo_gaincode = - clip1loG_gaincode_rev6[4]; - break; - case 5: - clip1lo_gaincode = - clip1loG_gaincode_rev6[5]; - break; - case 6: - clip1lo_gaincode = - clip1loG_gaincode_rev6[6]; - break; - case 7: - clip1lo_gaincode = - clip1loG_gaincode_rev6[7]; - break; - } - nbclip_th = nbclipG_th_rev6; - w1clip_th = w1clipG_th_rev6; - crsmin_th = crsminG_th_rev6; - crsminl_th = crsminlG_th_rev6; - crsminu_th = crsminuG_th_rev6; - rssi_gain = rssi_gain_default; - } - } else if (NREV_IS(pi->pubpi.phy_rev, 5)) { - lna1_gain_db = lna1G_gain_db_rev5; - lna2_gain_db = lna2G_gain_db_rev5; - if (pi->sh->boardflags & BFL_EXTLNA) { + case (0x1 << 9): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0xf8 : 0xfa; + val_mask = (0x7 << 0); + val_shift = 0; + break; - rfseq_init_gain = - rfseqG_init_gain_rev5_elna; - init_gaincode = - initG_gaincode_rev5_elna; - } else { - rfseq_init_gain = rfseqG_init_gain_rev5; - init_gaincode = initG_gaincode_rev5; - } - clip1hi_gaincode = clip1hiG_gaincode_rev5; - switch (triso) { - case 0: - clip1lo_gaincode = - clip1loG_gaincode_rev5[0]; - break; - case 1: - clip1lo_gaincode = - clip1loG_gaincode_rev5[1]; - break; - case 2: - clip1lo_gaincode = - clip1loG_gaincode_rev5[2]; - break; - case 3: + case (0x1 << 10): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0xf8 : 0xfa; + val_mask = (0x7 << 4); + val_shift = 4; + break; - clip1lo_gaincode = - clip1loG_gaincode_rev5[3]; - break; - case 4: - clip1lo_gaincode = - clip1loG_gaincode_rev5[4]; - break; - case 5: - clip1lo_gaincode = - clip1loG_gaincode_rev5[5]; - break; - case 6: - clip1lo_gaincode = - clip1loG_gaincode_rev5[6]; - break; - case 7: - clip1lo_gaincode = - clip1loG_gaincode_rev5[7]; - break; - default: - clip1lo_gaincode = - clip1loG_gaincode_rev5[3]; - break; - } - nbclip_th = nbclipG_th_rev5; - w1clip_th = w1clipG_th_rev5; - crsmin_th = crsminG_th_rev5; - crsminl_th = crsminlG_th_rev5; - crsminu_th = crsminuG_th_rev5; - rssi_gain = rssi_gain_default; - } else if (NREV_IS(pi->pubpi.phy_rev, 4)) { - lna1_gain_db = lna1G_gain_db_rev4; - lna2_gain_db = lna2G_gain_db; - rfseq_init_gain = rfseqG_init_gain_rev4; - init_gaincode = initG_gaincode_rev4; - clip1hi_gaincode = clip1hiG_gaincode_rev4; - clip1lo_gaincode = clip1loG_gaincode; - nbclip_th = nbclipG_th_rev4; - w1clip_th = w1clipG_th; - crsmin_th = crsminG_th; - crsminl_th = crsminlG_th; - crsminu_th = crsminuG_th; - rssi_gain = rssi_gain_default; - } else { - lna1_gain_db = lna1G_gain_db; - lna2_gain_db = lna2G_gain_db; - rfseq_init_gain = rfseqG_init_gain; - init_gaincode = initG_gaincode; - clip1hi_gaincode = clip1hiG_gaincode; - clip1lo_gaincode = clip1loG_gaincode; - nbclip_th = nbclipG_th; - w1clip_th = w1clipG_th; - crsmin_th = crsminG_th; - crsminl_th = crsminlG_th; - crsminu_th = crsminuG_th; - rssi_gain = rssi_gain_default; + case (0x1 << 12): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x7b : 0x7e; + val_mask = (0xffff << 0); + val_shift = 0; + break; + case (0x1 << 13): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0x7c : 0x7f; + val_mask = (0xffff << 0); + val_shift = 0; + break; + case (0x1 << 14): + en_addr = (core_num == 0) ? 0xe7 : 0xec; + val_addr = (core_num == 0) ? 0xf9 : 0xfb; + val_mask = (0x3 << 6); + val_shift = 6; + break; + case (0x1 << 0): + en_addr = (core_num == 0) ? 0xe5 : 0xe6; + val_addr = (core_num == 0) ? 0xf9 : 0xfb; + val_mask = (0x1 << 15); + val_shift = 15; + break; + default: + addr = 0xffff; + break; } - tia_gain_db = tiaG_gain_db; - tia_gainbits = tiaG_gainbits; - clip1md_gaincode = clip1mdG_gaincode; - } else { - if (NREV_GE(pi->pubpi.phy_rev, 6)) { - lna1_gain_db = lna1A_gain_db_rev6; - lna2_gain_db = lna2A_gain_db_rev6; - tia_gain_db = tiaA_gain_db_rev6; - tia_gainbits = tiaA_gainbits_rev6; - rfseq_init_gain = rfseqA_init_gain_rev6; - init_gaincode = initA_gaincode_rev6; - clip1hi_gaincode = clip1hiA_gaincode_rev6; - clip1md_gaincode = clip1mdA_gaincode_rev6; - clip1lo_gaincode = clip1loA_gaincode_rev6; - crsmin_th = crsminA_th_rev6; - crsminl_th = crsminlA_th_rev6; - if ((pi->pubpi.radiorev == 11) && - (CHSPEC_IS40(pi->radio_chanspec) == 0)) { - crsminu_th = crsminuA_th_rev6_224B0; - } else { - crsminu_th = crsminuA_th_rev6; - } - nbclip_th = nbclipA_th_rev6; - rssi_gain = rssiA_gain_rev6; - } else if (NREV_IS(pi->pubpi.phy_rev, 5)) { - lna1_gain_db = lna1A_gain_db_rev5; - lna2_gain_db = lna2A_gain_db_rev5; - tia_gain_db = tiaA_gain_db_rev5; - tia_gainbits = tiaA_gainbits_rev5; - rfseq_init_gain = rfseqA_init_gain_rev5; - init_gaincode = initA_gaincode_rev5; - clip1hi_gaincode = clip1hiA_gaincode_rev5; - clip1md_gaincode = clip1mdA_gaincode_rev5; - clip1lo_gaincode = clip1loA_gaincode_rev5; - crsmin_th = crsminA_th_rev5; - crsminl_th = crsminlA_th_rev5; - crsminu_th = crsminuA_th_rev5; - nbclip_th = nbclipA_th_rev5; - rssi_gain = rssiA_gain_rev5; - } else if (NREV_IS(pi->pubpi.phy_rev, 4)) { - lna1_gain_db = lna1A_gain_db_rev4; - lna2_gain_db = lna2A_gain_db_rev4; - tia_gain_db = tiaA_gain_db_rev4; - tia_gainbits = tiaA_gainbits_rev4; - if (pi->sh->boardflags & BFL_EXTLNA_5GHz) { - rfseq_init_gain = - rfseqA_init_gain_rev4_elna; - init_gaincode = - initA_gaincode_rev4_elna; - } else { - rfseq_init_gain = rfseqA_init_gain_rev4; - init_gaincode = initA_gaincode_rev4; - } - clip1hi_gaincode = clip1hiA_gaincode_rev4; - clip1md_gaincode = clip1mdA_gaincode_rev4; - clip1lo_gaincode = clip1loA_gaincode_rev4; - crsmin_th = crsminA_th_rev4; - crsminl_th = crsminlA_th_rev4; - crsminu_th = crsminuA_th_rev4; - nbclip_th = nbclipA_th_rev4; - rssi_gain = rssi_gain_default; + if (off) { + and_phy_reg(pi, en_addr, ~en_mask); + and_phy_reg(pi, val_addr, ~val_mask); } else { - lna1_gain_db = lna1A_gain_db; - lna2_gain_db = lna2A_gain_db; - tia_gain_db = tiaA_gain_db; - tia_gainbits = tiaA_gainbits; - rfseq_init_gain = rfseqA_init_gain; - init_gaincode = initA_gaincode; - clip1hi_gaincode = clip1hiA_gaincode; - clip1md_gaincode = clip1mdA_gaincode; - clip1lo_gaincode = clip1loA_gaincode; - crsmin_th = crsminA_th; - crsminl_th = crsminlA_th; - crsminu_th = crsminuA_th; - nbclip_th = nbclipA_th; - rssi_gain = rssi_gain_default; + + if ((core_mask == 0) + || (core_mask & (1 << core_num))) { + or_phy_reg(pi, en_addr, en_mask); + + if (addr != 0xffff) + mod_phy_reg(pi, val_addr, + val_mask, + (value << + val_shift)); + } } - w1clip_th = w1clipA_th; } + } else { - write_radio_reg(pi, - (RADIO_2056_RX_BIASPOLE_LNAG1_IDAC | - RADIO_2056_RX0), 0x17); - write_radio_reg(pi, - (RADIO_2056_RX_BIASPOLE_LNAG1_IDAC | - RADIO_2056_RX1), 0x17); + if (off) { + and_phy_reg(pi, 0xec, ~field); + value = 0x0; + } else { + or_phy_reg(pi, 0xec, field); + } - write_radio_reg(pi, (RADIO_2056_RX_LNAG2_IDAC | RADIO_2056_RX0), - 0xf0); - write_radio_reg(pi, (RADIO_2056_RX_LNAG2_IDAC | RADIO_2056_RX1), - 0xf0); + for (core_num = 0; core_num < 2; core_num++) { - write_radio_reg(pi, (RADIO_2056_RX_RSSI_POLE | RADIO_2056_RX0), - 0x0); - write_radio_reg(pi, (RADIO_2056_RX_RSSI_POLE | RADIO_2056_RX1), - 0x0); + switch (field) { + case (0x1 << 1): + case (0x1 << 9): + case (0x1 << 12): + case (0x1 << 13): + case (0x1 << 14): + addr = 0x78; - write_radio_reg(pi, (RADIO_2056_RX_RSSI_GAIN | RADIO_2056_RX0), - rssi_gain); - write_radio_reg(pi, (RADIO_2056_RX_RSSI_GAIN | RADIO_2056_RX1), - rssi_gain); + core_mask = 0x1; + break; + case (0x1 << 2): + case (0x1 << 3): + case (0x1 << 4): + case (0x1 << 5): + case (0x1 << 6): + case (0x1 << 7): + case (0x1 << 8): + addr = (core_num == 0) ? 0x7a : 0x7d; + break; + case (0x1 << 10): + addr = (core_num == 0) ? 0x7b : 0x7e; + break; + case (0x1 << 11): + addr = (core_num == 0) ? 0x7c : 0x7f; + break; + default: + addr = 0xffff; + } - write_radio_reg(pi, - (RADIO_2056_RX_BIASPOLE_LNAA1_IDAC | - RADIO_2056_RX0), 0x17); - write_radio_reg(pi, - (RADIO_2056_RX_BIASPOLE_LNAA1_IDAC | - RADIO_2056_RX1), 0x17); + switch (field) { + case (0x1 << 1): + mask = (0x7 << 3); + shift = 3; + break; + case (0x1 << 9): + mask = (0x1 << 2); + shift = 2; + break; + case (0x1 << 12): + mask = (0x1 << 8); + shift = 8; + break; + case (0x1 << 13): + mask = (0x1 << 9); + shift = 9; + break; + case (0x1 << 14): + mask = (0xf << 12); + shift = 12; + break; + case (0x1 << 2): + mask = (0x1 << 0); + shift = 0; + break; + case (0x1 << 3): + mask = (0x1 << 1); + shift = 1; + break; + case (0x1 << 4): + mask = (0x1 << 2); + shift = 2; + break; + case (0x1 << 5): + mask = (0x3 << 4); + shift = 4; + break; + case (0x1 << 6): + mask = (0x3 << 6); + shift = 6; + break; + case (0x1 << 7): + mask = (0x1 << 8); + shift = 8; + break; + case (0x1 << 8): + mask = (0x1 << 9); + shift = 9; + break; + case (0x1 << 10): + mask = 0x1fff; + shift = 0x0; + break; + case (0x1 << 11): + mask = 0x1fff; + shift = 0x0; + break; + default: + mask = 0x0; + shift = 0x0; + break; + } - write_radio_reg(pi, (RADIO_2056_RX_LNAA2_IDAC | RADIO_2056_RX0), - 0xFF); - write_radio_reg(pi, (RADIO_2056_RX_LNAA2_IDAC | RADIO_2056_RX1), - 0xFF); + if ((addr != 0xffff) && (core_mask & (1 << core_num))) + mod_phy_reg(pi, addr, mask, (value << shift)); + } - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 8, - 8, lna1_gain_db); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 8, - 8, lna1_gain_db); + or_phy_reg(pi, 0xec, (0x1 << 0)); + or_phy_reg(pi, 0x78, (0x1 << 0)); + udelay(1); + and_phy_reg(pi, 0xec, ~(0x1 << 0)); + } +} - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x10, - 8, lna2_gain_db); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x10, - 8, lna2_gain_db); +static void wlc_phy_txpwrctrl_idle_tssi_nphy(struct brcms_phy *pi) +{ + s32 rssi_buf[4]; + s32 int_val; - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 10, 0x20, - 8, tia_gain_db); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 10, 0x20, - 8, tia_gain_db); + if (SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi) || PHY_MUTED(pi)) - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 10, 0x20, - 8, tia_gainbits); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 10, 0x20, - 8, tia_gainbits); + return; - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 6, 0x40, - 8, &lpf_gain_db); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 6, 0x40, - 8, &lpf_gain_db); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 6, 0x40, - 8, &lpf_gainbits); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 6, 0x40, - 8, &lpf_gainbits); + if (PHY_IPA(pi)) + wlc_phy_ipa_internal_tssi_setup_nphy(pi); - write_phy_reg(pi, 0x20, init_gaincode); - write_phy_reg(pi, 0x2a7, init_gaincode); + if (NREV_GE(pi->pubpi.phy_rev, 7)) + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12), + 0, 0x3, 0, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + else if (NREV_GE(pi->pubpi.phy_rev, 3)) + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 13), 0, 3, 0); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, - pi->pubpi.phy_corenum, 0x106, 16, - rfseq_init_gain); + wlc_phy_stopplayback_nphy(pi); - write_phy_reg(pi, 0x22, clip1hi_gaincode); - write_phy_reg(pi, 0x2a9, clip1hi_gaincode); + wlc_phy_tx_tone_nphy(pi, 4000, 0, 0, 0, false); - write_phy_reg(pi, 0x24, clip1md_gaincode); - write_phy_reg(pi, 0x2ab, clip1md_gaincode); + udelay(20); + int_val = + wlc_phy_poll_rssi_nphy(pi, (u8) NPHY_RSSI_SEL_TSSI_2G, rssi_buf, + 1); + wlc_phy_stopplayback_nphy(pi); + wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_OFF, 0); - write_phy_reg(pi, 0x37, clip1lo_gaincode); - write_phy_reg(pi, 0x2ad, clip1lo_gaincode); + if (NREV_GE(pi->pubpi.phy_rev, 7)) + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12), + 0, 0x3, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + else if (NREV_GE(pi->pubpi.phy_rev, 3)) + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 13), 0, 3, 1); - mod_phy_reg(pi, 0x27d, (0xff << 0), (crsmin_th << 0)); - mod_phy_reg(pi, 0x280, (0xff << 0), (crsminl_th << 0)); - mod_phy_reg(pi, 0x283, (0xff << 0), (crsminu_th << 0)); + if (NREV_GE(pi->pubpi.phy_rev, 3)) { - write_phy_reg(pi, 0x2b, nbclip_th); - write_phy_reg(pi, 0x41, nbclip_th); + pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_2g = + (u8) ((int_val >> 24) & 0xff); + pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_5g = + (u8) ((int_val >> 24) & 0xff); - mod_phy_reg(pi, 0x27, (0x3f << 0), (w1clip_th << 0)); - mod_phy_reg(pi, 0x3d, (0x3f << 0), (w1clip_th << 0)); + pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_2g = + (u8) ((int_val >> 8) & 0xff); + pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_5g = + (u8) ((int_val >> 8) & 0xff); + } else { + pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_2g = + (u8) ((int_val >> 24) & 0xff); - write_phy_reg(pi, 0x150, 0x809c); + pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_2g = + (u8) ((int_val >> 8) & 0xff); - } else { + pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_5g = + (u8) ((int_val >> 16) & 0xff); + pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_5g = + (u8) ((int_val) & 0xff); + } - mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13)); - mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13)); +} - write_phy_reg(pi, 0x2b, 0x84); - write_phy_reg(pi, 0x41, 0x84); +static void wlc_phy_txpwr_limit_to_tbl_nphy(struct brcms_phy *pi) +{ + u8 idx, idx2, i, delta_ind; - if (CHSPEC_IS20(pi->radio_chanspec)) { - write_phy_reg(pi, 0x6b, 0x2b); - write_phy_reg(pi, 0x6c, 0x2b); - write_phy_reg(pi, 0x6d, 0x9); - write_phy_reg(pi, 0x6e, 0x9); - } + for (idx = TXP_FIRST_CCK; idx <= TXP_LAST_CCK; idx++) + pi->adj_pwr_tbl_nphy[idx] = pi->tx_power_offset[idx]; - w1th = NPHY_RSSICAL_W1_TARGET - 4; - mod_phy_reg(pi, 0x27, (0x3f << 0), (w1th << 0)); - mod_phy_reg(pi, 0x3d, (0x3f << 0), (w1th << 0)); + for (i = 0; i < 4; i++) { + idx2 = 0; - if (CHSPEC_IS20(pi->radio_chanspec)) { - mod_phy_reg(pi, 0x1c, (0x1f << 0), (0x1 << 0)); - mod_phy_reg(pi, 0x32, (0x1f << 0), (0x1 << 0)); + delta_ind = 0; - mod_phy_reg(pi, 0x1d, (0x1f << 0), (0x1 << 0)); - mod_phy_reg(pi, 0x33, (0x1f << 0), (0x1 << 0)); - } + switch (i) { + case 0: - write_phy_reg(pi, 0x150, 0x809c); + if (CHSPEC_IS40(pi->radio_chanspec) + && NPHY_IS_SROM_REINTERPRET) { + idx = TXP_FIRST_MCS_40_SISO; + } else { + idx = (CHSPEC_IS40(pi->radio_chanspec)) ? + TXP_FIRST_OFDM_40_SISO : TXP_FIRST_OFDM; + delta_ind = 1; + } + break; - if (pi->nphy_gain_boost) - if ((CHSPEC_IS2G(pi->radio_chanspec)) && - (CHSPEC_IS40(pi->radio_chanspec))) - hpf_code = 4; - else - hpf_code = 5; - else if (CHSPEC_IS40(pi->radio_chanspec)) - hpf_code = 6; - else - hpf_code = 7; + case 1: - mod_phy_reg(pi, 0x20, (0x1f << 7), (hpf_code << 7)); - mod_phy_reg(pi, 0x36, (0x1f << 7), (hpf_code << 7)); + idx = (CHSPEC_IS40(pi->radio_chanspec)) ? + TXP_FIRST_MCS_40_CDD : TXP_FIRST_MCS_20_CDD; + break; - for (ctr = 0; ctr < 4; ctr++) { - regval[ctr] = (hpf_code << 8) | 0x7c; - } - wlc_phy_table_write_nphy(pi, 7, 4, 0x106, 16, regval); + case 2: - wlc_phy_adjust_lnagaintbl_nphy(pi); + idx = (CHSPEC_IS40(pi->radio_chanspec)) ? + TXP_FIRST_MCS_40_STBC : TXP_FIRST_MCS_20_STBC; + break; - if (pi->nphy_elna_gain_config) { - regval[0] = 0; - regval[1] = 1; - regval[2] = 1; - regval[3] = 1; - wlc_phy_table_write_nphy(pi, 2, 4, 8, 16, regval); - wlc_phy_table_write_nphy(pi, 3, 4, 8, 16, regval); + case 3: - for (ctr = 0; ctr < 4; ctr++) { - regval[ctr] = (hpf_code << 8) | 0x74; - } - wlc_phy_table_write_nphy(pi, 7, 4, 0x106, 16, regval); + idx = (CHSPEC_IS40(pi->radio_chanspec)) ? + TXP_FIRST_MCS_40_SDM : TXP_FIRST_MCS_20_SDM; + break; } - if (NREV_IS(pi->pubpi.phy_rev, 2)) { - for (ctr = 0; ctr < 21; ctr++) { - regval[ctr] = 3 * ctr; - } - wlc_phy_table_write_nphy(pi, 0, 21, 32, 16, regval); - wlc_phy_table_write_nphy(pi, 1, 21, 32, 16, regval); + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx]; + idx = idx + delta_ind; + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx]; + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx]; + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx++]; - for (ctr = 0; ctr < 21; ctr++) { - regval[ctr] = (u16) ctr; - } - wlc_phy_table_write_nphy(pi, 2, 21, 32, 16, regval); - wlc_phy_table_write_nphy(pi, 3, 21, 32, 16, regval); - } + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx++]; + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx]; + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx]; + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx++]; - wlc_phy_set_rfseq_nphy(pi, NPHY_RFSEQ_UPDATEGAINU, - rfseq_updategainu_events, - rfseq_updategainu_dlys, - sizeof(rfseq_updategainu_events) / - sizeof(rfseq_updategainu_events[0])); + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx++]; + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx]; + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx]; + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx++]; - mod_phy_reg(pi, 0x153, (0xff << 8), (90 << 8)); + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx]; + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx++]; + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx]; + idx = idx + 1 - delta_ind; + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx]; - if (CHSPEC_IS2G(pi->radio_chanspec)) - mod_phy_reg(pi, - (NPHY_TO_BPHY_OFF + BPHY_OPTIONAL_MODES), - 0x7f, 0x4); + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx]; + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx]; + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx]; + pi->adj_pwr_tbl_nphy[4 + 4 * (idx2++) + i] = + pi->tx_power_offset[idx]; } } -static void wlc_phy_workarounds_nphy_gainctrl_2057_rev5(struct brcms_phy *pi) +static void wlc_phy_txpwrctrl_pwr_setup_nphy(struct brcms_phy *pi) { - s8 lna1_gain_db[] = { 8, 13, 17, 22 }; - s8 lna2_gain_db[] = { -2, 7, 11, 15 }; - s8 tia_gain_db[] = { -4, -1, 2, 5, 5, 5, 5, 5, 5, 5 }; - s8 tia_gainbits[] = { - 0x0, 0x01, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 }; + u32 idx; + s16 a1[2], b0[2], b1[2]; + s8 target_pwr_qtrdbm[2]; + s32 num, den, pwr_est; + u8 chan_freq_range; + u8 idle_tssi[2]; + u32 tbl_id, tbl_len, tbl_offset; + u32 regval[64]; + u8 core; - mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13)); - mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13)); + if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) { + wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK); + (void)R_REG(&pi->regs->maccontrol); + udelay(1); + } - mod_phy_reg(pi, 0x289, (0xff << 0), (0x46 << 0)); + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, true); - mod_phy_reg(pi, 0x283, (0xff << 0), (0x3c << 0)); - mod_phy_reg(pi, 0x280, (0xff << 0), (0x3c << 0)); + or_phy_reg(pi, 0x122, (0x1 << 0)); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x8, 8, - lna1_gain_db); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x8, 8, - lna1_gain_db); + if (NREV_GE(pi->pubpi.phy_rev, 3)) + and_phy_reg(pi, 0x1e7, (u16) (~(0x1 << 15))); + else + or_phy_reg(pi, 0x1e7, (0x1 << 15)); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x10, 8, - lna2_gain_db); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x10, 8, - lna2_gain_db); + if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) + wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, 0); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 10, 0x20, 8, - tia_gain_db); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 10, 0x20, 8, - tia_gain_db); + if (pi->sh->sromrev < 4) { + idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g; + idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g; + target_pwr_qtrdbm[0] = 13 * 4; + target_pwr_qtrdbm[1] = 13 * 4; + a1[0] = -424; + a1[1] = -424; + b0[0] = 5612; + b0[1] = 5612; + b1[1] = -1393; + b1[0] = -1393; + } else { - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 10, 0x20, 8, - tia_gainbits); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 10, 0x20, 8, - tia_gainbits); + chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, 0); + switch (chan_freq_range) { + case WL_CHAN_FREQ_RANGE_2G: + idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g; + idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g; + target_pwr_qtrdbm[0] = + pi->nphy_pwrctrl_info[0].max_pwr_2g; + target_pwr_qtrdbm[1] = + pi->nphy_pwrctrl_info[1].max_pwr_2g; + a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_a1; + a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_a1; + b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_b0; + b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_b0; + b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_b1; + b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_b1; + break; + case WL_CHAN_FREQ_RANGE_5GL: + idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g; + idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g; + target_pwr_qtrdbm[0] = + pi->nphy_pwrctrl_info[0].max_pwr_5gl; + target_pwr_qtrdbm[1] = + pi->nphy_pwrctrl_info[1].max_pwr_5gl; + a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_a1; + a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_a1; + b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_b0; + b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_b0; + b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_b1; + b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_b1; + break; + case WL_CHAN_FREQ_RANGE_5GM: + idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g; + idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g; + target_pwr_qtrdbm[0] = + pi->nphy_pwrctrl_info[0].max_pwr_5gm; + target_pwr_qtrdbm[1] = + pi->nphy_pwrctrl_info[1].max_pwr_5gm; + a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_a1; + a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_a1; + b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_b0; + b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_b0; + b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_b1; + b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_b1; + break; + case WL_CHAN_FREQ_RANGE_5GH: + idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g; + idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g; + target_pwr_qtrdbm[0] = + pi->nphy_pwrctrl_info[0].max_pwr_5gh; + target_pwr_qtrdbm[1] = + pi->nphy_pwrctrl_info[1].max_pwr_5gh; + a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_a1; + a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_a1; + b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_b0; + b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_b0; + b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_b1; + b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_b1; + break; + default: + idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g; + idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g; + target_pwr_qtrdbm[0] = 13 * 4; + target_pwr_qtrdbm[1] = 13 * 4; + a1[0] = -424; + a1[1] = -424; + b0[0] = 5612; + b0[1] = 5612; + b1[1] = -1393; + b1[0] = -1393; + break; + } + } - write_phy_reg(pi, 0x37, 0x74); - write_phy_reg(pi, 0x2ad, 0x74); - write_phy_reg(pi, 0x38, 0x18); - write_phy_reg(pi, 0x2ae, 0x18); + target_pwr_qtrdbm[0] = (s8) pi->tx_power_max; + target_pwr_qtrdbm[1] = (s8) pi->tx_power_max; - write_phy_reg(pi, 0x2b, 0xe8); - write_phy_reg(pi, 0x41, 0xe8); + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + if (pi->srom_fem2g.tssipos) + or_phy_reg(pi, 0x1e9, (0x1 << 14)); - if (CHSPEC_IS20(pi->radio_chanspec)) { + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + for (core = 0; core <= 1; core++) { + if (PHY_IPA(pi)) { + if (CHSPEC_IS2G(pi->radio_chanspec)) + WRITE_RADIO_REG3(pi, RADIO_2057, + TX, core, + TX_SSI_MUX, + 0xe); + else + WRITE_RADIO_REG3(pi, RADIO_2057, + TX, core, + TX_SSI_MUX, + 0xc); + } + } + } else { + if (PHY_IPA(pi)) { - mod_phy_reg(pi, 0x300, (0x3f << 0), (0x12 << 0)); - mod_phy_reg(pi, 0x301, (0x3f << 0), (0x12 << 0)); - } else { + write_radio_reg(pi, RADIO_2056_TX_TX_SSI_MUX | + RADIO_2056_TX0, + (CHSPEC_IS5G + (pi->radio_chanspec)) ? + 0xc : 0xe); + write_radio_reg(pi, + RADIO_2056_TX_TX_SSI_MUX | + RADIO_2056_TX1, + (CHSPEC_IS5G + (pi->radio_chanspec)) ? + 0xc : 0xe); + } else { - mod_phy_reg(pi, 0x300, (0x3f << 0), (0x10 << 0)); - mod_phy_reg(pi, 0x301, (0x3f << 0), (0x10 << 0)); + write_radio_reg(pi, RADIO_2056_TX_TX_SSI_MUX | + RADIO_2056_TX0, 0x11); + write_radio_reg(pi, RADIO_2056_TX_TX_SSI_MUX | + RADIO_2056_TX1, 0x11); + } + } } -} -static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(struct brcms_phy *pi) -{ - u16 currband; - s8 lna1G_gain_db_rev7[] = { 9, 14, 19, 24 }; - s8 *lna1_gain_db = NULL; - s8 *lna1_gain_db_2 = NULL; - s8 *lna2_gain_db = NULL; - s8 tiaA_gain_db_rev7[] = { -9, -6, -3, 0, 3, 3, 3, 3, 3, 3 }; - s8 *tia_gain_db; - s8 tiaA_gainbits_rev7[] = { 0, 1, 2, 3, 4, 4, 4, 4, 4, 4 }; - s8 *tia_gainbits; - u16 rfseqA_init_gain_rev7[] = { 0x624f, 0x624f }; - u16 *rfseq_init_gain; - u16 init_gaincode; - u16 clip1hi_gaincode; - u16 clip1md_gaincode = 0; - u16 clip1md_gaincode_B; - u16 clip1lo_gaincode; - u16 clip1lo_gaincode_B; - u8 crsminl_th = 0; - u8 crsminu_th; - u16 nbclip_th = 0; - u8 w1clip_th; - u16 freq; - s8 nvar_baseline_offset0 = 0, nvar_baseline_offset1 = 0; - u8 chg_nbclip_th = 0; + if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) { + wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK); + (void)R_REG(&pi->regs->maccontrol); + udelay(1); + } - mod_phy_reg(pi, 0x1c, (0x1 << 13), (1 << 13)); - mod_phy_reg(pi, 0x32, (0x1 << 13), (1 << 13)); + if (NREV_GE(pi->pubpi.phy_rev, 7)) + mod_phy_reg(pi, 0x1e7, (0x7f << 0), + (NPHY_TxPwrCtrlCmd_pwrIndex_init_rev7 << 0)); + else + mod_phy_reg(pi, 0x1e7, (0x7f << 0), + (NPHY_TxPwrCtrlCmd_pwrIndex_init << 0)); - currband = read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand; - if (currband == 0) { + if (NREV_GE(pi->pubpi.phy_rev, 7)) + mod_phy_reg(pi, 0x222, (0xff << 0), + (NPHY_TxPwrCtrlCmd_pwrIndex_init_rev7 << 0)); + else if (NREV_GT(pi->pubpi.phy_rev, 1)) + mod_phy_reg(pi, 0x222, (0xff << 0), + (NPHY_TxPwrCtrlCmd_pwrIndex_init << 0)); - lna1_gain_db = lna1G_gain_db_rev7; + if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) + wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, 0); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 8, 8, - lna1_gain_db); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 8, 8, - lna1_gain_db); + write_phy_reg(pi, 0x1e8, (0x3 << 8) | (240 << 0)); - mod_phy_reg(pi, 0x283, (0xff << 0), (0x40 << 0)); + write_phy_reg(pi, 0x1e9, + (1 << 15) | (idle_tssi[0] << 0) | (idle_tssi[1] << 8)); - if (CHSPEC_IS40(pi->radio_chanspec)) { - mod_phy_reg(pi, 0x280, (0xff << 0), (0x3e << 0)); - mod_phy_reg(pi, 0x283, (0xff << 0), (0x3e << 0)); + write_phy_reg(pi, 0x1ea, + (target_pwr_qtrdbm[0] << 0) | + (target_pwr_qtrdbm[1] << 8)); + + tbl_len = 64; + tbl_offset = 0; + for (tbl_id = NPHY_TBL_ID_CORE1TXPWRCTL; + tbl_id <= NPHY_TBL_ID_CORE2TXPWRCTL; tbl_id++) { + + for (idx = 0; idx < tbl_len; idx++) { + num = 8 * + (16 * b0[tbl_id - 26] + b1[tbl_id - 26] * idx); + den = 32768 + a1[tbl_id - 26] * idx; + pwr_est = max(((4 * num + den / 2) / den), -8); + if (NREV_LT(pi->pubpi.phy_rev, 3)) { + if (idx <= + (uint) (31 - idle_tssi[tbl_id - 26] + 1)) + pwr_est = + max(pwr_est, + target_pwr_qtrdbm + [tbl_id - 26] + 1); + } + regval[idx] = (u32) pwr_est; } + wlc_phy_table_write_nphy(pi, tbl_id, tbl_len, tbl_offset, 32, + regval); + } - mod_phy_reg(pi, 0x289, (0xff << 0), (0x46 << 0)); + wlc_phy_txpwr_limit_to_tbl_nphy(pi); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 84, 64, 8, + pi->adj_pwr_tbl_nphy); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 84, 64, 8, + pi->adj_pwr_tbl_nphy); - if (CHSPEC_IS20(pi->radio_chanspec)) { - mod_phy_reg(pi, 0x300, (0x3f << 0), (13 << 0)); - mod_phy_reg(pi, 0x301, (0x3f << 0), (13 << 0)); + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, false); +} + +static u32 *wlc_phy_get_ipa_gaintbl_nphy(struct brcms_phy *pi) +{ + u32 *tx_pwrctrl_tbl = NULL; + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + if ((pi->pubpi.radiorev == 4) + || (pi->pubpi.radiorev == 6)) + tx_pwrctrl_tbl = + nphy_tpc_txgain_ipa_2g_2057rev4n6; + else if (pi->pubpi.radiorev == 3) + tx_pwrctrl_tbl = + nphy_tpc_txgain_ipa_2g_2057rev3; + else if (pi->pubpi.radiorev == 5) + tx_pwrctrl_tbl = + nphy_tpc_txgain_ipa_2g_2057rev5; + else if ((pi->pubpi.radiorev == 7) + || (pi->pubpi.radiorev == 8)) + tx_pwrctrl_tbl = + nphy_tpc_txgain_ipa_2g_2057rev7; + } else if (NREV_IS(pi->pubpi.phy_rev, 6)) { + tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_rev6; + } else if (NREV_IS(pi->pubpi.phy_rev, 5)) { + tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_rev5; + } else { + tx_pwrctrl_tbl = nphy_tpc_txgain_ipa; } } else { - init_gaincode = 0x9e; - clip1hi_gaincode = 0x9e; - clip1md_gaincode_B = 0x24; - clip1lo_gaincode = 0x8a; - clip1lo_gaincode_B = 8; - rfseq_init_gain = rfseqA_init_gain_rev7; + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + if ((pi->pubpi.radiorev == 3) || + (pi->pubpi.radiorev == 4) || + (pi->pubpi.radiorev == 6)) + tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_5g_2057; + else if ((pi->pubpi.radiorev == 7) + || (pi->pubpi.radiorev == 8)) + tx_pwrctrl_tbl = + nphy_tpc_txgain_ipa_5g_2057rev7; + } else { + tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_5g; + } + } - tia_gain_db = tiaA_gain_db_rev7; - tia_gainbits = tiaA_gainbits_rev7; + return tx_pwrctrl_tbl; +} - freq = CHAN5G_FREQ(CHSPEC_CHANNEL(pi->radio_chanspec)); - if (CHSPEC_IS20(pi->radio_chanspec)) { +static void wlc_phy_restore_rssical_nphy(struct brcms_phy *pi) +{ + if (CHSPEC_IS2G(pi->radio_chanspec)) { + if (pi->nphy_rssical_chanspec_2G == 0) + return; - w1clip_th = 25; - clip1md_gaincode = 0x82; + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0, + RADIO_2057_VCM_MASK, + pi->rssical_cache. + rssical_radio_regs_2G[0]); + mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1, + RADIO_2057_VCM_MASK, + pi->rssical_cache. + rssical_radio_regs_2G[1]); + } else { + mod_radio_reg(pi, + RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX0, + RADIO_2056_VCM_MASK, + pi->rssical_cache. + rssical_radio_regs_2G[0]); + mod_radio_reg(pi, + RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX1, + RADIO_2056_VCM_MASK, + pi->rssical_cache. + rssical_radio_regs_2G[1]); + } - if ((freq <= 5080) || (freq == 5825)) { + write_phy_reg(pi, 0x1a6, + pi->rssical_cache.rssical_phyregs_2G[0]); + write_phy_reg(pi, 0x1ac, + pi->rssical_cache.rssical_phyregs_2G[1]); + write_phy_reg(pi, 0x1b2, + pi->rssical_cache.rssical_phyregs_2G[2]); + write_phy_reg(pi, 0x1b8, + pi->rssical_cache.rssical_phyregs_2G[3]); + write_phy_reg(pi, 0x1a4, + pi->rssical_cache.rssical_phyregs_2G[4]); + write_phy_reg(pi, 0x1aa, + pi->rssical_cache.rssical_phyregs_2G[5]); + write_phy_reg(pi, 0x1b0, + pi->rssical_cache.rssical_phyregs_2G[6]); + write_phy_reg(pi, 0x1b6, + pi->rssical_cache.rssical_phyregs_2G[7]); + write_phy_reg(pi, 0x1a5, + pi->rssical_cache.rssical_phyregs_2G[8]); + write_phy_reg(pi, 0x1ab, + pi->rssical_cache.rssical_phyregs_2G[9]); + write_phy_reg(pi, 0x1b1, + pi->rssical_cache.rssical_phyregs_2G[10]); + write_phy_reg(pi, 0x1b7, + pi->rssical_cache.rssical_phyregs_2G[11]); - s8 lna1A_gain_db_rev7[] = { 11, 16, 20, 24 }; - s8 lna1A_gain_db_2_rev7[] = { - 11, 17, 22, 25 }; - s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 }; + } else { + if (pi->nphy_rssical_chanspec_5G == 0) + return; - crsminu_th = 0x3e; - lna1_gain_db = lna1A_gain_db_rev7; - lna1_gain_db_2 = lna1A_gain_db_2_rev7; - lna2_gain_db = lna2A_gain_db_rev7; - } else if ((freq >= 5500) && (freq <= 5700)) { + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0, + RADIO_2057_VCM_MASK, + pi->rssical_cache. + rssical_radio_regs_5G[0]); + mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1, + RADIO_2057_VCM_MASK, + pi->rssical_cache. + rssical_radio_regs_5G[1]); + } else { + mod_radio_reg(pi, + RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX0, + RADIO_2056_VCM_MASK, + pi->rssical_cache. + rssical_radio_regs_5G[0]); + mod_radio_reg(pi, + RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX1, + RADIO_2056_VCM_MASK, + pi->rssical_cache. + rssical_radio_regs_5G[1]); + } - s8 lna1A_gain_db_rev7[] = { 11, 17, 21, 25 }; - s8 lna1A_gain_db_2_rev7[] = { - 12, 18, 22, 26 }; - s8 lna2A_gain_db_rev7[] = { 1, 8, 12, 16 }; + write_phy_reg(pi, 0x1a6, + pi->rssical_cache.rssical_phyregs_5G[0]); + write_phy_reg(pi, 0x1ac, + pi->rssical_cache.rssical_phyregs_5G[1]); + write_phy_reg(pi, 0x1b2, + pi->rssical_cache.rssical_phyregs_5G[2]); + write_phy_reg(pi, 0x1b8, + pi->rssical_cache.rssical_phyregs_5G[3]); + write_phy_reg(pi, 0x1a4, + pi->rssical_cache.rssical_phyregs_5G[4]); + write_phy_reg(pi, 0x1aa, + pi->rssical_cache.rssical_phyregs_5G[5]); + write_phy_reg(pi, 0x1b0, + pi->rssical_cache.rssical_phyregs_5G[6]); + write_phy_reg(pi, 0x1b6, + pi->rssical_cache.rssical_phyregs_5G[7]); + write_phy_reg(pi, 0x1a5, + pi->rssical_cache.rssical_phyregs_5G[8]); + write_phy_reg(pi, 0x1ab, + pi->rssical_cache.rssical_phyregs_5G[9]); + write_phy_reg(pi, 0x1b1, + pi->rssical_cache.rssical_phyregs_5G[10]); + write_phy_reg(pi, 0x1b7, + pi->rssical_cache.rssical_phyregs_5G[11]); + } +} - crsminu_th = 0x45; - clip1md_gaincode_B = 0x14; - nbclip_th = 0xff; - chg_nbclip_th = 1; - lna1_gain_db = lna1A_gain_db_rev7; - lna1_gain_db_2 = lna1A_gain_db_2_rev7; - lna2_gain_db = lna2A_gain_db_rev7; +static void wlc_phy_internal_cal_txgain_nphy(struct brcms_phy *pi) +{ + u16 txcal_gain[2]; + + pi->nphy_txcal_pwr_idx[0] = pi->nphy_cal_orig_pwr_idx[0]; + pi->nphy_txcal_pwr_idx[1] = pi->nphy_cal_orig_pwr_idx[0]; + wlc_phy_txpwr_index_nphy(pi, 1, pi->nphy_cal_orig_pwr_idx[0], true); + wlc_phy_txpwr_index_nphy(pi, 2, pi->nphy_cal_orig_pwr_idx[1], true); + + wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, + txcal_gain); + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + txcal_gain[0] = (txcal_gain[0] & 0xF000) | 0x0F40; + txcal_gain[1] = (txcal_gain[1] & 0xF000) | 0x0F40; + } else { + txcal_gain[0] = (txcal_gain[0] & 0xF000) | 0x0F60; + txcal_gain[1] = (txcal_gain[1] & 0xF000) | 0x0F60; + } + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, + txcal_gain); +} + +static void wlc_phy_precal_txgain_nphy(struct brcms_phy *pi) +{ + bool save_bbmult = false; + u8 txcal_index_2057_rev5n7 = 0; + u8 txcal_index_2057_rev3n4n6 = 10; + + if (pi->use_int_tx_iqlo_cal_nphy) { + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + if ((pi->pubpi.radiorev == 3) || + (pi->pubpi.radiorev == 4) || + (pi->pubpi.radiorev == 6)) { + + pi->nphy_txcal_pwr_idx[0] = + txcal_index_2057_rev3n4n6; + pi->nphy_txcal_pwr_idx[1] = + txcal_index_2057_rev3n4n6; + wlc_phy_txpwr_index_nphy( + pi, 3, + txcal_index_2057_rev3n4n6, + false); } else { - s8 lna1A_gain_db_rev7[] = { 12, 18, 22, 26 }; - s8 lna1A_gain_db_2_rev7[] = { - 12, 18, 22, 26 }; - s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 }; + pi->nphy_txcal_pwr_idx[0] = + txcal_index_2057_rev5n7; + pi->nphy_txcal_pwr_idx[1] = + txcal_index_2057_rev5n7; + wlc_phy_txpwr_index_nphy( + pi, 3, + txcal_index_2057_rev5n7, + false); + } + save_bbmult = true; - crsminu_th = 0x41; - lna1_gain_db = lna1A_gain_db_rev7; - lna1_gain_db_2 = lna1A_gain_db_2_rev7; - lna2_gain_db = lna2A_gain_db_rev7; + } else if (NREV_LT(pi->pubpi.phy_rev, 5)) { + wlc_phy_cal_txgainctrl_nphy(pi, 11, false); + if (pi->sh->hw_phytxchain != 3) { + pi->nphy_txcal_pwr_idx[1] = + pi->nphy_txcal_pwr_idx[0]; + wlc_phy_txpwr_index_nphy(pi, 3, + pi-> + nphy_txcal_pwr_idx[0], + true); + save_bbmult = true; } - if (freq <= 4920) { - nvar_baseline_offset0 = 5; - nvar_baseline_offset1 = 5; - } else if ((freq > 4920) && (freq <= 5320)) { - nvar_baseline_offset0 = 3; - nvar_baseline_offset1 = 5; - } else if ((freq > 5320) && (freq <= 5700)) { - nvar_baseline_offset0 = 3; - nvar_baseline_offset1 = 2; + } else if (NREV_IS(pi->pubpi.phy_rev, 5)) { + if (PHY_IPA(pi)) { + if (CHSPEC_IS2G(pi->radio_chanspec)) { + wlc_phy_cal_txgainctrl_nphy(pi, 12, + false); + } else { + pi->nphy_txcal_pwr_idx[0] = 80; + pi->nphy_txcal_pwr_idx[1] = 80; + wlc_phy_txpwr_index_nphy(pi, 3, 80, + false); + save_bbmult = true; + } } else { - nvar_baseline_offset0 = 4; - nvar_baseline_offset1 = 0; + wlc_phy_internal_cal_txgain_nphy(pi); + save_bbmult = true; } - } else { - crsminu_th = 0x3a; - crsminl_th = 0x3a; - w1clip_th = 20; - - if ((freq >= 4920) && (freq <= 5320)) { - nvar_baseline_offset0 = 4; - nvar_baseline_offset1 = 5; - } else if ((freq > 5320) && (freq <= 5550)) { - nvar_baseline_offset0 = 4; - nvar_baseline_offset1 = 2; + } else if (NREV_IS(pi->pubpi.phy_rev, 6)) { + if (PHY_IPA(pi)) { + if (CHSPEC_IS2G(pi->radio_chanspec)) + wlc_phy_cal_txgainctrl_nphy(pi, 12, + false); + else + wlc_phy_cal_txgainctrl_nphy(pi, 14, + false); } else { - nvar_baseline_offset0 = 5; - nvar_baseline_offset1 = 3; + wlc_phy_internal_cal_txgain_nphy(pi); + save_bbmult = true; } } - write_phy_reg(pi, 0x20, init_gaincode); - write_phy_reg(pi, 0x2a7, init_gaincode); + } else { + wlc_phy_cal_txgainctrl_nphy(pi, 10, false); + } - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, - pi->pubpi.phy_corenum, 0x106, 16, - rfseq_init_gain); + if (save_bbmult) + wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, + &pi->nphy_txcal_bbmult); +} - write_phy_reg(pi, 0x22, clip1hi_gaincode); - write_phy_reg(pi, 0x2a9, clip1hi_gaincode); +static void +wlc_phy_rfctrlintc_override_nphy(struct brcms_phy *pi, u8 field, u16 value, + u8 core_code) +{ + u16 mask; + u16 val; + u8 core; - write_phy_reg(pi, 0x36, clip1md_gaincode_B); - write_phy_reg(pi, 0x2ac, clip1md_gaincode_B); + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + for (core = 0; core < pi->pubpi.phy_corenum; core++) { + if (core_code == RADIO_MIMO_CORESEL_CORE1 + && core == PHY_CORE_1) + continue; + else if (core_code == RADIO_MIMO_CORESEL_CORE2 + && core == PHY_CORE_0) + continue; - write_phy_reg(pi, 0x37, clip1lo_gaincode); - write_phy_reg(pi, 0x2ad, clip1lo_gaincode); - write_phy_reg(pi, 0x38, clip1lo_gaincode_B); - write_phy_reg(pi, 0x2ae, clip1lo_gaincode_B); + if (NREV_LT(pi->pubpi.phy_rev, 7)) { - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 10, 0x20, 8, - tia_gain_db); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 10, 0x20, 8, - tia_gain_db); + mask = (0x1 << 10); + val = 1 << 10; + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x91 : + 0x92, mask, val); + } - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS1, 10, 0x20, 8, - tia_gainbits); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAINBITS2, 10, 0x20, 8, - tia_gainbits); + if (field == NPHY_RfctrlIntc_override_OFF) { - mod_phy_reg(pi, 0x283, (0xff << 0), (crsminu_th << 0)); + write_phy_reg(pi, (core == PHY_CORE_0) ? 0x91 : + 0x92, 0); - if (chg_nbclip_th == 1) { - write_phy_reg(pi, 0x2b, nbclip_th); - write_phy_reg(pi, 0x41, nbclip_th); - } + wlc_phy_force_rfseq_nphy(pi, + NPHY_RFSEQ_RESET2RX); + } else if (field == NPHY_RfctrlIntc_override_TRSW) { - mod_phy_reg(pi, 0x300, (0x3f << 0), (w1clip_th << 0)); - mod_phy_reg(pi, 0x301, (0x3f << 0), (w1clip_th << 0)); + if (NREV_GE(pi->pubpi.phy_rev, 7)) { - mod_phy_reg(pi, 0x2e4, - (0x3f << 0), (nvar_baseline_offset0 << 0)); + mask = (0x1 << 6) | (0x1 << 7); - mod_phy_reg(pi, 0x2e4, - (0x3f << 6), (nvar_baseline_offset1 << 6)); + val = value << 6; + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0x91 : 0x92, + mask, val); - if (CHSPEC_IS20(pi->radio_chanspec)) { + or_phy_reg(pi, + (core == + PHY_CORE_0) ? 0x91 : 0x92, + (0x1 << 10)); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 8, 8, - lna1_gain_db); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 8, 8, - lna1_gain_db_2); + and_phy_reg(pi, 0x2ff, (u16) + ~(0x3 << 14)); + or_phy_reg(pi, 0x2ff, (0x1 << 13)); + or_phy_reg(pi, 0x2ff, (0x1 << 0)); + } else { - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN1, 4, 0x10, - 8, lna2_gain_db); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_GAIN2, 4, 0x10, - 8, lna2_gain_db); + mask = (0x1 << 6) | + (0x1 << 7) | + (0x1 << 8) | (0x1 << 9); + val = value << 6; + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0x91 : 0x92, + mask, val); - write_phy_reg(pi, 0x24, clip1md_gaincode); - write_phy_reg(pi, 0x2ab, clip1md_gaincode); - } else { - mod_phy_reg(pi, 0x280, (0xff << 0), (crsminl_th << 0)); - } + mask = (0x1 << 0); + val = 1 << 0; + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0xe7 : 0xec, + mask, val); - } + mask = (core == PHY_CORE_0) ? + (0x1 << 0) : (0x1 << 1); + val = 1 << ((core == PHY_CORE_0) ? + 0 : 1); + mod_phy_reg(pi, 0x78, mask, val); + + SPINWAIT(((read_phy_reg(pi, 0x78) & val) + != 0), 10000); + if (WARN(read_phy_reg(pi, 0x78) & val, + "HW error: override failed")) + return; + + mask = (0x1 << 0); + val = 0 << 0; + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0xe7 : 0xec, + mask, val); + } + } else if (field == NPHY_RfctrlIntc_override_PA) { + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + + mask = (0x1 << 4) | (0x1 << 5); + if (CHSPEC_IS5G(pi->radio_chanspec)) + val = value << 5; + else + val = value << 4; + + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0x91 : 0x92, + mask, val); + + or_phy_reg(pi, + (core == + PHY_CORE_0) ? 0x91 : 0x92, + (0x1 << 12)); + } else { + + if (CHSPEC_IS5G(pi->radio_chanspec)) { + mask = (0x1 << 5); + val = value << 5; + } else { + mask = (0x1 << 4); + val = value << 4; + } + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0x91 : 0x92, + mask, val); + } + } else if (field == + NPHY_RfctrlIntc_override_EXT_LNA_PU) { + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + if (CHSPEC_IS5G(pi->radio_chanspec)) { + + mask = (0x1 << 0); + val = value << 0; + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0x91 + : 0x92, mask, val); + + mask = (0x1 << 2); + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0x91 + : 0x92, mask, 0); + } else { + + mask = (0x1 << 2); + val = value << 2; + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0x91 + : 0x92, mask, val); + + mask = (0x1 << 0); + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0x91 + : 0x92, mask, 0); + } + + mask = (0x1 << 11); + val = 1 << 11; + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0x91 : 0x92, + mask, val); + } else { + + if (CHSPEC_IS5G(pi->radio_chanspec)) { + mask = (0x1 << 0); + val = value << 0; + } else { + mask = (0x1 << 2); + val = value << 2; + } + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0x91 : 0x92, + mask, val); + } + } else if (field == + NPHY_RfctrlIntc_override_EXT_LNA_GAIN) { + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + if (CHSPEC_IS5G(pi->radio_chanspec)) { + + mask = (0x1 << 1); + val = value << 1; + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0x91 + : 0x92, mask, val); + + mask = (0x1 << 3); + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0x91 + : 0x92, mask, 0); + } else { + + mask = (0x1 << 3); + val = value << 3; + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0x91 + : 0x92, mask, val); + + mask = (0x1 << 1); + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0x91 + : 0x92, mask, 0); + } + + mask = (0x1 << 11); + val = 1 << 11; + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0x91 : 0x92, + mask, val); + } else { + + if (CHSPEC_IS5G(pi->radio_chanspec)) { + mask = (0x1 << 1); + val = value << 1; + } else { + mask = (0x1 << 3); + val = value << 3; + } + mod_phy_reg(pi, + (core == + PHY_CORE_0) ? 0x91 : 0x92, + mask, val); + } + } + } + } } -static void wlc_phy_adjust_lnagaintbl_nphy(struct brcms_phy *pi) +void +wlc_phy_cal_txgainctrl_nphy(struct brcms_phy *pi, s32 dBm_targetpower, + bool debug) { + int gainctrl_loopidx; uint core; - int ctr; - s16 gain_delta[2]; - u8 curr_channel; - u16 minmax_gain[2]; - u16 regval[4]; + u16 m0m1, curr_m0m1; + s32 delta_power; + s32 txpwrindex; + s32 qdBm_power[2]; + u16 orig_BBConfig; + u16 phy_saveregs[4]; + u32 freq_test; + u16 ampl_test = 250; + uint stepsize; + bool phyhang_avoid_state = false; + + if (NREV_GE(pi->pubpi.phy_rev, 7)) + stepsize = 2; + else + stepsize = 1; + + if (CHSPEC_IS40(pi->radio_chanspec)) + freq_test = 5000; + else + freq_test = 2500; + + wlc_phy_txpwr_index_nphy(pi, 1, pi->nphy_cal_orig_pwr_idx[0], true); + wlc_phy_txpwr_index_nphy(pi, 2, pi->nphy_cal_orig_pwr_idx[1], true); if (pi->phyhang_avoid) wlc_phy_stay_in_carriersearch_nphy(pi, true); - if (pi->nphy_gain_boost) { - if ((CHSPEC_IS2G(pi->radio_chanspec))) { + phyhang_avoid_state = pi->phyhang_avoid; + pi->phyhang_avoid = false; - gain_delta[0] = 6; - gain_delta[1] = 6; - } else { + phy_saveregs[0] = read_phy_reg(pi, 0x91); + phy_saveregs[1] = read_phy_reg(pi, 0x92); + phy_saveregs[2] = read_phy_reg(pi, 0xe7); + phy_saveregs[3] = read_phy_reg(pi, 0xec); + wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_PA, 1, + RADIO_MIMO_CORESEL_CORE1 | + RADIO_MIMO_CORESEL_CORE2); - curr_channel = CHSPEC_CHANNEL(pi->radio_chanspec); - gain_delta[0] = - (s16) - PHY_HW_ROUND(((nphy_lnagain_est0[0] * - curr_channel) + - nphy_lnagain_est0[1]), 13); - gain_delta[1] = - (s16) - PHY_HW_ROUND(((nphy_lnagain_est1[0] * - curr_channel) + - nphy_lnagain_est1[1]), 13); - } + if (!debug) { + wlc_phy_rfctrlintc_override_nphy(pi, + NPHY_RfctrlIntc_override_TRSW, + 0x2, RADIO_MIMO_CORESEL_CORE1); + wlc_phy_rfctrlintc_override_nphy(pi, + NPHY_RfctrlIntc_override_TRSW, + 0x8, RADIO_MIMO_CORESEL_CORE2); } else { - - gain_delta[0] = 0; - gain_delta[1] = 0; + wlc_phy_rfctrlintc_override_nphy(pi, + NPHY_RfctrlIntc_override_TRSW, + 0x1, RADIO_MIMO_CORESEL_CORE1); + wlc_phy_rfctrlintc_override_nphy(pi, + NPHY_RfctrlIntc_override_TRSW, + 0x7, RADIO_MIMO_CORESEL_CORE2); } + orig_BBConfig = read_phy_reg(pi, 0x01); + mod_phy_reg(pi, 0x01, (0x1 << 15), 0); + + wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m0m1); + for (core = 0; core < pi->pubpi.phy_corenum; core++) { - if (pi->nphy_elna_gain_config) { + txpwrindex = (s32) pi->nphy_cal_orig_pwr_idx[core]; - regval[0] = nphy_def_lnagains[2] + gain_delta[core]; - regval[1] = nphy_def_lnagains[3] + gain_delta[core]; - regval[2] = nphy_def_lnagains[3] + gain_delta[core]; - regval[3] = nphy_def_lnagains[3] + gain_delta[core]; - } else { - for (ctr = 0; ctr < 4; ctr++) { - regval[ctr] = - nphy_def_lnagains[ctr] + gain_delta[core]; + for (gainctrl_loopidx = 0; gainctrl_loopidx < 2; + gainctrl_loopidx++) { + wlc_phy_tx_tone_nphy(pi, freq_test, ampl_test, 0, 0, + false); + + if (core == PHY_CORE_0) + curr_m0m1 = m0m1 & 0xff00; + else + curr_m0m1 = m0m1 & 0x00ff; + + wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &curr_m0m1); + wlc_phy_table_write_nphy(pi, 15, 1, 95, 16, &curr_m0m1); + + udelay(50); + + wlc_phy_est_tonepwr_nphy(pi, qdBm_power, + NPHY_CAL_TSSISAMPS); + + pi->nphy_bb_mult_save = 0; + wlc_phy_stopplayback_nphy(pi); + + delta_power = (dBm_targetpower * 4) - qdBm_power[core]; + + txpwrindex -= stepsize * delta_power; + if (txpwrindex < 0) + txpwrindex = 0; + else if (txpwrindex > 127) + txpwrindex = 127; + + if (CHSPEC_IS5G(pi->radio_chanspec)) { + if (NREV_IS(pi->pubpi.phy_rev, 4) && + (pi->srom_fem5g.extpagain == 3)) { + if (txpwrindex < 30) + txpwrindex = 30; + } + } else { + if (NREV_GE(pi->pubpi.phy_rev, 5) && + (pi->srom_fem2g.extpagain == 3)) { + if (txpwrindex < 50) + txpwrindex = 50; + } } + + wlc_phy_txpwr_index_nphy(pi, (1 << core), + (u8) txpwrindex, true); } - wlc_phy_table_write_nphy(pi, core, 4, 8, 16, regval); - minmax_gain[core] = - (u16) (nphy_def_lnagains[2] + gain_delta[core] + 4); + pi->nphy_txcal_pwr_idx[core] = (u8) txpwrindex; + + if (debug) { + u16 radio_gain; + u16 dbg_m0m1; + + wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &dbg_m0m1); + + wlc_phy_tx_tone_nphy(pi, freq_test, ampl_test, 0, 0, + false); + + wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &dbg_m0m1); + wlc_phy_table_write_nphy(pi, 15, 1, 95, 16, &dbg_m0m1); + + udelay(100); + + wlc_phy_est_tonepwr_nphy(pi, qdBm_power, + NPHY_CAL_TSSISAMPS); + + wlc_phy_table_read_nphy(pi, 7, 1, (0x110 + core), 16, + &radio_gain); + + mdelay(4000); + pi->nphy_bb_mult_save = 0; + wlc_phy_stopplayback_nphy(pi); + } } - mod_phy_reg(pi, 0x1e, (0xff << 0), (minmax_gain[0] << 0)); - mod_phy_reg(pi, 0x34, (0xff << 0), (minmax_gain[1] << 0)); + wlc_phy_txpwr_index_nphy(pi, 1, pi->nphy_txcal_pwr_idx[0], true); + wlc_phy_txpwr_index_nphy(pi, 2, pi->nphy_txcal_pwr_idx[1], true); + + wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &pi->nphy_txcal_bbmult); + + write_phy_reg(pi, 0x01, orig_BBConfig); + + write_phy_reg(pi, 0x91, phy_saveregs[0]); + write_phy_reg(pi, 0x92, phy_saveregs[1]); + write_phy_reg(pi, 0xe7, phy_saveregs[2]); + write_phy_reg(pi, 0xec, phy_saveregs[3]); + + pi->phyhang_avoid = phyhang_avoid_state; if (pi->phyhang_avoid) wlc_phy_stay_in_carriersearch_nphy(pi, false); } -void wlc_phy_switch_radio_nphy(struct brcms_phy *pi, bool on) +static void wlc_phy_savecal_nphy(struct brcms_phy *pi) { - if (on) { + void *tbl_ptr; + int coreNum; + u16 *txcal_radio_regs = NULL; + + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, true); + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + + wlc_phy_rx_iq_coeffs_nphy(pi, 0, + &pi->calibration_cache. + rxcal_coeffs_2G); + if (NREV_GE(pi->pubpi.phy_rev, 7)) { - if (!pi->radio_is_on) { - wlc_phy_radio_preinit_205x(pi); - wlc_phy_radio_init_2057(pi); - wlc_phy_radio_postinit_2057(pi); - } + txcal_radio_regs = + pi->calibration_cache.txcal_radio_regs_2G; + } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { - wlc_phy_chanspec_set((struct brcms_phy_pub *) pi, - pi->radio_chanspec); + pi->calibration_cache.txcal_radio_regs_2G[0] = + read_radio_reg(pi, + RADIO_2056_TX_LOFT_FINE_I | + RADIO_2056_TX0); + pi->calibration_cache.txcal_radio_regs_2G[1] = + read_radio_reg(pi, + RADIO_2056_TX_LOFT_FINE_Q | + RADIO_2056_TX0); + pi->calibration_cache.txcal_radio_regs_2G[2] = + read_radio_reg(pi, + RADIO_2056_TX_LOFT_FINE_I | + RADIO_2056_TX1); + pi->calibration_cache.txcal_radio_regs_2G[3] = + read_radio_reg(pi, + RADIO_2056_TX_LOFT_FINE_Q | + RADIO_2056_TX1); + + pi->calibration_cache.txcal_radio_regs_2G[4] = + read_radio_reg(pi, + RADIO_2056_TX_LOFT_COARSE_I | + RADIO_2056_TX0); + pi->calibration_cache.txcal_radio_regs_2G[5] = + read_radio_reg(pi, + RADIO_2056_TX_LOFT_COARSE_Q | + RADIO_2056_TX0); + pi->calibration_cache.txcal_radio_regs_2G[6] = + read_radio_reg(pi, + RADIO_2056_TX_LOFT_COARSE_I | + RADIO_2056_TX1); + pi->calibration_cache.txcal_radio_regs_2G[7] = + read_radio_reg(pi, + RADIO_2056_TX_LOFT_COARSE_Q | + RADIO_2056_TX1); + } else { + pi->calibration_cache.txcal_radio_regs_2G[0] = + read_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL); + pi->calibration_cache.txcal_radio_regs_2G[1] = + read_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL); + pi->calibration_cache.txcal_radio_regs_2G[2] = + read_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM); + pi->calibration_cache.txcal_radio_regs_2G[3] = + read_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM); + } + + pi->nphy_iqcal_chanspec_2G = pi->radio_chanspec; + tbl_ptr = pi->calibration_cache.txcal_coeffs_2G; + } else { + + wlc_phy_rx_iq_coeffs_nphy(pi, 0, + &pi->calibration_cache. + rxcal_coeffs_5G); + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + txcal_radio_regs = + pi->calibration_cache.txcal_radio_regs_5G; } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { - wlc_phy_radio_preinit_205x(pi); - wlc_phy_radio_init_2056(pi); - wlc_phy_radio_postinit_2056(pi); - wlc_phy_chanspec_set((struct brcms_phy_pub *) pi, - pi->radio_chanspec); + pi->calibration_cache.txcal_radio_regs_5G[0] = + read_radio_reg(pi, + RADIO_2056_TX_LOFT_FINE_I | + RADIO_2056_TX0); + pi->calibration_cache.txcal_radio_regs_5G[1] = + read_radio_reg(pi, + RADIO_2056_TX_LOFT_FINE_Q | + RADIO_2056_TX0); + pi->calibration_cache.txcal_radio_regs_5G[2] = + read_radio_reg(pi, + RADIO_2056_TX_LOFT_FINE_I | + RADIO_2056_TX1); + pi->calibration_cache.txcal_radio_regs_5G[3] = + read_radio_reg(pi, + RADIO_2056_TX_LOFT_FINE_Q | + RADIO_2056_TX1); + + pi->calibration_cache.txcal_radio_regs_5G[4] = + read_radio_reg(pi, + RADIO_2056_TX_LOFT_COARSE_I | + RADIO_2056_TX0); + pi->calibration_cache.txcal_radio_regs_5G[5] = + read_radio_reg(pi, + RADIO_2056_TX_LOFT_COARSE_Q | + RADIO_2056_TX0); + pi->calibration_cache.txcal_radio_regs_5G[6] = + read_radio_reg(pi, + RADIO_2056_TX_LOFT_COARSE_I | + RADIO_2056_TX1); + pi->calibration_cache.txcal_radio_regs_5G[7] = + read_radio_reg(pi, + RADIO_2056_TX_LOFT_COARSE_Q | + RADIO_2056_TX1); } else { - wlc_phy_radio_preinit_2055(pi); - wlc_phy_radio_init_2055(pi); - wlc_phy_radio_postinit_2055(pi); + pi->calibration_cache.txcal_radio_regs_5G[0] = + read_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL); + pi->calibration_cache.txcal_radio_regs_5G[1] = + read_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL); + pi->calibration_cache.txcal_radio_regs_5G[2] = + read_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM); + pi->calibration_cache.txcal_radio_regs_5G[3] = + read_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM); } - pi->radio_is_on = true; + pi->nphy_iqcal_chanspec_5G = pi->radio_chanspec; + tbl_ptr = pi->calibration_cache.txcal_coeffs_5G; + } + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + for (coreNum = 0; coreNum <= 1; coreNum++) { + + txcal_radio_regs[2 * coreNum] = + READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum, + LOFT_FINE_I); + txcal_radio_regs[2 * coreNum + 1] = + READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum, + LOFT_FINE_Q); + + txcal_radio_regs[2 * coreNum + 4] = + READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum, + LOFT_COARSE_I); + txcal_radio_regs[2 * coreNum + 5] = + READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum, + LOFT_COARSE_Q); + } + } + + wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 8, 80, 16, tbl_ptr); + + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, false); +} + +static void wlc_phy_tx_iq_war_nphy(struct brcms_phy *pi) +{ + struct nphy_iq_comp tx_comp; + + wlc_phy_table_read_nphy(pi, 15, 4, 0x50, 16, &tx_comp); + + wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ, tx_comp.a0); + wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ + 2, tx_comp.b0); + wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ + 4, tx_comp.a1); + wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ + 6, tx_comp.b1); +} + +static void wlc_phy_restorecal_nphy(struct brcms_phy *pi) +{ + u16 *loft_comp; + u16 txcal_coeffs_bphy[4]; + u16 *tbl_ptr; + int coreNum; + u16 *txcal_radio_regs = NULL; + if (CHSPEC_IS2G(pi->radio_chanspec)) { + if (pi->nphy_iqcal_chanspec_2G == 0) + return; + + tbl_ptr = pi->calibration_cache.txcal_coeffs_2G; + loft_comp = &pi->calibration_cache.txcal_coeffs_2G[5]; } else { + if (pi->nphy_iqcal_chanspec_5G == 0) + return; - if (NREV_GE(pi->pubpi.phy_rev, 3) - && NREV_LT(pi->pubpi.phy_rev, 7)) { - and_phy_reg(pi, 0x78, ~RFCC_CHIP0_PU); - mod_radio_reg(pi, RADIO_2056_SYN_COM_PU, 0x2, 0x0); + tbl_ptr = pi->calibration_cache.txcal_coeffs_5G; + loft_comp = &pi->calibration_cache.txcal_coeffs_5G[5]; + } + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 80, 16, tbl_ptr); + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + txcal_coeffs_bphy[0] = tbl_ptr[0]; + txcal_coeffs_bphy[1] = tbl_ptr[1]; + txcal_coeffs_bphy[2] = tbl_ptr[2]; + txcal_coeffs_bphy[3] = tbl_ptr[3]; + } else { + txcal_coeffs_bphy[0] = 0; + txcal_coeffs_bphy[1] = 0; + txcal_coeffs_bphy[2] = 0; + txcal_coeffs_bphy[3] = 0; + } + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 88, 16, + txcal_coeffs_bphy); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 85, 16, loft_comp); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 93, 16, loft_comp); + + if (NREV_LT(pi->pubpi.phy_rev, 2)) + wlc_phy_tx_iq_war_nphy(pi); + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + txcal_radio_regs = + pi->calibration_cache.txcal_radio_regs_2G; + } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { write_radio_reg(pi, - RADIO_2056_TX_PADA_BOOST_TUNE | - RADIO_2056_TX0, 0); + RADIO_2056_TX_LOFT_FINE_I | + RADIO_2056_TX0, + pi->calibration_cache. + txcal_radio_regs_2G[0]); write_radio_reg(pi, - RADIO_2056_TX_PADG_BOOST_TUNE | - RADIO_2056_TX0, 0); + RADIO_2056_TX_LOFT_FINE_Q | + RADIO_2056_TX0, + pi->calibration_cache. + txcal_radio_regs_2G[1]); write_radio_reg(pi, - RADIO_2056_TX_PGAA_BOOST_TUNE | - RADIO_2056_TX0, 0); + RADIO_2056_TX_LOFT_FINE_I | + RADIO_2056_TX1, + pi->calibration_cache. + txcal_radio_regs_2G[2]); write_radio_reg(pi, - RADIO_2056_TX_PGAG_BOOST_TUNE | - RADIO_2056_TX0, 0); - mod_radio_reg(pi, - RADIO_2056_TX_MIXA_BOOST_TUNE | - RADIO_2056_TX0, 0xf0, 0); + RADIO_2056_TX_LOFT_FINE_Q | + RADIO_2056_TX1, + pi->calibration_cache. + txcal_radio_regs_2G[3]); + write_radio_reg(pi, - RADIO_2056_TX_MIXG_BOOST_TUNE | - RADIO_2056_TX0, 0); + RADIO_2056_TX_LOFT_COARSE_I | + RADIO_2056_TX0, + pi->calibration_cache. + txcal_radio_regs_2G[4]); + write_radio_reg(pi, + RADIO_2056_TX_LOFT_COARSE_Q | + RADIO_2056_TX0, + pi->calibration_cache. + txcal_radio_regs_2G[5]); + write_radio_reg(pi, + RADIO_2056_TX_LOFT_COARSE_I | + RADIO_2056_TX1, + pi->calibration_cache. + txcal_radio_regs_2G[6]); + write_radio_reg(pi, + RADIO_2056_TX_LOFT_COARSE_Q | + RADIO_2056_TX1, + pi->calibration_cache. + txcal_radio_regs_2G[7]); + } else { + write_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL, + pi->calibration_cache. + txcal_radio_regs_2G[0]); + write_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL, + pi->calibration_cache. + txcal_radio_regs_2G[1]); + write_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM, + pi->calibration_cache. + txcal_radio_regs_2G[2]); + write_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM, + pi->calibration_cache. + txcal_radio_regs_2G[3]); + } + + wlc_phy_rx_iq_coeffs_nphy(pi, 1, + &pi->calibration_cache. + rxcal_coeffs_2G); + } else { + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + txcal_radio_regs = + pi->calibration_cache.txcal_radio_regs_5G; + } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { write_radio_reg(pi, - RADIO_2056_TX_PADA_BOOST_TUNE | - RADIO_2056_TX1, 0); + RADIO_2056_TX_LOFT_FINE_I | + RADIO_2056_TX0, + pi->calibration_cache. + txcal_radio_regs_5G[0]); write_radio_reg(pi, - RADIO_2056_TX_PADG_BOOST_TUNE | - RADIO_2056_TX1, 0); + RADIO_2056_TX_LOFT_FINE_Q | + RADIO_2056_TX0, + pi->calibration_cache. + txcal_radio_regs_5G[1]); write_radio_reg(pi, - RADIO_2056_TX_PGAA_BOOST_TUNE | - RADIO_2056_TX1, 0); + RADIO_2056_TX_LOFT_FINE_I | + RADIO_2056_TX1, + pi->calibration_cache. + txcal_radio_regs_5G[2]); write_radio_reg(pi, - RADIO_2056_TX_PGAG_BOOST_TUNE | - RADIO_2056_TX1, 0); - mod_radio_reg(pi, - RADIO_2056_TX_MIXA_BOOST_TUNE | - RADIO_2056_TX1, 0xf0, 0); + RADIO_2056_TX_LOFT_FINE_Q | + RADIO_2056_TX1, + pi->calibration_cache. + txcal_radio_regs_5G[3]); + write_radio_reg(pi, - RADIO_2056_TX_MIXG_BOOST_TUNE | - RADIO_2056_TX1, 0); + RADIO_2056_TX_LOFT_COARSE_I | + RADIO_2056_TX0, + pi->calibration_cache. + txcal_radio_regs_5G[4]); + write_radio_reg(pi, + RADIO_2056_TX_LOFT_COARSE_Q | + RADIO_2056_TX0, + pi->calibration_cache. + txcal_radio_regs_5G[5]); + write_radio_reg(pi, + RADIO_2056_TX_LOFT_COARSE_I | + RADIO_2056_TX1, + pi->calibration_cache. + txcal_radio_regs_5G[6]); + write_radio_reg(pi, + RADIO_2056_TX_LOFT_COARSE_Q | + RADIO_2056_TX1, + pi->calibration_cache. + txcal_radio_regs_5G[7]); + } else { + write_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL, + pi->calibration_cache. + txcal_radio_regs_5G[0]); + write_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL, + pi->calibration_cache. + txcal_radio_regs_5G[1]); + write_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM, + pi->calibration_cache. + txcal_radio_regs_5G[2]); + write_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM, + pi->calibration_cache. + txcal_radio_regs_5G[3]); + } - pi->radio_is_on = false; + wlc_phy_rx_iq_coeffs_nphy(pi, 1, + &pi->calibration_cache. + rxcal_coeffs_5G); + } + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + for (coreNum = 0; coreNum <= 1; coreNum++) { + + WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum, + LOFT_FINE_I, + txcal_radio_regs[2 * coreNum]); + WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum, + LOFT_FINE_Q, + txcal_radio_regs[2 * coreNum + 1]); + + WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum, + LOFT_COARSE_I, + txcal_radio_regs[2 * coreNum + 4]); + WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum, + LOFT_COARSE_Q, + txcal_radio_regs[2 * coreNum + 5]); } + } +} - if (NREV_GE(pi->pubpi.phy_rev, 8)) { - and_phy_reg(pi, 0x78, ~RFCC_CHIP0_PU); - pi->radio_is_on = false; +static void wlc_phy_txpwrctrl_coeff_setup_nphy(struct brcms_phy *pi) +{ + u32 idx; + u16 iqloCalbuf[7]; + u32 iqcomp, locomp, curr_locomp; + s8 locomp_i, locomp_q; + s8 curr_locomp_i, curr_locomp_q; + u32 tbl_id, tbl_len, tbl_offset; + u32 regval[128]; + + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, true); + + wlc_phy_table_read_nphy(pi, 15, 7, 80, 16, iqloCalbuf); + + tbl_len = 128; + tbl_offset = 320; + for (tbl_id = NPHY_TBL_ID_CORE1TXPWRCTL; + tbl_id <= NPHY_TBL_ID_CORE2TXPWRCTL; tbl_id++) { + iqcomp = + (tbl_id == + 26) ? (((u32) (iqloCalbuf[0] & 0x3ff)) << 10) | + (iqloCalbuf[1] & 0x3ff) + : (((u32) (iqloCalbuf[2] & 0x3ff)) << 10) | + (iqloCalbuf[3] & 0x3ff); + + for (idx = 0; idx < tbl_len; idx++) + regval[idx] = iqcomp; + wlc_phy_table_write_nphy(pi, tbl_id, tbl_len, tbl_offset, 32, + regval); + } + + tbl_offset = 448; + for (tbl_id = NPHY_TBL_ID_CORE1TXPWRCTL; + tbl_id <= NPHY_TBL_ID_CORE2TXPWRCTL; tbl_id++) { + + locomp = + (u32) ((tbl_id == 26) ? iqloCalbuf[5] : iqloCalbuf[6]); + locomp_i = (s8) ((locomp >> 8) & 0xff); + locomp_q = (s8) ((locomp) & 0xff); + for (idx = 0; idx < tbl_len; idx++) { + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + curr_locomp_i = locomp_i; + curr_locomp_q = locomp_q; + } else { + curr_locomp_i = (s8) ((locomp_i * + nphy_tpc_loscale[idx] + + 128) >> 8); + curr_locomp_q = + (s8) ((locomp_q * + nphy_tpc_loscale[idx] + + 128) >> 8); + } + curr_locomp = (u32) ((curr_locomp_i & 0xff) << 8); + curr_locomp |= (u32) (curr_locomp_q & 0xff); + regval[idx] = curr_locomp; } + wlc_phy_table_write_nphy(pi, tbl_id, tbl_len, tbl_offset, 32, + regval); + } + + if (NREV_LT(pi->pubpi.phy_rev, 2)) { + wlapi_bmac_write_shm(pi->sh->physhim, M_CURR_IDX1, 0xFFFF); + wlapi_bmac_write_shm(pi->sh->physhim, M_CURR_IDX2, 0xFFFF); } + + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, false); } -static void wlc_phy_radio_preinit_2055(struct brcms_phy *pi) +static void wlc_phy_txlpfbw_nphy(struct brcms_phy *pi) { + u8 tx_lpf_bw = 0; - and_phy_reg(pi, 0x78, ~RFCC_POR_FORCE); - or_phy_reg(pi, 0x78, RFCC_CHIP0_PU | RFCC_OE_POR_FORCE); + if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) { + if (CHSPEC_IS40(pi->radio_chanspec)) + tx_lpf_bw = 3; + else + tx_lpf_bw = 1; - or_phy_reg(pi, 0x78, RFCC_POR_FORCE); + if (PHY_IPA(pi)) { + if (CHSPEC_IS40(pi->radio_chanspec)) + tx_lpf_bw = 5; + else + tx_lpf_bw = 4; + } + + write_phy_reg(pi, 0xe8, + (tx_lpf_bw << 0) | + (tx_lpf_bw << 3) | + (tx_lpf_bw << 6) | (tx_lpf_bw << 9)); + + if (PHY_IPA(pi)) { + + if (CHSPEC_IS40(pi->radio_chanspec)) + tx_lpf_bw = 4; + else + tx_lpf_bw = 1; + + write_phy_reg(pi, 0xe9, + (tx_lpf_bw << 0) | + (tx_lpf_bw << 3) | + (tx_lpf_bw << 6) | (tx_lpf_bw << 9)); + } + } } -static void wlc_phy_radio_init_2055(struct brcms_phy *pi) +static void +wlc_phy_adjust_rx_analpfbw_nphy(struct brcms_phy *pi, u16 reduction_factr) { - wlc_phy_init_radio_regs(pi, regs_2055, RADIO_DEFAULT_CORE); + if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) { + if ((CHSPEC_CHANNEL(pi->radio_chanspec) == 11) && + CHSPEC_IS40(pi->radio_chanspec)) { + if (!pi->nphy_anarxlpf_adjusted) { + write_radio_reg(pi, + (RADIO_2056_RX_RXLPF_RCCAL_LPC | + RADIO_2056_RX0), + ((pi->nphy_rccal_value + + reduction_factr) | 0x80)); + + pi->nphy_anarxlpf_adjusted = true; + } + } else { + if (pi->nphy_anarxlpf_adjusted) { + write_radio_reg(pi, + (RADIO_2056_RX_RXLPF_RCCAL_LPC | + RADIO_2056_RX0), + (pi->nphy_rccal_value | 0x80)); + + pi->nphy_anarxlpf_adjusted = false; + } + } + } } -static void wlc_phy_radio_postinit_2055(struct brcms_phy *pi) +static void +wlc_phy_adjust_min_noisevar_nphy(struct brcms_phy *pi, int ntones, + int *tone_id_buf, u32 *noise_var_buf) { + int i; + u32 offset; + int tone_id; + int tbllen = + CHSPEC_IS40(pi->radio_chanspec) ? + NPHY_NOISEVAR_TBLLEN40 : NPHY_NOISEVAR_TBLLEN20; - and_radio_reg(pi, RADIO_2055_MASTER_CNTRL1, - ~(RADIO_2055_JTAGCTRL_MASK | RADIO_2055_JTAGSYNC_MASK)); + if (pi->nphy_noisevars_adjusted) { + for (i = 0; i < pi->nphy_saved_noisevars.bufcount; i++) { + tone_id = pi->nphy_saved_noisevars.tone_id[i]; + offset = (tone_id >= 0) ? + ((tone_id * + 2) + 1) : (tbllen + (tone_id * 2) + 1); + wlc_phy_table_write_nphy( + pi, NPHY_TBL_ID_NOISEVAR, 1, + offset, 32, + &pi->nphy_saved_noisevars.min_noise_vars[i]); + } - if (((pi->sh->sromrev >= 4) - && !(pi->sh->boardflags2 & BFL2_RXBB_INT_REG_DIS)) - || ((pi->sh->sromrev < 4))) { - and_radio_reg(pi, RADIO_2055_CORE1_RXBB_REGULATOR, 0x7F); - and_radio_reg(pi, RADIO_2055_CORE2_RXBB_REGULATOR, 0x7F); + pi->nphy_saved_noisevars.bufcount = 0; + pi->nphy_noisevars_adjusted = false; } - mod_radio_reg(pi, RADIO_2055_RRCCAL_N_OPT_SEL, 0x3F, 0x2C); - write_radio_reg(pi, RADIO_2055_CAL_MISC, 0x3C); + if ((noise_var_buf != NULL) && (tone_id_buf != NULL)) { + pi->nphy_saved_noisevars.bufcount = 0; - and_radio_reg(pi, RADIO_2055_CAL_MISC, - ~(RADIO_2055_RRCAL_START | RADIO_2055_RRCAL_RST_N)); + for (i = 0; i < ntones; i++) { + tone_id = tone_id_buf[i]; + offset = (tone_id >= 0) ? + ((tone_id * 2) + 1) : + (tbllen + (tone_id * 2) + 1); + pi->nphy_saved_noisevars.tone_id[i] = tone_id; + wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, + offset, 32, + &pi->nphy_saved_noisevars. + min_noise_vars[i]); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, + offset, 32, &noise_var_buf[i]); + pi->nphy_saved_noisevars.bufcount++; + } - or_radio_reg(pi, RADIO_2055_CAL_LPO_CNTRL, RADIO_2055_CAL_LPO_ENABLE); + pi->nphy_noisevars_adjusted = true; + } +} - or_radio_reg(pi, RADIO_2055_CAL_MISC, RADIO_2055_RRCAL_RST_N); +static void wlc_phy_adjust_crsminpwr_nphy(struct brcms_phy *pi, u8 minpwr) +{ + u16 regval; - udelay(1000); + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + if ((CHSPEC_CHANNEL(pi->radio_chanspec) == 11) && + CHSPEC_IS40(pi->radio_chanspec)) { + if (!pi->nphy_crsminpwr_adjusted) { + regval = read_phy_reg(pi, 0x27d); + pi->nphy_crsminpwr[0] = regval & 0xff; + regval &= 0xff00; + regval |= (u16) minpwr; + write_phy_reg(pi, 0x27d, regval); - or_radio_reg(pi, RADIO_2055_CAL_MISC, RADIO_2055_RRCAL_START); + regval = read_phy_reg(pi, 0x280); + pi->nphy_crsminpwr[1] = regval & 0xff; + regval &= 0xff00; + regval |= (u16) minpwr; + write_phy_reg(pi, 0x280, regval); - SPINWAIT(((read_radio_reg(pi, RADIO_2055_CAL_COUNTER_OUT2) & - RADIO_2055_RCAL_DONE) != RADIO_2055_RCAL_DONE), 2000); + regval = read_phy_reg(pi, 0x283); + pi->nphy_crsminpwr[2] = regval & 0xff; + regval &= 0xff00; + regval |= (u16) minpwr; + write_phy_reg(pi, 0x283, regval); - if (WARN((read_radio_reg(pi, RADIO_2055_CAL_COUNTER_OUT2) & - RADIO_2055_RCAL_DONE) != RADIO_2055_RCAL_DONE, - "HW error: radio calibration1\n")) + pi->nphy_crsminpwr_adjusted = true; + } + } else { + if (pi->nphy_crsminpwr_adjusted) { + regval = read_phy_reg(pi, 0x27d); + regval &= 0xff00; + regval |= pi->nphy_crsminpwr[0]; + write_phy_reg(pi, 0x27d, regval); + + regval = read_phy_reg(pi, 0x280); + regval &= 0xff00; + regval |= pi->nphy_crsminpwr[1]; + write_phy_reg(pi, 0x280, regval); + + regval = read_phy_reg(pi, 0x283); + regval &= 0xff00; + regval |= pi->nphy_crsminpwr[2]; + write_phy_reg(pi, 0x283, regval); + + pi->nphy_crsminpwr_adjusted = false; + } + } + } +} + +static void wlc_phy_spurwar_nphy(struct brcms_phy *pi) +{ + u16 cur_channel = 0; + int nphy_adj_tone_id_buf[] = { 57, 58 }; + u32 nphy_adj_noise_var_buf[] = { 0x3ff, 0x3ff }; + bool isAdjustNoiseVar = false; + uint numTonesAdjust = 0; + u32 tempval = 0; + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, true); + + cur_channel = CHSPEC_CHANNEL(pi->radio_chanspec); + + if (pi->nphy_gband_spurwar_en) { + + wlc_phy_adjust_rx_analpfbw_nphy( + pi, + NPHY_ANARXLPFBW_REDUCTIONFACT); + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + if ((cur_channel == 11) + && CHSPEC_IS40(pi->radio_chanspec)) + wlc_phy_adjust_min_noisevar_nphy( + pi, 2, + nphy_adj_tone_id_buf, + nphy_adj_noise_var_buf); + else + wlc_phy_adjust_min_noisevar_nphy(pi, 0, + NULL, + NULL); + } + + wlc_phy_adjust_crsminpwr_nphy(pi, + NPHY_ADJUSTED_MINCRSPOWER); + } + + if ((pi->nphy_gband_spurwar2_en) + && CHSPEC_IS2G(pi->radio_chanspec)) { + + if (CHSPEC_IS40(pi->radio_chanspec)) { + switch (cur_channel) { + case 3: + nphy_adj_tone_id_buf[0] = 57; + nphy_adj_tone_id_buf[1] = 58; + nphy_adj_noise_var_buf[0] = 0x22f; + nphy_adj_noise_var_buf[1] = 0x25f; + isAdjustNoiseVar = true; + break; + case 4: + nphy_adj_tone_id_buf[0] = 41; + nphy_adj_tone_id_buf[1] = 42; + nphy_adj_noise_var_buf[0] = 0x22f; + nphy_adj_noise_var_buf[1] = 0x25f; + isAdjustNoiseVar = true; + break; + case 5: + nphy_adj_tone_id_buf[0] = 25; + nphy_adj_tone_id_buf[1] = 26; + nphy_adj_noise_var_buf[0] = 0x24f; + nphy_adj_noise_var_buf[1] = 0x25f; + isAdjustNoiseVar = true; + break; + case 6: + nphy_adj_tone_id_buf[0] = 9; + nphy_adj_tone_id_buf[1] = 10; + nphy_adj_noise_var_buf[0] = 0x22f; + nphy_adj_noise_var_buf[1] = 0x24f; + isAdjustNoiseVar = true; + break; + case 7: + nphy_adj_tone_id_buf[0] = 121; + nphy_adj_tone_id_buf[1] = 122; + nphy_adj_noise_var_buf[0] = 0x18f; + nphy_adj_noise_var_buf[1] = 0x24f; + isAdjustNoiseVar = true; + break; + case 8: + nphy_adj_tone_id_buf[0] = 105; + nphy_adj_tone_id_buf[1] = 106; + nphy_adj_noise_var_buf[0] = 0x22f; + nphy_adj_noise_var_buf[1] = 0x25f; + isAdjustNoiseVar = true; + break; + case 9: + nphy_adj_tone_id_buf[0] = 89; + nphy_adj_tone_id_buf[1] = 90; + nphy_adj_noise_var_buf[0] = 0x22f; + nphy_adj_noise_var_buf[1] = 0x24f; + isAdjustNoiseVar = true; + break; + case 10: + nphy_adj_tone_id_buf[0] = 73; + nphy_adj_tone_id_buf[1] = 74; + nphy_adj_noise_var_buf[0] = 0x22f; + nphy_adj_noise_var_buf[1] = 0x24f; + isAdjustNoiseVar = true; + break; + default: + isAdjustNoiseVar = false; + break; + } + } + + if (isAdjustNoiseVar) { + numTonesAdjust = sizeof(nphy_adj_tone_id_buf) / + sizeof(nphy_adj_tone_id_buf[0]); + + wlc_phy_adjust_min_noisevar_nphy( + pi, + numTonesAdjust, + nphy_adj_tone_id_buf, + nphy_adj_noise_var_buf); + + tempval = 0; + + } else { + wlc_phy_adjust_min_noisevar_nphy(pi, 0, NULL, + NULL); + } + } + + if ((pi->nphy_aband_spurwar_en) && + (CHSPEC_IS5G(pi->radio_chanspec))) { + switch (cur_channel) { + case 54: + nphy_adj_tone_id_buf[0] = 32; + nphy_adj_noise_var_buf[0] = 0x25f; + break; + case 38: + case 102: + case 118: + nphy_adj_tone_id_buf[0] = 0; + nphy_adj_noise_var_buf[0] = 0x0; + break; + case 134: + nphy_adj_tone_id_buf[0] = 32; + nphy_adj_noise_var_buf[0] = 0x21f; + break; + case 151: + nphy_adj_tone_id_buf[0] = 16; + nphy_adj_noise_var_buf[0] = 0x23f; + break; + case 153: + case 161: + nphy_adj_tone_id_buf[0] = 48; + nphy_adj_noise_var_buf[0] = 0x23f; + break; + default: + nphy_adj_tone_id_buf[0] = 0; + nphy_adj_noise_var_buf[0] = 0x0; + break; + } + + if (nphy_adj_tone_id_buf[0] + && nphy_adj_noise_var_buf[0]) + wlc_phy_adjust_min_noisevar_nphy( + pi, 1, + nphy_adj_tone_id_buf, + nphy_adj_noise_var_buf); + else + wlc_phy_adjust_min_noisevar_nphy(pi, 0, NULL, + NULL); + } + + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, false); + } +} + +void wlc_phy_init_nphy(struct brcms_phy *pi) +{ + u16 val; + u16 clip1_ths[2]; + struct nphy_txgains target_gain; + u8 tx_pwr_ctrl_state; + bool do_nphy_cal = false; + uint core; + uint origidx, intr_val; + struct d11regs *regs; + u32 d11_clk_ctl_st; + bool do_rssi_cal = false; + + core = 0; + + if (!(pi->measure_hold & PHY_HOLD_FOR_SCAN)) + pi->measure_hold |= PHY_HOLD_FOR_NOT_ASSOC; + + if ((ISNPHY(pi)) && (NREV_GE(pi->pubpi.phy_rev, 5)) && + ((pi->sh->chippkg == BCM4717_PKG_ID) || + (pi->sh->chippkg == BCM4718_PKG_ID))) { + if ((pi->sh->boardflags & BFL_EXTLNA) && + (CHSPEC_IS2G(pi->radio_chanspec))) + ai_corereg(pi->sh->sih, SI_CC_IDX, + offsetof(struct chipcregs, chipcontrol), + 0x40, 0x40); + } + + if ((pi->nphy_gband_spurwar2_en) && CHSPEC_IS2G(pi->radio_chanspec) && + CHSPEC_IS40(pi->radio_chanspec)) { + + regs = (struct d11regs *) ai_switch_core(pi->sh->sih, + D11_CORE_ID, &origidx, + &intr_val); + d11_clk_ctl_st = R_REG(®s->clk_ctl_st); + AND_REG(®s->clk_ctl_st, + ~(CCS_FORCEHT | CCS_HTAREQ)); + + W_REG(®s->clk_ctl_st, d11_clk_ctl_st); + + ai_restore_core(pi->sh->sih, origidx, intr_val); + } + + pi->use_int_tx_iqlo_cal_nphy = + (PHY_IPA(pi) || + (NREV_GE(pi->pubpi.phy_rev, 7) || + (NREV_GE(pi->pubpi.phy_rev, 5) + && pi->sh->boardflags2 & BFL2_INTERNDET_TXIQCAL))); + + pi->internal_tx_iqlo_cal_tapoff_intpa_nphy = false; + + pi->nphy_deaf_count = 0; + + wlc_phy_tbl_init_nphy(pi); + + pi->nphy_crsminpwr_adjusted = false; + pi->nphy_noisevars_adjusted = false; + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + write_phy_reg(pi, 0xe7, 0); + write_phy_reg(pi, 0xec, 0); + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + write_phy_reg(pi, 0x342, 0); + write_phy_reg(pi, 0x343, 0); + write_phy_reg(pi, 0x346, 0); + write_phy_reg(pi, 0x347, 0); + } + write_phy_reg(pi, 0xe5, 0); + write_phy_reg(pi, 0xe6, 0); + } else { + write_phy_reg(pi, 0xec, 0); + } + + write_phy_reg(pi, 0x91, 0); + write_phy_reg(pi, 0x92, 0); + if (NREV_LT(pi->pubpi.phy_rev, 6)) { + write_phy_reg(pi, 0x93, 0); + write_phy_reg(pi, 0x94, 0); + } + + and_phy_reg(pi, 0xa1, ~3); + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + write_phy_reg(pi, 0x8f, 0); + write_phy_reg(pi, 0xa5, 0); + } else { + write_phy_reg(pi, 0xa5, 0); + } + + if (NREV_IS(pi->pubpi.phy_rev, 2)) + mod_phy_reg(pi, 0xdc, 0x00ff, 0x3b); + else if (NREV_LT(pi->pubpi.phy_rev, 2)) + mod_phy_reg(pi, 0xdc, 0x00ff, 0x40); + + write_phy_reg(pi, 0x203, 32); + write_phy_reg(pi, 0x201, 32); + + if (pi->sh->boardflags2 & BFL2_SKWRKFEM_BRD) + write_phy_reg(pi, 0x20d, 160); + else + write_phy_reg(pi, 0x20d, 184); + + write_phy_reg(pi, 0x13a, 200); + + write_phy_reg(pi, 0x70, 80); + + write_phy_reg(pi, 0x1ff, 48); + + if (NREV_LT(pi->pubpi.phy_rev, 8)) + wlc_phy_update_mimoconfig_nphy(pi, pi->n_preamble_override); + + wlc_phy_stf_chain_upd_nphy(pi); + + if (NREV_LT(pi->pubpi.phy_rev, 2)) { + write_phy_reg(pi, 0x180, 0xaa8); + write_phy_reg(pi, 0x181, 0x9a4); + } + + if (PHY_IPA(pi)) { + for (core = 0; core < pi->pubpi.phy_corenum; core++) { + + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 : + 0x29b, (0x1 << 0), (1) << 0); + + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x298 : + 0x29c, (0x1ff << 7), + (pi->nphy_papd_epsilon_offset[core]) << 7); + + } + + wlc_phy_ipa_set_tx_digi_filts_nphy(pi); + } else if (NREV_GE(pi->pubpi.phy_rev, 5)) { + wlc_phy_extpa_set_tx_digi_filts_nphy(pi); + } + + wlc_phy_workarounds_nphy(pi); + + wlapi_bmac_phyclk_fgc(pi->sh->physhim, ON); + + val = read_phy_reg(pi, 0x01); + write_phy_reg(pi, 0x01, val | BBCFG_RESETCCA); + write_phy_reg(pi, 0x01, val & (~BBCFG_RESETCCA)); + wlapi_bmac_phyclk_fgc(pi->sh->physhim, OFF); + + wlapi_bmac_macphyclk_set(pi->sh->physhim, ON); + + wlc_phy_pa_override_nphy(pi, OFF); + wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RX2TX); + wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX); + wlc_phy_pa_override_nphy(pi, ON); + + wlc_phy_classifier_nphy(pi, 0, 0); + wlc_phy_clip_det_nphy(pi, 0, clip1_ths); + + if (CHSPEC_IS2G(pi->radio_chanspec)) + wlc_phy_bphy_init_nphy(pi); + + tx_pwr_ctrl_state = pi->nphy_txpwrctrl; + wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF); + + wlc_phy_txpwr_fixpower_nphy(pi); + + wlc_phy_txpwrctrl_idle_tssi_nphy(pi); + + wlc_phy_txpwrctrl_pwr_setup_nphy(pi); + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + u32 *tx_pwrctrl_tbl = NULL; + u16 idx; + s16 pga_gn = 0; + s16 pad_gn = 0; + s32 rfpwr_offset; + + if (PHY_IPA(pi)) { + tx_pwrctrl_tbl = wlc_phy_get_ipa_gaintbl_nphy(pi); + } else { + if (CHSPEC_IS5G(pi->radio_chanspec)) { + if (NREV_IS(pi->pubpi.phy_rev, 3)) + tx_pwrctrl_tbl = + nphy_tpc_5GHz_txgain_rev3; + else if (NREV_IS(pi->pubpi.phy_rev, 4)) + tx_pwrctrl_tbl = + (pi->srom_fem5g.extpagain == + 3) ? + nphy_tpc_5GHz_txgain_HiPwrEPA : + nphy_tpc_5GHz_txgain_rev4; + else + tx_pwrctrl_tbl = + nphy_tpc_5GHz_txgain_rev5; + } else { + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + if (pi->pubpi.radiorev == 5) + tx_pwrctrl_tbl = + nphy_tpc_txgain_epa_2057rev5; + else if (pi->pubpi.radiorev == 3) + tx_pwrctrl_tbl = + nphy_tpc_txgain_epa_2057rev3; + } else { + if (NREV_GE(pi->pubpi.phy_rev, 5) && + (pi->srom_fem2g.extpagain == 3)) + tx_pwrctrl_tbl = + nphy_tpc_txgain_HiPwrEPA; + else + tx_pwrctrl_tbl = + nphy_tpc_txgain_rev3; + } + } + } + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 128, + 192, 32, tx_pwrctrl_tbl); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 128, + 192, 32, tx_pwrctrl_tbl); + + pi->nphy_gmval = (u16) ((*tx_pwrctrl_tbl >> 16) & 0x7000); + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + + for (idx = 0; idx < 128; idx++) { + pga_gn = (tx_pwrctrl_tbl[idx] >> 24) & 0xf; + pad_gn = (tx_pwrctrl_tbl[idx] >> 19) & 0x1f; + rfpwr_offset = get_rf_pwr_offset(pi, pga_gn, + pad_gn); + wlc_phy_table_write_nphy( + pi, + NPHY_TBL_ID_CORE1TXPWRCTL, + 1, 576 + idx, 32, + &rfpwr_offset); + wlc_phy_table_write_nphy( + pi, + NPHY_TBL_ID_CORE2TXPWRCTL, + 1, 576 + idx, 32, + &rfpwr_offset); + } + } else { + + for (idx = 0; idx < 128; idx++) { + pga_gn = (tx_pwrctrl_tbl[idx] >> 24) & 0xf; + if (CHSPEC_IS2G(pi->radio_chanspec)) + rfpwr_offset = (s16) + nphy_papd_pga_gain_delta_ipa_2g + [pga_gn]; + else + rfpwr_offset = (s16) + nphy_papd_pga_gain_delta_ipa_5g + [pga_gn]; + + wlc_phy_table_write_nphy( + pi, + NPHY_TBL_ID_CORE1TXPWRCTL, + 1, 576 + idx, 32, + &rfpwr_offset); + wlc_phy_table_write_nphy( + pi, + NPHY_TBL_ID_CORE2TXPWRCTL, + 1, 576 + idx, 32, + &rfpwr_offset); + } + + } + } else { + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 128, + 192, 32, nphy_tpc_txgain); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 128, + 192, 32, nphy_tpc_txgain); + } + + if (pi->sh->phyrxchain != 0x3) + wlc_phy_rxcore_setstate_nphy((struct brcms_phy_pub *) pi, + pi->sh->phyrxchain); + + if (PHY_PERICAL_MPHASE_PENDING(pi)) + wlc_phy_cal_perical_mphase_restart(pi); + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + do_rssi_cal = (CHSPEC_IS2G(pi->radio_chanspec)) ? + (pi->nphy_rssical_chanspec_2G == 0) : + (pi->nphy_rssical_chanspec_5G == 0); + + if (do_rssi_cal) + wlc_phy_rssi_cal_nphy(pi); + else + wlc_phy_restore_rssical_nphy(pi); + } else { + wlc_phy_rssi_cal_nphy(pi); + } + + if (!SCAN_RM_IN_PROGRESS(pi)) + do_nphy_cal = (CHSPEC_IS2G(pi->radio_chanspec)) ? + (pi->nphy_iqcal_chanspec_2G == 0) : + (pi->nphy_iqcal_chanspec_5G == 0); + + if (!pi->do_initcal) + do_nphy_cal = false; + + if (do_nphy_cal) { + + target_gain = wlc_phy_get_tx_gain_nphy(pi); + + if (pi->antsel_type == ANTSEL_2x3) + wlc_phy_antsel_init((struct brcms_phy_pub *) pi, + true); + + if (pi->nphy_perical != PHY_PERICAL_MPHASE) { + wlc_phy_rssi_cal_nphy(pi); + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + pi->nphy_cal_orig_pwr_idx[0] = + pi->nphy_txpwrindex[PHY_CORE_0] + . + index_internal; + pi->nphy_cal_orig_pwr_idx[1] = + pi->nphy_txpwrindex[PHY_CORE_1] + . + index_internal; + + wlc_phy_precal_txgain_nphy(pi); + target_gain = + wlc_phy_get_tx_gain_nphy(pi); + } + + if (wlc_phy_cal_txiqlo_nphy + (pi, target_gain, true, + false) == 0) { + if (wlc_phy_cal_rxiq_nphy + (pi, target_gain, 2, + false) == 0) + wlc_phy_savecal_nphy(pi); + + } + } else if (pi->mphase_cal_phase_id == + MPHASE_CAL_STATE_IDLE) { + wlc_phy_cal_perical((struct brcms_phy_pub *) pi, + PHY_PERICAL_PHYINIT); + } + } else { + wlc_phy_restorecal_nphy(pi); + } + + wlc_phy_txpwrctrl_coeff_setup_nphy(pi); + + wlc_phy_txpwrctrl_enable_nphy(pi, tx_pwr_ctrl_state); + + wlc_phy_nphy_tkip_rifs_war(pi, pi->sh->_rifs_phy); + + if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LE(pi->pubpi.phy_rev, 6)) + + write_phy_reg(pi, 0x70, 50); + + wlc_phy_txlpfbw_nphy(pi); + + wlc_phy_spurwar_nphy(pi); + +} + +static void wlc_phy_resetcca_nphy(struct brcms_phy *pi) +{ + u16 val; + + wlapi_bmac_phyclk_fgc(pi->sh->physhim, ON); + + val = read_phy_reg(pi, 0x01); + write_phy_reg(pi, 0x01, val | BBCFG_RESETCCA); + udelay(1); + write_phy_reg(pi, 0x01, val & (~BBCFG_RESETCCA)); + + wlapi_bmac_phyclk_fgc(pi->sh->physhim, OFF); + + wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX); +} + +void wlc_phy_pa_override_nphy(struct brcms_phy *pi, bool en) +{ + u16 rfctrlintc_override_val; + + if (!en) { + + pi->rfctrlIntc1_save = read_phy_reg(pi, 0x91); + pi->rfctrlIntc2_save = read_phy_reg(pi, 0x92); + + if (NREV_GE(pi->pubpi.phy_rev, 7)) + rfctrlintc_override_val = 0x1480; + else if (NREV_GE(pi->pubpi.phy_rev, 3)) + rfctrlintc_override_val = + CHSPEC_IS5G(pi->radio_chanspec) ? 0x600 : 0x480; + else + rfctrlintc_override_val = + CHSPEC_IS5G(pi->radio_chanspec) ? 0x180 : 0x120; + + write_phy_reg(pi, 0x91, rfctrlintc_override_val); + write_phy_reg(pi, 0x92, rfctrlintc_override_val); + } else { + write_phy_reg(pi, 0x91, pi->rfctrlIntc1_save); + write_phy_reg(pi, 0x92, pi->rfctrlIntc2_save); + } + +} + +void wlc_phy_stf_chain_upd_nphy(struct brcms_phy *pi) +{ + + u16 txrx_chain = + (NPHY_RfseqCoreActv_TxRxChain0 | NPHY_RfseqCoreActv_TxRxChain1); + bool CoreActv_override = false; + + if (pi->nphy_txrx_chain == BRCMS_N_TXRX_CHAIN0) { + txrx_chain = NPHY_RfseqCoreActv_TxRxChain0; + CoreActv_override = true; + + if (NREV_LE(pi->pubpi.phy_rev, 2)) + and_phy_reg(pi, 0xa0, ~0x20); + } else if (pi->nphy_txrx_chain == BRCMS_N_TXRX_CHAIN1) { + txrx_chain = NPHY_RfseqCoreActv_TxRxChain1; + CoreActv_override = true; + + if (NREV_LE(pi->pubpi.phy_rev, 2)) + or_phy_reg(pi, 0xa0, 0x20); + } + + mod_phy_reg(pi, 0xa2, ((0xf << 0) | (0xf << 4)), txrx_chain); + + if (CoreActv_override) { + pi->nphy_perical = PHY_PERICAL_DISABLE; + or_phy_reg(pi, 0xa1, NPHY_RfseqMode_CoreActv_override); + } else { + pi->nphy_perical = PHY_PERICAL_MPHASE; + and_phy_reg(pi, 0xa1, ~NPHY_RfseqMode_CoreActv_override); + } +} + +void wlc_phy_rxcore_setstate_nphy(struct brcms_phy_pub *pih, u8 rxcore_bitmask) +{ + u16 regval; + u16 tbl_buf[16]; + uint i; + struct brcms_phy *pi = (struct brcms_phy *) pih; + u16 tbl_opcode; + bool suspend; + + pi->sh->phyrxchain = rxcore_bitmask; + + if (!pi->sh->clk) return; - and_radio_reg(pi, RADIO_2055_CAL_LPO_CNTRL, - ~(RADIO_2055_CAL_LPO_ENABLE)); + suspend = (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); + if (!suspend) + wlapi_suspend_mac_and_wait(pi->sh->physhim); - wlc_phy_chanspec_set((struct brcms_phy_pub *) pi, pi->radio_chanspec); + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, true); - write_radio_reg(pi, RADIO_2055_CORE1_RXBB_LPF, 9); - write_radio_reg(pi, RADIO_2055_CORE2_RXBB_LPF, 9); + regval = read_phy_reg(pi, 0xa2); + regval &= ~(0xf << 4); + regval |= ((u16) (rxcore_bitmask & 0x3)) << 4; + write_phy_reg(pi, 0xa2, regval); - write_radio_reg(pi, RADIO_2055_CORE1_RXBB_MIDAC_HIPAS, 0x83); - write_radio_reg(pi, RADIO_2055_CORE2_RXBB_MIDAC_HIPAS, 0x83); + if ((rxcore_bitmask & 0x3) != 0x3) { - mod_radio_reg(pi, RADIO_2055_CORE1_LNA_GAINBST, - RADIO_2055_GAINBST_VAL_MASK, RADIO_2055_GAINBST_CODE); - mod_radio_reg(pi, RADIO_2055_CORE2_LNA_GAINBST, - RADIO_2055_GAINBST_VAL_MASK, RADIO_2055_GAINBST_CODE); - if (pi->nphy_gain_boost) { - and_radio_reg(pi, RADIO_2055_CORE1_RXRF_SPC1, - ~(RADIO_2055_GAINBST_DISABLE)); - and_radio_reg(pi, RADIO_2055_CORE2_RXRF_SPC1, - ~(RADIO_2055_GAINBST_DISABLE)); + write_phy_reg(pi, 0x20e, 1); + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + if (pi->rx2tx_biasentry == -1) { + wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, + ARRAY_SIZE(tbl_buf), 80, + 16, tbl_buf); + + for (i = 0; i < ARRAY_SIZE(tbl_buf); i++) { + if (tbl_buf[i] == + NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS) { + pi->rx2tx_biasentry = (u8) i; + tbl_opcode = + NPHY_REV3_RFSEQ_CMD_NOP; + wlc_phy_table_write_nphy( + pi, + NPHY_TBL_ID_RFSEQ, + 1, i, + 16, + &tbl_opcode); + break; + } else if (tbl_buf[i] == + NPHY_REV3_RFSEQ_CMD_END) + break; + } + } + } } else { - or_radio_reg(pi, RADIO_2055_CORE1_RXRF_SPC1, - RADIO_2055_GAINBST_DISABLE); - or_radio_reg(pi, RADIO_2055_CORE2_RXRF_SPC1, - RADIO_2055_GAINBST_DISABLE); + + write_phy_reg(pi, 0x20e, 30); + + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + if (pi->rx2tx_biasentry != -1) { + tbl_opcode = NPHY_REV3_RFSEQ_CMD_CLR_RXRX_BIAS; + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, + 1, pi->rx2tx_biasentry, + 16, &tbl_opcode); + pi->rx2tx_biasentry = -1; + } + } } - udelay(2); + wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX); + + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, false); + + if (!suspend) + wlapi_enable_mac(pi->sh->physhim); +} + +u8 wlc_phy_rxcore_getstate_nphy(struct brcms_phy_pub *pih) +{ + u16 regval, rxen_bits; + struct brcms_phy *pi = (struct brcms_phy *) pih; + + regval = read_phy_reg(pi, 0xa2); + rxen_bits = (regval >> 4) & 0xf; + + return (u8) rxen_bits; +} + +bool wlc_phy_n_txpower_ipa_ison(struct brcms_phy *pi) +{ + return PHY_IPA(pi); +} + +void wlc_phy_cal_init_nphy(struct brcms_phy *pi) +{ } static void wlc_phy_radio_preinit_205x(struct brcms_phy *pi) @@ -17442,6 +19892,252 @@ static void wlc_phy_radio_preinit_205x(struct brcms_phy *pi) } +static void wlc_phy_radio_init_2057(struct brcms_phy *pi) +{ + struct radio_20xx_regs *regs_2057_ptr = NULL; + + if (NREV_IS(pi->pubpi.phy_rev, 7)) { + regs_2057_ptr = regs_2057_rev4; + } else if (NREV_IS(pi->pubpi.phy_rev, 8) + || NREV_IS(pi->pubpi.phy_rev, 9)) { + switch (pi->pubpi.radiorev) { + case 5: + + if (pi->pubpi.radiover == 0x0) + regs_2057_ptr = regs_2057_rev5; + else if (pi->pubpi.radiover == 0x1) + regs_2057_ptr = regs_2057_rev5v1; + else + break; + + case 7: + + regs_2057_ptr = regs_2057_rev7; + break; + + case 8: + + regs_2057_ptr = regs_2057_rev8; + break; + + default: + break; + } + } + + wlc_phy_init_radio_regs_allbands(pi, regs_2057_ptr); +} + +static u16 wlc_phy_radio205x_rcal(struct brcms_phy *pi) +{ + u16 rcal_reg = 0; + int i; + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + + if (pi->pubpi.radiorev == 5) { + + and_phy_reg(pi, 0x342, ~(0x1 << 1)); + + udelay(10); + + mod_radio_reg(pi, RADIO_2057_IQTEST_SEL_PU, 0x1, 0x1); + mod_radio_reg(pi, RADIO_2057v7_IQTEST_SEL_PU2, 0x2, + 0x1); + } + mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x1, 0x1); + + udelay(10); + + mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x3, 0x3); + + for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) { + rcal_reg = read_radio_reg(pi, RADIO_2057_RCAL_STATUS); + if (rcal_reg & 0x1) + break; + + udelay(100); + } + + if (WARN(i == MAX_205x_RCAL_WAITLOOPS, + "HW error: radio calib2")) + return 0; + + mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x2, 0x0); + + rcal_reg = read_radio_reg(pi, RADIO_2057_RCAL_STATUS) & 0x3e; + + mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x1, 0x0); + if (pi->pubpi.radiorev == 5) { + + mod_radio_reg(pi, RADIO_2057_IQTEST_SEL_PU, 0x1, 0x0); + mod_radio_reg(pi, RADIO_2057v7_IQTEST_SEL_PU2, 0x2, + 0x0); + } + + if ((pi->pubpi.radiorev <= 4) || (pi->pubpi.radiorev == 6)) { + + mod_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG, 0x3c, + rcal_reg); + mod_radio_reg(pi, RADIO_2057_BANDGAP_RCAL_TRIM, 0xf0, + rcal_reg << 2); + } + + } else if (NREV_IS(pi->pubpi.phy_rev, 3)) { + u16 savereg; + + savereg = + read_radio_reg( + pi, + RADIO_2056_SYN_PLL_MAST2 | + RADIO_2056_SYN); + write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2 | RADIO_2056_SYN, + savereg | 0x7); + udelay(10); + + write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN, + 0x1); + udelay(10); + + write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN, + 0x9); + + for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) { + rcal_reg = read_radio_reg( + pi, + RADIO_2056_SYN_RCAL_CODE_OUT | + RADIO_2056_SYN); + if (rcal_reg & 0x80) + break; + + udelay(100); + } + + if (WARN(i == MAX_205x_RCAL_WAITLOOPS, + "HW error: radio calib3")) + return 0; + + write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN, + 0x1); + + rcal_reg = + read_radio_reg(pi, + RADIO_2056_SYN_RCAL_CODE_OUT | + RADIO_2056_SYN); + + write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN, + 0x0); + + write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2 | RADIO_2056_SYN, + savereg); + + return rcal_reg & 0x1f; + } + return rcal_reg & 0x3e; +} + +static u16 wlc_phy_radio2057_rccal(struct brcms_phy *pi) +{ + u16 rccal_valid; + int i; + bool chip43226_6362A0; + + chip43226_6362A0 = ((pi->pubpi.radiorev == 3) + || (pi->pubpi.radiorev == 4) + || (pi->pubpi.radiorev == 6)); + + rccal_valid = 0; + if (chip43226_6362A0) { + write_radio_reg(pi, RADIO_2057_RCCAL_MASTER, 0x61); + write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xc0); + } else { + write_radio_reg(pi, RADIO_2057v7_RCCAL_MASTER, 0x61); + + write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xe9); + } + write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x6e); + write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x55); + + for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) { + rccal_valid = read_radio_reg(pi, RADIO_2057_RCCAL_DONE_OSCCAP); + if (rccal_valid & 0x2) + break; + + udelay(500); + } + + write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15); + + rccal_valid = 0; + if (chip43226_6362A0) { + write_radio_reg(pi, RADIO_2057_RCCAL_MASTER, 0x69); + write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xb0); + } else { + write_radio_reg(pi, RADIO_2057v7_RCCAL_MASTER, 0x69); + + write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xd5); + } + write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x6e); + write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x55); + + for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) { + rccal_valid = read_radio_reg(pi, RADIO_2057_RCCAL_DONE_OSCCAP); + if (rccal_valid & 0x2) + break; + + udelay(500); + } + + write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15); + + rccal_valid = 0; + if (chip43226_6362A0) { + write_radio_reg(pi, RADIO_2057_RCCAL_MASTER, 0x73); + + write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x28); + write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xb0); + } else { + write_radio_reg(pi, RADIO_2057v7_RCCAL_MASTER, 0x73); + write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x6e); + write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0x99); + } + write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x55); + + for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) { + rccal_valid = read_radio_reg(pi, RADIO_2057_RCCAL_DONE_OSCCAP); + if (rccal_valid & 0x2) + break; + + udelay(500); + } + + if (WARN(!(rccal_valid & 0x2), "HW error: radio calib4")) + return 0; + + write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15); + + return rccal_valid; +} + +static void wlc_phy_radio_postinit_2057(struct brcms_phy *pi) +{ + + mod_radio_reg(pi, RADIO_2057_XTALPUOVR_PINCTRL, 0x1, 0x1); + + mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x78, 0x78); + mod_radio_reg(pi, RADIO_2057_XTAL_CONFIG2, 0x80, 0x80); + mdelay(2); + mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x78, 0x0); + mod_radio_reg(pi, RADIO_2057_XTAL_CONFIG2, 0x80, 0x0); + + if (pi->phy_init_por) { + wlc_phy_radio205x_rcal(pi); + wlc_phy_radio2057_rccal(pi); + } + + mod_radio_reg(pi, RADIO_2057_RFPLL_MASTER, 0x8, 0x0); +} + static void wlc_phy_radio_init_2056(struct brcms_phy *pi) { struct radio_regs *regs_SYN_2056_ptr = NULL; @@ -17515,79 +20211,177 @@ static void wlc_phy_radio_postinit_2056(struct brcms_phy *pi) mod_radio_reg(pi, RADIO_2056_SYN_COM_RESET, 0x2, 0x0); if ((pi->sh->boardflags2 & BFL2_LEGACY) - || (pi->sh->boardflags2 & BFL2_XTALBUFOUTEN)) { - + || (pi->sh->boardflags2 & BFL2_XTALBUFOUTEN)) mod_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2, 0xf4, 0x0); - } else { - + else mod_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2, 0xfc, 0x0); - } mod_radio_reg(pi, RADIO_2056_SYN_RCCAL_CTRL0, 0x1, 0x0); - if (pi->phy_init_por) { + if (pi->phy_init_por) wlc_phy_radio205x_rcal(pi); - } } -static void wlc_phy_radio_init_2057(struct brcms_phy *pi) +static void wlc_phy_radio_preinit_2055(struct brcms_phy *pi) { - struct radio_20xx_regs *regs_2057_ptr = NULL; - if (NREV_IS(pi->pubpi.phy_rev, 7)) { + and_phy_reg(pi, 0x78, ~RFCC_POR_FORCE); + or_phy_reg(pi, 0x78, RFCC_CHIP0_PU | RFCC_OE_POR_FORCE); - regs_2057_ptr = regs_2057_rev4; - } else if (NREV_IS(pi->pubpi.phy_rev, 8) - || NREV_IS(pi->pubpi.phy_rev, 9)) { - switch (pi->pubpi.radiorev) { - case 5: + or_phy_reg(pi, 0x78, RFCC_POR_FORCE); +} - if (pi->pubpi.radiover == 0x0) { +static void wlc_phy_radio_init_2055(struct brcms_phy *pi) +{ + wlc_phy_init_radio_regs(pi, regs_2055, RADIO_DEFAULT_CORE); +} - regs_2057_ptr = regs_2057_rev5; +static void wlc_phy_radio_postinit_2055(struct brcms_phy *pi) +{ - } else if (pi->pubpi.radiover == 0x1) { + and_radio_reg(pi, RADIO_2055_MASTER_CNTRL1, + ~(RADIO_2055_JTAGCTRL_MASK | RADIO_2055_JTAGSYNC_MASK)); - regs_2057_ptr = regs_2057_rev5v1; - } else { - break; - } + if (((pi->sh->sromrev >= 4) + && !(pi->sh->boardflags2 & BFL2_RXBB_INT_REG_DIS)) + || ((pi->sh->sromrev < 4))) { + and_radio_reg(pi, RADIO_2055_CORE1_RXBB_REGULATOR, 0x7F); + and_radio_reg(pi, RADIO_2055_CORE2_RXBB_REGULATOR, 0x7F); + } - case 7: + mod_radio_reg(pi, RADIO_2055_RRCCAL_N_OPT_SEL, 0x3F, 0x2C); + write_radio_reg(pi, RADIO_2055_CAL_MISC, 0x3C); - regs_2057_ptr = regs_2057_rev7; - break; + and_radio_reg(pi, RADIO_2055_CAL_MISC, + ~(RADIO_2055_RRCAL_START | RADIO_2055_RRCAL_RST_N)); - case 8: + or_radio_reg(pi, RADIO_2055_CAL_LPO_CNTRL, RADIO_2055_CAL_LPO_ENABLE); - regs_2057_ptr = regs_2057_rev8; - break; + or_radio_reg(pi, RADIO_2055_CAL_MISC, RADIO_2055_RRCAL_RST_N); - default: - break; - } + udelay(1000); + + or_radio_reg(pi, RADIO_2055_CAL_MISC, RADIO_2055_RRCAL_START); + + SPINWAIT(((read_radio_reg(pi, RADIO_2055_CAL_COUNTER_OUT2) & + RADIO_2055_RCAL_DONE) != RADIO_2055_RCAL_DONE), 2000); + + if (WARN((read_radio_reg(pi, RADIO_2055_CAL_COUNTER_OUT2) & + RADIO_2055_RCAL_DONE) != RADIO_2055_RCAL_DONE, + "HW error: radio calibration1\n")) + return; + + and_radio_reg(pi, RADIO_2055_CAL_LPO_CNTRL, + ~(RADIO_2055_CAL_LPO_ENABLE)); + + wlc_phy_chanspec_set((struct brcms_phy_pub *) pi, pi->radio_chanspec); + + write_radio_reg(pi, RADIO_2055_CORE1_RXBB_LPF, 9); + write_radio_reg(pi, RADIO_2055_CORE2_RXBB_LPF, 9); + + write_radio_reg(pi, RADIO_2055_CORE1_RXBB_MIDAC_HIPAS, 0x83); + write_radio_reg(pi, RADIO_2055_CORE2_RXBB_MIDAC_HIPAS, 0x83); + + mod_radio_reg(pi, RADIO_2055_CORE1_LNA_GAINBST, + RADIO_2055_GAINBST_VAL_MASK, RADIO_2055_GAINBST_CODE); + mod_radio_reg(pi, RADIO_2055_CORE2_LNA_GAINBST, + RADIO_2055_GAINBST_VAL_MASK, RADIO_2055_GAINBST_CODE); + if (pi->nphy_gain_boost) { + and_radio_reg(pi, RADIO_2055_CORE1_RXRF_SPC1, + ~(RADIO_2055_GAINBST_DISABLE)); + and_radio_reg(pi, RADIO_2055_CORE2_RXRF_SPC1, + ~(RADIO_2055_GAINBST_DISABLE)); + } else { + or_radio_reg(pi, RADIO_2055_CORE1_RXRF_SPC1, + RADIO_2055_GAINBST_DISABLE); + or_radio_reg(pi, RADIO_2055_CORE2_RXRF_SPC1, + RADIO_2055_GAINBST_DISABLE); } - wlc_phy_init_radio_regs_allbands(pi, regs_2057_ptr); + udelay(2); } -static void wlc_phy_radio_postinit_2057(struct brcms_phy *pi) +void wlc_phy_switch_radio_nphy(struct brcms_phy *pi, bool on) { + if (on) { + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + if (!pi->radio_is_on) { + wlc_phy_radio_preinit_205x(pi); + wlc_phy_radio_init_2057(pi); + wlc_phy_radio_postinit_2057(pi); + } - mod_radio_reg(pi, RADIO_2057_XTALPUOVR_PINCTRL, 0x1, 0x1); + wlc_phy_chanspec_set((struct brcms_phy_pub *) pi, + pi->radio_chanspec); + } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { + wlc_phy_radio_preinit_205x(pi); + wlc_phy_radio_init_2056(pi); + wlc_phy_radio_postinit_2056(pi); - mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x78, 0x78); - mod_radio_reg(pi, RADIO_2057_XTAL_CONFIG2, 0x80, 0x80); - mdelay(2); - mod_radio_reg(pi, RADIO_2057_RFPLL_MISC_CAL_RESETN, 0x78, 0x0); - mod_radio_reg(pi, RADIO_2057_XTAL_CONFIG2, 0x80, 0x0); + wlc_phy_chanspec_set((struct brcms_phy_pub *) pi, + pi->radio_chanspec); + } else { + wlc_phy_radio_preinit_2055(pi); + wlc_phy_radio_init_2055(pi); + wlc_phy_radio_postinit_2055(pi); + } - if (pi->phy_init_por) { - wlc_phy_radio205x_rcal(pi); - wlc_phy_radio2057_rccal(pi); - } + pi->radio_is_on = true; - mod_radio_reg(pi, RADIO_2057_RFPLL_MASTER, 0x8, 0x0); + } else { + + if (NREV_GE(pi->pubpi.phy_rev, 3) + && NREV_LT(pi->pubpi.phy_rev, 7)) { + and_phy_reg(pi, 0x78, ~RFCC_CHIP0_PU); + mod_radio_reg(pi, RADIO_2056_SYN_COM_PU, 0x2, 0x0); + + write_radio_reg(pi, + RADIO_2056_TX_PADA_BOOST_TUNE | + RADIO_2056_TX0, 0); + write_radio_reg(pi, + RADIO_2056_TX_PADG_BOOST_TUNE | + RADIO_2056_TX0, 0); + write_radio_reg(pi, + RADIO_2056_TX_PGAA_BOOST_TUNE | + RADIO_2056_TX0, 0); + write_radio_reg(pi, + RADIO_2056_TX_PGAG_BOOST_TUNE | + RADIO_2056_TX0, 0); + mod_radio_reg(pi, + RADIO_2056_TX_MIXA_BOOST_TUNE | + RADIO_2056_TX0, 0xf0, 0); + write_radio_reg(pi, + RADIO_2056_TX_MIXG_BOOST_TUNE | + RADIO_2056_TX0, 0); + + write_radio_reg(pi, + RADIO_2056_TX_PADA_BOOST_TUNE | + RADIO_2056_TX1, 0); + write_radio_reg(pi, + RADIO_2056_TX_PADG_BOOST_TUNE | + RADIO_2056_TX1, 0); + write_radio_reg(pi, + RADIO_2056_TX_PGAA_BOOST_TUNE | + RADIO_2056_TX1, 0); + write_radio_reg(pi, + RADIO_2056_TX_PGAG_BOOST_TUNE | + RADIO_2056_TX1, 0); + mod_radio_reg(pi, + RADIO_2056_TX_MIXA_BOOST_TUNE | + RADIO_2056_TX1, 0xf0, 0); + write_radio_reg(pi, + RADIO_2056_TX_MIXG_BOOST_TUNE | + RADIO_2056_TX1, 0); + + pi->radio_is_on = false; + } + + if (NREV_GE(pi->pubpi.phy_rev, 8)) { + and_phy_reg(pi, 0x78, ~RFCC_CHIP0_PU); + pi->radio_is_on = false; + } + + } } static bool @@ -17621,40 +20415,35 @@ wlc_phy_chan2freq_nphy(struct brcms_phy *pi, uint channel, int *f, if (pi->pubpi.radiover == 0x0) { chan_info_tbl_p_2 = - chan_info_nphyrev8_2057_rev5; - tbl_len = - ARRAY_SIZE - (chan_info_nphyrev8_2057_rev5); + chan_info_nphyrev8_2057_rev5; + tbl_len = ARRAY_SIZE( + chan_info_nphyrev8_2057_rev5); } else if (pi->pubpi.radiover == 0x1) { chan_info_tbl_p_2 = - chan_info_nphyrev9_2057_rev5v1; - tbl_len = - ARRAY_SIZE - (chan_info_nphyrev9_2057_rev5v1); + chan_info_nphyrev9_2057_rev5v1; + tbl_len = ARRAY_SIZE( + chan_info_nphyrev9_2057_rev5v1); } break; case 7: chan_info_tbl_p_0 = - chan_info_nphyrev8_2057_rev7; - tbl_len = - ARRAY_SIZE(chan_info_nphyrev8_2057_rev7); + chan_info_nphyrev8_2057_rev7; + tbl_len = ARRAY_SIZE( + chan_info_nphyrev8_2057_rev7); break; case 8: chan_info_tbl_p_0 = - chan_info_nphyrev8_2057_rev8; - tbl_len = - ARRAY_SIZE(chan_info_nphyrev8_2057_rev8); + chan_info_nphyrev8_2057_rev8; + tbl_len = ARRAY_SIZE( + chan_info_nphyrev8_2057_rev8); break; default: - if (NORADIO_ENAB(pi->pubpi)) { - goto fail; - } break; } } else if (NREV_IS(pi->pubpi.phy_rev, 16)) { @@ -17677,9 +20466,9 @@ wlc_phy_chan2freq_nphy(struct brcms_phy *pi, uint channel, int *f, } } - if (i >= tbl_len) { + if (i >= tbl_len) goto fail; - } + if (pi->pubpi.radiorev == 5) { *t2 = &chan_info_tbl_p_2[i]; freq = chan_info_tbl_p_2[i].freq; @@ -17710,7 +20499,7 @@ wlc_phy_chan2freq_nphy(struct brcms_phy *pi, uint channel, int *f, case 9: chan_info_tbl_p_1 = chan_info_nphyrev5n6_2056v7; tbl_len = - ARRAY_SIZE(chan_info_nphyrev5n6_2056v7); + ARRAY_SIZE(chan_info_nphyrev5n6_2056v7); break; case 8: chan_info_tbl_p_1 = chan_info_nphyrev6_2056v8; @@ -17718,12 +20507,10 @@ wlc_phy_chan2freq_nphy(struct brcms_phy *pi, uint channel, int *f, break; case 11: chan_info_tbl_p_1 = chan_info_nphyrev6_2056v11; - tbl_len = ARRAY_SIZE(chan_info_nphyrev6_2056v11); + tbl_len = ARRAY_SIZE( + chan_info_nphyrev6_2056v11); break; default: - if (NORADIO_ENAB(pi->pubpi)) { - goto fail; - } break; } } @@ -17733,9 +20520,9 @@ wlc_phy_chan2freq_nphy(struct brcms_phy *pi, uint channel, int *f, break; } - if (i >= tbl_len) { + if (i >= tbl_len) goto fail; - } + *t1 = &chan_info_tbl_p_1[i]; freq = chan_info_tbl_p_1[i].freq; @@ -17744,9 +20531,9 @@ wlc_phy_chan2freq_nphy(struct brcms_phy *pi, uint channel, int *f, if (chan_info_nphy_2055[i].chan == channel) break; - if (i >= ARRAY_SIZE(chan_info_nphy_2055)) { + if (i >= ARRAY_SIZE(chan_info_nphy_2055)) goto fail; - } + *t3 = &chan_info_nphy_2055[i]; freq = chan_info_nphy_2055[i].freq; } @@ -17754,7 +20541,7 @@ wlc_phy_chan2freq_nphy(struct brcms_phy *pi, uint channel, int *f, *f = freq; return true; - fail: +fail: *f = WL_CHAN_FREQ_RANGE_2G; return false; } @@ -17767,9 +20554,6 @@ u8 wlc_phy_get_chan_freq_range_nphy(struct brcms_phy *pi, uint channel) struct chan_info_nphy_radio2057_rev5 *t2 = NULL; struct chan_info_nphy_2055 *t3 = NULL; - if (NORADIO_ENAB(pi->pubpi)) - return WL_CHAN_FREQ_RANGE_2G; - if (channel == 0) channel = CHSPEC_CHANNEL(pi->radio_chanspec); @@ -17778,13 +20562,12 @@ u8 wlc_phy_get_chan_freq_range_nphy(struct brcms_phy *pi, uint channel) if (CHSPEC_IS2G(pi->radio_chanspec)) return WL_CHAN_FREQ_RANGE_2G; - if ((freq >= BASE_LOW_5G_CHAN) && (freq < BASE_MID_5G_CHAN)) { + if ((freq >= BASE_LOW_5G_CHAN) && (freq < BASE_MID_5G_CHAN)) return WL_CHAN_FREQ_RANGE_5GL; - } else if ((freq >= BASE_MID_5G_CHAN) && (freq < BASE_HIGH_5G_CHAN)) { + else if ((freq >= BASE_MID_5G_CHAN) && (freq < BASE_HIGH_5G_CHAN)) return WL_CHAN_FREQ_RANGE_5GM; - } else { + else return WL_CHAN_FREQ_RANGE_5GH; - } } static void @@ -17960,15 +20743,14 @@ wlc_phy_chanspec_radio2056_setup(struct brcms_phy *pi, break; } } - if (CHSPEC_IS2G(pi->radio_chanspec)) { + if (CHSPEC_IS2G(pi->radio_chanspec)) write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 | RADIO_2056_SYN, (u16) regs_SYN_2056_ptr[0x49 - 2].init_g); - } else { + else write_radio_reg(pi, RADIO_2056_SYN_PLL_CP2 | RADIO_2056_SYN, (u16) regs_SYN_2056_ptr[0x49 - 2].init_a); - } if (pi->sh->boardflags2 & BFL2_GPLL_WAR) { if (CHSPEC_IS2G(pi->radio_chanspec)) { @@ -18116,11 +20898,11 @@ wlc_phy_chanspec_radio2056_setup(struct brcms_phy *pi, paa_boost_tune = 0x0; pada_boost_tune = 0x77; - if (freq != 5825) { + if (freq != 5825) pgaa_boost_tune = -(int)(freq - 18) / 36 + 168; - } else { + else pgaa_boost_tune = 6; - } + mixa_boost_tune = 0xf; } @@ -18146,9 +20928,8 @@ wlc_phy_chanspec_radio2056_setup(struct brcms_phy *pi, if ((pi->sh->chip == BCM43224_CHIP_ID) || (pi->sh->chip == BCM43225_CHIP_ID)) { - if (pi->sh->chippkg == BCM43224_FAB_SMIC) { + if (pi->sh->chippkg == BCM43224_FAB_SMIC) cascbias = 0x35; - } } pabias = (pi->phy_pabias == 0) ? 0x30 : pi->phy_pabias; @@ -18186,117 +20967,12 @@ void wlc_phy_radio205x_vcocal_nphy(struct brcms_phy *pi) udelay(300); } -#define MAX_205x_RCAL_WAITLOOPS 10000 - -static u16 wlc_phy_radio205x_rcal(struct brcms_phy *pi) -{ - u16 rcal_reg = 0; - int i; - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - - if (pi->pubpi.radiorev == 5) { - - and_phy_reg(pi, 0x342, ~(0x1 << 1)); - - udelay(10); - - mod_radio_reg(pi, RADIO_2057_IQTEST_SEL_PU, 0x1, 0x1); - mod_radio_reg(pi, RADIO_2057v7_IQTEST_SEL_PU2, 0x2, - 0x1); - } - mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x1, 0x1); - - udelay(10); - - mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x3, 0x3); - - for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) { - rcal_reg = read_radio_reg(pi, RADIO_2057_RCAL_STATUS); - if (rcal_reg & 0x1) { - break; - } - udelay(100); - } - - if (WARN(i == MAX_205x_RCAL_WAITLOOPS, - "HW error: radio calib2")) - return 0; - - mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x2, 0x0); - - rcal_reg = read_radio_reg(pi, RADIO_2057_RCAL_STATUS) & 0x3e; - - mod_radio_reg(pi, RADIO_2057_RCAL_CONFIG, 0x1, 0x0); - if (pi->pubpi.radiorev == 5) { - - mod_radio_reg(pi, RADIO_2057_IQTEST_SEL_PU, 0x1, 0x0); - mod_radio_reg(pi, RADIO_2057v7_IQTEST_SEL_PU2, 0x2, - 0x0); - } - - if ((pi->pubpi.radiorev <= 4) || (pi->pubpi.radiorev == 6)) { - - mod_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG, 0x3c, - rcal_reg); - mod_radio_reg(pi, RADIO_2057_BANDGAP_RCAL_TRIM, 0xf0, - rcal_reg << 2); - } - - } else if (NREV_IS(pi->pubpi.phy_rev, 3)) { - u16 savereg; - - savereg = - read_radio_reg(pi, - RADIO_2056_SYN_PLL_MAST2 | RADIO_2056_SYN); - write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2 | RADIO_2056_SYN, - savereg | 0x7); - udelay(10); - - write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN, - 0x1); - udelay(10); - - write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN, - 0x9); - - for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) { - rcal_reg = read_radio_reg(pi, - RADIO_2056_SYN_RCAL_CODE_OUT | - RADIO_2056_SYN); - if (rcal_reg & 0x80) { - break; - } - udelay(100); - } - - if (WARN(i == MAX_205x_RCAL_WAITLOOPS, - "HW error: radio calib3")) - return 0; - - write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN, - 0x1); - - rcal_reg = - read_radio_reg(pi, - RADIO_2056_SYN_RCAL_CODE_OUT | - RADIO_2056_SYN); - - write_radio_reg(pi, RADIO_2056_SYN_RCAL_MASTER | RADIO_2056_SYN, - 0x0); - - write_radio_reg(pi, RADIO_2056_SYN_PLL_MAST2 | RADIO_2056_SYN, - savereg); - - return rcal_reg & 0x1f; - } - return rcal_reg & 0x3e; -} - static void -wlc_phy_chanspec_radio2057_setup(struct brcms_phy *pi, - const struct chan_info_nphy_radio2057 *ci, - const struct chan_info_nphy_radio2057_rev5 *ci2) +wlc_phy_chanspec_radio2057_setup( + struct brcms_phy *pi, + const struct chan_info_nphy_radio2057 *ci, + const struct chan_info_nphy_radio2057_rev5 * + ci2) { int coreNum; u16 txmix2g_tune_boost_pu = 0; @@ -18455,9 +21131,8 @@ wlc_phy_chanspec_radio2057_setup(struct brcms_phy *pi, if (CHSPEC_IS2G(pi->radio_chanspec)) { if (PHY_IPA(pi)) { - if (pi->pubpi.radiorev == 3) { + if (pi->pubpi.radiorev == 3) txmix2g_tune_boost_pu = 0x6b; - } if (pi->pubpi.radiorev == 5) pad2g_tune_pus = 0x73; @@ -18489,430 +21164,8 @@ wlc_phy_chanspec_radio2057_setup(struct brcms_phy *pi, wlc_phy_radio205x_vcocal_nphy(pi); } -static u16 wlc_phy_radio2057_rccal(struct brcms_phy *pi) -{ - u16 rccal_valid; - int i; - bool chip43226_6362A0; - - chip43226_6362A0 = ((pi->pubpi.radiorev == 3) - || (pi->pubpi.radiorev == 4) - || (pi->pubpi.radiorev == 6)); - - rccal_valid = 0; - if (chip43226_6362A0) { - write_radio_reg(pi, RADIO_2057_RCCAL_MASTER, 0x61); - write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xc0); - } else { - write_radio_reg(pi, RADIO_2057v7_RCCAL_MASTER, 0x61); - - write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xe9); - } - write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x6e); - write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x55); - - for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) { - rccal_valid = read_radio_reg(pi, RADIO_2057_RCCAL_DONE_OSCCAP); - if (rccal_valid & 0x2) { - break; - } - udelay(500); - } - - write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15); - - rccal_valid = 0; - if (chip43226_6362A0) { - write_radio_reg(pi, RADIO_2057_RCCAL_MASTER, 0x69); - write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xb0); - } else { - write_radio_reg(pi, RADIO_2057v7_RCCAL_MASTER, 0x69); - - write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xd5); - } - write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x6e); - write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x55); - - for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) { - rccal_valid = read_radio_reg(pi, RADIO_2057_RCCAL_DONE_OSCCAP); - if (rccal_valid & 0x2) { - break; - } - udelay(500); - } - - write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15); - - rccal_valid = 0; - if (chip43226_6362A0) { - write_radio_reg(pi, RADIO_2057_RCCAL_MASTER, 0x73); - - write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x28); - write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0xb0); - } else { - write_radio_reg(pi, RADIO_2057v7_RCCAL_MASTER, 0x73); - write_radio_reg(pi, RADIO_2057_RCCAL_X1, 0x6e); - write_radio_reg(pi, RADIO_2057_RCCAL_TRC0, 0x99); - } - write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x55); - - for (i = 0; i < MAX_205x_RCAL_WAITLOOPS; i++) { - rccal_valid = read_radio_reg(pi, RADIO_2057_RCCAL_DONE_OSCCAP); - if (rccal_valid & 0x2) { - break; - } - udelay(500); - } - - if (WARN(!(rccal_valid & 0x2), "HW error: radio calib4")) - return 0; - - write_radio_reg(pi, RADIO_2057_RCCAL_START_R1_Q1_P1, 0x15); - - return rccal_valid; -} - static void -wlc_phy_adjust_rx_analpfbw_nphy(struct brcms_phy *pi, u16 reduction_factr) -{ - if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) { - if ((CHSPEC_CHANNEL(pi->radio_chanspec) == 11) && - CHSPEC_IS40(pi->radio_chanspec)) { - if (!pi->nphy_anarxlpf_adjusted) { - write_radio_reg(pi, - (RADIO_2056_RX_RXLPF_RCCAL_LPC | - RADIO_2056_RX0), - ((pi->nphy_rccal_value + - reduction_factr) | 0x80)); - - pi->nphy_anarxlpf_adjusted = true; - } - } else { - if (pi->nphy_anarxlpf_adjusted) { - write_radio_reg(pi, - (RADIO_2056_RX_RXLPF_RCCAL_LPC | - RADIO_2056_RX0), - (pi->nphy_rccal_value | 0x80)); - - pi->nphy_anarxlpf_adjusted = false; - } - } - } -} - -static void -wlc_phy_adjust_min_noisevar_nphy(struct brcms_phy *pi, int ntones, - int *tone_id_buf, u32 *noise_var_buf) -{ - int i; - u32 offset; - int tone_id; - int tbllen = - CHSPEC_IS40(pi-> - radio_chanspec) ? NPHY_NOISEVAR_TBLLEN40 : - NPHY_NOISEVAR_TBLLEN20; - - if (pi->nphy_noisevars_adjusted) { - for (i = 0; i < pi->nphy_saved_noisevars.bufcount; i++) { - tone_id = pi->nphy_saved_noisevars.tone_id[i]; - offset = (tone_id >= 0) ? - ((tone_id * 2) + 1) : (tbllen + (tone_id * 2) + 1); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, - offset, 32, - (void *)&pi-> - nphy_saved_noisevars. - min_noise_vars[i]); - } - - pi->nphy_saved_noisevars.bufcount = 0; - pi->nphy_noisevars_adjusted = false; - } - - if ((noise_var_buf != NULL) && (tone_id_buf != NULL)) { - pi->nphy_saved_noisevars.bufcount = 0; - - for (i = 0; i < ntones; i++) { - tone_id = tone_id_buf[i]; - offset = (tone_id >= 0) ? - ((tone_id * 2) + 1) : (tbllen + (tone_id * 2) + 1); - pi->nphy_saved_noisevars.tone_id[i] = tone_id; - wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, - offset, 32, - &pi->nphy_saved_noisevars. - min_noise_vars[i]); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_NOISEVAR, 1, - offset, 32, - (void *)&noise_var_buf[i]); - pi->nphy_saved_noisevars.bufcount++; - } - - pi->nphy_noisevars_adjusted = true; - } -} - -static void wlc_phy_adjust_crsminpwr_nphy(struct brcms_phy *pi, u8 minpwr) -{ - u16 regval; - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - if ((CHSPEC_CHANNEL(pi->radio_chanspec) == 11) && - CHSPEC_IS40(pi->radio_chanspec)) { - if (!pi->nphy_crsminpwr_adjusted) { - regval = read_phy_reg(pi, 0x27d); - pi->nphy_crsminpwr[0] = regval & 0xff; - regval &= 0xff00; - regval |= (u16) minpwr; - write_phy_reg(pi, 0x27d, regval); - - regval = read_phy_reg(pi, 0x280); - pi->nphy_crsminpwr[1] = regval & 0xff; - regval &= 0xff00; - regval |= (u16) minpwr; - write_phy_reg(pi, 0x280, regval); - - regval = read_phy_reg(pi, 0x283); - pi->nphy_crsminpwr[2] = regval & 0xff; - regval &= 0xff00; - regval |= (u16) minpwr; - write_phy_reg(pi, 0x283, regval); - - pi->nphy_crsminpwr_adjusted = true; - } - } else { - if (pi->nphy_crsminpwr_adjusted) { - regval = read_phy_reg(pi, 0x27d); - regval &= 0xff00; - regval |= pi->nphy_crsminpwr[0]; - write_phy_reg(pi, 0x27d, regval); - - regval = read_phy_reg(pi, 0x280); - regval &= 0xff00; - regval |= pi->nphy_crsminpwr[1]; - write_phy_reg(pi, 0x280, regval); - - regval = read_phy_reg(pi, 0x283); - regval &= 0xff00; - regval |= pi->nphy_crsminpwr[2]; - write_phy_reg(pi, 0x283, regval); - - pi->nphy_crsminpwr_adjusted = false; - } - } - } -} - -static void wlc_phy_txlpfbw_nphy(struct brcms_phy *pi) -{ - u8 tx_lpf_bw = 0; - - if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) { - if (CHSPEC_IS40(pi->radio_chanspec)) { - tx_lpf_bw = 3; - } else { - tx_lpf_bw = 1; - } - - if (PHY_IPA(pi)) { - if (CHSPEC_IS40(pi->radio_chanspec)) { - tx_lpf_bw = 5; - } else { - tx_lpf_bw = 4; - } - } - write_phy_reg(pi, 0xe8, - (tx_lpf_bw << 0) | - (tx_lpf_bw << 3) | - (tx_lpf_bw << 6) | (tx_lpf_bw << 9)); - - if (PHY_IPA(pi)) { - - if (CHSPEC_IS40(pi->radio_chanspec)) { - tx_lpf_bw = 4; - } else { - tx_lpf_bw = 1; - } - - write_phy_reg(pi, 0xe9, - (tx_lpf_bw << 0) | - (tx_lpf_bw << 3) | - (tx_lpf_bw << 6) | (tx_lpf_bw << 9)); - } - } -} - -static void wlc_phy_spurwar_nphy(struct brcms_phy *pi) -{ - u16 cur_channel = 0; - int nphy_adj_tone_id_buf[] = { 57, 58 }; - u32 nphy_adj_noise_var_buf[] = { 0x3ff, 0x3ff }; - bool isAdjustNoiseVar = false; - uint numTonesAdjust = 0; - u32 tempval = 0; - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, true); - - cur_channel = CHSPEC_CHANNEL(pi->radio_chanspec); - - if (pi->nphy_gband_spurwar_en) { - - wlc_phy_adjust_rx_analpfbw_nphy(pi, - NPHY_ANARXLPFBW_REDUCTIONFACT); - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - if ((cur_channel == 11) - && CHSPEC_IS40(pi->radio_chanspec)) { - - wlc_phy_adjust_min_noisevar_nphy(pi, 2, - nphy_adj_tone_id_buf, - nphy_adj_noise_var_buf); - } else { - - wlc_phy_adjust_min_noisevar_nphy(pi, 0, - NULL, - NULL); - } - } - wlc_phy_adjust_crsminpwr_nphy(pi, - NPHY_ADJUSTED_MINCRSPOWER); - } - - if ((pi->nphy_gband_spurwar2_en) - && CHSPEC_IS2G(pi->radio_chanspec)) { - - if (CHSPEC_IS40(pi->radio_chanspec)) { - switch (cur_channel) { - case 3: - nphy_adj_tone_id_buf[0] = 57; - nphy_adj_tone_id_buf[1] = 58; - nphy_adj_noise_var_buf[0] = 0x22f; - nphy_adj_noise_var_buf[1] = 0x25f; - isAdjustNoiseVar = true; - break; - case 4: - nphy_adj_tone_id_buf[0] = 41; - nphy_adj_tone_id_buf[1] = 42; - nphy_adj_noise_var_buf[0] = 0x22f; - nphy_adj_noise_var_buf[1] = 0x25f; - isAdjustNoiseVar = true; - break; - case 5: - nphy_adj_tone_id_buf[0] = 25; - nphy_adj_tone_id_buf[1] = 26; - nphy_adj_noise_var_buf[0] = 0x24f; - nphy_adj_noise_var_buf[1] = 0x25f; - isAdjustNoiseVar = true; - break; - case 6: - nphy_adj_tone_id_buf[0] = 9; - nphy_adj_tone_id_buf[1] = 10; - nphy_adj_noise_var_buf[0] = 0x22f; - nphy_adj_noise_var_buf[1] = 0x24f; - isAdjustNoiseVar = true; - break; - case 7: - nphy_adj_tone_id_buf[0] = 121; - nphy_adj_tone_id_buf[1] = 122; - nphy_adj_noise_var_buf[0] = 0x18f; - nphy_adj_noise_var_buf[1] = 0x24f; - isAdjustNoiseVar = true; - break; - case 8: - nphy_adj_tone_id_buf[0] = 105; - nphy_adj_tone_id_buf[1] = 106; - nphy_adj_noise_var_buf[0] = 0x22f; - nphy_adj_noise_var_buf[1] = 0x25f; - isAdjustNoiseVar = true; - break; - case 9: - nphy_adj_tone_id_buf[0] = 89; - nphy_adj_tone_id_buf[1] = 90; - nphy_adj_noise_var_buf[0] = 0x22f; - nphy_adj_noise_var_buf[1] = 0x24f; - isAdjustNoiseVar = true; - break; - case 10: - nphy_adj_tone_id_buf[0] = 73; - nphy_adj_tone_id_buf[1] = 74; - nphy_adj_noise_var_buf[0] = 0x22f; - nphy_adj_noise_var_buf[1] = 0x24f; - isAdjustNoiseVar = true; - break; - default: - isAdjustNoiseVar = false; - break; - } - } - - if (isAdjustNoiseVar) { - numTonesAdjust = sizeof(nphy_adj_tone_id_buf) / - sizeof(nphy_adj_tone_id_buf[0]); - - wlc_phy_adjust_min_noisevar_nphy(pi, - numTonesAdjust, - nphy_adj_tone_id_buf, - nphy_adj_noise_var_buf); - - tempval = 0; - - } else { - - wlc_phy_adjust_min_noisevar_nphy(pi, 0, NULL, - NULL); - } - } - - if ((pi->nphy_aband_spurwar_en) && - (CHSPEC_IS5G(pi->radio_chanspec))) { - switch (cur_channel) { - case 54: - nphy_adj_tone_id_buf[0] = 32; - nphy_adj_noise_var_buf[0] = 0x25f; - break; - case 38: - case 102: - case 118: - nphy_adj_tone_id_buf[0] = 0; - nphy_adj_noise_var_buf[0] = 0x0; - break; - case 134: - nphy_adj_tone_id_buf[0] = 32; - nphy_adj_noise_var_buf[0] = 0x21f; - break; - case 151: - nphy_adj_tone_id_buf[0] = 16; - nphy_adj_noise_var_buf[0] = 0x23f; - break; - case 153: - case 161: - nphy_adj_tone_id_buf[0] = 48; - nphy_adj_noise_var_buf[0] = 0x23f; - break; - default: - nphy_adj_tone_id_buf[0] = 0; - nphy_adj_noise_var_buf[0] = 0x0; - break; - } - - if (nphy_adj_tone_id_buf[0] - && nphy_adj_noise_var_buf[0]) { - wlc_phy_adjust_min_noisevar_nphy(pi, 1, - nphy_adj_tone_id_buf, - nphy_adj_noise_var_buf); - } else { - wlc_phy_adjust_min_noisevar_nphy(pi, 0, NULL, - NULL); - } - } - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, false); - } -} - -static void -wlc_phy_chanspec_nphy_setup(struct brcms_phy *pi, chanspec_t chanspec, +wlc_phy_chanspec_nphy_setup(struct brcms_phy *pi, u16 chanspec, const struct nphy_sfo_cfg *ci) { u16 val; @@ -18964,14 +21217,11 @@ wlc_phy_chanspec_nphy_setup(struct brcms_phy *pi, chanspec_t chanspec, and_phy_reg(pi, NPHY_TO_BPHY_OFF + BPHY_TEST, ~0x840); } - if (pi->nphy_txpwrctrl == PHY_TPC_HW_OFF) { + if (pi->nphy_txpwrctrl == PHY_TPC_HW_OFF) wlc_phy_txpwr_fixpower_nphy(pi); - } - - if (NREV_LT(pi->pubpi.phy_rev, 3)) { + if (NREV_LT(pi->pubpi.phy_rev, 3)) wlc_phy_adjust_lnagaintbl_nphy(pi); - } wlc_phy_txlpfbw_nphy(pi); @@ -18982,28 +21232,20 @@ wlc_phy_chanspec_nphy_setup(struct brcms_phy *pi, chanspec_t chanspec, val = CHSPEC_CHANNEL(chanspec); if (!CHSPEC_IS40(pi->radio_chanspec)) { if (NREV_GE(pi->pubpi.phy_rev, 7)) { - if ((val == 13) || (val == 14) || (val == 153)) { - spuravoid = 1; - } - } else { - - if (((val >= 5) && (val <= 8)) || (val == 13) - || (val == 14)) { + if ((val == 13) || (val == 14) || (val == 153)) spuravoid = 1; - } + } else if (((val >= 5) && (val <= 8)) || (val == 13) + || (val == 14)) { + spuravoid = 1; } + } else if (NREV_GE(pi->pubpi.phy_rev, 7)) { + if (val == 54) + spuravoid = 1; } else { - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - if (val == 54) { - spuravoid = 1; - } - } else { - - if (pi->nphy_aband_spurwar_en && - ((val == 38) || (val == 102) - || (val == 118))) - spuravoid = 1; - } + if (pi->nphy_aband_spurwar_en && + ((val == 38) || (val == 102) + || (val == 118))) + spuravoid = 1; } if (pi->phy_spuravoid == SPURAVOID_FORCEON) @@ -19047,7 +21289,7 @@ wlc_phy_chanspec_nphy_setup(struct brcms_phy *pi, chanspec_t chanspec, wlc_phy_spurwar_nphy(pi); } -void wlc_phy_chanspec_set_nphy(struct brcms_phy *pi, chanspec_t chanspec) +void wlc_phy_chanspec_set_nphy(struct brcms_phy *pi, u16 chanspec) { int freq; struct chan_info_nphy_radio2057 *t0 = NULL; @@ -19055,12 +21297,8 @@ void wlc_phy_chanspec_set_nphy(struct brcms_phy *pi, chanspec_t chanspec) struct chan_info_nphy_radio2057_rev5 *t2 = NULL; struct chan_info_nphy_2055 *t3 = NULL; - if (NORADIO_ENAB(pi->pubpi)) { - return; - } - if (!wlc_phy_chan2freq_nphy - (pi, CHSPEC_CHANNEL(chanspec), &freq, &t0, &t1, &t2, &t3)) + (pi, CHSPEC_CHANNEL(chanspec), &freq, &t0, &t1, &t2, &t3)) return; wlc_phy_chanspec_radio_set((struct brcms_phy_pub *) pi, chanspec); @@ -19071,15 +21309,13 @@ void wlc_phy_chanspec_set_nphy(struct brcms_phy *pi, chanspec_t chanspec) if (CHSPEC_IS40(chanspec)) { if (CHSPEC_SB_UPPER(chanspec)) { or_phy_reg(pi, 0xa0, BPHY_BAND_SEL_UP20); - if (NREV_GE(pi->pubpi.phy_rev, 7)) { + if (NREV_GE(pi->pubpi.phy_rev, 7)) or_phy_reg(pi, 0x310, PRIM_SEL_UP20); - } } else { and_phy_reg(pi, 0xa0, ~BPHY_BAND_SEL_UP20); - if (NREV_GE(pi->pubpi.phy_rev, 7)) { + if (NREV_GE(pi->pubpi.phy_rev, 7)) and_phy_reg(pi, 0x310, (~PRIM_SEL_UP20 & 0xffff)); - } } } @@ -19124,358 +21360,10 @@ void wlc_phy_chanspec_set_nphy(struct brcms_phy *pi, chanspec_t chanspec) wlc_phy_chanspec_radio2055_setup(pi, t3); wlc_phy_chanspec_nphy_setup(pi, chanspec, - (const struct nphy_sfo_cfg *)&(t3-> - PHY_BW1a)); - } - -} - -static void wlc_phy_savecal_nphy(struct brcms_phy *pi) -{ - void *tbl_ptr; - int coreNum; - u16 *txcal_radio_regs = NULL; - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, true); - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - - wlc_phy_rx_iq_coeffs_nphy(pi, 0, - &pi->calibration_cache. - rxcal_coeffs_2G); - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - txcal_radio_regs = - pi->calibration_cache.txcal_radio_regs_2G; - } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { - - pi->calibration_cache.txcal_radio_regs_2G[0] = - read_radio_reg(pi, - RADIO_2056_TX_LOFT_FINE_I | - RADIO_2056_TX0); - pi->calibration_cache.txcal_radio_regs_2G[1] = - read_radio_reg(pi, - RADIO_2056_TX_LOFT_FINE_Q | - RADIO_2056_TX0); - pi->calibration_cache.txcal_radio_regs_2G[2] = - read_radio_reg(pi, - RADIO_2056_TX_LOFT_FINE_I | - RADIO_2056_TX1); - pi->calibration_cache.txcal_radio_regs_2G[3] = - read_radio_reg(pi, - RADIO_2056_TX_LOFT_FINE_Q | - RADIO_2056_TX1); - - pi->calibration_cache.txcal_radio_regs_2G[4] = - read_radio_reg(pi, - RADIO_2056_TX_LOFT_COARSE_I | - RADIO_2056_TX0); - pi->calibration_cache.txcal_radio_regs_2G[5] = - read_radio_reg(pi, - RADIO_2056_TX_LOFT_COARSE_Q | - RADIO_2056_TX0); - pi->calibration_cache.txcal_radio_regs_2G[6] = - read_radio_reg(pi, - RADIO_2056_TX_LOFT_COARSE_I | - RADIO_2056_TX1); - pi->calibration_cache.txcal_radio_regs_2G[7] = - read_radio_reg(pi, - RADIO_2056_TX_LOFT_COARSE_Q | - RADIO_2056_TX1); - } else { - pi->calibration_cache.txcal_radio_regs_2G[0] = - read_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL); - pi->calibration_cache.txcal_radio_regs_2G[1] = - read_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL); - pi->calibration_cache.txcal_radio_regs_2G[2] = - read_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM); - pi->calibration_cache.txcal_radio_regs_2G[3] = - read_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM); - } - - pi->nphy_iqcal_chanspec_2G = pi->radio_chanspec; - tbl_ptr = pi->calibration_cache.txcal_coeffs_2G; - } else { - - wlc_phy_rx_iq_coeffs_nphy(pi, 0, - &pi->calibration_cache. - rxcal_coeffs_5G); - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - txcal_radio_regs = - pi->calibration_cache.txcal_radio_regs_5G; - } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { - - pi->calibration_cache.txcal_radio_regs_5G[0] = - read_radio_reg(pi, - RADIO_2056_TX_LOFT_FINE_I | - RADIO_2056_TX0); - pi->calibration_cache.txcal_radio_regs_5G[1] = - read_radio_reg(pi, - RADIO_2056_TX_LOFT_FINE_Q | - RADIO_2056_TX0); - pi->calibration_cache.txcal_radio_regs_5G[2] = - read_radio_reg(pi, - RADIO_2056_TX_LOFT_FINE_I | - RADIO_2056_TX1); - pi->calibration_cache.txcal_radio_regs_5G[3] = - read_radio_reg(pi, - RADIO_2056_TX_LOFT_FINE_Q | - RADIO_2056_TX1); - - pi->calibration_cache.txcal_radio_regs_5G[4] = - read_radio_reg(pi, - RADIO_2056_TX_LOFT_COARSE_I | - RADIO_2056_TX0); - pi->calibration_cache.txcal_radio_regs_5G[5] = - read_radio_reg(pi, - RADIO_2056_TX_LOFT_COARSE_Q | - RADIO_2056_TX0); - pi->calibration_cache.txcal_radio_regs_5G[6] = - read_radio_reg(pi, - RADIO_2056_TX_LOFT_COARSE_I | - RADIO_2056_TX1); - pi->calibration_cache.txcal_radio_regs_5G[7] = - read_radio_reg(pi, - RADIO_2056_TX_LOFT_COARSE_Q | - RADIO_2056_TX1); - } else { - pi->calibration_cache.txcal_radio_regs_5G[0] = - read_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL); - pi->calibration_cache.txcal_radio_regs_5G[1] = - read_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL); - pi->calibration_cache.txcal_radio_regs_5G[2] = - read_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM); - pi->calibration_cache.txcal_radio_regs_5G[3] = - read_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM); - } - - pi->nphy_iqcal_chanspec_5G = pi->radio_chanspec; - tbl_ptr = pi->calibration_cache.txcal_coeffs_5G; - } - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - for (coreNum = 0; coreNum <= 1; coreNum++) { - - txcal_radio_regs[2 * coreNum] = - READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum, - LOFT_FINE_I); - txcal_radio_regs[2 * coreNum + 1] = - READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum, - LOFT_FINE_Q); - - txcal_radio_regs[2 * coreNum + 4] = - READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum, - LOFT_COARSE_I); - txcal_radio_regs[2 * coreNum + 5] = - READ_RADIO_REG3(pi, RADIO_2057, TX, coreNum, - LOFT_COARSE_Q); - } - } - - wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 8, 80, 16, tbl_ptr); - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, false); -} - -static void wlc_phy_restorecal_nphy(struct brcms_phy *pi) -{ - u16 *loft_comp; - u16 txcal_coeffs_bphy[4]; - u16 *tbl_ptr; - int coreNum; - u16 *txcal_radio_regs = NULL; - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - if (pi->nphy_iqcal_chanspec_2G == 0) - return; - - tbl_ptr = pi->calibration_cache.txcal_coeffs_2G; - loft_comp = &pi->calibration_cache.txcal_coeffs_2G[5]; - } else { - if (pi->nphy_iqcal_chanspec_5G == 0) - return; - - tbl_ptr = pi->calibration_cache.txcal_coeffs_5G; - loft_comp = &pi->calibration_cache.txcal_coeffs_5G[5]; - } - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 80, 16, - (void *)tbl_ptr); - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - txcal_coeffs_bphy[0] = tbl_ptr[0]; - txcal_coeffs_bphy[1] = tbl_ptr[1]; - txcal_coeffs_bphy[2] = tbl_ptr[2]; - txcal_coeffs_bphy[3] = tbl_ptr[3]; - } else { - txcal_coeffs_bphy[0] = 0; - txcal_coeffs_bphy[1] = 0; - txcal_coeffs_bphy[2] = 0; - txcal_coeffs_bphy[3] = 0; - } - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 4, 88, 16, - txcal_coeffs_bphy); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 85, 16, loft_comp); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 2, 93, 16, loft_comp); - - if (NREV_LT(pi->pubpi.phy_rev, 2)) - wlc_phy_tx_iq_war_nphy(pi); - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - txcal_radio_regs = - pi->calibration_cache.txcal_radio_regs_2G; - } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { - - write_radio_reg(pi, - RADIO_2056_TX_LOFT_FINE_I | - RADIO_2056_TX0, - pi->calibration_cache. - txcal_radio_regs_2G[0]); - write_radio_reg(pi, - RADIO_2056_TX_LOFT_FINE_Q | - RADIO_2056_TX0, - pi->calibration_cache. - txcal_radio_regs_2G[1]); - write_radio_reg(pi, - RADIO_2056_TX_LOFT_FINE_I | - RADIO_2056_TX1, - pi->calibration_cache. - txcal_radio_regs_2G[2]); - write_radio_reg(pi, - RADIO_2056_TX_LOFT_FINE_Q | - RADIO_2056_TX1, - pi->calibration_cache. - txcal_radio_regs_2G[3]); - - write_radio_reg(pi, - RADIO_2056_TX_LOFT_COARSE_I | - RADIO_2056_TX0, - pi->calibration_cache. - txcal_radio_regs_2G[4]); - write_radio_reg(pi, - RADIO_2056_TX_LOFT_COARSE_Q | - RADIO_2056_TX0, - pi->calibration_cache. - txcal_radio_regs_2G[5]); - write_radio_reg(pi, - RADIO_2056_TX_LOFT_COARSE_I | - RADIO_2056_TX1, - pi->calibration_cache. - txcal_radio_regs_2G[6]); - write_radio_reg(pi, - RADIO_2056_TX_LOFT_COARSE_Q | - RADIO_2056_TX1, - pi->calibration_cache. - txcal_radio_regs_2G[7]); - } else { - write_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL, - pi->calibration_cache. - txcal_radio_regs_2G[0]); - write_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL, - pi->calibration_cache. - txcal_radio_regs_2G[1]); - write_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM, - pi->calibration_cache. - txcal_radio_regs_2G[2]); - write_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM, - pi->calibration_cache. - txcal_radio_regs_2G[3]); - } - - wlc_phy_rx_iq_coeffs_nphy(pi, 1, - &pi->calibration_cache. - rxcal_coeffs_2G); - } else { - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - txcal_radio_regs = - pi->calibration_cache.txcal_radio_regs_5G; - } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { - - write_radio_reg(pi, - RADIO_2056_TX_LOFT_FINE_I | - RADIO_2056_TX0, - pi->calibration_cache. - txcal_radio_regs_5G[0]); - write_radio_reg(pi, - RADIO_2056_TX_LOFT_FINE_Q | - RADIO_2056_TX0, - pi->calibration_cache. - txcal_radio_regs_5G[1]); - write_radio_reg(pi, - RADIO_2056_TX_LOFT_FINE_I | - RADIO_2056_TX1, - pi->calibration_cache. - txcal_radio_regs_5G[2]); - write_radio_reg(pi, - RADIO_2056_TX_LOFT_FINE_Q | - RADIO_2056_TX1, - pi->calibration_cache. - txcal_radio_regs_5G[3]); - - write_radio_reg(pi, - RADIO_2056_TX_LOFT_COARSE_I | - RADIO_2056_TX0, - pi->calibration_cache. - txcal_radio_regs_5G[4]); - write_radio_reg(pi, - RADIO_2056_TX_LOFT_COARSE_Q | - RADIO_2056_TX0, - pi->calibration_cache. - txcal_radio_regs_5G[5]); - write_radio_reg(pi, - RADIO_2056_TX_LOFT_COARSE_I | - RADIO_2056_TX1, - pi->calibration_cache. - txcal_radio_regs_5G[6]); - write_radio_reg(pi, - RADIO_2056_TX_LOFT_COARSE_Q | - RADIO_2056_TX1, - pi->calibration_cache. - txcal_radio_regs_5G[7]); - } else { - write_radio_reg(pi, RADIO_2055_CORE1_TX_VOS_CNCL, - pi->calibration_cache. - txcal_radio_regs_5G[0]); - write_radio_reg(pi, RADIO_2055_CORE2_TX_VOS_CNCL, - pi->calibration_cache. - txcal_radio_regs_5G[1]); - write_radio_reg(pi, RADIO_2055_CORE1_TX_BB_MXGM, - pi->calibration_cache. - txcal_radio_regs_5G[2]); - write_radio_reg(pi, RADIO_2055_CORE2_TX_BB_MXGM, - pi->calibration_cache. - txcal_radio_regs_5G[3]); - } - - wlc_phy_rx_iq_coeffs_nphy(pi, 1, - &pi->calibration_cache. - rxcal_coeffs_5G); + (const struct nphy_sfo_cfg *) + &(t3->PHY_BW1a)); } - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - for (coreNum = 0; coreNum <= 1; coreNum++) { - - WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum, - LOFT_FINE_I, - txcal_radio_regs[2 * coreNum]); - WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum, - LOFT_FINE_Q, - txcal_radio_regs[2 * coreNum + 1]); - - WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum, - LOFT_COARSE_I, - txcal_radio_regs[2 * coreNum + 4]); - WRITE_RADIO_REG3(pi, RADIO_2057, TX, coreNum, - LOFT_COARSE_Q, - txcal_radio_regs[2 * coreNum + 5]); - } - } } void wlc_phy_antsel_init(struct brcms_phy_pub *ppi, bool lut_init) @@ -19545,8 +21433,8 @@ u16 wlc_phy_classifier_nphy(struct brcms_phy *pi, u16 mask, u16 val) if (D11REV_IS(pi->sh->corerev, 16)) { suspended = - (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC) ? - false : true; + (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC) ? + false : true; if (!suspended) wlapi_suspend_mac_and_wait(pi->sh->physhim); } @@ -19563,18 +21451,6 @@ u16 wlc_phy_classifier_nphy(struct brcms_phy *pi, u16 mask, u16 val) return new_ctl; } -static void wlc_phy_clip_det_nphy(struct brcms_phy *pi, u8 write, u16 *vals) -{ - - if (write == 0) { - vals[0] = read_phy_reg(pi, 0x2c); - vals[1] = read_phy_reg(pi, 0x42); - } else { - write_phy_reg(pi, 0x2c, vals[0]); - write_phy_reg(pi, 0x42, vals[1]); - } -} - void wlc_phy_force_rfseq_nphy(struct brcms_phy *pi, u8 cmd) { u16 trigger_mask, status_mask; @@ -19620,577 +21496,6 @@ void wlc_phy_force_rfseq_nphy(struct brcms_phy *pi, u8 cmd) } static void -wlc_phy_set_rfseq_nphy(struct brcms_phy *pi, u8 cmd, u8 *events, u8 *dlys, - u8 len) -{ - u32 t1_offset, t2_offset; - u8 ctr; - u8 end_event = - NREV_GE(pi->pubpi.phy_rev, - 3) ? NPHY_REV3_RFSEQ_CMD_END : NPHY_RFSEQ_CMD_END; - u8 end_dly = 1; - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, true); - - t1_offset = cmd << 4; - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, len, t1_offset, 8, - events); - t2_offset = t1_offset + 0x080; - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, len, t2_offset, 8, - dlys); - - for (ctr = len; ctr < 16; ctr++) { - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, - t1_offset + ctr, 8, &end_event); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, - t2_offset + ctr, 8, &end_dly); - } - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, false); -} - -static u16 wlc_phy_read_lpf_bw_ctl_nphy(struct brcms_phy *pi, u16 offset) -{ - u16 lpf_bw_ctl_val = 0; - u16 rx2tx_lpf_rc_lut_offset = 0; - - if (offset == 0) { - if (CHSPEC_IS40(pi->radio_chanspec)) { - rx2tx_lpf_rc_lut_offset = 0x159; - } else { - rx2tx_lpf_rc_lut_offset = 0x154; - } - } else { - rx2tx_lpf_rc_lut_offset = offset; - } - wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 1, - (u32) rx2tx_lpf_rc_lut_offset, 16, - &lpf_bw_ctl_val); - - lpf_bw_ctl_val = lpf_bw_ctl_val & 0x7; - - return lpf_bw_ctl_val; -} - -static void -wlc_phy_rfctrl_override_nphy_rev7(struct brcms_phy *pi, u16 field, u16 value, - u8 core_mask, u8 off, u8 override_id) -{ - u8 core_num; - u16 addr = 0, en_addr = 0, val_addr = 0, en_mask = 0, val_mask = 0; - u8 val_shift = 0; - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - en_mask = field; - for (core_num = 0; core_num < 2; core_num++) { - if (override_id == NPHY_REV7_RFCTRLOVERRIDE_ID0) { - - switch (field) { - case (0x1 << 2): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x7a : - 0x7d; - val_mask = (0x1 << 1); - val_shift = 1; - break; - case (0x1 << 3): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x7a : - 0x7d; - val_mask = (0x1 << 2); - val_shift = 2; - break; - case (0x1 << 4): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x7a : - 0x7d; - val_mask = (0x1 << 4); - val_shift = 4; - break; - case (0x1 << 5): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x7a : - 0x7d; - val_mask = (0x1 << 5); - val_shift = 5; - break; - case (0x1 << 6): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x7a : - 0x7d; - val_mask = (0x1 << 6); - val_shift = 6; - break; - case (0x1 << 7): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x7a : - 0x7d; - val_mask = (0x1 << 7); - val_shift = 7; - break; - case (0x1 << 10): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0xf8 : - 0xfa; - val_mask = (0x7 << 4); - val_shift = 4; - break; - case (0x1 << 11): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x7b : - 0x7e; - val_mask = (0xffff << 0); - val_shift = 0; - break; - case (0x1 << 12): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x7c : - 0x7f; - val_mask = (0xffff << 0); - val_shift = 0; - break; - case (0x3 << 13): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x348 : - 0x349; - val_mask = (0xff << 0); - val_shift = 0; - break; - case (0x1 << 13): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x348 : - 0x349; - val_mask = (0xf << 0); - val_shift = 0; - break; - default: - addr = 0xffff; - break; - } - } else if (override_id == NPHY_REV7_RFCTRLOVERRIDE_ID1) { - - switch (field) { - case (0x1 << 1): - en_addr = (core_num == 0) ? 0x342 : - 0x343; - val_addr = (core_num == 0) ? 0x340 : - 0x341; - val_mask = (0x1 << 1); - val_shift = 1; - break; - case (0x1 << 3): - en_addr = (core_num == 0) ? 0x342 : - 0x343; - val_addr = (core_num == 0) ? 0x340 : - 0x341; - val_mask = (0x1 << 3); - val_shift = 3; - break; - case (0x1 << 5): - en_addr = (core_num == 0) ? 0x342 : - 0x343; - val_addr = (core_num == 0) ? 0x340 : - 0x341; - val_mask = (0x1 << 5); - val_shift = 5; - break; - case (0x1 << 4): - en_addr = (core_num == 0) ? 0x342 : - 0x343; - val_addr = (core_num == 0) ? 0x340 : - 0x341; - val_mask = (0x1 << 4); - val_shift = 4; - break; - case (0x1 << 2): - - en_addr = (core_num == 0) ? 0x342 : - 0x343; - val_addr = (core_num == 0) ? 0x340 : - 0x341; - val_mask = (0x1 << 2); - val_shift = 2; - break; - case (0x1 << 7): - - en_addr = (core_num == 0) ? 0x342 : - 0x343; - val_addr = (core_num == 0) ? 0x340 : - 0x341; - val_mask = (0x7 << 8); - val_shift = 8; - break; - case (0x1 << 11): - en_addr = (core_num == 0) ? 0x342 : - 0x343; - val_addr = (core_num == 0) ? 0x340 : - 0x341; - val_mask = (0x1 << 14); - val_shift = 14; - break; - case (0x1 << 10): - en_addr = (core_num == 0) ? 0x342 : - 0x343; - val_addr = (core_num == 0) ? 0x340 : - 0x341; - val_mask = (0x1 << 13); - val_shift = 13; - break; - case (0x1 << 9): - en_addr = (core_num == 0) ? 0x342 : - 0x343; - val_addr = (core_num == 0) ? 0x340 : - 0x341; - val_mask = (0x1 << 12); - val_shift = 12; - break; - case (0x1 << 8): - en_addr = (core_num == 0) ? 0x342 : - 0x343; - val_addr = (core_num == 0) ? 0x340 : - 0x341; - val_mask = (0x1 << 11); - val_shift = 11; - break; - case (0x1 << 6): - en_addr = (core_num == 0) ? 0x342 : - 0x343; - val_addr = (core_num == 0) ? 0x340 : - 0x341; - val_mask = (0x1 << 6); - val_shift = 6; - break; - case (0x1 << 0): - en_addr = (core_num == 0) ? 0x342 : - 0x343; - val_addr = (core_num == 0) ? 0x340 : - 0x341; - val_mask = (0x1 << 0); - val_shift = 0; - break; - default: - addr = 0xffff; - break; - } - } else if (override_id == NPHY_REV7_RFCTRLOVERRIDE_ID2) { - - switch (field) { - case (0x1 << 3): - en_addr = (core_num == 0) ? 0x346 : - 0x347; - val_addr = (core_num == 0) ? 0x344 : - 0x345; - val_mask = (0x1 << 3); - val_shift = 3; - break; - case (0x1 << 1): - en_addr = (core_num == 0) ? 0x346 : - 0x347; - val_addr = (core_num == 0) ? 0x344 : - 0x345; - val_mask = (0x1 << 1); - val_shift = 1; - break; - case (0x1 << 0): - en_addr = (core_num == 0) ? 0x346 : - 0x347; - val_addr = (core_num == 0) ? 0x344 : - 0x345; - val_mask = (0x1 << 0); - val_shift = 0; - break; - case (0x1 << 2): - en_addr = (core_num == 0) ? 0x346 : - 0x347; - val_addr = (core_num == 0) ? 0x344 : - 0x345; - val_mask = (0x1 << 2); - val_shift = 2; - break; - case (0x1 << 4): - en_addr = (core_num == 0) ? 0x346 : - 0x347; - val_addr = (core_num == 0) ? 0x344 : - 0x345; - val_mask = (0x1 << 4); - val_shift = 4; - break; - default: - addr = 0xffff; - break; - } - } - - if (off) { - and_phy_reg(pi, en_addr, ~en_mask); - and_phy_reg(pi, val_addr, ~val_mask); - } else { - - if ((core_mask == 0) - || (core_mask & (1 << core_num))) { - or_phy_reg(pi, en_addr, en_mask); - - if (addr != 0xffff) { - mod_phy_reg(pi, val_addr, - val_mask, - (value << - val_shift)); - } - } - } - } - } -} - -static void -wlc_phy_rfctrl_override_nphy(struct brcms_phy *pi, u16 field, u16 value, - u8 core_mask, u8 off) -{ - u8 core_num; - u16 addr = 0, mask = 0, en_addr = 0, val_addr = 0, en_mask = - 0, val_mask = 0; - u8 shift = 0, val_shift = 0; - - if (NREV_GE(pi->pubpi.phy_rev, 3) && NREV_LT(pi->pubpi.phy_rev, 7)) { - - en_mask = field; - for (core_num = 0; core_num < 2; core_num++) { - - switch (field) { - case (0x1 << 1): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x7a : 0x7d; - val_mask = (0x1 << 0); - val_shift = 0; - break; - case (0x1 << 2): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x7a : 0x7d; - val_mask = (0x1 << 1); - val_shift = 1; - break; - case (0x1 << 3): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x7a : 0x7d; - val_mask = (0x1 << 2); - val_shift = 2; - break; - case (0x1 << 4): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x7a : 0x7d; - val_mask = (0x1 << 4); - val_shift = 4; - break; - case (0x1 << 5): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x7a : 0x7d; - val_mask = (0x1 << 5); - val_shift = 5; - break; - case (0x1 << 6): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x7a : 0x7d; - val_mask = (0x1 << 6); - val_shift = 6; - break; - case (0x1 << 7): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x7a : 0x7d; - val_mask = (0x1 << 7); - val_shift = 7; - break; - case (0x1 << 8): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x7a : 0x7d; - val_mask = (0x7 << 8); - val_shift = 8; - break; - case (0x1 << 11): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x7a : 0x7d; - val_mask = (0x7 << 13); - val_shift = 13; - break; - - case (0x1 << 9): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0xf8 : 0xfa; - val_mask = (0x7 << 0); - val_shift = 0; - break; - - case (0x1 << 10): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0xf8 : 0xfa; - val_mask = (0x7 << 4); - val_shift = 4; - break; - - case (0x1 << 12): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x7b : 0x7e; - val_mask = (0xffff << 0); - val_shift = 0; - break; - case (0x1 << 13): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0x7c : 0x7f; - val_mask = (0xffff << 0); - val_shift = 0; - break; - case (0x1 << 14): - en_addr = (core_num == 0) ? 0xe7 : 0xec; - val_addr = (core_num == 0) ? 0xf9 : 0xfb; - val_mask = (0x3 << 6); - val_shift = 6; - break; - case (0x1 << 0): - en_addr = (core_num == 0) ? 0xe5 : 0xe6; - val_addr = (core_num == 0) ? 0xf9 : 0xfb; - val_mask = (0x1 << 15); - val_shift = 15; - break; - default: - addr = 0xffff; - break; - } - - if (off) { - and_phy_reg(pi, en_addr, ~en_mask); - and_phy_reg(pi, val_addr, ~val_mask); - } else { - - if ((core_mask == 0) - || (core_mask & (1 << core_num))) { - or_phy_reg(pi, en_addr, en_mask); - - if (addr != 0xffff) { - mod_phy_reg(pi, val_addr, - val_mask, - (value << - val_shift)); - } - } - } - } - } else { - - if (off) { - and_phy_reg(pi, 0xec, ~field); - value = 0x0; - } else { - or_phy_reg(pi, 0xec, field); - } - - for (core_num = 0; core_num < 2; core_num++) { - - switch (field) { - case (0x1 << 1): - case (0x1 << 9): - case (0x1 << 12): - case (0x1 << 13): - case (0x1 << 14): - addr = 0x78; - - core_mask = 0x1; - break; - case (0x1 << 2): - case (0x1 << 3): - case (0x1 << 4): - case (0x1 << 5): - case (0x1 << 6): - case (0x1 << 7): - case (0x1 << 8): - addr = (core_num == 0) ? 0x7a : 0x7d; - break; - case (0x1 << 10): - addr = (core_num == 0) ? 0x7b : 0x7e; - break; - case (0x1 << 11): - addr = (core_num == 0) ? 0x7c : 0x7f; - break; - default: - addr = 0xffff; - } - - switch (field) { - case (0x1 << 1): - mask = (0x7 << 3); - shift = 3; - break; - case (0x1 << 9): - mask = (0x1 << 2); - shift = 2; - break; - case (0x1 << 12): - mask = (0x1 << 8); - shift = 8; - break; - case (0x1 << 13): - mask = (0x1 << 9); - shift = 9; - break; - case (0x1 << 14): - mask = (0xf << 12); - shift = 12; - break; - case (0x1 << 2): - mask = (0x1 << 0); - shift = 0; - break; - case (0x1 << 3): - mask = (0x1 << 1); - shift = 1; - break; - case (0x1 << 4): - mask = (0x1 << 2); - shift = 2; - break; - case (0x1 << 5): - mask = (0x3 << 4); - shift = 4; - break; - case (0x1 << 6): - mask = (0x3 << 6); - shift = 6; - break; - case (0x1 << 7): - mask = (0x1 << 8); - shift = 8; - break; - case (0x1 << 8): - mask = (0x1 << 9); - shift = 9; - break; - case (0x1 << 10): - mask = 0x1fff; - shift = 0x0; - break; - case (0x1 << 11): - mask = 0x1fff; - shift = 0x0; - break; - default: - mask = 0x0; - shift = 0x0; - break; - } - - if ((addr != 0xffff) && (core_mask & (1 << core_num))) { - mod_phy_reg(pi, addr, mask, (value << shift)); - } - } - - or_phy_reg(pi, 0xec, (0x1 << 0)); - or_phy_reg(pi, 0x78, (0x1 << 0)); - udelay(1); - and_phy_reg(pi, 0xec, ~(0x1 << 0)); - } -} - -static void wlc_phy_rfctrl_override_1tomany_nphy(struct brcms_phy *pi, u16 cmd, u16 value, u8 core_mask, u8 off) { @@ -20201,76 +21506,93 @@ wlc_phy_rfctrl_override_1tomany_nphy(struct brcms_phy *pi, u16 cmd, u16 value, switch (cmd) { case NPHY_REV7_RfctrlOverride_cmd_rxrf_pu: - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5), - value, core_mask, off, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), value, - core_mask, off, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), value, - core_mask, off, - NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7( + pi, (0x1 << 5), + value, core_mask, off, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7( + pi, (0x1 << 4), value, + core_mask, off, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7( + pi, (0x1 << 3), value, + core_mask, off, + NPHY_REV7_RFCTRLOVERRIDE_ID1); break; case NPHY_REV7_RfctrlOverride_cmd_rx_pu: - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), - value, core_mask, off, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), value, - core_mask, off, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), value, - core_mask, off, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), value, - core_mask, off, - NPHY_REV7_RFCTRLOVERRIDE_ID2); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 0, - core_mask, off, - NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7( + pi, (0x1 << 2), + value, core_mask, off, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7( + pi, (0x1 << 1), value, + core_mask, off, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7( + pi, (0x1 << 0), value, + core_mask, off, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7( + pi, (0x1 << 1), value, + core_mask, off, + NPHY_REV7_RFCTRLOVERRIDE_ID2); + wlc_phy_rfctrl_override_nphy_rev7( + pi, (0x1 << 11), 0, + core_mask, off, + NPHY_REV7_RFCTRLOVERRIDE_ID1); break; case NPHY_REV7_RfctrlOverride_cmd_tx_pu: - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), - value, core_mask, off, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), value, - core_mask, off, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), value, - core_mask, off, - NPHY_REV7_RFCTRLOVERRIDE_ID2); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), value, - core_mask, off, - NPHY_REV7_RFCTRLOVERRIDE_ID2); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 1, - core_mask, off, - NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7( + pi, (0x1 << 2), + value, core_mask, off, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + wlc_phy_rfctrl_override_nphy_rev7( + pi, (0x1 << 1), value, + core_mask, off, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7( + pi, (0x1 << 0), value, + core_mask, off, + NPHY_REV7_RFCTRLOVERRIDE_ID2); + wlc_phy_rfctrl_override_nphy_rev7( + pi, (0x1 << 2), value, + core_mask, off, + NPHY_REV7_RFCTRLOVERRIDE_ID2); + wlc_phy_rfctrl_override_nphy_rev7( + pi, (0x1 << 11), 1, + core_mask, off, + NPHY_REV7_RFCTRLOVERRIDE_ID1); break; case NPHY_REV7_RfctrlOverride_cmd_rxgain: rfmxgain = value & 0x000ff; lpfgain = value & 0x0ff00; lpfgain = lpfgain >> 8; - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), - rfmxgain, core_mask, - off, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x3 << 13), - lpfgain, core_mask, - off, - NPHY_REV7_RFCTRLOVERRIDE_ID0); + wlc_phy_rfctrl_override_nphy_rev7( + pi, (0x1 << 11), + rfmxgain, core_mask, + off, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + wlc_phy_rfctrl_override_nphy_rev7( + pi, (0x3 << 13), + lpfgain, core_mask, + off, + NPHY_REV7_RFCTRLOVERRIDE_ID0); break; case NPHY_REV7_RfctrlOverride_cmd_txgain: tgain = value & 0x7fff; lpfgain = value & 0x8000; lpfgain = lpfgain >> 14; - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12), - tgain, core_mask, off, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 13), - lpfgain, core_mask, - off, - NPHY_REV7_RFCTRLOVERRIDE_ID0); + wlc_phy_rfctrl_override_nphy_rev7( + pi, (0x1 << 12), + tgain, core_mask, off, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + wlc_phy_rfctrl_override_nphy_rev7( + pi, (0x1 << 13), + lpfgain, core_mask, + off, + NPHY_REV7_RFCTRLOVERRIDE_ID0); break; } } @@ -20283,137 +21605,164 @@ wlc_phy_scale_offset_rssi_nphy(struct brcms_phy *pi, u16 scale, s8 offset, u16 valuetostuff; offset = (offset > NPHY_RSSICAL_MAXREAD) ? - NPHY_RSSICAL_MAXREAD : offset; + NPHY_RSSICAL_MAXREAD : offset; offset = (offset < (-NPHY_RSSICAL_MAXREAD - 1)) ? - -NPHY_RSSICAL_MAXREAD - 1 : offset; + -NPHY_RSSICAL_MAXREAD - 1 : offset; valuetostuff = ((scale & 0x3f) << 8) | (offset & 0x3f); if (((coresel == RADIO_MIMO_CORESEL_CORE1) || (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_NB)) { + (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_NB)) write_phy_reg(pi, 0x1a6, valuetostuff); - } + if (((coresel == RADIO_MIMO_CORESEL_CORE1) || (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_NB)) { + (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_NB)) write_phy_reg(pi, 0x1ac, valuetostuff); - } + if (((coresel == RADIO_MIMO_CORESEL_CORE2) || (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_NB)) { + (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_NB)) write_phy_reg(pi, 0x1b2, valuetostuff); - } + if (((coresel == RADIO_MIMO_CORESEL_CORE2) || (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_NB)) { + (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_NB)) write_phy_reg(pi, 0x1b8, valuetostuff); - } if (((coresel == RADIO_MIMO_CORESEL_CORE1) || (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W1)) { + (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W1)) write_phy_reg(pi, 0x1a4, valuetostuff); - } + if (((coresel == RADIO_MIMO_CORESEL_CORE1) || (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W1)) { + (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W1)) write_phy_reg(pi, 0x1aa, valuetostuff); - } + if (((coresel == RADIO_MIMO_CORESEL_CORE2) || (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W1)) { + (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W1)) write_phy_reg(pi, 0x1b0, valuetostuff); - } + if (((coresel == RADIO_MIMO_CORESEL_CORE2) || (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W1)) { + (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W1)) write_phy_reg(pi, 0x1b6, valuetostuff); - } if (((coresel == RADIO_MIMO_CORESEL_CORE1) || (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W2)) { + (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W2)) write_phy_reg(pi, 0x1a5, valuetostuff); - } if (((coresel == RADIO_MIMO_CORESEL_CORE1) || (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W2)) { + (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W2)) write_phy_reg(pi, 0x1ab, valuetostuff); - } + if (((coresel == RADIO_MIMO_CORESEL_CORE2) || (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W2)) { + (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_W2)) write_phy_reg(pi, 0x1b1, valuetostuff); - } + if (((coresel == RADIO_MIMO_CORESEL_CORE2) || (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W2)) { + (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_W2)) write_phy_reg(pi, 0x1b7, valuetostuff); - } if (((coresel == RADIO_MIMO_CORESEL_CORE1) || (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_TBD)) { + (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_TBD)) write_phy_reg(pi, 0x1a7, valuetostuff); - } if (((coresel == RADIO_MIMO_CORESEL_CORE1) || (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_TBD)) { + (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_TBD)) write_phy_reg(pi, 0x1ad, valuetostuff); - } if (((coresel == RADIO_MIMO_CORESEL_CORE2) || (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_TBD)) { + (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_TBD)) write_phy_reg(pi, 0x1b3, valuetostuff); - } if (((coresel == RADIO_MIMO_CORESEL_CORE2) || (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_TBD)) { + (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_TBD)) write_phy_reg(pi, 0x1b9, valuetostuff); - } if (((coresel == RADIO_MIMO_CORESEL_CORE1) || (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_IQ)) { + (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_IQ)) write_phy_reg(pi, 0x1a8, valuetostuff); - } + if (((coresel == RADIO_MIMO_CORESEL_CORE1) || (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_IQ)) { + (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_IQ)) write_phy_reg(pi, 0x1ae, valuetostuff); - } + if (((coresel == RADIO_MIMO_CORESEL_CORE2) || (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_IQ)) { + (rail == NPHY_RAIL_I) && (rssi_type == NPHY_RSSI_SEL_IQ)) write_phy_reg(pi, 0x1b4, valuetostuff); - } + if (((coresel == RADIO_MIMO_CORESEL_CORE2) || (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_IQ)) { + (rail == NPHY_RAIL_Q) && (rssi_type == NPHY_RSSI_SEL_IQ)) write_phy_reg(pi, 0x1ba, valuetostuff); - } if (((coresel == RADIO_MIMO_CORESEL_CORE1) || (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rssi_type == NPHY_RSSI_SEL_TSSI_2G)) { + (rssi_type == NPHY_RSSI_SEL_TSSI_2G)) write_phy_reg(pi, 0x1a9, valuetostuff); - } if (((coresel == RADIO_MIMO_CORESEL_CORE2) || (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rssi_type == NPHY_RSSI_SEL_TSSI_2G)) { + (rssi_type == NPHY_RSSI_SEL_TSSI_2G)) write_phy_reg(pi, 0x1b5, valuetostuff); - } if (((coresel == RADIO_MIMO_CORESEL_CORE1) || (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rssi_type == NPHY_RSSI_SEL_TSSI_5G)) { + (rssi_type == NPHY_RSSI_SEL_TSSI_5G)) write_phy_reg(pi, 0x1af, valuetostuff); - } + if (((coresel == RADIO_MIMO_CORESEL_CORE2) || (coresel == RADIO_MIMO_CORESEL_ALLRX)) && - (rssi_type == NPHY_RSSI_SEL_TSSI_5G)) { + (rssi_type == NPHY_RSSI_SEL_TSSI_5G)) write_phy_reg(pi, 0x1bb, valuetostuff); +} + +static void brcms_phy_wr_tx_mux(struct brcms_phy *pi, u8 core) +{ + if (PHY_IPA(pi)) { + if (NREV_GE(pi->pubpi.phy_rev, 7)) + write_radio_reg(pi, + ((core == PHY_CORE_0) ? + RADIO_2057_TX0_TX_SSI_MUX : + RADIO_2057_TX1_TX_SSI_MUX), + (CHSPEC_IS5G(pi->radio_chanspec) ? + 0xc : 0xe)); + else + write_radio_reg(pi, + RADIO_2056_TX_TX_SSI_MUX | + ((core == PHY_CORE_0) ? + RADIO_2056_TX0 : RADIO_2056_TX1), + (CHSPEC_IS5G(pi->radio_chanspec) ? + 0xc : 0xe)); + } else { + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + write_radio_reg(pi, + ((core == PHY_CORE_0) ? + RADIO_2057_TX0_TX_SSI_MUX : + RADIO_2057_TX1_TX_SSI_MUX), + 0x11); + + if (pi->pubpi.radioid == BCM2057_ID) + write_radio_reg(pi, + RADIO_2057_IQTEST_SEL_PU, 0x1); + + } else { + write_radio_reg(pi, + RADIO_2056_TX_TX_SSI_MUX | + ((core == PHY_CORE_0) ? + RADIO_2056_TX0 : RADIO_2056_TX1), + 0x11); + } } } @@ -20440,7 +21789,7 @@ void wlc_phy_rssisel_nphy(struct brcms_phy *pi, u8 core_code, u8 rssi_type) mod_phy_reg(pi, 0xe6, (0x1 << 5), 0); mask = (0x1 << 2) | - (0x1 << 3) | (0x1 << 4) | (0x1 << 5); + (0x1 << 3) | (0x1 << 4) | (0x1 << 5); mod_phy_reg(pi, 0xf9, mask, 0); mod_phy_reg(pi, 0xfb, mask, 0); @@ -20459,23 +21808,22 @@ void wlc_phy_rssisel_nphy(struct brcms_phy *pi, u8 core_code, u8 rssi_type) if (rssi_type == NPHY_RSSI_SEL_W1 || rssi_type == NPHY_RSSI_SEL_W2 || rssi_type == NPHY_RSSI_SEL_NB) { - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0xa6 : 0xa7, (0x3 << 8), 0); mask = (0x1 << 2) | - (0x1 << 3) | - (0x1 << 4) | (0x1 << 5); + (0x1 << 3) | + (0x1 << 4) | (0x1 << 5); mod_phy_reg(pi, (core == PHY_CORE_0) ? 0xf9 : 0xfb, mask, 0); if (rssi_type == NPHY_RSSI_SEL_W1) { - if (CHSPEC_IS5G - (pi->radio_chanspec)) { + if (CHSPEC_IS5G( + pi->radio_chanspec)) { mask = (0x1 << 2); val = 1 << 2; } else { @@ -20501,7 +21849,6 @@ void wlc_phy_rssisel_nphy(struct brcms_phy *pi, u8 core_code, u8 rssi_type) 0xe5 : 0xe6, mask, val); } else { if (rssi_type == NPHY_RSSI_SEL_TBD) { - mask = (0x3 << 8); val = 1 << 8; mod_phy_reg(pi, @@ -20516,7 +21863,6 @@ void wlc_phy_rssisel_nphy(struct brcms_phy *pi, u8 core_code, u8 rssi_type) : 0xa7, mask, val); } else if (rssi_type == NPHY_RSSI_SEL_IQ) { - mask = (0x3 << 8); val = 2 << 8; mod_phy_reg(pi, @@ -20530,7 +21876,6 @@ void wlc_phy_rssisel_nphy(struct brcms_phy *pi, u8 core_code, u8 rssi_type) PHY_CORE_0) ? 0xa6 : 0xa7, mask, val); } else { - mask = (0x3 << 8); val = 3 << 8; mod_phy_reg(pi, @@ -20543,86 +21888,13 @@ void wlc_phy_rssisel_nphy(struct brcms_phy *pi, u8 core_code, u8 rssi_type) (core == PHY_CORE_0) ? 0xa6 : 0xa7, mask, val); - - if (PHY_IPA(pi)) { - if (NREV_GE - (pi->pubpi.phy_rev, - 7)) { - - write_radio_reg - (pi, - ((core == - PHY_CORE_0) - ? - RADIO_2057_TX0_TX_SSI_MUX - : - RADIO_2057_TX1_TX_SSI_MUX), - (CHSPEC_IS5G - (pi-> - radio_chanspec) - ? 0xc : - 0xe)); - } else { - write_radio_reg - (pi, - RADIO_2056_TX_TX_SSI_MUX - | - ((core == - PHY_CORE_0) - ? - RADIO_2056_TX0 - : - RADIO_2056_TX1), - (CHSPEC_IS5G - (pi-> - radio_chanspec) - ? 0xc : - 0xe)); - } - } else { - - if (NREV_GE - (pi->pubpi.phy_rev, - 7)) { - write_radio_reg - (pi, - ((core == - PHY_CORE_0) - ? - RADIO_2057_TX0_TX_SSI_MUX - : - RADIO_2057_TX1_TX_SSI_MUX), - 0x11); - - if (pi->pubpi. - radioid == - BCM2057_ID) - write_radio_reg - (pi, - RADIO_2057_IQTEST_SEL_PU, - 0x1); - - } else { - write_radio_reg - (pi, - RADIO_2056_TX_TX_SSI_MUX - | - ((core == - PHY_CORE_0) - ? - RADIO_2056_TX0 - : - RADIO_2056_TX1), - 0x11); - } - } - + brcms_phy_wr_tx_mux(pi, core); afectrlovr_rssi_val = 1 << 9; mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0x8f - : 0xa5, (0x1 << 9), - afectrlovr_rssi_val); + (core == + PHY_CORE_0) ? 0x8f + : 0xa5, (0x1 << 9), + afectrlovr_rssi_val); } } } @@ -20631,19 +21903,15 @@ void wlc_phy_rssisel_nphy(struct brcms_phy *pi, u8 core_code, u8 rssi_type) if ((rssi_type == NPHY_RSSI_SEL_W1) || (rssi_type == NPHY_RSSI_SEL_W2) || - (rssi_type == NPHY_RSSI_SEL_NB)) { - + (rssi_type == NPHY_RSSI_SEL_NB)) val = 0x0; - } else if (rssi_type == NPHY_RSSI_SEL_TBD) { - + else if (rssi_type == NPHY_RSSI_SEL_TBD) val = 0x1; - } else if (rssi_type == NPHY_RSSI_SEL_IQ) { - + else if (rssi_type == NPHY_RSSI_SEL_IQ) val = 0x2; - } else { - + else val = 0x3; - } + mask = ((0x3 << 12) | (0x3 << 14)); val = (val << 12) | (val << 14); mod_phy_reg(pi, 0xa6, mask, val); @@ -20652,15 +21920,13 @@ void wlc_phy_rssisel_nphy(struct brcms_phy *pi, u8 core_code, u8 rssi_type) if ((rssi_type == NPHY_RSSI_SEL_W1) || (rssi_type == NPHY_RSSI_SEL_W2) || (rssi_type == NPHY_RSSI_SEL_NB)) { - if (rssi_type == NPHY_RSSI_SEL_W1) { + if (rssi_type == NPHY_RSSI_SEL_W1) val = 0x1; - } - if (rssi_type == NPHY_RSSI_SEL_W2) { + if (rssi_type == NPHY_RSSI_SEL_W2) val = 0x2; - } - if (rssi_type == NPHY_RSSI_SEL_NB) { + if (rssi_type == NPHY_RSSI_SEL_NB) val = 0x3; - } + mask = (0x3 << 4); val = (val << 4); mod_phy_reg(pi, 0x7a, mask, val); @@ -20698,16 +21964,16 @@ void wlc_phy_rssisel_nphy(struct brcms_phy *pi, u8 core_code, u8 rssi_type) (rssi_type == NPHY_RSSI_SEL_NB)) { rfctrlcmd_mask = ((0x1 << 8) | (0x7 << 3)); rfctrlcmd_val = (rfctrlcmd_rxen_val << 8) | - (rfctrlcmd_coresel_val << 3); + (rfctrlcmd_coresel_val << 3); rfctrlovr_mask = ((0x1 << 5) | (0x1 << 12) | (0x1 << 1) | (0x1 << 0)); rfctrlovr_val = (rfctrlovr_rssi_val << 5) | - (rfctrlovr_rxen_val << 12) | - (rfctrlovr_coresel_val << 1) | - (rfctrlovr_trigger_val << 0); + (rfctrlovr_rxen_val << 12) | + (rfctrlovr_coresel_val << 1) | + (rfctrlovr_trigger_val << 0); mod_phy_reg(pi, 0x78, rfctrlcmd_mask, rfctrlcmd_val); mod_phy_reg(pi, 0xec, rfctrlovr_mask, rfctrlovr_val); @@ -20762,13 +22028,11 @@ wlc_phy_poll_rssi_nphy(struct brcms_phy *pi, u8 rssi_type, s32 *rssi_buf, wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_ALLRX, rssi_type); gpiosel_orig = read_phy_reg(pi, 0xca); - if (NREV_LT(pi->pubpi.phy_rev, 2)) { + if (NREV_LT(pi->pubpi.phy_rev, 2)) write_phy_reg(pi, 0xca, 5); - } - for (ctr = 0; ctr < 4; ctr++) { + for (ctr = 0; ctr < 4; ctr++) rssi_buf[ctr] = 0; - } for (samp = 0; samp < nsamps; samp++) { if (NREV_LT(pi->pubpi.phy_rev, 2)) { @@ -20785,9 +22049,8 @@ wlc_phy_poll_rssi_nphy(struct brcms_phy *pi, u8 rssi_type, s32 *rssi_buf, tmp_buf[ctr++] = ((s8) ((rssi1 & 0x3f) << 2)) >> 2; tmp_buf[ctr++] = ((s8) (((rssi1 >> 8) & 0x3f) << 2)) >> 2; - for (ctr = 0; ctr < 4; ctr++) { + for (ctr = 0; ctr < 4; ctr++) rssi_buf[ctr] += tmp_buf[ctr]; - } } @@ -20796,9 +22059,8 @@ wlc_phy_poll_rssi_nphy(struct brcms_phy *pi, u8 rssi_type, s32 *rssi_buf, rssi_out_val |= (rssi_buf[1] & 0xff) << 16; rssi_out_val |= (rssi_buf[0] & 0xff) << 24; - if (NREV_LT(pi->pubpi.phy_rev, 2)) { + if (NREV_LT(pi->pubpi.phy_rev, 2)) write_phy_reg(pi, 0xca, gpiosel_orig); - } write_phy_reg(pi, 0xa6, afectrlCore1_save); write_phy_reg(pi, 0xa7, afectrlCore2_save); @@ -20848,7 +22110,7 @@ s16 wlc_phy_tempsense_nphy(struct brcms_phy *pi) u16 tempsense_Rcal; syn_tempprocsense_save = - read_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG); + read_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG); afectrlCore1_save = read_phy_reg(pi, 0xa6); afectrlCore2_save = read_phy_reg(pi, 0xa7); @@ -20982,7 +22244,7 @@ s16 wlc_phy_tempsense_nphy(struct brcms_phy *pi) } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { syn_tempprocsense_save = - read_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE); + read_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE); afectrlCore1_save = read_phy_reg(pi, 0xa6); afectrlCore2_save = read_phy_reg(pi, 0xa7); @@ -20997,14 +22259,13 @@ s16 wlc_phy_tempsense_nphy(struct brcms_phy *pi) write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE, 0x05); wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_IQ, radio_temp2, 1); - if (NREV_GE(pi->pubpi.phy_rev, 7)) { + if (NREV_GE(pi->pubpi.phy_rev, 7)) write_radio_reg(pi, RADIO_2057_TEMPSENSE_CONFIG, 0x01); - } else { + else write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE, 0x01); - } radio_temp[0] = - (126 * (radio_temp[1] + radio_temp2[1]) + 3987) / 64; + (126 * (radio_temp[1] + radio_temp2[1]) + 3987) / 64; write_radio_reg(pi, RADIO_2056_SYN_TEMPPROCSENSE, syn_tempprocsense_save); @@ -21019,17 +22280,17 @@ s16 wlc_phy_tempsense_nphy(struct brcms_phy *pi) } else { pwrdet_rxtx_core1_save = - read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1); + read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1); pwrdet_rxtx_core2_save = - read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2); + read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2); core1_txrf_iqcal1_save = - read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1); + read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1); core1_txrf_iqcal2_save = - read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2); + read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2); core2_txrf_iqcal1_save = - read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1); + read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1); core2_txrf_iqcal2_save = - read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2); + read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2); pd_pll_ts_save = read_radio_reg(pi, RADIO_2055_PD_PLL_TS); afectrlCore1_save = read_phy_reg(pi, 0xa6); @@ -21060,11 +22321,12 @@ s16 wlc_phy_tempsense_nphy(struct brcms_phy *pi) radio_temp[3] = (radio_temp[3] + radio_temp2[3]); radio_temp[0] = - (radio_temp[0] + radio_temp[1] + radio_temp[2] + - radio_temp[3]); + (radio_temp[0] + radio_temp[1] + radio_temp[2] + + radio_temp[3]); radio_temp[0] = - (radio_temp[0] + (8 * 32)) * (950 - 350) / 63 + (350 * 8); + (radio_temp[0] + + (8 * 32)) * (950 - 350) / 63 + (350 * 8); radio_temp[0] = (radio_temp[0] - (8 * 420)) / 38; @@ -21126,518 +22388,21 @@ wlc_phy_set_rssi_2055_vcm(struct brcms_phy *pi, u8 rssi_type, u8 *vcm_buf) RADIO_2055_NBRSSI_VCM_Q_SHIFT); } } else { - - if (core == PHY_CORE_0) { + if (core == PHY_CORE_0) mod_radio_reg(pi, RADIO_2055_CORE1_RXBB_RSSI_CTRL5, RADIO_2055_WBRSSI_VCM_IQ_MASK, vcm_buf[2 * core] << RADIO_2055_WBRSSI_VCM_IQ_SHIFT); - } else { + else mod_radio_reg(pi, RADIO_2055_CORE2_RXBB_RSSI_CTRL5, RADIO_2055_WBRSSI_VCM_IQ_MASK, vcm_buf[2 * core] << RADIO_2055_WBRSSI_VCM_IQ_SHIFT); - } - } - } -} - -void wlc_phy_rssi_cal_nphy(struct brcms_phy *pi) -{ - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - - wlc_phy_rssi_cal_nphy_rev3(pi); - } else { - wlc_phy_rssi_cal_nphy_rev2(pi, NPHY_RSSI_SEL_NB); - wlc_phy_rssi_cal_nphy_rev2(pi, NPHY_RSSI_SEL_W1); - wlc_phy_rssi_cal_nphy_rev2(pi, NPHY_RSSI_SEL_W2); - } -} - -static void wlc_phy_rssi_cal_nphy_rev2(struct brcms_phy *pi, u8 rssi_type) -{ - s32 target_code; - u16 classif_state; - u16 clip_state[2]; - u16 rssi_ctrl_state[2], pd_state[2]; - u16 rfctrlintc_state[2], rfpdcorerxtx_state[2]; - u16 rfctrlintc_override_val; - u16 clip_off[] = { 0xffff, 0xffff }; - u16 rf_pd_val, pd_mask, rssi_ctrl_mask; - u8 vcm, min_vcm, vcm_tmp[4]; - u8 vcm_final[4] = { 0, 0, 0, 0 }; - u8 result_idx, ctr; - s32 poll_results[4][4] = { - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0}, - {0, 0, 0, 0} - }; - s32 poll_miniq[4][2] = { - {0, 0}, - {0, 0}, - {0, 0}, - {0, 0} - }; - s32 min_d, curr_d; - s32 fine_digital_offset[4]; - s32 poll_results_min[4] = { 0, 0, 0, 0 }; - s32 min_poll; - - switch (rssi_type) { - case NPHY_RSSI_SEL_NB: - target_code = NPHY_RSSICAL_NB_TARGET; - break; - case NPHY_RSSI_SEL_W1: - target_code = NPHY_RSSICAL_W1_TARGET; - break; - case NPHY_RSSI_SEL_W2: - target_code = NPHY_RSSICAL_W2_TARGET; - break; - default: - return; - break; - } - - classif_state = wlc_phy_classifier_nphy(pi, 0, 0); - wlc_phy_classifier_nphy(pi, (0x7 << 0), 4); - wlc_phy_clip_det_nphy(pi, 0, clip_state); - wlc_phy_clip_det_nphy(pi, 1, clip_off); - - rf_pd_val = (rssi_type == NPHY_RSSI_SEL_NB) ? 0x6 : 0x4; - rfctrlintc_override_val = - CHSPEC_IS5G(pi->radio_chanspec) ? 0x140 : 0x110; - - rfctrlintc_state[0] = read_phy_reg(pi, 0x91); - rfpdcorerxtx_state[0] = read_radio_reg(pi, RADIO_2055_PD_CORE1_RXTX); - write_phy_reg(pi, 0x91, rfctrlintc_override_val); - write_radio_reg(pi, RADIO_2055_PD_CORE1_RXTX, rf_pd_val); - - rfctrlintc_state[1] = read_phy_reg(pi, 0x92); - rfpdcorerxtx_state[1] = read_radio_reg(pi, RADIO_2055_PD_CORE2_RXTX); - write_phy_reg(pi, 0x92, rfctrlintc_override_val); - write_radio_reg(pi, RADIO_2055_PD_CORE2_RXTX, rf_pd_val); - - pd_mask = RADIO_2055_NBRSSI_PD | RADIO_2055_WBRSSI_G1_PD | - RADIO_2055_WBRSSI_G2_PD; - pd_state[0] = - read_radio_reg(pi, RADIO_2055_PD_CORE1_RSSI_MISC) & pd_mask; - pd_state[1] = - read_radio_reg(pi, RADIO_2055_PD_CORE2_RSSI_MISC) & pd_mask; - mod_radio_reg(pi, RADIO_2055_PD_CORE1_RSSI_MISC, pd_mask, 0); - mod_radio_reg(pi, RADIO_2055_PD_CORE2_RSSI_MISC, pd_mask, 0); - rssi_ctrl_mask = RADIO_2055_NBRSSI_SEL | RADIO_2055_WBRSSI_G1_SEL | - RADIO_2055_WBRSSI_G2_SEL; - rssi_ctrl_state[0] = - read_radio_reg(pi, RADIO_2055_SP_RSSI_CORE1) & rssi_ctrl_mask; - rssi_ctrl_state[1] = - read_radio_reg(pi, RADIO_2055_SP_RSSI_CORE2) & rssi_ctrl_mask; - wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_ALLRX, rssi_type); - - wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0, RADIO_MIMO_CORESEL_ALLRX, - NPHY_RAIL_I, rssi_type); - wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0, RADIO_MIMO_CORESEL_ALLRX, - NPHY_RAIL_Q, rssi_type); - - for (vcm = 0; vcm < 4; vcm++) { - - vcm_tmp[0] = vcm_tmp[1] = vcm_tmp[2] = vcm_tmp[3] = vcm; - if (rssi_type != NPHY_RSSI_SEL_W2) { - wlc_phy_set_rssi_2055_vcm(pi, rssi_type, vcm_tmp); - } - - wlc_phy_poll_rssi_nphy(pi, rssi_type, &poll_results[vcm][0], - NPHY_RSSICAL_NPOLL); - - if ((rssi_type == NPHY_RSSI_SEL_W1) - || (rssi_type == NPHY_RSSI_SEL_W2)) { - for (ctr = 0; ctr < 2; ctr++) { - poll_miniq[vcm][ctr] = - min(poll_results[vcm][ctr * 2 + 0], - poll_results[vcm][ctr * 2 + 1]); - } - } - } - - for (result_idx = 0; result_idx < 4; result_idx++) { - min_d = NPHY_RSSICAL_MAXD; - min_vcm = 0; - min_poll = NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL + 1; - for (vcm = 0; vcm < 4; vcm++) { - curr_d = ABS(((rssi_type == NPHY_RSSI_SEL_NB) ? - poll_results[vcm][result_idx] : - poll_miniq[vcm][result_idx / 2]) - - (target_code * NPHY_RSSICAL_NPOLL)); - if (curr_d < min_d) { - min_d = curr_d; - min_vcm = vcm; - } - if (poll_results[vcm][result_idx] < min_poll) { - min_poll = poll_results[vcm][result_idx]; - } - } - vcm_final[result_idx] = min_vcm; - poll_results_min[result_idx] = min_poll; - } - - if (rssi_type != NPHY_RSSI_SEL_W2) { - wlc_phy_set_rssi_2055_vcm(pi, rssi_type, vcm_final); - } - - for (result_idx = 0; result_idx < 4; result_idx++) { - fine_digital_offset[result_idx] = - (target_code * NPHY_RSSICAL_NPOLL) - - poll_results[vcm_final[result_idx]][result_idx]; - if (fine_digital_offset[result_idx] < 0) { - fine_digital_offset[result_idx] = - ABS(fine_digital_offset[result_idx]); - fine_digital_offset[result_idx] += - (NPHY_RSSICAL_NPOLL / 2); - fine_digital_offset[result_idx] /= NPHY_RSSICAL_NPOLL; - fine_digital_offset[result_idx] = - -fine_digital_offset[result_idx]; - } else { - fine_digital_offset[result_idx] += - (NPHY_RSSICAL_NPOLL / 2); - fine_digital_offset[result_idx] /= NPHY_RSSICAL_NPOLL; - } - - if (poll_results_min[result_idx] == - NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL) { - fine_digital_offset[result_idx] = - (target_code - NPHY_RSSICAL_MAXREAD - 1); - } - - wlc_phy_scale_offset_rssi_nphy(pi, 0x0, - (s8) - fine_digital_offset[result_idx], - (result_idx / 2 == - 0) ? RADIO_MIMO_CORESEL_CORE1 : - RADIO_MIMO_CORESEL_CORE2, - (result_idx % 2 == - 0) ? NPHY_RAIL_I : NPHY_RAIL_Q, - rssi_type); - } - - mod_radio_reg(pi, RADIO_2055_PD_CORE1_RSSI_MISC, pd_mask, pd_state[0]); - mod_radio_reg(pi, RADIO_2055_PD_CORE2_RSSI_MISC, pd_mask, pd_state[1]); - if (rssi_ctrl_state[0] == RADIO_2055_NBRSSI_SEL) { - wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1, - NPHY_RSSI_SEL_NB); - } else if (rssi_ctrl_state[0] == RADIO_2055_WBRSSI_G1_SEL) { - wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1, - NPHY_RSSI_SEL_W1); - } else if (rssi_ctrl_state[0] == RADIO_2055_WBRSSI_G2_SEL) { - wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1, - NPHY_RSSI_SEL_W2); - } else { - wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1, - NPHY_RSSI_SEL_W2); - } - if (rssi_ctrl_state[1] == RADIO_2055_NBRSSI_SEL) { - wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2, - NPHY_RSSI_SEL_NB); - } else if (rssi_ctrl_state[1] == RADIO_2055_WBRSSI_G1_SEL) { - wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2, - NPHY_RSSI_SEL_W1); - } else if (rssi_ctrl_state[1] == RADIO_2055_WBRSSI_G2_SEL) { - wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2, - NPHY_RSSI_SEL_W2); - } else { - wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2, - NPHY_RSSI_SEL_W2); - } - - wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_OFF, rssi_type); - - write_phy_reg(pi, 0x91, rfctrlintc_state[0]); - write_radio_reg(pi, RADIO_2055_PD_CORE1_RXTX, rfpdcorerxtx_state[0]); - write_phy_reg(pi, 0x92, rfctrlintc_state[1]); - write_radio_reg(pi, RADIO_2055_PD_CORE2_RXTX, rfpdcorerxtx_state[1]); - - wlc_phy_classifier_nphy(pi, (0x7 << 0), classif_state); - wlc_phy_clip_det_nphy(pi, 1, clip_state); - - wlc_phy_resetcca_nphy(pi); -} - -int -wlc_phy_rssi_compute_nphy(struct brcms_phy *pi, struct brcms_d11rxhdr *wlc_rxh) -{ - struct d11rxhdr *rxh = &wlc_rxh->rxhdr; - s16 rxpwr, rxpwr0, rxpwr1; - s16 phyRx0_l, phyRx2_l; - - rxpwr = 0; - rxpwr0 = le16_to_cpu(rxh->PhyRxStatus_1) & PRXS1_nphy_PWR0_MASK; - rxpwr1 = (le16_to_cpu(rxh->PhyRxStatus_1) & PRXS1_nphy_PWR1_MASK) >> 8; - - if (rxpwr0 > 127) - rxpwr0 -= 256; - if (rxpwr1 > 127) - rxpwr1 -= 256; - - phyRx0_l = le16_to_cpu(rxh->PhyRxStatus_0) & 0x00ff; - phyRx2_l = le16_to_cpu(rxh->PhyRxStatus_2) & 0x00ff; - if (phyRx2_l > 127) - phyRx2_l -= 256; - - if (((rxpwr0 == 16) || (rxpwr0 == 32))) { - rxpwr0 = rxpwr1; - rxpwr1 = phyRx2_l; - } - - wlc_rxh->rxpwr[0] = (s8) rxpwr0; - wlc_rxh->rxpwr[1] = (s8) rxpwr1; - wlc_rxh->do_rssi_ma = 0; - - if (pi->sh->rssi_mode == RSSI_ANT_MERGE_MAX) - rxpwr = (rxpwr0 > rxpwr1) ? rxpwr0 : rxpwr1; - else if (pi->sh->rssi_mode == RSSI_ANT_MERGE_MIN) - rxpwr = (rxpwr0 < rxpwr1) ? rxpwr0 : rxpwr1; - else if (pi->sh->rssi_mode == RSSI_ANT_MERGE_AVG) - rxpwr = (rxpwr0 + rxpwr1) >> 1; - - return rxpwr; -} - -static void -wlc_phy_rfctrlintc_override_nphy(struct brcms_phy *pi, u8 field, u16 value, - u8 core_code) -{ - u16 mask; - u16 val; - u8 core; - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - for (core = 0; core < pi->pubpi.phy_corenum; core++) { - if (core_code == RADIO_MIMO_CORESEL_CORE1 - && core == PHY_CORE_1) - continue; - else if (core_code == RADIO_MIMO_CORESEL_CORE2 - && core == PHY_CORE_0) - continue; - - if (NREV_LT(pi->pubpi.phy_rev, 7)) { - - mask = (0x1 << 10); - val = 1 << 10; - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x91 : - 0x92, mask, val); - } - - if (field == NPHY_RfctrlIntc_override_OFF) { - - write_phy_reg(pi, (core == PHY_CORE_0) ? 0x91 : - 0x92, 0); - - wlc_phy_force_rfseq_nphy(pi, - NPHY_RFSEQ_RESET2RX); - } else if (field == NPHY_RfctrlIntc_override_TRSW) { - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - - mask = (0x1 << 6) | (0x1 << 7); - - val = value << 6; - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0x91 : 0x92, - mask, val); - - or_phy_reg(pi, - (core == - PHY_CORE_0) ? 0x91 : 0x92, - (0x1 << 10)); - - and_phy_reg(pi, 0x2ff, (u16) - ~(0x3 << 14)); - or_phy_reg(pi, 0x2ff, (0x1 << 13)); - or_phy_reg(pi, 0x2ff, (0x1 << 0)); - } else { - - mask = (0x1 << 6) | - (0x1 << 7) | - (0x1 << 8) | (0x1 << 9); - val = value << 6; - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0x91 : 0x92, - mask, val); - - mask = (0x1 << 0); - val = 1 << 0; - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0xe7 : 0xec, - mask, val); - - mask = (core == PHY_CORE_0) ? (0x1 << 0) - : (0x1 << 1); - val = 1 << ((core == PHY_CORE_0) ? - 0 : 1); - mod_phy_reg(pi, 0x78, mask, val); - - SPINWAIT(((read_phy_reg(pi, 0x78) & val) - != 0), 10000); - if (WARN(read_phy_reg(pi, 0x78) & val, - "HW error: override failed")) - return; - - mask = (0x1 << 0); - val = 0 << 0; - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0xe7 : 0xec, - mask, val); - } - } else if (field == NPHY_RfctrlIntc_override_PA) { - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - - mask = (0x1 << 4) | (0x1 << 5); - - if (CHSPEC_IS5G(pi->radio_chanspec)) { - val = value << 5; - } else { - val = value << 4; - } - - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0x91 : 0x92, - mask, val); - - or_phy_reg(pi, - (core == - PHY_CORE_0) ? 0x91 : 0x92, - (0x1 << 12)); - } else { - - if (CHSPEC_IS5G(pi->radio_chanspec)) { - mask = (0x1 << 5); - val = value << 5; - } else { - mask = (0x1 << 4); - val = value << 4; - } - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0x91 : 0x92, - mask, val); - } - } else if (field == NPHY_RfctrlIntc_override_EXT_LNA_PU) { - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - if (CHSPEC_IS5G(pi->radio_chanspec)) { - - mask = (0x1 << 0); - val = value << 0; - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0x91 - : 0x92, mask, val); - - mask = (0x1 << 2); - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0x91 - : 0x92, mask, 0); - } else { - - mask = (0x1 << 2); - val = value << 2; - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0x91 - : 0x92, mask, val); - - mask = (0x1 << 0); - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0x91 - : 0x92, mask, 0); - } - - mask = (0x1 << 11); - val = 1 << 11; - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0x91 : 0x92, - mask, val); - } else { - - if (CHSPEC_IS5G(pi->radio_chanspec)) { - mask = (0x1 << 0); - val = value << 0; - } else { - mask = (0x1 << 2); - val = value << 2; - } - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0x91 : 0x92, - mask, val); - } - } else if (field == - NPHY_RfctrlIntc_override_EXT_LNA_GAIN) { - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - if (CHSPEC_IS5G(pi->radio_chanspec)) { - - mask = (0x1 << 1); - val = value << 1; - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0x91 - : 0x92, mask, val); - - mask = (0x1 << 3); - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0x91 - : 0x92, mask, 0); - } else { - - mask = (0x1 << 3); - val = value << 3; - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0x91 - : 0x92, mask, val); - - mask = (0x1 << 1); - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0x91 - : 0x92, mask, 0); - } - - mask = (0x1 << 11); - val = 1 << 11; - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0x91 : 0x92, - mask, val); - } else { - - if (CHSPEC_IS5G(pi->radio_chanspec)) { - mask = (0x1 << 1); - val = value << 1; - } else { - mask = (0x1 << 3); - val = value << 3; - } - mod_phy_reg(pi, - (core == - PHY_CORE_0) ? 0x91 : 0x92, - mask, val); - } - } } - } else { - return; } } @@ -21683,10 +22448,14 @@ static void wlc_phy_rssi_cal_nphy_rev3(struct brcms_phy *pi) u16 NPHY_REV7_RfctrlMiscReg3_save, NPHY_REV7_RfctrlMiscReg4_save; u16 NPHY_REV7_RfctrlMiscReg5_save, NPHY_REV7_RfctrlMiscReg6_save; - NPHY_REV7_RfctrlOverride3_save = NPHY_REV7_RfctrlOverride4_save = - NPHY_REV7_RfctrlOverride5_save = NPHY_REV7_RfctrlOverride6_save = - NPHY_REV7_RfctrlMiscReg3_save = NPHY_REV7_RfctrlMiscReg4_save = - NPHY_REV7_RfctrlMiscReg5_save = NPHY_REV7_RfctrlMiscReg6_save = 0; + NPHY_REV7_RfctrlOverride3_save = + NPHY_REV7_RfctrlOverride4_save = + NPHY_REV7_RfctrlOverride5_save = + NPHY_REV7_RfctrlOverride6_save = + NPHY_REV7_RfctrlMiscReg3_save = + NPHY_REV7_RfctrlMiscReg4_save = + NPHY_REV7_RfctrlMiscReg5_save = + NPHY_REV7_RfctrlMiscReg6_save = 0; classif_state = wlc_phy_classifier_nphy(pi, 0, 0); wlc_phy_classifier_nphy(pi, (0x7 << 0), 4); @@ -21726,21 +22495,21 @@ static void wlc_phy_rssi_cal_nphy_rev3(struct brcms_phy *pi) wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_TRSW, 1, RADIO_MIMO_CORESEL_ALLRXTX); - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - wlc_phy_rfctrl_override_1tomany_nphy(pi, - NPHY_REV7_RfctrlOverride_cmd_rxrf_pu, - 0, 0, 0); - } else { + if (NREV_GE(pi->pubpi.phy_rev, 7)) + wlc_phy_rfctrl_override_1tomany_nphy( + pi, + NPHY_REV7_RfctrlOverride_cmd_rxrf_pu, + 0, 0, 0); + else wlc_phy_rfctrl_override_nphy(pi, (0x1 << 0), 0, 0, 0); - } - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - wlc_phy_rfctrl_override_1tomany_nphy(pi, - NPHY_REV7_RfctrlOverride_cmd_rx_pu, - 1, 0, 0); - } else { + if (NREV_GE(pi->pubpi.phy_rev, 7)) + wlc_phy_rfctrl_override_1tomany_nphy( + pi, + NPHY_REV7_RfctrlOverride_cmd_rx_pu, + 1, 0, 0); + else wlc_phy_rfctrl_override_nphy(pi, (0x1 << 1), 1, 0, 0); - } if (NREV_GE(pi->pubpi.phy_rev, 7)) { wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7), @@ -21755,12 +22524,14 @@ static void wlc_phy_rssi_cal_nphy_rev3(struct brcms_phy *pi) if (CHSPEC_IS5G(pi->radio_chanspec)) { if (NREV_GE(pi->pubpi.phy_rev, 7)) { - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5), - 0, 0, 0, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), 1, 0, - 0, - NPHY_REV7_RFCTRLOVERRIDE_ID0); + wlc_phy_rfctrl_override_nphy_rev7( + pi, (0x1 << 5), + 0, 0, 0, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + wlc_phy_rfctrl_override_nphy_rev7( + pi, (0x1 << 4), 1, 0, + 0, + NPHY_REV7_RFCTRLOVERRIDE_ID0); } else { wlc_phy_rfctrl_override_nphy(pi, (0x1 << 5), 0, 0, 0); wlc_phy_rfctrl_override_nphy(pi, (0x1 << 4), 1, 0, 0); @@ -21768,12 +22539,14 @@ static void wlc_phy_rssi_cal_nphy_rev3(struct brcms_phy *pi) } else { if (NREV_GE(pi->pubpi.phy_rev, 7)) { - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), - 0, 0, 0, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5), 1, 0, - 0, - NPHY_REV7_RFCTRLOVERRIDE_ID0); + wlc_phy_rfctrl_override_nphy_rev7( + pi, (0x1 << 4), + 0, 0, 0, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + wlc_phy_rfctrl_override_nphy_rev7( + pi, (0x1 << 5), 1, 0, + 0, + NPHY_REV7_RFCTRLOVERRIDE_ID0); } else { wlc_phy_rfctrl_override_nphy(pi, (0x1 << 4), 0, 0, 0); wlc_phy_rfctrl_override_nphy(pi, (0x1 << 5), 1, 0, 0); @@ -21781,7 +22554,7 @@ static void wlc_phy_rssi_cal_nphy_rev3(struct brcms_phy *pi) } rxcore_state = wlc_phy_rxcore_getstate_nphy( - (struct brcms_phy_pub *) pi); + (struct brcms_phy_pub *) pi); vcm_level_max = 8; @@ -21804,21 +22577,18 @@ static void wlc_phy_rssi_cal_nphy_rev3(struct brcms_phy *pi) NPHY_RAIL_Q, NPHY_RSSI_SEL_NB); for (vcm = 0; vcm < vcm_level_max; vcm++) { - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - + if (NREV_GE(pi->pubpi.phy_rev, 7)) mod_radio_reg(pi, (core == PHY_CORE_0) ? RADIO_2057_NB_MASTER_CORE0 : RADIO_2057_NB_MASTER_CORE1, RADIO_2057_VCM_MASK, vcm); - } else { - + else mod_radio_reg(pi, RADIO_2056_RX_RSSI_MISC | ((core == PHY_CORE_0) ? RADIO_2056_RX0 : RADIO_2056_RX1), RADIO_2056_VCM_MASK, vcm << RADIO_2056_RSSI_VCM_SHIFT); - } wlc_phy_poll_rssi_nphy(pi, NPHY_RSSI_SEL_NB, &poll_results[vcm][0], @@ -21826,92 +22596,90 @@ static void wlc_phy_rssi_cal_nphy_rev3(struct brcms_phy *pi) } for (result_idx = 0; result_idx < 4; result_idx++) { - if ((core == result_idx / 2) && (result_idx % 2 == 0)) { + if ((core == result_idx / 2) && + (result_idx % 2 == 0)) { min_d = NPHY_RSSICAL_MAXD; min_vcm = 0; min_poll = - NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL + - 1; + NPHY_RSSICAL_MAXREAD * + NPHY_RSSICAL_NPOLL + 1; for (vcm = 0; vcm < vcm_level_max; vcm++) { - curr_d = poll_results[vcm][result_idx] * - poll_results[vcm][result_idx] + - poll_results[vcm][result_idx + 1] * - poll_results[vcm][result_idx + 1]; + curr_d = + poll_results[vcm][result_idx] * + poll_results[vcm][result_idx] + + poll_results[vcm][result_idx + + 1] * + poll_results[vcm][result_idx + + 1]; if (curr_d < min_d) { min_d = curr_d; min_vcm = vcm; } if (poll_results[vcm][result_idx] < - min_poll) { + min_poll) min_poll = - poll_results[vcm] - [result_idx]; - } + poll_results[vcm] + [result_idx]; } vcm_final = min_vcm; poll_results_min[result_idx] = min_poll; } } - if (NREV_GE(pi->pubpi.phy_rev, 7)) { + if (NREV_GE(pi->pubpi.phy_rev, 7)) mod_radio_reg(pi, (core == PHY_CORE_0) ? RADIO_2057_NB_MASTER_CORE0 : RADIO_2057_NB_MASTER_CORE1, RADIO_2057_VCM_MASK, vcm_final); - } else { + else mod_radio_reg(pi, RADIO_2056_RX_RSSI_MISC | ((core == PHY_CORE_0) ? RADIO_2056_RX0 : RADIO_2056_RX1), RADIO_2056_VCM_MASK, vcm_final << RADIO_2056_RSSI_VCM_SHIFT); - } for (result_idx = 0; result_idx < 4; result_idx++) { if (core == result_idx / 2) { fine_digital_offset[result_idx] = - (NPHY_RSSICAL_NB_TARGET * - NPHY_RSSICAL_NPOLL) - - poll_results[vcm_final][result_idx]; + (NPHY_RSSICAL_NB_TARGET * + NPHY_RSSICAL_NPOLL) - + poll_results[vcm_final][result_idx]; if (fine_digital_offset[result_idx] < 0) { fine_digital_offset[result_idx] = - ABS(fine_digital_offset - [result_idx]); + ABS(fine_digital_offset + [result_idx]); fine_digital_offset[result_idx] += - (NPHY_RSSICAL_NPOLL / 2); + (NPHY_RSSICAL_NPOLL / 2); fine_digital_offset[result_idx] /= - NPHY_RSSICAL_NPOLL; + NPHY_RSSICAL_NPOLL; fine_digital_offset[result_idx] = - -fine_digital_offset[result_idx]; + -fine_digital_offset[ + result_idx]; } else { fine_digital_offset[result_idx] += - (NPHY_RSSICAL_NPOLL / 2); + (NPHY_RSSICAL_NPOLL / 2); fine_digital_offset[result_idx] /= - NPHY_RSSICAL_NPOLL; + NPHY_RSSICAL_NPOLL; } if (poll_results_min[result_idx] == - NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL) { + NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL) fine_digital_offset[result_idx] = - (NPHY_RSSICAL_NB_TARGET - - NPHY_RSSICAL_MAXREAD - 1); - } - - wlc_phy_scale_offset_rssi_nphy(pi, 0x0, - (s8) - fine_digital_offset - [result_idx], - (result_idx / - 2 == - 0) ? - RADIO_MIMO_CORESEL_CORE1 - : - RADIO_MIMO_CORESEL_CORE2, - (result_idx % - 2 == - 0) ? NPHY_RAIL_I - : NPHY_RAIL_Q, - NPHY_RSSI_SEL_NB); + (NPHY_RSSICAL_NB_TARGET - + NPHY_RSSICAL_MAXREAD - 1); + + wlc_phy_scale_offset_rssi_nphy( + pi, 0x0, + (s8) + fine_digital_offset + [result_idx], + (result_idx / 2 == 0) ? + RADIO_MIMO_CORESEL_CORE1 : + RADIO_MIMO_CORESEL_CORE2, + (result_idx % 2 == 0) ? + NPHY_RAIL_I : NPHY_RAIL_Q, + NPHY_RSSI_SEL_NB); } } @@ -21952,46 +22720,44 @@ static void wlc_phy_rssi_cal_nphy_rev3(struct brcms_phy *pi) for (result_idx = 0; result_idx < 4; result_idx++) { if (core == result_idx / 2) { fine_digital_offset[result_idx] = - (target_code * NPHY_RSSICAL_NPOLL) - - poll_result_core[result_idx]; - if (fine_digital_offset[result_idx] < 0) { + (target_code * + NPHY_RSSICAL_NPOLL) - + poll_result_core[result_idx]; + if (fine_digital_offset[result_idx] < + 0) { fine_digital_offset[result_idx] - = - ABS(fine_digital_offset - [result_idx]); + = ABS( + fine_digital_offset + [result_idx]); fine_digital_offset[result_idx] - += (NPHY_RSSICAL_NPOLL / 2); + += (NPHY_RSSICAL_NPOLL + / 2); fine_digital_offset[result_idx] - /= NPHY_RSSICAL_NPOLL; + /= NPHY_RSSICAL_NPOLL; fine_digital_offset[result_idx] - = - -fine_digital_offset - [result_idx]; + = -fine_digital_offset + [result_idx]; } else { fine_digital_offset[result_idx] - += (NPHY_RSSICAL_NPOLL / 2); + += (NPHY_RSSICAL_NPOLL + / 2); fine_digital_offset[result_idx] - /= NPHY_RSSICAL_NPOLL; + /= NPHY_RSSICAL_NPOLL; } - wlc_phy_scale_offset_rssi_nphy(pi, 0x0, - (s8) - fine_digital_offset - [core * - 2], - (core == - PHY_CORE_0) - ? - RADIO_MIMO_CORESEL_CORE1 - : - RADIO_MIMO_CORESEL_CORE2, - (result_idx - % 2 == - 0) ? - NPHY_RAIL_I - : - NPHY_RAIL_Q, - rssi_type); + wlc_phy_scale_offset_rssi_nphy( + pi, 0x0, + (s8) + fine_digital_offset + [core * + 2], + (core == PHY_CORE_0) ? + RADIO_MIMO_CORESEL_CORE1 : + RADIO_MIMO_CORESEL_CORE2, + (result_idx % 2 == 0) ? + NPHY_RAIL_I : + NPHY_RAIL_Q, + rssi_type); } } @@ -22040,87 +22806,87 @@ static void wlc_phy_rssi_cal_nphy_rev3(struct brcms_phy *pi) if (CHSPEC_IS2G(pi->radio_chanspec)) { if (NREV_GE(pi->pubpi.phy_rev, 7)) { pi->rssical_cache.rssical_radio_regs_2G[0] = - read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0); + read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0); pi->rssical_cache.rssical_radio_regs_2G[1] = - read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1); + read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1); } else { pi->rssical_cache.rssical_radio_regs_2G[0] = - read_radio_reg(pi, - RADIO_2056_RX_RSSI_MISC | - RADIO_2056_RX0); + read_radio_reg(pi, + RADIO_2056_RX_RSSI_MISC | + RADIO_2056_RX0); pi->rssical_cache.rssical_radio_regs_2G[1] = - read_radio_reg(pi, - RADIO_2056_RX_RSSI_MISC | - RADIO_2056_RX1); + read_radio_reg(pi, + RADIO_2056_RX_RSSI_MISC | + RADIO_2056_RX1); } pi->rssical_cache.rssical_phyregs_2G[0] = - read_phy_reg(pi, 0x1a6); + read_phy_reg(pi, 0x1a6); pi->rssical_cache.rssical_phyregs_2G[1] = - read_phy_reg(pi, 0x1ac); + read_phy_reg(pi, 0x1ac); pi->rssical_cache.rssical_phyregs_2G[2] = - read_phy_reg(pi, 0x1b2); + read_phy_reg(pi, 0x1b2); pi->rssical_cache.rssical_phyregs_2G[3] = - read_phy_reg(pi, 0x1b8); + read_phy_reg(pi, 0x1b8); pi->rssical_cache.rssical_phyregs_2G[4] = - read_phy_reg(pi, 0x1a4); + read_phy_reg(pi, 0x1a4); pi->rssical_cache.rssical_phyregs_2G[5] = - read_phy_reg(pi, 0x1aa); + read_phy_reg(pi, 0x1aa); pi->rssical_cache.rssical_phyregs_2G[6] = - read_phy_reg(pi, 0x1b0); + read_phy_reg(pi, 0x1b0); pi->rssical_cache.rssical_phyregs_2G[7] = - read_phy_reg(pi, 0x1b6); + read_phy_reg(pi, 0x1b6); pi->rssical_cache.rssical_phyregs_2G[8] = - read_phy_reg(pi, 0x1a5); + read_phy_reg(pi, 0x1a5); pi->rssical_cache.rssical_phyregs_2G[9] = - read_phy_reg(pi, 0x1ab); + read_phy_reg(pi, 0x1ab); pi->rssical_cache.rssical_phyregs_2G[10] = - read_phy_reg(pi, 0x1b1); + read_phy_reg(pi, 0x1b1); pi->rssical_cache.rssical_phyregs_2G[11] = - read_phy_reg(pi, 0x1b7); + read_phy_reg(pi, 0x1b7); pi->nphy_rssical_chanspec_2G = pi->radio_chanspec; } else { if (NREV_GE(pi->pubpi.phy_rev, 7)) { pi->rssical_cache.rssical_radio_regs_5G[0] = - read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0); + read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0); pi->rssical_cache.rssical_radio_regs_5G[1] = - read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1); + read_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1); } else { pi->rssical_cache.rssical_radio_regs_5G[0] = - read_radio_reg(pi, - RADIO_2056_RX_RSSI_MISC | - RADIO_2056_RX0); + read_radio_reg(pi, + RADIO_2056_RX_RSSI_MISC | + RADIO_2056_RX0); pi->rssical_cache.rssical_radio_regs_5G[1] = - read_radio_reg(pi, - RADIO_2056_RX_RSSI_MISC | - RADIO_2056_RX1); + read_radio_reg(pi, + RADIO_2056_RX_RSSI_MISC | + RADIO_2056_RX1); } pi->rssical_cache.rssical_phyregs_5G[0] = - read_phy_reg(pi, 0x1a6); + read_phy_reg(pi, 0x1a6); pi->rssical_cache.rssical_phyregs_5G[1] = - read_phy_reg(pi, 0x1ac); + read_phy_reg(pi, 0x1ac); pi->rssical_cache.rssical_phyregs_5G[2] = - read_phy_reg(pi, 0x1b2); + read_phy_reg(pi, 0x1b2); pi->rssical_cache.rssical_phyregs_5G[3] = - read_phy_reg(pi, 0x1b8); + read_phy_reg(pi, 0x1b8); pi->rssical_cache.rssical_phyregs_5G[4] = - read_phy_reg(pi, 0x1a4); + read_phy_reg(pi, 0x1a4); pi->rssical_cache.rssical_phyregs_5G[5] = - read_phy_reg(pi, 0x1aa); + read_phy_reg(pi, 0x1aa); pi->rssical_cache.rssical_phyregs_5G[6] = - read_phy_reg(pi, 0x1b0); + read_phy_reg(pi, 0x1b0); pi->rssical_cache.rssical_phyregs_5G[7] = - read_phy_reg(pi, 0x1b6); + read_phy_reg(pi, 0x1b6); pi->rssical_cache.rssical_phyregs_5G[8] = - read_phy_reg(pi, 0x1a5); + read_phy_reg(pi, 0x1a5); pi->rssical_cache.rssical_phyregs_5G[9] = - read_phy_reg(pi, 0x1ab); + read_phy_reg(pi, 0x1ab); pi->rssical_cache.rssical_phyregs_5G[10] = - read_phy_reg(pi, 0x1b1); + read_phy_reg(pi, 0x1b1); pi->rssical_cache.rssical_phyregs_5G[11] = - read_phy_reg(pi, 0x1b7); + read_phy_reg(pi, 0x1b7); pi->nphy_rssical_chanspec_5G = pi->radio_chanspec; } @@ -22129,121 +22895,292 @@ static void wlc_phy_rssi_cal_nphy_rev3(struct brcms_phy *pi) wlc_phy_clip_det_nphy(pi, 1, clip_state); } -static void wlc_phy_restore_rssical_nphy(struct brcms_phy *pi) +static void wlc_phy_rssi_cal_nphy_rev2(struct brcms_phy *pi, u8 rssi_type) { - if (CHSPEC_IS2G(pi->radio_chanspec)) { - if (pi->nphy_rssical_chanspec_2G == 0) - return; + s32 target_code; + u16 classif_state; + u16 clip_state[2]; + u16 rssi_ctrl_state[2], pd_state[2]; + u16 rfctrlintc_state[2], rfpdcorerxtx_state[2]; + u16 rfctrlintc_override_val; + u16 clip_off[] = { 0xffff, 0xffff }; + u16 rf_pd_val, pd_mask, rssi_ctrl_mask; + u8 vcm, min_vcm, vcm_tmp[4]; + u8 vcm_final[4] = { 0, 0, 0, 0 }; + u8 result_idx, ctr; + s32 poll_results[4][4] = { + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0} + }; + s32 poll_miniq[4][2] = { + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0} + }; + s32 min_d, curr_d; + s32 fine_digital_offset[4]; + s32 poll_results_min[4] = { 0, 0, 0, 0 }; + s32 min_poll; - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0, - RADIO_2057_VCM_MASK, - pi->rssical_cache. - rssical_radio_regs_2G[0]); - mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1, - RADIO_2057_VCM_MASK, - pi->rssical_cache. - rssical_radio_regs_2G[1]); - } else { - mod_radio_reg(pi, - RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX0, - RADIO_2056_VCM_MASK, - pi->rssical_cache. - rssical_radio_regs_2G[0]); - mod_radio_reg(pi, - RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX1, - RADIO_2056_VCM_MASK, - pi->rssical_cache. - rssical_radio_regs_2G[1]); + switch (rssi_type) { + case NPHY_RSSI_SEL_NB: + target_code = NPHY_RSSICAL_NB_TARGET; + break; + case NPHY_RSSI_SEL_W1: + target_code = NPHY_RSSICAL_W1_TARGET; + break; + case NPHY_RSSI_SEL_W2: + target_code = NPHY_RSSICAL_W2_TARGET; + break; + default: + return; + break; + } + + classif_state = wlc_phy_classifier_nphy(pi, 0, 0); + wlc_phy_classifier_nphy(pi, (0x7 << 0), 4); + wlc_phy_clip_det_nphy(pi, 0, clip_state); + wlc_phy_clip_det_nphy(pi, 1, clip_off); + + rf_pd_val = (rssi_type == NPHY_RSSI_SEL_NB) ? 0x6 : 0x4; + rfctrlintc_override_val = + CHSPEC_IS5G(pi->radio_chanspec) ? 0x140 : 0x110; + + rfctrlintc_state[0] = read_phy_reg(pi, 0x91); + rfpdcorerxtx_state[0] = read_radio_reg(pi, RADIO_2055_PD_CORE1_RXTX); + write_phy_reg(pi, 0x91, rfctrlintc_override_val); + write_radio_reg(pi, RADIO_2055_PD_CORE1_RXTX, rf_pd_val); + + rfctrlintc_state[1] = read_phy_reg(pi, 0x92); + rfpdcorerxtx_state[1] = read_radio_reg(pi, RADIO_2055_PD_CORE2_RXTX); + write_phy_reg(pi, 0x92, rfctrlintc_override_val); + write_radio_reg(pi, RADIO_2055_PD_CORE2_RXTX, rf_pd_val); + + pd_mask = RADIO_2055_NBRSSI_PD | RADIO_2055_WBRSSI_G1_PD | + RADIO_2055_WBRSSI_G2_PD; + pd_state[0] = + read_radio_reg(pi, RADIO_2055_PD_CORE1_RSSI_MISC) & pd_mask; + pd_state[1] = + read_radio_reg(pi, RADIO_2055_PD_CORE2_RSSI_MISC) & pd_mask; + mod_radio_reg(pi, RADIO_2055_PD_CORE1_RSSI_MISC, pd_mask, 0); + mod_radio_reg(pi, RADIO_2055_PD_CORE2_RSSI_MISC, pd_mask, 0); + rssi_ctrl_mask = RADIO_2055_NBRSSI_SEL | RADIO_2055_WBRSSI_G1_SEL | + RADIO_2055_WBRSSI_G2_SEL; + rssi_ctrl_state[0] = + read_radio_reg(pi, RADIO_2055_SP_RSSI_CORE1) & rssi_ctrl_mask; + rssi_ctrl_state[1] = + read_radio_reg(pi, RADIO_2055_SP_RSSI_CORE2) & rssi_ctrl_mask; + wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_ALLRX, rssi_type); + + wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0, RADIO_MIMO_CORESEL_ALLRX, + NPHY_RAIL_I, rssi_type); + wlc_phy_scale_offset_rssi_nphy(pi, 0x0, 0x0, RADIO_MIMO_CORESEL_ALLRX, + NPHY_RAIL_Q, rssi_type); + + for (vcm = 0; vcm < 4; vcm++) { + + vcm_tmp[0] = vcm_tmp[1] = vcm_tmp[2] = vcm_tmp[3] = vcm; + if (rssi_type != NPHY_RSSI_SEL_W2) + wlc_phy_set_rssi_2055_vcm(pi, rssi_type, vcm_tmp); + + wlc_phy_poll_rssi_nphy(pi, rssi_type, &poll_results[vcm][0], + NPHY_RSSICAL_NPOLL); + + if ((rssi_type == NPHY_RSSI_SEL_W1) + || (rssi_type == NPHY_RSSI_SEL_W2)) { + for (ctr = 0; ctr < 2; ctr++) + poll_miniq[vcm][ctr] = + min(poll_results[vcm][ctr * 2 + 0], + poll_results[vcm][ctr * 2 + 1]); } + } - write_phy_reg(pi, 0x1a6, - pi->rssical_cache.rssical_phyregs_2G[0]); - write_phy_reg(pi, 0x1ac, - pi->rssical_cache.rssical_phyregs_2G[1]); - write_phy_reg(pi, 0x1b2, - pi->rssical_cache.rssical_phyregs_2G[2]); - write_phy_reg(pi, 0x1b8, - pi->rssical_cache.rssical_phyregs_2G[3]); - write_phy_reg(pi, 0x1a4, - pi->rssical_cache.rssical_phyregs_2G[4]); - write_phy_reg(pi, 0x1aa, - pi->rssical_cache.rssical_phyregs_2G[5]); - write_phy_reg(pi, 0x1b0, - pi->rssical_cache.rssical_phyregs_2G[6]); - write_phy_reg(pi, 0x1b6, - pi->rssical_cache.rssical_phyregs_2G[7]); - write_phy_reg(pi, 0x1a5, - pi->rssical_cache.rssical_phyregs_2G[8]); - write_phy_reg(pi, 0x1ab, - pi->rssical_cache.rssical_phyregs_2G[9]); - write_phy_reg(pi, 0x1b1, - pi->rssical_cache.rssical_phyregs_2G[10]); - write_phy_reg(pi, 0x1b7, - pi->rssical_cache.rssical_phyregs_2G[11]); + for (result_idx = 0; result_idx < 4; result_idx++) { + min_d = NPHY_RSSICAL_MAXD; + min_vcm = 0; + min_poll = NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL + 1; + for (vcm = 0; vcm < 4; vcm++) { + curr_d = ABS(((rssi_type == NPHY_RSSI_SEL_NB) ? + poll_results[vcm][result_idx] : + poll_miniq[vcm][result_idx / 2]) - + (target_code * NPHY_RSSICAL_NPOLL)); + if (curr_d < min_d) { + min_d = curr_d; + min_vcm = vcm; + } + if (poll_results[vcm][result_idx] < min_poll) + min_poll = poll_results[vcm][result_idx]; + } + vcm_final[result_idx] = min_vcm; + poll_results_min[result_idx] = min_poll; + } - } else { - if (pi->nphy_rssical_chanspec_5G == 0) - return; + if (rssi_type != NPHY_RSSI_SEL_W2) + wlc_phy_set_rssi_2055_vcm(pi, rssi_type, vcm_final); - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE0, - RADIO_2057_VCM_MASK, - pi->rssical_cache. - rssical_radio_regs_5G[0]); - mod_radio_reg(pi, RADIO_2057_NB_MASTER_CORE1, - RADIO_2057_VCM_MASK, - pi->rssical_cache. - rssical_radio_regs_5G[1]); + for (result_idx = 0; result_idx < 4; result_idx++) { + fine_digital_offset[result_idx] = + (target_code * NPHY_RSSICAL_NPOLL) - + poll_results[vcm_final[result_idx]][result_idx]; + if (fine_digital_offset[result_idx] < 0) { + fine_digital_offset[result_idx] = + ABS(fine_digital_offset[result_idx]); + fine_digital_offset[result_idx] += + (NPHY_RSSICAL_NPOLL / 2); + fine_digital_offset[result_idx] /= NPHY_RSSICAL_NPOLL; + fine_digital_offset[result_idx] = + -fine_digital_offset[result_idx]; } else { - mod_radio_reg(pi, - RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX0, - RADIO_2056_VCM_MASK, - pi->rssical_cache. - rssical_radio_regs_5G[0]); - mod_radio_reg(pi, - RADIO_2056_RX_RSSI_MISC | RADIO_2056_RX1, - RADIO_2056_VCM_MASK, - pi->rssical_cache. - rssical_radio_regs_5G[1]); + fine_digital_offset[result_idx] += + (NPHY_RSSICAL_NPOLL / 2); + fine_digital_offset[result_idx] /= NPHY_RSSICAL_NPOLL; } - write_phy_reg(pi, 0x1a6, - pi->rssical_cache.rssical_phyregs_5G[0]); - write_phy_reg(pi, 0x1ac, - pi->rssical_cache.rssical_phyregs_5G[1]); - write_phy_reg(pi, 0x1b2, - pi->rssical_cache.rssical_phyregs_5G[2]); - write_phy_reg(pi, 0x1b8, - pi->rssical_cache.rssical_phyregs_5G[3]); - write_phy_reg(pi, 0x1a4, - pi->rssical_cache.rssical_phyregs_5G[4]); - write_phy_reg(pi, 0x1aa, - pi->rssical_cache.rssical_phyregs_5G[5]); - write_phy_reg(pi, 0x1b0, - pi->rssical_cache.rssical_phyregs_5G[6]); - write_phy_reg(pi, 0x1b6, - pi->rssical_cache.rssical_phyregs_5G[7]); - write_phy_reg(pi, 0x1a5, - pi->rssical_cache.rssical_phyregs_5G[8]); - write_phy_reg(pi, 0x1ab, - pi->rssical_cache.rssical_phyregs_5G[9]); - write_phy_reg(pi, 0x1b1, - pi->rssical_cache.rssical_phyregs_5G[10]); - write_phy_reg(pi, 0x1b7, - pi->rssical_cache.rssical_phyregs_5G[11]); + if (poll_results_min[result_idx] == + NPHY_RSSICAL_MAXREAD * NPHY_RSSICAL_NPOLL) + fine_digital_offset[result_idx] = + (target_code - NPHY_RSSICAL_MAXREAD - 1); + + wlc_phy_scale_offset_rssi_nphy(pi, 0x0, + (s8) + fine_digital_offset[result_idx], + (result_idx / 2 == + 0) ? RADIO_MIMO_CORESEL_CORE1 : + RADIO_MIMO_CORESEL_CORE2, + (result_idx % 2 == + 0) ? NPHY_RAIL_I : NPHY_RAIL_Q, + rssi_type); + } + + mod_radio_reg(pi, RADIO_2055_PD_CORE1_RSSI_MISC, pd_mask, pd_state[0]); + mod_radio_reg(pi, RADIO_2055_PD_CORE2_RSSI_MISC, pd_mask, pd_state[1]); + if (rssi_ctrl_state[0] == RADIO_2055_NBRSSI_SEL) + wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1, + NPHY_RSSI_SEL_NB); + else if (rssi_ctrl_state[0] == RADIO_2055_WBRSSI_G1_SEL) + wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1, + NPHY_RSSI_SEL_W1); + else if (rssi_ctrl_state[0] == RADIO_2055_WBRSSI_G2_SEL) + wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1, + NPHY_RSSI_SEL_W2); + else + wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE1, + NPHY_RSSI_SEL_W2); + if (rssi_ctrl_state[1] == RADIO_2055_NBRSSI_SEL) + wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2, + NPHY_RSSI_SEL_NB); + else if (rssi_ctrl_state[1] == RADIO_2055_WBRSSI_G1_SEL) + wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2, + NPHY_RSSI_SEL_W1); + else if (rssi_ctrl_state[1] == RADIO_2055_WBRSSI_G2_SEL) + wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2, + NPHY_RSSI_SEL_W2); + else + wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_CORE2, + NPHY_RSSI_SEL_W2); + + wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_OFF, rssi_type); + + write_phy_reg(pi, 0x91, rfctrlintc_state[0]); + write_radio_reg(pi, RADIO_2055_PD_CORE1_RXTX, rfpdcorerxtx_state[0]); + write_phy_reg(pi, 0x92, rfctrlintc_state[1]); + write_radio_reg(pi, RADIO_2055_PD_CORE2_RXTX, rfpdcorerxtx_state[1]); + + wlc_phy_classifier_nphy(pi, (0x7 << 0), classif_state); + wlc_phy_clip_det_nphy(pi, 1, clip_state); + + wlc_phy_resetcca_nphy(pi); +} + +void wlc_phy_rssi_cal_nphy(struct brcms_phy *pi) +{ + if (NREV_GE(pi->pubpi.phy_rev, 3)) { + wlc_phy_rssi_cal_nphy_rev3(pi); + } else { + wlc_phy_rssi_cal_nphy_rev2(pi, NPHY_RSSI_SEL_NB); + wlc_phy_rssi_cal_nphy_rev2(pi, NPHY_RSSI_SEL_W1); + wlc_phy_rssi_cal_nphy_rev2(pi, NPHY_RSSI_SEL_W2); } } +int +wlc_phy_rssi_compute_nphy(struct brcms_phy *pi, struct brcms_d11rxhdr *wlc_rxh) +{ + struct d11rxhdr *rxh = &wlc_rxh->rxhdr; + s16 rxpwr, rxpwr0, rxpwr1; + s16 phyRx0_l, phyRx2_l; + + rxpwr = 0; + rxpwr0 = le16_to_cpu(rxh->PhyRxStatus_1) & PRXS1_nphy_PWR0_MASK; + rxpwr1 = (le16_to_cpu(rxh->PhyRxStatus_1) & PRXS1_nphy_PWR1_MASK) >> 8; + + if (rxpwr0 > 127) + rxpwr0 -= 256; + if (rxpwr1 > 127) + rxpwr1 -= 256; + + phyRx0_l = le16_to_cpu(rxh->PhyRxStatus_0) & 0x00ff; + phyRx2_l = le16_to_cpu(rxh->PhyRxStatus_2) & 0x00ff; + if (phyRx2_l > 127) + phyRx2_l -= 256; + + if (((rxpwr0 == 16) || (rxpwr0 == 32))) { + rxpwr0 = rxpwr1; + rxpwr1 = phyRx2_l; + } + + wlc_rxh->rxpwr[0] = (s8) rxpwr0; + wlc_rxh->rxpwr[1] = (s8) rxpwr1; + wlc_rxh->do_rssi_ma = 0; + + if (pi->sh->rssi_mode == RSSI_ANT_MERGE_MAX) + rxpwr = (rxpwr0 > rxpwr1) ? rxpwr0 : rxpwr1; + else if (pi->sh->rssi_mode == RSSI_ANT_MERGE_MIN) + rxpwr = (rxpwr0 < rxpwr1) ? rxpwr0 : rxpwr1; + else if (pi->sh->rssi_mode == RSSI_ANT_MERGE_AVG) + rxpwr = (rxpwr0 + rxpwr1) >> 1; + + return rxpwr; +} + +static void +wlc_phy_loadsampletable_nphy(struct brcms_phy *pi, struct cordic_iq *tone_buf, + u16 num_samps) +{ + u16 t; + u32 *data_buf = NULL; + + data_buf = kmalloc(sizeof(u32) * num_samps, GFP_ATOMIC); + if (data_buf == NULL) + return; + + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, true); + + for (t = 0; t < num_samps; t++) + data_buf[t] = ((((unsigned int)tone_buf[t].i) & 0x3ff) << 10) | + (((unsigned int)tone_buf[t].q) & 0x3ff); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_SAMPLEPLAY, num_samps, 0, 32, + data_buf); + + kfree(data_buf); + + if (pi->phyhang_avoid) + wlc_phy_stay_in_carriersearch_nphy(pi, false); +} + static u16 wlc_phy_gen_load_samples_nphy(struct brcms_phy *pi, u32 f_kHz, u16 max_val, u8 dac_test_mode) { u8 phy_bw, is_phybw40; u16 num_samps, t, spur; - fixed theta = 0, rot = 0; + s32 theta = 0, rot = 0; u32 tbl_len; - cs32 *tone_buf = NULL; + struct cordic_iq *tone_buf = NULL; is_phybw40 = CHSPEC_IS40(pi->radio_chanspec); phy_bw = (is_phybw40 == 1) ? 40 : 20; @@ -22258,18 +23195,17 @@ wlc_phy_gen_load_samples_nphy(struct brcms_phy *pi, u32 f_kHz, u16 max_val, tbl_len = (phy_bw << 1); } - tone_buf = kmalloc(sizeof(cs32) * tbl_len, GFP_ATOMIC); - if (tone_buf == NULL) { + tone_buf = kmalloc(sizeof(struct cordic_iq) * tbl_len, GFP_ATOMIC); + if (tone_buf == NULL) return 0; - } num_samps = (u16) tbl_len; - rot = FIXED((f_kHz * 36) / phy_bw) / 100; + rot = ((f_kHz * 36) / phy_bw) / 100; theta = 0; for (t = 0; t < num_samps; t++) { - wlc_phy_cordic(theta, &tone_buf[t]); + tone_buf[t] = cordic_calc_iq(theta); theta += rot; @@ -22284,54 +23220,6 @@ wlc_phy_gen_load_samples_nphy(struct brcms_phy *pi, u32 f_kHz, u16 max_val, return num_samps; } -int -wlc_phy_tx_tone_nphy(struct brcms_phy *pi, u32 f_kHz, u16 max_val, - u8 iqmode, u8 dac_test_mode, bool modify_bbmult) -{ - u16 num_samps; - u16 loops = 0xffff; - u16 wait = 0; - - num_samps = - wlc_phy_gen_load_samples_nphy(pi, f_kHz, max_val, dac_test_mode); - if (num_samps == 0) { - return -EBADE; - } - - wlc_phy_runsamples_nphy(pi, num_samps, loops, wait, iqmode, - dac_test_mode, modify_bbmult); - - return 0; -} - -static void -wlc_phy_loadsampletable_nphy(struct brcms_phy *pi, cs32 *tone_buf, - u16 num_samps) -{ - u16 t; - u32 *data_buf = NULL; - - data_buf = kmalloc(sizeof(u32) * num_samps, GFP_ATOMIC); - if (data_buf == NULL) { - return; - } - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, true); - - for (t = 0; t < num_samps; t++) { - data_buf[t] = ((((unsigned int)tone_buf[t].i) & 0x3ff) << 10) | - (((unsigned int)tone_buf[t].q) & 0x3ff); - } - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_SAMPLEPLAY, num_samps, 0, 32, - data_buf); - - kfree(data_buf); - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, false); -} - static void wlc_phy_runsamples_nphy(struct brcms_phy *pi, u16 num_samps, u16 loops, u16 wait, u8 iqmode, u8 dac_test_mode, @@ -22356,22 +23244,24 @@ wlc_phy_runsamples_nphy(struct brcms_phy *pi, u16 num_samps, u16 loops, lpf_bw_ctl_override4 = read_phy_reg(pi, 0x343) & (0x1 << 7); if (lpf_bw_ctl_override3 | lpf_bw_ctl_override4) { lpf_bw_ctl_miscreg3 = read_phy_reg(pi, 0x340) & - (0x7 << 8); + (0x7 << 8); lpf_bw_ctl_miscreg4 = read_phy_reg(pi, 0x341) & - (0x7 << 8); + (0x7 << 8); } else { - wlc_phy_rfctrl_override_nphy_rev7(pi, - (0x1 << 7), - wlc_phy_read_lpf_bw_ctl_nphy - (pi, 0), 0, 0, - NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7( + pi, + (0x1 << 7), + wlc_phy_read_lpf_bw_ctl_nphy + (pi, + 0), 0, 0, + NPHY_REV7_RFCTRLOVERRIDE_ID1); pi->nphy_sample_play_lpf_bw_ctl_ovr = true; lpf_bw_ctl_miscreg3 = read_phy_reg(pi, 0x340) & - (0x7 << 8); + (0x7 << 8); lpf_bw_ctl_miscreg4 = read_phy_reg(pi, 0x341) & - (0x7 << 8); + (0x7 << 8); } } @@ -22380,7 +23270,7 @@ wlc_phy_runsamples_nphy(struct brcms_phy *pi, u16 num_samps, u16 loops, wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, 87, 16, &bb_mult); pi->nphy_bb_mult_save = - BB_MULT_VALID_MASK | (bb_mult & BB_MULT_MASK); + BB_MULT_VALID_MASK | (bb_mult & BB_MULT_MASK); } if (modify_bbmult) { @@ -22395,11 +23285,11 @@ wlc_phy_runsamples_nphy(struct brcms_phy *pi, u16 num_samps, u16 loops, write_phy_reg(pi, 0xc6, num_samps - 1); - if (loops != 0xffff) { + if (loops != 0xffff) write_phy_reg(pi, 0xc4, loops - 1); - } else { + else write_phy_reg(pi, 0xc4, loops); - } + write_phy_reg(pi, 0xc5, wait); orig_RfseqCoreActv = read_phy_reg(pi, 0xa1); @@ -22420,6 +23310,25 @@ wlc_phy_runsamples_nphy(struct brcms_phy *pi, u16 num_samps, u16 loops, write_phy_reg(pi, 0xa1, orig_RfseqCoreActv); } +int +wlc_phy_tx_tone_nphy(struct brcms_phy *pi, u32 f_kHz, u16 max_val, + u8 iqmode, u8 dac_test_mode, bool modify_bbmult) +{ + u16 num_samps; + u16 loops = 0xffff; + u16 wait = 0; + + num_samps = wlc_phy_gen_load_samples_nphy(pi, f_kHz, max_val, + dac_test_mode); + if (num_samps == 0) + return -EBADE; + + wlc_phy_runsamples_nphy(pi, num_samps, loops, wait, iqmode, + dac_test_mode, modify_bbmult); + + return 0; +} + void wlc_phy_stopplayback_nphy(struct brcms_phy *pi) { u16 playback_status; @@ -22429,13 +23338,11 @@ void wlc_phy_stopplayback_nphy(struct brcms_phy *pi) wlc_phy_stay_in_carriersearch_nphy(pi, true); playback_status = read_phy_reg(pi, 0xc7); - if (playback_status & 0x1) { + if (playback_status & 0x1) or_phy_reg(pi, 0xc3, NPHY_sampleCmd_STOP); - } else if (playback_status & 0x2) { - + else if (playback_status & 0x2) and_phy_reg(pi, 0xc2, (u16) ~NPHY_iqloCalCmdGctl_IQLO_CAL_EN); - } and_phy_reg(pi, 0xc3, (u16) ~(0x1 << 2)); @@ -22450,10 +23357,11 @@ void wlc_phy_stopplayback_nphy(struct brcms_phy *pi) if (NREV_IS(pi->pubpi.phy_rev, 7) || NREV_GE(pi->pubpi.phy_rev, 8)) { if (pi->nphy_sample_play_lpf_bw_ctl_ovr) { - wlc_phy_rfctrl_override_nphy_rev7(pi, - (0x1 << 7), - 0, 0, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7( + pi, + (0x1 << 7), + 0, 0, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID1); pi->nphy_sample_play_lpf_bw_ctl_ovr = false; } } @@ -22462,6 +23370,47 @@ void wlc_phy_stopplayback_nphy(struct brcms_phy *pi) wlc_phy_stay_in_carriersearch_nphy(pi, false); } +static u32 *brcms_phy_get_tx_pwrctrl_tbl(struct brcms_phy *pi) +{ + u32 *tx_pwrctrl_tbl = NULL; + uint phyrev = pi->pubpi.phy_rev; + + if (PHY_IPA(pi)) { + tx_pwrctrl_tbl = + wlc_phy_get_ipa_gaintbl_nphy(pi); + } else { + if (CHSPEC_IS5G(pi->radio_chanspec)) { + if (NREV_IS(phyrev, 3)) + tx_pwrctrl_tbl = nphy_tpc_5GHz_txgain_rev3; + else if (NREV_IS(phyrev, 4)) + tx_pwrctrl_tbl = + (pi->srom_fem5g.extpagain == 3) ? + nphy_tpc_5GHz_txgain_HiPwrEPA : + nphy_tpc_5GHz_txgain_rev4; + else + tx_pwrctrl_tbl = nphy_tpc_5GHz_txgain_rev5; + } else { + if (NREV_GE(phyrev, 7)) { + if (pi->pubpi.radiorev == 3) + tx_pwrctrl_tbl = + nphy_tpc_txgain_epa_2057rev3; + else if (pi->pubpi.radiorev == 5) + tx_pwrctrl_tbl = + nphy_tpc_txgain_epa_2057rev5; + } else { + if (NREV_GE(phyrev, 5) && + (pi->srom_fem2g.extpagain == 3)) + tx_pwrctrl_tbl = + nphy_tpc_txgain_HiPwrEPA; + else + tx_pwrctrl_tbl = + nphy_tpc_txgain_rev3; + } + } + } + return tx_pwrctrl_tbl; +} + struct nphy_txgains wlc_phy_get_tx_gain_nphy(struct brcms_phy *pi) { u16 base_idx[2], curr_gain[2]; @@ -22482,33 +23431,33 @@ struct nphy_txgains wlc_phy_get_tx_gain_nphy(struct brcms_phy *pi) for (core_no = 0; core_no < 2; core_no++) { if (NREV_GE(pi->pubpi.phy_rev, 7)) { target_gain.ipa[core_no] = - curr_gain[core_no] & 0x0007; + curr_gain[core_no] & 0x0007; target_gain.pad[core_no] = - ((curr_gain[core_no] & 0x00F8) >> 3); + ((curr_gain[core_no] & 0x00F8) >> 3); target_gain.pga[core_no] = - ((curr_gain[core_no] & 0x0F00) >> 8); + ((curr_gain[core_no] & 0x0F00) >> 8); target_gain.txgm[core_no] = - ((curr_gain[core_no] & 0x7000) >> 12); + ((curr_gain[core_no] & 0x7000) >> 12); target_gain.txlpf[core_no] = - ((curr_gain[core_no] & 0x8000) >> 15); + ((curr_gain[core_no] & 0x8000) >> 15); } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { target_gain.ipa[core_no] = - curr_gain[core_no] & 0x000F; + curr_gain[core_no] & 0x000F; target_gain.pad[core_no] = - ((curr_gain[core_no] & 0x00F0) >> 4); + ((curr_gain[core_no] & 0x00F0) >> 4); target_gain.pga[core_no] = - ((curr_gain[core_no] & 0x0F00) >> 8); + ((curr_gain[core_no] & 0x0F00) >> 8); target_gain.txgm[core_no] = - ((curr_gain[core_no] & 0x7000) >> 12); + ((curr_gain[core_no] & 0x7000) >> 12); } else { target_gain.ipa[core_no] = - curr_gain[core_no] & 0x0003; + curr_gain[core_no] & 0x0003; target_gain.pad[core_no] = - ((curr_gain[core_no] & 0x000C) >> 2); + ((curr_gain[core_no] & 0x000C) >> 2); target_gain.pga[core_no] = - ((curr_gain[core_no] & 0x0070) >> 4); + ((curr_gain[core_no] & 0x0070) >> 4); target_gain.txgm[core_no] = - ((curr_gain[core_no] & 0x0380) >> 7); + ((curr_gain[core_no] & 0x0380) >> 7); } } } else { @@ -22518,96 +23467,60 @@ struct nphy_txgains wlc_phy_get_tx_gain_nphy(struct brcms_phy *pi) base_idx[1] = (read_phy_reg(pi, 0x1ee) >> 8) & 0x7f; for (core_no = 0; core_no < 2; core_no++) { if (NREV_GE(phyrev, 3)) { - if (PHY_IPA(pi)) { - tx_pwrctrl_tbl = - wlc_phy_get_ipa_gaintbl_nphy(pi); - } else { - if (CHSPEC_IS5G(pi->radio_chanspec)) { - if (NREV_IS(phyrev, 3)) { - tx_pwrctrl_tbl = - nphy_tpc_5GHz_txgain_rev3; - } else if (NREV_IS(phyrev, 4)) { - tx_pwrctrl_tbl = - (pi->srom_fem5g. - extpagain == - 3) ? - nphy_tpc_5GHz_txgain_HiPwrEPA - : - nphy_tpc_5GHz_txgain_rev4; - } else { - tx_pwrctrl_tbl = - nphy_tpc_5GHz_txgain_rev5; - } - } else { - if (NREV_GE(phyrev, 7)) { - if (pi->pubpi. - radiorev == 3) { - tx_pwrctrl_tbl = - nphy_tpc_txgain_epa_2057rev3; - } else if (pi->pubpi. - radiorev == - 5) { - tx_pwrctrl_tbl = - nphy_tpc_txgain_epa_2057rev5; - } - - } else { - if (NREV_GE(phyrev, 5) - && (pi->srom_fem2g. - extpagain == - 3)) { - tx_pwrctrl_tbl = - nphy_tpc_txgain_HiPwrEPA; - } else { - tx_pwrctrl_tbl = - nphy_tpc_txgain_rev3; - } - } - } - } + tx_pwrctrl_tbl = + brcms_phy_get_tx_pwrctrl_tbl(pi); if (NREV_GE(phyrev, 7)) { target_gain.ipa[core_no] = - (tx_pwrctrl_tbl[base_idx[core_no]] - >> 16) & 0x7; + (tx_pwrctrl_tbl + [base_idx[core_no]] + >> 16) & 0x7; target_gain.pad[core_no] = - (tx_pwrctrl_tbl[base_idx[core_no]] - >> 19) & 0x1f; + (tx_pwrctrl_tbl + [base_idx[core_no]] + >> 19) & 0x1f; target_gain.pga[core_no] = - (tx_pwrctrl_tbl[base_idx[core_no]] - >> 24) & 0xf; + (tx_pwrctrl_tbl + [base_idx[core_no]] + >> 24) & 0xf; target_gain.txgm[core_no] = - (tx_pwrctrl_tbl[base_idx[core_no]] - >> 28) & 0x7; + (tx_pwrctrl_tbl + [base_idx[core_no]] + >> 28) & 0x7; target_gain.txlpf[core_no] = - (tx_pwrctrl_tbl[base_idx[core_no]] - >> 31) & 0x1; + (tx_pwrctrl_tbl + [base_idx[core_no]] + >> 31) & 0x1; } else { target_gain.ipa[core_no] = - (tx_pwrctrl_tbl[base_idx[core_no]] - >> 16) & 0xf; + (tx_pwrctrl_tbl + [base_idx[core_no]] + >> 16) & 0xf; target_gain.pad[core_no] = - (tx_pwrctrl_tbl[base_idx[core_no]] - >> 20) & 0xf; + (tx_pwrctrl_tbl + [base_idx[core_no]] + >> 20) & 0xf; target_gain.pga[core_no] = - (tx_pwrctrl_tbl[base_idx[core_no]] - >> 24) & 0xf; + (tx_pwrctrl_tbl + [base_idx[core_no]] + >> 24) & 0xf; target_gain.txgm[core_no] = - (tx_pwrctrl_tbl[base_idx[core_no]] - >> 28) & 0x7; + (tx_pwrctrl_tbl + [base_idx[core_no]] + >> 28) & 0x7; } } else { target_gain.ipa[core_no] = - (nphy_tpc_txgain[base_idx[core_no]] >> 16) & - 0x3; + (nphy_tpc_txgain[base_idx[core_no]] >> + 16) & 0x3; target_gain.pad[core_no] = - (nphy_tpc_txgain[base_idx[core_no]] >> 18) & - 0x3; + (nphy_tpc_txgain[base_idx[core_no]] >> + 18) & 0x3; target_gain.pga[core_no] = - (nphy_tpc_txgain[base_idx[core_no]] >> 20) & - 0x7; + (nphy_tpc_txgain[base_idx[core_no]] >> + 20) & 0x7; target_gain.txgm[core_no] = - (nphy_tpc_txgain[base_idx[core_no]] >> 23) & - 0x7; + (nphy_tpc_txgain[base_idx[core_no]] >> + 23) & 0x7; } } } @@ -22626,26 +23539,23 @@ wlc_phy_iqcal_gainparams_nphy(struct brcms_phy *pi, u16 core_no, u8 band_idx = (CHSPEC_IS5G(pi->radio_chanspec) ? 1 : 0); if (NREV_GE(pi->pubpi.phy_rev, 3)) { - if (NREV_GE(pi->pubpi.phy_rev, 7)) { + if (NREV_GE(pi->pubpi.phy_rev, 7)) params->txlpf = target_gain.txlpf[core_no]; - } + params->txgm = target_gain.txgm[core_no]; params->pga = target_gain.pga[core_no]; params->pad = target_gain.pad[core_no]; params->ipa = target_gain.ipa[core_no]; - if (NREV_GE(pi->pubpi.phy_rev, 7)) { + if (NREV_GE(pi->pubpi.phy_rev, 7)) params->cal_gain = - ((params->txlpf << 15) | (params-> - txgm << 12) | (params-> - pga << 8) | - (params->pad << 3) | (params->ipa)); - } else { + ((params->txlpf << 15) | (params->txgm << 12) | + (params->pga << 8) | + (params->pad << 3) | (params->ipa)); + else params->cal_gain = - ((params->txgm << 12) | (params-> - pga << 8) | (params-> - pad << 4) | - (params->ipa)); - } + ((params->txgm << 12) | (params->pga << 8) | + (params->pad << 4) | (params->ipa)); + params->ncorr[0] = 0x79; params->ncorr[1] = 0x79; params->ncorr[2] = 0x79; @@ -22654,9 +23564,8 @@ wlc_phy_iqcal_gainparams_nphy(struct brcms_phy *pi, u16 core_no, } else { gain_index = ((target_gain.pad[core_no] << 0) | - (target_gain.pga[core_no] << 4) | (target_gain. - txgm[core_no] - << 8)); + (target_gain.pga[core_no] << 4) | + (target_gain.txgm[core_no] << 8)); idx = -1; for (k = 0; k < NPHY_IQCAL_NUMGAINS; k++) { @@ -22688,37 +23597,39 @@ static void wlc_phy_txcal_radio_setup_nphy(struct brcms_phy *pi) for (core = 0; core <= 1; core++) { pi->tx_rx_cal_radio_saveregs[(core * 11) + 0] = - READ_RADIO_REG3(pi, RADIO_2057, TX, core, - TX_SSI_MASTER); + READ_RADIO_REG3(pi, RADIO_2057, TX, core, + TX_SSI_MASTER); pi->tx_rx_cal_radio_saveregs[(core * 11) + 1] = - READ_RADIO_REG3(pi, RADIO_2057, TX, core, - IQCAL_VCM_HG); + READ_RADIO_REG3(pi, RADIO_2057, TX, core, + IQCAL_VCM_HG); pi->tx_rx_cal_radio_saveregs[(core * 11) + 2] = - READ_RADIO_REG3(pi, RADIO_2057, TX, core, - IQCAL_IDAC); + READ_RADIO_REG3(pi, RADIO_2057, TX, core, + IQCAL_IDAC); pi->tx_rx_cal_radio_saveregs[(core * 11) + 3] = - READ_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_VCM); + READ_RADIO_REG3(pi, RADIO_2057, TX, core, + TSSI_VCM); pi->tx_rx_cal_radio_saveregs[(core * 11) + 4] = 0; pi->tx_rx_cal_radio_saveregs[(core * 11) + 5] = - READ_RADIO_REG3(pi, RADIO_2057, TX, core, - TX_SSI_MUX); + READ_RADIO_REG3(pi, RADIO_2057, TX, core, + TX_SSI_MUX); if (pi->pubpi.radiorev != 5) pi->tx_rx_cal_radio_saveregs[(core * 11) + 6] = - READ_RADIO_REG3(pi, RADIO_2057, TX, core, - TSSIA); + READ_RADIO_REG3(pi, RADIO_2057, TX, + core, + TSSIA); pi->tx_rx_cal_radio_saveregs[(core * 11) + 7] = - READ_RADIO_REG3(pi, RADIO_2057, TX, core, TSSIG); + READ_RADIO_REG3(pi, RADIO_2057, TX, core, TSSIG); pi->tx_rx_cal_radio_saveregs[(core * 11) + 8] = - READ_RADIO_REG3(pi, RADIO_2057, TX, core, - TSSI_MISC1); + READ_RADIO_REG3(pi, RADIO_2057, TX, core, + TSSI_MISC1); if (CHSPEC_IS5G(pi->radio_chanspec)) { WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, @@ -22734,19 +23645,15 @@ static void wlc_phy_txcal_radio_setup_nphy(struct brcms_phy *pi) if (pi->use_int_tx_iqlo_cal_nphy) { WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TX_SSI_MUX, 0x4); - if (! - (pi-> - internal_tx_iqlo_cal_tapoff_intpa_nphy)) { - + if (!(pi-> + internal_tx_iqlo_cal_tapoff_intpa_nphy)) WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSIA, 0x31); - } else { - + else WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSIA, 0x21); - } } WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_MISC1, 0x00); @@ -22767,19 +23674,15 @@ static void wlc_phy_txcal_radio_setup_nphy(struct brcms_phy *pi) WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TX_SSI_MUX, 0x06); - if (! - (pi-> - internal_tx_iqlo_cal_tapoff_intpa_nphy)) { - + if (!(pi-> + internal_tx_iqlo_cal_tapoff_intpa_nphy)) WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSIG, 0x31); - } else { - + else WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSIG, 0x21); - } } WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_MISC1, 0x00); @@ -22789,58 +23692,62 @@ static void wlc_phy_txcal_radio_setup_nphy(struct brcms_phy *pi) for (core = 0; core <= 1; core++) { jtag_core = - (core == - PHY_CORE_0) ? RADIO_2056_TX0 : RADIO_2056_TX1; + (core == + PHY_CORE_0) ? RADIO_2056_TX0 : RADIO_2056_TX1; pi->tx_rx_cal_radio_saveregs[(core * 11) + 0] = - read_radio_reg(pi, - RADIO_2056_TX_TX_SSI_MASTER | - jtag_core); + read_radio_reg(pi, + RADIO_2056_TX_TX_SSI_MASTER | + jtag_core); pi->tx_rx_cal_radio_saveregs[(core * 11) + 1] = - read_radio_reg(pi, - RADIO_2056_TX_IQCAL_VCM_HG | - jtag_core); + read_radio_reg(pi, + RADIO_2056_TX_IQCAL_VCM_HG | + jtag_core); pi->tx_rx_cal_radio_saveregs[(core * 11) + 2] = - read_radio_reg(pi, - RADIO_2056_TX_IQCAL_IDAC | - jtag_core); + read_radio_reg(pi, + RADIO_2056_TX_IQCAL_IDAC | + jtag_core); pi->tx_rx_cal_radio_saveregs[(core * 11) + 3] = - read_radio_reg(pi, - RADIO_2056_TX_TSSI_VCM | jtag_core); + read_radio_reg( + pi, + RADIO_2056_TX_TSSI_VCM | + jtag_core); pi->tx_rx_cal_radio_saveregs[(core * 11) + 4] = - read_radio_reg(pi, - RADIO_2056_TX_TX_AMP_DET | - jtag_core); + read_radio_reg(pi, + RADIO_2056_TX_TX_AMP_DET | + jtag_core); pi->tx_rx_cal_radio_saveregs[(core * 11) + 5] = - read_radio_reg(pi, - RADIO_2056_TX_TX_SSI_MUX | - jtag_core); + read_radio_reg(pi, + RADIO_2056_TX_TX_SSI_MUX | + jtag_core); pi->tx_rx_cal_radio_saveregs[(core * 11) + 6] = - read_radio_reg(pi, RADIO_2056_TX_TSSIA | jtag_core); + read_radio_reg(pi, + RADIO_2056_TX_TSSIA | jtag_core); pi->tx_rx_cal_radio_saveregs[(core * 11) + 7] = - read_radio_reg(pi, RADIO_2056_TX_TSSIG | jtag_core); + read_radio_reg(pi, + RADIO_2056_TX_TSSIG | jtag_core); pi->tx_rx_cal_radio_saveregs[(core * 11) + 8] = - read_radio_reg(pi, - RADIO_2056_TX_TSSI_MISC1 | - jtag_core); + read_radio_reg(pi, + RADIO_2056_TX_TSSI_MISC1 | + jtag_core); pi->tx_rx_cal_radio_saveregs[(core * 11) + 9] = - read_radio_reg(pi, - RADIO_2056_TX_TSSI_MISC2 | - jtag_core); + read_radio_reg(pi, + RADIO_2056_TX_TSSI_MISC2 | + jtag_core); pi->tx_rx_cal_radio_saveregs[(core * 11) + 10] = - read_radio_reg(pi, - RADIO_2056_TX_TSSI_MISC3 | - jtag_core); + read_radio_reg(pi, + RADIO_2056_TX_TSSI_MISC3 | + jtag_core); if (CHSPEC_IS5G(pi->radio_chanspec)) { write_radio_reg(pi, @@ -22860,16 +23767,18 @@ static void wlc_phy_txcal_radio_setup_nphy(struct brcms_phy *pi) jtag_core, 0x00); if (PHY_IPA(pi)) { - write_radio_reg(pi, - RADIO_2056_TX_TX_SSI_MUX - | jtag_core, 0x4); + write_radio_reg( + pi, + RADIO_2056_TX_TX_SSI_MUX + | jtag_core, 0x4); write_radio_reg(pi, RADIO_2056_TX_TSSIA | jtag_core, 0x1); } else { - write_radio_reg(pi, - RADIO_2056_TX_TX_SSI_MUX - | jtag_core, 0x00); + write_radio_reg( + pi, + RADIO_2056_TX_TX_SSI_MUX + | jtag_core, 0x00); write_radio_reg(pi, RADIO_2056_TX_TSSIA | jtag_core, 0x2f); @@ -22909,26 +23818,27 @@ static void wlc_phy_txcal_radio_setup_nphy(struct brcms_phy *pi) if (PHY_IPA(pi)) { - write_radio_reg(pi, - RADIO_2056_TX_TX_SSI_MUX - | jtag_core, 0x06); - if (NREV_LT(pi->pubpi.phy_rev, 5)) { - - write_radio_reg(pi, - RADIO_2056_TX_TSSIG - | jtag_core, - 0x11); - } else { - - write_radio_reg(pi, - RADIO_2056_TX_TSSIG - | jtag_core, - 0x1); - } + write_radio_reg( + pi, + RADIO_2056_TX_TX_SSI_MUX + | jtag_core, 0x06); + if (NREV_LT(pi->pubpi.phy_rev, 5)) + write_radio_reg( + pi, + RADIO_2056_TX_TSSIG + | jtag_core, + 0x11); + else + write_radio_reg( + pi, + RADIO_2056_TX_TSSIG + | jtag_core, + 0x1); } else { - write_radio_reg(pi, - RADIO_2056_TX_TX_SSI_MUX - | jtag_core, 0x00); + write_radio_reg( + pi, + RADIO_2056_TX_TX_SSI_MUX + | jtag_core, 0x00); write_radio_reg(pi, RADIO_2056_TX_TSSIG | jtag_core, 0x20); @@ -22948,23 +23858,23 @@ static void wlc_phy_txcal_radio_setup_nphy(struct brcms_phy *pi) } else { pi->tx_rx_cal_radio_saveregs[0] = - read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1); + read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1); write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL1, 0x29); pi->tx_rx_cal_radio_saveregs[1] = - read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2); + read_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2); write_radio_reg(pi, RADIO_2055_CORE1_TXRF_IQCAL2, 0x54); pi->tx_rx_cal_radio_saveregs[2] = - read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1); + read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1); write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL1, 0x29); pi->tx_rx_cal_radio_saveregs[3] = - read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2); + read_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2); write_radio_reg(pi, RADIO_2055_CORE2_TXRF_IQCAL2, 0x54); pi->tx_rx_cal_radio_saveregs[4] = - read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1); + read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE1); pi->tx_rx_cal_radio_saveregs[5] = - read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2); + read_radio_reg(pi, RADIO_2055_PWRDET_RXTX_CORE2); if ((read_phy_reg(pi, 0x09) & NPHY_BandControl_currentBand) == 0) { @@ -23025,11 +23935,8 @@ static void wlc_phy_txcal_radio_cleanup_nphy(struct brcms_phy *pi) if (pi->pubpi.radiorev != 5) WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSIA, - pi-> - tx_rx_cal_radio_saveregs[(core - * - 11) + - 6]); + pi->tx_rx_cal_radio_saveregs + [(core * 11) + 6]); WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSIG, pi-> @@ -23043,9 +23950,8 @@ static void wlc_phy_txcal_radio_cleanup_nphy(struct brcms_phy *pi) } } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { for (core = 0; core <= 1; core++) { - jtag_core = - (core == - PHY_CORE_0) ? RADIO_2056_TX0 : RADIO_2056_TX1; + jtag_core = (core == PHY_CORE_0) ? + RADIO_2056_TX0 : RADIO_2056_TX1; write_radio_reg(pi, RADIO_2056_TX_TX_SSI_MASTER | jtag_core, @@ -23171,23 +24077,22 @@ static void wlc_phy_txcal_physetup_nphy(struct brcms_phy *pi) pi->tx_rx_cal_phy_saveregs[7] = read_phy_reg(pi, 0x91); pi->tx_rx_cal_phy_saveregs[8] = read_phy_reg(pi, 0x92); - if (!(pi->use_int_tx_iqlo_cal_nphy)) { - - wlc_phy_rfctrlintc_override_nphy(pi, - NPHY_RfctrlIntc_override_PA, - 1, - RADIO_MIMO_CORESEL_CORE1 - | - RADIO_MIMO_CORESEL_CORE2); - } else { - - wlc_phy_rfctrlintc_override_nphy(pi, - NPHY_RfctrlIntc_override_PA, - 0, - RADIO_MIMO_CORESEL_CORE1 - | - RADIO_MIMO_CORESEL_CORE2); - } + if (!(pi->use_int_tx_iqlo_cal_nphy)) + wlc_phy_rfctrlintc_override_nphy( + pi, + NPHY_RfctrlIntc_override_PA, + 1, + RADIO_MIMO_CORESEL_CORE1 + | + RADIO_MIMO_CORESEL_CORE2); + else + wlc_phy_rfctrlintc_override_nphy( + pi, + NPHY_RfctrlIntc_override_PA, + 0, + RADIO_MIMO_CORESEL_CORE1 + | + RADIO_MIMO_CORESEL_CORE2); wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_TRSW, @@ -23205,12 +24110,13 @@ static void wlc_phy_txcal_physetup_nphy(struct brcms_phy *pi) 0x29b, (0x1 << 0), (0) << 0); if (NREV_IS(pi->pubpi.phy_rev, 7) - || NREV_GE(pi->pubpi.phy_rev, 8)) { - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7), - wlc_phy_read_lpf_bw_ctl_nphy - (pi, 0), 0, 0, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - } + || NREV_GE(pi->pubpi.phy_rev, 8)) + wlc_phy_rfctrl_override_nphy_rev7( + pi, (0x1 << 7), + wlc_phy_read_lpf_bw_ctl_nphy + (pi, + 0), 0, 0, + NPHY_REV7_RFCTRLOVERRIDE_ID1); if (pi->use_int_tx_iqlo_cal_nphy && !(pi->internal_tx_iqlo_cal_tapoff_intpa_nphy)) { @@ -23221,25 +24127,30 @@ static void wlc_phy_txcal_physetup_nphy(struct brcms_phy *pi) 1 << 4); if (CHSPEC_IS2G(pi->radio_chanspec)) { - mod_radio_reg(pi, - RADIO_2057_PAD2G_TUNE_PUS_CORE0, - 1, 0); - mod_radio_reg(pi, - RADIO_2057_PAD2G_TUNE_PUS_CORE1, - 1, 0); + mod_radio_reg( + pi, + RADIO_2057_PAD2G_TUNE_PUS_CORE0, + 1, 0); + mod_radio_reg( + pi, + RADIO_2057_PAD2G_TUNE_PUS_CORE1, + 1, 0); } else { - mod_radio_reg(pi, - RADIO_2057_IPA5G_CASCOFFV_PU_CORE0, - 1, 0); - mod_radio_reg(pi, - RADIO_2057_IPA5G_CASCOFFV_PU_CORE1, - 1, 0); + mod_radio_reg( + pi, + RADIO_2057_IPA5G_CASCOFFV_PU_CORE0, + 1, 0); + mod_radio_reg( + pi, + RADIO_2057_IPA5G_CASCOFFV_PU_CORE1, + 1, 0); } } else if (NREV_GE(pi->pubpi.phy_rev, 8)) { - wlc_phy_rfctrl_override_nphy_rev7(pi, - (0x1 << 3), 0, - 0x3, 0, - NPHY_REV7_RFCTRLOVERRIDE_ID0); + wlc_phy_rfctrl_override_nphy_rev7( + pi, + (0x1 << 3), 0, + 0x3, 0, + NPHY_REV7_RFCTRLOVERRIDE_ID0); } } } else { @@ -23302,11 +24213,11 @@ static void wlc_phy_txcal_phycleanup_nphy(struct brcms_phy *pi) write_phy_reg(pi, 0x29b, pi->tx_rx_cal_phy_saveregs[10]); if (NREV_IS(pi->pubpi.phy_rev, 7) - || NREV_GE(pi->pubpi.phy_rev, 8)) { - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7), 0, 0, - 1, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - } + || NREV_GE(pi->pubpi.phy_rev, 8)) + wlc_phy_rfctrl_override_nphy_rev7( + pi, (0x1 << 7), 0, 0, + 1, + NPHY_REV7_RFCTRLOVERRIDE_ID1); wlc_phy_resetcca_nphy(pi); @@ -23315,28 +24226,33 @@ static void wlc_phy_txcal_phycleanup_nphy(struct brcms_phy *pi) if (NREV_IS(pi->pubpi.phy_rev, 7)) { if (CHSPEC_IS2G(pi->radio_chanspec)) { - mod_radio_reg(pi, - RADIO_2057_PAD2G_TUNE_PUS_CORE0, - 1, 1); - mod_radio_reg(pi, - RADIO_2057_PAD2G_TUNE_PUS_CORE1, - 1, 1); + mod_radio_reg( + pi, + RADIO_2057_PAD2G_TUNE_PUS_CORE0, + 1, 1); + mod_radio_reg( + pi, + RADIO_2057_PAD2G_TUNE_PUS_CORE1, + 1, 1); } else { - mod_radio_reg(pi, - RADIO_2057_IPA5G_CASCOFFV_PU_CORE0, - 1, 1); - mod_radio_reg(pi, - RADIO_2057_IPA5G_CASCOFFV_PU_CORE1, - 1, 1); + mod_radio_reg( + pi, + RADIO_2057_IPA5G_CASCOFFV_PU_CORE0, + 1, 1); + mod_radio_reg( + pi, + RADIO_2057_IPA5G_CASCOFFV_PU_CORE1, + 1, 1); } mod_radio_reg(pi, RADIO_2057_OVR_REG0, 1 << 4, 0); } else if (NREV_GE(pi->pubpi.phy_rev, 8)) { - wlc_phy_rfctrl_override_nphy_rev7(pi, - (0x1 << 3), 0, - 0x3, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID0); + wlc_phy_rfctrl_override_nphy_rev7( + pi, + (0x1 << 3), 0, + 0x3, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID0); } } } else { @@ -23356,10 +24272,6 @@ static void wlc_phy_txcal_phycleanup_nphy(struct brcms_phy *pi) } } -#define NPHY_CAL_TSSISAMPS 64 -#define NPHY_TEST_TONE_FREQ_40MHz 4000 -#define NPHY_TEST_TONE_FREQ_20MHz 2500 - void wlc_phy_est_tonepwr_nphy(struct brcms_phy *pi, s32 *qdBm_pwrbuf, u8 num_samps) { @@ -23379,8 +24291,8 @@ wlc_phy_est_tonepwr_nphy(struct brcms_phy *pi, s32 *qdBm_pwrbuf, u8 num_samps) idle_tssi[1] = (temp <= 31) ? temp : (temp - 64); tssi_type = - CHSPEC_IS5G(pi->radio_chanspec) ? - (u8)NPHY_RSSI_SEL_TSSI_5G : (u8)NPHY_RSSI_SEL_TSSI_2G; + CHSPEC_IS5G(pi->radio_chanspec) ? + (u8)NPHY_RSSI_SEL_TSSI_5G : (u8)NPHY_RSSI_SEL_TSSI_2G; wlc_phy_poll_rssi_nphy(pi, tssi_type, rssi_buf, num_samps); @@ -23390,17 +24302,15 @@ wlc_phy_est_tonepwr_nphy(struct brcms_phy *pi, s32 *qdBm_pwrbuf, u8 num_samps) pwrindex[0] = idle_tssi[0] - tssival[0] + 64; pwrindex[1] = idle_tssi[1] - tssival[1] + 64; - if (pwrindex[0] < 0) { + if (pwrindex[0] < 0) pwrindex[0] = 0; - } else if (pwrindex[0] > 63) { + else if (pwrindex[0] > 63) pwrindex[0] = 63; - } - if (pwrindex[1] < 0) { + if (pwrindex[1] < 0) pwrindex[1] = 0; - } else if (pwrindex[1] > 63) { + else if (pwrindex[1] > 63) pwrindex[1] = 63; - } wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 1, (u32) pwrindex[0], 32, &qdBm_pwrbuf[0]); @@ -23408,326 +24318,1239 @@ wlc_phy_est_tonepwr_nphy(struct brcms_phy *pi, s32 *qdBm_pwrbuf, u8 num_samps) (u32) pwrindex[1], 32, &qdBm_pwrbuf[1]); } -static void wlc_phy_internal_cal_txgain_nphy(struct brcms_phy *pi) +static void wlc_phy_update_txcal_ladder_nphy(struct brcms_phy *pi, u16 core) { - u16 txcal_gain[2]; + int index; + u32 bbmult_scale; + u16 bbmult; + u16 tblentry; - pi->nphy_txcal_pwr_idx[0] = pi->nphy_cal_orig_pwr_idx[0]; - pi->nphy_txcal_pwr_idx[1] = pi->nphy_cal_orig_pwr_idx[0]; - wlc_phy_txpwr_index_nphy(pi, 1, pi->nphy_cal_orig_pwr_idx[0], true); - wlc_phy_txpwr_index_nphy(pi, 2, pi->nphy_cal_orig_pwr_idx[1], true); + struct nphy_txiqcal_ladder ladder_lo[] = { + {3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0}, + {25, 0}, {25, 1}, {25, 2}, {25, 3}, {25, 4}, {25, 5}, + {25, 6}, {25, 7}, {35, 7}, {50, 7}, {71, 7}, {100, 7} + }; - wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, - txcal_gain); + struct nphy_txiqcal_ladder ladder_iq[] = { + {3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0}, + {25, 0}, {35, 0}, {50, 0}, {71, 0}, {100, 0}, {100, 1}, + {100, 2}, {100, 3}, {100, 4}, {100, 5}, {100, 6}, {100, 7} + }; - if (CHSPEC_IS2G(pi->radio_chanspec)) { - txcal_gain[0] = (txcal_gain[0] & 0xF000) | 0x0F40; - txcal_gain[1] = (txcal_gain[1] & 0xF000) | 0x0F40; - } else { - txcal_gain[0] = (txcal_gain[0] & 0xF000) | 0x0F60; - txcal_gain[1] = (txcal_gain[1] & 0xF000) | 0x0F60; + bbmult = (core == PHY_CORE_0) ? + ((pi->nphy_txcal_bbmult >> 8) & 0xff) : + (pi->nphy_txcal_bbmult & 0xff); + + for (index = 0; index < 18; index++) { + bbmult_scale = ladder_lo[index].percent * bbmult; + bbmult_scale /= 100; + + tblentry = + ((bbmult_scale & 0xff) << 8) | ladder_lo[index].g_env; + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, index, 16, + &tblentry); + + bbmult_scale = ladder_iq[index].percent * bbmult; + bbmult_scale /= 100; + + tblentry = + ((bbmult_scale & 0xff) << 8) | ladder_iq[index].g_env; + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, index + 32, + 16, &tblentry); } +} - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, - txcal_gain); +static u8 wlc_phy_txpwr_idx_cur_get_nphy(struct brcms_phy *pi, u8 core) +{ + u16 tmp; + tmp = read_phy_reg(pi, ((core == PHY_CORE_0) ? 0x1ed : 0x1ee)); + + tmp = (tmp & (0x7f << 8)) >> 8; + return (u8) tmp; } -static void wlc_phy_precal_txgain_nphy(struct brcms_phy *pi) +static void +wlc_phy_txpwr_idx_cur_set_nphy(struct brcms_phy *pi, u8 idx0, u8 idx1) { - bool save_bbmult = false; - u8 txcal_index_2057_rev5n7 = 0; - u8 txcal_index_2057_rev3n4n6 = 10; + mod_phy_reg(pi, 0x1e7, (0x7f << 0), idx0); + + if (NREV_GT(pi->pubpi.phy_rev, 1)) + mod_phy_reg(pi, 0x222, (0xff << 0), idx1); +} + +static u16 wlc_phy_ipa_get_bbmult_nphy(struct brcms_phy *pi) +{ + u16 m0m1; + + wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m0m1); + + return m0m1; +} + +static void wlc_phy_ipa_set_bbmult_nphy(struct brcms_phy *pi, u8 m0, u8 m1) +{ + u16 m0m1 = (u16) ((m0 << 8) | m1); + + wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m0m1); + wlc_phy_table_write_nphy(pi, 15, 1, 95, 16, &m0m1); +} + +static void +wlc_phy_papd_cal_setup_nphy(struct brcms_phy *pi, + struct nphy_papd_restore_state *state, u8 core) +{ + s32 tone_freq; + u8 off_core; + u16 mixgain = 0; + + off_core = core ^ 0x1; + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + + if (NREV_IS(pi->pubpi.phy_rev, 7) + || NREV_GE(pi->pubpi.phy_rev, 8)) + wlc_phy_rfctrl_override_nphy_rev7( + pi, (0x1 << 7), + wlc_phy_read_lpf_bw_ctl_nphy + (pi, + 0), 0, 0, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + if (pi->pubpi.radiorev == 5) + mixgain = (core == 0) ? 0x20 : 0x00; + else if ((pi->pubpi.radiorev == 7) + || (pi->pubpi.radiorev == 8)) + mixgain = 0x00; + else if ((pi->pubpi.radiorev <= 4) + || (pi->pubpi.radiorev == 6)) + mixgain = 0x00; + } else { + if ((pi->pubpi.radiorev == 4) || + (pi->pubpi.radiorev == 6)) + mixgain = 0x50; + else if ((pi->pubpi.radiorev == 3) + || (pi->pubpi.radiorev == 7) + || (pi->pubpi.radiorev == 8)) + mixgain = 0x0; + } + + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), + mixgain, (1 << core), 0, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + + wlc_phy_rfctrl_override_1tomany_nphy( + pi, + NPHY_REV7_RfctrlOverride_cmd_tx_pu, + 1, (1 << core), 0); + wlc_phy_rfctrl_override_1tomany_nphy( + pi, + NPHY_REV7_RfctrlOverride_cmd_tx_pu, + 0, (1 << off_core), 0); + + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), + 0, 0x3, 0, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), 1, + (1 << core), 0, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 0, + (1 << core), 0, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), 1, + (1 << core), 0, + NPHY_REV7_RFCTRLOVERRIDE_ID2); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 8), 0, + (1 << core), 0, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 9), 1, + (1 << core), 0, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 10), 0, + (1 << core), 0, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), 1, + (1 << core), 0, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5), + 0, (1 << core), 0, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), 0, + (1 << core), 0, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + + state->afectrl[core] = read_phy_reg(pi, (core == PHY_CORE_0) ? + 0xa6 : 0xa7); + state->afeoverride[core] = + read_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f : 0xa5); + state->afectrl[off_core] = + read_phy_reg(pi, (core == PHY_CORE_0) ? 0xa7 : 0xa6); + state->afeoverride[off_core] = + read_phy_reg(pi, (core == PHY_CORE_0) ? 0xa5 : 0x8f); + + mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa6 : 0xa7), + (0x1 << 2), 0); + mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f : + 0xa5), (0x1 << 2), (0x1 << 2)); + + mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa7 : 0xa6), + (0x1 << 2), (0x1 << 2)); + mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa5 : + 0x8f), (0x1 << 2), (0x1 << 2)); + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + state->pwrup[core] = + READ_RADIO_REG3(pi, RADIO_2057, TX, core, + TXRXCOUPLE_2G_PWRUP); + state->atten[core] = + READ_RADIO_REG3(pi, RADIO_2057, TX, core, + TXRXCOUPLE_2G_ATTEN); + state->pwrup[off_core] = + READ_RADIO_REG3(pi, RADIO_2057, TX, off_core, + TXRXCOUPLE_2G_PWRUP); + state->atten[off_core] = + READ_RADIO_REG3(pi, RADIO_2057, TX, off_core, + TXRXCOUPLE_2G_ATTEN); + + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TXRXCOUPLE_2G_PWRUP, 0xc); - if (pi->use_int_tx_iqlo_cal_nphy) { - if (NREV_GE(pi->pubpi.phy_rev, 7)) { if ((pi->pubpi.radiorev == 3) || (pi->pubpi.radiorev == 4) || - (pi->pubpi.radiorev == 6)) { + (pi->pubpi.radiorev == 6)) + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TXRXCOUPLE_2G_ATTEN, 0xf0); + else if (pi->pubpi.radiorev == 5) + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TXRXCOUPLE_2G_ATTEN, + (core == 0) ? 0xf7 : 0xf2); + else if ((pi->pubpi.radiorev == 7) + || (pi->pubpi.radiorev == 8)) + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TXRXCOUPLE_2G_ATTEN, 0xf0); - pi->nphy_txcal_pwr_idx[0] = - txcal_index_2057_rev3n4n6; - pi->nphy_txcal_pwr_idx[1] = - txcal_index_2057_rev3n4n6; - wlc_phy_txpwr_index_nphy(pi, 3, - txcal_index_2057_rev3n4n6, - false); - } else { + WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core, + TXRXCOUPLE_2G_PWRUP, 0x0); + WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core, + TXRXCOUPLE_2G_ATTEN, 0xff); + } else { + state->pwrup[core] = + READ_RADIO_REG3(pi, RADIO_2057, TX, core, + TXRXCOUPLE_5G_PWRUP); + state->atten[core] = + READ_RADIO_REG3(pi, RADIO_2057, TX, core, + TXRXCOUPLE_5G_ATTEN); + state->pwrup[off_core] = + READ_RADIO_REG3(pi, RADIO_2057, TX, off_core, + TXRXCOUPLE_5G_PWRUP); + state->atten[off_core] = + READ_RADIO_REG3(pi, RADIO_2057, TX, off_core, + TXRXCOUPLE_5G_ATTEN); - pi->nphy_txcal_pwr_idx[0] = - txcal_index_2057_rev5n7; - pi->nphy_txcal_pwr_idx[1] = - txcal_index_2057_rev5n7; - wlc_phy_txpwr_index_nphy(pi, 3, - txcal_index_2057_rev5n7, - false); - } - save_bbmult = true; + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TXRXCOUPLE_5G_PWRUP, 0xc); - } else if (NREV_LT(pi->pubpi.phy_rev, 5)) { - wlc_phy_cal_txgainctrl_nphy(pi, 11, false); - if (pi->sh->hw_phytxchain != 3) { - pi->nphy_txcal_pwr_idx[1] = - pi->nphy_txcal_pwr_idx[0]; - wlc_phy_txpwr_index_nphy(pi, 3, - pi-> - nphy_txcal_pwr_idx[0], - true); - save_bbmult = true; + if ((pi->pubpi.radiorev == 7) + || (pi->pubpi.radiorev == 8)) + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TXRXCOUPLE_5G_ATTEN, 0xf4); + + else + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TXRXCOUPLE_5G_ATTEN, 0xf0); + + WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core, + TXRXCOUPLE_5G_PWRUP, 0x0); + WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core, + TXRXCOUPLE_5G_ATTEN, 0xff); + } + + tone_freq = 4000; + + wlc_phy_tx_tone_nphy(pi, tone_freq, 181, 0, 0, false); + + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 : + 0x29b, (0x1 << 0), (NPHY_PAPD_COMP_ON) << 0); + + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0x1 << 13), (1) << 13); + + mod_phy_reg(pi, (off_core == PHY_CORE_0) ? 0x297 : + 0x29b, (0x1 << 0), (NPHY_PAPD_COMP_OFF) << 0); + + mod_phy_reg(pi, (off_core == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0x1 << 13), (0) << 13); + + } else { + + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), 0, 0x3, 0); + + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 1, 0, 0); + + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 0), 0, 0x3, 0); + + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 2), 1, 0x3, 0); + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 1), 1, 0x3, 0); + + state->afectrl[core] = read_phy_reg(pi, (core == PHY_CORE_0) ? + 0xa6 : 0xa7); + state->afeoverride[core] = + read_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f : 0xa5); + + mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa6 : 0xa7), + (0x1 << 0) | (0x1 << 1) | (0x1 << 2), 0); + mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f : + 0xa5), + (0x1 << 0) | + (0x1 << 1) | + (0x1 << 2), (0x1 << 0) | (0x1 << 1) | (0x1 << 2)); + + state->vga_master[core] = + READ_RADIO_REG2(pi, RADIO_2056, RX, core, VGA_MASTER); + WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, VGA_MASTER, 0x2b); + if (CHSPEC_IS2G(pi->radio_chanspec)) { + state->fbmix[core] = + READ_RADIO_REG2(pi, RADIO_2056, RX, core, + TXFBMIX_G); + state->intpa_master[core] = + READ_RADIO_REG2(pi, RADIO_2056, TX, core, + INTPAG_MASTER); + + WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, TXFBMIX_G, + 0x03); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + INTPAG_MASTER, 0x04); + } else { + state->fbmix[core] = + READ_RADIO_REG2(pi, RADIO_2056, RX, core, + TXFBMIX_A); + state->intpa_master[core] = + READ_RADIO_REG2(pi, RADIO_2056, TX, core, + INTPAA_MASTER); + + WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, TXFBMIX_A, + 0x03); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + INTPAA_MASTER, 0x04); + + } + + tone_freq = 4000; + + wlc_phy_tx_tone_nphy(pi, tone_freq, 181, 0, 0, false); + + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 : + 0x29b, (0x1 << 0), (1) << 0); + + mod_phy_reg(pi, (off_core == PHY_CORE_0) ? 0x297 : + 0x29b, (0x1 << 0), (0) << 0); + + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 0x3, 0); + } +} + +static void +wlc_phy_papd_cal_cleanup_nphy(struct brcms_phy *pi, + struct nphy_papd_restore_state *state) +{ + u8 core; + + wlc_phy_stopplayback_nphy(pi); + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + + for (core = 0; core < pi->pubpi.phy_corenum; core++) { + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TXRXCOUPLE_2G_PWRUP, 0); + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TXRXCOUPLE_2G_ATTEN, + state->atten[core]); + } else { + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TXRXCOUPLE_5G_PWRUP, 0); + WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, + TXRXCOUPLE_5G_ATTEN, + state->atten[core]); } + } - } else if (NREV_IS(pi->pubpi.phy_rev, 5)) { - if (PHY_IPA(pi)) { - if (CHSPEC_IS2G(pi->radio_chanspec)) { - wlc_phy_cal_txgainctrl_nphy(pi, 12, - false); - } else { - pi->nphy_txcal_pwr_idx[0] = 80; - pi->nphy_txcal_pwr_idx[1] = 80; - wlc_phy_txpwr_index_nphy(pi, 3, 80, - false); - save_bbmult = true; - } + if ((pi->pubpi.radiorev == 4) || (pi->pubpi.radiorev == 6)) + wlc_phy_rfctrl_override_nphy_rev7( + pi, (0x1 << 2), + 1, 0x3, 0, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + else + wlc_phy_rfctrl_override_nphy_rev7( + pi, (0x1 << 2), + 0, 0x3, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), + 0, 0x3, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 0, 0x3, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID2); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), 0, 0x3, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID2); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 1, 0x3, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), 0, 0x3, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 0, 0x3, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12), 0, 0x3, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), 1, 0x3, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 0, 0x3, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), 1, 0x3, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID2); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 8), 0, 0x3, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 9), 1, 0x3, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 10), 0, 0x3, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), 1, 0x3, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5), 0, 0x3, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), 0, 0x3, 1, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + + for (core = 0; core < pi->pubpi.phy_corenum; core++) { + + write_phy_reg(pi, (core == PHY_CORE_0) ? + 0xa6 : 0xa7, state->afectrl[core]); + write_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f : + 0xa5, state->afeoverride[core]); + } + + wlc_phy_ipa_set_bbmult_nphy(pi, (state->mm >> 8) & 0xff, + (state->mm & 0xff)); + + if (NREV_IS(pi->pubpi.phy_rev, 7) + || NREV_GE(pi->pubpi.phy_rev, 8)) + wlc_phy_rfctrl_override_nphy_rev7( + pi, (0x1 << 7), 0, 0, + 1, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + } else { + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), 0, 0x3, 1); + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 13), 0, 0x3, 1); + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 0), 0, 0x3, 1); + + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 2), 0, 0x3, 1); + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 1), 0, 0x3, 1); + + for (core = 0; core < pi->pubpi.phy_corenum; core++) { + + WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, VGA_MASTER, + state->vga_master[core]); + if (CHSPEC_IS2G(pi->radio_chanspec)) { + WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, + TXFBMIX_G, state->fbmix[core]); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + INTPAG_MASTER, + state->intpa_master[core]); } else { + WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, + TXFBMIX_A, state->fbmix[core]); + WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, + INTPAA_MASTER, + state->intpa_master[core]); + } - wlc_phy_internal_cal_txgain_nphy(pi); - save_bbmult = true; + write_phy_reg(pi, (core == PHY_CORE_0) ? + 0xa6 : 0xa7, state->afectrl[core]); + write_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f : + 0xa5, state->afeoverride[core]); + } + + wlc_phy_ipa_set_bbmult_nphy(pi, (state->mm >> 8) & 0xff, + (state->mm & 0xff)); + + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 0x3, 1); + } +} + +static void +wlc_phy_a1_nphy(struct brcms_phy *pi, u8 core, u32 winsz, u32 start, + u32 end) +{ + u32 *buf, *src, *dst, sz; + + sz = end - start + 1; + + buf = kmalloc(2 * sizeof(u32) * NPHY_PAPD_EPS_TBL_SIZE, GFP_ATOMIC); + if (NULL == buf) + return; + + src = buf; + dst = buf + NPHY_PAPD_EPS_TBL_SIZE; + + wlc_phy_table_read_nphy(pi, + (core == + PHY_CORE_0 ? NPHY_TBL_ID_EPSILONTBL0 : + NPHY_TBL_ID_EPSILONTBL1), + NPHY_PAPD_EPS_TBL_SIZE, 0, 32, src); + + do { + u32 phy_a1, phy_a2; + s32 phy_a3, phy_a4, phy_a5, phy_a6, phy_a7; + + phy_a1 = end - min(end, (winsz >> 1)); + phy_a2 = min_t(u32, NPHY_PAPD_EPS_TBL_SIZE - 1, + end + (winsz >> 1)); + phy_a3 = phy_a2 - phy_a1 + 1; + phy_a6 = 0; + phy_a7 = 0; + + do { + wlc_phy_papd_decode_epsilon(src[phy_a2], &phy_a4, + &phy_a5); + phy_a6 += phy_a4; + phy_a7 += phy_a5; + } while (phy_a2-- != phy_a1); + + phy_a6 /= phy_a3; + phy_a7 /= phy_a3; + dst[end] = ((u32) phy_a7 << 13) | ((u32) phy_a6 & 0x1fff); + } while (end-- != start); + + wlc_phy_table_write_nphy(pi, + (core == + PHY_CORE_0) ? NPHY_TBL_ID_EPSILONTBL0 : + NPHY_TBL_ID_EPSILONTBL1, sz, start, 32, dst); + + kfree(buf); +} + +static void +wlc_phy_a2_nphy(struct brcms_phy *pi, struct nphy_ipa_txcalgains *txgains, + enum phy_cal_mode cal_mode, u8 core) +{ + u16 phy_a1, phy_a2, phy_a3; + u16 phy_a4, phy_a5; + bool phy_a6; + u8 phy_a7, m[2]; + u32 phy_a8 = 0; + struct nphy_txgains phy_a9; + + if (NREV_LT(pi->pubpi.phy_rev, 3)) + return; + + phy_a7 = (core == PHY_CORE_0) ? 1 : 0; + + phy_a6 = ((cal_mode == CAL_GCTRL) + || (cal_mode == CAL_SOFT)) ? true : false; + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + + phy_a9 = wlc_phy_get_tx_gain_nphy(pi); + + if (CHSPEC_IS2G(pi->radio_chanspec)) + phy_a5 = ((phy_a9.txlpf[core] << 15) | + (phy_a9.txgm[core] << 12) | + (phy_a9.pga[core] << 8) | + (txgains->gains.pad[core] << 3) | + (phy_a9.ipa[core])); + else + phy_a5 = ((phy_a9.txlpf[core] << 15) | + (phy_a9.txgm[core] << 12) | + (txgains->gains.pga[core] << 8) | + (phy_a9.pad[core] << 3) | (phy_a9.ipa[core])); + + wlc_phy_rfctrl_override_1tomany_nphy( + pi, + NPHY_REV7_RfctrlOverride_cmd_txgain, + phy_a5, (1 << core), 0); + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + if ((pi->pubpi.radiorev <= 4) + || (pi->pubpi.radiorev == 6)) + m[core] = IS40MHZ(pi) ? 60 : 79; + else + m[core] = IS40MHZ(pi) ? 45 : 64; + } else { + m[core] = IS40MHZ(pi) ? 75 : 107; + } + + m[phy_a7] = 0; + wlc_phy_ipa_set_bbmult_nphy(pi, m[0], m[1]); + + phy_a2 = 63; + + if (CHSPEC_IS2G(pi->radio_chanspec)) { + if ((pi->pubpi.radiorev == 4) + || (pi->pubpi.radiorev == 6)) { + phy_a1 = 30; + phy_a3 = 30; + } else { + phy_a1 = 25; + phy_a3 = 25; } + } else { + if ((pi->pubpi.radiorev == 5) + || (pi->pubpi.radiorev == 7) + || (pi->pubpi.radiorev == 8)) { + phy_a1 = 25; + phy_a3 = 25; + } else { + phy_a1 = 35; + phy_a3 = 35; + } + } - } else if (NREV_IS(pi->pubpi.phy_rev, 6)) { - if (PHY_IPA(pi)) { + if (cal_mode == CAL_GCTRL) { + if ((pi->pubpi.radiorev == 5) + && (CHSPEC_IS2G(pi->radio_chanspec))) + phy_a1 = 55; + else if (((pi->pubpi.radiorev == 7) && + (CHSPEC_IS2G(pi->radio_chanspec))) || + ((pi->pubpi.radiorev == 8) && + (CHSPEC_IS2G(pi->radio_chanspec)))) + phy_a1 = 60; + else + phy_a1 = 63; + + } else if ((cal_mode != CAL_FULL) && (cal_mode != CAL_SOFT)) { + + phy_a1 = 35; + phy_a3 = 35; + } + + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 : + 0x29b, (0x1 << 0), (1) << 0); + + mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x297 : + 0x29b, (0x1 << 0), (0) << 0); + + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0x1 << 13), (1) << 13); + + mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0x1 << 13), (0) << 13); + + write_phy_reg(pi, 0x2a1, 0x80); + write_phy_reg(pi, 0x2a2, 0x100); + + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0x7 << 4), (11) << 4); + + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0x7 << 8), (11) << 8); + + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0x7 << 0), (0x3) << 0); + + write_phy_reg(pi, 0x2e5, 0x20); + + mod_phy_reg(pi, 0x2a0, (0x3f << 0), (phy_a3) << 0); + + mod_phy_reg(pi, 0x29f, (0x3f << 0), (phy_a1) << 0); + + mod_phy_reg(pi, 0x29f, (0x3f << 8), (phy_a2) << 8); + + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), + 1, ((core == 0) ? 1 : 2), 0, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), + 0, ((core == 0) ? 2 : 1), 0, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + + write_phy_reg(pi, 0x2be, 1); + SPINWAIT(read_phy_reg(pi, 0x2be), 10 * 1000 * 1000); + + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), + 0, 0x3, 0, + NPHY_REV7_RFCTRLOVERRIDE_ID0); + + wlc_phy_table_write_nphy(pi, + (core == + PHY_CORE_0) ? NPHY_TBL_ID_EPSILONTBL0 + : NPHY_TBL_ID_EPSILONTBL1, 1, phy_a3, + 32, &phy_a8); + + if (cal_mode != CAL_GCTRL) { + if (CHSPEC_IS5G(pi->radio_chanspec)) + wlc_phy_a1_nphy(pi, core, 5, 0, 35); + } + + wlc_phy_rfctrl_override_1tomany_nphy( + pi, + NPHY_REV7_RfctrlOverride_cmd_txgain, + phy_a5, (1 << core), 1); + + } else { + + if (txgains) { + if (txgains->useindex) { + phy_a4 = 15 - ((txgains->index) >> 3); if (CHSPEC_IS2G(pi->radio_chanspec)) { - wlc_phy_cal_txgainctrl_nphy(pi, 12, - false); + if (NREV_GE(pi->pubpi.phy_rev, 6)) + phy_a5 = 0x00f7 | (phy_a4 << 8); + + else + if (NREV_IS(pi->pubpi.phy_rev, 5)) + phy_a5 = 0x10f7 | (phy_a4 << 8); + else + phy_a5 = 0x50f7 | (phy_a4 << 8); } else { - wlc_phy_cal_txgainctrl_nphy(pi, 14, - false); + phy_a5 = 0x70f7 | (phy_a4 << 8); } + wlc_phy_rfctrl_override_nphy(pi, + (0x1 << 13), + phy_a5, + (1 << core), 0); } else { - - wlc_phy_internal_cal_txgain_nphy(pi); - save_bbmult = true; + wlc_phy_rfctrl_override_nphy(pi, + (0x1 << 13), + 0x5bf7, + (1 << core), 0); } } - } else { - wlc_phy_cal_txgainctrl_nphy(pi, 10, false); - } + if (CHSPEC_IS2G(pi->radio_chanspec)) + m[core] = IS40MHZ(pi) ? 45 : 64; + else + m[core] = IS40MHZ(pi) ? 75 : 107; - if (save_bbmult) { - wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, - &pi->nphy_txcal_bbmult); + m[phy_a7] = 0; + wlc_phy_ipa_set_bbmult_nphy(pi, m[0], m[1]); + + phy_a2 = 63; + + if (cal_mode == CAL_FULL) { + phy_a1 = 25; + phy_a3 = 25; + } else if (cal_mode == CAL_SOFT) { + phy_a1 = 25; + phy_a3 = 25; + } else if (cal_mode == CAL_GCTRL) { + phy_a1 = 63; + phy_a3 = 25; + } else { + + phy_a1 = 25; + phy_a3 = 25; + } + + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 : + 0x29b, (0x1 << 0), (1) << 0); + + mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x297 : + 0x29b, (0x1 << 0), (0) << 0); + + if (NREV_GE(pi->pubpi.phy_rev, 6)) { + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0x1 << 13), (1) << 13); + + mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0x1 << 13), (0) << 13); + + write_phy_reg(pi, 0x2a1, 0x20); + write_phy_reg(pi, 0x2a2, 0x60); + + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0xf << 4), (9) << 4); + + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0xf << 8), (9) << 8); + + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0xf << 0), (0x2) << 0); + + write_phy_reg(pi, 0x2e5, 0x20); + } else { + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0x1 << 11), (1) << 11); + + mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0x1 << 11), (0) << 11); + + write_phy_reg(pi, 0x2a1, 0x80); + write_phy_reg(pi, 0x2a2, 0x600); + + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0x7 << 4), (0) << 4); + + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0x7 << 8), (0) << 8); + + mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0x7 << 0), (0x3) << 0); + + mod_phy_reg(pi, 0x2a0, (0x3f << 8), (0x20) << 8); + + } + + mod_phy_reg(pi, 0x2a0, (0x3f << 0), (phy_a3) << 0); + + mod_phy_reg(pi, 0x29f, (0x3f << 0), (phy_a1) << 0); + + mod_phy_reg(pi, 0x29f, (0x3f << 8), (phy_a2) << 8); + + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 1, 0x3, 0); + + write_phy_reg(pi, 0x2be, 1); + SPINWAIT(read_phy_reg(pi, 0x2be), 10 * 1000 * 1000); + + wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 0x3, 0); + + wlc_phy_table_write_nphy(pi, + (core == + PHY_CORE_0) ? NPHY_TBL_ID_EPSILONTBL0 + : NPHY_TBL_ID_EPSILONTBL1, 1, phy_a3, + 32, &phy_a8); + + if (cal_mode != CAL_GCTRL) + wlc_phy_a1_nphy(pi, core, 5, 0, 40); } } -void -wlc_phy_cal_txgainctrl_nphy(struct brcms_phy *pi, s32 dBm_targetpower, - bool debug) +static u8 wlc_phy_a3_nphy(struct brcms_phy *pi, u8 start_gain, u8 core) { - int gainctrl_loopidx; - uint core; - u16 m0m1, curr_m0m1; - s32 delta_power; - s32 txpwrindex; - s32 qdBm_power[2]; - u16 orig_BBConfig; - u16 phy_saveregs[4]; - u32 freq_test; - u16 ampl_test = 250; - uint stepsize; - bool phyhang_avoid_state = false; + int phy_a1; + int phy_a2; + bool phy_a3; + struct nphy_ipa_txcalgains phy_a4; + bool phy_a5 = false; + bool phy_a6 = true; + s32 phy_a7, phy_a8; + u32 phy_a9; + int phy_a10; + bool phy_a11 = false; + int phy_a12; + u8 phy_a13 = 0; + u8 phy_a14; + u8 *phy_a15 = NULL; + + phy_a4.useindex = true; + phy_a12 = start_gain; if (NREV_GE(pi->pubpi.phy_rev, 7)) { - stepsize = 2; - } else { + phy_a2 = 20; + phy_a1 = 1; - stepsize = 1; - } + if (CHSPEC_IS2G(pi->radio_chanspec)) { + if (pi->pubpi.radiorev == 5) { - if (CHSPEC_IS40(pi->radio_chanspec)) { - freq_test = 5000; - } else { - freq_test = 2500; - } + phy_a15 = pad_gain_codes_used_2057rev5; + phy_a13 = + sizeof(pad_gain_codes_used_2057rev5) / + sizeof(pad_gain_codes_used_2057rev5 + [0]) - 1; - wlc_phy_txpwr_index_nphy(pi, 1, pi->nphy_cal_orig_pwr_idx[0], true); - wlc_phy_txpwr_index_nphy(pi, 2, pi->nphy_cal_orig_pwr_idx[1], true); + } else if ((pi->pubpi.radiorev == 7) + || (pi->pubpi.radiorev == 8)) { - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, true); + phy_a15 = pad_gain_codes_used_2057rev7; + phy_a13 = + sizeof(pad_gain_codes_used_2057rev7) / + sizeof(pad_gain_codes_used_2057rev7 + [0]) - 1; - phyhang_avoid_state = pi->phyhang_avoid; - pi->phyhang_avoid = false; + } else { - phy_saveregs[0] = read_phy_reg(pi, 0x91); - phy_saveregs[1] = read_phy_reg(pi, 0x92); - phy_saveregs[2] = read_phy_reg(pi, 0xe7); - phy_saveregs[3] = read_phy_reg(pi, 0xec); - wlc_phy_rfctrlintc_override_nphy(pi, NPHY_RfctrlIntc_override_PA, 1, - RADIO_MIMO_CORESEL_CORE1 | - RADIO_MIMO_CORESEL_CORE2); + phy_a15 = pad_all_gain_codes_2057; + phy_a13 = sizeof(pad_all_gain_codes_2057) / + sizeof(pad_all_gain_codes_2057[0]) - + 1; + } - if (!debug) { - wlc_phy_rfctrlintc_override_nphy(pi, - NPHY_RfctrlIntc_override_TRSW, - 0x2, RADIO_MIMO_CORESEL_CORE1); - wlc_phy_rfctrlintc_override_nphy(pi, - NPHY_RfctrlIntc_override_TRSW, - 0x8, RADIO_MIMO_CORESEL_CORE2); - } else { - wlc_phy_rfctrlintc_override_nphy(pi, - NPHY_RfctrlIntc_override_TRSW, - 0x1, RADIO_MIMO_CORESEL_CORE1); - wlc_phy_rfctrlintc_override_nphy(pi, - NPHY_RfctrlIntc_override_TRSW, - 0x7, RADIO_MIMO_CORESEL_CORE2); - } + } else { - orig_BBConfig = read_phy_reg(pi, 0x01); - mod_phy_reg(pi, 0x01, (0x1 << 15), 0); + phy_a15 = pga_all_gain_codes_2057; + phy_a13 = sizeof(pga_all_gain_codes_2057) / + sizeof(pga_all_gain_codes_2057[0]) - 1; + } - wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m0m1); + phy_a14 = 0; - for (core = 0; core < pi->pubpi.phy_corenum; core++) { - txpwrindex = (s32) pi->nphy_cal_orig_pwr_idx[core]; + for (phy_a10 = 0; phy_a10 < phy_a2; phy_a10++) { + if (CHSPEC_IS2G(pi->radio_chanspec)) + phy_a4.gains.pad[core] = + (u16) phy_a15[phy_a12]; + else + phy_a4.gains.pga[core] = + (u16) phy_a15[phy_a12]; - for (gainctrl_loopidx = 0; gainctrl_loopidx < 2; - gainctrl_loopidx++) { - wlc_phy_tx_tone_nphy(pi, freq_test, ampl_test, 0, 0, - false); + wlc_phy_a2_nphy(pi, &phy_a4, CAL_GCTRL, core); - if (core == PHY_CORE_0) { - curr_m0m1 = m0m1 & 0xff00; - } else { - curr_m0m1 = m0m1 & 0x00ff; + wlc_phy_table_read_nphy(pi, + (core == + PHY_CORE_0 ? + NPHY_TBL_ID_EPSILONTBL0 : + NPHY_TBL_ID_EPSILONTBL1), 1, + 63, 32, &phy_a9); + + wlc_phy_papd_decode_epsilon(phy_a9, &phy_a7, &phy_a8); + + phy_a3 = ((phy_a7 == 4095) || (phy_a7 == -4096) || + (phy_a8 == 4095) || (phy_a8 == -4096)); + + if (!phy_a6 && (phy_a3 != phy_a5)) { + if (!phy_a3) + phy_a12 -= (u8) phy_a1; + + phy_a11 = true; + break; } - wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &curr_m0m1); - wlc_phy_table_write_nphy(pi, 15, 1, 95, 16, &curr_m0m1); + if (phy_a3) + phy_a12 += (u8) phy_a1; + else + phy_a12 -= (u8) phy_a1; - udelay(50); + if ((phy_a12 < phy_a14) || (phy_a12 > phy_a13)) { + if (phy_a12 < phy_a14) + phy_a12 = phy_a14; + else + phy_a12 = phy_a13; - wlc_phy_est_tonepwr_nphy(pi, qdBm_power, - NPHY_CAL_TSSISAMPS); + phy_a11 = true; + break; + } - pi->nphy_bb_mult_save = 0; - wlc_phy_stopplayback_nphy(pi); + phy_a6 = false; + phy_a5 = phy_a3; + } - delta_power = (dBm_targetpower * 4) - qdBm_power[core]; + } else { + phy_a2 = 10; + phy_a1 = 8; + for (phy_a10 = 0; phy_a10 < phy_a2; phy_a10++) { + phy_a4.index = (u8) phy_a12; + wlc_phy_a2_nphy(pi, &phy_a4, CAL_GCTRL, core); - txpwrindex -= stepsize * delta_power; - if (txpwrindex < 0) { - txpwrindex = 0; - } else if (txpwrindex > 127) { - txpwrindex = 127; + wlc_phy_table_read_nphy(pi, + (core == + PHY_CORE_0 ? + NPHY_TBL_ID_EPSILONTBL0 : + NPHY_TBL_ID_EPSILONTBL1), 1, + 63, 32, &phy_a9); + + wlc_phy_papd_decode_epsilon(phy_a9, &phy_a7, &phy_a8); + + phy_a3 = ((phy_a7 == 4095) || (phy_a7 == -4096) || + (phy_a8 == 4095) || (phy_a8 == -4096)); + + if (!phy_a6 && (phy_a3 != phy_a5)) { + if (!phy_a3) + phy_a12 -= (u8) phy_a1; + + phy_a11 = true; + break; } - if (CHSPEC_IS5G(pi->radio_chanspec)) { - if (NREV_IS(pi->pubpi.phy_rev, 4) && - (pi->srom_fem5g.extpagain == 3)) { - if (txpwrindex < 30) { - txpwrindex = 30; - } - } - } else { - if (NREV_GE(pi->pubpi.phy_rev, 5) && - (pi->srom_fem2g.extpagain == 3)) { - if (txpwrindex < 50) { - txpwrindex = 50; - } - } + if (phy_a3) + phy_a12 += (u8) phy_a1; + else + phy_a12 -= (u8) phy_a1; + + if ((phy_a12 < 0) || (phy_a12 > 127)) { + if (phy_a12 < 0) + phy_a12 = 0; + else + phy_a12 = 127; + + phy_a11 = true; + break; } - wlc_phy_txpwr_index_nphy(pi, (1 << core), - (u8) txpwrindex, true); + phy_a6 = false; + phy_a5 = phy_a3; } - pi->nphy_txcal_pwr_idx[core] = (u8) txpwrindex; + } - if (debug) { - u16 radio_gain; - u16 dbg_m0m1; + if (NREV_GE(pi->pubpi.phy_rev, 7)) + return (u8) phy_a15[phy_a12]; + else + return (u8) phy_a12; - wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &dbg_m0m1); +} - wlc_phy_tx_tone_nphy(pi, freq_test, ampl_test, 0, 0, - false); +static void wlc_phy_a4(struct brcms_phy *pi, bool full_cal) +{ + struct nphy_ipa_txcalgains phy_b1[2]; + struct nphy_papd_restore_state phy_b2; + bool phy_b3; + u8 phy_b4; + u8 phy_b5; + s16 phy_b6, phy_b7, phy_b8; + u16 phy_b9; + s16 phy_b10, phy_b11, phy_b12; - wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &dbg_m0m1); - wlc_phy_table_write_nphy(pi, 15, 1, 95, 16, &dbg_m0m1); + phy_b11 = 0; + phy_b12 = 0; + phy_b7 = 0; + phy_b8 = 0; + phy_b6 = 0; - udelay(100); + if (pi->nphy_papd_skip == 1) + return; - wlc_phy_est_tonepwr_nphy(pi, qdBm_power, - NPHY_CAL_TSSISAMPS); + phy_b3 = (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); + if (!phy_b3) + wlapi_suspend_mac_and_wait(pi->sh->physhim); - wlc_phy_table_read_nphy(pi, 7, 1, (0x110 + core), 16, - &radio_gain); + wlc_phy_stay_in_carriersearch_nphy(pi, true); - mdelay(4000); - pi->nphy_bb_mult_save = 0; - wlc_phy_stopplayback_nphy(pi); + pi->nphy_force_papd_cal = false; + + for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) + pi->nphy_papd_tx_gain_at_last_cal[phy_b5] = + wlc_phy_txpwr_idx_cur_get_nphy(pi, phy_b5); + + pi->nphy_papd_last_cal = pi->sh->now; + pi->nphy_papd_recal_counter++; + + phy_b4 = pi->nphy_txpwrctrl; + wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF); + + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_SCALARTBL0, 64, 0, 32, + nphy_papd_scaltbl); + wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_SCALARTBL1, 64, 0, 32, + nphy_papd_scaltbl); + + phy_b9 = read_phy_reg(pi, 0x01); + mod_phy_reg(pi, 0x01, (0x1 << 15), 0); + + for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) { + s32 i, val = 0; + for (i = 0; i < 64; i++) + wlc_phy_table_write_nphy(pi, + ((phy_b5 == + PHY_CORE_0) ? + NPHY_TBL_ID_EPSILONTBL0 : + NPHY_TBL_ID_EPSILONTBL1), 1, + i, 32, &val); + } + + wlc_phy_ipa_restore_tx_digi_filts_nphy(pi); + + phy_b2.mm = wlc_phy_ipa_get_bbmult_nphy(pi); + for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) { + wlc_phy_papd_cal_setup_nphy(pi, &phy_b2, phy_b5); + + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + if (CHSPEC_IS2G(pi->radio_chanspec)) { + if ((pi->pubpi.radiorev == 3) + || (pi->pubpi.radiorev == 4) + || (pi->pubpi.radiorev == 6)) { + pi->nphy_papd_cal_gain_index[phy_b5] = + 23; + } else if (pi->pubpi.radiorev == 5) { + pi->nphy_papd_cal_gain_index[phy_b5] = + 0; + pi->nphy_papd_cal_gain_index[phy_b5] = + wlc_phy_a3_nphy( + pi, + pi-> + nphy_papd_cal_gain_index + [phy_b5], + phy_b5); + + } else if ((pi->pubpi.radiorev == 7) + || (pi->pubpi.radiorev == 8)) { + + pi->nphy_papd_cal_gain_index[phy_b5] = + 0; + pi->nphy_papd_cal_gain_index[phy_b5] = + wlc_phy_a3_nphy( + pi, + pi-> + nphy_papd_cal_gain_index + [phy_b5], + phy_b5); + + } + + phy_b1[phy_b5].gains.pad[phy_b5] = + pi->nphy_papd_cal_gain_index[phy_b5]; + + } else { + pi->nphy_papd_cal_gain_index[phy_b5] = 0; + pi->nphy_papd_cal_gain_index[phy_b5] = + wlc_phy_a3_nphy( + pi, + pi-> + nphy_papd_cal_gain_index + [phy_b5], phy_b5); + phy_b1[phy_b5].gains.pga[phy_b5] = + pi->nphy_papd_cal_gain_index[phy_b5]; + } + } else { + phy_b1[phy_b5].useindex = true; + phy_b1[phy_b5].index = 16; + phy_b1[phy_b5].index = + wlc_phy_a3_nphy(pi, phy_b1[phy_b5].index, + phy_b5); + + pi->nphy_papd_cal_gain_index[phy_b5] = + 15 - ((phy_b1[phy_b5].index) >> 3); } + + switch (pi->nphy_papd_cal_type) { + case 0: + wlc_phy_a2_nphy(pi, &phy_b1[phy_b5], CAL_FULL, phy_b5); + break; + case 1: + wlc_phy_a2_nphy(pi, &phy_b1[phy_b5], CAL_SOFT, phy_b5); + break; + } + + if (NREV_GE(pi->pubpi.phy_rev, 7)) + wlc_phy_papd_cal_cleanup_nphy(pi, &phy_b2); } - wlc_phy_txpwr_index_nphy(pi, 1, pi->nphy_txcal_pwr_idx[0], true); - wlc_phy_txpwr_index_nphy(pi, 2, pi->nphy_txcal_pwr_idx[1], true); + if (NREV_LT(pi->pubpi.phy_rev, 7)) + wlc_phy_papd_cal_cleanup_nphy(pi, &phy_b2); - wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &pi->nphy_txcal_bbmult); + for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) { + int eps_offset = 0; - write_phy_reg(pi, 0x01, orig_BBConfig); + if (NREV_GE(pi->pubpi.phy_rev, 7)) { + if (CHSPEC_IS2G(pi->radio_chanspec)) { + if (pi->pubpi.radiorev == 3) + eps_offset = -2; + else if (pi->pubpi.radiorev == 5) + eps_offset = 3; + else + eps_offset = -1; + } else { + eps_offset = 2; + } - write_phy_reg(pi, 0x91, phy_saveregs[0]); - write_phy_reg(pi, 0x92, phy_saveregs[1]); - write_phy_reg(pi, 0xe7, phy_saveregs[2]); - write_phy_reg(pi, 0xec, phy_saveregs[3]); + if (CHSPEC_IS2G(pi->radio_chanspec)) { + phy_b8 = phy_b1[phy_b5].gains.pad[phy_b5]; + phy_b10 = 0; + if ((pi->pubpi.radiorev == 3) || + (pi->pubpi.radiorev == 4) || + (pi->pubpi.radiorev == 6)) { + phy_b12 = -( + nphy_papd_padgain_dlt_2g_2057rev3n4 + [phy_b8] + 1) / 2; + phy_b10 = -1; + } else if (pi->pubpi.radiorev == 5) { + phy_b12 = -( + nphy_papd_padgain_dlt_2g_2057rev5 + [phy_b8] + 1) / 2; + } else if ((pi->pubpi.radiorev == 7) || + (pi->pubpi.radiorev == 8)) { + phy_b12 = -( + nphy_papd_padgain_dlt_2g_2057rev7 + [phy_b8] + 1) / 2; + } + } else { + phy_b7 = phy_b1[phy_b5].gains.pga[phy_b5]; + if ((pi->pubpi.radiorev == 3) || + (pi->pubpi.radiorev == 4) || + (pi->pubpi.radiorev == 6)) + phy_b11 = + -(nphy_papd_pgagain_dlt_5g_2057 + [phy_b7] + + 1) / 2; + else if ((pi->pubpi.radiorev == 7) + || (pi->pubpi.radiorev == 8)) + phy_b11 = -( + nphy_papd_pgagain_dlt_5g_2057rev7 + [phy_b7] + 1) / 2; - pi->phyhang_avoid = phyhang_avoid_state; + phy_b10 = -9; + } - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, false); -} + if (CHSPEC_IS2G(pi->radio_chanspec)) + phy_b6 = + -60 + 27 + eps_offset + phy_b12 + + phy_b10; + else + phy_b6 = + -60 + 27 + eps_offset + phy_b11 + + phy_b10; -static void wlc_phy_update_txcal_ladder_nphy(struct brcms_phy *pi, u16 core) -{ - int index; - u32 bbmult_scale; - u16 bbmult; - u16 tblentry; + mod_phy_reg(pi, (phy_b5 == PHY_CORE_0) ? 0x298 : + 0x29c, (0x1ff << 7), (phy_b6) << 7); - struct nphy_txiqcal_ladder ladder_lo[] = { - {3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0}, - {25, 0}, {25, 1}, {25, 2}, {25, 3}, {25, 4}, {25, 5}, - {25, 6}, {25, 7}, {35, 7}, {50, 7}, {71, 7}, {100, 7} - }; + pi->nphy_papd_epsilon_offset[phy_b5] = phy_b6; + } else { + if (NREV_LT(pi->pubpi.phy_rev, 5)) + eps_offset = 4; + else + eps_offset = 2; - struct nphy_txiqcal_ladder ladder_iq[] = { - {3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0}, - {25, 0}, {35, 0}, {50, 0}, {71, 0}, {100, 0}, {100, 1}, - {100, 2}, {100, 3}, {100, 4}, {100, 5}, {100, 6}, {100, 7} - }; + phy_b7 = 15 - ((phy_b1[phy_b5].index) >> 3); - bbmult = (core == PHY_CORE_0) ? - ((pi->nphy_txcal_bbmult >> 8) & 0xff) : (pi-> - nphy_txcal_bbmult & 0xff); + if (CHSPEC_IS2G(pi->radio_chanspec)) { + phy_b11 = + -(nphy_papd_pga_gain_delta_ipa_2g[ + phy_b7] + + 1) / 2; + phy_b10 = 0; + } else { + phy_b11 = + -(nphy_papd_pga_gain_delta_ipa_5g[ + phy_b7] + + 1) / 2; + phy_b10 = -9; + } - for (index = 0; index < 18; index++) { - bbmult_scale = ladder_lo[index].percent * bbmult; - bbmult_scale /= 100; + phy_b6 = -60 + 27 + eps_offset + phy_b11 + phy_b10; - tblentry = - ((bbmult_scale & 0xff) << 8) | ladder_lo[index].g_env; - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, index, 16, - &tblentry); + mod_phy_reg(pi, (phy_b5 == PHY_CORE_0) ? 0x298 : + 0x29c, (0x1ff << 7), (phy_b6) << 7); - bbmult_scale = ladder_iq[index].percent * bbmult; - bbmult_scale /= 100; + pi->nphy_papd_epsilon_offset[phy_b5] = phy_b6; + } + } + + mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 : + 0x29b, (0x1 << 0), (NPHY_PAPD_COMP_ON) << 0); + + mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 : + 0x29b, (0x1 << 0), (NPHY_PAPD_COMP_ON) << 0); + + if (NREV_GE(pi->pubpi.phy_rev, 6)) { + mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0x1 << 13), (0) << 13); + + mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0x1 << 13), (0) << 13); + + } else { + mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0x1 << 11), (0) << 11); + + mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x2a3 : + 0x2a4, (0x1 << 11), (0) << 11); - tblentry = - ((bbmult_scale & 0xff) << 8) | ladder_iq[index].g_env; - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_IQLOCAL, 1, index + 32, - 16, &tblentry); } + pi->nphy_papdcomp = NPHY_PAPD_COMP_ON; + + write_phy_reg(pi, 0x01, phy_b9); + + wlc_phy_ipa_set_tx_digi_filts_nphy(pi); + + wlc_phy_txpwrctrl_enable_nphy(pi, phy_b4); + if (phy_b4 == PHY_TPC_HW_OFF) { + wlc_phy_txpwr_index_nphy(pi, (1 << 0), + (s8) (pi->nphy_txpwrindex[0]. + index_internal), false); + wlc_phy_txpwr_index_nphy(pi, (1 << 1), + (s8) (pi->nphy_txpwrindex[1]. + index_internal), false); + } + + wlc_phy_stay_in_carriersearch_nphy(pi, false); + + if (!phy_b3) + wlapi_enable_mac(pi->sh->physhim); } void wlc_phy_cal_perical_nphy_run(struct brcms_phy *pi, u8 caltype) @@ -23738,11 +25561,6 @@ void wlc_phy_cal_perical_nphy_run(struct brcms_phy *pi, u8 caltype) bool restore_tx_gain = false; bool mphase; - if (NORADIO_ENAB(pi->pubpi)) { - wlc_phy_cal_perical_mphase_reset(pi); - return; - } - if (PHY_MUTED(pi)) return; @@ -23751,19 +25569,18 @@ void wlc_phy_cal_perical_nphy_run(struct brcms_phy *pi, u8 caltype) else if (caltype == PHY_PERICAL_PARTIAL) fullcal = false; - if (pi->cal_type_override != PHY_PERICAL_AUTO) { + if (pi->cal_type_override != PHY_PERICAL_AUTO) fullcal = - (pi->cal_type_override == PHY_PERICAL_FULL) ? true : false; - } + (pi->cal_type_override == + PHY_PERICAL_FULL) ? true : false; if ((pi->mphase_cal_phase_id > MPHASE_CAL_STATE_INIT)) { if (pi->nphy_txiqlocal_chanspec != pi->radio_chanspec) wlc_phy_cal_perical_mphase_restart(pi); } - if ((pi->mphase_cal_phase_id == MPHASE_CAL_STATE_RXCAL)) { + if ((pi->mphase_cal_phase_id == MPHASE_CAL_STATE_RXCAL)) wlapi_bmac_write_shm(pi->sh->physhim, M_CTS_DURATION, 10000); - } wlapi_suspend_mac_and_wait(pi->sh->physhim); @@ -23772,9 +25589,9 @@ void wlc_phy_cal_perical_nphy_run(struct brcms_phy *pi, u8 caltype) if ((pi->mphase_cal_phase_id == MPHASE_CAL_STATE_IDLE) || (pi->mphase_cal_phase_id == MPHASE_CAL_STATE_INIT)) { pi->nphy_cal_orig_pwr_idx[0] = - (u8) ((read_phy_reg(pi, 0x1ed) >> 8) & 0x7f); + (u8) ((read_phy_reg(pi, 0x1ed) >> 8) & 0x7f); pi->nphy_cal_orig_pwr_idx[1] = - (u8) ((read_phy_reg(pi, 0x1ee) >> 8) & 0x7f); + (u8) ((read_phy_reg(pi, 0x1ee) >> 8) & 0x7f); if (pi->nphy_txpwrctrl != PHY_TPC_HW_OFF) { wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, @@ -23803,7 +25620,8 @@ void wlc_phy_cal_perical_nphy_run(struct brcms_phy *pi, u8 caltype) target_gain = pi->nphy_cal_target_gain; } if (0 == - wlc_phy_cal_txiqlo_nphy(pi, target_gain, fullcal, mphase)) { + wlc_phy_cal_txiqlo_nphy(pi, target_gain, fullcal, + mphase)) { if (PHY_IPA(pi)) wlc_phy_a4(pi, true); @@ -23815,13 +25633,9 @@ void wlc_phy_cal_perical_nphy_run(struct brcms_phy *pi, u8 caltype) wlc_phyreg_enter((struct brcms_phy_pub *) pi); if (0 == wlc_phy_cal_rxiq_nphy(pi, target_gain, - (pi-> - first_cal_after_assoc - || (pi-> - cal_type_override - == - PHY_PERICAL_FULL)) - ? 2 : 0, false)) { + (pi->first_cal_after_assoc || + (pi->cal_type_override == + PHY_PERICAL_FULL)) ? 2 : 0, false)) { wlc_phy_savecal_nphy(pi); wlc_phy_txpwrctrl_coeff_setup_nphy(pi); @@ -23829,9 +25643,8 @@ void wlc_phy_cal_perical_nphy_run(struct brcms_phy *pi, u8 caltype) pi->nphy_perical_last = pi->sh->now; } } - if (caltype != PHY_PERICAL_AUTO) { + if (caltype != PHY_PERICAL_AUTO) wlc_phy_rssi_cal_nphy(pi); - } if (pi->first_cal_after_assoc || (pi->cal_type_override == PHY_PERICAL_FULL)) { @@ -23840,18 +25653,17 @@ void wlc_phy_cal_perical_nphy_run(struct brcms_phy *pi, u8 caltype) wlc_phy_txpwrctrl_pwr_setup_nphy(pi); } - if (NREV_GE(pi->pubpi.phy_rev, 3)) { + if (NREV_GE(pi->pubpi.phy_rev, 3)) wlc_phy_radio205x_vcocal_nphy(pi); - } } else { switch (pi->mphase_cal_phase_id) { case MPHASE_CAL_STATE_INIT: pi->nphy_perical_last = pi->sh->now; pi->nphy_txiqlocal_chanspec = pi->radio_chanspec; - if (NREV_GE(pi->pubpi.phy_rev, 3)) { + if (NREV_GE(pi->pubpi.phy_rev, 3)) wlc_phy_precal_txgain_nphy(pi); - } + pi->nphy_cal_target_gain = wlc_phy_get_tx_gain_nphy(pi); pi->mphase_cal_phase_id++; break; @@ -23866,8 +25678,8 @@ void wlc_phy_cal_perical_nphy_run(struct brcms_phy *pi, u8 caltype) pi->nphy_rxcal_active = true; if (wlc_phy_cal_txiqlo_nphy - (pi, pi->nphy_cal_target_gain, fullcal, - true) != 0) { + (pi, pi->nphy_cal_target_gain, fullcal, + true) != 0) { wlc_phy_cal_perical_mphase_reset(pi); break; @@ -23875,20 +25687,19 @@ void wlc_phy_cal_perical_nphy_run(struct brcms_phy *pi, u8 caltype) if (NREV_LE(pi->pubpi.phy_rev, 2) && (pi->mphase_cal_phase_id == - MPHASE_CAL_STATE_TXPHASE4)) { + MPHASE_CAL_STATE_TXPHASE4)) pi->mphase_cal_phase_id += 2; - } else { + else pi->mphase_cal_phase_id++; - } break; case MPHASE_CAL_STATE_PAPDCAL: if ((pi->radar_percal_mask & 0x2) != 0) pi->nphy_rxcal_active = true; - if (PHY_IPA(pi)) { + if (PHY_IPA(pi)) wlc_phy_a4(pi, true); - } + pi->mphase_cal_phase_id++; break; @@ -23899,9 +25710,8 @@ void wlc_phy_cal_perical_nphy_run(struct brcms_phy *pi, u8 caltype) (pi->first_cal_after_assoc || (pi->cal_type_override == PHY_PERICAL_FULL)) ? 2 : 0, - false) == 0) { + false) == 0) wlc_phy_savecal_nphy(pi); - } pi->mphase_cal_phase_id++; break; @@ -23912,16 +25722,15 @@ void wlc_phy_cal_perical_nphy_run(struct brcms_phy *pi, u8 caltype) wlc_phy_txpwrctrl_coeff_setup_nphy(pi); wlc_phy_rssi_cal_nphy(pi); - if (NREV_GE(pi->pubpi.phy_rev, 3)) { + if (NREV_GE(pi->pubpi.phy_rev, 3)) wlc_phy_radio205x_vcocal_nphy(pi); - } + restore_tx_gain = true; - if (pi->first_cal_after_assoc) { + if (pi->first_cal_after_assoc) pi->mphase_cal_phase_id++; - } else { + else wlc_phy_cal_perical_mphase_reset(pi); - } break; @@ -23962,15 +25771,15 @@ void wlc_phy_cal_perical_nphy_run(struct brcms_phy *pi, u8 caltype) } else { wlc_phy_txpwr_index_nphy(pi, (1 << 0), (s8) (pi-> - nphy_txpwrindex - [0]. - index_internal), + nphy_txpwrindex + [0]. + index_internal), false); wlc_phy_txpwr_index_nphy(pi, (1 << 1), (s8) (pi-> - nphy_txpwrindex - [1]. - index_internal), + nphy_txpwrindex + [1]. + index_internal), false); } } @@ -24007,35 +25816,35 @@ wlc_phy_cal_txiqlo_nphy(struct brcms_phy *pi, struct nphy_txgains target_gain, u16 tbl_tx_iqlo_cal_loft_ladder_20[] = { 0x0300, 0x0500, 0x0700, 0x0900, 0x0d00, 0x1100, 0x1900, 0x1901, - 0x1902, + 0x1902, 0x1903, 0x1904, 0x1905, 0x1906, 0x1907, 0x2407, 0x3207, 0x4607, - 0x6407 + 0x6407 }; u16 tbl_tx_iqlo_cal_iqimb_ladder_20[] = { 0x0200, 0x0300, 0x0600, 0x0900, 0x0d00, 0x1100, 0x1900, 0x2400, - 0x3200, + 0x3200, 0x4600, 0x6400, 0x6401, 0x6402, 0x6403, 0x6404, 0x6405, 0x6406, - 0x6407 + 0x6407 }; u16 tbl_tx_iqlo_cal_loft_ladder_40[] = { 0x0200, 0x0300, 0x0400, 0x0700, 0x0900, 0x0c00, 0x1200, 0x1201, - 0x1202, + 0x1202, 0x1203, 0x1204, 0x1205, 0x1206, 0x1207, 0x1907, 0x2307, 0x3207, - 0x4707 + 0x4707 }; u16 tbl_tx_iqlo_cal_iqimb_ladder_40[] = { 0x0100, 0x0200, 0x0400, 0x0700, 0x0900, 0x0c00, 0x1200, 0x1900, - 0x2300, + 0x2300, 0x3200, 0x4700, 0x4701, 0x4702, 0x4703, 0x4704, 0x4705, 0x4706, - 0x4707 + 0x4707 }; u16 tbl_tx_iqlo_cal_startcoefs[] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000 + 0x0000 }; u16 tbl_tx_iqlo_cal_cmds_fullcal[] = { @@ -24071,11 +25880,10 @@ wlc_phy_cal_txiqlo_nphy(struct brcms_phy *pi, struct nphy_txgains target_gain, pi->phyhang_avoid = false; } - if (CHSPEC_IS40(pi->radio_chanspec)) { + if (CHSPEC_IS40(pi->radio_chanspec)) phy_bw = 40; - } else { + else phy_bw = 20; - } wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, gain_save); @@ -24117,11 +25925,10 @@ wlc_phy_cal_txiqlo_nphy(struct brcms_phy *pi, struct nphy_txgains target_gain, 16, tbl_ptr); } - if (NREV_GE(pi->pubpi.phy_rev, 7)) { + if (NREV_GE(pi->pubpi.phy_rev, 7)) write_phy_reg(pi, 0xc2, 0x8ad9); - } else { + else write_phy_reg(pi, 0xc2, 0x8aa9); - } max_val = 250; tone_freq = (phy_bw == 20) ? 2500 : 5000; @@ -24131,7 +25938,8 @@ wlc_phy_cal_txiqlo_nphy(struct brcms_phy *pi, struct nphy_txgains target_gain, bcmerror = 0; } else { bcmerror = - wlc_phy_tx_tone_nphy(pi, tone_freq, max_val, 1, 0, false); + wlc_phy_tx_tone_nphy(pi, tone_freq, max_val, 1, 0, + false); } if (bcmerror == 0) { @@ -24139,19 +25947,15 @@ wlc_phy_cal_txiqlo_nphy(struct brcms_phy *pi, struct nphy_txgains target_gain, if (pi->mphase_cal_phase_id > MPHASE_CAL_STATE_TXPHASE0) { tbl_ptr = pi->mphase_txcal_bestcoeffs; tbl_len = ARRAY_SIZE(pi->mphase_txcal_bestcoeffs); - if (NREV_LT(pi->pubpi.phy_rev, 3)) { - + if (NREV_LT(pi->pubpi.phy_rev, 3)) tbl_len -= 2; - } } else { if ((!fullcal) && (pi->nphy_txiqlocal_coeffsvalid)) { tbl_ptr = pi->nphy_txiqlocal_bestc; tbl_len = ARRAY_SIZE(pi->nphy_txiqlocal_bestc); - if (NREV_LT(pi->pubpi.phy_rev, 3)) { - + if (NREV_LT(pi->pubpi.phy_rev, 3)) tbl_len -= 2; - } } else { fullcal = true; @@ -24159,14 +25963,12 @@ wlc_phy_cal_txiqlo_nphy(struct brcms_phy *pi, struct nphy_txgains target_gain, if (NREV_GE(pi->pubpi.phy_rev, 3)) { tbl_ptr = tbl_tx_iqlo_cal_startcoefs_nphyrev3; - tbl_len = - ARRAY_SIZE - (tbl_tx_iqlo_cal_startcoefs_nphyrev3); + tbl_len = ARRAY_SIZE( + tbl_tx_iqlo_cal_startcoefs_nphyrev3); } else { tbl_ptr = tbl_tx_iqlo_cal_startcoefs; - tbl_len = - ARRAY_SIZE - (tbl_tx_iqlo_cal_startcoefs); + tbl_len = ARRAY_SIZE( + tbl_tx_iqlo_cal_startcoefs); } } } @@ -24175,21 +25977,22 @@ wlc_phy_cal_txiqlo_nphy(struct brcms_phy *pi, struct nphy_txgains target_gain, if (fullcal) { max_cal_cmds = (NREV_GE(pi->pubpi.phy_rev, 3)) ? - ARRAY_SIZE(tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3) : - ARRAY_SIZE(tbl_tx_iqlo_cal_cmds_fullcal); + ARRAY_SIZE( + tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3) : + ARRAY_SIZE(tbl_tx_iqlo_cal_cmds_fullcal); } else { max_cal_cmds = (NREV_GE(pi->pubpi.phy_rev, 3)) ? - ARRAY_SIZE(tbl_tx_iqlo_cal_cmds_recal_nphyrev3) : - ARRAY_SIZE(tbl_tx_iqlo_cal_cmds_recal); + ARRAY_SIZE( + tbl_tx_iqlo_cal_cmds_recal_nphyrev3) : + ARRAY_SIZE(tbl_tx_iqlo_cal_cmds_recal); } if (mphase) { cal_cnt = pi->mphase_txcal_cmdidx; - if ((cal_cnt + pi->mphase_txcal_numcmds) < max_cal_cmds) { + if ((cal_cnt + pi->mphase_txcal_numcmds) < max_cal_cmds) num_cals = cal_cnt + pi->mphase_txcal_numcmds; - } else { + else num_cals = max_cal_cmds; - } } else { cal_cnt = 0; num_cals = max_cal_cmds; @@ -24199,13 +26002,14 @@ wlc_phy_cal_txiqlo_nphy(struct brcms_phy *pi, struct nphy_txgains target_gain, if (fullcal) { cal_cmd = (NREV_GE(pi->pubpi.phy_rev, 3)) ? - tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3 - [cal_cnt] : - tbl_tx_iqlo_cal_cmds_fullcal[cal_cnt]; + tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3 + [cal_cnt] : + tbl_tx_iqlo_cal_cmds_fullcal[cal_cnt]; } else { cal_cmd = (NREV_GE(pi->pubpi.phy_rev, 3)) ? - tbl_tx_iqlo_cal_cmds_recal_nphyrev3[cal_cnt] - : tbl_tx_iqlo_cal_cmds_recal[cal_cnt]; + tbl_tx_iqlo_cal_cmds_recal_nphyrev3[ + cal_cnt] + : tbl_tx_iqlo_cal_cmds_recal[cal_cnt]; } core_no = ((cal_cmd & 0x3000) >> 12); @@ -24216,15 +26020,16 @@ wlc_phy_cal_txiqlo_nphy(struct brcms_phy *pi, struct nphy_txgains target_gain, PHY_IPA(pi) && (CHSPEC_IS2G(pi->radio_chanspec)))) { if (!ladder_updated[core_no]) { - wlc_phy_update_txcal_ladder_nphy(pi, - core_no); + wlc_phy_update_txcal_ladder_nphy( + pi, + core_no); ladder_updated[core_no] = true; } } val = - (cal_params[core_no]. - ncorr[cal_type] << 8) | NPHY_N_GCTL; + (cal_params[core_no]. + ncorr[cal_type] << 8) | NPHY_N_GCTL; write_phy_reg(pi, 0xc1, val); if ((cal_type == 1) || (cal_type == 3) @@ -24272,8 +26077,8 @@ wlc_phy_cal_txiqlo_nphy(struct brcms_phy *pi, struct nphy_txgains target_gain, } mphase_cal_lastphase = - (NREV_LE(pi->pubpi.phy_rev, 2)) ? - MPHASE_CAL_STATE_TXPHASE4 : MPHASE_CAL_STATE_TXPHASE5; + (NREV_LE(pi->pubpi.phy_rev, 2)) ? + MPHASE_CAL_STATE_TXPHASE4 : MPHASE_CAL_STATE_TXPHASE5; if (!mphase || (pi->mphase_cal_phase_id == mphase_cal_lastphase)) { @@ -24303,10 +26108,9 @@ wlc_phy_cal_txiqlo_nphy(struct brcms_phy *pi, struct nphy_txgains target_gain, 16, tbl_buf); tbl_len = ARRAY_SIZE(pi->nphy_txiqlocal_bestc); - if (NREV_LT(pi->pubpi.phy_rev, 3)) { - + if (NREV_LT(pi->pubpi.phy_rev, 3)) tbl_len -= 2; - } + wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, tbl_len, 96, 16, pi->nphy_txiqlocal_bestc); @@ -24315,10 +26119,9 @@ wlc_phy_cal_txiqlo_nphy(struct brcms_phy *pi, struct nphy_txgains target_gain, pi->nphy_txiqlocal_chanspec = pi->radio_chanspec; } else { tbl_len = ARRAY_SIZE(pi->mphase_txcal_bestcoeffs); - if (NREV_LT(pi->pubpi.phy_rev, 3)) { - + if (NREV_LT(pi->pubpi.phy_rev, 3)) tbl_len -= 2; - } + wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_IQLOCAL, tbl_len, 96, 16, pi->mphase_txcal_bestcoeffs); @@ -24343,9 +26146,8 @@ wlc_phy_cal_txiqlo_nphy(struct brcms_phy *pi, struct nphy_txgains target_gain, wlc_phy_tx_iq_war_nphy(pi); } - if (NREV_GE(pi->pubpi.phy_rev, 4)) { + if (NREV_GE(pi->pubpi.phy_rev, 4)) pi->phyhang_avoid = phyhang_avoid_state; - } wlc_phy_stay_in_carriersearch_nphy(pi, false); @@ -24387,18 +26189,6 @@ static void wlc_phy_reapply_txcal_coeffs_nphy(struct brcms_phy *pi) } } -static void wlc_phy_tx_iq_war_nphy(struct brcms_phy *pi) -{ - struct nphy_iq_comp tx_comp; - - wlc_phy_table_read_nphy(pi, 15, 4, 0x50, 16, (void *)&tx_comp); - - wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ, tx_comp.a0); - wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ + 2, tx_comp.b0); - wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ + 4, tx_comp.a1); - wlapi_bmac_write_shm(pi->sh->physhim, M_20IN40_IQ + 6, tx_comp.b1); -} - void wlc_phy_rx_iq_coeffs_nphy(struct brcms_phy *pi, u8 write, struct nphy_iq_comp *pcomp) @@ -24438,14 +26228,17 @@ wlc_phy_rx_iq_est_nphy(struct brcms_phy *pi, struct phy_iq_est *est, if ((read_phy_reg(pi, 0x129) & NPHY_IqestCmd_iqstart) == 0) { for (core = 0; core < pi->pubpi.phy_corenum; core++) { est[core].i_pwr = - (read_phy_reg(pi, NPHY_IqestipwrAccHi(core)) << 16) - | read_phy_reg(pi, NPHY_IqestipwrAccLo(core)); + (read_phy_reg(pi, + NPHY_IqestipwrAccHi(core)) << 16) + | read_phy_reg(pi, NPHY_IqestipwrAccLo(core)); est[core].q_pwr = - (read_phy_reg(pi, NPHY_IqestqpwrAccHi(core)) << 16) - | read_phy_reg(pi, NPHY_IqestqpwrAccLo(core)); + (read_phy_reg(pi, + NPHY_IqestqpwrAccHi(core)) << 16) + | read_phy_reg(pi, NPHY_IqestqpwrAccLo(core)); est[core].iq_prod = - (read_phy_reg(pi, NPHY_IqestIqAccHi(core)) << 16) | - read_phy_reg(pi, NPHY_IqestIqAccLo(core)); + (read_phy_reg(pi, + NPHY_IqestIqAccHi(core)) << 16) | + read_phy_reg(pi, NPHY_IqestIqAccLo(core)); } } } @@ -24470,7 +26263,7 @@ static void wlc_phy_calc_rx_iq_comp_nphy(struct brcms_phy *pi, u8 core_mask) new_comp.a0 = new_comp.b0 = new_comp.a1 = new_comp.b1 = 0x0; wlc_phy_rx_iq_coeffs_nphy(pi, 1, &new_comp); - cal_try: +cal_try: wlc_phy_rx_iq_est_nphy(pi, est, 0x4000, 32, 0); new_comp = old_comp; @@ -24561,7 +26354,7 @@ static void wlc_phy_calc_rx_iq_comp_nphy(struct brcms_phy *pi, u8 core_mask) if (bcmerror != 0) { printk(KERN_DEBUG "%s: Failed, cnt = %d\n", __func__, - cal_retry); + cal_retry); if (cal_retry < CAL_RETRY_CNT) { cal_retry++; @@ -24584,121 +26377,125 @@ static void wlc_phy_rxcal_radio_setup_nphy(struct brcms_phy *pi, u8 rx_core) if (rx_core == PHY_CORE_0) { if (CHSPEC_IS5G(pi->radio_chanspec)) { pi->tx_rx_cal_radio_saveregs[0] = - read_radio_reg(pi, - RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP); + read_radio_reg(pi, + RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP); pi->tx_rx_cal_radio_saveregs[1] = - read_radio_reg(pi, - RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN); + read_radio_reg(pi, + RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN); write_radio_reg(pi, - RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP, - 0x3); + RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP, + 0x3); write_radio_reg(pi, - RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN, - 0xaf); + RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN, + 0xaf); } else { pi->tx_rx_cal_radio_saveregs[0] = - read_radio_reg(pi, - RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP); + read_radio_reg(pi, + RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP); pi->tx_rx_cal_radio_saveregs[1] = - read_radio_reg(pi, - RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN); - - write_radio_reg(pi, - RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP, - 0x3); - write_radio_reg(pi, - RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN, - 0x7f); + read_radio_reg(pi, + RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN); + + write_radio_reg( + pi, + RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP, + 0x3); + write_radio_reg( + pi, + RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN, + 0x7f); } } else { if (CHSPEC_IS5G(pi->radio_chanspec)) { pi->tx_rx_cal_radio_saveregs[0] = - read_radio_reg(pi, - RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP); + read_radio_reg(pi, + RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP); pi->tx_rx_cal_radio_saveregs[1] = - read_radio_reg(pi, - RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN); - - write_radio_reg(pi, - RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP, - 0x3); - write_radio_reg(pi, - RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN, - 0xaf); + read_radio_reg(pi, + RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN); + + write_radio_reg( + pi, + RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP, + 0x3); + write_radio_reg( + pi, + RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN, + 0xaf); } else { pi->tx_rx_cal_radio_saveregs[0] = - read_radio_reg(pi, - RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP); + read_radio_reg(pi, + RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP); pi->tx_rx_cal_radio_saveregs[1] = - read_radio_reg(pi, - RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN); + read_radio_reg(pi, + RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN); write_radio_reg(pi, - RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP, - 0x3); + RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP, + 0x3); write_radio_reg(pi, - RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN, - 0x7f); + RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN, + 0x7f); } } } else { if (rx_core == PHY_CORE_0) { pi->tx_rx_cal_radio_saveregs[0] = - read_radio_reg(pi, - RADIO_2056_TX_RXIQCAL_TXMUX | - RADIO_2056_TX1); + read_radio_reg(pi, + RADIO_2056_TX_RXIQCAL_TXMUX | + RADIO_2056_TX1); pi->tx_rx_cal_radio_saveregs[1] = - read_radio_reg(pi, - RADIO_2056_RX_RXIQCAL_RXMUX | - RADIO_2056_RX0); + read_radio_reg(pi, + RADIO_2056_RX_RXIQCAL_RXMUX | + RADIO_2056_RX0); if (pi->pubpi.radiorev >= 5) { pi->tx_rx_cal_radio_saveregs[2] = - read_radio_reg(pi, - RADIO_2056_RX_RXSPARE2 | - RADIO_2056_RX0); + read_radio_reg(pi, + RADIO_2056_RX_RXSPARE2 | + RADIO_2056_RX0); pi->tx_rx_cal_radio_saveregs[3] = - read_radio_reg(pi, - RADIO_2056_TX_TXSPARE2 | - RADIO_2056_TX1); + read_radio_reg(pi, + RADIO_2056_TX_TXSPARE2 | + RADIO_2056_TX1); } if (CHSPEC_IS5G(pi->radio_chanspec)) { if (pi->pubpi.radiorev >= 5) { pi->tx_rx_cal_radio_saveregs[4] = - read_radio_reg(pi, - RADIO_2056_RX_LNAA_MASTER - | RADIO_2056_RX0); + read_radio_reg(pi, + RADIO_2056_RX_LNAA_MASTER + | RADIO_2056_RX0); - write_radio_reg(pi, - RADIO_2056_RX_LNAA_MASTER - | RADIO_2056_RX0, 0x40); + write_radio_reg( + pi, + RADIO_2056_RX_LNAA_MASTER + | RADIO_2056_RX0, 0x40); write_radio_reg(pi, - RADIO_2056_TX_TXSPARE2 | - RADIO_2056_TX1, bias_a); + RADIO_2056_TX_TXSPARE2 | + RADIO_2056_TX1, bias_a); write_radio_reg(pi, - RADIO_2056_RX_RXSPARE2 | - RADIO_2056_RX0, bias_a); + RADIO_2056_RX_RXSPARE2 | + RADIO_2056_RX0, bias_a); } else { pi->tx_rx_cal_radio_saveregs[4] = - read_radio_reg(pi, - RADIO_2056_RX_LNAA_TUNE - | RADIO_2056_RX0); + read_radio_reg(pi, + RADIO_2056_RX_LNAA_TUNE + | RADIO_2056_RX0); offtune_val = - (pi-> - tx_rx_cal_radio_saveregs[2] & 0xF0) - >> 8; + (pi->tx_rx_cal_radio_saveregs + [2] & 0xF0) >> 8; offtune_val = - (offtune_val <= 0x7) ? 0xF : 0; + (offtune_val <= 0x7) ? 0xF : 0; mod_radio_reg(pi, RADIO_2056_RX_LNAA_TUNE | @@ -24715,34 +26512,41 @@ static void wlc_phy_rxcal_radio_setup_nphy(struct brcms_phy *pi, u8 rx_core) } else { if (pi->pubpi.radiorev >= 5) { pi->tx_rx_cal_radio_saveregs[4] = - read_radio_reg(pi, - RADIO_2056_RX_LNAG_MASTER - | RADIO_2056_RX0); - - write_radio_reg(pi, - RADIO_2056_RX_LNAG_MASTER - | RADIO_2056_RX0, 0x40); - - write_radio_reg(pi, - RADIO_2056_TX_TXSPARE2 | - RADIO_2056_TX1, bias_g); - - write_radio_reg(pi, - RADIO_2056_RX_RXSPARE2 | - RADIO_2056_RX0, bias_g); + read_radio_reg( + pi, + RADIO_2056_RX_LNAG_MASTER + | RADIO_2056_RX0); + + write_radio_reg( + pi, + RADIO_2056_RX_LNAG_MASTER + | RADIO_2056_RX0, 0x40); + + write_radio_reg( + pi, + RADIO_2056_TX_TXSPARE2 + | + RADIO_2056_TX1, bias_g); + + write_radio_reg( + pi, + RADIO_2056_RX_RXSPARE2 + | + RADIO_2056_RX0, bias_g); } else { pi->tx_rx_cal_radio_saveregs[4] = - read_radio_reg(pi, - RADIO_2056_RX_LNAG_TUNE - | RADIO_2056_RX0); + read_radio_reg( + pi, + RADIO_2056_RX_LNAG_TUNE + | RADIO_2056_RX0); offtune_val = - (pi-> - tx_rx_cal_radio_saveregs[2] & 0xF0) - >> 8; + (pi-> + tx_rx_cal_radio_saveregs[2] & + 0xF0) >> 8; offtune_val = - (offtune_val <= 0x7) ? 0xF : 0; + (offtune_val <= 0x7) ? 0xF : 0; mod_radio_reg(pi, RADIO_2056_RX_LNAG_TUNE | @@ -24760,56 +26564,63 @@ static void wlc_phy_rxcal_radio_setup_nphy(struct brcms_phy *pi, u8 rx_core) } else { pi->tx_rx_cal_radio_saveregs[0] = - read_radio_reg(pi, - RADIO_2056_TX_RXIQCAL_TXMUX | - RADIO_2056_TX0); + read_radio_reg(pi, + RADIO_2056_TX_RXIQCAL_TXMUX | + RADIO_2056_TX0); pi->tx_rx_cal_radio_saveregs[1] = - read_radio_reg(pi, - RADIO_2056_RX_RXIQCAL_RXMUX | - RADIO_2056_RX1); + read_radio_reg(pi, + RADIO_2056_RX_RXIQCAL_RXMUX | + RADIO_2056_RX1); if (pi->pubpi.radiorev >= 5) { pi->tx_rx_cal_radio_saveregs[2] = - read_radio_reg(pi, - RADIO_2056_RX_RXSPARE2 | - RADIO_2056_RX1); + read_radio_reg(pi, + RADIO_2056_RX_RXSPARE2 | + RADIO_2056_RX1); pi->tx_rx_cal_radio_saveregs[3] = - read_radio_reg(pi, - RADIO_2056_TX_TXSPARE2 | - RADIO_2056_TX0); + read_radio_reg(pi, + RADIO_2056_TX_TXSPARE2 | + RADIO_2056_TX0); } if (CHSPEC_IS5G(pi->radio_chanspec)) { if (pi->pubpi.radiorev >= 5) { pi->tx_rx_cal_radio_saveregs[4] = - read_radio_reg(pi, - RADIO_2056_RX_LNAA_MASTER - | RADIO_2056_RX1); - - write_radio_reg(pi, - RADIO_2056_RX_LNAA_MASTER - | RADIO_2056_RX1, 0x40); - - write_radio_reg(pi, - RADIO_2056_TX_TXSPARE2 | - RADIO_2056_TX0, bias_a); - - write_radio_reg(pi, - RADIO_2056_RX_RXSPARE2 | - RADIO_2056_RX1, bias_a); + read_radio_reg( + pi, + RADIO_2056_RX_LNAA_MASTER + | RADIO_2056_RX1); + + write_radio_reg( + pi, + RADIO_2056_RX_LNAA_MASTER | + RADIO_2056_RX1, 0x40); + + write_radio_reg( + pi, + RADIO_2056_TX_TXSPARE2 + | + RADIO_2056_TX0, bias_a); + + write_radio_reg( + pi, + RADIO_2056_RX_RXSPARE2 + | + RADIO_2056_RX1, bias_a); } else { pi->tx_rx_cal_radio_saveregs[4] = - read_radio_reg(pi, - RADIO_2056_RX_LNAA_TUNE - | RADIO_2056_RX1); + read_radio_reg( + pi, + RADIO_2056_RX_LNAA_TUNE + | RADIO_2056_RX1); offtune_val = - (pi-> - tx_rx_cal_radio_saveregs[2] & 0xF0) - >> 8; + (pi-> + tx_rx_cal_radio_saveregs[2] & + 0xF0) >> 8; offtune_val = - (offtune_val <= 0x7) ? 0xF : 0; + (offtune_val <= 0x7) ? 0xF : 0; mod_radio_reg(pi, RADIO_2056_RX_LNAA_TUNE | @@ -24826,33 +26637,40 @@ static void wlc_phy_rxcal_radio_setup_nphy(struct brcms_phy *pi, u8 rx_core) } else { if (pi->pubpi.radiorev >= 5) { pi->tx_rx_cal_radio_saveregs[4] = - read_radio_reg(pi, - RADIO_2056_RX_LNAG_MASTER - | RADIO_2056_RX1); - - write_radio_reg(pi, - RADIO_2056_RX_LNAG_MASTER - | RADIO_2056_RX1, 0x40); - - write_radio_reg(pi, - RADIO_2056_TX_TXSPARE2 | - RADIO_2056_TX0, bias_g); - - write_radio_reg(pi, - RADIO_2056_RX_RXSPARE2 | - RADIO_2056_RX1, bias_g); + read_radio_reg( + pi, + RADIO_2056_RX_LNAG_MASTER + | RADIO_2056_RX1); + + write_radio_reg( + pi, + RADIO_2056_RX_LNAG_MASTER + | RADIO_2056_RX1, 0x40); + + write_radio_reg( + pi, + RADIO_2056_TX_TXSPARE2 + | + RADIO_2056_TX0, bias_g); + + write_radio_reg( + pi, + RADIO_2056_RX_RXSPARE2 + | + RADIO_2056_RX1, bias_g); } else { pi->tx_rx_cal_radio_saveregs[4] = - read_radio_reg(pi, - RADIO_2056_RX_LNAG_TUNE - | RADIO_2056_RX1); + read_radio_reg( + pi, + RADIO_2056_RX_LNAG_TUNE + | RADIO_2056_RX1); offtune_val = - (pi-> - tx_rx_cal_radio_saveregs[2] & 0xF0) - >> 8; + (pi-> + tx_rx_cal_radio_saveregs[2] & + 0xF0) >> 8; offtune_val = - (offtune_val <= 0x7) ? 0xF : 0; + (offtune_val <= 0x7) ? 0xF : 0; mod_radio_reg(pi, RADIO_2056_RX_LNAG_TUNE | @@ -24876,46 +26694,54 @@ static void wlc_phy_rxcal_radio_cleanup_nphy(struct brcms_phy *pi, u8 rx_core) if (NREV_GE(pi->pubpi.phy_rev, 7)) { if (rx_core == PHY_CORE_0) { if (CHSPEC_IS5G(pi->radio_chanspec)) { - write_radio_reg(pi, - RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP, - pi-> - tx_rx_cal_radio_saveregs[0]); - write_radio_reg(pi, - RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN, - pi-> - tx_rx_cal_radio_saveregs[1]); + write_radio_reg( + pi, + RADIO_2057_TX0_TXRXCOUPLE_5G_PWRUP, + pi-> + tx_rx_cal_radio_saveregs[0]); + write_radio_reg( + pi, + RADIO_2057_TX0_TXRXCOUPLE_5G_ATTEN, + pi-> + tx_rx_cal_radio_saveregs[1]); } else { - write_radio_reg(pi, - RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP, - pi-> - tx_rx_cal_radio_saveregs[0]); - write_radio_reg(pi, - RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN, - pi-> - tx_rx_cal_radio_saveregs[1]); + write_radio_reg( + pi, + RADIO_2057_TX0_TXRXCOUPLE_2G_PWRUP, + pi-> + tx_rx_cal_radio_saveregs[0]); + write_radio_reg( + pi, + RADIO_2057_TX0_TXRXCOUPLE_2G_ATTEN, + pi-> + tx_rx_cal_radio_saveregs[1]); } } else { if (CHSPEC_IS5G(pi->radio_chanspec)) { - write_radio_reg(pi, - RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP, - pi-> - tx_rx_cal_radio_saveregs[0]); - write_radio_reg(pi, - RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN, - pi-> - tx_rx_cal_radio_saveregs[1]); + write_radio_reg( + pi, + RADIO_2057_TX1_TXRXCOUPLE_5G_PWRUP, + pi-> + tx_rx_cal_radio_saveregs[0]); + write_radio_reg( + pi, + RADIO_2057_TX1_TXRXCOUPLE_5G_ATTEN, + pi-> + tx_rx_cal_radio_saveregs[1]); } else { - write_radio_reg(pi, - RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP, - pi-> - tx_rx_cal_radio_saveregs[0]); - write_radio_reg(pi, - RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN, - pi-> - tx_rx_cal_radio_saveregs[1]); + write_radio_reg( + pi, + RADIO_2057_TX1_TXRXCOUPLE_2G_PWRUP, + pi-> + tx_rx_cal_radio_saveregs[0]); + write_radio_reg( + pi, + RADIO_2057_TX1_TXRXCOUPLE_2G_ATTEN, + pi-> + tx_rx_cal_radio_saveregs[1]); } } @@ -24946,37 +26772,39 @@ static void wlc_phy_rxcal_radio_cleanup_nphy(struct brcms_phy *pi, u8 rx_core) } if (CHSPEC_IS5G(pi->radio_chanspec)) { - if (pi->pubpi.radiorev >= 5) { - write_radio_reg(pi, - RADIO_2056_RX_LNAA_MASTER - | RADIO_2056_RX0, - pi-> - tx_rx_cal_radio_saveregs - [4]); - } else { - write_radio_reg(pi, - RADIO_2056_RX_LNAA_TUNE - | RADIO_2056_RX0, - pi-> - tx_rx_cal_radio_saveregs - [4]); - } + if (pi->pubpi.radiorev >= 5) + write_radio_reg( + pi, + RADIO_2056_RX_LNAA_MASTER + | RADIO_2056_RX0, + pi-> + tx_rx_cal_radio_saveregs + [4]); + else + write_radio_reg( + pi, + RADIO_2056_RX_LNAA_TUNE + | RADIO_2056_RX0, + pi-> + tx_rx_cal_radio_saveregs + [4]); } else { - if (pi->pubpi.radiorev >= 5) { - write_radio_reg(pi, - RADIO_2056_RX_LNAG_MASTER - | RADIO_2056_RX0, - pi-> - tx_rx_cal_radio_saveregs - [4]); - } else { - write_radio_reg(pi, - RADIO_2056_RX_LNAG_TUNE - | RADIO_2056_RX0, - pi-> - tx_rx_cal_radio_saveregs - [4]); - } + if (pi->pubpi.radiorev >= 5) + write_radio_reg( + pi, + RADIO_2056_RX_LNAG_MASTER + | RADIO_2056_RX0, + pi-> + tx_rx_cal_radio_saveregs + [4]); + else + write_radio_reg( + pi, + RADIO_2056_RX_LNAG_TUNE + | RADIO_2056_RX0, + pi-> + tx_rx_cal_radio_saveregs + [4]); } } else { @@ -25005,37 +26833,39 @@ static void wlc_phy_rxcal_radio_cleanup_nphy(struct brcms_phy *pi, u8 rx_core) } if (CHSPEC_IS5G(pi->radio_chanspec)) { - if (pi->pubpi.radiorev >= 5) { - write_radio_reg(pi, - RADIO_2056_RX_LNAA_MASTER - | RADIO_2056_RX1, - pi-> - tx_rx_cal_radio_saveregs - [4]); - } else { - write_radio_reg(pi, - RADIO_2056_RX_LNAA_TUNE - | RADIO_2056_RX1, - pi-> - tx_rx_cal_radio_saveregs - [4]); - } + if (pi->pubpi.radiorev >= 5) + write_radio_reg( + pi, + RADIO_2056_RX_LNAA_MASTER + | RADIO_2056_RX1, + pi-> + tx_rx_cal_radio_saveregs + [4]); + else + write_radio_reg( + pi, + RADIO_2056_RX_LNAA_TUNE + | RADIO_2056_RX1, + pi-> + tx_rx_cal_radio_saveregs + [4]); } else { - if (pi->pubpi.radiorev >= 5) { - write_radio_reg(pi, - RADIO_2056_RX_LNAG_MASTER - | RADIO_2056_RX1, - pi-> - tx_rx_cal_radio_saveregs - [4]); - } else { - write_radio_reg(pi, - RADIO_2056_RX_LNAG_TUNE - | RADIO_2056_RX1, - pi-> - tx_rx_cal_radio_saveregs - [4]); - } + if (pi->pubpi.radiorev >= 5) + write_radio_reg( + pi, + RADIO_2056_RX_LNAG_MASTER + | RADIO_2056_RX1, + pi-> + tx_rx_cal_radio_saveregs + [4]); + else + write_radio_reg( + pi, + RADIO_2056_RX_LNAG_TUNE + | RADIO_2056_RX1, + pi-> + tx_rx_cal_radio_saveregs + [4]); } } } @@ -25046,18 +26876,16 @@ static void wlc_phy_rxcal_physetup_nphy(struct brcms_phy *pi, u8 rx_core) u8 tx_core; u16 rx_antval, tx_antval; - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - + if (NREV_GE(pi->pubpi.phy_rev, 7)) tx_core = rx_core; - } else { + else tx_core = (rx_core == PHY_CORE_0) ? 1 : 0; - } pi->tx_rx_cal_phy_saveregs[0] = read_phy_reg(pi, 0xa2); pi->tx_rx_cal_phy_saveregs[1] = - read_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0xa6 : 0xa7); + read_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0xa6 : 0xa7); pi->tx_rx_cal_phy_saveregs[2] = - read_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x8f : 0xa5); + read_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x8f : 0xa5); pi->tx_rx_cal_phy_saveregs[3] = read_phy_reg(pi, 0x91); pi->tx_rx_cal_phy_saveregs[4] = read_phy_reg(pi, 0x92); pi->tx_rx_cal_phy_saveregs[5] = read_phy_reg(pi, 0x7a); @@ -25122,17 +26950,19 @@ static void wlc_phy_rxcal_physetup_nphy(struct brcms_phy *pi, u8 rx_core) NPHY_REV7_RFCTRLOVERRIDE_ID2); wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 0, 0, 0, NPHY_REV7_RFCTRLOVERRIDE_ID1); - if (CHSPEC_IS40(pi->radio_chanspec)) { - wlc_phy_rfctrl_override_nphy_rev7(pi, - (0x1 << 7), - 2, 0, 0, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - } else { - wlc_phy_rfctrl_override_nphy_rev7(pi, - (0x1 << 7), - 0, 0, 0, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - } + if (CHSPEC_IS40(pi->radio_chanspec)) + wlc_phy_rfctrl_override_nphy_rev7( + pi, + (0x1 << 7), + 2, 0, 0, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + else + wlc_phy_rfctrl_override_nphy_rev7( + pi, + (0x1 << 7), + 0, 0, 0, + NPHY_REV7_RFCTRLOVERRIDE_ID1); + wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7), 0, 0, 0, NPHY_REV7_RFCTRLOVERRIDE_ID1); @@ -25203,8 +27033,8 @@ wlc_phy_rxcal_gainctrl_nphy_rev5(struct brcms_phy *pi, u8 rx_core, struct phy_iq_est est[PHY_CORE_MAX]; u8 tx_core; struct nphy_iq_comp save_comp, zero_comp; - u32 i_pwr, q_pwr, curr_pwr, optim_pwr = 0, prev_pwr = 0, thresh_pwr = - 10000; + u32 i_pwr, q_pwr, curr_pwr, optim_pwr = 0, prev_pwr = 0, + thresh_pwr = 10000; s16 desired_log2_pwr, actual_log2_pwr, delta_pwr; bool gainctrl_done = false; u8 mix_tia_gain = 3; @@ -25217,12 +27047,10 @@ wlc_phy_rxcal_gainctrl_nphy_rev5(struct brcms_phy *pi, u8 rx_core, s8 txpwrindex; u16 nphy_rxcal_txgain[2]; - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - + if (NREV_GE(pi->pubpi.phy_rev, 7)) tx_core = rx_core; - } else { + else tx_core = 1 - rx_core; - } num_samps = 1024; desired_log2_pwr = (cal_type == 0) ? 13 : 13; @@ -25232,45 +27060,42 @@ wlc_phy_rxcal_gainctrl_nphy_rev5(struct brcms_phy *pi, u8 rx_core, wlc_phy_rx_iq_coeffs_nphy(pi, 1, &zero_comp); if (CHSPEC_IS5G(pi->radio_chanspec)) { - if (NREV_GE(pi->pubpi.phy_rev, 7)) { + if (NREV_GE(pi->pubpi.phy_rev, 7)) mix_tia_gain = 3; - } else if (NREV_GE(pi->pubpi.phy_rev, 4)) { + else if (NREV_GE(pi->pubpi.phy_rev, 4)) mix_tia_gain = 4; - } else { + else mix_tia_gain = 6; - } - if (NREV_GE(pi->pubpi.phy_rev, 7)) { + if (NREV_GE(pi->pubpi.phy_rev, 7)) nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_5GHz_rev7; - } else { + else nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_5GHz; - } } else { - if (NREV_GE(pi->pubpi.phy_rev, 7)) { + if (NREV_GE(pi->pubpi.phy_rev, 7)) nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_2GHz_rev7; - } else { + else nphy_rxcal_gaintbl = nphy_ipa_rxcal_gaintbl_2GHz; - } } do { hpvga = (NREV_GE(pi->pubpi.phy_rev, 7)) ? - 0 : nphy_rxcal_gaintbl[curr_gaintbl_index].hpvga; + 0 : nphy_rxcal_gaintbl[curr_gaintbl_index].hpvga; lpf_biq1 = nphy_rxcal_gaintbl[curr_gaintbl_index].lpf_biq1; lpf_biq0 = nphy_rxcal_gaintbl[curr_gaintbl_index].lpf_biq0; lna2 = nphy_rxcal_gaintbl[curr_gaintbl_index].lna2; lna1 = nphy_rxcal_gaintbl[curr_gaintbl_index].lna1; txpwrindex = nphy_rxcal_gaintbl[curr_gaintbl_index].txpwrindex; - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - wlc_phy_rfctrl_override_1tomany_nphy(pi, - NPHY_REV7_RfctrlOverride_cmd_rxgain, - ((lpf_biq1 << 12) | - (lpf_biq0 << 8) | - (mix_tia_gain << - 4) | (lna2 << 2) - | lna1), 0x3, 0); - } else { + if (NREV_GE(pi->pubpi.phy_rev, 7)) + wlc_phy_rfctrl_override_1tomany_nphy( + pi, + NPHY_REV7_RfctrlOverride_cmd_rxgain, + ((lpf_biq1 << 12) | + (lpf_biq0 << 8) | + (mix_tia_gain << 4) | (lna2 << 2) + | lna1), 0x3, 0); + else wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), ((hpvga << 12) | (lpf_biq1 << 10) | @@ -25278,7 +27103,6 @@ wlc_phy_rxcal_gainctrl_nphy_rev5(struct brcms_phy *pi, u8 rx_core, (mix_tia_gain << 4) | (lna2 << 2) | lna1), 0x3, 0); - } pi->nphy_rxcal_pwr_idx[tx_core] = txpwrindex; @@ -25367,27 +27191,28 @@ wlc_phy_rxcal_gainctrl_nphy_rev5(struct brcms_phy *pi, u8 rx_core, if (NREV_GE(pi->pubpi.phy_rev, 7)) { fine_gain_idx = (int)lpf_biq1 + delta_pwr; - if (fine_gain_idx + (int)lpf_biq0 > 10) { + if (fine_gain_idx + (int)lpf_biq0 > 10) lpf_biq1 = 10 - lpf_biq0; - } else { + else lpf_biq1 = (u16) max(fine_gain_idx, 0); - } - wlc_phy_rfctrl_override_1tomany_nphy(pi, - NPHY_REV7_RfctrlOverride_cmd_rxgain, - ((lpf_biq1 << 12) | - (lpf_biq0 << 8) | - (mix_tia_gain << 4) | - (lna2 << 2) | lna1), 0x3, - 0); + + wlc_phy_rfctrl_override_1tomany_nphy( + pi, + NPHY_REV7_RfctrlOverride_cmd_rxgain, + ((lpf_biq1 << 12) | + (lpf_biq0 << 8) | + (mix_tia_gain << 4) | + (lna2 << 2) | lna1), 0x3, + 0); } else { hpvga = (u16) max(min(((int)hpvga) + delta_pwr, 10), 0); wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), - ((hpvga << 12) | (lpf_biq1 << 10) | - (lpf_biq0 << 8) | (mix_tia_gain << - 4) | (lna2 << - 2) | + ((hpvga << 12) | + (lpf_biq1 << 10) | + (lpf_biq0 << 8) | + (mix_tia_gain << 4) | + (lna2 << 2) | lna1), 0x3, 0); - } if (rxgain != NULL) { @@ -25444,9 +27269,8 @@ wlc_phy_rc_sweep_nphy(struct brcms_phy *pi, u8 core_idx, u8 loopback_type) u16 num_samps, log_num_samps = 10; struct phy_iq_est est[PHY_CORE_MAX]; - if (NREV_GE(pi->pubpi.phy_rev, 7)) { + if (NREV_GE(pi->pubpi.phy_rev, 7)) return 0; - } num_samps = (1 << log_num_samps); @@ -25465,20 +27289,21 @@ wlc_phy_rc_sweep_nphy(struct brcms_phy *pi, u8 core_idx, u8 loopback_type) if (core_idx == 0) { radio_addr_offset_rx = RADIO_2056_RX0; radio_addr_offset_tx = - (loopback_type == 0) ? RADIO_2056_TX0 : RADIO_2056_TX1; + (loopback_type == 0) ? RADIO_2056_TX0 : RADIO_2056_TX1; } else { radio_addr_offset_rx = RADIO_2056_RX1; radio_addr_offset_tx = - (loopback_type == 0) ? RADIO_2056_TX1 : RADIO_2056_TX0; + (loopback_type == 0) ? RADIO_2056_TX1 : RADIO_2056_TX0; } orig_txlpf_rccal_lpc_ovr_val = - read_radio_reg(pi, - (RADIO_2056_TX_TXLPF_RCCAL | radio_addr_offset_tx)); + read_radio_reg(pi, + (RADIO_2056_TX_TXLPF_RCCAL | + radio_addr_offset_tx)); orig_rxlpf_rccal_hpc_ovr_val = - read_radio_reg(pi, - (RADIO_2056_RX_RXLPF_RCCAL_HPC | - radio_addr_offset_rx)); + read_radio_reg(pi, + (RADIO_2056_RX_RXLPF_RCCAL_HPC | + radio_addr_offset_rx)); orig_dcBypass = ((read_phy_reg(pi, 0x48) >> 8) & 1); @@ -25549,17 +27374,18 @@ wlc_phy_rc_sweep_nphy(struct brcms_phy *pi, u8 core_idx, u8 loopback_type) wlc_phy_rx_iq_est_nphy(pi, est, num_samps, 32, 0); - if (core_idx == 0) { + if (core_idx == 0) ref_iq_vals = - max_t(u32, (est[0].i_pwr + - est[0].q_pwr) >> (log_num_samps + 1), - 1); - } else { + max_t(u32, (est[0].i_pwr + + est[0].q_pwr) >> + (log_num_samps + 1), + 1); + else ref_iq_vals = - max_t(u32, (est[1].i_pwr + - est[1].q_pwr) >> (log_num_samps + 1), - 1); - } + max_t(u32, (est[1].i_pwr + + est[1].q_pwr) >> + (log_num_samps + 1), + 1); wlc_phy_tx_tone_nphy(pi, target_bw, NPHY_RXCAL_TONEAMP, 0, 1, false); @@ -25568,20 +27394,19 @@ wlc_phy_rc_sweep_nphy(struct brcms_phy *pi, u8 core_idx, u8 loopback_type) wlc_phy_rx_iq_est_nphy(pi, est, num_samps, 32, 0); - if (core_idx == 0) { - target_iq_vals = - (est[0].i_pwr + est[0].q_pwr) >> (log_num_samps + - 1); - } else { + if (core_idx == 0) + target_iq_vals = (est[0].i_pwr + est[0].q_pwr) >> + (log_num_samps + 1); + else target_iq_vals = - (est[1].i_pwr + est[1].q_pwr) >> (log_num_samps + - 1); - } + (est[1].i_pwr + + est[1].q_pwr) >> (log_num_samps + 1); + pwr_ratio = (uint) ((target_iq_vals << 16) / ref_iq_vals); - if (rccal_stepsize == 0) { + if (rccal_stepsize == 0) rccal_stepsize--; - } else if (rccal_stepsize == 1) { + else if (rccal_stepsize == 1) { last_rccal_val = rccal_val; rccal_val += (pwr_ratio > target_pwr_ratio) ? 1 : -1; last_pwr_ratio = pwr_ratio; @@ -25594,21 +27419,20 @@ wlc_phy_rc_sweep_nphy(struct brcms_phy *pi, u8 core_idx, u8 loopback_type) if (rccal_stepsize == -1) { best_rccal_val = - (ABS((int)last_pwr_ratio - (int)target_pwr_ratio) < - ABS((int)pwr_ratio - - (int)target_pwr_ratio)) ? last_rccal_val : - rccal_val; + (ABS((int)last_pwr_ratio - + (int)target_pwr_ratio) < + ABS((int)pwr_ratio - + (int)target_pwr_ratio)) ? last_rccal_val : + rccal_val; if (CHSPEC_IS40(pi->radio_chanspec)) { if ((best_rccal_val > 140) - || (best_rccal_val < 135)) { + || (best_rccal_val < 135)) best_rccal_val = 138; - } } else { if ((best_rccal_val > 142) - || (best_rccal_val < 137)) { + || (best_rccal_val < 137)) best_rccal_val = 140; - } } write_radio_reg(pi, @@ -25649,7 +27473,7 @@ wlc_phy_rc_sweep_nphy(struct brcms_phy *pi, u8 core_idx, u8 loopback_type) return best_rccal_val - 0x80; } -#define WAIT_FOR_SCOPE 4000 +#define WAIT_FOR_SCOPE 4000 static int wlc_phy_cal_rxiq_nphy_rev3(struct brcms_phy *pi, struct nphy_txgains target_gain, u8 cal_type, bool debug) @@ -25687,12 +27511,12 @@ static int wlc_phy_cal_rxiq_nphy_rev3(struct brcms_phy *pi, wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, cal_gain); rxcore_state = wlc_phy_rxcore_getstate_nphy( - (struct brcms_phy_pub *) pi); + (struct brcms_phy_pub *) pi); for (rx_core = 0; rx_core < pi->pubpi.phy_corenum; rx_core++) { skip_rxiqcal = - ((rxcore_state & (1 << rx_core)) == 0) ? true : false; + ((rxcore_state & (1 << rx_core)) == 0) ? true : false; wlc_phy_rxcal_physetup_nphy(pi, rx_core); @@ -25703,7 +27527,8 @@ static int wlc_phy_cal_rxiq_nphy_rev3(struct brcms_phy *pi, wlc_phy_rxcal_gainctrl_nphy(pi, rx_core, NULL, 0); wlc_phy_tx_tone_nphy(pi, - (CHSPEC_IS40(pi->radio_chanspec)) ? + (CHSPEC_IS40( + pi->radio_chanspec)) ? NPHY_RXCAL_TONEFREQ_40MHz : NPHY_RXCAL_TONEFREQ_20MHz, NPHY_RXCAL_TONEAMP, 0, cal_type, @@ -25721,23 +27546,21 @@ static int wlc_phy_cal_rxiq_nphy_rev3(struct brcms_phy *pi, if (rx_core == PHY_CORE_1) { - if (rxcore_state == 1) { + if (rxcore_state == 1) wlc_phy_rxcore_setstate_nphy( (struct brcms_phy_pub *) pi, 3); - } wlc_phy_rxcal_gainctrl_nphy(pi, rx_core, NULL, 1); best_rccal[rx_core] = - wlc_phy_rc_sweep_nphy(pi, rx_core, 1); + wlc_phy_rc_sweep_nphy(pi, rx_core, 1); pi->nphy_rccal_value = best_rccal[rx_core]; - if (rxcore_state == 1) { + if (rxcore_state == 1) wlc_phy_rxcore_setstate_nphy( (struct brcms_phy_pub *) pi, rxcore_state); - } } } @@ -25756,7 +27579,7 @@ static int wlc_phy_cal_rxiq_nphy_rev3(struct brcms_phy *pi, for (rx_core = 0; rx_core < pi->pubpi.phy_corenum; rx_core++) { rxlpf_rccal_hpc = - (((int)best_rccal[rx_core] - 12) >> 1) + 10; + (((int)best_rccal[rx_core] - 12) >> 1) + 10; txlpf_rccal_lpc = ((int)best_rccal[rx_core] - 12) + 10; if (PHY_IPA(pi)) { @@ -25766,8 +27589,10 @@ static int wlc_phy_cal_rxiq_nphy_rev3(struct brcms_phy *pi, TXLPF_IDAC_4, txlpf_idac); } - rxlpf_rccal_hpc = max(min_t(u8, rxlpf_rccal_hpc, 31), 0); - txlpf_rccal_lpc = max(min_t(u8, txlpf_rccal_lpc, 31), 0); + rxlpf_rccal_hpc = max(min_t(u8, rxlpf_rccal_hpc, 31), + 0); + txlpf_rccal_lpc = max(min_t(u8, txlpf_rccal_lpc, 31), + 0); write_radio_reg(pi, (RADIO_2056_RX_RXLPF_RCCAL_HPC | ((rx_core == @@ -25787,21 +27612,21 @@ static int wlc_phy_cal_rxiq_nphy_rev3(struct brcms_phy *pi, wlc_phy_resetcca_nphy(pi); - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - wlc_phy_rfctrl_override_1tomany_nphy(pi, - NPHY_REV7_RfctrlOverride_cmd_rxgain, - 0, 0x3, 1); - } else { + if (NREV_GE(pi->pubpi.phy_rev, 7)) + wlc_phy_rfctrl_override_1tomany_nphy( + pi, + NPHY_REV7_RfctrlOverride_cmd_rxgain, + 0, 0x3, 1); + else wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), 0, 0x3, 1); - } + wlc_phy_force_rfseq_nphy(pi, NPHY_RFSEQ_RESET2RX); wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, gain_save); - if (NREV_GE(pi->pubpi.phy_rev, 4)) { + if (NREV_GE(pi->pubpi.phy_rev, 4)) pi->phyhang_avoid = phyhang_avoid_state; - } wlc_phy_stay_in_carriersearch_nphy(pi, false); @@ -25835,10 +27660,8 @@ wlc_phy_cal_rxiq_nphy_rev2(struct brcms_phy *pi, wlc_phy_stay_in_carriersearch_nphy(pi, true); - if (NREV_LT(pi->pubpi.phy_rev, 2)) { - + if (NREV_LT(pi->pubpi.phy_rev, 2)) wlc_phy_reapply_txcal_coeffs_nphy(pi); - } wlc_phy_table_read_nphy(pi, NPHY_TBL_ID_RFSEQ, 2, 0x110, 16, gain_save); @@ -25874,19 +27697,16 @@ wlc_phy_cal_rxiq_nphy_rev2(struct brcms_phy *pi, ((0x1 << 1) | (0x1 << 2))); or_phy_reg(pi, 0xa5, ((0x1 << 1) | (0x1 << 2))); - if (((pi->nphy_rxcalparams) & 0xff000000)) { - + if (((pi->nphy_rxcalparams) & 0xff000000)) write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x91 : 0x92, - (CHSPEC_IS5G(pi->radio_chanspec) ? 0x140 : - 0x110)); - } else { - + (CHSPEC_IS5G(pi->radio_chanspec) ? + 0x140 : 0x110)); + else write_phy_reg(pi, (rx_core == PHY_CORE_0) ? 0x91 : 0x92, - (CHSPEC_IS5G(pi->radio_chanspec) ? 0x180 : - 0x120)); - } + (CHSPEC_IS5G(pi->radio_chanspec) ? + 0x180 : 0x120)); write_phy_reg(pi, (tx_core == PHY_CORE_0) ? 0x91 : 0x92, (CHSPEC_IS5G(pi->radio_chanspec) ? 0x148 : @@ -25926,7 +27746,7 @@ wlc_phy_cal_rxiq_nphy_rev2(struct brcms_phy *pi, use_hpf_num = 1; curr_hpf = curr_hpf1; actual_log2_pwr = - wlc_phy_nbits(tot_pwr[2]); + wlc_phy_nbits(tot_pwr[2]); } else { if (tot_pwr[0] > 10000) { curr_lna = lna_vals[1]; @@ -25935,7 +27755,8 @@ wlc_phy_cal_rxiq_nphy_rev2(struct brcms_phy *pi, use_hpf_num = 1; curr_hpf = curr_hpf1; actual_log2_pwr = - wlc_phy_nbits(tot_pwr[1]); + wlc_phy_nbits( + tot_pwr[1]); } else { curr_lna = lna_vals[0]; curr_hpf1 = hpf1_vals[0]; @@ -25943,18 +27764,18 @@ wlc_phy_cal_rxiq_nphy_rev2(struct brcms_phy *pi, use_hpf_num = 2; curr_hpf = curr_hpf2; actual_log2_pwr = - wlc_phy_nbits(tot_pwr[0]); + wlc_phy_nbits( + tot_pwr[0]); } } hpf_change = desired_log2_pwr - actual_log2_pwr; curr_hpf += hpf_change; curr_hpf = max(min_t(u16, curr_hpf, 10), 0); - if (use_hpf_num == 1) { + if (use_hpf_num == 1) curr_hpf1 = curr_hpf; - } else { + else curr_hpf2 = curr_hpf; - } } wlc_phy_rfctrl_override_nphy(pi, (0x1 << 10), @@ -25967,15 +27788,12 @@ wlc_phy_cal_rxiq_nphy_rev2(struct brcms_phy *pi, if (first_playtone) { bcmerror = wlc_phy_tx_tone_nphy(pi, 4000, - (u16) (pi-> - nphy_rxcalparams - & - 0xffff), - 0, 0, true); + (u16) (pi->nphy_rxcalparams & + 0xffff), 0, 0, true); first_playtone = false; } else { - phy_bw = - (CHSPEC_IS40(pi->radio_chanspec)) ? 40 : 20; + phy_bw = (CHSPEC_IS40(pi->radio_chanspec)) ? + 40 : 20; wlc_phy_runsamples_nphy(pi, phy_bw * 8, 0xffff, 0, 0, 0, true); } @@ -25986,12 +27804,10 @@ wlc_phy_cal_rxiq_nphy_rev2(struct brcms_phy *pi, wlc_phy_rx_iq_est_nphy(pi, est, num_samps, 32, 0); - i_pwr = - (est[rx_core].i_pwr + - num_samps / 2) / num_samps; - q_pwr = - (est[rx_core].q_pwr + - num_samps / 2) / num_samps; + i_pwr = (est[rx_core].i_pwr + + num_samps / 2) / num_samps; + q_pwr = (est[rx_core].q_pwr + + num_samps / 2) / num_samps; tot_pwr[gain_pass] = i_pwr + q_pwr; } else { @@ -26038,1350 +27854,14 @@ int wlc_phy_cal_rxiq_nphy(struct brcms_phy *pi, struct nphy_txgains target_gain, u8 cal_type, bool debug) { - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - + if (NREV_GE(pi->pubpi.phy_rev, 7)) cal_type = 0; - } - if (NREV_GE(pi->pubpi.phy_rev, 3)) { + + if (NREV_GE(pi->pubpi.phy_rev, 3)) return wlc_phy_cal_rxiq_nphy_rev3(pi, target_gain, cal_type, debug); - } else { + else return wlc_phy_cal_rxiq_nphy_rev2(pi, target_gain, debug); - } -} - -static void wlc_phy_extpa_set_tx_digi_filts_nphy(struct brcms_phy *pi) -{ - int j, type = 2; - u16 addr_offset = 0x2c5; - - for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) { - write_phy_reg(pi, addr_offset + j, - NPHY_IPA_REV4_txdigi_filtcoeffs[type][j]); - } -} - -static void wlc_phy_ipa_set_tx_digi_filts_nphy(struct brcms_phy *pi) -{ - int j, type; - u16 addr_offset[] = { 0x186, 0x195, - 0x2c5 - }; - - for (type = 0; type < 3; type++) { - for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) { - write_phy_reg(pi, addr_offset[type] + j, - NPHY_IPA_REV4_txdigi_filtcoeffs[type][j]); - } - } - - if (IS40MHZ(pi)) { - for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) { - write_phy_reg(pi, 0x186 + j, - NPHY_IPA_REV4_txdigi_filtcoeffs[3][j]); - } - } else { - if (CHSPEC_IS5G(pi->radio_chanspec)) { - for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) { - write_phy_reg(pi, 0x186 + j, - NPHY_IPA_REV4_txdigi_filtcoeffs[5] - [j]); - } - } - - if (CHSPEC_CHANNEL(pi->radio_chanspec) == 14) { - for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) { - write_phy_reg(pi, 0x2c5 + j, - NPHY_IPA_REV4_txdigi_filtcoeffs[6] - [j]); - } - } - } -} - -static void wlc_phy_ipa_restore_tx_digi_filts_nphy(struct brcms_phy *pi) -{ - int j; - - if (IS40MHZ(pi)) { - for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) { - write_phy_reg(pi, 0x195 + j, - NPHY_IPA_REV4_txdigi_filtcoeffs[4][j]); - } - } else { - for (j = 0; j < NPHY_NUM_DIG_FILT_COEFFS; j++) { - write_phy_reg(pi, 0x186 + j, - NPHY_IPA_REV4_txdigi_filtcoeffs[3][j]); - } - } -} - -static u16 wlc_phy_ipa_get_bbmult_nphy(struct brcms_phy *pi) -{ - u16 m0m1; - - wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m0m1); - - return m0m1; -} - -static void wlc_phy_ipa_set_bbmult_nphy(struct brcms_phy *pi, u8 m0, u8 m1) -{ - u16 m0m1 = (u16) ((m0 << 8) | m1); - - wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m0m1); - wlc_phy_table_write_nphy(pi, 15, 1, 95, 16, &m0m1); -} - -static u32 *wlc_phy_get_ipa_gaintbl_nphy(struct brcms_phy *pi) -{ - u32 *tx_pwrctrl_tbl = NULL; - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - - if ((pi->pubpi.radiorev == 4) - || (pi->pubpi.radiorev == 6)) { - - tx_pwrctrl_tbl = - nphy_tpc_txgain_ipa_2g_2057rev4n6; - } else if (pi->pubpi.radiorev == 3) { - - tx_pwrctrl_tbl = - nphy_tpc_txgain_ipa_2g_2057rev3; - } else if (pi->pubpi.radiorev == 5) { - - tx_pwrctrl_tbl = - nphy_tpc_txgain_ipa_2g_2057rev5; - } else if ((pi->pubpi.radiorev == 7) - || (pi->pubpi.radiorev == 8)) { - - tx_pwrctrl_tbl = - nphy_tpc_txgain_ipa_2g_2057rev7; - } - - } else if (NREV_IS(pi->pubpi.phy_rev, 6)) { - - tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_rev6; - } else if (NREV_IS(pi->pubpi.phy_rev, 5)) { - - tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_rev5; - } else { - - tx_pwrctrl_tbl = nphy_tpc_txgain_ipa; - } - - } else { - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - if ((pi->pubpi.radiorev == 3) || - (pi->pubpi.radiorev == 4) || - (pi->pubpi.radiorev == 6)) { - - tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_5g_2057; - } else if ((pi->pubpi.radiorev == 7) - || (pi->pubpi.radiorev == 8)) { - - tx_pwrctrl_tbl = - nphy_tpc_txgain_ipa_5g_2057rev7; - } - - } else { - tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_5g; - } - } - - return tx_pwrctrl_tbl; -} - -static void -wlc_phy_papd_cal_setup_nphy(struct brcms_phy *pi, - struct nphy_papd_restore_state *state, u8 core) -{ - s32 tone_freq; - u8 off_core; - u16 mixgain = 0; - - off_core = core ^ 0x1; - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - - if (NREV_IS(pi->pubpi.phy_rev, 7) - || NREV_GE(pi->pubpi.phy_rev, 8)) { - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7), - wlc_phy_read_lpf_bw_ctl_nphy - (pi, 0), 0, 0, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - } - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - if (pi->pubpi.radiorev == 5) { - mixgain = (core == 0) ? 0x20 : 0x00; - - } else if ((pi->pubpi.radiorev == 7) - || (pi->pubpi.radiorev == 8)) { - - mixgain = 0x00; - - } else if ((pi->pubpi.radiorev <= 4) - || (pi->pubpi.radiorev == 6)) { - - mixgain = 0x00; - } - - } else { - if ((pi->pubpi.radiorev == 4) || - (pi->pubpi.radiorev == 6)) { - - mixgain = 0x50; - } else if ((pi->pubpi.radiorev == 3) - || (pi->pubpi.radiorev == 7) - || (pi->pubpi.radiorev == 8)) { - - mixgain = 0x0; - } - } - - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), - mixgain, (1 << core), 0, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - - wlc_phy_rfctrl_override_1tomany_nphy(pi, - NPHY_REV7_RfctrlOverride_cmd_tx_pu, - 1, (1 << core), 0); - wlc_phy_rfctrl_override_1tomany_nphy(pi, - NPHY_REV7_RfctrlOverride_cmd_tx_pu, - 0, (1 << off_core), 0); - - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), - 0, 0x3, 0, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), 1, - (1 << core), 0, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 0, - (1 << core), 0, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), 1, - (1 << core), 0, - NPHY_REV7_RFCTRLOVERRIDE_ID2); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 8), 0, - (1 << core), 0, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 9), 1, - (1 << core), 0, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 10), 0, - (1 << core), 0, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), 1, - (1 << core), 0, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5), - 0, (1 << core), 0, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), 0, - (1 << core), 0, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - - state->afectrl[core] = read_phy_reg(pi, (core == PHY_CORE_0) ? - 0xa6 : 0xa7); - state->afeoverride[core] = - read_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f : 0xa5); - state->afectrl[off_core] = - read_phy_reg(pi, (core == PHY_CORE_0) ? 0xa7 : 0xa6); - state->afeoverride[off_core] = - read_phy_reg(pi, (core == PHY_CORE_0) ? 0xa5 : 0x8f); - - mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa6 : 0xa7), - (0x1 << 2), 0); - mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f : - 0xa5), (0x1 << 2), (0x1 << 2)); - - mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa7 : 0xa6), - (0x1 << 2), (0x1 << 2)); - mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa5 : - 0x8f), (0x1 << 2), (0x1 << 2)); - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - state->pwrup[core] = - READ_RADIO_REG3(pi, RADIO_2057, TX, core, - TXRXCOUPLE_2G_PWRUP); - state->atten[core] = - READ_RADIO_REG3(pi, RADIO_2057, TX, core, - TXRXCOUPLE_2G_ATTEN); - state->pwrup[off_core] = - READ_RADIO_REG3(pi, RADIO_2057, TX, off_core, - TXRXCOUPLE_2G_PWRUP); - state->atten[off_core] = - READ_RADIO_REG3(pi, RADIO_2057, TX, off_core, - TXRXCOUPLE_2G_ATTEN); - - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TXRXCOUPLE_2G_PWRUP, 0xc); - - if ((pi->pubpi.radiorev == 3) || - (pi->pubpi.radiorev == 4) || - (pi->pubpi.radiorev == 6)) { - - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TXRXCOUPLE_2G_ATTEN, 0xf0); - - } else if (pi->pubpi.radiorev == 5) { - - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TXRXCOUPLE_2G_ATTEN, - (core == 0) ? 0xf7 : 0xf2); - - } else if ((pi->pubpi.radiorev == 7) - || (pi->pubpi.radiorev == 8)) { - - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TXRXCOUPLE_2G_ATTEN, 0xf0); - - } - - WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core, - TXRXCOUPLE_2G_PWRUP, 0x0); - WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core, - TXRXCOUPLE_2G_ATTEN, 0xff); - - } else { - state->pwrup[core] = - READ_RADIO_REG3(pi, RADIO_2057, TX, core, - TXRXCOUPLE_5G_PWRUP); - state->atten[core] = - READ_RADIO_REG3(pi, RADIO_2057, TX, core, - TXRXCOUPLE_5G_ATTEN); - state->pwrup[off_core] = - READ_RADIO_REG3(pi, RADIO_2057, TX, off_core, - TXRXCOUPLE_5G_PWRUP); - state->atten[off_core] = - READ_RADIO_REG3(pi, RADIO_2057, TX, off_core, - TXRXCOUPLE_5G_ATTEN); - - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TXRXCOUPLE_5G_PWRUP, 0xc); - - if ((pi->pubpi.radiorev == 7) - || (pi->pubpi.radiorev == 8)) { - - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TXRXCOUPLE_5G_ATTEN, 0xf4); - - } else { - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TXRXCOUPLE_5G_ATTEN, 0xf0); - } - - WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core, - TXRXCOUPLE_5G_PWRUP, 0x0); - WRITE_RADIO_REG3(pi, RADIO_2057, TX, off_core, - TXRXCOUPLE_5G_ATTEN, 0xff); - } - - tone_freq = 4000; - - wlc_phy_tx_tone_nphy(pi, tone_freq, 181, 0, 0, false); - - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 : - 0x29b, (0x1 << 0), (NPHY_PAPD_COMP_ON) << 0); - - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0x1 << 13), (1) << 13); - - mod_phy_reg(pi, (off_core == PHY_CORE_0) ? 0x297 : - 0x29b, (0x1 << 0), (NPHY_PAPD_COMP_OFF) << 0); - - mod_phy_reg(pi, (off_core == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0x1 << 13), (0) << 13); - - } else { - - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), 0, 0x3, 0); - - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 1, 0, 0); - - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 0), 0, 0x3, 0); - - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 2), 1, 0x3, 0); - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 1), 1, 0x3, 0); - - state->afectrl[core] = read_phy_reg(pi, (core == PHY_CORE_0) ? - 0xa6 : 0xa7); - state->afeoverride[core] = - read_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f : 0xa5); - - mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0xa6 : 0xa7), - (0x1 << 0) | (0x1 << 1) | (0x1 << 2), 0); - mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f : - 0xa5), - (0x1 << 0) | - (0x1 << 1) | - (0x1 << 2), (0x1 << 0) | (0x1 << 1) | (0x1 << 2)); - - state->vga_master[core] = - READ_RADIO_REG2(pi, RADIO_2056, RX, core, VGA_MASTER); - WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, VGA_MASTER, 0x2b); - if (CHSPEC_IS2G(pi->radio_chanspec)) { - state->fbmix[core] = - READ_RADIO_REG2(pi, RADIO_2056, RX, core, - TXFBMIX_G); - state->intpa_master[core] = - READ_RADIO_REG2(pi, RADIO_2056, TX, core, - INTPAG_MASTER); - - WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, TXFBMIX_G, - 0x03); - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - INTPAG_MASTER, 0x04); - } else { - state->fbmix[core] = - READ_RADIO_REG2(pi, RADIO_2056, RX, core, - TXFBMIX_A); - state->intpa_master[core] = - READ_RADIO_REG2(pi, RADIO_2056, TX, core, - INTPAA_MASTER); - - WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, TXFBMIX_A, - 0x03); - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - INTPAA_MASTER, 0x04); - - } - - tone_freq = 4000; - - wlc_phy_tx_tone_nphy(pi, tone_freq, 181, 0, 0, false); - - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 : - 0x29b, (0x1 << 0), (1) << 0); - - mod_phy_reg(pi, (off_core == PHY_CORE_0) ? 0x297 : - 0x29b, (0x1 << 0), (0) << 0); - - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 0x3, 0); - } -} - -static void -wlc_phy_papd_cal_cleanup_nphy(struct brcms_phy *pi, - struct nphy_papd_restore_state *state) -{ - u8 core; - - wlc_phy_stopplayback_nphy(pi); - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - - for (core = 0; core < pi->pubpi.phy_corenum; core++) { - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TXRXCOUPLE_2G_PWRUP, 0); - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TXRXCOUPLE_2G_ATTEN, - state->atten[core]); - } else { - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TXRXCOUPLE_5G_PWRUP, 0); - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TXRXCOUPLE_5G_ATTEN, - state->atten[core]); - } - } - - if ((pi->pubpi.radiorev == 4) || (pi->pubpi.radiorev == 6)) { - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), - 1, 0x3, 0, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - } else { - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), - 0, 0x3, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - } - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), - 0, 0x3, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 0, 0x3, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID2); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), 0, 0x3, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID2); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 1, 0x3, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), 0, 0x3, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 11), 0, 0x3, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12), 0, 0x3, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 2), 1, 0x3, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 0), 0, 0x3, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 1), 1, 0x3, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID2); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 8), 0, 0x3, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 9), 1, 0x3, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 10), 0, 0x3, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), 1, 0x3, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 5), 0, 0x3, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 4), 0, 0x3, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - - for (core = 0; core < pi->pubpi.phy_corenum; core++) { - - write_phy_reg(pi, (core == PHY_CORE_0) ? - 0xa6 : 0xa7, state->afectrl[core]); - write_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f : - 0xa5, state->afeoverride[core]); - } - - wlc_phy_ipa_set_bbmult_nphy(pi, (state->mm >> 8) & 0xff, - (state->mm & 0xff)); - - if (NREV_IS(pi->pubpi.phy_rev, 7) - || NREV_GE(pi->pubpi.phy_rev, 8)) { - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 7), 0, 0, - 1, - NPHY_REV7_RFCTRLOVERRIDE_ID1); - } - } else { - - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 12), 0, 0x3, 1); - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 13), 0, 0x3, 1); - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 0), 0, 0x3, 1); - - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 2), 0, 0x3, 1); - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 1), 0, 0x3, 1); - - for (core = 0; core < pi->pubpi.phy_corenum; core++) { - - WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, VGA_MASTER, - state->vga_master[core]); - if (CHSPEC_IS2G(pi->radio_chanspec)) { - WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, - TXFBMIX_G, state->fbmix[core]); - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - INTPAG_MASTER, - state->intpa_master[core]); - } else { - WRITE_RADIO_REG2(pi, RADIO_2056, RX, core, - TXFBMIX_A, state->fbmix[core]); - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - INTPAA_MASTER, - state->intpa_master[core]); - } - - write_phy_reg(pi, (core == PHY_CORE_0) ? - 0xa6 : 0xa7, state->afectrl[core]); - write_phy_reg(pi, (core == PHY_CORE_0) ? 0x8f : - 0xa5, state->afeoverride[core]); - } - - wlc_phy_ipa_set_bbmult_nphy(pi, (state->mm >> 8) & 0xff, - (state->mm & 0xff)); - - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 0x3, 1); - } -} - -static void -wlc_phy_a1_nphy(struct brcms_phy *pi, u8 core, u32 winsz, u32 start, - u32 end) -{ - u32 *buf, *src, *dst, sz; - - sz = end - start + 1; - - buf = kmalloc(2 * sizeof(u32) * NPHY_PAPD_EPS_TBL_SIZE, GFP_ATOMIC); - if (NULL == buf) { - return; - } - - src = buf; - dst = buf + NPHY_PAPD_EPS_TBL_SIZE; - - wlc_phy_table_read_nphy(pi, - (core == - PHY_CORE_0 ? NPHY_TBL_ID_EPSILONTBL0 : - NPHY_TBL_ID_EPSILONTBL1), - NPHY_PAPD_EPS_TBL_SIZE, 0, 32, src); - - do { - u32 phy_a1, phy_a2; - s32 phy_a3, phy_a4, phy_a5, phy_a6, phy_a7; - - phy_a1 = end - min(end, (winsz >> 1)); - phy_a2 = min_t(u32, NPHY_PAPD_EPS_TBL_SIZE - 1, end + (winsz >> 1)); - phy_a3 = phy_a2 - phy_a1 + 1; - phy_a6 = 0; - phy_a7 = 0; - - do { - wlc_phy_papd_decode_epsilon(src[phy_a2], &phy_a4, - &phy_a5); - phy_a6 += phy_a4; - phy_a7 += phy_a5; - } while (phy_a2-- != phy_a1); - - phy_a6 /= phy_a3; - phy_a7 /= phy_a3; - dst[end] = ((u32) phy_a7 << 13) | ((u32) phy_a6 & 0x1fff); - } while (end-- != start); - - wlc_phy_table_write_nphy(pi, - (core == - PHY_CORE_0) ? NPHY_TBL_ID_EPSILONTBL0 : - NPHY_TBL_ID_EPSILONTBL1, sz, start, 32, dst); - - kfree(buf); -} - -static void -wlc_phy_a2_nphy(struct brcms_phy *pi, struct nphy_ipa_txcalgains *txgains, - enum phy_cal_mode cal_mode, u8 core) -{ - u16 phy_a1, phy_a2, phy_a3; - u16 phy_a4, phy_a5; - bool phy_a6; - u8 phy_a7, m[2]; - u32 phy_a8 = 0; - struct nphy_txgains phy_a9; - - if (NREV_LT(pi->pubpi.phy_rev, 3)) - return; - - phy_a7 = (core == PHY_CORE_0) ? 1 : 0; - - phy_a6 = ((cal_mode == CAL_GCTRL) - || (cal_mode == CAL_SOFT)) ? true : false; - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - - phy_a9 = wlc_phy_get_tx_gain_nphy(pi); - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - phy_a5 = ((phy_a9.txlpf[core] << 15) | - (phy_a9.txgm[core] << 12) | - (phy_a9.pga[core] << 8) | - (txgains->gains.pad[core] << 3) | - (phy_a9.ipa[core])); - } else { - phy_a5 = ((phy_a9.txlpf[core] << 15) | - (phy_a9.txgm[core] << 12) | - (txgains->gains.pga[core] << 8) | - (phy_a9.pad[core] << 3) | (phy_a9.ipa[core])); - } - - wlc_phy_rfctrl_override_1tomany_nphy(pi, - NPHY_REV7_RfctrlOverride_cmd_txgain, - phy_a5, (1 << core), 0); - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - if ((pi->pubpi.radiorev <= 4) - || (pi->pubpi.radiorev == 6)) { - - m[core] = IS40MHZ(pi) ? 60 : 79; - } else { - - m[core] = IS40MHZ(pi) ? 45 : 64; - } - - } else { - m[core] = IS40MHZ(pi) ? 75 : 107; - } - - m[phy_a7] = 0; - wlc_phy_ipa_set_bbmult_nphy(pi, m[0], m[1]); - - phy_a2 = 63; - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - if ((pi->pubpi.radiorev == 4) - || (pi->pubpi.radiorev == 6)) { - phy_a1 = 30; - phy_a3 = 30; - } else { - phy_a1 = 25; - phy_a3 = 25; - } - } else { - if ((pi->pubpi.radiorev == 5) - || (pi->pubpi.radiorev == 7) - || (pi->pubpi.radiorev == 8)) { - phy_a1 = 25; - phy_a3 = 25; - } else { - phy_a1 = 35; - phy_a3 = 35; - } - } - - if (cal_mode == CAL_GCTRL) { - if ((pi->pubpi.radiorev == 5) - && (CHSPEC_IS2G(pi->radio_chanspec))) { - phy_a1 = 55; - } else if (((pi->pubpi.radiorev == 7) && - (CHSPEC_IS2G(pi->radio_chanspec))) || - ((pi->pubpi.radiorev == 8) && - (CHSPEC_IS2G(pi->radio_chanspec)))) { - phy_a1 = 60; - } else { - phy_a1 = 63; - } - - } else if ((cal_mode != CAL_FULL) && (cal_mode != CAL_SOFT)) { - - phy_a1 = 35; - phy_a3 = 35; - } - - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 : - 0x29b, (0x1 << 0), (1) << 0); - - mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x297 : - 0x29b, (0x1 << 0), (0) << 0); - - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0x1 << 13), (1) << 13); - - mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0x1 << 13), (0) << 13); - - write_phy_reg(pi, 0x2a1, 0x80); - write_phy_reg(pi, 0x2a2, 0x100); - - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0x7 << 4), (11) << 4); - - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0x7 << 8), (11) << 8); - - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0x7 << 0), (0x3) << 0); - - write_phy_reg(pi, 0x2e5, 0x20); - - mod_phy_reg(pi, 0x2a0, (0x3f << 0), (phy_a3) << 0); - - mod_phy_reg(pi, 0x29f, (0x3f << 0), (phy_a1) << 0); - - mod_phy_reg(pi, 0x29f, (0x3f << 8), (phy_a2) << 8); - - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), - 1, ((core == 0) ? 1 : 2), 0, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), - 0, ((core == 0) ? 2 : 1), 0, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - - write_phy_reg(pi, 0x2be, 1); - SPINWAIT(read_phy_reg(pi, 0x2be), 10 * 1000 * 1000); - - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 3), - 0, 0x3, 0, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - - wlc_phy_table_write_nphy(pi, - (core == - PHY_CORE_0) ? NPHY_TBL_ID_EPSILONTBL0 - : NPHY_TBL_ID_EPSILONTBL1, 1, phy_a3, - 32, &phy_a8); - - if (cal_mode != CAL_GCTRL) { - if (CHSPEC_IS5G(pi->radio_chanspec)) { - wlc_phy_a1_nphy(pi, core, 5, 0, 35); - } - } - - wlc_phy_rfctrl_override_1tomany_nphy(pi, - NPHY_REV7_RfctrlOverride_cmd_txgain, - phy_a5, (1 << core), 1); - - } else { - - if (txgains) { - if (txgains->useindex) { - phy_a4 = 15 - ((txgains->index) >> 3); - if (CHSPEC_IS2G(pi->radio_chanspec)) { - if (NREV_GE(pi->pubpi.phy_rev, 6)) - phy_a5 = 0x00f7 | (phy_a4 << 8); - - else - if (NREV_IS(pi->pubpi.phy_rev, 5)) - phy_a5 = 0x10f7 | (phy_a4 << 8); - else - phy_a5 = 0x50f7 | (phy_a4 << 8); - } else { - phy_a5 = 0x70f7 | (phy_a4 << 8); - } - wlc_phy_rfctrl_override_nphy(pi, - (0x1 << 13), - phy_a5, - (1 << core), 0); - } else { - wlc_phy_rfctrl_override_nphy(pi, - (0x1 << 13), - 0x5bf7, - (1 << core), 0); - } - } - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - m[core] = IS40MHZ(pi) ? 45 : 64; - } else { - m[core] = IS40MHZ(pi) ? 75 : 107; - } - - m[phy_a7] = 0; - wlc_phy_ipa_set_bbmult_nphy(pi, m[0], m[1]); - - phy_a2 = 63; - - if (cal_mode == CAL_FULL) { - phy_a1 = 25; - phy_a3 = 25; - } else if (cal_mode == CAL_SOFT) { - phy_a1 = 25; - phy_a3 = 25; - } else if (cal_mode == CAL_GCTRL) { - phy_a1 = 63; - phy_a3 = 25; - } else { - - phy_a1 = 25; - phy_a3 = 25; - } - - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 : - 0x29b, (0x1 << 0), (1) << 0); - - mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x297 : - 0x29b, (0x1 << 0), (0) << 0); - - if (NREV_GE(pi->pubpi.phy_rev, 6)) { - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0x1 << 13), (1) << 13); - - mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0x1 << 13), (0) << 13); - - write_phy_reg(pi, 0x2a1, 0x20); - write_phy_reg(pi, 0x2a2, 0x60); - - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0xf << 4), (9) << 4); - - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0xf << 8), (9) << 8); - - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0xf << 0), (0x2) << 0); - - write_phy_reg(pi, 0x2e5, 0x20); - } else { - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0x1 << 11), (1) << 11); - - mod_phy_reg(pi, (phy_a7 == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0x1 << 11), (0) << 11); - - write_phy_reg(pi, 0x2a1, 0x80); - write_phy_reg(pi, 0x2a2, 0x600); - - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0x7 << 4), (0) << 4); - - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0x7 << 8), (0) << 8); - - mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0x7 << 0), (0x3) << 0); - - mod_phy_reg(pi, 0x2a0, (0x3f << 8), (0x20) << 8); - - } - - mod_phy_reg(pi, 0x2a0, (0x3f << 0), (phy_a3) << 0); - - mod_phy_reg(pi, 0x29f, (0x3f << 0), (phy_a1) << 0); - - mod_phy_reg(pi, 0x29f, (0x3f << 8), (phy_a2) << 8); - - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 1, 0x3, 0); - - write_phy_reg(pi, 0x2be, 1); - SPINWAIT(read_phy_reg(pi, 0x2be), 10 * 1000 * 1000); - - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 3), 0, 0x3, 0); - - wlc_phy_table_write_nphy(pi, - (core == - PHY_CORE_0) ? NPHY_TBL_ID_EPSILONTBL0 - : NPHY_TBL_ID_EPSILONTBL1, 1, phy_a3, - 32, &phy_a8); - - if (cal_mode != CAL_GCTRL) { - wlc_phy_a1_nphy(pi, core, 5, 0, 40); - } - } -} - -static u8 wlc_phy_a3_nphy(struct brcms_phy *pi, u8 start_gain, u8 core) -{ - int phy_a1; - int phy_a2; - bool phy_a3; - struct nphy_ipa_txcalgains phy_a4; - bool phy_a5 = false; - bool phy_a6 = true; - s32 phy_a7, phy_a8; - u32 phy_a9; - int phy_a10; - bool phy_a11 = false; - int phy_a12; - u8 phy_a13 = 0; - u8 phy_a14; - u8 *phy_a15 = NULL; - - phy_a4.useindex = true; - phy_a12 = start_gain; - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - - phy_a2 = 20; - phy_a1 = 1; - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - if (pi->pubpi.radiorev == 5) { - - phy_a15 = pad_gain_codes_used_2057rev5; - phy_a13 = sizeof(pad_gain_codes_used_2057rev5) / - sizeof(pad_gain_codes_used_2057rev5[0]) - 1; - - } else if ((pi->pubpi.radiorev == 7) - || (pi->pubpi.radiorev == 8)) { - - phy_a15 = pad_gain_codes_used_2057rev7; - phy_a13 = sizeof(pad_gain_codes_used_2057rev7) / - sizeof(pad_gain_codes_used_2057rev7[0]) - 1; - - } else { - - phy_a15 = pad_all_gain_codes_2057; - phy_a13 = sizeof(pad_all_gain_codes_2057) / - sizeof(pad_all_gain_codes_2057[0]) - 1; - } - - } else { - - phy_a15 = pga_all_gain_codes_2057; - phy_a13 = sizeof(pga_all_gain_codes_2057) / - sizeof(pga_all_gain_codes_2057[0]) - 1; - } - - phy_a14 = 0; - - for (phy_a10 = 0; phy_a10 < phy_a2; phy_a10++) { - if (CHSPEC_IS2G(pi->radio_chanspec)) { - phy_a4.gains.pad[core] = - (u16) phy_a15[phy_a12]; - } else { - phy_a4.gains.pga[core] = - (u16) phy_a15[phy_a12]; - } - - wlc_phy_a2_nphy(pi, &phy_a4, CAL_GCTRL, core); - - wlc_phy_table_read_nphy(pi, - (core == - PHY_CORE_0 ? - NPHY_TBL_ID_EPSILONTBL0 : - NPHY_TBL_ID_EPSILONTBL1), 1, - 63, 32, &phy_a9); - - wlc_phy_papd_decode_epsilon(phy_a9, &phy_a7, &phy_a8); - - phy_a3 = ((phy_a7 == 4095) || (phy_a7 == -4096) || - (phy_a8 == 4095) || (phy_a8 == -4096)); - - if (!phy_a6 && (phy_a3 != phy_a5)) { - if (!phy_a3) { - phy_a12 -= (u8) phy_a1; - } - phy_a11 = true; - break; - } - - if (phy_a3) - phy_a12 += (u8) phy_a1; - else - phy_a12 -= (u8) phy_a1; - - if ((phy_a12 < phy_a14) || (phy_a12 > phy_a13)) { - if (phy_a12 < phy_a14) { - phy_a12 = phy_a14; - } else { - phy_a12 = phy_a13; - } - phy_a11 = true; - break; - } - - phy_a6 = false; - phy_a5 = phy_a3; - } - - } else { - phy_a2 = 10; - phy_a1 = 8; - for (phy_a10 = 0; phy_a10 < phy_a2; phy_a10++) { - phy_a4.index = (u8) phy_a12; - wlc_phy_a2_nphy(pi, &phy_a4, CAL_GCTRL, core); - - wlc_phy_table_read_nphy(pi, - (core == - PHY_CORE_0 ? - NPHY_TBL_ID_EPSILONTBL0 : - NPHY_TBL_ID_EPSILONTBL1), 1, - 63, 32, &phy_a9); - - wlc_phy_papd_decode_epsilon(phy_a9, &phy_a7, &phy_a8); - - phy_a3 = ((phy_a7 == 4095) || (phy_a7 == -4096) || - (phy_a8 == 4095) || (phy_a8 == -4096)); - - if (!phy_a6 && (phy_a3 != phy_a5)) { - if (!phy_a3) { - phy_a12 -= (u8) phy_a1; - } - phy_a11 = true; - break; - } - - if (phy_a3) - phy_a12 += (u8) phy_a1; - else - phy_a12 -= (u8) phy_a1; - - if ((phy_a12 < 0) || (phy_a12 > 127)) { - if (phy_a12 < 0) { - phy_a12 = 0; - } else { - phy_a12 = 127; - } - phy_a11 = true; - break; - } - - phy_a6 = false; - phy_a5 = phy_a3; - } - - } - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - return (u8) phy_a15[phy_a12]; - } else { - return (u8) phy_a12; - } - -} - -static void wlc_phy_a4(struct brcms_phy *pi, bool full_cal) -{ - struct nphy_ipa_txcalgains phy_b1[2]; - struct nphy_papd_restore_state phy_b2; - bool phy_b3; - u8 phy_b4; - u8 phy_b5; - s16 phy_b6, phy_b7, phy_b8; - u16 phy_b9; - s16 phy_b10, phy_b11, phy_b12; - - phy_b11 = 0; - phy_b12 = 0; - phy_b7 = 0; - phy_b8 = 0; - phy_b6 = 0; - - if (pi->nphy_papd_skip == 1) - return; - - phy_b3 = - (0 == (R_REG(&pi->regs->maccontrol) & MCTL_EN_MAC)); - if (!phy_b3) { - wlapi_suspend_mac_and_wait(pi->sh->physhim); - } - - wlc_phy_stay_in_carriersearch_nphy(pi, true); - - pi->nphy_force_papd_cal = false; - - for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) - pi->nphy_papd_tx_gain_at_last_cal[phy_b5] = - wlc_phy_txpwr_idx_cur_get_nphy(pi, phy_b5); - - pi->nphy_papd_last_cal = pi->sh->now; - pi->nphy_papd_recal_counter++; - - if (NORADIO_ENAB(pi->pubpi)) - return; - - phy_b4 = pi->nphy_txpwrctrl; - wlc_phy_txpwrctrl_enable_nphy(pi, PHY_TPC_HW_OFF); - - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_SCALARTBL0, 64, 0, 32, - nphy_papd_scaltbl); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_SCALARTBL1, 64, 0, 32, - nphy_papd_scaltbl); - - phy_b9 = read_phy_reg(pi, 0x01); - mod_phy_reg(pi, 0x01, (0x1 << 15), 0); - - for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) { - s32 i, val = 0; - for (i = 0; i < 64; i++) { - wlc_phy_table_write_nphy(pi, - ((phy_b5 == - PHY_CORE_0) ? - NPHY_TBL_ID_EPSILONTBL0 : - NPHY_TBL_ID_EPSILONTBL1), 1, - i, 32, &val); - } - } - - wlc_phy_ipa_restore_tx_digi_filts_nphy(pi); - - phy_b2.mm = wlc_phy_ipa_get_bbmult_nphy(pi); - for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) { - wlc_phy_papd_cal_setup_nphy(pi, &phy_b2, phy_b5); - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - if (CHSPEC_IS2G(pi->radio_chanspec)) { - - if ((pi->pubpi.radiorev == 3) - || (pi->pubpi.radiorev == 4) - || (pi->pubpi.radiorev == 6)) { - - pi->nphy_papd_cal_gain_index[phy_b5] = - 23; - - } else if (pi->pubpi.radiorev == 5) { - - pi->nphy_papd_cal_gain_index[phy_b5] = - 0; - pi->nphy_papd_cal_gain_index[phy_b5] = - wlc_phy_a3_nphy(pi, - pi-> - nphy_papd_cal_gain_index - [phy_b5], phy_b5); - - } else if ((pi->pubpi.radiorev == 7) - || (pi->pubpi.radiorev == 8)) { - - pi->nphy_papd_cal_gain_index[phy_b5] = - 0; - pi->nphy_papd_cal_gain_index[phy_b5] = - wlc_phy_a3_nphy(pi, - pi-> - nphy_papd_cal_gain_index - [phy_b5], phy_b5); - - } - - phy_b1[phy_b5].gains.pad[phy_b5] = - pi->nphy_papd_cal_gain_index[phy_b5]; - - } else { - pi->nphy_papd_cal_gain_index[phy_b5] = 0; - pi->nphy_papd_cal_gain_index[phy_b5] = - wlc_phy_a3_nphy(pi, - pi-> - nphy_papd_cal_gain_index - [phy_b5], phy_b5); - phy_b1[phy_b5].gains.pga[phy_b5] = - pi->nphy_papd_cal_gain_index[phy_b5]; - } - } else { - phy_b1[phy_b5].useindex = true; - phy_b1[phy_b5].index = 16; - phy_b1[phy_b5].index = - wlc_phy_a3_nphy(pi, phy_b1[phy_b5].index, phy_b5); - - pi->nphy_papd_cal_gain_index[phy_b5] = - 15 - ((phy_b1[phy_b5].index) >> 3); - } - - switch (pi->nphy_papd_cal_type) { - case 0: - wlc_phy_a2_nphy(pi, &phy_b1[phy_b5], CAL_FULL, phy_b5); - break; - case 1: - wlc_phy_a2_nphy(pi, &phy_b1[phy_b5], CAL_SOFT, phy_b5); - break; - } - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - wlc_phy_papd_cal_cleanup_nphy(pi, &phy_b2); - } - } - - if (NREV_LT(pi->pubpi.phy_rev, 7)) { - wlc_phy_papd_cal_cleanup_nphy(pi, &phy_b2); - } - - for (phy_b5 = 0; phy_b5 < pi->pubpi.phy_corenum; phy_b5++) { - int eps_offset = 0; - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - if (CHSPEC_IS2G(pi->radio_chanspec)) { - if (pi->pubpi.radiorev == 3) { - eps_offset = -2; - } else if (pi->pubpi.radiorev == 5) { - eps_offset = 3; - } else { - eps_offset = -1; - } - } else { - eps_offset = 2; - } - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - phy_b8 = phy_b1[phy_b5].gains.pad[phy_b5]; - phy_b10 = 0; - if ((pi->pubpi.radiorev == 3) || - (pi->pubpi.radiorev == 4) || - (pi->pubpi.radiorev == 6)) { - phy_b12 = - - - (nphy_papd_padgain_dlt_2g_2057rev3n4 - [phy_b8] - + 1) / 2; - phy_b10 = -1; - } else if (pi->pubpi.radiorev == 5) { - phy_b12 = - -(nphy_papd_padgain_dlt_2g_2057rev5 - [phy_b8] - + 1) / 2; - } else if ((pi->pubpi.radiorev == 7) || - (pi->pubpi.radiorev == 8)) { - phy_b12 = - -(nphy_papd_padgain_dlt_2g_2057rev7 - [phy_b8] - + 1) / 2; - } - } else { - phy_b7 = phy_b1[phy_b5].gains.pga[phy_b5]; - if ((pi->pubpi.radiorev == 3) || - (pi->pubpi.radiorev == 4) || - (pi->pubpi.radiorev == 6)) { - phy_b11 = - -(nphy_papd_pgagain_dlt_5g_2057 - [phy_b7] - + 1) / 2; - } else if ((pi->pubpi.radiorev == 7) - || (pi->pubpi.radiorev == 8)) { - phy_b11 = - -(nphy_papd_pgagain_dlt_5g_2057rev7 - [phy_b7] - + 1) / 2; - } - - phy_b10 = -9; - } - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - phy_b6 = - -60 + 27 + eps_offset + phy_b12 + phy_b10; - } else { - phy_b6 = - -60 + 27 + eps_offset + phy_b11 + phy_b10; - } - - mod_phy_reg(pi, (phy_b5 == PHY_CORE_0) ? 0x298 : - 0x29c, (0x1ff << 7), (phy_b6) << 7); - - pi->nphy_papd_epsilon_offset[phy_b5] = phy_b6; - } else { - if (NREV_LT(pi->pubpi.phy_rev, 5)) { - eps_offset = 4; - } else { - eps_offset = 2; - } - - phy_b7 = 15 - ((phy_b1[phy_b5].index) >> 3); - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - phy_b11 = - -(nphy_papd_pga_gain_delta_ipa_2g[phy_b7] + - 1) / 2; - phy_b10 = 0; - } else { - phy_b11 = - -(nphy_papd_pga_gain_delta_ipa_5g[phy_b7] + - 1) / 2; - phy_b10 = -9; - } - - phy_b6 = -60 + 27 + eps_offset + phy_b11 + phy_b10; - - mod_phy_reg(pi, (phy_b5 == PHY_CORE_0) ? 0x298 : - 0x29c, (0x1ff << 7), (phy_b6) << 7); - - pi->nphy_papd_epsilon_offset[phy_b5] = phy_b6; - } - } - - mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x297 : - 0x29b, (0x1 << 0), (NPHY_PAPD_COMP_ON) << 0); - - mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x297 : - 0x29b, (0x1 << 0), (NPHY_PAPD_COMP_ON) << 0); - - if (NREV_GE(pi->pubpi.phy_rev, 6)) { - mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0x1 << 13), (0) << 13); - - mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0x1 << 13), (0) << 13); - - } else { - mod_phy_reg(pi, (0 == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0x1 << 11), (0) << 11); - - mod_phy_reg(pi, (1 == PHY_CORE_0) ? 0x2a3 : - 0x2a4, (0x1 << 11), (0) << 11); - - } - pi->nphy_papdcomp = NPHY_PAPD_COMP_ON; - - write_phy_reg(pi, 0x01, phy_b9); - - wlc_phy_ipa_set_tx_digi_filts_nphy(pi); - - wlc_phy_txpwrctrl_enable_nphy(pi, phy_b4); - if (phy_b4 == PHY_TPC_HW_OFF) { - wlc_phy_txpwr_index_nphy(pi, (1 << 0), - (s8) (pi->nphy_txpwrindex[0]. - index_internal), false); - wlc_phy_txpwr_index_nphy(pi, (1 << 1), - (s8) (pi->nphy_txpwrindex[1]. - index_internal), false); - } - - wlc_phy_stay_in_carriersearch_nphy(pi, false); - - if (!phy_b3) { - wlapi_enable_mac(pi->sh->physhim); - } } void wlc_phy_txpwr_fixpower_nphy(struct brcms_phy *pi) @@ -27423,11 +27903,10 @@ void wlc_phy_txpwr_fixpower_nphy(struct brcms_phy *pi) } } - if (NREV_GE(pi->pubpi.phy_rev, 7)) { + if (NREV_GE(pi->pubpi.phy_rev, 7)) txpi[0] = txpi[1] = 30; - } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { + else if (NREV_GE(pi->pubpi.phy_rev, 3)) txpi[0] = txpi[1] = 40; - } if (NREV_LT(pi->pubpi.phy_rev, 7)) { @@ -27447,37 +27926,36 @@ void wlc_phy_txpwr_fixpower_nphy(struct brcms_phy *pi) if (NREV_GE(phyrev, 3)) { if (PHY_IPA(pi)) { u32 *tx_gaintbl = - wlc_phy_get_ipa_gaintbl_nphy(pi); + wlc_phy_get_ipa_gaintbl_nphy(pi); txgain = tx_gaintbl[txpi[core]]; } else { if (CHSPEC_IS5G(pi->radio_chanspec)) { if (NREV_IS(phyrev, 3)) { txgain = - nphy_tpc_5GHz_txgain_rev3 - [txpi[core]]; + nphy_tpc_5GHz_txgain_rev3 + [txpi[core]]; } else if (NREV_IS(phyrev, 4)) { - txgain = - (pi->srom_fem5g.extpagain == - 3) ? - nphy_tpc_5GHz_txgain_HiPwrEPA - [txpi[core]] : - nphy_tpc_5GHz_txgain_rev4 - [txpi[core]]; + txgain = ( + pi->srom_fem5g.extpagain == + 3) ? + nphy_tpc_5GHz_txgain_HiPwrEPA + [txpi[core]] : + nphy_tpc_5GHz_txgain_rev4 + [txpi[core]]; } else { txgain = - nphy_tpc_5GHz_txgain_rev5 - [txpi[core]]; + nphy_tpc_5GHz_txgain_rev5 + [txpi[core]]; } } else { if (NREV_GE(phyrev, 5) && (pi->srom_fem2g.extpagain == 3)) { txgain = - nphy_tpc_txgain_HiPwrEPA - [txpi[core]]; + nphy_tpc_txgain_HiPwrEPA + [txpi[core]]; } else { - txgain = - nphy_tpc_txgain_rev3[txpi - [core]]; + txgain = nphy_tpc_txgain_rev3 + [txpi[core]]; } } } @@ -27497,12 +27975,12 @@ void wlc_phy_txpwr_fixpower_nphy(struct brcms_phy *pi) bbmult = (txgain >> 0) & ((1 << (7 - 0 + 1)) - 1); - if (NREV_GE(phyrev, 3)) { + if (NREV_GE(phyrev, 3)) mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f : 0xa5), (0x1 << 8), (0x1 << 8)); - } else { + else mod_phy_reg(pi, 0xa5, (0x1 << 14), (0x1 << 14)); - } + write_phy_reg(pi, (core == PHY_CORE_0) ? 0xaa : 0xab, dac_gain); wlc_phy_table_write_nphy(pi, 7, 1, (0x110 + core), 16, @@ -27562,9 +28040,8 @@ wlc_phy_txpwr_nphy_po_apply(u8 *srom_max, u8 pwr_offset, { u8 rate; - for (rate = rate_start; rate <= rate_end; rate++) { + for (rate = rate_start; rate <= rate_end; rate++) srom_max[rate] -= 2 * pwr_offset; - } } void @@ -27603,7 +28080,8 @@ void wlc_phy_txpwr_apply_nphy(struct brcms_phy *pi) u16 pwr_offsets1[2], *pwr_offsets2 = NULL; u8 *tx_srom_max_rate = NULL; - for (band_num = 0; band_num < (CH_2G_GROUP + CH_5G_GROUP); band_num++) { + for (band_num = 0; band_num < (CH_2G_GROUP + CH_5G_GROUP); + band_num++) { switch (band_num) { case 0: @@ -27619,7 +28097,7 @@ void wlc_phy_txpwr_apply_nphy(struct brcms_phy *pi) pwr_offsets1[0] = (u16) (pi->ofdm2gpo & 0xffff); pwr_offsets1[1] = - (u16) (pi->ofdm2gpo >> 16) & 0xffff; + (u16) (pi->ofdm2gpo >> 16) & 0xffff; pwr_offsets2 = pi->mcs2gpo; @@ -27636,7 +28114,7 @@ void wlc_phy_txpwr_apply_nphy(struct brcms_phy *pi) pwr_offsets1[0] = (u16) (pi->ofdm5gpo & 0xffff); pwr_offsets1[1] = - (u16) (pi->ofdm5gpo >> 16) & 0xffff; + (u16) (pi->ofdm5gpo >> 16) & 0xffff; pwr_offsets2 = pi->mcs5gpo; @@ -27653,7 +28131,7 @@ void wlc_phy_txpwr_apply_nphy(struct brcms_phy *pi) pwr_offsets1[0] = (u16) (pi->ofdm5glpo & 0xffff); pwr_offsets1[1] = - (u16) (pi->ofdm5glpo >> 16) & 0xffff; + (u16) (pi->ofdm5glpo >> 16) & 0xffff; pwr_offsets2 = pi->mcs5glpo; @@ -27670,7 +28148,7 @@ void wlc_phy_txpwr_apply_nphy(struct brcms_phy *pi) pwr_offsets1[0] = (u16) (pi->ofdm5ghpo & 0xffff); pwr_offsets1[1] = - (u16) (pi->ofdm5ghpo >> 16) & 0xffff; + (u16) (pi->ofdm5ghpo >> 16) & 0xffff; pwr_offsets2 = pi->mcs5ghpo; @@ -27696,12 +28174,10 @@ void wlc_phy_txpwr_apply_nphy(struct brcms_phy *pi) TXP_FIRST_MCS_20_CDD, TXP_LAST_MCS_20_CDD); - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - + if (NREV_GE(pi->pubpi.phy_rev, 3)) wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate, tmp_cddpo, TXP_FIRST_MCS_20_CDD, TXP_LAST_MCS_20_CDD); - } wlc_phy_mcs_to_ofdm_powers_nphy(tx_srom_max_rate, TXP_FIRST_OFDM_20_CDD, @@ -27713,13 +28189,11 @@ void wlc_phy_txpwr_apply_nphy(struct brcms_phy *pi) TXP_FIRST_MCS_20_STBC, TXP_LAST_MCS_20_STBC); - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - + if (NREV_GE(pi->pubpi.phy_rev, 3)) wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate, tmp_stbcpo, TXP_FIRST_MCS_20_STBC, TXP_LAST_MCS_20_STBC); - } wlc_phy_txpwr_nphy_srom_convert(tx_srom_max_rate, &pwr_offsets2[2], tmp_max_pwr, @@ -27773,294 +28247,26 @@ void wlc_phy_txpwr_apply_nphy(struct brcms_phy *pi) } else { for (rate1 = TXP_FIRST_OFDM_40_SISO, rate2 = - TXP_FIRST_OFDM; rate1 <= TXP_LAST_MCS_40_SDM; + TXP_FIRST_OFDM; + rate1 <= TXP_LAST_MCS_40_SDM; rate1++, rate2++) tx_srom_max_rate[rate1] = - tx_srom_max_rate[rate2]; + tx_srom_max_rate[rate2]; } - if (NREV_GE(pi->pubpi.phy_rev, 3)) { + if (NREV_GE(pi->pubpi.phy_rev, 3)) wlc_phy_txpwr_nphy_po_apply(tx_srom_max_rate, tmp_bw40po, TXP_FIRST_OFDM_40_SISO, TXP_LAST_MCS_40_SDM); - } tx_srom_max_rate[TXP_MCS_32] = - tx_srom_max_rate[TXP_FIRST_MCS_40_CDD]; + tx_srom_max_rate[TXP_FIRST_MCS_40_CDD]; } return; } -static void wlc_phy_txpwr_srom_read_ppr_nphy(struct brcms_phy *pi) -{ - u16 bw40po, cddpo, stbcpo, bwduppo; - uint band_num; - - if (pi->sh->sromrev >= 9) { - - return; - } - - bw40po = (u16) PHY_GETINTVAR(pi, "bw40po"); - pi->bw402gpo = bw40po & 0xf; - pi->bw405gpo = (bw40po & 0xf0) >> 4; - pi->bw405glpo = (bw40po & 0xf00) >> 8; - pi->bw405ghpo = (bw40po & 0xf000) >> 12; - - cddpo = (u16) PHY_GETINTVAR(pi, "cddpo"); - pi->cdd2gpo = cddpo & 0xf; - pi->cdd5gpo = (cddpo & 0xf0) >> 4; - pi->cdd5glpo = (cddpo & 0xf00) >> 8; - pi->cdd5ghpo = (cddpo & 0xf000) >> 12; - - stbcpo = (u16) PHY_GETINTVAR(pi, "stbcpo"); - pi->stbc2gpo = stbcpo & 0xf; - pi->stbc5gpo = (stbcpo & 0xf0) >> 4; - pi->stbc5glpo = (stbcpo & 0xf00) >> 8; - pi->stbc5ghpo = (stbcpo & 0xf000) >> 12; - - bwduppo = (u16) PHY_GETINTVAR(pi, "bwduppo"); - pi->bwdup2gpo = bwduppo & 0xf; - pi->bwdup5gpo = (bwduppo & 0xf0) >> 4; - pi->bwdup5glpo = (bwduppo & 0xf00) >> 8; - pi->bwdup5ghpo = (bwduppo & 0xf000) >> 12; - - for (band_num = 0; band_num < (CH_2G_GROUP + CH_5G_GROUP); band_num++) { - switch (band_num) { - case 0: - - pi->nphy_txpid2g[PHY_CORE_0] = - (u8) PHY_GETINTVAR(pi, "txpid2ga0"); - pi->nphy_txpid2g[PHY_CORE_1] = - (u8) PHY_GETINTVAR(pi, "txpid2ga1"); - pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_2g = - (s8) PHY_GETINTVAR(pi, "maxp2ga0"); - pi->nphy_pwrctrl_info[PHY_CORE_1].max_pwr_2g = - (s8) PHY_GETINTVAR(pi, "maxp2ga1"); - pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_a1 = - (s16) PHY_GETINTVAR(pi, "pa2gw0a0"); - pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_a1 = - (s16) PHY_GETINTVAR(pi, "pa2gw0a1"); - pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_b0 = - (s16) PHY_GETINTVAR(pi, "pa2gw1a0"); - pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_b0 = - (s16) PHY_GETINTVAR(pi, "pa2gw1a1"); - pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_2g_b1 = - (s16) PHY_GETINTVAR(pi, "pa2gw2a0"); - pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_2g_b1 = - (s16) PHY_GETINTVAR(pi, "pa2gw2a1"); - pi->nphy_pwrctrl_info[PHY_CORE_0].idle_targ_2g = - (s8) PHY_GETINTVAR(pi, "itt2ga0"); - pi->nphy_pwrctrl_info[PHY_CORE_1].idle_targ_2g = - (s8) PHY_GETINTVAR(pi, "itt2ga1"); - - pi->cck2gpo = (u16) PHY_GETINTVAR(pi, "cck2gpo"); - - pi->ofdm2gpo = (u32) PHY_GETINTVAR(pi, "ofdm2gpo"); - - pi->mcs2gpo[0] = (u16) PHY_GETINTVAR(pi, "mcs2gpo0"); - pi->mcs2gpo[1] = (u16) PHY_GETINTVAR(pi, "mcs2gpo1"); - pi->mcs2gpo[2] = (u16) PHY_GETINTVAR(pi, "mcs2gpo2"); - pi->mcs2gpo[3] = (u16) PHY_GETINTVAR(pi, "mcs2gpo3"); - pi->mcs2gpo[4] = (u16) PHY_GETINTVAR(pi, "mcs2gpo4"); - pi->mcs2gpo[5] = (u16) PHY_GETINTVAR(pi, "mcs2gpo5"); - pi->mcs2gpo[6] = (u16) PHY_GETINTVAR(pi, "mcs2gpo6"); - pi->mcs2gpo[7] = (u16) PHY_GETINTVAR(pi, "mcs2gpo7"); - break; - case 1: - - pi->nphy_txpid5g[PHY_CORE_0] = - (u8) PHY_GETINTVAR(pi, "txpid5ga0"); - pi->nphy_txpid5g[PHY_CORE_1] = - (u8) PHY_GETINTVAR(pi, "txpid5ga1"); - pi->nphy_pwrctrl_info[PHY_CORE_0].max_pwr_5gm = - (s8) PHY_GETINTVAR(pi, "maxp5ga0"); - pi->nphy_pwrctrl_info[PHY_CORE_1].max_pwr_5gm = - (s8) PHY_GETINTVAR(pi, "maxp5ga1"); - pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_a1 = - (s16) PHY_GETINTVAR(pi, "pa5gw0a0"); - pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_a1 = - (s16) PHY_GETINTVAR(pi, "pa5gw0a1"); - pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_b0 = - (s16) PHY_GETINTVAR(pi, "pa5gw1a0"); - pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_b0 = - (s16) PHY_GETINTVAR(pi, "pa5gw1a1"); - pi->nphy_pwrctrl_info[PHY_CORE_0].pwrdet_5gm_b1 = - (s16) PHY_GETINTVAR(pi, "pa5gw2a0"); - pi->nphy_pwrctrl_info[PHY_CORE_1].pwrdet_5gm_b1 = - (s16) PHY_GETINTVAR(pi, "pa5gw2a1"); - pi->nphy_pwrctrl_info[PHY_CORE_0].idle_targ_5gm = - (s8) PHY_GETINTVAR(pi, "itt5ga0"); - pi->nphy_pwrctrl_info[PHY_CORE_1].idle_targ_5gm = - (s8) PHY_GETINTVAR(pi, "itt5ga1"); - - pi->ofdm5gpo = (u32) PHY_GETINTVAR(pi, "ofdm5gpo"); - - pi->mcs5gpo[0] = (u16) PHY_GETINTVAR(pi, "mcs5gpo0"); - pi->mcs5gpo[1] = (u16) PHY_GETINTVAR(pi, "mcs5gpo1"); - pi->mcs5gpo[2] = (u16) PHY_GETINTVAR(pi, "mcs5gpo2"); - pi->mcs5gpo[3] = (u16) PHY_GETINTVAR(pi, "mcs5gpo3"); - pi->mcs5gpo[4] = (u16) PHY_GETINTVAR(pi, "mcs5gpo4"); - pi->mcs5gpo[5] = (u16) PHY_GETINTVAR(pi, "mcs5gpo5"); - pi->mcs5gpo[6] = (u16) PHY_GETINTVAR(pi, "mcs5gpo6"); - pi->mcs5gpo[7] = (u16) PHY_GETINTVAR(pi, "mcs5gpo7"); - break; - case 2: - - pi->nphy_txpid5gl[0] = - (u8) PHY_GETINTVAR(pi, "txpid5gla0"); - pi->nphy_txpid5gl[1] = - (u8) PHY_GETINTVAR(pi, "txpid5gla1"); - pi->nphy_pwrctrl_info[0].max_pwr_5gl = - (s8) PHY_GETINTVAR(pi, "maxp5gla0"); - pi->nphy_pwrctrl_info[1].max_pwr_5gl = - (s8) PHY_GETINTVAR(pi, "maxp5gla1"); - pi->nphy_pwrctrl_info[0].pwrdet_5gl_a1 = - (s16) PHY_GETINTVAR(pi, "pa5glw0a0"); - pi->nphy_pwrctrl_info[1].pwrdet_5gl_a1 = - (s16) PHY_GETINTVAR(pi, "pa5glw0a1"); - pi->nphy_pwrctrl_info[0].pwrdet_5gl_b0 = - (s16) PHY_GETINTVAR(pi, "pa5glw1a0"); - pi->nphy_pwrctrl_info[1].pwrdet_5gl_b0 = - (s16) PHY_GETINTVAR(pi, "pa5glw1a1"); - pi->nphy_pwrctrl_info[0].pwrdet_5gl_b1 = - (s16) PHY_GETINTVAR(pi, "pa5glw2a0"); - pi->nphy_pwrctrl_info[1].pwrdet_5gl_b1 = - (s16) PHY_GETINTVAR(pi, "pa5glw2a1"); - pi->nphy_pwrctrl_info[0].idle_targ_5gl = 0; - pi->nphy_pwrctrl_info[1].idle_targ_5gl = 0; - - pi->ofdm5glpo = (u32) PHY_GETINTVAR(pi, "ofdm5glpo"); - - pi->mcs5glpo[0] = - (u16) PHY_GETINTVAR(pi, "mcs5glpo0"); - pi->mcs5glpo[1] = - (u16) PHY_GETINTVAR(pi, "mcs5glpo1"); - pi->mcs5glpo[2] = - (u16) PHY_GETINTVAR(pi, "mcs5glpo2"); - pi->mcs5glpo[3] = - (u16) PHY_GETINTVAR(pi, "mcs5glpo3"); - pi->mcs5glpo[4] = - (u16) PHY_GETINTVAR(pi, "mcs5glpo4"); - pi->mcs5glpo[5] = - (u16) PHY_GETINTVAR(pi, "mcs5glpo5"); - pi->mcs5glpo[6] = - (u16) PHY_GETINTVAR(pi, "mcs5glpo6"); - pi->mcs5glpo[7] = - (u16) PHY_GETINTVAR(pi, "mcs5glpo7"); - break; - case 3: - - pi->nphy_txpid5gh[0] = - (u8) PHY_GETINTVAR(pi, "txpid5gha0"); - pi->nphy_txpid5gh[1] = - (u8) PHY_GETINTVAR(pi, "txpid5gha1"); - pi->nphy_pwrctrl_info[0].max_pwr_5gh = - (s8) PHY_GETINTVAR(pi, "maxp5gha0"); - pi->nphy_pwrctrl_info[1].max_pwr_5gh = - (s8) PHY_GETINTVAR(pi, "maxp5gha1"); - pi->nphy_pwrctrl_info[0].pwrdet_5gh_a1 = - (s16) PHY_GETINTVAR(pi, "pa5ghw0a0"); - pi->nphy_pwrctrl_info[1].pwrdet_5gh_a1 = - (s16) PHY_GETINTVAR(pi, "pa5ghw0a1"); - pi->nphy_pwrctrl_info[0].pwrdet_5gh_b0 = - (s16) PHY_GETINTVAR(pi, "pa5ghw1a0"); - pi->nphy_pwrctrl_info[1].pwrdet_5gh_b0 = - (s16) PHY_GETINTVAR(pi, "pa5ghw1a1"); - pi->nphy_pwrctrl_info[0].pwrdet_5gh_b1 = - (s16) PHY_GETINTVAR(pi, "pa5ghw2a0"); - pi->nphy_pwrctrl_info[1].pwrdet_5gh_b1 = - (s16) PHY_GETINTVAR(pi, "pa5ghw2a1"); - pi->nphy_pwrctrl_info[0].idle_targ_5gh = 0; - pi->nphy_pwrctrl_info[1].idle_targ_5gh = 0; - - pi->ofdm5ghpo = (u32) PHY_GETINTVAR(pi, "ofdm5ghpo"); - - pi->mcs5ghpo[0] = - (u16) PHY_GETINTVAR(pi, "mcs5ghpo0"); - pi->mcs5ghpo[1] = - (u16) PHY_GETINTVAR(pi, "mcs5ghpo1"); - pi->mcs5ghpo[2] = - (u16) PHY_GETINTVAR(pi, "mcs5ghpo2"); - pi->mcs5ghpo[3] = - (u16) PHY_GETINTVAR(pi, "mcs5ghpo3"); - pi->mcs5ghpo[4] = - (u16) PHY_GETINTVAR(pi, "mcs5ghpo4"); - pi->mcs5ghpo[5] = - (u16) PHY_GETINTVAR(pi, "mcs5ghpo5"); - pi->mcs5ghpo[6] = - (u16) PHY_GETINTVAR(pi, "mcs5ghpo6"); - pi->mcs5ghpo[7] = - (u16) PHY_GETINTVAR(pi, "mcs5ghpo7"); - break; - } - } - - wlc_phy_txpwr_apply_nphy(pi); -} - -static bool wlc_phy_txpwr_srom_read_nphy(struct brcms_phy *pi) -{ - - pi->antswitch = (u8) PHY_GETINTVAR(pi, "antswitch"); - pi->aa2g = (u8) PHY_GETINTVAR(pi, "aa2g"); - pi->aa5g = (u8) PHY_GETINTVAR(pi, "aa5g"); - - pi->srom_fem2g.tssipos = (u8) PHY_GETINTVAR(pi, "tssipos2g"); - pi->srom_fem2g.extpagain = (u8) PHY_GETINTVAR(pi, "extpagain2g"); - pi->srom_fem2g.pdetrange = (u8) PHY_GETINTVAR(pi, "pdetrange2g"); - pi->srom_fem2g.triso = (u8) PHY_GETINTVAR(pi, "triso2g"); - pi->srom_fem2g.antswctrllut = (u8) PHY_GETINTVAR(pi, "antswctl2g"); - - pi->srom_fem5g.tssipos = (u8) PHY_GETINTVAR(pi, "tssipos5g"); - pi->srom_fem5g.extpagain = (u8) PHY_GETINTVAR(pi, "extpagain5g"); - pi->srom_fem5g.pdetrange = (u8) PHY_GETINTVAR(pi, "pdetrange5g"); - pi->srom_fem5g.triso = (u8) PHY_GETINTVAR(pi, "triso5g"); - if (PHY_GETVAR(pi, "antswctl5g")) { - - pi->srom_fem5g.antswctrllut = - (u8) PHY_GETINTVAR(pi, "antswctl5g"); - } else { - - pi->srom_fem5g.antswctrllut = - (u8) PHY_GETINTVAR(pi, "antswctl2g"); - } - - wlc_phy_txpower_ipa_upd(pi); - - pi->phy_txcore_disable_temp = (s16) PHY_GETINTVAR(pi, "tempthresh"); - if (pi->phy_txcore_disable_temp == 0) { - pi->phy_txcore_disable_temp = PHY_CHAIN_TX_DISABLE_TEMP; - } - - pi->phy_tempsense_offset = (s8) PHY_GETINTVAR(pi, "tempoffset"); - if (pi->phy_tempsense_offset != 0) { - if (pi->phy_tempsense_offset > - (NPHY_SROM_TEMPSHIFT + NPHY_SROM_MAXTEMPOFFSET)) { - pi->phy_tempsense_offset = NPHY_SROM_MAXTEMPOFFSET; - } else if (pi->phy_tempsense_offset < (NPHY_SROM_TEMPSHIFT + - NPHY_SROM_MINTEMPOFFSET)) { - pi->phy_tempsense_offset = NPHY_SROM_MINTEMPOFFSET; - } else { - pi->phy_tempsense_offset -= NPHY_SROM_TEMPSHIFT; - } - } - - pi->phy_txcore_enable_temp = - pi->phy_txcore_disable_temp - PHY_HYSTERESIS_DELTATEMP; - - pi->phycal_tempdelta = (u8) PHY_GETINTVAR(pi, "phycal_tempdelta"); - if (pi->phycal_tempdelta > NPHY_CAL_MAXTEMPDELTA) { - pi->phycal_tempdelta = 0; - } - - wlc_phy_txpwr_srom_read_ppr_nphy(pi); - - return true; -} - void wlc_phy_txpower_recalc_target_nphy(struct brcms_phy *pi) { u8 tx_pwr_ctrl_state; @@ -28081,512 +28287,10 @@ void wlc_phy_txpower_recalc_target_nphy(struct brcms_phy *pi) wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, 0); } -static void wlc_phy_txpwrctrl_coeff_setup_nphy(struct brcms_phy *pi) -{ - u32 idx; - u16 iqloCalbuf[7]; - u32 iqcomp, locomp, curr_locomp; - s8 locomp_i, locomp_q; - s8 curr_locomp_i, curr_locomp_q; - u32 tbl_id, tbl_len, tbl_offset; - u32 regval[128]; - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, true); - - wlc_phy_table_read_nphy(pi, 15, 7, 80, 16, iqloCalbuf); - - tbl_len = 128; - tbl_offset = 320; - for (tbl_id = NPHY_TBL_ID_CORE1TXPWRCTL; - tbl_id <= NPHY_TBL_ID_CORE2TXPWRCTL; tbl_id++) { - iqcomp = - (tbl_id == - 26) ? (((u32) (iqloCalbuf[0] & 0x3ff)) << 10) | - (iqloCalbuf[1] & 0x3ff) - : (((u32) (iqloCalbuf[2] & 0x3ff)) << 10) | - (iqloCalbuf[3] & 0x3ff); - - for (idx = 0; idx < tbl_len; idx++) { - regval[idx] = iqcomp; - } - wlc_phy_table_write_nphy(pi, tbl_id, tbl_len, tbl_offset, 32, - regval); - } - - tbl_offset = 448; - for (tbl_id = NPHY_TBL_ID_CORE1TXPWRCTL; - tbl_id <= NPHY_TBL_ID_CORE2TXPWRCTL; tbl_id++) { - - locomp = - (u32) ((tbl_id == 26) ? iqloCalbuf[5] : iqloCalbuf[6]); - locomp_i = (s8) ((locomp >> 8) & 0xff); - locomp_q = (s8) ((locomp) & 0xff); - for (idx = 0; idx < tbl_len; idx++) { - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - curr_locomp_i = locomp_i; - curr_locomp_q = locomp_q; - } else { - curr_locomp_i = (s8) ((locomp_i * - nphy_tpc_loscale[idx] + - 128) >> 8); - curr_locomp_q = - (s8) ((locomp_q * nphy_tpc_loscale[idx] + - 128) >> 8); - } - curr_locomp = (u32) ((curr_locomp_i & 0xff) << 8); - curr_locomp |= (u32) (curr_locomp_q & 0xff); - regval[idx] = curr_locomp; - } - wlc_phy_table_write_nphy(pi, tbl_id, tbl_len, tbl_offset, 32, - regval); - } - - if (NREV_LT(pi->pubpi.phy_rev, 2)) { - - wlapi_bmac_write_shm(pi->sh->physhim, M_CURR_IDX1, 0xFFFF); - wlapi_bmac_write_shm(pi->sh->physhim, M_CURR_IDX2, 0xFFFF); - } - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, false); -} - -static void wlc_phy_ipa_internal_tssi_setup_nphy(struct brcms_phy *pi) -{ - u8 core; - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - for (core = 0; core < pi->pubpi.phy_corenum; core++) { - if (CHSPEC_IS2G(pi->radio_chanspec)) { - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TX_SSI_MASTER, 0x5); - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TX_SSI_MUX, 0xe); - - if (pi->pubpi.radiorev != 5) - WRITE_RADIO_REG3(pi, RADIO_2057, TX, - core, TSSIA, 0); - - if (!NREV_IS(pi->pubpi.phy_rev, 7)) { - - WRITE_RADIO_REG3(pi, RADIO_2057, TX, - core, TSSIG, 0x1); - } else { - - WRITE_RADIO_REG3(pi, RADIO_2057, TX, - core, TSSIG, 0x31); - } - } else { - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TX_SSI_MASTER, 0x9); - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TX_SSI_MUX, 0xc); - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, - TSSIG, 0); - - if (pi->pubpi.radiorev != 5) { - if (!NREV_IS(pi->pubpi.phy_rev, 7)) { - - WRITE_RADIO_REG3(pi, RADIO_2057, - TX, core, - TSSIA, 0x1); - } else { - - WRITE_RADIO_REG3(pi, RADIO_2057, - TX, core, - TSSIA, 0x31); - } - } - } - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_VCM_HG, - 0); - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, IQCAL_IDAC, - 0); - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_VCM, - 0x3); - WRITE_RADIO_REG3(pi, RADIO_2057, TX, core, TSSI_MISC1, - 0x0); - } - } else { - WRITE_RADIO_SYN(pi, RADIO_2056, RESERVED_ADDR31, - (CHSPEC_IS2G(pi->radio_chanspec)) ? 0x128 : - 0x80); - WRITE_RADIO_SYN(pi, RADIO_2056, RESERVED_ADDR30, 0x0); - WRITE_RADIO_SYN(pi, RADIO_2056, GPIO_MASTER1, 0x29); - - for (core = 0; core < pi->pubpi.phy_corenum; core++) { - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, IQCAL_VCM_HG, - 0x0); - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, IQCAL_IDAC, - 0x0); - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_VCM, - 0x3); - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TX_AMP_DET, - 0x0); - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_MISC1, - 0x8); - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_MISC2, - 0x0); - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, TSSI_MISC3, - 0x0); - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - TX_SSI_MASTER, 0x5); - - if (pi->pubpi.radiorev != 5) - WRITE_RADIO_REG2(pi, RADIO_2056, TX, - core, TSSIA, 0x0); - if (NREV_GE(pi->pubpi.phy_rev, 5)) { - - WRITE_RADIO_REG2(pi, RADIO_2056, TX, - core, TSSIG, 0x31); - } else { - WRITE_RADIO_REG2(pi, RADIO_2056, TX, - core, TSSIG, 0x11); - } - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - TX_SSI_MUX, 0xe); - } else { - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - TX_SSI_MASTER, 0x9); - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - TSSIA, 0x31); - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - TSSIG, 0x0); - WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, - TX_SSI_MUX, 0xc); - } - } - } -} - -static void wlc_phy_txpwrctrl_idle_tssi_nphy(struct brcms_phy *pi) -{ - s32 rssi_buf[4]; - s32 int_val; - - if (SCAN_RM_IN_PROGRESS(pi) || PLT_INPROG_PHY(pi) || PHY_MUTED(pi)) - - return; - - if (PHY_IPA(pi)) { - wlc_phy_ipa_internal_tssi_setup_nphy(pi); - } - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12), - 0, 0x3, 0, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 13), 0, 3, 0); - } - - wlc_phy_stopplayback_nphy(pi); - - wlc_phy_tx_tone_nphy(pi, 4000, 0, 0, 0, false); - - udelay(20); - int_val = - wlc_phy_poll_rssi_nphy(pi, (u8) NPHY_RSSI_SEL_TSSI_2G, rssi_buf, - 1); - wlc_phy_stopplayback_nphy(pi); - wlc_phy_rssisel_nphy(pi, RADIO_MIMO_CORESEL_OFF, 0); - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - wlc_phy_rfctrl_override_nphy_rev7(pi, (0x1 << 12), - 0, 0x3, 1, - NPHY_REV7_RFCTRLOVERRIDE_ID0); - } else if (NREV_GE(pi->pubpi.phy_rev, 3)) { - wlc_phy_rfctrl_override_nphy(pi, (0x1 << 13), 0, 3, 1); - } - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - - pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_2g = - (u8) ((int_val >> 24) & 0xff); - pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_5g = - (u8) ((int_val >> 24) & 0xff); - - pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_2g = - (u8) ((int_val >> 8) & 0xff); - pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_5g = - (u8) ((int_val >> 8) & 0xff); - } else { - pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_2g = - (u8) ((int_val >> 24) & 0xff); - - pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_2g = - (u8) ((int_val >> 8) & 0xff); - - pi->nphy_pwrctrl_info[PHY_CORE_0].idle_tssi_5g = - (u8) ((int_val >> 16) & 0xff); - pi->nphy_pwrctrl_info[PHY_CORE_1].idle_tssi_5g = - (u8) ((int_val) & 0xff); - } - -} - -static void wlc_phy_txpwrctrl_pwr_setup_nphy(struct brcms_phy *pi) -{ - u32 idx; - s16 a1[2], b0[2], b1[2]; - s8 target_pwr_qtrdbm[2]; - s32 num, den, pwr_est; - u8 chan_freq_range; - u8 idle_tssi[2]; - u32 tbl_id, tbl_len, tbl_offset; - u32 regval[64]; - u8 core; - - if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) { - wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK); - (void)R_REG(&pi->regs->maccontrol); - udelay(1); - } - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, true); - - or_phy_reg(pi, 0x122, (0x1 << 0)); - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - and_phy_reg(pi, 0x1e7, (u16) (~(0x1 << 15))); - } else { - - or_phy_reg(pi, 0x1e7, (0x1 << 15)); - } - - if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) - wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, 0); - - if (pi->sh->sromrev < 4) { - idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g; - idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g; - target_pwr_qtrdbm[0] = 13 * 4; - target_pwr_qtrdbm[1] = 13 * 4; - a1[0] = -424; - a1[1] = -424; - b0[0] = 5612; - b0[1] = 5612; - b1[1] = -1393; - b1[0] = -1393; - } else { - - chan_freq_range = wlc_phy_get_chan_freq_range_nphy(pi, 0); - switch (chan_freq_range) { - case WL_CHAN_FREQ_RANGE_2G: - idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g; - idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g; - target_pwr_qtrdbm[0] = - pi->nphy_pwrctrl_info[0].max_pwr_2g; - target_pwr_qtrdbm[1] = - pi->nphy_pwrctrl_info[1].max_pwr_2g; - a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_a1; - a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_a1; - b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_b0; - b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_b0; - b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_2g_b1; - b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_2g_b1; - break; - case WL_CHAN_FREQ_RANGE_5GL: - idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g; - idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g; - target_pwr_qtrdbm[0] = - pi->nphy_pwrctrl_info[0].max_pwr_5gl; - target_pwr_qtrdbm[1] = - pi->nphy_pwrctrl_info[1].max_pwr_5gl; - a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_a1; - a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_a1; - b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_b0; - b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_b0; - b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gl_b1; - b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gl_b1; - break; - case WL_CHAN_FREQ_RANGE_5GM: - idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g; - idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g; - target_pwr_qtrdbm[0] = - pi->nphy_pwrctrl_info[0].max_pwr_5gm; - target_pwr_qtrdbm[1] = - pi->nphy_pwrctrl_info[1].max_pwr_5gm; - a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_a1; - a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_a1; - b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_b0; - b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_b0; - b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gm_b1; - b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gm_b1; - break; - case WL_CHAN_FREQ_RANGE_5GH: - idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_5g; - idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_5g; - target_pwr_qtrdbm[0] = - pi->nphy_pwrctrl_info[0].max_pwr_5gh; - target_pwr_qtrdbm[1] = - pi->nphy_pwrctrl_info[1].max_pwr_5gh; - a1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_a1; - a1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_a1; - b0[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_b0; - b0[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_b0; - b1[0] = pi->nphy_pwrctrl_info[0].pwrdet_5gh_b1; - b1[1] = pi->nphy_pwrctrl_info[1].pwrdet_5gh_b1; - break; - default: - idle_tssi[0] = pi->nphy_pwrctrl_info[0].idle_tssi_2g; - idle_tssi[1] = pi->nphy_pwrctrl_info[1].idle_tssi_2g; - target_pwr_qtrdbm[0] = 13 * 4; - target_pwr_qtrdbm[1] = 13 * 4; - a1[0] = -424; - a1[1] = -424; - b0[0] = 5612; - b0[1] = 5612; - b1[1] = -1393; - b1[0] = -1393; - break; - } - } - - target_pwr_qtrdbm[0] = (s8) pi->tx_power_max; - target_pwr_qtrdbm[1] = (s8) pi->tx_power_max; - - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - if (pi->srom_fem2g.tssipos) { - or_phy_reg(pi, 0x1e9, (0x1 << 14)); - } - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - for (core = 0; core <= 1; core++) { - if (PHY_IPA(pi)) { - - if (CHSPEC_IS2G(pi->radio_chanspec)) { - WRITE_RADIO_REG3(pi, RADIO_2057, - TX, core, - TX_SSI_MUX, - 0xe); - } else { - WRITE_RADIO_REG3(pi, RADIO_2057, - TX, core, - TX_SSI_MUX, - 0xc); - } - } else { - } - } - } else { - if (PHY_IPA(pi)) { - - write_radio_reg(pi, RADIO_2056_TX_TX_SSI_MUX | - RADIO_2056_TX0, - (CHSPEC_IS5G - (pi-> - radio_chanspec)) ? 0xc : 0xe); - write_radio_reg(pi, - RADIO_2056_TX_TX_SSI_MUX | - RADIO_2056_TX1, - (CHSPEC_IS5G - (pi-> - radio_chanspec)) ? 0xc : 0xe); - } else { - - write_radio_reg(pi, RADIO_2056_TX_TX_SSI_MUX | - RADIO_2056_TX0, 0x11); - write_radio_reg(pi, RADIO_2056_TX_TX_SSI_MUX | - RADIO_2056_TX1, 0x11); - } - } - } - - if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) { - wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, MCTL_PHYLOCK); - (void)R_REG(&pi->regs->maccontrol); - udelay(1); - } - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - mod_phy_reg(pi, 0x1e7, (0x7f << 0), - (NPHY_TxPwrCtrlCmd_pwrIndex_init_rev7 << 0)); - } else { - mod_phy_reg(pi, 0x1e7, (0x7f << 0), - (NPHY_TxPwrCtrlCmd_pwrIndex_init << 0)); - } - - if (NREV_GE(pi->pubpi.phy_rev, 7)) { - mod_phy_reg(pi, 0x222, (0xff << 0), - (NPHY_TxPwrCtrlCmd_pwrIndex_init_rev7 << 0)); - } else if (NREV_GT(pi->pubpi.phy_rev, 1)) { - mod_phy_reg(pi, 0x222, (0xff << 0), - (NPHY_TxPwrCtrlCmd_pwrIndex_init << 0)); - } - - if (D11REV_IS(pi->sh->corerev, 11) || D11REV_IS(pi->sh->corerev, 12)) - wlapi_bmac_mctrl(pi->sh->physhim, MCTL_PHYLOCK, 0); - - write_phy_reg(pi, 0x1e8, (0x3 << 8) | (240 << 0)); - - write_phy_reg(pi, 0x1e9, - (1 << 15) | (idle_tssi[0] << 0) | (idle_tssi[1] << 8)); - - write_phy_reg(pi, 0x1ea, - (target_pwr_qtrdbm[0] << 0) | - (target_pwr_qtrdbm[1] << 8)); - - tbl_len = 64; - tbl_offset = 0; - for (tbl_id = NPHY_TBL_ID_CORE1TXPWRCTL; - tbl_id <= NPHY_TBL_ID_CORE2TXPWRCTL; tbl_id++) { - - for (idx = 0; idx < tbl_len; idx++) { - num = - 8 * (16 * b0[tbl_id - 26] + b1[tbl_id - 26] * idx); - den = 32768 + a1[tbl_id - 26] * idx; - pwr_est = max(((4 * num + den / 2) / den), -8); - if (NREV_LT(pi->pubpi.phy_rev, 3)) { - if (idx <= - (uint) (31 - idle_tssi[tbl_id - 26] + 1)) - pwr_est = - max(pwr_est, - target_pwr_qtrdbm[tbl_id - 26] + - 1); - } - regval[idx] = (u32) pwr_est; - } - wlc_phy_table_write_nphy(pi, tbl_id, tbl_len, tbl_offset, 32, - regval); - } - - wlc_phy_txpwr_limit_to_tbl_nphy(pi); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE1TXPWRCTL, 84, 64, 8, - pi->adj_pwr_tbl_nphy); - wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_CORE2TXPWRCTL, 84, 64, 8, - pi->adj_pwr_tbl_nphy); - - if (pi->phyhang_avoid) - wlc_phy_stay_in_carriersearch_nphy(pi, false); -} - static bool wlc_phy_txpwr_ison_nphy(struct brcms_phy *pi) { return read_phy_reg((pi), 0x1e7) & ((0x1 << 15) | - (0x1 << 14) | (0x1 << 13)); -} - -static u8 wlc_phy_txpwr_idx_cur_get_nphy(struct brcms_phy *pi, u8 core) -{ - u16 tmp; - tmp = read_phy_reg(pi, ((core == PHY_CORE_0) ? 0x1ed : 0x1ee)); - - tmp = (tmp & (0x7f << 8)) >> 8; - return (u8) tmp; -} - -static void -wlc_phy_txpwr_idx_cur_set_nphy(struct brcms_phy *pi, u8 idx0, u8 idx1) -{ - mod_phy_reg(pi, 0x1e7, (0x7f << 0), idx0); - - if (NREV_GT(pi->pubpi.phy_rev, 1)) - mod_phy_reg(pi, 0x222, (0xff << 0), idx1); + (0x1 << 14) | (0x1 << 13)); } u16 wlc_phy_txpwr_idx_get_nphy(struct brcms_phy *pi) @@ -28600,12 +28304,9 @@ u16 wlc_phy_txpwr_idx_get_nphy(struct brcms_phy *pi) tmp = (pwr_idx[0] << 8) | pwr_idx[1]; } else { - tmp = - ((pi->nphy_txpwrindex[PHY_CORE_0]. - index_internal & 0xff) << 8) | (pi-> - nphy_txpwrindex - [PHY_CORE_1]. - index_internal & 0xff); + tmp = ((pi->nphy_txpwrindex[PHY_CORE_0].index_internal & 0xff) + << 8) | + (pi->nphy_txpwrindex[PHY_CORE_1].index_internal & 0xff); } return tmp; @@ -28622,9 +28323,8 @@ void wlc_phy_txpwr_papd_cal_nphy(struct brcms_phy *pi) pi->nphy_papd_tx_gain_at_last_cal[0]) >= 4) || ((u32) ABS(wlc_phy_txpwr_idx_cur_get_nphy(pi, 1) - - pi->nphy_papd_tx_gain_at_last_cal[1]) >= 4))))) { + pi->nphy_papd_tx_gain_at_last_cal[1]) >= 4))))) wlc_phy_a4(pi, true); - } } void wlc_phy_txpwrctrl_enable_nphy(struct brcms_phy *pi, u8 ctrl_type) @@ -28655,32 +28355,29 @@ void wlc_phy_txpwrctrl_enable_nphy(struct brcms_phy *pi, u8 ctrl_type) for (core = 0; core < pi->pubpi.phy_corenum; core++) pi->nphy_txpwr_idx[core] = - wlc_phy_txpwr_idx_cur_get_nphy(pi, - (u8) - core); + wlc_phy_txpwr_idx_cur_get_nphy( + pi, + (u8) core); } } tbl_len = 84; tbl_offset = 64; - for (ctr = 0; ctr < tbl_len; ctr++) { + for (ctr = 0; ctr < tbl_len; ctr++) regval[ctr] = 0; - } wlc_phy_table_write_nphy(pi, 26, tbl_len, tbl_offset, 16, regval); wlc_phy_table_write_nphy(pi, 27, tbl_len, tbl_offset, 16, regval); - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - + if (NREV_GE(pi->pubpi.phy_rev, 3)) and_phy_reg(pi, 0x1e7, (u16) (~((0x1 << 15) | - (0x1 << 14) | (0x1 << 13)))); - } else { + (0x1 << 14) | (0x1 << 13)))); + else and_phy_reg(pi, 0x1e7, (u16) (~((0x1 << 14) | (0x1 << 13)))); - } if (NREV_GE(pi->pubpi.phy_rev, 3)) { or_phy_reg(pi, 0x8f, (0x1 << 8)); @@ -28730,7 +28427,7 @@ void wlc_phy_txpwrctrl_enable_nphy(struct brcms_phy *pi, u8 ctrl_type) if (NREV_GE(pi->pubpi.phy_rev, 3)) { if ((pi->nphy_txpwr_idx[0] != 128) - && (pi->nphy_txpwr_idx[1] != 128)) { + && (pi->nphy_txpwr_idx[1] != 128)) wlc_phy_txpwr_idx_cur_set_nphy(pi, pi-> nphy_txpwr_idx @@ -28738,7 +28435,6 @@ void wlc_phy_txpwrctrl_enable_nphy(struct brcms_phy *pi, u8 ctrl_type) pi-> nphy_txpwr_idx [1]); - } } if (NREV_GE(pi->pubpi.phy_rev, 3)) { @@ -28799,17 +28495,14 @@ wlc_phy_txpwr_index_nphy(struct brcms_phy *pi, u8 core_mask, s8 txpwrindex, for (core = 0; core < pi->pubpi.phy_corenum; core++) { - if ((core_mask & (1 << core)) == 0) { + if ((core_mask & (1 << core)) == 0) continue; - } txpwrctl_tbl = (core == PHY_CORE_0) ? 26 : 27; if (txpwrindex < 0) { - if (pi->nphy_txpwrindex[core].index < 0) { - + if (pi->nphy_txpwrindex[core].index < 0) continue; - } if (NREV_GE(pi->pubpi.phy_rev, 3)) { mod_phy_reg(pi, 0x8f, @@ -28842,29 +28535,21 @@ wlc_phy_txpwr_index_nphy(struct brcms_phy *pi, u8 core_mask, s8 txpwrindex, wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m1m2); if (restore_cals) { - - wlc_phy_table_write_nphy(pi, 15, 2, - (80 + 2 * core), 16, - (void *)&pi-> - nphy_txpwrindex[core]. - iqcomp_a); - - wlc_phy_table_write_nphy(pi, 15, 1, (85 + core), - 16, - &pi-> - nphy_txpwrindex[core]. - locomp); - wlc_phy_table_write_nphy(pi, 15, 1, (93 + core), - 16, - (void *)&pi-> - nphy_txpwrindex[core]. - locomp); + wlc_phy_table_write_nphy( + pi, 15, 2, (80 + 2 * core), 16, + &pi->nphy_txpwrindex[core].iqcomp_a); + wlc_phy_table_write_nphy( + pi, 15, 1, (85 + core), 16, + &pi->nphy_txpwrindex[core].locomp); + wlc_phy_table_write_nphy( + pi, 15, 1, (93 + core), 16, + &pi->nphy_txpwrindex[core].locomp); } wlc_phy_txpwrctrl_enable_nphy(pi, pi->nphy_txpwrctrl); pi->nphy_txpwrindex[core].index_internal = - pi->nphy_txpwrindex[core].index_internal_save; + pi->nphy_txpwrindex[core].index_internal_save; } else { if (pi->nphy_txpwrindex[core].index < 0) { @@ -28879,14 +28564,13 @@ wlc_phy_txpwr_index_nphy(struct brcms_phy *pi, u8 core_mask, s8 txpwrindex, AfectrlOverride); } else { pi->nphy_txpwrindex[core]. - AfectrlOverride = - read_phy_reg(pi, 0xa5); + AfectrlOverride = + read_phy_reg(pi, 0xa5); } pi->nphy_txpwrindex[core].AfeCtrlDacGain = - read_phy_reg(pi, - (core == - PHY_CORE_0) ? 0xaa : 0xab); + read_phy_reg(pi, (core == PHY_CORE_0) ? + 0xaa : 0xab); wlc_phy_table_read_nphy(pi, 7, 1, (0x110 + core), 16, @@ -28898,23 +28582,23 @@ wlc_phy_txpwr_index_nphy(struct brcms_phy *pi, u8 core_mask, s8 txpwrindex, &tmpval); tmpval >>= ((core == PHY_CORE_0) ? 8 : 0); tmpval &= 0xff; - pi->nphy_txpwrindex[core].bbmult = - (u8) tmpval; + pi->nphy_txpwrindex[core].bbmult = (u8) tmpval; wlc_phy_table_read_nphy(pi, 15, 2, (80 + 2 * core), 16, - (void *)&pi-> + &pi-> nphy_txpwrindex[core]. iqcomp_a); wlc_phy_table_read_nphy(pi, 15, 1, (85 + core), 16, - (void *)&pi-> + &pi-> nphy_txpwrindex[core]. locomp); pi->nphy_txpwrindex[core].index_internal_save = - pi->nphy_txpwrindex[core].index_internal; + pi->nphy_txpwrindex[core]. + index_internal; } tx_pwr_ctrl_state = pi->nphy_txpwrctrl; @@ -28927,22 +28611,22 @@ wlc_phy_txpwr_index_nphy(struct brcms_phy *pi, u8 core_mask, s8 txpwrindex, (tx_ind0 + txpwrindex), 32, &txgain); - if (NREV_GE(pi->pubpi.phy_rev, 3)) { - rad_gain = - (txgain >> 16) & ((1 << (32 - 16 + 1)) - 1); - } else { - rad_gain = - (txgain >> 16) & ((1 << (28 - 16 + 1)) - 1); - } + if (NREV_GE(pi->pubpi.phy_rev, 3)) + rad_gain = (txgain >> 16) & + ((1 << (32 - 16 + 1)) - 1); + else + rad_gain = (txgain >> 16) & + ((1 << (28 - 16 + 1)) - 1); + dac_gain = (txgain >> 8) & ((1 << (13 - 8 + 1)) - 1); bbmult = (txgain >> 0) & ((1 << (7 - 0 + 1)) - 1); - if (NREV_GE(pi->pubpi.phy_rev, 3)) { + if (NREV_GE(pi->pubpi.phy_rev, 3)) mod_phy_reg(pi, ((core == PHY_CORE_0) ? 0x8f : 0xa5), (0x1 << 8), (0x1 << 8)); - } else { + else mod_phy_reg(pi, 0xa5, (0x1 << 14), (0x1 << 14)); - } + write_phy_reg(pi, (core == PHY_CORE_0) ? 0xaa : 0xab, dac_gain); @@ -28951,9 +28635,8 @@ wlc_phy_txpwr_index_nphy(struct brcms_phy *pi, u8 core_mask, s8 txpwrindex, wlc_phy_table_read_nphy(pi, 15, 1, 87, 16, &m1m2); m1m2 &= ((core == PHY_CORE_0) ? 0x00ff : 0xff00); - m1m2 |= - ((core == - PHY_CORE_0) ? (bbmult << 8) : (bbmult << 0)); + m1m2 |= ((core == PHY_CORE_0) ? + (bbmult << 8) : (bbmult << 0)); wlc_phy_table_write_nphy(pi, 15, 1, 87, 16, &m1m2); @@ -28974,23 +28657,20 @@ wlc_phy_txpwr_index_nphy(struct brcms_phy *pi, u8 core_mask, s8 txpwrindex, wlc_phy_table_read_nphy(pi, txpwrctl_tbl, 1, (lo_ind0 + txpwrindex), 32, &locomp); - if (restore_cals) { + if (restore_cals) wlc_phy_table_write_nphy(pi, 15, 1, (85 + core), 16, &locomp); - } if (NREV_IS(pi->pubpi.phy_rev, 1)) wlapi_bmac_phyclk_fgc(pi->sh->physhim, OFF); if (PHY_IPA(pi)) { wlc_phy_table_read_nphy(pi, - (core == - PHY_CORE_0 ? - NPHY_TBL_ID_CORE1TXPWRCTL - : - NPHY_TBL_ID_CORE2TXPWRCTL), - 1, 576 + txpwrindex, 32, - &rfpwr_offset); + (core == PHY_CORE_0 ? + NPHY_TBL_ID_CORE1TXPWRCTL : + NPHY_TBL_ID_CORE2TXPWRCTL), + 1, 576 + txpwrindex, 32, + &rfpwr_offset); mod_phy_reg(pi, (core == PHY_CORE_0) ? 0x297 : 0x29b, (0x1ff << 4), @@ -29046,7 +28726,7 @@ void wlc_phy_stay_in_carriersearch_nphy(struct brcms_phy *pi, bool enable) if (enable) { if (pi->nphy_deaf_count == 0) { pi->classifier_state = - wlc_phy_classifier_nphy(pi, 0, 0); + wlc_phy_classifier_nphy(pi, 0, 0); wlc_phy_classifier_nphy(pi, (0x7 << 0), 4); wlc_phy_clip_det_nphy(pi, 0, pi->clip_state); wlc_phy_clip_det_nphy(pi, 1, clip_off); @@ -29074,9 +28754,9 @@ void wlc_nphy_deaf_mode(struct brcms_phy *pi, bool mode) if (mode) { if (pi->nphy_deaf_count == 0) wlc_phy_stay_in_carriersearch_nphy(pi, true); - } else { - if (pi->nphy_deaf_count > 0) - wlc_phy_stay_in_carriersearch_nphy(pi, false); + } else if (pi->nphy_deaf_count > 0) { + wlc_phy_stay_in_carriersearch_nphy(pi, false); } + wlapi_enable_mac(pi->sh->physhim); } diff --git a/drivers/staging/brcm80211/brcmsmac/phy/phy_qmath.c b/drivers/staging/brcm80211/brcmsmac/phy/phy_qmath.c index 01ff0c8..faf1ebe 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/phy_qmath.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/phy_qmath.c @@ -17,89 +17,95 @@ #include "phy_qmath.h" /* -Description: This function make 16 bit unsigned multiplication. To fit the output into -16 bits the 32 bit multiplication result is right shifted by 16 bits. -*/ + * Description: This function make 16 bit unsigned multiplication. + * To fit the output into 16 bits the 32 bit multiplication result is right + * shifted by 16 bits. + */ u16 qm_mulu16(u16 op1, u16 op2) { return (u16) (((u32) op1 * (u32) op2) >> 16); } /* -Description: This function make 16 bit multiplication and return the result in 16 bits. -To fit the multiplication result into 16 bits the multiplication result is right shifted by -15 bits. Right shifting 15 bits instead of 16 bits is done to remove the extra sign bit formed -due to the multiplication. -When both the 16bit inputs are 0x8000 then the output is saturated to 0x7fffffff. -*/ + * Description: This function make 16 bit multiplication and return the result + * in 16 bits. To fit the multiplication result into 16 bits the multiplication + * result is right shifted by 15 bits. Right shifting 15 bits instead of 16 bits + * is done to remove the extra sign bit formed due to the multiplication. + * When both the 16bit inputs are 0x8000 then the output is saturated to + * 0x7fffffff. + */ s16 qm_muls16(s16 op1, s16 op2) { s32 result; - if (op1 == (s16) 0x8000 && op2 == (s16) 0x8000) { + if (op1 == (s16) 0x8000 && op2 == (s16) 0x8000) result = 0x7fffffff; - } else { + else result = ((s32) (op1) * (s32) (op2)); - } + return (s16) (result >> 15); } /* -Description: This function add two 32 bit numbers and return the 32bit result. -If the result overflow 32 bits, the output will be saturated to 32bits. -*/ + * Description: This function add two 32 bit numbers and return the 32bit + * result. If the result overflow 32 bits, the output will be saturated to + * 32bits. + */ s32 qm_add32(s32 op1, s32 op2) { s32 result; result = op1 + op2; - if (op1 < 0 && op2 < 0 && result > 0) { + if (op1 < 0 && op2 < 0 && result > 0) result = 0x80000000; - } else if (op1 > 0 && op2 > 0 && result < 0) { + else if (op1 > 0 && op2 > 0 && result < 0) result = 0x7fffffff; - } + return result; } /* -Description: This function add two 16 bit numbers and return the 16bit result. -If the result overflow 16 bits, the output will be saturated to 16bits. -*/ + * Description: This function add two 16 bit numbers and return the 16bit + * result. If the result overflow 16 bits, the output will be saturated to + * 16bits. + */ s16 qm_add16(s16 op1, s16 op2) { s16 result; s32 temp = (s32) op1 + (s32) op2; - if (temp > (s32) 0x7fff) { + if (temp > (s32) 0x7fff) result = (s16) 0x7fff; - } else if (temp < (s32) 0xffff8000) { + else if (temp < (s32) 0xffff8000) result = (s16) 0xffff8000; - } else { + else result = (s16) temp; - } + return result; } /* -Description: This function make 16 bit subtraction and return the 16bit result. -If the result overflow 16 bits, the output will be saturated to 16bits. -*/ + * Description: This function make 16 bit subtraction and return the 16bit + * result. If the result overflow 16 bits, the output will be saturated to + * 16bits. + */ s16 qm_sub16(s16 op1, s16 op2) { s16 result; s32 temp = (s32) op1 - (s32) op2; - if (temp > (s32) 0x7fff) { + if (temp > (s32) 0x7fff) result = (s16) 0x7fff; - } else if (temp < (s32) 0xffff8000) { + else if (temp < (s32) 0xffff8000) result = (s16) 0xffff8000; - } else { + else result = (s16) temp; - } + return result; } /* -Description: This function make a 32 bit saturated left shift when the specified shift -is +ve. This function will make a 32 bit right shift when the specified shift is -ve. -This function return the result after shifting operation. -*/ + * Description: This function make a 32 bit saturated left shift when the + * specified shift is +ve. This function will make a 32 bit right shift when + * the specified shift is -ve. This function return the result after shifting + * operation. + */ s32 qm_shl32(s32 op, int shift) { int i; @@ -110,20 +116,21 @@ s32 qm_shl32(s32 op, int shift) else if (shift < -31) shift = -31; if (shift >= 0) { - for (i = 0; i < shift; i++) { + for (i = 0; i < shift; i++) result = qm_add32(result, result); - } } else { result = result >> (-shift); } + return result; } /* -Description: This function make a 16 bit saturated left shift when the specified shift -is +ve. This function will make a 16 bit right shift when the specified shift is -ve. -This function return the result after shifting operation. -*/ + * Description: This function make a 16 bit saturated left shift when the + * specified shift is +ve. This function will make a 16 bit right shift when + * the specified shift is -ve. This function return the result after shifting + * operation. + */ s16 qm_shl16(s16 op, int shift) { int i; @@ -134,29 +141,29 @@ s16 qm_shl16(s16 op, int shift) else if (shift < -15) shift = -15; if (shift > 0) { - for (i = 0; i < shift; i++) { + for (i = 0; i < shift; i++) result = qm_add16(result, result); - } } else { result = result >> (-shift); } + return result; } /* -Description: This function make a 16 bit right shift when shift is +ve. -This function make a 16 bit saturated left shift when shift is -ve. This function -return the result of the shift operation. -*/ + * Description: This function make a 16 bit right shift when shift is +ve. + * This function make a 16 bit saturated left shift when shift is -ve. This + * function return the result of the shift operation. + */ s16 qm_shr16(s16 op, int shift) { return qm_shl16(op, -shift); } /* -Description: This function return the number of redundant sign bits in a 32 bit number. -Example: qm_norm32(0x00000080) = 23 -*/ + * Description: This function return the number of redundant sign bits in a + * 32 bit number. Example: qm_norm32(0x00000080) = 23 + */ s16 qm_norm32(s32 op) { u16 u16extraSignBits; @@ -208,28 +215,30 @@ static const s16 log_table[] = { 32024 }; -#define LOG_TABLE_SIZE 32 /* log_table size */ -#define LOG2_LOG_TABLE_SIZE 5 /* log2(log_table size) */ -#define Q_LOG_TABLE 15 /* qformat of log_table */ -#define LOG10_2 19728 /* log10(2) in q.16 */ +#define LOG_TABLE_SIZE 32 /* log_table size */ +#define LOG2_LOG_TABLE_SIZE 5 /* log2(log_table size) */ +#define Q_LOG_TABLE 15 /* qformat of log_table */ +#define LOG10_2 19728 /* log10(2) in q.16 */ /* -Description: -This routine takes the input number N and its q format qN and compute -the log10(N). This routine first normalizes the input no N. Then N is in mag*(2^x) format. -mag is any number in the range 2^30-(2^31 - 1). Then log2(mag * 2^x) = log2(mag) + x is computed. -From that log10(mag * 2^x) = log2(mag * 2^x) * log10(2) is computed. -This routine looks the log2 value in the table considering LOG2_LOG_TABLE_SIZE+1 MSBs. -As the MSB is always 1, only next LOG2_OF_LOG_TABLE_SIZE MSBs are used for table lookup. -Next 16 MSBs are used for interpolation. -Inputs: -N - number to which log10 has to be found. -qN - q format of N -log10N - address where log10(N) will be written. -qLog10N - address where log10N qformat will be written. -Note/Problem: -For accurate results input should be in normalized or near normalized form. -*/ + * Description: + * This routine takes the input number N and its q format qN and compute + * the log10(N). This routine first normalizes the input no N. Then N is in + * mag*(2^x) format. mag is any number in the range 2^30-(2^31 - 1). + * Then log2(mag * 2^x) = log2(mag) + x is computed. From that + * log10(mag * 2^x) = log2(mag * 2^x) * log10(2) is computed. + * This routine looks the log2 value in the table considering + * LOG2_LOG_TABLE_SIZE+1 MSBs. As the MSB is always 1, only next + * LOG2_OF_LOG_TABLE_SIZE MSBs are used for table lookup. Next 16 MSBs are used + * for interpolation. + * Inputs: + * N - number to which log10 has to be found. + * qN - q format of N + * log10N - address where log10(N) will be written. + * qLog10N - address where log10N qformat will be written. + * Note/Problem: + * For accurate results input should be in normalized or near normalized form. + */ void qm_log10(s32 N, s16 qN, s16 *log10N, s16 *qLog10N) { s16 s16norm, s16tableIndex, s16errorApproximation; @@ -248,12 +257,13 @@ void qm_log10(s32 N, s16 qN, s16 *log10N, s16 *qLog10N) */ qN = qN + s16norm - 30; - /* take the table index as the LOG2_OF_LOG_TABLE_SIZE bits right of the MSB */ + /* take the table index as the LOG2_OF_LOG_TABLE_SIZE bits right of the + * MSB */ s16tableIndex = (s16) (N >> (32 - (2 + LOG2_LOG_TABLE_SIZE))); /* remove the MSB. the MSB is always 1 after normalization. */ s16tableIndex = - s16tableIndex & (s16) ((1 << LOG2_LOG_TABLE_SIZE) - 1); + s16tableIndex & (s16) ((1 << LOG2_LOG_TABLE_SIZE) - 1); /* remove the (1+LOG2_OF_LOG_TABLE_SIZE) MSBs in the N. */ N = N & ((1 << (32 - (2 + LOG2_LOG_TABLE_SIZE))) - 1); @@ -263,23 +273,27 @@ void qm_log10(s32 N, s16 qN, s16 *log10N, s16 *qLog10N) u16offset = (u16) (N >> (32 - (2 + LOG2_LOG_TABLE_SIZE + 16))); /* look the log value in the table. */ - s32log = log_table[s16tableIndex]; /* q.15 format */ + s32log = log_table[s16tableIndex]; /* q.15 format */ - /* interpolate using the offset. */ - s16errorApproximation = (s16) qm_mulu16(u16offset, (u16) (log_table[s16tableIndex + 1] - log_table[s16tableIndex])); /* q.15 */ + /* interpolate using the offset. q.15 format. */ + s16errorApproximation = (s16) qm_mulu16(u16offset, + (u16) (log_table[s16tableIndex + 1] - + log_table[s16tableIndex])); - s32log = qm_add16((s16) s32log, s16errorApproximation); /* q.15 format */ + /* q.15 format */ + s32log = qm_add16((s16) s32log, s16errorApproximation); /* adjust for the qformat of the N as * log2(mag * 2^x) = log2(mag) + x */ - s32log = qm_add32(s32log, ((s32) -qN) << 15); /* q.15 format */ + s32log = qm_add32(s32log, ((s32) -qN) << 15); /* q.15 format */ /* normalize the result. */ s16norm = qm_norm32(s32log); /* bring all the important bits into lower 16 bits */ - s32log = qm_shl32(s32log, s16norm - 16); /* q.15+s16norm-16 format */ + /* q.15+s16norm-16 format */ + s32log = qm_shl32(s32log, s16norm - 16); /* compute the log10(N) by multiplying log2(N) with log10(2). * as log10(mag * 2^x) = log2(mag * 2^x) * log10(2) diff --git a/drivers/staging/brcm80211/brcmsmac/phy/phytbl_lcn.c b/drivers/staging/brcm80211/brcmsmac/phy/phytbl_lcn.c index 023d05a..c354496 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/phytbl_lcn.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/phytbl_lcn.c @@ -2834,26 +2834,26 @@ const struct phytbl_info dot11lcnphytbl_info_rev0[] = { 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 + sizeof(dot11lcn_sw_ctrl_tbl_4313_rev0) / + sizeof(dot11lcn_sw_ctrl_tbl_4313_rev0[0]), 15, 0, 16 }; 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 + sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0) / + sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0[0]), 15, 0, 16 }; 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 + sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo) / + sizeof(dot11lcn_sw_ctrl_tbl_4313_epa_rev0_combo[0]), 15, 0, 16 }; 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 + 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 = @@ -2861,778 +2861,394 @@ const u32 dot11lcnphytbl_info_sz_rev0 = const struct lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_extPA_gaintable_rev0[128] = { - {3, 0, 31, 0, 72,} - , - {3, 0, 31, 0, 70,} - , - {3, 0, 31, 0, 68,} - , - {3, 0, 30, 0, 67,} - , - {3, 0, 29, 0, 68,} - , - {3, 0, 28, 0, 68,} - , - {3, 0, 27, 0, 69,} - , - {3, 0, 26, 0, 70,} - , - {3, 0, 25, 0, 70,} - , - {3, 0, 24, 0, 71,} - , - {3, 0, 23, 0, 72,} - , - {3, 0, 23, 0, 70,} - , - {3, 0, 22, 0, 71,} - , - {3, 0, 21, 0, 72,} - , - {3, 0, 21, 0, 70,} - , - {3, 0, 21, 0, 68,} - , - {3, 0, 21, 0, 66,} - , - {3, 0, 21, 0, 64,} - , - {3, 0, 21, 0, 63,} - , - {3, 0, 20, 0, 64,} - , - {3, 0, 19, 0, 65,} - , - {3, 0, 19, 0, 64,} - , - {3, 0, 18, 0, 65,} - , - {3, 0, 18, 0, 64,} - , - {3, 0, 17, 0, 65,} - , - {3, 0, 17, 0, 64,} - , - {3, 0, 16, 0, 65,} - , - {3, 0, 16, 0, 64,} - , - {3, 0, 16, 0, 62,} - , - {3, 0, 16, 0, 60,} - , - {3, 0, 16, 0, 58,} - , - {3, 0, 15, 0, 61,} - , - {3, 0, 15, 0, 59,} - , - {3, 0, 14, 0, 61,} - , - {3, 0, 14, 0, 60,} - , - {3, 0, 14, 0, 58,} - , - {3, 0, 13, 0, 60,} - , - {3, 0, 13, 0, 59,} - , - {3, 0, 12, 0, 62,} - , - {3, 0, 12, 0, 60,} - , - {3, 0, 12, 0, 58,} - , - {3, 0, 11, 0, 62,} - , - {3, 0, 11, 0, 60,} - , - {3, 0, 11, 0, 59,} - , - {3, 0, 11, 0, 57,} - , - {3, 0, 10, 0, 61,} - , - {3, 0, 10, 0, 59,} - , - {3, 0, 10, 0, 57,} - , - {3, 0, 9, 0, 62,} - , - {3, 0, 9, 0, 60,} - , - {3, 0, 9, 0, 58,} - , - {3, 0, 9, 0, 57,} - , - {3, 0, 8, 0, 62,} - , - {3, 0, 8, 0, 60,} - , - {3, 0, 8, 0, 58,} - , - {3, 0, 8, 0, 57,} - , - {3, 0, 8, 0, 55,} - , - {3, 0, 7, 0, 61,} - , - {3, 0, 7, 0, 60,} - , - {3, 0, 7, 0, 58,} - , - {3, 0, 7, 0, 56,} - , - {3, 0, 7, 0, 55,} - , - {3, 0, 6, 0, 62,} - , - {3, 0, 6, 0, 60,} - , - {3, 0, 6, 0, 58,} - , - {3, 0, 6, 0, 57,} - , - {3, 0, 6, 0, 55,} - , - {3, 0, 6, 0, 54,} - , - {3, 0, 6, 0, 52,} - , - {3, 0, 5, 0, 61,} - , - {3, 0, 5, 0, 59,} - , - {3, 0, 5, 0, 57,} - , - {3, 0, 5, 0, 56,} - , - {3, 0, 5, 0, 54,} - , - {3, 0, 5, 0, 53,} - , - {3, 0, 5, 0, 51,} - , - {3, 0, 4, 0, 62,} - , - {3, 0, 4, 0, 60,} - , - {3, 0, 4, 0, 58,} - , - {3, 0, 4, 0, 57,} - , - {3, 0, 4, 0, 55,} - , - {3, 0, 4, 0, 54,} - , - {3, 0, 4, 0, 52,} - , - {3, 0, 4, 0, 51,} - , - {3, 0, 4, 0, 49,} - , - {3, 0, 4, 0, 48,} - , - {3, 0, 4, 0, 46,} - , - {3, 0, 3, 0, 60,} - , - {3, 0, 3, 0, 58,} - , - {3, 0, 3, 0, 57,} - , - {3, 0, 3, 0, 55,} - , - {3, 0, 3, 0, 54,} - , - {3, 0, 3, 0, 52,} - , - {3, 0, 3, 0, 51,} - , - {3, 0, 3, 0, 49,} - , - {3, 0, 3, 0, 48,} - , - {3, 0, 3, 0, 46,} - , - {3, 0, 3, 0, 45,} - , - {3, 0, 3, 0, 44,} - , - {3, 0, 3, 0, 43,} - , - {3, 0, 3, 0, 41,} - , - {3, 0, 2, 0, 61,} - , - {3, 0, 2, 0, 59,} - , - {3, 0, 2, 0, 57,} - , - {3, 0, 2, 0, 56,} - , - {3, 0, 2, 0, 54,} - , - {3, 0, 2, 0, 53,} - , - {3, 0, 2, 0, 51,} - , - {3, 0, 2, 0, 50,} - , - {3, 0, 2, 0, 48,} - , - {3, 0, 2, 0, 47,} - , - {3, 0, 2, 0, 46,} - , - {3, 0, 2, 0, 44,} - , - {3, 0, 2, 0, 43,} - , - {3, 0, 2, 0, 42,} - , - {3, 0, 2, 0, 41,} - , - {3, 0, 2, 0, 39,} - , - {3, 0, 2, 0, 38,} - , - {3, 0, 2, 0, 37,} - , - {3, 0, 2, 0, 36,} - , - {3, 0, 2, 0, 35,} - , - {3, 0, 2, 0, 34,} - , - {3, 0, 2, 0, 33,} - , - {3, 0, 2, 0, 32,} - , - {3, 0, 1, 0, 63,} - , - {3, 0, 1, 0, 61,} - , - {3, 0, 1, 0, 59,} - , - {3, 0, 1, 0, 57,} - , + {3, 0, 31, 0, 72}, + {3, 0, 31, 0, 70}, + {3, 0, 31, 0, 68}, + {3, 0, 30, 0, 67}, + {3, 0, 29, 0, 68}, + {3, 0, 28, 0, 68}, + {3, 0, 27, 0, 69}, + {3, 0, 26, 0, 70}, + {3, 0, 25, 0, 70}, + {3, 0, 24, 0, 71}, + {3, 0, 23, 0, 72}, + {3, 0, 23, 0, 70}, + {3, 0, 22, 0, 71}, + {3, 0, 21, 0, 72}, + {3, 0, 21, 0, 70}, + {3, 0, 21, 0, 68}, + {3, 0, 21, 0, 66}, + {3, 0, 21, 0, 64}, + {3, 0, 21, 0, 63}, + {3, 0, 20, 0, 64}, + {3, 0, 19, 0, 65}, + {3, 0, 19, 0, 64}, + {3, 0, 18, 0, 65}, + {3, 0, 18, 0, 64}, + {3, 0, 17, 0, 65}, + {3, 0, 17, 0, 64}, + {3, 0, 16, 0, 65}, + {3, 0, 16, 0, 64}, + {3, 0, 16, 0, 62}, + {3, 0, 16, 0, 60}, + {3, 0, 16, 0, 58}, + {3, 0, 15, 0, 61}, + {3, 0, 15, 0, 59}, + {3, 0, 14, 0, 61}, + {3, 0, 14, 0, 60}, + {3, 0, 14, 0, 58}, + {3, 0, 13, 0, 60}, + {3, 0, 13, 0, 59}, + {3, 0, 12, 0, 62}, + {3, 0, 12, 0, 60}, + {3, 0, 12, 0, 58}, + {3, 0, 11, 0, 62}, + {3, 0, 11, 0, 60}, + {3, 0, 11, 0, 59}, + {3, 0, 11, 0, 57}, + {3, 0, 10, 0, 61}, + {3, 0, 10, 0, 59}, + {3, 0, 10, 0, 57}, + {3, 0, 9, 0, 62}, + {3, 0, 9, 0, 60}, + {3, 0, 9, 0, 58}, + {3, 0, 9, 0, 57}, + {3, 0, 8, 0, 62}, + {3, 0, 8, 0, 60}, + {3, 0, 8, 0, 58}, + {3, 0, 8, 0, 57}, + {3, 0, 8, 0, 55}, + {3, 0, 7, 0, 61}, + {3, 0, 7, 0, 60}, + {3, 0, 7, 0, 58}, + {3, 0, 7, 0, 56}, + {3, 0, 7, 0, 55}, + {3, 0, 6, 0, 62}, + {3, 0, 6, 0, 60}, + {3, 0, 6, 0, 58}, + {3, 0, 6, 0, 57}, + {3, 0, 6, 0, 55}, + {3, 0, 6, 0, 54}, + {3, 0, 6, 0, 52}, + {3, 0, 5, 0, 61}, + {3, 0, 5, 0, 59}, + {3, 0, 5, 0, 57}, + {3, 0, 5, 0, 56}, + {3, 0, 5, 0, 54}, + {3, 0, 5, 0, 53}, + {3, 0, 5, 0, 51}, + {3, 0, 4, 0, 62}, + {3, 0, 4, 0, 60}, + {3, 0, 4, 0, 58}, + {3, 0, 4, 0, 57}, + {3, 0, 4, 0, 55}, + {3, 0, 4, 0, 54}, + {3, 0, 4, 0, 52}, + {3, 0, 4, 0, 51}, + {3, 0, 4, 0, 49}, + {3, 0, 4, 0, 48}, + {3, 0, 4, 0, 46}, + {3, 0, 3, 0, 60}, + {3, 0, 3, 0, 58}, + {3, 0, 3, 0, 57}, + {3, 0, 3, 0, 55}, + {3, 0, 3, 0, 54}, + {3, 0, 3, 0, 52}, + {3, 0, 3, 0, 51}, + {3, 0, 3, 0, 49}, + {3, 0, 3, 0, 48}, + {3, 0, 3, 0, 46}, + {3, 0, 3, 0, 45}, + {3, 0, 3, 0, 44}, + {3, 0, 3, 0, 43}, + {3, 0, 3, 0, 41}, + {3, 0, 2, 0, 61}, + {3, 0, 2, 0, 59}, + {3, 0, 2, 0, 57}, + {3, 0, 2, 0, 56}, + {3, 0, 2, 0, 54}, + {3, 0, 2, 0, 53}, + {3, 0, 2, 0, 51}, + {3, 0, 2, 0, 50}, + {3, 0, 2, 0, 48}, + {3, 0, 2, 0, 47}, + {3, 0, 2, 0, 46}, + {3, 0, 2, 0, 44}, + {3, 0, 2, 0, 43}, + {3, 0, 2, 0, 42}, + {3, 0, 2, 0, 41}, + {3, 0, 2, 0, 39}, + {3, 0, 2, 0, 38}, + {3, 0, 2, 0, 37}, + {3, 0, 2, 0, 36}, + {3, 0, 2, 0, 35}, + {3, 0, 2, 0, 34}, + {3, 0, 2, 0, 33}, + {3, 0, 2, 0, 32}, + {3, 0, 1, 0, 63}, + {3, 0, 1, 0, 61}, + {3, 0, 1, 0, 59}, + {3, 0, 1, 0, 57}, }; const struct lcnphy_tx_gain_tbl_entry dot11lcnphy_2GHz_gaintable_rev0[128] = { - {7, 0, 31, 0, 72,} - , - {7, 0, 31, 0, 70,} - , - {7, 0, 31, 0, 68,} - , - {7, 0, 30, 0, 67,} - , - {7, 0, 29, 0, 68,} - , - {7, 0, 28, 0, 68,} - , - {7, 0, 27, 0, 69,} - , - {7, 0, 26, 0, 70,} - , - {7, 0, 25, 0, 70,} - , - {7, 0, 24, 0, 71,} - , - {7, 0, 23, 0, 72,} - , - {7, 0, 23, 0, 70,} - , - {7, 0, 22, 0, 71,} - , - {7, 0, 21, 0, 72,} - , - {7, 0, 21, 0, 70,} - , - {7, 0, 21, 0, 68,} - , - {7, 0, 21, 0, 66,} - , - {7, 0, 21, 0, 64,} - , - {7, 0, 21, 0, 63,} - , - {7, 0, 20, 0, 64,} - , - {7, 0, 19, 0, 65,} - , - {7, 0, 19, 0, 64,} - , - {7, 0, 18, 0, 65,} - , - {7, 0, 18, 0, 64,} - , - {7, 0, 17, 0, 65,} - , - {7, 0, 17, 0, 64,} - , - {7, 0, 16, 0, 65,} - , - {7, 0, 16, 0, 64,} - , - {7, 0, 16, 0, 62,} - , - {7, 0, 16, 0, 60,} - , - {7, 0, 16, 0, 58,} - , - {7, 0, 15, 0, 61,} - , - {7, 0, 15, 0, 59,} - , - {7, 0, 14, 0, 61,} - , - {7, 0, 14, 0, 60,} - , - {7, 0, 14, 0, 58,} - , - {7, 0, 13, 0, 60,} - , - {7, 0, 13, 0, 59,} - , - {7, 0, 12, 0, 62,} - , - {7, 0, 12, 0, 60,} - , - {7, 0, 12, 0, 58,} - , - {7, 0, 11, 0, 62,} - , - {7, 0, 11, 0, 60,} - , - {7, 0, 11, 0, 59,} - , - {7, 0, 11, 0, 57,} - , - {7, 0, 10, 0, 61,} - , - {7, 0, 10, 0, 59,} - , - {7, 0, 10, 0, 57,} - , - {7, 0, 9, 0, 62,} - , - {7, 0, 9, 0, 60,} - , - {7, 0, 9, 0, 58,} - , - {7, 0, 9, 0, 57,} - , - {7, 0, 8, 0, 62,} - , - {7, 0, 8, 0, 60,} - , - {7, 0, 8, 0, 58,} - , - {7, 0, 8, 0, 57,} - , - {7, 0, 8, 0, 55,} - , - {7, 0, 7, 0, 61,} - , - {7, 0, 7, 0, 60,} - , - {7, 0, 7, 0, 58,} - , - {7, 0, 7, 0, 56,} - , - {7, 0, 7, 0, 55,} - , - {7, 0, 6, 0, 62,} - , - {7, 0, 6, 0, 60,} - , - {7, 0, 6, 0, 58,} - , - {7, 0, 6, 0, 57,} - , - {7, 0, 6, 0, 55,} - , - {7, 0, 6, 0, 54,} - , - {7, 0, 6, 0, 52,} - , - {7, 0, 5, 0, 61,} - , - {7, 0, 5, 0, 59,} - , - {7, 0, 5, 0, 57,} - , - {7, 0, 5, 0, 56,} - , - {7, 0, 5, 0, 54,} - , - {7, 0, 5, 0, 53,} - , - {7, 0, 5, 0, 51,} - , - {7, 0, 4, 0, 62,} - , - {7, 0, 4, 0, 60,} - , - {7, 0, 4, 0, 58,} - , - {7, 0, 4, 0, 57,} - , - {7, 0, 4, 0, 55,} - , - {7, 0, 4, 0, 54,} - , - {7, 0, 4, 0, 52,} - , - {7, 0, 4, 0, 51,} - , - {7, 0, 4, 0, 49,} - , - {7, 0, 4, 0, 48,} - , - {7, 0, 4, 0, 46,} - , - {7, 0, 3, 0, 60,} - , - {7, 0, 3, 0, 58,} - , - {7, 0, 3, 0, 57,} - , - {7, 0, 3, 0, 55,} - , - {7, 0, 3, 0, 54,} - , - {7, 0, 3, 0, 52,} - , - {7, 0, 3, 0, 51,} - , - {7, 0, 3, 0, 49,} - , - {7, 0, 3, 0, 48,} - , - {7, 0, 3, 0, 46,} - , - {7, 0, 3, 0, 45,} - , - {7, 0, 3, 0, 44,} - , - {7, 0, 3, 0, 43,} - , - {7, 0, 3, 0, 41,} - , - {7, 0, 2, 0, 61,} - , - {7, 0, 2, 0, 59,} - , - {7, 0, 2, 0, 57,} - , - {7, 0, 2, 0, 56,} - , - {7, 0, 2, 0, 54,} - , - {7, 0, 2, 0, 53,} - , - {7, 0, 2, 0, 51,} - , - {7, 0, 2, 0, 50,} - , - {7, 0, 2, 0, 48,} - , - {7, 0, 2, 0, 47,} - , - {7, 0, 2, 0, 46,} - , - {7, 0, 2, 0, 44,} - , - {7, 0, 2, 0, 43,} - , - {7, 0, 2, 0, 42,} - , - {7, 0, 2, 0, 41,} - , - {7, 0, 2, 0, 39,} - , - {7, 0, 2, 0, 38,} - , - {7, 0, 2, 0, 37,} - , - {7, 0, 2, 0, 36,} - , - {7, 0, 2, 0, 35,} - , - {7, 0, 2, 0, 34,} - , - {7, 0, 2, 0, 33,} - , - {7, 0, 2, 0, 32,} - , - {7, 0, 1, 0, 63,} - , - {7, 0, 1, 0, 61,} - , - {7, 0, 1, 0, 59,} - , - {7, 0, 1, 0, 57,} - , + {7, 0, 31, 0, 72}, + {7, 0, 31, 0, 70}, + {7, 0, 31, 0, 68}, + {7, 0, 30, 0, 67}, + {7, 0, 29, 0, 68}, + {7, 0, 28, 0, 68}, + {7, 0, 27, 0, 69}, + {7, 0, 26, 0, 70}, + {7, 0, 25, 0, 70}, + {7, 0, 24, 0, 71}, + {7, 0, 23, 0, 72}, + {7, 0, 23, 0, 70}, + {7, 0, 22, 0, 71}, + {7, 0, 21, 0, 72}, + {7, 0, 21, 0, 70}, + {7, 0, 21, 0, 68}, + {7, 0, 21, 0, 66}, + {7, 0, 21, 0, 64}, + {7, 0, 21, 0, 63}, + {7, 0, 20, 0, 64}, + {7, 0, 19, 0, 65}, + {7, 0, 19, 0, 64}, + {7, 0, 18, 0, 65}, + {7, 0, 18, 0, 64}, + {7, 0, 17, 0, 65}, + {7, 0, 17, 0, 64}, + {7, 0, 16, 0, 65}, + {7, 0, 16, 0, 64}, + {7, 0, 16, 0, 62}, + {7, 0, 16, 0, 60}, + {7, 0, 16, 0, 58}, + {7, 0, 15, 0, 61}, + {7, 0, 15, 0, 59}, + {7, 0, 14, 0, 61}, + {7, 0, 14, 0, 60}, + {7, 0, 14, 0, 58}, + {7, 0, 13, 0, 60}, + {7, 0, 13, 0, 59}, + {7, 0, 12, 0, 62}, + {7, 0, 12, 0, 60}, + {7, 0, 12, 0, 58}, + {7, 0, 11, 0, 62}, + {7, 0, 11, 0, 60}, + {7, 0, 11, 0, 59}, + {7, 0, 11, 0, 57}, + {7, 0, 10, 0, 61}, + {7, 0, 10, 0, 59}, + {7, 0, 10, 0, 57}, + {7, 0, 9, 0, 62}, + {7, 0, 9, 0, 60}, + {7, 0, 9, 0, 58}, + {7, 0, 9, 0, 57}, + {7, 0, 8, 0, 62}, + {7, 0, 8, 0, 60}, + {7, 0, 8, 0, 58}, + {7, 0, 8, 0, 57}, + {7, 0, 8, 0, 55}, + {7, 0, 7, 0, 61}, + {7, 0, 7, 0, 60}, + {7, 0, 7, 0, 58}, + {7, 0, 7, 0, 56}, + {7, 0, 7, 0, 55}, + {7, 0, 6, 0, 62}, + {7, 0, 6, 0, 60}, + {7, 0, 6, 0, 58}, + {7, 0, 6, 0, 57}, + {7, 0, 6, 0, 55}, + {7, 0, 6, 0, 54}, + {7, 0, 6, 0, 52}, + {7, 0, 5, 0, 61}, + {7, 0, 5, 0, 59}, + {7, 0, 5, 0, 57}, + {7, 0, 5, 0, 56}, + {7, 0, 5, 0, 54}, + {7, 0, 5, 0, 53}, + {7, 0, 5, 0, 51}, + {7, 0, 4, 0, 62}, + {7, 0, 4, 0, 60}, + {7, 0, 4, 0, 58}, + {7, 0, 4, 0, 57}, + {7, 0, 4, 0, 55}, + {7, 0, 4, 0, 54}, + {7, 0, 4, 0, 52}, + {7, 0, 4, 0, 51}, + {7, 0, 4, 0, 49}, + {7, 0, 4, 0, 48}, + {7, 0, 4, 0, 46}, + {7, 0, 3, 0, 60}, + {7, 0, 3, 0, 58}, + {7, 0, 3, 0, 57}, + {7, 0, 3, 0, 55}, + {7, 0, 3, 0, 54}, + {7, 0, 3, 0, 52}, + {7, 0, 3, 0, 51}, + {7, 0, 3, 0, 49}, + {7, 0, 3, 0, 48}, + {7, 0, 3, 0, 46}, + {7, 0, 3, 0, 45}, + {7, 0, 3, 0, 44}, + {7, 0, 3, 0, 43}, + {7, 0, 3, 0, 41}, + {7, 0, 2, 0, 61}, + {7, 0, 2, 0, 59}, + {7, 0, 2, 0, 57}, + {7, 0, 2, 0, 56}, + {7, 0, 2, 0, 54}, + {7, 0, 2, 0, 53}, + {7, 0, 2, 0, 51}, + {7, 0, 2, 0, 50}, + {7, 0, 2, 0, 48}, + {7, 0, 2, 0, 47}, + {7, 0, 2, 0, 46}, + {7, 0, 2, 0, 44}, + {7, 0, 2, 0, 43}, + {7, 0, 2, 0, 42}, + {7, 0, 2, 0, 41}, + {7, 0, 2, 0, 39}, + {7, 0, 2, 0, 38}, + {7, 0, 2, 0, 37}, + {7, 0, 2, 0, 36}, + {7, 0, 2, 0, 35}, + {7, 0, 2, 0, 34}, + {7, 0, 2, 0, 33}, + {7, 0, 2, 0, 32}, + {7, 0, 1, 0, 63}, + {7, 0, 1, 0, 61}, + {7, 0, 1, 0, 59}, + {7, 0, 1, 0, 57}, }; const struct lcnphy_tx_gain_tbl_entry dot11lcnphy_5GHz_gaintable_rev0[128] = { - {255, 255, 0xf0, 0, 152,} - , - {255, 255, 0xf0, 0, 147,} - , - {255, 255, 0xf0, 0, 143,} - , - {255, 255, 0xf0, 0, 139,} - , - {255, 255, 0xf0, 0, 135,} - , - {255, 255, 0xf0, 0, 131,} - , - {255, 255, 0xf0, 0, 128,} - , - {255, 255, 0xf0, 0, 124,} - , - {255, 255, 0xf0, 0, 121,} - , - {255, 255, 0xf0, 0, 117,} - , - {255, 255, 0xf0, 0, 114,} - , - {255, 255, 0xf0, 0, 111,} - , - {255, 255, 0xf0, 0, 107,} - , - {255, 255, 0xf0, 0, 104,} - , - {255, 255, 0xf0, 0, 101,} - , - {255, 255, 0xf0, 0, 99,} - , - {255, 255, 0xf0, 0, 96,} - , - {255, 255, 0xf0, 0, 93,} - , - {255, 255, 0xf0, 0, 90,} - , - {255, 255, 0xf0, 0, 88,} - , - {255, 255, 0xf0, 0, 85,} - , - {255, 255, 0xf0, 0, 83,} - , - {255, 255, 0xf0, 0, 81,} - , - {255, 255, 0xf0, 0, 78,} - , - {255, 255, 0xf0, 0, 76,} - , - {255, 255, 0xf0, 0, 74,} - , - {255, 255, 0xf0, 0, 72,} - , - {255, 255, 0xf0, 0, 70,} - , - {255, 255, 0xf0, 0, 68,} - , - {255, 255, 0xf0, 0, 66,} - , - {255, 255, 0xf0, 0, 64,} - , - {255, 248, 0xf0, 0, 64,} - , - {255, 241, 0xf0, 0, 64,} - , - {255, 251, 0xe0, 0, 64,} - , - {255, 244, 0xe0, 0, 64,} - , - {255, 254, 0xd0, 0, 64,} - , - {255, 246, 0xd0, 0, 64,} - , - {255, 239, 0xd0, 0, 64,} - , - {255, 249, 0xc0, 0, 64,} - , - {255, 242, 0xc0, 0, 64,} - , - {255, 255, 0xb0, 0, 64,} - , - {255, 248, 0xb0, 0, 64,} - , - {255, 241, 0xb0, 0, 64,} - , - {255, 254, 0xa0, 0, 64,} - , - {255, 246, 0xa0, 0, 64,} - , - {255, 239, 0xa0, 0, 64,} - , - {255, 255, 0x90, 0, 64,} - , - {255, 248, 0x90, 0, 64,} - , - {255, 241, 0x90, 0, 64,} - , - {255, 234, 0x90, 0, 64,} - , - {255, 255, 0x80, 0, 64,} - , - {255, 248, 0x80, 0, 64,} - , - {255, 241, 0x80, 0, 64,} - , - {255, 234, 0x80, 0, 64,} - , - {255, 255, 0x70, 0, 64,} - , - {255, 248, 0x70, 0, 64,} - , - {255, 241, 0x70, 0, 64,} - , - {255, 234, 0x70, 0, 64,} - , - {255, 227, 0x70, 0, 64,} - , - {255, 221, 0x70, 0, 64,} - , - {255, 215, 0x70, 0, 64,} - , - {255, 208, 0x70, 0, 64,} - , - {255, 203, 0x70, 0, 64,} - , - {255, 197, 0x70, 0, 64,} - , - {255, 255, 0x60, 0, 64,} - , - {255, 248, 0x60, 0, 64,} - , - {255, 241, 0x60, 0, 64,} - , - {255, 234, 0x60, 0, 64,} - , - {255, 227, 0x60, 0, 64,} - , - {255, 221, 0x60, 0, 64,} - , - {255, 255, 0x50, 0, 64,} - , - {255, 248, 0x50, 0, 64,} - , - {255, 241, 0x50, 0, 64,} - , - {255, 234, 0x50, 0, 64,} - , - {255, 227, 0x50, 0, 64,} - , - {255, 221, 0x50, 0, 64,} - , - {255, 215, 0x50, 0, 64,} - , - {255, 208, 0x50, 0, 64,} - , - {255, 255, 0x40, 0, 64,} - , - {255, 248, 0x40, 0, 64,} - , - {255, 241, 0x40, 0, 64,} - , - {255, 234, 0x40, 0, 64,} - , - {255, 227, 0x40, 0, 64,} - , - {255, 221, 0x40, 0, 64,} - , - {255, 215, 0x40, 0, 64,} - , - {255, 208, 0x40, 0, 64,} - , - {255, 203, 0x40, 0, 64,} - , - {255, 197, 0x40, 0, 64,} - , - {255, 255, 0x30, 0, 64,} - , - {255, 248, 0x30, 0, 64,} - , - {255, 241, 0x30, 0, 64,} - , - {255, 234, 0x30, 0, 64,} - , - {255, 227, 0x30, 0, 64,} - , - {255, 221, 0x30, 0, 64,} - , - {255, 215, 0x30, 0, 64,} - , - {255, 208, 0x30, 0, 64,} - , - {255, 203, 0x30, 0, 64,} - , - {255, 197, 0x30, 0, 64,} - , - {255, 191, 0x30, 0, 64,} - , - {255, 186, 0x30, 0, 64,} - , - {255, 181, 0x30, 0, 64,} - , - {255, 175, 0x30, 0, 64,} - , - {255, 255, 0x20, 0, 64,} - , - {255, 248, 0x20, 0, 64,} - , - {255, 241, 0x20, 0, 64,} - , - {255, 234, 0x20, 0, 64,} - , - {255, 227, 0x20, 0, 64,} - , - {255, 221, 0x20, 0, 64,} - , - {255, 215, 0x20, 0, 64,} - , - {255, 208, 0x20, 0, 64,} - , - {255, 203, 0x20, 0, 64,} - , - {255, 197, 0x20, 0, 64,} - , - {255, 191, 0x20, 0, 64,} - , - {255, 186, 0x20, 0, 64,} - , - {255, 181, 0x20, 0, 64,} - , - {255, 175, 0x20, 0, 64,} - , - {255, 170, 0x20, 0, 64,} - , - {255, 166, 0x20, 0, 64,} - , - {255, 161, 0x20, 0, 64,} - , - {255, 156, 0x20, 0, 64,} - , - {255, 152, 0x20, 0, 64,} - , - {255, 148, 0x20, 0, 64,} - , - {255, 143, 0x20, 0, 64,} - , - {255, 139, 0x20, 0, 64,} - , - {255, 135, 0x20, 0, 64,} - , - {255, 132, 0x20, 0, 64,} - , - {255, 255, 0x10, 0, 64,} - , - {255, 248, 0x10, 0, 64,} - , + {255, 255, 0xf0, 0, 152}, + {255, 255, 0xf0, 0, 147}, + {255, 255, 0xf0, 0, 143}, + {255, 255, 0xf0, 0, 139}, + {255, 255, 0xf0, 0, 135}, + {255, 255, 0xf0, 0, 131}, + {255, 255, 0xf0, 0, 128}, + {255, 255, 0xf0, 0, 124}, + {255, 255, 0xf0, 0, 121}, + {255, 255, 0xf0, 0, 117}, + {255, 255, 0xf0, 0, 114}, + {255, 255, 0xf0, 0, 111}, + {255, 255, 0xf0, 0, 107}, + {255, 255, 0xf0, 0, 104}, + {255, 255, 0xf0, 0, 101}, + {255, 255, 0xf0, 0, 99}, + {255, 255, 0xf0, 0, 96}, + {255, 255, 0xf0, 0, 93}, + {255, 255, 0xf0, 0, 90}, + {255, 255, 0xf0, 0, 88}, + {255, 255, 0xf0, 0, 85}, + {255, 255, 0xf0, 0, 83}, + {255, 255, 0xf0, 0, 81}, + {255, 255, 0xf0, 0, 78}, + {255, 255, 0xf0, 0, 76}, + {255, 255, 0xf0, 0, 74}, + {255, 255, 0xf0, 0, 72}, + {255, 255, 0xf0, 0, 70}, + {255, 255, 0xf0, 0, 68}, + {255, 255, 0xf0, 0, 66}, + {255, 255, 0xf0, 0, 64}, + {255, 248, 0xf0, 0, 64}, + {255, 241, 0xf0, 0, 64}, + {255, 251, 0xe0, 0, 64}, + {255, 244, 0xe0, 0, 64}, + {255, 254, 0xd0, 0, 64}, + {255, 246, 0xd0, 0, 64}, + {255, 239, 0xd0, 0, 64}, + {255, 249, 0xc0, 0, 64}, + {255, 242, 0xc0, 0, 64}, + {255, 255, 0xb0, 0, 64}, + {255, 248, 0xb0, 0, 64}, + {255, 241, 0xb0, 0, 64}, + {255, 254, 0xa0, 0, 64}, + {255, 246, 0xa0, 0, 64}, + {255, 239, 0xa0, 0, 64}, + {255, 255, 0x90, 0, 64}, + {255, 248, 0x90, 0, 64}, + {255, 241, 0x90, 0, 64}, + {255, 234, 0x90, 0, 64}, + {255, 255, 0x80, 0, 64}, + {255, 248, 0x80, 0, 64}, + {255, 241, 0x80, 0, 64}, + {255, 234, 0x80, 0, 64}, + {255, 255, 0x70, 0, 64}, + {255, 248, 0x70, 0, 64}, + {255, 241, 0x70, 0, 64}, + {255, 234, 0x70, 0, 64}, + {255, 227, 0x70, 0, 64}, + {255, 221, 0x70, 0, 64}, + {255, 215, 0x70, 0, 64}, + {255, 208, 0x70, 0, 64}, + {255, 203, 0x70, 0, 64}, + {255, 197, 0x70, 0, 64}, + {255, 255, 0x60, 0, 64}, + {255, 248, 0x60, 0, 64}, + {255, 241, 0x60, 0, 64}, + {255, 234, 0x60, 0, 64}, + {255, 227, 0x60, 0, 64}, + {255, 221, 0x60, 0, 64}, + {255, 255, 0x50, 0, 64}, + {255, 248, 0x50, 0, 64}, + {255, 241, 0x50, 0, 64}, + {255, 234, 0x50, 0, 64}, + {255, 227, 0x50, 0, 64}, + {255, 221, 0x50, 0, 64}, + {255, 215, 0x50, 0, 64}, + {255, 208, 0x50, 0, 64}, + {255, 255, 0x40, 0, 64}, + {255, 248, 0x40, 0, 64}, + {255, 241, 0x40, 0, 64}, + {255, 234, 0x40, 0, 64}, + {255, 227, 0x40, 0, 64}, + {255, 221, 0x40, 0, 64}, + {255, 215, 0x40, 0, 64}, + {255, 208, 0x40, 0, 64}, + {255, 203, 0x40, 0, 64}, + {255, 197, 0x40, 0, 64}, + {255, 255, 0x30, 0, 64}, + {255, 248, 0x30, 0, 64}, + {255, 241, 0x30, 0, 64}, + {255, 234, 0x30, 0, 64}, + {255, 227, 0x30, 0, 64}, + {255, 221, 0x30, 0, 64}, + {255, 215, 0x30, 0, 64}, + {255, 208, 0x30, 0, 64}, + {255, 203, 0x30, 0, 64}, + {255, 197, 0x30, 0, 64}, + {255, 191, 0x30, 0, 64}, + {255, 186, 0x30, 0, 64}, + {255, 181, 0x30, 0, 64}, + {255, 175, 0x30, 0, 64}, + {255, 255, 0x20, 0, 64}, + {255, 248, 0x20, 0, 64}, + {255, 241, 0x20, 0, 64}, + {255, 234, 0x20, 0, 64}, + {255, 227, 0x20, 0, 64}, + {255, 221, 0x20, 0, 64}, + {255, 215, 0x20, 0, 64}, + {255, 208, 0x20, 0, 64}, + {255, 203, 0x20, 0, 64}, + {255, 197, 0x20, 0, 64}, + {255, 191, 0x20, 0, 64}, + {255, 186, 0x20, 0, 64}, + {255, 181, 0x20, 0, 64}, + {255, 175, 0x20, 0, 64}, + {255, 170, 0x20, 0, 64}, + {255, 166, 0x20, 0, 64}, + {255, 161, 0x20, 0, 64}, + {255, 156, 0x20, 0, 64}, + {255, 152, 0x20, 0, 64}, + {255, 148, 0x20, 0, 64}, + {255, 143, 0x20, 0, 64}, + {255, 139, 0x20, 0, 64}, + {255, 135, 0x20, 0, 64}, + {255, 132, 0x20, 0, 64}, + {255, 255, 0x10, 0, 64}, + {255, 248, 0x10, 0, 64}, }; diff --git a/drivers/staging/brcm80211/brcmsmac/phy/phytbl_n.c b/drivers/staging/brcm80211/brcmsmac/phy/phytbl_n.c index 7f741f4..d1455ae 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/phytbl_n.c +++ b/drivers/staging/brcm80211/brcmsmac/phy/phytbl_n.c @@ -4522,7 +4522,8 @@ const struct phytbl_info mimophytbl_info_rev0[] = { {&chanest_tbl_rev0, sizeof(chanest_tbl_rev0) / sizeof(chanest_tbl_rev0[0]), 22, 0, 32} , - {&mcs_tbl_rev0, sizeof(mcs_tbl_rev0) / sizeof(mcs_tbl_rev0[0]), 18, 0, 8} + {&mcs_tbl_rev0, sizeof(mcs_tbl_rev0) / sizeof(mcs_tbl_rev0[0]), 18, 0, + 8} , {&noise_var_tbl0_rev0, sizeof(noise_var_tbl0_rev0) / sizeof(noise_var_tbl0_rev0[0]), 16, 0, diff --git a/drivers/staging/brcm80211/brcmsmac/phy/phytbl_n.h b/drivers/staging/brcm80211/brcmsmac/phy/phytbl_n.h index c5266cf..dc8a84e 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy/phytbl_n.h +++ b/drivers/staging/brcm80211/brcmsmac/phy/phytbl_n.h @@ -20,21 +20,31 @@ #include "phy_int.h" extern const struct phytbl_info mimophytbl_info_rev0[], - mimophytbl_info_rev0_volatile[]; -extern const u32 mimophytbl_info_sz_rev0, mimophytbl_info_sz_rev0_volatile; + mimophytbl_info_rev0_volatile[]; + +extern const u32 mimophytbl_info_sz_rev0, + mimophytbl_info_sz_rev0_volatile; extern const struct phytbl_info mimophytbl_info_rev3[], - mimophytbl_info_rev3_volatile[], mimophytbl_info_rev3_volatile1[], - mimophytbl_info_rev3_volatile2[], mimophytbl_info_rev3_volatile3[]; -extern const u32 mimophytbl_info_sz_rev3, mimophytbl_info_sz_rev3_volatile, - mimophytbl_info_sz_rev3_volatile1, mimophytbl_info_sz_rev3_volatile2, - mimophytbl_info_sz_rev3_volatile3; + mimophytbl_info_rev3_volatile[], + mimophytbl_info_rev3_volatile1[], + mimophytbl_info_rev3_volatile2[], + mimophytbl_info_rev3_volatile3[]; + +extern const u32 mimophytbl_info_sz_rev3, + mimophytbl_info_sz_rev3_volatile, + mimophytbl_info_sz_rev3_volatile1, + mimophytbl_info_sz_rev3_volatile2, + mimophytbl_info_sz_rev3_volatile3; extern const u32 noise_var_tbl_rev3[]; extern const struct phytbl_info mimophytbl_info_rev7[]; + extern const u32 mimophytbl_info_sz_rev7; + extern const u32 noise_var_tbl_rev7[]; extern const struct phytbl_info mimophytbl_info_rev16[]; + extern const u32 mimophytbl_info_sz_rev16; diff --git a/drivers/staging/brcm80211/brcmsmac/phy_shim.c b/drivers/staging/brcm80211/brcmsmac/phy_shim.c index 82ecdcd..31c9374 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy_shim.c +++ b/drivers/staging/brcm80211/brcmsmac/phy_shim.c @@ -15,15 +15,15 @@ */ /* - * This is "two-way" interface, acting as the SHIM layer between WL and PHY layer. - * WL driver can optinally call this translation layer to do some preprocessing, then reach PHY. - * On the PHY->WL driver direction, all calls go through this layer since PHY doesn't have the - * access to wlc_hw pointer. + * This is "two-way" interface, acting as the SHIM layer between driver + * and PHY layer. The driver can optionally call this translation layer + * to do some preprocessing, then reach PHY. On the PHY->driver direction, + * all calls go through this layer since PHY doesn't have access to the + * driver's brcms_hardware pointer. */ #include <linux/slab.h> #include <net/mac80211.h> -#include "bmac.h" #include "main.h" #include "mac80211_if.h" #include "phy_shim.h" @@ -31,12 +31,13 @@ /* PHY SHIM module specific state */ struct phy_shim_info { struct brcms_hardware *wlc_hw; /* pointer to main wlc_hw structure */ - void *wlc; /* pointer to main wlc structure */ - void *wl; /* pointer to os-specific private state */ + struct brcms_c_info *wlc; /* pointer to main wlc structure */ + struct brcms_info *wl; /* pointer to os-specific private state */ }; struct phy_shim_info *wlc_phy_shim_attach(struct brcms_hardware *wlc_hw, - void *wl, void *wlc) { + struct brcms_info *wl, + struct brcms_c_info *wlc) { struct phy_shim_info *physhim = NULL; physhim = kzalloc(sizeof(struct phy_shim_info), GFP_ATOMIC); @@ -59,11 +60,12 @@ void wlc_phy_shim_detach(struct phy_shim_info *physhim) } struct wlapi_timer *wlapi_init_timer(struct phy_shim_info *physhim, - void (*fn) (void *arg), void *arg, - const char *name) + void (*fn)(struct brcms_phy *pi), + void *arg, const char *name) { return (struct wlapi_timer *) - brcms_init_timer(physhim->wl, fn, arg, name); + brcms_init_timer(physhim->wl, (void (*)(void *))fn, + arg, name); } void wlapi_free_timer(struct phy_shim_info *physhim, struct wlapi_timer *t) diff --git a/drivers/staging/brcm80211/brcmsmac/phy_shim.h b/drivers/staging/brcm80211/brcmsmac/phy_shim.h index 2d12bb4..d88c820 100644 --- a/drivers/staging/brcm80211/brcmsmac/phy_shim.h +++ b/drivers/staging/brcm80211/brcmsmac/phy_shim.h @@ -45,17 +45,17 @@ #define FRA_ERR_20MHZ 60 #define FRA_ERR_40MHZ 120 -#define ANTSEL_NA 0 /* No boardlevel selection available */ -#define ANTSEL_2x4 1 /* 2x4 boardlevel selection available */ -#define ANTSEL_2x3 2 /* 2x3 CB2 boardlevel selection available */ +#define ANTSEL_NA 0 /* No boardlevel selection available */ +#define ANTSEL_2x4 1 /* 2x4 boardlevel selection available */ +#define ANTSEL_2x3 2 /* 2x3 CB2 boardlevel selection available */ /* Rx Antenna diversity control values */ -#define ANT_RX_DIV_FORCE_0 0 /* Use antenna 0 */ -#define ANT_RX_DIV_FORCE_1 1 /* Use antenna 1 */ -#define ANT_RX_DIV_START_1 2 /* Choose starting with 1 */ -#define ANT_RX_DIV_START_0 3 /* Choose starting with 0 */ -#define ANT_RX_DIV_ENABLE 3 /* APHY bbConfig Enable RX Diversity */ -#define ANT_RX_DIV_DEF ANT_RX_DIV_START_0 /* default antdiv setting */ +#define ANT_RX_DIV_FORCE_0 0 /* Use antenna 0 */ +#define ANT_RX_DIV_FORCE_1 1 /* Use antenna 1 */ +#define ANT_RX_DIV_START_1 2 /* Choose starting with 1 */ +#define ANT_RX_DIV_START_0 3 /* Choose starting with 0 */ +#define ANT_RX_DIV_ENABLE 3 /* APHY bbConfig Enable RX Diversity */ +#define ANT_RX_DIV_DEF ANT_RX_DIV_START_0 /* default antdiv setting */ #define WL_ANT_RX_MAX 2 /* max 2 receive antennas */ #define WL_ANT_HT_RX_MAX 3 /* max 3 receive antennas/cores */ @@ -77,26 +77,40 @@ #define WL_TX_POWER_RATES 101 #define WL_TX_POWER_CCK_FIRST 0 #define WL_TX_POWER_CCK_NUM 4 -#define WL_TX_POWER_OFDM_FIRST 4 /* Index for first 20MHz OFDM SISO rate */ -#define WL_TX_POWER_OFDM20_CDD_FIRST 12 /* Index for first 20MHz OFDM CDD rate */ -#define WL_TX_POWER_OFDM40_SISO_FIRST 52 /* Index for first 40MHz OFDM SISO rate */ -#define WL_TX_POWER_OFDM40_CDD_FIRST 60 /* Index for first 40MHz OFDM CDD rate */ +/* Index for first 20MHz OFDM SISO rate */ +#define WL_TX_POWER_OFDM_FIRST 4 +/* Index for first 20MHz OFDM CDD rate */ +#define WL_TX_POWER_OFDM20_CDD_FIRST 12 +/* Index for first 40MHz OFDM SISO rate */ +#define WL_TX_POWER_OFDM40_SISO_FIRST 52 +/* Index for first 40MHz OFDM CDD rate */ +#define WL_TX_POWER_OFDM40_CDD_FIRST 60 #define WL_TX_POWER_OFDM_NUM 8 -#define WL_TX_POWER_MCS20_SISO_FIRST 20 /* Index for first 20MHz MCS SISO rate */ -#define WL_TX_POWER_MCS20_CDD_FIRST 28 /* Index for first 20MHz MCS CDD rate */ -#define WL_TX_POWER_MCS20_STBC_FIRST 36 /* Index for first 20MHz MCS STBC rate */ -#define WL_TX_POWER_MCS20_SDM_FIRST 44 /* Index for first 20MHz MCS SDM rate */ -#define WL_TX_POWER_MCS40_SISO_FIRST 68 /* Index for first 40MHz MCS SISO rate */ -#define WL_TX_POWER_MCS40_CDD_FIRST 76 /* Index for first 40MHz MCS CDD rate */ -#define WL_TX_POWER_MCS40_STBC_FIRST 84 /* Index for first 40MHz MCS STBC rate */ -#define WL_TX_POWER_MCS40_SDM_FIRST 92 /* Index for first 40MHz MCS SDM rate */ +/* Index for first 20MHz MCS SISO rate */ +#define WL_TX_POWER_MCS20_SISO_FIRST 20 +/* Index for first 20MHz MCS CDD rate */ +#define WL_TX_POWER_MCS20_CDD_FIRST 28 +/* Index for first 20MHz MCS STBC rate */ +#define WL_TX_POWER_MCS20_STBC_FIRST 36 +/* Index for first 20MHz MCS SDM rate */ +#define WL_TX_POWER_MCS20_SDM_FIRST 44 +/* Index for first 40MHz MCS SISO rate */ +#define WL_TX_POWER_MCS40_SISO_FIRST 68 +/* Index for first 40MHz MCS CDD rate */ +#define WL_TX_POWER_MCS40_CDD_FIRST 76 +/* Index for first 40MHz MCS STBC rate */ +#define WL_TX_POWER_MCS40_STBC_FIRST 84 +/* Index for first 40MHz MCS SDM rate */ +#define WL_TX_POWER_MCS40_SDM_FIRST 92 #define WL_TX_POWER_MCS_1_STREAM_NUM 8 #define WL_TX_POWER_MCS_2_STREAM_NUM 8 -#define WL_TX_POWER_MCS_32 100 /* Index for 40MHz rate MCS 32 */ +/* Index for 40MHz rate MCS 32 */ +#define WL_TX_POWER_MCS_32 100 #define WL_TX_POWER_MCS_32_NUM 1 /* sslpnphy specifics */ -#define WL_TX_POWER_MCS20_SISO_FIRST_SSN 12 /* Index for first 20MHz MCS SISO rate */ +/* Index for first 20MHz MCS SISO rate */ +#define WL_TX_POWER_MCS20_SISO_FIRST_SSN 12 /* struct tx_power::flags bits */ #define WL_TX_POWER_F_ENABLED 1 @@ -108,14 +122,17 @@ #define BRCMS_N_TXRX_CHAIN0 0 #define BRCMS_N_TXRX_CHAIN1 1 +struct brcms_phy; + extern struct phy_shim_info *wlc_phy_shim_attach(struct brcms_hardware *wlc_hw, - void *wl, void *wlc); + struct brcms_info *wl, + struct brcms_c_info *wlc); extern void wlc_phy_shim_detach(struct phy_shim_info *physhim); /* PHY to WL utility functions */ extern struct wlapi_timer *wlapi_init_timer(struct phy_shim_info *physhim, - void (*fn) (void *arg), void *arg, - const char *name); + void (*fn) (struct brcms_phy *pi), + void *arg, const char *name); extern void wlapi_free_timer(struct phy_shim_info *physhim, struct wlapi_timer *t); extern void wlapi_add_timer(struct phy_shim_info *physhim, diff --git a/drivers/staging/brcm80211/brcmsmac/pmu.c b/drivers/staging/brcm80211/brcmsmac/pmu.c index e8b2b81..cdeaa4e 100644 --- a/drivers/staging/brcm80211/brcmsmac/pmu.c +++ b/drivers/staging/brcm80211/brcmsmac/pmu.c @@ -70,11 +70,13 @@ #define PMURES_BIT(bit) (1 << (bit)) /* PMU corerev and chip specific PLL controls. - * PMU<rev>_PLL<num>_XX where <rev> is PMU corerev and <num> is an arbitrary number - * to differentiate different PLLs controlled by the same PMU rev. + * PMU<rev>_PLL<num>_XX where <rev> is PMU corerev and <num> is an arbitrary + * number to differentiate different PLLs controlled by the same PMU rev. + */ +/* pllcontrol registers: + * ndiv_pwrdn, pwrdn_ch<x>, refcomp_pwrdn, dly_ch<x>, + * p1div, p2div, _bypass_sdmod */ -/* pllcontrol registers */ -/* ndiv_pwrdn, pwrdn_ch<x>, refcomp_pwrdn, dly_ch<x>, p1div, p2div, _bypass_sdmod */ #define PMU1_PLL0_PLLCTL0 0 #define PMU1_PLL0_PLLCTL1 1 #define PMU1_PLL0_PLLCTL2 2 @@ -137,7 +139,8 @@ static void si_pmu_res_masks(struct si_pub *sih, u32 * pmin, u32 * pmax) } static void -si_pmu_spuravoid_pllupdate(struct si_pub *sih, chipcregs_t *cc, u8 spuravoid) +si_pmu_spuravoid_pllupdate(struct si_pub *sih, struct chipcregs *cc, + u8 spuravoid) { u32 tmp = 0; @@ -209,7 +212,7 @@ u32 si_pmu_ilp_clock(struct si_pub *sih) if (ilpcycles_per_sec == 0) { u32 start, end, delta; u32 origidx = ai_coreidx(sih); - chipcregs_t *cc = ai_setcoreidx(sih, SI_CC_IDX); + struct chipcregs *cc = ai_setcoreidx(sih, SI_CC_IDX); start = R_REG(&cc->pmutimer); mdelay(ILP_CALC_DUR); end = R_REG(&cc->pmutimer); @@ -240,7 +243,7 @@ u16 si_pmu_fast_pwrup_delay(struct si_pub *sih) void si_pmu_sprom_enable(struct si_pub *sih, bool enable) { - chipcregs_t *cc; + struct chipcregs *cc; uint origidx; /* Remember original core before switch to chipc */ @@ -254,34 +257,37 @@ void si_pmu_sprom_enable(struct si_pub *sih, bool enable) /* Read/write a chipcontrol reg */ u32 si_pmu_chipcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val) { - ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol_addr), ~0, - reg); + ai_corereg(sih, SI_CC_IDX, offsetof(struct chipcregs, chipcontrol_addr), + ~0, reg); return ai_corereg(sih, SI_CC_IDX, - offsetof(chipcregs_t, chipcontrol_data), mask, val); + offsetof(struct chipcregs, chipcontrol_data), mask, + val); } /* Read/write a regcontrol reg */ u32 si_pmu_regcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val) { - ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, regcontrol_addr), ~0, - reg); + ai_corereg(sih, SI_CC_IDX, offsetof(struct chipcregs, regcontrol_addr), + ~0, reg); return ai_corereg(sih, SI_CC_IDX, - offsetof(chipcregs_t, regcontrol_data), mask, val); + offsetof(struct chipcregs, regcontrol_data), mask, + val); } /* Read/write a pllcontrol reg */ u32 si_pmu_pllcontrol(struct si_pub *sih, uint reg, u32 mask, u32 val) { - ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pllcontrol_addr), ~0, - reg); + ai_corereg(sih, SI_CC_IDX, offsetof(struct chipcregs, pllcontrol_addr), + ~0, reg); return ai_corereg(sih, SI_CC_IDX, - offsetof(chipcregs_t, pllcontrol_data), mask, val); + offsetof(struct chipcregs, pllcontrol_data), mask, + val); } /* PMU PLL update */ void si_pmu_pllupd(struct si_pub *sih) { - ai_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, pmucontrol), + ai_corereg(sih, SI_CC_IDX, offsetof(struct chipcregs, pmucontrol), PCTL_PLL_PLLCTL_UPD, PCTL_PLL_PLLCTL_UPD); } @@ -310,12 +316,12 @@ u32 si_pmu_alp_clock(struct si_pub *sih) void si_pmu_spuravoid(struct si_pub *sih, u8 spuravoid) { - chipcregs_t *cc; + struct chipcregs *cc; uint origidx, intr_val; /* Remember original core before switch to chipc */ - cc = (chipcregs_t *) ai_switch_core(sih, CC_CORE_ID, &origidx, - &intr_val); + cc = (struct chipcregs *) + ai_switch_core(sih, CC_CORE_ID, &origidx, &intr_val); /* update the pll changes */ si_pmu_spuravoid_pllupdate(sih, cc, spuravoid); @@ -327,7 +333,7 @@ void si_pmu_spuravoid(struct si_pub *sih, u8 spuravoid) /* initialize PMU */ void si_pmu_init(struct si_pub *sih) { - chipcregs_t *cc; + struct chipcregs *cc; uint origidx; /* Remember original core before switch to chipc */ @@ -366,7 +372,7 @@ void si_pmu_swreg_init(struct si_pub *sih) /* initialize PLL */ void si_pmu_pll_init(struct si_pub *sih, uint xtalfreq) { - chipcregs_t *cc; + struct chipcregs *cc; uint origidx; /* Remember original core before switch to chipc */ @@ -390,7 +396,7 @@ void si_pmu_pll_init(struct si_pub *sih, uint xtalfreq) /* initialize PMU resources */ void si_pmu_res_init(struct si_pub *sih) { - chipcregs_t *cc; + struct chipcregs *cc; uint origidx; u32 min_mask = 0, max_mask = 0; @@ -422,7 +428,7 @@ void si_pmu_res_init(struct si_pub *sih) u32 si_pmu_measure_alpclk(struct si_pub *sih) { - chipcregs_t *cc; + struct chipcregs *cc; uint origidx; u32 alp_khz; diff --git a/drivers/staging/brcm80211/brcmsmac/pub.h b/drivers/staging/brcm80211/brcmsmac/pub.h index 01d7460..f4e47e8 100644 --- a/drivers/staging/brcm80211/brcmsmac/pub.h +++ b/drivers/staging/brcm80211/brcmsmac/pub.h @@ -69,37 +69,52 @@ #define BRCMS_RATE_MASK 0x7f /* Rate value mask w/o basic rate flag */ /* legacy rx Antenna diversity for SISO rates */ -#define ANT_RX_DIV_FORCE_0 0 /* Use antenna 0 */ -#define ANT_RX_DIV_FORCE_1 1 /* Use antenna 1 */ -#define ANT_RX_DIV_START_1 2 /* Choose starting with 1 */ -#define ANT_RX_DIV_START_0 3 /* Choose starting with 0 */ -#define ANT_RX_DIV_ENABLE 3 /* APHY bbConfig Enable RX Diversity */ -#define ANT_RX_DIV_DEF ANT_RX_DIV_START_0 /* default antdiv setting */ +#define ANT_RX_DIV_FORCE_0 0 /* Use antenna 0 */ +#define ANT_RX_DIV_FORCE_1 1 /* Use antenna 1 */ +#define ANT_RX_DIV_START_1 2 /* Choose starting with 1 */ +#define ANT_RX_DIV_START_0 3 /* Choose starting with 0 */ +#define ANT_RX_DIV_ENABLE 3 /* APHY bbConfig Enable RX Diversity */ +/* default antdiv setting */ +#define ANT_RX_DIV_DEF ANT_RX_DIV_START_0 /* legacy rx Antenna diversity for SISO rates */ -#define ANT_TX_FORCE_0 0 /* Tx on antenna 0, "legacy term Main" */ -#define ANT_TX_FORCE_1 1 /* Tx on antenna 1, "legacy term Aux" */ -#define ANT_TX_LAST_RX 3 /* Tx on phy's last good Rx antenna */ -#define ANT_TX_DEF 3 /* driver's default tx antenna setting */ - -#define TXCORE_POLICY_ALL 0x1 /* use all available core for transmit */ +/* Tx on antenna 0, "legacy term Main" */ +#define ANT_TX_FORCE_0 0 +/* Tx on antenna 1, "legacy term Aux" */ +#define ANT_TX_FORCE_1 1 +/* Tx on phy's last good Rx antenna */ +#define ANT_TX_LAST_RX 3 +/* driver's default tx antenna setting */ +#define ANT_TX_DEF 3 + +/* use all available core for transmit */ +#define TXCORE_POLICY_ALL 0x1 /* Tx Chain values */ -#define TXCHAIN_DEF 0x1 /* def bitmap of txchain */ -#define TXCHAIN_DEF_NPHY 0x3 /* default bitmap of tx chains for nphy */ -#define TXCHAIN_DEF_HTPHY 0x7 /* default bitmap of tx chains for nphy */ -#define RXCHAIN_DEF 0x1 /* def bitmap of rxchain */ -#define RXCHAIN_DEF_NPHY 0x3 /* default bitmap of rx chains for nphy */ -#define RXCHAIN_DEF_HTPHY 0x7 /* default bitmap of rx chains for nphy */ -#define ANTSWITCH_NONE 0 /* no antenna switch */ -#define ANTSWITCH_TYPE_1 1 /* antenna switch on 4321CB2, 2of3 */ -#define ANTSWITCH_TYPE_2 2 /* antenna switch on 4321MPCI, 2of3 */ -#define ANTSWITCH_TYPE_3 3 /* antenna switch on 4322, 2of3 */ +/* def bitmap of txchain */ +#define TXCHAIN_DEF 0x1 +/* default bitmap of tx chains for nphy */ +#define TXCHAIN_DEF_NPHY 0x3 +/* default bitmap of tx chains for nphy */ +#define TXCHAIN_DEF_HTPHY 0x7 +/* def bitmap of rxchain */ +#define RXCHAIN_DEF 0x1 +/* default bitmap of rx chains for nphy */ +#define RXCHAIN_DEF_NPHY 0x3 +/* default bitmap of rx chains for nphy */ +#define RXCHAIN_DEF_HTPHY 0x7 +/* no antenna switch */ +#define ANTSWITCH_NONE 0 +/* antenna switch on 4321CB2, 2of3 */ +#define ANTSWITCH_TYPE_1 1 +/* antenna switch on 4321MPCI, 2of3 */ +#define ANTSWITCH_TYPE_2 2 +/* antenna switch on 4322, 2of3 */ +#define ANTSWITCH_TYPE_3 3 #define RXBUFSZ PKTBUFSZ -#ifndef AIDMAPSZ -#define AIDMAPSZ (roundup(MAXSCB, NBBY)/NBBY) /* aid bitmap size in bytes */ -#endif /* AIDMAPSZ */ +/* aid bitmap size in bytes */ +#define AIDMAPSZ (roundup(MAXSCB, NBBY)/NBBY) #define MAX_STREAMS_SUPPORTED 4 /* max number of streams supported */ @@ -108,24 +123,24 @@ #define WL_SPURAVOID_ON2 2 struct brcms_tunables { - int ntxd; /* size of tx descriptor table */ - int nrxd; /* size of rx descriptor table */ - int rxbufsz; /* size of rx buffers to post */ - int nrxbufpost; /* # of rx buffers to post */ - int maxscb; /* # of SCBs supported */ + int ntxd; /* size of tx descriptor table */ + int nrxd; /* size of rx descriptor table */ + int rxbufsz; /* size of rx buffers to post */ + int nrxbufpost; /* # of rx buffers to post */ + int maxscb; /* # of SCBs supported */ int ampdunummpdu; /* max number of mpdu in an ampdu */ - int maxpktcb; /* max # of packet callbacks */ - int maxucodebss; /* max # of BSS handled in ucode bcn/prb */ + int maxpktcb; /* max # of packet callbacks */ + int maxucodebss;/* max # of BSS handled in ucode bcn/prb */ int maxucodebss4; /* max # of BSS handled in sw bcn/prb */ - int maxbss; /* max # of bss info elements in scan list */ - int datahiwat; /* data msg txq hiwat mark */ + int maxbss; /* max # of bss info elements in scan list */ + int datahiwat; /* data msg txq hiwat mark */ int ampdudatahiwat; /* AMPDU msg txq hiwat mark */ - int rxbnd; /* max # of rx bufs to process before deferring to dpc */ - int txsbnd; /* max # tx status to process in wlc_txstatus() */ - int memreserved; /* memory reserved for BMAC's USB dma rx */ + int rxbnd; /* max # rx bufs to process before deferring to dpc */ + int txsbnd; /* max # tx status to process in wlc_txstatus() */ + int memreserved;/* memory reserved for BMAC's USB dma rx */ }; -struct brcms_rateset { +struct brcms_c_rateset { uint count; /* number of rates in rates[] */ /* rates in 500kbps units w/hi bit set if basic */ u8 rates[BRCMS_NUMRATES]; @@ -171,9 +186,9 @@ struct brcms_bss_info { s16 SNR; /* receive signal SNR in dB */ u16 beacon_period; /* units are Kusec */ u16 atim_window; /* units are Kusec */ - chanspec_t chanspec; /* Channel num, bw, ctrl_sb and band */ + u16 chanspec; /* Channel num, bw, ctrl_sb and band */ s8 infra; /* 0=IBSS, 1=infrastructure, 2=unknown */ - wlc_rateset_t rateset; /* supported rates */ + struct brcms_c_rateset rateset; /* supported rates */ u8 dtim_period; /* DTIM period */ s8 phy_noise; /* noise right after tx (in dBm) */ u16 capability; /* Capability information */ @@ -181,7 +196,7 @@ struct brcms_bss_info { struct rsn_parms wpa; struct rsn_parms wpa2; u16 qbss_load_aac; /* qbss load available admission capacity */ - /* qbss_load_chan_free <- (0xff - channel_utilization of qbss_load_ie_t) */ + /* qbss_load_chan_free <- (0xff - chan utilization of qbss_load_ie_t) */ u8 qbss_load_chan_free; /* indicates how free the channel is */ u8 mcipher; /* multicast cipher */ u8 wpacfg; /* wpa config index */ @@ -203,39 +218,15 @@ struct brcms_bss_info { #define IOVF_GET_BAND (1<<13) /* get requires fixed band */ #define IOVF_OPEN_ALLOW (1<<14) /* set allowed iovar for opensrc */ -/* watchdog down and dump callback function proto's */ -typedef int (*watchdog_fn_t) (void *handle); -typedef int (*down_fn_t) (void *handle); -typedef int (*dump_fn_t) (void *handle, struct brcmu_strbuf *b); - -/* IOVar handler - * - * handle - a pointer value registered with the function - * vi - iovar_info that was looked up - * actionid - action ID, calculated by IOV_GVAL() and IOV_SVAL() based on varid. - * name - the actual iovar name - * params/plen - parameters and length for a get, input only. - * arg/len - buffer and length for value to be set or retrieved, input or output. - * vsize - value size, valid for integer type only. - * wlcif - interface context (brcms_c_if pointer) - * - * All pointers may point into the same buffer. - */ -typedef int (*iovar_fn_t) (void *handle, const struct brcmu_iovar *vi, - u32 actionid, const char *name, void *params, - uint plen, void *arg, int alen, int vsize, - struct brcms_c_if *wlcif); - #define MAC80211_PROMISC_BCNS (1 << 0) #define MAC80211_SCAN (1 << 1) /* - * Public portion of "common" os-independent state structure. + * Public portion of common driver state structure. * The wlc handle points at this. */ struct brcms_pub { - void *wlc; - + struct brcms_c_info *wlc; struct ieee80211_hw *ieee_hw; struct scb *global_scb; struct scb_ampdu *global_ampdu; @@ -248,8 +239,8 @@ struct brcms_pub { bool hw_off; /* HW is off */ /* tunables: ntxd, nrxd, maxscb, etc. */ struct brcms_tunables *tunables; - bool hw_up; /* one time hw up/down(from boot or hibernation) */ - bool _piomode; /* true if pio mode *//* BMAC_NOTE: NEED In both */ + bool hw_up; /* one time hw up/down */ + bool _piomode; /* true if pio mode */ uint _nbands; /* # bands supported */ uint now; /* # elapsed seconds */ @@ -270,7 +261,7 @@ struct brcms_pub { u8 _n_enab; /* bitmap of 11N + HT support */ bool _n_reqd; /* N support required for clients */ - s8 _coex; /* 20/40 MHz BSS Management AUTO, ENAB, DISABLE */ + s8 _coex; /* 20/40 MHz BSS Management AUTO, ENAB, DISABLE */ bool _priofc; /* Priority-based flowcontrol */ u8 cur_etheraddr[ETH_ALEN]; /* our local ethernet address */ @@ -288,7 +279,7 @@ struct brcms_pub { int bcmerror; /* last bcm error */ - mbool radio_disabled; /* bit vector for radio disabled reasons */ + u32 radio_disabled; /* bit vector for radio disabled reasons */ bool radio_active; /* radio on/off state */ u16 roam_time_thresh; /* Max. # secs. of not hearing beacons * before roaming. @@ -331,39 +322,6 @@ struct wl_rxsts { struct brcms_if *wlif; /* wl interface */ }; -/* status per error RX pkt */ -#define WL_RXS_CRC_ERROR 0x00000001 /* CRC Error in packet */ -#define WL_RXS_RUNT_ERROR 0x00000002 /* Runt packet */ -#define WL_RXS_ALIGN_ERROR 0x00000004 /* Misaligned packet */ -#define WL_RXS_OVERSIZE_ERROR 0x00000008 /* packet bigger than RX_LENGTH (usually 1518) */ -#define WL_RXS_WEP_ICV_ERROR 0x00000010 /* Integrity Check Value error */ -#define WL_RXS_WEP_ENCRYPTED 0x00000020 /* Encrypted with WEP */ -#define WL_RXS_PLCP_SHORT 0x00000040 /* Short PLCP error */ -#define WL_RXS_DECRYPT_ERR 0x00000080 /* Decryption error */ -#define WL_RXS_OTHER_ERR 0x80000000 /* Other errors */ - -/* phy type */ -#define WL_RXS_PHY_A 0x00000000 /* A phy type */ -#define WL_RXS_PHY_B 0x00000001 /* B phy type */ -#define WL_RXS_PHY_G 0x00000002 /* G phy type */ -#define WL_RXS_PHY_N 0x00000004 /* N phy type */ - -/* encoding */ -#define WL_RXS_ENCODING_CCK 0x00000000 /* CCK encoding */ -#define WL_RXS_ENCODING_OFDM 0x00000001 /* OFDM encoding */ - -/* preamble */ -#define WL_RXS_UNUSED_STUB 0x0 /* stub to match with wlc_ethereal.h */ -#define WL_RXS_PREAMBLE_SHORT 0x00000001 /* Short preamble */ -#define WL_RXS_PREAMBLE_LONG 0x00000002 /* Long preamble */ -#define WL_RXS_PREAMBLE_MIMO_MM 0x00000003 /* MIMO mixed mode preamble */ -#define WL_RXS_PREAMBLE_MIMO_GF 0x00000004 /* MIMO green field preamble */ - -#define WL_RXS_NFRM_AMPDU_FIRST 0x00000001 /* first MPDU in A-MPDU */ -#define WL_RXS_NFRM_AMPDU_SUB 0x00000002 /* subsequent MPDU(s) in A-MPDU */ -#define WL_RXS_NFRM_AMSDU_FIRST 0x00000004 /* first MSDU in A-MSDU */ -#define WL_RXS_NFRM_AMSDU_SUB 0x00000008 /* subsequent MSDU(s) in A-MSDU */ - enum wlc_par_id { IOV_MPC = 1, IOV_RTSTHRESH, @@ -393,20 +351,10 @@ enum wlc_par_id { #define SUPPORT_11N (ENAB_1x1|ENAB_2x2) #define SUPPORT_HT (ENAB_1x1|ENAB_2x2|ENAB_3x3) /* WL11N Support */ -#if ((defined(NCONF) && (NCONF != 0)) || (defined(LCNCONF) && (LCNCONF != 0)) || \ - (defined(HTCONF) && (HTCONF != 0)) || (defined(SSLPNCONF) && (SSLPNCONF != 0))) #define N_ENAB(pub) ((pub)->_n_enab & SUPPORT_11N) #define N_REQD(pub) ((pub)->_n_reqd) -#else -#define N_ENAB(pub) 0 -#define N_REQD(pub) 0 -#endif - -#if (defined(HTCONF) && (HTCONF != 0)) -#define HT_ENAB(pub) (((pub)->_n_enab & SUPPORT_HT) == SUPPORT_HT) -#else + #define HT_ENAB(pub) 0 -#endif #define AMPDU_AGG_HOST 1 #define AMPDU_ENAB(pub) ((pub)->_ampdu) @@ -426,8 +374,10 @@ enum wlc_par_id { extern const u8 wlc_prio2prec_map[]; #define BRCMS_PRIO_TO_PREC(pri) wlc_prio2prec_map[(pri) & 7] -/* This maps priority to one precedence higher - Used by PS-Poll response packets to - * simulate enqueue-at-head operation, but still maintain the order on the queue +/* + * This maps priority to one precedence higher - Used by PS-Poll response + * packets to simulate enqueue-at-head operation, but still maintain the + * order on the queue */ #define BRCMS_PRIO_TO_HI_PREC(pri) min(BRCMS_PRIO_TO_PREC(pri) + 1,\ BRCMS_PREC_COUNT - 1) @@ -480,28 +430,34 @@ extern const u8 wme_fifo2ac[]; /* * 54g modes (basic bits may still be overridden) * - * GMODE_LEGACY_B Rateset: 1b, 2b, 5.5, 11 - * Preamble: Long - * Shortslot: Off - * GMODE_AUTO Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54 - * Extended Rateset: 6, 9, 12, 48 - * Preamble: Long - * Shortslot: Auto - * GMODE_ONLY Rateset: 1b, 2b, 5.5b, 11b, 18, 24b, 36, 54 - * Extended Rateset: 6b, 9, 12b, 48 - * Preamble: Short required - * Shortslot: Auto - * GMODE_B_DEFERRED Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54 - * Extended Rateset: 6, 9, 12, 48 - * Preamble: Long - * Shortslot: On - * GMODE_PERFORMANCE Rateset: 1b, 2b, 5.5b, 6b, 9, 11b, 12b, 18, 24b, 36, 48, 54 - * Preamble: Short required - * Shortslot: On and required - * GMODE_LRS Rateset: 1b, 2b, 5.5b, 11b - * Extended Rateset: 6, 9, 12, 18, 24, 36, 48, 54 - * Preamble: Long - * Shortslot: Auto + * GMODE_LEGACY_B + * Rateset: 1b, 2b, 5.5, 11 + * Preamble: Long + * Shortslot: Off + * GMODE_AUTO + * Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54 + * Extended Rateset: 6, 9, 12, 48 + * Preamble: Long + * Shortslot: Auto + * GMODE_ONLY + * Rateset: 1b, 2b, 5.5b, 11b, 18, 24b, 36, 54 + * Extended Rateset: 6b, 9, 12b, 48 + * Preamble: Short required + * Shortslot: Auto + * GMODE_B_DEFERRED + * Rateset: 1b, 2b, 5.5b, 11b, 18, 24, 36, 54 + * Extended Rateset: 6, 9, 12, 48 + * Preamble: Long + * Shortslot: On + * GMODE_PERFORMANCE + * Rateset: 1b, 2b, 5.5b, 6b, 9, 11b, 12b, 18, 24b, 36, 48, 54 + * Preamble: Short required + * Shortslot: On and required + * GMODE_LRS + * Rateset: 1b, 2b, 5.5b, 11b + * Extended Rateset: 6, 9, 12, 18, 24, 36, 48, 54 + * Preamble: Long + * Shortslot: Auto */ #define GMODE_LEGACY_B 0 #define GMODE_AUTO 1 @@ -544,12 +500,18 @@ extern const u8 wme_fifo2ac[]; #define BRCMS_N_SGI_40 0x02 /* defines used by the nrate iovar */ -#define NRATE_MCS_INUSE 0x00000080 /* MSC in use,indicates b0-6 holds an mcs */ -#define NRATE_RATE_MASK 0x0000007f /* rate/mcs value */ -#define NRATE_STF_MASK 0x0000ff00 /* stf mode mask: siso, cdd, stbc, sdm */ -#define NRATE_STF_SHIFT 8 /* stf mode shift */ -#define NRATE_OVERRIDE 0x80000000 /* bit indicates override both rate & mode */ -#define NRATE_OVERRIDE_MCS_ONLY 0x40000000 /* bit indicate to override mcs only */ +/* MSC in use,indicates b0-6 holds an mcs */ +#define NRATE_MCS_INUSE 0x00000080 +/* rate/mcs value */ +#define NRATE_RATE_MASK 0x0000007f +/* stf mode mask: siso, cdd, stbc, sdm */ +#define NRATE_STF_MASK 0x0000ff00 +/* stf mode shift */ +#define NRATE_STF_SHIFT 8 +/* bit indicates override both rate & mode */ +#define NRATE_OVERRIDE 0x80000000 +/* bit indicate to override mcs only */ +#define NRATE_OVERRIDE_MCS_ONLY 0x40000000 #define NRATE_SGI_MASK 0x00800000 /* sgi mode */ #define NRATE_SGI_SHIFT 23 /* sgi mode */ #define NRATE_LDPC_CODING 0x00400000 /* bit indicates adv coding in use */ @@ -560,9 +522,11 @@ extern const u8 wme_fifo2ac[]; #define NRATE_STF_STBC 2 /* stf mode STBC */ #define NRATE_STF_SDM 3 /* stf mode SDM */ -#define ANT_SELCFG_MAX 4 /* max number of antenna configurations */ +/* max number of antenna configurations */ +#define ANT_SELCFG_MAX 4 -#define HIGHEST_SINGLE_STREAM_MCS 7 /* MCS values greater than this enable multiple streams */ +/* MCS values greater than this enable multiple streams */ +#define HIGHEST_SINGLE_STREAM_MCS 7 struct brcms_antselcfg { u8 ant_config[ANT_SELCFG_MAX]; /* antenna configuration */ @@ -570,9 +534,9 @@ struct brcms_antselcfg { }; /* common functions for every port */ -extern void *brcms_c_attach(struct brcms_info *wl, u16 vendor, u16 device, - uint unit, bool piomode, void *regsva, uint bustype, - void *btparam, uint *perr); +struct brcms_c_info * +brcms_c_attach(struct brcms_info *wl, u16 vendor, u16 device, uint unit, + bool piomode, void *regsva, struct pci_dev *btparam, uint *perr); extern uint brcms_c_detach(struct brcms_c_info *wlc); extern int brcms_c_up(struct brcms_c_info *wlc); extern uint brcms_c_down(struct brcms_c_info *wlc); @@ -609,14 +573,15 @@ extern void brcms_c_set_addrmatch(struct brcms_c_info *wlc, extern void brcms_c_wme_setparams(struct brcms_c_info *wlc, u16 aci, const struct ieee80211_tx_queue_params *arg, bool suspend); -extern struct brcms_pub *brcms_c_pub(void *wlc); +extern struct brcms_pub *brcms_c_pub(struct brcms_c_info *wlc); /* common functions for every port */ extern void brcms_c_mhf(struct brcms_c_info *wlc, u8 idx, u16 mask, u16 val, int bands); extern void brcms_c_rate_lookup_init(struct brcms_c_info *wlc, - wlc_rateset_t *rateset); -extern void brcms_default_rateset(struct brcms_c_info *wlc, wlc_rateset_t *rs); + struct brcms_c_rateset *rateset); +extern void brcms_default_rateset(struct brcms_c_info *wlc, + struct brcms_c_rateset *rs); extern void brcms_c_ampdu_flush(struct brcms_c_info *wlc, struct ieee80211_sta *sta, u16 tid); @@ -634,10 +599,10 @@ extern void brcms_c_set_ps_ctrl(struct brcms_c_info *wlc); extern void brcms_c_mctrl(struct brcms_c_info *wlc, u32 mask, u32 val); extern int brcms_c_module_register(struct brcms_pub *pub, - const char *name, void *hdl, - watchdog_fn_t watchdog_fn, down_fn_t down_fn); + const char *name, struct brcms_info *hdl, + int (*down_fn)(void *handle)); extern int brcms_c_module_unregister(struct brcms_pub *pub, const char *name, - void *hdl); + struct brcms_info *hdl); extern void brcms_c_suspend_mac_and_wait(struct brcms_c_info *wlc); extern void brcms_c_enable_mac(struct brcms_c_info *wlc); extern void brcms_c_associate_upd(struct brcms_c_info *wlc, bool state); @@ -659,7 +624,4 @@ extern bool brcms_c_radio_monitor_stop(struct brcms_c_info *wlc); #define BAND_2G_NAME "2.4G" #define BAND_5G_NAME "5G" -/* BMAC RPC: 7 u32 params: pkttotlen, fifo, commit, fid, txpktpend, pktflag, rpc_id */ -#define BRCMS_RPCTX_PARAMS 32 - #endif /* _BRCM_PUB_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/rate.c b/drivers/staging/brcm80211/brcmsmac/rate.c index f0e4b99..5fb0d9e 100644 --- a/drivers/staging/brcm80211/brcmsmac/rate.c +++ b/drivers/staging/brcm80211/brcmsmac/rate.c @@ -21,7 +21,10 @@ #include "pub.h" #include "rate.h" -/* Rate info per rate: It tells whether a rate is ofdm or not and its phy_rate value */ +/* + * Rate info per rate: It tells whether a rate is ofdm or not and its phy_rate + * value + */ const u8 rate_info[BRCM_MAXRATE + 1] = { /* 0 1 2 3 4 5 6 7 8 9 */ /* 0 */ 0x00, 0x00, 0x0a, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -139,20 +142,25 @@ const struct brcms_mcs_info mcs_table[MCS_TABLE_SIZE] = { {0, 6000, 0, CEIL(6000 * 10, 9), 0x00, BRCM_RATE_6M}, }; -/* phycfg for legacy OFDM frames: code rate, modulation scheme, spatial streams - * Number of spatial streams: always 1 - * other fields: refer to table 78 of section 17.3.2.2 of the original .11a standard +/* + * phycfg for legacy OFDM frames: code rate, modulation scheme, spatial streams + * Number of spatial streams: always 1 other fields: refer to table 78 of + * section 17.3.2.2 of the original .11a standard */ struct legacy_phycfg { u32 rate_ofdm; /* ofdm mac rate */ - u8 tx_phy_ctl3; /* phy ctl byte 3, code rate, modulation type, # of streams */ + /* phy ctl byte 3, code rate, modulation type, # of streams */ + u8 tx_phy_ctl3; }; -#define LEGACY_PHYCFG_TABLE_SIZE 12 /* Number of legacy_rate_cfg entries in the table */ +/* Number of legacy_rate_cfg entries in the table */ +#define LEGACY_PHYCFG_TABLE_SIZE 12 -/* In CCK mode LPPHY overloads OFDM Modulation bits with CCK Data Rate */ -/* Eventually MIMOPHY would also be converted to this format */ -/* 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps */ +/* + * In CCK mode LPPHY overloads OFDM Modulation bits with CCK Data Rate + * Eventually MIMOPHY would also be converted to this format + * 0 = 1Mbps; 1 = 2Mbps; 2 = 5.5Mbps; 3 = 11Mbps + */ static const struct legacy_phycfg legacy_phycfg_table[LEGACY_PHYCFG_TABLE_SIZE] = { {BRCM_RATE_1M, 0x00}, /* CCK 1Mbps, data rate 0 */ @@ -179,86 +187,89 @@ legacy_phycfg legacy_phycfg_table[LEGACY_PHYCFG_TABLE_SIZE] = { /* Hardware rates (also encodes default basic rates) */ -const wlc_rateset_t cck_ofdm_mimo_rates = { +const struct brcms_c_rateset cck_ofdm_mimo_rates = { 12, - { /* 1b, 2b, 5.5b, 6, 9, 11b, 12, 18, 24, 36, 48, 54 Mbps */ - 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60, - 0x6c}, + /* 1b, 2b, 5.5b, 6, 9, 11b, 12, 18, 24, 36, 48, */ + { 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60, + /* 54 Mbps */ + 0x6c}, 0x00, - {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} + { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00} }; -const wlc_rateset_t ofdm_mimo_rates = { +const struct brcms_c_rateset ofdm_mimo_rates = { 8, - { /* 6b, 9, 12b, 18, 24b, 36, 48, 54 Mbps */ - 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c}, + /* 6b, 9, 12b, 18, 24b, 36, 48, 54 Mbps */ + { 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c}, 0x00, - {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} + { 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00} }; /* Default ratesets that include MCS32 for 40BW channels */ -const wlc_rateset_t cck_ofdm_40bw_mimo_rates = { +const struct brcms_c_rateset cck_ofdm_40bw_mimo_rates = { 12, - { /* 1b, 2b, 5.5b, 6, 9, 11b, 12, 18, 24, 36, 48, 54 Mbps */ - 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60, - 0x6c}, + /* 1b, 2b, 5.5b, 6, 9, 11b, 12, 18, 24, 36, 48 */ + { 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60, + /* 54 Mbps */ + 0x6c}, 0x00, - {0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} + { 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00} }; -const wlc_rateset_t ofdm_40bw_mimo_rates = { +const struct brcms_c_rateset ofdm_40bw_mimo_rates = { 8, - { /* 6b, 9, 12b, 18, 24b, 36, 48, 54 Mbps */ - 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c}, + /* 6b, 9, 12b, 18, 24b, 36, 48, 54 Mbps */ + { 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c}, 0x00, - {0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} + { 0xff, 0xff, 0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00} }; -const wlc_rateset_t cck_ofdm_rates = { +const struct brcms_c_rateset cck_ofdm_rates = { 12, - { /* 1b, 2b, 5.5b, 6, 9, 11b, 12, 18, 24, 36, 48, 54 Mbps */ - 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60, - 0x6c}, + /* 1b, 2b, 5.5b, 6, 9, 11b, 12, 18, 24, 36, 48,*/ + { 0x82, 0x84, 0x8b, 0x0c, 0x12, 0x96, 0x18, 0x24, 0x30, 0x48, 0x60, + /*54 Mbps */ + 0x6c}, 0x00, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00} }; -const wlc_rateset_t gphy_legacy_rates = { +const struct brcms_c_rateset gphy_legacy_rates = { 4, - { /* 1b, 2b, 5.5b, 11b Mbps */ - 0x82, 0x84, 0x8b, 0x96}, + /* 1b, 2b, 5.5b, 11b Mbps */ + { 0x82, 0x84, 0x8b, 0x96}, 0x00, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00} }; -const wlc_rateset_t ofdm_rates = { +const struct brcms_c_rateset ofdm_rates = { 8, - { /* 6b, 9, 12b, 18, 24b, 36, 48, 54 Mbps */ - 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c}, + /* 6b, 9, 12b, 18, 24b, 36, 48, 54 Mbps */ + { 0x8c, 0x12, 0x98, 0x24, 0xb0, 0x48, 0x60, 0x6c}, 0x00, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00} }; -const wlc_rateset_t cck_rates = { +const struct brcms_c_rateset cck_rates = { 4, - { /* 1b, 2b, 5.5, 11 Mbps */ - 0x82, 0x84, 0x0b, 0x16}, + /* 1b, 2b, 5.5, 11 Mbps */ + { 0x82, 0x84, 0x0b, 0x16}, 0x00, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00} + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00} }; /* check if rateset is valid. * if check_brate is true, rateset without a basic rate is considered NOT valid. */ -static bool brcms_c_rateset_valid(wlc_rateset_t *rs, bool check_brate) +static bool brcms_c_rateset_valid(struct brcms_c_rateset *rs, bool check_brate) { uint idx; @@ -276,19 +287,20 @@ static bool brcms_c_rateset_valid(wlc_rateset_t *rs, bool check_brate) return false; } -void brcms_c_rateset_mcs_upd(wlc_rateset_t *rs, u8 txstreams) +void brcms_c_rateset_mcs_upd(struct brcms_c_rateset *rs, u8 txstreams) { int i; for (i = txstreams; i < MAX_STREAMS_SUPPORTED; i++) rs->mcs[i] = 0; } -/* filter based on hardware rateset, and sort filtered rateset with basic bit(s) preserved, - * and check if resulting rateset is valid. +/* + * filter based on hardware rateset, and sort filtered rateset with basic + * bit(s) preserved, and check if resulting rateset is valid. */ bool -brcms_c_rate_hwrs_filter_sort_validate(wlc_rateset_t *rs, - const wlc_rateset_t *hw_rs, +brcms_c_rate_hwrs_filter_sort_validate(struct brcms_c_rateset *rs, + const struct brcms_c_rateset *hw_rs, bool check_brate, u8 txstreams) { u8 rateset[BRCM_MAXRATE + 1]; @@ -328,10 +340,10 @@ brcms_c_rate_hwrs_filter_sort_validate(wlc_rateset_t *rs, } /* calculate the rate of a rx'd frame and return it as a ratespec */ -ratespec_t brcms_c_compute_rspec(struct d11rxhdr *rxh, u8 *plcp) +u32 brcms_c_compute_rspec(struct d11rxhdr *rxh, u8 *plcp) { int phy_type; - ratespec_t rspec = PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT; + u32 rspec = PHY_TXC1_BW_20MHZ << RSPEC_BW_SHIFT; phy_type = ((rxh->RxChan & RXS_CHAN_PHYTYPE_MASK) >> RXS_CHAN_PHYTYPE_SHIFT); @@ -377,9 +389,10 @@ ratespec_t brcms_c_compute_rspec(struct d11rxhdr *rxh, u8 *plcp) } /* copy rateset src to dst as-is (no masking or sorting) */ -void brcms_c_rateset_copy(const wlc_rateset_t *src, wlc_rateset_t *dst) +void brcms_c_rateset_copy(const struct brcms_c_rateset *src, + struct brcms_c_rateset *dst) { - memcpy(dst, src, sizeof(wlc_rateset_t)); + memcpy(dst, src, sizeof(struct brcms_c_rateset)); } /* @@ -392,8 +405,8 @@ void brcms_c_rateset_copy(const wlc_rateset_t *src, wlc_rateset_t *dst) * 'xmask' is the copy mask (typically 0x7f or 0xff). */ void -brcms_c_rateset_filter(wlc_rateset_t *src, wlc_rateset_t *dst, bool basic_only, - u8 rates, uint xmask, bool mcsallow) +brcms_c_rateset_filter(struct brcms_c_rateset *src, struct brcms_c_rateset *dst, + bool basic_only, u8 rates, uint xmask, bool mcsallow) { uint i; uint r; @@ -423,24 +436,24 @@ brcms_c_rateset_filter(wlc_rateset_t *src, wlc_rateset_t *dst, bool basic_only, * and fill rs_tgt with result */ void -brcms_c_rateset_default(wlc_rateset_t *rs_tgt, const wlc_rateset_t *rs_hw, - uint phy_type, int bandtype, bool cck_only, uint rate_mask, - bool mcsallow, u8 bw, u8 txstreams) +brcms_c_rateset_default(struct brcms_c_rateset *rs_tgt, + const struct brcms_c_rateset *rs_hw, + uint phy_type, int bandtype, bool cck_only, + uint rate_mask, bool mcsallow, u8 bw, u8 txstreams) { - const wlc_rateset_t *rs_dflt; - wlc_rateset_t rs_sel; + const struct brcms_c_rateset *rs_dflt; + struct brcms_c_rateset rs_sel; if ((PHYTYPE_IS(phy_type, PHY_TYPE_HT)) || (PHYTYPE_IS(phy_type, PHY_TYPE_N)) || (PHYTYPE_IS(phy_type, PHY_TYPE_LCN)) || (PHYTYPE_IS(phy_type, PHY_TYPE_SSN))) { - if (BAND_5G(bandtype)) { + if (BAND_5G(bandtype)) rs_dflt = (bw == BRCMS_20_MHZ ? &ofdm_mimo_rates : &ofdm_40bw_mimo_rates); - } else { + else rs_dflt = (bw == BRCMS_20_MHZ ? &cck_ofdm_mimo_rates : &cck_ofdm_40bw_mimo_rates); - } } else if (PHYTYPE_IS(phy_type, PHY_TYPE_LP)) { rs_dflt = (BAND_5G(bandtype)) ? &ofdm_rates : &cck_ofdm_rates; } else if (PHYTYPE_IS(phy_type, PHY_TYPE_A)) { @@ -475,21 +488,21 @@ s16 brcms_c_rate_legacy_phyctl(uint rate) return -1; } -void brcms_c_rateset_mcs_clear(wlc_rateset_t *rateset) +void brcms_c_rateset_mcs_clear(struct brcms_c_rateset *rateset) { uint i; for (i = 0; i < MCSSET_LEN; i++) rateset->mcs[i] = 0; } -void brcms_c_rateset_mcs_build(wlc_rateset_t *rateset, u8 txstreams) +void brcms_c_rateset_mcs_build(struct brcms_c_rateset *rateset, u8 txstreams) { memcpy(&rateset->mcs[0], &cck_ofdm_mimo_rates.mcs[0], MCSSET_LEN); brcms_c_rateset_mcs_upd(rateset, txstreams); } /* Based on bandwidth passed, allow/disallow MCS 32 in the rateset */ -void brcms_c_rateset_bw_mcs_filter(wlc_rateset_t *rateset, u8 bw) +void brcms_c_rateset_bw_mcs_filter(struct brcms_c_rateset *rateset, u8 bw) { if (bw == BRCMS_40_MHZ) setbit(rateset->mcs, 32); diff --git a/drivers/staging/brcm80211/brcmsmac/rate.h b/drivers/staging/brcm80211/brcmsmac/rate.h index dbfd3e5..39e1796 100644 --- a/drivers/staging/brcm80211/brcmsmac/rate.h +++ b/drivers/staging/brcm80211/brcmsmac/rate.h @@ -20,22 +20,28 @@ #include "types.h" extern const u8 rate_info[]; -extern const struct brcms_rateset cck_ofdm_mimo_rates; -extern const struct brcms_rateset ofdm_mimo_rates; -extern const struct brcms_rateset cck_ofdm_rates; -extern const struct brcms_rateset ofdm_rates; -extern const struct brcms_rateset cck_rates; -extern const struct brcms_rateset gphy_legacy_rates; -extern const struct brcms_rateset wlc_lrs_rates; -extern const struct brcms_rateset rate_limit_1_2; +extern const struct brcms_c_rateset cck_ofdm_mimo_rates; +extern const struct brcms_c_rateset ofdm_mimo_rates; +extern const struct brcms_c_rateset cck_ofdm_rates; +extern const struct brcms_c_rateset ofdm_rates; +extern const struct brcms_c_rateset cck_rates; +extern const struct brcms_c_rateset gphy_legacy_rates; +extern const struct brcms_c_rateset wlc_lrs_rates; +extern const struct brcms_c_rateset rate_limit_1_2; struct brcms_mcs_info { - u32 phy_rate_20; /* phy rate in kbps [20Mhz] */ - u32 phy_rate_40; /* phy rate in kbps [40Mhz] */ - u32 phy_rate_20_sgi; /* phy rate in kbps [20Mhz] with SGI */ - u32 phy_rate_40_sgi; /* phy rate in kbps [40Mhz] with SGI */ - u8 tx_phy_ctl3; /* phy ctl byte 3, code rate, modulation type, # of streams */ - u8 leg_ofdm; /* matching legacy ofdm rate in 500bkps */ + /* phy rate in kbps [20Mhz] */ + u32 phy_rate_20; + /* phy rate in kbps [40Mhz] */ + u32 phy_rate_40; + /* phy rate in kbps [20Mhz] with SGI */ + u32 phy_rate_20_sgi; + /* phy rate in kbps [40Mhz] with SGI */ + u32 phy_rate_40_sgi; + /* phy ctl byte 3, code rate, modulation type, # of streams */ + u8 tx_phy_ctl3; + /* matching legacy ofdm rate in 500bkps */ + u8 leg_ofdm; }; #define BRCMS_MAXMCS 32 /* max valid mcs index */ @@ -49,11 +55,18 @@ extern const struct brcms_mcs_info mcs_table[]; #define MCS_TXS_MASK 0xc0 /* num tx streams - 1 bit mask */ #define MCS_TXS_SHIFT 6 /* num tx streams - 1 bit shift */ #define MCS_CR(_mcs) (mcs_table[_mcs].tx_phy_ctl3 & MCS_CR_MASK) -#define MCS_MOD(_mcs) ((mcs_table[_mcs].tx_phy_ctl3 & MCS_MOD_MASK) >> MCS_MOD_SHIFT) -#define MCS_TXS(_mcs) ((mcs_table[_mcs].tx_phy_ctl3 & MCS_TXS_MASK) >> MCS_TXS_SHIFT) + +#define MCS_MOD(_mcs) \ + ((mcs_table[_mcs].tx_phy_ctl3 & MCS_MOD_MASK) >> MCS_MOD_SHIFT) + +#define MCS_TXS(_mcs) \ + ((mcs_table[_mcs].tx_phy_ctl3 & MCS_TXS_MASK) >> MCS_TXS_SHIFT) + #define MCS_RATE(_mcs, _is40, _sgi) (_sgi ? \ - (_is40 ? mcs_table[_mcs].phy_rate_40_sgi : mcs_table[_mcs].phy_rate_20_sgi) : \ + (_is40 ? mcs_table[_mcs].phy_rate_40_sgi : \ + mcs_table[_mcs].phy_rate_20_sgi) : \ (_is40 ? mcs_table[_mcs].phy_rate_40 : mcs_table[_mcs].phy_rate_20)) + #define VALID_MCS(_mcs) ((_mcs < MCS_TABLE_SIZE)) /* Macro to use the rate_info table */ @@ -62,46 +75,78 @@ extern const struct brcms_mcs_info mcs_table[]; /* convert 500kbps to bps */ #define BRCMS_RATE_500K_TO_BPS(rate) ((rate) * 500000) -/* rate spec : holds rate and mode specific information required to generate a tx frame. */ -/* Legacy CCK and OFDM information is held in the same manner as was done in the past */ -/* (in the lower byte) the upper 3 bytes primarily hold MIMO specific information */ +/* + * rate spec : holds rate and mode specific information required to generate a + * tx frame. Legacy CCK and OFDM information is held in the same manner as was + * done in the past (in the lower byte) the upper 3 bytes primarily hold MIMO + * specific information + */ /* rate spec bit fields */ -#define RSPEC_RATE_MASK 0x0000007F /* Either 500Kbps units or MIMO MCS idx */ -#define RSPEC_MIMORATE 0x08000000 /* mimo MCS is stored in RSPEC_RATE_MASK */ -#define RSPEC_BW_MASK 0x00000700 /* mimo bw mask */ -#define RSPEC_BW_SHIFT 8 /* mimo bw shift */ -#define RSPEC_STF_MASK 0x00003800 /* mimo Space/Time/Frequency mode mask */ -#define RSPEC_STF_SHIFT 11 /* mimo Space/Time/Frequency mode shift */ -#define RSPEC_CT_MASK 0x0000C000 /* mimo coding type mask */ -#define RSPEC_CT_SHIFT 14 /* mimo coding type shift */ -#define RSPEC_STC_MASK 0x00300000 /* mimo num STC streams per PLCP defn. */ -#define RSPEC_STC_SHIFT 20 /* mimo num STC streams per PLCP defn. */ -#define RSPEC_LDPC_CODING 0x00400000 /* mimo bit indicates adv coding in use */ -#define RSPEC_SHORT_GI 0x00800000 /* mimo bit indicates short GI in use */ -#define RSPEC_OVERRIDE 0x80000000 /* bit indicates override both rate & mode */ -#define RSPEC_OVERRIDE_MCS_ONLY 0x40000000 /* bit indicates override rate only */ + +/* Either 500Kbps units or MIMO MCS idx */ +#define RSPEC_RATE_MASK 0x0000007F +/* mimo MCS is stored in RSPEC_RATE_MASK */ +#define RSPEC_MIMORATE 0x08000000 +/* mimo bw mask */ +#define RSPEC_BW_MASK 0x00000700 +/* mimo bw shift */ +#define RSPEC_BW_SHIFT 8 +/* mimo Space/Time/Frequency mode mask */ +#define RSPEC_STF_MASK 0x00003800 +/* mimo Space/Time/Frequency mode shift */ +#define RSPEC_STF_SHIFT 11 +/* mimo coding type mask */ +#define RSPEC_CT_MASK 0x0000C000 +/* mimo coding type shift */ +#define RSPEC_CT_SHIFT 14 +/* mimo num STC streams per PLCP defn. */ +#define RSPEC_STC_MASK 0x00300000 +/* mimo num STC streams per PLCP defn. */ +#define RSPEC_STC_SHIFT 20 +/* mimo bit indicates adv coding in use */ +#define RSPEC_LDPC_CODING 0x00400000 +/* mimo bit indicates short GI in use */ +#define RSPEC_SHORT_GI 0x00800000 +/* bit indicates override both rate & mode */ +#define RSPEC_OVERRIDE 0x80000000 +/* bit indicates override rate only */ +#define RSPEC_OVERRIDE_MCS_ONLY 0x40000000 #define BRCMS_HTPHY 127 /* HT PHY Membership */ #define RSPEC_ACTIVE(rspec) (rspec & (RSPEC_RATE_MASK | RSPEC_MIMORATE)) -#define RSPEC2RATE(rspec) ((rspec & RSPEC_MIMORATE) ? \ - MCS_RATE((rspec & RSPEC_RATE_MASK), RSPEC_IS40MHZ(rspec), RSPEC_ISSGI(rspec)) : \ + +#define RSPEC2RATE(rspec) \ + ((rspec & RSPEC_MIMORATE) ? \ + MCS_RATE((rspec & RSPEC_RATE_MASK), RSPEC_IS40MHZ(rspec), \ + RSPEC_ISSGI(rspec)) : \ (rspec & RSPEC_RATE_MASK)) + /* return rate in unit of 500Kbps -- for internal use in wlc_rate_sel.c */ -#define RSPEC2RATE500K(rspec) ((rspec & RSPEC_MIMORATE) ? \ - MCS_RATE((rspec & RSPEC_RATE_MASK), state->is40bw, RSPEC_ISSGI(rspec))/500 : \ - (rspec & RSPEC_RATE_MASK)) -#define CRSPEC2RATE500K(rspec) ((rspec & RSPEC_MIMORATE) ? \ - MCS_RATE((rspec & RSPEC_RATE_MASK), RSPEC_IS40MHZ(rspec), RSPEC_ISSGI(rspec))/500 :\ - (rspec & RSPEC_RATE_MASK)) - -#define RSPEC2KBPS(rspec) (IS_MCS(rspec) ? RSPEC2RATE(rspec) : RSPEC2RATE(rspec)*500) +#define RSPEC2RATE500K(rspec) \ + ((rspec & RSPEC_MIMORATE) ? \ + MCS_RATE((rspec & RSPEC_RATE_MASK), state->is40bw, \ + RSPEC_ISSGI(rspec))/500 : \ + (rspec & RSPEC_RATE_MASK)) + +#define CRSPEC2RATE500K(rspec) \ + ((rspec & RSPEC_MIMORATE) ? \ + MCS_RATE((rspec & RSPEC_RATE_MASK), RSPEC_IS40MHZ(rspec), \ + RSPEC_ISSGI(rspec))/500 :\ + (rspec & RSPEC_RATE_MASK)) + +#define RSPEC2KBPS(rspec) \ + (IS_MCS(rspec) ? RSPEC2RATE(rspec) : RSPEC2RATE(rspec)*500) + #define RSPEC_PHYTXBYTE2(rspec) ((rspec & 0xff00) >> 8) + #define RSPEC_GET_BW(rspec) ((rspec & RSPEC_BW_MASK) >> RSPEC_BW_SHIFT) -#define RSPEC_IS40MHZ(rspec) ((((rspec & RSPEC_BW_MASK) >> RSPEC_BW_SHIFT) == \ - PHY_TXC1_BW_40MHZ) || (((rspec & RSPEC_BW_MASK) >> \ - RSPEC_BW_SHIFT) == PHY_TXC1_BW_40MHZ_DUP)) + +#define RSPEC_IS40MHZ(rspec) \ + ((((rspec & RSPEC_BW_MASK) >> RSPEC_BW_SHIFT) == PHY_TXC1_BW_40MHZ) || \ + (((rspec & RSPEC_BW_MASK) >> RSPEC_BW_SHIFT) == PHY_TXC1_BW_40MHZ_DUP)) + #define RSPEC_ISSGI(rspec) ((rspec & RSPEC_SHORT_GI) == RSPEC_SHORT_GI) #define RSPEC_MIMOPLCP3(rspec) ((rspec & 0xf00000) >> 16) #define PLCP3_ISSGI(plcp) (plcp & (RSPEC_SHORT_GI >> 16)) @@ -111,26 +156,35 @@ extern const struct brcms_mcs_info mcs_table[]; #define PLCP3_STC_MASK 0x30 #define PLCP3_STC_SHIFT 4 -/* Rate info table; takes a legacy rate or ratespec_t */ +/* Rate info table; takes a legacy rate or u32 */ #define IS_MCS(r) (r & RSPEC_MIMORATE) + #define IS_OFDM(r) (!IS_MCS(r) && (rate_info[(r) & RSPEC_RATE_MASK] & \ BRCMS_RATE_FLAG)) + #define IS_CCK(r) (!IS_MCS(r) && ( \ ((r) & BRCMS_RATE_MASK) == BRCM_RATE_1M || \ ((r) & BRCMS_RATE_MASK) == BRCM_RATE_2M || \ ((r) & BRCMS_RATE_MASK) == BRCM_RATE_5M5 || \ ((r) & BRCMS_RATE_MASK) == BRCM_RATE_11M)) -#define IS_SINGLE_STREAM(mcs) (((mcs) <= HIGHEST_SINGLE_STREAM_MCS) || ((mcs) == 32)) + +#define IS_SINGLE_STREAM(mcs) \ + (((mcs) <= HIGHEST_SINGLE_STREAM_MCS) || ((mcs) == 32)) + #define CCK_RSPEC(cck) ((cck) & RSPEC_RATE_MASK) + #define OFDM_RSPEC(ofdm) (((ofdm) & RSPEC_RATE_MASK) |\ (PHY_TXC1_MODE_CDD << RSPEC_STF_SHIFT)) -#define LEGACY_RSPEC(rate) (IS_CCK(rate) ? CCK_RSPEC(rate) : OFDM_RSPEC(rate)) + +#define LEGACY_RSPEC(rate) \ + (IS_CCK(rate) ? CCK_RSPEC(rate) : OFDM_RSPEC(rate)) #define MCS_RSPEC(mcs) (((mcs) & RSPEC_RATE_MASK) | RSPEC_MIMORATE | \ (IS_SINGLE_STREAM(mcs) ? (PHY_TXC1_MODE_CDD << RSPEC_STF_SHIFT) : \ (PHY_TXC1_MODE_SDM << RSPEC_STF_SHIFT))) -/* Convert encoded rate value in plcp header to numerical rates in 500 KHz increments */ +/* Convert encoded rate value in plcp header to numerical rates in 500 KHz + * increments */ extern const u8 ofdm_rate_lookup[]; #define OFDM_PHY2MAC_RATE(rlpt) (ofdm_rate_lookup[rlpt & 0x7]) #define CCK_PHY2MAC_RATE(signal) (signal/5) @@ -140,34 +194,36 @@ extern const u8 ofdm_rate_lookup[]; #define BRCMS_RATES_CCK 1 #define BRCMS_RATES_OFDM 2 -/* sanitize, and sort a rateset with the basic bit(s) preserved, validate rateset */ +/* sanitize, and sort a rateset with the basic bit(s) preserved, validate + * rateset */ extern bool -brcms_c_rate_hwrs_filter_sort_validate(struct brcms_rateset *rs, - const struct brcms_rateset *hw_rs, +brcms_c_rate_hwrs_filter_sort_validate(struct brcms_c_rateset *rs, + const struct brcms_c_rateset *hw_rs, bool check_brate, u8 txstreams); /* copy rateset src to dst as-is (no masking or sorting) */ -extern void brcms_c_rateset_copy(const struct brcms_rateset *src, - struct brcms_rateset *dst); +extern void brcms_c_rateset_copy(const struct brcms_c_rateset *src, + struct brcms_c_rateset *dst); /* would be nice to have these documented ... */ -extern ratespec_t brcms_c_compute_rspec(struct d11rxhdr *rxh, u8 *plcp); +extern u32 brcms_c_compute_rspec(struct d11rxhdr *rxh, u8 *plcp); -extern void brcms_c_rateset_filter(struct brcms_rateset *src, - struct brcms_rateset *dst, bool basic_only, u8 rates, uint xmask, +extern void brcms_c_rateset_filter(struct brcms_c_rateset *src, + struct brcms_c_rateset *dst, bool basic_only, u8 rates, uint xmask, bool mcsallow); extern void -brcms_c_rateset_default(struct brcms_rateset *rs_tgt, - const struct brcms_rateset *rs_hw, uint phy_type, +brcms_c_rateset_default(struct brcms_c_rateset *rs_tgt, + const struct brcms_c_rateset *rs_hw, uint phy_type, int bandtype, bool cck_only, uint rate_mask, bool mcsallow, u8 bw, u8 txstreams); extern s16 brcms_c_rate_legacy_phyctl(uint rate); -extern void brcms_c_rateset_mcs_upd(struct brcms_rateset *rs, u8 txstreams); -extern void brcms_c_rateset_mcs_clear(struct brcms_rateset *rateset); -extern void brcms_c_rateset_mcs_build(struct brcms_rateset *rateset, +extern void brcms_c_rateset_mcs_upd(struct brcms_c_rateset *rs, u8 txstreams); +extern void brcms_c_rateset_mcs_clear(struct brcms_c_rateset *rateset); +extern void brcms_c_rateset_mcs_build(struct brcms_c_rateset *rateset, u8 txstreams); -extern void brcms_c_rateset_bw_mcs_filter(struct brcms_rateset *rateset, u8 bw); +extern void brcms_c_rateset_bw_mcs_filter(struct brcms_c_rateset *rateset, + u8 bw); #endif /* _BRCM_RATE_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/scb.h b/drivers/staging/brcm80211/brcmsmac/scb.h index d6c8328..efa5047 100644 --- a/drivers/staging/brcm80211/brcmsmac/scb.h +++ b/drivers/staging/brcm80211/brcmsmac/scb.h @@ -23,13 +23,15 @@ #include "types.h" #define AMPDU_TX_BA_MAX_WSIZE 64 /* max Tx ba window size (in pdu) */ + /* structure to store per-tid state for the ampdu initiator */ struct scb_ampdu_tid_ini { - u8 tx_in_transit; /* number of pending mpdus in transit in driver */ - u8 tid; /* initiator tid for easy lookup */ - u8 txretry[AMPDU_TX_BA_MAX_WSIZE]; /* tx retry count; indexed by seq modulo */ - struct scb *scb; /* backptr for easy lookup */ - u8 ba_wsize; /* negotiated ba window size (in pdu) */ + u8 tx_in_transit; /* number of pending mpdus in transit in driver */ + u8 tid; /* initiator tid for easy lookup */ + /* tx retry count; indexed by seq modulo */ + u8 txretry[AMPDU_TX_BA_MAX_WSIZE]; + struct scb *scb; /* backptr for easy lookup */ + u8 ba_wsize; /* negotiated ba window size (in pdu) */ }; #define AMPDU_MAX_SCB_TID NUMPRIO @@ -43,9 +45,10 @@ struct scb_ampdu { u32 max_rx_ampdu_bytes; /* max ampdu rcv length; 8k, 16k, 32k, 64k */ struct pktq txq; /* sdu transmit queue pending aggregation */ - /* This could easily be a ini[] pointer and we keep this info in wl itself instead - * of having mac80211 hold it for us. Also could be made dynamic per tid instead of - * static. + /* + * This could easily be a ini[] pointer and we keep this info in wl + * itself instead of having mac80211 hold it for us. Also could be made + * dynamic per tid instead of static. */ /* initiator info - per tid (NUMPRIO): */ struct scb_ampdu_tid_ini ini[AMPDU_MAX_SCB_TID]; @@ -56,18 +59,17 @@ struct scb_ampdu { /* station control block - one per remote MAC address */ struct scb { u32 magic; - u32 flags; /* various bit flags as defined below */ - u32 flags2; /* various bit flags2 as defined below */ - u8 state; /* current state bitfield of auth/assoc process */ + u32 flags; /* various bit flags as defined below */ + u32 flags2; /* various bit flags2 as defined below */ + u8 state; /* current state bitfield of auth/assoc process */ u8 ea[ETH_ALEN]; /* station address */ - void *fragbuf[NUMPRIO]; /* defragmentation buffer per prio */ - uint fragresid[NUMPRIO]; /* #bytes unused in frag buffer per prio */ + uint fragresid[NUMPRIO];/* #bytes unused in frag buffer per prio */ u16 seqctl[NUMPRIO]; /* seqctl of last received frame (for dups) */ - u16 seqctl_nonqos; /* seqctl of last received frame (for dups) for - * non-QoS data and management - */ - u16 seqnum[NUMPRIO]; /* WME: driver maintained sw seqnum per priority */ + /* seqctl of last received frame (for dups) for non-QoS data and + * management */ + u16 seqctl_nonqos; + u16 seqnum[NUMPRIO];/* WME: driver maintained sw seqnum per priority */ struct scb_ampdu scb_ampdu; /* AMPDU state including per tid info */ }; diff --git a/drivers/staging/brcm80211/brcmsmac/srom.c b/drivers/staging/brcm80211/brcmsmac/srom.c index f39442e..a8f7c00 100644 --- a/drivers/staging/brcm80211/brcmsmac/srom.c +++ b/drivers/staging/brcm80211/brcmsmac/srom.c @@ -18,6 +18,7 @@ #include <linux/string.h> #include <linux/io.h> #include <linux/etherdevice.h> +#include <linux/crc8.h> #include <stdarg.h> #include <chipcommon.h> @@ -33,10 +34,19 @@ ((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 */ +/* 500 ms after write enable/disable toggle */ +#define WRITE_ENABLE_DELAY 500 +/* 20 ms between each word write */ +#define WRITE_WORD_DELAY 20 #endif +/* + * SROM CRC8 polynomial value: + * + * x^8 + x^7 +x^6 + x^4 + x^2 + 1 + */ +#define SROM_CRC8_POLY 0xAB + /* Maximum srom: 6 Kilobits == 768 bytes */ #define SROM_MAX 768 @@ -260,7 +270,8 @@ /* Temp sense related entries */ #define SROM8_MPWR_RAWTS 90 #define SROM8_TS_SLP_OPT_CORRX 91 -/* FOC: freiquency offset correction, HWIQ: H/W IOCAL enable, IQSWP: IQ CAL swap disable */ +/* FOC: freiquency offset correction, HWIQ: H/W IOCAL enable, + * IQSWP: IQ CAL swap disable */ #define SROM8_FOC_HWIQ_IQSWP 92 /* Temperature delta for PHY calibration */ @@ -349,14 +360,17 @@ #define SROM9_PO_LOFDM40DUP 203 /* SROM flags (see sromvar_t) */ -#define SRFL_MORE 1 /* value continues as described by the next entry */ + +/* value continues as described by the next entry */ +#define SRFL_MORE 1 #define SRFL_NOFFS 2 /* value bits can't be all one's */ #define SRFL_PRHEX 4 /* value is in hexdecimal format */ #define SRFL_PRSIGN 8 /* value is in signed decimal format */ #define SRFL_CCODE 0x10 /* value is in country code format */ #define SRFL_ETHADDR 0x20 /* value is an Ethernet address */ #define SRFL_LEDDC 0x40 /* value is an LED duty cycle */ -#define SRFL_NOVAR 0x80 /* do not generate a nvram param, entry is for mfgc */ +/* do not generate a nvram param, entry is for mfgc */ +#define SRFL_NOVAR 0x80 /* Max. nvram variable table size */ #define MAXSZ_NVRAM_VARS 4096 @@ -375,17 +389,18 @@ struct brcms_varbuf { unsigned int size; /* current (residual) size in bytes */ }; -/* Assumptions: - * - Ethernet address spans across 3 consective words +/* + * Assumptions: + * - Ethernet address spans across 3 consecutive words * * Table rules: - * - Add multiple entries next to each other if a value spans across multiple words - * (even multiple fields in the same word) with each entry except the last having - * it's SRFL_MORE bit set. - * - Ethernet address entry does not follow above rule and must not have SRFL_MORE - * bit set. Its SRFL_ETHADDR bit implies it takes multiple words. - * - The last entry's name field must be NULL to indicate the end of the table. Other - * entries must have non-NULL name. + * - Add multiple entries next to each other if a value spans across multiple + * words (even multiple fields in the same word) with each entry except the + * last having it's SRFL_MORE bit set. + * - Ethernet address entry does not follow above rule and must not have + * SRFL_MORE bit set. Its SRFL_ETHADDR bit implies it takes multiple words. + * - The last entry's name field must be NULL to indicate the end of the table. + * Other entries must have non-NULL name. */ static const struct brcms_sromvar pci_sromvars[] = { {"devid", 0xffffff00, SRFL_PRHEX | SRFL_NOVAR, PCI_F0DEVID, 0xffff}, @@ -775,15 +790,15 @@ static const struct brcms_sromvar perpath_pci_sromvars[] = { {NULL, 0, 0, 0, 0} }; +static u8 srom_crc8_table[CRC8_TABLE_SIZE]; + static void _initvars_srom_pci(u8 sromrev, u16 *srom, uint off, struct brcms_varbuf *b); static int initvars_srom_pci(struct si_pub *sih, void *curmap, char **vars, uint *count); static int sprom_read_pci(struct si_pub *sih, u16 *sprom, uint wordoff, u16 *buf, uint nwords, bool check_crc); -#if defined(BCMNVRAMR) static int otp_read_pci(struct si_pub *sih, u16 *buf, uint bufsz); -#endif static int initvars_table(char *start, char *end, char **vars, uint *count); @@ -810,12 +825,12 @@ static int varbuf_append(struct brcms_varbuf *b, const char *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. + /* + * 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; @@ -853,8 +868,7 @@ static int varbuf_append(struct brcms_varbuf *b, const char *fmt, ...) * Initialize local vars from the right source for this platform. * Return 0 on success, nonzero on error. */ -int srom_var_init(struct si_pub *sih, uint bustype, void *curmap, - char **vars, uint *count) +int srom_var_init(struct si_pub *sih, void *curmap, char **vars, uint *count) { uint len; @@ -866,7 +880,7 @@ int srom_var_init(struct si_pub *sih, uint bustype, void *curmap, *vars = NULL; *count = 0; - if (curmap != NULL && bustype == PCI_BUS) + if (curmap != NULL) return initvars_srom_pci(sih, curmap, vars, count); return -EINVAL; @@ -874,13 +888,15 @@ int srom_var_init(struct si_pub *sih, uint bustype, void *curmap, static inline void ltoh16_buf(u16 *buf, unsigned int size) { - for (size /= 2; size; size--) + size /= 2; + while (size--) *(buf + size) = le16_to_cpu(*(buf + size)); } static inline void htol16_buf(u16 *buf, unsigned int size) { - for (size /= 2; size; size--) + size /= 2; + while (size--) *(buf + size) = cpu_to_le16(*(buf + size)); } @@ -901,28 +917,27 @@ sprom_read_pci(struct si_pub *sih, u16 *sprom, uint wordoff, 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. + 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 -ENODATA; - } /* fixup the endianness so crc8 will pass */ htol16_buf(buf, nwords * 2); - if (brcmu_crc8((u8 *) buf, nwords * 2, CRC8_INIT_VALUE) != - CRC8_GOOD_VALUE) { + if (crc8(srom_crc8_table, (u8 *) buf, nwords * 2, + CRC8_INIT_VALUE) != CRC8_GOOD_VALUE(srom_crc8_table)) /* DBG only pci always read srom4 first, then srom8/9 */ err = -EIO; - } + /* now correct the endianness of the byte array */ ltoh16_buf(buf, nwords * 2); } return err; } -#if defined(BCMNVRAMR) static int otp_read_pci(struct si_pub *sih, u16 *buf, uint bufsz) { u8 *otp; @@ -930,9 +945,8 @@ static int otp_read_pci(struct si_pub *sih, u16 *buf, uint bufsz) int err = 0; otp = kzalloc(OTP_SZ_MAX, GFP_ATOMIC); - if (otp == NULL) { + if (otp == NULL) return -ENOMEM; - } err = otp_read_region(sih, OTP_HW_RGN, (u16 *) otp, &sz); @@ -941,26 +955,25 @@ static int otp_read_pci(struct si_pub *sih, u16 *buf, uint bufsz) kfree(otp); /* Check CRC */ - if (buf[0] == 0xffff) { + 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 -ENODATA; - } /* fixup the endianness so crc8 will pass */ htol16_buf(buf, bufsz); - if (brcmu_crc8((u8 *) buf, SROM4_WORDS * 2, CRC8_INIT_VALUE) != - CRC8_GOOD_VALUE) { + if (crc8(srom_crc8_table, (u8 *) buf, SROM4_WORDS * 2, + CRC8_INIT_VALUE) != CRC8_GOOD_VALUE(srom_crc8_table)) err = -EIO; - } + /* 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. @@ -1084,8 +1097,10 @@ _initvars_srom_pci(u8 sromrev, u16 *srom, uint off, struct brcms_varbuf *b) *(oncount >> 24) (offcount >> 8) */ else if (flags & SRFL_LEDDC) { - u32 w32 = (((val >> 8) & 0xff) << 24) | /* oncount */ - (((val & 0xff)) << 8); /* offcount */ + u32 w32 = /* oncount */ + (((val >> 8) & 0xff) << 24) | + /* offcount */ + (((val & 0xff)) << 8); varbuf_append(b, "leddc=%d", w32); } else if (flags & SRFL_PRHEX) varbuf_append(b, "%s=0x%x", name, val); @@ -1119,7 +1134,6 @@ _initvars_srom_pci(u8 sromrev, u16 *srom, uint off, struct brcms_varbuf *b) if (pb + srv->off < off) continue; - /* This entry is for mfgc only. Don't generate param for it, */ if (srv->flags & SRFL_NOVAR) continue; @@ -1127,8 +1141,8 @@ _initvars_srom_pci(u8 sromrev, u16 *srom, uint off, struct brcms_varbuf *b) val = (w & srv->mask) >> mask_shift(srv->mask); width = mask_width(srv->mask); - /* Cheating: no per-path var is more than 1 word */ - + /* Cheating: no per-path var is more than + * 1 word */ if ((srv->flags & SRFL_NOFFS) && ((int)val == (1 << width) - 1)) continue; @@ -1167,6 +1181,8 @@ static int initvars_srom_pci(struct si_pub *sih, void *curmap, char **vars, return -ENOMEM; sromwindow = (u16 *) SROM_OFFSET(sih); + + crc8_populate_lsb(srom_crc8_table, SROM_CRC8_POLY); if (ai_is_sprom_available(sih)) { err = sprom_read_pci(sih, sromwindow, 0, srom, SROM_WORDS, true); @@ -1189,24 +1205,22 @@ static int initvars_srom_pci(struct si_pub *sih, void *curmap, char **vars, sromrev = 1; } } -#if defined(BCMNVRAMR) - /* Use OTP if SPROM not available */ else { + /* Use OTP if SPROM not available */ 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 - else - err = -ENODEV; -#endif if (!err) { /* Bitmask for the sromrev */ sr = 1 << sromrev; - /* srom version check: Current valid versions: 1, 2, 3, 4, 5, 8, 9 */ + /* + * srom version check: Current valid versions: 1, 2, 3, 4, 5, 8, + * 9 + */ if ((sr & 0x33e) == 0) { err = -EINVAL; goto errout; diff --git a/drivers/staging/brcm80211/brcmsmac/srom.h b/drivers/staging/brcm80211/brcmsmac/srom.h index efc4d1e..dd51156 100644 --- a/drivers/staging/brcm80211/brcmsmac/srom.h +++ b/drivers/staging/brcm80211/brcmsmac/srom.h @@ -20,8 +20,8 @@ #include "types.h" /* Prototypes */ -extern int srom_var_init(struct si_pub *sih, uint bus, void *curmap, - char **vars, uint *count); +extern int srom_var_init(struct si_pub *sih, void *curmap, char **vars, + uint *count); extern int srom_read(struct si_pub *sih, uint bus, void *curmap, uint byteoff, uint nbytes, u16 *buf, bool check_crc); diff --git a/drivers/staging/brcm80211/brcmsmac/stf.c b/drivers/staging/brcm80211/brcmsmac/stf.c index a55ff01..a4c5c63 100644 --- a/drivers/staging/brcm80211/brcmsmac/stf.c +++ b/drivers/staging/brcm80211/brcmsmac/stf.c @@ -22,7 +22,6 @@ #include "phy/phy_hal.h" #include "channel.h" #include "main.h" -#include "bmac.h" #include "stf.h" #define MIN_SPATIAL_EXPANSION 0 @@ -38,7 +37,7 @@ static void brcms_c_stf_stbc_rx_ht_update(struct brcms_c_info *wlc, int val); static void _brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc); static u16 _brcms_c_stf_phytxchain_sel(struct brcms_c_info *wlc, - ratespec_t rspec); + u32 rspec); #define NSTS_1 1 #define NSTS_2 2 @@ -69,7 +68,10 @@ static void brcms_c_stf_stbc_rx_ht_update(struct brcms_c_info *wlc, int val) } } -/* every WLC_TEMPSENSE_PERIOD seconds temperature check to decide whether to turn on/off txchain */ +/* + * every WLC_TEMPSENSE_PERIOD seconds temperature check to decide whether to + * turn on/off txchain. + */ void brcms_c_tempsense_upd(struct brcms_c_info *wlc) { struct brcms_phy_pub *pi = wlc->band->pi; @@ -81,21 +83,19 @@ void brcms_c_tempsense_upd(struct brcms_c_info *wlc) txchain = active_chains & 0xf; if (wlc->stf->txchain == wlc->stf->hw_txchain) { - if (txchain && (txchain < wlc->stf->hw_txchain)) { + if (txchain && (txchain < wlc->stf->hw_txchain)) /* turn off 1 tx chain */ brcms_c_stf_txchain_set(wlc, txchain, true); - } } else if (wlc->stf->txchain < wlc->stf->hw_txchain) { - if (txchain == wlc->stf->hw_txchain) { + if (txchain == wlc->stf->hw_txchain) /* turn back on txchain */ brcms_c_stf_txchain_set(wlc, txchain, true); - } } } void brcms_c_stf_ss_algo_channel_get(struct brcms_c_info *wlc, u16 *ss_algo_channel, - chanspec_t chanspec) + u16 chanspec) { struct tx_power power; u8 siso_mcs_id, cdd_mcs_id, stbc_mcs_id; @@ -120,16 +120,19 @@ brcms_c_stf_ss_algo_channel_get(struct brcms_c_info *wlc, u16 *ss_algo_channel, /* criteria to choose stf mode */ - /* the "+3dbm (12 0.25db units)" is to account for the fact that with CDD, tx occurs - * on both chains + /* + * the "+3dbm (12 0.25db units)" is to account for the fact that with + * CDD, tx occurs on both chains */ if (power.target[siso_mcs_id] > (power.target[cdd_mcs_id] + 12)) setbit(ss_algo_channel, PHY_TXC1_MODE_SISO); else setbit(ss_algo_channel, PHY_TXC1_MODE_CDD); - /* STBC is ORed into to algo channel as STBC requires per-packet SCB capability check - * so cannot be default mode of operation. One of SISO, CDD have to be set + /* + * STBC is ORed into to algo channel as STBC requires per-packet SCB + * capability check so cannot be default mode of operation. One of + * SISO, CDD have to be set */ if (power.target[siso_mcs_id] <= (power.target[stbc_mcs_id] + 12)) setbit(ss_algo_channel, PHY_TXC1_MODE_STBC); @@ -137,9 +140,8 @@ brcms_c_stf_ss_algo_channel_get(struct brcms_c_info *wlc, u16 *ss_algo_channel, static bool brcms_c_stf_stbc_tx_set(struct brcms_c_info *wlc, s32 int_val) { - if ((int_val != AUTO) && (int_val != OFF) && (int_val != ON)) { + if ((int_val != AUTO) && (int_val != OFF) && (int_val != ON)) return false; - } if ((int_val == ON) && (wlc->stf->txstreams == 1)) return false; @@ -159,9 +161,8 @@ static bool brcms_c_stf_stbc_tx_set(struct brcms_c_info *wlc, s32 int_val) bool brcms_c_stf_stbc_rx_set(struct brcms_c_info *wlc, s32 int_val) { if ((int_val != HT_CAP_RX_STBC_NO) - && (int_val != HT_CAP_RX_STBC_ONE_STREAM)) { + && (int_val != HT_CAP_RX_STBC_ONE_STREAM)) return false; - } if (BRCMS_STF_SS_STBC_RX(wlc)) { if ((int_val != HT_CAP_RX_STBC_NO) @@ -179,15 +180,13 @@ static int brcms_c_stf_txcore_set(struct brcms_c_info *wlc, u8 Nsts, BCMMSG(wlc->wiphy, "wl%d: Nsts %d core_mask %x\n", wlc->pub->unit, Nsts, core_mask); - if (BRCMS_BITSCNT(core_mask) > wlc->stf->txstreams) { + if (BRCMS_BITSCNT(core_mask) > wlc->stf->txstreams) core_mask = 0; - } if ((BRCMS_BITSCNT(core_mask) == wlc->stf->txstreams) && ((core_mask & ~wlc->stf->txchain) - || !(core_mask & wlc->stf->txchain))) { + || !(core_mask & wlc->stf->txchain))) core_mask = wlc->stf->txchain; - } wlc->stf->txcore[Nsts] = core_mask; /* Nsts = 1..4, txcore index = 1..4 */ @@ -236,7 +235,10 @@ int brcms_c_stf_txchain_set(struct brcms_c_info *wlc, s32 int_val, bool force) || !(txchain & wlc->stf->hw_txchain)) return -EINVAL; - /* if nrate override is configured to be non-SISO STF mode, reject reducing txchain to 1 */ + /* + * if nrate override is configured to be non-SISO STF mode, reject + * reducing txchain to 1 + */ txstreams = (u8) BRCMS_BITSCNT(txchain); if (txstreams > MAX_STREAMS_SUPPORTED) return -EINVAL; @@ -289,7 +291,10 @@ int brcms_c_stf_txchain_set(struct brcms_c_info *wlc, s32 int_val, bool force) return 0; } -/* update wlc->stf->ss_opmode which represents the operational stf_ss mode we're using */ +/* + * update wlc->stf->ss_opmode which represents the operational stf_ss mode + * we're using + */ int brcms_c_stf_ss_update(struct brcms_c_info *wlc, struct brcms_band *band) { int ret_code = 0; @@ -298,7 +303,10 @@ int brcms_c_stf_ss_update(struct brcms_c_info *wlc, struct brcms_band *band) prev_stf_ss = wlc->stf->ss_opmode; - /* NOTE: opmode can only be SISO or CDD as STBC is decided on a per-packet basis */ + /* + * NOTE: opmode can only be SISO or CDD as STBC is decided on a + * per-packet basis + */ if (BRCMS_STBC_CAP_PHY(wlc) && wlc->stf->ss_algosel_auto && (wlc->stf->ss_algo_channel != (u16) -1)) { @@ -340,7 +348,8 @@ int brcms_c_stf_attach(struct brcms_c_info *wlc) if (BRCMS_STBC_CAP_PHY(wlc)) { wlc->stf->ss_algosel_auto = true; - wlc->stf->ss_algo_channel = (u16) -1; /* Init the default value */ + /* Init the default value */ + wlc->stf->ss_algo_channel = (u16) -1; } return 0; } @@ -350,18 +359,20 @@ void brcms_c_stf_detach(struct brcms_c_info *wlc) } /* - * Centralized txant update function. call it whenever wlc->stf->txant and/or wlc->stf->txchain - * change + * Centralized txant update function. call it whenever wlc->stf->txant and/or + * wlc->stf->txchain change. * * Antennas are controlled by ucode indirectly, which drives PHY or GPIO to - * achieve various tx/rx antenna selection schemes + * achieve various tx/rx antenna selection schemes * - * legacy phy, bit 6 and bit 7 means antenna 0 and 1 respectively, bit6+bit7 means auto(last rx) - * for NREV<3, bit 6 and bit 7 means antenna 0 and 1 respectively, bit6+bit7 means last rx and - * do tx-antenna selection for SISO transmissions - * for NREV=3, bit 6 and bit _8_ means antenna 0 and 1 respectively, bit6+bit7 means last rx and - * do tx-antenna selection for SISO transmissions - * for NREV>=7, bit 6 and bit 7 mean antenna 0 and 1 respectively, nit6+bit7 means both cores active + * legacy phy, bit 6 and bit 7 means antenna 0 and 1 respectively, bit6+bit7 + * means auto(last rx). + * for NREV<3, bit 6 and bit 7 means antenna 0 and 1 respectively, bit6+bit7 + * means last rx and do tx-antenna selection for SISO transmissions + * for NREV=3, bit 6 and bit _8_ means antenna 0 and 1 respectively, bit6+bit7 + * means last rx and do tx-antenna selection for SISO transmissions + * for NREV>=7, bit 6 and bit 7 mean antenna 0 and 1 respectively, nit6+bit7 + * means both cores active */ static void _brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc) { @@ -376,9 +387,8 @@ static void _brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc) if (BRCMS_ISNPHY(wlc->band) && NREV_GE(wlc->band->phyrev, 3) - && NREV_LT(wlc->band->phyrev, 7)) { + && NREV_LT(wlc->band->phyrev, 7)) wlc->stf->phytxant = PHY_TXC_ANT_2; - } } else { if (BRCMS_ISLCNPHY(wlc->band) || BRCMS_ISSSLPNPHY(wlc->band)) @@ -415,22 +425,20 @@ void brcms_c_stf_phy_chain_calc(struct brcms_c_info *wlc) /* these parameter are intended to be used for all PHY types */ if (wlc->stf->hw_txchain == 0 || wlc->stf->hw_txchain == 0xf) { - if (BRCMS_ISNPHY(wlc->band)) { + if (BRCMS_ISNPHY(wlc->band)) wlc->stf->hw_txchain = TXCHAIN_DEF_NPHY; - } else { + else wlc->stf->hw_txchain = TXCHAIN_DEF; - } } wlc->stf->txchain = wlc->stf->hw_txchain; wlc->stf->txstreams = (u8) BRCMS_BITSCNT(wlc->stf->hw_txchain); if (wlc->stf->hw_rxchain == 0 || wlc->stf->hw_rxchain == 0xf) { - if (BRCMS_ISNPHY(wlc->band)) { + if (BRCMS_ISNPHY(wlc->band)) wlc->stf->hw_rxchain = RXCHAIN_DEF_NPHY; - } else { + else wlc->stf->hw_rxchain = RXCHAIN_DEF; - } } wlc->stf->rxchain = wlc->stf->hw_rxchain; @@ -445,24 +453,24 @@ void brcms_c_stf_phy_chain_calc(struct brcms_c_info *wlc) } static u16 _brcms_c_stf_phytxchain_sel(struct brcms_c_info *wlc, - ratespec_t rspec) + u32 rspec) { u16 phytxant = wlc->stf->phytxant; - if (RSPEC_STF(rspec) != PHY_TXC1_MODE_SISO) { + if (RSPEC_STF(rspec) != PHY_TXC1_MODE_SISO) phytxant = wlc->stf->txchain << PHY_TXC_ANT_SHIFT; - } else if (wlc->stf->txant == ANT_TX_DEF) + else if (wlc->stf->txant == ANT_TX_DEF) phytxant = wlc->stf->txchain << PHY_TXC_ANT_SHIFT; phytxant &= PHY_TXC_ANT_MASK; return phytxant; } -u16 brcms_c_stf_phytxchain_sel(struct brcms_c_info *wlc, ratespec_t rspec) +u16 brcms_c_stf_phytxchain_sel(struct brcms_c_info *wlc, u32 rspec) { return _brcms_c_stf_phytxchain_sel(wlc, rspec); } -u16 brcms_c_stf_d11hdrs_phyctl_txant(struct brcms_c_info *wlc, ratespec_t rspec) +u16 brcms_c_stf_d11hdrs_phyctl_txant(struct brcms_c_info *wlc, u32 rspec) { u16 phytxant = wlc->stf->phytxant; u16 mask = PHY_TXC_ANT_MASK; diff --git a/drivers/staging/brcm80211/brcmsmac/stf.h b/drivers/staging/brcm80211/brcmsmac/stf.h index 06c2a39..19f6580 100644 --- a/drivers/staging/brcm80211/brcmsmac/stf.h +++ b/drivers/staging/brcm80211/brcmsmac/stf.h @@ -25,7 +25,7 @@ extern void brcms_c_stf_detach(struct brcms_c_info *wlc); extern void brcms_c_tempsense_upd(struct brcms_c_info *wlc); extern void brcms_c_stf_ss_algo_channel_get(struct brcms_c_info *wlc, u16 *ss_algo_channel, - chanspec_t chanspec); + u16 chanspec); extern int brcms_c_stf_ss_update(struct brcms_c_info *wlc, struct brcms_band *band); extern void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc); @@ -35,8 +35,8 @@ extern bool brcms_c_stf_stbc_rx_set(struct brcms_c_info *wlc, s32 int_val); extern void brcms_c_stf_phy_txant_upd(struct brcms_c_info *wlc); extern void brcms_c_stf_phy_chain_calc(struct brcms_c_info *wlc); extern u16 brcms_c_stf_phytxchain_sel(struct brcms_c_info *wlc, - ratespec_t rspec); + u32 rspec); extern u16 brcms_c_stf_d11hdrs_phyctl_txant(struct brcms_c_info *wlc, - ratespec_t rspec); + u32 rspec); #endif /* _BRCM_STF_H_ */ diff --git a/drivers/staging/brcm80211/brcmsmac/types.h b/drivers/staging/brcm80211/brcmsmac/types.h index 823b5e4..6d17d7f 100644 --- a/drivers/staging/brcm80211/brcmsmac/types.h +++ b/drivers/staging/brcm80211/brcmsmac/types.h @@ -20,15 +20,6 @@ #include <linux/types.h> #include <linux/io.h> -/* Bus types */ -#define SI_BUS 0 /* SOC Interconnect */ -#define PCI_BUS 1 /* PCI target */ -#define SDIO_BUS 3 /* SDIO target */ -#define JTAG_BUS 4 /* JTAG */ -#define USB_BUS 5 /* USB (does not support R/W REG) */ -#define SPI_BUS 6 /* gSPI target */ -#define RPC_BUS 7 /* RPC target */ - #define WL_CHAN_FREQ_RANGE_2G 0 #define WL_CHAN_FREQ_RANGE_5GL 1 #define WL_CHAN_FREQ_RANGE_5GM 2 @@ -37,42 +28,71 @@ #define MAX_DMA_SEGS 4 /* boardflags */ -#define BFL_PACTRL 0x00000002 /* Board has gpio 9 controlling the PA */ -#define BFL_NOPLLDOWN 0x00000020 /* Not ok to power down the chip pll and oscillator */ -#define BFL_FEM 0x00000800 /* Board supports the Front End Module */ -#define BFL_EXTLNA 0x00001000 /* Board has an external LNA in 2.4GHz band */ -#define BFL_NOPA 0x00010000 /* Board has no PA */ -#define BFL_BUCKBOOST 0x00200000 /* Power topology uses BUCKBOOST */ -#define BFL_FEM_BT 0x00400000 /* Board has FEM and switch to share antenna w/ BT */ -#define BFL_NOCBUCK 0x00800000 /* Power topology doesn't use CBUCK */ -#define BFL_PALDO 0x02000000 /* Power topology uses PALDO */ -#define BFL_EXTLNA_5GHz 0x10000000 /* Board has an external LNA in 5GHz band */ + +/* Board has gpio 9 controlling the PA */ +#define BFL_PACTRL 0x00000002 +/* Not ok to power down the chip pll and oscillator */ +#define BFL_NOPLLDOWN 0x00000020 +/* Board supports the Front End Module */ +#define BFL_FEM 0x00000800 +/* Board has an external LNA in 2.4GHz band */ +#define BFL_EXTLNA 0x00001000 +/* Board has no PA */ +#define BFL_NOPA 0x00010000 +/* Power topology uses BUCKBOOST */ +#define BFL_BUCKBOOST 0x00200000 +/* Board has FEM and switch to share antenna w/ BT */ +#define BFL_FEM_BT 0x00400000 +/* Power topology doesn't use CBUCK */ +#define BFL_NOCBUCK 0x00800000 +/* Power topology uses PALDO */ +#define BFL_PALDO 0x02000000 +/* Board has an external LNA in 5GHz band */ +#define BFL_EXTLNA_5GHz 0x10000000 /* boardflags2 */ -#define BFL2_RXBB_INT_REG_DIS 0x00000001 /* Board has an external rxbb regulator */ -#define BFL2_APLL_WAR 0x00000002 /* Flag to implement alternative A-band PLL settings */ -#define BFL2_TXPWRCTRL_EN 0x00000004 /* Board permits enabling TX Power Control */ -#define BFL2_2X4_DIV 0x00000008 /* Board supports the 2X4 diversity switch */ -#define BFL2_5G_PWRGAIN 0x00000010 /* Board supports 5G band power gain */ -#define BFL2_PCIEWAR_OVR 0x00000020 /* Board overrides ASPM and Clkreq settings */ + +/* Board has an external rxbb regulator */ +#define BFL2_RXBB_INT_REG_DIS 0x00000001 +/* Flag to implement alternative A-band PLL settings */ +#define BFL2_APLL_WAR 0x00000002 +/* Board permits enabling TX Power Control */ +#define BFL2_TXPWRCTRL_EN 0x00000004 +/* Board supports the 2X4 diversity switch */ +#define BFL2_2X4_DIV 0x00000008 +/* Board supports 5G band power gain */ +#define BFL2_5G_PWRGAIN 0x00000010 +/* Board overrides ASPM and Clkreq settings */ +#define BFL2_PCIEWAR_OVR 0x00000020 #define BFL2_LEGACY 0x00000080 -#define BFL2_SKWRKFEM_BRD 0x00000100 /* 4321mcm93 board uses Skyworks FEM */ -#define BFL2_SPUR_WAR 0x00000200 /* Board has a WAR for clock-harmonic spurs */ -#define BFL2_GPLL_WAR 0x00000400 /* Flag to narrow G-band PLL loop b/w */ -#define BFL2_SINGLEANT_CCK 0x00001000 /* Tx CCK pkts on Ant 0 only */ -#define BFL2_2G_SPUR_WAR 0x00002000 /* WAR to reduce and avoid clock-harmonic spurs in 2G */ -#define BFL2_GPLL_WAR2 0x00010000 /* Flag to widen G-band PLL loop b/w */ +/* 4321mcm93 board uses Skyworks FEM */ +#define BFL2_SKWRKFEM_BRD 0x00000100 +/* Board has a WAR for clock-harmonic spurs */ +#define BFL2_SPUR_WAR 0x00000200 +/* Flag to narrow G-band PLL loop b/w */ +#define BFL2_GPLL_WAR 0x00000400 +/* Tx CCK pkts on Ant 0 only */ +#define BFL2_SINGLEANT_CCK 0x00001000 +/* WAR to reduce and avoid clock-harmonic spurs in 2G */ +#define BFL2_2G_SPUR_WAR 0x00002000 +/* Flag to widen G-band PLL loop b/w */ +#define BFL2_GPLL_WAR2 0x00010000 #define BFL2_IPALVLSHIFT_3P3 0x00020000 -#define BFL2_INTERNDET_TXIQCAL 0x00040000 /* Use internal envelope detector for TX IQCAL */ -#define BFL2_XTALBUFOUTEN 0x00080000 /* Keep the buffered Xtal output from radio "ON" - * Most drivers will turn it off without this flag - * to save power. - */ +/* Use internal envelope detector for TX IQCAL */ +#define BFL2_INTERNDET_TXIQCAL 0x00040000 +/* Keep the buffered Xtal output from radio "ON". Most drivers will turn it + * off without this flag to save power. */ +#define BFL2_XTALBUFOUTEN 0x00080000 -/* board specific GPIO assignment, gpio 0-3 are also customer-configurable led */ -#define BOARD_GPIO_PACTRL 0x200 /* bit 9 controls the PA on new 4306 boards */ -#define BOARD_GPIO_12 0x1000 /* gpio 12 */ -#define BOARD_GPIO_13 0x2000 /* gpio 13 */ +/* + * board specific GPIO assignment, gpio 0-3 are also customer-configurable + * led + */ + +/* bit 9 controls the PA on new 4306 boards */ +#define BOARD_GPIO_PACTRL 0x200 +#define BOARD_GPIO_12 0x1000 +#define BOARD_GPIO_13 0x2000 /* **** Core type/rev defaults **** */ #define D11CONF 0x0fffffb0 /* Supported D11 revs: 4, 5, 7-27 @@ -152,25 +172,53 @@ #define PHYCONF_HAS(val) CONF_HAS(PHYTYPE, val) #define PHYCONF_IS(val) CONF_IS(PHYTYPE, val) -#define NREV_IS(var, val) (NCONF_HAS(val) && (NCONF_IS(val) || ((var) == (val)))) -#define NREV_GE(var, val) (NCONF_GE(val) && (!NCONF_LT(val) || ((var) >= (val)))) -#define NREV_GT(var, val) (NCONF_GT(val) && (!NCONF_LE(val) || ((var) > (val)))) -#define NREV_LT(var, val) (NCONF_LT(val) && (!NCONF_GE(val) || ((var) < (val)))) -#define NREV_LE(var, val) (NCONF_LE(val) && (!NCONF_GT(val) || ((var) <= (val)))) +#define NREV_IS(var, val) \ + (NCONF_HAS(val) && (NCONF_IS(val) || ((var) == (val)))) + +#define NREV_GE(var, val) \ + (NCONF_GE(val) && (!NCONF_LT(val) || ((var) >= (val)))) + +#define NREV_GT(var, val) \ + (NCONF_GT(val) && (!NCONF_LE(val) || ((var) > (val)))) + +#define NREV_LT(var, val) \ + (NCONF_LT(val) && (!NCONF_GE(val) || ((var) < (val)))) + +#define NREV_LE(var, val) \ + (NCONF_LE(val) && (!NCONF_GT(val) || ((var) <= (val)))) + +#define LCNREV_IS(var, val) \ + (LCNCONF_HAS(val) && (LCNCONF_IS(val) || ((var) == (val)))) + +#define LCNREV_GE(var, val) \ + (LCNCONF_GE(val) && (!LCNCONF_LT(val) || ((var) >= (val)))) + +#define LCNREV_GT(var, val) \ + (LCNCONF_GT(val) && (!LCNCONF_LE(val) || ((var) > (val)))) -#define LCNREV_IS(var, val) (LCNCONF_HAS(val) && (LCNCONF_IS(val) || ((var) == (val)))) -#define LCNREV_GE(var, val) (LCNCONF_GE(val) && (!LCNCONF_LT(val) || ((var) >= (val)))) -#define LCNREV_GT(var, val) (LCNCONF_GT(val) && (!LCNCONF_LE(val) || ((var) > (val)))) -#define LCNREV_LT(var, val) (LCNCONF_LT(val) && (!LCNCONF_GE(val) || ((var) < (val)))) -#define LCNREV_LE(var, val) (LCNCONF_LE(val) && (!LCNCONF_GT(val) || ((var) <= (val)))) +#define LCNREV_LT(var, val) \ + (LCNCONF_LT(val) && (!LCNCONF_GE(val) || ((var) < (val)))) -#define D11REV_IS(var, val) (D11CONF_HAS(val) && (D11CONF_IS(val) || ((var) == (val)))) -#define D11REV_GE(var, val) (D11CONF_GE(val) && (!D11CONF_LT(val) || ((var) >= (val)))) -#define D11REV_GT(var, val) (D11CONF_GT(val) && (!D11CONF_LE(val) || ((var) > (val)))) -#define D11REV_LT(var, val) (D11CONF_LT(val) && (!D11CONF_GE(val) || ((var) < (val)))) -#define D11REV_LE(var, val) (D11CONF_LE(val) && (!D11CONF_GT(val) || ((var) <= (val)))) +#define LCNREV_LE(var, val) \ + (LCNCONF_LE(val) && (!LCNCONF_GT(val) || ((var) <= (val)))) -#define PHYTYPE_IS(var, val) (PHYCONF_HAS(val) && (PHYCONF_IS(val) || ((var) == (val)))) +#define D11REV_IS(var, val) \ + (D11CONF_HAS(val) && (D11CONF_IS(val) || ((var) == (val)))) + +#define D11REV_GE(var, val) \ + (D11CONF_GE(val) && (!D11CONF_LT(val) || ((var) >= (val)))) + +#define D11REV_GT(var, val) \ + (D11CONF_GT(val) && (!D11CONF_LE(val) || ((var) > (val)))) + +#define D11REV_LT(var, val) \ + (D11CONF_LT(val) && (!D11CONF_GE(val) || ((var) < (val)))) + +#define D11REV_LE(var, val) \ + (D11CONF_LE(val) && (!D11CONF_GT(val) || ((var) <= (val)))) + +#define PHYTYPE_IS(var, val)\ + (PHYCONF_HAS(val) && (PHYCONF_IS(val) || ((var) == (val)))) /* Finally, early-exit from switch case if anyone wants it... */ @@ -213,11 +261,18 @@ * * *********************************************** */ -#define NTXD 256 /* Max # of entries in Tx FIFO based on 4kb page size */ -#define NRXD 256 /* Max # of entries in Rx FIFO based on 4kb page size */ -#define NRXBUFPOST 32 /* try to keep this # rbufs posted to the chip */ -#define MAXSCB 32 /* Maximum SCBs in cache for STA */ -#define AMPDU_NUM_MPDU 16 /* max allowed number of mpdus in an ampdu (2 streams) */ + +/* Max # of entries in Tx FIFO based on 4kb page size */ +#define NTXD 256 +/* Max # of entries in Rx FIFO based on 4kb page size */ +#define NRXD 256 +/* try to keep this # rbufs posted to the chip */ +#define NRXBUFPOST 32 +/* Maximum SCBs in cache for STA */ +#define MAXSCB 32 + +/* max allowed number of mpdus in an ampdu (2 streams) */ +#define AMPDU_NUM_MPDU 16 /* Count of packet callback structures. either of following * 1. Set to the number of SCBs since a STA @@ -242,8 +297,8 @@ #define BRCMS_AMPDUDATAHIWAT 255 /* bounded rx loops */ -#define RXBND 8 /* max # frames to process in brcms_c_recv() */ -#define TXSBND 8 /* max # tx status to process in wlc_txstatus() */ +#define RXBND 8 /* max # frames to process in brcms_c_recv() */ +#define TXSBND 8 /* max # tx status to process in wlc_txstatus() */ #define BAND_5G(bt) ((bt) == BRCM_BAND_5G) #define BAND_2G(bt) ((bt) == BRCM_BAND_2G) @@ -256,21 +311,21 @@ do { \ #define WL_ERROR_ON() (brcm_msg_level & LOG_ERROR_VAL) -/* register access macros */ -#ifndef __BIG_ENDIAN -#ifndef __mips__ -#define R_REG(r) \ - ({\ - sizeof(*(r)) == sizeof(u8) ? \ - readb((u8 *)(r)) : \ - sizeof(*(r)) == sizeof(u16) ? readw((u16 *)(r)) : \ - readl((u32 *)(r)); \ - }) -#else /* __mips__ */ +/* + * Register access macros. + * + * These macro's take a pointer to the address to read as one of their + * arguments. The macro itself deduces the size of the IO transaction (u8, u16 + * or u32). Advantage of this approach in combination with using a struct to + * define the registers in a register block, is that access size and access + * location are defined in only one spot. This reduces the risk of the + * programmer trying to use an unsupported transaction size on a register. + * + */ + #define R_REG(r) \ ({ \ __typeof(*(r)) __osl_v; \ - __asm__ __volatile__("sync"); \ switch (sizeof(*(r))) { \ case sizeof(u8): \ __osl_v = readb((u8 *)(r)); \ @@ -279,39 +334,6 @@ do { \ __osl_v = readw((u16 *)(r)); \ break; \ case sizeof(u32): \ - __osl_v = \ - readl((u32 *)(r)); \ - break; \ - } \ - __asm__ __volatile__("sync"); \ - __osl_v; \ - }) -#endif /* __mips__ */ - -#define W_REG(r, v) do { \ - switch (sizeof(*(r))) { \ - case sizeof(u8): \ - writeb((u8)(v), (u8 *)(r)); break; \ - case sizeof(u16): \ - writew((u16)(v), (u16 *)(r)); break; \ - case sizeof(u32): \ - writel((u32)(v), (u32 *)(r)); break; \ - }; \ - } while (0) -#else /* __BIG_ENDIAN */ -#define R_REG(r) \ - ({ \ - __typeof(*(r)) __osl_v; \ - switch (sizeof(*(r))) { \ - case sizeof(u8): \ - __osl_v = \ - readb((u8 *)((r)^3)); \ - break; \ - case sizeof(u16): \ - __osl_v = \ - readw((u16 *)((r)^2)); \ - break; \ - case sizeof(u32): \ __osl_v = readl((u32 *)(r)); \ break; \ } \ @@ -321,19 +343,18 @@ do { \ #define W_REG(r, v) do { \ switch (sizeof(*(r))) { \ case sizeof(u8): \ - writeb((u8)(v), \ - (u8 *)((r)^3)); break; \ + writeb((u8)(v), (u8 *)(r)); \ + break; \ case sizeof(u16): \ - writew((u16)(v), \ - (u16 *)((r)^2)); break; \ + writew((u16)(v), (u16 *)(r)); \ + break; \ case sizeof(u32): \ - writel((u32)(v), \ - (u32 *)(r)); break; \ + writel((u32)(v), (u32 *)(r)); \ + break; \ } \ } while (0) -#endif /* __BIG_ENDIAN */ -#ifdef __mips__ +#ifdef CONFIG_BCM47XX /* * bcm4716 (which includes 4717 & 4718), plus 4706 on PCIe can reorder * transactions. As a fix, a read after write is performed on certain places @@ -342,7 +363,7 @@ do { \ #define W_REG_FLUSH(r, v) ({ W_REG((r), (v)); (void)R_REG(r); }) #else #define W_REG_FLUSH(r, v) W_REG((r), (v)) -#endif /* __mips__ */ +#endif /* CONFIG_BCM47XX */ #define AND_REG(r, v) W_REG((r), R_REG(r) & (v)) #define OR_REG(r, v) W_REG((r), R_REG(r) | (v)) @@ -351,10 +372,13 @@ do { \ W_REG((r), ((R_REG(r) & ~(mask)) | (val))) /* multi-bool data type: set of bools, mbool is true if any is set */ -typedef u32 mbool; -#define mboolset(mb, bit) ((mb) |= (bit)) /* set one bool */ -#define mboolclr(mb, bit) ((mb) &= ~(bit)) /* clear one bool */ -#define mboolisset(mb, bit) (((mb) & (bit)) != 0) /* true if one bool is set */ + +/* set one bool */ +#define mboolset(mb, bit) ((mb) |= (bit)) +/* clear one bool */ +#define mboolclr(mb, bit) ((mb) &= ~(bit)) +/* true if one bool is set */ +#define mboolisset(mb, bit) (((mb) & (bit)) != 0) #define mboolmaskset(mb, mask, val) ((mb) = (((mb) & ~(mask)) | (val))) /* forward declarations */ @@ -375,23 +399,6 @@ struct tx_status; struct d11rxhdr; struct brcms_d11rxhdr; struct txpwr_limits; -struct brcms_phy; - -typedef volatile struct intctrlregs intctrlregs_t; -typedef volatile struct pio2regs pio2regs_t; -typedef volatile struct pio2regp pio2regp_t; -typedef volatile struct pio4regs pio4regs_t; -typedef volatile struct pio4regp pio4regp_t; -typedef volatile struct fifo64 fifo64_t; -typedef volatile struct d11regs d11regs_t; -typedef volatile struct dma32diag dma32diag_t; -typedef volatile struct dma64regs dma64regs_t; -typedef struct brcms_rateset wlc_rateset_t; -typedef u32 ratespec_t; -typedef struct chanvec chanvec_t; -typedef s32 fixed; -typedef struct _cs32 cs32; -typedef volatile union pmqreg pmqreg_t; /* brcm_msg_level is a bit vector with defs in defs.h */ extern u32 brcm_msg_level; diff --git a/drivers/staging/brcm80211/brcmutil/utils.c b/drivers/staging/brcm80211/brcmutil/utils.c index 37b6b77..6280ec1 100644 --- a/drivers/staging/brcm80211/brcmutil/utils.c +++ b/drivers/staging/brcm80211/brcmutil/utils.c @@ -219,7 +219,7 @@ EXPORT_SYMBOL(brcmu_pktq_pdeq_tail); void brcmu_pktq_pflush(struct pktq *pq, int prec, bool dir, - ifpkt_cb_t fn, void *arg) + bool (*fn)(struct sk_buff *, void *), void *arg) { struct pktq_prec *q; struct sk_buff *p, *prev = NULL; @@ -244,14 +244,13 @@ brcmu_pktq_pflush(struct pktq *pq, int prec, bool dir, } } - if (q->head == NULL) { + if (q->head == NULL) q->tail = NULL; - } } EXPORT_SYMBOL(brcmu_pktq_pflush); void brcmu_pktq_flush(struct pktq *pq, bool dir, - ifpkt_cb_t fn, void *arg) + bool (*fn)(struct sk_buff *, void *), void *arg) { int prec; for (prec = 0; prec < pq->num_prec; prec++) @@ -350,21 +349,6 @@ struct sk_buff *brcmu_pktq_mdeq(struct pktq *pq, uint prec_bmp, } EXPORT_SYMBOL(brcmu_pktq_mdeq); -/* parse a xx:xx:xx:xx:xx:xx format ethernet address */ -int brcmu_ether_atoe(char *p, u8 *ea) -{ - int i = 0; - - for (;;) { - ea[i++] = (char)simple_strtoul(p, &p, 16); - if (!*p++ || i == 6) - break; - } - - return i == 6; -} -EXPORT_SYMBOL(brcmu_ether_atoe); - #if defined(BCMDBG) /* pretty hex print a pkt buffer chain */ void brcmu_prpkt(const char *msg, struct sk_buff *p0) @@ -419,26 +403,23 @@ int brcmu_iovar_lencheck(const struct brcmu_iovar *vi, void *arg, int len, case IOVT_UINT16: case IOVT_UINT32: /* all integers are s32 sized args at the ioctl interface */ - if (len < (int)sizeof(int)) { + if (len < (int)sizeof(int)) bcmerror = -EOVERFLOW; - } break; case IOVT_BUFFER: /* buffer must meet minimum length requirement */ - if (len < vi->minlen) { + if (len < vi->minlen) bcmerror = -EOVERFLOW; - } break; case IOVT_VOID: - if (!set) { + if (!set) /* Cannot return nil... */ bcmerror = -ENOTSUPP; - } else if (len) { + else if (len) /* Set is an action w/o parameters */ bcmerror = -ENOBUFS; - } break; default: @@ -450,75 +431,6 @@ int brcmu_iovar_lencheck(const struct brcmu_iovar *vi, void *arg, int len, } EXPORT_SYMBOL(brcmu_iovar_lencheck); -/******************************************************************************* - * crc8 - * - * Computes a crc8 over the input data using the polynomial: - * - * x^8 + x^7 +x^6 + x^4 + x^2 + 1 - * - * The caller provides the initial value (either CRC8_INIT_VALUE - * or the previous returned value) to allow for processing of - * discontiguous blocks of data. When generating the CRC the - * caller is responsible for complementing the final return value - * and inserting it into the byte stream. When checking, a final - * return value of CRC8_GOOD_VALUE indicates a valid CRC. - * - * Reference: Dallas Semiconductor Application Note 27 - * Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms", - * ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd., - * ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt - * - * **************************************************************************** - */ - -static const u8 crc8_table[256] = { - 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B, - 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21, - 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF, - 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5, - 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14, - 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E, - 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80, - 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA, - 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95, - 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF, - 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01, - 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B, - 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA, - 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0, - 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E, - 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34, - 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0, - 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A, - 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54, - 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E, - 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF, - 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5, - 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B, - 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61, - 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E, - 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74, - 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA, - 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0, - 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41, - 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B, - 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5, - 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F -}; - -u8 brcmu_crc8(u8 *pdata, /* pointer to array of data to process */ - uint nbytes, /* number of input data bytes to process */ - u8 crc /* either CRC8_INIT_VALUE or previous return value */ - ) { - /* loop over the buffer data */ - while (nbytes-- > 0) - crc = crc8_table[(crc ^ *pdata++) & 0xff]; - - return crc; -} -EXPORT_SYMBOL(brcmu_crc8); - /* * Traverse a string of 1-byte tag/1-byte length/variable-length value * triples, returning a pointer to the substring whose first element @@ -605,7 +517,10 @@ brcmu_format_flags(const struct brcmu_bit_desc *bd, u32 flags, char *buf, } EXPORT_SYMBOL(brcmu_format_flags); -/* print bytes formatted as hex to a string. return the resulting string length */ +/* + * print bytes formatted as hex to a string. return the resulting + * string length + */ int brcmu_format_hex(char *str, const void *bytes, int len) { int i; @@ -685,10 +600,9 @@ u16 brcmu_qdbm_to_mw(u8 qdbm) uint factor = 1; int idx = qdbm - QDBM_OFFSET; - if (idx >= QDBM_TABLE_LEN) { + if (idx >= QDBM_TABLE_LEN) /* clamp to max u16 mW value */ return 0xFFFF; - } /* scale the qdBm index up to the range of the table 0-40 * where an offset of 40 qdBm equals a factor of 10 mW. diff --git a/drivers/staging/brcm80211/brcmutil/wifi.c b/drivers/staging/brcm80211/brcmutil/wifi.c index b9ffe86..636515c 100644 --- a/drivers/staging/brcm80211/brcmutil/wifi.c +++ b/drivers/staging/brcm80211/brcmutil/wifi.c @@ -21,7 +21,7 @@ * combination could be legal given any set of circumstances. * RETURNS: true is the chanspec is malformed, false if it looks good. */ -bool brcmu_chspec_malformed(chanspec_t chanspec) +bool brcmu_chspec_malformed(u16 chanspec) { /* must be 2G or 5G band */ if (!CHSPEC_IS5G(chanspec) && !CHSPEC_IS2G(chanspec)) @@ -34,9 +34,8 @@ bool brcmu_chspec_malformed(chanspec_t chanspec) if (CHSPEC_IS20(chanspec)) { if (!CHSPEC_SB_NONE(chanspec)) return true; - } else { - if (!CHSPEC_SB_UPPER(chanspec) && !CHSPEC_SB_LOWER(chanspec)) - return true; + } else if (!CHSPEC_SB_UPPER(chanspec) && !CHSPEC_SB_LOWER(chanspec)) { + return true; } return false; @@ -44,11 +43,11 @@ bool brcmu_chspec_malformed(chanspec_t chanspec) EXPORT_SYMBOL(brcmu_chspec_malformed); /* - * This function returns the channel number that control traffic is being sent on, for legacy - * channels this is just the channel number, for 40MHZ channels it is the upper or lowre 20MHZ - * sideband depending on the chanspec selected + * This function returns the channel number that control traffic is being sent + * on, for legacy channels this is just the channel number, for 40MHZ channels + * it is the upper or lower 20MHZ sideband depending on the chanspec selected. */ -u8 brcmu_chspec_ctlchan(chanspec_t chspec) +u8 brcmu_chspec_ctlchan(u16 chspec) { u8 ctl_chan; @@ -56,17 +55,23 @@ u8 brcmu_chspec_ctlchan(chanspec_t chspec) if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_NONE) { return CHSPEC_CHANNEL(chspec); } else { - /* we only support 40MHZ with sidebands */ - /* chanspec channel holds the centre frequency, use that and the - * side band information to reconstruct the control channel number + /* + * we only support 40MHZ with sidebands. chanspec channel holds + * the centre frequency, use that and the side band information + * to reconstruct the control channel number */ - if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_UPPER) { - /* control chan is the upper 20 MHZ SB of the 40MHZ channel */ + if (CHSPEC_CTL_SB(chspec) == WL_CHANSPEC_CTL_SB_UPPER) + /* + * control chan is the upper 20 MHZ SB of the + * 40MHZ channel + */ ctl_chan = UPPER_20_SB(CHSPEC_CHANNEL(chspec)); - } else { - /* control chan is the lower 20 MHZ SB of the 40MHZ channel */ + else + /* + * control chan is the lower 20 MHZ SB of the + * 40MHZ channel + */ ctl_chan = LOWER_20_SB(CHSPEC_CHANNEL(chspec)); - } } return ctl_chan; diff --git a/drivers/staging/brcm80211/include/brcmu_utils.h b/drivers/staging/brcm80211/include/brcmu_utils.h index 2d54cc5..de627c2 100644 --- a/drivers/staging/brcm80211/include/brcmu_utils.h +++ b/drivers/staging/brcm80211/include/brcmu_utils.h @@ -45,12 +45,8 @@ struct brcmu_strbuf { } /* osl multi-precedence packet queue */ -#ifndef PKTQ_LEN_DEFAULT #define PKTQ_LEN_DEFAULT 128 /* Max 128 packets */ -#endif -#ifndef PKTQ_MAX_PREC #define PKTQ_MAX_PREC 16 /* Maximum precedence levels */ -#endif struct pktq_prec { struct sk_buff *head; /* first packet to dequeue */ @@ -72,9 +68,6 @@ struct pktq { struct pktq_prec q[PKTQ_MAX_PREC]; }; -/* fn(pkt, arg). return true if pkt belongs to if */ -typedef bool(*ifpkt_cb_t) (struct sk_buff *, void *); - /* operations on a specific precedence in packet queue */ #define pktq_psetmax(pq, prec, _max) ((pq)->q[prec].max = (_max)) @@ -98,8 +91,9 @@ extern struct sk_buff *brcmu_pkt_buf_get_skb(uint len); extern void brcmu_pkt_buf_free_skb(struct sk_buff *skb); /* Empty the queue at particular precedence level */ +/* callback function fn(pkt, arg) returns true if pkt belongs to if */ extern void brcmu_pktq_pflush(struct pktq *pq, int prec, - bool dir, ifpkt_cb_t fn, void *arg); + bool dir, bool (*fn)(struct sk_buff *, void *), void *arg); /* operations on a set of precedences in packet queue */ @@ -127,7 +121,7 @@ extern void brcmu_pktq_init(struct pktq *pq, int num_prec, int max_len); /* prec_out may be NULL if caller is not interested in return value */ extern struct sk_buff *brcmu_pktq_peek_tail(struct pktq *pq, int *prec_out); extern void brcmu_pktq_flush(struct pktq *pq, bool dir, - ifpkt_cb_t fn, void *arg); + bool (*fn)(struct sk_buff *, void *), void *arg); /* externs */ /* packet */ @@ -135,9 +129,6 @@ extern uint brcmu_pktfrombuf(struct sk_buff *p, uint offset, int len, unsigned char *buf); extern uint brcmu_pkttotlen(struct sk_buff *p); -/* ethernet address */ -extern int brcmu_ether_atoe(char *p, u8 *ea); - /* ip address */ struct ipv4_addr; @@ -197,9 +188,7 @@ extern int brcmu_iovar_lencheck(const struct brcmu_iovar *table, void *arg, #define BCME_STRLEN 64 /* Max string length for BCM errors */ -#ifndef ABS #define ABS(a) (((a) < 0) ? -(a) : (a)) -#endif /* ABS */ #define CEIL(x, y) (((x) + ((y)-1)) / (y)) #define ISPOWEROF2(x) ((((x)-1)&(x)) == 0) @@ -251,8 +240,6 @@ extern int brcmu_iovar_lencheck(const struct brcmu_iovar *table, void *arg, #define MODSUB_POW2(x, y, bound) (((x) - (y)) & ((bound) - 1)) /* crc defines */ -#define CRC8_INIT_VALUE 0xff /* Initial CRC8 checksum value */ -#define CRC8_GOOD_VALUE 0x9f /* Good final CRC8 checksum value */ #define CRC16_INIT_VALUE 0xffff /* Initial CRC16 checksum value */ #define CRC16_GOOD_VALUE 0xf0b8 /* Good final CRC16 checksum value */ @@ -269,12 +256,10 @@ struct brcmu_tlv { u8 data[1]; }; -#define ETHER_ADDR_STR_LEN 18 /* 18-bytes of Ethernet address buffer length */ +/* 18-bytes of Ethernet address buffer length */ +#define ETHER_ADDR_STR_LEN 18 /* externs */ -/* crc */ -extern u8 brcmu_crc8(u8 *p, uint nbytes, u8 crc); - /* format/print */ #if defined(BCMDBG) extern int brcmu_format_flags(const struct brcmu_bit_desc *bd, u32 flags, diff --git a/drivers/staging/brcm80211/include/brcmu_wifi.h b/drivers/staging/brcm80211/include/brcmu_wifi.h index fde592b..0ab432d 100644 --- a/drivers/staging/brcm80211/include/brcmu_wifi.h +++ b/drivers/staging/brcm80211/include/brcmu_wifi.h @@ -20,8 +20,10 @@ #include <linux/if_ether.h> /* for ETH_ALEN */ #include <linux/ieee80211.h> /* for WLAN_PMKID_LEN */ -/* A chanspec holds the channel number, band, bandwidth and control sideband */ -typedef u16 chanspec_t; +/* + * A chanspec (u16) holds the channel number, band, bandwidth and control + * sideband + */ /* channel defines */ #define CH_UPPER_SB 0x01 @@ -29,13 +31,16 @@ typedef u16 chanspec_t; #define CH_EWA_VALID 0x04 #define CH_20MHZ_APART 4 #define CH_10MHZ_APART 2 -#define CH_5MHZ_APART 1 /* 2G band channels are 5 Mhz apart */ +#define CH_5MHZ_APART 1 /* 2G band channels are 5 Mhz apart */ #define CH_MAX_2G_CHANNEL 14 /* Max channel in 2G band */ #define BRCM_MAX_2G_CHANNEL CH_MAX_2G_CHANNEL /* legacy define */ -#define MAXCHANNEL 224 /* max # supported channels. The max channel no is 216, - * this is that + 1 rounded up to a multiple of NBBY (8). - * DO NOT MAKE it > 255: channels are u8's all over - */ + +/* + * max # supported channels. The max channel no is 216, this is that + 1 + * rounded up to a multiple of NBBY (8). DO NOT MAKE it > 255: channels are + * u8's all over +*/ +#define MAXCHANNEL 224 #define WL_CHANSPEC_CHAN_MASK 0x00ff #define WL_CHANSPEC_CHAN_SHIFT 0 @@ -64,53 +69,67 @@ typedef u16 chanspec_t; #define WF_CHAN_FACTOR_4_G 8000 /* 4.9 GHz band for Japan */ /* channel defines */ -#define LOWER_20_SB(channel) (((channel) > CH_10MHZ_APART) ? ((channel) - CH_10MHZ_APART) : 0) -#define UPPER_20_SB(channel) (((channel) < (MAXCHANNEL - CH_10MHZ_APART)) ? \ - ((channel) + CH_10MHZ_APART) : 0) -#define CHSPEC_BANDUNIT(chspec) (CHSPEC_IS5G(chspec) ? BAND_5G_INDEX : \ - BAND_2G_INDEX) -#define CH20MHZ_CHSPEC(channel) (chanspec_t)((chanspec_t)(channel) | WL_CHANSPEC_BW_20 | \ - WL_CHANSPEC_CTL_SB_NONE | (((channel) <= CH_MAX_2G_CHANNEL) ? \ - WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G)) -#define NEXT_20MHZ_CHAN(channel) (((channel) < (MAXCHANNEL - CH_20MHZ_APART)) ? \ - ((channel) + CH_20MHZ_APART) : 0) -#define CH40MHZ_CHSPEC(channel, ctlsb) (chanspec_t) \ - ((channel) | (ctlsb) | WL_CHANSPEC_BW_40 | \ - ((channel) <= CH_MAX_2G_CHANNEL ? WL_CHANSPEC_BAND_2G : \ - WL_CHANSPEC_BAND_5G)) -#define CHSPEC_CHANNEL(chspec) ((u8)((chspec) & WL_CHANSPEC_CHAN_MASK)) -#define CHSPEC_BAND(chspec) ((chspec) & WL_CHANSPEC_BAND_MASK) +#define LOWER_20_SB(channel) \ + (((channel) > CH_10MHZ_APART) ? ((channel) - CH_10MHZ_APART) : 0) -#ifdef WL11N_20MHZONLY +#define UPPER_20_SB(channel) \ + (((channel) < (MAXCHANNEL - CH_10MHZ_APART)) ? \ + ((channel) + CH_10MHZ_APART) : 0) -#define CHSPEC_CTL_SB(chspec) WL_CHANSPEC_CTL_SB_NONE -#define CHSPEC_BW(chspec) WL_CHANSPEC_BW_20 -#define CHSPEC_IS10(chspec) 0 -#define CHSPEC_IS20(chspec) 1 -#ifndef CHSPEC_IS40 -#define CHSPEC_IS40(chspec) 0 -#endif +#define CHSPEC_BANDUNIT(chspec) \ + (CHSPEC_IS5G(chspec) ? BAND_5G_INDEX : BAND_2G_INDEX) + +#define CH20MHZ_CHSPEC(channel) \ + (u16)((u16)(channel) | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE | \ + (((channel) <= CH_MAX_2G_CHANNEL) ? \ + WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G)) -#else /* !WL11N_20MHZONLY */ +#define NEXT_20MHZ_CHAN(channel) \ + (((channel) < (MAXCHANNEL - CH_20MHZ_APART)) ? \ + ((channel) + CH_20MHZ_APART) : 0) + +#define CH40MHZ_CHSPEC(channel, ctlsb) \ + (u16)((channel) | (ctlsb) | WL_CHANSPEC_BW_40 | \ + ((channel) <= CH_MAX_2G_CHANNEL ? \ + WL_CHANSPEC_BAND_2G : WL_CHANSPEC_BAND_5G)) + +#define CHSPEC_CHANNEL(chspec) ((u8)((chspec) & WL_CHANSPEC_CHAN_MASK)) +#define CHSPEC_BAND(chspec) ((chspec) & WL_CHANSPEC_BAND_MASK) #define CHSPEC_CTL_SB(chspec) ((chspec) & WL_CHANSPEC_CTL_SB_MASK) #define CHSPEC_BW(chspec) ((chspec) & WL_CHANSPEC_BW_MASK) -#define CHSPEC_IS10(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_10) -#define CHSPEC_IS20(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20) + +#define CHSPEC_IS10(chspec) \ + (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_10) + +#define CHSPEC_IS20(chspec) \ + (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_20) + #ifndef CHSPEC_IS40 -#define CHSPEC_IS40(chspec) (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40) +#define CHSPEC_IS40(chspec) \ + (((chspec) & WL_CHANSPEC_BW_MASK) == WL_CHANSPEC_BW_40) #endif -#endif /* !WL11N_20MHZONLY */ +#define CHSPEC_IS5G(chspec) \ + (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_5G) + +#define CHSPEC_IS2G(chspec) \ + (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_2G) + +#define CHSPEC_SB_NONE(chspec) \ + (((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_NONE) + +#define CHSPEC_SB_UPPER(chspec) \ + (((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_UPPER) + +#define CHSPEC_SB_LOWER(chspec) \ + (((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_LOWER) + +#define CHSPEC_CTL_CHAN(chspec) \ + ((CHSPEC_SB_LOWER(chspec)) ? \ + (LOWER_20_SB(((chspec) & WL_CHANSPEC_CHAN_MASK))) : \ + (UPPER_20_SB(((chspec) & WL_CHANSPEC_CHAN_MASK)))) -#define CHSPEC_IS5G(chspec) (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_5G) -#define CHSPEC_IS2G(chspec) (((chspec) & WL_CHANSPEC_BAND_MASK) == WL_CHANSPEC_BAND_2G) -#define CHSPEC_SB_NONE(chspec) (((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_NONE) -#define CHSPEC_SB_UPPER(chspec) (((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_UPPER) -#define CHSPEC_SB_LOWER(chspec) (((chspec) & WL_CHANSPEC_CTL_SB_MASK) == WL_CHANSPEC_CTL_SB_LOWER) -#define CHSPEC_CTL_CHAN(chspec) ((CHSPEC_SB_LOWER(chspec)) ? \ - (LOWER_20_SB(((chspec) & WL_CHANSPEC_CHAN_MASK))) : \ - (UPPER_20_SB(((chspec) & WL_CHANSPEC_CHAN_MASK)))) #define CHSPEC2BAND(chspec) (CHSPEC_IS5G(chspec) ? BRCM_BAND_5G : BRCM_BAND_2G) #define CHANSPEC_STR_LEN 8 @@ -142,14 +161,14 @@ typedef u16 chanspec_t; * combination could be legal given any set of circumstances. * RETURNS: true is the chanspec is malformed, false if it looks good. */ -extern bool brcmu_chspec_malformed(chanspec_t chanspec); +extern bool brcmu_chspec_malformed(u16 chanspec); /* - * This function returns the channel number that control traffic is being sent on, for legacy - * channels this is just the channel number, for 40MHZ channels it is the upper or lowre 20MHZ - * sideband depending on the chanspec selected + * This function returns the channel number that control traffic is being sent + * on, for legacy channels this is just the channel number, for 40MHZ channels + * it is the upper or lower 20MHZ sideband depending on the chanspec selected. */ -extern u8 brcmu_chspec_ctlchan(chanspec_t chspec); +extern u8 brcmu_chspec_ctlchan(u16 chspec); /* * Return the channel number for a given frequency and base frequency. @@ -183,11 +202,13 @@ extern int brcmu_mhz2channel(uint freq, uint start_factor); #define CRYPTO_ALGO_NALG 7 /* wireless security bitvec */ + #define WEP_ENABLED 0x0001 #define TKIP_ENABLED 0x0002 #define AES_ENABLED 0x0004 #define WSEC_SWFLAG 0x0008 -#define SES_OW_ENABLED 0x0040 /* to go into transition mode without setting wep */ +/* to go into transition mode without setting wep */ +#define SES_OW_ENABLED 0x0040 /* WPA authentication mode bitvec */ #define WPA_AUTH_DISABLED 0x0000 /* Legacy (i.e., non-WPA) */ @@ -196,7 +217,7 @@ extern int brcmu_mhz2channel(uint freq, uint start_factor); #define WPA_AUTH_PSK 0x0004 /* Pre-shared key */ #define WPA_AUTH_RESERVED1 0x0008 #define WPA_AUTH_RESERVED2 0x0010 - /* #define WPA_AUTH_8021X 0x0020 *//* 802.1x, reserved */ + #define WPA2_AUTH_RESERVED1 0x0020 #define WPA2_AUTH_UNSPECIFIED 0x0040 /* over 802.1x */ #define WPA2_AUTH_PSK 0x0080 /* Pre-shared key */ @@ -218,26 +239,24 @@ extern int brcmu_mhz2channel(uint freq, uint start_factor); #define HT_CAP_RX_STBC_NO 0x0 #define HT_CAP_RX_STBC_ONE_STREAM 0x1 -typedef struct _pmkid { +struct pmkid { u8 BSSID[ETH_ALEN]; u8 PMKID[WLAN_PMKID_LEN]; -} pmkid_t; +}; -typedef struct _pmkid_list { +struct pmkid_list { u32 npmkid; - pmkid_t pmkid[1]; -} pmkid_list_t; + struct pmkid pmkid[1]; +}; -typedef struct _pmkid_cand { +struct pmkid_cand { u8 BSSID[ETH_ALEN]; u8 preauth; -} pmkid_cand_t; +}; -typedef struct _pmkid_cand_list { +struct pmkid_cand_list { u32 npmkid_cand; - pmkid_cand_t pmkid_cand[1]; -} pmkid_cand_list_t; - -typedef u8 ac_bitmap_t; + struct pmkid_cand pmkid_cand[1]; +}; #endif /* _BRCMU_WIFI_H_ */ diff --git a/drivers/staging/brcm80211/include/chipcommon.h b/drivers/staging/brcm80211/include/chipcommon.h index 296582a..fefabc3 100644 --- a/drivers/staging/brcm80211/include/chipcommon.h +++ b/drivers/staging/brcm80211/include/chipcommon.h @@ -19,7 +19,7 @@ #include "defs.h" /* for PAD macro */ -typedef volatile struct { +struct chipcregs { u32 chipid; /* 0x0 */ u32 capabilities; u32 corecontrol; /* corerev >= 1 */ @@ -214,7 +214,7 @@ typedef volatile struct { u32 pmu_xtalfreq; /* 0x66C, pmurev >= 10 */ u32 PAD[100]; u16 sromotp[768]; -} chipcregs_t; +}; /* chipid */ #define CID_ID_MASK 0x0000ffff /* Chip Id mask */ @@ -231,7 +231,8 @@ typedef volatile struct { #define CC_CAP_UARTS_MASK 0x00000003 /* Number of UARTs */ #define CC_CAP_MIPSEB 0x00000004 /* MIPS is in big-endian mode */ #define CC_CAP_UCLKSEL 0x00000018 /* UARTs clock select */ -#define CC_CAP_UINTCLK 0x00000008 /* UARTs are driven by internal divided clock */ +/* UARTs are driven by internal divided clock */ +#define CC_CAP_UINTCLK 0x00000008 #define CC_CAP_UARTGPIO 0x00000020 /* UARTs own GPIOs 15:12 */ #define CC_CAP_EXTBUS_MASK 0x000000c0 /* External bus mask */ #define CC_CAP_EXTBUS_NONE 0x00000000 /* No ExtBus present */ @@ -248,10 +249,12 @@ typedef volatile struct { #define CC_CAP_BKPLN64 0x08000000 /* 64-bit backplane */ #define CC_CAP_PMU 0x10000000 /* PMU Present, rev >= 20 */ #define CC_CAP_SROM 0x40000000 /* Srom Present, rev >= 32 */ -#define CC_CAP_NFLASH 0x80000000 /* Nand flash present, rev >= 35 */ +/* Nand flash present, rev >= 35 */ +#define CC_CAP_NFLASH 0x80000000 #define CC_CAP2_SECI 0x00000001 /* SECI Present, rev >= 36 */ -#define CC_CAP2_GSIO 0x00000002 /* GSIO (spi/i2c) present, rev >= 37 */ +/* GSIO (spi/i2c) present, rev >= 37 */ +#define CC_CAP2_GSIO 0x00000002 /* pmucapabilities */ #define PCAP_REV_MASK 0x000000ff diff --git a/drivers/staging/brcm80211/include/defs.h b/drivers/staging/brcm80211/include/defs.h index 8b3e17d..c745b7e 100644 --- a/drivers/staging/brcm80211/include/defs.h +++ b/drivers/staging/brcm80211/include/defs.h @@ -27,14 +27,8 @@ #define USB_BUS 5 #define SPI_BUS 6 -#ifndef OFF #define OFF 0 -#endif - -#ifndef ON #define ON 1 /* ON = 1 */ -#endif - #define AUTO (-1) /* Auto = -1 */ /* @@ -54,10 +48,12 @@ #define WL_NUMRATES 16 /* max # of rates in a rateset */ -typedef struct wl_rateset { - u32 count; /* # rates in this set */ - u8 rates[WL_NUMRATES]; /* rates in 500kbps units w/hi bit set if basic */ -} wl_rateset_t; +struct brcm_rateset { + /* # rates in this set */ + u32 count; + /* rates in 500kbps units w/hi bit set if basic */ + u8 rates[WL_NUMRATES]; +}; #define BRCM_CNTRY_BUF_SZ 4 /* Country string is 3 bytes + NUL */ @@ -71,10 +67,12 @@ typedef struct wl_rateset { #define BRCM_GET_PHYLIST 180 /* Bit masks for radio disabled status - returned by WL_GET_RADIO */ + #define WL_RADIO_SW_DISABLE (1<<0) #define WL_RADIO_HW_DISABLE (1<<1) #define WL_RADIO_MPC_DISABLE (1<<2) -#define WL_RADIO_COUNTRY_DISABLE (1<<3) /* some countries don't support any channel */ +/* some countries don't support any channel */ +#define WL_RADIO_COUNTRY_DISABLE (1<<3) /* Override bit for SET_TXPWR. if set, ignore other level limits */ #define WL_TXPWR_OVERRIDE (1U<<31) @@ -100,7 +98,9 @@ typedef struct wl_rateset { /* * Sonics Configuration Space Registers. */ -#define SBCONFIGOFF 0xf00 /* core sbconfig regs are top 256bytes of regs */ + +/* core sbconfig regs are top 256bytes of regs */ +#define SBCONFIGOFF 0xf00 /* cpp contortions to concatenate w/arg prescan */ #ifndef PAD diff --git a/drivers/staging/brcm80211/include/soc.h b/drivers/staging/brcm80211/include/soc.h index 6e5a705..4fcb956 100644 --- a/drivers/staging/brcm80211/include/soc.h +++ b/drivers/staging/brcm80211/include/soc.h @@ -17,11 +17,7 @@ #ifndef _BRCM_SOC_H #define _BRCM_SOC_H -#ifdef SI_ENUM_BASE_VARIABLE -#define SI_ENUM_BASE (sii->pub.si_enum_base) -#else #define SI_ENUM_BASE 0x18000000 /* Enumeration space base */ -#endif /* SI_ENUM_BASE_VARIABLE */ /* core codes */ #define NODEV_CORE_ID 0x700 /* Invalid coreid */ @@ -81,9 +77,8 @@ #define DMEMS_CORE_ID 0x835 /* SDR/DDR1 memory controller core */ #define DEF_SHIM_COMP 0x837 /* SHIM component in ubus/6362 */ #define OOB_ROUTER_CORE_ID 0x367 /* OOB router core ID */ -#define DEF_AI_COMP 0xfff /* Default component, in ai chips it maps all - * unused address ranges - */ +/* Default component, in ai chips it maps all unused address ranges */ +#define DEF_AI_COMP 0xfff /* Common core control flags */ #define SICF_BIST_EN 0x8000 diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig index 5e65dde..4c77e50 100644 --- a/drivers/staging/comedi/Kconfig +++ b/drivers/staging/comedi/Kconfig @@ -1244,11 +1244,10 @@ config COMEDI_DT9812 called dt9812. config COMEDI_USBDUX - tristate "ITL USBDUX support" + tristate "ITL USB-DUX-D support" default N ---help--- - Enable support for the University of Stirling USB DAQ and INCITE - Technology Limited driver + Enable support for the Incite Technology Ltd USB-DUX-D Board To compile this driver as a module, choose M here: the module will be called usbdux. @@ -1258,12 +1257,21 @@ config COMEDI_USBDUXFAST select COMEDI_FC default N ---help--- - Enable support for the University of Stirling USB-DUXfast and INCITE - Technology Limited driver + Enable support for the Incite Technology Ltd USB-DUXfast Board To compile this driver as a module, choose M here: the module will be called usbduxfast. +config COMEDI_USBDUXSIGMA + tristate "ITL USB-DUXsigma support" + select COMEDI_FC + default N + ---help--- + Enable support for the Incite Technology Ltd USB-DUXsigma Board + + To compile this driver as a module, choose M here: the module will be + called usbduxsigma. + config COMEDI_VMK80XX tristate "Velleman VM110/VM140 USB Board support" default N diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index e90e3cc..21d8c1c 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c @@ -101,7 +101,7 @@ static int do_insn_ioctl(struct comedi_device *dev, static int do_poll_ioctl(struct comedi_device *dev, unsigned int subd, void *file); -extern void do_become_nonbusy(struct comedi_device *dev, +static void do_become_nonbusy(struct comedi_device *dev, struct comedi_subdevice *s); static int do_cancel(struct comedi_device *dev, struct comedi_subdevice *s); diff --git a/drivers/staging/comedi/drivers/Makefile b/drivers/staging/comedi/drivers/Makefile index 33bf1f5..170da60 100644 --- a/drivers/staging/comedi/drivers/Makefile +++ b/drivers/staging/comedi/drivers/Makefile @@ -126,6 +126,7 @@ obj-$(CONFIG_COMEDI_QUATECH_DAQP_CS) += quatech_daqp_cs.o obj-$(CONFIG_COMEDI_DT9812) += dt9812.o obj-$(CONFIG_COMEDI_USBDUX) += usbdux.o obj-$(CONFIG_COMEDI_USBDUXFAST) += usbduxfast.o +obj-$(CONFIG_COMEDI_USBDUXSIGMA) += usbduxsigma.o obj-$(CONFIG_COMEDI_VMK80XX) += vmk80xx.o # Comedi NI drivers diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index d23799b..69334f6 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c @@ -422,7 +422,7 @@ struct pci_dio_private { unsigned short IDIFiltrHigh[8]; /* IDI's filter value high signal */ }; -static struct pci_dio_private *pci_priv = NULL; /* list of allocated cards */ +static struct pci_dio_private *pci_priv; /* list of allocated cards */ #define devpriv ((struct pci_dio_private *)dev->private) #define this_board ((const struct dio_boardtype *)dev->board_ptr) diff --git a/drivers/staging/comedi/drivers/ni_labpc.c b/drivers/staging/comedi/drivers/ni_labpc.c index 6859af0..721b2be 100644 --- a/drivers/staging/comedi/drivers/ni_labpc.c +++ b/drivers/staging/comedi/drivers/ni_labpc.c @@ -241,8 +241,10 @@ static int labpc_eeprom_write_insn(struct comedi_device *dev, struct comedi_insn *insn, unsigned int *data); static void labpc_adc_timing(struct comedi_device *dev, struct comedi_cmd *cmd); -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_ISA_DMA_API static unsigned int labpc_suggest_transfer_size(struct comedi_cmd cmd); +#endif +#ifdef CONFIG_COMEDI_PCI_DRIVERS static int labpc_find_device(struct comedi_device *dev, int bus, int slot); #endif static int labpc_dio_mem_callback(int dir, int port, int data, @@ -459,7 +461,7 @@ static const struct labpc_board_struct labpc_boards[] = { .ai_scan_up = 0, .memory_mapped_io = 0, }, -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_PCI_DRIVERS { .name = "pci-1200", .device_id = 0x161, @@ -503,14 +505,14 @@ static struct comedi_driver driver_labpc = { .offset = sizeof(struct labpc_board_struct), }; -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_PCI_DRIVERS static DEFINE_PCI_DEVICE_TABLE(labpc_pci_table) = { {PCI_DEVICE(PCI_VENDOR_ID_NI, 0x161)}, {0} }; MODULE_DEVICE_TABLE(pci, labpc_pci_table); -#endif /* CONFIG_COMEDI_PCI */ +#endif /* CONFIG_COMEDI_PCI_DRIVERS */ static inline int labpc_counter_load(struct comedi_device *dev, unsigned long base_address, @@ -720,7 +722,7 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it) unsigned long iobase = 0; unsigned int irq = 0; unsigned int dma_chan = 0; -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_PCI_DRIVERS int retval; #endif @@ -742,7 +744,7 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it) #endif break; case pci_bustype: -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_PCI_DRIVERS retval = labpc_find_device(dev, it->options[0], it->options[1]); if (retval < 0) return retval; @@ -772,7 +774,7 @@ static int labpc_attach(struct comedi_device *dev, struct comedi_devconfig *it) } /* adapted from ni_pcimio for finding mite based boards (pc-1200) */ -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_PCI_DRIVERS static int labpc_find_device(struct comedi_device *dev, int bus, int slot) { struct mite_struct *mite; @@ -820,7 +822,7 @@ int labpc_common_detach(struct comedi_device *dev) free_irq(dev->irq, dev); if (thisboard->bustype == isa_bustype && dev->iobase) release_region(dev->iobase, LABPC_SIZE); -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_PCI_DRIVERS if (devpriv->mite) mite_unsetup(devpriv->mite); #endif @@ -2135,7 +2137,7 @@ static void write_caldac(struct comedi_device *dev, unsigned int channel, devpriv->write_byte(devpriv->command5_bits, dev->iobase + COMMAND5_REG); } -#ifdef CONFIG_COMEDI_PCI +#ifdef CONFIG_COMEDI_PCI_DRIVERS static int __devinit driver_labpc_pci_probe(struct pci_dev *dev, const struct pci_device_id *ent) { diff --git a/drivers/staging/comedi/drivers/ni_pcidio.c b/drivers/staging/comedi/drivers/ni_pcidio.c index 8dd3a01..045a4c0 100644 --- a/drivers/staging/comedi/drivers/ni_pcidio.c +++ b/drivers/staging/comedi/drivers/ni_pcidio.c @@ -688,7 +688,7 @@ static void ni_pcidio_print_status(unsigned int flags) static void debug_int(struct comedi_device *dev) { int a, b; - static int n_int = 0; + static int n_int; struct timeval tv; do_gettimeofday(&tv); diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c new file mode 100644 index 0000000..a8fea9a --- /dev/null +++ b/drivers/staging/comedi/drivers/usbduxsigma.c @@ -0,0 +1,2880 @@ +#define DRIVER_VERSION "v0.5" +#define DRIVER_AUTHOR "Bernd Porr, BerndPorr@f2s.com" +#define DRIVER_DESC "Stirling/ITL USB-DUX SIGMA -- Bernd.Porr@f2s.com" +/* + comedi/drivers/usbdux.c + Copyright (C) 2011 Bernd Porr, Bernd.Porr@f2s.com + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + */ +/* +Driver: usbduxsigma +Description: University of Stirling USB DAQ & INCITE Technology Limited +Devices: [ITL] USB-DUX (usbduxsigma.o) +Author: Bernd Porr <BerndPorr@f2s.com> +Updated: 21 Jul 2011 +Status: testing +*/ +/* + * I must give credit here to Chris Baugher who + * wrote the driver for AT-MIO-16d. I used some parts of this + * driver. I also must give credits to David Brownell + * who supported me with the USB development. + * + * Note: the raw data from the A/D converter is 24 bit big endian + * anything else is little endian to/from the dux board + * + * + * Revision history: + * 0.1: inital version + * 0.2: all basic functions implemented, digital I/O only for one port + * 0.3: proper vendor ID and driver name + * 0.4: fixed D/A voltage range + * 0.5: various bug fixes, health check at startup + */ + +/* generates loads of debug info */ +/* #define NOISY_DUX_DEBUGBUG */ + +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/slab.h> +#include <linux/input.h> +#include <linux/usb.h> +#include <linux/fcntl.h> +#include <linux/compiler.h> +#include <linux/firmware.h> +#include "comedi_fc.h" +#include "../comedidev.h" + +#define BOARDNAME "usbduxsigma" + +/* timeout for the USB-transfer in ms*/ +#define BULK_TIMEOUT 1000 + +/* constants for "firmware" upload and download */ +#define USBDUXSUB_FIRMWARE 0xA0 +#define VENDOR_DIR_IN 0xC0 +#define VENDOR_DIR_OUT 0x40 + +/* internal addresses of the 8051 processor */ +#define USBDUXSUB_CPUCS 0xE600 + +/* + * the minor device number, major is 180 only for debugging purposes and to + * upload special firmware (programming the eeprom etc) which is not + * compatible with the comedi framwork + */ +#define USBDUXSUB_MINOR 32 + +/* max lenghth of the transfer-buffer for software upload */ +#define TB_LEN 0x2000 + +/* Input endpoint number: ISO/IRQ */ +#define ISOINEP 6 + +/* Output endpoint number: ISO/IRQ */ +#define ISOOUTEP 2 + +/* This EP sends DUX commands to USBDUX */ +#define COMMAND_OUT_EP 1 + +/* This EP receives the DUX commands from USBDUX */ +#define COMMAND_IN_EP 8 + +/* Output endpoint for PWM */ +#define PWM_EP 4 + +/* 300Hz max frequ under PWM */ +#define MIN_PWM_PERIOD ((long)(1E9/300)) + +/* Default PWM frequency */ +#define PWM_DEFAULT_PERIOD ((long)(1E9/100)) + +/* Number of channels (16 AD and offset)*/ +#define NUMCHANNELS 16 + +/* Size of one A/D value */ +#define SIZEADIN ((sizeof(int32_t))) + +/* + * Size of the async input-buffer IN BYTES, the DIO state is transmitted + * as the first byte. + */ +#define SIZEINBUF (((NUMCHANNELS+1)*SIZEADIN)) + +/* 16 bytes. */ +#define SIZEINSNBUF 16 + +/* Number of DA channels */ +#define NUMOUTCHANNELS 8 + +/* size of one value for the D/A converter: channel and value */ +#define SIZEDAOUT ((sizeof(uint8_t)+sizeof(int16_t))) + +/* + * Size of the output-buffer in bytes + * Actually only the first 4 triplets are used but for the + * high speed mode we need to pad it to 8 (microframes). + */ +#define SIZEOUTBUF ((8*SIZEDAOUT)) + +/* + * Size of the buffer for the dux commands: just now max size is determined + * by the analogue out + command byte + panic bytes... + */ +#define SIZEOFDUXBUFFER ((8*SIZEDAOUT+2)) + +/* Number of in-URBs which receive the data: min=2 */ +#define NUMOFINBUFFERSFULL 5 + +/* Number of out-URBs which send the data: min=2 */ +#define NUMOFOUTBUFFERSFULL 5 + +/* Number of in-URBs which receive the data: min=5 */ +/* must have more buffers due to buggy USB ctr */ +#define NUMOFINBUFFERSHIGH 10 + +/* Number of out-URBs which send the data: min=5 */ +/* must have more buffers due to buggy USB ctr */ +#define NUMOFOUTBUFFERSHIGH 10 + +/* Total number of usbdux devices */ +#define NUMUSBDUX 16 + +/* Analogue in subdevice */ +#define SUBDEV_AD 0 + +/* Analogue out subdevice */ +#define SUBDEV_DA 1 + +/* Digital I/O */ +#define SUBDEV_DIO 2 + +/* timer aka pwm output */ +#define SUBDEV_PWM 3 + +/* number of retries to get the right dux command */ +#define RETRIES 10 + +/**************************************************/ +/* comedi constants */ +static const struct comedi_lrange range_usbdux_ai_range = { 1, { + BIP_RANGE + (2.65) + } +}; + +static const struct comedi_lrange range_usbdux_ao_range = { 1, { + UNI_RANGE + (2.5), + } +}; + +/* + * private structure of one subdevice + */ + +/* + * This is the structure which holds all the data of + * this driver one sub device just now: A/D + */ +struct usbduxsub { + /* attached? */ + int attached; + /* is it associated with a subdevice? */ + int probed; + /* pointer to the usb-device */ + struct usb_device *usbdev; + /* actual number of in-buffers */ + int numOfInBuffers; + /* actual number of out-buffers */ + int numOfOutBuffers; + /* ISO-transfer handling: buffers */ + struct urb **urbIn; + struct urb **urbOut; + /* pwm-transfer handling */ + struct urb *urbPwm; + /* PWM period */ + unsigned int pwmPeriod; + /* PWM internal delay for the GPIF in the FX2 */ + uint8_t pwmDelay; + /* size of the PWM buffer which holds the bit pattern */ + int sizePwmBuf; + /* input buffer for the ISO-transfer */ + int32_t *inBuffer; + /* input buffer for single insn */ + int8_t *insnBuffer; + /* output buffer for single DA outputs */ + int16_t *outBuffer; + /* interface number */ + int ifnum; + /* interface structure in 2.6 */ + struct usb_interface *interface; + /* comedi device for the interrupt context */ + struct comedi_device *comedidev; + /* is it USB_SPEED_HIGH or not? */ + short int high_speed; + /* asynchronous command is running */ + short int ai_cmd_running; + short int ao_cmd_running; + /* pwm is running */ + short int pwm_cmd_running; + /* continous aquisition */ + short int ai_continous; + short int ao_continous; + /* number of samples to acquire */ + int ai_sample_count; + int ao_sample_count; + /* time between samples in units of the timer */ + unsigned int ai_timer; + unsigned int ao_timer; + /* counter between aquisitions */ + unsigned int ai_counter; + unsigned int ao_counter; + /* interval in frames/uframes */ + unsigned int ai_interval; + /* D/A commands */ + uint8_t *dac_commands; + /* commands */ + uint8_t *dux_commands; + struct semaphore sem; +}; + +/* + * The pointer to the private usb-data of the driver is also the private data + * for the comedi-device. This has to be global as the usb subsystem needs + * global variables. The other reason is that this structure must be there + * _before_ any comedi command is issued. The usb subsystem must be initialised + * before comedi can access it. + */ +static struct usbduxsub usbduxsub[NUMUSBDUX]; + +static DEFINE_SEMAPHORE(start_stop_sem); + +/* + * Stops the data acquision + * It should be safe to call this function from any context + */ +static int usbduxsub_unlink_InURBs(struct usbduxsub *usbduxsub_tmp) +{ + int i = 0; + int err = 0; + + if (usbduxsub_tmp && usbduxsub_tmp->urbIn) { + for (i = 0; i < usbduxsub_tmp->numOfInBuffers; i++) { + if (usbduxsub_tmp->urbIn[i]) { + /* We wait here until all transfers have been + * cancelled. */ + usb_kill_urb(usbduxsub_tmp->urbIn[i]); + } + dev_dbg(&usbduxsub_tmp->interface->dev, + "comedi: usbdux: unlinked InURB %d, err=%d\n", + i, err); + } + } + return err; +} + +/* + * This will stop a running acquisition operation + * Is called from within this driver from both the + * interrupt context and from comedi + */ +static int usbdux_ai_stop(struct usbduxsub *this_usbduxsub, int do_unlink) +{ + int ret = 0; + + if (!this_usbduxsub) { + pr_err("comedi?: usbdux_ai_stop: this_usbduxsub=NULL!\n"); + return -EFAULT; + } + dev_dbg(&this_usbduxsub->interface->dev, "comedi: usbdux_ai_stop\n"); + + if (do_unlink) { + /* stop aquistion */ + ret = usbduxsub_unlink_InURBs(this_usbduxsub); + } + + this_usbduxsub->ai_cmd_running = 0; + + return ret; +} + +/* + * This will cancel a running acquisition operation. + * This is called by comedi but never from inside the driver. + */ +static int usbdux_ai_cancel(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + struct usbduxsub *this_usbduxsub; + int res = 0; + + /* force unlink of all urbs */ + this_usbduxsub = dev->private; + if (!this_usbduxsub) + return -EFAULT; + + dev_dbg(&this_usbduxsub->interface->dev, "comedi: usbdux_ai_cancel\n"); + + /* prevent other CPUs from submitting new commands just now */ + down(&this_usbduxsub->sem); + if (!(this_usbduxsub->probed)) { + up(&this_usbduxsub->sem); + return -ENODEV; + } + /* unlink only if the urb really has been submitted */ + res = usbdux_ai_stop(this_usbduxsub, this_usbduxsub->ai_cmd_running); + up(&this_usbduxsub->sem); + return res; +} + +/* analogue IN - interrupt service routine */ +static void usbduxsub_ai_IsocIrq(struct urb *urb) +{ + int i, err, n; + struct usbduxsub *this_usbduxsub; + struct comedi_device *this_comedidev; + struct comedi_subdevice *s; + int32_t v; + unsigned int dio_state; + + /* the context variable points to the comedi device */ + this_comedidev = urb->context; + /* the private structure of the subdevice is struct usbduxsub */ + this_usbduxsub = this_comedidev->private; + /* subdevice which is the AD converter */ + s = this_comedidev->subdevices + SUBDEV_AD; + + /* first we test if something unusual has just happened */ + switch (urb->status) { + case 0: + /* copy the result in the transfer buffer */ + memcpy(this_usbduxsub->inBuffer, + urb->transfer_buffer, SIZEINBUF); + break; + case -EILSEQ: + /* error in the ISOchronous data */ + /* we don't copy the data into the transfer buffer */ + /* and recycle the last data byte */ + dev_dbg(&urb->dev->dev, + "comedi%d: usbdux: CRC error in ISO IN stream.\n", + this_usbduxsub->comedidev->minor); + + break; + + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + case -ECONNABORTED: + /* happens after an unlink command */ + if (this_usbduxsub->ai_cmd_running) { + /* we are still running a command */ + /* tell this comedi */ + s->async->events |= COMEDI_CB_EOA; + s->async->events |= COMEDI_CB_ERROR; + comedi_event(this_usbduxsub->comedidev, s); + /* stop the transfer w/o unlink */ + usbdux_ai_stop(this_usbduxsub, 0); + } + return; + + default: + /* a real error on the bus */ + /* pass error to comedi if we are really running a command */ + if (this_usbduxsub->ai_cmd_running) { + dev_err(&urb->dev->dev, + "Non-zero urb status received in ai intr " + "context: %d\n", urb->status); + s->async->events |= COMEDI_CB_EOA; + s->async->events |= COMEDI_CB_ERROR; + comedi_event(this_usbduxsub->comedidev, s); + /* don't do an unlink here */ + usbdux_ai_stop(this_usbduxsub, 0); + } + return; + } + + /* + * at this point we are reasonably sure that nothing dodgy has happened + * are we running a command? + */ + if (unlikely((!(this_usbduxsub->ai_cmd_running)))) { + /* + * not running a command, do not continue execution if no + * asynchronous command is running in particular not resubmit + */ + return; + } + + urb->dev = this_usbduxsub->usbdev; + + /* resubmit the urb */ + err = usb_submit_urb(urb, GFP_ATOMIC); + if (unlikely(err < 0)) { + dev_err(&urb->dev->dev, + "comedi_: urb resubmit failed in int-context!" + "err=%d\n", + err); + if (err == -EL2NSYNC) + dev_err(&urb->dev->dev, + "buggy USB host controller or bug in IRQ " + "handler!\n"); + s->async->events |= COMEDI_CB_EOA; + s->async->events |= COMEDI_CB_ERROR; + comedi_event(this_usbduxsub->comedidev, s); + /* don't do an unlink here */ + usbdux_ai_stop(this_usbduxsub, 0); + return; + } + + /* get the state of the dio pins to allow external trigger */ + dio_state = be32_to_cpu(this_usbduxsub->inBuffer[0]); + + this_usbduxsub->ai_counter--; + if (likely(this_usbduxsub->ai_counter > 0)) + return; + + /* timer zero, transfer measurements to comedi */ + this_usbduxsub->ai_counter = this_usbduxsub->ai_timer; + + /* test, if we transmit only a fixed number of samples */ + if (!(this_usbduxsub->ai_continous)) { + /* not continous, fixed number of samples */ + this_usbduxsub->ai_sample_count--; + /* all samples received? */ + if (this_usbduxsub->ai_sample_count < 0) { + /* prevent a resubmit next time */ + usbdux_ai_stop(this_usbduxsub, 0); + /* say comedi that the acquistion is over */ + s->async->events |= COMEDI_CB_EOA; + comedi_event(this_usbduxsub->comedidev, s); + return; + } + } + /* get the data from the USB bus and hand it over to comedi */ + n = s->async->cmd.chanlist_len; + for (i = 0; i < n; i++) { + /* transfer data, note first byte is the DIO state */ + v = be32_to_cpu(this_usbduxsub->inBuffer[i+1]); + /* strip status byte */ + v = v & 0x00ffffff; + /* convert to unsigned */ + v = v ^ 0x00800000; + /* write the byte to the buffer */ + err = cfc_write_array_to_buffer(s, &v, sizeof(uint32_t)); + if (unlikely(err == 0)) { + /* buffer overflow */ + usbdux_ai_stop(this_usbduxsub, 0); + return; + } + } + /* tell comedi that data is there */ + s->async->events |= COMEDI_CB_BLOCK | COMEDI_CB_EOS; + comedi_event(this_usbduxsub->comedidev, s); +} + +static int usbduxsub_unlink_OutURBs(struct usbduxsub *usbduxsub_tmp) +{ + int i = 0; + int err = 0; + + if (usbduxsub_tmp && usbduxsub_tmp->urbOut) { + for (i = 0; i < usbduxsub_tmp->numOfOutBuffers; i++) { + if (usbduxsub_tmp->urbOut[i]) + usb_kill_urb(usbduxsub_tmp->urbOut[i]); + + dev_dbg(&usbduxsub_tmp->interface->dev, + "comedi: usbdux: unlinked OutURB %d: res=%d\n", + i, err); + } + } + return err; +} + +/* This will cancel a running acquisition operation + * in any context. + */ +static int usbdux_ao_stop(struct usbduxsub *this_usbduxsub, int do_unlink) +{ + int ret = 0; + + if (!this_usbduxsub) + return -EFAULT; + dev_dbg(&this_usbduxsub->interface->dev, "comedi: usbdux_ao_cancel\n"); + + if (do_unlink) + ret = usbduxsub_unlink_OutURBs(this_usbduxsub); + + this_usbduxsub->ao_cmd_running = 0; + + return ret; +} + +/* force unlink, is called by comedi */ +static int usbdux_ao_cancel(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + struct usbduxsub *this_usbduxsub = dev->private; + int res = 0; + + if (!this_usbduxsub) + return -EFAULT; + + /* prevent other CPUs from submitting a command just now */ + down(&this_usbduxsub->sem); + if (!(this_usbduxsub->probed)) { + up(&this_usbduxsub->sem); + return -ENODEV; + } + /* unlink only if it is really running */ + res = usbdux_ao_stop(this_usbduxsub, this_usbduxsub->ao_cmd_running); + up(&this_usbduxsub->sem); + return res; +} + +static void usbduxsub_ao_IsocIrq(struct urb *urb) +{ + int i, ret; + uint8_t *datap; + struct usbduxsub *this_usbduxsub; + struct comedi_device *this_comedidev; + struct comedi_subdevice *s; + + /* the context variable points to the subdevice */ + this_comedidev = urb->context; + /* the private structure of the subdevice is struct usbduxsub */ + this_usbduxsub = this_comedidev->private; + + s = this_comedidev->subdevices + SUBDEV_DA; + + switch (urb->status) { + case 0: + /* success */ + break; + + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + case -ECONNABORTED: + /* after an unlink command, unplug, ... etc */ + /* no unlink needed here. Already shutting down. */ + if (this_usbduxsub->ao_cmd_running) { + s->async->events |= COMEDI_CB_EOA; + comedi_event(this_usbduxsub->comedidev, s); + usbdux_ao_stop(this_usbduxsub, 0); + } + return; + + default: + /* a real error */ + if (this_usbduxsub->ao_cmd_running) { + dev_err(&urb->dev->dev, + "comedi_: Non-zero urb status received in ao " + "intr context: %d\n", urb->status); + s->async->events |= COMEDI_CB_ERROR; + s->async->events |= COMEDI_CB_EOA; + comedi_event(this_usbduxsub->comedidev, s); + /* we do an unlink if we are in the high speed mode */ + usbdux_ao_stop(this_usbduxsub, 0); + } + return; + } + + /* are we actually running? */ + if (!(this_usbduxsub->ao_cmd_running)) + return; + + /* normal operation: executing a command in this subdevice */ + this_usbduxsub->ao_counter--; + if ((int)this_usbduxsub->ao_counter <= 0) { + /* timer zero */ + this_usbduxsub->ao_counter = this_usbduxsub->ao_timer; + + /* handle non continous aquisition */ + if (!(this_usbduxsub->ao_continous)) { + /* fixed number of samples */ + this_usbduxsub->ao_sample_count--; + if (this_usbduxsub->ao_sample_count < 0) { + /* all samples transmitted */ + usbdux_ao_stop(this_usbduxsub, 0); + s->async->events |= COMEDI_CB_EOA; + comedi_event(this_usbduxsub->comedidev, s); + /* no resubmit of the urb */ + return; + } + } + /* transmit data to the USB bus */ + ((uint8_t *) (urb->transfer_buffer))[0] = + s->async->cmd.chanlist_len; + for (i = 0; i < s->async->cmd.chanlist_len; i++) { + short temp; + if (i >= NUMOUTCHANNELS) + break; + + /* pointer to the DA */ + datap = + (&(((uint8_t *) urb->transfer_buffer)[i * 2 + 1])); + /* get the data from comedi */ + ret = comedi_buf_get(s->async, &temp); + datap[0] = temp; + datap[1] = this_usbduxsub->dac_commands[i]; + /* printk("data[0]=%x, data[1]=%x, data[2]=%x\n", */ + /* datap[0],datap[1],datap[2]); */ + if (ret < 0) { + dev_err(&urb->dev->dev, + "comedi: buffer underflow\n"); + s->async->events |= COMEDI_CB_EOA; + s->async->events |= COMEDI_CB_OVERFLOW; + } + /* transmit data to comedi */ + s->async->events |= COMEDI_CB_BLOCK; + comedi_event(this_usbduxsub->comedidev, s); + } + } + urb->transfer_buffer_length = SIZEOUTBUF; + urb->dev = this_usbduxsub->usbdev; + urb->status = 0; + if (this_usbduxsub->ao_cmd_running) { + if (this_usbduxsub->high_speed) { + /* uframes */ + urb->interval = 8; + } else { + /* frames */ + urb->interval = 1; + } + urb->number_of_packets = 1; + urb->iso_frame_desc[0].offset = 0; + urb->iso_frame_desc[0].length = SIZEOUTBUF; + urb->iso_frame_desc[0].status = 0; + ret = usb_submit_urb(urb, GFP_ATOMIC); + if (ret < 0) { + dev_err(&urb->dev->dev, + "comedi_: ao urb resubm failed in int-cont. " + "ret=%d", ret); + if (ret == EL2NSYNC) + dev_err(&urb->dev->dev, + "buggy USB host controller or bug in " + "IRQ handling!\n"); + + s->async->events |= COMEDI_CB_EOA; + s->async->events |= COMEDI_CB_ERROR; + comedi_event(this_usbduxsub->comedidev, s); + /* don't do an unlink here */ + usbdux_ao_stop(this_usbduxsub, 0); + } + } +} + +static int usbduxsub_start(struct usbduxsub *usbduxsub) +{ + int errcode = 0; + uint8_t local_transfer_buffer[16]; + + /* 7f92 to zero */ + local_transfer_buffer[0] = 0; + errcode = usb_control_msg(usbduxsub->usbdev, + /* create a pipe for a control transfer */ + usb_sndctrlpipe(usbduxsub->usbdev, 0), + /* bRequest, "Firmware" */ + USBDUXSUB_FIRMWARE, + /* bmRequestType */ + VENDOR_DIR_OUT, + /* Value */ + USBDUXSUB_CPUCS, + /* Index */ + 0x0000, + /* address of the transfer buffer */ + local_transfer_buffer, + /* Length */ + 1, + /* Timeout */ + BULK_TIMEOUT); + if (errcode < 0) { + dev_err(&usbduxsub->interface->dev, + "comedi_: control msg failed (start)\n"); + return errcode; + } + return 0; +} + +static int usbduxsub_stop(struct usbduxsub *usbduxsub) +{ + int errcode = 0; + + uint8_t local_transfer_buffer[16]; + + /* 7f92 to one */ + local_transfer_buffer[0] = 1; + errcode = usb_control_msg(usbduxsub->usbdev, + usb_sndctrlpipe(usbduxsub->usbdev, 0), + /* bRequest, "Firmware" */ + USBDUXSUB_FIRMWARE, + /* bmRequestType */ + VENDOR_DIR_OUT, + /* Value */ + USBDUXSUB_CPUCS, + /* Index */ + 0x0000, local_transfer_buffer, + /* Length */ + 1, + /* Timeout */ + BULK_TIMEOUT); + if (errcode < 0) { + dev_err(&usbduxsub->interface->dev, + "comedi_: control msg failed (stop)\n"); + return errcode; + } + return 0; +} + +static int usbduxsub_upload(struct usbduxsub *usbduxsub, + uint8_t *local_transfer_buffer, + unsigned int startAddr, unsigned int len) +{ + int errcode; + + errcode = usb_control_msg(usbduxsub->usbdev, + usb_sndctrlpipe(usbduxsub->usbdev, 0), + /* brequest, firmware */ + USBDUXSUB_FIRMWARE, + /* bmRequestType */ + VENDOR_DIR_OUT, + /* value */ + startAddr, + /* index */ + 0x0000, + /* our local safe buffer */ + local_transfer_buffer, + /* length */ + len, + /* timeout */ + BULK_TIMEOUT); + dev_dbg(&usbduxsub->interface->dev, "comedi_: result=%d\n", errcode); + if (errcode < 0) { + dev_err(&usbduxsub->interface->dev, + "comedi_: upload failed\n"); + return errcode; + } + return 0; +} + +/* the FX2LP has twice as much as the standard FX2 */ +#define FIRMWARE_MAX_LEN 0x4000 + +static int firmwareUpload(struct usbduxsub *usbduxsub, + const u8 *firmwareBinary, int sizeFirmware) +{ + int ret; + uint8_t *fwBuf; + + if (!firmwareBinary) + return 0; + + if (sizeFirmware > FIRMWARE_MAX_LEN) { + dev_err(&usbduxsub->interface->dev, + "usbduxsigma firmware binary it too large for FX2.\n"); + return -ENOMEM; + } + + /* we generate a local buffer for the firmware */ + fwBuf = kmemdup(firmwareBinary, sizeFirmware, GFP_KERNEL); + if (!fwBuf) { + dev_err(&usbduxsub->interface->dev, + "comedi_: mem alloc for firmware failed\n"); + return -ENOMEM; + } + + ret = usbduxsub_stop(usbduxsub); + if (ret < 0) { + dev_err(&usbduxsub->interface->dev, + "comedi_: can not stop firmware\n"); + kfree(fwBuf); + return ret; + } + + ret = usbduxsub_upload(usbduxsub, fwBuf, 0, sizeFirmware); + if (ret < 0) { + dev_err(&usbduxsub->interface->dev, + "comedi_: firmware upload failed\n"); + kfree(fwBuf); + return ret; + } + ret = usbduxsub_start(usbduxsub); + if (ret < 0) { + dev_err(&usbduxsub->interface->dev, + "comedi_: can not start firmware\n"); + kfree(fwBuf); + return ret; + } + kfree(fwBuf); + return 0; +} + +static int usbduxsub_submit_InURBs(struct usbduxsub *usbduxsub) +{ + int i, errFlag; + + if (!usbduxsub) + return -EFAULT; + + /* Submit all URBs and start the transfer on the bus */ + for (i = 0; i < usbduxsub->numOfInBuffers; i++) { + /* in case of a resubmission after an unlink... */ + usbduxsub->urbIn[i]->interval = usbduxsub->ai_interval; + usbduxsub->urbIn[i]->context = usbduxsub->comedidev; + usbduxsub->urbIn[i]->dev = usbduxsub->usbdev; + usbduxsub->urbIn[i]->status = 0; + usbduxsub->urbIn[i]->transfer_flags = URB_ISO_ASAP; + dev_dbg(&usbduxsub->interface->dev, + "comedi%d: submitting in-urb[%d]: %p,%p intv=%d\n", + usbduxsub->comedidev->minor, i, + (usbduxsub->urbIn[i]->context), + (usbduxsub->urbIn[i]->dev), + (usbduxsub->urbIn[i]->interval)); + errFlag = usb_submit_urb(usbduxsub->urbIn[i], GFP_ATOMIC); + if (errFlag) { + dev_err(&usbduxsub->interface->dev, + "comedi_: ai: usb_submit_urb(%d) error %d\n", + i, errFlag); + return errFlag; + } + } + return 0; +} + +static int usbduxsub_submit_OutURBs(struct usbduxsub *usbduxsub) +{ + int i, errFlag; + + if (!usbduxsub) + return -EFAULT; + + for (i = 0; i < usbduxsub->numOfOutBuffers; i++) { + dev_dbg(&usbduxsub->interface->dev, + "comedi_: submitting out-urb[%d]\n", i); + /* in case of a resubmission after an unlink... */ + usbduxsub->urbOut[i]->context = usbduxsub->comedidev; + usbduxsub->urbOut[i]->dev = usbduxsub->usbdev; + usbduxsub->urbOut[i]->status = 0; + usbduxsub->urbOut[i]->transfer_flags = URB_ISO_ASAP; + errFlag = usb_submit_urb(usbduxsub->urbOut[i], GFP_ATOMIC); + if (errFlag) { + dev_err(&usbduxsub->interface->dev, + "comedi_: ao: usb_submit_urb(%d) error %d\n", + i, errFlag); + return errFlag; + } + } + return 0; +} + +static int chanToInterval(int nChannels) +{ + if (nChannels <= 2) + /* 4kHz */ + return 2; + if (nChannels <= 8) + /* 2kHz */ + return 4; + /* 1kHz */ + return 8; +} + +static int usbdux_ai_cmdtest(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_cmd *cmd) +{ + int err = 0, tmp, i; + unsigned int tmpTimer; + struct usbduxsub *this_usbduxsub = dev->private; + + if (!(this_usbduxsub->probed)) + return -ENODEV; + + dev_dbg(&this_usbduxsub->interface->dev, + "comedi%d: usbdux_ai_cmdtest\n", dev->minor); + + /* make sure triggers are valid */ + /* Only immediate triggers are allowed */ + tmp = cmd->start_src; + cmd->start_src &= TRIG_NOW | TRIG_INT; + if (!cmd->start_src || tmp != cmd->start_src) + err++; + + /* trigger should happen timed */ + tmp = cmd->scan_begin_src; + /* start a new _scan_ with a timer */ + cmd->scan_begin_src &= TRIG_TIMER; + if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) + err++; + + /* scanning is continous */ + tmp = cmd->convert_src; + cmd->convert_src &= TRIG_NOW; + if (!cmd->convert_src || tmp != cmd->convert_src) + err++; + + /* issue a trigger when scan is finished and start a new scan */ + tmp = cmd->scan_end_src; + cmd->scan_end_src &= TRIG_COUNT; + if (!cmd->scan_end_src || tmp != cmd->scan_end_src) + err++; + + /* trigger at the end of count events or not, stop condition or not */ + tmp = cmd->stop_src; + cmd->stop_src &= TRIG_COUNT | TRIG_NONE; + if (!cmd->stop_src || tmp != cmd->stop_src) + err++; + + if (err) + return 1; + + /* + * step 2: make sure trigger sources are unique and mutually compatible + * note that mutual compatibility is not an issue here + */ + if (cmd->scan_begin_src != TRIG_FOLLOW && + cmd->scan_begin_src != TRIG_EXT && + cmd->scan_begin_src != TRIG_TIMER) + err++; + if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) + err++; + + if (err) + return 2; + + /* step 3: make sure arguments are trivially compatible */ + if (cmd->start_arg != 0) { + cmd->start_arg = 0; + err++; + } + + if (cmd->scan_begin_src == TRIG_FOLLOW) { + /* internal trigger */ + if (cmd->scan_begin_arg != 0) { + cmd->scan_begin_arg = 0; + err++; + } + } + + if (cmd->scan_begin_src == TRIG_TIMER) { + if (this_usbduxsub->high_speed) { + /* + * In high speed mode microframes are possible. + * However, during one microframe we can roughly + * sample two channels. Thus, the more channels + * are in the channel list the more time we need. + */ + i = chanToInterval(cmd->chanlist_len); + if (cmd->scan_begin_arg < (1000000 / 8 * i)) { + cmd->scan_begin_arg = 1000000 / 8 * i; + err++; + } + /* now calc the real sampling rate with all the + * rounding errors */ + tmpTimer = + ((unsigned int)(cmd->scan_begin_arg / 125000)) * + 125000; + if (cmd->scan_begin_arg != tmpTimer) { + cmd->scan_begin_arg = tmpTimer; + err++; + } + } else { + /* full speed */ + /* 1kHz scans every USB frame */ + if (cmd->scan_begin_arg < 1000000) { + cmd->scan_begin_arg = 1000000; + err++; + } + /* + * calc the real sampling rate with the rounding errors + */ + tmpTimer = ((unsigned int)(cmd->scan_begin_arg / + 1000000)) * 1000000; + if (cmd->scan_begin_arg != tmpTimer) { + cmd->scan_begin_arg = tmpTimer; + err++; + } + } + } + /* the same argument */ + if (cmd->scan_end_arg != cmd->chanlist_len) { + cmd->scan_end_arg = cmd->chanlist_len; + err++; + } + + if (cmd->stop_src == TRIG_COUNT) { + /* any count is allowed */ + } else { + /* TRIG_NONE */ + if (cmd->stop_arg != 0) { + cmd->stop_arg = 0; + err++; + } + } + + if (err) + return 3; + + return 0; +} + +/* + * creates the ADC command for the MAX1271 + * range is the range value from comedi + */ +static void create_adc_command(unsigned int chan, + uint8_t *muxsg0, + uint8_t *muxsg1) +{ + if (chan < 8) + (*muxsg0) = (*muxsg0) | (1 << chan); + else if (chan < 16) + (*muxsg1) = (*muxsg1) | (1 << (chan-8)); +} + + +/* bulk transfers to usbdux */ + +#define SENDADCOMMANDS 0 +#define SENDDACOMMANDS 1 +#define SENDDIOCONFIGCOMMAND 2 +#define SENDDIOBITSCOMMAND 3 +#define SENDSINGLEAD 4 +#define SENDPWMON 7 +#define SENDPWMOFF 8 + +static int send_dux_commands(struct usbduxsub *this_usbduxsub, int cmd_type) +{ + int result, nsent; + + this_usbduxsub->dux_commands[0] = cmd_type; +#ifdef NOISY_DUX_DEBUGBUG + printk(KERN_DEBUG "comedi%d: usbdux: dux_commands: ", + this_usbduxsub->comedidev->minor); + for (result = 0; result < SIZEOFDUXBUFFER; result++) + printk(" %02x", this_usbduxsub->dux_commands[result]); + printk("\n"); +#endif + result = usb_bulk_msg(this_usbduxsub->usbdev, + usb_sndbulkpipe(this_usbduxsub->usbdev, + COMMAND_OUT_EP), + this_usbduxsub->dux_commands, SIZEOFDUXBUFFER, + &nsent, BULK_TIMEOUT); + if (result < 0) + dev_err(&this_usbduxsub->interface->dev, "comedi%d: " + "could not transmit dux_command to the usb-device, " + "err=%d\n", this_usbduxsub->comedidev->minor, result); + + return result; +} + +static int receive_dux_commands(struct usbduxsub *this_usbduxsub, int command) +{ + int result = (-EFAULT); + int nrec; + int i; + + for (i = 0; i < RETRIES; i++) { + result = usb_bulk_msg(this_usbduxsub->usbdev, + usb_rcvbulkpipe(this_usbduxsub->usbdev, + COMMAND_IN_EP), + this_usbduxsub->insnBuffer, SIZEINSNBUF, + &nrec, BULK_TIMEOUT); + if (result < 0) { + dev_err(&this_usbduxsub->interface->dev, "comedi%d: " + "insn: USB error %d " + "while receiving DUX command" + "\n", this_usbduxsub->comedidev->minor, + result); + return result; + } + if (this_usbduxsub->insnBuffer[0] == command) + return result; + } + /* this is only reached if the data has been requested a couple of + * times */ + dev_err(&this_usbduxsub->interface->dev, "comedi%d: insn: " + "wrong data returned from firmware: want %d, got %d.\n", + this_usbduxsub->comedidev->minor, command, + this_usbduxsub->insnBuffer[0]); + return -EFAULT; +} + +static int usbdux_ai_inttrig(struct comedi_device *dev, + struct comedi_subdevice *s, unsigned int trignum) +{ + int ret; + struct usbduxsub *this_usbduxsub = dev->private; + if (!this_usbduxsub) + return -EFAULT; + + down(&this_usbduxsub->sem); + if (!(this_usbduxsub->probed)) { + up(&this_usbduxsub->sem); + return -ENODEV; + } + dev_dbg(&this_usbduxsub->interface->dev, + "comedi%d: usbdux_ai_inttrig\n", dev->minor); + + if (trignum != 0) { + dev_err(&this_usbduxsub->interface->dev, + "comedi%d: usbdux_ai_inttrig: invalid trignum\n", + dev->minor); + up(&this_usbduxsub->sem); + return -EINVAL; + } + if (!(this_usbduxsub->ai_cmd_running)) { + this_usbduxsub->ai_cmd_running = 1; + ret = usbduxsub_submit_InURBs(this_usbduxsub); + if (ret < 0) { + dev_err(&this_usbduxsub->interface->dev, + "comedi%d: usbdux_ai_inttrig: " + "urbSubmit: err=%d\n", dev->minor, ret); + this_usbduxsub->ai_cmd_running = 0; + up(&this_usbduxsub->sem); + return ret; + } + s->async->inttrig = NULL; + } else { + dev_err(&this_usbduxsub->interface->dev, + "comedi%d: ai_inttrig but acqu is already running\n", + dev->minor); + } + up(&this_usbduxsub->sem); + return 1; +} + +static int usbdux_ai_cmd(struct comedi_device *dev, struct comedi_subdevice *s) +{ + struct comedi_cmd *cmd = &s->async->cmd; + unsigned int chan; + int i, ret; + struct usbduxsub *this_usbduxsub = dev->private; + int result; + uint8_t muxsg0 = 0; + uint8_t muxsg1 = 0; + uint8_t sysred = 0; + + if (!this_usbduxsub) + return -EFAULT; + + dev_dbg(&this_usbduxsub->interface->dev, + "comedi%d: usbdux_ai_cmd\n", dev->minor); + + /* block other CPUs from starting an ai_cmd */ + down(&this_usbduxsub->sem); + + if (!(this_usbduxsub->probed)) { + up(&this_usbduxsub->sem); + return -ENODEV; + } + if (this_usbduxsub->ai_cmd_running) { + dev_err(&this_usbduxsub->interface->dev, "comedi%d: " + "ai_cmd not possible. Another ai_cmd is running.\n", + dev->minor); + up(&this_usbduxsub->sem); + return -EBUSY; + } + /* set current channel of the running aquisition to zero */ + s->async->cur_chan = 0; + + /* first the number of channels per time step */ + this_usbduxsub->dux_commands[1] = cmd->chanlist_len; + + /* CONFIG0 */ + this_usbduxsub->dux_commands[2] = 0x12; + + /* CONFIG1: 23kHz sampling rate, delay = 0us, */ + this_usbduxsub->dux_commands[3] = 0x03; + + /* CONFIG3: differential channels off */ + this_usbduxsub->dux_commands[4] = 0x00; + + for (i = 0; i < cmd->chanlist_len; i++) { + chan = CR_CHAN(cmd->chanlist[i]); + create_adc_command(chan, &muxsg0, &muxsg1); + if (i >= NUMCHANNELS) { + dev_err(&this_usbduxsub->interface->dev, + "comedi%d: channel list too long\n", + dev->minor); + break; + } + } + this_usbduxsub->dux_commands[5] = muxsg0; + this_usbduxsub->dux_commands[6] = muxsg1; + this_usbduxsub->dux_commands[7] = sysred; + + dev_dbg(&this_usbduxsub->interface->dev, + "comedi %d: sending commands to the usb device: size=%u\n", + dev->minor, NUMCHANNELS); + + result = send_dux_commands(this_usbduxsub, SENDADCOMMANDS); + if (result < 0) { + up(&this_usbduxsub->sem); + return result; + } + + if (this_usbduxsub->high_speed) { + /* + * every 2 channels get a time window of 125us. Thus, if we + * sample all 16 channels we need 1ms. If we sample only one + * channel we need only 125us + */ + this_usbduxsub->ai_interval = + chanToInterval(cmd->chanlist_len); + this_usbduxsub->ai_timer = cmd->scan_begin_arg / (125000 * + (this_usbduxsub-> + ai_interval)); + } else { + /* interval always 1ms */ + this_usbduxsub->ai_interval = 1; + this_usbduxsub->ai_timer = cmd->scan_begin_arg / 1000000; + } + if (this_usbduxsub->ai_timer < 1) { + dev_err(&this_usbduxsub->interface->dev, "comedi%d: ai_cmd: " + "timer=%d, scan_begin_arg=%d. " + "Not properly tested by cmdtest?\n", dev->minor, + this_usbduxsub->ai_timer, cmd->scan_begin_arg); + up(&this_usbduxsub->sem); + return -EINVAL; + } + this_usbduxsub->ai_counter = this_usbduxsub->ai_timer; + + if (cmd->stop_src == TRIG_COUNT) { + /* data arrives as one packet */ + this_usbduxsub->ai_sample_count = cmd->stop_arg; + this_usbduxsub->ai_continous = 0; + } else { + /* continous aquisition */ + this_usbduxsub->ai_continous = 1; + this_usbduxsub->ai_sample_count = 0; + } + + if (cmd->start_src == TRIG_NOW) { + /* enable this acquisition operation */ + this_usbduxsub->ai_cmd_running = 1; + ret = usbduxsub_submit_InURBs(this_usbduxsub); + if (ret < 0) { + this_usbduxsub->ai_cmd_running = 0; + /* fixme: unlink here?? */ + up(&this_usbduxsub->sem); + return ret; + } + s->async->inttrig = NULL; + } else { + /* TRIG_INT */ + /* don't enable the acquision operation */ + /* wait for an internal signal */ + s->async->inttrig = usbdux_ai_inttrig; + } + up(&this_usbduxsub->sem); + return 0; +} + +/* Mode 0 is used to get a single conversion on demand */ +static int usbdux_ai_insn_read(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + int i; + int32_t one = 0; + int chan; + int err; + struct usbduxsub *this_usbduxsub = dev->private; + uint8_t muxsg0 = 0; + uint8_t muxsg1 = 0; + uint8_t sysred = 0; + + if (!this_usbduxsub) + return 0; + + dev_dbg(&this_usbduxsub->interface->dev, + "comedi%d: ai_insn_read, insn->n=%d, insn->subdev=%d\n", + dev->minor, insn->n, insn->subdev); + + down(&this_usbduxsub->sem); + if (!(this_usbduxsub->probed)) { + up(&this_usbduxsub->sem); + return -ENODEV; + } + if (this_usbduxsub->ai_cmd_running) { + dev_err(&this_usbduxsub->interface->dev, + "comedi%d: ai_insn_read not possible. " + "Async Command is running.\n", dev->minor); + up(&this_usbduxsub->sem); + return 0; + } + + /* sample one channel */ + /* CONFIG0: chopper on */ + this_usbduxsub->dux_commands[1] = 0x16; + + /* CONFIG1: 2kHz sampling rate */ + this_usbduxsub->dux_commands[2] = 0x80; + + /* CONFIG3: differential channels off */ + this_usbduxsub->dux_commands[3] = 0x00; + + chan = CR_CHAN(insn->chanspec); + create_adc_command(chan, &muxsg0, &muxsg1); + + this_usbduxsub->dux_commands[4] = muxsg0; + this_usbduxsub->dux_commands[5] = muxsg1; + this_usbduxsub->dux_commands[6] = sysred; + + /* adc commands */ + err = send_dux_commands(this_usbduxsub, SENDSINGLEAD); + if (err < 0) { + up(&this_usbduxsub->sem); + return err; + } + + for (i = 0; i < insn->n; i++) { + err = receive_dux_commands(this_usbduxsub, SENDSINGLEAD); + if (err < 0) { + up(&this_usbduxsub->sem); + return 0; + } + /* 32 bits big endian from the A/D converter */ + one = be32_to_cpu(*((int32_t *) + ((this_usbduxsub->insnBuffer)+1))); + /* mask out the staus byte */ + one = one & 0x00ffffff; + /* turn it into an unsigned integer */ + one = one ^ 0x00800000; + data[i] = one; + } + up(&this_usbduxsub->sem); + return i; +} + + + + +static int usbdux_getstatusinfo(struct comedi_device *dev, int chan) +{ + struct usbduxsub *this_usbduxsub = dev->private; + uint8_t sysred = 0; + uint32_t one; + int err; + + if (!this_usbduxsub) + return 0; + + if (this_usbduxsub->ai_cmd_running) { + dev_err(&this_usbduxsub->interface->dev, + "comedi%d: status read not possible. " + "Async Command is running.\n", dev->minor); + return 0; + } + + /* CONFIG0 */ + this_usbduxsub->dux_commands[1] = 0x12; + + /* CONFIG1: 2kHz sampling rate */ + this_usbduxsub->dux_commands[2] = 0x80; + + /* CONFIG3: differential channels off */ + this_usbduxsub->dux_commands[3] = 0x00; + + if (chan == 1) { + /* ADC offset */ + sysred = sysred | 1; + } else if (chan == 2) { + /* VCC */ + sysred = sysred | 4; + } else if (chan == 3) { + /* temperature */ + sysred = sysred | 8; + } else if (chan == 4) { + /* gain */ + sysred = sysred | 16; + } else if (chan == 5) { + /* ref */ + sysred = sysred | 32; + } + + this_usbduxsub->dux_commands[4] = 0; + this_usbduxsub->dux_commands[5] = 0; + this_usbduxsub->dux_commands[6] = sysred; + + /* adc commands */ + err = send_dux_commands(this_usbduxsub, SENDSINGLEAD); + if (err < 0) + return err; + + err = receive_dux_commands(this_usbduxsub, SENDSINGLEAD); + if (err < 0) + return err; + + /* 32 bits big endian from the A/D converter */ + one = be32_to_cpu(*((int32_t *)((this_usbduxsub->insnBuffer)+1))); + /* mask out the staus byte */ + one = one & 0x00ffffff; + one = one ^ 0x00800000; + + return (int)one; +} + + + + + + +/************************************/ +/* analog out */ + +static int usbdux_ao_insn_read(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + int i; + int chan = CR_CHAN(insn->chanspec); + struct usbduxsub *this_usbduxsub = dev->private; + + if (!this_usbduxsub) + return -EFAULT; + + down(&this_usbduxsub->sem); + if (!(this_usbduxsub->probed)) { + up(&this_usbduxsub->sem); + return -ENODEV; + } + for (i = 0; i < insn->n; i++) + data[i] = this_usbduxsub->outBuffer[chan]; + + up(&this_usbduxsub->sem); + return i; +} + +static int usbdux_ao_insn_write(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + int i, err; + int chan = CR_CHAN(insn->chanspec); + struct usbduxsub *this_usbduxsub = dev->private; + + if (!this_usbduxsub) + return -EFAULT; + + dev_dbg(&this_usbduxsub->interface->dev, + "comedi%d: ao_insn_write\n", dev->minor); + + down(&this_usbduxsub->sem); + if (!(this_usbduxsub->probed)) { + up(&this_usbduxsub->sem); + return -ENODEV; + } + if (this_usbduxsub->ao_cmd_running) { + dev_err(&this_usbduxsub->interface->dev, + "comedi%d: ao_insn_write: " + "ERROR: asynchronous ao_cmd is running\n", dev->minor); + up(&this_usbduxsub->sem); + return 0; + } + + for (i = 0; i < insn->n; i++) { + dev_dbg(&this_usbduxsub->interface->dev, + "comedi%d: ao_insn_write: data[chan=%d,i=%d]=%d\n", + dev->minor, chan, i, data[i]); + + /* number of channels: 1 */ + this_usbduxsub->dux_commands[1] = 1; + /* channel number */ + this_usbduxsub->dux_commands[2] = data[i]; + this_usbduxsub->outBuffer[chan] = data[i]; + this_usbduxsub->dux_commands[3] = chan; + err = send_dux_commands(this_usbduxsub, SENDDACOMMANDS); + if (err < 0) { + up(&this_usbduxsub->sem); + return err; + } + } + up(&this_usbduxsub->sem); + + return i; +} + +static int usbdux_ao_inttrig(struct comedi_device *dev, + struct comedi_subdevice *s, unsigned int trignum) +{ + int ret; + struct usbduxsub *this_usbduxsub = dev->private; + + if (!this_usbduxsub) + return -EFAULT; + + down(&this_usbduxsub->sem); + if (!(this_usbduxsub->probed)) { + up(&this_usbduxsub->sem); + return -ENODEV; + } + if (trignum != 0) { + dev_err(&this_usbduxsub->interface->dev, + "comedi%d: usbdux_ao_inttrig: invalid trignum\n", + dev->minor); + return -EINVAL; + } + if (!(this_usbduxsub->ao_cmd_running)) { + this_usbduxsub->ao_cmd_running = 1; + ret = usbduxsub_submit_OutURBs(this_usbduxsub); + if (ret < 0) { + dev_err(&this_usbduxsub->interface->dev, + "comedi%d: usbdux_ao_inttrig: submitURB: " + "err=%d\n", dev->minor, ret); + this_usbduxsub->ao_cmd_running = 0; + up(&this_usbduxsub->sem); + return ret; + } + s->async->inttrig = NULL; + } else { + dev_err(&this_usbduxsub->interface->dev, + "comedi%d: ao_inttrig but acqu is already running.\n", + dev->minor); + } + up(&this_usbduxsub->sem); + return 1; +} + +static int usbdux_ao_cmdtest(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_cmd *cmd) +{ + int err = 0, tmp; + struct usbduxsub *this_usbduxsub = dev->private; + + if (!this_usbduxsub) + return -EFAULT; + + if (!(this_usbduxsub->probed)) + return -ENODEV; + + dev_dbg(&this_usbduxsub->interface->dev, + "comedi%d: usbdux_ao_cmdtest\n", dev->minor); + + /* make sure triggers are valid */ + /* Only immediate triggers are allowed */ + tmp = cmd->start_src; + cmd->start_src &= TRIG_NOW | TRIG_INT; + if (!cmd->start_src || tmp != cmd->start_src) + err++; + + /* trigger should happen timed */ + tmp = cmd->scan_begin_src; + /* just now we scan also in the high speed mode every frame */ + /* this is due to ehci driver limitations */ + if (0) { /* (this_usbduxsub->high_speed) */ + /* start immidiately a new scan */ + /* the sampling rate is set by the coversion rate */ + cmd->scan_begin_src &= TRIG_FOLLOW; + } else { + /* start a new scan (output at once) with a timer */ + cmd->scan_begin_src &= TRIG_TIMER; + } + if (!cmd->scan_begin_src || tmp != cmd->scan_begin_src) + err++; + + /* scanning is continous */ + tmp = cmd->convert_src; + + /* all conversion events happen simultaneously */ + cmd->convert_src &= TRIG_NOW; + + if (!cmd->convert_src || tmp != cmd->convert_src) + err++; + + /* issue a trigger when scan is finished and start a new scan */ + tmp = cmd->scan_end_src; + cmd->scan_end_src &= TRIG_COUNT; + if (!cmd->scan_end_src || tmp != cmd->scan_end_src) + err++; + + /* trigger at the end of count events or not, stop condition or not */ + tmp = cmd->stop_src; + cmd->stop_src &= TRIG_COUNT | TRIG_NONE; + if (!cmd->stop_src || tmp != cmd->stop_src) + err++; + + if (err) + return 1; + + /* + * step 2: make sure trigger sources + * are unique and mutually compatible + * note that mutual compatibility is not an issue here + */ + if (cmd->scan_begin_src != TRIG_FOLLOW && + cmd->scan_begin_src != TRIG_EXT && + cmd->scan_begin_src != TRIG_TIMER) + err++; + if (cmd->stop_src != TRIG_COUNT && cmd->stop_src != TRIG_NONE) + err++; + + if (err) + return 2; + + /* step 3: make sure arguments are trivially compatible */ + + if (cmd->start_arg != 0) { + cmd->start_arg = 0; + err++; + } + + if (cmd->scan_begin_src == TRIG_FOLLOW) { + /* internal trigger */ + if (cmd->scan_begin_arg != 0) { + cmd->scan_begin_arg = 0; + err++; + } + } + + if (cmd->scan_begin_src == TRIG_TIMER) { + /* timer */ + if (cmd->scan_begin_arg < 1000000) { + cmd->scan_begin_arg = 1000000; + err++; + } + } + /* not used now, is for later use */ + if (cmd->convert_src == TRIG_TIMER) { + if (cmd->convert_arg < 125000) { + cmd->convert_arg = 125000; + err++; + } + } + + /* the same argument */ + if (cmd->scan_end_arg != cmd->chanlist_len) { + cmd->scan_end_arg = cmd->chanlist_len; + err++; + } + + if (cmd->stop_src == TRIG_COUNT) { + /* any count is allowed */ + } else { + /* TRIG_NONE */ + if (cmd->stop_arg != 0) { + cmd->stop_arg = 0; + err++; + } + } + + dev_dbg(&this_usbduxsub->interface->dev, "comedi%d: err=%d, " + "scan_begin_src=%d, scan_begin_arg=%d, convert_src=%d, " + "convert_arg=%d\n", dev->minor, err, cmd->scan_begin_src, + cmd->scan_begin_arg, cmd->convert_src, cmd->convert_arg); + + if (err) + return 3; + + return 0; +} + +static int usbdux_ao_cmd(struct comedi_device *dev, struct comedi_subdevice *s) +{ + struct comedi_cmd *cmd = &s->async->cmd; + unsigned int chan, gain; + int i, ret; + struct usbduxsub *this_usbduxsub = dev->private; + + if (!this_usbduxsub) + return -EFAULT; + + down(&this_usbduxsub->sem); + if (!(this_usbduxsub->probed)) { + up(&this_usbduxsub->sem); + return -ENODEV; + } + dev_dbg(&this_usbduxsub->interface->dev, + "comedi%d: %s\n", dev->minor, __func__); + + /* set current channel of the running aquisition to zero */ + s->async->cur_chan = 0; + for (i = 0; i < cmd->chanlist_len; ++i) { + chan = CR_CHAN(cmd->chanlist[i]); + gain = CR_RANGE(cmd->chanlist[i]); + if (i >= NUMOUTCHANNELS) { + dev_err(&this_usbduxsub->interface->dev, + "comedi%d: %s: channel list too long\n", + dev->minor, __func__); + break; + } + this_usbduxsub->dac_commands[i] = chan; + dev_dbg(&this_usbduxsub->interface->dev, + "comedi%d: dac command for ch %d is %x\n", + dev->minor, i, this_usbduxsub->dac_commands[i]); + } + + /* we count in steps of 1ms (125us) */ + /* 125us mode not used yet */ + if (0) { /* (this_usbduxsub->high_speed) */ + /* 125us */ + /* timing of the conversion itself: every 125 us */ + this_usbduxsub->ao_timer = cmd->convert_arg / 125000; + } else { + /* 1ms */ + /* timing of the scan: we get all channels at once */ + this_usbduxsub->ao_timer = cmd->scan_begin_arg / 1000000; + dev_dbg(&this_usbduxsub->interface->dev, + "comedi%d: scan_begin_src=%d, scan_begin_arg=%d, " + "convert_src=%d, convert_arg=%d\n", dev->minor, + cmd->scan_begin_src, cmd->scan_begin_arg, + cmd->convert_src, cmd->convert_arg); + dev_dbg(&this_usbduxsub->interface->dev, + "comedi%d: ao_timer=%d (ms)\n", + dev->minor, this_usbduxsub->ao_timer); + if (this_usbduxsub->ao_timer < 1) { + dev_err(&this_usbduxsub->interface->dev, + "comedi%d: usbdux: ao_timer=%d, " + "scan_begin_arg=%d. " + "Not properly tested by cmdtest?\n", + dev->minor, this_usbduxsub->ao_timer, + cmd->scan_begin_arg); + up(&this_usbduxsub->sem); + return -EINVAL; + } + } + this_usbduxsub->ao_counter = this_usbduxsub->ao_timer; + + if (cmd->stop_src == TRIG_COUNT) { + /* not continous */ + /* counter */ + /* high speed also scans everything at once */ + if (0) { /* (this_usbduxsub->high_speed) */ + this_usbduxsub->ao_sample_count = + (cmd->stop_arg) * (cmd->scan_end_arg); + } else { + /* there's no scan as the scan has been */ + /* perf inside the FX2 */ + /* data arrives as one packet */ + this_usbduxsub->ao_sample_count = cmd->stop_arg; + } + this_usbduxsub->ao_continous = 0; + } else { + /* continous aquisition */ + this_usbduxsub->ao_continous = 1; + this_usbduxsub->ao_sample_count = 0; + } + + if (cmd->start_src == TRIG_NOW) { + /* enable this acquisition operation */ + this_usbduxsub->ao_cmd_running = 1; + ret = usbduxsub_submit_OutURBs(this_usbduxsub); + if (ret < 0) { + this_usbduxsub->ao_cmd_running = 0; + /* fixme: unlink here?? */ + up(&this_usbduxsub->sem); + return ret; + } + s->async->inttrig = NULL; + } else { + /* TRIG_INT */ + /* submit the urbs later */ + /* wait for an internal signal */ + s->async->inttrig = usbdux_ao_inttrig; + } + + up(&this_usbduxsub->sem); + return 0; +} + +static int usbdux_dio_insn_config(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + int chan = CR_CHAN(insn->chanspec); + + /* The input or output configuration of each digital line is + * configured by a special insn_config instruction. chanspec + * contains the channel to be changed, and data[0] contains the + * value COMEDI_INPUT or COMEDI_OUTPUT. */ + + switch (data[0]) { + case INSN_CONFIG_DIO_OUTPUT: + s->io_bits |= 1 << chan; /* 1 means Out */ + break; + case INSN_CONFIG_DIO_INPUT: + s->io_bits &= ~(1 << chan); + break; + case INSN_CONFIG_DIO_QUERY: + data[1] = + (s->io_bits & (1 << chan)) ? COMEDI_OUTPUT : COMEDI_INPUT; + break; + default: + return -EINVAL; + break; + } + /* we don't tell the firmware here as it would take 8 frames */ + /* to submit the information. We do it in the insn_bits. */ + return insn->n; +} + +static int usbdux_dio_insn_bits(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, + unsigned int *data) +{ + + struct usbduxsub *this_usbduxsub = dev->private; + int err; + + if (!this_usbduxsub) + return -EFAULT; + + if (insn->n != 2) + return -EINVAL; + + down(&this_usbduxsub->sem); + + if (!(this_usbduxsub->probed)) { + up(&this_usbduxsub->sem); + return -ENODEV; + } + + /* The insn data is a mask in data[0] and the new data + * in data[1], each channel cooresponding to a bit. */ + s->state &= ~data[0]; + s->state |= data[0] & data[1]; + /* The commands are 8 bits wide */ + this_usbduxsub->dux_commands[1] = (s->io_bits) & 0x000000FF; + this_usbduxsub->dux_commands[4] = (s->state) & 0x000000FF; + this_usbduxsub->dux_commands[2] = ((s->io_bits) & 0x0000FF00) >> 8; + this_usbduxsub->dux_commands[5] = ((s->state) & 0x0000FF00) >> 8; + this_usbduxsub->dux_commands[3] = ((s->io_bits) & 0x00FF0000) >> 16; + this_usbduxsub->dux_commands[6] = ((s->state) & 0x00FF0000) >> 16; + + /* This command also tells the firmware to return */ + /* the digital input lines */ + err = send_dux_commands(this_usbduxsub, SENDDIOBITSCOMMAND); + if (err < 0) { + up(&this_usbduxsub->sem); + return err; + } + err = receive_dux_commands(this_usbduxsub, SENDDIOBITSCOMMAND); + if (err < 0) { + up(&this_usbduxsub->sem); + return err; + } + + data[1] = (((unsigned int)(this_usbduxsub->insnBuffer[1]))&0xff) | + ((((unsigned int)(this_usbduxsub->insnBuffer[2]))&0xff) << 8) | + ((((unsigned int)(this_usbduxsub->insnBuffer[3]))&0xff) << 16); + + s->state = data[1]; + + up(&this_usbduxsub->sem); + return 2; +} + +/***********************************/ +/* PWM */ + +static int usbduxsub_unlink_PwmURBs(struct usbduxsub *usbduxsub_tmp) +{ + int err = 0; + + if (usbduxsub_tmp && usbduxsub_tmp->urbPwm) { + if (usbduxsub_tmp->urbPwm) + usb_kill_urb(usbduxsub_tmp->urbPwm); + dev_dbg(&usbduxsub_tmp->interface->dev, + "comedi: unlinked PwmURB: res=%d\n", err); + } + return err; +} + +/* This cancels a running acquisition operation + * in any context. + */ +static int usbdux_pwm_stop(struct usbduxsub *this_usbduxsub, int do_unlink) +{ + int ret = 0; + + if (!this_usbduxsub) + return -EFAULT; + + dev_dbg(&this_usbduxsub->interface->dev, "comedi: %s\n", __func__); + if (do_unlink) + ret = usbduxsub_unlink_PwmURBs(this_usbduxsub); + + this_usbduxsub->pwm_cmd_running = 0; + + return ret; +} + +/* force unlink - is called by comedi */ +static int usbdux_pwm_cancel(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + struct usbduxsub *this_usbduxsub = dev->private; + int res = 0; + + /* unlink only if it is really running */ + res = usbdux_pwm_stop(this_usbduxsub, this_usbduxsub->pwm_cmd_running); + + dev_dbg(&this_usbduxsub->interface->dev, + "comedi %d: sending pwm off command to the usb device.\n", + dev->minor); + res = send_dux_commands(this_usbduxsub, SENDPWMOFF); + if (res < 0) + return res; + + return res; +} + +static void usbduxsub_pwm_irq(struct urb *urb) +{ + int ret; + struct usbduxsub *this_usbduxsub; + struct comedi_device *this_comedidev; + struct comedi_subdevice *s; + + /* printk(KERN_DEBUG "PWM: IRQ\n"); */ + + /* the context variable points to the subdevice */ + this_comedidev = urb->context; + /* the private structure of the subdevice is struct usbduxsub */ + this_usbduxsub = this_comedidev->private; + + s = this_comedidev->subdevices + SUBDEV_DA; + + switch (urb->status) { + case 0: + /* success */ + break; + + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + case -ECONNABORTED: + /* + * after an unlink command, unplug, ... etc + * no unlink needed here. Already shutting down. + */ + if (this_usbduxsub->pwm_cmd_running) + usbdux_pwm_stop(this_usbduxsub, 0); + + return; + + default: + /* a real error */ + if (this_usbduxsub->pwm_cmd_running) { + dev_err(&this_usbduxsub->interface->dev, + "comedi_: Non-zero urb status received in " + "pwm intr context: %d\n", urb->status); + usbdux_pwm_stop(this_usbduxsub, 0); + } + return; + } + + /* are we actually running? */ + if (!(this_usbduxsub->pwm_cmd_running)) + return; + + urb->transfer_buffer_length = this_usbduxsub->sizePwmBuf; + urb->dev = this_usbduxsub->usbdev; + urb->status = 0; + if (this_usbduxsub->pwm_cmd_running) { + ret = usb_submit_urb(urb, GFP_ATOMIC); + if (ret < 0) { + dev_err(&this_usbduxsub->interface->dev, + "comedi_: pwm urb resubm failed in int-cont. " + "ret=%d", ret); + if (ret == EL2NSYNC) + dev_err(&this_usbduxsub->interface->dev, + "buggy USB host controller or bug in " + "IRQ handling!\n"); + + /* don't do an unlink here */ + usbdux_pwm_stop(this_usbduxsub, 0); + } + } +} + +static int usbduxsub_submit_PwmURBs(struct usbduxsub *usbduxsub) +{ + int errFlag; + + if (!usbduxsub) + return -EFAULT; + + dev_dbg(&usbduxsub->interface->dev, "comedi_: submitting pwm-urb\n"); + + /* in case of a resubmission after an unlink... */ + usb_fill_bulk_urb(usbduxsub->urbPwm, + usbduxsub->usbdev, + usb_sndbulkpipe(usbduxsub->usbdev, PWM_EP), + usbduxsub->urbPwm->transfer_buffer, + usbduxsub->sizePwmBuf, usbduxsub_pwm_irq, + usbduxsub->comedidev); + + errFlag = usb_submit_urb(usbduxsub->urbPwm, GFP_ATOMIC); + if (errFlag) { + dev_err(&usbduxsub->interface->dev, + "comedi_: usbduxsigma: pwm: usb_submit_urb error %d\n", + errFlag); + return errFlag; + } + return 0; +} + +static int usbdux_pwm_period(struct comedi_device *dev, + struct comedi_subdevice *s, unsigned int period) +{ + struct usbduxsub *this_usbduxsub = dev->private; + int fx2delay = 255; + + if (period < MIN_PWM_PERIOD) { + dev_err(&this_usbduxsub->interface->dev, + "comedi%d: illegal period setting for pwm.\n", + dev->minor); + return -EAGAIN; + } else { + fx2delay = period / ((int)(6 * 512 * (1.0 / 0.033))) - 6; + if (fx2delay > 255) { + dev_err(&this_usbduxsub->interface->dev, + "comedi%d: period %d for pwm is too low.\n", + dev->minor, period); + return -EAGAIN; + } + } + this_usbduxsub->pwmDelay = fx2delay; + this_usbduxsub->pwmPeriod = period; + dev_dbg(&this_usbduxsub->interface->dev, "%s: frequ=%d, period=%d\n", + __func__, period, fx2delay); + return 0; +} + +/* is called from insn so there's no need to do all the sanity checks */ +static int usbdux_pwm_start(struct comedi_device *dev, + struct comedi_subdevice *s) +{ + int ret, i; + struct usbduxsub *this_usbduxsub = dev->private; + + dev_dbg(&this_usbduxsub->interface->dev, "comedi%d: %s\n", + dev->minor, __func__); + + if (this_usbduxsub->pwm_cmd_running) { + /* already running */ + return 0; + } + + this_usbduxsub->dux_commands[1] = ((uint8_t) this_usbduxsub->pwmDelay); + ret = send_dux_commands(this_usbduxsub, SENDPWMON); + if (ret < 0) + return ret; + + /* initialise the buffer */ + for (i = 0; i < this_usbduxsub->sizePwmBuf; i++) + ((char *)(this_usbduxsub->urbPwm->transfer_buffer))[i] = 0; + + this_usbduxsub->pwm_cmd_running = 1; + ret = usbduxsub_submit_PwmURBs(this_usbduxsub); + if (ret < 0) { + this_usbduxsub->pwm_cmd_running = 0; + return ret; + } + return 0; +} + +/* generates the bit pattern for PWM with the optional sign bit */ +static int usbdux_pwm_pattern(struct comedi_device *dev, + struct comedi_subdevice *s, int channel, + unsigned int value, unsigned int sign) +{ + struct usbduxsub *this_usbduxsub = dev->private; + int i, szbuf; + char *pBuf; + char pwm_mask; + char sgn_mask; + char c; + + if (!this_usbduxsub) + return -EFAULT; + + /* this is the DIO bit which carries the PWM data */ + pwm_mask = (1 << channel); + /* this is the DIO bit which carries the optional direction bit */ + sgn_mask = (16 << channel); + /* this is the buffer which will be filled with the with bit */ + /* pattern for one period */ + szbuf = this_usbduxsub->sizePwmBuf; + pBuf = (char *)(this_usbduxsub->urbPwm->transfer_buffer); + for (i = 0; i < szbuf; i++) { + c = *pBuf; + /* reset bits */ + c = c & (~pwm_mask); + /* set the bit as long as the index is lower than the value */ + if (i < value) + c = c | pwm_mask; + /* set the optional sign bit for a relay */ + if (!sign) { + /* positive value */ + c = c & (~sgn_mask); + } else { + /* negative value */ + c = c | sgn_mask; + } + *(pBuf++) = c; + } + return 1; +} + +static int usbdux_pwm_write(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + struct usbduxsub *this_usbduxsub = dev->private; + + if (!this_usbduxsub) + return -EFAULT; + + if ((insn->n) != 1) { + /* + * doesn't make sense to have more than one value here because + * it would just overwrite the PWM buffer a couple of times + */ + return -EINVAL; + } + + /* + * the sign is set via a special INSN only, this gives us 8 bits for + * normal operation + * relay sign 0 by default + */ + return usbdux_pwm_pattern(dev, s, CR_CHAN(insn->chanspec), data[0], 0); +} + +static int usbdux_pwm_read(struct comedi_device *x1, + struct comedi_subdevice *x2, struct comedi_insn *x3, + unsigned int *x4) +{ + /* not needed */ + return -EINVAL; +}; + +/* switches on/off PWM */ +static int usbdux_pwm_config(struct comedi_device *dev, + struct comedi_subdevice *s, + struct comedi_insn *insn, unsigned int *data) +{ + struct usbduxsub *this_usbduxsub = dev->private; + switch (data[0]) { + case INSN_CONFIG_ARM: + /* switch it on */ + dev_dbg(&this_usbduxsub->interface->dev, + "comedi%d: %s: pwm on\n", dev->minor, __func__); + /* + * if not zero the PWM is limited to a certain time which is + * not supported here + */ + if (data[1] != 0) + return -EINVAL; + return usbdux_pwm_start(dev, s); + case INSN_CONFIG_DISARM: + dev_dbg(&this_usbduxsub->interface->dev, + "comedi%d: %s: pwm off\n", dev->minor, __func__); + return usbdux_pwm_cancel(dev, s); + case INSN_CONFIG_GET_PWM_STATUS: + /* + * to check if the USB transmission has failed or in case PWM + * was limited to n cycles to check if it has terminated + */ + data[1] = this_usbduxsub->pwm_cmd_running; + return 0; + case INSN_CONFIG_PWM_SET_PERIOD: + dev_dbg(&this_usbduxsub->interface->dev, + "comedi%d: %s: setting period\n", dev->minor, + __func__); + return usbdux_pwm_period(dev, s, data[1]); + case INSN_CONFIG_PWM_GET_PERIOD: + data[1] = this_usbduxsub->pwmPeriod; + return 0; + case INSN_CONFIG_PWM_SET_H_BRIDGE: + /* value in the first byte and the sign in the second for a + relay */ + return usbdux_pwm_pattern(dev, s, + /* the channel number */ + CR_CHAN(insn->chanspec), + /* actual PWM data */ + data[1], + /* just a sign */ + (data[2] != 0)); + case INSN_CONFIG_PWM_GET_H_BRIDGE: + /* values are not kept in this driver, nothing to return */ + return -EINVAL; + } + return -EINVAL; +} + +/* end of PWM */ +/*****************************************************************/ + +static void tidy_up(struct usbduxsub *usbduxsub_tmp) +{ + int i; + + if (!usbduxsub_tmp) + return; + dev_dbg(&usbduxsub_tmp->interface->dev, "comedi_: tiding up\n"); + + /* shows the usb subsystem that the driver is down */ + if (usbduxsub_tmp->interface) + usb_set_intfdata(usbduxsub_tmp->interface, NULL); + + usbduxsub_tmp->probed = 0; + + if (usbduxsub_tmp->urbIn) { + if (usbduxsub_tmp->ai_cmd_running) { + usbduxsub_tmp->ai_cmd_running = 0; + usbduxsub_unlink_InURBs(usbduxsub_tmp); + } + for (i = 0; i < usbduxsub_tmp->numOfInBuffers; i++) { + kfree(usbduxsub_tmp->urbIn[i]->transfer_buffer); + usbduxsub_tmp->urbIn[i]->transfer_buffer = NULL; + usb_kill_urb(usbduxsub_tmp->urbIn[i]); + usb_free_urb(usbduxsub_tmp->urbIn[i]); + usbduxsub_tmp->urbIn[i] = NULL; + } + kfree(usbduxsub_tmp->urbIn); + usbduxsub_tmp->urbIn = NULL; + } + if (usbduxsub_tmp->urbOut) { + if (usbduxsub_tmp->ao_cmd_running) { + usbduxsub_tmp->ao_cmd_running = 0; + usbduxsub_unlink_OutURBs(usbduxsub_tmp); + } + for (i = 0; i < usbduxsub_tmp->numOfOutBuffers; i++) { + if (usbduxsub_tmp->urbOut[i]->transfer_buffer) { + kfree(usbduxsub_tmp-> + urbOut[i]->transfer_buffer); + usbduxsub_tmp->urbOut[i]->transfer_buffer = + NULL; + } + if (usbduxsub_tmp->urbOut[i]) { + usb_kill_urb(usbduxsub_tmp->urbOut[i]); + usb_free_urb(usbduxsub_tmp->urbOut[i]); + usbduxsub_tmp->urbOut[i] = NULL; + } + } + kfree(usbduxsub_tmp->urbOut); + usbduxsub_tmp->urbOut = NULL; + } + if (usbduxsub_tmp->urbPwm) { + if (usbduxsub_tmp->pwm_cmd_running) { + usbduxsub_tmp->pwm_cmd_running = 0; + usbduxsub_unlink_PwmURBs(usbduxsub_tmp); + } + kfree(usbduxsub_tmp->urbPwm->transfer_buffer); + usbduxsub_tmp->urbPwm->transfer_buffer = NULL; + usb_kill_urb(usbduxsub_tmp->urbPwm); + usb_free_urb(usbduxsub_tmp->urbPwm); + usbduxsub_tmp->urbPwm = NULL; + } + kfree(usbduxsub_tmp->inBuffer); + usbduxsub_tmp->inBuffer = NULL; + kfree(usbduxsub_tmp->insnBuffer); + usbduxsub_tmp->insnBuffer = NULL; + kfree(usbduxsub_tmp->outBuffer); + usbduxsub_tmp->outBuffer = NULL; + kfree(usbduxsub_tmp->dac_commands); + usbduxsub_tmp->dac_commands = NULL; + kfree(usbduxsub_tmp->dux_commands); + usbduxsub_tmp->dux_commands = NULL; + usbduxsub_tmp->ai_cmd_running = 0; + usbduxsub_tmp->ao_cmd_running = 0; + usbduxsub_tmp->pwm_cmd_running = 0; +} + +static void usbdux_firmware_request_complete_handler(const struct firmware *fw, + void *context) +{ + struct usbduxsub *usbduxsub_tmp = context; + struct usb_device *usbdev = usbduxsub_tmp->usbdev; + int ret; + + if (fw == NULL) { + dev_err(&usbdev->dev, + "Firmware complete handler without firmware!\n"); + return; + } + + /* + * we need to upload the firmware here because fw will be + * freed once we've left this function + */ + ret = firmwareUpload(usbduxsub_tmp, fw->data, fw->size); + + if (ret) { + dev_err(&usbdev->dev, + "Could not upload firmware (err=%d)\n", ret); + goto out; + } + comedi_usb_auto_config(usbdev, BOARDNAME); +out: + release_firmware(fw); +} + +/* allocate memory for the urbs and initialise them */ +static int usbduxsigma_probe(struct usb_interface *uinterf, + const struct usb_device_id *id) +{ + struct usb_device *udev = interface_to_usbdev(uinterf); + struct device *dev = &uinterf->dev; + int i; + int index; + int ret; + + dev_dbg(dev, "comedi_: usbdux_: " + "finding a free structure for the usb-device\n"); + + down(&start_stop_sem); + /* look for a free place in the usbdux array */ + index = -1; + for (i = 0; i < NUMUSBDUX; i++) { + if (!(usbduxsub[i].probed)) { + index = i; + break; + } + } + + /* no more space */ + if (index == -1) { + dev_err(dev, "Too many usbduxsigma-devices connected.\n"); + up(&start_stop_sem); + return -EMFILE; + } + dev_dbg(dev, "comedi_: usbdux: " + "usbduxsub[%d] is ready to connect to comedi.\n", index); + + sema_init(&(usbduxsub[index].sem), 1); + /* save a pointer to the usb device */ + usbduxsub[index].usbdev = udev; + + /* save the interface itself */ + usbduxsub[index].interface = uinterf; + /* get the interface number from the interface */ + usbduxsub[index].ifnum = uinterf->altsetting->desc.bInterfaceNumber; + /* hand the private data over to the usb subsystem */ + /* will be needed for disconnect */ + usb_set_intfdata(uinterf, &(usbduxsub[index])); + + dev_dbg(dev, "comedi_: usbdux: ifnum=%d\n", usbduxsub[index].ifnum); + + /* test if it is high speed (USB 2.0) */ + usbduxsub[index].high_speed = + (usbduxsub[index].usbdev->speed == USB_SPEED_HIGH); + + /* create space for the commands of the DA converter */ + usbduxsub[index].dac_commands = kzalloc(NUMOUTCHANNELS, GFP_KERNEL); + if (!usbduxsub[index].dac_commands) { + dev_err(dev, "comedi_: usbduxsigma: " + "error alloc space for dac commands\n"); + tidy_up(&(usbduxsub[index])); + up(&start_stop_sem); + return -ENOMEM; + } + /* create space for the commands going to the usb device */ + usbduxsub[index].dux_commands = kzalloc(SIZEOFDUXBUFFER, GFP_KERNEL); + if (!usbduxsub[index].dux_commands) { + dev_err(dev, "comedi_: usbduxsigma: " + "error alloc space for dux commands\n"); + tidy_up(&(usbduxsub[index])); + up(&start_stop_sem); + return -ENOMEM; + } + /* create space for the in buffer and set it to zero */ + usbduxsub[index].inBuffer = kzalloc(SIZEINBUF, GFP_KERNEL); + if (!(usbduxsub[index].inBuffer)) { + dev_err(dev, "comedi_: usbduxsigma: " + "could not alloc space for inBuffer\n"); + tidy_up(&(usbduxsub[index])); + up(&start_stop_sem); + return -ENOMEM; + } + /* create space of the instruction buffer */ + usbduxsub[index].insnBuffer = kzalloc(SIZEINSNBUF, GFP_KERNEL); + if (!(usbduxsub[index].insnBuffer)) { + dev_err(dev, "comedi_: usbduxsigma: " + "could not alloc space for insnBuffer\n"); + tidy_up(&(usbduxsub[index])); + up(&start_stop_sem); + return -ENOMEM; + } + /* create space for the outbuffer */ + usbduxsub[index].outBuffer = kzalloc(SIZEOUTBUF, GFP_KERNEL); + if (!(usbduxsub[index].outBuffer)) { + dev_err(dev, "comedi_: usbduxsigma: " + "could not alloc space for outBuffer\n"); + tidy_up(&(usbduxsub[index])); + up(&start_stop_sem); + return -ENOMEM; + } + /* setting to alternate setting 3: enabling iso ep and bulk ep. */ + i = usb_set_interface(usbduxsub[index].usbdev, + usbduxsub[index].ifnum, 3); + if (i < 0) { + dev_err(dev, "comedi_: usbduxsigma%d: " + "could not set alternate setting 3 in high speed.\n", + index); + tidy_up(&(usbduxsub[index])); + up(&start_stop_sem); + return -ENODEV; + } + if (usbduxsub[index].high_speed) + usbduxsub[index].numOfInBuffers = NUMOFINBUFFERSHIGH; + else + usbduxsub[index].numOfInBuffers = NUMOFINBUFFERSFULL; + + usbduxsub[index].urbIn = + kzalloc(sizeof(struct urb *) * usbduxsub[index].numOfInBuffers, + GFP_KERNEL); + if (!(usbduxsub[index].urbIn)) { + dev_err(dev, "comedi_: usbduxsigma: " + "Could not alloc. urbIn array\n"); + tidy_up(&(usbduxsub[index])); + up(&start_stop_sem); + return -ENOMEM; + } + for (i = 0; i < usbduxsub[index].numOfInBuffers; i++) { + /* one frame: 1ms */ + usbduxsub[index].urbIn[i] = usb_alloc_urb(1, GFP_KERNEL); + if (usbduxsub[index].urbIn[i] == NULL) { + dev_err(dev, "comedi_: usbduxsigma%d: " + "Could not alloc. urb(%d)\n", index, i); + tidy_up(&(usbduxsub[index])); + up(&start_stop_sem); + return -ENOMEM; + } + usbduxsub[index].urbIn[i]->dev = usbduxsub[index].usbdev; + /* will be filled later with a pointer to the comedi-device */ + /* and ONLY then the urb should be submitted */ + usbduxsub[index].urbIn[i]->context = NULL; + usbduxsub[index].urbIn[i]->pipe = + usb_rcvisocpipe(usbduxsub[index].usbdev, ISOINEP); + usbduxsub[index].urbIn[i]->transfer_flags = URB_ISO_ASAP; + usbduxsub[index].urbIn[i]->transfer_buffer = + kzalloc(SIZEINBUF, GFP_KERNEL); + if (!(usbduxsub[index].urbIn[i]->transfer_buffer)) { + dev_err(dev, "comedi_: usbduxsigma%d: " + "could not alloc. transb.\n", index); + tidy_up(&(usbduxsub[index])); + up(&start_stop_sem); + return -ENOMEM; + } + usbduxsub[index].urbIn[i]->complete = usbduxsub_ai_IsocIrq; + usbduxsub[index].urbIn[i]->number_of_packets = 1; + usbduxsub[index].urbIn[i]->transfer_buffer_length = SIZEINBUF; + usbduxsub[index].urbIn[i]->iso_frame_desc[0].offset = 0; + usbduxsub[index].urbIn[i]->iso_frame_desc[0].length = + SIZEINBUF; + } + + /* out */ + if (usbduxsub[index].high_speed) + usbduxsub[index].numOfOutBuffers = NUMOFOUTBUFFERSHIGH; + else + usbduxsub[index].numOfOutBuffers = NUMOFOUTBUFFERSFULL; + + usbduxsub[index].urbOut = + kzalloc(sizeof(struct urb *) * usbduxsub[index].numOfOutBuffers, + GFP_KERNEL); + if (!(usbduxsub[index].urbOut)) { + dev_err(dev, "comedi_: usbduxsigma: " + "Could not alloc. urbOut array\n"); + tidy_up(&(usbduxsub[index])); + up(&start_stop_sem); + return -ENOMEM; + } + for (i = 0; i < usbduxsub[index].numOfOutBuffers; i++) { + /* one frame: 1ms */ + usbduxsub[index].urbOut[i] = usb_alloc_urb(1, GFP_KERNEL); + if (usbduxsub[index].urbOut[i] == NULL) { + dev_err(dev, "comedi_: usbduxsigma%d: " + "Could not alloc. urb(%d)\n", index, i); + tidy_up(&(usbduxsub[index])); + up(&start_stop_sem); + return -ENOMEM; + } + usbduxsub[index].urbOut[i]->dev = usbduxsub[index].usbdev; + /* will be filled later with a pointer to the comedi-device */ + /* and ONLY then the urb should be submitted */ + usbduxsub[index].urbOut[i]->context = NULL; + usbduxsub[index].urbOut[i]->pipe = + usb_sndisocpipe(usbduxsub[index].usbdev, ISOOUTEP); + usbduxsub[index].urbOut[i]->transfer_flags = URB_ISO_ASAP; + usbduxsub[index].urbOut[i]->transfer_buffer = + kzalloc(SIZEOUTBUF, GFP_KERNEL); + if (!(usbduxsub[index].urbOut[i]->transfer_buffer)) { + dev_err(dev, "comedi_: usbduxsigma%d: " + "could not alloc. transb.\n", index); + tidy_up(&(usbduxsub[index])); + up(&start_stop_sem); + return -ENOMEM; + } + usbduxsub[index].urbOut[i]->complete = usbduxsub_ao_IsocIrq; + usbduxsub[index].urbOut[i]->number_of_packets = 1; + usbduxsub[index].urbOut[i]->transfer_buffer_length = + SIZEOUTBUF; + usbduxsub[index].urbOut[i]->iso_frame_desc[0].offset = 0; + usbduxsub[index].urbOut[i]->iso_frame_desc[0].length = + SIZEOUTBUF; + if (usbduxsub[index].high_speed) { + /* uframes */ + usbduxsub[index].urbOut[i]->interval = 8; + } else { + /* frames */ + usbduxsub[index].urbOut[i]->interval = 1; + } + } + + /* pwm */ + if (usbduxsub[index].high_speed) { + /* max bulk ep size in high speed */ + usbduxsub[index].sizePwmBuf = 512; + usbduxsub[index].urbPwm = usb_alloc_urb(0, GFP_KERNEL); + if (usbduxsub[index].urbPwm == NULL) { + dev_err(dev, "comedi_: usbduxsigma%d: " + "Could not alloc. pwm urb\n", index); + tidy_up(&(usbduxsub[index])); + up(&start_stop_sem); + return -ENOMEM; + } + usbduxsub[index].urbPwm->transfer_buffer = + kzalloc(usbduxsub[index].sizePwmBuf, GFP_KERNEL); + if (!(usbduxsub[index].urbPwm->transfer_buffer)) { + dev_err(dev, "comedi_: usbduxsigma%d: " + "could not alloc. transb. for pwm\n", index); + tidy_up(&(usbduxsub[index])); + up(&start_stop_sem); + return -ENOMEM; + } + } else { + usbduxsub[index].urbPwm = NULL; + usbduxsub[index].sizePwmBuf = 0; + } + + usbduxsub[index].ai_cmd_running = 0; + usbduxsub[index].ao_cmd_running = 0; + usbduxsub[index].pwm_cmd_running = 0; + + /* we've reached the bottom of the function */ + usbduxsub[index].probed = 1; + up(&start_stop_sem); + + ret = request_firmware_nowait(THIS_MODULE, + FW_ACTION_HOTPLUG, + "usbduxsigma_firmware.bin", + &udev->dev, + GFP_KERNEL, + usbduxsub + index, + usbdux_firmware_request_complete_handler + ); + + if (ret) { + dev_err(dev, "Could not load firmware (err=%d)\n", ret); + return ret; + } + + dev_info(dev, "comedi_: successfully initialised.\n"); + /* success */ + return 0; +} + +static void usbduxsigma_disconnect(struct usb_interface *intf) +{ + struct usbduxsub *usbduxsub_tmp = usb_get_intfdata(intf); + struct usb_device *udev = interface_to_usbdev(intf); + + if (!usbduxsub_tmp) { + dev_err(&intf->dev, + "comedi_: disconnect called with null pointer.\n"); + return; + } + if (usbduxsub_tmp->usbdev != udev) { + dev_err(&intf->dev, "comedi_: BUG! wrong ptr!\n"); + return; + } + if (usbduxsub_tmp->ai_cmd_running) + /* we are still running a command */ + usbdux_ai_stop(usbduxsub_tmp, 1); + if (usbduxsub_tmp->ao_cmd_running) + /* we are still running a command */ + usbdux_ao_stop(usbduxsub_tmp, 1); + comedi_usb_auto_unconfig(udev); + down(&start_stop_sem); + down(&usbduxsub_tmp->sem); + tidy_up(usbduxsub_tmp); + up(&usbduxsub_tmp->sem); + up(&start_stop_sem); + dev_info(&intf->dev, "comedi_: disconnected from the usb\n"); +} + +/* is called when comedi-config is called */ +static int usbduxsigma_attach(struct comedi_device *dev, + struct comedi_devconfig *it) +{ + int ret; + int index; + int i; + struct usbduxsub *udev; + + int offset; + + struct comedi_subdevice *s = NULL; + dev->private = NULL; + + down(&start_stop_sem); + /* find a valid device which has been detected by the probe function of + * the usb */ + index = -1; + for (i = 0; i < NUMUSBDUX; i++) { + if ((usbduxsub[i].probed) && (!usbduxsub[i].attached)) { + index = i; + break; + } + } + + if (index < 0) { + printk(KERN_ERR "comedi%d: usbduxsigma: error: attach failed," + "dev not connected to the usb bus.\n", dev->minor); + up(&start_stop_sem); + return -ENODEV; + } + + udev = &usbduxsub[index]; + down(&udev->sem); + /* pointer back to the corresponding comedi device */ + udev->comedidev = dev; + + /* trying to upload the firmware into the FX2 */ + if (comedi_aux_data(it->options, 0) && + it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]) { + firmwareUpload(udev, comedi_aux_data(it->options, 0), + it->options[COMEDI_DEVCONF_AUX_DATA_LENGTH]); + } + + dev->board_name = BOARDNAME; + + /* set number of subdevices */ + if (udev->high_speed) { + /* with pwm */ + dev->n_subdevices = 4; + } else { + /* without pwm */ + dev->n_subdevices = 3; + } + + /* allocate space for the subdevices */ + ret = alloc_subdevices(dev, dev->n_subdevices); + if (ret < 0) { + dev_err(&udev->interface->dev, + "comedi%d: no space for subdev\n", dev->minor); + up(&start_stop_sem); + return ret; + } + + /* private structure is also simply the usb-structure */ + dev->private = udev; + + /* the first subdevice is the A/D converter */ + s = dev->subdevices + SUBDEV_AD; + /* the URBs get the comedi subdevice */ + /* which is responsible for reading */ + /* this is the subdevice which reads data */ + dev->read_subdev = s; + /* the subdevice receives as private structure the */ + /* usb-structure */ + s->private = NULL; + /* analog input */ + s->type = COMEDI_SUBD_AI; + /* readable and ref is to ground, 32 bit wide data! */ + s->subdev_flags = SDF_READABLE | SDF_GROUND | + SDF_CMD_READ | SDF_LSAMPL; + /* 16 A/D channels */ + s->n_chan = NUMCHANNELS; + /* length of the channellist */ + s->len_chanlist = NUMCHANNELS; + /* callback functions */ + s->insn_read = usbdux_ai_insn_read; + s->do_cmdtest = usbdux_ai_cmdtest; + s->do_cmd = usbdux_ai_cmd; + s->cancel = usbdux_ai_cancel; + /* max value from the A/D converter (24bit) */ + s->maxdata = 0x00FFFFFF; + /* range table to convert to physical units */ + s->range_table = (&range_usbdux_ai_range); + + /* analog out */ + s = dev->subdevices + SUBDEV_DA; + /* analog out */ + s->type = COMEDI_SUBD_AO; + /* backward pointer */ + dev->write_subdev = s; + /* the subdevice receives as private structure the */ + /* usb-structure */ + s->private = NULL; + /* are writable */ + s->subdev_flags = SDF_WRITABLE | SDF_GROUND | SDF_CMD_WRITE; + /* 4 channels */ + s->n_chan = 4; + /* length of the channellist */ + s->len_chanlist = 4; + /* 8 bit resolution */ + s->maxdata = 0x00ff; + /* unipolar range */ + s->range_table = (&range_usbdux_ao_range); + /* callback */ + s->do_cmdtest = usbdux_ao_cmdtest; + s->do_cmd = usbdux_ao_cmd; + s->cancel = usbdux_ao_cancel; + s->insn_read = usbdux_ao_insn_read; + s->insn_write = usbdux_ao_insn_write; + + /* digital I/O */ + s = dev->subdevices + SUBDEV_DIO; + s->type = COMEDI_SUBD_DIO; + s->subdev_flags = SDF_READABLE | SDF_WRITABLE; + /* 8 external and 16 internal channels */ + s->n_chan = 24; + s->maxdata = 1; + s->range_table = (&range_digital); + s->insn_bits = usbdux_dio_insn_bits; + s->insn_config = usbdux_dio_insn_config; + /* we don't use it */ + s->private = NULL; + + if (udev->high_speed) { + /* timer / pwm */ + s = dev->subdevices + SUBDEV_PWM; + s->type = COMEDI_SUBD_PWM; + s->subdev_flags = SDF_WRITABLE | SDF_PWM_HBRIDGE; + s->n_chan = 8; + /* this defines the max duty cycle resolution */ + s->maxdata = udev->sizePwmBuf; + s->insn_write = usbdux_pwm_write; + s->insn_read = usbdux_pwm_read; + s->insn_config = usbdux_pwm_config; + usbdux_pwm_period(dev, s, PWM_DEFAULT_PERIOD); + } + /* finally decide that it's attached */ + udev->attached = 1; + + up(&udev->sem); + + up(&start_stop_sem); + + offset = usbdux_getstatusinfo(dev, 0); + if (offset < 0) + dev_err(&udev->interface->dev, + "Communication to USBDUXSIGMA failed!" + "Check firmware and cabling."); + + dev_info(&udev->interface->dev, + "comedi%d: attached, ADC_zero = %x", dev->minor, offset); + + return 0; +} + +static int usbduxsigma_detach(struct comedi_device *dev) +{ + struct usbduxsub *usbduxsub_tmp; + + if (!dev) { + printk(KERN_ERR + "comedi? usbduxsigma detach: dev=NULL\n"); + return -EFAULT; + } + + usbduxsub_tmp = dev->private; + if (!usbduxsub_tmp) { + printk(KERN_ERR + "comedi?: usbduxsigma detach: private=NULL\n"); + return -EFAULT; + } + + dev_dbg(&usbduxsub_tmp->interface->dev, + "comedi%d: detach usb device\n", + dev->minor); + + down(&usbduxsub_tmp->sem); + /* Don't allow detach to free the private structure */ + /* It's one entry of of usbduxsub[] */ + dev->private = NULL; + usbduxsub_tmp->attached = 0; + usbduxsub_tmp->comedidev = NULL; + dev_info(&usbduxsub_tmp->interface->dev, + "comedi%d: successfully detached.\n", dev->minor); + up(&usbduxsub_tmp->sem); + return 0; +} + +/* main driver struct */ +static struct comedi_driver driver_usbduxsigma = { + .driver_name = "usbduxsigma", + .module = THIS_MODULE, + .attach = usbduxsigma_attach, + .detach = usbduxsigma_detach, +}; + +/* Table with the USB-devices */ +static const struct usb_device_id usbduxsigma_table[] = { + {USB_DEVICE(0x13d8, 0x0020)}, + {USB_DEVICE(0x13d8, 0x0021)}, + {USB_DEVICE(0x13d8, 0x0022)}, + {} /* Terminating entry */ +}; + +MODULE_DEVICE_TABLE(usb, usbduxsigma_table); + +/* The usbduxsub-driver */ +static struct usb_driver usbduxsigma_driver = { + .name = BOARDNAME, + .probe = usbduxsigma_probe, + .disconnect = usbduxsigma_disconnect, + .id_table = usbduxsigma_table, +}; + +/* Can't use the nice macro as I have also to initialise the USB */ +/* subsystem: */ +/* registering the usb-system _and_ the comedi-driver */ +static int __init init_usbduxsigma(void) +{ + printk(KERN_INFO KBUILD_MODNAME ": " + DRIVER_VERSION ":" DRIVER_DESC "\n"); + usb_register(&usbduxsigma_driver); + comedi_driver_register(&driver_usbduxsigma); + return 0; +} + +/* deregistering the comedi driver and the usb-subsystem */ +static void __exit exit_usbduxsigma(void) +{ + comedi_driver_unregister(&driver_usbduxsigma); + usb_deregister(&usbduxsigma_driver); +} + +module_init(init_usbduxsigma); +module_exit(exit_usbduxsigma); + +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/cxd2099/Makefile b/drivers/staging/cxd2099/Makefile index 72b1455..64cfc77 100644 --- a/drivers/staging/cxd2099/Makefile +++ b/drivers/staging/cxd2099/Makefile @@ -1,5 +1,5 @@ obj-$(CONFIG_DVB_CXD2099) += cxd2099.o -EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -EXTRA_CFLAGS += -Idrivers/media/dvb/frontends/ -EXTRA_CFLAGS += -Idrivers/media/common/tuners/ +ccflags-y += -Idrivers/media/dvb/dvb-core/ +ccflags-y += -Idrivers/media/dvb/frontends/ +ccflags-y += -Idrivers/media/common/tuners/ diff --git a/drivers/staging/dt3155v4l/dt3155v4l.c b/drivers/staging/dt3155v4l/dt3155v4l.c index 05aa41c..4059ea6 100644 --- a/drivers/staging/dt3155v4l/dt3155v4l.c +++ b/drivers/staging/dt3155v4l/dt3155v4l.c @@ -18,6 +18,7 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ +#include <linux/module.h> #include <linux/version.h> #include <linux/stringify.h> #include <linux/delay.h> diff --git a/drivers/staging/easycap/easycap_ioctl.c b/drivers/staging/easycap/easycap_ioctl.c index 0accab9..91262fb 100644 --- a/drivers/staging/easycap/easycap_ioctl.c +++ b/drivers/staging/easycap/easycap_ioctl.c @@ -1317,17 +1317,12 @@ long easycap_unlocked_ioctl(struct file *file, struct v4l2_control *pv4l2_control; JOM(8, "VIDIOC_G_CTRL\n"); - pv4l2_control = kzalloc(sizeof(struct v4l2_control), GFP_KERNEL); - if (!pv4l2_control) { - SAM("ERROR: out of memory\n"); + pv4l2_control = memdup_user((void __user *)arg, + sizeof(struct v4l2_control)); + if (IS_ERR(pv4l2_control)) { + SAM("ERROR: copy from user failed\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -ENOMEM; - } - if (0 != copy_from_user(pv4l2_control, (void __user *)arg, - sizeof(struct v4l2_control))) { - kfree(pv4l2_control); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; + return PTR_ERR(pv4l2_control); } switch (pv4l2_control->id) { @@ -2356,17 +2351,12 @@ long easycap_unlocked_ioctl(struct file *file, struct v4l2_streamparm *pv4l2_streamparm; JOM(8, "VIDIOC_G_PARM\n"); - pv4l2_streamparm = kzalloc(sizeof(struct v4l2_streamparm), GFP_KERNEL); - if (!pv4l2_streamparm) { - SAM("ERROR: out of memory\n"); - mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -ENOMEM; - } - if (copy_from_user(pv4l2_streamparm, - (void __user *)arg, sizeof(struct v4l2_streamparm))) { - kfree(pv4l2_streamparm); + pv4l2_streamparm = memdup_user((void __user *)arg, + sizeof(struct v4l2_streamparm)); + if (IS_ERR(pv4l2_streamparm)) { + SAM("ERROR: copy from user failed\n"); mutex_unlock(&easycapdc60_dongle[kd].mutex_video); - return -EFAULT; + return PTR_ERR(pv4l2_streamparm); } if (pv4l2_streamparm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { diff --git a/drivers/staging/et131x/et1310_eeprom.c b/drivers/staging/et131x/et1310_eeprom.c index 2375840..e810254 100644 --- a/drivers/staging/et131x/et1310_eeprom.c +++ b/drivers/staging/et131x/et1310_eeprom.c @@ -150,15 +150,15 @@ static int eeprom_wait_ready(struct pci_dev *pdev, u32 *status) /** * eeprom_write - Write a byte to the ET1310's EEPROM - * @etdev: pointer to our private adapter structure + * @adapter: pointer to our private adapter structure * @addr: the address to write * @data: the value to write * * Returns 1 for a successful write. */ -static int eeprom_write(struct et131x_adapter *etdev, u32 addr, u8 data) +static int eeprom_write(struct et131x_adapter *adapter, u32 addr, u8 data) { - struct pci_dev *pdev = etdev->pdev; + struct pci_dev *pdev = adapter->pdev; int index = 0; int retries; int err = 0; @@ -222,7 +222,7 @@ static int eeprom_write(struct et131x_adapter *etdev, u32 addr, u8 data) * 1, this is so we do a blind write for load bug. */ if ((status & LBCIF_STATUS_GENERAL_ERROR) - && etdev->pdev->revision == 0) + && adapter->pdev->revision == 0) break; /* @@ -280,7 +280,7 @@ static int eeprom_write(struct et131x_adapter *etdev, u32 addr, u8 data) /** * eeprom_read - Read a byte from the ET1310's EEPROM - * @etdev: pointer to our private adapter structure + * @adapter: pointer to our private adapter structure * @addr: the address from which to read * @pdata: a pointer to a byte in which to store the value of the read * @eeprom_id: the ID of the EEPROM @@ -288,9 +288,9 @@ static int eeprom_write(struct et131x_adapter *etdev, u32 addr, u8 data) * * Returns 1 for a successful read */ -static int eeprom_read(struct et131x_adapter *etdev, u32 addr, u8 *pdata) +static int eeprom_read(struct et131x_adapter *adapter, u32 addr, u8 *pdata) { - struct pci_dev *pdev = etdev->pdev; + struct pci_dev *pdev = adapter->pdev; int err; u32 status; @@ -337,9 +337,9 @@ static int eeprom_read(struct et131x_adapter *etdev, u32 addr, u8 *pdata) return (status & LBCIF_STATUS_ACK_ERROR) ? -EIO : 0; } -int et131x_init_eeprom(struct et131x_adapter *etdev) +int et131x_init_eeprom(struct et131x_adapter *adapter) { - struct pci_dev *pdev = etdev->pdev; + struct pci_dev *pdev = adapter->pdev; u8 eestatus; /* We first need to check the EEPROM Status code located at offset @@ -374,7 +374,7 @@ int et131x_init_eeprom(struct et131x_adapter *etdev) * corruption seen with 1310 B Silicon */ for (i = 0; i < 3; i++) - if (eeprom_write(etdev, i, eedata[i]) < 0) + if (eeprom_write(adapter, i, eedata[i]) < 0) write_failed = 1; } if (pdev->revision != 0x01 || write_failed) { @@ -387,21 +387,21 @@ int et131x_init_eeprom(struct et131x_adapter *etdev) * gather additional information that normally would * come from the eeprom, like MAC Address */ - etdev->has_eeprom = 0; + adapter->has_eeprom = 0; return -EIO; } } - etdev->has_eeprom = 1; + adapter->has_eeprom = 1; /* Read the EEPROM for information regarding LED behavior. Refer to * ET1310_phy.c, et131x_xcvr_init(), for its use. */ - eeprom_read(etdev, 0x70, &etdev->eeprom_data[0]); - eeprom_read(etdev, 0x71, &etdev->eeprom_data[1]); + eeprom_read(adapter, 0x70, &adapter->eeprom_data[0]); + eeprom_read(adapter, 0x71, &adapter->eeprom_data[1]); - if (etdev->eeprom_data[0] != 0xcd) + if (adapter->eeprom_data[0] != 0xcd) /* Disable all optional features */ - etdev->eeprom_data[1] = 0x00; + adapter->eeprom_data[1] = 0x00; return 0; } diff --git a/drivers/staging/et131x/et1310_mac.c b/drivers/staging/et131x/et1310_mac.c index 656be4b..ab85cb3 100644 --- a/drivers/staging/et131x/et1310_mac.c +++ b/drivers/staging/et131x/et1310_mac.c @@ -99,12 +99,12 @@ #define COUNTER_MASK_12_BIT (COUNTER_WRAP_12_BIT - 1) /** - * ConfigMacRegs1 - Initialize the first part of MAC regs - * @pAdpater: pointer to our adapter structure + * et1310_config_mac_regs1 - Initialize the first part of MAC regs + * @adapter: pointer to our adapter structure */ -void ConfigMACRegs1(struct et131x_adapter *etdev) +void et1310_config_mac_regs1(struct et131x_adapter *adapter) { - struct mac_regs __iomem *pMac = &etdev->regs->mac; + struct mac_regs __iomem *macregs = &adapter->regs->mac; u32 station1; u32 station2; u32 ipg; @@ -112,22 +112,22 @@ void ConfigMACRegs1(struct et131x_adapter *etdev) /* First we need to reset everything. Write to MAC configuration * register 1 to perform reset. */ - writel(0xC00F0000, &pMac->cfg1); + writel(0xC00F0000, ¯egs->cfg1); /* Next lets configure the MAC Inter-packet gap register */ ipg = 0x38005860; /* IPG1 0x38 IPG2 0x58 B2B 0x60 */ ipg |= 0x50 << 8; /* ifg enforce 0x50 */ - writel(ipg, &pMac->ipg); + writel(ipg, ¯egs->ipg); /* Next lets configure the MAC Half Duplex register */ /* BEB trunc 0xA, Ex Defer, Rexmit 0xF Coll 0x37 */ - writel(0x00A1F037, &pMac->hfdp); + writel(0x00A1F037, ¯egs->hfdp); /* Next lets configure the MAC Interface Control register */ - writel(0, &pMac->if_ctrl); + writel(0, ¯egs->if_ctrl); /* Let's move on to setting up the mii management configuration */ - writel(0x07, &pMac->mii_mgmt_cfg); /* Clock reset 0x7 */ + writel(0x07, ¯egs->mii_mgmt_cfg); /* Clock reset 0x7 */ /* Next lets configure the MAC Station Address register. These * values are read from the EEPROM during initialization and stored @@ -136,49 +136,49 @@ void ConfigMACRegs1(struct et131x_adapter *etdev) * station address is used for generating and checking pause control * packets. */ - station2 = (etdev->addr[1] << ET_MAC_STATION_ADDR2_OC2_SHIFT) | - (etdev->addr[0] << ET_MAC_STATION_ADDR2_OC1_SHIFT); - station1 = (etdev->addr[5] << ET_MAC_STATION_ADDR1_OC6_SHIFT) | - (etdev->addr[4] << ET_MAC_STATION_ADDR1_OC5_SHIFT) | - (etdev->addr[3] << ET_MAC_STATION_ADDR1_OC4_SHIFT) | - etdev->addr[2]; - writel(station1, &pMac->station_addr_1); - writel(station2, &pMac->station_addr_2); + station2 = (adapter->addr[1] << ET_MAC_STATION_ADDR2_OC2_SHIFT) | + (adapter->addr[0] << ET_MAC_STATION_ADDR2_OC1_SHIFT); + station1 = (adapter->addr[5] << ET_MAC_STATION_ADDR1_OC6_SHIFT) | + (adapter->addr[4] << ET_MAC_STATION_ADDR1_OC5_SHIFT) | + (adapter->addr[3] << ET_MAC_STATION_ADDR1_OC4_SHIFT) | + adapter->addr[2]; + writel(station1, ¯egs->station_addr_1); + writel(station2, ¯egs->station_addr_2); /* Max ethernet packet in bytes that will passed by the mac without * being truncated. Allow the MAC to pass 4 more than our max packet * size. This is 4 for the Ethernet CRC. * - * Packets larger than (RegistryJumboPacket) that do not contain a + * Packets larger than (registry_jumbo_packet) that do not contain a * VLAN ID will be dropped by the Rx function. */ - writel(etdev->RegistryJumboPacket + 4, &pMac->max_fm_len); + writel(adapter->registry_jumbo_packet + 4, ¯egs->max_fm_len); /* clear out MAC config reset */ - writel(0, &pMac->cfg1); + writel(0, ¯egs->cfg1); } /** - * ConfigMacRegs2 - Initialize the second part of MAC regs - * @pAdpater: pointer to our adapter structure + * et1310_config_mac_regs2 - Initialize the second part of MAC regs + * @adapter: pointer to our adapter structure */ -void ConfigMACRegs2(struct et131x_adapter *etdev) +void et1310_config_mac_regs2(struct et131x_adapter *adapter) { int32_t delay = 0; - struct mac_regs __iomem *pMac = &etdev->regs->mac; + struct mac_regs __iomem *mac = &adapter->regs->mac; u32 cfg1; u32 cfg2; u32 ifctrl; u32 ctl; - ctl = readl(&etdev->regs->txmac.ctl); - cfg1 = readl(&pMac->cfg1); - cfg2 = readl(&pMac->cfg2); - ifctrl = readl(&pMac->if_ctrl); + ctl = readl(&adapter->regs->txmac.ctl); + cfg1 = readl(&mac->cfg1); + cfg2 = readl(&mac->cfg2); + ifctrl = readl(&mac->if_ctrl); /* Set up the if mode bits */ cfg2 &= ~0x300; - if (etdev->linkspeed == TRUEPHY_SPEED_1000MBPS) { + if (adapter->linkspeed == TRUEPHY_SPEED_1000MBPS) { cfg2 |= 0x200; /* Phy mode bit */ ifctrl &= ~(1 << 24); @@ -188,12 +188,12 @@ void ConfigMACRegs2(struct et131x_adapter *etdev) } /* We need to enable Rx/Tx */ - cfg1 |= CFG1_RX_ENABLE|CFG1_TX_ENABLE|CFG1_TX_FLOW; + cfg1 |= CFG1_RX_ENABLE | CFG1_TX_ENABLE | CFG1_TX_FLOW; /* Initialize loop back to off */ - cfg1 &= ~(CFG1_LOOPBACK|CFG1_RX_FLOW); - if (etdev->flowcontrol == FLOW_RXONLY || etdev->flowcontrol == FLOW_BOTH) + cfg1 &= ~(CFG1_LOOPBACK | CFG1_RX_FLOW); + if (adapter->flowcontrol == FLOW_RXONLY || adapter->flowcontrol == FLOW_BOTH) cfg1 |= CFG1_RX_FLOW; - writel(cfg1, &pMac->cfg1); + writel(cfg1, &mac->cfg1); /* Now we need to initialize the MAC Configuration 2 register */ /* preamble 7, check length, huge frame off, pad crc, crc enable @@ -202,118 +202,118 @@ void ConfigMACRegs2(struct et131x_adapter *etdev) cfg2 &= ~0x0021; /* Turn on duplex if needed */ - if (etdev->duplex_mode) + if (adapter->duplex_mode) cfg2 |= 0x01; ifctrl &= ~(1 << 26); - if (!etdev->duplex_mode) + if (!adapter->duplex_mode) ifctrl |= (1<<26); /* Enable ghd */ - writel(ifctrl, &pMac->if_ctrl); - writel(cfg2, &pMac->cfg2); + writel(ifctrl, &mac->if_ctrl); + writel(cfg2, &mac->cfg2); do { udelay(10); delay++; - cfg1 = readl(&pMac->cfg1); + cfg1 = readl(&mac->cfg1); } while ((cfg1 & CFG1_WAIT) != CFG1_WAIT && delay < 100); if (delay == 100) { - dev_warn(&etdev->pdev->dev, + dev_warn(&adapter->pdev->dev, "Syncd bits did not respond correctly cfg1 word 0x%08x\n", cfg1); } - /* Enable TXMAC */ + /* Enable txmac */ ctl |= 0x09; /* TX mac enable, FC disable */ - writel(ctl, &etdev->regs->txmac.ctl); + writel(ctl, &adapter->regs->txmac.ctl); /* Ready to start the RXDMA/TXDMA engine */ - if (etdev->flags & fMP_ADAPTER_LOWER_POWER) { - et131x_rx_dma_enable(etdev); - et131x_tx_dma_enable(etdev); + if (adapter->flags & fMP_ADAPTER_LOWER_POWER) { + et131x_rx_dma_enable(adapter); + et131x_tx_dma_enable(adapter); } } -void ConfigRxMacRegs(struct et131x_adapter *etdev) +void et1310_config_rxmac_regs(struct et131x_adapter *adapter) { - struct rxmac_regs __iomem *pRxMac = &etdev->regs->rxmac; + struct rxmac_regs __iomem *rxmac = &adapter->regs->rxmac; u32 sa_lo; u32 sa_hi = 0; u32 pf_ctrl = 0; /* Disable the MAC while it is being configured (also disable WOL) */ - writel(0x8, &pRxMac->ctrl); + writel(0x8, &rxmac->ctrl); /* Initialize WOL to disabled. */ - writel(0, &pRxMac->crc0); - writel(0, &pRxMac->crc12); - writel(0, &pRxMac->crc34); + writel(0, &rxmac->crc0); + writel(0, &rxmac->crc12); + writel(0, &rxmac->crc34); /* We need to set the WOL mask0 - mask4 next. We initialize it to * its default Values of 0x00000000 because there are not WOL masks * as of this time. */ - writel(0, &pRxMac->mask0_word0); - writel(0, &pRxMac->mask0_word1); - writel(0, &pRxMac->mask0_word2); - writel(0, &pRxMac->mask0_word3); - - writel(0, &pRxMac->mask1_word0); - writel(0, &pRxMac->mask1_word1); - writel(0, &pRxMac->mask1_word2); - writel(0, &pRxMac->mask1_word3); - - writel(0, &pRxMac->mask2_word0); - writel(0, &pRxMac->mask2_word1); - writel(0, &pRxMac->mask2_word2); - writel(0, &pRxMac->mask2_word3); - - writel(0, &pRxMac->mask3_word0); - writel(0, &pRxMac->mask3_word1); - writel(0, &pRxMac->mask3_word2); - writel(0, &pRxMac->mask3_word3); - - writel(0, &pRxMac->mask4_word0); - writel(0, &pRxMac->mask4_word1); - writel(0, &pRxMac->mask4_word2); - writel(0, &pRxMac->mask4_word3); + writel(0, &rxmac->mask0_word0); + writel(0, &rxmac->mask0_word1); + writel(0, &rxmac->mask0_word2); + writel(0, &rxmac->mask0_word3); + + writel(0, &rxmac->mask1_word0); + writel(0, &rxmac->mask1_word1); + writel(0, &rxmac->mask1_word2); + writel(0, &rxmac->mask1_word3); + + writel(0, &rxmac->mask2_word0); + writel(0, &rxmac->mask2_word1); + writel(0, &rxmac->mask2_word2); + writel(0, &rxmac->mask2_word3); + + writel(0, &rxmac->mask3_word0); + writel(0, &rxmac->mask3_word1); + writel(0, &rxmac->mask3_word2); + writel(0, &rxmac->mask3_word3); + + writel(0, &rxmac->mask4_word0); + writel(0, &rxmac->mask4_word1); + writel(0, &rxmac->mask4_word2); + writel(0, &rxmac->mask4_word3); /* Lets setup the WOL Source Address */ - sa_lo = (etdev->addr[2] << ET_WOL_LO_SA3_SHIFT) | - (etdev->addr[3] << ET_WOL_LO_SA4_SHIFT) | - (etdev->addr[4] << ET_WOL_LO_SA5_SHIFT) | - etdev->addr[5]; - writel(sa_lo, &pRxMac->sa_lo); + sa_lo = (adapter->addr[2] << ET_WOL_LO_SA3_SHIFT) | + (adapter->addr[3] << ET_WOL_LO_SA4_SHIFT) | + (adapter->addr[4] << ET_WOL_LO_SA5_SHIFT) | + adapter->addr[5]; + writel(sa_lo, &rxmac->sa_lo); - sa_hi = (u32) (etdev->addr[0] << ET_WOL_HI_SA1_SHIFT) | - etdev->addr[1]; - writel(sa_hi, &pRxMac->sa_hi); + sa_hi = (u32) (adapter->addr[0] << ET_WOL_HI_SA1_SHIFT) | + adapter->addr[1]; + writel(sa_hi, &rxmac->sa_hi); /* Disable all Packet Filtering */ - writel(0, &pRxMac->pf_ctrl); + writel(0, &rxmac->pf_ctrl); /* Let's initialize the Unicast Packet filtering address */ - if (etdev->PacketFilter & ET131X_PACKET_TYPE_DIRECTED) { - SetupDeviceForUnicast(etdev); + if (adapter->packet_filter & ET131X_PACKET_TYPE_DIRECTED) { + et1310_setup_device_for_unicast(adapter); pf_ctrl |= 4; /* Unicast filter */ } else { - writel(0, &pRxMac->uni_pf_addr1); - writel(0, &pRxMac->uni_pf_addr2); - writel(0, &pRxMac->uni_pf_addr3); + writel(0, &rxmac->uni_pf_addr1); + writel(0, &rxmac->uni_pf_addr2); + writel(0, &rxmac->uni_pf_addr3); } /* Let's initialize the Multicast hash */ - if (!(etdev->PacketFilter & ET131X_PACKET_TYPE_ALL_MULTICAST)) { + if (!(adapter->packet_filter & ET131X_PACKET_TYPE_ALL_MULTICAST)) { pf_ctrl |= 2; /* Multicast filter */ - SetupDeviceForMulticast(etdev); + et1310_setup_device_for_multicast(adapter); } /* Runt packet filtering. Didn't work in version A silicon. */ pf_ctrl |= (NIC_MIN_PACKET_SIZE + 4) << 16; pf_ctrl |= 8; /* Fragment filter */ - if (etdev->RegistryJumboPacket > 8192) + if (adapter->registry_jumbo_packet > 8192) /* In order to transmit jumbo packets greater than 8k, the * FIFO between RxMAC and RxDMA needs to be reduced in size * to (16k - Jumbo packet size). In order to implement this, @@ -324,18 +324,18 @@ void ConfigRxMacRegs(struct et131x_adapter *etdev) * * seg_en on, fc_en off, size 0x10 */ - writel(0x41, &pRxMac->mcif_ctrl_max_seg); + writel(0x41, &rxmac->mcif_ctrl_max_seg); else - writel(0, &pRxMac->mcif_ctrl_max_seg); + writel(0, &rxmac->mcif_ctrl_max_seg); /* Initialize the MCIF water marks */ - writel(0, &pRxMac->mcif_water_mark); + writel(0, &rxmac->mcif_water_mark); /* Initialize the MIF control */ - writel(0, &pRxMac->mif_ctrl); + writel(0, &rxmac->mif_ctrl); /* Initialize the Space Available Register */ - writel(0, &pRxMac->space_avail); + writel(0, &rxmac->space_avail); /* Initialize the the mif_ctrl register * bit 3: Receive code error. One or more nibbles were signaled as @@ -350,10 +350,10 @@ void ConfigRxMacRegs(struct et131x_adapter *etdev) * bit 16: Receive frame truncated. * bit 17: Drop packet enable */ - if (etdev->linkspeed == TRUEPHY_SPEED_100MBPS) - writel(0x30038, &pRxMac->mif_ctrl); + if (adapter->linkspeed == TRUEPHY_SPEED_100MBPS) + writel(0x30038, &rxmac->mif_ctrl); else - writel(0x30030, &pRxMac->mif_ctrl); + writel(0x30030, &rxmac->mif_ctrl); /* Finally we initialize RxMac to be enabled & WOL disabled. Packet * filter is always enabled since it is where the runt packets are @@ -361,28 +361,28 @@ void ConfigRxMacRegs(struct et131x_adapter *etdev) * dropping doesn't work, so it is disabled in the pf_ctrl register, * but we still leave the packet filter on. */ - writel(pf_ctrl, &pRxMac->pf_ctrl); - writel(0x9, &pRxMac->ctrl); + writel(pf_ctrl, &rxmac->pf_ctrl); + writel(0x9, &rxmac->ctrl); } -void ConfigTxMacRegs(struct et131x_adapter *etdev) +void et1310_config_txmac_regs(struct et131x_adapter *adapter) { - struct txmac_regs *txmac = &etdev->regs->txmac; + struct txmac_regs *txmac = &adapter->regs->txmac; /* We need to update the Control Frame Parameters * cfpt - control frame pause timer set to 64 (0x40) * cfep - control frame extended pause timer set to 0x0 */ - if (etdev->flowcontrol == FLOW_NONE) + if (adapter->flowcontrol == FLOW_NONE) writel(0, &txmac->cf_param); else writel(0x40, &txmac->cf_param); } -void ConfigMacStatRegs(struct et131x_adapter *etdev) +void et1310_config_macstat_regs(struct et131x_adapter *adapter) { struct macstat_regs __iomem *macstat = - &etdev->regs->macstat; + &adapter->regs->macstat; /* Next we need to initialize all the macstat registers to zero on * the device. @@ -444,78 +444,78 @@ void ConfigMacStatRegs(struct et131x_adapter *etdev) writel(0xFFFE7E8B, &macstat->carry_reg2_mask); } -void ConfigFlowControl(struct et131x_adapter *etdev) +void et1310_config_flow_control(struct et131x_adapter *adapter) { - if (etdev->duplex_mode == 0) { - etdev->flowcontrol = FLOW_NONE; + if (adapter->duplex_mode == 0) { + adapter->flowcontrol = FLOW_NONE; } else { char remote_pause, remote_async_pause; - ET1310_PhyAccessMiBit(etdev, - TRUEPHY_BIT_READ, 5, 10, &remote_pause); - ET1310_PhyAccessMiBit(etdev, - TRUEPHY_BIT_READ, 5, 11, - &remote_async_pause); + et1310_phy_access_mii_bit(adapter, + TRUEPHY_BIT_READ, 5, 10, &remote_pause); + et1310_phy_access_mii_bit(adapter, + TRUEPHY_BIT_READ, 5, 11, + &remote_async_pause); if ((remote_pause == TRUEPHY_BIT_SET) && (remote_async_pause == TRUEPHY_BIT_SET)) { - etdev->flowcontrol = etdev->wanted_flow; + adapter->flowcontrol = adapter->wanted_flow; } else if ((remote_pause == TRUEPHY_BIT_SET) && (remote_async_pause == TRUEPHY_BIT_CLEAR)) { - if (etdev->wanted_flow == FLOW_BOTH) - etdev->flowcontrol = FLOW_BOTH; + if (adapter->wanted_flow == FLOW_BOTH) + adapter->flowcontrol = FLOW_BOTH; else - etdev->flowcontrol = FLOW_NONE; + adapter->flowcontrol = FLOW_NONE; } else if ((remote_pause == TRUEPHY_BIT_CLEAR) && (remote_async_pause == TRUEPHY_BIT_CLEAR)) { - etdev->flowcontrol = FLOW_NONE; + adapter->flowcontrol = FLOW_NONE; } else {/* if (remote_pause == TRUEPHY_CLEAR_BIT && remote_async_pause == TRUEPHY_SET_BIT) */ - if (etdev->wanted_flow == FLOW_BOTH) - etdev->flowcontrol = FLOW_RXONLY; + if (adapter->wanted_flow == FLOW_BOTH) + adapter->flowcontrol = FLOW_RXONLY; else - etdev->flowcontrol = FLOW_NONE; + adapter->flowcontrol = FLOW_NONE; } } } /** - * UpdateMacStatHostCounters - Update the local copy of the statistics - * @etdev: pointer to the adapter structure + * et1310_update_macstat_host_counters - Update the local copy of the statistics + * @adapter: pointer to the adapter structure */ -void UpdateMacStatHostCounters(struct et131x_adapter *etdev) +void et1310_update_macstat_host_counters(struct et131x_adapter *adapter) { - struct ce_stats *stats = &etdev->stats; + struct ce_stats *stats = &adapter->stats; struct macstat_regs __iomem *macstat = - &etdev->regs->macstat; - - stats->collisions += readl(&macstat->tx_total_collisions); - stats->first_collision += readl(&macstat->tx_single_collisions); - stats->tx_deferred += readl(&macstat->tx_deferred); - stats->excessive_collisions += readl(&macstat->tx_multiple_collisions); - stats->late_collisions += readl(&macstat->tx_late_collisions); - stats->tx_uflo += readl(&macstat->tx_undersize_frames); - stats->max_pkt_error += readl(&macstat->tx_oversize_frames); - - stats->alignment_err += readl(&macstat->rx_align_errs); - stats->crc_err += readl(&macstat->rx_code_errs); - stats->norcvbuf += readl(&macstat->rx_drops); - stats->rx_ov_flow += readl(&macstat->rx_oversize_packets); - stats->code_violations += readl(&macstat->rx_fcs_errs); - stats->length_err += readl(&macstat->rx_frame_len_errs); - - stats->other_errors += readl(&macstat->rx_fragment_packets); + &adapter->regs->macstat; + + stats->tx_collisions += readl(&macstat->tx_total_collisions); + stats->tx_first_collisions += readl(&macstat->tx_single_collisions); + stats->tx_deferred += readl(&macstat->tx_deferred); + stats->tx_excessive_collisions += + readl(&macstat->tx_multiple_collisions); + stats->tx_late_collisions += readl(&macstat->tx_late_collisions); + stats->tx_underflows += readl(&macstat->tx_undersize_frames); + stats->tx_max_pkt_errs += readl(&macstat->tx_oversize_frames); + + stats->rx_align_errs += readl(&macstat->rx_align_errs); + stats->rx_crc_errs += readl(&macstat->rx_code_errs); + stats->rcvd_pkts_dropped += readl(&macstat->rx_drops); + stats->rx_overflows += readl(&macstat->rx_oversize_packets); + stats->rx_code_violations += readl(&macstat->rx_fcs_errs); + stats->rx_length_errs += readl(&macstat->rx_frame_len_errs); + stats->rx_other_errs += readl(&macstat->rx_fragment_packets); } /** - * HandleMacStatInterrupt - * @etdev: pointer to the adapter structure + * et1310_handle_macstat_interrupt + * @adapter: pointer to the adapter structure * * One of the MACSTAT counters has wrapped. Update the local copy of * the statistics held in the adapter structure, checking the "wrap" * bit for each counter. */ -void HandleMacStatInterrupt(struct et131x_adapter *etdev) +void et1310_handle_macstat_interrupt(struct et131x_adapter *adapter) { u32 carry_reg1; u32 carry_reg2; @@ -523,11 +523,11 @@ void HandleMacStatInterrupt(struct et131x_adapter *etdev) /* Read the interrupt bits from the register(s). These are Clear On * Write. */ - carry_reg1 = readl(&etdev->regs->macstat.carry_reg1); - carry_reg2 = readl(&etdev->regs->macstat.carry_reg2); + carry_reg1 = readl(&adapter->regs->macstat.carry_reg1); + carry_reg2 = readl(&adapter->regs->macstat.carry_reg2); - writel(carry_reg2, &etdev->regs->macstat.carry_reg1); - writel(carry_reg2, &etdev->regs->macstat.carry_reg2); + writel(carry_reg1, &adapter->regs->macstat.carry_reg1); + writel(carry_reg2, &adapter->regs->macstat.carry_reg2); /* We need to do update the host copy of all the MAC_STAT counters. * For each counter, check it's overflow bit. If the overflow bit is @@ -536,38 +536,38 @@ void HandleMacStatInterrupt(struct et131x_adapter *etdev) * block indicates that one of the counters has wrapped. */ if (carry_reg1 & (1 << 14)) - etdev->stats.code_violations += COUNTER_WRAP_16_BIT; + adapter->stats.rx_code_violations += COUNTER_WRAP_16_BIT; if (carry_reg1 & (1 << 8)) - etdev->stats.alignment_err += COUNTER_WRAP_12_BIT; + adapter->stats.rx_align_errs += COUNTER_WRAP_12_BIT; if (carry_reg1 & (1 << 7)) - etdev->stats.length_err += COUNTER_WRAP_16_BIT; + adapter->stats.rx_length_errs += COUNTER_WRAP_16_BIT; if (carry_reg1 & (1 << 2)) - etdev->stats.other_errors += COUNTER_WRAP_16_BIT; + adapter->stats.rx_other_errs += COUNTER_WRAP_16_BIT; if (carry_reg1 & (1 << 6)) - etdev->stats.crc_err += COUNTER_WRAP_16_BIT; + adapter->stats.rx_crc_errs += COUNTER_WRAP_16_BIT; if (carry_reg1 & (1 << 3)) - etdev->stats.rx_ov_flow += COUNTER_WRAP_16_BIT; + adapter->stats.rx_overflows += COUNTER_WRAP_16_BIT; if (carry_reg1 & (1 << 0)) - etdev->stats.norcvbuf += COUNTER_WRAP_16_BIT; + adapter->stats.rcvd_pkts_dropped += COUNTER_WRAP_16_BIT; if (carry_reg2 & (1 << 16)) - etdev->stats.max_pkt_error += COUNTER_WRAP_12_BIT; + adapter->stats.tx_max_pkt_errs += COUNTER_WRAP_12_BIT; if (carry_reg2 & (1 << 15)) - etdev->stats.tx_uflo += COUNTER_WRAP_12_BIT; + adapter->stats.tx_underflows += COUNTER_WRAP_12_BIT; if (carry_reg2 & (1 << 6)) - etdev->stats.first_collision += COUNTER_WRAP_12_BIT; + adapter->stats.tx_first_collisions += COUNTER_WRAP_12_BIT; if (carry_reg2 & (1 << 8)) - etdev->stats.tx_deferred += COUNTER_WRAP_12_BIT; + adapter->stats.tx_deferred += COUNTER_WRAP_12_BIT; if (carry_reg2 & (1 << 5)) - etdev->stats.excessive_collisions += COUNTER_WRAP_12_BIT; + adapter->stats.tx_excessive_collisions += COUNTER_WRAP_12_BIT; if (carry_reg2 & (1 << 4)) - etdev->stats.late_collisions += COUNTER_WRAP_12_BIT; + adapter->stats.tx_late_collisions += COUNTER_WRAP_12_BIT; if (carry_reg2 & (1 << 2)) - etdev->stats.collisions += COUNTER_WRAP_12_BIT; + adapter->stats.tx_collisions += COUNTER_WRAP_12_BIT; } -void SetupDeviceForMulticast(struct et131x_adapter *etdev) +void et1310_setup_device_for_multicast(struct et131x_adapter *adapter) { - struct rxmac_regs __iomem *rxmac = &etdev->regs->rxmac; + struct rxmac_regs __iomem *rxmac = &adapter->regs->rxmac; uint32_t nIndex; uint32_t result; uint32_t hash1 = 0; @@ -581,10 +581,11 @@ void SetupDeviceForMulticast(struct et131x_adapter *etdev) * specified) then we should pass NO multi-cast addresses to the * driver. */ - if (etdev->PacketFilter & ET131X_PACKET_TYPE_MULTICAST) { + if (adapter->packet_filter & ET131X_PACKET_TYPE_MULTICAST) { /* Loop through our multicast array and set up the device */ - for (nIndex = 0; nIndex < etdev->MCAddressCount; nIndex++) { - result = ether_crc(6, etdev->MCList[nIndex]); + for (nIndex = 0; nIndex < adapter->multicast_addr_count; + nIndex++) { + result = ether_crc(6, adapter->multicast_list[nIndex]); result = (result & 0x3F800000) >> 23; @@ -604,7 +605,7 @@ void SetupDeviceForMulticast(struct et131x_adapter *etdev) } /* Write out the new hash to the device */ - pm_csr = readl(&etdev->regs->global.pm_csr); + pm_csr = readl(&adapter->regs->global.pm_csr); if ((pm_csr & ET_PM_PHY_SW_COMA) == 0) { writel(hash1, &rxmac->multi_hash1); writel(hash2, &rxmac->multi_hash2); @@ -613,9 +614,9 @@ void SetupDeviceForMulticast(struct et131x_adapter *etdev) } } -void SetupDeviceForUnicast(struct et131x_adapter *etdev) +void et1310_setup_device_for_unicast(struct et131x_adapter *adapter) { - struct rxmac_regs __iomem *rxmac = &etdev->regs->rxmac; + struct rxmac_regs __iomem *rxmac = &adapter->regs->rxmac; u32 uni_pf1; u32 uni_pf2; u32 uni_pf3; @@ -630,22 +631,22 @@ void SetupDeviceForUnicast(struct et131x_adapter *etdev) * Set up unicast packet filter reg 3 to be the octets 2 - 5 of the * MAC address for first address */ - uni_pf3 = (etdev->addr[0] << ET_UNI_PF_ADDR2_1_SHIFT) | - (etdev->addr[1] << ET_UNI_PF_ADDR2_2_SHIFT) | - (etdev->addr[0] << ET_UNI_PF_ADDR1_1_SHIFT) | - etdev->addr[1]; - - uni_pf2 = (etdev->addr[2] << ET_UNI_PF_ADDR2_3_SHIFT) | - (etdev->addr[3] << ET_UNI_PF_ADDR2_4_SHIFT) | - (etdev->addr[4] << ET_UNI_PF_ADDR2_5_SHIFT) | - etdev->addr[5]; - - uni_pf1 = (etdev->addr[2] << ET_UNI_PF_ADDR1_3_SHIFT) | - (etdev->addr[3] << ET_UNI_PF_ADDR1_4_SHIFT) | - (etdev->addr[4] << ET_UNI_PF_ADDR1_5_SHIFT) | - etdev->addr[5]; - - pm_csr = readl(&etdev->regs->global.pm_csr); + uni_pf3 = (adapter->addr[0] << ET_UNI_PF_ADDR2_1_SHIFT) | + (adapter->addr[1] << ET_UNI_PF_ADDR2_2_SHIFT) | + (adapter->addr[0] << ET_UNI_PF_ADDR1_1_SHIFT) | + adapter->addr[1]; + + uni_pf2 = (adapter->addr[2] << ET_UNI_PF_ADDR2_3_SHIFT) | + (adapter->addr[3] << ET_UNI_PF_ADDR2_4_SHIFT) | + (adapter->addr[4] << ET_UNI_PF_ADDR2_5_SHIFT) | + adapter->addr[5]; + + uni_pf1 = (adapter->addr[2] << ET_UNI_PF_ADDR1_3_SHIFT) | + (adapter->addr[3] << ET_UNI_PF_ADDR1_4_SHIFT) | + (adapter->addr[4] << ET_UNI_PF_ADDR1_5_SHIFT) | + adapter->addr[5]; + + pm_csr = readl(&adapter->regs->global.pm_csr); if ((pm_csr & ET_PM_PHY_SW_COMA) == 0) { writel(uni_pf1, &rxmac->uni_pf_addr1); writel(uni_pf2, &rxmac->uni_pf_addr2); diff --git a/drivers/staging/et131x/et1310_phy.c b/drivers/staging/et131x/et1310_phy.c index 0bcb7fb..c845c27 100644 --- a/drivers/staging/et131x/et1310_phy.c +++ b/drivers/staging/et131x/et1310_phy.c @@ -93,39 +93,36 @@ #include "et131x.h" -/* Prototypes for functions with local scope */ -static void et131x_xcvr_init(struct et131x_adapter *etdev); - /** - * PhyMiRead - Read from the PHY through the MII Interface on the MAC - * @etdev: pointer to our private adapter structure - * @xcvrAddr: the address of the transceiver - * @xcvrReg: the register to read + * et131x_phy_mii_read - Read from the PHY through the MII Interface on the MAC + * @adapter: pointer to our private adapter structure + * @xcvr_addr: the address of the transceiver + * @xcvr_reg: the register to read * @value: pointer to a 16-bit value in which the value will be stored * * Returns 0 on success, errno on failure (as defined in errno.h) */ -int PhyMiRead(struct et131x_adapter *etdev, u8 xcvrAddr, - u8 xcvrReg, u16 *value) +int et131x_phy_mii_read(struct et131x_adapter *adapter, u8 xcvr_addr, + u8 xcvr_reg, u16 *value) { - struct mac_regs __iomem *mac = &etdev->regs->mac; + struct mac_regs __iomem *mac = &adapter->regs->mac; int status = 0; u32 delay; - u32 miiAddr; - u32 miiCmd; - u32 miiIndicator; + u32 mii_addr; + u32 mii_cmd; + u32 mii_indicator; /* Save a local copy of the registers we are dealing with so we can * set them back */ - miiAddr = readl(&mac->mii_mgmt_addr); - miiCmd = readl(&mac->mii_mgmt_cmd); + mii_addr = readl(&mac->mii_mgmt_addr); + mii_cmd = readl(&mac->mii_mgmt_cmd); /* Stop the current operation */ writel(0, &mac->mii_mgmt_cmd); /* Set up the register we need to read from on the correct PHY */ - writel(MII_ADDR(xcvrAddr, xcvrReg), &mac->mii_mgmt_addr); + writel(MII_ADDR(xcvr_addr, xcvr_reg), &mac->mii_mgmt_addr); /* Kick the read cycle off */ delay = 0; @@ -135,15 +132,15 @@ int PhyMiRead(struct et131x_adapter *etdev, u8 xcvrAddr, do { udelay(50); delay++; - miiIndicator = readl(&mac->mii_mgmt_indicator); - } while ((miiIndicator & MGMT_WAIT) && delay < 50); + mii_indicator = readl(&mac->mii_mgmt_indicator); + } while ((mii_indicator & MGMT_WAIT) && delay < 50); /* If we hit the max delay, we could not read the register */ if (delay == 50) { - dev_warn(&etdev->pdev->dev, - "xcvrReg 0x%08x could not be read\n", xcvrReg); - dev_warn(&etdev->pdev->dev, "status is 0x%08x\n", - miiIndicator); + dev_warn(&adapter->pdev->dev, + "xcvrReg 0x%08x could not be read\n", xcvr_reg); + dev_warn(&adapter->pdev->dev, "status is 0x%08x\n", + mii_indicator); status = -EIO; } @@ -158,43 +155,43 @@ int PhyMiRead(struct et131x_adapter *etdev, u8 xcvrAddr, /* set the registers we touched back to the state at which we entered * this function */ - writel(miiAddr, &mac->mii_mgmt_addr); - writel(miiCmd, &mac->mii_mgmt_cmd); + writel(mii_addr, &mac->mii_mgmt_addr); + writel(mii_cmd, &mac->mii_mgmt_cmd); return status; } /** - * MiWrite - Write to a PHY register through the MII interface of the MAC - * @etdev: pointer to our private adapter structure - * @xcvrReg: the register to read + * et131x_mii_write - Write to a PHY register through the MII interface of the MAC + * @adapter: pointer to our private adapter structure + * @xcvr_reg: the register to read * @value: 16-bit value to write * * FIXME: one caller in netdev still * * Return 0 on success, errno on failure (as defined in errno.h) */ -int MiWrite(struct et131x_adapter *etdev, u8 xcvrReg, u16 value) +int et131x_mii_write(struct et131x_adapter *adapter, u8 xcvr_reg, u16 value) { - struct mac_regs __iomem *mac = &etdev->regs->mac; + struct mac_regs __iomem *mac = &adapter->regs->mac; int status = 0; - u8 xcvrAddr = etdev->stats.xcvr_addr; + u8 xcvr_addr = adapter->stats.xcvr_addr; u32 delay; - u32 miiAddr; - u32 miiCmd; - u32 miiIndicator; + u32 mii_addr; + u32 mii_cmd; + u32 mii_indicator; /* Save a local copy of the registers we are dealing with so we can * set them back */ - miiAddr = readl(&mac->mii_mgmt_addr); - miiCmd = readl(&mac->mii_mgmt_cmd); + mii_addr = readl(&mac->mii_mgmt_addr); + mii_cmd = readl(&mac->mii_mgmt_cmd); /* Stop the current operation */ writel(0, &mac->mii_mgmt_cmd); /* Set up the register we need to write to on the correct PHY */ - writel(MII_ADDR(xcvrAddr, xcvrReg), &mac->mii_mgmt_addr); + writel(MII_ADDR(xcvr_addr, xcvr_reg), &mac->mii_mgmt_addr); /* Add the value to write to the registers to the mac */ writel(value, &mac->mii_mgmt_ctrl); @@ -203,43 +200,44 @@ int MiWrite(struct et131x_adapter *etdev, u8 xcvrReg, u16 value) do { udelay(50); delay++; - miiIndicator = readl(&mac->mii_mgmt_indicator); - } while ((miiIndicator & MGMT_BUSY) && delay < 100); + mii_indicator = readl(&mac->mii_mgmt_indicator); + } while ((mii_indicator & MGMT_BUSY) && delay < 100); /* If we hit the max delay, we could not write the register */ if (delay == 100) { - u16 TempValue; + u16 tmp; - dev_warn(&etdev->pdev->dev, - "xcvrReg 0x%08x could not be written", xcvrReg); - dev_warn(&etdev->pdev->dev, "status is 0x%08x\n", - miiIndicator); - dev_warn(&etdev->pdev->dev, "command is 0x%08x\n", + dev_warn(&adapter->pdev->dev, + "xcvrReg 0x%08x could not be written", xcvr_reg); + dev_warn(&adapter->pdev->dev, "status is 0x%08x\n", + mii_indicator); + dev_warn(&adapter->pdev->dev, "command is 0x%08x\n", readl(&mac->mii_mgmt_cmd)); - MiRead(etdev, xcvrReg, &TempValue); + et131x_mii_read(adapter, xcvr_reg, &tmp); status = -EIO; } /* Stop the write operation */ writel(0, &mac->mii_mgmt_cmd); - /* set the registers we touched back to the state at which we entered + /* + * set the registers we touched back to the state at which we entered * this function */ - writel(miiAddr, &mac->mii_mgmt_addr); - writel(miiCmd, &mac->mii_mgmt_cmd); + writel(mii_addr, &mac->mii_mgmt_addr); + writel(mii_cmd, &mac->mii_mgmt_cmd); return status; } /** * et131x_xcvr_find - Find the PHY ID - * @etdev: pointer to our private adapter structure + * @adapter: pointer to our private adapter structure * * Returns 0 on success, errno on failure (as defined in errno.h) */ -int et131x_xcvr_find(struct et131x_adapter *etdev) +int et131x_xcvr_find(struct et131x_adapter *adapter) { u8 xcvr_addr; u16 idr1; @@ -249,32 +247,32 @@ int et131x_xcvr_find(struct et131x_adapter *etdev) /* We need to get xcvr id and address we just get the first one */ for (xcvr_addr = 0; xcvr_addr < 32; xcvr_addr++) { /* Read the ID from the PHY */ - PhyMiRead(etdev, xcvr_addr, - (u8) offsetof(struct mi_regs, idr1), - &idr1); - PhyMiRead(etdev, xcvr_addr, - (u8) offsetof(struct mi_regs, idr2), - &idr2); + et131x_phy_mii_read(adapter, xcvr_addr, + (u8) offsetof(struct mi_regs, idr1), + &idr1); + et131x_phy_mii_read(adapter, xcvr_addr, + (u8) offsetof(struct mi_regs, idr2), + &idr2); xcvr_id = (u32) ((idr1 << 16) | idr2); if (idr1 != 0 && idr1 != 0xffff) { - etdev->stats.xcvr_id = xcvr_id; - etdev->stats.xcvr_addr = xcvr_addr; + adapter->stats.xcvr_id = xcvr_id; + adapter->stats.xcvr_addr = xcvr_addr; return 0; } } return -ENODEV; } -void ET1310_PhyReset(struct et131x_adapter *etdev) +void et1310_phy_reset(struct et131x_adapter *adapter) { - MiWrite(etdev, PHY_CONTROL, 0x8000); + et131x_mii_write(adapter, PHY_CONTROL, 0x8000); } /** - * ET1310_PhyPowerDown - PHY power control - * @etdev: device to control + * et1310_phy_power_down - PHY power control + * @adapter: device to control * @down: true for off/false for back on * * one hundred, ten, one thousand megs @@ -282,81 +280,77 @@ void ET1310_PhyReset(struct et131x_adapter *etdev) * Can't you see that this code processed * Phy power, phy power.. */ - -void ET1310_PhyPowerDown(struct et131x_adapter *etdev, bool down) +void et1310_phy_power_down(struct et131x_adapter *adapter, bool down) { u16 data; - MiRead(etdev, PHY_CONTROL, &data); + et131x_mii_read(adapter, PHY_CONTROL, &data); data &= ~0x0800; /* Power UP */ if (down) /* Power DOWN */ data |= 0x0800; - MiWrite(etdev, PHY_CONTROL, data); + et131x_mii_write(adapter, PHY_CONTROL, data); } /** - * ET130_PhyAutoNEg - autonegotiate control - * @etdev: device to control + * et1310_phy_auto_neg - autonegotiate control + * @adapter: device to control * @enabe: autoneg on/off * * Set up the autonegotiation state according to whether we will be * negotiating the state or forcing a speed. */ - -static void ET1310_PhyAutoNeg(struct et131x_adapter *etdev, bool enable) +static void et1310_phy_auto_neg(struct et131x_adapter *adapter, bool enable) { u16 data; - MiRead(etdev, PHY_CONTROL, &data); + et131x_mii_read(adapter, PHY_CONTROL, &data); data &= ~0x1000; /* Autonegotiation OFF */ if (enable) data |= 0x1000; /* Autonegotiation ON */ - MiWrite(etdev, PHY_CONTROL, data); + et131x_mii_write(adapter, PHY_CONTROL, data); } /** - * ET130_PhyDuplexMode - duplex control - * @etdev: device to control + * et1310_phy_duplex_mode - duplex control + * @adapter: device to control * @duplex: duplex on/off * * Set up the duplex state on the PHY */ - -static void ET1310_PhyDuplexMode(struct et131x_adapter *etdev, u16 duplex) +static void et1310_phy_duplex_mode(struct et131x_adapter *adapter, u16 duplex) { u16 data; - MiRead(etdev, PHY_CONTROL, &data); + et131x_mii_read(adapter, PHY_CONTROL, &data); data &= ~0x100; /* Set Half Duplex */ if (duplex == TRUEPHY_DUPLEX_FULL) data |= 0x100; /* Set Full Duplex */ - MiWrite(etdev, PHY_CONTROL, data); + et131x_mii_write(adapter, PHY_CONTROL, data); } /** - * ET130_PhySpeedSelect - speed control - * @etdev: device to control + * et1310_phy_speed_select - speed control + * @adapter: device to control * @duplex: duplex on/off * * Set the speed of our PHY. */ - -static void ET1310_PhySpeedSelect(struct et131x_adapter *etdev, u16 speed) +static void et1310_phy_speed_select(struct et131x_adapter *adapter, u16 speed) { u16 data; static const u16 bits[3] = {0x0000, 0x2000, 0x0040}; /* Read the PHY control register */ - MiRead(etdev, PHY_CONTROL, &data); + et131x_mii_read(adapter, PHY_CONTROL, &data); /* Clear all Speed settings (Bits 6, 13) */ data &= ~0x2040; /* Write back the new speed */ - MiWrite(etdev, PHY_CONTROL, data | bits[speed]); + et131x_mii_write(adapter, PHY_CONTROL, data | bits[speed]); } /** - * ET1310_PhyLinkStatus - read link state - * @etdev: device to read + * et1310_phy_link_status - read link state + * @adapter: device to read * @link_status: reported link state * @autoneg: reported autonegotiation state (complete/incomplete/disabled) * @linkspeed: returnedlink speed in use @@ -370,8 +364,7 @@ static void ET1310_PhySpeedSelect(struct et131x_adapter *etdev, u16 speed) * I know your link speed * I see all the setting that you'd rather keep */ - -static void ET1310_PhyLinkStatus(struct et131x_adapter *etdev, +static void et1310_phy_link_status(struct et131x_adapter *adapter, u8 *link_status, u32 *autoneg, u32 *linkspeed, @@ -384,10 +377,10 @@ static void ET1310_PhyLinkStatus(struct et131x_adapter *etdev, u16 vmi_phystatus = 0; u16 control = 0; - MiRead(etdev, PHY_STATUS, &mistatus); - MiRead(etdev, PHY_1000_STATUS, &is1000BaseT); - MiRead(etdev, PHY_PHY_STATUS, &vmi_phystatus); - MiRead(etdev, PHY_CONTROL, &control); + et131x_mii_read(adapter, PHY_STATUS, &mistatus); + et131x_mii_read(adapter, PHY_1000_STATUS, &is1000BaseT); + et131x_mii_read(adapter, PHY_PHY_STATUS, &vmi_phystatus); + et131x_mii_read(adapter, PHY_CONTROL, &control); *link_status = (vmi_phystatus & 0x0040) ? 1 : 0; *autoneg = (control & 0x1000) ? ((vmi_phystatus & 0x0020) ? @@ -405,26 +398,26 @@ static void ET1310_PhyLinkStatus(struct et131x_adapter *etdev, TRUEPHY_POLARITY_INVERTED : TRUEPHY_POLARITY_NORMAL; } -static void ET1310_PhyAndOrReg(struct et131x_adapter *etdev, - u16 regnum, u16 andMask, u16 orMask) +static void et1310_phy_and_or_reg(struct et131x_adapter *adapter, + u16 regnum, u16 and_mask, u16 or_mask) { u16 reg; - MiRead(etdev, regnum, ®); - reg &= andMask; - reg |= orMask; - MiWrite(etdev, regnum, reg); + et131x_mii_read(adapter, regnum, ®); + reg &= and_mask; + reg |= or_mask; + et131x_mii_write(adapter, regnum, reg); } -/* Still used from _mac for BIT_READ */ -void ET1310_PhyAccessMiBit(struct et131x_adapter *etdev, u16 action, - u16 regnum, u16 bitnum, u8 *value) +/* Still used from _mac for BIT_READ */ +void et1310_phy_access_mii_bit(struct et131x_adapter *adapter, u16 action, + u16 regnum, u16 bitnum, u8 *value) { u16 reg; u16 mask = 0x0001 << bitnum; /* Read the requested register */ - MiRead(etdev, regnum, ®); + et131x_mii_read(adapter, regnum, ®); switch (action) { case TRUEPHY_BIT_READ: @@ -432,11 +425,11 @@ void ET1310_PhyAccessMiBit(struct et131x_adapter *etdev, u16 action, break; case TRUEPHY_BIT_SET: - MiWrite(etdev, regnum, reg | mask); + et131x_mii_write(adapter, regnum, reg | mask); break; case TRUEPHY_BIT_CLEAR: - MiWrite(etdev, regnum, reg & ~mask); + et131x_mii_write(adapter, regnum, reg & ~mask); break; default: @@ -444,13 +437,13 @@ void ET1310_PhyAccessMiBit(struct et131x_adapter *etdev, u16 action, } } -void ET1310_PhyAdvertise1000BaseT(struct et131x_adapter *etdev, +void et1310_phy_advertise_1000BaseT(struct et131x_adapter *adapter, u16 duplex) { u16 data; /* Read the PHY 1000 Base-T Control Register */ - MiRead(etdev, PHY_1000_CONTROL, &data); + et131x_mii_read(adapter, PHY_1000_CONTROL, &data); /* Clear Bits 8,9 */ data &= ~0x0300; @@ -477,16 +470,16 @@ void ET1310_PhyAdvertise1000BaseT(struct et131x_adapter *etdev, } /* Write back advertisement */ - MiWrite(etdev, PHY_1000_CONTROL, data); + et131x_mii_write(adapter, PHY_1000_CONTROL, data); } -static void ET1310_PhyAdvertise100BaseT(struct et131x_adapter *etdev, - u16 duplex) +static void et1310_phy_advertise_100BaseT(struct et131x_adapter *adapter, + u16 duplex) { u16 data; /* Read the Autonegotiation Register (10/100) */ - MiRead(etdev, PHY_AUTO_ADVERTISEMENT, &data); + et131x_mii_read(adapter, PHY_AUTO_ADVERTISEMENT, &data); /* Clear bits 7,8 */ data &= ~0x0180; @@ -514,16 +507,16 @@ static void ET1310_PhyAdvertise100BaseT(struct et131x_adapter *etdev, } /* Write back advertisement */ - MiWrite(etdev, PHY_AUTO_ADVERTISEMENT, data); + et131x_mii_write(adapter, PHY_AUTO_ADVERTISEMENT, data); } -static void ET1310_PhyAdvertise10BaseT(struct et131x_adapter *etdev, +static void et1310_phy_advertise_10BaseT(struct et131x_adapter *adapter, u16 duplex) { u16 data; /* Read the Autonegotiation Register (10/100) */ - MiRead(etdev, PHY_AUTO_ADVERTISEMENT, &data); + et131x_mii_read(adapter, PHY_AUTO_ADVERTISEMENT, &data); /* Clear bits 5,6 */ data &= ~0x0060; @@ -551,48 +544,32 @@ static void ET1310_PhyAdvertise10BaseT(struct et131x_adapter *etdev, } /* Write back advertisement */ - MiWrite(etdev, PHY_AUTO_ADVERTISEMENT, data); -} - -/** - * et131x_setphy_normal - Set PHY for normal operation. - * @etdev: pointer to our private adapter structure - * - * Used by Power Management to force the PHY into 10 Base T half-duplex mode, - * when going to D3 in WOL mode. Also used during initialization to set the - * PHY for normal operation. - */ -void et131x_setphy_normal(struct et131x_adapter *etdev) -{ - /* Make sure the PHY is powered up */ - ET1310_PhyPowerDown(etdev, 0); - et131x_xcvr_init(etdev); + et131x_mii_write(adapter, PHY_AUTO_ADVERTISEMENT, data); } - /** * et131x_xcvr_init - Init the phy if we are setting it into force mode - * @etdev: pointer to our private adapter structure + * @adapter: pointer to our private adapter structure * */ -static void et131x_xcvr_init(struct et131x_adapter *etdev) +static void et131x_xcvr_init(struct et131x_adapter *adapter) { u16 imr; u16 isr; u16 lcr2; /* Zero out the adapter structure variable representing BMSR */ - etdev->bmsr = 0; + adapter->bmsr = 0; - MiRead(etdev, (u8) offsetof(struct mi_regs, isr), &isr); - MiRead(etdev, (u8) offsetof(struct mi_regs, imr), &imr); + et131x_mii_read(adapter, (u8) offsetof(struct mi_regs, isr), &isr); + et131x_mii_read(adapter, (u8) offsetof(struct mi_regs, imr), &imr); /* Set the link status interrupt only. Bad behavior when link status * and auto neg are set, we run into a nested interrupt problem */ imr |= 0x0105; - MiWrite(etdev, (u8) offsetof(struct mi_regs, imr), imr); + et131x_mii_write(adapter, (u8) offsetof(struct mi_regs, imr), imr); /* Set the LED behavior such that LED 1 indicates speed (off = * 10Mbits, blink = 100Mbits, on = 1000Mbits) and LED 2 indicates @@ -602,133 +579,150 @@ static void et131x_xcvr_init(struct et131x_adapter *etdev) * vendors; The LED behavior is now determined by vendor data in the * EEPROM. However, the above description is the default. */ - if ((etdev->eeprom_data[1] & 0x4) == 0) { - MiRead(etdev, (u8) offsetof(struct mi_regs, lcr2), + if ((adapter->eeprom_data[1] & 0x4) == 0) { + et131x_mii_read(adapter, (u8) offsetof(struct mi_regs, lcr2), &lcr2); lcr2 &= 0x00FF; lcr2 |= 0xA000; /* led link */ - if ((etdev->eeprom_data[1] & 0x8) == 0) + if ((adapter->eeprom_data[1] & 0x8) == 0) lcr2 |= 0x0300; else lcr2 |= 0x0400; - MiWrite(etdev, (u8) offsetof(struct mi_regs, lcr2), + et131x_mii_write(adapter, (u8) offsetof(struct mi_regs, lcr2), lcr2); } /* Determine if we need to go into a force mode and set it */ - if (etdev->AiForceSpeed == 0 && etdev->AiForceDpx == 0) { - if (etdev->wanted_flow == FLOW_TXONLY || - etdev->wanted_flow == FLOW_BOTH) - ET1310_PhyAccessMiBit(etdev, + if (adapter->ai_force_speed == 0 && adapter->ai_force_duplex == 0) { + if (adapter->wanted_flow == FLOW_TXONLY || + adapter->wanted_flow == FLOW_BOTH) + et1310_phy_access_mii_bit(adapter, TRUEPHY_BIT_SET, 4, 11, NULL); else - ET1310_PhyAccessMiBit(etdev, + et1310_phy_access_mii_bit(adapter, TRUEPHY_BIT_CLEAR, 4, 11, NULL); - if (etdev->wanted_flow == FLOW_BOTH) - ET1310_PhyAccessMiBit(etdev, + if (adapter->wanted_flow == FLOW_BOTH) + et1310_phy_access_mii_bit(adapter, TRUEPHY_BIT_SET, 4, 10, NULL); else - ET1310_PhyAccessMiBit(etdev, + et1310_phy_access_mii_bit(adapter, TRUEPHY_BIT_CLEAR, 4, 10, NULL); /* Set the phy to autonegotiation */ - ET1310_PhyAutoNeg(etdev, true); + et1310_phy_auto_neg(adapter, true); /* NOTE - Do we need this? */ - ET1310_PhyAccessMiBit(etdev, TRUEPHY_BIT_SET, 0, 9, NULL); + et1310_phy_access_mii_bit(adapter, TRUEPHY_BIT_SET, 0, 9, NULL); return; } - ET1310_PhyAutoNeg(etdev, false); + et1310_phy_auto_neg(adapter, false); /* Set to the correct force mode. */ - if (etdev->AiForceDpx != 1) { - if (etdev->wanted_flow == FLOW_TXONLY || - etdev->wanted_flow == FLOW_BOTH) - ET1310_PhyAccessMiBit(etdev, + if (adapter->ai_force_duplex != 1) { + if (adapter->wanted_flow == FLOW_TXONLY || + adapter->wanted_flow == FLOW_BOTH) + et1310_phy_access_mii_bit(adapter, TRUEPHY_BIT_SET, 4, 11, NULL); else - ET1310_PhyAccessMiBit(etdev, + et1310_phy_access_mii_bit(adapter, TRUEPHY_BIT_CLEAR, 4, 11, NULL); - if (etdev->wanted_flow == FLOW_BOTH) - ET1310_PhyAccessMiBit(etdev, + if (adapter->wanted_flow == FLOW_BOTH) + et1310_phy_access_mii_bit(adapter, TRUEPHY_BIT_SET, 4, 10, NULL); else - ET1310_PhyAccessMiBit(etdev, + et1310_phy_access_mii_bit(adapter, TRUEPHY_BIT_CLEAR, 4, 10, NULL); } else { - ET1310_PhyAccessMiBit(etdev, TRUEPHY_BIT_CLEAR, 4, 10, NULL); - ET1310_PhyAccessMiBit(etdev, TRUEPHY_BIT_CLEAR, 4, 11, NULL); + et1310_phy_access_mii_bit(adapter, TRUEPHY_BIT_CLEAR, + 4, 10, NULL); + et1310_phy_access_mii_bit(adapter, TRUEPHY_BIT_CLEAR, + 4, 11, NULL); } - ET1310_PhyPowerDown(etdev, 1); - switch (etdev->AiForceSpeed) { + et1310_phy_power_down(adapter, 1); + switch (adapter->ai_force_speed) { case 10: /* First we need to turn off all other advertisement */ - ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); - ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); - if (etdev->AiForceDpx == 1) { + et1310_phy_advertise_1000BaseT(adapter, TRUEPHY_ADV_DUPLEX_NONE); + et1310_phy_advertise_100BaseT(adapter, TRUEPHY_ADV_DUPLEX_NONE); + if (adapter->ai_force_duplex == 1) { /* Set our advertise values accordingly */ - ET1310_PhyAdvertise10BaseT(etdev, + et1310_phy_advertise_10BaseT(adapter, TRUEPHY_ADV_DUPLEX_HALF); - } else if (etdev->AiForceDpx == 2) { + } else if (adapter->ai_force_duplex == 2) { /* Set our advertise values accordingly */ - ET1310_PhyAdvertise10BaseT(etdev, + et1310_phy_advertise_10BaseT(adapter, TRUEPHY_ADV_DUPLEX_FULL); } else { /* Disable autoneg */ - ET1310_PhyAutoNeg(etdev, false); + et1310_phy_auto_neg(adapter, false); /* Disable rest of the advertisements */ - ET1310_PhyAdvertise10BaseT(etdev, + et1310_phy_advertise_10BaseT(adapter, TRUEPHY_ADV_DUPLEX_NONE); /* Force 10 Mbps */ - ET1310_PhySpeedSelect(etdev, TRUEPHY_SPEED_10MBPS); + et1310_phy_speed_select(adapter, TRUEPHY_SPEED_10MBPS); /* Force Full duplex */ - ET1310_PhyDuplexMode(etdev, TRUEPHY_DUPLEX_FULL); + et1310_phy_duplex_mode(adapter, TRUEPHY_DUPLEX_FULL); } break; case 100: /* first we need to turn off all other advertisement */ - ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); - ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); - if (etdev->AiForceDpx == 1) { + et1310_phy_advertise_1000BaseT(adapter, TRUEPHY_ADV_DUPLEX_NONE); + et1310_phy_advertise_10BaseT(adapter, TRUEPHY_ADV_DUPLEX_NONE); + if (adapter->ai_force_duplex == 1) { /* Set our advertise values accordingly */ - ET1310_PhyAdvertise100BaseT(etdev, + et1310_phy_advertise_100BaseT(adapter, TRUEPHY_ADV_DUPLEX_HALF); /* Set speed */ - ET1310_PhySpeedSelect(etdev, TRUEPHY_SPEED_100MBPS); - } else if (etdev->AiForceDpx == 2) { + et1310_phy_speed_select(adapter, TRUEPHY_SPEED_100MBPS); + } else if (adapter->ai_force_duplex == 2) { /* Set our advertise values accordingly */ - ET1310_PhyAdvertise100BaseT(etdev, + et1310_phy_advertise_100BaseT(adapter, TRUEPHY_ADV_DUPLEX_FULL); } else { /* Disable autoneg */ - ET1310_PhyAutoNeg(etdev, false); + et1310_phy_auto_neg(adapter, false); /* Disable other advertisement */ - ET1310_PhyAdvertise100BaseT(etdev, + et1310_phy_advertise_100BaseT(adapter, TRUEPHY_ADV_DUPLEX_NONE); /* Force 100 Mbps */ - ET1310_PhySpeedSelect(etdev, TRUEPHY_SPEED_100MBPS); + et1310_phy_speed_select(adapter, TRUEPHY_SPEED_100MBPS); /* Force Full duplex */ - ET1310_PhyDuplexMode(etdev, TRUEPHY_DUPLEX_FULL); + et1310_phy_duplex_mode(adapter, TRUEPHY_DUPLEX_FULL); } break; case 1000: /* first we need to turn off all other advertisement */ - ET1310_PhyAdvertise100BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); - ET1310_PhyAdvertise10BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); + et1310_phy_advertise_100BaseT(adapter, TRUEPHY_ADV_DUPLEX_NONE); + et1310_phy_advertise_10BaseT(adapter, TRUEPHY_ADV_DUPLEX_NONE); /* set our advertise values accordingly */ - ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_FULL); + et1310_phy_advertise_1000BaseT(adapter, TRUEPHY_ADV_DUPLEX_FULL); break; } - ET1310_PhyPowerDown(etdev, 0); + et1310_phy_power_down(adapter, 0); } -void et131x_Mii_check(struct et131x_adapter *etdev, +/** + * et131x_setphy_normal - Set PHY for normal operation. + * @adapter: pointer to our private adapter structure + * + * Used by Power Management to force the PHY into 10 Base T half-duplex mode, + * when going to D3 in WOL mode. Also used during initialization to set the + * PHY for normal operation. + */ +void et131x_setphy_normal(struct et131x_adapter *adapter) +{ + /* Make sure the PHY is powered up */ + et1310_phy_power_down(adapter, 0); + et131x_xcvr_init(adapter); +} + +void et131x_mii_check(struct et131x_adapter *adapter, u16 bmsr, u16 bmsr_ints) { u8 link_status; @@ -738,127 +732,104 @@ void et131x_Mii_check(struct et131x_adapter *etdev, u32 mdi_mdix; u32 masterslave; u32 polarity; - unsigned long flags; if (bmsr_ints & MI_BMSR_LINK_STATUS) { if (bmsr & MI_BMSR_LINK_STATUS) { - etdev->boot_coma = 20; - - /* Update our state variables and indicate the - * connected state - */ - spin_lock_irqsave(&etdev->Lock, flags); - - etdev->MediaState = NETIF_STATUS_MEDIA_CONNECT; - - spin_unlock_irqrestore(&etdev->Lock, flags); - - netif_carrier_on(etdev->netdev); + adapter->boot_coma = 20; + netif_carrier_on(adapter->netdev); } else { - dev_warn(&etdev->pdev->dev, + dev_warn(&adapter->pdev->dev, "Link down - cable problem ?\n"); - if (etdev->linkspeed == TRUEPHY_SPEED_10MBPS) { + if (adapter->linkspeed == TRUEPHY_SPEED_10MBPS) { /* NOTE - Is there a way to query this without * TruePHY? - * && TRU_QueryCoreType(etdev->hTruePhy, 0) == + * && TRU_QueryCoreType(adapter->hTruePhy, 0) == * EMI_TRUEPHY_A13O) { */ - u16 Register18; - - MiRead(etdev, 0x12, &Register18); - MiWrite(etdev, 0x12, Register18 | 0x4); - MiWrite(etdev, 0x10, Register18 | 0x8402); - MiWrite(etdev, 0x11, Register18 | 511); - MiWrite(etdev, 0x12, Register18); + u16 register18; + + et131x_mii_read(adapter, 0x12, ®ister18); + et131x_mii_write(adapter, 0x12, register18 | 0x4); + et131x_mii_write(adapter, 0x10, + register18 | 0x8402); + et131x_mii_write(adapter, 0x11, register18 | 511); + et131x_mii_write(adapter, 0x12, register18); } - /* For the first N seconds of life, we are in "link - * detection" When we are in this state, we should - * only report "connected". When the LinkDetection - * Timer expires, we can report disconnected (handled - * in the LinkDetectionDPC). - */ - if ((etdev->MediaState == NETIF_STATUS_MEDIA_DISCONNECT)) { - spin_lock_irqsave(&etdev->Lock, flags); - etdev->MediaState = - NETIF_STATUS_MEDIA_DISCONNECT; - spin_unlock_irqrestore(&etdev->Lock, - flags); - - netif_carrier_off(etdev->netdev); - } + netif_carrier_off(adapter->netdev); - etdev->linkspeed = 0; - etdev->duplex_mode = 0; + adapter->linkspeed = 0; + adapter->duplex_mode = 0; /* Free the packets being actively sent & stopped */ - et131x_free_busy_send_packets(etdev); + et131x_free_busy_send_packets(adapter); /* Re-initialize the send structures */ - et131x_init_send(etdev); + et131x_init_send(adapter); /* Reset the RFD list and re-start RU */ - et131x_reset_recv(etdev); + et131x_reset_recv(adapter); /* * Bring the device back to the state it was during * init prior to autonegotiation being complete. This * way, when we get the auto-neg complete interrupt, - * we can complete init by calling ConfigMacREGS2. + * we can complete init by calling config_mac_regs2. */ - et131x_soft_reset(etdev); + et131x_soft_reset(adapter); /* Setup ET1310 as per the documentation */ - et131x_adapter_setup(etdev); + et131x_adapter_setup(adapter); /* Setup the PHY into coma mode until the cable is * plugged back in */ - if (etdev->RegistryPhyComa == 1) - EnablePhyComa(etdev); + if (adapter->registry_phy_coma == 1) + et1310_enable_phy_coma(adapter); } } if ((bmsr_ints & MI_BMSR_AUTO_NEG_COMPLETE) || - (etdev->AiForceDpx == 3 && (bmsr_ints & MI_BMSR_LINK_STATUS))) { + (adapter->ai_force_duplex == 3 && (bmsr_ints & MI_BMSR_LINK_STATUS))) { if ((bmsr & MI_BMSR_AUTO_NEG_COMPLETE) || - etdev->AiForceDpx == 3) { - ET1310_PhyLinkStatus(etdev, + adapter->ai_force_duplex == 3) { + et1310_phy_link_status(adapter, &link_status, &autoneg_status, &speed, &duplex, &mdi_mdix, &masterslave, &polarity); - etdev->linkspeed = speed; - etdev->duplex_mode = duplex; + adapter->linkspeed = speed; + adapter->duplex_mode = duplex; - etdev->boot_coma = 20; + adapter->boot_coma = 20; - if (etdev->linkspeed == TRUEPHY_SPEED_10MBPS) { + if (adapter->linkspeed == TRUEPHY_SPEED_10MBPS) { /* * NOTE - Is there a way to query this without * TruePHY? - * && TRU_QueryCoreType(etdev->hTruePhy, 0)== + * && TRU_QueryCoreType(adapter->hTruePhy, 0)== * EMI_TRUEPHY_A13O) { */ - u16 Register18; - - MiRead(etdev, 0x12, &Register18); - MiWrite(etdev, 0x12, Register18 | 0x4); - MiWrite(etdev, 0x10, Register18 | 0x8402); - MiWrite(etdev, 0x11, Register18 | 511); - MiWrite(etdev, 0x12, Register18); + u16 register18; + + et131x_mii_read(adapter, 0x12, ®ister18); + et131x_mii_write(adapter, 0x12, register18 | 0x4); + et131x_mii_write(adapter, 0x10, + register18 | 0x8402); + et131x_mii_write(adapter, 0x11, register18 | 511); + et131x_mii_write(adapter, 0x12, register18); } - ConfigFlowControl(etdev); + et1310_config_flow_control(adapter); - if (etdev->linkspeed == TRUEPHY_SPEED_1000MBPS && - etdev->RegistryJumboPacket > 2048) - ET1310_PhyAndOrReg(etdev, 0x16, 0xcfff, + if (adapter->linkspeed == TRUEPHY_SPEED_1000MBPS && + adapter->registry_jumbo_packet > 2048) + et1310_phy_and_or_reg(adapter, 0x16, 0xcfff, 0x2000); - SetRxDmaTimer(etdev); - ConfigMACRegs2(etdev); + et131x_set_rx_dma_timer(adapter); + et1310_config_mac_regs2(adapter); } } } @@ -868,9 +839,8 @@ void et131x_Mii_check(struct et131x_adapter *etdev, * primarily by the routines above (although there are a few places elsewhere * in the driver where this level of access is required). */ - -static const u16 ConfigPhy[25][2] = { - /* Reg Value Register */ +static const u16 config_phy[25][2] = { + /* Reg Value Register */ /* Addr */ {0x880B, 0x0926}, /* AfeIfCreg4B1000Msbs */ {0x880C, 0x0926}, /* AfeIfCreg4B100Msbs */ @@ -906,74 +876,74 @@ static const u16 ConfigPhy[25][2] = { {0x8010, 46}, /* IdlguardTime */ {0, 0} - }; /* condensed version of the phy initialization routine */ -void ET1310_PhyInit(struct et131x_adapter *etdev) +void et1310_phy_init(struct et131x_adapter *adapter) { u16 data, index; - if (etdev == NULL) - return; - /* get the identity (again ?) */ - MiRead(etdev, PHY_ID_1, &data); - MiRead(etdev, PHY_ID_2, &data); + et131x_mii_read(adapter, PHY_ID_1, &data); + et131x_mii_read(adapter, PHY_ID_2, &data); /* what does this do/achieve ? */ - MiRead(etdev, PHY_MPHY_CONTROL_REG, &data); /* should read 0002 */ - MiWrite(etdev, PHY_MPHY_CONTROL_REG, 0x0006); + /* should read 0002 */ + et131x_mii_read(adapter, PHY_MPHY_CONTROL_REG, &data); + et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG, 0x0006); /* read modem register 0402, should I do something with the return data ? */ - MiWrite(etdev, PHY_INDEX_REG, 0x0402); - MiRead(etdev, PHY_DATA_REG, &data); + et131x_mii_write(adapter, PHY_INDEX_REG, 0x0402); + et131x_mii_read(adapter, PHY_DATA_REG, &data); /* what does this do/achieve ? */ - MiWrite(etdev, PHY_MPHY_CONTROL_REG, 0x0002); + et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG, 0x0002); /* get the identity (again ?) */ - MiRead(etdev, PHY_ID_1, &data); - MiRead(etdev, PHY_ID_2, &data); + et131x_mii_read(adapter, PHY_ID_1, &data); + et131x_mii_read(adapter, PHY_ID_2, &data); /* what does this achieve ? */ - MiRead(etdev, PHY_MPHY_CONTROL_REG, &data); /* should read 0002 */ - MiWrite(etdev, PHY_MPHY_CONTROL_REG, 0x0006); + /* should read 0002 */ + et131x_mii_read(adapter, PHY_MPHY_CONTROL_REG, &data); + et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG, 0x0006); /* read modem register 0402, should I do something with the return data? */ - MiWrite(etdev, PHY_INDEX_REG, 0x0402); - MiRead(etdev, PHY_DATA_REG, &data); + et131x_mii_write(adapter, PHY_INDEX_REG, 0x0402); + et131x_mii_read(adapter, PHY_DATA_REG, &data); - MiWrite(etdev, PHY_MPHY_CONTROL_REG, 0x0002); + et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG, 0x0002); /* what does this achieve (should return 0x1040) */ - MiRead(etdev, PHY_CONTROL, &data); - MiRead(etdev, PHY_MPHY_CONTROL_REG, &data); /* should read 0002 */ - MiWrite(etdev, PHY_CONTROL, 0x1840); + et131x_mii_read(adapter, PHY_CONTROL, &data); + /* should read 0002 */ + et131x_mii_read(adapter, PHY_MPHY_CONTROL_REG, &data); + et131x_mii_write(adapter, PHY_CONTROL, 0x1840); - MiWrite(etdev, PHY_MPHY_CONTROL_REG, 0x0007); + et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG, 0x0007); /* here the writing of the array starts.... */ index = 0; - while (ConfigPhy[index][0] != 0x0000) { + while (config_phy[index][0] != 0x0000) { /* write value */ - MiWrite(etdev, PHY_INDEX_REG, ConfigPhy[index][0]); - MiWrite(etdev, PHY_DATA_REG, ConfigPhy[index][1]); + et131x_mii_write(adapter, PHY_INDEX_REG, config_phy[index][0]); + et131x_mii_write(adapter, PHY_DATA_REG, config_phy[index][1]); /* read it back */ - MiWrite(etdev, PHY_INDEX_REG, ConfigPhy[index][0]); - MiRead(etdev, PHY_DATA_REG, &data); + et131x_mii_write(adapter, PHY_INDEX_REG, config_phy[index][0]); + et131x_mii_read(adapter, PHY_DATA_REG, &data); /* do a check on the value read back ? */ index++; } /* here the writing of the array ends... */ - MiRead(etdev, PHY_CONTROL, &data); /* 0x1840 */ - MiRead(etdev, PHY_MPHY_CONTROL_REG, &data);/* should read 0007 */ - MiWrite(etdev, PHY_CONTROL, 0x1040); - MiWrite(etdev, PHY_MPHY_CONTROL_REG, 0x0002); + et131x_mii_read(adapter, PHY_CONTROL, &data); /* 0x1840 */ + /* should read 0007 */ + et131x_mii_read(adapter, PHY_MPHY_CONTROL_REG, &data); + et131x_mii_write(adapter, PHY_CONTROL, 0x1040); + et131x_mii_write(adapter, PHY_MPHY_CONTROL_REG, 0x0002); } diff --git a/drivers/staging/et131x/et1310_pm.c b/drivers/staging/et131x/et1310_pm.c index 29d4d66..5ebf064 100644 --- a/drivers/staging/et131x/et1310_pm.c +++ b/drivers/staging/et131x/et1310_pm.c @@ -87,8 +87,8 @@ #include "et131x.h" /** - * EnablePhyComa - called when network cable is unplugged - * @etdev: pointer to our adapter structure + * et1310_enable_phy_coma - called when network cable is unplugged + * @adapter: pointer to our adapter structure * * driver receive an phy status change interrupt while in D0 and check that * phy_status is down. @@ -106,75 +106,75 @@ * indicating linkup status, call the MPDisablePhyComa routine to * restore JAGCore and gigE PHY */ -void EnablePhyComa(struct et131x_adapter *etdev) +void et1310_enable_phy_coma(struct et131x_adapter *adapter) { unsigned long flags; u32 pmcsr; - pmcsr = readl(&etdev->regs->global.pm_csr); + pmcsr = readl(&adapter->regs->global.pm_csr); /* Save the GbE PHY speed and duplex modes. Need to restore this * when cable is plugged back in */ - etdev->pdown_speed = etdev->AiForceSpeed; - etdev->pdown_duplex = etdev->AiForceDpx; + adapter->pdown_speed = adapter->ai_force_speed; + adapter->pdown_duplex = adapter->ai_force_duplex; /* Stop sending packets. */ - spin_lock_irqsave(&etdev->send_hw_lock, flags); - etdev->flags |= fMP_ADAPTER_LOWER_POWER; - spin_unlock_irqrestore(&etdev->send_hw_lock, flags); + spin_lock_irqsave(&adapter->send_hw_lock, flags); + adapter->flags |= fMP_ADAPTER_LOWER_POWER; + spin_unlock_irqrestore(&adapter->send_hw_lock, flags); /* Wait for outstanding Receive packets */ /* Gate off JAGCore 3 clock domains */ pmcsr &= ~ET_PMCSR_INIT; - writel(pmcsr, &etdev->regs->global.pm_csr); + writel(pmcsr, &adapter->regs->global.pm_csr); /* Program gigE PHY in to Coma mode */ pmcsr |= ET_PM_PHY_SW_COMA; - writel(pmcsr, &etdev->regs->global.pm_csr); + writel(pmcsr, &adapter->regs->global.pm_csr); } /** - * DisablePhyComa - Disable the Phy Coma Mode - * @etdev: pointer to our adapter structure + * et1310_disable_phy_coma - Disable the Phy Coma Mode + * @adapter: pointer to our adapter structure */ -void DisablePhyComa(struct et131x_adapter *etdev) +void et1310_disable_phy_coma(struct et131x_adapter *adapter) { u32 pmcsr; - pmcsr = readl(&etdev->regs->global.pm_csr); + pmcsr = readl(&adapter->regs->global.pm_csr); /* Disable phy_sw_coma register and re-enable JAGCore clocks */ pmcsr |= ET_PMCSR_INIT; pmcsr &= ~ET_PM_PHY_SW_COMA; - writel(pmcsr, &etdev->regs->global.pm_csr); + writel(pmcsr, &adapter->regs->global.pm_csr); /* Restore the GbE PHY speed and duplex modes; * Reset JAGCore; re-configure and initialize JAGCore and gigE PHY */ - etdev->AiForceSpeed = etdev->pdown_speed; - etdev->AiForceDpx = etdev->pdown_duplex; + adapter->ai_force_speed = adapter->pdown_speed; + adapter->ai_force_duplex = adapter->pdown_duplex; /* Re-initialize the send structures */ - et131x_init_send(etdev); + et131x_init_send(adapter); /* Reset the RFD list and re-start RU */ - et131x_reset_recv(etdev); + et131x_reset_recv(adapter); /* Bring the device back to the state it was during init prior to * autonegotiation being complete. This way, when we get the auto-neg * complete interrupt, we can complete init by calling ConfigMacREGS2. */ - et131x_soft_reset(etdev); + et131x_soft_reset(adapter); /* setup et1310 as per the documentation ?? */ - et131x_adapter_setup(etdev); + et131x_adapter_setup(adapter); /* Allow Tx to restart */ - etdev->flags &= ~fMP_ADAPTER_LOWER_POWER; + adapter->flags &= ~fMP_ADAPTER_LOWER_POWER; /* Need to re-enable Rx. */ - et131x_rx_dma_enable(etdev); + et131x_rx_dma_enable(adapter); } diff --git a/drivers/staging/et131x/et1310_rx.c b/drivers/staging/et131x/et1310_rx.c index 7e386e0..e6458db 100644 --- a/drivers/staging/et131x/et1310_rx.c +++ b/drivers/staging/et131x/et1310_rx.c @@ -88,22 +88,22 @@ #include "et1310_rx.h" #include "et131x.h" -static inline u32 bump_fbr(u32 *fbr, u32 limit) +static inline u32 bump_free_buff_ring(u32 *free_buff_ring, u32 limit) { - u32 v = *fbr; - v++; + u32 tmp_free_buff_ring = *free_buff_ring; + tmp_free_buff_ring++; /* This works for all cases where limit < 1024. The 1023 case works because 1023++ is 1024 which means the if condition is not taken but the carry of the bit into the wrap bit toggles the wrap value correctly */ - if ((v & ET_DMA10_MASK) > limit) { - v &= ~ET_DMA10_MASK; - v ^= ET_DMA10_WRAP; + if ((tmp_free_buff_ring & ET_DMA10_MASK) > limit) { + tmp_free_buff_ring &= ~ET_DMA10_MASK; + tmp_free_buff_ring ^= ET_DMA10_WRAP; } /* For the 1023 case */ - v &= (ET_DMA10_MASK|ET_DMA10_WRAP); - *fbr = v; - return v; + tmp_free_buff_ring &= (ET_DMA10_MASK|ET_DMA10_WRAP); + *free_buff_ring = tmp_free_buff_ring; + return tmp_free_buff_ring; } /** @@ -119,7 +119,7 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) { u32 i, j; u32 bufsize; - u32 pktStatRingSize, FBRChunkSize; + u32 pktstat_ringsize, fbr_chunksize; struct rx_ring *rx_ring; /* Setup some convenience pointers */ @@ -149,42 +149,42 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) * the number of entries halves. FBR0 increases in size, however. */ - if (adapter->RegistryJumboPacket < 2048) { + if (adapter->registry_jumbo_packet < 2048) { #ifdef USE_FBR0 - rx_ring->Fbr0BufferSize = 256; - rx_ring->Fbr0NumEntries = 512; + rx_ring->fbr0_buffsize = 256; + rx_ring->fbr0_num_entries = 512; #endif - rx_ring->Fbr1BufferSize = 2048; - rx_ring->Fbr1NumEntries = 512; - } else if (adapter->RegistryJumboPacket < 4096) { + rx_ring->fbr1_buffsize = 2048; + rx_ring->fbr1_num_entries = 512; + } else if (adapter->registry_jumbo_packet < 4096) { #ifdef USE_FBR0 - rx_ring->Fbr0BufferSize = 512; - rx_ring->Fbr0NumEntries = 1024; + rx_ring->fbr0_buffsize = 512; + rx_ring->fbr0_num_entries = 1024; #endif - rx_ring->Fbr1BufferSize = 4096; - rx_ring->Fbr1NumEntries = 512; + rx_ring->fbr1_buffsize = 4096; + rx_ring->fbr1_num_entries = 512; } else { #ifdef USE_FBR0 - rx_ring->Fbr0BufferSize = 1024; - rx_ring->Fbr0NumEntries = 768; + rx_ring->fbr0_buffsize = 1024; + rx_ring->fbr0_num_entries = 768; #endif - rx_ring->Fbr1BufferSize = 16384; - rx_ring->Fbr1NumEntries = 128; + rx_ring->fbr1_buffsize = 16384; + rx_ring->fbr1_num_entries = 128; } #ifdef USE_FBR0 - adapter->rx_ring.PsrNumEntries = adapter->rx_ring.Fbr0NumEntries + - adapter->rx_ring.Fbr1NumEntries; + adapter->rx_ring.psr_num_entries = adapter->rx_ring.fbr0_num_entries + + adapter->rx_ring.fbr1_num_entries; #else - adapter->rx_ring.PsrNumEntries = adapter->rx_ring.Fbr1NumEntries; + adapter->rx_ring.psr_num_entries = adapter->rx_ring.fbr1_num_entries; #endif /* Allocate an area of memory for Free Buffer Ring 1 */ - bufsize = (sizeof(struct fbr_desc) * rx_ring->Fbr1NumEntries) + 0xfff; - rx_ring->pFbr1RingVa = pci_alloc_consistent(adapter->pdev, - bufsize, - &rx_ring->pFbr1RingPa); - if (!rx_ring->pFbr1RingVa) { + bufsize = (sizeof(struct fbr_desc) * rx_ring->fbr1_num_entries) + 0xfff; + rx_ring->fbr1_ring_virtaddr = pci_alloc_consistent(adapter->pdev, + bufsize, + &rx_ring->fbr1_ring_physaddr); + if (!rx_ring->fbr1_ring_virtaddr) { dev_err(&adapter->pdev->dev, "Cannot alloc memory for Free Buffer Ring 1\n"); return -ENOMEM; @@ -197,23 +197,24 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) * are ever returned, make sure the high part is retrieved here * before storing the adjusted address. */ - rx_ring->Fbr1Realpa = rx_ring->pFbr1RingPa; + rx_ring->fbr1_real_physaddr = rx_ring->fbr1_ring_physaddr; /* Align Free Buffer Ring 1 on a 4K boundary */ et131x_align_allocated_memory(adapter, - &rx_ring->Fbr1Realpa, - &rx_ring->Fbr1offset, 0x0FFF); + &rx_ring->fbr1_real_physaddr, + &rx_ring->fbr1_offset, 0x0FFF); - rx_ring->pFbr1RingVa = (void *)((u8 *) rx_ring->pFbr1RingVa + - rx_ring->Fbr1offset); + rx_ring->fbr1_ring_virtaddr = + (void *)((u8 *) rx_ring->fbr1_ring_virtaddr + + rx_ring->fbr1_offset); #ifdef USE_FBR0 /* Allocate an area of memory for Free Buffer Ring 0 */ - bufsize = (sizeof(struct fbr_desc) * rx_ring->Fbr0NumEntries) + 0xfff; - rx_ring->pFbr0RingVa = pci_alloc_consistent(adapter->pdev, - bufsize, - &rx_ring->pFbr0RingPa); - if (!rx_ring->pFbr0RingVa) { + bufsize = (sizeof(struct fbr_desc) * rx_ring->fbr0_num_entries) + 0xfff; + rx_ring->fbr0_ring_virtaddr = pci_alloc_consistent(adapter->pdev, + bufsize, + &rx_ring->fbr0_ring_physaddr); + if (!rx_ring->fbr0_ring_virtaddr) { dev_err(&adapter->pdev->dev, "Cannot alloc memory for Free Buffer Ring 0\n"); return -ENOMEM; @@ -226,22 +227,21 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) * are ever returned, make sure the high part is retrieved here before * storing the adjusted address. */ - rx_ring->Fbr0Realpa = rx_ring->pFbr0RingPa; + rx_ring->fbr0_real_physaddr = rx_ring->fbr0_ring_physaddr; /* Align Free Buffer Ring 0 on a 4K boundary */ et131x_align_allocated_memory(adapter, - &rx_ring->Fbr0Realpa, - &rx_ring->Fbr0offset, 0x0FFF); + &rx_ring->fbr0_real_physaddr, + &rx_ring->fbr0_offset, 0x0FFF); - rx_ring->pFbr0RingVa = (void *)((u8 *) rx_ring->pFbr0RingVa + - rx_ring->Fbr0offset); + rx_ring->fbr0_ring_virtaddr = + (void *)((u8 *) rx_ring->fbr0_ring_virtaddr + + rx_ring->fbr0_offset); #endif - - for (i = 0; i < (rx_ring->Fbr1NumEntries / FBR_CHUNKS); - i++) { - u64 Fbr1Offset; - u64 Fbr1TempPa; - u32 Fbr1Align; + for (i = 0; i < (rx_ring->fbr1_num_entries / FBR_CHUNKS); i++) { + u64 fbr1_offset; + u64 fbr1_tmp_physaddr; + u32 fbr1_align; /* This code allocates an area of memory big enough for N * free buffers + (buffer_size - 1) so that the buffers can @@ -250,29 +250,29 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) * the size of FBR0. By allocating N buffers at once, we * reduce this overhead. */ - if (rx_ring->Fbr1BufferSize > 4096) - Fbr1Align = 4096; + if (rx_ring->fbr1_buffsize > 4096) + fbr1_align = 4096; else - Fbr1Align = rx_ring->Fbr1BufferSize; + fbr1_align = rx_ring->fbr1_buffsize; - FBRChunkSize = - (FBR_CHUNKS * rx_ring->Fbr1BufferSize) + Fbr1Align - 1; - rx_ring->Fbr1MemVa[i] = - pci_alloc_consistent(adapter->pdev, FBRChunkSize, - &rx_ring->Fbr1MemPa[i]); + fbr_chunksize = + (FBR_CHUNKS * rx_ring->fbr1_buffsize) + fbr1_align - 1; + rx_ring->fbr1_mem_virtaddrs[i] = + pci_alloc_consistent(adapter->pdev, fbr_chunksize, + &rx_ring->fbr1_mem_physaddrs[i]); - if (!rx_ring->Fbr1MemVa[i]) { + if (!rx_ring->fbr1_mem_virtaddrs[i]) { dev_err(&adapter->pdev->dev, "Could not alloc memory\n"); return -ENOMEM; } /* See NOTE in "Save Physical Address" comment above */ - Fbr1TempPa = rx_ring->Fbr1MemPa[i]; + fbr1_tmp_physaddr = rx_ring->fbr1_mem_physaddrs[i]; et131x_align_allocated_memory(adapter, - &Fbr1TempPa, - &Fbr1Offset, (Fbr1Align - 1)); + &fbr1_tmp_physaddr, + &fbr1_offset, (fbr1_align - 1)); for (j = 0; j < FBR_CHUNKS; j++) { u32 index = (i * FBR_CHUNKS) + j; @@ -281,17 +281,18 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) * access later */ rx_ring->fbr[1]->virt[index] = - (u8 *) rx_ring->Fbr1MemVa[i] + - (j * rx_ring->Fbr1BufferSize) + Fbr1Offset; + (u8 *) rx_ring->fbr1_mem_virtaddrs[i] + + (j * rx_ring->fbr1_buffsize) + fbr1_offset; /* now store the physical address in the descriptor * so the device can access it */ rx_ring->fbr[1]->bus_high[index] = - (u32) (Fbr1TempPa >> 32); - rx_ring->fbr[1]->bus_low[index] = (u32) Fbr1TempPa; + (u32) (fbr1_tmp_physaddr >> 32); + rx_ring->fbr[1]->bus_low[index] = + (u32) fbr1_tmp_physaddr; - Fbr1TempPa += rx_ring->Fbr1BufferSize; + fbr1_tmp_physaddr += rx_ring->fbr1_buffsize; rx_ring->fbr[1]->buffer1[index] = rx_ring->fbr[1]->virt[index]; @@ -302,42 +303,43 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) #ifdef USE_FBR0 /* Same for FBR0 (if in use) */ - for (i = 0; i < (rx_ring->Fbr0NumEntries / FBR_CHUNKS); - i++) { - u64 Fbr0Offset; - u64 Fbr0TempPa; + for (i = 0; i < (rx_ring->fbr0_num_entries / FBR_CHUNKS); i++) { + u64 fbr0_offset; + u64 fbr0_tmp_physaddr; - FBRChunkSize = ((FBR_CHUNKS + 1) * rx_ring->Fbr0BufferSize) - 1; - rx_ring->Fbr0MemVa[i] = - pci_alloc_consistent(adapter->pdev, FBRChunkSize, - &rx_ring->Fbr0MemPa[i]); + fbr_chunksize = + ((FBR_CHUNKS + 1) * rx_ring->fbr0_buffsize) - 1; + rx_ring->fbr0_mem_virtaddrs[i] = + pci_alloc_consistent(adapter->pdev, fbr_chunksize, + &rx_ring->fbr0_mem_physaddrs[i]); - if (!rx_ring->Fbr0MemVa[i]) { + if (!rx_ring->fbr0_mem_virtaddrs[i]) { dev_err(&adapter->pdev->dev, "Could not alloc memory\n"); return -ENOMEM; } /* See NOTE in "Save Physical Address" comment above */ - Fbr0TempPa = rx_ring->Fbr0MemPa[i]; + fbr0_tmp_physaddr = rx_ring->fbr0_mem_physaddrs[i]; et131x_align_allocated_memory(adapter, - &Fbr0TempPa, - &Fbr0Offset, - rx_ring->Fbr0BufferSize - 1); + &fbr0_tmp_physaddr, + &fbr0_offset, + rx_ring->fbr0_buffsize - 1); for (j = 0; j < FBR_CHUNKS; j++) { u32 index = (i * FBR_CHUNKS) + j; rx_ring->fbr[0]->virt[index] = - (u8 *) rx_ring->Fbr0MemVa[i] + - (j * rx_ring->Fbr0BufferSize) + Fbr0Offset; + (u8 *) rx_ring->fbr0_mem_virtaddrs[i] + + (j * rx_ring->fbr0_buffsize) + fbr0_offset; rx_ring->fbr[0]->bus_high[index] = - (u32) (Fbr0TempPa >> 32); - rx_ring->fbr[0]->bus_low[index] = (u32) Fbr0TempPa; + (u32) (fbr0_tmp_physaddr >> 32); + rx_ring->fbr[0]->bus_low[index] = + (u32) fbr0_tmp_physaddr; - Fbr0TempPa += rx_ring->Fbr0BufferSize; + fbr0_tmp_physaddr += rx_ring->fbr0_buffsize; rx_ring->fbr[0]->buffer1[index] = rx_ring->fbr[0]->virt[index]; @@ -348,19 +350,20 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) #endif /* Allocate an area of memory for FIFO of Packet Status ring entries */ - pktStatRingSize = - sizeof(struct pkt_stat_desc) * adapter->rx_ring.PsrNumEntries; + pktstat_ringsize = + sizeof(struct pkt_stat_desc) * adapter->rx_ring.psr_num_entries; - rx_ring->pPSRingVa = pci_alloc_consistent(adapter->pdev, - pktStatRingSize, - &rx_ring->pPSRingPa); + rx_ring->ps_ring_virtaddr = pci_alloc_consistent(adapter->pdev, + pktstat_ringsize, + &rx_ring->ps_ring_physaddr); - if (!rx_ring->pPSRingVa) { + if (!rx_ring->ps_ring_virtaddr) { dev_err(&adapter->pdev->dev, "Cannot alloc memory for Packet Status Ring\n"); return -ENOMEM; } - printk(KERN_INFO "PSR %lx\n", (unsigned long) rx_ring->pPSRingPa); + printk(KERN_INFO "Packet Status Ring %lx\n", + (unsigned long) rx_ring->ps_ring_physaddr); /* * NOTE : pci_alloc_consistent(), used above to alloc DMA regions, @@ -378,7 +381,7 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) "Cannot alloc memory for Status Block\n"); return -ENOMEM; } - rx_ring->NumRfd = NIC_DEFAULT_NUM_RFD; + rx_ring->num_rfd = NIC_DEFAULT_NUM_RFD; printk(KERN_INFO "PRS %lx\n", (unsigned long)rx_ring->rx_status_bus); /* Recv @@ -387,7 +390,7 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) * freed to the lookaside list. * RFDs will be allocated from this pool. */ - rx_ring->RecvLookaside = kmem_cache_create(adapter->netdev->name, + rx_ring->recv_lookaside = kmem_cache_create(adapter->netdev->name, sizeof(struct rfd), 0, SLAB_CACHE_DMA | @@ -399,7 +402,7 @@ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter) /* The RFDs are going to be put on lists later on, so initialize the * lists now. */ - INIT_LIST_HEAD(&rx_ring->RecvList); + INIT_LIST_HEAD(&rx_ring->recv_list); return 0; } @@ -411,7 +414,7 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) { u32 index; u32 bufsize; - u32 pktStatRingSize; + u32 pktstat_ringsize; struct rfd *rfd; struct rx_ring *rx_ring; @@ -419,100 +422,104 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) rx_ring = &adapter->rx_ring; /* Free RFDs and associated packet descriptors */ - WARN_ON(rx_ring->nReadyRecv != rx_ring->NumRfd); + WARN_ON(rx_ring->num_ready_recv != rx_ring->num_rfd); - while (!list_empty(&rx_ring->RecvList)) { - rfd = (struct rfd *) list_entry(rx_ring->RecvList.next, + while (!list_empty(&rx_ring->recv_list)) { + rfd = (struct rfd *) list_entry(rx_ring->recv_list.next, struct rfd, list_node); list_del(&rfd->list_node); rfd->skb = NULL; - kmem_cache_free(adapter->rx_ring.RecvLookaside, rfd); + kmem_cache_free(adapter->rx_ring.recv_lookaside, rfd); } /* Free Free Buffer Ring 1 */ - if (rx_ring->pFbr1RingVa) { + if (rx_ring->fbr1_ring_virtaddr) { /* First the packet memory */ for (index = 0; index < - (rx_ring->Fbr1NumEntries / FBR_CHUNKS); index++) { - if (rx_ring->Fbr1MemVa[index]) { - u32 Fbr1Align; + (rx_ring->fbr1_num_entries / FBR_CHUNKS); index++) { + if (rx_ring->fbr1_mem_virtaddrs[index]) { + u32 fbr1_align; - if (rx_ring->Fbr1BufferSize > 4096) - Fbr1Align = 4096; + if (rx_ring->fbr1_buffsize > 4096) + fbr1_align = 4096; else - Fbr1Align = rx_ring->Fbr1BufferSize; + fbr1_align = rx_ring->fbr1_buffsize; bufsize = - (rx_ring->Fbr1BufferSize * FBR_CHUNKS) + - Fbr1Align - 1; + (rx_ring->fbr1_buffsize * FBR_CHUNKS) + + fbr1_align - 1; pci_free_consistent(adapter->pdev, - bufsize, - rx_ring->Fbr1MemVa[index], - rx_ring->Fbr1MemPa[index]); + bufsize, + rx_ring->fbr1_mem_virtaddrs[index], + rx_ring->fbr1_mem_physaddrs[index]); - rx_ring->Fbr1MemVa[index] = NULL; + rx_ring->fbr1_mem_virtaddrs[index] = NULL; } } /* Now the FIFO itself */ - rx_ring->pFbr1RingVa = (void *)((u8 *) - rx_ring->pFbr1RingVa - rx_ring->Fbr1offset); + rx_ring->fbr1_ring_virtaddr = (void *)((u8 *) + rx_ring->fbr1_ring_virtaddr - rx_ring->fbr1_offset); - bufsize = (sizeof(struct fbr_desc) * rx_ring->Fbr1NumEntries) + bufsize = (sizeof(struct fbr_desc) * rx_ring->fbr1_num_entries) + 0xfff; pci_free_consistent(adapter->pdev, bufsize, - rx_ring->pFbr1RingVa, rx_ring->pFbr1RingPa); + rx_ring->fbr1_ring_virtaddr, + rx_ring->fbr1_ring_physaddr); - rx_ring->pFbr1RingVa = NULL; + rx_ring->fbr1_ring_virtaddr = NULL; } #ifdef USE_FBR0 /* Now the same for Free Buffer Ring 0 */ - if (rx_ring->pFbr0RingVa) { + if (rx_ring->fbr0_ring_virtaddr) { /* First the packet memory */ for (index = 0; index < - (rx_ring->Fbr0NumEntries / FBR_CHUNKS); index++) { - if (rx_ring->Fbr0MemVa[index]) { + (rx_ring->fbr0_num_entries / FBR_CHUNKS); index++) { + if (rx_ring->fbr0_mem_virtaddrs[index]) { bufsize = - (rx_ring->Fbr0BufferSize * + (rx_ring->fbr0_buffsize * (FBR_CHUNKS + 1)) - 1; pci_free_consistent(adapter->pdev, - bufsize, - rx_ring->Fbr0MemVa[index], - rx_ring->Fbr0MemPa[index]); + bufsize, + rx_ring->fbr0_mem_virtaddrs[index], + rx_ring->fbr0_mem_physaddrs[index]); - rx_ring->Fbr0MemVa[index] = NULL; + rx_ring->fbr0_mem_virtaddrs[index] = NULL; } } /* Now the FIFO itself */ - rx_ring->pFbr0RingVa = (void *)((u8 *) - rx_ring->pFbr0RingVa - rx_ring->Fbr0offset); + rx_ring->fbr0_ring_virtaddr = (void *)((u8 *) + rx_ring->fbr0_ring_virtaddr - rx_ring->fbr0_offset); - bufsize = (sizeof(struct fbr_desc) * rx_ring->Fbr0NumEntries) + bufsize = (sizeof(struct fbr_desc) * rx_ring->fbr0_num_entries) + 0xfff; pci_free_consistent(adapter->pdev, bufsize, - rx_ring->pFbr0RingVa, rx_ring->pFbr0RingPa); + rx_ring->fbr0_ring_virtaddr, + rx_ring->fbr0_ring_physaddr); - rx_ring->pFbr0RingVa = NULL; + rx_ring->fbr0_ring_virtaddr = NULL; } #endif /* Free Packet Status Ring */ - if (rx_ring->pPSRingVa) { - pktStatRingSize = - sizeof(struct pkt_stat_desc) * adapter->rx_ring.PsrNumEntries; + if (rx_ring->ps_ring_virtaddr) { + pktstat_ringsize = + sizeof(struct pkt_stat_desc) * + adapter->rx_ring.psr_num_entries; - pci_free_consistent(adapter->pdev, pktStatRingSize, - rx_ring->pPSRingVa, rx_ring->pPSRingPa); + pci_free_consistent(adapter->pdev, pktstat_ringsize, + rx_ring->ps_ring_virtaddr, + rx_ring->ps_ring_physaddr); - rx_ring->pPSRingVa = NULL; + rx_ring->ps_ring_virtaddr = NULL; } /* Free area of memory for the writeback of status information */ @@ -529,7 +536,7 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) /* Destroy the lookaside (RFD) pool */ if (adapter->flags & fMP_ADAPTER_RECV_LOOKASIDE) { - kmem_cache_destroy(rx_ring->RecvLookaside); + kmem_cache_destroy(rx_ring->recv_lookaside); adapter->flags &= ~fMP_ADAPTER_RECV_LOOKASIDE; } @@ -541,7 +548,7 @@ void et131x_rx_dma_memory_free(struct et131x_adapter *adapter) kfree(rx_ring->fbr[1]); /* Reset Counters */ - rx_ring->nReadyRecv = 0; + rx_ring->num_ready_recv = 0; } /** @@ -562,8 +569,8 @@ int et131x_init_recv(struct et131x_adapter *adapter) rx_ring = &adapter->rx_ring; /* Setup each RFD */ - for (rfdct = 0; rfdct < rx_ring->NumRfd; rfdct++) { - rfd = kmem_cache_alloc(rx_ring->RecvLookaside, + for (rfdct = 0; rfdct < rx_ring->num_rfd; rfdct++) { + rfd = kmem_cache_alloc(rx_ring->recv_lookaside, GFP_ATOMIC | GFP_DMA); if (!rfd) { @@ -575,21 +582,21 @@ int et131x_init_recv(struct et131x_adapter *adapter) rfd->skb = NULL; - /* Add this RFD to the RecvList */ - list_add_tail(&rfd->list_node, &rx_ring->RecvList); + /* Add this RFD to the recv_list */ + list_add_tail(&rfd->list_node, &rx_ring->recv_list); /* Increment both the available RFD's, and the total RFD's. */ - rx_ring->nReadyRecv++; + rx_ring->num_ready_recv++; numrfd++; } if (numrfd > NIC_MIN_NUM_RFD) status = 0; - rx_ring->NumRfd = numrfd; + rx_ring->num_rfd = numrfd; if (status != 0) { - kmem_cache_free(rx_ring->RecvLookaside, rfd); + kmem_cache_free(rx_ring->recv_lookaside, rfd); dev_err(&adapter->pdev->dev, "Allocation problems in et131x_init_recv\n"); } @@ -597,20 +604,20 @@ int et131x_init_recv(struct et131x_adapter *adapter) } /** - * ConfigRxDmaRegs - Start of Rx_DMA init sequence - * @etdev: pointer to our adapter structure + * et131x_config_rx_dma_regs - Start of Rx_DMA init sequence + * @adapter: pointer to our adapter structure */ -void ConfigRxDmaRegs(struct et131x_adapter *etdev) +void et131x_config_rx_dma_regs(struct et131x_adapter *adapter) { - struct rxdma_regs __iomem *rx_dma = &etdev->regs->rxdma; - struct rx_ring *rx_local = &etdev->rx_ring; + struct rxdma_regs __iomem *rx_dma = &adapter->regs->rxdma; + struct rx_ring *rx_local = &adapter->rx_ring; struct fbr_desc *fbr_entry; u32 entry; u32 psr_num_des; unsigned long flags; /* Halt RXDMA to perform the reconfigure. */ - et131x_rx_dma_disable(etdev); + et131x_rx_dma_disable(adapter); /* Load the completion writeback physical address * @@ -628,24 +635,24 @@ void ConfigRxDmaRegs(struct et131x_adapter *etdev) /* Set the address and parameters of the packet status ring into the * 1310's registers */ - writel((u32) ((u64)rx_local->pPSRingPa >> 32), + writel((u32) ((u64)rx_local->ps_ring_physaddr >> 32), &rx_dma->psr_base_hi); - writel((u32) rx_local->pPSRingPa, &rx_dma->psr_base_lo); - writel(rx_local->PsrNumEntries - 1, &rx_dma->psr_num_des); + writel((u32) rx_local->ps_ring_physaddr, &rx_dma->psr_base_lo); + writel(rx_local->psr_num_entries - 1, &rx_dma->psr_num_des); writel(0, &rx_dma->psr_full_offset); psr_num_des = readl(&rx_dma->psr_num_des) & 0xFFF; writel((psr_num_des * LO_MARK_PERCENT_FOR_PSR) / 100, &rx_dma->psr_min_des); - spin_lock_irqsave(&etdev->rcv_lock, flags); + spin_lock_irqsave(&adapter->rcv_lock, flags); /* These local variables track the PSR in the adapter structure */ rx_local->local_psr_full = 0; /* Now's the best time to initialize FBR1 contents */ - fbr_entry = (struct fbr_desc *) rx_local->pFbr1RingVa; - for (entry = 0; entry < rx_local->Fbr1NumEntries; entry++) { + fbr_entry = (struct fbr_desc *) rx_local->fbr1_ring_virtaddr; + for (entry = 0; entry < rx_local->fbr1_num_entries; entry++) { fbr_entry->addr_hi = rx_local->fbr[1]->bus_high[entry]; fbr_entry->addr_lo = rx_local->fbr[1]->bus_low[entry]; fbr_entry->word2 = entry; @@ -655,39 +662,43 @@ void ConfigRxDmaRegs(struct et131x_adapter *etdev) /* Set the address and parameters of Free buffer ring 1 (and 0 if * required) into the 1310's registers */ - writel((u32) (rx_local->Fbr1Realpa >> 32), &rx_dma->fbr1_base_hi); - writel((u32) rx_local->Fbr1Realpa, &rx_dma->fbr1_base_lo); - writel(rx_local->Fbr1NumEntries - 1, &rx_dma->fbr1_num_des); + writel((u32) (rx_local->fbr1_real_physaddr >> 32), + &rx_dma->fbr1_base_hi); + writel((u32) rx_local->fbr1_real_physaddr, &rx_dma->fbr1_base_lo); + writel(rx_local->fbr1_num_entries - 1, &rx_dma->fbr1_num_des); writel(ET_DMA10_WRAP, &rx_dma->fbr1_full_offset); /* This variable tracks the free buffer ring 1 full position, so it * has to match the above. */ - rx_local->local_Fbr1_full = ET_DMA10_WRAP; - writel(((rx_local->Fbr1NumEntries * LO_MARK_PERCENT_FOR_RX) / 100) - 1, - &rx_dma->fbr1_min_des); + rx_local->local_fbr1_full = ET_DMA10_WRAP; + writel( + ((rx_local->fbr1_num_entries * LO_MARK_PERCENT_FOR_RX) / 100) - 1, + &rx_dma->fbr1_min_des); #ifdef USE_FBR0 /* Now's the best time to initialize FBR0 contents */ - fbr_entry = (struct fbr_desc *) rx_local->pFbr0RingVa; - for (entry = 0; entry < rx_local->Fbr0NumEntries; entry++) { + fbr_entry = (struct fbr_desc *) rx_local->fbr0_ring_virtaddr; + for (entry = 0; entry < rx_local->fbr0_num_entries; entry++) { fbr_entry->addr_hi = rx_local->fbr[0]->bus_high[entry]; fbr_entry->addr_lo = rx_local->fbr[0]->bus_low[entry]; fbr_entry->word2 = entry; fbr_entry++; } - writel((u32) (rx_local->Fbr0Realpa >> 32), &rx_dma->fbr0_base_hi); - writel((u32) rx_local->Fbr0Realpa, &rx_dma->fbr0_base_lo); - writel(rx_local->Fbr0NumEntries - 1, &rx_dma->fbr0_num_des); + writel((u32) (rx_local->fbr0_real_physaddr >> 32), + &rx_dma->fbr0_base_hi); + writel((u32) rx_local->fbr0_real_physaddr, &rx_dma->fbr0_base_lo); + writel(rx_local->fbr0_num_entries - 1, &rx_dma->fbr0_num_des); writel(ET_DMA10_WRAP, &rx_dma->fbr0_full_offset); /* This variable tracks the free buffer ring 0 full position, so it * has to match the above. */ - rx_local->local_Fbr0_full = ET_DMA10_WRAP; - writel(((rx_local->Fbr0NumEntries * LO_MARK_PERCENT_FOR_RX) / 100) - 1, - &rx_dma->fbr0_min_des); + rx_local->local_fbr0_full = ET_DMA10_WRAP; + writel( + ((rx_local->fbr0_num_entries * LO_MARK_PERCENT_FOR_RX) / 100) - 1, + &rx_dma->fbr0_min_des); #endif /* Program the number of packets we will receive before generating an @@ -704,36 +715,36 @@ void ConfigRxDmaRegs(struct et131x_adapter *etdev) */ writel(PARM_RX_TIME_INT_DEF, &rx_dma->max_pkt_time); - spin_unlock_irqrestore(&etdev->rcv_lock, flags); + spin_unlock_irqrestore(&adapter->rcv_lock, flags); } /** - * SetRxDmaTimer - Set the heartbeat timer according to line rate. - * @etdev: pointer to our adapter structure + * et131x_set_rx_dma_timer - Set the heartbeat timer according to line rate. + * @adapter: pointer to our adapter structure */ -void SetRxDmaTimer(struct et131x_adapter *etdev) +void et131x_set_rx_dma_timer(struct et131x_adapter *adapter) { /* For version B silicon, we do not use the RxDMA timer for 10 and 100 * Mbits/s line rates. We do not enable and RxDMA interrupt coalescing. */ - if ((etdev->linkspeed == TRUEPHY_SPEED_100MBPS) || - (etdev->linkspeed == TRUEPHY_SPEED_10MBPS)) { - writel(0, &etdev->regs->rxdma.max_pkt_time); - writel(1, &etdev->regs->rxdma.num_pkt_done); + if ((adapter->linkspeed == TRUEPHY_SPEED_100MBPS) || + (adapter->linkspeed == TRUEPHY_SPEED_10MBPS)) { + writel(0, &adapter->regs->rxdma.max_pkt_time); + writel(1, &adapter->regs->rxdma.num_pkt_done); } } /** * NICReturnRFD - Recycle a RFD and put it back onto the receive list - * @etdev: pointer to our adapter + * @adapter: pointer to our adapter * @rfd: pointer to the RFD */ -void nic_return_rfd(struct et131x_adapter *etdev, struct rfd *rfd) +static void nic_return_rfd(struct et131x_adapter *adapter, struct rfd *rfd) { - struct rx_ring *rx_local = &etdev->rx_ring; - struct rxdma_regs __iomem *rx_dma = &etdev->regs->rxdma; - u16 bi = rfd->bufferindex; - u8 ri = rfd->ringindex; + struct rx_ring *rx_local = &adapter->rx_ring; + struct rxdma_regs __iomem *rx_dma = &adapter->regs->rxdma; + u16 buff_index = rfd->bufferindex; + u8 ring_index = rfd->ringindex; unsigned long flags; /* We don't use any of the OOB data besides status. Otherwise, we @@ -741,79 +752,79 @@ void nic_return_rfd(struct et131x_adapter *etdev, struct rfd *rfd) */ if ( #ifdef USE_FBR0 - (ri == 0 && bi < rx_local->Fbr0NumEntries) || + (ring_index == 0 && buff_index < rx_local->fbr0_num_entries) || #endif - (ri == 1 && bi < rx_local->Fbr1NumEntries)) { - spin_lock_irqsave(&etdev->FbrLock, flags); + (ring_index == 1 && buff_index < rx_local->fbr1_num_entries)) { + spin_lock_irqsave(&adapter->fbr_lock, flags); - if (ri == 1) { + if (ring_index == 1) { struct fbr_desc *next = - (struct fbr_desc *) (rx_local->pFbr1RingVa) + - INDEX10(rx_local->local_Fbr1_full); + (struct fbr_desc *) (rx_local->fbr1_ring_virtaddr) + + INDEX10(rx_local->local_fbr1_full); /* Handle the Free Buffer Ring advancement here. Write * the PA / Buffer Index for the returned buffer into * the oldest (next to be freed)FBR entry */ - next->addr_hi = rx_local->fbr[1]->bus_high[bi]; - next->addr_lo = rx_local->fbr[1]->bus_low[bi]; - next->word2 = bi; + next->addr_hi = rx_local->fbr[1]->bus_high[buff_index]; + next->addr_lo = rx_local->fbr[1]->bus_low[buff_index]; + next->word2 = buff_index; - writel(bump_fbr(&rx_local->local_Fbr1_full, - rx_local->Fbr1NumEntries - 1), + writel(bump_free_buff_ring(&rx_local->local_fbr1_full, + rx_local->fbr1_num_entries - 1), &rx_dma->fbr1_full_offset); } #ifdef USE_FBR0 else { struct fbr_desc *next = (struct fbr_desc *) - rx_local->pFbr0RingVa + - INDEX10(rx_local->local_Fbr0_full); + rx_local->fbr0_ring_virtaddr + + INDEX10(rx_local->local_fbr0_full); /* Handle the Free Buffer Ring advancement here. Write * the PA / Buffer Index for the returned buffer into * the oldest (next to be freed) FBR entry */ - next->addr_hi = rx_local->fbr[0]->bus_high[bi]; - next->addr_lo = rx_local->fbr[0]->bus_low[bi]; - next->word2 = bi; + next->addr_hi = rx_local->fbr[0]->bus_high[buff_index]; + next->addr_lo = rx_local->fbr[0]->bus_low[buff_index]; + next->word2 = buff_index; - writel(bump_fbr(&rx_local->local_Fbr0_full, - rx_local->Fbr0NumEntries - 1), + writel(bump_free_buff_ring(&rx_local->local_fbr0_full, + rx_local->fbr0_num_entries - 1), &rx_dma->fbr0_full_offset); } #endif - spin_unlock_irqrestore(&etdev->FbrLock, flags); + spin_unlock_irqrestore(&adapter->fbr_lock, flags); } else { - dev_err(&etdev->pdev->dev, - "NICReturnRFD illegal Buffer Index returned\n"); + dev_err(&adapter->pdev->dev, + "%s illegal Buffer Index returned\n", __func__); } /* The processing on this RFD is done, so put it back on the tail of * our list */ - spin_lock_irqsave(&etdev->rcv_lock, flags); - list_add_tail(&rfd->list_node, &rx_local->RecvList); - rx_local->nReadyRecv++; - spin_unlock_irqrestore(&etdev->rcv_lock, flags); + spin_lock_irqsave(&adapter->rcv_lock, flags); + list_add_tail(&rfd->list_node, &rx_local->recv_list); + rx_local->num_ready_recv++; + spin_unlock_irqrestore(&adapter->rcv_lock, flags); - WARN_ON(rx_local->nReadyRecv > rx_local->NumRfd); + WARN_ON(rx_local->num_ready_recv > rx_local->num_rfd); } /** * et131x_rx_dma_disable - Stop of Rx_DMA on the ET1310 - * @etdev: pointer to our adapter structure + * @adapter: pointer to our adapter structure */ -void et131x_rx_dma_disable(struct et131x_adapter *etdev) +void et131x_rx_dma_disable(struct et131x_adapter *adapter) { u32 csr; /* Setup the receive dma configuration register */ - writel(0x00002001, &etdev->regs->rxdma.csr); - csr = readl(&etdev->regs->rxdma.csr); + writel(0x00002001, &adapter->regs->rxdma.csr); + csr = readl(&adapter->regs->rxdma.csr); if ((csr & 0x00020000) == 0) { /* Check halt status (bit 17) */ udelay(5); - csr = readl(&etdev->regs->rxdma.csr); + csr = readl(&adapter->regs->rxdma.csr); if ((csr & 0x00020000) == 0) - dev_err(&etdev->pdev->dev, + dev_err(&adapter->pdev->dev, "RX Dma failed to enter halt state. CSR 0x%08x\n", csr); } @@ -821,36 +832,36 @@ void et131x_rx_dma_disable(struct et131x_adapter *etdev) /** * et131x_rx_dma_enable - re-start of Rx_DMA on the ET1310. - * @etdev: pointer to our adapter structure + * @adapter: pointer to our adapter structure */ -void et131x_rx_dma_enable(struct et131x_adapter *etdev) +void et131x_rx_dma_enable(struct et131x_adapter *adapter) { /* Setup the receive dma configuration register for normal operation */ u32 csr = 0x2000; /* FBR1 enable */ - if (etdev->rx_ring.Fbr1BufferSize == 4096) + if (adapter->rx_ring.fbr1_buffsize == 4096) csr |= 0x0800; - else if (etdev->rx_ring.Fbr1BufferSize == 8192) + else if (adapter->rx_ring.fbr1_buffsize == 8192) csr |= 0x1000; - else if (etdev->rx_ring.Fbr1BufferSize == 16384) + else if (adapter->rx_ring.fbr1_buffsize == 16384) csr |= 0x1800; #ifdef USE_FBR0 csr |= 0x0400; /* FBR0 enable */ - if (etdev->rx_ring.Fbr0BufferSize == 256) + if (adapter->rx_ring.fbr0_buffsize == 256) csr |= 0x0100; - else if (etdev->rx_ring.Fbr0BufferSize == 512) + else if (adapter->rx_ring.fbr0_buffsize == 512) csr |= 0x0200; - else if (etdev->rx_ring.Fbr0BufferSize == 1024) + else if (adapter->rx_ring.fbr0_buffsize == 1024) csr |= 0x0300; #endif - writel(csr, &etdev->regs->rxdma.csr); + writel(csr, &adapter->regs->rxdma.csr); - csr = readl(&etdev->regs->rxdma.csr); + csr = readl(&adapter->regs->rxdma.csr); if ((csr & 0x00020000) != 0) { udelay(5); - csr = readl(&etdev->regs->rxdma.csr); + csr = readl(&adapter->regs->rxdma.csr); if ((csr & 0x00020000) != 0) { - dev_err(&etdev->pdev->dev, + dev_err(&adapter->pdev->dev, "RX Dma failed to exit halt state. CSR 0x%08x\n", csr); } @@ -859,18 +870,18 @@ void et131x_rx_dma_enable(struct et131x_adapter *etdev) /** * nic_rx_pkts - Checks the hardware for available packets - * @etdev: pointer to our adapter + * @adapter: pointer to our adapter * * Returns rfd, a pointer to our MPRFD. * * Checks the hardware for available packets, using completion ring - * If packets are available, it gets an RFD from the RecvList, attaches + * If packets are available, it gets an RFD from the recv_list, attaches * the packet to it, puts the RFD in the RecvPendList, and also returns * the pointer to the RFD. */ -struct rfd *nic_rx_pkts(struct et131x_adapter *etdev) +static struct rfd *nic_rx_pkts(struct et131x_adapter *adapter) { - struct rx_ring *rx_local = &etdev->rx_ring; + struct rx_ring *rx_local = &adapter->rx_ring; struct rx_status_block *status; struct pkt_stat_desc *psr; struct rfd *rfd; @@ -878,8 +889,8 @@ struct rfd *nic_rx_pkts(struct et131x_adapter *etdev) u8 *buf; unsigned long flags; struct list_head *element; - u8 rindex; - u16 bindex; + u8 ring_index; + u16 buff_index; u32 len; u32 word0; u32 word1; @@ -889,7 +900,7 @@ struct rfd *nic_rx_pkts(struct et131x_adapter *etdev) * Status Ring, and also the two Free Buffer rings. */ status = rx_local->rx_status_block; - word1 = status->Word1 >> 16; /* Get the useful bits */ + word1 = status->word1 >> 16; /* Get the useful bits */ /* Check the PSR and wrap bits do not match */ if ((word1 & 0x1FFF) == (rx_local->local_psr_full & 0x1FFF)) @@ -897,7 +908,7 @@ struct rfd *nic_rx_pkts(struct et131x_adapter *etdev) return NULL; /* The packet status ring indicates that data is available. */ - psr = (struct pkt_stat_desc *) (rx_local->pPSRingVa) + + psr = (struct pkt_stat_desc *) (rx_local->ps_ring_virtaddr) + (rx_local->local_psr_full & 0xFFF); /* Grab any information that is required once the PSR is @@ -905,65 +916,66 @@ struct rfd *nic_rx_pkts(struct et131x_adapter *etdev) * accurate */ len = psr->word1 & 0xFFFF; - rindex = (psr->word1 >> 26) & 0x03; - bindex = (psr->word1 >> 16) & 0x3FF; + ring_index = (psr->word1 >> 26) & 0x03; + buff_index = (psr->word1 >> 16) & 0x3FF; word0 = psr->word0; /* Indicate that we have used this PSR entry. */ /* FIXME wrap 12 */ add_12bit(&rx_local->local_psr_full, 1); - if ((rx_local->local_psr_full & 0xFFF) > rx_local->PsrNumEntries - 1) { + if ( + (rx_local->local_psr_full & 0xFFF) > rx_local->psr_num_entries - 1) { /* Clear psr full and toggle the wrap bit */ rx_local->local_psr_full &= ~0xFFF; rx_local->local_psr_full ^= 0x1000; } writel(rx_local->local_psr_full, - &etdev->regs->rxdma.psr_full_offset); + &adapter->regs->rxdma.psr_full_offset); #ifndef USE_FBR0 - if (rindex != 1) + if (ring_index != 1) return NULL; #endif #ifdef USE_FBR0 - if (rindex > 1 || - (rindex == 0 && - bindex > rx_local->Fbr0NumEntries - 1) || - (rindex == 1 && - bindex > rx_local->Fbr1NumEntries - 1)) + if (ring_index > 1 || + (ring_index == 0 && + buff_index > rx_local->fbr0_num_entries - 1) || + (ring_index == 1 && + buff_index > rx_local->fbr1_num_entries - 1)) #else - if (rindex != 1 || bindex > rx_local->Fbr1NumEntries - 1) + if (ring_index != 1 || buff_index > rx_local->fbr1_num_entries - 1) #endif { /* Illegal buffer or ring index cannot be used by S/W*/ - dev_err(&etdev->pdev->dev, + dev_err(&adapter->pdev->dev, "NICRxPkts PSR Entry %d indicates " "length of %d and/or bad bi(%d)\n", rx_local->local_psr_full & 0xFFF, - len, bindex); + len, buff_index); return NULL; } /* Get and fill the RFD. */ - spin_lock_irqsave(&etdev->rcv_lock, flags); + spin_lock_irqsave(&adapter->rcv_lock, flags); rfd = NULL; - element = rx_local->RecvList.next; + element = rx_local->recv_list.next; rfd = (struct rfd *) list_entry(element, struct rfd, list_node); if (rfd == NULL) { - spin_unlock_irqrestore(&etdev->rcv_lock, flags); + spin_unlock_irqrestore(&adapter->rcv_lock, flags); return NULL; } list_del(&rfd->list_node); - rx_local->nReadyRecv--; + rx_local->num_ready_recv--; - spin_unlock_irqrestore(&etdev->rcv_lock, flags); + spin_unlock_irqrestore(&adapter->rcv_lock, flags); - rfd->bufferindex = bindex; - rfd->ringindex = rindex; + rfd->bufferindex = buff_index; + rfd->ringindex = ring_index; /* In V1 silicon, there is a bug which screws up filtering of * runt packets. Therefore runt packet filtering is disabled @@ -971,18 +983,18 @@ struct rfd *nic_rx_pkts(struct et131x_adapter *etdev) * also counted here. */ if (len < (NIC_MIN_PACKET_SIZE + 4)) { - etdev->stats.other_errors++; + adapter->stats.rx_other_errs++; len = 0; } if (len) { - if (etdev->ReplicaPhyLoopbk == 1) { - buf = rx_local->fbr[rindex]->virt[bindex]; + if (adapter->replica_phy_loopbk == 1) { + buf = rx_local->fbr[ring_index]->virt[buff_index]; - if (memcmp(&buf[6], etdev->addr, ETH_ALEN) == 0) { + if (memcmp(&buf[6], adapter->addr, ETH_ALEN) == 0) { if (memcmp(&buf[42], "Replica packet", ETH_HLEN)) { - etdev->ReplicaPhyLoopbkPF = 1; + adapter->replica_phy_loopbk_passfail = 1; } } } @@ -997,31 +1009,33 @@ struct rfd *nic_rx_pkts(struct et131x_adapter *etdev) * filters. Generally filter is 0x2b when in * promiscuous mode. */ - if ((etdev->PacketFilter & ET131X_PACKET_TYPE_MULTICAST) - && !(etdev->PacketFilter & ET131X_PACKET_TYPE_PROMISCUOUS) - && !(etdev->PacketFilter & ET131X_PACKET_TYPE_ALL_MULTICAST)) { - buf = rx_local->fbr[rindex]-> - virt[bindex]; + if ((adapter->packet_filter & + ET131X_PACKET_TYPE_MULTICAST) + && !(adapter->packet_filter & + ET131X_PACKET_TYPE_PROMISCUOUS) + && !(adapter->packet_filter & + ET131X_PACKET_TYPE_ALL_MULTICAST)) { + buf = rx_local->fbr[ring_index]-> + virt[buff_index]; /* Loop through our list to see if the * destination address of this packet * matches one in our list. */ - for (i = 0; - i < etdev->MCAddressCount; + for (i = 0; i < adapter->multicast_addr_count; i++) { if (buf[0] == - etdev->MCList[i][0] + adapter->multicast_list[i][0] && buf[1] == - etdev->MCList[i][1] + adapter->multicast_list[i][1] && buf[2] == - etdev->MCList[i][2] + adapter->multicast_list[i][2] && buf[3] == - etdev->MCList[i][3] + adapter->multicast_list[i][3] && buf[4] == - etdev->MCList[i][4] + adapter->multicast_list[i][4] && buf[5] == - etdev->MCList[i][5]) { + adapter->multicast_list[i][5]) { break; } } @@ -1034,21 +1048,21 @@ struct rfd *nic_rx_pkts(struct et131x_adapter *etdev) * so we free our RFD when we return * from this function. */ - if (i == etdev->MCAddressCount) + if (i == adapter->multicast_addr_count) len = 0; } if (len > 0) - etdev->stats.multircv++; + adapter->stats.multicast_pkts_rcvd++; } else if (word0 & ALCATEL_BROADCAST_PKT) - etdev->stats.brdcstrcv++; + adapter->stats.broadcast_pkts_rcvd++; else /* Not sure what this counter measures in * promiscuous mode. Perhaps we should check * the MAC address to see if it is directed * to us in promiscuous mode. */ - etdev->stats.unircv++; + adapter->stats.unicast_pkts_rcvd++; } if (len > 0) { @@ -1059,19 +1073,19 @@ struct rfd *nic_rx_pkts(struct et131x_adapter *etdev) skb = dev_alloc_skb(rfd->len + 2); if (!skb) { - dev_err(&etdev->pdev->dev, + dev_err(&adapter->pdev->dev, "Couldn't alloc an SKB for Rx\n"); return NULL; } - etdev->net_stats.rx_bytes += rfd->len; + adapter->net_stats.rx_bytes += rfd->len; memcpy(skb_put(skb, rfd->len), - rx_local->fbr[rindex]->virt[bindex], + rx_local->fbr[ring_index]->virt[buff_index], rfd->len); - skb->dev = etdev->netdev; - skb->protocol = eth_type_trans(skb, etdev->netdev); + skb->dev = adapter->netdev; + skb->protocol = eth_type_trans(skb, adapter->netdev); skb->ip_summed = CHECKSUM_NONE; netif_rx(skb); @@ -1079,29 +1093,28 @@ struct rfd *nic_rx_pkts(struct et131x_adapter *etdev) rfd->len = 0; } - nic_return_rfd(etdev, rfd); + nic_return_rfd(adapter, rfd); return rfd; } /** * et131x_reset_recv - Reset the receive list - * @etdev: pointer to our adapter + * @adapter: pointer to our adapter * * Assumption, Rcv spinlock has been acquired. */ -void et131x_reset_recv(struct et131x_adapter *etdev) +void et131x_reset_recv(struct et131x_adapter *adapter) { - WARN_ON(list_empty(&etdev->rx_ring.RecvList)); - + WARN_ON(list_empty(&adapter->rx_ring.recv_list)); } /** * et131x_handle_recv_interrupt - Interrupt handler for receive processing - * @etdev: pointer to our adapter + * @adapter: pointer to our adapter * * Assumption, Rcv spinlock has been acquired. */ -void et131x_handle_recv_interrupt(struct et131x_adapter *etdev) +void et131x_handle_recv_interrupt(struct et131x_adapter *adapter) { struct rfd *rfd = NULL; u32 count = 0; @@ -1109,13 +1122,13 @@ void et131x_handle_recv_interrupt(struct et131x_adapter *etdev) /* Process up to available RFD's */ while (count < NUM_PACKETS_HANDLED) { - if (list_empty(&etdev->rx_ring.RecvList)) { - WARN_ON(etdev->rx_ring.nReadyRecv != 0); + if (list_empty(&adapter->rx_ring.recv_list)) { + WARN_ON(adapter->rx_ring.num_ready_recv != 0); done = false; break; } - rfd = nic_rx_pkts(etdev); + rfd = nic_rx_pkts(adapter); if (rfd == NULL) break; @@ -1125,28 +1138,28 @@ void et131x_handle_recv_interrupt(struct et131x_adapter *etdev) * If length is zero, return the RFD in order to advance the * Free buffer ring. */ - if (!etdev->PacketFilter || - !netif_carrier_ok(etdev->netdev) || + if (!adapter->packet_filter || + !netif_carrier_ok(adapter->netdev) || rfd->len == 0) continue; /* Increment the number of packets we received */ - etdev->net_stats.rx_packets++; + adapter->net_stats.rx_packets++; /* Set the status on the packet, either resources or success */ - if (etdev->rx_ring.nReadyRecv < RFD_LOW_WATER_MARK) { - dev_warn(&etdev->pdev->dev, + if (adapter->rx_ring.num_ready_recv < RFD_LOW_WATER_MARK) { + dev_warn(&adapter->pdev->dev, "RFD's are running out\n"); } count++; } if (count == NUM_PACKETS_HANDLED || !done) { - etdev->rx_ring.UnfinishedReceives = true; + adapter->rx_ring.unfinished_receives = true; writel(PARM_TX_TIME_INT_DEF * NANO_IN_A_MICRO, - &etdev->regs->global.watchdog_timer); + &adapter->regs->global.watchdog_timer); } else /* Watchdog timer will disable itself if appropriate. */ - etdev->rx_ring.UnfinishedReceives = false; + adapter->rx_ring.unfinished_receives = false; } diff --git a/drivers/staging/et131x/et1310_rx.h b/drivers/staging/et131x/et1310_rx.h index e8c653d..1448aa9 100644 --- a/drivers/staging/et131x/et1310_rx.h +++ b/drivers/staging/et131x/et1310_rx.h @@ -174,8 +174,8 @@ struct pkt_stat_desc { * DMA engine it sits in free memory, and is pointed to by 0x101c / 0x1020 */ struct rx_status_block { - u32 Word0; - u32 Word1; + u32 word0; + u32 word1; }; /* @@ -190,54 +190,54 @@ struct fbr_lookup { }; /* - * struct rx_ring is the ssructure representing the adaptor's local + * struct rx_ring is the sructure representing the adaptor's local * reference(s) to the rings */ struct rx_ring { #ifdef USE_FBR0 - void *pFbr0RingVa; - dma_addr_t pFbr0RingPa; - void *Fbr0MemVa[MAX_DESC_PER_RING_RX / FBR_CHUNKS]; - dma_addr_t Fbr0MemPa[MAX_DESC_PER_RING_RX / FBR_CHUNKS]; - uint64_t Fbr0Realpa; - uint64_t Fbr0offset; - u32 local_Fbr0_full; - u32 Fbr0NumEntries; - u32 Fbr0BufferSize; + void *fbr0_ring_virtaddr; + dma_addr_t fbr0_ring_physaddr; + void *fbr0_mem_virtaddrs[MAX_DESC_PER_RING_RX / FBR_CHUNKS]; + dma_addr_t fbr0_mem_physaddrs[MAX_DESC_PER_RING_RX / FBR_CHUNKS]; + uint64_t fbr0_real_physaddr; + uint64_t fbr0_offset; + u32 local_fbr0_full; + u32 fbr0_num_entries; + u32 fbr0_buffsize; #endif - void *pFbr1RingVa; - dma_addr_t pFbr1RingPa; - void *Fbr1MemVa[MAX_DESC_PER_RING_RX / FBR_CHUNKS]; - dma_addr_t Fbr1MemPa[MAX_DESC_PER_RING_RX / FBR_CHUNKS]; - uint64_t Fbr1Realpa; - uint64_t Fbr1offset; + void *fbr1_ring_virtaddr; + dma_addr_t fbr1_ring_physaddr; + void *fbr1_mem_virtaddrs[MAX_DESC_PER_RING_RX / FBR_CHUNKS]; + dma_addr_t fbr1_mem_physaddrs[MAX_DESC_PER_RING_RX / FBR_CHUNKS]; + uint64_t fbr1_real_physaddr; + uint64_t fbr1_offset; struct fbr_lookup *fbr[2]; /* One per ring */ - u32 local_Fbr1_full; - u32 Fbr1NumEntries; - u32 Fbr1BufferSize; + u32 local_fbr1_full; + u32 fbr1_num_entries; + u32 fbr1_buffsize; - void *pPSRingVa; - dma_addr_t pPSRingPa; + void *ps_ring_virtaddr; + dma_addr_t ps_ring_physaddr; u32 local_psr_full; - u32 PsrNumEntries; + u32 psr_num_entries; struct rx_status_block *rx_status_block; dma_addr_t rx_status_bus; - struct list_head RecvBufferPool; + struct list_head recv_buff_pool; /* RECV */ - struct list_head RecvList; - u32 nReadyRecv; + struct list_head recv_list; + u32 num_ready_recv; - u32 NumRfd; + u32 num_rfd; - bool UnfinishedReceives; + bool unfinished_receives; - struct list_head RecvPacketPool; + struct list_head recv_packet_pool; /* lookaside lists */ - struct kmem_cache *RecvLookaside; + struct kmem_cache *recv_lookaside; }; #endif /* __ET1310_RX_H__ */ diff --git a/drivers/staging/et131x/et1310_tx.c b/drivers/staging/et131x/et1310_tx.c index 8fb3051..f821104 100644 --- a/drivers/staging/et131x/et1310_tx.c +++ b/drivers/staging/et131x/et1310_tx.c @@ -88,12 +88,6 @@ #include "et1310_tx.h" #include "et131x.h" -static inline void et131x_free_send_packet(struct et131x_adapter *etdev, - struct tcb *tcb); -static int et131x_send_packet(struct sk_buff *skb, - struct et131x_adapter *etdev); -static int nic_send_packet(struct et131x_adapter *etdev, struct tcb *tcb); - /** * et131x_tx_dma_memory_alloc * @adapter: pointer to our private adapter structure @@ -186,60 +180,60 @@ void et131x_tx_dma_memory_free(struct et131x_adapter *adapter) } /** - * ConfigTxDmaRegs - Set up the tx dma section of the JAGCore. - * @etdev: pointer to our private adapter structure + * et131x_config_tx_dma_regs - Set up the tx dma section of the JAGCore. + * @adapter: pointer to our private adapter structure * * Configure the transmit engine with the ring buffers we have created * and prepare it for use. */ -void ConfigTxDmaRegs(struct et131x_adapter *etdev) +void et131x_config_tx_dma_regs(struct et131x_adapter *adapter) { - struct txdma_regs __iomem *txdma = &etdev->regs->txdma; + struct txdma_regs __iomem *txdma = &adapter->regs->txdma; /* Load the hardware with the start of the transmit descriptor ring. */ - writel((u32) ((u64)etdev->tx_ring.tx_desc_ring_pa >> 32), + writel((u32) ((u64)adapter->tx_ring.tx_desc_ring_pa >> 32), &txdma->pr_base_hi); - writel((u32) etdev->tx_ring.tx_desc_ring_pa, + writel((u32) adapter->tx_ring.tx_desc_ring_pa, &txdma->pr_base_lo); /* Initialise the transmit DMA engine */ writel(NUM_DESC_PER_RING_TX - 1, &txdma->pr_num_des); /* Load the completion writeback physical address */ - writel((u32)((u64)etdev->tx_ring.tx_status_pa >> 32), + writel((u32)((u64)adapter->tx_ring.tx_status_pa >> 32), &txdma->dma_wb_base_hi); - writel((u32)etdev->tx_ring.tx_status_pa, &txdma->dma_wb_base_lo); + writel((u32)adapter->tx_ring.tx_status_pa, &txdma->dma_wb_base_lo); - *etdev->tx_ring.tx_status = 0; + *adapter->tx_ring.tx_status = 0; writel(0, &txdma->service_request); - etdev->tx_ring.send_idx = 0; + adapter->tx_ring.send_idx = 0; } /** * et131x_tx_dma_disable - Stop of Tx_DMA on the ET1310 - * @etdev: pointer to our adapter structure + * @adapter: pointer to our adapter structure */ -void et131x_tx_dma_disable(struct et131x_adapter *etdev) +void et131x_tx_dma_disable(struct et131x_adapter *adapter) { /* Setup the tramsmit dma configuration register */ writel(ET_TXDMA_CSR_HALT|ET_TXDMA_SNGL_EPKT, - &etdev->regs->txdma.csr); + &adapter->regs->txdma.csr); } /** * et131x_tx_dma_enable - re-start of Tx_DMA on the ET1310. - * @etdev: pointer to our adapter structure + * @adapter: pointer to our adapter structure * * Mainly used after a return to the D0 (full-power) state from a lower state. */ -void et131x_tx_dma_enable(struct et131x_adapter *etdev) +void et131x_tx_dma_enable(struct et131x_adapter *adapter) { /* Setup the transmit dma configuration register for normal * operation */ writel(ET_TXDMA_SNGL_EPKT|(PARM_DMA_CACHE_DEF << ET_TXDMA_CACHE_SHIFT), - &etdev->regs->txdma.csr); + &adapter->regs->txdma.csr); } /** @@ -277,138 +271,13 @@ void et131x_init_send(struct et131x_adapter *adapter) } /** - * et131x_send_packets - This function is called by the OS to send packets - * @skb: the packet(s) to send - * @netdev:device on which to TX the above packet(s) - * - * Return 0 in almost all cases; non-zero value in extreme hard failure only - */ -int et131x_send_packets(struct sk_buff *skb, struct net_device *netdev) -{ - int status = 0; - struct et131x_adapter *etdev = NULL; - - etdev = netdev_priv(netdev); - - /* Send these packets - * - * NOTE: The Linux Tx entry point is only given one packet at a time - * to Tx, so the PacketCount and it's array used makes no sense here - */ - - /* TCB is not available */ - if (etdev->tx_ring.used >= NUM_TCB) { - /* NOTE: If there's an error on send, no need to queue the - * packet under Linux; if we just send an error up to the - * netif layer, it will resend the skb to us. - */ - status = -ENOMEM; - } else { - /* We need to see if the link is up; if it's not, make the - * netif layer think we're good and drop the packet - */ - if ((etdev->flags & fMP_ADAPTER_FAIL_SEND_MASK) || - !netif_carrier_ok(netdev)) { - dev_kfree_skb_any(skb); - skb = NULL; - - etdev->net_stats.tx_dropped++; - } else { - status = et131x_send_packet(skb, etdev); - if (status != 0 && status != -ENOMEM) { - /* On any other error, make netif think we're - * OK and drop the packet - */ - dev_kfree_skb_any(skb); - skb = NULL; - etdev->net_stats.tx_dropped++; - } - } - } - return status; -} - -/** - * et131x_send_packet - Do the work to send a packet - * @skb: the packet(s) to send - * @etdev: a pointer to the device's private adapter structure - * - * Return 0 in almost all cases; non-zero value in extreme hard failure only. - * - * Assumption: Send spinlock has been acquired - */ -static int et131x_send_packet(struct sk_buff *skb, - struct et131x_adapter *etdev) -{ - int status; - struct tcb *tcb = NULL; - u16 *shbufva; - unsigned long flags; - - /* All packets must have at least a MAC address and a protocol type */ - if (skb->len < ETH_HLEN) - return -EIO; - - /* Get a TCB for this packet */ - spin_lock_irqsave(&etdev->TCBReadyQLock, flags); - - tcb = etdev->tx_ring.tcb_qhead; - - if (tcb == NULL) { - spin_unlock_irqrestore(&etdev->TCBReadyQLock, flags); - return -ENOMEM; - } - - etdev->tx_ring.tcb_qhead = tcb->next; - - if (etdev->tx_ring.tcb_qhead == NULL) - etdev->tx_ring.tcb_qtail = NULL; - - spin_unlock_irqrestore(&etdev->TCBReadyQLock, flags); - - tcb->skb = skb; - - if (skb->data != NULL && skb->len - skb->data_len >= 6) { - shbufva = (u16 *) skb->data; - - if ((shbufva[0] == 0xffff) && - (shbufva[1] == 0xffff) && (shbufva[2] == 0xffff)) { - tcb->flags |= fMP_DEST_BROAD; - } else if ((shbufva[0] & 0x3) == 0x0001) { - tcb->flags |= fMP_DEST_MULTI; - } - } - - tcb->next = NULL; - - /* Call the NIC specific send handler. */ - status = nic_send_packet(etdev, tcb); - - if (status != 0) { - spin_lock_irqsave(&etdev->TCBReadyQLock, flags); - - if (etdev->tx_ring.tcb_qtail) - etdev->tx_ring.tcb_qtail->next = tcb; - else - /* Apparently ready Q is empty. */ - etdev->tx_ring.tcb_qhead = tcb; - - etdev->tx_ring.tcb_qtail = tcb; - spin_unlock_irqrestore(&etdev->TCBReadyQLock, flags); - return status; - } - WARN_ON(etdev->tx_ring.used > NUM_TCB); - return 0; -} - -/** * nic_send_packet - NIC specific send handler for version B silicon. - * @etdev: pointer to our adapter + * @adapter: pointer to our adapter * @tcb: pointer to struct tcb * * Returns 0 or errno. */ -static int nic_send_packet(struct et131x_adapter *etdev, struct tcb *tcb) +static int nic_send_packet(struct et131x_adapter *adapter, struct tcb *tcb) { u32 i; struct tx_desc desc[24]; /* 24 x 16 byte */ @@ -462,7 +331,7 @@ static int nic_send_packet(struct et131x_adapter *etdev, struct tcb *tcb) * subsystem) */ desc[frag++].addr_lo = - pci_map_single(etdev->pdev, + pci_map_single(adapter->pdev, skb->data, skb->len - skb->data_len, @@ -481,7 +350,7 @@ static int nic_send_packet(struct et131x_adapter *etdev, struct tcb *tcb) * subsystem) */ desc[frag++].addr_lo = - pci_map_single(etdev->pdev, + pci_map_single(adapter->pdev, skb->data, ((skb->len - skb->data_len) / 2), @@ -500,7 +369,7 @@ static int nic_send_packet(struct et131x_adapter *etdev, struct tcb *tcb) * subsystem) */ desc[frag++].addr_lo = - pci_map_single(etdev->pdev, + pci_map_single(adapter->pdev, skb->data + ((skb->len - skb->data_len) / 2), @@ -520,7 +389,7 @@ static int nic_send_packet(struct et131x_adapter *etdev, struct tcb *tcb) * addressable (as defined by the pci/dma subsystem) */ desc[frag++].addr_lo = - pci_map_page(etdev->pdev, + pci_map_page(adapter->pdev, frags[i - 1].page, frags[i - 1].page_offset, frags[i - 1].size, @@ -531,11 +400,11 @@ static int nic_send_packet(struct et131x_adapter *etdev, struct tcb *tcb) if (frag == 0) return -EIO; - if (etdev->linkspeed == TRUEPHY_SPEED_1000MBPS) { - if (++etdev->tx_ring.since_irq == PARM_TX_NUM_BUFS_DEF) { + if (adapter->linkspeed == TRUEPHY_SPEED_1000MBPS) { + if (++adapter->tx_ring.since_irq == PARM_TX_NUM_BUFS_DEF) { /* Last element & Interrupt flag */ desc[frag - 1].flags = 0x5; - etdev->tx_ring.since_irq = 0; + adapter->tx_ring.since_irq = 0; } else { /* Last element */ desc[frag - 1].flags = 0x1; } @@ -544,13 +413,13 @@ static int nic_send_packet(struct et131x_adapter *etdev, struct tcb *tcb) desc[0].flags |= 2; /* First element flag */ - tcb->index_start = etdev->tx_ring.send_idx; + tcb->index_start = adapter->tx_ring.send_idx; tcb->stale = 0; - spin_lock_irqsave(&etdev->send_hw_lock, flags); + spin_lock_irqsave(&adapter->send_hw_lock, flags); thiscopy = NUM_DESC_PER_RING_TX - - INDEX10(etdev->tx_ring.send_idx); + INDEX10(adapter->tx_ring.send_idx); if (thiscopy >= frag) { remainder = 0; @@ -559,87 +428,210 @@ static int nic_send_packet(struct et131x_adapter *etdev, struct tcb *tcb) remainder = frag - thiscopy; } - memcpy(etdev->tx_ring.tx_desc_ring + - INDEX10(etdev->tx_ring.send_idx), desc, + memcpy(adapter->tx_ring.tx_desc_ring + + INDEX10(adapter->tx_ring.send_idx), desc, sizeof(struct tx_desc) * thiscopy); - add_10bit(&etdev->tx_ring.send_idx, thiscopy); + add_10bit(&adapter->tx_ring.send_idx, thiscopy); - if (INDEX10(etdev->tx_ring.send_idx) == 0 || - INDEX10(etdev->tx_ring.send_idx) == NUM_DESC_PER_RING_TX) { - etdev->tx_ring.send_idx &= ~ET_DMA10_MASK; - etdev->tx_ring.send_idx ^= ET_DMA10_WRAP; + if (INDEX10(adapter->tx_ring.send_idx) == 0 || + INDEX10(adapter->tx_ring.send_idx) == NUM_DESC_PER_RING_TX) { + adapter->tx_ring.send_idx &= ~ET_DMA10_MASK; + adapter->tx_ring.send_idx ^= ET_DMA10_WRAP; } if (remainder) { - memcpy(etdev->tx_ring.tx_desc_ring, + memcpy(adapter->tx_ring.tx_desc_ring, desc + thiscopy, sizeof(struct tx_desc) * remainder); - add_10bit(&etdev->tx_ring.send_idx, remainder); + add_10bit(&adapter->tx_ring.send_idx, remainder); } - if (INDEX10(etdev->tx_ring.send_idx) == 0) { - if (etdev->tx_ring.send_idx) + if (INDEX10(adapter->tx_ring.send_idx) == 0) { + if (adapter->tx_ring.send_idx) tcb->index = NUM_DESC_PER_RING_TX - 1; else tcb->index = ET_DMA10_WRAP|(NUM_DESC_PER_RING_TX - 1); } else - tcb->index = etdev->tx_ring.send_idx - 1; + tcb->index = adapter->tx_ring.send_idx - 1; - spin_lock(&etdev->TCBSendQLock); + spin_lock(&adapter->tcb_send_qlock); - if (etdev->tx_ring.send_tail) - etdev->tx_ring.send_tail->next = tcb; + if (adapter->tx_ring.send_tail) + adapter->tx_ring.send_tail->next = tcb; else - etdev->tx_ring.send_head = tcb; + adapter->tx_ring.send_head = tcb; - etdev->tx_ring.send_tail = tcb; + adapter->tx_ring.send_tail = tcb; WARN_ON(tcb->next != NULL); - etdev->tx_ring.used++; + adapter->tx_ring.used++; - spin_unlock(&etdev->TCBSendQLock); + spin_unlock(&adapter->tcb_send_qlock); /* Write the new write pointer back to the device. */ - writel(etdev->tx_ring.send_idx, - &etdev->regs->txdma.service_request); + writel(adapter->tx_ring.send_idx, + &adapter->regs->txdma.service_request); /* For Gig only, we use Tx Interrupt coalescing. Enable the software * timer to wake us up if this packet isn't followed by N more. */ - if (etdev->linkspeed == TRUEPHY_SPEED_1000MBPS) { + if (adapter->linkspeed == TRUEPHY_SPEED_1000MBPS) { writel(PARM_TX_TIME_INT_DEF * NANO_IN_A_MICRO, - &etdev->regs->global.watchdog_timer); + &adapter->regs->global.watchdog_timer); } - spin_unlock_irqrestore(&etdev->send_hw_lock, flags); + spin_unlock_irqrestore(&adapter->send_hw_lock, flags); return 0; } +/** + * send_packet - Do the work to send a packet + * @skb: the packet(s) to send + * @adapter: a pointer to the device's private adapter structure + * + * Return 0 in almost all cases; non-zero value in extreme hard failure only. + * + * Assumption: Send spinlock has been acquired + */ +static int send_packet(struct sk_buff *skb, struct et131x_adapter *adapter) +{ + int status; + struct tcb *tcb = NULL; + u16 *shbufva; + unsigned long flags; + + /* All packets must have at least a MAC address and a protocol type */ + if (skb->len < ETH_HLEN) + return -EIO; + + /* Get a TCB for this packet */ + spin_lock_irqsave(&adapter->tcb_ready_qlock, flags); + + tcb = adapter->tx_ring.tcb_qhead; + + if (tcb == NULL) { + spin_unlock_irqrestore(&adapter->tcb_ready_qlock, flags); + return -ENOMEM; + } + + adapter->tx_ring.tcb_qhead = tcb->next; + + if (adapter->tx_ring.tcb_qhead == NULL) + adapter->tx_ring.tcb_qtail = NULL; + + spin_unlock_irqrestore(&adapter->tcb_ready_qlock, flags); + + tcb->skb = skb; + + if (skb->data != NULL && skb->len - skb->data_len >= 6) { + shbufva = (u16 *) skb->data; + + if ((shbufva[0] == 0xffff) && + (shbufva[1] == 0xffff) && (shbufva[2] == 0xffff)) { + tcb->flags |= fMP_DEST_BROAD; + } else if ((shbufva[0] & 0x3) == 0x0001) { + tcb->flags |= fMP_DEST_MULTI; + } + } + + tcb->next = NULL; + + /* Call the NIC specific send handler. */ + status = nic_send_packet(adapter, tcb); + + if (status != 0) { + spin_lock_irqsave(&adapter->tcb_ready_qlock, flags); + + if (adapter->tx_ring.tcb_qtail) + adapter->tx_ring.tcb_qtail->next = tcb; + else + /* Apparently ready Q is empty. */ + adapter->tx_ring.tcb_qhead = tcb; + + adapter->tx_ring.tcb_qtail = tcb; + spin_unlock_irqrestore(&adapter->tcb_ready_qlock, flags); + return status; + } + WARN_ON(adapter->tx_ring.used > NUM_TCB); + return 0; +} + +/** + * et131x_send_packets - This function is called by the OS to send packets + * @skb: the packet(s) to send + * @netdev:device on which to TX the above packet(s) + * + * Return 0 in almost all cases; non-zero value in extreme hard failure only + */ +int et131x_send_packets(struct sk_buff *skb, struct net_device *netdev) +{ + int status = 0; + struct et131x_adapter *adapter = NULL; + + adapter = netdev_priv(netdev); + + /* Send these packets + * + * NOTE: The Linux Tx entry point is only given one packet at a time + * to Tx, so the PacketCount and it's array used makes no sense here + */ + + /* TCB is not available */ + if (adapter->tx_ring.used >= NUM_TCB) { + /* NOTE: If there's an error on send, no need to queue the + * packet under Linux; if we just send an error up to the + * netif layer, it will resend the skb to us. + */ + status = -ENOMEM; + } else { + /* We need to see if the link is up; if it's not, make the + * netif layer think we're good and drop the packet + */ + if ((adapter->flags & fMP_ADAPTER_FAIL_SEND_MASK) || + !netif_carrier_ok(netdev)) { + dev_kfree_skb_any(skb); + skb = NULL; + + adapter->net_stats.tx_dropped++; + } else { + status = send_packet(skb, adapter); + if (status != 0 && status != -ENOMEM) { + /* On any other error, make netif think we're + * OK and drop the packet + */ + dev_kfree_skb_any(skb); + skb = NULL; + adapter->net_stats.tx_dropped++; + } + } + } + return status; +} /** - * et131x_free_send_packet - Recycle a struct tcb - * @etdev: pointer to our adapter + * free_send_packet - Recycle a struct tcb + * @adapter: pointer to our adapter * @tcb: pointer to struct tcb * * Complete the packet if necessary * Assumption - Send spinlock has been acquired */ -inline void et131x_free_send_packet(struct et131x_adapter *etdev, +static inline void free_send_packet(struct et131x_adapter *adapter, struct tcb *tcb) { unsigned long flags; struct tx_desc *desc = NULL; - struct net_device_stats *stats = &etdev->net_stats; + struct net_device_stats *stats = &adapter->net_stats; if (tcb->flags & fMP_DEST_BROAD) - atomic_inc(&etdev->stats.brdcstxmt); + atomic_inc(&adapter->stats.broadcast_pkts_xmtd); else if (tcb->flags & fMP_DEST_MULTI) - atomic_inc(&etdev->stats.multixmt); + atomic_inc(&adapter->stats.multicast_pkts_xmtd); else - atomic_inc(&etdev->stats.unixmt); + atomic_inc(&adapter->stats.unicast_pkts_xmtd); if (tcb->skb) { stats->tx_bytes += tcb->skb->len; @@ -649,10 +641,10 @@ inline void et131x_free_send_packet(struct et131x_adapter *etdev, * they point to */ do { - desc = (struct tx_desc *)(etdev->tx_ring.tx_desc_ring + + desc = (struct tx_desc *)(adapter->tx_ring.tx_desc_ring + INDEX10(tcb->index_start)); - pci_unmap_single(etdev->pdev, + pci_unmap_single(adapter->pdev, desc->addr_lo, desc->len_vlan, PCI_DMA_TODEVICE); @@ -662,7 +654,7 @@ inline void et131x_free_send_packet(struct et131x_adapter *etdev, tcb->index_start &= ~ET_DMA10_MASK; tcb->index_start ^= ET_DMA10_WRAP; } - } while (desc != (etdev->tx_ring.tx_desc_ring + + } while (desc != (adapter->tx_ring.tx_desc_ring + INDEX10(tcb->index))); dev_kfree_skb_any(tcb->skb); @@ -671,127 +663,127 @@ inline void et131x_free_send_packet(struct et131x_adapter *etdev, memset(tcb, 0, sizeof(struct tcb)); /* Add the TCB to the Ready Q */ - spin_lock_irqsave(&etdev->TCBReadyQLock, flags); + spin_lock_irqsave(&adapter->tcb_ready_qlock, flags); - etdev->net_stats.tx_packets++; + adapter->net_stats.tx_packets++; - if (etdev->tx_ring.tcb_qtail) - etdev->tx_ring.tcb_qtail->next = tcb; + if (adapter->tx_ring.tcb_qtail) + adapter->tx_ring.tcb_qtail->next = tcb; else /* Apparently ready Q is empty. */ - etdev->tx_ring.tcb_qhead = tcb; + adapter->tx_ring.tcb_qhead = tcb; - etdev->tx_ring.tcb_qtail = tcb; + adapter->tx_ring.tcb_qtail = tcb; - spin_unlock_irqrestore(&etdev->TCBReadyQLock, flags); - WARN_ON(etdev->tx_ring.used < 0); + spin_unlock_irqrestore(&adapter->tcb_ready_qlock, flags); + WARN_ON(adapter->tx_ring.used < 0); } /** * et131x_free_busy_send_packets - Free and complete the stopped active sends - * @etdev: pointer to our adapter + * @adapter: pointer to our adapter * * Assumption - Send spinlock has been acquired */ -void et131x_free_busy_send_packets(struct et131x_adapter *etdev) +void et131x_free_busy_send_packets(struct et131x_adapter *adapter) { struct tcb *tcb; unsigned long flags; u32 freed = 0; /* Any packets being sent? Check the first TCB on the send list */ - spin_lock_irqsave(&etdev->TCBSendQLock, flags); + spin_lock_irqsave(&adapter->tcb_send_qlock, flags); - tcb = etdev->tx_ring.send_head; + tcb = adapter->tx_ring.send_head; while (tcb != NULL && freed < NUM_TCB) { struct tcb *next = tcb->next; - etdev->tx_ring.send_head = next; + adapter->tx_ring.send_head = next; if (next == NULL) - etdev->tx_ring.send_tail = NULL; + adapter->tx_ring.send_tail = NULL; - etdev->tx_ring.used--; + adapter->tx_ring.used--; - spin_unlock_irqrestore(&etdev->TCBSendQLock, flags); + spin_unlock_irqrestore(&adapter->tcb_send_qlock, flags); freed++; - et131x_free_send_packet(etdev, tcb); + free_send_packet(adapter, tcb); - spin_lock_irqsave(&etdev->TCBSendQLock, flags); + spin_lock_irqsave(&adapter->tcb_send_qlock, flags); - tcb = etdev->tx_ring.send_head; + tcb = adapter->tx_ring.send_head; } WARN_ON(freed == NUM_TCB); - spin_unlock_irqrestore(&etdev->TCBSendQLock, flags); + spin_unlock_irqrestore(&adapter->tcb_send_qlock, flags); - etdev->tx_ring.used = 0; + adapter->tx_ring.used = 0; } /** * et131x_handle_send_interrupt - Interrupt handler for sending processing - * @etdev: pointer to our adapter + * @adapter: pointer to our adapter * * Re-claim the send resources, complete sends and get more to send from * the send wait queue. * * Assumption - Send spinlock has been acquired */ -void et131x_handle_send_interrupt(struct et131x_adapter *etdev) +void et131x_handle_send_interrupt(struct et131x_adapter *adapter) { unsigned long flags; u32 serviced; struct tcb *tcb; u32 index; - serviced = readl(&etdev->regs->txdma.new_service_complete); + serviced = readl(&adapter->regs->txdma.new_service_complete); index = INDEX10(serviced); /* Has the ring wrapped? Process any descriptors that do not have * the same "wrap" indicator as the current completion indicator */ - spin_lock_irqsave(&etdev->TCBSendQLock, flags); + spin_lock_irqsave(&adapter->tcb_send_qlock, flags); - tcb = etdev->tx_ring.send_head; + tcb = adapter->tx_ring.send_head; while (tcb && ((serviced ^ tcb->index) & ET_DMA10_WRAP) && index < INDEX10(tcb->index)) { - etdev->tx_ring.used--; - etdev->tx_ring.send_head = tcb->next; + adapter->tx_ring.used--; + adapter->tx_ring.send_head = tcb->next; if (tcb->next == NULL) - etdev->tx_ring.send_tail = NULL; + adapter->tx_ring.send_tail = NULL; - spin_unlock_irqrestore(&etdev->TCBSendQLock, flags); - et131x_free_send_packet(etdev, tcb); - spin_lock_irqsave(&etdev->TCBSendQLock, flags); + spin_unlock_irqrestore(&adapter->tcb_send_qlock, flags); + free_send_packet(adapter, tcb); + spin_lock_irqsave(&adapter->tcb_send_qlock, flags); /* Goto the next packet */ - tcb = etdev->tx_ring.send_head; + tcb = adapter->tx_ring.send_head; } while (tcb && !((serviced ^ tcb->index) & ET_DMA10_WRAP) && index > (tcb->index & ET_DMA10_MASK)) { - etdev->tx_ring.used--; - etdev->tx_ring.send_head = tcb->next; + adapter->tx_ring.used--; + adapter->tx_ring.send_head = tcb->next; if (tcb->next == NULL) - etdev->tx_ring.send_tail = NULL; + adapter->tx_ring.send_tail = NULL; - spin_unlock_irqrestore(&etdev->TCBSendQLock, flags); - et131x_free_send_packet(etdev, tcb); - spin_lock_irqsave(&etdev->TCBSendQLock, flags); + spin_unlock_irqrestore(&adapter->tcb_send_qlock, flags); + free_send_packet(adapter, tcb); + spin_lock_irqsave(&adapter->tcb_send_qlock, flags); /* Goto the next packet */ - tcb = etdev->tx_ring.send_head; + tcb = adapter->tx_ring.send_head; } /* Wake up the queue when we hit a low-water mark */ - if (etdev->tx_ring.used <= NUM_TCB / 3) - netif_wake_queue(etdev->netdev); + if (adapter->tx_ring.used <= NUM_TCB / 3) + netif_wake_queue(adapter->netdev); - spin_unlock_irqrestore(&etdev->TCBSendQLock, flags); + spin_unlock_irqrestore(&adapter->tcb_send_qlock, flags); } diff --git a/drivers/staging/et131x/et131x.h b/drivers/staging/et131x/et131x.h index 48ebac0..91fafc0 100644 --- a/drivers/staging/et131x/et131x.h +++ b/drivers/staging/et131x/et131x.h @@ -49,11 +49,10 @@ */ /* et131x_eeprom.c */ -int et131x_init_eeprom(struct et131x_adapter *etdev); +int et131x_init_eeprom(struct et131x_adapter *adapter); /* et131x_initpci.c */ -void ConfigGlobalRegs(struct et131x_adapter *pAdapter); -void ConfigMMCRegs(struct et131x_adapter *pAdapter); +void et131x_configure_global_regs(struct et131x_adapter *adapter); void et131x_enable_interrupts(struct et131x_adapter *adapter); void et131x_disable_interrupts(struct et131x_adapter *adapter); void et131x_align_allocated_memory(struct et131x_adapter *adapter, @@ -71,33 +70,33 @@ irqreturn_t et131x_isr(int irq, void *dev_id); void et131x_isr_handler(struct work_struct *work); /* et1310_mac.c */ -void ConfigMACRegs1(struct et131x_adapter *adapter); -void ConfigMACRegs2(struct et131x_adapter *adapter); -void ConfigRxMacRegs(struct et131x_adapter *adapter); -void ConfigTxMacRegs(struct et131x_adapter *adapter); -void ConfigMacStatRegs(struct et131x_adapter *adapter); -void ConfigFlowControl(struct et131x_adapter *adapter); -void UpdateMacStatHostCounters(struct et131x_adapter *adapter); -void HandleMacStatInterrupt(struct et131x_adapter *adapter); -void SetupDeviceForMulticast(struct et131x_adapter *adapter); -void SetupDeviceForUnicast(struct et131x_adapter *adapter); +void et1310_config_mac_regs1(struct et131x_adapter *adapter); +void et1310_config_mac_regs2(struct et131x_adapter *adapter); +void et1310_config_rxmac_regs(struct et131x_adapter *adapter); +void et1310_config_txmac_regs(struct et131x_adapter *adapter); +void et1310_config_macstat_regs(struct et131x_adapter *adapter); +void et1310_config_flow_control(struct et131x_adapter *adapter); +void et1310_update_macstat_host_counters(struct et131x_adapter *adapter); +void et1310_handle_macstat_interrupt(struct et131x_adapter *adapter); +void et1310_setup_device_for_multicast(struct et131x_adapter *adapter); +void et1310_setup_device_for_unicast(struct et131x_adapter *adapter); /* et131x_netdev.c */ struct net_device *et131x_device_alloc(void); -/* et131x_pm.c */ -void EnablePhyComa(struct et131x_adapter *adapter); -void DisablePhyComa(struct et131x_adapter *adapter); +/* et1310_pm.c */ +void et1310_enable_phy_coma(struct et131x_adapter *adapter); +void et1310_disable_phy_coma(struct et131x_adapter *adapter); -/* et131x_phy.c */ -void ET1310_PhyInit(struct et131x_adapter *adapter); -void ET1310_PhyReset(struct et131x_adapter *adapter); -void ET1310_PhyPowerDown(struct et131x_adapter *adapter, bool down); -void ET1310_PhyAdvertise1000BaseT(struct et131x_adapter *adapter, - u16 duplex); -void ET1310_PhyAccessMiBit(struct et131x_adapter *adapter, - u16 action, - u16 regnum, u16 bitnum, u8 *value); +/* et1310_phy.c */ +void et1310_phy_init(struct et131x_adapter *adapter); +void et1310_phy_reset(struct et131x_adapter *adapter); +void et1310_phy_power_down(struct et131x_adapter *adapter, bool down); +void et1310_phy_advertise_1000BaseT(struct et131x_adapter *adapter, + u16 duplex); +void et1310_phy_access_mii_bit(struct et131x_adapter *adapter, + u16 action, + u16 regnum, u16 bitnum, u8 *value); int et131x_xcvr_find(struct et131x_adapter *adapter); void et131x_setphy_normal(struct et131x_adapter *adapter); @@ -105,23 +104,18 @@ void et131x_setphy_normal(struct et131x_adapter *adapter); /* static inline function does not work because et131x_adapter is not always * defined */ -int PhyMiRead(struct et131x_adapter *adapter, u8 xcvrAddr, +int et131x_phy_mii_read(struct et131x_adapter *adapter, u8 xcvrAddr, u8 xcvrReg, u16 *value); -#define MiRead(adapter, xcvrReg, value) \ - PhyMiRead((adapter), (adapter)->stats.xcvr_addr, (xcvrReg), (value)) +#define et131x_mii_read(adapter, xcvrReg, value) \ + et131x_phy_mii_read((adapter), \ + (adapter)->stats.xcvr_addr, \ + (xcvrReg), (value)) -int32_t MiWrite(struct et131x_adapter *adapter, +int32_t et131x_mii_write(struct et131x_adapter *adapter, u8 xcvReg, u16 value); -void et131x_Mii_check(struct et131x_adapter *pAdapter, +void et131x_mii_check(struct et131x_adapter *pAdapter, u16 bmsr, u16 bmsr_ints); -/* This last is not strictly required (the driver could call the TPAL - * version instead), but this sets the adapter up correctly, and calls the - * access routine indirectly. This protects the driver from changes in TPAL. - */ -void SetPhy_10BaseTHalfDuplex(struct et131x_adapter *adapter); - - /* et1310_rx.c */ int et131x_rx_dma_memory_alloc(struct et131x_adapter *adapter); void et131x_rx_dma_memory_free(struct et131x_adapter *adapter); @@ -131,8 +125,8 @@ void et131x_rfd_resources_free(struct et131x_adapter *adapter, struct rfd *rfd); int et131x_init_recv(struct et131x_adapter *adapter); -void ConfigRxDmaRegs(struct et131x_adapter *adapter); -void SetRxDmaTimer(struct et131x_adapter *adapter); +void et131x_config_rx_dma_regs(struct et131x_adapter *adapter); +void et131x_set_rx_dma_timer(struct et131x_adapter *adapter); void et131x_rx_dma_disable(struct et131x_adapter *adapter); void et131x_rx_dma_enable(struct et131x_adapter *adapter); @@ -143,7 +137,7 @@ void et131x_handle_recv_interrupt(struct et131x_adapter *adapter); /* et131x_tx.c */ int et131x_tx_dma_memory_alloc(struct et131x_adapter *adapter); void et131x_tx_dma_memory_free(struct et131x_adapter *adapter); -void ConfigTxDmaRegs(struct et131x_adapter *adapter); +void et131x_config_tx_dma_regs(struct et131x_adapter *adapter); void et131x_init_send(struct et131x_adapter *adapter); void et131x_tx_dma_disable(struct et131x_adapter *adapter); void et131x_tx_dma_enable(struct et131x_adapter *adapter); diff --git a/drivers/staging/et131x/et131x_adapter.h b/drivers/staging/et131x/et131x_adapter.h index 408c50b..762e07c 100644 --- a/drivers/staging/et131x/et131x_adapter.h +++ b/drivers/staging/et131x/et131x_adapter.h @@ -105,40 +105,39 @@ struct ce_stats { * MUST have 32, then we'll need another way to perform atomic * operations */ - u32 unircv; /* # multicast packets received */ - atomic_t unixmt; /* # multicast packets for Tx */ - u32 multircv; /* # multicast packets received */ - atomic_t multixmt; /* # multicast packets for Tx */ - u32 brdcstrcv; /* # broadcast packets received */ - atomic_t brdcstxmt; /* # broadcast packets for Tx */ - u32 norcvbuf; /* # Rx packets discarded */ - u32 noxmtbuf; /* # Tx packets discarded */ + u32 unicast_pkts_rcvd; + atomic_t unicast_pkts_xmtd; + u32 multicast_pkts_rcvd; + atomic_t multicast_pkts_xmtd; + u32 broadcast_pkts_rcvd; + atomic_t broadcast_pkts_xmtd; + u32 rcvd_pkts_dropped; /* Transceiver state informations. */ - u8 xcvr_addr; - u32 xcvr_id; + u8 xcvr_addr; + u32 xcvr_id; /* Tx Statistics. */ - u32 tx_uflo; /* Tx Underruns */ + u32 tx_underflows; - u32 collisions; - u32 excessive_collisions; - u32 first_collision; - u32 late_collisions; - u32 max_pkt_error; - u32 tx_deferred; + u32 tx_collisions; + u32 tx_excessive_collisions; + u32 tx_first_collisions; + u32 tx_late_collisions; + u32 tx_max_pkt_errs; + u32 tx_deferred; /* Rx Statistics. */ - u32 rx_ov_flow; /* Rx Overflow */ + u32 rx_overflows; - u32 length_err; - u32 alignment_err; - u32 crc_err; - u32 code_violations; - u32 other_errors; + u32 rx_length_errs; + u32 rx_align_errs; + u32 rx_crc_errs; + u32 rx_code_violations; + u32 rx_other_errs; - u32 SynchrounousIterations; - u32 InterruptStatus; + u32 synchronous_iterations; + u32 interrupt_status; }; @@ -151,7 +150,7 @@ struct et131x_adapter { /* Flags that indicate current state of the adapter */ u32 flags; - u32 HwErrCount; + u32 hw_errs; /* Configuration */ u8 rom_addr[ETH_ALEN]; @@ -160,52 +159,46 @@ struct et131x_adapter { u8 eeprom_data[2]; /* Spinlocks */ - spinlock_t Lock; + spinlock_t lock; - spinlock_t TCBSendQLock; - spinlock_t TCBReadyQLock; + spinlock_t tcb_send_qlock; + spinlock_t tcb_ready_qlock; spinlock_t send_hw_lock; spinlock_t rcv_lock; - spinlock_t RcvPendLock; - spinlock_t FbrLock; + spinlock_t rcv_pend_lock; + spinlock_t fbr_lock; - spinlock_t PHYLock; + spinlock_t phy_lock; /* Packet Filter and look ahead size */ - u32 PacketFilter; + u32 packet_filter; u32 linkspeed; u32 duplex_mode; /* multicast list */ - u32 MCAddressCount; - u8 MCList[NIC_MAX_MCAST_LIST][ETH_ALEN]; + u32 multicast_addr_count; + u8 multicast_list[NIC_MAX_MCAST_LIST][ETH_ALEN]; /* Pointer to the device's PCI register space */ struct address_map __iomem *regs; /* Registry parameters */ - u8 SpeedDuplex; /* speed/duplex */ + u8 speed_duplex; /* speed/duplex */ u8 wanted_flow; /* Flow we want for 802.3x flow control */ - u8 RegistryPhyComa; /* Phy Coma mode enable/disable */ + u8 registry_phy_coma; /* Phy Coma mode enable/disable */ - u32 RegistryRxMemEnd; /* Size of internal rx memory */ - u32 RegistryJumboPacket; /* Max supported ethernet packet size */ + u32 registry_rx_mem_end; /* Size of internal rx memory */ + u32 registry_jumbo_packet; /* Max supported ethernet packet size */ /* Derived from the registry: */ - u8 AiForceDpx; /* duplex setting */ - u16 AiForceSpeed; /* 'Speed', user over-ride of line speed */ + u8 ai_force_duplex; /* duplex setting */ + u16 ai_force_speed; /* 'Speed', user over-ride of line speed */ u8 flowcontrol; /* flow control validated by the far-end */ - enum { - NETIF_STATUS_INVALID = 0, - NETIF_STATUS_MEDIA_CONNECT, - NETIF_STATUS_MEDIA_DISCONNECT, - NETIF_STATUS_MAX - } MediaState; /* Minimize init-time */ - struct timer_list ErrorTimer; + struct timer_list error_timer; /* variable putting the phy into coma mode when boot up with no cable * plugged in after 5 seconds @@ -219,7 +212,7 @@ struct et131x_adapter { u16 pdown_speed; u8 pdown_duplex; - u32 CachedMaskValue; + u32 cached_mask_value; /* Xcvr status at last poll */ u16 bmsr; @@ -231,8 +224,8 @@ struct et131x_adapter { struct rx_ring rx_ring; /* Loopback specifics */ - u8 ReplicaPhyLoopbk; /* Replica Enable */ - u8 ReplicaPhyLoopbkPF; /* Replica Enable Pass/Fail */ + u8 replica_phy_loopbk; /* Replica Enable */ + u8 replica_phy_loopbk_passfail; /* Replica Enable Pass/Fail */ /* Stats */ struct ce_stats stats; diff --git a/drivers/staging/et131x/et131x_initpci.c b/drivers/staging/et131x/et131x_initpci.c index 8c8d6b8..072cfb5 100644 --- a/drivers/staging/et131x/et131x_initpci.c +++ b/drivers/staging/et131x/et131x_initpci.c @@ -263,76 +263,55 @@ static int et131x_pci_init(struct et131x_adapter *adapter, */ void et131x_error_timer_handler(unsigned long data) { - struct et131x_adapter *etdev = (struct et131x_adapter *) data; + struct et131x_adapter *adapter = (struct et131x_adapter *) data; u32 pm_csr; - pm_csr = readl(&etdev->regs->global.pm_csr); + pm_csr = readl(&adapter->regs->global.pm_csr); if ((pm_csr & ET_PM_PHY_SW_COMA) == 0) - UpdateMacStatHostCounters(etdev); + et1310_update_macstat_host_counters(adapter); else - dev_err(&etdev->pdev->dev, + dev_err(&adapter->pdev->dev, "No interrupts, in PHY coma, pm_csr = 0x%x\n", pm_csr); - if (!(etdev->bmsr & MI_BMSR_LINK_STATUS) && - etdev->RegistryPhyComa && - etdev->boot_coma < 11) { - etdev->boot_coma++; + if (!(adapter->bmsr & MI_BMSR_LINK_STATUS) && + adapter->registry_phy_coma && + adapter->boot_coma < 11) { + adapter->boot_coma++; } - if (etdev->boot_coma == 10) { - if (!(etdev->bmsr & MI_BMSR_LINK_STATUS) - && etdev->RegistryPhyComa) { + if (adapter->boot_coma == 10) { + if (!(adapter->bmsr & MI_BMSR_LINK_STATUS) + && adapter->registry_phy_coma) { if ((pm_csr & ET_PM_PHY_SW_COMA) == 0) { /* NOTE - This was originally a 'sync with * interrupt'. How to do that under Linux? */ - et131x_enable_interrupts(etdev); - EnablePhyComa(etdev); + et131x_enable_interrupts(adapter); + et1310_enable_phy_coma(adapter); } } } /* This is a periodic timer, so reschedule */ - mod_timer(&etdev->ErrorTimer, jiffies + + mod_timer(&adapter->error_timer, jiffies + TX_ERROR_PERIOD * HZ / 1000); } /** - * et131x_link_detection_handler - * - * Timer function for link up at driver load time - */ -void et131x_link_detection_handler(unsigned long data) -{ - struct et131x_adapter *etdev = (struct et131x_adapter *) data; - unsigned long flags; - - if (etdev->MediaState == 0) { - spin_lock_irqsave(&etdev->Lock, flags); - - etdev->MediaState = NETIF_STATUS_MEDIA_DISCONNECT; - - spin_unlock_irqrestore(&etdev->Lock, flags); - - netif_carrier_off(etdev->netdev); - } -} - -/** * et131x_configure_global_regs - configure JAGCore global regs - * @etdev: pointer to our adapter structure + * @adapter: pointer to our adapter structure * * Used to configure the global registers on the JAGCore */ -void ConfigGlobalRegs(struct et131x_adapter *etdev) +void et131x_configure_global_regs(struct et131x_adapter *adapter) { - struct global_regs __iomem *regs = &etdev->regs->global; + struct global_regs __iomem *regs = &adapter->regs->global; writel(0, ®s->rxq_start_addr); writel(INTERNAL_MEM_SIZE - 1, ®s->txq_end_addr); - if (etdev->RegistryJumboPacket < 2048) { + if (adapter->registry_jumbo_packet < 2048) { /* Tx / RxDMA and Tx/Rx MAC interfaces have a 1k word * block of RAM that the driver can split between Tx * and Rx as it desires. Our default is to split it @@ -340,7 +319,7 @@ void ConfigGlobalRegs(struct et131x_adapter *etdev) */ writel(PARM_RX_MEM_END_DEF, ®s->rxq_end_addr); writel(PARM_RX_MEM_END_DEF + 1, ®s->txq_start_addr); - } else if (etdev->RegistryJumboPacket < 8192) { + } else if (adapter->registry_jumbo_packet < 8192) { /* For jumbo packets > 2k but < 8k, split 50-50. */ writel(INTERNAL_MEM_RX_OFFSET, ®s->rxq_end_addr); writel(INTERNAL_MEM_RX_OFFSET + 1, ®s->txq_start_addr); @@ -366,63 +345,62 @@ void ConfigGlobalRegs(struct et131x_adapter *etdev) writel(0, ®s->watchdog_timer); } - /** * et131x_adapter_setup - Set the adapter up as per cassini+ documentation * @adapter: pointer to our private adapter structure * * Returns 0 on success, errno on failure (as defined in errno.h) */ -int et131x_adapter_setup(struct et131x_adapter *etdev) +int et131x_adapter_setup(struct et131x_adapter *adapter) { int status = 0; /* Configure the JAGCore */ - ConfigGlobalRegs(etdev); + et131x_configure_global_regs(adapter); - ConfigMACRegs1(etdev); + et1310_config_mac_regs1(adapter); /* Configure the MMC registers */ /* All we need to do is initialize the Memory Control Register */ - writel(ET_MMC_ENABLE, &etdev->regs->mmc.mmc_ctrl); + writel(ET_MMC_ENABLE, &adapter->regs->mmc.mmc_ctrl); - ConfigRxMacRegs(etdev); - ConfigTxMacRegs(etdev); + et1310_config_rxmac_regs(adapter); + et1310_config_txmac_regs(adapter); - ConfigRxDmaRegs(etdev); - ConfigTxDmaRegs(etdev); + et131x_config_rx_dma_regs(adapter); + et131x_config_tx_dma_regs(adapter); - ConfigMacStatRegs(etdev); + et1310_config_macstat_regs(adapter); /* Move the following code to Timer function?? */ - status = et131x_xcvr_find(etdev); + status = et131x_xcvr_find(adapter); if (status != 0) - dev_warn(&etdev->pdev->dev, "Could not find the xcvr\n"); + dev_warn(&adapter->pdev->dev, "Could not find the xcvr\n"); /* Prepare the TRUEPHY library. */ - ET1310_PhyInit(etdev); + et1310_phy_init(adapter); /* Reset the phy now so changes take place */ - ET1310_PhyReset(etdev); + et1310_phy_reset(adapter); /* Power down PHY */ - ET1310_PhyPowerDown(etdev, 1); + et1310_phy_power_down(adapter, 1); /* * We need to turn off 1000 base half dulplex, the mac does not * support it. For the 10/100 part, turn off all gig advertisement */ - if (etdev->pdev->device != ET131X_PCI_DEVICE_ID_FAST) - ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_FULL); + if (adapter->pdev->device != ET131X_PCI_DEVICE_ID_FAST) + et1310_phy_advertise_1000BaseT(adapter, TRUEPHY_ADV_DUPLEX_FULL); else - ET1310_PhyAdvertise1000BaseT(etdev, TRUEPHY_ADV_DUPLEX_NONE); + et1310_phy_advertise_1000BaseT(adapter, TRUEPHY_ADV_DUPLEX_NONE); /* Power up PHY */ - ET1310_PhyPowerDown(etdev, 0); + et1310_phy_power_down(adapter, 0); - et131x_setphy_normal(etdev); -; return status; + et131x_setphy_normal(adapter); + return status; } /** @@ -517,18 +495,14 @@ void et131x_adapter_memory_free(struct et131x_adapter *adapter) et131x_rx_dma_memory_free(adapter); } - - /** * et131x_adapter_init - * @etdev: pointer to the private adapter struct + * @adapter: pointer to the private adapter struct * @pdev: pointer to the PCI device * * Initialize the data structures for the et131x_adapter object and link * them together with the platform provided device structures. */ - - static struct et131x_adapter *et131x_adapter_init(struct net_device *netdev, struct pci_dev *pdev) { @@ -536,43 +510,43 @@ static struct et131x_adapter *et131x_adapter_init(struct net_device *netdev, static const u8 duplex[] = { 0, 1, 2, 1, 2, 2 }; static const u16 speed[] = { 0, 10, 10, 100, 100, 1000 }; - struct et131x_adapter *etdev; + struct et131x_adapter *adapter; /* Setup the fundamental net_device and private adapter structure * elements */ SET_NETDEV_DEV(netdev, &pdev->dev); /* Allocate private adapter struct and copy in relevant information */ - etdev = netdev_priv(netdev); - etdev->pdev = pci_dev_get(pdev); - etdev->netdev = netdev; + adapter = netdev_priv(netdev); + adapter->pdev = pci_dev_get(pdev); + adapter->netdev = netdev; /* Do the same for the netdev struct */ netdev->irq = pdev->irq; netdev->base_addr = pci_resource_start(pdev, 0); /* Initialize spinlocks here */ - spin_lock_init(&etdev->Lock); - spin_lock_init(&etdev->TCBSendQLock); - spin_lock_init(&etdev->TCBReadyQLock); - spin_lock_init(&etdev->send_hw_lock); - spin_lock_init(&etdev->rcv_lock); - spin_lock_init(&etdev->RcvPendLock); - spin_lock_init(&etdev->FbrLock); - spin_lock_init(&etdev->PHYLock); + spin_lock_init(&adapter->lock); + spin_lock_init(&adapter->tcb_send_qlock); + spin_lock_init(&adapter->tcb_ready_qlock); + spin_lock_init(&adapter->send_hw_lock); + spin_lock_init(&adapter->rcv_lock); + spin_lock_init(&adapter->rcv_pend_lock); + spin_lock_init(&adapter->fbr_lock); + spin_lock_init(&adapter->phy_lock); /* Parse configuration parameters into the private adapter struct */ if (et131x_speed_set) - dev_info(&etdev->pdev->dev, + dev_info(&adapter->pdev->dev, "Speed set manually to : %d\n", et131x_speed_set); - etdev->SpeedDuplex = et131x_speed_set; - etdev->RegistryJumboPacket = 1514; /* 1514-9216 */ + adapter->speed_duplex = et131x_speed_set; + adapter->registry_jumbo_packet = 1514; /* 1514-9216 */ /* Set the MAC address to a default */ - memcpy(etdev->addr, default_mac, ETH_ALEN); + memcpy(adapter->addr, default_mac, ETH_ALEN); - /* Decode SpeedDuplex + /* Decode speed_duplex * * Set up as if we are auto negotiating always and then change if we * go into force mode @@ -580,14 +554,14 @@ static struct et131x_adapter *et131x_adapter_init(struct net_device *netdev, * If we are the 10/100 device, and gigabit is somehow requested then * knock it down to 100 full. */ - if (etdev->pdev->device == ET131X_PCI_DEVICE_ID_FAST && - etdev->SpeedDuplex == 5) - etdev->SpeedDuplex = 4; + if (adapter->pdev->device == ET131X_PCI_DEVICE_ID_FAST && + adapter->speed_duplex == 5) + adapter->speed_duplex = 4; - etdev->AiForceSpeed = speed[etdev->SpeedDuplex]; - etdev->AiForceDpx = duplex[etdev->SpeedDuplex]; /* Auto FDX */ + adapter->ai_force_speed = speed[adapter->speed_duplex]; + adapter->ai_force_duplex = duplex[adapter->speed_duplex]; /* Auto FDX */ - return etdev; + return adapter; } /** @@ -602,7 +576,6 @@ static struct et131x_adapter *et131x_adapter_init(struct net_device *netdev, * contained in the pci_device_id table. This routine is the equivalent to * a device insertion routine. */ - static int __devinit et131x_pci_setup(struct pci_dev *pdev, const struct pci_device_id *ent) { @@ -717,14 +690,14 @@ static int __devinit et131x_pci_setup(struct pci_dev *pdev, et131x_adapter_setup(adapter); /* Create a timer to count errors received by the NIC */ - init_timer(&adapter->ErrorTimer); + init_timer(&adapter->error_timer); - adapter->ErrorTimer.expires = jiffies + TX_ERROR_PERIOD * HZ / 1000; - adapter->ErrorTimer.function = et131x_error_timer_handler; - adapter->ErrorTimer.data = (unsigned long)adapter; + adapter->error_timer.expires = jiffies + TX_ERROR_PERIOD * HZ / 1000; + adapter->error_timer.function = et131x_error_timer_handler; + adapter->error_timer.data = (unsigned long)adapter; /* Initialize link state */ - et131x_link_detection_handler((unsigned long)adapter); + netif_carrier_off(adapter->netdev); /* Initialize variable for counting how long we do not have link status */ @@ -774,7 +747,6 @@ err_disable: * PCI subsystem detects that a PCI device which matches the information * contained in the pci_device_id table has been removed. */ - static void __devexit et131x_pci_remove(struct pci_dev *pdev) { struct net_device *netdev; @@ -815,7 +787,6 @@ static struct pci_driver et131x_driver = { .resume = NULL, /* et131x_pci_resume */ }; - /** * et131x_init_module - The "main" entry point called on driver initialization * diff --git a/drivers/staging/et131x/et131x_isr.c b/drivers/staging/et131x/et131x_isr.c index 9c33209..7cfd213 100644 --- a/drivers/staging/et131x/et131x_isr.c +++ b/drivers/staging/et131x/et131x_isr.c @@ -124,7 +124,7 @@ void et131x_enable_interrupts(struct et131x_adapter *adapter) else mask = INT_MASK_ENABLE_NO_FLOW; - adapter->CachedMaskValue = mask; + adapter->cached_mask_value = mask; writel(mask, &adapter->regs->global.int_mask); } @@ -138,7 +138,7 @@ void et131x_enable_interrupts(struct et131x_adapter *adapter) void et131x_disable_interrupts(struct et131x_adapter *adapter) { /* Disable all global interrupts */ - adapter->CachedMaskValue = INT_MASK_DISABLE; + adapter->cached_mask_value = INT_MASK_DISABLE; writel(INT_MASK_DISABLE, &adapter->regs->global.int_mask); } @@ -200,7 +200,7 @@ irqreturn_t et131x_isr(int irq, void *dev_id) if (++tcb->stale > 1) status |= ET_INTR_TXDMA_ISR; - if (adapter->rx_ring.UnfinishedReceives) + if (adapter->rx_ring.unfinished_receives) status |= ET_INTR_RXDMA_XFR_DONE; else if (tcb == NULL) writel(0, &adapter->regs->global.watchdog_timer); @@ -222,7 +222,7 @@ irqreturn_t et131x_isr(int irq, void *dev_id) * DPC. We will clear the software copy of that in that * routine. */ - adapter->stats.InterruptStatus = status; + adapter->stats.interrupt_status = status; /* Schedule the ISR handler as a bottom-half task in the * kernel's tq_immediate queue, and mark the queue for @@ -242,10 +242,10 @@ out: */ void et131x_isr_handler(struct work_struct *work) { - struct et131x_adapter *etdev = + struct et131x_adapter *adapter = container_of(work, struct et131x_adapter, task); - u32 status = etdev->stats.InterruptStatus; - struct address_map __iomem *iomem = etdev->regs; + u32 status = adapter->stats.interrupt_status; + struct address_map __iomem *iomem = adapter->regs; /* * These first two are by far the most common. Once handled, we clear @@ -254,11 +254,11 @@ void et131x_isr_handler(struct work_struct *work) */ /* Handle all the completed Transmit interrupts */ if (status & ET_INTR_TXDMA_ISR) - et131x_handle_send_interrupt(etdev); + et131x_handle_send_interrupt(adapter); /* Handle all the completed Receives interrupts */ if (status & ET_INTR_RXDMA_XFR_DONE) - et131x_handle_recv_interrupt(etdev); + et131x_handle_recv_interrupt(adapter); status &= 0xffffffd7; @@ -270,7 +270,7 @@ void et131x_isr_handler(struct work_struct *work) /* Following read also clears the register (COR) */ txdma_err = readl(&iomem->txdma.tx_dma_error); - dev_warn(&etdev->pdev->dev, + dev_warn(&adapter->pdev->dev, "TXDMA_ERR interrupt, error = %d\n", txdma_err); } @@ -295,8 +295,8 @@ void et131x_isr_handler(struct work_struct *work) /* If the user has flow control on, then we will * send a pause packet, otherwise just exit */ - if (etdev->flowcontrol == FLOW_TXONLY || - etdev->flowcontrol == FLOW_BOTH) { + if (adapter->flowcontrol == FLOW_TXONLY || + adapter->flowcontrol == FLOW_BOTH) { u32 pm_csr; /* Tell the device to send a pause packet via @@ -345,7 +345,7 @@ void et131x_isr_handler(struct work_struct *work) */ /* TRAP();*/ - dev_warn(&etdev->pdev->dev, + dev_warn(&adapter->pdev->dev, "RxDMA_ERR interrupt, error %x\n", readl(&iomem->txmac.tx_test)); } @@ -359,7 +359,7 @@ void et131x_isr_handler(struct work_struct *work) * message when we are in DBG mode, otherwise we * will ignore it. */ - dev_err(&etdev->pdev->dev, "WAKE_ON_LAN interrupt\n"); + dev_err(&adapter->pdev->dev, "WAKE_ON_LAN interrupt\n"); } /* Handle the PHY interrupt */ @@ -379,25 +379,26 @@ void et131x_isr_handler(struct work_struct *work) * so, disable it because we will not be able * to read PHY values until we are out. */ - DisablePhyComa(etdev); + et1310_disable_phy_coma(adapter); } /* Read the PHY ISR to clear the reason for the * interrupt. */ - MiRead(etdev, (uint8_t) offsetof(struct mi_regs, isr), - &myisr); + et131x_mii_read(adapter, + (uint8_t) offsetof(struct mi_regs, isr), + &myisr); - if (!etdev->ReplicaPhyLoopbk) { - MiRead(etdev, + if (!adapter->replica_phy_loopbk) { + et131x_mii_read(adapter, (uint8_t) offsetof(struct mi_regs, bmsr), &bmsr_data); - bmsr_ints = etdev->bmsr ^ bmsr_data; - etdev->bmsr = bmsr_data; + bmsr_ints = adapter->bmsr ^ bmsr_data; + adapter->bmsr = bmsr_data; /* Do all the cable in / cable out stuff */ - et131x_Mii_check(etdev, bmsr_data, bmsr_ints); + et131x_mii_check(adapter, bmsr_data, bmsr_ints); } } @@ -415,7 +416,7 @@ void et131x_isr_handler(struct work_struct *work) * a nutshell, the whole Tx path will have to be reset * and re-configured afterwards. */ - dev_warn(&etdev->pdev->dev, + dev_warn(&adapter->pdev->dev, "TXMAC interrupt, error 0x%08x\n", err); @@ -433,14 +434,14 @@ void et131x_isr_handler(struct work_struct *work) * set the flag to cause us to reset so we can solve * this issue. */ - /* MP_SET_FLAG( etdev, + /* MP_SET_FLAG( adapter, fMP_ADAPTER_HARDWARE_ERROR); */ - dev_warn(&etdev->pdev->dev, + dev_warn(&adapter->pdev->dev, "RXMAC interrupt, error 0x%08x. Requesting reset\n", readl(&iomem->rxmac.err_reg)); - dev_warn(&etdev->pdev->dev, + dev_warn(&adapter->pdev->dev, "Enable 0x%08x, Diag 0x%08x\n", readl(&iomem->rxmac.ctrl), readl(&iomem->rxmac.rxq_diag)); @@ -460,7 +461,7 @@ void et131x_isr_handler(struct work_struct *work) * to maintain the top, software managed bits of the * counter(s). */ - HandleMacStatInterrupt(etdev); + et1310_handle_macstat_interrupt(adapter); } /* Handle SLV Timeout Interrupt */ @@ -476,5 +477,5 @@ void et131x_isr_handler(struct work_struct *work) */ } } - et131x_enable_interrupts(etdev); + et131x_enable_interrupts(adapter); } diff --git a/drivers/staging/et131x/et131x_netdev.c b/drivers/staging/et131x/et131x_netdev.c index 5f25bba..7555a24 100644 --- a/drivers/staging/et131x/et131x_netdev.c +++ b/drivers/staging/et131x/et131x_netdev.c @@ -100,15 +100,18 @@ static struct net_device_stats *et131x_stats(struct net_device *netdev) struct net_device_stats *stats = &adapter->net_stats; struct ce_stats *devstat = &adapter->stats; - stats->rx_errors = devstat->length_err + devstat->alignment_err + - devstat->crc_err + devstat->code_violations + devstat->other_errors; - stats->tx_errors = devstat->max_pkt_error; - stats->multicast = devstat->multircv; - stats->collisions = devstat->collisions; - - stats->rx_length_errors = devstat->length_err; - stats->rx_over_errors = devstat->rx_ov_flow; - stats->rx_crc_errors = devstat->crc_err; + stats->rx_errors = devstat->rx_length_errs + + devstat->rx_align_errs + + devstat->rx_crc_errs + + devstat->rx_code_violations + + devstat->rx_other_errs; + stats->tx_errors = devstat->tx_max_pkt_errs; + stats->multicast = devstat->multicast_pkts_rcvd; + stats->collisions = devstat->tx_collisions; + + stats->rx_length_errors = devstat->rx_length_errs; + stats->rx_over_errors = devstat->rx_overflows; + stats->rx_crc_errors = devstat->rx_crc_errs; /* NOTE: These stats don't have corresponding values in CE_STATS, * so we're going to have to update these directly from within the @@ -144,13 +147,13 @@ int et131x_open(struct net_device *netdev) struct et131x_adapter *adapter = netdev_priv(netdev); /* Start the timer to track NIC errors */ - add_timer(&adapter->ErrorTimer); + add_timer(&adapter->error_timer); /* Register our IRQ */ result = request_irq(netdev->irq, et131x_isr, IRQF_SHARED, netdev->name, netdev); if (result) { - dev_err(&adapter->pdev->dev, "c ould not register IRQ %d\n", + dev_err(&adapter->pdev->dev, "could not register IRQ %d\n", netdev->irq); return result; } @@ -179,6 +182,9 @@ int et131x_close(struct net_device *netdev) { struct et131x_adapter *adapter = netdev_priv(netdev); + /* Save the timestamp for the TX watchdog, prevent a timeout */ + netdev->trans_start = jiffies; + /* First thing is to stop the queue */ netif_stop_queue(netdev); @@ -194,7 +200,7 @@ int et131x_close(struct net_device *netdev) free_irq(netdev->irq, netdev); /* Stop the error timer */ - del_timer_sync(&adapter->ErrorTimer); + del_timer_sync(&adapter->error_timer); return 0; } @@ -209,19 +215,19 @@ int et131x_close(struct net_device *netdev) int et131x_ioctl_mii(struct net_device *netdev, struct ifreq *reqbuf, int cmd) { int status = 0; - struct et131x_adapter *etdev = netdev_priv(netdev); + struct et131x_adapter *adapter = netdev_priv(netdev); struct mii_ioctl_data *data = if_mii(reqbuf); switch (cmd) { case SIOCGMIIPHY: - data->phy_id = etdev->stats.xcvr_addr; + data->phy_id = adapter->stats.xcvr_addr; break; case SIOCGMIIREG: if (!capable(CAP_NET_ADMIN)) status = -EPERM; else - status = MiRead(etdev, + status = et131x_mii_read(adapter, data->reg_num, &data->val_out); break; @@ -229,7 +235,7 @@ int et131x_ioctl_mii(struct net_device *netdev, struct ifreq *reqbuf, int cmd) if (!capable(CAP_NET_ADMIN)) status = -EPERM; else - status = MiWrite(etdev, data->reg_num, + status = et131x_mii_write(adapter, data->reg_num, data->val_in); break; @@ -275,7 +281,7 @@ int et131x_ioctl(struct net_device *netdev, struct ifreq *reqbuf, int cmd) int et131x_set_packet_filter(struct et131x_adapter *adapter) { int status = 0; - uint32_t filter = adapter->PacketFilter; + uint32_t filter = adapter->packet_filter; u32 ctrl; u32 pf_ctrl; @@ -301,14 +307,14 @@ int et131x_set_packet_filter(struct et131x_adapter *adapter) if (filter & ET131X_PACKET_TYPE_ALL_MULTICAST) pf_ctrl &= ~2; /* Multicast filter bit */ else { - SetupDeviceForMulticast(adapter); + et1310_setup_device_for_multicast(adapter); pf_ctrl |= 2; ctrl &= ~0x04; } /* Set us up with Unicast packet filtering */ if (filter & ET131X_PACKET_TYPE_DIRECTED) { - SetupDeviceForUnicast(adapter); + et1310_setup_device_for_unicast(adapter); pf_ctrl |= 4; ctrl &= ~0x04; } @@ -337,67 +343,67 @@ int et131x_set_packet_filter(struct et131x_adapter *adapter) void et131x_multicast(struct net_device *netdev) { struct et131x_adapter *adapter = netdev_priv(netdev); - uint32_t PacketFilter = 0; + uint32_t packet_filter = 0; unsigned long flags; struct netdev_hw_addr *ha; int i; - spin_lock_irqsave(&adapter->Lock, flags); + spin_lock_irqsave(&adapter->lock, flags); /* Before we modify the platform-independent filter flags, store them * locally. This allows us to determine if anything's changed and if * we even need to bother the hardware */ - PacketFilter = adapter->PacketFilter; + packet_filter = adapter->packet_filter; /* Clear the 'multicast' flag locally; because we only have a single * flag to check multicast, and multiple multicast addresses can be * set, this is the easiest way to determine if more than one * multicast address is being set. */ - PacketFilter &= ~ET131X_PACKET_TYPE_MULTICAST; + packet_filter &= ~ET131X_PACKET_TYPE_MULTICAST; /* Check the net_device flags and set the device independent flags * accordingly */ if (netdev->flags & IFF_PROMISC) - adapter->PacketFilter |= ET131X_PACKET_TYPE_PROMISCUOUS; + adapter->packet_filter |= ET131X_PACKET_TYPE_PROMISCUOUS; else - adapter->PacketFilter &= ~ET131X_PACKET_TYPE_PROMISCUOUS; + adapter->packet_filter &= ~ET131X_PACKET_TYPE_PROMISCUOUS; if (netdev->flags & IFF_ALLMULTI) - adapter->PacketFilter |= ET131X_PACKET_TYPE_ALL_MULTICAST; + adapter->packet_filter |= ET131X_PACKET_TYPE_ALL_MULTICAST; if (netdev_mc_count(netdev) > NIC_MAX_MCAST_LIST) - adapter->PacketFilter |= ET131X_PACKET_TYPE_ALL_MULTICAST; + adapter->packet_filter |= ET131X_PACKET_TYPE_ALL_MULTICAST; if (netdev_mc_count(netdev) < 1) { - adapter->PacketFilter &= ~ET131X_PACKET_TYPE_ALL_MULTICAST; - adapter->PacketFilter &= ~ET131X_PACKET_TYPE_MULTICAST; + adapter->packet_filter &= ~ET131X_PACKET_TYPE_ALL_MULTICAST; + adapter->packet_filter &= ~ET131X_PACKET_TYPE_MULTICAST; } else - adapter->PacketFilter |= ET131X_PACKET_TYPE_MULTICAST; + adapter->packet_filter |= ET131X_PACKET_TYPE_MULTICAST; /* Set values in the private adapter struct */ i = 0; netdev_for_each_mc_addr(ha, netdev) { if (i == NIC_MAX_MCAST_LIST) break; - memcpy(adapter->MCList[i++], ha->addr, ETH_ALEN); + memcpy(adapter->multicast_list[i++], ha->addr, ETH_ALEN); } - adapter->MCAddressCount = i; + adapter->multicast_addr_count = i; /* Are the new flags different from the previous ones? If not, then no * action is required * - * NOTE - This block will always update the MCList with the hardware, - * even if the addresses aren't the same. + * NOTE - This block will always update the multicast_list with the + * hardware, even if the addresses aren't the same. */ - if (PacketFilter != adapter->PacketFilter) { + if (packet_filter != adapter->packet_filter) { /* Call the device's filter function */ et131x_set_packet_filter(adapter); } - spin_unlock_irqrestore(&adapter->Lock, flags); + spin_unlock_irqrestore(&adapter->lock, flags); } /** @@ -442,47 +448,70 @@ int et131x_tx(struct sk_buff *skb, struct net_device *netdev) */ void et131x_tx_timeout(struct net_device *netdev) { - struct et131x_adapter *etdev = netdev_priv(netdev); + struct et131x_adapter *adapter = netdev_priv(netdev); struct tcb *tcb; unsigned long flags; + /* If the device is closed, ignore the timeout */ + if (~(adapter->flags & fMP_ADAPTER_INTERRUPT_IN_USE)); + return; + /* Any nonrecoverable hardware error? * Checks adapter->flags for any failure in phy reading */ - if (etdev->flags & fMP_ADAPTER_NON_RECOVER_ERROR) + if (adapter->flags & fMP_ADAPTER_NON_RECOVER_ERROR) return; /* Hardware failure? */ - if (etdev->flags & fMP_ADAPTER_HARDWARE_ERROR) { - dev_err(&etdev->pdev->dev, "hardware error - reset\n"); + if (adapter->flags & fMP_ADAPTER_HARDWARE_ERROR) { + dev_err(&adapter->pdev->dev, "hardware error - reset\n"); return; } /* Is send stuck? */ - spin_lock_irqsave(&etdev->TCBSendQLock, flags); + spin_lock_irqsave(&adapter->tcb_send_qlock, flags); - tcb = etdev->tx_ring.send_head; + tcb = adapter->tx_ring.send_head; if (tcb != NULL) { tcb->count++; if (tcb->count > NIC_SEND_HANG_THRESHOLD) { - spin_unlock_irqrestore(&etdev->TCBSendQLock, + spin_unlock_irqrestore(&adapter->tcb_send_qlock, flags); - dev_warn(&etdev->pdev->dev, + dev_warn(&adapter->pdev->dev, "Send stuck - reset. tcb->WrIndex %x, flags 0x%08x\n", tcb->index, tcb->flags); - et131x_close(netdev); - et131x_open(netdev); + adapter->net_stats.tx_errors++; + /* perform reset */ + /* First thing is to stop the queue */ + netif_stop_queue(netdev); + + /* Stop the Tx and Rx DMA engines */ + et131x_rx_dma_disable(adapter); + et131x_tx_dma_disable(adapter); + + /* Disable device interrupts */ + et131x_disable_interrupts(adapter); + + /* Enable the Tx and Rx DMA engines (if not already enabled) */ + et131x_rx_dma_enable(adapter); + et131x_tx_dma_enable(adapter); + + /* Enable device interrupts */ + et131x_enable_interrupts(adapter); + + /* We're ready to move some data, so start the queue */ + netif_start_queue(netdev); return; } } - spin_unlock_irqrestore(&etdev->TCBSendQLock, flags); + spin_unlock_irqrestore(&adapter->tcb_send_qlock, flags); } /** @@ -520,7 +549,7 @@ int et131x_change_mtu(struct net_device *netdev, int new_mtu) et131x_adapter_memory_free(adapter); /* Set the config parameter for Jumbo Packet support */ - adapter->RegistryJumboPacket = new_mtu + 14; + adapter->registry_jumbo_packet = new_mtu + 14; et131x_soft_reset(adapter); /* Alloc and init Rx DMA memory */ @@ -590,7 +619,6 @@ int et131x_set_mac_addr(struct net_device *netdev, void *new_mac) /* Set the new MAC */ /* netdev->set_mac_address = &new_mac; */ - /* netdev->mtu = new_mtu; */ memcpy(netdev->dev_addr, address->sa_data, netdev->addr_len); @@ -600,10 +628,6 @@ int et131x_set_mac_addr(struct net_device *netdev, void *new_mac) /* Free Rx DMA memory */ et131x_adapter_memory_free(adapter); - /* Set the config parameter for Jumbo Packet support */ - /* adapter->RegistryJumboPacket = new_mtu + 14; */ - /* blux: not needet here, we'll change the MAC */ - et131x_soft_reset(adapter); /* Alloc and init Rx DMA memory */ @@ -668,13 +692,12 @@ struct net_device *et131x_device_alloc(void) return NULL; } - /* Setup the function registration table (and other data) for a + /* + * Setup the function registration table (and other data) for a * net_device */ - /* netdev->init = &et131x_init; */ - /* netdev->set_config = &et131x_config; */ netdev->watchdog_timeo = ET131X_TX_TIMEOUT; - netdev->netdev_ops = &et131x_netdev_ops; + netdev->netdev_ops = &et131x_netdev_ops; /* netdev->ethtool_ops = &et131x_ethtool_ops; */ diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000.h b/drivers/staging/ft1000/ft1000-pcmcia/ft1000.h index 3b0130f..adb436e 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000.h +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000.h @@ -68,6 +68,16 @@ struct ft1000_info { char netdevname[IFNAMSIZ]; }; +struct pcmcia_device; +struct net_device; +extern struct net_device *init_ft1000_card(struct pcmcia_device *link, + void *ft1000_reset); +extern void stop_ft1000_card(struct net_device *dev); +extern int card_download(struct net_device *dev, const u8 *pFileStart, + size_t FileLength); +extern void ft1000InitProc(struct net_device *dev); +extern void ft1000CleanupProc(struct net_device *dev); + extern u16 ft1000_read_dpram(struct net_device *dev, int offset); extern void card_bootload(struct net_device *dev); extern u16 ft1000_read_dpram_mag_16(struct net_device *dev, int offset, int Index); diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_cs.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_cs.c index 6a1c1d4..f376ca4 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_cs.c +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_cs.c @@ -41,14 +41,12 @@ MODULE_LICENSE("GPL"); /*====================================================================*/ -struct net_device *init_ft1000_card(struct pcmcia_device *link, - void *ft1000_reset); -void stop_ft1000_card(struct net_device *); - static int ft1000_config(struct pcmcia_device *link); static void ft1000_detach(struct pcmcia_device *link); static int ft1000_attach(struct pcmcia_device *link); +#include "ft1000.h" + /*====================================================================*/ static void ft1000_reset(struct pcmcia_device *link) @@ -75,7 +73,7 @@ static void ft1000_detach(struct pcmcia_device *link) free_netdev(dev); } -int ft1000_confcheck(struct pcmcia_device *link, void *priv_data) +static int ft1000_confcheck(struct pcmcia_device *link, void *priv_data) { return pcmcia_request_io(link); } diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c index c956857..f8b8e71 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_dnld.c @@ -287,7 +287,8 @@ u16 hdr_checksum(struct pseudo_hdr *pHdr) return chksum; } -int card_download(struct net_device *dev, const u8 *pFileStart, u32 FileLength) +int card_download(struct net_device *dev, const u8 *pFileStart, + size_t FileLength) { struct ft1000_info *info = (struct ft1000_info *) netdev_priv(dev); int Status = SUCCESS; diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c index 990b2af..b3d743a 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c @@ -56,16 +56,11 @@ #include <linux/delay.h> #include "ft1000.h" -int card_download(struct net_device *dev, const u8 *pFileStart, u32 FileLength); - -void ft1000InitProc(struct net_device *dev); -void ft1000CleanupProc(struct net_device *dev); - -const struct firmware *fw_entry; +static const struct firmware *fw_entry; static void ft1000_hbchk(u_long data); static struct timer_list poll_timer = { - function:ft1000_hbchk + .function = ft1000_hbchk }; static u16 cmdbuffer[1024]; @@ -788,7 +783,7 @@ static void ft1000_hbchk(u_long data) // Output: // //--------------------------------------------------------------------------- -void ft1000_send_cmd (struct net_device *dev, u16 *ptempbuffer, int size, u16 qtype) +static void ft1000_send_cmd (struct net_device *dev, u16 *ptempbuffer, int size, u16 qtype) { struct ft1000_info *info = netdev_priv(dev); int i; @@ -873,7 +868,8 @@ void ft1000_send_cmd (struct net_device *dev, u16 *ptempbuffer, int size, u16 qt // = 1 (successful) // //--------------------------------------------------------------------------- -bool ft1000_receive_cmd(struct net_device *dev, u16 * pbuffer, int maxsz, u16 *pnxtph) +static bool ft1000_receive_cmd(struct net_device *dev, u16 *pbuffer, + int maxsz, u16 *pnxtph) { struct ft1000_info *info = netdev_priv(dev); u16 size; @@ -966,7 +962,7 @@ bool ft1000_receive_cmd(struct net_device *dev, u16 * pbuffer, int maxsz, u16 *p // none // //--------------------------------------------------------------------------- -void ft1000_proc_drvmsg(struct net_device *dev) +static void ft1000_proc_drvmsg(struct net_device *dev) { struct ft1000_info *info = netdev_priv(dev); u16 msgtype; @@ -1245,7 +1241,7 @@ void ft1000_proc_drvmsg(struct net_device *dev) // SUCCESS // //--------------------------------------------------------------------------- -int ft1000_parse_dpram_msg(struct net_device *dev) +static int ft1000_parse_dpram_msg(struct net_device *dev) { struct ft1000_info *info = netdev_priv(dev); u16 doorbell; @@ -1546,7 +1542,7 @@ static void ft1000_flush_fifo(struct net_device *dev, u16 DrvErrNum) // SUCCESS // //--------------------------------------------------------------------------- -int ft1000_copy_up_pkt(struct net_device *dev) +static int ft1000_copy_up_pkt(struct net_device *dev) { u16 tempword; struct ft1000_info *info = netdev_priv(dev); @@ -1734,7 +1730,7 @@ int ft1000_copy_up_pkt(struct net_device *dev) // SUCCESS // //--------------------------------------------------------------------------- -int ft1000_copy_down_pkt(struct net_device *dev, u16 * packet, u16 len) +static int ft1000_copy_down_pkt(struct net_device *dev, u16 * packet, u16 len) { struct ft1000_info *info = netdev_priv(dev); union { @@ -2102,7 +2098,7 @@ static const struct ethtool_ops ops = { }; struct net_device *init_ft1000_card(struct pcmcia_device *link, - void *ft1000_reset) + void *ft1000_reset) { struct ft1000_info *info; struct net_device *dev; diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c index 9e728b3..7faeada 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c @@ -48,8 +48,8 @@ } \ len += snprintf(page+len, PAGE_SIZE - len, "%d\n", var[i]) -int ft1000ReadProc(char *page, char **start, off_t off, - int count, int *eof, void *data) +static int ft1000ReadProc(char *page, char **start, off_t off, + int count, int *eof, void *data) { struct net_device *dev; int len; diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 3f303ea..aaf44c3 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -485,7 +485,7 @@ void card_send_command(struct ft1000_device *ft1000dev, void *ptempbuffer, DEBUG("card_send_command: enter card_send_command... size=%d\n", size); - commandbuf = (unsigned char *)kmalloc(size + 2, GFP_KERNEL); + commandbuf = kmalloc(size + 2, GFP_KERNEL); memcpy((void *)commandbuf + 2, (void *)ptempbuffer, size); ft1000_read_register(ft1000dev, &temp, FT1000_REG_DOORBELL); diff --git a/drivers/staging/gma500/accel_2d.c b/drivers/staging/gma500/accel_2d.c index 14400fc..be92371 100644 --- a/drivers/staging/gma500/accel_2d.c +++ b/drivers/staging/gma500/accel_2d.c @@ -118,7 +118,7 @@ static int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf, size -= submit_size; ret = psb_2d_wait_available(dev_priv, submit_size); if (ret) - break; + break; submit_size <<= 2; @@ -388,19 +388,19 @@ int psb_accel_ioctl(struct drm_device *dev, void *data, struct drm_file *file) for (i = 0; i < op->size; i++, op_ptr++) { u32 r = *op_ptr & 0xF0000000; /* Fill in the GTT offsets for the command buffer */ - if (r == PSB_2D_SRC_SURF_BH || - r == PSB_2D_DST_SURF_BH || + if (r == PSB_2D_SRC_SURF_BH || + r == PSB_2D_DST_SURF_BH || r == PSB_2D_MASK_SURF_BH || r == PSB_2D_PAT_SURF_BH) { i++; op_ptr++; if (i == op->size) goto bad; - if (*op_ptr) + if (*op_ptr) goto bad; - *op_ptr = gtt->offset; - continue; - } + *op_ptr = gtt->offset; + continue; + } } psbfb_2d_submit(dev_priv, op->cmd, op->size); err = 0; diff --git a/drivers/staging/gma500/cdv_device.c b/drivers/staging/gma500/cdv_device.c index 87614e0..8ec10ca 100644 --- a/drivers/staging/gma500/cdv_device.c +++ b/drivers/staging/gma500/cdv_device.c @@ -30,7 +30,6 @@ #define VGA_SR_INDEX 0x3c4 #define VGA_SR_DATA 0x3c5 -/* FIXME: should check if we are the active VGA device ?? */ static void cdv_disable_vga(struct drm_device *dev) { u8 sr1; diff --git a/drivers/staging/gma500/framebuffer.c b/drivers/staging/gma500/framebuffer.c index ebfde13..7748331 100644 --- a/drivers/staging/gma500/framebuffer.c +++ b/drivers/staging/gma500/framebuffer.c @@ -733,9 +733,12 @@ static void psb_setup_outputs(struct drm_device *dev) clone_mask = (1 << INTEL_OUTPUT_MIPI2); break; case INTEL_OUTPUT_HDMI: - if (IS_MFLD(dev)) + /* HDMI on crtc 1 for SoC devices and crtc 0 for + Cedarview. HDMI on Poulsbo is only via external + logic */ + if (IS_MFLD(dev) || IS_MRST(dev)) crtc_mask = (1 << 1); - else /* FIXME: review Oaktrail */ + else crtc_mask = (1 << 0); /* Cedarview */ clone_mask = (1 << INTEL_OUTPUT_HDMI); break; diff --git a/drivers/staging/gma500/gem.c b/drivers/staging/gma500/gem.c index 65fdd6b..f6433c0 100644 --- a/drivers/staging/gma500/gem.c +++ b/drivers/staging/gma500/gem.c @@ -120,8 +120,7 @@ static int psb_gem_create(struct drm_file *file, /* Initialize the extra goodies GEM needs to do all the hard work */ if (drm_gem_object_init(dev, &r->gem, size) != 0) { psb_gtt_free_range(dev, r); - /* GEM doesn't give an error code and we don't have an - EGEMSUCKS so make something up for now - FIXME */ + /* GEM doesn't give an error code so use -ENOMEM */ dev_err(dev->dev, "GEM init failed for %lld\n", size); return -ENOMEM; } @@ -191,8 +190,6 @@ int psb_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev, * The VMA was set up by GEM. In doing so it also ensured that the * vma->vm_private_data points to the GEM object that is backing this * mapping. - * - * FIXME */ int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { diff --git a/drivers/staging/gma500/gtt.c b/drivers/staging/gma500/gtt.c index 461ead2..a246239 100644 --- a/drivers/staging/gma500/gtt.c +++ b/drivers/staging/gma500/gtt.c @@ -72,9 +72,8 @@ u32 *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r) * @r: our GTT range * * Take our preallocated GTT range and insert the GEM object into - * the GTT. - * - * FIXME: gtt lock ? + * the GTT. This is protected via the gtt mutex which the caller + * must hold. */ static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r) { @@ -111,7 +110,8 @@ static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r) * @r: our GTT range * * Remove a preallocated GTT range from the GTT. Overwrite all the - * page table entries with the dummy page + * page table entries with the dummy page. This is protected via the gtt + * mutex which the caller must hold. */ static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r) @@ -136,7 +136,8 @@ static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r) * @gt: the gtt range * * Pin and build an in kernel list of the pages that back our GEM object. - * While we hold this the pages cannot be swapped out + * While we hold this the pages cannot be swapped out. This is protected + * via the gtt mutex which the caller must hold. */ static int psb_gtt_attach_pages(struct gtt_range *gt) { @@ -158,7 +159,7 @@ static int psb_gtt_attach_pages(struct gtt_range *gt) gt->npage = pages; for (i = 0; i < pages; i++) { - /* FIXME: review flags later */ + /* FIXME: needs updating as per mail from Hugh Dickins */ p = read_cache_page_gfp(mapping, i, __GFP_COLD | GFP_KERNEL); if (IS_ERR(p)) @@ -181,7 +182,8 @@ err: * * Undo the effect of psb_gtt_attach_pages. At this point the pages * must have been removed from the GTT as they could now be paged out - * and move bus address. + * and move bus address. This is protected via the gtt mutex which the + * caller must hold. */ static void psb_gtt_detach_pages(struct gtt_range *gt) { @@ -390,15 +392,18 @@ int psb_gtt_init(struct drm_device *dev, int resume) pg->gtt_phys_start = dev_priv->pge_ctl & PAGE_MASK; /* - * FIXME: video mmu has hw bug to access 0x0D0000000, - * then make gatt start at 0x0e000,0000 + * The video mmu has a hw bug when accessing 0x0D0000000. + * Make gatt start at 0x0e000,0000. This doesn't actually + * matter for us but may do if the video acceleration ever + * gets opened up. */ pg->mmu_gatt_start = 0xE0000000; pg->gtt_start = pci_resource_start(dev->pdev, PSB_GTT_RESOURCE); gtt_pages = pci_resource_len(dev->pdev, PSB_GTT_RESOURCE) >> PAGE_SHIFT; - /* CDV workaround */ + /* Some CDV firmware doesn't report this currently. In which case the + system has 64 gtt pages */ if (pg->gtt_start == 0 || gtt_pages == 0) { dev_err(dev->dev, "GTT PCI BAR not initialized.\n"); gtt_pages = 64; @@ -412,13 +417,16 @@ int psb_gtt_init(struct drm_device *dev, int resume) if (pg->gatt_pages == 0 || pg->gatt_start == 0) { static struct resource fudge; /* Preferably peppermint */ - /* This can occur on CDV SDV systems. Fudge it in this case. We really don't care what imaginary space is being allocated at this point */ dev_err(dev->dev, "GATT PCI BAR not initialized.\n"); pg->gatt_start = 0x40000000; pg->gatt_pages = (128 * 1024 * 1024) >> PAGE_SHIFT; + /* This is a little confusing but in fact the GTT is providing + a view from the GPU into memory and not vice versa. As such + this is really allocating space that is not the same as the + CPU address space on CDV */ fudge.start = 0x40000000; fudge.end = 0x40000000 + 128 * 1024 * 1024 - 1; fudge.name = "fudge"; diff --git a/drivers/staging/gma500/intel_opregion.c b/drivers/staging/gma500/intel_opregion.c index d2e6037..d946bc1 100644 --- a/drivers/staging/gma500/intel_opregion.c +++ b/drivers/staging/gma500/intel_opregion.c @@ -20,6 +20,7 @@ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * + * FIXME: resolve with the i915 version */ #include "psb_drv.h" diff --git a/drivers/staging/gma500/mdfld_intel_display.c b/drivers/staging/gma500/mdfld_intel_display.c index aa2ff55..8eb827e 100644 --- a/drivers/staging/gma500/mdfld_intel_display.c +++ b/drivers/staging/gma500/mdfld_intel_display.c @@ -282,7 +282,7 @@ static int mdfld_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) return -EINVAL; } -#if 1 /* FIXME_JLIU7 can't enalbe cursorB/C HW issue. need to remove after HW fix */ +#if 1 /* FIXME_JLIU7 can't enable cursorB/C HW issue. need to remove after HW fix */ if (pipe != 0) return 0; #endif @@ -484,7 +484,7 @@ void mdfld_disable_crtc (struct drm_device *dev, int pipe) /* FIXME_JLIU7 MDFLD_PO revisit */ /* Wait for vblank for the disable to take effect */ -// MDFLD_PO_JLIU7 psb_intel_wait_for_vblank(dev); +/* MDFLD_PO_JLIU7 psb_intel_wait_for_vblank(dev); */ /* Next, disable display pipes */ temp = REG_READ(pipeconf_reg); @@ -561,7 +561,6 @@ static void mdfld_crtc_dpms(struct drm_crtc *crtc, int mode) //gbdispstatus = true; } - /* FIXME_JLIU7 MDFLD_PO replaced w/ the following function */ /* mdfld_dbi_dpms (struct drm_device *dev, int pipe, bool enabled) */ @@ -1150,8 +1149,11 @@ static int mdfld_crtc_mode_set(struct drm_crtc *crtc, dev->mode_config.scaling_mode_property, &scalingType); if (scalingType == DRM_MODE_SCALE_NO_SCALE) { - /*Moorestown doesn't have register support for centering so we need to - mess with the h/vblank and h/vsync start and ends to get centering*/ + /* + * Medfield doesn't have register support for centering so + * we need to mess with the h/vblank and h/vsync start and + * ends to get central + */ int offsetX = 0, offsetY = 0; offsetX = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2; diff --git a/drivers/staging/gma500/mrst_crtc.c b/drivers/staging/gma500/mrst_crtc.c index 72464dd..c9311a5 100644 --- a/drivers/staging/gma500/mrst_crtc.c +++ b/drivers/staging/gma500/mrst_crtc.c @@ -521,12 +521,11 @@ int mrst_pipe_set_base(struct drm_crtc *crtc, int x, int y, struct drm_framebuffer *old_fb) { struct drm_device *dev = crtc->dev; - /* struct drm_i915_master_private *master_priv; */ struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb); int pipe = psb_intel_crtc->pipe; unsigned long start, offset; - /* FIXME: check if we need this surely MRST is pipe 0 only */ + int dspbase = (pipe == 0 ? DSPALINOFF : DSPBBASE); int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF); int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE; @@ -572,15 +571,10 @@ int mrst_pipe_set_base(struct drm_crtc *crtc, } REG_WRITE(dspcntr_reg, dspcntr); - if (0 /* FIXMEAC - check what PSB needs */) { - REG_WRITE(dspbase, offset); - REG_READ(dspbase); - REG_WRITE(dspsurf, start); - REG_READ(dspsurf); - } else { - REG_WRITE(dspbase, start + offset); - REG_READ(dspbase); - } + REG_WRITE(dspbase, offset); + REG_READ(dspbase); + REG_WRITE(dspsurf, start); + REG_READ(dspsurf); pipe_set_base_exit: gma_power_end(dev); diff --git a/drivers/staging/gma500/power.c b/drivers/staging/gma500/power.c index 972bea7..436fe97 100644 --- a/drivers/staging/gma500/power.c +++ b/drivers/staging/gma500/power.c @@ -83,7 +83,7 @@ static void gma_suspend_display(struct drm_device *dev) { struct drm_psb_private *dev_priv = dev->dev_private; - if (dev_priv->suspended) + if (!dev_priv->display_power) return; dev_priv->ops->save_regs(dev); dev_priv->ops->power_down(dev); @@ -101,7 +101,7 @@ static void gma_resume_display(struct pci_dev *pdev) struct drm_device *dev = pci_get_drvdata(pdev); struct drm_psb_private *dev_priv = dev->dev_private; - if (dev_priv->suspended == false) + if (dev_priv->display_power) return; /* turn on the display power island */ @@ -265,6 +265,8 @@ bool gma_power_begin(struct drm_device *dev, bool force_on) /* Ok power up needed */ ret = gma_resume_pci(dev->pdev); if (ret == 0) { + /* FIXME: we want to defer this for Medfield/Oaktrail */ + gma_resume_display(dev); psb_irq_preinstall(dev); psb_irq_postinstall(dev); pm_runtime_get(&dev->pdev->dev); @@ -302,7 +304,7 @@ int psb_runtime_suspend(struct device *dev) int psb_runtime_resume(struct device *dev) { - return 0; + return gma_power_resume(dev);; } int psb_runtime_idle(struct device *dev) diff --git a/drivers/staging/gma500/psb_device.c b/drivers/staging/gma500/psb_device.c index 4659132..b97aa78 100644 --- a/drivers/staging/gma500/psb_device.c +++ b/drivers/staging/gma500/psb_device.c @@ -213,7 +213,6 @@ static int psb_restore_display_registers(struct drm_device *dev) struct drm_psb_private *dev_priv = dev->dev_private; struct drm_crtc *crtc; struct drm_connector *connector; - int pp_stat; /* Display arbitration + watermarks */ PSB_WVDC32(dev_priv->saveDSPARB, DSPARB); @@ -237,37 +236,6 @@ static int psb_restore_display_registers(struct drm_device *dev) connector->funcs->restore(connector); mutex_unlock(&dev->mode_config.mutex); - - if (dev_priv->iLVDS_enable) { - /*shutdown the panel*/ - PSB_WVDC32(0, PP_CONTROL); - do { - pp_stat = PSB_RVDC32(PP_STATUS); - } while (pp_stat & 0x80000000); - - /* Turn off the plane */ - PSB_WVDC32(0x58000000, DSPACNTR); - PSB_WVDC32(0, DSPASURF);/*trigger the plane disable*/ - /* Wait ~4 ticks */ - msleep(4); - /* Turn off pipe */ - PSB_WVDC32(0x0, PIPEACONF); - /* Wait ~8 ticks */ - msleep(8); - - /* Turn off PLLs */ - PSB_WVDC32(0, MRST_DPLL_A); - } else { - PSB_WVDC32(DPI_SHUT_DOWN, DPI_CONTROL_REG); - PSB_WVDC32(0x0, PIPEACONF); - PSB_WVDC32(0x2faf0000, BLC_PWM_CTL); - while (REG_READ(0x70008) & 0x40000000) - cpu_relax(); - while ((PSB_RVDC32(GEN_FIFO_STAT_REG) & DPI_FIFO_EMPTY) - != DPI_FIFO_EMPTY) - cpu_relax(); - PSB_WVDC32(0, DEVICE_READY_REG); - } return 0; } diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c index b2cdce7..297b05a 100644 --- a/drivers/staging/gma500/psb_drv.c +++ b/drivers/staging/gma500/psb_drv.c @@ -183,7 +183,6 @@ static void psb_lastclose(struct drm_device *dev) static void psb_do_takedown(struct drm_device *dev) { - /* FIXME: do we need to clean up the gtt here ? */ } static int psb_do_init(struct drm_device *dev) @@ -329,6 +328,11 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) dev_priv->dev = dev; dev->dev_private = (void *) dev_priv; + if (!IS_PSB(dev)) { + if (pci_enable_msi(dev->pdev)) + dev_warn(dev->dev, "Enabling MSI failed!\n"); + } + dev_priv->num_pipe = dev_priv->ops->pipes; resource_start = pci_resource_start(dev->pdev, PSB_MMIO_RESOURCE); @@ -410,7 +414,7 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) PSB_WVDC32(0x00000000, PSB_INT_ENABLE_R); PSB_WVDC32(0xFFFFFFFF, PSB_INT_MASK_R); spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); - if (drm_core_check_feature(dev, DRIVER_MODESET)) + if (IS_PSB(dev) && drm_core_check_feature(dev, DRIVER_MODESET)) drm_irq_install(dev); dev->vblank_disable_allowed = 1; @@ -444,12 +448,9 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) if (ret) return ret; -#if 0 - /*enable runtime pm at last*/ - pm_runtime_enable(&dev->pdev->dev); + + /* Enable runtime pm at last */ pm_runtime_set_active(&dev->pdev->dev); -#endif - /*Intel drm driver load is done, continue doing pvr load*/ return 0; out_err: psb_driver_unload(dev); @@ -466,14 +467,13 @@ static int psb_sizes_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_psb_private *dev_priv = psb_priv(dev); - struct drm_psb_sizes_arg *arg = - (struct drm_psb_sizes_arg *) data; + struct drm_psb_sizes_arg *arg = data; *arg = dev_priv->sizes; return 0; } -static int psb_dc_state_ioctl(struct drm_device *dev, void * data, +static int psb_dc_state_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { uint32_t flags; @@ -481,8 +481,7 @@ static int psb_dc_state_ioctl(struct drm_device *dev, void * data, struct drm_mode_object *obj; struct drm_connector *connector; struct drm_crtc *crtc; - struct drm_psb_dc_state_arg *arg = - (struct drm_psb_dc_state_arg *)data; + struct drm_psb_dc_state_arg *arg = data; /* Double check MRST case */ @@ -1110,15 +1109,12 @@ static long psb_unlocked_ioctl(struct file *filp, unsigned int cmd, { struct drm_file *file_priv = filp->private_data; struct drm_device *dev = file_priv->minor->dev; - struct drm_psb_private *dev_priv = dev->dev_private; - static unsigned int runtime_allowed; - - if (runtime_allowed == 1 && dev_priv->is_lvds_on) { - runtime_allowed++; - pm_runtime_allow(&dev->pdev->dev); - dev_priv->rpm_enabled = 1; - } - return drm_ioctl(filp, cmd, arg); + int ret; + + pm_runtime_forbid(dev->dev); + ret = drm_ioctl(filp, cmd, arg); + pm_runtime_allow(dev->dev); + return ret; /* FIXME: do we need to wrap the other side of this */ } @@ -1137,8 +1133,12 @@ static void psb_remove(struct pci_dev *pdev) } static const struct dev_pm_ops psb_pm_ops = { - .resume = gma_power_resume, .suspend = gma_power_suspend, + .resume = gma_power_resume, + .freeze = gma_power_suspend, + .thaw = gma_power_resume, + .poweroff = gma_power_suspend, + .restore = gma_power_resume, .runtime_suspend = psb_runtime_suspend, .runtime_resume = psb_runtime_resume, .runtime_idle = psb_runtime_idle, @@ -1207,9 +1207,6 @@ static struct pci_driver psb_pci_driver = { static int psb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { - /* MLD Added this from Inaky's patch */ - if (pci_enable_msi(pdev)) - dev_warn(&pdev->dev, "Enable MSI failed!\n"); return drm_get_pci_dev(pdev, ent, &driver); } diff --git a/drivers/staging/gma500/psb_drv.h b/drivers/staging/gma500/psb_drv.h index fd4732d..9cbb494 100644 --- a/drivers/staging/gma500/psb_drv.h +++ b/drivers/staging/gma500/psb_drv.h @@ -43,6 +43,7 @@ enum { CHIP_MFLD_0130 = 3, /* Medfield */ }; +#define IS_PSB(dev) (((dev)->pci_device & 0xfffe) == 0x8108) #define IS_MRST(dev) (((dev)->pci_device & 0xfffc) == 0x4100) #define IS_MFLD(dev) (((dev)->pci_device & 0xfff8) == 0x0130) @@ -134,6 +135,9 @@ enum { #define _PSB_IRQ_MSVDX_FLAG (1<<19) #define _LNC_IRQ_TOPAZ_FLAG (1<<20) +#define _PSB_PIPE_EVENT_FLAG (_PSB_VSYNC_PIPEA_FLAG | \ + _PSB_VSYNC_PIPEB_FLAG) + /* This flag includes all the display IRQ bits excepts the vblank irqs. */ #define _MDFLD_DISP_ALL_IRQ_FLAG (_MDFLD_PIPEC_EVENT_FLAG | \ _MDFLD_PIPEB_EVENT_FLAG | \ diff --git a/drivers/staging/gma500/psb_intel_display.c b/drivers/staging/gma500/psb_intel_display.c index 4afa671..caa9d86 100644 --- a/drivers/staging/gma500/psb_intel_display.c +++ b/drivers/staging/gma500/psb_intel_display.c @@ -1102,10 +1102,6 @@ static int psb_crtc_set_config(struct drm_mode_set *set) { int ret; struct drm_device *dev = set->crtc->dev; - struct drm_psb_private *dev_priv = dev->dev_private; - - if (!dev_priv->rpm_enabled) - return drm_crtc_helper_set_config(set); pm_runtime_forbid(&dev->pdev->dev); ret = drm_crtc_helper_set_config(set); diff --git a/drivers/staging/gma500/psb_intel_lvds.c b/drivers/staging/gma500/psb_intel_lvds.c index c6436da..21022e1 100644 --- a/drivers/staging/gma500/psb_intel_lvds.c +++ b/drivers/staging/gma500/psb_intel_lvds.c @@ -68,20 +68,23 @@ struct psb_intel_lvds_priv { static u32 psb_intel_lvds_get_max_backlight(struct drm_device *dev) { struct drm_psb_private *dev_priv = dev->dev_private; - u32 retVal; + u32 ret; if (gma_power_begin(dev, false)) { - retVal = ((REG_READ(BLC_PWM_CTL) & - BACKLIGHT_MODULATION_FREQ_MASK) >> - BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; - + ret = REG_READ(BLC_PWM_CTL); gma_power_end(dev); - } else - retVal = ((dev_priv->saveBLC_PWM_CTL & - BACKLIGHT_MODULATION_FREQ_MASK) >> - BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; - - return retVal; + } else /* Powered off, use the saved value */ + ret = dev_priv->saveBLC_PWM_CTL; + + /* Top 15bits hold the frequency mask */ + ret = (ret & BACKLIGHT_MODULATION_FREQ_MASK) >> + BACKLIGHT_MODULATION_FREQ_SHIFT; + + ret *= 2; /* Return a 16bit range as needed for setting */ + if (ret == 0) + dev_err(dev->dev, "BL bug: Reg %08x save %08X\n", + REG_READ(BLC_PWM_CTL), dev_priv->saveBLC_PWM_CTL); + return ret; } /* @@ -142,7 +145,7 @@ static int psb_lvds_pwm_set_brightness(struct drm_device *dev, int level) max_pwm_blc = psb_intel_lvds_get_max_backlight(dev); /*BLC_PWM_CTL Should be initiated while backlight device init*/ - BUG_ON((max_pwm_blc & PSB_BLC_MAX_PWM_REG_FREQ) == 0); + BUG_ON(max_pwm_blc == 0); blc_pwm_duty_cycle = level * max_pwm_blc / BRIGHTNESS_MAX_LEVEL; @@ -154,6 +157,10 @@ static int psb_lvds_pwm_set_brightness(struct drm_device *dev, int level) (max_pwm_blc << PSB_BACKLIGHT_PWM_CTL_SHIFT) | (blc_pwm_duty_cycle)); + dev_info(dev->dev, "Backlight lvds set brightness %08x\n", + (max_pwm_blc << PSB_BACKLIGHT_PWM_CTL_SHIFT) | + (blc_pwm_duty_cycle)); + return 0; } @@ -162,14 +169,12 @@ static int psb_lvds_pwm_set_brightness(struct drm_device *dev, int level) */ void psb_intel_lvds_set_brightness(struct drm_device *dev, int level) { - /*u32 blc_pwm_ctl;*/ - struct drm_psb_private *dev_priv = - (struct drm_psb_private *)dev->dev_private; + struct drm_psb_private *dev_priv = dev->dev_private; dev_dbg(dev->dev, "backlight level is %d\n", level); if (!dev_priv->lvds_bl) { - dev_err(dev->dev, "NO LVDS Backlight Info\n"); + dev_err(dev->dev, "NO LVDS backlight info\n"); return; } @@ -190,11 +195,13 @@ static void psb_intel_lvds_set_backlight(struct drm_device *dev, int level) u32 blc_pwm_ctl; if (gma_power_begin(dev, false)) { - blc_pwm_ctl = - REG_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK; + blc_pwm_ctl = REG_READ(BLC_PWM_CTL); + blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK; REG_WRITE(BLC_PWM_CTL, (blc_pwm_ctl | (level << BACKLIGHT_DUTY_CYCLE_SHIFT))); + dev_priv->saveBLC_PWM_CTL = (blc_pwm_ctl | + (level << BACKLIGHT_DUTY_CYCLE_SHIFT)); gma_power_end(dev); } else { blc_pwm_ctl = dev_priv->saveBLC_PWM_CTL & @@ -212,9 +219,11 @@ static void psb_intel_lvds_set_power(struct drm_device *dev, { u32 pp_status; - if (!gma_power_begin(dev, true)) + if (!gma_power_begin(dev, true)) { + dev_err(dev->dev, "set power, chip off!\n"); return; - + } + if (on) { REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) | POWER_TARGET_ON); @@ -296,9 +305,6 @@ static void psb_intel_lvds_restore(struct drm_connector *connector) { struct drm_device *dev = connector->dev; u32 pp_status; - - /*struct drm_psb_private *dev_priv = - (struct drm_psb_private *)dev->dev_private;*/ struct psb_intel_output *psb_intel_output = to_psb_intel_output(connector); struct psb_intel_lvds_priv *lvds_priv = @@ -382,7 +388,6 @@ bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder, if (psb_intel_output->type == INTEL_OUTPUT_MIPI2) panel_fixed_mode = mode_dev->panel_fixed_mode2; - /* FIXME: review for Medfield */ /* PSB requires the LVDS is on pipe B, MRST has only one pipe anyway */ if (!IS_MRST(dev) && psb_intel_crtc->pipe == 0) { printk(KERN_ERR "Can't support LVDS on pipe A\n"); @@ -622,7 +627,8 @@ int psb_intel_lvds_set_property(struct drm_connector *connector, goto set_prop_error; else { #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE - struct drm_psb_private *devp = encoder->dev->dev_private; + struct drm_psb_private *devp = + encoder->dev->dev_private; struct backlight_device *bd = devp->backlight_device; if (bd) { bd->props.brightness = value; @@ -695,8 +701,7 @@ void psb_intel_lvds_init(struct drm_device *dev, struct drm_encoder *encoder; struct drm_display_mode *scan; /* *modes, *bios_mode; */ struct drm_crtc *crtc; - struct drm_psb_private *dev_priv = - (struct drm_psb_private *)dev->dev_private; + struct drm_psb_private *dev_priv = dev->dev_private; u32 lvds; int pipe; @@ -712,8 +717,8 @@ void psb_intel_lvds_init(struct drm_device *dev, } psb_intel_output->dev_priv = lvds_priv; - psb_intel_output->mode_dev = mode_dev; + connector = &psb_intel_output->base; encoder = &psb_intel_output->enc; drm_connector_init(dev, &psb_intel_output->base, diff --git a/drivers/staging/gma500/psb_irq.c b/drivers/staging/gma500/psb_irq.c index 4a0fa42..36dd630 100644 --- a/drivers/staging/gma500/psb_irq.c +++ b/drivers/staging/gma500/psb_irq.c @@ -139,21 +139,10 @@ void mid_disable_pipe_event(struct drm_psb_private *dev_priv, int pipe) } /** - * Display controller interrupt handler for vsync/vblank. - * - */ -static void mid_vblank_handler(struct drm_device *dev, uint32_t pipe) -{ - drm_handle_vblank(dev, pipe); -} - - -/** * Display controller interrupt handler for pipe event. * */ -#define WAIT_STATUS_CLEAR_LOOP_COUNT 0xffff -static void mid_pipe_event_handler(struct drm_device *dev, uint32_t pipe) +static void mid_pipe_event_handler(struct drm_device *dev, int pipe) { struct drm_psb_private *dev_priv = (struct drm_psb_private *) dev->dev_private; @@ -162,6 +151,7 @@ static void mid_pipe_event_handler(struct drm_device *dev, uint32_t pipe) uint32_t pipe_stat_reg = psb_pipestat(pipe); uint32_t pipe_enable = dev_priv->pipestat[pipe]; uint32_t pipe_status = dev_priv->pipestat[pipe] >> 16; + uint32_t pipe_clear; uint32_t i = 0; spin_lock(&dev_priv->irqmask_lock); @@ -172,27 +162,23 @@ static void mid_pipe_event_handler(struct drm_device *dev, uint32_t pipe) spin_unlock(&dev_priv->irqmask_lock); - /* clear the 2nd level interrupt status bits */ - /** - * FIXME: shouldn't use while loop here. However, the interrupt - * status 'sticky' bits cannot be cleared by setting '1' to that - * bit once... - */ - for (i = 0; i < WAIT_STATUS_CLEAR_LOOP_COUNT; i++) { + /* Clear the 2nd level interrupt status bits + * Sometimes the bits are very sticky so we repeat until they unstick */ + for (i = 0; i < 0xffff; i++) { PSB_WVDC32(PSB_RVDC32(pipe_stat_reg), pipe_stat_reg); - (void) PSB_RVDC32(pipe_stat_reg); + pipe_clear = PSB_RVDC32(pipe_stat_reg) & pipe_status; - if ((PSB_RVDC32(pipe_stat_reg) & pipe_status) == 0) + if (pipe_clear == 0) break; } - if (i == WAIT_STATUS_CLEAR_LOOP_COUNT) + if (pipe_clear) dev_err(dev->dev, - "%s, can't clear the status bits in pipe_stat_reg, its value = 0x%x.\n", - __func__, PSB_RVDC32(pipe_stat_reg)); + "%s, can't clear status bits for pipe %d, its value = 0x%x.\n", + __func__, pipe, PSB_RVDC32(pipe_stat_reg)); if (pipe_stat_val & PIPE_VBLANK_STATUS) - mid_vblank_handler(dev, pipe); + drm_handle_vblank(dev, pipe); if (pipe_stat_val & PIPE_TE_STATUS) drm_handle_vblank(dev, pipe); @@ -203,8 +189,11 @@ static void mid_pipe_event_handler(struct drm_device *dev, uint32_t pipe) */ static void psb_vdc_interrupt(struct drm_device *dev, uint32_t vdc_stat) { - if (vdc_stat & _PSB_PIPEA_EVENT_FLAG) + if (vdc_stat & _PSB_VSYNC_PIPEA_FLAG) mid_pipe_event_handler(dev, 0); + + if (vdc_stat & _PSB_VSYNC_PIPEB_FLAG) + mid_pipe_event_handler(dev, 1); } irqreturn_t psb_irq_handler(DRM_IRQ_ARGS) @@ -220,8 +209,13 @@ irqreturn_t psb_irq_handler(DRM_IRQ_ARGS) vdc_stat = PSB_RVDC32(PSB_INT_IDENTITY_R); + if (vdc_stat & _PSB_PIPE_EVENT_FLAG) + dsp_int = 1; + + /* FIXME: Handle Medfield if (vdc_stat & _MDFLD_DISP_ALL_IRQ_FLAG) dsp_int = 1; + */ if (vdc_stat & _PSB_IRQ_SGX_FLAG) sgx_int = 1; @@ -267,13 +261,18 @@ void psb_irq_preinstall(struct drm_device *dev) if (gma_power_is_on(dev)) PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); if (dev->vblank_enabled[0]) - dev_priv->vdc_irq_mask |= _PSB_PIPEA_EVENT_FLAG; + dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEA_FLAG; + if (dev->vblank_enabled[1]) + dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEB_FLAG; + + /* FIXME: Handle Medfield irq mask if (dev->vblank_enabled[1]) dev_priv->vdc_irq_mask |= _MDFLD_PIPEB_EVENT_FLAG; if (dev->vblank_enabled[2]) dev_priv->vdc_irq_mask |= _MDFLD_PIPEC_EVENT_FLAG; + */ - /*This register is safe even if display island is off*/ + /* This register is safe even if display island is off */ PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); } @@ -471,7 +470,13 @@ int psb_enable_vblank(struct drm_device *dev, int pipe) spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); - mid_enable_pipe_event(dev_priv, pipe); + if (pipe == 0) + dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEA_FLAG; + else if (pipe == 1) + dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEB_FLAG; + + PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); + PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); psb_enable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE); spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); @@ -493,7 +498,13 @@ void psb_disable_vblank(struct drm_device *dev, int pipe) #endif spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); - mid_disable_pipe_event(dev_priv, pipe); + if (pipe == 0) + dev_priv->vdc_irq_mask &= ~_PSB_VSYNC_PIPEA_FLAG; + else if (pipe == 1) + dev_priv->vdc_irq_mask &= ~_PSB_VSYNC_PIPEB_FLAG; + + PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); + PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); psb_disable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE); spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); diff --git a/drivers/staging/gma500/psb_lid.c b/drivers/staging/gma500/psb_lid.c index af32851..b867aabe 100644 --- a/drivers/staging/gma500/psb_lid.c +++ b/drivers/staging/gma500/psb_lid.c @@ -52,8 +52,6 @@ static void psb_lid_timer_func(unsigned long data) pp_status = REG_READ(PP_STATUS); } while ((pp_status & PP_ON) == 0); } - /* printk(KERN_INFO"%s: lid: closed\n", __FUNCTION__); */ - dev_priv->lid_last_state = readl(lid_state); lid_timer_schedule: diff --git a/drivers/staging/go7007/Makefile b/drivers/staging/go7007/Makefile index 60a9185..6ee837c 100644 --- a/drivers/staging/go7007/Makefile +++ b/drivers/staging/go7007/Makefile @@ -20,15 +20,11 @@ go7007-y := go7007-v4l2.o go7007-driver.o go7007-i2c.o go7007-fw.o \ s2250-y := s2250-board.o # Uncomment when the saa7134 patches get into upstream -#ifneq ($(CONFIG_VIDEO_SAA7134),) #obj-$(CONFIG_VIDEO_SAA7134) += saa7134-go7007.o -#EXTRA_CFLAGS += -Idrivers/media/video/saa7134 -DSAA7134_MPEG_GO7007=3 -#endif +#ccflags-$(CONFIG_VIDEO_SAA7134:m=y) += -Idrivers/media/video/saa7134 -DSAA7134_MPEG_GO7007=3 # S2250 needs cypress ezusb loader from dvb-usb -ifneq ($(CONFIG_VIDEO_GO7007_USB_S2250_BOARD),) -ccflags-y := -Idrivers/media/dvb/dvb-usb -endif +ccflags-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD:m=y) += -Idrivers/media/dvb/dvb-usb ccflags-y += -Idrivers/media/dvb/frontends ccflags-y += -Idrivers/media/dvb/dvb-core diff --git a/drivers/staging/go7007/wis-tw2804.c b/drivers/staging/go7007/wis-tw2804.c index 5b218c5..9134f03 100644 --- a/drivers/staging/go7007/wis-tw2804.c +++ b/drivers/staging/go7007/wis-tw2804.c @@ -33,8 +33,7 @@ struct wis_tw2804 { int hue; }; -static u8 global_registers[] = -{ +static u8 global_registers[] = { 0x39, 0x00, 0x3a, 0xff, 0x3b, 0x84, @@ -45,8 +44,7 @@ static u8 global_registers[] = 0xff, 0xff, /* Terminator (reg 0xff does not exist) */ }; -static u8 channel_registers[] = -{ +static u8 channel_registers[] = { 0x01, 0xc4, 0x02, 0xa5, 0x03, 0x20, diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index d286b22..2b41eb6 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -109,15 +109,6 @@ struct block_device_context { int users; }; -static const char *drv_name = "blkvsc"; - -/* {32412632-86cb-44a2-9b5c-50d1417354f5} */ -static const struct hv_guid dev_type = { - .data = { - 0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44, - 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5 - } -}; /* * There is a circular dependency involving blkvsc_request_completion() @@ -155,13 +146,13 @@ static int blkvsc_device_add(struct hv_device *device, * id. For IDE devices, the device instance id is formatted as * <bus id> * - <device id> - 8899 - 000000000000. */ - device_info->path_id = device->dev_instance.data[3] << 24 | - device->dev_instance.data[2] << 16 | - device->dev_instance.data[1] << 8 | - device->dev_instance.data[0]; + device_info->path_id = device->dev_instance.b[3] << 24 | + device->dev_instance.b[2] << 16 | + device->dev_instance.b[1] << 8 | + device->dev_instance.b[0]; - device_info->target_id = device->dev_instance.data[5] << 8 | - device->dev_instance.data[4]; + device_info->target_id = device->dev_instance.b[5] << 8 | + device->dev_instance.b[4]; return ret; } @@ -734,7 +725,7 @@ static int blkvsc_do_request(struct block_device_context *blkdev, } else { ret = blkvsc_submit_request(blkvsc_req, blkvsc_request_completion); - if (ret == -1) { + if (ret == -EAGAIN) { pending = 1; list_add_tail(&blkvsc_req->pend_entry, &blkdev->pending_list); @@ -802,10 +793,19 @@ static void blkvsc_request(struct request_queue *queue) } } +static const struct hv_vmbus_device_id id_table[] = { + /* IDE guid */ + { VMBUS_DEVICE(0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44, + 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5) }, + { }, +}; +MODULE_DEVICE_TABLE(vmbus, id_table); /* The one and only one */ static struct hv_driver blkvsc_drv = { + .name = "blkvsc", + .id_table = id_table, .probe = blkvsc_probe, .remove = blkvsc_remove, .shutdown = blkvsc_shutdown, @@ -824,25 +824,13 @@ static const struct block_device_operations block_ops = { */ static int blkvsc_drv_init(void) { - struct hv_driver *drv = &blkvsc_drv; - int ret; - BUILD_BUG_ON(sizeof(sector_t) != 8); - - memcpy(&drv->dev_type, &dev_type, sizeof(struct hv_guid)); - drv->driver.name = drv_name; - - /* The driver belongs to vmbus */ - ret = vmbus_child_driver_register(&drv->driver); - - return ret; + return vmbus_driver_register(&blkvsc_drv); } - static void blkvsc_drv_exit(void) { - - vmbus_child_driver_unregister(&blkvsc_drv.driver); + vmbus_driver_unregister(&blkvsc_drv); } /* diff --git a/drivers/staging/hv/channel.c b/drivers/staging/hv/channel.c index 455f47a..ac92c1f 100644 --- a/drivers/staging/hv/channel.c +++ b/drivers/staging/hv/channel.c @@ -76,15 +76,14 @@ void vmbus_get_debug_info(struct vmbus_channel *channel, struct hv_monitor_page *monitorpage; u8 monitor_group = (u8)channel->offermsg.monitorid / 32; u8 monitor_offset = (u8)channel->offermsg.monitorid % 32; - /* u32 monitorBit = 1 << monitorOffset; */ debuginfo->relid = channel->offermsg.child_relid; debuginfo->state = channel->state; memcpy(&debuginfo->interfacetype, - &channel->offermsg.offer.if_type, sizeof(struct hv_guid)); + &channel->offermsg.offer.if_type, sizeof(uuid_le)); memcpy(&debuginfo->interface_instance, &channel->offermsg.offer.if_instance, - sizeof(struct hv_guid)); + sizeof(uuid_le)); monitorpage = (struct hv_monitor_page *)vmbus_connection.monitor_pages; @@ -119,8 +118,8 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, u32 recv_ringbuffer_size, void *userdata, u32 userdatalen, void (*onchannelcallback)(void *context), void *context) { - struct vmbus_channel_open_channel *openMsg; - struct vmbus_channel_msginfo *openInfo = NULL; + struct vmbus_channel_open_channel *open_msg; + struct vmbus_channel_msginfo *open_info = NULL; void *in, *out; unsigned long flags; int ret, t, err = 0; @@ -173,24 +172,24 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, } /* Create and init the channel open message */ - openInfo = kmalloc(sizeof(*openInfo) + + open_info = kmalloc(sizeof(*open_info) + sizeof(struct vmbus_channel_open_channel), GFP_KERNEL); - if (!openInfo) { + if (!open_info) { err = -ENOMEM; goto errorout; } - init_completion(&openInfo->waitevent); + init_completion(&open_info->waitevent); - openMsg = (struct vmbus_channel_open_channel *)openInfo->msg; - openMsg->header.msgtype = CHANNELMSG_OPENCHANNEL; - openMsg->openid = newchannel->offermsg.child_relid; - openMsg->child_relid = newchannel->offermsg.child_relid; - openMsg->ringbuffer_gpadlhandle = newchannel->ringbuffer_gpadlhandle; - openMsg->downstream_ringbuffer_pageoffset = send_ringbuffer_size >> + open_msg = (struct vmbus_channel_open_channel *)open_info->msg; + open_msg->header.msgtype = CHANNELMSG_OPENCHANNEL; + open_msg->openid = newchannel->offermsg.child_relid; + open_msg->child_relid = newchannel->offermsg.child_relid; + open_msg->ringbuffer_gpadlhandle = newchannel->ringbuffer_gpadlhandle; + open_msg->downstream_ringbuffer_pageoffset = send_ringbuffer_size >> PAGE_SHIFT; - openMsg->server_contextarea_gpadlhandle = 0; + open_msg->server_contextarea_gpadlhandle = 0; if (userdatalen > MAX_USER_DEFINED_BYTES) { err = -EINVAL; @@ -198,35 +197,35 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, } if (userdatalen) - memcpy(openMsg->userdata, userdata, userdatalen); + memcpy(open_msg->userdata, userdata, userdatalen); spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); - list_add_tail(&openInfo->msglistentry, + list_add_tail(&open_info->msglistentry, &vmbus_connection.chn_msg_list); spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); - ret = vmbus_post_msg(openMsg, + ret = vmbus_post_msg(open_msg, sizeof(struct vmbus_channel_open_channel)); if (ret != 0) goto cleanup; - t = wait_for_completion_timeout(&openInfo->waitevent, 5*HZ); + t = wait_for_completion_timeout(&open_info->waitevent, 5*HZ); if (t == 0) { err = -ETIMEDOUT; goto errorout; } - if (openInfo->response.open_result.status) - err = openInfo->response.open_result.status; + if (open_info->response.open_result.status) + err = open_info->response.open_result.status; cleanup: spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); - list_del(&openInfo->msglistentry); + list_del(&open_info->msglistentry); spin_unlock_irqrestore(&vmbus_connection.channelmsg_lock, flags); - kfree(openInfo); + kfree(open_info); return err; errorout: @@ -234,57 +233,12 @@ errorout: hv_ringbuffer_cleanup(&newchannel->inbound); free_pages((unsigned long)out, get_order(send_ringbuffer_size + recv_ringbuffer_size)); - kfree(openInfo); + kfree(open_info); return err; } EXPORT_SYMBOL_GPL(vmbus_open); /* - * dump_gpadl_body - Dump the gpadl body message to the console for - * debugging purposes. - */ -static void dump_gpadl_body(struct vmbus_channel_gpadl_body *gpadl, u32 len) -{ - int i; - int pfncount; - - pfncount = (len - sizeof(struct vmbus_channel_gpadl_body)) / - sizeof(u64); - - DPRINT_DBG(VMBUS, "gpadl body - len %d pfn count %d", len, pfncount); - - for (i = 0; i < pfncount; i++) - DPRINT_DBG(VMBUS, "gpadl body - %d) pfn %llu", - i, gpadl->pfn[i]); -} - -/* - * dump_gpadl_header - Dump the gpadl header message to the console for - * debugging purposes. - */ -static void dump_gpadl_header(struct vmbus_channel_gpadl_header *gpadl) -{ - int i, j; - int pagecount; - - DPRINT_DBG(VMBUS, - "gpadl header - relid %d, range count %d, range buflen %d", - gpadl->child_relid, gpadl->rangecount, gpadl->range_buflen); - for (i = 0; i < gpadl->rangecount; i++) { - pagecount = gpadl->range[i].byte_count >> PAGE_SHIFT; - pagecount = (pagecount > 26) ? 26 : pagecount; - - DPRINT_DBG(VMBUS, "gpadl range %d - len %d offset %d " - "page count %d", i, gpadl->range[i].byte_count, - gpadl->range[i].byte_offset, pagecount); - - for (j = 0; j < pagecount; j++) - DPRINT_DBG(VMBUS, "%d) pfn %llu", j, - gpadl->range[i].pfn_array[j]); - } -} - -/* * create_gpadl_header - Creates a gpadl for the specified buffer */ static int create_gpadl_header(void *kbuffer, u32 size, @@ -437,7 +391,6 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, { struct vmbus_channel_gpadl_header *gpadlmsg; struct vmbus_channel_gpadl_body *gpadl_body; - /* struct vmbus_channel_gpadl_created *gpadlCreated; */ struct vmbus_channel_msginfo *msginfo = NULL; struct vmbus_channel_msginfo *submsginfo; u32 msgcount; @@ -461,7 +414,6 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, gpadlmsg->child_relid = channel->offermsg.child_relid; gpadlmsg->gpadl = next_gpadl_handle; - dump_gpadl_header(gpadlmsg); spin_lock_irqsave(&vmbus_connection.channelmsg_lock, flags); list_add_tail(&msginfo->msglistentry, @@ -485,8 +437,6 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, CHANNELMSG_GPADL_BODY; gpadl_body->gpadl = next_gpadl_handle; - dump_gpadl_body(gpadl_body, submsginfo->msgsize - - sizeof(*submsginfo)); ret = vmbus_post_msg(gpadl_body, submsginfo->msgsize - sizeof(*submsginfo)); @@ -522,8 +472,6 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle) unsigned long flags; int ret, t; - /* ASSERT(gpadl_handle != 0); */ - info = kmalloc(sizeof(*info) + sizeof(struct vmbus_channel_gpadl_teardown), GFP_KERNEL); if (!info) @@ -863,7 +811,7 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer, pr_err("Buffer too small - needed %d bytes but " "got space for only %d bytes\n", packetlen, bufferlen); - return -2; + return -ENOBUFS; } *requestid = desc.trans_id; diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c index bf011f3..11beb41 100644 --- a/drivers/staging/hv/channel_mgmt.c +++ b/drivers/staging/hv/channel_mgmt.c @@ -40,12 +40,12 @@ struct vmbus_channel_message_table_entry { #define MAX_MSG_TYPES 4 #define MAX_NUM_DEVICE_CLASSES_SUPPORTED 8 -static const struct hv_guid +static const uuid_le supported_device_classes[MAX_NUM_DEVICE_CLASSES_SUPPORTED] = { /* {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} */ /* Storage - SCSI */ { - .data = { + .b = { 0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d, 0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f } @@ -54,7 +54,7 @@ static const struct hv_guid /* {F8615163-DF3E-46c5-913F-F2D2F965ED0E} */ /* Network */ { - .data = { + .b = { 0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46, 0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E } @@ -63,7 +63,7 @@ static const struct hv_guid /* {CFA8B69E-5B4A-4cc0-B98B-8BA1A1F3F95A} */ /* Input */ { - .data = { + .b = { 0x9E, 0xB6, 0xA8, 0xCF, 0x4A, 0x5B, 0xc0, 0x4c, 0xB9, 0x8B, 0x8B, 0xA1, 0xA1, 0xF3, 0xF9, 0x5A } @@ -72,7 +72,7 @@ static const struct hv_guid /* {32412632-86cb-44a2-9b5c-50d1417354f5} */ /* IDE */ { - .data = { + .b = { 0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44, 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5 } @@ -80,7 +80,7 @@ static const struct hv_guid /* 0E0B6031-5213-4934-818B-38D90CED39DB */ /* Shutdown */ { - .data = { + .b = { 0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49, 0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB } @@ -88,7 +88,7 @@ static const struct hv_guid /* {9527E630-D0AE-497b-ADCE-E80AB0175CAF} */ /* TimeSync */ { - .data = { + .b = { 0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49, 0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf } @@ -96,7 +96,7 @@ static const struct hv_guid /* {57164f39-9115-4e78-ab55-382f3bd5422d} */ /* Heartbeat */ { - .data = { + .b = { 0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e, 0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d } @@ -104,7 +104,7 @@ static const struct hv_guid /* {A9A0F4E7-5A45-4d96-B827-8A841E8C03E6} */ /* KVP */ { - .data = { + .b = { 0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d, 0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3, 0xe6 } @@ -231,7 +231,7 @@ struct hyperv_service_callback hv_cb_utils[MAX_MSG_TYPES] = { /* Shutdown */ { .msg_type = HV_SHUTDOWN_MSG, - .data = { + .data.b = { 0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49, 0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB }, @@ -242,7 +242,7 @@ struct hyperv_service_callback hv_cb_utils[MAX_MSG_TYPES] = { /* TimeSync */ { .msg_type = HV_TIMESYNC_MSG, - .data = { + .data.b = { 0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49, 0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf }, @@ -252,7 +252,7 @@ struct hyperv_service_callback hv_cb_utils[MAX_MSG_TYPES] = { /* Heartbeat */ { .msg_type = HV_HEARTBEAT_MSG, - .data = { + .data.b = { 0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e, 0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d }, @@ -261,7 +261,7 @@ struct hyperv_service_callback hv_cb_utils[MAX_MSG_TYPES] = { /* {A9A0F4E7-5A45-4d96-B827-8A841E8C03E6} */ /* KVP */ { - .data = { + .data.b = { 0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d, 0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3, 0xe6 }, @@ -358,12 +358,10 @@ static void vmbus_process_offer(struct work_struct *work) spin_lock_irqsave(&vmbus_connection.channel_lock, flags); list_for_each_entry(channel, &vmbus_connection.chn_list, listentry) { - if (!memcmp(&channel->offermsg.offer.if_type, - &newchannel->offermsg.offer.if_type, - sizeof(struct hv_guid)) && - !memcmp(&channel->offermsg.offer.if_instance, - &newchannel->offermsg.offer.if_instance, - sizeof(struct hv_guid))) { + if (!uuid_le_cmp(channel->offermsg.offer.if_type, + newchannel->offermsg.offer.if_type) && + !uuid_le_cmp(channel->offermsg.offer.if_instance, + newchannel->offermsg.offer.if_instance)) { fnew = false; break; } @@ -416,9 +414,8 @@ static void vmbus_process_offer(struct work_struct *work) /* Open IC channels */ for (cnt = 0; cnt < MAX_MSG_TYPES; cnt++) { - if (memcmp(&newchannel->offermsg.offer.if_type, - &hv_cb_utils[cnt].data, - sizeof(struct hv_guid)) == 0 && + if (!uuid_le_cmp(newchannel->offermsg.offer.if_type, + hv_cb_utils[cnt].data) && vmbus_open(newchannel, 2 * PAGE_SIZE, 2 * PAGE_SIZE, NULL, 0, chn_cb_negotiate, @@ -444,16 +441,15 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr) { struct vmbus_channel_offer_channel *offer; struct vmbus_channel *newchannel; - struct hv_guid *guidtype; - struct hv_guid *guidinstance; + uuid_le *guidtype; + uuid_le *guidinstance; int i; int fsupported = 0; offer = (struct vmbus_channel_offer_channel *)hdr; for (i = 0; i < MAX_NUM_DEVICE_CLASSES_SUPPORTED; i++) { - if (memcmp(&offer->offer.if_type, - &supported_device_classes[i], - sizeof(struct hv_guid)) == 0) { + if (!uuid_le_cmp(offer->offer.if_type, + supported_device_classes[i])) { fsupported = 1; break; } diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c index e6b4039..a88ad70 100644 --- a/drivers/staging/hv/connection.c +++ b/drivers/staging/hv/connection.c @@ -25,6 +25,7 @@ #include <linux/kernel.h> #include <linux/sched.h> #include <linux/wait.h> +#include <linux/delay.h> #include <linux/mm.h> #include <linux/slab.h> #include <linux/vmalloc.h> @@ -215,8 +216,6 @@ static void process_chn_event(u32 relid) { struct vmbus_channel *channel; - /* ASSERT(relId > 0); */ - /* * Find the channel based on this relid and invokes the * channel callback to process the event @@ -270,10 +269,25 @@ void vmbus_on_event(unsigned long data) int vmbus_post_msg(void *buffer, size_t buflen) { union hv_connection_id conn_id; + int ret = 0; + int retries = 0; conn_id.asu32 = 0; conn_id.u.id = VMBUS_MESSAGE_CONNECTION_ID; - return hv_post_message(conn_id, 1, buffer, buflen); + + /* + * hv_post_message() can have transient failures because of + * insufficient resources. Retry the operation a couple of + * times before giving up. + */ + while (retries < 3) { + ret = hv_post_message(conn_id, 1, buffer, buflen); + if (ret != HV_STATUS_INSUFFICIENT_BUFFERS) + return ret; + retries++; + msleep(100); + } + return ret; } /* diff --git a/drivers/staging/hv/hv.c b/drivers/staging/hv/hv.c index 824f816..736794e 100644 --- a/drivers/staging/hv/hv.c +++ b/drivers/staging/hv/hv.c @@ -111,7 +111,7 @@ static u64 do_hypercall(u64 control, void *input, void *output) u64 hv_status = 0; u64 input_address = (input) ? virt_to_phys(input) : 0; u64 output_address = (output) ? virt_to_phys(output) : 0; - volatile void *hypercall_page = hv_context.hypercall_page; + void *hypercall_page = hv_context.hypercall_page; __asm__ __volatile__("mov %0, %%r8" : : "r" (output_address) : "r8"); __asm__ __volatile__("call *%3" : "=a" (hv_status) : @@ -132,7 +132,7 @@ static u64 do_hypercall(u64 control, void *input, void *output) u64 output_address = (output) ? virt_to_phys(output) : 0; u32 output_address_hi = output_address >> 32; u32 output_address_lo = output_address & 0xFFFFFFFF; - volatile void *hypercall_page = hv_context.hypercall_page; + void *hypercall_page = hv_context.hypercall_page; __asm__ __volatile__ ("call *%8" : "=d"(hv_status_hi), "=a"(hv_status_lo) : "d" (control_hi), @@ -151,7 +151,6 @@ static u64 do_hypercall(u64 control, void *input, void *output) */ int hv_init(void) { - int ret = 0; int max_leaf; union hv_x64_msr_hypercall_contents hypercall_msr; void *virtaddr = NULL; @@ -164,11 +163,7 @@ int hv_init(void) goto cleanup; max_leaf = query_hypervisor_info(); - /* HvQueryHypervisorFeatures(maxLeaf); */ - /* - * We only support running on top of Hyper-V - */ rdmsrl(HV_X64_MSR_GUEST_OS_ID, hv_context.guestid); if (hv_context.guestid != 0) @@ -181,10 +176,6 @@ int hv_init(void) /* See if the hypercall page is already set */ rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); - /* - * Allocate the hypercall page memory - * virtaddr = osd_page_alloc(1); - */ virtaddr = __vmalloc(PAGE_SIZE, GFP_KERNEL, PAGE_KERNEL_EXEC); if (!virtaddr) @@ -222,7 +213,7 @@ int hv_init(void) hv_context.signal_event_param->flag_number = 0; hv_context.signal_event_param->rsvdz = 0; - return ret; + return 0; cleanup: if (virtaddr) { @@ -233,8 +224,8 @@ cleanup: vfree(virtaddr); } - ret = -1; - return ret; + + return -ENOTSUPP; } /* diff --git a/drivers/staging/hv/hv_mouse.c b/drivers/staging/hv/hv_mouse.c index d957fc2..090736a 100644 --- a/drivers/staging/hv/hv_mouse.c +++ b/drivers/staging/hv/hv_mouse.c @@ -22,8 +22,6 @@ #include <linux/input.h> #include <linux/hid.h> #include <linux/hiddev.h> -#include <linux/pci.h> -#include <linux/dmi.h> #include "hyperv.h" @@ -54,7 +52,7 @@ struct hv_input_dev_info { (SYNTHHID_INPUT_VERSION_MAJOR << 16)) -#pragma pack(push,1) +#pragma pack(push, 1) /* * Message types in the synthetic input protocol */ @@ -120,8 +118,8 @@ struct synthhid_input_report { #pragma pack(pop) -#define INPUTVSC_SEND_RING_BUFFER_SIZE 10*PAGE_SIZE -#define INPUTVSC_RECV_RING_BUFFER_SIZE 10*PAGE_SIZE +#define INPUTVSC_SEND_RING_BUFFER_SIZE (10*PAGE_SIZE) +#define INPUTVSC_RECV_RING_BUFFER_SIZE (10*PAGE_SIZE) #define NBITS(x) (((x)/BITS_PER_LONG)+1) @@ -175,19 +173,13 @@ struct mousevsc_dev { struct hv_input_dev_info hid_dev_info; }; - -static const char *driver_name = "mousevsc"; - -/* {CFA8B69E-5B4A-4cc0-B98B-8BA1A1F3F95A} */ -static const struct hv_guid mouse_guid = { - .data = {0x9E, 0xB6, 0xA8, 0xCF, 0x4A, 0x5B, 0xc0, 0x4c, - 0xB9, 0x8B, 0x8B, 0xA1, 0xA1, 0xF3, 0xF9, 0x5A} +struct input_device_context { + struct hv_device *device_ctx; + struct hid_device *hid_device; + struct hv_input_dev_info device_info; + int connected; }; -static void deviceinfo_callback(struct hv_device *dev, struct hv_input_dev_info *info); -static void inputreport_callback(struct hv_device *dev, void *packet, u32 len); -static void reportdesc_callback(struct hv_device *dev, void *packet, u32 len); - static struct mousevsc_dev *alloc_input_device(struct hv_device *device) { struct mousevsc_dev *input_dev; @@ -344,7 +336,7 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device, if (!input_device->hid_desc) { pr_err("unable to allocate hid descriptor - size %d", desc->bLength); - goto Cleanup; + goto cleanup; } memcpy(input_device->hid_desc, desc, desc->bLength); @@ -357,7 +349,7 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device, if (!input_device->report_desc) { pr_err("unable to allocate report descriptor - size %d", input_device->report_desc_size); - goto Cleanup; + goto cleanup; } memcpy(input_device->report_desc, @@ -384,7 +376,7 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device, if (ret != 0) { pr_err("unable to send synthhid device info ack - ret %d", ret); - goto Cleanup; + goto cleanup; } input_device->device_wait_condition = 1; @@ -392,7 +384,7 @@ static void mousevsc_on_receive_device_info(struct mousevsc_dev *input_device, return; -Cleanup: +cleanup: kfree(input_device->hid_desc); input_device->hid_desc = NULL; @@ -408,6 +400,7 @@ static void mousevsc_on_receive_input_report(struct mousevsc_dev *input_device, struct synthhid_input_report *input_report) { struct hv_driver *input_drv; + struct input_device_context *input_dev_ctx; if (!input_device->init_complete) { pr_info("Initialization incomplete...ignoring input_report msg"); @@ -416,9 +409,11 @@ static void mousevsc_on_receive_input_report(struct mousevsc_dev *input_device, input_drv = drv_to_hv_drv(input_device->device->device.driver); - inputreport_callback(input_device->device, - input_report->buffer, - input_report->header.size); + input_dev_ctx = dev_get_drvdata(&input_device->device->device); + + hid_input_report(input_dev_ctx->hid_device, + HID_INPUT_REPORT, input_report->buffer, input_report->header.size, 1); + } static void mousevsc_on_receive(struct hv_device *device, @@ -509,22 +504,22 @@ static void mousevsc_on_channel_callback(void *context) desc = (struct vmpacket_descriptor *)buffer; switch (desc->type) { - case VM_PKT_COMP: - mousevsc_on_send_completion( - device, desc); - break; - - case VM_PKT_DATA_INBAND: - mousevsc_on_receive( - device, desc); - break; - - default: - pr_err("unhandled packet type %d, tid %llx len %d\n", - desc->type, - req_id, - bytes_recvd); - break; + case VM_PKT_COMP: + mousevsc_on_send_completion( + device, desc); + break; + + case VM_PKT_DATA_INBAND: + mousevsc_on_receive( + device, desc); + break; + + default: + pr_err("unhandled packet type %d, tid %llx len %d\n", + desc->type, + req_id, + bytes_recvd); + break; } /* reset */ @@ -547,7 +542,7 @@ static void mousevsc_on_channel_callback(void *context) } break; } - } else if (ret == -2) { + } else if (ret == -ENOBUFS) { /* Handle large packet */ bufferlen = bytes_recvd; buffer = kzalloc(bytes_recvd, GFP_KERNEL); @@ -611,7 +606,7 @@ static int mousevsc_connect_to_vsp(struct hv_device *device) VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret != 0) { pr_err("unable to send synthhid protocol request."); - goto Cleanup; + goto cleanup; } input_dev->protocol_wait_condition = 0; @@ -619,7 +614,7 @@ static int mousevsc_connect_to_vsp(struct hv_device *device) input_dev->protocol_wait_condition, msecs_to_jiffies(1000)); if (input_dev->protocol_wait_condition == 0) { ret = -ETIMEDOUT; - goto Cleanup; + goto cleanup; } response = &input_dev->protocol_resp; @@ -628,7 +623,7 @@ static int mousevsc_connect_to_vsp(struct hv_device *device) pr_err("synthhid protocol request failed (version %d)", SYNTHHID_INPUT_VERSION); ret = -1; - goto Cleanup; + goto cleanup; } input_dev->device_wait_condition = 0; @@ -636,7 +631,7 @@ static int mousevsc_connect_to_vsp(struct hv_device *device) input_dev->device_wait_condition, msecs_to_jiffies(1000)); if (input_dev->device_wait_condition == 0) { ret = -ETIMEDOUT; - goto Cleanup; + goto cleanup; } /* @@ -648,12 +643,74 @@ static int mousevsc_connect_to_vsp(struct hv_device *device) else ret = -1; -Cleanup: +cleanup: put_input_device(device); return ret; } +static int mousevsc_hid_open(struct hid_device *hid) +{ + return 0; +} + +static void mousevsc_hid_close(struct hid_device *hid) +{ +} + +static void reportdesc_callback(struct hv_device *dev, void *packet, u32 len) +{ + struct input_device_context *input_device_ctx = + dev_get_drvdata(&dev->device); + struct hid_device *hid_dev; + + /* hid_debug = -1; */ + hid_dev = kmalloc(sizeof(struct hid_device), GFP_KERNEL); + + if (hid_parse_report(hid_dev, packet, len)) { + DPRINT_INFO(INPUTVSC_DRV, "Unable to call hd_parse_report"); + return; + } + + if (hid_dev) { + DPRINT_INFO(INPUTVSC_DRV, "hid_device created"); + + hid_dev->ll_driver->open = mousevsc_hid_open; + hid_dev->ll_driver->close = mousevsc_hid_close; + + hid_dev->bus = BUS_VIRTUAL; + hid_dev->vendor = input_device_ctx->device_info.vendor; + hid_dev->product = input_device_ctx->device_info.product; + hid_dev->version = input_device_ctx->device_info.version; + hid_dev->dev = dev->device; + + sprintf(hid_dev->name, "%s", + input_device_ctx->device_info.name); + + /* + * HJ Do we want to call it with a 0 + */ + if (!hidinput_connect(hid_dev, 0)) { + hid_dev->claimed |= HID_CLAIMED_INPUT; + + input_device_ctx->connected = 1; + + DPRINT_INFO(INPUTVSC_DRV, + "HID device claimed by input\n"); + } + + if (!hid_dev->claimed) { + DPRINT_ERR(INPUTVSC_DRV, + "HID device not claimed by " + "input or hiddev\n"); + } + + input_device_ctx->hid_device = hid_dev; + } + + kfree(hid_dev); +} + static int mousevsc_on_device_add(struct hv_device *device, void *additional_info) { @@ -661,12 +718,13 @@ static int mousevsc_on_device_add(struct hv_device *device, struct mousevsc_dev *input_dev; struct hv_driver *input_drv; struct hv_input_dev_info dev_info; + struct input_device_context *input_device_ctx; input_dev = alloc_input_device(device); if (!input_dev) { ret = -1; - goto Cleanup; + goto cleanup; } input_dev->init_complete = false; @@ -707,7 +765,9 @@ static int mousevsc_on_device_add(struct hv_device *device, strcpy(dev_info.name, "Microsoft Vmbus HID-compliant Mouse"); /* Send the device info back up */ - deviceinfo_callback(device, &dev_info); + input_device_ctx = dev_get_drvdata(&device->device); + memcpy(&input_device_ctx->device_info, &dev_info, + sizeof(struct hv_input_dev_info)); /* Send the report desc back up */ /* workaround SA-167 */ @@ -719,7 +779,7 @@ static int mousevsc_on_device_add(struct hv_device *device, input_dev->init_complete = true; -Cleanup: +cleanup: return ret; } @@ -762,50 +822,6 @@ static int mousevsc_on_device_remove(struct hv_device *device) } -/* - * Data types - */ -struct input_device_context { - struct hv_device *device_ctx; - struct hid_device *hid_device; - struct hv_input_dev_info device_info; - int connected; -}; - - -static void deviceinfo_callback(struct hv_device *dev, struct hv_input_dev_info *info) -{ - struct input_device_context *input_device_ctx = - dev_get_drvdata(&dev->device); - - memcpy(&input_device_ctx->device_info, info, - sizeof(struct hv_input_dev_info)); - - DPRINT_INFO(INPUTVSC_DRV, "%s", __func__); -} - -static void inputreport_callback(struct hv_device *dev, void *packet, u32 len) -{ - int ret = 0; - - struct input_device_context *input_dev_ctx = - dev_get_drvdata(&dev->device); - - ret = hid_input_report(input_dev_ctx->hid_device, - HID_INPUT_REPORT, packet, len, 1); - - DPRINT_DBG(INPUTVSC_DRV, "hid_input_report (ret %d)", ret); -} - -static int mousevsc_hid_open(struct hid_device *hid) -{ - return 0; -} - -static void mousevsc_hid_close(struct hid_device *hid) -{ -} - static int mousevsc_probe(struct hv_device *dev) { int ret = 0; @@ -831,15 +847,10 @@ static int mousevsc_probe(struct hv_device *dev) static int mousevsc_remove(struct hv_device *dev) { - int ret = 0; - struct input_device_context *input_dev_ctx; + int ret; - input_dev_ctx = kmalloc(sizeof(struct input_device_context), - GFP_KERNEL); - - dev_set_drvdata(&dev->device, input_dev_ctx); - + input_dev_ctx = dev_get_drvdata(&dev->device); if (input_dev_ctx->connected) { hidinput_disconnect(input_dev_ctx->hid_device); input_dev_ctx->connected = 0; @@ -850,7 +861,6 @@ static int mousevsc_remove(struct hv_device *dev) * is being removed */ ret = mousevsc_on_device_remove(dev); - if (ret != 0) { DPRINT_ERR(INPUTVSC_DRV, "unable to remove vsc device (ret %d)", ret); @@ -861,112 +871,35 @@ static int mousevsc_remove(struct hv_device *dev) return ret; } -static void reportdesc_callback(struct hv_device *dev, void *packet, u32 len) -{ - struct input_device_context *input_device_ctx = - dev_get_drvdata(&dev->device); - struct hid_device *hid_dev; - - /* hid_debug = -1; */ - hid_dev = kmalloc(sizeof(struct hid_device), GFP_KERNEL); - - if (hid_parse_report(hid_dev, packet, len)) { - DPRINT_INFO(INPUTVSC_DRV, "Unable to call hd_parse_report"); - return; - } - - if (hid_dev) { - DPRINT_INFO(INPUTVSC_DRV, "hid_device created"); - - hid_dev->ll_driver->open = mousevsc_hid_open; - hid_dev->ll_driver->close = mousevsc_hid_close; - - hid_dev->bus = BUS_VIRTUAL; - hid_dev->vendor = input_device_ctx->device_info.vendor; - hid_dev->product = input_device_ctx->device_info.product; - hid_dev->version = input_device_ctx->device_info.version; - hid_dev->dev = dev->device; - - sprintf(hid_dev->name, "%s", - input_device_ctx->device_info.name); - - /* - * HJ Do we want to call it with a 0 - */ - if (!hidinput_connect(hid_dev, 0)) { - hid_dev->claimed |= HID_CLAIMED_INPUT; - - input_device_ctx->connected = 1; - - DPRINT_INFO(INPUTVSC_DRV, - "HID device claimed by input\n"); - } - - if (!hid_dev->claimed) { - DPRINT_ERR(INPUTVSC_DRV, - "HID device not claimed by " - "input or hiddev\n"); - } - - input_device_ctx->hid_device = hid_dev; - } - - kfree(hid_dev); -} +static const struct hv_vmbus_device_id id_table[] = { + /* Mouse guid */ + { VMBUS_DEVICE(0x9E, 0xB6, 0xA8, 0xCF, 0x4A, 0x5B, 0xc0, 0x4c, + 0xB9, 0x8B, 0x8B, 0xA1, 0xA1, 0xF3, 0xF9, 0x5A) }, + { }, +}; +/* + * The mouse driver is not functional; do not auto-load it. + */ +/* MODULE_DEVICE_TABLE(vmbus, id_table); */ static struct hv_driver mousevsc_drv = { + .name = "mousevsc", + .id_table = id_table, .probe = mousevsc_probe, .remove = mousevsc_remove, }; -static void mousevsc_drv_exit(void) -{ - vmbus_child_driver_unregister(&mousevsc_drv.driver); -} - static int __init mousevsc_init(void) { - struct hv_driver *drv = &mousevsc_drv; - - DPRINT_INFO(INPUTVSC_DRV, "Hyper-V Mouse driver initializing."); - - memcpy(&drv->dev_type, &mouse_guid, - sizeof(struct hv_guid)); - - drv->driver.name = driver_name; - - /* The driver belongs to vmbus */ - vmbus_child_driver_register(&drv->driver); - - return 0; + return vmbus_driver_register(&mousevsc_drv); } static void __exit mousevsc_exit(void) { - mousevsc_drv_exit(); + vmbus_driver_unregister(&mousevsc_drv); } -/* - * We don't want to automatically load this driver just yet, it's quite - * broken. It's safe if you want to load it yourself manually, but - * don't inflict it on unsuspecting users, that's just mean. - */ -#if 0 - -/* - * We use a PCI table to determine if we should autoload this driver This is - * needed by distro tools to determine if the hyperv drivers should be - * installed and/or configured. We don't do anything else with the table, but - * it needs to be present. - */ -const static struct pci_device_id microsoft_hv_pci_table[] = { - { PCI_DEVICE(0x1414, 0x5353) }, /* VGA compatible controller */ - { 0 } -}; -MODULE_DEVICE_TABLE(pci, microsoft_hv_pci_table); -#endif - MODULE_LICENSE("GPL"); MODULE_VERSION(HV_DRV_VERSION); module_init(mousevsc_init); diff --git a/drivers/staging/hv/hv_util.c b/drivers/staging/hv/hv_util.c index c164b54..f2f456f 100644 --- a/drivers/staging/hv/hv_util.c +++ b/drivers/staging/hv/hv_util.c @@ -26,8 +26,6 @@ #include <linux/slab.h> #include <linux/sysctl.h> #include <linux/reboot.h> -#include <linux/dmi.h> -#include <linux/pci.h> #include "hyperv.h" #include "hv_kvp.h" @@ -210,28 +208,45 @@ static void heartbeat_onchannelcallback(void *context) } } -static const struct pci_device_id __initconst -hv_utils_pci_table[] __maybe_unused = { - { PCI_DEVICE(0x1414, 0x5353) }, /* Hyper-V emulated VGA controller */ - { 0 } -}; -MODULE_DEVICE_TABLE(pci, hv_utils_pci_table); - - -static const struct dmi_system_id __initconst -hv_utils_dmi_table[] __maybe_unused = { - { - .ident = "Hyper-V", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), - DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"), - DMI_MATCH(DMI_BOARD_NAME, "Virtual Machine"), - }, - }, +/* + * The devices managed by the util driver don't need any additional + * setup. + */ +static int util_probe(struct hv_device *dev) +{ + return 0; +} + +static int util_remove(struct hv_device *dev) +{ + return 0; +} + +static const struct hv_vmbus_device_id id_table[] = { + /* Shutdown guid */ + { VMBUS_DEVICE(0x31, 0x60, 0x0B, 0X0E, 0x13, 0x52, 0x34, 0x49, + 0x81, 0x8B, 0x38, 0XD9, 0x0C, 0xED, 0x39, 0xDB) }, + /* Time synch guid */ + { VMBUS_DEVICE(0x30, 0xe6, 0x27, 0x95, 0xae, 0xd0, 0x7b, 0x49, + 0xad, 0xce, 0xe8, 0x0a, 0xb0, 0x17, 0x5c, 0xaf) }, + /* Heartbeat guid */ + { VMBUS_DEVICE(0x39, 0x4f, 0x16, 0x57, 0x15, 0x91, 0x78, 0x4e, + 0xab, 0x55, 0x38, 0x2f, 0x3b, 0xd5, 0x42, 0x2d) }, + /* KVP guid */ + { VMBUS_DEVICE(0xe7, 0xf4, 0xa0, 0xa9, 0x45, 0x5a, 0x96, 0x4d, + 0xb8, 0x27, 0x8a, 0x84, 0x1e, 0x8c, 0x3, 0xe6) }, { }, }; -MODULE_DEVICE_TABLE(dmi, hv_utils_dmi_table); +MODULE_DEVICE_TABLE(vmbus, id_table); + +/* The one and only one */ +static struct hv_driver util_drv = { + .name = "hv_util", + .id_table = id_table, + .probe = util_probe, + .remove = util_remove, +}; static int __init init_hyperv_utils(void) { @@ -241,9 +256,6 @@ static int __init init_hyperv_utils(void) return -ENODEV; - if (!dmi_check_system(hv_utils_dmi_table)) - return -ENODEV; - shut_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL); time_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL); hbeat_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL); @@ -264,7 +276,7 @@ static int __init init_hyperv_utils(void) hv_cb_utils[HV_KVP_MSG].callback = &hv_kvp_onchannelcallback; - return 0; + return vmbus_driver_register(&util_drv); } static void exit_hyperv_utils(void) @@ -296,6 +308,7 @@ static void exit_hyperv_utils(void) kfree(shut_txf_buf); kfree(time_txf_buf); kfree(hbeat_txf_buf); + vmbus_driver_unregister(&util_drv); } module_init(init_hyperv_utils); diff --git a/drivers/staging/hv/hyperv.h b/drivers/staging/hv/hyperv.h index 1747a24..c249811 100644 --- a/drivers/staging/hv/hyperv.h +++ b/drivers/staging/hv/hyperv.h @@ -27,17 +27,16 @@ #include <linux/scatterlist.h> #include <linux/list.h> +#include <linux/uuid.h> #include <linux/timer.h> #include <linux/workqueue.h> #include <linux/completion.h> #include <linux/device.h> +#include <linux/mod_devicetable.h> #include <asm/hyperv.h> -struct hv_guid { - unsigned char data[16]; -}; #define MAX_PAGE_BUFFER_COUNT 16 #define MAX_MULTIPAGE_BUFFER_COUNT 32 /* 128K */ @@ -156,8 +155,8 @@ struct hv_ring_buffer_debug_info { * struct contains the fundamental information about an offer. */ struct vmbus_channel_offer { - struct hv_guid if_type; - struct hv_guid if_instance; + uuid_le if_type; + uuid_le if_instance; u64 int_latency; /* in 100ns units */ u32 if_revision; u32 server_ctx_size; /* in bytes */ @@ -526,8 +525,8 @@ enum vmbus_channel_state { struct vmbus_channel_debug_info { u32 relid; enum vmbus_channel_state state; - struct hv_guid interfacetype; - struct hv_guid interface_instance; + uuid_le interfacetype; + uuid_le interface_instance; u32 monitorid; u32 servermonitor_pending; u32 servermonitor_latency; @@ -786,8 +785,8 @@ struct hv_dev_port_info { struct hv_device_info { u32 chn_id; u32 chn_state; - struct hv_guid chn_type; - struct hv_guid chn_instance; + uuid_le chn_type; + uuid_le chn_instance; u32 monitor_id; u32 server_monitor_pending; @@ -806,7 +805,8 @@ struct hv_driver { const char *name; /* the device type supported by this driver */ - struct hv_guid dev_type; + uuid_le dev_type; + const struct hv_vmbus_device_id *id_table; struct device_driver driver; @@ -819,10 +819,10 @@ struct hv_driver { /* Base device object */ struct hv_device { /* the device type id of this device */ - struct hv_guid dev_type; + uuid_le dev_type; /* the device instance id of this device */ - struct hv_guid dev_instance; + uuid_le dev_instance; struct device device; @@ -845,8 +845,23 @@ static inline struct hv_driver *drv_to_hv_drv(struct device_driver *d) /* Vmbus interface */ -int vmbus_child_driver_register(struct device_driver *drv); -void vmbus_child_driver_unregister(struct device_driver *drv); +#define vmbus_driver_register(driver) \ + __vmbus_driver_register(driver, THIS_MODULE, KBUILD_MODNAME) +int __must_check __vmbus_driver_register(struct hv_driver *hv_driver, + struct module *owner, + const char *mod_name); +void vmbus_driver_unregister(struct hv_driver *hv_driver); + +/** + * VMBUS_DEVICE - macro used to describe a specific hyperv vmbus device + * + * This macro is used to create a struct hv_vmbus_device_id that matches a + * specific device. + */ +#define VMBUS_DEVICE(g0, g1, g2, g3, g4, g5, g6, g7, \ + g8, g9, ga, gb, gc, gd, ge, gf) \ + .guid = { g0, g1, g2, g3, g4, g5, g6, g7, \ + g8, g9, ga, gb, gc, gd, ge, gf }, /* * Common header for Hyper-V ICs @@ -935,7 +950,7 @@ struct ictimesync_data { struct hyperv_service_callback { u8 msg_type; char *log_msg; - unsigned char data[16]; + uuid_le data; struct vmbus_channel *channel; void (*callback) (void *context); }; diff --git a/drivers/staging/hv/hyperv_net.h b/drivers/staging/hv/hyperv_net.h index 27f987b..5782fea 100644 --- a/drivers/staging/hv/hyperv_net.h +++ b/drivers/staging/hv/hyperv_net.h @@ -96,7 +96,6 @@ void netvsc_linkstatus_callback(struct hv_device *device_obj, unsigned int status); int netvsc_recv_callback(struct hv_device *device_obj, struct hv_netvsc_packet *packet); -int netvsc_initialize(struct hv_driver *drv); int rndis_filter_open(struct hv_device *dev); int rndis_filter_close(struct hv_device *dev); int rndis_filter_device_add(struct hv_device *dev, diff --git a/drivers/staging/hv/hyperv_vmbus.h b/drivers/staging/hv/hyperv_vmbus.h index 349ad80..16ca90d 100644 --- a/drivers/staging/hv/hyperv_vmbus.h +++ b/drivers/staging/hv/hyperv_vmbus.h @@ -451,8 +451,8 @@ enum { /* #define VMBUS_PORT_ID 11 */ /* 628180B8-308D-4c5e-B7DB-1BEB62E62EF4 */ -static const struct hv_guid VMBUS_SERVICE_ID = { - .data = { +static const uuid_le VMBUS_SERVICE_ID = { + .b = { 0xb8, 0x80, 0x81, 0x62, 0x8d, 0x30, 0x5e, 0x4c, 0xb7, 0xdb, 0x1b, 0xeb, 0x62, 0xe6, 0x2e, 0xf4 }, @@ -601,8 +601,8 @@ extern struct vmbus_connection vmbus_connection; /* General vmbus interface */ -struct hv_device *vmbus_child_device_create(struct hv_guid *type, - struct hv_guid *instance, +struct hv_device *vmbus_child_device_create(uuid_le *type, + uuid_le *instance, struct vmbus_channel *channel); int vmbus_child_device_register(struct hv_device *child_device_obj); diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c index dc5e5c4..b6e1fb9 100644 --- a/drivers/staging/hv/netvsc.c +++ b/drivers/staging/hv/netvsc.c @@ -32,18 +32,6 @@ #include "hyperv_net.h" -/* Globals */ -static const char *driver_name = "netvsc"; - -/* {F8615163-DF3E-46c5-913F-F2D2F965ED0E} */ -static const struct hv_guid netvsc_device_type = { - .data = { - 0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46, - 0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E - } -}; - - static struct netvsc_device *alloc_net_device(struct hv_device *device) { struct netvsc_device *net_device; @@ -172,7 +160,7 @@ static int netvsc_destroy_recv_buf(struct netvsc_device *net_device) if (ret != 0) { dev_err(&net_device->dev->device, "unable to send " "revoke receive buffer to netvsp"); - return -1; + return ret; } } @@ -187,7 +175,7 @@ static int netvsc_destroy_recv_buf(struct netvsc_device *net_device) if (ret != 0) { dev_err(&net_device->dev->device, "unable to teardown receive buffer's gpadl"); - return -1; + return -ret; } net_device->recv_buf_gpadl_handle = 0; } @@ -219,7 +207,7 @@ static int netvsc_init_recv_buf(struct hv_device *device) if (!net_device) { dev_err(&device->device, "unable to get net device..." "device being destroyed?"); - return -1; + return -ENODEV; } net_device->recv_buf = @@ -228,7 +216,7 @@ static int netvsc_init_recv_buf(struct hv_device *device) if (!net_device->recv_buf) { dev_err(&device->device, "unable to allocate receive " "buffer of size %d", net_device->recv_buf_size); - ret = -1; + ret = -ENOMEM; goto cleanup; } @@ -281,7 +269,7 @@ static int netvsc_init_recv_buf(struct hv_device *device) "initialzation with NetVsp - status %d", init_packet->msg.v1_msg. send_recv_buf_complete.status); - ret = -1; + ret = -EINVAL; goto cleanup; } @@ -293,7 +281,7 @@ static int netvsc_init_recv_buf(struct hv_device *device) net_device->recv_section = kmalloc(net_device->recv_section_cnt * sizeof(struct nvsp_1_receive_buffer_section), GFP_KERNEL); if (net_device->recv_section == NULL) { - ret = -1; + ret = -EINVAL; goto cleanup; } @@ -309,7 +297,7 @@ static int netvsc_init_recv_buf(struct hv_device *device) */ if (net_device->recv_section_cnt != 1 || net_device->recv_section->offset != 0) { - ret = -1; + ret = -EINVAL; goto cleanup; } @@ -335,7 +323,7 @@ static int netvsc_connect_vsp(struct hv_device *device) if (!net_device) { dev_err(&device->device, "unable to get net device..." "device being destroyed?"); - return -1; + return -ENODEV; } init_packet = &net_device->channel_init_pkt; @@ -366,13 +354,13 @@ static int netvsc_connect_vsp(struct hv_device *device) if (init_packet->msg.init_msg.init_complete.status != NVSP_STAT_SUCCESS) { - ret = -1; + ret = -EINVAL; goto cleanup; } if (init_packet->msg.init_msg.init_complete. negotiated_protocol_ver != NVSP_PROTOCOL_VERSION_1) { - ret = -1; + ret = -EPROTO; goto cleanup; } /* Send the ndis version */ @@ -393,10 +381,8 @@ static int netvsc_connect_vsp(struct hv_device *device) sizeof(struct nvsp_message), (unsigned long)init_packet, VM_PKT_DATA_INBAND, 0); - if (ret != 0) { - ret = -1; + if (ret != 0) goto cleanup; - } /* Post the big receive buffer to NetVSP */ ret = netvsc_init_recv_buf(device); @@ -423,7 +409,7 @@ int netvsc_device_remove(struct hv_device *device) net_device = release_outbound_net_device(device); if (!net_device) { dev_err(&device->device, "No net device present!!"); - return -1; + return -ENODEV; } /* Wait for all send completions */ @@ -513,7 +499,7 @@ int netvsc_send(struct hv_device *device, if (!net_device) { dev_err(&device->device, "net device (%p) shutting down..." "ignoring outbound packets", net_device); - return -2; + return -ENODEV; } sendMessage.hdr.msg_type = NVSP_MSG1_TYPE_SEND_RNDIS_PKT; @@ -577,7 +563,7 @@ retry_send_cmplt: if (ret == 0) { /* success */ /* no-op */ - } else if (ret == -1) { + } else if (ret == -EAGAIN) { /* no more room...wait a bit and attempt to retry 3 times */ retries++; dev_err(&device->device, "unable to send receive completion pkt" @@ -896,7 +882,7 @@ static void netvsc_channel_cb(void *context) break; } - } else if (ret == -2) { + } else if (ret == -ENOBUFS) { /* Handle large packet */ buffer = kmalloc(bytes_recvd, GFP_ATOMIC); if (buffer == NULL) { @@ -932,7 +918,7 @@ int netvsc_device_add(struct hv_device *device, void *additional_info) net_device = alloc_net_device(device); if (!net_device) { - ret = -1; + ret = -ENOMEM; goto cleanup; } @@ -961,7 +947,6 @@ int netvsc_device_add(struct hv_device *device, void *additional_info) if (ret != 0) { dev_err(&device->device, "unable to open channel: %d", ret); - ret = -1; goto cleanup; } @@ -973,7 +958,6 @@ int netvsc_device_add(struct hv_device *device, void *additional_info) if (ret != 0) { dev_err(&device->device, "unable to connect to NetVSP - %d", ret); - ret = -1; goto close; } @@ -1001,15 +985,3 @@ cleanup: return ret; } - -/* - * netvsc_initialize - Main entry point - */ -int netvsc_initialize(struct hv_driver *drv) -{ - - drv->name = driver_name; - memcpy(&drv->dev_type, &netvsc_device_type, sizeof(struct hv_guid)); - - return 0; -} diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index 61989f0..90a3198 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -33,8 +33,6 @@ #include <linux/skbuff.h> #include <linux/in.h> #include <linux/slab.h> -#include <linux/dmi.h> -#include <linux/pci.h> #include <net/arp.h> #include <net/route.h> #include <net/sock.h> @@ -340,7 +338,7 @@ static int netvsc_probe(struct hv_device *dev) net = alloc_etherdev(sizeof(struct net_device_context)); if (!net) - return -1; + return -ENOMEM; /* Set initial state */ netif_carrier_off(net); @@ -357,8 +355,6 @@ static int netvsc_probe(struct hv_device *dev) if (ret != 0) { free_netdev(net); dev_set_drvdata(&dev->device, NULL); - - netdev_err(net, "unable to add netvsc device (ret %d)\n", ret); return ret; } @@ -413,61 +409,33 @@ static int netvsc_remove(struct hv_device *dev) return 0; } +static const struct hv_vmbus_device_id id_table[] = { + /* Network guid */ + { VMBUS_DEVICE(0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46, + 0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E) }, + { }, +}; + +MODULE_DEVICE_TABLE(vmbus, id_table); + /* The one and only one */ static struct hv_driver netvsc_drv = { + .name = "netvsc", + .id_table = id_table, .probe = netvsc_probe, .remove = netvsc_remove, }; static void __exit netvsc_drv_exit(void) { - vmbus_child_driver_unregister(&netvsc_drv.driver); + vmbus_driver_unregister(&netvsc_drv); } - -static const struct dmi_system_id __initconst -hv_netvsc_dmi_table[] __maybe_unused = { - { - .ident = "Hyper-V", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), - DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"), - DMI_MATCH(DMI_BOARD_NAME, "Virtual Machine"), - }, - }, - { }, -}; -MODULE_DEVICE_TABLE(dmi, hv_netvsc_dmi_table); - static int __init netvsc_drv_init(void) { - struct hv_driver *drv = &netvsc_drv; - int ret; - - pr_info("initializing...."); - - if (!dmi_check_system(hv_netvsc_dmi_table)) - return -ENODEV; - - - /* Callback to client driver to complete the initialization */ - netvsc_initialize(drv); - - drv->driver.name = drv->name; - - /* The driver belongs to vmbus */ - ret = vmbus_child_driver_register(&drv->driver); - - return ret; + return vmbus_driver_register(&netvsc_drv); } -static const struct pci_device_id __initconst -hv_netvsc_pci_table[] __maybe_unused = { - { PCI_DEVICE(0x1414, 0x5353) }, /* VGA compatible controller */ - { 0 } -}; -MODULE_DEVICE_TABLE(pci, hv_netvsc_pci_table); - MODULE_LICENSE("GPL"); MODULE_VERSION(HV_DRV_VERSION); MODULE_DESCRIPTION("Microsoft Hyper-V network driver"); diff --git a/drivers/staging/hv/ring_buffer.c b/drivers/staging/hv/ring_buffer.c index 42f7672..9212699 100644 --- a/drivers/staging/hv/ring_buffer.c +++ b/drivers/staging/hv/ring_buffer.c @@ -390,7 +390,7 @@ int hv_ringbuffer_write(struct hv_ring_buffer_info *outring_info, /* is empty since the read index == write index */ if (bytes_avail_towrite <= totalbytes_towrite) { spin_unlock_irqrestore(&outring_info->ring_lock, flags); - return -1; + return -EAGAIN; } /* Write to the ring buffer */ @@ -450,7 +450,7 @@ int hv_ringbuffer_peek(struct hv_ring_buffer_info *Inring_info, spin_unlock_irqrestore(&Inring_info->ring_lock, flags); - return -1; + return -EAGAIN; } /* Convert to byte offset */ @@ -496,7 +496,7 @@ int hv_ringbuffer_read(struct hv_ring_buffer_info *inring_info, void *buffer, if (bytes_avail_toread < buflen) { spin_unlock_irqrestore(&inring_info->ring_lock, flags); - return -1; + return -EAGAIN; } next_read_location = diff --git a/drivers/staging/hv/rndis_filter.c b/drivers/staging/hv/rndis_filter.c index dbb5201..6db48b9 100644 --- a/drivers/staging/hv/rndis_filter.c +++ b/drivers/staging/hv/rndis_filter.c @@ -358,14 +358,14 @@ int rndis_filter_receive(struct hv_device *dev, if (!net_dev->extension) { dev_err(&dev->device, "got rndis message but no rndis device - " "dropping this message!\n"); - return -1; + return -ENODEV; } rndis_dev = (struct rndis_device *)net_dev->extension; if (rndis_dev->state == RNDIS_DEV_UNINITIALIZED) { dev_err(&dev->device, "got rndis message but rndis device " "uninitialized...dropping this message!\n"); - return -1; + return -ENODEV; } rndis_hdr = (struct rndis_message *)kmap_atomic( @@ -437,8 +437,8 @@ static int rndis_filter_query_device(struct rndis_device *dev, u32 oid, request = get_rndis_request(dev, REMOTE_NDIS_QUERY_MSG, RNDIS_MESSAGE_SIZE(struct rndis_query_request)); if (!request) { - ret = -1; - goto Cleanup; + ret = -ENOMEM; + goto cleanup; } /* Setup the rndis query */ @@ -450,12 +450,12 @@ static int rndis_filter_query_device(struct rndis_device *dev, u32 oid, ret = rndis_filter_send_request(dev, request); if (ret != 0) - goto Cleanup; + goto cleanup; t = wait_for_completion_timeout(&request->wait_event, 5*HZ); if (t == 0) { ret = -ETIMEDOUT; - goto Cleanup; + goto cleanup; } /* Copy the response back */ @@ -463,7 +463,7 @@ static int rndis_filter_query_device(struct rndis_device *dev, u32 oid, if (query_complete->info_buflen > inresult_size) { ret = -1; - goto Cleanup; + goto cleanup; } memcpy(result, @@ -473,7 +473,7 @@ static int rndis_filter_query_device(struct rndis_device *dev, u32 oid, *result_size = query_complete->info_buflen; -Cleanup: +cleanup: if (request) put_rndis_request(dev, request); @@ -511,8 +511,8 @@ static int rndis_filter_set_packet_filter(struct rndis_device *dev, RNDIS_MESSAGE_SIZE(struct rndis_set_request) + sizeof(u32)); if (!request) { - ret = -1; - goto Cleanup; + ret = -ENOMEM; + goto cleanup; } /* Setup the rndis set */ @@ -526,30 +526,27 @@ static int rndis_filter_set_packet_filter(struct rndis_device *dev, ret = rndis_filter_send_request(dev, request); if (ret != 0) - goto Cleanup; + goto cleanup; t = wait_for_completion_timeout(&request->wait_event, 5*HZ); if (t == 0) { - ret = -1; dev_err(&dev->net_dev->dev->device, "timeout before we got a set response...\n"); /* * We can't deallocate the request since we may still receive a * send completion for it. */ - goto Exit; + goto exit; } else { - if (ret > 0) - ret = 0; set_complete = &request->response_msg.msg.set_complete; status = set_complete->status; } -Cleanup: +cleanup: if (request) put_rndis_request(dev, request); -Exit: +exit: return ret; } @@ -565,8 +562,8 @@ static int rndis_filter_init_device(struct rndis_device *dev) request = get_rndis_request(dev, REMOTE_NDIS_INITIALIZE_MSG, RNDIS_MESSAGE_SIZE(struct rndis_initialize_request)); if (!request) { - ret = -1; - goto Cleanup; + ret = -ENOMEM; + goto cleanup; } /* Setup the rndis set */ @@ -581,7 +578,7 @@ static int rndis_filter_init_device(struct rndis_device *dev) ret = rndis_filter_send_request(dev, request); if (ret != 0) { dev->state = RNDIS_DEV_UNINITIALIZED; - goto Cleanup; + goto cleanup; } @@ -589,7 +586,7 @@ static int rndis_filter_init_device(struct rndis_device *dev) if (t == 0) { ret = -ETIMEDOUT; - goto Cleanup; + goto cleanup; } init_complete = &request->response_msg.msg.init_complete; @@ -599,10 +596,10 @@ static int rndis_filter_init_device(struct rndis_device *dev) ret = 0; } else { dev->state = RNDIS_DEV_UNINITIALIZED; - ret = -1; + ret = -EINVAL; } -Cleanup: +cleanup: if (request) put_rndis_request(dev, request); @@ -618,7 +615,7 @@ static void rndis_filter_halt_device(struct rndis_device *dev) request = get_rndis_request(dev, REMOTE_NDIS_HALT_MSG, RNDIS_MESSAGE_SIZE(struct rndis_halt_request)); if (!request) - goto Cleanup; + goto cleanup; /* Setup the rndis set */ halt = &request->request_msg.msg.halt_req; @@ -629,7 +626,7 @@ static void rndis_filter_halt_device(struct rndis_device *dev) dev->state = RNDIS_DEV_UNINITIALIZED; -Cleanup: +cleanup: if (request) put_rndis_request(dev, request); return; @@ -676,7 +673,7 @@ int rndis_filter_device_add(struct hv_device *dev, rndisDevice = get_rndis_device(); if (!rndisDevice) - return -1; + return -ENODEV; /* * Let the inner driver handle this first to create the netvsc channel diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index 3029786..827b6a3 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -111,7 +111,7 @@ static int storvsc_channel_init(struct hv_device *device) stor_device = get_stor_device(device); if (!stor_device) - return -1; + return -ENODEV; request = &stor_device->init_request; vstor_packet = &request->vstor_packet; @@ -125,8 +125,6 @@ static int storvsc_channel_init(struct hv_device *device) vstor_packet->operation = VSTOR_OPERATION_BEGIN_INITIALIZATION; vstor_packet->flags = REQUEST_COMPLETION_FLAG; - DPRINT_INFO(STORVSC, "BEGIN_INITIALIZATION_OPERATION..."); - ret = vmbus_sendpacket(device->channel, vstor_packet, sizeof(struct vstor_packet), (unsigned long)request, @@ -145,7 +143,6 @@ static int storvsc_channel_init(struct hv_device *device) vstor_packet->status != 0) goto cleanup; - DPRINT_INFO(STORVSC, "QUERY_PROTOCOL_VERSION_OPERATION..."); /* reuse the packet for version range supported */ memset(vstor_packet, 0, sizeof(struct vstor_packet)); @@ -169,13 +166,10 @@ static int storvsc_channel_init(struct hv_device *device) goto cleanup; } - /* TODO: Check returned version */ if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || vstor_packet->status != 0) goto cleanup; - /* Query channel properties */ - DPRINT_INFO(STORVSC, "QUERY_PROPERTIES_OPERATION..."); memset(vstor_packet, 0, sizeof(struct vstor_packet)); vstor_packet->operation = VSTOR_OPERATION_QUERY_PROPERTIES; @@ -198,7 +192,6 @@ static int storvsc_channel_init(struct hv_device *device) goto cleanup; } - /* TODO: Check returned version */ if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || vstor_packet->status != 0) goto cleanup; @@ -207,8 +200,6 @@ static int storvsc_channel_init(struct hv_device *device) stor_device->target_id = vstor_packet->storage_channel_properties.target_id; - DPRINT_INFO(STORVSC, "END_INITIALIZATION_OPERATION..."); - memset(vstor_packet, 0, sizeof(struct vstor_packet)); vstor_packet->operation = VSTOR_OPERATION_END_INITIALIZATION; vstor_packet->flags = REQUEST_COMPLETION_FLAG; @@ -232,7 +223,6 @@ static int storvsc_channel_init(struct hv_device *device) vstor_packet->status != 0) goto cleanup; - DPRINT_INFO(STORVSC, "**** storage channel up and running!! ****"); cleanup: put_stor_device(device); @@ -305,13 +295,8 @@ static void storvsc_on_receive(struct hv_device *device, storvsc_on_io_completion(device, vstor_packet, request); break; case VSTOR_OPERATION_REMOVE_DEVICE: - DPRINT_INFO(STORVSC, "REMOVE_DEVICE_OPERATION"); - /* TODO: */ - break; default: - DPRINT_INFO(STORVSC, "Unknown operation received - %d", - vstor_packet->operation); break; } } @@ -376,7 +361,7 @@ static int storvsc_connect_to_vsp(struct hv_device *device, u32 ring_size) storvsc_on_channel_callback, device); if (ret != 0) - return -1; + return ret; ret = storvsc_channel_init(device); @@ -392,28 +377,29 @@ int storvsc_dev_add(struct hv_device *device, device_info = (struct storvsc_device_info *)additional_info; stor_device = alloc_stor_device(device); - if (!stor_device) { - ret = -1; - goto cleanup; - } + if (!stor_device) + return -ENOMEM; /* Save the channel properties to our storvsc channel */ - /* FIXME: */ /* * If we support more than 1 scsi channel, we need to set the * port number here to the scsi channel but how do we get the - * scsi channel prior to the bus scan + * scsi channel prior to the bus scan. + * + * The host does not support this. */ stor_device->port_number = device_info->port_number; /* Send it back up */ ret = storvsc_connect_to_vsp(device, device_info->ring_buffer_size); - + if (ret) { + free_stor_device(stor_device); + return ret; + } device_info->path_id = stor_device->path_id; device_info->target_id = stor_device->target_id; -cleanup: return ret; } @@ -421,9 +407,6 @@ int storvsc_dev_remove(struct hv_device *device) { struct storvsc_device *stor_device; - DPRINT_INFO(STORVSC, "disabling storage device (%p)...", - device->ext); - stor_device = release_stor_device(device); /* @@ -454,7 +437,7 @@ int storvsc_do_io(struct hv_device *device, stor_device = get_stor_device(device); if (!stor_device) - return -2; + return -ENODEV; request->device = device; @@ -561,4 +544,3 @@ int storvsc_get_major_info(struct storvsc_device_info *device_info, return -ENODEV; } - diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 7effaf3..faa8d57 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -24,7 +24,6 @@ #include <linux/module.h> #include <linux/device.h> #include <linux/blkdev.h> -#include <linux/dmi.h> #include <scsi/scsi.h> #include <scsi/scsi_cmnd.h> #include <scsi/scsi_host.h> @@ -42,16 +41,6 @@ static int storvsc_ringbuffer_size = STORVSC_RING_BUFFER_SIZE; module_param(storvsc_ringbuffer_size, int, S_IRUGO); MODULE_PARM_DESC(storvsc_ringbuffer_size, "Ring buffer size (bytes)"); -static const char *driver_name = "storvsc"; - -/* {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} */ -static const struct hv_guid stor_vsci_device_type = { - .data = { - 0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d, - 0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f - } -}; - struct hv_host_device { struct hv_device *dev; struct kmem_cache *request_pool; @@ -357,7 +346,7 @@ static int storvsc_host_reset(struct hv_device *device) stor_device = get_stor_device(device); if (!stor_device) - return -1; + return -ENODEV; request = &stor_device->reset_request; vstor_packet = &request->vstor_packet; @@ -589,7 +578,7 @@ retry_request: /* Invokes the vsc to start an IO */ ret = storvsc_do_io(dev, &cmd_request->request); - if (ret == -1) { + if (ret == -EAGAIN) { /* no more space */ if (cmd_request->bounce_sgl_count) { @@ -646,7 +635,14 @@ static struct scsi_host_template scsi_driver = { .dma_boundary = PAGE_SIZE-1, }; +static const struct hv_vmbus_device_id id_table[] = { + /* SCSI guid */ + { VMBUS_DEVICE(0xd9, 0x63, 0x61, 0xba, 0xa1, 0x04, 0x29, 0x4d, + 0xb6, 0x05, 0x72, 0xe2, 0xff, 0xb1, 0xdc, 0x7f) }, + { }, +}; +MODULE_DEVICE_TABLE(vmbus, id_table); /* * storvsc_probe - Add a new device for this driver */ @@ -689,7 +685,7 @@ static int storvsc_probe(struct hv_device *device) if (ret != 0) { kmem_cache_destroy(host_dev->request_pool); scsi_host_put(host); - return -1; + return -ENODEV; } host_dev->path = device_info.path_id; @@ -710,7 +706,7 @@ static int storvsc_probe(struct hv_device *device) kmem_cache_destroy(host_dev->request_pool); scsi_host_put(host); - return -1; + return -ENODEV; } scsi_scan_host(host); @@ -720,35 +716,14 @@ static int storvsc_probe(struct hv_device *device) /* The one and only one */ static struct hv_driver storvsc_drv = { + .name = "storvsc", + .id_table = id_table, .probe = storvsc_probe, .remove = storvsc_remove, }; -/* - * We use a DMI table to determine if we should autoload this driver This is - * needed by distro tools to determine if the hyperv drivers should be - * installed and/or configured. We don't do anything else with the table, but - * it needs to be present. - */ - -static const struct dmi_system_id __initconst -hv_stor_dmi_table[] __maybe_unused = { - { - .ident = "Hyper-V", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"), - DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"), - DMI_MATCH(DMI_BOARD_NAME, "Virtual Machine"), - }, - }, - { }, -}; -MODULE_DEVICE_TABLE(dmi, hv_stor_dmi_table); - static int __init storvsc_drv_init(void) { - int ret; - struct hv_driver *drv = &storvsc_drv; u32 max_outstanding_req_per_channel; /* @@ -757,32 +732,22 @@ static int __init storvsc_drv_init(void) * the ring buffer indices) by the max request size (which is * vmbus_channel_packet_multipage_buffer + struct vstor_packet + u64) */ - max_outstanding_req_per_channel = - ((storvsc_ringbuffer_size - PAGE_SIZE) / - ALIGN(MAX_MULTIPAGE_BUFFER_PACKET + - sizeof(struct vstor_packet) + sizeof(u64), - sizeof(u64))); - - memcpy(&drv->dev_type, &stor_vsci_device_type, - sizeof(struct hv_guid)); + ((storvsc_ringbuffer_size - PAGE_SIZE) / + ALIGN(MAX_MULTIPAGE_BUFFER_PACKET + + sizeof(struct vstor_packet) + sizeof(u64), + sizeof(u64))); if (max_outstanding_req_per_channel < STORVSC_MAX_IO_REQUESTS) - return -1; - - drv->driver.name = driver_name; - + return -EINVAL; - /* The driver belongs to vmbus */ - ret = vmbus_child_driver_register(&drv->driver); - - return ret; + return vmbus_driver_register(&storvsc_drv); } static void __exit storvsc_drv_exit(void) { - vmbus_child_driver_unregister(&storvsc_drv.driver); + vmbus_driver_unregister(&storvsc_drv); } MODULE_LICENSE("GPL"); diff --git a/drivers/staging/hv/tools/hv_kvp_daemon.c b/drivers/staging/hv/tools/hv_kvp_daemon.c index a4a407f..11224ed 100644 --- a/drivers/staging/hv/tools/hv_kvp_daemon.c +++ b/drivers/staging/hv/tools/hv_kvp_daemon.c @@ -116,7 +116,16 @@ void kvp_get_os_info(void) uname(&uts_buf); os_build = uts_buf.release; - processor_arch= uts_buf.machine; + processor_arch = uts_buf.machine; + + /* + * The current windows host (win7) expects the build + * string to be of the form: x.y.z + * Strip additional information we may have. + */ + p = strchr(os_build, '-'); + if (p) + *p = '\0'; file = fopen("/etc/SuSE-release", "r"); if (file != NULL) @@ -264,22 +273,20 @@ static int kvp_get_domain_name(char *buffer, int length) { struct addrinfo hints, *info ; - gethostname(buffer, length); int error = 0; + gethostname(buffer, length); memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; /*Get only ipv4 addrinfo. */ hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_CANONNAME; - error = getaddrinfo(buffer, "http", &hints, &info); + error = getaddrinfo(buffer, NULL, &hints, &info); if (error != 0) { strcpy(buffer, "getaddrinfo failed\n"); - error = 1; - goto get_domain_done; + return error; } strcpy(buffer, info->ai_canonname); -get_domain_done: freeaddrinfo(info); return error; } diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 1c949f5..be62b62 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -28,8 +28,6 @@ #include <linux/irq.h> #include <linux/interrupt.h> #include <linux/sysctl.h> -#include <linux/pci.h> -#include <linux/dmi.h> #include <linux/slab.h> #include <linux/acpi.h> #include <acpi/acpi_bus.h> @@ -46,8 +44,6 @@ static struct tasklet_struct event_dpc; unsigned int vmbus_loglevel = (ALL_MODULES << 16 | INFO_LVL); EXPORT_SYMBOL(vmbus_loglevel); - /* (ALL_MODULES << 16 | DEBUG_LVL_ENTEREXIT); */ - /* (((VMBUS | VMBUS_DRV)<<16) | DEBUG_LVL_ENTEREXIT); */ static struct completion probe_event; static int irq; @@ -65,9 +61,9 @@ static void get_channel_info(struct hv_device *device, info->chn_id = debug_info.relid; info->chn_state = debug_info.state; memcpy(&info->chn_type, &debug_info.interfacetype, - sizeof(struct hv_guid)); + sizeof(uuid_le)); memcpy(&info->chn_instance, &debug_info.interface_instance, - sizeof(struct hv_guid)); + sizeof(uuid_le)); info->monitor_id = debug_info.monitorid; @@ -117,41 +113,41 @@ static ssize_t vmbus_show_device_attr(struct device *dev, if (!strcmp(dev_attr->attr.name, "class_id")) { return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-" "%02x%02x%02x%02x%02x%02x%02x%02x}\n", - device_info.chn_type.data[3], - device_info.chn_type.data[2], - device_info.chn_type.data[1], - device_info.chn_type.data[0], - device_info.chn_type.data[5], - device_info.chn_type.data[4], - device_info.chn_type.data[7], - device_info.chn_type.data[6], - device_info.chn_type.data[8], - device_info.chn_type.data[9], - device_info.chn_type.data[10], - device_info.chn_type.data[11], - device_info.chn_type.data[12], - device_info.chn_type.data[13], - device_info.chn_type.data[14], - device_info.chn_type.data[15]); + device_info.chn_type.b[3], + device_info.chn_type.b[2], + device_info.chn_type.b[1], + device_info.chn_type.b[0], + device_info.chn_type.b[5], + device_info.chn_type.b[4], + device_info.chn_type.b[7], + device_info.chn_type.b[6], + device_info.chn_type.b[8], + device_info.chn_type.b[9], + device_info.chn_type.b[10], + device_info.chn_type.b[11], + device_info.chn_type.b[12], + device_info.chn_type.b[13], + device_info.chn_type.b[14], + device_info.chn_type.b[15]); } else if (!strcmp(dev_attr->attr.name, "device_id")) { return sprintf(buf, "{%02x%02x%02x%02x-%02x%02x-%02x%02x-" "%02x%02x%02x%02x%02x%02x%02x%02x}\n", - device_info.chn_instance.data[3], - device_info.chn_instance.data[2], - device_info.chn_instance.data[1], - device_info.chn_instance.data[0], - device_info.chn_instance.data[5], - device_info.chn_instance.data[4], - device_info.chn_instance.data[7], - device_info.chn_instance.data[6], - device_info.chn_instance.data[8], - device_info.chn_instance.data[9], - device_info.chn_instance.data[10], - device_info.chn_instance.data[11], - device_info.chn_instance.data[12], - device_info.chn_instance.data[13], - device_info.chn_instance.data[14], - device_info.chn_instance.data[15]); + device_info.chn_instance.b[3], + device_info.chn_instance.b[2], + device_info.chn_instance.b[1], + device_info.chn_instance.b[0], + device_info.chn_instance.b[5], + device_info.chn_instance.b[4], + device_info.chn_instance.b[7], + device_info.chn_instance.b[6], + device_info.chn_instance.b[8], + device_info.chn_instance.b[9], + device_info.chn_instance.b[10], + device_info.chn_instance.b[11], + device_info.chn_instance.b[12], + device_info.chn_instance.b[13], + device_info.chn_instance.b[14], + device_info.chn_instance.b[15]); } else if (!strcmp(dev_attr->attr.name, "state")) { return sprintf(buf, "%d\n", device_info.chn_state); } else if (!strcmp(dev_attr->attr.name, "id")) { @@ -238,58 +234,31 @@ static struct device_attribute vmbus_device_attrs[] = { * This routine is invoked when a device is added or removed on the vmbus to * generate a uevent to udev in the userspace. The udev will then look at its * rule and the uevent generated here to load the appropriate driver + * + * The alias string will be of the form vmbus:guid where guid is the string + * representation of the device guid (each byte of the guid will be + * represented with two hex characters. */ static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env) { struct hv_device *dev = device_to_hv_device(device); - int ret; + int i, ret; + char alias_name[((sizeof((struct hv_vmbus_device_id *)0)->guid) + 1) * 2]; - ret = add_uevent_var(env, "VMBUS_DEVICE_CLASS_GUID={" - "%02x%02x%02x%02x-%02x%02x-%02x%02x-" - "%02x%02x%02x%02x%02x%02x%02x%02x}", - dev->dev_type.data[3], - dev->dev_type.data[2], - dev->dev_type.data[1], - dev->dev_type.data[0], - dev->dev_type.data[5], - dev->dev_type.data[4], - dev->dev_type.data[7], - dev->dev_type.data[6], - dev->dev_type.data[8], - dev->dev_type.data[9], - dev->dev_type.data[10], - dev->dev_type.data[11], - dev->dev_type.data[12], - dev->dev_type.data[13], - dev->dev_type.data[14], - dev->dev_type.data[15]); + for (i = 0; i < ((sizeof((struct hv_vmbus_device_id *)0)->guid) * 2); i += 2) + sprintf(&alias_name[i], "%02x", dev->dev_type.b[i/2]); - if (ret) - return ret; + ret = add_uevent_var(env, "MODALIAS=vmbus:%s", alias_name); + return ret; +} - ret = add_uevent_var(env, "VMBUS_DEVICE_DEVICE_GUID={" - "%02x%02x%02x%02x-%02x%02x-%02x%02x-" - "%02x%02x%02x%02x%02x%02x%02x%02x}", - dev->dev_instance.data[3], - dev->dev_instance.data[2], - dev->dev_instance.data[1], - dev->dev_instance.data[0], - dev->dev_instance.data[5], - dev->dev_instance.data[4], - dev->dev_instance.data[7], - dev->dev_instance.data[6], - dev->dev_instance.data[8], - dev->dev_instance.data[9], - dev->dev_instance.data[10], - dev->dev_instance.data[11], - dev->dev_instance.data[12], - dev->dev_instance.data[13], - dev->dev_instance.data[14], - dev->dev_instance.data[15]); - if (ret) - return ret; +static uuid_le null_guid; - return 0; +static inline bool is_null_guid(const __u8 *guid) +{ + if (memcmp(guid, &null_guid, sizeof(uuid_le))) + return false; + return true; } @@ -298,16 +267,16 @@ static int vmbus_uevent(struct device *device, struct kobj_uevent_env *env) */ static int vmbus_match(struct device *device, struct device_driver *driver) { - int match = 0; struct hv_driver *drv = drv_to_hv_drv(driver); struct hv_device *hv_dev = device_to_hv_device(device); + const struct hv_vmbus_device_id *id_array = drv->id_table; - /* We found our driver ? */ - if (memcmp(&hv_dev->dev_type, &drv->dev_type, - sizeof(struct hv_guid)) == 0) - match = 1; + for (; !is_null_guid(id_array->guid); id_array++) + if (!memcmp(&id_array->guid, &hv_dev->dev_type.b, + sizeof(struct hv_vmbus_device_id))) + return 1; - return match; + return 0; } /* @@ -581,58 +550,57 @@ static int vmbus_bus_init(int irq) } /** - * vmbus_child_driver_register() - Register a vmbus's child driver - * @drv: Pointer to driver structure you want to register - * + * __vmbus_child_driver_register - Register a vmbus's driver + * @drv: Pointer to driver structure you want to register + * @owner: owner module of the drv + * @mod_name: module name string * * Registers the given driver with Linux through the 'driver_register()' call - * And sets up the hyper-v vmbus handling for this driver. + * and sets up the hyper-v vmbus handling for this driver. * It will return the state of the 'driver_register()' call. * - * Mainly used by Hyper-V drivers. */ -int vmbus_child_driver_register(struct device_driver *drv) +int __vmbus_driver_register(struct hv_driver *hv_driver, struct module *owner, const char *mod_name) { int ret; - pr_info("child driver registering - name %s\n", drv->name); + pr_info("registering driver %s\n", hv_driver->name); - /* The child driver on this vmbus */ - drv->bus = &hv_bus; + hv_driver->driver.name = hv_driver->name; + hv_driver->driver.owner = owner; + hv_driver->driver.mod_name = mod_name; + hv_driver->driver.bus = &hv_bus; - ret = driver_register(drv); + ret = driver_register(&hv_driver->driver); vmbus_request_offers(); return ret; } -EXPORT_SYMBOL(vmbus_child_driver_register); +EXPORT_SYMBOL_GPL(__vmbus_driver_register); /** - * vmbus_child_driver_unregister() - Unregister a vmbus's child driver - * @drv: Pointer to driver structure you want to un-register - * + * vmbus_driver_unregister() - Unregister a vmbus's driver + * @drv: Pointer to driver structure you want to un-register * - * Un-register the given driver with Linux through the 'driver_unregister()' - * call. And ungegisters the driver from the Hyper-V vmbus handler. - * - * Mainly used by Hyper-V drivers. + * Un-register the given driver that was previous registered with a call to + * vmbus_driver_register() */ -void vmbus_child_driver_unregister(struct device_driver *drv) +void vmbus_driver_unregister(struct hv_driver *hv_driver) { - pr_info("child driver unregistering - name %s\n", drv->name); + pr_info("unregistering driver %s\n", hv_driver->name); - driver_unregister(drv); + driver_unregister(&hv_driver->driver); } -EXPORT_SYMBOL(vmbus_child_driver_unregister); +EXPORT_SYMBOL_GPL(vmbus_driver_unregister); /* * vmbus_child_device_create - Creates and registers a new child device * on the vmbus. */ -struct hv_device *vmbus_child_device_create(struct hv_guid *type, - struct hv_guid *instance, +struct hv_device *vmbus_child_device_create(uuid_le *type, + uuid_le *instance, struct vmbus_channel *channel) { struct hv_device *child_device_obj; @@ -645,9 +613,9 @@ struct hv_device *vmbus_child_device_create(struct hv_guid *type, } child_device_obj->channel = channel; - memcpy(&child_device_obj->dev_type, type, sizeof(struct hv_guid)); + memcpy(&child_device_obj->dev_type, type, sizeof(uuid_le)); memcpy(&child_device_obj->dev_instance, instance, - sizeof(struct hv_guid)); + sizeof(uuid_le)); return child_device_obj; @@ -754,21 +722,9 @@ static struct acpi_driver vmbus_acpi_driver = { }, }; -/* - * We use a PCI table to determine if we should autoload this driver This is - * needed by distro tools to determine if the hyperv drivers should be - * installed and/or configured. We don't do anything else with the table, but - * it needs to be present. - */ -static const struct pci_device_id microsoft_hv_pci_table[] = { - { PCI_DEVICE(0x1414, 0x5353) }, /* VGA compatible controller */ - { 0 } -}; -MODULE_DEVICE_TABLE(pci, microsoft_hv_pci_table); - static int __init hv_acpi_init(void) { - int ret; + int ret, t; init_completion(&probe_event); @@ -781,16 +737,25 @@ static int __init hv_acpi_init(void) if (ret) return ret; - wait_for_completion(&probe_event); + t = wait_for_completion_timeout(&probe_event, 5*HZ); + if (t == 0) { + ret = -ETIMEDOUT; + goto cleanup; + } if (irq <= 0) { - acpi_bus_unregister_driver(&vmbus_acpi_driver); - return -ENODEV; + ret = -ENODEV; + goto cleanup; } ret = vmbus_bus_init(irq); if (ret) - acpi_bus_unregister_driver(&vmbus_acpi_driver); + goto cleanup; + + return 0; + +cleanup: + acpi_bus_unregister_driver(&vmbus_acpi_driver); return ret; } diff --git a/drivers/staging/iio/Documentation/sysfs-bus-iio b/drivers/staging/iio/Documentation/sysfs-bus-iio index 467c49a..c19dbf4 100644 --- a/drivers/staging/iio/Documentation/sysfs-bus-iio +++ b/drivers/staging/iio/Documentation/sysfs-bus-iio @@ -2,7 +2,7 @@ What: /sys/bus/iio/devices/deviceX KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: - Hardware chip or device accessed by on communication port. + Hardware chip or device accessed by one communication port. Corresponds to a grouping of sensor channels. X is the IIO index of the device. @@ -711,3 +711,24 @@ Contact: linux-iio@xxxxxxxxxxxxxxx Description: This attribute is used to read the amount of quadrature error present in the device at a given time. + +What: /sys/.../iio:deviceX/ac_excitation_en +KernelVersion: 3.1.0 +Contact: linux-iio@vger.kernel.org +Description: + This attribute, if available, is used to enable the AC + excitation mode found on some converters. In ac excitation mode, + the polarity of the excitation voltage is reversed on + alternate cycles, to eliminate DC errors. + +What: /sys/.../iio:deviceX/bridge_switch_en +KernelVersion: 3.1.0 +Contact: linux-iio@vger.kernel.org +Description: + This attribute, if available, is used to close or open the + bridge power down switch found on some converters. + In bridge applications, such as strain gauges and load cells, + the bridge itself consumes the majority of the current in the + system. To minimize the current consumption of the system, + the bridge can be disconnected (when it is not being used + using the bridge_switch_en attribute. diff --git a/drivers/staging/iio/Documentation/sysfs-bus-iio-adc-ad7280a b/drivers/staging/iio/Documentation/sysfs-bus-iio-adc-ad7280a new file mode 100644 index 0000000..863d385 --- /dev/null +++ b/drivers/staging/iio/Documentation/sysfs-bus-iio-adc-ad7280a @@ -0,0 +1,21 @@ +What: /sys/bus/iio/devices/deviceX/inY-inZ_balance_switch_en +KernelVersion: 3.0.0 +Contact: linux-iio@vger.kernel.org +Description: + Writing 1 enables the cell balance output switch corresponding + to input Y. Writing 0 disables it. If the inY-inZ_balance_timer + is set to a none zero value, the corresponding switch will + enable for the programmed amount of time, before it + automatically disables. + +What: /sys/bus/iio/devices/deviceX/inY-inZ_balance_timer +KernelVersion: 3.0.0 +Contact: linux-iio@vger.kernel.org +Description: + The inY-inZ_balance_timer file allows the user to program + individual times for each cell balance output. The AD7280A + allows the user to set the timer to a value from 0 minutes to + 36.9 minutes. The resolution of the timer is 71.5 sec. + The value written is the on-time in milliseconds. When the + timer value is set 0, the timer is disabled. The cell balance + outputs are controlled only by inY-inZ_balance_switch_en. diff --git a/drivers/staging/iio/Documentation/sysfs-bus-iio-impedance-analyzer-ad5933 b/drivers/staging/iio/Documentation/sysfs-bus-iio-impedance-analyzer-ad5933 new file mode 100644 index 0000000..79c7e88 --- /dev/null +++ b/drivers/staging/iio/Documentation/sysfs-bus-iio-impedance-analyzer-ad5933 @@ -0,0 +1,30 @@ +What: /sys/bus/iio/devices/iio:deviceX/outY_freq_start +KernelVersion: 3.1.0 +Contact: linux-iio@vger.kernel.org +Description: + Frequency sweep start frequency in Hz. + +What: /sys/bus/iio/devices/iio:deviceX/outY_freq_increment +KernelVersion: 3.1.0 +Contact: linux-iio@vger.kernel.org +Description: + Frequency increment in Hz (step size) between consecutive + frequency points along the sweep. + +What: /sys/bus/iio/devices/iio:deviceX/outY_freq_points +KernelVersion: 3.1.0 +Contact: linux-iio@vger.kernel.org +Description: + Number of frequency points (steps) in the frequency sweep. + This value, in conjunction with the outY_freq_start and the + outY_freq_increment, determines the frequency sweep range + for the sweep operation. + +What: /sys/bus/iio/devices/iio:deviceX/outY_settling_cycles +KernelVersion: 3.1.0 +Contact: linux-iio@vger.kernel.org +Description: + Number of output excitation cycles (settling time cycles) + that are allowed to pass through the unknown impedance, + after each frequency increment, and before the ADC is triggered + to perform a conversion sequence of the response signal. diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig index d329635..7526567 100644 --- a/drivers/staging/iio/Kconfig +++ b/drivers/staging/iio/Kconfig @@ -62,6 +62,7 @@ source "drivers/staging/iio/addac/Kconfig" source "drivers/staging/iio/dac/Kconfig" source "drivers/staging/iio/dds/Kconfig" source "drivers/staging/iio/gyro/Kconfig" +source "drivers/staging/iio/impedance-analyzer/Kconfig" source "drivers/staging/iio/imu/Kconfig" source "drivers/staging/iio/light/Kconfig" source "drivers/staging/iio/magnetometer/Kconfig" diff --git a/drivers/staging/iio/Makefile b/drivers/staging/iio/Makefile index bb5c95c..eaff649 100644 --- a/drivers/staging/iio/Makefile +++ b/drivers/staging/iio/Makefile @@ -16,6 +16,7 @@ obj-y += addac/ obj-y += dac/ obj-y += dds/ obj-y += gyro/ +obj-y += impedance-analyzer/ obj-y += imu/ obj-y += light/ obj-y += magnetometer/ diff --git a/drivers/staging/iio/accel/accel.h b/drivers/staging/iio/accel/accel.h deleted file mode 100644 index 50651f8..0000000 --- a/drivers/staging/iio/accel/accel.h +++ /dev/null @@ -1,87 +0,0 @@ - -#include "../sysfs.h" - -/* Accelerometer types of attribute */ -#define IIO_DEV_ATTR_ACCEL_OFFSET(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(accel_offset, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_ACCEL_X_OFFSET(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(accel_x_offset, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_ACCEL_Y_OFFSET(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(accel_y_offset, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_ACCEL_Z_OFFSET(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(accel_z_offset, _mode, _show, _store, _addr) - -#define IIO_CONST_ATTR_ACCEL_SCALE(_string) \ - IIO_CONST_ATTR(accel_scale, _string) - -#define IIO_DEV_ATTR_ACCEL_SCALE(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(accel_scale, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_ACCEL_X_SCALE(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(accel_x_scale, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_ACCEL_Y_SCALE(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(accel_y_scale, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_ACCEL_Z_SCALE(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(accel_z_scale, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_ACCEL_CALIBBIAS(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(accel_calibbias, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_ACCEL_X_CALIBBIAS(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(accel_x_calibbias, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_ACCEL_Y_CALIBBIAS(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(accel_y_calibbias, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_ACCEL_Z_CALIBBIAS(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(accel_z_calibbias, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_ACCEL_CALIBSCALE(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(accel_calibscale, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_ACCEL_X_CALIBSCALE(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(accel_x_calibscale, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_ACCEL_Y_CALIBSCALE(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(accel_y_calibscale, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_ACCEL_Z_CALIBSCALE(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(accel_z_calibscale, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_ACCEL(_show, _addr) \ - IIO_DEVICE_ATTR(accel_raw, S_IRUGO, _show, NULL, _addr) - -#define IIO_DEV_ATTR_ACCEL_X(_show, _addr) \ - IIO_DEVICE_ATTR(accel_x_raw, S_IRUGO, _show, NULL, _addr) - -#define IIO_DEV_ATTR_ACCEL_Y(_show, _addr) \ - IIO_DEVICE_ATTR(accel_y_raw, S_IRUGO, _show, NULL, _addr) - -#define IIO_DEV_ATTR_ACCEL_Z(_show, _addr) \ - IIO_DEVICE_ATTR(accel_z_raw, S_IRUGO, _show, NULL, _addr) - -#define IIO_DEV_ATTR_ACCEL_XY(_show, _addr) \ - IIO_DEVICE_ATTR(accel_xy, S_IRUGO, _show, NULL, _addr) - -#define IIO_DEV_ATTR_ACCEL_PEAK(_show, _addr) \ - IIO_DEVICE_ATTR(accel_peak, S_IRUGO, _show, NULL, _addr) - -#define IIO_DEV_ATTR_ACCEL_XPEAK(_show, _addr) \ - IIO_DEVICE_ATTR(accel_xpeak, S_IRUGO, _show, NULL, _addr) - -#define IIO_DEV_ATTR_ACCEL_YPEAK(_show, _addr) \ - IIO_DEVICE_ATTR(accel_ypeak, S_IRUGO, _show, NULL, _addr) - -#define IIO_DEV_ATTR_ACCEL_ZPEAK(_show, _addr) \ - IIO_DEVICE_ATTR(accel_zpeak, S_IRUGO, _show, NULL, _addr) - -#define IIO_DEV_ATTR_ACCEL_XYPEAK(_show, _addr) \ - IIO_DEVICE_ATTR(accel_xypeak, S_IRUGO, _show, NULL, _addr) - -#define IIO_DEV_ATTR_ACCEL_XYZPEAK(_show, _addr) \ - IIO_DEVICE_ATTR(accel_xyzpeak, S_IRUGO, _show, NULL, _addr) diff --git a/drivers/staging/iio/accel/adis16201_core.c b/drivers/staging/iio/accel/adis16201_core.c index 2fd01ae..2b8c5e9 100644 --- a/drivers/staging/iio/accel/adis16201_core.c +++ b/drivers/staging/iio/accel/adis16201_core.c @@ -13,15 +13,12 @@ #include <linux/spi/spi.h> #include <linux/slab.h> #include <linux/sysfs.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" #include "../ring_generic.h" -#include "accel.h" -#include "inclinometer.h" -#include "../adc/adc.h" - #include "adis16201.h" enum adis16201_chan { diff --git a/drivers/staging/iio/accel/adis16201_ring.c b/drivers/staging/iio/accel/adis16201_ring.c index 66e708d..4b433c5 100644 --- a/drivers/staging/iio/accel/adis16201_ring.c +++ b/drivers/staging/iio/accel/adis16201_ring.c @@ -1,17 +1,12 @@ #include <linux/interrupt.h> -#include <linux/irq.h> #include <linux/mutex.h> -#include <linux/device.h> #include <linux/kernel.h> #include <linux/spi/spi.h> #include <linux/slab.h> -#include <linux/sysfs.h> #include "../iio.h" -#include "../sysfs.h" #include "../ring_sw.h" -#include "accel.h" -#include "../trigger.h" +#include "../trigger_consumer.h" #include "adis16201.h" @@ -38,10 +33,12 @@ static int adis16201_read_ring_data(struct iio_dev *indio_dev, u8 *rx) xfers[i].cs_change = 1; xfers[i].len = 2; xfers[i].delay_usecs = 20; - xfers[i].tx_buf = st->tx + 2 * i; - st->tx[2 * i] = ADIS16201_READ_REG(ADIS16201_SUPPLY_OUT + - 2 * i); - st->tx[2 * i + 1] = 0; + if (i < ADIS16201_OUTPUTS) { + xfers[i].tx_buf = st->tx + 2 * i; + st->tx[2 * i] = ADIS16201_READ_REG(ADIS16201_SUPPLY_OUT + + 2 * i); + st->tx[2 * i + 1] = 0; + } if (i >= 1) xfers[i].rx_buf = rx + 2 * (i - 1); spi_message_add_tail(&xfers[i], &msg); @@ -62,7 +59,7 @@ static int adis16201_read_ring_data(struct iio_dev *indio_dev, u8 *rx) static irqreturn_t adis16201_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->private_data; + struct iio_dev *indio_dev = pf->indio_dev; struct adis16201_state *st = iio_priv(indio_dev); struct iio_ring_buffer *ring = indio_dev->ring; diff --git a/drivers/staging/iio/accel/adis16201_trigger.c b/drivers/staging/iio/accel/adis16201_trigger.c index 3a95c08..f448258 100644 --- a/drivers/staging/iio/accel/adis16201_trigger.c +++ b/drivers/staging/iio/accel/adis16201_trigger.c @@ -1,13 +1,8 @@ #include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/mutex.h> -#include <linux/device.h> #include <linux/kernel.h> -#include <linux/sysfs.h> #include <linux/spi/spi.h> #include "../iio.h" -#include "../sysfs.h" #include "../trigger.h" #include "adis16201.h" @@ -23,6 +18,11 @@ static int adis16201_data_rdy_trigger_set_state(struct iio_trigger *trig, return adis16201_set_irq(indio_dev, state); } +static const struct iio_trigger_ops adis16201_trigger_ops = { + .owner = THIS_MODULE, + .set_trigger_state = &adis16201_data_rdy_trigger_set_state, +}; + int adis16201_probe_trigger(struct iio_dev *indio_dev) { int ret; @@ -41,9 +41,8 @@ int adis16201_probe_trigger(struct iio_dev *indio_dev) if (ret) goto error_free_trig; st->trig->dev.parent = &st->us->dev; - st->trig->owner = THIS_MODULE; + st->trig->ops = &adis16201_trigger_ops; st->trig->private_data = indio_dev; - st->trig->set_trigger_state = &adis16201_data_rdy_trigger_set_state; ret = iio_trigger_register(st->trig); /* select default trigger */ diff --git a/drivers/staging/iio/accel/adis16203_core.c b/drivers/staging/iio/accel/adis16203_core.c index cf5d15d..1483676 100644 --- a/drivers/staging/iio/accel/adis16203_core.c +++ b/drivers/staging/iio/accel/adis16203_core.c @@ -13,13 +13,11 @@ #include <linux/spi/spi.h> #include <linux/slab.h> #include <linux/sysfs.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" -#include "accel.h" -#include "inclinometer.h" #include "../ring_generic.h" -#include "../adc/adc.h" #include "adis16203.h" diff --git a/drivers/staging/iio/accel/adis16203_ring.c b/drivers/staging/iio/accel/adis16203_ring.c index d2c07c5..993e239 100644 --- a/drivers/staging/iio/accel/adis16203_ring.c +++ b/drivers/staging/iio/accel/adis16203_ring.c @@ -1,20 +1,12 @@ #include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/gpio.h> -#include <linux/workqueue.h> #include <linux/mutex.h> -#include <linux/device.h> #include <linux/kernel.h> #include <linux/spi/spi.h> #include <linux/slab.h> -#include <linux/sysfs.h> -#include <linux/list.h> #include "../iio.h" -#include "../sysfs.h" #include "../ring_sw.h" -#include "accel.h" -#include "../trigger.h" +#include "../trigger_consumer.h" #include "adis16203.h" /** @@ -67,7 +59,7 @@ static int adis16203_read_ring_data(struct device *dev, u8 *rx) static irqreturn_t adis16203_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->private_data; + struct iio_dev *indio_dev = pf->indio_dev; struct adis16203_state *st = iio_priv(indio_dev); struct iio_ring_buffer *ring = indio_dev->ring; diff --git a/drivers/staging/iio/accel/adis16203_trigger.c b/drivers/staging/iio/accel/adis16203_trigger.c index 3caf3e8..50165f9 100644 --- a/drivers/staging/iio/accel/adis16203_trigger.c +++ b/drivers/staging/iio/accel/adis16203_trigger.c @@ -1,14 +1,8 @@ #include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/mutex.h> -#include <linux/device.h> #include <linux/kernel.h> -#include <linux/sysfs.h> -#include <linux/list.h> #include <linux/spi/spi.h> #include "../iio.h" -#include "../sysfs.h" #include "../trigger.h" #include "adis16203.h" @@ -24,6 +18,11 @@ static int adis16203_data_rdy_trigger_set_state(struct iio_trigger *trig, return adis16203_set_irq(indio_dev, state); } +static const struct iio_trigger_ops adis16203_trigger_ops = { + .owner = THIS_MODULE, + .set_trigger_state = &adis16203_data_rdy_trigger_set_state, +}; + int adis16203_probe_trigger(struct iio_dev *indio_dev) { int ret; @@ -44,9 +43,8 @@ int adis16203_probe_trigger(struct iio_dev *indio_dev) goto error_free_trig; st->trig->dev.parent = &st->us->dev; - st->trig->owner = THIS_MODULE; + st->trig->ops = &adis16203_trigger_ops; st->trig->private_data = indio_dev; - st->trig->set_trigger_state = &adis16203_data_rdy_trigger_set_state; ret = iio_trigger_register(st->trig); /* select default trigger */ diff --git a/drivers/staging/iio/accel/adis16204_core.c b/drivers/staging/iio/accel/adis16204_core.c index 3e2b626..445a75b 100644 --- a/drivers/staging/iio/accel/adis16204_core.c +++ b/drivers/staging/iio/accel/adis16204_core.c @@ -17,12 +17,11 @@ #include <linux/slab.h> #include <linux/sysfs.h> #include <linux/list.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" #include "../ring_generic.h" -#include "accel.h" -#include "../adc/adc.h" #include "adis16204.h" @@ -299,12 +298,15 @@ static int adis16204_initial_setup(struct iio_dev *indio_dev) err_ret: return ret; } + +/* Unique to this driver currently */ +#define IIO_DEV_ATTR_ACCEL_XY(_show, _addr) \ + IIO_DEVICE_ATTR(accel_xy, S_IRUGO, _show, NULL, _addr) +#define IIO_DEV_ATTR_ACCEL_XYPEAK(_show, _addr) \ + IIO_DEVICE_ATTR(accel_xypeak, S_IRUGO, _show, NULL, _addr) + static IIO_DEV_ATTR_ACCEL_XY(adis16204_read_14bit_signed, ADIS16204_XY_RSS_OUT); -static IIO_DEV_ATTR_ACCEL_XPEAK(adis16204_read_14bit_signed, - ADIS16204_X_PEAK_OUT); -static IIO_DEV_ATTR_ACCEL_YPEAK(adis16204_read_14bit_signed, - ADIS16204_Y_PEAK_OUT); static IIO_DEV_ATTR_ACCEL_XYPEAK(adis16204_read_14bit_signed, ADIS16204_XY_PEAK_OUT); static IIO_CONST_ATTR(accel_xy_scale, "0.017125"); @@ -319,13 +321,16 @@ enum adis16204_channel { accel_y, }; -static u8 adis16204_addresses[5][2] = { +static u8 adis16204_addresses[5][3] = { [in_supply] = { ADIS16204_SUPPLY_OUT }, [in_aux] = { ADIS16204_AUX_ADC }, [temp] = { ADIS16204_TEMP_OUT }, - [accel_x] = { ADIS16204_XACCL_OUT, ADIS16204_XACCL_NULL }, - [accel_y] = { ADIS16204_XACCL_OUT, ADIS16204_YACCL_NULL }, + [accel_x] = { ADIS16204_XACCL_OUT, ADIS16204_XACCL_NULL, + ADIS16204_X_PEAK_OUT }, + [accel_y] = { ADIS16204_XACCL_OUT, ADIS16204_YACCL_NULL, + ADIS16204_Y_PEAK_OUT }, }; + static int adis16204_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, @@ -335,6 +340,7 @@ static int adis16204_read_raw(struct iio_dev *indio_dev, int bits; u8 addr; s16 val16; + int addrind; switch (mask) { case 0: @@ -389,15 +395,16 @@ static int adis16204_read_raw(struct iio_dev *indio_dev, *val = 25; return IIO_VAL_INT; case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE): - switch (chan->type) { - case IIO_ACCEL: + case (1 << IIO_CHAN_INFO_PEAK_SEPARATE): + if (mask == (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE)) { bits = 12; - break; - default: - return -EINVAL; - }; + addrind = 1; + } else { /* PEAK_SEPARATE */ + bits = 14; + addrind = 2; + } mutex_lock(&indio_dev->mlock); - addr = adis16204_addresses[chan->address][1]; + addr = adis16204_addresses[chan->address][addrind]; ret = adis16204_spi_read_reg_16(indio_dev, addr, &val16); if (ret) { mutex_unlock(&indio_dev->mlock); @@ -453,21 +460,22 @@ static struct iio_chan_spec adis16204_channels[] = { IIO_ST('u', 12, 16, 0), 0), IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X, (1 << IIO_CHAN_INFO_SCALE_SEPARATE) | - (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE), + (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | + (1 << IIO_CHAN_INFO_PEAK_SEPARATE), accel_x, ADIS16204_SCAN_ACC_X, IIO_ST('s', 14, 16, 0), 0), IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y, (1 << IIO_CHAN_INFO_SCALE_SEPARATE) | - (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE), + (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | + (1 << IIO_CHAN_INFO_PEAK_SEPARATE), accel_y, ADIS16204_SCAN_ACC_Y, IIO_ST('s', 14, 16, 0), 0), IIO_CHAN_SOFT_TIMESTAMP(5), }; + static struct attribute *adis16204_attributes[] = { &iio_dev_attr_reset.dev_attr.attr, &iio_dev_attr_accel_xy.dev_attr.attr, - &iio_dev_attr_accel_xpeak.dev_attr.attr, - &iio_dev_attr_accel_ypeak.dev_attr.attr, &iio_dev_attr_accel_xypeak.dev_attr.attr, &iio_const_attr_accel_xy_scale.dev_attr.attr, NULL diff --git a/drivers/staging/iio/accel/adis16204_ring.c b/drivers/staging/iio/accel/adis16204_ring.c index 852df06..847f438 100644 --- a/drivers/staging/iio/accel/adis16204_ring.c +++ b/drivers/staging/iio/accel/adis16204_ring.c @@ -1,20 +1,12 @@ #include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/gpio.h> -#include <linux/workqueue.h> #include <linux/mutex.h> -#include <linux/device.h> #include <linux/kernel.h> #include <linux/spi/spi.h> #include <linux/slab.h> -#include <linux/sysfs.h> -#include <linux/list.h> #include "../iio.h" -#include "../sysfs.h" #include "../ring_sw.h" -#include "accel.h" -#include "../trigger.h" +#include "../trigger_consumer.h" #include "adis16204.h" /** @@ -65,7 +57,7 @@ static int adis16204_read_ring_data(struct device *dev, u8 *rx) static irqreturn_t adis16204_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->private_data; + struct iio_dev *indio_dev = pf->indio_dev; struct adis16204_state *st = iio_priv(indio_dev); struct iio_ring_buffer *ring = indio_dev->ring; int i = 0; diff --git a/drivers/staging/iio/accel/adis16204_trigger.c b/drivers/staging/iio/accel/adis16204_trigger.c index 01f73b9..55b661c 100644 --- a/drivers/staging/iio/accel/adis16204_trigger.c +++ b/drivers/staging/iio/accel/adis16204_trigger.c @@ -1,14 +1,8 @@ #include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/mutex.h> -#include <linux/device.h> #include <linux/kernel.h> -#include <linux/sysfs.h> -#include <linux/list.h> #include <linux/spi/spi.h> #include "../iio.h" -#include "../sysfs.h" #include "../trigger.h" #include "adis16204.h" @@ -24,6 +18,11 @@ static int adis16204_data_rdy_trigger_set_state(struct iio_trigger *trig, return adis16204_set_irq(indio_dev, state); } +static const struct iio_trigger_ops adis16204_trigger_ops = { + .owner = THIS_MODULE, + .set_trigger_state = &adis16204_data_rdy_trigger_set_state, +}; + int adis16204_probe_trigger(struct iio_dev *indio_dev) { int ret; @@ -44,9 +43,8 @@ int adis16204_probe_trigger(struct iio_dev *indio_dev) goto error_free_trig; st->trig->dev.parent = &st->us->dev; - st->trig->owner = THIS_MODULE; + st->trig->ops = &adis16204_trigger_ops; st->trig->private_data = indio_dev; - st->trig->set_trigger_state = &adis16204_data_rdy_trigger_set_state; ret = iio_trigger_register(st->trig); /* select default trigger */ diff --git a/drivers/staging/iio/accel/adis16209_core.c b/drivers/staging/iio/accel/adis16209_core.c index bec1fa8..ca671dd 100644 --- a/drivers/staging/iio/accel/adis16209_core.c +++ b/drivers/staging/iio/accel/adis16209_core.c @@ -14,13 +14,11 @@ #include <linux/slab.h> #include <linux/sysfs.h> #include <linux/list.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" #include "../ring_generic.h" -#include "accel.h" -#include "inclinometer.h" -#include "../adc/adc.h" #include "adis16209.h" diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c index 45017d3..f889fe7 100644 --- a/drivers/staging/iio/accel/adis16209_ring.c +++ b/drivers/staging/iio/accel/adis16209_ring.c @@ -1,20 +1,12 @@ #include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/gpio.h> -#include <linux/workqueue.h> #include <linux/mutex.h> -#include <linux/device.h> #include <linux/kernel.h> #include <linux/spi/spi.h> #include <linux/slab.h> -#include <linux/sysfs.h> -#include <linux/list.h> #include "../iio.h" -#include "../sysfs.h" #include "../ring_sw.h" -#include "accel.h" -#include "../trigger.h" +#include "../trigger_consumer.h" #include "adis16209.h" /** @@ -65,7 +57,7 @@ static int adis16209_read_ring_data(struct device *dev, u8 *rx) static irqreturn_t adis16209_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->private_data; + struct iio_dev *indio_dev = pf->indio_dev; struct adis16209_state *st = iio_priv(indio_dev); struct iio_ring_buffer *ring = indio_dev->ring; diff --git a/drivers/staging/iio/accel/adis16209_trigger.c b/drivers/staging/iio/accel/adis16209_trigger.c index 6df7b47..8df8a97 100644 --- a/drivers/staging/iio/accel/adis16209_trigger.c +++ b/drivers/staging/iio/accel/adis16209_trigger.c @@ -1,14 +1,8 @@ #include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/mutex.h> -#include <linux/device.h> #include <linux/kernel.h> -#include <linux/sysfs.h> -#include <linux/list.h> #include <linux/spi/spi.h> #include "../iio.h" -#include "../sysfs.h" #include "../trigger.h" #include "adis16209.h" @@ -33,6 +27,11 @@ static int adis16209_data_rdy_trigger_set_state(struct iio_trigger *trig, return adis16209_set_irq(indio_dev, state); } +static const struct iio_trigger_ops adis16209_trigger_ops = { + .owner = THIS_MODULE, + .set_trigger_state = &adis16209_data_rdy_trigger_set_state, +}; + int adis16209_probe_trigger(struct iio_dev *indio_dev) { int ret; @@ -52,9 +51,8 @@ int adis16209_probe_trigger(struct iio_dev *indio_dev) if (ret) goto error_free_trig; st->trig->dev.parent = &st->us->dev; - st->trig->owner = THIS_MODULE; + st->trig->ops = &adis16209_trigger_ops; st->trig->private_data = indio_dev; - st->trig->set_trigger_state = &adis16209_data_rdy_trigger_set_state; ret = iio_trigger_register(st->trig); /* select default trigger */ diff --git a/drivers/staging/iio/accel/adis16220_core.c b/drivers/staging/iio/accel/adis16220_core.c index bf9ba07..18b0830 100644 --- a/drivers/staging/iio/accel/adis16220_core.c +++ b/drivers/staging/iio/accel/adis16220_core.c @@ -6,9 +6,6 @@ * Licensed under the GPL-2 or later. */ -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/gpio.h> #include <linux/delay.h> #include <linux/mutex.h> #include <linux/device.h> @@ -16,12 +13,10 @@ #include <linux/spi/spi.h> #include <linux/slab.h> #include <linux/sysfs.h> -#include <linux/list.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" -#include "accel.h" -#include "../adc/adc.h" #include "adis16220.h" @@ -29,16 +24,15 @@ /** * adis16220_spi_write_reg_8() - write single byte to a register - * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @indio_dev: iio device associated with child of actual device * @reg_address: the address of the register to be written * @val: the value to write **/ -static int adis16220_spi_write_reg_8(struct device *dev, +static int adis16220_spi_write_reg_8(struct iio_dev *indio_dev, u8 reg_address, u8 val) { int ret; - struct iio_dev *indio_dev = dev_get_drvdata(dev); struct adis16220_state *st = iio_priv(indio_dev); mutex_lock(&st->buf_lock); @@ -53,18 +47,17 @@ static int adis16220_spi_write_reg_8(struct device *dev, /** * adis16220_spi_write_reg_16() - write 2 bytes to a pair of registers - * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @indio_dev: iio device associated with child of actual device * @reg_address: the address of the lower of the two registers. Second register * is assumed to have address one greater. * @val: value to be written **/ -static int adis16220_spi_write_reg_16(struct device *dev, +static int adis16220_spi_write_reg_16(struct iio_dev *indio_dev, u8 lower_reg_address, u16 value) { int ret; struct spi_message msg; - struct iio_dev *indio_dev = dev_get_drvdata(dev); struct adis16220_state *st = iio_priv(indio_dev); struct spi_transfer xfers[] = { { @@ -77,7 +70,6 @@ static int adis16220_spi_write_reg_16(struct device *dev, .tx_buf = st->tx + 2, .bits_per_word = 8, .len = 2, - .cs_change = 1, .delay_usecs = 35, }, }; @@ -99,17 +91,16 @@ static int adis16220_spi_write_reg_16(struct device *dev, /** * adis16220_spi_read_reg_16() - read 2 bytes from a 16-bit register - * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @indio_dev: iio device associated with child of actual device * @reg_address: the address of the lower of the two registers. Second register * is assumed to have address one greater. * @val: somewhere to pass back the value read **/ -static int adis16220_spi_read_reg_16(struct device *dev, - u8 lower_reg_address, - u16 *val) +static int adis16220_spi_read_reg_16(struct iio_dev *indio_dev, + u8 lower_reg_address, + u16 *val) { struct spi_message msg; - struct iio_dev *indio_dev = dev_get_drvdata(dev); struct adis16220_state *st = iio_priv(indio_dev); int ret; struct spi_transfer xfers[] = { @@ -149,52 +140,23 @@ error_ret: return ret; } -static ssize_t adis16220_spi_read_signed(struct device *dev, - struct device_attribute *attr, - char *buf, - unsigned bits) -{ - int ret; - s16 val = 0; - unsigned shift = 16 - bits; - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - - ret = adis16220_spi_read_reg_16(dev, this_attr->address, (u16 *)&val); - if (ret) - return ret; - - val = ((s16)(val << shift) >> shift); - return sprintf(buf, "%d\n", val); -} - -static ssize_t adis16220_read_12bit_unsigned(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int ret; - u16 val = 0; - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - - ret = adis16220_spi_read_reg_16(dev, this_attr->address, &val); - if (ret) - return ret; - - return sprintf(buf, "%u\n", val & 0x0FFF); -} - static ssize_t adis16220_read_16bit(struct device *dev, struct device_attribute *attr, char *buf) { + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); struct iio_dev *indio_dev = dev_get_drvdata(dev); ssize_t ret; + s16 val = 0; /* Take the iio_dev status lock */ mutex_lock(&indio_dev->mlock); - ret = adis16220_spi_read_signed(dev, attr, buf, 16); + ret = adis16220_spi_read_reg_16(indio_dev, this_attr->address, + (u16 *)&val); mutex_unlock(&indio_dev->mlock); - - return ret; + if (ret) + return ret; + return sprintf(buf, "%d\n", val); } static ssize_t adis16220_write_16bit(struct device *dev, @@ -202,6 +164,7 @@ static ssize_t adis16220_write_16bit(struct device *dev, const char *buf, size_t len) { + struct iio_dev *indio_dev = dev_get_drvdata(dev); struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); int ret; long val; @@ -209,34 +172,34 @@ static ssize_t adis16220_write_16bit(struct device *dev, ret = strict_strtol(buf, 10, &val); if (ret) goto error_ret; - ret = adis16220_spi_write_reg_16(dev, this_attr->address, val); + ret = adis16220_spi_write_reg_16(indio_dev, this_attr->address, val); error_ret: return ret ? ret : len; } -static int adis16220_capture(struct device *dev) +static int adis16220_capture(struct iio_dev *indio_dev) { int ret; - ret = adis16220_spi_write_reg_16(dev, + ret = adis16220_spi_write_reg_16(indio_dev, ADIS16220_GLOB_CMD, 0xBF08); /* initiates a manual data capture */ if (ret) - dev_err(dev, "problem beginning capture"); + dev_err(&indio_dev->dev, "problem beginning capture"); msleep(10); /* delay for capture to finish */ return ret; } -static int adis16220_reset(struct device *dev) +static int adis16220_reset(struct iio_dev *indio_dev) { int ret; - ret = adis16220_spi_write_reg_8(dev, + ret = adis16220_spi_write_reg_8(indio_dev, ADIS16220_GLOB_CMD, ADIS16220_GLOB_CMD_SW_RESET); if (ret) - dev_err(dev, "problem resetting device"); + dev_err(&indio_dev->dev, "problem resetting device"); return ret; } @@ -245,72 +208,84 @@ static ssize_t adis16220_write_reset(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { - if (len < 1) - return -1; - switch (buf[0]) { - case '1': - case 'y': - case 'Y': - return adis16220_reset(dev) == 0 ? len : -EIO; - } - return -1; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + bool val; + int ret; + + ret = strtobool(buf, &val); + if (ret) + return ret; + if (!val) + return -EINVAL; + + ret = adis16220_reset(indio_dev); + if (ret) + return ret; + return len; } static ssize_t adis16220_write_capture(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { - if (len < 1) - return -1; - switch (buf[0]) { - case '1': - case 'y': - case 'Y': - return adis16220_capture(dev) == 0 ? len : -EIO; - } - return -1; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + bool val; + int ret; + + ret = strtobool(buf, &val); + if (ret) + return ret; + if (!val) + return -EINVAL; + ret = adis16220_capture(indio_dev); + if (ret) + return ret; + + return len; } -static int adis16220_check_status(struct device *dev) +static int adis16220_check_status(struct iio_dev *indio_dev) { u16 status; int ret; - ret = adis16220_spi_read_reg_16(dev, ADIS16220_DIAG_STAT, &status); + ret = adis16220_spi_read_reg_16(indio_dev, ADIS16220_DIAG_STAT, + &status); if (ret < 0) { - dev_err(dev, "Reading status failed\n"); + dev_err(&indio_dev->dev, "Reading status failed\n"); goto error_ret; } ret = status & 0x7F; if (status & ADIS16220_DIAG_STAT_VIOLATION) - dev_err(dev, "Capture period violation/interruption\n"); + dev_err(&indio_dev->dev, + "Capture period violation/interruption\n"); if (status & ADIS16220_DIAG_STAT_SPI_FAIL) - dev_err(dev, "SPI failure\n"); + dev_err(&indio_dev->dev, "SPI failure\n"); if (status & ADIS16220_DIAG_STAT_FLASH_UPT) - dev_err(dev, "Flash update failed\n"); + dev_err(&indio_dev->dev, "Flash update failed\n"); if (status & ADIS16220_DIAG_STAT_POWER_HIGH) - dev_err(dev, "Power supply above 3.625V\n"); + dev_err(&indio_dev->dev, "Power supply above 3.625V\n"); if (status & ADIS16220_DIAG_STAT_POWER_LOW) - dev_err(dev, "Power supply below 3.15V\n"); + dev_err(&indio_dev->dev, "Power supply below 3.15V\n"); error_ret: return ret; } -static int adis16220_self_test(struct device *dev) +static int adis16220_self_test(struct iio_dev *indio_dev) { int ret; - ret = adis16220_spi_write_reg_16(dev, + ret = adis16220_spi_write_reg_16(indio_dev, ADIS16220_MSC_CTRL, ADIS16220_MSC_CTRL_SELF_TEST_EN); if (ret) { - dev_err(dev, "problem starting self test"); + dev_err(&indio_dev->dev, "problem starting self test"); goto err_ret; } - adis16220_check_status(dev); + adis16220_check_status(indio_dev); err_ret: return ret; @@ -319,24 +294,23 @@ err_ret: static int adis16220_initial_setup(struct iio_dev *indio_dev) { int ret; - struct device *dev = &indio_dev->dev; /* Do self test */ - ret = adis16220_self_test(dev); + ret = adis16220_self_test(indio_dev); if (ret) { - dev_err(dev, "self test failure"); + dev_err(&indio_dev->dev, "self test failure"); goto err_ret; } /* Read status register to check the result */ - ret = adis16220_check_status(dev); + ret = adis16220_check_status(indio_dev); if (ret) { - adis16220_reset(dev); - dev_err(dev, "device not playing ball -> reset"); + adis16220_reset(indio_dev); + dev_err(&indio_dev->dev, "device not playing ball -> reset"); msleep(ADIS16220_STARTUP_DELAY); - ret = adis16220_check_status(dev); + ret = adis16220_check_status(indio_dev); if (ret) { - dev_err(dev, "giving up"); + dev_err(&indio_dev->dev, "giving up"); goto err_ret; } } @@ -381,7 +355,7 @@ static ssize_t adis16220_capture_buffer_read(struct iio_dev *indio_dev, count = ADIS16220_CAPTURE_SIZE - off; /* write the begin position of capture buffer */ - ret = adis16220_spi_write_reg_16(&indio_dev->dev, + ret = adis16220_spi_write_reg_16(indio_dev, ADIS16220_CAPT_PNTR, off > 1); if (ret) @@ -480,24 +454,6 @@ static struct bin_attribute adc2_bin = { .size = ADIS16220_CAPTURE_SIZE, }; -static IIO_DEV_ATTR_IN_NAMED_RAW(0, supply, adis16220_read_12bit_unsigned, - ADIS16220_CAPT_SUPPLY); -static IIO_CONST_ATTR_IN_NAMED_SCALE(0, supply, "0.0012207"); -static IIO_DEV_ATTR_ACCEL(adis16220_read_16bit, ADIS16220_CAPT_BUFA); -static IIO_DEVICE_ATTR(accel_peak_raw, S_IRUGO, adis16220_read_16bit, - NULL, ADIS16220_CAPT_PEAKA); -static IIO_DEV_ATTR_ACCEL_OFFSET(S_IWUSR | S_IRUGO, - adis16220_read_16bit, - adis16220_write_16bit, - ADIS16220_ACCL_NULL); -static IIO_CONST_ATTR_ACCEL_SCALE("0.18704223545"); -static IIO_DEV_ATTR_TEMP_RAW(adis16220_read_12bit_unsigned); -static IIO_CONST_ATTR_TEMP_OFFSET("25"); -static IIO_CONST_ATTR_TEMP_SCALE("-0.47"); - -static IIO_DEV_ATTR_IN_RAW(1, adis16220_read_16bit, ADIS16220_CAPT_BUF1); -static IIO_DEV_ATTR_IN_RAW(2, adis16220_read_16bit, ADIS16220_CAPT_BUF2); - static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16220_write_reset, 0); @@ -514,21 +470,142 @@ static IIO_DEV_ATTR_CAPTURE_COUNT(S_IWUSR | S_IRUGO, adis16220_write_16bit, ADIS16220_CAPT_PNTR); -static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("100200"); +enum adis16220_channel { + in_supply, in_1, in_2, accel, temp +}; + +struct adis16220_address_spec { + u8 addr; + u8 bits; + bool sign; +}; + +/* Address / bits / signed */ +static const struct adis16220_address_spec adis16220_addresses[][3] = { + [in_supply] = { { ADIS16220_CAPT_SUPPLY, 12, 0 }, }, + [in_1] = { { ADIS16220_CAPT_BUF1, 16, 1 }, + { ADIS16220_AIN1_NULL, 16, 1 }, + { ADIS16220_CAPT_PEAK1, 16, 1 }, }, + [in_2] = { { ADIS16220_CAPT_BUF2, 16, 1 }, + { ADIS16220_AIN2_NULL, 16, 1 }, + { ADIS16220_CAPT_PEAK2, 16, 1 }, }, + [accel] = { { ADIS16220_CAPT_BUFA, 16, 1 }, + { ADIS16220_ACCL_NULL, 16, 1 }, + { ADIS16220_CAPT_PEAKA, 16, 1 }, }, + [temp] = { { ADIS16220_CAPT_TEMP, 12, 0 }, } +}; + +static int adis16220_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, + long mask) +{ + int ret = -EINVAL; + int addrind = 0; + u16 uval; + s16 sval; + u8 bits; + + switch (mask) { + case 0: + addrind = 0; + break; + case (1 << IIO_CHAN_INFO_OFFSET_SEPARATE): + if (chan->type == IIO_TEMP) { + *val = 25; + return IIO_VAL_INT; + } + addrind = 1; + break; + case (1 << IIO_CHAN_INFO_PEAK_SEPARATE): + addrind = 2; + break; + case (1 << IIO_CHAN_INFO_SCALE_SEPARATE): + *val = 0; + switch (chan->type) { + case IIO_TEMP: + *val2 = -470000; + return IIO_VAL_INT_PLUS_MICRO; + case IIO_ACCEL: + *val2 = 1887042; + return IIO_VAL_INT_PLUS_MICRO; + case IIO_IN: + if (chan->channel == 0) + *val2 = 0012221; + else /* Should really be dependent on VDD */ + *val2 = 305; + return IIO_VAL_INT_PLUS_MICRO; + default: + return -EINVAL; + } + default: + return -EINVAL; + } + if (adis16220_addresses[chan->address][addrind].sign) { + ret = adis16220_spi_read_reg_16(indio_dev, + adis16220_addresses[chan + ->address] + [addrind].addr, + &sval); + if (ret) + return ret; + bits = adis16220_addresses[chan->address][addrind].bits; + sval &= (1 << bits) - 1; + sval = (s16)(sval << (16 - bits)) >> (16 - bits); + *val = sval; + return IIO_VAL_INT; + } else { + ret = adis16220_spi_read_reg_16(indio_dev, + adis16220_addresses[chan + ->address] + [addrind].addr, + &uval); + if (ret) + return ret; + bits = adis16220_addresses[chan->address][addrind].bits; + uval &= (1 << bits) - 1; + *val = uval; + return IIO_VAL_INT; + } +} + +static const struct iio_chan_spec adis16220_channels[] = { + { + .type = IIO_IN, + .indexed = 1, + .channel = 0, + .extend_name = "supply", + .info_mask = (1 << IIO_CHAN_INFO_SCALE_SEPARATE), + .address = in_supply, + }, { + .type = IIO_ACCEL, + .info_mask = (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) | + (1 << IIO_CHAN_INFO_SCALE_SEPARATE) | + (1 << IIO_CHAN_INFO_PEAK_SEPARATE), + .address = accel, + }, { + .type = IIO_TEMP, + .indexed = 1, + .channel = 0, + .info_mask = (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) | + (1 << IIO_CHAN_INFO_SCALE_SEPARATE), + .address = temp, + }, { + .type = IIO_IN, + .indexed = 1, + .channel = 1, + .info_mask = (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) | + (1 << IIO_CHAN_INFO_SCALE_SEPARATE), + .address = in_1, + }, { + .type = IIO_IN, + .indexed = 1, + .channel = 2, + .address = in_2, + } +}; static struct attribute *adis16220_attributes[] = { - &iio_dev_attr_in0_supply_raw.dev_attr.attr, - &iio_const_attr_in0_supply_scale.dev_attr.attr, - &iio_dev_attr_accel_raw.dev_attr.attr, - &iio_dev_attr_accel_offset.dev_attr.attr, - &iio_dev_attr_accel_peak_raw.dev_attr.attr, - &iio_const_attr_accel_scale.dev_attr.attr, - &iio_dev_attr_temp_raw.dev_attr.attr, - &iio_dev_attr_in1_raw.dev_attr.attr, - &iio_dev_attr_in2_raw.dev_attr.attr, - &iio_const_attr_temp_offset.dev_attr.attr, - &iio_const_attr_temp_scale.dev_attr.attr, - &iio_const_attr_sampling_frequency_available.dev_attr.attr, &iio_dev_attr_reset.dev_attr.attr, &iio_dev_attr_capture.dev_attr.attr, &iio_dev_attr_capture_count.dev_attr.attr, @@ -542,7 +619,9 @@ static const struct attribute_group adis16220_attribute_group = { static const struct iio_info adis16220_info = { .attrs = &adis16220_attribute_group, .driver_module = THIS_MODULE, + .read_raw = &adis16220_read_raw, }; + static int __devinit adis16220_probe(struct spi_device *spi) { int ret, regdone = 0; @@ -567,6 +646,8 @@ static int __devinit adis16220_probe(struct spi_device *spi) indio_dev->dev.parent = &spi->dev; indio_dev->info = &adis16220_info; indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = adis16220_channels; + indio_dev->num_channels = ARRAY_SIZE(adis16220_channels); ret = iio_device_register(indio_dev); if (ret) diff --git a/drivers/staging/iio/accel/adis16240_core.c b/drivers/staging/iio/accel/adis16240_core.c index aee8b69..d485f73 100644 --- a/drivers/staging/iio/accel/adis16240_core.c +++ b/drivers/staging/iio/accel/adis16240_core.c @@ -17,12 +17,11 @@ #include <linux/slab.h> #include <linux/sysfs.h> #include <linux/list.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" #include "../ring_generic.h" -#include "accel.h" -#include "../adc/adc.h" #include "adis16240.h" diff --git a/drivers/staging/iio/accel/adis16240_ring.c b/drivers/staging/iio/accel/adis16240_ring.c index c812a34..051ba64 100644 --- a/drivers/staging/iio/accel/adis16240_ring.c +++ b/drivers/staging/iio/accel/adis16240_ring.c @@ -1,20 +1,12 @@ #include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/gpio.h> -#include <linux/workqueue.h> #include <linux/mutex.h> -#include <linux/device.h> #include <linux/kernel.h> #include <linux/spi/spi.h> #include <linux/slab.h> -#include <linux/sysfs.h> -#include <linux/list.h> #include "../iio.h" -#include "../sysfs.h" #include "../ring_sw.h" -#include "accel.h" -#include "../trigger.h" +#include "../trigger_consumer.h" #include "adis16240.h" /** @@ -62,7 +54,7 @@ static int adis16240_read_ring_data(struct device *dev, u8 *rx) static irqreturn_t adis16240_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->private_data; + struct iio_dev *indio_dev = pf->indio_dev; struct adis16240_state *st = iio_priv(indio_dev); struct iio_ring_buffer *ring = indio_dev->ring; diff --git a/drivers/staging/iio/accel/adis16240_trigger.c b/drivers/staging/iio/accel/adis16240_trigger.c index 17135fc3..13f1d14 100644 --- a/drivers/staging/iio/accel/adis16240_trigger.c +++ b/drivers/staging/iio/accel/adis16240_trigger.c @@ -1,14 +1,8 @@ #include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/mutex.h> -#include <linux/device.h> #include <linux/kernel.h> -#include <linux/sysfs.h> -#include <linux/list.h> #include <linux/spi/spi.h> #include "../iio.h" -#include "../sysfs.h" #include "../trigger.h" #include "adis16240.h" @@ -33,6 +27,11 @@ static int adis16240_data_rdy_trigger_set_state(struct iio_trigger *trig, return adis16240_set_irq(indio_dev, state); } +static const struct iio_trigger_ops adis16240_trigger_ops = { + .owner = THIS_MODULE, + .set_trigger_state = &adis16240_data_rdy_trigger_set_state, +}; + int adis16240_probe_trigger(struct iio_dev *indio_dev) { int ret; @@ -53,9 +52,8 @@ int adis16240_probe_trigger(struct iio_dev *indio_dev) goto error_free_trig; st->trig->dev.parent = &st->us->dev; - st->trig->owner = THIS_MODULE; + st->trig->ops = &adis16240_trigger_ops; st->trig->private_data = indio_dev; - st->trig->set_trigger_state = &adis16240_data_rdy_trigger_set_state; ret = iio_trigger_register(st->trig); /* select default trigger */ diff --git a/drivers/staging/iio/accel/inclinometer.h b/drivers/staging/iio/accel/inclinometer.h deleted file mode 100644 index faf73d7..0000000 --- a/drivers/staging/iio/accel/inclinometer.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Inclinometer related attributes - */ -#include "../sysfs.h" - -#define IIO_DEV_ATTR_INCLI_X(_show, _addr) \ - IIO_DEVICE_ATTR(incli_x_raw, S_IRUGO, _show, NULL, _addr) - -#define IIO_DEV_ATTR_INCLI_Y(_show, _addr) \ - IIO_DEVICE_ATTR(incli_y_raw, S_IRUGO, _show, NULL, _addr) - -#define IIO_DEV_ATTR_INCLI_Z(_show, _addr) \ - IIO_DEVICE_ATTR(incli_z_raw, S_IRUGO, _show, NULL, _addr) - -#define IIO_DEV_ATTR_INCLI_X_OFFSET(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(incli_x_offset, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_INCLI_Y_OFFSET(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(incli_y_offset, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_INCLI_Z_OFFSET(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(incli_z_offset, _mode, _show, _store, _addr) - -#define IIO_CONST_ATTR_INCLI_SCALE(_string) \ - IIO_CONST_ATTR(incli_scale, _string) diff --git a/drivers/staging/iio/accel/kxsd9.c b/drivers/staging/iio/accel/kxsd9.c index c8a358a..2a05651 100644 --- a/drivers/staging/iio/accel/kxsd9.c +++ b/drivers/staging/iio/accel/kxsd9.c @@ -21,11 +21,10 @@ #include <linux/spi/spi.h> #include <linux/sysfs.h> #include <linux/slab.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" -#include "../adc/adc.h" -#include "accel.h" #define KXSD9_REG_X 0x00 #define KXSD9_REG_Y 0x02 @@ -34,10 +33,6 @@ #define KXSD9_REG_RESET 0x0a #define KXSD9_REG_CTRL_C 0x0c -#define KXSD9_FS_8 0x00 -#define KXSD9_FS_6 0x01 -#define KXSD9_FS_4 0x02 -#define KXSD9_FS_2 0x03 #define KXSD9_FS_MASK 0x03 #define KXSD9_REG_CTRL_B 0x0d @@ -46,13 +41,8 @@ #define KXSD9_READ(a) (0x80 | (a)) #define KXSD9_WRITE(a) (a) -#define KXSD9_SCALE_2G "0.011978" -#define KXSD9_SCALE_4G "0.023927" -#define KXSD9_SCALE_6G "0.035934" -#define KXSD9_SCALE_8G "0.047853" - #define KXSD9_STATE_RX_SIZE 2 -#define KXSD9_STATE_TX_SIZE 4 +#define KXSD9_STATE_TX_SIZE 2 /** * struct kxsd9_state - device related storage * @buf_lock: protect the rx and tx buffers. @@ -67,170 +57,70 @@ struct kxsd9_state { u8 tx[KXSD9_STATE_TX_SIZE]; }; -/* This may want to move to mili g to allow for non integer ranges */ -static ssize_t kxsd9_read_scale(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int ret; - ssize_t len = 0; - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct kxsd9_state *st = iio_priv(indio_dev); - struct spi_transfer xfer = { - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - .tx_buf = st->tx, - .rx_buf = st->rx, - }; - struct spi_message msg; - - mutex_lock(&st->buf_lock); - st->tx[0] = KXSD9_READ(KXSD9_REG_CTRL_C); - st->tx[1] = 0; - spi_message_init(&msg); - spi_message_add_tail(&xfer, &msg); - ret = spi_sync(st->us, &msg); - if (ret) - goto error_ret; - - switch (st->rx[1] & KXSD9_FS_MASK) { - case KXSD9_FS_8: - len += sprintf(buf, "%s\n", KXSD9_SCALE_8G); - break; - case KXSD9_FS_6: - len += sprintf(buf, "%s\n", KXSD9_SCALE_6G); - break; - case KXSD9_FS_4: - len += sprintf(buf, "%s\n", KXSD9_SCALE_4G); - break; - case KXSD9_FS_2: - len += sprintf(buf, "%s\n", KXSD9_SCALE_2G); - break; - } +#define KXSD9_SCALE_2G "0.011978" +#define KXSD9_SCALE_4G "0.023927" +#define KXSD9_SCALE_6G "0.035934" +#define KXSD9_SCALE_8G "0.047853" -error_ret: - mutex_unlock(&st->buf_lock); +/* reverse order */ +static const int kxsd9_micro_scales[4] = { 47853, 35934, 23927, 11978 }; - return ret ? ret : len; -} -static ssize_t kxsd9_write_scale(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) +static int kxsd9_write_scale(struct iio_dev *indio_dev, int micro) { - - struct spi_message msg; - int ret; - struct iio_dev *indio_dev = dev_get_drvdata(dev); + int ret, i; struct kxsd9_state *st = iio_priv(indio_dev); - u8 val; - struct spi_transfer xfers[] = { - { - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - .tx_buf = st->tx, - .rx_buf = st->rx, - }, { - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - .tx_buf = st->tx, - }, - }; - - if (!strncmp(buf, KXSD9_SCALE_8G, - strlen(buf) < strlen(KXSD9_SCALE_8G) - ? strlen(buf) : strlen(KXSD9_SCALE_8G))) - val = KXSD9_FS_8; - else if (!strncmp(buf, KXSD9_SCALE_6G, - strlen(buf) < strlen(KXSD9_SCALE_6G) - ? strlen(buf) : strlen(KXSD9_SCALE_6G))) - val = KXSD9_FS_6; - else if (!strncmp(buf, KXSD9_SCALE_4G, - strlen(buf) < strlen(KXSD9_SCALE_4G) - ? strlen(buf) : strlen(KXSD9_SCALE_4G))) - val = KXSD9_FS_4; - else if (!strncmp(buf, KXSD9_SCALE_2G, - strlen(buf) < strlen(KXSD9_SCALE_2G) - ? strlen(buf) : strlen(KXSD9_SCALE_2G))) - val = KXSD9_FS_2; - else + bool foundit = false; + + for (i = 0; i < 4; i++) + if (micro == kxsd9_micro_scales[i]) { + foundit = true; + break; + } + if (!foundit) return -EINVAL; mutex_lock(&st->buf_lock); - st->tx[0] = KXSD9_READ(KXSD9_REG_CTRL_C); - st->tx[1] = 0; - spi_message_init(&msg); - spi_message_add_tail(&xfers[0], &msg); - ret = spi_sync(st->us, &msg); + ret = spi_w8r8(st->us, KXSD9_READ(KXSD9_REG_CTRL_C)); if (ret) goto error_ret; st->tx[0] = KXSD9_WRITE(KXSD9_REG_CTRL_C); - st->tx[1] = (st->rx[1] & ~KXSD9_FS_MASK) | val; + st->tx[1] = (ret & ~KXSD9_FS_MASK) | i; - spi_message_init(&msg); - spi_message_add_tail(&xfers[1], &msg); - ret = spi_sync(st->us, &msg); + ret = spi_write(st->us, st->tx, 2); error_ret: mutex_unlock(&st->buf_lock); - return ret ? ret : len; + return ret; } -static ssize_t kxsd9_read_accel(struct device *dev, - struct device_attribute *attr, - char *buf) +static int kxsd9_read(struct iio_dev *indio_dev, u8 address) { struct spi_message msg; int ret; - ssize_t len = 0; - u16 val; - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - struct iio_dev *indio_dev = dev_get_drvdata(dev); struct kxsd9_state *st = iio_priv(indio_dev); struct spi_transfer xfers[] = { { .bits_per_word = 8, .len = 1, - .cs_change = 0, .delay_usecs = 200, .tx_buf = st->tx, }, { .bits_per_word = 8, .len = 2, - .cs_change = 1, .rx_buf = st->rx, }, }; mutex_lock(&st->buf_lock); - st->tx[0] = KXSD9_READ(this_attr->address); + st->tx[0] = KXSD9_READ(address); spi_message_init(&msg); spi_message_add_tail(&xfers[0], &msg); spi_message_add_tail(&xfers[1], &msg); ret = spi_sync(st->us, &msg); if (ret) - goto error_ret; - val = (((u16)(st->rx[0])) << 8) | (st->rx[1] & 0xF0); - len = sprintf(buf, "%d\n", val); -error_ret: - mutex_unlock(&st->buf_lock); - - return ret ? ret : len; + return ret; + return (((u16)(st->rx[0])) << 8) | (st->rx[1] & 0xF0); } -static IIO_DEV_ATTR_ACCEL_X(kxsd9_read_accel, KXSD9_REG_X); -static IIO_DEV_ATTR_ACCEL_Y(kxsd9_read_accel, KXSD9_REG_Y); -static IIO_DEV_ATTR_ACCEL_Z(kxsd9_read_accel, KXSD9_REG_Z); -static IIO_DEV_ATTR_IN_RAW(0, kxsd9_read_accel, KXSD9_REG_AUX); - -static IIO_DEVICE_ATTR(accel_scale, - S_IRUGO | S_IWUSR, - kxsd9_read_scale, - kxsd9_write_scale, - 0); - static IIO_CONST_ATTR(accel_scale_available, KXSD9_SCALE_2G " " KXSD9_SCALE_4G " " @@ -238,48 +128,94 @@ static IIO_CONST_ATTR(accel_scale_available, KXSD9_SCALE_8G); static struct attribute *kxsd9_attributes[] = { - &iio_dev_attr_accel_x_raw.dev_attr.attr, - &iio_dev_attr_accel_y_raw.dev_attr.attr, - &iio_dev_attr_accel_z_raw.dev_attr.attr, - &iio_dev_attr_in0_raw.dev_attr.attr, - &iio_dev_attr_accel_scale.dev_attr.attr, &iio_const_attr_accel_scale_available.dev_attr.attr, NULL, }; +static int kxsd9_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, + int val2, + long mask) +{ + int ret = -EINVAL; + + if (mask == (1 << IIO_CHAN_INFO_SCALE_SHARED)) { + /* Check no integer component */ + if (val) + return -EINVAL; + ret = kxsd9_write_scale(indio_dev, val2); + } + + return ret; +} + +static int kxsd9_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + int ret = -EINVAL; + struct kxsd9_state *st = iio_priv(indio_dev); + + switch (mask) { + case 0: + ret = kxsd9_read(indio_dev, chan->address); + if (ret < 0) + goto error_ret; + *val = ret; + break; + case (1 << IIO_CHAN_INFO_SCALE_SHARED): + ret = spi_w8r8(st->us, KXSD9_READ(KXSD9_REG_CTRL_C)); + if (ret) + goto error_ret; + *val2 = kxsd9_micro_scales[ret & KXSD9_FS_MASK]; + ret = IIO_VAL_INT_PLUS_MICRO; + break; + }; + +error_ret: + return ret; +}; +#define KXSD9_ACCEL_CHAN(axis) \ + { \ + .type = IIO_ACCEL, \ + .modified = 1, \ + .channel2 = IIO_MOD_##axis, \ + .info_mask = 1 << IIO_CHAN_INFO_SCALE_SHARED, \ + .address = KXSD9_REG_##axis, \ + } + +static struct iio_chan_spec kxsd9_channels[] = { + KXSD9_ACCEL_CHAN(X), KXSD9_ACCEL_CHAN(Y), KXSD9_ACCEL_CHAN(Z), + { + .type = IIO_IN, + .indexed = 1, + .address = KXSD9_REG_AUX, + } +}; + static const struct attribute_group kxsd9_attribute_group = { .attrs = kxsd9_attributes, }; static int __devinit kxsd9_power_up(struct kxsd9_state *st) { - struct spi_transfer xfers[2] = { - { - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - .tx_buf = st->tx, - }, { - .bits_per_word = 8, - .len = 2, - .cs_change = 1, - .tx_buf = st->tx + 2, - }, - }; - struct spi_message msg; + int ret; + st->tx[0] = 0x0d; st->tx[1] = 0x40; - st->tx[2] = 0x0c; - st->tx[3] = 0x9b; - - spi_message_init(&msg); - spi_message_add_tail(&xfers[0], &msg); - spi_message_add_tail(&xfers[1], &msg); + ret = spi_write(st->us, st->tx, 2); + if (ret) + return ret; - return spi_sync(st->us, &msg); + st->tx[0] = 0x0c; + st->tx[1] = 0x9b; + return spi_write(st->us, st->tx, 2); }; static const struct iio_info kxsd9_info = { + .read_raw = &kxsd9_read_raw, + .write_raw = &kxsd9_write_raw, .attrs = &kxsd9_attribute_group, .driver_module = THIS_MODULE, }; @@ -300,7 +236,9 @@ static int __devinit kxsd9_probe(struct spi_device *spi) st->us = spi; mutex_init(&st->buf_lock); - + indio_dev->channels = kxsd9_channels; + indio_dev->num_channels = ARRAY_SIZE(kxsd9_channels); + indio_dev->name = spi_get_device_id(spi)->name; indio_dev->dev.parent = &spi->dev; indio_dev->info = &kxsd9_info; indio_dev->modes = INDIO_DIRECT_MODE; @@ -328,6 +266,10 @@ static int __devexit kxsd9_remove(struct spi_device *spi) return 0; } +static const struct spi_device_id kxsd9_id[] = { + {"kxsd9", 0} +}; + static struct spi_driver kxsd9_driver = { .driver = { .name = "kxsd9", @@ -335,6 +277,7 @@ static struct spi_driver kxsd9_driver = { }, .probe = kxsd9_probe, .remove = __devexit_p(kxsd9_remove), + .id_table = kxsd9_id, }; static __init int kxsd9_spi_init(void) diff --git a/drivers/staging/iio/accel/lis3l02dq_core.c b/drivers/staging/iio/accel/lis3l02dq_core.c index a29dfd2..33001f8 100644 --- a/drivers/staging/iio/accel/lis3l02dq_core.c +++ b/drivers/staging/iio/accel/lis3l02dq_core.c @@ -21,13 +21,12 @@ #include <linux/spi/spi.h> #include <linux/slab.h> #include <linux/sysfs.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" #include "../ring_generic.h" -#include "accel.h" - #include "lis3l02dq.h" /* At the moment the spi framework doesn't allow global setting of cs_change. @@ -454,54 +453,54 @@ static irqreturn_t lis3l02dq_event_handler(int irq, void *private) if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Z_HIGH) iio_push_event(indio_dev, 0, - IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL, + IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, - IIO_EV_MOD_Z, + IIO_MOD_Z, IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), timestamp); if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Z_LOW) iio_push_event(indio_dev, 0, - IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL, + IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, - IIO_EV_MOD_Z, + IIO_MOD_Z, IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), timestamp); if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Y_HIGH) iio_push_event(indio_dev, 0, - IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL, + IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, - IIO_EV_MOD_Y, + IIO_MOD_Y, IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), timestamp); if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_Y_LOW) iio_push_event(indio_dev, 0, - IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL, + IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, - IIO_EV_MOD_Y, + IIO_MOD_Y, IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), timestamp); if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_X_HIGH) iio_push_event(indio_dev, 0, - IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL, + IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, - IIO_EV_MOD_X, + IIO_MOD_X, IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), timestamp); if (t & LIS3L02DQ_REG_WAKE_UP_SRC_INTERRUPT_X_LOW) iio_push_event(indio_dev, 0, - IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL, + IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, - IIO_EV_MOD_X, + IIO_MOD_X, IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), timestamp); diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c index 8d5c8ac..5c6fe13 100644 --- a/drivers/staging/iio/accel/lis3l02dq_ring.c +++ b/drivers/staging/iio/accel/lis3l02dq_ring.c @@ -1,19 +1,15 @@ #include <linux/interrupt.h> -#include <linux/irq.h> #include <linux/gpio.h> #include <linux/mutex.h> -#include <linux/device.h> #include <linux/kernel.h> #include <linux/spi/spi.h> -#include <linux/sysfs.h> #include <linux/slab.h> #include "../iio.h" -#include "../sysfs.h" #include "../ring_sw.h" #include "../kfifo_buf.h" -#include "accel.h" #include "../trigger.h" +#include "../trigger_consumer.h" #include "lis3l02dq.h" /** @@ -165,7 +161,7 @@ static int lis3l02dq_get_ring_element(struct iio_dev *indio_dev, static irqreturn_t lis3l02dq_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->private_data; + struct iio_dev *indio_dev = pf->indio_dev; struct iio_ring_buffer *ring = indio_dev->ring; int len = 0; size_t datasize = ring->access->get_bytes_per_datum(ring); @@ -306,6 +302,12 @@ static int lis3l02dq_trig_try_reen(struct iio_trigger *trig) return 0; } +static const struct iio_trigger_ops lis3l02dq_trigger_ops = { + .owner = THIS_MODULE, + .set_trigger_state = &lis3l02dq_data_rdy_trigger_set_state, + .try_reenable = &lis3l02dq_trig_try_reen, +}; + int lis3l02dq_probe_trigger(struct iio_dev *indio_dev) { int ret; @@ -318,10 +320,8 @@ int lis3l02dq_probe_trigger(struct iio_dev *indio_dev) } st->trig->dev.parent = &st->us->dev; - st->trig->owner = THIS_MODULE; + st->trig->ops = &lis3l02dq_trigger_ops; st->trig->private_data = indio_dev; - st->trig->set_trigger_state = &lis3l02dq_data_rdy_trigger_set_state; - st->trig->try_reenable = &lis3l02dq_trig_try_reen; ret = iio_trigger_register(st->trig); if (ret) goto error_free_trig; diff --git a/drivers/staging/iio/accel/sca3000_core.c b/drivers/staging/iio/accel/sca3000_core.c index 603f5bc..dbf1622 100644 --- a/drivers/staging/iio/accel/sca3000_core.c +++ b/drivers/staging/iio/accel/sca3000_core.c @@ -18,11 +18,11 @@ #include <linux/kernel.h> #include <linux/spi/spi.h> #include <linux/sysfs.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" #include "../ring_generic.h" -#include "accel.h" #include "sca3000.h" enum sca3000_variant { @@ -422,7 +422,7 @@ static IIO_DEVICE_ATTR(measurement_mode, S_IRUGO | S_IWUSR, /* More standard attributes */ -static IIO_DEV_ATTR_REV(sca3000_show_rev); +static IIO_DEVICE_ATTR(revision, S_IRUGO, sca3000_show_rev, NULL, 0); #define SCA3000_INFO_MASK \ (1 << IIO_CHAN_INFO_SCALE_SHARED) @@ -816,36 +816,36 @@ static irqreturn_t sca3000_event_handler(int irq, void *private) if (val & SCA3000_INT_STATUS_FREE_FALL) iio_push_event(indio_dev, 0, - IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL, + IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, - IIO_EV_MOD_X_AND_Y_AND_Z, + IIO_MOD_X_AND_Y_AND_Z, IIO_EV_TYPE_MAG, IIO_EV_DIR_FALLING), last_timestamp); if (val & SCA3000_INT_STATUS_Y_TRIGGER) iio_push_event(indio_dev, 0, - IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL, + IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, - IIO_EV_MOD_Y, + IIO_MOD_Y, IIO_EV_TYPE_MAG, IIO_EV_DIR_RISING), last_timestamp); if (val & SCA3000_INT_STATUS_X_TRIGGER) iio_push_event(indio_dev, 0, - IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL, + IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, - IIO_EV_MOD_X, + IIO_MOD_X, IIO_EV_TYPE_MAG, IIO_EV_DIR_RISING), last_timestamp); if (val & SCA3000_INT_STATUS_Z_TRIGGER) iio_push_event(indio_dev, 0, - IIO_MOD_EVENT_CODE(IIO_EV_CLASS_ACCEL, + IIO_MOD_EVENT_CODE(IIO_ACCEL, 0, - IIO_EV_MOD_Z, + IIO_MOD_Z, IIO_EV_TYPE_MAG, IIO_EV_DIR_RISING), last_timestamp); diff --git a/drivers/staging/iio/accel/sca3000_ring.c b/drivers/staging/iio/accel/sca3000_ring.c index a704c75..0b736db 100644 --- a/drivers/staging/iio/accel/sca3000_ring.c +++ b/drivers/staging/iio/accel/sca3000_ring.c @@ -10,9 +10,7 @@ */ #include <linux/interrupt.h> -#include <linux/gpio.h> #include <linux/fs.h> -#include <linux/device.h> #include <linux/slab.h> #include <linux/kernel.h> #include <linux/spi/spi.h> @@ -24,7 +22,6 @@ #include "../sysfs.h" #include "../ring_generic.h" #include "../ring_hw.h" -#include "accel.h" #include "sca3000.h" /* RFC / future work @@ -226,74 +223,6 @@ static IIO_DEVICE_ATTR(75_percent, S_IRUGO | S_IWUSR, sca3000_set_ring_int, SCA3000_INT_MASK_RING_THREE_QUARTER); - -/** - * sca3000_show_ring_bpse() -sysfs function to query bits per sample from ring - * @dev: ring buffer device - * @attr: this device attribute - * @buf: buffer to write to - **/ -static ssize_t sca3000_show_ring_bpse(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int len = 0, ret; - struct iio_ring_buffer *ring = dev_get_drvdata(dev); - struct iio_dev *indio_dev = ring->indio_dev; - struct sca3000_state *st = iio_priv(indio_dev); - - mutex_lock(&st->lock); - ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1); - if (ret) - goto error_ret; - if (st->rx[0] & SCA3000_RING_BUF_8BIT) - len = sprintf(buf, "s8/8\n"); - else - len = sprintf(buf, "s11/16\n"); -error_ret: - mutex_unlock(&st->lock); - - return ret ? ret : len; -} - -/** - * sca3000_store_ring_bpse() - bits per scan element - * @dev: ring buffer device - * @attr: attribute called from - * @buf: input from userspace - * @len: length of input - **/ -static ssize_t sca3000_store_ring_bpse(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - struct iio_ring_buffer *ring = dev_get_drvdata(dev); - struct iio_dev *indio_dev = ring->indio_dev; - struct sca3000_state *st = iio_priv(indio_dev); - int ret; - - mutex_lock(&st->lock); - - ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_MODE, 1); - if (ret) - goto error_ret; - if (sysfs_streq(buf, "s8/8")) { - ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE, - st->rx[0] | SCA3000_RING_BUF_8BIT); - st->bpse = 8; - } else if (sysfs_streq(buf, "s11/16")) { - ret = sca3000_write_reg(st, SCA3000_REG_ADDR_MODE, - st->rx[0] & ~SCA3000_RING_BUF_8BIT); - st->bpse = 11; - } else - ret = -EINVAL; -error_ret: - mutex_unlock(&st->lock); - - return ret ? ret : len; -} - static ssize_t sca3000_show_buffer_scale(struct device *dev, struct device_attribute *attr, char *buf) diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index b39f2e1..25566c6 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -161,6 +161,20 @@ config AD7816 Say yes here to build support for Analog Devices AD7816/7/8 temperature sensors and ADC. +config AD7192 + tristate "Analog Devices AD7190 AD7192 AD7195 ADC driver" + depends on SPI + select IIO_RING_BUFFER + select IIO_SW_RING + select IIO_TRIGGER + help + Say yes here to build support for Analog Devices AD7190, + AD7192 or AD7195 SPI analog to digital convertors (ADC). + If unsure, say N (but it's safe to say "Y"). + + To compile this driver as a module, choose M here: the + module will be called ad7192. + config ADT75 tristate "Analog Devices ADT75 temperature sensor driver" depends on I2C @@ -182,6 +196,16 @@ config ADT7410 Say yes here to build support for Analog Devices ADT7410 temperature sensors. +config AD7280 + tristate "Analog Devices AD7280A Lithium Ion Battery Monitoring System" + depends on SPI + help + Say yes here to build support for Analog Devices AD7280A + Lithium Ion Battery Monitoring System. + + To compile this driver as a module, choose M here: the + module will be called ad7280a + config MAX1363 tristate "Maxim max1363 ADC driver" depends on I2C diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile index f020351..990d3fa 100644 --- a/drivers/staging/iio/adc/Makefile +++ b/drivers/staging/iio/adc/Makefile @@ -37,6 +37,8 @@ obj-$(CONFIG_AD7745) += ad7745.o obj-$(CONFIG_AD7780) += ad7780.o obj-$(CONFIG_AD7793) += ad7793.o obj-$(CONFIG_AD7816) += ad7816.o +obj-$(CONFIG_AD7192) += ad7192.o obj-$(CONFIG_ADT75) += adt75.o obj-$(CONFIG_ADT7310) += adt7310.o obj-$(CONFIG_ADT7410) += adt7410.o +obj-$(CONFIG_AD7280) += ad7280a.o diff --git a/drivers/staging/iio/adc/ad7150.c b/drivers/staging/iio/adc/ad7150.c index 04017ef..c01acbc 100644 --- a/drivers/staging/iio/adc/ad7150.c +++ b/drivers/staging/iio/adc/ad7150.c @@ -11,6 +11,7 @@ #include <linux/kernel.h> #include <linux/slab.h> #include <linux/i2c.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" @@ -617,6 +618,8 @@ static IIO_DEV_ATTR_POWERDOWN_TIMER(S_IRUGO | S_IWUSR, ad7150_store_powerdown_timer); static struct attribute *ad7150_attributes[] = { + &iio_dev_attr_available_conversion_modes.dev_attr.attr, + &iio_dev_attr_conversion_mode.dev_attr.attr, &iio_dev_attr_available_threshold_modes.dev_attr.attr, &iio_dev_attr_threshold_mode.dev_attr.attr, &iio_dev_attr_ch1_threshold.dev_attr.attr, @@ -652,14 +655,14 @@ static irqreturn_t ad7150_event_handler(int irq, void *private) if ((int_status & AD7150_STATUS_OUT1) && !(chip->old_state & AD7150_STATUS_OUT1)) iio_push_event(indio_dev, 0, - IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_IN, + IIO_UNMOD_EVENT_CODE(IIO_IN, 0, IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), timestamp); else if ((!(int_status & AD7150_STATUS_OUT1)) && (chip->old_state & AD7150_STATUS_OUT1)) iio_push_event(indio_dev, 0, - IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_IN, + IIO_UNMOD_EVENT_CODE(IIO_IN, 0, IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), @@ -667,14 +670,14 @@ static irqreturn_t ad7150_event_handler(int irq, void *private) if ((int_status & AD7150_STATUS_OUT2) && !(chip->old_state & AD7150_STATUS_OUT2)) iio_push_event(indio_dev, 0, - IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_IN, + IIO_UNMOD_EVENT_CODE(IIO_IN, 1, IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), timestamp); else if ((!(int_status & AD7150_STATUS_OUT2)) && (chip->old_state & AD7150_STATUS_OUT2)) iio_push_event(indio_dev, 0, - IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_IN, + IIO_UNMOD_EVENT_CODE(IIO_IN, 1, IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), diff --git a/drivers/staging/iio/adc/ad7152.c b/drivers/staging/iio/adc/ad7152.c index 21f5f38..fcec9b6 100644 --- a/drivers/staging/iio/adc/ad7152.c +++ b/drivers/staging/iio/adc/ad7152.c @@ -12,6 +12,7 @@ #include <linux/slab.h> #include <linux/sysfs.h> #include <linux/i2c.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c new file mode 100644 index 0000000..adf6d95 --- /dev/null +++ b/drivers/staging/iio/adc/ad7192.c @@ -0,0 +1,1184 @@ +/* + * AD7190 AD7192 AD7195 SPI ADC driver + * + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#include <linux/interrupt.h> +#include <linux/device.h> +#include <linux/kernel.h> +#include <linux/slab.h> +#include <linux/sysfs.h> +#include <linux/spi/spi.h> +#include <linux/regulator/consumer.h> +#include <linux/err.h> +#include <linux/sched.h> +#include <linux/delay.h> + +#include "../iio.h" +#include "../sysfs.h" +#include "../ring_generic.h" +#include "../ring_sw.h" +#include "../trigger.h" +#include "../trigger_consumer.h" + +#include "ad7192.h" + +/* Registers */ +#define AD7192_REG_COMM 0 /* Communications Register (WO, 8-bit) */ +#define AD7192_REG_STAT 0 /* Status Register (RO, 8-bit) */ +#define AD7192_REG_MODE 1 /* Mode Register (RW, 24-bit */ +#define AD7192_REG_CONF 2 /* Configuration Register (RW, 24-bit) */ +#define AD7192_REG_DATA 3 /* Data Register (RO, 24/32-bit) */ +#define AD7192_REG_ID 4 /* ID Register (RO, 8-bit) */ +#define AD7192_REG_GPOCON 5 /* GPOCON Register (RO, 8-bit) */ +#define AD7192_REG_OFFSET 6 /* Offset Register (RW, 16-bit + * (AD7792)/24-bit (AD7192)) */ +#define AD7192_REG_FULLSALE 7 /* Full-Scale Register + * (RW, 16-bit (AD7792)/24-bit (AD7192)) */ + +/* Communications Register Bit Designations (AD7192_REG_COMM) */ +#define AD7192_COMM_WEN (1 << 7) /* Write Enable */ +#define AD7192_COMM_WRITE (0 << 6) /* Write Operation */ +#define AD7192_COMM_READ (1 << 6) /* Read Operation */ +#define AD7192_COMM_ADDR(x) (((x) & 0x7) << 3) /* Register Address */ +#define AD7192_COMM_CREAD (1 << 2) /* Continuous Read of Data Register */ + +/* Status Register Bit Designations (AD7192_REG_STAT) */ +#define AD7192_STAT_RDY (1 << 7) /* Ready */ +#define AD7192_STAT_ERR (1 << 6) /* Error (Overrange, Underrange) */ +#define AD7192_STAT_NOREF (1 << 5) /* Error no external reference */ +#define AD7192_STAT_PARITY (1 << 4) /* Parity */ +#define AD7192_STAT_CH3 (1 << 2) /* Channel 3 */ +#define AD7192_STAT_CH2 (1 << 1) /* Channel 2 */ +#define AD7192_STAT_CH1 (1 << 0) /* Channel 1 */ + +/* Mode Register Bit Designations (AD7192_REG_MODE) */ +#define AD7192_MODE_SEL(x) (((x) & 0x7) << 21) /* Operation Mode Select */ +#define AD7192_MODE_DAT_STA (1 << 20) /* Status Register transmission */ +#define AD7192_MODE_CLKSRC(x) (((x) & 0x3) << 18) /* Clock Source Select */ +#define AD7192_MODE_SINC3 (1 << 15) /* SINC3 Filter Select */ +#define AD7192_MODE_ACX (1 << 14) /* AC excitation enable(AD7195 only)*/ +#define AD7192_MODE_ENPAR (1 << 13) /* Parity Enable */ +#define AD7192_MODE_CLKDIV (1 << 12) /* Clock divide by 2 (AD7190/2 only)*/ +#define AD7192_MODE_SCYCLE (1 << 11) /* Single cycle conversion */ +#define AD7192_MODE_REJ60 (1 << 10) /* 50/60Hz notch filter */ +#define AD7192_MODE_RATE(x) ((x) & 0x3FF) /* Filter Update Rate Select */ + +/* Mode Register: AD7192_MODE_SEL options */ +#define AD7192_MODE_CONT 0 /* Continuous Conversion Mode */ +#define AD7192_MODE_SINGLE 1 /* Single Conversion Mode */ +#define AD7192_MODE_IDLE 2 /* Idle Mode */ +#define AD7192_MODE_PWRDN 3 /* Power-Down Mode */ +#define AD7192_MODE_CAL_INT_ZERO 4 /* Internal Zero-Scale Calibration */ +#define AD7192_MODE_CAL_INT_FULL 5 /* Internal Full-Scale Calibration */ +#define AD7192_MODE_CAL_SYS_ZERO 6 /* System Zero-Scale Calibration */ +#define AD7192_MODE_CAL_SYS_FULL 7 /* System Full-Scale Calibration */ + +/* Mode Register: AD7192_MODE_CLKSRC options */ +#define AD7192_CLK_EXT_MCLK1_2 0 /* External 4.92 MHz Clock connected + * from MCLK1 to MCLK2 */ +#define AD7192_CLK_EXT_MCLK2 1 /* External Clock applied to MCLK2 */ +#define AD7192_CLK_INT 2 /* Internal 4.92 MHz Clock not + * available at the MCLK2 pin */ +#define AD7192_CLK_INT_CO 3 /* Internal 4.92 MHz Clock available + * at the MCLK2 pin */ + + +/* Configuration Register Bit Designations (AD7192_REG_CONF) */ + +#define AD7192_CONF_CHOP (1 << 23) /* CHOP enable */ +#define AD7192_CONF_REFSEL (1 << 20) /* REFIN1/REFIN2 Reference Select */ +#define AD7192_CONF_CHAN(x) (((x) & 0xFF) << 8) /* Channel select */ +#define AD7192_CONF_BURN (1 << 7) /* Burnout current enable */ +#define AD7192_CONF_REFDET (1 << 6) /* Reference detect enable */ +#define AD7192_CONF_BUF (1 << 4) /* Buffered Mode Enable */ +#define AD7192_CONF_UNIPOLAR (1 << 3) /* Unipolar/Bipolar Enable */ +#define AD7192_CONF_GAIN(x) ((x) & 0x7) /* Gain Select */ + +#define AD7192_CH_AIN1P_AIN2M 0 /* AIN1(+) - AIN2(-) */ +#define AD7192_CH_AIN3P_AIN4M 1 /* AIN3(+) - AIN4(-) */ +#define AD7192_CH_TEMP 2 /* Temp Sensor */ +#define AD7192_CH_AIN2P_AIN2M 3 /* AIN2(+) - AIN2(-) */ +#define AD7192_CH_AIN1 4 /* AIN1 - AINCOM */ +#define AD7192_CH_AIN2 5 /* AIN2 - AINCOM */ +#define AD7192_CH_AIN3 6 /* AIN3 - AINCOM */ +#define AD7192_CH_AIN4 7 /* AIN4 - AINCOM */ + +/* ID Register Bit Designations (AD7192_REG_ID) */ +#define ID_AD7190 0x4 +#define ID_AD7192 0x0 +#define ID_AD7195 0x6 +#define AD7192_ID_MASK 0x0F + +/* GPOCON Register Bit Designations (AD7192_REG_GPOCON) */ +#define AD7192_GPOCON_BPDSW (1 << 6) /* Bridge power-down switch enable */ +#define AD7192_GPOCON_GP32EN (1 << 5) /* Digital Output P3 and P2 enable */ +#define AD7192_GPOCON_GP10EN (1 << 4) /* Digital Output P1 and P0 enable */ +#define AD7192_GPOCON_P3DAT (1 << 3) /* P3 state */ +#define AD7192_GPOCON_P2DAT (1 << 2) /* P2 state */ +#define AD7192_GPOCON_P1DAT (1 << 1) /* P1 state */ +#define AD7192_GPOCON_P0DAT (1 << 0) /* P0 state */ + +#define AD7192_INT_FREQ_MHz 4915200 + +/* NOTE: + * The AD7190/2/5 features a dual use data out ready DOUT/RDY output. + * In order to avoid contentions on the SPI bus, it's therefore necessary + * to use spi bus locking. + * + * The DOUT/RDY output must also be wired to an interrupt capable GPIO. + */ + +struct ad7192_state { + struct spi_device *spi; + struct iio_trigger *trig; + struct regulator *reg; + struct ad7192_platform_data *pdata; + wait_queue_head_t wq_data_avail; + bool done; + bool irq_dis; + u16 int_vref_mv; + u32 mclk; + u32 f_order; + u32 mode; + u32 conf; + u32 scale_avail[8][2]; + u32 available_scan_masks[9]; + u8 gpocon; + u8 devid; + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + */ + u8 data[4] ____cacheline_aligned; +}; + +static int __ad7192_write_reg(struct ad7192_state *st, bool locked, + bool cs_change, unsigned char reg, + unsigned size, unsigned val) +{ + u8 *data = st->data; + struct spi_transfer t = { + .tx_buf = data, + .len = size + 1, + .cs_change = cs_change, + }; + struct spi_message m; + + data[0] = AD7192_COMM_WRITE | AD7192_COMM_ADDR(reg); + + switch (size) { + case 3: + data[1] = val >> 16; + data[2] = val >> 8; + data[3] = val; + break; + case 2: + data[1] = val >> 8; + data[2] = val; + break; + case 1: + data[1] = val; + break; + default: + return -EINVAL; + } + + spi_message_init(&m); + spi_message_add_tail(&t, &m); + + if (locked) + return spi_sync_locked(st->spi, &m); + else + return spi_sync(st->spi, &m); +} + +static int ad7192_write_reg(struct ad7192_state *st, + unsigned reg, unsigned size, unsigned val) +{ + return __ad7192_write_reg(st, false, false, reg, size, val); +} + +static int __ad7192_read_reg(struct ad7192_state *st, bool locked, + bool cs_change, unsigned char reg, + int *val, unsigned size) +{ + u8 *data = st->data; + int ret; + struct spi_transfer t[] = { + { + .tx_buf = data, + .len = 1, + }, { + .rx_buf = data, + .len = size, + .cs_change = cs_change, + }, + }; + struct spi_message m; + + data[0] = AD7192_COMM_READ | AD7192_COMM_ADDR(reg); + + spi_message_init(&m); + spi_message_add_tail(&t[0], &m); + spi_message_add_tail(&t[1], &m); + + if (locked) + ret = spi_sync_locked(st->spi, &m); + else + ret = spi_sync(st->spi, &m); + + if (ret < 0) + return ret; + + switch (size) { + case 3: + *val = data[0] << 16 | data[1] << 8 | data[2]; + break; + case 2: + *val = data[0] << 8 | data[1]; + break; + case 1: + *val = data[0]; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int ad7192_read_reg(struct ad7192_state *st, + unsigned reg, int *val, unsigned size) +{ + return __ad7192_read_reg(st, 0, 0, reg, val, size); +} + +static int ad7192_read(struct ad7192_state *st, unsigned ch, + unsigned len, int *val) +{ + int ret; + st->conf = (st->conf & ~AD7192_CONF_CHAN(-1)) | + AD7192_CONF_CHAN(1 << ch); + st->mode = (st->mode & ~AD7192_MODE_SEL(-1)) | + AD7192_MODE_SEL(AD7192_MODE_SINGLE); + + ad7192_write_reg(st, AD7192_REG_CONF, 3, st->conf); + + spi_bus_lock(st->spi->master); + st->done = false; + + ret = __ad7192_write_reg(st, 1, 1, AD7192_REG_MODE, 3, st->mode); + if (ret < 0) + goto out; + + st->irq_dis = false; + enable_irq(st->spi->irq); + wait_event_interruptible(st->wq_data_avail, st->done); + + ret = __ad7192_read_reg(st, 1, 0, AD7192_REG_DATA, val, len); +out: + spi_bus_unlock(st->spi->master); + + return ret; +} + +static int ad7192_calibrate(struct ad7192_state *st, unsigned mode, unsigned ch) +{ + int ret; + + st->conf = (st->conf & ~AD7192_CONF_CHAN(-1)) | + AD7192_CONF_CHAN(1 << ch); + st->mode = (st->mode & ~AD7192_MODE_SEL(-1)) | AD7192_MODE_SEL(mode); + + ad7192_write_reg(st, AD7192_REG_CONF, 3, st->conf); + + spi_bus_lock(st->spi->master); + st->done = false; + + ret = __ad7192_write_reg(st, 1, 1, AD7192_REG_MODE, 3, + (st->devid != ID_AD7195) ? + st->mode | AD7192_MODE_CLKDIV : + st->mode); + if (ret < 0) + goto out; + + st->irq_dis = false; + enable_irq(st->spi->irq); + wait_event_interruptible(st->wq_data_avail, st->done); + + st->mode = (st->mode & ~AD7192_MODE_SEL(-1)) | + AD7192_MODE_SEL(AD7192_MODE_IDLE); + + ret = __ad7192_write_reg(st, 1, 0, AD7192_REG_MODE, 3, st->mode); +out: + spi_bus_unlock(st->spi->master); + + return ret; +} + +static const u8 ad7192_calib_arr[8][2] = { + {AD7192_MODE_CAL_INT_ZERO, AD7192_CH_AIN1}, + {AD7192_MODE_CAL_INT_FULL, AD7192_CH_AIN1}, + {AD7192_MODE_CAL_INT_ZERO, AD7192_CH_AIN2}, + {AD7192_MODE_CAL_INT_FULL, AD7192_CH_AIN2}, + {AD7192_MODE_CAL_INT_ZERO, AD7192_CH_AIN3}, + {AD7192_MODE_CAL_INT_FULL, AD7192_CH_AIN3}, + {AD7192_MODE_CAL_INT_ZERO, AD7192_CH_AIN4}, + {AD7192_MODE_CAL_INT_FULL, AD7192_CH_AIN4} +}; + +static int ad7192_calibrate_all(struct ad7192_state *st) +{ + int i, ret; + + for (i = 0; i < ARRAY_SIZE(ad7192_calib_arr); i++) { + ret = ad7192_calibrate(st, ad7192_calib_arr[i][0], + ad7192_calib_arr[i][1]); + if (ret) + goto out; + } + + return 0; +out: + dev_err(&st->spi->dev, "Calibration failed\n"); + return ret; +} + +static int ad7192_setup(struct ad7192_state *st) +{ + struct iio_dev *indio_dev = spi_get_drvdata(st->spi); + struct ad7192_platform_data *pdata = st->pdata; + unsigned long long scale_uv; + int i, ret, id; + u8 ones[6]; + + /* reset the serial interface */ + memset(&ones, 0xFF, 6); + ret = spi_write(st->spi, &ones, 6); + if (ret < 0) + goto out; + msleep(1); /* Wait for at least 500us */ + + /* write/read test for device presence */ + ret = ad7192_read_reg(st, AD7192_REG_ID, &id, 1); + if (ret) + goto out; + + id &= AD7192_ID_MASK; + + if (id != st->devid) + dev_warn(&st->spi->dev, "device ID query failed (0x%X)\n", id); + + switch (pdata->clock_source_sel) { + case AD7192_CLK_EXT_MCLK1_2: + case AD7192_CLK_EXT_MCLK2: + st->mclk = AD7192_INT_FREQ_MHz; + break; + case AD7192_CLK_INT: + case AD7192_CLK_INT_CO: + if (pdata->ext_clk_Hz) + st->mclk = pdata->ext_clk_Hz; + else + st->mclk = AD7192_INT_FREQ_MHz; + break; + default: + ret = -EINVAL; + goto out; + } + + st->mode = AD7192_MODE_SEL(AD7192_MODE_IDLE) | + AD7192_MODE_CLKSRC(pdata->clock_source_sel) | + AD7192_MODE_RATE(480); + + st->conf = AD7192_CONF_GAIN(0); + + if (pdata->rej60_en) + st->mode |= AD7192_MODE_REJ60; + + if (pdata->sinc3_en) + st->mode |= AD7192_MODE_SINC3; + + if (pdata->refin2_en && (st->devid != ID_AD7195)) + st->conf |= AD7192_CONF_REFSEL; + + if (pdata->chop_en) { + st->conf |= AD7192_CONF_CHOP; + if (pdata->sinc3_en) + st->f_order = 3; /* SINC 3rd order */ + else + st->f_order = 4; /* SINC 4th order */ + } else { + st->f_order = 1; + } + + if (pdata->buf_en) + st->conf |= AD7192_CONF_BUF; + + if (pdata->unipolar_en) + st->conf |= AD7192_CONF_UNIPOLAR; + + if (pdata->burnout_curr_en) + st->conf |= AD7192_CONF_BURN; + + ret = ad7192_write_reg(st, AD7192_REG_MODE, 3, st->mode); + if (ret) + goto out; + + ret = ad7192_write_reg(st, AD7192_REG_CONF, 3, st->conf); + if (ret) + goto out; + + ret = ad7192_calibrate_all(st); + if (ret) + goto out; + + /* Populate available ADC input ranges */ + for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++) { + scale_uv = ((u64)st->int_vref_mv * 100000000) + >> (indio_dev->channels[0].scan_type.realbits - + ((st->conf & AD7192_CONF_UNIPOLAR) ? 0 : 1)); + scale_uv >>= i; + + st->scale_avail[i][1] = do_div(scale_uv, 100000000) * 10; + st->scale_avail[i][0] = scale_uv; + } + + return 0; +out: + dev_err(&st->spi->dev, "setup failed\n"); + return ret; +} + +static int ad7192_scan_from_ring(struct ad7192_state *st, unsigned ch, int *val) +{ + struct iio_ring_buffer *ring = iio_priv_to_dev(st)->ring; + int ret; + s64 dat64[2]; + u32 *dat32 = (u32 *)dat64; + + if (!(ring->scan_mask & (1 << ch))) + return -EBUSY; + + ret = ring->access->read_last(ring, (u8 *) &dat64); + if (ret) + return ret; + + *val = *dat32; + + return 0; +} + +static int ad7192_ring_preenable(struct iio_dev *indio_dev) +{ + struct ad7192_state *st = iio_priv(indio_dev); + struct iio_ring_buffer *ring = indio_dev->ring; + size_t d_size; + unsigned channel; + + if (!ring->scan_count) + return -EINVAL; + + channel = __ffs(ring->scan_mask); + + d_size = ring->scan_count * + indio_dev->channels[0].scan_type.storagebits / 8; + + if (ring->scan_timestamp) { + d_size += sizeof(s64); + + if (d_size % sizeof(s64)) + d_size += sizeof(s64) - (d_size % sizeof(s64)); + } + + if (indio_dev->ring->access->set_bytes_per_datum) + indio_dev->ring->access->set_bytes_per_datum(indio_dev->ring, + d_size); + + st->mode = (st->mode & ~AD7192_MODE_SEL(-1)) | + AD7192_MODE_SEL(AD7192_MODE_CONT); + st->conf = (st->conf & ~AD7192_CONF_CHAN(-1)) | + AD7192_CONF_CHAN(1 << indio_dev->channels[channel].address); + + ad7192_write_reg(st, AD7192_REG_CONF, 3, st->conf); + + spi_bus_lock(st->spi->master); + __ad7192_write_reg(st, 1, 1, AD7192_REG_MODE, 3, st->mode); + + st->irq_dis = false; + enable_irq(st->spi->irq); + + return 0; +} + +static int ad7192_ring_postdisable(struct iio_dev *indio_dev) +{ + struct ad7192_state *st = iio_priv(indio_dev); + + st->mode = (st->mode & ~AD7192_MODE_SEL(-1)) | + AD7192_MODE_SEL(AD7192_MODE_IDLE); + + st->done = false; + wait_event_interruptible(st->wq_data_avail, st->done); + + if (!st->irq_dis) + disable_irq_nosync(st->spi->irq); + + __ad7192_write_reg(st, 1, 0, AD7192_REG_MODE, 3, st->mode); + + return spi_bus_unlock(st->spi->master); +} + +/** + * ad7192_trigger_handler() bh of trigger launched polling to ring buffer + **/ +static irqreturn_t ad7192_trigger_handler(int irq, void *p) +{ + struct iio_poll_func *pf = p; + struct iio_dev *indio_dev = pf->indio_dev; + struct iio_ring_buffer *ring = indio_dev->ring; + struct ad7192_state *st = iio_priv(indio_dev); + s64 dat64[2]; + s32 *dat32 = (s32 *)dat64; + + if (ring->scan_count) + __ad7192_read_reg(st, 1, 1, AD7192_REG_DATA, + dat32, + indio_dev->channels[0].scan_type.realbits/8); + + /* Guaranteed to be aligned with 8 byte boundary */ + if (ring->scan_timestamp) + dat64[1] = pf->timestamp; + + ring->access->store_to(ring, (u8 *)dat64, pf->timestamp); + + iio_trigger_notify_done(indio_dev->trig); + st->irq_dis = false; + enable_irq(st->spi->irq); + + return IRQ_HANDLED; +} + +static const struct iio_ring_setup_ops ad7192_ring_setup_ops = { + .preenable = &ad7192_ring_preenable, + .postenable = &iio_triggered_ring_postenable, + .predisable = &iio_triggered_ring_predisable, + .postdisable = &ad7192_ring_postdisable, +}; + +static int ad7192_register_ring_funcs_and_init(struct iio_dev *indio_dev) +{ + int ret; + + indio_dev->ring = iio_sw_rb_allocate(indio_dev); + if (!indio_dev->ring) { + ret = -ENOMEM; + goto error_ret; + } + /* Effectively select the ring buffer implementation */ + indio_dev->ring->access = &ring_sw_access_funcs; + indio_dev->pollfunc = iio_alloc_pollfunc(&iio_pollfunc_store_time, + &ad7192_trigger_handler, + IRQF_ONESHOT, + indio_dev, + "ad7192_consumer%d", + indio_dev->id); + if (indio_dev->pollfunc == NULL) { + ret = -ENOMEM; + goto error_deallocate_sw_rb; + } + + /* Ring buffer functions - here trigger setup related */ + indio_dev->ring->setup_ops = &ad7192_ring_setup_ops; + + /* Flag that polled ring buffering is possible */ + indio_dev->modes |= INDIO_RING_TRIGGERED; + return 0; + +error_deallocate_sw_rb: + iio_sw_rb_free(indio_dev->ring); +error_ret: + return ret; +} + +static void ad7192_ring_cleanup(struct iio_dev *indio_dev) +{ + iio_dealloc_pollfunc(indio_dev->pollfunc); + iio_sw_rb_free(indio_dev->ring); +} + +/** + * ad7192_data_rdy_trig_poll() the event handler for the data rdy trig + **/ +static irqreturn_t ad7192_data_rdy_trig_poll(int irq, void *private) +{ + struct ad7192_state *st = iio_priv(private); + + st->done = true; + wake_up_interruptible(&st->wq_data_avail); + disable_irq_nosync(irq); + st->irq_dis = true; + iio_trigger_poll(st->trig, iio_get_time_ns()); + + return IRQ_HANDLED; +} + +static int ad7192_probe_trigger(struct iio_dev *indio_dev) +{ + struct ad7192_state *st = iio_priv(indio_dev); + int ret; + + st->trig = iio_allocate_trigger("%s-dev%d", + spi_get_device_id(st->spi)->name, + indio_dev->id); + if (st->trig == NULL) { + ret = -ENOMEM; + goto error_ret; + } + + ret = request_irq(st->spi->irq, + ad7192_data_rdy_trig_poll, + IRQF_TRIGGER_LOW, + spi_get_device_id(st->spi)->name, + indio_dev); + if (ret) + goto error_free_trig; + + disable_irq_nosync(st->spi->irq); + st->irq_dis = true; + st->trig->dev.parent = &st->spi->dev; + st->trig->owner = THIS_MODULE; + st->trig->private_data = indio_dev; + + ret = iio_trigger_register(st->trig); + + /* select default trigger */ + indio_dev->trig = st->trig; + if (ret) + goto error_free_irq; + + return 0; + +error_free_irq: + free_irq(st->spi->irq, indio_dev); +error_free_trig: + iio_free_trigger(st->trig); +error_ret: + return ret; +} + +static void ad7192_remove_trigger(struct iio_dev *indio_dev) +{ + struct ad7192_state *st = iio_priv(indio_dev); + + iio_trigger_unregister(st->trig); + free_irq(st->spi->irq, indio_dev); + iio_free_trigger(st->trig); +} + +static ssize_t ad7192_read_frequency(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad7192_state *st = iio_priv(indio_dev); + + return sprintf(buf, "%d\n", st->mclk / + (st->f_order * 1024 * AD7192_MODE_RATE(st->mode))); +} + +static ssize_t ad7192_write_frequency(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad7192_state *st = iio_priv(indio_dev); + unsigned long lval; + int div, ret; + + ret = strict_strtoul(buf, 10, &lval); + if (ret) + return ret; + + mutex_lock(&indio_dev->mlock); + if (iio_ring_enabled(indio_dev)) { + mutex_unlock(&indio_dev->mlock); + return -EBUSY; + } + + div = st->mclk / (lval * st->f_order * 1024); + if (div < 1 || div > 1023) { + ret = -EINVAL; + goto out; + } + + st->mode &= ~AD7192_MODE_RATE(-1); + st->mode |= AD7192_MODE_RATE(div); + ad7192_write_reg(st, AD7192_REG_MODE, 3, st->mode); + +out: + mutex_unlock(&indio_dev->mlock); + + return ret ? ret : len; +} + +static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, + ad7192_read_frequency, + ad7192_write_frequency); + + +static ssize_t ad7192_show_scale_available(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad7192_state *st = iio_priv(indio_dev); + int i, len = 0; + + for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++) + len += sprintf(buf + len, "%d.%09u ", st->scale_avail[i][0], + st->scale_avail[i][1]); + + len += sprintf(buf + len, "\n"); + + return len; +} + +static IIO_DEVICE_ATTR_NAMED(in_m_in_scale_available, in-in_scale_available, + S_IRUGO, ad7192_show_scale_available, NULL, 0); + +static IIO_DEVICE_ATTR(in_scale_available, S_IRUGO, + ad7192_show_scale_available, NULL, 0); + +static ssize_t ad7192_show_ac_excitation(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad7192_state *st = iio_priv(indio_dev); + + return sprintf(buf, "%d\n", !!(st->mode & AD7192_MODE_ACX)); +} + +static ssize_t ad7192_show_bridge_switch(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad7192_state *st = iio_priv(indio_dev); + + return sprintf(buf, "%d\n", !!(st->gpocon & AD7192_GPOCON_BPDSW)); +} + +static ssize_t ad7192_set(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad7192_state *st = iio_priv(indio_dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int ret; + bool val; + + ret = strtobool(buf, &val); + if (ret < 0) + return ret; + + mutex_lock(&indio_dev->mlock); + if (iio_ring_enabled(indio_dev)) { + mutex_unlock(&indio_dev->mlock); + return -EBUSY; + } + + switch (this_attr->address) { + case AD7192_REG_GPOCON: + if (val) + st->gpocon |= AD7192_GPOCON_BPDSW; + else + st->gpocon &= ~AD7192_GPOCON_BPDSW; + + ad7192_write_reg(st, AD7192_REG_GPOCON, 1, st->gpocon); + break; + case AD7192_REG_MODE: + if (val) + st->mode |= AD7192_MODE_ACX; + else + st->mode &= ~AD7192_MODE_ACX; + + ad7192_write_reg(st, AD7192_REG_GPOCON, 3, st->mode); + break; + default: + ret = -EINVAL; + } + + mutex_unlock(&indio_dev->mlock); + + return ret ? ret : len; +} + +static IIO_DEVICE_ATTR(bridge_switch_en, S_IRUGO | S_IWUSR, + ad7192_show_bridge_switch, ad7192_set, + AD7192_REG_GPOCON); + +static IIO_DEVICE_ATTR(ac_excitation_en, S_IRUGO | S_IWUSR, + ad7192_show_ac_excitation, ad7192_set, + AD7192_REG_MODE); + +static struct attribute *ad7192_attributes[] = { + &iio_dev_attr_sampling_frequency.dev_attr.attr, + &iio_dev_attr_in_m_in_scale_available.dev_attr.attr, + &iio_dev_attr_in_scale_available.dev_attr.attr, + &iio_dev_attr_bridge_switch_en.dev_attr.attr, + &iio_dev_attr_ac_excitation_en.dev_attr.attr, + NULL +}; + +static mode_t ad7192_attr_is_visible(struct kobject *kobj, + struct attribute *attr, int n) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7192_state *st = iio_priv(dev_info); + + mode_t mode = attr->mode; + + if ((st->devid != ID_AD7195) && + (attr == &iio_dev_attr_ac_excitation_en.dev_attr.attr)) + mode = 0; + + return mode; +} + +static const struct attribute_group ad7192_attribute_group = { + .attrs = ad7192_attributes, + .is_visible = ad7192_attr_is_visible, +}; + +static int ad7192_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long m) +{ + struct ad7192_state *st = iio_priv(indio_dev); + int ret, smpl = 0; + bool unipolar = !!(st->conf & AD7192_CONF_UNIPOLAR); + + switch (m) { + case 0: + mutex_lock(&indio_dev->mlock); + if (iio_ring_enabled(indio_dev)) + ret = ad7192_scan_from_ring(st, + chan->scan_index, &smpl); + else + ret = ad7192_read(st, chan->address, + chan->scan_type.realbits / 8, &smpl); + mutex_unlock(&indio_dev->mlock); + + if (ret < 0) + return ret; + + *val = (smpl >> chan->scan_type.shift) & + ((1 << (chan->scan_type.realbits)) - 1); + + switch (chan->type) { + case IIO_IN: + case IIO_IN_DIFF: + if (!unipolar) + *val -= (1 << (chan->scan_type.realbits - 1)); + break; + case IIO_TEMP: + *val -= 0x800000; + *val /= 2815; /* temp Kelvin */ + *val -= 273; /* temp Celsius */ + break; + default: + return -EINVAL; + } + return IIO_VAL_INT; + + case (1 << IIO_CHAN_INFO_SCALE_SHARED): + mutex_lock(&indio_dev->mlock); + *val = st->scale_avail[AD7192_CONF_GAIN(st->conf)][0]; + *val2 = st->scale_avail[AD7192_CONF_GAIN(st->conf)][1]; + mutex_unlock(&indio_dev->mlock); + + return IIO_VAL_INT_PLUS_NANO; + + case (1 << IIO_CHAN_INFO_SCALE_SEPARATE): + *val = 1000; + + return IIO_VAL_INT; + } + + return -EINVAL; +} + +static int ad7192_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, + int val2, + long mask) +{ + struct ad7192_state *st = iio_priv(indio_dev); + int ret, i; + unsigned int tmp; + + mutex_lock(&indio_dev->mlock); + if (iio_ring_enabled(indio_dev)) { + mutex_unlock(&indio_dev->mlock); + return -EBUSY; + } + + switch (mask) { + case (1 << IIO_CHAN_INFO_SCALE_SHARED): + ret = -EINVAL; + for (i = 0; i < ARRAY_SIZE(st->scale_avail); i++) + if (val2 == st->scale_avail[i][1]) { + tmp = st->conf; + st->conf &= ~AD7192_CONF_GAIN(-1); + st->conf |= AD7192_CONF_GAIN(i); + + if (tmp != st->conf) { + ad7192_write_reg(st, AD7192_REG_CONF, + 3, st->conf); + ad7192_calibrate_all(st); + } + ret = 0; + } + + default: + ret = -EINVAL; + } + + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static int ad7192_validate_trigger(struct iio_dev *indio_dev, + struct iio_trigger *trig) +{ + if (indio_dev->trig != trig) + return -EINVAL; + + return 0; +} + +static int ad7192_write_raw_get_fmt(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + long mask) +{ + return IIO_VAL_INT_PLUS_NANO; +} + +static const struct iio_info ad7192_info = { + .read_raw = &ad7192_read_raw, + .write_raw = &ad7192_write_raw, + .write_raw_get_fmt = &ad7192_write_raw_get_fmt, + .attrs = &ad7192_attribute_group, + .validate_trigger = ad7192_validate_trigger, + .driver_module = THIS_MODULE, +}; + +#define AD7192_CHAN_DIFF(_chan, _chan2, _name, _address, _si) \ + { .type = IIO_IN_DIFF, \ + .indexed = 1, \ + .extend_name = _name, \ + .channel = _chan, \ + .channel2 = _chan2, \ + .info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED), \ + .address = _address, \ + .scan_index = _si, \ + .scan_type = IIO_ST('s', 24, 32, 0)} + +#define AD7192_CHAN(_chan, _address, _si) \ + { .type = IIO_IN, \ + .indexed = 1, \ + .channel = _chan, \ + .info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED), \ + .address = _address, \ + .scan_index = _si, \ + .scan_type = IIO_ST('s', 24, 32, 0)} + +#define AD7192_CHAN_TEMP(_chan, _address, _si) \ + { .type = IIO_TEMP, \ + .indexed = 1, \ + .channel = _chan, \ + .info_mask = (1 << IIO_CHAN_INFO_SCALE_SEPARATE), \ + .address = _address, \ + .scan_index = _si, \ + .scan_type = IIO_ST('s', 24, 32, 0)} + +static struct iio_chan_spec ad7192_channels[] = { + AD7192_CHAN_DIFF(1, 2, NULL, AD7192_CH_AIN1P_AIN2M, 0), + AD7192_CHAN_DIFF(3, 4, NULL, AD7192_CH_AIN3P_AIN4M, 1), + AD7192_CHAN_TEMP(0, AD7192_CH_TEMP, 2), + AD7192_CHAN_DIFF(2, 2, "shorted", AD7192_CH_AIN2P_AIN2M, 3), + AD7192_CHAN(1, AD7192_CH_AIN1, 4), + AD7192_CHAN(2, AD7192_CH_AIN2, 5), + AD7192_CHAN(3, AD7192_CH_AIN3, 6), + AD7192_CHAN(4, AD7192_CH_AIN4, 7), + IIO_CHAN_SOFT_TIMESTAMP(8), +}; + +static int __devinit ad7192_probe(struct spi_device *spi) +{ + struct ad7192_platform_data *pdata = spi->dev.platform_data; + struct ad7192_state *st; + struct iio_dev *indio_dev; + int ret, i , voltage_uv = 0, regdone = 0; + + if (!pdata) { + dev_err(&spi->dev, "no platform data?\n"); + return -ENODEV; + } + + if (!spi->irq) { + dev_err(&spi->dev, "no IRQ?\n"); + return -ENODEV; + } + + indio_dev = iio_allocate_device(sizeof(*st)); + if (indio_dev == NULL) + return -ENOMEM; + + st = iio_priv(indio_dev); + + st->reg = regulator_get(&spi->dev, "vcc"); + if (!IS_ERR(st->reg)) { + ret = regulator_enable(st->reg); + if (ret) + goto error_put_reg; + + voltage_uv = regulator_get_voltage(st->reg); + } + + st->pdata = pdata; + + if (pdata && pdata->vref_mv) + st->int_vref_mv = pdata->vref_mv; + else if (voltage_uv) + st->int_vref_mv = voltage_uv / 1000; + else + dev_warn(&spi->dev, "reference voltage undefined\n"); + + spi_set_drvdata(spi, indio_dev); + st->spi = spi; + st->devid = spi_get_device_id(spi)->driver_data; + indio_dev->dev.parent = &spi->dev; + indio_dev->name = spi_get_device_id(spi)->name; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = ad7192_channels; + indio_dev->num_channels = ARRAY_SIZE(ad7192_channels); + indio_dev->available_scan_masks = st->available_scan_masks; + indio_dev->info = &ad7192_info; + + for (i = 0; i < indio_dev->num_channels; i++) + st->available_scan_masks[i] = (1 << i) | (1 << + indio_dev->channels[indio_dev->num_channels - 1]. + scan_index); + + init_waitqueue_head(&st->wq_data_avail); + + ret = ad7192_register_ring_funcs_and_init(indio_dev); + if (ret) + goto error_disable_reg; + + ret = iio_device_register(indio_dev); + if (ret) + goto error_unreg_ring; + regdone = 1; + + ret = ad7192_probe_trigger(indio_dev); + if (ret) + goto error_unreg_ring; + + ret = iio_ring_buffer_register_ex(indio_dev->ring, 0, + indio_dev->channels, + indio_dev->num_channels); + if (ret) + goto error_remove_trigger; + + ret = ad7192_setup(st); + if (ret) + goto error_uninitialize_ring; + + return 0; + +error_uninitialize_ring: + iio_ring_buffer_unregister(indio_dev->ring); +error_remove_trigger: + ad7192_remove_trigger(indio_dev); +error_unreg_ring: + ad7192_ring_cleanup(indio_dev); +error_disable_reg: + if (!IS_ERR(st->reg)) + regulator_disable(st->reg); +error_put_reg: + if (!IS_ERR(st->reg)) + regulator_put(st->reg); + + if (regdone) + iio_device_unregister(indio_dev); + else + iio_free_device(indio_dev); + + return ret; +} + +static int ad7192_remove(struct spi_device *spi) +{ + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct ad7192_state *st = iio_priv(indio_dev); + + iio_ring_buffer_unregister(indio_dev->ring); + ad7192_remove_trigger(indio_dev); + ad7192_ring_cleanup(indio_dev); + + if (!IS_ERR(st->reg)) { + regulator_disable(st->reg); + regulator_put(st->reg); + } + + iio_device_unregister(indio_dev); + + return 0; +} + +static const struct spi_device_id ad7192_id[] = { + {"ad7190", ID_AD7190}, + {"ad7192", ID_AD7192}, + {"ad7195", ID_AD7195}, + {} +}; + +static struct spi_driver ad7192_driver = { + .driver = { + .name = "ad7192", + .owner = THIS_MODULE, + }, + .probe = ad7192_probe, + .remove = __devexit_p(ad7192_remove), + .id_table = ad7192_id, +}; + +static int __init ad7192_init(void) +{ + return spi_register_driver(&ad7192_driver); +} +module_init(ad7192_init); + +static void __exit ad7192_exit(void) +{ + spi_unregister_driver(&ad7192_driver); +} +module_exit(ad7192_exit); + +MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); +MODULE_DESCRIPTION("Analog Devices AD7190, AD7192, AD7195 ADC"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/adc/ad7192.h b/drivers/staging/iio/adc/ad7192.h new file mode 100644 index 0000000..a0a5b61 --- /dev/null +++ b/drivers/staging/iio/adc/ad7192.h @@ -0,0 +1,47 @@ +/* + * AD7190 AD7192 AD7195 SPI ADC driver + * + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ +#ifndef IIO_ADC_AD7192_H_ +#define IIO_ADC_AD7192_H_ + +/* + * TODO: struct ad7192_platform_data needs to go into include/linux/iio + */ + +/** + * struct ad7192_platform_data - platform/board specific information + * @vref_mv: the external reference voltage in millivolt + * @clock_source_sel: [0..3] + * 0 External 4.92 MHz clock connected from MCLK1 to MCLK2 + * 1 External Clock applied to MCLK2 + * 2 Internal 4.92 MHz Clock not available at the MCLK2 pin + * 3 Internal 4.92 MHz Clock available at the MCLK2 pin + * @ext_clk_Hz: the external clock frequency in Hz, if not set + * the driver uses the internal clock (16.776 MHz) + * @refin2_en: REFIN1/REFIN2 Reference Select (AD7190/2 only) + * @rej60_en: 50/60Hz notch filter enable + * @sinc3_en: SINC3 filter enable (default SINC4) + * @chop_en: CHOP mode enable + * @buf_en: buffered input mode enable + * @unipolar_en: unipolar mode enable + * @burnout_curr_en: constant current generators on AIN(+|-) enable + */ + +struct ad7192_platform_data { + u16 vref_mv; + u8 clock_source_sel; + u32 ext_clk_Hz; + bool refin2_en; + bool rej60_en; + bool sinc3_en; + bool chop_en; + bool buf_en; + bool unipolar_en; + bool burnout_curr_en; +}; + +#endif /* IIO_ADC_AD7192_H_ */ diff --git a/drivers/staging/iio/adc/ad7280a.c b/drivers/staging/iio/adc/ad7280a.c new file mode 100644 index 0000000..ab6cf9c --- /dev/null +++ b/drivers/staging/iio/adc/ad7280a.c @@ -0,0 +1,992 @@ +/* + * AD7280A Lithium Ion Battery Monitoring System + * + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#include <linux/device.h> +#include <linux/kernel.h> +#include <linux/slab.h> +#include <linux/sysfs.h> +#include <linux/spi/spi.h> +#include <linux/err.h> +#include <linux/delay.h> +#include <linux/interrupt.h> + +#include "../iio.h" +#include "../sysfs.h" + +#include "ad7280a.h" + +/* Registers */ +#define AD7280A_CELL_VOLTAGE_1 0x0 /* D11 to D0, Read only */ +#define AD7280A_CELL_VOLTAGE_2 0x1 /* D11 to D0, Read only */ +#define AD7280A_CELL_VOLTAGE_3 0x2 /* D11 to D0, Read only */ +#define AD7280A_CELL_VOLTAGE_4 0x3 /* D11 to D0, Read only */ +#define AD7280A_CELL_VOLTAGE_5 0x4 /* D11 to D0, Read only */ +#define AD7280A_CELL_VOLTAGE_6 0x5 /* D11 to D0, Read only */ +#define AD7280A_AUX_ADC_1 0x6 /* D11 to D0, Read only */ +#define AD7280A_AUX_ADC_2 0x7 /* D11 to D0, Read only */ +#define AD7280A_AUX_ADC_3 0x8 /* D11 to D0, Read only */ +#define AD7280A_AUX_ADC_4 0x9 /* D11 to D0, Read only */ +#define AD7280A_AUX_ADC_5 0xA /* D11 to D0, Read only */ +#define AD7280A_AUX_ADC_6 0xB /* D11 to D0, Read only */ +#define AD7280A_SELF_TEST 0xC /* D11 to D0, Read only */ +#define AD7280A_CONTROL_HB 0xD /* D15 to D8, Read/write */ +#define AD7280A_CONTROL_LB 0xE /* D7 to D0, Read/write */ +#define AD7280A_CELL_OVERVOLTAGE 0xF /* D7 to D0, Read/write */ +#define AD7280A_CELL_UNDERVOLTAGE 0x10 /* D7 to D0, Read/write */ +#define AD7280A_AUX_ADC_OVERVOLTAGE 0x11 /* D7 to D0, Read/write */ +#define AD7280A_AUX_ADC_UNDERVOLTAGE 0x12 /* D7 to D0, Read/write */ +#define AD7280A_ALERT 0x13 /* D7 to D0, Read/write */ +#define AD7280A_CELL_BALANCE 0x14 /* D7 to D0, Read/write */ +#define AD7280A_CB1_TIMER 0x15 /* D7 to D0, Read/write */ +#define AD7280A_CB2_TIMER 0x16 /* D7 to D0, Read/write */ +#define AD7280A_CB3_TIMER 0x17 /* D7 to D0, Read/write */ +#define AD7280A_CB4_TIMER 0x18 /* D7 to D0, Read/write */ +#define AD7280A_CB5_TIMER 0x19 /* D7 to D0, Read/write */ +#define AD7280A_CB6_TIMER 0x1A /* D7 to D0, Read/write */ +#define AD7280A_PD_TIMER 0x1B /* D7 to D0, Read/write */ +#define AD7280A_READ 0x1C /* D7 to D0, Read/write */ +#define AD7280A_CNVST_CONTROL 0x1D /* D7 to D0, Read/write */ + +/* Bits and Masks */ +#define AD7280A_CTRL_HB_CONV_INPUT_ALL (0 << 6) +#define AD7280A_CTRL_HB_CONV_INPUT_6CELL_AUX1_3_4 (1 << 6) +#define AD7280A_CTRL_HB_CONV_INPUT_6CELL (2 << 6) +#define AD7280A_CTRL_HB_CONV_INPUT_SELF_TEST (3 << 6) +#define AD7280A_CTRL_HB_CONV_RES_READ_ALL (0 << 4) +#define AD7280A_CTRL_HB_CONV_RES_READ_6CELL_AUX1_3_4 (1 << 4) +#define AD7280A_CTRL_HB_CONV_RES_READ_6CELL (2 << 4) +#define AD7280A_CTRL_HB_CONV_RES_READ_NO (3 << 4) +#define AD7280A_CTRL_HB_CONV_START_CNVST (0 << 3) +#define AD7280A_CTRL_HB_CONV_START_CS (1 << 3) +#define AD7280A_CTRL_HB_CONV_AVG_DIS (0 << 1) +#define AD7280A_CTRL_HB_CONV_AVG_2 (1 << 1) +#define AD7280A_CTRL_HB_CONV_AVG_4 (2 << 1) +#define AD7280A_CTRL_HB_CONV_AVG_8 (3 << 1) +#define AD7280A_CTRL_HB_CONV_AVG(x) ((x) << 1) +#define AD7280A_CTRL_HB_PWRDN_SW (1 << 0) + +#define AD7280A_CTRL_LB_SWRST (1 << 7) +#define AD7280A_CTRL_LB_ACQ_TIME_400ns (0 << 5) +#define AD7280A_CTRL_LB_ACQ_TIME_800ns (1 << 5) +#define AD7280A_CTRL_LB_ACQ_TIME_1200ns (2 << 5) +#define AD7280A_CTRL_LB_ACQ_TIME_1600ns (3 << 5) +#define AD7280A_CTRL_LB_ACQ_TIME(x) ((x) << 5) +#define AD7280A_CTRL_LB_MUST_SET (1 << 4) +#define AD7280A_CTRL_LB_THERMISTOR_EN (1 << 3) +#define AD7280A_CTRL_LB_LOCK_DEV_ADDR (1 << 2) +#define AD7280A_CTRL_LB_INC_DEV_ADDR (1 << 1) +#define AD7280A_CTRL_LB_DAISY_CHAIN_RB_EN (1 << 0) + +#define AD7280A_ALERT_GEN_STATIC_HIGH (1 << 6) +#define AD7280A_ALERT_RELAY_SIG_CHAIN_DOWN (3 << 6) + +#define AD7280A_ALL_CELLS (0xAD << 16) + +#define AD7280A_MAX_SPI_CLK_Hz 700000 /* < 1MHz */ +#define AD7280A_MAX_CHAIN 8 +#define AD7280A_CELLS_PER_DEV 6 +#define AD7280A_BITS 12 +#define AD7280A_NUM_CH (AD7280A_AUX_ADC_6 - \ + AD7280A_CELL_VOLTAGE_1 + 1) + +#define AD7280A_DEVADDR_MASTER 0 +#define AD7280A_DEVADDR_ALL 0x1F +/* 5-bit device address is sent LSB first */ +#define AD7280A_DEVADDR(addr) (((addr & 0x1) << 4) | ((addr & 0x2) << 3) | \ + (addr & 0x4) | ((addr & 0x8) >> 3) | \ + ((addr & 0x10) >> 4)) + +/* During a read a valid write is mandatory. + * So writing to the highest available address (Address 0x1F) + * and setting the address all parts bit to 0 is recommended + * So the TXVAL is AD7280A_DEVADDR_ALL + CRC + */ +#define AD7280A_READ_TXVAL 0xF800030A + +/* + * AD7280 CRC + * + * P(x) = x^8 + x^5 + x^3 + x^2 + x^1 + x^0 = 0b100101111 => 0x2F + */ +#define POLYNOM 0x2F +#define POLYNOM_ORDER 8 +#define HIGHBIT 1 << (POLYNOM_ORDER - 1); + +struct ad7280_state { + struct spi_device *spi; + struct iio_chan_spec *channels; + struct iio_dev_attr *iio_attr; + int slave_num; + int scan_cnt; + int readback_delay_us; + unsigned char crc_tab[256]; + unsigned char ctrl_hb; + unsigned char ctrl_lb; + unsigned char cell_threshhigh; + unsigned char cell_threshlow; + unsigned char aux_threshhigh; + unsigned char aux_threshlow; + unsigned char cb_mask[AD7280A_MAX_CHAIN]; +}; + +static void ad7280_crc8_build_table(unsigned char *crc_tab) +{ + unsigned char bit, crc; + int cnt, i; + + for (cnt = 0; cnt < 256; cnt++) { + crc = cnt; + for (i = 0; i < 8; i++) { + bit = crc & HIGHBIT; + crc <<= 1; + if (bit) + crc ^= POLYNOM; + } + crc_tab[cnt] = crc; + } +} + +static unsigned char ad7280_calc_crc8(unsigned char *crc_tab, unsigned val) +{ + unsigned char crc; + + crc = crc_tab[val >> 16 & 0xFF]; + crc = crc_tab[crc ^ (val >> 8 & 0xFF)]; + + return crc ^ (val & 0xFF); +} + +static int ad7280_check_crc(struct ad7280_state *st, unsigned val) +{ + unsigned char crc = ad7280_calc_crc8(st->crc_tab, val >> 10); + + if (crc != ((val >> 2) & 0xFF)) + return -EIO; + + return 0; +} + +/* After initiating a conversion sequence we need to wait until the + * conversion is done. The delay is typically in the range of 15..30 us + * however depending an the number of devices in the daisy chain and the + * number of averages taken, conversion delays and acquisition time options + * it may take up to 250us, in this case we better sleep instead of busy + * wait. + */ + +static void ad7280_delay(struct ad7280_state *st) +{ + if (st->readback_delay_us < 50) + udelay(st->readback_delay_us); + else + msleep(1); +} + +static int __ad7280_read32(struct spi_device *spi, unsigned *val) +{ + unsigned rx_buf, tx_buf = cpu_to_be32(AD7280A_READ_TXVAL); + int ret; + + struct spi_transfer t = { + .tx_buf = &tx_buf, + .rx_buf = &rx_buf, + .len = 4, + }; + struct spi_message m; + + spi_message_init(&m); + spi_message_add_tail(&t, &m); + + ret = spi_sync(spi, &m); + if (ret) + return ret; + + *val = be32_to_cpu(rx_buf); + + return 0; +} + +static int ad7280_write(struct ad7280_state *st, unsigned devaddr, + unsigned addr, bool all, unsigned val) +{ + unsigned reg = (devaddr << 27 | addr << 21 | + (val & 0xFF) << 13 | all << 12); + + reg |= ad7280_calc_crc8(st->crc_tab, reg >> 11) << 3 | 0x2; + reg = cpu_to_be32(reg); + + return spi_write(st->spi, ®, 4); +} + +static int ad7280_read(struct ad7280_state *st, unsigned devaddr, + unsigned addr) +{ + int ret; + unsigned tmp; + + /* turns off the read operation on all parts */ + ret = ad7280_write(st, AD7280A_DEVADDR_MASTER, AD7280A_CONTROL_HB, 1, + AD7280A_CTRL_HB_CONV_INPUT_ALL | + AD7280A_CTRL_HB_CONV_RES_READ_NO | + st->ctrl_hb); + if (ret) + return ret; + + /* turns on the read operation on the addressed part */ + ret = ad7280_write(st, devaddr, AD7280A_CONTROL_HB, 0, + AD7280A_CTRL_HB_CONV_INPUT_ALL | + AD7280A_CTRL_HB_CONV_RES_READ_ALL | + st->ctrl_hb); + if (ret) + return ret; + + /* Set register address on the part to be read from */ + ret = ad7280_write(st, devaddr, AD7280A_READ, 0, addr << 2); + if (ret) + return ret; + + __ad7280_read32(st->spi, &tmp); + + if (ad7280_check_crc(st, tmp)) + return -EIO; + + if (((tmp >> 27) != devaddr) || (((tmp >> 21) & 0x3F) != addr)) + return -EFAULT; + + return (tmp >> 13) & 0xFF; +} + +static int ad7280_read_channel(struct ad7280_state *st, unsigned devaddr, + unsigned addr) +{ + int ret; + unsigned tmp; + + ret = ad7280_write(st, devaddr, AD7280A_READ, 0, addr << 2); + if (ret) + return ret; + + ret = ad7280_write(st, AD7280A_DEVADDR_MASTER, AD7280A_CONTROL_HB, 1, + AD7280A_CTRL_HB_CONV_INPUT_ALL | + AD7280A_CTRL_HB_CONV_RES_READ_NO | + st->ctrl_hb); + if (ret) + return ret; + + ret = ad7280_write(st, devaddr, AD7280A_CONTROL_HB, 0, + AD7280A_CTRL_HB_CONV_INPUT_ALL | + AD7280A_CTRL_HB_CONV_RES_READ_ALL | + AD7280A_CTRL_HB_CONV_START_CS | + st->ctrl_hb); + if (ret) + return ret; + + ad7280_delay(st); + + __ad7280_read32(st->spi, &tmp); + + if (ad7280_check_crc(st, tmp)) + return -EIO; + + if (((tmp >> 27) != devaddr) || (((tmp >> 23) & 0xF) != addr)) + return -EFAULT; + + return (tmp >> 11) & 0xFFF; +} + +static int ad7280_read_all_channels(struct ad7280_state *st, unsigned cnt, + unsigned *array) +{ + int i, ret; + unsigned tmp, sum = 0; + + ret = ad7280_write(st, AD7280A_DEVADDR_MASTER, AD7280A_READ, 1, + AD7280A_CELL_VOLTAGE_1 << 2); + if (ret) + return ret; + + ret = ad7280_write(st, AD7280A_DEVADDR_MASTER, AD7280A_CONTROL_HB, 1, + AD7280A_CTRL_HB_CONV_INPUT_ALL | + AD7280A_CTRL_HB_CONV_RES_READ_ALL | + AD7280A_CTRL_HB_CONV_START_CS | + st->ctrl_hb); + if (ret) + return ret; + + ad7280_delay(st); + + for (i = 0; i < cnt; i++) { + __ad7280_read32(st->spi, &tmp); + + if (ad7280_check_crc(st, tmp)) + return -EIO; + + if (array) + array[i] = tmp; + /* only sum cell voltages */ + if (((tmp >> 23) & 0xF) <= AD7280A_CELL_VOLTAGE_6) + sum += ((tmp >> 11) & 0xFFF); + } + + return sum; +} + +static int ad7280_chain_setup(struct ad7280_state *st) +{ + unsigned val, n; + int ret; + + ret = ad7280_write(st, AD7280A_DEVADDR_MASTER, AD7280A_CONTROL_LB, 1, + AD7280A_CTRL_LB_DAISY_CHAIN_RB_EN | + AD7280A_CTRL_LB_LOCK_DEV_ADDR | + AD7280A_CTRL_LB_MUST_SET | + AD7280A_CTRL_LB_SWRST | + st->ctrl_lb); + if (ret) + return ret; + + ret = ad7280_write(st, AD7280A_DEVADDR_MASTER, AD7280A_CONTROL_LB, 1, + AD7280A_CTRL_LB_DAISY_CHAIN_RB_EN | + AD7280A_CTRL_LB_LOCK_DEV_ADDR | + AD7280A_CTRL_LB_MUST_SET | + st->ctrl_lb); + if (ret) + return ret; + + ret = ad7280_write(st, AD7280A_DEVADDR_MASTER, AD7280A_READ, 1, + AD7280A_CONTROL_LB << 2); + if (ret) + return ret; + + for (n = 0; n <= AD7280A_MAX_CHAIN; n++) { + __ad7280_read32(st->spi, &val); + if (val == 0) + return n - 1; + + if (ad7280_check_crc(st, val)) + return -EIO; + + if (n != AD7280A_DEVADDR(val >> 27)) + return -EIO; + } + + return -EFAULT; +} + +static ssize_t ad7280_show_balance_sw(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7280_state *st = iio_priv(dev_info); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + return sprintf(buf, "%d\n", + !!(st->cb_mask[this_attr->address >> 8] & + (1 << ((this_attr->address & 0xFF) + 2)))); +} + +static ssize_t ad7280_store_balance_sw(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7280_state *st = iio_priv(dev_info); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + bool readin; + int ret; + unsigned devaddr, ch; + + ret = strtobool(buf, &readin); + if (ret) + return ret; + + devaddr = this_attr->address >> 8; + ch = this_attr->address & 0xFF; + + mutex_lock(&dev_info->mlock); + if (readin) + st->cb_mask[devaddr] |= 1 << (ch + 2); + else + st->cb_mask[devaddr] &= ~(1 << (ch + 2)); + + ret = ad7280_write(st, devaddr, AD7280A_CELL_BALANCE, + 0, st->cb_mask[devaddr]); + mutex_unlock(&dev_info->mlock); + + return ret ? ret : len; +} + +static ssize_t ad7280_show_balance_timer(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7280_state *st = iio_priv(dev_info); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int ret; + unsigned msecs; + + mutex_lock(&dev_info->mlock); + ret = ad7280_read(st, this_attr->address >> 8, + this_attr->address & 0xFF); + mutex_unlock(&dev_info->mlock); + + if (ret < 0) + return ret; + + msecs = (ret >> 3) * 71500; + + return sprintf(buf, "%d\n", msecs); +} + +static ssize_t ad7280_store_balance_timer(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7280_state *st = iio_priv(dev_info); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + long val; + int ret; + + ret = strict_strtoul(buf, 10, &val); + if (ret) + return ret; + + val /= 71500; + + if (val > 31) + return -EINVAL; + + mutex_lock(&dev_info->mlock); + ret = ad7280_write(st, this_attr->address >> 8, + this_attr->address & 0xFF, + 0, (val & 0x1F) << 3); + mutex_unlock(&dev_info->mlock); + + return ret ? ret : len; +} + +static struct attribute *ad7280_attributes[AD7280A_MAX_CHAIN * + AD7280A_CELLS_PER_DEV * 2 + 1]; + +static struct attribute_group ad7280_attrs_group = { + .attrs = ad7280_attributes, +}; + +static int ad7280_channel_init(struct ad7280_state *st) +{ + int dev, ch, cnt; + + st->channels = kzalloc(sizeof(*st->channels) * + ((st->slave_num + 1) * 12 + 2), GFP_KERNEL); + if (st->channels == NULL) + return -ENOMEM; + + for (dev = 0, cnt = 0; dev <= st->slave_num; dev++) + for (ch = AD7280A_CELL_VOLTAGE_1; ch <= AD7280A_AUX_ADC_6; ch++, + cnt++) { + if (ch < AD7280A_AUX_ADC_1) { + st->channels[cnt].type = IIO_IN_DIFF; + st->channels[cnt].channel = (dev * 6) + ch; + st->channels[cnt].channel2 = + st->channels[cnt].channel + 1; + } else { + st->channels[cnt].type = IIO_TEMP; + st->channels[cnt].channel = (dev * 6) + ch - 6; + } + st->channels[cnt].indexed = 1; + st->channels[cnt].info_mask = + (1 << IIO_CHAN_INFO_SCALE_SHARED); + st->channels[cnt].address = + AD7280A_DEVADDR(dev) << 8 | ch; + st->channels[cnt].scan_index = cnt; + st->channels[cnt].scan_type.sign = 'u'; + st->channels[cnt].scan_type.realbits = 12; + st->channels[cnt].scan_type.storagebits = 32; + st->channels[cnt].scan_type.shift = 0; + } + + st->channels[cnt].type = IIO_IN_DIFF; + st->channels[cnt].channel = 0; + st->channels[cnt].channel2 = dev * 6; + st->channels[cnt].address = AD7280A_ALL_CELLS; + st->channels[cnt].indexed = 1; + st->channels[cnt].info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED); + st->channels[cnt].scan_index = cnt; + st->channels[cnt].scan_type.sign = 'u'; + st->channels[cnt].scan_type.realbits = 32; + st->channels[cnt].scan_type.storagebits = 32; + st->channels[cnt].scan_type.shift = 0; + cnt++; + st->channels[cnt].type = IIO_TIMESTAMP; + st->channels[cnt].channel = -1; + st->channels[cnt].scan_index = cnt; + st->channels[cnt].scan_type.sign = 's'; + st->channels[cnt].scan_type.realbits = 64; + st->channels[cnt].scan_type.storagebits = 64; + st->channels[cnt].scan_type.shift = 0; + + return cnt + 1; +} + +static int ad7280_attr_init(struct ad7280_state *st) +{ + int dev, ch, cnt; + + st->iio_attr = kzalloc(sizeof(*st->iio_attr) * (st->slave_num + 1) * + AD7280A_CELLS_PER_DEV * 2, GFP_KERNEL); + if (st->iio_attr == NULL) + return -ENOMEM; + + for (dev = 0, cnt = 0; dev <= st->slave_num; dev++) + for (ch = AD7280A_CELL_VOLTAGE_1; ch <= AD7280A_CELL_VOLTAGE_6; + ch++, cnt++) { + st->iio_attr[cnt].address = + AD7280A_DEVADDR(dev) << 8 | ch; + st->iio_attr[cnt].dev_attr.attr.mode = + S_IWUSR | S_IRUGO; + st->iio_attr[cnt].dev_attr.show = + ad7280_show_balance_sw; + st->iio_attr[cnt].dev_attr.store = + ad7280_store_balance_sw; + st->iio_attr[cnt].dev_attr.attr.name = + kasprintf(GFP_KERNEL, + "in%d-in%d_balance_switch_en", + (dev * AD7280A_CELLS_PER_DEV) + ch, + (dev * AD7280A_CELLS_PER_DEV) + ch + 1); + ad7280_attributes[cnt] = + &st->iio_attr[cnt].dev_attr.attr; + cnt++; + st->iio_attr[cnt].address = + AD7280A_DEVADDR(dev) << 8 | + (AD7280A_CB1_TIMER + ch); + st->iio_attr[cnt].dev_attr.attr.mode = + S_IWUSR | S_IRUGO; + st->iio_attr[cnt].dev_attr.show = + ad7280_show_balance_timer; + st->iio_attr[cnt].dev_attr.store = + ad7280_store_balance_timer; + st->iio_attr[cnt].dev_attr.attr.name = + kasprintf(GFP_KERNEL, "in%d-in%d_balance_timer", + (dev * AD7280A_CELLS_PER_DEV) + ch, + (dev * AD7280A_CELLS_PER_DEV) + ch + 1); + ad7280_attributes[cnt] = + &st->iio_attr[cnt].dev_attr.attr; + } + + ad7280_attributes[cnt] = NULL; + + return 0; +} + +static ssize_t ad7280_read_channel_config(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7280_state *st = iio_priv(dev_info); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + unsigned val; + + switch (this_attr->address) { + case AD7280A_CELL_OVERVOLTAGE: + val = 1000 + (st->cell_threshhigh * 1568) / 100; + break; + case AD7280A_CELL_UNDERVOLTAGE: + val = 1000 + (st->cell_threshlow * 1568) / 100; + break; + case AD7280A_AUX_ADC_OVERVOLTAGE: + val = (st->aux_threshhigh * 196) / 10; + break; + case AD7280A_AUX_ADC_UNDERVOLTAGE: + val = (st->aux_threshlow * 196) / 10; + break; + default: + return -EINVAL; + } + + return sprintf(buf, "%d\n", val); +} + +static ssize_t ad7280_write_channel_config(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7280_state *st = iio_priv(dev_info); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + long val; + int ret; + + ret = strict_strtol(buf, 10, &val); + if (ret) + return ret; + + switch (this_attr->address) { + case AD7280A_CELL_OVERVOLTAGE: + case AD7280A_CELL_UNDERVOLTAGE: + val = ((val - 1000) * 100) / 1568; /* LSB 15.68mV */ + break; + case AD7280A_AUX_ADC_OVERVOLTAGE: + case AD7280A_AUX_ADC_UNDERVOLTAGE: + val = (val * 10) / 196; /* LSB 19.6mV */ + break; + default: + return -EFAULT; + } + + val = clamp(val, 0L, 0xFFL); + + mutex_lock(&dev_info->mlock); + switch (this_attr->address) { + case AD7280A_CELL_OVERVOLTAGE: + st->cell_threshhigh = val; + break; + case AD7280A_CELL_UNDERVOLTAGE: + st->cell_threshlow = val; + break; + case AD7280A_AUX_ADC_OVERVOLTAGE: + st->aux_threshhigh = val; + break; + case AD7280A_AUX_ADC_UNDERVOLTAGE: + st->aux_threshlow = val; + break; + } + + ret = ad7280_write(st, AD7280A_DEVADDR_MASTER, + this_attr->address, 1, val); + + mutex_unlock(&dev_info->mlock); + + return ret ? ret : len; +} + +static irqreturn_t ad7280_event_handler(int irq, void *private) +{ + struct iio_dev *dev_info = private; + struct ad7280_state *st = iio_priv(dev_info); + unsigned *channels; + int i, ret; + + channels = kzalloc(sizeof(*channels) * st->scan_cnt, GFP_KERNEL); + if (channels == NULL) + return IRQ_HANDLED; + + ret = ad7280_read_all_channels(st, st->scan_cnt, channels); + if (ret < 0) + return IRQ_HANDLED; + + for (i = 0; i < st->scan_cnt; i++) { + if (((channels[i] >> 23) & 0xF) <= AD7280A_CELL_VOLTAGE_6) { + if (((channels[i] >> 11) & 0xFFF) >= + st->cell_threshhigh) + iio_push_event(dev_info, 0, + IIO_UNMOD_EVENT_CODE(IIO_IN_DIFF, + 0, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_RISING), + iio_get_time_ns()); + else if (((channels[i] >> 11) & 0xFFF) <= + st->cell_threshlow) + iio_push_event(dev_info, 0, + IIO_UNMOD_EVENT_CODE(IIO_IN_DIFF, + 0, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_FALLING), + iio_get_time_ns()); + } else { + if (((channels[i] >> 11) & 0xFFF) >= st->aux_threshhigh) + iio_push_event(dev_info, 0, + IIO_UNMOD_EVENT_CODE(IIO_TEMP, + 0, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_RISING), + iio_get_time_ns()); + else if (((channels[i] >> 11) & 0xFFF) <= + st->aux_threshlow) + iio_push_event(dev_info, 0, + IIO_UNMOD_EVENT_CODE(IIO_TEMP, + 0, + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_FALLING), + iio_get_time_ns()); + } + } + + kfree(channels); + + return IRQ_HANDLED; +} + +static IIO_DEVICE_ATTR_NAMED(in_thresh_low_value, + in-in_thresh_low_value, + S_IRUGO | S_IWUSR, + ad7280_read_channel_config, + ad7280_write_channel_config, + AD7280A_CELL_UNDERVOLTAGE); + +static IIO_DEVICE_ATTR_NAMED(in_thresh_high_value, + in-in_thresh_high_value, + S_IRUGO | S_IWUSR, + ad7280_read_channel_config, + ad7280_write_channel_config, + AD7280A_CELL_OVERVOLTAGE); + +static IIO_DEVICE_ATTR(temp_thresh_low_value, + S_IRUGO | S_IWUSR, + ad7280_read_channel_config, + ad7280_write_channel_config, + AD7280A_AUX_ADC_UNDERVOLTAGE); + +static IIO_DEVICE_ATTR(temp_thresh_high_value, + S_IRUGO | S_IWUSR, + ad7280_read_channel_config, + ad7280_write_channel_config, + AD7280A_AUX_ADC_OVERVOLTAGE); + + +static struct attribute *ad7280_event_attributes[] = { + &iio_dev_attr_in_thresh_low_value.dev_attr.attr, + &iio_dev_attr_in_thresh_high_value.dev_attr.attr, + &iio_dev_attr_temp_thresh_low_value.dev_attr.attr, + &iio_dev_attr_temp_thresh_high_value.dev_attr.attr, + NULL, +}; + +static struct attribute_group ad7280_event_attrs_group = { + .attrs = ad7280_event_attributes, +}; + +static int ad7280_read_raw(struct iio_dev *dev_info, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long m) +{ + struct ad7280_state *st = iio_priv(dev_info); + unsigned int scale_uv; + int ret; + + switch (m) { + case 0: + mutex_lock(&dev_info->mlock); + if (chan->address == AD7280A_ALL_CELLS) + ret = ad7280_read_all_channels(st, st->scan_cnt, NULL); + else + ret = ad7280_read_channel(st, chan->address >> 8, + chan->address & 0xFF); + mutex_unlock(&dev_info->mlock); + + if (ret < 0) + return ret; + + *val = ret; + + return IIO_VAL_INT; + case (1 << IIO_CHAN_INFO_SCALE_SHARED): + if ((chan->address & 0xFF) <= AD7280A_CELL_VOLTAGE_6) + scale_uv = (4000 * 1000) >> AD7280A_BITS; + else + scale_uv = (5000 * 1000) >> AD7280A_BITS; + + *val = scale_uv / 1000; + *val2 = (scale_uv % 1000) * 1000; + return IIO_VAL_INT_PLUS_MICRO; + } + return -EINVAL; +} + +static const struct iio_info ad7280_info = { + .read_raw = &ad7280_read_raw, + .num_interrupt_lines = 1, + .event_attrs = &ad7280_event_attrs_group, + .attrs = &ad7280_attrs_group, + .driver_module = THIS_MODULE, +}; + +static const struct ad7280_platform_data ad7793_default_pdata = { + .acquisition_time = AD7280A_ACQ_TIME_400ns, + .conversion_averaging = AD7280A_CONV_AVG_DIS, + .thermistor_term_en = true, +}; + +static int __devinit ad7280_probe(struct spi_device *spi) +{ + const struct ad7280_platform_data *pdata = spi->dev.platform_data; + struct ad7280_state *st; + int ret, regdone = 0; + const unsigned short tACQ_ns[4] = {465, 1010, 1460, 1890}; + const unsigned short nAVG[4] = {1, 2, 4, 8}; + struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st)); + + if (indio_dev == NULL) + return -ENOMEM; + + st = iio_priv(indio_dev); + spi_set_drvdata(spi, indio_dev); + st->spi = spi; + + if (!pdata) + pdata = &ad7793_default_pdata; + + ad7280_crc8_build_table(st->crc_tab); + + st->spi->max_speed_hz = AD7280A_MAX_SPI_CLK_Hz; + st->spi->mode = SPI_MODE_1; + spi_setup(st->spi); + + st->ctrl_lb = AD7280A_CTRL_LB_ACQ_TIME(pdata->acquisition_time & 0x3); + st->ctrl_hb = AD7280A_CTRL_HB_CONV_AVG(pdata->conversion_averaging + & 0x3) | (pdata->thermistor_term_en ? + AD7280A_CTRL_LB_THERMISTOR_EN : 0); + + ret = ad7280_chain_setup(st); + if (ret < 0) + goto error_free_device; + + st->slave_num = ret; + st->scan_cnt = (st->slave_num + 1) * AD7280A_NUM_CH; + st->cell_threshhigh = 0xFF; + st->aux_threshhigh = 0xFF; + + /* + * Total Conversion Time = ((tACQ + tCONV) * + * (Number of Conversions per Part)) − + * tACQ + ((N - 1) * tDELAY) + * + * Readback Delay = Total Conversion Time + tWAIT + */ + + st->readback_delay_us = + ((tACQ_ns[pdata->acquisition_time & 0x3] + 695) * + (AD7280A_NUM_CH * nAVG[pdata->conversion_averaging & 0x3])) + - tACQ_ns[pdata->acquisition_time & 0x3] + + st->slave_num * 250; + + /* Convert to usecs */ + st->readback_delay_us = DIV_ROUND_UP(st->readback_delay_us, 1000); + st->readback_delay_us += 5; /* Add tWAIT */ + + indio_dev->name = spi_get_device_id(spi)->name; + indio_dev->dev.parent = &spi->dev; + indio_dev->modes = INDIO_DIRECT_MODE; + + ret = ad7280_channel_init(st); + if (ret < 0) + goto error_free_device; + + indio_dev->num_channels = ret; + indio_dev->channels = st->channels; + indio_dev->info = &ad7280_info; + + ret = ad7280_attr_init(st); + if (ret < 0) + goto error_free_channels; + + ret = iio_device_register(indio_dev); + if (ret) + goto error_free_attr; + regdone = 1; + + if (spi->irq > 0) { + ret = ad7280_write(st, AD7280A_DEVADDR_MASTER, + AD7280A_ALERT, 1, + AD7280A_ALERT_RELAY_SIG_CHAIN_DOWN); + if (ret) + goto error_free_attr; + + ret = ad7280_write(st, AD7280A_DEVADDR(st->slave_num), + AD7280A_ALERT, 0, + AD7280A_ALERT_GEN_STATIC_HIGH | + (pdata->chain_last_alert_ignore & 0xF)); + if (ret) + goto error_free_attr; + + ret = request_threaded_irq(spi->irq, + NULL, + ad7280_event_handler, + IRQF_TRIGGER_FALLING | + IRQF_ONESHOT, + indio_dev->name, + indio_dev); + if (ret) + goto error_free_attr; + } + + return 0; + +error_free_attr: + kfree(st->iio_attr); + +error_free_channels: + kfree(st->channels); + +error_free_device: + if (regdone) + iio_device_unregister(indio_dev); + else + iio_free_device(indio_dev); + + return ret; +} + +static int __devexit ad7280_remove(struct spi_device *spi) +{ + struct iio_dev *indio_dev = spi_get_drvdata(spi); + struct ad7280_state *st = iio_priv(indio_dev); + + if (spi->irq > 0) + free_irq(spi->irq, indio_dev); + + ad7280_write(st, AD7280A_DEVADDR_MASTER, AD7280A_CONTROL_HB, 1, + AD7280A_CTRL_HB_PWRDN_SW | st->ctrl_hb); + + kfree(st->channels); + kfree(st->iio_attr); + iio_device_unregister(indio_dev); + + return 0; +} + +static const struct spi_device_id ad7280_id[] = { + {"ad7280a", 0}, + {} +}; + +static struct spi_driver ad7280_driver = { + .driver = { + .name = "ad7280", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + .probe = ad7280_probe, + .remove = __devexit_p(ad7280_remove), + .id_table = ad7280_id, +}; + +static int __init ad7280_init(void) +{ + return spi_register_driver(&ad7280_driver); +} +module_init(ad7280_init); + +static void __exit ad7280_exit(void) +{ + spi_unregister_driver(&ad7280_driver); +} +module_exit(ad7280_exit); + +MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); +MODULE_DESCRIPTION("Analog Devices AD7280A"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/adc/ad7280a.h b/drivers/staging/iio/adc/ad7280a.h new file mode 100644 index 0000000..20400b0 --- /dev/null +++ b/drivers/staging/iio/adc/ad7280a.h @@ -0,0 +1,38 @@ +/* + * AD7280A Lithium Ion Battery Monitoring System + * + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#ifndef IIO_ADC_AD7280_H_ +#define IIO_ADC_AD7280_H_ + +/* + * TODO: struct ad7280_platform_data needs to go into include/linux/iio + */ + +#define AD7280A_ACQ_TIME_400ns 0 +#define AD7280A_ACQ_TIME_800ns 1 +#define AD7280A_ACQ_TIME_1200ns 2 +#define AD7280A_ACQ_TIME_1600ns 3 + +#define AD7280A_CONV_AVG_DIS 0 +#define AD7280A_CONV_AVG_2 1 +#define AD7280A_CONV_AVG_4 2 +#define AD7280A_CONV_AVG_8 3 + +#define AD7280A_ALERT_REMOVE_VIN5 (1 << 2) +#define AD7280A_ALERT_REMOVE_VIN4_VIN5 (2 << 2) +#define AD7280A_ALERT_REMOVE_AUX5 (1 << 0) +#define AD7280A_ALERT_REMOVE_AUX4_AUX5 (2 << 0) + +struct ad7280_platform_data { + unsigned acquisition_time; + unsigned conversion_averaging; + unsigned chain_last_alert_ignore; + bool thermistor_term_en; +}; + +#endif /* IIO_ADC_AD7280_H_ */ diff --git a/drivers/staging/iio/adc/ad7291.c b/drivers/staging/iio/adc/ad7291.c index 96cbb17..e884c78 100644 --- a/drivers/staging/iio/adc/ad7291.c +++ b/drivers/staging/iio/adc/ad7291.c @@ -14,6 +14,7 @@ #include <linux/sysfs.h> #include <linux/list.h> #include <linux/i2c.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" diff --git a/drivers/staging/iio/adc/ad7298_core.c b/drivers/staging/iio/adc/ad7298_core.c index b8e4ae2..3e5bead 100644 --- a/drivers/staging/iio/adc/ad7298_core.c +++ b/drivers/staging/iio/adc/ad7298_core.c @@ -14,11 +14,11 @@ #include <linux/regulator/consumer.h> #include <linux/err.h> #include <linux/delay.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" #include "../ring_generic.h" -#include "adc.h" #include "ad7298.h" diff --git a/drivers/staging/iio/adc/ad7298_ring.c b/drivers/staging/iio/adc/ad7298_ring.c index a04c033..741818c 100644 --- a/drivers/staging/iio/adc/ad7298_ring.c +++ b/drivers/staging/iio/adc/ad7298_ring.c @@ -7,17 +7,14 @@ */ #include <linux/interrupt.h> -#include <linux/device.h> #include <linux/kernel.h> #include <linux/slab.h> -#include <linux/sysfs.h> #include <linux/spi/spi.h> #include "../iio.h" #include "../ring_generic.h" #include "../ring_sw.h" -#include "../trigger.h" -#include "../sysfs.h" +#include "../trigger_consumer.h" #include "ad7298.h" @@ -120,7 +117,7 @@ static int ad7298_ring_preenable(struct iio_dev *indio_dev) static irqreturn_t ad7298_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->private_data; + struct iio_dev *indio_dev = pf->indio_dev; struct ad7298_state *st = iio_priv(indio_dev); struct iio_ring_buffer *ring = indio_dev->ring; s64 time_ns; @@ -192,11 +189,6 @@ error_ret: void ad7298_ring_cleanup(struct iio_dev *indio_dev) { - if (indio_dev->trig) { - iio_put_trigger(indio_dev->trig); - iio_trigger_dettach_poll_func(indio_dev->trig, - indio_dev->pollfunc); - } iio_dealloc_pollfunc(indio_dev->pollfunc); iio_sw_rb_free(indio_dev->ring); } diff --git a/drivers/staging/iio/adc/ad7314.c b/drivers/staging/iio/adc/ad7314.c index 9070d9c..e3d38db 100644 --- a/drivers/staging/iio/adc/ad7314.c +++ b/drivers/staging/iio/adc/ad7314.c @@ -11,6 +11,7 @@ #include <linux/slab.h> #include <linux/sysfs.h> #include <linux/spi/spi.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" diff --git a/drivers/staging/iio/adc/ad7476_core.c b/drivers/staging/iio/adc/ad7476_core.c index c210898..bb8be5d 100644 --- a/drivers/staging/iio/adc/ad7476_core.c +++ b/drivers/staging/iio/adc/ad7476_core.c @@ -13,11 +13,11 @@ #include <linux/spi/spi.h> #include <linux/regulator/consumer.h> #include <linux/err.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" #include "../ring_generic.h" -#include "adc.h" #include "ad7476.h" diff --git a/drivers/staging/iio/adc/ad7476_ring.c b/drivers/staging/iio/adc/ad7476_ring.c index a92fc5a..b109afb 100644 --- a/drivers/staging/iio/adc/ad7476_ring.c +++ b/drivers/staging/iio/adc/ad7476_ring.c @@ -11,14 +11,12 @@ #include <linux/device.h> #include <linux/kernel.h> #include <linux/slab.h> -#include <linux/sysfs.h> #include <linux/spi/spi.h> #include "../iio.h" #include "../ring_generic.h" #include "../ring_sw.h" -#include "../trigger.h" -#include "../sysfs.h" +#include "../trigger_consumer.h" #include "ad7476.h" @@ -78,7 +76,7 @@ static int ad7476_ring_preenable(struct iio_dev *indio_dev) static irqreturn_t ad7476_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->private_data; + struct iio_dev *indio_dev = pf->indio_dev; struct ad7476_state *st = iio_priv(indio_dev); s64 time_ns; __u8 *rxbuf; @@ -154,12 +152,6 @@ error_ret: void ad7476_ring_cleanup(struct iio_dev *indio_dev) { - /* ensure that the trigger has been detached */ - if (indio_dev->trig) { - iio_put_trigger(indio_dev->trig); - iio_trigger_dettach_poll_func(indio_dev->trig, - indio_dev->pollfunc); - } iio_dealloc_pollfunc(indio_dev->pollfunc); iio_sw_rb_free(indio_dev->ring); } diff --git a/drivers/staging/iio/adc/ad7606_core.c b/drivers/staging/iio/adc/ad7606_core.c index 459371a..ef05581 100644 --- a/drivers/staging/iio/adc/ad7606_core.c +++ b/drivers/staging/iio/adc/ad7606_core.c @@ -16,11 +16,11 @@ #include <linux/gpio.h> #include <linux/delay.h> #include <linux/sched.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" #include "../ring_generic.h" -#include "adc.h" #include "ad7606.h" diff --git a/drivers/staging/iio/adc/ad7606_ring.c b/drivers/staging/iio/adc/ad7606_ring.c index a199bf4..e642430 100644 --- a/drivers/staging/iio/adc/ad7606_ring.c +++ b/drivers/staging/iio/adc/ad7606_ring.c @@ -10,13 +10,11 @@ #include <linux/device.h> #include <linux/kernel.h> #include <linux/slab.h> -#include <linux/sysfs.h> #include "../iio.h" #include "../ring_generic.h" #include "../ring_sw.h" -#include "../trigger.h" -#include "../sysfs.h" +#include "../trigger_consumer.h" #include "ad7606.h" @@ -82,8 +80,7 @@ static int ad7606_ring_preenable(struct iio_dev *indio_dev) static irqreturn_t ad7606_trigger_handler_th_bh(int irq, void *p) { struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->private_data; - struct ad7606_state *st = iio_priv(indio_dev); + struct ad7606_state *st = iio_priv(pf->indio_dev); gpio_set_value(st->pdata->gpio_convst, 1); @@ -200,11 +197,6 @@ error_ret: void ad7606_ring_cleanup(struct iio_dev *indio_dev) { - if (indio_dev->trig) { - iio_put_trigger(indio_dev->trig); - iio_trigger_dettach_poll_func(indio_dev->trig, - indio_dev->pollfunc); - } iio_dealloc_pollfunc(indio_dev->pollfunc); iio_sw_rb_free(indio_dev->ring); } diff --git a/drivers/staging/iio/adc/ad7745.c b/drivers/staging/iio/adc/ad7745.c index 4c13f26..91d598c 100644 --- a/drivers/staging/iio/adc/ad7745.c +++ b/drivers/staging/iio/adc/ad7745.c @@ -14,6 +14,7 @@ #include <linux/sysfs.h> #include <linux/list.h> #include <linux/i2c.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" diff --git a/drivers/staging/iio/adc/ad7780.c b/drivers/staging/iio/adc/ad7780.c index e0c7b6c..46d1f8f 100644 --- a/drivers/staging/iio/adc/ad7780.c +++ b/drivers/staging/iio/adc/ad7780.c @@ -16,11 +16,11 @@ #include <linux/err.h> #include <linux/sched.h> #include <linux/gpio.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" #include "../ring_generic.h" -#include "adc.h" #include "ad7780.h" diff --git a/drivers/staging/iio/adc/ad7793.c b/drivers/staging/iio/adc/ad7793.c index 90f6c03..1bcb3eb 100644 --- a/drivers/staging/iio/adc/ad7793.c +++ b/drivers/staging/iio/adc/ad7793.c @@ -22,7 +22,7 @@ #include "../ring_generic.h" #include "../ring_sw.h" #include "../trigger.h" -#include "adc.h" +#include "../trigger_consumer.h" #include "ad7793.h" @@ -402,7 +402,7 @@ static int ad7793_ring_postdisable(struct iio_dev *indio_dev) static irqreturn_t ad7793_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->private_data; + struct iio_dev *indio_dev = pf->indio_dev; struct iio_ring_buffer *ring = indio_dev->ring; struct ad7793_state *st = iio_priv(indio_dev); s64 dat64[2]; @@ -470,12 +470,6 @@ error_ret: static void ad7793_ring_cleanup(struct iio_dev *indio_dev) { - /* ensure that the trigger has been detached */ - if (indio_dev->trig) { - iio_put_trigger(indio_dev->trig); - iio_trigger_dettach_poll_func(indio_dev->trig, - indio_dev->pollfunc); - } iio_dealloc_pollfunc(indio_dev->pollfunc); iio_sw_rb_free(indio_dev->ring); } diff --git a/drivers/staging/iio/adc/ad7816.c b/drivers/staging/iio/adc/ad7816.c index 0c84217..f5aa57b 100644 --- a/drivers/staging/iio/adc/ad7816.c +++ b/drivers/staging/iio/adc/ad7816.c @@ -14,6 +14,7 @@ #include <linux/sysfs.h> #include <linux/list.h> #include <linux/spi/spi.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" @@ -246,7 +247,7 @@ static const struct attribute_group ad7816_attribute_group = { * temperature bound events */ -#define IIO_EVENT_CODE_AD7816_OTI IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_TEMP, \ +#define IIO_EVENT_CODE_AD7816_OTI IIO_UNMOD_EVENT_CODE(IIO_TEMP, \ 0, \ IIO_EV_TYPE_THRESH, \ IIO_EV_DIR_FALLING) diff --git a/drivers/staging/iio/adc/ad7887_core.c b/drivers/staging/iio/adc/ad7887_core.c index 3d9121e..74e222f 100644 --- a/drivers/staging/iio/adc/ad7887_core.c +++ b/drivers/staging/iio/adc/ad7887_core.c @@ -13,11 +13,12 @@ #include <linux/spi/spi.h> #include <linux/regulator/consumer.h> #include <linux/err.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" #include "../ring_generic.h" -#include "adc.h" + #include "ad7887.h" diff --git a/drivers/staging/iio/adc/ad7887_ring.c b/drivers/staging/iio/adc/ad7887_ring.c index 0ac7c0b..6b3daf4 100644 --- a/drivers/staging/iio/adc/ad7887_ring.c +++ b/drivers/staging/iio/adc/ad7887_ring.c @@ -8,17 +8,14 @@ */ #include <linux/interrupt.h> -#include <linux/device.h> #include <linux/kernel.h> #include <linux/slab.h> -#include <linux/sysfs.h> #include <linux/spi/spi.h> #include "../iio.h" #include "../ring_generic.h" #include "../ring_sw.h" -#include "../trigger.h" -#include "../sysfs.h" +#include "../trigger_consumer.h" #include "ad7887.h" @@ -115,7 +112,7 @@ static int ad7887_ring_postdisable(struct iio_dev *indio_dev) static irqreturn_t ad7887_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->private_data; + struct iio_dev *indio_dev = pf->indio_dev; struct ad7887_state *st = iio_priv(indio_dev); struct iio_ring_buffer *ring = indio_dev->ring; s64 time_ns; @@ -191,12 +188,6 @@ error_ret: void ad7887_ring_cleanup(struct iio_dev *indio_dev) { - /* ensure that the trigger has been detached */ - if (indio_dev->trig) { - iio_put_trigger(indio_dev->trig); - iio_trigger_dettach_poll_func(indio_dev->trig, - indio_dev->pollfunc); - } iio_dealloc_pollfunc(indio_dev->pollfunc); iio_sw_rb_free(indio_dev->ring); } diff --git a/drivers/staging/iio/adc/ad799x_core.c b/drivers/staging/iio/adc/ad799x_core.c index 92cfe2e..33e4e21 100644 --- a/drivers/staging/iio/adc/ad799x_core.c +++ b/drivers/staging/iio/adc/ad799x_core.c @@ -31,12 +31,12 @@ #include <linux/slab.h> #include <linux/types.h> #include <linux/err.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" - #include "../ring_generic.h" -#include "adc.h" + #include "ad799x.h" /* @@ -336,8 +336,14 @@ static irqreturn_t ad799x_event_handler(int irq, void *private) if (status & (1 << i)) iio_push_event(indio_dev, 0, i & 0x1 ? - IIO_EVENT_CODE_IN_HIGH_THRESH(i >> 1) : - IIO_EVENT_CODE_IN_LOW_THRESH(i >> 1), + IIO_UNMOD_EVENT_CODE(IIO_IN, + (i >> 1), + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_RISING) : + IIO_UNMOD_EVENT_CODE(IIO_IN, + (i >> 1), + IIO_EV_TYPE_THRESH, + IIO_EV_DIR_FALLING), iio_get_time_ns()); } diff --git a/drivers/staging/iio/adc/ad799x_ring.c b/drivers/staging/iio/adc/ad799x_ring.c index 0376a82..8f1fc52 100644 --- a/drivers/staging/iio/adc/ad799x_ring.c +++ b/drivers/staging/iio/adc/ad799x_ring.c @@ -10,10 +10,8 @@ */ #include <linux/interrupt.h> -#include <linux/device.h> #include <linux/slab.h> #include <linux/kernel.h> -#include <linux/sysfs.h> #include <linux/list.h> #include <linux/i2c.h> #include <linux/bitops.h> @@ -21,8 +19,7 @@ #include "../iio.h" #include "../ring_generic.h" #include "../ring_sw.h" -#include "../trigger.h" -#include "../sysfs.h" +#include "../trigger_consumer.h" #include "ad799x.h" @@ -108,7 +105,7 @@ static int ad799x_ring_preenable(struct iio_dev *indio_dev) static irqreturn_t ad799x_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->private_data; + struct iio_dev *indio_dev = pf->indio_dev; struct ad799x_state *st = iio_priv(indio_dev); struct iio_ring_buffer *ring = indio_dev->ring; s64 time_ns; @@ -207,12 +204,6 @@ error_ret: void ad799x_ring_cleanup(struct iio_dev *indio_dev) { - /* ensure that the trigger has been detached */ - if (indio_dev->trig) { - iio_put_trigger(indio_dev->trig); - iio_trigger_dettach_poll_func(indio_dev->trig, - indio_dev->pollfunc); - } iio_dealloc_pollfunc(indio_dev->pollfunc); iio_sw_rb_free(indio_dev->ring); } diff --git a/drivers/staging/iio/adc/adc.h b/drivers/staging/iio/adc/adc.h deleted file mode 100644 index 40c5949..0000000 --- a/drivers/staging/iio/adc/adc.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * adc.h - sysfs attributes associated with ADCs - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * Copyright (c) 2008 Jonathan Cameron <jic23@cam.ac.uk> - * - */ - -/* Deprecated */ -#define IIO_DEV_ATTR_ADC(_num, _show, _addr) \ - IIO_DEVICE_ATTR(adc_##_num, S_IRUGO, _show, NULL, _addr) - -#define IIO_DEV_ATTR_IN_RAW(_num, _show, _addr) \ - IIO_DEVICE_ATTR(in##_num##_raw, S_IRUGO, _show, NULL, _addr) - -#define IIO_DEV_ATTR_IN_NAMED_RAW(_num, _name, _show, _addr) \ - IIO_DEVICE_ATTR(in##_num##_##_name##_raw, S_IRUGO, _show, NULL, _addr) - -#define IIO_DEV_ATTR_IN_DIFF_RAW(_nump, _numn, _show, _addr) \ - IIO_DEVICE_ATTR_NAMED(in##_nump##min##_numn##_raw, \ - in##_nump-in##_numn##_raw, \ - S_IRUGO, \ - _show, \ - NULL, \ - _addr) - - -#define IIO_CONST_ATTR_IN_NAMED_OFFSET(_num, _name, _string) \ - IIO_CONST_ATTR(in##_num##_##_name##_offset, _string) - -#define IIO_CONST_ATTR_IN_NAMED_SCALE(_num, _name, _string) \ - IIO_CONST_ATTR(in##_num##_##_name##_scale, _string) - -#define IIO_EVENT_CODE_IN_HIGH_THRESH(a) \ - IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_IN, a, IIO_EV_TYPE_THRESH, \ - IIO_EV_DIR_RISING) -#define IIO_EVENT_CODE_IN_LOW_THRESH(a) \ - IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_IN, a, IIO_EV_TYPE_THRESH, \ - IIO_EV_DIR_FALLING) diff --git a/drivers/staging/iio/adc/adt7310.c b/drivers/staging/iio/adc/adt7310.c index 1a41b80..697ad1b 100644 --- a/drivers/staging/iio/adc/adt7310.c +++ b/drivers/staging/iio/adc/adt7310.c @@ -13,6 +13,7 @@ #include <linux/sysfs.h> #include <linux/list.h> #include <linux/spi/spi.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" diff --git a/drivers/staging/iio/adc/adt7410.c b/drivers/staging/iio/adc/adt7410.c index 76aa063..b7631f1 100644 --- a/drivers/staging/iio/adc/adt7410.c +++ b/drivers/staging/iio/adc/adt7410.c @@ -13,6 +13,7 @@ #include <linux/sysfs.h> #include <linux/list.h> #include <linux/i2c.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" diff --git a/drivers/staging/iio/adc/adt75.c b/drivers/staging/iio/adc/adt75.c index 38f141d..dd78277 100644 --- a/drivers/staging/iio/adc/adt75.c +++ b/drivers/staging/iio/adc/adt75.c @@ -12,6 +12,7 @@ #include <linux/slab.h> #include <linux/sysfs.h> #include <linux/i2c.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" @@ -257,7 +258,7 @@ static const struct attribute_group adt75_attribute_group = { * temperature bound events */ -#define IIO_EVENT_CODE_ADT75_OTI IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_TEMP, \ +#define IIO_EVENT_CODE_ADT75_OTI IIO_UNMOD_EVENT_CODE(IIO_TEMP, \ 0, \ IIO_EV_TYPE_THRESH, \ IIO_EV_DIR_FALLING) diff --git a/drivers/staging/iio/adc/max1363_core.c b/drivers/staging/iio/adc/max1363_core.c index 72b0917..e10a4d8 100644 --- a/drivers/staging/iio/adc/max1363_core.c +++ b/drivers/staging/iio/adc/max1363_core.c @@ -30,12 +30,12 @@ #include <linux/regulator/consumer.h> #include <linux/slab.h> #include <linux/err.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" - #include "../ring_generic.h" -#include "adc.h" + #include "max1363.h" #define MAX1363_MODE_SINGLE(_num, _mask) { \ @@ -255,7 +255,7 @@ static int max1363_read_raw(struct iio_dev *indio_dev, switch (m) { case 0: ret = max1363_read_single_chan(indio_dev, chan, val, m); - if (ret) + if (ret < 0) return ret; return IIO_VAL_INT; case (1 << IIO_CHAN_INFO_SCALE_SHARED): @@ -592,10 +592,14 @@ static int max1363_write_thresh(struct iio_dev *indio_dev, } static const int max1363_event_codes[] = { - IIO_EVENT_CODE_IN_LOW_THRESH(3), IIO_EVENT_CODE_IN_HIGH_THRESH(3), - IIO_EVENT_CODE_IN_LOW_THRESH(2), IIO_EVENT_CODE_IN_HIGH_THRESH(2), - IIO_EVENT_CODE_IN_LOW_THRESH(1), IIO_EVENT_CODE_IN_HIGH_THRESH(1), - IIO_EVENT_CODE_IN_LOW_THRESH(0), IIO_EVENT_CODE_IN_HIGH_THRESH(0) + IIO_UNMOD_EVENT_CODE(IIO_IN, 0, IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), + IIO_UNMOD_EVENT_CODE(IIO_IN, 1, IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), + IIO_UNMOD_EVENT_CODE(IIO_IN, 2, IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), + IIO_UNMOD_EVENT_CODE(IIO_IN, 3, IIO_EV_TYPE_THRESH, IIO_EV_DIR_FALLING), + IIO_UNMOD_EVENT_CODE(IIO_IN, 0, IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), + IIO_UNMOD_EVENT_CODE(IIO_IN, 1, IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), + IIO_UNMOD_EVENT_CODE(IIO_IN, 2, IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), + IIO_UNMOD_EVENT_CODE(IIO_IN, 3, IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), }; static irqreturn_t max1363_event_handler(int irq, void *private) @@ -1295,6 +1299,8 @@ static int __devinit max1363_probe(struct i2c_client *client, indio_dev->info = st->chip_info->info; indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = st->chip_info->channels; + indio_dev->num_channels = st->chip_info->num_channels; ret = max1363_initial_setup(st); if (ret < 0) goto error_free_available_scan_masks; diff --git a/drivers/staging/iio/adc/max1363_ring.c b/drivers/staging/iio/adc/max1363_ring.c index f43befd..be601e0 100644 --- a/drivers/staging/iio/adc/max1363_ring.c +++ b/drivers/staging/iio/adc/max1363_ring.c @@ -9,19 +9,15 @@ */ #include <linux/interrupt.h> -#include <linux/device.h> #include <linux/slab.h> #include <linux/kernel.h> -#include <linux/sysfs.h> -#include <linux/list.h> #include <linux/i2c.h> #include <linux/bitops.h> #include "../iio.h" #include "../ring_generic.h" #include "../ring_sw.h" -#include "../trigger.h" -#include "../sysfs.h" +#include "../trigger_consumer.h" #include "max1363.h" @@ -108,7 +104,7 @@ static int max1363_ring_preenable(struct iio_dev *indio_dev) static irqreturn_t max1363_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->private_data; + struct iio_dev *indio_dev = pf->indio_dev; struct max1363_state *st = iio_priv(indio_dev); s64 time_ns; __u8 *rxbuf; @@ -199,11 +195,6 @@ error_ret: void max1363_ring_cleanup(struct iio_dev *indio_dev) { /* ensure that the trigger has been detached */ - if (indio_dev->trig) { - iio_put_trigger(indio_dev->trig); - iio_trigger_dettach_poll_func(indio_dev->trig, - indio_dev->pollfunc); - } iio_dealloc_pollfunc(indio_dev->pollfunc); iio_sw_rb_free(indio_dev->ring); } diff --git a/drivers/staging/iio/addac/adt7316-i2c.c b/drivers/staging/iio/addac/adt7316-i2c.c index 52d1ea3..69fab53 100644 --- a/drivers/staging/iio/addac/adt7316-i2c.c +++ b/drivers/staging/iio/addac/adt7316-i2c.c @@ -11,6 +11,7 @@ #include <linux/kernel.h> #include <linux/i2c.h> #include <linux/interrupt.h> +#include <linux/module.h> #include "adt7316.h" diff --git a/drivers/staging/iio/addac/adt7316.c b/drivers/staging/iio/addac/adt7316.c index 637316f..474d946 100644 --- a/drivers/staging/iio/addac/adt7316.c +++ b/drivers/staging/iio/addac/adt7316.c @@ -17,6 +17,7 @@ #include <linux/list.h> #include <linux/i2c.h> #include <linux/rtc.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" @@ -203,7 +204,7 @@ struct adt7316_chip_info { #define ADT7316_TEMP_INT_MASK 0x1F #define ADT7516_AIN_INT_MASK 0xE0 #define ADT7316_TEMP_AIN_INT_MASK \ - (ADT7316_TEMP_INT_MASK | ADT7316_TEMP_INT_MASK) + (ADT7316_TEMP_INT_MASK) /* * struct adt7316_chip_info - chip specifc information diff --git a/drivers/staging/iio/dac/ad5446.c b/drivers/staging/iio/dac/ad5446.c index e8a9d0b..c670fb9 100644 --- a/drivers/staging/iio/dac/ad5446.c +++ b/drivers/staging/iio/dac/ad5446.c @@ -16,6 +16,7 @@ #include <linux/spi/spi.h> #include <linux/regulator/consumer.h> #include <linux/err.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" diff --git a/drivers/staging/iio/dac/ad5504.c b/drivers/staging/iio/dac/ad5504.c index 1915f45..5243ef9 100644 --- a/drivers/staging/iio/dac/ad5504.c +++ b/drivers/staging/iio/dac/ad5504.c @@ -15,6 +15,7 @@ #include <linux/slab.h> #include <linux/sysfs.h> #include <linux/regulator/consumer.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" @@ -251,7 +252,7 @@ static struct attribute_group ad5504_ev_attribute_group = { static irqreturn_t ad5504_event_handler(int irq, void *private) { iio_push_event(private, 0, - IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_TEMP, + IIO_UNMOD_EVENT_CODE(IIO_TEMP, 0, IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), @@ -338,7 +339,7 @@ error_free_dev: iio_free_device(indio_dev); error_disable_reg: if (!IS_ERR(reg)) - regulator_disable(st->reg); + regulator_disable(reg); error_put_reg: if (!IS_ERR(reg)) regulator_put(reg); diff --git a/drivers/staging/iio/dac/ad5624r_spi.c b/drivers/staging/iio/dac/ad5624r_spi.c index a5b3776..7303bb1 100644 --- a/drivers/staging/iio/dac/ad5624r_spi.c +++ b/drivers/staging/iio/dac/ad5624r_spi.c @@ -15,6 +15,7 @@ #include <linux/slab.h> #include <linux/sysfs.h> #include <linux/regulator/consumer.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" diff --git a/drivers/staging/iio/dac/ad5686.c b/drivers/staging/iio/dac/ad5686.c index fd67cfa..ae71d3f 100644 --- a/drivers/staging/iio/dac/ad5686.c +++ b/drivers/staging/iio/dac/ad5686.c @@ -10,6 +10,7 @@ #include <linux/gpio.h> #include <linux/fs.h> #include <linux/device.h> +#include <linux/module.h> #include <linux/kernel.h> #include <linux/spi/spi.h> #include <linux/slab.h> diff --git a/drivers/staging/iio/dac/ad5791.c b/drivers/staging/iio/dac/ad5791.c index 64770d2..5c45d0f 100644 --- a/drivers/staging/iio/dac/ad5791.c +++ b/drivers/staging/iio/dac/ad5791.c @@ -15,6 +15,7 @@ #include <linux/slab.h> #include <linux/sysfs.h> #include <linux/regulator/consumer.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" @@ -381,7 +382,6 @@ error_put_reg_pos: if (!IS_ERR(reg_vdd)) regulator_put(reg_vdd); -error_ret: return ret; } diff --git a/drivers/staging/iio/dds/ad5930.c b/drivers/staging/iio/dds/ad5930.c index 0b2aa4c..4847ea2 100644 --- a/drivers/staging/iio/dds/ad5930.c +++ b/drivers/staging/iio/dds/ad5930.c @@ -14,6 +14,7 @@ #include <linux/spi/spi.h> #include <linux/slab.h> #include <linux/sysfs.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" diff --git a/drivers/staging/iio/dds/ad9832.c b/drivers/staging/iio/dds/ad9832.c index e3e61a4..e6cfa64 100644 --- a/drivers/staging/iio/dds/ad9832.c +++ b/drivers/staging/iio/dds/ad9832.c @@ -13,6 +13,7 @@ #include <linux/spi/spi.h> #include <linux/regulator/consumer.h> #include <linux/err.h> +#include <linux/module.h> #include <asm/div64.h> #include "../iio.h" diff --git a/drivers/staging/iio/dds/ad9834.c b/drivers/staging/iio/dds/ad9834.c index e6454d5..a5b5aed 100644 --- a/drivers/staging/iio/dds/ad9834.c +++ b/drivers/staging/iio/dds/ad9834.c @@ -16,6 +16,7 @@ #include <linux/spi/spi.h> #include <linux/regulator/consumer.h> #include <linux/err.h> +#include <linux/module.h> #include <asm/div64.h> #include "../iio.h" diff --git a/drivers/staging/iio/dds/ad9850.c b/drivers/staging/iio/dds/ad9850.c index d7c9d05..7f2dd47 100644 --- a/drivers/staging/iio/dds/ad9850.c +++ b/drivers/staging/iio/dds/ad9850.c @@ -14,6 +14,7 @@ #include <linux/spi/spi.h> #include <linux/slab.h> #include <linux/sysfs.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" diff --git a/drivers/staging/iio/dds/ad9852.c b/drivers/staging/iio/dds/ad9852.c index 0184585..7f65b92 100644 --- a/drivers/staging/iio/dds/ad9852.c +++ b/drivers/staging/iio/dds/ad9852.c @@ -14,6 +14,7 @@ #include <linux/spi/spi.h> #include <linux/slab.h> #include <linux/sysfs.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" @@ -217,7 +218,6 @@ static struct attribute *ad9852_attributes[] = { }; static const struct attribute_group ad9852_attribute_group = { - .name = DRV_NAME, .attrs = ad9852_attributes, }; diff --git a/drivers/staging/iio/dds/ad9910.c b/drivers/staging/iio/dds/ad9910.c index 0fa217f..b72df8c 100644 --- a/drivers/staging/iio/dds/ad9910.c +++ b/drivers/staging/iio/dds/ad9910.c @@ -14,6 +14,7 @@ #include <linux/spi/spi.h> #include <linux/slab.h> #include <linux/sysfs.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" @@ -352,7 +353,6 @@ static struct attribute *ad9910_attributes[] = { }; static const struct attribute_group ad9910_attribute_group = { - .name = DRV_NAME, .attrs = ad9910_attributes, }; diff --git a/drivers/staging/iio/dds/ad9951.c b/drivers/staging/iio/dds/ad9951.c index d361d1f..3d478e7 100644 --- a/drivers/staging/iio/dds/ad9951.c +++ b/drivers/staging/iio/dds/ad9951.c @@ -14,6 +14,7 @@ #include <linux/spi/spi.h> #include <linux/slab.h> #include <linux/sysfs.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" @@ -161,7 +162,6 @@ static struct attribute *ad9951_attributes[] = { }; static const struct attribute_group ad9951_attribute_group = { - .name = DRV_NAME, .attrs = ad9951_attributes, }; diff --git a/drivers/staging/iio/gyro/adis16060_core.c b/drivers/staging/iio/gyro/adis16060_core.c index afa52d1..3f50873 100644 --- a/drivers/staging/iio/gyro/adis16060_core.c +++ b/drivers/staging/iio/gyro/adis16060_core.c @@ -13,12 +13,10 @@ #include <linux/spi/spi.h> #include <linux/slab.h> #include <linux/sysfs.h> - +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" -#include "gyro.h" -#include "../adc/adc.h" #define ADIS16060_GYRO 0x20 /* Measure Angular Rate (Gyro) */ #define ADIS16060_TEMP_OUT 0x10 /* Measure Temperature */ @@ -42,11 +40,9 @@ struct adis16060_state { static struct iio_dev *adis16060_iio_dev; -static int adis16060_spi_write(struct device *dev, - u8 val) +static int adis16060_spi_write(struct iio_dev *indio_dev, u8 val) { int ret; - struct iio_dev *indio_dev = dev_get_drvdata(dev); struct adis16060_state *st = iio_priv(indio_dev); mutex_lock(&st->buf_lock); @@ -57,11 +53,9 @@ static int adis16060_spi_write(struct device *dev, return ret; } -static int adis16060_spi_read(struct device *dev, - u16 *val) +static int adis16060_spi_read(struct iio_dev *indio_dev, u16 *val) { int ret; - struct iio_dev *indio_dev = dev_get_drvdata(dev); struct adis16060_state *st = iio_priv(indio_dev); mutex_lock(&st->buf_lock); @@ -82,60 +76,71 @@ static int adis16060_spi_read(struct device *dev, return ret; } -static ssize_t adis16060_read(struct device *dev, - struct device_attribute *attr, - char *buf) +static int adis16060_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, + long mask) { - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - struct iio_dev *indio_dev = dev_get_drvdata(dev); - u16 val = 0; - ssize_t ret; - - /* Take the iio_dev status lock */ - mutex_lock(&indio_dev->mlock); + u16 tval = 0; + int ret; - ret = adis16060_spi_write(dev, this_attr->address); - if (ret < 0) - goto error_ret; - ret = adis16060_spi_read(dev, &val); -error_ret: - mutex_unlock(&indio_dev->mlock); + switch (mask) { + case 0: + /* Take the iio_dev status lock */ + mutex_lock(&indio_dev->mlock); + ret = adis16060_spi_write(indio_dev, chan->address); + if (ret < 0) { + mutex_unlock(&indio_dev->mlock); + return ret; + } + ret = adis16060_spi_read(indio_dev, &tval); + mutex_unlock(&indio_dev->mlock); + *val = tval; + return IIO_VAL_INT; + case (1 << IIO_CHAN_INFO_OFFSET_SEPARATE): + *val = -7; + *val2 = 461117; + return IIO_VAL_INT_PLUS_MICRO; + case (1 << IIO_CHAN_INFO_SCALE_SEPARATE): + *val = 0; + *val2 = 34000; + return IIO_VAL_INT_PLUS_MICRO; + } - if (ret == 0) - return sprintf(buf, "%d\n", val); - else - return ret; + return -EINVAL; } -static IIO_DEV_ATTR_GYRO_Z(adis16060_read, ADIS16060_GYRO); -static IIO_DEVICE_ATTR(temp_raw, S_IRUGO, adis16060_read, NULL, - ADIS16060_TEMP_OUT); -static IIO_CONST_ATTR_TEMP_SCALE("34"); /* Milli degrees C */ -static IIO_CONST_ATTR_TEMP_OFFSET("-7461.117"); /* Milli degrees C */ -static IIO_DEV_ATTR_IN_RAW(0, adis16060_read, ADIS16060_AIN1); -static IIO_DEV_ATTR_IN_RAW(1, adis16060_read, ADIS16060_AIN2); -static IIO_CONST_ATTR(name, "adis16060"); - -static struct attribute *adis16060_attributes[] = { - &iio_dev_attr_gyro_z_raw.dev_attr.attr, - &iio_dev_attr_temp_raw.dev_attr.attr, - &iio_const_attr_temp_scale.dev_attr.attr, - &iio_const_attr_temp_offset.dev_attr.attr, - &iio_dev_attr_in0_raw.dev_attr.attr, - &iio_dev_attr_in1_raw.dev_attr.attr, - &iio_const_attr_name.dev_attr.attr, - NULL -}; - -static const struct attribute_group adis16060_attribute_group = { - .attrs = adis16060_attributes, -}; - static const struct iio_info adis16060_info = { - .attrs = &adis16060_attribute_group, + .read_raw = &adis16060_read_raw, .driver_module = THIS_MODULE, }; +static const struct iio_chan_spec adis16060_channels[] = { + { + .type = IIO_GYRO, + .modified = 1, + .channel2 = IIO_MOD_Z, + .address = ADIS16060_GYRO, + }, { + .type = IIO_IN, + .indexed = 1, + .channel = 0, + .address = ADIS16060_AIN1, + }, { + .type = IIO_IN, + .indexed = 1, + .channel = 1, + .address = ADIS16060_AIN2, + }, { + .type = IIO_TEMP, + .indexed = 1, + .channel = 0, + .info_mask = (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) | + (1 << IIO_CHAN_INFO_SCALE_SEPARATE), + .address = ADIS16060_TEMP_OUT, + } +}; + static int __devinit adis16060_r_probe(struct spi_device *spi) { int ret, regdone = 0; @@ -154,9 +159,12 @@ static int __devinit adis16060_r_probe(struct spi_device *spi) st->us_r = spi; mutex_init(&st->buf_lock); + indio_dev->name = spi->dev.driver->name; indio_dev->dev.parent = &spi->dev; indio_dev->info = &adis16060_info; indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = adis16060_channels; + indio_dev->num_channels = ARRAY_SIZE(adis16060_channels); ret = iio_device_register(indio_dev); if (ret) diff --git a/drivers/staging/iio/gyro/adis16080_core.c b/drivers/staging/iio/gyro/adis16080_core.c index ad2db4d..16ba0e1 100644 --- a/drivers/staging/iio/gyro/adis16080_core.c +++ b/drivers/staging/iio/gyro/adis16080_core.c @@ -13,11 +13,10 @@ #include <linux/spi/spi.h> #include <linux/slab.h> #include <linux/sysfs.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" -#include "gyro.h" -#include "../adc/adc.h" #define ADIS16080_DIN_GYRO (0 << 10) /* Gyroscope output */ #define ADIS16080_DIN_TEMP (1 << 10) /* Temperature output */ @@ -44,11 +43,10 @@ struct adis16080_state { u8 buf[2] ____cacheline_aligned; }; -static int adis16080_spi_write(struct device *dev, +static int adis16080_spi_write(struct iio_dev *indio_dev, u16 val) { int ret; - struct iio_dev *indio_dev = dev_get_drvdata(dev); struct adis16080_state *st = iio_priv(indio_dev); mutex_lock(&st->buf_lock); @@ -61,11 +59,10 @@ static int adis16080_spi_write(struct device *dev, return ret; } -static int adis16080_spi_read(struct device *dev, - u16 *val) +static int adis16080_spi_read(struct iio_dev *indio_dev, + u16 *val) { int ret; - struct iio_dev *indio_dev = dev_get_drvdata(dev); struct adis16080_state *st = iio_priv(indio_dev); mutex_lock(&st->buf_lock); @@ -79,50 +76,62 @@ static int adis16080_spi_read(struct device *dev, return ret; } -static ssize_t adis16080_read(struct device *dev, - struct device_attribute *attr, - char *buf) +static int adis16080_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long mask) { - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - struct iio_dev *indio_dev = dev_get_drvdata(dev); - u16 val = 0; - ssize_t ret; - + int ret = -EINVAL; + u16 ut; /* Take the iio_dev status lock */ + mutex_lock(&indio_dev->mlock); - ret = adis16080_spi_write(dev, - this_attr->address | ADIS16080_DIN_WRITE); - if (ret < 0) - goto error_ret; - ret = adis16080_spi_read(dev, &val); -error_ret: + switch (mask) { + case 0: + ret = adis16080_spi_write(indio_dev, + chan->address | + ADIS16080_DIN_WRITE); + if (ret < 0) + break; + ret = adis16080_spi_read(indio_dev, &ut); + if (ret < 0) + break; + *val = ut; + ret = IIO_VAL_INT; + break; + } mutex_unlock(&indio_dev->mlock); - if (ret == 0) - return sprintf(buf, "%d\n", val); - else - return ret; + return ret; } -static IIO_DEV_ATTR_GYRO_Z(adis16080_read, ADIS16080_DIN_GYRO); -static IIO_DEVICE_ATTR(temp_raw, S_IRUGO, adis16080_read, NULL, - ADIS16080_DIN_TEMP); -static IIO_DEV_ATTR_IN_RAW(0, adis16080_read, ADIS16080_DIN_AIN1); -static IIO_DEV_ATTR_IN_RAW(1, adis16080_read, ADIS16080_DIN_AIN2); - -static struct attribute *adis16080_attributes[] = { - &iio_dev_attr_gyro_z_raw.dev_attr.attr, - &iio_dev_attr_temp_raw.dev_attr.attr, - &iio_dev_attr_in0_raw.dev_attr.attr, - &iio_dev_attr_in1_raw.dev_attr.attr, - NULL -}; -static const struct attribute_group adis16080_attribute_group = { - .attrs = adis16080_attributes, +static const struct iio_chan_spec adis16080_channels[] = { + { + .type = IIO_GYRO, + .modified = 1, + .channel2 = IIO_MOD_Z, + .address = ADIS16080_DIN_GYRO, + }, { + .type = IIO_IN, + .indexed = 1, + .channel = 0, + .address = ADIS16080_DIN_AIN1, + }, { + .type = IIO_IN, + .indexed = 1, + .channel = 1, + .address = ADIS16080_DIN_AIN2, + }, { + .type = IIO_TEMP, + .indexed = 1, + .channel = 0, + .address = ADIS16080_DIN_TEMP, + } }; static const struct iio_info adis16080_info = { - .attrs = &adis16080_attribute_group, + .read_raw = &adis16080_read_raw, .driver_module = THIS_MODULE, }; @@ -147,6 +156,8 @@ static int __devinit adis16080_probe(struct spi_device *spi) mutex_init(&st->buf_lock); indio_dev->name = spi->dev.driver->name; + indio_dev->channels = adis16080_channels; + indio_dev->num_channels = ARRAY_SIZE(adis16080_channels); indio_dev->dev.parent = &spi->dev; indio_dev->info = &adis16080_info; indio_dev->modes = INDIO_DIRECT_MODE; diff --git a/drivers/staging/iio/gyro/adis16130_core.c b/drivers/staging/iio/gyro/adis16130_core.c index c80e908..a9f270e 100644 --- a/drivers/staging/iio/gyro/adis16130_core.c +++ b/drivers/staging/iio/gyro/adis16130_core.c @@ -14,11 +14,10 @@ #include <linux/slab.h> #include <linux/sysfs.h> #include <linux/list.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" -#include "gyro.h" -#include "../adc/adc.h" #define ADIS16130_CON 0x0 #define ADIS16130_CON_RD (1 << 6) @@ -41,140 +40,77 @@ /** * struct adis16130_state - device instance specific data * @us: actual spi_device to write data - * @mode: 24 bits (1) or 16 bits (0) * @buf_lock: mutex to protect tx and rx * @buf: unified tx/rx buffer **/ struct adis16130_state { struct spi_device *us; - u32 mode; struct mutex buf_lock; u8 buf[4] ____cacheline_aligned; }; -static int adis16130_spi_write(struct device *dev, u8 reg_addr, - u8 val) +static int adis16130_spi_read(struct iio_dev *indio_dev, u8 reg_addr, u32 *val) { int ret; - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct adis16130_state *st = iio_priv(indio_dev); - - mutex_lock(&st->buf_lock); - st->buf[0] = reg_addr; - st->buf[1] = val; - - ret = spi_write(st->us, st->buf, 2); - mutex_unlock(&st->buf_lock); - - return ret; -} - -static int adis16130_spi_read(struct device *dev, u8 reg_addr, - u32 *val) -{ - int ret; - struct iio_dev *indio_dev = dev_get_drvdata(dev); struct adis16130_state *st = iio_priv(indio_dev); + struct spi_message msg; + struct spi_transfer xfer = { + .tx_buf = st->buf, + .rx_buf = st->buf, + .len = 4, + }; mutex_lock(&st->buf_lock); st->buf[0] = ADIS16130_CON_RD | reg_addr; - if (st->mode) - ret = spi_read(st->us, st->buf, 4); - else - ret = spi_read(st->us, st->buf, 3); - - if (ret == 0) { - if (st->mode) - *val = (st->buf[1] << 16) | - (st->buf[2] << 8) | - st->buf[3]; - else - *val = (st->buf[1] << 8) | st->buf[2]; - } + st->buf[1] = st->buf[2] = st->buf[3] = 0; + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->us, &msg); + ret = spi_read(st->us, st->buf, 4); + + if (ret == 0) + *val = (st->buf[1] << 16) | (st->buf[2] << 8) | st->buf[3]; mutex_unlock(&st->buf_lock); return ret; } -static ssize_t adis16130_val_read(struct device *dev, - struct device_attribute *attr, - char *buf) +static int adis16130_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, + long mask) { - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); - struct iio_dev *indio_dev = dev_get_drvdata(dev); - u32 val; - ssize_t ret; + int ret; + u32 temp; /* Take the iio_dev status lock */ mutex_lock(&indio_dev->mlock); - ret = adis16130_spi_read(dev, this_attr->address, &val); + ret = adis16130_spi_read(indio_dev, chan->address, &temp); mutex_unlock(&indio_dev->mlock); - - if (ret == 0) - return sprintf(buf, "%d\n", val); - else + if (ret) return ret; + *val = temp; + return IIO_VAL_INT; } -static ssize_t adis16130_bitsmode_read(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct adis16130_state *st = iio_priv(indio_dev); - - if (st->mode == 1) - return sprintf(buf, "s24\n"); - else - return sprintf(buf, "s16\n"); -} - -static ssize_t adis16130_bitsmode_write(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - int ret; - u8 val; - - if (sysfs_streq(buf, "s16")) - val = 0; - else if (sysfs_streq(buf, "s24")) - val = 1; - else - return -EINVAL; - - ret = adis16130_spi_write(dev, ADIS16130_MODE, val); - - return ret ? ret : len; -} -static IIO_DEVICE_ATTR(temp_raw, S_IRUGO, adis16130_val_read, NULL, - ADIS16130_TEMPDATA); - -static IIO_DEV_ATTR_GYRO_Z(adis16130_val_read, ADIS16130_RATEDATA); - -static IIO_DEVICE_ATTR(gyro_z_type, S_IWUSR | S_IRUGO, adis16130_bitsmode_read, - adis16130_bitsmode_write, - ADIS16130_MODE); - -static IIO_CONST_ATTR(gyro_z_type_available, "s16 s24"); - -static struct attribute *adis16130_attributes[] = { - &iio_dev_attr_temp_raw.dev_attr.attr, - &iio_dev_attr_gyro_z_raw.dev_attr.attr, - &iio_dev_attr_gyro_z_type.dev_attr.attr, - &iio_const_attr_gyro_z_type_available.dev_attr.attr, - NULL -}; - -static const struct attribute_group adis16130_attribute_group = { - .attrs = adis16130_attributes, +static const struct iio_chan_spec adis16130_channels[] = { + { + .type = IIO_GYRO, + .modified = 1, + .channel2 = IIO_MOD_Z, + .address = ADIS16130_RATEDATA, + }, { + .type = IIO_TEMP, + .indexed = 1, + .channel = 0, + .address = ADIS16130_TEMPDATA, + } }; static const struct iio_info adis16130_info = { - .attrs = &adis16130_attribute_group, + .read_raw = &adis16130_read_raw, .driver_module = THIS_MODULE, }; @@ -196,10 +132,11 @@ static int __devinit adis16130_probe(struct spi_device *spi) st->us = spi; mutex_init(&st->buf_lock); indio_dev->name = spi->dev.driver->name; + indio_dev->channels = adis16130_channels; + indio_dev->num_channels = ARRAY_SIZE(adis16130_channels); indio_dev->dev.parent = &spi->dev; indio_dev->info = &adis16130_info; indio_dev->modes = INDIO_DIRECT_MODE; - st->mode = 1; ret = iio_device_register(indio_dev); if (ret) diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c index f2d43cf..fcd7819 100644 --- a/drivers/staging/iio/gyro/adis16260_core.c +++ b/drivers/staging/iio/gyro/adis16260_core.c @@ -17,12 +17,11 @@ #include <linux/slab.h> #include <linux/sysfs.h> #include <linux/list.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" #include "../ring_generic.h" -#include "../adc/adc.h" -#include "gyro.h" #include "adis16260.h" diff --git a/drivers/staging/iio/gyro/adis16260_ring.c b/drivers/staging/iio/gyro/adis16260_ring.c index a4df8b3..10f8a66 100644 --- a/drivers/staging/iio/gyro/adis16260_ring.c +++ b/drivers/staging/iio/gyro/adis16260_ring.c @@ -1,20 +1,12 @@ #include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/gpio.h> -#include <linux/workqueue.h> #include <linux/mutex.h> -#include <linux/device.h> #include <linux/kernel.h> #include <linux/spi/spi.h> #include <linux/slab.h> -#include <linux/sysfs.h> -#include <linux/list.h> #include "../iio.h" -#include "../sysfs.h" #include "../ring_sw.h" -#include "../accel/accel.h" -#include "../trigger.h" +#include "../trigger_consumer.h" #include "adis16260.h" /** @@ -68,7 +60,7 @@ static int adis16260_read_ring_data(struct device *dev, u8 *rx) static irqreturn_t adis16260_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->private_data; + struct iio_dev *indio_dev = pf->indio_dev; struct adis16260_state *st = iio_priv(indio_dev); struct iio_ring_buffer *ring = indio_dev->ring; int i = 0; diff --git a/drivers/staging/iio/gyro/adis16260_trigger.c b/drivers/staging/iio/gyro/adis16260_trigger.c index 01094d0..2f2b216 100644 --- a/drivers/staging/iio/gyro/adis16260_trigger.c +++ b/drivers/staging/iio/gyro/adis16260_trigger.c @@ -1,14 +1,8 @@ #include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/mutex.h> -#include <linux/device.h> #include <linux/kernel.h> -#include <linux/sysfs.h> -#include <linux/list.h> #include <linux/spi/spi.h> #include "../iio.h" -#include "../sysfs.h" #include "../trigger.h" #include "adis16260.h" @@ -24,6 +18,11 @@ static int adis16260_data_rdy_trigger_set_state(struct iio_trigger *trig, return adis16260_set_irq(indio_dev, state); } +static const struct iio_trigger_ops adis16260_trigger_ops = { + .owner = THIS_MODULE, + .set_trigger_state = &adis16260_data_rdy_trigger_set_state, +}; + int adis16260_probe_trigger(struct iio_dev *indio_dev) { int ret; @@ -46,9 +45,8 @@ int adis16260_probe_trigger(struct iio_dev *indio_dev) goto error_free_trig; st->trig->dev.parent = &st->us->dev; - st->trig->owner = THIS_MODULE; + st->trig->ops = &adis16260_trigger_ops; st->trig->private_data = indio_dev; - st->trig->set_trigger_state = &adis16260_data_rdy_trigger_set_state; ret = iio_trigger_register(st->trig); /* select default trigger */ diff --git a/drivers/staging/iio/gyro/adxrs450_core.c b/drivers/staging/iio/gyro/adxrs450_core.c index 7502a26..670b615 100644 --- a/drivers/staging/iio/gyro/adxrs450_core.c +++ b/drivers/staging/iio/gyro/adxrs450_core.c @@ -17,11 +17,10 @@ #include <linux/slab.h> #include <linux/sysfs.h> #include <linux/list.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" -#include "gyro.h" -#include "../adc/adc.h" #include "adxrs450.h" @@ -32,26 +31,12 @@ * Second register's address is reg_address + 1. * @val: somewhere to pass back the value read **/ -static int adxrs450_spi_read_reg_16(struct device *dev, - u8 reg_address, - u16 *val) +static int adxrs450_spi_read_reg_16(struct iio_dev *indio_dev, + u8 reg_address, + u16 *val) { - struct spi_message msg; - struct iio_dev *indio_dev = dev_get_drvdata(dev); struct adxrs450_state *st = iio_priv(indio_dev); int ret; - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 4, - .cs_change = 1, - }, { - .rx_buf = st->rx, - .bits_per_word = 8, - .len = 4, - }, - }; mutex_lock(&st->buf_lock); st->tx[0] = ADXRS450_READ_DATA | (reg_address >> 7); @@ -62,10 +47,13 @@ static int adxrs450_spi_read_reg_16(struct device *dev, if (!(hweight32(be32_to_cpu(*(u32 *)st->tx)) & 1)) st->tx[3] |= ADXRS450_P; - spi_message_init(&msg); - spi_message_add_tail(&xfers[0], &msg); - spi_message_add_tail(&xfers[1], &msg); - ret = spi_sync(st->us, &msg); + ret = spi_write(st->us, st->tx, 4); + if (ret) { + dev_err(&st->us->dev, "problem while reading 16 bit register 0x%02x\n", + reg_address); + goto error_ret; + } + ret = spi_read(st->us, st->rx, 4); if (ret) { dev_err(&st->us->dev, "problem while reading 16 bit register 0x%02x\n", reg_address); @@ -86,20 +74,12 @@ error_ret: * Second register's address is reg_address + 1. * @val: value to be written. **/ -static int adxrs450_spi_write_reg_16(struct device *dev, - u8 reg_address, - u16 val) +static int adxrs450_spi_write_reg_16(struct iio_dev *indio_dev, + u8 reg_address, + u16 val) { - struct spi_message msg; - struct iio_dev *indio_dev = dev_get_drvdata(dev); struct adxrs450_state *st = iio_priv(indio_dev); int ret; - struct spi_transfer xfers = { - .tx_buf = st->tx, - .rx_buf = st->rx, - .bits_per_word = 8, - .len = 4, - }; mutex_lock(&st->buf_lock); st->tx[0] = ADXRS450_WRITE_DATA | reg_address >> 7; @@ -108,14 +88,12 @@ static int adxrs450_spi_write_reg_16(struct device *dev, st->tx[3] = val << 1; if (!(hweight32(be32_to_cpu(*(u32 *)st->tx)) & 1)) - st->tx[3] |= ADXRS450_P; + st->tx[3] |= ADXRS450_P; - spi_message_init(&msg); - spi_message_add_tail(&xfers, &msg); - ret = spi_sync(st->us, &msg); + ret = spi_write(st->us, st->tx, 4); if (ret) dev_err(&st->us->dev, "problem while writing 16 bit register 0x%02x\n", - reg_address); + reg_address); msleep(1); /* enforce sequential transfer delay 0.1ms */ mutex_unlock(&st->buf_lock); return ret; @@ -126,24 +104,10 @@ static int adxrs450_spi_write_reg_16(struct device *dev, * @dev: device associated with child of actual iio_dev * @val: somewhere to pass back the value read **/ -static int adxrs450_spi_sensor_data(struct device *dev, s16 *val) +static int adxrs450_spi_sensor_data(struct iio_dev *indio_dev, s16 *val) { - struct spi_message msg; - struct iio_dev *indio_dev = dev_get_drvdata(dev); struct adxrs450_state *st = iio_priv(indio_dev); int ret; - struct spi_transfer xfers[] = { - { - .tx_buf = st->tx, - .bits_per_word = 8, - .len = 4, - .cs_change = 1, - }, { - .rx_buf = st->rx, - .bits_per_word = 8, - .len = 4, - }, - }; mutex_lock(&st->buf_lock); st->tx[0] = ADXRS450_SENSOR_DATA; @@ -151,10 +115,13 @@ static int adxrs450_spi_sensor_data(struct device *dev, s16 *val) st->tx[2] = 0; st->tx[3] = 0; - spi_message_init(&msg); - spi_message_add_tail(&xfers[0], &msg); - spi_message_add_tail(&xfers[1], &msg); - ret = spi_sync(st->us, &msg); + ret = spi_write(st->us, st->tx, 4); + if (ret) { + dev_err(&st->us->dev, "Problem while reading sensor data\n"); + goto error_ret; + } + + ret = spi_read(st->us, st->rx, 4); if (ret) { dev_err(&st->us->dev, "Problem while reading sensor data\n"); goto error_ret; @@ -206,73 +173,12 @@ error_ret: return ret; } -static ssize_t adxrs450_read_temp(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int ret; - u16 t; - ret = adxrs450_spi_read_reg_16(dev, - ADXRS450_TEMP1, - &t); - if (ret) - return ret; - return sprintf(buf, "%d\n", t >> 7); -} - -static ssize_t adxrs450_read_quad(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int ret; - s16 t; - ret = adxrs450_spi_read_reg_16(dev, - ADXRS450_QUAD1, - &t); - if (ret) - return ret; - return sprintf(buf, "%d\n", t); -} - -static ssize_t adxrs450_write_dnc(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) -{ - int ret; - long val; - - ret = strict_strtol(buf, 10, &val); - if (ret) - goto error_ret; - ret = adxrs450_spi_write_reg_16(dev, - ADXRS450_DNC1, - val & 0x3FF); -error_ret: - return ret ? ret : len; -} - -static ssize_t adxrs450_read_sensor_data(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - int ret; - s16 t; - - ret = adxrs450_spi_sensor_data(dev, &t); - if (ret) - return ret; - - return sprintf(buf, "%d\n", t); -} - /* Recommended Startup Sequence by spec */ static int adxrs450_initial_setup(struct iio_dev *indio_dev) { u32 t; u16 data; int ret; - struct device *dev = &indio_dev->dev; struct adxrs450_state *st = iio_priv(indio_dev); msleep(ADXRS450_STARTUP_DELAY*2); @@ -305,23 +211,23 @@ static int adxrs450_initial_setup(struct iio_dev *indio_dev) return -EIO; } - ret = adxrs450_spi_read_reg_16(dev, ADXRS450_FAULT1, &data); + ret = adxrs450_spi_read_reg_16(indio_dev, ADXRS450_FAULT1, &data); if (ret) return ret; if (data & 0x0fff) { dev_err(&st->us->dev, "The device is not in normal status!\n"); return -EINVAL; } - ret = adxrs450_spi_read_reg_16(dev, ADXRS450_PID1, &data); + ret = adxrs450_spi_read_reg_16(indio_dev, ADXRS450_PID1, &data); if (ret) return ret; dev_info(&st->us->dev, "The Part ID is 0x%x\n", data); - ret = adxrs450_spi_read_reg_16(dev, ADXRS450_SNL, &data); + ret = adxrs450_spi_read_reg_16(indio_dev, ADXRS450_SNL, &data); if (ret) return ret; t = data; - ret = adxrs450_spi_read_reg_16(dev, ADXRS450_SNH, &data); + ret = adxrs450_spi_read_reg_16(indio_dev, ADXRS450_SNH, &data); if (ret) return ret; t |= data << 16; @@ -330,29 +236,91 @@ static int adxrs450_initial_setup(struct iio_dev *indio_dev) return 0; } -static IIO_DEV_ATTR_GYRO_Z(adxrs450_read_sensor_data, 0); -static IIO_DEV_ATTR_TEMP_RAW(adxrs450_read_temp); -static IIO_DEV_ATTR_GYRO_Z_QUADRATURE_CORRECTION(adxrs450_read_quad, 0); -static IIO_DEV_ATTR_GYRO_Z_CALIBBIAS(S_IWUSR, - NULL, adxrs450_write_dnc, 0); -static IIO_CONST_ATTR(name, "adxrs450"); - -static struct attribute *adxrs450_attributes[] = { - &iio_dev_attr_gyro_z_raw.dev_attr.attr, - &iio_dev_attr_temp_raw.dev_attr.attr, - &iio_dev_attr_gyro_z_quadrature_correction_raw.dev_attr.attr, - &iio_dev_attr_gyro_z_calibbias.dev_attr.attr, - &iio_const_attr_name.dev_attr.attr, - NULL -}; +static int adxrs450_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, + int val2, + long mask) +{ + int ret; + switch (mask) { + case (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE): + ret = adxrs450_spi_write_reg_16(indio_dev, + ADXRS450_DNC1, + val & 0x3FF); + break; + default: + ret = -EINVAL; + break; + } + return ret; +} -static const struct attribute_group adxrs450_attribute_group = { - .attrs = adxrs450_attributes, +static int adxrs450_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long mask) +{ + int ret; + s16 t; + u16 ut; + switch (mask) { + case 0: + switch (chan->type) { + case IIO_GYRO: + ret = adxrs450_spi_sensor_data(indio_dev, &t); + if (ret) + break; + *val = t; + ret = IIO_VAL_INT; + break; + case IIO_TEMP: + ret = adxrs450_spi_read_reg_16(indio_dev, + ADXRS450_TEMP1, &ut); + if (ret) + break; + *val = ut; + ret = IIO_VAL_INT; + break; + default: + ret = -EINVAL; + break; + } + break; + case (1 << IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW_SEPARATE): + ret = adxrs450_spi_read_reg_16(indio_dev, ADXRS450_QUAD1, &t); + if (ret) + break; + *val = t; + ret = IIO_VAL_INT; + break; + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static const struct iio_chan_spec adxrs450_channels[] = { + { + .type = IIO_GYRO, + .modified = 1, + .channel2 = IIO_MOD_Z, + .info_mask = (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | + (1 << IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW_SEPARATE) + }, { + .type = IIO_TEMP, + .indexed = 1, + .channel = 0, + } }; static const struct iio_info adxrs450_info = { - .attrs = &adxrs450_attribute_group, .driver_module = THIS_MODULE, + .read_raw = &adxrs450_read_raw, + .write_raw = &adxrs450_write_raw, }; static int __devinit adxrs450_probe(struct spi_device *spi) @@ -376,6 +344,9 @@ static int __devinit adxrs450_probe(struct spi_device *spi) indio_dev->dev.parent = &spi->dev; indio_dev->info = &adxrs450_info; indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = adxrs450_channels; + indio_dev->num_channels = ARRAY_SIZE(adxrs450_channels); + indio_dev->name = spi->dev.driver->name; ret = iio_device_register(indio_dev); if (ret) diff --git a/drivers/staging/iio/gyro/gyro.h b/drivers/staging/iio/gyro/gyro.h deleted file mode 100644 index b5495613..0000000 --- a/drivers/staging/iio/gyro/gyro.h +++ /dev/null @@ -1,85 +0,0 @@ - -#include "../sysfs.h" - -/* Gyroscope types of attribute */ - -#define IIO_CONST_ATTR_GYRO_OFFSET(_string) \ - IIO_CONST_ATTR(gyro_offset, _string) - -#define IIO_DEV_ATTR_GYRO_OFFSET(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(gyro_offset, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_GYRO_X_OFFSET(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(gyro_x_offset, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_GYRO_Y_OFFSET(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(gyro_y_offset, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_GYRO_Z_OFFSET(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(gyro_z_offset, _mode, _show, _store, _addr) - -#define IIO_CONST_ATTR_GYRO_SCALE(_string) \ - IIO_CONST_ATTR(gyro_scale, _string) - -#define IIO_DEV_ATTR_GYRO_SCALE(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(gyro_scale, S_IRUGO, _show, _store, _addr) - -#define IIO_DEV_ATTR_GYRO_X_SCALE(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(gyro_x_scale, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_GYRO_Y_SCALE(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(gyro_y_scale, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_GYRO_Z_SCALE(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(gyro_z_scale, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_GYRO_CALIBBIAS(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(gyro_calibbias, S_IRUGO, _show, _store, _addr) - -#define IIO_DEV_ATTR_GYRO_X_CALIBBIAS(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(gyro_x_calibbias, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_GYRO_Y_CALIBBIAS(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(gyro_y_calibbias, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_GYRO_Z_CALIBBIAS(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(gyro_z_calibbias, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_GYRO_CALIBSCALE(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(gyro_calibscale, S_IRUGO, _show, _store, _addr) - -#define IIO_DEV_ATTR_GYRO_X_CALIBSCALE(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(gyro_x_calibscale, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_GYRO_Y_CALIBSCALE(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(gyro_y_calibscale, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_GYRO_Z_CALIBSCALE(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(gyro_z_calibscale, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_GYRO_Z_QUADRATURE_CORRECTION(_show, _addr) \ - IIO_DEVICE_ATTR(gyro_z_quadrature_correction_raw, S_IRUGO, _show, NULL, _addr) - -#define IIO_DEV_ATTR_GYRO(_show, _addr) \ - IIO_DEVICE_ATTR(gyro_raw, S_IRUGO, _show, NULL, _addr) - -#define IIO_DEV_ATTR_GYRO_X(_show, _addr) \ - IIO_DEVICE_ATTR(gyro_x_raw, S_IRUGO, _show, NULL, _addr) - -#define IIO_DEV_ATTR_GYRO_Y(_show, _addr) \ - IIO_DEVICE_ATTR(gyro_y_raw, S_IRUGO, _show, NULL, _addr) - -#define IIO_DEV_ATTR_GYRO_Z(_show, _addr) \ - IIO_DEVICE_ATTR(gyro_z_raw, S_IRUGO, _show, NULL, _addr) - -#define IIO_DEV_ATTR_ANGL(_show, _addr) \ - IIO_DEVICE_ATTR(angl_raw, S_IRUGO, _show, NULL, _addr) - -#define IIO_DEV_ATTR_ANGL_X(_show, _addr) \ - IIO_DEVICE_ATTR(angl_x_raw, S_IRUGO, _show, NULL, _addr) - -#define IIO_DEV_ATTR_ANGL_Y(_show, _addr) \ - IIO_DEVICE_ATTR(angl_y_raw, S_IRUGO, _show, NULL, _addr) - -#define IIO_DEV_ATTR_ANGL_Z(_show, _addr) \ - IIO_DEVICE_ATTR(angl_z_raw, S_IRUGO, _show, NULL, _addr) diff --git a/drivers/staging/iio/iio.h b/drivers/staging/iio/iio.h index 7a6ce4d..753f769 100644 --- a/drivers/staging/iio/iio.h +++ b/drivers/staging/iio/iio.h @@ -1,3 +1,4 @@ + /* The industrial I/O core * * Copyright (c) 2008 Jonathan Cameron @@ -22,11 +23,6 @@ * Currently assumes nano seconds. */ -/* Event interface flags */ -#define IIO_BUSY_BIT_POS 1 - -/* naughty temporary hack to match these against the event version - - need to flattern these together */ enum iio_chan_type { /* real channel types */ IIO_IN, @@ -75,6 +71,8 @@ enum iio_chan_info_enum { IIO_CHAN_INFO_PEAK_SEPARATE, IIO_CHAN_INFO_PEAK_SCALE_SHARED, IIO_CHAN_INFO_PEAK_SCALE_SEPARATE, + IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW_SHARED, + IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW_SEPARATE, }; /** @@ -121,26 +119,14 @@ struct iio_chan_spec { u8 storagebits; u8 shift; } scan_type; - const long info_mask; - const long event_mask; - const char *extend_name; + long info_mask; + long event_mask; + char *extend_name; unsigned processed_val:1; unsigned modified:1; unsigned indexed:1; }; -/* Meant for internal use only */ -void __iio_device_attr_deinit(struct device_attribute *dev_attr); -int __iio_device_attr_init(struct device_attribute *dev_attr, - const char *postfix, - struct iio_chan_spec const *chan, - ssize_t (*readfunc)(struct device *dev, - struct device_attribute *attr, - char *buf), - ssize_t (*writefunc)(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len), - bool generic); + #define IIO_ST(si, rb, sb, sh) \ { .sign = si, .realbits = rb, .storagebits = sb, .shift = sh } @@ -163,20 +149,6 @@ int __iio_device_attr_init(struct device_attribute *dev_attr, { .type = IIO_TIMESTAMP, .channel = -1, \ .scan_index = _si, .scan_type = IIO_ST('s', 64, 64, 0) } -int __iio_add_chan_devattr(const char *postfix, - const char *group, - struct iio_chan_spec const *chan, - ssize_t (*func)(struct device *dev, - struct device_attribute *attr, - char *buf), - ssize_t (*writefunc)(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len), - int mask, - bool generic, - struct device *dev, - struct list_head *attr_list); /** * iio_get_time_ns() - utility function to get a time stamp for events etc **/ @@ -276,7 +248,6 @@ struct iio_info { /** * struct iio_dev - industrial I/O device * @id: [INTERN] used to identify device internally - * @dev_data: [DRIVER] device specific data * @modes: [DRIVER] operating modes supported by device * @currentmode: [DRIVER] current operating mode * @dev: [DRIVER] device structure, should be assigned a parent @@ -296,7 +267,7 @@ struct iio_info { **/ struct iio_dev { int id; - void *dev_data; + int modes; int currentmode; struct device dev; @@ -342,13 +313,6 @@ int iio_push_event(struct iio_dev *dev_info, int ev_code, s64 timestamp); -/* Used to distinguish between bipolar and unipolar scan elemenents. - * Whilst this may seem obvious, we may well want to change the representation - * in the future!*/ -#define IIO_SIGNED(a) -(a) -#define IIO_UNSIGNED(a) (a) - -extern dev_t iio_devt; extern struct bus_type iio_bus_type; /** @@ -361,25 +325,6 @@ static inline void iio_put_device(struct iio_dev *dev) put_device(&dev->dev); }; -/** - * to_iio_dev() - get iio_dev for which we have the struct device - * @d: the struct device - **/ -static inline struct iio_dev *to_iio_dev(struct device *d) -{ - return container_of(d, struct iio_dev, dev); -}; - -/** - * iio_dev_get_devdata() - helper function gets device specific data - * @d: the iio_dev associated with the device - **/ -static inline void *iio_dev_get_devdata(struct iio_dev *d) -{ - return d->dev_data; -} - - /* Can we make this smaller? */ #define IIO_ALIGN L1_CACHE_BYTES /** @@ -406,22 +351,6 @@ static inline struct iio_dev *iio_priv_to_dev(void *priv) void iio_free_device(struct iio_dev *dev); /** - * iio_put() - internal module reference count reduce - **/ -void iio_put(void); - -/** - * iio_get() - internal module reference count increase - **/ -void iio_get(void); - -/** - * iio_device_get_chrdev_minor() - get an unused minor number - **/ -int iio_device_get_chrdev_minor(void); -void iio_device_free_chrdev_minor(int val); - -/** * iio_ring_enabled() - helper function to test if any form of ring is enabled * @dev_info: IIO device info structure for device **/ @@ -432,8 +361,4 @@ static inline bool iio_ring_enabled(struct iio_dev *dev_info) | INDIO_RING_HARDWARE_BUFFER); }; -struct ida; - -int iio_get_new_ida_val(struct ida *this_ida); -void iio_free_ida_val(struct ida *this_ida, int id); #endif /* _INDUSTRIAL_IO_H_ */ diff --git a/drivers/staging/iio/iio_core.h b/drivers/staging/iio/iio_core.h new file mode 100644 index 0000000..00e894d --- /dev/null +++ b/drivers/staging/iio/iio_core.h @@ -0,0 +1,48 @@ +/* The industrial I/O core function defs. + * + * Copyright (c) 2008 Jonathan Cameron + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + * + * These definitions are meant for use only within the IIO core, not indvidual + * drivers. + */ + +/** + * iio_device_get_chrdev_minor() - get an unused minor number + **/ +int iio_device_get_chrdev_minor(void); +void iio_device_free_chrdev_minor(int val); + + +/** + * iio_put() - internal module reference count reduce + **/ +void iio_put(void); + +/** + * iio_get() - internal module reference count increase + **/ +void iio_get(void); + +extern dev_t iio_devt; + +int __iio_add_chan_devattr(const char *postfix, + const char *group, + struct iio_chan_spec const *chan, + ssize_t (*func)(struct device *dev, + struct device_attribute *attr, + char *buf), + ssize_t (*writefunc)(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len), + int mask, + bool generic, + struct device *dev, + struct list_head *attr_list); + +/* Event interface flags */ +#define IIO_BUSY_BIT_POS 1 diff --git a/drivers/staging/iio/iio_core_trigger.h b/drivers/staging/iio/iio_core_trigger.h new file mode 100644 index 0000000..3e5195a --- /dev/null +++ b/drivers/staging/iio/iio_core_trigger.h @@ -0,0 +1,46 @@ + +/* The industrial I/O core, trigger consumer handling functions + * + * Copyright (c) 2008 Jonathan Cameron + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +#ifdef CONFIG_IIO_TRIGGER +/** + * iio_device_register_trigger_consumer() - set up an iio_dev to use triggers + * @dev_info: iio_dev associated with the device that will consume the trigger + **/ +int iio_device_register_trigger_consumer(struct iio_dev *dev_info); + +/** + * iio_device_unregister_trigger_consumer() - reverse the registration process + * @dev_info: iio_dev associated with the device that consumed the trigger + **/ +void iio_device_unregister_trigger_consumer(struct iio_dev *dev_info); + +#else + +/** + * iio_device_register_trigger_consumer() - set up an iio_dev to use triggers + * @dev_info: iio_dev associated with the device that will consume the trigger + **/ +static int iio_device_register_trigger_consumer(struct iio_dev *dev_info) +{ + return 0; +}; + +/** + * iio_device_unregister_trigger_consumer() - reverse the registration process + * @dev_info: iio_dev associated with the device that consumed the trigger + **/ +static void iio_device_unregister_trigger_consumer(struct iio_dev *dev_info) +{ +}; + +#endif /* CONFIG_TRIGGER_CONSUMER */ + + + diff --git a/drivers/staging/iio/impedance-analyzer/Kconfig b/drivers/staging/iio/impedance-analyzer/Kconfig new file mode 100644 index 0000000..9e91a9b --- /dev/null +++ b/drivers/staging/iio/impedance-analyzer/Kconfig @@ -0,0 +1,16 @@ +# +# Impedance Converter, Network Analyzer drivers +# +comment "Network Analyzer, Impedance Converters" + +config AD5933 + tristate "Analog Devices AD5933, AD5934 driver" + depends on I2C + select IIO_RING_BUFFER + select IIO_SW_RING + help + Say yes here to build support for Analog Devices Impedance Converter, + Network Analyzer, AD5933/4, provides direct access via sysfs. + + To compile this driver as a module, choose M here: the + module will be called ad5933. diff --git a/drivers/staging/iio/impedance-analyzer/Makefile b/drivers/staging/iio/impedance-analyzer/Makefile new file mode 100644 index 0000000..7604d78 --- /dev/null +++ b/drivers/staging/iio/impedance-analyzer/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for Impedance Converter, Network Analyzer drivers +# + +obj-$(CONFIG_AD5933) += ad5933.o diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.c b/drivers/staging/iio/impedance-analyzer/ad5933.c new file mode 100644 index 0000000..acc0e69 --- /dev/null +++ b/drivers/staging/iio/impedance-analyzer/ad5933.c @@ -0,0 +1,818 @@ +/* + * AD5933 AD5934 Impedance Converter, Network Analyzer + * + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#include <linux/interrupt.h> +#include <linux/device.h> +#include <linux/kernel.h> +#include <linux/sysfs.h> +#include <linux/i2c.h> +#include <linux/regulator/consumer.h> +#include <linux/slab.h> +#include <linux/types.h> +#include <linux/err.h> +#include <linux/delay.h> +#include <asm/div64.h> + +#include "../iio.h" +#include "../sysfs.h" +#include "../ring_generic.h" +#include "../ring_sw.h" + +#include "ad5933.h" + +/* AD5933/AD5934 Registers */ +#define AD5933_REG_CONTROL_HB 0x80 /* R/W, 2 bytes */ +#define AD5933_REG_CONTROL_LB 0x81 /* R/W, 2 bytes */ +#define AD5933_REG_FREQ_START 0x82 /* R/W, 3 bytes */ +#define AD5933_REG_FREQ_INC 0x85 /* R/W, 3 bytes */ +#define AD5933_REG_INC_NUM 0x88 /* R/W, 2 bytes, 9 bit */ +#define AD5933_REG_SETTLING_CYCLES 0x8A /* R/W, 2 bytes */ +#define AD5933_REG_STATUS 0x8F /* R, 1 byte */ +#define AD5933_REG_TEMP_DATA 0x92 /* R, 2 bytes*/ +#define AD5933_REG_REAL_DATA 0x94 /* R, 2 bytes*/ +#define AD5933_REG_IMAG_DATA 0x96 /* R, 2 bytes*/ + +/* AD5933_REG_CONTROL_HB Bits */ +#define AD5933_CTRL_INIT_START_FREQ (0x1 << 4) +#define AD5933_CTRL_START_SWEEP (0x2 << 4) +#define AD5933_CTRL_INC_FREQ (0x3 << 4) +#define AD5933_CTRL_REPEAT_FREQ (0x4 << 4) +#define AD5933_CTRL_MEASURE_TEMP (0x9 << 4) +#define AD5933_CTRL_POWER_DOWN (0xA << 4) +#define AD5933_CTRL_STANDBY (0xB << 4) + +#define AD5933_CTRL_RANGE_2000mVpp (0x0 << 1) +#define AD5933_CTRL_RANGE_200mVpp (0x1 << 1) +#define AD5933_CTRL_RANGE_400mVpp (0x2 << 1) +#define AD5933_CTRL_RANGE_1000mVpp (0x3 << 1) +#define AD5933_CTRL_RANGE(x) ((x) << 1) + +#define AD5933_CTRL_PGA_GAIN_1 (0x1 << 0) +#define AD5933_CTRL_PGA_GAIN_5 (0x0 << 0) + +/* AD5933_REG_CONTROL_LB Bits */ +#define AD5933_CTRL_RESET (0x1 << 4) +#define AD5933_CTRL_INT_SYSCLK (0x0 << 3) +#define AD5933_CTRL_EXT_SYSCLK (0x1 << 3) + +/* AD5933_REG_STATUS Bits */ +#define AD5933_STAT_TEMP_VALID (0x1 << 0) +#define AD5933_STAT_DATA_VALID (0x1 << 1) +#define AD5933_STAT_SWEEP_DONE (0x1 << 2) + +/* I2C Block Commands */ +#define AD5933_I2C_BLOCK_WRITE 0xA0 +#define AD5933_I2C_BLOCK_READ 0xA1 +#define AD5933_I2C_ADDR_POINTER 0xB0 + +/* Device Specs */ +#define AD5933_INT_OSC_FREQ_Hz 16776000 +#define AD5933_MAX_OUTPUT_FREQ_Hz 100000 +#define AD5933_MAX_RETRIES 100 + +#define AD5933_OUT_RANGE 1 +#define AD5933_OUT_RANGE_AVAIL 2 +#define AD5933_OUT_SETTLING_CYCLES 3 +#define AD5933_IN_PGA_GAIN 4 +#define AD5933_IN_PGA_GAIN_AVAIL 5 +#define AD5933_FREQ_POINTS 6 + +#define AD5933_POLL_TIME_ms 10 +#define AD5933_INIT_EXCITATION_TIME_ms 100 + +struct ad5933_state { + struct i2c_client *client; + struct regulator *reg; + struct ad5933_platform_data *pdata; + struct delayed_work work; + unsigned long mclk_hz; + unsigned char ctrl_hb; + unsigned char ctrl_lb; + unsigned range_avail[4]; + unsigned short vref_mv; + unsigned short settling_cycles; + unsigned short freq_points; + unsigned freq_start; + unsigned freq_inc; + unsigned state; + unsigned poll_time_jiffies; +}; + +static struct ad5933_platform_data ad5933_default_pdata = { + .vref_mv = 3300, +}; + +static struct iio_chan_spec ad5933_channels[] = { + IIO_CHAN(IIO_TEMP, 0, 1, 1, NULL, 0, 0, 0, + 0, AD5933_REG_TEMP_DATA, IIO_ST('s', 14, 16, 0), 0), + /* Ring Channels */ + IIO_CHAN(IIO_IN, 0, 1, 0, "real_raw", 0, 0, + (1 << IIO_CHAN_INFO_SCALE_SEPARATE), + AD5933_REG_REAL_DATA, 0, IIO_ST('s', 16, 16, 0), 0), + IIO_CHAN(IIO_IN, 0, 1, 0, "imag_raw", 0, 0, + (1 << IIO_CHAN_INFO_SCALE_SEPARATE), + AD5933_REG_IMAG_DATA, 1, IIO_ST('s', 16, 16, 0), 0), +}; + +static int ad5933_i2c_write(struct i2c_client *client, + u8 reg, u8 len, u8 *data) +{ + int ret; + + while (len--) { + ret = i2c_smbus_write_byte_data(client, reg++, *data++); + if (ret < 0) { + dev_err(&client->dev, "I2C write error\n"); + return ret; + } + } + return 0; +} + +static int ad5933_i2c_read(struct i2c_client *client, + u8 reg, u8 len, u8 *data) +{ + int ret; + + while (len--) { + ret = i2c_smbus_read_byte_data(client, reg++); + if (ret < 0) { + dev_err(&client->dev, "I2C read error\n"); + return ret; + } + *data++ = ret; + } + return 0; +} + +static int ad5933_cmd(struct ad5933_state *st, unsigned char cmd) +{ + unsigned char dat = st->ctrl_hb | cmd; + + return ad5933_i2c_write(st->client, + AD5933_REG_CONTROL_HB, 1, &dat); +} + +static int ad5933_reset(struct ad5933_state *st) +{ + unsigned char dat = st->ctrl_lb | AD5933_CTRL_RESET; + return ad5933_i2c_write(st->client, + AD5933_REG_CONTROL_LB, 1, &dat); +} + +static int ad5933_wait_busy(struct ad5933_state *st, unsigned char event) +{ + unsigned char val, timeout = AD5933_MAX_RETRIES; + int ret; + + while (timeout--) { + ret = ad5933_i2c_read(st->client, AD5933_REG_STATUS, 1, &val); + if (ret < 0) + return ret; + if (val & event) + return val; + cpu_relax(); + mdelay(1); + } + + return -EAGAIN; +} + +static int ad5933_set_freq(struct ad5933_state *st, + unsigned reg, unsigned long freq) +{ + unsigned long long freqreg; + union { + u32 d32; + u8 d8[4]; + } dat; + + freqreg = (u64) freq * (u64) (1 << 27); + do_div(freqreg, st->mclk_hz / 4); + + switch (reg) { + case AD5933_REG_FREQ_START: + st->freq_start = freq; + break; + case AD5933_REG_FREQ_INC: + st->freq_inc = freq; + break; + default: + return -EINVAL; + } + + dat.d32 = cpu_to_be32(freqreg); + return ad5933_i2c_write(st->client, reg, 3, &dat.d8[1]); +} + +static int ad5933_setup(struct ad5933_state *st) +{ + unsigned short dat; + int ret; + + ret = ad5933_reset(st); + if (ret < 0) + return ret; + + ret = ad5933_set_freq(st, AD5933_REG_FREQ_START, 10000); + if (ret < 0) + return ret; + + ret = ad5933_set_freq(st, AD5933_REG_FREQ_INC, 200); + if (ret < 0) + return ret; + + st->settling_cycles = 10; + dat = cpu_to_be16(st->settling_cycles); + + ret = ad5933_i2c_write(st->client, + AD5933_REG_SETTLING_CYCLES, 2, (u8 *)&dat); + if (ret < 0) + return ret; + + st->freq_points = 100; + dat = cpu_to_be16(st->freq_points); + + return ad5933_i2c_write(st->client, AD5933_REG_INC_NUM, 2, (u8 *)&dat); +} + +static void ad5933_calc_out_ranges(struct ad5933_state *st) +{ + int i; + unsigned normalized_3v3[4] = {1980, 198, 383, 970}; + + for (i = 0; i < 4; i++) + st->range_avail[i] = normalized_3v3[i] * st->vref_mv / 3300; + +} + +/* + * handles: AD5933_REG_FREQ_START and AD5933_REG_FREQ_INC + */ + +static ssize_t ad5933_show_frequency(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad5933_state *st = iio_priv(dev_info); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int ret; + unsigned long long freqreg; + union { + u32 d32; + u8 d8[4]; + } dat; + + mutex_lock(&dev_info->mlock); + ret = ad5933_i2c_read(st->client, this_attr->address, 3, &dat.d8[1]); + mutex_unlock(&dev_info->mlock); + if (ret < 0) + return ret; + + freqreg = be32_to_cpu(dat.d32) & 0xFFFFFF; + + freqreg = (u64) freqreg * (u64) (st->mclk_hz / 4); + do_div(freqreg, 1 << 27); + + return sprintf(buf, "%d\n", (int) freqreg); +} + +static ssize_t ad5933_store_frequency(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad5933_state *st = iio_priv(dev_info); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + long val; + int ret; + + ret = strict_strtoul(buf, 10, &val); + if (ret) + return ret; + + if (val > AD5933_MAX_OUTPUT_FREQ_Hz) + return -EINVAL; + + mutex_lock(&dev_info->mlock); + ret = ad5933_set_freq(st, this_attr->address, val); + mutex_unlock(&dev_info->mlock); + + return ret ? ret : len; +} + +static IIO_DEVICE_ATTR(out0_freq_start, S_IRUGO | S_IWUSR, + ad5933_show_frequency, + ad5933_store_frequency, + AD5933_REG_FREQ_START); + +static IIO_DEVICE_ATTR(out0_freq_increment, S_IRUGO | S_IWUSR, + ad5933_show_frequency, + ad5933_store_frequency, + AD5933_REG_FREQ_INC); + +static ssize_t ad5933_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad5933_state *st = iio_priv(dev_info); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int ret = 0, len = 0; + + mutex_lock(&dev_info->mlock); + switch (this_attr->address) { + case AD5933_OUT_RANGE: + len = sprintf(buf, "%d\n", + st->range_avail[(st->ctrl_hb >> 1) & 0x3]); + break; + case AD5933_OUT_RANGE_AVAIL: + len = sprintf(buf, "%d %d %d %d\n", st->range_avail[0], + st->range_avail[3], st->range_avail[2], + st->range_avail[1]); + break; + case AD5933_OUT_SETTLING_CYCLES: + len = sprintf(buf, "%d\n", st->settling_cycles); + break; + case AD5933_IN_PGA_GAIN: + len = sprintf(buf, "%s\n", + (st->ctrl_hb & AD5933_CTRL_PGA_GAIN_1) ? + "1" : "0.2"); + break; + case AD5933_IN_PGA_GAIN_AVAIL: + len = sprintf(buf, "1 0.2\n"); + break; + case AD5933_FREQ_POINTS: + len = sprintf(buf, "%d\n", st->freq_points); + break; + default: + ret = -EINVAL; + } + + mutex_unlock(&dev_info->mlock); + return ret ? ret : len; +} + +static ssize_t ad5933_store(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad5933_state *st = iio_priv(dev_info); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + long val; + int i, ret = 0; + unsigned short dat; + + if (this_attr->address != AD5933_IN_PGA_GAIN) { + ret = strict_strtol(buf, 10, &val); + if (ret) + return ret; + } + + mutex_lock(&dev_info->mlock); + switch (this_attr->address) { + case AD5933_OUT_RANGE: + for (i = 0; i < 4; i++) + if (val == st->range_avail[i]) { + st->ctrl_hb &= ~AD5933_CTRL_RANGE(0x3); + st->ctrl_hb |= AD5933_CTRL_RANGE(i); + ret = ad5933_cmd(st, 0); + break; + } + ret = -EINVAL; + break; + case AD5933_IN_PGA_GAIN: + if (sysfs_streq(buf, "1")) { + st->ctrl_hb |= AD5933_CTRL_PGA_GAIN_1; + } else if (sysfs_streq(buf, "0.2")) { + st->ctrl_hb &= ~AD5933_CTRL_PGA_GAIN_1; + } else { + ret = -EINVAL; + break; + } + ret = ad5933_cmd(st, 0); + break; + case AD5933_OUT_SETTLING_CYCLES: + val = clamp(val, 0L, 0x7FFL); + st->settling_cycles = val; + + /* 2x, 4x handling, see datasheet */ + if (val > 511) + val = (val >> 1) | (1 << 9); + else if (val > 1022) + val = (val >> 2) | (3 << 9); + + dat = cpu_to_be16(val); + ret = ad5933_i2c_write(st->client, + AD5933_REG_SETTLING_CYCLES, 2, (u8 *)&dat); + break; + case AD5933_FREQ_POINTS: + val = clamp(val, 0L, 511L); + st->freq_points = val; + + dat = cpu_to_be16(val); + ret = ad5933_i2c_write(st->client, AD5933_REG_INC_NUM, 2, + (u8 *)&dat); + break; + default: + ret = -EINVAL; + } + + mutex_unlock(&dev_info->mlock); + return ret ? ret : len; +} + +static IIO_DEVICE_ATTR(out0_scale, S_IRUGO | S_IWUSR, + ad5933_show, + ad5933_store, + AD5933_OUT_RANGE); + +static IIO_DEVICE_ATTR(out0_scale_available, S_IRUGO, + ad5933_show, + NULL, + AD5933_OUT_RANGE_AVAIL); + +static IIO_DEVICE_ATTR(in0_scale, S_IRUGO | S_IWUSR, + ad5933_show, + ad5933_store, + AD5933_IN_PGA_GAIN); + +static IIO_DEVICE_ATTR(in0_scale_available, S_IRUGO, + ad5933_show, + NULL, + AD5933_IN_PGA_GAIN_AVAIL); + +static IIO_DEVICE_ATTR(out0_freq_points, S_IRUGO | S_IWUSR, + ad5933_show, + ad5933_store, + AD5933_FREQ_POINTS); + +static IIO_DEVICE_ATTR(out0_settling_cycles, S_IRUGO | S_IWUSR, + ad5933_show, + ad5933_store, + AD5933_OUT_SETTLING_CYCLES); + +/* note: + * ideally we would handle the scale attributes via the iio_info + * (read|write)_raw methods, however this part is a untypical since we + * don't create dedicated sysfs channel attributes for out0 and in0. + */ +static struct attribute *ad5933_attributes[] = { + &iio_dev_attr_out0_scale.dev_attr.attr, + &iio_dev_attr_out0_scale_available.dev_attr.attr, + &iio_dev_attr_out0_freq_start.dev_attr.attr, + &iio_dev_attr_out0_freq_increment.dev_attr.attr, + &iio_dev_attr_out0_freq_points.dev_attr.attr, + &iio_dev_attr_out0_settling_cycles.dev_attr.attr, + &iio_dev_attr_in0_scale.dev_attr.attr, + &iio_dev_attr_in0_scale_available.dev_attr.attr, + NULL +}; + +static const struct attribute_group ad5933_attribute_group = { + .attrs = ad5933_attributes, +}; + +static int ad5933_read_raw(struct iio_dev *dev_info, + struct iio_chan_spec const *chan, + int *val, + int *val2, + long m) +{ + struct ad5933_state *st = iio_priv(dev_info); + unsigned short dat; + int ret = -EINVAL; + + mutex_lock(&dev_info->mlock); + switch (m) { + case 0: + if (iio_ring_enabled(dev_info)) { + ret = -EBUSY; + goto out; + } + ret = ad5933_cmd(st, AD5933_CTRL_MEASURE_TEMP); + if (ret < 0) + goto out; + ret = ad5933_wait_busy(st, AD5933_STAT_TEMP_VALID); + if (ret < 0) + goto out; + + ret = ad5933_i2c_read(st->client, + AD5933_REG_TEMP_DATA, 2, + (u8 *)&dat); + if (ret < 0) + goto out; + mutex_unlock(&dev_info->mlock); + ret = be16_to_cpu(dat); + /* Temp in Milli degrees Celsius */ + if (ret < 8192) + *val = ret * 1000 / 32; + else + *val = (ret - 16384) * 1000 / 32; + + return IIO_VAL_INT; + } + +out: + mutex_unlock(&dev_info->mlock); + return ret; +} + +static const struct iio_info ad5933_info = { + .read_raw = &ad5933_read_raw, + .attrs = &ad5933_attribute_group, + .driver_module = THIS_MODULE, +}; + +static int ad5933_ring_preenable(struct iio_dev *indio_dev) +{ + struct ad5933_state *st = iio_priv(indio_dev); + struct iio_ring_buffer *ring = indio_dev->ring; + size_t d_size; + int ret; + + if (!ring->scan_count) + return -EINVAL; + + d_size = ring->scan_count * + ad5933_channels[1].scan_type.storagebits / 8; + + if (indio_dev->ring->access->set_bytes_per_datum) + indio_dev->ring->access->set_bytes_per_datum(indio_dev->ring, + d_size); + + ret = ad5933_reset(st); + if (ret < 0) + return ret; + + ret = ad5933_cmd(st, AD5933_CTRL_STANDBY); + if (ret < 0) + return ret; + + ret = ad5933_cmd(st, AD5933_CTRL_INIT_START_FREQ); + if (ret < 0) + return ret; + + st->state = AD5933_CTRL_INIT_START_FREQ; + + return 0; +} + +static int ad5933_ring_postenable(struct iio_dev *indio_dev) +{ + struct ad5933_state *st = iio_priv(indio_dev); + + /* AD5933_CTRL_INIT_START_FREQ: + * High Q complex circuits require a long time to reach steady state. + * To facilitate the measurement of such impedances, this mode allows + * the user full control of the settling time requirement before + * entering start frequency sweep mode where the impedance measurement + * takes place. In this mode the impedance is excited with the + * programmed start frequency (ad5933_ring_preenable), + * but no measurement takes place. + */ + + schedule_delayed_work(&st->work, + msecs_to_jiffies(AD5933_INIT_EXCITATION_TIME_ms)); + return 0; +} + +static int ad5933_ring_postdisable(struct iio_dev *indio_dev) +{ + struct ad5933_state *st = iio_priv(indio_dev); + + cancel_delayed_work_sync(&st->work); + return ad5933_cmd(st, AD5933_CTRL_POWER_DOWN); +} + +static const struct iio_ring_setup_ops ad5933_ring_setup_ops = { + .preenable = &ad5933_ring_preenable, + .postenable = &ad5933_ring_postenable, + .postdisable = &ad5933_ring_postdisable, +}; + +static int ad5933_register_ring_funcs_and_init(struct iio_dev *indio_dev) +{ + indio_dev->ring = iio_sw_rb_allocate(indio_dev); + if (!indio_dev->ring) + return -ENOMEM; + + /* Effectively select the ring buffer implementation */ + indio_dev->ring->access = &ring_sw_access_funcs; + + /* Ring buffer functions - here trigger setup related */ + indio_dev->ring->setup_ops = &ad5933_ring_setup_ops; + + indio_dev->modes |= INDIO_RING_HARDWARE_BUFFER; + + return 0; +} + +static void ad5933_work(struct work_struct *work) +{ + struct ad5933_state *st = container_of(work, + struct ad5933_state, work.work); + struct iio_dev *indio_dev = i2c_get_clientdata(st->client); + struct iio_ring_buffer *ring = indio_dev->ring; + signed short buf[2]; + unsigned char status; + + mutex_lock(&indio_dev->mlock); + if (st->state == AD5933_CTRL_INIT_START_FREQ) { + /* start sweep */ + ad5933_cmd(st, AD5933_CTRL_START_SWEEP); + st->state = AD5933_CTRL_START_SWEEP; + schedule_delayed_work(&st->work, st->poll_time_jiffies); + mutex_unlock(&indio_dev->mlock); + return; + } + + ad5933_i2c_read(st->client, AD5933_REG_STATUS, 1, &status); + + if (status & AD5933_STAT_DATA_VALID) { + ad5933_i2c_read(st->client, + (ring->scan_mask & (1 << 0)) ? + AD5933_REG_REAL_DATA : AD5933_REG_IMAG_DATA, + ring->scan_count * 2, (u8 *)buf); + + if (ring->scan_count == 2) { + buf[0] = be16_to_cpu(buf[0]); + buf[1] = be16_to_cpu(buf[1]); + } else { + buf[0] = be16_to_cpu(buf[0]); + } + /* save datum to the ring */ + ring->access->store_to(ring, (u8 *)buf, iio_get_time_ns()); + } else { + /* no data available - try again later */ + schedule_delayed_work(&st->work, st->poll_time_jiffies); + mutex_unlock(&indio_dev->mlock); + return; + } + + if (status & AD5933_STAT_SWEEP_DONE) { + /* last sample received - power down do nothing until + * the ring enable is toggled */ + ad5933_cmd(st, AD5933_CTRL_POWER_DOWN); + } else { + /* we just received a valid datum, move on to the next */ + ad5933_cmd(st, AD5933_CTRL_INC_FREQ); + schedule_delayed_work(&st->work, st->poll_time_jiffies); + } + + mutex_unlock(&indio_dev->mlock); +} + +static int __devinit ad5933_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int ret, regdone = 0, voltage_uv = 0; + struct ad5933_platform_data *pdata = client->dev.platform_data; + struct ad5933_state *st; + struct iio_dev *indio_dev = iio_allocate_device(sizeof(*st)); + if (indio_dev == NULL) + return -ENOMEM; + + st = iio_priv(indio_dev); + i2c_set_clientdata(client, indio_dev); + st->client = client; + + if (!pdata) + st->pdata = &ad5933_default_pdata; + else + st->pdata = pdata; + + st->reg = regulator_get(&client->dev, "vcc"); + if (!IS_ERR(st->reg)) { + ret = regulator_enable(st->reg); + if (ret) + goto error_put_reg; + voltage_uv = regulator_get_voltage(st->reg); + } + + if (voltage_uv) + st->vref_mv = voltage_uv / 1000; + else + st->vref_mv = st->pdata->vref_mv; + + if (st->pdata->ext_clk_Hz) { + st->mclk_hz = st->pdata->ext_clk_Hz; + st->ctrl_lb = AD5933_CTRL_EXT_SYSCLK; + } else { + st->mclk_hz = AD5933_INT_OSC_FREQ_Hz; + st->ctrl_lb = AD5933_CTRL_INT_SYSCLK; + } + + ad5933_calc_out_ranges(st); + INIT_DELAYED_WORK(&st->work, ad5933_work); + st->poll_time_jiffies = msecs_to_jiffies(AD5933_POLL_TIME_ms); + + indio_dev->dev.parent = &client->dev; + indio_dev->info = &ad5933_info; + indio_dev->name = id->name; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = ad5933_channels; + indio_dev->num_channels = 1; /* only register temp0_input */ + + ret = ad5933_register_ring_funcs_and_init(indio_dev); + if (ret) + goto error_disable_reg; + + ret = iio_device_register(indio_dev); + if (ret) + goto error_unreg_ring; + regdone = 1; + + /* skip temp0_input, register in0_(real|imag)_raw */ + ret = iio_ring_buffer_register_ex(indio_dev->ring, 0, + &ad5933_channels[1], + 2); + if (ret) + goto error_unreg_ring; + + /* enable both REAL and IMAG channels by default */ + iio_scan_mask_set(indio_dev->ring, 0); + iio_scan_mask_set(indio_dev->ring, 1); + + ret = ad5933_setup(st); + if (ret) + goto error_uninitialize_ring; + + return 0; + +error_uninitialize_ring: + iio_ring_buffer_unregister(indio_dev->ring); +error_unreg_ring: + iio_sw_rb_free(indio_dev->ring); +error_disable_reg: + if (!IS_ERR(st->reg)) + regulator_disable(st->reg); +error_put_reg: + if (!IS_ERR(st->reg)) + regulator_put(st->reg); + + if (regdone) + iio_device_unregister(indio_dev); + else + iio_free_device(indio_dev); + + return ret; +} + +static __devexit int ad5933_remove(struct i2c_client *client) +{ + struct iio_dev *indio_dev = i2c_get_clientdata(client); + struct ad5933_state *st = iio_priv(indio_dev); + + iio_ring_buffer_unregister(indio_dev->ring); + iio_sw_rb_free(indio_dev->ring); + if (!IS_ERR(st->reg)) { + regulator_disable(st->reg); + regulator_put(st->reg); + } + iio_device_unregister(indio_dev); + + return 0; +} + +static const struct i2c_device_id ad5933_id[] = { + { "ad5933", 0 }, + { "ad5934", 0 }, + {} +}; + +MODULE_DEVICE_TABLE(i2c, ad5933_id); + +static struct i2c_driver ad5933_driver = { + .driver = { + .name = "ad5933", + }, + .probe = ad5933_probe, + .remove = __devexit_p(ad5933_remove), + .id_table = ad5933_id, +}; + +static __init int ad5933_init(void) +{ + return i2c_add_driver(&ad5933_driver); +} +module_init(ad5933_init); + +static __exit void ad5933_exit(void) +{ + i2c_del_driver(&ad5933_driver); +} +module_exit(ad5933_exit); + +MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); +MODULE_DESCRIPTION("Analog Devices AD5933 Impedance Conv. Network Analyzer"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/impedance-analyzer/ad5933.h b/drivers/staging/iio/impedance-analyzer/ad5933.h new file mode 100644 index 0000000..b140e42 --- /dev/null +++ b/drivers/staging/iio/impedance-analyzer/ad5933.h @@ -0,0 +1,28 @@ +/* + * AD5933 AD5934 Impedance Converter, Network Analyzer + * + * Copyright 2011 Analog Devices Inc. + * + * Licensed under the GPL-2. + */ + +#ifndef IIO_ADC_AD5933_H_ +#define IIO_ADC_AD5933_H_ + +/* + * TODO: struct ad5933_platform_data needs to go into include/linux/iio + */ + +/** + * struct ad5933_platform_data - platform specific data + * @ext_clk_Hz: the external clock frequency in Hz, if not set + * the driver uses the internal clock (16.776 MHz) + * @vref_mv: the external reference voltage in millivolt + */ + +struct ad5933_platform_data { + unsigned long ext_clk_Hz; + unsigned short vref_mv; +}; + +#endif /* IIO_ADC_AD5933_H_ */ diff --git a/drivers/staging/iio/imu/adis16400_core.c b/drivers/staging/iio/imu/adis16400_core.c index a2c3b67..58a29b1 100644 --- a/drivers/staging/iio/imu/adis16400_core.c +++ b/drivers/staging/iio/imu/adis16400_core.c @@ -25,21 +25,18 @@ #include <linux/slab.h> #include <linux/sysfs.h> #include <linux/list.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" #include "../ring_generic.h" -#include "../accel/accel.h" -#include "../adc/adc.h" -#include "../gyro/gyro.h" -#include "../magnetometer/magnet.h" - #include "adis16400.h" #define DRIVER_NAME "adis16400" enum adis16400_chip_variant { ADIS16300, + ADIS16344, ADIS16350, ADIS16360, ADIS16362, @@ -150,8 +147,6 @@ static int adis16400_spi_read_reg_16(struct iio_dev *indio_dev, mutex_lock(&st->buf_lock); st->tx[0] = ADIS16400_READ_REG(lower_reg_address); st->tx[1] = 0; - st->tx[2] = 0; - st->tx[3] = 0; spi_message_init(&msg); spi_message_add_tail(&xfers[0], &msg); @@ -240,17 +235,18 @@ static ssize_t adis16400_write_reset(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); + bool val; + int ret; - if (len < 1) - return -1; - switch (buf[0]) { - case '1': - case 'y': - case 'Y': - return adis16400_reset(indio_dev); - } - return -1; + ret = strtobool(buf, &val); + if (ret < 0) + return ret; + if (val) + ret = adis16400_reset(dev_get_drvdata(dev)); + if (ret < 0) + return ret; + + return len; } int adis16400_set_irq(struct iio_dev *indio_dev, bool enable) @@ -695,6 +691,38 @@ static struct iio_chan_spec adis16300_channels[] = { IIO_CHAN_SOFT_TIMESTAMP(14) }; +static const struct iio_chan_spec adis16344_channels[] = { + IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, IIO_MOD_X, + (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | + (1 << IIO_CHAN_INFO_SCALE_SHARED), + gyro_x, ADIS16400_SCAN_GYRO_X, IIO_ST('s', 14, 16, 0), 0), + IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, IIO_MOD_Y, + (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | + (1 << IIO_CHAN_INFO_SCALE_SHARED), + gyro_y, ADIS16400_SCAN_GYRO_Y, IIO_ST('s', 14, 16, 0), 0), + IIO_CHAN(IIO_GYRO, 1, 0, 0, NULL, 0, IIO_MOD_Z, + (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | + (1 << IIO_CHAN_INFO_SCALE_SHARED), + gyro_z, ADIS16400_SCAN_GYRO_Z, IIO_ST('s', 14, 16, 0), 0), + IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_X, + (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | + (1 << IIO_CHAN_INFO_SCALE_SHARED), + accel_x, ADIS16400_SCAN_ACC_X, IIO_ST('s', 14, 16, 0), 0), + IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Y, + (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | + (1 << IIO_CHAN_INFO_SCALE_SHARED), + accel_y, ADIS16400_SCAN_ACC_Y, IIO_ST('s', 14, 16, 0), 0), + IIO_CHAN(IIO_ACCEL, 1, 0, 0, NULL, 0, IIO_MOD_Z, + (1 << IIO_CHAN_INFO_CALIBBIAS_SEPARATE) | + (1 << IIO_CHAN_INFO_SCALE_SHARED), + accel_z, ADIS16400_SCAN_ACC_Z, IIO_ST('s', 14, 16, 0), 0), + IIO_CHAN(IIO_TEMP, 0, 1, 0, NULL, 0, 0, + (1 << IIO_CHAN_INFO_OFFSET_SEPARATE) | + (1 << IIO_CHAN_INFO_SCALE_SEPARATE), + temp0, ADIS16350_SCAN_TEMP_X, IIO_ST('s', 12, 16, 0), 0), + IIO_CHAN_SOFT_TIMESTAMP(12) +}; + static struct attribute *adis16400_attributes[] = { &iio_dev_attr_sampling_frequency.dev_attr.attr, &iio_const_attr_sampling_frequency_available.dev_attr.attr, @@ -719,6 +747,16 @@ static struct adis16400_chip_info adis16400_chips[] = { (1 << ADIS16300_SCAN_INCLI_X) | (1 << ADIS16300_SCAN_INCLI_Y) | (1 << 14), }, + [ADIS16344] = { + .channels = adis16344_channels, + .num_channels = ARRAY_SIZE(adis16344_channels), + .gyro_scale_micro = 873, + .accel_scale_micro = 981, + .default_scan_mask = (1 << ADIS16400_SCAN_GYRO_X) | + (1 << ADIS16400_SCAN_GYRO_Y) | (1 << ADIS16400_SCAN_GYRO_Z) | + (1 << ADIS16400_SCAN_ACC_X) | (1 << ADIS16400_SCAN_ACC_Y) | + (1 << ADIS16400_SCAN_ACC_Z), + }, [ADIS16350] = { .channels = adis16350_channels, .num_channels = ARRAY_SIZE(adis16350_channels), @@ -874,6 +912,7 @@ err_ret: static const struct spi_device_id adis16400_id[] = { {"adis16300", ADIS16300}, + {"adis16344", ADIS16344}, {"adis16350", ADIS16350}, {"adis16354", ADIS16350}, {"adis16355", ADIS16350}, diff --git a/drivers/staging/iio/imu/adis16400_ring.c b/drivers/staging/iio/imu/adis16400_ring.c index 3612373..3fc2403 100644 --- a/drivers/staging/iio/imu/adis16400_ring.c +++ b/drivers/staging/iio/imu/adis16400_ring.c @@ -1,21 +1,13 @@ #include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/gpio.h> -#include <linux/workqueue.h> #include <linux/mutex.h> -#include <linux/device.h> #include <linux/kernel.h> #include <linux/spi/spi.h> #include <linux/slab.h> -#include <linux/sysfs.h> -#include <linux/list.h> #include <linux/bitops.h> #include "../iio.h" -#include "../sysfs.h" #include "../ring_sw.h" -#include "../accel/accel.h" -#include "../trigger.h" +#include "../trigger_consumer.h" #include "adis16400.h" /** @@ -119,7 +111,7 @@ static int adis16350_spi_read_all(struct device *dev, u8 *rx) static irqreturn_t adis16400_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->private_data; + struct iio_dev *indio_dev = pf->indio_dev; struct adis16400_state *st = iio_priv(indio_dev); struct iio_ring_buffer *ring = indio_dev->ring; int i = 0, j, ret = 0; diff --git a/drivers/staging/iio/imu/adis16400_trigger.c b/drivers/staging/iio/imu/adis16400_trigger.c index c6ec41a..3860d92 100644 --- a/drivers/staging/iio/imu/adis16400_trigger.c +++ b/drivers/staging/iio/imu/adis16400_trigger.c @@ -1,14 +1,8 @@ #include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/mutex.h> -#include <linux/device.h> #include <linux/kernel.h> -#include <linux/sysfs.h> -#include <linux/list.h> #include <linux/spi/spi.h> #include "../iio.h" -#include "../sysfs.h" #include "../trigger.h" #include "adis16400.h" @@ -24,6 +18,11 @@ static int adis16400_data_rdy_trigger_set_state(struct iio_trigger *trig, return adis16400_set_irq(indio_dev, state); } +static const struct iio_trigger_ops adis16400_trigger_ops = { + .owner = THIS_MODULE, + .set_trigger_state = &adis16400_data_rdy_trigger_set_state, +}; + int adis16400_probe_trigger(struct iio_dev *indio_dev) { int ret; @@ -45,9 +44,8 @@ int adis16400_probe_trigger(struct iio_dev *indio_dev) if (ret) goto error_free_trig; st->trig->dev.parent = &st->us->dev; - st->trig->owner = THIS_MODULE; st->trig->private_data = indio_dev; - st->trig->set_trigger_state = &adis16400_data_rdy_trigger_set_state; + st->trig->ops = &adis16400_trigger_ops; ret = iio_trigger_register(st->trig); /* select default trigger */ diff --git a/drivers/staging/iio/industrialio-core.c b/drivers/staging/iio/industrialio-core.c index 19819e7..ed8a6df 100644 --- a/drivers/staging/iio/industrialio-core.c +++ b/drivers/staging/iio/industrialio-core.c @@ -22,7 +22,8 @@ #include <linux/cdev.h> #include <linux/slab.h> #include "iio.h" -#include "trigger_consumer.h" +#include "iio_core.h" +#include "iio_core_trigger.h" #define IIO_ID_PREFIX "device" #define IIO_ID_FORMAT IIO_ID_PREFIX "%d" @@ -35,7 +36,6 @@ static DEFINE_IDA(iio_chrdev_ida); static DEFINE_SPINLOCK(iio_ida_lock); dev_t iio_devt; -EXPORT_SYMBOL(iio_devt); #define IIO_DEV_MAX 256 struct bus_type iio_bus_type = { @@ -85,8 +85,38 @@ static const char * const iio_chan_info_postfix[] = { [IIO_CHAN_INFO_CALIBBIAS_SHARED/2] = "calibbias", [IIO_CHAN_INFO_PEAK_SHARED/2] = "peak_raw", [IIO_CHAN_INFO_PEAK_SCALE_SHARED/2] = "peak_scale", + [IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW_SHARED/2] + = "quadrature_correction_raw", }; +/* Return a negative errno on failure */ +static int iio_get_new_ida_val(struct ida *this_ida) +{ + int ret; + int val; + +ida_again: + if (unlikely(ida_pre_get(this_ida, GFP_KERNEL) == 0)) + return -ENOMEM; + + spin_lock(&iio_ida_lock); + ret = ida_get_new(this_ida, &val); + spin_unlock(&iio_ida_lock); + if (unlikely(ret == -EAGAIN)) + goto ida_again; + else if (unlikely(ret)) + return ret; + + return val; +} + +static void iio_free_ida_val(struct ida *this_ida, int id) +{ + spin_lock(&iio_ida_lock); + ida_remove(this_ida, id); + spin_unlock(&iio_ida_lock); +} + int iio_push_event(struct iio_dev *dev_info, int ev_line, int ev_code, @@ -246,28 +276,18 @@ static struct device_type iio_event_type = { int iio_device_get_chrdev_minor(void) { - int ret, val; + int ret; -ida_again: - if (unlikely(ida_pre_get(&iio_chrdev_ida, GFP_KERNEL) == 0)) - return -ENOMEM; - spin_lock(&iio_ida_lock); - ret = ida_get_new(&iio_chrdev_ida, &val); - spin_unlock(&iio_ida_lock); - if (unlikely(ret == -EAGAIN)) - goto ida_again; - else if (unlikely(ret)) + ret = iio_get_new_ida_val(&iio_chrdev_ida); + if (ret < IIO_DEV_MAX) /* both errors and valid */ return ret; - if (val > IIO_DEV_MAX) + else return -ENOMEM; - return val; } void iio_device_free_chrdev_minor(int val) { - spin_lock(&iio_ida_lock); - ida_remove(&iio_chrdev_ida, val); - spin_unlock(&iio_ida_lock); + iio_free_ida_val(&iio_chrdev_ida, val); } static int iio_setup_ev_int(struct iio_event_interface *ev_int, @@ -329,24 +349,6 @@ static void iio_free_ev_int(struct iio_event_interface *ev_int) put_device(&ev_int->dev); } -static int __init iio_dev_init(void) -{ - int err; - - err = alloc_chrdev_region(&iio_devt, 0, IIO_DEV_MAX, "iio"); - if (err < 0) - printk(KERN_ERR "%s: failed to allocate char dev region\n", - __FILE__); - - return err; -} - -static void __exit iio_dev_exit(void) -{ - if (iio_devt) - unregister_chrdev_region(iio_devt, IIO_DEV_MAX); -} - static int __init iio_init(void) { int ret; @@ -360,9 +362,12 @@ static int __init iio_init(void) goto error_nothing; } - ret = iio_dev_init(); - if (ret < 0) + ret = alloc_chrdev_region(&iio_devt, 0, IIO_DEV_MAX, "iio"); + if (ret < 0) { + printk(KERN_ERR "%s: failed to allocate char dev region\n", + __FILE__); goto error_unregister_bus_type; + } return 0; @@ -374,7 +379,8 @@ error_nothing: static void __exit iio_exit(void) { - iio_dev_exit(); + if (iio_devt) + unregister_chrdev_region(iio_devt, IIO_DEV_MAX); bus_unregister(&iio_bus_type); } @@ -524,6 +530,7 @@ static int __iio_build_postfix(struct iio_chan_spec const *chan, return 0; } +static int __iio_device_attr_init(struct device_attribute *dev_attr, const char *postfix, struct iio_chan_spec const *chan, @@ -596,7 +603,7 @@ error_ret: return ret; } -void __iio_device_attr_deinit(struct device_attribute *dev_attr) +static void __iio_device_attr_deinit(struct device_attribute *dev_attr) { kfree(dev_attr->attr.name); } @@ -725,19 +732,29 @@ static ssize_t iio_show_dev_name(struct device *dev, static DEVICE_ATTR(name, S_IRUGO, iio_show_dev_name, NULL); +static struct attribute *iio_base_dummy_attrs[] = { + NULL +}; +static struct attribute_group iio_base_dummy_group = { + .attrs = iio_base_dummy_attrs, +}; + static int iio_device_register_sysfs(struct iio_dev *dev_info) { int i, ret = 0; struct iio_dev_attr *p, *n; - if (dev_info->info->attrs) { + if (dev_info->info->attrs) ret = sysfs_create_group(&dev_info->dev.kobj, dev_info->info->attrs); - if (ret) { - dev_err(dev_info->dev.parent, - "Failed to register sysfs hooks\n"); - goto error_ret; - } + else + ret = sysfs_create_group(&dev_info->dev.kobj, + &iio_base_dummy_group); + + if (ret) { + dev_err(dev_info->dev.parent, + "Failed to register sysfs hooks\n"); + goto error_ret; } /* @@ -753,7 +770,7 @@ static int iio_device_register_sysfs(struct iio_dev *dev_info) if (ret < 0) goto error_clear_attrs; } - if (dev_info->name) { + if (dev_info->name) { ret = sysfs_add_file_to_group(&dev_info->dev.kobj, &dev_attr_name.attr, NULL); @@ -770,6 +787,8 @@ error_clear_attrs: } if (dev_info->info->attrs) sysfs_remove_group(&dev_info->dev.kobj, dev_info->info->attrs); + else + sysfs_remove_group(&dev_info->dev.kobj, &iio_base_dummy_group); error_ret: return ret; @@ -790,38 +809,10 @@ static void iio_device_unregister_sysfs(struct iio_dev *dev_info) if (dev_info->info->attrs) sysfs_remove_group(&dev_info->dev.kobj, dev_info->info->attrs); + else + sysfs_remove_group(&dev_info->dev.kobj, &iio_base_dummy_group); } -/* Return a negative errno on failure */ -int iio_get_new_ida_val(struct ida *this_ida) -{ - int ret; - int val; - -ida_again: - if (unlikely(ida_pre_get(this_ida, GFP_KERNEL) == 0)) - return -ENOMEM; - - spin_lock(&iio_ida_lock); - ret = ida_get_new(this_ida, &val); - spin_unlock(&iio_ida_lock); - if (unlikely(ret == -EAGAIN)) - goto ida_again; - else if (unlikely(ret)) - return ret; - - return val; -} -EXPORT_SYMBOL(iio_get_new_ida_val); - -void iio_free_ida_val(struct ida *this_ida, int id) -{ - spin_lock(&iio_ida_lock); - ida_remove(this_ida, id); - spin_unlock(&iio_ida_lock); -} -EXPORT_SYMBOL(iio_free_ida_val); - static const char * const iio_ev_type_text[] = { [IIO_EV_TYPE_THRESH] = "thresh", [IIO_EV_TYPE_MAG] = "mag", @@ -911,7 +902,7 @@ static int iio_device_add_event_sysfs(struct iio_dev *dev_info, struct iio_chan_spec const *chan) { - int ret = 0, i, mask; + int ret = 0, i, mask = 0; char *postfix; if (!chan->event_mask) return 0; @@ -944,6 +935,7 @@ static int iio_device_add_event_sysfs(struct iio_dev *dev_info, break; default: printk(KERN_INFO "currently unhandled type of event\n"); + continue; } ret = __iio_add_chan_devattr(postfix, NULL, @@ -989,18 +981,17 @@ error_ret: return ret; } -static inline void __iio_remove_all_event_sysfs(struct iio_dev *dev_info, - const char *groupname, - int num) +static inline void __iio_remove_event_config_attrs(struct iio_dev *dev_info, + int i) { struct iio_dev_attr *p, *n; list_for_each_entry_safe(p, n, - &dev_info->event_interfaces[num]. + &dev_info->event_interfaces[i]. dev_attr_list, l) { sysfs_remove_file_from_group(&dev_info - ->event_interfaces[num].dev.kobj, + ->event_interfaces[i].dev.kobj, &p->dev_attr.attr, - groupname); + NULL); kfree(p->dev_attr.attr.name); kfree(p); } @@ -1010,7 +1001,7 @@ static inline int __iio_add_event_config_attrs(struct iio_dev *dev_info, int i) { int j; int ret; - INIT_LIST_HEAD(&dev_info->event_interfaces[0].dev_attr_list); + INIT_LIST_HEAD(&dev_info->event_interfaces[i].dev_attr_list); /* Dynically created from the channels array */ if (dev_info->channels) { for (j = 0; j < dev_info->num_channels; j++) { @@ -1024,18 +1015,11 @@ static inline int __iio_add_event_config_attrs(struct iio_dev *dev_info, int i) return 0; error_clear_attrs: - __iio_remove_all_event_sysfs(dev_info, NULL, i); + __iio_remove_event_config_attrs(dev_info, i); return ret; } -static inline int __iio_remove_event_config_attrs(struct iio_dev *dev_info, - int i) -{ - __iio_remove_all_event_sysfs(dev_info, NULL, i); - return 0; -} - static int iio_device_register_eventset(struct iio_dev *dev_info) { int ret = 0, i, j; @@ -1061,7 +1045,7 @@ static int iio_device_register_eventset(struct iio_dev *dev_info) if (ret) { dev_err(&dev_info->dev, "Could not get chrdev interface\n"); - goto error_free_setup_ev_ints; + goto error_free_setup_event_lines; } dev_set_drvdata(&dev_info->event_interfaces[i].dev, @@ -1077,31 +1061,33 @@ static int iio_device_register_eventset(struct iio_dev *dev_info) if (ret) { dev_err(&dev_info->dev, "Failed to register sysfs for event attrs"); - goto error_remove_sysfs_interfaces; + iio_free_ev_int(&dev_info->event_interfaces[i]); + goto error_free_setup_event_lines; } - } - - for (i = 0; i < dev_info->info->num_interrupt_lines; i++) { ret = __iio_add_event_config_attrs(dev_info, i); - if (ret) - goto error_unregister_config_attrs; + if (ret) { + if (dev_info->info->event_attrs != NULL) + sysfs_remove_group(&dev_info + ->event_interfaces[i] + .dev.kobj, + &dev_info->info + ->event_attrs[i]); + iio_free_ev_int(&dev_info->event_interfaces[i]); + goto error_free_setup_event_lines; + } } return 0; -error_unregister_config_attrs: - for (j = 0; j < i; j++) - __iio_remove_event_config_attrs(dev_info, i); - i = dev_info->info->num_interrupt_lines - 1; -error_remove_sysfs_interfaces: - for (j = 0; j < i; j++) +error_free_setup_event_lines: + for (j = 0; j < i; j++) { + __iio_remove_event_config_attrs(dev_info, j); if (dev_info->info->event_attrs != NULL) sysfs_remove_group(&dev_info - ->event_interfaces[j].dev.kobj, - &dev_info->info->event_attrs[j]); -error_free_setup_ev_ints: - for (j = 0; j < i; j++) + ->event_interfaces[j].dev.kobj, + &dev_info->info->event_attrs[j]); iio_free_ev_int(&dev_info->event_interfaces[j]); + } kfree(dev_info->event_interfaces); error_ret: @@ -1120,17 +1106,16 @@ static void iio_device_unregister_eventset(struct iio_dev *dev_info) sysfs_remove_group(&dev_info ->event_interfaces[i].dev.kobj, &dev_info->info->event_attrs[i]); - } - - for (i = 0; i < dev_info->info->num_interrupt_lines; i++) iio_free_ev_int(&dev_info->event_interfaces[i]); + } kfree(dev_info->event_interfaces); } static void iio_dev_release(struct device *device) { + struct iio_dev *dev_info = container_of(device, struct iio_dev, dev); iio_put(); - kfree(to_iio_dev(device)); + kfree(dev_info); } static struct device_type iio_dev_type = { diff --git a/drivers/staging/iio/industrialio-ring.c b/drivers/staging/iio/industrialio-ring.c index 843eb82..dce50b1 100644 --- a/drivers/staging/iio/industrialio-ring.c +++ b/drivers/staging/iio/industrialio-ring.c @@ -21,6 +21,7 @@ #include <linux/poll.h> #include "iio.h" +#include "iio_core.h" #include "ring_generic.h" /** diff --git a/drivers/staging/iio/industrialio-trigger.c b/drivers/staging/iio/industrialio-trigger.c index 90ca2df..f1ece86 100644 --- a/drivers/staging/iio/industrialio-trigger.c +++ b/drivers/staging/iio/industrialio-trigger.c @@ -8,7 +8,6 @@ */ #include <linux/kernel.h> -#include <linux/module.h> #include <linux/idr.h> #include <linux/err.h> #include <linux/device.h> @@ -18,6 +17,8 @@ #include "iio.h" #include "trigger.h" +#include "iio_core.h" +#include "iio_core_trigger.h" #include "trigger_consumer.h" /* RFC - Question of approach @@ -173,13 +174,12 @@ static struct iio_trigger *iio_trigger_find_by_name(const char *name, void iio_trigger_poll(struct iio_trigger *trig, s64 time) { int i; - if (!trig->use_count) { + if (!trig->use_count) for (i = 0; i < CONFIG_IIO_CONSUMERS_PER_TRIGGER; i++) if (trig->subirqs[i].enabled) { trig->use_count++; generic_handle_irq(trig->subirq_base + i); } - } } EXPORT_SYMBOL(iio_trigger_poll); @@ -206,8 +206,8 @@ EXPORT_SYMBOL(iio_trigger_poll_chained); void iio_trigger_notify_done(struct iio_trigger *trig) { trig->use_count--; - if (trig->use_count == 0 && trig->try_reenable) - if (trig->try_reenable(trig)) { + if (trig->use_count == 0 && trig->ops && trig->ops->try_reenable) + if (trig->ops->try_reenable(trig)) { /* Missed and interrupt so launch new poll now */ iio_trigger_poll(trig, 0); } @@ -215,6 +215,26 @@ void iio_trigger_notify_done(struct iio_trigger *trig) EXPORT_SYMBOL(iio_trigger_notify_done); /* Trigger Consumer related functions */ +static int iio_trigger_get_irq(struct iio_trigger *trig) +{ + int ret; + mutex_lock(&trig->pool_lock); + ret = bitmap_find_free_region(trig->pool, + CONFIG_IIO_CONSUMERS_PER_TRIGGER, + ilog2(1)); + mutex_unlock(&trig->pool_lock); + if (ret >= 0) + ret += trig->subirq_base; + + return ret; +} + +static void iio_trigger_put_irq(struct iio_trigger *trig, int irq) +{ + mutex_lock(&trig->pool_lock); + clear_bit(irq - trig->subirq_base, trig->pool); + mutex_unlock(&trig->pool_lock); +} /* Complexity in here. With certain triggers (datardy) an acknowledgement * may be needed if the pollfuncs do not include the data read for the @@ -223,44 +243,45 @@ EXPORT_SYMBOL(iio_trigger_notify_done); * the relevant function is in there may be the best option. */ /* Worth protecting against double additions?*/ -int iio_trigger_attach_poll_func(struct iio_trigger *trig, - struct iio_poll_func *pf) +static int iio_trigger_attach_poll_func(struct iio_trigger *trig, + struct iio_poll_func *pf) { int ret = 0; bool notinuse = bitmap_empty(trig->pool, CONFIG_IIO_CONSUMERS_PER_TRIGGER); + /* Prevent the module being removed whilst attached to a trigger */ + __module_get(pf->indio_dev->info->driver_module); pf->irq = iio_trigger_get_irq(trig); ret = request_threaded_irq(pf->irq, pf->h, pf->thread, pf->type, pf->name, pf); - if (trig->set_trigger_state && notinuse) - ret = trig->set_trigger_state(trig, true); + if (trig->ops && trig->ops->set_trigger_state && notinuse) + ret = trig->ops->set_trigger_state(trig, true); return ret; } -EXPORT_SYMBOL(iio_trigger_attach_poll_func); -int iio_trigger_dettach_poll_func(struct iio_trigger *trig, - struct iio_poll_func *pf) +static int iio_trigger_dettach_poll_func(struct iio_trigger *trig, + struct iio_poll_func *pf) { int ret = 0; bool no_other_users = (bitmap_weight(trig->pool, CONFIG_IIO_CONSUMERS_PER_TRIGGER) == 1); - if (trig->set_trigger_state && no_other_users) { - ret = trig->set_trigger_state(trig, false); + if (trig->ops && trig->ops->set_trigger_state && no_other_users) { + ret = trig->ops->set_trigger_state(trig, false); if (ret) goto error_ret; } iio_trigger_put_irq(trig, pf->irq); free_irq(pf->irq, pf); + module_put(pf->indio_dev->info->driver_module); error_ret: return ret; } -EXPORT_SYMBOL(iio_trigger_dettach_poll_func); irqreturn_t iio_pollfunc_store_time(int irq, void *p) { @@ -274,7 +295,7 @@ struct iio_poll_func *iio_alloc_pollfunc(irqreturn_t (*h)(int irq, void *p), irqreturn_t (*thread)(int irq, void *p), int type, - void *private, + struct iio_dev *indio_dev, const char *fmt, ...) { @@ -294,7 +315,7 @@ struct iio_poll_func pf->h = h; pf->thread = thread; pf->type = type; - pf->private_data = private; + pf->indio_dev = indio_dev; return pf; } @@ -318,12 +339,10 @@ static ssize_t iio_trigger_read_current(struct device *dev, char *buf) { struct iio_dev *dev_info = dev_get_drvdata(dev); - int len = 0; + if (dev_info->trig) - len = sprintf(buf, - "%s\n", - dev_info->trig->name); - return len; + return sprintf(buf, "%s\n", dev_info->trig->name); + return 0; } /** @@ -358,8 +377,8 @@ static ssize_t iio_trigger_write_current(struct device *dev, return ret; } - if (trig && trig->validate_device) { - ret = trig->validate_device(trig, dev_info); + if (trig && trig->ops && trig->ops->validate_device) { + ret = trig->ops->validate_device(trig, dev_info); if (ret) return ret; } @@ -477,6 +496,7 @@ struct iio_trigger *iio_allocate_trigger(const char *fmt, ...) IRQ_NOPROBE); } iio_get(); + get_device(&trig->dev); } return trig; } @@ -491,20 +511,18 @@ EXPORT_SYMBOL(iio_free_trigger); int iio_device_register_trigger_consumer(struct iio_dev *dev_info) { - int ret; - ret = sysfs_create_group(&dev_info->dev.kobj, - &iio_trigger_consumer_attr_group); - return ret; + return sysfs_create_group(&dev_info->dev.kobj, + &iio_trigger_consumer_attr_group); } -EXPORT_SYMBOL(iio_device_register_trigger_consumer); -int iio_device_unregister_trigger_consumer(struct iio_dev *dev_info) +void iio_device_unregister_trigger_consumer(struct iio_dev *dev_info) { + /* Clean up and associated but not attached triggers references */ + if (dev_info->trig) + iio_put_trigger(dev_info->trig); sysfs_remove_group(&dev_info->dev.kobj, &iio_trigger_consumer_attr_group); - return 0; } -EXPORT_SYMBOL(iio_device_unregister_trigger_consumer); int iio_triggered_ring_postenable(struct iio_dev *indio_dev) { diff --git a/drivers/staging/iio/light/isl29018.c b/drivers/staging/iio/light/isl29018.c index 426b6af..da5bb33 100644 --- a/drivers/staging/iio/light/isl29018.c +++ b/drivers/staging/iio/light/isl29018.c @@ -53,6 +53,10 @@ #define ISL29018_REG_ADD_DATA_MSB 0x03 #define ISL29018_MAX_REGS ISL29018_REG_ADD_DATA_MSB +#define ISL29018_REG_TEST 0x08 +#define ISL29018_TEST_SHIFT 0 +#define ISL29018_TEST_MASK (0xFF << ISL29018_TEST_SHIFT) + struct isl29018_chip { struct i2c_client *client; struct mutex lock; @@ -457,6 +461,48 @@ static int isl29018_chip_init(struct i2c_client *client) memset(chip->reg_cache, 0, sizeof(chip->reg_cache)); + /* Code added per Intersil Application Note 1534: + * When VDD sinks to approximately 1.8V or below, some of + * the part's registers may change their state. When VDD + * recovers to 2.25V (or greater), the part may thus be in an + * unknown mode of operation. The user can return the part to + * a known mode of operation either by (a) setting VDD = 0V for + * 1 second or more and then powering back up with a slew rate + * of 0.5V/ms or greater, or (b) via I2C disable all ALS/PROX + * conversions, clear the test registers, and then rewrite all + * registers to the desired values. + * ... + * FOR ISL29011, ISL29018, ISL29021, ISL29023 + * 1. Write 0x00 to register 0x08 (TEST) + * 2. Write 0x00 to register 0x00 (CMD1) + * 3. Rewrite all registers to the desired values + * + * ISL29018 Data Sheet (FN6619.1, Feb 11, 2010) essentially says + * the same thing EXCEPT the data sheet asks for a 1ms delay after + * writing the CMD1 register. + */ + status = isl29018_write_data(client, ISL29018_REG_TEST, 0, + ISL29018_TEST_MASK, ISL29018_TEST_SHIFT); + if (status < 0) { + dev_err(&client->dev, "Failed to clear isl29018 TEST reg." + "(%d)\n", status); + return status; + } + + /* See Intersil AN1534 comments above. + * "Operating Mode" (COMMAND1) register is reprogrammed when + * data is read from the device. + */ + status = isl29018_write_data(client, ISL29018_REG_ADD_COMMAND1, 0, + 0xff, 0); + if (status < 0) { + dev_err(&client->dev, "Failed to clear isl29018 CMD1 reg." + "(%d)\n", status); + return status; + } + + msleep(1); /* per data sheet, page 10 */ + /* set defaults */ status = isl29018_set_range(client, chip->range, &new_range); if (status < 0) { diff --git a/drivers/staging/iio/light/tsl2563.c b/drivers/staging/iio/light/tsl2563.c index f25243b..665a744 100644 --- a/drivers/staging/iio/light/tsl2563.c +++ b/drivers/staging/iio/light/tsl2563.c @@ -596,7 +596,7 @@ static irqreturn_t tsl2563_event_handler(int irq, void *private) struct tsl2563_chip *chip = iio_priv(dev_info); iio_push_event(dev_info, 0, - IIO_UNMOD_EVENT_CODE(IIO_EV_CLASS_LIGHT, + IIO_UNMOD_EVENT_CODE(IIO_LIGHT, 0, IIO_EV_TYPE_THRESH, IIO_EV_DIR_EITHER), @@ -697,7 +697,7 @@ static int __devinit tsl2563_probe(struct i2c_client *client, struct tsl2563_platform_data *pdata = client->dev.platform_data; int err = 0; int ret; - u8 id; + u8 id = 0; indio_dev = iio_allocate_device(sizeof(*chip)); if (!indio_dev) diff --git a/drivers/staging/iio/light/tsl2583.c b/drivers/staging/iio/light/tsl2583.c index 5694610..c7daa2f 100644 --- a/drivers/staging/iio/light/tsl2583.c +++ b/drivers/staging/iio/light/tsl2583.c @@ -27,6 +27,7 @@ #include <linux/mutex.h> #include <linux/unistd.h> #include <linux/slab.h> +#include <linux/module.h> #include "../iio.h" #define TSL258X_MAX_DEVICE_REGS 32 @@ -68,7 +69,7 @@ enum { TSL258X_CHIP_UNKNOWN = 0, TSL258X_CHIP_WORKING = 1, TSL258X_CHIP_SUSPENDED = 2 -} TSL258X_CHIP_WORKING_STATUS; +}; /* Per-device data */ struct taos_als_info { @@ -87,7 +88,6 @@ struct taos_settings { struct tsl2583_chip { struct mutex als_mutex; struct i2c_client *client; - struct iio_dev *iio_dev; struct taos_als_info als_cur_info; struct taos_settings taos_settings; int als_time_scale; @@ -114,7 +114,7 @@ struct taos_lux { /* This structure is intentionally large to accommodate updates via sysfs. */ /* Sized to 11 = max 10 segments + 1 termination segment */ /* Assumption is is one and only one type of glass used */ -struct taos_lux taos_device_lux[11] = { +static struct taos_lux taos_device_lux[11] = { { 9830, 8520, 15729 }, { 12452, 10807, 23344 }, { 14746, 6383, 11705 }, @@ -159,8 +159,7 @@ static void taos_defaults(struct tsl2583_chip *chip) static int taos_i2c_read(struct i2c_client *client, u8 reg, u8 *val, unsigned int len) { - int ret; - int i; + int i, ret; for (i = 0; i < len; i++) { /* select register to write */ @@ -191,47 +190,47 @@ taos_i2c_read(struct i2c_client *client, u8 reg, u8 *val, unsigned int len) * the array are then used along with the time scale factor array values, to * calculate the lux. */ -static int taos_get_lux(struct i2c_client *client) +static int taos_get_lux(struct iio_dev *indio_dev) { u16 ch0, ch1; /* separated ch0/ch1 data from device */ u32 lux; /* raw lux calculated from device data */ u32 ratio; u8 buf[5]; struct taos_lux *p; - struct tsl2583_chip *chip = i2c_get_clientdata(client); + struct tsl2583_chip *chip = iio_priv(indio_dev); int i, ret; u32 ch0lux = 0; u32 ch1lux = 0; if (mutex_trylock(&chip->als_mutex) == 0) { - dev_info(&client->dev, "taos_get_lux device is busy\n"); + dev_info(&chip->client->dev, "taos_get_lux device is busy\n"); return chip->als_cur_info.lux; /* busy, so return LAST VALUE */ } if (chip->taos_chip_status != TSL258X_CHIP_WORKING) { /* device is not enabled */ - dev_err(&client->dev, "taos_get_lux device is not enabled\n"); + dev_err(&chip->client->dev, "taos_get_lux device is not enabled\n"); ret = -EBUSY ; goto out_unlock; } - ret = taos_i2c_read(client, (TSL258X_CMD_REG), &buf[0], 1); + ret = taos_i2c_read(chip->client, (TSL258X_CMD_REG), &buf[0], 1); if (ret < 0) { - dev_err(&client->dev, "taos_get_lux failed to read CMD_REG\n"); + dev_err(&chip->client->dev, "taos_get_lux failed to read CMD_REG\n"); goto out_unlock; } /* is data new & valid */ if (!(buf[0] & TSL258X_STA_ADC_INTR)) { - dev_err(&client->dev, "taos_get_lux data not valid\n"); + dev_err(&chip->client->dev, "taos_get_lux data not valid\n"); ret = chip->als_cur_info.lux; /* return LAST VALUE */ goto out_unlock; } for (i = 0; i < 4; i++) { int reg = TSL258X_CMD_REG | (TSL258X_ALS_CHAN0LO + i); - ret = taos_i2c_read(client, reg, &buf[i], 1); + ret = taos_i2c_read(chip->client, reg, &buf[i], 1); if (ret < 0) { - dev_err(&client->dev, "taos_get_lux failed to read" + dev_err(&chip->client->dev, "taos_get_lux failed to read" " register %x\n", reg); goto out_unlock; } @@ -239,11 +238,12 @@ static int taos_get_lux(struct i2c_client *client) /* clear status, really interrupt status (interrupts are off), but * we use the bit anyway - don't forget 0x80 - this is a command*/ - ret = i2c_smbus_write_byte(client, - (TSL258X_CMD_REG | TSL258X_CMD_SPL_FN | TSL258X_CMD_ALS_INT_CLR)); + ret = i2c_smbus_write_byte(chip->client, + (TSL258X_CMD_REG | TSL258X_CMD_SPL_FN | + TSL258X_CMD_ALS_INT_CLR)); if (ret < 0) { - dev_err(&client->dev, + dev_err(&chip->client->dev, "taos_i2c_write_command failed in taos_get_lux, err = %d\n", ret); goto out_unlock; /* have no data, so return failure */ @@ -285,7 +285,7 @@ static int taos_get_lux(struct i2c_client *client) /* note: lux is 31 bit max at this point */ if (ch1lux > ch0lux) { - dev_dbg(&client->dev, "No Data - Return last value\n"); + dev_dbg(&chip->client->dev, "No Data - Return last value\n"); ret = chip->als_cur_info.lux = 0; goto out_unlock; } @@ -319,54 +319,56 @@ out_unlock: * to derive actual lux). * Return updated gain_trim value. */ -int taos_als_calibrate(struct i2c_client *client) +static int taos_als_calibrate(struct iio_dev *indio_dev) { - struct tsl2583_chip *chip = i2c_get_clientdata(client); + struct tsl2583_chip *chip = iio_priv(indio_dev); u8 reg_val; unsigned int gain_trim_val; int ret; int lux_val; - ret = i2c_smbus_write_byte(client, (TSL258X_CMD_REG | TSL258X_CNTRL)); + ret = i2c_smbus_write_byte(chip->client, + (TSL258X_CMD_REG | TSL258X_CNTRL)); if (ret < 0) { - dev_err(&client->dev, + dev_err(&chip->client->dev, "taos_als_calibrate failed to reach the CNTRL register, ret=%d\n", ret); return ret; } - reg_val = i2c_smbus_read_byte(client); + reg_val = i2c_smbus_read_byte(chip->client); if ((reg_val & (TSL258X_CNTL_ADC_ENBL | TSL258X_CNTL_PWR_ON)) != (TSL258X_CNTL_ADC_ENBL | TSL258X_CNTL_PWR_ON)) { - dev_err(&client->dev, + dev_err(&chip->client->dev, "taos_als_calibrate failed: device not powered on with ADC enabled\n"); return -1; } - ret = i2c_smbus_write_byte(client, (TSL258X_CMD_REG | TSL258X_CNTRL)); + ret = i2c_smbus_write_byte(chip->client, + (TSL258X_CMD_REG | TSL258X_CNTRL)); if (ret < 0) { - dev_err(&client->dev, + dev_err(&chip->client->dev, "taos_als_calibrate failed to reach the STATUS register, ret=%d\n", ret); return ret; } - reg_val = i2c_smbus_read_byte(client); + reg_val = i2c_smbus_read_byte(chip->client); if ((reg_val & TSL258X_STA_ADC_VALID) != TSL258X_STA_ADC_VALID) { - dev_err(&client->dev, + dev_err(&chip->client->dev, "taos_als_calibrate failed: STATUS - ADC not valid.\n"); return -ENODATA; } - lux_val = taos_get_lux(client); + lux_val = taos_get_lux(indio_dev); if (lux_val < 0) { - dev_err(&client->dev, "taos_als_calibrate failed to get lux\n"); + dev_err(&chip->client->dev, "taos_als_calibrate failed to get lux\n"); return lux_val; } gain_trim_val = (unsigned int) (((chip->taos_settings.als_cal_target) * chip->taos_settings.als_gain_trim) / lux_val); if ((gain_trim_val < 250) || (gain_trim_val > 4000)) { - dev_err(&client->dev, + dev_err(&chip->client->dev, "taos_als_calibrate failed: trim_val of %d is out of range\n", gain_trim_val); return -ENODATA; @@ -380,21 +382,21 @@ int taos_als_calibrate(struct i2c_client *client) * Turn the device on. * Configuration must be set before calling this function. */ -static int taos_chip_on(struct i2c_client *client) +static int taos_chip_on(struct iio_dev *indio_dev) { int i; - int ret = 0; + int ret; u8 *uP; u8 utmp; int als_count; int als_time; - struct tsl2583_chip *chip = i2c_get_clientdata(client); + struct tsl2583_chip *chip = iio_priv(indio_dev); /* and make sure we're not already on */ if (chip->taos_chip_status == TSL258X_CHIP_WORKING) { /* if forcing a register update - turn off, then on */ - dev_info(&client->dev, "device is already enabled\n"); - return -EINVAL; + dev_info(&chip->client->dev, "device is already enabled\n"); + return -EINVAL; } /* determine als integration regster */ @@ -416,20 +418,21 @@ static int taos_chip_on(struct i2c_client *client) /* TSL258x Specific power-on / adc enable sequence * Power on the device 1st. */ utmp = TSL258X_CNTL_PWR_ON; - ret = i2c_smbus_write_byte_data(client, - TSL258X_CMD_REG | TSL258X_CNTRL, utmp); + ret = i2c_smbus_write_byte_data(chip->client, + TSL258X_CMD_REG | TSL258X_CNTRL, utmp); if (ret < 0) { - dev_err(&client->dev, "taos_chip_on failed on CNTRL reg.\n"); + dev_err(&chip->client->dev, "taos_chip_on failed on CNTRL reg.\n"); return -1; } /* Use the following shadow copy for our delay before enabling ADC. * Write all the registers. */ for (i = 0, uP = chip->taos_config; i < TSL258X_REG_MAX; i++) { - ret = i2c_smbus_write_byte_data(client, TSL258X_CMD_REG + i, + ret = i2c_smbus_write_byte_data(chip->client, + TSL258X_CMD_REG + i, *uP++); if (ret < 0) { - dev_err(&client->dev, + dev_err(&chip->client->dev, "taos_chip_on failed on reg %d.\n", i); return -1; } @@ -439,10 +442,11 @@ static int taos_chip_on(struct i2c_client *client) /* NOW enable the ADC * initialize the desired mode of operation */ utmp = TSL258X_CNTL_PWR_ON | TSL258X_CNTL_ADC_ENBL; - ret = i2c_smbus_write_byte_data(client, TSL258X_CMD_REG | TSL258X_CNTRL, + ret = i2c_smbus_write_byte_data(chip->client, + TSL258X_CMD_REG | TSL258X_CNTRL, utmp); if (ret < 0) { - dev_err(&client->dev, "taos_chip_on failed on 2nd CTRL reg.\n"); + dev_err(&chip->client->dev, "taos_chip_on failed on 2nd CTRL reg.\n"); return -1; } chip->taos_chip_status = TSL258X_CHIP_WORKING; @@ -450,33 +454,26 @@ static int taos_chip_on(struct i2c_client *client) return ret; } -static int taos_chip_off(struct i2c_client *client) +static int taos_chip_off(struct iio_dev *indio_dev) { - struct tsl2583_chip *chip = i2c_get_clientdata(client); + struct tsl2583_chip *chip = iio_priv(indio_dev); int ret; /* turn device off */ chip->taos_chip_status = TSL258X_CHIP_SUSPENDED; - ret = i2c_smbus_write_byte_data(client, TSL258X_CMD_REG | TSL258X_CNTRL, + ret = i2c_smbus_write_byte_data(chip->client, + TSL258X_CMD_REG | TSL258X_CNTRL, 0x00); return ret; } /* Sysfs Interface Functions */ -static ssize_t taos_device_id(struct device *dev, -struct device_attribute *attr, char *buf) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct tsl2583_chip *chip = indio_dev->dev_data; - - return sprintf(buf, "%s\n", chip->client->name); -} static ssize_t taos_power_state_show(struct device *dev, struct device_attribute *attr, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct tsl2583_chip *chip = indio_dev->dev_data; + struct tsl2583_chip *chip = iio_priv(indio_dev); return sprintf(buf, "%d\n", chip->taos_chip_status); } @@ -485,16 +482,15 @@ static ssize_t taos_power_state_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct tsl2583_chip *chip = indio_dev->dev_data; unsigned long value; if (strict_strtoul(buf, 0, &value)) return -EINVAL; if (value == 0) - taos_chip_off(chip->client); + taos_chip_off(indio_dev); else - taos_chip_on(chip->client); + taos_chip_on(indio_dev); return len; } @@ -503,7 +499,7 @@ static ssize_t taos_gain_show(struct device *dev, struct device_attribute *attr, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct tsl2583_chip *chip = indio_dev->dev_data; + struct tsl2583_chip *chip = iio_priv(indio_dev); char gain[4] = {0}; switch (chip->taos_settings.als_gain) { @@ -528,7 +524,7 @@ static ssize_t taos_gain_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct tsl2583_chip *chip = indio_dev->dev_data; + struct tsl2583_chip *chip = iio_priv(indio_dev); unsigned long value; if (strict_strtoul(buf, 0, &value)) @@ -565,7 +561,7 @@ static ssize_t taos_als_time_show(struct device *dev, struct device_attribute *attr, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct tsl2583_chip *chip = indio_dev->dev_data; + struct tsl2583_chip *chip = iio_priv(indio_dev); return sprintf(buf, "%d\n", chip->taos_settings.als_time); } @@ -574,7 +570,7 @@ static ssize_t taos_als_time_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct tsl2583_chip *chip = indio_dev->dev_data; + struct tsl2583_chip *chip = iio_priv(indio_dev); unsigned long value; if (strict_strtoul(buf, 0, &value)) @@ -586,7 +582,7 @@ static ssize_t taos_als_time_store(struct device *dev, if (value % 50) return -EINVAL; - chip->taos_settings.als_time = value; + chip->taos_settings.als_time = value; return len; } @@ -602,7 +598,7 @@ static ssize_t taos_als_trim_show(struct device *dev, struct device_attribute *attr, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct tsl2583_chip *chip = indio_dev->dev_data; + struct tsl2583_chip *chip = iio_priv(indio_dev); return sprintf(buf, "%d\n", chip->taos_settings.als_gain_trim); } @@ -611,7 +607,7 @@ static ssize_t taos_als_trim_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct tsl2583_chip *chip = indio_dev->dev_data; + struct tsl2583_chip *chip = iio_priv(indio_dev); unsigned long value; if (strict_strtoul(buf, 0, &value)) @@ -627,7 +623,7 @@ static ssize_t taos_als_cal_target_show(struct device *dev, struct device_attribute *attr, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct tsl2583_chip *chip = indio_dev->dev_data; + struct tsl2583_chip *chip = iio_priv(indio_dev); return sprintf(buf, "%d\n", chip->taos_settings.als_cal_target); } @@ -636,7 +632,7 @@ static ssize_t taos_als_cal_target_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct tsl2583_chip *chip = indio_dev->dev_data; + struct tsl2583_chip *chip = iio_priv(indio_dev); unsigned long value; if (strict_strtoul(buf, 0, &value)) @@ -651,27 +647,26 @@ static ssize_t taos_als_cal_target_store(struct device *dev, static ssize_t taos_lux_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct tsl2583_chip *chip = indio_dev->dev_data; - int lux; + int ret; - lux = taos_get_lux(chip->client); + ret = taos_get_lux(dev_get_drvdata(dev)); + if (ret < 0) + return ret; - return sprintf(buf, "%d\n", lux); + return sprintf(buf, "%d\n", ret); } static ssize_t taos_do_calibrate(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct tsl2583_chip *chip = indio_dev->dev_data; unsigned long value; if (strict_strtoul(buf, 0, &value)) return -EINVAL; if (value == 1) - taos_als_calibrate(chip->client); + taos_als_calibrate(indio_dev); return len; } @@ -703,8 +698,8 @@ static ssize_t taos_luxtable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) { struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct tsl2583_chip *chip = indio_dev->dev_data; - int value[ARRAY_SIZE(taos_device_lux)]; + struct tsl2583_chip *chip = iio_priv(indio_dev); + int value[ARRAY_SIZE(taos_device_lux)*3 + 1]; int n; get_options(buf, ARRAY_SIZE(value), value); @@ -725,18 +720,17 @@ static ssize_t taos_luxtable_store(struct device *dev, } if (chip->taos_chip_status == TSL258X_CHIP_WORKING) - taos_chip_off(chip->client); + taos_chip_off(indio_dev); /* Zero out the table */ memset(taos_device_lux, 0, sizeof(taos_device_lux)); memcpy(taos_device_lux, &value[1], (value[0] * 4)); - taos_chip_on(chip->client); + taos_chip_on(indio_dev); return len; } -static DEVICE_ATTR(name, S_IRUGO, taos_device_id, NULL); static DEVICE_ATTR(power_state, S_IRUGO | S_IWUSR, taos_power_state_show, taos_power_state_store); @@ -762,7 +756,6 @@ static DEVICE_ATTR(illuminance0_lux_table, S_IRUGO | S_IWUSR, taos_luxtable_show, taos_luxtable_store); static struct attribute *sysfs_attrs_ctrl[] = { - &dev_attr_name.attr, &dev_attr_power_state.attr, &dev_attr_illuminance0_calibscale.attr, /* Gain */ &dev_attr_illuminance0_calibscale_available.attr, @@ -798,9 +791,10 @@ static const struct iio_info tsl2583_info = { static int __devinit taos_probe(struct i2c_client *clientp, const struct i2c_device_id *idp) { - int i, ret = 0; + int i, ret; unsigned char buf[TSL258X_MAX_DEVICE_REGS]; - static struct tsl2583_chip *chip; + struct tsl2583_chip *chip; + struct iio_dev *indio_dev; if (!i2c_check_functionality(clientp->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { @@ -810,12 +804,15 @@ static int __devinit taos_probe(struct i2c_client *clientp, return -EOPNOTSUPP; } - chip = kzalloc(sizeof(struct tsl2583_chip), GFP_KERNEL); - if (!chip) - return -ENOMEM; - + indio_dev = iio_allocate_device(sizeof(*chip)); + if (indio_dev == NULL) { + ret = -ENOMEM; + dev_err(&clientp->dev, "iio allocation failed\n"); + goto fail1; + } + chip = iio_priv(indio_dev); chip->client = clientp; - i2c_set_clientdata(clientp, chip); + i2c_set_clientdata(clientp, indio_dev); mutex_init(&chip->als_mutex); chip->taos_chip_status = TSL258X_CHIP_UNKNOWN; @@ -827,14 +824,14 @@ static int __devinit taos_probe(struct i2c_client *clientp, if (ret < 0) { dev_err(&clientp->dev, "i2c_smbus_write_bytes() to cmd " "reg failed in taos_probe(), err = %d\n", ret); - goto fail1; + goto fail2; } ret = i2c_smbus_read_byte(clientp); if (ret < 0) { dev_err(&clientp->dev, "i2c_smbus_read_byte from " "reg failed in taos_probe(), err = %d\n", ret); - goto fail1; + goto fail2; } buf[i] = ret; } @@ -842,58 +839,50 @@ static int __devinit taos_probe(struct i2c_client *clientp, if (!taos_tsl258x_device(buf)) { dev_info(&clientp->dev, "i2c device found but does not match " "expected id in taos_probe()\n"); - goto fail1; + goto fail2; } ret = i2c_smbus_write_byte(clientp, (TSL258X_CMD_REG | TSL258X_CNTRL)); if (ret < 0) { dev_err(&clientp->dev, "i2c_smbus_write_byte() to cmd reg " "failed in taos_probe(), err = %d\n", ret); - goto fail1; - } - - chip->iio_dev = iio_allocate_device(0); - if (!chip->iio_dev) { - ret = -ENOMEM; - dev_err(&clientp->dev, "iio allocation failed\n"); - goto fail1; + goto fail2; } - chip->iio_dev->info = &tsl2583_info; - chip->iio_dev->dev.parent = &clientp->dev; - chip->iio_dev->dev_data = (void *)(chip); - chip->iio_dev->modes = INDIO_DIRECT_MODE; - ret = iio_device_register(chip->iio_dev); + indio_dev->info = &tsl2583_info; + indio_dev->dev.parent = &clientp->dev; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->name = chip->client->name; + ret = iio_device_register(indio_dev); if (ret) { dev_err(&clientp->dev, "iio registration failed\n"); - goto fail1; + goto fail2; } /* Load up the V2 defaults (these are hard coded defaults for now) */ taos_defaults(chip); /* Make sure the chip is on */ - taos_chip_on(clientp); + taos_chip_on(indio_dev); dev_info(&clientp->dev, "Light sensor found.\n"); - return 0; - fail1: - kfree(chip); - + iio_free_device(indio_dev); +fail2: return ret; } static int taos_suspend(struct i2c_client *client, pm_message_t state) { - struct tsl2583_chip *chip = i2c_get_clientdata(client); + struct iio_dev *indio_dev = i2c_get_clientdata(client); + struct tsl2583_chip *chip = iio_priv(indio_dev); int ret = 0; mutex_lock(&chip->als_mutex); if (chip->taos_chip_status == TSL258X_CHIP_WORKING) { - ret = taos_chip_off(client); + ret = taos_chip_off(indio_dev); chip->taos_chip_status = TSL258X_CHIP_SUSPENDED; } @@ -903,13 +892,14 @@ static int taos_suspend(struct i2c_client *client, pm_message_t state) static int taos_resume(struct i2c_client *client) { - struct tsl2583_chip *chip = i2c_get_clientdata(client); + struct iio_dev *indio_dev = i2c_get_clientdata(client); + struct tsl2583_chip *chip = iio_priv(indio_dev); int ret = 0; mutex_lock(&chip->als_mutex); if (chip->taos_chip_status == TSL258X_CHIP_SUSPENDED) - ret = taos_chip_on(client); + ret = taos_chip_on(indio_dev); mutex_unlock(&chip->als_mutex); return ret; @@ -918,11 +908,8 @@ static int taos_resume(struct i2c_client *client) static int __devexit taos_remove(struct i2c_client *client) { - struct tsl2583_chip *chip = i2c_get_clientdata(client); - - iio_device_unregister(chip->iio_dev); + iio_device_unregister(i2c_get_clientdata(client)); - kfree(chip); return 0; } diff --git a/drivers/staging/iio/magnetometer/ak8975.c b/drivers/staging/iio/magnetometer/ak8975.c index 33919e8..a17fa9f 100644 --- a/drivers/staging/iio/magnetometer/ak8975.c +++ b/drivers/staging/iio/magnetometer/ak8975.c @@ -31,7 +31,6 @@ #include <linux/gpio.h> #include "../iio.h" -#include "magnet.h" /* * Register definitions, as well as various shifts and masks to get at the @@ -93,38 +92,28 @@ struct ak8975_data { struct mutex lock; u8 asa[3]; long raw_to_gauss[3]; - unsigned long mode; + bool mode; u8 reg_cache[AK8975_MAX_REGS]; int eoc_gpio; int eoc_irq; }; +static const int ak8975_index_to_reg[] = { + AK8975_REG_HXL, AK8975_REG_HYL, AK8975_REG_HZL, +}; + /* * Helper function to write to the I2C device's registers. */ static int ak8975_write_data(struct i2c_client *client, u8 reg, u8 val, u8 mask, u8 shift) { - u8 regval; - struct i2c_msg msg; - u8 w_data[2]; - int ret = 0; - struct ak8975_data *data = i2c_get_clientdata(client); + u8 regval; + int ret; - regval = data->reg_cache[reg]; - regval &= ~mask; - regval |= val << shift; - - w_data[0] = reg; - w_data[1] = regval; - - msg.addr = client->addr; - msg.flags = 0; - msg.len = 2; - msg.buf = w_data; - - ret = i2c_transfer(client->adapter, &msg, 1); + regval = (data->reg_cache[reg] & ~mask) | (val << shift); + ret = i2c_smbus_write_byte_data(client, reg, regval); if (ret < 0) { dev_err(&client->dev, "Write to device fails status %x\n", ret); return ret; @@ -140,21 +129,20 @@ static int ak8975_write_data(struct i2c_client *client, static int ak8975_read_data(struct i2c_client *client, u8 reg, u8 length, u8 *buffer) { - struct i2c_msg msg[2]; - u8 w_data[2]; int ret; - - w_data[0] = reg; - - msg[0].addr = client->addr; - msg[0].flags = I2C_M_NOSTART; /* set repeated start and write */ - msg[0].len = 1; - msg[0].buf = w_data; - - msg[1].addr = client->addr; - msg[1].flags = I2C_M_RD; - msg[1].len = length; - msg[1].buf = buffer; + struct i2c_msg msg[2] = { + { + .addr = client->addr, + .flags = I2C_M_NOSTART, + .len = 1, + .buf = ®, + }, { + .addr = client->addr, + .flags = I2C_M_RD, + .len = length, + .buf = buffer, + } + }; ret = i2c_transfer(client->adapter, msg, 2); if (ret < 0) { @@ -204,8 +192,41 @@ static int ak8975_setup(struct i2c_client *client) return ret; } - /* Precalculate scale factor for each axis and - store in the device data. */ +/* + * Precalculate scale factor (in Gauss units) for each axis and + * store in the device data. + * + * This scale factor is axis-dependent, and is derived from 3 calibration + * factors ASA(x), ASA(y), and ASA(z). + * + * These ASA values are read from the sensor device at start of day, and + * cached in the device context struct. + * + * Adjusting the flux value with the sensitivity adjustment value should be + * done via the following formula: + * + * Hadj = H * ( ( ( (ASA-128)*0.5 ) / 128 ) + 1 ) + * + * where H is the raw value, ASA is the sensitivity adjustment, and Hadj + * is the resultant adjusted value. + * + * We reduce the formula to: + * + * Hadj = H * (ASA + 128) / 256 + * + * H is in the range of -4096 to 4095. The magnetometer has a range of + * +-1229uT. To go from the raw value to uT is: + * + * HuT = H * 1229/4096, or roughly, 3/10. + * + * Since 1uT = 100 gauss, our final scale factor becomes: + * + * Hadj = H * ((ASA + 128) / 256) * 3/10 * 100 + * Hadj = H * ((ASA + 128) * 30 / 256 + * + * Since ASA doesn't change, we cache the resultant scale factor into the + * device context in ak8975_setup(). + */ data->raw_to_gauss[0] = ((data->asa[0] + 128) * 30) >> 8; data->raw_to_gauss[1] = ((data->asa[1] + 128) * 30) >> 8; data->raw_to_gauss[2] = ((data->asa[2] + 128) * 30) >> 8; @@ -222,7 +243,7 @@ static ssize_t show_mode(struct device *dev, struct device_attribute *devattr, struct iio_dev *indio_dev = dev_get_drvdata(dev); struct ak8975_data *data = iio_priv(indio_dev); - return sprintf(buf, "%lu\n", data->mode); + return sprintf(buf, "%u\n", data->mode); } /* @@ -235,26 +256,22 @@ static ssize_t store_mode(struct device *dev, struct device_attribute *devattr, struct iio_dev *indio_dev = dev_get_drvdata(dev); struct ak8975_data *data = iio_priv(indio_dev); struct i2c_client *client = data->client; - unsigned long oval; + bool value; int ret; /* Convert mode string and do some basic sanity checking on it. only 0 or 1 are valid. */ - if (strict_strtoul(buf, 10, &oval)) - return -EINVAL; - - if (oval > 1) { - dev_err(dev, "mode value is not supported\n"); - return -EINVAL; - } + ret = strtobool(buf, &value); + if (ret < 0) + return ret; mutex_lock(&data->lock); /* Write the mode to the device. */ - if (data->mode != oval) { + if (data->mode != value) { ret = ak8975_write_data(client, AK8975_REG_CNTL, - (u8)oval, + (u8)value, AK8975_REG_CNTL_MODE_MASK, AK8975_REG_CNTL_MODE_SHIFT); @@ -263,7 +280,7 @@ static ssize_t store_mode(struct device *dev, struct device_attribute *devattr, mutex_unlock(&data->lock); return ret; } - data->mode = oval; + data->mode = value; } mutex_unlock(&data->lock); @@ -271,50 +288,6 @@ static ssize_t store_mode(struct device *dev, struct device_attribute *devattr, return count; } -/* - * Emits the scale factor to bring the raw value into Gauss units. - * - * This scale factor is axis-dependent, and is derived from 3 calibration - * factors ASA(x), ASA(y), and ASA(z). - * - * These ASA values are read from the sensor device at start of day, and - * cached in the device context struct. - * - * Adjusting the flux value with the sensitivity adjustment value should be - * done via the following formula: - * - * Hadj = H * ( ( ( (ASA-128)*0.5 ) / 128 ) + 1 ) - * - * where H is the raw value, ASA is the sensitivity adjustment, and Hadj - * is the resultant adjusted value. - * - * We reduce the formula to: - * - * Hadj = H * (ASA + 128) / 256 - * - * H is in the range of -4096 to 4095. The magnetometer has a range of - * +-1229uT. To go from the raw value to uT is: - * - * HuT = H * 1229/4096, or roughly, 3/10. - * - * Since 1uT = 100 gauss, our final scale factor becomes: - * - * Hadj = H * ((ASA + 128) / 256) * 3/10 * 100 - * Hadj = H * ((ASA + 128) * 30 / 256 - * - * Since ASA doesn't change, we cache the resultant scale factor into the - * device context in ak8975_setup(). - */ -static ssize_t show_scale(struct device *dev, struct device_attribute *devattr, - char *buf) -{ - struct iio_dev *indio_dev = dev_get_drvdata(dev); - struct ak8975_data *data = iio_priv(indio_dev); - struct iio_dev_attr *this_attr = to_iio_dev_attr(devattr); - - return sprintf(buf, "%ld\n", data->raw_to_gauss[this_attr->address]); -} - static int wait_conversion_complete_gpio(struct ak8975_data *data) { struct i2c_client *client = data->client; @@ -371,13 +344,10 @@ static int wait_conversion_complete_polled(struct ak8975_data *data) /* * Emits the raw flux value for the x, y, or z axis. */ -static ssize_t show_raw(struct device *dev, struct device_attribute *devattr, - char *buf) +static int ak8975_read_axis(struct iio_dev *indio_dev, int index, int *val) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); struct ak8975_data *data = iio_priv(indio_dev); struct i2c_client *client = data->client; - struct iio_dev_attr *this_attr = to_iio_dev_attr(devattr); u16 meas_reg; s16 raw; u8 read_status; @@ -429,7 +399,8 @@ static ssize_t show_raw(struct device *dev, struct device_attribute *devattr, /* Read the flux value from the appropriate register (the register is specified in the iio device attributes). */ - ret = ak8975_read_data(client, this_attr->address, 2, (u8 *)&meas_reg); + ret = ak8975_read_data(client, ak8975_index_to_reg[index], + 2, (u8 *)&meas_reg); if (ret < 0) { dev_err(&client->dev, "Read axis data fails\n"); goto exit; @@ -442,30 +413,48 @@ static ssize_t show_raw(struct device *dev, struct device_attribute *devattr, /* Clamp to valid range. */ raw = clamp_t(s16, raw, -4096, 4095); - - return sprintf(buf, "%d\n", raw); + *val = raw; + return IIO_VAL_INT; exit: mutex_unlock(&data->lock); return ret; } +static int ak8975_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, + long mask) +{ + struct ak8975_data *data = iio_priv(indio_dev); + + switch (mask) { + case 0: + return ak8975_read_axis(indio_dev, chan->address, val); + case (1 << IIO_CHAN_INFO_SCALE_SEPARATE): + *val = data->raw_to_gauss[chan->address]; + return IIO_VAL_INT; + } + return -EINVAL; +} + +#define AK8975_CHANNEL(axis, index) \ + { \ + .type = IIO_MAGN, \ + .modified = 1, \ + .channel2 = IIO_MOD_##axis, \ + .info_mask = (1 << IIO_CHAN_INFO_SCALE_SEPARATE), \ + .address = index, \ + } + +static const struct iio_chan_spec ak8975_channels[] = { + AK8975_CHANNEL(X, 0), AK8975_CHANNEL(Y, 1), AK8975_CHANNEL(Z, 2), +}; + static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, show_mode, store_mode, 0); -static IIO_DEV_ATTR_MAGN_X_SCALE(S_IRUGO, show_scale, NULL, 0); -static IIO_DEV_ATTR_MAGN_Y_SCALE(S_IRUGO, show_scale, NULL, 1); -static IIO_DEV_ATTR_MAGN_Z_SCALE(S_IRUGO, show_scale, NULL, 2); -static IIO_DEV_ATTR_MAGN_X(show_raw, AK8975_REG_HXL); -static IIO_DEV_ATTR_MAGN_Y(show_raw, AK8975_REG_HYL); -static IIO_DEV_ATTR_MAGN_Z(show_raw, AK8975_REG_HZL); static struct attribute *ak8975_attr[] = { &iio_dev_attr_mode.dev_attr.attr, - &iio_dev_attr_magn_x_scale.dev_attr.attr, - &iio_dev_attr_magn_y_scale.dev_attr.attr, - &iio_dev_attr_magn_z_scale.dev_attr.attr, - &iio_dev_attr_magn_x_raw.dev_attr.attr, - &iio_dev_attr_magn_y_raw.dev_attr.attr, - &iio_dev_attr_magn_z_raw.dev_attr.attr, NULL }; @@ -475,6 +464,7 @@ static struct attribute_group ak8975_attr_group = { static const struct iio_info ak8975_info = { .attrs = &ak8975_attr_group, + .read_raw = &ak8975_read_raw, .driver_module = THIS_MODULE, }; @@ -530,6 +520,8 @@ static int ak8975_probe(struct i2c_client *client, data->eoc_irq = client->irq; data->eoc_gpio = eoc_gpio; indio_dev->dev.parent = &client->dev; + indio_dev->channels = ak8975_channels; + indio_dev->num_channels = ARRAY_SIZE(ak8975_channels); indio_dev->info = &ak8975_info; indio_dev->modes = INDIO_DIRECT_MODE; diff --git a/drivers/staging/iio/magnetometer/hmc5843.c b/drivers/staging/iio/magnetometer/hmc5843.c index b44c273a..1bb7186 100644 --- a/drivers/staging/iio/magnetometer/hmc5843.c +++ b/drivers/staging/iio/magnetometer/hmc5843.c @@ -24,7 +24,6 @@ #include <linux/types.h> #include "../iio.h" #include "../sysfs.h" -#include "magnet.h" #define HMC5843_I2C_ADDRESS 0x1E @@ -62,9 +61,9 @@ /* * Device status */ -#define DATA_READY 0x01 -#define DATA_OUTPUT_LOCK 0x02 -#define VOLTAGE_REGULATOR_ENABLED 0x04 +#define DATA_READY 0x01 +#define DATA_OUTPUT_LOCK 0x02 +#define VOLTAGE_REGULATOR_ENABLED 0x04 /* * Mode register configuration @@ -89,22 +88,16 @@ /* * Device Configutration */ -#define CONF_NORMAL 0x00 +#define CONF_NORMAL 0x00 #define CONF_POSITIVE_BIAS 0x01 #define CONF_NEGATIVE_BIAS 0x02 #define CONF_NOT_USED 0x03 #define MEAS_CONF_MASK 0x03 -static const char *regval_to_scale[] = { - "0.0000006173", - "0.0000007692", - "0.0000010309", - "0.0000012821", - "0.0000018868", - "0.0000021739", - "0.0000025641", - "0.0000035714", +static int hmc5843_regval_to_nanoscale[] = { + 6173, 7692, 10309, 12821, 18868, 21739, 25641, 35714 }; + static const int regval_to_input_field_mg[] = { 700, 1000, @@ -115,7 +108,7 @@ static const int regval_to_input_field_mg[] = { 4500, 6500 }; -static const char *regval_to_samp_freq[] = { +static const char * const regval_to_samp_freq[] = { "0.5", "1", "2", @@ -150,37 +143,28 @@ static s32 hmc5843_configure(struct i2c_client *client, } /* Return the measurement value from the specified channel */ -static ssize_t hmc5843_read_measurement(struct device *dev, - struct device_attribute *attr, - char *buf) +static int hmc5843_read_measurement(struct iio_dev *indio_dev, + int address, + int *val) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); struct i2c_client *client = to_i2c_client(indio_dev->dev.parent); - s16 coordinate_val; - struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); struct hmc5843_data *data = iio_priv(indio_dev); s32 result; mutex_lock(&data->lock); - result = i2c_smbus_read_byte_data(client, HMC5843_STATUS_REG); while (!(result & DATA_READY)) result = i2c_smbus_read_byte_data(client, HMC5843_STATUS_REG); - result = i2c_smbus_read_word_data(client, this_attr->address); + result = i2c_smbus_read_word_data(client, address); mutex_unlock(&data->lock); if (result < 0) return -EINVAL; - coordinate_val = (s16)swab16((u16)result); - return sprintf(buf, "%d\n", coordinate_val); + *val = (s16)swab16((u16)result); + return IIO_VAL_INT; } -static IIO_DEV_ATTR_MAGN_X(hmc5843_read_measurement, - HMC5843_DATA_OUT_X_MSB_REG); -static IIO_DEV_ATTR_MAGN_Y(hmc5843_read_measurement, - HMC5843_DATA_OUT_Y_MSB_REG); -static IIO_DEV_ATTR_MAGN_Z(hmc5843_read_measurement, - HMC5843_DATA_OUT_Z_MSB_REG); + /* * From the datasheet @@ -336,7 +320,7 @@ static s32 hmc5843_set_rate(struct i2c_client *client, reg_val = (data->meas_conf) | (rate << RATE_OFFSET); if (rate >= RATE_NOT_USED) { dev_err(&client->dev, - "This data output rate is not supported \n"); + "This data output rate is not supported\n"); return -EINVAL; } return i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_A, reg_val); @@ -467,28 +451,46 @@ static IIO_DEVICE_ATTR(magn_range, set_range, HMC5843_CONFIG_REG_B); -static ssize_t show_scale(struct device *dev, - struct device_attribute *attr, - char *buf) +static int hmc5843_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, + long mask) { - struct iio_dev *indio_dev = dev_get_drvdata(dev); struct hmc5843_data *data = iio_priv(indio_dev); - return strlen(strcpy(buf, regval_to_scale[data->range])); + + switch (mask) { + case 0: + return hmc5843_read_measurement(indio_dev, + chan->address, + val); + case (1 << IIO_CHAN_INFO_SCALE_SHARED): + *val = 0; + *val2 = hmc5843_regval_to_nanoscale[data->range]; + return IIO_VAL_INT_PLUS_NANO; + }; + return -EINVAL; } -static IIO_DEVICE_ATTR(magn_scale, - S_IRUGO, - show_scale, - NULL , 0); + +#define HMC5843_CHANNEL(axis, add) \ + { \ + .type = IIO_MAGN, \ + .modified = 1, \ + .channel2 = IIO_MOD_##axis, \ + .info_mask = (1 << IIO_CHAN_INFO_SCALE_SHARED), \ + .address = add \ + } + +static const struct iio_chan_spec hmc5843_channels[] = { + HMC5843_CHANNEL(X, HMC5843_DATA_OUT_X_MSB_REG), + HMC5843_CHANNEL(Y, HMC5843_DATA_OUT_Y_MSB_REG), + HMC5843_CHANNEL(Z, HMC5843_DATA_OUT_Z_MSB_REG), +}; static struct attribute *hmc5843_attributes[] = { &iio_dev_attr_meas_conf.dev_attr.attr, &iio_dev_attr_operating_mode.dev_attr.attr, &iio_dev_attr_sampling_frequency.dev_attr.attr, &iio_dev_attr_magn_range.dev_attr.attr, - &iio_dev_attr_magn_scale.dev_attr.attr, - &iio_dev_attr_magn_x_raw.dev_attr.attr, - &iio_dev_attr_magn_y_raw.dev_attr.attr, - &iio_dev_attr_magn_z_raw.dev_attr.attr, &iio_const_attr_sampling_frequency_available.dev_attr.attr, NULL }; @@ -530,6 +532,7 @@ static void hmc5843_init_client(struct i2c_client *client) static const struct iio_info hmc5843_info = { .attrs = &hmc5843_group, + .read_raw = &hmc5843_read_raw, .driver_module = THIS_MODULE, }; @@ -558,6 +561,9 @@ static int hmc5843_probe(struct i2c_client *client, hmc5843_init_client(client); indio_dev->info = &hmc5843_info; + indio_dev->name = id->name; + indio_dev->channels = hmc5843_channels; + indio_dev->num_channels = ARRAY_SIZE(hmc5843_channels); indio_dev->dev.parent = &client->dev; indio_dev->modes = INDIO_DIRECT_MODE; err = iio_device_register(indio_dev); diff --git a/drivers/staging/iio/magnetometer/magnet.h b/drivers/staging/iio/magnetometer/magnet.h deleted file mode 100644 index 1260eb7..0000000 --- a/drivers/staging/iio/magnetometer/magnet.h +++ /dev/null @@ -1,31 +0,0 @@ - -#include "../sysfs.h" - -/* Magnetometer types of attribute */ - -#define IIO_DEV_ATTR_MAGN_X_OFFSET(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(magn_x_offset, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_MAGN_Y_OFFSET(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(magn_y_offset, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_MAGN_Z_OFFSET(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(magn_z_offset, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_MAGN_X_SCALE(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(magn_x_scale, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_MAGN_Y_SCALE(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(magn_y_scale, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_MAGN_Z_SCALE(_mode, _show, _store, _addr) \ - IIO_DEVICE_ATTR(magn_z_scale, _mode, _show, _store, _addr) - -#define IIO_DEV_ATTR_MAGN_X(_show, _addr) \ - IIO_DEVICE_ATTR(magn_x_raw, S_IRUGO, _show, NULL, _addr) - -#define IIO_DEV_ATTR_MAGN_Y(_show, _addr) \ - IIO_DEVICE_ATTR(magn_y_raw, S_IRUGO, _show, NULL, _addr) - -#define IIO_DEV_ATTR_MAGN_Z(_show, _addr) \ - IIO_DEVICE_ATTR(magn_z_raw, S_IRUGO, _show, NULL, _addr) diff --git a/drivers/staging/iio/meter/ade7753.c b/drivers/staging/iio/meter/ade7753.c index 4d1bd42..bccc579 100644 --- a/drivers/staging/iio/meter/ade7753.c +++ b/drivers/staging/iio/meter/ade7753.c @@ -17,6 +17,7 @@ #include <linux/slab.h> #include <linux/sysfs.h> #include <linux/list.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c index f4f85fd..6f0f464 100644 --- a/drivers/staging/iio/meter/ade7754.c +++ b/drivers/staging/iio/meter/ade7754.c @@ -17,6 +17,7 @@ #include <linux/slab.h> #include <linux/sysfs.h> #include <linux/list.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c index 299b954..ac0e092 100644 --- a/drivers/staging/iio/meter/ade7758_core.c +++ b/drivers/staging/iio/meter/ade7758_core.c @@ -17,6 +17,7 @@ #include <linux/slab.h> #include <linux/sysfs.h> #include <linux/list.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" diff --git a/drivers/staging/iio/meter/ade7758_ring.c b/drivers/staging/iio/meter/ade7758_ring.c index b89b7f8..1e2a096 100644 --- a/drivers/staging/iio/meter/ade7758_ring.c +++ b/drivers/staging/iio/meter/ade7758_ring.c @@ -6,23 +6,14 @@ * Licensed under the GPL-2. */ #include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/gpio.h> -#include <linux/workqueue.h> -#include <linux/mutex.h> -#include <linux/device.h> #include <linux/kernel.h> #include <linux/spi/spi.h> #include <linux/slab.h> -#include <linux/sysfs.h> -#include <linux/list.h> #include <asm/unaligned.h> #include "../iio.h" -#include "../sysfs.h" #include "../ring_sw.h" -#include "../accel/accel.h" -#include "../trigger.h" +#include "../trigger_consumer.h" #include "ade7758.h" /** @@ -69,7 +60,7 @@ out: static irqreturn_t ade7758_trigger_handler(int irq, void *p) { struct iio_poll_func *pf = p; - struct iio_dev *indio_dev = pf->private_data; + struct iio_dev *indio_dev = pf->indio_dev; struct iio_ring_buffer *ring = indio_dev->ring; struct ade7758_state *st = iio_priv(indio_dev); s64 dat64[2]; @@ -136,12 +127,6 @@ static const struct iio_ring_setup_ops ade7758_ring_setup_ops = { void ade7758_unconfigure_ring(struct iio_dev *indio_dev) { - /* ensure that the trigger has been detached */ - if (indio_dev->trig) { - iio_put_trigger(indio_dev->trig); - iio_trigger_dettach_poll_func(indio_dev->trig, - indio_dev->pollfunc); - } iio_dealloc_pollfunc(indio_dev->pollfunc); iio_sw_rb_free(indio_dev->ring); } diff --git a/drivers/staging/iio/meter/ade7758_trigger.c b/drivers/staging/iio/meter/ade7758_trigger.c index a5c3248..392dfe3 100644 --- a/drivers/staging/iio/meter/ade7758_trigger.c +++ b/drivers/staging/iio/meter/ade7758_trigger.c @@ -7,16 +7,10 @@ */ #include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/mutex.h> -#include <linux/device.h> #include <linux/kernel.h> -#include <linux/sysfs.h> -#include <linux/list.h> #include <linux/spi/spi.h> #include "../iio.h" -#include "../sysfs.h" #include "../trigger.h" #include "ade7758.h" @@ -57,6 +51,12 @@ static int ade7758_trig_try_reen(struct iio_trigger *trig) return 0; } +static const struct iio_trigger_ops ade7758_trigger_ops = { + .owner = THIS_MODULE, + .set_trigger_state = &ade7758_data_rdy_trigger_set_state, + .try_reenable = &ade7758_trig_try_reen, +}; + int ade7758_probe_trigger(struct iio_dev *indio_dev) { struct ade7758_state *st = iio_priv(indio_dev); @@ -79,10 +79,8 @@ int ade7758_probe_trigger(struct iio_dev *indio_dev) goto error_free_trig; st->trig->dev.parent = &st->us->dev; - st->trig->owner = THIS_MODULE; + st->trig->ops = &ade7758_trigger_ops; st->trig->private_data = indio_dev; - st->trig->set_trigger_state = &ade7758_data_rdy_trigger_set_state; - st->trig->try_reenable = &ade7758_trig_try_reen; ret = iio_trigger_register(st->trig); /* select default trigger */ diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c index a51a64c..31723e8 100644 --- a/drivers/staging/iio/meter/ade7759.c +++ b/drivers/staging/iio/meter/ade7759.c @@ -17,6 +17,7 @@ #include <linux/slab.h> #include <linux/sysfs.h> #include <linux/list.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" diff --git a/drivers/staging/iio/meter/ade7854-i2c.c b/drivers/staging/iio/meter/ade7854-i2c.c index dd72343..cbca3fd 100644 --- a/drivers/staging/iio/meter/ade7854-i2c.c +++ b/drivers/staging/iio/meter/ade7854-i2c.c @@ -10,6 +10,7 @@ #include <linux/kernel.h> #include <linux/i2c.h> #include <linux/slab.h> +#include <linux/module.h> #include "../iio.h" #include "ade7854.h" diff --git a/drivers/staging/iio/meter/ade7854-spi.c b/drivers/staging/iio/meter/ade7854-spi.c index e0d1086..cfa23ba 100644 --- a/drivers/staging/iio/meter/ade7854-spi.c +++ b/drivers/staging/iio/meter/ade7854-spi.c @@ -10,6 +10,7 @@ #include <linux/kernel.h> #include <linux/spi/spi.h> #include <linux/slab.h> +#include <linux/module.h> #include "../iio.h" #include "ade7854.h" diff --git a/drivers/staging/iio/meter/ade7854.c b/drivers/staging/iio/meter/ade7854.c index b82659f..bc1f83e 100644 --- a/drivers/staging/iio/meter/ade7854.c +++ b/drivers/staging/iio/meter/ade7854.c @@ -16,6 +16,7 @@ #include <linux/slab.h> #include <linux/sysfs.h> #include <linux/list.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" @@ -582,7 +583,7 @@ error_unreg_dev: iio_device_unregister(indio_dev); error_free_dev: iio_free_device(indio_dev); -error_ret: + return ret; } EXPORT_SYMBOL(ade7854_probe); diff --git a/drivers/staging/iio/resolver/ad2s120x.c b/drivers/staging/iio/resolver/ad2s120x.c index bed4c72..fdaf0a8 100644 --- a/drivers/staging/iio/resolver/ad2s120x.c +++ b/drivers/staging/iio/resolver/ad2s120x.c @@ -16,6 +16,7 @@ #include <linux/sysfs.h> #include <linux/delay.h> #include <linux/gpio.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c index ecaf7bb..f8459e8 100644 --- a/drivers/staging/iio/resolver/ad2s1210.c +++ b/drivers/staging/iio/resolver/ad2s1210.c @@ -16,6 +16,7 @@ #include <linux/sysfs.h> #include <linux/delay.h> #include <linux/gpio.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" @@ -639,7 +640,6 @@ static struct attribute *ad2s1210_attributes[] = { }; static const struct attribute_group ad2s1210_attribute_group = { - .name = DRV_NAME, .attrs = ad2s1210_attributes, }; diff --git a/drivers/staging/iio/resolver/ad2s90.c b/drivers/staging/iio/resolver/ad2s90.c index 166e241..3739bd2 100644 --- a/drivers/staging/iio/resolver/ad2s90.c +++ b/drivers/staging/iio/resolver/ad2s90.c @@ -14,6 +14,7 @@ #include <linux/spi/spi.h> #include <linux/slab.h> #include <linux/sysfs.h> +#include <linux/module.h> #include "../iio.h" #include "../sysfs.h" @@ -58,7 +59,6 @@ static struct attribute *ad2s90_attributes[] = { }; static const struct attribute_group ad2s90_attribute_group = { - .name = DRV_NAME, .attrs = ad2s90_attributes, }; diff --git a/drivers/staging/iio/sysfs.h b/drivers/staging/iio/sysfs.h index dd79b58..0b75823 100644 --- a/drivers/staging/iio/sysfs.h +++ b/drivers/staging/iio/sysfs.h @@ -12,19 +12,17 @@ #ifndef _INDUSTRIAL_IO_SYSFS_H_ #define _INDUSTRIAL_IO_SYSFS_H_ -#include "iio.h" +struct iio_chan_spec; /** * struct iio_dev_attr - iio specific device attribute * @dev_attr: underlying device attribute * @address: associated register address - * @val2: secondary attribute value * @l: list head for maintaining list of dynamically created attrs. */ struct iio_dev_attr { struct device_attribute dev_attr; int address; - int val2; struct list_head l; struct iio_chan_spec const *c; }; @@ -64,10 +62,6 @@ struct iio_const_attr { struct iio_dev_attr iio_dev_attr_##_vname \ = IIO_ATTR(_name, _mode, _show, _store, _addr) -#define IIO_DEVICE_ATTR_2(_name, _mode, _show, _store, _addr, _val2) \ - struct iio_dev_attr iio_dev_attr_##_name \ - = IIO_ATTR_2(_name, _mode, _show, _store, _addr, _val2) - #define IIO_CONST_ATTR(_name, _string) \ struct iio_const_attr iio_const_attr_##_name \ = { .string = _string, \ @@ -77,17 +71,8 @@ struct iio_const_attr { struct iio_const_attr iio_const_attr_##_vname \ = { .string = _string, \ .dev_attr = __ATTR(_name, S_IRUGO, iio_read_const_attr, NULL)} -/* Generic attributes of onetype or another */ - -/** - * IIO_DEV_ATTR_REV - revision number for the device - * @_show: output method for the attribute - * - * Very much device dependent. - **/ -#define IIO_DEV_ATTR_REV(_show) \ - IIO_DEVICE_ATTR(revision, S_IRUGO, _show, NULL, 0) +/* Generic attributes of onetype or another */ /** * IIO_DEV_ATTR_RESET: resets the device **/ @@ -95,13 +80,6 @@ struct iio_const_attr { IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, _store, 0) /** - * IIO_CONST_ATTR_NAME - constant identifier - * @_string: the name - **/ -#define IIO_CONST_ATTR_NAME(_string) \ - IIO_CONST_ATTR(name, _string) - -/** * IIO_DEV_ATTR_SAMP_FREQ - sets any internal clock frequency * @_mode: sysfs file mode/permissions * @_show: output method for the attribute @@ -111,15 +89,11 @@ struct iio_const_attr { IIO_DEVICE_ATTR(sampling_frequency, _mode, _show, _store, 0) /** - * IIO_DEV_ATTR_AVAIL_SAMP_FREQ - list available sampling frequencies + * IIO_DEV_ATTR_SAMP_FREQ_AVAIL - list available sampling frequencies * @_show: output method for the attribute * * May be mode dependent on some devices **/ -/* Deprecated */ -#define IIO_DEV_ATTR_AVAIL_SAMP_FREQ(_show) \ - IIO_DEVICE_ATTR(available_sampling_frequency, S_IRUGO, _show, NULL, 0) - #define IIO_DEV_ATTR_SAMP_FREQ_AVAIL(_show) \ IIO_DEVICE_ATTR(sampling_frequency_available, S_IRUGO, _show, NULL, 0) /** @@ -131,27 +105,6 @@ struct iio_const_attr { #define IIO_CONST_ATTR_SAMP_FREQ_AVAIL(_string) \ IIO_CONST_ATTR(sampling_frequency_available, _string) -/** - * IIO_DEV_ATTR_SW_RING_ENABLE - enable software ring buffer - * @_show: output method for the attribute - * @_store: input method for the attribute - * - * Success may be dependent on attachment of trigger previously. - **/ -#define IIO_DEV_ATTR_SW_RING_ENABLE(_show, _store) \ - IIO_DEVICE_ATTR(sw_ring_enable, S_IRUGO | S_IWUSR, _show, _store, 0) - -/** - * IIO_DEV_ATTR_HW_RING_ENABLE - enable hardware ring buffer - * @_show: output method for the attribute - * @_store: input method for the attribute - * - * This is a different attribute from the software one as one can envision - * schemes where a combination of the two may be used. - **/ -#define IIO_DEV_ATTR_HW_RING_ENABLE(_show, _store) \ - IIO_DEVICE_ATTR(hw_ring_enable, S_IRUGO | S_IWUSR, _show, _store, 0) - #define IIO_DEV_ATTR_TEMP_RAW(_show) \ IIO_DEVICE_ATTR(temp_raw, S_IRUGO, _show, NULL, 0) @@ -161,28 +114,6 @@ struct iio_const_attr { #define IIO_CONST_ATTR_TEMP_SCALE(_string) \ IIO_CONST_ATTR(temp_scale, _string) -/* must match our channel defs */ -#define IIO_EV_CLASS_IN IIO_IN -#define IIO_EV_CLASS_IN_DIFF IIO_IN_DIFF -#define IIO_EV_CLASS_ACCEL IIO_ACCEL -#define IIO_EV_CLASS_GYRO IIO_GYRO -#define IIO_EV_CLASS_MAGN IIO_MAGN -#define IIO_EV_CLASS_LIGHT IIO_LIGHT -#define IIO_EV_CLASS_PROXIMITY IIO_PROXIMITY -#define IIO_EV_CLASS_TEMP IIO_TEMP - -#define IIO_EV_MOD_X IIO_MOD_X -#define IIO_EV_MOD_Y IIO_MOD_Y -#define IIO_EV_MOD_Z IIO_MOD_Z -#define IIO_EV_MOD_X_AND_Y IIO_MOD_X_AND_Y -#define IIO_EV_MOD_X_ANX_Z IIO_MOD_X_AND_Z -#define IIO_EV_MOD_Y_AND_Z IIO_MOD_Y_AND_Z -#define IIO_EV_MOD_X_AND_Y_AND_Z IIO_MOD_X_AND_Y_AND_Z -#define IIO_EV_MOD_X_OR_Y IIO_MOD_X_OR_Y -#define IIO_EV_MOD_X_OR_Z IIO_MOD_X_OR_Z -#define IIO_EV_MOD_Y_OR_Z IIO_MOD_Y_OR_Z -#define IIO_EV_MOD_X_OR_Y_OR_Z IIO_MOD_X_OR_Y_OR_Z - #define IIO_EV_TYPE_THRESH 0 #define IIO_EV_TYPE_MAG 1 #define IIO_EV_TYPE_ROC 2 @@ -207,10 +138,6 @@ struct iio_const_attr { #define IIO_UNMOD_EVENT_CODE(channelclass, number, type, direction) \ IIO_EVENT_CODE(channelclass, 0, number, 0, type, direction) - -#define IIO_BUFFER_EVENT_CODE(code) \ - (IIO_EV_CLASS_BUFFER | (code << 8)) - #define IIO_EVENT_CODE_EXTRACT_DIR(mask) ((mask >> 24) & 0xf) /* Event code number extraction depends on which type of event we have. diff --git a/drivers/staging/iio/trigger.h b/drivers/staging/iio/trigger.h index e0b58ed..598fcb3 100644 --- a/drivers/staging/iio/trigger.h +++ b/drivers/staging/iio/trigger.h @@ -7,6 +7,7 @@ * the Free Software Foundation. */ #include <linux/irq.h> +#include <linux/module.h> #ifndef _IIO_TRIGGER_H_ #define _IIO_TRIGGER_H_ @@ -16,6 +17,27 @@ struct iio_subirq { }; /** + * struct iio_trigger_ops - operations structure for an iio_trigger. + * @owner: used to monitor usage count of the trigger. + * @set_trigger_state: switch on/off the trigger on demand + * @try_reenable: function to reenable the trigger when the + * use count is zero (may be NULL) + * @validate_device: function to validate the device when the + * current trigger gets changed. + * + * This is typically static const within a driver and shared by + * instances of a given device. + **/ +struct iio_trigger_ops { + struct module *owner; + int (*set_trigger_state)(struct iio_trigger *trig, bool state); + int (*try_reenable)(struct iio_trigger *trig); + int (*validate_device)(struct iio_trigger *trig, + struct iio_dev *indio_dev); +}; + + +/** * struct iio_trigger - industrial I/O trigger device * * @id: [INTERN] unique id number @@ -26,11 +48,6 @@ struct iio_subirq { * @alloc_list: [DRIVER] used for driver specific trigger list * @owner: [DRIVER] used to monitor usage count of the trigger. * @use_count: use count for the trigger - * @set_trigger_state: [DRIVER] switch on/off the trigger on demand - * @try_reenable: function to reenable the trigger when the - * use count is zero (may be NULL) - * @validate_device: function to validate the device when the - * current trigger gets changed. * @subirq_chip: [INTERN] associate 'virtual' irq chip. * @subirq_base: [INTERN] base number for irqs provided by trigger. * @subirqs: [INTERN] information about the 'child' irqs. @@ -38,6 +55,7 @@ struct iio_subirq { * @pool_lock: [INTERN] protection of the irq pool. **/ struct iio_trigger { + const struct iio_trigger_ops *ops; int id; const char *name; struct device dev; @@ -48,11 +66,6 @@ struct iio_trigger { struct module *owner; int use_count; - int (*set_trigger_state)(struct iio_trigger *trig, bool state); - int (*try_reenable)(struct iio_trigger *trig); - int (*validate_device)(struct iio_trigger *trig, - struct iio_dev *indio_dev); - struct irq_chip subirq_chip; int subirq_base; @@ -61,29 +74,6 @@ struct iio_trigger { struct mutex pool_lock; }; -/** - * struct iio_poll_func - poll function pair - * - * @private_data: data specific to device (passed into poll func) - * @h: the function that is actually run on trigger - * @thread: threaded interrupt part - * @type: the type of interrupt (basically if oneshot) - * @name: name used to identify the trigger consumer. - * @irq: the corresponding irq as allocated from the - * trigger pool - * @timestamp: some devices need a timestamp grabbed as soon - * as possible after the trigger - hence handler - * passes it via here. - **/ -struct iio_poll_func { - void *private_data; - irqreturn_t (*h)(int irq, void *p); - irqreturn_t (*thread)(int irq, void *p); - int type; - char *name; - int irq; - s64 timestamp; -}; static inline struct iio_trigger *to_iio_trigger(struct device *d) { @@ -92,14 +82,14 @@ static inline struct iio_trigger *to_iio_trigger(struct device *d) static inline void iio_put_trigger(struct iio_trigger *trig) { + module_put(trig->ops->owner); put_device(&trig->dev); - module_put(trig->owner); }; static inline void iio_get_trigger(struct iio_trigger *trig) { - __module_get(trig->owner); get_device(&trig->dev); + __module_get(trig->ops->owner); }; /** @@ -115,23 +105,6 @@ int iio_trigger_register(struct iio_trigger *trig_info); void iio_trigger_unregister(struct iio_trigger *trig_info); /** - * iio_trigger_attach_poll_func() - add a function pair to be run on trigger - * @trig: trigger to which the function pair are being added - * @pf: poll function pair - **/ -int iio_trigger_attach_poll_func(struct iio_trigger *trig, - struct iio_poll_func *pf); - -/** - * iio_trigger_dettach_poll_func() - remove function pair from those to be - * run on trigger - * @trig: trigger from which the function is being removed - * @pf: poll function pair - **/ -int iio_trigger_dettach_poll_func(struct iio_trigger *trig, - struct iio_poll_func *pf); - -/** * iio_trigger_poll() - called on a trigger occurring * @trig: trigger which occurred * @@ -139,48 +112,9 @@ int iio_trigger_dettach_poll_func(struct iio_trigger *trig, **/ void iio_trigger_poll(struct iio_trigger *trig, s64 time); void iio_trigger_poll_chained(struct iio_trigger *trig, s64 time); -void iio_trigger_notify_done(struct iio_trigger *trig); irqreturn_t iio_trigger_generic_data_rdy_poll(int irq, void *private); -static inline int iio_trigger_get_irq(struct iio_trigger *trig) -{ - int ret; - mutex_lock(&trig->pool_lock); - ret = bitmap_find_free_region(trig->pool, - CONFIG_IIO_CONSUMERS_PER_TRIGGER, - ilog2(1)); - mutex_unlock(&trig->pool_lock); - if (ret >= 0) - ret += trig->subirq_base; - - return ret; -}; - -static inline void iio_trigger_put_irq(struct iio_trigger *trig, int irq) -{ - mutex_lock(&trig->pool_lock); - clear_bit(irq - trig->subirq_base, trig->pool); - mutex_unlock(&trig->pool_lock); -}; - -struct iio_poll_func -*iio_alloc_pollfunc(irqreturn_t (*h)(int irq, void *p), - irqreturn_t (*thread)(int irq, void *p), - int type, - void *private, - const char *fmt, - ...); -void iio_dealloc_pollfunc(struct iio_poll_func *pf); -irqreturn_t iio_pollfunc_store_time(int irq, void *p); - -/* - * Two functions for common case where all that happens is a pollfunc - * is attached and detached from a trigger - */ -int iio_triggered_ring_postenable(struct iio_dev *indio_dev); -int iio_triggered_ring_predisable(struct iio_dev *indio_dev); - struct iio_trigger *iio_allocate_trigger(const char *fmt, ...) __attribute__((format(printf, 1, 2))); void iio_free_trigger(struct iio_trigger *trig); diff --git a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c index 4f17295..243f38f 100644 --- a/drivers/staging/iio/trigger/iio-trig-bfin-timer.c +++ b/drivers/staging/iio/trigger/iio-trig-bfin-timer.c @@ -143,6 +143,10 @@ static int iio_bfin_tmr_get_number(int irq) return -ENODEV; } +static const struct iio_trigger_ops iio_bfin_tmr_trigger_ops = { + owner = THIS_MODULE, +}; + static int __devinit iio_bfin_tmr_trigger_probe(struct platform_device *pdev) { struct bfin_tmr_state *st; @@ -175,7 +179,7 @@ static int __devinit iio_bfin_tmr_trigger_probe(struct platform_device *pdev) } st->trig->private_data = st; - st->trig->owner = THIS_MODULE; + st->trig->ops = &iio_bfin_tmr_trigger_ops; st->trig->dev.groups = iio_bfin_tmr_trigger_attr_groups; ret = iio_trigger_register(st->trig); if (ret) diff --git a/drivers/staging/iio/trigger/iio-trig-gpio.c b/drivers/staging/iio/trigger/iio-trig-gpio.c index f1fb795..f2a6559 100644 --- a/drivers/staging/iio/trigger/iio-trig-gpio.c +++ b/drivers/staging/iio/trigger/iio-trig-gpio.c @@ -47,6 +47,10 @@ static irqreturn_t iio_gpio_trigger_poll(int irq, void *private) return IRQ_HANDLED; } +static const struct iio_trigger_ops iio_gpio_trigger_ops = { + .owner = THIS_MODULE, +}; + static int iio_gpio_trigger_probe(struct platform_device *pdev) { struct iio_gpio_trigger_info *trig_info; @@ -81,7 +85,7 @@ static int iio_gpio_trigger_probe(struct platform_device *pdev) } trig->private_data = trig_info; trig_info->irq = irq; - trig->owner = THIS_MODULE; + trig->ops = &iio_gpio_trigger_ops; ret = request_irq(irq, iio_gpio_trigger_poll, irqflags, trig->name, trig); if (ret) { diff --git a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c index 01cf7e2..d35d085 100644 --- a/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c +++ b/drivers/staging/iio/trigger/iio-trig-periodic-rtc.c @@ -96,6 +96,11 @@ static void iio_prtc_trigger_poll(void *private_data) iio_trigger_poll(private_data, 0); } +static const struct iio_trigger_ops iio_prtc_trigger_ops = { + .owner = THIS_MODULE, + .set_trigger_state = &iio_trig_periodic_rtc_set_state, +}; + static int iio_trig_periodic_rtc_probe(struct platform_device *dev) { char **pdata = dev->dev.platform_data; @@ -121,7 +126,7 @@ static int iio_trig_periodic_rtc_probe(struct platform_device *dev) } trig->private_data = trig_info; trig->owner = THIS_MODULE; - trig->set_trigger_state = &iio_trig_periodic_rtc_set_state; + trig->ops = &iio_prtc_trigger_ops; /* RTC access */ trig_info->rtc = rtc_class_open(pdata[i]); diff --git a/drivers/staging/iio/trigger/iio-trig-sysfs.c b/drivers/staging/iio/trigger/iio-trig-sysfs.c index 47248cd..174dc65 100644 --- a/drivers/staging/iio/trigger/iio-trig-sysfs.c +++ b/drivers/staging/iio/trigger/iio-trig-sysfs.c @@ -77,9 +77,16 @@ static const struct attribute_group *iio_sysfs_trig_groups[] = { NULL }; + +/* Nothing to actually do upon release */ +static void iio_trigger_sysfs_release(struct device *dev) +{ +} + static struct device iio_sysfs_trig_dev = { .bus = &iio_bus_type, .groups = iio_sysfs_trig_groups, + .release = &iio_trigger_sysfs_release, }; static ssize_t iio_sysfs_trigger_poll(struct device *dev, @@ -107,6 +114,10 @@ static const struct attribute_group *iio_sysfs_trigger_attr_groups[] = { NULL }; +static const struct iio_trigger_ops iio_sysfs_trigger_ops = { + .owner = THIS_MODULE, +}; + static int iio_sysfs_trigger_probe(int id) { struct iio_sysfs_trig *t; @@ -135,7 +146,7 @@ static int iio_sysfs_trigger_probe(int id) } t->trig->dev.groups = iio_sysfs_trigger_attr_groups; - t->trig->owner = THIS_MODULE; + t->trig->ops = &iio_sysfs_trigger_ops; t->trig->dev.parent = &iio_sysfs_trig_dev; ret = iio_trigger_register(t->trig); diff --git a/drivers/staging/iio/trigger_consumer.h b/drivers/staging/iio/trigger_consumer.h index 9d52d96..418e0bd 100644 --- a/drivers/staging/iio/trigger_consumer.h +++ b/drivers/staging/iio/trigger_consumer.h @@ -1,47 +1,52 @@ - -/* The industrial I/O core, trigger consumer handling functions +/* The industrial I/O core, trigger consumer functions * - * Copyright (c) 2008 Jonathan Cameron + * Copyright (c) 2008-2011 Jonathan Cameron * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as published by * the Free Software Foundation. */ -#ifdef CONFIG_IIO_TRIGGER -/** - * iio_device_register_trigger_consumer() - set up an iio_dev to use triggers - * @dev_info: iio_dev associated with the device that will consume the trigger - **/ -int iio_device_register_trigger_consumer(struct iio_dev *dev_info); - -/** - * iio_device_unregister_trigger_consumer() - reverse the registration process - * @dev_info: iio_dev associated with the device that consumed the trigger - **/ -int iio_device_unregister_trigger_consumer(struct iio_dev *dev_info); - -#else - /** - * iio_device_register_trigger_consumer() - set up an iio_dev to use triggers - * @dev_info: iio_dev associated with the device that will consume the trigger - **/ -static int iio_device_register_trigger_consumer(struct iio_dev *dev_info) -{ - return 0; -}; - -/** - * iio_device_unregister_trigger_consumer() - reverse the registration process - * @dev_info: iio_dev associated with the device that consumed the trigger + * struct iio_poll_func - poll function pair + * + * @indio_dev: data specific to device (passed into poll func) + * @h: the function that is actually run on trigger + * @thread: threaded interrupt part + * @type: the type of interrupt (basically if oneshot) + * @name: name used to identify the trigger consumer. + * @irq: the corresponding irq as allocated from the + * trigger pool + * @timestamp: some devices need a timestamp grabbed as soon + * as possible after the trigger - hence handler + * passes it via here. **/ -static int iio_device_unregister_trigger_consumer(struct iio_dev *dev_info) -{ - return 0; +struct iio_poll_func { + struct iio_dev *indio_dev; + irqreturn_t (*h)(int irq, void *p); + irqreturn_t (*thread)(int irq, void *p); + int type; + char *name; + int irq; + s64 timestamp; }; -#endif /* CONFIG_TRIGGER_CONSUMER */ +struct iio_poll_func +*iio_alloc_pollfunc(irqreturn_t (*h)(int irq, void *p), + irqreturn_t (*thread)(int irq, void *p), + int type, + struct iio_dev *indio_dev, + const char *fmt, + ...); +void iio_dealloc_pollfunc(struct iio_poll_func *pf); +irqreturn_t iio_pollfunc_store_time(int irq, void *p); +void iio_trigger_notify_done(struct iio_trigger *trig); +/* + * Two functions for common case where all that happens is a pollfunc + * is attached and detached from a trigger + */ +int iio_triggered_ring_postenable(struct iio_dev *indio_dev); +int iio_triggered_ring_predisable(struct iio_dev *indio_dev); diff --git a/drivers/staging/keucr/scsiglue.c b/drivers/staging/keucr/scsiglue.c index 135f7f2..e1f3931 100644 --- a/drivers/staging/keucr/scsiglue.c +++ b/drivers/staging/keucr/scsiglue.c @@ -144,7 +144,7 @@ static int command_abort(struct scsi_cmnd *srb) scsi_lock(us_to_host(us)); if (us->srb != srb) { scsi_unlock(us_to_host(us)); - printk ("-- nothing to abort\n"); + printk("-- nothing to abort\n"); return FAILED; } @@ -279,7 +279,8 @@ static int proc_info(struct Scsi_Host *host, char *buffer, char **start, pos += sprintf(pos, " Quirks:"); #define US_FLAG(name, value) \ - if (us->fflags & value) pos += sprintf(pos, " " #name); + if (us->fflags & value)\ + pos += sprintf(pos, " " #name); US_DO_ALL_FLAGS #undef US_FLAG diff --git a/drivers/staging/keucr/smil.h b/drivers/staging/keucr/smil.h index b5a8fa7..24a636a 100644 --- a/drivers/staging/keucr/smil.h +++ b/drivers/staging/keucr/smil.h @@ -177,8 +177,7 @@ struct SSFDCTYPE { WORD MaxLogBlocks; }; -typedef struct SSFDCTYPE_T -{ +typedef struct SSFDCTYPE_T { BYTE Model; BYTE Attribute; BYTE MaxZones; @@ -194,8 +193,7 @@ struct ADDRESS { WORD LogBlock; /* Logical Block Number of Zone */ }; -typedef struct ADDRESS_T -{ +typedef struct ADDRESS_T { BYTE Zone; /* Zone Number */ BYTE Sector; /* Sector(512byte) Number on Block */ WORD PhyBlock; /* Physical Block Number on Zone */ diff --git a/drivers/staging/keucr/smilsub.c b/drivers/staging/keucr/smilsub.c index b315d5f..d4dd5ed 100644 --- a/drivers/staging/keucr/smilsub.c +++ b/drivers/staging/keucr/smilsub.c @@ -2,42 +2,37 @@ #include "usb.h" #include "scsiglue.h" #include "transport.h" -//#include "init.h" -//#include "stdlib.h" -//#include "EUCR6SK.h" #include "smcommon.h" #include "smil.h" -void _Set_D_SsfdcRdCmd (BYTE); -void _Set_D_SsfdcRdAddr (BYTE); -void _Set_D_SsfdcRdChip (void); -void _Set_D_SsfdcRdStandby (void); -void _Start_D_SsfdcRdHwECC (void); -void _Stop_D_SsfdcRdHwECC (void); -void _Load_D_SsfdcRdHwECC (BYTE); -void _Set_D_SsfdcWrCmd (BYTE); -void _Set_D_SsfdcWrAddr (BYTE); -void _Set_D_SsfdcWrBlock (void); -void _Set_D_SsfdcWrStandby (void); -void _Start_D_SsfdcWrHwECC (void); -void _Load_D_SsfdcWrHwECC (BYTE); -int _Check_D_SsfdcBusy (WORD); -int _Check_D_SsfdcStatus (void); -void _Reset_D_SsfdcErr (void); -void _Read_D_SsfdcBuf (BYTE *); -void _Write_D_SsfdcBuf (BYTE *); -void _Read_D_SsfdcByte (BYTE *); -void _ReadRedt_D_SsfdcBuf (BYTE *); -void _WriteRedt_D_SsfdcBuf (BYTE *); -BYTE _Check_D_DevCode (BYTE); - -void _Set_D_ECCdata (BYTE,BYTE *); -void _Calc_D_ECCdata (BYTE *); - -//void SM_ReadDataWithDMA (PFDO_DEVICE_EXTENSION, BYTE *, WORD); -//void SM_WriteDataWithDMA (PFDO_DEVICE_EXTENSION, BYTE *, WORD); -// +void _Set_D_SsfdcRdCmd(BYTE); +void _Set_D_SsfdcRdAddr(BYTE); +void _Set_D_SsfdcRdChip(void); +void _Set_D_SsfdcRdStandby(void); +void _Start_D_SsfdcRdHwECC(void); +void _Stop_D_SsfdcRdHwECC(void); +void _Load_D_SsfdcRdHwECC(BYTE); +void _Set_D_SsfdcWrCmd(BYTE); +void _Set_D_SsfdcWrAddr(BYTE); +void _Set_D_SsfdcWrBlock(void); +void _Set_D_SsfdcWrStandby(void); +void _Start_D_SsfdcWrHwECC(void); +void _Load_D_SsfdcWrHwECC(BYTE); +int _Check_D_SsfdcBusy(WORD); +int _Check_D_SsfdcStatus(void); +void _Reset_D_SsfdcErr(void); +void _Read_D_SsfdcBuf(BYTE *); +void _Write_D_SsfdcBuf(BYTE *); +void _Read_D_SsfdcByte(BYTE *); +void _ReadRedt_D_SsfdcBuf(BYTE *); +void _WriteRedt_D_SsfdcBuf(BYTE *); +BYTE _Check_D_DevCode(BYTE); + +void _Set_D_ECCdata(BYTE, BYTE *); +void _Calc_D_ECCdata(BYTE *); + + struct SSFDCTYPE Ssfdc; struct ADDRESS Media; struct CIS_AREA CisArea; @@ -49,221 +44,179 @@ extern DWORD ErrXDCode; extern WORD ReadBlock; extern WORD WriteBlock; -//KEVENT SM_DMADoneEvent; -#define EVEN 0 // Even Page for 256byte/page -#define ODD 1 // Odd Page for 256byte/page +#define EVEN 0 /* Even Page for 256byte/page */ +#define ODD 1 /* Odd Page for 256byte/page */ -//SmartMedia Redundant buffer data Control Subroutine -//----- Check_D_DataBlank() -------------------------------------------- + +/* SmartMedia Redundant buffer data Control Subroutine + *----- Check_D_DataBlank() -------------------------------------------- + */ int Check_D_DataBlank(BYTE *redundant) { char i; - for(i=0; i<REDTSIZE; i++) - if (*redundant++!=0xFF) - return(ERROR); + for (i = 0; i < REDTSIZE; i++) + if (*redundant++ != 0xFF) + return ERROR; - return(SMSUCCESS); + return SMSUCCESS; } -//----- Check_D_FailBlock() -------------------------------------------- +/* ----- Check_D_FailBlock() -------------------------------------------- */ int Check_D_FailBlock(BYTE *redundant) { - redundant+=REDT_BLOCK; + redundant += REDT_BLOCK; - if (*redundant==0xFF) - return(SMSUCCESS); + if (*redundant == 0xFF) + return SMSUCCESS; if (!*redundant) - return(ERROR); - if (hweight8(*redundant)<7) - return(ERROR); + return ERROR; + if (hweight8(*redundant) < 7) + return ERROR; - return(SMSUCCESS); + return SMSUCCESS; } -//----- Check_D_DataStatus() ------------------------------------------- +/* ----- Check_D_DataStatus() ------------------------------------------- */ int Check_D_DataStatus(BYTE *redundant) { - redundant+=REDT_DATA; + redundant += REDT_DATA; - if (*redundant==0xFF) - return(SMSUCCESS); - if (!*redundant) - { + if (*redundant == 0xFF) + return SMSUCCESS; + if (!*redundant) { ErrXDCode = ERR_DataStatus; - return(ERROR); - } - else + return ERROR; + } else ErrXDCode = NO_ERROR; - if (hweight8(*redundant)<5) - return(ERROR); + if (hweight8(*redundant) < 5) + return ERROR; - return(SMSUCCESS); + return SMSUCCESS; } -//----- Load_D_LogBlockAddr() ------------------------------------------ +/* ----- Load_D_LogBlockAddr() ------------------------------------------ */ int Load_D_LogBlockAddr(BYTE *redundant) { - WORD addr1,addr2; - //SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc; - //ADDRESS_T bb = (ADDRESS_T) &Media; + WORD addr1, addr2; - addr1=(WORD)*(redundant+REDT_ADDR1H)*0x0100+(WORD)*(redundant+REDT_ADDR1L); - addr2=(WORD)*(redundant+REDT_ADDR2H)*0x0100+(WORD)*(redundant+REDT_ADDR2L); + addr1 = (WORD)*(redundant + REDT_ADDR1H)*0x0100 + (WORD)*(redundant + REDT_ADDR1L); + addr2 = (WORD)*(redundant + REDT_ADDR2H)*0x0100 + (WORD)*(redundant + REDT_ADDR2L); - if (addr1==addr2) - if ((addr1 &0xF000)==0x1000) - { Media.LogBlock=(addr1 &0x0FFF)/2; return(SMSUCCESS); } + if (addr1 == addr2) + if ((addr1 & 0xF000) == 0x1000) { + Media.LogBlock = (addr1 & 0x0FFF) / 2; + return SMSUCCESS; + } - if (hweight16((WORD)(addr1^addr2))!=0x01) return(ERROR); + if (hweight16((WORD)(addr1^addr2)) != 0x01) + return ERROR; - if ((addr1 &0xF000)==0x1000) - if (!(hweight16(addr1) &0x01)) - { Media.LogBlock=(addr1 &0x0FFF)/2; return(SMSUCCESS); } + if ((addr1 & 0xF000) == 0x1000) + if (!(hweight16(addr1) & 0x01)) { + Media.LogBlock = (addr1 & 0x0FFF) / 2; + return SMSUCCESS; + } - if ((addr2 &0xF000)==0x1000) - if (!(hweight16(addr2) &0x01)) - { Media.LogBlock=(addr2 &0x0FFF)/2; return(SMSUCCESS); } + if ((addr2 & 0xF000) == 0x1000) + if (!(hweight16(addr2) & 0x01)) { + Media.LogBlock = (addr2 & 0x0FFF) / 2; + return SMSUCCESS; + } - return(ERROR); + return ERROR; } -//----- Clr_D_RedundantData() ------------------------------------------ +/* ----- Clr_D_RedundantData() ------------------------------------------ */ void Clr_D_RedundantData(BYTE *redundant) { char i; - for(i=0; i<REDTSIZE; i++) - *(redundant+i)=0xFF; + for (i = 0; i < REDTSIZE; i++) + *(redundant + i) = 0xFF; } -//----- Set_D_LogBlockAddr() ------------------------------------------- +/* ----- Set_D_LogBlockAddr() ------------------------------------------- */ void Set_D_LogBlockAddr(BYTE *redundant) { WORD addr; - *(redundant+REDT_BLOCK)=0xFF; - *(redundant+REDT_DATA) =0xFF; - addr=Media.LogBlock*2+0x1000; + *(redundant + REDT_BLOCK) = 0xFF; + *(redundant + REDT_DATA) = 0xFF; + addr = Media.LogBlock*2 + 0x1000; - if ((hweight16(addr)%2)) + if ((hweight16(addr) % 2)) addr++; - *(redundant+REDT_ADDR1H)=*(redundant+REDT_ADDR2H)=(BYTE)(addr/0x0100); - *(redundant+REDT_ADDR1L)=*(redundant+REDT_ADDR2L)=(BYTE)addr; + *(redundant + REDT_ADDR1H) = *(redundant + REDT_ADDR2H) = (BYTE)(addr / 0x0100); + *(redundant + REDT_ADDR1L) = *(redundant + REDT_ADDR2L) = (BYTE)addr; } -//----- Set_D_FailBlock() ---------------------------------------------- +/*----- Set_D_FailBlock() ---------------------------------------------- */ void Set_D_FailBlock(BYTE *redundant) { - char i; - - for(i=0; i<REDTSIZE; i++) - *redundant++=(BYTE)((i==REDT_BLOCK)?0xF0:0xFF); + char i; + for (i = 0; i < REDTSIZE; i++) + *redundant++ = (BYTE)((i == REDT_BLOCK) ? 0xF0 : 0xFF); } -//----- Set_D_DataStaus() ---------------------------------------------- +/* ----- Set_D_DataStaus() ---------------------------------------------- */ void Set_D_DataStaus(BYTE *redundant) { - redundant+=REDT_DATA; - *redundant=0x00; + redundant += REDT_DATA; + *redundant = 0x00; } -//SmartMedia Function Command Subroutine -// 6250 CMD 6 -//----- Ssfdc_D_Reset() ------------------------------------------------ +/* SmartMedia Function Command Subroutine + * 6250 CMD 6 + */ +/* ----- Ssfdc_D_Reset() ------------------------------------------------ */ void Ssfdc_D_Reset(struct us_data *us) { - //NTSTATUS ntStatus = STATUS_SUCCESS; - //PBULK_CBW pBulkCbw = fdoExt->pBulkCbw; - //BYTE buf[0x200]; - - //printk("Ssfdc_D_Reset --- But do nothing !!\n"); return; -/* RtlZeroMemory(pBulkCbw, sizeof(struct _BULK_CBW)); - pBulkCbw->dCBWSignature = CBW_SIGNTURE; - pBulkCbw->bCBWLun = CBW_LUN; - //pBulkCbw->dCBWDataTransferLength = 0x200; - pBulkCbw->bmCBWFlags = 0x80; - pBulkCbw->CBWCb[0] = 0xF2; - pBulkCbw->CBWCb[1] = 0x07; - - ntStatus = ENE_SendScsiCmd(fdoExt, FDIR_READ, NULL); - - if (!NT_SUCCESS(ntStatus)) - { - ENE_Print("Ssfdc_D_Reset Fail !!\n"); - //return ntStatus; - }*/ } -//----- Ssfdc_D_ReadCisSect() ------------------------------------------ -int Ssfdc_D_ReadCisSect(struct us_data *us, BYTE *buf,BYTE *redundant) +/* ----- Ssfdc_D_ReadCisSect() ------------------------------------------ */ +int Ssfdc_D_ReadCisSect(struct us_data *us, BYTE *buf, BYTE *redundant) { - BYTE zone,sector; + BYTE zone, sector; WORD block; - //SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc; - //ADDRESS_T bb = (ADDRESS_T) &Media; - - zone=Media.Zone; block=Media.PhyBlock; sector=Media.Sector; - Media.Zone=0; - Media.PhyBlock=CisArea.PhyBlock; - Media.Sector=CisArea.Sector; - - if (Ssfdc_D_ReadSect(us,buf,redundant)) - { - Media.Zone=zone; Media.PhyBlock=block; Media.Sector=sector; - return(ERROR); + + zone = Media.Zone; block = Media.PhyBlock; sector = Media.Sector; + Media.Zone = 0; + Media.PhyBlock = CisArea.PhyBlock; + Media.Sector = CisArea.Sector; + + if (Ssfdc_D_ReadSect(us, buf, redundant)) { + Media.Zone = zone; Media.PhyBlock = block; Media.Sector = sector; + return ERROR; } - Media.Zone=zone; Media.PhyBlock=block; Media.Sector=sector; - return(SMSUCCESS); + Media.Zone = zone; Media.PhyBlock = block; Media.Sector = sector; + return SMSUCCESS; } -/* -////----- Ssfdc_D_WriteRedtMode() ---------------------------------------- -//void Ssfdc_D_WriteRedtMode(void) -//{ -// _Set_D_SsfdcRdCmd (RST_CHIP); -// _Check_D_SsfdcBusy (BUSY_RESET); -// _Set_D_SsfdcRdCmd (READ_REDT); -// _Check_D_SsfdcBusy (BUSY_READ); -// _Set_D_SsfdcRdStandby (); -//} -// -////----- Ssfdc_D_ReadID() ----------------------------------------------- -//void Ssfdc_D_ReadID(BYTE *buf, BYTE ReadID) -//{ -// _Set_D_SsfdcRdCmd (ReadID); -// _Set_D_SsfdcRdChip (); -// _Read_D_SsfdcByte (buf++); -// _Read_D_SsfdcByte (buf++); -// _Read_D_SsfdcByte (buf++); -// _Read_D_SsfdcByte (buf); -// _Set_D_SsfdcRdStandby (); -//} -*/ -// 6250 CMD 1 -//----- Ssfdc_D_ReadSect() --------------------------------------------- -int Ssfdc_D_ReadSect(struct us_data *us, BYTE *buf,BYTE *redundant) + +/* 6250 CMD 1 */ +/* ----- Ssfdc_D_ReadSect() --------------------------------------------- */ +int Ssfdc_D_ReadSect(struct us_data *us, BYTE *buf, BYTE *redundant) { struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; int result; WORD addr; result = ENE_LoadBinCode(us, SM_RW_PATTERN); - if (result != USB_STOR_XFER_GOOD) - { + if (result != USB_STOR_XFER_GOOD) { printk("Load SM RW Code Fail !!\n"); return USB_STOR_TRANSPORT_ERROR; } - addr = (WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock; - addr = addr*(WORD)Ssfdc.MaxSectors+Media.Sector; + addr = (WORD)Media.Zone*Ssfdc.MaxBlocks + Media.PhyBlock; + addr = addr*(WORD)Ssfdc.MaxSectors + Media.Sector; - // Read sect data + /* Read sect data */ memset(bcb, 0, sizeof(struct bulk_cb_wrap)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x200; @@ -271,14 +224,14 @@ int Ssfdc_D_ReadSect(struct us_data *us, BYTE *buf,BYTE *redundant) bcb->CDB[0] = 0xF1; bcb->CDB[1] = 0x02; bcb->CDB[4] = (BYTE)addr; - bcb->CDB[3] = (BYTE)(addr/0x0100); - bcb->CDB[2] = Media.Zone/2; + bcb->CDB[3] = (BYTE)(addr / 0x0100); + bcb->CDB[2] = Media.Zone / 2; result = ENE_SendScsiCmd(us, FDIR_READ, buf, 0); if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - // Read redundant + /* Read redundant */ memset(bcb, 0, sizeof(struct bulk_cb_wrap)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x10; @@ -286,8 +239,8 @@ int Ssfdc_D_ReadSect(struct us_data *us, BYTE *buf,BYTE *redundant) bcb->CDB[0] = 0xF1; bcb->CDB[1] = 0x03; bcb->CDB[4] = (BYTE)addr; - bcb->CDB[3] = (BYTE)(addr/0x0100); - bcb->CDB[2] = Media.Zone/2; + bcb->CDB[3] = (BYTE)(addr / 0x0100); + bcb->CDB[2] = Media.Zone / 2; bcb->CDB[8] = 0; bcb->CDB[9] = 1; @@ -298,25 +251,23 @@ int Ssfdc_D_ReadSect(struct us_data *us, BYTE *buf,BYTE *redundant) return USB_STOR_TRANSPORT_GOOD; } -//----- Ssfdc_D_ReadBlock() --------------------------------------------- -int Ssfdc_D_ReadBlock(struct us_data *us, WORD count, BYTE *buf,BYTE *redundant) +/* ----- Ssfdc_D_ReadBlock() --------------------------------------------- */ +int Ssfdc_D_ReadBlock(struct us_data *us, WORD count, BYTE *buf, BYTE *redundant) { struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; int result; WORD addr; - //printk("Ssfdc_D_ReadBlock\n"); result = ENE_LoadBinCode(us, SM_RW_PATTERN); - if (result != USB_STOR_XFER_GOOD) - { + if (result != USB_STOR_XFER_GOOD) { printk("Load SM RW Code Fail !!\n"); return USB_STOR_TRANSPORT_ERROR; } - addr = (WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock; - addr = addr*(WORD)Ssfdc.MaxSectors+Media.Sector; + addr = (WORD)Media.Zone*Ssfdc.MaxBlocks + Media.PhyBlock; + addr = addr*(WORD)Ssfdc.MaxSectors + Media.Sector; - // Read sect data + /* Read sect data */ memset(bcb, 0, sizeof(struct bulk_cb_wrap)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x200*count; @@ -324,14 +275,14 @@ int Ssfdc_D_ReadBlock(struct us_data *us, WORD count, BYTE *buf,BYTE *redundant) bcb->CDB[0] = 0xF1; bcb->CDB[1] = 0x02; bcb->CDB[4] = (BYTE)addr; - bcb->CDB[3] = (BYTE)(addr/0x0100); - bcb->CDB[2] = Media.Zone/2; + bcb->CDB[3] = (BYTE)(addr / 0x0100); + bcb->CDB[2] = Media.Zone / 2; result = ENE_SendScsiCmd(us, FDIR_READ, buf, 0); if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - // Read redundant + /* Read redundant */ memset(bcb, 0, sizeof(struct bulk_cb_wrap)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x10; @@ -339,8 +290,8 @@ int Ssfdc_D_ReadBlock(struct us_data *us, WORD count, BYTE *buf,BYTE *redundant) bcb->CDB[0] = 0xF1; bcb->CDB[1] = 0x03; bcb->CDB[4] = (BYTE)addr; - bcb->CDB[3] = (BYTE)(addr/0x0100); - bcb->CDB[2] = Media.Zone/2; + bcb->CDB[3] = (BYTE)(addr / 0x0100); + bcb->CDB[2] = Media.Zone / 2; bcb->CDB[8] = 0; bcb->CDB[9] = 1; @@ -350,190 +301,27 @@ int Ssfdc_D_ReadBlock(struct us_data *us, WORD count, BYTE *buf,BYTE *redundant) return USB_STOR_TRANSPORT_GOOD; } -/* -////----- Ssfdc_D_ReadSect_DMA() --------------------------------------------- -//int Ssfdc_D_ReadSect_DMA(PFDO_DEVICE_EXTENSION fdoExt, BYTE *buf,BYTE *redundant) -//{ -// WORD SectByteCount, addr; -// DWORD Buffer[4]; -// WORD len; -// -// if (!_Hw_D_ChkCardIn()) -// return(ERROR); -// addr=(WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock; -// addr=addr*(WORD)Ssfdc.MaxSectors+Media.Sector; -// // cycle starting address -// SM_STARTADDR_LSB = 0x00; -// SM_STARTADDR_IISB = (BYTE)addr; -// SM_STARTADDR_IIISB = (BYTE)(addr/0x0100); -// SM_STARTADDR_MSB = Media.Zone/2; -// -// //Sector byte count = 0x200(DMA) -// SectByteCount = 0x20f; -// SM_BYTECNT_LO = (BYTE)SectByteCount; -// SM_CMD_CTRL3 = (SM_CMD_CTRL3 & 0xFC) | (BYTE)(SectByteCount/0x0100); -// if ( ((fdoExt->ChipID==READER_CB712)&&(fdoExt->RevID==CHIP_A)) || fdoExt->IsHibernate ) -// SM_FIFO_CTRL = (SM_APB08_MASK | SM_DMAEN_MASK | SM_DMA_UPSTREAM_MASK | SM_FIFOSHLDVLU_8_MASK); -// else -// SM_FIFO_CTRL = (SM_APB32_MASK | SM_DMAEN_MASK | SM_DMA_UPSTREAM_MASK | SM_FIFOSHLDVLU_8_MASK); -// -// _Hw_D_EccRdReset(); -// _Hw_D_EccRdStart(); -// -// SM_CMD_CTRL1 = (SM_CMD_READ_1); -// SM_CMD_CTRL1 = (SM_CMD_READ_1 | SM_CMD_START_BIT); -// -// SectByteCount = 0x1ff; -// //SM_ReadDataWithDMA(fdoExt, buf, SectByteCount); -// //_ReadRedt_D_SsfdcBuf(redundant); -// len = 0x1000 - ((WORD)(buf) & 0x0FFF); -// if (len < 0x200) -// { -// SM_ReadDataWithDMA(fdoExt, buf, len-1); -// SM_ReadDataWithDMA(fdoExt, buf+len, SectByteCount-len); -// //ENE_Print("Read DMA !!! buf1 = %p, len = %x, buf2 = %p\n", buf, len, buf+len); -// } -// else -// SM_ReadDataWithDMA(fdoExt, buf, SectByteCount); -// -// if ( ((fdoExt->ChipID==READER_CB712)&&(fdoExt->RevID==CHIP_A)) || fdoExt->IsHibernate ) -// { -// _ReadRedt_D_SsfdcBuf(redundant); -// } -// else -// { -// Buffer[0] = READ_PORT_DWORD(SM_REG_DATA); -// Buffer[1] = READ_PORT_DWORD(SM_REG_DATA); -// Buffer[2] = READ_PORT_DWORD(SM_REG_DATA); -// Buffer[3] = READ_PORT_DWORD(SM_REG_DATA); -// memcpy(redundant, Buffer, 0x10); -// } -// -// while ( _Hw_D_ChkCardIn() ) -// { -// if((READ_PORT_BYTE(SM_REG_INT_STATUS) & 0x10)) -// { -// WRITE_PORT_BYTE(SM_REG_INT_STATUS, 0x10); -// break; -// } -// } -// _Hw_D_EccRdStop(); -// _Hw_D_SetRdStandby(); -// _Load_D_SsfdcRdHwECC(EVEN); -// -// _Calc_D_ECCdata(buf); -// _Set_D_SsfdcRdStandby(); -// -// if (!_Hw_D_ChkCardIn()) -// return(ERROR); -// return(SMSUCCESS); -//} -// -////----- Ssfdc_D_ReadSect_PIO() --------------------------------------------- -//int Ssfdc_D_ReadSect_PIO(PFDO_DEVICE_EXTENSION fdoExt, BYTE *buf,BYTE *redundant) -//{ -// _Set_D_SsfdcRdCmd(READ); -// _Set_D_SsfdcRdAddr(EVEN); -// -// if (_Check_D_SsfdcBusy(BUSY_READ)) -// { _Reset_D_SsfdcErr(); return(ERROR); } -// -// _Start_D_SsfdcRdHwECC(); -// _Read_D_SsfdcBuf(buf); -// _Stop_D_SsfdcRdHwECC(); -// _ReadRedt_D_SsfdcBuf(redundant); -// _Load_D_SsfdcRdHwECC(EVEN); -// -// if (_Check_D_SsfdcBusy(BUSY_READ)) -// { _Reset_D_SsfdcErr(); return(ERROR); } -// -// _Calc_D_ECCdata(buf); -// _Set_D_SsfdcRdStandby(); -// return(SMSUCCESS); -//} - -// 6250 CMD 3 -//----- Ssfdc_D_WriteSect() -------------------------------------------- -int Ssfdc_D_WriteSect(PFDO_DEVICE_EXTENSION fdoExt, BYTE *buf,BYTE *redundant) -{ - PBULK_CBW pBulkCbw = fdoExt->pBulkCbw; - NTSTATUS ntStatus; - WORD addr; - - //ENE_Print("SMILSUB --- Ssfdc_D_WriteSect\n"); - ENE_LoadBinCode(fdoExt, SM_RW_PATTERN); - - addr = (WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock; - addr = addr*(WORD)Ssfdc.MaxSectors+Media.Sector; - - // Write sect data - RtlZeroMemory(pBulkCbw, sizeof(struct _BULK_CBW)); - pBulkCbw->dCBWSignature = CBW_SIGNTURE; - pBulkCbw->bCBWLun = CBW_LUN; - pBulkCbw->dCBWDataTransferLength = 0x200; - pBulkCbw->bmCBWFlags = 0x00; - pBulkCbw->CBWCb[0] = 0xF0; - pBulkCbw->CBWCb[1] = 0x04; - //pBulkCbw->CBWCb[4] = (BYTE)addr; - //pBulkCbw->CBWCb[3] = (BYTE)(addr/0x0100); - //pBulkCbw->CBWCb[2] = Media.Zone/2; - //pBulkCbw->CBWCb[5] = *(redundant+REDT_ADDR1H); - //pBulkCbw->CBWCb[6] = *(redundant+REDT_ADDR1L); - pBulkCbw->CBWCb[7] = (BYTE)addr; - pBulkCbw->CBWCb[6] = (BYTE)(addr/0x0100); - pBulkCbw->CBWCb[5] = Media.Zone/2; - pBulkCbw->CBWCb[8] = *(redundant+REDT_ADDR1H); - pBulkCbw->CBWCb[9] = *(redundant+REDT_ADDR1L); - - ntStatus = ENE_SendScsiCmd(fdoExt, FDIR_WRITE, buf); - - if (!NT_SUCCESS(ntStatus)) - return(ERROR); - -// // For Test -// { -// BYTE bf[0x200], rdd[0x10]; -// ULONG i; -// -// RtlZeroMemory(bf, 0x200); -// RtlZeroMemory(rdd, 0x10); -// ntStatus = SM_ReadBlock(fdoExt, bf, rdd); -// for (i=0; i<0x200; i++) -// { -// if (buf[i] != bf[i]) -// ENE_Print("buf[%x] = %x, bf[%x] = %x\n", buf, bf); -// } -// if (!NT_SUCCESS(ntStatus)) -// ENE_Print("Error\n"); -// } - - return(SMSUCCESS); -} -*/ -//----- Ssfdc_D_CopyBlock() -------------------------------------------- -int Ssfdc_D_CopyBlock(struct us_data *us, WORD count, BYTE *buf,BYTE *redundant) + + +/* ----- Ssfdc_D_CopyBlock() -------------------------------------------- */ +int Ssfdc_D_CopyBlock(struct us_data *us, WORD count, BYTE *buf, BYTE *redundant) { struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; int result; - //PBULK_CBW pBulkCbw = fdoExt->pBulkCbw; - //NTSTATUS ntStatus; WORD ReadAddr, WriteAddr; - //printk("Ssfdc_D_WriteSect --- ZONE = %x, ReadBlock = %x, WriteBlock = %x\n", Media.Zone, ReadBlock, WriteBlock); - result = ENE_LoadBinCode(us, SM_RW_PATTERN); - if (result != USB_STOR_XFER_GOOD) - { + if (result != USB_STOR_XFER_GOOD) { printk("Load SM RW Code Fail !!\n"); return USB_STOR_TRANSPORT_ERROR; } - ReadAddr = (WORD)Media.Zone*Ssfdc.MaxBlocks+ReadBlock; + ReadAddr = (WORD)Media.Zone*Ssfdc.MaxBlocks + ReadBlock; ReadAddr = ReadAddr*(WORD)Ssfdc.MaxSectors; - WriteAddr = (WORD)Media.Zone*Ssfdc.MaxBlocks+WriteBlock; + WriteAddr = (WORD)Media.Zone*Ssfdc.MaxBlocks + WriteBlock; WriteAddr = WriteAddr*(WORD)Ssfdc.MaxSectors; - // Write sect data + /* Write sect data */ memset(bcb, 0, sizeof(struct bulk_cb_wrap)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x200*count; @@ -541,19 +329,17 @@ int Ssfdc_D_CopyBlock(struct us_data *us, WORD count, BYTE *buf,BYTE *redundant) bcb->CDB[0] = 0xF0; bcb->CDB[1] = 0x08; bcb->CDB[7] = (BYTE)WriteAddr; - bcb->CDB[6] = (BYTE)(WriteAddr/0x0100); - bcb->CDB[5] = Media.Zone/2; - bcb->CDB[8] = *(redundant+REDT_ADDR1H); - bcb->CDB[9] = *(redundant+REDT_ADDR1L); + bcb->CDB[6] = (BYTE)(WriteAddr / 0x0100); + bcb->CDB[5] = Media.Zone / 2; + bcb->CDB[8] = *(redundant + REDT_ADDR1H); + bcb->CDB[9] = *(redundant + REDT_ADDR1L); bcb->CDB[10] = Media.Sector; - if (ReadBlock != NO_ASSIGN) - { + if (ReadBlock != NO_ASSIGN) { bcb->CDB[4] = (BYTE)ReadAddr; - bcb->CDB[3] = (BYTE)(ReadAddr/0x0100); - bcb->CDB[2] = Media.Zone/2; - } - else + bcb->CDB[3] = (BYTE)(ReadAddr / 0x0100); + bcb->CDB[2] = Media.Zone / 2; + } else bcb->CDB[11] = 1; result = ENE_SendScsiCmd(us, FDIR_WRITE, buf, 0); @@ -562,196 +348,25 @@ int Ssfdc_D_CopyBlock(struct us_data *us, WORD count, BYTE *buf,BYTE *redundant) return USB_STOR_TRANSPORT_GOOD; } -/* -//----- Ssfdc_D_WriteBlock() -------------------------------------------- -int Ssfdc_D_WriteBlock(PFDO_DEVICE_EXTENSION fdoExt, WORD count, BYTE *buf,BYTE *redundant) -{ - PBULK_CBW pBulkCbw = fdoExt->pBulkCbw; - NTSTATUS ntStatus; - WORD addr; - - //ENE_Print("SMILSUB --- Ssfdc_D_WriteSect\n"); - ENE_LoadBinCode(fdoExt, SM_RW_PATTERN); - - addr = (WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock; - addr = addr*(WORD)Ssfdc.MaxSectors+Media.Sector; - - // Write sect data - RtlZeroMemory(pBulkCbw, sizeof(struct _BULK_CBW)); - pBulkCbw->dCBWSignature = CBW_SIGNTURE; - pBulkCbw->bCBWLun = CBW_LUN; - pBulkCbw->dCBWDataTransferLength = 0x200*count; - pBulkCbw->bmCBWFlags = 0x00; - pBulkCbw->CBWCb[0] = 0xF0; - pBulkCbw->CBWCb[1] = 0x04; - pBulkCbw->CBWCb[7] = (BYTE)addr; - pBulkCbw->CBWCb[6] = (BYTE)(addr/0x0100); - pBulkCbw->CBWCb[5] = Media.Zone/2; - pBulkCbw->CBWCb[8] = *(redundant+REDT_ADDR1H); - pBulkCbw->CBWCb[9] = *(redundant+REDT_ADDR1L); - - ntStatus = ENE_SendScsiCmd(fdoExt, FDIR_WRITE, buf); - - if (!NT_SUCCESS(ntStatus)) - return(ERROR); - -// // For Test -// { -// BYTE bf[0x200], rdd[0x10]; -// ULONG i; -// -// RtlZeroMemory(bf, 0x200); -// RtlZeroMemory(rdd, 0x10); -// ntStatus = SM_ReadBlock(fdoExt, bf, rdd); -// for (i=0; i<0x200; i++) -// { -// if (buf[i] != bf[i]) -// ENE_Print("buf[%x] = %x, bf[%x] = %x\n", buf, bf); -// } -// if (!NT_SUCCESS(ntStatus)) -// ENE_Print("Error\n"); -// } - - return(SMSUCCESS); -} -// -////----- Ssfdc_D_WriteSect_DMA() -------------------------------------------- -//int Ssfdc_D_WriteSect_DMA(PFDO_DEVICE_EXTENSION fdoExt, BYTE *buf,BYTE *redundant) -//{ -// WORD SectByteCount, addr; -// DWORD Buffer[4]; -// WORD len; -// -// if (!_Hw_D_ChkCardIn()) -// return(ERROR); -// addr=(WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock; -// addr=addr*(WORD)Ssfdc.MaxSectors+Media.Sector; -// // cycle starting address -// SM_STARTADDR_LSB = 0x00; -// SM_STARTADDR_IISB = (BYTE)addr; -// SM_STARTADDR_IIISB = (BYTE)(addr/0x0100); -// SM_STARTADDR_MSB = Media.Zone/2; -// -// //Sector byte count (DMA) -// SectByteCount = 0x20f; -// SM_BYTECNT_LO = (BYTE)SectByteCount; -// SM_CMD_CTRL3 = (SM_CMD_CTRL3 & 0xFC) | 0x20 | (BYTE)(SectByteCount/0x0100); -// if ( ((fdoExt->ChipID==READER_CB712)&&(fdoExt->RevID==CHIP_A)) || fdoExt->IsHibernate ) -// SM_FIFO_CTRL = (SM_APB08_MASK | SM_DMAEN_MASK | SM_DMA_DOWNSTREAM_MASK | SM_FIFOSHLDVLU_8_MASK); -// else -// SM_FIFO_CTRL = (SM_APB32_MASK | SM_DMAEN_MASK | SM_DMA_DOWNSTREAM_MASK | SM_FIFOSHLDVLU_8_MASK); -// -// _Hw_D_EccRdReset(); -// _Hw_D_EccRdStart(); -// -// SM_CMD_CTRL1 = SM_CMD_PAGPRGM_TRUE; -// SM_CMD_CTRL1 = (SM_CMD_PAGPRGM_TRUE | SM_CMD_START_BIT); -// -// SectByteCount = 0x1ff; -// //SM_WriteDataWithDMA(fdoExt, buf, SectByteCount); -// //_WriteRedt_D_SsfdcBuf(redundant); -// len = 0x1000 - ((WORD)(buf) & 0x0FFF); -// if (len < 0x200) -// { -// SM_WriteDataWithDMA(fdoExt, buf, len-1); -// SM_WriteDataWithDMA(fdoExt, buf+len, SectByteCount-len); -// //ENE_Print("Read DMA !!! buf1 = %p, len = %x, buf2 = %p\n", buf, len, buf+len); -// } -// else -// SM_WriteDataWithDMA(fdoExt, buf, SectByteCount); -// -// //T1 = (ULONGLONG)buf & 0xFFFFFFFFFFFFF000; -// //T2 = ((ULONGLONG)buf + 0x1FF) & 0xFFFFFFFFFFFFF000; -// //if (T1 != T2) -// // ENE_Print("Ssfdc_D_WriteSect_DMA !!! buf = %p, T1 = %p, T2 = %p\n", buf, T1, T2); -// //if (T2-T1) -// //{ -// // l1 = (WORD)(T2 - (ULONGLONG)buf); -// // SM_WriteDataWithDMA(fdoExt, buf, l1-1); -// // SM_WriteDataWithDMA(fdoExt, (PBYTE)T2, SectByteCount-l1); -// //} -// //else -// // SM_WriteDataWithDMA(fdoExt, buf, SectByteCount); -// -// if ( ((fdoExt->ChipID==READER_CB712)&&(fdoExt->RevID==CHIP_A)) || fdoExt->IsHibernate ) -// { -// _WriteRedt_D_SsfdcBuf(redundant); -// } -// else -// { -// memcpy(Buffer, redundant, 0x10); -// WRITE_PORT_DWORD(SM_REG_DATA, Buffer[0]); -// WRITE_PORT_DWORD(SM_REG_DATA, Buffer[1]); -// WRITE_PORT_DWORD(SM_REG_DATA, Buffer[2]); -// WRITE_PORT_DWORD(SM_REG_DATA, Buffer[3]); -// } -// -// while ( _Hw_D_ChkCardIn() ) -// { -// if ((READ_PORT_BYTE(SM_REG_INT_STATUS) & 0x10)) -// { -// WRITE_PORT_BYTE(SM_REG_INT_STATUS, 0x10); -// break; -// } -// } -// _Hw_D_EccRdStop(); -// _Hw_D_SetRdStandby(); -// -// _Set_D_SsfdcWrStandby(); -// _Set_D_SsfdcRdStandby(); -// if (!_Hw_D_ChkCardIn()) -// return(ERROR); -// -// return(SMSUCCESS); -//} -// -////----- Ssfdc_D_WriteSect_PIO() -------------------------------------------- -//int Ssfdc_D_WriteSect_PIO(PFDO_DEVICE_EXTENSION fdoExt, BYTE *buf,BYTE *redundant) -//{ -// _Calc_D_ECCdata(buf); -// _Set_D_SsfdcWrCmd(WRDATA); -// _Set_D_SsfdcWrAddr(EVEN); -// _Start_D_SsfdcWrHwECC(); -// -// _Write_D_SsfdcBuf(buf); -// -// _Load_D_SsfdcWrHwECC(EVEN); -// _Set_D_ECCdata(EVEN,redundant); -// -// _WriteRedt_D_SsfdcBuf(redundant); -// -// _Set_D_SsfdcWrCmd(WRITE); -// -// if (_Check_D_SsfdcBusy(BUSY_PROG)) -// { _Reset_D_SsfdcErr(); return(ERROR); } -// -// _Set_D_SsfdcWrStandby(); -// _Set_D_SsfdcRdStandby(); -// return(SMSUCCESS); -//} -*/ -//----- Ssfdc_D_WriteSectForCopy() ------------------------------------- + +/* ----- Ssfdc_D_WriteSectForCopy() ------------------------------------- */ int Ssfdc_D_WriteSectForCopy(struct us_data *us, BYTE *buf, BYTE *redundant) { struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; int result; - //PBULK_CBW pBulkCbw = fdoExt->pBulkCbw; - //NTSTATUS ntStatus; - WORD addr; + WORD addr; - //printk("SMILSUB --- Ssfdc_D_WriteSectForCopy\n"); result = ENE_LoadBinCode(us, SM_RW_PATTERN); - if (result != USB_STOR_XFER_GOOD) - { + if (result != USB_STOR_XFER_GOOD) { printk("Load SM RW Code Fail !!\n"); return USB_STOR_TRANSPORT_ERROR; } - addr = (WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock; - addr = addr*(WORD)Ssfdc.MaxSectors+Media.Sector; + addr = (WORD)Media.Zone*Ssfdc.MaxBlocks + Media.PhyBlock; + addr = addr*(WORD)Ssfdc.MaxSectors + Media.Sector; - // Write sect data + /* Write sect data */ memset(bcb, 0, sizeof(struct bulk_cb_wrap)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x200; @@ -759,10 +374,10 @@ int Ssfdc_D_WriteSectForCopy(struct us_data *us, BYTE *buf, BYTE *redundant) bcb->CDB[0] = 0xF0; bcb->CDB[1] = 0x04; bcb->CDB[7] = (BYTE)addr; - bcb->CDB[6] = (BYTE)(addr/0x0100); - bcb->CDB[5] = Media.Zone/2; - bcb->CDB[8] = *(redundant+REDT_ADDR1H); - bcb->CDB[9] = *(redundant+REDT_ADDR1L); + bcb->CDB[6] = (BYTE)(addr / 0x0100); + bcb->CDB[5] = Media.Zone / 2; + bcb->CDB[8] = *(redundant + REDT_ADDR1H); + bcb->CDB[9] = *(redundant + REDT_ADDR1L); result = ENE_SendScsiCmd(us, FDIR_WRITE, buf, 0); if (result != USB_STOR_XFER_GOOD) @@ -771,8 +386,8 @@ int Ssfdc_D_WriteSectForCopy(struct us_data *us, BYTE *buf, BYTE *redundant) return USB_STOR_TRANSPORT_GOOD; } -// 6250 CMD 5 -//----- Ssfdc_D_EraseBlock() ------------------------------------------- +/* 6250 CMD 5 */ +/* ----- Ssfdc_D_EraseBlock() ------------------------------------------- */ int Ssfdc_D_EraseBlock(struct us_data *us) { struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; @@ -780,14 +395,13 @@ int Ssfdc_D_EraseBlock(struct us_data *us) WORD addr; result = ENE_LoadBinCode(us, SM_RW_PATTERN); - if (result != USB_STOR_XFER_GOOD) - { + if (result != USB_STOR_XFER_GOOD) { printk("Load SM RW Code Fail !!\n"); return USB_STOR_TRANSPORT_ERROR; } - addr=(WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock; - addr=addr*(WORD)Ssfdc.MaxSectors; + addr = (WORD)Media.Zone*Ssfdc.MaxBlocks + Media.PhyBlock; + addr = addr*(WORD)Ssfdc.MaxSectors; memset(bcb, 0, sizeof(struct bulk_cb_wrap)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); @@ -796,8 +410,8 @@ int Ssfdc_D_EraseBlock(struct us_data *us) bcb->CDB[0] = 0xF2; bcb->CDB[1] = 0x06; bcb->CDB[7] = (BYTE)addr; - bcb->CDB[6] = (BYTE)(addr/0x0100); - bcb->CDB[5] = Media.Zone/2; + bcb->CDB[6] = (BYTE)(addr / 0x0100); + bcb->CDB[5] = Media.Zone / 2; result = ENE_SendScsiCmd(us, FDIR_READ, NULL, 0); if (result != USB_STOR_XFER_GOOD) @@ -806,24 +420,23 @@ int Ssfdc_D_EraseBlock(struct us_data *us) return USB_STOR_TRANSPORT_GOOD; } -// 6250 CMD 2 -//----- Ssfdc_D_ReadRedtData() ----------------------------------------- +/* 6250 CMD 2 */ +/*----- Ssfdc_D_ReadRedtData() ----------------------------------------- */ int Ssfdc_D_ReadRedtData(struct us_data *us, BYTE *redundant) { struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; int result; WORD addr; - BYTE *buf; + BYTE *buf; result = ENE_LoadBinCode(us, SM_RW_PATTERN); - if (result != USB_STOR_XFER_GOOD) - { + if (result != USB_STOR_XFER_GOOD) { printk("Load SM RW Code Fail !!\n"); return USB_STOR_TRANSPORT_ERROR; } - addr = (WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock; - addr = addr*(WORD)Ssfdc.MaxSectors+Media.Sector; + addr = (WORD)Media.Zone*Ssfdc.MaxBlocks + Media.PhyBlock; + addr = addr*(WORD)Ssfdc.MaxSectors + Media.Sector; memset(bcb, 0, sizeof(struct bulk_cb_wrap)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); @@ -832,13 +445,12 @@ int Ssfdc_D_ReadRedtData(struct us_data *us, BYTE *redundant) bcb->CDB[0] = 0xF1; bcb->CDB[1] = 0x03; bcb->CDB[4] = (BYTE)addr; - bcb->CDB[3] = (BYTE)(addr/0x0100); - bcb->CDB[2] = Media.Zone/2; + bcb->CDB[3] = (BYTE)(addr / 0x0100); + bcb->CDB[2] = Media.Zone / 2; bcb->CDB[8] = 0; bcb->CDB[9] = 1; buf = kmalloc(0x10, GFP_KERNEL); - //result = ENE_SendScsiCmd(us, FDIR_READ, redundant, 0); result = ENE_SendScsiCmd(us, FDIR_READ, buf, 0); memcpy(redundant, buf, 0x10); kfree(buf); @@ -848,25 +460,22 @@ int Ssfdc_D_ReadRedtData(struct us_data *us, BYTE *redundant) return USB_STOR_TRANSPORT_GOOD; } -// 6250 CMD 4 -//----- Ssfdc_D_WriteRedtData() ---------------------------------------- +/* 6250 CMD 4 */ +/* ----- Ssfdc_D_WriteRedtData() ---------------------------------------- */ int Ssfdc_D_WriteRedtData(struct us_data *us, BYTE *redundant) { struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; int result; - //PBULK_CBW pBulkCbw = fdoExt->pBulkCbw; - //NTSTATUS ntStatus; WORD addr; result = ENE_LoadBinCode(us, SM_RW_PATTERN); - if (result != USB_STOR_XFER_GOOD) - { + if (result != USB_STOR_XFER_GOOD) { printk("Load SM RW Code Fail !!\n"); return USB_STOR_TRANSPORT_ERROR; } - addr = (WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock; - addr = addr*(WORD)Ssfdc.MaxSectors+Media.Sector; + addr = (WORD)Media.Zone*Ssfdc.MaxBlocks + Media.PhyBlock; + addr = addr*(WORD)Ssfdc.MaxSectors + Media.Sector; memset(bcb, 0, sizeof(struct bulk_cb_wrap)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); @@ -875,10 +484,10 @@ int Ssfdc_D_WriteRedtData(struct us_data *us, BYTE *redundant) bcb->CDB[0] = 0xF2; bcb->CDB[1] = 0x05; bcb->CDB[7] = (BYTE)addr; - bcb->CDB[6] = (BYTE)(addr/0x0100); - bcb->CDB[5] = Media.Zone/2; - bcb->CDB[8] = *(redundant+REDT_ADDR1H); - bcb->CDB[9] = *(redundant+REDT_ADDR1L); + bcb->CDB[6] = (BYTE)(addr / 0x0100); + bcb->CDB[5] = Media.Zone / 2; + bcb->CDB[8] = *(redundant + REDT_ADDR1H); + bcb->CDB[9] = *(redundant + REDT_ADDR1L); result = ENE_SendScsiCmd(us, FDIR_READ, NULL, 0); if (result != USB_STOR_XFER_GOOD) @@ -887,609 +496,167 @@ int Ssfdc_D_WriteRedtData(struct us_data *us, BYTE *redundant) return USB_STOR_TRANSPORT_GOOD; } -//----- Ssfdc_D_CheckStatus() ------------------------------------------ +/* ----- Ssfdc_D_CheckStatus() ------------------------------------------ */ int Ssfdc_D_CheckStatus(void) { - // Driver ¤£°µ - return(SMSUCCESS); - //_Set_D_SsfdcRdCmd(RDSTATUS); - // - //if (_Check_D_SsfdcStatus()) - //{ _Set_D_SsfdcRdStandby(); return(ERROR); } - // - //_Set_D_SsfdcRdStandby(); - //return(SMSUCCESS); + return SMSUCCESS; } -/* -////NAND Memory (SmartMedia) Control Subroutine for Read Data -////----- _Set_D_SsfdcRdCmd() -------------------------------------------- -//void _Set_D_SsfdcRdCmd(BYTE cmd) -//{ -// _Hw_D_SetRdCmd(); -// _Hw_D_OutData(cmd); -// _Hw_D_SetRdData(); -//} -// -////----- _Set_D_SsfdcRdAddr() ------------------------------------------- -//void _Set_D_SsfdcRdAddr(BYTE add) -//{ -// WORD addr; -// SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc; -// ADDRESS_T bb = (ADDRESS_T) &Media; -// -// addr=(WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock; -// addr=addr*(WORD)Ssfdc.MaxSectors+Media.Sector; -// -// //if ((Ssfdc.Attribute &MPS)==PS256) // for 256byte/page -// // addr=addr*2+(WORD)add; -// -// _Hw_D_SetRdAddr(); -// _Hw_D_OutData(0x00); -// _Hw_D_OutData((BYTE)addr); -// _Hw_D_OutData((BYTE)(addr/0x0100)); -// -// if ((Ssfdc.Attribute &MADC)==AD4CYC) -// _Hw_D_OutData((BYTE)(Media.Zone/2)); // Patch -// -// _Hw_D_SetRdData(); -//} -// -////----- _Set_D_SsfdcRdChip() ------------------------------------------- -//void _Set_D_SsfdcRdChip(void) -//{ -// _Hw_D_SetRdAddr(); -// _Hw_D_OutData(0x00); -// _Hw_D_SetRdData(); -//} -// -////----- _Set_D_SsfdcRdStandby() ---------------------------------------- -//void _Set_D_SsfdcRdStandby(void) -//{ -// _Hw_D_SetRdStandby(); -//} -// -////----- _Start_D_SsfdcRdHwECC() ---------------------------------------- -//void _Start_D_SsfdcRdHwECC(void) -//{ -//#ifdef HW_ECC_SUPPORTED -// _Hw_D_EccRdReset(); -// _Hw_D_InData(); -// _Hw_D_EccRdStart(); -//#endif -//} -// -////----- _Stop_D_SsfdcRdHwECC() ----------------------------------------- -//void _Stop_D_SsfdcRdHwECC(void) -//{ -//#ifdef HW_ECC_SUPPORTED -// _Hw_D_EccRdStop(); -//#endif -//} -// -////----- _Load_D_SsfdcRdHwECC() ----------------------------------------- -//void _Load_D_SsfdcRdHwECC(BYTE add) -//{ -//#ifdef HW_ECC_SUPPORTED -// _Hw_D_EccRdRead(); -// //if (!(add==ODD && (Ssfdc.Attribute &MPS)==PS256)) -// { -// EccBuf[0]=_Hw_D_InData(); -// EccBuf[1]=_Hw_D_InData(); -// EccBuf[2]=_Hw_D_InData(); -// } -// -// //if (!(add==EVEN && (Ssfdc.Attribute &MPS)==PS256)) -// { -// EccBuf[3]=_Hw_D_InData(); -// EccBuf[4]=_Hw_D_InData(); -// EccBuf[5]=_Hw_D_InData(); -// } -// -// _Hw_D_EccRdStop(); -//#endif -//} -// -////NAND Memory (SmartMedia) Control Subroutine for Write Data -// -////----- _Set_D_SsfdcWrCmd() ----------------------------------------- -//void _Set_D_SsfdcWrCmd(BYTE cmd) -//{ -// _Hw_D_SetWrCmd(); -// _Hw_D_OutData(cmd); -// _Hw_D_SetWrData(); -//} -// -////----- _Set_D_SsfdcWrAddr() ----------------------------------------- -//void _Set_D_SsfdcWrAddr(BYTE add) -//{ -// WORD addr; -// SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc; -// ADDRESS_T bb = (ADDRESS_T) &Media; -// -// addr=(WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock; -// addr=addr*(WORD)Ssfdc.MaxSectors+Media.Sector; -// -// //if ((Ssfdc.Attribute &MPS)==PS256) // for 256byte/page -// // addr=addr*2+(WORD)add; -// -// _Hw_D_SetWrAddr(); -// _Hw_D_OutData(0x00); -// _Hw_D_OutData((BYTE)addr); -// _Hw_D_OutData((BYTE)(addr/0x0100)); -// -// if ((Ssfdc.Attribute &MADC)==AD4CYC) -// _Hw_D_OutData((BYTE)(Media.Zone/2)); // Patch -// -// _Hw_D_SetWrData(); -//} -// -////----- _Set_D_SsfdcWrBlock() ----------------------------------------- -//void _Set_D_SsfdcWrBlock(void) -//{ -// WORD addr; -// SSFDCTYPE_T aa = (SSFDCTYPE_T ) &Ssfdc; -// ADDRESS_T bb = (ADDRESS_T) &Media; -// -// addr=(WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock; -// addr=addr*(WORD)Ssfdc.MaxSectors; -// -// //if ((Ssfdc.Attribute &MPS)==PS256) // for 256byte/page -// // addr=addr*2; -// -// _Hw_D_SetWrAddr(); -// _Hw_D_OutData((BYTE)addr); -// _Hw_D_OutData((BYTE)(addr/0x0100)); -// -// if ((Ssfdc.Attribute &MADC)==AD4CYC) -// _Hw_D_OutData((BYTE)(Media.Zone/2)); // Patch -// -// _Hw_D_SetWrData(); -//} -// -////----- _Set_D_SsfdcWrStandby() ----------------------------------------- -//void _Set_D_SsfdcWrStandby(void) -//{ -// _Hw_D_SetWrStandby(); -//} -// -////----- _Start_D_SsfdcWrHwECC() ----------------------------------------- -//void _Start_D_SsfdcWrHwECC(void) -//{ -//#ifdef HW_ECC_SUPPORTED -// _Hw_D_EccWrReset(); -// _Hw_D_InData(); -// _Hw_D_EccWrStart(); -//#endif -//} -// -////----- _Load_D_SsfdcWrHwECC() ----------------------------------------- -//void _Load_D_SsfdcWrHwECC(BYTE add) -//{ -//#ifdef HW_ECC_SUPPORTED -// _Hw_D_EccWrRead(); -// //if (!(add==ODD && (Ssfdc.Attribute &MPS)==PS256)) -// { -// EccBuf[0]=_Hw_D_InData(); -// EccBuf[1]=_Hw_D_InData(); -// EccBuf[2]=_Hw_D_InData(); -// } -// -// //if (!(add==EVEN && (Ssfdc.Attribute &MPS)==PS256)) -// { -// EccBuf[3]=_Hw_D_InData(); -// EccBuf[4]=_Hw_D_InData(); -// EccBuf[5]=_Hw_D_InData(); -// } -// -// _Hw_D_EccWrStop(); -//#endif -//} -// -////NAND Memory (SmartMedia) Control Subroutine -////----- _Check_D_SsfdcBusy() ------------------------------------------- -//int _Check_D_SsfdcBusy(WORD time) -//{ -// WORD count = 0; -// -// do { -// if (!_Hw_D_ChkBusy()) -// return(SMSUCCESS); -// EDelay(100); -// count++; -// } while (count<=time); -// -// return(ERROR); -//} -// -////----- _Check_D_SsfdcStatus() ----------------------------------------- -//int _Check_D_SsfdcStatus(void) -//{ -// if (_Hw_D_InData() & WR_FAIL) -// return(ERROR); -// -// return(SMSUCCESS); -//} -// -//// For 712 -////----- _Reset_D_SsfdcErr() ----------------------------------------- -//void _Reset_D_SsfdcErr(void) -//{ -// WORD count = 0; -// -// _Hw_D_SetRdCmd(); -// _Hw_D_OutData(RST_CHIP); -// _Hw_D_SetRdData(); -// -// do { -// if (!_Hw_D_ChkBusy()) -// break; -// EDelay(100); -// count++; -// } while (count<=BUSY_RESET); -// -// _Hw_D_SetRdStandby(); -//} -// -////NAND Memory (SmartMedia) Buffer Data Xfer Subroutine -////----- SM_ReadDataWithDMA() ----------------------------------------- -//void SM_ReadDataWithDMA(PFDO_DEVICE_EXTENSION fdoExt, BYTE *databuf, WORD SectByteCount) -//{ -// PHYSICAL_ADDRESS Addr; -// LARGE_INTEGER ptimeout ; -// -// KeClearEvent(&fdoExt->SM_DMADoneEvent); -// -// Addr = MmGetPhysicalAddress(databuf); -// -// WRITE_PORT_DWORD(SM_DMA_ADDR_REG, (DWORD)Addr.LowPart); -// WRITE_PORT_BYTE(SM_DMA_DATA_CTRL, 0); -// WRITE_PORT_WORD(SM_DMA_BYTE_COUNT_REG, SectByteCount); -// -// while ( _Hw_D_ChkCardIn() ) -// { -// if ((READ_PORT_BYTE(SM_REG_FIFO_STATUS) & 0x80)) -// break; -// } -// if (!_Hw_D_ChkCardIn()) return; -// WRITE_PORT_BYTE(SM_DMA_DATA_CTRL, 0x01); -// -// ptimeout.QuadPart = 2000 * (-10000); // 2 sec -// KeWaitForSingleObject(&fdoExt->SM_DMADoneEvent, Executive, KernelMode, FALSE, &ptimeout); -// _Hw_D_SetDMAIntMask(); -//} -// -////----- SM_WriteDataWithDMA() ----------------------------------------- -//void SM_WriteDataWithDMA(PFDO_DEVICE_EXTENSION fdoExt, BYTE *databuf, WORD SectByteCount) -//{ -// PHYSICAL_ADDRESS Addr; -// LARGE_INTEGER ptimeout ; -// -// KeClearEvent(&fdoExt->SM_DMADoneEvent); -// -// Addr = MmGetPhysicalAddress(databuf); -// -// WRITE_PORT_DWORD(SM_DMA_ADDR_REG, (DWORD)Addr.LowPart); -// WRITE_PORT_BYTE(SM_DMA_DATA_CTRL, 2); -// WRITE_PORT_WORD(SM_DMA_BYTE_COUNT_REG, SectByteCount); -// -// while ( _Hw_D_ChkCardIn() ) -// { -// if ((READ_PORT_BYTE(SM_REG_FIFO_STATUS) & 0x40)) -// break; -// } -// if (!_Hw_D_ChkCardIn()) return; -// WRITE_PORT_BYTE(SM_DMA_DATA_CTRL, 0x03); -// -// ptimeout.QuadPart = 2000 * (-10000); // 2 sec -// KeWaitForSingleObject(&fdoExt->SM_DMADoneEvent, Executive, KernelMode, FALSE, &ptimeout); -// _Hw_D_SetDMAIntMask(); -//} -// -////----- _Read_D_SsfdcBuf() ----------------------------------------- -//void _Read_D_SsfdcBuf(BYTE *databuf) -//{ -// int i; -// -// //for(i=0x0000;i<(((Ssfdc.Attribute &MPS)==PS256)?0x0100:0x0200);i++) -// for(i=0; i<0x200; i++) -// *databuf++ =_Hw_D_InData(); -//} -// -////----- _Write_D_SsfdcBuf() ----------------------------------------- -//void _Write_D_SsfdcBuf(BYTE *databuf) -//{ -// int i; -// -// //for(i=0x0000;i<(((Ssfdc.Attribute &MPS)==PS256)?0x0100:0x0200);i++) -// for(i=0; i<0x200; i++) -// _Hw_D_OutData(*databuf++); -//} -// -////----- _Read_D_SsfdcByte() ----------------------------------------- -//void _Read_D_SsfdcByte(BYTE *databuf) -//{ -// *databuf=(BYTE)_Hw_D_InData(); -//} -// -////----- _ReadRedt_D_SsfdcBuf() ----------------------------------------- -//void _ReadRedt_D_SsfdcBuf(BYTE *redundant) -//{ -// char i; -// -// //for(i=0x00;i<(((Ssfdc.Attribute &MPS)==PS256)?0x08:0x10);i++) -// for(i=0; i<0x10; i++) -// redundant[i] =_Hw_D_InData(); -//} -// -////----- _WriteRedt_D_SsfdcBuf() ----------------------------------------- -//void _WriteRedt_D_SsfdcBuf(BYTE *redundant) -//{ -// char i; -// -// //for(i=0x00;i<(((Ssfdc.Attribute &MPS)==PS256)?0x08:0x10);i++) -// for(i=0; i<0x10; i++) -// _Hw_D_OutData(*redundant++); -//} -*/ -//SmartMedia ID Code Check & Mode Set Subroutine -//----- Set_D_SsfdcModel() --------------------------------------------- + + + +/* SmartMedia ID Code Check & Mode Set Subroutine + * ----- Set_D_SsfdcModel() --------------------------------------------- + */ int Set_D_SsfdcModel(BYTE dcode) { - switch (_Check_D_DevCode(dcode)) { - case SSFDC1MB: - Ssfdc.Model = SSFDC1MB; - Ssfdc.Attribute = FLASH | AD3CYC | BS16 | PS256; - Ssfdc.MaxZones = 1; - Ssfdc.MaxBlocks = 256; - Ssfdc.MaxLogBlocks = 250; - Ssfdc.MaxSectors = 8; - break; - case SSFDC2MB: - Ssfdc.Model = SSFDC2MB; - Ssfdc.Attribute = FLASH | AD3CYC | BS16 | PS256; - Ssfdc.MaxZones = 1; - Ssfdc.MaxBlocks = 512; - Ssfdc.MaxLogBlocks = 500; - Ssfdc.MaxSectors = 8; - break; - case SSFDC4MB: - Ssfdc.Model = SSFDC4MB; - Ssfdc.Attribute = FLASH | AD3CYC | BS16 | PS512; - Ssfdc.MaxZones = 1; - Ssfdc.MaxBlocks = 512; - Ssfdc.MaxLogBlocks = 500; - Ssfdc.MaxSectors = 16; - break; - case SSFDC8MB: - Ssfdc.Model = SSFDC8MB; - Ssfdc.Attribute = FLASH | AD3CYC | BS16 | PS512; - Ssfdc.MaxZones = 1; - Ssfdc.MaxBlocks = 1024; - Ssfdc.MaxLogBlocks = 1000; - Ssfdc.MaxSectors = 16; - break; - case SSFDC16MB: - Ssfdc.Model = SSFDC16MB; - Ssfdc.Attribute = FLASH | AD3CYC | BS32 | PS512; - Ssfdc.MaxZones = 1; - Ssfdc.MaxBlocks = 1024; - Ssfdc.MaxLogBlocks = 1000; - Ssfdc.MaxSectors = 32; - break; - case SSFDC32MB: - Ssfdc.Model = SSFDC32MB; - Ssfdc.Attribute = FLASH | AD3CYC | BS32 | PS512; - Ssfdc.MaxZones = 2; - Ssfdc.MaxBlocks = 1024; - Ssfdc.MaxLogBlocks = 1000; - Ssfdc.MaxSectors = 32; - break; - case SSFDC64MB: - Ssfdc.Model = SSFDC64MB; - Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512; - Ssfdc.MaxZones = 4; - Ssfdc.MaxBlocks = 1024; - Ssfdc.MaxLogBlocks = 1000; - Ssfdc.MaxSectors = 32; - break; - case SSFDC128MB: - Ssfdc.Model = SSFDC128MB; - Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512; - Ssfdc.MaxZones = 8; - Ssfdc.MaxBlocks = 1024; - Ssfdc.MaxLogBlocks = 1000; - Ssfdc.MaxSectors = 32; - break; - case SSFDC256MB: - Ssfdc.Model = SSFDC256MB; - Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512; - Ssfdc.MaxZones = 16; - Ssfdc.MaxBlocks = 1024; - Ssfdc.MaxLogBlocks = 1000; - Ssfdc.MaxSectors = 32; - break; - case SSFDC512MB: - Ssfdc.Model = SSFDC512MB; - Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512; - Ssfdc.MaxZones = 32; - Ssfdc.MaxBlocks = 1024; - Ssfdc.MaxLogBlocks = 1000; - Ssfdc.MaxSectors = 32; - break; - case SSFDC1GB: - Ssfdc.Model = SSFDC1GB; - Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512; - Ssfdc.MaxZones = 64; - Ssfdc.MaxBlocks = 1024; - Ssfdc.MaxLogBlocks = 1000; - Ssfdc.MaxSectors = 32; - break; - case SSFDC2GB: - Ssfdc.Model = SSFDC2GB; - Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512; - Ssfdc.MaxZones = 128; - Ssfdc.MaxBlocks = 1024; - Ssfdc.MaxLogBlocks = 1000; - Ssfdc.MaxSectors = 32; - break; - default: - Ssfdc.Model = NOSSFDC; - return(ERROR); - } - - return(SMSUCCESS); + switch (_Check_D_DevCode(dcode)) { + case SSFDC1MB: + Ssfdc.Model = SSFDC1MB; + Ssfdc.Attribute = FLASH | AD3CYC | BS16 | PS256; + Ssfdc.MaxZones = 1; + Ssfdc.MaxBlocks = 256; + Ssfdc.MaxLogBlocks = 250; + Ssfdc.MaxSectors = 8; + break; + case SSFDC2MB: + Ssfdc.Model = SSFDC2MB; + Ssfdc.Attribute = FLASH | AD3CYC | BS16 | PS256; + Ssfdc.MaxZones = 1; + Ssfdc.MaxBlocks = 512; + Ssfdc.MaxLogBlocks = 500; + Ssfdc.MaxSectors = 8; + break; + case SSFDC4MB: + Ssfdc.Model = SSFDC4MB; + Ssfdc.Attribute = FLASH | AD3CYC | BS16 | PS512; + Ssfdc.MaxZones = 1; + Ssfdc.MaxBlocks = 512; + Ssfdc.MaxLogBlocks = 500; + Ssfdc.MaxSectors = 16; + break; + case SSFDC8MB: + Ssfdc.Model = SSFDC8MB; + Ssfdc.Attribute = FLASH | AD3CYC | BS16 | PS512; + Ssfdc.MaxZones = 1; + Ssfdc.MaxBlocks = 1024; + Ssfdc.MaxLogBlocks = 1000; + Ssfdc.MaxSectors = 16; + break; + case SSFDC16MB: + Ssfdc.Model = SSFDC16MB; + Ssfdc.Attribute = FLASH | AD3CYC | BS32 | PS512; + Ssfdc.MaxZones = 1; + Ssfdc.MaxBlocks = 1024; + Ssfdc.MaxLogBlocks = 1000; + Ssfdc.MaxSectors = 32; + break; + case SSFDC32MB: + Ssfdc.Model = SSFDC32MB; + Ssfdc.Attribute = FLASH | AD3CYC | BS32 | PS512; + Ssfdc.MaxZones = 2; + Ssfdc.MaxBlocks = 1024; + Ssfdc.MaxLogBlocks = 1000; + Ssfdc.MaxSectors = 32; + break; + case SSFDC64MB: + Ssfdc.Model = SSFDC64MB; + Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512; + Ssfdc.MaxZones = 4; + Ssfdc.MaxBlocks = 1024; + Ssfdc.MaxLogBlocks = 1000; + Ssfdc.MaxSectors = 32; + break; + case SSFDC128MB: + Ssfdc.Model = SSFDC128MB; + Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512; + Ssfdc.MaxZones = 8; + Ssfdc.MaxBlocks = 1024; + Ssfdc.MaxLogBlocks = 1000; + Ssfdc.MaxSectors = 32; + break; + case SSFDC256MB: + Ssfdc.Model = SSFDC256MB; + Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512; + Ssfdc.MaxZones = 16; + Ssfdc.MaxBlocks = 1024; + Ssfdc.MaxLogBlocks = 1000; + Ssfdc.MaxSectors = 32; + break; + case SSFDC512MB: + Ssfdc.Model = SSFDC512MB; + Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512; + Ssfdc.MaxZones = 32; + Ssfdc.MaxBlocks = 1024; + Ssfdc.MaxLogBlocks = 1000; + Ssfdc.MaxSectors = 32; + break; + case SSFDC1GB: + Ssfdc.Model = SSFDC1GB; + Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512; + Ssfdc.MaxZones = 64; + Ssfdc.MaxBlocks = 1024; + Ssfdc.MaxLogBlocks = 1000; + Ssfdc.MaxSectors = 32; + break; + case SSFDC2GB: + Ssfdc.Model = SSFDC2GB; + Ssfdc.Attribute = FLASH | AD4CYC | BS32 | PS512; + Ssfdc.MaxZones = 128; + Ssfdc.MaxBlocks = 1024; + Ssfdc.MaxLogBlocks = 1000; + Ssfdc.MaxSectors = 32; + break; + default: + Ssfdc.Model = NOSSFDC; + return ERROR; + } + + return SMSUCCESS; } -//----- _Check_D_DevCode() --------------------------------------------- +/* ----- _Check_D_DevCode() --------------------------------------------- */ BYTE _Check_D_DevCode(BYTE dcode) { - switch(dcode){ - case 0x6E: - case 0xE8: - case 0xEC: return(SSFDC1MB); // 8Mbit (1M) NAND - case 0x64: - case 0xEA: return(SSFDC2MB); // 16Mbit (2M) NAND - case 0x6B: - case 0xE3: - case 0xE5: return(SSFDC4MB); // 32Mbit (4M) NAND - case 0xE6: return(SSFDC8MB); // 64Mbit (8M) NAND - case 0x73: return(SSFDC16MB); // 128Mbit (16M)NAND - case 0x75: return(SSFDC32MB); // 256Mbit (32M)NAND - case 0x76: return(SSFDC64MB); // 512Mbit (64M)NAND - case 0x79: return(SSFDC128MB); // 1Gbit(128M)NAND - case 0x71: return(SSFDC256MB); - case 0xDC: return(SSFDC512MB); - case 0xD3: return(SSFDC1GB); - case 0xD5: return(SSFDC2GB); - default: return(NOSSFDC); - } + switch (dcode) { + case 0x6E: + case 0xE8: + case 0xEC: return SSFDC1MB; /* 8Mbit (1M) NAND */ + case 0x64: + case 0xEA: return SSFDC2MB; /* 16Mbit (2M) NAND */ + case 0x6B: + case 0xE3: + case 0xE5: return SSFDC4MB; /* 32Mbit (4M) NAND */ + case 0xE6: return SSFDC8MB; /* 64Mbit (8M) NAND */ + case 0x73: return SSFDC16MB; /* 128Mbit (16M)NAND */ + case 0x75: return SSFDC32MB; /* 256Mbit (32M)NAND */ + case 0x76: return SSFDC64MB; /* 512Mbit (64M)NAND */ + case 0x79: return SSFDC128MB; /* 1Gbit(128M)NAND */ + case 0x71: return SSFDC256MB; + case 0xDC: return SSFDC512MB; + case 0xD3: return SSFDC1GB; + case 0xD5: return SSFDC2GB; + default: return NOSSFDC; + } } -/* -////SmartMedia Power Control Subroutine -////----- Cnt_D_Reset() ---------------------------------------------- -//void Cnt_D_Reset(void) -//{ -// _Hw_D_LedOff(); -// _Hw_D_SetRdStandby(); -// _Hw_D_VccOff(); -//} -// -////----- Cnt_D_PowerOn() ---------------------------------------------- -//int Cnt_D_PowerOn(void) -//{ -// // No support 5V. -// _Hw_D_EnableVcc3VOn(); // Set SM_REG_CTRL_5 Reg. to 3V -// _Hw_D_VccOn(); -// _Hw_D_SetRdStandby(); -// _Wait_D_Timer(TIME_PON); -// -// if (_Hw_D_ChkPower()) -// { -// _Hw_D_EnableOB(); // Set SM_REG_CTRL_5 Reg. to 0x83 -// return(SMSUCCESS); -// } -// -// _Hw_D_SetVccOff(); -// return(ERROR); -//} -// -////----- Cnt_D_PowerOff() ---------------------------------------------- -//void Cnt_D_PowerOff(void) -//{ -// _Hw_D_SetRdStandby(); -// _Hw_D_SetVccOff(); -// _Hw_D_VccOff(); -//} -// -////----- Cnt_D_LedOn() ---------------------------------------------- -//void Cnt_D_LedOn(void) -//{ -// _Hw_D_LedOn(); -//} -// -////----- Cnt_D_LedOff() ---------------------------------------------- -//void Cnt_D_LedOff(void) -//{ -// _Hw_D_LedOff(); -//} -// -////----- Check_D_CntPower() ---------------------------------------------- -//int Check_D_CntPower(void) -//{ -// if (_Hw_D_ChkPower()) -// return(SMSUCCESS); // Power On -// -// return(ERROR); // Power Off -//} -// -////----- Check_D_CardExist() ---------------------------------------------- -//int Check_D_CardExist(void) -//{ -// char i,j,k; -// -// if (!_Hw_D_ChkStatus()) // Not Status Change -// if (_Hw_D_ChkCardIn()) -// return(SMSUCCESS); // Card exist in Slot -// -// for(i=0,j=0,k=0; i<16; i++) { -// if (_Hw_D_ChkCardIn()) // Status Change -// { -// j++; k=0; -// } -// else -// { -// j=0; k++; -// } -// -// if (j>3) -// return(SMSUCCESS); // Card exist in Slot -// if (k>3) -// return(ERROR); // NO Card exist in Slot -// -// _Wait_D_Timer(TIME_CDCHK); -// } -// -// return(ERROR); -//} -// -////----- Check_D_CardStsChg() ---------------------------------------------- -//int Check_D_CardStsChg(void) -//{ -// if (_Hw_D_ChkStatus()) -// return(ERROR); // Status Change -// -// return(SMSUCCESS); // Not Status Change -//} -// -////----- Check_D_SsfdcWP() ---------------------------------------------- -//int Check_D_SsfdcWP(void) -//{ // ERROR: WP, SMSUCCESS: Not WP -// char i; -// -// for(i=0; i<8; i++) { -// if (_Hw_D_ChkWP()) -// return(ERROR); -// _Wait_D_Timer(TIME_WPCHK); -// } -// -// return(SMSUCCESS); -//} -// -*/ -//SmartMedia ECC Control Subroutine -//----- Check_D_ReadError() ---------------------------------------------- + + + + +/* SmartMedia ECC Control Subroutine + * ----- Check_D_ReadError() ---------------------------------------------- + */ int Check_D_ReadError(BYTE *redundant) { return SMSUCCESS; } -//----- Check_D_Correct() ---------------------------------------------- -int Check_D_Correct(BYTE *buf,BYTE *redundant) +/* ----- Check_D_Correct() ---------------------------------------------- */ +int Check_D_Correct(BYTE *buf, BYTE *redundant) { return SMSUCCESS; } -//----- Check_D_CISdata() ---------------------------------------------- +/* ----- Check_D_CISdata() ---------------------------------------------- */ int Check_D_CISdata(BYTE *buf, BYTE *redundant) { BYTE cis[] = {0x01, 0x03, 0xD9, 0x01, 0xFF, 0x18, 0x02, @@ -1516,86 +683,11 @@ int Check_D_CISdata(BYTE *buf, BYTE *redundant) return ERROR; } -//----- Set_D_RightECC() ---------------------------------------------- +/* ----- Set_D_RightECC() ---------------------------------------------- */ void Set_D_RightECC(BYTE *redundant) { - // Driver ¤£°µ ECC Check + /* Driver ECC Check */ return; - //StringCopy((char *)(redundant+0x0D),(char *)EccBuf,3); - //StringCopy((char *)(redundant+0x08),(char *)(EccBuf+0x03),3); } -/* -////----- _Calc_D_ECCdata() ---------------------------------------------- -//void _Calc_D_ECCdata(BYTE *buf) -//{ -//#ifdef HW_ECC_SUPPORTED -//#else -// _Calculate_D_SwECC(buf,EccBuf); -// buf+=0x0100; -// _Calculate_D_SwECC(buf,EccBuf+0x03); -//#endif -//} -// -////----- _Set_D_ECCdata() ---------------------------------------------- -//void _Set_D_ECCdata(BYTE add,BYTE *redundant) -//{ -// //if (add==EVEN && (Ssfdc.Attribute &MPS)==PS256) -// // return; -// -// // for 256byte/page -// StringCopy((char *)(redundant+0x0D),(char *)EccBuf,3); -// StringCopy((char *)(redundant+0x08),(char *)(EccBuf+0x03),3); -//} -*/ - -/* -//----- SM_ReadBlock() --------------------------------------------- -int SM_ReadBlock(PFDO_DEVICE_EXTENSION fdoExt, BYTE *buf,BYTE *redundant) -{ - PBULK_CBW pBulkCbw = fdoExt->pBulkCbw; - NTSTATUS ntStatus; - WORD addr; - - ENE_LoadBinCode(fdoExt, SM_RW_PATTERN); - - addr = (WORD)Media.Zone*Ssfdc.MaxBlocks+Media.PhyBlock; - addr = addr*(WORD)Ssfdc.MaxSectors+Media.Sector; - - // Read sect data - RtlZeroMemory(pBulkCbw, sizeof(struct _BULK_CBW)); - pBulkCbw->dCBWSignature = CBW_SIGNTURE; - pBulkCbw->bCBWLun = CBW_LUN; - pBulkCbw->dCBWDataTransferLength = 0x200; - pBulkCbw->bmCBWFlags = 0x80; - pBulkCbw->CBWCb[0] = 0xF1; - pBulkCbw->CBWCb[1] = 0x02; - pBulkCbw->CBWCb[4] = (BYTE)addr; - pBulkCbw->CBWCb[3] = (BYTE)(addr/0x0100); - pBulkCbw->CBWCb[2] = Media.Zone/2; - - ntStatus = ENE_SendScsiCmd(fdoExt, FDIR_READ, buf); - - if (!NT_SUCCESS(ntStatus)) - return(ERROR); - - // Read redundant - RtlZeroMemory(pBulkCbw, sizeof(struct _BULK_CBW)); - pBulkCbw->dCBWSignature = CBW_SIGNTURE; - pBulkCbw->bCBWLun = CBW_LUN; - pBulkCbw->dCBWDataTransferLength = 0x10; - pBulkCbw->bmCBWFlags = 0x80; - pBulkCbw->CBWCb[0] = 0xF1; - pBulkCbw->CBWCb[1] = 0x03; - pBulkCbw->CBWCb[4] = (BYTE)addr; - pBulkCbw->CBWCb[3] = (BYTE)(addr/0x0100); - pBulkCbw->CBWCb[2] = Media.Zone/2; - pBulkCbw->CBWCb[5] = 0; - pBulkCbw->CBWCb[6] = 1; - - ntStatus = ENE_SendScsiCmd(fdoExt, FDIR_READ, redundant); - - if (!NT_SUCCESS(ntStatus)) - return(ERROR); - - return(SMSUCCESS); -}*/ + + diff --git a/drivers/staging/keucr/smscsi.c b/drivers/staging/keucr/smscsi.c index a6fa77f..58b5555 100644 --- a/drivers/staging/keucr/smscsi.c +++ b/drivers/staging/keucr/smscsi.c @@ -9,36 +9,46 @@ #include "usb.h" #include "scsiglue.h" #include "transport.h" -//#include "smcommon.h" #include "smil.h" -int SM_SCSI_Test_Unit_Ready (struct us_data *us, struct scsi_cmnd *srb); -int SM_SCSI_Inquiry (struct us_data *us, struct scsi_cmnd *srb); -int SM_SCSI_Mode_Sense (struct us_data *us, struct scsi_cmnd *srb); -int SM_SCSI_Start_Stop (struct us_data *us, struct scsi_cmnd *srb); -int SM_SCSI_Read_Capacity (struct us_data *us, struct scsi_cmnd *srb); -int SM_SCSI_Read (struct us_data *us, struct scsi_cmnd *srb); -int SM_SCSI_Write (struct us_data *us, struct scsi_cmnd *srb); +int SM_SCSI_Test_Unit_Ready(struct us_data *us, struct scsi_cmnd *srb); +int SM_SCSI_Inquiry(struct us_data *us, struct scsi_cmnd *srb); +int SM_SCSI_Mode_Sense(struct us_data *us, struct scsi_cmnd *srb); +int SM_SCSI_Start_Stop(struct us_data *us, struct scsi_cmnd *srb); +int SM_SCSI_Read_Capacity(struct us_data *us, struct scsi_cmnd *srb); +int SM_SCSI_Read(struct us_data *us, struct scsi_cmnd *srb); +int SM_SCSI_Write(struct us_data *us, struct scsi_cmnd *srb); extern PBYTE SMHostAddr; extern DWORD ErrXDCode; -//----- SM_SCSIIrp() -------------------------------------------------- +/* ----- SM_SCSIIrp() -------------------------------------------------- */ int SM_SCSIIrp(struct us_data *us, struct scsi_cmnd *srb) { int result; us->SrbStatus = SS_SUCCESS; - switch (srb->cmnd[0]) - { - case TEST_UNIT_READY : result = SM_SCSI_Test_Unit_Ready (us, srb); break; //0x00 - case INQUIRY : result = SM_SCSI_Inquiry (us, srb); break; //0x12 - case MODE_SENSE : result = SM_SCSI_Mode_Sense (us, srb); break; //0x1A - case READ_CAPACITY : result = SM_SCSI_Read_Capacity (us, srb); break; //0x25 - case READ_10 : result = SM_SCSI_Read (us, srb); break; //0x28 - case WRITE_10 : result = SM_SCSI_Write (us, srb); break; //0x2A - - default: + switch (srb->cmnd[0]) { + case TEST_UNIT_READY: + result = SM_SCSI_Test_Unit_Ready(us, srb); + break; /* 0x00 */ + case INQUIRY: + result = SM_SCSI_Inquiry(us, srb); + break; /* 0x12 */ + case MODE_SENSE: + result = SM_SCSI_Mode_Sense(us, srb); + break; /* 0x1A */ + case READ_CAPACITY: + result = SM_SCSI_Read_Capacity(us, srb); + break; /* 0x25 */ + case READ_10: + result = SM_SCSI_Read(us, srb); + break; /* 0x28 */ + case WRITE_10: + result = SM_SCSI_Write(us, srb); + break; /* 0x2A */ + + default: us->SrbStatus = SS_ILLEGAL_REQUEST; result = USB_STOR_TRANSPORT_FAILED; break; @@ -46,25 +56,22 @@ int SM_SCSIIrp(struct us_data *us, struct scsi_cmnd *srb) return result; } -//----- SM_SCSI_Test_Unit_Ready() -------------------------------------------------- +/* ----- SM_SCSI_Test_Unit_Ready() -------------------------------------------------- */ int SM_SCSI_Test_Unit_Ready(struct us_data *us, struct scsi_cmnd *srb) { - //printk("SM_SCSI_Test_Unit_Ready\n"); if (us->SM_Status.Insert && us->SM_Status.Ready) return USB_STOR_TRANSPORT_GOOD; - else - { + else { ENE_SMInit(us); return USB_STOR_TRANSPORT_GOOD; } - + return USB_STOR_TRANSPORT_GOOD; } -//----- SM_SCSI_Inquiry() -------------------------------------------------- +/* ----- SM_SCSI_Inquiry() -------------------------------------------------- */ int SM_SCSI_Inquiry(struct us_data *us, struct scsi_cmnd *srb) { - //printk("SM_SCSI_Inquiry\n"); BYTE data_ptr[36] = {0x00, 0x80, 0x02, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x55, 0x53, 0x42, 0x32, 0x2E, 0x30, 0x20, 0x20, 0x43, 0x61, 0x72, 0x64, 0x52, 0x65, 0x61, 0x64, 0x65, 0x72, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x31, 0x30, 0x30}; usb_stor_set_xfer_buf(us, data_ptr, 36, srb, TO_XFER_BUF); @@ -72,11 +79,11 @@ int SM_SCSI_Inquiry(struct us_data *us, struct scsi_cmnd *srb) } -//----- SM_SCSI_Mode_Sense() -------------------------------------------------- +/* ----- SM_SCSI_Mode_Sense() -------------------------------------------------- */ int SM_SCSI_Mode_Sense(struct us_data *us, struct scsi_cmnd *srb) { - BYTE mediaNoWP[12] = {0x0b,0x00,0x00,0x08,0x00,0x00,0x71,0xc0,0x00,0x00,0x02,0x00}; - BYTE mediaWP[12] = {0x0b,0x00,0x80,0x08,0x00,0x00,0x71,0xc0,0x00,0x00,0x02,0x00}; + BYTE mediaNoWP[12] = {0x0b, 0x00, 0x00, 0x08, 0x00, 0x00, 0x71, 0xc0, 0x00, 0x00, 0x02, 0x00}; + BYTE mediaWP[12] = {0x0b, 0x00, 0x80, 0x08, 0x00, 0x00, 0x71, 0xc0, 0x00, 0x00, 0x02, 0x00}; if (us->SM_Status.WtP) usb_stor_set_xfer_buf(us, mediaWP, 12, srb, TO_XFER_BUF); @@ -87,7 +94,7 @@ int SM_SCSI_Mode_Sense(struct us_data *us, struct scsi_cmnd *srb) return USB_STOR_TRANSPORT_GOOD; } -//----- SM_SCSI_Read_Capacity() -------------------------------------------------- +/* ----- SM_SCSI_Read_Capacity() -------------------------------------------------- */ int SM_SCSI_Read_Capacity(struct us_data *us, struct scsi_cmnd *srb) { unsigned int offset = 0; @@ -100,45 +107,37 @@ int SM_SCSI_Read_Capacity(struct us_data *us, struct scsi_cmnd *srb) bl_len = 0x200; bl_num = Ssfdc.MaxLogBlocks * Ssfdc.MaxSectors * Ssfdc.MaxZones - 1; - //printk("MaxLogBlocks = %x\n", Ssfdc.MaxLogBlocks); - //printk("MaxSectors = %x\n", Ssfdc.MaxSectors); - //printk("MaxZones = %x\n", Ssfdc.MaxZones); - //printk("bl_num = %x\n", bl_num); us->bl_num = bl_num; printk("bl_len = %x\n", bl_len); printk("bl_num = %x\n", bl_num); - //srb->request_bufflen = 8; - buf[0] = (bl_num>>24) & 0xff; - buf[1] = (bl_num>>16) & 0xff; - buf[2] = (bl_num>> 8) & 0xff; - buf[3] = (bl_num>> 0) & 0xff; - buf[4] = (bl_len>>24) & 0xff; - buf[5] = (bl_len>>16) & 0xff; - buf[6] = (bl_len>> 8) & 0xff; - buf[7] = (bl_len>> 0) & 0xff; - + buf[0] = (bl_num >> 24) & 0xff; + buf[1] = (bl_num >> 16) & 0xff; + buf[2] = (bl_num >> 8) & 0xff; + buf[3] = (bl_num >> 0) & 0xff; + buf[4] = (bl_len >> 24) & 0xff; + buf[5] = (bl_len >> 16) & 0xff; + buf[6] = (bl_len >> 8) & 0xff; + buf[7] = (bl_len >> 0) & 0xff; + usb_stor_access_xfer_buf(us, buf, 8, srb, &sg, &offset, TO_XFER_BUF); - //usb_stor_set_xfer_buf(us, buf, srb->request_bufflen, srb, TO_XFER_BUF); return USB_STOR_TRANSPORT_GOOD; } -//----- SM_SCSI_Read() -------------------------------------------------- +/* ----- SM_SCSI_Read() -------------------------------------------------- */ int SM_SCSI_Read(struct us_data *us, struct scsi_cmnd *srb) { - //struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; - int result=0; + int result = 0; PBYTE Cdb = srb->cmnd; - DWORD bn = ((Cdb[2]<<24) & 0xff000000) | ((Cdb[3]<<16) & 0x00ff0000) | - ((Cdb[4]<< 8) & 0x0000ff00) | ((Cdb[5]<< 0) & 0x000000ff); - WORD blen = ((Cdb[7]<< 8) & 0xff00) | ((Cdb[8]<< 0) & 0x00ff); + DWORD bn = ((Cdb[2] << 24) & 0xff000000) | ((Cdb[3] << 16) & 0x00ff0000) | + ((Cdb[4] << 8) & 0x0000ff00) | ((Cdb[5] << 0) & 0x000000ff); + WORD blen = ((Cdb[7] << 8) & 0xff00) | ((Cdb[8] << 0) & 0x00ff); DWORD blenByte = blen * 0x200; void *buf; - //printk("SCSIOP_READ --- bn = %X, blen = %X, srb->use_sg = %X\n", bn, blen, srb->use_sg); - + if (bn > us->bl_num) return USB_STOR_TRANSPORT_ERROR; @@ -157,19 +156,17 @@ int SM_SCSI_Read(struct us_data *us, struct scsi_cmnd *srb) return USB_STOR_TRANSPORT_GOOD; } -//----- SM_SCSI_Write() -------------------------------------------------- +/* ----- SM_SCSI_Write() -------------------------------------------------- */ int SM_SCSI_Write(struct us_data *us, struct scsi_cmnd *srb) { - //struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; - int result=0; + int result = 0; PBYTE Cdb = srb->cmnd; - DWORD bn = ((Cdb[2]<<24) & 0xff000000) | ((Cdb[3]<<16) & 0x00ff0000) | - ((Cdb[4]<< 8) & 0x0000ff00) | ((Cdb[5]<< 0) & 0x000000ff); - WORD blen = ((Cdb[7]<< 8) & 0xff00) | ((Cdb[8]<< 0) & 0x00ff); + DWORD bn = ((Cdb[2] << 24) & 0xff000000) | ((Cdb[3] << 16) & 0x00ff0000) | + ((Cdb[4] << 8) & 0x0000ff00) | ((Cdb[5] << 0) & 0x000000ff); + WORD blen = ((Cdb[7] << 8) & 0xff00) | ((Cdb[8] << 0) & 0x00ff); DWORD blenByte = blen * 0x200; void *buf; - //printk("SCSIOP_Write --- bn = %X, blen = %X, srb->use_sg = %X\n", bn, blen, srb->use_sg); if (bn > us->bl_num) return USB_STOR_TRANSPORT_ERROR; diff --git a/drivers/staging/mei/interrupt.c b/drivers/staging/mei/interrupt.c index 9cb186b..ca1e0c9 100644 --- a/drivers/staging/mei/interrupt.c +++ b/drivers/staging/mei/interrupt.c @@ -1540,6 +1540,12 @@ irqreturn_t mei_interrupt_thread_handler(int irq, void *dev_id) mutex_lock(&dev->device_lock); mei_io_list_init(&complete_list); dev->host_hw_state = mei_hcsr_read(dev); + + /* Ack the interrupt here + * In case of MSI we don't go throuhg the quick handler */ + if (pci_dev_msi_enabled(dev->pdev)) + mei_reg_write(dev, H_CSR, dev->host_hw_state); + dev->me_hw_state = mei_mecsr_read(dev); /* check if ME wants a reset */ diff --git a/drivers/staging/mei/main.c b/drivers/staging/mei/main.c index de8825f..8d76785 100644 --- a/drivers/staging/mei/main.c +++ b/drivers/staging/mei/main.c @@ -151,11 +151,20 @@ static int __devinit mei_probe(struct pci_dev *pdev, err = -ENOMEM; goto free_device; } - /* request and enable interrupt */ - err = request_threaded_irq(pdev->irq, + pci_enable_msi(pdev); + + /* request and enable interrupt */ + if (pci_dev_msi_enabled(pdev)) + err = request_threaded_irq(pdev->irq, + NULL, + mei_interrupt_thread_handler, + 0, mei_driver_name, dev); + else + err = request_threaded_irq(pdev->irq, mei_interrupt_quick_handler, mei_interrupt_thread_handler, IRQF_SHARED, mei_driver_name, dev); + if (err) { printk(KERN_ERR "mei: request_threaded_irq failure. irq = %d\n", pdev->irq); @@ -183,6 +192,7 @@ release_irq: mei_disable_interrupts(dev); flush_scheduled_work(); free_irq(pdev->irq, dev); + pci_disable_msi(pdev); unmap_memory: pci_iounmap(pdev, dev->mem_addr); free_device: @@ -247,6 +257,7 @@ static void __devexit mei_remove(struct pci_dev *pdev) mei_disable_interrupts(dev); free_irq(pdev->irq, dev); + pci_disable_msi(pdev); pci_set_drvdata(pdev, NULL); if (dev->mem_addr) @@ -1096,7 +1107,7 @@ static int mei_pci_suspend(struct device *device) mutex_unlock(&dev->device_lock); free_irq(pdev->irq, dev); - + pci_disable_msi(pdev); return err; } @@ -1111,11 +1122,20 @@ static int mei_pci_resume(struct device *device) if (!dev) return -ENODEV; - /* request and enable interrupt */ - err = request_threaded_irq(pdev->irq, + pci_enable_msi(pdev); + + /* request and enable interrupt */ + if (pci_dev_msi_enabled(pdev)) + err = request_threaded_irq(pdev->irq, + NULL, + mei_interrupt_thread_handler, + 0, mei_driver_name, dev); + else + err = request_threaded_irq(pdev->irq, mei_interrupt_quick_handler, mei_interrupt_thread_handler, IRQF_SHARED, mei_driver_name, dev); + if (err) { printk(KERN_ERR "mei: Request_irq failure. irq = %d\n", pdev->irq); diff --git a/drivers/staging/nvec/nvec.c b/drivers/staging/nvec/nvec.c index 72258e8..efdc8db 100644 --- a/drivers/staging/nvec/nvec.c +++ b/drivers/staging/nvec/nvec.c @@ -22,6 +22,7 @@ #include <linux/list.h> #include <linux/notifier.h> #include <linux/platform_device.h> +#include <linux/mfd/core.h> #include "nvec.h" static unsigned char EC_DISABLE_EVENT_REPORTING[] = {'\x04','\x00','\x00'}; @@ -30,6 +31,25 @@ static unsigned char EC_GET_FIRMWARE_VERSION[] = {'\x07','\x15'}; static struct nvec_chip *nvec_power_handle; +static struct mfd_cell nvec_devices[] = { + { + .name = "nvec-kbd", + .id = 1, + }, + { + .name = "nvec-mouse", + .id = 1, + }, + { + .name = "nvec-power", + .id = 1, + }, + { + .name = "nvec-power", + .id = 2, + }, +}; + int nvec_register_notifier(struct nvec_chip *nvec, struct notifier_block *nb, unsigned int events) { @@ -139,7 +159,7 @@ static void nvec_dispatch(struct work_struct *work) } else { parse_msg(nvec, msg); if((!msg) || (!msg->data)) - dev_warn(nvec->dev, "attempt access zero pointer"); + dev_warn(nvec->dev, "attempt access zero pointer\n"); else { kfree(msg->data); kfree(msg); @@ -148,16 +168,16 @@ static void nvec_dispatch(struct work_struct *work) } } -static irqreturn_t i2c_interrupt(int irq, void *dev) +static irqreturn_t nvec_interrupt(int irq, void *dev) { unsigned long status; unsigned long received; unsigned char to_send; struct nvec_msg *msg; struct nvec_chip *nvec = (struct nvec_chip *)dev; - unsigned char *i2c_regs = nvec->i2c_regs; + void __iomem *base = nvec->base; - status = readl(i2c_regs + I2C_SL_STATUS); + status = readl(base + I2C_SL_STATUS); if(!(status & I2C_SL_IRQ)) { @@ -222,7 +242,7 @@ static irqreturn_t i2c_interrupt(int irq, void *dev) nvec->state = NVEC_WAIT; } } - writel(to_send, i2c_regs + I2C_SL_RCVD); + writel(to_send, base + I2C_SL_RCVD); gpio_set_value(nvec->gpio, 1); @@ -230,10 +250,10 @@ static irqreturn_t i2c_interrupt(int irq, void *dev) goto handled; } else { - received = readl(i2c_regs + I2C_SL_RCVD); + received = readl(base + I2C_SL_RCVD); //Workaround? if(status & RCVD) { - writel(0, i2c_regs + I2C_SL_RCVD); + writel(0, base + I2C_SL_RCVD); goto handled; } @@ -258,37 +278,26 @@ handled: return IRQ_HANDLED; } -static int __devinit nvec_add_subdev(struct nvec_chip *nvec, struct nvec_subdev *subdev) -{ - struct platform_device *pdev; - - pdev = platform_device_alloc(subdev->name, subdev->id); - pdev->dev.parent = nvec->dev; - pdev->dev.platform_data = subdev->platform_data; - - return platform_device_add(pdev); -} - -static void tegra_init_i2c_slave(struct nvec_platform_data *pdata, unsigned char *i2c_regs, - struct clk *i2c_clk) +static void tegra_init_i2c_slave(struct nvec_chip *nvec) { u32 val; - clk_enable(i2c_clk); - tegra_periph_reset_assert(i2c_clk); + clk_enable(nvec->i2c_clk); + + tegra_periph_reset_assert(nvec->i2c_clk); udelay(2); - tegra_periph_reset_deassert(i2c_clk); + tegra_periph_reset_deassert(nvec->i2c_clk); - writel(pdata->i2c_addr>>1, i2c_regs + I2C_SL_ADDR1); - writel(0, i2c_regs + I2C_SL_ADDR2); + writel(nvec->i2c_addr>>1, nvec->base + I2C_SL_ADDR1); + writel(0, nvec->base + I2C_SL_ADDR2); - writel(0x1E, i2c_regs + I2C_SL_DELAY_COUNT); + writel(0x1E, nvec->base + I2C_SL_DELAY_COUNT); val = I2C_CNFG_NEW_MASTER_SFM | I2C_CNFG_PACKET_MODE_EN | (0x2 << I2C_CNFG_DEBOUNCE_CNT_SHIFT); - writel(val, i2c_regs + I2C_CNFG); - writel(I2C_SL_NEWL, i2c_regs + I2C_SL_CNFG); + writel(val, nvec->base + I2C_CNFG); + writel(I2C_SL_NEWL, nvec->base + I2C_SL_CNFG); - clk_disable(i2c_clk); + clk_disable(nvec->i2c_clk); } static void nvec_power_off(void) @@ -299,12 +308,14 @@ static void nvec_power_off(void) static int __devinit tegra_nvec_probe(struct platform_device *pdev) { - int err, i, ret; + int err, ret; struct clk *i2c_clk; struct nvec_platform_data *pdata = pdev->dev.platform_data; struct nvec_chip *nvec; struct nvec_msg *msg; - unsigned char *i2c_regs; + struct resource *res; + struct resource *iomem; + void __iomem *base; nvec = kzalloc(sizeof(struct nvec_chip), GFP_KERNEL); if(nvec == NULL) { @@ -314,49 +325,51 @@ static int __devinit tegra_nvec_probe(struct platform_device *pdev) platform_set_drvdata(pdev, nvec); nvec->dev = &pdev->dev; nvec->gpio = pdata->gpio; - nvec->irq = pdata->irq; - -/* - i2c_clk=clk_get_sys(NULL, "i2c"); - if(IS_ERR_OR_NULL(i2c_clk)) - printk(KERN_ERR"No such clock tegra-i2c.2\n"); - else - clk_enable(i2c_clk); -*/ - i2c_regs = ioremap(pdata->base, pdata->size); - if(!i2c_regs) { - dev_err(nvec->dev, "failed to ioremap registers\n"); - goto failed; + nvec->i2c_addr = pdata->i2c_addr; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "no mem resource?\n"); + return -ENODEV; } - nvec->i2c_regs = i2c_regs; + iomem = request_mem_region(res->start, resource_size(res), pdev->name); + if (!iomem) { + dev_err(&pdev->dev, "I2C region already claimed\n"); + return -EBUSY; + } - i2c_clk = clk_get_sys(pdata->clock, NULL); - if(IS_ERR_OR_NULL(i2c_clk)) { - dev_err(nvec->dev, "failed to get clock tegra-i2c.2\n"); - goto failed; + base = ioremap(iomem->start, resource_size(iomem)); + if (!base) { + dev_err(&pdev->dev, "Can't ioremap I2C region\n"); + return -ENOMEM; } - tegra_init_i2c_slave(pdata, i2c_regs, i2c_clk); + res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!res) { + dev_err(&pdev->dev, "no irq resource?\n"); + ret = -ENODEV; + goto err_iounmap; + } - err = request_irq(nvec->irq, i2c_interrupt, IRQF_DISABLED, "nvec", nvec); - if(err) { - dev_err(nvec->dev, "couldn't request irq"); - goto failed; + i2c_clk = clk_get_sys("tegra-i2c.2", NULL); + if (IS_ERR(i2c_clk)) { + dev_err(nvec->dev, "failed to get controller clock\n"); + goto err_iounmap; } clk_enable(i2c_clk); clk_set_rate(i2c_clk, 8*80000); + nvec->base = base; + nvec->irq = res->start; + nvec->i2c_clk = i2c_clk; + /* Set the gpio to low when we've got something to say */ err = gpio_request(nvec->gpio, "nvec gpio"); if(err < 0) dev_err(nvec->dev, "couldn't request gpio\n"); - tegra_gpio_enable(nvec->gpio); - gpio_direction_output(nvec->gpio, 1); - gpio_set_value(nvec->gpio, 1); - ATOMIC_INIT_NOTIFIER_HEAD(&nvec->notifier_list); init_completion(&nvec->sync_write); @@ -366,20 +379,21 @@ static int __devinit tegra_nvec_probe(struct platform_device *pdev) INIT_WORK(&nvec->rx_work, nvec_dispatch); INIT_WORK(&nvec->tx_work, nvec_request_master); + err = request_irq(nvec->irq, nvec_interrupt, 0, "nvec", nvec); + if (err) { + dev_err(nvec->dev, "couldn't request irq\n"); + goto failed; + } + + tegra_init_i2c_slave(nvec); + + gpio_direction_output(nvec->gpio, 1); + gpio_set_value(nvec->gpio, 1); + /* enable event reporting */ nvec_write_async(nvec, EC_ENABLE_EVENT_REPORTING, sizeof(EC_ENABLE_EVENT_REPORTING)); - nvec_kbd_init(nvec); -#ifdef CONFIG_SERIO_NVEC_PS2 - nvec_ps2(nvec); -#endif - - /* setup subdevs */ - for (i = 0; i < pdata->num_subdevs; i++) { - ret = nvec_add_subdev(nvec, &pdata->subdevs[i]); - } - nvec->nvec_status_notifier.notifier_call = nvec_status_notifier; nvec_register_notifier(nvec, &nvec->nvec_status_notifier, 0); @@ -396,6 +410,11 @@ static int __devinit tegra_nvec_probe(struct platform_device *pdev) kfree(msg->data); kfree(msg); + ret = mfd_add_devices(nvec->dev, -1, nvec_devices, + ARRAY_SIZE(nvec_devices), base, 0); + if(ret) + dev_err(nvec->dev, "error adding subdevices\n"); + /* unmute speakers? */ nvec_write_async(nvec, "\x0d\x10\x59\x94", 4); @@ -407,6 +426,8 @@ static int __devinit tegra_nvec_probe(struct platform_device *pdev) return 0; +err_iounmap: + iounmap(base); failed: kfree(nvec); return -ENOMEM; @@ -414,7 +435,15 @@ failed: static int __devexit tegra_nvec_remove(struct platform_device *pdev) { - // TODO: unregister + struct nvec_chip *nvec = platform_get_drvdata(pdev); + + nvec_write_async(nvec, EC_DISABLE_EVENT_REPORTING, 3); + mfd_remove_devices(nvec->dev); + free_irq(nvec->irq, &nvec_interrupt); + iounmap(nvec->base); + gpio_free(nvec->gpio); + kfree(nvec); + return 0; } @@ -436,6 +465,7 @@ static int tegra_nvec_resume(struct platform_device *pdev) { struct nvec_chip *nvec = platform_get_drvdata(pdev); dev_dbg(nvec->dev, "resuming\n"); + tegra_init_i2c_slave(nvec); nvec_write_async(nvec, EC_ENABLE_EVENT_REPORTING, 3); return 0; diff --git a/drivers/staging/nvec/nvec.h b/drivers/staging/nvec/nvec.h index a2d82dc..d9ff721 100644 --- a/drivers/staging/nvec/nvec.h +++ b/drivers/staging/nvec/nvec.h @@ -45,21 +45,17 @@ struct nvec_subdev { }; struct nvec_platform_data { - int num_subdevs; int i2c_addr; int gpio; - int irq; - int base; - int size; - char clock[16]; - struct nvec_subdev *subdevs; }; struct nvec_chip { struct device *dev; int gpio; int irq; - unsigned char *i2c_regs; + int i2c_addr; + void __iomem *base; + struct clk *i2c_clk; nvec_state state; struct atomic_notifier_head notifier_list; struct list_head rx_data, tx_data; @@ -84,9 +80,6 @@ extern int nvec_unregister_notifier(struct device *dev, const char *nvec_send_msg(unsigned char *src, unsigned char *dst_size, how_care care_resp, void (*rt_handler)(unsigned char *data)); -extern int nvec_ps2(struct nvec_chip *nvec); -extern int nvec_kbd_init(struct nvec_chip *nvec); - #define I2C_CNFG 0x00 #define I2C_CNFG_PACKET_MODE_EN (1<<10) #define I2C_CNFG_NEW_MASTER_SFM (1<<11) diff --git a/drivers/staging/nvec/nvec_kbd.c b/drivers/staging/nvec/nvec_kbd.c index 9a98507..347a38c 100644 --- a/drivers/staging/nvec/nvec_kbd.c +++ b/drivers/staging/nvec/nvec_kbd.c @@ -1,10 +1,11 @@ #include <linux/slab.h> #include <linux/input.h> #include <linux/delay.h> +#include <linux/platform_device.h> #include "nvec-keytable.h" #include "nvec.h" -#define ACK_KBD_EVENT {'\x05','\xed','\x01'} +#define ACK_KBD_EVENT {'\x05', '\xed', '\x01'} static unsigned char keycodes[ARRAY_SIZE(code_tab_102us) + ARRAY_SIZE(extcode_tab_us102)]; @@ -27,10 +28,10 @@ static int nvec_keys_notifier(struct notifier_block *nb, nvec_size _size = (msg[0] & (3 << 5)) >> 5; /* power on/off button */ - if(_size == NVEC_VAR_SIZE) + if (_size == NVEC_VAR_SIZE) return NOTIFY_STOP; - if(_size == NVEC_3BYTES) + if (_size == NVEC_3BYTES) msg++; code = msg[1] & 0x7f; @@ -51,13 +52,13 @@ static int nvec_kbd_event(struct input_dev *dev, unsigned int type, unsigned char buf[] = ACK_KBD_EVENT; struct nvec_chip *nvec = keys_dev.nvec; - if(type==EV_REP) + if (type == EV_REP) return 0; - if(type!=EV_LED) + if (type != EV_LED) return -1; - if(code!=LED_CAPSL) + if (code != LED_CAPSL) return -1; buf[2] = !!value; @@ -66,18 +67,19 @@ static int nvec_kbd_event(struct input_dev *dev, unsigned int type, return 0; } -int __init nvec_kbd_init(struct nvec_chip *nvec) +static int __devinit nvec_kbd_probe(struct platform_device *pdev) { + struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent); int i, j, err; struct input_dev *idev; j = 0; - for(i = 0; i < ARRAY_SIZE(code_tab_102us); ++i) + for (i = 0; i < ARRAY_SIZE(code_tab_102us); ++i) keycodes[j++] = code_tab_102us[i]; - for(i = 0; i < ARRAY_SIZE(extcode_tab_us102); ++i) - keycodes[j++]=extcode_tab_us102[i]; + for (i = 0; i < ARRAY_SIZE(extcode_tab_us102); ++i) + keycodes[j++] = extcode_tab_us102[i]; idev = input_allocate_device(); idev->name = "Tegra nvec keyboard"; @@ -89,12 +91,12 @@ int __init nvec_kbd_init(struct nvec_chip *nvec) idev->keycodesize = sizeof(unsigned char); idev->keycodemax = ARRAY_SIZE(keycodes); - for( i = 0; i < ARRAY_SIZE(keycodes); ++i) + for (i = 0; i < ARRAY_SIZE(keycodes); ++i) set_bit(keycodes[i], idev->keybit); clear_bit(0, idev->keybit); err = input_register_device(idev); - if(err) + if (err) goto fail; keys_dev.input = idev; @@ -120,3 +122,18 @@ fail: input_free_device(idev); return err; } + +static struct platform_driver nvec_kbd_driver = { + .probe = nvec_kbd_probe, + .driver = { + .name = "nvec-kbd", + .owner = THIS_MODULE, + }, +}; + +static int __init nvec_kbd_init(void) +{ + return platform_driver_register(&nvec_kbd_driver); +} + +module_init(nvec_kbd_init); diff --git a/drivers/staging/nvec/nvec_ps2.c b/drivers/staging/nvec/nvec_ps2.c index 6bb9430..0d3149b 100644 --- a/drivers/staging/nvec/nvec_ps2.c +++ b/drivers/staging/nvec/nvec_ps2.c @@ -1,6 +1,7 @@ #include <linux/slab.h> #include <linux/serio.h> #include <linux/delay.h> +#include <linux/platform_device.h> #include "nvec.h" #define START_STREAMING {'\x06','\x03','\x01'} @@ -77,8 +78,9 @@ static int nvec_ps2_notifier(struct notifier_block *nb, } -int __init nvec_ps2(struct nvec_chip *nvec) +static int __devinit nvec_mouse_probe(struct platform_device *pdev) { + struct nvec_chip *nvec = dev_get_drvdata(pdev->dev.parent); struct serio *ser_dev = kzalloc(sizeof(struct serio), GFP_KERNEL); ser_dev->id.type=SERIO_8042; @@ -101,3 +103,18 @@ int __init nvec_ps2(struct nvec_chip *nvec) return 0; } + +static struct platform_driver nvec_mouse_driver = { + .probe = nvec_mouse_probe, + .driver = { + .name = "nvec-mouse", + .owner = THIS_MODULE, + }, +}; + +static int __init nvec_mouse_init(void) +{ + return platform_driver_register(&nvec_mouse_driver); +} + +module_init(nvec_mouse_init); diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c index 750fe50..af24ddf 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.c +++ b/drivers/staging/olpc_dcon/olpc_dcon.c @@ -21,6 +21,7 @@ #include <linux/pci_ids.h> #include <linux/interrupt.h> #include <linux/delay.h> +#include <linux/module.h> #include <linux/backlight.h> #include <linux/device.h> #include <linux/uaccess.h> @@ -36,9 +37,6 @@ static int resumeline = 898; module_param(resumeline, int, 0444); -static int noinit; -module_param(noinit, int, 0444); - /* Default off since it doesn't work on DCON ASIC in B-test OLPC board */ static int useaa = 1; module_param(useaa, int, 0444); @@ -68,11 +66,10 @@ static s32 dcon_read(struct dcon_priv *dcon, u8 reg) static int dcon_hw_init(struct dcon_priv *dcon, int is_init) { - struct i2c_client *client = dcon->client; uint16_t ver; int rc = 0; - ver = i2c_smbus_read_word_data(client, DCON_REG_ID); + ver = dcon_read(dcon, DCON_REG_ID); if ((ver >> 8) != 0xDC) { printk(KERN_ERR "olpc-dcon: DCON ID not 0xDCxx: 0x%04x " "instead.\n", ver); @@ -90,30 +87,19 @@ static int dcon_hw_init(struct dcon_priv *dcon, int is_init) } } - if (ver < 0xdc02 && !noinit) { - /* Initialize the DCON registers */ - - /* Start with work-arounds for DCON ASIC */ - i2c_smbus_write_word_data(client, 0x4b, 0x00cc); - i2c_smbus_write_word_data(client, 0x4b, 0x00cc); - i2c_smbus_write_word_data(client, 0x4b, 0x00cc); - i2c_smbus_write_word_data(client, 0x0b, 0x007a); - i2c_smbus_write_word_data(client, 0x36, 0x025c); - i2c_smbus_write_word_data(client, 0x37, 0x025e); - - /* Initialise SDRAM */ - - i2c_smbus_write_word_data(client, 0x3b, 0x002b); - i2c_smbus_write_word_data(client, 0x41, 0x0101); - i2c_smbus_write_word_data(client, 0x42, 0x0101); - } else if (!noinit) { - /* SDRAM setup/hold time */ - i2c_smbus_write_word_data(client, 0x3a, 0xc040); - i2c_smbus_write_word_data(client, 0x41, 0x0000); - i2c_smbus_write_word_data(client, 0x41, 0x0101); - i2c_smbus_write_word_data(client, 0x42, 0x0101); + if (ver < 0xdc02) { + dev_err(&dcon->client->dev, + "DCON v1 is unsupported, giving up..\n"); + rc = -ENODEV; + goto err; } + /* SDRAM setup/hold time */ + dcon_write(dcon, 0x3a, 0xc040); + dcon_write(dcon, 0x41, 0x0000); + dcon_write(dcon, 0x41, 0x0101); + dcon_write(dcon, 0x42, 0x0101); + /* Colour swizzle, AA, no passthrough, backlight */ if (is_init) { dcon->disp_mode = MODE_PASSTHRU | MODE_BL_ENABLE | @@ -121,11 +107,11 @@ static int dcon_hw_init(struct dcon_priv *dcon, int is_init) if (useaa) dcon->disp_mode |= MODE_COL_AA; } - i2c_smbus_write_word_data(client, DCON_REG_MODE, dcon->disp_mode); + dcon_write(dcon, DCON_REG_MODE, dcon->disp_mode); /* Set the scanline to interrupt on during resume */ - i2c_smbus_write_word_data(client, DCON_REG_SCAN_INT, resumeline); + dcon_write(dcon, DCON_REG_SCAN_INT, resumeline); err: return rc; @@ -712,7 +698,6 @@ static int dcon_probe(struct i2c_client *client, const struct i2c_device_id *id) eirq: free_irq(DCON_IRQ, dcon); einit: - i2c_set_clientdata(client, NULL); kfree(dcon); return rc; } @@ -721,8 +706,6 @@ static int dcon_remove(struct i2c_client *client) { struct dcon_priv *dcon = i2c_get_clientdata(client); - i2c_set_clientdata(client, NULL); - fb_unregister_client(&dcon->fbevent_nb); unregister_reboot_notifier(&dcon->reboot_nb); atomic_notifier_chain_unregister(&panic_notifier_list, &dcon_panic_nb); diff --git a/drivers/staging/pohmelfs/trans.c b/drivers/staging/pohmelfs/trans.c index 36a2535..06c1a74 100644 --- a/drivers/staging/pohmelfs/trans.c +++ b/drivers/staging/pohmelfs/trans.c @@ -50,7 +50,7 @@ static int netfs_trans_send_pages(struct netfs_trans *t, struct netfs_state *st) int err = 0; unsigned int i, attached_pages = t->attached_pages, ci; struct msghdr msg; - struct page **pages = (t->eng)?t->eng->pages:t->pages; + struct page **pages = (t->eng) ? t->eng->pages : t->pages; struct page *p; unsigned int size; @@ -61,7 +61,7 @@ static int netfs_trans_send_pages(struct netfs_trans *t, struct netfs_state *st) msg.msg_flags = MSG_WAITALL | MSG_MORE; ci = 0; - for (i=0; i<t->page_num; ++i) { + for (i = 0; i < t->page_num; ++i) { struct page *page = pages[ci]; struct netfs_cmd cmd; struct iovec io; @@ -169,7 +169,7 @@ int netfs_trans_send(struct netfs_trans *t, struct netfs_state *st) } dprintk("%s: sent %s transaction: t: %p, gen: %u, size: %zu, page_num: %u.\n", - __func__, (t->page_num)?"partial":"full", + __func__, (t->page_num) ? "partial" : "full", t, t->gen, t->iovec.iov_len, t->page_num); err = 0; diff --git a/drivers/staging/rtl8187se/Makefile b/drivers/staging/rtl8187se/Makefile index 11a9226..72db504 100644 --- a/drivers/staging/rtl8187se/Makefile +++ b/drivers/staging/rtl8187se/Makefile @@ -1,7 +1,7 @@ -#EXTRA_CFLAGS += -DCONFIG_IEEE80211_NOWEP=y -#EXTRA_CFLAGS += -std=gnu89 -#EXTRA_CFLAGS += -O2 +#ccflags-y += -DCONFIG_IEEE80211_NOWEP=y +#ccflags-y += -std=gnu89 +#ccflags-y += -O2 #CC = gcc ccflags-y := -DSW_ANTE diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211.h b/drivers/staging/rtl8187se/ieee80211/ieee80211.h index e79a7e2..40dd715 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211.h @@ -1339,8 +1339,8 @@ int ieee80211_wx_set_mlme(struct ieee80211_device *ieee, int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len); /* ieee80211_softmac.c */ -extern short ieee80211_is_54g(struct ieee80211_network net); -extern short ieee80211_is_shortslot(struct ieee80211_network net); +extern short ieee80211_is_54g(const struct ieee80211_network *net); +extern short ieee80211_is_shortslot(const struct ieee80211_network *net); extern int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats, u16 type, u16 stype); diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c index 38e67f0..26bacb9 100644 --- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c @@ -32,14 +32,14 @@ u8 rsn_authen_cipher_suite[16][4] = { {0x00,0x0F,0xAC,0x05}, //WEP-104 }; -short ieee80211_is_54g(struct ieee80211_network net) +short ieee80211_is_54g(const struct ieee80211_network *net) { - return ((net.rates_ex_len > 0) || (net.rates_len > 4)); + return (net->rates_ex_len > 0) || (net->rates_len > 4); } -short ieee80211_is_shortslot(struct ieee80211_network net) +short ieee80211_is_shortslot(const struct ieee80211_network *net) { - return (net.capability & WLAN_CAPABILITY_SHORT_SLOT); + return net->capability & WLAN_CAPABILITY_SHORT_SLOT; } /* returns the total length needed for pleacing the RATE MFIE @@ -789,7 +789,7 @@ static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *d else atim_len = 0; - if(ieee80211_is_54g(ieee->current_network)) + if(ieee80211_is_54g(&ieee->current_network)) erp_len = 3; else erp_len = 0; @@ -1258,7 +1258,7 @@ void ieee80211_associate_complete_wq(struct work_struct *work) struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_complete_wq); printk(KERN_INFO "Associated successfully\n"); - if(ieee80211_is_54g(ieee->current_network) && + if(ieee80211_is_54g(&ieee->current_network) && (ieee->modulation & IEEE80211_OFDM_MODULATION)){ ieee->rate = 540; @@ -1379,7 +1379,7 @@ inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee ieee->beinretry = false; queue_work(ieee->wq, &ieee->associate_procedure_wq); }else{ - if(ieee80211_is_54g(ieee->current_network) && + if(ieee80211_is_54g(&ieee->current_network) && (ieee->modulation & IEEE80211_OFDM_MODULATION)){ ieee->rate = 540; printk(KERN_INFO"Using G rates\n"); diff --git a/drivers/staging/rtl8187se/r8180_rtl8225z2.c b/drivers/staging/rtl8187se/r8180_rtl8225z2.c index 3f09f76..ee5b867 100644 --- a/drivers/staging/rtl8187se/r8180_rtl8225z2.c +++ b/drivers/staging/rtl8187se/r8180_rtl8225z2.c @@ -596,7 +596,7 @@ static void rtl8225_rf_set_chan(struct net_device *dev, short ch) { struct r8180_priv *priv = ieee80211_priv(dev); short gset = (priv->ieee80211->state == IEEE80211_LINKED && - ieee80211_is_54g(priv->ieee80211->current_network)) || + ieee80211_is_54g(&priv->ieee80211->current_network)) || priv->ieee80211->iw_mode == IW_MODE_MONITOR; rtl8225_SetTXPowerLevel(dev, ch); @@ -615,7 +615,7 @@ static void rtl8225_rf_set_chan(struct net_device *dev, short ch) } if (priv->ieee80211->state == IEEE80211_LINKED && - ieee80211_is_shortslot(priv->ieee80211->current_network)) + ieee80211_is_shortslot(&priv->ieee80211->current_network)) write_nic_byte(dev, SLOT, 0x9); else write_nic_byte(dev, SLOT, 0x14); diff --git a/drivers/staging/rtl8192e/Makefile b/drivers/staging/rtl8192e/Makefile index 6e41067..a66a9ad 100644 --- a/drivers/staging/rtl8192e/Makefile +++ b/drivers/staging/rtl8192e/Makefile @@ -1,38 +1,41 @@ -NIC_SELECT = RTL8192E - -ccflags-y := -DRTL8192E -ccflags-y += -std=gnu89 -ccflags-y += -O2 -ccflags-y += -DTHOMAS_TURBO +ccflags-y += -DUSE_FW_SOURCE_IMG_FILE +ccflags-y += -DCONFIG_PM_RTL +ccflags-y += -DCONFIG_PM +ccflags-y += -DHAVE_NET_DEVICE_OPS ccflags-y += -DENABLE_DOT11D -ccflags-y += -DENABLE_IPS -ccflags-y += -DENABLE_LPS - r8192e_pci-objs := \ - r8192E_core.o \ - r8180_93cx6.o \ - r8192E_wx.o \ - r8190_rtl8256.o \ - r819xE_phy.o \ - r819xE_firmware.o \ - r819xE_cmdpkt.o \ - r8192E_dm.o \ - r8192_pm.o \ - ieee80211/ieee80211_rx.o \ - ieee80211/ieee80211_softmac.o \ - ieee80211/ieee80211_tx.o \ - ieee80211/ieee80211_wx.o \ - ieee80211/ieee80211_module.o \ - ieee80211/ieee80211_softmac_wx.o \ - ieee80211/rtl819x_HTProc.o \ - ieee80211/rtl819x_TSProc.o \ - ieee80211/rtl819x_BAProc.o \ - ieee80211/dot11d.o \ - ieee80211/ieee80211_crypt.o \ - ieee80211/ieee80211_crypt_tkip.o \ - ieee80211/ieee80211_crypt_ccmp.o \ - ieee80211/ieee80211_crypt_wep.o + rtl_core.o \ + rtl_eeprom.o \ + rtl_ps.o \ + rtl_wx.o \ + rtl_cam.o \ + rtl_dm.o \ + rtl_pm.o \ + rtl_pci.o \ + rtl_debug.o \ + rtl_ethtool.o \ + r8192E_dev.o \ + r8192E_phy.o \ + r8192E_firmware.o \ + r8192E_cmdpkt.o \ + r8192E_hwimg.o \ + r8190P_rtl8256.o \ + rtllib_rx.o \ + rtllib_softmac.o \ + rtllib_tx.o \ + rtllib_wx.o \ + rtllib_module.o \ + rtllib_softmac_wx.o \ + rtl819x_HTProc.o \ + rtl819x_TSProc.o \ + rtl819x_BAProc.o \ + dot11d.o \ + rtllib_crypt.o \ + rtllib_crypt_tkip.o \ + rtllib_crypt_ccmp.o \ + rtllib_crypt_wep.o obj-$(CONFIG_RTL8192E) += r8192e_pci.o +ccflags-y += -D__CHECK_ENDIAN__ diff --git a/drivers/staging/rtl8192e/TODO b/drivers/staging/rtl8192e/TODO new file mode 100644 index 0000000..d51f159 --- /dev/null +++ b/drivers/staging/rtl8192e/TODO @@ -0,0 +1,2 @@ +* merge into drivers/net/wireless/rtllib/rtl8192e +* clean up function naming diff --git a/drivers/staging/rtl8192e/dot11d.c b/drivers/staging/rtl8192e/dot11d.c new file mode 100644 index 0000000..ee0381e --- /dev/null +++ b/drivers/staging/rtl8192e/dot11d.c @@ -0,0 +1,216 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> +******************************************************************************/ +#include "dot11d.h" + +struct channel_list { + u8 Channel[32]; + u8 Len; +}; + +static struct channel_list ChannelPlan[] = { + {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64, + 149, 153, 157, 161, 165}, 24}, + {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11}, + {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, + 60, 64}, 21}, + {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, + {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, + {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, + 56, 60, 64}, 22}, + {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, + 56, 60, 64}, 22}, + {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, + {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, + 56, 60, 64}, 22}, + {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36, 40, 44, 48, 52, + 56, 60, 64}, 22}, + {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14}, + {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}, + {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, + 56, 60, 64}, 21} +}; + +void Dot11d_Init(struct rtllib_device *ieee) +{ + struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(ieee); + pDot11dInfo->bEnabled = false; + + pDot11dInfo->State = DOT11D_STATE_NONE; + pDot11dInfo->CountryIeLen = 0; + memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1); + memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1); + RESET_CIE_WATCHDOG(ieee); + +} + +void Dot11d_Channelmap(u8 channel_plan, struct rtllib_device *ieee) +{ + int i, max_chan = 14, min_chan = 1; + + ieee->bGlobalDomain = false; + + if (ChannelPlan[channel_plan].Len != 0) { + memset(GET_DOT11D_INFO(ieee)->channel_map, 0, + sizeof(GET_DOT11D_INFO(ieee)->channel_map)); + for (i = 0; i < ChannelPlan[channel_plan].Len; i++) { + if (ChannelPlan[channel_plan].Channel[i] < min_chan || + ChannelPlan[channel_plan].Channel[i] > max_chan) + break; + GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan + [channel_plan].Channel[i]] = 1; + } + } + + switch (channel_plan) { + case COUNTRY_CODE_GLOBAL_DOMAIN: + ieee->bGlobalDomain = true; + for (i = 12; i <= 14; i++) + GET_DOT11D_INFO(ieee)->channel_map[i] = 2; + ieee->IbssStartChnl = 10; + ieee->ibss_maxjoin_chal = 11; + break; + + case COUNTRY_CODE_WORLD_WIDE_13: + for (i = 12; i <= 13; i++) + GET_DOT11D_INFO(ieee)->channel_map[i] = 2; + ieee->IbssStartChnl = 10; + ieee->ibss_maxjoin_chal = 11; + break; + + default: + ieee->IbssStartChnl = 1; + ieee->ibss_maxjoin_chal = 14; + break; + } +} + + +void Dot11d_Reset(struct rtllib_device *ieee) +{ + struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(ieee); + u32 i; + + memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1); + memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1); + for (i = 1; i <= 11; i++) + (pDot11dInfo->channel_map)[i] = 1; + for (i = 12; i <= 14; i++) + (pDot11dInfo->channel_map)[i] = 2; + pDot11dInfo->State = DOT11D_STATE_NONE; + pDot11dInfo->CountryIeLen = 0; + RESET_CIE_WATCHDOG(ieee); +} + +void Dot11d_UpdateCountryIe(struct rtllib_device *dev, u8 *pTaddr, + u16 CoutryIeLen, u8 *pCoutryIe) +{ + struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(dev); + u8 i, j, NumTriples, MaxChnlNum; + struct chnl_txpow_triple *pTriple; + + memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1); + memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1); + MaxChnlNum = 0; + NumTriples = (CoutryIeLen - 3) / 3; + pTriple = (struct chnl_txpow_triple *)(pCoutryIe + 3); + for (i = 0; i < NumTriples; i++) { + if (MaxChnlNum >= pTriple->FirstChnl) { + printk(KERN_INFO "Dot11d_UpdateCountryIe(): Invalid" + " country IE, skip it........1\n"); + return; + } + if (MAX_CHANNEL_NUMBER < (pTriple->FirstChnl + + pTriple->NumChnls)) { + printk(KERN_INFO "Dot11d_UpdateCountryIe(): Invalid " + "country IE, skip it........2\n"); + return; + } + + for (j = 0 ; j < pTriple->NumChnls; j++) { + pDot11dInfo->channel_map[pTriple->FirstChnl + j] = 1; + pDot11dInfo->MaxTxPwrDbmList[pTriple->FirstChnl + j] = + pTriple->MaxTxPowerInDbm; + MaxChnlNum = pTriple->FirstChnl + j; + } + + pTriple = (struct chnl_txpow_triple *)((u8*)pTriple + 3); + } + + UPDATE_CIE_SRC(dev, pTaddr); + + pDot11dInfo->CountryIeLen = CoutryIeLen; + memcpy(pDot11dInfo->CountryIeBuf, pCoutryIe, CoutryIeLen); + pDot11dInfo->State = DOT11D_STATE_LEARNED; +} + +u8 DOT11D_GetMaxTxPwrInDbm(struct rtllib_device *dev, u8 Channel) +{ + struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(dev); + u8 MaxTxPwrInDbm = 255; + + if (MAX_CHANNEL_NUMBER < Channel) { + printk(KERN_INFO "DOT11D_GetMaxTxPwrInDbm(): Invalid " + "Channel\n"); + return MaxTxPwrInDbm; + } + if (pDot11dInfo->channel_map[Channel]) + MaxTxPwrInDbm = pDot11dInfo->MaxTxPwrDbmList[Channel]; + + return MaxTxPwrInDbm; +} + +void DOT11D_ScanComplete(struct rtllib_device *dev) +{ + struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(dev); + + switch (pDot11dInfo->State) { + case DOT11D_STATE_LEARNED: + pDot11dInfo->State = DOT11D_STATE_DONE; + break; + case DOT11D_STATE_DONE: + Dot11d_Reset(dev); + break; + case DOT11D_STATE_NONE: + break; + } +} + +int ToLegalChannel(struct rtllib_device *dev, u8 channel) +{ + struct rt_dot11d_info *pDot11dInfo = GET_DOT11D_INFO(dev); + u8 default_chn = 0; + u32 i; + + for (i = 1; i <= MAX_CHANNEL_NUMBER; i++) { + if (pDot11dInfo->channel_map[i] > 0) { + default_chn = i; + break; + } + } + + if (MAX_CHANNEL_NUMBER < channel) { + printk(KERN_ERR "%s(): Invalid Channel\n", __func__); + return default_chn; + } + + if (pDot11dInfo->channel_map[channel] > 0) + return channel; + + return default_chn; +} diff --git a/drivers/staging/rtl8192e/dot11d.h b/drivers/staging/rtl8192e/dot11d.h index 8e64461..032f700 100644 --- a/drivers/staging/rtl8192e/dot11d.h +++ b/drivers/staging/rtl8192e/dot11d.h @@ -1,24 +1,42 @@ -#ifndef INC_DOT11D_H -#define INC_DOT11D_H - -#ifdef ENABLE_DOT11D -#include "ieee80211.h" - -struct _CHNL_TXPOWER_TRIPLE { +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> +******************************************************************************/ +#ifndef __INC_DOT11D_H +#define __INC_DOT11D_H + +#include "rtllib.h" + + + +struct chnl_txpow_triple { u8 FirstChnl; u8 NumChnls; u8 MaxTxPowerInDbm; }; -enum _DOT11D_STATE { +enum dot11d_state { DOT11D_STATE_NONE = 0, DOT11D_STATE_LEARNED, DOT11D_STATE_DONE, }; /** - * struct _RT_DOT11D_INFO - * @CountryIeLen: value greater than 0 if @CountryIeBuf contains + * struct rt_dot11d_info * @CountryIeLen: value greater than 0 if @CountryIeBuf contains * valid country information element. * @chanell_map: holds channel values * 0 - invalid, @@ -27,18 +45,19 @@ enum _DOT11D_STATE { * @CountryIeSrcAddr - Source AP of the country IE */ -struct _RT_DOT11D_INFO { +struct rt_dot11d_info { + bool bEnabled; u16 CountryIeLen; - u8 CountryIeBuf[MAX_IE_LEN]; - u8 CountryIeSrcAddr[6]; - u8 CountryIeWatchdog; + u8 CountryIeBuf[MAX_IE_LEN]; + u8 CountryIeSrcAddr[6]; + u8 CountryIeWatchdog; - u8 channel_map[MAX_CHANNEL_NUMBER+1]; - u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1]; + u8 channel_map[MAX_CHANNEL_NUMBER+1]; + u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1]; - DOT11D_STATE State; + enum dot11d_state State; }; static inline void cpMacAddr(unsigned char *des, unsigned char *src) @@ -46,49 +65,41 @@ static inline void cpMacAddr(unsigned char *des, unsigned char *src) memcpy(des, src, 6); } -#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO) \ - ((__pIeeeDev)->pDot11dInfo)) +#define GET_DOT11D_INFO(__pIeeeDev) \ + ((struct rt_dot11d_info *)((__pIeeeDev)->pDot11dInfo)) -#define IS_DOT11D_ENABLE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->bEnabled) -#define IS_COUNTRY_IE_VALID(__pIeeeDev) \ - (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0) +#define IS_DOT11D_ENABLE(__pIeeeDev) \ + (GET_DOT11D_INFO(__pIeeeDev)->bEnabled) +#define IS_COUNTRY_IE_VALID(__pIeeeDev) \ + (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0) -#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) \ - eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa) - -#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) \ - cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa) +#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) \ + eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa) +#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) \ + cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa) #define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \ - (((__Ie).Length == 0 || (__Ie).Length != \ - GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? FALSE : \ - (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, \ + (((__Ie).Length == 0 || (__Ie).Length != \ + GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \ + false : (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, \ (__Ie).Octet, (__Ie).Length))) #define CIE_WATCHDOG_TH 1 -#define GET_CIE_WATCHDOG(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)-> \ - CountryIeWatchdog) +#define GET_CIE_WATCHDOG(__pIeeeDev) \ + (GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog) #define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0 #define UPDATE_CIE_WATCHDOG(__pIeeeDev) (++GET_CIE_WATCHDOG(__pIeeeDev)) -#define IS_DOT11D_STATE_DONE(__pIeeeDev) \ - (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE) - - -void Dot11d_Init(struct ieee80211_device *dev); - -void Dot11d_Reset(struct ieee80211_device *dev); - -void Dot11d_UpdateCountryIe(struct ieee80211_device *dev, u8 *pTaddr, - u16 CoutryIeLen, u8 *pCoutryIe); - -u8 DOT11D_GetMaxTxPwrInDbm(struct ieee80211_device *dev, u8 channel); - -void DOT11D_ScanComplete(struct ieee80211_device *dev); - -int IsLegalChannel(struct ieee80211_device *dev, u8 channel); +#define IS_DOT11D_STATE_DONE(__pIeeeDev) \ + (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE) -int ToLegalChannel(struct ieee80211_device *dev, u8 channel); +void Dot11d_Init(struct rtllib_device *dev); +void Dot11d_Channelmap(u8 channel_plan, struct rtllib_device *ieee); +void Dot11d_Reset(struct rtllib_device *dev); +void Dot11d_UpdateCountryIe(struct rtllib_device *dev, u8 *pTaddr, + u16 CoutryIeLen, u8 *pCoutryIe); +u8 DOT11D_GetMaxTxPwrInDbm(struct rtllib_device *dev, u8 Channel); +void DOT11D_ScanComplete(struct rtllib_device *dev); +int ToLegalChannel(struct rtllib_device *dev, u8 channel); -#endif /* ENABLE_DOT11D */ -#endif /* INC_DOT11D_H */ +#endif diff --git a/drivers/staging/rtl8192e/ieee80211/dot11d.c b/drivers/staging/rtl8192e/ieee80211/dot11d.c deleted file mode 100644 index 98e4648..0000000 --- a/drivers/staging/rtl8192e/ieee80211/dot11d.c +++ /dev/null @@ -1,218 +0,0 @@ -#ifdef ENABLE_DOT11D -//----------------------------------------------------------------------------- -// File: -// Dot11d.c -// -// Description: -// Implement 802.11d. -// -//----------------------------------------------------------------------------- - -#include "dot11d.h" - -void -Dot11d_Init(struct ieee80211_device *ieee) -{ - PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee); - - pDot11dInfo->bEnabled = 0; - - pDot11dInfo->State = DOT11D_STATE_NONE; - pDot11dInfo->CountryIeLen = 0; - memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1); - memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1); - RESET_CIE_WATCHDOG(ieee); - - printk("Dot11d_Init()\n"); -} - -// -// Description: -// Reset to the state as we are just entering a regulatory domain. -// -void -Dot11d_Reset(struct ieee80211_device *ieee) -{ - u32 i; - PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee); -#if 0 - if(!pDot11dInfo->bEnabled) - return; -#endif - // Clear old channel map - memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1); - memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1); - // Set new channel map - for (i=1; i<=11; i++) { - (pDot11dInfo->channel_map)[i] = 1; - } - for (i=12; i<=14; i++) { - (pDot11dInfo->channel_map)[i] = 2; - } - - pDot11dInfo->State = DOT11D_STATE_NONE; - pDot11dInfo->CountryIeLen = 0; - RESET_CIE_WATCHDOG(ieee); -} - -// -// Description: -// Update country IE from Beacon or Probe Resopnse -// and configure PHY for operation in the regulatory domain. -// -// TODO: -// Configure Tx power. -// -// Assumption: -// 1. IS_DOT11D_ENABLE() is TRUE. -// 2. Input IE is an valid one. -// -void -Dot11d_UpdateCountryIe( - struct ieee80211_device *dev, - u8 * pTaddr, - u16 CoutryIeLen, - u8 * pCoutryIe - ) -{ - PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev); - u8 i, j, NumTriples, MaxChnlNum; - PCHNL_TXPOWER_TRIPLE pTriple; - - memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1); - memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1); - MaxChnlNum = 0; - NumTriples = (CoutryIeLen - 3) / 3; // skip 3-byte country string. - pTriple = (PCHNL_TXPOWER_TRIPLE)(pCoutryIe + 3); - for(i = 0; i < NumTriples; i++) - { - if(MaxChnlNum >= pTriple->FirstChnl) - { // It is not in a monotonically increasing order, so stop processing. - printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n"); - return; - } - if(MAX_CHANNEL_NUMBER < (pTriple->FirstChnl + pTriple->NumChnls)) - { // It is not a valid set of channel id, so stop processing. - printk("Dot11d_UpdateCountryIe(): Invalid country IE, skip it........2\n"); - return; - } - - for(j = 0 ; j < pTriple->NumChnls; j++) - { - pDot11dInfo->channel_map[pTriple->FirstChnl + j] = 1; - pDot11dInfo->MaxTxPwrDbmList[pTriple->FirstChnl + j] = pTriple->MaxTxPowerInDbm; - MaxChnlNum = pTriple->FirstChnl + j; - } - - pTriple = (PCHNL_TXPOWER_TRIPLE)((u8*)pTriple + 3); - } -#if 1 - printk("Channel List:"); - for(i=1; i<= MAX_CHANNEL_NUMBER; i++) - if(pDot11dInfo->channel_map[i] > 0) - printk(" %d", i); - printk("\n"); -#endif - - UPDATE_CIE_SRC(dev, pTaddr); - - pDot11dInfo->CountryIeLen = CoutryIeLen; - memcpy(pDot11dInfo->CountryIeBuf, pCoutryIe,CoutryIeLen); - pDot11dInfo->State = DOT11D_STATE_LEARNED; -} - - -u8 -DOT11D_GetMaxTxPwrInDbm( - struct ieee80211_device *dev, - u8 Channel - ) -{ - PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev); - u8 MaxTxPwrInDbm = 255; - - if(MAX_CHANNEL_NUMBER < Channel) - { - printk("DOT11D_GetMaxTxPwrInDbm(): Invalid Channel\n"); - return MaxTxPwrInDbm; - } - if(pDot11dInfo->channel_map[Channel]) - { - MaxTxPwrInDbm = pDot11dInfo->MaxTxPwrDbmList[Channel]; - } - - return MaxTxPwrInDbm; -} - - -void -DOT11D_ScanComplete( - struct ieee80211_device * dev - ) -{ - PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev); - - switch(pDot11dInfo->State) - { - case DOT11D_STATE_LEARNED: - pDot11dInfo->State = DOT11D_STATE_DONE; - break; - - case DOT11D_STATE_DONE: - if( GET_CIE_WATCHDOG(dev) == 0 ) - { // Reset country IE if previous one is gone. - Dot11d_Reset(dev); - } - break; - case DOT11D_STATE_NONE: - break; - } -} - -int IsLegalChannel( - struct ieee80211_device * dev, - u8 channel -) -{ - PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev); - - if(MAX_CHANNEL_NUMBER < channel) - { - printk("IsLegalChannel(): Invalid Channel\n"); - return 0; - } - if(pDot11dInfo->channel_map[channel] > 0) - return 1; - return 0; -} - -int ToLegalChannel( - struct ieee80211_device * dev, - u8 channel -) -{ - PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev); - u8 default_chn = 0; - u32 i = 0; - - for (i=1; i<= MAX_CHANNEL_NUMBER; i++) - { - if(pDot11dInfo->channel_map[i] > 0) - { - default_chn = i; - break; - } - } - - if(MAX_CHANNEL_NUMBER < channel) - { - printk("IsLegalChannel(): Invalid Channel\n"); - return default_chn; - } - - if(pDot11dInfo->channel_map[channel] > 0) - return channel; - - return default_chn; -} -#endif diff --git a/drivers/staging/rtl8192e/ieee80211/dot11d.h b/drivers/staging/rtl8192e/ieee80211/dot11d.h deleted file mode 100644 index 15b7a4b..0000000 --- a/drivers/staging/rtl8192e/ieee80211/dot11d.h +++ /dev/null @@ -1,102 +0,0 @@ -#ifndef __INC_DOT11D_H -#define __INC_DOT11D_H - -#ifdef ENABLE_DOT11D -#include "ieee80211.h" - -//#define ENABLE_DOT11D - -//#define DOT11D_MAX_CHNL_NUM 83 - -typedef struct _CHNL_TXPOWER_TRIPLE { - u8 FirstChnl; - u8 NumChnls; - u8 MaxTxPowerInDbm; -}CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE; - -typedef enum _DOT11D_STATE { - DOT11D_STATE_NONE = 0, - DOT11D_STATE_LEARNED, - DOT11D_STATE_DONE, -}DOT11D_STATE; - -typedef struct _RT_DOT11D_INFO { - //DECLARE_RT_OBJECT(RT_DOT11D_INFO); - - bool bEnabled; // dot11MultiDomainCapabilityEnabled - - u16 CountryIeLen; // > 0 if CountryIeBuf[] contains valid country information element. - u8 CountryIeBuf[MAX_IE_LEN]; - u8 CountryIeSrcAddr[6]; // Source AP of the country IE. - u8 CountryIeWatchdog; - - u8 channel_map[MAX_CHANNEL_NUMBER+1]; //!!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan) - //u8 ChnlListLen; // #Bytes valid in ChnlList[]. - //u8 ChnlList[DOT11D_MAX_CHNL_NUM]; - u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1]; - - DOT11D_STATE State; -}RT_DOT11D_INFO, *PRT_DOT11D_INFO; -#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 ) -#define cpMacAddr(des,src) ((des)[0]=(src)[0],(des)[1]=(src)[1],(des)[2]=(src)[2],(des)[3]=(src)[3],(des)[4]=(src)[4],(des)[5]=(src)[5]) -#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo)) - -#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled -#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0) - -#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa) -#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa) - -#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \ - (((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \ - FALSE : \ - (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length))) - -#define CIE_WATCHDOG_TH 1 -#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog -#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0 -#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev) - -#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE) - - -void -Dot11d_Init( - struct ieee80211_device *dev - ); - -void -Dot11d_Reset( - struct ieee80211_device *dev - ); - -void -Dot11d_UpdateCountryIe( - struct ieee80211_device *dev, - u8 * pTaddr, - u16 CoutryIeLen, - u8 * pCoutryIe - ); - -u8 -DOT11D_GetMaxTxPwrInDbm( - struct ieee80211_device *dev, - u8 Channel - ); - -void -DOT11D_ScanComplete( - struct ieee80211_device * dev - ); - -int IsLegalChannel( - struct ieee80211_device * dev, - u8 channel -); - -int ToLegalChannel( - struct ieee80211_device * dev, - u8 channel -); -#endif //ENABLE_DOT11D -#endif // #ifndef __INC_DOT11D_H diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211.h b/drivers/staging/rtl8192e/ieee80211/ieee80211.h deleted file mode 100644 index 6d7963e..0000000 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211.h +++ /dev/null @@ -1,2636 +0,0 @@ -/* - * Merged with mainline ieee80211.h in Aug 2004. Original ieee802_11 - * remains copyright by the original authors - * - * Portions of the merged code are based on Host AP (software wireless - * LAN access point) driver for Intersil Prism2/2.5/3. - * - * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen - * <jkmaline@cc.hut.fi> - * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi> - * - * Adaption to a generic IEEE 802.11 stack by James Ketrenos - * <jketreno@linux.intel.com> - * Copyright (c) 2004, Intel Corporation - * - * Modified for Realtek's wi-fi cards by Andrea Merello - * <andreamrl@tiscali.it> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See README and COPYING for - * more details. - */ -#ifndef IEEE80211_H -#define IEEE80211_H -#include <linux/if_ether.h> /* ETH_ALEN */ -#include <linux/kernel.h> /* ARRAY_SIZE */ -#include <linux/module.h> -#include <linux/jiffies.h> -#include <linux/timer.h> -#include <linux/sched.h> -#include <linux/semaphore.h> -#include <linux/interrupt.h> - -#include <linux/delay.h> -#include <linux/wireless.h> - -#include "rtl819x_HT.h" -#include "rtl819x_BA.h" -#include "rtl819x_TS.h" - -#ifndef IW_MODE_MONITOR -#define IW_MODE_MONITOR 6 -#endif - -#ifndef IWEVCUSTOM -#define IWEVCUSTOM 0x8c02 -#endif - -#ifndef container_of -/** - * container_of - cast a member of a structure out to the containing structure - * - * @ptr: the pointer to the member. - * @type: the type of the container struct this is embedded in. - * @member: the name of the member within the struct. - * - */ -#define container_of(ptr, type, member) ({ \ - const typeof( ((type *)0)->member ) *__mptr = (ptr); \ - (type *)( (char *)__mptr - offsetof(type,member) );}) -#endif - -#define KEY_TYPE_NA 0x0 -#define KEY_TYPE_WEP40 0x1 -#define KEY_TYPE_TKIP 0x2 -#define KEY_TYPE_CCMP 0x4 -#define KEY_TYPE_WEP104 0x5 - -/* added for rtl819x tx procedure */ -#define MAX_QUEUE_SIZE 0x10 - -// -// 8190 queue mapping -// -#define BK_QUEUE 0 -#define BE_QUEUE 1 -#define VI_QUEUE 2 -#define VO_QUEUE 3 -#define HCCA_QUEUE 4 -#define TXCMD_QUEUE 5 -#define MGNT_QUEUE 6 -#define HIGH_QUEUE 7 -#define BEACON_QUEUE 8 - -#define LOW_QUEUE BE_QUEUE -#define NORMAL_QUEUE MGNT_QUEUE - -//added by amy for ps -#define SWRF_TIMEOUT 50 - -//added by amy for LEAP related -#define IE_CISCO_FLAG_POSITION 0x08 // Flag byte: byte 8, numbered from 0. -#define SUPPORT_CKIP_MIC 0x08 // bit3 -#define SUPPORT_CKIP_PK 0x10 // bit4 -/* defined for skb cb field */ -/* At most 28 byte */ -typedef struct cb_desc { - /* Tx Desc Related flags (8-9) */ - u8 bLastIniPkt:1; - u8 bCmdOrInit:1; - u8 bFirstSeg:1; - u8 bLastSeg:1; - u8 bEncrypt:1; - u8 bTxDisableRateFallBack:1; - u8 bTxUseDriverAssingedRate:1; - u8 bHwSec:1; //indicate whether use Hw security. WB - - u8 reserved1; - - /* Tx Firmware Relaged flags (10-11)*/ - u8 bCTSEnable:1; - u8 bRTSEnable:1; - u8 bUseShortGI:1; - u8 bUseShortPreamble:1; - u8 bTxEnableFwCalcDur:1; - u8 bAMPDUEnable:1; - u8 bRTSSTBC:1; - u8 RTSSC:1; - - u8 bRTSBW:1; - u8 bPacketBW:1; - u8 bRTSUseShortPreamble:1; - u8 bRTSUseShortGI:1; - u8 bMulticast:1; - u8 bBroadcast:1; - //u8 reserved2:2; - u8 drv_agg_enable:1; - u8 reserved2:1; - - /* Tx Desc related element(12-19) */ - u8 rata_index; - u8 queue_index; - //u8 reserved3; - //u8 reserved4; - u16 txbuf_size; - //u8 reserved5; - u8 RATRIndex; - u8 reserved6; - u8 reserved7; - u8 reserved8; - - /* Tx firmware related element(20-27) */ - u8 data_rate; - u8 rts_rate; - u8 ampdu_factor; - u8 ampdu_density; - //u8 reserved9; - //u8 reserved10; - //u8 reserved11; - u8 DrvAggrNum; - u16 pkt_size; - u8 reserved12; - - u8 bdhcp; -}cb_desc, *pcb_desc; - -/*--------------------------Define -------------------------------------------*/ -#define MGN_1M 0x02 -#define MGN_2M 0x04 -#define MGN_5_5M 0x0b -#define MGN_11M 0x16 - -#define MGN_6M 0x0c -#define MGN_9M 0x12 -#define MGN_12M 0x18 -#define MGN_18M 0x24 -#define MGN_24M 0x30 -#define MGN_36M 0x48 -#define MGN_48M 0x60 -#define MGN_54M 0x6c - -#define MGN_MCS0 0x80 -#define MGN_MCS1 0x81 -#define MGN_MCS2 0x82 -#define MGN_MCS3 0x83 -#define MGN_MCS4 0x84 -#define MGN_MCS5 0x85 -#define MGN_MCS6 0x86 -#define MGN_MCS7 0x87 -#define MGN_MCS8 0x88 -#define MGN_MCS9 0x89 -#define MGN_MCS10 0x8a -#define MGN_MCS11 0x8b -#define MGN_MCS12 0x8c -#define MGN_MCS13 0x8d -#define MGN_MCS14 0x8e -#define MGN_MCS15 0x8f - -//---------------------------------------------------------------------------- -// 802.11 Management frame Reason Code field -//---------------------------------------------------------------------------- -enum _ReasonCode{ - unspec_reason = 0x1, - auth_not_valid = 0x2, - deauth_lv_ss = 0x3, - inactivity = 0x4, - ap_overload = 0x5, - class2_err = 0x6, - class3_err = 0x7, - disas_lv_ss = 0x8, - asoc_not_auth = 0x9, - - //----MIC_CHECK - mic_failure = 0xe, - //----END MIC_CHECK - - // Reason code defined in 802.11i D10.0 p.28. - invalid_IE = 0x0d, - four_way_tmout = 0x0f, - two_way_tmout = 0x10, - IE_dismatch = 0x11, - invalid_Gcipher = 0x12, - invalid_Pcipher = 0x13, - invalid_AKMP = 0x14, - unsup_RSNIEver = 0x15, - invalid_RSNIE = 0x16, - auth_802_1x_fail= 0x17, - ciper_reject = 0x18, - - // Reason code defined in 7.3.1.7, 802.1e D13.0, p.42. Added by Annie, 2005-11-15. - QoS_unspec = 0x20, // 32 - QAP_bandwidth = 0x21, // 33 - poor_condition = 0x22, // 34 - no_facility = 0x23, // 35 - // Where is 36??? - req_declined = 0x25, // 37 - invalid_param = 0x26, // 38 - req_not_honored= 0x27, // 39 - TS_not_created = 0x2F, // 47 - DL_not_allowed = 0x30, // 48 - dest_not_exist = 0x31, // 49 - dest_not_QSTA = 0x32, // 50 -}; - - - -#define aSifsTime (((priv->ieee80211->current_network.mode == IEEE_A)||(priv->ieee80211->current_network.mode == IEEE_N_24G)||(priv->ieee80211->current_network.mode == IEEE_N_5G))? 16 : 10) - -#define MGMT_QUEUE_NUM 5 - -#define IEEE_CMD_SET_WPA_PARAM 1 -#define IEEE_CMD_SET_WPA_IE 2 -#define IEEE_CMD_SET_ENCRYPTION 3 -#define IEEE_CMD_MLME 4 - -#define IEEE_PARAM_WPA_ENABLED 1 -#define IEEE_PARAM_TKIP_COUNTERMEASURES 2 -#define IEEE_PARAM_DROP_UNENCRYPTED 3 -#define IEEE_PARAM_PRIVACY_INVOKED 4 -#define IEEE_PARAM_AUTH_ALGS 5 -#define IEEE_PARAM_IEEE_802_1X 6 -//It should consistent with the driver_XXX.c -// David, 2006.9.26 -#define IEEE_PARAM_WPAX_SELECT 7 -//Added for notify the encryption type selection -// David, 2006.9.26 -#define IEEE_PROTO_WPA 1 -#define IEEE_PROTO_RSN 2 -//Added for notify the encryption type selection -// David, 2006.9.26 -#define IEEE_WPAX_USEGROUP 0 -#define IEEE_WPAX_WEP40 1 -#define IEEE_WPAX_TKIP 2 -#define IEEE_WPAX_WRAP 3 -#define IEEE_WPAX_CCMP 4 -#define IEEE_WPAX_WEP104 5 - -#define IEEE_KEY_MGMT_IEEE8021X 1 -#define IEEE_KEY_MGMT_PSK 2 - -#define IEEE_MLME_STA_DEAUTH 1 -#define IEEE_MLME_STA_DISASSOC 2 - - -#define IEEE_CRYPT_ERR_UNKNOWN_ALG 2 -#define IEEE_CRYPT_ERR_UNKNOWN_ADDR 3 -#define IEEE_CRYPT_ERR_CRYPT_INIT_FAILED 4 -#define IEEE_CRYPT_ERR_KEY_SET_FAILED 5 -#define IEEE_CRYPT_ERR_TX_KEY_SET_FAILED 6 -#define IEEE_CRYPT_ERR_CARD_CONF_FAILED 7 - - -#define IEEE_CRYPT_ALG_NAME_LEN 16 - -#define MAX_IE_LEN 0xff - -// added for kernel conflict -#define ieee80211_crypt_deinit_entries ieee80211_crypt_deinit_entries_rsl -#define ieee80211_crypt_deinit_handler ieee80211_crypt_deinit_handler_rsl -#define ieee80211_crypt_delayed_deinit ieee80211_crypt_delayed_deinit_rsl -#define ieee80211_register_crypto_ops ieee80211_register_crypto_ops_rsl -#define ieee80211_unregister_crypto_ops ieee80211_unregister_crypto_ops_rsl -#define ieee80211_get_crypto_ops ieee80211_get_crypto_ops_rsl - -#define ieee80211_ccmp_null ieee80211_ccmp_null_rsl - -#define ieee80211_tkip_null ieee80211_tkip_null_rsl - -#define ieee80211_wep_null ieee80211_wep_null_rsl - -#define free_ieee80211 free_ieee80211_rsl -#define alloc_ieee80211 alloc_ieee80211_rsl - -#define ieee80211_rx ieee80211_rx_rsl -#define ieee80211_rx_mgt ieee80211_rx_mgt_rsl - -#define ieee80211_get_beacon ieee80211_get_beacon_rsl -#define ieee80211_rtl_wake_queue ieee80211_rtl_wake_queue_rsl -#define ieee80211_rtl_stop_queue ieee80211_rtl_stop_queue_rsl -#define ieee80211_reset_queue ieee80211_reset_queue_rsl -#define ieee80211_softmac_stop_protocol ieee80211_softmac_stop_protocol_rsl -#define ieee80211_softmac_start_protocol ieee80211_softmac_start_protocol_rsl -#define ieee80211_is_shortslot ieee80211_is_shortslot_rsl -#define ieee80211_is_54g ieee80211_is_54g_rsl -#define ieee80211_wpa_supplicant_ioctl ieee80211_wpa_supplicant_ioctl_rsl -#define ieee80211_ps_tx_ack ieee80211_ps_tx_ack_rsl -#define ieee80211_softmac_xmit ieee80211_softmac_xmit_rsl -#define ieee80211_stop_send_beacons ieee80211_stop_send_beacons_rsl -#define notify_wx_assoc_event notify_wx_assoc_event_rsl -#define SendDisassociation SendDisassociation_rsl -#define ieee80211_disassociate ieee80211_disassociate_rsl -#define ieee80211_start_send_beacons ieee80211_start_send_beacons_rsl -#define ieee80211_stop_scan ieee80211_stop_scan_rsl -#define ieee80211_send_probe_requests ieee80211_send_probe_requests_rsl -#define ieee80211_softmac_scan_syncro ieee80211_softmac_scan_syncro_rsl -#define ieee80211_start_scan_syncro ieee80211_start_scan_syncro_rsl - -#define ieee80211_wx_get_essid ieee80211_wx_get_essid_rsl -#define ieee80211_wx_set_essid ieee80211_wx_set_essid_rsl -#define ieee80211_wx_set_rate ieee80211_wx_set_rate_rsl -#define ieee80211_wx_get_rate ieee80211_wx_get_rate_rsl -#define ieee80211_wx_set_wap ieee80211_wx_set_wap_rsl -#define ieee80211_wx_get_wap ieee80211_wx_get_wap_rsl -#define ieee80211_wx_set_mode ieee80211_wx_set_mode_rsl -#define ieee80211_wx_get_mode ieee80211_wx_get_mode_rsl -#define ieee80211_wx_set_scan ieee80211_wx_set_scan_rsl -#define ieee80211_wx_get_freq ieee80211_wx_get_freq_rsl -#define ieee80211_wx_set_freq ieee80211_wx_set_freq_rsl -#define ieee80211_wx_set_rawtx ieee80211_wx_set_rawtx_rsl -#define ieee80211_wx_get_name ieee80211_wx_get_name_rsl -#define ieee80211_wx_set_power ieee80211_wx_set_power_rsl -#define ieee80211_wx_get_power ieee80211_wx_get_power_rsl -#define ieee80211_wlan_frequencies ieee80211_wlan_frequencies_rsl -#define ieee80211_wx_set_rts ieee80211_wx_set_rts_rsl -#define ieee80211_wx_get_rts ieee80211_wx_get_rts_rsl - -#define ieee80211_txb_free ieee80211_txb_free_rsl - -#define ieee80211_wx_set_gen_ie ieee80211_wx_set_gen_ie_rsl -#define ieee80211_wx_get_scan ieee80211_wx_get_scan_rsl -#define ieee80211_wx_set_encode ieee80211_wx_set_encode_rsl -#define ieee80211_wx_get_encode ieee80211_wx_get_encode_rsl -#define ieee80211_wx_set_mlme ieee80211_wx_set_mlme_rsl -#define ieee80211_wx_set_auth ieee80211_wx_set_auth_rsl -#define ieee80211_wx_set_encode_ext ieee80211_wx_set_encode_ext_rsl -#define ieee80211_wx_get_encode_ext ieee80211_wx_get_encode_ext_rsl - - -typedef struct ieee_param { - u32 cmd; - u8 sta_addr[ETH_ALEN]; - union { - struct { - u8 name; - u32 value; - } wpa_param; - struct { - u32 len; - u8 reserved[32]; - u8 data[0]; - } wpa_ie; - struct{ - int command; - int reason_code; - } mlme; - struct { - u8 alg[IEEE_CRYPT_ALG_NAME_LEN]; - u8 set_tx; - u32 err; - u8 idx; - u8 seq[8]; /* sequence counter (set: RX, get: TX) */ - u16 key_len; - u8 key[0]; - } crypt; - } u; -}ieee_param; - - -// linux under 2.6.9 release may not support it, so modify it for common use -#define MSECS(t) msecs_to_jiffies(t) -#define msleep_interruptible_rsl msleep_interruptible - -#define IEEE80211_DATA_LEN 2304 -/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section - 6.2.1.1.2. - - The figure in section 7.1.2 suggests a body size of up to 2312 - bytes is allowed, which is a bit confusing, I suspect this - represents the 2304 bytes of real data, plus a possible 8 bytes of - WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */ -#define IEEE80211_1ADDR_LEN 10 -#define IEEE80211_2ADDR_LEN 16 -#define IEEE80211_3ADDR_LEN 24 -#define IEEE80211_4ADDR_LEN 30 -#define IEEE80211_FCS_LEN 4 -#define IEEE80211_HLEN (IEEE80211_4ADDR_LEN) -#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN) -#define IEEE80211_MGMT_HDR_LEN 24 -#define IEEE80211_DATA_HDR3_LEN 24 -#define IEEE80211_DATA_HDR4_LEN 30 - -#define MIN_FRAG_THRESHOLD 256U -#define MAX_FRAG_THRESHOLD 2346U - - -/* Frame control field constants */ -#define IEEE80211_FCTL_VERS 0x0003 -#define IEEE80211_FCTL_FTYPE 0x000c -#define IEEE80211_FCTL_STYPE 0x00f0 -#define IEEE80211_FCTL_FRAMETYPE 0x00fc -#define IEEE80211_FCTL_TODS 0x0100 -#define IEEE80211_FCTL_FROMDS 0x0200 -#define IEEE80211_FCTL_DSTODS 0x0300 //added by david -#define IEEE80211_FCTL_MOREFRAGS 0x0400 -#define IEEE80211_FCTL_RETRY 0x0800 -#define IEEE80211_FCTL_PM 0x1000 -#define IEEE80211_FCTL_MOREDATA 0x2000 -#define IEEE80211_FCTL_WEP 0x4000 -#define IEEE80211_FCTL_ORDER 0x8000 - -#define IEEE80211_FTYPE_MGMT 0x0000 -#define IEEE80211_FTYPE_CTL 0x0004 -#define IEEE80211_FTYPE_DATA 0x0008 - -/* management */ -#define IEEE80211_STYPE_ASSOC_REQ 0x0000 -#define IEEE80211_STYPE_ASSOC_RESP 0x0010 -#define IEEE80211_STYPE_REASSOC_REQ 0x0020 -#define IEEE80211_STYPE_REASSOC_RESP 0x0030 -#define IEEE80211_STYPE_PROBE_REQ 0x0040 -#define IEEE80211_STYPE_PROBE_RESP 0x0050 -#define IEEE80211_STYPE_BEACON 0x0080 -#define IEEE80211_STYPE_ATIM 0x0090 -#define IEEE80211_STYPE_DISASSOC 0x00A0 -#define IEEE80211_STYPE_AUTH 0x00B0 -#define IEEE80211_STYPE_DEAUTH 0x00C0 -#define IEEE80211_STYPE_MANAGE_ACT 0x00D0 - -/* control */ -#define IEEE80211_STYPE_PSPOLL 0x00A0 -#define IEEE80211_STYPE_RTS 0x00B0 -#define IEEE80211_STYPE_CTS 0x00C0 -#define IEEE80211_STYPE_ACK 0x00D0 -#define IEEE80211_STYPE_CFEND 0x00E0 -#define IEEE80211_STYPE_CFENDACK 0x00F0 -#define IEEE80211_STYPE_BLOCKACK 0x0094 - -/* data */ -#define IEEE80211_STYPE_DATA 0x0000 -#define IEEE80211_STYPE_DATA_CFACK 0x0010 -#define IEEE80211_STYPE_DATA_CFPOLL 0x0020 -#define IEEE80211_STYPE_DATA_CFACKPOLL 0x0030 -#define IEEE80211_STYPE_NULLFUNC 0x0040 -#define IEEE80211_STYPE_CFACK 0x0050 -#define IEEE80211_STYPE_CFPOLL 0x0060 -#define IEEE80211_STYPE_CFACKPOLL 0x0070 -#define IEEE80211_STYPE_QOS_DATA 0x0080 //added for WMM 2006/8/2 -#define IEEE80211_STYPE_QOS_NULL 0x00C0 - -#define IEEE80211_SCTL_FRAG 0x000F -#define IEEE80211_SCTL_SEQ 0xFFF0 - -/* QOS control */ -#define IEEE80211_QCTL_TID 0x000F - -#define FC_QOS_BIT BIT7 -#define IsDataFrame(pdu) ( ((pdu[0] & 0x0C)==0x08) ? true : false ) -#define IsLegacyDataFrame(pdu) (IsDataFrame(pdu) && (!(pdu[0]&FC_QOS_BIT)) ) -//added by wb. Is this right? -#define IsQoSDataFrame(pframe) ((*(u16*)pframe&(IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA)) == (IEEE80211_STYPE_QOS_DATA|IEEE80211_FTYPE_DATA)) -#define Frame_Order(pframe) (*(u16*)pframe&IEEE80211_FCTL_ORDER) -#define SN_LESS(a, b) (((a-b)&0x800)!=0) -#define SN_EQUAL(a, b) (a == b) -#define MAX_DEV_ADDR_SIZE 8 -typedef enum _ACT_CATEGORY{ - ACT_CAT_QOS = 1, - ACT_CAT_DLS = 2, - ACT_CAT_BA = 3, - ACT_CAT_HT = 7, - ACT_CAT_WMM = 17, -} ACT_CATEGORY, *PACT_CATEGORY; - -typedef enum _TS_ACTION{ - ACT_ADDTSREQ = 0, - ACT_ADDTSRSP = 1, - ACT_DELTS = 2, - ACT_SCHEDULE = 3, -} TS_ACTION, *PTS_ACTION; - -typedef enum _BA_ACTION{ - ACT_ADDBAREQ = 0, - ACT_ADDBARSP = 1, - ACT_DELBA = 2, -} BA_ACTION, *PBA_ACTION; - -typedef enum _InitialGainOpType{ - IG_Backup=0, - IG_Restore, - IG_Max -}InitialGainOpType; - -/* debug macros */ -#define CONFIG_IEEE80211_DEBUG -#ifdef CONFIG_IEEE80211_DEBUG -extern u32 ieee80211_debug_level; -#define IEEE80211_DEBUG(level, fmt, args...) \ -do { if (ieee80211_debug_level & (level)) \ - printk(KERN_DEBUG "ieee80211: " fmt, ## args); } while (0) -//wb added to debug out data buf -//if you want print DATA buffer related BA, please set ieee80211_debug_level to DATA|BA -#define IEEE80211_DEBUG_DATA(level, data, datalen) \ - do{ if ((ieee80211_debug_level & (level)) == (level)) \ - { \ - int i; \ - u8* pdata = (u8*) data; \ - printk(KERN_DEBUG "ieee80211: %s()\n", __FUNCTION__); \ - for(i=0; i<(int)(datalen); i++) \ - { \ - printk("%2x ", pdata[i]); \ - if ((i+1)%16 == 0) printk("\n"); \ - } \ - printk("\n"); \ - } \ - } while (0) -#else -#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0) -#define IEEE80211_DEBUG_DATA(level, data, datalen) do {} while(0) -#endif /* CONFIG_IEEE80211_DEBUG */ - -/* debug macros not dependent on CONFIG_IEEE80211_DEBUG */ - -/* - * To use the debug system; - * - * If you are defining a new debug classification, simply add it to the #define - * list here in the form of: - * - * #define IEEE80211_DL_xxxx VALUE - * - * shifting value to the left one bit from the previous entry. xxxx should be - * the name of the classification (for example, WEP) - * - * You then need to either add a IEEE80211_xxxx_DEBUG() macro definition for your - * classification, or use IEEE80211_DEBUG(IEEE80211_DL_xxxx, ...) whenever you want - * to send output to that classification. - * - * To add your debug level to the list of levels seen when you perform - * - * % cat /proc/net/ipw/debug_level - * - * you simply need to add your entry to the ipw_debug_levels array. - * - * If you do not see debug_level in /proc/net/ipw then you do not have - * CONFIG_IEEE80211_DEBUG defined in your kernel configuration - * - */ - -#define IEEE80211_DL_INFO (1<<0) -#define IEEE80211_DL_WX (1<<1) -#define IEEE80211_DL_SCAN (1<<2) -#define IEEE80211_DL_STATE (1<<3) -#define IEEE80211_DL_MGMT (1<<4) -#define IEEE80211_DL_FRAG (1<<5) -#define IEEE80211_DL_EAP (1<<6) -#define IEEE80211_DL_DROP (1<<7) - -#define IEEE80211_DL_TX (1<<8) -#define IEEE80211_DL_RX (1<<9) - -#define IEEE80211_DL_HT (1<<10) //HT -#define IEEE80211_DL_BA (1<<11) //ba -#define IEEE80211_DL_TS (1<<12) //TS -#define IEEE80211_DL_QOS (1<<13) -#define IEEE80211_DL_REORDER (1<<14) -#define IEEE80211_DL_IOT (1<<15) -#define IEEE80211_DL_IPS (1<<16) -#define IEEE80211_DL_TRACE (1<<29) //trace function, need to user net_ratelimit() together in order not to print too much to the screen -#define IEEE80211_DL_DATA (1<<30) //use this flag to control whether print data buf out. -#define IEEE80211_DL_ERR (1<<31) //always open -#define IEEE80211_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a) -#define IEEE80211_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a) -#define IEEE80211_DEBUG_INFO(f, a...) IEEE80211_DEBUG(IEEE80211_DL_INFO, f, ## a) - -#define IEEE80211_DEBUG_WX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_WX, f, ## a) -#define IEEE80211_DEBUG_SCAN(f, a...) IEEE80211_DEBUG(IEEE80211_DL_SCAN, f, ## a) -#define IEEE80211_DEBUG_STATE(f, a...) IEEE80211_DEBUG(IEEE80211_DL_STATE, f, ## a) -#define IEEE80211_DEBUG_MGMT(f, a...) IEEE80211_DEBUG(IEEE80211_DL_MGMT, f, ## a) -#define IEEE80211_DEBUG_FRAG(f, a...) IEEE80211_DEBUG(IEEE80211_DL_FRAG, f, ## a) -#define IEEE80211_DEBUG_EAP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_EAP, f, ## a) -#define IEEE80211_DEBUG_DROP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_DROP, f, ## a) -#define IEEE80211_DEBUG_TX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_TX, f, ## a) -#define IEEE80211_DEBUG_RX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_RX, f, ## a) -#define IEEE80211_DEBUG_QOS(f, a...) IEEE80211_DEBUG(IEEE80211_DL_QOS, f, ## a) - -#ifdef CONFIG_IEEE80211_DEBUG -/* Added by Annie, 2005-11-22. */ -#define MAX_STR_LEN 64 -/* I want to see ASCII 33 to 126 only. Otherwise, I print '?'. Annie, 2005-11-22.*/ -#define PRINTABLE(_ch) (_ch>'!' && _ch<'~') -#define IEEE80211_PRINT_STR(_Comp, _TitleString, _Ptr, _Len) \ - if((_Comp) & level) \ - { \ - int __i; \ - u8 buffer[MAX_STR_LEN]; \ - int length = (_Len<MAX_STR_LEN)? _Len : (MAX_STR_LEN-1) ; \ - memset(buffer, 0, MAX_STR_LEN); \ - memcpy(buffer, (u8 *)_Ptr, length ); \ - for( __i=0; __i<MAX_STR_LEN; __i++ ) \ - { \ - if( !PRINTABLE(buffer[__i]) ) buffer[__i] = '?'; \ - } \ - buffer[length] = '\0'; \ - printk("Rtl819x: "); \ - printk(_TitleString); \ - printk(": %d, <%s>\n", _Len, buffer); \ - } -#else -#define IEEE80211_PRINT_STR(_Comp, _TitleString, _Ptr, _Len) do {} while (0) -#endif - -#include <linux/netdevice.h> -#include <linux/if_arp.h> /* ARPHRD_ETHER */ - -#ifndef WIRELESS_SPY -#define WIRELESS_SPY // enable iwspy support -#endif -#include <net/iw_handler.h> // new driver API - -#ifndef ETH_P_PAE -#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */ -#endif /* ETH_P_PAE */ - -#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */ - -#ifndef ETH_P_80211_RAW -#define ETH_P_80211_RAW (ETH_P_ECONET + 1) -#endif - -/* IEEE 802.11 defines */ - -#define P80211_OUI_LEN 3 - -struct ieee80211_snap_hdr { - - u8 dsap; /* always 0xAA */ - u8 ssap; /* always 0xAA */ - u8 ctrl; /* always 0x03 */ - u8 oui[P80211_OUI_LEN]; /* organizational universal id */ - -} __attribute__ ((packed)); - -#define SNAP_SIZE sizeof(struct ieee80211_snap_hdr) - -#define WLAN_FC_GET_VERS(fc) ((fc) & IEEE80211_FCTL_VERS) -#define WLAN_FC_GET_TYPE(fc) ((fc) & IEEE80211_FCTL_FTYPE) -#define WLAN_FC_GET_STYPE(fc) ((fc) & IEEE80211_FCTL_STYPE) -#define WLAN_FC_MORE_DATA(fc) ((fc) & IEEE80211_FCTL_MOREDATA) - - -#define WLAN_FC_GET_FRAMETYPE(fc) ((fc) & IEEE80211_FCTL_FRAMETYPE) -#define WLAN_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG) -#define WLAN_GET_SEQ_SEQ(seq) (((seq) & IEEE80211_SCTL_SEQ) >> 4) - -/* Authentication algorithms */ -#define WLAN_AUTH_OPEN 0 -#define WLAN_AUTH_SHARED_KEY 1 -#define WLAN_AUTH_LEAP 2 - -#define WLAN_AUTH_CHALLENGE_LEN 128 - -#define WLAN_CAPABILITY_BSS (1<<0) -#define WLAN_CAPABILITY_IBSS (1<<1) -#define WLAN_CAPABILITY_CF_POLLABLE (1<<2) -#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3) -#define WLAN_CAPABILITY_PRIVACY (1<<4) -#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5) -#define WLAN_CAPABILITY_PBCC (1<<6) -#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7) -#define WLAN_CAPABILITY_SPECTRUM_MGMT (1<<8) -#define WLAN_CAPABILITY_QOS (1<<9) -#define WLAN_CAPABILITY_SHORT_SLOT (1<<10) -#define WLAN_CAPABILITY_DSSS_OFDM (1<<13) - -/* 802.11g ERP information element */ -#define WLAN_ERP_NON_ERP_PRESENT (1<<0) -#define WLAN_ERP_USE_PROTECTION (1<<1) -#define WLAN_ERP_BARKER_PREAMBLE (1<<2) - -/* Status codes */ -enum ieee80211_statuscode { - WLAN_STATUS_SUCCESS = 0, - WLAN_STATUS_UNSPECIFIED_FAILURE = 1, - WLAN_STATUS_CAPS_UNSUPPORTED = 10, - WLAN_STATUS_REASSOC_NO_ASSOC = 11, - WLAN_STATUS_ASSOC_DENIED_UNSPEC = 12, - WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG = 13, - WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION = 14, - WLAN_STATUS_CHALLENGE_FAIL = 15, - WLAN_STATUS_AUTH_TIMEOUT = 16, - WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA = 17, - WLAN_STATUS_ASSOC_DENIED_RATES = 18, - /* 802.11b */ - WLAN_STATUS_ASSOC_DENIED_NOSHORTPREAMBLE = 19, - WLAN_STATUS_ASSOC_DENIED_NOPBCC = 20, - WLAN_STATUS_ASSOC_DENIED_NOAGILITY = 21, - /* 802.11h */ - WLAN_STATUS_ASSOC_DENIED_NOSPECTRUM = 22, - WLAN_STATUS_ASSOC_REJECTED_BAD_POWER = 23, - WLAN_STATUS_ASSOC_REJECTED_BAD_SUPP_CHAN = 24, - /* 802.11g */ - WLAN_STATUS_ASSOC_DENIED_NOSHORTTIME = 25, - WLAN_STATUS_ASSOC_DENIED_NODSSSOFDM = 26, - /* 802.11i */ - WLAN_STATUS_INVALID_IE = 40, - WLAN_STATUS_INVALID_GROUP_CIPHER = 41, - WLAN_STATUS_INVALID_PAIRWISE_CIPHER = 42, - WLAN_STATUS_INVALID_AKMP = 43, - WLAN_STATUS_UNSUPP_RSN_VERSION = 44, - WLAN_STATUS_INVALID_RSN_IE_CAP = 45, - WLAN_STATUS_CIPHER_SUITE_REJECTED = 46, -}; - -/* Reason codes */ -enum ieee80211_reasoncode { - WLAN_REASON_UNSPECIFIED = 1, - WLAN_REASON_PREV_AUTH_NOT_VALID = 2, - WLAN_REASON_DEAUTH_LEAVING = 3, - WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY = 4, - WLAN_REASON_DISASSOC_AP_BUSY = 5, - WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA = 6, - WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA = 7, - WLAN_REASON_DISASSOC_STA_HAS_LEFT = 8, - WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH = 9, - /* 802.11h */ - WLAN_REASON_DISASSOC_BAD_POWER = 10, - WLAN_REASON_DISASSOC_BAD_SUPP_CHAN = 11, - /* 802.11i */ - WLAN_REASON_INVALID_IE = 13, - WLAN_REASON_MIC_FAILURE = 14, - WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT = 15, - WLAN_REASON_GROUP_KEY_HANDSHAKE_TIMEOUT = 16, - WLAN_REASON_IE_DIFFERENT = 17, - WLAN_REASON_INVALID_GROUP_CIPHER = 18, - WLAN_REASON_INVALID_PAIRWISE_CIPHER = 19, - WLAN_REASON_INVALID_AKMP = 20, - WLAN_REASON_UNSUPP_RSN_VERSION = 21, - WLAN_REASON_INVALID_RSN_IE_CAP = 22, - WLAN_REASON_IEEE8021X_FAILED = 23, - WLAN_REASON_CIPHER_SUITE_REJECTED = 24, -}; - -#define IEEE80211_STATMASK_SIGNAL (1<<0) -#define IEEE80211_STATMASK_RSSI (1<<1) -#define IEEE80211_STATMASK_NOISE (1<<2) -#define IEEE80211_STATMASK_RATE (1<<3) -#define IEEE80211_STATMASK_WEMASK 0x7 - -#define IEEE80211_CCK_MODULATION (1<<0) -#define IEEE80211_OFDM_MODULATION (1<<1) - -#define IEEE80211_24GHZ_BAND (1<<0) -#define IEEE80211_52GHZ_BAND (1<<1) - -#define IEEE80211_CCK_RATE_LEN 4 -#define IEEE80211_CCK_RATE_1MB 0x02 -#define IEEE80211_CCK_RATE_2MB 0x04 -#define IEEE80211_CCK_RATE_5MB 0x0B -#define IEEE80211_CCK_RATE_11MB 0x16 -#define IEEE80211_OFDM_RATE_LEN 8 -#define IEEE80211_OFDM_RATE_6MB 0x0C -#define IEEE80211_OFDM_RATE_9MB 0x12 -#define IEEE80211_OFDM_RATE_12MB 0x18 -#define IEEE80211_OFDM_RATE_18MB 0x24 -#define IEEE80211_OFDM_RATE_24MB 0x30 -#define IEEE80211_OFDM_RATE_36MB 0x48 -#define IEEE80211_OFDM_RATE_48MB 0x60 -#define IEEE80211_OFDM_RATE_54MB 0x6C -#define IEEE80211_BASIC_RATE_MASK 0x80 - -#define IEEE80211_CCK_RATE_1MB_MASK (1<<0) -#define IEEE80211_CCK_RATE_2MB_MASK (1<<1) -#define IEEE80211_CCK_RATE_5MB_MASK (1<<2) -#define IEEE80211_CCK_RATE_11MB_MASK (1<<3) -#define IEEE80211_OFDM_RATE_6MB_MASK (1<<4) -#define IEEE80211_OFDM_RATE_9MB_MASK (1<<5) -#define IEEE80211_OFDM_RATE_12MB_MASK (1<<6) -#define IEEE80211_OFDM_RATE_18MB_MASK (1<<7) -#define IEEE80211_OFDM_RATE_24MB_MASK (1<<8) -#define IEEE80211_OFDM_RATE_36MB_MASK (1<<9) -#define IEEE80211_OFDM_RATE_48MB_MASK (1<<10) -#define IEEE80211_OFDM_RATE_54MB_MASK (1<<11) - -#define IEEE80211_CCK_RATES_MASK 0x0000000F -#define IEEE80211_CCK_BASIC_RATES_MASK (IEEE80211_CCK_RATE_1MB_MASK | \ - IEEE80211_CCK_RATE_2MB_MASK) -#define IEEE80211_CCK_DEFAULT_RATES_MASK (IEEE80211_CCK_BASIC_RATES_MASK | \ - IEEE80211_CCK_RATE_5MB_MASK | \ - IEEE80211_CCK_RATE_11MB_MASK) - -#define IEEE80211_OFDM_RATES_MASK 0x00000FF0 -#define IEEE80211_OFDM_BASIC_RATES_MASK (IEEE80211_OFDM_RATE_6MB_MASK | \ - IEEE80211_OFDM_RATE_12MB_MASK | \ - IEEE80211_OFDM_RATE_24MB_MASK) -#define IEEE80211_OFDM_DEFAULT_RATES_MASK (IEEE80211_OFDM_BASIC_RATES_MASK | \ - IEEE80211_OFDM_RATE_9MB_MASK | \ - IEEE80211_OFDM_RATE_18MB_MASK | \ - IEEE80211_OFDM_RATE_36MB_MASK | \ - IEEE80211_OFDM_RATE_48MB_MASK | \ - IEEE80211_OFDM_RATE_54MB_MASK) -#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \ - IEEE80211_CCK_DEFAULT_RATES_MASK) - -#define IEEE80211_NUM_OFDM_RATES 8 -#define IEEE80211_NUM_CCK_RATES 4 -#define IEEE80211_OFDM_SHIFT_MASK_A 4 - - -/* this is stolen and modified from the madwifi driver*/ -#define IEEE80211_FC0_TYPE_MASK 0x0c -#define IEEE80211_FC0_TYPE_DATA 0x08 -#define IEEE80211_FC0_SUBTYPE_MASK 0xB0 -#define IEEE80211_FC0_SUBTYPE_QOS 0x80 - -#define IEEE80211_QOS_HAS_SEQ(fc) \ - (((fc) & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == \ - (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS)) - -/* this is stolen from ipw2200 driver */ -#define IEEE_IBSS_MAC_HASH_SIZE 31 -struct ieee_ibss_seq { - u8 mac[ETH_ALEN]; - u16 seq_num[17]; - u16 frag_num[17]; - unsigned long packet_time[17]; - struct list_head list; -}; - -/* NOTE: This data is for statistical purposes; not all hardware provides this - * information for frames received. Not setting these will not cause - * any adverse affects. */ -struct ieee80211_rx_stats { - u32 mac_time[2]; - s8 rssi; - u8 signal; - u8 noise; - u16 rate; /* in 100 kbps */ - u8 received_channel; - u8 control; - u8 mask; - u8 freq; - u16 len; - u64 tsf; - u32 beacon_time; - u8 nic_type; - u16 Length; - u8 SignalQuality; // in 0-100 index. - s32 RecvSignalPower; // Real power in dBm for this packet, no beautification and aggregation. - s8 RxPower; // in dBm Translate from PWdB - u8 SignalStrength; // in 0-100 index. - u16 bHwError:1; - u16 bCRC:1; - u16 bICV:1; - u16 bShortPreamble:1; - u16 Antenna:1; //for rtl8185 - u16 Decrypted:1; //for rtl8185, rtl8187 - u16 Wakeup:1; //for rtl8185 - u16 Reserved0:1; //for rtl8185 - u8 AGC; - u32 TimeStampLow; - u32 TimeStampHigh; - bool bShift; - bool bIsQosData; // Added by Annie, 2005-12-22. - u8 UserPriority; - - //1!!!!!!!!!!!!!!!!!!!!!!!!!!! - //1Attention Please!!!<11n or 8190 specific code should be put below this line> - //1!!!!!!!!!!!!!!!!!!!!!!!!!!! - - u8 RxDrvInfoSize; - u8 RxBufShift; - bool bIsAMPDU; - bool bFirstMPDU; - bool bContainHTC; - u32 RxPWDBAll; - u8 RxMIMOSignalStrength[4]; // in 0~100 index - s8 RxMIMOSignalQuality[2]; - bool bPacketMatchBSSID; - bool bIsCCK; - bool bPacketToSelf; - u8* virtual_address; - bool bPacketBeacon; //cosa add for rssi - bool bToSelfBA; //cosa add for rssi - char cck_adc_pwdb[4]; //cosa add for rx path selection -}; - -/* IEEE 802.11 requires that STA supports concurrent reception of at least - * three fragmented frames. This define can be increased to support more - * concurrent frames, but it should be noted that each entry can consume about - * 2 kB of RAM and increasing cache size will slow down frame reassembly. */ -#define IEEE80211_FRAG_CACHE_LEN 4 - -struct ieee80211_frag_entry { - unsigned long first_frag_time; - unsigned int seq; - unsigned int last_frag; - struct sk_buff *skb; - u8 src_addr[ETH_ALEN]; - u8 dst_addr[ETH_ALEN]; -}; - -struct ieee80211_stats { - unsigned int tx_unicast_frames; - unsigned int tx_multicast_frames; - unsigned int tx_fragments; - unsigned int tx_unicast_octets; - unsigned int tx_multicast_octets; - unsigned int tx_deferred_transmissions; - unsigned int tx_single_retry_frames; - unsigned int tx_multiple_retry_frames; - unsigned int tx_retry_limit_exceeded; - unsigned int tx_discards; - unsigned int rx_unicast_frames; - unsigned int rx_multicast_frames; - unsigned int rx_fragments; - unsigned int rx_unicast_octets; - unsigned int rx_multicast_octets; - unsigned int rx_fcs_errors; - unsigned int rx_discards_no_buffer; - unsigned int tx_discards_wrong_sa; - unsigned int rx_discards_undecryptable; - unsigned int rx_message_in_msg_fragments; - unsigned int rx_message_in_bad_msg_fragments; -}; - -struct ieee80211_device; - -#include "ieee80211_crypt.h" - -#define SEC_KEY_1 (1<<0) -#define SEC_KEY_2 (1<<1) -#define SEC_KEY_3 (1<<2) -#define SEC_KEY_4 (1<<3) -#define SEC_ACTIVE_KEY (1<<4) -#define SEC_AUTH_MODE (1<<5) -#define SEC_UNICAST_GROUP (1<<6) -#define SEC_LEVEL (1<<7) -#define SEC_ENABLED (1<<8) -#define SEC_ENCRYPT (1<<9) - -#define SEC_LEVEL_0 0 /* None */ -#define SEC_LEVEL_1 1 /* WEP 40 and 104 bit */ -#define SEC_LEVEL_2 2 /* Level 1 + TKIP */ -#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */ -#define SEC_LEVEL_3 4 /* Level 2 + CCMP */ - -#define SEC_ALG_NONE 0 -#define SEC_ALG_WEP 1 -#define SEC_ALG_TKIP 2 -#define SEC_ALG_CCMP 4 - -#define WEP_KEYS 4 -#define WEP_KEY_LEN 13 -#define SCM_KEY_LEN 32 -#define SCM_TEMPORAL_KEY_LENGTH 16 - -struct ieee80211_security { - u16 active_key:2, - enabled:1, - auth_mode:2, - auth_algo:4, - unicast_uses_group:1, - encrypt:1; - u8 key_sizes[WEP_KEYS]; - u8 keys[WEP_KEYS][SCM_KEY_LEN]; - u8 level; - u16 flags; -} __attribute__ ((packed)); - - -/* - 802.11 data frame from AP - ,-------------------------------------------------------------------. -Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 | - |------|------|---------|---------|---------|------|---------|------| -Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | frame | fcs | - | | tion | (BSSID) | | | ence | data | | - `-------------------------------------------------------------------' -Total: 28-2340 bytes -*/ - -/* Management Frame Information Element Types */ -enum ieee80211_mfie { - MFIE_TYPE_SSID = 0, - MFIE_TYPE_RATES = 1, - MFIE_TYPE_FH_SET = 2, - MFIE_TYPE_DS_SET = 3, - MFIE_TYPE_CF_SET = 4, - MFIE_TYPE_TIM = 5, - MFIE_TYPE_IBSS_SET = 6, - MFIE_TYPE_COUNTRY = 7, - MFIE_TYPE_HOP_PARAMS = 8, - MFIE_TYPE_HOP_TABLE = 9, - MFIE_TYPE_REQUEST = 10, - MFIE_TYPE_CHALLENGE = 16, - MFIE_TYPE_POWER_CONSTRAINT = 32, - MFIE_TYPE_POWER_CAPABILITY = 33, - MFIE_TYPE_TPC_REQUEST = 34, - MFIE_TYPE_TPC_REPORT = 35, - MFIE_TYPE_SUPP_CHANNELS = 36, - MFIE_TYPE_CSA = 37, - MFIE_TYPE_MEASURE_REQUEST = 38, - MFIE_TYPE_MEASURE_REPORT = 39, - MFIE_TYPE_QUIET = 40, - MFIE_TYPE_IBSS_DFS = 41, - MFIE_TYPE_ERP = 42, - MFIE_TYPE_RSN = 48, - MFIE_TYPE_RATES_EX = 50, - MFIE_TYPE_HT_CAP= 45, - MFIE_TYPE_HT_INFO= 61, - MFIE_TYPE_AIRONET=133, - MFIE_TYPE_GENERIC = 221, - MFIE_TYPE_QOS_PARAMETER = 222, -}; - -/* Minimal header; can be used for passing 802.11 frames with sufficient - * information to determine what type of underlying data type is actually - * stored in the data. */ - struct ieee80211_pspoll_hdr { - __le16 frame_ctl; - __le16 aid; - u8 bssid[ETH_ALEN]; - u8 ta[ETH_ALEN]; - //u8 payload[0]; -} __attribute__ ((packed)); - -struct ieee80211_hdr { - __le16 frame_ctl; - __le16 duration_id; - u8 payload[0]; -} __attribute__ ((packed)); - -struct ieee80211_hdr_1addr { - __le16 frame_ctl; - __le16 duration_id; - u8 addr1[ETH_ALEN]; - u8 payload[0]; -} __attribute__ ((packed)); - -struct ieee80211_hdr_2addr { - __le16 frame_ctl; - __le16 duration_id; - u8 addr1[ETH_ALEN]; - u8 addr2[ETH_ALEN]; - u8 payload[0]; -} __attribute__ ((packed)); - -struct ieee80211_hdr_3addr { - __le16 frame_ctl; - __le16 duration_id; - u8 addr1[ETH_ALEN]; - u8 addr2[ETH_ALEN]; - u8 addr3[ETH_ALEN]; - __le16 seq_ctl; - u8 payload[0]; -} __attribute__ ((packed)); - -struct ieee80211_hdr_4addr { - __le16 frame_ctl; - __le16 duration_id; - u8 addr1[ETH_ALEN]; - u8 addr2[ETH_ALEN]; - u8 addr3[ETH_ALEN]; - __le16 seq_ctl; - u8 addr4[ETH_ALEN]; - u8 payload[0]; -} __attribute__ ((packed)); - -struct ieee80211_hdr_3addrqos { - __le16 frame_ctl; - __le16 duration_id; - u8 addr1[ETH_ALEN]; - u8 addr2[ETH_ALEN]; - u8 addr3[ETH_ALEN]; - __le16 seq_ctl; - u8 payload[0]; - __le16 qos_ctl; -} __attribute__ ((packed)); - -struct ieee80211_hdr_4addrqos { - __le16 frame_ctl; - __le16 duration_id; - u8 addr1[ETH_ALEN]; - u8 addr2[ETH_ALEN]; - u8 addr3[ETH_ALEN]; - __le16 seq_ctl; - u8 addr4[ETH_ALEN]; - u8 payload[0]; - __le16 qos_ctl; -} __attribute__ ((packed)); - -struct ieee80211_info_element { - u8 id; - u8 len; - u8 data[0]; -} __attribute__ ((packed)); - -struct ieee80211_authentication { - struct ieee80211_hdr_3addr header; - __le16 algorithm; - __le16 transaction; - __le16 status; - /*challenge*/ - struct ieee80211_info_element info_element[0]; -} __attribute__ ((packed)); - -struct ieee80211_disassoc { - struct ieee80211_hdr_3addr header; - __le16 reason; -} __attribute__ ((packed)); - -struct ieee80211_probe_request { - struct ieee80211_hdr_3addr header; - /* SSID, supported rates */ - struct ieee80211_info_element info_element[0]; -} __attribute__ ((packed)); - -struct ieee80211_probe_response { - struct ieee80211_hdr_3addr header; - u32 time_stamp[2]; - __le16 beacon_interval; - __le16 capability; - /* SSID, supported rates, FH params, DS params, - * CF params, IBSS params, TIM (if beacon), RSN */ - struct ieee80211_info_element info_element[0]; -} __attribute__ ((packed)); - -/* Alias beacon for probe_response */ -#define ieee80211_beacon ieee80211_probe_response - -struct ieee80211_assoc_request_frame { - struct ieee80211_hdr_3addr header; - __le16 capability; - __le16 listen_interval; - /* SSID, supported rates, RSN */ - struct ieee80211_info_element info_element[0]; -} __attribute__ ((packed)); - -struct ieee80211_reassoc_request_frame { - struct ieee80211_hdr_3addr header; - __le16 capability; - __le16 listen_interval; - u8 current_ap[ETH_ALEN]; - /* SSID, supported rates, RSN */ - struct ieee80211_info_element info_element[0]; -} __attribute__ ((packed)); - -struct ieee80211_assoc_response_frame { - struct ieee80211_hdr_3addr header; - __le16 capability; - __le16 status; - __le16 aid; - struct ieee80211_info_element info_element[0]; /* supported rates */ -} __attribute__ ((packed)); - -struct ieee80211_txb { - u8 nr_frags; - u8 encrypted; - u8 queue_index; - u8 rts_included; - u16 reserved; - __le16 frag_size; - __le16 payload_size; - struct sk_buff *fragments[0]; -}; - -#define MAX_TX_AGG_COUNT 16 -struct ieee80211_drv_agg_txb { - u8 nr_drv_agg_frames; - struct sk_buff *tx_agg_frames[MAX_TX_AGG_COUNT]; -}__attribute__((packed)); - -#define MAX_SUBFRAME_COUNT 64 -struct ieee80211_rxb { - u8 nr_subframes; - struct sk_buff *subframes[MAX_SUBFRAME_COUNT]; - u8 dst[ETH_ALEN]; - u8 src[ETH_ALEN]; -}__attribute__((packed)); - -typedef union _frameqos { - u16 shortdata; - u8 chardata[2]; - struct { - u16 tid:4; - u16 eosp:1; - u16 ack_policy:2; - u16 reserved:1; - u16 txop:8; - }field; -}frameqos,*pframeqos; - -/* SWEEP TABLE ENTRIES NUMBER*/ -#define MAX_SWEEP_TAB_ENTRIES 42 -#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET 7 -/* MAX_RATES_LENGTH needs to be 12. The spec says 8, and many APs - * only use 8, and then use extended rates for the remaining supported - * rates. Other APs, however, stick all of their supported rates on the - * main rates information element... */ -#define MAX_RATES_LENGTH ((u8)12) -#define MAX_RATES_EX_LENGTH ((u8)16) -#define MAX_NETWORK_COUNT 128 - -#define MAX_CHANNEL_NUMBER 161 -#define IEEE80211_SOFTMAC_SCAN_TIME 100 -//(HZ / 2) -#define IEEE80211_SOFTMAC_ASSOC_RETRY_TIME (HZ * 2) - -#define CRC_LENGTH 4U - -#define MAX_WPA_IE_LEN 64 - -#define NETWORK_EMPTY_ESSID (1<<0) -#define NETWORK_HAS_OFDM (1<<1) -#define NETWORK_HAS_CCK (1<<2) - -/* QoS structure */ -#define NETWORK_HAS_QOS_PARAMETERS (1<<3) -#define NETWORK_HAS_QOS_INFORMATION (1<<4) -#define NETWORK_HAS_QOS_MASK (NETWORK_HAS_QOS_PARAMETERS | \ - NETWORK_HAS_QOS_INFORMATION) -/* 802.11h */ -#define NETWORK_HAS_POWER_CONSTRAINT (1<<5) -#define NETWORK_HAS_CSA (1<<6) -#define NETWORK_HAS_QUIET (1<<7) -#define NETWORK_HAS_IBSS_DFS (1<<8) -#define NETWORK_HAS_TPC_REPORT (1<<9) - -#define NETWORK_HAS_ERP_VALUE (1<<10) - -#define QOS_QUEUE_NUM 4 -#define QOS_OUI_LEN 3 -#define QOS_OUI_TYPE 2 -#define QOS_ELEMENT_ID 221 -#define QOS_OUI_INFO_SUB_TYPE 0 -#define QOS_OUI_PARAM_SUB_TYPE 1 -#define QOS_VERSION_1 1 -#define QOS_AIFSN_MIN_VALUE 2 - -struct ieee80211_qos_information_element { - u8 elementID; - u8 length; - u8 qui[QOS_OUI_LEN]; - u8 qui_type; - u8 qui_subtype; - u8 version; - u8 ac_info; -} __attribute__ ((packed)); - -struct ieee80211_qos_ac_parameter { - u8 aci_aifsn; - u8 ecw_min_max; - __le16 tx_op_limit; -} __attribute__ ((packed)); - -struct ieee80211_qos_parameter_info { - struct ieee80211_qos_information_element info_element; - u8 reserved; - struct ieee80211_qos_ac_parameter ac_params_record[QOS_QUEUE_NUM]; -} __attribute__ ((packed)); - -struct ieee80211_qos_parameters { - __le16 cw_min[QOS_QUEUE_NUM]; - __le16 cw_max[QOS_QUEUE_NUM]; - u8 aifs[QOS_QUEUE_NUM]; - u8 flag[QOS_QUEUE_NUM]; - __le16 tx_op_limit[QOS_QUEUE_NUM]; -} __attribute__ ((packed)); - -struct ieee80211_qos_data { - struct ieee80211_qos_parameters parameters; - int active; - int supported; - u8 param_count; - u8 old_param_count; -}; - -struct ieee80211_tim_parameters { - u8 tim_count; - u8 tim_period; -} __attribute__ ((packed)); - -//#else -struct ieee80211_wmm_ac_param { - u8 ac_aci_acm_aifsn; - u8 ac_ecwmin_ecwmax; - u16 ac_txop_limit; -}; - -struct ieee80211_wmm_ts_info { - u8 ac_dir_tid; - u8 ac_up_psb; - u8 reserved; -} __attribute__ ((packed)); - -struct ieee80211_wmm_tspec_elem { - struct ieee80211_wmm_ts_info ts_info; - u16 norm_msdu_size; - u16 max_msdu_size; - u32 min_serv_inter; - u32 max_serv_inter; - u32 inact_inter; - u32 suspen_inter; - u32 serv_start_time; - u32 min_data_rate; - u32 mean_data_rate; - u32 peak_data_rate; - u32 max_burst_size; - u32 delay_bound; - u32 min_phy_rate; - u16 surp_band_allow; - u16 medium_time; -}__attribute__((packed)); - -enum eap_type { - EAP_PACKET = 0, - EAPOL_START, - EAPOL_LOGOFF, - EAPOL_KEY, - EAPOL_ENCAP_ASF_ALERT -}; - -static const char *eap_types[] = { - [EAP_PACKET] = "EAP-Packet", - [EAPOL_START] = "EAPOL-Start", - [EAPOL_LOGOFF] = "EAPOL-Logoff", - [EAPOL_KEY] = "EAPOL-Key", - [EAPOL_ENCAP_ASF_ALERT] = "EAPOL-Encap-ASF-Alert" -}; - -static inline const char *eap_get_type(int type) -{ - return ((u32)type >= ARRAY_SIZE(eap_types)) ? "Unknown" : eap_types[type]; -} -//added by amy for reorder -static inline u8 Frame_QoSTID(u8* buf) -{ - struct ieee80211_hdr_3addr *hdr; - u16 fc; - hdr = (struct ieee80211_hdr_3addr *)buf; - fc = le16_to_cpu(hdr->frame_ctl); - return (u8)((frameqos*)(buf + (((fc & IEEE80211_FCTL_TODS)&&(fc & IEEE80211_FCTL_FROMDS))? 30 : 24)))->field.tid; -} - -//added by amy for reorder - -struct eapol { - u8 snap[6]; - u16 ethertype; - u8 version; - u8 type; - u16 length; -} __attribute__ ((packed)); - -struct ieee80211_softmac_stats{ - unsigned int rx_ass_ok; - unsigned int rx_ass_err; - unsigned int rx_probe_rq; - unsigned int tx_probe_rs; - unsigned int tx_beacons; - unsigned int rx_auth_rq; - unsigned int rx_auth_rs_ok; - unsigned int rx_auth_rs_err; - unsigned int tx_auth_rq; - unsigned int no_auth_rs; - unsigned int no_ass_rs; - unsigned int tx_ass_rq; - unsigned int rx_ass_rq; - unsigned int tx_probe_rq; - unsigned int reassoc; - unsigned int swtxstop; - unsigned int swtxawake; - unsigned char CurrentShowTxate; - unsigned char last_packet_rate; - unsigned int txretrycount; -}; - -#define BEACON_PROBE_SSID_ID_POSITION 12 - -struct ieee80211_info_element_hdr { - u8 id; - u8 len; -} __attribute__ ((packed)); - -/* - * These are the data types that can make up management packets - * - u16 auth_algorithm; - u16 auth_sequence; - u16 beacon_interval; - u16 capability; - u8 current_ap[ETH_ALEN]; - u16 listen_interval; - struct { - u16 association_id:14, reserved:2; - } __attribute__ ((packed)); - u32 time_stamp[2]; - u16 reason; - u16 status; -*/ - -#define IEEE80211_DEFAULT_TX_ESSID "Penguin" -#define IEEE80211_DEFAULT_BASIC_RATE 2 //1Mbps - -enum {WMM_all_frame, WMM_two_frame, WMM_four_frame, WMM_six_frame}; -#define MAX_SP_Len (WMM_all_frame << 4) -#define IEEE80211_QOS_TID 0x0f -#define QOS_CTL_NOTCONTAIN_ACK (0x01 << 5) - -#define IEEE80211_DTIM_MBCAST 4 -#define IEEE80211_DTIM_UCAST 2 -#define IEEE80211_DTIM_VALID 1 -#define IEEE80211_DTIM_INVALID 0 - -#define IEEE80211_PS_DISABLED 0 -#define IEEE80211_PS_UNICAST IEEE80211_DTIM_UCAST -#define IEEE80211_PS_MBCAST IEEE80211_DTIM_MBCAST - -//added by David for QoS 2006/6/30 -//#define WMM_Hang_8187 -#ifdef WMM_Hang_8187 -#undef WMM_Hang_8187 -#endif - -#define WME_AC_BK 0x00 -#define WME_AC_BE 0x01 -#define WME_AC_VI 0x02 -#define WME_AC_VO 0x03 -#define WME_ACI_MASK 0x03 -#define WME_AIFSN_MASK 0x03 -#define WME_AC_PRAM_LEN 16 - -#define MAX_RECEIVE_BUFFER_SIZE 9100 - -//UP Mapping to AC, using in MgntQuery_SequenceNumber() and maybe for DSCP -#define UP2AC(up) ( \ - ((up) < 1) ? WME_AC_BE : \ - ((up) < 3) ? WME_AC_BK : \ - ((up) < 4) ? WME_AC_BE : \ - ((up) < 6) ? WME_AC_VI : \ - WME_AC_VO) - -//AC Mapping to UP, using in Tx part for selecting the corresponding TX queue -#define AC2UP(_ac) ( \ - ((_ac) == WME_AC_VO) ? 6 : \ - ((_ac) == WME_AC_VI) ? 5 : \ - ((_ac) == WME_AC_BK) ? 1 : \ - 0) - -#define ETHER_ADDR_LEN 6 /* length of an Ethernet address */ -#define ETHERNET_HEADER_SIZE 14 /* length of two Ethernet address plus ether type*/ - -struct ether_header { - u8 ether_dhost[ETHER_ADDR_LEN]; - u8 ether_shost[ETHER_ADDR_LEN]; - u16 ether_type; -} __attribute__((packed)); - -#ifndef ETHERTYPE_PAE -#define ETHERTYPE_PAE 0x888e /* EAPOL PAE/802.1x */ -#endif -#ifndef ETHERTYPE_IP -#define ETHERTYPE_IP 0x0800 /* IP protocol */ -#endif - -typedef struct _bss_ht{ - - bool support_ht; - - // HT related elements - u8 ht_cap_buf[32]; - u16 ht_cap_len; - u8 ht_info_buf[32]; - u16 ht_info_len; - - HT_SPEC_VER ht_spec_ver; - - bool aggregation; - bool long_slot_time; -}bss_ht, *pbss_ht; - -typedef enum _erp_t{ - ERP_NonERPpresent = 0x01, - ERP_UseProtection = 0x02, - ERP_BarkerPreambleMode = 0x04, -} erp_t; - - -struct ieee80211_network { - /* These entries are used to identify a unique network */ - u8 bssid[ETH_ALEN]; - u8 channel; - /* Ensure null-terminated for any debug msgs */ - u8 ssid[IW_ESSID_MAX_SIZE + 1]; - u8 ssid_len; - struct ieee80211_qos_data qos_data; - - //added by amy for LEAP - bool bWithAironetIE; - bool bCkipSupported; - bool bCcxRmEnable; - u16 CcxRmState[2]; - // CCXv4 S59, MBSSID. - bool bMBssidValid; - u8 MBssidMask; - u8 MBssid[6]; - // CCX 2 S38, WLAN Device Version Number element. Annie, 2006-08-20. - bool bWithCcxVerNum; - u8 BssCcxVerNumber; - /* These are network statistics */ - struct ieee80211_rx_stats stats; - u16 capability; - u8 rates[MAX_RATES_LENGTH]; - u8 rates_len; - u8 rates_ex[MAX_RATES_EX_LENGTH]; - u8 rates_ex_len; - unsigned long last_scanned; - u8 mode; - u32 flags; - u32 last_associate; - u32 time_stamp[2]; - u16 beacon_interval; - u16 listen_interval; - u16 atim_window; - u8 erp_value; - u8 wpa_ie[MAX_WPA_IE_LEN]; - size_t wpa_ie_len; - u8 rsn_ie[MAX_WPA_IE_LEN]; - size_t rsn_ie_len; - - struct ieee80211_tim_parameters tim; - u8 dtim_period; - u8 dtim_data; - u32 last_dtim_sta_time[2]; - - //appeded for QoS - u8 wmm_info; - struct ieee80211_wmm_ac_param wmm_param[4]; - u8 QoS_Enable; -#ifdef THOMAS_TURBO - u8 Turbo_Enable;//enable turbo mode, added by thomas -#endif -#ifdef ENABLE_DOT11D - u16 CountryIeLen; - u8 CountryIeBuf[MAX_IE_LEN]; -#endif - // HT Related, by amy, 2008.04.29 - BSS_HT bssht; - // Add to handle broadcom AP management frame CCK rate. - bool broadcom_cap_exist; - bool ralink_cap_exist; - bool atheros_cap_exist; - bool cisco_cap_exist; - bool marvell_cap_exist; - bool unknown_cap_exist; -// u8 berp_info; - bool berp_info_valid; - bool buseprotection; - //put at the end of the structure. - struct list_head list; -}; - -enum ieee80211_state { - - /* the card is not linked at all */ - IEEE80211_NOLINK = 0, - - /* IEEE80211_ASSOCIATING* are for BSS client mode - * the driver shall not perform RX filtering unless - * the state is LINKED. - * The driver shall just check for the state LINKED and - * defaults to NOLINK for ALL the other states (including - * LINKED_SCANNING) - */ - - /* the association procedure will start (wq scheduling)*/ - IEEE80211_ASSOCIATING, - IEEE80211_ASSOCIATING_RETRY, - - /* the association procedure is sending AUTH request*/ - IEEE80211_ASSOCIATING_AUTHENTICATING, - - /* the association procedure has successfully authentcated - * and is sending association request - */ - IEEE80211_ASSOCIATING_AUTHENTICATED, - - /* the link is ok. the card associated to a BSS or linked - * to a ibss cell or acting as an AP and creating the bss - */ - IEEE80211_LINKED, - - /* same as LINKED, but the driver shall apply RX filter - * rules as we are in NO_LINK mode. As the card is still - * logically linked, but it is doing a syncro site survey - * then it will be back to LINKED state. - */ - IEEE80211_LINKED_SCANNING, - -}; - -#define DEFAULT_MAX_SCAN_AGE (15 * HZ) -#define DEFAULT_FTS 2346 - -#define CFG_IEEE80211_RESERVE_FCS (1<<0) -#define CFG_IEEE80211_COMPUTE_FCS (1<<1) -#define CFG_IEEE80211_RTS (1<<2) - -#define IEEE80211_24GHZ_MIN_CHANNEL 1 -#define IEEE80211_24GHZ_MAX_CHANNEL 14 -#define IEEE80211_24GHZ_CHANNELS (IEEE80211_24GHZ_MAX_CHANNEL - \ - IEEE80211_24GHZ_MIN_CHANNEL + 1) - -#define IEEE80211_52GHZ_MIN_CHANNEL 34 -#define IEEE80211_52GHZ_MAX_CHANNEL 165 -#define IEEE80211_52GHZ_CHANNELS (IEEE80211_52GHZ_MAX_CHANNEL - \ - IEEE80211_52GHZ_MIN_CHANNEL + 1) - -typedef struct tx_pending_t{ - int frag; - struct ieee80211_txb *txb; -}tx_pending_t; - -typedef struct _bandwidth_autoswitch -{ - long threshold_20Mhzto40Mhz; - long threshold_40Mhzto20Mhz; - bool bforced_tx20Mhz; - bool bautoswitch_enable; -}bandwidth_autoswitch,*pbandwidth_autoswitch; - - -//added by amy for order - -#define REORDER_WIN_SIZE 128 -#define REORDER_ENTRY_NUM 128 -typedef struct _RX_REORDER_ENTRY -{ - struct list_head List; - u16 SeqNum; - struct ieee80211_rxb* prxb; -} RX_REORDER_ENTRY, *PRX_REORDER_ENTRY; -//added by amy for order -typedef enum _Fsync_State{ - Default_Fsync, - HW_Fsync, - SW_Fsync -}Fsync_State; - -typedef struct _IbssParms{ - u16 atimWin; -}IbssParms, *PIbssParms; -#define MAX_NUM_RATES 264 // Max num of support rates element: 8, Max num of ext. support rate: 255. 061122, by rcnjko. - -#ifdef ENABLE_DOT11D -typedef enum -{ - COUNTRY_CODE_FCC = 0, - COUNTRY_CODE_IC = 1, - COUNTRY_CODE_ETSI = 2, - COUNTRY_CODE_SPAIN = 3, - COUNTRY_CODE_FRANCE = 4, - COUNTRY_CODE_MKK = 5, - COUNTRY_CODE_MKK1 = 6, - COUNTRY_CODE_ISRAEL = 7, - COUNTRY_CODE_TELEC, - COUNTRY_CODE_MIC, - COUNTRY_CODE_GLOBAL_DOMAIN -}country_code_type_t; -#endif - -#define RT_MAX_LD_SLOT_NUM 10 -typedef struct _RT_LINK_DETECT_T{ - - u32 NumRecvBcnInPeriod; - u32 NumRecvDataInPeriod; - - u32 RxBcnNum[RT_MAX_LD_SLOT_NUM]; // number of Rx beacon / CheckForHang_period to determine link status - u32 RxDataNum[RT_MAX_LD_SLOT_NUM]; // number of Rx data / CheckForHang_period to determine link status - u16 SlotNum; // number of CheckForHang period to determine link status - u16 SlotIndex; - - u32 NumTxOkInPeriod; - u32 NumRxOkInPeriod; - u32 NumRxUnicastOkInPeriod; - bool bBusyTraffic; -}RT_LINK_DETECT_T, *PRT_LINK_DETECT_T; - -//added by amy 090330 -typedef enum _HW_VARIABLES{ - HW_VAR_ETHER_ADDR, - HW_VAR_MULTICAST_REG, - HW_VAR_BASIC_RATE, - HW_VAR_BSSID, - HW_VAR_MEDIA_STATUS, - HW_VAR_SECURITY_CONF, - HW_VAR_BEACON_INTERVAL, - HW_VAR_ATIM_WINDOW, - HW_VAR_LISTEN_INTERVAL, - HW_VAR_CS_COUNTER, - HW_VAR_DEFAULTKEY0, - HW_VAR_DEFAULTKEY1, - HW_VAR_DEFAULTKEY2, - HW_VAR_DEFAULTKEY3, - HW_VAR_SIFS, - HW_VAR_DIFS, - HW_VAR_EIFS, - HW_VAR_SLOT_TIME, - HW_VAR_ACK_PREAMBLE, - HW_VAR_CW_CONFIG, - HW_VAR_CW_VALUES, - HW_VAR_RATE_FALLBACK_CONTROL, - HW_VAR_CONTENTION_WINDOW, - HW_VAR_RETRY_COUNT, - HW_VAR_TR_SWITCH, - HW_VAR_COMMAND, // For Command Register, Annie, 2006-04-07. - HW_VAR_WPA_CONFIG, //2004/08/23, kcwu, for 8187 Security config - HW_VAR_AMPDU_MIN_SPACE, // The spacing between sub-frame. Roger, 2008.07.04. - HW_VAR_SHORTGI_DENSITY, // The density for shortGI. Roger, 2008.07.04. - HW_VAR_AMPDU_FACTOR, - HW_VAR_MCS_RATE_AVAILABLE, - HW_VAR_AC_PARAM, // For AC Parameters, 2005.12.01, by rcnjko. - HW_VAR_ACM_CTRL, // For ACM Control, Annie, 2005-12-13. - HW_VAR_DIS_Req_Qsize, // For DIS_Reg_Qsize, Joseph - HW_VAR_CCX_CHNL_LOAD, // For CCX 2 channel load request, 2006.05.04. - HW_VAR_CCX_NOISE_HISTOGRAM, // For CCX 2 noise histogram request, 2006.05.04. - HW_VAR_CCX_CLM_NHM, // For CCX 2 parallel channel load request and noise histogram request, 2006.05.12. - HW_VAR_TxOPLimit, // For turbo mode related settings, added by Roger, 2006.12.07 - HW_VAR_TURBO_MODE, // For turbo mode related settings, added by Roger, 2006.12.15. - HW_VAR_RF_STATE, // For change or query RF power state, 061214, rcnjko. - HW_VAR_RF_OFF_BY_HW, // For UI to query if external HW signal disable RF, 061229, rcnjko. - HW_VAR_BUS_SPEED, // In unit of bps. 2006.07.03, by rcnjko. - HW_VAR_SET_DEV_POWER, // Set to low power, added by LanHsin, 2007. - - //1!!!!!!!!!!!!!!!!!!!!!!!!!!! - //1Attention Please!!!<11n or 8190 specific code should be put below this line> - //1!!!!!!!!!!!!!!!!!!!!!!!!!!! - HW_VAR_RCR, //for RCR, David 2006,05,11 - HW_VAR_RATR_0, - HW_VAR_RRSR, - HW_VAR_CPU_RST, - HW_VAR_CHECK_BSSID, - HW_VAR_LBK_MODE, // Set lookback mode, 2008.06.11. added by Roger. - // Set HW related setting for 11N AES bug. - HW_VAR_AES_11N_FIX, - // Set Usb Rx Aggregation - HW_VAR_USB_RX_AGGR, - HW_VAR_USER_CONTROL_TURBO_MODE, - HW_VAR_RETRY_LIMIT, -#ifndef _RTL8192_EXT_PATCH_ - HW_VAR_INIT_TX_RATE, //Get Current Tx rate register. 2008.12.10. Added by tynli -#endif - HW_VAR_TX_RATE_REG, //Get Current Tx rate register. 2008.12.10. Added by tynli - HW_VAR_EFUSE_USAGE, //Get current EFUSE utilization. 2008.12.19. Added by Roger. - HW_VAR_EFUSE_BYTES, - HW_VAR_AUTOLOAD_STATUS, //Get current autoload status, 0: autoload success, 1: autoload fail. 2008.12.19. Added by Roger. - HW_VAR_RF_2R_DISABLE, // 2R disable - HW_VAR_SET_RPWM, - HW_VAR_H2C_FW_PWRMODE, // For setting FW related H2C cmd structure. by tynli. 2009.2.18 - HW_VAR_H2C_FW_JOINBSSRPT, // For setting FW related H2C cmd structure. by tynli. 2009.2.18 - HW_VAR_1X1_RECV_COMBINE, // For 1T2R but only 1SS, Add by hpfan 2009.04.16 hpfan - HW_VAR_STOP_SEND_BEACON, - HW_VAR_TSF_TIMER, // Read from TSF register to get the current TSF timer, by Bruce, 2009-07-22. - HW_VAR_IO_CMD, - HW_VAR_HANDLE_FW_C2H, //Added by tynli. For handling FW C2H command. 2009.10.07. - HW_VAR_DL_FW_RSVD_PAGE, //Added by tynli. Download the packets that FW will use to RSVD page. 2009.10.14. - HW_VAR_AID, //Added by tynli. - HW_VAR_HW_SEQ_ENABLE, //Added by tynli. 2009.10.20. - HW_VAR_UPDATE_TSF, //Added by tynli. 2009.10.22. For Hw count TBTT time. - HW_VAR_BCN_VALID, //Added by tynli. - HW_VAR_FWLPS_RF_ON //Added by tynli. 2009.11.09. For checking if Fw finishs RF on sequence. -}HW_VARIABLES; - -#define RT_CHECK_FOR_HANG_PERIOD 2 - -struct ieee80211_device { - struct net_device *dev; - struct ieee80211_security sec; - - bool need_sw_enc; -#ifdef ENABLE_LPS - bool bAwakePktSent; - u8 LPSDelayCnt; - bool bIsAggregateFrame; - bool polling; - void (*LeisurePSLeave)(struct ieee80211_device *ieee); -#endif - -#ifdef ENABLE_IPS - bool proto_stoppping; - bool wx_set_enc; - struct semaphore ips_sem; - struct work_struct ips_leave_wq; - void (*ieee80211_ips_leave_wq) (struct ieee80211_device *ieee); - void (*ieee80211_ips_leave)(struct ieee80211_device *ieee); -#endif - void (*SetHwRegHandler)(struct ieee80211_device *ieee, u8 variable, u8 *val); - u8 (*rtllib_ap_sec_type)(struct ieee80211_device *ieee); - - //hw security related - u8 hwsec_active; //hw security active. - bool is_silent_reset; - bool is_roaming; - bool ieee_up; - bool bSupportRemoteWakeUp; - bool actscanning; - bool beinretry; - bool is_set_key; - //11n spec related I wonder if These info structure need to be moved out of ieee80211_device - - //11n HT below - PRT_HIGH_THROUGHPUT pHTInfo; - spinlock_t bw_spinlock; - - spinlock_t reorder_spinlock; - // for HT operation rate set. we use this one for HT data rate to separate different descriptors - //the way fill this is the same as in the IE - u8 Regdot11HTOperationalRateSet[16]; //use RATR format - u8 dot11HTOperationalRateSet[16]; //use RATR format - u8 RegHTSuppRateSet[16]; - u8 HTCurrentOperaRate; - u8 HTHighestOperaRate; - //wb added for rate operation mode to firmware - u8 bTxDisableRateFallBack; - u8 bTxUseDriverAssingedRate; - atomic_t atm_chnlop; - atomic_t atm_swbw; - - // 802.11e and WMM Traffic Stream Info (TX) - struct list_head Tx_TS_Admit_List; - struct list_head Tx_TS_Pending_List; - struct list_head Tx_TS_Unused_List; - TX_TS_RECORD TxTsRecord[TOTAL_TS_NUM]; - // 802.11e and WMM Traffic Stream Info (RX) - struct list_head Rx_TS_Admit_List; - struct list_head Rx_TS_Pending_List; - struct list_head Rx_TS_Unused_List; - RX_TS_RECORD RxTsRecord[TOTAL_TS_NUM]; - RX_REORDER_ENTRY RxReorderEntry[128]; - struct list_head RxReorder_Unused_List; - u8 ForcedPriority; // Force per-packet priority 1~7. (default: 0, not to force it.) - - - /* Bookkeeping structures */ - struct net_device_stats stats; - struct ieee80211_stats ieee_stats; - struct ieee80211_softmac_stats softmac_stats; - - /* Probe / Beacon management */ - struct list_head network_free_list; - struct list_head network_list; - struct ieee80211_network *networks; - int scans; - int scan_age; - - int iw_mode; /* operating mode (IW_MODE_*) */ - struct iw_spy_data spy_data; - - spinlock_t lock; - spinlock_t wpax_suitlist_lock; - - int tx_headroom; /* Set to size of any additional room needed at front - * of allocated Tx SKBs */ - u32 config; - - /* WEP and other encryption related settings at the device level */ - int open_wep; /* Set to 1 to allow unencrypted frames */ - int auth_mode; - int reset_on_keychange; /* Set to 1 if the HW needs to be reset on - * WEP key changes */ - - /* If the host performs {en,de}cryption, then set to 1 */ - int host_encrypt; - int host_encrypt_msdu; - int host_decrypt; - /* host performs multicast decryption */ - int host_mc_decrypt; - - /* host should strip IV and ICV from protected frames */ - /* meaningful only when hardware decryption is being used */ - int host_strip_iv_icv; - - int host_open_frag; - int host_build_iv; - int ieee802_1x; /* is IEEE 802.1X used */ - - /* WPA data */ - bool bHalfWirelessN24GMode; - int wpa_enabled; - int drop_unencrypted; - int tkip_countermeasures; - int privacy_invoked; - size_t wpa_ie_len; - u8 *wpa_ie; - u8 ap_mac_addr[6]; - u16 pairwise_key_type; - u16 group_key_type; - struct list_head crypt_deinit_list; - struct ieee80211_crypt_data *crypt[WEP_KEYS]; - int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */ - struct timer_list crypt_deinit_timer; - int crypt_quiesced; - - int bcrx_sta_key; /* use individual keys to override default keys even - * with RX of broad/multicast frames */ - - /* Fragmentation structures */ - // each streaming contain a entry - struct ieee80211_frag_entry frag_cache[17][IEEE80211_FRAG_CACHE_LEN]; - unsigned int frag_next_idx[17]; - u16 fts; /* Fragmentation Threshold */ -#define DEFAULT_RTS_THRESHOLD 2346U -#define MIN_RTS_THRESHOLD 1 -#define MAX_RTS_THRESHOLD 2346U - u16 rts; /* RTS threshold */ - - /* Association info */ - u8 bssid[ETH_ALEN]; - - /* This stores infos for the current network. - * Either the network we are associated in INFRASTRUCTURE - * or the network that we are creating in MASTER mode. - * ad-hoc is a mixture ;-). - * Note that in infrastructure mode, even when not associated, - * fields bssid and essid may be valid (if wpa_set and essid_set - * are true) as thy carry the value set by the user via iwconfig - */ - struct ieee80211_network current_network; - - enum ieee80211_state state; - - int short_slot; - int reg_mode; - int mode; /* A, B, G */ - int modulation; /* CCK, OFDM */ - int freq_band; /* 2.4Ghz, 5.2Ghz, Mixed */ - int abg_true; /* ABG flag */ - - /* used for forcing the ibss workqueue to terminate - * without wait for the syncro scan to terminate - */ - short sync_scan_hurryup; - - int perfect_rssi; - int worst_rssi; - - u16 prev_seq_ctl; /* used to drop duplicate frames */ - - /* map of allowed channels. 0 is dummy */ - // FIXME: remember to default to a basic channel plan depending of the PHY type -#ifdef ENABLE_DOT11D - void* pDot11dInfo; - bool bGlobalDomain; -#else - int channel_map[MAX_CHANNEL_NUMBER+1]; -#endif - int rate; /* current rate */ - int basic_rate; - //FIXME: pleace callback, see if redundant with softmac_features - short active_scan; - - /* this contains flags for selectively enable softmac support */ - u16 softmac_features; - - /* if the sequence control field is not filled by HW */ - u16 seq_ctrl[5]; - - /* association procedure transaction sequence number */ - u16 associate_seq; - - /* AID for RTXed association responses */ - u16 assoc_id; - - /* power save mode related*/ - u8 ack_tx_to_ieee; - short ps; - short sta_sleep; - int ps_timeout; - int ps_period; - struct tasklet_struct ps_task; - u32 ps_th; - u32 ps_tl; - - short raw_tx; - /* used if IEEE_SOFTMAC_TX_QUEUE is set */ - short queue_stop; - short scanning; - short proto_started; - - struct semaphore wx_sem; - struct semaphore scan_sem; - - spinlock_t mgmt_tx_lock; - spinlock_t beacon_lock; - - short beacon_txing; - - short wap_set; - short ssid_set; - - u8 wpax_type_set; //{added by David, 2006.9.28} - u32 wpax_type_notify; //{added by David, 2006.9.26} - - /* QoS related flag */ - char init_wmmparam_flag; - /* set on initialization */ - u8 qos_support; - - /* for discarding duplicated packets in IBSS */ - struct list_head ibss_mac_hash[IEEE_IBSS_MAC_HASH_SIZE]; - - /* for discarding duplicated packets in BSS */ - u16 last_rxseq_num[17]; /* rx seq previous per-tid */ - u16 last_rxfrag_num[17];/* tx frag previous per-tid */ - unsigned long last_packet_time[17]; - - /* for PS mode */ - unsigned long last_rx_ps_time; - u8 LPSAwakeIntvl; - u8 RegMaxLPSAwakeIntvl; - - /* used if IEEE_SOFTMAC_SINGLE_QUEUE is set */ - struct sk_buff *mgmt_queue_ring[MGMT_QUEUE_NUM]; - int mgmt_queue_head; - int mgmt_queue_tail; -#define IEEE80211_QUEUE_LIMIT 128 - u8 AsocRetryCount; - unsigned int hw_header; - struct sk_buff_head skb_waitQ[MAX_QUEUE_SIZE]; - struct sk_buff_head skb_aggQ[MAX_QUEUE_SIZE]; - struct sk_buff_head skb_drv_aggQ[MAX_QUEUE_SIZE]; - u32 sta_edca_param[4]; - bool aggregation; - // Enable/Disable Rx immediate BA capability. - bool enable_rx_imm_BA; - bool bibsscoordinator; - - //+by amy for DM ,080515 - //Dynamic Tx power for near/far range enable/Disable , by amy , 2008-05-15 - bool bdynamic_txpower_enable; - - bool bCTSToSelfEnable; - u8 CTSToSelfTH; - - u32 fsync_time_interval; - u32 fsync_rate_bitmap; - u8 fsync_rssi_threshold; - bool bfsync_enable; - - u8 fsync_multiple_timeinterval; // FsyncMultipleTimeInterval * FsyncTimeInterval - u32 fsync_firstdiff_ratethreshold; // low threshold - u32 fsync_seconddiff_ratethreshold; // decrease threshold - Fsync_State fsync_state; - bool bis_any_nonbepkts; - //20Mhz 40Mhz AutoSwitch Threshold - bandwidth_autoswitch bandwidth_auto_switch; - //for txpower tracking - bool FwRWRF; - - //added by amy for AP roaming - RT_LINK_DETECT_T LinkDetectInfo; - - /* used if IEEE_SOFTMAC_TX_QUEUE is set */ - struct tx_pending_t tx_pending; - - /* used if IEEE_SOFTMAC_ASSOCIATE is set */ - struct timer_list associate_timer; - - /* used if IEEE_SOFTMAC_BEACONS is set */ - struct timer_list beacon_timer; - struct work_struct associate_complete_wq; - struct work_struct associate_procedure_wq; - struct delayed_work softmac_scan_wq; - struct delayed_work associate_retry_wq; - struct delayed_work start_ibss_wq; - struct delayed_work hw_wakeup_wq; - - struct work_struct wx_sync_scan_wq; - struct workqueue_struct *wq; - - /* Callback functions */ - void (*set_security)(struct ieee80211_device *ieee, - struct ieee80211_security *sec); - - /* Used to TX data frame by using txb structs. - * this is not used if in the softmac_features - * is set the flag IEEE_SOFTMAC_TX_QUEUE - */ - int (*hard_start_xmit)(struct ieee80211_txb *txb, - struct ieee80211_device *ieee); - - int (*reset_port)(struct ieee80211_device *ieee); - int (*is_queue_full) (struct ieee80211_device *ieee, int pri); - - int (*handle_management) (struct ieee80211_device *ieee, - struct ieee80211_network * network, u16 type); - int (*is_qos_active) (struct ieee80211_device *ieee, struct sk_buff *skb); - - /* Softmac-generated frames (mamagement) are TXed via this - * callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is - * not set. As some cards may have different HW queues that - * one might want to use for data and management frames - * the option to have two callbacks might be useful. - * This function can't sleep. - */ - int (*softmac_hard_start_xmit)(struct sk_buff *skb, - struct ieee80211_device *ieee80211); - - /* used instead of hard_start_xmit (not softmac_hard_start_xmit) - * if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data - * frames. I the option IEEE_SOFTMAC_SINGLE_QUEUE is also set - * then also management frames are sent via this callback. - * This function can't sleep. - */ - void (*softmac_data_hard_start_xmit)(struct sk_buff *skb, - struct ieee80211_device *ieee80211, int rate); - - /* stops the HW queue for DATA frames. Useful to avoid - * waste time to TX data frame when we are reassociating - * This function can sleep. - */ - void (*data_hard_stop)(struct ieee80211_device *ieee80211); - - /* OK this is complementar to data_poll_hard_stop */ - void (*data_hard_resume)(struct ieee80211_device *ieee80211); - - /* ask to the driver to retune the radio . - * This function can sleep. the driver should ensure - * the radio has been swithced before return. - */ - void (*set_chan)(struct ieee80211_device *ieee80211, short ch); - - /* These are not used if the ieee stack takes care of - * scanning (IEEE_SOFTMAC_SCAN feature set). - * In this case only the set_chan is used. - * - * The syncro version is similar to the start_scan but - * does not return until all channels has been scanned. - * this is called in user context and should sleep, - * it is called in a work_queue when swithcing to ad-hoc mode - * or in behalf of iwlist scan when the card is associated - * and root user ask for a scan. - * the function stop_scan should stop both the syncro and - * background scanning and can sleep. - * The function start_scan should initiate the background - * scanning and can't sleep. - */ - void (*scan_syncro)(struct ieee80211_device *ieee80211); - void (*start_scan)(struct ieee80211_device *ieee80211); - void (*stop_scan)(struct ieee80211_device *ieee80211); - - /* indicate the driver that the link state is changed - * for example it may indicate the card is associated now. - * Driver might be interested in this to apply RX filter - * rules or simply light the LINK led - */ - void (*link_change)(struct ieee80211_device *ieee80211); - - /* these two function indicates to the HW when to start - * and stop to send beacons. This is used when the - * IEEE_SOFTMAC_BEACONS is not set. For now the - * stop_send_bacons is NOT guaranteed to be called only - * after start_send_beacons. - */ - void (*start_send_beacons) (struct ieee80211_device *dev); - void (*stop_send_beacons) (struct ieee80211_device *dev); - - /* power save mode related */ - void (*sta_wake_up) (struct ieee80211_device *ieee80211); - void (*enter_sleep_state) (struct ieee80211_device *ieee80211, u32 th, u32 tl); - short (*ps_is_queue_empty) (struct ieee80211_device *ieee80211); - int (*handle_beacon) (struct ieee80211_device *ieee80211, struct ieee80211_beacon *beacon, struct ieee80211_network *network); - int (*handle_assoc_response) (struct ieee80211_device *ieee80211, struct ieee80211_assoc_response_frame *resp, struct ieee80211_network *network); - - /* check whether Tx hw resouce available */ - short (*check_nic_enough_desc)(struct ieee80211_device *ieee80211, int queue_index); - //added by wb for HT related - void (*SetBWModeHandler)(struct ieee80211_device *ieee80211, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset); - bool (*GetNmodeSupportBySecCfg)(struct ieee80211_device *ieee80211); - void (*SetWirelessMode)(struct ieee80211_device *ieee80211, u8 wireless_mode); - bool (*GetHalfNmodeSupportByAPsHandler)(struct ieee80211_device *ieee80211); - void (*InitialGainHandler)(struct ieee80211_device *ieee80211, u8 Operation); - - /* This must be the last item so that it points to the data - * allocated beyond this structure by alloc_ieee80211 */ - u8 priv[0]; -}; - -#define RT_RF_OFF_LEVL_ASPM BIT0 // PCI ASPM -#define RT_RF_OFF_LEVL_CLK_REQ BIT1 // PCI clock request -#define RT_RF_OFF_LEVL_PCI_D3 BIT2 // PCI D3 mode -#define RT_RF_OFF_LEVL_HALT_NIC BIT3 // NIC halt, re-initialize hw parameters -#define RT_RF_OFF_LEVL_FREE_FW BIT4 // FW free, re-download the FW -#define RT_RF_OFF_LEVL_FW_32K BIT5 // FW in 32k -#define RT_RF_PS_LEVEL_ALWAYS_ASPM BIT6 // Always enable ASPM and Clock Req in initialization. -#define RT_RF_LPS_DISALBE_2R BIT30 // When LPS is on, disable 2R if no packet is received or transmittd. -#define RT_RF_LPS_LEVEL_ASPM BIT31 // LPS with ASPM -#define RT_IN_PS_LEVEL(pPSC, _PS_FLAG) ((pPSC->CurPsLevel & _PS_FLAG) ? true : false) -#define RT_CLEAR_PS_LEVEL(pPSC, _PS_FLAG) (pPSC->CurPsLevel &= (~(_PS_FLAG))) -#define RT_SET_PS_LEVEL(pPSC, _PS_FLAG) (pPSC->CurPsLevel |= _PS_FLAG) - -#define IEEE_A (1<<0) -#define IEEE_B (1<<1) -#define IEEE_G (1<<2) -#define IEEE_N_24G (1<<4) -#define IEEE_N_5G (1<<5) -#define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G) - -/* Generate a 802.11 header */ - -/* Uses the channel change callback directly - * instead of [start/stop] scan callbacks - */ -#define IEEE_SOFTMAC_SCAN (1<<2) - -/* Perform authentication and association handshake */ -#define IEEE_SOFTMAC_ASSOCIATE (1<<3) - -/* Generate probe requests */ -#define IEEE_SOFTMAC_PROBERQ (1<<4) - -/* Generate respones to probe requests */ -#define IEEE_SOFTMAC_PROBERS (1<<5) - -/* The ieee802.11 stack will manages the netif queue - * wake/stop for the driver, taking care of 802.11 - * fragmentation. See softmac.c for details. */ -#define IEEE_SOFTMAC_TX_QUEUE (1<<7) - -/* Uses only the softmac_data_hard_start_xmit - * even for TX management frames. - */ -#define IEEE_SOFTMAC_SINGLE_QUEUE (1<<8) - -/* Generate beacons. The stack will enqueue beacons - * to the card - */ -#define IEEE_SOFTMAC_BEACONS (1<<6) - -static inline void *ieee80211_priv(struct net_device *dev) -{ - return ((struct ieee80211_device *)netdev_priv(dev))->priv; -} - -extern inline int ieee80211_is_empty_essid(const char *essid, int essid_len) -{ - /* Single white space is for Linksys APs */ - if (essid_len == 1 && essid[0] == ' ') - return 1; - - /* Otherwise, if the entire essid is 0, we assume it is hidden */ - while (essid_len) { - essid_len--; - if (essid[essid_len] != '\0') - return 0; - } - - return 1; -} - -extern inline int ieee80211_is_valid_mode(struct ieee80211_device *ieee, int mode) -{ - /* - * It is possible for both access points and our device to support - * combinations of modes, so as long as there is one valid combination - * of ap/device supported modes, then return success - * - */ - if ((mode & IEEE_A) && - (ieee->modulation & IEEE80211_OFDM_MODULATION) && - (ieee->freq_band & IEEE80211_52GHZ_BAND)) - return 1; - - if ((mode & IEEE_G) && - (ieee->modulation & IEEE80211_OFDM_MODULATION) && - (ieee->freq_band & IEEE80211_24GHZ_BAND)) - return 1; - - if ((mode & IEEE_B) && - (ieee->modulation & IEEE80211_CCK_MODULATION) && - (ieee->freq_band & IEEE80211_24GHZ_BAND)) - return 1; - - return 0; -} - -extern inline int ieee80211_get_hdrlen(u16 fc) -{ - int hdrlen = IEEE80211_3ADDR_LEN; - - switch (WLAN_FC_GET_TYPE(fc)) { - case IEEE80211_FTYPE_DATA: - if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS)) - hdrlen = IEEE80211_4ADDR_LEN; /* Addr4 */ - if(IEEE80211_QOS_HAS_SEQ(fc)) - hdrlen += 2; /* QOS ctrl*/ - break; - case IEEE80211_FTYPE_CTL: - switch (WLAN_FC_GET_STYPE(fc)) { - case IEEE80211_STYPE_CTS: - case IEEE80211_STYPE_ACK: - hdrlen = IEEE80211_1ADDR_LEN; - break; - default: - hdrlen = IEEE80211_2ADDR_LEN; - break; - } - break; - } - - return hdrlen; -} - -static inline u8 *ieee80211_get_payload(struct ieee80211_hdr *hdr) -{ - switch (ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl))) { - case IEEE80211_1ADDR_LEN: - return ((struct ieee80211_hdr_1addr *)hdr)->payload; - case IEEE80211_2ADDR_LEN: - return ((struct ieee80211_hdr_2addr *)hdr)->payload; - case IEEE80211_3ADDR_LEN: - return ((struct ieee80211_hdr_3addr *)hdr)->payload; - case IEEE80211_4ADDR_LEN: - return ((struct ieee80211_hdr_4addr *)hdr)->payload; - } - return NULL; -} - -static inline int ieee80211_is_ofdm_rate(u8 rate) -{ - switch (rate & ~IEEE80211_BASIC_RATE_MASK) { - case IEEE80211_OFDM_RATE_6MB: - case IEEE80211_OFDM_RATE_9MB: - case IEEE80211_OFDM_RATE_12MB: - case IEEE80211_OFDM_RATE_18MB: - case IEEE80211_OFDM_RATE_24MB: - case IEEE80211_OFDM_RATE_36MB: - case IEEE80211_OFDM_RATE_48MB: - case IEEE80211_OFDM_RATE_54MB: - return 1; - } - return 0; -} - -static inline int ieee80211_is_cck_rate(u8 rate) -{ - switch (rate & ~IEEE80211_BASIC_RATE_MASK) { - case IEEE80211_CCK_RATE_1MB: - case IEEE80211_CCK_RATE_2MB: - case IEEE80211_CCK_RATE_5MB: - case IEEE80211_CCK_RATE_11MB: - return 1; - } - return 0; -} - - -/* ieee80211.c */ -void free_ieee80211(struct net_device *dev); -struct net_device *alloc_ieee80211(int sizeof_priv); - -int ieee80211_set_encryption(struct ieee80211_device *ieee); - -/* ieee80211_tx.c */ - -int ieee80211_encrypt_fragment( - struct ieee80211_device *ieee, - struct sk_buff *frag, - int hdr_len); - -int ieee80211_rtl_xmit(struct sk_buff *skb, - struct net_device *dev); -void ieee80211_txb_free(struct ieee80211_txb *); - - -/* ieee80211_rx.c */ -int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, - struct ieee80211_rx_stats *rx_stats); -void ieee80211_rx_mgt(struct ieee80211_device *ieee, - struct ieee80211_hdr_4addr *header, - struct ieee80211_rx_stats *stats); - -/* ieee80211_wx.c */ -int ieee80211_wx_get_scan(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *key); -int ieee80211_wx_set_encode(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *key); -int ieee80211_wx_get_encode(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *key); -int ieee80211_wx_get_encode_ext(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data* wrqu, char *extra); -int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data* wrqu, char *extra); -int ieee80211_wx_set_auth(struct ieee80211_device *ieee, - struct iw_request_info *info, - struct iw_param *data, char *extra); -int ieee80211_wx_set_mlme(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); -int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len); - -/* ieee80211_softmac.c */ -short ieee80211_is_54g(struct ieee80211_network net); -short ieee80211_is_shortslot(struct ieee80211_network net); -int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb, - struct ieee80211_rx_stats *rx_stats, u16 type, - u16 stype); -void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net); - -void SendDisassociation(struct ieee80211_device *ieee, u8* asSta, u8 asRsn); -void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee); - -void ieee80211_stop_send_beacons(struct ieee80211_device *ieee); -void notify_wx_assoc_event(struct ieee80211_device *ieee); -void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee); -void ieee80211_start_bss(struct ieee80211_device *ieee); -void ieee80211_start_master_bss(struct ieee80211_device *ieee); -void ieee80211_start_ibss(struct ieee80211_device *ieee); -void ieee80211_softmac_init(struct ieee80211_device *ieee); -void ieee80211_softmac_free(struct ieee80211_device *ieee); -void ieee80211_associate_abort(struct ieee80211_device *ieee); -void ieee80211_disassociate(struct ieee80211_device *ieee); -void ieee80211_stop_scan(struct ieee80211_device *ieee); -void ieee80211_start_scan_syncro(struct ieee80211_device *ieee); -void ieee80211_check_all_nets(struct ieee80211_device *ieee); -void ieee80211_start_protocol(struct ieee80211_device *ieee); -void ieee80211_stop_protocol(struct ieee80211_device *ieee,u8 shutdown); -void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee); -void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee,u8 shutdown); -void ieee80211_reset_queue(struct ieee80211_device *ieee); -void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee); -void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee); -struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee); -void ieee80211_start_send_beacons(struct ieee80211_device *ieee); -void ieee80211_stop_send_beacons(struct ieee80211_device *ieee); -int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p); -void notify_wx_assoc_event(struct ieee80211_device *ieee); -void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success); - -void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee); - -/* ieee80211_crypt_ccmp&tkip&wep.c */ -void ieee80211_tkip_null(void); -void ieee80211_wep_null(void); -void ieee80211_ccmp_null(void); - -/* ieee80211_softmac_wx.c */ - -int ieee80211_wx_get_wap(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *ext); - -int ieee80211_wx_set_wap(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *awrq, - char *extra); - -int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b); - -int ieee80211_wx_set_rate(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -int ieee80211_wx_get_rate(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a, - union iwreq_data *wrqu, char *b); - -int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a, - union iwreq_data *wrqu, char *b); - -int ieee80211_wx_set_essid(struct ieee80211_device *ieee, - struct iw_request_info *a, - union iwreq_data *wrqu, char *extra); - -int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a, - union iwreq_data *wrqu, char *b); - -int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a, - union iwreq_data *wrqu, char *b); - -int ieee80211_wx_get_freq(struct ieee80211_device *ieee, struct iw_request_info *a, - union iwreq_data *wrqu, char *b); - -void ieee80211_wx_sync_scan_wq(struct work_struct *work); - -int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -int ieee80211_wx_get_name(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -int ieee80211_wx_set_power(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -int ieee80211_wx_get_power(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -int ieee80211_wx_set_rts(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); - -int ieee80211_wx_get_rts(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra); -//HT -#define MAX_RECEIVE_BUFFER_SIZE 9100 -void HTDebugHTCapability(u8 *CapIE, u8 *TitleString ); -void HTDebugHTInfo(u8 *InfoIE, u8 *TitleString); - -void HTSetConnectBwMode(struct ieee80211_device *ieee, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset); -void HTUpdateDefaultSetting(struct ieee80211_device *ieee); -void HTConstructCapabilityElement(struct ieee80211_device *ieee, u8 *posHTCap, u8 *len, u8 isEncrypt); -void HTConstructInfoElement(struct ieee80211_device *ieee, u8 *posHTInfo, u8 *len, u8 isEncrypt); -void HTConstructRT2RTAggElement(struct ieee80211_device *ieee, u8 *posRT2RTAgg, u8 *len); -void HTOnAssocRsp(struct ieee80211_device *ieee); -void HTInitializeHTInfo(struct ieee80211_device *ieee); -void HTInitializeBssDesc(PBSS_HT pBssHT); -void HTResetSelfAndSavePeerSetting(struct ieee80211_device *ieee, struct ieee80211_network *pNetwork); -void HTUpdateSelfAndPeerSetting(struct ieee80211_device *ieee, struct ieee80211_network *pNetwork); -u8 HTGetHighestMCSRate(struct ieee80211_device *ieee, u8 *pMCSRateSet, u8 *pMCSFilter); -extern u8 MCS_FILTER_ALL[]; -extern u16 MCS_DATA_RATE[2][2][77] ; - -u8 HTCCheck(struct ieee80211_device *ieee, u8 *pFrame); -void HTResetIOTSetting(PRT_HIGH_THROUGHPUT pHTInfo); -bool IsHTHalfNmodeAPs(struct ieee80211_device *ieee); -u16 HTHalfMcsToDataRate(struct ieee80211_device *ieee, u8 nMcsRate); -u16 HTMcsToDataRate( struct ieee80211_device *ieee, u8 nMcsRate); -u16 TxCountToDataRate( struct ieee80211_device *ieee, u8 nDataRate); -int ieee80211_rx_ADDBAReq( struct ieee80211_device *ieee, struct sk_buff *skb); -int ieee80211_rx_ADDBARsp( struct ieee80211_device *ieee, struct sk_buff *skb); -int ieee80211_rx_DELBA(struct ieee80211_device *ieee, struct sk_buff *skb); -void TsInitAddBA( struct ieee80211_device *ieee, PTX_TS_RECORD pTS, u8 Policy, u8 bOverwritePending); -void TsInitDelBA( struct ieee80211_device *ieee, PTS_COMMON_INFO pTsCommonInfo, TR_SELECT TxRxSelect); -void BaSetupTimeOut(unsigned long data); -void TxBaInactTimeout(unsigned long data); -void RxBaInactTimeout(unsigned long data); -void ResetBaEntry( PBA_RECORD pBA); -//function in TS.c -bool GetTs( - struct ieee80211_device* ieee, - PTS_COMMON_INFO *ppTS, - u8* Addr, - u8 TID, - TR_SELECT TxRxSelect, //Rx:1, Tx:0 - bool bAddNewTs - ); -void TSInitialize(struct ieee80211_device *ieee); -void TsStartAddBaProcess(struct ieee80211_device *ieee, PTX_TS_RECORD pTxTS); -void RemovePeerTS(struct ieee80211_device *ieee, u8 *Addr); -void RemoveAllTS(struct ieee80211_device *ieee); -void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee); - -extern const long ieee80211_wlan_frequencies[]; - -extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee) -{ - ieee->scans++; -} - -extern inline int ieee80211_get_scans(struct ieee80211_device *ieee) -{ - return ieee->scans; -} - -static inline const char *escape_essid(const char *essid, u8 essid_len) { - static char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; - const char *s = essid; - char *d = escaped; - - if (ieee80211_is_empty_essid(essid, essid_len)) { - memcpy(escaped, "<hidden>", sizeof("<hidden>")); - return escaped; - } - - essid_len = min(essid_len, (u8)IW_ESSID_MAX_SIZE); - while (essid_len--) { - if (*s == '\0') { - *d++ = '\\'; - *d++ = '0'; - s++; - } else { - *d++ = *s++; - } - } - *d = '\0'; - return escaped; -} - -/* For the function is more related to hardware setting, it's better to use the - * ieee handler to refer to it. - */ -int ieee80211_data_xmit(struct sk_buff *skb, struct net_device *dev); -int ieee80211_parse_info_param(struct ieee80211_device *ieee, - struct ieee80211_info_element *info_element, - u16 length, - struct ieee80211_network *network, - struct ieee80211_rx_stats *stats); - -void ieee80211_indicate_packets(struct ieee80211_device *ieee, struct ieee80211_rxb** prxbIndicateArray,u8 index); -void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr); -void ieee80211_sta_ps_send_pspoll_frame(struct ieee80211_device *ieee); -#define RT_ASOC_RETRY_LIMIT 5 -#endif /* IEEE80211_H */ diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c deleted file mode 100644 index 37a65ff..0000000 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_module.c +++ /dev/null @@ -1,352 +0,0 @@ -/******************************************************************************* - - Copyright(c) 2004 Intel Corporation. All rights reserved. - - Portions of this file are based on the WEP enablement code provided by the - Host AP project hostap-drivers v0.1.3 - Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen - <jkmaline@cc.hut.fi> - Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi> - - This program is free software; you can redistribute it and/or modify it - under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - You should have received a copy of the GNU General Public License along with - this program; if not, write to the Free Software Foundation, Inc., 59 - Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - The full GNU General Public License is included in this distribution in the - file called LICENSE. - - Contact Information: - James P. Ketrenos <ipw2100-admin@linux.intel.com> - Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - -*******************************************************************************/ - -#include <linux/compiler.h> -#include <linux/errno.h> -#include <linux/if_arp.h> -#include <linux/in6.h> -#include <linux/in.h> -#include <linux/ip.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/netdevice.h> -#include <linux/pci.h> -#include <linux/proc_fs.h> -#include <linux/skbuff.h> -#include <linux/slab.h> -#include <linux/tcp.h> -#include <linux/types.h> -#include <linux/wireless.h> -#include <linux/etherdevice.h> -#include <asm/uaccess.h> -#include <net/arp.h> - -#include "ieee80211.h" - -MODULE_DESCRIPTION("802.11 data/management/control stack"); -MODULE_AUTHOR("Copyright (C) 2004 Intel Corporation <jketreno@linux.intel.com>"); -MODULE_LICENSE("GPL"); - -#define DRV_NAME "ieee80211" - -static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee) -{ - if (ieee->networks) - return 0; - - ieee->networks = kcalloc( - MAX_NETWORK_COUNT, sizeof(struct ieee80211_network), - GFP_KERNEL); - if (!ieee->networks) { - printk(KERN_WARNING "%s: Out of memory allocating beacons\n", - ieee->dev->name); - return -ENOMEM; - } - - return 0; -} - -static inline void ieee80211_networks_free(struct ieee80211_device *ieee) -{ - if (!ieee->networks) - return; - kfree(ieee->networks); - ieee->networks = NULL; -} - -static inline void ieee80211_networks_initialize(struct ieee80211_device *ieee) -{ - int i; - - INIT_LIST_HEAD(&ieee->network_free_list); - INIT_LIST_HEAD(&ieee->network_list); - for (i = 0; i < MAX_NETWORK_COUNT; i++) - list_add_tail(&ieee->networks[i].list, &ieee->network_free_list); -} - - -struct net_device *alloc_ieee80211(int sizeof_priv) -{ - struct ieee80211_device *ieee; - struct net_device *dev; - int i, err; - - IEEE80211_DEBUG_INFO("Initializing...\n"); - - dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv); - if (!dev) { - IEEE80211_ERROR("Unable to network device.\n"); - goto failed; - } - - ieee = netdev_priv(dev); - - memset(ieee, 0, sizeof(struct ieee80211_device) + sizeof_priv); - ieee->dev = dev; - - err = ieee80211_networks_allocate(ieee); - if (err) { - IEEE80211_ERROR("Unable to allocate beacon storage: %d\n", - err); - goto failed; - } - ieee80211_networks_initialize(ieee); - - - /* Default fragmentation threshold is maximum payload size */ - ieee->fts = DEFAULT_FTS; - ieee->scan_age = DEFAULT_MAX_SCAN_AGE; - ieee->open_wep = 1; - - /* Default to enabling full open WEP with host based encrypt/decrypt */ - ieee->host_encrypt = 1; - ieee->host_decrypt = 1; - ieee->ieee802_1x = 1; /* Default to supporting 802.1x */ - - INIT_LIST_HEAD(&ieee->crypt_deinit_list); - init_timer(&ieee->crypt_deinit_timer); - ieee->crypt_deinit_timer.data = (unsigned long)ieee; - ieee->crypt_deinit_timer.function = ieee80211_crypt_deinit_handler; - - spin_lock_init(&ieee->lock); - spin_lock_init(&ieee->wpax_suitlist_lock); - spin_lock_init(&ieee->bw_spinlock); - spin_lock_init(&ieee->reorder_spinlock); - - /* added by WB */ - atomic_set(&(ieee->atm_chnlop), 0); - atomic_set(&(ieee->atm_swbw), 0); - - ieee->wpax_type_set = 0; - ieee->wpa_enabled = 0; - ieee->tkip_countermeasures = 0; - ieee->drop_unencrypted = 0; - ieee->privacy_invoked = 0; - ieee->ieee802_1x = 1; - ieee->raw_tx = 0; - /* ieee->hwsec_support = 1; default support hw security: use module_param instead */ - ieee->hwsec_active = 0; /* disable hwsec, switch it on when necessary */ - - ieee80211_softmac_init(ieee); - - ieee->pHTInfo = kzalloc(sizeof(RT_HIGH_THROUGHPUT), GFP_KERNEL); - if (ieee->pHTInfo == NULL) - { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for HTInfo\n"); - return NULL; - } - HTUpdateDefaultSetting(ieee); - HTInitializeHTInfo(ieee); /* may move to other place */ - TSInitialize(ieee); - for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++) - INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]); - - for (i = 0; i < 17; i++) { - ieee->last_rxseq_num[i] = -1; - ieee->last_rxfrag_num[i] = -1; - ieee->last_packet_time[i] = 0; - } - - /* Functions to load crypt module automatically */ - ieee80211_tkip_null(); - ieee80211_wep_null(); - ieee80211_ccmp_null(); - - return dev; - -failed: - if (dev) - free_netdev(dev); - return NULL; -} - - -void free_ieee80211(struct net_device *dev) -{ - struct ieee80211_device *ieee = netdev_priv(dev); - int i; - kfree(ieee->pHTInfo); - ieee->pHTInfo = NULL; - RemoveAllTS(ieee); - ieee80211_softmac_free(ieee); - del_timer_sync(&ieee->crypt_deinit_timer); - ieee80211_crypt_deinit_entries(ieee, 1); - - for (i = 0; i < WEP_KEYS; i++) { - struct ieee80211_crypt_data *crypt = ieee->crypt[i]; - if (crypt) { - if (crypt->ops) - crypt->ops->deinit(crypt->priv); - kfree(crypt); - ieee->crypt[i] = NULL; - } - } - - ieee80211_networks_free(ieee); - free_netdev(dev); -} - -#ifdef CONFIG_IEEE80211_DEBUG - -u32 ieee80211_debug_level = 0; -static int debug = - /* IEEE80211_DL_INFO | */ - /* IEEE80211_DL_WX | */ - /* IEEE80211_DL_SCAN | */ - /* IEEE80211_DL_STATE | */ - /* IEEE80211_DL_MGMT | */ - /* IEEE80211_DL_FRAG | */ - /* IEEE80211_DL_EAP | */ - /* IEEE80211_DL_DROP | */ - /* IEEE80211_DL_TX | */ - /* IEEE80211_DL_RX | */ - /* IEEE80211_DL_QOS | */ - /* IEEE80211_DL_HT | */ - /* IEEE80211_DL_TS | */ - /* IEEE80211_DL_BA | */ - /* IEEE80211_DL_REORDER | */ - /* IEEE80211_DL_TRACE | */ - /* IEEE80211_DL_DATA | */ - IEEE80211_DL_ERR /* always open this flag to show error out */ - ; -struct proc_dir_entry *ieee80211_proc = NULL; - -static int show_debug_level(char *page, char **start, off_t offset, - int count, int *eof, void *data) -{ - return snprintf(page, count, "0x%08X\n", ieee80211_debug_level); -} - -static int store_debug_level(struct file *file, const char *buffer, - unsigned long count, void *data) -{ - char buf[] = "0x00000000"; - unsigned long len = min(sizeof(buf) - 1, (u32)count); - char *p = (char *)buf; - unsigned long val; - - if (copy_from_user(buf, buffer, len)) - return count; - buf[len] = 0; - if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') { - p++; - if (p[0] == 'x' || p[0] == 'X') - p++; - val = simple_strtoul(p, &p, 16); - } else - val = simple_strtoul(p, &p, 10); - if (p == buf) - printk(KERN_INFO DRV_NAME - ": %s is not in hex or decimal form.\n", buf); - else - ieee80211_debug_level = val; - - return strnlen(buf, count); -} - -extern int ieee80211_crypto_init(void); -extern void ieee80211_crypto_deinit(void); -extern int ieee80211_crypto_tkip_init(void); -extern void ieee80211_crypto_tkip_exit(void); -extern int ieee80211_crypto_ccmp_init(void); -extern void ieee80211_crypto_ccmp_exit(void); -extern int ieee80211_crypto_wep_init(void); -extern void ieee80211_crypto_wep_exit(void); - -int __init ieee80211_rtl_init(void) -{ - struct proc_dir_entry *e; - int retval; - - retval = ieee80211_crypto_init(); - if (retval) - return retval; - retval = ieee80211_crypto_tkip_init(); - if (retval) { - ieee80211_crypto_deinit(); - return retval; - } - retval = ieee80211_crypto_ccmp_init(); - if (retval) { - ieee80211_crypto_tkip_exit(); - ieee80211_crypto_deinit(); - return retval; - } - retval = ieee80211_crypto_wep_init(); - if (retval) { - ieee80211_crypto_ccmp_exit(); - ieee80211_crypto_tkip_exit(); - ieee80211_crypto_deinit(); - return retval; - } - - ieee80211_debug_level = debug; - ieee80211_proc = proc_mkdir(DRV_NAME, init_net.proc_net); - if (ieee80211_proc == NULL) { - IEEE80211_ERROR("Unable to create " DRV_NAME - " proc directory\n"); - return -EIO; - } - e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR, - ieee80211_proc); - if (!e) { - remove_proc_entry(DRV_NAME, init_net.proc_net); - ieee80211_proc = NULL; - return -EIO; - } - e->read_proc = show_debug_level; - e->write_proc = store_debug_level; - e->data = NULL; - - return 0; -} - -void __exit ieee80211_rtl_exit(void) -{ - if (ieee80211_proc) { - remove_proc_entry("debug_level", ieee80211_proc); - remove_proc_entry(DRV_NAME, init_net.proc_net); - ieee80211_proc = NULL; - } - ieee80211_crypto_wep_exit(); - ieee80211_crypto_ccmp_exit(); - ieee80211_crypto_tkip_exit(); - ieee80211_crypto_deinit(); -} - -#include <linux/moduleparam.h> -module_param(debug, int, 0444); -MODULE_PARM_DESC(debug, "debug output mask"); - - -#endif - diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c deleted file mode 100644 index 022086d..0000000 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_rx.c +++ /dev/null @@ -1,2676 +0,0 @@ -/* - * Original code based Host AP (software wireless LAN access point) driver - * for Intersil Prism2/2.5/3 - hostap.o module, common routines - * - * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen - * <jkmaline@cc.hut.fi> - * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi> - * Copyright (c) 2004, Intel Corporation - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. See README and COPYING for - * more details. - ****************************************************************************** - - Few modifications for Realtek's Wi-Fi drivers by - Andrea Merello <andreamrl@tiscali.it> - - A special thanks goes to Realtek for their support ! - -******************************************************************************/ - - -#include <linux/compiler.h> -#include <linux/errno.h> -#include <linux/if_arp.h> -#include <linux/in6.h> -#include <linux/in.h> -#include <linux/ip.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/netdevice.h> -#include <linux/pci.h> -#include <linux/proc_fs.h> -#include <linux/skbuff.h> -#include <linux/slab.h> -#include <linux/tcp.h> -#include <linux/types.h> -#include <linux/wireless.h> -#include <linux/etherdevice.h> -#include <asm/uaccess.h> -#include <linux/ctype.h> - -#include "ieee80211.h" -#ifdef ENABLE_DOT11D -#include "dot11d.h" -#endif -static inline void ieee80211_monitor_rx(struct ieee80211_device *ieee, - struct sk_buff *skb, - struct ieee80211_rx_stats *rx_stats) -{ - struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *)skb->data; - u16 fc = le16_to_cpu(hdr->frame_ctl); - - skb->dev = ieee->dev; - skb_reset_mac_header(skb); - - skb_pull(skb, ieee80211_get_hdrlen(fc)); - skb->pkt_type = PACKET_OTHERHOST; - skb->protocol = __constant_htons(ETH_P_80211_RAW); - memset(skb->cb, 0, sizeof(skb->cb)); - netif_rx(skb); -} - - -/* Called only as a tasklet (software IRQ) */ -static struct ieee80211_frag_entry * -ieee80211_frag_cache_find(struct ieee80211_device *ieee, unsigned int seq, - unsigned int frag, u8 tid,u8 *src, u8 *dst) -{ - struct ieee80211_frag_entry *entry; - int i; - - for (i = 0; i < IEEE80211_FRAG_CACHE_LEN; i++) { - entry = &ieee->frag_cache[tid][i]; - if (entry->skb != NULL && - time_after(jiffies, entry->first_frag_time + 2 * HZ)) { - IEEE80211_DEBUG_FRAG( - "expiring fragment cache entry " - "seq=%u last_frag=%u\n", - entry->seq, entry->last_frag); - dev_kfree_skb_any(entry->skb); - entry->skb = NULL; - } - - if (entry->skb != NULL && entry->seq == seq && - (entry->last_frag + 1 == frag || frag == -1) && - memcmp(entry->src_addr, src, ETH_ALEN) == 0 && - memcmp(entry->dst_addr, dst, ETH_ALEN) == 0) - return entry; - } - - return NULL; -} - -/* Called only as a tasklet (software IRQ) */ -static struct sk_buff * -ieee80211_frag_cache_get(struct ieee80211_device *ieee, - struct ieee80211_hdr_4addr *hdr) -{ - struct sk_buff *skb = NULL; - u16 fc = le16_to_cpu(hdr->frame_ctl); - u16 sc = le16_to_cpu(hdr->seq_ctl); - unsigned int frag = WLAN_GET_SEQ_FRAG(sc); - unsigned int seq = WLAN_GET_SEQ_SEQ(sc); - struct ieee80211_frag_entry *entry; - struct ieee80211_hdr_3addrqos *hdr_3addrqos; - struct ieee80211_hdr_4addrqos *hdr_4addrqos; - u8 tid; - - if (((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) { - hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)hdr; - tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QCTL_TID; - tid = UP2AC(tid); - tid ++; - } else if (IEEE80211_QOS_HAS_SEQ(fc)) { - hdr_3addrqos = (struct ieee80211_hdr_3addrqos *)hdr; - tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QCTL_TID; - tid = UP2AC(tid); - tid ++; - } else { - tid = 0; - } - - if (frag == 0) { - /* Reserve enough space to fit maximum frame length */ - skb = dev_alloc_skb(ieee->dev->mtu + - sizeof(struct ieee80211_hdr_4addr) + - 8 /* LLC */ + - 2 /* alignment */ + - 8 /* WEP */ + - ETH_ALEN /* WDS */ + - (IEEE80211_QOS_HAS_SEQ(fc)?2:0) /* QOS Control */); - if (skb == NULL) - return NULL; - - entry = &ieee->frag_cache[tid][ieee->frag_next_idx[tid]]; - ieee->frag_next_idx[tid]++; - if (ieee->frag_next_idx[tid] >= IEEE80211_FRAG_CACHE_LEN) - ieee->frag_next_idx[tid] = 0; - - if (entry->skb != NULL) - dev_kfree_skb_any(entry->skb); - - entry->first_frag_time = jiffies; - entry->seq = seq; - entry->last_frag = frag; - entry->skb = skb; - memcpy(entry->src_addr, hdr->addr2, ETH_ALEN); - memcpy(entry->dst_addr, hdr->addr1, ETH_ALEN); - } else { - /* received a fragment of a frame for which the head fragment - * should have already been received */ - entry = ieee80211_frag_cache_find(ieee, seq, frag, tid,hdr->addr2, - hdr->addr1); - if (entry != NULL) { - entry->last_frag = frag; - skb = entry->skb; - } - } - - return skb; -} - - -/* Called only as a tasklet (software IRQ) */ -static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee, - struct ieee80211_hdr_4addr *hdr) -{ - u16 fc = le16_to_cpu(hdr->frame_ctl); - u16 sc = le16_to_cpu(hdr->seq_ctl); - unsigned int seq = WLAN_GET_SEQ_SEQ(sc); - struct ieee80211_frag_entry *entry; - struct ieee80211_hdr_3addrqos *hdr_3addrqos; - struct ieee80211_hdr_4addrqos *hdr_4addrqos; - u8 tid; - - if(((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) { - hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)hdr; - tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QCTL_TID; - tid = UP2AC(tid); - tid ++; - } else if (IEEE80211_QOS_HAS_SEQ(fc)) { - hdr_3addrqos = (struct ieee80211_hdr_3addrqos *)hdr; - tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QCTL_TID; - tid = UP2AC(tid); - tid ++; - } else { - tid = 0; - } - - entry = ieee80211_frag_cache_find(ieee, seq, -1, tid,hdr->addr2, - hdr->addr1); - - if (entry == NULL) { - IEEE80211_DEBUG_FRAG( - "could not invalidate fragment cache " - "entry (seq=%u)\n", seq); - return -1; - } - - entry->skb = NULL; - return 0; -} - - - -/* ieee80211_rx_frame_mgtmt - * - * Responsible for handling management control frames - * - * Called by ieee80211_rx */ -static inline int -ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb, - struct ieee80211_rx_stats *rx_stats, u16 type, - u16 stype) -{ - /* On the struct stats definition there is written that - * this is not mandatory.... but seems that the probe - * response parser uses it - */ - struct ieee80211_hdr_3addr * hdr = (struct ieee80211_hdr_3addr *)skb->data; - - rx_stats->len = skb->len; - ieee80211_rx_mgt(ieee,(struct ieee80211_hdr_4addr *)skb->data,rx_stats); - if ((memcmp(hdr->addr1, ieee->dev->dev_addr, ETH_ALEN)))//use ADDR1 to perform address matching for Management frames - { - dev_kfree_skb_any(skb); - return 0; - } - - ieee80211_rx_frame_softmac(ieee, skb, rx_stats, type, stype); - - dev_kfree_skb_any(skb); - - return 0; - - #ifdef NOT_YET - if (ieee->iw_mode == IW_MODE_MASTER) { - printk(KERN_DEBUG "%s: Master mode not yet suppported.\n", - ieee->dev->name); - return 0; - } - - if (ieee->hostapd && type == IEEE80211_TYPE_MGMT) { - if (stype == WLAN_FC_STYPE_BEACON && - ieee->iw_mode == IW_MODE_MASTER) { - struct sk_buff *skb2; - /* Process beacon frames also in kernel driver to - * update STA(AP) table statistics */ - skb2 = skb_clone(skb, GFP_ATOMIC); - if (skb2) - hostap_rx(skb2->dev, skb2, rx_stats); - } - - /* send management frames to the user space daemon for - * processing */ - ieee->apdevstats.rx_packets++; - ieee->apdevstats.rx_bytes += skb->len; - prism2_rx_80211(ieee->apdev, skb, rx_stats, PRISM2_RX_MGMT); - return 0; - } - - if (ieee->iw_mode == IW_MODE_MASTER) { - if (type != WLAN_FC_TYPE_MGMT && type != WLAN_FC_TYPE_CTRL) { - printk(KERN_DEBUG "%s: unknown management frame " - "(type=0x%02x, stype=0x%02x) dropped\n", - skb->dev->name, type, stype); - return -1; - } - - hostap_rx(skb->dev, skb, rx_stats); - return 0; - } - - printk(KERN_DEBUG "%s: hostap_rx_frame_mgmt: management frame " - "received in non-Host AP mode\n", skb->dev->name); - return -1; - #endif -} - - - -/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */ -/* Ethernet-II snap header (RFC1042 for most EtherTypes) */ -static unsigned char rfc1042_header[] = -{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 }; -/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */ -static unsigned char bridge_tunnel_header[] = -{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 }; -/* No encapsulation header if EtherType < 0x600 (=length) */ - -/* Called by ieee80211_rx_frame_decrypt */ -static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee, - struct sk_buff *skb, size_t hdrlen) -{ - struct net_device *dev = ieee->dev; - u16 fc, ethertype; - struct ieee80211_hdr_4addr *hdr; - u8 *pos; - - if (skb->len < 24) - return 0; - - if (ieee->hwsec_active) - { - cb_desc *tcb_desc = (cb_desc *)(skb->cb+ MAX_DEV_ADDR_SIZE); - tcb_desc->bHwSec = 1; - - if(ieee->need_sw_enc) - tcb_desc->bHwSec = 0; - } - - hdr = (struct ieee80211_hdr_4addr *) skb->data; - fc = le16_to_cpu(hdr->frame_ctl); - - /* check that the frame is unicast frame to us */ - if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == - IEEE80211_FCTL_TODS && - memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0 && - memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) { - /* ToDS frame with own addr BSSID and DA */ - } else if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == - IEEE80211_FCTL_FROMDS && - memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) { - /* FromDS frame with own addr as DA */ - } else - return 0; - - if (skb->len < 24 + 8) - return 0; - - /* check for port access entity Ethernet type */ - pos = skb->data + hdrlen; - ethertype = (pos[6] << 8) | pos[7]; - if (ethertype == ETH_P_PAE) - return 1; - - return 0; -} - -/* Called only as a tasklet (software IRQ), by ieee80211_rx */ -static inline int -ieee80211_rx_frame_decrypt(struct ieee80211_device* ieee, struct sk_buff *skb, - struct ieee80211_crypt_data *crypt) -{ - struct ieee80211_hdr_4addr *hdr; - int res, hdrlen; - - if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL) - return 0; - - if (ieee->hwsec_active) - { - cb_desc *tcb_desc = (cb_desc *)(skb->cb+ MAX_DEV_ADDR_SIZE); - tcb_desc->bHwSec = 1; - } - - hdr = (struct ieee80211_hdr_4addr *) skb->data; - hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl)); - -#ifdef CONFIG_IEEE80211_CRYPT_TKIP - if (ieee->tkip_countermeasures && - strcmp(crypt->ops->name, "TKIP") == 0) { - if (net_ratelimit()) { - printk(KERN_DEBUG "%s: TKIP countermeasures: dropped " - "received packet from %pM\n", - ieee->dev->name, hdr->addr2); - } - return -1; - } -#endif - - atomic_inc(&crypt->refcnt); - res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv); - atomic_dec(&crypt->refcnt); - if (res < 0) { - IEEE80211_DEBUG_DROP( - "decryption failed (SA=%pM" - ") res=%d\n", hdr->addr2, res); - if (res == -2) - IEEE80211_DEBUG_DROP("Decryption failed ICV " - "mismatch (key %d)\n", - skb->data[hdrlen + 3] >> 6); - ieee->ieee_stats.rx_discards_undecryptable++; - return -1; - } - - return res; -} - - -/* Called only as a tasklet (software IRQ), by ieee80211_rx */ -static inline int -ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device* ieee, struct sk_buff *skb, - int keyidx, struct ieee80211_crypt_data *crypt) -{ - struct ieee80211_hdr_4addr *hdr; - int res, hdrlen; - - if (crypt == NULL || crypt->ops->decrypt_msdu == NULL) - return 0; - if (ieee->hwsec_active) - { - cb_desc *tcb_desc = (cb_desc *)(skb->cb+ MAX_DEV_ADDR_SIZE); - tcb_desc->bHwSec = 1; - - if(ieee->need_sw_enc) - tcb_desc->bHwSec = 0; - - } - - hdr = (struct ieee80211_hdr_4addr *) skb->data; - hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl)); - - atomic_inc(&crypt->refcnt); - res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv); - atomic_dec(&crypt->refcnt); - if (res < 0) { - printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed" - " (SA=%pM keyidx=%d)\n", - ieee->dev->name, hdr->addr2, keyidx); - return -1; - } - - return 0; -} - - -/* this function is stolen from ipw2200 driver*/ -#define IEEE_PACKET_RETRY_TIME (5*HZ) -static int is_duplicate_packet(struct ieee80211_device *ieee, - struct ieee80211_hdr_4addr *header) -{ - u16 fc = le16_to_cpu(header->frame_ctl); - u16 sc = le16_to_cpu(header->seq_ctl); - u16 seq = WLAN_GET_SEQ_SEQ(sc); - u16 frag = WLAN_GET_SEQ_FRAG(sc); - u16 *last_seq, *last_frag; - unsigned long *last_time; - struct ieee80211_hdr_3addrqos *hdr_3addrqos; - struct ieee80211_hdr_4addrqos *hdr_4addrqos; - u8 tid; - - - //TO2DS and QoS - if(((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS)&&IEEE80211_QOS_HAS_SEQ(fc)) { - hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)header; - tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QCTL_TID; - tid = UP2AC(tid); - tid ++; - } else if(IEEE80211_QOS_HAS_SEQ(fc)) { //QoS - hdr_3addrqos = (struct ieee80211_hdr_3addrqos*)header; - tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QCTL_TID; - tid = UP2AC(tid); - tid ++; - } else { // no QoS - tid = 0; - } - - switch (ieee->iw_mode) { - case IW_MODE_ADHOC: - { - struct list_head *p; - struct ieee_ibss_seq *entry = NULL; - u8 *mac = header->addr2; - int index = mac[5] % IEEE_IBSS_MAC_HASH_SIZE; - - list_for_each(p, &ieee->ibss_mac_hash[index]) { - entry = list_entry(p, struct ieee_ibss_seq, list); - if (!memcmp(entry->mac, mac, ETH_ALEN)) - break; - } - - if (p == &ieee->ibss_mac_hash[index]) { - entry = kmalloc(sizeof(struct ieee_ibss_seq), GFP_ATOMIC); - if (!entry) { - printk(KERN_WARNING "Cannot malloc new mac entry\n"); - return 0; - } - memcpy(entry->mac, mac, ETH_ALEN); - entry->seq_num[tid] = seq; - entry->frag_num[tid] = frag; - entry->packet_time[tid] = jiffies; - list_add(&entry->list, &ieee->ibss_mac_hash[index]); - return 0; - } - last_seq = &entry->seq_num[tid]; - last_frag = &entry->frag_num[tid]; - last_time = &entry->packet_time[tid]; - break; - } - - case IW_MODE_INFRA: - last_seq = &ieee->last_rxseq_num[tid]; - last_frag = &ieee->last_rxfrag_num[tid]; - last_time = &ieee->last_packet_time[tid]; - - break; - default: - return 0; - } - - if ((*last_seq == seq) && - time_after(*last_time + IEEE_PACKET_RETRY_TIME, jiffies)) { - if (*last_frag == frag){ - goto drop; - - } - if (*last_frag + 1 != frag) - /* out-of-order fragment */ - goto drop; - } else - *last_seq = seq; - - *last_frag = frag; - *last_time = jiffies; - return 0; - -drop: - return 1; -} -bool -AddReorderEntry( - PRX_TS_RECORD pTS, - PRX_REORDER_ENTRY pReorderEntry - ) -{ - struct list_head *pList = &pTS->RxPendingPktList; - - while(pList->next != &pTS->RxPendingPktList) - { - if( SN_LESS(pReorderEntry->SeqNum, ((PRX_REORDER_ENTRY)list_entry(pList->next,RX_REORDER_ENTRY,List))->SeqNum) ) - { - pList = pList->next; - } - else if( SN_EQUAL(pReorderEntry->SeqNum, ((PRX_REORDER_ENTRY)list_entry(pList->next,RX_REORDER_ENTRY,List))->SeqNum) ) - { - return false; - } - else - { - break; - } - } - - pReorderEntry->List.next = pList->next; - pReorderEntry->List.next->prev = &pReorderEntry->List; - pReorderEntry->List.prev = pList; - pList->next = &pReorderEntry->List; - - return true; -} - -void ieee80211_indicate_packets(struct ieee80211_device *ieee, struct ieee80211_rxb** prxbIndicateArray,u8 index) -{ - u8 i = 0 , j=0; - u16 ethertype; - - for(j = 0; j<index; j++) - { -//added by amy for reorder - struct ieee80211_rxb* prxb = prxbIndicateArray[j]; - for(i = 0; i<prxb->nr_subframes; i++) { - struct sk_buff *sub_skb = prxb->subframes[i]; - - /* convert hdr + possible LLC headers into Ethernet header */ - ethertype = (sub_skb->data[6] << 8) | sub_skb->data[7]; - if (sub_skb->len >= 8 && - ((memcmp(sub_skb->data, rfc1042_header, SNAP_SIZE) == 0 && - ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) || - memcmp(sub_skb->data, bridge_tunnel_header, SNAP_SIZE) == 0)) { - /* remove RFC1042 or Bridge-Tunnel encapsulation and - * replace EtherType */ - skb_pull(sub_skb, SNAP_SIZE); - memcpy(skb_push(sub_skb, ETH_ALEN), prxb->src, ETH_ALEN); - memcpy(skb_push(sub_skb, ETH_ALEN), prxb->dst, ETH_ALEN); - } else { - u16 len; - /* Leave Ethernet header part of hdr and full payload */ - len = htons(sub_skb->len); - memcpy(skb_push(sub_skb, 2), &len, 2); - memcpy(skb_push(sub_skb, ETH_ALEN), prxb->src, ETH_ALEN); - memcpy(skb_push(sub_skb, ETH_ALEN), prxb->dst, ETH_ALEN); - } - - /* Indicat the packets to upper layer */ - if (sub_skb) { - sub_skb->protocol = eth_type_trans(sub_skb, ieee->dev); - memset(sub_skb->cb, 0, sizeof(sub_skb->cb)); - sub_skb->dev = ieee->dev; - sub_skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */ - ieee->last_rx_ps_time = jiffies; - netif_rx(sub_skb); - } - } - kfree(prxb); - prxb = NULL; - } -} - - -void RxReorderIndicatePacket( struct ieee80211_device *ieee, - struct ieee80211_rxb* prxb, - PRX_TS_RECORD pTS, - u16 SeqNum) -{ - PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; - PRX_REORDER_ENTRY pReorderEntry = NULL; - struct ieee80211_rxb* prxbIndicateArray[REORDER_WIN_SIZE]; - u8 WinSize = pHTInfo->RxReorderWinSize; - u16 WinEnd = (pTS->RxIndicateSeq + WinSize -1)%4096; - u8 index = 0; - bool bMatchWinStart = false, bPktInBuf = false; - IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): Seq is %d,pTS->RxIndicateSeq is %d, WinSize is %d\n",__FUNCTION__,SeqNum,pTS->RxIndicateSeq,WinSize); - - /* Rx Reorder initialize condition.*/ - if(pTS->RxIndicateSeq == 0xffff) { - pTS->RxIndicateSeq = SeqNum; - } - - /* Drop out the packet which SeqNum is smaller than WinStart */ - if(SN_LESS(SeqNum, pTS->RxIndicateSeq)) { - IEEE80211_DEBUG(IEEE80211_DL_REORDER,"Packet Drop! IndicateSeq: %d, NewSeq: %d\n", - pTS->RxIndicateSeq, SeqNum); - pHTInfo->RxReorderDropCounter++; - { - int i; - for(i =0; i < prxb->nr_subframes; i++) { - dev_kfree_skb(prxb->subframes[i]); - } - kfree(prxb); - prxb = NULL; - } - return; - } - - /* - * Sliding window manipulation. Conditions includes: - * 1. Incoming SeqNum is equal to WinStart =>Window shift 1 - * 2. Incoming SeqNum is larger than the WinEnd => Window shift N - */ - if(SN_EQUAL(SeqNum, pTS->RxIndicateSeq)) { - pTS->RxIndicateSeq = (pTS->RxIndicateSeq + 1) % 4096; - bMatchWinStart = true; - } else if(SN_LESS(WinEnd, SeqNum)) { - if(SeqNum >= (WinSize - 1)) { - pTS->RxIndicateSeq = SeqNum + 1 -WinSize; - } else { - pTS->RxIndicateSeq = 4095 - (WinSize - (SeqNum +1)) + 1; - } - IEEE80211_DEBUG(IEEE80211_DL_REORDER, "Window Shift! IndicateSeq: %d, NewSeq: %d\n",pTS->RxIndicateSeq, SeqNum); - } - - /* - * Indication process. - * After Packet dropping and Sliding Window shifting as above, we can now just indicate the packets - * with the SeqNum smaller than latest WinStart and buffer other packets. - */ - /* For Rx Reorder condition: - * 1. All packets with SeqNum smaller than WinStart => Indicate - * 2. All packets with SeqNum larger than or equal to WinStart => Buffer it. - */ - if(bMatchWinStart) { - /* Current packet is going to be indicated.*/ - IEEE80211_DEBUG(IEEE80211_DL_REORDER, "Packets indication!! IndicateSeq: %d, NewSeq: %d\n",\ - pTS->RxIndicateSeq, SeqNum); - prxbIndicateArray[0] = prxb; - index = 1; - } else { - /* Current packet is going to be inserted into pending list.*/ - if(!list_empty(&ieee->RxReorder_Unused_List)) { - pReorderEntry = (PRX_REORDER_ENTRY)list_entry(ieee->RxReorder_Unused_List.next,RX_REORDER_ENTRY,List); - list_del_init(&pReorderEntry->List); - - /* Make a reorder entry and insert into a the packet list.*/ - pReorderEntry->SeqNum = SeqNum; - pReorderEntry->prxb = prxb; - - if(!AddReorderEntry(pTS, pReorderEntry)) { - IEEE80211_DEBUG(IEEE80211_DL_REORDER, "%s(): Duplicate packet is dropped!! IndicateSeq: %d, NewSeq: %d\n", - __FUNCTION__, pTS->RxIndicateSeq, SeqNum); - list_add_tail(&pReorderEntry->List,&ieee->RxReorder_Unused_List); - { - int i; - for(i =0; i < prxb->nr_subframes; i++) { - dev_kfree_skb(prxb->subframes[i]); - } - kfree(prxb); - prxb = NULL; - } - } else { - IEEE80211_DEBUG(IEEE80211_DL_REORDER, - "Pkt insert into buffer!! IndicateSeq: %d, NewSeq: %d\n",pTS->RxIndicateSeq, SeqNum); - } - } - else { - /* - * Packets are dropped if there is not enough reorder entries. - * This part shall be modified!! We can just indicate all the - * packets in buffer and get reorder entries. - */ - IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): There is no reorder entry!! Packet is dropped!!\n"); - { - int i; - for(i =0; i < prxb->nr_subframes; i++) { - dev_kfree_skb(prxb->subframes[i]); - } - kfree(prxb); - prxb = NULL; - } - } - } - - /* Check if there is any packet need indicate.*/ - while(!list_empty(&pTS->RxPendingPktList)) { - IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): start RREORDER indicate\n",__FUNCTION__); -#if 1 - pReorderEntry = (PRX_REORDER_ENTRY)list_entry(pTS->RxPendingPktList.prev,RX_REORDER_ENTRY,List); - if( SN_LESS(pReorderEntry->SeqNum, pTS->RxIndicateSeq) || - SN_EQUAL(pReorderEntry->SeqNum, pTS->RxIndicateSeq)) - { - /* This protect buffer from overflow. */ - if(index >= REORDER_WIN_SIZE) { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): Buffer overflow!! \n"); - bPktInBuf = true; - break; - } - - list_del_init(&pReorderEntry->List); - - if(SN_EQUAL(pReorderEntry->SeqNum, pTS->RxIndicateSeq)) - pTS->RxIndicateSeq = (pTS->RxIndicateSeq + 1) % 4096; - - IEEE80211_DEBUG(IEEE80211_DL_REORDER,"Packets indication!! IndicateSeq: %d, NewSeq: %d\n",pTS->RxIndicateSeq, SeqNum); - prxbIndicateArray[index] = pReorderEntry->prxb; - index++; - - list_add_tail(&pReorderEntry->List,&ieee->RxReorder_Unused_List); - } else { - bPktInBuf = true; - break; - } -#endif - } - - /* Handling pending timer. Set this timer to prevent from long time Rx buffering.*/ - if(index>0) { - // Cancel previous pending timer. - if (timer_pending(&pTS->RxPktPendingTimer)) - del_timer_sync(&pTS->RxPktPendingTimer); - pTS->RxTimeoutIndicateSeq = 0xffff; - - // Indicate packets - if(index>REORDER_WIN_SIZE){ - IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): Rx Reorer buffer full!! \n"); - return; - } - ieee80211_indicate_packets(ieee, prxbIndicateArray, index); - bPktInBuf = false; - } - - if(bPktInBuf && pTS->RxTimeoutIndicateSeq==0xffff) { - // Set new pending timer. - IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): SET rx timeout timer\n", __FUNCTION__); - pTS->RxTimeoutIndicateSeq = pTS->RxIndicateSeq; - - mod_timer(&pTS->RxPktPendingTimer, jiffies + MSECS(pHTInfo->RxReorderPendingTime)); - } -} - -u8 parse_subframe(struct ieee80211_device* ieee,struct sk_buff *skb, - struct ieee80211_rx_stats *rx_stats, - struct ieee80211_rxb *rxb,u8* src,u8* dst) -{ - struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr* )skb->data; - u16 fc = le16_to_cpu(hdr->frame_ctl); - - u16 LLCOffset= sizeof(struct ieee80211_hdr_3addr); - u16 ChkLength; - bool bIsAggregateFrame = false; - u16 nSubframe_Length; - u8 nPadding_Length = 0; - u16 SeqNum=0; - - struct sk_buff *sub_skb; - u8 *data_ptr; - /* just for debug purpose */ - SeqNum = WLAN_GET_SEQ_SEQ(le16_to_cpu(hdr->seq_ctl)); - - if((IEEE80211_QOS_HAS_SEQ(fc))&&\ - (((frameqos *)(skb->data + IEEE80211_3ADDR_LEN))->field.reserved)) { - bIsAggregateFrame = true; - } - - if(IEEE80211_QOS_HAS_SEQ(fc)) { - LLCOffset += 2; - } - - if(rx_stats->bContainHTC) { - LLCOffset += sHTCLng; - } - // Null packet, don't indicate it to upper layer - ChkLength = LLCOffset;/* + (Frame_WEP(frame)!=0 ?Adapter->MgntInfo.SecurityInfo.EncryptionHeadOverhead:0);*/ - - if( skb->len <= ChkLength ) { - return 0; - } - - skb_pull(skb, LLCOffset); - ieee->bIsAggregateFrame = bIsAggregateFrame;//added by amy for Leisure PS - - if(!bIsAggregateFrame) { - rxb->nr_subframes = 1; -#ifdef JOHN_NOCPY - rxb->subframes[0] = skb; -#else - rxb->subframes[0] = skb_copy(skb, GFP_ATOMIC); -#endif - - memcpy(rxb->src,src,ETH_ALEN); - memcpy(rxb->dst,dst,ETH_ALEN); - //IEEE80211_DEBUG_DATA(IEEE80211_DL_RX,skb->data,skb->len); - return 1; - } else { - rxb->nr_subframes = 0; - memcpy(rxb->src,src,ETH_ALEN); - memcpy(rxb->dst,dst,ETH_ALEN); - while(skb->len > ETHERNET_HEADER_SIZE) { - /* Offset 12 denote 2 mac address */ - nSubframe_Length = *((u16*)(skb->data + 12)); - //==m==>change the length order - nSubframe_Length = (nSubframe_Length>>8) + (nSubframe_Length<<8); - - if(skb->len<(ETHERNET_HEADER_SIZE + nSubframe_Length)) { - printk("%s: A-MSDU parse error!! pRfd->nTotalSubframe : %d\n",\ - __FUNCTION__,rxb->nr_subframes); - printk("%s: A-MSDU parse error!! Subframe Length: %d\n",__FUNCTION__, nSubframe_Length); - printk("nRemain_Length is %d and nSubframe_Length is : %d\n",skb->len,nSubframe_Length); - printk("The Packet SeqNum is %d\n",SeqNum); - return 0; - } - - /* move the data point to data content */ - skb_pull(skb, ETHERNET_HEADER_SIZE); - -#ifdef JOHN_NOCPY - sub_skb = skb_clone(skb, GFP_ATOMIC); - sub_skb->len = nSubframe_Length; - sub_skb->tail = sub_skb->data + nSubframe_Length; -#else - /* Allocate new skb for releasing to upper layer */ - sub_skb = dev_alloc_skb(nSubframe_Length + 12); - skb_reserve(sub_skb, 12); - data_ptr = (u8 *)skb_put(sub_skb, nSubframe_Length); - memcpy(data_ptr,skb->data,nSubframe_Length); -#endif - rxb->subframes[rxb->nr_subframes++] = sub_skb; - if(rxb->nr_subframes >= MAX_SUBFRAME_COUNT) { - IEEE80211_DEBUG_RX("ParseSubframe(): Too many Subframes! Packets dropped!\n"); - break; - } - skb_pull(skb,nSubframe_Length); - - if(skb->len != 0) { - nPadding_Length = 4 - ((nSubframe_Length + ETHERNET_HEADER_SIZE) % 4); - if(nPadding_Length == 4) { - nPadding_Length = 0; - } - - if(skb->len < nPadding_Length) { - return 0; - } - - skb_pull(skb,nPadding_Length); - } - } -#ifdef JOHN_NOCPY - dev_kfree_skb(skb); -#endif - return rxb->nr_subframes; - } -} - -/* All received frames are sent to this function. @skb contains the frame in - * IEEE 802.11 format, i.e., in the format it was sent over air. - * This function is called only as a tasklet (software IRQ). */ -int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb, - struct ieee80211_rx_stats *rx_stats) -{ - struct net_device *dev = ieee->dev; - struct ieee80211_hdr_4addr *hdr; - - size_t hdrlen; - u16 fc, type, stype, sc; - struct net_device_stats *stats; - unsigned int frag; - u8 *payload; - u16 ethertype; - //added by amy for reorder - u8 TID = 0; - u16 SeqNum = 0; - PRX_TS_RECORD pTS = NULL; - bool unicast_packet = false; - //added by amy for reorder -#ifdef NOT_YET - struct net_device *wds = NULL; - struct sk_buff *skb2 = NULL; - struct net_device *wds = NULL; - int frame_authorized = 0; - int from_assoc_ap = 0; - void *sta = NULL; -#endif - u8 dst[ETH_ALEN]; - u8 src[ETH_ALEN]; - u8 bssid[ETH_ALEN]; - struct ieee80211_crypt_data *crypt = NULL; - int keyidx = 0; - - int i; - struct ieee80211_rxb* rxb = NULL; - // cheat the the hdr type - hdr = (struct ieee80211_hdr_4addr *)skb->data; - stats = &ieee->stats; - - if (skb->len < 10) { - printk(KERN_INFO "%s: SKB length < 10\n", - dev->name); - goto rx_dropped; - } - - fc = le16_to_cpu(hdr->frame_ctl); - type = WLAN_FC_GET_TYPE(fc); - stype = WLAN_FC_GET_STYPE(fc); - sc = le16_to_cpu(hdr->seq_ctl); - - frag = WLAN_GET_SEQ_FRAG(sc); - hdrlen = ieee80211_get_hdrlen(fc); - - if(HTCCheck(ieee, skb->data)) - { - if(net_ratelimit()) - printk("find HTCControl\n"); - hdrlen += 4; - rx_stats->bContainHTC = 1; - } - -#ifdef NOT_YET -#if WIRELESS_EXT > 15 - /* Put this code here so that we avoid duplicating it in all - * Rx paths. - Jean II */ -#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */ - /* If spy monitoring on */ - if (iface->spy_data.spy_number > 0) { - struct iw_quality wstats; - wstats.level = rx_stats->rssi; - wstats.noise = rx_stats->noise; - wstats.updated = 6; /* No qual value */ - /* Update spy records */ - wireless_spy_update(dev, hdr->addr2, &wstats); - } -#endif /* IW_WIRELESS_SPY */ -#endif /* WIRELESS_EXT > 15 */ - hostap_update_rx_stats(local->ap, hdr, rx_stats); -#endif - -#if WIRELESS_EXT > 15 - if (ieee->iw_mode == IW_MODE_MONITOR) { - ieee80211_monitor_rx(ieee, skb, rx_stats); - stats->rx_packets++; - stats->rx_bytes += skb->len; - return 1; - } -#endif - if (ieee->host_decrypt) { - int idx = 0; - if (skb->len >= hdrlen + 3) - idx = skb->data[hdrlen + 3] >> 6; - crypt = ieee->crypt[idx]; -#ifdef NOT_YET - sta = NULL; - - /* Use station specific key to override default keys if the - * receiver address is a unicast address ("individual RA"). If - * bcrx_sta_key parameter is set, station specific key is used - * even with broad/multicast targets (this is against IEEE - * 802.11, but makes it easier to use different keys with - * stations that do not support WEP key mapping). */ - - if (!(hdr->addr1[0] & 0x01) || local->bcrx_sta_key) - (void) hostap_handle_sta_crypto(local, hdr, &crypt, - &sta); -#endif - - /* allow NULL decrypt to indicate an station specific override - * for default encryption */ - if (crypt && (crypt->ops == NULL || - crypt->ops->decrypt_mpdu == NULL)) - crypt = NULL; - - if (!crypt && (fc & IEEE80211_FCTL_WEP)) { - /* This seems to be triggered by some (multicast?) - * frames from other than current BSS, so just drop the - * frames silently instead of filling system log with - * these reports. */ - IEEE80211_DEBUG_DROP("Decryption failed (not set)" - " (SA=%pM)\n", - hdr->addr2); - ieee->ieee_stats.rx_discards_undecryptable++; - goto rx_dropped; - } - } - - if (skb->len < IEEE80211_DATA_HDR3_LEN) - goto rx_dropped; - - // if QoS enabled, should check the sequence for each of the AC - if( (ieee->pHTInfo->bCurRxReorderEnable == false) || !ieee->current_network.qos_data.active|| !IsDataFrame(skb->data) || IsLegacyDataFrame(skb->data)){ - if (is_duplicate_packet(ieee, hdr)) - goto rx_dropped; - - } - else - { - PRX_TS_RECORD pRxTS = NULL; - - if(GetTs( - ieee, - (PTS_COMMON_INFO*) &pRxTS, - hdr->addr2, - (u8)Frame_QoSTID((u8*)(skb->data)), - RX_DIR, - true)) - { - - if( (fc & (1<<11)) && - (frag == pRxTS->RxLastFragNum) && - (WLAN_GET_SEQ_SEQ(sc) == pRxTS->RxLastSeqNum) ) - { - goto rx_dropped; - } - else - { - pRxTS->RxLastFragNum = frag; - pRxTS->RxLastSeqNum = WLAN_GET_SEQ_SEQ(sc); - } - } - else - { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "%s(): No TS!! Skip the check!!\n",__FUNCTION__); - goto rx_dropped; - } - } - - if (type == IEEE80211_FTYPE_MGMT) { - - if (ieee80211_rx_frame_mgmt(ieee, skb, rx_stats, type, stype)) - goto rx_dropped; - else - goto rx_exit; - } - - /* Data frame - extract src/dst addresses */ - switch (fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) { - case IEEE80211_FCTL_FROMDS: - memcpy(dst, hdr->addr1, ETH_ALEN); - memcpy(src, hdr->addr3, ETH_ALEN); - memcpy(bssid, hdr->addr2, ETH_ALEN); - break; - case IEEE80211_FCTL_TODS: - memcpy(dst, hdr->addr3, ETH_ALEN); - memcpy(src, hdr->addr2, ETH_ALEN); - memcpy(bssid, hdr->addr1, ETH_ALEN); - break; - case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS: - if (skb->len < IEEE80211_DATA_HDR4_LEN) - goto rx_dropped; - memcpy(dst, hdr->addr3, ETH_ALEN); - memcpy(src, hdr->addr4, ETH_ALEN); - memcpy(bssid, ieee->current_network.bssid, ETH_ALEN); - break; - case 0: - memcpy(dst, hdr->addr1, ETH_ALEN); - memcpy(src, hdr->addr2, ETH_ALEN); - memcpy(bssid, hdr->addr3, ETH_ALEN); - break; - } - -#ifdef NOT_YET - if (hostap_rx_frame_wds(ieee, hdr, fc, &wds)) - goto rx_dropped; - if (wds) { - skb->dev = dev = wds; - stats = hostap_get_stats(dev); - } - - if (ieee->iw_mode == IW_MODE_MASTER && !wds && - (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == IEEE80211_FCTL_FROMDS && - ieee->stadev && - memcmp(hdr->addr2, ieee->assoc_ap_addr, ETH_ALEN) == 0) { - /* Frame from BSSID of the AP for which we are a client */ - skb->dev = dev = ieee->stadev; - stats = hostap_get_stats(dev); - from_assoc_ap = 1; - } -#endif - - dev->last_rx = jiffies; - -#ifdef NOT_YET - if ((ieee->iw_mode == IW_MODE_MASTER || - ieee->iw_mode == IW_MODE_REPEAT) && - !from_assoc_ap) { - switch (hostap_handle_sta_rx(ieee, dev, skb, rx_stats, - wds != NULL)) { - case AP_RX_CONTINUE_NOT_AUTHORIZED: - frame_authorized = 0; - break; - case AP_RX_CONTINUE: - frame_authorized = 1; - break; - case AP_RX_DROP: - goto rx_dropped; - case AP_RX_EXIT: - goto rx_exit; - } - } -#endif - /* Nullfunc frames may have PS-bit set, so they must be passed to - * hostap_handle_sta_rx() before being dropped here. */ - if (stype != IEEE80211_STYPE_DATA && - stype != IEEE80211_STYPE_DATA_CFACK && - stype != IEEE80211_STYPE_DATA_CFPOLL && - stype != IEEE80211_STYPE_DATA_CFACKPOLL&& - stype != IEEE80211_STYPE_QOS_DATA//add by David,2006.8.4 - ) { - if (stype != IEEE80211_STYPE_NULLFUNC) - IEEE80211_DEBUG_DROP( - "RX: dropped data frame " - "with no data (type=0x%02x, " - "subtype=0x%02x, len=%d)\n", - type, stype, skb->len); - goto rx_dropped; - } - if (memcmp(bssid, ieee->current_network.bssid, ETH_ALEN)) - goto rx_dropped; - -#ifdef ENABLE_LPS - if ((ieee->iw_mode == IW_MODE_INFRA) && (ieee->sta_sleep == 1) - && (ieee->polling)) { - if (WLAN_FC_MORE_DATA(fc)) { - /* more data bit is set, let's request a new frame from the AP */ - ieee80211_sta_ps_send_pspoll_frame(ieee); - } else { - ieee->polling = false; - } - } -#endif - - ieee->need_sw_enc = 0; - - if((!rx_stats->Decrypted)){ - ieee->need_sw_enc = 1; - } - - /* skb: hdr + (possibly fragmented, possibly encrypted) payload */ - - if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) && - (keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0) - { - printk("decrypt frame error\n"); - goto rx_dropped; - } - - - hdr = (struct ieee80211_hdr_4addr *) skb->data; - - /* skb: hdr + (possibly fragmented) plaintext payload */ - // PR: FIXME: hostap has additional conditions in the "if" below: - // ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) && - if ((frag != 0 || (fc & IEEE80211_FCTL_MOREFRAGS))) { - int flen; - struct sk_buff *frag_skb = ieee80211_frag_cache_get(ieee, hdr); - IEEE80211_DEBUG_FRAG("Rx Fragment received (%u)\n", frag); - - if (!frag_skb) { - IEEE80211_DEBUG(IEEE80211_DL_RX | IEEE80211_DL_FRAG, - "Rx cannot get skb from fragment " - "cache (morefrag=%d seq=%u frag=%u)\n", - (fc & IEEE80211_FCTL_MOREFRAGS) != 0, - WLAN_GET_SEQ_SEQ(sc), frag); - goto rx_dropped; - } - flen = skb->len; - if (frag != 0) - flen -= hdrlen; - - if (frag_skb->tail + flen > frag_skb->end) { - printk(KERN_WARNING "%s: host decrypted and " - "reassembled frame did not fit skb\n", - dev->name); - ieee80211_frag_cache_invalidate(ieee, hdr); - goto rx_dropped; - } - - if (frag == 0) { - /* copy first fragment (including full headers) into - * beginning of the fragment cache skb */ - memcpy(skb_put(frag_skb, flen), skb->data, flen); - } else { - /* append frame payload to the end of the fragment - * cache skb */ - memcpy(skb_put(frag_skb, flen), skb->data + hdrlen, - flen); - } - dev_kfree_skb_any(skb); - skb = NULL; - - if (fc & IEEE80211_FCTL_MOREFRAGS) { - /* more fragments expected - leave the skb in fragment - * cache for now; it will be delivered to upper layers - * after all fragments have been received */ - goto rx_exit; - } - - /* this was the last fragment and the frame will be - * delivered, so remove skb from fragment cache */ - skb = frag_skb; - hdr = (struct ieee80211_hdr_4addr *) skb->data; - ieee80211_frag_cache_invalidate(ieee, hdr); - } - - /* skb: hdr + (possible reassembled) full MSDU payload; possibly still - * encrypted/authenticated */ - if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) && - ieee80211_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt)) - { - printk("==>decrypt msdu error\n"); - goto rx_dropped; - } - - //added by amy for AP roaming - ieee->LinkDetectInfo.NumRecvDataInPeriod++; - ieee->LinkDetectInfo.NumRxOkInPeriod++; - - hdr = (struct ieee80211_hdr_4addr *) skb->data; - if((!is_multicast_ether_addr(hdr->addr1)) && (!is_broadcast_ether_addr(hdr->addr1))) - unicast_packet = true; - - if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep) { - if (/*ieee->ieee802_1x &&*/ - ieee80211_is_eapol_frame(ieee, skb, hdrlen)) { - -#ifdef CONFIG_IEEE80211_DEBUG - /* pass unencrypted EAPOL frames even if encryption is - * configured */ - struct eapol *eap = (struct eapol *)(skb->data + - 24); - IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n", - eap_get_type(eap->type)); -#endif - } else { - IEEE80211_DEBUG_DROP( - "encryption configured, but RX " - "frame not encrypted (SA=%pM)\n", - hdr->addr2); - goto rx_dropped; - } - } - -#ifdef CONFIG_IEEE80211_DEBUG - if (crypt && !(fc & IEEE80211_FCTL_WEP) && - ieee80211_is_eapol_frame(ieee, skb, hdrlen)) { - struct eapol *eap = (struct eapol *)(skb->data + - 24); - IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n", - eap_get_type(eap->type)); - } -#endif - - if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep && - !ieee80211_is_eapol_frame(ieee, skb, hdrlen)) { - IEEE80211_DEBUG_DROP( - "dropped unencrypted RX data " - "frame from %pM" - " (drop_unencrypted=1)\n", - hdr->addr2); - goto rx_dropped; - } -//added by amy for reorder - if(ieee->current_network.qos_data.active && IsQoSDataFrame(skb->data) - && !is_multicast_ether_addr(hdr->addr1) && !is_broadcast_ether_addr(hdr->addr1)) - { - TID = Frame_QoSTID(skb->data); - SeqNum = WLAN_GET_SEQ_SEQ(sc); - GetTs(ieee,(PTS_COMMON_INFO*) &pTS,hdr->addr2,TID,RX_DIR,true); - if(TID !=0 && TID !=3) - { - ieee->bis_any_nonbepkts = true; - } - } - -//added by amy for reorder - /* skb: hdr + (possible reassembled) full plaintext payload */ - payload = skb->data + hdrlen; - - rxb = kmalloc(sizeof(struct ieee80211_rxb), GFP_ATOMIC); - if(rxb == NULL) - { - IEEE80211_DEBUG(IEEE80211_DL_ERR,"%s(): kmalloc rxb error\n",__FUNCTION__); - goto rx_dropped; - } - /* to parse amsdu packets */ - /* qos data packets & reserved bit is 1 */ - if(parse_subframe(ieee, skb,rx_stats,rxb,src,dst) == 0) { - /* only to free rxb, and not submit the packets to upper layer */ - for(i =0; i < rxb->nr_subframes; i++) { - dev_kfree_skb(rxb->subframes[i]); - } - kfree(rxb); - rxb = NULL; - goto rx_dropped; - } - -#ifdef ENABLE_LPS - if(unicast_packet) - { - if (type == IEEE80211_FTYPE_DATA) - { - - if(ieee->bIsAggregateFrame) - ieee->LinkDetectInfo.NumRxUnicastOkInPeriod+=rxb->nr_subframes; - else - ieee->LinkDetectInfo.NumRxUnicastOkInPeriod++; - - // 2009.03.03 Leave DC mode immediately when detect high traffic - if((ieee->state == IEEE80211_LINKED) /*&& !MgntInitAdapterInProgress(pMgntInfo)*/) - { - if( ((ieee->LinkDetectInfo.NumRxUnicastOkInPeriod +ieee->LinkDetectInfo.NumTxOkInPeriod) > 8 ) || - (ieee->LinkDetectInfo.NumRxUnicastOkInPeriod > 2) ) - { - if(ieee->LeisurePSLeave) - ieee->LeisurePSLeave(ieee); - } - } - } - } -#endif - - ieee->last_rx_ps_time = jiffies; -//added by amy for reorder - if(ieee->pHTInfo->bCurRxReorderEnable == false ||pTS == NULL){ -//added by amy for reorder - for(i = 0; i<rxb->nr_subframes; i++) { - struct sk_buff *sub_skb = rxb->subframes[i]; - - if (sub_skb) { - /* convert hdr + possible LLC headers into Ethernet header */ - ethertype = (sub_skb->data[6] << 8) | sub_skb->data[7]; - if (sub_skb->len >= 8 && - ((memcmp(sub_skb->data, rfc1042_header, SNAP_SIZE) == 0 && - ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) || - memcmp(sub_skb->data, bridge_tunnel_header, SNAP_SIZE) == 0)) { - /* remove RFC1042 or Bridge-Tunnel encapsulation and - * replace EtherType */ - skb_pull(sub_skb, SNAP_SIZE); - memcpy(skb_push(sub_skb, ETH_ALEN), src, ETH_ALEN); - memcpy(skb_push(sub_skb, ETH_ALEN), dst, ETH_ALEN); - } else { - u16 len; - /* Leave Ethernet header part of hdr and full payload */ - len = htons(sub_skb->len); - memcpy(skb_push(sub_skb, 2), &len, 2); - memcpy(skb_push(sub_skb, ETH_ALEN), src, ETH_ALEN); - memcpy(skb_push(sub_skb, ETH_ALEN), dst, ETH_ALEN); - } - - stats->rx_packets++; - stats->rx_bytes += sub_skb->len; - if(is_multicast_ether_addr(dst)) { - stats->multicast++; - } - - /* Indicat the packets to upper layer */ - sub_skb->protocol = eth_type_trans(sub_skb, dev); - memset(sub_skb->cb, 0, sizeof(sub_skb->cb)); - sub_skb->dev = dev; - sub_skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */ - netif_rx(sub_skb); - } - } - kfree(rxb); - rxb = NULL; - - } - else - { - IEEE80211_DEBUG(IEEE80211_DL_REORDER,"%s(): REORDER ENABLE AND PTS not NULL, and we will enter RxReorderIndicatePacket()\n",__FUNCTION__); - RxReorderIndicatePacket(ieee, rxb, pTS, SeqNum); - } -#ifndef JOHN_NOCPY - dev_kfree_skb(skb); -#endif - - rx_exit: -#ifdef NOT_YET - if (sta) - hostap_handle_sta_release(sta); -#endif - return 1; - - rx_dropped: - kfree(rxb); - rxb = NULL; - stats->rx_dropped++; - - /* Returning 0 indicates to caller that we have not handled the SKB-- - * so it is still allocated and can be used again by underlying - * hardware as a DMA target */ - return 0; -} - -#define MGMT_FRAME_FIXED_PART_LENGTH 0x24 - -static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 }; - -/* -* Make the structure we read from the beacon packet to have -* the right values -*/ -static int ieee80211_verify_qos_info(struct ieee80211_qos_information_element - *info_element, int sub_type) -{ - - if (info_element->qui_subtype != sub_type) - return -1; - if (memcmp(info_element->qui, qos_oui, QOS_OUI_LEN)) - return -1; - if (info_element->qui_type != QOS_OUI_TYPE) - return -1; - if (info_element->version != QOS_VERSION_1) - return -1; - - return 0; -} - - -/* - * Parse a QoS parameter element - */ -static int ieee80211_read_qos_param_element(struct ieee80211_qos_parameter_info - *element_param, struct ieee80211_info_element - *info_element) -{ - int ret = 0; - u16 size = sizeof(struct ieee80211_qos_parameter_info) - 2; - - if ((info_element == NULL) || (element_param == NULL)) - return -1; - - if (info_element->id == QOS_ELEMENT_ID && info_element->len == size) { - memcpy(element_param->info_element.qui, info_element->data, - info_element->len); - element_param->info_element.elementID = info_element->id; - element_param->info_element.length = info_element->len; - } else - ret = -1; - if (ret == 0) - ret = ieee80211_verify_qos_info(&element_param->info_element, - QOS_OUI_PARAM_SUB_TYPE); - return ret; -} - -/* - * Parse a QoS information element - */ -static int ieee80211_read_qos_info_element(struct - ieee80211_qos_information_element - *element_info, struct ieee80211_info_element - *info_element) -{ - int ret = 0; - u16 size = sizeof(struct ieee80211_qos_information_element) - 2; - - if (element_info == NULL) - return -1; - if (info_element == NULL) - return -1; - - if ((info_element->id == QOS_ELEMENT_ID) && (info_element->len == size)) { - memcpy(element_info->qui, info_element->data, - info_element->len); - element_info->elementID = info_element->id; - element_info->length = info_element->len; - } else - ret = -1; - - if (ret == 0) - ret = ieee80211_verify_qos_info(element_info, - QOS_OUI_INFO_SUB_TYPE); - return ret; -} - - -/* - * Write QoS parameters from the ac parameters. - */ -static int ieee80211_qos_convert_ac_to_parameters(struct - ieee80211_qos_parameter_info - *param_elm, struct - ieee80211_qos_parameters - *qos_param) -{ - int rc = 0; - int i; - struct ieee80211_qos_ac_parameter *ac_params; - u8 aci; - - for (i = 0; i < QOS_QUEUE_NUM; i++) { - ac_params = &(param_elm->ac_params_record[i]); - - aci = (ac_params->aci_aifsn & 0x60) >> 5; - - if(aci >= QOS_QUEUE_NUM) - continue; - qos_param->aifs[aci] = (ac_params->aci_aifsn) & 0x0f; - - /* WMM spec P.11: The minimum value for AIFSN shall be 2 */ - qos_param->aifs[aci] = (qos_param->aifs[aci] < 2) ? 2:qos_param->aifs[aci]; - - qos_param->cw_min[aci] = ac_params->ecw_min_max & 0x0F; - - qos_param->cw_max[aci] = (ac_params->ecw_min_max & 0xF0) >> 4; - - qos_param->flag[aci] = - (ac_params->aci_aifsn & 0x10) ? 0x01 : 0x00; - qos_param->tx_op_limit[aci] = le16_to_cpu(ac_params->tx_op_limit); - } - return rc; -} - -/* - * we have a generic data element which it may contain QoS information or - * parameters element. check the information element length to decide - * which type to read - */ -static int ieee80211_parse_qos_info_param_IE(struct ieee80211_info_element - *info_element, - struct ieee80211_network *network) -{ - int rc = 0; - struct ieee80211_qos_parameters *qos_param = NULL; - struct ieee80211_qos_information_element qos_info_element; - - rc = ieee80211_read_qos_info_element(&qos_info_element, info_element); - - if (rc == 0) { - network->qos_data.param_count = qos_info_element.ac_info & 0x0F; - network->flags |= NETWORK_HAS_QOS_INFORMATION; - } else { - struct ieee80211_qos_parameter_info param_element; - - rc = ieee80211_read_qos_param_element(¶m_element, - info_element); - if (rc == 0) { - qos_param = &(network->qos_data.parameters); - ieee80211_qos_convert_ac_to_parameters(¶m_element, - qos_param); - network->flags |= NETWORK_HAS_QOS_PARAMETERS; - network->qos_data.param_count = - param_element.info_element.ac_info & 0x0F; - } - } - - if (rc == 0) { - IEEE80211_DEBUG_QOS("QoS is supported\n"); - network->qos_data.supported = 1; - } - return rc; -} - -#ifdef CONFIG_IEEE80211_DEBUG -#define MFIE_STRING(x) case MFIE_TYPE_ ##x: return #x - -static const char *get_info_element_string(u16 id) -{ - switch (id) { - MFIE_STRING(SSID); - MFIE_STRING(RATES); - MFIE_STRING(FH_SET); - MFIE_STRING(DS_SET); - MFIE_STRING(CF_SET); - MFIE_STRING(TIM); - MFIE_STRING(IBSS_SET); - MFIE_STRING(COUNTRY); - MFIE_STRING(HOP_PARAMS); - MFIE_STRING(HOP_TABLE); - MFIE_STRING(REQUEST); - MFIE_STRING(CHALLENGE); - MFIE_STRING(POWER_CONSTRAINT); - MFIE_STRING(POWER_CAPABILITY); - MFIE_STRING(TPC_REQUEST); - MFIE_STRING(TPC_REPORT); - MFIE_STRING(SUPP_CHANNELS); - MFIE_STRING(CSA); - MFIE_STRING(MEASURE_REQUEST); - MFIE_STRING(MEASURE_REPORT); - MFIE_STRING(QUIET); - MFIE_STRING(IBSS_DFS); - // MFIE_STRING(ERP_INFO); - MFIE_STRING(RSN); - MFIE_STRING(RATES_EX); - MFIE_STRING(GENERIC); - MFIE_STRING(QOS_PARAMETER); - default: - return "UNKNOWN"; - } -} -#endif - -#ifdef ENABLE_DOT11D -static inline void ieee80211_extract_country_ie( - struct ieee80211_device *ieee, - struct ieee80211_info_element *info_element, - struct ieee80211_network *network, - u8 * addr2 -) -{ - if(IS_DOT11D_ENABLE(ieee)) - { - if(info_element->len!= 0) - { - memcpy(network->CountryIeBuf, info_element->data, info_element->len); - network->CountryIeLen = info_element->len; - - if(!IS_COUNTRY_IE_VALID(ieee)) - { - Dot11d_UpdateCountryIe(ieee, addr2, info_element->len, info_element->data); - } - } - - // - // 070305, rcnjko: I update country IE watch dog here because - // some AP (e.g. Cisco 1242) don't include country IE in their - // probe response frame. - // - if(IS_EQUAL_CIE_SRC(ieee, addr2) ) - { - UPDATE_CIE_WATCHDOG(ieee); - } - } - -} -#endif - -int ieee80211_parse_info_param(struct ieee80211_device *ieee, - struct ieee80211_info_element *info_element, - u16 length, - struct ieee80211_network *network, - struct ieee80211_rx_stats *stats) -{ - u8 i; - short offset; - u16 tmp_htcap_len=0; - u16 tmp_htinfo_len=0; - u16 ht_realtek_agg_len=0; - u8 ht_realtek_agg_buf[MAX_IE_LEN]; -#ifdef CONFIG_IEEE80211_DEBUG - char rates_str[64]; - char *p; -#endif - - while (length >= sizeof(*info_element)) { - if (sizeof(*info_element) + info_element->len > length) { - IEEE80211_DEBUG_MGMT("Info elem: parse failed: " - "info_element->len + 2 > left : " - "info_element->len+2=%zd left=%d, id=%d.\n", - info_element->len + - sizeof(*info_element), - length, info_element->id); - /* We stop processing but don't return an error here - * because some misbehaviour APs break this rule. ie. - * Orinoco AP1000. */ - break; - } - - switch (info_element->id) { - case MFIE_TYPE_SSID: - if (ieee80211_is_empty_essid(info_element->data, - info_element->len)) { - network->flags |= NETWORK_EMPTY_ESSID; - break; - } - - network->ssid_len = min(info_element->len, - (u8) IW_ESSID_MAX_SIZE); - memcpy(network->ssid, info_element->data, network->ssid_len); - if (network->ssid_len < IW_ESSID_MAX_SIZE) - memset(network->ssid + network->ssid_len, 0, - IW_ESSID_MAX_SIZE - network->ssid_len); - - IEEE80211_DEBUG_MGMT("MFIE_TYPE_SSID: '%s' len=%d.\n", - network->ssid, network->ssid_len); - break; - - case MFIE_TYPE_RATES: -#ifdef CONFIG_IEEE80211_DEBUG - p = rates_str; -#endif - network->rates_len = min(info_element->len, - MAX_RATES_LENGTH); - for (i = 0; i < network->rates_len; i++) { - network->rates[i] = info_element->data[i]; -#ifdef CONFIG_IEEE80211_DEBUG - p += snprintf(p, sizeof(rates_str) - - (p - rates_str), "%02X ", - network->rates[i]); -#endif - if (ieee80211_is_ofdm_rate - (info_element->data[i])) { - network->flags |= NETWORK_HAS_OFDM; - if (info_element->data[i] & - IEEE80211_BASIC_RATE_MASK) - network->flags &= - ~NETWORK_HAS_CCK; - } - } - - IEEE80211_DEBUG_MGMT("MFIE_TYPE_RATES: '%s' (%d)\n", - rates_str, network->rates_len); - break; - - case MFIE_TYPE_RATES_EX: -#ifdef CONFIG_IEEE80211_DEBUG - p = rates_str; -#endif - network->rates_ex_len = min(info_element->len, - MAX_RATES_EX_LENGTH); - for (i = 0; i < network->rates_ex_len; i++) { - network->rates_ex[i] = info_element->data[i]; -#ifdef CONFIG_IEEE80211_DEBUG - p += snprintf(p, sizeof(rates_str) - - (p - rates_str), "%02X ", - network->rates[i]); -#endif - if (ieee80211_is_ofdm_rate - (info_element->data[i])) { - network->flags |= NETWORK_HAS_OFDM; - if (info_element->data[i] & - IEEE80211_BASIC_RATE_MASK) - network->flags &= - ~NETWORK_HAS_CCK; - } - } - - IEEE80211_DEBUG_MGMT("MFIE_TYPE_RATES_EX: '%s' (%d)\n", - rates_str, network->rates_ex_len); - break; - - case MFIE_TYPE_DS_SET: - IEEE80211_DEBUG_MGMT("MFIE_TYPE_DS_SET: %d\n", - info_element->data[0]); - network->channel = info_element->data[0]; - break; - - case MFIE_TYPE_FH_SET: - IEEE80211_DEBUG_MGMT("MFIE_TYPE_FH_SET: ignored\n"); - break; - - case MFIE_TYPE_CF_SET: - IEEE80211_DEBUG_MGMT("MFIE_TYPE_CF_SET: ignored\n"); - break; - - case MFIE_TYPE_TIM: - if(info_element->len < 4) - break; - - network->tim.tim_count = info_element->data[0]; - network->tim.tim_period = info_element->data[1]; - - network->dtim_period = info_element->data[1]; - if(ieee->state != IEEE80211_LINKED) - break; - //we use jiffies for legacy Power save - network->last_dtim_sta_time[0] = jiffies; - network->last_dtim_sta_time[1] = stats->mac_time[1]; - - network->dtim_data = IEEE80211_DTIM_VALID; - - if(info_element->data[0] != 0) - break; - - if(info_element->data[2] & 1) - network->dtim_data |= IEEE80211_DTIM_MBCAST; - - offset = (info_element->data[2] >> 1)*2; - - if(ieee->assoc_id < 8*offset || - ieee->assoc_id > 8*(offset + info_element->len -3)) - - break; - - offset = (ieee->assoc_id / 8) - offset;// + ((aid % 8)? 0 : 1) ; - - if(info_element->data[3+offset] & (1<<(ieee->assoc_id%8))) - network->dtim_data |= IEEE80211_DTIM_UCAST; - - break; - - case MFIE_TYPE_ERP: - network->erp_value = info_element->data[0]; - network->flags |= NETWORK_HAS_ERP_VALUE; - IEEE80211_DEBUG_MGMT("MFIE_TYPE_ERP_SET: %d\n", - network->erp_value); - break; - case MFIE_TYPE_IBSS_SET: - network->atim_window = info_element->data[0]; - IEEE80211_DEBUG_MGMT("MFIE_TYPE_IBSS_SET: %d\n", - network->atim_window); - break; - - case MFIE_TYPE_CHALLENGE: - IEEE80211_DEBUG_MGMT("MFIE_TYPE_CHALLENGE: ignored\n"); - break; - - case MFIE_TYPE_GENERIC: - IEEE80211_DEBUG_MGMT("MFIE_TYPE_GENERIC: %d bytes\n", - info_element->len); - if (!ieee80211_parse_qos_info_param_IE(info_element, - network)) - break; - - if (info_element->len >= 4 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x50 && - info_element->data[2] == 0xf2 && - info_element->data[3] == 0x01) { - network->wpa_ie_len = min(info_element->len + 2, - MAX_WPA_IE_LEN); - memcpy(network->wpa_ie, info_element, - network->wpa_ie_len); - break; - } - -#ifdef THOMAS_TURBO - if (info_element->len == 7 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0xe0 && - info_element->data[2] == 0x4c && - info_element->data[3] == 0x01 && - info_element->data[4] == 0x02) { - network->Turbo_Enable = 1; - } -#endif - - //for HTcap and HTinfo parameters - if(tmp_htcap_len == 0){ - if(info_element->len >= 4 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x90 && - info_element->data[2] == 0x4c && - info_element->data[3] == 0x033){ - - tmp_htcap_len = min(info_element->len,(u8)MAX_IE_LEN); - if(tmp_htcap_len != 0){ - network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC; - network->bssht.bdHTCapLen = tmp_htcap_len > sizeof(network->bssht.bdHTCapBuf)?\ - sizeof(network->bssht.bdHTCapBuf):tmp_htcap_len; - memcpy(network->bssht.bdHTCapBuf,info_element->data,network->bssht.bdHTCapLen); - } - } - if(tmp_htcap_len != 0) - network->bssht.bdSupportHT = true; - else - network->bssht.bdSupportHT = false; - } - - - if(tmp_htinfo_len == 0){ - if(info_element->len >= 4 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x90 && - info_element->data[2] == 0x4c && - info_element->data[3] == 0x034){ - - tmp_htinfo_len = min(info_element->len,(u8)MAX_IE_LEN); - if(tmp_htinfo_len != 0){ - network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC; - if(tmp_htinfo_len){ - network->bssht.bdHTInfoLen = tmp_htinfo_len > sizeof(network->bssht.bdHTInfoBuf)?\ - sizeof(network->bssht.bdHTInfoBuf):tmp_htinfo_len; - memcpy(network->bssht.bdHTInfoBuf,info_element->data,network->bssht.bdHTInfoLen); - } - - } - - } - } - - if(ieee->aggregation){ - if(network->bssht.bdSupportHT){ - if(info_element->len >= 4 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0xe0 && - info_element->data[2] == 0x4c && - info_element->data[3] == 0x02){ - - ht_realtek_agg_len = min(info_element->len,(u8)MAX_IE_LEN); - memcpy(ht_realtek_agg_buf,info_element->data,info_element->len); - - } - if(ht_realtek_agg_len >= 5){ - network->bssht.bdRT2RTAggregation = true; - - if((ht_realtek_agg_buf[4] == 1) && (ht_realtek_agg_buf[5] & 0x02)) - network->bssht.bdRT2RTLongSlotTime = true; - } - } - - } - - if((info_element->len >= 3 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x05 && - info_element->data[2] == 0xb5) || - (info_element->len >= 3 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x0a && - info_element->data[2] == 0xf7) || - (info_element->len >= 3 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x10 && - info_element->data[2] == 0x18)){ - - network->broadcom_cap_exist = true; - - } - - if(info_element->len >= 3 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x0c && - info_element->data[2] == 0x43) - { - network->ralink_cap_exist = true; - } - else - network->ralink_cap_exist = false; - //added by amy for atheros AP - if((info_element->len >= 3 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x03 && - info_element->data[2] == 0x7f) || - (info_element->len >= 3 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x13 && - info_element->data[2] == 0x74)) - { - network->atheros_cap_exist = true; - } - else - network->atheros_cap_exist = false; - - if ((info_element->len >= 3 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x50 && - info_element->data[2] == 0x43) ) - { - network->marvell_cap_exist = true; - } - - - if(info_element->len >= 3 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x40 && - info_element->data[2] == 0x96) - { - network->cisco_cap_exist = true; - } - else - network->cisco_cap_exist = false; - //added by amy for LEAP of cisco - if(info_element->len > 4 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x40 && - info_element->data[2] == 0x96 && - info_element->data[3] == 0x01) - { - if(info_element->len == 6) - { - memcpy(network->CcxRmState, &info_element[4], 2); - if(network->CcxRmState[0] != 0) - { - network->bCcxRmEnable = true; - } - else - network->bCcxRmEnable = false; - // - // CCXv4 Table 59-1 MBSSID Masks. - // - network->MBssidMask = network->CcxRmState[1] & 0x07; - if(network->MBssidMask != 0) - { - network->bMBssidValid = true; - network->MBssidMask = 0xff << (network->MBssidMask); - cpMacAddr(network->MBssid, network->bssid); - network->MBssid[5] &= network->MBssidMask; - } - else - { - network->bMBssidValid = false; - } - } - else - { - network->bCcxRmEnable = false; - } - } - if(info_element->len > 4 && - info_element->data[0] == 0x00 && - info_element->data[1] == 0x40 && - info_element->data[2] == 0x96 && - info_element->data[3] == 0x03) - { - if(info_element->len == 5) - { - network->bWithCcxVerNum = true; - network->BssCcxVerNumber = info_element->data[4]; - } - else - { - network->bWithCcxVerNum = false; - network->BssCcxVerNumber = 0; - } - } - break; - - case MFIE_TYPE_RSN: - IEEE80211_DEBUG_MGMT("MFIE_TYPE_RSN: %d bytes\n", - info_element->len); - network->rsn_ie_len = min(info_element->len + 2, - MAX_WPA_IE_LEN); - memcpy(network->rsn_ie, info_element, - network->rsn_ie_len); - break; - - //HT related element. - case MFIE_TYPE_HT_CAP: - IEEE80211_DEBUG_SCAN("MFIE_TYPE_HT_CAP: %d bytes\n", - info_element->len); - tmp_htcap_len = min(info_element->len,(u8)MAX_IE_LEN); - if(tmp_htcap_len != 0){ - network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC; - network->bssht.bdHTCapLen = tmp_htcap_len > sizeof(network->bssht.bdHTCapBuf)?\ - sizeof(network->bssht.bdHTCapBuf):tmp_htcap_len; - memcpy(network->bssht.bdHTCapBuf,info_element->data,network->bssht.bdHTCapLen); - - //If peer is HT, but not WMM, call QosSetLegacyWMMParamWithHT() - // windows driver will update WMM parameters each beacon received once connected - // Linux driver is a bit different. - network->bssht.bdSupportHT = true; - } - else - network->bssht.bdSupportHT = false; - break; - - - case MFIE_TYPE_HT_INFO: - IEEE80211_DEBUG_SCAN("MFIE_TYPE_HT_INFO: %d bytes\n", - info_element->len); - tmp_htinfo_len = min(info_element->len,(u8)MAX_IE_LEN); - if(tmp_htinfo_len){ - network->bssht.bdHTSpecVer = HT_SPEC_VER_IEEE; - network->bssht.bdHTInfoLen = tmp_htinfo_len > sizeof(network->bssht.bdHTInfoBuf)?\ - sizeof(network->bssht.bdHTInfoBuf):tmp_htinfo_len; - memcpy(network->bssht.bdHTInfoBuf,info_element->data,network->bssht.bdHTInfoLen); - } - break; - - case MFIE_TYPE_AIRONET: - IEEE80211_DEBUG_SCAN("MFIE_TYPE_AIRONET: %d bytes\n", - info_element->len); - if(info_element->len >IE_CISCO_FLAG_POSITION) - { - network->bWithAironetIE = true; - - // CCX 1 spec v1.13, A01.1 CKIP Negotiation (page23): - // "A Cisco access point advertises support for CKIP in beacon and probe response packets, - // by adding an Aironet element and setting one or both of the CKIP negotiation bits." - if( (info_element->data[IE_CISCO_FLAG_POSITION]&SUPPORT_CKIP_MIC) || - (info_element->data[IE_CISCO_FLAG_POSITION]&SUPPORT_CKIP_PK) ) - { - network->bCkipSupported = true; - } - else - { - network->bCkipSupported = false; - } - } - else - { - network->bWithAironetIE = false; - network->bCkipSupported = false; - } - break; - case MFIE_TYPE_QOS_PARAMETER: - printk(KERN_ERR - "QoS Error need to parse QOS_PARAMETER IE\n"); - break; - -#ifdef ENABLE_DOT11D - case MFIE_TYPE_COUNTRY: - IEEE80211_DEBUG_SCAN("MFIE_TYPE_COUNTRY: %d bytes\n", - info_element->len); - ieee80211_extract_country_ie(ieee, info_element, network, network->bssid);//addr2 is same as addr3 when from an AP - break; -#endif - - default: - IEEE80211_DEBUG_MGMT - ("Unsupported info element: %s (%d)\n", - get_info_element_string(info_element->id), - info_element->id); - break; - } - - length -= sizeof(*info_element) + info_element->len; - info_element = - (struct ieee80211_info_element *)&info_element-> - data[info_element->len]; - } - - if(!network->atheros_cap_exist && !network->broadcom_cap_exist && - !network->cisco_cap_exist && !network->ralink_cap_exist && !network->bssht.bdRT2RTAggregation && - !network->marvell_cap_exist) - { - network->unknown_cap_exist = true; - } - else - { - network->unknown_cap_exist = false; - } - return 0; -} - -static inline u8 ieee80211_SignalStrengthTranslate( - u8 CurrSS - ) -{ - u8 RetSS; - - // Step 1. Scale mapping. - if(CurrSS >= 71 && CurrSS <= 100) - { - RetSS = 90 + ((CurrSS - 70) / 3); - } - else if(CurrSS >= 41 && CurrSS <= 70) - { - RetSS = 78 + ((CurrSS - 40) / 3); - } - else if(CurrSS >= 31 && CurrSS <= 40) - { - RetSS = 66 + (CurrSS - 30); - } - else if(CurrSS >= 21 && CurrSS <= 30) - { - RetSS = 54 + (CurrSS - 20); - } - else if(CurrSS >= 5 && CurrSS <= 20) - { - RetSS = 42 + (((CurrSS - 5) * 2) / 3); - } - else if(CurrSS == 4) - { - RetSS = 36; - } - else if(CurrSS == 3) - { - RetSS = 27; - } - else if(CurrSS == 2) - { - RetSS = 18; - } - else if(CurrSS == 1) - { - RetSS = 9; - } - else - { - RetSS = CurrSS; - } - - return RetSS; -} - -long ieee80211_translate_todbm(u8 signal_strength_index )// 0-100 index. -{ - long signal_power; // in dBm. - - // Translate to dBm (x=0.5y-95). - signal_power = (long)((signal_strength_index + 1) >> 1); - signal_power -= 95; - - return signal_power; -} - -static inline int ieee80211_network_init( - struct ieee80211_device *ieee, - struct ieee80211_probe_response *beacon, - struct ieee80211_network *network, - struct ieee80211_rx_stats *stats) -{ - network->qos_data.active = 0; - network->qos_data.supported = 0; - network->qos_data.param_count = 0; - network->qos_data.old_param_count = 0; - - /* Pull out fixed field data */ - memcpy(network->bssid, beacon->header.addr3, ETH_ALEN); - network->capability = le16_to_cpu(beacon->capability); - network->last_scanned = jiffies; - network->time_stamp[0] = le32_to_cpu(beacon->time_stamp[0]); - network->time_stamp[1] = le32_to_cpu(beacon->time_stamp[1]); - network->beacon_interval = le32_to_cpu(beacon->beacon_interval); - /* Where to pull this? beacon->listen_interval;*/ - network->listen_interval = 0x0A; - network->rates_len = network->rates_ex_len = 0; - network->last_associate = 0; - network->ssid_len = 0; - network->flags = 0; - network->atim_window = 0; - network->erp_value = (network->capability & WLAN_CAPABILITY_IBSS) ? - 0x3 : 0x0; - network->berp_info_valid = false; - network->broadcom_cap_exist = false; - network->ralink_cap_exist = false; - network->atheros_cap_exist = false; - network->marvell_cap_exist = false; - network->cisco_cap_exist = false; - network->unknown_cap_exist = false; -#ifdef THOMAS_TURBO - network->Turbo_Enable = 0; -#endif -#ifdef ENABLE_DOT11D - network->CountryIeLen = 0; - memset(network->CountryIeBuf, 0, MAX_IE_LEN); -#endif -//Initialize HT parameters - HTInitializeBssDesc(&network->bssht); - if (stats->freq == IEEE80211_52GHZ_BAND) { - /* for A band (No DS info) */ - network->channel = stats->received_channel; - } else - network->flags |= NETWORK_HAS_CCK; - - network->wpa_ie_len = 0; - network->rsn_ie_len = 0; - - if (ieee80211_parse_info_param - (ieee,beacon->info_element, stats->len - sizeof(*beacon), network, stats)) - return 1; - - network->mode = 0; - if (stats->freq == IEEE80211_52GHZ_BAND) - network->mode = IEEE_A; - else { - if (network->flags & NETWORK_HAS_OFDM) - network->mode |= IEEE_G; - if (network->flags & NETWORK_HAS_CCK) - network->mode |= IEEE_B; - } - - if (network->mode == 0) { - IEEE80211_DEBUG_SCAN("Filtered out '%s (%pM)' " - "network.\n", - escape_essid(network->ssid, - network->ssid_len), - network->bssid); - return 1; - } - - if(network->bssht.bdSupportHT){ - if(network->mode == IEEE_A) - network->mode = IEEE_N_5G; - else if(network->mode & (IEEE_G | IEEE_B)) - network->mode = IEEE_N_24G; - } - if (ieee80211_is_empty_essid(network->ssid, network->ssid_len)) - network->flags |= NETWORK_EMPTY_ESSID; - - stats->signal = 30 + (stats->SignalStrength * 70) / 100; - stats->noise = ieee80211_translate_todbm((u8)(100-stats->signal)) -25; - - memcpy(&network->stats, stats, sizeof(network->stats)); - - return 0; -} - -static inline int is_same_network(struct ieee80211_network *src, - struct ieee80211_network *dst, struct ieee80211_device* ieee) -{ - /* A network is only a duplicate if the channel, BSSID, ESSID - * and the capability field (in particular IBSS and BSS) all match. - * We treat all <hidden> with the same BSSID and channel - * as one network */ - return (((src->ssid_len == dst->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && - (src->channel == dst->channel) && - !memcmp(src->bssid, dst->bssid, ETH_ALEN) && - (!memcmp(src->ssid, dst->ssid, src->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && - ((src->capability & WLAN_CAPABILITY_IBSS) == - (dst->capability & WLAN_CAPABILITY_IBSS)) && - ((src->capability & WLAN_CAPABILITY_BSS) == - (dst->capability & WLAN_CAPABILITY_BSS))); -} - -static inline void update_network(struct ieee80211_network *dst, - struct ieee80211_network *src) -{ - int qos_active; - u8 old_param; - - memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats)); - dst->capability = src->capability; - memcpy(dst->rates, src->rates, src->rates_len); - dst->rates_len = src->rates_len; - memcpy(dst->rates_ex, src->rates_ex, src->rates_ex_len); - dst->rates_ex_len = src->rates_ex_len; - if(src->ssid_len > 0) - { - memset(dst->ssid, 0, dst->ssid_len); - dst->ssid_len = src->ssid_len; - memcpy(dst->ssid, src->ssid, src->ssid_len); - } - dst->mode = src->mode; - dst->flags = src->flags; - dst->time_stamp[0] = src->time_stamp[0]; - dst->time_stamp[1] = src->time_stamp[1]; - if (src->flags & NETWORK_HAS_ERP_VALUE) - { - dst->erp_value = src->erp_value; - dst->berp_info_valid = src->berp_info_valid = true; - } - dst->beacon_interval = src->beacon_interval; - dst->listen_interval = src->listen_interval; - dst->atim_window = src->atim_window; - dst->dtim_period = src->dtim_period; - dst->dtim_data = src->dtim_data; - dst->last_dtim_sta_time[0] = src->last_dtim_sta_time[0]; - dst->last_dtim_sta_time[1] = src->last_dtim_sta_time[1]; - memcpy(&dst->tim, &src->tim, sizeof(struct ieee80211_tim_parameters)); - - dst->bssht.bdSupportHT = src->bssht.bdSupportHT; - dst->bssht.bdRT2RTAggregation = src->bssht.bdRT2RTAggregation; - dst->bssht.bdHTCapLen= src->bssht.bdHTCapLen; - memcpy(dst->bssht.bdHTCapBuf,src->bssht.bdHTCapBuf,src->bssht.bdHTCapLen); - dst->bssht.bdHTInfoLen= src->bssht.bdHTInfoLen; - memcpy(dst->bssht.bdHTInfoBuf,src->bssht.bdHTInfoBuf,src->bssht.bdHTInfoLen); - dst->bssht.bdHTSpecVer = src->bssht.bdHTSpecVer; - dst->bssht.bdRT2RTLongSlotTime = src->bssht.bdRT2RTLongSlotTime; - dst->broadcom_cap_exist = src->broadcom_cap_exist; - dst->ralink_cap_exist = src->ralink_cap_exist; - dst->atheros_cap_exist = src->atheros_cap_exist; - dst->marvell_cap_exist = src->marvell_cap_exist; - dst->cisco_cap_exist = src->cisco_cap_exist; - dst->unknown_cap_exist = src->unknown_cap_exist; - memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len); - dst->wpa_ie_len = src->wpa_ie_len; - memcpy(dst->rsn_ie, src->rsn_ie, src->rsn_ie_len); - dst->rsn_ie_len = src->rsn_ie_len; - - dst->last_scanned = jiffies; - /* qos related parameters */ - qos_active = dst->qos_data.active; - old_param = dst->qos_data.param_count; - if(dst->flags & NETWORK_HAS_QOS_MASK){ - //not update QOS paramter in beacon, as most AP will set all these parameter to 0.//WB - } - else { - dst->qos_data.supported = src->qos_data.supported; - dst->qos_data.param_count = src->qos_data.param_count; - } - - if(dst->qos_data.supported == 1) { - dst->QoS_Enable = 1; - if(dst->ssid_len) - IEEE80211_DEBUG_QOS - ("QoS the network %s is QoS supported\n", - dst->ssid); - else - IEEE80211_DEBUG_QOS - ("QoS the network is QoS supported\n"); - } - dst->qos_data.active = qos_active; - dst->qos_data.old_param_count = old_param; - - /* dst->last_associate is not overwritten */ - dst->wmm_info = src->wmm_info; //sure to exist in beacon or probe response frame. - if(src->wmm_param[0].ac_aci_acm_aifsn|| \ - src->wmm_param[1].ac_aci_acm_aifsn|| \ - src->wmm_param[2].ac_aci_acm_aifsn|| \ - src->wmm_param[3].ac_aci_acm_aifsn) { - memcpy(dst->wmm_param, src->wmm_param, WME_AC_PRAM_LEN); - } -#ifdef THOMAS_TURBO - dst->Turbo_Enable = src->Turbo_Enable; -#endif - -#ifdef ENABLE_DOT11D - dst->CountryIeLen = src->CountryIeLen; - memcpy(dst->CountryIeBuf, src->CountryIeBuf, src->CountryIeLen); -#endif - - //added by amy for LEAP - dst->bWithAironetIE = src->bWithAironetIE; - dst->bCkipSupported = src->bCkipSupported; - memcpy(dst->CcxRmState,src->CcxRmState,2); - dst->bCcxRmEnable = src->bCcxRmEnable; - dst->MBssidMask = src->MBssidMask; - dst->bMBssidValid = src->bMBssidValid; - memcpy(dst->MBssid,src->MBssid,6); - dst->bWithCcxVerNum = src->bWithCcxVerNum; - dst->BssCcxVerNumber = src->BssCcxVerNumber; - -} - -static inline int is_beacon(__le16 fc) -{ - return (WLAN_FC_GET_STYPE(le16_to_cpu(fc)) == IEEE80211_STYPE_BEACON); -} - -static inline void ieee80211_process_probe_response( - struct ieee80211_device *ieee, - struct ieee80211_probe_response *beacon, - struct ieee80211_rx_stats *stats) -{ - struct ieee80211_network network; - struct ieee80211_network *target; - struct ieee80211_network *oldest = NULL; -#ifdef CONFIG_IEEE80211_DEBUG - struct ieee80211_info_element *info_element = &beacon->info_element[0]; -#endif - unsigned long flags; - short renew; - - memset(&network, 0, sizeof(struct ieee80211_network)); - IEEE80211_DEBUG_SCAN( - "'%s' (%pM): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n", - escape_essid(info_element->data, info_element->len), - beacon->header.addr3, - (beacon->capability & (1<<0xf)) ? '1' : '0', - (beacon->capability & (1<<0xe)) ? '1' : '0', - (beacon->capability & (1<<0xd)) ? '1' : '0', - (beacon->capability & (1<<0xc)) ? '1' : '0', - (beacon->capability & (1<<0xb)) ? '1' : '0', - (beacon->capability & (1<<0xa)) ? '1' : '0', - (beacon->capability & (1<<0x9)) ? '1' : '0', - (beacon->capability & (1<<0x8)) ? '1' : '0', - (beacon->capability & (1<<0x7)) ? '1' : '0', - (beacon->capability & (1<<0x6)) ? '1' : '0', - (beacon->capability & (1<<0x5)) ? '1' : '0', - (beacon->capability & (1<<0x4)) ? '1' : '0', - (beacon->capability & (1<<0x3)) ? '1' : '0', - (beacon->capability & (1<<0x2)) ? '1' : '0', - (beacon->capability & (1<<0x1)) ? '1' : '0', - (beacon->capability & (1<<0x0)) ? '1' : '0'); - - if (ieee80211_network_init(ieee, beacon, &network, stats)) { - IEEE80211_DEBUG_SCAN("Dropped '%s' (%pM) via %s.\n", - escape_essid(info_element->data, - info_element->len), - beacon->header.addr3, - WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == - IEEE80211_STYPE_PROBE_RESP ? - "PROBE RESPONSE" : "BEACON"); - return; - } - -#ifdef ENABLE_DOT11D - // For Asus EeePc request, - // (1) if wireless adapter receive get any 802.11d country code in AP beacon, - // wireless adapter should follow the country code. - // (2) If there is no any country code in beacon, - // then wireless adapter should do active scan from ch1~11 and - // passive scan from ch12~14 - - if( !IsLegalChannel(ieee, network.channel) ) - return; - if(ieee->bGlobalDomain) - { - if (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_PROBE_RESP) - { - // Case 1: Country code - if(IS_COUNTRY_IE_VALID(ieee) ) - { - if( !IsLegalChannel(ieee, network.channel) ) - { - printk("GetScanInfo(): For Country code, filter probe response at channel(%d).\n", network.channel); - return; - } - } - // Case 2: No any country code. - else - { - // Filter over channel ch12~14 - if(network.channel > 11) - { - printk("GetScanInfo(): For Global Domain, filter probe response at channel(%d).\n", network.channel); - return; - } - } - } - else - { - // Case 1: Country code - if(IS_COUNTRY_IE_VALID(ieee) ) - { - if( !IsLegalChannel(ieee, network.channel) ) - { - printk("GetScanInfo(): For Country code, filter beacon at channel(%d).\n",network.channel); - return; - } - } - // Case 2: No any country code. - else - { - // Filter over channel ch12~14 - if(network.channel > 14) - { - printk("GetScanInfo(): For Global Domain, filter beacon at channel(%d).\n",network.channel); - return; - } - } - } - } -#endif - - /* The network parsed correctly -- so now we scan our known networks - * to see if we can find it in our list. - * - * NOTE: This search is definitely not optimized. Once its doing - * the "right thing" we'll optimize it for efficiency if - * necessary */ - - /* Search for this entry in the list and update it if it is - * already there. */ - - spin_lock_irqsave(&ieee->lock, flags); - - if(is_same_network(&ieee->current_network, &network, ieee)) { - update_network(&ieee->current_network, &network); - if((ieee->current_network.mode == IEEE_N_24G || ieee->current_network.mode == IEEE_G) - && ieee->current_network.berp_info_valid){ - if(ieee->current_network.erp_value& ERP_UseProtection) - ieee->current_network.buseprotection = true; - else - ieee->current_network.buseprotection = false; - } - if(is_beacon(beacon->header.frame_ctl)) - { - if(ieee->state == IEEE80211_LINKED) - ieee->LinkDetectInfo.NumRecvBcnInPeriod++; - } - else //hidden AP - network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & ieee->current_network.flags); - } - - list_for_each_entry(target, &ieee->network_list, list) { - if (is_same_network(target, &network, ieee)) - break; - if ((oldest == NULL) || - (target->last_scanned < oldest->last_scanned)) - oldest = target; - } - - /* If we didn't find a match, then get a new network slot to initialize - * with this beacon's information */ - if (&target->list == &ieee->network_list) { - if (list_empty(&ieee->network_free_list)) { - /* If there are no more slots, expire the oldest */ - list_del(&oldest->list); - target = oldest; - IEEE80211_DEBUG_SCAN("Expired '%s' (%pM) from " - "network list.\n", - escape_essid(target->ssid, - target->ssid_len), - target->bssid); - } else { - /* Otherwise just pull from the free list */ - target = list_entry(ieee->network_free_list.next, - struct ieee80211_network, list); - list_del(ieee->network_free_list.next); - } - - -#ifdef CONFIG_IEEE80211_DEBUG - IEEE80211_DEBUG_SCAN("Adding '%s' (%pM) via %s.\n", - escape_essid(network.ssid, - network.ssid_len), - network.bssid, - WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == - IEEE80211_STYPE_PROBE_RESP ? - "PROBE RESPONSE" : "BEACON"); -#endif - memcpy(target, &network, sizeof(*target)); - list_add_tail(&target->list, &ieee->network_list); - } else { - IEEE80211_DEBUG_SCAN("Updating '%s' (%pM) via %s.\n", - escape_essid(target->ssid, - target->ssid_len), - target->bssid, - WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == - IEEE80211_STYPE_PROBE_RESP ? - "PROBE RESPONSE" : "BEACON"); - - /* we have an entry and we are going to update it. But this entry may - * be already expired. In this case we do the same as we found a new - * net and call the new_net handler - */ - renew = !time_after(target->last_scanned + ieee->scan_age, jiffies); - //YJ,add,080819,for hidden ap - if(is_beacon(beacon->header.frame_ctl) == 0) - network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & target->flags); - if(((network.flags & NETWORK_EMPTY_ESSID) == NETWORK_EMPTY_ESSID) \ - && (((network.ssid_len > 0) && (strncmp(target->ssid, network.ssid, network.ssid_len)))\ - ||((ieee->current_network.ssid_len == network.ssid_len)&&(strncmp(ieee->current_network.ssid, network.ssid, network.ssid_len) == 0)&&(ieee->state == IEEE80211_NOLINK)))) - renew = 1; - //YJ,add,080819,for hidden ap,end - - update_network(target, &network); - } - - spin_unlock_irqrestore(&ieee->lock, flags); - if (is_beacon(beacon->header.frame_ctl)&&is_same_network(&ieee->current_network, &network, ieee)&&\ - (ieee->state == IEEE80211_LINKED)) { - if(ieee->handle_beacon != NULL) { - ieee->handle_beacon(ieee, beacon, &ieee->current_network); - } - } -} - -void ieee80211_rx_mgt(struct ieee80211_device *ieee, - struct ieee80211_hdr_4addr *header, - struct ieee80211_rx_stats *stats) -{ - if(WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP && - WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON) - ieee->last_rx_ps_time = jiffies; - - switch (WLAN_FC_GET_STYPE(header->frame_ctl)) { - - case IEEE80211_STYPE_BEACON: - IEEE80211_DEBUG_MGMT("received BEACON (%d)\n", - WLAN_FC_GET_STYPE(header->frame_ctl)); - IEEE80211_DEBUG_SCAN("Beacon\n"); - ieee80211_process_probe_response( - ieee, (struct ieee80211_probe_response *)header, stats); - - if(ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED && - ieee->iw_mode == IW_MODE_INFRA && - ieee->state == IEEE80211_LINKED)) - { - tasklet_schedule(&ieee->ps_task); - } - - break; - - case IEEE80211_STYPE_PROBE_RESP: - IEEE80211_DEBUG_MGMT("received PROBE RESPONSE (%d)\n", - WLAN_FC_GET_STYPE(header->frame_ctl)); - IEEE80211_DEBUG_SCAN("Probe response\n"); - ieee80211_process_probe_response( - ieee, (struct ieee80211_probe_response *)header, stats); - break; - - } -} diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c deleted file mode 100644 index 60e9a09..0000000 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac.c +++ /dev/null @@ -1,3278 +0,0 @@ -/* IEEE 802.11 SoftMAC layer - * Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it> - * - * Mostly extracted from the rtl8180-sa2400 driver for the - * in-kernel generic ieee802.11 stack. - * - * Few lines might be stolen from other part of the ieee80211 - * stack. Copyright who own it's copyright - * - * WPA code stolen from the ipw2200 driver. - * Copyright who own it's copyright. - * - * released under the GPL - */ - - -#include "ieee80211.h" - -#include <linux/random.h> -#include <linux/delay.h> -#include <linux/slab.h> -#include <asm/uaccess.h> -#ifdef ENABLE_DOT11D -#include "dot11d.h" -#endif - -u8 rsn_authen_cipher_suite[16][4] = { - {0x00,0x0F,0xAC,0x00}, //Use group key, //Reserved - {0x00,0x0F,0xAC,0x01}, //WEP-40 //RSNA default - {0x00,0x0F,0xAC,0x02}, //TKIP //NONE //{used just as default} - {0x00,0x0F,0xAC,0x03}, //WRAP-historical - {0x00,0x0F,0xAC,0x04}, //CCMP - {0x00,0x0F,0xAC,0x05}, //WEP-104 -}; - -short ieee80211_is_54g(struct ieee80211_network net) -{ - return ((net.rates_ex_len > 0) || (net.rates_len > 4)); -} - -short ieee80211_is_shortslot(struct ieee80211_network net) -{ - return (net.capability & WLAN_CAPABILITY_SHORT_SLOT); -} - -/* returns the total length needed for pleacing the RATE MFIE - * tag and the EXTENDED RATE MFIE tag if needed. - * It encludes two bytes per tag for the tag itself and its len - */ -unsigned int ieee80211_MFIE_rate_len(struct ieee80211_device *ieee) -{ - unsigned int rate_len = 0; - - if (ieee->modulation & IEEE80211_CCK_MODULATION) - rate_len = IEEE80211_CCK_RATE_LEN + 2; - - if (ieee->modulation & IEEE80211_OFDM_MODULATION) - - rate_len += IEEE80211_OFDM_RATE_LEN + 2; - - return rate_len; -} - -/* pleace the MFIE rate, tag to the memory (double) poined. - * Then it updates the pointer so that - * it points after the new MFIE tag added. - */ -void ieee80211_MFIE_Brate(struct ieee80211_device *ieee, u8 **tag_p) -{ - u8 *tag = *tag_p; - - if (ieee->modulation & IEEE80211_CCK_MODULATION){ - *tag++ = MFIE_TYPE_RATES; - *tag++ = 4; - *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB; - *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB; - *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB; - *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB; - } - - /* We may add an option for custom rates that specific HW might support */ - *tag_p = tag; -} - -void ieee80211_MFIE_Grate(struct ieee80211_device *ieee, u8 **tag_p) -{ - u8 *tag = *tag_p; - - if (ieee->modulation & IEEE80211_OFDM_MODULATION){ - - *tag++ = MFIE_TYPE_RATES_EX; - *tag++ = 8; - *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB; - *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB; - *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB; - *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB; - *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB; - *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB; - *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB; - *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB; - - } - - /* We may add an option for custom rates that specific HW might support */ - *tag_p = tag; -} - - -void ieee80211_WMM_Info(struct ieee80211_device *ieee, u8 **tag_p) { - u8 *tag = *tag_p; - - *tag++ = MFIE_TYPE_GENERIC; //0 - *tag++ = 7; - *tag++ = 0x00; - *tag++ = 0x50; - *tag++ = 0xf2; - *tag++ = 0x02;//5 - *tag++ = 0x00; - *tag++ = 0x01; -#ifdef SUPPORT_USPD - if(ieee->current_network.wmm_info & 0x80) { - *tag++ = 0x0f|MAX_SP_Len; - } else { - *tag++ = MAX_SP_Len; - } -#else - *tag++ = MAX_SP_Len; -#endif - *tag_p = tag; -} - -#ifdef THOMAS_TURBO -void ieee80211_TURBO_Info(struct ieee80211_device *ieee, u8 **tag_p) { - u8 *tag = *tag_p; - - *tag++ = MFIE_TYPE_GENERIC; //0 - *tag++ = 7; - *tag++ = 0x00; - *tag++ = 0xe0; - *tag++ = 0x4c; - *tag++ = 0x01;//5 - *tag++ = 0x02; - *tag++ = 0x11; - *tag++ = 0x00; - - *tag_p = tag; - printk(KERN_ALERT "This is enable turbo mode IE process\n"); -} -#endif - -void enqueue_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb) -{ - int nh; - nh = (ieee->mgmt_queue_head +1) % MGMT_QUEUE_NUM; - -/* - * if the queue is full but we have newer frames then - * just overwrites the oldest. - * - * if (nh == ieee->mgmt_queue_tail) - * return -1; - */ - ieee->mgmt_queue_head = nh; - ieee->mgmt_queue_ring[nh] = skb; -} - -struct sk_buff *dequeue_mgmt(struct ieee80211_device *ieee) -{ - struct sk_buff *ret; - - if(ieee->mgmt_queue_tail == ieee->mgmt_queue_head) - return NULL; - - ret = ieee->mgmt_queue_ring[ieee->mgmt_queue_tail]; - - ieee->mgmt_queue_tail = - (ieee->mgmt_queue_tail+1) % MGMT_QUEUE_NUM; - - return ret; -} - -void init_mgmt_queue(struct ieee80211_device *ieee) -{ - ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0; -} - -u8 MgntQuery_MgntFrameTxRate(struct ieee80211_device *ieee) -{ - PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; - u8 rate; - - // 2008/01/25 MH For broadcom, MGNT frame set as OFDM 6M. - if(pHTInfo->IOTAction & HT_IOT_ACT_MGNT_USE_CCK_6M) - rate = 0x0c; - else - rate = ieee->basic_rate & 0x7f; - - if(rate == 0){ - // 2005.01.26, by rcnjko. - if(ieee->mode == IEEE_A|| - ieee->mode== IEEE_N_5G|| - (ieee->mode== IEEE_N_24G&&!pHTInfo->bCurSuppCCK)) - rate = 0x0c; - else - rate = 0x02; - } - - return rate; -} - - -void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl); - -inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee) -{ - unsigned long flags; - short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE; - struct ieee80211_hdr_3addr *header= - (struct ieee80211_hdr_3addr *) skb->data; - - cb_desc *tcb_desc = (cb_desc *)(skb->cb + 8); - spin_lock_irqsave(&ieee->lock, flags); - - /* called with 2nd param 0, no mgmt lock required */ - ieee80211_sta_wakeup(ieee,0); - - tcb_desc->queue_index = MGNT_QUEUE; - tcb_desc->data_rate = MgntQuery_MgntFrameTxRate(ieee); - tcb_desc->RATRIndex = 7; - tcb_desc->bTxDisableRateFallBack = 1; - tcb_desc->bTxUseDriverAssingedRate = 1; - - if(single){ - if(ieee->queue_stop){ - enqueue_mgmt(ieee,skb); - }else{ - header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4); - - if (ieee->seq_ctrl[0] == 0xFFF) - ieee->seq_ctrl[0] = 0; - else - ieee->seq_ctrl[0]++; - - /* avoid watchdog triggers */ - ieee->softmac_data_hard_start_xmit(skb, ieee, ieee->basic_rate); - } - - spin_unlock_irqrestore(&ieee->lock, flags); - }else{ - spin_unlock_irqrestore(&ieee->lock, flags); - spin_lock(&ieee->mgmt_tx_lock); - - header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); - - if (ieee->seq_ctrl[0] == 0xFFF) - ieee->seq_ctrl[0] = 0; - else - ieee->seq_ctrl[0]++; - - /* check wether the managed packet queued greater than 5 */ - if(!ieee->check_nic_enough_desc(ieee, tcb_desc->queue_index)|| - (skb_queue_len(&ieee->skb_waitQ[tcb_desc->queue_index]) != 0)|| - (ieee->queue_stop) ) { - /* insert the skb packet to the management queue */ - /* as for the completion function, it does not need - * to check it any more. - * */ - skb_queue_tail(&ieee->skb_waitQ[tcb_desc->queue_index], skb); - } else { - ieee->softmac_hard_start_xmit(skb, ieee); - } - spin_unlock(&ieee->mgmt_tx_lock); - } -} - -inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee) -{ - - short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE; - struct ieee80211_hdr_3addr *header = - (struct ieee80211_hdr_3addr *) skb->data; - cb_desc *tcb_desc = (cb_desc *)(skb->cb + 8); - - tcb_desc->queue_index = MGNT_QUEUE; - tcb_desc->data_rate = MgntQuery_MgntFrameTxRate(ieee); - tcb_desc->RATRIndex = 7; - tcb_desc->bTxDisableRateFallBack = 1; - tcb_desc->bTxUseDriverAssingedRate = 1; - if(single){ - - header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); - - if (ieee->seq_ctrl[0] == 0xFFF) - ieee->seq_ctrl[0] = 0; - else - ieee->seq_ctrl[0]++; - - /* avoid watchdog triggers */ - ieee->softmac_data_hard_start_xmit(skb, ieee, ieee->basic_rate); - - }else{ - - header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); - - if (ieee->seq_ctrl[0] == 0xFFF) - ieee->seq_ctrl[0] = 0; - else - ieee->seq_ctrl[0]++; - - ieee->softmac_hard_start_xmit(skb, ieee); - - } -} - -inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee) -{ - unsigned int len,rate_len; - u8 *tag; - struct sk_buff *skb; - struct ieee80211_probe_request *req; - - len = ieee->current_network.ssid_len; - - rate_len = ieee80211_MFIE_rate_len(ieee); - - skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) + - 2 + len + rate_len + ieee->tx_headroom); - if (!skb) - return NULL; - - skb_reserve(skb, ieee->tx_headroom); - - req = (struct ieee80211_probe_request *) skb_put(skb,sizeof(struct ieee80211_probe_request)); - req->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ); - req->header.duration_id = 0; //FIXME: is this OK ? - - memset(req->header.addr1, 0xff, ETH_ALEN); - memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN); - memset(req->header.addr3, 0xff, ETH_ALEN); - - tag = (u8 *) skb_put(skb,len+2+rate_len); - - *tag++ = MFIE_TYPE_SSID; - *tag++ = len; - memcpy(tag, ieee->current_network.ssid, len); - tag += len; - - ieee80211_MFIE_Brate(ieee,&tag); - ieee80211_MFIE_Grate(ieee,&tag); - return skb; -} - -struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee); -void ieee80211_send_beacon(struct ieee80211_device *ieee) -{ - struct sk_buff *skb; - if(!ieee->ieee_up) - return; - - skb = ieee80211_get_beacon_(ieee); - - if (skb){ - softmac_mgmt_xmit(skb, ieee); - ieee->softmac_stats.tx_beacons++; - } - - if(ieee->beacon_txing && ieee->ieee_up){ - mod_timer(&ieee->beacon_timer,jiffies+(MSECS(ieee->current_network.beacon_interval-5))); - } -} - - -void ieee80211_send_beacon_cb(unsigned long _ieee) -{ - struct ieee80211_device *ieee = - (struct ieee80211_device *) _ieee; - unsigned long flags; - - spin_lock_irqsave(&ieee->beacon_lock, flags); - ieee80211_send_beacon(ieee); - spin_unlock_irqrestore(&ieee->beacon_lock, flags); -} - - -void ieee80211_send_probe(struct ieee80211_device *ieee) -{ - struct sk_buff *skb; - - skb = ieee80211_probe_req(ieee); - if (skb){ - softmac_mgmt_xmit(skb, ieee); - ieee->softmac_stats.tx_probe_rq++; - } -} - -void ieee80211_send_probe_requests(struct ieee80211_device *ieee) -{ - if (ieee->active_scan && (ieee->softmac_features & IEEE_SOFTMAC_PROBERQ)){ - ieee80211_send_probe(ieee); - ieee80211_send_probe(ieee); - } -} - -/* this performs syncro scan blocking the caller until all channels - * in the allowed channel map has been checked. - */ -void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee) -{ - short ch = 0; -#ifdef ENABLE_DOT11D - u8 channel_map[MAX_CHANNEL_NUMBER+1]; - memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1); -#endif - down(&ieee->scan_sem); - - while(1) - { - - do{ - ch++; - if (ch > MAX_CHANNEL_NUMBER) - goto out; /* scan completed */ -#ifdef ENABLE_DOT11D - }while(!channel_map[ch]); -#else - }while(!ieee->channel_map[ch]); -#endif - - /* this function can be called in two situations - * 1- We have switched to ad-hoc mode and we are - * performing a complete syncro scan before conclude - * there are no interesting cell and to create a - * new one. In this case the link state is - * IEEE80211_NOLINK until we found an interesting cell. - * If so the ieee8021_new_net, called by the RX path - * will set the state to IEEE80211_LINKED, so we stop - * scanning - * 2- We are linked and the root uses run iwlist scan. - * So we switch to IEEE80211_LINKED_SCANNING to remember - * that we are still logically linked (not interested in - * new network events, despite for updating the net list, - * but we are temporarly 'unlinked' as the driver shall - * not filter RX frames and the channel is changing. - * So the only situation in witch are interested is to check - * if the state become LINKED because of the #1 situation - */ - - if (ieee->state == IEEE80211_LINKED) - goto out; - ieee->set_chan(ieee, ch); -#ifdef ENABLE_DOT11D - if(channel_map[ch] == 1) -#endif - ieee80211_send_probe_requests(ieee); - - /* this prevent excessive time wait when we - * need to wait for a syncro scan to end.. - */ - if(ieee->state < IEEE80211_LINKED) - ; - else - if (ieee->sync_scan_hurryup) - goto out; - - - msleep_interruptible_rsl(IEEE80211_SOFTMAC_SCAN_TIME); - - } -out: - if(ieee->state < IEEE80211_LINKED){ - ieee->actscanning = false; - up(&ieee->scan_sem); - } - else{ - ieee->sync_scan_hurryup = 0; -#ifdef ENABLE_DOT11D - if(IS_DOT11D_ENABLE(ieee)) - DOT11D_ScanComplete(ieee); -#endif - up(&ieee->scan_sem); -} -} - - -void ieee80211_softmac_scan_wq(struct work_struct *work) -{ - struct delayed_work *dwork = container_of(work, struct delayed_work, work); - struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, softmac_scan_wq); - static short watchdog = 0; - u8 last_channel = ieee->current_network.channel; -#ifdef ENABLE_DOT11D - u8 channel_map[MAX_CHANNEL_NUMBER+1]; - memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1); -#endif - if(!ieee->ieee_up) - return; - down(&ieee->scan_sem); - do{ - ieee->current_network.channel = - (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER; - if (watchdog++ > MAX_CHANNEL_NUMBER) { - /* if current channel is not in channel map, set to default channel. */ -#ifdef ENABLE_DOT11D - if (!channel_map[ieee->current_network.channel]) { -#else - if (!ieee->channel_map[ieee->current_network.channel]) { -#endif - ieee->current_network.channel = 6; - goto out; /* no good chans */ - } - } -#ifdef ENABLE_DOT11D - }while(!channel_map[ieee->current_network.channel]); -#else - }while(!ieee->channel_map[ieee->current_network.channel]); -#endif - if (ieee->scanning == 0 ) - goto out; - ieee->set_chan(ieee, ieee->current_network.channel); -#ifdef ENABLE_DOT11D - if(channel_map[ieee->current_network.channel] == 1) -#endif - ieee80211_send_probe_requests(ieee); - - - queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME); - - up(&ieee->scan_sem); - return; -out: -#ifdef ENABLE_DOT11D - if(IS_DOT11D_ENABLE(ieee)) - DOT11D_ScanComplete(ieee); -#endif - ieee->current_network.channel = last_channel; - ieee->actscanning = false; - watchdog = 0; - ieee->scanning = 0; - up(&ieee->scan_sem); -} - -void ieee80211_beacons_start(struct ieee80211_device *ieee) -{ - unsigned long flags; - spin_lock_irqsave(&ieee->beacon_lock,flags); - - ieee->beacon_txing = 1; - ieee80211_send_beacon(ieee); - - spin_unlock_irqrestore(&ieee->beacon_lock,flags); -} - -void ieee80211_beacons_stop(struct ieee80211_device *ieee) -{ - unsigned long flags; - - spin_lock_irqsave(&ieee->beacon_lock,flags); - - ieee->beacon_txing = 0; - del_timer_sync(&ieee->beacon_timer); - - spin_unlock_irqrestore(&ieee->beacon_lock,flags); - -} - - -void ieee80211_stop_send_beacons(struct ieee80211_device *ieee) -{ - if(ieee->stop_send_beacons) - ieee->stop_send_beacons(ieee); - if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS) - ieee80211_beacons_stop(ieee); -} - - -void ieee80211_start_send_beacons(struct ieee80211_device *ieee) -{ - if(ieee->start_send_beacons) - ieee->start_send_beacons(ieee); - if(ieee->softmac_features & IEEE_SOFTMAC_BEACONS) - ieee80211_beacons_start(ieee); -} - - -void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee) -{ - down(&ieee->scan_sem); - - if (ieee->scanning == 1){ - ieee->scanning = 0; - - cancel_delayed_work(&ieee->softmac_scan_wq); - } - - up(&ieee->scan_sem); -} - -void ieee80211_stop_scan(struct ieee80211_device *ieee) -{ - if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) - ieee80211_softmac_stop_scan(ieee); - else - ieee->stop_scan(ieee); -} - -/* called with ieee->lock held */ -void ieee80211_rtl_start_scan(struct ieee80211_device *ieee) -{ -#ifdef ENABLE_IPS - if(ieee->ieee80211_ips_leave_wq != NULL) - ieee->ieee80211_ips_leave_wq(ieee); -#endif - -#ifdef ENABLE_DOT11D - if(IS_DOT11D_ENABLE(ieee) ) - { - if(IS_COUNTRY_IE_VALID(ieee)) - { - RESET_CIE_WATCHDOG(ieee); - } - } -#endif - if (ieee->softmac_features & IEEE_SOFTMAC_SCAN){ - if (ieee->scanning == 0){ - ieee->scanning = 1; - queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, 0); - } - }else - ieee->start_scan(ieee); - -} - -/* called with wx_sem held */ -void ieee80211_start_scan_syncro(struct ieee80211_device *ieee) -{ -#ifdef ENABLE_DOT11D - if(IS_DOT11D_ENABLE(ieee) ) - { - if(IS_COUNTRY_IE_VALID(ieee)) - { - RESET_CIE_WATCHDOG(ieee); - } - } -#endif - ieee->sync_scan_hurryup = 0; - if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) - ieee80211_softmac_scan_syncro(ieee); - else - ieee->scan_syncro(ieee); - -} - -inline struct sk_buff *ieee80211_authentication_req(struct ieee80211_network *beacon, - struct ieee80211_device *ieee, int challengelen) -{ - struct sk_buff *skb; - struct ieee80211_authentication *auth; - int len = sizeof(struct ieee80211_authentication) + challengelen + ieee->tx_headroom; - - - skb = dev_alloc_skb(len); - if (!skb) return NULL; - - skb_reserve(skb, ieee->tx_headroom); - auth = (struct ieee80211_authentication *) - skb_put(skb, sizeof(struct ieee80211_authentication)); - - auth->header.frame_ctl = IEEE80211_STYPE_AUTH; - if (challengelen) auth->header.frame_ctl |= IEEE80211_FCTL_WEP; - - auth->header.duration_id = 0x013a; //FIXME - - memcpy(auth->header.addr1, beacon->bssid, ETH_ALEN); - memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN); - memcpy(auth->header.addr3, beacon->bssid, ETH_ALEN); - - if(ieee->auth_mode == 0) - auth->algorithm = WLAN_AUTH_OPEN; - else if(ieee->auth_mode == 1) - auth->algorithm = WLAN_AUTH_SHARED_KEY; - else if(ieee->auth_mode == 2) - auth->algorithm = WLAN_AUTH_OPEN;//0x80; - printk("=================>%s():auth->algorithm is %d\n",__FUNCTION__,auth->algorithm); - auth->transaction = cpu_to_le16(ieee->associate_seq); - ieee->associate_seq++; - - auth->status = cpu_to_le16(WLAN_STATUS_SUCCESS); - - return skb; - -} - - -static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *dest) -{ - u8 *tag; - int beacon_size; - struct ieee80211_probe_response *beacon_buf; - struct sk_buff *skb = NULL; - int encrypt; - int atim_len,erp_len; - struct ieee80211_crypt_data* crypt; - - char *ssid = ieee->current_network.ssid; - int ssid_len = ieee->current_network.ssid_len; - int rate_len = ieee->current_network.rates_len+2; - int rate_ex_len = ieee->current_network.rates_ex_len; - int wpa_ie_len = ieee->wpa_ie_len; - u8 erpinfo_content = 0; - - u8* tmp_ht_cap_buf; - u8 tmp_ht_cap_len=0; - u8* tmp_ht_info_buf; - u8 tmp_ht_info_len=0; - PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; - u8* tmp_generic_ie_buf=NULL; - u8 tmp_generic_ie_len=0; - - if(rate_ex_len > 0) rate_ex_len+=2; - - if(ieee->current_network.capability & WLAN_CAPABILITY_IBSS) - atim_len = 4; - else - atim_len = 0; - - if(ieee80211_is_54g(ieee->current_network)) - erp_len = 3; - else - erp_len = 0; - - crypt = ieee->crypt[ieee->tx_keyidx]; - - - encrypt = ieee->host_encrypt && crypt && crypt->ops && - ((0 == strcmp(crypt->ops->name, "WEP") || wpa_ie_len)); - //HT ralated element - - tmp_ht_cap_buf =(u8*) &(ieee->pHTInfo->SelfHTCap); - tmp_ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap); - tmp_ht_info_buf =(u8*) &(ieee->pHTInfo->SelfHTInfo); - tmp_ht_info_len = sizeof(ieee->pHTInfo->SelfHTInfo); - HTConstructCapabilityElement(ieee, tmp_ht_cap_buf, &tmp_ht_cap_len,encrypt); - HTConstructInfoElement(ieee,tmp_ht_info_buf,&tmp_ht_info_len, encrypt); - - - if(pHTInfo->bRegRT2RTAggregation) - { - tmp_generic_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer; - tmp_generic_ie_len = sizeof(ieee->pHTInfo->szRT2RTAggBuffer); - HTConstructRT2RTAggElement(ieee, tmp_generic_ie_buf, &tmp_generic_ie_len); - } - - beacon_size = sizeof(struct ieee80211_probe_response)+2+ - ssid_len - +3 //channel - +rate_len - +rate_ex_len - +atim_len - +erp_len - +wpa_ie_len - +ieee->tx_headroom; - skb = dev_alloc_skb(beacon_size); - if (!skb) - return NULL; - skb_reserve(skb, ieee->tx_headroom); - beacon_buf = (struct ieee80211_probe_response*) skb_put(skb, (beacon_size - ieee->tx_headroom)); - memcpy (beacon_buf->header.addr1, dest,ETH_ALEN); - memcpy (beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN); - memcpy (beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN); - - beacon_buf->header.duration_id = 0; //FIXME - beacon_buf->beacon_interval = - cpu_to_le16(ieee->current_network.beacon_interval); - beacon_buf->capability = - cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_IBSS); - beacon_buf->capability |= - cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE); //add short preamble here - - if(ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT)) - beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT); - - crypt = ieee->crypt[ieee->tx_keyidx]; - if (encrypt) - beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY); - - - beacon_buf->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP); - beacon_buf->info_element[0].id = MFIE_TYPE_SSID; - beacon_buf->info_element[0].len = ssid_len; - - tag = (u8*) beacon_buf->info_element[0].data; - - memcpy(tag, ssid, ssid_len); - - tag += ssid_len; - - *(tag++) = MFIE_TYPE_RATES; - *(tag++) = rate_len-2; - memcpy(tag,ieee->current_network.rates,rate_len-2); - tag+=rate_len-2; - - *(tag++) = MFIE_TYPE_DS_SET; - *(tag++) = 1; - *(tag++) = ieee->current_network.channel; - - if(atim_len){ - u16 val16; - *(tag++) = MFIE_TYPE_IBSS_SET; - *(tag++) = 2; - val16 = cpu_to_le16(ieee->current_network.atim_window); - memcpy((u8 *)tag, (u8 *)&val16, 2); - tag+=2; - } - - if(erp_len){ - *(tag++) = MFIE_TYPE_ERP; - *(tag++) = 1; - *(tag++) = erpinfo_content; - } - if(rate_ex_len){ - *(tag++) = MFIE_TYPE_RATES_EX; - *(tag++) = rate_ex_len-2; - memcpy(tag,ieee->current_network.rates_ex,rate_ex_len-2); - tag+=rate_ex_len-2; - } - - if (wpa_ie_len) - { - if (ieee->iw_mode == IW_MODE_ADHOC) - {//as Windows will set pairwise key same as the group key which is not allowed in Linux, so set this for IOT issue. WB 2008.07.07 - memcpy(&ieee->wpa_ie[14], &ieee->wpa_ie[8], 4); - } - memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len); - tag += wpa_ie_len; - } - - return skb; -} - - -struct sk_buff* ieee80211_assoc_resp(struct ieee80211_device *ieee, u8 *dest) -{ - struct sk_buff *skb; - u8* tag; - - struct ieee80211_crypt_data* crypt; - struct ieee80211_assoc_response_frame *assoc; - short encrypt; - - unsigned int rate_len = ieee80211_MFIE_rate_len(ieee); - int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len + ieee->tx_headroom; - - skb = dev_alloc_skb(len); - - if (!skb) - return NULL; - - skb_reserve(skb, ieee->tx_headroom); - - assoc = (struct ieee80211_assoc_response_frame *) - skb_put(skb,sizeof(struct ieee80211_assoc_response_frame)); - - assoc->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP); - memcpy(assoc->header.addr1, dest,ETH_ALEN); - memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN); - memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN); - assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ? - WLAN_CAPABILITY_BSS : WLAN_CAPABILITY_IBSS); - - - if(ieee->short_slot) - assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT); - - if (ieee->host_encrypt) - crypt = ieee->crypt[ieee->tx_keyidx]; - else crypt = NULL; - - encrypt = ( crypt && crypt->ops); - - if (encrypt) - assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY); - - assoc->status = 0; - assoc->aid = cpu_to_le16(ieee->assoc_id); - if (ieee->assoc_id == 0x2007) ieee->assoc_id=0; - else ieee->assoc_id++; - - tag = (u8*) skb_put(skb, rate_len); - - ieee80211_MFIE_Brate(ieee, &tag); - ieee80211_MFIE_Grate(ieee, &tag); - - return skb; -} - -struct sk_buff* ieee80211_auth_resp(struct ieee80211_device *ieee,int status, u8 *dest) -{ - struct sk_buff *skb; - struct ieee80211_authentication *auth; - int len = ieee->tx_headroom + sizeof(struct ieee80211_authentication)+1; - - skb = dev_alloc_skb(len); - - if (!skb) - return NULL; - - skb->len = sizeof(struct ieee80211_authentication); - - auth = (struct ieee80211_authentication *)skb->data; - - auth->status = cpu_to_le16(status); - auth->transaction = cpu_to_le16(2); - auth->algorithm = cpu_to_le16(WLAN_AUTH_OPEN); - - memcpy(auth->header.addr3, ieee->dev->dev_addr, ETH_ALEN); - memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN); - memcpy(auth->header.addr1, dest, ETH_ALEN); - auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH); - return skb; - - -} - -struct sk_buff* ieee80211_null_func(struct ieee80211_device *ieee,short pwr) -{ - struct sk_buff *skb; - struct ieee80211_hdr_3addr* hdr; - - skb = dev_alloc_skb(sizeof(struct ieee80211_hdr_3addr)); - - if (!skb) - return NULL; - - hdr = (struct ieee80211_hdr_3addr*)skb_put(skb,sizeof(struct ieee80211_hdr_3addr)); - - memcpy(hdr->addr1, ieee->current_network.bssid, ETH_ALEN); - memcpy(hdr->addr2, ieee->dev->dev_addr, ETH_ALEN); - memcpy(hdr->addr3, ieee->current_network.bssid, ETH_ALEN); - - hdr->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA | - IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS | - (pwr ? IEEE80211_FCTL_PM:0)); - - return skb; - - -} - -struct sk_buff* ieee80211_pspoll_func(struct ieee80211_device *ieee) -{ - struct sk_buff *skb; - struct ieee80211_pspoll_hdr* hdr; - -#ifdef USB_USE_ALIGNMENT - u32 Tmpaddr=0; - int alignment=0; - skb = dev_alloc_skb(sizeof(struct ieee80211_pspoll_hdr) + ieee->tx_headroom + USB_512B_ALIGNMENT_SIZE); -#else - skb = dev_alloc_skb(sizeof(struct ieee80211_pspoll_hdr)+ieee->tx_headroom); -#endif - if (!skb) - return NULL; - -#ifdef USB_USE_ALIGNMENT - Tmpaddr = (u32)skb->data; - alignment = Tmpaddr & 0x1ff; - skb_reserve(skb,(USB_512B_ALIGNMENT_SIZE - alignment)); -#endif - skb_reserve(skb, ieee->tx_headroom); - - hdr = (struct ieee80211_pspoll_hdr*)skb_put(skb,sizeof(struct ieee80211_pspoll_hdr)); - - memcpy(hdr->bssid, ieee->current_network.bssid, ETH_ALEN); - memcpy(hdr->ta, ieee->dev->dev_addr, ETH_ALEN); - - hdr->aid = cpu_to_le16(ieee->assoc_id | 0xc000); - hdr->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_CTL |IEEE80211_STYPE_PSPOLL | IEEE80211_FCTL_PM); - - return skb; - -} - - -void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8* dest) -{ - struct sk_buff *buf = ieee80211_assoc_resp(ieee, dest); - - if (buf) - softmac_mgmt_xmit(buf, ieee); -} - - -void ieee80211_resp_to_auth(struct ieee80211_device *ieee, int s, u8* dest) -{ - struct sk_buff *buf = ieee80211_auth_resp(ieee, s, dest); - - if (buf) - softmac_mgmt_xmit(buf, ieee); -} - - -void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest) -{ - - - struct sk_buff *buf = ieee80211_probe_resp(ieee, dest); - if (buf) - softmac_mgmt_xmit(buf, ieee); -} - - -inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beacon,struct ieee80211_device *ieee) -{ - struct sk_buff *skb; - struct ieee80211_assoc_request_frame *hdr; - u8 *tag; - u8* ht_cap_buf = NULL; - u8 ht_cap_len=0; - u8* realtek_ie_buf=NULL; - u8 realtek_ie_len=0; - int wpa_ie_len= ieee->wpa_ie_len; - unsigned int ckip_ie_len=0; - unsigned int ccxrm_ie_len=0; - unsigned int cxvernum_ie_len=0; - struct ieee80211_crypt_data* crypt; - int encrypt; - - unsigned int rate_len = ieee80211_MFIE_rate_len(ieee); - unsigned int wmm_info_len = beacon->qos_data.supported?9:0; -#ifdef THOMAS_TURBO - unsigned int turbo_info_len = beacon->Turbo_Enable?9:0; -#endif - - int len = 0; - - crypt = ieee->crypt[ieee->tx_keyidx]; - encrypt = ieee->host_encrypt && crypt && crypt->ops && ((0 == strcmp(crypt->ops->name,"WEP") || wpa_ie_len)); - - //Include High Throuput capability && Realtek proprietary - if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT) - { - ht_cap_buf = (u8*)&(ieee->pHTInfo->SelfHTCap); - ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap); - HTConstructCapabilityElement(ieee, ht_cap_buf, &ht_cap_len, encrypt); - if(ieee->pHTInfo->bCurrentRT2RTAggregation) - { - realtek_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer; - realtek_ie_len = sizeof( ieee->pHTInfo->szRT2RTAggBuffer); - HTConstructRT2RTAggElement(ieee, realtek_ie_buf, &realtek_ie_len); - - } - } - if(ieee->qos_support){ - wmm_info_len = beacon->qos_data.supported?9:0; - } - - - if(beacon->bCkipSupported) - { - ckip_ie_len = 30+2; - } - if(beacon->bCcxRmEnable) - { - ccxrm_ie_len = 6+2; - } - if( beacon->BssCcxVerNumber >= 2 ) - { - cxvernum_ie_len = 5+2; - } -#ifdef THOMAS_TURBO - len = sizeof(struct ieee80211_assoc_request_frame)+ 2 - + beacon->ssid_len//essid tagged val - + rate_len//rates tagged val - + wpa_ie_len - + wmm_info_len - + turbo_info_len - + ht_cap_len - + realtek_ie_len - + ckip_ie_len - + ccxrm_ie_len - + cxvernum_ie_len - + ieee->tx_headroom; -#else - len = sizeof(struct ieee80211_assoc_request_frame)+ 2 - + beacon->ssid_len//essid tagged val - + rate_len//rates tagged val - + wpa_ie_len - + wmm_info_len - + ht_cap_len - + realtek_ie_len - + ckip_ie_len - + ccxrm_ie_len - + cxvernum_ie_len - + ieee->tx_headroom; -#endif - - skb = dev_alloc_skb(len); - - if (!skb) - return NULL; - - skb_reserve(skb, ieee->tx_headroom); - - hdr = (struct ieee80211_assoc_request_frame *) - skb_put(skb, sizeof(struct ieee80211_assoc_request_frame)+2); - - - hdr->header.frame_ctl = IEEE80211_STYPE_ASSOC_REQ; - hdr->header.duration_id= 37; //FIXME - memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN); - memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN); - memcpy(hdr->header.addr3, beacon->bssid, ETH_ALEN); - - memcpy(ieee->ap_mac_addr, beacon->bssid, ETH_ALEN);//for HW security, John - - hdr->capability = cpu_to_le16(WLAN_CAPABILITY_BSS); - if (beacon->capability & WLAN_CAPABILITY_PRIVACY ) - hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY); - - if (beacon->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) - hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE); //add short_preamble here - - if(ieee->short_slot) - hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT); - if (wmm_info_len) //QOS - hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_QOS); - - hdr->listen_interval = 0xa; //FIXME - - hdr->info_element[0].id = MFIE_TYPE_SSID; - - hdr->info_element[0].len = beacon->ssid_len; - tag = skb_put(skb, beacon->ssid_len); - memcpy(tag, beacon->ssid, beacon->ssid_len); - - tag = skb_put(skb, rate_len); - - ieee80211_MFIE_Brate(ieee, &tag); - ieee80211_MFIE_Grate(ieee, &tag); - // For CCX 1 S13, CKIP. Added by Annie, 2006-08-14. - if( beacon->bCkipSupported ) - { - static u8 AironetIeOui[] = {0x00, 0x01, 0x66}; // "4500-client" - u8 CcxAironetBuf[30]; - OCTET_STRING osCcxAironetIE; - - memset(CcxAironetBuf, 0,30); - osCcxAironetIE.Octet = CcxAironetBuf; - osCcxAironetIE.Length = sizeof(CcxAironetBuf); - // - // Ref. CCX test plan v3.61, 3.2.3.1 step 13. - // We want to make the device type as "4500-client". 060926, by CCW. - // - memcpy(osCcxAironetIE.Octet, AironetIeOui, sizeof(AironetIeOui)); - - // CCX1 spec V1.13, A01.1 CKIP Negotiation (page23): - // "The CKIP negotiation is started with the associate request from the client to the access point, - // containing an Aironet element with both the MIC and KP bits set." - osCcxAironetIE.Octet[IE_CISCO_FLAG_POSITION] |= (SUPPORT_CKIP_PK|SUPPORT_CKIP_MIC) ; - tag = skb_put(skb, ckip_ie_len); - *tag++ = MFIE_TYPE_AIRONET; - *tag++ = osCcxAironetIE.Length; - memcpy(tag,osCcxAironetIE.Octet,osCcxAironetIE.Length); - tag += osCcxAironetIE.Length; - } - - if(beacon->bCcxRmEnable) - { - static u8 CcxRmCapBuf[] = {0x00, 0x40, 0x96, 0x01, 0x01, 0x00}; - OCTET_STRING osCcxRmCap; - - osCcxRmCap.Octet = CcxRmCapBuf; - osCcxRmCap.Length = sizeof(CcxRmCapBuf); - tag = skb_put(skb,ccxrm_ie_len); - *tag++ = MFIE_TYPE_GENERIC; - *tag++ = osCcxRmCap.Length; - memcpy(tag,osCcxRmCap.Octet,osCcxRmCap.Length); - tag += osCcxRmCap.Length; - } - - if( beacon->BssCcxVerNumber >= 2 ) - { - u8 CcxVerNumBuf[] = {0x00, 0x40, 0x96, 0x03, 0x00}; - OCTET_STRING osCcxVerNum; - CcxVerNumBuf[4] = beacon->BssCcxVerNumber; - osCcxVerNum.Octet = CcxVerNumBuf; - osCcxVerNum.Length = sizeof(CcxVerNumBuf); - tag = skb_put(skb,cxvernum_ie_len); - *tag++ = MFIE_TYPE_GENERIC; - *tag++ = osCcxVerNum.Length; - memcpy(tag,osCcxVerNum.Octet,osCcxVerNum.Length); - tag += osCcxVerNum.Length; - } - //HT cap element - if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT){ - if(ieee->pHTInfo->ePeerHTSpecVer != HT_SPEC_VER_EWC) - { - tag = skb_put(skb, ht_cap_len); - *tag++ = MFIE_TYPE_HT_CAP; - *tag++ = ht_cap_len - 2; - memcpy(tag, ht_cap_buf,ht_cap_len -2); - tag += ht_cap_len -2; - } - } - - - //choose what wpa_supplicant gives to associate. - tag = skb_put(skb, wpa_ie_len); - if (wpa_ie_len){ - memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len); - } - - tag = skb_put(skb,wmm_info_len); - if(wmm_info_len) { - ieee80211_WMM_Info(ieee, &tag); - } -#ifdef THOMAS_TURBO - tag = skb_put(skb,turbo_info_len); - if(turbo_info_len) { - ieee80211_TURBO_Info(ieee, &tag); - } -#endif - - if(ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT){ - if(ieee->pHTInfo->ePeerHTSpecVer == HT_SPEC_VER_EWC) - { - tag = skb_put(skb, ht_cap_len); - *tag++ = MFIE_TYPE_GENERIC; - *tag++ = ht_cap_len - 2; - memcpy(tag, ht_cap_buf,ht_cap_len - 2); - tag += ht_cap_len -2; - } - - if(ieee->pHTInfo->bCurrentRT2RTAggregation){ - tag = skb_put(skb, realtek_ie_len); - *tag++ = MFIE_TYPE_GENERIC; - *tag++ = realtek_ie_len - 2; - memcpy(tag, realtek_ie_buf,realtek_ie_len -2 ); - } - } - return skb; -} - -void ieee80211_associate_abort(struct ieee80211_device *ieee) -{ - - unsigned long flags; - spin_lock_irqsave(&ieee->lock, flags); - - ieee->associate_seq++; - - /* don't scan, and avoid to have the RX path possibily - * try again to associate. Even do not react to AUTH or - * ASSOC response. Just wait for the retry wq to be scheduled. - * Here we will check if there are good nets to associate - * with, so we retry or just get back to NO_LINK and scanning - */ - if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING){ - IEEE80211_DEBUG_MGMT("Authentication failed\n"); - ieee->softmac_stats.no_auth_rs++; - }else{ - IEEE80211_DEBUG_MGMT("Association failed\n"); - ieee->softmac_stats.no_ass_rs++; - } - - ieee->state = IEEE80211_ASSOCIATING_RETRY; - - queue_delayed_work(ieee->wq, &ieee->associate_retry_wq, \ - IEEE80211_SOFTMAC_ASSOC_RETRY_TIME); - spin_unlock_irqrestore(&ieee->lock, flags); -} - -void ieee80211_associate_abort_cb(unsigned long dev) -{ - ieee80211_associate_abort((struct ieee80211_device *) dev); -} - - -void ieee80211_associate_step1(struct ieee80211_device *ieee) -{ - struct ieee80211_network *beacon = &ieee->current_network; - struct sk_buff *skb; - - IEEE80211_DEBUG_MGMT("Stopping scan\n"); - - ieee->softmac_stats.tx_auth_rq++; - skb=ieee80211_authentication_req(beacon, ieee, 0); - - if (!skb) - ieee80211_associate_abort(ieee); - else{ - ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATING ; - IEEE80211_DEBUG_MGMT("Sending authentication request\n"); - softmac_mgmt_xmit(skb, ieee); - //BUGON when you try to add_timer twice, using mod_timer may be better, john0709 - if(!timer_pending(&ieee->associate_timer)){ - ieee->associate_timer.expires = jiffies + (HZ / 2); - add_timer(&ieee->associate_timer); - } - } -} - -void ieee80211_rtl_auth_challenge(struct ieee80211_device *ieee, u8 *challenge, int chlen) -{ - u8 *c; - struct sk_buff *skb; - struct ieee80211_network *beacon = &ieee->current_network; - - ieee->associate_seq++; - ieee->softmac_stats.tx_auth_rq++; - - skb = ieee80211_authentication_req(beacon, ieee, chlen+2); - if (!skb) - ieee80211_associate_abort(ieee); - else{ - c = skb_put(skb, chlen+2); - *(c++) = MFIE_TYPE_CHALLENGE; - *(c++) = chlen; - memcpy(c, challenge, chlen); - - IEEE80211_DEBUG_MGMT("Sending authentication challenge response\n"); - - ieee80211_encrypt_fragment(ieee, skb, sizeof(struct ieee80211_hdr_3addr )); - - softmac_mgmt_xmit(skb, ieee); - mod_timer(&ieee->associate_timer, jiffies + (HZ/2)); - } - kfree(challenge); -} - -void ieee80211_associate_step2(struct ieee80211_device *ieee) -{ - struct sk_buff* skb; - struct ieee80211_network *beacon = &ieee->current_network; - - del_timer_sync(&ieee->associate_timer); - - IEEE80211_DEBUG_MGMT("Sending association request\n"); - - ieee->softmac_stats.tx_ass_rq++; - skb=ieee80211_association_req(beacon, ieee); - if (!skb) - ieee80211_associate_abort(ieee); - else{ - softmac_mgmt_xmit(skb, ieee); - mod_timer(&ieee->associate_timer, jiffies + (HZ/2)); - } -} -void ieee80211_associate_complete_wq(struct work_struct *work) -{ - struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_complete_wq); - printk(KERN_INFO "Associated successfully\n"); - ieee->is_roaming = false; - if(ieee80211_is_54g(ieee->current_network) && - (ieee->modulation & IEEE80211_OFDM_MODULATION)){ - - ieee->rate = 108; - printk(KERN_INFO"Using G rates:%d\n", ieee->rate); - }else{ - ieee->rate = 22; - printk(KERN_INFO"Using B rates:%d\n", ieee->rate); - } - if (ieee->pHTInfo->bCurrentHTSupport&&ieee->pHTInfo->bEnableHT) - { - printk("Successfully associated, ht enabled\n"); - HTOnAssocRsp(ieee); - } - else - { - printk("Successfully associated, ht not enabled(%d, %d)\n", ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bEnableHT); - memset(ieee->dot11HTOperationalRateSet, 0, 16); - } - ieee->LinkDetectInfo.SlotNum = 2 * (1 + ieee->current_network.beacon_interval/500); - // To prevent the immediately calling watch_dog after association. - if(ieee->LinkDetectInfo.NumRecvBcnInPeriod==0||ieee->LinkDetectInfo.NumRecvDataInPeriod==0 ) - { - ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1; - ieee->LinkDetectInfo.NumRecvDataInPeriod= 1; - } - ieee->link_change(ieee); - if(ieee->is_silent_reset == 0){ - printk("============>normal associate\n"); - notify_wx_assoc_event(ieee); - } - else if(ieee->is_silent_reset == 1) - { - printk("==================>silent reset associate\n"); - ieee->is_silent_reset = 0; - } - - if (ieee->data_hard_resume) - ieee->data_hard_resume(ieee); - netif_carrier_on(ieee->dev); -} - -void ieee80211_associate_complete(struct ieee80211_device *ieee) -{ - del_timer_sync(&ieee->associate_timer); - - ieee->state = IEEE80211_LINKED; - queue_work(ieee->wq, &ieee->associate_complete_wq); -} - -void ieee80211_associate_procedure_wq(struct work_struct *work) -{ - struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_procedure_wq); - ieee->sync_scan_hurryup = 1; -#ifdef ENABLE_IPS - if(ieee->ieee80211_ips_leave != NULL) - ieee->ieee80211_ips_leave(ieee); -#endif - - down(&ieee->wx_sem); - - if (ieee->data_hard_stop) - ieee->data_hard_stop(ieee); - - ieee80211_stop_scan(ieee); - printk("===>%s(), chan:%d\n", __FUNCTION__, ieee->current_network.channel); - HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); - - ieee->associate_seq = 1; - ieee80211_associate_step1(ieee); - - up(&ieee->wx_sem); -} - -inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee80211_network *net) -{ - u8 tmp_ssid[IW_ESSID_MAX_SIZE+1]; - int tmp_ssid_len = 0; - - short apset,ssidset,ssidbroad,apmatch,ssidmatch; - - /* we are interested in new new only if we are not associated - * and we are not associating / authenticating - */ - if (ieee->state != IEEE80211_NOLINK) - return; - - if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability & WLAN_CAPABILITY_BSS)) - return; - - if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & WLAN_CAPABILITY_IBSS)) - return; - - - if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC){ - /* if the user specified the AP MAC, we need also the essid - * This could be obtained by beacons or, if the network does not - * broadcast it, it can be put manually. - */ - apset = ieee->wap_set; - ssidset = ieee->ssid_set; - ssidbroad = !(net->ssid_len == 0 || net->ssid[0]== '\0'); - apmatch = (memcmp(ieee->current_network.bssid, net->bssid, ETH_ALEN)==0); - ssidmatch = (ieee->current_network.ssid_len == net->ssid_len)&&\ - (!strncmp(ieee->current_network.ssid, net->ssid, net->ssid_len)); - - - if ( /* if the user set the AP check if match. - * if the network does not broadcast essid we check the user supplyed ANY essid - * if the network does broadcast and the user does not set essid it is OK - * if the network does broadcast and the user did set essid chech if essid match - */ - ( apset && apmatch && - ((ssidset && ssidbroad && ssidmatch) || (ssidbroad && !ssidset) || (!ssidbroad && ssidset)) ) || - /* if the ap is not set, check that the user set the bssid - * and the network does bradcast and that those two bssid matches - */ - (!apset && ssidset && ssidbroad && ssidmatch) - ){ - /* if the essid is hidden replace it with the - * essid provided by the user. - */ - if (!ssidbroad){ - strncpy(tmp_ssid, ieee->current_network.ssid, IW_ESSID_MAX_SIZE); - tmp_ssid_len = ieee->current_network.ssid_len; - } - memcpy(&ieee->current_network, net, sizeof(struct ieee80211_network)); - - if (!ssidbroad){ - strncpy(ieee->current_network.ssid, tmp_ssid, IW_ESSID_MAX_SIZE); - ieee->current_network.ssid_len = tmp_ssid_len; - } - printk(KERN_INFO"Linking with %s,channel:%d, qos:%d, myHT:%d, networkHT:%d\n",ieee->current_network.ssid,ieee->current_network.channel, ieee->current_network.qos_data.supported, ieee->pHTInfo->bEnableHT, ieee->current_network.bssht.bdSupportHT); - - HTResetIOTSetting(ieee->pHTInfo); - if (ieee->iw_mode == IW_MODE_INFRA){ - /* Join the network for the first time */ - ieee->AsocRetryCount = 0; - //for HT by amy 080514 - if((ieee->current_network.qos_data.supported == 1) && - ieee->current_network.bssht.bdSupportHT) -/*WB, 2008.09.09:bCurrentHTSupport and bEnableHT two flags are going to put together to check whether we are in HT now, so needn't to check bEnableHT flags here. That's is to say we will set to HT support whenever joined AP has the ability to support HT. And whether we are in HT or not, please check bCurrentHTSupport&&bEnableHT now please.*/ - { - HTResetSelfAndSavePeerSetting(ieee, &(ieee->current_network)); - } - else - { - ieee->pHTInfo->bCurrentHTSupport = false; - } - - ieee->state = IEEE80211_ASSOCIATING; - queue_work(ieee->wq, &ieee->associate_procedure_wq); - }else{ - if(ieee80211_is_54g(ieee->current_network) && - (ieee->modulation & IEEE80211_OFDM_MODULATION)){ - ieee->rate = 108; - ieee->SetWirelessMode(ieee, IEEE_G); - printk(KERN_INFO"Using G rates\n"); - }else{ - ieee->rate = 22; - ieee->SetWirelessMode(ieee, IEEE_B); - printk(KERN_INFO"Using B rates\n"); - } - memset(ieee->dot11HTOperationalRateSet, 0, 16); - ieee->state = IEEE80211_LINKED; - } - - } - } - -} - -void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee) -{ - unsigned long flags; - struct ieee80211_network *target; - - spin_lock_irqsave(&ieee->lock, flags); - - list_for_each_entry(target, &ieee->network_list, list) { - - /* if the state become different that NOLINK means - * we had found what we are searching for - */ - - if (ieee->state != IEEE80211_NOLINK) - break; - - if (ieee->scan_age == 0 || time_after(target->last_scanned + ieee->scan_age, jiffies)) - ieee80211_softmac_new_net(ieee, target); - } - - spin_unlock_irqrestore(&ieee->lock, flags); - -} - - -static inline u16 auth_parse(struct sk_buff *skb, u8** challenge, int *chlen) -{ - struct ieee80211_authentication *a; - u8 *t; - if (skb->len < (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){ - IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n",skb->len); - return 0xcafe; - } - *challenge = NULL; - a = (struct ieee80211_authentication*) skb->data; - if(skb->len > (sizeof(struct ieee80211_authentication) +3)){ - t = skb->data + sizeof(struct ieee80211_authentication); - - if(*(t++) == MFIE_TYPE_CHALLENGE){ - *chlen = *(t++); - *challenge = kmemdup(t, *chlen, GFP_ATOMIC); - if (!*challenge) - return -ENOMEM; - } - } - - return cpu_to_le16(a->status); - -} - - -int auth_rq_parse(struct sk_buff *skb,u8* dest) -{ - struct ieee80211_authentication *a; - - if (skb->len < (sizeof(struct ieee80211_authentication)-sizeof(struct ieee80211_info_element))){ - IEEE80211_DEBUG_MGMT("invalid len in auth request: %d\n",skb->len); - return -1; - } - a = (struct ieee80211_authentication*) skb->data; - - memcpy(dest,a->header.addr2, ETH_ALEN); - - if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN) - return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG; - - return WLAN_STATUS_SUCCESS; -} - -static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb, u8 *src) -{ - u8 *tag; - u8 *skbend; - u8 *ssid=NULL; - u8 ssidlen = 0; - - struct ieee80211_hdr_3addr *header = - (struct ieee80211_hdr_3addr *) skb->data; - - if (skb->len < sizeof (struct ieee80211_hdr_3addr )) - return -1; /* corrupted */ - - memcpy(src,header->addr2, ETH_ALEN); - - skbend = (u8*)skb->data + skb->len; - - tag = skb->data + sizeof (struct ieee80211_hdr_3addr ); - - while (tag+1 < skbend){ - if (*tag == 0){ - ssid = tag+2; - ssidlen = *(tag+1); - break; - } - tag++; /* point to the len field */ - tag = tag + *(tag); /* point to the last data byte of the tag */ - tag++; /* point to the next tag */ - } - - if (ssidlen == 0) return 1; - - if (!ssid) return 1; /* ssid not found in tagged param */ - return (!strncmp(ssid, ieee->current_network.ssid, ssidlen)); - -} - -int assoc_rq_parse(struct sk_buff *skb,u8* dest) -{ - struct ieee80211_assoc_request_frame *a; - - if (skb->len < (sizeof(struct ieee80211_assoc_request_frame) - - sizeof(struct ieee80211_info_element))) { - - IEEE80211_DEBUG_MGMT("invalid len in auth request:%d \n", skb->len); - return -1; - } - - a = (struct ieee80211_assoc_request_frame*) skb->data; - - memcpy(dest,a->header.addr2,ETH_ALEN); - - return 0; -} - -static inline u16 assoc_parse(struct ieee80211_device *ieee, struct sk_buff *skb, int *aid) -{ - struct ieee80211_assoc_response_frame *response_head; - u16 status_code; - - if (skb->len < sizeof(struct ieee80211_assoc_response_frame)){ - IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len); - return 0xcafe; - } - - response_head = (struct ieee80211_assoc_response_frame*) skb->data; - *aid = le16_to_cpu(response_head->aid) & 0x3fff; - - status_code = le16_to_cpu(response_head->status); - if((status_code==WLAN_STATUS_ASSOC_DENIED_RATES || \ - status_code==WLAN_STATUS_CAPS_UNSUPPORTED)&& - ((ieee->mode == IEEE_G) && - (ieee->current_network.mode == IEEE_N_24G) && - (ieee->AsocRetryCount++ < (RT_ASOC_RETRY_LIMIT-1)))) { - ieee->pHTInfo->IOTAction |= HT_IOT_ACT_PURE_N_MODE; - }else { - ieee->AsocRetryCount = 0; - } - - return le16_to_cpu(response_head->status); -} - -static inline void -ieee80211_rx_probe_rq(struct ieee80211_device *ieee, struct sk_buff *skb) -{ - u8 dest[ETH_ALEN]; - - ieee->softmac_stats.rx_probe_rq++; - if (probe_rq_parse(ieee, skb, dest)){ - ieee->softmac_stats.tx_probe_rs++; - ieee80211_resp_to_probe(ieee, dest); - } -} - -static inline void -ieee80211_rx_auth_rq(struct ieee80211_device *ieee, struct sk_buff *skb) -{ - u8 dest[ETH_ALEN]; - int status; - ieee->softmac_stats.rx_auth_rq++; - - status = auth_rq_parse(skb, dest); - if (status != -1) { - ieee80211_resp_to_auth(ieee, status, dest); - } -} - -static inline void -ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb) -{ - u8 dest[ETH_ALEN]; - - ieee->softmac_stats.rx_ass_rq++; - if (assoc_rq_parse(skb,dest) != -1){ - ieee80211_resp_to_assoc_rq(ieee, dest); - } - - printk(KERN_INFO"New client associated: %pM\n", dest); -} - - - -void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr) -{ - - struct sk_buff *buf = ieee80211_null_func(ieee, pwr); - - if (buf) - softmac_ps_mgmt_xmit(buf, ieee); - -} - -void ieee80211_sta_ps_send_pspoll_frame(struct ieee80211_device *ieee) -{ - - struct sk_buff *buf = ieee80211_pspoll_func(ieee); - - if (buf) - softmac_ps_mgmt_xmit(buf, ieee); - -} - -short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h, u32 *time_l) -{ - int timeout = ieee->ps_timeout; - u8 dtim; - - if(ieee->LPSDelayCnt) - { - ieee->LPSDelayCnt --; - return 0; - } - - dtim = ieee->current_network.dtim_data; - if(!(dtim & IEEE80211_DTIM_VALID)) - return 0; - timeout = ieee->current_network.beacon_interval; //should we use ps_timeout value or beacon_interval - ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID; - /* there's no need to nofity AP that I find you buffered with broadcast packet */ - if(dtim & (IEEE80211_DTIM_UCAST & ieee->ps)) - return 2; - - if(!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout))){ - return 0; - } - if(!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout))){ - return 0; - } - if((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE ) && - (ieee->mgmt_queue_tail != ieee->mgmt_queue_head)) - return 0; - - if(time_l){ - if(ieee->bAwakePktSent == true) { - ieee->LPSAwakeIntvl = 1;//tx wake one beacon - } else { - u8 MaxPeriod = 1; - - if(ieee->LPSAwakeIntvl == 0) - ieee->LPSAwakeIntvl = 1; - if(ieee->RegMaxLPSAwakeIntvl == 0) // Default (0x0 - eFastPs, 0xFF -DTIM, 0xNN - 0xNN * BeaconIntvl) - MaxPeriod = 1; // 1 Beacon interval - else if(ieee->RegMaxLPSAwakeIntvl == 0xFF) // DTIM - MaxPeriod = ieee->current_network.dtim_period; - else - MaxPeriod = ieee->RegMaxLPSAwakeIntvl; - ieee->LPSAwakeIntvl = (ieee->LPSAwakeIntvl >= MaxPeriod) ? MaxPeriod : (ieee->LPSAwakeIntvl + 1); - } - { - u8 LPSAwakeIntvl_tmp = 0; - u8 period = ieee->current_network.dtim_period; - u8 count = ieee->current_network.tim.tim_count; - if(count == 0 ) { - if(ieee->LPSAwakeIntvl > period) - LPSAwakeIntvl_tmp = period + (ieee->LPSAwakeIntvl - period) -((ieee->LPSAwakeIntvl-period)%period); - else - LPSAwakeIntvl_tmp = ieee->LPSAwakeIntvl; - - } else { - if(ieee->LPSAwakeIntvl > ieee->current_network.tim.tim_count) - LPSAwakeIntvl_tmp = count + (ieee->LPSAwakeIntvl - count) -((ieee->LPSAwakeIntvl-count)%period); - else - LPSAwakeIntvl_tmp = ieee->LPSAwakeIntvl; - } - - *time_l = ieee->current_network.last_dtim_sta_time[0] - + MSECS(ieee->current_network.beacon_interval * LPSAwakeIntvl_tmp); - } - } - - if(time_h){ - *time_h = ieee->current_network.last_dtim_sta_time[1]; - if(time_l && *time_l < ieee->current_network.last_dtim_sta_time[0]) - *time_h += 1; - } - - return 1; - - -} - -inline void ieee80211_sta_ps(struct ieee80211_device *ieee) -{ - - u32 th,tl; - short sleep; - unsigned long flags; - - spin_lock_irqsave(&ieee->lock, flags); - - if((ieee->ps == IEEE80211_PS_DISABLED || - ieee->iw_mode != IW_MODE_INFRA || - ieee->state != IEEE80211_LINKED)){ - - // #warning CHECK_LOCK_HERE - printk("=====>%s(): no need to ps,wake up!! ieee->ps is %d,ieee->iw_mode is %d,ieee->state is %d\n", - __FUNCTION__,ieee->ps,ieee->iw_mode,ieee->state); - spin_lock(&ieee->mgmt_tx_lock); - - ieee80211_sta_wakeup(ieee, 1); - - spin_unlock(&ieee->mgmt_tx_lock); - } - - sleep = ieee80211_sta_ps_sleep(ieee,&th, &tl); - /* 2 wake, 1 sleep, 0 do nothing */ - if(sleep == 0)//it is not time out or dtim is not valid - { - goto out; - } - if(sleep == 1){ - if(ieee->sta_sleep == 1){ - ieee->enter_sleep_state(ieee, th, tl); - } - - else if(ieee->sta_sleep == 0){ - spin_lock(&ieee->mgmt_tx_lock); - - if (ieee->ps_is_queue_empty(ieee)) { - ieee->sta_sleep = 2; - ieee->ack_tx_to_ieee = 1; - ieee80211_sta_ps_send_null_frame(ieee,1); - ieee->ps_th = th; - ieee->ps_tl = tl; - } - spin_unlock(&ieee->mgmt_tx_lock); - - } - - ieee->bAwakePktSent = false;//after null to power save we set it to false. not listen every beacon. - - }else if(sleep == 2){ - spin_lock(&ieee->mgmt_tx_lock); - - ieee80211_sta_wakeup(ieee,1); - - spin_unlock(&ieee->mgmt_tx_lock); - } - -out: - spin_unlock_irqrestore(&ieee->lock, flags); - -} - -void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl) -{ - if(ieee->sta_sleep == 0){ - if(nl){ - if(ieee->pHTInfo->IOTAction & HT_IOT_ACT_NULL_DATA_POWER_SAVING) - { - ieee->ack_tx_to_ieee = 1; - ieee80211_sta_ps_send_null_frame(ieee, 0); - } - else - { - ieee->ack_tx_to_ieee = 1; - ieee80211_sta_ps_send_pspoll_frame(ieee); - } - } - return; - - } - - if(ieee->sta_sleep == 1) - ieee->sta_wake_up(ieee); - if(nl){ - - if(ieee->pHTInfo->IOTAction & HT_IOT_ACT_NULL_DATA_POWER_SAVING) - { - ieee->ack_tx_to_ieee = 1; - ieee80211_sta_ps_send_null_frame(ieee, 0); - } - else - { - ieee->ack_tx_to_ieee = 1; - ieee->polling = true; - //ieee80211_sta_ps_send_null_frame(ieee, 0); - ieee80211_sta_ps_send_pspoll_frame(ieee); - } - - } else { - ieee->sta_sleep = 0; - ieee->polling = false; - } -} - -void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success) -{ - unsigned long flags; - - spin_lock_irqsave(&ieee->lock, flags); - - if(ieee->sta_sleep == 2){ - /* Null frame with PS bit set */ - if(success){ - ieee->sta_sleep = 1; - ieee->enter_sleep_state(ieee, ieee->ps_th, ieee->ps_tl); - } - } else {/* 21112005 - tx again null without PS bit if lost */ - - if((ieee->sta_sleep == 0) && !success){ - spin_lock(&ieee->mgmt_tx_lock); - //ieee80211_sta_ps_send_null_frame(ieee, 0); - if(ieee->pHTInfo->IOTAction & HT_IOT_ACT_NULL_DATA_POWER_SAVING) - { - ieee80211_sta_ps_send_null_frame(ieee, 0); - } - else - { - ieee80211_sta_ps_send_pspoll_frame(ieee); - } - spin_unlock(&ieee->mgmt_tx_lock); - } - } - spin_unlock_irqrestore(&ieee->lock, flags); -} - -void ieee80211_process_action(struct ieee80211_device* ieee, struct sk_buff* skb) -{ - struct ieee80211_hdr* header = (struct ieee80211_hdr*)skb->data; - u8* act = ieee80211_get_payload(header); - u8 tmp = 0; - - if (act == NULL) - { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "error to get payload of action frame\n"); - return; - } - tmp = *act; - act ++; - switch (tmp) - { - case ACT_CAT_BA: - if (*act == ACT_ADDBAREQ) - ieee80211_rx_ADDBAReq(ieee, skb); - else if (*act == ACT_ADDBARSP) - ieee80211_rx_ADDBARsp(ieee, skb); - else if (*act == ACT_DELBA) - ieee80211_rx_DELBA(ieee, skb); - break; - default: - break; - } - return; - -} -inline int -ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb, - struct ieee80211_rx_stats *rx_stats, u16 type, - u16 stype) -{ - struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *) skb->data; - u16 errcode; - u8* challenge; - int chlen=0; - int aid; - struct ieee80211_assoc_response_frame *assoc_resp; - bool bSupportNmode = true, bHalfSupportNmode = false; //default support N mode, disable halfNmode - - if(!ieee->proto_started) - return 0; - - switch (WLAN_FC_GET_STYPE(header->frame_ctl)) { - - case IEEE80211_STYPE_ASSOC_RESP: - case IEEE80211_STYPE_REASSOC_RESP: - - IEEE80211_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n", - WLAN_FC_GET_STYPE(header->frame_ctl)); - if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) && - ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATED && - ieee->iw_mode == IW_MODE_INFRA){ - struct ieee80211_network network_resp; - struct ieee80211_network *network = &network_resp; - - if (0 == (errcode=assoc_parse(ieee,skb, &aid))){ - ieee->state=IEEE80211_LINKED; - ieee->assoc_id = aid; - ieee->softmac_stats.rx_ass_ok++; - /* station support qos */ - /* Let the register setting defaultly with Legacy station */ - if(ieee->qos_support) { - assoc_resp = (struct ieee80211_assoc_response_frame*)skb->data; - memset(network, 0, sizeof(*network)); - if (ieee80211_parse_info_param(ieee,assoc_resp->info_element,\ - rx_stats->len - sizeof(*assoc_resp),\ - network,rx_stats)){ - return 1; - } - else - { //filling the PeerHTCap. //maybe not necessary as we can get its info from current_network. - memcpy(ieee->pHTInfo->PeerHTCapBuf, network->bssht.bdHTCapBuf, network->bssht.bdHTCapLen); - memcpy(ieee->pHTInfo->PeerHTInfoBuf, network->bssht.bdHTInfoBuf, network->bssht.bdHTInfoLen); - } - if (ieee->handle_assoc_response != NULL) - ieee->handle_assoc_response(ieee, (struct ieee80211_assoc_response_frame*)header, network); - } - ieee80211_associate_complete(ieee); - } else { - /* aid could not been allocated */ - ieee->softmac_stats.rx_ass_err++; - printk( - "Association response status code 0x%x\n", - errcode); - IEEE80211_DEBUG_MGMT( - "Association response status code 0x%x\n", - errcode); - if(ieee->AsocRetryCount < RT_ASOC_RETRY_LIMIT) { - queue_work(ieee->wq, &ieee->associate_procedure_wq); - } else { - ieee80211_associate_abort(ieee); - } - } - } - break; - - case IEEE80211_STYPE_ASSOC_REQ: - case IEEE80211_STYPE_REASSOC_REQ: - - if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) && - ieee->iw_mode == IW_MODE_MASTER) - - ieee80211_rx_assoc_rq(ieee, skb); - break; - - case IEEE80211_STYPE_AUTH: - - if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE){ - if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING && - ieee->iw_mode == IW_MODE_INFRA){ - - IEEE80211_DEBUG_MGMT("Received authentication response"); - - if (0 == (errcode=auth_parse(skb, &challenge, &chlen))){ - if(ieee->open_wep || !challenge){ - ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATED; - ieee->softmac_stats.rx_auth_rs_ok++; - if(!(ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE)) - { - if (!ieee->GetNmodeSupportBySecCfg(ieee)) - { - // WEP or TKIP encryption - if(IsHTHalfNmodeAPs(ieee)) - { - bSupportNmode = true; - bHalfSupportNmode = true; - } - else - { - bSupportNmode = false; - bHalfSupportNmode = false; - } - printk("==========>to link with AP using SEC(%d, %d)\n", bSupportNmode, bHalfSupportNmode); - } - } - /* Dummy wirless mode setting to avoid encryption issue */ - if(bSupportNmode) { - //N mode setting - ieee->SetWirelessMode(ieee, - ieee->current_network.mode); - }else{ - //b/g mode setting - /*TODO*/ - ieee->SetWirelessMode(ieee, IEEE_G); - } - - if (ieee->current_network.mode == IEEE_N_24G && bHalfSupportNmode == true) - { - printk("===============>entern half N mode\n"); - ieee->bHalfWirelessN24GMode = true; - } - else - ieee->bHalfWirelessN24GMode = false; - - ieee80211_associate_step2(ieee); - }else{ - ieee80211_rtl_auth_challenge(ieee, challenge, chlen); - } - }else{ - ieee->softmac_stats.rx_auth_rs_err++; - IEEE80211_DEBUG_MGMT("Authentication respose status code 0x%x",errcode); - - printk("Authentication respose status code 0x%x",errcode); - ieee80211_associate_abort(ieee); - } - - }else if (ieee->iw_mode == IW_MODE_MASTER){ - ieee80211_rx_auth_rq(ieee, skb); - } - } - break; - - case IEEE80211_STYPE_PROBE_REQ: - - if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) && - ((ieee->iw_mode == IW_MODE_ADHOC || - ieee->iw_mode == IW_MODE_MASTER) && - ieee->state == IEEE80211_LINKED)){ - ieee80211_rx_probe_rq(ieee, skb); - } - break; - - case IEEE80211_STYPE_DISASSOC: - case IEEE80211_STYPE_DEAUTH: - /* FIXME for now repeat all the association procedure - * both for disassociation and deauthentication - */ - if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) && - ieee->state == IEEE80211_LINKED && - ieee->iw_mode == IW_MODE_INFRA){ - - ieee->state = IEEE80211_ASSOCIATING; - ieee->softmac_stats.reassoc++; - ieee->is_roaming = true; - ieee80211_disassociate(ieee); - RemovePeerTS(ieee, header->addr2); - queue_work(ieee->wq, &ieee->associate_procedure_wq); - } - break; - case IEEE80211_STYPE_MANAGE_ACT: - ieee80211_process_action(ieee,skb); - break; - default: - return -1; - break; - } - - return 0; -} - -/* following are for a simpler TX queue management. - * Instead of using netif_[stop/wake]_queue the driver - * will uses these two function (plus a reset one), that - * will internally uses the kernel netif_* and takes - * care of the ieee802.11 fragmentation. - * So the driver receives a fragment per time and might - * call the stop function when it want without take care - * to have enough room to TX an entire packet. - * This might be useful if each fragment need it's own - * descriptor, thus just keep a total free memory > than - * the max fragmentation threshold is not enough.. If the - * ieee802.11 stack passed a TXB struct then you needed - * to keep N free descriptors where - * N = MAX_PACKET_SIZE / MIN_FRAG_TRESHOLD - * In this way you need just one and the 802.11 stack - * will take care of buffering fragments and pass them to - * to the driver later, when it wakes the queue. - */ -void ieee80211_softmac_xmit(struct ieee80211_txb *txb, struct ieee80211_device *ieee) -{ - - unsigned int queue_index = txb->queue_index; - unsigned long flags; - int i; - cb_desc *tcb_desc = NULL; - - spin_lock_irqsave(&ieee->lock,flags); - - /* called with 2nd parm 0, no tx mgmt lock required */ - ieee80211_sta_wakeup(ieee,0); - - /* update the tx status */ - tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE); - if(tcb_desc->bMulticast) { - ieee->stats.multicast++; - } - - /* if xmit available, just xmit it immediately, else just insert it to the wait queue */ - for(i = 0; i < txb->nr_frags; i++) { -#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE - if ((skb_queue_len(&ieee->skb_drv_aggQ[queue_index]) != 0) || -#else - if ((skb_queue_len(&ieee->skb_waitQ[queue_index]) != 0) || -#endif - (!ieee->check_nic_enough_desc(ieee, queue_index))|| - (ieee->queue_stop)) { - /* insert the skb packet to the wait queue */ - /* as for the completion function, it does not need - * to check it any more. - * */ -#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE - skb_queue_tail(&ieee->skb_drv_aggQ[queue_index], txb->fragments[i]); -#else - skb_queue_tail(&ieee->skb_waitQ[queue_index], txb->fragments[i]); -#endif - }else{ - ieee->softmac_data_hard_start_xmit( - txb->fragments[i], - ieee, ieee->rate); - } - } - - ieee80211_txb_free(txb); - - spin_unlock_irqrestore(&ieee->lock,flags); - -} - -/* called with ieee->lock acquired */ -void ieee80211_resume_tx(struct ieee80211_device *ieee) -{ - int i; - for(i = ieee->tx_pending.frag; i < ieee->tx_pending.txb->nr_frags; i++) { - - if (ieee->queue_stop){ - ieee->tx_pending.frag = i; - return; - }else{ - - ieee->softmac_data_hard_start_xmit( - ieee->tx_pending.txb->fragments[i], - ieee, ieee->rate); - ieee->stats.tx_packets++; - } - } - - - ieee80211_txb_free(ieee->tx_pending.txb); - ieee->tx_pending.txb = NULL; -} - - -void ieee80211_reset_queue(struct ieee80211_device *ieee) -{ - unsigned long flags; - - spin_lock_irqsave(&ieee->lock,flags); - init_mgmt_queue(ieee); - if (ieee->tx_pending.txb){ - ieee80211_txb_free(ieee->tx_pending.txb); - ieee->tx_pending.txb = NULL; - } - ieee->queue_stop = 0; - spin_unlock_irqrestore(&ieee->lock,flags); - -} - -void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee) -{ - - unsigned long flags; - struct sk_buff *skb; - struct ieee80211_hdr_3addr *header; - - spin_lock_irqsave(&ieee->lock,flags); - if (! ieee->queue_stop) goto exit; - - ieee->queue_stop = 0; - - if(ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE){ - while (!ieee->queue_stop && (skb = dequeue_mgmt(ieee))){ - - header = (struct ieee80211_hdr_3addr *) skb->data; - - header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); - - if (ieee->seq_ctrl[0] == 0xFFF) - ieee->seq_ctrl[0] = 0; - else - ieee->seq_ctrl[0]++; - - ieee->softmac_data_hard_start_xmit(skb, ieee, ieee->basic_rate); - } - } - if (!ieee->queue_stop && ieee->tx_pending.txb) - ieee80211_resume_tx(ieee); - - if (!ieee->queue_stop && netif_queue_stopped(ieee->dev)){ - ieee->softmac_stats.swtxawake++; - netif_wake_queue(ieee->dev); - } - -exit : - spin_unlock_irqrestore(&ieee->lock,flags); -} - - -void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee) -{ - if (! netif_queue_stopped(ieee->dev)){ - netif_stop_queue(ieee->dev); - ieee->softmac_stats.swtxstop++; - } - ieee->queue_stop = 1; -} - - -inline void ieee80211_randomize_cell(struct ieee80211_device *ieee) -{ - - get_random_bytes(ieee->current_network.bssid, ETH_ALEN); - - /* an IBSS cell address must have the two less significant - * bits of the first byte = 2 - */ - ieee->current_network.bssid[0] &= ~0x01; - ieee->current_network.bssid[0] |= 0x02; -} - -/* called in user context only */ -void ieee80211_start_master_bss(struct ieee80211_device *ieee) -{ - ieee->assoc_id = 1; - - if (ieee->current_network.ssid_len == 0){ - strncpy(ieee->current_network.ssid, - IEEE80211_DEFAULT_TX_ESSID, - IW_ESSID_MAX_SIZE); - - ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID); - ieee->ssid_set = 1; - } - - memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN); - - ieee->set_chan(ieee, ieee->current_network.channel); - ieee->state = IEEE80211_LINKED; - ieee->link_change(ieee); - notify_wx_assoc_event(ieee); - - if (ieee->data_hard_resume) - ieee->data_hard_resume(ieee); - - netif_carrier_on(ieee->dev); -} - -void ieee80211_start_monitor_mode(struct ieee80211_device *ieee) -{ - if(ieee->raw_tx){ - - if (ieee->data_hard_resume) - ieee->data_hard_resume(ieee); - - netif_carrier_on(ieee->dev); - } -} -void ieee80211_start_ibss_wq(struct work_struct *work) -{ - - struct delayed_work *dwork = container_of(work, struct delayed_work, work); - struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, start_ibss_wq); - /* iwconfig mode ad-hoc will schedule this and return - * on the other hand this will block further iwconfig SET - * operations because of the wx_sem hold. - * Anyway some most set operations set a flag to speed-up - * (abort) this wq (when syncro scanning) before sleeping - * on the semaphore - */ - if(!ieee->proto_started){ - printk("==========oh driver down return\n"); - return; - } - down(&ieee->wx_sem); - - if (ieee->current_network.ssid_len == 0){ - strcpy(ieee->current_network.ssid,IEEE80211_DEFAULT_TX_ESSID); - ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID); - ieee->ssid_set = 1; - } - - ieee->state = IEEE80211_NOLINK; - /* check if we have this cell in our network list */ - ieee80211_softmac_check_all_nets(ieee); - - -#ifdef ENABLE_DOT11D //if creating an ad-hoc, set its channel to 10 temporarily--this is the requirement for ASUS, not 11D, so disable 11d. - if (ieee->state == IEEE80211_NOLINK) - ieee->current_network.channel = 6; -#endif - /* if not then the state is not linked. Maybe the user swithced to - * ad-hoc mode just after being in monitor mode, or just after - * being very few time in managed mode (so the card have had no - * time to scan all the chans..) or we have just run up the iface - * after setting ad-hoc mode. So we have to give another try.. - * Here, in ibss mode, should be safe to do this without extra care - * (in bss mode we had to make sure no-one tryed to associate when - * we had just checked the ieee->state and we was going to start the - * scan) beacause in ibss mode the ieee80211_new_net function, when - * finds a good net, just set the ieee->state to IEEE80211_LINKED, - * so, at worst, we waste a bit of time to initiate an unneeded syncro - * scan, that will stop at the first round because it sees the state - * associated. - */ - if (ieee->state == IEEE80211_NOLINK) - ieee80211_start_scan_syncro(ieee); - - /* the network definitively is not here.. create a new cell */ - if (ieee->state == IEEE80211_NOLINK){ - printk("creating new IBSS cell\n"); - if(!ieee->wap_set) - ieee80211_randomize_cell(ieee); - - if(ieee->modulation & IEEE80211_CCK_MODULATION){ - - ieee->current_network.rates_len = 4; - - ieee->current_network.rates[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB; - ieee->current_network.rates[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB; - ieee->current_network.rates[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB; - ieee->current_network.rates[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB; - - }else - ieee->current_network.rates_len = 0; - - if(ieee->modulation & IEEE80211_OFDM_MODULATION){ - ieee->current_network.rates_ex_len = 8; - - ieee->current_network.rates_ex[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB; - ieee->current_network.rates_ex[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB; - ieee->current_network.rates_ex[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB; - ieee->current_network.rates_ex[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB; - ieee->current_network.rates_ex[4] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB; - ieee->current_network.rates_ex[5] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB; - ieee->current_network.rates_ex[6] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB; - ieee->current_network.rates_ex[7] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB; - - ieee->rate = 108; - }else{ - ieee->current_network.rates_ex_len = 0; - ieee->rate = 22; - } - - // By default, WMM function will be disabled in IBSS mode - ieee->current_network.QoS_Enable = 0; - ieee->SetWirelessMode(ieee, IEEE_G); - ieee->current_network.atim_window = 0; - ieee->current_network.capability = WLAN_CAPABILITY_IBSS; - if(ieee->short_slot) - ieee->current_network.capability |= WLAN_CAPABILITY_SHORT_SLOT; - - } - - ieee->state = IEEE80211_LINKED; - - ieee->set_chan(ieee, ieee->current_network.channel); - ieee->link_change(ieee); - - notify_wx_assoc_event(ieee); - - ieee80211_start_send_beacons(ieee); - - if (ieee->data_hard_resume) - ieee->data_hard_resume(ieee); - netif_carrier_on(ieee->dev); - - up(&ieee->wx_sem); -} - -inline void ieee80211_start_ibss(struct ieee80211_device *ieee) -{ - queue_delayed_work(ieee->wq, &ieee->start_ibss_wq, 150); -} - -/* this is called only in user context, with wx_sem held */ -void ieee80211_start_bss(struct ieee80211_device *ieee) -{ - unsigned long flags; -#ifdef ENABLE_DOT11D - // - // Ref: 802.11d 11.1.3.3 - // STA shall not start a BSS unless properly formed Beacon frame including a Country IE. - // - if(IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee)) - { - if(! ieee->bGlobalDomain) - { - return; - } - } -#endif - /* check if we have already found the net we - * are interested in (if any). - * if not (we are disassociated and we are not - * in associating / authenticating phase) start the background scanning. - */ - ieee80211_softmac_check_all_nets(ieee); - - /* ensure no-one start an associating process (thus setting - * the ieee->state to ieee80211_ASSOCIATING) while we - * have just cheked it and we are going to enable scan. - * The ieee80211_new_net function is always called with - * lock held (from both ieee80211_softmac_check_all_nets and - * the rx path), so we cannot be in the middle of such function - */ - spin_lock_irqsave(&ieee->lock, flags); - - if (ieee->state == IEEE80211_NOLINK){ -#ifdef ENABLE_IPS - if(ieee->ieee80211_ips_leave_wq != NULL) - ieee->ieee80211_ips_leave_wq(ieee); -#endif - ieee->actscanning = true; - ieee80211_rtl_start_scan(ieee); - } - spin_unlock_irqrestore(&ieee->lock, flags); -} - -/* called only in userspace context */ -void ieee80211_disassociate(struct ieee80211_device *ieee) -{ - - - netif_carrier_off(ieee->dev); - if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE) - ieee80211_reset_queue(ieee); - - if (ieee->data_hard_stop) - ieee->data_hard_stop(ieee); -#ifdef ENABLE_DOT11D - if(IS_DOT11D_ENABLE(ieee)) - Dot11d_Reset(ieee); -#endif - ieee->is_set_key = false; - ieee->link_change(ieee); - if (ieee->state == IEEE80211_LINKED || - ieee->state == IEEE80211_ASSOCIATING) { - ieee->state = IEEE80211_NOLINK; - notify_wx_assoc_event(ieee); - } - - ieee->state = IEEE80211_NOLINK; - -} -void ieee80211_associate_retry_wq(struct work_struct *work) -{ - struct delayed_work *dwork = container_of(work, struct delayed_work, work); - struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, associate_retry_wq); - unsigned long flags; - - down(&ieee->wx_sem); - if(!ieee->proto_started) - goto exit; - - if(ieee->state != IEEE80211_ASSOCIATING_RETRY) - goto exit; - - /* until we do not set the state to IEEE80211_NOLINK - * there are no possibility to have someone else trying - * to start an association procdure (we get here with - * ieee->state = IEEE80211_ASSOCIATING). - * When we set the state to IEEE80211_NOLINK it is possible - * that the RX path run an attempt to associate, but - * both ieee80211_softmac_check_all_nets and the - * RX path works with ieee->lock held so there are no - * problems. If we are still disassociated then start a scan. - * the lock here is necessary to ensure no one try to start - * an association procedure when we have just checked the - * state and we are going to start the scan. - */ - ieee->beinretry = true; - ieee->state = IEEE80211_NOLINK; - - ieee80211_softmac_check_all_nets(ieee); - - spin_lock_irqsave(&ieee->lock, flags); - - if(ieee->state == IEEE80211_NOLINK) - { - ieee->is_roaming= false; - ieee->actscanning = true; - ieee80211_rtl_start_scan(ieee); - } - spin_unlock_irqrestore(&ieee->lock, flags); - - ieee->beinretry = false; -exit: - up(&ieee->wx_sem); -} - -struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee) -{ - u8 broadcast_addr[] = {0xff,0xff,0xff,0xff,0xff,0xff}; - - struct sk_buff *skb; - struct ieee80211_probe_response *b; - - skb = ieee80211_probe_resp(ieee, broadcast_addr); - - if (!skb) - return NULL; - - b = (struct ieee80211_probe_response *) skb->data; - b->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_BEACON); - - return skb; - -} - -struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee) -{ - struct sk_buff *skb; - struct ieee80211_probe_response *b; - - skb = ieee80211_get_beacon_(ieee); - if(!skb) - return NULL; - - b = (struct ieee80211_probe_response *) skb->data; - b->header.seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); - - if (ieee->seq_ctrl[0] == 0xFFF) - ieee->seq_ctrl[0] = 0; - else - ieee->seq_ctrl[0]++; - - return skb; -} - -void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee, u8 shutdown) -{ - ieee->sync_scan_hurryup = 1; - down(&ieee->wx_sem); - ieee80211_stop_protocol(ieee, shutdown); - up(&ieee->wx_sem); -} - - -void ieee80211_stop_protocol(struct ieee80211_device *ieee, u8 shutdown) -{ - if (!ieee->proto_started) - return; - - if(shutdown) - ieee->proto_started = 0; - ieee->proto_stoppping = 1; - - ieee80211_stop_send_beacons(ieee); - del_timer_sync(&ieee->associate_timer); - cancel_delayed_work(&ieee->associate_retry_wq); - cancel_delayed_work(&ieee->start_ibss_wq); - ieee80211_stop_scan(ieee); - - ieee80211_disassociate(ieee); - RemoveAllTS(ieee); //added as we disconnect from the previous BSS, Remove all TS - - ieee->proto_stoppping = 0; -} - -void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee) -{ - ieee->sync_scan_hurryup = 0; - down(&ieee->wx_sem); - ieee80211_start_protocol(ieee); - up(&ieee->wx_sem); -} - -void ieee80211_start_protocol(struct ieee80211_device *ieee) -{ - short ch = 0; - int i = 0; - if (ieee->proto_started) - return; - - ieee->proto_started = 1; - - if (ieee->current_network.channel == 0){ - do{ - ch++; - if (ch > MAX_CHANNEL_NUMBER) - return; /* no channel found */ -#ifdef ENABLE_DOT11D - }while(!GET_DOT11D_INFO(ieee)->channel_map[ch]); -#else - }while(!ieee->channel_map[ch]); -#endif - ieee->current_network.channel = ch; - } - - if (ieee->current_network.beacon_interval == 0) - ieee->current_network.beacon_interval = 100; - - for(i = 0; i < 17; i++) { - ieee->last_rxseq_num[i] = -1; - ieee->last_rxfrag_num[i] = -1; - ieee->last_packet_time[i] = 0; - } - - ieee->init_wmmparam_flag = 0;//reinitialize AC_xx_PARAM registers. - - ieee->state = IEEE80211_NOLINK; - - - /* if the user set the MAC of the ad-hoc cell and then - * switch to managed mode, shall we make sure that association - * attempts does not fail just because the user provide the essid - * and the nic is still checking for the AP MAC ?? - */ - if (ieee->iw_mode == IW_MODE_INFRA) - ieee80211_start_bss(ieee); - - else if (ieee->iw_mode == IW_MODE_ADHOC) - ieee80211_start_ibss(ieee); - - else if (ieee->iw_mode == IW_MODE_MASTER) - ieee80211_start_master_bss(ieee); - - else if(ieee->iw_mode == IW_MODE_MONITOR) - ieee80211_start_monitor_mode(ieee); -} - - -#define DRV_NAME "Ieee80211" -void ieee80211_softmac_init(struct ieee80211_device *ieee) -{ - int i; - memset(&ieee->current_network, 0, sizeof(struct ieee80211_network)); - - ieee->state = IEEE80211_NOLINK; - ieee->sync_scan_hurryup = 0; - for(i = 0; i < 5; i++) { - ieee->seq_ctrl[i] = 0; - } -#ifdef ENABLE_DOT11D - ieee->pDot11dInfo = kzalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC); - if (!ieee->pDot11dInfo) - IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for DOT11D\n"); -#endif - //added for AP roaming - ieee->LinkDetectInfo.SlotNum = 2; - ieee->LinkDetectInfo.NumRecvBcnInPeriod=0; - ieee->LinkDetectInfo.NumRecvDataInPeriod=0; - - ieee->assoc_id = 0; - ieee->queue_stop = 0; - ieee->scanning = 0; - ieee->softmac_features = 0; //so IEEE2100-like driver are happy - ieee->wap_set = 0; - ieee->ssid_set = 0; - ieee->proto_started = 0; - ieee->basic_rate = IEEE80211_DEFAULT_BASIC_RATE; - ieee->rate = 22; - ieee->ps = IEEE80211_PS_DISABLED; - ieee->sta_sleep = 0; - ieee->Regdot11HTOperationalRateSet[0]= 0xff;//support MCS 0~7 - ieee->Regdot11HTOperationalRateSet[1]= 0xff;//support MCS 8~15 - ieee->Regdot11HTOperationalRateSet[4]= 0x01; - //added by amy - ieee->actscanning = false; - ieee->beinretry = false; - ieee->is_set_key = false; - init_mgmt_queue(ieee); - - ieee->sta_edca_param[0] = 0x0000A403; - ieee->sta_edca_param[1] = 0x0000A427; - ieee->sta_edca_param[2] = 0x005E4342; - ieee->sta_edca_param[3] = 0x002F3262; - ieee->aggregation = true; - ieee->enable_rx_imm_BA = 1; - ieee->tx_pending.txb = NULL; - - init_timer(&ieee->associate_timer); - ieee->associate_timer.data = (unsigned long)ieee; - ieee->associate_timer.function = ieee80211_associate_abort_cb; - - init_timer(&ieee->beacon_timer); - ieee->beacon_timer.data = (unsigned long) ieee; - ieee->beacon_timer.function = ieee80211_send_beacon_cb; - - ieee->wq = create_workqueue(DRV_NAME); - - INIT_DELAYED_WORK(&ieee->start_ibss_wq,ieee80211_start_ibss_wq); - INIT_WORK(&ieee->associate_complete_wq, ieee80211_associate_complete_wq); - INIT_WORK(&ieee->associate_procedure_wq, ieee80211_associate_procedure_wq); - INIT_DELAYED_WORK(&ieee->softmac_scan_wq,ieee80211_softmac_scan_wq); - INIT_DELAYED_WORK(&ieee->associate_retry_wq, ieee80211_associate_retry_wq); - INIT_WORK(&ieee->wx_sync_scan_wq,ieee80211_wx_sync_scan_wq); - - sema_init(&ieee->wx_sem, 1); - sema_init(&ieee->scan_sem, 1); -#ifdef ENABLE_IPS - sema_init(&ieee->ips_sem,1); -#endif - spin_lock_init(&ieee->mgmt_tx_lock); - spin_lock_init(&ieee->beacon_lock); - - tasklet_init(&ieee->ps_task, - (void(*)(unsigned long)) ieee80211_sta_ps, - (unsigned long)ieee); - -} - -void ieee80211_softmac_free(struct ieee80211_device *ieee) -{ - down(&ieee->wx_sem); -#ifdef ENABLE_DOT11D - kfree(ieee->pDot11dInfo); - ieee->pDot11dInfo = NULL; -#endif - del_timer_sync(&ieee->associate_timer); - - cancel_delayed_work(&ieee->associate_retry_wq); - destroy_workqueue(ieee->wq); - - up(&ieee->wx_sem); -} - -/******************************************************** - * Start of WPA code. * - * this is stolen from the ipw2200 driver * - ********************************************************/ - - -static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value) -{ - /* This is called when wpa_supplicant loads and closes the driver - * interface. */ - printk("%s WPA\n",value ? "enabling" : "disabling"); - ieee->wpa_enabled = value; - return 0; -} - - -void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee, char *wpa_ie, int wpa_ie_len) -{ - /* make sure WPA is enabled */ - ieee80211_wpa_enable(ieee, 1); - - ieee80211_disassociate(ieee); -} - - -static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command, int reason) -{ - - int ret = 0; - - switch (command) { - case IEEE_MLME_STA_DEAUTH: - // silently ignore - break; - - case IEEE_MLME_STA_DISASSOC: - ieee80211_disassociate(ieee); - break; - - default: - printk("Unknown MLME request: %d\n", command); - ret = -EOPNOTSUPP; - } - - return ret; -} - - -static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee, - struct ieee_param *param, int plen) -{ - u8 *buf; - - if (param->u.wpa_ie.len > MAX_WPA_IE_LEN || - (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL)) - return -EINVAL; - - if (param->u.wpa_ie.len) { - buf = kmemdup(param->u.wpa_ie.data, param->u.wpa_ie.len, - GFP_KERNEL); - if (buf == NULL) - return -ENOMEM; - - kfree(ieee->wpa_ie); - ieee->wpa_ie = buf; - ieee->wpa_ie_len = param->u.wpa_ie.len; - } else { - kfree(ieee->wpa_ie); - ieee->wpa_ie = NULL; - ieee->wpa_ie_len = 0; - } - - ieee80211_wpa_assoc_frame(ieee, ieee->wpa_ie, ieee->wpa_ie_len); - return 0; -} - -#define AUTH_ALG_OPEN_SYSTEM 0x1 -#define AUTH_ALG_SHARED_KEY 0x2 - -static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value) -{ - - struct ieee80211_security sec = { - .flags = SEC_AUTH_MODE, - }; - int ret = 0; - - if (value & AUTH_ALG_SHARED_KEY) { - sec.auth_mode = WLAN_AUTH_SHARED_KEY; - ieee->open_wep = 0; - ieee->auth_mode = 1; - } else if (value & AUTH_ALG_OPEN_SYSTEM){ - sec.auth_mode = WLAN_AUTH_OPEN; - ieee->open_wep = 1; - ieee->auth_mode = 0; - } - else if (value & IW_AUTH_ALG_LEAP){ - sec.auth_mode = WLAN_AUTH_LEAP; - ieee->open_wep = 1; - ieee->auth_mode = 2; - } - - - if (ieee->set_security) - ieee->set_security(ieee, &sec); - - return ret; -} - -static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name, u32 value) -{ - int ret=0; - unsigned long flags; - - switch (name) { - case IEEE_PARAM_WPA_ENABLED: - ret = ieee80211_wpa_enable(ieee, value); - break; - - case IEEE_PARAM_TKIP_COUNTERMEASURES: - ieee->tkip_countermeasures=value; - break; - - case IEEE_PARAM_DROP_UNENCRYPTED: { - /* HACK: - * - * wpa_supplicant calls set_wpa_enabled when the driver - * is loaded and unloaded, regardless of if WPA is being - * used. No other calls are made which can be used to - * determine if encryption will be used or not prior to - * association being expected. If encryption is not being - * used, drop_unencrypted is set to false, else true -- we - * can use this to determine if the CAP_PRIVACY_ON bit should - * be set. - */ - struct ieee80211_security sec = { - .flags = SEC_ENABLED, - .enabled = value, - }; - ieee->drop_unencrypted = value; - /* We only change SEC_LEVEL for open mode. Others - * are set by ipw_wpa_set_encryption. - */ - if (!value) { - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_0; - } - else { - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_1; - } - if (ieee->set_security) - ieee->set_security(ieee, &sec); - break; - } - - case IEEE_PARAM_PRIVACY_INVOKED: - ieee->privacy_invoked=value; - break; - - case IEEE_PARAM_AUTH_ALGS: - ret = ieee80211_wpa_set_auth_algs(ieee, value); - break; - - case IEEE_PARAM_IEEE_802_1X: - ieee->ieee802_1x=value; - break; - case IEEE_PARAM_WPAX_SELECT: - // added for WPA2 mixed mode - spin_lock_irqsave(&ieee->wpax_suitlist_lock,flags); - ieee->wpax_type_set = 1; - ieee->wpax_type_notify = value; - spin_unlock_irqrestore(&ieee->wpax_suitlist_lock,flags); - break; - - default: - printk("Unknown WPA param: %d\n",name); - ret = -EOPNOTSUPP; - } - - return ret; -} - -/* implementation borrowed from hostap driver */ - -static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee, - struct ieee_param *param, int param_len) -{ - int ret = 0; - - struct ieee80211_crypto_ops *ops; - struct ieee80211_crypt_data **crypt; - - struct ieee80211_security sec = { - .flags = 0, - }; - - param->u.crypt.err = 0; - param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0'; - - if (param_len != - (int) ((char *) param->u.crypt.key - (char *) param) + - param->u.crypt.key_len) { - printk("Len mismatch %d, %d\n", param_len, - param->u.crypt.key_len); - return -EINVAL; - } - if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && - param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && - param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { - if (param->u.crypt.idx >= WEP_KEYS) - return -EINVAL; - crypt = &ieee->crypt[param->u.crypt.idx]; - } else { - return -EINVAL; - } - - if (strcmp(param->u.crypt.alg, "none") == 0) { - if (crypt) { - sec.enabled = 0; - // FIXME FIXME - //sec.encrypt = 0; - sec.level = SEC_LEVEL_0; - sec.flags |= SEC_ENABLED | SEC_LEVEL; - ieee80211_crypt_delayed_deinit(ieee, crypt); - } - goto done; - } - sec.enabled = 1; -// FIXME FIXME -// sec.encrypt = 1; - sec.flags |= SEC_ENABLED; - - /* IPW HW cannot build TKIP MIC, host decryption still needed. */ - if (!(ieee->host_encrypt || ieee->host_decrypt) && - strcmp(param->u.crypt.alg, "TKIP")) - goto skip_host_crypt; - - ops = ieee80211_get_crypto_ops(param->u.crypt.alg); - if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) - ops = ieee80211_get_crypto_ops(param->u.crypt.alg); - /* set WEP40 first, it will be modified according to WEP104 or - * WEP40 at other place */ - else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) - ops = ieee80211_get_crypto_ops(param->u.crypt.alg); - else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) - ops = ieee80211_get_crypto_ops(param->u.crypt.alg); - if (ops == NULL) { - printk("unknown crypto alg '%s'\n", param->u.crypt.alg); - param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG; - ret = -EINVAL; - goto done; - } - - if (*crypt == NULL || (*crypt)->ops != ops) { - struct ieee80211_crypt_data *new_crypt; - - ieee80211_crypt_delayed_deinit(ieee, crypt); - - new_crypt = kmalloc(sizeof(*new_crypt), GFP_KERNEL); - if (new_crypt == NULL) { - ret = -ENOMEM; - goto done; - } - memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data)); - new_crypt->ops = ops; - if (new_crypt->ops) - new_crypt->priv = - new_crypt->ops->init(param->u.crypt.idx); - - if (new_crypt->priv == NULL) { - kfree(new_crypt); - param->u.crypt.err = IEEE_CRYPT_ERR_CRYPT_INIT_FAILED; - ret = -EINVAL; - goto done; - } - - *crypt = new_crypt; - } - - if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key && - (*crypt)->ops->set_key(param->u.crypt.key, - param->u.crypt.key_len, param->u.crypt.seq, - (*crypt)->priv) < 0) { - printk("key setting failed\n"); - param->u.crypt.err = IEEE_CRYPT_ERR_KEY_SET_FAILED; - ret = -EINVAL; - goto done; - } - - skip_host_crypt: - if (param->u.crypt.set_tx) { - ieee->tx_keyidx = param->u.crypt.idx; - sec.active_key = param->u.crypt.idx; - sec.flags |= SEC_ACTIVE_KEY; - } else - sec.flags &= ~SEC_ACTIVE_KEY; - - if (param->u.crypt.alg != NULL) { - memcpy(sec.keys[param->u.crypt.idx], - param->u.crypt.key, - param->u.crypt.key_len); - sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len; - sec.flags |= (1 << param->u.crypt.idx); - - if (strcmp(param->u.crypt.alg, "WEP") == 0) { - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_1; - } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) { - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_2; - } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) { - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_3; - } - } - done: - if (ieee->set_security) - ieee->set_security(ieee, &sec); - - /* Do not reset port if card is in Managed mode since resetting will - * generate new IEEE 802.11 authentication which may end up in looping - * with IEEE 802.1X. If your hardware requires a reset after WEP - * configuration (for example... Prism2), implement the reset_port in - * the callbacks structures used to initialize the 802.11 stack. */ - if (ieee->reset_on_keychange && - ieee->iw_mode != IW_MODE_INFRA && - ieee->reset_port && - ieee->reset_port(ieee)) { - printk("reset_port failed\n"); - param->u.crypt.err = IEEE_CRYPT_ERR_CARD_CONF_FAILED; - return -EINVAL; - } - - return ret; -} - -inline struct sk_buff *ieee80211_disassociate_skb( - struct ieee80211_network *beacon, - struct ieee80211_device *ieee, - u8 asRsn) -{ - struct sk_buff *skb; - struct ieee80211_disassoc *disass; - - skb = dev_alloc_skb(sizeof(struct ieee80211_disassoc)); - if (!skb) - return NULL; - - disass = (struct ieee80211_disassoc *) skb_put(skb,sizeof(struct ieee80211_disassoc)); - disass->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_DISASSOC); - disass->header.duration_id = 0; - - memcpy(disass->header.addr1, beacon->bssid, ETH_ALEN); - memcpy(disass->header.addr2, ieee->dev->dev_addr, ETH_ALEN); - memcpy(disass->header.addr3, beacon->bssid, ETH_ALEN); - - disass->reason = asRsn; - return skb; -} - - -void -SendDisassociation( - struct ieee80211_device *ieee, - u8* asSta, - u8 asRsn -) -{ - struct ieee80211_network *beacon = &ieee->current_network; - struct sk_buff *skb; - skb = ieee80211_disassociate_skb(beacon,ieee,asRsn); - if (skb){ - softmac_mgmt_xmit(skb, ieee); - //dev_kfree_skb_any(skb);//edit by thomas - } -} - -int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee, struct iw_point *p) -{ - struct ieee_param *param; - int ret=0; - - down(&ieee->wx_sem); - //IEEE_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length); - - if (p->length < sizeof(struct ieee_param) || !p->pointer){ - ret = -EINVAL; - goto out; - } - - param = kmalloc(p->length, GFP_KERNEL); - if (param == NULL){ - ret = -ENOMEM; - goto out; - } - if (copy_from_user(param, p->pointer, p->length)) { - kfree(param); - ret = -EFAULT; - goto out; - } - - switch (param->cmd) { - - case IEEE_CMD_SET_WPA_PARAM: - ret = ieee80211_wpa_set_param(ieee, param->u.wpa_param.name, - param->u.wpa_param.value); - break; - - case IEEE_CMD_SET_WPA_IE: - ret = ieee80211_wpa_set_wpa_ie(ieee, param, p->length); - break; - - case IEEE_CMD_SET_ENCRYPTION: - ret = ieee80211_wpa_set_encryption(ieee, param, p->length); - break; - - case IEEE_CMD_MLME: - ret = ieee80211_wpa_mlme(ieee, param->u.mlme.command, - param->u.mlme.reason_code); - break; - - default: - printk("Unknown WPA supplicant request: %d\n",param->cmd); - ret = -EOPNOTSUPP; - break; - } - - if (ret == 0 && copy_to_user(p->pointer, param, p->length)) - ret = -EFAULT; - - kfree(param); -out: - up(&ieee->wx_sem); - - return ret; -} - -void notify_wx_assoc_event(struct ieee80211_device *ieee) -{ - union iwreq_data wrqu; - wrqu.ap_addr.sa_family = ARPHRD_ETHER; - if (ieee->state == IEEE80211_LINKED) - memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid, ETH_ALEN); - else - memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); - wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL); -} diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c deleted file mode 100644 index 424dd48..0000000 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c +++ /dev/null @@ -1,955 +0,0 @@ -/****************************************************************************** - - Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved. - - This program is free software; you can redistribute it and/or modify it - under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - You should have received a copy of the GNU General Public License along with - this program; if not, write to the Free Software Foundation, Inc., 59 - Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - The full GNU General Public License is included in this distribution in the - file called LICENSE. - - Contact Information: - James P. Ketrenos <ipw2100-admin@linux.intel.com> - Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - -****************************************************************************** - - Few modifications for Realtek's Wi-Fi drivers by - Andrea Merello <andreamrl@tiscali.it> - - A special thanks goes to Realtek for their support ! - -******************************************************************************/ - -#include <linux/compiler.h> -#include <linux/errno.h> -#include <linux/if_arp.h> -#include <linux/in6.h> -#include <linux/in.h> -#include <linux/ip.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/netdevice.h> -#include <linux/pci.h> -#include <linux/proc_fs.h> -#include <linux/skbuff.h> -#include <linux/slab.h> -#include <linux/tcp.h> -#include <linux/types.h> -#include <linux/wireless.h> -#include <linux/etherdevice.h> -#include <asm/uaccess.h> -#include <linux/if_vlan.h> - -#include "ieee80211.h" - - -/* - - -802.11 Data Frame - - -802.11 frame_contorl for data frames - 2 bytes - ,-----------------------------------------------------------------------------------------. -bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e | - |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------| -val | 0 | 0 | 0 | 1 | x | 0 | 0 | 0 | 1 | 0 | x | x | x | x | x | - |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------| -desc | ^-ver-^ | ^type-^ | ^-----subtype-----^ | to |from |more |retry| pwr |more |wep | - | | | x=0 data,x=1 data+ack | DS | DS |frag | | mgm |data | | - '-----------------------------------------------------------------------------------------' - /\ - | -802.11 Data Frame | - ,--------- 'ctrl' expands to >-----------' - | - ,--'---,-------------------------------------------------------------. -Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 | - |------|------|---------|---------|---------|------|---------|------| -Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | Frame | fcs | - | | tion | (BSSID) | | | ence | data | | - `--------------------------------------------------| |------' -Total: 28 non-data bytes `----.----' - | - .- 'Frame data' expands to <---------------------------' - | - V - ,---------------------------------------------------. -Bytes | 1 | 1 | 1 | 3 | 2 | 0-2304 | - |------|------|---------|----------|------|---------| -Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP | - | DSAP | SSAP | | | | Packet | - | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8| | | - `-----------------------------------------| | -Total: 8 non-data bytes `----.----' - | - .- 'IP Packet' expands, if WEP enabled, to <--' - | - V - ,-----------------------. -Bytes | 4 | 0-2296 | 4 | - |-----|-----------|-----| -Desc. | IV | Encrypted | ICV | - | | IP Packet | | - `-----------------------' -Total: 8 non-data bytes - - -802.3 Ethernet Data Frame - - ,-----------------------------------------. -Bytes | 6 | 6 | 2 | Variable | 4 | - |-------|-------|------|-----------|------| -Desc. | Dest. | Source| Type | IP Packet | fcs | - | MAC | MAC | | | | - `-----------------------------------------' -Total: 18 non-data bytes - -In the event that fragmentation is required, the incoming payload is split into -N parts of size ieee->fts. The first fragment contains the SNAP header and the -remaining packets are just data. - -If encryption is enabled, each fragment payload size is reduced by enough space -to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP) -So if you have 1500 bytes of payload with ieee->fts set to 500 without -encryption it will take 3 frames. With WEP it will take 4 frames as the -payload of each frame is reduced to 492 bytes. - -* SKB visualization -* -* ,- skb->data -* | -* | ETHERNET HEADER ,-<-- PAYLOAD -* | | 14 bytes from skb->data -* | 2 bytes for Type --> ,T. | (sizeof ethhdr) -* | | | | -* |,-Dest.--. ,--Src.---. | | | -* | 6 bytes| | 6 bytes | | | | -* v | | | | | | -* 0 | v 1 | v | v 2 -* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 -* ^ | ^ | ^ | -* | | | | | | -* | | | | `T' <---- 2 bytes for Type -* | | | | -* | | '---SNAP--' <-------- 6 bytes for SNAP -* | | -* `-IV--' <-------------------- 4 bytes for IV (WEP) -* -* SNAP HEADER -* -*/ - -static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 }; -static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 }; - -static inline int ieee80211_put_snap(u8 *data, u16 h_proto) -{ - struct ieee80211_snap_hdr *snap; - u8 *oui; - - snap = (struct ieee80211_snap_hdr *)data; - snap->dsap = 0xaa; - snap->ssap = 0xaa; - snap->ctrl = 0x03; - - if (h_proto == 0x8137 || h_proto == 0x80f3) - oui = P802_1H_OUI; - else - oui = RFC1042_OUI; - snap->oui[0] = oui[0]; - snap->oui[1] = oui[1]; - snap->oui[2] = oui[2]; - - *(u16 *)(data + SNAP_SIZE) = htons(h_proto); - - return SNAP_SIZE + sizeof(u16); -} - -int ieee80211_encrypt_fragment( - struct ieee80211_device *ieee, - struct sk_buff *frag, - int hdr_len) -{ - struct ieee80211_crypt_data* crypt = ieee->crypt[ieee->tx_keyidx]; - int res; - - if (!(crypt && crypt->ops)) - { - printk("=========>%s(), crypt is null\n", __FUNCTION__); - return -1; - } -#ifdef CONFIG_IEEE80211_CRYPT_TKIP - struct ieee80211_hdr *header; - - if (ieee->tkip_countermeasures && - crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) { - header = (struct ieee80211_hdr *) frag->data; - if (net_ratelimit()) { - printk(KERN_DEBUG "%s: TKIP countermeasures: dropped " - "TX packet to %pM\n", - ieee->dev->name, header->addr1); - } - return -1; - } -#endif - /* To encrypt, frame format is: - * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */ - - // PR: FIXME: Copied from hostap. Check fragmentation/MSDU/MPDU encryption. - /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so - * call both MSDU and MPDU encryption functions from here. */ - atomic_inc(&crypt->refcnt); - res = 0; - if (crypt->ops->encrypt_msdu) - res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv); - if (res == 0 && crypt->ops->encrypt_mpdu) - res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv); - - atomic_dec(&crypt->refcnt); - if (res < 0) { - printk(KERN_INFO "%s: Encryption failed: len=%d.\n", - ieee->dev->name, frag->len); - ieee->ieee_stats.tx_discards++; - return -1; - } - - return 0; -} - - -void ieee80211_txb_free(struct ieee80211_txb *txb) { - if (unlikely(!txb)) - return; - kfree(txb); -} - -struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size, - int gfp_mask) -{ - struct ieee80211_txb *txb; - int i; - txb = kmalloc( - sizeof(struct ieee80211_txb) + (sizeof(u8*) * nr_frags), - gfp_mask); - if (!txb) - return NULL; - - memset(txb, 0, sizeof(struct ieee80211_txb)); - txb->nr_frags = nr_frags; - txb->frag_size = txb_size; - - for (i = 0; i < nr_frags; i++) { - txb->fragments[i] = dev_alloc_skb(txb_size); - if (unlikely(!txb->fragments[i])) { - i--; - break; - } - memset(txb->fragments[i]->cb, 0, sizeof(txb->fragments[i]->cb)); - } - if (unlikely(i != nr_frags)) { - while (i >= 0) - dev_kfree_skb_any(txb->fragments[i--]); - kfree(txb); - return NULL; - } - return txb; -} - -// Classify the to-be send data packet -// Need to acquire the sent queue index. -static int -ieee80211_classify(struct sk_buff *skb, struct ieee80211_network *network) -{ - struct ethhdr *eth; - struct iphdr *ip; - eth = (struct ethhdr *)skb->data; - if (eth->h_proto != htons(ETH_P_IP)) - return 0; - - ip = ip_hdr(skb); - switch (ip->tos & 0xfc) { - case 0x20: - return 2; - case 0x40: - return 1; - case 0x60: - return 3; - case 0x80: - return 4; - case 0xa0: - return 5; - case 0xc0: - return 6; - case 0xe0: - return 7; - default: - return 0; - } -} - -#define SN_LESS(a, b) (((a-b)&0x800)!=0) -void ieee80211_tx_query_agg_cap(struct ieee80211_device* ieee, struct sk_buff* skb, cb_desc* tcb_desc) -{ - PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; - PTX_TS_RECORD pTxTs = NULL; - struct ieee80211_hdr_1addr* hdr = (struct ieee80211_hdr_1addr*)skb->data; - - if (!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT) - return; - if (!IsQoSDataFrame(skb->data)) - return; - - if (is_multicast_ether_addr(hdr->addr1) || is_broadcast_ether_addr(hdr->addr1)) - return; - //check packet and mode later -#ifdef TO_DO_LIST - if(pTcb->PacketLength >= 4096) - return; - // For RTL819X, if pairwisekey = wep/tkip, we don't aggrregation. - if(!Adapter->HalFunc.GetNmodeSupportBySecCfgHandler(Adapter)) - return; -#endif - - if(tcb_desc->bdhcp)// || ieee->CntAfterLink<2) - { - return; - } - - -#if 1 - if (!ieee->GetNmodeSupportBySecCfg(ieee)) - { - return; - } -#endif - if(pHTInfo->bCurrentAMPDUEnable) - { - if (!GetTs(ieee, (PTS_COMMON_INFO*)(&pTxTs), hdr->addr1, skb->priority, TX_DIR, true)) - { - printk("===>can't get TS\n"); - return; - } - if (pTxTs->TxAdmittedBARecord.bValid == false) - { - //as some AP will refuse our action frame until key handshake has been finished. WB - if (ieee->wpa_ie_len && (ieee->pairwise_key_type == KEY_TYPE_NA)) - ; - else - TsStartAddBaProcess(ieee, pTxTs); - goto FORCED_AGG_SETTING; - } - else if (pTxTs->bUsingBa == false) - { - if (SN_LESS(pTxTs->TxAdmittedBARecord.BaStartSeqCtrl.field.SeqNum, (pTxTs->TxCurSeq+1)%4096)) - pTxTs->bUsingBa = true; - else - goto FORCED_AGG_SETTING; - } - - if (ieee->iw_mode == IW_MODE_INFRA) - { - tcb_desc->bAMPDUEnable = true; - tcb_desc->ampdu_factor = pHTInfo->CurrentAMPDUFactor; - tcb_desc->ampdu_density = pHTInfo->CurrentMPDUDensity; - } - } -FORCED_AGG_SETTING: - switch(pHTInfo->ForcedAMPDUMode ) - { - case HT_AGG_AUTO: - break; - - case HT_AGG_FORCE_ENABLE: - tcb_desc->bAMPDUEnable = true; - tcb_desc->ampdu_density = pHTInfo->ForcedMPDUDensity; - tcb_desc->ampdu_factor = pHTInfo->ForcedAMPDUFactor; - break; - - case HT_AGG_FORCE_DISABLE: - tcb_desc->bAMPDUEnable = false; - tcb_desc->ampdu_density = 0; - tcb_desc->ampdu_factor = 0; - break; - - } - return; -} - -extern void ieee80211_qurey_ShortPreambleMode(struct ieee80211_device* ieee, cb_desc* tcb_desc) -{ - tcb_desc->bUseShortPreamble = false; - if (tcb_desc->data_rate == 2) - {//// 1M can only use Long Preamble. 11B spec - return; - } - else if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE) - { - tcb_desc->bUseShortPreamble = true; - } - return; -} -extern void -ieee80211_query_HTCapShortGI(struct ieee80211_device *ieee, cb_desc *tcb_desc) -{ - PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; - - tcb_desc->bUseShortGI = false; - - if(!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT) - return; - - if(pHTInfo->bForcedShortGI) - { - tcb_desc->bUseShortGI = true; - return; - } - - if((pHTInfo->bCurBW40MHz==true) && pHTInfo->bCurShortGI40MHz) - tcb_desc->bUseShortGI = true; - else if((pHTInfo->bCurBW40MHz==false) && pHTInfo->bCurShortGI20MHz) - tcb_desc->bUseShortGI = true; -} - -void ieee80211_query_BandwidthMode(struct ieee80211_device* ieee, cb_desc *tcb_desc) -{ - PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; - - tcb_desc->bPacketBW = false; - - if(!pHTInfo->bCurrentHTSupport||!pHTInfo->bEnableHT) - return; - - if(tcb_desc->bMulticast || tcb_desc->bBroadcast) - return; - - if((tcb_desc->data_rate & 0x80)==0) // If using legacy rate, it shall use 20MHz channel. - return; - //BandWidthAutoSwitch is for auto switch to 20 or 40 in long distance - if(pHTInfo->bCurBW40MHz && pHTInfo->bCurTxBW40MHz && !ieee->bandwidth_auto_switch.bforced_tx20Mhz) - tcb_desc->bPacketBW = true; - return; -} - -void ieee80211_query_protectionmode(struct ieee80211_device* ieee, cb_desc* tcb_desc, struct sk_buff* skb) -{ - // Common Settings - tcb_desc->bRTSSTBC = false; - tcb_desc->bRTSUseShortGI = false; // Since protection frames are always sent by legacy rate, ShortGI will never be used. - tcb_desc->bCTSEnable = false; // Most of protection using RTS/CTS - tcb_desc->RTSSC = 0; // 20MHz: Don't care; 40MHz: Duplicate. - tcb_desc->bRTSBW = false; // RTS frame bandwidth is always 20MHz - - if(tcb_desc->bBroadcast || tcb_desc->bMulticast)//only unicast frame will use rts/cts - return; - - if (is_broadcast_ether_addr(skb->data+16)) //check addr3 as infrastructure add3 is DA. - return; - - if (ieee->mode < IEEE_N_24G) //b, g mode - { - // (1) RTS_Threshold is compared to the MPDU, not MSDU. - // (2) If there are more than one frag in this MSDU, only the first frag uses protection frame. - // Other fragments are protected by previous fragment. - // So we only need to check the length of first fragment. - if (skb->len > ieee->rts) - { - tcb_desc->bRTSEnable = true; - tcb_desc->rts_rate = MGN_24M; - } - else if (ieee->current_network.buseprotection) - { - // Use CTS-to-SELF in protection mode. - tcb_desc->bRTSEnable = true; - tcb_desc->bCTSEnable = true; - tcb_desc->rts_rate = MGN_24M; - } - //otherwise return; - return; - } - else - {// 11n High throughput case. - PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; - while (true) - { - //check ERP protection - if (ieee->current_network.buseprotection) - {// CTS-to-SELF - tcb_desc->bRTSEnable = true; - tcb_desc->bCTSEnable = true; - tcb_desc->rts_rate = MGN_24M; - break; - } - //check HT op mode - if(pHTInfo->bCurrentHTSupport && pHTInfo->bEnableHT) - { - u8 HTOpMode = pHTInfo->CurrentOpMode; - if((pHTInfo->bCurBW40MHz && (HTOpMode == 2 || HTOpMode == 3)) || - (!pHTInfo->bCurBW40MHz && HTOpMode == 3) ) - { - tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps. - tcb_desc->bRTSEnable = true; - break; - } - } - //check rts - if (skb->len > ieee->rts) - { - tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps. - tcb_desc->bRTSEnable = true; - break; - } - //to do list: check MIMO power save condition. - //check AMPDU aggregation for TXOP - if(tcb_desc->bAMPDUEnable) - { - tcb_desc->rts_rate = MGN_24M; // Rate is 24Mbps. - // According to 8190 design, firmware sends CF-End only if RTS/CTS is enabled. However, it degrads - // throughput around 10M, so we disable of this mechanism. 2007.08.03 by Emily - tcb_desc->bRTSEnable = false; - break; - } - //check IOT action - if(pHTInfo->IOTAction & HT_IOT_ACT_FORCED_CTS2SELF) - { - tcb_desc->bCTSEnable = true; - tcb_desc->rts_rate = MGN_24M; - tcb_desc->bRTSEnable = true; - break; - } - // Totally no protection case!! - goto NO_PROTECTION; - } - } - // For test , CTS replace with RTS - if( 0 ) - { - tcb_desc->bCTSEnable = true; - tcb_desc->rts_rate = MGN_24M; - tcb_desc->bRTSEnable = true; - } - if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE) - tcb_desc->bUseShortPreamble = true; - if (ieee->mode == IW_MODE_MASTER) - goto NO_PROTECTION; - return; -NO_PROTECTION: - tcb_desc->bRTSEnable = false; - tcb_desc->bCTSEnable = false; - tcb_desc->rts_rate = 0; - tcb_desc->RTSSC = 0; - tcb_desc->bRTSBW = false; -} - - -void ieee80211_txrate_selectmode(struct ieee80211_device* ieee, cb_desc* tcb_desc) -{ -#ifdef TO_DO_LIST - if(!IsDataFrame(pFrame)) - { - pTcb->bTxDisableRateFallBack = TRUE; - pTcb->bTxUseDriverAssingedRate = TRUE; - pTcb->RATRIndex = 7; - return; - } - - if(pMgntInfo->ForcedDataRate!= 0) - { - pTcb->bTxDisableRateFallBack = TRUE; - pTcb->bTxUseDriverAssingedRate = TRUE; - return; - } -#endif - if(ieee->bTxDisableRateFallBack) - tcb_desc->bTxDisableRateFallBack = true; - - if(ieee->bTxUseDriverAssingedRate) - tcb_desc->bTxUseDriverAssingedRate = true; - if(!tcb_desc->bTxDisableRateFallBack || !tcb_desc->bTxUseDriverAssingedRate) - { - if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC) - tcb_desc->RATRIndex = 0; - } -} - -void ieee80211_query_seqnum(struct ieee80211_device*ieee, struct sk_buff* skb, u8* dst) -{ - if (is_multicast_ether_addr(dst) || is_broadcast_ether_addr(dst)) - return; - if (IsQoSDataFrame(skb->data)) //we deal qos data only - { - PTX_TS_RECORD pTS = NULL; - if (!GetTs(ieee, (PTS_COMMON_INFO*)(&pTS), dst, skb->priority, TX_DIR, true)) - { - return; - } - pTS->TxCurSeq = (pTS->TxCurSeq+1)%4096; - } -} - -int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev) -{ - struct ieee80211_device *ieee = netdev_priv(dev); - struct ieee80211_txb *txb = NULL; - struct ieee80211_hdr_3addrqos *frag_hdr; - int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size; - unsigned long flags; - struct net_device_stats *stats = &ieee->stats; - int ether_type = 0, encrypt; - int bytes, fc, qos_ctl = 0, hdr_len; - struct sk_buff *skb_frag; - struct ieee80211_hdr_3addrqos header = { /* Ensure zero initialized */ - .duration_id = 0, - .seq_ctl = 0, - .qos_ctl = 0 - }; - u8 dest[ETH_ALEN], src[ETH_ALEN]; - int qos_actived = ieee->current_network.qos_data.active; - - struct ieee80211_crypt_data* crypt; - bool bdhcp =false; - - cb_desc *tcb_desc; - - spin_lock_irqsave(&ieee->lock, flags); - - /* If there is no driver handler to take the TXB, dont' bother - * creating it... */ - if ((!ieee->hard_start_xmit && !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE))|| - ((!ieee->softmac_data_hard_start_xmit && (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) { - printk(KERN_WARNING "%s: No xmit handler.\n", - ieee->dev->name); - goto success; - } - - - if(likely(ieee->raw_tx == 0)){ - if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) { - printk(KERN_WARNING "%s: skb too small (%d).\n", - ieee->dev->name, skb->len); - goto success; - } - - memset(skb->cb, 0, sizeof(skb->cb)); - ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto); - - crypt = ieee->crypt[ieee->tx_keyidx]; - - encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) && - ieee->host_encrypt && crypt && crypt->ops; - - if (!encrypt && ieee->ieee802_1x && - ieee->drop_unencrypted && ether_type != ETH_P_PAE) { - stats->tx_dropped++; - goto success; - } - #ifdef CONFIG_IEEE80211_DEBUG - if (crypt && !encrypt && ether_type == ETH_P_PAE) { - struct eapol *eap = (struct eapol *)(skb->data + - sizeof(struct ethhdr) - SNAP_SIZE - sizeof(u16)); - IEEE80211_DEBUG_EAP("TX: IEEE 802.11 EAPOL frame: %s\n", - eap_get_type(eap->type)); - } - #endif - - // The following is for DHCP and ARP packet, we use cck1M to tx these packets and let LPS awake some time - // to prevent DHCP protocol fail - if (skb->len > 282){//MINIMUM_DHCP_PACKET_SIZE) { - if (ETH_P_IP == ether_type) {// IP header - const struct iphdr *ip = (struct iphdr *)((u8 *)skb->data+14); - if (IPPROTO_UDP == ip->protocol) {//FIXME windows is 11 but here UDP in linux kernel is 17. - struct udphdr *udp = (struct udphdr *)((u8 *)ip + (ip->ihl << 2)); - if(((((u8 *)udp)[1] == 68) && (((u8 *)udp)[3] == 67)) || - ((((u8 *)udp)[1] == 67) && (((u8 *)udp)[3] == 68))) { - // 68 : UDP BOOTP client - // 67 : UDP BOOTP server - printk("DHCP pkt src port:%d, dest port:%d!!\n", ((u8 *)udp)[1],((u8 *)udp)[3]); - - bdhcp = true; -#ifdef _RTL8192_EXT_PATCH_ - ieee->LPSDelayCnt = 100;//pPSC->LPSAwakeIntvl*2; //AMY,090701 -#else - ieee->LPSDelayCnt = 100;//pPSC->LPSAwakeIntvl*2; -#endif - } - } - }else if(ETH_P_ARP == ether_type){// IP ARP packet - printk("=================>DHCP Protocol start tx ARP pkt!!\n"); - bdhcp = true; - ieee->LPSDelayCnt = ieee->current_network.tim.tim_count; - - } - } - - /* Save source and destination addresses */ - memcpy(&dest, skb->data, ETH_ALEN); - memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN); - - /* Advance the SKB to the start of the payload */ - skb_pull(skb, sizeof(struct ethhdr)); - - /* Determine total amount of storage required for TXB packets */ - bytes = skb->len + SNAP_SIZE + sizeof(u16); - - if (encrypt) - fc = IEEE80211_FTYPE_DATA | IEEE80211_FCTL_WEP; - else - - fc = IEEE80211_FTYPE_DATA; - - if(qos_actived) - fc |= IEEE80211_STYPE_QOS_DATA; - else - fc |= IEEE80211_STYPE_DATA; - - if (ieee->iw_mode == IW_MODE_INFRA) { - fc |= IEEE80211_FCTL_TODS; - /* To DS: Addr1 = BSSID, Addr2 = SA, - Addr3 = DA */ - memcpy(&header.addr1, ieee->current_network.bssid, ETH_ALEN); - memcpy(&header.addr2, &src, ETH_ALEN); - memcpy(&header.addr3, &dest, ETH_ALEN); - } else if (ieee->iw_mode == IW_MODE_ADHOC) { - /* not From/To DS: Addr1 = DA, Addr2 = SA, - Addr3 = BSSID */ - memcpy(&header.addr1, dest, ETH_ALEN); - memcpy(&header.addr2, src, ETH_ALEN); - memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN); - } - - header.frame_ctl = cpu_to_le16(fc); - - /* Determine fragmentation size based on destination (multicast - * and broadcast are not fragmented) */ - if (is_multicast_ether_addr(header.addr1) || - is_broadcast_ether_addr(header.addr1)) { - frag_size = MAX_FRAG_THRESHOLD; - qos_ctl |= QOS_CTL_NOTCONTAIN_ACK; - } - else { - frag_size = ieee->fts;//default:392 - qos_ctl = 0; - } - - if(qos_actived) - { - hdr_len = IEEE80211_3ADDR_LEN + 2; - - skb->priority = ieee80211_classify(skb, &ieee->current_network); - qos_ctl |= skb->priority; //set in the ieee80211_classify - header.qos_ctl = cpu_to_le16(qos_ctl & IEEE80211_QOS_TID); - } else { - hdr_len = IEEE80211_3ADDR_LEN; - } - /* Determine amount of payload per fragment. Regardless of if - * this stack is providing the full 802.11 header, one will - * eventually be affixed to this fragment -- so we must account for - * it when determining the amount of payload space. */ - bytes_per_frag = frag_size - hdr_len; - if (ieee->config & - (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS)) - bytes_per_frag -= IEEE80211_FCS_LEN; - - /* Each fragment may need to have room for encryption pre/postfix */ - if (encrypt) - bytes_per_frag -= crypt->ops->extra_prefix_len + - crypt->ops->extra_postfix_len; - - /* Number of fragments is the total bytes_per_frag / - * payload_per_fragment */ - nr_frags = bytes / bytes_per_frag; - bytes_last_frag = bytes % bytes_per_frag; - if (bytes_last_frag) - nr_frags++; - else - bytes_last_frag = bytes_per_frag; - - /* When we allocate the TXB we allocate enough space for the reserve - * and full fragment bytes (bytes_per_frag doesn't include prefix, - * postfix, header, FCS, etc.) */ - txb = ieee80211_alloc_txb(nr_frags, frag_size + ieee->tx_headroom, GFP_ATOMIC); - if (unlikely(!txb)) { - printk(KERN_WARNING "%s: Could not allocate TXB\n", - ieee->dev->name); - goto failed; - } - txb->encrypted = encrypt; - txb->payload_size = bytes; - - if(qos_actived) - { - txb->queue_index = UP2AC(skb->priority); - } else { - txb->queue_index = WME_AC_BK; - } - - - - for (i = 0; i < nr_frags; i++) { - skb_frag = txb->fragments[i]; - tcb_desc = (cb_desc *)(skb_frag->cb + MAX_DEV_ADDR_SIZE); - if(qos_actived){ - skb_frag->priority = skb->priority;//UP2AC(skb->priority); - tcb_desc->queue_index = UP2AC(skb->priority); - } else { - skb_frag->priority = WME_AC_BK; - tcb_desc->queue_index = WME_AC_BK; - } - skb_reserve(skb_frag, ieee->tx_headroom); - - if (encrypt){ - if (ieee->hwsec_active) - tcb_desc->bHwSec = 1; - else - tcb_desc->bHwSec = 0; - skb_reserve(skb_frag, crypt->ops->extra_prefix_len); - } - else - { - tcb_desc->bHwSec = 0; - } - frag_hdr = (struct ieee80211_hdr_3addrqos *)skb_put(skb_frag, hdr_len); - memcpy(frag_hdr, &header, hdr_len); - - /* If this is not the last fragment, then add the MOREFRAGS - * bit to the frame control */ - if (i != nr_frags - 1) { - frag_hdr->frame_ctl = cpu_to_le16( - fc | IEEE80211_FCTL_MOREFRAGS); - bytes = bytes_per_frag; - - } else { - /* The last fragment takes the remaining length */ - bytes = bytes_last_frag; - } - - if(qos_actived) - { - // add 1 only indicate to corresponding seq number control 2006/7/12 - frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[UP2AC(skb->priority)+1]<<4 | i); - } else { - frag_hdr->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4 | i); - } - - /* Put a SNAP header on the first fragment */ - if (i == 0) { - ieee80211_put_snap( - skb_put(skb_frag, SNAP_SIZE + sizeof(u16)), - ether_type); - bytes -= SNAP_SIZE + sizeof(u16); - } - - memcpy(skb_put(skb_frag, bytes), skb->data, bytes); - - /* Advance the SKB... */ - skb_pull(skb, bytes); - - /* Encryption routine will move the header forward in order - * to insert the IV between the header and the payload */ - if (encrypt) - ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len); - if (ieee->config & - (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS)) - skb_put(skb_frag, 4); - } - - if(qos_actived) - { - if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF) - ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0; - else - ieee->seq_ctrl[UP2AC(skb->priority) + 1]++; - } else { - if (ieee->seq_ctrl[0] == 0xFFF) - ieee->seq_ctrl[0] = 0; - else - ieee->seq_ctrl[0]++; - } - }else{ - if (unlikely(skb->len < sizeof(struct ieee80211_hdr_3addr))) { - printk(KERN_WARNING "%s: skb too small (%d).\n", - ieee->dev->name, skb->len); - goto success; - } - - txb = ieee80211_alloc_txb(1, skb->len, GFP_ATOMIC); - if(!txb){ - printk(KERN_WARNING "%s: Could not allocate TXB\n", - ieee->dev->name); - goto failed; - } - - txb->encrypted = 0; - txb->payload_size = skb->len; - memcpy(skb_put(txb->fragments[0],skb->len), skb->data, skb->len); - } - - success: -//WB add to fill data tcb_desc here. only first fragment is considered, need to change, and you may remove to other place. - if (txb) - { - cb_desc *tcb_desc = (cb_desc *)(txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE); - tcb_desc->bTxEnableFwCalcDur = 1; - if (is_multicast_ether_addr(header.addr1)) - tcb_desc->bMulticast = 1; - if (is_broadcast_ether_addr(header.addr1)) - tcb_desc->bBroadcast = 1; - ieee80211_txrate_selectmode(ieee, tcb_desc); - if ( tcb_desc->bMulticast || tcb_desc->bBroadcast) - tcb_desc->data_rate = ieee->basic_rate; - else - tcb_desc->data_rate = CURRENT_RATE(ieee->mode, ieee->rate, ieee->HTCurrentOperaRate); - - if(bdhcp == true){ - tcb_desc->data_rate = MGN_1M; - tcb_desc->bTxDisableRateFallBack = 1; - - tcb_desc->RATRIndex = 7; - tcb_desc->bTxUseDriverAssingedRate = 1; - tcb_desc->bdhcp = 1; - } - - - ieee80211_qurey_ShortPreambleMode(ieee, tcb_desc); - ieee80211_tx_query_agg_cap(ieee, txb->fragments[0], tcb_desc); - ieee80211_query_HTCapShortGI(ieee, tcb_desc); - ieee80211_query_BandwidthMode(ieee, tcb_desc); - ieee80211_query_protectionmode(ieee, tcb_desc, txb->fragments[0]); - ieee80211_query_seqnum(ieee, txb->fragments[0], header.addr1); - } - spin_unlock_irqrestore(&ieee->lock, flags); - dev_kfree_skb_any(skb); - if (txb) { - if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE){ - ieee80211_softmac_xmit(txb, ieee); - }else{ - if ((*ieee->hard_start_xmit)(txb, ieee) == 0) { - stats->tx_packets++; - stats->tx_bytes += txb->payload_size; - return 0; - } - ieee80211_txb_free(txb); - } - } - - return 0; - - failed: - spin_unlock_irqrestore(&ieee->lock, flags); - netif_stop_queue(dev); - stats->tx_errors++; - return 1; - -} - diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c deleted file mode 100644 index 6530d9b..0000000 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_wx.c +++ /dev/null @@ -1,872 +0,0 @@ -/****************************************************************************** - - Copyright(c) 2004 Intel Corporation. All rights reserved. - - Portions of this file are based on the WEP enablement code provided by the - Host AP project hostap-drivers v0.1.3 - Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen - <jkmaline@cc.hut.fi> - Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi> - - This program is free software; you can redistribute it and/or modify it - under the terms of version 2 of the GNU General Public License as - published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - You should have received a copy of the GNU General Public License along with - this program; if not, write to the Free Software Foundation, Inc., 59 - Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - The full GNU General Public License is included in this distribution in the - file called LICENSE. - - Contact Information: - James P. Ketrenos <ipw2100-admin@linux.intel.com> - Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 - -******************************************************************************/ -#include <linux/wireless.h> -#include <linux/version.h> -#include <linux/kmod.h> -#include <linux/slab.h> -#include <linux/module.h> - -#include "ieee80211.h" - -struct modes_unit { - char *mode_string; - int mode_size; -}; -struct modes_unit ieee80211_modes[] = { - {"a",1}, - {"b",1}, - {"g",1}, - {"?",1}, - {"N-24G",5}, - {"N-5G",4}, -}; - -#define iwe_stream_add_event_rsl iwe_stream_add_event - -#define MAX_CUSTOM_LEN 64 -static inline char *rtl819x_translate_scan(struct ieee80211_device *ieee, - char *start, char *stop, - struct ieee80211_network *network, - struct iw_request_info *info) -{ - char custom[MAX_CUSTOM_LEN]; - char proto_name[IFNAMSIZ]; - char *pname = proto_name; - char *p; - struct iw_event iwe; - int i, j; - u16 max_rate, rate; - static u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; - - /* First entry *MUST* be the AP MAC address */ - iwe.cmd = SIOCGIWAP; - iwe.u.ap_addr.sa_family = ARPHRD_ETHER; - memcpy(iwe.u.ap_addr.sa_data, network->bssid, ETH_ALEN); - start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_ADDR_LEN); - /* Remaining entries will be displayed in the order we provide them */ - - /* Add the ESSID */ - iwe.cmd = SIOCGIWESSID; - iwe.u.data.flags = 1; -// if (network->flags & NETWORK_EMPTY_ESSID) { - if (network->ssid_len == 0) { - iwe.u.data.length = sizeof("<hidden>"); - start = iwe_stream_add_point(info, start, stop, &iwe, "<hidden>"); - } else { - iwe.u.data.length = min(network->ssid_len, (u8)32); - start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid); - } - /* Add the protocol name */ - iwe.cmd = SIOCGIWNAME; - for(i=0; i<ARRAY_SIZE(ieee80211_modes); i++) { - if(network->mode&(1<<i)) { - sprintf(pname,ieee80211_modes[i].mode_string,ieee80211_modes[i].mode_size); - pname +=ieee80211_modes[i].mode_size; - } - } - *pname = '\0'; - snprintf(iwe.u.name, IFNAMSIZ, "IEEE802.11%s", proto_name); - start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_CHAR_LEN); - /* Add mode */ - iwe.cmd = SIOCGIWMODE; - if (network->capability & - (WLAN_CAPABILITY_BSS | WLAN_CAPABILITY_IBSS)) { - if (network->capability & WLAN_CAPABILITY_BSS) - iwe.u.mode = IW_MODE_MASTER; - else - iwe.u.mode = IW_MODE_ADHOC; - start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_UINT_LEN); - } - - /* Add frequency/channel */ - iwe.cmd = SIOCGIWFREQ; -/* iwe.u.freq.m = ieee80211_frequency(network->channel, network->mode); - iwe.u.freq.e = 3; */ - iwe.u.freq.m = network->channel; - iwe.u.freq.e = 0; - iwe.u.freq.i = 0; - start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_FREQ_LEN); - /* Add encryption capability */ - iwe.cmd = SIOCGIWENCODE; - if (network->capability & WLAN_CAPABILITY_PRIVACY) - iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; - else - iwe.u.data.flags = IW_ENCODE_DISABLED; - iwe.u.data.length = 0; - start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid); - /* Add basic and extended rates */ - max_rate = 0; - p = custom; - p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): "); - for (i = 0, j = 0; i < network->rates_len; ) { - if (j < network->rates_ex_len && - ((network->rates_ex[j] & 0x7F) < - (network->rates[i] & 0x7F))) - rate = network->rates_ex[j++] & 0x7F; - else - rate = network->rates[i++] & 0x7F; - if (rate > max_rate) - max_rate = rate; - p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), - "%d%s ", rate >> 1, (rate & 1) ? ".5" : ""); - } - for (; j < network->rates_ex_len; j++) { - rate = network->rates_ex[j] & 0x7F; - p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), - "%d%s ", rate >> 1, (rate & 1) ? ".5" : ""); - if (rate > max_rate) - max_rate = rate; - } - - if (network->mode >= IEEE_N_24G)//add N rate here; - { - PHT_CAPABILITY_ELE ht_cap = NULL; - bool is40M = false, isShortGI = false; - u8 max_mcs = 0; - if (!memcmp(network->bssht.bdHTCapBuf, EWC11NHTCap, 4)) - ht_cap = (PHT_CAPABILITY_ELE)&network->bssht.bdHTCapBuf[4]; - else - ht_cap = (PHT_CAPABILITY_ELE)&network->bssht.bdHTCapBuf[0]; - is40M = (ht_cap->ChlWidth)?1:0; - isShortGI = (ht_cap->ChlWidth)? - ((ht_cap->ShortGI40Mhz)?1:0): - ((ht_cap->ShortGI20Mhz)?1:0); - - max_mcs = HTGetHighestMCSRate(ieee, ht_cap->MCS, MCS_FILTER_ALL); - rate = MCS_DATA_RATE[is40M][isShortGI][max_mcs&0x7f]; - if (rate > max_rate) - max_rate = rate; - } - iwe.cmd = SIOCGIWRATE; - iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; - iwe.u.bitrate.value = max_rate * 500000; - start = iwe_stream_add_event_rsl(info, start, stop, &iwe, - IW_EV_PARAM_LEN); - iwe.cmd = IWEVCUSTOM; - iwe.u.data.length = p - custom; - if (iwe.u.data.length) - start = iwe_stream_add_point(info, start, stop, &iwe, custom); - /* Add quality statistics */ - /* TODO: Fix these values... */ - iwe.cmd = IWEVQUAL; - iwe.u.qual.qual = network->stats.signal; - iwe.u.qual.level = network->stats.rssi; - iwe.u.qual.noise = network->stats.noise; - iwe.u.qual.updated = network->stats.mask & IEEE80211_STATMASK_WEMASK; - if (!(network->stats.mask & IEEE80211_STATMASK_RSSI)) - iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID; - if (!(network->stats.mask & IEEE80211_STATMASK_NOISE)) - iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID; - if (!(network->stats.mask & IEEE80211_STATMASK_SIGNAL)) - iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID; - iwe.u.qual.updated = 7; - start = iwe_stream_add_event_rsl(info, start, stop, &iwe, IW_EV_QUAL_LEN); - iwe.cmd = IWEVCUSTOM; - p = custom; - - iwe.u.data.length = p - custom; - if (iwe.u.data.length) - start = iwe_stream_add_point(info, start, stop, &iwe, custom); -#if (WIRELESS_EXT < 18) - if (ieee->wpa_enabled && network->wpa_ie_len){ - char buf[MAX_WPA_IE_LEN * 2 + 30]; - u8 *p = buf; - p += sprintf(p, "wpa_ie="); - for (i = 0; i < network->wpa_ie_len; i++) { - p += sprintf(p, "%02x", network->wpa_ie[i]); - } - - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = IWEVCUSTOM; - iwe.u.data.length = strlen(buf); - start = iwe_stream_add_point(info, start, stop, &iwe, buf); - } - - if (ieee->wpa_enabled && network->rsn_ie_len){ - char buf[MAX_WPA_IE_LEN * 2 + 30]; - - u8 *p = buf; - p += sprintf(p, "rsn_ie="); - for (i = 0; i < network->rsn_ie_len; i++) { - p += sprintf(p, "%02x", network->rsn_ie[i]); - } - - memset(&iwe, 0, sizeof(iwe)); - iwe.cmd = IWEVCUSTOM; - iwe.u.data.length = strlen(buf); - start = iwe_stream_add_point(info, start, stop, &iwe, buf); - } -#else - memset(&iwe, 0, sizeof(iwe)); - if (network->wpa_ie_len) - { - char buf[MAX_WPA_IE_LEN]; - memcpy(buf, network->wpa_ie, network->wpa_ie_len); - iwe.cmd = IWEVGENIE; - iwe.u.data.length = network->wpa_ie_len; - start = iwe_stream_add_point(info, start, stop, &iwe, buf); - } - memset(&iwe, 0, sizeof(iwe)); - if (network->rsn_ie_len) - { - char buf[MAX_WPA_IE_LEN]; - memcpy(buf, network->rsn_ie, network->rsn_ie_len); - iwe.cmd = IWEVGENIE; - iwe.u.data.length = network->rsn_ie_len; - start = iwe_stream_add_point(info, start, stop, &iwe, buf); - } -#endif - - - /* Add EXTRA: Age to display seconds since last beacon/probe response - * for given network. */ - iwe.cmd = IWEVCUSTOM; - p = custom; - p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), - " Last beacon: %lums ago", (jiffies - network->last_scanned) / (HZ / 100)); - iwe.u.data.length = p - custom; - if (iwe.u.data.length) - start = iwe_stream_add_point(info, start, stop, &iwe, custom); - - return start; -} - -int ieee80211_wx_get_scan(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct ieee80211_network *network; - unsigned long flags; - - char *ev = extra; -// char *stop = ev + IW_SCAN_MAX_DATA; - char *stop = ev + wrqu->data.length;//IW_SCAN_MAX_DATA; - //char *stop = ev + IW_SCAN_MAX_DATA; - int i = 0; - int err = 0; - IEEE80211_DEBUG_WX("Getting scan\n"); - down(&ieee->wx_sem); - spin_lock_irqsave(&ieee->lock, flags); - - list_for_each_entry(network, &ieee->network_list, list) { - i++; - if((stop-ev)<200) - { - err = -E2BIG; - break; - } - if (ieee->scan_age == 0 || - time_after(network->last_scanned + ieee->scan_age, jiffies)) - ev = rtl819x_translate_scan(ieee, ev, stop, network, info); - else - IEEE80211_DEBUG_SCAN( - "Not showing network '%s (" - "%pM)' due to age (%lums).\n", - escape_essid(network->ssid, - network->ssid_len), - network->bssid, - (jiffies - network->last_scanned) / (HZ / 100)); - } - - spin_unlock_irqrestore(&ieee->lock, flags); - up(&ieee->wx_sem); - wrqu->data.length = ev - extra; - wrqu->data.flags = 0; - - IEEE80211_DEBUG_WX("exit: %d networks returned.\n", i); - - return err; -} - -int ieee80211_wx_set_encode(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *keybuf) -{ - struct iw_point *erq = &(wrqu->encoding); - struct net_device *dev = ieee->dev; - struct ieee80211_security sec = { - .flags = 0 - }; - int i, key, key_provided, len; - struct ieee80211_crypt_data **crypt; - - IEEE80211_DEBUG_WX("SET_ENCODE\n"); - - key = erq->flags & IW_ENCODE_INDEX; - if (key) { - if (key > WEP_KEYS) - return -EINVAL; - key--; - key_provided = 1; - } else { - key_provided = 0; - key = ieee->tx_keyidx; - } - - IEEE80211_DEBUG_WX("Key: %d [%s]\n", key, key_provided ? - "provided" : "default"); - crypt = &ieee->crypt[key]; - - if (erq->flags & IW_ENCODE_DISABLED) { - if (key_provided && *crypt) { - IEEE80211_DEBUG_WX("Disabling encryption on key %d.\n", - key); - ieee80211_crypt_delayed_deinit(ieee, crypt); - } else - IEEE80211_DEBUG_WX("Disabling encryption.\n"); - - /* Check all the keys to see if any are still configured, - * and if no key index was provided, de-init them all */ - for (i = 0; i < WEP_KEYS; i++) { - if (ieee->crypt[i] != NULL) { - if (key_provided) - break; - ieee80211_crypt_delayed_deinit( - ieee, &ieee->crypt[i]); - } - } - - if (i == WEP_KEYS) { - sec.enabled = 0; - sec.level = SEC_LEVEL_0; - sec.flags |= SEC_ENABLED | SEC_LEVEL; - } - - goto done; - } - - - - sec.enabled = 1; - sec.flags |= SEC_ENABLED; - - if (*crypt != NULL && (*crypt)->ops != NULL && - strcmp((*crypt)->ops->name, "WEP") != 0) { - /* changing to use WEP; deinit previously used algorithm - * on this key */ - ieee80211_crypt_delayed_deinit(ieee, crypt); - } - - if (*crypt == NULL) { - struct ieee80211_crypt_data *new_crypt; - - /* take WEP into use */ - new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data), - GFP_KERNEL); - if (new_crypt == NULL) - return -ENOMEM; - new_crypt->ops = ieee80211_get_crypto_ops("WEP"); - if (!new_crypt->ops) - new_crypt->ops = ieee80211_get_crypto_ops("WEP"); - if (new_crypt->ops) - new_crypt->priv = new_crypt->ops->init(key); - - if (!new_crypt->ops || !new_crypt->priv) { - kfree(new_crypt); - new_crypt = NULL; - - printk(KERN_WARNING "%s: could not initialize WEP: " - "load module ieee80211_crypt_wep\n", - dev->name); - return -EOPNOTSUPP; - } - *crypt = new_crypt; - } - - /* If a new key was provided, set it up */ - if (erq->length > 0) { - len = erq->length <= 5 ? 5 : 13; - memcpy(sec.keys[key], keybuf, erq->length); - if (len > erq->length) - memset(sec.keys[key] + erq->length, 0, - len - erq->length); - IEEE80211_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n", - key, escape_essid(sec.keys[key], len), - erq->length, len); - sec.key_sizes[key] = len; - (*crypt)->ops->set_key(sec.keys[key], len, NULL, - (*crypt)->priv); - sec.flags |= (1 << key); - /* This ensures a key will be activated if no key is - * explicitely set */ - if (key == sec.active_key) - sec.flags |= SEC_ACTIVE_KEY; - ieee->tx_keyidx = key; - - } else { - len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN, - NULL, (*crypt)->priv); - if (len == 0) { - /* Set a default key of all 0 */ - printk("Setting key %d to all zero.\n", - key); - - IEEE80211_DEBUG_WX("Setting key %d to all zero.\n", - key); - memset(sec.keys[key], 0, 13); - (*crypt)->ops->set_key(sec.keys[key], 13, NULL, - (*crypt)->priv); - sec.key_sizes[key] = 13; - sec.flags |= (1 << key); - } - - /* No key data - just set the default TX key index */ - if (key_provided) { - IEEE80211_DEBUG_WX( - "Setting key %d to default Tx key.\n", key); - ieee->tx_keyidx = key; - sec.active_key = key; - sec.flags |= SEC_ACTIVE_KEY; - } - } - - done: - ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED); - ieee->auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY; - sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY; - sec.flags |= SEC_AUTH_MODE; - IEEE80211_DEBUG_WX("Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ? - "OPEN" : "SHARED KEY"); - - /* For now we just support WEP, so only set that security level... - * TODO: When WPA is added this is one place that needs to change */ - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */ - - if (ieee->set_security) - ieee->set_security(ieee, &sec); - - /* Do not reset port if card is in Managed mode since resetting will - * generate new IEEE 802.11 authentication which may end up in looping - * with IEEE 802.1X. If your hardware requires a reset after WEP - * configuration (for example... Prism2), implement the reset_port in - * the callbacks structures used to initialize the 802.11 stack. */ - if (ieee->reset_on_keychange && - ieee->iw_mode != IW_MODE_INFRA && - ieee->reset_port && ieee->reset_port(ieee)) { - printk(KERN_DEBUG "%s: reset_port failed\n", dev->name); - return -EINVAL; - } - return 0; -} - -int ieee80211_wx_get_encode(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *keybuf) -{ - struct iw_point *erq = &(wrqu->encoding); - int len, key; - struct ieee80211_crypt_data *crypt; - - IEEE80211_DEBUG_WX("GET_ENCODE\n"); - - if(ieee->iw_mode == IW_MODE_MONITOR) - return -1; - - key = erq->flags & IW_ENCODE_INDEX; - if (key) { - if (key > WEP_KEYS) - return -EINVAL; - key--; - } else - key = ieee->tx_keyidx; - - crypt = ieee->crypt[key]; - erq->flags = key + 1; - - if (crypt == NULL || crypt->ops == NULL) { - erq->length = 0; - erq->flags |= IW_ENCODE_DISABLED; - return 0; - } -#if 0 - if (strcmp(crypt->ops->name, "WEP") != 0) { - /* only WEP is supported with wireless extensions, so just - * report that encryption is used */ - erq->length = 0; - erq->flags |= IW_ENCODE_ENABLED; - return 0; - } -#endif - len = crypt->ops->get_key(keybuf, SCM_KEY_LEN, NULL, crypt->priv); - erq->length = (len >= 0 ? len : 0); - - erq->flags |= IW_ENCODE_ENABLED; - - if (ieee->open_wep) - erq->flags |= IW_ENCODE_OPEN; - else - erq->flags |= IW_ENCODE_RESTRICTED; - - return 0; -} -#if (WIRELESS_EXT >= 18) -int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - int ret = 0; - struct net_device *dev = ieee->dev; - struct iw_point *encoding = &wrqu->encoding; - struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; - int i, idx; - int group_key = 0; - const char *alg; - struct ieee80211_crypto_ops *ops; - struct ieee80211_crypt_data **crypt; - - struct ieee80211_security sec = { - .flags = 0, - }; - idx = encoding->flags & IW_ENCODE_INDEX; - if (idx) { - if (idx < 1 || idx > WEP_KEYS) - return -EINVAL; - idx--; - } else - idx = ieee->tx_keyidx; - - if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { - - crypt = &ieee->crypt[idx]; - - group_key = 1; - } else { - /* some Cisco APs use idx>0 for unicast in dynamic WEP */ - if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP) - return -EINVAL; - if (ieee->iw_mode == IW_MODE_INFRA) - - crypt = &ieee->crypt[idx]; - - else - return -EINVAL; - } - - sec.flags |= SEC_ENABLED;// | SEC_ENCRYPT; - if ((encoding->flags & IW_ENCODE_DISABLED) || - ext->alg == IW_ENCODE_ALG_NONE) { - if (*crypt) - ieee80211_crypt_delayed_deinit(ieee, crypt); - - for (i = 0; i < WEP_KEYS; i++) - - if (ieee->crypt[i] != NULL) - - break; - - if (i == WEP_KEYS) { - sec.enabled = 0; - // sec.encrypt = 0; - sec.level = SEC_LEVEL_0; - sec.flags |= SEC_LEVEL; - } - goto done; - } - - sec.enabled = 1; - // sec.encrypt = 1; -#if 0 - if (group_key ? !ieee->host_mc_decrypt : - !(ieee->host_encrypt || ieee->host_decrypt || - ieee->host_encrypt_msdu)) - goto skip_host_crypt; -#endif - switch (ext->alg) { - case IW_ENCODE_ALG_WEP: - alg = "WEP"; - break; - case IW_ENCODE_ALG_TKIP: - alg = "TKIP"; - break; - case IW_ENCODE_ALG_CCMP: - alg = "CCMP"; - break; - default: - IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n", - dev->name, ext->alg); - ret = -EINVAL; - goto done; - } - printk("alg name:%s\n",alg); - - ops = ieee80211_get_crypto_ops(alg); - if (ops == NULL) - ops = ieee80211_get_crypto_ops(alg); - if (ops == NULL) { - IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n", - dev->name, ext->alg); - printk("========>unknown crypto alg %d\n", ext->alg); - ret = -EINVAL; - goto done; - } - - if (*crypt == NULL || (*crypt)->ops != ops) { - struct ieee80211_crypt_data *new_crypt; - - ieee80211_crypt_delayed_deinit(ieee, crypt); - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13)) - new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL); -#else - new_crypt = kmalloc(sizeof(*new_crypt), GFP_KERNEL); - memset(new_crypt,0,sizeof(*new_crypt)); -#endif - if (new_crypt == NULL) { - ret = -ENOMEM; - goto done; - } - new_crypt->ops = ops; - if (new_crypt->ops) - new_crypt->priv = new_crypt->ops->init(idx); - if (new_crypt->priv == NULL) { - kfree(new_crypt); - ret = -EINVAL; - goto done; - } - *crypt = new_crypt; - - } - - if (ext->key_len > 0 && (*crypt)->ops->set_key && - (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq, - (*crypt)->priv) < 0) { - IEEE80211_DEBUG_WX("%s: key setting failed\n", dev->name); - printk("key setting failed\n"); - ret = -EINVAL; - goto done; - } -#if 1 - if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { - ieee->tx_keyidx = idx; - sec.active_key = idx; - sec.flags |= SEC_ACTIVE_KEY; - } - - if (ext->alg != IW_ENCODE_ALG_NONE) { - //memcpy(sec.keys[idx], ext->key, ext->key_len); - sec.key_sizes[idx] = ext->key_len; - sec.flags |= (1 << idx); - if (ext->alg == IW_ENCODE_ALG_WEP) { - // sec.encode_alg[idx] = SEC_ALG_WEP; - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_1; - } else if (ext->alg == IW_ENCODE_ALG_TKIP) { - // sec.encode_alg[idx] = SEC_ALG_TKIP; - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_2; - } else if (ext->alg == IW_ENCODE_ALG_CCMP) { - // sec.encode_alg[idx] = SEC_ALG_CCMP; - sec.flags |= SEC_LEVEL; - sec.level = SEC_LEVEL_3; - } - /* Don't set sec level for group keys. */ - if (group_key) - sec.flags &= ~SEC_LEVEL; - } -#endif -done: - if (ieee->set_security) - ieee->set_security(ieee, &sec); - - if (ieee->reset_on_keychange && - ieee->iw_mode != IW_MODE_INFRA && - ieee->reset_port && ieee->reset_port(ieee)) { - IEEE80211_DEBUG_WX("%s: reset_port failed\n", dev->name); - return -EINVAL; - } - return ret; -} - -int ieee80211_wx_get_encode_ext(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct iw_point *encoding = &wrqu->encoding; - struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; - struct ieee80211_crypt_data *crypt; - int idx, max_key_len; - - max_key_len = encoding->length - sizeof(*ext); - if (max_key_len < 0) - return -EINVAL; - - idx = encoding->flags & IW_ENCODE_INDEX; - if (idx) { - if (idx < 1 || idx > WEP_KEYS) - return -EINVAL; - idx--; - } else - idx = ieee->tx_keyidx; - - if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) && - ext->alg != IW_ENCODE_ALG_WEP) - if (idx != 0 || ieee->iw_mode != IW_MODE_INFRA) - return -EINVAL; - - crypt = ieee->crypt[idx]; - encoding->flags = idx + 1; - memset(ext, 0, sizeof(*ext)); - - if (crypt == NULL || crypt->ops == NULL ) { - ext->alg = IW_ENCODE_ALG_NONE; - ext->key_len = 0; - encoding->flags |= IW_ENCODE_DISABLED; - } else { - if (strcmp(crypt->ops->name, "WEP") == 0 ) - ext->alg = IW_ENCODE_ALG_WEP; - else if (strcmp(crypt->ops->name, "TKIP")) - ext->alg = IW_ENCODE_ALG_TKIP; - else if (strcmp(crypt->ops->name, "CCMP")) - ext->alg = IW_ENCODE_ALG_CCMP; - else - return -EINVAL; - ext->key_len = crypt->ops->get_key(ext->key, SCM_KEY_LEN, NULL, crypt->priv); - encoding->flags |= IW_ENCODE_ENABLED; - if (ext->key_len && - (ext->alg == IW_ENCODE_ALG_TKIP || - ext->alg == IW_ENCODE_ALG_CCMP)) - ext->ext_flags |= IW_ENCODE_EXT_TX_SEQ_VALID; - - } - - return 0; -} - -int ieee80211_wx_set_mlme(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct iw_mlme *mlme = (struct iw_mlme *) extra; - switch (mlme->cmd) { - case IW_MLME_DEAUTH: - case IW_MLME_DISASSOC: - ieee80211_disassociate(ieee); - break; - default: - return -EOPNOTSUPP; - } - return 0; -} - -int ieee80211_wx_set_auth(struct ieee80211_device *ieee, - struct iw_request_info *info, - struct iw_param *data, char *extra) -{ - switch (data->flags & IW_AUTH_INDEX) { - case IW_AUTH_WPA_VERSION: - /*need to support wpa2 here*/ - break; - case IW_AUTH_CIPHER_PAIRWISE: - case IW_AUTH_CIPHER_GROUP: - case IW_AUTH_KEY_MGMT: - /* - * * Host AP driver does not use these parameters and allows - * * wpa_supplicant to control them internally. - * */ - break; - case IW_AUTH_TKIP_COUNTERMEASURES: - ieee->tkip_countermeasures = data->value; - break; - case IW_AUTH_DROP_UNENCRYPTED: - ieee->drop_unencrypted = data->value; - break; - - case IW_AUTH_80211_AUTH_ALG: - if(data->value & IW_AUTH_ALG_SHARED_KEY){ - ieee->open_wep = 0; - ieee->auth_mode = 1; - } - else if(data->value & IW_AUTH_ALG_OPEN_SYSTEM){ - ieee->open_wep = 1; - ieee->auth_mode = 0; - } - else if(data->value & IW_AUTH_ALG_LEAP){ - ieee->open_wep = 1; - ieee->auth_mode = 2; - } - else - return -EINVAL; - break; - -#if 1 - case IW_AUTH_WPA_ENABLED: - ieee->wpa_enabled = (data->value)?1:0; - break; - -#endif - case IW_AUTH_RX_UNENCRYPTED_EAPOL: - ieee->ieee802_1x = data->value; - break; - case IW_AUTH_PRIVACY_INVOKED: - ieee->privacy_invoked = data->value; - break; - default: - return -EOPNOTSUPP; - } - return 0; -} -#endif -#if 1 -int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len) -{ - u8 *buf; - - if (len>MAX_WPA_IE_LEN || (len && ie == NULL)) - { - return -EINVAL; - } - - - if (len) - { - if (len != ie[1]+2) - { - printk("len:%zu, ie:%d\n", len, ie[1]); - return -EINVAL; - } - buf = kmemdup(ie, len, GFP_KERNEL); - if (buf == NULL) - return -ENOMEM; - kfree(ieee->wpa_ie); - ieee->wpa_ie = buf; - ieee->wpa_ie_len = len; - } - else{ - kfree(ieee->wpa_ie); - ieee->wpa_ie = NULL; - ieee->wpa_ie_len = 0; - } - return 0; - -} -#endif diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_BA.h b/drivers/staging/rtl8192e/ieee80211/rtl819x_BA.h deleted file mode 100644 index 8ddc8bf9..0000000 --- a/drivers/staging/rtl8192e/ieee80211/rtl819x_BA.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef _BATYPE_H_ -#define _BATYPE_H_ - -#define TOTAL_TXBA_NUM 16 -#define TOTAL_RXBA_NUM 16 - -#define BA_SETUP_TIMEOUT 200 -#define BA_INACT_TIMEOUT 60000 - -#define BA_POLICY_DELAYED 0 -#define BA_POLICY_IMMEDIATE 1 - -#define ADDBA_STATUS_SUCCESS 0 -#define ADDBA_STATUS_REFUSED 37 -#define ADDBA_STATUS_INVALID_PARAM 38 - -#define DELBA_REASON_QSTA_LEAVING 36 -#define DELBA_REASON_END_BA 37 -#define DELBA_REASON_UNKNOWN_BA 38 -#define DELBA_REASON_TIMEOUT 39 -/* whether need define BA Action frames here? -struct ieee80211_ADDBA_Req{ - struct ieee80211_header_data header; - u8 category; - u8 -} __attribute__ ((packed)); -*/ -//Is this need?I put here just to make it easier to define structure BA_RECORD //WB -typedef union _SEQUENCE_CONTROL{ - u16 ShortData; - struct - { - u16 FragNum:4; - u16 SeqNum:12; - }field; -}SEQUENCE_CONTROL, *PSEQUENCE_CONTROL; - -typedef union _BA_PARAM_SET { - u8 charData[2]; - u16 shortData; - struct { - u16 AMSDU_Support:1; - u16 BAPolicy:1; - u16 TID:4; - u16 BufferSize:10; - } field; -} BA_PARAM_SET, *PBA_PARAM_SET; - -typedef union _DELBA_PARAM_SET { - u8 charData[2]; - u16 shortData; - struct { - u16 Reserved:11; - u16 Initiator:1; - u16 TID:4; - } field; -} DELBA_PARAM_SET, *PDELBA_PARAM_SET; - -typedef struct _BA_RECORD { - struct timer_list Timer; - u8 bValid; - u8 DialogToken; - BA_PARAM_SET BaParamSet; - u16 BaTimeoutValue; - SEQUENCE_CONTROL BaStartSeqCtrl; -} BA_RECORD, *PBA_RECORD; - -#endif //end _BATYPE_H_ - diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c b/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c deleted file mode 100644 index b690cbc..0000000 --- a/drivers/staging/rtl8192e/ieee80211/rtl819x_BAProc.c +++ /dev/null @@ -1,676 +0,0 @@ -/* - * This file is created to process BA Action Frame. According to 802.11 spec, - * there are 3 BA action types at all. And as BA is related to TS, this part - * need some struture defined in QOS side code. Also TX RX is going to be - * resturctured, so how to send ADDBAREQ ADDBARSP and DELBA packet is still - * on consideration. Temporarily use MANAGE QUEUE instead of Normal Queue. - */ -#include "ieee80211.h" -#include "rtl819x_BA.h" - -/* - * Activate BA entry. And if Time is nozero, start timer. - */ -void ActivateBAEntry(struct ieee80211_device* ieee, PBA_RECORD pBA, u16 Time) -{ - pBA->bValid = true; - if(Time != 0) - mod_timer(&pBA->Timer, jiffies + MSECS(Time)); -} - -/* - * deactivate BA entry, including its timer. - */ -void DeActivateBAEntry( struct ieee80211_device* ieee, PBA_RECORD pBA) -{ - pBA->bValid = false; - del_timer_sync(&pBA->Timer); -} - -/* - * deactivete BA entry in Tx Ts, and send DELBA. - */ -u8 TxTsDeleteBA( struct ieee80211_device* ieee, PTX_TS_RECORD pTxTs) -{ - PBA_RECORD pAdmittedBa = &pTxTs->TxAdmittedBARecord; //These two BA entries must exist in TS structure - PBA_RECORD pPendingBa = &pTxTs->TxPendingBARecord; - u8 bSendDELBA = false; - - // Delete pending BA - if(pPendingBa->bValid) - { - DeActivateBAEntry(ieee, pPendingBa); - bSendDELBA = true; - } - - // Delete admitted BA - if(pAdmittedBa->bValid) - { - DeActivateBAEntry(ieee, pAdmittedBa); - bSendDELBA = true; - } - - return bSendDELBA; -} - -/* - * deactivete BA entry in Tx Ts, and send DELBA. - */ -u8 RxTsDeleteBA( struct ieee80211_device* ieee, PRX_TS_RECORD pRxTs) -{ - PBA_RECORD pBa = &pRxTs->RxAdmittedBARecord; - u8 bSendDELBA = false; - - if(pBa->bValid) - { - DeActivateBAEntry(ieee, pBa); - bSendDELBA = true; - } - - return bSendDELBA; -} - -/* - * reset BA entry - */ -void ResetBaEntry( PBA_RECORD pBA) -{ - pBA->bValid = false; - pBA->BaParamSet.shortData = 0; - pBA->BaTimeoutValue = 0; - pBA->DialogToken = 0; - pBA->BaStartSeqCtrl.ShortData = 0; -} - -/* - * construct ADDBAREQ and ADDBARSP frame here together. - * return constructed skb to xmit - */ -static struct sk_buff* ieee80211_ADDBA(struct ieee80211_device* ieee, u8* Dst, PBA_RECORD pBA, u16 StatusCode, u8 type) -{ - struct sk_buff *skb = NULL; - struct ieee80211_hdr_3addr* BAReq = NULL; - u8* tag = NULL; - u16 tmp = 0; - u16 len = ieee->tx_headroom + 9; - //category(1) + action field(1) + Dialog Token(1) + BA Parameter Set(2) + BA Timeout Value(2) + BA Start SeqCtrl(2)(or StatusCode(2)) - IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), frame(%d) sentd to:%pM, ieee->dev:%p\n", __FUNCTION__, type, Dst, ieee->dev); - if (pBA == NULL||ieee == NULL) - { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "pBA(%p) is NULL or ieee(%p) is NULL\n", pBA, ieee); - return NULL; - } - skb = dev_alloc_skb(len + sizeof( struct ieee80211_hdr_3addr)); //need to add something others? FIXME - if (skb == NULL) - { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc skb for ADDBA_REQ\n"); - return NULL; - } - - memset(skb->data, 0, sizeof( struct ieee80211_hdr_3addr)); //I wonder whether it's necessary. Apparently kernel will not do it when alloc a skb. - skb_reserve(skb, ieee->tx_headroom); - - BAReq = ( struct ieee80211_hdr_3addr *) skb_put(skb,sizeof( struct ieee80211_hdr_3addr)); - - memcpy(BAReq->addr1, Dst, ETH_ALEN); - memcpy(BAReq->addr2, ieee->dev->dev_addr, ETH_ALEN); - - memcpy(BAReq->addr3, ieee->current_network.bssid, ETH_ALEN); - - BAReq->frame_ctl = cpu_to_le16(IEEE80211_STYPE_MANAGE_ACT); //action frame - - //tag += sizeof( struct ieee80211_hdr_3addr); //move to action field - tag = (u8*)skb_put(skb, 9); - *tag ++= ACT_CAT_BA; - *tag ++= type; - // Dialog Token - *tag ++= pBA->DialogToken; - - if (ACT_ADDBARSP == type) - { - // Status Code - printk("=====>to send ADDBARSP\n"); - tmp = cpu_to_le16(StatusCode); - memcpy(tag, (u8*)&tmp, 2); - tag += 2; - } - // BA Parameter Set - tmp = cpu_to_le16(pBA->BaParamSet.shortData); - memcpy(tag, (u8*)&tmp, 2); - tag += 2; - // BA Timeout Value - tmp = cpu_to_le16(pBA->BaTimeoutValue); - memcpy(tag, (u8*)&tmp, 2); - tag += 2; - - if (ACT_ADDBAREQ == type) - { - // BA Start SeqCtrl - memcpy(tag,(u8*)&(pBA->BaStartSeqCtrl), 2); - tag += 2; - } - - IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len); - return skb; - //return NULL; -} - -/* - * construct DELBA frame - */ -static struct sk_buff* ieee80211_DELBA( - struct ieee80211_device* ieee, - u8* dst, - PBA_RECORD pBA, - TR_SELECT TxRxSelect, - u16 ReasonCode - ) -{ - DELBA_PARAM_SET DelbaParamSet; - struct sk_buff *skb = NULL; - struct ieee80211_hdr_3addr* Delba = NULL; - u8* tag = NULL; - u16 tmp = 0; - //len = head len + DELBA Parameter Set(2) + Reason Code(2) - u16 len = 6 + ieee->tx_headroom; - - if (net_ratelimit()) - IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "========>%s(), ReasonCode(%d) sentd to:%pM\n", __FUNCTION__, ReasonCode, dst); - - memset(&DelbaParamSet, 0, 2); - - DelbaParamSet.field.Initiator = (TxRxSelect==TX_DIR)?1:0; - DelbaParamSet.field.TID = pBA->BaParamSet.field.TID; - - skb = dev_alloc_skb(len + sizeof( struct ieee80211_hdr_3addr)); //need to add something others? FIXME - if (skb == NULL) - { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc skb for ADDBA_REQ\n"); - return NULL; - } -// memset(skb->data, 0, len+sizeof( struct ieee80211_hdr_3addr)); - skb_reserve(skb, ieee->tx_headroom); - - Delba = ( struct ieee80211_hdr_3addr *) skb_put(skb,sizeof( struct ieee80211_hdr_3addr)); - - memcpy(Delba->addr1, dst, ETH_ALEN); - memcpy(Delba->addr2, ieee->dev->dev_addr, ETH_ALEN); - memcpy(Delba->addr3, ieee->current_network.bssid, ETH_ALEN); - Delba->frame_ctl = cpu_to_le16(IEEE80211_STYPE_MANAGE_ACT); //action frame - - tag = (u8*)skb_put(skb, 6); - - *tag ++= ACT_CAT_BA; - *tag ++= ACT_DELBA; - - // DELBA Parameter Set - tmp = cpu_to_le16(DelbaParamSet.shortData); - memcpy(tag, (u8*)&tmp, 2); - tag += 2; - // Reason Code - tmp = cpu_to_le16(ReasonCode); - memcpy(tag, (u8*)&tmp, 2); - tag += 2; - - IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len); - if (net_ratelimit()) - IEEE80211_DEBUG(IEEE80211_DL_TRACE | IEEE80211_DL_BA, "<=====%s()\n", __FUNCTION__); - return skb; -} - -/* - * send ADDBAReq frame out - * If any possible, please hide pBA in ieee. - * And temporarily use Manage Queue as softmac_mgmt_xmit() usually does - */ -void ieee80211_send_ADDBAReq(struct ieee80211_device* ieee, u8* dst, PBA_RECORD pBA) -{ - struct sk_buff *skb = NULL; - skb = ieee80211_ADDBA(ieee, dst, pBA, 0, ACT_ADDBAREQ); //construct ACT_ADDBAREQ frames so set statuscode zero. - - if (skb) - { - softmac_mgmt_xmit(skb, ieee); - //add statistic needed here. - //and skb will be freed in softmac_mgmt_xmit(), so omit all dev_kfree_skb_any() outside softmac_mgmt_xmit() - //WB - } - else - { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "alloc skb error in function %s()\n", __FUNCTION__); - } -} - -/* - * send ADDBARSP frame out - * If any possible, please hide pBA in ieee. - * And temporarily use Manage Queue as softmac_mgmt_xmit() usually does - */ -void ieee80211_send_ADDBARsp(struct ieee80211_device* ieee, u8* dst, PBA_RECORD pBA, u16 StatusCode) -{ - struct sk_buff *skb = NULL; - skb = ieee80211_ADDBA(ieee, dst, pBA, StatusCode, ACT_ADDBARSP); //construct ACT_ADDBARSP frames - if (skb) - { - softmac_mgmt_xmit(skb, ieee); - //same above - } - else - { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "alloc skb error in function %s()\n", __FUNCTION__); - } -} - -/* - * send ADDBARSP frame out - * If any possible, please hide pBA in ieee. - * And temporarily use Manage Queue as softmac_mgmt_xmit() usually does - */ -void ieee80211_send_DELBA(struct ieee80211_device* ieee, u8* dst, PBA_RECORD pBA, TR_SELECT TxRxSelect, u16 ReasonCode) -{ - struct sk_buff *skb = NULL; - skb = ieee80211_DELBA(ieee, dst, pBA, TxRxSelect, ReasonCode); //construct ACT_ADDBARSP frames - if (skb) - { - softmac_mgmt_xmit(skb, ieee); - //same above - } - else - { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "alloc skb error in function %s()\n", __FUNCTION__); - } - return ; -} - -int ieee80211_rx_ADDBAReq( struct ieee80211_device* ieee, struct sk_buff *skb) -{ - struct ieee80211_hdr_3addr* req = NULL; - u16 rc = 0; - u8 * dst = NULL, *pDialogToken = NULL, *tag = NULL; - PBA_RECORD pBA = NULL; - PBA_PARAM_SET pBaParamSet = NULL; - u16* pBaTimeoutVal = NULL; - PSEQUENCE_CONTROL pBaStartSeqCtrl = NULL; - PRX_TS_RECORD pTS = NULL; - - if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9) - { - IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BAREQ(%d / %zu)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 9)); - return -1; - } - - IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len); - - req = ( struct ieee80211_hdr_3addr*) skb->data; - tag = (u8*)req; - dst = (u8*)(&req->addr2[0]); - tag += sizeof( struct ieee80211_hdr_3addr); - pDialogToken = tag + 2; //category+action - pBaParamSet = (PBA_PARAM_SET)(tag + 3); //+DialogToken - pBaTimeoutVal = (u16*)(tag + 5); - pBaStartSeqCtrl = (PSEQUENCE_CONTROL)(req + 7); - - printk("====================>rx ADDBAREQ from :%pM\n", dst); -//some other capability is not ready now. - if( (ieee->current_network.qos_data.active == 0) || - (ieee->pHTInfo->bCurrentHTSupport == false)) //|| - // (ieee->pStaQos->bEnableRxImmBA == false) ) - { - rc = ADDBA_STATUS_REFUSED; - IEEE80211_DEBUG(IEEE80211_DL_ERR, "Failed to reply on ADDBA_REQ as some capability is not ready(%d, %d)\n", ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport); - goto OnADDBAReq_Fail; - } - // Search for related traffic stream. - // If there is no matched TS, reject the ADDBA request. - if( !GetTs( - ieee, - (PTS_COMMON_INFO*)(&pTS), - dst, - (u8)(pBaParamSet->field.TID), - RX_DIR, - true) ) - { - rc = ADDBA_STATUS_REFUSED; - IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't get TS in %s()\n", __FUNCTION__); - goto OnADDBAReq_Fail; - } - pBA = &pTS->RxAdmittedBARecord; - // To Determine the ADDBA Req content - // We can do much more check here, including BufferSize, AMSDU_Support, Policy, StartSeqCtrl... - // I want to check StartSeqCtrl to make sure when we start aggregation!!! - // - if(pBaParamSet->field.BAPolicy == BA_POLICY_DELAYED) - { - rc = ADDBA_STATUS_INVALID_PARAM; - IEEE80211_DEBUG(IEEE80211_DL_ERR, "BA Policy is not correct in %s()\n", __FUNCTION__); - goto OnADDBAReq_Fail; - } - // Admit the ADDBA Request - // - DeActivateBAEntry(ieee, pBA); - pBA->DialogToken = *pDialogToken; - pBA->BaParamSet = *pBaParamSet; - pBA->BaTimeoutValue = *pBaTimeoutVal; - pBA->BaStartSeqCtrl = *pBaStartSeqCtrl; - //for half N mode we only aggregate 1 frame - if (ieee->GetHalfNmodeSupportByAPsHandler(ieee)) - pBA->BaParamSet.field.BufferSize = 1; - else - pBA->BaParamSet.field.BufferSize = 32; - ActivateBAEntry(ieee, pBA, pBA->BaTimeoutValue); - ieee80211_send_ADDBARsp(ieee, dst, pBA, ADDBA_STATUS_SUCCESS); - - // End of procedure. - return 0; - -OnADDBAReq_Fail: - { - BA_RECORD BA; - BA.BaParamSet = *pBaParamSet; - BA.BaTimeoutValue = *pBaTimeoutVal; - BA.DialogToken = *pDialogToken; - BA.BaParamSet.field.BAPolicy = BA_POLICY_IMMEDIATE; - ieee80211_send_ADDBARsp(ieee, dst, &BA, rc); - return 0; //we send RSP out. - } - -} - -int ieee80211_rx_ADDBARsp( struct ieee80211_device* ieee, struct sk_buff *skb) -{ - struct ieee80211_hdr_3addr* rsp = NULL; - PBA_RECORD pPendingBA, pAdmittedBA; - PTX_TS_RECORD pTS = NULL; - u8* dst = NULL, *pDialogToken = NULL, *tag = NULL; - u16* pStatusCode = NULL, *pBaTimeoutVal = NULL; - PBA_PARAM_SET pBaParamSet = NULL; - u16 ReasonCode; - - if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 9) - { - IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in BARSP(%d / %zu)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 9)); - return -1; - } - rsp = ( struct ieee80211_hdr_3addr*)skb->data; - tag = (u8*)rsp; - dst = (u8*)(&rsp->addr2[0]); - tag += sizeof( struct ieee80211_hdr_3addr); - pDialogToken = tag + 2; - pStatusCode = (u16*)(tag + 3); - pBaParamSet = (PBA_PARAM_SET)(tag + 5); - pBaTimeoutVal = (u16*)(tag + 7); - - // Check the capability - // Since we can always receive A-MPDU, we just check if it is under HT mode. - if( ieee->current_network.qos_data.active == 0 || - ieee->pHTInfo->bCurrentHTSupport == false || - ieee->pHTInfo->bCurrentAMPDUEnable == false ) - { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "reject to ADDBA_RSP as some capability is not ready(%d, %d, %d)\n",ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport, ieee->pHTInfo->bCurrentAMPDUEnable); - ReasonCode = DELBA_REASON_UNKNOWN_BA; - goto OnADDBARsp_Reject; - } - - - // - // Search for related TS. - // If there is no TS found, we wil reject ADDBA Rsp by sending DELBA frame. - // - if (!GetTs( - ieee, - (PTS_COMMON_INFO*)(&pTS), - dst, - (u8)(pBaParamSet->field.TID), - TX_DIR, - false) ) - { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't get TS in %s()\n", __FUNCTION__); - ReasonCode = DELBA_REASON_UNKNOWN_BA; - goto OnADDBARsp_Reject; - } - - pTS->bAddBaReqInProgress = false; - pPendingBA = &pTS->TxPendingBARecord; - pAdmittedBA = &pTS->TxAdmittedBARecord; - - - // - // Check if related BA is waiting for setup. - // If not, reject by sending DELBA frame. - // - if((pAdmittedBA->bValid==true)) - { - // Since BA is already setup, we ignore all other ADDBA Response. - IEEE80211_DEBUG(IEEE80211_DL_BA, "OnADDBARsp(): Recv ADDBA Rsp. Drop because already admit it! \n"); - return -1; - } - else if((pPendingBA->bValid == false) ||(*pDialogToken != pPendingBA->DialogToken)) - { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "OnADDBARsp(): Recv ADDBA Rsp. BA invalid, DELBA! \n"); - ReasonCode = DELBA_REASON_UNKNOWN_BA; - goto OnADDBARsp_Reject; - } - else - { - IEEE80211_DEBUG(IEEE80211_DL_BA, "OnADDBARsp(): Recv ADDBA Rsp. BA is admitted! Status code:%X\n", *pStatusCode); - DeActivateBAEntry(ieee, pPendingBA); - } - - - if(*pStatusCode == ADDBA_STATUS_SUCCESS) - { - // - // Determine ADDBA Rsp content here. - // We can compare the value of BA parameter set that Peer returned and Self sent. - // If it is OK, then admitted. Or we can send DELBA to cancel BA mechanism. - // - if(pBaParamSet->field.BAPolicy == BA_POLICY_DELAYED) - { - // Since this is a kind of ADDBA failed, we delay next ADDBA process. - pTS->bAddBaReqDelayed = true; - DeActivateBAEntry(ieee, pAdmittedBA); - ReasonCode = DELBA_REASON_END_BA; - goto OnADDBARsp_Reject; - } - - - // - // Admitted condition - // - pAdmittedBA->DialogToken = *pDialogToken; - pAdmittedBA->BaTimeoutValue = *pBaTimeoutVal; - pAdmittedBA->BaStartSeqCtrl = pPendingBA->BaStartSeqCtrl; - pAdmittedBA->BaParamSet = *pBaParamSet; - DeActivateBAEntry(ieee, pAdmittedBA); - ActivateBAEntry(ieee, pAdmittedBA, *pBaTimeoutVal); - } - else - { - // Delay next ADDBA process. - pTS->bAddBaReqDelayed = true; - } - - // End of procedure - return 0; - -OnADDBARsp_Reject: - { - BA_RECORD BA; - BA.BaParamSet = *pBaParamSet; - ieee80211_send_DELBA(ieee, dst, &BA, TX_DIR, ReasonCode); - return 0; - } - -} - -int ieee80211_rx_DELBA(struct ieee80211_device* ieee,struct sk_buff *skb) -{ - struct ieee80211_hdr_3addr* delba = NULL; - PDELBA_PARAM_SET pDelBaParamSet = NULL; - u16* pReasonCode = NULL; - u8* dst = NULL; - - if (skb->len < sizeof( struct ieee80211_hdr_3addr) + 6) - { - IEEE80211_DEBUG(IEEE80211_DL_ERR, " Invalid skb len in DELBA(%d / %zu)\n", skb->len, (sizeof( struct ieee80211_hdr_3addr) + 6)); - return -1; - } - - if(ieee->current_network.qos_data.active == 0 || - ieee->pHTInfo->bCurrentHTSupport == false ) - { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "received DELBA while QOS or HT is not supported(%d, %d)\n",ieee->current_network.qos_data.active, ieee->pHTInfo->bCurrentHTSupport); - return -1; - } - - IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_BA, skb->data, skb->len); - delba = ( struct ieee80211_hdr_3addr*)skb->data; - dst = (u8*)(&delba->addr2[0]); - delba += sizeof( struct ieee80211_hdr_3addr); - pDelBaParamSet = (PDELBA_PARAM_SET)(delba+2); - pReasonCode = (u16*)(delba+4); - - if(pDelBaParamSet->field.Initiator == 1) - { - PRX_TS_RECORD pRxTs; - - if( !GetTs( - ieee, - (PTS_COMMON_INFO*)&pRxTs, - dst, - (u8)pDelBaParamSet->field.TID, - RX_DIR, - false) ) - { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't get TS for RXTS in %s()\n", __FUNCTION__); - return -1; - } - - RxTsDeleteBA(ieee, pRxTs); - } - else - { - PTX_TS_RECORD pTxTs; - - if(!GetTs( - ieee, - (PTS_COMMON_INFO*)&pTxTs, - dst, - (u8)pDelBaParamSet->field.TID, - TX_DIR, - false) ) - { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't get TS for TXTS in %s()\n", __FUNCTION__); - return -1; - } - - pTxTs->bUsingBa = false; - pTxTs->bAddBaReqInProgress = false; - pTxTs->bAddBaReqDelayed = false; - del_timer_sync(&pTxTs->TsAddBaTimer); - //PlatformCancelTimer(Adapter, &pTxTs->TsAddBaTimer); - TxTsDeleteBA(ieee, pTxTs); - } - return 0; -} - -/* ADDBA initiate. This can only be called by TX side. */ -void -TsInitAddBA( - struct ieee80211_device* ieee, - PTX_TS_RECORD pTS, - u8 Policy, - u8 bOverwritePending - ) -{ - PBA_RECORD pBA = &pTS->TxPendingBARecord; - - if(pBA->bValid==true && bOverwritePending==false) - return; - - // Set parameters to "Pending" variable set - DeActivateBAEntry(ieee, pBA); - - pBA->DialogToken++; // DialogToken: Only keep the latest dialog token - pBA->BaParamSet.field.AMSDU_Support = 0; // Do not support A-MSDU with A-MPDU now!! - pBA->BaParamSet.field.BAPolicy = Policy; // Policy: Delayed or Immediate - pBA->BaParamSet.field.TID = pTS->TsCommonInfo.TSpec.f.TSInfo.field.ucTSID; // TID - // BufferSize: This need to be set according to A-MPDU vector - pBA->BaParamSet.field.BufferSize = 32; // BufferSize: This need to be set according to A-MPDU vector - pBA->BaTimeoutValue = 0; // Timeout value: Set 0 to disable Timer - pBA->BaStartSeqCtrl.field.SeqNum = (pTS->TxCurSeq + 3) % 4096; // Block Ack will start after 3 packets later. - - ActivateBAEntry(ieee, pBA, BA_SETUP_TIMEOUT); - - ieee80211_send_ADDBAReq(ieee, pTS->TsCommonInfo.Addr, pBA); -} - -void -TsInitDelBA( struct ieee80211_device* ieee, PTS_COMMON_INFO pTsCommonInfo, TR_SELECT TxRxSelect) -{ - - if(TxRxSelect == TX_DIR) - { - PTX_TS_RECORD pTxTs = (PTX_TS_RECORD)pTsCommonInfo; - - if(TxTsDeleteBA(ieee, pTxTs)) - ieee80211_send_DELBA( - ieee, - pTsCommonInfo->Addr, - (pTxTs->TxAdmittedBARecord.bValid)?(&pTxTs->TxAdmittedBARecord):(&pTxTs->TxPendingBARecord), - TxRxSelect, - DELBA_REASON_END_BA); - } - else if(TxRxSelect == RX_DIR) - { - PRX_TS_RECORD pRxTs = (PRX_TS_RECORD)pTsCommonInfo; - if(RxTsDeleteBA(ieee, pRxTs)) - ieee80211_send_DELBA( - ieee, - pTsCommonInfo->Addr, - &pRxTs->RxAdmittedBARecord, - TxRxSelect, - DELBA_REASON_END_BA ); - } -} - -/* - * BA setup timer - * acturally we send TX_TS_RECORD or RX_TS_RECORD to these timer - */ -void BaSetupTimeOut(unsigned long data) -{ - PTX_TS_RECORD pTxTs = (PTX_TS_RECORD)data; - - pTxTs->bAddBaReqInProgress = false; - pTxTs->bAddBaReqDelayed = true; - pTxTs->TxPendingBARecord.bValid = false; -} - -void TxBaInactTimeout(unsigned long data) -{ - PTX_TS_RECORD pTxTs = (PTX_TS_RECORD)data; - struct ieee80211_device *ieee = container_of(pTxTs, struct ieee80211_device, TxTsRecord[pTxTs->num]); - TxTsDeleteBA(ieee, pTxTs); - ieee80211_send_DELBA( - ieee, - pTxTs->TsCommonInfo.Addr, - &pTxTs->TxAdmittedBARecord, - TX_DIR, - DELBA_REASON_TIMEOUT); -} - -void RxBaInactTimeout(unsigned long data) -{ - PRX_TS_RECORD pRxTs = (PRX_TS_RECORD)data; - struct ieee80211_device *ieee = container_of(pRxTs, struct ieee80211_device, RxTsRecord[pRxTs->num]); - - RxTsDeleteBA(ieee, pRxTs); - ieee80211_send_DELBA( - ieee, - pRxTs->TsCommonInfo.Addr, - &pRxTs->RxAdmittedBARecord, - RX_DIR, - DELBA_REASON_TIMEOUT); -} - diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_HT.h b/drivers/staging/rtl8192e/ieee80211/rtl819x_HT.h deleted file mode 100644 index 56a120c..0000000 --- a/drivers/staging/rtl8192e/ieee80211/rtl819x_HT.h +++ /dev/null @@ -1,483 +0,0 @@ -#ifndef _RTL819XU_HTTYPE_H_ -#define _RTL819XU_HTTYPE_H_ - -//------------------------------------------------------------ -// The HT Capability element is present in beacons, association request, -// reassociation request and probe response frames -//------------------------------------------------------------ - -// -// Operation mode value -// -#define HT_OPMODE_NO_PROTECT 0 -#define HT_OPMODE_OPTIONAL 1 -#define HT_OPMODE_40MHZ_PROTECT 2 -#define HT_OPMODE_MIXED 3 - -// -// MIMO Power Save Setings -// -#define MIMO_PS_STATIC 0 -#define MIMO_PS_DYNAMIC 1 -#define MIMO_PS_NOLIMIT 3 - - -// -// There should be 128 bits to cover all of the MCS rates. However, since -// 8190 does not support too much rates, one integer is quite enough. -// - -#define sHTCLng 4 - - -#define HT_SUPPORTED_MCS_1SS_BITMAP 0x000000ff -#define HT_SUPPORTED_MCS_2SS_BITMAP 0x0000ff00 -#define HT_SUPPORTED_MCS_1SS_2SS_BITMAP HT_MCS_1SS_BITMAP|HT_MCS_1SS_2SS_BITMAP - - -typedef enum _HT_MCS_RATE{ - HT_MCS0 = 0x00000001, - HT_MCS1 = 0x00000002, - HT_MCS2 = 0x00000004, - HT_MCS3 = 0x00000008, - HT_MCS4 = 0x00000010, - HT_MCS5 = 0x00000020, - HT_MCS6 = 0x00000040, - HT_MCS7 = 0x00000080, - HT_MCS8 = 0x00000100, - HT_MCS9 = 0x00000200, - HT_MCS10 = 0x00000400, - HT_MCS11 = 0x00000800, - HT_MCS12 = 0x00001000, - HT_MCS13 = 0x00002000, - HT_MCS14 = 0x00004000, - HT_MCS15 = 0x00008000, - // Do not define MCS32 here although 8190 support MCS32 -}HT_MCS_RATE,*PHT_MCS_RATE; - -// -// Represent Channel Width in HT Capabilities -// -typedef enum _HT_CHANNEL_WIDTH{ - HT_CHANNEL_WIDTH_20 = 0, - HT_CHANNEL_WIDTH_20_40 = 1, -}HT_CHANNEL_WIDTH, *PHT_CHANNEL_WIDTH; - -// -// Represent Extension Channel Offset in HT Capabilities -// This is available only in 40Mhz mode. -// -typedef enum _HT_EXTCHNL_OFFSET{ - HT_EXTCHNL_OFFSET_NO_EXT = 0, - HT_EXTCHNL_OFFSET_UPPER = 1, - HT_EXTCHNL_OFFSET_NO_DEF = 2, - HT_EXTCHNL_OFFSET_LOWER = 3, -}HT_EXTCHNL_OFFSET, *PHT_EXTCHNL_OFFSET; - -typedef enum _CHNLOP{ - CHNLOP_NONE = 0, // No Action now - CHNLOP_SCAN = 1, // Scan in progress - CHNLOP_SWBW = 2, // Bandwidth switching in progress - CHNLOP_SWCHNL = 3, // Software Channel switching in progress -} CHNLOP, *PCHNLOP; - -// Determine if the Channel Operation is in progress -#define CHHLOP_IN_PROGRESS(_pHTInfo) \ - ((_pHTInfo)->ChnlOp > CHNLOP_NONE) ? TRUE : FALSE - -/* -typedef union _HT_CAPABILITY{ - u16 ShortData; - u8 CharData[2]; - struct - { - u16 AdvCoding:1; - u16 ChlWidth:1; - u16 MimoPwrSave:2; - u16 GreenField:1; - u16 ShortGI20Mhz:1; - u16 ShortGI40Mhz:1; - u16 STBC:1; - u16 BeamForm:1; - u16 DelayBA:1; - u16 MaxAMSDUSize:1; - u16 DssCCk:1; - u16 PSMP:1; - u16 Rsvd:3; - }Field; -}HT_CAPABILITY, *PHT_CAPABILITY; - -typedef union _HT_CAPABILITY_MACPARA{ - u8 ShortData; - u8 CharData[1]; - struct - { - u8 MaxRxAMPDU:2; - u8 MPDUDensity:2; - u8 Rsvd:4; - }Field; -}HT_CAPABILITY_MACPARA, *PHT_CAPABILITY_MACPARA; -*/ - -typedef enum _HT_ACTION{ - ACT_RECOMMAND_WIDTH = 0, - ACT_MIMO_PWR_SAVE = 1, - ACT_PSMP = 2, - ACT_SET_PCO_PHASE = 3, - ACT_MIMO_CHL_MEASURE = 4, - ACT_RECIPROCITY_CORRECT = 5, - ACT_MIMO_CSI_MATRICS = 6, - ACT_MIMO_NOCOMPR_STEER = 7, - ACT_MIMO_COMPR_STEER = 8, - ACT_ANTENNA_SELECT = 9, -} HT_ACTION, *PHT_ACTION; - - -/* 2007/06/07 MH Define sub-carrier mode for 40MHZ. */ -typedef enum _HT_Bandwidth_40MHZ_Sub_Carrier{ - SC_MODE_DUPLICATE = 0, - SC_MODE_LOWER = 1, - SC_MODE_UPPER = 2, - SC_MODE_FULL40MHZ = 3, -}HT_BW40_SC_E; - -typedef struct _HT_CAPABILITY_ELE{ - - //HT capability info - u8 AdvCoding:1; - u8 ChlWidth:1; - u8 MimoPwrSave:2; - u8 GreenField:1; - u8 ShortGI20Mhz:1; - u8 ShortGI40Mhz:1; - u8 TxSTBC:1; - u8 RxSTBC:2; - u8 DelayBA:1; - u8 MaxAMSDUSize:1; - u8 DssCCk:1; - u8 PSMP:1; - u8 Rsvd1:1; - u8 LSigTxopProtect:1; - - //MAC HT parameters info - u8 MaxRxAMPDUFactor:2; - u8 MPDUDensity:3; - u8 Rsvd2:3; - - //Supported MCS set - u8 MCS[16]; - - - //Extended HT Capability Info - u16 ExtHTCapInfo; - - //TXBF Capabilities - u8 TxBFCap[4]; - - //Antenna Selection Capabilities - u8 ASCap; - -} __attribute__ ((packed)) HT_CAPABILITY_ELE, *PHT_CAPABILITY_ELE; - -//------------------------------------------------------------ -// The HT Information element is present in beacons -// Only AP is required to include this element -//------------------------------------------------------------ - -typedef struct _HT_INFORMATION_ELE{ - u8 ControlChl; - - u8 ExtChlOffset:2; - u8 RecommemdedTxWidth:1; - u8 RIFS:1; - u8 PSMPAccessOnly:1; - u8 SrvIntGranularity:3; - - u8 OptMode:2; - u8 NonGFDevPresent:1; - u8 Revd1:5; - u8 Revd2:8; - - u8 Rsvd3:6; - u8 DualBeacon:1; - u8 DualCTSProtect:1; - - u8 SecondaryBeacon:1; - u8 LSigTxopProtectFull:1; - u8 PcoActive:1; - u8 PcoPhase:1; - u8 Rsvd4:4; - - u8 BasicMSC[16]; -} __attribute__ ((packed)) HT_INFORMATION_ELE, *PHT_INFORMATION_ELE; - -// -// MIMO Power Save control field. -// This is appear in MIMO Power Save Action Frame -// -typedef struct _MIMOPS_CTRL{ - u8 MimoPsEnable:1; - u8 MimoPsMode:1; - u8 Reserved:6; -} MIMOPS_CTRL, *PMIMOPS_CTRL; - -typedef enum _HT_SPEC_VER{ - HT_SPEC_VER_IEEE = 0, - HT_SPEC_VER_EWC = 1, -}HT_SPEC_VER, *PHT_SPEC_VER; - -typedef enum _HT_AGGRE_MODE_E{ - HT_AGG_AUTO = 0, - HT_AGG_FORCE_ENABLE = 1, - HT_AGG_FORCE_DISABLE = 2, -}HT_AGGRE_MODE_E, *PHT_AGGRE_MODE_E; - -//------------------------------------------------------------ -// The Data structure is used to keep HT related variables when card is -// configured as non-AP STA mode. **Note** Current_xxx should be set -// to default value in HTInitializeHTInfo() -//------------------------------------------------------------ - -typedef struct _RT_HIGH_THROUGHPUT{ - u8 bEnableHT; - u8 bCurrentHTSupport; - - u8 bRegBW40MHz; // Tx 40MHz channel capablity - u8 bCurBW40MHz; // Tx 40MHz channel capability - - u8 bRegShortGI40MHz; // Tx Short GI for 40Mhz - u8 bCurShortGI40MHz; // Tx Short GI for 40MHz - - u8 bRegShortGI20MHz; // Tx Short GI for 20MHz - u8 bCurShortGI20MHz; // Tx Short GI for 20MHz - - u8 bRegSuppCCK; // Tx CCK rate capability - u8 bCurSuppCCK; // Tx CCK rate capability - - // 802.11n spec version for "peer" - HT_SPEC_VER ePeerHTSpecVer; - - - // HT related information for "Self" - HT_CAPABILITY_ELE SelfHTCap; // This is HT cap element sent to peer STA, which also indicate HT Rx capabilities. - HT_INFORMATION_ELE SelfHTInfo; // This is HT info element sent to peer STA, which also indicate HT Rx capabilities. - - // HT related information for "Peer" - u8 PeerHTCapBuf[32]; - u8 PeerHTInfoBuf[32]; - - - // A-MSDU related - u8 bAMSDU_Support; // This indicates Tx A-MSDU capability - u16 nAMSDU_MaxSize; // This indicates Tx A-MSDU capability - u8 bCurrent_AMSDU_Support; // This indicates Tx A-MSDU capability - u16 nCurrent_AMSDU_MaxSize; // This indicates Tx A-MSDU capability - - - // AMPDU related <2006.08.10 Emily> - u8 bAMPDUEnable; // This indicate Tx A-MPDU capability - u8 bCurrentAMPDUEnable; // This indicate Tx A-MPDU capability - u8 AMPDU_Factor; // This indicate Tx A-MPDU capability - u8 CurrentAMPDUFactor; // This indicate Tx A-MPDU capability - u8 MPDU_Density; // This indicate Tx A-MPDU capability - u8 CurrentMPDUDensity; // This indicate Tx A-MPDU capability - - // Forced A-MPDU enable - HT_AGGRE_MODE_E ForcedAMPDUMode; - u8 ForcedAMPDUFactor; - u8 ForcedMPDUDensity; - - // Forced A-MSDU enable - HT_AGGRE_MODE_E ForcedAMSDUMode; - u16 ForcedAMSDUMaxSize; - - u8 bForcedShortGI; - - u8 CurrentOpMode; - - // MIMO PS related - u8 SelfMimoPs; - u8 PeerMimoPs; - - // 40MHz Channel Offset settings. - HT_EXTCHNL_OFFSET CurSTAExtChnlOffset; - u8 bCurTxBW40MHz; // If we use 40 MHz to Tx - u8 PeerBandwidth; - - // For Bandwidth Switching - u8 bSwBwInProgress; - CHNLOP ChnlOp; // software switching channel in progress. By Bruce, 2008-02-15. - u8 SwBwStep; - //struct timer_list SwBwTimer; //moved to ieee80211_device. as timer_list need include some header file here. - - // For Realtek proprietary A-MPDU factor for aggregation - u8 bRegRT2RTAggregation; - u8 bCurrentRT2RTAggregation; - u8 bCurrentRT2RTLongSlotTime; - u8 szRT2RTAggBuffer[10]; - - // Rx Reorder control - u8 bRegRxReorderEnable; - u8 bCurRxReorderEnable; - u8 RxReorderWinSize; - u8 RxReorderPendingTime; - u16 RxReorderDropCounter; - -#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE - u8 UsbTxAggrNum; -#endif -#ifdef USB_RX_AGGREGATION_SUPPORT - u8 UsbRxFwAggrEn; - u8 UsbRxFwAggrPageNum; - u8 UsbRxFwAggrPacketNum; - u8 UsbRxFwAggrTimeout; -#endif - - // Add for Broadcom(Linksys) IOT. Joseph - u8 bIsPeerBcm; - - // For IOT issue. - u8 IOTPeer; - u32 IOTAction; -} __attribute__ ((packed)) RT_HIGH_THROUGHPUT, *PRT_HIGH_THROUGHPUT; - - -//------------------------------------------------------------ -// The Data structure is used to keep HT related variable for "each Sta" -// when card is configured as "AP mode" -//------------------------------------------------------------ - -typedef struct _RT_HTINFO_STA_ENTRY{ - u8 bEnableHT; - - u8 bSupportCck; - - u16 AMSDU_MaxSize; - - u8 AMPDU_Factor; - u8 MPDU_Density; - - u8 HTHighestOperaRate; - - u8 bBw40MHz; - - u8 MimoPs; - - u8 McsRateSet[16]; - - -}RT_HTINFO_STA_ENTRY, *PRT_HTINFO_STA_ENTRY; - - - - - -//------------------------------------------------------------ -// The Data structure is used to keep HT related variable for "each AP" -// when card is configured as "STA mode" -//------------------------------------------------------------ - -typedef struct _BSS_HT{ - - u8 bdSupportHT; - - // HT related elements - u8 bdHTCapBuf[32]; - u16 bdHTCapLen; - u8 bdHTInfoBuf[32]; - u16 bdHTInfoLen; - - HT_SPEC_VER bdHTSpecVer; - //HT_CAPABILITY_ELE bdHTCapEle; - //HT_INFORMATION_ELE bdHTInfoEle; - - u8 bdRT2RTAggregation; - u8 bdRT2RTLongSlotTime; -} __attribute__ ((packed)) BSS_HT, *PBSS_HT; - -typedef struct _MIMO_RSSI{ - u32 EnableAntenna; - u32 AntennaA; - u32 AntennaB; - u32 AntennaC; - u32 AntennaD; - u32 Average; -}MIMO_RSSI, *PMIMO_RSSI; - -typedef struct _MIMO_EVM{ - u32 EVM1; - u32 EVM2; -}MIMO_EVM, *PMIMO_EVM; - -typedef struct _FALSE_ALARM_STATISTICS{ - u32 Cnt_Parity_Fail; - u32 Cnt_Rate_Illegal; - u32 Cnt_Crc8_fail; - u32 Cnt_all; -}FALSE_ALARM_STATISTICS, *PFALSE_ALARM_STATISTICS; - - -extern u8 MCS_FILTER_ALL[16]; -extern u8 MCS_FILTER_1SS[16]; - -/* 2007/07/11 MH Modify the macro. Becaus STA may link with a N-AP. If we set - STA in A/B/G mode and AP is still in N mode. The macro will be wrong. We have - to add a macro to judge wireless mode. */ -#define PICK_RATE(_nLegacyRate, _nMcsRate) \ - (_nMcsRate==0)?(_nLegacyRate&0x7f):(_nMcsRate) -/* 2007/07/12 MH We only define legacy and HT wireless mode now. */ -#define LEGACY_WIRELESS_MODE IEEE_MODE_MASK - -#define CURRENT_RATE(WirelessMode, LegacyRate, HTRate) \ - ((WirelessMode & (LEGACY_WIRELESS_MODE))!=0)?\ - (LegacyRate):\ - (PICK_RATE(LegacyRate, HTRate)) - - - -// MCS Bw 40 {1~7, 12~15,32} -#define RATE_ADPT_1SS_MASK 0xFF -#define RATE_ADPT_2SS_MASK 0xF0 //Skip MCS8~11 because mcs7 > mcs6, 9, 10, 11. 2007.01.16 by Emily -#define RATE_ADPT_MCS32_MASK 0x01 - -#define IS_11N_MCS_RATE(rate) (rate&0x80) - -typedef enum _HT_AGGRE_SIZE{ - HT_AGG_SIZE_8K = 0, - HT_AGG_SIZE_16K = 1, - HT_AGG_SIZE_32K = 2, - HT_AGG_SIZE_64K = 3, -}HT_AGGRE_SIZE_E, *PHT_AGGRE_SIZE_E; - -/* Indicate different AP vendor for IOT issue */ -typedef enum _HT_IOT_PEER -{ - HT_IOT_PEER_UNKNOWN = 0, - HT_IOT_PEER_REALTEK = 1, - HT_IOT_PEER_BROADCOM = 2, - HT_IOT_PEER_RALINK = 3, - HT_IOT_PEER_ATHEROS = 4, - HT_IOT_PEER_CISCO= 5, - HT_IOT_PEER_MARVELL=6, - HT_IOT_PEER_MAX = 7 -}HT_IOT_PEER_E, *PHTIOT_PEER_E; - -// -// IOT Action for different AP -// -typedef enum _HT_IOT_ACTION{ - HT_IOT_ACT_TX_USE_AMSDU_4K = 0x00000001, - HT_IOT_ACT_TX_USE_AMSDU_8K = 0x00000002, - HT_IOT_ACT_DISABLE_MCS14 = 0x00000004, - HT_IOT_ACT_DISABLE_MCS15 = 0x00000008, - HT_IOT_ACT_DISABLE_ALL_2SS = 0x00000010, - HT_IOT_ACT_DISABLE_EDCA_TURBO = 0x00000020, - HT_IOT_ACT_MGNT_USE_CCK_6M = 0x00000040, - HT_IOT_ACT_CDD_FSYNC = 0x00000080, - HT_IOT_ACT_PURE_N_MODE = 0x00000100, - HT_IOT_ACT_FORCED_CTS2SELF = 0x00000200, - HT_IOT_ACT_NULL_DATA_POWER_SAVING = 0x00800000, -}HT_IOT_ACTION_E, *PHT_IOT_ACTION_E; - -#endif //_RTL819XU_HTTYPE_H_ - diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c b/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c deleted file mode 100644 index f7a9da3..0000000 --- a/drivers/staging/rtl8192e/ieee80211/rtl819x_HTProc.c +++ /dev/null @@ -1,1732 +0,0 @@ - -//As this function is mainly ported from Windows driver, so leave the name little changed. If any confusion caused, tell me. Created by WB. 2008.05.08 -#include "ieee80211.h" -#include "rtl819x_HT.h" -u8 MCS_FILTER_ALL[16] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - -u8 MCS_FILTER_1SS[16] = {0xff, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - -u16 MCS_DATA_RATE[2][2][77] = - { { {13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78 ,104, 156, 208, 234, 260, - 39, 78, 117, 234, 312, 351, 390, 52, 104, 156, 208, 312, 416, 468, 520, - 0, 78, 104, 130, 117, 156, 195, 104, 130, 130, 156, 182, 182, 208, 156, 195, - 195, 234, 273, 273, 312, 130, 156, 181, 156, 181, 208, 234, 208, 234, 260, 260, - 286, 195, 234, 273, 234, 273, 312, 351, 312, 351, 390, 390, 429}, // Long GI, 20MHz - {14, 29, 43, 58, 87, 116, 130, 144, 29, 58, 87, 116, 173, 231, 260, 289, - 43, 87, 130, 173, 260, 347, 390, 433, 58, 116, 173, 231, 347, 462, 520, 578, - 0, 87, 116, 144, 130, 173, 217, 116, 144, 144, 173, 202, 202, 231, 173, 217, - 217, 260, 303, 303, 347, 144, 173, 202, 173, 202, 231, 260, 231, 260, 289, 289, - 318, 217, 260, 303, 260, 303, 347, 390, 347, 390, 433, 433, 477} }, // Short GI, 20MHz - { {27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, 540, - 81, 162, 243, 324, 486, 648, 729, 810, 108, 216, 324, 432, 648, 864, 972, 1080, - 12, 162, 216, 270, 243, 324, 405, 216, 270, 270, 324, 378, 378, 432, 324, 405, - 405, 486, 567, 567, 648, 270, 324, 378, 324, 378, 432, 486, 432, 486, 540, 540, - 594, 405, 486, 567, 486, 567, 648, 729, 648, 729, 810, 810, 891}, // Long GI, 40MHz - {30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, 600, - 90, 180, 270, 360, 540, 720, 810, 900, 120, 240, 360, 480, 720, 960, 1080, 1200, - 13, 180, 240, 300, 270, 360, 450, 240, 300, 300, 360, 420, 420, 480, 360, 450, - 450, 540, 630, 630, 720, 300, 360, 420, 360, 420, 480, 540, 480, 540, 600, 600, - 660, 450, 540, 630, 540, 630, 720, 810, 720, 810, 900, 900, 990} } // Short GI, 40MHz - }; - -static const u8 UNKNOWN_BORADCOM[3] = {0x00, 0x14, 0xbf}; -static const u8 LINKSYSWRT330_LINKSYSWRT300_BROADCOM[3] = {0x00, 0x1a, 0x70}; -static const u8 LINKSYSWRT350_LINKSYSWRT150_BROADCOM[3] = {0x00, 0x1d, 0x7e}; -//static u8 NETGEAR834Bv2_BROADCOM[3] = {0x00, 0x1b, 0x2f}; -static const u8 BELKINF5D8233V1_RALINK[3] = {0x00, 0x17, 0x3f}; -static const u8 BELKINF5D82334V3_RALINK[3] = {0x00, 0x1c, 0xdf}; -static const u8 PCI_RALINK[3] = {0x00, 0x90, 0xcc}; -static const u8 EDIMAX_RALINK[3] = {0x00, 0x0e, 0x2e}; -static const u8 AIRLINK_RALINK[3] = {0x00, 0x18, 0x02}; -static const u8 DLINK_ATHEROS[3] = {0x00, 0x1c, 0xf0}; -static const u8 CISCO_BROADCOM[3] = {0x00, 0x17, 0x94}; -static const u8 LINKSYS_MARVELL_4400N[3] = {0x00, 0x14, 0xa4}; - -// 2008/04/01 MH For Cisco G mode RX TP We need to change FW duration. Should we put the -// code in other place?? -//static u8 WIFI_CISCO_G_AP[3] = {0x00, 0x40, 0x96}; -/******************************************************************************************************************** - *function: This function update default settings in pHTInfo structure - * input: PRT_HIGH_THROUGHPUT pHTInfo - * output: none - * return: none - * notice: These value need be modified if any changes. - * *****************************************************************************************************************/ -void HTUpdateDefaultSetting(struct ieee80211_device* ieee) -{ - PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; - - // ShortGI support - pHTInfo->bRegShortGI20MHz= 1; - pHTInfo->bRegShortGI40MHz= 1; - - // 40MHz channel support - pHTInfo->bRegBW40MHz = 1; - - // CCK rate support in 40MHz channel - if(pHTInfo->bRegBW40MHz) - pHTInfo->bRegSuppCCK = 1; - else - pHTInfo->bRegSuppCCK = true; - - // AMSDU related - pHTInfo->nAMSDU_MaxSize = 7935UL; - pHTInfo->bAMSDU_Support = 0; - - // AMPDU related - pHTInfo->bAMPDUEnable = 1; - pHTInfo->AMPDU_Factor = 2; //// 0: 2n13(8K), 1:2n14(16K), 2:2n15(32K), 3:2n16(64k) - pHTInfo->MPDU_Density = 0;// 0: No restriction, 1: 1/8usec, 2: 1/4usec, 3: 1/2usec, 4: 1usec, 5: 2usec, 6: 4usec, 7:8usec - - // MIMO Power Save - pHTInfo->SelfMimoPs = 3;// 0: Static Mimo Ps, 1: Dynamic Mimo Ps, 3: No Limitation, 2: Reserved(Set to 3 automatically.) - if(pHTInfo->SelfMimoPs == 2) - pHTInfo->SelfMimoPs = 3; - // 8190 only. Assign rate operation mode to firmware - ieee->bTxDisableRateFallBack = 0; - ieee->bTxUseDriverAssingedRate = 0; - -#ifdef TO_DO_LIST - // 8190 only. Assign duration operation mode to firmware - pMgntInfo->bTxEnableFwCalcDur = (BOOLEAN)pNdisCommon->bRegTxEnableFwCalcDur; -#endif - // 8190 only, Realtek proprietary aggregation mode - // Set MPDUDensity=2, 1: Set MPDUDensity=2(32k) for Realtek AP and set MPDUDensity=0(8k) for others - pHTInfo->bRegRT2RTAggregation = 1;//0: Set MPDUDensity=2, 1: Set MPDUDensity=2(32k) for Realtek AP and set MPDUDensity=0(8k) for others - - // For Rx Reorder Control - pHTInfo->bRegRxReorderEnable = 1; - pHTInfo->RxReorderWinSize = 64; - pHTInfo->RxReorderPendingTime = 30; - -#ifdef USB_TX_DRIVER_AGGREGATION_ENABLE - pHTInfo->UsbTxAggrNum = 4; -#endif -#ifdef USB_RX_AGGREGATION_SUPPORT - pHTInfo->UsbRxFwAggrEn = 1; - pHTInfo->UsbRxFwAggrPageNum = 24; - pHTInfo->UsbRxFwAggrPacketNum = 8; - pHTInfo->UsbRxFwAggrTimeout = 16; ////usb rx FW aggregation timeout threshold.It's in units of 64us -#endif - - -} -/******************************************************************************************************************** - *function: This function print out each field on HT capability IE mainly from (Beacon/ProbeRsp/AssocReq) - * input: u8* CapIE //Capability IE to be printed out - * u8* TitleString //mainly print out caller function - * output: none - * return: none - * notice: Driver should not print out this message by default. - * *****************************************************************************************************************/ -void HTDebugHTCapability(u8* CapIE, u8* TitleString ) -{ - - static u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; // For 11n EWC definition, 2007.07.17, by Emily - PHT_CAPABILITY_ELE pCapELE; - - if(!memcmp(CapIE, EWC11NHTCap, sizeof(EWC11NHTCap))) - { - //EWC IE - IEEE80211_DEBUG(IEEE80211_DL_HT, "EWC IE in %s()\n", __FUNCTION__); - pCapELE = (PHT_CAPABILITY_ELE)(&CapIE[4]); - }else - pCapELE = (PHT_CAPABILITY_ELE)(&CapIE[0]); - - IEEE80211_DEBUG(IEEE80211_DL_HT, "<Log HT Capability>. Called by %s\n", TitleString ); - - IEEE80211_DEBUG(IEEE80211_DL_HT, "\tSupported Channel Width = %s\n", (pCapELE->ChlWidth)?"20MHz": "20/40MHz"); - IEEE80211_DEBUG(IEEE80211_DL_HT, "\tSupport Short GI for 20M = %s\n", (pCapELE->ShortGI20Mhz)?"YES": "NO"); - IEEE80211_DEBUG(IEEE80211_DL_HT, "\tSupport Short GI for 40M = %s\n", (pCapELE->ShortGI40Mhz)?"YES": "NO"); - IEEE80211_DEBUG(IEEE80211_DL_HT, "\tSupport TX STBC = %s\n", (pCapELE->TxSTBC)?"YES": "NO"); - IEEE80211_DEBUG(IEEE80211_DL_HT, "\tMax AMSDU Size = %s\n", (pCapELE->MaxAMSDUSize)?"3839": "7935"); - IEEE80211_DEBUG(IEEE80211_DL_HT, "\tSupport CCK in 20/40 mode = %s\n", (pCapELE->DssCCk)?"YES": "NO"); - IEEE80211_DEBUG(IEEE80211_DL_HT, "\tMax AMPDU Factor = %d\n", pCapELE->MaxRxAMPDUFactor); - IEEE80211_DEBUG(IEEE80211_DL_HT, "\tMPDU Density = %d\n", pCapELE->MPDUDensity); - IEEE80211_DEBUG(IEEE80211_DL_HT, "\tMCS Rate Set = [%x][%x][%x][%x][%x]\n", pCapELE->MCS[0],\ - pCapELE->MCS[1], pCapELE->MCS[2], pCapELE->MCS[3], pCapELE->MCS[4]); -} -/******************************************************************************************************************** - *function: This function print out each field on HT Information IE mainly from (Beacon/ProbeRsp) - * input: u8* InfoIE //Capability IE to be printed out - * u8* TitleString //mainly print out caller function - * output: none - * return: none - * notice: Driver should not print out this message by default. - * *****************************************************************************************************************/ -void HTDebugHTInfo(u8* InfoIE, u8* TitleString) -{ - - static u8 EWC11NHTInfo[] = {0x00, 0x90, 0x4c, 0x34}; // For 11n EWC definition, 2007.07.17, by Emily - PHT_INFORMATION_ELE pHTInfoEle; - - if(!memcmp(InfoIE, EWC11NHTInfo, sizeof(EWC11NHTInfo))) - { - // Not EWC IE - IEEE80211_DEBUG(IEEE80211_DL_HT, "EWC IE in %s()\n", __FUNCTION__); - pHTInfoEle = (PHT_INFORMATION_ELE)(&InfoIE[4]); - }else - pHTInfoEle = (PHT_INFORMATION_ELE)(&InfoIE[0]); - - - IEEE80211_DEBUG(IEEE80211_DL_HT, "<Log HT Information Element>. Called by %s\n", TitleString); - - IEEE80211_DEBUG(IEEE80211_DL_HT, "\tPrimary channel = %d\n", pHTInfoEle->ControlChl); - IEEE80211_DEBUG(IEEE80211_DL_HT, "\tSenondary channel ="); - switch(pHTInfoEle->ExtChlOffset) - { - case 0: - IEEE80211_DEBUG(IEEE80211_DL_HT, "Not Present\n"); - break; - case 1: - IEEE80211_DEBUG(IEEE80211_DL_HT, "Upper channel\n"); - break; - case 2: - IEEE80211_DEBUG(IEEE80211_DL_HT, "Reserved. Eooro!!!\n"); - break; - case 3: - IEEE80211_DEBUG(IEEE80211_DL_HT, "Lower Channel\n"); - break; - } - IEEE80211_DEBUG(IEEE80211_DL_HT, "\tRecommended channel width = %s\n", (pHTInfoEle->RecommemdedTxWidth)?"20Mhz": "40Mhz"); - - IEEE80211_DEBUG(IEEE80211_DL_HT, "\tOperation mode for protection = "); - switch(pHTInfoEle->OptMode) - { - case 0: - IEEE80211_DEBUG(IEEE80211_DL_HT, "No Protection\n"); - break; - case 1: - IEEE80211_DEBUG(IEEE80211_DL_HT, "HT non-member protection mode\n"); - break; - case 2: - IEEE80211_DEBUG(IEEE80211_DL_HT, "Suggest to open protection\n"); - break; - case 3: - IEEE80211_DEBUG(IEEE80211_DL_HT, "HT mixed mode\n"); - break; - } - - IEEE80211_DEBUG(IEEE80211_DL_HT, "\tBasic MCS Rate Set = [%x][%x][%x][%x][%x]\n", pHTInfoEle->BasicMSC[0],\ - pHTInfoEle->BasicMSC[1], pHTInfoEle->BasicMSC[2], pHTInfoEle->BasicMSC[3], pHTInfoEle->BasicMSC[4]); -} - -/* -* Return: true if station in half n mode and AP supports 40 bw -*/ -bool IsHTHalfNmode40Bandwidth(struct ieee80211_device* ieee) -{ - bool retValue = false; - PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; - - if(pHTInfo->bCurrentHTSupport == false ) // wireless is n mode - retValue = false; - else if(pHTInfo->bRegBW40MHz == false) // station supports 40 bw - retValue = false; - else if (!ieee->GetHalfNmodeSupportByAPsHandler(ieee)) // station in half n mode - retValue = false; - else if(((PHT_CAPABILITY_ELE)(pHTInfo->PeerHTCapBuf))->ChlWidth) // ap support 40 bw - retValue = true; - else - retValue = false; - - return retValue; -} - -bool IsHTHalfNmodeSGI(struct ieee80211_device* ieee, bool is40MHz) -{ - bool retValue = false; - PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; - - if(pHTInfo->bCurrentHTSupport == false ) // wireless is n mode - retValue = false; - else if (!ieee->GetHalfNmodeSupportByAPsHandler(ieee)) // station in half n mode - retValue = false; - else if(is40MHz) // ap support 40 bw - { - if(((PHT_CAPABILITY_ELE)(pHTInfo->PeerHTCapBuf))->ShortGI40Mhz) // ap support 40 bw short GI - retValue = true; - else - retValue = false; - } - else - { - if(((PHT_CAPABILITY_ELE)(pHTInfo->PeerHTCapBuf))->ShortGI20Mhz) // ap support 40 bw short GI - retValue = true; - else - retValue = false; - } - - return retValue; -} - -u16 HTHalfMcsToDataRate(struct ieee80211_device* ieee, u8 nMcsRate) -{ - - u8 is40MHz; - u8 isShortGI; - - is40MHz = (IsHTHalfNmode40Bandwidth(ieee))?1:0; - isShortGI = (IsHTHalfNmodeSGI(ieee, is40MHz))? 1:0; - - return MCS_DATA_RATE[is40MHz][isShortGI][(nMcsRate&0x7f)]; -} - - -u16 HTMcsToDataRate( struct ieee80211_device* ieee, u8 nMcsRate) -{ - PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; - - u8 is40MHz = (pHTInfo->bCurBW40MHz)?1:0; - u8 isShortGI = (pHTInfo->bCurBW40MHz)? - ((pHTInfo->bCurShortGI40MHz)?1:0): - ((pHTInfo->bCurShortGI20MHz)?1:0); - return MCS_DATA_RATE[is40MHz][isShortGI][(nMcsRate&0x7f)]; -} - -/******************************************************************************************************************** - *function: This function returns current datarate. - * input: struct ieee80211_device* ieee - * u8 nDataRate - * output: none - * return: tx rate - * notice: quite unsure about how to use this function //wb - * *****************************************************************************************************************/ -u16 TxCountToDataRate( struct ieee80211_device* ieee, u8 nDataRate) -{ - //PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; - u16 CCKOFDMRate[12] = {0x02 , 0x04 , 0x0b , 0x16 , 0x0c , 0x12 , 0x18 , 0x24 , 0x30 , 0x48 , 0x60 , 0x6c}; - u8 is40MHz = 0; - u8 isShortGI = 0; - - if(nDataRate < 12) - { - return CCKOFDMRate[nDataRate]; - } - else - { - if (nDataRate >= 0x10 && nDataRate <= 0x1f)//if(nDataRate > 11 && nDataRate < 28 ) - { - is40MHz = 0; - isShortGI = 0; - - // nDataRate = nDataRate - 12; - } - else if(nDataRate >=0x20 && nDataRate <= 0x2f ) //(27, 44) - { - is40MHz = 1; - isShortGI = 0; - - //nDataRate = nDataRate - 28; - } - else if(nDataRate >= 0x30 && nDataRate <= 0x3f ) //(43, 60) - { - is40MHz = 0; - isShortGI = 1; - - //nDataRate = nDataRate - 44; - } - else if(nDataRate >= 0x40 && nDataRate <= 0x4f ) //(59, 76) - { - is40MHz = 1; - isShortGI = 1; - - //nDataRate = nDataRate - 60; - } - return MCS_DATA_RATE[is40MHz][isShortGI][nDataRate&0xf]; - } -} - - - -bool IsHTHalfNmodeAPs(struct ieee80211_device* ieee) -{ - bool retValue = false; - struct ieee80211_network* net = &ieee->current_network; -#if 0 - if(ieee->bHalfNMode == false) - retValue = false; - else -#endif - if((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3)==0) || - (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3)==0) || - (memcmp(net->bssid, PCI_RALINK, 3)==0) || - (memcmp(net->bssid, EDIMAX_RALINK, 3)==0) || - (memcmp(net->bssid, AIRLINK_RALINK, 3)==0) || - (net->ralink_cap_exist)) - retValue = true; - else if((memcmp(net->bssid, UNKNOWN_BORADCOM, 3)==0) || - (memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0)|| - (memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)==0)|| - //(memcmp(net->bssid, NETGEAR834Bv2_BROADCOM, 3)==0) || - (net->broadcom_cap_exist)) - retValue = true; - else if(net->bssht.bdRT2RTAggregation) - retValue = true; - else - retValue = false; - - return retValue; -} - -/******************************************************************************************************************** - *function: This function returns peer IOT. - * input: struct ieee80211_device* ieee - * output: none - * return: - * notice: - * *****************************************************************************************************************/ -void HTIOTPeerDetermine(struct ieee80211_device* ieee) -{ - PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; - struct ieee80211_network* net = &ieee->current_network; - if(net->bssht.bdRT2RTAggregation) - pHTInfo->IOTPeer = HT_IOT_PEER_REALTEK; - else if(net->broadcom_cap_exist){ - pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM; - } - else if((memcmp(net->bssid, UNKNOWN_BORADCOM, 3)==0) || - (memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0)|| - (memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)==0)){//|| - //(memcmp(net->bssid, NETGEAR834Bv2_BROADCOM, 3)==0) ){ - pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM; - } - else if((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3)==0) || - (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3)==0) || - (memcmp(net->bssid, PCI_RALINK, 3)==0) || - (memcmp(net->bssid, EDIMAX_RALINK, 3)==0) || - (memcmp(net->bssid, AIRLINK_RALINK, 3)==0) || - net->ralink_cap_exist) - pHTInfo->IOTPeer = HT_IOT_PEER_RALINK; - else if((net->atheros_cap_exist )|| (memcmp(net->bssid, DLINK_ATHEROS, 3) == 0)) - pHTInfo->IOTPeer = HT_IOT_PEER_ATHEROS; - else if(memcmp(net->bssid, CISCO_BROADCOM, 3)==0) - pHTInfo->IOTPeer = HT_IOT_PEER_CISCO; - else if ((memcmp(net->bssid, LINKSYS_MARVELL_4400N, 3) == 0) || - net->marvell_cap_exist){ - pHTInfo->IOTPeer = HT_IOT_PEER_MARVELL; - } - else - pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN; - - IEEE80211_DEBUG(IEEE80211_DL_IOT, "Joseph debug!! IOTPEER: %x\n", pHTInfo->IOTPeer); -} -/******************************************************************************************************************** - *function: Check whether driver should declare received rate up to MCS13 only since some chipset is not good - * at receiving MCS14~15 frame from some AP. - * input: struct ieee80211_device* ieee - * u8 * PeerMacAddr - * output: none - * return: return 1 if driver should declare MCS13 only(otherwise return 0) - * *****************************************************************************************************************/ -u8 HTIOTActIsDisableMCS14(struct ieee80211_device* ieee, u8* PeerMacAddr) -{ - u8 ret = 0; -#if 0 - // Apply for 819u only -#if (HAL_CODE_BASE==RTL8192 && DEV_BUS_TYPE==USB_INTERFACE) - if((memcmp(PeerMacAddr, UNKNOWN_BORADCOM, 3)==0) || - (memcmp(PeerMacAddr, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0) - ) - { - ret = 1; - } - - - if(pHTInfo->bCurrentRT2RTAggregation) - { - // The parameter of pHTInfo->bCurrentRT2RTAggregation must be decided previously - ret = 1; - } -#endif -#endif - return ret; - } - -u8 HTIOTActIsForcedCTS2Self(struct ieee80211_device *ieee, struct ieee80211_network *network) -{ - u8 retValue = 0; - //if(network->marvell_cap_exist) - if(ieee->pHTInfo->IOTPeer == HT_IOT_PEER_MARVELL) - { - retValue = 1; - } - - return retValue; -} - - -/** -* Function: HTIOTActIsDisableMCS15 -* -* Overview: Check whether driver should declare capability of receiving MCS15 -* -* Input: -* PADAPTER Adapter, -* -* Output: None -* Return: true if driver should disable MCS15 -* 2008.04.15 Emily -*/ -bool HTIOTActIsDisableMCS15(struct ieee80211_device* ieee) -{ - bool retValue = false; - -#ifdef TODO - // Apply for 819u only -#if (HAL_CODE_BASE==RTL8192) - -#if (DEV_BUS_TYPE == USB_INTERFACE) - // Alway disable MCS15 by Jerry Chang's request.by Emily, 2008.04.15 - retValue = true; -#elif (DEV_BUS_TYPE == PCI_INTERFACE) - // Enable MCS15 if the peer is Cisco AP. by Emily, 2008.05.12 -// if(pBssDesc->bCiscoCapExist) -// retValue = false; -// else - retValue = false; -#endif -#endif -#endif - // Jerry Chang suggest that 8190 1x2 does not need to disable MCS15 - - return retValue; -} - -/** -* Function: HTIOTActIsDisableMCSTwoSpatialStream -* -* Overview: Check whether driver should declare capability of receiving All 2 ss packets -* -* Input: -* PADAPTER Adapter, -* -* Output: None -* Return: true if driver should disable all two spatial stream packet -* 2008.04.21 Emily -*/ -bool HTIOTActIsDisableMCSTwoSpatialStream(struct ieee80211_device* ieee, u8 *PeerMacAddr) -{ - bool retValue = false; - -#ifdef TODO - // Apply for 819u only -//#if (HAL_CODE_BASE==RTL8192) - - //This rule only apply to Belkin(Ralink) AP - if(IS_UNDER_11N_AES_MODE(Adapter)) - { - if((PlatformCompareMemory(PeerMacAddr, BELKINF5D8233V1_RALINK, 3)==0) || - (PlatformCompareMemory(PeerMacAddr, PCI_RALINK, 3)==0) || - (PlatformCompareMemory(PeerMacAddr, EDIMAX_RALINK, 3)==0)) - { - //Set True to disable this function. Disable by default, Emily, 2008.04.23 - retValue = false; - } - } - -//#endif -#endif - return retValue; -} - -/******************************************************************************************************************** - *function: Check whether driver should disable EDCA turbo mode - * input: struct ieee80211_device* ieee - * u8* PeerMacAddr - * output: none - * return: return 1 if driver should disable EDCA turbo mode(otherwise return 0) - * *****************************************************************************************************************/ -u8 HTIOTActIsDisableEDCATurbo(struct ieee80211_device* ieee, u8* PeerMacAddr) -{ - u8 retValue = false; // default enable EDCA Turbo mode. - // Set specific EDCA parameter for different AP in DM handler. - - return retValue; -#if 0 - if((memcmp(PeerMacAddr, UNKNOWN_BORADCOM, 3)==0)|| - (memcmp(PeerMacAddr, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0)|| - (memcmp(PeerMacAddr, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)==0)|| - (memcmp(PeerMacAddr, NETGEAR834Bv2_BROADCOM, 3)==0)) - - { - retValue = 1; //Linksys disable EDCA turbo mode - } - - return retValue; -#endif -} - -/******************************************************************************************************************** - *function: Check whether we need to use OFDM to sned MGNT frame for broadcom AP - * input: struct ieee80211_network *network //current network we live - * output: none - * return: return 1 if true - * *****************************************************************************************************************/ -u8 HTIOTActIsMgntUseCCK6M(struct ieee80211_network *network) -{ - u8 retValue = 0; - - // 2008/01/25 MH Judeg if we need to use OFDM to sned MGNT frame for broadcom AP. - // 2008/01/28 MH We must prevent that we select null bssid to link. - - if(network->broadcom_cap_exist) - { - retValue = 1; - } - - return retValue; -} - -u8 HTIOTActIsCCDFsync(u8* PeerMacAddr) -{ - u8 retValue = 0; - if( (memcmp(PeerMacAddr, UNKNOWN_BORADCOM, 3)==0) || - (memcmp(PeerMacAddr, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3)==0) || - (memcmp(PeerMacAddr, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3) ==0)) - { - retValue = 1; - } - - return retValue; -} - -// -// Send null data for to tell AP that we are awake. -// -bool -HTIOTActIsNullDataPowerSaving(struct ieee80211_device* ieee,struct ieee80211_network *network) -{ - bool retValue = false; - - PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; - { - if(pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) // ||(pBssDesc->Vender == HT_IOT_PEER_ATHEROS && pBssDesc->SubTypeOfVender == HT_IOT_PEER_ATHEROS_DIR635)) - return true; - - } - return retValue; -} - -void HTResetIOTSetting( - PRT_HIGH_THROUGHPUT pHTInfo -) -{ - pHTInfo->IOTAction = 0; - pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN; -} - - -/******************************************************************************************************************** - *function: Construct Capablility Element in Beacon... if HTEnable is turned on - * input: struct ieee80211_device* ieee - * u8* posHTCap //pointer to store Capability Ele - * u8* len //store length of CE - * u8 IsEncrypt //whether encrypt, needed further - * output: none - * return: none - * notice: posHTCap can't be null and should be initialized before. - * *****************************************************************************************************************/ -void HTConstructCapabilityElement(struct ieee80211_device* ieee, u8* posHTCap, u8* len, u8 IsEncrypt) -{ - PRT_HIGH_THROUGHPUT pHT = ieee->pHTInfo; - PHT_CAPABILITY_ELE pCapELE = NULL; - //u8 bIsDeclareMCS13; - - if ((posHTCap == NULL) || (pHT == NULL)) - { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "posHTCap or pHTInfo can't be null in HTConstructCapabilityElement()\n"); - return; - } - memset(posHTCap, 0, *len); - if(pHT->ePeerHTSpecVer == HT_SPEC_VER_EWC) - { - u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; // For 11n EWC definition, 2007.07.17, by Emily - memcpy(posHTCap, EWC11NHTCap, sizeof(EWC11NHTCap)); - pCapELE = (PHT_CAPABILITY_ELE)&(posHTCap[4]); - }else - { - pCapELE = (PHT_CAPABILITY_ELE)posHTCap; - } - - - //HT capability info - pCapELE->AdvCoding = 0; // This feature is not supported now!! - if (ieee->GetHalfNmodeSupportByAPsHandler(ieee)) - { - pCapELE->ChlWidth = 0; - } - else - { - pCapELE->ChlWidth = (pHT->bRegBW40MHz?1:0); - } - -// pCapELE->ChlWidth = (pHT->bRegBW40MHz?1:0); - pCapELE->MimoPwrSave = pHT->SelfMimoPs; - pCapELE->GreenField = 0; // This feature is not supported now!! - pCapELE->ShortGI20Mhz = 1; // We can receive Short GI!! - pCapELE->ShortGI40Mhz = 1; // We can receive Short GI!! - //DbgPrint("TX HT cap/info ele BW=%d SG20=%d SG40=%d\n\r", - //pCapELE->ChlWidth, pCapELE->ShortGI20Mhz, pCapELE->ShortGI40Mhz); - pCapELE->TxSTBC = 1; - pCapELE->RxSTBC = 0; - pCapELE->DelayBA = 0; // Do not support now!! - pCapELE->MaxAMSDUSize = (MAX_RECEIVE_BUFFER_SIZE>=7935)?1:0; - pCapELE->DssCCk = ((pHT->bRegBW40MHz)?(pHT->bRegSuppCCK?1:0):0); - pCapELE->PSMP = 0; // Do not support now!! - pCapELE->LSigTxopProtect = 0; // Do not support now!! - - - //MAC HT parameters info - // TODO: Nedd to take care of this part - IEEE80211_DEBUG(IEEE80211_DL_HT, "TX HT cap/info ele BW=%d MaxAMSDUSize:%d DssCCk:%d\n", pCapELE->ChlWidth, pCapELE->MaxAMSDUSize, pCapELE->DssCCk); - - if( IsEncrypt) - { - pCapELE->MPDUDensity = 7; // 8us - pCapELE->MaxRxAMPDUFactor = 2; // 2 is for 32 K and 3 is 64K - } - else - { - pCapELE->MaxRxAMPDUFactor = 3; // 2 is for 32 K and 3 is 64K - pCapELE->MPDUDensity = 0; // no density - } - - //Supported MCS set - memcpy(pCapELE->MCS, ieee->Regdot11HTOperationalRateSet, 16); - if(pHT->IOTAction & HT_IOT_ACT_DISABLE_MCS15) - pCapELE->MCS[1] &= 0x7f; - - if(pHT->IOTAction & HT_IOT_ACT_DISABLE_MCS14) - pCapELE->MCS[1] &= 0xbf; - - if(pHT->IOTAction & HT_IOT_ACT_DISABLE_ALL_2SS) - pCapELE->MCS[1] &= 0x00; - - // 2008.06.12 - // For RTL819X, if pairwisekey = wep/tkip, ap is ralink, we support only MCS0~7. - if (ieee->GetHalfNmodeSupportByAPsHandler(ieee)) - { - int i; - for(i = 1; i< 16; i++) - pCapELE->MCS[i] = 0; - } - - //Extended HT Capability Info - memset(&pCapELE->ExtHTCapInfo, 0, 2); - - - //TXBF Capabilities - memset(pCapELE->TxBFCap, 0, 4); - - //Antenna Selection Capabilities - pCapELE->ASCap = 0; -//add 2 to give space for element ID and len when construct frames - if(pHT->ePeerHTSpecVer == HT_SPEC_VER_EWC) - *len = 30 + 2; - else - *len = 26 + 2; -} -/******************************************************************************************************************** - *function: Construct Information Element in Beacon... if HTEnable is turned on - * input: struct ieee80211_device* ieee - * u8* posHTCap //pointer to store Information Ele - * u8* len //store len of - * u8 IsEncrypt //whether encrypt, needed further - * output: none - * return: none - * notice: posHTCap can't be null and be initialized before. only AP and IBSS sta should do this - * *****************************************************************************************************************/ -void HTConstructInfoElement(struct ieee80211_device* ieee, u8* posHTInfo, u8* len, u8 IsEncrypt) -{ - PRT_HIGH_THROUGHPUT pHT = ieee->pHTInfo; - PHT_INFORMATION_ELE pHTInfoEle = (PHT_INFORMATION_ELE)posHTInfo; - if ((posHTInfo == NULL) || (pHTInfoEle == NULL)) - { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "posHTInfo or pHTInfoEle can't be null in HTConstructInfoElement()\n"); - return; - } - - memset(posHTInfo, 0, *len); - if ( (ieee->iw_mode == IW_MODE_ADHOC) || (ieee->iw_mode == IW_MODE_MASTER)) //ap mode is not currently supported - { - pHTInfoEle->ControlChl = ieee->current_network.channel; - pHTInfoEle->ExtChlOffset = ((pHT->bRegBW40MHz == false)?HT_EXTCHNL_OFFSET_NO_EXT: - (ieee->current_network.channel<=6)? - HT_EXTCHNL_OFFSET_UPPER:HT_EXTCHNL_OFFSET_LOWER); - pHTInfoEle->RecommemdedTxWidth = pHT->bRegBW40MHz; - pHTInfoEle->RIFS = 0; - pHTInfoEle->PSMPAccessOnly = 0; - pHTInfoEle->SrvIntGranularity = 0; - pHTInfoEle->OptMode = pHT->CurrentOpMode; - pHTInfoEle->NonGFDevPresent = 0; - pHTInfoEle->DualBeacon = 0; - pHTInfoEle->SecondaryBeacon = 0; - pHTInfoEle->LSigTxopProtectFull = 0; - pHTInfoEle->PcoActive = 0; - pHTInfoEle->PcoPhase = 0; - - memset(pHTInfoEle->BasicMSC, 0, 16); - - - *len = 22 + 2; //same above - - } - else - { - //STA should not generate High Throughput Information Element - *len = 0; - } -} - -/* - * According to experiment, Realtek AP to STA (based on rtl8190) may achieve best performance - * if both STA and AP set limitation of aggregation size to 32K, that is, set AMPDU density to 2 - * (Ref: IEEE 11n specification). However, if Realtek STA associates to other AP, STA should set - * limitation of aggregation size to 8K, otherwise, performance of traffic stream from STA to AP - * will be much less than the traffic stream from AP to STA if both of the stream runs concurrently - * at the same time. - * - * Frame Format - * Element ID Length OUI Type1 Reserved - * 1 byte 1 byte 3 bytes 1 byte 1 byte - * - * OUI = 0x00, 0xe0, 0x4c, - * Type = 0x02 - * Reserved = 0x00 - * - * 2007.8.21 by Emily -*/ -/******************************************************************************************************************** - *function: Construct Information Element in Beacon... in RT2RT condition - * input: struct ieee80211_device* ieee - * u8* posRT2RTAgg //pointer to store Information Ele - * u8* len //store len - * output: none - * return: none - * notice: - * *****************************************************************************************************************/ -void HTConstructRT2RTAggElement(struct ieee80211_device* ieee, u8* posRT2RTAgg, u8* len) -{ - if (posRT2RTAgg == NULL) { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "posRT2RTAgg can't be null in HTConstructRT2RTAggElement()\n"); - return; - } - memset(posRT2RTAgg, 0, *len); - *posRT2RTAgg++ = 0x00; - *posRT2RTAgg++ = 0xe0; - *posRT2RTAgg++ = 0x4c; - *posRT2RTAgg++ = 0x02; - *posRT2RTAgg++ = 0x01; - *posRT2RTAgg = 0x10;//*posRT2RTAgg = 0x02; - - if(ieee->bSupportRemoteWakeUp) { - *posRT2RTAgg |= 0x08;//RT_HT_CAP_USE_WOW; - } - - *len = 6 + 2; - return; -#ifdef TODO -#if(HAL_CODE_BASE == RTL8192 && DEV_BUS_TYPE == USB_INTERFACE) - /* - //Emily. If it is required to Ask Realtek AP to send AMPDU during AES mode, enable this - section of code. - if(IS_UNDER_11N_AES_MODE(Adapter)) - { - posRT2RTAgg->Octet[5] |=RT_HT_CAP_USE_AMPDU; - }else - { - posRT2RTAgg->Octet[5] &= 0xfb; - } - */ - -#else - // Do Nothing -#endif - - posRT2RTAgg->Length = 6; -#endif - - - - -} - - -/******************************************************************************************************************** - *function: Pick the right Rate Adaptive table to use - * input: struct ieee80211_device* ieee - * u8* pOperateMCS //A pointer to MCS rate bitmap - * return: always we return true - * notice: - * *****************************************************************************************************************/ -u8 HT_PickMCSRate(struct ieee80211_device* ieee, u8* pOperateMCS) -{ - u8 i; - if (pOperateMCS == NULL) - { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "pOperateMCS can't be null in HT_PickMCSRate()\n"); - return false; - } - - switch(ieee->mode) - { - case IEEE_A: - case IEEE_B: - case IEEE_G: - //legacy rate routine handled at selectedrate - - //no MCS rate - for(i=0;i<=15;i++){ - pOperateMCS[i] = 0; - } - break; - - case IEEE_N_24G: //assume CCK rate ok - case IEEE_N_5G: - // Legacy part we only use 6, 5.5,2,1 for N_24G and 6 for N_5G. - // Legacy part shall be handled at SelectRateSet(). - - //HT part - // TODO: may be different if we have different number of antenna - pOperateMCS[0] &=RATE_ADPT_1SS_MASK; //support MCS 0~7 - pOperateMCS[1] &=RATE_ADPT_2SS_MASK; - pOperateMCS[3] &=RATE_ADPT_MCS32_MASK; - break; - - //should never reach here - default: - - break; - - } - - return true; -} - -/* -* Description: -* This function will get the highest speed rate in input MCS set. -* -* /param Adapter Pionter to Adapter entity -* pMCSRateSet Pointer to MCS rate bitmap -* pMCSFilter Pointer to MCS rate filter -* -* /return Highest MCS rate included in pMCSRateSet and filtered by pMCSFilter. -* -*/ -/******************************************************************************************************************** - *function: This function will get the highest speed rate in input MCS set. - * input: struct ieee80211_device* ieee - * u8* pMCSRateSet //Pointer to MCS rate bitmap - * u8* pMCSFilter //Pointer to MCS rate filter - * return: Highest MCS rate included in pMCSRateSet and filtered by pMCSFilter - * notice: - * *****************************************************************************************************************/ -u8 HTGetHighestMCSRate(struct ieee80211_device* ieee, u8* pMCSRateSet, u8* pMCSFilter) -{ - u8 i, j; - u8 bitMap; - u8 mcsRate = 0; - u8 availableMcsRate[16]; - if (pMCSRateSet == NULL || pMCSFilter == NULL) - { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "pMCSRateSet or pMCSFilter can't be null in HTGetHighestMCSRate()\n"); - return false; - } - for(i=0; i<16; i++) - availableMcsRate[i] = pMCSRateSet[i] & pMCSFilter[i]; - - for(i = 0; i < 16; i++) - { - if(availableMcsRate[i] != 0) - break; - } - if(i == 16) - return false; - - for(i = 0; i < 16; i++) - { - if(availableMcsRate[i] != 0) - { - bitMap = availableMcsRate[i]; - for(j = 0; j < 8; j++) - { - if((bitMap%2) != 0) - { - if(HTMcsToDataRate(ieee, (8*i+j)) > HTMcsToDataRate(ieee, mcsRate)) - mcsRate = (8*i+j); - } - bitMap = bitMap>>1; - } - } - } - return (mcsRate|0x80); -} - - - -/* -** -**1.Filter our operation rate set with AP's rate set -**2.shall reference channel bandwidth, STBC, Antenna number -**3.generate rate adative table for firmware -**David 20060906 -** -** \pHTSupportedCap: the connected STA's supported rate Capability element -*/ -u8 HTFilterMCSRate( struct ieee80211_device* ieee, u8* pSupportMCS, u8* pOperateMCS) -{ - - u8 i=0; - - // filter out operational rate set not supported by AP, the lenth of it is 16 - for(i=0;i<=15;i++){ - pOperateMCS[i] = ieee->Regdot11HTOperationalRateSet[i]&pSupportMCS[i]; - } - - - // TODO: adjust our operational rate set according to our channel bandwidth, STBC and Antenna number - - // TODO: fill suggested rate adaptive rate index and give firmware info using Tx command packet - // we also shall suggested the first start rate set according to our singal strength - HT_PickMCSRate(ieee, pOperateMCS); - - // For RTL819X, if pairwisekey = wep/tkip, we support only MCS0~7. - if (ieee->GetHalfNmodeSupportByAPsHandler(ieee)) - pOperateMCS[1] = 0; - - // - // For RTL819X, we support only MCS0~15. - // And also, we do not know how to use MCS32 now. - // - for(i=2; i<=15; i++) - pOperateMCS[i] = 0; - - return true; -} -void HTSetConnectBwMode(struct ieee80211_device* ieee, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset); -void HTOnAssocRsp(struct ieee80211_device *ieee) -{ - PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; - PHT_CAPABILITY_ELE pPeerHTCap = NULL; - PHT_INFORMATION_ELE pPeerHTInfo = NULL; - u16 nMaxAMSDUSize = 0; - u8* pMcsFilter = NULL; - - static u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; // For 11n EWC definition, 2007.07.17, by Emily - static u8 EWC11NHTInfo[] = {0x00, 0x90, 0x4c, 0x34}; // For 11n EWC definition, 2007.07.17, by Emily - - if( pHTInfo->bCurrentHTSupport == false ) - { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "<=== HTOnAssocRsp(): HT_DISABLE\n"); - return; - } - IEEE80211_DEBUG(IEEE80211_DL_HT, "===> HTOnAssocRsp_wq(): HT_ENABLE\n"); -// IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, pHTInfo->PeerHTCapBuf, sizeof(HT_CAPABILITY_ELE)); -// IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA, pHTInfo->PeerHTInfoBuf, sizeof(HT_INFORMATION_ELE)); - -// HTDebugHTCapability(pHTInfo->PeerHTCapBuf,"HTOnAssocRsp_wq"); -// HTDebugHTInfo(pHTInfo->PeerHTInfoBuf,"HTOnAssocRsp_wq"); - // - if(!memcmp(pHTInfo->PeerHTCapBuf,EWC11NHTCap, sizeof(EWC11NHTCap))) - pPeerHTCap = (PHT_CAPABILITY_ELE)(&pHTInfo->PeerHTCapBuf[4]); - else - pPeerHTCap = (PHT_CAPABILITY_ELE)(pHTInfo->PeerHTCapBuf); - - if(!memcmp(pHTInfo->PeerHTInfoBuf, EWC11NHTInfo, sizeof(EWC11NHTInfo))) - pPeerHTInfo = (PHT_INFORMATION_ELE)(&pHTInfo->PeerHTInfoBuf[4]); - else - pPeerHTInfo = (PHT_INFORMATION_ELE)(pHTInfo->PeerHTInfoBuf); - - - //////////////////////////////////////////////////////// - // Configurations: - //////////////////////////////////////////////////////// - IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_HT, pPeerHTCap, sizeof(HT_CAPABILITY_ELE)); -// IEEE80211_DEBUG_DATA(IEEE80211_DL_DATA|IEEE80211_DL_HT, pPeerHTInfo, sizeof(HT_INFORMATION_ELE)); - // Config Supported Channel Width setting - // - HTSetConnectBwMode(ieee, (HT_CHANNEL_WIDTH)(pPeerHTCap->ChlWidth), (HT_EXTCHNL_OFFSET)(pPeerHTInfo->ExtChlOffset)); - -// if(pHTInfo->bCurBW40MHz == true) - pHTInfo->bCurTxBW40MHz = ((pPeerHTInfo->RecommemdedTxWidth == 1)?true:false); - - // - // Update short GI/ long GI setting - // - // TODO: - pHTInfo->bCurShortGI20MHz= - ((pHTInfo->bRegShortGI20MHz)?((pPeerHTCap->ShortGI20Mhz==1)?true:false):false); - pHTInfo->bCurShortGI40MHz= - ((pHTInfo->bRegShortGI40MHz)?((pPeerHTCap->ShortGI40Mhz==1)?true:false):false); - - // - // Config TX STBC setting - // - // TODO: - - // - // Config DSSS/CCK mode in 40MHz mode - // - // TODO: - pHTInfo->bCurSuppCCK = - ((pHTInfo->bRegSuppCCK)?((pPeerHTCap->DssCCk==1)?true:false):false); - - - // - // Config and configure A-MSDU setting - // - pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support; - if (ieee->rtllib_ap_sec_type && - (ieee->rtllib_ap_sec_type(ieee)&(SEC_ALG_WEP|SEC_ALG_TKIP))){ - if( (pHTInfo->IOTPeer== HT_IOT_PEER_ATHEROS) || - (pHTInfo->IOTPeer == HT_IOT_PEER_UNKNOWN) ) - pHTInfo->bCurrentAMPDUEnable = false; - } - - - nMaxAMSDUSize = (pPeerHTCap->MaxAMSDUSize==0)?3839:7935; - - if(pHTInfo->nAMSDU_MaxSize > nMaxAMSDUSize ) - pHTInfo->nCurrent_AMSDU_MaxSize = nMaxAMSDUSize; - else - pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize; - - - // - // Config A-MPDU setting - // - pHTInfo->bCurrentAMPDUEnable = pHTInfo->bAMPDUEnable; - - // <1> Decide AMPDU Factor - - // By Emily - if(!pHTInfo->bRegRT2RTAggregation) - { - // Decide AMPDU Factor according to protocol handshake - if(pHTInfo->AMPDU_Factor > pPeerHTCap->MaxRxAMPDUFactor) - pHTInfo->CurrentAMPDUFactor = pPeerHTCap->MaxRxAMPDUFactor; - else - pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor; - - }else - { - // Set MPDU density to 2 to Realtek AP, and set it to 0 for others - // Replace MPDU factor declared in original association response frame format. 2007.08.20 by Emily -#if 0 - osTmp= PacketGetElement( asocpdu, EID_Vendor, OUI_SUB_REALTEK_AGG, OUI_SUBTYPE_DONT_CARE); - if(osTmp.Length >= 5) //00:e0:4c:02:00 -#endif - if (ieee->current_network.bssht.bdRT2RTAggregation) - { - if( ieee->pairwise_key_type != KEY_TYPE_NA) - // Realtek may set 32k in security mode and 64k for others - pHTInfo->CurrentAMPDUFactor = pPeerHTCap->MaxRxAMPDUFactor; - else - pHTInfo->CurrentAMPDUFactor = HT_AGG_SIZE_64K; - }else - { - if(pPeerHTCap->MaxRxAMPDUFactor < HT_AGG_SIZE_32K) - pHTInfo->CurrentAMPDUFactor = pPeerHTCap->MaxRxAMPDUFactor; - else - pHTInfo->CurrentAMPDUFactor = HT_AGG_SIZE_32K; - } - } - - // <2> Set AMPDU Minimum MPDU Start Spacing - // 802.11n 3.0 section 9.7d.3 -#if 1 - if(pHTInfo->MPDU_Density > pPeerHTCap->MPDUDensity) - pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density; - else - pHTInfo->CurrentMPDUDensity = pPeerHTCap->MPDUDensity; - if(ieee->pairwise_key_type != KEY_TYPE_NA ) - pHTInfo->CurrentMPDUDensity = 7; // 8us -#else - if(pHTInfo->MPDU_Density > pPeerHTCap->MPDUDensity) - pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density; - else - pHTInfo->CurrentMPDUDensity = pPeerHTCap->MPDUDensity; -#endif - // Force TX AMSDU - - // Lanhsin: mark for tmp to avoid deauth by ap from s3 - //if(memcmp(pMgntInfo->Bssid, NETGEAR834Bv2_BROADCOM, 3)==0) - if(0) - { - - pHTInfo->bCurrentAMPDUEnable = false; - pHTInfo->ForcedAMSDUMode = HT_AGG_FORCE_ENABLE; - pHTInfo->ForcedAMSDUMaxSize = 7935; - - pHTInfo->IOTAction |= HT_IOT_ACT_TX_USE_AMSDU_8K; - } - - // Rx Reorder Setting - pHTInfo->bCurRxReorderEnable = pHTInfo->bRegRxReorderEnable; - - // - // Filter out unsupported HT rate for this AP - // Update RATR table - // This is only for 8190 ,8192 or later product which using firmware to handle rate adaptive mechanism. - // - - // Handle Ralink AP bad MCS rate set condition. Joseph. - // This fix the bug of Ralink AP. This may be removed in the future. - if(pPeerHTCap->MCS[0] == 0) - pPeerHTCap->MCS[0] = 0xff; - - HTFilterMCSRate(ieee, pPeerHTCap->MCS, ieee->dot11HTOperationalRateSet); - - // - // Config MIMO Power Save setting - // - pHTInfo->PeerMimoPs = pPeerHTCap->MimoPwrSave; - if(pHTInfo->PeerMimoPs == MIMO_PS_STATIC) - pMcsFilter = MCS_FILTER_1SS; - else - pMcsFilter = MCS_FILTER_ALL; - //WB add for MCS8 bug -// pMcsFilter = MCS_FILTER_1SS; - ieee->HTHighestOperaRate = HTGetHighestMCSRate(ieee, ieee->dot11HTOperationalRateSet, pMcsFilter); - ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate; - - // - // Config current operation mode. - // - pHTInfo->CurrentOpMode = pPeerHTInfo->OptMode; - - - -} - -void HTSetConnectBwModeCallback(struct ieee80211_device* ieee); -/******************************************************************************************************************** - *function: initialize HT info(struct PRT_HIGH_THROUGHPUT) - * input: struct ieee80211_device* ieee - * output: none - * return: none - * notice: This function is called when * (1) MPInitialization Phase * (2) Receiving of Deauthentication from AP -********************************************************************************************************************/ -// TODO: Should this funciton be called when receiving of Disassociation? -void HTInitializeHTInfo(struct ieee80211_device* ieee) -{ - PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; - - // - // These parameters will be reset when receiving deauthentication packet - // - IEEE80211_DEBUG(IEEE80211_DL_HT, "===========>%s()\n", __FUNCTION__); - pHTInfo->bCurrentHTSupport = false; - - // 40MHz channel support - pHTInfo->bCurBW40MHz = false; - pHTInfo->bCurTxBW40MHz = false; - - // Short GI support - pHTInfo->bCurShortGI20MHz = false; - pHTInfo->bCurShortGI40MHz = false; - pHTInfo->bForcedShortGI = false; - - // CCK rate support - // This flag is set to true to support CCK rate by default. - // It will be affected by "pHTInfo->bRegSuppCCK" and AP capabilities only when associate to - // 11N BSS. - pHTInfo->bCurSuppCCK = true; - - // AMSDU related - pHTInfo->bCurrent_AMSDU_Support = false; - pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize; - - // AMPUD related - pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density; - pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor; - - - - // Initialize all of the parameters related to 11n - memset((void*)(&(pHTInfo->SelfHTCap)), 0, sizeof(pHTInfo->SelfHTCap)); - memset((void*)(&(pHTInfo->SelfHTInfo)), 0, sizeof(pHTInfo->SelfHTInfo)); - memset((void*)(&(pHTInfo->PeerHTCapBuf)), 0, sizeof(pHTInfo->PeerHTCapBuf)); - memset((void*)(&(pHTInfo->PeerHTInfoBuf)), 0, sizeof(pHTInfo->PeerHTInfoBuf)); - - pHTInfo->bSwBwInProgress = false; - pHTInfo->ChnlOp = CHNLOP_NONE; - - // Set default IEEE spec for Draft N - pHTInfo->ePeerHTSpecVer = HT_SPEC_VER_IEEE; - - // Realtek proprietary aggregation mode - pHTInfo->bCurrentRT2RTAggregation = false; - pHTInfo->bCurrentRT2RTLongSlotTime = false; - pHTInfo->IOTPeer = 0; - pHTInfo->IOTAction = 0; - - //MCS rate initialized here - { - u8* RegHTSuppRateSets = &(ieee->RegHTSuppRateSet[0]); - RegHTSuppRateSets[0] = 0xFF; //support MCS 0~7 - RegHTSuppRateSets[1] = 0xFF; //support MCS 8~15 - RegHTSuppRateSets[4] = 0x01; //support MCS 32 - } -} -/******************************************************************************************************************** - *function: initialize Bss HT structure(struct PBSS_HT) - * input: PBSS_HT pBssHT //to be initialized - * output: none - * return: none - * notice: This function is called when initialize network structure -********************************************************************************************************************/ -void HTInitializeBssDesc(PBSS_HT pBssHT) -{ - - pBssHT->bdSupportHT = false; - memset(pBssHT->bdHTCapBuf, 0, sizeof(pBssHT->bdHTCapBuf)); - pBssHT->bdHTCapLen = 0; - memset(pBssHT->bdHTInfoBuf, 0, sizeof(pBssHT->bdHTInfoBuf)); - pBssHT->bdHTInfoLen = 0; - - pBssHT->bdHTSpecVer= HT_SPEC_VER_IEEE; - - pBssHT->bdRT2RTAggregation = false; - pBssHT->bdRT2RTLongSlotTime = false; -} -#if 0 -//below function has merged into ieee80211_network_init() in ieee80211_rx.c -void -HTParsingHTCapElement( - IN PADAPTER Adapter, - IN OCTET_STRING HTCapIE, - OUT PRT_WLAN_BSS pBssDesc -) -{ - PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; - - if( HTCapIE.Length > sizeof(pBssDesc->BssHT.bdHTCapBuf) ) - { - RT_TRACE( COMP_HT, DBG_LOUD, ("HTParsingHTCapElement(): HT Capability Element length is too long!\n") ); - return; - } - - // TODO: Check the correctness of HT Cap - //Print each field in detail. Driver should not print out this message by default - if(!pMgntInfo->mActingAsAp && !pMgntInfo->mAssoc) - HTDebugHTCapability(DBG_TRACE, Adapter, &HTCapIE, (pu8)"HTParsingHTCapElement()"); - - HTCapIE.Length = HTCapIE.Length > sizeof(pBssDesc->BssHT.bdHTCapBuf)?\ - sizeof(pBssDesc->BssHT.bdHTCapBuf):HTCapIE.Length; //prevent from overflow - - CopyMem(pBssDesc->BssHT.bdHTCapBuf, HTCapIE.Octet, HTCapIE.Length); - pBssDesc->BssHT.bdHTCapLen = HTCapIE.Length; - -} - - -void -HTParsingHTInfoElement( - PADAPTER Adapter, - OCTET_STRING HTInfoIE, - PRT_WLAN_BSS pBssDesc -) -{ - PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; - - if( HTInfoIE.Length > sizeof(pBssDesc->BssHT.bdHTInfoBuf)) - { - RT_TRACE( COMP_HT, DBG_LOUD, ("HTParsingHTInfoElement(): HT Information Element length is too long!\n") ); - return; - } - - // TODO: Check the correctness of HT Info - //Print each field in detail. Driver should not print out this message by default - if(!pMgntInfo->mActingAsAp && !pMgntInfo->mAssoc) - HTDebugHTInfo(DBG_TRACE, Adapter, &HTInfoIE, (pu8)"HTParsingHTInfoElement()"); - - HTInfoIE.Length = HTInfoIE.Length > sizeof(pBssDesc->BssHT.bdHTInfoBuf)?\ - sizeof(pBssDesc->BssHT.bdHTInfoBuf):HTInfoIE.Length; //prevent from overflow - - CopyMem( pBssDesc->BssHT.bdHTInfoBuf, HTInfoIE.Octet, HTInfoIE.Length); - pBssDesc->BssHT.bdHTInfoLen = HTInfoIE.Length; -} - -/* - * Get HT related information from beacon and save it in BssDesc - * - * (1) Parse HTCap, and HTInfo, and record whether it is 11n AP - * (2) If peer is HT, but not WMM, call QosSetLegacyWMMParamWithHT() - * (3) Check whether peer is Realtek AP (for Realtek proprietary aggregation mode). - * Input: - * PADAPTER Adapter - * - * Output: - * PRT_TCB BssDesc - * -*/ -void HTGetValueFromBeaconOrProbeRsp( - PADAPTER Adapter, - POCTET_STRING pSRCmmpdu, - PRT_WLAN_BSS bssDesc -) -{ - PMGNT_INFO pMgntInfo = &Adapter->MgntInfo; - PRT_HIGH_THROUGHPUT pHTInfo = GET_HT_INFO(pMgntInfo); - OCTET_STRING HTCapIE, HTInfoIE, HTRealtekAgg, mmpdu; - OCTET_STRING BroadcomElement, CiscoElement; - - mmpdu.Octet = pSRCmmpdu->Octet; - mmpdu.Length = pSRCmmpdu->Length; - - //2Note: - // Mark for IOT testing using Linksys WRT350N, This AP does not contain WMM IE when - // it is configured at pure-N mode. - // if(bssDesc->BssQos.bdQoSMode & QOS_WMM) - // - - HTInitializeBssDesc (&bssDesc->BssHT); - - //2<1> Parse HTCap, and HTInfo - // Get HT Capability IE: (1) Get IEEE Draft N IE or (2) Get EWC IE - HTCapIE = PacketGetElement(mmpdu, EID_HTCapability, OUI_SUB_DONT_CARE, OUI_SUBTYPE_DONT_CARE); - if(HTCapIE.Length == 0) - { - HTCapIE = PacketGetElement(mmpdu, EID_Vendor, OUI_SUB_11N_EWC_HT_CAP, OUI_SUBTYPE_DONT_CARE); - if(HTCapIE.Length != 0) - bssDesc->BssHT.bdHTSpecVer= HT_SPEC_VER_EWC; - } - if(HTCapIE.Length != 0) - HTParsingHTCapElement(Adapter, HTCapIE, bssDesc); - - // Get HT Information IE: (1) Get IEEE Draft N IE or (2) Get EWC IE - HTInfoIE = PacketGetElement(mmpdu, EID_HTInfo, OUI_SUB_DONT_CARE, OUI_SUBTYPE_DONT_CARE); - if(HTInfoIE.Length == 0) - { - HTInfoIE = PacketGetElement(mmpdu, EID_Vendor, OUI_SUB_11N_EWC_HT_INFO, OUI_SUBTYPE_DONT_CARE); - if(HTInfoIE.Length != 0) - bssDesc->BssHT.bdHTSpecVer = HT_SPEC_VER_EWC; - } - if(HTInfoIE.Length != 0) - HTParsingHTInfoElement(Adapter, HTInfoIE, bssDesc); - - //2<2>If peer is HT, but not WMM, call QosSetLegacyWMMParamWithHT() - if(HTCapIE.Length != 0) - { - bssDesc->BssHT.bdSupportHT = true; - if(bssDesc->BssQos.bdQoSMode == QOS_DISABLE) - QosSetLegacyWMMParamWithHT(Adapter, bssDesc); - } - else - { - bssDesc->BssHT.bdSupportHT = false; - } - - //2<3>Check whether the peer is Realtek AP/STA - if(pHTInfo->bRegRT2RTAggregation) - { - if(bssDesc->BssHT.bdSupportHT) - { - HTRealtekAgg = PacketGetElement(mmpdu, EID_Vendor, OUI_SUB_REALTEK_AGG, OUI_SUBTYPE_DONT_CARE); - if(HTRealtekAgg.Length >=5 ) - { - bssDesc->BssHT.bdRT2RTAggregation = true; - - if((HTRealtekAgg.Octet[4]==1) && (HTRealtekAgg.Octet[5] & 0x02)) - bssDesc->BssHT.bdRT2RTLongSlotTime = true; - } - } - } - - // - // 2008/01/25 MH Get Broadcom AP IE for manamgent frame CCK rate problem. - // AP can not receive CCK managemtn from from 92E. - // - - // Initialize every new bss broadcom cap exist as false.. - bssDesc->bBroadcomCapExist= false; - - if(HTCapIE.Length != 0 || HTInfoIE.Length != 0) - { - u4Byte Length = 0; - - FillOctetString(BroadcomElement, NULL, 0); - - BroadcomElement = PacketGetElement( mmpdu, EID_Vendor, OUI_SUB_BROADCOM_IE_1, OUI_SUBTYPE_DONT_CARE); - Length += BroadcomElement.Length; - BroadcomElement = PacketGetElement( mmpdu, EID_Vendor, OUI_SUB_BROADCOM_IE_2, OUI_SUBTYPE_DONT_CARE); - Length += BroadcomElement.Length; - BroadcomElement = PacketGetElement( mmpdu, EID_Vendor, OUI_SUB_BROADCOM_IE_3, OUI_SUBTYPE_DONT_CARE); - Length += BroadcomElement.Length; - - if(Length > 0) - bssDesc->bBroadcomCapExist = true; - } - - - // For Cisco IOT issue - CiscoElement = PacketGetElement( mmpdu, EID_Vendor, OUI_SUB_CISCO_IE, OUI_SUBTYPE_DONT_CARE); - if(CiscoElement.Length != 0){ // 3: 0x00, 0x40, 0x96 .... - bssDesc->bCiscoCapExist = true; - }else{ - bssDesc->bCiscoCapExist = false; - } -} - - -#endif -/******************************************************************************************************************** - *function: initialize Bss HT structure(struct PBSS_HT) - * input: struct ieee80211_device *ieee - * struct ieee80211_network *pNetwork //usually current network we are live in - * output: none - * return: none - * notice: This function should ONLY be called before association -********************************************************************************************************************/ -void HTResetSelfAndSavePeerSetting(struct ieee80211_device* ieee, struct ieee80211_network * pNetwork) -{ - PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; -// u16 nMaxAMSDUSize; -// PHT_CAPABILITY_ELE pPeerHTCap = (PHT_CAPABILITY_ELE)pNetwork->bssht.bdHTCapBuf; -// PHT_INFORMATION_ELE pPeerHTInfo = (PHT_INFORMATION_ELE)pNetwork->bssht.bdHTInfoBuf; -// u8* pMcsFilter; - u8 bIOTAction = 0; - - // - // Save Peer Setting before Association - // - IEEE80211_DEBUG(IEEE80211_DL_HT, "==============>%s()\n", __FUNCTION__); - /*unmark bEnableHT flag here is the same reason why unmarked in function ieee80211_softmac_new_net. WB 2008.09.10*/ -// if( pHTInfo->bEnableHT && pNetwork->bssht.bdSupportHT) - if (pNetwork->bssht.bdSupportHT) - { - pHTInfo->bCurrentHTSupport = true; - pHTInfo->ePeerHTSpecVer = pNetwork->bssht.bdHTSpecVer; - - // Save HTCap and HTInfo information Element - if(pNetwork->bssht.bdHTCapLen > 0 && pNetwork->bssht.bdHTCapLen <= sizeof(pHTInfo->PeerHTCapBuf)) - memcpy(pHTInfo->PeerHTCapBuf, pNetwork->bssht.bdHTCapBuf, pNetwork->bssht.bdHTCapLen); - - if(pNetwork->bssht.bdHTInfoLen > 0 && pNetwork->bssht.bdHTInfoLen <= sizeof(pHTInfo->PeerHTInfoBuf)) - memcpy(pHTInfo->PeerHTInfoBuf, pNetwork->bssht.bdHTInfoBuf, pNetwork->bssht.bdHTInfoLen); - - // Check whether RT to RT aggregation mode is enabled - if(pHTInfo->bRegRT2RTAggregation) - { - pHTInfo->bCurrentRT2RTAggregation = pNetwork->bssht.bdRT2RTAggregation; - pHTInfo->bCurrentRT2RTLongSlotTime = pNetwork->bssht.bdRT2RTLongSlotTime; - } - else - { - pHTInfo->bCurrentRT2RTAggregation = false; - pHTInfo->bCurrentRT2RTLongSlotTime = false; - } - - // Determine the IOT Peer Vendor. - HTIOTPeerDetermine(ieee); - - // Decide IOT Action - // Must be called after the parameter of pHTInfo->bCurrentRT2RTAggregation is decided - pHTInfo->IOTAction = 0; - bIOTAction = HTIOTActIsDisableMCS14(ieee, pNetwork->bssid); - if(bIOTAction) - pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_MCS14; - bIOTAction = HTIOTActIsForcedCTS2Self(ieee, pNetwork); - if(bIOTAction) - pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF; - - bIOTAction = HTIOTActIsDisableMCS15(ieee); - if(bIOTAction) - pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_MCS15; - - bIOTAction = HTIOTActIsDisableMCSTwoSpatialStream(ieee, pNetwork->bssid); - if(bIOTAction) - pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_ALL_2SS; - - - bIOTAction = HTIOTActIsDisableEDCATurbo(ieee, pNetwork->bssid); - if(bIOTAction) - pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_EDCA_TURBO; - - bIOTAction = HTIOTActIsMgntUseCCK6M(pNetwork); - if(bIOTAction) - pHTInfo->IOTAction |= HT_IOT_ACT_MGNT_USE_CCK_6M; - - bIOTAction = HTIOTActIsCCDFsync(pNetwork->bssid); - if(bIOTAction) - pHTInfo->IOTAction |= HT_IOT_ACT_CDD_FSYNC; - - bIOTAction = HTIOTActIsNullDataPowerSaving(ieee, pNetwork); - if(bIOTAction) - pHTInfo->IOTAction |= HT_IOT_ACT_NULL_DATA_POWER_SAVING; - - } - else - { - pHTInfo->bCurrentHTSupport = false; - pHTInfo->bCurrentRT2RTAggregation = false; - pHTInfo->bCurrentRT2RTLongSlotTime = false; - - pHTInfo->IOTAction = 0; - } - -} - -void HTUpdateSelfAndPeerSetting(struct ieee80211_device* ieee, struct ieee80211_network * pNetwork) -{ - PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; -// PHT_CAPABILITY_ELE pPeerHTCap = (PHT_CAPABILITY_ELE)pNetwork->bssht.bdHTCapBuf; - PHT_INFORMATION_ELE pPeerHTInfo = (PHT_INFORMATION_ELE)pNetwork->bssht.bdHTInfoBuf; - - if(pHTInfo->bCurrentHTSupport) - { - // - // Config current operation mode. - // - if(pNetwork->bssht.bdHTInfoLen != 0) - pHTInfo->CurrentOpMode = pPeerHTInfo->OptMode; - - // - // <TODO: Config according to OBSS non-HT STA present!!> - // - } -} - -void HTUseDefaultSetting(struct ieee80211_device* ieee) -{ - PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; -// u8 regBwOpMode; - - if(pHTInfo->bEnableHT) - { - pHTInfo->bCurrentHTSupport = true; - - pHTInfo->bCurSuppCCK = pHTInfo->bRegSuppCCK; - - pHTInfo->bCurBW40MHz = pHTInfo->bRegBW40MHz; - - pHTInfo->bCurShortGI20MHz= pHTInfo->bRegShortGI20MHz; - - pHTInfo->bCurShortGI40MHz= pHTInfo->bRegShortGI40MHz; - - pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support; - - pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize; - - pHTInfo->bCurrentAMPDUEnable = pHTInfo->bAMPDUEnable; - - pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor; - - pHTInfo->CurrentMPDUDensity = pHTInfo->CurrentMPDUDensity; - - // Set BWOpMode register - - //update RATR index0 - HTFilterMCSRate(ieee, ieee->Regdot11HTOperationalRateSet, ieee->dot11HTOperationalRateSet); - //function below is not implemented at all. WB -#ifdef TODO - Adapter->HalFunc.InitHalRATRTableHandler( Adapter, &pMgntInfo->dot11OperationalRateSet, pMgntInfo->dot11HTOperationalRateSet); -#endif - ieee->HTHighestOperaRate = HTGetHighestMCSRate(ieee, ieee->dot11HTOperationalRateSet, MCS_FILTER_ALL); - ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate; - - } - else - { - pHTInfo->bCurrentHTSupport = false; - } -} -/******************************************************************************************************************** - *function: check whether HT control field exists - * input: struct ieee80211_device *ieee - * u8* pFrame //coming skb->data - * output: none - * return: return true if HT control field exists(false otherwise) - * notice: -********************************************************************************************************************/ -u8 HTCCheck(struct ieee80211_device* ieee, u8* pFrame) -{ - if(ieee->pHTInfo->bCurrentHTSupport) - { - if( (IsQoSDataFrame(pFrame) && Frame_Order(pFrame)) == 1) - { - IEEE80211_DEBUG(IEEE80211_DL_HT, "HT CONTROL FILED EXIST!!\n"); - return true; - } - } - return false; -} - -// -// This function set bandwidth mode in protocol layer. -// -void HTSetConnectBwMode(struct ieee80211_device* ieee, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset) -{ - PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; -// u32 flags = 0; - - if(pHTInfo->bRegBW40MHz == false) - return; - - - - // To reduce dummy operation -// if((pHTInfo->bCurBW40MHz==false && Bandwidth==HT_CHANNEL_WIDTH_20) || -// (pHTInfo->bCurBW40MHz==true && Bandwidth==HT_CHANNEL_WIDTH_20_40 && Offset==pHTInfo->CurSTAExtChnlOffset)) -// return; - -// spin_lock_irqsave(&(ieee->bw_spinlock), flags); - if(pHTInfo->bSwBwInProgress) { -// spin_unlock_irqrestore(&(ieee->bw_spinlock), flags); - return; - } - //if in half N mode, set to 20M bandwidth please 09.08.2008 WB. - if (Bandwidth==HT_CHANNEL_WIDTH_20_40 && (!ieee->GetHalfNmodeSupportByAPsHandler(ieee))) - { - // Handle Illegal extension channel offset!! - if(ieee->current_network.channel<2 && Offset==HT_EXTCHNL_OFFSET_LOWER) - Offset = HT_EXTCHNL_OFFSET_NO_EXT; - if(Offset==HT_EXTCHNL_OFFSET_UPPER || Offset==HT_EXTCHNL_OFFSET_LOWER) { - pHTInfo->bCurBW40MHz = true; - pHTInfo->CurSTAExtChnlOffset = Offset; - } else { - pHTInfo->bCurBW40MHz = false; - pHTInfo->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT; - } - } else { - pHTInfo->bCurBW40MHz = false; - pHTInfo->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT; - } - - pHTInfo->bSwBwInProgress = true; - - // TODO: 2007.7.13 by Emily Wait 2000ms in order to guarantee that switching - // bandwidth is executed after scan is finished. It is a temporal solution - // because software should ganrantee the last operation of switching bandwidth - // is executed properlly. - HTSetConnectBwModeCallback(ieee); - -// spin_unlock_irqrestore(&(ieee->bw_spinlock), flags); -} - -void HTSetConnectBwModeCallback(struct ieee80211_device* ieee) -{ - PRT_HIGH_THROUGHPUT pHTInfo = ieee->pHTInfo; - - IEEE80211_DEBUG(IEEE80211_DL_HT, "======>%s()\n", __FUNCTION__); - - if(pHTInfo->bCurBW40MHz) - { - if(pHTInfo->CurSTAExtChnlOffset==HT_EXTCHNL_OFFSET_UPPER) - ieee->set_chan(ieee, ieee->current_network.channel+2); - else if(pHTInfo->CurSTAExtChnlOffset==HT_EXTCHNL_OFFSET_LOWER) - ieee->set_chan(ieee, ieee->current_network.channel-2); - else - ieee->set_chan(ieee, ieee->current_network.channel); - - ieee->SetBWModeHandler(ieee, HT_CHANNEL_WIDTH_20_40, pHTInfo->CurSTAExtChnlOffset); - } else { - ieee->set_chan(ieee, ieee->current_network.channel); - ieee->SetBWModeHandler(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); - } - - pHTInfo->bSwBwInProgress = false; -} diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_Qos.h b/drivers/staging/rtl8192e/ieee80211/rtl819x_Qos.h deleted file mode 100644 index d4565ec..0000000 --- a/drivers/staging/rtl8192e/ieee80211/rtl819x_Qos.h +++ /dev/null @@ -1,582 +0,0 @@ -#ifndef __INC_QOS_TYPE_H -#define __INC_QOS_TYPE_H - -#define BIT0 0x00000001 -#define BIT1 0x00000002 -#define BIT2 0x00000004 -#define BIT3 0x00000008 -#define BIT4 0x00000010 -#define BIT5 0x00000020 -#define BIT6 0x00000040 -#define BIT7 0x00000080 -#define BIT8 0x00000100 -#define BIT9 0x00000200 -#define BIT10 0x00000400 -#define BIT11 0x00000800 -#define BIT12 0x00001000 -#define BIT13 0x00002000 -#define BIT14 0x00004000 -#define BIT15 0x00008000 -#define BIT16 0x00010000 -#define BIT17 0x00020000 -#define BIT18 0x00040000 -#define BIT19 0x00080000 -#define BIT20 0x00100000 -#define BIT21 0x00200000 -#define BIT22 0x00400000 -#define BIT23 0x00800000 -#define BIT24 0x01000000 -#define BIT25 0x02000000 -#define BIT26 0x04000000 -#define BIT27 0x08000000 -#define BIT28 0x10000000 -#define BIT29 0x20000000 -#define BIT30 0x40000000 -#define BIT31 0x80000000 - -#define MAX_WMMELE_LENGTH 64 - -// -// QoS mode. -// enum 0, 1, 2, 4: since we can use the OR(|) operation. -// -// QOS_MODE is redefined for enum can't be ++, | under C++ compiler, 2006.05.17, by rcnjko. -//typedef enum _QOS_MODE{ -// QOS_DISABLE = 0, -// QOS_WMM = 1, -// QOS_EDCA = 2, -// QOS_HCCA = 4, -//}QOS_MODE,*PQOS_MODE; -// -typedef u32 QOS_MODE, *PQOS_MODE; -#define QOS_DISABLE 0 -#define QOS_WMM 1 -#define QOS_WMMSA 2 -#define QOS_EDCA 4 -#define QOS_HCCA 8 -#define QOS_WMM_UAPSD 16 //WMM Power Save, 2006-06-14 Isaiah - -#define AC_PARAM_SIZE 4 -#define WMM_PARAM_ELE_BODY_LEN 18 - -// -// QoS ACK Policy Field Values -// Ref: WMM spec 2.1.6: QoS Control Field, p.10. -// -typedef enum _ACK_POLICY{ - eAckPlc0_ACK = 0x00, - eAckPlc1_NoACK = 0x01, -}ACK_POLICY,*PACK_POLICY; - -#define WMM_PARAM_ELEMENT_SIZE (8+(4*AC_PARAM_SIZE)) - -// -// QoS Control Field -// Ref: -// 1. WMM spec 2.1.6: QoS Control Field, p.9. -// 2. 802.11e/D13.0 7.1.3.5, p.26. -// -typedef union _QOS_CTRL_FIELD{ - u8 charData[2]; - u16 shortData; - - // WMM spec - struct - { - u8 UP:3; - u8 usRsvd1:1; - u8 EOSP:1; - u8 AckPolicy:2; - u8 usRsvd2:1; - u8 ucRsvdByte; - }WMM; - - // 802.11e: QoS data type frame sent by non-AP QSTAs. - struct - { - u8 TID:4; - u8 bIsQsize:1;// 0: BIT[8:15] is TXOP Duration Requested, 1: BIT[8:15] is Queue Size. - u8 AckPolicy:2; - u8 usRsvd:1; - u8 TxopOrQsize; // (BIT4=0)TXOP Duration Requested or (BIT4=1)Queue Size. - }BySta; - - // 802.11e: QoS data, QoS Null, and QoS Data+CF-Ack frames sent by HC. - struct - { - u8 TID:4; - u8 EOSP:1; - u8 AckPolicy:2; - u8 usRsvd:1; - u8 PSBufState; // QAP PS Buffer State. - }ByHc_Data; - - // 802.11e: QoS (+) CF-Poll frames sent by HC. - struct - { - u8 TID:4; - u8 EOSP:1; - u8 AckPolicy:2; - u8 usRsvd:1; - u8 TxopLimit; // TXOP Limit. - }ByHc_CFP; - -}QOS_CTRL_FIELD, *PQOS_CTRL_FIELD; - - -// -// QoS Info Field -// Ref: -// 1. WMM spec 2.2.1: WME Information Element, p.11. -// 2. 8185 QoS code: QOS_INFO [def. in QoS_mp.h] -// -typedef union _QOS_INFO_FIELD{ - u8 charData; - - struct - { - u8 ucParameterSetCount:4; - u8 ucReserved:4; - }WMM; - - struct - { - //Ref WMM_Specification_1-1.pdf, 2006-06-13 Isaiah - u8 ucAC_VO_UAPSD:1; - u8 ucAC_VI_UAPSD:1; - u8 ucAC_BE_UAPSD:1; - u8 ucAC_BK_UAPSD:1; - u8 ucReserved1:1; - u8 ucMaxSPLen:2; - u8 ucReserved2:1; - - }ByWmmPsSta; - - struct - { - //Ref WMM_Specification_1-1.pdf, 2006-06-13 Isaiah - u8 ucParameterSetCount:4; - u8 ucReserved:3; - u8 ucApUapsd:1; - }ByWmmPsAp; - - struct - { - u8 ucAC3_UAPSD:1; - u8 ucAC2_UAPSD:1; - u8 ucAC1_UAPSD:1; - u8 ucAC0_UAPSD:1; - u8 ucQAck:1; - u8 ucMaxSPLen:2; - u8 ucMoreDataAck:1; - } By11eSta; - - struct - { - u8 ucParameterSetCount:4; - u8 ucQAck:1; - u8 ucQueueReq:1; - u8 ucTXOPReq:1; - u8 ucReserved:1; - } By11eAp; - - struct - { - u8 ucReserved1:4; - u8 ucQAck:1; - u8 ucReserved2:2; - u8 ucMoreDataAck:1; - } ByWmmsaSta; - - struct - { - u8 ucReserved1:4; - u8 ucQAck:1; - u8 ucQueueReq:1; - u8 ucTXOPReq:1; - u8 ucReserved2:1; - } ByWmmsaAp; - - struct - { - u8 ucAC3_UAPSD:1; - u8 ucAC2_UAPSD:1; - u8 ucAC1_UAPSD:1; - u8 ucAC0_UAPSD:1; - u8 ucQAck:1; - u8 ucMaxSPLen:2; - u8 ucMoreDataAck:1; - } ByAllSta; - - struct - { - u8 ucParameterSetCount:4; - u8 ucQAck:1; - u8 ucQueueReq:1; - u8 ucTXOPReq:1; - u8 ucApUapsd:1; - } ByAllAp; - -}QOS_INFO_FIELD, *PQOS_INFO_FIELD; - -// -// ACI to AC coding. -// Ref: WMM spec 2.2.2: WME Parameter Element, p.13. -// -// AC_CODING is redefined for enum can't be ++, | under C++ compiler, 2006.05.17, by rcnjko. -//typedef enum _AC_CODING{ -// AC0_BE = 0, // ACI: 0x00 // Best Effort -// AC1_BK = 1, // ACI: 0x01 // Background -// AC2_VI = 2, // ACI: 0x10 // Video -// AC3_VO = 3, // ACI: 0x11 // Voice -// AC_MAX = 4, // Max: define total number; Should not to be used as a real enum. -//}AC_CODING,*PAC_CODING; -// -typedef u32 AC_CODING; -#define AC0_BE 0 // ACI: 0x00 // Best Effort -#define AC1_BK 1 // ACI: 0x01 // Background -#define AC2_VI 2 // ACI: 0x10 // Video -#define AC3_VO 3 // ACI: 0x11 // Voice -#define AC_MAX 4 // Max: define total number; Should not to be used as a real enum. - -// -// ACI/AIFSN Field. -// Ref: WMM spec 2.2.2: WME Parameter Element, p.12. -// -typedef union _ACI_AIFSN{ - u8 charData; - - struct - { - u8 AIFSN:4; - u8 ACM:1; - u8 ACI:2; - u8 Reserved:1; - }f; // Field -}ACI_AIFSN, *PACI_AIFSN; - -// -// ECWmin/ECWmax field. -// Ref: WMM spec 2.2.2: WME Parameter Element, p.13. -// -typedef union _ECW{ - u8 charData; - struct - { - u8 ECWmin:4; - u8 ECWmax:4; - }f; // Field -}ECW, *PECW; - -// -// AC Parameters Record Format. -// Ref: WMM spec 2.2.2: WME Parameter Element, p.12. -// -typedef union _AC_PARAM{ - u32 longData; - u8 charData[4]; - - struct - { - ACI_AIFSN AciAifsn; - ECW Ecw; - u16 TXOPLimit; - }f; // Field -}AC_PARAM, *PAC_PARAM; - - - -// -// QoS element subtype -// -typedef enum _QOS_ELE_SUBTYPE{ - QOSELE_TYPE_INFO = 0x00, // 0x00: Information element - QOSELE_TYPE_PARAM = 0x01, // 0x01: parameter element -}QOS_ELE_SUBTYPE,*PQOS_ELE_SUBTYPE; - - -// -// Direction Field Values. -// Ref: WMM spec 2.2.11: WME TSPEC Element, p.18. -// -typedef enum _DIRECTION_VALUE{ - DIR_UP = 0, // 0x00 // UpLink - DIR_DOWN = 1, // 0x01 // DownLink - DIR_DIRECT = 2, // 0x10 // DirectLink - DIR_BI_DIR = 3, // 0x11 // Bi-Direction -}DIRECTION_VALUE,*PDIRECTION_VALUE; - - -// -// TS Info field in WMM TSPEC Element. -// Ref: -// 1. WMM spec 2.2.11: WME TSPEC Element, p.18. -// 2. 8185 QoS code: QOS_TSINFO [def. in QoS_mp.h] -// -typedef union _QOS_TSINFO{ - u8 charData[3]; - struct { - u8 ucTrafficType:1; //WMM is reserved - u8 ucTSID:4; - u8 ucDirection:2; - u8 ucAccessPolicy:2; //WMM: bit8=0, bit7=1 - u8 ucAggregation:1; //WMM is reserved - u8 ucPSB:1; //WMMSA is APSD - u8 ucUP:3; - u8 ucTSInfoAckPolicy:2; //WMM is reserved - u8 ucSchedule:1; //WMM is reserved - u8 ucReserved:7; - }field; -}QOS_TSINFO, *PQOS_TSINFO; - -// -// WMM TSPEC Body. -// Ref: WMM spec 2.2.11: WME TSPEC Element, p.16. -// -typedef union _TSPEC_BODY{ - u8 charData[55]; - - struct - { - QOS_TSINFO TSInfo; //u8 TSInfo[3]; - u16 NominalMSDUsize; - u16 MaxMSDUsize; - u32 MinServiceItv; - u32 MaxServiceItv; - u32 InactivityItv; - u32 SuspenItv; - u32 ServiceStartTime; - u32 MinDataRate; - u32 MeanDataRate; - u32 PeakDataRate; - u32 MaxBurstSize; - u32 DelayBound; - u32 MinPhyRate; - u16 SurplusBandwidthAllowance; - u16 MediumTime; - } f; // Field -}TSPEC_BODY, *PTSPEC_BODY; - - -// -// WMM TSPEC Element. -// Ref: WMM spec 2.2.11: WME TSPEC Element, p.16. -// -typedef struct _WMM_TSPEC{ - u8 ID; - u8 Length; - u8 OUI[3]; - u8 OUI_Type; - u8 OUI_SubType; - u8 Version; - TSPEC_BODY Body; -} WMM_TSPEC, *PWMM_TSPEC; - -// -// ACM implementation method. -// Annie, 2005-12-13. -// -typedef enum _ACM_METHOD{ - eAcmWay0_SwAndHw = 0, // By SW and HW. - eAcmWay1_HW = 1, // By HW. - eAcmWay2_SW = 2, // By SW. -}ACM_METHOD,*PACM_METHOD; - - -typedef struct _ACM{ -// u8 RegEnableACM; - u64 UsedTime; - u64 MediumTime; - u8 HwAcmCtl; // TRUE: UsedTime exceed => Do NOT USE this AC. It wll be written to ACM_CONTROL(0xBF BIT 0/1/2 in 8185B). -}ACM, *PACM; - -typedef u8 AC_UAPSD, *PAC_UAPSD; - -#define GET_VO_UAPSD(_apsd) ((_apsd) & BIT0) -#define SET_VO_UAPSD(_apsd) ((_apsd) |= BIT0) - -#define GET_VI_UAPSD(_apsd) ((_apsd) & BIT1) -#define SET_VI_UAPSD(_apsd) ((_apsd) |= BIT1) - -#define GET_BK_UAPSD(_apsd) ((_apsd) & BIT2) -#define SET_BK_UAPSD(_apsd) ((_apsd) |= BIT2) - -#define GET_BE_UAPSD(_apsd) ((_apsd) & BIT3) -#define SET_BE_UAPSD(_apsd) ((_apsd) |= BIT3) - - -//typedef struct _TCLASS{ -// TODO -//} TCLASS, *PTCLASS; -typedef union _QOS_TCLAS{ - - struct _TYPE_GENERAL{ - u8 Priority; - u8 ClassifierType; - u8 Mask; - } TYPE_GENERAL; - - struct _TYPE0_ETH{ - u8 Priority; - u8 ClassifierType; - u8 Mask; - u8 SrcAddr[6]; - u8 DstAddr[6]; - u16 Type; - } TYPE0_ETH; - - struct _TYPE1_IPV4{ - u8 Priority; - u8 ClassifierType; - u8 Mask; - u8 Version; - u8 SrcIP[4]; - u8 DstIP[4]; - u16 SrcPort; - u16 DstPort; - u8 DSCP; - u8 Protocol; - u8 Reserved; - } TYPE1_IPV4; - - struct _TYPE1_IPV6{ - u8 Priority; - u8 ClassifierType; - u8 Mask; - u8 Version; - u8 SrcIP[16]; - u8 DstIP[16]; - u16 SrcPort; - u16 DstPort; - u8 FlowLabel[3]; - } TYPE1_IPV6; - - struct _TYPE2_8021Q{ - u8 Priority; - u8 ClassifierType; - u8 Mask; - u16 TagType; - } TYPE2_8021Q; -} QOS_TCLAS, *PQOS_TCLAS; - -//typedef struct _WMM_TSTREAM{ -// -//- TSPEC -//- AC (which to mapping) -//} WMM_TSTREAM, *PWMM_TSTREAM; -typedef struct _QOS_TSTREAM{ - u8 AC; - WMM_TSPEC TSpec; - QOS_TCLAS TClass; -} QOS_TSTREAM, *PQOS_TSTREAM; - -//typedef struct _U_APSD{ -//- TriggerEnable [4] -//- MaxSPLength -//- HighestAcBuffered -//} U_APSD, *PU_APSD; - -//joseph TODO: -// UAPSD function should be implemented by 2 data structure -// "Qos control field" and "Qos info field" -//typedef struct _QOS_UAPSD{ -// u8 bTriggerEnable[4]; -// u8 MaxSPLength; -// u8 HighestBufAC; -//} QOS_UAPSD, *PQOS_APSD; - -//---------------------------------------------------------------------------- -// 802.11 Management frame Status Code field -//---------------------------------------------------------------------------- -typedef struct _OCTET_STRING{ - u8 *Octet; - u16 Length; -}OCTET_STRING, *POCTET_STRING; - -// -// STA QoS data. -// Ref: DOT11_QOS in 8185 code. [def. in QoS_mp.h] -// -typedef struct _STA_QOS{ - //DECLARE_RT_OBJECT(STA_QOS); - u8 WMMIEBuf[MAX_WMMELE_LENGTH]; - u8* WMMIE; - - // Part 1. Self QoS Mode. - QOS_MODE QosCapability; //QoS Capability, 2006-06-14 Isaiah - QOS_MODE CurrentQosMode; - - // For WMM Power Save Mode : - // ACs are trigger/delivery enabled or legacy power save enabled. 2006-06-13 Isaiah - AC_UAPSD b4ac_Uapsd; //VoUapsd(bit0), ViUapsd(bit1), BkUapsd(bit2), BeUapsd(bit3), - AC_UAPSD Curr4acUapsd; - u8 bInServicePeriod; - u8 MaxSPLength; - int NumBcnBeforeTrigger; - - // Part 2. EDCA Parameter (perAC) - u8 * pWMMInfoEle; - u8 WMMParamEle[WMM_PARAM_ELEMENT_SIZE]; - u8 WMMPELength; - - // <Bruce_Note> - //2 ToDo: remove the Qos Info Field and replace it by the above WMM Info element. - // By Bruce, 2008-01-30. - // Part 2. EDCA Parameter (perAC) - QOS_INFO_FIELD QosInfoField_STA; // Maintained by STA - QOS_INFO_FIELD QosInfoField_AP; // Retrieved from AP - - AC_PARAM CurAcParameters[4]; - - // Part 3. ACM - ACM acm[4]; - ACM_METHOD AcmMethod; - - // Part 4. Per TID (Part 5: TCLASS will be described by TStream) - QOS_TSTREAM TStream[16]; - WMM_TSPEC TSpec; - - u32 QBssWirelessMode; - - // No Ack Setting - u8 bNoAck; - - // Enable/Disable Rx immediate BA capability. - u8 bEnableRxImmBA; - -}STA_QOS, *PSTA_QOS; - -// -// BSS QOS data. -// Ref: BssDscr in 8185 code. [def. in BssDscr.h] -// -typedef struct _BSS_QOS{ - QOS_MODE bdQoSMode; - - u8 bdWMMIEBuf[MAX_WMMELE_LENGTH]; - u8* bdWMMIE; - - QOS_ELE_SUBTYPE EleSubType; - - u8 * pWMMInfoEle; - u8 * pWMMParamEle; - - QOS_INFO_FIELD QosInfoField; - AC_PARAM AcParameter[4]; -}BSS_QOS, *PBSS_QOS; - - -// -// Ref: sQoSCtlLng and QoSCtl definition in 8185 QoS code. -//#define QoSCtl (( (Adapter->bRegQoS) && (Adapter->dot11QoS.QoSMode &(QOS_EDCA|QOS_HCCA)) ) ?sQoSCtlLng:0) -// -#define sQoSCtlLng 2 -#define QOS_CTRL_LEN(_QosMode) ((_QosMode > QOS_DISABLE)? sQoSCtlLng : 0) - - -//Added by joseph -//UP Mapping to AC, using in MgntQuery_SequenceNumber() and maybe for DSCP -//#define UP2AC(up) ((up<3)?((up==0)?1:0):(up>>1)) -#define IsACValid(ac) ((ac<=7 )?true:false ) - -#endif // #ifndef __INC_QOS_TYPE_H diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_TS.h b/drivers/staging/rtl8192e/ieee80211/rtl819x_TS.h deleted file mode 100644 index e7e26fd..0000000 --- a/drivers/staging/rtl8192e/ieee80211/rtl819x_TS.h +++ /dev/null @@ -1,56 +0,0 @@ -#ifndef _TSTYPE_H_ -#define _TSTYPE_H_ -#include "rtl819x_Qos.h" -#define TS_SETUP_TIMEOUT 60 // In millisecond -#define TS_INACT_TIMEOUT 60 -#define TS_ADDBA_DELAY 60 - -#define TOTAL_TS_NUM 16 -#define TCLAS_NUM 4 - -// This define the Tx/Rx directions -typedef enum _TR_SELECT { - TX_DIR = 0, - RX_DIR = 1, -} TR_SELECT, *PTR_SELECT; - -typedef struct _TS_COMMON_INFO{ - struct list_head List; - struct timer_list SetupTimer; - struct timer_list InactTimer; - u8 Addr[6]; - TSPEC_BODY TSpec; - QOS_TCLAS TClass[TCLAS_NUM]; - u8 TClasProc; - u8 TClasNum; -} TS_COMMON_INFO, *PTS_COMMON_INFO; - -typedef struct _TX_TS_RECORD{ - TS_COMMON_INFO TsCommonInfo; - u16 TxCurSeq; - BA_RECORD TxPendingBARecord; // For BA Originator - BA_RECORD TxAdmittedBARecord; // For BA Originator -// QOS_DL_RECORD DLRecord; - u8 bAddBaReqInProgress; - u8 bAddBaReqDelayed; - u8 bUsingBa; - struct timer_list TsAddBaTimer; - u8 num; -} TX_TS_RECORD, *PTX_TS_RECORD; - -typedef struct _RX_TS_RECORD { - TS_COMMON_INFO TsCommonInfo; - u16 RxIndicateSeq; - u16 RxTimeoutIndicateSeq; - struct list_head RxPendingPktList; - struct timer_list RxPktPendingTimer; - BA_RECORD RxAdmittedBARecord; // For BA Recipient - u16 RxLastSeqNum; - u8 RxLastFragNum; - u8 num; -// QOS_DL_RECORD DLRecord; -} RX_TS_RECORD, *PRX_TS_RECORD; - - -#endif - diff --git a/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c b/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c deleted file mode 100644 index ad6872d..0000000 --- a/drivers/staging/rtl8192e/ieee80211/rtl819x_TSProc.c +++ /dev/null @@ -1,627 +0,0 @@ -#include "ieee80211.h" -#include <linux/etherdevice.h> -#include <linux/slab.h> -#include "rtl819x_TS.h" - -void TsSetupTimeOut(unsigned long data) -{ - // Not implement yet - // This is used for WMMSA and ACM , that would send ADDTSReq frame. -} - -void TsInactTimeout(unsigned long data) -{ - // Not implement yet - // This is used for WMMSA and ACM. - // This function would be call when TS is no Tx/Rx for some period of time. -} - -/******************************************************************************************************************** - *function: I still not understand this function, so wait for further implementation - * input: unsigned long data //acturally we send TX_TS_RECORD or RX_TS_RECORD to these timer - * return: NULL - * notice: -********************************************************************************************************************/ -void RxPktPendingTimeout(unsigned long data) -{ - PRX_TS_RECORD pRxTs = (PRX_TS_RECORD)data; - struct ieee80211_device *ieee = container_of(pRxTs, struct ieee80211_device, RxTsRecord[pRxTs->num]); - - PRX_REORDER_ENTRY pReorderEntry = NULL; - - //u32 flags = 0; - unsigned long flags = 0; - struct ieee80211_rxb *stats_IndicateArray[REORDER_WIN_SIZE]; - u8 index = 0; - bool bPktInBuf = false; - - - spin_lock_irqsave(&(ieee->reorder_spinlock), flags); - //PlatformAcquireSpinLock(Adapter, RT_RX_SPINLOCK); - IEEE80211_DEBUG(IEEE80211_DL_REORDER,"==================>%s()\n",__FUNCTION__); - if(pRxTs->RxTimeoutIndicateSeq != 0xffff) - { - // Indicate the pending packets sequentially according to SeqNum until meet the gap. - while(!list_empty(&pRxTs->RxPendingPktList)) - { - pReorderEntry = (PRX_REORDER_ENTRY)list_entry(pRxTs->RxPendingPktList.prev,RX_REORDER_ENTRY,List); - if(index == 0) - pRxTs->RxIndicateSeq = pReorderEntry->SeqNum; - - if( SN_LESS(pReorderEntry->SeqNum, pRxTs->RxIndicateSeq) || - SN_EQUAL(pReorderEntry->SeqNum, pRxTs->RxIndicateSeq) ) - { - list_del_init(&pReorderEntry->List); - - if(SN_EQUAL(pReorderEntry->SeqNum, pRxTs->RxIndicateSeq)) - pRxTs->RxIndicateSeq = (pRxTs->RxIndicateSeq + 1) % 4096; - - IEEE80211_DEBUG(IEEE80211_DL_REORDER,"RxPktPendingTimeout(): IndicateSeq: %d\n", pReorderEntry->SeqNum); - stats_IndicateArray[index] = pReorderEntry->prxb; - index++; - - list_add_tail(&pReorderEntry->List, &ieee->RxReorder_Unused_List); - } - else - { - bPktInBuf = true; - break; - } - } - } - - if(index>0) - { - // Set RxTimeoutIndicateSeq to 0xffff to indicate no pending packets in buffer now. - pRxTs->RxTimeoutIndicateSeq = 0xffff; - - // Indicate packets - if(index > REORDER_WIN_SIZE){ - IEEE80211_DEBUG(IEEE80211_DL_ERR, "RxReorderIndicatePacket(): Rx Reorer buffer full!! \n"); - spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags); - return; - } - ieee80211_indicate_packets(ieee, stats_IndicateArray, index); - } - - if(bPktInBuf && (pRxTs->RxTimeoutIndicateSeq==0xffff)) - { - pRxTs->RxTimeoutIndicateSeq = pRxTs->RxIndicateSeq; - mod_timer(&pRxTs->RxPktPendingTimer, jiffies + MSECS(ieee->pHTInfo->RxReorderPendingTime)); - } - spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags); - //PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK); -} - -/******************************************************************************************************************** - *function: Add BA timer function - * input: unsigned long data //acturally we send TX_TS_RECORD or RX_TS_RECORD to these timer - * return: NULL - * notice: -********************************************************************************************************************/ -void TsAddBaProcess(unsigned long data) -{ - PTX_TS_RECORD pTxTs = (PTX_TS_RECORD)data; - u8 num = pTxTs->num; - struct ieee80211_device *ieee = container_of(pTxTs, struct ieee80211_device, TxTsRecord[num]); - - TsInitAddBA(ieee, pTxTs, BA_POLICY_IMMEDIATE, false); - IEEE80211_DEBUG(IEEE80211_DL_BA, "TsAddBaProcess(): ADDBA Req is started!! \n"); -} - - -void ResetTsCommonInfo(PTS_COMMON_INFO pTsCommonInfo) -{ - memset(pTsCommonInfo->Addr, 0, 6); - memset(&pTsCommonInfo->TSpec, 0, sizeof(TSPEC_BODY)); - memset(&pTsCommonInfo->TClass, 0, sizeof(QOS_TCLAS)*TCLAS_NUM); - pTsCommonInfo->TClasProc = 0; - pTsCommonInfo->TClasNum = 0; -} - -void ResetTxTsEntry(PTX_TS_RECORD pTS) -{ - ResetTsCommonInfo(&pTS->TsCommonInfo); - pTS->TxCurSeq = 0; - pTS->bAddBaReqInProgress = false; - pTS->bAddBaReqDelayed = false; - pTS->bUsingBa = false; - ResetBaEntry(&pTS->TxAdmittedBARecord); //For BA Originator - ResetBaEntry(&pTS->TxPendingBARecord); -} - -void ResetRxTsEntry(PRX_TS_RECORD pTS) -{ - ResetTsCommonInfo(&pTS->TsCommonInfo); - pTS->RxIndicateSeq = 0xffff; // This indicate the RxIndicateSeq is not used now!! - pTS->RxTimeoutIndicateSeq = 0xffff; // This indicate the RxTimeoutIndicateSeq is not used now!! - ResetBaEntry(&pTS->RxAdmittedBARecord); // For BA Recipient -} - -void TSInitialize(struct ieee80211_device *ieee) -{ - PTX_TS_RECORD pTxTS = ieee->TxTsRecord; - PRX_TS_RECORD pRxTS = ieee->RxTsRecord; - PRX_REORDER_ENTRY pRxReorderEntry = ieee->RxReorderEntry; - u8 count = 0; - IEEE80211_DEBUG(IEEE80211_DL_TS, "==========>%s()\n", __FUNCTION__); - // Initialize Tx TS related info. - INIT_LIST_HEAD(&ieee->Tx_TS_Admit_List); - INIT_LIST_HEAD(&ieee->Tx_TS_Pending_List); - INIT_LIST_HEAD(&ieee->Tx_TS_Unused_List); - - for(count = 0; count < TOTAL_TS_NUM; count++) - { - // - pTxTS->num = count; - // The timers for the operation of Traffic Stream and Block Ack. - // DLS related timer will be add here in the future!! - init_timer(&pTxTS->TsCommonInfo.SetupTimer); - pTxTS->TsCommonInfo.SetupTimer.data = (unsigned long)pTxTS; - pTxTS->TsCommonInfo.SetupTimer.function = TsSetupTimeOut; - - init_timer(&pTxTS->TsCommonInfo.InactTimer); - pTxTS->TsCommonInfo.InactTimer.data = (unsigned long)pTxTS; - pTxTS->TsCommonInfo.InactTimer.function = TsInactTimeout; - - init_timer(&pTxTS->TsAddBaTimer); - pTxTS->TsAddBaTimer.data = (unsigned long)pTxTS; - pTxTS->TsAddBaTimer.function = TsAddBaProcess; - - init_timer(&pTxTS->TxPendingBARecord.Timer); - pTxTS->TxPendingBARecord.Timer.data = (unsigned long)pTxTS; - pTxTS->TxPendingBARecord.Timer.function = BaSetupTimeOut; - - init_timer(&pTxTS->TxAdmittedBARecord.Timer); - pTxTS->TxAdmittedBARecord.Timer.data = (unsigned long)pTxTS; - pTxTS->TxAdmittedBARecord.Timer.function = TxBaInactTimeout; - - ResetTxTsEntry(pTxTS); - list_add_tail(&pTxTS->TsCommonInfo.List, &ieee->Tx_TS_Unused_List); - pTxTS++; - } - - // Initialize Rx TS related info. - INIT_LIST_HEAD(&ieee->Rx_TS_Admit_List); - INIT_LIST_HEAD(&ieee->Rx_TS_Pending_List); - INIT_LIST_HEAD(&ieee->Rx_TS_Unused_List); - for(count = 0; count < TOTAL_TS_NUM; count++) - { - pRxTS->num = count; - INIT_LIST_HEAD(&pRxTS->RxPendingPktList); - - init_timer(&pRxTS->TsCommonInfo.SetupTimer); - pRxTS->TsCommonInfo.SetupTimer.data = (unsigned long)pRxTS; - pRxTS->TsCommonInfo.SetupTimer.function = TsSetupTimeOut; - - init_timer(&pRxTS->TsCommonInfo.InactTimer); - pRxTS->TsCommonInfo.InactTimer.data = (unsigned long)pRxTS; - pRxTS->TsCommonInfo.InactTimer.function = TsInactTimeout; - - init_timer(&pRxTS->RxAdmittedBARecord.Timer); - pRxTS->RxAdmittedBARecord.Timer.data = (unsigned long)pRxTS; - pRxTS->RxAdmittedBARecord.Timer.function = RxBaInactTimeout; - - init_timer(&pRxTS->RxPktPendingTimer); - pRxTS->RxPktPendingTimer.data = (unsigned long)pRxTS; - pRxTS->RxPktPendingTimer.function = RxPktPendingTimeout; - - ResetRxTsEntry(pRxTS); - list_add_tail(&pRxTS->TsCommonInfo.List, &ieee->Rx_TS_Unused_List); - pRxTS++; - } - // Initialize unused Rx Reorder List. - INIT_LIST_HEAD(&ieee->RxReorder_Unused_List); -//#ifdef TO_DO_LIST - for(count = 0; count < REORDER_ENTRY_NUM; count++) - { - list_add_tail( &pRxReorderEntry->List,&ieee->RxReorder_Unused_List); - if(count == (REORDER_ENTRY_NUM-1)) - break; - pRxReorderEntry = &ieee->RxReorderEntry[count+1]; - } -//#endif - -} - -void AdmitTS(struct ieee80211_device *ieee, PTS_COMMON_INFO pTsCommonInfo, u32 InactTime) -{ - del_timer_sync(&pTsCommonInfo->SetupTimer); - del_timer_sync(&pTsCommonInfo->InactTimer); - - if(InactTime!=0) - mod_timer(&pTsCommonInfo->InactTimer, jiffies + MSECS(InactTime)); -} - - -PTS_COMMON_INFO SearchAdmitTRStream(struct ieee80211_device *ieee, u8* Addr, u8 TID, TR_SELECT TxRxSelect) -{ - //DIRECTION_VALUE dir; - u8 dir; - bool search_dir[4] = {0, 0, 0, 0}; - struct list_head* psearch_list; //FIXME - PTS_COMMON_INFO pRet = NULL; - if(ieee->iw_mode == IW_MODE_MASTER) //ap mode - { - if(TxRxSelect == TX_DIR) - { - search_dir[DIR_DOWN] = true; - search_dir[DIR_BI_DIR]= true; - } - else - { - search_dir[DIR_UP] = true; - search_dir[DIR_BI_DIR]= true; - } - } - else if(ieee->iw_mode == IW_MODE_ADHOC) - { - if(TxRxSelect == TX_DIR) - search_dir[DIR_UP] = true; - else - search_dir[DIR_DOWN] = true; - } - else - { - if(TxRxSelect == TX_DIR) - { - search_dir[DIR_UP] = true; - search_dir[DIR_BI_DIR]= true; - search_dir[DIR_DIRECT]= true; - } - else - { - search_dir[DIR_DOWN] = true; - search_dir[DIR_BI_DIR]= true; - search_dir[DIR_DIRECT]= true; - } - } - - if(TxRxSelect == TX_DIR) - psearch_list = &ieee->Tx_TS_Admit_List; - else - psearch_list = &ieee->Rx_TS_Admit_List; - - //for(dir = DIR_UP; dir <= DIR_BI_DIR; dir++) - for(dir = 0; dir <= DIR_BI_DIR; dir++) - { - if(search_dir[dir] ==false ) - continue; - list_for_each_entry(pRet, psearch_list, List){ - // IEEE80211_DEBUG(IEEE80211_DL_TS, "ADD:%pM, TID:%d, dir:%d\n", pRet->Addr, pRet->TSpec.f.TSInfo.field.ucTSID, pRet->TSpec.f.TSInfo.field.ucDirection); - if (memcmp(pRet->Addr, Addr, 6) == 0) - if (pRet->TSpec.f.TSInfo.field.ucTSID == TID) - if(pRet->TSpec.f.TSInfo.field.ucDirection == dir) - { - break; - } - - } - if(&pRet->List != psearch_list) - break; - } - - if(&pRet->List != psearch_list){ - return pRet ; - } - else - return NULL; -} - -void MakeTSEntry( - PTS_COMMON_INFO pTsCommonInfo, - u8* Addr, - PTSPEC_BODY pTSPEC, - PQOS_TCLAS pTCLAS, - u8 TCLAS_Num, - u8 TCLAS_Proc - ) -{ - u8 count; - - if(pTsCommonInfo == NULL) - return; - - memcpy(pTsCommonInfo->Addr, Addr, 6); - - if(pTSPEC != NULL) - memcpy((u8*)(&(pTsCommonInfo->TSpec)), (u8*)pTSPEC, sizeof(TSPEC_BODY)); - - for(count = 0; count < TCLAS_Num; count++) - memcpy((u8*)(&(pTsCommonInfo->TClass[count])), (u8*)pTCLAS, sizeof(QOS_TCLAS)); - - pTsCommonInfo->TClasProc = TCLAS_Proc; - pTsCommonInfo->TClasNum = TCLAS_Num; -} - - -bool GetTs( - struct ieee80211_device* ieee, - PTS_COMMON_INFO *ppTS, - u8* Addr, - u8 TID, - TR_SELECT TxRxSelect, //Rx:1, Tx:0 - bool bAddNewTs - ) -{ - u8 UP = 0; - // - // We do not build any TS for Broadcast or Multicast stream. - // So reject these kinds of search here. - // - if(is_broadcast_ether_addr(Addr) || is_multicast_ether_addr(Addr)) - { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "get TS for Broadcast or Multicast\n"); - return false; - } - - if (ieee->current_network.qos_data.supported == 0) - UP = 0; - else - { - // In WMM case: we use 4 TID only - if (!IsACValid(TID)) - { - IEEE80211_DEBUG(IEEE80211_DL_ERR, " in %s(), TID(%d) is not valid\n", __FUNCTION__, TID); - return false; - } - - switch(TID) - { - case 0: - case 3: - UP = 0; - break; - - case 1: - case 2: - UP = 2; - break; - - case 4: - case 5: - UP = 5; - break; - - case 6: - case 7: - UP = 7; - break; - } - } - - *ppTS = SearchAdmitTRStream( - ieee, - Addr, - UP, - TxRxSelect); - if(*ppTS != NULL) - { - return true; - } - else - { - if(bAddNewTs == false) - { - IEEE80211_DEBUG(IEEE80211_DL_TS, "add new TS failed(tid:%d)\n", UP); - return false; - } - else - { - // - // Create a new Traffic stream for current Tx/Rx - // This is for EDCA and WMM to add a new TS. - // For HCCA or WMMSA, TS cannot be addmit without negotiation. - // - TSPEC_BODY TSpec; - PQOS_TSINFO pTSInfo = &TSpec.f.TSInfo; - struct list_head* pUnusedList = - (TxRxSelect == TX_DIR)? - (&ieee->Tx_TS_Unused_List): - (&ieee->Rx_TS_Unused_List); - - struct list_head* pAddmitList = - (TxRxSelect == TX_DIR)? - (&ieee->Tx_TS_Admit_List): - (&ieee->Rx_TS_Admit_List); - - DIRECTION_VALUE Dir = (ieee->iw_mode == IW_MODE_MASTER)? - ((TxRxSelect==TX_DIR)?DIR_DOWN:DIR_UP): - ((TxRxSelect==TX_DIR)?DIR_UP:DIR_DOWN); - IEEE80211_DEBUG(IEEE80211_DL_TS, "to add Ts\n"); - if(!list_empty(pUnusedList)) - { - (*ppTS) = list_entry(pUnusedList->next, TS_COMMON_INFO, List); - list_del_init(&(*ppTS)->List); - if(TxRxSelect==TX_DIR) - { - PTX_TS_RECORD tmp = container_of(*ppTS, TX_TS_RECORD, TsCommonInfo); - ResetTxTsEntry(tmp); - } - else{ - PRX_TS_RECORD tmp = container_of(*ppTS, RX_TS_RECORD, TsCommonInfo); - ResetRxTsEntry(tmp); - } - - IEEE80211_DEBUG(IEEE80211_DL_TS, "to init current TS, UP:%d, Dir:%d, addr:%pM\n", UP, Dir, Addr); - // Prepare TS Info releated field - pTSInfo->field.ucTrafficType = 0; // Traffic type: WMM is reserved in this field - pTSInfo->field.ucTSID = UP; // TSID - pTSInfo->field.ucDirection = Dir; // Direction: if there is DirectLink, this need additional consideration. - pTSInfo->field.ucAccessPolicy = 1; // Access policy - pTSInfo->field.ucAggregation = 0; // Aggregation - pTSInfo->field.ucPSB = 0; // Aggregation - pTSInfo->field.ucUP = UP; // User priority - pTSInfo->field.ucTSInfoAckPolicy = 0; // Ack policy - pTSInfo->field.ucSchedule = 0; // Schedule - - MakeTSEntry(*ppTS, Addr, &TSpec, NULL, 0, 0); - AdmitTS(ieee, *ppTS, 0); - list_add_tail(&((*ppTS)->List), pAddmitList); - // if there is DirectLink, we need to do additional operation here!! - - return true; - } - else - { - IEEE80211_DEBUG(IEEE80211_DL_ERR, "in function %s() There is not enough TS record to be used!!", __FUNCTION__); - return false; - } - } - } -} - -void RemoveTsEntry( - struct ieee80211_device* ieee, - PTS_COMMON_INFO pTs, - TR_SELECT TxRxSelect - ) -{ - //u32 flags = 0; - unsigned long flags = 0; - del_timer_sync(&pTs->SetupTimer); - del_timer_sync(&pTs->InactTimer); - TsInitDelBA(ieee, pTs, TxRxSelect); - - if(TxRxSelect == RX_DIR) - { -//#ifdef TO_DO_LIST - PRX_REORDER_ENTRY pRxReorderEntry; - PRX_TS_RECORD pRxTS = (PRX_TS_RECORD)pTs; - if(timer_pending(&pRxTS->RxPktPendingTimer)) - del_timer_sync(&pRxTS->RxPktPendingTimer); - - while(!list_empty(&pRxTS->RxPendingPktList)) - { - // PlatformAcquireSpinLock(Adapter, RT_RX_SPINLOCK); - spin_lock_irqsave(&(ieee->reorder_spinlock), flags); - //pRxReorderEntry = list_entry(&pRxTS->RxPendingPktList.prev,RX_REORDER_ENTRY,List); - pRxReorderEntry = (PRX_REORDER_ENTRY)list_entry(pRxTS->RxPendingPktList.prev,RX_REORDER_ENTRY,List); - list_del_init(&pRxReorderEntry->List); - { - int i = 0; - struct ieee80211_rxb * prxb = pRxReorderEntry->prxb; - if (unlikely(!prxb)) - { - spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags); - return; - } - for(i =0; i < prxb->nr_subframes; i++) { - dev_kfree_skb(prxb->subframes[i]); - } - kfree(prxb); - prxb = NULL; - } - list_add_tail(&pRxReorderEntry->List,&ieee->RxReorder_Unused_List); - //PlatformReleaseSpinLock(Adapter, RT_RX_SPINLOCK); - spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags); - } - -//#endif - } - else - { - PTX_TS_RECORD pTxTS = (PTX_TS_RECORD)pTs; - del_timer_sync(&pTxTS->TsAddBaTimer); - } -} - -void RemovePeerTS(struct ieee80211_device* ieee, u8* Addr) -{ - PTS_COMMON_INFO pTS, pTmpTS; - - printk("===========>RemovePeerTS,%pM\n", Addr); - list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List) - { - if (memcmp(pTS->Addr, Addr, 6) == 0) - { - RemoveTsEntry(ieee, pTS, TX_DIR); - list_del_init(&pTS->List); - list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List); - } - } - - list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Admit_List, List) - { - if (memcmp(pTS->Addr, Addr, 6) == 0) - { - printk("====>remove Tx_TS_admin_list\n"); - RemoveTsEntry(ieee, pTS, TX_DIR); - list_del_init(&pTS->List); - list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List); - } - } - - list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Pending_List, List) - { - if (memcmp(pTS->Addr, Addr, 6) == 0) - { - RemoveTsEntry(ieee, pTS, RX_DIR); - list_del_init(&pTS->List); - list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List); - } - } - - list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Admit_List, List) - { - if (memcmp(pTS->Addr, Addr, 6) == 0) - { - RemoveTsEntry(ieee, pTS, RX_DIR); - list_del_init(&pTS->List); - list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List); - } - } -} - -void RemoveAllTS(struct ieee80211_device* ieee) -{ - PTS_COMMON_INFO pTS, pTmpTS; - - list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List) - { - RemoveTsEntry(ieee, pTS, TX_DIR); - list_del_init(&pTS->List); - list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List); - } - - list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Admit_List, List) - { - RemoveTsEntry(ieee, pTS, TX_DIR); - list_del_init(&pTS->List); - list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List); - } - - list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Pending_List, List) - { - RemoveTsEntry(ieee, pTS, RX_DIR); - list_del_init(&pTS->List); - list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List); - } - - list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Admit_List, List) - { - RemoveTsEntry(ieee, pTS, RX_DIR); - list_del_init(&pTS->List); - list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List); - } -} - -void TsStartAddBaProcess(struct ieee80211_device* ieee, PTX_TS_RECORD pTxTS) -{ - if(pTxTS->bAddBaReqInProgress == false) - { - pTxTS->bAddBaReqInProgress = true; - if(pTxTS->bAddBaReqDelayed) - { - IEEE80211_DEBUG(IEEE80211_DL_BA, "TsStartAddBaProcess(): Delayed Start ADDBA after 60 sec!!\n"); - mod_timer(&pTxTS->TsAddBaTimer, jiffies + MSECS(TS_ADDBA_DELAY)); - } - else - { - IEEE80211_DEBUG(IEEE80211_DL_BA,"TsStartAddBaProcess(): Immediately Start ADDBA now!!\n"); - mod_timer(&pTxTS->TsAddBaTimer, jiffies+10); //set 10 ticks - } - } - else - IEEE80211_DEBUG(IEEE80211_DL_ERR, "%s()==>BA timer is already added\n", __FUNCTION__); -} diff --git a/drivers/staging/rtl8192e/license b/drivers/staging/rtl8192e/license new file mode 100644 index 0000000..4bea9fa --- /dev/null +++ b/drivers/staging/rtl8192e/license @@ -0,0 +1,339 @@ + +"This software program is licensed subject to the GNU General Public License +(GPL). Version 2, June 1991, available at +<http: + +GNU General Public License + +Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. +59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + +Everyone is permitted to copy and distribute verbatim copies of this license +document, but changing it is not allowed. + +Preamble + +The licenses for most software are designed to take away your freedom to +share and change it. By contrast, the GNU General Public License is intended +to guarantee your freedom to share and change free software--to make sure +the software is free for all its users. This General Public License applies +to most of the Free Software Foundation's software and to any other program +whose authors commit to using it. (Some other Free Software Foundation +software is covered by the GNU Library General Public License instead.) You +can apply it to your programs, too. + +When we speak of free software, we are referring to freedom, not price. Our +General Public Licenses are designed to make sure that you have the freedom +to distribute copies of free software (and charge for this service if you +wish), that you receive source code or can get it if you want it, that you +can change the software or use pieces of it in new free programs; and that +you know you can do these things. + +To protect your rights, we need to make restrictions that forbid anyone to +deny you these rights or to ask you to surrender the rights. These +restrictions translate to certain responsibilities for you if you distribute +copies of the software, or if you modify it. + +For example, if you distribute copies of such a program, whether gratis or +for a fee, you must give the recipients all the rights that you have. You +must make sure that they, too, receive or can get the source code. And you +must show them these terms so they know their rights. + +We protect your rights with two steps: (1) copyright the software, and (2) +offer you this license which gives you legal permission to copy, distribute +and/or modify the software. + +Also, for each author's protection and ours, we want to make certain that +everyone understands that there is no warranty for this free software. If +the software is modified by someone else and passed on, we want its +recipients to know that what they have is not the original, so that any +problems introduced by others will not reflect on the original authors' +reputations. + +Finally, any free program is threatened constantly by software patents. We +wish to avoid the danger that redistributors of a free program will +individually obtain patent licenses, in effect making the program +proprietary. To prevent this, we have made it clear that any patent must be +licensed for everyone's free use or not licensed at all. + +The precise terms and conditions for copying, distribution and modification +follow. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License applies to any program or other work which contains a notice + placed by the copyright holder saying it may be distributed under the + terms of this General Public License. The "Program", below, refers to any + such program or work, and a "work based on the Program" means either the + Program or any derivative work under copyright law: that is to say, a + work containing the Program or a portion of it, either verbatim or with + modifications and/or translated into another language. (Hereinafter, + translation is included without limitation in the term "modification".) + Each licensee is addressed as "you". + + Activities other than copying, distribution and modification are not + covered by this License; they are outside its scope. The act of running + the Program is not restricted, and the output from the Program is covered + only if its contents constitute a work based on the Program (independent + of having been made by running the Program). Whether that is true depends + on what the Program does. + +1. You may copy and distribute verbatim copies of the Program's source code + as you receive it, in any medium, provided that you conspicuously and + appropriately publish on each copy an appropriate copyright notice and + disclaimer of warranty; keep intact all the notices that refer to this + License and to the absence of any warranty; and give any other recipients + of the Program a copy of this License along with the Program. + + You may charge a fee for the physical act of transferring a copy, and you + may at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Program or any portion of it, + thus forming a work based on the Program, and copy and distribute such + modifications or work under the terms of Section 1 above, provided that + you also meet all of these conditions: + + * a) You must cause the modified files to carry prominent notices stating + that you changed the files and the date of any change. + + * b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any part + thereof, to be licensed as a whole at no charge to all third parties + under the terms of this License. + + * c) If the modified program normally reads commands interactively when + run, you must cause it, when started running for such interactive + use in the most ordinary way, to print or display an announcement + including an appropriate copyright notice and a notice that there is + no warranty (or else, saying that you provide a warranty) and that + users may redistribute the program under these conditions, and + telling the user how to view a copy of this License. (Exception: if + the Program itself is interactive but does not normally print such + an announcement, your work based on the Program is not required to + print an announcement.) + + These requirements apply to the modified work as a whole. If identifiable + sections of that work are not derived from the Program, and can be + reasonably considered independent and separate works in themselves, then + this License, and its terms, do not apply to those sections when you + distribute them as separate works. But when you distribute the same + sections as part of a whole which is a work based on the Program, the + distribution of the whole must be on the terms of this License, whose + permissions for other licensees extend to the entire whole, and thus to + each and every part regardless of who wrote it. + + Thus, it is not the intent of this section to claim rights or contest + your rights to work written entirely by you; rather, the intent is to + exercise the right to control the distribution of derivative or + collective works based on the Program. + + In addition, mere aggregation of another work not based on the Program + with the Program (or with a work based on the Program) on a volume of a + storage or distribution medium does not bring the other work under the + scope of this License. + +3. You may copy and distribute the Program (or a work based on it, under + Section 2) in object code or executable form under the terms of Sections + 1 and 2 above provided that you also do one of the following: + + * a) Accompany it with the complete corresponding machine-readable source + code, which must be distributed under the terms of Sections 1 and 2 + above on a medium customarily used for software interchange; or, + + * b) Accompany it with a written offer, valid for at least three years, + to give any third party, for a charge no more than your cost of + physically performing source distribution, a complete machine- + readable copy of the corresponding source code, to be distributed + under the terms of Sections 1 and 2 above on a medium customarily + used for software interchange; or, + + * c) Accompany it with the information you received as to the offer to + distribute corresponding source code. (This alternative is allowed + only for noncommercial distribution and only if you received the + program in object code or executable form with such an offer, in + accord with Subsection b above.) + + The source code for a work means the preferred form of the work for + making modifications to it. For an executable work, complete source code + means all the source code for all modules it contains, plus any + associated interface definition files, plus the scripts used to control + compilation and installation of the executable. However, as a special + exception, the source code distributed need not include anything that is + normally distributed (in either source or binary form) with the major + components (compiler, kernel, and so on) of the operating system on which + the executable runs, unless that component itself accompanies the + executable. + + If distribution of executable or object code is made by offering access + to copy from a designated place, then offering equivalent access to copy + the source code from the same place counts as distribution of the source + code, even though third parties are not compelled to copy the source + along with the object code. + +4. You may not copy, modify, sublicense, or distribute the Program except as + expressly provided under this License. Any attempt otherwise to copy, + modify, sublicense or distribute the Program is void, and will + automatically terminate your rights under this License. However, parties + who have received copies, or rights, from you under this License will not + have their licenses terminated so long as such parties remain in full + compliance. + +5. You are not required to accept this License, since you have not signed + it. However, nothing else grants you permission to modify or distribute + the Program or its derivative works. These actions are prohibited by law + if you do not accept this License. Therefore, by modifying or + distributing the Program (or any work based on the Program), you + indicate your acceptance of this License to do so, and all its terms and + conditions for copying, distributing or modifying the Program or works + based on it. + +6. Each time you redistribute the Program (or any work based on the + Program), the recipient automatically receives a license from the + original licensor to copy, distribute or modify the Program subject to + these terms and conditions. You may not impose any further restrictions + on the recipients' exercise of the rights granted herein. You are not + responsible for enforcing compliance by third parties to this License. + +7. If, as a consequence of a court judgment or allegation of patent + infringement or for any other reason (not limited to patent issues), + conditions are imposed on you (whether by court order, agreement or + otherwise) that contradict the conditions of this License, they do not + excuse you from the conditions of this License. If you cannot distribute + so as to satisfy simultaneously your obligations under this License and + any other pertinent obligations, then as a consequence you may not + distribute the Program at all. For example, if a patent license would + not permit royalty-free redistribution of the Program by all those who + receive copies directly or indirectly through you, then the only way you + could satisfy both it and this License would be to refrain entirely from + distribution of the Program. + + If any portion of this section is held invalid or unenforceable under any + particular circumstance, the balance of the section is intended to apply + and the section as a whole is intended to apply in other circumstances. + + It is not the purpose of this section to induce you to infringe any + patents or other property right claims or to contest validity of any + such claims; this section has the sole purpose of protecting the + integrity of the free software distribution system, which is implemented + by public license practices. Many people have made generous contributions + to the wide range of software distributed through that system in + reliance on consistent application of that system; it is up to the + author/donor to decide if he or she is willing to distribute software + through any other system and a licensee cannot impose that choice. + + This section is intended to make thoroughly clear what is believed to be + a consequence of the rest of this License. + +8. If the distribution and/or use of the Program is restricted in certain + countries either by patents or by copyrighted interfaces, the original + copyright holder who places the Program under this License may add an + explicit geographical distribution limitation excluding those countries, + so that distribution is permitted only in or among countries not thus + excluded. In such case, this License incorporates the limitation as if + written in the body of this License. + +9. The Free Software Foundation may publish revised and/or new versions of + the General Public License from time to time. Such new versions will be + similar in spirit to the present version, but may differ in detail to + address new problems or concerns. + + Each version is given a distinguishing version number. If the Program + specifies a version number of this License which applies to it and "any + later version", you have the option of following the terms and + conditions either of that version or of any later version published by + the Free Software Foundation. If the Program does not specify a version + number of this License, you may choose any version ever published by the + Free Software Foundation. + +10. If you wish to incorporate parts of the Program into other free programs + whose distribution conditions are different, write to the author to ask + for permission. For software which is copyrighted by the Free Software + Foundation, write to the Free Software Foundation; we sometimes make + exceptions for this. Our decision will be guided by the two goals of + preserving the free status of all derivatives of our free software and + of promoting the sharing and reuse of software generally. + + NO WARRANTY + +11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY + FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN + OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES + PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER + EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE + ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH + YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL + NECESSARY SERVICING, REPAIR OR CORRECTION. + +12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING + WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR + REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR + DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL + DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM + (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED + INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF + THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR + OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it free +software which everyone can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest to +attach them to the start of each source file to most effectively convey the +exclusion of warranty; and each file should have at least the "copyright" +line and a pointer to where the full notice is found. + +one line to give the program's name and an idea of what it does. +Copyright (C) yyyy name of author + +This program is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the Free +Software Foundation; either version 2 of the License, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 +Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this when +it starts in an interactive mode: + +Gnomovision version 69, Copyright (C) year name of author Gnomovision comes +with ABSOLUTELY NO WARRANTY; for details type 'show w'. This is free +software, and you are welcome to redistribute it under certain conditions; +type 'show c' for details. + +The hypothetical commands 'show w' and 'show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may be +called something other than 'show w' and 'show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + +Yoyodyne, Inc., hereby disclaims all copyright interest in the program +'Gnomovision' (which makes passes at compilers) written by James Hacker. + +signature of Ty Coon, 1 April 1989 +Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General Public +License instead of this License. diff --git a/drivers/staging/rtl8192e/r8180_93cx6.c b/drivers/staging/rtl8192e/r8180_93cx6.c deleted file mode 100644 index 55d4f56..0000000 --- a/drivers/staging/rtl8192e/r8180_93cx6.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - This files contains card eeprom (93c46 or 93c56) programming routines, - memory is addressed by 16 bits words. - - This is part of rtl8180 OpenSource driver. - Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it> - Released under the terms of GPL (General Public Licence) - - Parts of this driver are based on the GPL part of the - official realtek driver. - - Parts of this driver are based on the rtl8180 driver skeleton - from Patric Schenke & Andres Salomon. - - Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver. - - We want to tanks the Authors of those projects and the Ndiswrapper - project Authors. -*/ - -#include "r8180_93cx6.h" - -static void eprom_cs(struct r8192_priv *priv, short bit) -{ - if (bit) - write_nic_byte(priv, EPROM_CMD, - (1<<EPROM_CS_SHIFT) | - read_nic_byte(priv, EPROM_CMD)); //enable EPROM - else - write_nic_byte(priv, EPROM_CMD, read_nic_byte(priv, EPROM_CMD) - &~(1<<EPROM_CS_SHIFT)); //disable EPROM - - udelay(EPROM_DELAY); -} - - -static void eprom_ck_cycle(struct r8192_priv *priv) -{ - write_nic_byte(priv, EPROM_CMD, - (1<<EPROM_CK_SHIFT) | read_nic_byte(priv, EPROM_CMD)); - udelay(EPROM_DELAY); - write_nic_byte(priv, EPROM_CMD, - read_nic_byte(priv, EPROM_CMD) & ~(1<<EPROM_CK_SHIFT)); - udelay(EPROM_DELAY); -} - - -static void eprom_w(struct r8192_priv *priv, short bit) -{ - if (bit) - write_nic_byte(priv, EPROM_CMD, (1<<EPROM_W_SHIFT) | - read_nic_byte(priv, EPROM_CMD)); - else - write_nic_byte(priv, EPROM_CMD, read_nic_byte(priv, EPROM_CMD) - &~(1<<EPROM_W_SHIFT)); - - udelay(EPROM_DELAY); -} - - -static short eprom_r(struct r8192_priv *priv) -{ - short bit; - - bit = (read_nic_byte(priv, EPROM_CMD) & (1<<EPROM_R_SHIFT)); - udelay(EPROM_DELAY); - - if (bit) - return 1; - return 0; -} - - -static void eprom_send_bits_string(struct r8192_priv *priv, short b[], int len) -{ - int i; - - for (i = 0; i < len; i++) { - eprom_w(priv, b[i]); - eprom_ck_cycle(priv); - } -} - - -u32 eprom_read(struct r8192_priv *priv, u32 addr) -{ - short read_cmd[] = {1, 1, 0}; - short addr_str[8]; - int i; - int addr_len; - u32 ret; - - ret = 0; - //enable EPROM programming - write_nic_byte(priv, EPROM_CMD, - (EPROM_CMD_PROGRAM<<EPROM_CMD_OPERATING_MODE_SHIFT)); - udelay(EPROM_DELAY); - - if (priv->epromtype == EPROM_93c56) { - addr_str[7] = addr & 1; - addr_str[6] = addr & (1<<1); - addr_str[5] = addr & (1<<2); - addr_str[4] = addr & (1<<3); - addr_str[3] = addr & (1<<4); - addr_str[2] = addr & (1<<5); - addr_str[1] = addr & (1<<6); - addr_str[0] = addr & (1<<7); - addr_len = 8; - } else { - addr_str[5] = addr & 1; - addr_str[4] = addr & (1<<1); - addr_str[3] = addr & (1<<2); - addr_str[2] = addr & (1<<3); - addr_str[1] = addr & (1<<4); - addr_str[0] = addr & (1<<5); - addr_len = 6; - } - eprom_cs(priv, 1); - eprom_ck_cycle(priv); - eprom_send_bits_string(priv, read_cmd, 3); - eprom_send_bits_string(priv, addr_str, addr_len); - - //keep chip pin D to low state while reading. - //I'm unsure if it is necessary, but anyway shouldn't hurt - eprom_w(priv, 0); - - for (i = 0; i < 16; i++) { - //eeprom needs a clk cycle between writing opcode&adr - //and reading data. (eeprom outs a dummy 0) - eprom_ck_cycle(priv); - ret |= (eprom_r(priv)<<(15-i)); - } - - eprom_cs(priv, 0); - eprom_ck_cycle(priv); - - //disable EPROM programming - write_nic_byte(priv, EPROM_CMD, - (EPROM_CMD_NORMAL<<EPROM_CMD_OPERATING_MODE_SHIFT)); - return ret; -} diff --git a/drivers/staging/rtl8192e/r8180_93cx6.h b/drivers/staging/rtl8192e/r8180_93cx6.h deleted file mode 100644 index 55d2054..0000000 --- a/drivers/staging/rtl8192e/r8180_93cx6.h +++ /dev/null @@ -1,41 +0,0 @@ -/* r8180_93cx6.h - 93c46 or 93c56 eeprom card programming routines - * - * This is part of rtl8187 OpenSource driver - * Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it> - * Released under the terms of GPL (General Public Licence) - * Parts of this driver are based on the GPL part of the official realtek driver - * - * Parts of this driver are based on the rtl8180 driver skeleton from - * Patric Schenke & Andres Salomon. - * - * Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver - * - * We want to thank the authors of the above mentioned projects and to - * the authors of the Ndiswrapper project. - */ - -#include "r8192E.h" -#include "r8192E_hw.h" - -#define EPROM_DELAY 10 - -#define EPROM_ANAPARAM_ADDRLWORD 0xd -#define EPROM_ANAPARAM_ADDRHWORD 0xe - -#define EPROM_RFCHIPID 0x6 -#define EPROM_TXPW_BASE 0x05 -#define EPROM_RFCHIPID_RTL8225U 5 -#define EPROM_RF_PARAM 0x4 -#define EPROM_CONFIG2 0xc - -#define EPROM_VERSION 0x1E -#define MAC_ADR 0x7 - -#define CIS 0x18 - -#define EPROM_TXPW0 0x16 -#define EPROM_TXPW2 0x1b -#define EPROM_TXPW1 0x3d - -/* Reads a 16 bits word. */ -u32 eprom_read(struct r8192_priv *priv, u32 addr); diff --git a/drivers/staging/rtl8192e/r8190P_def.h b/drivers/staging/rtl8192e/r8190P_def.h new file mode 100644 index 0000000..b7bb71f --- /dev/null +++ b/drivers/staging/rtl8192e/r8190P_def.h @@ -0,0 +1,410 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> +******************************************************************************/ + + +#ifndef R8190P_DEF_H +#define R8190P_DEF_H + +#include <linux/types.h> + +#define MAX_SILENT_RESET_RX_SLOT_NUM 10 + +#define RX_MPDU_QUEUE 0 +#define RX_CMD_QUEUE 1 + + +enum rtl819x_loopback { + RTL819X_NO_LOOPBACK = 0, + RTL819X_MAC_LOOPBACK = 1, + RTL819X_DMA_LOOPBACK = 2, + RTL819X_CCK_LOOPBACK = 3, +}; + + +#define RESET_DELAY_8185 20 + +#define RT_IBSS_INT_MASKS (IMR_BcnInt | IMR_BcnInt | IMR_TBDOK | IMR_TBDER) + +#define DESC90_RATE1M 0x00 +#define DESC90_RATE2M 0x01 +#define DESC90_RATE5_5M 0x02 +#define DESC90_RATE11M 0x03 +#define DESC90_RATE6M 0x04 +#define DESC90_RATE9M 0x05 +#define DESC90_RATE12M 0x06 +#define DESC90_RATE18M 0x07 +#define DESC90_RATE24M 0x08 +#define DESC90_RATE36M 0x09 +#define DESC90_RATE48M 0x0a +#define DESC90_RATE54M 0x0b +#define DESC90_RATEMCS0 0x00 +#define DESC90_RATEMCS1 0x01 +#define DESC90_RATEMCS2 0x02 +#define DESC90_RATEMCS3 0x03 +#define DESC90_RATEMCS4 0x04 +#define DESC90_RATEMCS5 0x05 +#define DESC90_RATEMCS6 0x06 +#define DESC90_RATEMCS7 0x07 +#define DESC90_RATEMCS8 0x08 +#define DESC90_RATEMCS9 0x09 +#define DESC90_RATEMCS10 0x0a +#define DESC90_RATEMCS11 0x0b +#define DESC90_RATEMCS12 0x0c +#define DESC90_RATEMCS13 0x0d +#define DESC90_RATEMCS14 0x0e +#define DESC90_RATEMCS15 0x0f +#define DESC90_RATEMCS32 0x20 + +#define SHORT_SLOT_TIME 9 +#define NON_SHORT_SLOT_TIME 20 + + +#define MAX_LINES_HWCONFIG_TXT 1000 +#define MAX_BYTES_LINE_HWCONFIG_TXT 128 + +#define SW_THREE_WIRE 0 +#define HW_THREE_WIRE 2 + +#define BT_DEMO_BOARD 0 +#define BT_QA_BOARD 1 +#define BT_FPGA 2 + +#define RX_SMOOTH 20 + +#define QSLT_BK 0x1 +#define QSLT_BE 0x0 +#define QSLT_VI 0x4 +#define QSLT_VO 0x6 +#define QSLT_BEACON 0x10 +#define QSLT_HIGH 0x11 +#define QSLT_MGNT 0x12 +#define QSLT_CMD 0x13 + +#define NUM_OF_FIRMWARE_QUEUE 10 +#define NUM_OF_PAGES_IN_FW 0x100 +#define NUM_OF_PAGE_IN_FW_QUEUE_BK 0x007 +#define NUM_OF_PAGE_IN_FW_QUEUE_BE 0x0aa +#define NUM_OF_PAGE_IN_FW_QUEUE_VI 0x024 +#define NUM_OF_PAGE_IN_FW_QUEUE_VO 0x007 +#define NUM_OF_PAGE_IN_FW_QUEUE_HCCA 0 +#define NUM_OF_PAGE_IN_FW_QUEUE_CMD 0x2 +#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT 0x10 +#define NUM_OF_PAGE_IN_FW_QUEUE_HIGH 0 +#define NUM_OF_PAGE_IN_FW_QUEUE_BCN 0x4 +#define NUM_OF_PAGE_IN_FW_QUEUE_PUB 0xd + +#define NUM_OF_PAGE_IN_FW_QUEUE_BK_DTM 0x026 +#define NUM_OF_PAGE_IN_FW_QUEUE_BE_DTM 0x048 +#define NUM_OF_PAGE_IN_FW_QUEUE_VI_DTM 0x048 +#define NUM_OF_PAGE_IN_FW_QUEUE_VO_DTM 0x026 +#define NUM_OF_PAGE_IN_FW_QUEUE_PUB_DTM 0x00 + +#define APPLIED_RESERVED_QUEUE_IN_FW 0x80000000 +#define RSVD_FW_QUEUE_PAGE_BK_SHIFT 0x00 +#define RSVD_FW_QUEUE_PAGE_BE_SHIFT 0x08 +#define RSVD_FW_QUEUE_PAGE_VI_SHIFT 0x10 +#define RSVD_FW_QUEUE_PAGE_VO_SHIFT 0x18 +#define RSVD_FW_QUEUE_PAGE_MGNT_SHIFT 0x10 +#define RSVD_FW_QUEUE_PAGE_BCN_SHIFT 0x00 +#define RSVD_FW_QUEUE_PAGE_PUB_SHIFT 0x08 + +#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0 +#define HAL_PRIME_CHNL_OFFSET_LOWER 1 +#define HAL_PRIME_CHNL_OFFSET_UPPER 2 + + +enum version_8190_loopback { + VERSION_8190_BD = 0x3, + VERSION_8190_BE +}; + +#define IC_VersionCut_C 0x2 +#define IC_VersionCut_D 0x3 +#define IC_VersionCut_E 0x4 + +enum rf_optype { + RF_OP_By_SW_3wire = 0, + RF_OP_By_FW, + RF_OP_MAX +}; + + +enum power_save_mode { + POWER_SAVE_MODE_ACTIVE, + POWER_SAVE_MODE_SAVE, +}; + +enum interface_select_8190pci { + INTF_SEL1_MINICARD = 0, + INTF_SEL0_PCIE = 1, + INTF_SEL2_RSV = 2, + INTF_SEL3_RSV = 3, +}; + +struct bb_reg_definition { + u32 rfintfs; + u32 rfintfi; + u32 rfintfo; + u32 rfintfe; + u32 rf3wireOffset; + u32 rfLSSI_Select; + u32 rfTxGainStage; + u32 rfHSSIPara1; + u32 rfHSSIPara2; + u32 rfSwitchControl; + u32 rfAGCControl1; + u32 rfAGCControl2; + u32 rfRxIQImbalance; + u32 rfRxAFE; + u32 rfTxIQImbalance; + u32 rfTxAFE; + u32 rfLSSIReadBack; + u32 rfLSSIReadBackPi; +}; + +struct tx_fwinfo { + u8 TxRate:7; + u8 CtsEnable:1; + u8 RtsRate:7; + u8 RtsEnable:1; + u8 TxHT:1; + u8 Short:1; + u8 TxBandwidth:1; + u8 TxSubCarrier:2; + u8 STBC:2; + u8 AllowAggregation:1; + u8 RtsHT:1; + u8 RtsShort:1; + u8 RtsBandwidth:1; + u8 RtsSubcarrier:2; + u8 RtsSTBC:2; + u8 EnableCPUDur:1; + + u32 RxMF:2; + u32 RxAMD:3; + u32 Reserved1:3; + u32 TxAGCOffset:4; + u32 TxAGCSign:1; + u32 Tx_INFO_RSVD:6; + u32 PacketID:13; +}; + +struct tx_fwinfo_8190pci { + u8 TxRate:7; + u8 CtsEnable:1; + u8 RtsRate:7; + u8 RtsEnable:1; + u8 TxHT:1; + u8 Short:1; + u8 TxBandwidth:1; + u8 TxSubCarrier:2; + u8 STBC:2; + u8 AllowAggregation:1; + u8 RtsHT:1; + u8 RtsShort:1; + u8 RtsBandwidth:1; + u8 RtsSubcarrier:2; + u8 RtsSTBC:2; + u8 EnableCPUDur:1; + + u32 RxMF:2; + u32 RxAMD:3; + u32 TxPerPktInfoFeedback:1; + u32 Reserved1:2; + u32 TxAGCOffset:4; + u32 TxAGCSign:1; + u32 RAW_TXD:1; + u32 Retry_Limit:4; + u32 Reserved2:1; + u32 PacketID:13; + + +}; + + +#define TX_DESC_SIZE 32 + +#define TX_DESC_CMD_SIZE 32 + + +#define TX_STATUS_DESC_SIZE 32 + +#define TX_FWINFO_SIZE 8 + + +#define RX_DESC_SIZE 16 + +#define RX_STATUS_DESC_SIZE 16 + +#define RX_DRIVER_INFO_SIZE 8 + +struct log_int_8190 { + u32 nIMR_COMDOK; + u32 nIMR_MGNTDOK; + u32 nIMR_HIGH; + u32 nIMR_VODOK; + u32 nIMR_VIDOK; + u32 nIMR_BEDOK; + u32 nIMR_BKDOK; + u32 nIMR_ROK; + u32 nIMR_RCOK; + u32 nIMR_TBDOK; + u32 nIMR_BDOK; + u32 nIMR_RXFOVW; +}; + +struct phy_ofdm_rx_status_rxsc_sgien_exintfflag { + u8 reserved:4; + u8 rxsc:2; + u8 sgi_en:1; + u8 ex_intf_flag:1; +}; + +struct phy_sts_ofdm_819xpci { + u8 trsw_gain_X[4]; + u8 pwdb_all; + u8 cfosho_X[4]; + u8 cfotail_X[4]; + u8 rxevm_X[2]; + u8 rxsnr_X[4]; + u8 pdsnr_X[2]; + u8 csi_current_X[2]; + u8 csi_target_X[2]; + u8 sigevm; + u8 max_ex_pwr; + u8 sgi_en; + u8 rxsc_sgien_exflg; +}; + +struct phy_sts_cck_819xpci { + u8 adc_pwdb_X[4]; + u8 sq_rpt; + u8 cck_agc_rpt; +}; + + +#define PHY_RSSI_SLID_WIN_MAX 100 +#define PHY_Beacon_RSSI_SLID_WIN_MAX 10 + +struct tx_desc { + u16 PktSize; + u8 Offset; + u8 Reserved1:3; + u8 CmdInit:1; + u8 LastSeg:1; + u8 FirstSeg:1; + u8 LINIP:1; + u8 OWN:1; + + u8 TxFWInfoSize; + u8 RATid:3; + u8 DISFB:1; + u8 USERATE:1; + u8 MOREFRAG:1; + u8 NoEnc:1; + u8 PIFS:1; + u8 QueueSelect:5; + u8 NoACM:1; + u8 Resv:2; + u8 SecCAMID:5; + u8 SecDescAssign:1; + u8 SecType:2; + + u16 TxBufferSize; + u8 PktId:7; + u8 Resv1:1; + u8 Reserved2; + + u32 TxBuffAddr; + + u32 NextDescAddress; + + u32 Reserved5; + u32 Reserved6; + u32 Reserved7; +}; + + +struct tx_desc_cmd { + u16 PktSize; + u8 Reserved1; + u8 CmdType:3; + u8 CmdInit:1; + u8 LastSeg:1; + u8 FirstSeg:1; + u8 LINIP:1; + u8 OWN:1; + + u16 ElementReport; + u16 Reserved2; + + u16 TxBufferSize; + u16 Reserved3; + + u32 TxBuffAddr; + u32 NextDescAddress; + u32 Reserved4; + u32 Reserved5; + u32 Reserved6; +}; + +struct rx_desc { + u16 Length:14; + u16 CRC32:1; + u16 ICV:1; + u8 RxDrvInfoSize; + u8 Shift:2; + u8 PHYStatus:1; + u8 SWDec:1; + u8 LastSeg:1; + u8 FirstSeg:1; + u8 EOR:1; + u8 OWN:1; + + u32 Reserved2; + + u32 Reserved3; + + u32 BufferAddress; + +}; + + +struct rx_fwinfo { + u16 Reserved1:12; + u16 PartAggr:1; + u16 FirstAGGR:1; + u16 Reserved2:2; + + u8 RxRate:7; + u8 RxHT:1; + + u8 BW:1; + u8 SPLCP:1; + u8 Reserved3:2; + u8 PAM:1; + u8 Mcast:1; + u8 Bcast:1; + u8 Reserved4:1; + + u32 TSFL; + +}; + +#endif diff --git a/drivers/staging/rtl8192e/r8190P_rtl8256.c b/drivers/staging/rtl8192e/r8190P_rtl8256.c new file mode 100644 index 0000000..0da56c8 --- /dev/null +++ b/drivers/staging/rtl8192e/r8190P_rtl8256.c @@ -0,0 +1,306 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> +******************************************************************************/ + +#include "rtl_core.h" +#include "r8192E_phyreg.h" +#include "r8192E_phy.h" +#include "r8190P_rtl8256.h" + +void PHY_SetRF8256Bandwidth(struct net_device *dev, + enum ht_channel_width Bandwidth) +{ + u8 eRFPath; + struct r8192_priv *priv = rtllib_priv(dev); + + for (eRFPath = 0; eRFPath < priv->NumTotalRFPath; eRFPath++) { + if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath)) + continue; + + switch (Bandwidth) { + case HT_CHANNEL_WIDTH_20: + if (priv->card_8192_version == VERSION_8190_BD || + priv->card_8192_version == VERSION_8190_BE) { + rtl8192_phy_SetRFReg(dev, + (enum rf90_radio_path)eRFPath, + 0x0b, bMask12Bits, 0x100); + rtl8192_phy_SetRFReg(dev, + (enum rf90_radio_path)eRFPath, + 0x2c, bMask12Bits, 0x3d7); + rtl8192_phy_SetRFReg(dev, + (enum rf90_radio_path)eRFPath, + 0x0e, bMask12Bits, 0x021); + + } else { + RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): " + "unknown hardware version\n"); + } + + break; + case HT_CHANNEL_WIDTH_20_40: + if (priv->card_8192_version == VERSION_8190_BD || + priv->card_8192_version == VERSION_8190_BE) { + rtl8192_phy_SetRFReg(dev, + (enum rf90_radio_path)eRFPath, + 0x0b, bMask12Bits, 0x300); + rtl8192_phy_SetRFReg(dev, + (enum rf90_radio_path)eRFPath, + 0x2c, bMask12Bits, 0x3ff); + rtl8192_phy_SetRFReg(dev, + (enum rf90_radio_path)eRFPath, + 0x0e, bMask12Bits, 0x0e1); + + } else { + RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): " + "unknown hardware version\n"); + } + + + break; + default: + RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown " + "Bandwidth: %#X\n", Bandwidth); + break; + + } + } + return; +} + +bool PHY_RF8256_Config(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + bool rtStatus = true; + priv->NumTotalRFPath = RTL819X_TOTAL_RF_PATH; + rtStatus = phy_RF8256_Config_ParaFile(dev); + + return rtStatus; +} + +bool phy_RF8256_Config_ParaFile(struct net_device *dev) +{ + u32 u4RegValue = 0; + u8 eRFPath; + bool rtStatus = true; + struct bb_reg_definition *pPhyReg; + struct r8192_priv *priv = rtllib_priv(dev); + u32 RegOffSetToBeCheck = 0x3; + u32 RegValueToBeCheck = 0x7f1; + u32 RF3_Final_Value = 0; + u8 ConstRetryTimes = 5, RetryTimes = 5; + u8 ret = 0; + + for (eRFPath = (enum rf90_radio_path)RF90_PATH_A; + eRFPath < priv->NumTotalRFPath; eRFPath++) { + if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath)) + continue; + + pPhyReg = &priv->PHYRegDef[eRFPath]; + + + switch (eRFPath) { + case RF90_PATH_A: + case RF90_PATH_C: + u4RegValue = rtl8192_QueryBBReg(dev, pPhyReg->rfintfs, + bRFSI_RFENV); + break; + case RF90_PATH_B: + case RF90_PATH_D: + u4RegValue = rtl8192_QueryBBReg(dev, pPhyReg->rfintfs, + bRFSI_RFENV<<16); + break; + } + + rtl8192_setBBreg(dev, pPhyReg->rfintfe, bRFSI_RFENV<<16, 0x1); + + rtl8192_setBBreg(dev, pPhyReg->rfintfo, bRFSI_RFENV, 0x1); + + rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, + b3WireAddressLength, 0x0); + rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, + b3WireDataLength, 0x0); + + rtl8192_phy_SetRFReg(dev, (enum rf90_radio_path) eRFPath, 0x0, + bMask12Bits, 0xbf); + + rtStatus = rtl8192_phy_checkBBAndRF(dev, HW90_BLOCK_RF, + (enum rf90_radio_path)eRFPath); + if (rtStatus != true) { + RT_TRACE(COMP_ERR, "PHY_RF8256_Config():Check " + "Radio[%d] Fail!!\n", eRFPath); + goto phy_RF8256_Config_ParaFile_Fail; + } + + RetryTimes = ConstRetryTimes; + RF3_Final_Value = 0; + switch (eRFPath) { + case RF90_PATH_A: + while (RF3_Final_Value != RegValueToBeCheck && + RetryTimes != 0) { + ret = rtl8192_phy_ConfigRFWithHeaderFile(dev, + (enum rf90_radio_path)eRFPath); + RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, + (enum rf90_radio_path)eRFPath, + RegOffSetToBeCheck, + bMask12Bits); + RT_TRACE(COMP_RF, "RF %d %d register final " + "value: %x\n", eRFPath, + RegOffSetToBeCheck, RF3_Final_Value); + RetryTimes--; + } + break; + case RF90_PATH_B: + while (RF3_Final_Value != RegValueToBeCheck && + RetryTimes != 0) { + ret = rtl8192_phy_ConfigRFWithHeaderFile(dev, + (enum rf90_radio_path)eRFPath); + RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, + (enum rf90_radio_path)eRFPath, + RegOffSetToBeCheck, + bMask12Bits); + RT_TRACE(COMP_RF, "RF %d %d register final " + "value: %x\n", eRFPath, + RegOffSetToBeCheck, RF3_Final_Value); + RetryTimes--; + } + break; + case RF90_PATH_C: + while (RF3_Final_Value != RegValueToBeCheck && + RetryTimes != 0) { + ret = rtl8192_phy_ConfigRFWithHeaderFile(dev, + (enum rf90_radio_path)eRFPath); + RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, + (enum rf90_radio_path)eRFPath, + RegOffSetToBeCheck, + bMask12Bits); + RT_TRACE(COMP_RF, "RF %d %d register final " + "value: %x\n", eRFPath, + RegOffSetToBeCheck, RF3_Final_Value); + RetryTimes--; + } + break; + case RF90_PATH_D: + while (RF3_Final_Value != RegValueToBeCheck && + RetryTimes != 0) { + ret = rtl8192_phy_ConfigRFWithHeaderFile(dev, + (enum rf90_radio_path)eRFPath); + RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, + (enum rf90_radio_path)eRFPath, + RegOffSetToBeCheck, bMask12Bits); + RT_TRACE(COMP_RF, "RF %d %d register final " + "value: %x\n", eRFPath, + RegOffSetToBeCheck, RF3_Final_Value); + RetryTimes--; + } + break; + } + + switch (eRFPath) { + case RF90_PATH_A: + case RF90_PATH_C: + rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV, + u4RegValue); + break; + case RF90_PATH_B: + case RF90_PATH_D: + rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV<<16, + u4RegValue); + break; + } + + if (ret) { + RT_TRACE(COMP_ERR, "phy_RF8256_Config_ParaFile():" + "Radio[%d] Fail!!", eRFPath); + goto phy_RF8256_Config_ParaFile_Fail; + } + + } + + RT_TRACE(COMP_PHY, "PHY Initialization Success\n") ; + return true; + +phy_RF8256_Config_ParaFile_Fail: + RT_TRACE(COMP_ERR, "PHY Initialization failed\n") ; + return false; +} + +void PHY_SetRF8256CCKTxPower(struct net_device *dev, u8 powerlevel) +{ + u32 TxAGC = 0; + struct r8192_priv *priv = rtllib_priv(dev); + + TxAGC = powerlevel; + if (priv->bDynamicTxLowPower == true) { + if (priv->CustomerID == RT_CID_819x_Netcore) + TxAGC = 0x22; + else + TxAGC += priv->CckPwEnl; + } + if (TxAGC > 0x24) + TxAGC = 0x24; + rtl8192_setBBreg(dev, rTxAGC_CCK_Mcs32, bTxAGCRateCCK, TxAGC); +} + + +void PHY_SetRF8256OFDMTxPower(struct net_device *dev, u8 powerlevel) +{ + struct r8192_priv *priv = rtllib_priv(dev); + u32 writeVal, powerBase0, powerBase1, writeVal_tmp; + u8 index = 0; + u16 RegOffset[6] = {0xe00, 0xe04, 0xe10, 0xe14, 0xe18, 0xe1c}; + u8 byte0, byte1, byte2, byte3; + + powerBase0 = powerlevel + priv->LegacyHTTxPowerDiff; + powerBase0 = (powerBase0 << 24) | (powerBase0 << 16) | + (powerBase0 << 8) | powerBase0; + powerBase1 = powerlevel; + powerBase1 = (powerBase1 << 24) | (powerBase1 << 16) | + (powerBase1 << 8) | powerBase1; + + for (index = 0; index < 6; index++) { + writeVal = (u32)(priv->MCSTxPowerLevelOriginalOffset[index] + + ((index < 2) ? powerBase0 : powerBase1)); + byte0 = (u8)(writeVal & 0x7f); + byte1 = (u8)((writeVal & 0x7f00)>>8); + byte2 = (u8)((writeVal & 0x7f0000)>>16); + byte3 = (u8)((writeVal & 0x7f000000)>>24); + if (byte0 > 0x24) + byte0 = 0x24; + if (byte1 > 0x24) + byte1 = 0x24; + if (byte2 > 0x24) + byte2 = 0x24; + if (byte3 > 0x24) + byte3 = 0x24; + + if (index == 3) { + writeVal_tmp = (byte3 << 24) | (byte2 << 16) | + (byte1 << 8) | byte0; + priv->Pwr_Track = writeVal_tmp; + } + + if (priv->bDynamicTxHighPower == true) + writeVal = 0x03030303; + else + writeVal = (byte3 << 24) | (byte2 << 16) | + (byte1 << 8) | byte0; + rtl8192_setBBreg(dev, RegOffset[index], 0x7f7f7f7f, writeVal); + } + + return; +} diff --git a/drivers/staging/rtl8192e/r8190P_rtl8256.h b/drivers/staging/rtl8192e/r8190P_rtl8256.h new file mode 100644 index 0000000..64e831d --- /dev/null +++ b/drivers/staging/rtl8192e/r8190P_rtl8256.h @@ -0,0 +1,31 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> +******************************************************************************/ + +#ifndef RTL8225H +#define RTL8225H + +#define RTL819X_TOTAL_RF_PATH 2 +extern void PHY_SetRF8256Bandwidth(struct net_device *dev, + enum ht_channel_width Bandwidth); +extern bool PHY_RF8256_Config(struct net_device *dev); +extern bool phy_RF8256_Config_ParaFile(struct net_device *dev); +extern void PHY_SetRF8256CCKTxPower(struct net_device *dev, u8 powerlevel); +extern void PHY_SetRF8256OFDMTxPower(struct net_device *dev, u8 powerlevel); + +#endif diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.c b/drivers/staging/rtl8192e/r8190_rtl8256.c deleted file mode 100644 index 286462c..0000000 --- a/drivers/staging/rtl8192e/r8190_rtl8256.c +++ /dev/null @@ -1,677 +0,0 @@ -/* - This is part of the rtl8192 driver - released under the GPL (See file COPYING for details). - - This files contains programming code for the rtl8256 - radio frontend. - - *Many* thanks to Realtek Corp. for their great support! - -*/ - -#include "r8192E.h" -#include "r8192E_hw.h" -#include "r819xE_phyreg.h" -#include "r819xE_phy.h" -#include "r8190_rtl8256.h" - -/*-------------------------------------------------------------------------- - * Overview: set RF band width (20M or 40M) - * Input: struct net_device* dev - * WIRELESS_BANDWIDTH_E Bandwidth //20M or 40M - * Output: NONE - * Return: NONE - * Note: 8226 support both 20M and 40 MHz - *---------------------------------------------------------------------------*/ -void PHY_SetRF8256Bandwidth(struct r8192_priv *priv, HT_CHANNEL_WIDTH Bandwidth) //20M or 40M -{ - u8 eRFPath; - - //for(eRFPath = RF90_PATH_A; eRFPath <pHalData->NumTotalRFPath; eRFPath++) - for(eRFPath = 0; eRFPath <priv->NumTotalRFPath; eRFPath++) - { - if (!rtl8192_phy_CheckIsLegalRFPath(priv, eRFPath)) - continue; - - switch(Bandwidth) - { - case HT_CHANNEL_WIDTH_20: - if(priv->card_8192_version == VERSION_8190_BD || priv->card_8192_version == VERSION_8190_BE)// 8256 D-cut, E-cut, xiong: consider it later! - { - rtl8192_phy_SetRFReg(priv, (RF90_RADIO_PATH_E)eRFPath, 0x0b, bMask12Bits, 0x100); //phy para:1ba - rtl8192_phy_SetRFReg(priv, (RF90_RADIO_PATH_E)eRFPath, 0x2c, bMask12Bits, 0x3d7); - rtl8192_phy_SetRFReg(priv, (RF90_RADIO_PATH_E)eRFPath, 0x0e, bMask12Bits, 0x021); - - //cosa add for sd3's request 01/23/2008 - //rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x14, bMask12Bits, 0x5ab); - } - else - { - RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown hardware version\n"); - } - - break; - case HT_CHANNEL_WIDTH_20_40: - if(priv->card_8192_version == VERSION_8190_BD ||priv->card_8192_version == VERSION_8190_BE)// 8256 D-cut, E-cut, xiong: consider it later! - { - rtl8192_phy_SetRFReg(priv, (RF90_RADIO_PATH_E)eRFPath, 0x0b, bMask12Bits, 0x300); //phy para:3ba - rtl8192_phy_SetRFReg(priv, (RF90_RADIO_PATH_E)eRFPath, 0x2c, bMask12Bits, 0x3ff); - rtl8192_phy_SetRFReg(priv, (RF90_RADIO_PATH_E)eRFPath, 0x0e, bMask12Bits, 0x0e1); - - } - else - { - RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown hardware version\n"); - } - - - break; - default: - RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown Bandwidth: %#X\n",Bandwidth ); - break; - - } - } -} -/*-------------------------------------------------------------------------- - * Overview: Interface to config 8256 - * Input: struct net_device* dev - * Output: NONE - * Return: NONE - *---------------------------------------------------------------------------*/ -RT_STATUS PHY_RF8256_Config(struct r8192_priv *priv) -{ - // Initialize general global value - // - RT_STATUS rtStatus = RT_STATUS_SUCCESS; - // TODO: Extend RF_PATH_C and RF_PATH_D in the future - priv->NumTotalRFPath = RTL819X_TOTAL_RF_PATH; - // Config BB and RF - rtStatus = phy_RF8256_Config_ParaFile(priv); - - return rtStatus; -} - -/*-------------------------------------------------------------------------- - * Overview: Interface to config 8256 - * Input: struct net_device* dev - * Output: NONE - * Return: NONE - *---------------------------------------------------------------------------*/ -RT_STATUS phy_RF8256_Config_ParaFile(struct r8192_priv *priv) -{ - u32 u4RegValue = 0; - u8 eRFPath; - RT_STATUS rtStatus = RT_STATUS_SUCCESS; - BB_REGISTER_DEFINITION_T *pPhyReg; - u32 RegOffSetToBeCheck = 0x3; - u32 RegValueToBeCheck = 0x7f1; - u32 RF3_Final_Value = 0; - u8 ConstRetryTimes = 5, RetryTimes = 5; - u8 ret = 0; - - //3//----------------------------------------------------------------- - //3// <2> Initialize RF - //3//----------------------------------------------------------------- - for(eRFPath = (RF90_RADIO_PATH_E)RF90_PATH_A; eRFPath <priv->NumTotalRFPath; eRFPath++) - { - if (!rtl8192_phy_CheckIsLegalRFPath(priv, eRFPath)) - continue; - - pPhyReg = &priv->PHYRegDef[eRFPath]; - - /*----Store original RFENV control type----*/ - switch(eRFPath) - { - case RF90_PATH_A: - case RF90_PATH_C: - u4RegValue = rtl8192_QueryBBReg(priv, pPhyReg->rfintfs, bRFSI_RFENV); - break; - case RF90_PATH_B : - case RF90_PATH_D: - u4RegValue = rtl8192_QueryBBReg(priv, pPhyReg->rfintfs, bRFSI_RFENV<<16); - break; - } - - /*----Set RF_ENV enable----*/ - rtl8192_setBBreg(priv, pPhyReg->rfintfe, bRFSI_RFENV<<16, 0x1); - - /*----Set RF_ENV output high----*/ - rtl8192_setBBreg(priv, pPhyReg->rfintfo, bRFSI_RFENV, 0x1); - - /* Set bit number of Address and Data for RF register */ - rtl8192_setBBreg(priv, pPhyReg->rfHSSIPara2, b3WireAddressLength, 0x0); // Set 0 to 4 bits for Z-serial and set 1 to 6 bits for 8258 - rtl8192_setBBreg(priv, pPhyReg->rfHSSIPara2, b3WireDataLength, 0x0); // Set 0 to 12 bits for Z-serial and 8258, and set 1 to 14 bits for ??? - - rtl8192_phy_SetRFReg(priv, (RF90_RADIO_PATH_E) eRFPath, 0x0, bMask12Bits, 0xbf); - - /*----Check RF block (for FPGA platform only)----*/ - // TODO: this function should be removed on ASIC , Emily 2007.2.2 - rtStatus = rtl8192_phy_checkBBAndRF(priv, HW90_BLOCK_RF, (RF90_RADIO_PATH_E)eRFPath); - if(rtStatus!= RT_STATUS_SUCCESS) - { - RT_TRACE(COMP_ERR, "PHY_RF8256_Config():Check Radio[%d] Fail!!\n", eRFPath); - goto phy_RF8256_Config_ParaFile_Fail; - } - - RetryTimes = ConstRetryTimes; - RF3_Final_Value = 0; - /*----Initialize RF fom connfiguration file----*/ - switch(eRFPath) - { - case RF90_PATH_A: - while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0) - { - ret = rtl8192_phy_ConfigRFWithHeaderFile(priv,(RF90_RADIO_PATH_E)eRFPath); - RF3_Final_Value = rtl8192_phy_QueryRFReg(priv, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits); - RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value); - RetryTimes--; - } - break; - case RF90_PATH_B: - while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0) - { - ret = rtl8192_phy_ConfigRFWithHeaderFile(priv,(RF90_RADIO_PATH_E)eRFPath); - RF3_Final_Value = rtl8192_phy_QueryRFReg(priv, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits); - RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value); - RetryTimes--; - } - break; - case RF90_PATH_C: - while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0) - { - ret = rtl8192_phy_ConfigRFWithHeaderFile(priv,(RF90_RADIO_PATH_E)eRFPath); - RF3_Final_Value = rtl8192_phy_QueryRFReg(priv, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits); - RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value); - RetryTimes--; - } - break; - case RF90_PATH_D: - while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0) - { - ret = rtl8192_phy_ConfigRFWithHeaderFile(priv,(RF90_RADIO_PATH_E)eRFPath); - RF3_Final_Value = rtl8192_phy_QueryRFReg(priv, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits); - RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value); - RetryTimes--; - } - break; - } - - /*----Restore RFENV control type----*/; - switch(eRFPath) - { - case RF90_PATH_A: - case RF90_PATH_C: - rtl8192_setBBreg(priv, pPhyReg->rfintfs, bRFSI_RFENV, u4RegValue); - break; - case RF90_PATH_B : - case RF90_PATH_D: - rtl8192_setBBreg(priv, pPhyReg->rfintfs, bRFSI_RFENV<<16, u4RegValue); - break; - } - - if(ret){ - RT_TRACE(COMP_ERR, "phy_RF8256_Config_ParaFile():Radio[%d] Fail!!", eRFPath); - goto phy_RF8256_Config_ParaFile_Fail; - } - - } - - RT_TRACE(COMP_PHY, "PHY Initialization Success\n") ; - return RT_STATUS_SUCCESS; - -phy_RF8256_Config_ParaFile_Fail: - RT_TRACE(COMP_ERR, "PHY Initialization failed\n") ; - return RT_STATUS_FAILURE; -} - - -void PHY_SetRF8256CCKTxPower(struct r8192_priv *priv, u8 powerlevel) -{ - u32 TxAGC=0; - - TxAGC = powerlevel; - if(priv->bDynamicTxLowPower == true)//cosa 04282008 for cck long range - { - if(priv->CustomerID == RT_CID_819x_Netcore) - TxAGC = 0x22; - else - TxAGC += priv->CckPwEnl; - } - if(TxAGC > 0x24) - TxAGC = 0x24; - rtl8192_setBBreg(priv, rTxAGC_CCK_Mcs32, bTxAGCRateCCK, TxAGC); -} - - -void PHY_SetRF8256OFDMTxPower(struct r8192_priv *priv, u8 powerlevel) -{ - - u32 writeVal, powerBase0, powerBase1, writeVal_tmp; - u8 index = 0; - u16 RegOffset[6] = {0xe00, 0xe04, 0xe10, 0xe14, 0xe18, 0xe1c}; - u8 byte0, byte1, byte2, byte3; - - powerBase0 = powerlevel + priv->LegacyHTTxPowerDiff; //OFDM rates - powerBase0 = (powerBase0<<24) | (powerBase0<<16) |(powerBase0<<8) |powerBase0; - powerBase1 = powerlevel; //MCS rates - powerBase1 = (powerBase1<<24) | (powerBase1<<16) |(powerBase1<<8) |powerBase1; - - for(index=0; index<6; index++) - { - writeVal = priv->MCSTxPowerLevelOriginalOffset[index] + ((index<2)?powerBase0:powerBase1); - byte0 = (u8)(writeVal & 0x7f); - byte1 = (u8)((writeVal & 0x7f00)>>8); - byte2 = (u8)((writeVal & 0x7f0000)>>16); - byte3 = (u8)((writeVal & 0x7f000000)>>24); - if(byte0 > 0x24) // Max power index = 0x24 - byte0 = 0x24; - if(byte1 > 0x24) - byte1 = 0x24; - if(byte2 > 0x24) - byte2 = 0x24; - if(byte3 > 0x24) - byte3 = 0x24; - - if(index == 3) - { - writeVal_tmp = (byte3<<24) | (byte2<<16) |(byte1<<8) |byte0; - priv->Pwr_Track = writeVal_tmp; - } - - if(priv->bDynamicTxHighPower == true) //Add by Jacken 2008/03/06 //when DM implement, add this - { - writeVal = 0x03030303; - } - else - { - writeVal = (byte3<<24) | (byte2<<16) |(byte1<<8) |byte0; - } - rtl8192_setBBreg(priv, RegOffset[index], 0x7f7f7f7f, writeVal); - } -} - -#define MAX_DOZE_WAITING_TIMES_9x 64 -static void r8192e_drain_tx_queues(struct r8192_priv *priv) -{ - u8 i, QueueID; - - for (QueueID = 0, i = 0; QueueID < MAX_TX_QUEUE; ) - { - struct rtl8192_tx_ring *ring = &priv->tx_ring[QueueID]; - - if(skb_queue_len(&ring->queue) == 0) - { - QueueID++; - continue; - } - - udelay(10); - i++; - - if (i >= MAX_DOZE_WAITING_TIMES_9x) - { - RT_TRACE(COMP_POWER, "r8192e_drain_tx_queues() timeout queue %d\n", QueueID); - break; - } - } -} - -static bool SetRFPowerState8190(struct r8192_priv *priv, - RT_RF_POWER_STATE eRFPowerState) -{ - PRT_POWER_SAVE_CONTROL pPSC = &priv->PowerSaveControl; - bool bResult = true; - - if (eRFPowerState == priv->eRFPowerState && - priv->bHwRfOffAction == 0) { - bResult = false; - goto out; - } - - switch( eRFPowerState ) - { - case eRfOn: - - // turn on RF - if ((priv->eRFPowerState == eRfOff) && - RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC)) - { - /* - * The current RF state is OFF and the RF OFF level - * is halting the NIC, re-initialize the NIC. - */ - if (!NicIFEnableNIC(priv)) { - RT_TRACE(COMP_ERR, "%s(): NicIFEnableNIC failed\n",__FUNCTION__); - bResult = false; - goto out; - } - - RT_CLEAR_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC); - } else { - write_nic_byte(priv, ANAPAR, 0x37);//160MHz - mdelay(1); - //enable clock 80/88 MHz - rtl8192_setBBreg(priv, rFPGA0_AnalogParameter1, 0x4, 0x1); // 0x880[2] - priv->bHwRfOffAction = 0; - - //RF-A, RF-B - //enable RF-Chip A/B - rtl8192_setBBreg(priv, rFPGA0_XA_RFInterfaceOE, BIT4, 0x1); // 0x860[4] - //analog to digital on - rtl8192_setBBreg(priv, rFPGA0_AnalogParameter4, 0x300, 0x3);// 0x88c[9:8] - //digital to analog on - rtl8192_setBBreg(priv, rFPGA0_AnalogParameter1, 0x18, 0x3); // 0x880[4:3] - //rx antenna on - rtl8192_setBBreg(priv, rOFDM0_TRxPathEnable, 0x3, 0x3);// 0xc04[1:0] - //rx antenna on - rtl8192_setBBreg(priv, rOFDM1_TRxPathEnable, 0x3, 0x3);// 0xd04[1:0] - //analog to digital part2 on - rtl8192_setBBreg(priv, rFPGA0_AnalogParameter1, 0x60, 0x3); // 0x880[6:5] - - } - - break; - - // - // In current solution, RFSleep=RFOff in order to save power under 802.11 power save. - // By Bruce, 2008-01-16. - // - case eRfSleep: - - // HW setting had been configured with deeper mode. - if(priv->eRFPowerState == eRfOff) - break; - - r8192e_drain_tx_queues(priv); - - PHY_SetRtl8192eRfOff(priv); - - break; - - case eRfOff: - - // - // Disconnect with Any AP or STA. - // - r8192e_drain_tx_queues(priv); - - - if (pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_HALT_NIC && !RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC)) - { - /* Disable all components. */ - NicIFDisableNIC(priv); - RT_SET_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC); - } - else if (!(pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_HALT_NIC)) - { - /* Normal case - IPS should go to this. */ - PHY_SetRtl8192eRfOff(priv); - } - break; - - default: - bResult = false; - RT_TRACE(COMP_ERR, "SetRFPowerState8190(): unknow state to set: 0x%X!!!\n", eRFPowerState); - break; - } - - if(bResult) - { - // Update current RF state variable. - priv->eRFPowerState = eRFPowerState; - } - -out: - return bResult; -} - - - - - -static void MgntDisconnectIBSS(struct r8192_priv *priv) -{ - u8 i; - bool bFilterOutNonAssociatedBSSID = false; - - priv->ieee80211->state = IEEE80211_NOLINK; - - for(i=0;i<6;i++) priv->ieee80211->current_network.bssid[i]= 0x55; - priv->OpMode = RT_OP_MODE_NO_LINK; - write_nic_word(priv, BSSIDR, ((u16*)priv->ieee80211->current_network.bssid)[0]); - write_nic_dword(priv, BSSIDR+2, ((u32*)(priv->ieee80211->current_network.bssid+2))[0]); - { - RT_OP_MODE OpMode = priv->OpMode; - u8 btMsr = read_nic_byte(priv, MSR); - - btMsr &= 0xfc; - - switch(OpMode) - { - case RT_OP_MODE_INFRASTRUCTURE: - btMsr |= MSR_LINK_MANAGED; - break; - - case RT_OP_MODE_IBSS: - btMsr |= MSR_LINK_ADHOC; - // led link set separate - break; - - case RT_OP_MODE_AP: - btMsr |= MSR_LINK_MASTER; - break; - - default: - btMsr |= MSR_LINK_NONE; - break; - } - - write_nic_byte(priv, MSR, btMsr); - } - ieee80211_stop_send_beacons(priv->ieee80211); - - // If disconnect, clear RCR CBSSID bit - bFilterOutNonAssociatedBSSID = false; - { - u32 RegRCR, Type; - Type = bFilterOutNonAssociatedBSSID; - RegRCR = read_nic_dword(priv, RCR); - priv->ReceiveConfig = RegRCR; - if (Type == true) - RegRCR |= (RCR_CBSSID); - else if (Type == false) - RegRCR &= (~RCR_CBSSID); - - { - write_nic_dword(priv, RCR, RegRCR); - priv->ReceiveConfig = RegRCR; - } - - } - notify_wx_assoc_event(priv->ieee80211); - -} - -static void MlmeDisassociateRequest(struct r8192_priv *priv, u8 *asSta, - u8 asRsn) -{ - u8 i; - - RemovePeerTS(priv->ieee80211, asSta); - - SendDisassociation( priv->ieee80211, asSta, asRsn ); - - if(memcpy(priv->ieee80211->current_network.bssid,asSta,6) == NULL) - { - //ShuChen TODO: change media status. - //ShuChen TODO: What to do when disassociate. - priv->ieee80211->state = IEEE80211_NOLINK; - for(i=0;i<6;i++) priv->ieee80211->current_network.bssid[i] = 0x22; - priv->OpMode = RT_OP_MODE_NO_LINK; - { - RT_OP_MODE OpMode = priv->OpMode; - u8 btMsr = read_nic_byte(priv, MSR); - - btMsr &= 0xfc; - - switch(OpMode) - { - case RT_OP_MODE_INFRASTRUCTURE: - btMsr |= MSR_LINK_MANAGED; - break; - - case RT_OP_MODE_IBSS: - btMsr |= MSR_LINK_ADHOC; - // led link set separate - break; - - case RT_OP_MODE_AP: - btMsr |= MSR_LINK_MASTER; - break; - - default: - btMsr |= MSR_LINK_NONE; - break; - } - - write_nic_byte(priv, MSR, btMsr); - } - ieee80211_disassociate(priv->ieee80211); - - write_nic_word(priv, BSSIDR, ((u16*)priv->ieee80211->current_network.bssid)[0]); - write_nic_dword(priv, BSSIDR+2, ((u32*)(priv->ieee80211->current_network.bssid+2))[0]); - - } - -} - - -static void MgntDisconnectAP(struct r8192_priv *priv, u8 asRsn) -{ - bool bFilterOutNonAssociatedBSSID = false; - u32 RegRCR, Type; - - /* If disconnect, clear RCR CBSSID bit */ - bFilterOutNonAssociatedBSSID = false; - - Type = bFilterOutNonAssociatedBSSID; - RegRCR = read_nic_dword(priv, RCR); - priv->ReceiveConfig = RegRCR; - - if (Type == true) - RegRCR |= (RCR_CBSSID); - else if (Type == false) - RegRCR &= (~RCR_CBSSID); - - write_nic_dword(priv, RCR, RegRCR); - priv->ReceiveConfig = RegRCR; - - MlmeDisassociateRequest(priv, priv->ieee80211->current_network.bssid, asRsn); - - priv->ieee80211->state = IEEE80211_NOLINK; -} - - -static bool MgntDisconnect(struct r8192_priv *priv, u8 asRsn) -{ - // In adhoc mode, update beacon frame. - if( priv->ieee80211->state == IEEE80211_LINKED ) - { - if( priv->ieee80211->iw_mode == IW_MODE_ADHOC ) - { - MgntDisconnectIBSS(priv); - } - if( priv->ieee80211->iw_mode == IW_MODE_INFRA ) - { - // We clear key here instead of MgntDisconnectAP() because that - // MgntActSet_802_11_DISASSOCIATE() is an interface called by OS, - // e.g. OID_802_11_DISASSOCIATE in Windows while as MgntDisconnectAP() is - // used to handle disassociation related things to AP, e.g. send Disassoc - // frame to AP. 2005.01.27, by rcnjko. - MgntDisconnectAP(priv, asRsn); - } - } - - return true; -} - -// -// Description: -// Chang RF Power State. -// Note that, only MgntActSet_RF_State() is allowed to set HW_VAR_RF_STATE. -// -// Assumption: -// PASSIVE LEVEL. -// -bool MgntActSet_RF_State(struct r8192_priv *priv, RT_RF_POWER_STATE StateToSet, - RT_RF_CHANGE_SOURCE ChangeSource) -{ - bool bActionAllowed = false; - bool bConnectBySSID = false; - RT_RF_POWER_STATE rtState; - - RT_TRACE(COMP_POWER, "===>MgntActSet_RF_State(): StateToSet(%d)\n",StateToSet); - - spin_lock(&priv->rf_ps_lock); - - rtState = priv->eRFPowerState; - - switch(StateToSet) - { - case eRfOn: - priv->RfOffReason &= (~ChangeSource); - - if (!priv->RfOffReason) - { - priv->RfOffReason = 0; - bActionAllowed = true; - - - if(rtState == eRfOff && ChangeSource >=RF_CHANGE_BY_HW ) - { - bConnectBySSID = true; - } - } - else - RT_TRACE(COMP_POWER, "MgntActSet_RF_State - eRfon reject pMgntInfo->RfOffReason= 0x%x, ChangeSource=0x%X\n", priv->RfOffReason, ChangeSource); - - break; - - case eRfOff: - - if (priv->RfOffReason > RF_CHANGE_BY_IPS) - { - // Disconnect to current BSS when radio off. Asked by QuanTa. - MgntDisconnect(priv, disas_lv_ss); - } - - priv->RfOffReason |= ChangeSource; - bActionAllowed = true; - break; - - case eRfSleep: - priv->RfOffReason |= ChangeSource; - bActionAllowed = true; - break; - } - - if (bActionAllowed) - { - RT_TRACE(COMP_POWER, "MgntActSet_RF_State(): Action is allowed.... StateToSet(%d), RfOffReason(%#X)\n", StateToSet, priv->RfOffReason); - // Config HW to the specified mode. - SetRFPowerState8190(priv, StateToSet); - } - else - { - RT_TRACE(COMP_POWER, "MgntActSet_RF_State(): Action is rejected.... StateToSet(%d), ChangeSource(%#X), RfOffReason(%#X)\n", StateToSet, ChangeSource, priv->RfOffReason); - } - - // Release RF spinlock - spin_unlock(&priv->rf_ps_lock); - - RT_TRACE(COMP_POWER, "<===MgntActSet_RF_State()\n"); - return bActionAllowed; -} - - diff --git a/drivers/staging/rtl8192e/r8190_rtl8256.h b/drivers/staging/rtl8192e/r8190_rtl8256.h deleted file mode 100644 index 58f9290..0000000 --- a/drivers/staging/rtl8192e/r8190_rtl8256.h +++ /dev/null @@ -1,29 +0,0 @@ -/* r8190_rtl8256.h - rtl8256 radio frontend - * - * This is part of the rtl8180-sa2400 driver - * released under the GPL (See file COPYING for details). - * Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it> - * - * Many thanks to Realtek Corp. for their great support! - */ - -#ifndef RTL8225_H -#define RTL8225_H - -#define RTL819X_TOTAL_RF_PATH 2 /* for 8192E */ - -void PHY_SetRF8256Bandwidth(struct r8192_priv *priv, - HT_CHANNEL_WIDTH Bandwidth); - -RT_STATUS PHY_RF8256_Config(struct r8192_priv *priv); - -RT_STATUS phy_RF8256_Config_ParaFile(struct r8192_priv *priv); - -void PHY_SetRF8256CCKTxPower(struct r8192_priv *priv, u8 powerlevel); -void PHY_SetRF8256OFDMTxPower(struct r8192_priv *priv, u8 powerlevel); - -bool MgntActSet_RF_State(struct r8192_priv *priv, - RT_RF_POWER_STATE StateToSet, - RT_RF_CHANGE_SOURCE ChangeSource); - -#endif /* RTL8225_H */ diff --git a/drivers/staging/rtl8192e/r8192E.h b/drivers/staging/rtl8192e/r8192E.h deleted file mode 100644 index 137f66b..0000000 --- a/drivers/staging/rtl8192e/r8192E.h +++ /dev/null @@ -1,1148 +0,0 @@ -/* - This is part of rtl8187 OpenSource driver. - Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it> - Released under the terms of GPL (General Public Licence) - - Parts of this driver are based on the GPL part of the - official realtek driver - - Parts of this driver are based on the rtl8192 driver skeleton - from Patric Schenke & Andres Salomon - - Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver - - We want to tanks the Authors of those projects and the Ndiswrapper - project Authors. -*/ - -#ifndef R819xU_H -#define R819xU_H - -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/init.h> -#include <linux/ioport.h> -#include <linux/sched.h> -#include <linux/types.h> -#include <linux/slab.h> -#include <linux/netdevice.h> -#include <linux/pci.h> -#include <linux/etherdevice.h> -#include <linux/delay.h> -#include <linux/rtnetlink.h> //for rtnl_lock() -#include <linux/wireless.h> -#include <linux/timer.h> -#include <linux/proc_fs.h> // Necessary because we use the proc fs -#include <linux/if_arp.h> -#include <linux/random.h> -#include <linux/interrupt.h> -#include <asm/io.h> -#include "ieee80211/rtl819x_HT.h" -#include "ieee80211/ieee80211.h" - - - - -#define RTL819xE_MODULE_NAME "rtl819xE" - -#define FALSE 0 -#define TRUE 1 -#define MAX_KEY_LEN 61 -#define KEY_BUF_SIZE 5 - -#define BIT0 0x00000001 -#define BIT1 0x00000002 -#define BIT2 0x00000004 -#define BIT3 0x00000008 -#define BIT4 0x00000010 -#define BIT5 0x00000020 -#define BIT6 0x00000040 -#define BIT7 0x00000080 -#define BIT8 0x00000100 -#define BIT9 0x00000200 -#define BIT10 0x00000400 -#define BIT11 0x00000800 -#define BIT12 0x00001000 -#define BIT13 0x00002000 -#define BIT14 0x00004000 -#define BIT15 0x00008000 -#define BIT16 0x00010000 -#define BIT17 0x00020000 -#define BIT18 0x00040000 -#define BIT19 0x00080000 -#define BIT20 0x00100000 -#define BIT21 0x00200000 -#define BIT22 0x00400000 -#define BIT23 0x00800000 -#define BIT24 0x01000000 -#define BIT25 0x02000000 -#define BIT26 0x04000000 -#define BIT27 0x08000000 -#define BIT28 0x10000000 -#define BIT29 0x20000000 -#define BIT30 0x40000000 -#define BIT31 0x80000000 -// Rx smooth factor -#define Rx_Smooth_Factor 20 -/* 2007/06/04 MH Define sliding window for RSSI history. */ -#define PHY_RSSI_SLID_WIN_MAX 100 -#define PHY_Beacon_RSSI_SLID_WIN_MAX 10 - -#define IC_VersionCut_D 0x3 -#define IC_VersionCut_E 0x4 - -#if 0 //we need to use RT_TRACE instead DMESG as RT_TRACE will clearly show debug level wb. -#define DMESG(x,a...) printk(KERN_INFO RTL819xE_MODULE_NAME ": " x "\n", ## a) -#else -#define DMESG(x,a...) -extern u32 rt_global_debug_component; -#define RT_TRACE(component, x, args...) \ -do { if(rt_global_debug_component & component) \ - printk(KERN_DEBUG RTL819xE_MODULE_NAME ":" x , \ - ##args);\ -}while(0); - -#define COMP_TRACE BIT0 // For function call tracing. -#define COMP_DBG BIT1 // Only for temporary debug message. -#define COMP_INIT BIT2 // during driver initialization / halt / reset. - - -#define COMP_RECV BIT3 // Reveive part data path. -#define COMP_SEND BIT4 // Send part path. -#define COMP_IO BIT5 // I/O Related. Added by Annie, 2006-03-02. -#define COMP_POWER BIT6 // 802.11 Power Save mode or System/Device Power state related. -#define COMP_EPROM BIT7 // 802.11 link related: join/start BSS, leave BSS. -#define COMP_SWBW BIT8 // For bandwidth switch. -#define COMP_SEC BIT9// For Security. - - -#define COMP_TURBO BIT10 // For Turbo Mode related. By Annie, 2005-10-21. -#define COMP_QOS BIT11 // For QoS. - -#define COMP_RATE BIT12 // For Rate Adaptive mechanism, 2006.07.02, by rcnjko. #define COMP_EVENTS 0x00000080 // Event handling -#define COMP_RXDESC BIT13 // Show Rx desc information for SD3 debug. Added by Annie, 2006-07-15. -#define COMP_PHY BIT14 -#define COMP_DIG BIT15 // For DIG, 2006.09.25, by rcnjko. -#define COMP_TXAGC BIT16 // For Tx power, 060928, by rcnjko. -#define COMP_HALDM BIT17 // For HW Dynamic Mechanism, 061010, by rcnjko. -#define COMP_POWER_TRACKING BIT18 //FOR 8190 TX POWER TRACKING -#define COMP_EVENTS BIT19 // Event handling - -#define COMP_RF BIT20 // For RF. - -/* 11n or 8190 specific code should be put below this line */ - - -#define COMP_FIRMWARE BIT21 //for firmware downloading -#define COMP_HT BIT22 // For 802.11n HT related information. by Emily 2006-8-11 - -#define COMP_RESET BIT23 -#define COMP_CMDPKT BIT24 -#define COMP_SCAN BIT25 -#define COMP_IPS BIT26 -#define COMP_DOWN BIT27 // for rm driver module -#define COMP_INTR BIT28 // for interrupt -#define COMP_ERR BIT31 // for error out, always on -#endif - - -// -// Queue Select Value in TxDesc -// -#define QSLT_BK 0x1 -#define QSLT_BE 0x0 -#define QSLT_VI 0x4 -#define QSLT_VO 0x6 -#define QSLT_BEACON 0x10 -#define QSLT_HIGH 0x11 -#define QSLT_MGNT 0x12 -#define QSLT_CMD 0x13 - -#define DESC90_RATE1M 0x00 -#define DESC90_RATE2M 0x01 -#define DESC90_RATE5_5M 0x02 -#define DESC90_RATE11M 0x03 -#define DESC90_RATE6M 0x04 -#define DESC90_RATE9M 0x05 -#define DESC90_RATE12M 0x06 -#define DESC90_RATE18M 0x07 -#define DESC90_RATE24M 0x08 -#define DESC90_RATE36M 0x09 -#define DESC90_RATE48M 0x0a -#define DESC90_RATE54M 0x0b -#define DESC90_RATEMCS0 0x00 -#define DESC90_RATEMCS1 0x01 -#define DESC90_RATEMCS2 0x02 -#define DESC90_RATEMCS3 0x03 -#define DESC90_RATEMCS4 0x04 -#define DESC90_RATEMCS5 0x05 -#define DESC90_RATEMCS6 0x06 -#define DESC90_RATEMCS7 0x07 -#define DESC90_RATEMCS8 0x08 -#define DESC90_RATEMCS9 0x09 -#define DESC90_RATEMCS10 0x0a -#define DESC90_RATEMCS11 0x0b -#define DESC90_RATEMCS12 0x0c -#define DESC90_RATEMCS13 0x0d -#define DESC90_RATEMCS14 0x0e -#define DESC90_RATEMCS15 0x0f -#define DESC90_RATEMCS32 0x20 - -#define RTL819X_DEFAULT_RF_TYPE RF_1T2R -#define EEPROM_Default_LegacyHTTxPowerDiff 0x4 -#define IEEE80211_WATCH_DOG_TIME 2000 - -typedef u32 RT_RF_CHANGE_SOURCE; -#define RF_CHANGE_BY_SW BIT31 -#define RF_CHANGE_BY_HW BIT30 -#define RF_CHANGE_BY_PS BIT29 -#define RF_CHANGE_BY_IPS BIT28 -#define RF_CHANGE_BY_INIT 0 // Do not change the RFOff reason. Defined by Bruce, 2008-01-17. - -// RF state. -typedef enum _RT_RF_POWER_STATE { - eRfOn, - eRfSleep, - eRfOff -} RT_RF_POWER_STATE; - -typedef enum _RT_JOIN_ACTION { - RT_JOIN_INFRA = 1, - RT_JOIN_IBSS = 2, - RT_START_IBSS = 3, - RT_NO_ACTION = 4, -} RT_JOIN_ACTION; - -typedef enum _IPS_CALLBACK_FUNCION { - IPS_CALLBACK_NONE = 0, - IPS_CALLBACK_MGNT_LINK_REQUEST = 1, - IPS_CALLBACK_JOIN_REQUEST = 2, -} IPS_CALLBACK_FUNCION; - -typedef struct _RT_POWER_SAVE_CONTROL { - /* Inactive Power Save(IPS) : Disable RF when disconnected */ - bool bInactivePs; - bool bIPSModeBackup; - bool bSwRfProcessing; - RT_RF_POWER_STATE eInactivePowerState; - struct work_struct InactivePsWorkItem; - struct timer_list InactivePsTimer; - - /* Return point for join action */ - IPS_CALLBACK_FUNCION ReturnPoint; - - /* Recored Parameters for rescheduled JoinRequest */ - bool bTmpBssDesc; - RT_JOIN_ACTION tmpJoinAction; - struct ieee80211_network tmpBssDesc; - - /* Recored Parameters for rescheduled MgntLinkRequest */ - bool bTmpScanOnly; - bool bTmpActiveScan; - bool bTmpFilterHiddenAP; - bool bTmpUpdateParms; - u8 tmpSsidBuf[33]; - OCTET_STRING tmpSsid2Scan; - bool bTmpSsid2Scan; - u8 tmpNetworkType; - u8 tmpChannelNumber; - u16 tmpBcnPeriod; - u8 tmpDtimPeriod; - u16 tmpmCap; - OCTET_STRING tmpSuppRateSet; - u8 tmpSuppRateBuf[MAX_NUM_RATES]; - bool bTmpSuppRate; - IbssParms tmpIbpm; - bool bTmpIbpm; - - /* - * Leisure Power Save: - * Disable RF if connected but traffic is not busy - */ - bool bLeisurePs; - u32 PowerProfile; - u8 LpsIdleCount; - - u32 CurPsLevel; - u32 RegRfPsLevel; - - bool bFwCtrlLPS; - u8 FWCtrlPSMode; - - bool LinkReqInIPSRFOffPgs; - bool BufConnectinfoBefore; -} RT_POWER_SAVE_CONTROL, *PRT_POWER_SAVE_CONTROL; - -/* For rtl819x */ -typedef struct _tx_desc_819x_pci { - //DWORD 0 - u16 PktSize; - u8 Offset; - u8 Reserved1:3; - u8 CmdInit:1; - u8 LastSeg:1; - u8 FirstSeg:1; - u8 LINIP:1; - u8 OWN:1; - - //DWORD 1 - u8 TxFWInfoSize; - u8 RATid:3; - u8 DISFB:1; - u8 USERATE:1; - u8 MOREFRAG:1; - u8 NoEnc:1; - u8 PIFS:1; - u8 QueueSelect:5; - u8 NoACM:1; - u8 Resv:2; - u8 SecCAMID:5; - u8 SecDescAssign:1; - u8 SecType:2; - - //DWORD 2 - u16 TxBufferSize; - u8 PktId:7; - u8 Resv1:1; - u8 Reserved2; - - //DWORD 3 - u32 TxBuffAddr; - - //DWORD 4 - u32 NextDescAddress; - - //DWORD 5,6,7 - u32 Reserved5; - u32 Reserved6; - u32 Reserved7; -}tx_desc_819x_pci, *ptx_desc_819x_pci; - - -typedef struct _tx_desc_cmd_819x_pci { - //DWORD 0 - u16 PktSize; - u8 Reserved1; - u8 CmdType:3; - u8 CmdInit:1; - u8 LastSeg:1; - u8 FirstSeg:1; - u8 LINIP:1; - u8 OWN:1; - - //DOWRD 1 - u16 ElementReport; - u16 Reserved2; - - //DOWRD 2 - u16 TxBufferSize; - u16 Reserved3; - - //DWORD 3,4,5 - u32 TxBufferAddr; - u32 NextDescAddress; - u32 Reserved4; - u32 Reserved5; - u32 Reserved6; -}tx_desc_cmd_819x_pci, *ptx_desc_cmd_819x_pci; - - -typedef struct _tx_fwinfo_819x_pci { - //DOWRD 0 - u8 TxRate:7; - u8 CtsEnable:1; - u8 RtsRate:7; - u8 RtsEnable:1; - u8 TxHT:1; - u8 Short:1; //Short PLCP for CCK, or short GI for 11n MCS - u8 TxBandwidth:1; // This is used for HT MCS rate only. - u8 TxSubCarrier:2; // This is used for legacy OFDM rate only. - u8 STBC:2; - u8 AllowAggregation:1; - u8 RtsHT:1; //Interpre RtsRate field as high throughput data rate - u8 RtsShort:1; //Short PLCP for CCK, or short GI for 11n MCS - u8 RtsBandwidth:1; // This is used for HT MCS rate only. - u8 RtsSubcarrier:2; // This is used for legacy OFDM rate only. - u8 RtsSTBC:2; - u8 EnableCPUDur:1; //Enable firmware to recalculate and assign packet duration - - //DWORD 1 - u8 RxMF:2; - u8 RxAMD:3; - u8 Reserved1:3; - u8 Reserved2; - u8 Reserved3; - u8 Reserved4; - - //u32 Reserved; -}tx_fwinfo_819x_pci, *ptx_fwinfo_819x_pci; - -typedef struct _rx_desc_819x_pci{ - //DOWRD 0 - u16 Length:14; - u16 CRC32:1; - u16 ICV:1; - u8 RxDrvInfoSize; - u8 Shift:2; - u8 PHYStatus:1; - u8 SWDec:1; - u8 LastSeg:1; - u8 FirstSeg:1; - u8 EOR:1; - u8 OWN:1; - - //DWORD 1 - u32 Reserved2; - - //DWORD 2 - u32 Reserved3; - - //DWORD 3 - u32 BufferAddress; - -}rx_desc_819x_pci, *prx_desc_819x_pci; - -typedef struct _rx_fwinfo_819x_pci{ - //DWORD 0 - u16 Reserved1:12; - u16 PartAggr:1; - u16 FirstAGGR:1; - u16 Reserved2:2; - - u8 RxRate:7; - u8 RxHT:1; - - u8 BW:1; - u8 SPLCP:1; - u8 Reserved3:2; - u8 PAM:1; - u8 Mcast:1; - u8 Bcast:1; - u8 Reserved4:1; - - //DWORD 1 - u32 TSFL; - -}rx_fwinfo_819x_pci, *prx_fwinfo_819x_pci; - -#define MAX_DEV_ADDR_SIZE 8 /* support till 64 bit bus width OS */ -#define MAX_FIRMWARE_INFORMATION_SIZE 32 /*2006/04/30 by Emily forRTL8190*/ -#define MAX_802_11_HEADER_LENGTH (40 + MAX_FIRMWARE_INFORMATION_SIZE) -#define ENCRYPTION_MAX_OVERHEAD 128 -#define MAX_FRAGMENT_COUNT 8 -#define MAX_TRANSMIT_BUFFER_SIZE (1600+(MAX_802_11_HEADER_LENGTH+ENCRYPTION_MAX_OVERHEAD)*MAX_FRAGMENT_COUNT) - -#define scrclng 4 // octets for crc32 (FCS, ICV) -/* 8190 Loopback Mode definition */ -typedef enum _rtl819x_loopback{ - RTL819X_NO_LOOPBACK = 0, - RTL819X_MAC_LOOPBACK = 1, - RTL819X_DMA_LOOPBACK = 2, - RTL819X_CCK_LOOPBACK = 3, -}rtl819x_loopback_e; - -/* due to rtl8192 firmware */ -typedef enum _desc_packet_type_e{ - DESC_PACKET_TYPE_INIT = 0, - DESC_PACKET_TYPE_NORMAL = 1, -}desc_packet_type_e; - -typedef enum _firmware_status{ - FW_STATUS_0_INIT = 0, - FW_STATUS_1_MOVE_BOOT_CODE = 1, - FW_STATUS_2_MOVE_MAIN_CODE = 2, - FW_STATUS_3_TURNON_CPU = 3, - FW_STATUS_4_MOVE_DATA_CODE = 4, - FW_STATUS_5_READY = 5, -}firmware_status_e; - -typedef struct _rt_firmware{ - firmware_status_e firmware_status; - u16 cmdpacket_frag_thresold; -#define RTL8190_MAX_FIRMWARE_CODE_SIZE 64000 //64k -#define MAX_FW_INIT_STEP 3 - u8 firmware_buf[MAX_FW_INIT_STEP][RTL8190_MAX_FIRMWARE_CODE_SIZE]; - u16 firmware_buf_size[MAX_FW_INIT_STEP]; -}rt_firmware, *prt_firmware; - -#define MAX_RECEIVE_BUFFER_SIZE 9100 // Add this to 9100 bytes to receive A-MSDU from RT-AP - -/* Firmware Queue Layout */ -#define NUM_OF_FIRMWARE_QUEUE 10 -#define NUM_OF_PAGES_IN_FW 0x100 -#define NUM_OF_PAGE_IN_FW_QUEUE_BE 0x0aa -#define NUM_OF_PAGE_IN_FW_QUEUE_BK 0x007 -#define NUM_OF_PAGE_IN_FW_QUEUE_VI 0x024 -#define NUM_OF_PAGE_IN_FW_QUEUE_VO 0x007 -#define NUM_OF_PAGE_IN_FW_QUEUE_HCCA 0 -#define NUM_OF_PAGE_IN_FW_QUEUE_CMD 0x2 -#define NUM_OF_PAGE_IN_FW_QUEUE_MGNT 0x10 -#define NUM_OF_PAGE_IN_FW_QUEUE_HIGH 0 -#define NUM_OF_PAGE_IN_FW_QUEUE_BCN 0x4 -#define NUM_OF_PAGE_IN_FW_QUEUE_PUB 0xd -#define APPLIED_RESERVED_QUEUE_IN_FW 0x80000000 -#define RSVD_FW_QUEUE_PAGE_BK_SHIFT 0x00 -#define RSVD_FW_QUEUE_PAGE_BE_SHIFT 0x08 -#define RSVD_FW_QUEUE_PAGE_VI_SHIFT 0x10 -#define RSVD_FW_QUEUE_PAGE_VO_SHIFT 0x18 -#define RSVD_FW_QUEUE_PAGE_MGNT_SHIFT 0x10 -#define RSVD_FW_QUEUE_PAGE_CMD_SHIFT 0x08 -#define RSVD_FW_QUEUE_PAGE_BCN_SHIFT 0x00 -#define RSVD_FW_QUEUE_PAGE_PUB_SHIFT 0x08 - -#define DCAM 0xAC // Debug CAM Interface -#define AESMSK_FC 0xB2 // AES Mask register for frame control (0xB2~0xB3). Added by Annie, 2006-03-06. - - -#define CAM_CONTENT_COUNT 8 -#define CFG_VALID BIT15 -#define EPROM_93c46 0 -#define EPROM_93c56 1 - -#define DEFAULT_FRAG_THRESHOLD 2342U -#define MIN_FRAG_THRESHOLD 256U -#define DEFAULT_BEACONINTERVAL 0x64U - -#define DEFAULT_RETRY_RTS 7 -#define DEFAULT_RETRY_DATA 7 - -#define PHY_RSSI_SLID_WIN_MAX 100 - - -typedef enum _WIRELESS_MODE { - WIRELESS_MODE_UNKNOWN = 0x00, - WIRELESS_MODE_A = 0x01, - WIRELESS_MODE_B = 0x02, - WIRELESS_MODE_G = 0x04, - WIRELESS_MODE_AUTO = 0x08, - WIRELESS_MODE_N_24G = 0x10, - WIRELESS_MODE_N_5G = 0x20 -} WIRELESS_MODE; - -#define RTL_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30 - -typedef struct buffer -{ - struct buffer *next; - u32 *buf; - dma_addr_t dma; - -} buffer; - -typedef struct _rt_9x_tx_rate_history { - u32 cck[4]; - u32 ofdm[8]; - // HT_MCS[0][]: BW=0 SG=0 - // HT_MCS[1][]: BW=1 SG=0 - // HT_MCS[2][]: BW=0 SG=1 - // HT_MCS[3][]: BW=1 SG=1 - u32 ht_mcs[4][16]; -}rt_tx_rahis_t, *prt_tx_rahis_t; - -typedef struct _RT_SMOOTH_DATA_4RF { - char elements[4][100];//array to store values - u32 index; //index to current array to store - u32 TotalNum; //num of valid elements - u32 TotalVal[4]; //sum of valid elements -}RT_SMOOTH_DATA_4RF, *PRT_SMOOTH_DATA_4RF; - -typedef enum _tag_TxCmd_Config_Index{ - TXCMD_TXRA_HISTORY_CTRL = 0xFF900000, - TXCMD_RESET_TX_PKT_BUFF = 0xFF900001, - TXCMD_RESET_RX_PKT_BUFF = 0xFF900002, - TXCMD_SET_TX_DURATION = 0xFF900003, - TXCMD_SET_RX_RSSI = 0xFF900004, - TXCMD_SET_TX_PWR_TRACKING = 0xFF900005, - TXCMD_XXXX_CTRL, -}DCMD_TXCMD_OP; - -typedef struct Stats -{ - unsigned long rxrdu; - unsigned long rxok; - unsigned long received_rate_histogram[4][32]; //0: Total, 1:OK, 2:CRC, 3:ICV - unsigned long rxoverflow; - unsigned long rxint; - unsigned long txoverflow; - unsigned long txbeokint; - unsigned long txbkokint; - unsigned long txviokint; - unsigned long txvookint; - unsigned long txbeaconokint; - unsigned long txbeaconerr; - unsigned long txmanageokint; - unsigned long txcmdpktokint; - unsigned long txfeedback; - unsigned long txfeedbackok; - unsigned long txoktotal; - unsigned long txbytesunicast; - unsigned long rxbytesunicast; - - unsigned long slide_signal_strength[100]; - unsigned long slide_evm[100]; - unsigned long slide_rssi_total; // For recording sliding window's RSSI value - unsigned long slide_evm_total; // For recording sliding window's EVM value - long signal_strength; // Transformed, in dbm. Beautified signal strength for UI, not correct. - u8 rx_rssi_percentage[4]; - u8 rx_evm_percentage[2]; - u32 Slide_Beacon_pwdb[100]; - u32 Slide_Beacon_Total; - RT_SMOOTH_DATA_4RF cck_adc_pwdb; -} Stats; - - -// Bandwidth Offset -#define HAL_PRIME_CHNL_OFFSET_DONT_CARE 0 -#define HAL_PRIME_CHNL_OFFSET_LOWER 1 -#define HAL_PRIME_CHNL_OFFSET_UPPER 2 - -typedef struct ChnlAccessSetting { - u16 SIFS_Timer; - u16 DIFS_Timer; - u16 SlotTimeTimer; - u16 EIFS_Timer; - u16 CWminIndex; - u16 CWmaxIndex; -}*PCHANNEL_ACCESS_SETTING,CHANNEL_ACCESS_SETTING; - -typedef struct _BB_REGISTER_DEFINITION{ - u32 rfintfs; // set software control: // 0x870~0x877[8 bytes] - u32 rfintfi; // readback data: // 0x8e0~0x8e7[8 bytes] - u32 rfintfo; // output data: // 0x860~0x86f [16 bytes] - u32 rfintfe; // output enable: // 0x860~0x86f [16 bytes] - u32 rf3wireOffset; // LSSI data: // 0x840~0x84f [16 bytes] - u32 rfLSSI_Select; // BB Band Select: // 0x878~0x87f [8 bytes] - u32 rfTxGainStage; // Tx gain stage: // 0x80c~0x80f [4 bytes] - u32 rfHSSIPara1; // wire parameter control1 : // 0x820~0x823,0x828~0x82b, 0x830~0x833, 0x838~0x83b [16 bytes] - u32 rfHSSIPara2; // wire parameter control2 : // 0x824~0x827,0x82c~0x82f, 0x834~0x837, 0x83c~0x83f [16 bytes] - u32 rfSwitchControl; //Tx Rx antenna control : // 0x858~0x85f [16 bytes] - u32 rfAGCControl1; //AGC parameter control1 : // 0xc50~0xc53,0xc58~0xc5b, 0xc60~0xc63, 0xc68~0xc6b [16 bytes] - u32 rfAGCControl2; //AGC parameter control2 : // 0xc54~0xc57,0xc5c~0xc5f, 0xc64~0xc67, 0xc6c~0xc6f [16 bytes] - u32 rfRxIQImbalance; //OFDM Rx IQ imbalance matrix : // 0xc14~0xc17,0xc1c~0xc1f, 0xc24~0xc27, 0xc2c~0xc2f [16 bytes] - u32 rfRxAFE; //Rx IQ DC ofset and Rx digital filter, Rx DC notch filter : // 0xc10~0xc13,0xc18~0xc1b, 0xc20~0xc23, 0xc28~0xc2b [16 bytes] - u32 rfTxIQImbalance; //OFDM Tx IQ imbalance matrix // 0xc80~0xc83,0xc88~0xc8b, 0xc90~0xc93, 0xc98~0xc9b [16 bytes] - u32 rfTxAFE; //Tx IQ DC Offset and Tx DFIR type // 0xc84~0xc87,0xc8c~0xc8f, 0xc94~0xc97, 0xc9c~0xc9f [16 bytes] - u32 rfLSSIReadBack; //LSSI RF readback data // 0x8a0~0x8af [16 bytes] -}BB_REGISTER_DEFINITION_T, *PBB_REGISTER_DEFINITION_T; - -typedef struct _rate_adaptive -{ - u8 rate_adaptive_disabled; - u8 ratr_state; - u16 reserve; - - u32 high_rssi_thresh_for_ra; - u32 high2low_rssi_thresh_for_ra; - u8 low2high_rssi_thresh_for_ra40M; - u32 low_rssi_thresh_for_ra40M; - u8 low2high_rssi_thresh_for_ra20M; - u32 low_rssi_thresh_for_ra20M; - u32 upper_rssi_threshold_ratr; - u32 middle_rssi_threshold_ratr; - u32 low_rssi_threshold_ratr; - u32 low_rssi_threshold_ratr_40M; - u32 low_rssi_threshold_ratr_20M; - u8 ping_rssi_enable; //cosa add for test - u32 ping_rssi_ratr; //cosa add for test - u32 ping_rssi_thresh_for_ra;//cosa add for test - u32 last_ratr; - -} rate_adaptive, *prate_adaptive; -#define TxBBGainTableLength 37 -#define CCKTxBBGainTableLength 23 -typedef struct _txbbgain_struct -{ - long txbb_iq_amplifygain; - u32 txbbgain_value; -} txbbgain_struct, *ptxbbgain_struct; - -typedef struct _ccktxbbgain_struct -{ - //The Value is from a22 to a29 one Byte one time is much Safer - u8 ccktxbb_valuearray[8]; -} ccktxbbgain_struct,*pccktxbbgain_struct; - - -typedef struct _init_gain -{ - u8 xaagccore1; - u8 xbagccore1; - u8 xcagccore1; - u8 xdagccore1; - u8 cca; - -} init_gain, *pinit_gain; - -/* 2007/11/02 MH Define RF mode temporarily for test. */ -typedef enum tag_Rf_Operatetion_State -{ - RF_STEP_INIT = 0, - RF_STEP_NORMAL, - RF_STEP_MAX -}RF_STEP_E; - -typedef enum _RT_STATUS{ - RT_STATUS_SUCCESS, - RT_STATUS_FAILURE, - RT_STATUS_PENDING, - RT_STATUS_RESOURCE -}RT_STATUS,*PRT_STATUS; - -typedef enum _RT_CUSTOMER_ID -{ - RT_CID_DEFAULT = 0, - RT_CID_8187_ALPHA0 = 1, - RT_CID_8187_SERCOMM_PS = 2, - RT_CID_8187_HW_LED = 3, - RT_CID_8187_NETGEAR = 4, - RT_CID_WHQL = 5, - RT_CID_819x_CAMEO = 6, - RT_CID_819x_RUNTOP = 7, - RT_CID_819x_Senao = 8, - RT_CID_TOSHIBA = 9, // Merge by Jacken, 2008/01/31. - RT_CID_819x_Netcore = 10, - RT_CID_Nettronix = 11, - RT_CID_DLINK = 12, - RT_CID_PRONET = 13, - RT_CID_COREGA = 14, -}RT_CUSTOMER_ID, *PRT_CUSTOMER_ID; - -/* LED customization. */ - -typedef enum _LED_STRATEGY_8190{ - SW_LED_MODE0, // SW control 1 LED via GPIO0. It is default option. - SW_LED_MODE1, // SW control for PCI Express - SW_LED_MODE2, // SW control for Cameo. - SW_LED_MODE3, // SW contorl for RunTop. - SW_LED_MODE4, // SW control for Netcore - SW_LED_MODE5, //added by vivi, for led new mode, DLINK - SW_LED_MODE6, //added by vivi, for led new mode, PRONET - HW_LED, // HW control 2 LEDs, LED0 and LED1 (there are 4 different control modes) -}LED_STRATEGY_8190, *PLED_STRATEGY_8190; - -#define CHANNEL_PLAN_LEN 10 - -#define sCrcLng 4 - -typedef struct _TX_FWINFO_STRUCUTRE{ - //DOWRD 0 - u8 TxRate:7; - u8 CtsEnable:1; - u8 RtsRate:7; - u8 RtsEnable:1; - u8 TxHT:1; - u8 Short:1; - u8 TxBandwidth:1; - u8 TxSubCarrier:2; - u8 STBC:2; - u8 AllowAggregation:1; - u8 RtsHT:1; - u8 RtsShort:1; - u8 RtsBandwidth:1; - u8 RtsSubcarrier:2; - u8 RtsSTBC:2; - u8 EnableCPUDur:1; - - //DWORD 1 - u32 RxMF:2; - u32 RxAMD:3; - u32 Reserved1:3; - u32 TxAGCOffset:4; - u32 TxAGCSign:1; - u32 Tx_INFO_RSVD:6; - u32 PacketID:13; -}TX_FWINFO_T; - - -typedef struct _TX_FWINFO_8190PCI{ - //DOWRD 0 - u8 TxRate:7; - u8 CtsEnable:1; - u8 RtsRate:7; - u8 RtsEnable:1; - u8 TxHT:1; - u8 Short:1; //Short PLCP for CCK, or short GI for 11n MCS - u8 TxBandwidth:1; // This is used for HT MCS rate only. - u8 TxSubCarrier:2; // This is used for legacy OFDM rate only. - u8 STBC:2; - u8 AllowAggregation:1; - u8 RtsHT:1; //Interpre RtsRate field as high throughput data rate - u8 RtsShort:1; //Short PLCP for CCK, or short GI for 11n MCS - u8 RtsBandwidth:1; // This is used for HT MCS rate only. - u8 RtsSubcarrier:2; // This is used for legacy OFDM rate only. - u8 RtsSTBC:2; - u8 EnableCPUDur:1; //Enable firmware to recalculate and assign packet duration - - //DWORD 1 - u32 RxMF:2; - u32 RxAMD:3; - u32 TxPerPktInfoFeedback:1; // 1: indicate that the transimission info of this packet should be gathered by Firmware and retured by Rx Cmd. - u32 Reserved1:2; - u32 TxAGCOffset:4; // Only 90 support - u32 TxAGCSign:1; // Only 90 support - u32 RAW_TXD:1; // MAC will send data in txpktbuffer without any processing,such as CRC check - u32 Retry_Limit:4; // CCX Support relative retry limit FW page only support 4 bits now. - u32 Reserved2:1; - u32 PacketID:13; - - // DW 2 - -}TX_FWINFO_8190PCI, *PTX_FWINFO_8190PCI; - -typedef struct _phy_ofdm_rx_status_report_819xpci -{ - u8 trsw_gain_X[4]; - u8 pwdb_all; - u8 cfosho_X[4]; - u8 cfotail_X[4]; - u8 rxevm_X[2]; - u8 rxsnr_X[4]; - u8 pdsnr_X[2]; - u8 csi_current_X[2]; - u8 csi_target_X[2]; - u8 sigevm; - u8 max_ex_pwr; - u8 sgi_en; - u8 rxsc_sgien_exflg; -}phy_sts_ofdm_819xpci_t; - -typedef struct _phy_cck_rx_status_report_819xpci -{ - /* For CCK rate descriptor. This is a unsigned 8:1 variable. LSB bit presend - 0.5. And MSB 7 bts presend a signed value. Range from -64~+63.5. */ - u8 adc_pwdb_X[4]; - u8 sq_rpt; - u8 cck_agc_rpt; -}phy_sts_cck_819xpci_t; - -typedef struct _phy_ofdm_rx_status_rxsc_sgien_exintfflag{ - u8 reserved:4; - u8 rxsc:2; - u8 sgi_en:1; - u8 ex_intf_flag:1; -}phy_ofdm_rx_status_rxsc_sgien_exintfflag; - -typedef enum _RT_OP_MODE{ - RT_OP_MODE_AP, - RT_OP_MODE_INFRASTRUCTURE, - RT_OP_MODE_IBSS, - RT_OP_MODE_NO_LINK, -}RT_OP_MODE, *PRT_OP_MODE; - - -/* 2007/11/02 MH Define RF mode temporarily for test. */ -typedef enum tag_Rf_OpType -{ - RF_OP_By_SW_3wire = 0, - RF_OP_By_FW, - RF_OP_MAX -}RF_OpType_E; - -typedef enum _RESET_TYPE { - RESET_TYPE_NORESET = 0x00, - RESET_TYPE_NORMAL = 0x01, - RESET_TYPE_SILENT = 0x02 -} RESET_TYPE; - -typedef struct _tx_ring{ - u32 * desc; - u8 nStuckCount; - struct _tx_ring * next; -}__attribute__ ((packed)) tx_ring, * ptx_ring; - -struct rtl8192_tx_ring { - tx_desc_819x_pci *desc; - dma_addr_t dma; - unsigned int idx; - unsigned int entries; - struct sk_buff_head queue; -}; - -#define NIC_SEND_HANG_THRESHOLD_NORMAL 4 -#define NIC_SEND_HANG_THRESHOLD_POWERSAVE 8 -#define MAX_TX_QUEUE 9 // BK, BE, VI, VO, HCCA, MANAGEMENT, COMMAND, HIGH, BEACON. - -#define MAX_RX_COUNT 64 -#define MAX_TX_QUEUE_COUNT 9 - -typedef struct r8192_priv -{ - struct pci_dev *pdev; - u8 *mem_start; - - /* maintain info from eeprom */ - short epromtype; - u16 eeprom_vid; - u16 eeprom_did; - u8 eeprom_CustomerID; - u16 eeprom_ChannelPlan; - RT_CUSTOMER_ID CustomerID; - u8 IC_Cut; - int irq; - struct ieee80211_device *ieee80211; -#ifdef ENABLE_LPS - bool ps_force; - bool force_lps; - bool bdisable_nic; -#endif - bool being_init_adapter; - u8 Rf_Mode; - u8 card_8192_version; /* if TCR reports card V B/C this discriminates */ - spinlock_t irq_th_lock; - spinlock_t rf_ps_lock; - struct mutex mutex; - - short chan; - short sens; - /* RX stuff */ - rx_desc_819x_pci *rx_ring; - dma_addr_t rx_ring_dma; - unsigned int rx_idx; - struct sk_buff *rx_buf[MAX_RX_COUNT]; - int rxringcount; - u16 rxbuffersize; - - /* TX stuff */ - struct rtl8192_tx_ring tx_ring[MAX_TX_QUEUE_COUNT]; - int txringcount; - - struct tasklet_struct irq_rx_tasklet; - struct tasklet_struct irq_tx_tasklet; - struct tasklet_struct irq_prepare_beacon_tasklet; - - short up; - short crcmon; //if 1 allow bad crc frame reception in monitor mode - struct semaphore wx_sem; - struct semaphore rf_sem; //used to lock rf write operation added by wb, modified by david - u8 rf_type; /* 0 means 1T2R, 1 means 2T4R */ - - short (*rf_set_sens)(struct net_device *dev, short sens); - u8 (*rf_set_chan)(struct ieee80211_device *ieee80211, u8 ch); - short promisc; - /* stats */ - struct Stats stats; - struct iw_statistics wstats; - struct proc_dir_entry *dir_dev; - struct ieee80211_rx_stats previous_stats; - - /* RX stuff */ - struct sk_buff_head skb_queue; - struct work_struct qos_activate; - - //2 Tx Related variables - u16 ShortRetryLimit; - u16 LongRetryLimit; - - u32 LastRxDescTSFHigh; - u32 LastRxDescTSFLow; - - - //2 Rx Related variables - u32 ReceiveConfig; - - u8 retry_data; - u8 retry_rts; - - struct work_struct reset_wq; - u8 rx_chk_cnt; - -//for rtl819xPci - // Data Rate Config. Added by Annie, 2006-04-13. - u16 basic_rate; - u8 short_preamble; - u8 slot_time; - u16 SifsTime; -/* WirelessMode*/ - u8 RegWirelessMode; -/*Firmware*/ - prt_firmware pFirmware; - rtl819x_loopback_e LoopbackMode; - bool AutoloadFailFlag; - u16 EEPROMAntPwDiff; // Antenna gain offset from B/C/D to A - u8 EEPROMThermalMeter; - u8 EEPROMCrystalCap; - u8 EEPROMTxPowerLevelCCK[14];// CCK channel 1~14 - // The following definition is for eeprom 93c56 - u8 EEPROMRfACCKChnl1TxPwLevel[3]; //RF-A CCK Tx Power Level at channel 7 - u8 EEPROMRfAOfdmChnlTxPwLevel[3];//RF-A CCK Tx Power Level at [0],[1],[2] = channel 1,7,13 - u8 EEPROMRfCCCKChnl1TxPwLevel[3]; //RF-C CCK Tx Power Level at channel 7 - u8 EEPROMRfCOfdmChnlTxPwLevel[3];//RF-C CCK Tx Power Level at [0],[1],[2] = channel 1,7,13 - u8 EEPROMTxPowerLevelOFDM24G[14]; // OFDM 2.4G channel 1~14 - u8 EEPROMLegacyHTTxPowerDiff; // Legacy to HT rate power diff - bool bTXPowerDataReadFromEEPORM; -/*channel plan*/ - u16 RegChannelPlan; // Channel Plan specifed by user, 15: following setting of EEPROM, 0-14: default channel plan index specified by user. - u16 ChannelPlan; -/*PS related*/ - // Rf off action for power save - u8 bHwRfOffAction; //0:No action, 1:By GPIO, 2:By Disable -/*PHY related*/ - BB_REGISTER_DEFINITION_T PHYRegDef[4]; //Radio A/B/C/D - // Read/write are allow for following hardware information variables - u32 MCSTxPowerLevelOriginalOffset[6]; - u32 CCKTxPowerLevelOriginalOffset; - u8 TxPowerLevelCCK[14]; // CCK channel 1~14 - u8 TxPowerLevelCCK_A[14]; // RF-A, CCK channel 1~14 - u8 TxPowerLevelCCK_C[14]; - u8 TxPowerLevelOFDM24G[14]; // OFDM 2.4G channel 1~14 - u8 TxPowerLevelOFDM5G[14]; // OFDM 5G - u8 TxPowerLevelOFDM24G_A[14]; // RF-A, OFDM 2.4G channel 1~14 - u8 TxPowerLevelOFDM24G_C[14]; // RF-C, OFDM 2.4G channel 1~14 - u8 LegacyHTTxPowerDiff; // Legacy to HT rate power diff - u8 AntennaTxPwDiff[3]; // Antenna gain offset, index 0 for B, 1 for C, and 2 for D - u8 CrystalCap; // CrystalCap. - u8 ThermalMeter[2]; // ThermalMeter, index 0 for RFIC0, and 1 for RFIC1 - //05/27/2008 cck power enlarge - u8 CckPwEnl; - u16 TSSI_13dBm; - u32 Pwr_Track; - u8 CCKPresentAttentuation_20Mdefault; - u8 CCKPresentAttentuation_40Mdefault; - char CCKPresentAttentuation_difference; - char CCKPresentAttentuation; - // Use to calculate PWBD. - RT_RF_POWER_STATE eRFPowerState; - RT_RF_CHANGE_SOURCE RfOffReason; - RT_POWER_SAVE_CONTROL PowerSaveControl; - u8 bCckHighPower; - long undecorated_smoothed_pwdb; - long undecorated_smoothed_cck_adc_pwdb[4]; - //for set channel - u8 SwChnlInProgress; - u8 SwChnlStage; - u8 SwChnlStep; - u8 SetBWModeInProgress; - HT_CHANNEL_WIDTH CurrentChannelBW; - - // 8190 40MHz mode - // - u8 nCur40MhzPrimeSC; // Control channel sub-carrier - // Joseph test for shorten RF configuration time. - // We save RF reg0 in this variable to reduce RF reading. - // - u32 RfReg0Value[4]; - u8 NumTotalRFPath; - bool brfpath_rxenable[4]; -//+by amy 080507 - struct timer_list watch_dog_timer; - u8 watchdog_last_time; - u8 watchdog_check_reset_cnt; - -//+by amy 080515 for dynamic mechenism - //Add by amy Tx Power Control for Near/Far Range 2008/05/15 - bool bDynamicTxHighPower; // Tx high power state - bool bDynamicTxLowPower; // Tx low power state - bool bLastDTPFlag_High; - bool bLastDTPFlag_Low; - - /* OFDM RSSI. For high power or not */ - u8 phy_check_reg824; - u32 phy_reg824_bit9; - - //Add by amy for Rate Adaptive - rate_adaptive rate_adaptive; - //Add by amy for TX power tracking - //2008/05/15 Mars OPEN/CLOSE TX POWER TRACKING - const txbbgain_struct * txbbgain_table; - u8 txpower_count;//For 6 sec do tracking again - bool btxpower_trackingInit; - u8 OFDM_index; - u8 CCK_index; - u8 Record_CCK_20Mindex; - u8 Record_CCK_40Mindex; - //2007/09/10 Mars Add CCK TX Power Tracking - const ccktxbbgain_struct *cck_txbbgain_table; - const ccktxbbgain_struct *cck_txbbgain_ch14_table; - u8 rfa_txpowertrackingindex; - u8 rfa_txpowertrackingindex_real; - u8 rfa_txpowertracking_default; - u8 rfc_txpowertrackingindex; - u8 rfc_txpowertrackingindex_real; - u8 rfc_txpowertracking_default; - bool btxpower_tracking; - bool bcck_in_ch14; - - //For Backup Initial Gain - init_gain initgain_backup; - u8 DefaultInitialGain[4]; - // For EDCA Turbo mode, Added by amy 080515. - bool bis_any_nonbepkts; - bool bcurrent_turbo_EDCA; - - bool bis_cur_rdlstate; - struct timer_list fsync_timer; - u32 rate_record; - u32 rateCountDiffRecord; - u32 ContiuneDiffCount; - bool bswitch_fsync; - - u8 framesync; - u32 framesyncC34; - u8 framesyncMonitor; - - //by amy for gpio - bool bHwRadioOff; - //by amy for ps - RT_OP_MODE OpMode; - //by amy for reset_count - u32 reset_count; - - //by amy for silent reset - RESET_TYPE ResetProgress; - bool bForcedSilentReset; - bool bDisableNormalResetCheck; - u16 TxCounter; - u16 RxCounter; - int IrpPendingCount; - bool bResetInProgress; - bool force_reset; - u8 InitialGainOperateType; - - //define work item by amy 080526 - struct delayed_work update_beacon_wq; - struct delayed_work watch_dog_wq; - struct delayed_work txpower_tracking_wq; - struct delayed_work rfpath_check_wq; - struct delayed_work gpio_change_rf_wq; - struct delayed_work initialgain_operate_wq; - struct workqueue_struct *priv_wq; -}r8192_priv; - -bool init_firmware(struct r8192_priv *priv); -u32 read_cam(struct r8192_priv *priv, u8 addr); -void write_cam(struct r8192_priv *priv, u8 addr, u32 data); -u8 read_nic_byte(struct r8192_priv *priv, int x); -u32 read_nic_dword(struct r8192_priv *priv, int x); -u16 read_nic_word(struct r8192_priv *priv, int x) ; -void write_nic_byte(struct r8192_priv *priv, int x,u8 y); -void write_nic_word(struct r8192_priv *priv, int x,u16 y); -void write_nic_dword(struct r8192_priv *priv, int x,u32 y); - -int rtl8192_down(struct net_device *dev); -int rtl8192_up(struct net_device *dev); -void rtl8192_commit(struct r8192_priv *priv); -void write_phy(struct net_device *dev, u8 adr, u8 data); -void CamResetAllEntry(struct r8192_priv *priv); -void EnableHWSecurityConfig8192(struct r8192_priv *priv); -void setKey(struct r8192_priv *priv, u8 EntryNo, u8 KeyIndex, u16 KeyType, - const u8 *MacAddr, u8 DefaultKey, u32 *KeyContent); -void firmware_init_param(struct r8192_priv *priv); -RT_STATUS cmpk_message_handle_tx(struct r8192_priv *priv, u8 *codevirtualaddress, u32 packettype, u32 buffer_len); - -#ifdef ENABLE_IPS -void IPSEnter(struct r8192_priv *priv); -void IPSLeave(struct r8192_priv *priv); -void IPSLeave_wq(struct work_struct *work); -void ieee80211_ips_leave_wq(struct ieee80211_device *ieee80211); -void ieee80211_ips_leave(struct ieee80211_device *ieee80211); -#endif -#ifdef ENABLE_LPS -void LeisurePSEnter(struct ieee80211_device *ieee80211); -void LeisurePSLeave(struct ieee80211_device *ieee80211); -#endif - -bool NicIFEnableNIC(struct r8192_priv *priv); -bool NicIFDisableNIC(struct r8192_priv *priv); - -void PHY_SetRtl8192eRfOff(struct r8192_priv *priv); -#endif diff --git a/drivers/staging/rtl8192e/r8192E_cmdpkt.c b/drivers/staging/rtl8192e/r8192E_cmdpkt.c new file mode 100644 index 0000000..09978b6 --- /dev/null +++ b/drivers/staging/rtl8192e/r8192E_cmdpkt.c @@ -0,0 +1,420 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> +******************************************************************************/ + +#include "rtl_core.h" +#include "r8192E_hw.h" +#include "r8192E_cmdpkt.h" +/*---------------------------Define Local Constant---------------------------*/ +/* Debug constant*/ +#define CMPK_DEBOUNCE_CNT 1 +#define CMPK_PRINT(Address)\ +{\ + unsigned char i;\ + u32 temp[10];\ + \ + memcpy(temp, Address, 40);\ + for (i = 0; i < 40; i += 4)\ + printk(KERN_INFO "\r\n %08x", temp[i]);\ +} + +/*---------------------------Define functions---------------------------------*/ +bool cmpk_message_handle_tx( + struct net_device *dev, + u8 *code_virtual_address, + u32 packettype, + u32 buffer_len) +{ + + bool rt_status = true; + struct r8192_priv *priv = rtllib_priv(dev); + u16 frag_threshold; + u16 frag_length = 0, frag_offset = 0; + struct rt_firmware *pfirmware = priv->pFirmware; + struct sk_buff *skb; + unsigned char *seg_ptr; + struct cb_desc *tcb_desc; + u8 bLastIniPkt; + + struct tx_fwinfo_8190pci *pTxFwInfo = NULL; + + RT_TRACE(COMP_CMDPKT, "%s(),buffer_len is %d\n", __func__, buffer_len); + firmware_init_param(dev); + frag_threshold = pfirmware->cmdpacket_frag_thresold; + + do { + if ((buffer_len - frag_offset) > frag_threshold) { + frag_length = frag_threshold ; + bLastIniPkt = 0; + + } else { + frag_length = (u16)(buffer_len - frag_offset); + bLastIniPkt = 1; + } + + skb = dev_alloc_skb(frag_length + + priv->rtllib->tx_headroom + 4); + + if (skb == NULL) { + rt_status = false; + goto Failed; + } + + memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev)); + tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); + tcb_desc->queue_index = TXCMD_QUEUE; + tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_NORMAL; + tcb_desc->bLastIniPkt = bLastIniPkt; + tcb_desc->pkt_size = frag_length; + + seg_ptr = skb_put(skb, priv->rtllib->tx_headroom); + pTxFwInfo = (struct tx_fwinfo_8190pci *)seg_ptr; + memset(pTxFwInfo, 0, sizeof(struct tx_fwinfo_8190pci)); + memset(pTxFwInfo, 0x12, 8); + + seg_ptr = skb_put(skb, frag_length); + memcpy(seg_ptr, code_virtual_address, (u32)frag_length); + + priv->rtllib->softmac_hard_start_xmit(skb, dev); + + code_virtual_address += frag_length; + frag_offset += frag_length; + + } while (frag_offset < buffer_len); + + write_nic_byte(dev, TPPoll, TPPoll_CQ); +Failed: + return rt_status; +} /* CMPK_Message_Handle_Tx */ + +static void +cmpk_count_txstatistic( + struct net_device *dev, + struct cmpk_txfb *pstx_fb) +{ + struct r8192_priv *priv = rtllib_priv(dev); +#ifdef ENABLE_PS + enum rt_rf_power_state rtState; + + pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, + (pu1Byte)(&rtState)); + + if (rtState == eRfOff) + return; +#endif + + if (pstx_fb->tok) { + priv->stats.txfeedbackok++; + priv->stats.txoktotal++; + priv->stats.txokbytestotal += pstx_fb->pkt_length; + priv->stats.txokinperiod++; + + if (pstx_fb->pkt_type == PACKET_MULTICAST) { + priv->stats.txmulticast++; + priv->stats.txbytesmulticast += pstx_fb->pkt_length; + } else if (pstx_fb->pkt_type == PACKET_BROADCAST) { + priv->stats.txbroadcast++; + priv->stats.txbytesbroadcast += pstx_fb->pkt_length; + } else { + priv->stats.txunicast++; + priv->stats.txbytesunicast += pstx_fb->pkt_length; + } + } else { + priv->stats.txfeedbackfail++; + priv->stats.txerrtotal++; + priv->stats.txerrbytestotal += pstx_fb->pkt_length; + + if (pstx_fb->pkt_type == PACKET_MULTICAST) + priv->stats.txerrmulticast++; + else if (pstx_fb->pkt_type == PACKET_BROADCAST) + priv->stats.txerrbroadcast++; + else + priv->stats.txerrunicast++; + } + + priv->stats.txretrycount += pstx_fb->retry_cnt; + priv->stats.txfeedbackretry += pstx_fb->retry_cnt; + +} /* cmpk_CountTxStatistic */ + + + +static void cmpk_handle_tx_feedback(struct net_device *dev, u8 *pmsg) +{ + struct r8192_priv *priv = rtllib_priv(dev); + struct cmpk_txfb rx_tx_fb; /* */ + + priv->stats.txfeedback++; + + + memcpy((u8 *)&rx_tx_fb, pmsg, sizeof(struct cmpk_txfb)); + cmpk_count_txstatistic(dev, &rx_tx_fb); + +} /* cmpk_Handle_Tx_Feedback */ + +static void cmdpkt_beacontimerinterrupt_819xusb(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + u16 tx_rate; + + if ((priv->rtllib->current_network.mode == IEEE_A) || + (priv->rtllib->current_network.mode == IEEE_N_5G) || + ((priv->rtllib->current_network.mode == IEEE_N_24G) && + (!priv->rtllib->pHTInfo->bCurSuppCCK))) { + tx_rate = 60; + DMESG("send beacon frame tx rate is 6Mbpm\n"); + } else { + tx_rate = 10; + DMESG("send beacon frame tx rate is 1Mbpm\n"); + } + +} + +static void cmpk_handle_interrupt_status(struct net_device *dev, u8 *pmsg) +{ + struct cmpk_intr_sta rx_intr_status; /* */ + struct r8192_priv *priv = rtllib_priv(dev); + + DMESG("---> cmpk_Handle_Interrupt_Status()\n"); + + + rx_intr_status.length = pmsg[1]; + if (rx_intr_status.length != (sizeof(struct cmpk_intr_sta) - 2)) { + DMESG("cmpk_Handle_Interrupt_Status: wrong length!\n"); + return; + } + + + if (priv->rtllib->iw_mode == IW_MODE_ADHOC) { + rx_intr_status.interrupt_status = *((u32 *)(pmsg + 4)); + + DMESG("interrupt status = 0x%x\n", + rx_intr_status.interrupt_status); + + if (rx_intr_status.interrupt_status & ISR_TxBcnOk) { + priv->rtllib->bibsscoordinator = true; + priv->stats.txbeaconokint++; + } else if (rx_intr_status.interrupt_status & ISR_TxBcnErr) { + priv->rtllib->bibsscoordinator = false; + priv->stats.txbeaconerr++; + } + + if (rx_intr_status.interrupt_status & ISR_BcnTimerIntr) + cmdpkt_beacontimerinterrupt_819xusb(dev); + } + + DMESG("<---- cmpk_handle_interrupt_status()\n"); + +} /* cmpk_handle_interrupt_status */ + + +static void cmpk_handle_query_config_rx(struct net_device *dev, u8 *pmsg) +{ + cmpk_query_cfg_t rx_query_cfg; /* */ + + + rx_query_cfg.cfg_action = (pmsg[4] & 0x80000000)>>31; + rx_query_cfg.cfg_type = (pmsg[4] & 0x60) >> 5; + rx_query_cfg.cfg_size = (pmsg[4] & 0x18) >> 3; + rx_query_cfg.cfg_page = (pmsg[6] & 0x0F) >> 0; + rx_query_cfg.cfg_offset = pmsg[7]; + rx_query_cfg.value = (pmsg[8] << 24) | (pmsg[9] << 16) | + (pmsg[10] << 8) | (pmsg[11] << 0); + rx_query_cfg.mask = (pmsg[12] << 24) | (pmsg[13] << 16) | + (pmsg[14] << 8) | (pmsg[15] << 0); + +} /* cmpk_Handle_Query_Config_Rx */ + + +static void cmpk_count_tx_status(struct net_device *dev, + struct cmpk_tx_status *pstx_status) +{ + struct r8192_priv *priv = rtllib_priv(dev); + +#ifdef ENABLE_PS + + enum rt_rf_power_state rtstate; + + pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, + (pu1Byte)(&rtState)); + + if (rtState == eRfOff) + return; +#endif + + priv->stats.txfeedbackok += pstx_status->txok; + priv->stats.txoktotal += pstx_status->txok; + + priv->stats.txfeedbackfail += pstx_status->txfail; + priv->stats.txerrtotal += pstx_status->txfail; + + priv->stats.txretrycount += pstx_status->txretry; + priv->stats.txfeedbackretry += pstx_status->txretry; + + + priv->stats.txmulticast += pstx_status->txmcok; + priv->stats.txbroadcast += pstx_status->txbcok; + priv->stats.txunicast += pstx_status->txucok; + + priv->stats.txerrmulticast += pstx_status->txmcfail; + priv->stats.txerrbroadcast += pstx_status->txbcfail; + priv->stats.txerrunicast += pstx_status->txucfail; + + priv->stats.txbytesmulticast += pstx_status->txmclength; + priv->stats.txbytesbroadcast += pstx_status->txbclength; + priv->stats.txbytesunicast += pstx_status->txuclength; + + priv->stats.last_packet_rate = pstx_status->rate; +} /* cmpk_CountTxStatus */ + + + +static void cmpk_handle_tx_status(struct net_device *dev, u8 *pmsg) +{ + struct cmpk_tx_status rx_tx_sts; /* */ + + memcpy((void *)&rx_tx_sts, (void *)pmsg, sizeof(struct cmpk_tx_status)); + cmpk_count_tx_status(dev, &rx_tx_sts); +} + +static void cmpk_handle_tx_rate_history(struct net_device *dev, u8 *pmsg) +{ + struct cmpk_tx_rahis *ptxrate; + u8 i, j; + u16 length = sizeof(struct cmpk_tx_rahis); + u32 *ptemp; + struct r8192_priv *priv = rtllib_priv(dev); + + +#ifdef ENABLE_PS + pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, + (pu1Byte)(&rtState)); + + if (rtState == eRfOff) + return; +#endif + + ptemp = (u32 *)pmsg; + + for (i = 0; i < (length / 4); i++) { + u16 temp1, temp2; + + temp1 = ptemp[i] & 0x0000FFFF; + temp2 = ptemp[i] >> 16; + ptemp[i] = (temp1 << 16) | temp2; + } + + ptxrate = (struct cmpk_tx_rahis *)pmsg; + + if (ptxrate == NULL) + return; + + for (i = 0; i < 16; i++) { + if (i < 4) + priv->stats.txrate.cck[i] += ptxrate->cck[i]; + + if (i < 8) + priv->stats.txrate.ofdm[i] += ptxrate->ofdm[i]; + + for (j = 0; j < 4; j++) + priv->stats.txrate.ht_mcs[j][i] += + ptxrate->ht_mcs[j][i]; + } + +} + + +u32 cmpk_message_handle_rx(struct net_device *dev, + struct rtllib_rx_stats *pstats) +{ + struct r8192_priv *priv = rtllib_priv(dev); + int total_length; + u8 cmd_length, exe_cnt = 0; + u8 element_id; + u8 *pcmd_buff; + + RT_TRACE(COMP_CMDPKT, "---->cmpk_message_handle_rx()\n"); + + if (pstats == NULL) { + /* Print error message. */ + /*RT_TRACE(COMP_SEND, DebugLevel, + ("\n\r[CMPK]-->Err queue id or pointer"));*/ + return 0; + } + + total_length = pstats->Length; + + pcmd_buff = pstats->virtual_address; + + element_id = pcmd_buff[0]; + + while (total_length > 0 || exe_cnt++ > 100) { + element_id = pcmd_buff[0]; + + switch (element_id) { + case RX_TX_FEEDBACK: + RT_TRACE(COMP_CMDPKT, "---->cmpk_message_handle_rx():" + "RX_TX_FEEDBACK\n"); + cmpk_handle_tx_feedback(dev, pcmd_buff); + cmd_length = CMPK_RX_TX_FB_SIZE; + break; + case RX_INTERRUPT_STATUS: + RT_TRACE(COMP_CMDPKT, "---->cmpk_message_handle_rx():" + "RX_INTERRUPT_STATUS\n"); + cmpk_handle_interrupt_status(dev, pcmd_buff); + cmd_length = sizeof(struct cmpk_intr_sta); + break; + case BOTH_QUERY_CONFIG: + RT_TRACE(COMP_CMDPKT, "---->cmpk_message_handle_rx():" + "BOTH_QUERY_CONFIG\n"); + cmpk_handle_query_config_rx(dev, pcmd_buff); + cmd_length = CMPK_BOTH_QUERY_CONFIG_SIZE; + break; + case RX_TX_STATUS: + RT_TRACE(COMP_CMDPKT, "---->cmpk_message_handle_rx():" + "RX_TX_STATUS\n"); + cmpk_handle_tx_status(dev, pcmd_buff); + cmd_length = CMPK_RX_TX_STS_SIZE; + break; + case RX_TX_PER_PKT_FEEDBACK: + RT_TRACE(COMP_CMDPKT, "---->cmpk_message_handle_rx():" + "RX_TX_PER_PKT_FEEDBACK\n"); + cmd_length = CMPK_RX_TX_FB_SIZE; + break; + case RX_TX_RATE_HISTORY: + RT_TRACE(COMP_CMDPKT, "---->cmpk_message_handle_rx():" + "RX_TX_HISTORY\n"); + cmpk_handle_tx_rate_history(dev, pcmd_buff); + cmd_length = CMPK_TX_RAHIS_SIZE; + break; + default: + + RT_TRACE(COMP_CMDPKT, "---->cmpk_message_handle_rx():" + "unknow CMD Element\n"); + return 1; + } + + priv->stats.rxcmdpkt[element_id]++; + + total_length -= cmd_length; + pcmd_buff += cmd_length; + } + return 1; + + RT_TRACE(COMP_CMDPKT, "<----cmpk_message_handle_rx()\n"); +} diff --git a/drivers/staging/rtl8192e/r8192E_cmdpkt.h b/drivers/staging/rtl8192e/r8192E_cmdpkt.h new file mode 100644 index 0000000..23219e1 --- /dev/null +++ b/drivers/staging/rtl8192e/r8192E_cmdpkt.h @@ -0,0 +1,159 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> +******************************************************************************/ +#ifndef R819XUSB_CMDPKT_H +#define R819XUSB_CMDPKT_H +#define CMPK_RX_TX_FB_SIZE sizeof(struct cmpk_txfb) +#define CMPK_TX_SET_CONFIG_SIZE sizeof(struct cmpk_set_cfg) +#define CMPK_BOTH_QUERY_CONFIG_SIZE sizeof(struct cmpk_set_cfg) +#define CMPK_RX_TX_STS_SIZE sizeof(struct cmpk_tx_status) +#define CMPK_RX_DBG_MSG_SIZE sizeof(struct cmpk_rx_dbginfo) +#define CMPK_TX_RAHIS_SIZE sizeof(struct cmpk_tx_rahis) + +#define ISR_TxBcnOk BIT27 +#define ISR_TxBcnErr BIT26 +#define ISR_BcnTimerIntr BIT13 + + +struct cmpk_txfb { + u8 element_id; + u8 length; + u8 TID:4; /* */ + u8 fail_reason:3; /* */ + u8 tok:1; + u8 reserve1:4; /* */ + u8 pkt_type:2; /* */ + u8 bandwidth:1; /* */ + u8 qos_pkt:1; /* */ + + u8 reserve2; /* */ + u8 retry_cnt; /* */ + u16 pkt_id; /* */ + + u16 seq_num; /* */ + u8 s_rate; + u8 f_rate; + + u8 s_rts_rate; /* */ + u8 f_rts_rate; /* */ + u16 pkt_length; /* */ + + u16 reserve3; /* */ + u16 duration; /* */ +}; + +struct cmpk_intr_sta { + u8 element_id; + u8 length; + u16 reserve; + u32 interrupt_status; +}; + + +struct cmpk_set_cfg { + u8 element_id; + u8 length; + u16 reserve1; + u8 cfg_reserve1:3; + u8 cfg_size:2; + u8 cfg_type:2; + u8 cfg_action:1; + u8 cfg_reserve2; + u8 cfg_page:4; + u8 cfg_reserve3:4; + u8 cfg_offset; + u32 value; + u32 mask; +}; + +#define cmpk_query_cfg_t struct cmpk_set_cfg + +struct cmpk_tx_status { + u16 reserve1; + u8 length; + u8 element_id; + + u16 txfail; + u16 txok; + + u16 txmcok; + u16 txretry; + + u16 txucok; + u16 txbcok; + + u16 txbcfail; + u16 txmcfail; + + u16 reserve2; + u16 txucfail; + + u32 txmclength; + u32 txbclength; + u32 txuclength; + + u16 reserve3_23; + u8 reserve3_1; + u8 rate; +} __packed; + +struct cmpk_rx_dbginfo { + u16 reserve1; + u8 length; + u8 element_id; + + +}; + +struct cmpk_tx_rahis { + u8 element_id; + u8 length; + u16 reserved1; + + u16 cck[4]; + + u16 ofdm[8]; + + + + + + u16 ht_mcs[4][16]; + +} __packed; + +enum cmpk_element { + RX_TX_FEEDBACK = 0, + RX_INTERRUPT_STATUS = 1, + TX_SET_CONFIG = 2, + BOTH_QUERY_CONFIG = 3, + RX_TX_STATUS = 4, + RX_DBGINFO_FEEDBACK = 5, + RX_TX_PER_PKT_FEEDBACK = 6, + RX_TX_RATE_HISTORY = 7, + RX_CMD_ELE_MAX +}; + +extern u32 cmpk_message_handle_rx(struct net_device *dev, + struct rtllib_rx_stats *pstats); +extern bool cmpk_message_handle_tx(struct net_device *dev, + u8 *codevirtualaddress, u32 packettype, + u32 buffer_len); + + +#endif diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c deleted file mode 100644 index 94d9c8d..0000000 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ /dev/null @@ -1,5039 +0,0 @@ -/****************************************************************************** - * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. - * Linux device driver for RTL8192E - * - * Based on the r8180 driver, which is: - * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al. - * This program is free software; you can redistribute it and/or modify it - * under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA - * - * The full GNU General Public License is included in this distribution in the - * file called LICENSE. - * - * Contact Information: - * Jerry chuang <wlanfae@realtek.com> - */ - - -#include <linux/vmalloc.h> -#include <linux/slab.h> -#include <linux/interrupt.h> -#include <linux/hardirq.h> -#include <asm/uaccess.h> -#include "r8192E_hw.h" -#include "r8192E.h" -#include "r8190_rtl8256.h" /* RTL8225 Radio frontend */ -#include "r8180_93cx6.h" /* Card EEPROM */ -#include "r8192E_wx.h" -#include "r819xE_phy.h" //added by WB 4.30.2008 -#include "r819xE_phyreg.h" -#include "r819xE_cmdpkt.h" -#include "r8192E_dm.h" - -#ifdef CONFIG_PM -#include "r8192_pm.h" -#endif - -#ifdef ENABLE_DOT11D -#include "ieee80211/dot11d.h" -#endif - -//set here to open your trace code. //WB -u32 rt_global_debug_component = COMP_ERR ; //always open err flags on - -static DEFINE_PCI_DEVICE_TABLE(rtl8192_pci_id_tbl) = { - /* Realtek */ - { PCI_DEVICE(0x10ec, 0x8192) }, - - /* Corega */ - { PCI_DEVICE(0x07aa, 0x0044) }, - { PCI_DEVICE(0x07aa, 0x0047) }, - {} -}; - -static char ifname[IFNAMSIZ] = "wlan%d"; -static int hwwep = 1; //default use hw. set 0 to use software security -static int channels = 0x3fff; - -MODULE_LICENSE("GPL"); -MODULE_VERSION("V 1.1"); -MODULE_DEVICE_TABLE(pci, rtl8192_pci_id_tbl); -//MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>"); -MODULE_DESCRIPTION("Linux driver for Realtek RTL819x WiFi cards"); - - -module_param_string(ifname, ifname, sizeof(ifname), S_IRUGO|S_IWUSR); -module_param(hwwep,int, S_IRUGO|S_IWUSR); -module_param(channels,int, S_IRUGO|S_IWUSR); - -MODULE_PARM_DESC(ifname," Net interface name, wlan%d=default"); -MODULE_PARM_DESC(hwwep," Try to use hardware WEP support. Still broken and not available on all cards"); -MODULE_PARM_DESC(channels," Channel bitmask for specific locales. NYI"); - -static int __devinit rtl8192_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *id); -static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev); - -static struct pci_driver rtl8192_pci_driver = { - .name = RTL819xE_MODULE_NAME, /* Driver name */ - .id_table = rtl8192_pci_id_tbl, /* PCI_ID table */ - .probe = rtl8192_pci_probe, /* probe fn */ - .remove = __devexit_p(rtl8192_pci_disconnect), /* remove fn */ -#ifdef CONFIG_PM - .suspend = rtl8192E_suspend, /* PM suspend fn */ - .resume = rtl8192E_resume, /* PM resume fn */ -#else - .suspend = NULL, /* PM suspend fn */ - .resume = NULL, /* PM resume fn */ -#endif -}; - -static void rtl8192_start_beacon(struct ieee80211_device *ieee80211); -static void rtl8192_stop_beacon(struct ieee80211_device *ieee80211); -static void rtl819x_watchdog_wqcallback(struct work_struct *work); -static void rtl8192_irq_rx_tasklet(unsigned long arg); -static void rtl8192_irq_tx_tasklet(unsigned long arg); -static void rtl8192_prepare_beacon(unsigned long arg); -static irqreturn_t rtl8192_interrupt(int irq, void *param); -static void rtl819xE_tx_cmd(struct r8192_priv *priv, struct sk_buff *skb); -static void rtl8192_update_ratr_table(struct r8192_priv *priv); -static void rtl8192_restart(struct work_struct *work); -static void watch_dog_timer_callback(unsigned long data); -static int _rtl8192_up(struct r8192_priv *priv); -static void rtl8192_cancel_deferred_work(struct r8192_priv* priv); -static short rtl8192_tx(struct r8192_priv *priv, struct sk_buff* skb); - -#ifdef ENABLE_DOT11D - -typedef struct _CHANNEL_LIST -{ - u8 Channel[32]; - u8 Len; -}CHANNEL_LIST, *PCHANNEL_LIST; - -static const CHANNEL_LIST ChannelPlan[] = { - {{1,2,3,4,5,6,7,8,9,10,11,36,40,44,48,52,56,60,64,149,153,157,161,165},24}, //FCC - {{1,2,3,4,5,6,7,8,9,10,11},11}, //IC - {{1,2,3,4,5,6,7,8,9,10,11,12,13,36,40,44,48,52,56,60,64},21}, //ETSI - {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Spain. Change to ETSI. - {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //France. Change to ETSI. - {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22}, //MKK //MKK - {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22},//MKK1 - {{1,2,3,4,5,6,7,8,9,10,11,12,13},13}, //Israel. - {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64},22}, // For 11a , TELEC - {{1,2,3,4,5,6,7,8,9,10,11,12,13,14,36,40,44,48,52,56,60,64}, 22}, //MIC - {{1,2,3,4,5,6,7,8,9,10,11,12,13,14},14} //For Global Domain. 1-11:active scan, 12-14 passive scan. //+YJ, 080626 -}; - -static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv* priv) -{ - int i, max_chan=-1, min_chan=-1; - struct ieee80211_device* ieee = priv->ieee80211; - switch (channel_plan) - { - case COUNTRY_CODE_FCC: - case COUNTRY_CODE_IC: - case COUNTRY_CODE_ETSI: - case COUNTRY_CODE_SPAIN: - case COUNTRY_CODE_FRANCE: - case COUNTRY_CODE_MKK: - case COUNTRY_CODE_MKK1: - case COUNTRY_CODE_ISRAEL: - case COUNTRY_CODE_TELEC: - case COUNTRY_CODE_MIC: - { - Dot11d_Init(ieee); - ieee->bGlobalDomain = false; - //acturally 8225 & 8256 rf chip only support B,G,24N mode - min_chan = 1; - max_chan = 14; - - if (ChannelPlan[channel_plan].Len != 0){ - // Clear old channel map - memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map)); - // Set new channel map - for (i=0;i<ChannelPlan[channel_plan].Len;i++) - { - if (ChannelPlan[channel_plan].Channel[i] < min_chan || ChannelPlan[channel_plan].Channel[i] > max_chan) - break; - GET_DOT11D_INFO(ieee)->channel_map[ChannelPlan[channel_plan].Channel[i]] = 1; - } - } - break; - } - case COUNTRY_CODE_GLOBAL_DOMAIN: - { - GET_DOT11D_INFO(ieee)->bEnabled = 0; //this flag enabled to follow 11d country IE setting, otherwise, it shall follow global domain setting - Dot11d_Reset(ieee); - ieee->bGlobalDomain = true; - break; - } - default: - break; - } -} -#endif - -static inline bool rx_hal_is_cck_rate(prx_fwinfo_819x_pci pdrvinfo) -{ - return (pdrvinfo->RxRate == DESC90_RATE1M || - pdrvinfo->RxRate == DESC90_RATE2M || - pdrvinfo->RxRate == DESC90_RATE5_5M || - pdrvinfo->RxRate == DESC90_RATE11M) && - !pdrvinfo->RxHT; -} - -void CamResetAllEntry(struct r8192_priv* priv) -{ - write_nic_dword(priv, RWCAM, BIT31|BIT30); -} - -void write_cam(struct r8192_priv *priv, u8 addr, u32 data) -{ - write_nic_dword(priv, WCAMI, data); - write_nic_dword(priv, RWCAM, BIT31|BIT16|(addr&0xff) ); -} - -u32 read_cam(struct r8192_priv *priv, u8 addr) -{ - write_nic_dword(priv, RWCAM, 0x80000000|(addr&0xff) ); - return read_nic_dword(priv, 0xa8); -} - -u8 read_nic_byte(struct r8192_priv *priv, int x) -{ - return 0xff & readb(priv->mem_start + x); -} - -u32 read_nic_dword(struct r8192_priv *priv, int x) -{ - return readl(priv->mem_start + x); -} - -u16 read_nic_word(struct r8192_priv *priv, int x) -{ - return readw(priv->mem_start + x); -} - -void write_nic_byte(struct r8192_priv *priv, int x,u8 y) -{ - writeb(y, priv->mem_start + x); - udelay(20); -} - -void write_nic_dword(struct r8192_priv *priv, int x,u32 y) -{ - writel(y, priv->mem_start + x); - udelay(20); -} - -void write_nic_word(struct r8192_priv *priv, int x,u16 y) -{ - writew(y, priv->mem_start + x); - udelay(20); -} - -u8 rtl8192e_ap_sec_type(struct ieee80211_device *ieee) -{ - static const u8 ccmp_ie[4] = {0x00,0x50,0xf2,0x04}; - static const u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04}; - int wpa_ie_len= ieee->wpa_ie_len; - struct ieee80211_crypt_data* crypt; - int encrypt; - - crypt = ieee->crypt[ieee->tx_keyidx]; - - encrypt = (ieee->current_network.capability & WLAN_CAPABILITY_PRIVACY) || - (ieee->host_encrypt && crypt && crypt->ops && - (0 == strcmp(crypt->ops->name,"WEP"))); - - /* simply judge */ - if(encrypt && (wpa_ie_len == 0)) { - // wep encryption, no N mode setting */ - return SEC_ALG_WEP; - } else if((wpa_ie_len != 0)) { - // parse pairwise key type */ - if (((ieee->wpa_ie[0] == 0xdd) && (!memcmp(&(ieee->wpa_ie[14]),ccmp_ie,4))) || - ((ieee->wpa_ie[0] == 0x30) && (!memcmp(&ieee->wpa_ie[10],ccmp_rsn_ie, 4)))) - return SEC_ALG_CCMP; - else - return SEC_ALG_TKIP; - } else { - return SEC_ALG_NONE; - } -} - -void rtl8192e_SetHwReg(struct ieee80211_device *ieee80211, u8 variable, u8 *val) -{ - struct r8192_priv *priv = ieee80211_priv(ieee80211->dev); - - switch(variable) - { - - case HW_VAR_BSSID: - write_nic_dword(priv, BSSIDR, ((u32*)(val))[0]); - write_nic_word(priv, BSSIDR+2, ((u16*)(val+2))[0]); - break; - - case HW_VAR_MEDIA_STATUS: - { - RT_OP_MODE OpMode = *((RT_OP_MODE *)(val)); - u8 btMsr = read_nic_byte(priv, MSR); - - btMsr &= 0xfc; - - switch(OpMode) - { - case RT_OP_MODE_INFRASTRUCTURE: - btMsr |= MSR_INFRA; - break; - - case RT_OP_MODE_IBSS: - btMsr |= MSR_ADHOC; - break; - - case RT_OP_MODE_AP: - btMsr |= MSR_AP; - break; - - default: - btMsr |= MSR_NOLINK; - break; - } - - write_nic_byte(priv, MSR, btMsr); - } - break; - - case HW_VAR_CHECK_BSSID: - { - u32 RegRCR, Type; - - Type = ((u8*)(val))[0]; - RegRCR = read_nic_dword(priv, RCR); - priv->ReceiveConfig = RegRCR; - - if (Type == true) - RegRCR |= (RCR_CBSSID); - else if (Type == false) - RegRCR &= (~RCR_CBSSID); - - write_nic_dword(priv, RCR,RegRCR); - priv->ReceiveConfig = RegRCR; - - } - break; - - case HW_VAR_SLOT_TIME: - { - priv->slot_time = val[0]; - write_nic_byte(priv, SLOT_TIME, val[0]); - - } - break; - - case HW_VAR_ACK_PREAMBLE: - { - u32 regTmp = 0; - priv->short_preamble = (bool)(*(u8*)val ); - regTmp = priv->basic_rate; - if (priv->short_preamble) - regTmp |= BRSR_AckShortPmb; - write_nic_dword(priv, RRSR, regTmp); - } - break; - - case HW_VAR_CPU_RST: - write_nic_dword(priv, CPU_GEN, ((u32*)(val))[0]); - break; - - default: - break; - } - -} - -static struct proc_dir_entry *rtl8192_proc = NULL; - -static int proc_get_stats_ap(char *page, char **start, - off_t offset, int count, - int *eof, void *data) -{ - struct r8192_priv *priv = data; - struct ieee80211_device *ieee = priv->ieee80211; - struct ieee80211_network *target; - int len = 0; - - list_for_each_entry(target, &ieee->network_list, list) { - - len += snprintf(page + len, count - len, - "%s ", target->ssid); - - if(target->wpa_ie_len>0 || target->rsn_ie_len>0){ - len += snprintf(page + len, count - len, - "WPA\n"); - } - else{ - len += snprintf(page + len, count - len, - "non_WPA\n"); - } - - } - - *eof = 1; - return len; -} - -static int proc_get_registers(char *page, char **start, - off_t offset, int count, - int *eof, void *data) -{ - struct r8192_priv *priv = data; - int len = 0; - int i,n; - int max=0xff; - - /* This dump the current register page */ - len += snprintf(page + len, count - len, - "\n####################page 0##################\n "); - - for(n=0;n<=max;) - { - len += snprintf(page + len, count - len, - "\nD: %2x > ",n); - - for(i=0;i<16 && n<=max;i++,n++) - len += snprintf(page + len, count - len, - "%2x ",read_nic_byte(priv,n)); - } - len += snprintf(page + len, count - len,"\n"); - len += snprintf(page + len, count - len, - "\n####################page 1##################\n "); - for(n=0;n<=max;) - { - len += snprintf(page + len, count - len, - "\nD: %2x > ",n); - - for(i=0;i<16 && n<=max;i++,n++) - len += snprintf(page + len, count - len, - "%2x ",read_nic_byte(priv,0x100|n)); - } - - len += snprintf(page + len, count - len, - "\n####################page 3##################\n "); - for(n=0;n<=max;) - { - len += snprintf(page + len, count - len, - "\nD: %2x > ",n); - - for(i=0;i<16 && n<=max;i++,n++) - len += snprintf(page + len, count - len, - "%2x ",read_nic_byte(priv,0x300|n)); - } - - *eof = 1; - return len; - -} - -static int proc_get_stats_tx(char *page, char **start, - off_t offset, int count, - int *eof, void *data) -{ - struct r8192_priv *priv = data; - - int len = 0; - - len += snprintf(page + len, count - len, - "TX VI priority ok int: %lu\n" - "TX VO priority ok int: %lu\n" - "TX BE priority ok int: %lu\n" - "TX BK priority ok int: %lu\n" - "TX MANAGE priority ok int: %lu\n" - "TX BEACON priority ok int: %lu\n" - "TX BEACON priority error int: %lu\n" - "TX CMDPKT priority ok int: %lu\n" - "TX queue stopped?: %d\n" - "TX fifo overflow: %lu\n" - "TX total data packets %lu\n" - "TX total data bytes :%lu\n", - priv->stats.txviokint, - priv->stats.txvookint, - priv->stats.txbeokint, - priv->stats.txbkokint, - priv->stats.txmanageokint, - priv->stats.txbeaconokint, - priv->stats.txbeaconerr, - priv->stats.txcmdpktokint, - netif_queue_stopped(priv->ieee80211->dev), - priv->stats.txoverflow, - priv->ieee80211->stats.tx_packets, - priv->ieee80211->stats.tx_bytes); - - *eof = 1; - return len; -} - - - -static int proc_get_stats_rx(char *page, char **start, - off_t offset, int count, - int *eof, void *data) -{ - struct r8192_priv *priv = data; - int len = 0; - - len += snprintf(page + len, count - len, - "RX packets: %lu\n" - "RX desc err: %lu\n" - "RX rx overflow error: %lu\n", - priv->stats.rxint, - priv->stats.rxrdu, - priv->stats.rxoverflow); - - *eof = 1; - return len; -} - -static void rtl8192_proc_module_init(void) -{ - RT_TRACE(COMP_INIT, "Initializing proc filesystem\n"); - rtl8192_proc = proc_mkdir(RTL819xE_MODULE_NAME, init_net.proc_net); -} - - -static void rtl8192_proc_module_remove(void) -{ - remove_proc_entry(RTL819xE_MODULE_NAME, init_net.proc_net); -} - - -static void rtl8192_proc_remove_one(struct r8192_priv *priv) -{ - struct net_device *dev = priv->ieee80211->dev; - - printk("dev name=======> %s\n",dev->name); - - if (priv->dir_dev) { - remove_proc_entry("stats-tx", priv->dir_dev); - remove_proc_entry("stats-rx", priv->dir_dev); - remove_proc_entry("stats-ap", priv->dir_dev); - remove_proc_entry("registers", priv->dir_dev); - remove_proc_entry("wlan0", rtl8192_proc); - priv->dir_dev = NULL; - } -} - - -static void rtl8192_proc_init_one(struct r8192_priv *priv) -{ - struct net_device *dev = priv->ieee80211->dev; - struct proc_dir_entry *e; - - priv->dir_dev = proc_mkdir(dev->name, rtl8192_proc); - if (!priv->dir_dev) { - RT_TRACE(COMP_ERR, "Unable to initialize /proc/net/rtl8192/%s\n", - dev->name); - return; - } - e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_stats_rx, priv); - - if (!e) { - RT_TRACE(COMP_ERR,"Unable to initialize " - "/proc/net/rtl8192/%s/stats-rx\n", - dev->name); - } - - - e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_stats_tx, priv); - - if (!e) { - RT_TRACE(COMP_ERR, "Unable to initialize " - "/proc/net/rtl8192/%s/stats-tx\n", - dev->name); - } - - e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_stats_ap, priv); - - if (!e) { - RT_TRACE(COMP_ERR, "Unable to initialize " - "/proc/net/rtl8192/%s/stats-ap\n", - dev->name); - } - - e = create_proc_read_entry("registers", S_IFREG | S_IRUGO, - priv->dir_dev, proc_get_registers, priv); - if (!e) { - RT_TRACE(COMP_ERR, "Unable to initialize " - "/proc/net/rtl8192/%s/registers\n", - dev->name); - } -} - -static short check_nic_enough_desc(struct ieee80211_device *ieee, int prio) -{ - struct r8192_priv *priv = ieee80211_priv(ieee->dev); - struct rtl8192_tx_ring *ring = &priv->tx_ring[prio]; - - /* for now we reserve two free descriptor as a safety boundary - * between the tail and the head - */ - return (ring->entries - skb_queue_len(&ring->queue) >= 2); -} - -static void tx_timeout(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - schedule_work(&priv->reset_wq); - printk("TXTIMEOUT"); -} - -static void rtl8192_irq_enable(struct r8192_priv *priv) -{ - u32 mask; - - mask = IMR_ROK | IMR_VODOK | IMR_VIDOK | IMR_BEDOK | IMR_BKDOK | - IMR_HCCADOK | IMR_MGNTDOK | IMR_COMDOK | IMR_HIGHDOK | - IMR_BDOK | IMR_RXCMDOK | IMR_TIMEOUT0 | IMR_RDU | IMR_RXFOVW | - IMR_TXFOVW | IMR_BcnInt | IMR_TBDOK | IMR_TBDER; - - write_nic_dword(priv, INTA_MASK, mask); -} - -static void rtl8192_irq_disable(struct r8192_priv *priv) -{ - write_nic_dword(priv, INTA_MASK, 0); - synchronize_irq(priv->irq); -} - -static void rtl8192_update_msr(struct r8192_priv *priv) -{ - u8 msr; - - msr = read_nic_byte(priv, MSR); - msr &= ~ MSR_LINK_MASK; - - /* do not change in link_state != WLAN_LINK_ASSOCIATED. - * msr must be updated if the state is ASSOCIATING. - * this is intentional and make sense for ad-hoc and - * master (see the create BSS/IBSS func) - */ - if (priv->ieee80211->state == IEEE80211_LINKED){ - - if (priv->ieee80211->iw_mode == IW_MODE_INFRA) - msr |= (MSR_LINK_MANAGED<<MSR_LINK_SHIFT); - else if (priv->ieee80211->iw_mode == IW_MODE_ADHOC) - msr |= (MSR_LINK_ADHOC<<MSR_LINK_SHIFT); - else if (priv->ieee80211->iw_mode == IW_MODE_MASTER) - msr |= (MSR_LINK_MASTER<<MSR_LINK_SHIFT); - - }else - msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT); - - write_nic_byte(priv, MSR, msr); -} - -static void rtl8192_set_chan(struct ieee80211_device *ieee80211, short ch) -{ - struct r8192_priv *priv = ieee80211_priv(ieee80211->dev); - - priv->chan = ch; - - /* need to implement rf set channel here WB */ - - if (priv->rf_set_chan) - priv->rf_set_chan(ieee80211, priv->chan); -} - -static void rtl8192_rx_enable(struct r8192_priv *priv) -{ - write_nic_dword(priv, RDQDA, priv->rx_ring_dma); -} - -/* the TX_DESC_BASE setting is according to the following queue index - * BK_QUEUE ===> 0 - * BE_QUEUE ===> 1 - * VI_QUEUE ===> 2 - * VO_QUEUE ===> 3 - * HCCA_QUEUE ===> 4 - * TXCMD_QUEUE ===> 5 - * MGNT_QUEUE ===> 6 - * HIGH_QUEUE ===> 7 - * BEACON_QUEUE ===> 8 - * */ -static const u32 TX_DESC_BASE[] = {BKQDA, BEQDA, VIQDA, VOQDA, HCCAQDA, CQDA, MQDA, HQDA, BQDA}; -static void rtl8192_tx_enable(struct r8192_priv *priv) -{ - u32 i; - - for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) - write_nic_dword(priv, TX_DESC_BASE[i], priv->tx_ring[i].dma); - - ieee80211_reset_queue(priv->ieee80211); -} - - -static void rtl8192_free_rx_ring(struct r8192_priv *priv) -{ - int i; - - for (i = 0; i < priv->rxringcount; i++) { - struct sk_buff *skb = priv->rx_buf[i]; - if (!skb) - continue; - - pci_unmap_single(priv->pdev, - *((dma_addr_t *)skb->cb), - priv->rxbuffersize, PCI_DMA_FROMDEVICE); - kfree_skb(skb); - } - - pci_free_consistent(priv->pdev, sizeof(*priv->rx_ring) * priv->rxringcount, - priv->rx_ring, priv->rx_ring_dma); - priv->rx_ring = NULL; -} - -static void rtl8192_free_tx_ring(struct r8192_priv *priv, unsigned int prio) -{ - struct rtl8192_tx_ring *ring = &priv->tx_ring[prio]; - - while (skb_queue_len(&ring->queue)) { - tx_desc_819x_pci *entry = &ring->desc[ring->idx]; - struct sk_buff *skb = __skb_dequeue(&ring->queue); - - pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr), - skb->len, PCI_DMA_TODEVICE); - kfree_skb(skb); - ring->idx = (ring->idx + 1) % ring->entries; - } - - pci_free_consistent(priv->pdev, sizeof(*ring->desc)*ring->entries, - ring->desc, ring->dma); - ring->desc = NULL; -} - -void PHY_SetRtl8192eRfOff(struct r8192_priv *priv) -{ - //disable RF-Chip A/B - rtl8192_setBBreg(priv, rFPGA0_XA_RFInterfaceOE, BIT4, 0x0); - //analog to digital off, for power save - rtl8192_setBBreg(priv, rFPGA0_AnalogParameter4, 0x300, 0x0); - //digital to analog off, for power save - rtl8192_setBBreg(priv, rFPGA0_AnalogParameter1, 0x18, 0x0); - //rx antenna off - rtl8192_setBBreg(priv, rOFDM0_TRxPathEnable, 0xf, 0x0); - //rx antenna off - rtl8192_setBBreg(priv, rOFDM1_TRxPathEnable, 0xf, 0x0); - //analog to digital part2 off, for power save - rtl8192_setBBreg(priv, rFPGA0_AnalogParameter1, 0x60, 0x0); - rtl8192_setBBreg(priv, rFPGA0_AnalogParameter1, 0x4, 0x0); - // Analog parameter!!Change bias and Lbus control. - write_nic_byte(priv, ANAPAR_FOR_8192PciE, 0x07); -} - -static void rtl8192_halt_adapter(struct r8192_priv *priv, bool reset) -{ - int i; - u8 OpMode; - u32 ulRegRead; - - OpMode = RT_OP_MODE_NO_LINK; - priv->ieee80211->SetHwRegHandler(priv->ieee80211, HW_VAR_MEDIA_STATUS, &OpMode); - - if (!priv->ieee80211->bSupportRemoteWakeUp) { - /* - * disable tx/rx. In 8185 we write 0x10 (Reset bit), - * but here we make reference to WMAC and wirte 0x0 - */ - write_nic_byte(priv, CMDR, 0); - } - - mdelay(20); - - if (!reset) { - mdelay(150); - - priv->bHwRfOffAction = 2; - - /* - * Call MgntActSet_RF_State instead to - * prevent RF config race condition. - */ - if (!priv->ieee80211->bSupportRemoteWakeUp) { - PHY_SetRtl8192eRfOff(priv); - ulRegRead = read_nic_dword(priv, CPU_GEN); - ulRegRead |= CPU_GEN_SYSTEM_RESET; - write_nic_dword(priv,CPU_GEN, ulRegRead); - } else { - /* for WOL */ - write_nic_dword(priv, WFCRC0, 0xffffffff); - write_nic_dword(priv, WFCRC1, 0xffffffff); - write_nic_dword(priv, WFCRC2, 0xffffffff); - - /* Write PMR register */ - write_nic_byte(priv, PMR, 0x5); - /* Disable tx, enanble rx */ - write_nic_byte(priv, MacBlkCtrl, 0xa); - } - } - - for(i = 0; i < MAX_QUEUE_SIZE; i++) { - skb_queue_purge(&priv->ieee80211->skb_waitQ [i]); - } - for(i = 0; i < MAX_QUEUE_SIZE; i++) { - skb_queue_purge(&priv->ieee80211->skb_aggQ [i]); - } - - skb_queue_purge(&priv->skb_queue); -} - -static void rtl8192_data_hard_stop(struct ieee80211_device *ieee80211) -{ -} - -static void rtl8192_data_hard_resume(struct ieee80211_device *ieee80211) -{ -} - -/* - * this function TX data frames when the ieee80211 stack requires this. - * It checks also if we need to stop the ieee tx queue, eventually do it - */ -static void rtl8192_hard_data_xmit(struct sk_buff *skb, - struct ieee80211_device *ieee80211, int rate) -{ - struct r8192_priv *priv = ieee80211_priv(ieee80211->dev); - int ret; - cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); - u8 queue_index = tcb_desc->queue_index; - - /* shall not be referred by command packet */ - BUG_ON(queue_index == TXCMD_QUEUE); - - if (priv->bHwRadioOff || (!priv->up)) - { - kfree_skb(skb); - return; - } - - skb_push(skb, priv->ieee80211->tx_headroom); - ret = rtl8192_tx(priv, skb); - if (ret != 0) { - kfree_skb(skb); - } - - if (queue_index != MGNT_QUEUE) { - priv->ieee80211->stats.tx_bytes += (skb->len - priv->ieee80211->tx_headroom); - priv->ieee80211->stats.tx_packets++; - } -} - -/* - * This is a rough attempt to TX a frame - * This is called by the ieee 80211 stack to TX management frames. - * If the ring is full packet are dropped (for data frame the queue - * is stopped before this can happen). - */ -static int rtl8192_hard_start_xmit(struct sk_buff *skb, struct ieee80211_device *ieee80211) -{ - struct r8192_priv *priv = ieee80211_priv(ieee80211->dev); - int ret; - cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); - u8 queue_index = tcb_desc->queue_index; - - if (queue_index != TXCMD_QUEUE) { - if (priv->bHwRadioOff || (!priv->up)) - { - kfree_skb(skb); - return 0; - } - } - - if (queue_index == TXCMD_QUEUE) { - rtl819xE_tx_cmd(priv, skb); - ret = 0; - return ret; - } else { - tcb_desc->RATRIndex = 7; - tcb_desc->bTxDisableRateFallBack = 1; - tcb_desc->bTxUseDriverAssingedRate = 1; - tcb_desc->bTxEnableFwCalcDur = 1; - skb_push(skb, ieee80211->tx_headroom); - ret = rtl8192_tx(priv, skb); - if (ret != 0) { - kfree_skb(skb); - } - } - - return ret; -} - - -static void rtl8192_tx_isr(struct r8192_priv *priv, int prio) -{ - struct rtl8192_tx_ring *ring = &priv->tx_ring[prio]; - - while (skb_queue_len(&ring->queue)) { - tx_desc_819x_pci *entry = &ring->desc[ring->idx]; - struct sk_buff *skb; - - /* - * beacon packet will only use the first descriptor defaultly, - * and the OWN may not be cleared by the hardware - */ - if (prio != BEACON_QUEUE) { - if (entry->OWN) - return; - ring->idx = (ring->idx + 1) % ring->entries; - } - - skb = __skb_dequeue(&ring->queue); - pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr), - skb->len, PCI_DMA_TODEVICE); - - kfree_skb(skb); - } - - if (prio != BEACON_QUEUE) { - /* try to deal with the pending packets */ - tasklet_schedule(&priv->irq_tx_tasklet); - } -} - -static void rtl8192_stop_beacon(struct ieee80211_device *ieee80211) -{ -} - -static void rtl8192_config_rate(struct r8192_priv *priv, u16* rate_config) -{ - struct ieee80211_network *net; - u8 i=0, basic_rate = 0; - net = & priv->ieee80211->current_network; - - for (i=0; i<net->rates_len; i++) - { - basic_rate = net->rates[i]&0x7f; - switch(basic_rate) - { - case MGN_1M: *rate_config |= RRSR_1M; break; - case MGN_2M: *rate_config |= RRSR_2M; break; - case MGN_5_5M: *rate_config |= RRSR_5_5M; break; - case MGN_11M: *rate_config |= RRSR_11M; break; - case MGN_6M: *rate_config |= RRSR_6M; break; - case MGN_9M: *rate_config |= RRSR_9M; break; - case MGN_12M: *rate_config |= RRSR_12M; break; - case MGN_18M: *rate_config |= RRSR_18M; break; - case MGN_24M: *rate_config |= RRSR_24M; break; - case MGN_36M: *rate_config |= RRSR_36M; break; - case MGN_48M: *rate_config |= RRSR_48M; break; - case MGN_54M: *rate_config |= RRSR_54M; break; - } - } - for (i=0; i<net->rates_ex_len; i++) - { - basic_rate = net->rates_ex[i]&0x7f; - switch(basic_rate) - { - case MGN_1M: *rate_config |= RRSR_1M; break; - case MGN_2M: *rate_config |= RRSR_2M; break; - case MGN_5_5M: *rate_config |= RRSR_5_5M; break; - case MGN_11M: *rate_config |= RRSR_11M; break; - case MGN_6M: *rate_config |= RRSR_6M; break; - case MGN_9M: *rate_config |= RRSR_9M; break; - case MGN_12M: *rate_config |= RRSR_12M; break; - case MGN_18M: *rate_config |= RRSR_18M; break; - case MGN_24M: *rate_config |= RRSR_24M; break; - case MGN_36M: *rate_config |= RRSR_36M; break; - case MGN_48M: *rate_config |= RRSR_48M; break; - case MGN_54M: *rate_config |= RRSR_54M; break; - } - } -} - - -#define SHORT_SLOT_TIME 9 -#define NON_SHORT_SLOT_TIME 20 - -static void rtl8192_update_cap(struct r8192_priv *priv, u16 cap) -{ - u32 tmp = 0; - struct ieee80211_network *net = &priv->ieee80211->current_network; - - priv->short_preamble = cap & WLAN_CAPABILITY_SHORT_PREAMBLE; - tmp = priv->basic_rate; - if (priv->short_preamble) - tmp |= BRSR_AckShortPmb; - write_nic_dword(priv, RRSR, tmp); - - if (net->mode & (IEEE_G|IEEE_N_24G)) - { - u8 slot_time = 0; - if ((cap & WLAN_CAPABILITY_SHORT_SLOT)&&(!priv->ieee80211->pHTInfo->bCurrentRT2RTLongSlotTime)) - {//short slot time - slot_time = SHORT_SLOT_TIME; - } - else //long slot time - slot_time = NON_SHORT_SLOT_TIME; - priv->slot_time = slot_time; - write_nic_byte(priv, SLOT_TIME, slot_time); - } - -} - -static void rtl8192_net_update(struct r8192_priv *priv) -{ - struct ieee80211_network *net; - u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf; - u16 rate_config = 0; - net = &priv->ieee80211->current_network; - - /* update Basic rate: RR, BRSR */ - rtl8192_config_rate(priv, &rate_config); - - /* - * Select RRSR (in Legacy-OFDM and CCK) - * For 8190, we select only 24M, 12M, 6M, 11M, 5.5M, - * 2M, and 1M from the Basic rate. - * We do not use other rates. - */ - priv->basic_rate = rate_config &= 0x15f; - - /* BSSID */ - write_nic_dword(priv, BSSIDR, ((u32 *)net->bssid)[0]); - write_nic_word(priv, BSSIDR+4, ((u16 *)net->bssid)[2]); - - if (priv->ieee80211->iw_mode == IW_MODE_ADHOC) - { - write_nic_word(priv, ATIMWND, 2); - write_nic_word(priv, BCN_DMATIME, 256); - write_nic_word(priv, BCN_INTERVAL, net->beacon_interval); - /* - * BIT15 of BCN_DRV_EARLY_INT will indicate - * whether software beacon or hw beacon is applied. - */ - write_nic_word(priv, BCN_DRV_EARLY_INT, 10); - write_nic_byte(priv, BCN_ERR_THRESH, 100); - - BcnTimeCfg |= (BcnCW<<BCN_TCFG_CW_SHIFT); - /* TODO: BcnIFS may required to be changed on ASIC */ - BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS; - write_nic_word(priv, BCN_TCFG, BcnTimeCfg); - } -} - -static void rtl819xE_tx_cmd(struct r8192_priv *priv, struct sk_buff *skb) -{ - struct rtl8192_tx_ring *ring; - tx_desc_819x_pci *entry; - unsigned int idx; - dma_addr_t mapping; - cb_desc *tcb_desc; - unsigned long flags; - - ring = &priv->tx_ring[TXCMD_QUEUE]; - mapping = pci_map_single(priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); - - spin_lock_irqsave(&priv->irq_th_lock,flags); - idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries; - entry = &ring->desc[idx]; - - tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); - memset(entry,0,12); - entry->LINIP = tcb_desc->bLastIniPkt; - entry->FirstSeg = 1;//first segment - entry->LastSeg = 1; //last segment - if(tcb_desc->bCmdOrInit == DESC_PACKET_TYPE_INIT) { - entry->CmdInit = DESC_PACKET_TYPE_INIT; - } else { - entry->CmdInit = DESC_PACKET_TYPE_NORMAL; - entry->Offset = sizeof(TX_FWINFO_8190PCI) + 8; - entry->PktSize = (u16)(tcb_desc->pkt_size + entry->Offset); - entry->QueueSelect = QSLT_CMD; - entry->TxFWInfoSize = 0x08; - entry->RATid = (u8)DESC_PACKET_TYPE_INIT; - } - entry->TxBufferSize = skb->len; - entry->TxBuffAddr = cpu_to_le32(mapping); - entry->OWN = 1; - - __skb_queue_tail(&ring->queue, skb); - spin_unlock_irqrestore(&priv->irq_th_lock,flags); - - write_nic_byte(priv, TPPoll, TPPoll_CQ); - - return; -} - -/* - * Mapping Software/Hardware descriptor queue id to "Queue Select Field" - * in TxFwInfo data structure - */ -static u8 MapHwQueueToFirmwareQueue(u8 QueueID) -{ - u8 QueueSelect = 0; - - switch (QueueID) { - case BE_QUEUE: - QueueSelect = QSLT_BE; - break; - - case BK_QUEUE: - QueueSelect = QSLT_BK; - break; - - case VO_QUEUE: - QueueSelect = QSLT_VO; - break; - - case VI_QUEUE: - QueueSelect = QSLT_VI; - break; - - case MGNT_QUEUE: - QueueSelect = QSLT_MGNT; - break; - - case BEACON_QUEUE: - QueueSelect = QSLT_BEACON; - break; - - case TXCMD_QUEUE: - QueueSelect = QSLT_CMD; - break; - - case HIGH_QUEUE: - default: - RT_TRACE(COMP_ERR, "Impossible Queue Selection: %d\n", QueueID); - break; - } - return QueueSelect; -} - -static u8 MRateToHwRate8190Pci(u8 rate) -{ - u8 ret = DESC90_RATE1M; - - switch(rate) { - case MGN_1M: ret = DESC90_RATE1M; break; - case MGN_2M: ret = DESC90_RATE2M; break; - case MGN_5_5M: ret = DESC90_RATE5_5M; break; - case MGN_11M: ret = DESC90_RATE11M; break; - case MGN_6M: ret = DESC90_RATE6M; break; - case MGN_9M: ret = DESC90_RATE9M; break; - case MGN_12M: ret = DESC90_RATE12M; break; - case MGN_18M: ret = DESC90_RATE18M; break; - case MGN_24M: ret = DESC90_RATE24M; break; - case MGN_36M: ret = DESC90_RATE36M; break; - case MGN_48M: ret = DESC90_RATE48M; break; - case MGN_54M: ret = DESC90_RATE54M; break; - - // HT rate since here - case MGN_MCS0: ret = DESC90_RATEMCS0; break; - case MGN_MCS1: ret = DESC90_RATEMCS1; break; - case MGN_MCS2: ret = DESC90_RATEMCS2; break; - case MGN_MCS3: ret = DESC90_RATEMCS3; break; - case MGN_MCS4: ret = DESC90_RATEMCS4; break; - case MGN_MCS5: ret = DESC90_RATEMCS5; break; - case MGN_MCS6: ret = DESC90_RATEMCS6; break; - case MGN_MCS7: ret = DESC90_RATEMCS7; break; - case MGN_MCS8: ret = DESC90_RATEMCS8; break; - case MGN_MCS9: ret = DESC90_RATEMCS9; break; - case MGN_MCS10: ret = DESC90_RATEMCS10; break; - case MGN_MCS11: ret = DESC90_RATEMCS11; break; - case MGN_MCS12: ret = DESC90_RATEMCS12; break; - case MGN_MCS13: ret = DESC90_RATEMCS13; break; - case MGN_MCS14: ret = DESC90_RATEMCS14; break; - case MGN_MCS15: ret = DESC90_RATEMCS15; break; - case (0x80|0x20): ret = DESC90_RATEMCS32; break; - - default: break; - } - return ret; -} - - -static u8 QueryIsShort(u8 TxHT, u8 TxRate, cb_desc *tcb_desc) -{ - u8 tmp_Short; - - tmp_Short = (TxHT==1)?((tcb_desc->bUseShortGI)?1:0):((tcb_desc->bUseShortPreamble)?1:0); - - if(TxHT==1 && TxRate != DESC90_RATEMCS15) - tmp_Short = 0; - - return tmp_Short; -} - -/* - * The tx procedure is just as following, - * skb->cb will contain all the following information, - * priority, morefrag, rate, &dev. - */ -static short rtl8192_tx(struct r8192_priv *priv, struct sk_buff* skb) -{ - struct rtl8192_tx_ring *ring; - unsigned long flags; - cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); - tx_desc_819x_pci *pdesc = NULL; - TX_FWINFO_8190PCI *pTxFwInfo = NULL; - dma_addr_t mapping; - bool multi_addr = false, broad_addr = false, uni_addr = false; - u8 *pda_addr = NULL; - int idx; - - if (priv->bdisable_nic) { - RT_TRACE(COMP_ERR, "Nic is disabled! Can't tx packet len=%d qidx=%d!!!\n", - skb->len, tcb_desc->queue_index); - return skb->len; - } - -#ifdef ENABLE_LPS - priv->ieee80211->bAwakePktSent = true; -#endif - - mapping = pci_map_single(priv->pdev, skb->data, skb->len, PCI_DMA_TODEVICE); - - /* collect the tx packets statitcs */ - pda_addr = ((u8 *)skb->data) + sizeof(TX_FWINFO_8190PCI); - if (is_multicast_ether_addr(pda_addr)) - multi_addr = true; - else if (is_broadcast_ether_addr(pda_addr)) - broad_addr = true; - else - uni_addr = true; - - if (uni_addr) - priv->stats.txbytesunicast += (u8)(skb->len) - sizeof(TX_FWINFO_8190PCI); - - /* fill tx firmware */ - pTxFwInfo = (PTX_FWINFO_8190PCI)skb->data; - memset(pTxFwInfo, 0, sizeof(TX_FWINFO_8190PCI)); - pTxFwInfo->TxHT = (tcb_desc->data_rate&0x80) ? 1 : 0; - pTxFwInfo->TxRate = MRateToHwRate8190Pci((u8)tcb_desc->data_rate); - pTxFwInfo->EnableCPUDur = tcb_desc->bTxEnableFwCalcDur; - pTxFwInfo->Short = QueryIsShort(pTxFwInfo->TxHT, pTxFwInfo->TxRate, tcb_desc); - - /* Aggregation related */ - if (tcb_desc->bAMPDUEnable) { - pTxFwInfo->AllowAggregation = 1; - pTxFwInfo->RxMF = tcb_desc->ampdu_factor; - pTxFwInfo->RxAMD = tcb_desc->ampdu_density; - } else { - pTxFwInfo->AllowAggregation = 0; - pTxFwInfo->RxMF = 0; - pTxFwInfo->RxAMD = 0; - } - - /* Protection mode related */ - pTxFwInfo->RtsEnable = (tcb_desc->bRTSEnable) ? 1 : 0; - pTxFwInfo->CtsEnable = (tcb_desc->bCTSEnable) ? 1 : 0; - pTxFwInfo->RtsSTBC = (tcb_desc->bRTSSTBC) ? 1 : 0; - pTxFwInfo->RtsHT = (tcb_desc->rts_rate&0x80) ? 1 : 0; - pTxFwInfo->RtsRate = MRateToHwRate8190Pci((u8)tcb_desc->rts_rate); - pTxFwInfo->RtsBandwidth = 0; - pTxFwInfo->RtsSubcarrier = tcb_desc->RTSSC; - pTxFwInfo->RtsShort = (pTxFwInfo->RtsHT == 0) ? (tcb_desc->bRTSUseShortPreamble ? 1 : 0) : (tcb_desc->bRTSUseShortGI? 1 : 0); - - /* Set Bandwidth and sub-channel settings. */ - if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40) { - if (tcb_desc->bPacketBW) { - pTxFwInfo->TxBandwidth = 1; - /* use duplicated mode */ - pTxFwInfo->TxSubCarrier = 0; - } else { - pTxFwInfo->TxBandwidth = 0; - pTxFwInfo->TxSubCarrier = priv->nCur40MhzPrimeSC; - } - } else { - pTxFwInfo->TxBandwidth = 0; - pTxFwInfo->TxSubCarrier = 0; - } - - spin_lock_irqsave(&priv->irq_th_lock, flags); - ring = &priv->tx_ring[tcb_desc->queue_index]; - if (tcb_desc->queue_index != BEACON_QUEUE) - idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries; - else - idx = 0; - - pdesc = &ring->desc[idx]; - if ((pdesc->OWN == 1) && (tcb_desc->queue_index != BEACON_QUEUE)) { - RT_TRACE(COMP_ERR, "No more TX desc@%d, ring->idx = %d,idx = %d,%x\n", - tcb_desc->queue_index, ring->idx, idx, skb->len); - spin_unlock_irqrestore(&priv->irq_th_lock, flags); - return skb->len; - } - - /* fill tx descriptor */ - memset(pdesc, 0, 12); - - /*DWORD 0*/ - pdesc->LINIP = 0; - pdesc->CmdInit = 1; - pdesc->Offset = sizeof(TX_FWINFO_8190PCI) + 8; /* We must add 8!! */ - pdesc->PktSize = (u16)skb->len-sizeof(TX_FWINFO_8190PCI); - - /*DWORD 1*/ - pdesc->SecCAMID = 0; - pdesc->RATid = tcb_desc->RATRIndex; - - pdesc->NoEnc = 1; - pdesc->SecType = 0x0; - if (tcb_desc->bHwSec) { - switch (priv->ieee80211->pairwise_key_type) { - case KEY_TYPE_WEP40: - case KEY_TYPE_WEP104: - pdesc->SecType = 0x1; - pdesc->NoEnc = 0; - break; - case KEY_TYPE_TKIP: - pdesc->SecType = 0x2; - pdesc->NoEnc = 0; - break; - case KEY_TYPE_CCMP: - pdesc->SecType = 0x3; - pdesc->NoEnc = 0; - break; - case KEY_TYPE_NA: - pdesc->SecType = 0x0; - pdesc->NoEnc = 1; - break; - } - } - - /* Set Packet ID */ - pdesc->PktId = 0x0; - - pdesc->QueueSelect = MapHwQueueToFirmwareQueue(tcb_desc->queue_index); - pdesc->TxFWInfoSize = sizeof(TX_FWINFO_8190PCI); - - pdesc->DISFB = tcb_desc->bTxDisableRateFallBack; - pdesc->USERATE = tcb_desc->bTxUseDriverAssingedRate; - - pdesc->FirstSeg = 1; - pdesc->LastSeg = 1; - pdesc->TxBufferSize = skb->len; - - pdesc->TxBuffAddr = cpu_to_le32(mapping); - __skb_queue_tail(&ring->queue, skb); - pdesc->OWN = 1; - spin_unlock_irqrestore(&priv->irq_th_lock, flags); - priv->ieee80211->dev->trans_start = jiffies; - write_nic_word(priv, TPPoll, 0x01<<tcb_desc->queue_index); - return 0; -} - -static short rtl8192_alloc_rx_desc_ring(struct r8192_priv *priv) -{ - rx_desc_819x_pci *entry = NULL; - int i; - - priv->rx_ring = pci_alloc_consistent(priv->pdev, - sizeof(*priv->rx_ring) * priv->rxringcount, &priv->rx_ring_dma); - - if (!priv->rx_ring || (unsigned long)priv->rx_ring & 0xFF) { - RT_TRACE(COMP_ERR,"Cannot allocate RX ring\n"); - return -ENOMEM; - } - - memset(priv->rx_ring, 0, sizeof(*priv->rx_ring) * priv->rxringcount); - priv->rx_idx = 0; - - for (i = 0; i < priv->rxringcount; i++) { - struct sk_buff *skb = dev_alloc_skb(priv->rxbuffersize); - dma_addr_t *mapping; - entry = &priv->rx_ring[i]; - if (!skb) - return 0; - priv->rx_buf[i] = skb; - mapping = (dma_addr_t *)skb->cb; - *mapping = pci_map_single(priv->pdev, skb_tail_pointer(skb), - priv->rxbuffersize, PCI_DMA_FROMDEVICE); - - entry->BufferAddress = cpu_to_le32(*mapping); - - entry->Length = priv->rxbuffersize; - entry->OWN = 1; - } - - entry->EOR = 1; - return 0; -} - -static int rtl8192_alloc_tx_desc_ring(struct r8192_priv *priv, - unsigned int prio, unsigned int entries) -{ - tx_desc_819x_pci *ring; - dma_addr_t dma; - int i; - - ring = pci_alloc_consistent(priv->pdev, sizeof(*ring) * entries, &dma); - if (!ring || (unsigned long)ring & 0xFF) { - RT_TRACE(COMP_ERR, "Cannot allocate TX ring (prio = %d)\n", prio); - return -ENOMEM; - } - - memset(ring, 0, sizeof(*ring)*entries); - priv->tx_ring[prio].desc = ring; - priv->tx_ring[prio].dma = dma; - priv->tx_ring[prio].idx = 0; - priv->tx_ring[prio].entries = entries; - skb_queue_head_init(&priv->tx_ring[prio].queue); - - for (i = 0; i < entries; i++) - ring[i].NextDescAddress = - cpu_to_le32((u32)dma + ((i + 1) % entries) * sizeof(*ring)); - - return 0; -} - -static short rtl8192_pci_initdescring(struct r8192_priv *priv) -{ - u32 ret; - int i; - - ret = rtl8192_alloc_rx_desc_ring(priv); - if (ret) - return ret; - - /* general process for other queue */ - for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) { - ret = rtl8192_alloc_tx_desc_ring(priv, i, priv->txringcount); - if (ret) - goto err_free_rings; - } - - return 0; - -err_free_rings: - rtl8192_free_rx_ring(priv); - for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) - if (priv->tx_ring[i].desc) - rtl8192_free_tx_ring(priv, i); - return 1; -} - -static void rtl8192_pci_resetdescring(struct r8192_priv *priv) -{ - int i; - - /* force the rx_idx to the first one */ - if(priv->rx_ring) { - rx_desc_819x_pci *entry = NULL; - for (i = 0; i < priv->rxringcount; i++) { - entry = &priv->rx_ring[i]; - entry->OWN = 1; - } - priv->rx_idx = 0; - } - - /* after reset, release previous pending packet, and force the - * tx idx to the first one */ - for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) { - if (priv->tx_ring[i].desc) { - struct rtl8192_tx_ring *ring = &priv->tx_ring[i]; - - while (skb_queue_len(&ring->queue)) { - tx_desc_819x_pci *entry = &ring->desc[ring->idx]; - struct sk_buff *skb = __skb_dequeue(&ring->queue); - - pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr), - skb->len, PCI_DMA_TODEVICE); - kfree_skb(skb); - ring->idx = (ring->idx + 1) % ring->entries; - } - ring->idx = 0; - } - } -} - -static void rtl8192_link_change(struct ieee80211_device *ieee) -{ - struct r8192_priv *priv = ieee80211_priv(ieee->dev); - - if (ieee->state == IEEE80211_LINKED) - { - rtl8192_net_update(priv); - rtl8192_update_ratr_table(priv); - - //add this as in pure N mode, wep encryption will use software way, but there is no chance to set this as wep will not set group key in wext. WB.2008.07.08 - if ((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) - EnableHWSecurityConfig8192(priv); - } - else - { - write_nic_byte(priv, 0x173, 0); - } - - rtl8192_update_msr(priv); - - // 2007/10/16 MH MAC Will update TSF according to all received beacon, so we have - // // To set CBSSID bit when link with any AP or STA. - if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC) - { - u32 reg = 0; - reg = read_nic_dword(priv, RCR); - if (priv->ieee80211->state == IEEE80211_LINKED) - priv->ReceiveConfig = reg |= RCR_CBSSID; - else - priv->ReceiveConfig = reg &= ~RCR_CBSSID; - write_nic_dword(priv, RCR, reg); - } -} - - -static const struct ieee80211_qos_parameters def_qos_parameters = { - {3,3,3,3},/* cw_min */ - {7,7,7,7},/* cw_max */ - {2,2,2,2},/* aifs */ - {0,0,0,0},/* flags */ - {0,0,0,0} /* tx_op_limit */ -}; - -static void rtl8192_update_beacon(struct work_struct * work) -{ - struct r8192_priv *priv = container_of(work, struct r8192_priv, update_beacon_wq.work); - struct ieee80211_device* ieee = priv->ieee80211; - struct ieee80211_network* net = &ieee->current_network; - - if (ieee->pHTInfo->bCurrentHTSupport) - HTUpdateSelfAndPeerSetting(ieee, net); - ieee->pHTInfo->bCurrentRT2RTLongSlotTime = net->bssht.bdRT2RTLongSlotTime; - rtl8192_update_cap(priv, net->capability); -} - -/* -* background support to run QoS activate functionality -*/ -static const int WDCAPARA_ADD[] = {EDCAPARA_BE,EDCAPARA_BK,EDCAPARA_VI,EDCAPARA_VO}; -static void rtl8192_qos_activate(struct work_struct * work) -{ - struct r8192_priv *priv = container_of(work, struct r8192_priv, qos_activate); - struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters; - u8 mode = priv->ieee80211->current_network.mode; - u8 u1bAIFS; - u32 u4bAcParam; - int i; - - mutex_lock(&priv->mutex); - if(priv->ieee80211->state != IEEE80211_LINKED) - goto success; - RT_TRACE(COMP_QOS,"qos active process with associate response received\n"); - /* It better set slot time at first */ - /* For we just support b/g mode at present, let the slot time at 9/20 selection */ - /* update the ac parameter to related registers */ - for(i = 0; i < QOS_QUEUE_NUM; i++) { - //Mode G/A: slotTimeTimer = 9; Mode B: 20 - u1bAIFS = qos_parameters->aifs[i] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime; - u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[i]))<< AC_PARAM_TXOP_LIMIT_OFFSET)| - (((u32)(qos_parameters->cw_max[i]))<< AC_PARAM_ECW_MAX_OFFSET)| - (((u32)(qos_parameters->cw_min[i]))<< AC_PARAM_ECW_MIN_OFFSET)| - ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET)); - write_nic_dword(priv, WDCAPARA_ADD[i], u4bAcParam); - } - -success: - mutex_unlock(&priv->mutex); -} - -static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv, - int active_network, - struct ieee80211_network *network) -{ - int ret = 0; - u32 size = sizeof(struct ieee80211_qos_parameters); - - if(priv->ieee80211->state !=IEEE80211_LINKED) - return ret; - - if ((priv->ieee80211->iw_mode != IW_MODE_INFRA)) - return ret; - - if (network->flags & NETWORK_HAS_QOS_MASK) { - if (active_network && - (network->flags & NETWORK_HAS_QOS_PARAMETERS)) - network->qos_data.active = network->qos_data.supported; - - if ((network->qos_data.active == 1) && (active_network == 1) && - (network->flags & NETWORK_HAS_QOS_PARAMETERS) && - (network->qos_data.old_param_count != - network->qos_data.param_count)) { - network->qos_data.old_param_count = - network->qos_data.param_count; - queue_work(priv->priv_wq, &priv->qos_activate); - RT_TRACE (COMP_QOS, "QoS parameters change call " - "qos_activate\n"); - } - } else { - memcpy(&priv->ieee80211->current_network.qos_data.parameters, - &def_qos_parameters, size); - - if ((network->qos_data.active == 1) && (active_network == 1)) { - queue_work(priv->priv_wq, &priv->qos_activate); - RT_TRACE(COMP_QOS, "QoS was disabled call qos_activate\n"); - } - network->qos_data.active = 0; - network->qos_data.supported = 0; - } - - return 0; -} - -/* handle manage frame frame beacon and probe response */ -static int rtl8192_handle_beacon(struct ieee80211_device *ieee, - struct ieee80211_beacon * beacon, - struct ieee80211_network * network) -{ - struct r8192_priv *priv = ieee80211_priv(ieee->dev); - - rtl8192_qos_handle_probe_response(priv,1,network); - - queue_delayed_work(priv->priv_wq, &priv->update_beacon_wq, 0); - return 0; - -} - -/* - * handling the beaconing responses. if we get different QoS setting - * off the network from the associated setting, adjust the QoS setting - */ -static int rtl8192_qos_association_resp(struct r8192_priv *priv, - struct ieee80211_network *network) -{ - int ret = 0; - unsigned long flags; - u32 size = sizeof(struct ieee80211_qos_parameters); - int set_qos_param = 0; - - if ((priv == NULL) || (network == NULL)) - return ret; - - if (priv->ieee80211->state != IEEE80211_LINKED) - return ret; - - if ((priv->ieee80211->iw_mode != IW_MODE_INFRA)) - return ret; - - spin_lock_irqsave(&priv->ieee80211->lock, flags); - if (network->flags & NETWORK_HAS_QOS_PARAMETERS) { - memcpy(&priv->ieee80211->current_network.qos_data.parameters, - &network->qos_data.parameters, - sizeof(struct ieee80211_qos_parameters)); - priv->ieee80211->current_network.qos_data.active = 1; - set_qos_param = 1; - /* update qos parameter for current network */ - priv->ieee80211->current_network.qos_data.old_param_count = - priv->ieee80211->current_network.qos_data.param_count; - priv->ieee80211->current_network.qos_data.param_count = - network->qos_data.param_count; - - } else { - memcpy(&priv->ieee80211->current_network.qos_data.parameters, - &def_qos_parameters, size); - priv->ieee80211->current_network.qos_data.active = 0; - priv->ieee80211->current_network.qos_data.supported = 0; - set_qos_param = 1; - } - - spin_unlock_irqrestore(&priv->ieee80211->lock, flags); - - RT_TRACE(COMP_QOS, "%s: network->flags = %d,%d\n", __FUNCTION__, - network->flags, priv->ieee80211->current_network.qos_data.active); - if (set_qos_param == 1) - queue_work(priv->priv_wq, &priv->qos_activate); - - return ret; -} - - -static int rtl8192_handle_assoc_response(struct ieee80211_device *ieee, - struct ieee80211_assoc_response_frame *resp, - struct ieee80211_network *network) -{ - struct r8192_priv *priv = ieee80211_priv(ieee->dev); - rtl8192_qos_association_resp(priv, network); - return 0; -} - - -/* updateRATRTabel for MCS only. Basic rate is not implemented. */ -static void rtl8192_update_ratr_table(struct r8192_priv* priv) -{ - struct ieee80211_device* ieee = priv->ieee80211; - u8* pMcsRate = ieee->dot11HTOperationalRateSet; - u32 ratr_value = 0; - u8 rate_index = 0; - - rtl8192_config_rate(priv, (u16*)(&ratr_value)); - ratr_value |= (*(u16*)(pMcsRate)) << 12; - - switch (ieee->mode) - { - case IEEE_A: - ratr_value &= 0x00000FF0; - break; - case IEEE_B: - ratr_value &= 0x0000000F; - break; - case IEEE_G: - ratr_value &= 0x00000FF7; - break; - case IEEE_N_24G: - case IEEE_N_5G: - if (ieee->pHTInfo->PeerMimoPs == 0) //MIMO_PS_STATIC - ratr_value &= 0x0007F007; - else{ - if (priv->rf_type == RF_1T2R) - ratr_value &= 0x000FF007; - else - ratr_value &= 0x0F81F007; - } - break; - default: - break; - } - ratr_value &= 0x0FFFFFFF; - if(ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI40MHz){ - ratr_value |= 0x80000000; - }else if(!ieee->pHTInfo->bCurTxBW40MHz && ieee->pHTInfo->bCurShortGI20MHz){ - ratr_value |= 0x80000000; - } - write_nic_dword(priv, RATR0+rate_index*4, ratr_value); - write_nic_byte(priv, UFWP, 1); -} - -static bool GetNmodeSupportBySecCfg8190Pci(struct ieee80211_device *ieee) -{ - return !(ieee->rtllib_ap_sec_type && - (ieee->rtllib_ap_sec_type(ieee)&(SEC_ALG_WEP|SEC_ALG_TKIP))); -} - -static void rtl8192_refresh_supportrate(struct r8192_priv* priv) -{ - struct ieee80211_device* ieee = priv->ieee80211; - //we donot consider set support rate for ABG mode, only HT MCS rate is set here. - if (ieee->mode == WIRELESS_MODE_N_24G || ieee->mode == WIRELESS_MODE_N_5G) - { - memcpy(ieee->Regdot11HTOperationalRateSet, ieee->RegHTSuppRateSet, 16); - } - else - memset(ieee->Regdot11HTOperationalRateSet, 0, 16); -} - -static u8 rtl8192_getSupportedWireleeMode(void) -{ - return (WIRELESS_MODE_N_24G|WIRELESS_MODE_G|WIRELESS_MODE_B); -} - -static void rtl8192_SetWirelessMode(struct ieee80211_device *ieee, u8 wireless_mode) -{ - struct r8192_priv *priv = ieee80211_priv(ieee->dev); - u8 bSupportMode = rtl8192_getSupportedWireleeMode(); - - if ((wireless_mode == WIRELESS_MODE_AUTO) || ((wireless_mode&bSupportMode)==0)) - { - if(bSupportMode & WIRELESS_MODE_N_24G) - { - wireless_mode = WIRELESS_MODE_N_24G; - } - else if(bSupportMode & WIRELESS_MODE_N_5G) - { - wireless_mode = WIRELESS_MODE_N_5G; - } - else if((bSupportMode & WIRELESS_MODE_A)) - { - wireless_mode = WIRELESS_MODE_A; - } - else if((bSupportMode & WIRELESS_MODE_G)) - { - wireless_mode = WIRELESS_MODE_G; - } - else if((bSupportMode & WIRELESS_MODE_B)) - { - wireless_mode = WIRELESS_MODE_B; - } - else{ - RT_TRACE(COMP_ERR, "%s(), No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n", __FUNCTION__,bSupportMode); - wireless_mode = WIRELESS_MODE_B; - } - } - priv->ieee80211->mode = wireless_mode; - - if ((wireless_mode == WIRELESS_MODE_N_24G) || (wireless_mode == WIRELESS_MODE_N_5G)) - priv->ieee80211->pHTInfo->bEnableHT = 1; - else - priv->ieee80211->pHTInfo->bEnableHT = 0; - RT_TRACE(COMP_INIT, "Current Wireless Mode is %x\n", wireless_mode); - rtl8192_refresh_supportrate(priv); -} - -static bool GetHalfNmodeSupportByAPs819xPci(struct ieee80211_device* ieee) -{ - return ieee->bHalfWirelessN24GMode; -} - -static short rtl8192_is_tx_queue_empty(struct ieee80211_device *ieee) -{ - int i=0; - struct r8192_priv *priv = ieee80211_priv(ieee->dev); - - for (i=0; i<=MGNT_QUEUE; i++) - { - if ((i== TXCMD_QUEUE) || (i == HCCA_QUEUE) ) - continue; - if (skb_queue_len(&(&priv->tx_ring[i])->queue) > 0){ - printk("===>tx queue is not empty:%d, %d\n", i, skb_queue_len(&(&priv->tx_ring[i])->queue)); - return 0; - } - } - return 1; -} - -static void rtl8192_hw_sleep_down(struct r8192_priv *priv) -{ - MgntActSet_RF_State(priv, eRfSleep, RF_CHANGE_BY_PS); -} - -static void rtl8192_hw_wakeup(struct ieee80211_device *ieee) -{ - struct r8192_priv *priv = ieee80211_priv(ieee->dev); - MgntActSet_RF_State(priv, eRfOn, RF_CHANGE_BY_PS); -} - -static void rtl8192_hw_wakeup_wq (struct work_struct *work) -{ - struct delayed_work *dwork = container_of(work,struct delayed_work,work); - struct ieee80211_device *ieee = container_of(dwork,struct ieee80211_device,hw_wakeup_wq); - - rtl8192_hw_wakeup(ieee); -} - -#define MIN_SLEEP_TIME 50 -#define MAX_SLEEP_TIME 10000 -static void rtl8192_hw_to_sleep(struct ieee80211_device *ieee, u32 th, u32 tl) -{ - struct r8192_priv *priv = ieee80211_priv(ieee->dev); - u32 tmp; - u32 rb = jiffies; - - // Writing HW register with 0 equals to disable - // the timer, that is not really what we want - // - tl -= MSECS(8+16+7); - - // If the interval in witch we are requested to sleep is too - // short then give up and remain awake - // when we sleep after send null frame, the timer will be too short to sleep. - // - if(((tl>=rb)&& (tl-rb) <= MSECS(MIN_SLEEP_TIME)) - ||((rb>tl)&& (rb-tl) < MSECS(MIN_SLEEP_TIME))) { - printk("too short to sleep::%x, %x, %lx\n",tl, rb, MSECS(MIN_SLEEP_TIME)); - return; - } - - if(((tl > rb) && ((tl-rb) > MSECS(MAX_SLEEP_TIME)))|| - ((tl < rb) && (tl>MSECS(69)) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))|| - ((tl<rb)&&(tl<MSECS(69))&&((tl+0xffffffff-rb)>MSECS(MAX_SLEEP_TIME)))) { - printk("========>too long to sleep:%x, %x, %lx\n", tl, rb, MSECS(MAX_SLEEP_TIME)); - return; - } - - tmp = (tl>rb)?(tl-rb):(rb-tl); - queue_delayed_work(priv->ieee80211->wq, - &priv->ieee80211->hw_wakeup_wq,tmp); - - rtl8192_hw_sleep_down(priv); -} - -static void rtl8192_init_priv_variable(struct r8192_priv *priv) -{ - u8 i; - PRT_POWER_SAVE_CONTROL pPSC = &priv->PowerSaveControl; - - // Default Halt the NIC if RF is OFF. - pPSC->RegRfPsLevel |= RT_RF_OFF_LEVL_HALT_NIC; - pPSC->RegRfPsLevel |= RT_RF_OFF_LEVL_CLK_REQ; - pPSC->RegRfPsLevel |= RT_RF_OFF_LEVL_ASPM; - pPSC->RegRfPsLevel |= RT_RF_LPS_LEVEL_ASPM; - pPSC->bLeisurePs = true; - priv->ieee80211->RegMaxLPSAwakeIntvl = 5; - priv->bHwRadioOff = false; - - priv->being_init_adapter = false; - priv->txringcount = 64;//32; - priv->rxbuffersize = 9100;//2048;//1024; - priv->rxringcount = MAX_RX_COUNT;//64; - priv->chan = 1; //set to channel 1 - priv->RegWirelessMode = WIRELESS_MODE_AUTO; - priv->RegChannelPlan = 0xf; - priv->ieee80211->mode = WIRELESS_MODE_AUTO; //SET AUTO - priv->ieee80211->iw_mode = IW_MODE_INFRA; - priv->ieee80211->ieee_up=0; - priv->retry_rts = DEFAULT_RETRY_RTS; - priv->retry_data = DEFAULT_RETRY_DATA; - priv->ieee80211->rts = DEFAULT_RTS_THRESHOLD; - priv->ieee80211->rate = 110; //11 mbps - priv->ieee80211->short_slot = 1; - priv->promisc = (priv->ieee80211->dev->flags & IFF_PROMISC) ? 1:0; - priv->bcck_in_ch14 = false; - priv->CCKPresentAttentuation = 0; - priv->rfa_txpowertrackingindex = 0; - priv->rfc_txpowertrackingindex = 0; - priv->CckPwEnl = 6; - //added by amy for silent reset - priv->ResetProgress = RESET_TYPE_NORESET; - priv->bForcedSilentReset = 0; - priv->bDisableNormalResetCheck = false; - priv->force_reset = false; - //added by amy for power save - priv->RfOffReason = 0; - priv->bHwRfOffAction = 0; - priv->PowerSaveControl.bInactivePs = true; - priv->PowerSaveControl.bIPSModeBackup = false; - - priv->ieee80211->current_network.beacon_interval = DEFAULT_BEACONINTERVAL; - priv->ieee80211->iw_mode = IW_MODE_INFRA; - priv->ieee80211->softmac_features = IEEE_SOFTMAC_SCAN | - IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ | - IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE;/* | - IEEE_SOFTMAC_BEACONS;*///added by amy 080604 //| //IEEE_SOFTMAC_SINGLE_QUEUE; - - priv->ieee80211->active_scan = 1; - priv->ieee80211->modulation = IEEE80211_CCK_MODULATION | IEEE80211_OFDM_MODULATION; - priv->ieee80211->host_encrypt = 1; - priv->ieee80211->host_decrypt = 1; - priv->ieee80211->start_send_beacons = rtl8192_start_beacon; - priv->ieee80211->stop_send_beacons = rtl8192_stop_beacon; - priv->ieee80211->softmac_hard_start_xmit = rtl8192_hard_start_xmit; - priv->ieee80211->set_chan = rtl8192_set_chan; - priv->ieee80211->link_change = rtl8192_link_change; - priv->ieee80211->softmac_data_hard_start_xmit = rtl8192_hard_data_xmit; - priv->ieee80211->data_hard_stop = rtl8192_data_hard_stop; - priv->ieee80211->data_hard_resume = rtl8192_data_hard_resume; - priv->ieee80211->init_wmmparam_flag = 0; - priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD; - priv->ieee80211->check_nic_enough_desc = check_nic_enough_desc; - priv->ieee80211->tx_headroom = sizeof(TX_FWINFO_8190PCI); - priv->ieee80211->qos_support = 1; - priv->ieee80211->SetBWModeHandler = rtl8192_SetBWMode; - priv->ieee80211->handle_assoc_response = rtl8192_handle_assoc_response; - priv->ieee80211->handle_beacon = rtl8192_handle_beacon; - - priv->ieee80211->sta_wake_up = rtl8192_hw_wakeup; - priv->ieee80211->enter_sleep_state = rtl8192_hw_to_sleep; - priv->ieee80211->ps_is_queue_empty = rtl8192_is_tx_queue_empty; - priv->ieee80211->GetNmodeSupportBySecCfg = GetNmodeSupportBySecCfg8190Pci; - priv->ieee80211->SetWirelessMode = rtl8192_SetWirelessMode; - priv->ieee80211->GetHalfNmodeSupportByAPsHandler = GetHalfNmodeSupportByAPs819xPci; - - priv->ieee80211->InitialGainHandler = InitialGain819xPci; - -#ifdef ENABLE_IPS - priv->ieee80211->ieee80211_ips_leave_wq = ieee80211_ips_leave_wq; - priv->ieee80211->ieee80211_ips_leave = ieee80211_ips_leave; -#endif -#ifdef ENABLE_LPS - priv->ieee80211->LeisurePSLeave = LeisurePSLeave; -#endif - - priv->ieee80211->SetHwRegHandler = rtl8192e_SetHwReg; - priv->ieee80211->rtllib_ap_sec_type = rtl8192e_ap_sec_type; - - priv->ShortRetryLimit = 0x30; - priv->LongRetryLimit = 0x30; - - priv->ReceiveConfig = RCR_ADD3 | - RCR_AMF | RCR_ADF | //accept management/data - RCR_AICV | //accept control frame for SW AP needs PS-poll, 2005.07.07, by rcnjko. - RCR_AB | RCR_AM | RCR_APM | //accept BC/MC/UC - RCR_AAP | ((u32)7<<RCR_MXDMA_OFFSET) | - ((u32)7 << RCR_FIFO_OFFSET) | RCR_ONLYERLPKT; - - priv->pFirmware = vzalloc(sizeof(rt_firmware)); - - /* rx related queue */ - skb_queue_head_init(&priv->skb_queue); - - /* Tx related queue */ - for(i = 0; i < MAX_QUEUE_SIZE; i++) { - skb_queue_head_init(&priv->ieee80211->skb_waitQ [i]); - } - for(i = 0; i < MAX_QUEUE_SIZE; i++) { - skb_queue_head_init(&priv->ieee80211->skb_aggQ [i]); - } - priv->rf_set_chan = rtl8192_phy_SwChnl; -} - -static void rtl8192_init_priv_lock(struct r8192_priv* priv) -{ - spin_lock_init(&priv->irq_th_lock); - spin_lock_init(&priv->rf_ps_lock); - sema_init(&priv->wx_sem,1); - sema_init(&priv->rf_sem,1); - mutex_init(&priv->mutex); -} - -/* init tasklet and wait_queue here */ -#define DRV_NAME "wlan0" -static void rtl8192_init_priv_task(struct r8192_priv *priv) -{ - priv->priv_wq = create_workqueue(DRV_NAME); - -#ifdef ENABLE_IPS - INIT_WORK(&priv->ieee80211->ips_leave_wq, IPSLeave_wq); -#endif - - INIT_WORK(&priv->reset_wq, rtl8192_restart); - INIT_DELAYED_WORK(&priv->watch_dog_wq, rtl819x_watchdog_wqcallback); - INIT_DELAYED_WORK(&priv->txpower_tracking_wq, dm_txpower_trackingcallback); - INIT_DELAYED_WORK(&priv->rfpath_check_wq, dm_rf_pathcheck_workitemcallback); - INIT_DELAYED_WORK(&priv->update_beacon_wq, rtl8192_update_beacon); - INIT_WORK(&priv->qos_activate, rtl8192_qos_activate); - INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq, rtl8192_hw_wakeup_wq); - - tasklet_init(&priv->irq_rx_tasklet, rtl8192_irq_rx_tasklet, - (unsigned long) priv); - tasklet_init(&priv->irq_tx_tasklet, rtl8192_irq_tx_tasklet, - (unsigned long) priv); - tasklet_init(&priv->irq_prepare_beacon_tasklet, rtl8192_prepare_beacon, - (unsigned long) priv); -} - -static void rtl8192_get_eeprom_size(struct r8192_priv *priv) -{ - u16 curCR = 0; - RT_TRACE(COMP_INIT, "===========>%s()\n", __FUNCTION__); - curCR = read_nic_dword(priv, EPROM_CMD); - RT_TRACE(COMP_INIT, "read from Reg Cmd9346CR(%x):%x\n", EPROM_CMD, curCR); - //whether need I consider BIT5? - priv->epromtype = (curCR & EPROM_CMD_9356SEL) ? EPROM_93c56 : EPROM_93c46; - RT_TRACE(COMP_INIT, "<===========%s(), epromtype:%d\n", __FUNCTION__, priv->epromtype); -} - -/* - * Adapter->EEPROMAddressSize should be set before this function call. - * EEPROM address size can be got through GetEEPROMSize8185() - */ -static void rtl8192_read_eeprom_info(struct r8192_priv *priv) -{ - struct net_device *dev = priv->ieee80211->dev; - u8 tempval; - u8 ICVer8192, ICVer8256; - u16 i,usValue, IC_Version; - u16 EEPROMId; - u8 bMac_Tmp_Addr[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x01}; - RT_TRACE(COMP_INIT, "====> rtl8192_read_eeprom_info\n"); - - - // TODO: I don't know if we need to apply EF function to EEPROM read function - - //2 Read EEPROM ID to make sure autoload is success - EEPROMId = eprom_read(priv, 0); - if( EEPROMId != RTL8190_EEPROM_ID ) - { - RT_TRACE(COMP_ERR, "EEPROM ID is invalid:%x, %x\n", EEPROMId, RTL8190_EEPROM_ID); - priv->AutoloadFailFlag=true; - } - else - { - priv->AutoloadFailFlag=false; - } - - // - // Assign Chip Version ID - // - // Read IC Version && Channel Plan - if(!priv->AutoloadFailFlag) - { - // VID, PID - priv->eeprom_vid = eprom_read(priv, (EEPROM_VID >> 1)); - priv->eeprom_did = eprom_read(priv, (EEPROM_DID >> 1)); - - usValue = eprom_read(priv, (u16)(EEPROM_Customer_ID>>1)) >> 8 ; - priv->eeprom_CustomerID = (u8)( usValue & 0xff); - usValue = eprom_read(priv, (EEPROM_ICVersion_ChannelPlan>>1)); - priv->eeprom_ChannelPlan = usValue&0xff; - IC_Version = ((usValue&0xff00)>>8); - - ICVer8192 = (IC_Version&0xf); //bit0~3; 1:A cut, 2:B cut, 3:C cut... - ICVer8256 = ((IC_Version&0xf0)>>4);//bit4~6, bit7 reserved for other RF chip; 1:A cut, 2:B cut, 3:C cut... - RT_TRACE(COMP_INIT, "ICVer8192 = 0x%x\n", ICVer8192); - RT_TRACE(COMP_INIT, "ICVer8256 = 0x%x\n", ICVer8256); - if(ICVer8192 == 0x2) //B-cut - { - if(ICVer8256 == 0x5) //E-cut - priv->card_8192_version= VERSION_8190_BE; - } - - switch(priv->card_8192_version) - { - case VERSION_8190_BD: - case VERSION_8190_BE: - break; - default: - priv->card_8192_version = VERSION_8190_BD; - break; - } - RT_TRACE(COMP_INIT, "\nIC Version = 0x%x\n", priv->card_8192_version); - } - else - { - priv->card_8192_version = VERSION_8190_BD; - priv->eeprom_vid = 0; - priv->eeprom_did = 0; - priv->eeprom_CustomerID = 0; - priv->eeprom_ChannelPlan = 0; - RT_TRACE(COMP_INIT, "IC Version = 0x%x\n", 0xff); - } - - RT_TRACE(COMP_INIT, "EEPROM VID = 0x%4x\n", priv->eeprom_vid); - RT_TRACE(COMP_INIT, "EEPROM DID = 0x%4x\n", priv->eeprom_did); - RT_TRACE(COMP_INIT,"EEPROM Customer ID: 0x%2x\n", priv->eeprom_CustomerID); - - //2 Read Permanent MAC address - if(!priv->AutoloadFailFlag) - { - for(i = 0; i < 6; i += 2) - { - usValue = eprom_read(priv, (u16) ((EEPROM_NODE_ADDRESS_BYTE_0+i)>>1)); - *(u16*)(&dev->dev_addr[i]) = usValue; - } - } else { - // when auto load failed, the last address byte set to be a random one. - // added by david woo.2007/11/7 - memcpy(dev->dev_addr, bMac_Tmp_Addr, 6); - } - - RT_TRACE(COMP_INIT, "Permanent Address = %pM\n", dev->dev_addr); - - //2 TX Power Check EEPROM Fail or not - if(priv->card_8192_version > VERSION_8190_BD) { - priv->bTXPowerDataReadFromEEPORM = true; - } else { - priv->bTXPowerDataReadFromEEPORM = false; - } - - // 2007/11/15 MH 8190PCI Default=2T4R, 8192PCIE default=1T2R - priv->rf_type = RTL819X_DEFAULT_RF_TYPE; - - if(priv->card_8192_version > VERSION_8190_BD) - { - // Read RF-indication and Tx Power gain index diff of legacy to HT OFDM rate. - if(!priv->AutoloadFailFlag) - { - tempval = (eprom_read(priv, (EEPROM_RFInd_PowerDiff>>1))) & 0xff; - priv->EEPROMLegacyHTTxPowerDiff = tempval & 0xf; // bit[3:0] - - if (tempval&0x80) //RF-indication, bit[7] - priv->rf_type = RF_1T2R; - else - priv->rf_type = RF_2T4R; - } - else - { - priv->EEPROMLegacyHTTxPowerDiff = EEPROM_Default_LegacyHTTxPowerDiff; - } - RT_TRACE(COMP_INIT, "EEPROMLegacyHTTxPowerDiff = %d\n", - priv->EEPROMLegacyHTTxPowerDiff); - - // Read ThermalMeter from EEPROM - if(!priv->AutoloadFailFlag) - { - priv->EEPROMThermalMeter = (u8)(((eprom_read(priv, (EEPROM_ThermalMeter>>1))) & 0xff00)>>8); - } - else - { - priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter; - } - RT_TRACE(COMP_INIT, "ThermalMeter = %d\n", priv->EEPROMThermalMeter); - //vivi, for tx power track - priv->TSSI_13dBm = priv->EEPROMThermalMeter *100; - - if(priv->epromtype == EPROM_93c46) - { - // Read antenna tx power offset of B/C/D to A and CrystalCap from EEPROM - if(!priv->AutoloadFailFlag) - { - usValue = eprom_read(priv, (EEPROM_TxPwDiff_CrystalCap>>1)); - priv->EEPROMAntPwDiff = (usValue&0x0fff); - priv->EEPROMCrystalCap = (u8)((usValue&0xf000)>>12); - } - else - { - priv->EEPROMAntPwDiff = EEPROM_Default_AntTxPowerDiff; - priv->EEPROMCrystalCap = EEPROM_Default_TxPwDiff_CrystalCap; - } - RT_TRACE(COMP_INIT, "EEPROMAntPwDiff = %d\n", priv->EEPROMAntPwDiff); - RT_TRACE(COMP_INIT, "EEPROMCrystalCap = %d\n", priv->EEPROMCrystalCap); - - // - // Get per-channel Tx Power Level - // - for(i=0; i<14; i+=2) - { - if(!priv->AutoloadFailFlag) - { - usValue = eprom_read(priv, (u16) ((EEPROM_TxPwIndex_CCK+i)>>1) ); - } - else - { - usValue = EEPROM_Default_TxPower; - } - *((u16*)(&priv->EEPROMTxPowerLevelCCK[i])) = usValue; - RT_TRACE(COMP_INIT,"CCK Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelCCK[i]); - RT_TRACE(COMP_INIT, "CCK Tx Power Level, Index %d = 0x%02x\n", i+1, priv->EEPROMTxPowerLevelCCK[i+1]); - } - for(i=0; i<14; i+=2) - { - if(!priv->AutoloadFailFlag) - { - usValue = eprom_read(priv, (u16) ((EEPROM_TxPwIndex_OFDM_24G+i)>>1) ); - } - else - { - usValue = EEPROM_Default_TxPower; - } - *((u16*)(&priv->EEPROMTxPowerLevelOFDM24G[i])) = usValue; - RT_TRACE(COMP_INIT, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i, priv->EEPROMTxPowerLevelOFDM24G[i]); - RT_TRACE(COMP_INIT, "OFDM 2.4G Tx Power Level, Index %d = 0x%02x\n", i+1, priv->EEPROMTxPowerLevelOFDM24G[i+1]); - } - } - - // - // Update HAL variables. - // - if(priv->epromtype == EPROM_93c46) - { - for(i=0; i<14; i++) - { - priv->TxPowerLevelCCK[i] = priv->EEPROMTxPowerLevelCCK[i]; - priv->TxPowerLevelOFDM24G[i] = priv->EEPROMTxPowerLevelOFDM24G[i]; - } - priv->LegacyHTTxPowerDiff = priv->EEPROMLegacyHTTxPowerDiff; - // Antenna B gain offset to antenna A, bit0~3 - priv->AntennaTxPwDiff[0] = (priv->EEPROMAntPwDiff & 0xf); - // Antenna C gain offset to antenna A, bit4~7 - priv->AntennaTxPwDiff[1] = ((priv->EEPROMAntPwDiff & 0xf0)>>4); - // Antenna D gain offset to antenna A, bit8~11 - priv->AntennaTxPwDiff[2] = ((priv->EEPROMAntPwDiff & 0xf00)>>8); - // CrystalCap, bit12~15 - priv->CrystalCap = priv->EEPROMCrystalCap; - // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2 - priv->ThermalMeter[0] = (priv->EEPROMThermalMeter & 0xf); - priv->ThermalMeter[1] = ((priv->EEPROMThermalMeter & 0xf0)>>4); - } - else if(priv->epromtype == EPROM_93c56) - { - for(i=0; i<3; i++) // channel 1~3 use the same Tx Power Level. - { - priv->TxPowerLevelCCK_A[i] = priv->EEPROMRfACCKChnl1TxPwLevel[0]; - priv->TxPowerLevelOFDM24G_A[i] = priv->EEPROMRfAOfdmChnlTxPwLevel[0]; - priv->TxPowerLevelCCK_C[i] = priv->EEPROMRfCCCKChnl1TxPwLevel[0]; - priv->TxPowerLevelOFDM24G_C[i] = priv->EEPROMRfCOfdmChnlTxPwLevel[0]; - } - for(i=3; i<9; i++) // channel 4~9 use the same Tx Power Level - { - priv->TxPowerLevelCCK_A[i] = priv->EEPROMRfACCKChnl1TxPwLevel[1]; - priv->TxPowerLevelOFDM24G_A[i] = priv->EEPROMRfAOfdmChnlTxPwLevel[1]; - priv->TxPowerLevelCCK_C[i] = priv->EEPROMRfCCCKChnl1TxPwLevel[1]; - priv->TxPowerLevelOFDM24G_C[i] = priv->EEPROMRfCOfdmChnlTxPwLevel[1]; - } - for(i=9; i<14; i++) // channel 10~14 use the same Tx Power Level - { - priv->TxPowerLevelCCK_A[i] = priv->EEPROMRfACCKChnl1TxPwLevel[2]; - priv->TxPowerLevelOFDM24G_A[i] = priv->EEPROMRfAOfdmChnlTxPwLevel[2]; - priv->TxPowerLevelCCK_C[i] = priv->EEPROMRfCCCKChnl1TxPwLevel[2]; - priv->TxPowerLevelOFDM24G_C[i] = priv->EEPROMRfCOfdmChnlTxPwLevel[2]; - } - for(i=0; i<14; i++) - RT_TRACE(COMP_INIT, "priv->TxPowerLevelCCK_A[%d] = 0x%x\n", i, priv->TxPowerLevelCCK_A[i]); - for(i=0; i<14; i++) - RT_TRACE(COMP_INIT,"priv->TxPowerLevelOFDM24G_A[%d] = 0x%x\n", i, priv->TxPowerLevelOFDM24G_A[i]); - for(i=0; i<14; i++) - RT_TRACE(COMP_INIT, "priv->TxPowerLevelCCK_C[%d] = 0x%x\n", i, priv->TxPowerLevelCCK_C[i]); - for(i=0; i<14; i++) - RT_TRACE(COMP_INIT, "priv->TxPowerLevelOFDM24G_C[%d] = 0x%x\n", i, priv->TxPowerLevelOFDM24G_C[i]); - priv->LegacyHTTxPowerDiff = priv->EEPROMLegacyHTTxPowerDiff; - priv->AntennaTxPwDiff[0] = 0; - priv->AntennaTxPwDiff[1] = 0; - priv->AntennaTxPwDiff[2] = 0; - priv->CrystalCap = priv->EEPROMCrystalCap; - // ThermalMeter, bit0~3 for RFIC1, bit4~7 for RFIC2 - priv->ThermalMeter[0] = (priv->EEPROMThermalMeter & 0xf); - priv->ThermalMeter[1] = ((priv->EEPROMThermalMeter & 0xf0)>>4); - } - } - - if(priv->rf_type == RF_1T2R) - { - RT_TRACE(COMP_INIT, "1T2R config\n"); - } - else if (priv->rf_type == RF_2T4R) - { - RT_TRACE(COMP_INIT, "2T4R config\n"); - } - - // 2008/01/16 MH We can only know RF type in the function. So we have to init - // DIG RATR table again. - init_rate_adaptive(priv); - - //1 Make a copy for following variables and we can change them if we want - - if(priv->RegChannelPlan == 0xf) - { - priv->ChannelPlan = priv->eeprom_ChannelPlan; - } - else - { - priv->ChannelPlan = priv->RegChannelPlan; - } - - // - // Used PID and DID to Set CustomerID - // - if( priv->eeprom_vid == 0x1186 && priv->eeprom_did == 0x3304 ) - { - priv->CustomerID = RT_CID_DLINK; - } - - switch(priv->eeprom_CustomerID) - { - case EEPROM_CID_DEFAULT: - priv->CustomerID = RT_CID_DEFAULT; - break; - case EEPROM_CID_CAMEO: - priv->CustomerID = RT_CID_819x_CAMEO; - break; - case EEPROM_CID_RUNTOP: - priv->CustomerID = RT_CID_819x_RUNTOP; - break; - case EEPROM_CID_NetCore: - priv->CustomerID = RT_CID_819x_Netcore; - break; - case EEPROM_CID_TOSHIBA: // Merge by Jacken, 2008/01/31 - priv->CustomerID = RT_CID_TOSHIBA; - if(priv->eeprom_ChannelPlan&0x80) - priv->ChannelPlan = priv->eeprom_ChannelPlan&0x7f; - else - priv->ChannelPlan = 0x0; - RT_TRACE(COMP_INIT, "Toshiba ChannelPlan = 0x%x\n", - priv->ChannelPlan); - break; - case EEPROM_CID_Nettronix: - priv->CustomerID = RT_CID_Nettronix; - break; - case EEPROM_CID_Pronet: - priv->CustomerID = RT_CID_PRONET; - break; - case EEPROM_CID_DLINK: - priv->CustomerID = RT_CID_DLINK; - break; - - case EEPROM_CID_WHQL: - break; - default: - // value from RegCustomerID - break; - } - - //Avoid the channel plan array overflow, by Bruce, 2007-08-27. - if(priv->ChannelPlan > CHANNEL_PLAN_LEN - 1) - priv->ChannelPlan = 0; //FCC - - if( priv->eeprom_vid == 0x1186 && priv->eeprom_did == 0x3304) - priv->ieee80211->bSupportRemoteWakeUp = true; - else - priv->ieee80211->bSupportRemoteWakeUp = false; - - - RT_TRACE(COMP_INIT, "RegChannelPlan(%d)\n", priv->RegChannelPlan); - RT_TRACE(COMP_INIT, "ChannelPlan = %d\n", priv->ChannelPlan); - RT_TRACE(COMP_TRACE, "<==== ReadAdapterInfo\n"); -} - - -static short rtl8192_get_channel_map(struct r8192_priv *priv) -{ -#ifdef ENABLE_DOT11D - if(priv->ChannelPlan> COUNTRY_CODE_GLOBAL_DOMAIN){ - printk("rtl8180_init:Error channel plan! Set to default.\n"); - priv->ChannelPlan= 0; - } - RT_TRACE(COMP_INIT, "Channel plan is %d\n",priv->ChannelPlan); - - rtl819x_set_channel_map(priv->ChannelPlan, priv); -#else - int ch,i; - //Set Default Channel Plan - if(!channels){ - DMESG("No channels, aborting"); - return -1; - } - ch=channels; - priv->ChannelPlan= 0;//hikaru - // set channels 1..14 allowed in given locale - for (i=1; i<=14; i++) { - (priv->ieee80211->channel_map)[i] = (u8)(ch & 0x01); - ch >>= 1; - } -#endif - return 0; -} - -static short rtl8192_init(struct r8192_priv *priv) -{ - struct net_device *dev = priv->ieee80211->dev; - - memset(&(priv->stats),0,sizeof(struct Stats)); - rtl8192_init_priv_variable(priv); - rtl8192_init_priv_lock(priv); - rtl8192_init_priv_task(priv); - rtl8192_get_eeprom_size(priv); - rtl8192_read_eeprom_info(priv); - rtl8192_get_channel_map(priv); - init_hal_dm(priv); - init_timer(&priv->watch_dog_timer); - priv->watch_dog_timer.data = (unsigned long)priv; - priv->watch_dog_timer.function = watch_dog_timer_callback; - if (request_irq(dev->irq, rtl8192_interrupt, IRQF_SHARED, dev->name, priv)) { - printk("Error allocating IRQ %d",dev->irq); - return -1; - }else{ - priv->irq=dev->irq; - printk("IRQ %d",dev->irq); - } - if (rtl8192_pci_initdescring(priv) != 0){ - printk("Endopoints initialization failed"); - return -1; - } - - return 0; -} - -/* - * Actually only set RRSR, RATR and BW_OPMODE registers - * not to do all the hw config as its name says - * This part need to modified according to the rate set we filtered - */ -static void rtl8192_hwconfig(struct r8192_priv *priv) -{ - u32 regRATR = 0, regRRSR = 0; - u8 regBwOpMode = 0, regTmp = 0; - -// Set RRSR, RATR, and BW_OPMODE registers - // - switch (priv->ieee80211->mode) - { - case WIRELESS_MODE_B: - regBwOpMode = BW_OPMODE_20MHZ; - regRATR = RATE_ALL_CCK; - regRRSR = RATE_ALL_CCK; - break; - case WIRELESS_MODE_A: - regBwOpMode = BW_OPMODE_5G |BW_OPMODE_20MHZ; - regRATR = RATE_ALL_OFDM_AG; - regRRSR = RATE_ALL_OFDM_AG; - break; - case WIRELESS_MODE_G: - regBwOpMode = BW_OPMODE_20MHZ; - regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; - regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; - break; - case WIRELESS_MODE_AUTO: - case WIRELESS_MODE_N_24G: - // It support CCK rate by default. - // CCK rate will be filtered out only when associated AP does not support it. - regBwOpMode = BW_OPMODE_20MHZ; - regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS; - regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; - break; - case WIRELESS_MODE_N_5G: - regBwOpMode = BW_OPMODE_5G; - regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS; - regRRSR = RATE_ALL_OFDM_AG; - break; - } - - write_nic_byte(priv, BW_OPMODE, regBwOpMode); - { - u32 ratr_value = 0; - ratr_value = regRATR; - if (priv->rf_type == RF_1T2R) - { - ratr_value &= ~(RATE_ALL_OFDM_2SS); - } - write_nic_dword(priv, RATR0, ratr_value); - write_nic_byte(priv, UFWP, 1); - } - regTmp = read_nic_byte(priv, 0x313); - regRRSR = ((regTmp) << 24) | (regRRSR & 0x00ffffff); - write_nic_dword(priv, RRSR, regRRSR); - - // - // Set Retry Limit here - // - write_nic_word(priv, RETRY_LIMIT, - priv->ShortRetryLimit << RETRY_LIMIT_SHORT_SHIFT | - priv->LongRetryLimit << RETRY_LIMIT_LONG_SHIFT); - // Set Contention Window here - - // Set Tx AGC - - // Set Tx Antenna including Feedback control - - // Set Auto Rate fallback control - - -} - - -static RT_STATUS rtl8192_adapter_start(struct r8192_priv *priv) -{ - struct net_device *dev = priv->ieee80211->dev; - u32 ulRegRead; - RT_STATUS rtStatus = RT_STATUS_SUCCESS; - u8 tmpvalue; - u8 ICVersion,SwitchingRegulatorOutput; - bool bfirmwareok = true; - u32 tmpRegA, tmpRegC, TempCCk; - int i =0; - - RT_TRACE(COMP_INIT, "====>%s()\n", __FUNCTION__); - priv->being_init_adapter = true; - rtl8192_pci_resetdescring(priv); - // 2007/11/02 MH Before initalizing RF. We can not use FW to do RF-R/W. - priv->Rf_Mode = RF_OP_By_SW_3wire; - - //dPLL on - if(priv->ResetProgress == RESET_TYPE_NORESET) - { - write_nic_byte(priv, ANAPAR, 0x37); - // Accordign to designer's explain, LBUS active will never > 10ms. We delay 10ms - // Joseph increae the time to prevent firmware download fail - mdelay(500); - } - - //PlatformSleepUs(10000); - // For any kind of InitializeAdapter process, we shall use system now!! - priv->pFirmware->firmware_status = FW_STATUS_0_INIT; - - // - //3 //Config CPUReset Register - //3// - //3 Firmware Reset Or Not - ulRegRead = read_nic_dword(priv, CPU_GEN); - if(priv->pFirmware->firmware_status == FW_STATUS_0_INIT) - { //called from MPInitialized. do nothing - ulRegRead |= CPU_GEN_SYSTEM_RESET; - }else if(priv->pFirmware->firmware_status == FW_STATUS_5_READY) - ulRegRead |= CPU_GEN_FIRMWARE_RESET; // Called from MPReset - else - RT_TRACE(COMP_ERR, "ERROR in %s(): undefined firmware state(%d)\n", __FUNCTION__, priv->pFirmware->firmware_status); - - write_nic_dword(priv, CPU_GEN, ulRegRead); - - //3// - //3 //Fix the issue of E-cut high temperature issue - //3// - // TODO: E cut only - ICVersion = read_nic_byte(priv, IC_VERRSION); - if(ICVersion >= 0x4) //E-cut only - { - // HW SD suggest that we should not wirte this register too often, so driver - // should readback this register. This register will be modified only when - // power on reset - SwitchingRegulatorOutput = read_nic_byte(priv, SWREGULATOR); - if(SwitchingRegulatorOutput != 0xb8) - { - write_nic_byte(priv, SWREGULATOR, 0xa8); - mdelay(1); - write_nic_byte(priv, SWREGULATOR, 0xb8); - } - } - - //3// - //3// Initialize BB before MAC - //3// - RT_TRACE(COMP_INIT, "BB Config Start!\n"); - rtStatus = rtl8192_BBConfig(priv); - if(rtStatus != RT_STATUS_SUCCESS) - { - RT_TRACE(COMP_ERR, "BB Config failed\n"); - return rtStatus; - } - RT_TRACE(COMP_INIT,"BB Config Finished!\n"); - - //3//Set Loopback mode or Normal mode - //3// - //2006.12.13 by emily. Note!We should not merge these two CPU_GEN register writings - // because setting of System_Reset bit reset MAC to default transmission mode. - //Loopback mode or not - priv->LoopbackMode = RTL819X_NO_LOOPBACK; - if(priv->ResetProgress == RESET_TYPE_NORESET) - { - ulRegRead = read_nic_dword(priv, CPU_GEN); - if(priv->LoopbackMode == RTL819X_NO_LOOPBACK) - { - ulRegRead = ((ulRegRead & CPU_GEN_NO_LOOPBACK_MSK) | CPU_GEN_NO_LOOPBACK_SET); - } - else if (priv->LoopbackMode == RTL819X_MAC_LOOPBACK ) - { - ulRegRead |= CPU_CCK_LOOPBACK; - } - else - { - RT_TRACE(COMP_ERR,"Serious error: wrong loopback mode setting\n"); - } - - //2008.06.03, for WOL - //ulRegRead &= (~(CPU_GEN_GPIO_UART)); - write_nic_dword(priv, CPU_GEN, ulRegRead); - - // 2006.11.29. After reset cpu, we sholud wait for a second, otherwise, it may fail to write registers. Emily - udelay(500); - } - //3Set Hardware(Do nothing now) - rtl8192_hwconfig(priv); - //2======================================================= - // Common Setting for all of the FPGA platform. (part 1) - //2======================================================= - // If there is changes, please make sure it applies to all of the FPGA version - //3 Turn on Tx/Rx - write_nic_byte(priv, CMDR, CR_RE|CR_TE); - - //2Set Tx dma burst - write_nic_byte(priv, PCIF, ((MXDMA2_NoLimit<<MXDMA2_RX_SHIFT) | - (MXDMA2_NoLimit<<MXDMA2_TX_SHIFT) )); - - //set IDR0 here - write_nic_dword(priv, MAC0, ((u32*)dev->dev_addr)[0]); - write_nic_word(priv, MAC4, ((u16*)(dev->dev_addr + 4))[0]); - //set RCR - write_nic_dword(priv, RCR, priv->ReceiveConfig); - - //3 Initialize Number of Reserved Pages in Firmware Queue - write_nic_dword(priv, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK << RSVD_FW_QUEUE_PAGE_BK_SHIFT | - NUM_OF_PAGE_IN_FW_QUEUE_BE << RSVD_FW_QUEUE_PAGE_BE_SHIFT | - NUM_OF_PAGE_IN_FW_QUEUE_VI << RSVD_FW_QUEUE_PAGE_VI_SHIFT | - NUM_OF_PAGE_IN_FW_QUEUE_VO <<RSVD_FW_QUEUE_PAGE_VO_SHIFT); - write_nic_dword(priv, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << RSVD_FW_QUEUE_PAGE_MGNT_SHIFT); - write_nic_dword(priv, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW| - NUM_OF_PAGE_IN_FW_QUEUE_BCN<<RSVD_FW_QUEUE_PAGE_BCN_SHIFT| - NUM_OF_PAGE_IN_FW_QUEUE_PUB<<RSVD_FW_QUEUE_PAGE_PUB_SHIFT); - - rtl8192_tx_enable(priv); - rtl8192_rx_enable(priv); - //3Set Response Rate Setting Register - // CCK rate is supported by default. - // CCK rate will be filtered out only when associated AP does not support it. - ulRegRead = (0xFFF00000 & read_nic_dword(priv, RRSR)) | RATE_ALL_OFDM_AG | RATE_ALL_CCK; - write_nic_dword(priv, RRSR, ulRegRead); - write_nic_dword(priv, RATR0+4*7, (RATE_ALL_OFDM_AG | RATE_ALL_CCK)); - - //2Set AckTimeout - // TODO: (it value is only for FPGA version). need to be changed!!2006.12.18, by Emily - write_nic_byte(priv, ACK_TIMEOUT, 0x30); - - if(priv->ResetProgress == RESET_TYPE_NORESET) - rtl8192_SetWirelessMode(priv->ieee80211, priv->ieee80211->mode); - //----------------------------------------------------------------------------- - // Set up security related. 070106, by rcnjko: - // 1. Clear all H/W keys. - // 2. Enable H/W encryption/decryption. - //----------------------------------------------------------------------------- - CamResetAllEntry(priv); - { - u8 SECR_value = 0x0; - SECR_value |= SCR_TxEncEnable; - SECR_value |= SCR_RxDecEnable; - SECR_value |= SCR_NoSKMC; - write_nic_byte(priv, SECR, SECR_value); - } - //3Beacon related - write_nic_word(priv, ATIMWND, 2); - write_nic_word(priv, BCN_INTERVAL, 100); - for (i=0; i<QOS_QUEUE_NUM; i++) - write_nic_dword(priv, WDCAPARA_ADD[i], 0x005e4332); - // - // Switching regulator controller: This is set temporarily. - // It's not sure if this can be removed in the future. - // PJ advised to leave it by default. - // - write_nic_byte(priv, 0xbe, 0xc0); - - //2======================================================= - // Set PHY related configuration defined in MAC register bank - //2======================================================= - rtl8192_phy_configmac(priv); - - if (priv->card_8192_version > (u8) VERSION_8190_BD) { - rtl8192_phy_getTxPower(priv); - rtl8192_phy_setTxPower(priv, priv->chan); - } - - //if D or C cut - tmpvalue = read_nic_byte(priv, IC_VERRSION); - priv->IC_Cut = tmpvalue; - RT_TRACE(COMP_INIT, "priv->IC_Cut = 0x%x\n", priv->IC_Cut); - if(priv->IC_Cut >= IC_VersionCut_D) - { - //pHalData->bDcut = TRUE; - if(priv->IC_Cut == IC_VersionCut_D) - RT_TRACE(COMP_INIT, "D-cut\n"); - if(priv->IC_Cut == IC_VersionCut_E) - { - RT_TRACE(COMP_INIT, "E-cut\n"); - // HW SD suggest that we should not wirte this register too often, so driver - // should readback this register. This register will be modified only when - // power on reset - } - } - else - { - //pHalData->bDcut = FALSE; - RT_TRACE(COMP_INIT, "Before C-cut\n"); - } - - //Firmware download - RT_TRACE(COMP_INIT, "Load Firmware!\n"); - bfirmwareok = init_firmware(priv); - if(bfirmwareok != true) { - rtStatus = RT_STATUS_FAILURE; - return rtStatus; - } - RT_TRACE(COMP_INIT, "Load Firmware finished!\n"); - - //RF config - if(priv->ResetProgress == RESET_TYPE_NORESET) - { - RT_TRACE(COMP_INIT, "RF Config Started!\n"); - rtStatus = rtl8192_phy_RFConfig(priv); - if(rtStatus != RT_STATUS_SUCCESS) - { - RT_TRACE(COMP_ERR, "RF Config failed\n"); - return rtStatus; - } - RT_TRACE(COMP_INIT, "RF Config Finished!\n"); - } - rtl8192_phy_updateInitGain(priv); - - /*---- Set CCK and OFDM Block "ON"----*/ - rtl8192_setBBreg(priv, rFPGA0_RFMOD, bCCKEn, 0x1); - rtl8192_setBBreg(priv, rFPGA0_RFMOD, bOFDMEn, 0x1); - - //Enable Led - write_nic_byte(priv, 0x87, 0x0); - - //2======================================================= - // RF Power Save - //2======================================================= -#ifdef ENABLE_IPS - -{ - if(priv->RfOffReason > RF_CHANGE_BY_PS) - { // H/W or S/W RF OFF before sleep. - RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RfOffReason(%d)\n", __FUNCTION__,priv->RfOffReason); - MgntActSet_RF_State(priv, eRfOff, priv->RfOffReason); - } - else if(priv->RfOffReason >= RF_CHANGE_BY_IPS) - { // H/W or S/W RF OFF before sleep. - RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for RfOffReason(%d)\n", __FUNCTION__, priv->RfOffReason); - MgntActSet_RF_State(priv, eRfOff, priv->RfOffReason); - } - else - { - RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): RF-ON \n",__FUNCTION__); - priv->eRFPowerState = eRfOn; - priv->RfOffReason = 0; - } -} -#endif - // We can force firmware to do RF-R/W - if(priv->ieee80211->FwRWRF) - priv->Rf_Mode = RF_OP_By_FW; - else - priv->Rf_Mode = RF_OP_By_SW_3wire; - - if(priv->ResetProgress == RESET_TYPE_NORESET) - { - dm_initialize_txpower_tracking(priv); - - if(priv->IC_Cut >= IC_VersionCut_D) - { - tmpRegA = rtl8192_QueryBBReg(priv, rOFDM0_XATxIQImbalance, bMaskDWord); - tmpRegC = rtl8192_QueryBBReg(priv, rOFDM0_XCTxIQImbalance, bMaskDWord); - for(i = 0; i<TxBBGainTableLength; i++) - { - if(tmpRegA == priv->txbbgain_table[i].txbbgain_value) - { - priv->rfa_txpowertrackingindex= (u8)i; - priv->rfa_txpowertrackingindex_real= (u8)i; - priv->rfa_txpowertracking_default = priv->rfa_txpowertrackingindex; - break; - } - } - - TempCCk = rtl8192_QueryBBReg(priv, rCCK0_TxFilter1, bMaskByte2); - - for(i=0 ; i<CCKTxBBGainTableLength ; i++) - { - if(TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0]) - { - priv->CCKPresentAttentuation_20Mdefault =(u8) i; - break; - } - } - priv->CCKPresentAttentuation_40Mdefault = 0; - priv->CCKPresentAttentuation_difference = 0; - priv->CCKPresentAttentuation = priv->CCKPresentAttentuation_20Mdefault; - RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_initial = %d\n", priv->rfa_txpowertrackingindex); - RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real__initial = %d\n", priv->rfa_txpowertrackingindex_real); - RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference_initial = %d\n", priv->CCKPresentAttentuation_difference); - RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_initial = %d\n", priv->CCKPresentAttentuation); - priv->btxpower_tracking = FALSE;//TEMPLY DISABLE - } - } - - rtl8192_irq_enable(priv); - priv->being_init_adapter = false; - return rtStatus; - -} - -static void rtl8192_prepare_beacon(unsigned long arg) -{ - struct r8192_priv *priv = (struct r8192_priv*) arg; - struct sk_buff *skb; - cb_desc *tcb_desc; - - skb = ieee80211_get_beacon(priv->ieee80211); - tcb_desc = (cb_desc *)(skb->cb + 8); - /* prepare misc info for the beacon xmit */ - tcb_desc->queue_index = BEACON_QUEUE; - /* IBSS does not support HT yet, use 1M defaultly */ - tcb_desc->data_rate = 2; - tcb_desc->RATRIndex = 7; - tcb_desc->bTxDisableRateFallBack = 1; - tcb_desc->bTxUseDriverAssingedRate = 1; - - skb_push(skb, priv->ieee80211->tx_headroom); - if(skb){ - rtl8192_tx(priv, skb); - } -} - - -/* - * configure registers for beacon tx and enables it via - * rtl8192_beacon_tx_enable(). rtl8192_beacon_tx_disable() might - * be used to stop beacon transmission - */ -static void rtl8192_start_beacon(struct ieee80211_device *ieee80211) -{ - struct r8192_priv *priv = ieee80211_priv(ieee80211->dev); - struct ieee80211_network *net = &priv->ieee80211->current_network; - u16 BcnTimeCfg = 0; - u16 BcnCW = 6; - u16 BcnIFS = 0xf; - - DMESG("Enabling beacon TX"); - rtl8192_irq_disable(priv); - //rtl8192_beacon_tx_enable(dev); - - /* ATIM window */ - write_nic_word(priv, ATIMWND, 2); - - /* Beacon interval (in unit of TU) */ - write_nic_word(priv, BCN_INTERVAL, net->beacon_interval); - - /* - * DrvErlyInt (in unit of TU). - * (Time to send interrupt to notify driver to c - * hange beacon content) - * */ - write_nic_word(priv, BCN_DRV_EARLY_INT, 10); - - /* - * BcnDMATIM(in unit of us). - * Indicates the time before TBTT to perform beacon queue DMA - * */ - write_nic_word(priv, BCN_DMATIME, 256); - - /* - * Force beacon frame transmission even after receiving - * beacon frame from other ad hoc STA - * */ - write_nic_byte(priv, BCN_ERR_THRESH, 100); - - /* Set CW and IFS */ - BcnTimeCfg |= BcnCW<<BCN_TCFG_CW_SHIFT; - BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS; - write_nic_word(priv, BCN_TCFG, BcnTimeCfg); - - - /* enable the interrupt for ad-hoc process */ - rtl8192_irq_enable(priv); -} - -static bool HalRxCheckStuck8190Pci(struct r8192_priv *priv) -{ - u16 RegRxCounter = read_nic_word(priv, 0x130); - bool bStuck = FALSE; - - RT_TRACE(COMP_RESET,"%s(): RegRxCounter is %d,RxCounter is %d\n",__FUNCTION__,RegRxCounter,priv->RxCounter); - // If rssi is small, we should check rx for long time because of bad rx. - // or maybe it will continuous silent reset every 2 seconds. - priv->rx_chk_cnt++; - if(priv->undecorated_smoothed_pwdb >= (RateAdaptiveTH_High+5)) - { - priv->rx_chk_cnt = 0; /* high rssi, check rx stuck right now. */ - } - else if(priv->undecorated_smoothed_pwdb < (RateAdaptiveTH_High+5) && - ((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_40M) || - (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb>=RateAdaptiveTH_Low_20M)) ) - - { - if(priv->rx_chk_cnt < 2) - { - return bStuck; - } - else - { - priv->rx_chk_cnt = 0; - } - } - else if(((priv->CurrentChannelBW!=HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_40M) || - (priv->CurrentChannelBW==HT_CHANNEL_WIDTH_20&&priv->undecorated_smoothed_pwdb<RateAdaptiveTH_Low_20M)) && - priv->undecorated_smoothed_pwdb >= VeryLowRSSI) - { - if(priv->rx_chk_cnt < 4) - { - return bStuck; - } - else - { - priv->rx_chk_cnt = 0; - } - } - else - { - if(priv->rx_chk_cnt < 8) - { - return bStuck; - } - else - { - priv->rx_chk_cnt = 0; - } - } - if(priv->RxCounter==RegRxCounter) - bStuck = TRUE; - - priv->RxCounter = RegRxCounter; - - return bStuck; -} - -static RESET_TYPE RxCheckStuck(struct r8192_priv *priv) -{ - - if(HalRxCheckStuck8190Pci(priv)) - { - RT_TRACE(COMP_RESET, "RxStuck Condition\n"); - return RESET_TYPE_SILENT; - } - - return RESET_TYPE_NORESET; -} - -static RESET_TYPE rtl819x_check_reset(struct r8192_priv *priv) -{ - RESET_TYPE RxResetType = RESET_TYPE_NORESET; - RT_RF_POWER_STATE rfState; - - rfState = priv->eRFPowerState; - - if (rfState != eRfOff && (priv->ieee80211->iw_mode != IW_MODE_ADHOC)) { - /* - * If driver is in the status of firmware download failure, - * driver skips RF initialization and RF is in turned off state. - * Driver should check whether Rx stuck and do silent reset. And - * if driver is in firmware download failure status, driver - * should initialize RF in the following silent reset procedure - * - * Driver should not check RX stuck in IBSS mode because it is - * required to set Check BSSID in order to send beacon, however, - * if check BSSID is set, STA cannot hear any packet a all. - */ - RxResetType = RxCheckStuck(priv); - } - - RT_TRACE(COMP_RESET, "%s(): RxResetType is %d\n", __FUNCTION__, RxResetType); - - return RxResetType; -} - -#ifdef ENABLE_IPS -static void InactivePsWorkItemCallback(struct r8192_priv *priv) -{ - PRT_POWER_SAVE_CONTROL pPSC = &priv->PowerSaveControl; - - RT_TRACE(COMP_POWER, "InactivePsWorkItemCallback() --------->\n"); - // - // This flag "bSwRfProcessing", indicates the status of IPS procedure, should be set if the IPS workitem - // is really scheduled. - // The old code, sets this flag before scheduling the IPS workitem and however, at the same time the - // previous IPS workitem did not end yet, fails to schedule the current workitem. Thus, bSwRfProcessing - // blocks the IPS procedure of switching RF. - // By Bruce, 2007-12-25. - // - pPSC->bSwRfProcessing = TRUE; - - RT_TRACE(COMP_RF, "InactivePsWorkItemCallback(): Set RF to %s.\n", - pPSC->eInactivePowerState == eRfOff?"OFF":"ON"); - - - MgntActSet_RF_State(priv, pPSC->eInactivePowerState, RF_CHANGE_BY_IPS); - - // - // To solve CAM values miss in RF OFF, rewrite CAM values after RF ON. By Bruce, 2007-09-20. - // - pPSC->bSwRfProcessing = FALSE; - RT_TRACE(COMP_POWER, "InactivePsWorkItemCallback() <---------\n"); -} - -#ifdef ENABLE_LPS -/* Change current and default preamble mode. */ -bool MgntActSet_802_11_PowerSaveMode(struct r8192_priv *priv, u8 rtPsMode) -{ - - // Currently, we do not change power save mode on IBSS mode. - if(priv->ieee80211->iw_mode == IW_MODE_ADHOC) - { - return false; - } - - // - // <RJ_NOTE> If we make HW to fill up the PwrMgt bit for us, - // some AP will not response to our mgnt frames with PwrMgt bit set, - // e.g. cannot associate the AP. - // So I commented out it. 2005.02.16, by rcnjko. - // -// // Change device's power save mode. -// Adapter->HalFunc.SetPSModeHandler( Adapter, rtPsMode ); - - // Update power save mode configured. - //RT_TRACE(COMP_LPS,"%s(): set ieee->ps = %x\n",__FUNCTION__,rtPsMode); - if(!priv->ps_force) { - priv->ieee80211->ps = rtPsMode; - } - - // Awake immediately - if(priv->ieee80211->sta_sleep != 0 && rtPsMode == IEEE80211_PS_DISABLED) - { - // Notify the AP we awke. - rtl8192_hw_wakeup(priv->ieee80211); - priv->ieee80211->sta_sleep = 0; - - spin_lock(&priv->ieee80211->mgmt_tx_lock); - printk("LPS leave: notify AP we are awaked ++++++++++ SendNullFunctionData\n"); - ieee80211_sta_ps_send_null_frame(priv->ieee80211, 0); - spin_unlock(&priv->ieee80211->mgmt_tx_lock); - } - - return true; -} - -/* Enter the leisure power save mode. */ -void LeisurePSEnter(struct ieee80211_device *ieee80211) -{ - struct r8192_priv *priv = ieee80211_priv(ieee80211->dev); - PRT_POWER_SAVE_CONTROL pPSC = &priv->PowerSaveControl; - - if(!((priv->ieee80211->iw_mode == IW_MODE_INFRA) && - (priv->ieee80211->state == IEEE80211_LINKED)) || - (priv->ieee80211->iw_mode == IW_MODE_ADHOC) || - (priv->ieee80211->iw_mode == IW_MODE_MASTER)) - return; - - if (pPSC->bLeisurePs) - { - // Idle for a while if we connect to AP a while ago. - if(pPSC->LpsIdleCount >= RT_CHECK_FOR_HANG_PERIOD) // 4 Sec - { - - if(priv->ieee80211->ps == IEEE80211_PS_DISABLED) - { - MgntActSet_802_11_PowerSaveMode(priv, IEEE80211_PS_MBCAST|IEEE80211_PS_UNICAST); - - } - } - else - pPSC->LpsIdleCount++; - } -} - - -/* Leave leisure power save mode. */ -void LeisurePSLeave(struct ieee80211_device *ieee80211) -{ - struct r8192_priv *priv = ieee80211_priv(ieee80211->dev); - PRT_POWER_SAVE_CONTROL pPSC = &priv->PowerSaveControl; - - if (pPSC->bLeisurePs) - { - if(priv->ieee80211->ps != IEEE80211_PS_DISABLED) - { - // move to lps_wakecomplete() - MgntActSet_802_11_PowerSaveMode(priv, IEEE80211_PS_DISABLED); - - } - } -} -#endif - - -/* Enter the inactive power save mode. RF will be off */ -void IPSEnter(struct r8192_priv *priv) -{ - PRT_POWER_SAVE_CONTROL pPSC = &priv->PowerSaveControl; - RT_RF_POWER_STATE rtState; - - if (pPSC->bInactivePs) - { - rtState = priv->eRFPowerState; - // - // Added by Bruce, 2007-12-25. - // Do not enter IPS in the following conditions: - // (1) RF is already OFF or Sleep - // (2) bSwRfProcessing (indicates the IPS is still under going) - // (3) Connectted (only disconnected can trigger IPS) - // (4) IBSS (send Beacon) - // (5) AP mode (send Beacon) - // - if (rtState == eRfOn && !pPSC->bSwRfProcessing - && (priv->ieee80211->state != IEEE80211_LINKED) ) - { - RT_TRACE(COMP_RF,"IPSEnter(): Turn off RF.\n"); - pPSC->eInactivePowerState = eRfOff; -// queue_work(priv->priv_wq,&(pPSC->InactivePsWorkItem)); - InactivePsWorkItemCallback(priv); - } - } -} - -// -// Description: -// Leave the inactive power save mode, RF will be on. -// 2007.08.17, by shien chang. -// -void IPSLeave(struct r8192_priv *priv) -{ - PRT_POWER_SAVE_CONTROL pPSC = &priv->PowerSaveControl; - RT_RF_POWER_STATE rtState; - - if (pPSC->bInactivePs) - { - rtState = priv->eRFPowerState; - if (rtState != eRfOn && !pPSC->bSwRfProcessing && priv->RfOffReason <= RF_CHANGE_BY_IPS) - { - RT_TRACE(COMP_POWER, "IPSLeave(): Turn on RF.\n"); - pPSC->eInactivePowerState = eRfOn; - InactivePsWorkItemCallback(priv); - } - } -} - -void IPSLeave_wq(struct work_struct *work) -{ - struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, ips_leave_wq); - struct net_device *dev = ieee->dev; - - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); - down(&priv->ieee80211->ips_sem); - IPSLeave(priv); - up(&priv->ieee80211->ips_sem); -} - -void ieee80211_ips_leave_wq(struct ieee80211_device *ieee80211) -{ - struct r8192_priv *priv = ieee80211_priv(ieee80211->dev); - RT_RF_POWER_STATE rtState; - rtState = priv->eRFPowerState; - - if (priv->PowerSaveControl.bInactivePs){ - if(rtState == eRfOff){ - if(priv->RfOffReason > RF_CHANGE_BY_IPS) - { - RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__); - return; - } - else{ - printk("=========>%s(): IPSLeave\n",__FUNCTION__); - queue_work(priv->ieee80211->wq,&priv->ieee80211->ips_leave_wq); - } - } - } -} -//added by amy 090331 end -void ieee80211_ips_leave(struct ieee80211_device *ieee80211) -{ - struct r8192_priv *priv = ieee80211_priv(ieee80211->dev); - down(&ieee80211->ips_sem); - IPSLeave(priv); - up(&ieee80211->ips_sem); -} -#endif - -static void rtl819x_update_rxcounts( - struct r8192_priv *priv, - u32* TotalRxBcnNum, - u32* TotalRxDataNum -) -{ - u16 SlotIndex; - u8 i; - - *TotalRxBcnNum = 0; - *TotalRxDataNum = 0; - - SlotIndex = (priv->ieee80211->LinkDetectInfo.SlotIndex++)%(priv->ieee80211->LinkDetectInfo.SlotNum); - priv->ieee80211->LinkDetectInfo.RxBcnNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvBcnInPeriod; - priv->ieee80211->LinkDetectInfo.RxDataNum[SlotIndex] = priv->ieee80211->LinkDetectInfo.NumRecvDataInPeriod; - for( i=0; i<priv->ieee80211->LinkDetectInfo.SlotNum; i++ ){ - *TotalRxBcnNum += priv->ieee80211->LinkDetectInfo.RxBcnNum[i]; - *TotalRxDataNum += priv->ieee80211->LinkDetectInfo.RxDataNum[i]; - } -} - - -static void rtl819x_watchdog_wqcallback(struct work_struct *work) -{ - struct delayed_work *dwork = container_of(work,struct delayed_work,work); - struct r8192_priv *priv = container_of(dwork,struct r8192_priv,watch_dog_wq); - struct ieee80211_device* ieee = priv->ieee80211; - RESET_TYPE ResetType = RESET_TYPE_NORESET; - bool bBusyTraffic = false; - bool bEnterPS = false; - - if ((!priv->up) || priv->bHwRadioOff) - return; - - if(!priv->up) - return; - hal_dm_watchdog(priv); -#ifdef ENABLE_IPS - if(ieee->actscanning == false){ - if((ieee->iw_mode == IW_MODE_INFRA) && (ieee->state == IEEE80211_NOLINK) && - (priv->eRFPowerState == eRfOn) && !ieee->is_set_key && - (!ieee->proto_stoppping) && !ieee->wx_set_enc){ - if (priv->PowerSaveControl.ReturnPoint == IPS_CALLBACK_NONE){ - IPSEnter(priv); - } - } - } -#endif - {//to get busy traffic condition - if(ieee->state == IEEE80211_LINKED) - { - if( ieee->LinkDetectInfo.NumRxOkInPeriod> 100 || - ieee->LinkDetectInfo.NumTxOkInPeriod> 100 ) { - bBusyTraffic = true; - } - -#ifdef ENABLE_LPS - //added by amy for Leisure PS - if( ((ieee->LinkDetectInfo.NumRxUnicastOkInPeriod + ieee->LinkDetectInfo.NumTxOkInPeriod) > 8 ) || - (ieee->LinkDetectInfo.NumRxUnicastOkInPeriod > 2) ) - { - bEnterPS= false; - } - else - { - bEnterPS= true; - } - - // LeisurePS only work in infra mode. - if(bEnterPS) - { - LeisurePSEnter(priv->ieee80211); - } - else - { - LeisurePSLeave(priv->ieee80211); - } -#endif - - } - else - { -#ifdef ENABLE_LPS - LeisurePSLeave(priv->ieee80211); -#endif - } - - ieee->LinkDetectInfo.NumRxOkInPeriod = 0; - ieee->LinkDetectInfo.NumTxOkInPeriod = 0; - ieee->LinkDetectInfo.NumRxUnicastOkInPeriod = 0; - ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic; - } - - - //added by amy for AP roaming - if(ieee->state == IEEE80211_LINKED && ieee->iw_mode == IW_MODE_INFRA) - { - u32 TotalRxBcnNum = 0; - u32 TotalRxDataNum = 0; - - rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum); - if((TotalRxBcnNum+TotalRxDataNum) == 0) - { - if (priv->eRFPowerState == eRfOff) - RT_TRACE(COMP_ERR,"========>%s()\n",__FUNCTION__); - printk("===>%s(): AP is power off,connect another one\n",__FUNCTION__); - // Dot11d_Reset(dev); - ieee->state = IEEE80211_ASSOCIATING; - notify_wx_assoc_event(priv->ieee80211); - RemovePeerTS(priv->ieee80211,priv->ieee80211->current_network.bssid); - ieee->is_roaming = true; - ieee->is_set_key = false; - ieee->link_change(ieee); - queue_work(ieee->wq, &ieee->associate_procedure_wq); - } - } - ieee->LinkDetectInfo.NumRecvBcnInPeriod=0; - ieee->LinkDetectInfo.NumRecvDataInPeriod=0; - - //check if reset the driver - if (priv->watchdog_check_reset_cnt++ >= 3 && !ieee->is_roaming && - priv->watchdog_last_time != 1) - { - ResetType = rtl819x_check_reset(priv); - priv->watchdog_check_reset_cnt = 3; - } - if(!priv->bDisableNormalResetCheck && ResetType == RESET_TYPE_NORMAL) - { - priv->ResetProgress = RESET_TYPE_NORMAL; - RT_TRACE(COMP_RESET,"%s(): NOMAL RESET\n",__FUNCTION__); - return; - } - /* disable silent reset temply 2008.9.11*/ - - if( ((priv->force_reset) || (!priv->bDisableNormalResetCheck && ResetType==RESET_TYPE_SILENT))) // This is control by OID set in Pomelo - { - priv->watchdog_last_time = 1; - } - else - priv->watchdog_last_time = 0; - - priv->force_reset = false; - priv->bForcedSilentReset = false; - priv->bResetInProgress = false; - RT_TRACE(COMP_TRACE, " <==RtUsbCheckForHangWorkItemCallback()\n"); - -} - -void watch_dog_timer_callback(unsigned long data) -{ - struct r8192_priv *priv = (struct r8192_priv *) data; - queue_delayed_work(priv->priv_wq,&priv->watch_dog_wq,0); - mod_timer(&priv->watch_dog_timer, jiffies + MSECS(IEEE80211_WATCH_DOG_TIME)); - -} - -static int _rtl8192_up(struct r8192_priv *priv) -{ - RT_STATUS init_status = RT_STATUS_SUCCESS; - struct net_device *dev = priv->ieee80211->dev; - - priv->up=1; - priv->ieee80211->ieee_up=1; - priv->bdisable_nic = false; //YJ,add,091111 - RT_TRACE(COMP_INIT, "Bringing up iface\n"); - - init_status = rtl8192_adapter_start(priv); - if(init_status != RT_STATUS_SUCCESS) - { - RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n",__FUNCTION__); - return -1; - } - RT_TRACE(COMP_INIT, "start adapter finished\n"); - - if (priv->eRFPowerState != eRfOn) - MgntActSet_RF_State(priv, eRfOn, priv->RfOffReason); - - if(priv->ieee80211->state != IEEE80211_LINKED) - ieee80211_softmac_start_protocol(priv->ieee80211); - ieee80211_reset_queue(priv->ieee80211); - watch_dog_timer_callback((unsigned long) priv); - if(!netif_queue_stopped(dev)) - netif_start_queue(dev); - else - netif_wake_queue(dev); - - return 0; -} - - -static int rtl8192_open(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - int ret; - - down(&priv->wx_sem); - ret = rtl8192_up(dev); - up(&priv->wx_sem); - return ret; - -} - - -int rtl8192_up(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - if (priv->up == 1) return -1; - - return _rtl8192_up(priv); -} - - -static int rtl8192_close(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - int ret; - - down(&priv->wx_sem); - - ret = rtl8192_down(dev); - - up(&priv->wx_sem); - - return ret; - -} - -int rtl8192_down(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - if (priv->up == 0) return -1; - -#ifdef ENABLE_LPS - //LZM for PS-Poll AID issue. 090429 - if(priv->ieee80211->state == IEEE80211_LINKED) - LeisurePSLeave(priv->ieee80211); -#endif - - priv->up=0; - priv->ieee80211->ieee_up = 0; - RT_TRACE(COMP_DOWN, "==========>%s()\n", __FUNCTION__); -/* FIXME */ - if (!netif_queue_stopped(dev)) - netif_stop_queue(dev); - - rtl8192_irq_disable(priv); - rtl8192_cancel_deferred_work(priv); - deinit_hal_dm(priv); - del_timer_sync(&priv->watch_dog_timer); - - ieee80211_softmac_stop_protocol(priv->ieee80211,true); - - rtl8192_halt_adapter(priv, false); - memset(&priv->ieee80211->current_network, 0 , offsetof(struct ieee80211_network, list)); - - RT_TRACE(COMP_DOWN, "<==========%s()\n", __FUNCTION__); - - return 0; -} - - -void rtl8192_commit(struct r8192_priv *priv) -{ - if (priv->up == 0) return ; - - - ieee80211_softmac_stop_protocol(priv->ieee80211,true); - - rtl8192_irq_disable(priv); - rtl8192_halt_adapter(priv, true); - _rtl8192_up(priv); -} - -static void rtl8192_restart(struct work_struct *work) -{ - struct r8192_priv *priv = container_of(work, struct r8192_priv, reset_wq); - - down(&priv->wx_sem); - - rtl8192_commit(priv); - - up(&priv->wx_sem); -} - -static void r8192_set_multicast(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - priv->promisc = (dev->flags & IFF_PROMISC) ? 1 : 0; -} - - -static int r8192_set_mac_adr(struct net_device *dev, void *mac) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - struct sockaddr *addr = mac; - - down(&priv->wx_sem); - - memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); - - schedule_work(&priv->reset_wq); - up(&priv->wx_sem); - - return 0; -} - -static void r8192e_set_hw_key(struct r8192_priv *priv, struct ieee_param *ipw) -{ - struct ieee80211_device *ieee = priv->ieee80211; - u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff}; - u32 key[4]; - - if (ipw->u.crypt.set_tx) { - if (strcmp(ipw->u.crypt.alg, "CCMP") == 0) - ieee->pairwise_key_type = KEY_TYPE_CCMP; - else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0) - ieee->pairwise_key_type = KEY_TYPE_TKIP; - else if (strcmp(ipw->u.crypt.alg, "WEP") == 0) { - if (ipw->u.crypt.key_len == 13) - ieee->pairwise_key_type = KEY_TYPE_WEP104; - else if (ipw->u.crypt.key_len == 5) - ieee->pairwise_key_type = KEY_TYPE_WEP40; - } else - ieee->pairwise_key_type = KEY_TYPE_NA; - - if (ieee->pairwise_key_type) { - memcpy(key, ipw->u.crypt.key, 16); - EnableHWSecurityConfig8192(priv); - /* - * We fill both index entry and 4th entry for pairwise - * key as in IPW interface, adhoc will only get here, - * so we need index entry for its default key serching! - */ - setKey(priv, 4, ipw->u.crypt.idx, - ieee->pairwise_key_type, - (u8*)ieee->ap_mac_addr, 0, key); - - /* LEAP WEP will never set this. */ - if (ieee->auth_mode != 2) - setKey(priv, ipw->u.crypt.idx, ipw->u.crypt.idx, - ieee->pairwise_key_type, - (u8*)ieee->ap_mac_addr, 0, key); - } - if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) && - ieee->pHTInfo->bCurrentHTSupport) { - write_nic_byte(priv, 0x173, 1); /* fix aes bug */ - } - } else { - memcpy(key, ipw->u.crypt.key, 16); - if (strcmp(ipw->u.crypt.alg, "CCMP") == 0) - ieee->group_key_type= KEY_TYPE_CCMP; - else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0) - ieee->group_key_type = KEY_TYPE_TKIP; - else if (strcmp(ipw->u.crypt.alg, "WEP") == 0) { - if (ipw->u.crypt.key_len == 13) - ieee->group_key_type = KEY_TYPE_WEP104; - else if (ipw->u.crypt.key_len == 5) - ieee->group_key_type = KEY_TYPE_WEP40; - } else - ieee->group_key_type = KEY_TYPE_NA; - - if (ieee->group_key_type) { - setKey(priv, ipw->u.crypt.idx, ipw->u.crypt.idx, - ieee->group_key_type, broadcast_addr, 0, key); - } - } -} - -/* based on ipw2200 driver */ -static int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) -{ - struct r8192_priv *priv = (struct r8192_priv *)ieee80211_priv(dev); - struct iwreq *wrq = (struct iwreq *)rq; - int ret=-1; - struct iw_point *p = &wrq->u.data; - struct ieee_param *ipw = NULL;//(struct ieee_param *)wrq->u.data.pointer; - - down(&priv->wx_sem); - - - if (p->length < sizeof(struct ieee_param) || !p->pointer){ - ret = -EINVAL; - goto out; - } - - ipw = kmalloc(p->length, GFP_KERNEL); - if (ipw == NULL){ - ret = -ENOMEM; - goto out; - } - if (copy_from_user(ipw, p->pointer, p->length)) { - kfree(ipw); - ret = -EFAULT; - goto out; - } - - switch (cmd) { - case RTL_IOCTL_WPA_SUPPLICANT: - /* parse here for HW security */ - if (ipw->cmd == IEEE_CMD_SET_ENCRYPTION) - r8192e_set_hw_key(priv, ipw); - ret = ieee80211_wpa_supplicant_ioctl(priv->ieee80211, &wrq->u.data); - break; - - default: - ret = -EOPNOTSUPP; - break; - } - - kfree(ipw); -out: - up(&priv->wx_sem); - - return ret; -} - -static u8 HwRateToMRate90(bool bIsHT, u8 rate) -{ - u8 ret_rate = 0x02; - - if(!bIsHT) { - switch(rate) { - case DESC90_RATE1M: ret_rate = MGN_1M; break; - case DESC90_RATE2M: ret_rate = MGN_2M; break; - case DESC90_RATE5_5M: ret_rate = MGN_5_5M; break; - case DESC90_RATE11M: ret_rate = MGN_11M; break; - case DESC90_RATE6M: ret_rate = MGN_6M; break; - case DESC90_RATE9M: ret_rate = MGN_9M; break; - case DESC90_RATE12M: ret_rate = MGN_12M; break; - case DESC90_RATE18M: ret_rate = MGN_18M; break; - case DESC90_RATE24M: ret_rate = MGN_24M; break; - case DESC90_RATE36M: ret_rate = MGN_36M; break; - case DESC90_RATE48M: ret_rate = MGN_48M; break; - case DESC90_RATE54M: ret_rate = MGN_54M; break; - - default: - RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n", rate, bIsHT); - break; - } - - } else { - switch(rate) { - case DESC90_RATEMCS0: ret_rate = MGN_MCS0; break; - case DESC90_RATEMCS1: ret_rate = MGN_MCS1; break; - case DESC90_RATEMCS2: ret_rate = MGN_MCS2; break; - case DESC90_RATEMCS3: ret_rate = MGN_MCS3; break; - case DESC90_RATEMCS4: ret_rate = MGN_MCS4; break; - case DESC90_RATEMCS5: ret_rate = MGN_MCS5; break; - case DESC90_RATEMCS6: ret_rate = MGN_MCS6; break; - case DESC90_RATEMCS7: ret_rate = MGN_MCS7; break; - case DESC90_RATEMCS8: ret_rate = MGN_MCS8; break; - case DESC90_RATEMCS9: ret_rate = MGN_MCS9; break; - case DESC90_RATEMCS10: ret_rate = MGN_MCS10; break; - case DESC90_RATEMCS11: ret_rate = MGN_MCS11; break; - case DESC90_RATEMCS12: ret_rate = MGN_MCS12; break; - case DESC90_RATEMCS13: ret_rate = MGN_MCS13; break; - case DESC90_RATEMCS14: ret_rate = MGN_MCS14; break; - case DESC90_RATEMCS15: ret_rate = MGN_MCS15; break; - case DESC90_RATEMCS32: ret_rate = (0x80|0x20); break; - - default: - RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported Rate [%x], bIsHT = %d!!!\n",rate, bIsHT); - break; - } - } - - return ret_rate; -} - -/* Record the TSF time stamp when receiving a packet */ -static void UpdateRxPktTimeStamp8190(struct r8192_priv *priv, struct ieee80211_rx_stats *stats) -{ - - if(stats->bIsAMPDU && !stats->bFirstMPDU) { - stats->mac_time[0] = priv->LastRxDescTSFLow; - stats->mac_time[1] = priv->LastRxDescTSFHigh; - } else { - priv->LastRxDescTSFLow = stats->mac_time[0]; - priv->LastRxDescTSFHigh = stats->mac_time[1]; - } -} - -static long rtl819x_translate_todbm(u8 signal_strength_index)// 0-100 index. -{ - long signal_power; // in dBm. - - // Translate to dBm (x=0.5y-95). - signal_power = (long)((signal_strength_index + 1) >> 1); - signal_power -= 95; - - return signal_power; -} - -/* 2008/01/22 MH We can not delcare RSSI/EVM total value of sliding window to - be a local static. Otherwise, it may increase when we return from S3/S4. The - value will be kept in memory or disk. We must delcare the value in adapter - and it will be reinitialized when return from S3/S4. */ -static void rtl8192_process_phyinfo(struct r8192_priv * priv, u8* buffer,struct ieee80211_rx_stats * pprevious_stats, struct ieee80211_rx_stats * pcurrent_stats) -{ - bool bcheck = false; - u8 rfpath; - u32 nspatial_stream, tmp_val; - static u32 slide_rssi_index=0, slide_rssi_statistics=0; - static u32 slide_evm_index=0, slide_evm_statistics=0; - static u32 last_rssi=0, last_evm=0; - //cosa add for beacon rssi smoothing - static u32 slide_beacon_adc_pwdb_index=0, slide_beacon_adc_pwdb_statistics=0; - static u32 last_beacon_adc_pwdb=0; - - struct ieee80211_hdr_3addr *hdr; - u16 sc ; - unsigned int frag,seq; - hdr = (struct ieee80211_hdr_3addr *)buffer; - sc = le16_to_cpu(hdr->seq_ctl); - frag = WLAN_GET_SEQ_FRAG(sc); - seq = WLAN_GET_SEQ_SEQ(sc); - - // - // Check whether we should take the previous packet into accounting - // - if(!pprevious_stats->bIsAMPDU) - { - // if previous packet is not aggregated packet - bcheck = true; - } - - if(slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX) - { - slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX; - last_rssi = priv->stats.slide_signal_strength[slide_rssi_index]; - priv->stats.slide_rssi_total -= last_rssi; - } - priv->stats.slide_rssi_total += pprevious_stats->SignalStrength; - - priv->stats.slide_signal_strength[slide_rssi_index++] = pprevious_stats->SignalStrength; - if(slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX) - slide_rssi_index = 0; - - // <1> Showed on UI for user, in dbm - tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics; - priv->stats.signal_strength = rtl819x_translate_todbm((u8)tmp_val); - pcurrent_stats->rssi = priv->stats.signal_strength; - // - // If the previous packet does not match the criteria, neglect it - // - if(!pprevious_stats->bPacketMatchBSSID) - { - if(!pprevious_stats->bToSelfBA) - return; - } - - if(!bcheck) - return; - - // <2> Showed on UI for engineering - // hardware does not provide rssi information for each rf path in CCK - if(!pprevious_stats->bIsCCK && pprevious_stats->bPacketToSelf) - { - for (rfpath = RF90_PATH_A; rfpath < RF90_PATH_C; rfpath++) - { - if (!rtl8192_phy_CheckIsLegalRFPath(priv, rfpath)) - continue; - RT_TRACE(COMP_DBG, "pPreviousstats->RxMIMOSignalStrength[rfpath] = %d\n", pprevious_stats->RxMIMOSignalStrength[rfpath]); - //Fixed by Jacken 2008-03-20 - if(priv->stats.rx_rssi_percentage[rfpath] == 0) - { - priv->stats.rx_rssi_percentage[rfpath] = pprevious_stats->RxMIMOSignalStrength[rfpath]; - } - if(pprevious_stats->RxMIMOSignalStrength[rfpath] > priv->stats.rx_rssi_percentage[rfpath]) - { - priv->stats.rx_rssi_percentage[rfpath] = - ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) + - (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor); - priv->stats.rx_rssi_percentage[rfpath] = priv->stats.rx_rssi_percentage[rfpath] + 1; - } - else - { - priv->stats.rx_rssi_percentage[rfpath] = - ( (priv->stats.rx_rssi_percentage[rfpath]*(Rx_Smooth_Factor-1)) + - (pprevious_stats->RxMIMOSignalStrength[rfpath])) /(Rx_Smooth_Factor); - } - RT_TRACE(COMP_DBG, "priv->RxStats.RxRSSIPercentage[rfPath] = %d \n" , priv->stats.rx_rssi_percentage[rfpath]); - } - } - - - // - // Check PWDB. - // - //cosa add for beacon rssi smoothing by average. - if(pprevious_stats->bPacketBeacon) - { - /* record the beacon pwdb to the sliding window. */ - if(slide_beacon_adc_pwdb_statistics++ >= PHY_Beacon_RSSI_SLID_WIN_MAX) - { - slide_beacon_adc_pwdb_statistics = PHY_Beacon_RSSI_SLID_WIN_MAX; - last_beacon_adc_pwdb = priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index]; - priv->stats.Slide_Beacon_Total -= last_beacon_adc_pwdb; - // slide_beacon_adc_pwdb_index, last_beacon_adc_pwdb, Adapter->RxStats.Slide_Beacon_Total); - } - priv->stats.Slide_Beacon_Total += pprevious_stats->RxPWDBAll; - priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index] = pprevious_stats->RxPWDBAll; - slide_beacon_adc_pwdb_index++; - if(slide_beacon_adc_pwdb_index >= PHY_Beacon_RSSI_SLID_WIN_MAX) - slide_beacon_adc_pwdb_index = 0; - pprevious_stats->RxPWDBAll = priv->stats.Slide_Beacon_Total/slide_beacon_adc_pwdb_statistics; - if(pprevious_stats->RxPWDBAll >= 3) - pprevious_stats->RxPWDBAll -= 3; - } - - RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n", - pprevious_stats->bIsCCK? "CCK": "OFDM", - pprevious_stats->RxPWDBAll); - - if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA) - { - if(priv->undecorated_smoothed_pwdb < 0) // initialize - { - priv->undecorated_smoothed_pwdb = pprevious_stats->RxPWDBAll; - } - - if(pprevious_stats->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb) - { - priv->undecorated_smoothed_pwdb = - ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) + - (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor); - priv->undecorated_smoothed_pwdb = priv->undecorated_smoothed_pwdb + 1; - } - else - { - priv->undecorated_smoothed_pwdb = - ( ((priv->undecorated_smoothed_pwdb)*(Rx_Smooth_Factor-1)) + - (pprevious_stats->RxPWDBAll)) /(Rx_Smooth_Factor); - } - } - - // - // Check EVM - // - /* record the general EVM to the sliding window. */ - if(pprevious_stats->SignalQuality == 0) - { - } - else - { - if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA){ - if(slide_evm_statistics++ >= PHY_RSSI_SLID_WIN_MAX){ - slide_evm_statistics = PHY_RSSI_SLID_WIN_MAX; - last_evm = priv->stats.slide_evm[slide_evm_index]; - priv->stats.slide_evm_total -= last_evm; - } - - priv->stats.slide_evm_total += pprevious_stats->SignalQuality; - - priv->stats.slide_evm[slide_evm_index++] = pprevious_stats->SignalQuality; - if(slide_evm_index >= PHY_RSSI_SLID_WIN_MAX) - slide_evm_index = 0; - - // <1> Showed on UI for user, in percentage. - tmp_val = priv->stats.slide_evm_total/slide_evm_statistics; - //cosa add 10/11/2007, Showed on UI for user in Windows Vista, for Link quality. - } - - // <2> Showed on UI for engineering - if(pprevious_stats->bPacketToSelf || pprevious_stats->bPacketBeacon || pprevious_stats->bToSelfBA) - { - for(nspatial_stream = 0; nspatial_stream<2 ; nspatial_stream++) // 2 spatial stream - { - if(pprevious_stats->RxMIMOSignalQuality[nspatial_stream] != -1) - { - if(priv->stats.rx_evm_percentage[nspatial_stream] == 0) // initialize - { - priv->stats.rx_evm_percentage[nspatial_stream] = pprevious_stats->RxMIMOSignalQuality[nspatial_stream]; - } - priv->stats.rx_evm_percentage[nspatial_stream] = - ( (priv->stats.rx_evm_percentage[nspatial_stream]* (Rx_Smooth_Factor-1)) + - (pprevious_stats->RxMIMOSignalQuality[nspatial_stream]* 1)) / (Rx_Smooth_Factor); - } - } - } - } - -} - -static u8 rtl819x_query_rxpwrpercentage( - char antpower - ) -{ - if ((antpower <= -100) || (antpower >= 20)) - { - return 0; - } - else if (antpower >= 0) - { - return 100; - } - else - { - return (100+antpower); - } - -} - -static u8 -rtl819x_evm_dbtopercentage( - char value - ) -{ - char ret_val; - - ret_val = value; - - if(ret_val >= 0) - ret_val = 0; - if(ret_val <= -33) - ret_val = -33; - ret_val = 0 - ret_val; - ret_val*=3; - if(ret_val == 99) - ret_val = 100; - return ret_val; -} - -/* We want good-looking for signal strength/quality */ -static long rtl819x_signal_scale_mapping(long currsig) -{ - long retsig; - - // Step 1. Scale mapping. - if(currsig >= 61 && currsig <= 100) - { - retsig = 90 + ((currsig - 60) / 4); - } - else if(currsig >= 41 && currsig <= 60) - { - retsig = 78 + ((currsig - 40) / 2); - } - else if(currsig >= 31 && currsig <= 40) - { - retsig = 66 + (currsig - 30); - } - else if(currsig >= 21 && currsig <= 30) - { - retsig = 54 + (currsig - 20); - } - else if(currsig >= 5 && currsig <= 20) - { - retsig = 42 + (((currsig - 5) * 2) / 3); - } - else if(currsig == 4) - { - retsig = 36; - } - else if(currsig == 3) - { - retsig = 27; - } - else if(currsig == 2) - { - retsig = 18; - } - else if(currsig == 1) - { - retsig = 9; - } - else - { - retsig = currsig; - } - - return retsig; -} - -static void rtl8192_query_rxphystatus( - struct r8192_priv * priv, - struct ieee80211_rx_stats * pstats, - prx_desc_819x_pci pdesc, - prx_fwinfo_819x_pci pdrvinfo, - struct ieee80211_rx_stats * precord_stats, - bool bpacket_match_bssid, - bool bpacket_toself, - bool bPacketBeacon, - bool bToSelfBA - ) -{ - //PRT_RFD_STATUS pRtRfdStatus = &(pRfd->Status); - phy_sts_ofdm_819xpci_t* pofdm_buf; - phy_sts_cck_819xpci_t * pcck_buf; - phy_ofdm_rx_status_rxsc_sgien_exintfflag* prxsc; - u8 *prxpkt; - u8 i,max_spatial_stream, tmp_rxsnr, tmp_rxevm, rxsc_sgien_exflg; - char rx_pwr[4], rx_pwr_all=0; - //long rx_avg_pwr = 0; - char rx_snrX, rx_evmX; - u8 evm, pwdb_all; - u32 RSSI, total_rssi=0;//, total_evm=0; -// long signal_strength_index = 0; - u8 is_cck_rate=0; - u8 rf_rx_num = 0; - - is_cck_rate = rx_hal_is_cck_rate(pdrvinfo); - - // Record it for next packet processing - memset(precord_stats, 0, sizeof(struct ieee80211_rx_stats)); - pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID = bpacket_match_bssid; - pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself; - pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate;//RX_HAL_IS_CCK_RATE(pDrvInfo); - pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon; - pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA; - /*2007.08.30 requested by SD3 Jerry */ - if (priv->phy_check_reg824 == 0) - { - priv->phy_reg824_bit9 = rtl8192_QueryBBReg(priv, rFPGA0_XA_HSSIParameter2, 0x200); - priv->phy_check_reg824 = 1; - } - - - prxpkt = (u8*)pdrvinfo; - - /* Move pointer to the 16th bytes. Phy status start address. */ - prxpkt += sizeof(rx_fwinfo_819x_pci); - - /* Initial the cck and ofdm buffer pointer */ - pcck_buf = (phy_sts_cck_819xpci_t *)prxpkt; - pofdm_buf = (phy_sts_ofdm_819xpci_t *)prxpkt; - - pstats->RxMIMOSignalQuality[0] = -1; - pstats->RxMIMOSignalQuality[1] = -1; - precord_stats->RxMIMOSignalQuality[0] = -1; - precord_stats->RxMIMOSignalQuality[1] = -1; - - if(is_cck_rate) - { - // - // (1)Hardware does not provide RSSI for CCK - // - - // - // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive) - // - u8 report;//, cck_agc_rpt; - - if (!priv->phy_reg824_bit9) - { - report = pcck_buf->cck_agc_rpt & 0xc0; - report = report>>6; - switch(report) - { - //Fixed by Jacken from Bryant 2008-03-20 - //Original value is -38 , -26 , -14 , -2 - //Fixed value is -35 , -23 , -11 , 6 - case 0x3: - rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & 0x3e); - break; - case 0x2: - rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt & 0x3e); - break; - case 0x1: - rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt & 0x3e); - break; - case 0x0: - rx_pwr_all = 8 - (pcck_buf->cck_agc_rpt & 0x3e); - break; - } - } - else - { - report = pcck_buf->cck_agc_rpt & 0x60; - report = report>>5; - switch(report) - { - case 0x3: - rx_pwr_all = -35 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ; - break; - case 0x2: - rx_pwr_all = -23 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1); - break; - case 0x1: - rx_pwr_all = -11 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ; - break; - case 0x0: - rx_pwr_all = -8 - ((pcck_buf->cck_agc_rpt & 0x1f)<<1) ; - break; - } - } - - pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all); - pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all; - pstats->RecvSignalPower = rx_pwr_all; - - // - // (3) Get Signal Quality (EVM) - // - if(bpacket_match_bssid) - { - u8 sq; - - if(pstats->RxPWDBAll > 40) - { - sq = 100; - }else - { - sq = pcck_buf->sq_rpt; - - if(pcck_buf->sq_rpt > 64) - sq = 0; - else if (pcck_buf->sq_rpt < 20) - sq = 100; - else - sq = ((64-sq) * 100) / 44; - } - pstats->SignalQuality = precord_stats->SignalQuality = sq; - pstats->RxMIMOSignalQuality[0] = precord_stats->RxMIMOSignalQuality[0] = sq; - pstats->RxMIMOSignalQuality[1] = precord_stats->RxMIMOSignalQuality[1] = -1; - } - } - else - { - // - // (1)Get RSSI for HT rate - // - for(i=RF90_PATH_A; i<RF90_PATH_MAX; i++) - { - // 2008/01/30 MH we will judge RF RX path now. - if (priv->brfpath_rxenable[i]) - rf_rx_num++; - //else - //continue; - - //Fixed by Jacken from Bryant 2008-03-20 - //Original value is 106 - rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i]&0x3F)*2) - 110; - - //Get Rx snr value in DB - tmp_rxsnr = pofdm_buf->rxsnr_X[i]; - rx_snrX = (char)(tmp_rxsnr); - rx_snrX /= 2; - - /* Translate DBM to percentage. */ - RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]); - if (priv->brfpath_rxenable[i]) - total_rssi += RSSI; - - /* Record Signal Strength for next packet */ - if(bpacket_match_bssid) - { - pstats->RxMIMOSignalStrength[i] =(u8) RSSI; - precord_stats->RxMIMOSignalStrength[i] =(u8) RSSI; - } - } - - - // - // (2)PWDB, Average PWDB cacluated by hardware (for rate adaptive) - // - //Fixed by Jacken from Bryant 2008-03-20 - //Original value is 106 - rx_pwr_all = (((pofdm_buf->pwdb_all ) >> 1 )& 0x7f) -106; - pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all); - - pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all; - pstats->RxPower = precord_stats->RxPower = rx_pwr_all; - pstats->RecvSignalPower = rx_pwr_all; - // - // (3)EVM of HT rate - // - if(pdrvinfo->RxHT && pdrvinfo->RxRate>=DESC90_RATEMCS8 && - pdrvinfo->RxRate<=DESC90_RATEMCS15) - max_spatial_stream = 2; //both spatial stream make sense - else - max_spatial_stream = 1; //only spatial stream 1 makes sense - - for(i=0; i<max_spatial_stream; i++) - { - tmp_rxevm = pofdm_buf->rxevm_X[i]; - rx_evmX = (char)(tmp_rxevm); - - // Do not use shift operation like "rx_evmX >>= 1" because the compilor of free build environment - // fill most significant bit to "zero" when doing shifting operation which may change a negative - // value to positive one, then the dbm value (which is supposed to be negative) is not correct anymore. - rx_evmX /= 2; //dbm - - evm = rtl819x_evm_dbtopercentage(rx_evmX); - if(bpacket_match_bssid) - { - if(i==0) // Fill value in RFD, Get the first spatial stream only - pstats->SignalQuality = precord_stats->SignalQuality = (u8)(evm & 0xff); - pstats->RxMIMOSignalQuality[i] = precord_stats->RxMIMOSignalQuality[i] = (u8)(evm & 0xff); - } - } - - - /* record rx statistics for debug */ - rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg; - prxsc = (phy_ofdm_rx_status_rxsc_sgien_exintfflag *)&rxsc_sgien_exflg; - } - - //UI BSS List signal strength(in percentage), make it good looking, from 0~100. - //It is assigned to the BSS List in GetValueFromBeaconOrProbeRsp(). - if(is_cck_rate) - { - pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)pwdb_all));//PWDB_ALL; - - } - else - { - //pRfd->Status.SignalStrength = pRecordRfd->Status.SignalStrength = (u1Byte)(SignalScaleMapping(total_rssi/=RF90_PATH_MAX));//(u1Byte)(total_rssi/=RF90_PATH_MAX); - // We can judge RX path number now. - if (rf_rx_num != 0) - pstats->SignalStrength = precord_stats->SignalStrength = (u8)(rtl819x_signal_scale_mapping((long)(total_rssi/=rf_rx_num))); - } -} - -static void -rtl8192_record_rxdesc_forlateruse( - struct ieee80211_rx_stats * psrc_stats, - struct ieee80211_rx_stats * ptarget_stats -) -{ - ptarget_stats->bIsAMPDU = psrc_stats->bIsAMPDU; - ptarget_stats->bFirstMPDU = psrc_stats->bFirstMPDU; -} - - - -static void TranslateRxSignalStuff819xpci(struct r8192_priv *priv, - struct sk_buff *skb, - struct ieee80211_rx_stats * pstats, - prx_desc_819x_pci pdesc, - prx_fwinfo_819x_pci pdrvinfo) -{ - // TODO: We must only check packet for current MAC address. Not finish - bool bpacket_match_bssid, bpacket_toself; - bool bPacketBeacon=false, bToSelfBA=false; - struct ieee80211_hdr_3addr *hdr; - u16 fc,type; - - // Get Signal Quality for only RX data queue (but not command queue) - - u8* tmp_buf; - u8 *praddr; - - /* Get MAC frame start address. */ - tmp_buf = skb->data; - - hdr = (struct ieee80211_hdr_3addr *)tmp_buf; - fc = le16_to_cpu(hdr->frame_ctl); - type = WLAN_FC_GET_TYPE(fc); - praddr = hdr->addr1; - - /* Check if the received packet is acceptabe. */ - bpacket_match_bssid = ((IEEE80211_FTYPE_CTL != type) && - (!compare_ether_addr(priv->ieee80211->current_network.bssid, (fc & IEEE80211_FCTL_TODS)? hdr->addr1 : (fc & IEEE80211_FCTL_FROMDS )? hdr->addr2 : hdr->addr3)) - && (!pstats->bHwError) && (!pstats->bCRC)&& (!pstats->bICV)); - bpacket_toself = bpacket_match_bssid & (!compare_ether_addr(praddr, priv->ieee80211->dev->dev_addr)); - - if(WLAN_FC_GET_FRAMETYPE(fc)== IEEE80211_STYPE_BEACON) - { - bPacketBeacon = true; - } - if(WLAN_FC_GET_FRAMETYPE(fc) == IEEE80211_STYPE_BLOCKACK) - { - if (!compare_ether_addr(praddr, priv->ieee80211->dev->dev_addr)) - bToSelfBA = true; - } - - // - // Process PHY information for previous packet (RSSI/PWDB/EVM) - // - // Because phy information is contained in the last packet of AMPDU only, so driver - // should process phy information of previous packet - rtl8192_process_phyinfo(priv, tmp_buf, &priv->previous_stats, pstats); - rtl8192_query_rxphystatus(priv, pstats, pdesc, pdrvinfo, &priv->previous_stats, bpacket_match_bssid, - bpacket_toself ,bPacketBeacon, bToSelfBA); - rtl8192_record_rxdesc_forlateruse(pstats, &priv->previous_stats); - -} - - -static void rtl8192_tx_resume(struct r8192_priv *priv) -{ - struct ieee80211_device *ieee = priv->ieee80211; - struct sk_buff *skb; - int i; - - for (i = BK_QUEUE; i < TXCMD_QUEUE; i++) { - while ((!skb_queue_empty(&ieee->skb_waitQ[i])) && - (priv->ieee80211->check_nic_enough_desc(ieee, i) > 0)) { - /* 1. dequeue the packet from the wait queue */ - skb = skb_dequeue(&ieee->skb_waitQ[i]); - /* 2. tx the packet directly */ - ieee->softmac_data_hard_start_xmit(skb, ieee, 0); - } - } -} - -static void rtl8192_irq_tx_tasklet(unsigned long arg) -{ - struct r8192_priv *priv = (struct r8192_priv*) arg; - struct rtl8192_tx_ring *mgnt_ring = &priv->tx_ring[MGNT_QUEUE]; - unsigned long flags; - - /* check if we need to report that the management queue is drained */ - spin_lock_irqsave(&priv->irq_th_lock, flags); - - if (!skb_queue_len(&mgnt_ring->queue) && - priv->ieee80211->ack_tx_to_ieee && - rtl8192_is_tx_queue_empty(priv->ieee80211)) { - priv->ieee80211->ack_tx_to_ieee = 0; - ieee80211_ps_tx_ack(priv->ieee80211, 1); - } - - spin_unlock_irqrestore(&priv->irq_th_lock, flags); - - rtl8192_tx_resume(priv); -} - -/* Record the received data rate */ -static void UpdateReceivedRateHistogramStatistics8190( - struct r8192_priv *priv, - struct ieee80211_rx_stats* pstats - ) -{ - u32 rcvType=1; //0: Total, 1:OK, 2:CRC, 3:ICV - u32 rateIndex; - u32 preamble_guardinterval; //1: short preamble/GI, 0: long preamble/GI - - if(pstats->bCRC) - rcvType = 2; - else if(pstats->bICV) - rcvType = 3; - - if(pstats->bShortPreamble) - preamble_guardinterval = 1;// short - else - preamble_guardinterval = 0;// long - - switch(pstats->rate) - { - // - // CCK rate - // - case MGN_1M: rateIndex = 0; break; - case MGN_2M: rateIndex = 1; break; - case MGN_5_5M: rateIndex = 2; break; - case MGN_11M: rateIndex = 3; break; - // - // Legacy OFDM rate - // - case MGN_6M: rateIndex = 4; break; - case MGN_9M: rateIndex = 5; break; - case MGN_12M: rateIndex = 6; break; - case MGN_18M: rateIndex = 7; break; - case MGN_24M: rateIndex = 8; break; - case MGN_36M: rateIndex = 9; break; - case MGN_48M: rateIndex = 10; break; - case MGN_54M: rateIndex = 11; break; - // - // 11n High throughput rate - // - case MGN_MCS0: rateIndex = 12; break; - case MGN_MCS1: rateIndex = 13; break; - case MGN_MCS2: rateIndex = 14; break; - case MGN_MCS3: rateIndex = 15; break; - case MGN_MCS4: rateIndex = 16; break; - case MGN_MCS5: rateIndex = 17; break; - case MGN_MCS6: rateIndex = 18; break; - case MGN_MCS7: rateIndex = 19; break; - case MGN_MCS8: rateIndex = 20; break; - case MGN_MCS9: rateIndex = 21; break; - case MGN_MCS10: rateIndex = 22; break; - case MGN_MCS11: rateIndex = 23; break; - case MGN_MCS12: rateIndex = 24; break; - case MGN_MCS13: rateIndex = 25; break; - case MGN_MCS14: rateIndex = 26; break; - case MGN_MCS15: rateIndex = 27; break; - default: rateIndex = 28; break; - } - priv->stats.received_rate_histogram[0][rateIndex]++; //total - priv->stats.received_rate_histogram[rcvType][rateIndex]++; -} - -static void rtl8192_rx(struct r8192_priv *priv) -{ - struct ieee80211_hdr_1addr *ieee80211_hdr = NULL; - bool unicast_packet = false; - struct ieee80211_rx_stats stats = { - .signal = 0, - .noise = -98, - .rate = 0, - .freq = IEEE80211_24GHZ_BAND, - }; - unsigned int count = priv->rxringcount; - prx_fwinfo_819x_pci pDrvInfo = NULL; - struct sk_buff *new_skb; - - while (count--) { - rx_desc_819x_pci *pdesc = &priv->rx_ring[priv->rx_idx];//rx descriptor - struct sk_buff *skb = priv->rx_buf[priv->rx_idx];//rx pkt - - if (pdesc->OWN) - /* wait data to be filled by hardware */ - return; - - stats.bICV = pdesc->ICV; - stats.bCRC = pdesc->CRC32; - stats.bHwError = pdesc->CRC32 | pdesc->ICV; - - stats.Length = pdesc->Length; - if(stats.Length < 24) - stats.bHwError |= 1; - - if(stats.bHwError) { - stats.bShift = false; - goto done; - } - pDrvInfo = NULL; - new_skb = dev_alloc_skb(priv->rxbuffersize); - - if (unlikely(!new_skb)) - goto done; - - stats.RxDrvInfoSize = pdesc->RxDrvInfoSize; - stats.RxBufShift = ((pdesc->Shift)&0x03); - stats.Decrypted = !pdesc->SWDec; - - pci_dma_sync_single_for_cpu(priv->pdev, - *((dma_addr_t *)skb->cb), - priv->rxbuffersize, - PCI_DMA_FROMDEVICE); - skb_put(skb, pdesc->Length); - pDrvInfo = (rx_fwinfo_819x_pci *)(skb->data + stats.RxBufShift); - skb_reserve(skb, stats.RxDrvInfoSize + stats.RxBufShift); - - stats.rate = HwRateToMRate90((bool)pDrvInfo->RxHT, (u8)pDrvInfo->RxRate); - stats.bShortPreamble = pDrvInfo->SPLCP; - - /* it is debug only. It should be disabled in released driver. - * 2007.1.11 by Emily - * */ - UpdateReceivedRateHistogramStatistics8190(priv, &stats); - - stats.bIsAMPDU = (pDrvInfo->PartAggr==1); - stats.bFirstMPDU = (pDrvInfo->PartAggr==1) && (pDrvInfo->FirstAGGR==1); - - stats.TimeStampLow = pDrvInfo->TSFL; - stats.TimeStampHigh = read_nic_dword(priv, TSFR+4); - - UpdateRxPktTimeStamp8190(priv, &stats); - - // - // Get Total offset of MPDU Frame Body - // - if((stats.RxBufShift + stats.RxDrvInfoSize) > 0) - stats.bShift = 1; - - /* ???? */ - TranslateRxSignalStuff819xpci(priv, skb, &stats, pdesc, pDrvInfo); - - /* Rx A-MPDU */ - if(pDrvInfo->FirstAGGR==1 || pDrvInfo->PartAggr == 1) - RT_TRACE(COMP_RXDESC, "pDrvInfo->FirstAGGR = %d, pDrvInfo->PartAggr = %d\n", - pDrvInfo->FirstAGGR, pDrvInfo->PartAggr); - skb_trim(skb, skb->len - 4/*sCrcLng*/); - /* rx packets statistics */ - ieee80211_hdr = (struct ieee80211_hdr_1addr *)skb->data; - unicast_packet = false; - - if(is_broadcast_ether_addr(ieee80211_hdr->addr1)) { - //TODO - }else if(is_multicast_ether_addr(ieee80211_hdr->addr1)){ - //TODO - }else { - /* unicast packet */ - unicast_packet = true; - } - - if(!ieee80211_rtl_rx(priv->ieee80211, skb, &stats)){ - dev_kfree_skb_any(skb); - } else { - priv->stats.rxok++; - if(unicast_packet) { - priv->stats.rxbytesunicast += skb->len; - } - } - - pci_unmap_single(priv->pdev, *((dma_addr_t *) skb->cb), - priv->rxbuffersize, PCI_DMA_FROMDEVICE); - - skb = new_skb; - priv->rx_buf[priv->rx_idx] = skb; - *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, skb_tail_pointer(skb), priv->rxbuffersize, PCI_DMA_FROMDEVICE); - -done: - pdesc->BufferAddress = cpu_to_le32(*((dma_addr_t *)skb->cb)); - pdesc->OWN = 1; - pdesc->Length = priv->rxbuffersize; - if (priv->rx_idx == priv->rxringcount-1) - pdesc->EOR = 1; - priv->rx_idx = (priv->rx_idx + 1) % priv->rxringcount; - } - -} - -static void rtl8192_irq_rx_tasklet(unsigned long arg) -{ - struct r8192_priv *priv = (struct r8192_priv*) arg; - rtl8192_rx(priv); - /* unmask RDU */ - write_nic_dword(priv, INTA_MASK, read_nic_dword(priv, INTA_MASK) | IMR_RDU); -} - -static const struct net_device_ops rtl8192_netdev_ops = { - .ndo_open = rtl8192_open, - .ndo_stop = rtl8192_close, - .ndo_tx_timeout = tx_timeout, - .ndo_do_ioctl = rtl8192_ioctl, - .ndo_set_multicast_list = r8192_set_multicast, - .ndo_set_mac_address = r8192_set_mac_adr, - .ndo_start_xmit = ieee80211_rtl_xmit, -}; - -static int __devinit rtl8192_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *id) -{ - struct net_device *dev = NULL; - struct r8192_priv *priv= NULL; - u8 unit = 0; - int ret = -ENODEV; - unsigned long pmem_start, pmem_len, pmem_flags; - u8 revisionid; - - RT_TRACE(COMP_INIT,"Configuring chip resources\n"); - - if( pci_enable_device (pdev) ){ - RT_TRACE(COMP_ERR,"Failed to enable PCI device"); - return -EIO; - } - - pci_set_master(pdev); - //pci_set_wmi(pdev); - pci_set_dma_mask(pdev, 0xffffff00ULL); - pci_set_consistent_dma_mask(pdev,0xffffff00ULL); - dev = alloc_ieee80211(sizeof(struct r8192_priv)); - if (!dev) { - ret = -ENOMEM; - goto fail_free; - } - - pci_set_drvdata(pdev, dev); - SET_NETDEV_DEV(dev, &pdev->dev); - priv = ieee80211_priv(dev); - priv->ieee80211 = netdev_priv(dev); - priv->pdev=pdev; - if((pdev->subsystem_vendor == PCI_VENDOR_ID_DLINK)&&(pdev->subsystem_device == 0x3304)){ - priv->ieee80211->bSupportRemoteWakeUp = 1; - } else - { - priv->ieee80211->bSupportRemoteWakeUp = 0; - } - - pmem_start = pci_resource_start(pdev, 1); - pmem_len = pci_resource_len(pdev, 1); - pmem_flags = pci_resource_flags (pdev, 1); - - if (!(pmem_flags & IORESOURCE_MEM)) { - RT_TRACE(COMP_ERR, "region #1 not a MMIO resource, aborting\n"); - goto fail; - } - - //DMESG("Memory mapped space @ 0x%08lx ", pmem_start); - if( ! request_mem_region(pmem_start, pmem_len, RTL819xE_MODULE_NAME)) { - RT_TRACE(COMP_ERR,"request_mem_region failed!\n"); - goto fail; - } - - priv->mem_start = ioremap_nocache(pmem_start, pmem_len); - if (!priv->mem_start) { - RT_TRACE(COMP_ERR,"ioremap failed!\n"); - goto fail1; - } - - dev->mem_start = (unsigned long) priv->mem_start; - dev->mem_end = (unsigned long) (priv->mem_start + - pci_resource_len(pdev, 0)); - - /* We disable the RETRY_TIMEOUT register (0x41) to keep - * PCI Tx retries from interfering with C3 CPU state */ - pci_write_config_byte(pdev, 0x41, 0x00); - - - pci_read_config_byte(pdev, 0x08, &revisionid); - /* If the revisionid is 0x10, the device uses rtl8192se. */ - if (pdev->device == 0x8192 && revisionid == 0x10) - goto fail1; - - pci_read_config_byte(pdev, 0x05, &unit); - pci_write_config_byte(pdev, 0x05, unit & (~0x04)); - - dev->irq = pdev->irq; - priv->irq = 0; - - dev->netdev_ops = &rtl8192_netdev_ops; - - dev->wireless_handlers = &r8192_wx_handlers_def; - dev->type=ARPHRD_ETHER; - - dev->watchdog_timeo = HZ*3; - - if (dev_alloc_name(dev, ifname) < 0){ - RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying wlan%%d...\n"); - strcpy(ifname, "wlan%d"); - dev_alloc_name(dev, ifname); - } - - RT_TRACE(COMP_INIT, "Driver probe completed1\n"); - if (rtl8192_init(priv)!=0) { - RT_TRACE(COMP_ERR, "Initialization failed\n"); - goto fail; - } - - register_netdev(dev); - RT_TRACE(COMP_INIT, "dev name=======> %s\n",dev->name); - rtl8192_proc_init_one(priv); - - - RT_TRACE(COMP_INIT, "Driver probe completed\n"); - return 0; - -fail1: - - if (priv->mem_start) { - iounmap(priv->mem_start); - release_mem_region( pci_resource_start(pdev, 1), - pci_resource_len(pdev, 1) ); - } - -fail: - if(dev){ - - if (priv->irq) { - free_irq(priv->irq, priv); - priv->irq = 0; - } - free_ieee80211(dev); - } - -fail_free: - pci_disable_device(pdev); - - DMESG("wlan driver load failed\n"); - pci_set_drvdata(pdev, NULL); - return ret; - -} - -/* detach all the work and timer structure declared or inititialized - * in r8192_init function. - * */ -static void rtl8192_cancel_deferred_work(struct r8192_priv* priv) -{ - /* call cancel_work_sync instead of cancel_delayed_work if and only if Linux_version_code - * is or is newer than 2.6.20 and work structure is defined to be struct work_struct. - * Otherwise call cancel_delayed_work is enough. - * FIXME (2.6.20 should 2.6.22, work_struct should not cancel) - * */ - cancel_delayed_work(&priv->watch_dog_wq); - cancel_delayed_work(&priv->update_beacon_wq); - cancel_delayed_work(&priv->ieee80211->hw_wakeup_wq); - cancel_delayed_work(&priv->gpio_change_rf_wq); - cancel_work_sync(&priv->reset_wq); - cancel_work_sync(&priv->qos_activate); -} - - -static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev) -{ - struct net_device *dev = pci_get_drvdata(pdev); - struct r8192_priv *priv ; - u32 i; - - if (dev) { - - unregister_netdev(dev); - - priv = ieee80211_priv(dev); - - rtl8192_proc_remove_one(priv); - - rtl8192_down(dev); - if (priv->pFirmware) - { - vfree(priv->pFirmware); - priv->pFirmware = NULL; - } - destroy_workqueue(priv->priv_wq); - - /* free tx/rx rings */ - rtl8192_free_rx_ring(priv); - for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) - rtl8192_free_tx_ring(priv, i); - - if (priv->irq) { - printk("Freeing irq %d\n", priv->irq); - free_irq(priv->irq, priv); - priv->irq = 0; - } - - if (priv->mem_start) { - iounmap(priv->mem_start); - release_mem_region( pci_resource_start(pdev, 1), - pci_resource_len(pdev, 1) ); - } - - free_ieee80211(dev); - } - - pci_disable_device(pdev); - RT_TRACE(COMP_DOWN, "wlan driver removed\n"); -} - -extern int ieee80211_rtl_init(void); -extern void ieee80211_rtl_exit(void); - -static int __init rtl8192_pci_module_init(void) -{ - int retval; - - retval = ieee80211_rtl_init(); - if (retval) - return retval; - - printk(KERN_INFO "\nLinux kernel driver for RTL8192 based WLAN cards\n"); - printk(KERN_INFO "Copyright (c) 2007-2008, Realsil Wlan\n"); - RT_TRACE(COMP_INIT, "Initializing module\n"); - rtl8192_proc_module_init(); - if(0!=pci_register_driver(&rtl8192_pci_driver)) - { - DMESG("No device found"); - /*pci_unregister_driver (&rtl8192_pci_driver);*/ - return -ENODEV; - } - return 0; -} - - -static void __exit rtl8192_pci_module_exit(void) -{ - pci_unregister_driver(&rtl8192_pci_driver); - - RT_TRACE(COMP_DOWN, "Exiting\n"); - rtl8192_proc_module_remove(); - ieee80211_rtl_exit(); -} - -static irqreturn_t rtl8192_interrupt(int irq, void *param) -{ - struct r8192_priv *priv = param; - struct net_device *dev = priv->ieee80211->dev; - unsigned long flags; - u32 inta; - irqreturn_t ret = IRQ_HANDLED; - - spin_lock_irqsave(&priv->irq_th_lock, flags); - - /* ISR: 4bytes */ - - inta = read_nic_dword(priv, ISR); /* & priv->IntrMask; */ - write_nic_dword(priv, ISR, inta); /* reset int situation */ - - if (!inta) { - /* - * most probably we can safely return IRQ_NONE, - * but for now is better to avoid problems - */ - goto out_unlock; - } - - if (inta == 0xffff) { - /* HW disappared */ - goto out_unlock; - } - - if (!netif_running(dev)) - goto out_unlock; - - if (inta & IMR_TBDOK) { - RT_TRACE(COMP_INTR, "beacon ok interrupt!\n"); - rtl8192_tx_isr(priv, BEACON_QUEUE); - priv->stats.txbeaconokint++; - } - - if (inta & IMR_TBDER) { - RT_TRACE(COMP_INTR, "beacon ok interrupt!\n"); - rtl8192_tx_isr(priv, BEACON_QUEUE); - priv->stats.txbeaconerr++; - } - - if (inta & IMR_MGNTDOK ) { - RT_TRACE(COMP_INTR, "Manage ok interrupt!\n"); - priv->stats.txmanageokint++; - rtl8192_tx_isr(priv, MGNT_QUEUE); - } - - if (inta & IMR_COMDOK) - { - priv->stats.txcmdpktokint++; - rtl8192_tx_isr(priv, TXCMD_QUEUE); - } - - if (inta & IMR_ROK) { - priv->stats.rxint++; - tasklet_schedule(&priv->irq_rx_tasklet); - } - - if (inta & IMR_BcnInt) { - RT_TRACE(COMP_INTR, "prepare beacon for interrupt!\n"); - tasklet_schedule(&priv->irq_prepare_beacon_tasklet); - } - - if (inta & IMR_RDU) { - RT_TRACE(COMP_INTR, "rx descriptor unavailable!\n"); - priv->stats.rxrdu++; - /* reset int situation */ - write_nic_dword(priv, INTA_MASK, read_nic_dword(priv, INTA_MASK) & ~IMR_RDU); - tasklet_schedule(&priv->irq_rx_tasklet); - } - - if (inta & IMR_RXFOVW) { - RT_TRACE(COMP_INTR, "rx overflow !\n"); - priv->stats.rxoverflow++; - tasklet_schedule(&priv->irq_rx_tasklet); - } - - if (inta & IMR_TXFOVW) - priv->stats.txoverflow++; - - if (inta & IMR_BKDOK) { - RT_TRACE(COMP_INTR, "BK Tx OK interrupt!\n"); - priv->stats.txbkokint++; - priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++; - rtl8192_tx_isr(priv, BK_QUEUE); - } - - if (inta & IMR_BEDOK) { - RT_TRACE(COMP_INTR, "BE TX OK interrupt!\n"); - priv->stats.txbeokint++; - priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++; - rtl8192_tx_isr(priv, BE_QUEUE); - } - - if (inta & IMR_VIDOK) { - RT_TRACE(COMP_INTR, "VI TX OK interrupt!\n"); - priv->stats.txviokint++; - priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++; - rtl8192_tx_isr(priv, VI_QUEUE); - } - - if (inta & IMR_VODOK) { - priv->stats.txvookint++; - priv->ieee80211->LinkDetectInfo.NumTxOkInPeriod++; - rtl8192_tx_isr(priv, VO_QUEUE); - } - -out_unlock: - spin_unlock_irqrestore(&priv->irq_th_lock, flags); - - return ret; -} - -void EnableHWSecurityConfig8192(struct r8192_priv *priv) -{ - u8 SECR_value = 0x0; - struct ieee80211_device* ieee = priv->ieee80211; - - SECR_value = SCR_TxEncEnable | SCR_RxDecEnable; - - if (((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) && (priv->ieee80211->auth_mode != 2)) - { - SECR_value |= SCR_RxUseDK; - SECR_value |= SCR_TxUseDK; - } - else if ((ieee->iw_mode == IW_MODE_ADHOC) && (ieee->pairwise_key_type & (KEY_TYPE_CCMP | KEY_TYPE_TKIP))) - { - SECR_value |= SCR_RxUseDK; - SECR_value |= SCR_TxUseDK; - } - - //add HWSec active enable here. -//default using hwsec. when peer AP is in N mode only and pairwise_key_type is none_aes(which HT_IOT_ACT_PURE_N_MODE indicates it), use software security. when peer AP is in b,g,n mode mixed and pairwise_key_type is none_aes, use g mode hw security. WB on 2008.7.4 - ieee->hwsec_active = 1; - - if ((ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE) || !hwwep)//!ieee->hwsec_support) //add hwsec_support flag to totol control hw_sec on/off - { - ieee->hwsec_active = 0; - SECR_value &= ~SCR_RxDecEnable; - } - - RT_TRACE(COMP_SEC,"%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", __FUNCTION__, - ieee->hwsec_active, ieee->pairwise_key_type, SECR_value); - { - write_nic_byte(priv, SECR, SECR_value);//SECR_value | SCR_UseDK ); - } - -} -#define TOTAL_CAM_ENTRY 32 -//#define CAM_CONTENT_COUNT 8 -void setKey(struct r8192_priv *priv, u8 EntryNo, u8 KeyIndex, u16 KeyType, - const u8 *MacAddr, u8 DefaultKey, u32 *KeyContent) -{ - u32 TargetCommand = 0; - u32 TargetContent = 0; - u16 usConfig = 0; - u8 i; -#ifdef ENABLE_IPS - RT_RF_POWER_STATE rtState; - - rtState = priv->eRFPowerState; - if (priv->PowerSaveControl.bInactivePs){ - if(rtState == eRfOff){ - if(priv->RfOffReason > RF_CHANGE_BY_IPS) - { - RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__); - //up(&priv->wx_sem); - return ; - } - else{ - down(&priv->ieee80211->ips_sem); - IPSLeave(priv); - up(&priv->ieee80211->ips_sem); - } - } - } - priv->ieee80211->is_set_key = true; -#endif - if (EntryNo >= TOTAL_CAM_ENTRY) - RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n"); - - RT_TRACE(COMP_SEC, "====>to setKey(), priv:%p, EntryNo:%d, KeyIndex:%d, KeyType:%d, MacAddr%pM\n", priv, EntryNo, KeyIndex, KeyType, MacAddr); - - if (DefaultKey) - usConfig |= BIT15 | (KeyType<<2); - else - usConfig |= BIT15 | (KeyType<<2) | KeyIndex; -// usConfig |= BIT15 | (KeyType<<2) | (DefaultKey<<5) | KeyIndex; - - - for(i=0 ; i<CAM_CONTENT_COUNT; i++){ - TargetCommand = i+CAM_CONTENT_COUNT*EntryNo; - TargetCommand |= BIT31|BIT16; - - if(i==0){//MAC|Config - TargetContent = (u32)(*(MacAddr+0)) << 16| - (u32)(*(MacAddr+1)) << 24| - (u32)usConfig; - - write_nic_dword(priv, WCAMI, TargetContent); - write_nic_dword(priv, RWCAM, TargetCommand); - } - else if(i==1){//MAC - TargetContent = (u32)(*(MacAddr+2)) | - (u32)(*(MacAddr+3)) << 8| - (u32)(*(MacAddr+4)) << 16| - (u32)(*(MacAddr+5)) << 24; - write_nic_dword(priv, WCAMI, TargetContent); - write_nic_dword(priv, RWCAM, TargetCommand); - } - else { //Key Material - if(KeyContent != NULL) - { - write_nic_dword(priv, WCAMI, (u32)(*(KeyContent+i-2)) ); - write_nic_dword(priv, RWCAM, TargetCommand); - } - } - } - RT_TRACE(COMP_SEC,"=========>after set key, usconfig:%x\n", usConfig); -} - -bool NicIFEnableNIC(struct r8192_priv *priv) -{ - RT_STATUS init_status = RT_STATUS_SUCCESS; - PRT_POWER_SAVE_CONTROL pPSC = &priv->PowerSaveControl; - - //YJ,add,091109 - if (priv->up == 0){ - RT_TRACE(COMP_ERR, "ERR!!! %s(): Driver is already down!\n",__FUNCTION__); - priv->bdisable_nic = false; //YJ,add,091111 - return false; - } - // <1> Reset memory: descriptor, buffer,.. - //NicIFResetMemory(Adapter); - - // <2> Enable Adapter - //priv->bfirst_init = true; - init_status = rtl8192_adapter_start(priv); - if (init_status != RT_STATUS_SUCCESS) { - RT_TRACE(COMP_ERR,"ERR!!! %s(): initialization is failed!\n",__FUNCTION__); - priv->bdisable_nic = false; //YJ,add,091111 - return -1; - } - RT_CLEAR_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC); - //priv->bfirst_init = false; - - // <3> Enable Interrupt - rtl8192_irq_enable(priv); - priv->bdisable_nic = false; - - return (init_status == RT_STATUS_SUCCESS); -} - -bool NicIFDisableNIC(struct r8192_priv *priv) -{ - bool status = true; - u8 tmp_state = 0; - // <1> Disable Interrupt - - priv->bdisable_nic = true; //YJ,move,091109 - tmp_state = priv->ieee80211->state; - - ieee80211_softmac_stop_protocol(priv->ieee80211, false); - - priv->ieee80211->state = tmp_state; - rtl8192_cancel_deferred_work(priv); - rtl8192_irq_disable(priv); - // <2> Stop all timer - - // <3> Disable Adapter - rtl8192_halt_adapter(priv, false); -// priv->bdisable_nic = true; - - return status; -} - -module_init(rtl8192_pci_module_init); -module_exit(rtl8192_pci_module_exit); diff --git a/drivers/staging/rtl8192e/r8192E_dev.c b/drivers/staging/rtl8192e/r8192E_dev.c new file mode 100644 index 0000000..899e4e5 --- /dev/null +++ b/drivers/staging/rtl8192e/r8192E_dev.c @@ -0,0 +1,2413 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * Based on the r8180 driver, which is: + * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al. + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> +******************************************************************************/ +#include "rtl_core.h" +#include "r8192E_phy.h" +#include "r8192E_phyreg.h" +#include "r8190P_rtl8256.h" +#include "r8192E_cmdpkt.h" +#include "rtl_dm.h" +#include "rtl_wx.h" + +extern int WDCAPARA_ADD[]; + +void rtl8192e_start_beacon(struct net_device *dev) +{ + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + struct rtllib_network *net = &priv->rtllib->current_network; + u16 BcnTimeCfg = 0; + u16 BcnCW = 6; + u16 BcnIFS = 0xf; + + DMESG("Enabling beacon TX"); + rtl8192_irq_disable(dev); + + write_nic_word(dev, ATIMWND, 2); + + write_nic_word(dev, BCN_INTERVAL, net->beacon_interval); + write_nic_word(dev, BCN_DRV_EARLY_INT, 10); + write_nic_word(dev, BCN_DMATIME, 256); + + write_nic_byte(dev, BCN_ERR_THRESH, 100); + + BcnTimeCfg |= BcnCW<<BCN_TCFG_CW_SHIFT; + BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS; + write_nic_word(dev, BCN_TCFG, BcnTimeCfg); + rtl8192_irq_enable(dev); +} + +static void rtl8192e_update_msr(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + u8 msr; + enum led_ctl_mode LedAction = LED_CTL_NO_LINK; + msr = read_nic_byte(dev, MSR); + msr &= ~MSR_LINK_MASK; + + switch (priv->rtllib->iw_mode) { + case IW_MODE_INFRA: + if (priv->rtllib->state == RTLLIB_LINKED) + msr |= (MSR_LINK_MANAGED << MSR_LINK_SHIFT); + else + msr |= (MSR_LINK_NONE << MSR_LINK_SHIFT); + LedAction = LED_CTL_LINK; + break; + case IW_MODE_ADHOC: + if (priv->rtllib->state == RTLLIB_LINKED) + msr |= (MSR_LINK_ADHOC << MSR_LINK_SHIFT); + else + msr |= (MSR_LINK_NONE << MSR_LINK_SHIFT); + break; + case IW_MODE_MASTER: + if (priv->rtllib->state == RTLLIB_LINKED) + msr |= (MSR_LINK_MASTER << MSR_LINK_SHIFT); + else + msr |= (MSR_LINK_NONE << MSR_LINK_SHIFT); + break; + default: + break; + } + + write_nic_byte(dev, MSR, msr); + if (priv->rtllib->LedControlHandler) + priv->rtllib->LedControlHandler(dev, LedAction); +} + +void rtl8192e_SetHwReg(struct net_device *dev, u8 variable, u8 *val) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + switch (variable) { + case HW_VAR_BSSID: + write_nic_dword(dev, BSSIDR, ((u32 *)(val))[0]); + write_nic_word(dev, BSSIDR+2, ((u16 *)(val+2))[0]); + break; + + case HW_VAR_MEDIA_STATUS: + { + enum rt_op_mode OpMode = *((enum rt_op_mode *)(val)); + enum led_ctl_mode LedAction = LED_CTL_NO_LINK; + u8 btMsr = read_nic_byte(dev, MSR); + + btMsr &= 0xfc; + + switch (OpMode) { + case RT_OP_MODE_INFRASTRUCTURE: + btMsr |= MSR_INFRA; + LedAction = LED_CTL_LINK; + break; + + case RT_OP_MODE_IBSS: + btMsr |= MSR_ADHOC; + break; + + case RT_OP_MODE_AP: + btMsr |= MSR_AP; + LedAction = LED_CTL_LINK; + break; + + default: + btMsr |= MSR_NOLINK; + break; + } + + write_nic_byte(dev, MSR, btMsr); + + } + break; + + case HW_VAR_CECHK_BSSID: + { + u32 RegRCR, Type; + + Type = ((u8 *)(val))[0]; + RegRCR = read_nic_dword(dev, RCR); + priv->ReceiveConfig = RegRCR; + + if (Type == true) + RegRCR |= (RCR_CBSSID); + else if (Type == false) + RegRCR &= (~RCR_CBSSID); + + write_nic_dword(dev, RCR, RegRCR); + priv->ReceiveConfig = RegRCR; + + } + break; + + case HW_VAR_SLOT_TIME: + + priv->slot_time = val[0]; + write_nic_byte(dev, SLOT_TIME, val[0]); + + break; + + case HW_VAR_ACK_PREAMBLE: + { + u32 regTmp; + priv->short_preamble = (bool)(*(u8 *)val); + regTmp = priv->basic_rate; + if (priv->short_preamble) + regTmp |= BRSR_AckShortPmb; + write_nic_dword(dev, RRSR, regTmp); + break; + } + + case HW_VAR_CPU_RST: + write_nic_dword(dev, CPU_GEN, ((u32 *)(val))[0]); + break; + + case HW_VAR_AC_PARAM: + { + u8 pAcParam = *((u8 *)val); + u32 eACI = pAcParam; + u8 u1bAIFS; + u32 u4bAcParam; + u8 mode = priv->rtllib->mode; + struct rtllib_qos_parameters *qos_parameters = + &priv->rtllib->current_network.qos_data.parameters; + + u1bAIFS = qos_parameters->aifs[pAcParam] * + ((mode&(IEEE_G|IEEE_N_24G)) ? 9 : 20) + aSifsTime; + + dm_init_edca_turbo(dev); + + u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[pAcParam])) << + AC_PARAM_TXOP_LIMIT_OFFSET) | + (((u32)(qos_parameters->cw_max[pAcParam])) << + AC_PARAM_ECW_MAX_OFFSET) | + (((u32)(qos_parameters->cw_min[pAcParam])) << + AC_PARAM_ECW_MIN_OFFSET) | + (((u32)u1bAIFS) << AC_PARAM_AIFS_OFFSET)); + + RT_TRACE(COMP_DBG, "%s():HW_VAR_AC_PARAM eACI:%x:%x\n", + __func__, eACI, u4bAcParam); + switch (eACI) { + case AC1_BK: + write_nic_dword(dev, EDCAPARA_BK, u4bAcParam); + break; + + case AC0_BE: + write_nic_dword(dev, EDCAPARA_BE, u4bAcParam); + break; + + case AC2_VI: + write_nic_dword(dev, EDCAPARA_VI, u4bAcParam); + break; + + case AC3_VO: + write_nic_dword(dev, EDCAPARA_VO, u4bAcParam); + break; + + default: + printk(KERN_INFO "SetHwReg8185(): invalid ACI: %d !\n", + eACI); + break; + } + priv->rtllib->SetHwRegHandler(dev, HW_VAR_ACM_CTRL, + (u8 *)(&pAcParam)); + break; + } + + case HW_VAR_ACM_CTRL: + { + struct rtllib_qos_parameters *qos_parameters = + &priv->rtllib->current_network.qos_data.parameters; + u8 pAcParam = *((u8 *)val); + u32 eACI = pAcParam; + union aci_aifsn *pAciAifsn = (union aci_aifsn *) & + (qos_parameters->aifs[0]); + u8 acm = pAciAifsn->f.acm; + u8 AcmCtrl = read_nic_byte(dev, AcmHwCtrl); + + RT_TRACE(COMP_DBG, "===========>%s():HW_VAR_ACM_CTRL:%x\n", + __func__, eACI); + AcmCtrl = AcmCtrl | ((priv->AcmMethod == 2) ? 0x0 : 0x1); + + if (acm) { + switch (eACI) { + case AC0_BE: + AcmCtrl |= AcmHw_BeqEn; + break; + + case AC2_VI: + AcmCtrl |= AcmHw_ViqEn; + break; + + case AC3_VO: + AcmCtrl |= AcmHw_VoqEn; + break; + + default: + RT_TRACE(COMP_QOS, "SetHwReg8185(): [HW_VAR_" + "ACM_CTRL] acm set failed: eACI is " + "%d\n", eACI); + break; + } + } else { + switch (eACI) { + case AC0_BE: + AcmCtrl &= (~AcmHw_BeqEn); + break; + + case AC2_VI: + AcmCtrl &= (~AcmHw_ViqEn); + break; + + case AC3_VO: + AcmCtrl &= (~AcmHw_BeqEn); + break; + + default: + break; + } + } + + RT_TRACE(COMP_QOS, "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write" + " 0x%X\n", AcmCtrl); + write_nic_byte(dev, AcmHwCtrl, AcmCtrl); + break; + } + + case HW_VAR_SIFS: + write_nic_byte(dev, SIFS, val[0]); + write_nic_byte(dev, SIFS+1, val[0]); + break; + + case HW_VAR_RF_TIMING: + { + u8 Rf_Timing = *((u8 *)val); + write_nic_byte(dev, rFPGA0_RFTiming1, Rf_Timing); + break; + } + + default: + break; + } + +} + +static void rtl8192_read_eeprom_info(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + u8 tempval; + u8 ICVer8192, ICVer8256; + u16 i, usValue, IC_Version; + u16 EEPROMId; + u8 bMac_Tmp_Addr[6] = {0x00, 0xe0, 0x4c, 0x00, 0x00, 0x01}; + RT_TRACE(COMP_INIT, "====> rtl8192_read_eeprom_info\n"); + + EEPROMId = eprom_read(dev, 0); + if (EEPROMId != RTL8190_EEPROM_ID) { + RT_TRACE(COMP_ERR, "EEPROM ID is invalid:%x, %x\n", + EEPROMId, RTL8190_EEPROM_ID); + priv->AutoloadFailFlag = true; + } else { + priv->AutoloadFailFlag = false; + } + + if (!priv->AutoloadFailFlag) { + priv->eeprom_vid = eprom_read(dev, (EEPROM_VID >> 1)); + priv->eeprom_did = eprom_read(dev, (EEPROM_DID >> 1)); + + usValue = eprom_read(dev, (u16)(EEPROM_Customer_ID>>1)) >> 8; + priv->eeprom_CustomerID = (u8)(usValue & 0xff); + usValue = eprom_read(dev, (EEPROM_ICVersion_ChannelPlan>>1)); + priv->eeprom_ChannelPlan = usValue&0xff; + IC_Version = ((usValue&0xff00)>>8); + + ICVer8192 = (IC_Version&0xf); + ICVer8256 = ((IC_Version&0xf0)>>4); + RT_TRACE(COMP_INIT, "\nICVer8192 = 0x%x\n", ICVer8192); + RT_TRACE(COMP_INIT, "\nICVer8256 = 0x%x\n", ICVer8256); + if (ICVer8192 == 0x2) { + if (ICVer8256 == 0x5) + priv->card_8192_version = VERSION_8190_BE; + } + switch (priv->card_8192_version) { + case VERSION_8190_BD: + case VERSION_8190_BE: + break; + default: + priv->card_8192_version = VERSION_8190_BD; + break; + } + RT_TRACE(COMP_INIT, "\nIC Version = 0x%x\n", + priv->card_8192_version); + } else { + priv->card_8192_version = VERSION_8190_BD; + priv->eeprom_vid = 0; + priv->eeprom_did = 0; + priv->eeprom_CustomerID = 0; + priv->eeprom_ChannelPlan = 0; + RT_TRACE(COMP_INIT, "\nIC Version = 0x%x\n", 0xff); + } + + RT_TRACE(COMP_INIT, "EEPROM VID = 0x%4x\n", priv->eeprom_vid); + RT_TRACE(COMP_INIT, "EEPROM DID = 0x%4x\n", priv->eeprom_did); + RT_TRACE(COMP_INIT, "EEPROM Customer ID: 0x%2x\n", + priv->eeprom_CustomerID); + + if (!priv->AutoloadFailFlag) { + for (i = 0; i < 6; i += 2) { + usValue = eprom_read(dev, + (u16)((EEPROM_NODE_ADDRESS_BYTE_0 + i) >> 1)); + *(u16 *)(&dev->dev_addr[i]) = usValue; + } + } else { + memcpy(dev->dev_addr, bMac_Tmp_Addr, 6); + } + + RT_TRACE(COMP_INIT, "Permanent Address = %pM\n", + dev->dev_addr); + + if (priv->card_8192_version > VERSION_8190_BD) + priv->bTXPowerDataReadFromEEPORM = true; + else + priv->bTXPowerDataReadFromEEPORM = false; + + priv->rf_type = RTL819X_DEFAULT_RF_TYPE; + + if (priv->card_8192_version > VERSION_8190_BD) { + if (!priv->AutoloadFailFlag) { + tempval = (eprom_read(dev, (EEPROM_RFInd_PowerDiff >> + 1))) & 0xff; + priv->EEPROMLegacyHTTxPowerDiff = tempval & 0xf; + + if (tempval&0x80) + priv->rf_type = RF_1T2R; + else + priv->rf_type = RF_2T4R; + } else { + priv->EEPROMLegacyHTTxPowerDiff = 0x04; + } + RT_TRACE(COMP_INIT, "EEPROMLegacyHTTxPowerDiff = %d\n", + priv->EEPROMLegacyHTTxPowerDiff); + + if (!priv->AutoloadFailFlag) + priv->EEPROMThermalMeter = (u8)(((eprom_read(dev, + (EEPROM_ThermalMeter>>1))) & + 0xff00)>>8); + else + priv->EEPROMThermalMeter = EEPROM_Default_ThermalMeter; + RT_TRACE(COMP_INIT, "ThermalMeter = %d\n", + priv->EEPROMThermalMeter); + priv->TSSI_13dBm = priv->EEPROMThermalMeter * 100; + + if (priv->epromtype == EEPROM_93C46) { + if (!priv->AutoloadFailFlag) { + usValue = eprom_read(dev, + (EEPROM_TxPwDiff_CrystalCap >> 1)); + priv->EEPROMAntPwDiff = (usValue&0x0fff); + priv->EEPROMCrystalCap = (u8)((usValue & 0xf000) + >> 12); + } else { + priv->EEPROMAntPwDiff = + EEPROM_Default_AntTxPowerDiff; + priv->EEPROMCrystalCap = + EEPROM_Default_TxPwDiff_CrystalCap; + } + RT_TRACE(COMP_INIT, "EEPROMAntPwDiff = %d\n", + priv->EEPROMAntPwDiff); + RT_TRACE(COMP_INIT, "EEPROMCrystalCap = %d\n", + priv->EEPROMCrystalCap); + + for (i = 0; i < 14; i += 2) { + if (!priv->AutoloadFailFlag) + usValue = eprom_read(dev, + (u16)((EEPROM_TxPwIndex_CCK + + i) >> 1)); + else + usValue = EEPROM_Default_TxPower; + *((u16 *)(&priv->EEPROMTxPowerLevelCCK[i])) = + usValue; + RT_TRACE(COMP_INIT, "CCK Tx Power Level, Index" + " %d = 0x%02x\n", i, + priv->EEPROMTxPowerLevelCCK[i]); + RT_TRACE(COMP_INIT, "CCK Tx Power Level, Index" + " %d = 0x%02x\n", i+1, + priv->EEPROMTxPowerLevelCCK[i+1]); + } + for (i = 0; i < 14; i += 2) { + if (!priv->AutoloadFailFlag) + usValue = eprom_read(dev, + (u16)((EEPROM_TxPwIndex_OFDM_24G + + i) >> 1)); + else + usValue = EEPROM_Default_TxPower; + *((u16 *)(&priv->EEPROMTxPowerLevelOFDM24G[i])) + = usValue; + RT_TRACE(COMP_INIT, "OFDM 2.4G Tx Power Level," + " Index %d = 0x%02x\n", i, + priv->EEPROMTxPowerLevelOFDM24G[i]); + RT_TRACE(COMP_INIT, "OFDM 2.4G Tx Power Level," + " Index %d = 0x%02x\n", i + 1, + priv->EEPROMTxPowerLevelOFDM24G[i+1]); + } + } + if (priv->epromtype == EEPROM_93C46) { + for (i = 0; i < 14; i++) { + priv->TxPowerLevelCCK[i] = + priv->EEPROMTxPowerLevelCCK[i]; + priv->TxPowerLevelOFDM24G[i] = + priv->EEPROMTxPowerLevelOFDM24G[i]; + } + priv->LegacyHTTxPowerDiff = + priv->EEPROMLegacyHTTxPowerDiff; + priv->AntennaTxPwDiff[0] = (priv->EEPROMAntPwDiff & + 0xf); + priv->AntennaTxPwDiff[1] = ((priv->EEPROMAntPwDiff & + 0xf0)>>4); + priv->AntennaTxPwDiff[2] = ((priv->EEPROMAntPwDiff & + 0xf00)>>8); + priv->CrystalCap = priv->EEPROMCrystalCap; + priv->ThermalMeter[0] = (priv->EEPROMThermalMeter & + 0xf); + priv->ThermalMeter[1] = ((priv->EEPROMThermalMeter & + 0xf0)>>4); + } else if (priv->epromtype == EEPROM_93C56) { + + for (i = 0; i < 3; i++) { + priv->TxPowerLevelCCK_A[i] = + priv->EEPROMRfACCKChnl1TxPwLevel[0]; + priv->TxPowerLevelOFDM24G_A[i] = + priv->EEPROMRfAOfdmChnlTxPwLevel[0]; + priv->TxPowerLevelCCK_C[i] = + priv->EEPROMRfCCCKChnl1TxPwLevel[0]; + priv->TxPowerLevelOFDM24G_C[i] = + priv->EEPROMRfCOfdmChnlTxPwLevel[0]; + } + for (i = 3; i < 9; i++) { + priv->TxPowerLevelCCK_A[i] = + priv->EEPROMRfACCKChnl1TxPwLevel[1]; + priv->TxPowerLevelOFDM24G_A[i] = + priv->EEPROMRfAOfdmChnlTxPwLevel[1]; + priv->TxPowerLevelCCK_C[i] = + priv->EEPROMRfCCCKChnl1TxPwLevel[1]; + priv->TxPowerLevelOFDM24G_C[i] = + priv->EEPROMRfCOfdmChnlTxPwLevel[1]; + } + for (i = 9; i < 14; i++) { + priv->TxPowerLevelCCK_A[i] = + priv->EEPROMRfACCKChnl1TxPwLevel[2]; + priv->TxPowerLevelOFDM24G_A[i] = + priv->EEPROMRfAOfdmChnlTxPwLevel[2]; + priv->TxPowerLevelCCK_C[i] = + priv->EEPROMRfCCCKChnl1TxPwLevel[2]; + priv->TxPowerLevelOFDM24G_C[i] = + priv->EEPROMRfCOfdmChnlTxPwLevel[2]; + } + for (i = 0; i < 14; i++) + RT_TRACE(COMP_INIT, "priv->TxPowerLevelCCK_A" + "[%d] = 0x%x\n", i, + priv->TxPowerLevelCCK_A[i]); + for (i = 0; i < 14; i++) + RT_TRACE(COMP_INIT, "priv->TxPowerLevelOFDM" + "24G_A[%d] = 0x%x\n", i, + priv->TxPowerLevelOFDM24G_A[i]); + for (i = 0; i < 14; i++) + RT_TRACE(COMP_INIT, "priv->TxPowerLevelCCK_C" + "[%d] = 0x%x\n", i, + priv->TxPowerLevelCCK_C[i]); + for (i = 0; i < 14; i++) + RT_TRACE(COMP_INIT, "priv->TxPowerLevelOFDM" + "24G_C[%d] = 0x%x\n", i, + priv->TxPowerLevelOFDM24G_C[i]); + priv->LegacyHTTxPowerDiff = + priv->EEPROMLegacyHTTxPowerDiff; + priv->AntennaTxPwDiff[0] = 0; + priv->AntennaTxPwDiff[1] = 0; + priv->AntennaTxPwDiff[2] = 0; + priv->CrystalCap = priv->EEPROMCrystalCap; + priv->ThermalMeter[0] = (priv->EEPROMThermalMeter & + 0xf); + priv->ThermalMeter[1] = ((priv->EEPROMThermalMeter & + 0xf0)>>4); + } + } + + if (priv->rf_type == RF_1T2R) { + /* no matter what checkpatch says, the braces are needed */ + RT_TRACE(COMP_INIT, "\n1T2R config\n"); + } else if (priv->rf_type == RF_2T4R) { + RT_TRACE(COMP_INIT, "\n2T4R config\n"); + } + + init_rate_adaptive(dev); + + priv->rf_chip = RF_8256; + + if (priv->RegChannelPlan == 0xf) + priv->ChannelPlan = priv->eeprom_ChannelPlan; + else + priv->ChannelPlan = priv->RegChannelPlan; + + if (priv->eeprom_vid == 0x1186 && priv->eeprom_did == 0x3304) + priv->CustomerID = RT_CID_DLINK; + + switch (priv->eeprom_CustomerID) { + case EEPROM_CID_DEFAULT: + priv->CustomerID = RT_CID_DEFAULT; + break; + case EEPROM_CID_CAMEO: + priv->CustomerID = RT_CID_819x_CAMEO; + break; + case EEPROM_CID_RUNTOP: + priv->CustomerID = RT_CID_819x_RUNTOP; + break; + case EEPROM_CID_NetCore: + priv->CustomerID = RT_CID_819x_Netcore; + break; + case EEPROM_CID_TOSHIBA: + priv->CustomerID = RT_CID_TOSHIBA; + if (priv->eeprom_ChannelPlan&0x80) + priv->ChannelPlan = priv->eeprom_ChannelPlan&0x7f; + else + priv->ChannelPlan = 0x0; + RT_TRACE(COMP_INIT, "Toshiba ChannelPlan = 0x%x\n", + priv->ChannelPlan); + break; + case EEPROM_CID_Nettronix: + priv->ScanDelay = 100; + priv->CustomerID = RT_CID_Nettronix; + break; + case EEPROM_CID_Pronet: + priv->CustomerID = RT_CID_PRONET; + break; + case EEPROM_CID_DLINK: + priv->CustomerID = RT_CID_DLINK; + break; + + case EEPROM_CID_WHQL: + break; + default: + break; + } + + if (priv->ChannelPlan > CHANNEL_PLAN_LEN - 1) + priv->ChannelPlan = 0; + priv->ChannelPlan = COUNTRY_CODE_WORLD_WIDE_13; + + if (priv->eeprom_vid == 0x1186 && priv->eeprom_did == 0x3304) + priv->rtllib->bSupportRemoteWakeUp = true; + else + priv->rtllib->bSupportRemoteWakeUp = false; + + RT_TRACE(COMP_INIT, "RegChannelPlan(%d)\n", priv->RegChannelPlan); + RT_TRACE(COMP_INIT, "ChannelPlan = %d\n", priv->ChannelPlan); + RT_TRACE(COMP_TRACE, "<==== ReadAdapterInfo\n"); +} + +void rtl8192_get_eeprom_size(struct net_device *dev) +{ + u16 curCR; + struct r8192_priv *priv = rtllib_priv(dev); + + RT_TRACE(COMP_INIT, "===========>%s()\n", __func__); + curCR = read_nic_dword(dev, EPROM_CMD); + RT_TRACE(COMP_INIT, "read from Reg Cmd9346CR(%x):%x\n", EPROM_CMD, + curCR); + priv->epromtype = (curCR & EPROM_CMD_9356SEL) ? EEPROM_93C56 : + EEPROM_93C46; + RT_TRACE(COMP_INIT, "<===========%s(), epromtype:%d\n", __func__, + priv->epromtype); + rtl8192_read_eeprom_info(dev); +} + +static void rtl8192_hwconfig(struct net_device *dev) +{ + u32 regRATR = 0, regRRSR = 0; + u8 regBwOpMode = 0, regTmp = 0; + struct r8192_priv *priv = rtllib_priv(dev); + + switch (priv->rtllib->mode) { + case WIRELESS_MODE_B: + regBwOpMode = BW_OPMODE_20MHZ; + regRATR = RATE_ALL_CCK; + regRRSR = RATE_ALL_CCK; + break; + case WIRELESS_MODE_A: + regBwOpMode = BW_OPMODE_5G | BW_OPMODE_20MHZ; + regRATR = RATE_ALL_OFDM_AG; + regRRSR = RATE_ALL_OFDM_AG; + break; + case WIRELESS_MODE_G: + regBwOpMode = BW_OPMODE_20MHZ; + regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; + regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; + break; + case WIRELESS_MODE_AUTO: + case WIRELESS_MODE_N_24G: + regBwOpMode = BW_OPMODE_20MHZ; + regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG | + RATE_ALL_OFDM_1SS | RATE_ALL_OFDM_2SS; + regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; + break; + case WIRELESS_MODE_N_5G: + regBwOpMode = BW_OPMODE_5G; + regRATR = RATE_ALL_OFDM_AG | RATE_ALL_OFDM_1SS | + RATE_ALL_OFDM_2SS; + regRRSR = RATE_ALL_OFDM_AG; + break; + default: + regBwOpMode = BW_OPMODE_20MHZ; + regRATR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; + regRRSR = RATE_ALL_CCK | RATE_ALL_OFDM_AG; + break; + } + + write_nic_byte(dev, BW_OPMODE, regBwOpMode); + { + u32 ratr_value = 0; + ratr_value = regRATR; + if (priv->rf_type == RF_1T2R) + ratr_value &= ~(RATE_ALL_OFDM_2SS); + write_nic_dword(dev, RATR0, ratr_value); + write_nic_byte(dev, UFWP, 1); + } + regTmp = read_nic_byte(dev, 0x313); + regRRSR = ((regTmp) << 24) | (regRRSR & 0x00ffffff); + write_nic_dword(dev, RRSR, regRRSR); + + write_nic_word(dev, RETRY_LIMIT, + priv->ShortRetryLimit << RETRY_LIMIT_SHORT_SHIFT | + priv->LongRetryLimit << RETRY_LIMIT_LONG_SHIFT); +} + +bool rtl8192_adapter_start(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + u32 ulRegRead; + bool rtStatus = true; + u8 tmpvalue; + u8 ICVersion, SwitchingRegulatorOutput; + bool bfirmwareok = true; + u32 tmpRegA, tmpRegC, TempCCk; + int i = 0; + u32 retry_times = 0; + + RT_TRACE(COMP_INIT, "====>%s()\n", __func__); + priv->being_init_adapter = true; + +start: + rtl8192_pci_resetdescring(dev); + priv->Rf_Mode = RF_OP_By_SW_3wire; + if (priv->ResetProgress == RESET_TYPE_NORESET) { + write_nic_byte(dev, ANAPAR, 0x37); + mdelay(500); + } + priv->pFirmware->firmware_status = FW_STATUS_0_INIT; + + if (priv->RegRfOff == true) + priv->rtllib->eRFPowerState = eRfOff; + + ulRegRead = read_nic_dword(dev, CPU_GEN); + if (priv->pFirmware->firmware_status == FW_STATUS_0_INIT) + ulRegRead |= CPU_GEN_SYSTEM_RESET; + else if (priv->pFirmware->firmware_status == FW_STATUS_5_READY) + ulRegRead |= CPU_GEN_FIRMWARE_RESET; + else + RT_TRACE(COMP_ERR, "ERROR in %s(): undefined firmware state(%d)" + "\n", __func__, priv->pFirmware->firmware_status); + + write_nic_dword(dev, CPU_GEN, ulRegRead); + + ICVersion = read_nic_byte(dev, IC_VERRSION); + if (ICVersion >= 0x4) { + SwitchingRegulatorOutput = read_nic_byte(dev, SWREGULATOR); + if (SwitchingRegulatorOutput != 0xb8) { + write_nic_byte(dev, SWREGULATOR, 0xa8); + mdelay(1); + write_nic_byte(dev, SWREGULATOR, 0xb8); + } + } + RT_TRACE(COMP_INIT, "BB Config Start!\n"); + rtStatus = rtl8192_BBConfig(dev); + if (rtStatus != true) { + RT_TRACE(COMP_ERR, "BB Config failed\n"); + return rtStatus; + } + RT_TRACE(COMP_INIT, "BB Config Finished!\n"); + + priv->LoopbackMode = RTL819X_NO_LOOPBACK; + if (priv->ResetProgress == RESET_TYPE_NORESET) { + ulRegRead = read_nic_dword(dev, CPU_GEN); + if (priv->LoopbackMode == RTL819X_NO_LOOPBACK) + ulRegRead = ((ulRegRead & CPU_GEN_NO_LOOPBACK_MSK) | + CPU_GEN_NO_LOOPBACK_SET); + else if (priv->LoopbackMode == RTL819X_MAC_LOOPBACK) + ulRegRead |= CPU_CCK_LOOPBACK; + else + RT_TRACE(COMP_ERR, "Serious error: wrong loopback" + " mode setting\n"); + + write_nic_dword(dev, CPU_GEN, ulRegRead); + + udelay(500); + } + rtl8192_hwconfig(dev); + write_nic_byte(dev, CMDR, CR_RE | CR_TE); + + write_nic_byte(dev, PCIF, ((MXDMA2_NoLimit<<MXDMA2_RX_SHIFT) | + (MXDMA2_NoLimit<<MXDMA2_TX_SHIFT))); + write_nic_dword(dev, MAC0, ((u32 *)dev->dev_addr)[0]); + write_nic_word(dev, MAC4, ((u16 *)(dev->dev_addr + 4))[0]); + write_nic_dword(dev, RCR, priv->ReceiveConfig); + + write_nic_dword(dev, RQPN1, NUM_OF_PAGE_IN_FW_QUEUE_BK << + RSVD_FW_QUEUE_PAGE_BK_SHIFT | + NUM_OF_PAGE_IN_FW_QUEUE_BE << + RSVD_FW_QUEUE_PAGE_BE_SHIFT | + NUM_OF_PAGE_IN_FW_QUEUE_VI << + RSVD_FW_QUEUE_PAGE_VI_SHIFT | + NUM_OF_PAGE_IN_FW_QUEUE_VO << + RSVD_FW_QUEUE_PAGE_VO_SHIFT); + write_nic_dword(dev, RQPN2, NUM_OF_PAGE_IN_FW_QUEUE_MGNT << + RSVD_FW_QUEUE_PAGE_MGNT_SHIFT); + write_nic_dword(dev, RQPN3, APPLIED_RESERVED_QUEUE_IN_FW | + NUM_OF_PAGE_IN_FW_QUEUE_BCN << + RSVD_FW_QUEUE_PAGE_BCN_SHIFT| + NUM_OF_PAGE_IN_FW_QUEUE_PUB << + RSVD_FW_QUEUE_PAGE_PUB_SHIFT); + + rtl8192_tx_enable(dev); + rtl8192_rx_enable(dev); + ulRegRead = (0xFFF00000 & read_nic_dword(dev, RRSR)) | + RATE_ALL_OFDM_AG | RATE_ALL_CCK; + write_nic_dword(dev, RRSR, ulRegRead); + write_nic_dword(dev, RATR0+4*7, (RATE_ALL_OFDM_AG | RATE_ALL_CCK)); + + write_nic_byte(dev, ACK_TIMEOUT, 0x30); + + if (priv->ResetProgress == RESET_TYPE_NORESET) + rtl8192_SetWirelessMode(dev, priv->rtllib->mode); + CamResetAllEntry(dev); + { + u8 SECR_value = 0x0; + SECR_value |= SCR_TxEncEnable; + SECR_value |= SCR_RxDecEnable; + SECR_value |= SCR_NoSKMC; + write_nic_byte(dev, SECR, SECR_value); + } + write_nic_word(dev, ATIMWND, 2); + write_nic_word(dev, BCN_INTERVAL, 100); + { + int i; + for (i = 0; i < QOS_QUEUE_NUM; i++) + write_nic_dword(dev, WDCAPARA_ADD[i], 0x005e4332); + } + write_nic_byte(dev, 0xbe, 0xc0); + + rtl8192_phy_configmac(dev); + + if (priv->card_8192_version > (u8) VERSION_8190_BD) { + rtl8192_phy_getTxPower(dev); + rtl8192_phy_setTxPower(dev, priv->chan); + } + + tmpvalue = read_nic_byte(dev, IC_VERRSION); + priv->IC_Cut = tmpvalue; + RT_TRACE(COMP_INIT, "priv->IC_Cut= 0x%x\n", priv->IC_Cut); + if (priv->IC_Cut >= IC_VersionCut_D) { + if (priv->IC_Cut == IC_VersionCut_D) { + /* no matter what checkpatch says, braces are needed */ + RT_TRACE(COMP_INIT, "D-cut\n"); + } else if (priv->IC_Cut == IC_VersionCut_E) { + RT_TRACE(COMP_INIT, "E-cut\n"); + } + } else { + RT_TRACE(COMP_INIT, "Before C-cut\n"); + } + + RT_TRACE(COMP_INIT, "Load Firmware!\n"); + bfirmwareok = init_firmware(dev); + if (!bfirmwareok) { + if (retry_times < 10) { + retry_times++; + goto start; + } else { + rtStatus = false; + goto end; + } + } + RT_TRACE(COMP_INIT, "Load Firmware finished!\n"); + if (priv->ResetProgress == RESET_TYPE_NORESET) { + RT_TRACE(COMP_INIT, "RF Config Started!\n"); + rtStatus = rtl8192_phy_RFConfig(dev); + if (rtStatus != true) { + RT_TRACE(COMP_ERR, "RF Config failed\n"); + return rtStatus; + } + RT_TRACE(COMP_INIT, "RF Config Finished!\n"); + } + rtl8192_phy_updateInitGain(dev); + + rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn, 0x1); + rtl8192_setBBreg(dev, rFPGA0_RFMOD, bOFDMEn, 0x1); + + write_nic_byte(dev, 0x87, 0x0); + + if (priv->RegRfOff == true) { + RT_TRACE((COMP_INIT | COMP_RF | COMP_POWER), + "%s(): Turn off RF for RegRfOff ----------\n", + __func__); + MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_SW, true); + } else if (priv->rtllib->RfOffReason > RF_CHANGE_BY_PS) { + RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for" + " RfOffReason(%d) ----------\n", __func__, + priv->rtllib->RfOffReason); + MgntActSet_RF_State(dev, eRfOff, priv->rtllib->RfOffReason, + true); + } else if (priv->rtllib->RfOffReason >= RF_CHANGE_BY_IPS) { + RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): Turn off RF for" + " RfOffReason(%d) ----------\n", __func__, + priv->rtllib->RfOffReason); + MgntActSet_RF_State(dev, eRfOff, priv->rtllib->RfOffReason, + true); + } else { + RT_TRACE((COMP_INIT|COMP_RF|COMP_POWER), "%s(): RF-ON\n", + __func__); + priv->rtllib->eRFPowerState = eRfOn; + priv->rtllib->RfOffReason = 0; + } + + if (priv->rtllib->FwRWRF) + priv->Rf_Mode = RF_OP_By_FW; + else + priv->Rf_Mode = RF_OP_By_SW_3wire; + + if (priv->ResetProgress == RESET_TYPE_NORESET) { + dm_initialize_txpower_tracking(dev); + + if (priv->IC_Cut >= IC_VersionCut_D) { + tmpRegA = rtl8192_QueryBBReg(dev, + rOFDM0_XATxIQImbalance, bMaskDWord); + tmpRegC = rtl8192_QueryBBReg(dev, + rOFDM0_XCTxIQImbalance, bMaskDWord); + for (i = 0; i < TxBBGainTableLength; i++) { + if (tmpRegA == + priv->txbbgain_table[i].txbbgain_value) { + priv->rfa_txpowertrackingindex = (u8)i; + priv->rfa_txpowertrackingindex_real = + (u8)i; + priv->rfa_txpowertracking_default = + priv->rfa_txpowertrackingindex; + break; + } + } + + TempCCk = rtl8192_QueryBBReg(dev, + rCCK0_TxFilter1, bMaskByte2); + + for (i = 0; i < CCKTxBBGainTableLength; i++) { + if (TempCCk == priv->cck_txbbgain_table[i].ccktxbb_valuearray[0]) { + priv->CCKPresentAttentuation_20Mdefault = (u8)i; + break; + } + } + priv->CCKPresentAttentuation_40Mdefault = 0; + priv->CCKPresentAttentuation_difference = 0; + priv->CCKPresentAttentuation = + priv->CCKPresentAttentuation_20Mdefault; + RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpower" + "trackingindex_initial = %d\n", + priv->rfa_txpowertrackingindex); + RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpower" + "trackingindex_real__initial = %d\n", + priv->rfa_txpowertrackingindex_real); + RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresent" + "Attentuation_difference_initial = %d\n", + priv->CCKPresentAttentuation_difference); + RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresent" + "Attentuation_initial = %d\n", + priv->CCKPresentAttentuation); + priv->btxpower_tracking = false; + } + } + rtl8192_irq_enable(dev); +end: + priv->being_init_adapter = false; + return rtStatus; +} + +static void rtl8192_net_update(struct net_device *dev) +{ + + struct r8192_priv *priv = rtllib_priv(dev); + struct rtllib_network *net; + u16 BcnTimeCfg = 0, BcnCW = 6, BcnIFS = 0xf; + u16 rate_config = 0; + + net = &priv->rtllib->current_network; + rtl8192_config_rate(dev, &rate_config); + priv->dot11CurrentPreambleMode = PREAMBLE_AUTO; + priv->basic_rate = rate_config &= 0x15f; + write_nic_dword(dev, BSSIDR, ((u32 *)net->bssid)[0]); + write_nic_word(dev, BSSIDR+4, ((u16 *)net->bssid)[2]); + + if (priv->rtllib->iw_mode == IW_MODE_ADHOC) { + write_nic_word(dev, ATIMWND, 2); + write_nic_word(dev, BCN_DMATIME, 256); + write_nic_word(dev, BCN_INTERVAL, net->beacon_interval); + write_nic_word(dev, BCN_DRV_EARLY_INT, 10); + write_nic_byte(dev, BCN_ERR_THRESH, 100); + + BcnTimeCfg |= (BcnCW<<BCN_TCFG_CW_SHIFT); + BcnTimeCfg |= BcnIFS<<BCN_TCFG_IFS; + + write_nic_word(dev, BCN_TCFG, BcnTimeCfg); + } +} + +void rtl8192_link_change(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + struct rtllib_device *ieee = priv->rtllib; + + if (!priv->up) + return; + + if (ieee->state == RTLLIB_LINKED) { + rtl8192_net_update(dev); + priv->ops->update_ratr_table(dev); + if ((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || + (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) + EnableHWSecurityConfig8192(dev); + } else { + write_nic_byte(dev, 0x173, 0); + } + rtl8192e_update_msr(dev); + + if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC) { + u32 reg = 0; + reg = read_nic_dword(dev, RCR); + if (priv->rtllib->state == RTLLIB_LINKED) { + if (ieee->IntelPromiscuousModeInfo.bPromiscuousOn) + ; + else + priv->ReceiveConfig = reg |= RCR_CBSSID; + } else + priv->ReceiveConfig = reg &= ~RCR_CBSSID; + + write_nic_dword(dev, RCR, reg); + } +} + +void rtl8192_AllowAllDestAddr(struct net_device *dev, + bool bAllowAllDA, bool WriteIntoReg) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + if (bAllowAllDA) + priv->ReceiveConfig |= RCR_AAP; + else + priv->ReceiveConfig &= ~RCR_AAP; + + if (WriteIntoReg) + write_nic_dword(dev, RCR, priv->ReceiveConfig); +} + +static u8 MRateToHwRate8190Pci(u8 rate) +{ + u8 ret = DESC90_RATE1M; + + switch (rate) { + case MGN_1M: + ret = DESC90_RATE1M; + break; + case MGN_2M: + ret = DESC90_RATE2M; + break; + case MGN_5_5M: + ret = DESC90_RATE5_5M; + break; + case MGN_11M: + ret = DESC90_RATE11M; + break; + case MGN_6M: + ret = DESC90_RATE6M; + break; + case MGN_9M: + ret = DESC90_RATE9M; + break; + case MGN_12M: + ret = DESC90_RATE12M; + break; + case MGN_18M: + ret = DESC90_RATE18M; + break; + case MGN_24M: + ret = DESC90_RATE24M; + break; + case MGN_36M: + ret = DESC90_RATE36M; + break; + case MGN_48M: + ret = DESC90_RATE48M; + break; + case MGN_54M: + ret = DESC90_RATE54M; + break; + case MGN_MCS0: + ret = DESC90_RATEMCS0; + break; + case MGN_MCS1: + ret = DESC90_RATEMCS1; + break; + case MGN_MCS2: + ret = DESC90_RATEMCS2; + break; + case MGN_MCS3: + ret = DESC90_RATEMCS3; + break; + case MGN_MCS4: + ret = DESC90_RATEMCS4; + break; + case MGN_MCS5: + ret = DESC90_RATEMCS5; + break; + case MGN_MCS6: + ret = DESC90_RATEMCS6; + break; + case MGN_MCS7: + ret = DESC90_RATEMCS7; + break; + case MGN_MCS8: + ret = DESC90_RATEMCS8; + break; + case MGN_MCS9: + ret = DESC90_RATEMCS9; + break; + case MGN_MCS10: + ret = DESC90_RATEMCS10; + break; + case MGN_MCS11: + ret = DESC90_RATEMCS11; + break; + case MGN_MCS12: + ret = DESC90_RATEMCS12; + break; + case MGN_MCS13: + ret = DESC90_RATEMCS13; + break; + case MGN_MCS14: + ret = DESC90_RATEMCS14; + break; + case MGN_MCS15: + ret = DESC90_RATEMCS15; + break; + case (0x80|0x20): + ret = DESC90_RATEMCS32; + break; + default: + break; + } + return ret; +} + +static u8 rtl8192_MapHwQueueToFirmwareQueue(u8 QueueID, u8 priority) +{ + u8 QueueSelect = 0x0; + + switch (QueueID) { + case BE_QUEUE: + QueueSelect = QSLT_BE; + break; + + case BK_QUEUE: + QueueSelect = QSLT_BK; + break; + + case VO_QUEUE: + QueueSelect = QSLT_VO; + break; + + case VI_QUEUE: + QueueSelect = QSLT_VI; + break; + case MGNT_QUEUE: + QueueSelect = QSLT_MGNT; + break; + case BEACON_QUEUE: + QueueSelect = QSLT_BEACON; + break; + case TXCMD_QUEUE: + QueueSelect = QSLT_CMD; + break; + case HIGH_QUEUE: + QueueSelect = QSLT_HIGH; + break; + default: + RT_TRACE(COMP_ERR, "TransmitTCB(): Impossible Queue Selection:" + " %d\n", QueueID); + break; + } + return QueueSelect; +} + +void rtl8192_tx_fill_desc(struct net_device *dev, struct tx_desc *pdesc, + struct cb_desc *cb_desc, struct sk_buff *skb) +{ + struct r8192_priv *priv = rtllib_priv(dev); + dma_addr_t mapping = pci_map_single(priv->pdev, skb->data, skb->len, + PCI_DMA_TODEVICE); + struct tx_fwinfo_8190pci *pTxFwInfo = NULL; + pTxFwInfo = (struct tx_fwinfo_8190pci *)skb->data; + memset(pTxFwInfo, 0, sizeof(struct tx_fwinfo_8190pci)); + pTxFwInfo->TxHT = (cb_desc->data_rate & 0x80) ? 1 : 0; + pTxFwInfo->TxRate = MRateToHwRate8190Pci((u8)cb_desc->data_rate); + pTxFwInfo->EnableCPUDur = cb_desc->bTxEnableFwCalcDur; + pTxFwInfo->Short = rtl8192_QueryIsShort(pTxFwInfo->TxHT, + pTxFwInfo->TxRate, + cb_desc); + + if (cb_desc->bAMPDUEnable) { + pTxFwInfo->AllowAggregation = 1; + pTxFwInfo->RxMF = cb_desc->ampdu_factor; + pTxFwInfo->RxAMD = cb_desc->ampdu_density; + } else { + pTxFwInfo->AllowAggregation = 0; + pTxFwInfo->RxMF = 0; + pTxFwInfo->RxAMD = 0; + } + + pTxFwInfo->RtsEnable = (cb_desc->bRTSEnable) ? 1 : 0; + pTxFwInfo->CtsEnable = (cb_desc->bCTSEnable) ? 1 : 0; + pTxFwInfo->RtsSTBC = (cb_desc->bRTSSTBC) ? 1 : 0; + pTxFwInfo->RtsHT = (cb_desc->rts_rate&0x80) ? 1 : 0; + pTxFwInfo->RtsRate = MRateToHwRate8190Pci((u8)cb_desc->rts_rate); + pTxFwInfo->RtsBandwidth = 0; + pTxFwInfo->RtsSubcarrier = cb_desc->RTSSC; + pTxFwInfo->RtsShort = (pTxFwInfo->RtsHT == 0) ? + (cb_desc->bRTSUseShortPreamble ? 1 : 0) : + (cb_desc->bRTSUseShortGI ? 1 : 0); + if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20_40) { + if (cb_desc->bPacketBW) { + pTxFwInfo->TxBandwidth = 1; + pTxFwInfo->TxSubCarrier = 0; + } else { + pTxFwInfo->TxBandwidth = 0; + pTxFwInfo->TxSubCarrier = priv->nCur40MhzPrimeSC; + } + } else { + pTxFwInfo->TxBandwidth = 0; + pTxFwInfo->TxSubCarrier = 0; + } + + memset((u8 *)pdesc, 0, 12); + pdesc->LINIP = 0; + pdesc->CmdInit = 1; + pdesc->Offset = sizeof(struct tx_fwinfo_8190pci) + 8; + pdesc->PktSize = (u16)skb->len-sizeof(struct tx_fwinfo_8190pci); + + pdesc->SecCAMID = 0; + pdesc->RATid = cb_desc->RATRIndex; + + + pdesc->NoEnc = 1; + pdesc->SecType = 0x0; + if (cb_desc->bHwSec) { + static u8 tmp; + if (!tmp) { + RT_TRACE(COMP_DBG, "==>================hw sec\n"); + tmp = 1; + } + switch (priv->rtllib->pairwise_key_type) { + case KEY_TYPE_WEP40: + case KEY_TYPE_WEP104: + pdesc->SecType = 0x1; + pdesc->NoEnc = 0; + break; + case KEY_TYPE_TKIP: + pdesc->SecType = 0x2; + pdesc->NoEnc = 0; + break; + case KEY_TYPE_CCMP: + pdesc->SecType = 0x3; + pdesc->NoEnc = 0; + break; + case KEY_TYPE_NA: + pdesc->SecType = 0x0; + pdesc->NoEnc = 1; + break; + } + } + + pdesc->PktId = 0x0; + + pdesc->QueueSelect = rtl8192_MapHwQueueToFirmwareQueue( + cb_desc->queue_index, + cb_desc->priority); + pdesc->TxFWInfoSize = sizeof(struct tx_fwinfo_8190pci); + + pdesc->DISFB = cb_desc->bTxDisableRateFallBack; + pdesc->USERATE = cb_desc->bTxUseDriverAssingedRate; + + pdesc->FirstSeg = 1; + pdesc->LastSeg = 1; + pdesc->TxBufferSize = skb->len; + + pdesc->TxBuffAddr = cpu_to_le32(mapping); +} + +void rtl8192_tx_fill_cmd_desc(struct net_device *dev, + struct tx_desc_cmd *entry, + struct cb_desc *cb_desc, struct sk_buff* skb) +{ + struct r8192_priv *priv = rtllib_priv(dev); + dma_addr_t mapping = pci_map_single(priv->pdev, skb->data, skb->len, + PCI_DMA_TODEVICE); + + memset(entry, 0, 12); + entry->LINIP = cb_desc->bLastIniPkt; + entry->FirstSeg = 1; + entry->LastSeg = 1; + if (cb_desc->bCmdOrInit == DESC_PACKET_TYPE_INIT) { + entry->CmdInit = DESC_PACKET_TYPE_INIT; + } else { + struct tx_desc * entry_tmp = (struct tx_desc *)entry; + entry_tmp->CmdInit = DESC_PACKET_TYPE_NORMAL; + entry_tmp->Offset = sizeof(struct tx_fwinfo_8190pci) + 8; + entry_tmp->PktSize = (u16)(cb_desc->pkt_size + + entry_tmp->Offset); + entry_tmp->QueueSelect = QSLT_CMD; + entry_tmp->TxFWInfoSize = 0x08; + entry_tmp->RATid = (u8)DESC_PACKET_TYPE_INIT; + } + entry->TxBufferSize = skb->len; + entry->TxBuffAddr = cpu_to_le32(mapping); + entry->OWN = 1; +} + +static u8 HwRateToMRate90(bool bIsHT, u8 rate) +{ + u8 ret_rate = 0x02; + + if (!bIsHT) { + switch (rate) { + case DESC90_RATE1M: + ret_rate = MGN_1M; + break; + case DESC90_RATE2M: + ret_rate = MGN_2M; + break; + case DESC90_RATE5_5M: + ret_rate = MGN_5_5M; + break; + case DESC90_RATE11M: + ret_rate = MGN_11M; + break; + case DESC90_RATE6M: + ret_rate = MGN_6M; + break; + case DESC90_RATE9M: + ret_rate = MGN_9M; + break; + case DESC90_RATE12M: + ret_rate = MGN_12M; + break; + case DESC90_RATE18M: + ret_rate = MGN_18M; + break; + case DESC90_RATE24M: + ret_rate = MGN_24M; + break; + case DESC90_RATE36M: + ret_rate = MGN_36M; + break; + case DESC90_RATE48M: + ret_rate = MGN_48M; + break; + case DESC90_RATE54M: + ret_rate = MGN_54M; + break; + + default: + RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported" + "Rate [%x], bIsHT = %d!!!\n", rate, bIsHT); + break; + } + + } else { + switch (rate) { + case DESC90_RATEMCS0: + ret_rate = MGN_MCS0; + break; + case DESC90_RATEMCS1: + ret_rate = MGN_MCS1; + break; + case DESC90_RATEMCS2: + ret_rate = MGN_MCS2; + break; + case DESC90_RATEMCS3: + ret_rate = MGN_MCS3; + break; + case DESC90_RATEMCS4: + ret_rate = MGN_MCS4; + break; + case DESC90_RATEMCS5: + ret_rate = MGN_MCS5; + break; + case DESC90_RATEMCS6: + ret_rate = MGN_MCS6; + break; + case DESC90_RATEMCS7: + ret_rate = MGN_MCS7; + break; + case DESC90_RATEMCS8: + ret_rate = MGN_MCS8; + break; + case DESC90_RATEMCS9: + ret_rate = MGN_MCS9; + break; + case DESC90_RATEMCS10: + ret_rate = MGN_MCS10; + break; + case DESC90_RATEMCS11: + ret_rate = MGN_MCS11; + break; + case DESC90_RATEMCS12: + ret_rate = MGN_MCS12; + break; + case DESC90_RATEMCS13: + ret_rate = MGN_MCS13; + break; + case DESC90_RATEMCS14: + ret_rate = MGN_MCS14; + break; + case DESC90_RATEMCS15: + ret_rate = MGN_MCS15; + break; + case DESC90_RATEMCS32: + ret_rate = (0x80|0x20); + break; + + default: + RT_TRACE(COMP_RECV, "HwRateToMRate90(): Non supported " + "Rate [%x], bIsHT = %d!!!\n", rate, bIsHT); + break; + } + } + + return ret_rate; +} + +static long rtl8192_signal_scale_mapping(struct r8192_priv *priv, long currsig) +{ + long retsig; + + if (currsig >= 61 && currsig <= 100) + retsig = 90 + ((currsig - 60) / 4); + else if (currsig >= 41 && currsig <= 60) + retsig = 78 + ((currsig - 40) / 2); + else if (currsig >= 31 && currsig <= 40) + retsig = 66 + (currsig - 30); + else if (currsig >= 21 && currsig <= 30) + retsig = 54 + (currsig - 20); + else if (currsig >= 5 && currsig <= 20) + retsig = 42 + (((currsig - 5) * 2) / 3); + else if (currsig == 4) + retsig = 36; + else if (currsig == 3) + retsig = 27; + else if (currsig == 2) + retsig = 18; + else if (currsig == 1) + retsig = 9; + else + retsig = currsig; + + return retsig; +} + + +#define rx_hal_is_cck_rate(_pdrvinfo)\ + ((_pdrvinfo->RxRate == DESC90_RATE1M ||\ + _pdrvinfo->RxRate == DESC90_RATE2M ||\ + _pdrvinfo->RxRate == DESC90_RATE5_5M ||\ + _pdrvinfo->RxRate == DESC90_RATE11M) &&\ + !_pdrvinfo->RxHT) + +static void rtl8192_query_rxphystatus( + struct r8192_priv *priv, + struct rtllib_rx_stats *pstats, + struct rx_desc *pdesc, + struct rx_fwinfo *pdrvinfo, + struct rtllib_rx_stats *precord_stats, + bool bpacket_match_bssid, + bool bpacket_toself, + bool bPacketBeacon, + bool bToSelfBA + ) +{ + struct phy_sts_ofdm_819xpci *pofdm_buf; + struct phy_sts_cck_819xpci *pcck_buf; + struct phy_ofdm_rx_status_rxsc_sgien_exintfflag *prxsc; + u8 *prxpkt; + u8 i, max_spatial_stream, tmp_rxsnr, tmp_rxevm, rxsc_sgien_exflg; + char rx_pwr[4], rx_pwr_all = 0; + char rx_snrX, rx_evmX; + u8 evm, pwdb_all; + u32 RSSI, total_rssi = 0; + u8 is_cck_rate = 0; + u8 rf_rx_num = 0; + static u8 check_reg824; + static u32 reg824_bit9; + + priv->stats.numqry_phystatus++; + + is_cck_rate = rx_hal_is_cck_rate(pdrvinfo); + memset(precord_stats, 0, sizeof(struct rtllib_rx_stats)); + pstats->bPacketMatchBSSID = precord_stats->bPacketMatchBSSID = + bpacket_match_bssid; + pstats->bPacketToSelf = precord_stats->bPacketToSelf = bpacket_toself; + pstats->bIsCCK = precord_stats->bIsCCK = is_cck_rate; + pstats->bPacketBeacon = precord_stats->bPacketBeacon = bPacketBeacon; + pstats->bToSelfBA = precord_stats->bToSelfBA = bToSelfBA; + if (check_reg824 == 0) { + reg824_bit9 = rtl8192_QueryBBReg(priv->rtllib->dev, + rFPGA0_XA_HSSIParameter2, 0x200); + check_reg824 = 1; + } + + + prxpkt = (u8 *)pdrvinfo; + + prxpkt += sizeof(struct rx_fwinfo); + + pcck_buf = (struct phy_sts_cck_819xpci *)prxpkt; + pofdm_buf = (struct phy_sts_ofdm_819xpci *)prxpkt; + + pstats->RxMIMOSignalQuality[0] = -1; + pstats->RxMIMOSignalQuality[1] = -1; + precord_stats->RxMIMOSignalQuality[0] = -1; + precord_stats->RxMIMOSignalQuality[1] = -1; + + if (is_cck_rate) { + u8 report; + + priv->stats.numqry_phystatusCCK++; + if (!reg824_bit9) { + report = pcck_buf->cck_agc_rpt & 0xc0; + report = report>>6; + switch (report) { + case 0x3: + rx_pwr_all = -35 - (pcck_buf->cck_agc_rpt & + 0x3e); + break; + case 0x2: + rx_pwr_all = -23 - (pcck_buf->cck_agc_rpt & + 0x3e); + break; + case 0x1: + rx_pwr_all = -11 - (pcck_buf->cck_agc_rpt & + 0x3e); + break; + case 0x0: + rx_pwr_all = 8 - (pcck_buf->cck_agc_rpt & 0x3e); + break; + } + } else { + report = pcck_buf->cck_agc_rpt & 0x60; + report = report>>5; + switch (report) { + case 0x3: + rx_pwr_all = -35 - + ((pcck_buf->cck_agc_rpt & + 0x1f) << 1); + break; + case 0x2: + rx_pwr_all = -23 - + ((pcck_buf->cck_agc_rpt & + 0x1f) << 1); + break; + case 0x1: + rx_pwr_all = -11 - + ((pcck_buf->cck_agc_rpt & + 0x1f) << 1); + break; + case 0x0: + rx_pwr_all = -8 - + ((pcck_buf->cck_agc_rpt & + 0x1f) << 1); + break; + } + } + + pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all); + pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all; + pstats->RecvSignalPower = rx_pwr_all; + + if (bpacket_match_bssid) { + u8 sq; + + if (pstats->RxPWDBAll > 40) { + sq = 100; + } else { + sq = pcck_buf->sq_rpt; + + if (pcck_buf->sq_rpt > 64) + sq = 0; + else if (pcck_buf->sq_rpt < 20) + sq = 100; + else + sq = ((64-sq) * 100) / 44; + } + pstats->SignalQuality = sq; + precord_stats->SignalQuality = sq; + pstats->RxMIMOSignalQuality[0] = sq; + precord_stats->RxMIMOSignalQuality[0] = sq; + pstats->RxMIMOSignalQuality[1] = -1; + precord_stats->RxMIMOSignalQuality[1] = -1; + } + } else { + priv->stats.numqry_phystatusHT++; + for (i = RF90_PATH_A; i < RF90_PATH_MAX; i++) { + if (priv->brfpath_rxenable[i]) + rf_rx_num++; + + rx_pwr[i] = ((pofdm_buf->trsw_gain_X[i] & 0x3F) * + 2) - 110; + + tmp_rxsnr = pofdm_buf->rxsnr_X[i]; + rx_snrX = (char)(tmp_rxsnr); + rx_snrX /= 2; + priv->stats.rxSNRdB[i] = (long)rx_snrX; + + RSSI = rtl819x_query_rxpwrpercentage(rx_pwr[i]); + if (priv->brfpath_rxenable[i]) + total_rssi += RSSI; + + if (bpacket_match_bssid) { + pstats->RxMIMOSignalStrength[i] = (u8) RSSI; + precord_stats->RxMIMOSignalStrength[i] = + (u8) RSSI; + } + } + + + rx_pwr_all = (((pofdm_buf->pwdb_all) >> 1) & 0x7f) - 106; + pwdb_all = rtl819x_query_rxpwrpercentage(rx_pwr_all); + + pstats->RxPWDBAll = precord_stats->RxPWDBAll = pwdb_all; + pstats->RxPower = precord_stats->RxPower = rx_pwr_all; + pstats->RecvSignalPower = rx_pwr_all; + if (pdrvinfo->RxHT && pdrvinfo->RxRate >= DESC90_RATEMCS8 && + pdrvinfo->RxRate <= DESC90_RATEMCS15) + max_spatial_stream = 2; + else + max_spatial_stream = 1; + + for (i = 0; i < max_spatial_stream; i++) { + tmp_rxevm = pofdm_buf->rxevm_X[i]; + rx_evmX = (char)(tmp_rxevm); + + rx_evmX /= 2; + + evm = rtl819x_evm_dbtopercentage(rx_evmX); + if (bpacket_match_bssid) { + if (i == 0) { + pstats->SignalQuality = (u8)(evm & + 0xff); + precord_stats->SignalQuality = (u8)(evm + & 0xff); + } + pstats->RxMIMOSignalQuality[i] = (u8)(evm & + 0xff); + precord_stats->RxMIMOSignalQuality[i] = (u8)(evm + & 0xff); + } + } + + + rxsc_sgien_exflg = pofdm_buf->rxsc_sgien_exflg; + prxsc = (struct phy_ofdm_rx_status_rxsc_sgien_exintfflag *) + &rxsc_sgien_exflg; + if (pdrvinfo->BW) + priv->stats.received_bwtype[1+prxsc->rxsc]++; + else + priv->stats.received_bwtype[0]++; + } + + if (is_cck_rate) { + pstats->SignalStrength = precord_stats->SignalStrength = + (u8)(rtl8192_signal_scale_mapping(priv, + (long)pwdb_all)); + + } else { + if (rf_rx_num != 0) + pstats->SignalStrength = precord_stats->SignalStrength = + (u8)(rtl8192_signal_scale_mapping(priv, + (long)(total_rssi /= rf_rx_num))); + } +} + +static void rtl8192_process_phyinfo(struct r8192_priv *priv, u8 *buffer, + struct rtllib_rx_stats *prev_st, + struct rtllib_rx_stats *curr_st) +{ + bool bcheck = false; + u8 rfpath; + u32 ij, tmp_val; + static u32 slide_rssi_index, slide_rssi_statistics; + static u32 slide_evm_index, slide_evm_statistics; + static u32 last_rssi, last_evm; + static u32 slide_beacon_adc_pwdb_index; + static u32 slide_beacon_adc_pwdb_statistics; + static u32 last_beacon_adc_pwdb; + struct rtllib_hdr_3addr *hdr; + u16 sc; + unsigned int frag, seq; + + hdr = (struct rtllib_hdr_3addr *)buffer; + sc = le16_to_cpu(hdr->seq_ctl); + frag = WLAN_GET_SEQ_FRAG(sc); + seq = WLAN_GET_SEQ_SEQ(sc); + curr_st->Seq_Num = seq; + if (!prev_st->bIsAMPDU) + bcheck = true; + + if (slide_rssi_statistics++ >= PHY_RSSI_SLID_WIN_MAX) { + slide_rssi_statistics = PHY_RSSI_SLID_WIN_MAX; + last_rssi = priv->stats.slide_signal_strength[slide_rssi_index]; + priv->stats.slide_rssi_total -= last_rssi; + } + priv->stats.slide_rssi_total += prev_st->SignalStrength; + + priv->stats.slide_signal_strength[slide_rssi_index++] = + prev_st->SignalStrength; + if (slide_rssi_index >= PHY_RSSI_SLID_WIN_MAX) + slide_rssi_index = 0; + + tmp_val = priv->stats.slide_rssi_total/slide_rssi_statistics; + priv->stats.signal_strength = rtl819x_translate_todbm(priv, + (u8)tmp_val); + curr_st->rssi = priv->stats.signal_strength; + if (!prev_st->bPacketMatchBSSID) { + if (!prev_st->bToSelfBA) + return; + } + + if (!bcheck) + return; + + rtl819x_process_cck_rxpathsel(priv, prev_st); + + priv->stats.num_process_phyinfo++; + if (!prev_st->bIsCCK && prev_st->bPacketToSelf) { + for (rfpath = RF90_PATH_A; rfpath < RF90_PATH_C; rfpath++) { + if (!rtl8192_phy_CheckIsLegalRFPath(priv->rtllib->dev, + rfpath)) + continue; + RT_TRACE(COMP_DBG, "Jacken -> pPreviousstats->RxMIMO" + "SignalStrength[rfpath] = %d\n", + prev_st->RxMIMOSignalStrength[rfpath]); + if (priv->stats.rx_rssi_percentage[rfpath] == 0) { + priv->stats.rx_rssi_percentage[rfpath] = + prev_st->RxMIMOSignalStrength[rfpath]; + } + if (prev_st->RxMIMOSignalStrength[rfpath] > + priv->stats.rx_rssi_percentage[rfpath]) { + priv->stats.rx_rssi_percentage[rfpath] = + ((priv->stats.rx_rssi_percentage[rfpath] + * (RX_SMOOTH - 1)) + + (prev_st->RxMIMOSignalStrength + [rfpath])) / (RX_SMOOTH); + priv->stats.rx_rssi_percentage[rfpath] = + priv->stats.rx_rssi_percentage[rfpath] + + 1; + } else { + priv->stats.rx_rssi_percentage[rfpath] = + ((priv->stats.rx_rssi_percentage[rfpath] * + (RX_SMOOTH-1)) + + (prev_st->RxMIMOSignalStrength[rfpath])) / + (RX_SMOOTH); + } + RT_TRACE(COMP_DBG, "Jacken -> priv->RxStats.RxRSSI" + "Percentage[rfPath] = %d\n", + priv->stats.rx_rssi_percentage[rfpath]); + } + } + + + if (prev_st->bPacketBeacon) { + if (slide_beacon_adc_pwdb_statistics++ >= + PHY_Beacon_RSSI_SLID_WIN_MAX) { + slide_beacon_adc_pwdb_statistics = + PHY_Beacon_RSSI_SLID_WIN_MAX; + last_beacon_adc_pwdb = priv->stats.Slide_Beacon_pwdb + [slide_beacon_adc_pwdb_index]; + priv->stats.Slide_Beacon_Total -= last_beacon_adc_pwdb; + } + priv->stats.Slide_Beacon_Total += prev_st->RxPWDBAll; + priv->stats.Slide_Beacon_pwdb[slide_beacon_adc_pwdb_index] = + prev_st->RxPWDBAll; + slide_beacon_adc_pwdb_index++; + if (slide_beacon_adc_pwdb_index >= PHY_Beacon_RSSI_SLID_WIN_MAX) + slide_beacon_adc_pwdb_index = 0; + prev_st->RxPWDBAll = priv->stats.Slide_Beacon_Total / + slide_beacon_adc_pwdb_statistics; + if (prev_st->RxPWDBAll >= 3) + prev_st->RxPWDBAll -= 3; + } + + RT_TRACE(COMP_RXDESC, "Smooth %s PWDB = %d\n", + prev_st->bIsCCK ? "CCK" : "OFDM", + prev_st->RxPWDBAll); + + if (prev_st->bPacketToSelf || prev_st->bPacketBeacon || + prev_st->bToSelfBA) { + if (priv->undecorated_smoothed_pwdb < 0) + priv->undecorated_smoothed_pwdb = prev_st->RxPWDBAll; + if (prev_st->RxPWDBAll > (u32)priv->undecorated_smoothed_pwdb) { + priv->undecorated_smoothed_pwdb = + (((priv->undecorated_smoothed_pwdb) * + (RX_SMOOTH-1)) + + (prev_st->RxPWDBAll)) / (RX_SMOOTH); + priv->undecorated_smoothed_pwdb = + priv->undecorated_smoothed_pwdb + 1; + } else { + priv->undecorated_smoothed_pwdb = + (((priv->undecorated_smoothed_pwdb) * + (RX_SMOOTH-1)) + + (prev_st->RxPWDBAll)) / (RX_SMOOTH); + } + rtl819x_update_rxsignalstatistics8190pci(priv, prev_st); + } + + if (prev_st->SignalQuality != 0) { + if (prev_st->bPacketToSelf || prev_st->bPacketBeacon || + prev_st->bToSelfBA) { + if (slide_evm_statistics++ >= PHY_RSSI_SLID_WIN_MAX) { + slide_evm_statistics = PHY_RSSI_SLID_WIN_MAX; + last_evm = + priv->stats.slide_evm[slide_evm_index]; + priv->stats.slide_evm_total -= last_evm; + } + + priv->stats.slide_evm_total += prev_st->SignalQuality; + + priv->stats.slide_evm[slide_evm_index++] = + prev_st->SignalQuality; + if (slide_evm_index >= PHY_RSSI_SLID_WIN_MAX) + slide_evm_index = 0; + + tmp_val = priv->stats.slide_evm_total / + slide_evm_statistics; + priv->stats.signal_quality = tmp_val; + priv->stats.last_signal_strength_inpercent = tmp_val; + } + + if (prev_st->bPacketToSelf || + prev_st->bPacketBeacon || + prev_st->bToSelfBA) { + for (ij = 0; ij < 2; ij++) { + if (prev_st->RxMIMOSignalQuality[ij] != -1) { + if (priv->stats.rx_evm_percentage[ij] == 0) + priv->stats.rx_evm_percentage[ij] = + prev_st->RxMIMOSignalQuality[ij]; + priv->stats.rx_evm_percentage[ij] = + ((priv->stats.rx_evm_percentage[ij] * + (RX_SMOOTH - 1)) + + (prev_st->RxMIMOSignalQuality[ij])) / + (RX_SMOOTH); + } + } + } + } +} + +static void rtl8192_TranslateRxSignalStuff(struct net_device *dev, + struct sk_buff *skb, + struct rtllib_rx_stats *pstats, + struct rx_desc *pdesc, + struct rx_fwinfo *pdrvinfo) +{ + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + bool bpacket_match_bssid, bpacket_toself; + bool bPacketBeacon = false; + struct rtllib_hdr_3addr *hdr; + bool bToSelfBA = false; + static struct rtllib_rx_stats previous_stats; + u16 fc, type; + u8 *tmp_buf; + u8 *praddr; + + tmp_buf = skb->data + pstats->RxDrvInfoSize + pstats->RxBufShift; + + hdr = (struct rtllib_hdr_3addr *)tmp_buf; + fc = le16_to_cpu(hdr->frame_ctl); + type = WLAN_FC_GET_TYPE(fc); + praddr = hdr->addr1; + + bpacket_match_bssid = ((RTLLIB_FTYPE_CTL != type) && + (!compare_ether_addr(priv->rtllib-> + current_network.bssid, + (fc & RTLLIB_FCTL_TODS) ? hdr->addr1 : + (fc & RTLLIB_FCTL_FROMDS) ? hdr->addr2 : hdr->addr3)) + && (!pstats->bHwError) && (!pstats->bCRC) && (!pstats->bICV)); + bpacket_toself = bpacket_match_bssid && /* check this */ + (!compare_ether_addr(praddr, + priv->rtllib->dev->dev_addr)); + if (WLAN_FC_GET_FRAMETYPE(fc) == RTLLIB_STYPE_BEACON) + bPacketBeacon = true; + if (bpacket_match_bssid) + priv->stats.numpacket_matchbssid++; + if (bpacket_toself) + priv->stats.numpacket_toself++; + rtl8192_process_phyinfo(priv, tmp_buf, &previous_stats, pstats); + rtl8192_query_rxphystatus(priv, pstats, pdesc, pdrvinfo, + &previous_stats, bpacket_match_bssid, + bpacket_toself, bPacketBeacon, bToSelfBA); + rtl8192_record_rxdesc_forlateruse(pstats, &previous_stats); +} + +static void rtl8192_UpdateReceivedRateHistogramStatistics( + struct net_device *dev, + struct rtllib_rx_stats *pstats) +{ + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + u32 rcvType = 1; + u32 rateIndex; + u32 preamble_guardinterval; + + if (pstats->bCRC) + rcvType = 2; + else if (pstats->bICV) + rcvType = 3; + + if (pstats->bShortPreamble) + preamble_guardinterval = 1; + else + preamble_guardinterval = 0; + + switch (pstats->rate) { + case MGN_1M: + rateIndex = 0; + break; + case MGN_2M: + rateIndex = 1; + break; + case MGN_5_5M: + rateIndex = 2; + break; + case MGN_11M: + rateIndex = 3; + break; + case MGN_6M: + rateIndex = 4; + break; + case MGN_9M: + rateIndex = 5; + break; + case MGN_12M: + rateIndex = 6; + break; + case MGN_18M: + rateIndex = 7; + break; + case MGN_24M: + rateIndex = 8; + break; + case MGN_36M: + rateIndex = 9; + break; + case MGN_48M: + rateIndex = 10; + break; + case MGN_54M: + rateIndex = 11; + break; + case MGN_MCS0: + rateIndex = 12; + break; + case MGN_MCS1: + rateIndex = 13; + break; + case MGN_MCS2: + rateIndex = 14; + break; + case MGN_MCS3: + rateIndex = 15; + break; + case MGN_MCS4: + rateIndex = 16; + break; + case MGN_MCS5: + rateIndex = 17; + break; + case MGN_MCS6: + rateIndex = 18; + break; + case MGN_MCS7: + rateIndex = 19; + break; + case MGN_MCS8: + rateIndex = 20; + break; + case MGN_MCS9: + rateIndex = 21; + break; + case MGN_MCS10: + rateIndex = 22; + break; + case MGN_MCS11: + rateIndex = 23; + break; + case MGN_MCS12: + rateIndex = 24; + break; + case MGN_MCS13: + rateIndex = 25; + break; + case MGN_MCS14: + rateIndex = 26; + break; + case MGN_MCS15: + rateIndex = 27; + break; + default: + rateIndex = 28; + break; + } + priv->stats.received_preamble_GI[preamble_guardinterval][rateIndex]++; + priv->stats.received_rate_histogram[0][rateIndex]++; + priv->stats.received_rate_histogram[rcvType][rateIndex]++; +} + +bool rtl8192_rx_query_status_desc(struct net_device *dev, + struct rtllib_rx_stats *stats, + struct rx_desc *pdesc, + struct sk_buff *skb) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + stats->bICV = pdesc->ICV; + stats->bCRC = pdesc->CRC32; + stats->bHwError = pdesc->CRC32 | pdesc->ICV; + + stats->Length = pdesc->Length; + if (stats->Length < 24) + stats->bHwError |= 1; + + if (stats->bHwError) { + stats->bShift = false; + + if (pdesc->CRC32) { + if (pdesc->Length < 500) + priv->stats.rxcrcerrmin++; + else if (pdesc->Length > 1000) + priv->stats.rxcrcerrmax++; + else + priv->stats.rxcrcerrmid++; + } + return false; + } else { + struct rx_fwinfo *pDrvInfo = NULL; + stats->RxDrvInfoSize = pdesc->RxDrvInfoSize; + stats->RxBufShift = ((pdesc->Shift)&0x03); + stats->Decrypted = !pdesc->SWDec; + + pDrvInfo = (struct rx_fwinfo *)(skb->data + stats->RxBufShift); + + stats->rate = HwRateToMRate90((bool)pDrvInfo->RxHT, + (u8)pDrvInfo->RxRate); + stats->bShortPreamble = pDrvInfo->SPLCP; + + rtl8192_UpdateReceivedRateHistogramStatistics(dev, stats); + + stats->bIsAMPDU = (pDrvInfo->PartAggr == 1); + stats->bFirstMPDU = (pDrvInfo->PartAggr == 1) && + (pDrvInfo->FirstAGGR == 1); + + stats->TimeStampLow = pDrvInfo->TSFL; + stats->TimeStampHigh = read_nic_dword(dev, TSFR+4); + + rtl819x_UpdateRxPktTimeStamp(dev, stats); + + if ((stats->RxBufShift + stats->RxDrvInfoSize) > 0) + stats->bShift = 1; + + stats->RxIs40MHzPacket = pDrvInfo->BW; + + rtl8192_TranslateRxSignalStuff(dev, skb, stats, pdesc, + pDrvInfo); + + if (pDrvInfo->FirstAGGR == 1 || pDrvInfo->PartAggr == 1) + RT_TRACE(COMP_RXDESC, "pDrvInfo->FirstAGGR = %d," + " pDrvInfo->PartAggr = %d\n", + pDrvInfo->FirstAGGR, pDrvInfo->PartAggr); + skb_trim(skb, skb->len - 4/*sCrcLng*/); + + + stats->packetlength = stats->Length-4; + stats->fraglength = stats->packetlength; + stats->fragoffset = 0; + stats->ntotalfrag = 1; + return true; + } +} + +void rtl8192_halt_adapter(struct net_device *dev, bool reset) +{ + struct r8192_priv *priv = rtllib_priv(dev); + int i; + u8 OpMode; + u8 u1bTmp; + u32 ulRegRead; + + OpMode = RT_OP_MODE_NO_LINK; + priv->rtllib->SetHwRegHandler(dev, HW_VAR_MEDIA_STATUS, &OpMode); + + if (!priv->rtllib->bSupportRemoteWakeUp) { + u1bTmp = 0x0; + write_nic_byte(dev, CMDR, u1bTmp); + } + + mdelay(20); + + if (!reset) { + mdelay(150); + + priv->bHwRfOffAction = 2; + + if (!priv->rtllib->bSupportRemoteWakeUp) { + PHY_SetRtl8192eRfOff(dev); + ulRegRead = read_nic_dword(dev, CPU_GEN); + ulRegRead |= CPU_GEN_SYSTEM_RESET; + write_nic_dword(dev, CPU_GEN, ulRegRead); + } else { + write_nic_dword(dev, WFCRC0, 0xffffffff); + write_nic_dword(dev, WFCRC1, 0xffffffff); + write_nic_dword(dev, WFCRC2, 0xffffffff); + + + write_nic_byte(dev, PMR, 0x5); + write_nic_byte(dev, MacBlkCtrl, 0xa); + } + } + + for (i = 0; i < MAX_QUEUE_SIZE; i++) + skb_queue_purge(&priv->rtllib->skb_waitQ[i]); + for (i = 0; i < MAX_QUEUE_SIZE; i++) + skb_queue_purge(&priv->rtllib->skb_aggQ[i]); + + skb_queue_purge(&priv->skb_queue); + return; +} + +void rtl8192_update_ratr_table(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + struct rtllib_device *ieee = priv->rtllib; + u8 *pMcsRate = ieee->dot11HTOperationalRateSet; + u32 ratr_value = 0; + u8 rate_index = 0; + + rtl8192_config_rate(dev, (u16 *)(&ratr_value)); + ratr_value |= (*(u16 *)(pMcsRate)) << 12; + switch (ieee->mode) { + case IEEE_A: + ratr_value &= 0x00000FF0; + break; + case IEEE_B: + ratr_value &= 0x0000000F; + break; + case IEEE_G: + case IEEE_G|IEEE_B: + ratr_value &= 0x00000FF7; + break; + case IEEE_N_24G: + case IEEE_N_5G: + if (ieee->pHTInfo->PeerMimoPs == 0) { + ratr_value &= 0x0007F007; + } else { + if (priv->rf_type == RF_1T2R) + ratr_value &= 0x000FF007; + else + ratr_value &= 0x0F81F007; + } + break; + default: + break; + } + ratr_value &= 0x0FFFFFFF; + if (ieee->pHTInfo->bCurTxBW40MHz && + ieee->pHTInfo->bCurShortGI40MHz) + ratr_value |= 0x80000000; + else if (!ieee->pHTInfo->bCurTxBW40MHz && + ieee->pHTInfo->bCurShortGI20MHz) + ratr_value |= 0x80000000; + write_nic_dword(dev, RATR0+rate_index*4, ratr_value); + write_nic_byte(dev, UFWP, 1); +} + +void +rtl8192_InitializeVariables(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + strcpy(priv->nick, "rtl8192E"); + + priv->rtllib->softmac_features = IEEE_SOFTMAC_SCAN | + IEEE_SOFTMAC_ASSOCIATE | IEEE_SOFTMAC_PROBERQ | + IEEE_SOFTMAC_PROBERS | IEEE_SOFTMAC_TX_QUEUE /* | + IEEE_SOFTMAC_BEACONS*/; + + priv->rtllib->tx_headroom = sizeof(struct tx_fwinfo_8190pci); + + priv->ShortRetryLimit = 0x30; + priv->LongRetryLimit = 0x30; + + priv->EarlyRxThreshold = 7; + priv->pwrGroupCnt = 0; + + priv->bIgnoreSilentReset = false; + priv->enable_gpio0 = 0; + + priv->TransmitConfig = 0; + + priv->ReceiveConfig = RCR_ADD3 | + RCR_AMF | RCR_ADF | + RCR_AICV | + RCR_AB | RCR_AM | RCR_APM | + RCR_AAP | ((u32)7<<RCR_MXDMA_OFFSET) | + ((u32)7 << RCR_FIFO_OFFSET) | RCR_ONLYERLPKT; + + priv->irq_mask[0] = (u32)(IMR_ROK | IMR_VODOK | IMR_VIDOK | + IMR_BEDOK | IMR_BKDOK | IMR_HCCADOK | + IMR_MGNTDOK | IMR_COMDOK | IMR_HIGHDOK | + IMR_BDOK | IMR_RXCMDOK | IMR_TIMEOUT0 | + IMR_RDU | IMR_RXFOVW | IMR_TXFOVW | + IMR_BcnInt | IMR_TBDOK | IMR_TBDER); + + + priv->MidHighPwrTHR_L1 = 0x3B; + priv->MidHighPwrTHR_L2 = 0x40; + priv->PwrDomainProtect = false; + + priv->bfirst_after_down = 0; +} + +void rtl8192_EnableInterrupt(struct net_device *dev) +{ + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + priv->irq_enabled = 1; + + write_nic_dword(dev, INTA_MASK, priv->irq_mask[0]); + +} + +void rtl8192_DisableInterrupt(struct net_device *dev) +{ + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + + write_nic_dword(dev, INTA_MASK, 0); + + priv->irq_enabled = 0; +} + +void rtl8192_ClearInterrupt(struct net_device *dev) +{ + u32 tmp = 0; + tmp = read_nic_dword(dev, ISR); + write_nic_dword(dev, ISR, tmp); +} + + +void rtl8192_enable_rx(struct net_device *dev) +{ + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + write_nic_dword(dev, RDQDA, priv->rx_ring_dma[RX_MPDU_QUEUE]); +} + +static const u32 TX_DESC_BASE[] = { + BKQDA, BEQDA, VIQDA, VOQDA, HCCAQDA, CQDA, MQDA, HQDA, BQDA +}; + +void rtl8192_enable_tx(struct net_device *dev) +{ + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + u32 i; + + for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) + write_nic_dword(dev, TX_DESC_BASE[i], priv->tx_ring[i].dma); +} + + +void rtl8192_interrupt_recognized(struct net_device *dev, u32 *p_inta, + u32 *p_intb) +{ + *p_inta = read_nic_dword(dev, ISR); + write_nic_dword(dev, ISR, *p_inta); +} + +bool rtl8192_HalRxCheckStuck(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + u16 RegRxCounter = read_nic_word(dev, 0x130); + bool bStuck = false; + static u8 rx_chk_cnt; + u32 SlotIndex = 0, TotalRxStuckCount = 0; + u8 i; + u8 SilentResetRxSoltNum = 4; + + RT_TRACE(COMP_RESET, "%s(): RegRxCounter is %d, RxCounter is %d\n", + __func__, RegRxCounter, priv->RxCounter); + + rx_chk_cnt++; + if (priv->undecorated_smoothed_pwdb >= (RateAdaptiveTH_High+5)) { + rx_chk_cnt = 0; + } else if ((priv->undecorated_smoothed_pwdb < (RateAdaptiveTH_High + 5)) + && (((priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) && + (priv->undecorated_smoothed_pwdb >= RateAdaptiveTH_Low_40M)) + || ((priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20) && + (priv->undecorated_smoothed_pwdb >= RateAdaptiveTH_Low_20M)))) { + if (rx_chk_cnt < 2) + return bStuck; + else + rx_chk_cnt = 0; + } else if ((((priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) && + (priv->undecorated_smoothed_pwdb < RateAdaptiveTH_Low_40M)) || + ((priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20) && + (priv->undecorated_smoothed_pwdb < RateAdaptiveTH_Low_20M))) && + priv->undecorated_smoothed_pwdb >= VeryLowRSSI) { + if (rx_chk_cnt < 4) + return bStuck; + else + rx_chk_cnt = 0; + } else { + if (rx_chk_cnt < 8) + return bStuck; + else + rx_chk_cnt = 0; + } + + + SlotIndex = (priv->SilentResetRxSlotIndex++)%SilentResetRxSoltNum; + + if (priv->RxCounter == RegRxCounter) { + priv->SilentResetRxStuckEvent[SlotIndex] = 1; + + for (i = 0; i < SilentResetRxSoltNum; i++) + TotalRxStuckCount += priv->SilentResetRxStuckEvent[i]; + + if (TotalRxStuckCount == SilentResetRxSoltNum) { + bStuck = true; + for (i = 0; i < SilentResetRxSoltNum; i++) + TotalRxStuckCount += + priv->SilentResetRxStuckEvent[i]; + } + + + } else { + priv->SilentResetRxStuckEvent[SlotIndex] = 0; + } + + priv->RxCounter = RegRxCounter; + + return bStuck; +} + +bool rtl8192_HalTxCheckStuck(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + bool bStuck = false; + u16 RegTxCounter = read_nic_word(dev, 0x128); + + RT_TRACE(COMP_RESET, "%s():RegTxCounter is %d,TxCounter is %d\n", + __func__, RegTxCounter, priv->TxCounter); + + if (priv->TxCounter == RegTxCounter) + bStuck = true; + + priv->TxCounter = RegTxCounter; + + return bStuck; +} + +bool rtl8192_GetNmodeSupportBySecCfg(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + struct rtllib_device *ieee = priv->rtllib; + if (ieee->rtllib_ap_sec_type && + (ieee->rtllib_ap_sec_type(priv->rtllib)&(SEC_ALG_WEP | + SEC_ALG_TKIP))) { + return false; + } else { + return true; + } +} + +bool rtl8192_GetHalfNmodeSupportByAPs(struct net_device *dev) +{ + bool Reval; + struct r8192_priv *priv = rtllib_priv(dev); + struct rtllib_device *ieee = priv->rtllib; + + if (ieee->bHalfWirelessN24GMode == true) + Reval = true; + else + Reval = false; + + return Reval; +} + +u8 rtl8192_QueryIsShort(u8 TxHT, u8 TxRate, struct cb_desc *tcb_desc) +{ + u8 tmp_Short; + + tmp_Short = (TxHT == 1) ? ((tcb_desc->bUseShortGI) ? 1 : 0) : + ((tcb_desc->bUseShortPreamble) ? 1 : 0); + if (TxHT == 1 && TxRate != DESC90_RATEMCS15) + tmp_Short = 0; + + return tmp_Short; +} + +void +ActUpdateChannelAccessSetting( + struct net_device *dev, + enum wireless_mode WirelessMode, + struct channel_access_setting *ChnlAccessSetting + ) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + return; + + { + u16 SIFS_Timer; + + if (WirelessMode == WIRELESS_MODE_G) + SIFS_Timer = 0x0e0e; + else + SIFS_Timer = priv->SifsTime; + + priv->rtllib->SetHwRegHandler(dev, HW_VAR_SIFS, + (u8 *)&SIFS_Timer); + } + +} diff --git a/drivers/staging/rtl8192e/r8192E_dev.h b/drivers/staging/rtl8192e/r8192E_dev.h new file mode 100644 index 0000000..b9b3b52 --- /dev/null +++ b/drivers/staging/rtl8192e/r8192E_dev.h @@ -0,0 +1,62 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * Based on the r8180 driver, which is: + * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al. + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> +******************************************************************************/ +#ifndef _RTL8192E_H +#define _RTL8192E_H + +#include "r8190P_def.h" + +u8 rtl8192_QueryIsShort(u8 TxHT, u8 TxRate, struct cb_desc *tcb_desc); +bool rtl8192_GetHalfNmodeSupportByAPs(struct net_device *dev); +bool rtl8192_GetNmodeSupportBySecCfg(struct net_device *dev); +bool rtl8192_HalTxCheckStuck(struct net_device *dev); +bool rtl8192_HalRxCheckStuck(struct net_device *dev); +void rtl8192_interrupt_recognized(struct net_device *dev, u32 *p_inta, + u32 *p_intb); +void rtl8192_enable_rx(struct net_device *dev); +void rtl8192_enable_tx(struct net_device *dev); +void rtl8192_EnableInterrupt(struct net_device *dev); +void rtl8192_DisableInterrupt(struct net_device *dev); +void rtl8192_ClearInterrupt(struct net_device *dev); +void rtl8192_InitializeVariables(struct net_device *dev); +void rtl8192e_start_beacon(struct net_device *dev); +void rtl8192e_SetHwReg(struct net_device *dev, u8 variable, u8 *val); +void rtl8192_get_eeprom_size(struct net_device *dev); +bool rtl8192_adapter_start(struct net_device *dev); +void rtl8192_link_change(struct net_device *dev); +void rtl8192_AllowAllDestAddr(struct net_device *dev, bool bAllowAllDA, + bool WriteIntoReg); +void rtl8192_tx_fill_desc(struct net_device *dev, struct tx_desc *pdesc, + struct cb_desc *cb_desc, + struct sk_buff *skb); +void rtl8192_tx_fill_cmd_desc(struct net_device *dev, + struct tx_desc_cmd *entry, + struct cb_desc *cb_desc, struct sk_buff *skb); +bool rtl8192_rx_query_status_desc(struct net_device *dev, + struct rtllib_rx_stats *stats, + struct rx_desc *pdesc, + struct sk_buff *skb); +void rtl8192_halt_adapter(struct net_device *dev, bool reset); +void rtl8192_update_ratr_table(struct net_device *dev); +#endif diff --git a/drivers/staging/rtl8192e/r8192E_dm.c b/drivers/staging/rtl8192e/r8192E_dm.c deleted file mode 100644 index 688d29b..0000000 --- a/drivers/staging/rtl8192e/r8192E_dm.c +++ /dev/null @@ -1,2554 +0,0 @@ -/*++ -Copyright-c Realtek Semiconductor Corp. All rights reserved. - -Module Name: - r8192U_dm.c - -Abstract: - HW dynamic mechanism. - -Major Change History: - When Who What - ---------- --------------- ------------------------------- - 2008-05-14 amy create version 0 porting from windows code. - ---*/ -#include "r8192E.h" -#include "r8192E_dm.h" -#include "r8192E_hw.h" -#include "r819xE_phy.h" -#include "r819xE_phyreg.h" -#include "r8190_rtl8256.h" - -#define DRV_NAME "rtl819xE" - -// -// Indicate different AP vendor for IOT issue. -// -static const u32 edca_setting_DL[HT_IOT_PEER_MAX] = -{ 0x5e4322, 0x5e4322, 0x5e4322, 0x604322, 0xa44f, 0x5e4322, 0x5e4322}; -static const u32 edca_setting_UL[HT_IOT_PEER_MAX] = -{ 0x5e4322, 0xa44f, 0x5e4322, 0x604322, 0x5e4322, 0x5e4322, 0x5e4322}; - -#define RTK_UL_EDCA 0xa44f -#define RTK_DL_EDCA 0x5e4322 - - -dig_t dm_digtable; -// For Dynamic Rx Path Selection by Signal Strength -DRxPathSel DM_RxPathSelTable; - -void dm_gpio_change_rf_callback(struct work_struct *work); - -// DM --> Rate Adaptive -static void dm_check_rate_adaptive(struct r8192_priv *priv); - -// DM --> Bandwidth switch -static void dm_init_bandwidth_autoswitch(struct r8192_priv *priv); -static void dm_bandwidth_autoswitch(struct r8192_priv *priv); - -// DM --> TX power control -static void dm_check_txpower_tracking(struct r8192_priv *priv); - -// DM --> Dynamic Init Gain by RSSI -static void dm_dig_init(struct r8192_priv *priv); -static void dm_ctrl_initgain_byrssi(struct r8192_priv *priv); -static void dm_ctrl_initgain_byrssi_highpwr(struct r8192_priv *priv); -static void dm_ctrl_initgain_byrssi_by_driverrssi(struct r8192_priv *priv); -static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(struct r8192_priv *priv); -static void dm_initial_gain(struct r8192_priv *priv); -static void dm_pd_th(struct r8192_priv *priv); -static void dm_cs_ratio(struct r8192_priv *priv); - -static void dm_init_ctstoself(struct r8192_priv *priv); -// DM --> EDCA turboe mode control -static void dm_check_edca_turbo(struct r8192_priv *priv); -static void dm_init_edca_turbo(struct r8192_priv *priv); - -// DM --> HW RF control -static void dm_check_rfctrl_gpio(struct r8192_priv *priv); - -// DM --> Check current RX RF path state -static void dm_check_rx_path_selection(struct r8192_priv *priv); -static void dm_init_rxpath_selection(struct r8192_priv *priv); -static void dm_rxpath_sel_byrssi(struct r8192_priv *priv); - -// DM --> Fsync for broadcom ap -static void dm_init_fsync(struct r8192_priv *priv); -static void dm_deInit_fsync(struct r8192_priv *priv); - -static void dm_check_txrateandretrycount(struct r8192_priv *priv); -static void dm_check_fsync(struct r8192_priv *priv); - - -/*---------------------Define of Tx Power Control For Near/Far Range --------*/ //Add by Jacken 2008/02/18 -static void dm_init_dynamic_txpower(struct r8192_priv *priv); -static void dm_dynamic_txpower(struct r8192_priv *priv); - -// DM --> For rate adaptive and DIG, we must send RSSI to firmware -static void dm_send_rssi_tofw(struct r8192_priv *priv); -static void dm_ctstoself(struct r8192_priv *priv); - -static void dm_fsync_timer_callback(unsigned long data); - -/* - * Prepare SW resource for HW dynamic mechanism. - * This function is only invoked at driver intialization once. - */ -void init_hal_dm(struct r8192_priv *priv) -{ - // Undecorated Smoothed Signal Strength, it can utilized to dynamic mechanism. - priv->undecorated_smoothed_pwdb = -1; - - //Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code. - dm_init_dynamic_txpower(priv); - init_rate_adaptive(priv); - //dm_initialize_txpower_tracking(dev); - dm_dig_init(priv); - dm_init_edca_turbo(priv); - dm_init_bandwidth_autoswitch(priv); - dm_init_fsync(priv); - dm_init_rxpath_selection(priv); - dm_init_ctstoself(priv); - INIT_DELAYED_WORK(&priv->gpio_change_rf_wq, dm_gpio_change_rf_callback); - -} - -void deinit_hal_dm(struct r8192_priv *priv) -{ - dm_deInit_fsync(priv); -} - -void hal_dm_watchdog(struct r8192_priv *priv) -{ - - /*Add by amy 2008/05/15 ,porting from windows code.*/ - dm_check_rate_adaptive(priv); - dm_dynamic_txpower(priv); - dm_check_txrateandretrycount(priv); - - dm_check_txpower_tracking(priv); - - dm_ctrl_initgain_byrssi(priv); - dm_check_edca_turbo(priv); - dm_bandwidth_autoswitch(priv); - - dm_check_rfctrl_gpio(priv); - dm_check_rx_path_selection(priv); - dm_check_fsync(priv); - - // Add by amy 2008-05-15 porting from windows code. - dm_send_rssi_tofw(priv); - dm_ctstoself(priv); -} - - -/* - * Decide Rate Adaptive Set according to distance (signal strength) - * 01/11/2008 MHC Modify input arguments and RATR table level. - * 01/16/2008 MHC RF_Type is assigned in ReadAdapterInfo(). We must call - * the function after making sure RF_Type. - */ -void init_rate_adaptive(struct r8192_priv *priv) -{ - prate_adaptive pra = &priv->rate_adaptive; - - pra->ratr_state = DM_RATR_STA_MAX; - pra->high2low_rssi_thresh_for_ra = RateAdaptiveTH_High; - pra->low2high_rssi_thresh_for_ra20M = RateAdaptiveTH_Low_20M+5; - pra->low2high_rssi_thresh_for_ra40M = RateAdaptiveTH_Low_40M+5; - - pra->high_rssi_thresh_for_ra = RateAdaptiveTH_High+5; - pra->low_rssi_thresh_for_ra20M = RateAdaptiveTH_Low_20M; - pra->low_rssi_thresh_for_ra40M = RateAdaptiveTH_Low_40M; - - if(priv->CustomerID == RT_CID_819x_Netcore) - pra->ping_rssi_enable = 1; - else - pra->ping_rssi_enable = 0; - pra->ping_rssi_thresh_for_ra = 15; - - - if (priv->rf_type == RF_2T4R) - { - // 07/10/08 MH Modify for RA smooth scheme. - /* 2008/01/11 MH Modify 2T RATR table for different RSSI. 080515 porting by amy from windows code.*/ - pra->upper_rssi_threshold_ratr = 0x8f0f0000; - pra->middle_rssi_threshold_ratr = 0x8f0ff000; - pra->low_rssi_threshold_ratr = 0x8f0ff001; - pra->low_rssi_threshold_ratr_40M = 0x8f0ff005; - pra->low_rssi_threshold_ratr_20M = 0x8f0ff001; - pra->ping_rssi_ratr = 0x0000000d;//cosa add for test - } - else if (priv->rf_type == RF_1T2R) - { - pra->upper_rssi_threshold_ratr = 0x000f0000; - pra->middle_rssi_threshold_ratr = 0x000ff000; - pra->low_rssi_threshold_ratr = 0x000ff001; - pra->low_rssi_threshold_ratr_40M = 0x000ff005; - pra->low_rssi_threshold_ratr_20M = 0x000ff001; - pra->ping_rssi_ratr = 0x0000000d;//cosa add for test - } - -} - - -static void dm_check_rate_adaptive(struct r8192_priv *priv) -{ - PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo; - prate_adaptive pra = (prate_adaptive)&priv->rate_adaptive; - u32 currentRATR, targetRATR = 0; - u32 LowRSSIThreshForRA = 0, HighRSSIThreshForRA = 0; - bool bshort_gi_enabled = false; - static u8 ping_rssi_state=0; - - - if(!priv->up) - { - RT_TRACE(COMP_RATE, "<---- dm_check_rate_adaptive(): driver is going to unload\n"); - return; - } - - if(pra->rate_adaptive_disabled)//this variable is set by ioctl. - return; - - // TODO: Only 11n mode is implemented currently, - if( !(priv->ieee80211->mode == WIRELESS_MODE_N_24G || - priv->ieee80211->mode == WIRELESS_MODE_N_5G)) - return; - - if( priv->ieee80211->state == IEEE80211_LINKED ) - { - // RT_TRACE(COMP_RATE, "dm_CheckRateAdaptive(): \t"); - - // - // Check whether Short GI is enabled - // - bshort_gi_enabled = (pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI40MHz) || - (!pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI20MHz); - - - pra->upper_rssi_threshold_ratr = - (pra->upper_rssi_threshold_ratr & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ; - - pra->middle_rssi_threshold_ratr = - (pra->middle_rssi_threshold_ratr & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ; - - if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) - { - pra->low_rssi_threshold_ratr = - (pra->low_rssi_threshold_ratr_40M & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ; - } - else - { - pra->low_rssi_threshold_ratr = - (pra->low_rssi_threshold_ratr_20M & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ; - } - //cosa add for test - pra->ping_rssi_ratr = - (pra->ping_rssi_ratr & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ; - - /* 2007/10/08 MH We support RA smooth scheme now. When it is the first - time to link with AP. We will not change upper/lower threshold. If - STA stay in high or low level, we must change two different threshold - to prevent jumping frequently. */ - if (pra->ratr_state == DM_RATR_STA_HIGH) - { - HighRSSIThreshForRA = pra->high2low_rssi_thresh_for_ra; - LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)? - (pra->low_rssi_thresh_for_ra40M):(pra->low_rssi_thresh_for_ra20M); - } - else if (pra->ratr_state == DM_RATR_STA_LOW) - { - HighRSSIThreshForRA = pra->high_rssi_thresh_for_ra; - LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)? - (pra->low2high_rssi_thresh_for_ra40M):(pra->low2high_rssi_thresh_for_ra20M); - } - else - { - HighRSSIThreshForRA = pra->high_rssi_thresh_for_ra; - LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)? - (pra->low_rssi_thresh_for_ra40M):(pra->low_rssi_thresh_for_ra20M); - } - - if(priv->undecorated_smoothed_pwdb >= (long)HighRSSIThreshForRA) - { - pra->ratr_state = DM_RATR_STA_HIGH; - targetRATR = pra->upper_rssi_threshold_ratr; - }else if(priv->undecorated_smoothed_pwdb >= (long)LowRSSIThreshForRA) - { - pra->ratr_state = DM_RATR_STA_MIDDLE; - targetRATR = pra->middle_rssi_threshold_ratr; - }else - { - pra->ratr_state = DM_RATR_STA_LOW; - targetRATR = pra->low_rssi_threshold_ratr; - } - - //cosa add for test - if(pra->ping_rssi_enable) - { - //pHalData->UndecoratedSmoothedPWDB = 19; - if(priv->undecorated_smoothed_pwdb < (long)(pra->ping_rssi_thresh_for_ra+5)) - { - if( (priv->undecorated_smoothed_pwdb < (long)pra->ping_rssi_thresh_for_ra) || - ping_rssi_state ) - { - pra->ratr_state = DM_RATR_STA_LOW; - targetRATR = pra->ping_rssi_ratr; - ping_rssi_state = 1; - } - } - else - { - ping_rssi_state = 0; - } - } - - // For RTL819X, if pairwisekey = wep/tkip, we support only MCS0~7. - if(priv->ieee80211->GetHalfNmodeSupportByAPsHandler(priv->ieee80211)) - targetRATR &= 0xf00fffff; - - // - // Check whether updating of RATR0 is required - // - currentRATR = read_nic_dword(priv, RATR0); - if( targetRATR != currentRATR ) - { - u32 ratr_value; - ratr_value = targetRATR; - RT_TRACE(COMP_RATE,"currentRATR = %x, targetRATR = %x\n", currentRATR, targetRATR); - if(priv->rf_type == RF_1T2R) - { - ratr_value &= ~(RATE_ALL_OFDM_2SS); - } - write_nic_dword(priv, RATR0, ratr_value); - write_nic_byte(priv, UFWP, 1); - - pra->last_ratr = targetRATR; - } - - } - else - { - pra->ratr_state = DM_RATR_STA_MAX; - } - -} - - -static void dm_init_bandwidth_autoswitch(struct r8192_priv *priv) -{ - priv->ieee80211->bandwidth_auto_switch.threshold_20Mhzto40Mhz = BW_AUTO_SWITCH_LOW_HIGH; - priv->ieee80211->bandwidth_auto_switch.threshold_40Mhzto20Mhz = BW_AUTO_SWITCH_HIGH_LOW; - priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = false; - priv->ieee80211->bandwidth_auto_switch.bautoswitch_enable = false; - -} - - -static void dm_bandwidth_autoswitch(struct r8192_priv *priv) -{ - if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 ||!priv->ieee80211->bandwidth_auto_switch.bautoswitch_enable){ - return; - }else{ - if(priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz == false){//If send packets in 40 Mhz in 20/40 - if(priv->undecorated_smoothed_pwdb <= priv->ieee80211->bandwidth_auto_switch.threshold_40Mhzto20Mhz) - priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = true; - }else{//in force send packets in 20 Mhz in 20/40 - if(priv->undecorated_smoothed_pwdb >= priv->ieee80211->bandwidth_auto_switch.threshold_20Mhzto40Mhz) - priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = false; - - } - } -} - -//OFDM default at 0db, index=6. -static const u32 OFDMSwingTable[OFDM_Table_Length] = { - 0x7f8001fe, // 0, +6db - 0x71c001c7, // 1, +5db - 0x65400195, // 2, +4db - 0x5a400169, // 3, +3db - 0x50800142, // 4, +2db - 0x47c0011f, // 5, +1db - 0x40000100, // 6, +0db ===> default, upper for higher temperature, lower for low temperature - 0x390000e4, // 7, -1db - 0x32c000cb, // 8, -2db - 0x2d4000b5, // 9, -3db - 0x288000a2, // 10, -4db - 0x24000090, // 11, -5db - 0x20000080, // 12, -6db - 0x1c800072, // 13, -7db - 0x19800066, // 14, -8db - 0x26c0005b, // 15, -9db - 0x24400051, // 16, -10db - 0x12000048, // 17, -11db - 0x10000040 // 18, -12db -}; -static const u8 CCKSwingTable_Ch1_Ch13[CCK_Table_length][8] = { - {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, // 0, +0db ===> CCK40M default - {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, // 1, -1db - {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, // 2, -2db - {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, // 3, -3db - {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, // 4, -4db - {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, // 5, -5db - {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, // 6, -6db ===> CCK20M default - {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, // 7, -7db - {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, // 8, -8db - {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, // 9, -9db - {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, // 10, -10db - {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01} // 11, -11db -}; - -static const u8 CCKSwingTable_Ch14[CCK_Table_length][8] = { - {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, // 0, +0db ===> CCK40M default - {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, // 1, -1db - {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, // 2, -2db - {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, // 3, -3db - {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, // 4, -4db - {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, // 5, -5db - {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, // 6, -6db ===> CCK20M default - {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, // 7, -7db - {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, // 8, -8db - {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, // 9, -9db - {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, // 10, -10db - {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00} // 11, -11db -}; - -#define Pw_Track_Flag 0x11d -#define Tssi_Mea_Value 0x13c -#define Tssi_Report_Value1 0x134 -#define Tssi_Report_Value2 0x13e -#define FW_Busy_Flag 0x13f -static void dm_TXPowerTrackingCallback_TSSI(struct r8192_priv *priv) -{ - bool bHighpowerstate, viviflag = FALSE; - DCMD_TXCMD_T tx_cmd; - u8 powerlevelOFDM24G; - int i =0, j = 0, k = 0; - u8 RF_Type, tmp_report[5]={0, 0, 0, 0, 0}; - u32 Value; - u8 Pwr_Flag; - u16 Avg_TSSI_Meas, TSSI_13dBm, Avg_TSSI_Meas_from_driver=0; -// bool rtStatus = true; - u32 delta=0; - RT_TRACE(COMP_POWER_TRACKING,"%s()\n",__FUNCTION__); -// write_nic_byte(priv, 0x1ba, 0); - write_nic_byte(priv, Pw_Track_Flag, 0); - write_nic_byte(priv, FW_Busy_Flag, 0); - priv->ieee80211->bdynamic_txpower_enable = false; - bHighpowerstate = priv->bDynamicTxHighPower; - - powerlevelOFDM24G = (u8)(priv->Pwr_Track>>24); - RF_Type = priv->rf_type; - Value = (RF_Type<<8) | powerlevelOFDM24G; - - RT_TRACE(COMP_POWER_TRACKING, "powerlevelOFDM24G = %x\n", powerlevelOFDM24G); - - for(j = 0; j<=30; j++) -{ //fill tx_cmd - - tx_cmd.Op = TXCMD_SET_TX_PWR_TRACKING; - tx_cmd.Length = 4; - tx_cmd.Value = Value; - cmpk_message_handle_tx(priv, (u8*)&tx_cmd, DESC_PACKET_TYPE_INIT, sizeof(DCMD_TXCMD_T)); - mdelay(1); - - for(i = 0;i <= 30; i++) - { - Pwr_Flag = read_nic_byte(priv, Pw_Track_Flag); - - if (Pwr_Flag == 0) - { - mdelay(1); - continue; - } - - Avg_TSSI_Meas = read_nic_word(priv, Tssi_Mea_Value); - - if(Avg_TSSI_Meas == 0) - { - write_nic_byte(priv, Pw_Track_Flag, 0); - write_nic_byte(priv, FW_Busy_Flag, 0); - return; - } - - for(k = 0;k < 5; k++) - { - if(k !=4) - tmp_report[k] = read_nic_byte(priv, Tssi_Report_Value1+k); - else - tmp_report[k] = read_nic_byte(priv, Tssi_Report_Value2); - - RT_TRACE(COMP_POWER_TRACKING, "TSSI_report_value = %d\n", tmp_report[k]); - } - - //check if the report value is right - for(k = 0;k < 5; k++) - { - if(tmp_report[k] <= 20) - { - viviflag =TRUE; - break; - } - } - if(viviflag ==TRUE) - { - write_nic_byte(priv, Pw_Track_Flag, 0); - viviflag = FALSE; - RT_TRACE(COMP_POWER_TRACKING, "we filted this data\n"); - for(k = 0;k < 5; k++) - tmp_report[k] = 0; - break; - } - - for(k = 0;k < 5; k++) - { - Avg_TSSI_Meas_from_driver += tmp_report[k]; - } - - Avg_TSSI_Meas_from_driver = Avg_TSSI_Meas_from_driver*100/5; - RT_TRACE(COMP_POWER_TRACKING, "Avg_TSSI_Meas_from_driver = %d\n", Avg_TSSI_Meas_from_driver); - TSSI_13dBm = priv->TSSI_13dBm; - RT_TRACE(COMP_POWER_TRACKING, "TSSI_13dBm = %d\n", TSSI_13dBm); - - //if(abs(Avg_TSSI_Meas_from_driver - TSSI_13dBm) <= E_FOR_TX_POWER_TRACK) - // For MacOS-compatible - if(Avg_TSSI_Meas_from_driver > TSSI_13dBm) - delta = Avg_TSSI_Meas_from_driver - TSSI_13dBm; - else - delta = TSSI_13dBm - Avg_TSSI_Meas_from_driver; - - if(delta <= E_FOR_TX_POWER_TRACK) - { - priv->ieee80211->bdynamic_txpower_enable = TRUE; - write_nic_byte(priv, Pw_Track_Flag, 0); - write_nic_byte(priv, FW_Busy_Flag, 0); - RT_TRACE(COMP_POWER_TRACKING, "tx power track is done\n"); - RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex); - RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real); - RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference = %d\n", priv->CCKPresentAttentuation_difference); - RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation = %d\n", priv->CCKPresentAttentuation); - return; - } - else - { - if(Avg_TSSI_Meas_from_driver < TSSI_13dBm - E_FOR_TX_POWER_TRACK) - { - if (RF_Type == RF_2T4R) - { - - if((priv->rfa_txpowertrackingindex > 0) &&(priv->rfc_txpowertrackingindex > 0)) - { - priv->rfa_txpowertrackingindex--; - if(priv->rfa_txpowertrackingindex_real > 4) - { - priv->rfa_txpowertrackingindex_real--; - rtl8192_setBBreg(priv, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value); - } - - priv->rfc_txpowertrackingindex--; - if(priv->rfc_txpowertrackingindex_real > 4) - { - priv->rfc_txpowertrackingindex_real--; - rtl8192_setBBreg(priv, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value); - } - } - else - { - rtl8192_setBBreg(priv, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[4].txbbgain_value); - rtl8192_setBBreg(priv, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[4].txbbgain_value); - } - } - else - { - if(priv->rfc_txpowertrackingindex > 0) - { - priv->rfc_txpowertrackingindex--; - if(priv->rfc_txpowertrackingindex_real > 4) - { - priv->rfc_txpowertrackingindex_real--; - rtl8192_setBBreg(priv, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value); - } - } - else - rtl8192_setBBreg(priv, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[4].txbbgain_value); - } - } - else - { - if (RF_Type == RF_2T4R) - { - if((priv->rfa_txpowertrackingindex < TxBBGainTableLength - 1) &&(priv->rfc_txpowertrackingindex < TxBBGainTableLength - 1)) - { - priv->rfa_txpowertrackingindex++; - priv->rfa_txpowertrackingindex_real++; - rtl8192_setBBreg(priv, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value); - priv->rfc_txpowertrackingindex++; - priv->rfc_txpowertrackingindex_real++; - rtl8192_setBBreg(priv, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value); - } - else - { - rtl8192_setBBreg(priv, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[TxBBGainTableLength - 1].txbbgain_value); - rtl8192_setBBreg(priv, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[TxBBGainTableLength - 1].txbbgain_value); - } - } - else - { - if(priv->rfc_txpowertrackingindex < (TxBBGainTableLength - 1)) - { - priv->rfc_txpowertrackingindex++; - priv->rfc_txpowertrackingindex_real++; - rtl8192_setBBreg(priv, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value); - } - else - rtl8192_setBBreg(priv, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[TxBBGainTableLength - 1].txbbgain_value); - } - } - if (RF_Type == RF_2T4R) - priv->CCKPresentAttentuation_difference - = priv->rfa_txpowertrackingindex - priv->rfa_txpowertracking_default; - else - priv->CCKPresentAttentuation_difference - = priv->rfc_txpowertrackingindex - priv->rfc_txpowertracking_default; - - if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20) - priv->CCKPresentAttentuation - = priv->CCKPresentAttentuation_20Mdefault + priv->CCKPresentAttentuation_difference; - else - priv->CCKPresentAttentuation - = priv->CCKPresentAttentuation_40Mdefault + priv->CCKPresentAttentuation_difference; - - if(priv->CCKPresentAttentuation > (CCKTxBBGainTableLength-1)) - priv->CCKPresentAttentuation = CCKTxBBGainTableLength-1; - if(priv->CCKPresentAttentuation < 0) - priv->CCKPresentAttentuation = 0; - - if(1) - { - if(priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14) - { - priv->bcck_in_ch14 = TRUE; - dm_cck_txpower_adjust(priv, priv->bcck_in_ch14); - } - else if(priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14) - { - priv->bcck_in_ch14 = FALSE; - dm_cck_txpower_adjust(priv, priv->bcck_in_ch14); - } - else - dm_cck_txpower_adjust(priv, priv->bcck_in_ch14); - } - RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex); - RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real); - RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference = %d\n", priv->CCKPresentAttentuation_difference); - RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation = %d\n", priv->CCKPresentAttentuation); - - if (priv->CCKPresentAttentuation_difference <= -12||priv->CCKPresentAttentuation_difference >= 24) - { - priv->ieee80211->bdynamic_txpower_enable = TRUE; - write_nic_byte(priv, Pw_Track_Flag, 0); - write_nic_byte(priv, FW_Busy_Flag, 0); - RT_TRACE(COMP_POWER_TRACKING, "tx power track--->limited\n"); - return; - } - - - } - write_nic_byte(priv, Pw_Track_Flag, 0); - Avg_TSSI_Meas_from_driver = 0; - for(k = 0;k < 5; k++) - tmp_report[k] = 0; - break; - } - write_nic_byte(priv, FW_Busy_Flag, 0); -} - priv->ieee80211->bdynamic_txpower_enable = TRUE; - write_nic_byte(priv, Pw_Track_Flag, 0); -} - -static void dm_TXPowerTrackingCallback_ThermalMeter(struct r8192_priv *priv) -{ -#define ThermalMeterVal 9 - u32 tmpRegA, TempCCk; - u8 tmpOFDMindex, tmpCCKindex, tmpCCK20Mindex, tmpCCK40Mindex, tmpval; - int i =0, CCKSwingNeedUpdate=0; - - if(!priv->btxpower_trackingInit) - { - //Query OFDM default setting - tmpRegA = rtl8192_QueryBBReg(priv, rOFDM0_XATxIQImbalance, bMaskDWord); - for(i=0; i<OFDM_Table_Length; i++) //find the index - { - if(tmpRegA == OFDMSwingTable[i]) - { - priv->OFDM_index= (u8)i; - RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x = 0x%x, OFDM_index=0x%x\n", - rOFDM0_XATxIQImbalance, tmpRegA, priv->OFDM_index); - } - } - - //Query CCK default setting From 0xa22 - TempCCk = rtl8192_QueryBBReg(priv, rCCK0_TxFilter1, bMaskByte2); - for(i=0 ; i<CCK_Table_length ; i++) - { - if(TempCCk == (u32)CCKSwingTable_Ch1_Ch13[i][0]) - { - priv->CCK_index =(u8) i; - RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x = 0x%x, CCK_index=0x%x\n", - rCCK0_TxFilter1, TempCCk, priv->CCK_index); - break; - } - } - priv->btxpower_trackingInit = TRUE; - //pHalData->TXPowercount = 0; - return; - } - - // read and filter out unreasonable value - tmpRegA = rtl8192_phy_QueryRFReg(priv, RF90_PATH_A, 0x12, 0x078); // 0x12: RF Reg[10:7] - RT_TRACE(COMP_POWER_TRACKING, "Readback ThermalMeterA = %d\n", tmpRegA); - if(tmpRegA < 3 || tmpRegA > 13) - return; - if(tmpRegA >= 12) // if over 12, TP will be bad when high temperature - tmpRegA = 12; - RT_TRACE(COMP_POWER_TRACKING, "Valid ThermalMeterA = %d\n", tmpRegA); - priv->ThermalMeter[0] = ThermalMeterVal; //We use fixed value by Bryant's suggestion - priv->ThermalMeter[1] = ThermalMeterVal; //We use fixed value by Bryant's suggestion - - //Get current RF-A temperature index - if(priv->ThermalMeter[0] >= (u8)tmpRegA) //lower temperature - { - tmpOFDMindex = tmpCCK20Mindex = 6+(priv->ThermalMeter[0]-(u8)tmpRegA); - tmpCCK40Mindex = tmpCCK20Mindex - 6; - if(tmpOFDMindex >= OFDM_Table_Length) - tmpOFDMindex = OFDM_Table_Length-1; - if(tmpCCK20Mindex >= CCK_Table_length) - tmpCCK20Mindex = CCK_Table_length-1; - if(tmpCCK40Mindex >= CCK_Table_length) - tmpCCK40Mindex = CCK_Table_length-1; - } - else - { - tmpval = ((u8)tmpRegA - priv->ThermalMeter[0]); - if(tmpval >= 6) // higher temperature - tmpOFDMindex = tmpCCK20Mindex = 0; // max to +6dB - else - tmpOFDMindex = tmpCCK20Mindex = 6 - tmpval; - tmpCCK40Mindex = 0; - } - - if(priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) //40M - tmpCCKindex = tmpCCK40Mindex; - else - tmpCCKindex = tmpCCK20Mindex; - - //record for bandwidth swith - priv->Record_CCK_20Mindex = tmpCCK20Mindex; - priv->Record_CCK_40Mindex = tmpCCK40Mindex; - RT_TRACE(COMP_POWER_TRACKING, "Record_CCK_20Mindex / Record_CCK_40Mindex = %d / %d.\n", - priv->Record_CCK_20Mindex, priv->Record_CCK_40Mindex); - - if(priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14) - { - priv->bcck_in_ch14 = TRUE; - CCKSwingNeedUpdate = 1; - } - else if(priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14) - { - priv->bcck_in_ch14 = FALSE; - CCKSwingNeedUpdate = 1; - } - - if(priv->CCK_index != tmpCCKindex) -{ - priv->CCK_index = tmpCCKindex; - CCKSwingNeedUpdate = 1; - } - - if(CCKSwingNeedUpdate) - { - dm_cck_txpower_adjust(priv, priv->bcck_in_ch14); - } - if(priv->OFDM_index != tmpOFDMindex) - { - priv->OFDM_index = tmpOFDMindex; - rtl8192_setBBreg(priv, rOFDM0_XATxIQImbalance, bMaskDWord, OFDMSwingTable[priv->OFDM_index]); - RT_TRACE(COMP_POWER_TRACKING, "Update OFDMSwing[%d] = 0x%x\n", - priv->OFDM_index, OFDMSwingTable[priv->OFDM_index]); - } - priv->txpower_count = 0; -} - -void dm_txpower_trackingcallback(struct work_struct *work) -{ - struct delayed_work *dwork = container_of(work,struct delayed_work,work); - struct r8192_priv *priv = container_of(dwork,struct r8192_priv,txpower_tracking_wq); - - if(priv->IC_Cut >= IC_VersionCut_D) - dm_TXPowerTrackingCallback_TSSI(priv); - else - dm_TXPowerTrackingCallback_ThermalMeter(priv); -} - - -static const txbbgain_struct rtl8192_txbbgain_table[] = { - { 12, 0x7f8001fe }, - { 11, 0x788001e2 }, - { 10, 0x71c001c7 }, - { 9, 0x6b8001ae }, - { 8, 0x65400195 }, - { 7, 0x5fc0017f }, - { 6, 0x5a400169 }, - { 5, 0x55400155 }, - { 4, 0x50800142 }, - { 3, 0x4c000130 }, - { 2, 0x47c0011f }, - { 1, 0x43c0010f }, - { 0, 0x40000100 }, - { -1, 0x3c8000f2 }, - { -2, 0x390000e4 }, - { -3, 0x35c000d7 }, - { -4, 0x32c000cb }, - { -5, 0x300000c0 }, - { -6, 0x2d4000b5 }, - { -7, 0x2ac000ab }, - { -8, 0x288000a2 }, - { -9, 0x26000098 }, - { -10, 0x24000090 }, - { -11, 0x22000088 }, - { -12, 0x20000080 }, - { -13, 0x1a00006c }, - { -14, 0x1c800072 }, - { -15, 0x18000060 }, - { -16, 0x19800066 }, - { -17, 0x15800056 }, - { -18, 0x26c0005b }, - { -19, 0x14400051 }, - { -20, 0x24400051 }, - { -21, 0x1300004c }, - { -22, 0x12000048 }, - { -23, 0x11000044 }, - { -24, 0x10000040 }, -}; - -/* - * ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29 - * This Table is for CH1~CH13 - */ -static const ccktxbbgain_struct rtl8192_cck_txbbgain_table[] = { - {{ 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04 }}, - {{ 0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04 }}, - {{ 0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03 }}, - {{ 0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03 }}, - {{ 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03 }}, - {{ 0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03 }}, - {{ 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03 }}, - {{ 0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03 }}, - {{ 0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02 }}, - {{ 0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02 }}, - {{ 0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02 }}, - {{ 0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02 }}, - {{ 0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02 }}, - {{ 0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02 }}, - {{ 0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02 }}, - {{ 0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02 }}, - {{ 0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01 }}, - {{ 0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02 }}, - {{ 0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01 }}, - {{ 0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01 }}, - {{ 0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01 }}, - {{ 0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01 }}, - {{ 0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01 }}, -}; - -/* - * ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29 - * This Table is for CH14 - */ -static const ccktxbbgain_struct rtl8192_cck_txbbgain_ch14_table[] = { - {{ 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00 }}, - {{ 0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00 }}, - {{ 0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00 }}, - {{ 0x2d, 0x2d, 0x27, 0x17, 0x00, 0x00, 0x00, 0x00 }}, - {{ 0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00 }}, - {{ 0x28, 0x28, 0x22, 0x14, 0x00, 0x00, 0x00, 0x00 }}, - {{ 0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00 }}, - {{ 0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00 }}, - {{ 0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00 }}, - {{ 0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00 }}, - {{ 0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00 }}, - {{ 0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00 }}, - {{ 0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00 }}, - {{ 0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00 }}, - {{ 0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00 }}, - {{ 0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00 }}, - {{ 0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00 }}, - {{ 0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00 }}, - {{ 0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00 }}, - {{ 0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00 }}, - {{ 0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00 }}, - {{ 0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00 }}, - {{ 0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00 }}, -}; - -static void dm_InitializeTXPowerTracking_TSSI(struct r8192_priv *priv) -{ - priv->txbbgain_table = rtl8192_txbbgain_table; - priv->cck_txbbgain_table = rtl8192_cck_txbbgain_table; - priv->cck_txbbgain_ch14_table = rtl8192_cck_txbbgain_ch14_table; - - priv->btxpower_tracking = TRUE; - priv->txpower_count = 0; - priv->btxpower_trackingInit = FALSE; - -} - -static void dm_InitializeTXPowerTracking_ThermalMeter(struct r8192_priv *priv) -{ - // Tx Power tracking by Theremal Meter require Firmware R/W 3-wire. This mechanism - // can be enabled only when Firmware R/W 3-wire is enabled. Otherwise, frequent r/w - // 3-wire by driver cause RF goes into wrong state. - if(priv->ieee80211->FwRWRF) - priv->btxpower_tracking = TRUE; - else - priv->btxpower_tracking = FALSE; - priv->txpower_count = 0; - priv->btxpower_trackingInit = FALSE; -} - -void dm_initialize_txpower_tracking(struct r8192_priv *priv) -{ - if(priv->IC_Cut >= IC_VersionCut_D) - dm_InitializeTXPowerTracking_TSSI(priv); - else - dm_InitializeTXPowerTracking_ThermalMeter(priv); -} - - -static void dm_CheckTXPowerTracking_TSSI(struct r8192_priv *priv) -{ - static u32 tx_power_track_counter = 0; - RT_TRACE(COMP_POWER_TRACKING,"%s()\n",__FUNCTION__); - if(read_nic_byte(priv, 0x11e) ==1) - return; - if(!priv->btxpower_tracking) - return; - tx_power_track_counter++; - - if (tx_power_track_counter > 90) { - queue_delayed_work(priv->priv_wq,&priv->txpower_tracking_wq,0); - tx_power_track_counter =0; - } -} - -static void dm_CheckTXPowerTracking_ThermalMeter(struct r8192_priv *priv) -{ - static u8 TM_Trigger=0; - - if(!priv->btxpower_tracking) - return; - else - { - if(priv->txpower_count <= 2) - { - priv->txpower_count++; - return; - } - } - - if(!TM_Trigger) - { - //Attention!! You have to wirte all 12bits data to RF, or it may cause RF to crash - //actually write reg0x02 bit1=0, then bit1=1. - rtl8192_phy_SetRFReg(priv, RF90_PATH_A, 0x02, bMask12Bits, 0x4d); - rtl8192_phy_SetRFReg(priv, RF90_PATH_A, 0x02, bMask12Bits, 0x4f); - rtl8192_phy_SetRFReg(priv, RF90_PATH_A, 0x02, bMask12Bits, 0x4d); - rtl8192_phy_SetRFReg(priv, RF90_PATH_A, 0x02, bMask12Bits, 0x4f); - TM_Trigger = 1; - return; - } - else { - queue_delayed_work(priv->priv_wq,&priv->txpower_tracking_wq,0); - TM_Trigger = 0; - } -} - -static void dm_check_txpower_tracking(struct r8192_priv *priv) -{ - if(priv->IC_Cut >= IC_VersionCut_D) - dm_CheckTXPowerTracking_TSSI(priv); - else - dm_CheckTXPowerTracking_ThermalMeter(priv); -} - - -static void dm_CCKTxPowerAdjust_TSSI(struct r8192_priv *priv, bool bInCH14) -{ - u32 TempVal; - //Write 0xa22 0xa23 - TempVal = 0; - if(!bInCH14){ - //Write 0xa22 0xa23 - TempVal = (u32)(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[0] + - (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[1]<<8)) ; - - rtl8192_setBBreg(priv, rCCK0_TxFilter1, bMaskHWord, TempVal); - //Write 0xa24 ~ 0xa27 - TempVal = 0; - TempVal = (u32)(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[2] + - (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[3]<<8) + - (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[4]<<16 )+ - (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[5]<<24)); - rtl8192_setBBreg(priv, rCCK0_TxFilter2, bMaskDWord, TempVal); - //Write 0xa28 0xa29 - TempVal = 0; - TempVal = (u32)(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[6] + - (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[7]<<8)) ; - - rtl8192_setBBreg(priv, rCCK0_DebugPort, bMaskLWord, TempVal); - } - else - { - TempVal = (u32)(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[0] + - (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[1]<<8)) ; - - rtl8192_setBBreg(priv, rCCK0_TxFilter1, bMaskHWord, TempVal); - //Write 0xa24 ~ 0xa27 - TempVal = 0; - TempVal = (u32)(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[2] + - (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[3]<<8) + - (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[4]<<16 )+ - (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[5]<<24)); - rtl8192_setBBreg(priv, rCCK0_TxFilter2, bMaskDWord, TempVal); - //Write 0xa28 0xa29 - TempVal = 0; - TempVal = (u32)(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[6] + - (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[7]<<8)) ; - - rtl8192_setBBreg(priv, rCCK0_DebugPort, bMaskLWord, TempVal); - } - - -} - -static void dm_CCKTxPowerAdjust_ThermalMeter(struct r8192_priv *priv, - bool bInCH14) -{ - u32 TempVal; - - TempVal = 0; - if(!bInCH14) - { - //Write 0xa22 0xa23 - TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][0] + - (CCKSwingTable_Ch1_Ch13[priv->CCK_index][1]<<8) ; - rtl8192_setBBreg(priv, rCCK0_TxFilter1, bMaskHWord, TempVal); - RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n", - rCCK0_TxFilter1, TempVal); - //Write 0xa24 ~ 0xa27 - TempVal = 0; - TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][2] + - (CCKSwingTable_Ch1_Ch13[priv->CCK_index][3]<<8) + - (CCKSwingTable_Ch1_Ch13[priv->CCK_index][4]<<16 )+ - (CCKSwingTable_Ch1_Ch13[priv->CCK_index][5]<<24); - rtl8192_setBBreg(priv, rCCK0_TxFilter2, bMaskDWord, TempVal); - RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n", - rCCK0_TxFilter2, TempVal); - //Write 0xa28 0xa29 - TempVal = 0; - TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][6] + - (CCKSwingTable_Ch1_Ch13[priv->CCK_index][7]<<8) ; - - rtl8192_setBBreg(priv, rCCK0_DebugPort, bMaskLWord, TempVal); - RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n", - rCCK0_DebugPort, TempVal); - } - else - { -// priv->CCKTxPowerAdjustCntNotCh14++; //cosa add for debug. - //Write 0xa22 0xa23 - TempVal = CCKSwingTable_Ch14[priv->CCK_index][0] + - (CCKSwingTable_Ch14[priv->CCK_index][1]<<8) ; - - rtl8192_setBBreg(priv, rCCK0_TxFilter1, bMaskHWord, TempVal); - RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n", - rCCK0_TxFilter1, TempVal); - //Write 0xa24 ~ 0xa27 - TempVal = 0; - TempVal = CCKSwingTable_Ch14[priv->CCK_index][2] + - (CCKSwingTable_Ch14[priv->CCK_index][3]<<8) + - (CCKSwingTable_Ch14[priv->CCK_index][4]<<16 )+ - (CCKSwingTable_Ch14[priv->CCK_index][5]<<24); - rtl8192_setBBreg(priv, rCCK0_TxFilter2, bMaskDWord, TempVal); - RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n", - rCCK0_TxFilter2, TempVal); - //Write 0xa28 0xa29 - TempVal = 0; - TempVal = CCKSwingTable_Ch14[priv->CCK_index][6] + - (CCKSwingTable_Ch14[priv->CCK_index][7]<<8) ; - - rtl8192_setBBreg(priv, rCCK0_DebugPort, bMaskLWord, TempVal); - RT_TRACE(COMP_POWER_TRACKING,"CCK chnl 14, reg 0x%x = 0x%x\n", - rCCK0_DebugPort, TempVal); - } -} - -void dm_cck_txpower_adjust(struct r8192_priv *priv, bool binch14) -{ - if(priv->IC_Cut >= IC_VersionCut_D) - dm_CCKTxPowerAdjust_TSSI(priv, binch14); - else - dm_CCKTxPowerAdjust_ThermalMeter(priv, binch14); -} - -/* Set DIG scheme init value. */ -static void dm_dig_init(struct r8192_priv *priv) -{ - /* 2007/10/05 MH Disable DIG scheme now. Not tested. */ - dm_digtable.dig_enable_flag = true; - dm_digtable.dig_algorithm = DIG_ALGO_BY_RSSI; - dm_digtable.dbg_mode = DM_DBG_OFF; //off=by real rssi value, on=by DM_DigTable.Rssi_val for new dig - dm_digtable.dig_algorithm_switch = 0; - - /* 2007/10/04 MH Define init gain threshold. */ - dm_digtable.dig_state = DM_STA_DIG_MAX; - dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX; - dm_digtable.initialgain_lowerbound_state = false; - - dm_digtable.rssi_low_thresh = DM_DIG_THRESH_LOW; - dm_digtable.rssi_high_thresh = DM_DIG_THRESH_HIGH; - - dm_digtable.rssi_high_power_lowthresh = DM_DIG_HIGH_PWR_THRESH_LOW; - dm_digtable.rssi_high_power_highthresh = DM_DIG_HIGH_PWR_THRESH_HIGH; - - dm_digtable.rssi_val = 50; //for new dig debug rssi value - dm_digtable.backoff_val = DM_DIG_BACKOFF; - dm_digtable.rx_gain_range_max = DM_DIG_MAX; - if(priv->CustomerID == RT_CID_819x_Netcore) - dm_digtable.rx_gain_range_min = DM_DIG_MIN_Netcore; - else - dm_digtable.rx_gain_range_min = DM_DIG_MIN; - -} - - -/* - * Driver must monitor RSSI and notify firmware to change initial - * gain according to different threshold. BB team provide the - * suggested solution. - */ -static void dm_ctrl_initgain_byrssi(struct r8192_priv *priv) -{ - if (dm_digtable.dig_enable_flag == false) - return; - - if(dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM) - dm_ctrl_initgain_byrssi_by_fwfalse_alarm(priv); - else if(dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI) - dm_ctrl_initgain_byrssi_by_driverrssi(priv); -} - - -static void dm_ctrl_initgain_byrssi_by_driverrssi(struct r8192_priv *priv) -{ - u8 i; - static u8 fw_dig=0; - - if (dm_digtable.dig_enable_flag == false) - return; - - if(dm_digtable.dig_algorithm_switch) // if swithed algorithm, we have to disable FW Dig. - fw_dig = 0; - if(fw_dig <= 3) // execute several times to make sure the FW Dig is disabled - {// FW DIG Off - for(i=0; i<3; i++) - rtl8192_setBBreg(priv, UFWP, bMaskByte1, 0x8); // Only clear byte 1 and rewrite. - fw_dig++; - dm_digtable.dig_state = DM_STA_DIG_OFF; //fw dig off. - } - - if(priv->ieee80211->state == IEEE80211_LINKED) - dm_digtable.cur_connect_state = DIG_CONNECT; - else - dm_digtable.cur_connect_state = DIG_DISCONNECT; - - if(dm_digtable.dbg_mode == DM_DBG_OFF) - dm_digtable.rssi_val = priv->undecorated_smoothed_pwdb; - - dm_initial_gain(priv); - dm_pd_th(priv); - dm_cs_ratio(priv); - if(dm_digtable.dig_algorithm_switch) - dm_digtable.dig_algorithm_switch = 0; - dm_digtable.pre_connect_state = dm_digtable.cur_connect_state; - -} - -static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(struct r8192_priv *priv) -{ - static u32 reset_cnt = 0; - u8 i; - - if (dm_digtable.dig_enable_flag == false) - return; - - if(dm_digtable.dig_algorithm_switch) - { - dm_digtable.dig_state = DM_STA_DIG_MAX; - // Fw DIG On. - for(i=0; i<3; i++) - rtl8192_setBBreg(priv, UFWP, bMaskByte1, 0x1); // Only clear byte 1 and rewrite. - dm_digtable.dig_algorithm_switch = 0; - } - - if (priv->ieee80211->state != IEEE80211_LINKED) - return; - - // For smooth, we can not change DIG state. - if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_low_thresh) && - (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_thresh)) - { - return; - } - - /* 1. When RSSI decrease, We have to judge if it is smaller than a threshold - and then execute below step. */ - if ((priv->undecorated_smoothed_pwdb <= dm_digtable.rssi_low_thresh)) - { - /* 2008/02/05 MH When we execute silent reset, the DIG PHY parameters - will be reset to init value. We must prevent the condition. */ - if (dm_digtable.dig_state == DM_STA_DIG_OFF && - (priv->reset_count == reset_cnt)) - { - return; - } - else - { - reset_cnt = priv->reset_count; - } - - // If DIG is off, DIG high power state must reset. - dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX; - dm_digtable.dig_state = DM_STA_DIG_OFF; - - // 1.1 DIG Off. - rtl8192_setBBreg(priv, UFWP, bMaskByte1, 0x8); // Only clear byte 1 and rewrite. - - // 1.2 Set initial gain. - write_nic_byte(priv, rOFDM0_XAAGCCore1, 0x17); - write_nic_byte(priv, rOFDM0_XBAGCCore1, 0x17); - write_nic_byte(priv, rOFDM0_XCAGCCore1, 0x17); - write_nic_byte(priv, rOFDM0_XDAGCCore1, 0x17); - - // 1.3 Lower PD_TH for OFDM. - if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) - { - /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */ - // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same. - write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x00); - } - else - write_nic_byte(priv, rOFDM0_RxDetector1, 0x42); - - // 1.4 Lower CS ratio for CCK. - write_nic_byte(priv, 0xa0a, 0x08); - - // 1.5 Higher EDCCA. - //PlatformEFIOWrite4Byte(pAdapter, rOFDM0_ECCAThreshold, 0x325); - return; - - } - - /* 2. When RSSI increase, We have to judge if it is larger than a threshold - and then execute below step. */ - if ((priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) ) - { - u8 reset_flag = 0; - - if (dm_digtable.dig_state == DM_STA_DIG_ON && - (priv->reset_count == reset_cnt)) - { - dm_ctrl_initgain_byrssi_highpwr(priv); - return; - } - else - { - if (priv->reset_count != reset_cnt) - reset_flag = 1; - - reset_cnt = priv->reset_count; - } - - dm_digtable.dig_state = DM_STA_DIG_ON; - - // 2.1 Set initial gain. - // 2008/02/26 MH SD3-Jerry suggest to prevent dirty environment. - if (reset_flag == 1) - { - write_nic_byte(priv, rOFDM0_XAAGCCore1, 0x2c); - write_nic_byte(priv, rOFDM0_XBAGCCore1, 0x2c); - write_nic_byte(priv, rOFDM0_XCAGCCore1, 0x2c); - write_nic_byte(priv, rOFDM0_XDAGCCore1, 0x2c); - } - else - { - write_nic_byte(priv, rOFDM0_XAAGCCore1, 0x20); - write_nic_byte(priv, rOFDM0_XBAGCCore1, 0x20); - write_nic_byte(priv, rOFDM0_XCAGCCore1, 0x20); - write_nic_byte(priv, rOFDM0_XDAGCCore1, 0x20); - } - - // 2.2 Higher PD_TH for OFDM. - if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) - { - /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */ - // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same. - write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x20); - } - else - write_nic_byte(priv, rOFDM0_RxDetector1, 0x44); - - // 2.3 Higher CS ratio for CCK. - write_nic_byte(priv, 0xa0a, 0xcd); - - // 2.4 Lower EDCCA. - /* 2008/01/11 MH 90/92 series are the same. */ - //PlatformEFIOWrite4Byte(pAdapter, rOFDM0_ECCAThreshold, 0x346); - - // 2.5 DIG On. - rtl8192_setBBreg(priv, UFWP, bMaskByte1, 0x1); // Only clear byte 1 and rewrite. - - } - - dm_ctrl_initgain_byrssi_highpwr(priv); - -} - -static void dm_ctrl_initgain_byrssi_highpwr(struct r8192_priv *priv) -{ - static u32 reset_cnt_highpwr = 0; - - // For smooth, we can not change high power DIG state in the range. - if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_high_power_lowthresh) && - (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_highthresh)) - { - return; - } - - /* 3. When RSSI >75% or <70%, it is a high power issue. We have to judge if - it is larger than a threshold and then execute below step. */ - // 2008/02/05 MH SD3-Jerry Modify PD_TH for high power issue. - if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_power_highthresh) - { - if (dm_digtable.dig_highpwr_state == DM_STA_DIG_ON && - (priv->reset_count == reset_cnt_highpwr)) - return; - else - dm_digtable.dig_highpwr_state = DM_STA_DIG_ON; - - // 3.1 Higher PD_TH for OFDM for high power state. - if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) - { - write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x10); - } - else - write_nic_byte(priv, rOFDM0_RxDetector1, 0x43); - } - else - { - if (dm_digtable.dig_highpwr_state == DM_STA_DIG_OFF&& - (priv->reset_count == reset_cnt_highpwr)) - return; - else - dm_digtable.dig_highpwr_state = DM_STA_DIG_OFF; - - if (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_lowthresh && - priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) - { - // 3.2 Recover PD_TH for OFDM for normal power region. - if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) - { - write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x20); - } - else - write_nic_byte(priv, rOFDM0_RxDetector1, 0x44); - } - } - - reset_cnt_highpwr = priv->reset_count; - -} - - -static void dm_initial_gain(struct r8192_priv *priv) -{ - u8 initial_gain=0; - static u8 initialized=0, force_write=0; - static u32 reset_cnt=0; - - if(dm_digtable.dig_algorithm_switch) - { - initialized = 0; - reset_cnt = 0; - } - - if(dm_digtable.pre_connect_state == dm_digtable.cur_connect_state) - { - if(dm_digtable.cur_connect_state == DIG_CONNECT) - { - if((dm_digtable.rssi_val+10-dm_digtable.backoff_val) > dm_digtable.rx_gain_range_max) - dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_max; - else if((dm_digtable.rssi_val+10-dm_digtable.backoff_val) < dm_digtable.rx_gain_range_min) - dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_min; - else - dm_digtable.cur_ig_value = dm_digtable.rssi_val+10-dm_digtable.backoff_val; - } - else //current state is disconnected - { - if(dm_digtable.cur_ig_value == 0) - dm_digtable.cur_ig_value = priv->DefaultInitialGain[0]; - else - dm_digtable.cur_ig_value = dm_digtable.pre_ig_value; - } - } - else // disconnected -> connected or connected -> disconnected - { - dm_digtable.cur_ig_value = priv->DefaultInitialGain[0]; - dm_digtable.pre_ig_value = 0; - } - - // if silent reset happened, we should rewrite the values back - if(priv->reset_count != reset_cnt) - { - force_write = 1; - reset_cnt = priv->reset_count; - } - - if(dm_digtable.pre_ig_value != read_nic_byte(priv, rOFDM0_XAAGCCore1)) - force_write = 1; - - { - if((dm_digtable.pre_ig_value != dm_digtable.cur_ig_value) - || !initialized || force_write) - { - initial_gain = (u8)dm_digtable.cur_ig_value; - // Set initial gain. - write_nic_byte(priv, rOFDM0_XAAGCCore1, initial_gain); - write_nic_byte(priv, rOFDM0_XBAGCCore1, initial_gain); - write_nic_byte(priv, rOFDM0_XCAGCCore1, initial_gain); - write_nic_byte(priv, rOFDM0_XDAGCCore1, initial_gain); - dm_digtable.pre_ig_value = dm_digtable.cur_ig_value; - initialized = 1; - force_write = 0; - } - } -} - -static void dm_pd_th(struct r8192_priv *priv) -{ - static u8 initialized=0, force_write=0; - static u32 reset_cnt = 0; - - if(dm_digtable.dig_algorithm_switch) - { - initialized = 0; - reset_cnt = 0; - } - - if(dm_digtable.pre_connect_state == dm_digtable.cur_connect_state) - { - if(dm_digtable.cur_connect_state == DIG_CONNECT) - { - if (dm_digtable.rssi_val >= dm_digtable.rssi_high_power_highthresh) - dm_digtable.curpd_thstate = DIG_PD_AT_HIGH_POWER; - else if ((dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh)) - dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER; - else if ((dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh) && - (dm_digtable.rssi_val < dm_digtable.rssi_high_power_lowthresh)) - dm_digtable.curpd_thstate = DIG_PD_AT_NORMAL_POWER; - else - dm_digtable.curpd_thstate = dm_digtable.prepd_thstate; - } - else - { - dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER; - } - } - else // disconnected -> connected or connected -> disconnected - { - dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER; - } - - // if silent reset happened, we should rewrite the values back - if(priv->reset_count != reset_cnt) - { - force_write = 1; - reset_cnt = priv->reset_count; - } - - { - if((dm_digtable.prepd_thstate != dm_digtable.curpd_thstate) || - (initialized<=3) || force_write) - { - if(dm_digtable.curpd_thstate == DIG_PD_AT_LOW_POWER) - { - // Lower PD_TH for OFDM. - if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) - { - /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */ - // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same. - write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x00); - } - else - write_nic_byte(priv, rOFDM0_RxDetector1, 0x42); - } - else if(dm_digtable.curpd_thstate == DIG_PD_AT_NORMAL_POWER) - { - // Higher PD_TH for OFDM. - if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) - { - /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */ - // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same. - write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x20); - } - else - write_nic_byte(priv, rOFDM0_RxDetector1, 0x44); - } - else if(dm_digtable.curpd_thstate == DIG_PD_AT_HIGH_POWER) - { - // Higher PD_TH for OFDM for high power state. - if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) - { - write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x10); - } - else - write_nic_byte(priv, rOFDM0_RxDetector1, 0x43); - } - dm_digtable.prepd_thstate = dm_digtable.curpd_thstate; - if(initialized <= 3) - initialized++; - force_write = 0; - } - } -} - -static void dm_cs_ratio(struct r8192_priv *priv) -{ - static u8 initialized=0,force_write=0; - static u32 reset_cnt = 0; - - if(dm_digtable.dig_algorithm_switch) - { - initialized = 0; - reset_cnt = 0; - } - - if(dm_digtable.pre_connect_state == dm_digtable.cur_connect_state) - { - if(dm_digtable.cur_connect_state == DIG_CONNECT) - { - if ((dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh)) - dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER; - else if ((dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh) ) - dm_digtable.curcs_ratio_state = DIG_CS_RATIO_HIGHER; - else - dm_digtable.curcs_ratio_state = dm_digtable.precs_ratio_state; - } - else - { - dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER; - } - } - else // disconnected -> connected or connected -> disconnected - { - dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER; - } - - // if silent reset happened, we should rewrite the values back - if(priv->reset_count != reset_cnt) - { - force_write = 1; - reset_cnt = priv->reset_count; - } - - - if((dm_digtable.precs_ratio_state != dm_digtable.curcs_ratio_state) || - !initialized || force_write) - { - if(dm_digtable.curcs_ratio_state == DIG_CS_RATIO_LOWER) - { - // Lower CS ratio for CCK. - write_nic_byte(priv, 0xa0a, 0x08); - } - else if(dm_digtable.curcs_ratio_state == DIG_CS_RATIO_HIGHER) - { - // Higher CS ratio for CCK. - write_nic_byte(priv, 0xa0a, 0xcd); - } - dm_digtable.precs_ratio_state = dm_digtable.curcs_ratio_state; - initialized = 1; - force_write = 0; - } -} - -void dm_init_edca_turbo(struct r8192_priv *priv) -{ - - priv->bcurrent_turbo_EDCA = false; - priv->ieee80211->bis_any_nonbepkts = false; - priv->bis_cur_rdlstate = false; -} - -static void dm_check_edca_turbo(struct r8192_priv *priv) -{ - PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo; - //PSTA_QOS pStaQos = pMgntInfo->pStaQos; - - // Keep past Tx/Rx packet count for RT-to-RT EDCA turbo. - static unsigned long lastTxOkCnt = 0; - static unsigned long lastRxOkCnt = 0; - unsigned long curTxOkCnt = 0; - unsigned long curRxOkCnt = 0; - - // - // Do not be Turbo if it's under WiFi config and Qos Enabled, because the EDCA parameters - // should follow the settings from QAP. By Bruce, 2007-12-07. - // - if(priv->ieee80211->state != IEEE80211_LINKED) - goto dm_CheckEdcaTurbo_EXIT; - // We do not turn on EDCA turbo mode for some AP that has IOT issue - if(priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_EDCA_TURBO) - goto dm_CheckEdcaTurbo_EXIT; - - // Check the status for current condition. - if(!priv->ieee80211->bis_any_nonbepkts) - { - curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt; - curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt; - // For RT-AP, we needs to turn it on when Rx>Tx - if(curRxOkCnt > 4*curTxOkCnt) - { - if(!priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA) - { - write_nic_dword(priv, EDCAPARA_BE, edca_setting_DL[pHTInfo->IOTPeer]); - priv->bis_cur_rdlstate = true; - } - } - else - { - if(priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA) - { - write_nic_dword(priv, EDCAPARA_BE, edca_setting_UL[pHTInfo->IOTPeer]); - priv->bis_cur_rdlstate = false; - } - - } - - priv->bcurrent_turbo_EDCA = true; - } - else - { - // - // Turn Off EDCA turbo here. - // Restore original EDCA according to the declaration of AP. - // - if(priv->bcurrent_turbo_EDCA) - { - - { - u8 u1bAIFS; - u32 u4bAcParam; - struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters; - u8 mode = priv->ieee80211->mode; - - // For Each time updating EDCA parameter, reset EDCA turbo mode status. - dm_init_edca_turbo(priv); - u1bAIFS = qos_parameters->aifs[0] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime; - u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[0]))<< AC_PARAM_TXOP_LIMIT_OFFSET)| - (((u32)(qos_parameters->cw_max[0]))<< AC_PARAM_ECW_MAX_OFFSET)| - (((u32)(qos_parameters->cw_min[0]))<< AC_PARAM_ECW_MIN_OFFSET)| - ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET)); - printk("===>u4bAcParam:%x, ", u4bAcParam); - //write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam); - write_nic_dword(priv, EDCAPARA_BE, u4bAcParam); - - // Check ACM bit. - // If it is set, immediately set ACM control bit to downgrading AC for passing WMM testplan. Annie, 2005-12-13. - { - // TODO: Modified this part and try to set acm control in only 1 IO processing!! - - PACI_AIFSN pAciAifsn = (PACI_AIFSN)&(qos_parameters->aifs[0]); - u8 AcmCtrl = read_nic_byte(priv, AcmHwCtrl ); - if( pAciAifsn->f.ACM ) - { // ACM bit is 1. - AcmCtrl |= AcmHw_BeqEn; - } - else - { // ACM bit is 0. - AcmCtrl &= (~AcmHw_BeqEn); - } - - RT_TRACE( COMP_QOS,"SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl ) ; - write_nic_byte(priv, AcmHwCtrl, AcmCtrl ); - } - } - priv->bcurrent_turbo_EDCA = false; - } - } - - -dm_CheckEdcaTurbo_EXIT: - // Set variables for next time. - priv->ieee80211->bis_any_nonbepkts = false; - lastTxOkCnt = priv->stats.txbytesunicast; - lastRxOkCnt = priv->stats.rxbytesunicast; -} - -static void dm_init_ctstoself(struct r8192_priv *priv) -{ - priv->ieee80211->bCTSToSelfEnable = TRUE; - priv->ieee80211->CTSToSelfTH = CTSToSelfTHVal; -} - -static void dm_ctstoself(struct r8192_priv *priv) -{ - PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo; - static unsigned long lastTxOkCnt = 0; - static unsigned long lastRxOkCnt = 0; - unsigned long curTxOkCnt = 0; - unsigned long curRxOkCnt = 0; - - if(priv->ieee80211->bCTSToSelfEnable != TRUE) - { - pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF; - return; - } - /* - 1. Uplink - 2. Linksys350/Linksys300N - 3. <50 disable, >55 enable - */ - - if(pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) - { - curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt; - curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt; - if(curRxOkCnt > 4*curTxOkCnt) //downlink, disable CTS to self - { - pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF; - } - else //uplink - { - pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF; - } - - lastTxOkCnt = priv->stats.txbytesunicast; - lastRxOkCnt = priv->stats.rxbytesunicast; - } -} - - - -/* Copy 8187B template for 9xseries */ -static void dm_check_rfctrl_gpio(struct r8192_priv *priv) -{ - - // Walk around for DTM test, we will not enable HW - radio on/off because r/w - // page 1 register before Lextra bus is enabled cause system fails when resuming - // from S4. 20080218, Emily - - // Stop to execute workitem to prevent S3/S4 bug. - queue_delayed_work(priv->priv_wq,&priv->gpio_change_rf_wq,0); -} - -/* PCI will not support workitem call back HW radio on-off control. */ -void dm_gpio_change_rf_callback(struct work_struct *work) -{ - struct delayed_work *dwork = container_of(work,struct delayed_work,work); - struct r8192_priv *priv = container_of(dwork,struct r8192_priv,gpio_change_rf_wq); - u8 tmp1byte; - RT_RF_POWER_STATE eRfPowerStateToSet; - bool bActuallySet = false; - - if (!priv->up) { - RT_TRACE((COMP_INIT | COMP_POWER | COMP_RF),"dm_gpio_change_rf_callback(): Callback function breaks out!!\n"); - } else { - // 0x108 GPIO input register is read only - //set 0x108 B1= 1: RF-ON; 0: RF-OFF. - tmp1byte = read_nic_byte(priv, GPI); - - eRfPowerStateToSet = (tmp1byte&BIT1) ? eRfOn : eRfOff; - - if (priv->bHwRadioOff && (eRfPowerStateToSet == eRfOn)) { - RT_TRACE(COMP_RF, "gpiochangeRF - HW Radio ON\n"); - - priv->bHwRadioOff = false; - bActuallySet = true; - } else if ((!priv->bHwRadioOff) && (eRfPowerStateToSet == eRfOff)) { - RT_TRACE(COMP_RF, "gpiochangeRF - HW Radio OFF\n"); - priv->bHwRadioOff = true; - bActuallySet = true; - } - - if (bActuallySet) { - priv->bHwRfOffAction = 1; - MgntActSet_RF_State(priv, eRfPowerStateToSet, RF_CHANGE_BY_HW); - //DrvIFIndicateCurrentPhyStatus(pAdapter); - } else { - msleep(2000); - } - } -} - -/* Check if Current RF RX path is enabled */ -void dm_rf_pathcheck_workitemcallback(struct work_struct *work) -{ - struct delayed_work *dwork = container_of(work,struct delayed_work,work); - struct r8192_priv *priv = container_of(dwork,struct r8192_priv,rfpath_check_wq); - u8 rfpath = 0, i; - - - /* 2008/01/30 MH After discussing with SD3 Jerry, 0xc04/0xd04 register will - always be the same. We only read 0xc04 now. */ - rfpath = read_nic_byte(priv, 0xc04); - - // Check Bit 0-3, it means if RF A-D is enabled. - for (i = 0; i < RF90_PATH_MAX; i++) - { - if (rfpath & (0x01<<i)) - priv->brfpath_rxenable[i] = 1; - else - priv->brfpath_rxenable[i] = 0; - } - if(!DM_RxPathSelTable.Enable) - return; - - dm_rxpath_sel_byrssi(priv); -} - -static void dm_init_rxpath_selection(struct r8192_priv *priv) -{ - u8 i; - - DM_RxPathSelTable.Enable = 1; //default enabled - DM_RxPathSelTable.SS_TH_low = RxPathSelection_SS_TH_low; - DM_RxPathSelTable.diff_TH = RxPathSelection_diff_TH; - if(priv->CustomerID == RT_CID_819x_Netcore) - DM_RxPathSelTable.cck_method = CCK_Rx_Version_2; - else - DM_RxPathSelTable.cck_method = CCK_Rx_Version_1; - DM_RxPathSelTable.DbgMode = DM_DBG_OFF; - DM_RxPathSelTable.disabledRF = 0; - for(i=0; i<4; i++) - { - DM_RxPathSelTable.rf_rssi[i] = 50; - DM_RxPathSelTable.cck_pwdb_sta[i] = -64; - DM_RxPathSelTable.rf_enable_rssi_th[i] = 100; - } -} - -static void dm_rxpath_sel_byrssi(struct r8192_priv *priv) -{ - u8 i, max_rssi_index=0, min_rssi_index=0, sec_rssi_index=0, rf_num=0; - u8 tmp_max_rssi=0, tmp_min_rssi=0, tmp_sec_rssi=0; - u8 cck_default_Rx=0x2; //RF-C - u8 cck_optional_Rx=0x3;//RF-D - long tmp_cck_max_pwdb=0, tmp_cck_min_pwdb=0, tmp_cck_sec_pwdb=0; - u8 cck_rx_ver2_max_index=0, cck_rx_ver2_min_index=0, cck_rx_ver2_sec_index=0; - u8 cur_rf_rssi; - long cur_cck_pwdb; - static u8 disabled_rf_cnt=0, cck_Rx_Path_initialized=0; - u8 update_cck_rx_path; - - if(priv->rf_type != RF_2T4R) - return; - - if(!cck_Rx_Path_initialized) - { - DM_RxPathSelTable.cck_Rx_path = (read_nic_byte(priv, 0xa07)&0xf); - cck_Rx_Path_initialized = 1; - } - - DM_RxPathSelTable.disabledRF = 0xf; - DM_RxPathSelTable.disabledRF &=~ (read_nic_byte(priv, 0xc04)); - - if(priv->ieee80211->mode == WIRELESS_MODE_B) - { - DM_RxPathSelTable.cck_method = CCK_Rx_Version_2; //pure B mode, fixed cck version2 - } - - //decide max/sec/min rssi index - for (i=0; i<RF90_PATH_MAX; i++) - { - if(!DM_RxPathSelTable.DbgMode) - DM_RxPathSelTable.rf_rssi[i] = priv->stats.rx_rssi_percentage[i]; - - if(priv->brfpath_rxenable[i]) - { - rf_num++; - cur_rf_rssi = DM_RxPathSelTable.rf_rssi[i]; - - if(rf_num == 1) // find first enabled rf path and the rssi values - { //initialize, set all rssi index to the same one - max_rssi_index = min_rssi_index = sec_rssi_index = i; - tmp_max_rssi = tmp_min_rssi = tmp_sec_rssi = cur_rf_rssi; - } - else if(rf_num == 2) - { // we pick up the max index first, and let sec and min to be the same one - if(cur_rf_rssi >= tmp_max_rssi) - { - tmp_max_rssi = cur_rf_rssi; - max_rssi_index = i; - } - else - { - tmp_sec_rssi = tmp_min_rssi = cur_rf_rssi; - sec_rssi_index = min_rssi_index = i; - } - } - else - { - if(cur_rf_rssi > tmp_max_rssi) - { - tmp_sec_rssi = tmp_max_rssi; - sec_rssi_index = max_rssi_index; - tmp_max_rssi = cur_rf_rssi; - max_rssi_index = i; - } - else if(cur_rf_rssi == tmp_max_rssi) - { // let sec and min point to the different index - tmp_sec_rssi = cur_rf_rssi; - sec_rssi_index = i; - } - else if((cur_rf_rssi < tmp_max_rssi) &&(cur_rf_rssi > tmp_sec_rssi)) - { - tmp_sec_rssi = cur_rf_rssi; - sec_rssi_index = i; - } - else if(cur_rf_rssi == tmp_sec_rssi) - { - if(tmp_sec_rssi == tmp_min_rssi) - { // let sec and min point to the different index - tmp_sec_rssi = cur_rf_rssi; - sec_rssi_index = i; - } - else - { - // This case we don't need to set any index - } - } - else if((cur_rf_rssi < tmp_sec_rssi) && (cur_rf_rssi > tmp_min_rssi)) - { - // This case we don't need to set any index - } - else if(cur_rf_rssi == tmp_min_rssi) - { - if(tmp_sec_rssi == tmp_min_rssi) - { // let sec and min point to the different index - tmp_min_rssi = cur_rf_rssi; - min_rssi_index = i; - } - else - { - // This case we don't need to set any index - } - } - else if(cur_rf_rssi < tmp_min_rssi) - { - tmp_min_rssi = cur_rf_rssi; - min_rssi_index = i; - } - } - } - } - - rf_num = 0; - // decide max/sec/min cck pwdb index - if(DM_RxPathSelTable.cck_method == CCK_Rx_Version_2) - { - for (i=0; i<RF90_PATH_MAX; i++) - { - if(priv->brfpath_rxenable[i]) - { - rf_num++; - cur_cck_pwdb = DM_RxPathSelTable.cck_pwdb_sta[i]; - - if(rf_num == 1) // find first enabled rf path and the rssi values - { //initialize, set all rssi index to the same one - cck_rx_ver2_max_index = cck_rx_ver2_min_index = cck_rx_ver2_sec_index = i; - tmp_cck_max_pwdb = tmp_cck_min_pwdb = tmp_cck_sec_pwdb = cur_cck_pwdb; - } - else if(rf_num == 2) - { // we pick up the max index first, and let sec and min to be the same one - if(cur_cck_pwdb >= tmp_cck_max_pwdb) - { - tmp_cck_max_pwdb = cur_cck_pwdb; - cck_rx_ver2_max_index = i; - } - else - { - tmp_cck_sec_pwdb = tmp_cck_min_pwdb = cur_cck_pwdb; - cck_rx_ver2_sec_index = cck_rx_ver2_min_index = i; - } - } - else - { - if(cur_cck_pwdb > tmp_cck_max_pwdb) - { - tmp_cck_sec_pwdb = tmp_cck_max_pwdb; - cck_rx_ver2_sec_index = cck_rx_ver2_max_index; - tmp_cck_max_pwdb = cur_cck_pwdb; - cck_rx_ver2_max_index = i; - } - else if(cur_cck_pwdb == tmp_cck_max_pwdb) - { // let sec and min point to the different index - tmp_cck_sec_pwdb = cur_cck_pwdb; - cck_rx_ver2_sec_index = i; - } - else if((cur_cck_pwdb < tmp_cck_max_pwdb) &&(cur_cck_pwdb > tmp_cck_sec_pwdb)) - { - tmp_cck_sec_pwdb = cur_cck_pwdb; - cck_rx_ver2_sec_index = i; - } - else if(cur_cck_pwdb == tmp_cck_sec_pwdb) - { - if(tmp_cck_sec_pwdb == tmp_cck_min_pwdb) - { // let sec and min point to the different index - tmp_cck_sec_pwdb = cur_cck_pwdb; - cck_rx_ver2_sec_index = i; - } - else - { - // This case we don't need to set any index - } - } - else if((cur_cck_pwdb < tmp_cck_sec_pwdb) && (cur_cck_pwdb > tmp_cck_min_pwdb)) - { - // This case we don't need to set any index - } - else if(cur_cck_pwdb == tmp_cck_min_pwdb) - { - if(tmp_cck_sec_pwdb == tmp_cck_min_pwdb) - { // let sec and min point to the different index - tmp_cck_min_pwdb = cur_cck_pwdb; - cck_rx_ver2_min_index = i; - } - else - { - // This case we don't need to set any index - } - } - else if(cur_cck_pwdb < tmp_cck_min_pwdb) - { - tmp_cck_min_pwdb = cur_cck_pwdb; - cck_rx_ver2_min_index = i; - } - } - - } - } - } - - - // Set CCK Rx path - // reg0xA07[3:2]=cck default rx path, reg0xa07[1:0]=cck optional rx path. - update_cck_rx_path = 0; - if(DM_RxPathSelTable.cck_method == CCK_Rx_Version_2) - { - cck_default_Rx = cck_rx_ver2_max_index; - cck_optional_Rx = cck_rx_ver2_sec_index; - if(tmp_cck_max_pwdb != -64) - update_cck_rx_path = 1; - } - - if(tmp_min_rssi < DM_RxPathSelTable.SS_TH_low && disabled_rf_cnt < 2) - { - if((tmp_max_rssi - tmp_min_rssi) >= DM_RxPathSelTable.diff_TH) - { - //record the enabled rssi threshold - DM_RxPathSelTable.rf_enable_rssi_th[min_rssi_index] = tmp_max_rssi+5; - //disable the BB Rx path, OFDM - rtl8192_setBBreg(priv, rOFDM0_TRxPathEnable, 0x1<<min_rssi_index, 0x0); // 0xc04[3:0] - rtl8192_setBBreg(priv, rOFDM1_TRxPathEnable, 0x1<<min_rssi_index, 0x0); // 0xd04[3:0] - disabled_rf_cnt++; - } - if(DM_RxPathSelTable.cck_method == CCK_Rx_Version_1) - { - cck_default_Rx = max_rssi_index; - cck_optional_Rx = sec_rssi_index; - if(tmp_max_rssi) - update_cck_rx_path = 1; - } - } - - if(update_cck_rx_path) - { - DM_RxPathSelTable.cck_Rx_path = (cck_default_Rx<<2)|(cck_optional_Rx); - rtl8192_setBBreg(priv, rCCK0_AFESetting, 0x0f000000, DM_RxPathSelTable.cck_Rx_path); - } - - if(DM_RxPathSelTable.disabledRF) - { - for(i=0; i<4; i++) - { - if((DM_RxPathSelTable.disabledRF>>i) & 0x1) //disabled rf - { - if(tmp_max_rssi >= DM_RxPathSelTable.rf_enable_rssi_th[i]) - { - //enable the BB Rx path - rtl8192_setBBreg(priv, rOFDM0_TRxPathEnable, 0x1<<i, 0x1); // 0xc04[3:0] - rtl8192_setBBreg(priv, rOFDM1_TRxPathEnable, 0x1<<i, 0x1); // 0xd04[3:0] - DM_RxPathSelTable.rf_enable_rssi_th[i] = 100; - disabled_rf_cnt--; - } - } - } - } -} - -/* - * Call a workitem to check current RXRF path and Rx Path selection by RSSI. - */ -static void dm_check_rx_path_selection(struct r8192_priv *priv) -{ - queue_delayed_work(priv->priv_wq,&priv->rfpath_check_wq,0); -} - -static void dm_init_fsync(struct r8192_priv *priv) -{ - priv->ieee80211->fsync_time_interval = 500; - priv->ieee80211->fsync_rate_bitmap = 0x0f000800; - priv->ieee80211->fsync_rssi_threshold = 30; - priv->ieee80211->bfsync_enable = false; - priv->ieee80211->fsync_multiple_timeinterval = 3; - priv->ieee80211->fsync_firstdiff_ratethreshold= 100; - priv->ieee80211->fsync_seconddiff_ratethreshold= 200; - priv->ieee80211->fsync_state = Default_Fsync; - priv->framesyncMonitor = 1; // current default 0xc38 monitor on - - init_timer(&priv->fsync_timer); - priv->fsync_timer.data = (unsigned long)priv; - priv->fsync_timer.function = dm_fsync_timer_callback; -} - - -static void dm_deInit_fsync(struct r8192_priv *priv) -{ - del_timer_sync(&priv->fsync_timer); -} - -static void dm_fsync_timer_callback(unsigned long data) -{ - struct r8192_priv *priv = (struct r8192_priv *)data; - u32 rate_index, rate_count = 0, rate_count_diff=0; - bool bSwitchFromCountDiff = false; - bool bDoubleTimeInterval = false; - - if( priv->ieee80211->state == IEEE80211_LINKED && - priv->ieee80211->bfsync_enable && - (priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC)) - { - // Count rate 54, MCS [7], [12, 13, 14, 15] - u32 rate_bitmap; - for(rate_index = 0; rate_index <= 27; rate_index++) - { - rate_bitmap = 1 << rate_index; - if(priv->ieee80211->fsync_rate_bitmap & rate_bitmap) - rate_count+= priv->stats.received_rate_histogram[1][rate_index]; - } - - if(rate_count < priv->rate_record) - rate_count_diff = 0xffffffff - rate_count + priv->rate_record; - else - rate_count_diff = rate_count - priv->rate_record; - if(rate_count_diff < priv->rateCountDiffRecord) - { - - u32 DiffNum = priv->rateCountDiffRecord - rate_count_diff; - // Contiune count - if(DiffNum >= priv->ieee80211->fsync_seconddiff_ratethreshold) - priv->ContiuneDiffCount++; - else - priv->ContiuneDiffCount = 0; - - // Contiune count over - if(priv->ContiuneDiffCount >=2) - { - bSwitchFromCountDiff = true; - priv->ContiuneDiffCount = 0; - } - } - else - { - // Stop contiune count - priv->ContiuneDiffCount = 0; - } - - //If Count diff <= FsyncRateCountThreshold - if(rate_count_diff <= priv->ieee80211->fsync_firstdiff_ratethreshold) - { - bSwitchFromCountDiff = true; - priv->ContiuneDiffCount = 0; - } - priv->rate_record = rate_count; - priv->rateCountDiffRecord = rate_count_diff; - RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff , priv->bswitch_fsync); - // if we never receive those mcs rate and rssi > 30 % then switch fsyn - if(priv->undecorated_smoothed_pwdb > priv->ieee80211->fsync_rssi_threshold && bSwitchFromCountDiff) - { - bDoubleTimeInterval = true; - priv->bswitch_fsync = !priv->bswitch_fsync; - if(priv->bswitch_fsync) - { - write_nic_byte(priv,0xC36, 0x1c); - write_nic_byte(priv, 0xC3e, 0x90); - } - else - { - write_nic_byte(priv, 0xC36, 0x5c); - write_nic_byte(priv, 0xC3e, 0x96); - } - } - else if(priv->undecorated_smoothed_pwdb <= priv->ieee80211->fsync_rssi_threshold) - { - if(priv->bswitch_fsync) - { - priv->bswitch_fsync = false; - write_nic_byte(priv, 0xC36, 0x5c); - write_nic_byte(priv, 0xC3e, 0x96); - } - } - if(bDoubleTimeInterval){ - if(timer_pending(&priv->fsync_timer)) - del_timer_sync(&priv->fsync_timer); - priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval*priv->ieee80211->fsync_multiple_timeinterval); - add_timer(&priv->fsync_timer); - } - else{ - if(timer_pending(&priv->fsync_timer)) - del_timer_sync(&priv->fsync_timer); - priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval); - add_timer(&priv->fsync_timer); - } - } - else - { - // Let Register return to default value; - if(priv->bswitch_fsync) - { - priv->bswitch_fsync = false; - write_nic_byte(priv, 0xC36, 0x5c); - write_nic_byte(priv, 0xC3e, 0x96); - } - priv->ContiuneDiffCount = 0; - write_nic_dword(priv, rOFDM0_RxDetector2, 0x465c52cd); - } - RT_TRACE(COMP_HALDM, "ContiuneDiffCount %d\n", priv->ContiuneDiffCount); - RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff , priv->bswitch_fsync); -} - -static void dm_StartHWFsync(struct r8192_priv *priv) -{ - RT_TRACE(COMP_HALDM, "%s\n", __FUNCTION__); - write_nic_dword(priv, rOFDM0_RxDetector2, 0x465c12cf); - write_nic_byte(priv, 0xc3b, 0x41); -} - -static void dm_EndSWFsync(struct r8192_priv *priv) -{ - RT_TRACE(COMP_HALDM, "%s\n", __FUNCTION__); - del_timer_sync(&(priv->fsync_timer)); - - // Let Register return to default value; - if(priv->bswitch_fsync) - { - priv->bswitch_fsync = false; - - write_nic_byte(priv, 0xC36, 0x40); - - write_nic_byte(priv, 0xC3e, 0x96); - } - - priv->ContiuneDiffCount = 0; - - write_nic_dword(priv, rOFDM0_RxDetector2, 0x465c52cd); -} - -static void dm_StartSWFsync(struct r8192_priv *priv) -{ - u32 rateIndex; - u32 rateBitmap; - - RT_TRACE(COMP_HALDM,"%s\n", __FUNCTION__); - // Initial rate record to zero, start to record. - priv->rate_record = 0; - // Initial contiune diff count to zero, start to record. - priv->ContiuneDiffCount = 0; - priv->rateCountDiffRecord = 0; - priv->bswitch_fsync = false; - - if(priv->ieee80211->mode == WIRELESS_MODE_N_24G) - { - priv->ieee80211->fsync_firstdiff_ratethreshold= 600; - priv->ieee80211->fsync_seconddiff_ratethreshold = 0xffff; - } - else - { - priv->ieee80211->fsync_firstdiff_ratethreshold= 200; - priv->ieee80211->fsync_seconddiff_ratethreshold = 200; - } - for(rateIndex = 0; rateIndex <= 27; rateIndex++) - { - rateBitmap = 1 << rateIndex; - if(priv->ieee80211->fsync_rate_bitmap & rateBitmap) - priv->rate_record += priv->stats.received_rate_histogram[1][rateIndex]; - } - if(timer_pending(&priv->fsync_timer)) - del_timer_sync(&priv->fsync_timer); - priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval); - add_timer(&priv->fsync_timer); - - write_nic_dword(priv, rOFDM0_RxDetector2, 0x465c12cd); -} - -static void dm_EndHWFsync(struct r8192_priv *priv) -{ - RT_TRACE(COMP_HALDM,"%s\n", __FUNCTION__); - write_nic_dword(priv, rOFDM0_RxDetector2, 0x465c52cd); - write_nic_byte(priv, 0xc3b, 0x49); -} - -static void dm_check_fsync(struct r8192_priv *priv) -{ -#define RegC38_Default 0 -#define RegC38_NonFsync_Other_AP 1 -#define RegC38_Fsync_AP_BCM 2 - //u32 framesyncC34; - static u8 reg_c38_State=RegC38_Default; - static u32 reset_cnt=0; - - RT_TRACE(COMP_HALDM, "RSSI %d TimeInterval %d MultipleTimeInterval %d\n", priv->ieee80211->fsync_rssi_threshold, priv->ieee80211->fsync_time_interval, priv->ieee80211->fsync_multiple_timeinterval); - RT_TRACE(COMP_HALDM, "RateBitmap 0x%x FirstDiffRateThreshold %d SecondDiffRateThreshold %d\n", priv->ieee80211->fsync_rate_bitmap, priv->ieee80211->fsync_firstdiff_ratethreshold, priv->ieee80211->fsync_seconddiff_ratethreshold); - - if( priv->ieee80211->state == IEEE80211_LINKED && - (priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC)) - { - if(priv->ieee80211->bfsync_enable == 0) - { - switch(priv->ieee80211->fsync_state) - { - case Default_Fsync: - dm_StartHWFsync(priv); - priv->ieee80211->fsync_state = HW_Fsync; - break; - case SW_Fsync: - dm_EndSWFsync(priv); - dm_StartHWFsync(priv); - priv->ieee80211->fsync_state = HW_Fsync; - break; - case HW_Fsync: - default: - break; - } - } - else - { - switch(priv->ieee80211->fsync_state) - { - case Default_Fsync: - dm_StartSWFsync(priv); - priv->ieee80211->fsync_state = SW_Fsync; - break; - case HW_Fsync: - dm_EndHWFsync(priv); - dm_StartSWFsync(priv); - priv->ieee80211->fsync_state = SW_Fsync; - break; - case SW_Fsync: - default: - break; - - } - } - if(priv->framesyncMonitor) - { - if(reg_c38_State != RegC38_Fsync_AP_BCM) - { //For broadcom AP we write different default value - write_nic_byte(priv, rOFDM0_RxDetector3, 0x95); - - reg_c38_State = RegC38_Fsync_AP_BCM; - } - } - } - else - { - switch(priv->ieee80211->fsync_state) - { - case HW_Fsync: - dm_EndHWFsync(priv); - priv->ieee80211->fsync_state = Default_Fsync; - break; - case SW_Fsync: - dm_EndSWFsync(priv); - priv->ieee80211->fsync_state = Default_Fsync; - break; - case Default_Fsync: - default: - break; - } - - if(priv->framesyncMonitor) - { - if(priv->ieee80211->state == IEEE80211_LINKED) - { - if(priv->undecorated_smoothed_pwdb <= RegC38_TH) - { - if(reg_c38_State != RegC38_NonFsync_Other_AP) - { - write_nic_byte(priv, rOFDM0_RxDetector3, 0x90); - - reg_c38_State = RegC38_NonFsync_Other_AP; - } - } - else if(priv->undecorated_smoothed_pwdb >= (RegC38_TH+5)) - { - if(reg_c38_State) - { - write_nic_byte(priv, rOFDM0_RxDetector3, priv->framesync); - reg_c38_State = RegC38_Default; - } - } - } - else - { - if(reg_c38_State) - { - write_nic_byte(priv, rOFDM0_RxDetector3, priv->framesync); - reg_c38_State = RegC38_Default; - } - } - } - } - if(priv->framesyncMonitor) - { - if(priv->reset_count != reset_cnt) - { //After silent reset, the reg_c38_State will be returned to default value - write_nic_byte(priv, rOFDM0_RxDetector3, priv->framesync); - reg_c38_State = RegC38_Default; - reset_cnt = priv->reset_count; - } - } - else - { - if(reg_c38_State) - { - write_nic_byte(priv, rOFDM0_RxDetector3, priv->framesync); - reg_c38_State = RegC38_Default; - } - } -} - -/* - * Detect Signal strength to control TX Registry - * Tx Power Control For Near/Far Range - */ -static void dm_init_dynamic_txpower(struct r8192_priv *priv) -{ - //Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code. - priv->ieee80211->bdynamic_txpower_enable = true; //Default to enable Tx Power Control - priv->bLastDTPFlag_High = false; - priv->bLastDTPFlag_Low = false; - priv->bDynamicTxHighPower = false; - priv->bDynamicTxLowPower = false; -} - -static void dm_dynamic_txpower(struct r8192_priv *priv) -{ - unsigned int txhipower_threshhold=0; - unsigned int txlowpower_threshold=0; - if(priv->ieee80211->bdynamic_txpower_enable != true) - { - priv->bDynamicTxHighPower = false; - priv->bDynamicTxLowPower = false; - return; - } - if((priv->ieee80211->current_network.atheros_cap_exist ) && (priv->ieee80211->mode == IEEE_G)){ - txhipower_threshhold = TX_POWER_ATHEROAP_THRESH_HIGH; - txlowpower_threshold = TX_POWER_ATHEROAP_THRESH_LOW; - } - else - { - txhipower_threshhold = TX_POWER_NEAR_FIELD_THRESH_HIGH; - txlowpower_threshold = TX_POWER_NEAR_FIELD_THRESH_LOW; - } - - RT_TRACE(COMP_TXAGC, "priv->undecorated_smoothed_pwdb = %ld\n" , priv->undecorated_smoothed_pwdb); - - if(priv->ieee80211->state == IEEE80211_LINKED) - { - if(priv->undecorated_smoothed_pwdb >= txhipower_threshhold) - { - priv->bDynamicTxHighPower = true; - priv->bDynamicTxLowPower = false; - } - else - { - // high power state check - if(priv->undecorated_smoothed_pwdb < txlowpower_threshold && priv->bDynamicTxHighPower == true) - { - priv->bDynamicTxHighPower = false; - } - // low power state check - if(priv->undecorated_smoothed_pwdb < 35) - { - priv->bDynamicTxLowPower = true; - } - else if(priv->undecorated_smoothed_pwdb >= 40) - { - priv->bDynamicTxLowPower = false; - } - } - } - else - { - //pHalData->bTXPowerCtrlforNearFarRange = !pHalData->bTXPowerCtrlforNearFarRange; - priv->bDynamicTxHighPower = false; - priv->bDynamicTxLowPower = false; - } - - if( (priv->bDynamicTxHighPower != priv->bLastDTPFlag_High ) || - (priv->bDynamicTxLowPower != priv->bLastDTPFlag_Low ) ) - { - RT_TRACE(COMP_TXAGC, "SetTxPowerLevel8190() channel = %d\n", priv->ieee80211->current_network.channel); - - - rtl8192_phy_setTxPower(priv, priv->ieee80211->current_network.channel); - - } - priv->bLastDTPFlag_High = priv->bDynamicTxHighPower; - priv->bLastDTPFlag_Low = priv->bDynamicTxLowPower; - -} - -//added by vivi, for read tx rate and retrycount -static void dm_check_txrateandretrycount(struct r8192_priv *priv) -{ - struct ieee80211_device* ieee = priv->ieee80211; - - //for initial tx rate - ieee->softmac_stats.last_packet_rate = read_nic_byte(priv ,Initial_Tx_Rate_Reg); - //for tx tx retry count - ieee->softmac_stats.txretrycount = read_nic_dword(priv, Tx_Retry_Count_Reg); -} - -static void dm_send_rssi_tofw(struct r8192_priv *priv) -{ - // If we test chariot, we should stop the TX command ? - // Because 92E will always silent reset when we send tx command. We use register - // 0x1e0(byte) to botify driver. - write_nic_byte(priv, DRIVER_RSSI, (u8)priv->undecorated_smoothed_pwdb); - return; -} - diff --git a/drivers/staging/rtl8192e/r8192E_dm.h b/drivers/staging/rtl8192e/r8192E_dm.h deleted file mode 100644 index b5b34ea..0000000 --- a/drivers/staging/rtl8192e/r8192E_dm.h +++ /dev/null @@ -1,228 +0,0 @@ -/***************************************************************************** - * Copyright(c) 2007, RealTEK Technology Inc. All Right Reserved. - * - * Module: Hal819xUsbDM.h (RTL8192 Header H File) - * - * - * Note: For dynamic control definition constant structure. - * - * - * Export: - * - * Abbrev: - * - * History: - * Data Who Remark - * 10/04/2007 MHC Create initial version. - * - *****************************************************************************/ - -#ifndef __R8192UDM_H__ -#define __R8192UDM_H__ - -#define OFDM_Table_Length 19 -#define CCK_Table_length 12 - -#define DM_DIG_THRESH_HIGH 40 -#define DM_DIG_THRESH_LOW 35 - -#define DM_DIG_HIGH_PWR_THRESH_HIGH 75 -#define DM_DIG_HIGH_PWR_THRESH_LOW 70 - -#define BW_AUTO_SWITCH_HIGH_LOW 25 -#define BW_AUTO_SWITCH_LOW_HIGH 30 - -#define DM_check_fsync_time_interval 500 - - -#define DM_DIG_BACKOFF 12 -#define DM_DIG_MAX 0x36 -#define DM_DIG_MIN 0x1c -#define DM_DIG_MIN_Netcore 0x12 - -#define RxPathSelection_SS_TH_low 30 -#define RxPathSelection_diff_TH 18 - -#define RateAdaptiveTH_High 50 -#define RateAdaptiveTH_Low_20M 30 -#define RateAdaptiveTH_Low_40M 10 -#define VeryLowRSSI 15 -#define CTSToSelfTHVal 35 - -//defined by vivi, for tx power track -#define E_FOR_TX_POWER_TRACK 300 -//Dynamic Tx Power Control Threshold -#define TX_POWER_NEAR_FIELD_THRESH_HIGH 68 -#define TX_POWER_NEAR_FIELD_THRESH_LOW 62 -//added by amy for atheros AP -#define TX_POWER_ATHEROAP_THRESH_HIGH 78 -#define TX_POWER_ATHEROAP_THRESH_LOW 72 - -//defined by vivi, for showing on UI. Newer firmware has changed to 0x1e0 -#define Current_Tx_Rate_Reg 0x1e0//0x1b8 -#define Initial_Tx_Rate_Reg 0x1e1 //0x1b9 -#define Tx_Retry_Count_Reg 0x1ac -#define RegC38_TH 20 - -/* 2007/10/04 MH Define upper and lower threshold of DIG enable or disable. */ -typedef struct _dynamic_initial_gain_threshold_ -{ - u8 dig_enable_flag; - u8 dig_algorithm; - u8 dbg_mode; - u8 dig_algorithm_switch; - - long rssi_low_thresh; - long rssi_high_thresh; - - long rssi_high_power_lowthresh; - long rssi_high_power_highthresh; - - u8 dig_state; - u8 dig_highpwr_state; - u8 cur_connect_state; - u8 pre_connect_state; - - u8 curpd_thstate; - u8 prepd_thstate; - u8 curcs_ratio_state; - u8 precs_ratio_state; - - u32 pre_ig_value; - u32 cur_ig_value; - - u8 backoff_val; - u8 rx_gain_range_max; - u8 rx_gain_range_min; - bool initialgain_lowerbound_state; - - long rssi_val; -}dig_t; - -typedef enum tag_dynamic_init_gain_state_definition -{ - DM_STA_DIG_OFF = 0, - DM_STA_DIG_ON, - DM_STA_DIG_MAX -}dm_dig_sta_e; - - -/* 2007/10/08 MH Define RATR state. */ -typedef enum tag_dynamic_ratr_state_definition -{ - DM_RATR_STA_HIGH = 0, - DM_RATR_STA_MIDDLE = 1, - DM_RATR_STA_LOW = 2, - DM_RATR_STA_MAX -}dm_ratr_sta_e; - -/* 2007/10/11 MH Define DIG operation type. */ -typedef enum tag_dynamic_init_gain_operation_type_definition -{ - DIG_TYPE_THRESH_HIGH = 0, - DIG_TYPE_THRESH_LOW = 1, - DIG_TYPE_THRESH_HIGHPWR_HIGH = 2, - DIG_TYPE_THRESH_HIGHPWR_LOW = 3, - DIG_TYPE_DBG_MODE = 4, - DIG_TYPE_RSSI = 5, - DIG_TYPE_ALGORITHM = 6, - DIG_TYPE_BACKOFF = 7, - DIG_TYPE_PWDB_FACTOR = 8, - DIG_TYPE_RX_GAIN_MIN = 9, - DIG_TYPE_RX_GAIN_MAX = 10, - DIG_TYPE_ENABLE = 20, - DIG_TYPE_DISABLE = 30, - DIG_OP_TYPE_MAX -}dm_dig_op_e; - -typedef enum tag_dig_algorithm_definition -{ - DIG_ALGO_BY_FALSE_ALARM = 0, - DIG_ALGO_BY_RSSI = 1, - DIG_ALGO_MAX -}dm_dig_alg_e; - -typedef enum tag_dig_dbgmode_definition -{ - DIG_DBG_OFF = 0, - DIG_DBG_ON = 1, - DIG_DBG_MAX -}dm_dig_dbg_e; - -typedef enum tag_dig_connect_definition -{ - DIG_DISCONNECT = 0, - DIG_CONNECT = 1, - DIG_CONNECT_MAX -}dm_dig_connect_e; - -typedef enum tag_dig_packetdetection_threshold_definition -{ - DIG_PD_AT_LOW_POWER = 0, - DIG_PD_AT_NORMAL_POWER = 1, - DIG_PD_AT_HIGH_POWER = 2, - DIG_PD_MAX -}dm_dig_pd_th_e; - -typedef enum tag_dig_cck_cs_ratio_state_definition -{ - DIG_CS_RATIO_LOWER = 0, - DIG_CS_RATIO_HIGHER = 1, - DIG_CS_MAX -}dm_dig_cs_ratio_e; -typedef struct _Dynamic_Rx_Path_Selection_ -{ - u8 Enable; - u8 DbgMode; - u8 cck_method; - u8 cck_Rx_path; - - u8 SS_TH_low; - u8 diff_TH; - u8 disabledRF; - u8 reserved; - - u8 rf_rssi[4]; - u8 rf_enable_rssi_th[4]; - long cck_pwdb_sta[4]; -}DRxPathSel; - -typedef enum tag_CCK_Rx_Path_Method_Definition -{ - CCK_Rx_Version_1 = 0, - CCK_Rx_Version_2= 1, - CCK_Rx_Version_MAX -}DM_CCK_Rx_Path_Method; - -typedef enum tag_DM_DbgMode_Definition -{ - DM_DBG_OFF = 0, - DM_DBG_ON = 1, - DM_DBG_MAX -}DM_DBG_E; - -typedef struct tag_Tx_Config_Cmd_Format -{ - u32 Op; /* Command packet type. */ - u32 Length; /* Command packet length. */ - u32 Value; -}DCMD_TXCMD_T, *PDCMD_TXCMD_T; - - -extern dig_t dm_digtable; -extern DRxPathSel DM_RxPathSelTable; - -void init_hal_dm(struct r8192_priv *priv); -void deinit_hal_dm(struct r8192_priv *priv); - -void hal_dm_watchdog(struct r8192_priv *priv); - -void init_rate_adaptive(struct r8192_priv *priv); -void dm_txpower_trackingcallback(struct work_struct *work); -void dm_rf_pathcheck_workitemcallback(struct work_struct *work); -void dm_initialize_txpower_tracking(struct r8192_priv *priv); -void dm_cck_txpower_adjust(struct r8192_priv *priv, bool binch14); - - -#endif /*__R8192UDM_H__ */ - diff --git a/drivers/staging/rtl8192e/r8192E_firmware.c b/drivers/staging/rtl8192e/r8192E_firmware.c new file mode 100644 index 0000000..3771985 --- /dev/null +++ b/drivers/staging/rtl8192e/r8192E_firmware.c @@ -0,0 +1,348 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> +******************************************************************************/ + +#include "rtl_core.h" +#include "r8192E_hw.h" +#include "r8192E_hwimg.h" +#include "r8192E_firmware.h" +#include <linux/firmware.h> + +void firmware_init_param(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + struct rt_firmware *pfirmware = priv->pFirmware; + + pfirmware->cmdpacket_frag_thresold = GET_COMMAND_PACKET_FRAG_THRESHOLD( + MAX_TRANSMIT_BUFFER_SIZE); +} + +static bool fw_download_code(struct net_device *dev, u8 *code_virtual_address, + u32 buffer_len) +{ + struct r8192_priv *priv = rtllib_priv(dev); + bool rt_status = true; + u16 frag_threshold; + u16 frag_length, frag_offset = 0; + int i; + + struct rt_firmware *pfirmware = priv->pFirmware; + struct sk_buff *skb; + unsigned char *seg_ptr; + struct cb_desc *tcb_desc; + u8 bLastIniPkt; + + firmware_init_param(dev); + frag_threshold = pfirmware->cmdpacket_frag_thresold; + do { + if ((buffer_len - frag_offset) > frag_threshold) { + frag_length = frag_threshold ; + bLastIniPkt = 0; + + } else { + frag_length = buffer_len - frag_offset; + bLastIniPkt = 1; + + } + + skb = dev_alloc_skb(frag_length + 4); + memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev)); + tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); + tcb_desc->queue_index = TXCMD_QUEUE; + tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_INIT; + tcb_desc->bLastIniPkt = bLastIniPkt; + + seg_ptr = skb->data; + for (i = 0; i < frag_length; i += 4) { + *seg_ptr++ = ((i+0) < frag_length) ? + code_virtual_address[i+3] : 0; + *seg_ptr++ = ((i+1) < frag_length) ? + code_virtual_address[i+2] : 0; + *seg_ptr++ = ((i+2) < frag_length) ? + code_virtual_address[i+1] : 0; + *seg_ptr++ = ((i+3) < frag_length) ? + code_virtual_address[i+0] : 0; + } + tcb_desc->txbuf_size = (u16)i; + skb_put(skb, i); + + if (!priv->rtllib->check_nic_enough_desc(dev, tcb_desc->queue_index) || + (!skb_queue_empty(&priv->rtllib->skb_waitQ[tcb_desc->queue_index])) || + (priv->rtllib->queue_stop)) { + RT_TRACE(COMP_FIRMWARE, "===================> tx " + "full!\n"); + skb_queue_tail(&priv->rtllib->skb_waitQ + [tcb_desc->queue_index], skb); + } else { + priv->rtllib->softmac_hard_start_xmit(skb, dev); + } + + code_virtual_address += frag_length; + frag_offset += frag_length; + + } while (frag_offset < buffer_len); + + write_nic_byte(dev, TPPoll, TPPoll_CQ); + + return rt_status; +} + +static bool CPUcheck_maincodeok_turnonCPU(struct net_device *dev) +{ + bool rt_status = true; + u32 CPU_status = 0; + unsigned long timeout; + + timeout = jiffies + MSECS(200); + while (time_before(jiffies, timeout)) { + CPU_status = read_nic_dword(dev, CPU_GEN); + if (CPU_status & CPU_GEN_PUT_CODE_OK) + break; + mdelay(2); + } + + if (!(CPU_status&CPU_GEN_PUT_CODE_OK)) { + RT_TRACE(COMP_ERR, "Download Firmware: Put code fail!\n"); + goto CPUCheckMainCodeOKAndTurnOnCPU_Fail; + } else { + RT_TRACE(COMP_FIRMWARE, "Download Firmware: Put code ok!\n"); + } + + CPU_status = read_nic_dword(dev, CPU_GEN); + write_nic_byte(dev, CPU_GEN, + (u8)((CPU_status|CPU_GEN_PWR_STB_CPU)&0xff)); + mdelay(1); + + timeout = jiffies + MSECS(200); + while (time_before(jiffies, timeout)) { + CPU_status = read_nic_dword(dev, CPU_GEN); + if (CPU_status&CPU_GEN_BOOT_RDY) + break; + mdelay(2); + } + + if (!(CPU_status&CPU_GEN_BOOT_RDY)) + goto CPUCheckMainCodeOKAndTurnOnCPU_Fail; + else + RT_TRACE(COMP_FIRMWARE, "Download Firmware: Boot ready!\n"); + + return rt_status; + +CPUCheckMainCodeOKAndTurnOnCPU_Fail: + RT_TRACE(COMP_ERR, "ERR in %s()\n", __func__); + rt_status = false; + return rt_status; +} + +static bool CPUcheck_firmware_ready(struct net_device *dev) +{ + + bool rt_status = true; + u32 CPU_status = 0; + unsigned long timeout; + + timeout = jiffies + MSECS(20); + while (time_before(jiffies, timeout)) { + CPU_status = read_nic_dword(dev, CPU_GEN); + if (CPU_status&CPU_GEN_FIRM_RDY) + break; + mdelay(2); + } + + if (!(CPU_status&CPU_GEN_FIRM_RDY)) + goto CPUCheckFirmwareReady_Fail; + else + RT_TRACE(COMP_FIRMWARE, "Download Firmware: Firmware ready!\n"); + + return rt_status; + +CPUCheckFirmwareReady_Fail: + RT_TRACE(COMP_ERR, "ERR in %s()\n", __func__); + rt_status = false; + return rt_status; + +} + +static bool firmware_check_ready(struct net_device *dev, + u8 load_fw_status) +{ + struct r8192_priv *priv = rtllib_priv(dev); + struct rt_firmware *pfirmware = priv->pFirmware; + bool rt_status = true; + + switch (load_fw_status) { + case FW_INIT_STEP0_BOOT: + pfirmware->firmware_status = FW_STATUS_1_MOVE_BOOT_CODE; + break; + + case FW_INIT_STEP1_MAIN: + pfirmware->firmware_status = FW_STATUS_2_MOVE_MAIN_CODE; + + rt_status = CPUcheck_maincodeok_turnonCPU(dev); + if (rt_status) + pfirmware->firmware_status = FW_STATUS_3_TURNON_CPU; + else + RT_TRACE(COMP_FIRMWARE, "CPUcheck_maincodeok_turnon" + "CPU fail!\n"); + + break; + + case FW_INIT_STEP2_DATA: + pfirmware->firmware_status = FW_STATUS_4_MOVE_DATA_CODE; + mdelay(1); + + rt_status = CPUcheck_firmware_ready(dev); + if (rt_status) + pfirmware->firmware_status = FW_STATUS_5_READY; + else + RT_TRACE(COMP_FIRMWARE, "CPUcheck_firmware_ready fail" + "(%d)!\n", rt_status); + + break; + default: + rt_status = false; + RT_TRACE(COMP_FIRMWARE, "Unknown firware status"); + break; + } + + return rt_status; +} + +bool init_firmware(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + bool rt_status = true; + + u8 *firmware_img_buf[3] = { &Rtl8192PciEFwBootArray[0], + &Rtl8192PciEFwMainArray[0], + &Rtl8192PciEFwDataArray[0]}; + + u32 firmware_img_len[3] = { sizeof(Rtl8192PciEFwBootArray), + sizeof(Rtl8192PciEFwMainArray), + sizeof(Rtl8192PciEFwDataArray)}; + u32 file_length = 0; + u8 *mapped_file = NULL; + u8 init_step = 0; + enum opt_rst_type rst_opt = OPT_SYSTEM_RESET; + enum firmware_init_step starting_state = FW_INIT_STEP0_BOOT; + + struct rt_firmware *pfirmware = priv->pFirmware; + + RT_TRACE(COMP_FIRMWARE, " PlatformInitFirmware()==>\n"); + + if (pfirmware->firmware_status == FW_STATUS_0_INIT) { + rst_opt = OPT_SYSTEM_RESET; + starting_state = FW_INIT_STEP0_BOOT; + + } else if (pfirmware->firmware_status == FW_STATUS_5_READY) { + rst_opt = OPT_FIRMWARE_RESET; + starting_state = FW_INIT_STEP2_DATA; + } else { + RT_TRACE(COMP_FIRMWARE, "PlatformInitFirmware: undefined" + " firmware state\n"); + } + + priv->firmware_source = FW_SOURCE_IMG_FILE; + for (init_step = starting_state; init_step <= FW_INIT_STEP2_DATA; + init_step++) { + if (rst_opt == OPT_SYSTEM_RESET) { + switch (priv->firmware_source) { + case FW_SOURCE_IMG_FILE: + { + if (pfirmware->firmware_buf_size[init_step] == 0) { + const char *fw_name[3] = { "RTL8192E/boot.img", + "RTL8192E/main.img", + "RTL8192E/data.img" + }; + const struct firmware *fw_entry; + int rc; + rc = request_firmware(&fw_entry, + fw_name[init_step], &priv->pdev->dev); + if (rc < 0) { + RT_TRACE(COMP_FIRMWARE, "request firm" + "ware fail!\n"); + goto download_firmware_fail; + } + if (fw_entry->size > + sizeof(pfirmware->firmware_buf[init_step])) { + RT_TRACE(COMP_FIRMWARE, "img file size " + "exceed the container struct " + "buffer fail!\n"); + goto download_firmware_fail; + } + + if (init_step != FW_INIT_STEP1_MAIN) { + memcpy(pfirmware->firmware_buf[init_step], + fw_entry->data, fw_entry->size); + pfirmware->firmware_buf_size[init_step] = + fw_entry->size; + + } else { + memset(pfirmware->firmware_buf[init_step], + 0, 128); + memcpy(&pfirmware->firmware_buf[init_step][128], + fw_entry->data, fw_entry->size); + pfirmware->firmware_buf_size[init_step] = + fw_entry->size + 128; + } + + if (rst_opt == OPT_SYSTEM_RESET) + release_firmware(fw_entry); + } + mapped_file = pfirmware->firmware_buf[init_step]; + file_length = pfirmware->firmware_buf_size[init_step]; + break; + } + case FW_SOURCE_HEADER_FILE: + mapped_file = firmware_img_buf[init_step]; + file_length = firmware_img_len[init_step]; + if (init_step == FW_INIT_STEP2_DATA) { + memcpy(pfirmware->firmware_buf[init_step], mapped_file, file_length); + pfirmware->firmware_buf_size[init_step] = file_length; + } + break; + + default: + break; + } + + + } else if (rst_opt == OPT_FIRMWARE_RESET) { + mapped_file = pfirmware->firmware_buf[init_step]; + file_length = pfirmware->firmware_buf_size[init_step]; + } + + rt_status = fw_download_code(dev, mapped_file, file_length); + if (rt_status != true) { + goto download_firmware_fail; + } + + if (!firmware_check_ready(dev, init_step)) { + goto download_firmware_fail; + } + } + + RT_TRACE(COMP_FIRMWARE, "Firmware Download Success\n"); + return rt_status; + +download_firmware_fail: + RT_TRACE(COMP_ERR, "ERR in %s()\n", __func__); + rt_status = false; + return rt_status; + +} diff --git a/drivers/staging/rtl8192e/r8192E_firmware.h b/drivers/staging/rtl8192e/r8192E_firmware.h new file mode 100644 index 0000000..caa8788 --- /dev/null +++ b/drivers/staging/rtl8192e/r8192E_firmware.h @@ -0,0 +1,73 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> +******************************************************************************/ +#ifndef __INC_FIRMWARE_H +#define __INC_FIRMWARE_H + +#define RTL8190_CPU_START_OFFSET 0x80 + +#define GET_COMMAND_PACKET_FRAG_THRESHOLD(v) (4*(v/4) - 8) + +enum firmware_init_step { + FW_INIT_STEP0_BOOT = 0, + FW_INIT_STEP1_MAIN = 1, + FW_INIT_STEP2_DATA = 2, +}; + +enum opt_rst_type { + OPT_SYSTEM_RESET = 0, + OPT_FIRMWARE_RESET = 1, +}; + +enum desc_packet_type { + DESC_PACKET_TYPE_INIT = 0, + DESC_PACKET_TYPE_NORMAL = 1, +}; + +enum firmware_source { + FW_SOURCE_IMG_FILE = 0, + FW_SOURCE_HEADER_FILE = 1, +}; + +enum firmware_status { + FW_STATUS_0_INIT = 0, + FW_STATUS_1_MOVE_BOOT_CODE = 1, + FW_STATUS_2_MOVE_MAIN_CODE = 2, + FW_STATUS_3_TURNON_CPU = 3, + FW_STATUS_4_MOVE_DATA_CODE = 4, + FW_STATUS_5_READY = 5, +}; + +struct fw_seg_container { + u16 seg_size; + u8 *seg_ptr; +}; + +struct rt_firmware { + enum firmware_status firmware_status; + u16 cmdpacket_frag_thresold; +#define RTL8190_MAX_FIRMWARE_CODE_SIZE 64000 +#define MAX_FW_INIT_STEP 3 + u8 firmware_buf[MAX_FW_INIT_STEP][RTL8190_MAX_FIRMWARE_CODE_SIZE]; + u16 firmware_buf_size[MAX_FW_INIT_STEP]; +}; + +bool init_firmware(struct net_device *dev); +extern void firmware_init_param(struct net_device *dev); + +#endif diff --git a/drivers/staging/rtl8192e/r8192E_hw.h b/drivers/staging/rtl8192e/r8192E_hw.h index 24e7303..43c3fb8 100644 --- a/drivers/staging/rtl8192e/r8192E_hw.h +++ b/drivers/staging/rtl8192e/r8192E_hw.h @@ -1,49 +1,36 @@ -/* - This is part of rtl8187 OpenSource driver. - Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it> - Released under the terms of GPL (General Public Licence) +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> +******************************************************************************/ - Parts of this driver are based on the GPL part of the - official Realtek driver. - Parts of this driver are based on the rtl8180 driver skeleton - from Patric Schenke & Andres Salomon. - Parts of this driver are based on the Intel Pro Wireless - 2100 GPL driver. - We want to tanks the Authors of those projects - and the Ndiswrapper project Authors. -*/ - -/* Mariusz Matuszek added full registers definition with Realtek's name */ - -/* this file contains register definitions for the rtl8187 MAC controller */ #ifndef R8180_HW #define R8180_HW -typedef enum _VERSION_8190{ - VERSION_8190_BD=0x3, - VERSION_8190_BE -}VERSION_8190,*PVERSION_8190; -//added for different RF type -typedef enum _RT_RF_TYPE_DEF -{ - RF_1T2R = 0, - RF_2T4R, - - RF_819X_MAX_TYPE -}RT_RF_TYPE_DEF; - -typedef enum _BaseBand_Config_Type{ - BaseBand_Config_PHY_REG = 0, //Radio Path A - BaseBand_Config_AGC_TAB = 1, //Radio Path B -}BaseBand_Config_Type, *PBaseBand_Config_Type; +enum baseband_config { + BaseBand_Config_PHY_REG = 0, + BaseBand_Config_AGC_TAB = 1, +}; #define RTL8187_REQT_READ 0xc0 #define RTL8187_REQT_WRITE 0x40 #define RTL8187_REQ_GET_REGS 0x05 #define RTL8187_REQ_SET_REGS 0x05 -#define R8180_MAX_RETRY 255 #define MAX_TX_URB 5 #define MAX_RX_URB 16 #define RX_URB_SIZE 9100 @@ -65,14 +52,14 @@ typedef enum _BaseBand_Config_Type{ #define EEPROM_TxPowerDiff 0x1F -#define EEPROM_PwDiff 0x21 //0x21 -#define EEPROM_CrystalCap 0x22 //0x22 +#define EEPROM_PwDiff 0x21 +#define EEPROM_CrystalCap 0x22 -#define EEPROM_TxPwIndex_CCK_V1 0x29 //0x29~0x2B -#define EEPROM_TxPwIndex_OFDM_24G_V1 0x2C //0x2C~0x2E -#define EEPROM_TxPwIndex_Ver 0x27 //0x27 +#define EEPROM_TxPwIndex_CCK_V1 0x29 +#define EEPROM_TxPwIndex_OFDM_24G_V1 0x2C +#define EEPROM_TxPwIndex_Ver 0x27 #define EEPROM_Default_TxPowerDiff 0x0 #define EEPROM_Default_ThermalMeter 0x77 @@ -81,42 +68,35 @@ typedef enum _BaseBand_Config_Type{ #define EEPROM_Default_PwDiff 0x4 #define EEPROM_Default_CrystalCap 0x5 #define EEPROM_Default_TxPower 0x1010 -#define EEPROM_ICVersion_ChannelPlan 0x7C //0x7C:ChannelPlan, 0x7D:IC_Version -#define EEPROM_Customer_ID 0x7B //0x7B:CustomerID - +#define EEPROM_ICVersion_ChannelPlan 0x7C +#define EEPROM_Customer_ID 0x7B #define EEPROM_RFInd_PowerDiff 0x28 #define EEPROM_ThermalMeter 0x29 -#define EEPROM_TxPwDiff_CrystalCap 0x2A //0x2A~0x2B -#define EEPROM_TxPwIndex_CCK 0x2C //0x23 -#define EEPROM_TxPwIndex_OFDM_24G 0x3A //0x24~0x26 - +#define EEPROM_TxPwDiff_CrystalCap 0x2A +#define EEPROM_TxPwIndex_CCK 0x2C +#define EEPROM_TxPwIndex_OFDM_24G 0x3A #define EEPROM_Default_TxPowerLevel 0x10 - -#define EEPROM_IC_VER 0x7d //0x7D -#define EEPROM_CRC 0x7e //0x7E~0x7F +#define EEPROM_IC_VER 0x7d +#define EEPROM_CRC 0x7e #define EEPROM_CID_DEFAULT 0x0 #define EEPROM_CID_CAMEO 0x1 #define EEPROM_CID_RUNTOP 0x2 #define EEPROM_CID_Senao 0x3 -#define EEPROM_CID_TOSHIBA 0x4 // Toshiba setting, Merge by Jacken, 2008/01/31 +#define EEPROM_CID_TOSHIBA 0x4 #define EEPROM_CID_NetCore 0x5 #define EEPROM_CID_Nettronix 0x6 #define EEPROM_CID_Pronet 0x7 #define EEPROM_CID_DLINK 0x8 -#define EEPROM_CID_WHQL 0xFE //added by sherry for dtm, 20080728 - +#define EEPROM_CID_WHQL 0xFE enum _RTL8192Pci_HW { - MAC0 = 0x000, - MAC1 = 0x001, - MAC2 = 0x002, - MAC3 = 0x003, - MAC4 = 0x004, - MAC5 = 0x005, - PCIF = 0x009, // PCI Function Register 0x0009h~0x000bh -//---------------------------------------------------------------------------- -// 8190 PCIF bits (Offset 0x009-000b, 24bit) -//---------------------------------------------------------------------------- + MAC0 = 0x000, + MAC1 = 0x001, + MAC2 = 0x002, + MAC3 = 0x003, + MAC4 = 0x004, + MAC5 = 0x005, + PCIF = 0x009, #define MXDMA2_16bytes 0x000 #define MXDMA2_32bytes 0x001 #define MXDMA2_64bytes 0x010 @@ -129,8 +109,8 @@ enum _RTL8192Pci_HW { #define MULRW_SHIFT 3 #define MXDMA2_RX_SHIFT 4 #define MXDMA2_TX_SHIFT 0 - PMR = 0x00c, // Power management register - EPROM_CMD = 0x00e, + PMR = 0x00c, + EPROM_CMD = 0x00e, #define EPROM_CMD_RESERVED_MASK BIT5 #define EPROM_CMD_9356SEL BIT4 #define EPROM_CMD_OPERATING_MODE_SHIFT 6 @@ -151,71 +131,66 @@ enum _RTL8192Pci_HW { ANAPAR = 0x17, #define BB_GLOBAL_RESET_BIT 0x1 - BB_GLOBAL_RESET = 0x020, // BasebandGlobal Reset Register - BSSIDR = 0x02E, // BSSID Register - CMDR = 0x037, // Command register -#define CR_RST 0x10 -#define CR_RE 0x08 -#define CR_TE 0x04 -#define CR_MulRW 0x01 - SIFS = 0x03E, // SIFS register - TCR = 0x040, // Transmit Configuration Register - RCR = 0x044, // Receive Configuration Register -//---------------------------------------------------------------------------- -//// 8190 (RCR) Receive Configuration Register (Offset 0x44~47, 32 bit) -////---------------------------------------------------------------------------- -#define RCR_FILTER_MASK (BIT0|BIT1|BIT2|BIT3|BIT5|BIT12|BIT18|BIT19|BIT20|BIT21|BIT22|BIT23) -#define RCR_ONLYERLPKT BIT31 // Early Receiving based on Packet Size. -#define RCR_ENCS2 BIT30 // Enable Carrier Sense Detection Method 2 -#define RCR_ENCS1 BIT29 // Enable Carrier Sense Detection Method 1 -#define RCR_ENMBID BIT27 // Enable Multiple BssId. -#define RCR_ACKTXBW (BIT24|BIT25) // TXBW Setting of ACK frames -#define RCR_CBSSID BIT23 // Accept BSSID match packet -#define RCR_APWRMGT BIT22 // Accept power management packet -#define RCR_ADD3 BIT21 // Accept address 3 match packet -#define RCR_AMF BIT20 // Accept management type frame -#define RCR_ACF BIT19 // Accept control type frame -#define RCR_ADF BIT18 // Accept data type frame -#define RCR_RXFTH BIT13 // Rx FIFO Threshold -#define RCR_AICV BIT12 // Accept ICV error packet -#define RCR_ACRC32 BIT5 // Accept CRC32 error packet -#define RCR_AB BIT3 // Accept broadcast packet -#define RCR_AM BIT2 // Accept multicast packet -#define RCR_APM BIT1 // Accept physical match packet -#define RCR_AAP BIT0 // Accept all unicast packet + BB_GLOBAL_RESET = 0x020, + BSSIDR = 0x02E, + CMDR = 0x037, +#define CR_RST 0x10 +#define CR_RE 0x08 +#define CR_TE 0x04 +#define CR_MulRW 0x01 + SIFS = 0x03E, + TCR = 0x040, + RCR = 0x044, +#define RCR_FILTER_MASK (BIT0 | BIT1 | BIT2 | BIT3 | BIT5 | BIT12 | \ + BIT18 | BIT19 | BIT20 | BIT21 | BIT22 | BIT23) +#define RCR_ONLYERLPKT BIT31 +#define RCR_ENCS2 BIT30 +#define RCR_ENCS1 BIT29 +#define RCR_ENMBID BIT27 +#define RCR_ACKTXBW (BIT24|BIT25) +#define RCR_CBSSID BIT23 +#define RCR_APWRMGT BIT22 +#define RCR_ADD3 BIT21 +#define RCR_AMF BIT20 +#define RCR_ACF BIT19 +#define RCR_ADF BIT18 +#define RCR_RXFTH BIT13 +#define RCR_AICV BIT12 +#define RCR_ACRC32 BIT5 +#define RCR_AB BIT3 +#define RCR_AM BIT2 +#define RCR_APM BIT1 +#define RCR_AAP BIT0 #define RCR_MXDMA_OFFSET 8 #define RCR_FIFO_OFFSET 13 - SLOT_TIME = 0x049, // Slot Time Register - ACK_TIMEOUT = 0x04c, // Ack Timeout Register - PIFS_TIME = 0x04d, // PIFS time - USTIME = 0x04e, // Microsecond Tuning Register, Sets the microsecond time unit used by MAC clock. - EDCAPARA_BE = 0x050, // EDCA Parameter of AC BE - EDCAPARA_BK = 0x054, // EDCA Parameter of AC BK - EDCAPARA_VO = 0x058, // EDCA Parameter of AC VO - EDCAPARA_VI = 0x05C, // EDCA Parameter of AC VI + SLOT_TIME = 0x049, + ACK_TIMEOUT = 0x04c, + PIFS_TIME = 0x04d, + USTIME = 0x04e, + EDCAPARA_BE = 0x050, + EDCAPARA_BK = 0x054, + EDCAPARA_VO = 0x058, + EDCAPARA_VI = 0x05C, #define AC_PARAM_TXOP_LIMIT_OFFSET 16 #define AC_PARAM_ECW_MAX_OFFSET 12 #define AC_PARAM_ECW_MIN_OFFSET 8 #define AC_PARAM_AIFS_OFFSET 0 - RFPC = 0x05F, // Rx FIFO Packet Count - CWRR = 0x060, // Contention Window Report Register - BCN_TCFG = 0x062, // Beacon Time Configuration + RFPC = 0x05F, + CWRR = 0x060, + BCN_TCFG = 0x062, #define BCN_TCFG_CW_SHIFT 8 #define BCN_TCFG_IFS 0 - BCN_INTERVAL = 0x070, // Beacon Interval (TU) - ATIMWND = 0x072, // ATIM Window Size (TU) - BCN_DRV_EARLY_INT = 0x074, // Driver Early Interrupt Time (TU). Time to send interrupt to notify to change beacon content before TBTT + BCN_INTERVAL = 0x070, + ATIMWND = 0x072, + BCN_DRV_EARLY_INT = 0x074, #define BCN_DRV_EARLY_INT_SWBCN_SHIFT 8 #define BCN_DRV_EARLY_INT_TIME_SHIFT 0 - BCN_DMATIME = 0x076, // Beacon DMA and ATIM interrupt time (US). Indicates the time before TBTT to perform beacon queue DMA - BCN_ERR_THRESH = 0x078, // Beacon Error Threshold - RWCAM = 0x0A0, //IN 8190 Data Sheet is called CAMcmd - //---------------------------------------------------------------------------- - //// 8190 CAM Command Register (offset 0xA0, 4 byte) - ////---------------------------------------------------------------------------- -#define CAM_CM_SecCAMPolling BIT31 //Security CAM Polling -#define CAM_CM_SecCAMClr BIT30 //Clear all bits in CAM -#define CAM_CM_SecCAMWE BIT16 //Security CAM enable + BCN_DMATIME = 0x076, + BCN_ERR_THRESH = 0x078, + RWCAM = 0x0A0, +#define CAM_CM_SecCAMPolling BIT31 +#define CAM_CM_SecCAMClr BIT30 +#define CAM_CM_SecCAMWE BIT16 #define CAM_VALID BIT15 #define CAM_NOTVALID 0x0000 #define CAM_USEDK BIT5 @@ -234,68 +209,62 @@ enum _RTL8192Pci_HW { #define CAM_READ 0x00000000 #define CAM_POLLINIG BIT31 #define SCR_UseDK 0x01 - WCAMI = 0x0A4, // Software write CAM input content - RCAMO = 0x0A8, // Software read/write CAM config - SECR = 0x0B0, //Security Configuration Register -#define SCR_TxUseDK BIT0 //Force Tx Use Default Key -#define SCR_RxUseDK BIT1 //Force Rx Use Default Key -#define SCR_TxEncEnable BIT2 //Enable Tx Encryption -#define SCR_RxDecEnable BIT3 //Enable Rx Decryption -#define SCR_SKByA2 BIT4 //Search kEY BY A2 -#define SCR_NoSKMC BIT5 //No Key Search for Multicast - SWREGULATOR = 0x0BD, // Switching Regulator - INTA_MASK = 0x0f4, -//---------------------------------------------------------------------------- -// 8190 IMR/ISR bits (offset 0xfd, 8bits) -//---------------------------------------------------------------------------- + WCAMI = 0x0A4, + RCAMO = 0x0A8, + SECR = 0x0B0, +#define SCR_TxUseDK BIT0 +#define SCR_RxUseDK BIT1 +#define SCR_TxEncEnable BIT2 +#define SCR_RxDecEnable BIT3 +#define SCR_SKByA2 BIT4 +#define SCR_NoSKMC BIT5 + SWREGULATOR = 0x0BD, + INTA_MASK = 0x0f4, #define IMR8190_DISABLED 0x0 -#define IMR_ATIMEND BIT28 // ATIM Window End Interrupt -#define IMR_TBDOK BIT27 // Transmit Beacon OK Interrupt -#define IMR_TBDER BIT26 // Transmit Beacon Error Interrupt -#define IMR_TXFOVW BIT15 // Transmit FIFO Overflow -#define IMR_TIMEOUT0 BIT14 // TimeOut0 -#define IMR_BcnInt BIT13 // Beacon DMA Interrupt 0 -#define IMR_RXFOVW BIT12 // Receive FIFO Overflow -#define IMR_RDU BIT11 // Receive Descriptor Unavailable -#define IMR_RXCMDOK BIT10 // Receive Command Packet OK -#define IMR_BDOK BIT9 // Beacon Queue DMA OK Interrup -#define IMR_HIGHDOK BIT8 // High Queue DMA OK Interrupt -#define IMR_COMDOK BIT7 // Command Queue DMA OK Interrupt -#define IMR_MGNTDOK BIT6 // Management Queue DMA OK Interrupt -#define IMR_HCCADOK BIT5 // HCCA Queue DMA OK Interrupt -#define IMR_BKDOK BIT4 // AC_BK DMA OK Interrupt -#define IMR_BEDOK BIT3 // AC_BE DMA OK Interrupt -#define IMR_VIDOK BIT2 // AC_VI DMA OK Interrupt -#define IMR_VODOK BIT1 // AC_VO DMA Interrupt -#define IMR_ROK BIT0 // Receive DMA OK Interrupt - ISR = 0x0f8, // Interrupt Status Register - TPPoll = 0x0fd, // Transmit priority polling register -#define TPPoll_BKQ BIT0 // BK queue polling -#define TPPoll_BEQ BIT1 // BE queue polling -#define TPPoll_VIQ BIT2 // VI queue polling -#define TPPoll_VOQ BIT3 // VO queue polling -#define TPPoll_BQ BIT4 // Beacon queue polling -#define TPPoll_CQ BIT5 // Command queue polling -#define TPPoll_MQ BIT6 // Management queue polling -#define TPPoll_HQ BIT7 // High queue polling -#define TPPoll_HCCAQ BIT8 // HCCA queue polling -#define TPPoll_StopBK BIT9 // Stop BK queue -#define TPPoll_StopBE BIT10 // Stop BE queue -#define TPPoll_StopVI BIT11 // Stop VI queue -#define TPPoll_StopVO BIT12 // Stop VO queue -#define TPPoll_StopMgt BIT13 // Stop Mgnt queue -#define TPPoll_StopHigh BIT14 // Stop High queue -#define TPPoll_StopHCCA BIT15 // Stop HCCA queue -#define TPPoll_SHIFT 8 // Queue ID mapping - - PSR = 0x0ff, // Page Select Register -#define PSR_GEN 0x0 // Page 0 register general MAC Control -#define PSR_CPU 0x1 // Page 1 register for CPU - CPU_GEN = 0x100, // CPU Reset Register - BB_RESET = 0x101, // Baseband Reset -//---------------------------------------------------------------------------- -// 8190 CPU General Register (offset 0x100, 4 byte) -//---------------------------------------------------------------------------- +#define IMR_ATIMEND BIT28 +#define IMR_TBDOK BIT27 +#define IMR_TBDER BIT26 +#define IMR_TXFOVW BIT15 +#define IMR_TIMEOUT0 BIT14 +#define IMR_BcnInt BIT13 +#define IMR_RXFOVW BIT12 +#define IMR_RDU BIT11 +#define IMR_RXCMDOK BIT10 +#define IMR_BDOK BIT9 +#define IMR_HIGHDOK BIT8 +#define IMR_COMDOK BIT7 +#define IMR_MGNTDOK BIT6 +#define IMR_HCCADOK BIT5 +#define IMR_BKDOK BIT4 +#define IMR_BEDOK BIT3 +#define IMR_VIDOK BIT2 +#define IMR_VODOK BIT1 +#define IMR_ROK BIT0 + ISR = 0x0f8, + TPPoll = 0x0fd, +#define TPPoll_BKQ BIT0 +#define TPPoll_BEQ BIT1 +#define TPPoll_VIQ BIT2 +#define TPPoll_VOQ BIT3 +#define TPPoll_BQ BIT4 +#define TPPoll_CQ BIT5 +#define TPPoll_MQ BIT6 +#define TPPoll_HQ BIT7 +#define TPPoll_HCCAQ BIT8 +#define TPPoll_StopBK BIT9 +#define TPPoll_StopBE BIT10 +#define TPPoll_StopVI BIT11 +#define TPPoll_StopVO BIT12 +#define TPPoll_StopMgt BIT13 +#define TPPoll_StopHigh BIT14 +#define TPPoll_StopHCCA BIT15 +#define TPPoll_SHIFT 8 + + PSR = 0x0ff, +#define PSR_GEN 0x0 +#define PSR_CPU 0x1 + CPU_GEN = 0x100, + BB_RESET = 0x101, #define CPU_CCK_LOOPBACK 0x00030000 #define CPU_GEN_SYSTEM_RESET 0x00000001 #define CPU_GEN_FIRMWARE_RESET 0x00000008 @@ -304,19 +273,15 @@ enum _RTL8192Pci_HW { #define CPU_GEN_PUT_CODE_OK 0x00000080 #define CPU_GEN_BB_RST 0x00000100 #define CPU_GEN_PWR_STB_CPU 0x00000004 -#define CPU_GEN_NO_LOOPBACK_MSK 0xFFF8FFFF // Set bit18,17,16 to 0. Set bit19 -#define CPU_GEN_NO_LOOPBACK_SET 0x00080000 // Set BIT19 to 1 +#define CPU_GEN_NO_LOOPBACK_MSK 0xFFF8FFFF +#define CPU_GEN_NO_LOOPBACK_SET 0x00080000 #define CPU_GEN_GPIO_UART 0x00007000 - LED1Cfg = 0x154,// LED1 Configuration Register - LED0Cfg = 0x155,// LED0 Configuration Register + LED1Cfg = 0x154, + LED0Cfg = 0x155, - AcmAvg = 0x170, // ACM Average Period Register - AcmHwCtrl = 0x171, // ACM Hardware Control Register -//---------------------------------------------------------------------------- -// -// 8190 AcmHwCtrl bits (offset 0x171, 1 byte) -//---------------------------------------------------------------------------- + AcmAvg = 0x170, + AcmHwCtrl = 0x171, #define AcmHw_HwEn BIT0 #define AcmHw_BeqEn BIT1 #define AcmHw_ViqEn BIT2 @@ -324,67 +289,65 @@ enum _RTL8192Pci_HW { #define AcmHw_BeqStatus BIT4 #define AcmHw_ViqStatus BIT5 #define AcmHw_VoqStatus BIT6 - AcmFwCtrl = 0x172, // ACM Firmware Control Register + AcmFwCtrl = 0x172, #define AcmFw_BeqStatus BIT0 #define AcmFw_ViqStatus BIT1 #define AcmFw_VoqStatus BIT2 - VOAdmTime = 0x174, // VO Queue Admitted Time Register - VIAdmTime = 0x178, // VI Queue Admitted Time Register - BEAdmTime = 0x17C, // BE Queue Admitted Time Register - RQPN1 = 0x180, // Reserved Queue Page Number , Vo Vi, Be, Bk - RQPN2 = 0x184, // Reserved Queue Page Number, HCCA, Cmd, Mgnt, High - RQPN3 = 0x188, // Reserved Queue Page Number, Bcn, Public, - QPRR = 0x1E0, // Queue Page Report per TID - QPNR = 0x1F0, // Queue Packet Number report per TID -/* there's 9 tx descriptor base address available */ - BQDA = 0x200, // Beacon Queue Descriptor Address - HQDA = 0x204, // High Priority Queue Descriptor Address - CQDA = 0x208, // Command Queue Descriptor Address - MQDA = 0x20C, // Management Queue Descriptor Address - HCCAQDA = 0x210, // HCCA Queue Descriptor Address - VOQDA = 0x214, // VO Queue Descriptor Address - VIQDA = 0x218, // VI Queue Descriptor Address - BEQDA = 0x21C, // BE Queue Descriptor Address - BKQDA = 0x220, // BK Queue Descriptor Address -/* there's 2 rx descriptor base address availalbe */ - RCQDA = 0x224, // Receive command Queue Descriptor Address - RDQDA = 0x228, // Receive Queue Descriptor Start Address - - MAR0 = 0x240, // Multicast filter. + VOAdmTime = 0x174, + VIAdmTime = 0x178, + BEAdmTime = 0x17C, + RQPN1 = 0x180, + RQPN2 = 0x184, + RQPN3 = 0x188, + QPRR = 0x1E0, + QPNR = 0x1F0, + BQDA = 0x200, + HQDA = 0x204, + CQDA = 0x208, + MQDA = 0x20C, + HCCAQDA = 0x210, + VOQDA = 0x214, + VIQDA = 0x218, + BEQDA = 0x21C, + BKQDA = 0x220, + RCQDA = 0x224, + RDQDA = 0x228, + + MAR0 = 0x240, MAR4 = 0x244, - CCX_PERIOD = 0x250, // CCX Measurement Period Register, in unit of TU. - CLM_RESULT = 0x251, // CCA Busy fraction register. - NHM_PERIOD = 0x252, // NHM Measurement Period register, in unit of TU. - - NHM_THRESHOLD0 = 0x253, // Noise Histogram Meashorement0. - NHM_THRESHOLD1 = 0x254, // Noise Histogram Meashorement1. - NHM_THRESHOLD2 = 0x255, // Noise Histogram Meashorement2. - NHM_THRESHOLD3 = 0x256, // Noise Histogram Meashorement3. - NHM_THRESHOLD4 = 0x257, // Noise Histogram Meashorement4. - NHM_THRESHOLD5 = 0x258, // Noise Histogram Meashorement5. - NHM_THRESHOLD6 = 0x259, // Noise Histogram Meashorement6 - - MCTRL = 0x25A, // Measurement Control - - NHM_RPI_COUNTER0 = 0x264, // Noise Histogram RPI counter0, the fraction of signal strength < NHM_THRESHOLD0. - NHM_RPI_COUNTER1 = 0x265, // Noise Histogram RPI counter1, the fraction of signal strength in (NHM_THRESHOLD0, NHM_THRESHOLD1]. - NHM_RPI_COUNTER2 = 0x266, // Noise Histogram RPI counter2, the fraction of signal strength in (NHM_THRESHOLD1, NHM_THRESHOLD2]. - NHM_RPI_COUNTER3 = 0x267, // Noise Histogram RPI counter3, the fraction of signal strength in (NHM_THRESHOLD2, NHM_THRESHOLD3]. - NHM_RPI_COUNTER4 = 0x268, // Noise Histogram RPI counter4, the fraction of signal strength in (NHM_THRESHOLD3, NHM_THRESHOLD4]. - NHM_RPI_COUNTER5 = 0x269, // Noise Histogram RPI counter5, the fraction of signal strength in (NHM_THRESHOLD4, NHM_THRESHOLD5]. - NHM_RPI_COUNTER6 = 0x26A, // Noise Histogram RPI counter6, the fraction of signal strength in (NHM_THRESHOLD5, NHM_THRESHOLD6]. - NHM_RPI_COUNTER7 = 0x26B, // Noise Histogram RPI counter7, the fraction of signal strength in (NHM_THRESHOLD6, NHM_THRESHOLD7]. - WFCRC0 = 0x2f0, - WFCRC1 = 0x2f4, - WFCRC2 = 0x2f8, - - BW_OPMODE = 0x300, // Bandwidth operation mode + CCX_PERIOD = 0x250, + CLM_RESULT = 0x251, + NHM_PERIOD = 0x252, + + NHM_THRESHOLD0 = 0x253, + NHM_THRESHOLD1 = 0x254, + NHM_THRESHOLD2 = 0x255, + NHM_THRESHOLD3 = 0x256, + NHM_THRESHOLD4 = 0x257, + NHM_THRESHOLD5 = 0x258, + NHM_THRESHOLD6 = 0x259, + + MCTRL = 0x25A, + + NHM_RPI_COUNTER0 = 0x264, + NHM_RPI_COUNTER1 = 0x265, + NHM_RPI_COUNTER2 = 0x266, + NHM_RPI_COUNTER3 = 0x267, + NHM_RPI_COUNTER4 = 0x268, + NHM_RPI_COUNTER5 = 0x269, + NHM_RPI_COUNTER6 = 0x26A, + NHM_RPI_COUNTER7 = 0x26B, + WFCRC0 = 0x2f0, + WFCRC1 = 0x2f4, + WFCRC2 = 0x2f8, + + BW_OPMODE = 0x300, #define BW_OPMODE_11J BIT0 #define BW_OPMODE_5G BIT1 #define BW_OPMODE_20MHZ BIT2 - IC_VERRSION = 0x301, //IC_VERSION - MSR = 0x303, // Media Status register + IC_VERRSION = 0x301, + MSR = 0x303, #define MSR_LINK_MASK ((1<<0)|(1<<1)) #define MSR_LINK_MANAGED 2 #define MSR_LINK_NONE 0 @@ -392,49 +355,50 @@ enum _RTL8192Pci_HW { #define MSR_LINK_ADHOC 1 #define MSR_LINK_MASTER 3 #define MSR_LINK_ENEDCA (1<<4) - RETRY_LIMIT = 0x304, // Retry Limit [15:8]-short, [7:0]-long + +#define MSR_NOLINK 0x00 +#define MSR_ADHOC 0x01 +#define MSR_INFRA 0x02 +#define MSR_AP 0x03 + + RETRY_LIMIT = 0x304, #define RETRY_LIMIT_SHORT_SHIFT 8 #define RETRY_LIMIT_LONG_SHIFT 0 TSFR = 0x308, - RRSR = 0x310, // Response Rate Set -#define RRSR_RSC_OFFSET 21 + RRSR = 0x310, +#define RRSR_RSC_OFFSET 21 #define RRSR_SHORT_OFFSET 23 #define RRSR_RSC_DUPLICATE 0x600000 #define RRSR_RSC_UPSUBCHNL 0x400000 -#define RRSR_RSC_LOWSUBCHNL 0x200000 -#define RRSR_SHORT 0x800000 -#define RRSR_1M BIT0 -#define RRSR_2M BIT1 -#define RRSR_5_5M BIT2 -#define RRSR_11M BIT3 -#define RRSR_6M BIT4 -#define RRSR_9M BIT5 -#define RRSR_12M BIT6 -#define RRSR_18M BIT7 -#define RRSR_24M BIT8 -#define RRSR_36M BIT9 -#define RRSR_48M BIT10 -#define RRSR_54M BIT11 -#define RRSR_MCS0 BIT12 -#define RRSR_MCS1 BIT13 -#define RRSR_MCS2 BIT14 -#define RRSR_MCS3 BIT15 -#define RRSR_MCS4 BIT16 -#define RRSR_MCS5 BIT17 -#define RRSR_MCS6 BIT18 -#define RRSR_MCS7 BIT19 -#define BRSR_AckShortPmb BIT23 // CCK ACK: use Short Preamble or not +#define RRSR_RSC_LOWSUBCHNL 0x200000 +#define RRSR_SHORT 0x800000 +#define RRSR_1M BIT0 +#define RRSR_2M BIT1 +#define RRSR_5_5M BIT2 +#define RRSR_11M BIT3 +#define RRSR_6M BIT4 +#define RRSR_9M BIT5 +#define RRSR_12M BIT6 +#define RRSR_18M BIT7 +#define RRSR_24M BIT8 +#define RRSR_36M BIT9 +#define RRSR_48M BIT10 +#define RRSR_54M BIT11 +#define RRSR_MCS0 BIT12 +#define RRSR_MCS1 BIT13 +#define RRSR_MCS2 BIT14 +#define RRSR_MCS3 BIT15 +#define RRSR_MCS4 BIT16 +#define RRSR_MCS5 BIT17 +#define RRSR_MCS6 BIT18 +#define RRSR_MCS7 BIT19 +#define BRSR_AckShortPmb BIT23 UFWP = 0x318, - RATR0 = 0x320, // Rate Adaptive Table register1 -//---------------------------------------------------------------------------- -// 8190 Rate Adaptive Table Register (offset 0x320, 4 byte) -//---------------------------------------------------------------------------- -//CCK + RATR0 = 0x320, #define RATR_1M 0x00000001 #define RATR_2M 0x00000002 #define RATR_55M 0x00000004 #define RATR_11M 0x00000008 -//OFDM #define RATR_6M 0x00000010 #define RATR_9M 0x00000020 #define RATR_12M 0x00000040 @@ -443,7 +407,6 @@ enum _RTL8192Pci_HW { #define RATR_36M 0x00000200 #define RATR_48M 0x00000400 #define RATR_54M 0x00000800 -//MCS 1 Spatial Stream #define RATR_MCS0 0x00001000 #define RATR_MCS1 0x00002000 #define RATR_MCS2 0x00004000 @@ -452,7 +415,6 @@ enum _RTL8192Pci_HW { #define RATR_MCS5 0x00020000 #define RATR_MCS6 0x00040000 #define RATR_MCS7 0x00080000 -//MCS 2 Spatial Stream #define RATR_MCS8 0x00100000 #define RATR_MCS9 0x00200000 #define RATR_MCS10 0x00400000 @@ -461,31 +423,31 @@ enum _RTL8192Pci_HW { #define RATR_MCS13 0x02000000 #define RATR_MCS14 0x04000000 #define RATR_MCS15 0x08000000 -// ALL CCK Rate -#define RATE_ALL_CCK RATR_1M|RATR_2M|RATR_55M|RATR_11M -#define RATE_ALL_OFDM_AG RATR_6M|RATR_9M|RATR_12M|RATR_18M|RATR_24M|RATR_36M|RATR_48M|RATR_54M -#define RATE_ALL_OFDM_1SS RATR_MCS0|RATR_MCS1|RATR_MCS2|RATR_MCS3 | \ - RATR_MCS4|RATR_MCS5|RATR_MCS6 |RATR_MCS7 -#define RATE_ALL_OFDM_2SS RATR_MCS8|RATR_MCS9 |RATR_MCS10|RATR_MCS11| \ - RATR_MCS12|RATR_MCS13|RATR_MCS14|RATR_MCS15 +#define RATE_ALL_CCK (RATR_1M | RATR_2M | RATR_55M | RATR_11M) +#define RATE_ALL_OFDM_AG (RATR_6M | RATR_9M | RATR_12M | RATR_18M | \ + RATR_24M | RATR_36M | RATR_48M | RATR_54M) +#define RATE_ALL_OFDM_1SS (RATR_MCS0 | RATR_MCS1 | RATR_MCS2 | \ + RATR_MCS3 | RATR_MCS4 | RATR_MCS5 | \ + RATR_MCS6 | RATR_MCS7) +#define RATE_ALL_OFDM_2SS (RATR_MCS8 | RATR_MCS9 | RATR_MCS10 | \ + RATR_MCS11 | RATR_MCS12 | RATR_MCS13 | \ + RATR_MCS14|RATR_MCS15) - DRIVER_RSSI = 0x32c, // Driver tell Firmware current RSSI - MCS_TXAGC = 0x340, // MCS AGC - CCK_TXAGC = 0x348, // CCK AGC - MacBlkCtrl = 0x403, // Mac block on/off control register + DRIVER_RSSI = 0x32c, + MCS_TXAGC = 0x340, + CCK_TXAGC = 0x348, + MacBlkCtrl = 0x403, -}; +} +; #define GPI 0x108 #define GPO 0x109 #define GPE 0x10a -#define ANAPAR_FOR_8192PciE 0x17 // Analog parameter register +#define HWSET_MAX_SIZE_92S 128 -#define MSR_NOLINK 0x00 -#define MSR_ADHOC 0x01 -#define MSR_INFRA 0x02 -#define MSR_AP 0x03 +#define ANAPAR_FOR_8192PciE 0x17 #endif diff --git a/drivers/staging/rtl8192e/r8192E_hwimg.c b/drivers/staging/rtl8192e/r8192E_hwimg.c new file mode 100644 index 0000000..08e7dbb --- /dev/null +++ b/drivers/staging/rtl8192e/r8192E_hwimg.c @@ -0,0 +1,3336 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> +******************************************************************************/ +/*Created on 2008/11/18, 3: 7*/ + +#include "r8192E_hwimg.h" + +u8 Rtl8192PciEFwBootArray[BootArrayLengthPciE] = { +0x10,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x3c,0x08,0xbf,0xc0,0x25,0x08,0x00,0x08, +0x3c,0x09,0xb0,0x03,0xad,0x28,0x00,0x20,0x40,0x80,0x68,0x00,0x00,0x00,0x00,0x00, +0x3c,0x0a,0xd0,0x00,0x40,0x8a,0x60,0x00,0x00,0x00,0x00,0x00,0x3c,0x08,0x80,0x01, +0x25,0x08,0xa8,0x04,0x24,0x09,0x00,0x01,0x3c,0x01,0x7f,0xff,0x34,0x21,0xff,0xff, +0x01,0x01,0x50,0x24,0x00,0x09,0x48,0x40,0x35,0x29,0x00,0x01,0x01,0x2a,0x10,0x2b, +0x14,0x40,0xff,0xfc,0x00,0x00,0x00,0x00,0x3c,0x0a,0x00,0x00,0x25,0x4a,0x00,0x00, +0x4c,0x8a,0x00,0x00,0x4c,0x89,0x08,0x00,0x00,0x00,0x00,0x00,0x3c,0x08,0x80,0x01, +0x25,0x08,0xa8,0x04,0x3c,0x01,0x80,0x00,0x01,0x21,0x48,0x25,0x3c,0x0a,0xbf,0xc0, +0x25,0x4a,0x00,0x7c,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20,0xad,0x00,0x00,0x00, +0x21,0x08,0x00,0x04,0x01,0x09,0x10,0x2b,0x14,0x40,0xff,0xf8,0x00,0x00,0x00,0x00, +0x3c,0x08,0x80,0x01,0x25,0x08,0x7f,0xff,0x24,0x09,0x00,0x01,0x3c,0x01,0x7f,0xff, +0x34,0x21,0xff,0xff,0x01,0x01,0x50,0x24,0x00,0x09,0x48,0x40,0x35,0x29,0x00,0x01, +0x01,0x2a,0x10,0x2b,0x14,0x40,0xff,0xfc,0x00,0x00,0x00,0x00,0x3c,0x0a,0x80,0x01, +0x25,0x4a,0x00,0x00,0x3c,0x01,0x7f,0xff,0x34,0x21,0xff,0xff,0x01,0x41,0x50,0x24, +0x3c,0x09,0x00,0x01,0x35,0x29,0x7f,0xff,0x4c,0x8a,0x20,0x00,0x4c,0x89,0x28,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0x08,0x04,0x10, +0x00,0x00,0x00,0x00,0x40,0x88,0xa0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x3c,0x08,0xbf,0xc0,0x00,0x00,0x00,0x00,0x8d,0x09,0x00,0x00,0x00,0x00,0x00,0x00, +0x3c,0x0a,0xbf,0xc0,0x25,0x4a,0x01,0x20,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20, +0x3c,0x08,0xb0,0x03,0x8d,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x35,0x29,0x00,0x10, +0xad,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x3c,0x08,0x80,0x00,0x25,0x08,0x4b,0x94, +0x01,0x00,0x00,0x08,0x00,0x00,0x00,0x00,}; + +u8 Rtl8192PciEFwMainArray[MainArrayLengthPciE] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x40,0x04,0x68,0x00,0x40,0x05,0x70,0x00,0x40,0x06,0x40,0x00,0x0c,0x00,0x12,0x98, +0x00,0x00,0x00,0x00,0x40,0x1a,0x68,0x00,0x33,0x5b,0x00,0x3c,0x17,0x60,0x00,0x09, +0x00,0x00,0x00,0x00,0x40,0x1b,0x60,0x00,0x00,0x00,0x00,0x00,0x03,0x5b,0xd0,0x24, +0x40,0x1a,0x70,0x00,0x03,0x40,0x00,0x08,0x42,0x00,0x00,0x10,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x3c,0x02,0xff,0xff,0x34,0x42,0xff,0xff,0x8c,0x43,0x00,0x00, +0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x00,0xd0, +0xac,0x62,0x00,0x00,0x00,0x00,0x20,0x21,0x27,0x85,0x8b,0x70,0x00,0x85,0x18,0x21, +0x24,0x84,0x00,0x01,0x28,0x82,0x00,0x0a,0x14,0x40,0xff,0xfc,0xa0,0x60,0x00,0x00, +0x27,0x82,0x8b,0x7a,0x24,0x04,0x00,0x06,0x24,0x84,0xff,0xff,0xa4,0x40,0x00,0x00, +0x04,0x81,0xff,0xfd,0x24,0x42,0x00,0x02,0x24,0x02,0x00,0x03,0xa3,0x82,0x8b,0x70, +0x24,0x02,0x00,0x0a,0x24,0x03,0x09,0xc4,0xa3,0x82,0x8b,0x72,0x24,0x02,0x00,0x04, +0x24,0x04,0x00,0x01,0x24,0x05,0x00,0x02,0xa7,0x83,0x8b,0x86,0xa3,0x82,0x8b,0x78, +0x24,0x03,0x04,0x00,0x24,0x02,0x02,0x00,0xaf,0x83,0x8b,0x8c,0xa3,0x85,0x8b,0x79, +0xa7,0x82,0x8b,0x7a,0xa7,0x84,0x8b,0x7c,0xaf,0x84,0x8b,0x88,0xa3,0x84,0x8b,0x71, +0xa3,0x80,0x8b,0x73,0xa3,0x80,0x8b,0x74,0xa3,0x80,0x8b,0x75,0xa3,0x84,0x8b,0x76, +0xa3,0x85,0x8b,0x77,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03, +0x3c,0x02,0x80,0x00,0x24,0x42,0x01,0x7c,0x34,0x63,0x00,0x20,0xac,0x62,0x00,0x00, +0x27,0x84,0x8b,0x98,0x00,0x00,0x10,0x21,0x24,0x42,0x00,0x01,0x00,0x02,0x16,0x00, +0x00,0x02,0x16,0x03,0x28,0x43,0x00,0x03,0xac,0x80,0xff,0xfc,0xa0,0x80,0x00,0x00, +0x14,0x60,0xff,0xf9,0x24,0x84,0x00,0x0c,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00, +0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x01,0xc0, +0x3c,0x08,0xb0,0x03,0xac,0x62,0x00,0x00,0x35,0x08,0x00,0x70,0x8d,0x02,0x00,0x00, +0x00,0xa0,0x48,0x21,0x00,0x04,0x26,0x00,0x00,0x02,0x2a,0x43,0x00,0x06,0x36,0x00, +0x00,0x07,0x3e,0x00,0x00,0x02,0x12,0x03,0x29,0x23,0x00,0x03,0x00,0x04,0x56,0x03, +0x00,0x06,0x36,0x03,0x00,0x07,0x3e,0x03,0x30,0x48,0x00,0x01,0x10,0x60,0x00,0x11, +0x30,0xa5,0x00,0x07,0x24,0x02,0x00,0x02,0x00,0x49,0x10,0x23,0x00,0x45,0x10,0x07, +0x30,0x42,0x00,0x01,0x10,0x40,0x00,0x66,0x00,0x00,0x00,0x00,0x8f,0xa2,0x00,0x10, +0x00,0x00,0x00,0x00,0x00,0x02,0x21,0x43,0x11,0x00,0x00,0x10,0x00,0x07,0x20,0x0b, +0x15,0x20,0x00,0x06,0x24,0x02,0x00,0x01,0x3c,0x02,0xb0,0x05,0x34,0x42,0x01,0x20, +0xa4,0x44,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x11,0x22,0x00,0x04, +0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x05,0x08,0x00,0x00,0x94,0x34,0x42,0x01,0x24, +0x3c,0x02,0xb0,0x05,0x08,0x00,0x00,0x94,0x34,0x42,0x01,0x22,0x15,0x20,0x00,0x54, +0x24,0x02,0x00,0x01,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x74,0x90,0x43,0x00,0x00, +0x00,0x00,0x00,0x00,0xaf,0x83,0x8b,0x94,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x70, +0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x6b,0x00,0x08,0x11,0x60,0x00,0x18, +0x00,0x09,0x28,0x40,0x00,0x00,0x40,0x21,0x27,0x85,0x8b,0x90,0x8c,0xa3,0x00,0x00, +0x8c,0xa2,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x62,0x38,0x23,0x00,0x43,0x10,0x2a, +0x10,0x40,0x00,0x3d,0x00,0x00,0x00,0x00,0xac,0xa7,0x00,0x00,0x25,0x02,0x00,0x01, +0x00,0x02,0x16,0x00,0x00,0x02,0x46,0x03,0x29,0x03,0x00,0x03,0x14,0x60,0xff,0xf3, +0x24,0xa5,0x00,0x0c,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x70,0x90,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x4b,0x10,0x23,0xa0,0x62,0x00,0x00,0x00,0x09,0x28,0x40, +0x00,0xa9,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x8b,0x98,0x00,0x0a,0x20,0x0b, +0x00,0x43,0x18,0x21,0x10,0xc0,0x00,0x05,0x00,0x00,0x38,0x21,0x80,0x62,0x00,0x01, +0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x05,0x00,0x00,0x00,0x00,0x80,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x03,0x00,0xa9,0x10,0x21,0x24,0x07,0x00,0x01, +0x00,0xa9,0x10,0x21,0x00,0x02,0x30,0x80,0x27,0x82,0x8b,0x98,0xa0,0x67,0x00,0x01, +0x00,0xc2,0x38,0x21,0x80,0xe3,0x00,0x01,0x00,0x00,0x00,0x00,0x10,0x60,0x00,0x07, +0x00,0x00,0x00,0x00,0x27,0x83,0x8b,0x90,0x00,0xc3,0x18,0x21,0x8c,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x44,0x10,0x21,0xac,0x62,0x00,0x00,0x27,0x85,0x8b,0x94, +0x27,0x82,0x8b,0x90,0x00,0xc5,0x28,0x21,0x00,0xc2,0x10,0x21,0x8c,0x43,0x00,0x00, +0x8c,0xa4,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x64,0x18,0x2a,0x14,0x60,0x00,0x03, +0x24,0x02,0x00,0x01,0x03,0xe0,0x00,0x08,0xa0,0xe2,0x00,0x00,0xa0,0xe0,0x00,0x00, +0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0xb7,0xac,0xa0,0x00,0x00, +0x11,0x22,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x7c, +0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0xaf,0x83,0x8b,0xac,0x08,0x00,0x00,0xa7, +0x3c,0x02,0xb0,0x03,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x78,0x90,0x43,0x00,0x00, +0x00,0x00,0x00,0x00,0xaf,0x83,0x8b,0xa0,0x08,0x00,0x00,0xa7,0x3c,0x02,0xb0,0x03, +0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x04,0x10, +0x3c,0x05,0xb0,0x03,0xac,0x62,0x00,0x00,0x34,0xa5,0x00,0x70,0x8c,0xa2,0x00,0x00, +0x90,0x84,0x00,0x08,0x3c,0x06,0xb0,0x03,0x00,0x02,0x16,0x00,0x2c,0x83,0x00,0x03, +0x34,0xc6,0x00,0x72,0x24,0x07,0x00,0x01,0x10,0x60,0x00,0x11,0x00,0x02,0x2f,0xc2, +0x90,0xc2,0x00,0x00,0x00,0x00,0x18,0x21,0x00,0x02,0x16,0x00,0x10,0xa7,0x00,0x09, +0x00,0x02,0x16,0x03,0x14,0x80,0x00,0x0c,0x30,0x43,0x00,0x03,0x83,0x82,0x8b,0x98, +0x00,0x00,0x00,0x00,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x00,0x02,0x16,0x00, +0x00,0x02,0x1e,0x03,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x72,0xa0,0x43,0x00,0x00, +0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0x45,0x00,0x05,0x10,0x87,0x00,0x04, +0x30,0x43,0x00,0x06,0x93,0x82,0x8b,0xb0,0x08,0x00,0x01,0x1f,0x00,0x43,0x10,0x21, +0x83,0x82,0x8b,0xa4,0x00,0x00,0x00,0x00,0x00,0x02,0x10,0x40,0x08,0x00,0x01,0x1f, +0x00,0x45,0x10,0x21,0x10,0x80,0x00,0x05,0x00,0x00,0x18,0x21,0x24,0x63,0x00,0x01, +0x00,0x64,0x10,0x2b,0x14,0x40,0xff,0xfd,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08, +0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x24,0x42,0x04,0xe4, +0x3c,0x04,0xb0,0x02,0x34,0x63,0x00,0x20,0xac,0x62,0x00,0x00,0x34,0x84,0x00,0x08, +0x24,0x02,0x00,0x01,0xaf,0x84,0x8b,0xc0,0xa3,0x82,0x8b,0xd0,0xa7,0x80,0x8b,0xc4, +0xa7,0x80,0x8b,0xc6,0xaf,0x80,0x8b,0xc8,0xaf,0x80,0x8b,0xcc,0x03,0xe0,0x00,0x08, +0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20, +0x24,0x42,0x05,0x24,0x3c,0x04,0xb0,0x03,0xac,0x62,0x00,0x00,0x34,0x84,0x00,0xac, +0x80,0xa2,0x00,0x15,0x8c,0x83,0x00,0x00,0x27,0xbd,0xff,0xf0,0x00,0x43,0x10,0x21, +0xac,0x82,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x10,0x3c,0x02,0xb0,0x03, +0x3c,0x03,0x80,0x00,0x34,0x42,0x00,0x20,0x24,0x63,0x05,0x5c,0x27,0xbd,0xff,0xe0, +0xac,0x43,0x00,0x00,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x18, +0x8f,0x90,0x8b,0xc0,0x0c,0x00,0x02,0x98,0x00,0x80,0x88,0x21,0x14,0x40,0x00,0x2a, +0x3c,0x02,0x00,0x80,0x16,0x20,0x00,0x02,0x34,0x42,0x02,0x01,0x24,0x02,0x02,0x01, +0xae,0x02,0x00,0x00,0x97,0x84,0x8b,0xc4,0x97,0x82,0x8b,0xc6,0x3c,0x03,0xb0,0x02, +0x00,0x83,0x20,0x21,0x24,0x42,0x00,0x04,0xa7,0x82,0x8b,0xc6,0xa4,0x82,0x00,0x00, +0x8f,0x84,0x8b,0xc8,0x8f,0x82,0x8b,0xc0,0x93,0x85,0x8b,0x72,0x24,0x84,0x00,0x01, +0x24,0x42,0x00,0x04,0x24,0x03,0x8f,0xff,0x3c,0x07,0xb0,0x06,0x3c,0x06,0xb0,0x03, +0x00,0x43,0x10,0x24,0x00,0x85,0x28,0x2a,0x34,0xe7,0x80,0x18,0xaf,0x82,0x8b,0xc0, +0xaf,0x84,0x8b,0xc8,0x10,0xa0,0x00,0x08,0x34,0xc6,0x01,0x08,0x8f,0x83,0x8b,0xcc, +0x8f,0x84,0x8b,0x8c,0x8c,0xc2,0x00,0x00,0x00,0x64,0x18,0x21,0x00,0x43,0x10,0x2b, +0x14,0x40,0x00,0x09,0x00,0x00,0x00,0x00,0x8c,0xe2,0x00,0x00,0x3c,0x03,0x0f,0x00, +0x3c,0x04,0x04,0x00,0x00,0x43,0x10,0x24,0x10,0x44,0x00,0x03,0x00,0x00,0x00,0x00, +0x0c,0x00,0x04,0x96,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x18,0x7b,0xb0,0x00,0xbc, +0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x27,0xbd,0xff,0xd8,0x3c,0x02,0xb0,0x03, +0x3c,0x03,0x80,0x00,0x24,0x63,0x06,0x48,0xaf,0xb0,0x00,0x10,0x34,0x42,0x00,0x20, +0x8f,0x90,0x8b,0xc0,0xac,0x43,0x00,0x00,0xaf,0xb3,0x00,0x1c,0xaf,0xb2,0x00,0x18, +0xaf,0xb1,0x00,0x14,0xaf,0xbf,0x00,0x20,0x00,0x80,0x88,0x21,0x00,0xa0,0x90,0x21, +0x0c,0x00,0x02,0x98,0x00,0xc0,0x98,0x21,0x24,0x07,0x8f,0xff,0x14,0x40,0x00,0x19, +0x26,0x03,0x00,0x04,0x24,0x02,0x0e,0x03,0xae,0x02,0x00,0x00,0x00,0x67,0x80,0x24, +0x26,0x02,0x00,0x04,0xae,0x11,0x00,0x00,0x00,0x47,0x80,0x24,0x97,0x86,0x8b,0xc4, +0x26,0x03,0x00,0x04,0xae,0x12,0x00,0x00,0x00,0x67,0x80,0x24,0xae,0x13,0x00,0x00, +0x8f,0x84,0x8b,0xc0,0x3c,0x02,0xb0,0x02,0x97,0x85,0x8b,0xc6,0x00,0xc2,0x30,0x21, +0x8f,0x82,0x8b,0xc8,0x24,0x84,0x00,0x10,0x24,0xa5,0x00,0x10,0x00,0x87,0x20,0x24, +0x24,0x42,0x00,0x01,0xa7,0x85,0x8b,0xc6,0xaf,0x84,0x8b,0xc0,0xaf,0x82,0x8b,0xc8, +0xa4,0xc5,0x00,0x00,0x8f,0xbf,0x00,0x20,0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc, +0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28,0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10, +0x94,0x82,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x42,0xe0,0x00,0x14,0x40,0x00,0x14, +0x00,0x00,0x00,0x00,0x90,0x82,0x00,0x02,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xfc, +0x00,0x82,0x28,0x21,0x8c,0xa4,0x00,0x00,0x3c,0x02,0x00,0x70,0x8c,0xa6,0x00,0x08, +0x00,0x82,0x10,0x21,0x2c,0x43,0x00,0x06,0x10,0x60,0x00,0x09,0x3c,0x03,0x80,0x01, +0x00,0x02,0x10,0x80,0x24,0x63,0x01,0xe8,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x08,0x00,0x00,0x00,0x00,0xaf,0x86,0x80,0x14, +0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18, +0x8c,0xa4,0x00,0x00,0x0c,0x00,0x17,0x84,0x00,0x00,0x00,0x00,0x08,0x00,0x01,0xdc, +0x00,0x00,0x00,0x00,0x0c,0x00,0x24,0x49,0x00,0xc0,0x20,0x21,0x08,0x00,0x01,0xdc, +0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x34,0x42,0x01,0x08,0x8c,0x44,0x00,0x00, +0x8f,0x82,0x80,0x18,0x3c,0x03,0x00,0x0f,0x34,0x63,0x42,0x40,0x00,0x43,0x10,0x21, +0x00,0x82,0x20,0x2b,0x10,0x80,0x00,0x09,0x24,0x03,0x00,0x05,0x8f,0x82,0x83,0x60, +0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,0xaf,0x82,0x83,0x60,0x10,0x43,0x00,0x03, +0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03, +0x8c,0x63,0x01,0x08,0x24,0x02,0x00,0x01,0xa3,0x82,0x80,0x11,0xaf,0x80,0x83,0x60, +0xaf,0x83,0x80,0x18,0x08,0x00,0x01,0xf9,0x00,0x00,0x00,0x00,0x30,0x84,0x00,0xff, +0x14,0x80,0x00,0x2f,0x00,0x00,0x00,0x00,0x8f,0x82,0x80,0x14,0xa3,0x85,0x83,0x93, +0x10,0x40,0x00,0x2b,0x2c,0xa2,0x00,0x04,0x14,0x40,0x00,0x06,0x00,0x05,0x10,0x40, +0x24,0xa2,0xff,0xfc,0x2c,0x42,0x00,0x08,0x10,0x40,0x00,0x09,0x24,0xa2,0xff,0xf0, +0x00,0x05,0x10,0x40,0x27,0x84,0x83,0x9c,0x00,0x44,0x10,0x21,0x94,0x43,0x00,0x00, +0x00,0x00,0x00,0x00,0x24,0x63,0x00,0x01,0x03,0xe0,0x00,0x08,0xa4,0x43,0x00,0x00, +0x2c,0x42,0x00,0x10,0x14,0x40,0x00,0x0a,0x00,0x05,0x10,0x40,0x24,0xa2,0xff,0xe0, +0x2c,0x42,0x00,0x10,0x14,0x40,0x00,0x06,0x00,0x05,0x10,0x40,0x24,0xa2,0xff,0xd0, +0x2c,0x42,0x00,0x10,0x10,0x40,0x00,0x09,0x24,0xa2,0xff,0xc0,0x00,0x05,0x10,0x40, +0x27,0x84,0x83,0x9c,0x00,0x44,0x10,0x21,0x94,0x43,0xff,0xf8,0x00,0x00,0x00,0x00, +0x24,0x63,0x00,0x01,0x03,0xe0,0x00,0x08,0xa4,0x43,0xff,0xf8,0x2c,0x42,0x00,0x10, +0x10,0x40,0x00,0x07,0x00,0x05,0x10,0x40,0x27,0x84,0x83,0x9c,0x00,0x44,0x10,0x21, +0x94,0x43,0xff,0xf8,0x00,0x00,0x00,0x00,0x24,0x63,0x00,0x01,0xa4,0x43,0xff,0xf8, +0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x8f,0x86,0x8b,0xc0,0x8f,0x82,0x80,0x14, +0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10,0x10,0x40,0x00,0x2a,0x00,0xc0,0x38,0x21, +0x24,0x02,0x00,0x07,0x24,0x03,0xff,0x9c,0xa3,0x82,0x83,0x9b,0xa3,0x83,0x83,0x9a, +0x27,0x8a,0x83,0x98,0x00,0x00,0x20,0x21,0x24,0x09,0x8f,0xff,0x00,0x04,0x10,0x80, +0x00,0x4a,0x28,0x21,0x8c,0xa2,0x00,0x00,0x24,0xe3,0x00,0x04,0x24,0x88,0x00,0x01, +0xac,0xe2,0x00,0x00,0x10,0x80,0x00,0x02,0x00,0x69,0x38,0x24,0xac,0xa0,0x00,0x00, +0x31,0x04,0x00,0xff,0x2c,0x82,0x00,0x27,0x14,0x40,0xff,0xf5,0x00,0x04,0x10,0x80, +0x97,0x83,0x8b,0xc6,0x97,0x85,0x8b,0xc4,0x3c,0x02,0xb0,0x02,0x24,0x63,0x00,0x9c, +0x00,0xa2,0x28,0x21,0x3c,0x04,0xb0,0x06,0xa7,0x83,0x8b,0xc6,0x34,0x84,0x80,0x18, +0xa4,0xa3,0x00,0x00,0x8c,0x85,0x00,0x00,0x24,0x02,0x8f,0xff,0x24,0xc6,0x00,0x9c, +0x3c,0x03,0x0f,0x00,0x00,0xc2,0x30,0x24,0x00,0xa3,0x28,0x24,0x3c,0x02,0x04,0x00, +0xaf,0x86,0x8b,0xc0,0x10,0xa2,0x00,0x03,0x00,0x00,0x00,0x00,0x0c,0x00,0x04,0x96, +0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x18,0x8f,0x86,0x8b,0xc0,0x27,0xbd,0xff,0xc8,0x24,0x02,0x00,0x08, +0x24,0x03,0x00,0x20,0xaf,0xbf,0x00,0x30,0xa3,0xa2,0x00,0x13,0xa3,0xa3,0x00,0x12, +0xa7,0xa4,0x00,0x10,0x00,0xc0,0x28,0x21,0x27,0xa9,0x00,0x10,0x00,0x00,0x38,0x21, +0x24,0x08,0x8f,0xff,0x00,0x07,0x10,0x80,0x00,0x49,0x10,0x21,0x8c,0x44,0x00,0x00, +0x24,0xe3,0x00,0x01,0x30,0x67,0x00,0xff,0x24,0xa2,0x00,0x04,0x2c,0xe3,0x00,0x08, +0xac,0xa4,0x00,0x00,0x14,0x60,0xff,0xf7,0x00,0x48,0x28,0x24,0x97,0x83,0x8b,0xc6, +0x97,0x85,0x8b,0xc4,0x3c,0x02,0xb0,0x02,0x24,0x63,0x00,0x20,0x00,0xa2,0x28,0x21, +0x3c,0x04,0xb0,0x06,0xa7,0x83,0x8b,0xc6,0x34,0x84,0x80,0x18,0xa4,0xa3,0x00,0x00, +0x8c,0x85,0x00,0x00,0x24,0x02,0x8f,0xff,0x24,0xc6,0x00,0x20,0x3c,0x03,0x0f,0x00, +0x00,0xc2,0x30,0x24,0x00,0xa3,0x28,0x24,0x3c,0x02,0x04,0x00,0xaf,0x86,0x8b,0xc0, +0x10,0xa2,0x00,0x03,0x00,0x00,0x00,0x00,0x0c,0x00,0x04,0x96,0x00,0x00,0x00,0x00, +0x8f,0xbf,0x00,0x30,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x38, +0x93,0x82,0x8b,0xd0,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x11,0x24,0x06,0x00,0x01, +0x8f,0x82,0x8b,0xc8,0x3c,0x05,0xb0,0x06,0x3c,0x04,0xb0,0x03,0x34,0xa5,0x80,0x18, +0x34,0x84,0x01,0x08,0x14,0x40,0x00,0x09,0x00,0x00,0x30,0x21,0x97,0x82,0x8b,0xc4, +0x8c,0x84,0x00,0x00,0x3c,0x03,0xb0,0x02,0x00,0x43,0x10,0x21,0xaf,0x84,0x8b,0xcc, +0xa7,0x80,0x8b,0xc6,0xac,0x40,0x00,0x00,0xac,0x40,0x00,0x04,0x8c,0xa2,0x00,0x00, +0x03,0xe0,0x00,0x08,0x00,0xc0,0x10,0x21,0x8f,0x86,0x8b,0xc0,0x8f,0x82,0x8b,0xc8, +0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10,0x00,0xc0,0x40,0x21,0x14,0x40,0x00,0x0a, +0x00,0x40,0x50,0x21,0x00,0x00,0x38,0x21,0x27,0x89,0x83,0x68,0x24,0xe2,0x00,0x01, +0x00,0x07,0x18,0x80,0x30,0x47,0x00,0xff,0x00,0x69,0x18,0x21,0x2c,0xe2,0x00,0x0a, +0x14,0x40,0xff,0xfa,0xac,0x60,0x00,0x00,0x3c,0x02,0x00,0x80,0x10,0x82,0x00,0x6f, +0x00,0x00,0x00,0x00,0x97,0x82,0x83,0x6e,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01, +0xa7,0x82,0x83,0x6e,0x90,0xa3,0x00,0x15,0x97,0x82,0x83,0x70,0x00,0x03,0x1e,0x00, +0x00,0x03,0x1e,0x03,0x00,0x43,0x10,0x21,0xa7,0x82,0x83,0x70,0x8c,0xa4,0x00,0x20, +0x3c,0x02,0x00,0x60,0x3c,0x03,0x00,0x20,0x00,0x82,0x20,0x24,0x10,0x83,0x00,0x54, +0x00,0x00,0x00,0x00,0x14,0x80,0x00,0x47,0x00,0x00,0x00,0x00,0x97,0x82,0x83,0x74, +0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,0xa7,0x82,0x83,0x74,0x84,0xa3,0x00,0x06, +0x8f,0x82,0x83,0x84,0x00,0x00,0x00,0x00,0x00,0x43,0x10,0x21,0xaf,0x82,0x83,0x84, +0x25,0x42,0x00,0x01,0x28,0x43,0x27,0x10,0xaf,0x82,0x8b,0xc8,0x10,0x60,0x00,0x09, +0x24,0x02,0x00,0x04,0x93,0x83,0x80,0x11,0x24,0x02,0x00,0x01,0x10,0x62,0x00,0x05, +0x24,0x02,0x00,0x04,0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x18,0x24,0x03,0x00,0x28,0xa3,0x83,0x83,0x6a,0xa3,0x82,0x83,0x6b, +0x90,0xa2,0x00,0x18,0x93,0x83,0x83,0x93,0x00,0x00,0x38,0x21,0x00,0x02,0x16,0x00, +0x00,0x02,0x16,0x03,0xa7,0x82,0x83,0x7e,0xa3,0x83,0x83,0x8c,0x27,0x89,0x83,0x68, +0x24,0x05,0x8f,0xff,0x00,0x07,0x10,0x80,0x00,0x49,0x10,0x21,0x8c,0x44,0x00,0x00, +0x24,0xe3,0x00,0x01,0x30,0x67,0x00,0xff,0x25,0x02,0x00,0x04,0x2c,0xe3,0x00,0x0a, +0xad,0x04,0x00,0x00,0x14,0x60,0xff,0xf7,0x00,0x45,0x40,0x24,0x97,0x83,0x8b,0xc6, +0x97,0x85,0x8b,0xc4,0x3c,0x02,0xb0,0x02,0x24,0x63,0x00,0x28,0x00,0xa2,0x28,0x21, +0x3c,0x04,0xb0,0x06,0xa7,0x83,0x8b,0xc6,0x34,0x84,0x80,0x18,0xa4,0xa3,0x00,0x00, +0x8c,0x85,0x00,0x00,0x24,0x02,0x8f,0xff,0x24,0xc6,0x00,0x28,0x3c,0x03,0x0f,0x00, +0x00,0xc2,0x30,0x24,0x00,0xa3,0x28,0x24,0x3c,0x02,0x04,0x00,0xaf,0x86,0x8b,0xc0, +0x10,0xa2,0x00,0x03,0x00,0x00,0x00,0x00,0x0c,0x00,0x04,0x96,0x00,0x00,0x00,0x00, +0x0c,0x00,0x02,0x36,0x00,0x00,0x00,0x00,0xa3,0x80,0x80,0x11,0x08,0x00,0x02,0xe5, +0x00,0x00,0x00,0x00,0x97,0x82,0x83,0x76,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01, +0xa7,0x82,0x83,0x76,0x84,0xa3,0x00,0x06,0x8f,0x82,0x83,0x88,0x00,0x00,0x00,0x00, +0x00,0x43,0x10,0x21,0xaf,0x82,0x83,0x88,0x08,0x00,0x02,0xdd,0x25,0x42,0x00,0x01, +0x97,0x82,0x83,0x72,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,0xa7,0x82,0x83,0x72, +0x84,0xa3,0x00,0x06,0x8f,0x82,0x83,0x80,0x00,0x00,0x00,0x00,0x00,0x43,0x10,0x21, +0xaf,0x82,0x83,0x80,0x08,0x00,0x02,0xdd,0x25,0x42,0x00,0x01,0x97,0x82,0x83,0x6c, +0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,0xa7,0x82,0x83,0x6c,0x08,0x00,0x02,0xc5, +0x00,0x00,0x00,0x00,0x27,0xbd,0xff,0xd0,0xaf,0xbf,0x00,0x28,0x8c,0xa3,0x00,0x20, +0x8f,0x8a,0x8b,0xc0,0x3c,0x02,0x00,0x10,0x00,0x62,0x10,0x24,0x00,0xa0,0x38,0x21, +0x01,0x40,0x48,0x21,0x10,0x40,0x00,0x3d,0x00,0x80,0x28,0x21,0x8c,0xe4,0x00,0x1c, +0x34,0xa5,0x12,0x06,0xaf,0xa5,0x00,0x10,0x8c,0x82,0x00,0x08,0x00,0x03,0x1c,0x42, +0x30,0x63,0x00,0x30,0x00,0x02,0x13,0x02,0x30,0x42,0x00,0x40,0x00,0x43,0x10,0x25, +0x90,0xe6,0x00,0x10,0x90,0xe4,0x00,0x13,0x94,0xe8,0x00,0x0c,0x94,0xe3,0x00,0x1a, +0x00,0x02,0x16,0x00,0x90,0xe7,0x00,0x12,0x00,0xa2,0x28,0x25,0x24,0x02,0x12,0x34, +0xa7,0xa2,0x00,0x1c,0x24,0x02,0x56,0x78,0xaf,0xa5,0x00,0x10,0xa3,0xa6,0x00,0x18, +0xa3,0xa7,0x00,0x1f,0xa7,0xa3,0x00,0x1a,0xa3,0xa4,0x00,0x19,0xa7,0xa8,0x00,0x20, +0xa7,0xa2,0x00,0x22,0x00,0x00,0x28,0x21,0x27,0xa7,0x00,0x10,0x24,0x06,0x8f,0xff, +0x00,0x05,0x10,0x80,0x00,0x47,0x10,0x21,0x8c,0x44,0x00,0x00,0x24,0xa3,0x00,0x01, +0x30,0x65,0x00,0xff,0x25,0x22,0x00,0x04,0x2c,0xa3,0x00,0x05,0xad,0x24,0x00,0x00, +0x14,0x60,0xff,0xf7,0x00,0x46,0x48,0x24,0x97,0x83,0x8b,0xc6,0x97,0x85,0x8b,0xc4, +0x3c,0x02,0xb0,0x02,0x24,0x63,0x00,0x14,0x00,0xa2,0x28,0x21,0x3c,0x04,0xb0,0x06, +0xa7,0x83,0x8b,0xc6,0x34,0x84,0x80,0x18,0xa4,0xa3,0x00,0x00,0x8c,0x85,0x00,0x00, +0x24,0x02,0x8f,0xff,0x25,0x46,0x00,0x14,0x3c,0x03,0x0f,0x00,0x00,0xc2,0x50,0x24, +0x00,0xa3,0x28,0x24,0x3c,0x02,0x04,0x00,0xaf,0x8a,0x8b,0xc0,0x10,0xa2,0x00,0x03, +0x00,0x00,0x00,0x00,0x0c,0x00,0x04,0x96,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x28, +0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x30,0x3c,0x05,0xb0,0x03, +0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xc8,0x00,0x04,0x22,0x00,0x34,0xa5,0x00,0x20, +0x24,0x42,0x0d,0xfc,0x3c,0x03,0xb0,0x00,0xaf,0xb5,0x00,0x24,0xaf,0xb4,0x00,0x20, +0xaf,0xb2,0x00,0x18,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x30,0x00,0x83,0x80,0x21, +0xaf,0xb7,0x00,0x2c,0xaf,0xb6,0x00,0x28,0xaf,0xb3,0x00,0x1c,0xaf,0xb1,0x00,0x14, +0xac,0xa2,0x00,0x00,0x8e,0x09,0x00,0x00,0x00,0x00,0x90,0x21,0x26,0x10,0x00,0x08, +0x00,0x09,0xa6,0x02,0x12,0x80,0x00,0x13,0x00,0x00,0xa8,0x21,0x24,0x13,0x00,0x02, +0x3c,0x16,0x00,0xff,0x3c,0x17,0xff,0x00,0x8e,0x09,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x09,0x12,0x02,0x24,0x42,0x00,0x02,0x31,0x25,0x00,0xff,0x10,0xb3,0x00,0x76, +0x30,0x51,0x00,0xff,0x24,0x02,0x00,0x03,0x10,0xa2,0x00,0x18,0x00,0x00,0x00,0x00, +0x02,0x51,0x10,0x21,0x30,0x52,0xff,0xff,0x02,0x54,0x18,0x2b,0x14,0x60,0xff,0xf2, +0x02,0x11,0x80,0x21,0x12,0xa0,0x00,0x0a,0x3c,0x02,0xb0,0x06,0x34,0x42,0x80,0x18, +0x8c,0x43,0x00,0x00,0x3c,0x04,0x0f,0x00,0x3c,0x02,0x04,0x00,0x00,0x64,0x18,0x24, +0x10,0x62,0x00,0x03,0x00,0x00,0x00,0x00,0x0c,0x00,0x04,0x96,0x00,0x00,0x00,0x00, +0x8f,0xbf,0x00,0x30,0x7b,0xb6,0x01,0x7c,0x7b,0xb4,0x01,0x3c,0x7b,0xb2,0x00,0xfc, +0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x38,0x8e,0x09,0x00,0x04, +0x24,0x15,0x00,0x01,0x8e,0x06,0x00,0x0c,0x00,0x09,0x11,0x42,0x00,0x09,0x18,0xc2, +0x30,0x48,0x00,0x03,0x00,0x09,0x14,0x02,0x30,0x6c,0x00,0x03,0x00,0x09,0x26,0x02, +0x11,0x15,0x00,0x45,0x30,0x43,0x00,0x0f,0x29,0x02,0x00,0x02,0x14,0x40,0x00,0x26, +0x00,0x00,0x00,0x00,0x11,0x13,0x00,0x0f,0x00,0x00,0x38,0x21,0x00,0x07,0x22,0x02, +0x30,0x84,0xff,0x00,0x3c,0x03,0x00,0xff,0x00,0x07,0x2e,0x02,0x00,0x07,0x12,0x00, +0x00,0x43,0x10,0x24,0x00,0xa4,0x28,0x25,0x00,0xa2,0x28,0x25,0x00,0x07,0x1e,0x00, +0x00,0xa3,0x28,0x25,0x0c,0x00,0x01,0x92,0x01,0x20,0x20,0x21,0x08,0x00,0x03,0xa5, +0x02,0x51,0x10,0x21,0x11,0x95,0x00,0x0f,0x00,0x00,0x00,0x00,0x11,0x88,0x00,0x07, +0x00,0x00,0x00,0x00,0x00,0x04,0x10,0x80,0x27,0x83,0x8b,0x70,0x00,0x43,0x10,0x21, +0x8c,0x47,0x00,0x18,0x08,0x00,0x03,0xcc,0x00,0x07,0x22,0x02,0x00,0x04,0x10,0x40, +0x27,0x83,0x8b,0x78,0x00,0x43,0x10,0x21,0x94,0x47,0x00,0x02,0x08,0x00,0x03,0xcc, +0x00,0x07,0x22,0x02,0x27,0x82,0x8b,0x70,0x00,0x82,0x10,0x21,0x90,0x47,0x00,0x00, +0x08,0x00,0x03,0xcc,0x00,0x07,0x22,0x02,0x15,0x00,0xff,0xdc,0x00,0x00,0x38,0x21, +0x10,0x75,0x00,0x05,0x00,0x80,0x38,0x21,0x00,0x65,0x18,0x26,0x24,0x82,0x01,0x00, +0x00,0x00,0x38,0x21,0x00,0x43,0x38,0x0a,0x24,0x02,0x00,0x01,0x11,0x82,0x00,0x0e, +0x3c,0x02,0xb0,0x03,0x24,0x02,0x00,0x02,0x11,0x82,0x00,0x06,0x00,0x00,0x00,0x00, +0x3c,0x02,0xb0,0x03,0x00,0xe2,0x10,0x21,0x8c,0x47,0x00,0x00,0x08,0x00,0x03,0xcc, +0x00,0x07,0x22,0x02,0x3c,0x02,0xb0,0x03,0x00,0xe2,0x10,0x21,0x94,0x43,0x00,0x00, +0x08,0x00,0x03,0xcb,0x30,0x67,0xff,0xff,0x00,0xe2,0x10,0x21,0x90,0x43,0x00,0x00, +0x08,0x00,0x03,0xcb,0x30,0x67,0x00,0xff,0x30,0x62,0x00,0x03,0x00,0x02,0x12,0x00, +0x11,0x95,0x00,0x07,0x00,0x44,0x38,0x21,0x11,0x93,0x00,0x03,0x00,0x00,0x00,0x00, +0x08,0x00,0x03,0xfd,0x3c,0x02,0xb0,0x0a,0x08,0x00,0x04,0x02,0x3c,0x02,0xb0,0x0a, +0x08,0x00,0x04,0x06,0x3c,0x02,0xb0,0x0a,0x8e,0x09,0x00,0x04,0x8e,0x02,0x00,0x08, +0x8e,0x03,0x00,0x0c,0x00,0x09,0x41,0x42,0x00,0x02,0x22,0x02,0x00,0x03,0x3a,0x02, +0x30,0x84,0xff,0x00,0x30,0xe7,0xff,0x00,0x00,0x02,0x5e,0x02,0x00,0x02,0x32,0x00, +0x00,0x03,0x56,0x02,0x00,0x03,0x2a,0x00,0x01,0x64,0x58,0x25,0x00,0xd6,0x30,0x24, +0x01,0x47,0x50,0x25,0x00,0x02,0x16,0x00,0x00,0xb6,0x28,0x24,0x00,0x03,0x1e,0x00, +0x01,0x66,0x58,0x25,0x01,0x45,0x50,0x25,0x00,0x57,0x10,0x24,0x00,0x77,0x18,0x24, +0x01,0x62,0x38,0x25,0x01,0x43,0x30,0x25,0x00,0x09,0x10,0xc2,0x00,0x09,0x1c,0x02, +0x31,0x08,0x00,0x03,0x30,0x4c,0x00,0x03,0x30,0x63,0x00,0x0f,0x00,0x09,0x26,0x02, +0x00,0xe0,0x58,0x21,0x15,0x00,0x00,0x28,0x00,0xc0,0x50,0x21,0x24,0x02,0x00,0x01, +0x10,0x62,0x00,0x06,0x00,0x80,0x28,0x21,0x24,0x02,0x00,0x03,0x14,0x62,0xff,0x69, +0x02,0x51,0x10,0x21,0x24,0x85,0x01,0x00,0x24,0x02,0x00,0x01,0x11,0x82,0x00,0x15, +0x24,0x02,0x00,0x02,0x11,0x82,0x00,0x0a,0x3c,0x03,0xb0,0x03,0x00,0xa3,0x18,0x21, +0x8c,0x62,0x00,0x00,0x00,0x0a,0x20,0x27,0x01,0x6a,0x28,0x24,0x00,0x44,0x10,0x24, +0x00,0x45,0x10,0x25,0xac,0x62,0x00,0x00,0x08,0x00,0x03,0xa5,0x02,0x51,0x10,0x21, +0x00,0xa3,0x18,0x21,0x94,0x62,0x00,0x00,0x00,0x0a,0x20,0x27,0x01,0x6a,0x28,0x24, +0x00,0x44,0x10,0x24,0x00,0x45,0x10,0x25,0xa4,0x62,0x00,0x00,0x08,0x00,0x03,0xa5, +0x02,0x51,0x10,0x21,0x3c,0x03,0xb0,0x03,0x00,0xa3,0x18,0x21,0x90,0x62,0x00,0x00, +0x00,0x0a,0x20,0x27,0x01,0x6a,0x28,0x24,0x00,0x44,0x10,0x24,0x00,0x45,0x10,0x25, +0x08,0x00,0x03,0xa4,0xa0,0x62,0x00,0x00,0x24,0x02,0x00,0x01,0x11,0x02,0x00,0x21, +0x00,0x00,0x00,0x00,0x15,0x13,0xff,0x42,0x00,0x00,0x00,0x00,0x11,0x82,0x00,0x17, +0x00,0x00,0x00,0x00,0x11,0x88,0x00,0x0b,0x00,0x00,0x00,0x00,0x27,0x83,0x8b,0x70, +0x00,0x04,0x20,0x80,0x00,0x83,0x20,0x21,0x8c,0x82,0x00,0x18,0x00,0x06,0x18,0x27, +0x00,0xe6,0x28,0x24,0x00,0x43,0x10,0x24,0x00,0x45,0x10,0x25,0x08,0x00,0x03,0xa4, +0xac,0x82,0x00,0x18,0x27,0x83,0x8b,0x78,0x00,0x04,0x20,0x40,0x00,0x83,0x20,0x21, +0x94,0x82,0x00,0x02,0x00,0x06,0x18,0x27,0x00,0xe6,0x28,0x24,0x00,0x43,0x10,0x24, +0x00,0x45,0x10,0x25,0x08,0x00,0x03,0xa4,0xa4,0x82,0x00,0x02,0x27,0x83,0x8b,0x70, +0x00,0x83,0x18,0x21,0x90,0x62,0x00,0x00,0x00,0x06,0x20,0x27,0x08,0x00,0x04,0x5a, +0x00,0xe6,0x28,0x24,0x30,0x62,0x00,0x07,0x00,0x02,0x12,0x00,0x11,0x88,0x00,0x0f, +0x00,0x44,0x10,0x21,0x11,0x93,0x00,0x07,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x0a, +0x00,0x43,0x18,0x21,0x8c,0x62,0x00,0x00,0x00,0x06,0x20,0x27,0x08,0x00,0x04,0x47, +0x00,0xe6,0x28,0x24,0x3c,0x03,0xb0,0x0a,0x00,0x43,0x18,0x21,0x94,0x62,0x00,0x00, +0x00,0x06,0x20,0x27,0x08,0x00,0x04,0x50,0x00,0xe6,0x28,0x24,0x3c,0x03,0xb0,0x0a, +0x08,0x00,0x04,0x7d,0x00,0x43,0x18,0x21,0x97,0x85,0x8b,0xc4,0x3c,0x07,0xb0,0x02, +0x3c,0x04,0xb0,0x03,0x3c,0x02,0x80,0x00,0x00,0xa7,0x28,0x21,0x34,0x84,0x00,0x20, +0x24,0x42,0x12,0x58,0x24,0x03,0xff,0x80,0xac,0x82,0x00,0x00,0xa0,0xa3,0x00,0x07, +0x97,0x82,0x8b,0xc6,0x97,0x85,0x8b,0xc4,0x3c,0x06,0xb0,0x06,0x30,0x42,0xff,0xf8, +0x24,0x42,0x00,0x10,0x00,0xa2,0x10,0x21,0x30,0x42,0x0f,0xff,0x24,0x44,0x00,0x08, +0x30,0x84,0x0f,0xff,0x00,0x05,0x28,0xc2,0x3c,0x03,0x00,0x40,0x00,0xa3,0x28,0x25, +0x00,0x87,0x20,0x21,0x34,0xc6,0x80,0x18,0xac,0xc5,0x00,0x00,0xaf,0x84,0x8b,0xc0, +0xa7,0x82,0x8b,0xc4,0xa7,0x80,0x8b,0xc6,0xaf,0x80,0x8b,0xc8,0x03,0xe0,0x00,0x08, +0x00,0x00,0x00,0x00,0x30,0xa5,0x00,0xff,0x30,0x84,0x00,0xff,0x24,0x02,0x00,0x01, +0x00,0xe0,0x48,0x21,0x30,0xc6,0x00,0xff,0x8f,0xa7,0x00,0x10,0x10,0x82,0x00,0x07, +0x00,0xa0,0x40,0x21,0x24,0x02,0x00,0x03,0x10,0x82,0x00,0x03,0x00,0x00,0x00,0x00, +0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x24,0xa8,0x01,0x00,0x3c,0x03,0xb0,0x03, +0x24,0x02,0x00,0x01,0x00,0x07,0x20,0x27,0x01,0x27,0x28,0x24,0x10,0xc2,0x00,0x14, +0x01,0x03,0x18,0x21,0x24,0x02,0x00,0x02,0x10,0xc2,0x00,0x09,0x00,0x07,0x50,0x27, +0x3c,0x03,0xb0,0x03,0x01,0x03,0x18,0x21,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x4a,0x10,0x24,0x00,0x45,0x10,0x25,0x08,0x00,0x04,0xe1,0xac,0x62,0x00,0x00, +0x3c,0x03,0xb0,0x03,0x01,0x03,0x18,0x21,0x94,0x62,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x4a,0x10,0x24,0x00,0x45,0x10,0x25,0x03,0xe0,0x00,0x08,0xa4,0x62,0x00,0x00, +0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x10,0x24,0x00,0x45,0x10,0x25, +0xa0,0x62,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0x84,0x00,0x07, +0x00,0x04,0x22,0x00,0x30,0xa5,0x00,0xff,0x00,0x85,0x28,0x21,0x3c,0x02,0xb0,0x0a, +0x00,0xa2,0x40,0x21,0x30,0xc6,0x00,0xff,0x24,0x02,0x00,0x01,0x8f,0xa4,0x00,0x10, +0x10,0xc2,0x00,0x14,0x24,0x02,0x00,0x02,0x00,0x04,0x50,0x27,0x10,0xc2,0x00,0x09, +0x00,0xe4,0x48,0x24,0x3c,0x03,0xb0,0x0a,0x00,0xa3,0x18,0x21,0x8c,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x4a,0x10,0x24,0x00,0x49,0x10,0x25,0x03,0xe0,0x00,0x08, +0xac,0x62,0x00,0x00,0x3c,0x03,0xb0,0x0a,0x00,0xa3,0x18,0x21,0x94,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x4a,0x10,0x24,0x00,0x49,0x10,0x25,0x03,0xe0,0x00,0x08, +0xa4,0x62,0x00,0x00,0x91,0x02,0x00,0x00,0x00,0x04,0x18,0x27,0x00,0xe4,0x20,0x24, +0x00,0x43,0x10,0x24,0x00,0x44,0x10,0x25,0x03,0xe0,0x00,0x08,0xa1,0x02,0x00,0x00, +0x30,0xa9,0x00,0xff,0x27,0x83,0x8b,0x70,0x30,0x85,0x00,0xff,0x24,0x02,0x00,0x01, +0x00,0x07,0x50,0x27,0x00,0xc7,0x40,0x24,0x11,0x22,0x00,0x17,0x00,0xa3,0x18,0x21, +0x00,0x05,0x20,0x40,0x27,0x82,0x8b,0x70,0x00,0x05,0x28,0x80,0x27,0x83,0x8b,0x78, +0x00,0x83,0x50,0x21,0x00,0xa2,0x20,0x21,0x24,0x02,0x00,0x02,0x00,0x07,0x40,0x27, +0x11,0x22,0x00,0x07,0x00,0xc7,0x28,0x24,0x8c,0x82,0x00,0x18,0x00,0x00,0x00,0x00, +0x00,0x48,0x10,0x24,0x00,0x45,0x10,0x25,0x03,0xe0,0x00,0x08,0xac,0x82,0x00,0x18, +0x95,0x42,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x48,0x10,0x24,0x00,0x45,0x10,0x25, +0x03,0xe0,0x00,0x08,0xa5,0x42,0x00,0x02,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x4a,0x10,0x24,0x00,0x48,0x10,0x25,0x03,0xe0,0x00,0x08,0xa0,0x62,0x00,0x00, +0x00,0x04,0x32,0x02,0x30,0xc6,0xff,0x00,0x00,0x04,0x16,0x02,0x00,0x04,0x1a,0x00, +0x3c,0x05,0x00,0xff,0x00,0x65,0x18,0x24,0x00,0x46,0x10,0x25,0x00,0x43,0x10,0x25, +0x00,0x04,0x26,0x00,0x03,0xe0,0x00,0x08,0x00,0x44,0x10,0x25,0x3c,0x03,0xb0,0x03, +0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xe8,0x34,0x63,0x00,0x20,0x24,0x42,0x14,0xdc, +0x3c,0x04,0xb0,0x03,0xaf,0xbf,0x00,0x14,0xac,0x62,0x00,0x00,0xaf,0xb0,0x00,0x10, +0x34,0x84,0x00,0x2c,0x8c,0x83,0x00,0x00,0xa7,0x80,0xbc,0x00,0x00,0x03,0x12,0x02, +0x00,0x03,0x2d,0x02,0x30,0x42,0x0f,0xff,0xa3,0x83,0xbc,0x08,0xa7,0x85,0xbc,0x0c, +0xa7,0x82,0xbc,0x0a,0xa7,0x80,0xbc,0x02,0xa7,0x80,0xbc,0x04,0xa7,0x80,0xbc,0x06, +0x0c,0x00,0x06,0xd1,0x24,0x04,0x05,0x00,0x3c,0x05,0x08,0x00,0x00,0x45,0x28,0x25, +0x24,0x04,0x05,0x00,0x0c,0x00,0x06,0xbf,0x00,0x40,0x80,0x21,0x3c,0x02,0xf7,0xff, +0x34,0x42,0xff,0xff,0x02,0x02,0x80,0x24,0x02,0x00,0x28,0x21,0x0c,0x00,0x06,0xbf, +0x24,0x04,0x05,0x00,0x3c,0x02,0xb0,0x03,0x3c,0x03,0xb0,0x03,0x34,0x42,0x01,0x08, +0x34,0x63,0x01,0x18,0x8c,0x45,0x00,0x00,0x8c,0x64,0x00,0x00,0x3c,0x02,0x00,0x0f, +0x3c,0x03,0x00,0x4c,0x30,0x84,0x02,0x00,0x34,0x63,0x4b,0x40,0xaf,0x85,0xbc,0x10, +0x10,0x80,0x00,0x06,0x34,0x42,0x42,0x40,0xaf,0x83,0xbc,0x14,0x8f,0xbf,0x00,0x14, +0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0xaf,0x82,0xbc,0x14, +0x08,0x00,0x05,0x67,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00, +0x27,0xbd,0xff,0xc8,0x34,0x63,0x00,0x20,0x24,0x42,0x15,0xb8,0x30,0x84,0x00,0xff, +0xaf,0xbf,0x00,0x30,0xaf,0xb7,0x00,0x2c,0xaf,0xb6,0x00,0x28,0xaf,0xb5,0x00,0x24, +0xaf,0xb4,0x00,0x20,0xaf,0xb3,0x00,0x1c,0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14, +0xaf,0xb0,0x00,0x10,0xac,0x62,0x00,0x00,0x10,0x80,0x00,0x1c,0x24,0x02,0x00,0x02, +0x10,0x82,0x00,0x08,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x30,0x7b,0xb6,0x01,0x7c, +0x7b,0xb4,0x01,0x3c,0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x38,0xa7,0x80,0xbc,0x00,0xa7,0x80,0xbc,0x02,0xa7,0x80,0xbc,0x04, +0xa7,0x80,0xbc,0x06,0x0c,0x00,0x06,0xd1,0x24,0x04,0x05,0x00,0x3c,0x05,0x08,0x00, +0x00,0x45,0x28,0x25,0x24,0x04,0x05,0x00,0x0c,0x00,0x06,0xbf,0x00,0x40,0x80,0x21, +0x3c,0x05,0xf7,0xff,0x34,0xa5,0xff,0xff,0x02,0x05,0x28,0x24,0x0c,0x00,0x06,0xbf, +0x24,0x04,0x05,0x00,0x08,0x00,0x05,0x82,0x00,0x00,0x00,0x00,0x0c,0x00,0x06,0xd1, +0x24,0x04,0x05,0xa0,0x24,0x04,0x05,0xa4,0x0c,0x00,0x06,0xd1,0x00,0x02,0xbc,0x02, +0x24,0x04,0x05,0xa8,0x00,0x02,0xb4,0x02,0x0c,0x00,0x06,0xd1,0x30,0x55,0xff,0xff, +0x00,0x40,0x80,0x21,0x97,0x84,0xbc,0x00,0x97,0x82,0xbc,0x02,0x97,0x83,0xbc,0x06, +0x02,0xe4,0x20,0x23,0x02,0xa2,0x10,0x23,0x00,0x82,0x20,0x21,0x97,0x82,0xbc,0x04, +0x32,0x14,0xff,0xff,0x02,0x83,0x18,0x23,0x02,0xc2,0x10,0x23,0x00,0x82,0x20,0x21, +0x93,0x82,0xbc,0x08,0x00,0x83,0x20,0x21,0x30,0x84,0xff,0xff,0x00,0x82,0x10,0x2b, +0x14,0x40,0x00,0xaa,0x00,0x00,0x00,0x00,0x97,0x82,0xbc,0x0c,0x00,0x00,0x00,0x00, +0x00,0x44,0x10,0x2b,0x14,0x40,0x00,0x7f,0x00,0x00,0x00,0x00,0x97,0x82,0xbc,0x0a, +0x00,0x00,0x00,0x00,0x00,0x44,0x10,0x2b,0x10,0x40,0x00,0x3a,0x00,0x00,0x00,0x00, +0x0c,0x00,0x06,0xd1,0x24,0x04,0x04,0x50,0x30,0x51,0x00,0x7f,0x00,0x40,0x80,0x21, +0x2e,0x22,0x00,0x32,0x10,0x40,0x00,0x13,0x24,0x02,0x00,0x20,0x12,0x22,0x00,0x17, +0x24,0x02,0xff,0x80,0x02,0x02,0x10,0x24,0x26,0x31,0x00,0x01,0x00,0x51,0x80,0x25, +0x02,0x00,0x28,0x21,0x0c,0x00,0x06,0xbf,0x24,0x04,0x04,0x50,0x02,0x00,0x28,0x21, +0x0c,0x00,0x06,0xbf,0x24,0x04,0x04,0x58,0x02,0x00,0x28,0x21,0x0c,0x00,0x06,0xbf, +0x24,0x04,0x04,0x60,0x02,0x00,0x28,0x21,0x24,0x04,0x04,0x68,0x0c,0x00,0x06,0xbf, +0x00,0x00,0x00,0x00,0xa7,0x97,0xbc,0x00,0xa7,0x95,0xbc,0x02,0xa7,0x96,0xbc,0x04, +0xa7,0x94,0xbc,0x06,0x08,0x00,0x05,0x82,0x00,0x00,0x00,0x00,0x0c,0x00,0x06,0xd1, +0x24,0x04,0x02,0x08,0x3c,0x04,0x00,0xc0,0x00,0x40,0x28,0x21,0x00,0x44,0x10,0x24, +0x00,0x02,0x15,0x82,0x24,0x03,0x00,0x03,0x10,0x43,0x00,0x07,0x00,0x00,0x00,0x00, +0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff,0x00,0xa2,0x10,0x24,0x00,0x44,0x28,0x25, +0x0c,0x00,0x06,0xbf,0x24,0x04,0x02,0x08,0x0c,0x00,0x06,0xd1,0x24,0x04,0x02,0x2c, +0x00,0x40,0x90,0x21,0x3c,0x02,0xff,0xff,0x34,0x42,0x3f,0xff,0x02,0x42,0x90,0x24, +0x02,0x40,0x28,0x21,0x0c,0x00,0x06,0xbf,0x24,0x04,0x02,0x2c,0x08,0x00,0x05,0xc9, +0x24,0x02,0xff,0x80,0x0c,0x00,0x06,0xd1,0x24,0x04,0x04,0x50,0x30,0x51,0x00,0x7f, +0x24,0x02,0x00,0x20,0x16,0x22,0xff,0xdb,0x00,0x00,0x00,0x00,0x0c,0x00,0x06,0xd1, +0x24,0x04,0x02,0x2c,0x34,0x52,0x40,0x00,0x02,0x40,0x28,0x21,0x0c,0x00,0x06,0xbf, +0x24,0x04,0x02,0x2c,0x0c,0x00,0x06,0xd1,0x24,0x04,0x02,0x58,0x24,0x04,0x02,0x5c, +0x0c,0x00,0x06,0xd1,0x00,0x02,0x9e,0x02,0x30,0x43,0x00,0xff,0x00,0x13,0x12,0x00, +0x00,0x43,0x10,0x25,0x2c,0x43,0x00,0x04,0x14,0x60,0x00,0x1d,0x2c,0x42,0x00,0x11, +0x10,0x40,0x00,0x0b,0x00,0x00,0x00,0x00,0x3c,0x02,0xff,0xff,0x34,0x42,0x3f,0xff, +0x02,0x42,0x90,0x24,0x02,0x40,0x28,0x21,0x24,0x04,0x02,0x2c,0x0c,0x00,0x06,0xbf, +0x36,0x52,0x80,0x00,0x02,0x40,0x28,0x21,0x08,0x00,0x05,0xd7,0x24,0x04,0x02,0x2c, +0x0c,0x00,0x06,0xd1,0x24,0x04,0x02,0x08,0x3c,0x04,0x00,0xc0,0x00,0x40,0x28,0x21, +0x00,0x44,0x10,0x24,0x00,0x02,0x15,0x82,0x24,0x03,0x00,0x02,0x14,0x43,0xff,0xee, +0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff,0x00,0xa2,0x10,0x24,0x00,0x44,0x28,0x25, +0x0c,0x00,0x06,0xbf,0x24,0x04,0x02,0x08,0x08,0x00,0x06,0x13,0x3c,0x02,0xff,0xff, +0x0c,0x00,0x06,0xd1,0x24,0x04,0x02,0x08,0x00,0x40,0x28,0x21,0x00,0x02,0x15,0x82, +0x30,0x42,0x00,0x03,0x24,0x03,0x00,0x03,0x14,0x43,0xff,0xdf,0x3c,0x02,0xff,0x3f, +0x34,0x42,0xff,0xff,0x00,0xa2,0x10,0x24,0x3c,0x03,0x00,0x80,0x08,0x00,0x06,0x28, +0x00,0x43,0x28,0x25,0x0c,0x00,0x06,0xd1,0x24,0x04,0x04,0x50,0x30,0x51,0x00,0x7f, +0x00,0x40,0x80,0x21,0x2e,0x22,0x00,0x32,0x10,0x40,0xff,0x9a,0x24,0x02,0x00,0x20, +0x12,0x22,0x00,0x04,0x24,0x02,0xff,0x80,0x02,0x02,0x10,0x24,0x08,0x00,0x05,0xcb, +0x26,0x31,0x00,0x02,0x0c,0x00,0x06,0xd1,0x24,0x04,0x02,0x08,0x3c,0x04,0x00,0xc0, +0x00,0x40,0x28,0x21,0x00,0x44,0x10,0x24,0x00,0x02,0x15,0x82,0x24,0x03,0x00,0x03, +0x10,0x43,0x00,0x07,0x00,0x00,0x00,0x00,0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff, +0x00,0xa2,0x10,0x24,0x00,0x44,0x28,0x25,0x0c,0x00,0x06,0xbf,0x24,0x04,0x02,0x08, +0x0c,0x00,0x06,0xd1,0x24,0x04,0x02,0x2c,0x00,0x40,0x90,0x21,0x3c,0x02,0xff,0xff, +0x34,0x42,0x3f,0xff,0x02,0x42,0x90,0x24,0x02,0x40,0x28,0x21,0x0c,0x00,0x06,0xbf, +0x24,0x04,0x02,0x2c,0x08,0x00,0x06,0x42,0x24,0x02,0xff,0x80,0x0c,0x00,0x06,0xd1, +0x24,0x04,0x04,0x50,0x00,0x40,0x80,0x21,0x30,0x51,0x00,0x7f,0x24,0x02,0x00,0x20, +0x12,0x22,0x00,0x1d,0x2e,0x22,0x00,0x21,0x14,0x40,0xff,0x72,0x24,0x02,0xff,0x80, +0x02,0x02,0x10,0x24,0x26,0x31,0xff,0xff,0x00,0x51,0x80,0x25,0x24,0x04,0x04,0x50, +0x0c,0x00,0x06,0xbf,0x02,0x00,0x28,0x21,0x24,0x04,0x04,0x58,0x0c,0x00,0x06,0xbf, +0x02,0x00,0x28,0x21,0x24,0x04,0x04,0x60,0x0c,0x00,0x06,0xbf,0x02,0x00,0x28,0x21, +0x02,0x00,0x28,0x21,0x0c,0x00,0x06,0xbf,0x24,0x04,0x04,0x68,0x24,0x02,0x00,0x20, +0x16,0x22,0xff,0x60,0x00,0x00,0x00,0x00,0x0c,0x00,0x06,0xd1,0x24,0x04,0x02,0x2c, +0x00,0x40,0x90,0x21,0x3c,0x02,0xff,0xff,0x34,0x42,0x3f,0xff,0x02,0x42,0x10,0x24, +0x08,0x00,0x06,0x19,0x34,0x52,0x80,0x00,0x0c,0x00,0x06,0xd1,0x24,0x04,0x02,0x2c, +0x34,0x52,0x40,0x00,0x02,0x40,0x28,0x21,0x0c,0x00,0x06,0xbf,0x24,0x04,0x02,0x2c, +0x0c,0x00,0x06,0xd1,0x24,0x04,0x02,0x58,0x24,0x04,0x02,0x5c,0x0c,0x00,0x06,0xd1, +0x00,0x02,0x9e,0x02,0x30,0x43,0x00,0xff,0x00,0x13,0x12,0x00,0x00,0x43,0x10,0x25, +0x2c,0x43,0x00,0x04,0x14,0x60,0x00,0x20,0x2c,0x42,0x00,0x11,0x10,0x40,0x00,0x0d, +0x00,0x00,0x00,0x00,0x3c,0x02,0xff,0xff,0x34,0x42,0x3f,0xff,0x02,0x42,0x90,0x24, +0x02,0x40,0x28,0x21,0x24,0x04,0x02,0x2c,0x0c,0x00,0x06,0xbf,0x36,0x52,0x80,0x00, +0x02,0x40,0x28,0x21,0x0c,0x00,0x06,0xbf,0x24,0x04,0x02,0x2c,0x08,0x00,0x06,0x66, +0x2e,0x22,0x00,0x21,0x0c,0x00,0x06,0xd1,0x24,0x04,0x02,0x08,0x3c,0x04,0x00,0xc0, +0x00,0x40,0x28,0x21,0x00,0x44,0x10,0x24,0x00,0x02,0x15,0x82,0x24,0x03,0x00,0x02, +0x14,0x43,0xff,0xec,0x00,0x00,0x00,0x00,0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff, +0x00,0xa2,0x10,0x24,0x00,0x44,0x28,0x25,0x0c,0x00,0x06,0xbf,0x24,0x04,0x02,0x08, +0x08,0x00,0x06,0x96,0x3c,0x02,0xff,0xff,0x0c,0x00,0x06,0xd1,0x24,0x04,0x02,0x08, +0x00,0x40,0x28,0x21,0x00,0x02,0x15,0x82,0x30,0x42,0x00,0x03,0x24,0x03,0x00,0x03, +0x14,0x43,0xff,0xdc,0x3c,0x03,0x00,0x80,0x3c,0x02,0xff,0x3f,0x34,0x42,0xff,0xff, +0x00,0xa2,0x10,0x24,0x08,0x00,0x06,0xae,0x00,0x43,0x28,0x25,0x30,0x83,0x00,0x03, +0x00,0x04,0x20,0x40,0x00,0x83,0x20,0x23,0x3c,0x02,0xb0,0x0a,0x00,0x82,0x20,0x21, +0x3c,0x06,0x00,0x01,0xac,0x85,0x00,0x00,0x24,0x07,0x00,0x01,0x00,0x00,0x28,0x21, +0x34,0xc6,0x86,0x9f,0x8c,0x82,0x10,0x00,0x24,0xa5,0x00,0x01,0x10,0x47,0x00,0x03, +0x00,0xc5,0x18,0x2b,0x10,0x60,0xff,0xfb,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08, +0x00,0x00,0x00,0x00,0x30,0x83,0x00,0x03,0x00,0x04,0x20,0x40,0x3c,0x02,0xb0,0x0a, +0x00,0x83,0x20,0x23,0x00,0x82,0x20,0x21,0x3c,0x06,0x00,0x01,0x24,0x02,0xff,0xff, +0xac,0x82,0x10,0x00,0x00,0x00,0x28,0x21,0x24,0x07,0x00,0x01,0x34,0xc6,0x86,0x9f, +0x8c,0x82,0x10,0x00,0x24,0xa5,0x00,0x01,0x10,0x47,0x00,0x03,0x00,0xc5,0x18,0x2b, +0x10,0x60,0xff,0xfb,0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x00,0x03,0xe0,0x00,0x08, +0x00,0x00,0x00,0x00,0x3c,0x05,0xb0,0x03,0x3c,0x02,0x80,0x00,0x24,0x42,0x1b,0x94, +0x24,0x03,0x00,0x01,0x34,0xa5,0x00,0x20,0x3c,0x06,0xb0,0x03,0xac,0xa2,0x00,0x00, +0x34,0xc6,0x01,0x04,0xa0,0x83,0x00,0x48,0xa0,0x80,0x00,0x04,0xa0,0x80,0x00,0x05, +0xa0,0x80,0x00,0x06,0xa0,0x80,0x00,0x07,0xa0,0x80,0x00,0x08,0xa0,0x80,0x00,0x09, +0xa0,0x80,0x00,0x0a,0xa0,0x80,0x00,0x11,0xa0,0x80,0x00,0x13,0xa0,0x80,0x00,0x49, +0x94,0xc2,0x00,0x00,0xac,0x80,0x00,0x00,0xa0,0x80,0x00,0x4e,0x00,0x02,0x14,0x00, +0x00,0x02,0x14,0x03,0x30,0x43,0x00,0xff,0x30,0x42,0xff,0x00,0xa4,0x82,0x00,0x44, +0xa4,0x83,0x00,0x46,0xac,0x80,0x00,0x24,0xac,0x80,0x00,0x28,0xac,0x80,0x00,0x2c, +0xac,0x80,0x00,0x30,0xac,0x80,0x00,0x34,0xac,0x80,0x00,0x38,0xac,0x80,0x00,0x3c, +0x03,0xe0,0x00,0x08,0xac,0x80,0x00,0x40,0x84,0x83,0x00,0x0c,0x3c,0x07,0xb0,0x03, +0x34,0xe7,0x00,0x20,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80, +0x27,0x83,0x90,0x04,0x00,0x43,0x10,0x21,0x8c,0x48,0x00,0x18,0x3c,0x02,0x80,0x00, +0x24,0x42,0x1c,0x28,0xac,0xe2,0x00,0x00,0x8d,0x03,0x00,0x08,0x80,0x82,0x00,0x13, +0x00,0x05,0x2c,0x00,0x00,0x03,0x1e,0x02,0x00,0x02,0x12,0x00,0x30,0x63,0x00,0x7e, +0x00,0x62,0x18,0x21,0x00,0x65,0x18,0x21,0x3c,0x02,0xc0,0x00,0x3c,0x05,0xb0,0x05, +0x34,0x42,0x04,0x00,0x24,0x63,0x00,0x01,0x3c,0x07,0xb0,0x05,0x3c,0x08,0xb0,0x05, +0x34,0xa5,0x04,0x20,0xac,0xa3,0x00,0x00,0x00,0xc2,0x30,0x21,0x34,0xe7,0x04,0x24, +0x35,0x08,0x02,0x28,0x24,0x02,0x00,0x01,0x24,0x03,0x00,0x20,0xac,0xe6,0x00,0x00, +0xac,0x82,0x00,0x3c,0x03,0xe0,0x00,0x08,0xa1,0x03,0x00,0x00,0x27,0xbd,0xff,0xa8, +0x00,0x07,0x60,0x80,0x27,0x82,0xb4,0x00,0xaf,0xbe,0x00,0x50,0xaf,0xb7,0x00,0x4c, +0xaf,0xb5,0x00,0x44,0xaf,0xb4,0x00,0x40,0xaf,0xbf,0x00,0x54,0xaf,0xb6,0x00,0x48, +0xaf,0xb3,0x00,0x3c,0xaf,0xb2,0x00,0x38,0xaf,0xb1,0x00,0x34,0xaf,0xb0,0x00,0x30, +0x01,0x82,0x10,0x21,0x8c,0x43,0x00,0x00,0x00,0xe0,0x70,0x21,0x3c,0x02,0x80,0x00, +0x94,0x73,0x00,0x14,0x3c,0x07,0xb0,0x03,0x34,0xe7,0x00,0x20,0x24,0x42,0x1c,0xbc, +0x3c,0x03,0xb0,0x05,0xac,0xe2,0x00,0x00,0x34,0x63,0x01,0x28,0x90,0x67,0x00,0x00, +0x00,0x13,0xa8,0xc0,0x02,0xb3,0x18,0x21,0x27,0x82,0x90,0x04,0x00,0x03,0x18,0x80, +0x00,0x62,0x18,0x21,0x00,0x05,0x2c,0x00,0x00,0x07,0x3e,0x00,0x28,0xc2,0x00,0x03, +0x00,0xc0,0xa0,0x21,0x00,0x80,0x78,0x21,0x00,0x05,0xbc,0x03,0x8c,0x68,0x00,0x18, +0x02,0xa0,0x58,0x21,0x10,0x40,0x01,0x81,0x00,0x07,0xf6,0x03,0x00,0xde,0x10,0x07, +0x30,0x5e,0x00,0x01,0x01,0x73,0x10,0x21,0x27,0x83,0x90,0x08,0x00,0x02,0x10,0x80, +0x00,0x43,0x10,0x21,0x80,0x4d,0x00,0x06,0x8d,0x03,0x00,0x00,0x8d,0x02,0x00,0x04, +0x8d,0x0a,0x00,0x08,0x8d,0x03,0x00,0x0c,0xaf,0xa2,0x00,0x20,0x11,0xa0,0x01,0x71, +0xaf,0xa3,0x00,0x18,0x27,0x82,0xb4,0x00,0x01,0x82,0x10,0x21,0x8c,0x44,0x00,0x00, +0x00,0x00,0x00,0x00,0x90,0x83,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x04, +0x14,0x60,0x00,0x12,0x00,0x00,0xb0,0x21,0x3c,0x02,0xb0,0x09,0x34,0x42,0x01,0x46, +0x90,0x43,0x00,0x00,0x2a,0x84,0x00,0x04,0x10,0x80,0x01,0x56,0x30,0x65,0x00,0x01, +0x91,0xe2,0x00,0x09,0x00,0x00,0x00,0x00,0x12,0x82,0x00,0x02,0x00,0x00,0x00,0x00, +0x00,0x00,0x28,0x21,0x14,0xa0,0x00,0x03,0x00,0x00,0x38,0x21,0x13,0xc0,0x00,0x03, +0x38,0xf6,0x00,0x01,0x24,0x07,0x00,0x01,0x38,0xf6,0x00,0x01,0x01,0x73,0x10,0x21, +0x00,0x02,0x30,0x80,0x27,0x83,0x90,0x10,0x00,0xc3,0x48,0x21,0x91,0x25,0x00,0x00, +0x8f,0xa4,0x00,0x20,0x2c,0xa3,0x00,0x04,0x00,0x04,0x11,0xc3,0x30,0x42,0x00,0x01, +0x00,0x03,0xb0,0x0b,0x12,0xc0,0x00,0xd8,0xaf,0xa2,0x00,0x24,0x93,0x90,0xbb,0xea, +0x00,0x0a,0x16,0x42,0x30,0x52,0x00,0x3f,0x2e,0x06,0x00,0x0c,0x10,0xc0,0x00,0xc0, +0x00,0xa0,0x20,0x21,0x2c,0xa2,0x00,0x10,0x14,0x40,0x00,0x04,0x00,0x90,0x10,0x2b, +0x30,0xa2,0x00,0x07,0x24,0x44,0x00,0x04,0x00,0x90,0x10,0x2b,0x10,0x40,0x00,0x0b, +0x01,0x73,0x10,0x21,0x27,0x85,0xbb,0x1c,0x00,0x10,0x10,0x40,0x00,0x50,0x10,0x21, +0x00,0x45,0x10,0x21,0x90,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x18,0x2b, +0x14,0x60,0xff,0xfa,0x00,0x10,0x10,0x40,0x01,0x73,0x10,0x21,0x00,0x02,0x10,0x80, +0x27,0x83,0x90,0x08,0x00,0x43,0x10,0x21,0x31,0xa4,0x00,0x01,0x10,0x80,0x00,0xa5, +0xa0,0x50,0x00,0x07,0x3c,0x04,0xb0,0x05,0x34,0x84,0x00,0x08,0x24,0x02,0x00,0x01, +0x3c,0x03,0x80,0x00,0xa1,0xe2,0x00,0x4e,0xac,0x83,0x00,0x00,0x8c,0x85,0x00,0x00, +0x3c,0x02,0x00,0xf0,0x3c,0x03,0x40,0xf0,0x34,0x42,0xf0,0x00,0x34,0x63,0xf0,0x00, +0x24,0x17,0x00,0x0e,0x24,0x13,0x01,0x06,0xac,0x82,0x00,0x00,0xac,0x83,0x00,0x00, +0x27,0x82,0xb4,0x00,0x01,0x82,0x10,0x21,0x8c,0x43,0x00,0x00,0x24,0x05,0x00,0x01, +0xaf,0xa5,0x00,0x1c,0x90,0x62,0x00,0x16,0x00,0x13,0xa8,0xc0,0x32,0x51,0x00,0x02, +0x34,0x42,0x00,0x04,0xa0,0x62,0x00,0x16,0x8f,0xa3,0x00,0x20,0x8f,0xa4,0x00,0x18, +0x00,0x03,0x13,0x43,0x00,0x04,0x1a,0x02,0x30,0x47,0x00,0x01,0x12,0x20,0x00,0x04, +0x30,0x64,0x07,0xff,0x2e,0x03,0x00,0x04,0x32,0x42,0x00,0x33,0x00,0x43,0x90,0x0b, +0x8f,0xa5,0x00,0x24,0x8f,0xa6,0x00,0x1c,0x00,0x12,0x10,0x40,0x00,0x05,0x19,0xc0, +0x00,0x47,0x10,0x21,0x00,0x06,0x2a,0x80,0x00,0x43,0x10,0x21,0x00,0x10,0x32,0x00, +0x00,0x04,0x24,0x80,0x02,0x65,0x28,0x21,0x00,0xa4,0x28,0x21,0x00,0x46,0x10,0x21, +0x00,0x17,0x1c,0x00,0x3c,0x04,0xc0,0x00,0x00,0x43,0x30,0x21,0x16,0x80,0x00,0x29, +0x00,0xa4,0x28,0x21,0x3c,0x02,0xb0,0x05,0x34,0x42,0x04,0x00,0x3c,0x03,0xb0,0x05, +0x3c,0x04,0xb0,0x05,0xac,0x46,0x00,0x00,0x34,0x63,0x04,0x04,0x34,0x84,0x02,0x28, +0x24,0x02,0x00,0x01,0xac,0x65,0x00,0x00,0xa0,0x82,0x00,0x00,0x3c,0x02,0xb0,0x09, +0x34,0x42,0x01,0x46,0x90,0x44,0x00,0x00,0x91,0xe3,0x00,0x09,0x30,0x86,0x00,0x01, +0x02,0x83,0x18,0x26,0x00,0x03,0x30,0x0b,0x14,0xc0,0x00,0x03,0x00,0x00,0x28,0x21, +0x13,0xc0,0x00,0x03,0x02,0xb3,0x10,0x21,0x24,0x05,0x00,0x01,0x02,0xb3,0x10,0x21, +0x27,0x83,0x90,0x08,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x84,0x48,0x00,0x04, +0x00,0xa0,0x30,0x21,0x00,0xe0,0x20,0x21,0x02,0x80,0x28,0x21,0x02,0xc0,0x38,0x21, +0x0c,0x00,0x00,0x70,0xaf,0xa8,0x00,0x10,0x7b,0xbe,0x02,0xbc,0x7b,0xb6,0x02,0x7c, +0x7b,0xb4,0x02,0x3c,0x7b,0xb2,0x01,0xfc,0x7b,0xb0,0x01,0xbc,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x58,0x24,0x02,0x00,0x01,0x12,0x82,0x00,0x3d,0x3c,0x02,0xb0,0x05, +0x24,0x02,0x00,0x02,0x12,0x82,0x00,0x31,0x3c,0x02,0xb0,0x05,0x24,0x02,0x00,0x03, +0x12,0x82,0x00,0x25,0x3c,0x02,0xb0,0x05,0x24,0x02,0x00,0x10,0x12,0x82,0x00,0x19, +0x3c,0x02,0xb0,0x05,0x24,0x02,0x00,0x11,0x12,0x82,0x00,0x0d,0x3c,0x02,0xb0,0x05, +0x24,0x02,0x00,0x12,0x16,0x82,0xff,0xd1,0x3c,0x02,0xb0,0x05,0x3c,0x03,0xb0,0x05, +0x34,0x42,0x04,0x20,0x3c,0x04,0xb0,0x05,0x34,0x63,0x04,0x24,0xac,0x46,0x00,0x00, +0x34,0x84,0x02,0x28,0xac,0x65,0x00,0x00,0x08,0x00,0x07,0xe6,0x24,0x02,0x00,0x20, +0x34,0x42,0x04,0x40,0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05,0xac,0x46,0x00,0x00, +0x34,0x63,0x04,0x44,0x34,0x84,0x02,0x28,0x24,0x02,0x00,0x40,0x08,0x00,0x07,0xe6, +0xac,0x65,0x00,0x00,0x34,0x42,0x04,0x28,0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05, +0xac,0x46,0x00,0x00,0x34,0x63,0x04,0x2c,0x34,0x84,0x02,0x28,0x24,0x02,0xff,0x80, +0x08,0x00,0x07,0xe6,0xac,0x65,0x00,0x00,0x34,0x42,0x04,0x18,0x3c,0x03,0xb0,0x05, +0x3c,0x04,0xb0,0x05,0xac,0x46,0x00,0x00,0x34,0x63,0x04,0x1c,0x34,0x84,0x02,0x28, +0x24,0x02,0x00,0x08,0x08,0x00,0x07,0xe6,0xac,0x65,0x00,0x00,0x34,0x42,0x04,0x10, +0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05,0xac,0x46,0x00,0x00,0x34,0x63,0x04,0x14, +0x34,0x84,0x02,0x28,0x24,0x02,0x00,0x04,0x08,0x00,0x07,0xe6,0xac,0x65,0x00,0x00, +0x34,0x42,0x04,0x08,0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05,0xac,0x46,0x00,0x00, +0x34,0x63,0x04,0x0c,0x34,0x84,0x02,0x28,0x24,0x02,0x00,0x02,0x08,0x00,0x07,0xe6, +0xac,0x65,0x00,0x00,0x24,0x17,0x00,0x14,0x08,0x00,0x07,0xb8,0x24,0x13,0x01,0x02, +0x30,0xa2,0x00,0x07,0x24,0x44,0x00,0x0c,0x00,0x90,0x18,0x2b,0x10,0x60,0x00,0x0c, +0x26,0x02,0x00,0x04,0x27,0x85,0xbb,0x1c,0x00,0x10,0x10,0x40,0x00,0x50,0x10,0x21, +0x00,0x45,0x10,0x21,0x90,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0x18,0x2b, +0x14,0x60,0xff,0xfa,0x00,0x10,0x10,0x40,0x2e,0x06,0x00,0x0c,0x26,0x02,0x00,0x04, +0x08,0x00,0x07,0xa2,0x00,0x46,0x80,0x0a,0x27,0x82,0xb4,0x00,0x01,0x82,0x20,0x21, +0x8c,0x87,0x00,0x00,0x00,0x00,0x00,0x00,0x90,0xe2,0x00,0x19,0x00,0x00,0x00,0x00, +0x14,0x40,0x00,0x07,0x00,0x00,0x00,0x00,0x27,0x82,0x90,0x20,0x00,0xc2,0x10,0x21, +0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x60,0x00,0x14,0x00,0x00,0x00,0x00, +0x90,0xe3,0x00,0x16,0x27,0x82,0x90,0x08,0x00,0xc2,0x10,0x21,0x34,0x63,0x00,0x20, +0x90,0x50,0x00,0x07,0xa0,0xe3,0x00,0x16,0x8c,0x84,0x00,0x00,0x00,0x0a,0x1e,0x42, +0x24,0x06,0x00,0x01,0x90,0x82,0x00,0x16,0x30,0x71,0x00,0x02,0x30,0x72,0x00,0x3f, +0x30,0x42,0x00,0xfb,0x24,0x17,0x00,0x18,0x24,0x13,0x01,0x03,0x24,0x15,0x08,0x18, +0xaf,0xa6,0x00,0x1c,0x08,0x00,0x07,0xc2,0xa0,0x82,0x00,0x16,0x8d,0x02,0x00,0x04, +0x00,0x0a,0x1c,0x42,0x30,0x42,0x00,0x10,0x14,0x40,0x00,0x15,0x30,0x72,0x00,0x3f, +0x81,0x22,0x00,0x05,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x11,0x30,0x72,0x00,0x3e, +0x27,0x83,0x90,0x18,0x00,0xc3,0x18,0x21,0x80,0x64,0x00,0x00,0x27,0x83,0xb5,0x78, +0x00,0x04,0x11,0x00,0x00,0x44,0x10,0x23,0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x23, +0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x90,0x44,0x00,0x05,0x90,0x43,0x00,0x04, +0x00,0x00,0x00,0x00,0x00,0x64,0x18,0x24,0x30,0x63,0x00,0x01,0x02,0x43,0x90,0x25, +0x27,0x85,0xb4,0x00,0x01,0x85,0x28,0x21,0x8c,0xa6,0x00,0x00,0x01,0x73,0x10,0x21, +0x27,0x83,0x90,0x10,0x90,0xc4,0x00,0x16,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21, +0x30,0x84,0x00,0xdf,0x90,0x50,0x00,0x00,0xa0,0xc4,0x00,0x16,0x80,0xc6,0x00,0x12, +0x8c,0xa3,0x00,0x00,0x2d,0xc4,0x00,0x02,0xaf,0xa6,0x00,0x1c,0x90,0x62,0x00,0x16, +0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xfb,0x14,0x80,0x00,0x06,0xa0,0x62,0x00,0x16, +0x24,0x02,0x00,0x06,0x11,0xc2,0x00,0x03,0x24,0x02,0x00,0x04,0x15,0xc2,0xff,0x0e, +0x32,0x51,0x00,0x02,0x32,0x51,0x00,0x02,0x2e,0x02,0x00,0x0c,0x14,0x40,0x00,0x0f, +0x00,0x11,0x18,0x2b,0x32,0x02,0x00,0x0f,0x34,0x42,0x00,0x10,0x00,0x03,0x19,0x00, +0x00,0x43,0x18,0x21,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xe0,0xa0,0x43,0x00,0x00, +0x00,0x00,0x20,0x21,0x02,0x00,0x28,0x21,0x0c,0x00,0x02,0x03,0xaf,0xaf,0x00,0x28, +0x8f,0xaf,0x00,0x28,0x08,0x00,0x07,0xc2,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0xbd, +0x32,0x03,0x00,0xff,0x3c,0x03,0xb0,0x05,0x34,0x63,0x02,0x42,0x90,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x0f,0x14,0x40,0xfe,0xaa,0x00,0x00,0x00,0x00, +0x91,0xe2,0x00,0x09,0x00,0x00,0x00,0x00,0x02,0x82,0x10,0x26,0x08,0x00,0x07,0x79, +0x00,0x02,0x28,0x0b,0x08,0x00,0x07,0x7f,0x00,0x00,0xb0,0x21,0x24,0x02,0x00,0x10, +0x10,0xc2,0x00,0x08,0x24,0x02,0x00,0x11,0x10,0xc2,0xfe,0x7d,0x00,0x07,0x17,0x83, +0x24,0x02,0x00,0x12,0x14,0xc2,0xfe,0x7b,0x00,0x07,0x17,0x43,0x08,0x00,0x07,0x59, +0x30,0x5e,0x00,0x01,0x08,0x00,0x07,0x59,0x00,0x07,0xf7,0xc2,0x00,0x04,0x10,0x40, +0x27,0x83,0x80,0x1c,0x00,0x43,0x10,0x21,0x00,0x80,0x40,0x21,0x94,0x44,0x00,0x00, +0x2d,0x07,0x00,0x04,0x24,0xc2,0x00,0x03,0x00,0x47,0x30,0x0a,0x00,0x86,0x00,0x18, +0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x23,0x8c, +0xac,0x62,0x00,0x00,0x2d,0x06,0x00,0x10,0x00,0x00,0x20,0x12,0x00,0x04,0x22,0x42, +0x24,0x84,0x00,0x01,0x24,0x83,0x00,0xc0,0x10,0xe0,0x00,0x0b,0x24,0x82,0x00,0x60, +0x00,0x40,0x20,0x21,0x00,0x65,0x20,0x0a,0x3c,0x03,0xb0,0x03,0x34,0x63,0x01,0x00, +0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,0x00,0x44,0x20,0x04, +0x03,0xe0,0x00,0x08,0x00,0x80,0x10,0x21,0x24,0x85,0x00,0x28,0x24,0x83,0x00,0x24, +0x31,0x02,0x00,0x08,0x14,0xc0,0xff,0xf4,0x24,0x84,0x00,0x14,0x00,0x60,0x20,0x21, +0x08,0x00,0x08,0xfa,0x00,0xa2,0x20,0x0b,0x27,0xbd,0xff,0xe0,0x3c,0x03,0xb0,0x03, +0x3c,0x02,0x80,0x00,0xaf,0xb0,0x00,0x10,0x24,0x42,0x24,0x28,0x00,0x80,0x80,0x21, +0x34,0x63,0x00,0x20,0x3c,0x04,0xb0,0x03,0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14, +0xaf,0xbf,0x00,0x1c,0x83,0xb1,0x00,0x33,0x83,0xa8,0x00,0x37,0x34,0x84,0x01,0x10, +0xac,0x62,0x00,0x00,0x2e,0x02,0x00,0x10,0x00,0xe0,0x90,0x21,0x8c,0x87,0x00,0x00, +0x14,0x40,0x00,0x0c,0x2e,0x02,0x00,0x0c,0x3c,0x02,0x00,0x0f,0x34,0x42,0xf0,0x00, +0x00,0xe2,0x10,0x24,0x14,0x40,0x00,0x37,0x32,0x02,0x00,0x08,0x32,0x02,0x00,0x07, +0x27,0x83,0x80,0xcc,0x00,0x43,0x10,0x21,0x90,0x50,0x00,0x00,0x00,0x00,0x00,0x00, +0x2e,0x02,0x00,0x0c,0x14,0x40,0x00,0x03,0x02,0x00,0x20,0x21,0x32,0x02,0x00,0x0f, +0x24,0x44,0x00,0x0c,0x00,0x87,0x10,0x06,0x30,0x42,0x00,0x01,0x14,0x40,0x00,0x07, +0x2c,0x82,0x00,0x0c,0x00,0x04,0x10,0x80,0x27,0x83,0xb4,0x50,0x00,0x43,0x10,0x21, +0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x2c,0x82,0x00,0x0c,0x14,0x40,0x00,0x05, +0x00,0x05,0x10,0x40,0x00,0x46,0x10,0x21,0x00,0x02,0x11,0x00,0x00,0x82,0x10,0x21, +0x24,0x44,0x00,0x04,0x15,0x00,0x00,0x02,0x24,0x06,0x00,0x20,0x24,0x06,0x00,0x0e, +0x0c,0x00,0x08,0xe3,0x00,0x00,0x00,0x00,0x00,0x40,0x30,0x21,0x3c,0x02,0xb0,0x03, +0x34,0x42,0x01,0x00,0x90,0x43,0x00,0x00,0x2e,0x04,0x00,0x04,0x24,0x02,0x00,0x10, +0x24,0x05,0x00,0x0a,0x00,0x44,0x28,0x0a,0x30,0x63,0x00,0x01,0x14,0x60,0x00,0x02, +0x00,0x05,0x10,0x40,0x00,0xa0,0x10,0x21,0x30,0x45,0x00,0xff,0x00,0xc5,0x10,0x21, +0x24,0x46,0x00,0x46,0x02,0x26,0x18,0x04,0xa6,0x43,0x00,0x00,0x8f,0xbf,0x00,0x1c, +0x8f,0xb2,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x00,0xc0,0x10,0x21,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x20,0x10,0x40,0xff,0xcf,0x2e,0x02,0x00,0x0c,0x32,0x02,0x00,0x07, +0x27,0x83,0x80,0xc4,0x00,0x43,0x10,0x21,0x90,0x44,0x00,0x00,0x08,0x00,0x09,0x28, +0x02,0x04,0x80,0x23,0x27,0xbd,0xff,0xb8,0x00,0x05,0x38,0x80,0x27,0x82,0xb4,0x00, +0xaf,0xbe,0x00,0x40,0xaf,0xb6,0x00,0x38,0xaf,0xb3,0x00,0x2c,0xaf,0xbf,0x00,0x44, +0xaf,0xb7,0x00,0x3c,0xaf,0xb5,0x00,0x34,0xaf,0xb4,0x00,0x30,0xaf,0xb2,0x00,0x28, +0xaf,0xb1,0x00,0x24,0xaf,0xb0,0x00,0x20,0x00,0xe2,0x38,0x21,0x8c,0xe6,0x00,0x00, +0xaf,0xa5,0x00,0x4c,0x3c,0x02,0x80,0x00,0x3c,0x05,0xb0,0x03,0x34,0xa5,0x00,0x20, +0x24,0x42,0x25,0x84,0x24,0x03,0x00,0x01,0xac,0xa2,0x00,0x00,0xa0,0xc3,0x00,0x12, +0x8c,0xe5,0x00,0x00,0x94,0xc3,0x00,0x06,0x90,0xa2,0x00,0x16,0xa4,0xc3,0x00,0x14, +0x27,0x83,0x90,0x00,0x34,0x42,0x00,0x08,0xa0,0xa2,0x00,0x16,0x8c,0xe8,0x00,0x00, +0xaf,0xa4,0x00,0x48,0x27,0x82,0x90,0x04,0x95,0x11,0x00,0x14,0x00,0x00,0x00,0x00, +0x00,0x11,0x98,0xc0,0x02,0x71,0x20,0x21,0x00,0x04,0x20,0x80,0x00,0x82,0x10,0x21, +0x8c,0x52,0x00,0x18,0x00,0x83,0x18,0x21,0x84,0x75,0x00,0x06,0x8e,0x45,0x00,0x08, +0x8e,0x46,0x00,0x04,0x8e,0x47,0x00,0x04,0x00,0x05,0x1c,0x82,0x00,0x06,0x31,0x42, +0x27,0x82,0x90,0x10,0x30,0x63,0x00,0x01,0x30,0xc6,0x00,0x01,0x00,0x82,0x20,0x21, +0xa5,0x15,0x00,0x1a,0x00,0x05,0x14,0x42,0xaf,0xa3,0x00,0x18,0xaf,0xa6,0x00,0x1c, +0x30,0xe7,0x00,0x10,0x30,0x56,0x00,0x01,0x80,0x97,0x00,0x06,0x14,0xe0,0x00,0x47, +0x00,0x05,0xf7,0xc2,0x80,0x82,0x00,0x05,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x44, +0x02,0x71,0x10,0x21,0x93,0x90,0xbb,0xe9,0x00,0x00,0x00,0x00,0x2e,0x02,0x00,0x0c, +0x14,0x40,0x00,0x06,0x02,0x00,0x20,0x21,0x00,0x16,0x10,0x40,0x00,0x43,0x10,0x21, +0x00,0x02,0x11,0x00,0x02,0x02,0x10,0x21,0x24,0x44,0x00,0x04,0x02,0x71,0x10,0x21, +0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x10,0x00,0x43,0x10,0x21,0x00,0x80,0x80,0x21, +0xa0,0x44,0x00,0x03,0xa0,0x44,0x00,0x00,0x02,0x00,0x20,0x21,0x02,0xc0,0x28,0x21, +0x0c,0x00,0x08,0xe3,0x02,0xa0,0x30,0x21,0x02,0x71,0x18,0x21,0x00,0x03,0x88,0x80, +0x00,0x40,0xa0,0x21,0x27,0x82,0x90,0x20,0x02,0x22,0x10,0x21,0x8c,0x44,0x00,0x00, +0x26,0xe3,0x00,0x02,0x00,0x03,0x17,0xc2,0x00,0x62,0x18,0x21,0x00,0x04,0x25,0xc2, +0x00,0x03,0x18,0x43,0x30,0x84,0x00,0x01,0x00,0x03,0x18,0x40,0x03,0xc4,0x20,0x24, +0x14,0x80,0x00,0x15,0x02,0x43,0x38,0x21,0x3c,0x08,0xb0,0x03,0x35,0x08,0x00,0x28, +0x8d,0x03,0x00,0x00,0x8f,0xa6,0x00,0x4c,0x8f,0xa4,0x00,0x48,0x27,0x82,0x90,0x08, +0x02,0x22,0x10,0x21,0x24,0x63,0x00,0x01,0x02,0xa0,0x28,0x21,0xa4,0x54,0x00,0x04, +0x00,0xc0,0x38,0x21,0x0c,0x00,0x07,0x2f,0xad,0x03,0x00,0x00,0x7b,0xbe,0x02,0x3c, +0x7b,0xb6,0x01,0xfc,0x7b,0xb4,0x01,0xbc,0x7b,0xb2,0x01,0x7c,0x7b,0xb0,0x01,0x3c, +0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x48,0x8f,0xa2,0x00,0x1c,0x8f,0xa6,0x00,0x18, +0x02,0x00,0x20,0x21,0x02,0xc0,0x28,0x21,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x09,0x0a, +0xaf,0xa0,0x00,0x14,0x08,0x00,0x09,0xc6,0x02,0x82,0xa0,0x21,0x02,0x71,0x10,0x21, +0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x10,0x00,0x43,0x10,0x21,0x90,0x50,0x00,0x00, +0x08,0x00,0x09,0xb2,0xa0,0x50,0x00,0x03,0x27,0xbd,0xff,0xb8,0xaf,0xb1,0x00,0x24, +0x8f,0xb1,0x00,0x5c,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20, +0x24,0x42,0x27,0xa8,0xaf,0xbe,0x00,0x40,0xaf,0xb7,0x00,0x3c,0xaf,0xb6,0x00,0x38, +0xaf,0xb5,0x00,0x34,0xaf,0xb4,0x00,0x30,0xaf,0xa5,0x00,0x4c,0x8f,0xb5,0x00,0x58, +0xaf,0xbf,0x00,0x44,0xaf,0xb3,0x00,0x2c,0xaf,0xb2,0x00,0x28,0xaf,0xb0,0x00,0x20, +0x00,0xe0,0xb0,0x21,0xac,0x62,0x00,0x00,0x00,0x80,0xf0,0x21,0x00,0x00,0xb8,0x21, +0x16,0x20,0x00,0x2b,0x00,0x00,0xa0,0x21,0x27,0x85,0xb4,0x00,0x00,0x07,0x10,0x80, +0x00,0x45,0x10,0x21,0x8c,0x53,0x00,0x00,0x00,0x15,0x18,0x80,0x00,0x65,0x18,0x21, +0x92,0x62,0x00,0x16,0x8c,0x72,0x00,0x00,0x30,0x42,0x00,0x03,0x14,0x40,0x00,0x2d, +0x00,0x00,0x00,0x00,0x92,0x42,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x03, +0x14,0x40,0x00,0x28,0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x34,0x00,0x00,0x00,0x00, +0x14,0x40,0x00,0x18,0x02,0x20,0x10,0x21,0x8c,0x82,0x00,0x38,0x00,0x00,0x00,0x00, +0x14,0x40,0x00,0x14,0x02,0x20,0x10,0x21,0x8c,0x82,0x00,0x3c,0x00,0x00,0x00,0x00, +0x14,0x40,0x00,0x0f,0x3c,0x03,0xb0,0x09,0x3c,0x05,0xb0,0x05,0x34,0x63,0x01,0x44, +0x34,0xa5,0x02,0x52,0x94,0x66,0x00,0x00,0x90,0xa2,0x00,0x00,0x8f,0xa3,0x00,0x4c, +0x00,0x00,0x00,0x00,0x00,0x62,0x10,0x06,0x30,0x42,0x00,0x01,0x10,0x40,0x00,0x04, +0x30,0xc6,0xff,0xff,0x2c,0xc2,0x00,0x41,0x10,0x40,0x00,0x09,0x24,0x05,0x00,0x14, +0x02,0x20,0x10,0x21,0x7b,0xbe,0x02,0x3c,0x7b,0xb6,0x01,0xfc,0x7b,0xb4,0x01,0xbc, +0x7b,0xb2,0x01,0x7c,0x7b,0xb0,0x01,0x3c,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x48, +0x0c,0x00,0x07,0x0a,0x24,0x06,0x01,0x07,0x24,0x02,0x00,0x01,0x08,0x00,0x0a,0x2c, +0xa3,0xc2,0x00,0x11,0x10,0xc0,0x00,0x1c,0x24,0x02,0x00,0x01,0x10,0xc2,0x00,0x17, +0x00,0xc0,0x88,0x21,0x96,0x54,0x00,0x1a,0x02,0xa0,0xb8,0x21,0x12,0x20,0xff,0xed, +0x02,0x20,0x10,0x21,0x27,0x83,0xb4,0x00,0x00,0x17,0x10,0x80,0x00,0x43,0x10,0x21, +0x8c,0x44,0x00,0x00,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x28,0x80,0x86,0x00,0x12, +0x8c,0x62,0x00,0x00,0x00,0x14,0x2c,0x00,0x00,0x05,0x2c,0x03,0x00,0x46,0x10,0x21, +0x8f,0xa6,0x00,0x4c,0x02,0xe0,0x38,0x21,0x03,0xc0,0x20,0x21,0x0c,0x00,0x07,0x2f, +0xac,0x62,0x00,0x00,0x08,0x00,0x0a,0x2c,0xaf,0xd1,0x00,0x40,0x96,0x74,0x00,0x1a, +0x08,0x00,0x0a,0x3f,0x02,0xc0,0xb8,0x21,0x3c,0x02,0xb0,0x03,0x34,0x42,0x01,0x08, +0x8c,0x50,0x00,0x00,0x02,0x60,0x20,0x21,0x0c,0x00,0x1e,0xf3,0x02,0x00,0x28,0x21, +0x30,0x42,0x00,0xff,0x02,0x00,0x28,0x21,0x02,0x40,0x20,0x21,0x0c,0x00,0x1e,0xf3, +0xaf,0xa2,0x00,0x18,0x8f,0xa4,0x00,0x18,0x00,0x00,0x00,0x00,0x10,0x80,0x00,0xed, +0x30,0x50,0x00,0xff,0x12,0x00,0x00,0x18,0x24,0x11,0x00,0x01,0x96,0x63,0x00,0x14, +0x96,0x44,0x00,0x14,0x27,0x85,0x90,0x00,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21, +0x00,0x02,0x10,0x80,0x00,0x45,0x10,0x21,0x00,0x04,0x18,0xc0,0x8c,0x46,0x00,0x08, +0x00,0x64,0x18,0x21,0x00,0x03,0x18,0x80,0x00,0x65,0x18,0x21,0x00,0x06,0x17,0x02, +0x24,0x04,0x00,0xff,0x8c,0x63,0x00,0x08,0x10,0x44,0x00,0xd6,0x00,0x03,0x17,0x02, +0x10,0x44,0x00,0xd5,0x3c,0x02,0x80,0x00,0x00,0x66,0x18,0x2b,0x24,0x11,0x00,0x02, +0x24,0x02,0x00,0x01,0x00,0x43,0x88,0x0a,0x24,0x02,0x00,0x01,0x12,0x22,0x00,0x5a, +0x24,0x02,0x00,0x02,0x16,0x22,0xff,0xbd,0x00,0x00,0x00,0x00,0x96,0x49,0x00,0x14, +0x27,0x82,0x90,0x04,0x02,0xa0,0xb8,0x21,0x00,0x09,0x50,0xc0,0x01,0x49,0x18,0x21, +0x00,0x03,0x40,0x80,0x01,0x02,0x10,0x21,0x8c,0x43,0x00,0x18,0x00,0x00,0x00,0x00, +0x8c,0x65,0x00,0x08,0x8c,0x62,0x00,0x0c,0x8c,0x62,0x00,0x04,0x00,0x05,0x24,0x42, +0x00,0x05,0x1c,0x82,0x30,0x42,0x00,0x10,0x30,0x66,0x00,0x01,0x14,0x40,0x00,0x41, +0x30,0x87,0x00,0x01,0x27,0x82,0x90,0x18,0x01,0x02,0x10,0x21,0x80,0x44,0x00,0x00, +0x27,0x82,0xb5,0x78,0x00,0x04,0x19,0x00,0x00,0x64,0x18,0x23,0x00,0x03,0x18,0x80, +0x00,0x64,0x18,0x23,0x00,0x03,0x18,0x80,0x00,0x62,0x10,0x21,0x90,0x45,0x00,0x05, +0x27,0x84,0xb4,0xa0,0x00,0x64,0x18,0x21,0x90,0x63,0x00,0x00,0x10,0xa0,0x00,0x2b, +0x2c,0x64,0x00,0x0c,0x14,0x80,0x00,0x04,0x00,0x60,0x10,0x21,0x00,0x06,0x11,0x00, +0x00,0x62,0x10,0x21,0x24,0x42,0x00,0x24,0x3c,0x01,0xb0,0x03,0xa0,0x22,0x00,0xe1, +0x14,0x80,0x00,0x06,0x00,0x60,0x28,0x21,0x00,0x07,0x10,0x40,0x00,0x46,0x10,0x21, +0x00,0x02,0x11,0x00,0x00,0x62,0x10,0x21,0x24,0x45,0x00,0x04,0x01,0x49,0x10,0x21, +0x27,0x83,0x90,0x10,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x00,0xa0,0x18,0x21, +0xa0,0x45,0x00,0x03,0xa0,0x45,0x00,0x00,0x24,0x02,0x00,0x08,0x12,0x02,0x00,0x0b, +0x24,0x02,0x00,0x01,0x00,0x60,0x28,0x21,0x02,0x40,0x20,0x21,0x0c,0x00,0x1f,0x6f, +0xaf,0xa2,0x00,0x10,0x30,0x54,0xff,0xff,0x92,0x42,0x00,0x16,0x00,0x00,0x00,0x00, +0x02,0x02,0x10,0x25,0x08,0x00,0x0a,0x3f,0xa2,0x42,0x00,0x16,0x00,0x60,0x28,0x21, +0x02,0x40,0x20,0x21,0x0c,0x00,0x1f,0x20,0xaf,0xa0,0x00,0x10,0x08,0x00,0x0a,0xc2, +0x30,0x54,0xff,0xff,0x08,0x00,0x0a,0xaa,0x00,0x60,0x10,0x21,0x14,0x80,0xff,0xfd, +0x00,0x00,0x00,0x00,0x00,0x06,0x11,0x00,0x00,0x62,0x10,0x21,0x08,0x00,0x0a,0xaa, +0x24,0x42,0x00,0x04,0x27,0x82,0x90,0x10,0x01,0x02,0x10,0x21,0x90,0x43,0x00,0x00, +0x08,0x00,0x0a,0xba,0xa0,0x43,0x00,0x03,0x96,0x69,0x00,0x14,0x02,0xc0,0xb8,0x21, +0x24,0x0b,0x00,0x01,0x00,0x09,0x10,0xc0,0x00,0x49,0x18,0x21,0x00,0x03,0x40,0x80, +0x00,0x40,0x50,0x21,0x27,0x82,0x90,0x04,0x01,0x02,0x10,0x21,0x8c,0x43,0x00,0x18, +0x00,0x00,0x00,0x00,0x8c,0x65,0x00,0x08,0x8c,0x62,0x00,0x0c,0x8c,0x62,0x00,0x04, +0x00,0x05,0x24,0x42,0x00,0x05,0x1c,0x82,0x30,0x42,0x00,0x10,0x30,0x66,0x00,0x01, +0x10,0x40,0x00,0x0d,0x30,0x87,0x00,0x01,0x27,0x82,0x90,0x18,0x01,0x02,0x10,0x21, +0x80,0x43,0x00,0x00,0x00,0x00,0x58,0x21,0x00,0x03,0x11,0x00,0x00,0x43,0x10,0x23, +0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x23,0x00,0x02,0x10,0x80,0x27,0x83,0xb5,0x70, +0x00,0x43,0x10,0x21,0xa0,0x40,0x00,0x04,0x11,0x60,0x00,0x4f,0x00,0x00,0x00,0x00, +0x01,0x49,0x10,0x21,0x00,0x02,0x20,0x80,0x27,0x85,0x90,0x10,0x00,0x85,0x10,0x21, +0x80,0x43,0x00,0x05,0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x42,0x01,0x49,0x10,0x21, +0x27,0x82,0x90,0x18,0x00,0x82,0x10,0x21,0x80,0x44,0x00,0x00,0x27,0x82,0xb5,0x78, +0x00,0x04,0x19,0x00,0x00,0x64,0x18,0x23,0x00,0x03,0x18,0x80,0x00,0x64,0x18,0x23, +0x00,0x03,0x18,0x80,0x00,0x62,0x10,0x21,0x90,0x45,0x00,0x05,0x27,0x84,0xb4,0xa0, +0x00,0x64,0x18,0x21,0x90,0x63,0x00,0x00,0x10,0xa0,0x00,0x2c,0x2c,0x64,0x00,0x0c, +0x14,0x80,0x00,0x04,0x00,0x60,0x10,0x21,0x00,0x06,0x11,0x00,0x00,0x62,0x10,0x21, +0x24,0x42,0x00,0x24,0x3c,0x01,0xb0,0x03,0xa0,0x22,0x00,0xe1,0x14,0x80,0x00,0x06, +0x00,0x60,0x28,0x21,0x00,0x07,0x10,0x40,0x00,0x46,0x10,0x21,0x00,0x02,0x11,0x00, +0x00,0x62,0x10,0x21,0x24,0x45,0x00,0x04,0x01,0x49,0x10,0x21,0x27,0x83,0x90,0x10, +0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x00,0xa0,0x18,0x21,0xa0,0x45,0x00,0x03, +0xa0,0x45,0x00,0x00,0x8f,0xa4,0x00,0x18,0x24,0x02,0x00,0x08,0x10,0x82,0x00,0x0c, +0x00,0x60,0x28,0x21,0x24,0x02,0x00,0x01,0x02,0x60,0x20,0x21,0x0c,0x00,0x1f,0x6f, +0xaf,0xa2,0x00,0x10,0x8f,0xa3,0x00,0x18,0x30,0x54,0xff,0xff,0x92,0x62,0x00,0x16, +0x00,0x00,0x00,0x00,0x00,0x62,0x10,0x25,0x08,0x00,0x0a,0x3f,0xa2,0x62,0x00,0x16, +0x02,0x60,0x20,0x21,0x0c,0x00,0x1f,0x20,0xaf,0xa0,0x00,0x10,0x08,0x00,0x0b,0x31, +0x00,0x00,0x00,0x00,0x08,0x00,0x0b,0x19,0x00,0x60,0x10,0x21,0x14,0x80,0xff,0xfd, +0x00,0x00,0x00,0x00,0x00,0x06,0x11,0x00,0x00,0x62,0x10,0x21,0x08,0x00,0x0b,0x19, +0x24,0x42,0x00,0x04,0x00,0x02,0x10,0x80,0x00,0x45,0x10,0x21,0x90,0x43,0x00,0x00, +0x08,0x00,0x0b,0x29,0xa0,0x43,0x00,0x03,0x27,0x85,0x90,0x10,0x08,0x00,0x0b,0x45, +0x01,0x49,0x10,0x21,0x3c,0x02,0x80,0x00,0x00,0x62,0x18,0x26,0x08,0x00,0x0a,0x7a, +0x00,0xc2,0x30,0x26,0x12,0x00,0xff,0x2d,0x24,0x02,0x00,0x01,0x08,0x00,0x0a,0x7f, +0x24,0x11,0x00,0x02,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xd0, +0x24,0x42,0x2d,0x54,0x34,0x63,0x00,0x20,0x3c,0x05,0xb0,0x05,0xaf,0xb3,0x00,0x24, +0xaf,0xb2,0x00,0x20,0xaf,0xb1,0x00,0x1c,0xaf,0xbf,0x00,0x28,0xaf,0xb0,0x00,0x18, +0xac,0x62,0x00,0x00,0x34,0xa5,0x02,0x42,0x90,0xa2,0x00,0x00,0x00,0x80,0x90,0x21, +0x24,0x11,0x00,0x10,0x30,0x53,0x00,0xff,0x24,0x02,0x00,0x10,0x12,0x22,0x00,0xcf, +0x00,0x00,0x18,0x21,0x24,0x02,0x00,0x11,0x12,0x22,0x00,0xc1,0x24,0x02,0x00,0x12, +0x12,0x22,0x00,0xb4,0x00,0x00,0x00,0x00,0x14,0x60,0x00,0xad,0xae,0x43,0x00,0x40, +0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2c,0x8c,0x44,0x00,0x00,0x3c,0x03,0x00,0x02, +0x34,0x63,0x00,0xff,0x00,0x83,0x80,0x24,0x00,0x10,0x14,0x43,0x10,0x40,0x00,0x05, +0x00,0x00,0x00,0x00,0x8e,0x42,0x00,0x34,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x92, +0x00,0x00,0x00,0x00,0x93,0x83,0x8b,0x71,0x00,0x00,0x00,0x00,0x30,0x62,0x00,0x02, +0x10,0x40,0x00,0x04,0x32,0x10,0x00,0xff,0x00,0x10,0x11,0xc3,0x14,0x40,0x00,0x86, +0x00,0x00,0x00,0x00,0x16,0x00,0x00,0x15,0x02,0x00,0x10,0x21,0x26,0x22,0x00,0x01, +0x30,0x51,0x00,0xff,0x2e,0x23,0x00,0x13,0x14,0x60,0xff,0xdb,0x24,0x03,0x00,0x02, +0x12,0x63,0x00,0x73,0x24,0x02,0x00,0x05,0x2a,0x62,0x00,0x03,0x10,0x40,0x00,0x58, +0x24,0x02,0x00,0x04,0x24,0x02,0x00,0x01,0x12,0x62,0x00,0x4b,0x02,0x40,0x20,0x21, +0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2c,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00, +0x30,0x70,0x00,0xff,0x12,0x00,0x00,0x06,0x02,0x00,0x10,0x21,0x8f,0xbf,0x00,0x28, +0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x30, +0x92,0x46,0x00,0x04,0x8e,0x43,0x00,0x24,0x24,0x02,0x00,0x07,0x02,0x40,0x20,0x21, +0x00,0x00,0x28,0x21,0x24,0x07,0x00,0x06,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x09,0xea, +0xaf,0xa3,0x00,0x14,0xae,0x42,0x00,0x24,0x3c,0x02,0xb0,0x05,0x8c,0x42,0x02,0x2c, +0x00,0x00,0x00,0x00,0x30,0x50,0x00,0xff,0x16,0x00,0xff,0xec,0x02,0x00,0x10,0x21, +0x92,0x46,0x00,0x05,0x8e,0x43,0x00,0x28,0x24,0x02,0x00,0x05,0x02,0x40,0x20,0x21, +0x24,0x05,0x00,0x01,0x24,0x07,0x00,0x04,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x09,0xea, +0xaf,0xa3,0x00,0x14,0xae,0x42,0x00,0x28,0x3c,0x02,0xb0,0x05,0x8c,0x42,0x02,0x2c, +0x00,0x00,0x00,0x00,0x30,0x50,0x00,0xff,0x16,0x00,0xff,0xdc,0x02,0x00,0x10,0x21, +0x92,0x46,0x00,0x06,0x8e,0x43,0x00,0x2c,0x24,0x02,0x00,0x03,0x02,0x40,0x20,0x21, +0x24,0x05,0x00,0x02,0x00,0x00,0x38,0x21,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x09,0xea, +0xaf,0xa3,0x00,0x14,0xae,0x42,0x00,0x2c,0x3c,0x02,0xb0,0x05,0x8c,0x42,0x02,0x2c, +0x00,0x00,0x00,0x00,0x30,0x50,0x00,0xff,0x16,0x00,0xff,0xcc,0x02,0x00,0x10,0x21, +0x92,0x46,0x00,0x07,0x8e,0x43,0x00,0x30,0x24,0x02,0x00,0x02,0x02,0x40,0x20,0x21, +0x24,0x05,0x00,0x03,0x24,0x07,0x00,0x01,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x09,0xea, +0xaf,0xa3,0x00,0x14,0xae,0x42,0x00,0x30,0x3c,0x02,0xb0,0x05,0x8c,0x42,0x02,0x2c, +0x08,0x00,0x0b,0x9b,0x30,0x42,0x00,0xff,0x92,0x46,0x00,0x04,0x8e,0x43,0x00,0x24, +0x24,0x02,0x00,0x07,0x00,0x00,0x28,0x21,0x24,0x07,0x00,0x06,0xaf,0xa2,0x00,0x10, +0x0c,0x00,0x09,0xea,0xaf,0xa3,0x00,0x14,0x08,0x00,0x0b,0x94,0xae,0x42,0x00,0x24, +0x12,0x62,0x00,0x0d,0x24,0x02,0x00,0x03,0x24,0x02,0x00,0x08,0x16,0x62,0xff,0xa8, +0x02,0x40,0x20,0x21,0x92,0x46,0x00,0x07,0x8e,0x42,0x00,0x30,0x24,0x05,0x00,0x03, +0x24,0x07,0x00,0x01,0xaf,0xa3,0x00,0x10,0x0c,0x00,0x09,0xea,0xaf,0xa2,0x00,0x14, +0x08,0x00,0x0b,0x94,0xae,0x42,0x00,0x30,0x92,0x46,0x00,0x06,0x8e,0x43,0x00,0x2c, +0x02,0x40,0x20,0x21,0x24,0x05,0x00,0x02,0x00,0x00,0x38,0x21,0xaf,0xa2,0x00,0x10, +0x0c,0x00,0x09,0xea,0xaf,0xa3,0x00,0x14,0x08,0x00,0x0b,0x94,0xae,0x42,0x00,0x2c, +0x92,0x46,0x00,0x05,0x8e,0x43,0x00,0x28,0x02,0x40,0x20,0x21,0x24,0x05,0x00,0x01, +0x24,0x07,0x00,0x04,0xaf,0xa2,0x00,0x10,0x0c,0x00,0x09,0xea,0xaf,0xa3,0x00,0x14, +0x08,0x00,0x0b,0x94,0xae,0x42,0x00,0x28,0x0c,0x00,0x01,0x57,0x24,0x04,0x00,0x01, +0x08,0x00,0x0b,0x85,0x00,0x00,0x00,0x00,0x8f,0x84,0xb4,0x40,0xae,0x40,0x00,0x34, +0x94,0x85,0x00,0x14,0x0c,0x00,0x1b,0x66,0x00,0x00,0x00,0x00,0x93,0x83,0x8b,0x71, +0x00,0x00,0x00,0x00,0x30,0x62,0x00,0x02,0x10,0x40,0xff,0x69,0x00,0x00,0x00,0x00, +0x0c,0x00,0x01,0x57,0x00,0x00,0x20,0x21,0x08,0x00,0x0b,0x7d,0x00,0x00,0x00,0x00, +0x02,0x40,0x20,0x21,0x0c,0x00,0x09,0x61,0x02,0x20,0x28,0x21,0x08,0x00,0x0b,0x71, +0x3c,0x02,0xb0,0x05,0x8e,0x42,0x00,0x3c,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0x4a, +0x00,0x00,0x00,0x00,0x8f,0x82,0xb4,0x48,0x00,0x00,0x00,0x00,0x90,0x42,0x00,0x0a, +0x00,0x00,0x00,0x00,0x00,0x02,0x18,0x2b,0x08,0x00,0x0b,0x6e,0xae,0x43,0x00,0x3c, +0x8e,0x42,0x00,0x38,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0x3d,0x24,0x02,0x00,0x12, +0x8f,0x82,0xb4,0x44,0x00,0x00,0x00,0x00,0x90,0x42,0x00,0x0a,0x00,0x00,0x00,0x00, +0x00,0x02,0x18,0x2b,0x08,0x00,0x0b,0x6e,0xae,0x43,0x00,0x38,0x8e,0x42,0x00,0x34, +0x00,0x00,0x00,0x00,0x14,0x40,0xff,0x30,0x24,0x02,0x00,0x11,0x8f,0x82,0xb4,0x40, +0x00,0x00,0x00,0x00,0x90,0x42,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,0x02,0x18,0x2b, +0x08,0x00,0x0b,0x6e,0xae,0x43,0x00,0x34,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00, +0x27,0xbd,0xff,0xe0,0x34,0x63,0x00,0x20,0x24,0x42,0x31,0x08,0x3c,0x08,0xb0,0x03, +0xaf,0xb1,0x00,0x14,0xac,0x62,0x00,0x00,0x35,0x08,0x01,0x00,0xaf,0xbf,0x00,0x18, +0xaf,0xb0,0x00,0x10,0x91,0x03,0x00,0x00,0x00,0xa0,0x48,0x21,0x24,0x11,0x00,0x0a, +0x2c,0xa5,0x00,0x04,0x24,0x02,0x00,0x10,0x00,0x45,0x88,0x0a,0x30,0x63,0x00,0x01, +0x00,0xc0,0x28,0x21,0x14,0x60,0x00,0x02,0x00,0x11,0x40,0x40,0x02,0x20,0x40,0x21, +0x84,0x83,0x00,0x0c,0x31,0x11,0x00,0xff,0x01,0x20,0x20,0x21,0x00,0x03,0x10,0xc0, +0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x08,0x00,0x43,0x10,0x21, +0x84,0x43,0x00,0x04,0x24,0x06,0x00,0x0e,0x10,0xe0,0x00,0x06,0x02,0x23,0x80,0x21, +0x02,0x00,0x10,0x21,0x8f,0xbf,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x20,0x0c,0x00,0x08,0xe3,0x00,0x00,0x00,0x00,0x02,0x11,0x18,0x21, +0x08,0x00,0x0c,0x64,0x00,0x62,0x80,0x21,0x27,0xbd,0xff,0xd0,0xaf,0xbf,0x00,0x28, +0xaf,0xb4,0x00,0x20,0xaf,0xb3,0x00,0x1c,0xaf,0xb2,0x00,0x18,0xaf,0xb5,0x00,0x24, +0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0x84,0x82,0x00,0x0c,0x3c,0x06,0xb0,0x03, +0x34,0xc6,0x00,0x20,0x00,0x02,0x18,0xc0,0x00,0x62,0x18,0x21,0x00,0x03,0x18,0x80, +0x27,0x82,0x90,0x04,0x00,0x62,0x10,0x21,0x8c,0x55,0x00,0x18,0x3c,0x02,0x80,0x00, +0x24,0x42,0x31,0xb8,0xac,0xc2,0x00,0x00,0x8e,0xb0,0x00,0x08,0x27,0x82,0x90,0x08, +0x00,0x62,0x18,0x21,0x90,0x71,0x00,0x07,0x00,0x10,0x86,0x43,0x32,0x10,0x00,0x01, +0x00,0xa0,0x38,0x21,0x02,0x00,0x30,0x21,0x00,0xa0,0x98,0x21,0x02,0x20,0x28,0x21, +0x0c,0x00,0x0c,0x42,0x00,0x80,0x90,0x21,0x02,0x20,0x20,0x21,0x02,0x00,0x28,0x21, +0x24,0x06,0x00,0x14,0x0c,0x00,0x08,0xe3,0x00,0x40,0xa0,0x21,0x86,0x43,0x00,0x0c, +0x3c,0x09,0xb0,0x09,0x3c,0x08,0xb0,0x09,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21, +0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x10,0x00,0x43,0x10,0x21,0x80,0x43,0x00,0x06, +0x3c,0x07,0xb0,0x09,0x3c,0x05,0xb0,0x09,0x28,0x62,0x00,0x00,0x24,0x64,0x00,0x03, +0x00,0x82,0x18,0x0b,0x00,0x03,0x18,0x83,0x3c,0x02,0xb0,0x09,0x00,0x03,0x18,0x80, +0x34,0x42,0x01,0x02,0x35,0x29,0x01,0x10,0x35,0x08,0x01,0x14,0x34,0xe7,0x01,0x20, +0x34,0xa5,0x01,0x24,0xa4,0x54,0x00,0x00,0x12,0x60,0x00,0x11,0x02,0xa3,0xa8,0x21, +0x8e,0xa2,0x00,0x0c,0x8e,0xa3,0x00,0x08,0x00,0x02,0x14,0x00,0x00,0x03,0x1c,0x02, +0x00,0x43,0x10,0x21,0xad,0x22,0x00,0x00,0x8e,0xa3,0x00,0x0c,0x00,0x00,0x00,0x00, +0x00,0x03,0x1c,0x02,0xa5,0x03,0x00,0x00,0x8f,0xbf,0x00,0x28,0x7b,0xb4,0x01,0x3c, +0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x30, +0x8e,0xa2,0x00,0x04,0x00,0x00,0x00,0x00,0xad,0x22,0x00,0x00,0x8e,0xa4,0x00,0x08, +0x00,0x00,0x00,0x00,0xa5,0x04,0x00,0x00,0x7a,0xa2,0x00,0x7c,0x00,0x00,0x00,0x00, +0x00,0x03,0x1c,0x00,0x00,0x02,0x14,0x02,0x00,0x62,0x18,0x21,0xac,0xe3,0x00,0x00, +0x8e,0xa2,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x02,0x14,0x02,0x08,0x00,0x0c,0xb6, +0xa4,0xa2,0x00,0x00,0x27,0xbd,0xff,0xe0,0xaf,0xb2,0x00,0x18,0xaf,0xb0,0x00,0x10, +0xaf,0xbf,0x00,0x1c,0xaf,0xb1,0x00,0x14,0x84,0x82,0x00,0x0c,0x00,0x80,0x90,0x21, +0x3c,0x05,0xb0,0x03,0x00,0x02,0x20,0xc0,0x00,0x82,0x20,0x21,0x00,0x04,0x20,0x80, +0x27,0x82,0x90,0x04,0x00,0x82,0x10,0x21,0x8c,0x51,0x00,0x18,0x3c,0x02,0x80,0x00, +0x34,0xa5,0x00,0x20,0x24,0x42,0x33,0x34,0x27,0x83,0x90,0x08,0xac,0xa2,0x00,0x00, +0x00,0x83,0x20,0x21,0x3c,0x02,0xb0,0x03,0x90,0x86,0x00,0x07,0x34,0x42,0x01,0x00, +0x8e,0x23,0x00,0x08,0x90,0x44,0x00,0x00,0x2c,0xc5,0x00,0x04,0x24,0x02,0x00,0x10, +0x24,0x10,0x00,0x0a,0x00,0x45,0x80,0x0a,0x00,0x03,0x1e,0x43,0x30,0x84,0x00,0x01, +0x30,0x65,0x00,0x01,0x14,0x80,0x00,0x02,0x00,0x10,0x10,0x40,0x02,0x00,0x10,0x21, +0x00,0xc0,0x20,0x21,0x24,0x06,0x00,0x20,0x0c,0x00,0x08,0xe3,0x30,0x50,0x00,0xff, +0x86,0x44,0x00,0x0c,0x27,0x85,0x90,0x10,0x3c,0x06,0xb0,0x09,0x00,0x04,0x18,0xc0, +0x00,0x64,0x18,0x21,0x00,0x03,0x18,0x80,0x00,0x65,0x18,0x21,0x80,0x64,0x00,0x06, +0x00,0x50,0x10,0x21,0x34,0xc6,0x01,0x02,0x24,0x85,0x00,0x03,0x28,0x83,0x00,0x00, +0x00,0xa3,0x20,0x0b,0x00,0x04,0x20,0x83,0x00,0x04,0x20,0x80,0xa4,0xc2,0x00,0x00, +0x02,0x24,0x20,0x21,0x8c,0x83,0x00,0x04,0x3c,0x02,0xb0,0x09,0x34,0x42,0x01,0x10, +0xac,0x43,0x00,0x00,0x8c,0x86,0x00,0x08,0x3c,0x02,0xb0,0x09,0x34,0x42,0x01,0x14, +0xa4,0x46,0x00,0x00,0x8c,0x85,0x00,0x0c,0x8c,0x82,0x00,0x08,0x3c,0x06,0xb0,0x09, +0x00,0x05,0x2c,0x00,0x00,0x02,0x14,0x02,0x00,0xa2,0x28,0x21,0x34,0xc6,0x01,0x20, +0xac,0xc5,0x00,0x00,0x8c,0x83,0x00,0x0c,0x3c,0x05,0xb0,0x09,0x34,0xa5,0x01,0x24, +0x00,0x03,0x1c,0x02,0xa4,0xa3,0x00,0x00,0x92,0x42,0x00,0x0a,0x3c,0x03,0xb0,0x09, +0x34,0x63,0x01,0x30,0x00,0x02,0x13,0x00,0x24,0x42,0x00,0x04,0x30,0x42,0xff,0xff, +0xa4,0x62,0x00,0x00,0x86,0x44,0x00,0x0c,0x27,0x83,0x90,0x18,0x8f,0xbf,0x00,0x1c, +0x00,0x04,0x10,0xc0,0x00,0x44,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21, +0x94,0x44,0x00,0x02,0x8f,0xb2,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x3c,0x05,0xb0,0x09, +0x34,0xa5,0x01,0x32,0xa4,0xa4,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20, +0x27,0xbd,0xff,0xe0,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x00,0xaf,0xb0,0x00,0x10, +0x34,0x42,0x00,0x20,0x00,0xa0,0x80,0x21,0x24,0x63,0x34,0xc0,0x00,0x05,0x2c,0x43, +0xaf,0xb1,0x00,0x14,0xaf,0xbf,0x00,0x18,0xac,0x43,0x00,0x00,0x10,0xa0,0x00,0x05, +0x00,0x80,0x88,0x21,0x8c,0x82,0x00,0x34,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0xb6, +0x00,0x00,0x00,0x00,0x32,0x10,0x00,0xff,0x12,0x00,0x00,0x4c,0x00,0x00,0x10,0x21, +0x24,0x02,0x00,0x08,0x12,0x02,0x00,0xa3,0x2a,0x02,0x00,0x09,0x10,0x40,0x00,0x89, +0x24,0x02,0x00,0x40,0x24,0x04,0x00,0x02,0x12,0x04,0x00,0x79,0x2a,0x02,0x00,0x03, +0x10,0x40,0x00,0x69,0x24,0x02,0x00,0x04,0x24,0x02,0x00,0x01,0x12,0x02,0x00,0x5a, +0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x05,0x34,0x42,0x00,0x08,0x3c,0x03,0x80,0x00, +0xa2,0x20,0x00,0x4e,0xac,0x43,0x00,0x00,0x82,0x24,0x00,0x11,0x92,0x27,0x00,0x11, +0x10,0x80,0x00,0x4e,0x00,0x00,0x00,0x00,0x92,0x26,0x00,0x0a,0x24,0x02,0x00,0x12, +0x10,0x46,0x00,0x09,0x30,0xc2,0x00,0xff,0x27,0x83,0xb4,0x00,0x00,0x02,0x10,0x80, +0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x94,0x83,0x00,0x14, +0x00,0x00,0x00,0x00,0xa6,0x23,0x00,0x0c,0x3c,0x02,0xb0,0x09,0x34,0x42,0x00,0x40, +0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x03,0xa2,0x23,0x00,0x10, +0x14,0x60,0x00,0x2b,0x30,0x65,0x00,0x01,0x30,0xc2,0x00,0xff,0x27,0x83,0xb4,0x00, +0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x82,0x23,0x00,0x12, +0x90,0x82,0x00,0x16,0x00,0x00,0x00,0x00,0x00,0x02,0x11,0x42,0x30,0x42,0x00,0x01, +0x00,0x62,0x18,0x21,0x00,0x03,0x26,0x00,0x14,0x80,0x00,0x18,0xa2,0x23,0x00,0x12, +0x00,0x07,0x16,0x00,0x14,0x40,0x00,0x11,0x24,0x02,0x00,0x01,0x96,0x23,0x00,0x0c, +0x27,0x84,0x90,0x10,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80, +0x00,0x44,0x10,0x21,0x80,0x45,0x00,0x06,0x00,0x03,0x1a,0x00,0x3c,0x02,0xb0,0x00, +0x00,0x65,0x18,0x21,0x00,0x62,0x18,0x21,0x90,0x64,0x00,0x00,0x90,0x62,0x00,0x04, +0xa2,0x20,0x00,0x15,0xa3,0x80,0x8b,0xd4,0x24,0x02,0x00,0x01,0x8f,0xbf,0x00,0x18, +0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x0c,0x00,0x0c,0xcd, +0x02,0x20,0x20,0x21,0x92,0x27,0x00,0x11,0x08,0x00,0x0d,0x7d,0x00,0x07,0x16,0x00, +0x0c,0x00,0x0c,0x6e,0x02,0x20,0x20,0x21,0x86,0x23,0x00,0x0c,0x27,0x84,0x90,0x08, +0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x44,0x20,0x21, +0x90,0x85,0x00,0x07,0x27,0x83,0x90,0x10,0x00,0x43,0x10,0x21,0xa2,0x25,0x00,0x13, +0x90,0x83,0x00,0x07,0x08,0x00,0x0d,0x95,0xa0,0x43,0x00,0x02,0x92,0x26,0x00,0x0a, +0x08,0x00,0x0d,0x5e,0x30,0xc2,0x00,0xff,0x8e,0x22,0x00,0x24,0x00,0x00,0x00,0x00, +0x10,0x50,0x00,0x07,0xa2,0x20,0x00,0x08,0x24,0x02,0x00,0x07,0xa2,0x22,0x00,0x0a, +0x92,0x22,0x00,0x27,0xae,0x20,0x00,0x24,0x08,0x00,0x0d,0x51,0xa2,0x22,0x00,0x04, +0x08,0x00,0x0d,0xaf,0x24,0x02,0x00,0x06,0x16,0x02,0xff,0x9b,0x3c,0x02,0xb0,0x05, +0x8e,0x23,0x00,0x2c,0x24,0x02,0x00,0x01,0x10,0x62,0x00,0x07,0xa2,0x24,0x00,0x08, +0x24,0x02,0x00,0x03,0xa2,0x22,0x00,0x0a,0x92,0x22,0x00,0x2f,0xae,0x20,0x00,0x2c, +0x08,0x00,0x0d,0x51,0xa2,0x22,0x00,0x06,0x08,0x00,0x0d,0xbe,0xa2,0x20,0x00,0x0a, +0x8e,0x22,0x00,0x28,0x24,0x03,0x00,0x01,0x24,0x04,0x00,0x01,0x10,0x44,0x00,0x07, +0xa2,0x23,0x00,0x08,0x24,0x02,0x00,0x05,0xa2,0x22,0x00,0x0a,0x92,0x22,0x00,0x2b, +0xae,0x20,0x00,0x28,0x08,0x00,0x0d,0x51,0xa2,0x22,0x00,0x05,0x08,0x00,0x0d,0xca, +0x24,0x02,0x00,0x04,0x12,0x02,0x00,0x12,0x2a,0x02,0x00,0x41,0x10,0x40,0x00,0x09, +0x24,0x02,0x00,0x80,0x24,0x02,0x00,0x20,0x16,0x02,0xff,0x7b,0x3c,0x02,0xb0,0x05, +0x24,0x02,0x00,0x12,0xa2,0x22,0x00,0x0a,0xa2,0x22,0x00,0x08,0x08,0x00,0x0d,0x51, +0xae,0x20,0x00,0x3c,0x16,0x02,0xff,0x74,0x3c,0x02,0xb0,0x05,0x24,0x02,0x00,0x10, +0xa2,0x22,0x00,0x0a,0xa2,0x22,0x00,0x08,0x08,0x00,0x0d,0x51,0xae,0x20,0x00,0x34, +0x24,0x02,0x00,0x11,0xa2,0x22,0x00,0x0a,0xa2,0x22,0x00,0x08,0x08,0x00,0x0d,0x51, +0xae,0x20,0x00,0x38,0x8e,0x24,0x00,0x30,0x24,0x02,0x00,0x03,0x24,0x03,0x00,0x01, +0x10,0x83,0x00,0x07,0xa2,0x22,0x00,0x08,0x24,0x02,0x00,0x02,0xa2,0x22,0x00,0x0a, +0x92,0x22,0x00,0x33,0xae,0x20,0x00,0x30,0x08,0x00,0x0d,0x51,0xa2,0x22,0x00,0x07, +0x08,0x00,0x0d,0xf0,0xa2,0x24,0x00,0x0a,0x8f,0x84,0xb4,0x40,0xae,0x20,0x00,0x34, +0x94,0x85,0x00,0x14,0x0c,0x00,0x1b,0x66,0x32,0x10,0x00,0xff,0x08,0x00,0x0d,0x42, +0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x24,0x42,0x37,0xf4, +0x34,0x63,0x00,0x20,0xac,0x62,0x00,0x00,0x80,0xa2,0x00,0x15,0x3c,0x06,0xb0,0x05, +0x10,0x40,0x00,0x0a,0x34,0xc6,0x02,0x54,0x83,0x83,0x8b,0xd4,0x00,0x00,0x00,0x00, +0xac,0x83,0x00,0x24,0x8c,0xc2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x17,0x42, +0x30,0x42,0x00,0x01,0x03,0xe0,0x00,0x08,0xac,0x82,0x00,0x28,0x8c,0x82,0x00,0x2c, +0x3c,0x06,0xb0,0x05,0x34,0xc6,0x04,0x50,0x00,0x02,0x18,0x43,0x30,0x63,0x00,0x01, +0x10,0x40,0x00,0x04,0x30,0x45,0x00,0x01,0xac,0x83,0x00,0x28,0x03,0xe0,0x00,0x08, +0xac,0x85,0x00,0x24,0x90,0xc2,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff, +0x30,0x43,0x00,0x02,0x30,0x42,0x00,0x01,0xac,0x83,0x00,0x28,0x03,0xe0,0x00,0x08, +0xac,0x82,0x00,0x24,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xd8, +0x34,0x63,0x00,0x20,0x24,0x42,0x38,0x84,0xac,0x62,0x00,0x00,0xaf,0xb1,0x00,0x1c, +0xaf,0xbf,0x00,0x20,0xaf,0xb0,0x00,0x18,0x90,0xa6,0x00,0x0a,0x27,0x83,0xb4,0x00, +0x00,0xa0,0x88,0x21,0x00,0x06,0x10,0x80,0x00,0x43,0x10,0x21,0x8c,0x50,0x00,0x00, +0x80,0xa5,0x00,0x11,0x92,0x03,0x00,0x12,0x10,0xa0,0x00,0x04,0xa2,0x20,0x00,0x15, +0x24,0x02,0x00,0x12,0x10,0xc2,0x00,0xda,0x00,0x00,0x00,0x00,0x82,0x22,0x00,0x12, +0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x67,0x00,0x00,0x00,0x00,0xa2,0x20,0x00,0x12, +0xa2,0x00,0x00,0x19,0x86,0x23,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x03,0x10,0xc0, +0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x20,0x00,0x43,0x10,0x21, +0xa0,0x40,0x00,0x00,0x92,0x03,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0xdf, +0xa2,0x03,0x00,0x16,0x82,0x02,0x00,0x12,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x20, +0x00,0x00,0x00,0x00,0x92,0x23,0x00,0x08,0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x45, +0x24,0x02,0x00,0x01,0xa2,0x20,0x00,0x04,0x92,0x08,0x00,0x04,0x00,0x00,0x00,0x00, +0x15,0x00,0x00,0x1e,0x24,0x02,0x00,0x01,0x92,0x07,0x00,0x0a,0xa2,0x02,0x00,0x17, +0x92,0x02,0x00,0x16,0x30,0xe3,0x00,0xff,0x30,0x42,0x00,0xe4,0x10,0x60,0x00,0x03, +0xa2,0x02,0x00,0x16,0x34,0x42,0x00,0x01,0xa2,0x02,0x00,0x16,0x11,0x00,0x00,0x05, +0x00,0x00,0x00,0x00,0x92,0x02,0x00,0x16,0x00,0x00,0x00,0x00,0x34,0x42,0x00,0x02, +0xa2,0x02,0x00,0x16,0x92,0x02,0x00,0x17,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x08, +0x00,0x00,0x00,0x00,0x96,0x02,0x00,0x06,0x00,0x00,0x00,0x00,0xa6,0x02,0x00,0x14, +0x8f,0xbf,0x00,0x20,0x7b,0xb0,0x00,0xfc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28, +0x96,0x02,0x00,0x00,0x08,0x00,0x0e,0x6c,0xa6,0x02,0x00,0x14,0x92,0x07,0x00,0x0a, +0x00,0x00,0x00,0x00,0x14,0xe0,0x00,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0x0e,0x58, +0xa2,0x00,0x00,0x17,0x96,0x04,0x00,0x00,0x96,0x05,0x00,0x06,0x27,0x86,0x90,0x00, +0x00,0x04,0x18,0xc0,0x00,0x64,0x18,0x21,0x00,0x05,0x10,0xc0,0x00,0x45,0x10,0x21, +0x00,0x03,0x18,0x80,0x00,0x66,0x18,0x21,0x00,0x02,0x10,0x80,0x00,0x46,0x10,0x21, +0x8c,0x66,0x00,0x08,0x8c,0x45,0x00,0x08,0x3c,0x03,0x80,0x00,0x00,0xc3,0x20,0x24, +0x10,0x80,0x00,0x08,0x00,0xa3,0x10,0x24,0x10,0x40,0x00,0x04,0x00,0x00,0x18,0x21, +0x10,0x80,0x00,0x02,0x24,0x03,0x00,0x01,0x00,0xa6,0x18,0x2b,0x08,0x00,0x0e,0x58, +0xa2,0x03,0x00,0x17,0x10,0x40,0xff,0xfd,0x00,0xa6,0x18,0x2b,0x08,0x00,0x0e,0x8c, +0x00,0x00,0x00,0x00,0x10,0x62,0x00,0x09,0x24,0x02,0x00,0x02,0x10,0x62,0x00,0x05, +0x24,0x02,0x00,0x03,0x14,0x62,0xff,0xb8,0x00,0x00,0x00,0x00,0x08,0x00,0x0e,0x52, +0xa2,0x20,0x00,0x07,0x08,0x00,0x0e,0x52,0xa2,0x20,0x00,0x06,0x08,0x00,0x0e,0x52, +0xa2,0x20,0x00,0x05,0x82,0x22,0x00,0x10,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x69, +0x2c,0x62,0x00,0x02,0x10,0x40,0x00,0x49,0x3c,0x02,0xb0,0x09,0x92,0x25,0x00,0x08, +0x00,0x00,0x00,0x00,0x30,0xa6,0x00,0xff,0x2c,0xc2,0x00,0x04,0x10,0x40,0x00,0x3b, +0x2c,0xc2,0x00,0x10,0x3c,0x04,0xb0,0x05,0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00, +0x24,0x02,0x00,0x01,0x00,0xc2,0x10,0x04,0x00,0x02,0x10,0x27,0x00,0x62,0x18,0x24, +0xa0,0x83,0x00,0x00,0x86,0x23,0x00,0x0c,0x96,0x26,0x00,0x0c,0x00,0x03,0x10,0xc0, +0x00,0x43,0x10,0x21,0x00,0x02,0x28,0x80,0x27,0x83,0x90,0x04,0x00,0xa3,0x18,0x21, +0x8c,0x64,0x00,0x18,0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x04,0x00,0x00,0x00,0x00, +0x30,0x42,0x00,0x10,0x10,0x40,0x00,0x18,0x24,0x07,0x00,0x01,0x93,0x82,0x8b,0x71, +0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,0x14,0x40,0x00,0x0a,0x24,0x05,0x00,0x24, +0x00,0x06,0x2c,0x00,0x00,0x05,0x2c,0x03,0x0c,0x00,0x1b,0x66,0x02,0x00,0x20,0x21, +0x92,0x02,0x00,0x16,0xa2,0x00,0x00,0x12,0x30,0x42,0x00,0xe7,0x08,0x00,0x0e,0x49, +0xa2,0x02,0x00,0x16,0xf0,0xc5,0x00,0x06,0x00,0x00,0x28,0x12,0x27,0x82,0x90,0x00, +0x00,0xa2,0x28,0x21,0x0c,0x00,0x01,0x49,0x3c,0x04,0x00,0x80,0x96,0x26,0x00,0x0c, +0x08,0x00,0x0e,0xc9,0x00,0x06,0x2c,0x00,0x27,0x83,0x90,0x10,0x27,0x82,0x90,0x18, +0x00,0xa2,0x10,0x21,0x00,0xa3,0x18,0x21,0x90,0x44,0x00,0x00,0x90,0x65,0x00,0x05, +0x93,0x82,0x80,0x10,0x00,0x00,0x30,0x21,0x0c,0x00,0x21,0x9a,0xaf,0xa2,0x00,0x10, +0x96,0x26,0x00,0x0c,0x08,0x00,0x0e,0xc3,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0xcd, +0x3c,0x04,0xb0,0x05,0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,0x30,0xa5,0x00,0x0f, +0x24,0x02,0x00,0x80,0x08,0x00,0x0e,0xb2,0x00,0xa2,0x10,0x07,0x86,0x26,0x00,0x0c, +0x3c,0x03,0xb0,0x09,0x34,0x42,0x01,0x72,0x34,0x63,0x01,0x78,0x94,0x47,0x00,0x00, +0x8c,0x65,0x00,0x00,0x00,0x06,0x10,0xc0,0x00,0x46,0x10,0x21,0x3c,0x04,0xb0,0x09, +0xae,0x25,0x00,0x1c,0x34,0x84,0x01,0x7c,0x27,0x83,0x90,0x04,0x00,0x02,0x10,0x80, +0x8c,0x85,0x00,0x00,0x00,0x43,0x10,0x21,0x8c,0x43,0x00,0x18,0xae,0x25,0x00,0x20, +0xa6,0x27,0x00,0x18,0x8c,0x66,0x00,0x08,0x02,0x20,0x20,0x21,0x0c,0x00,0x0f,0x19, +0x00,0x00,0x28,0x21,0x86,0x25,0x00,0x18,0x8e,0x26,0x00,0x1c,0x8e,0x27,0x00,0x20, +0x02,0x20,0x20,0x21,0x0c,0x00,0x1c,0x68,0xaf,0xa2,0x00,0x10,0x08,0x00,0x0e,0x49, +0xa2,0x02,0x00,0x12,0x92,0x22,0x00,0x08,0x08,0x00,0x0e,0x49,0xa2,0x22,0x00,0x09, +0xa2,0x20,0x00,0x11,0x80,0x82,0x00,0x50,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x03, +0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xd0,0xac,0x40,0x00,0x00,0x08,0x00,0x0e,0x49, +0xa0,0x80,0x00,0x50,0x94,0x8a,0x00,0x0c,0x24,0x03,0x00,0x24,0x00,0x80,0x70,0x21, +0x3c,0x02,0x80,0x00,0x3c,0x04,0xb0,0x03,0x24,0x42,0x3c,0x64,0xf1,0x43,0x00,0x06, +0x34,0x84,0x00,0x20,0x00,0x00,0x18,0x12,0x00,0xa0,0x68,0x21,0xac,0x82,0x00,0x00, +0x27,0x85,0x90,0x10,0x27,0x82,0x90,0x0f,0x27,0xbd,0xff,0xf8,0x00,0x62,0x60,0x21, +0x00,0x65,0x58,0x21,0x00,0x00,0xc0,0x21,0x11,0xa0,0x00,0xcc,0x00,0x00,0x78,0x21, +0x00,0x0a,0x1c,0x00,0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21, +0x00,0x02,0x10,0x80,0x00,0x45,0x10,0x21,0x91,0x87,0x00,0x00,0x80,0x48,0x00,0x04, +0x03,0xa0,0x60,0x21,0x00,0x0a,0x1c,0x00,0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0, +0x00,0x43,0x10,0x21,0x00,0x02,0x48,0x80,0x27,0x83,0x90,0x04,0xa3,0xa7,0x00,0x00, +0x01,0x23,0x18,0x21,0x8c,0x64,0x00,0x18,0x25,0x02,0xff,0xff,0x00,0x48,0x40,0x0b, +0x8c,0x83,0x00,0x04,0x2d,0x05,0x00,0x07,0x24,0x02,0x00,0x06,0x30,0x63,0x00,0x08, +0x14,0x60,0x00,0x35,0x00,0x45,0x40,0x0a,0x93,0xa7,0x00,0x00,0x27,0x82,0x90,0x18, +0x01,0x22,0x10,0x21,0x30,0xe3,0x00,0xf0,0x38,0x63,0x00,0x50,0x30,0xe5,0x00,0xff, +0x00,0x05,0x20,0x2b,0x00,0x03,0x18,0x2b,0x00,0x64,0x18,0x24,0x90,0x49,0x00,0x00, +0x10,0x60,0x00,0x16,0x30,0xe4,0x00,0x0f,0x24,0x02,0x00,0x04,0x10,0xa2,0x00,0x9d, +0x00,0x00,0x00,0x00,0x11,0xa0,0x00,0x3a,0x2c,0xa2,0x00,0x0c,0x10,0x40,0x00,0x02, +0x24,0x84,0x00,0x0c,0x00,0xe0,0x20,0x21,0x30,0x84,0x00,0xff,0x00,0x04,0x10,0x40, +0x27,0x83,0xbb,0x1c,0x00,0x44,0x10,0x21,0x00,0x43,0x10,0x21,0x90,0x47,0x00,0x00, +0x00,0x00,0x00,0x00,0x2c,0xe3,0x00,0x0c,0xa3,0xa7,0x00,0x00,0x10,0x60,0x00,0x02, +0x24,0xe2,0x00,0x04,0x00,0xe0,0x10,0x21,0xa3,0xa2,0x00,0x00,0x91,0x65,0x00,0x00, +0x91,0x82,0x00,0x00,0x30,0xa3,0x00,0xff,0x00,0x62,0x10,0x2b,0x10,0x40,0x00,0x0e, +0x2c,0x62,0x00,0x0c,0x14,0x40,0x00,0x03,0x00,0x60,0x20,0x21,0x30,0xa2,0x00,0x0f, +0x24,0x44,0x00,0x0c,0x00,0x04,0x10,0x40,0x00,0x44,0x20,0x21,0x27,0x83,0xbb,0x1c, +0x00,0x83,0x18,0x21,0x90,0x62,0x00,0x02,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x05, +0x00,0x09,0x11,0x00,0xa1,0x85,0x00,0x00,0x93,0xa2,0x00,0x00,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x08,0x00,0x49,0x10,0x23,0x00,0x02,0x10,0x80,0x00,0x49,0x10,0x23, +0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x21,0x27,0x83,0xb4,0xa8,0x00,0x43,0x10,0x21, +0x90,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x2c,0x83,0x00,0x0c,0x14,0x60,0x00,0x06, +0x00,0x80,0x10,0x21,0x00,0x18,0x10,0x40,0x00,0x4f,0x10,0x21,0x00,0x02,0x11,0x00, +0x00,0x82,0x10,0x21,0x24,0x42,0x00,0x04,0x08,0x00,0x0f,0x7a,0xa1,0x82,0x00,0x00, +0x8f,0x8d,0x81,0x5c,0x00,0x00,0x00,0x00,0x01,0xa8,0x10,0x21,0x90,0x43,0x00,0x00, +0x00,0x00,0x00,0x00,0x10,0x60,0xff,0xd1,0x00,0x00,0x28,0x21,0x00,0x06,0x74,0x82, +0x30,0xe2,0x00,0xff,0x2c,0x42,0x00,0x0c,0x14,0x40,0x00,0x03,0x00,0xe0,0x10,0x21, +0x30,0xe2,0x00,0x0f,0x24,0x42,0x00,0x0c,0x30,0x44,0x00,0xff,0xa3,0xa2,0x00,0x00, +0x24,0x02,0x00,0x0c,0x10,0x82,0x00,0x0d,0x00,0x09,0x11,0x00,0x00,0x49,0x10,0x23, +0x00,0x02,0x10,0x80,0x00,0x04,0x18,0x40,0x00,0x49,0x10,0x23,0x00,0x64,0x18,0x21, +0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x27,0x84,0xb4,0xa8,0x00,0x44,0x10,0x21, +0x90,0x47,0x00,0x00,0x00,0x00,0x00,0x00,0xa3,0xa7,0x00,0x00,0x00,0x0a,0x1c,0x00, +0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80, +0x27,0x83,0x90,0x04,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x18,0x00,0x00,0x00,0x00, +0x8c,0x83,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x10,0x14,0x60,0x00,0x33, +0x00,0x06,0x14,0x42,0x00,0x09,0x11,0x00,0x00,0x49,0x10,0x23,0x00,0x02,0x10,0x80, +0x00,0x49,0x10,0x23,0x27,0x83,0xb5,0x78,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21, +0x90,0x44,0x00,0x04,0x90,0x43,0x00,0x05,0x00,0x00,0x00,0x00,0x00,0x64,0xc0,0x24, +0x93,0xa7,0x00,0x00,0x00,0x00,0x00,0x00,0x2c,0xe2,0x00,0x0f,0x10,0x40,0x00,0x0f, +0x31,0xcf,0x00,0x01,0x00,0x0a,0x1c,0x00,0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0, +0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x84,0x90,0x00,0x00,0x44,0x10,0x21, +0x84,0x43,0x00,0x06,0x00,0x00,0x00,0x00,0x28,0x63,0x06,0x41,0x14,0x60,0x00,0x04, +0x30,0xe2,0x00,0xff,0x24,0x07,0x00,0x0f,0xa3,0xa7,0x00,0x00,0x30,0xe2,0x00,0xff, +0x2c,0x42,0x00,0x0c,0x14,0x40,0x00,0x06,0x00,0xe0,0x10,0x21,0x00,0x18,0x10,0x40, +0x00,0x4f,0x10,0x21,0x00,0x02,0x11,0x00,0x00,0x47,0x10,0x21,0x24,0x42,0x00,0x04, +0xa3,0xa2,0x00,0x00,0x00,0x40,0x38,0x21,0x01,0xa8,0x10,0x21,0x90,0x43,0x00,0x00, +0x24,0xa4,0x00,0x01,0x30,0x85,0xff,0xff,0x00,0xa3,0x18,0x2b,0x14,0x60,0xff,0xad, +0x30,0xe2,0x00,0xff,0x08,0x00,0x0f,0x67,0x00,0x00,0x00,0x00,0x08,0x00,0x0f,0xc8, +0x30,0x58,0x00,0x01,0x81,0xc2,0x00,0x48,0x00,0x00,0x00,0x00,0x10,0x40,0xff,0x73, +0x00,0x00,0x00,0x00,0x08,0x00,0x0f,0x55,0x00,0x00,0x00,0x00,0x00,0x0a,0x1c,0x00, +0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80, +0x00,0x45,0x10,0x21,0x80,0x48,0x00,0x05,0x91,0x67,0x00,0x00,0x08,0x00,0x0f,0x35, +0x03,0xa0,0x58,0x21,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20, +0x24,0x42,0x40,0x04,0x03,0xe0,0x00,0x08,0xac,0x62,0x00,0x00,0x27,0xbd,0xff,0xc0, +0xaf,0xb7,0x00,0x34,0xaf,0xb6,0x00,0x30,0xaf,0xb5,0x00,0x2c,0xaf,0xb4,0x00,0x28, +0xaf,0xb3,0x00,0x24,0xaf,0xb2,0x00,0x20,0xaf,0xbf,0x00,0x3c,0xaf,0xbe,0x00,0x38, +0xaf,0xb1,0x00,0x1c,0xaf,0xb0,0x00,0x18,0x84,0x82,0x00,0x0c,0x27,0x93,0x90,0x04, +0x3c,0x05,0xb0,0x03,0x00,0x02,0x18,0xc0,0x00,0x62,0x18,0x21,0x00,0x03,0x18,0x80, +0x00,0x73,0x10,0x21,0x8c,0x5e,0x00,0x18,0x3c,0x02,0x80,0x00,0x34,0xa5,0x00,0x20, +0x24,0x42,0x40,0x1c,0xac,0xa2,0x00,0x00,0x8f,0xd0,0x00,0x08,0x27,0x95,0x90,0x10, +0x00,0x75,0x18,0x21,0x00,0x00,0x28,0x21,0x02,0x00,0x30,0x21,0x90,0x71,0x00,0x00, +0x0c,0x00,0x0f,0x19,0x00,0x80,0xb0,0x21,0x00,0x40,0x90,0x21,0x00,0x10,0x14,0x42, +0x30,0x54,0x00,0x01,0x02,0x40,0x20,0x21,0x00,0x10,0x14,0x82,0x02,0x80,0x28,0x21, +0x12,0x51,0x00,0x23,0x00,0x10,0xbf,0xc2,0x86,0xc3,0x00,0x0c,0x30,0x50,0x00,0x01, +0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x55,0x10,0x21, +0xa0,0x52,0x00,0x00,0x86,0xc3,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x03,0x10,0xc0, +0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x53,0x30,0x21,0x8c,0xc7,0x00,0x18, +0x27,0x83,0x90,0x00,0x00,0x43,0x10,0x21,0x8c,0xe3,0x00,0x04,0x84,0x46,0x00,0x06, +0x00,0x03,0x19,0x42,0x0c,0x00,0x08,0xe3,0x30,0x73,0x00,0x01,0x00,0x40,0x88,0x21, +0x02,0x40,0x20,0x21,0x02,0x80,0x28,0x21,0x16,0xe0,0x00,0x10,0x02,0x00,0x30,0x21, +0x86,0xc2,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x02,0x18,0xc0,0x00,0x62,0x18,0x21, +0x00,0x03,0x18,0x80,0x27,0x82,0x90,0x08,0x00,0x62,0x18,0x21,0xa4,0x71,0x00,0x04, +0x7b,0xbe,0x01,0xfc,0x7b,0xb6,0x01,0xbc,0x7b,0xb4,0x01,0x7c,0x7b,0xb2,0x01,0x3c, +0x7b,0xb0,0x00,0xfc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x40,0x86,0xc3,0x00,0x0c, +0xaf,0xb3,0x00,0x10,0xaf,0xa0,0x00,0x14,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21, +0x00,0x02,0x10,0x80,0x00,0x55,0x10,0x21,0x80,0x47,0x00,0x06,0x00,0x00,0x00,0x00, +0x24,0xe7,0x00,0x02,0x00,0x07,0x17,0xc2,0x00,0xe2,0x38,0x21,0x00,0x07,0x38,0x43, +0x00,0x07,0x38,0x40,0x0c,0x00,0x09,0x0a,0x03,0xc7,0x38,0x21,0x08,0x00,0x10,0x48, +0x02,0x22,0x88,0x21,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0xd0, +0x34,0x63,0x00,0x20,0x24,0x42,0x41,0xa4,0xaf,0xb2,0x00,0x20,0xac,0x62,0x00,0x00, +0xaf,0xbf,0x00,0x28,0xaf,0xb3,0x00,0x24,0xaf,0xb1,0x00,0x1c,0xaf,0xb0,0x00,0x18, +0x3c,0x02,0xb0,0x03,0x90,0x83,0x00,0x0a,0x34,0x42,0x01,0x04,0x94,0x45,0x00,0x00, +0x00,0x03,0x18,0x80,0x27,0x82,0xb4,0x00,0x00,0x62,0x18,0x21,0x30,0xa6,0xff,0xff, +0x8c,0x71,0x00,0x00,0x80,0x85,0x00,0x12,0x30,0xc9,0x00,0xff,0x00,0x06,0x32,0x02, +0xa4,0x86,0x00,0x44,0xa4,0x89,0x00,0x46,0x82,0x22,0x00,0x12,0x00,0x80,0x90,0x21, +0x10,0xa0,0x00,0x1b,0xa0,0x80,0x00,0x15,0x00,0xc5,0x10,0x2a,0x10,0x40,0x00,0x14, +0x00,0x00,0x00,0x00,0xa2,0x20,0x00,0x19,0x84,0x83,0x00,0x0c,0x00,0x00,0x00,0x00, +0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x20, +0x00,0x43,0x10,0x21,0xa0,0x40,0x00,0x00,0xa0,0x80,0x00,0x12,0x92,0x22,0x00,0x16, +0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xdf,0xa2,0x22,0x00,0x16,0x8f,0xbf,0x00,0x28, +0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x30, +0x0c,0x00,0x10,0x01,0x00,0x00,0x00,0x00,0x08,0x00,0x10,0x97,0x00,0x00,0x00,0x00, +0x28,0x42,0x00,0x02,0x10,0x40,0x01,0x76,0x00,0x00,0x28,0x21,0x94,0x87,0x00,0x0c, +0x00,0x00,0x00,0x00,0x00,0xe0,0x10,0x21,0x00,0x02,0x14,0x00,0x00,0x02,0x14,0x03, +0x00,0x07,0x24,0x00,0x00,0x04,0x24,0x03,0x00,0x02,0x18,0xc0,0x00,0x62,0x18,0x21, +0x00,0x04,0x28,0xc0,0x00,0xa4,0x28,0x21,0x27,0x82,0x90,0x20,0x00,0x03,0x18,0x80, +0x00,0x62,0x18,0x21,0x00,0x05,0x28,0x80,0x27,0x82,0x90,0x08,0x00,0xa2,0x10,0x21, +0x8c,0x68,0x00,0x00,0x80,0x44,0x00,0x06,0x27,0x82,0x90,0x10,0x00,0x08,0x1d,0x02, +0x00,0xa2,0x28,0x21,0x38,0x84,0x00,0x00,0x30,0x63,0x00,0x01,0x01,0x24,0x30,0x0b, +0x80,0xaa,0x00,0x04,0x80,0xa9,0x00,0x05,0x10,0x60,0x00,0x02,0x00,0x08,0x14,0x02, +0x30,0x46,0x00,0x0f,0x15,0x20,0x00,0x28,0x01,0x49,0x10,0x21,0x15,0x40,0x00,0x11, +0x30,0xe3,0xff,0xff,0x92,0x45,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0xa8,0x00,0xff, +0x2d,0x02,0x00,0x04,0x10,0x40,0x01,0x46,0x2d,0x02,0x00,0x10,0x3c,0x04,0xb0,0x05, +0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,0x24,0x02,0x00,0x01,0x01,0x02,0x10,0x04, +0x00,0x62,0x18,0x25,0xa0,0x83,0x00,0x00,0x96,0x47,0x00,0x0c,0x00,0x00,0x00,0x00, +0x30,0xe3,0xff,0xff,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x27,0x84,0x90,0x10, +0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x21,0x80,0x45,0x00,0x06,0x00,0x03,0x1a,0x00, +0x3c,0x04,0xb0,0x00,0x00,0x65,0x18,0x21,0x00,0x64,0x20,0x21,0x94,0x82,0x00,0x00, +0x82,0x43,0x00,0x10,0x00,0x02,0x14,0x00,0x14,0x60,0x00,0x06,0x00,0x02,0x3c,0x03, +0x30,0xe2,0x00,0x04,0x14,0x40,0x00,0x04,0x01,0x49,0x10,0x21,0x34,0xe2,0x08,0x00, +0xa4,0x82,0x00,0x00,0x01,0x49,0x10,0x21,0x00,0x02,0x16,0x00,0x00,0x02,0x16,0x03, +0x00,0x46,0x10,0x2a,0x10,0x40,0x00,0x7c,0x00,0x00,0x00,0x00,0x82,0x42,0x00,0x10, +0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0e,0x00,0x00,0x00,0x00,0x86,0x43,0x00,0x0c, +0x25,0x44,0x00,0x01,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80, +0x27,0x83,0x90,0x10,0x00,0x43,0x10,0x21,0xa0,0x44,0x00,0x04,0x92,0x23,0x00,0x16, +0x02,0x40,0x20,0x21,0x30,0x63,0x00,0xfb,0x08,0x00,0x10,0x9c,0xa2,0x23,0x00,0x16, +0x86,0x43,0x00,0x0c,0x25,0x24,0x00,0x01,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21, +0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x10,0x00,0x43,0x10,0x21,0xa0,0x44,0x00,0x05, +0x86,0x45,0x00,0x0c,0x0c,0x00,0x1e,0xea,0x02,0x20,0x20,0x21,0x10,0x40,0x00,0x5a, +0x00,0x00,0x00,0x00,0x92,0x45,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0xa6,0x00,0xff, +0x2c,0xc2,0x00,0x04,0x10,0x40,0x00,0x4c,0x2c,0xc2,0x00,0x10,0x3c,0x04,0xb0,0x05, +0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,0x24,0x02,0x00,0x01,0x00,0xc2,0x10,0x04, +0x00,0x02,0x10,0x27,0x00,0x62,0x18,0x24,0xa0,0x83,0x00,0x00,0x92,0x45,0x00,0x08, +0x00,0x00,0x00,0x00,0x30,0xa5,0x00,0xff,0x14,0xa0,0x00,0x33,0x24,0x02,0x00,0x01, +0xa2,0x40,0x00,0x04,0x92,0x22,0x00,0x04,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x0c, +0x24,0x02,0x00,0x01,0xa2,0x22,0x00,0x17,0x92,0x22,0x00,0x17,0x00,0x00,0x00,0x00, +0x10,0x40,0x00,0x04,0x00,0x00,0x00,0x00,0x96,0x22,0x00,0x06,0x08,0x00,0x10,0x97, +0xa6,0x22,0x00,0x14,0x96,0x22,0x00,0x00,0x08,0x00,0x10,0x97,0xa6,0x22,0x00,0x14, +0x92,0x22,0x00,0x0a,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x03,0x00,0x00,0x00,0x00, +0x08,0x00,0x11,0x26,0xa2,0x20,0x00,0x17,0x96,0x24,0x00,0x00,0x96,0x25,0x00,0x06, +0x27,0x86,0x90,0x00,0x00,0x04,0x18,0xc0,0x00,0x64,0x18,0x21,0x00,0x05,0x10,0xc0, +0x00,0x45,0x10,0x21,0x00,0x03,0x18,0x80,0x00,0x66,0x18,0x21,0x00,0x02,0x10,0x80, +0x00,0x46,0x10,0x21,0x8c,0x65,0x00,0x08,0x8c,0x44,0x00,0x08,0x3c,0x03,0x80,0x00, +0x00,0xa3,0x30,0x24,0x10,0xc0,0x00,0x08,0x00,0x83,0x10,0x24,0x10,0x40,0x00,0x04, +0x00,0x00,0x18,0x21,0x10,0xc0,0x00,0x02,0x24,0x03,0x00,0x01,0x00,0x85,0x18,0x2b, +0x08,0x00,0x11,0x26,0xa2,0x23,0x00,0x17,0x10,0x40,0xff,0xfd,0x00,0x85,0x18,0x2b, +0x08,0x00,0x11,0x49,0x00,0x00,0x00,0x00,0x10,0xa2,0x00,0x09,0x24,0x02,0x00,0x02, +0x10,0xa2,0x00,0x05,0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0xca,0x00,0x00,0x00,0x00, +0x08,0x00,0x11,0x21,0xa2,0x40,0x00,0x07,0x08,0x00,0x11,0x21,0xa2,0x40,0x00,0x06, +0x08,0x00,0x11,0x21,0xa2,0x40,0x00,0x05,0x14,0x40,0xff,0xbe,0x3c,0x04,0xb0,0x05, +0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,0x30,0xa5,0x00,0x0f,0x24,0x02,0x00,0x80, +0x08,0x00,0x11,0x18,0x00,0xa2,0x10,0x07,0x0c,0x00,0x10,0x07,0x02,0x40,0x20,0x21, +0x08,0x00,0x10,0x97,0x00,0x00,0x00,0x00,0x92,0x45,0x00,0x08,0x00,0x00,0x00,0x00, +0x30,0xa6,0x00,0xff,0x2c,0xc2,0x00,0x04,0x10,0x40,0x00,0x99,0x2c,0xc2,0x00,0x10, +0x3c,0x04,0xb0,0x05,0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00,0x24,0x02,0x00,0x01, +0x00,0xc2,0x10,0x04,0x00,0x02,0x10,0x27,0x00,0x62,0x18,0x24,0xa0,0x83,0x00,0x00, +0x92,0x45,0x00,0x08,0x00,0x00,0x00,0x00,0x30,0xa5,0x00,0xff,0x14,0xa0,0x00,0x80, +0x24,0x02,0x00,0x01,0xa2,0x40,0x00,0x04,0x86,0x43,0x00,0x0c,0x27,0x93,0x90,0x04, +0x96,0x47,0x00,0x0c,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x28,0x80, +0x00,0xb3,0x18,0x21,0x8c,0x64,0x00,0x18,0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x04, +0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x10,0x10,0x40,0x00,0x64,0x00,0x00,0x30,0x21, +0x00,0x07,0x1c,0x00,0x00,0x03,0x1c,0x03,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21, +0x00,0x02,0x10,0x80,0x00,0x53,0x10,0x21,0x8c,0x43,0x00,0x18,0x93,0x82,0x8b,0x71, +0x8c,0x64,0x00,0x04,0x30,0x42,0x00,0x01,0x00,0x04,0x21,0x42,0x14,0x40,0x00,0x4d, +0x30,0x90,0x00,0x01,0x00,0x07,0x2c,0x00,0x00,0x05,0x2c,0x03,0x0c,0x00,0x1b,0x66, +0x02,0x20,0x20,0x21,0x96,0x26,0x00,0x06,0x12,0x00,0x00,0x14,0x30,0xc5,0xff,0xff, +0x02,0x60,0x90,0x21,0x00,0x05,0x10,0xc0,0x00,0x45,0x10,0x21,0x00,0x02,0x10,0x80, +0x00,0x52,0x18,0x21,0x92,0x22,0x00,0x0a,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0b, +0x02,0x20,0x20,0x21,0x8c,0x63,0x00,0x18,0x00,0x00,0x00,0x00,0x8c,0x62,0x00,0x04, +0x00,0x00,0x00,0x00,0x00,0x02,0x11,0x42,0x0c,0x00,0x1b,0x66,0x30,0x50,0x00,0x01, +0x96,0x26,0x00,0x06,0x16,0x00,0xff,0xef,0x30,0xc5,0xff,0xff,0x92,0x22,0x00,0x04, +0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x0d,0x24,0x02,0x00,0x01,0xa2,0x22,0x00,0x17, +0x92,0x22,0x00,0x17,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x05,0x00,0x00,0x00,0x00, +0xa6,0x26,0x00,0x14,0x92,0x22,0x00,0x16,0x08,0x00,0x10,0x96,0x30,0x42,0x00,0xc3, +0x96,0x22,0x00,0x00,0x08,0x00,0x11,0xbd,0xa6,0x22,0x00,0x14,0x92,0x22,0x00,0x0a, +0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0x11,0xb8, +0xa2,0x20,0x00,0x17,0x96,0x24,0x00,0x00,0x30,0xc5,0xff,0xff,0x00,0x05,0x18,0xc0, +0x00,0x04,0x10,0xc0,0x00,0x44,0x10,0x21,0x00,0x65,0x18,0x21,0x27,0x84,0x90,0x00, +0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x21,0x00,0x03,0x18,0x80,0x8c,0x45,0x00,0x08, +0x00,0x64,0x18,0x21,0x8c,0x64,0x00,0x08,0x3c,0x02,0x80,0x00,0x00,0xa2,0x38,0x24, +0x10,0xe0,0x00,0x08,0x00,0x82,0x10,0x24,0x10,0x40,0x00,0x04,0x00,0x00,0x18,0x21, +0x10,0xe0,0x00,0x02,0x24,0x03,0x00,0x01,0x00,0x85,0x18,0x2b,0x08,0x00,0x11,0xb8, +0xa2,0x23,0x00,0x17,0x10,0x40,0xff,0xfd,0x00,0x85,0x18,0x2b,0x08,0x00,0x11,0xdc, +0x00,0x00,0x00,0x00,0x24,0x05,0x00,0x24,0xf0,0xe5,0x00,0x06,0x00,0x00,0x28,0x12, +0x27,0x82,0x90,0x00,0x00,0xa2,0x28,0x21,0x0c,0x00,0x01,0x49,0x00,0x00,0x20,0x21, +0x96,0x47,0x00,0x0c,0x08,0x00,0x11,0x9a,0x00,0x07,0x2c,0x00,0x27,0x83,0x90,0x10, +0x27,0x82,0x90,0x18,0x00,0xa2,0x10,0x21,0x00,0xa3,0x18,0x21,0x90,0x44,0x00,0x00, +0x90,0x65,0x00,0x05,0x93,0x82,0x80,0x10,0x24,0x07,0x00,0x01,0x0c,0x00,0x21,0x9a, +0xaf,0xa2,0x00,0x10,0x96,0x47,0x00,0x0c,0x08,0x00,0x11,0x8d,0x00,0x07,0x1c,0x00, +0x10,0xa2,0x00,0x09,0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x05,0x24,0x02,0x00,0x03, +0x14,0xa2,0xff,0x7d,0x00,0x00,0x00,0x00,0x08,0x00,0x11,0x7e,0xa2,0x40,0x00,0x07, +0x08,0x00,0x11,0x7e,0xa2,0x40,0x00,0x06,0x08,0x00,0x11,0x7e,0xa2,0x40,0x00,0x05, +0x14,0x40,0xff,0x71,0x3c,0x04,0xb0,0x05,0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00, +0x30,0xa5,0x00,0x0f,0x24,0x02,0x00,0x80,0x08,0x00,0x11,0x75,0x00,0xa2,0x10,0x07, +0x14,0x40,0xfe,0xc3,0x3c,0x04,0xb0,0x05,0x34,0x84,0x02,0x29,0x90,0x83,0x00,0x00, +0x30,0xa5,0x00,0x0f,0x24,0x02,0x00,0x80,0x08,0x00,0x10,0xd0,0x00,0xa2,0x10,0x07, +0x84,0x83,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21, +0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x04,0x00,0x43,0x10,0x21,0x8c,0x47,0x00,0x18, +0x00,0x00,0x00,0x00,0x8c,0xe6,0x00,0x08,0x0c,0x00,0x0f,0x19,0x00,0x00,0x00,0x00, +0x02,0x40,0x20,0x21,0x00,0x00,0x28,0x21,0x00,0x00,0x30,0x21,0x00,0x00,0x38,0x21, +0x0c,0x00,0x1c,0x68,0xaf,0xa2,0x00,0x10,0x00,0x02,0x1e,0x00,0x14,0x60,0xfe,0x6b, +0xa2,0x22,0x00,0x12,0x92,0x43,0x00,0x08,0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x40, +0x24,0x02,0x00,0x01,0xa2,0x40,0x00,0x04,0x92,0x28,0x00,0x04,0x00,0x00,0x00,0x00, +0x15,0x00,0x00,0x19,0x24,0x02,0x00,0x01,0x92,0x27,0x00,0x0a,0xa2,0x22,0x00,0x17, +0x92,0x22,0x00,0x17,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x10,0x00,0x00,0x00,0x00, +0x96,0x22,0x00,0x06,0x00,0x00,0x00,0x00,0xa6,0x22,0x00,0x14,0x92,0x22,0x00,0x16, +0x30,0xe3,0x00,0xff,0x30,0x42,0x00,0xc0,0x10,0x60,0x00,0x03,0xa2,0x22,0x00,0x16, +0x34,0x42,0x00,0x01,0xa2,0x22,0x00,0x16,0x11,0x00,0xfe,0x50,0x00,0x00,0x00,0x00, +0x92,0x22,0x00,0x16,0x08,0x00,0x10,0x96,0x34,0x42,0x00,0x02,0x96,0x22,0x00,0x00, +0x08,0x00,0x12,0x3f,0xa6,0x22,0x00,0x14,0x92,0x27,0x00,0x0a,0x00,0x00,0x00,0x00, +0x14,0xe0,0x00,0x03,0x00,0x00,0x00,0x00,0x08,0x00,0x12,0x38,0xa2,0x20,0x00,0x17, +0x96,0x24,0x00,0x00,0x96,0x25,0x00,0x06,0x27,0x86,0x90,0x00,0x00,0x04,0x18,0xc0, +0x00,0x64,0x18,0x21,0x00,0x05,0x10,0xc0,0x00,0x45,0x10,0x21,0x00,0x03,0x18,0x80, +0x00,0x66,0x18,0x21,0x00,0x02,0x10,0x80,0x00,0x46,0x10,0x21,0x8c,0x65,0x00,0x08, +0x8c,0x44,0x00,0x08,0x3c,0x03,0x80,0x00,0x00,0xa3,0x30,0x24,0x10,0xc0,0x00,0x08, +0x00,0x83,0x10,0x24,0x10,0x40,0x00,0x04,0x00,0x00,0x18,0x21,0x10,0xc0,0x00,0x02, +0x24,0x03,0x00,0x01,0x00,0x85,0x18,0x2b,0x08,0x00,0x12,0x38,0xa2,0x23,0x00,0x17, +0x10,0x40,0xff,0xfd,0x00,0x85,0x18,0x2b,0x08,0x00,0x12,0x67,0x00,0x00,0x00,0x00, +0x10,0x62,0x00,0x09,0x24,0x02,0x00,0x02,0x10,0x62,0x00,0x05,0x24,0x02,0x00,0x03, +0x14,0x62,0xff,0xbd,0x00,0x00,0x00,0x00,0x08,0x00,0x12,0x32,0xa2,0x40,0x00,0x07, +0x08,0x00,0x12,0x32,0xa2,0x40,0x00,0x06,0x08,0x00,0x12,0x32,0xa2,0x40,0x00,0x05, +0x3c,0x02,0x80,0x00,0x00,0x82,0x30,0x24,0x10,0xc0,0x00,0x08,0x00,0xa2,0x18,0x24, +0x10,0x60,0x00,0x04,0x00,0x00,0x10,0x21,0x10,0xc0,0x00,0x02,0x24,0x02,0x00,0x01, +0x00,0xa4,0x10,0x2b,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x10,0x60,0xff,0xfd, +0x00,0xa4,0x10,0x2b,0x08,0x00,0x12,0x82,0x00,0x00,0x00,0x00,0x30,0x82,0xff,0xff, +0x00,0x02,0x18,0xc0,0x00,0x62,0x18,0x21,0x27,0x84,0x90,0x10,0x00,0x03,0x18,0x80, +0x00,0x64,0x18,0x21,0x80,0x66,0x00,0x06,0x00,0x02,0x12,0x00,0x3c,0x03,0xb0,0x00, +0x00,0x46,0x10,0x21,0x00,0x45,0x10,0x21,0x03,0xe0,0x00,0x08,0x00,0x43,0x10,0x21, +0x27,0xbd,0xff,0xe0,0x30,0x82,0x00,0x7c,0x30,0x84,0xff,0x00,0xaf,0xbf,0x00,0x1c, +0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0x14,0x40,0x00,0x41, +0x00,0x04,0x22,0x03,0x24,0x02,0x00,0x04,0x3c,0x10,0xb0,0x03,0x8e,0x10,0x00,0x00, +0x10,0x82,0x00,0x32,0x24,0x02,0x00,0x08,0x10,0x82,0x00,0x03,0x32,0x02,0x00,0x20, +0x08,0x00,0x12,0xa8,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x17,0x3c,0x02,0xb0,0x06, +0x34,0x42,0x80,0x24,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x67,0x00,0xff, +0x10,0xe0,0x00,0x23,0x00,0x00,0x88,0x21,0x8f,0x85,0x8f,0xe0,0x00,0x40,0x30,0x21, +0x94,0xa2,0x00,0x08,0x8c,0xc3,0x00,0x00,0x26,0x31,0x00,0x01,0x24,0x42,0x00,0x02, +0x30,0x42,0x01,0xff,0x34,0x63,0x01,0x00,0x02,0x27,0x20,0x2a,0xa4,0xa2,0x00,0x08, +0x14,0x80,0xff,0xf7,0xac,0xc3,0x00,0x00,0x84,0xa3,0x00,0x08,0x3c,0x02,0xb0,0x03, +0x34,0x42,0x00,0x30,0xac,0x43,0x00,0x00,0x27,0x92,0xb4,0x00,0x24,0x11,0x00,0x12, +0x8e,0x44,0x00,0x00,0x26,0x31,0xff,0xff,0x90,0x82,0x00,0x10,0x00,0x00,0x00,0x00, +0x10,0x40,0x00,0x03,0x26,0x52,0x00,0x04,0x0c,0x00,0x18,0xd0,0x00,0x00,0x00,0x00, +0x06,0x21,0xff,0xf7,0x24,0x02,0xff,0xdf,0x02,0x02,0x80,0x24,0x3c,0x01,0xb0,0x03, +0x0c,0x00,0x13,0x1c,0xac,0x30,0x00,0x00,0x08,0x00,0x12,0xa8,0x00,0x00,0x00,0x00, +0x8f,0x85,0x8f,0xe0,0x08,0x00,0x12,0xbe,0x00,0x00,0x00,0x00,0x24,0x02,0xff,0x95, +0x3c,0x03,0xb0,0x03,0x02,0x02,0x80,0x24,0x34,0x63,0x00,0x30,0x3c,0x01,0xb0,0x03, +0xac,0x30,0x00,0x00,0x0c,0x00,0x12,0xe5,0xac,0x60,0x00,0x00,0x08,0x00,0x12,0xa8, +0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x50,0x08,0x00,0x12,0xa8, +0xac,0x46,0x00,0x00,0x3c,0x0a,0x80,0x00,0x25,0x4a,0x4b,0x94,0x3c,0x0b,0xb0,0x03, +0xad,0x6a,0x00,0x20,0x3c,0x08,0x80,0x01,0x25,0x08,0x00,0x00,0x3c,0x09,0x80,0x01, +0x25,0x29,0x03,0x50,0x11,0x09,0x00,0x10,0x00,0x00,0x00,0x00,0x3c,0x0a,0x80,0x00, +0x25,0x4a,0x4b,0xbc,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20,0x3c,0x08,0xb0,0x06, +0x35,0x08,0x80,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x8d,0x09,0x00,0x00, +0x00,0x00,0x00,0x00,0x31,0x29,0x00,0x01,0x00,0x00,0x00,0x00,0x24,0x01,0x00,0x01, +0x15,0x21,0xff,0xf2,0x00,0x00,0x00,0x00,0x3c,0x0a,0x80,0x00,0x25,0x4a,0x4b,0xf8, +0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20,0x3c,0x02,0xb0,0x03,0x8c,0x43,0x00,0x00, +0x00,0x00,0x00,0x00,0x34,0x63,0x00,0x40,0x00,0x00,0x00,0x00,0xac,0x43,0x00,0x00, +0x00,0x00,0x00,0x00,0x3c,0x0a,0x80,0x00,0x25,0x4a,0x4c,0x24,0x3c,0x0b,0xb0,0x03, +0xad,0x6a,0x00,0x20,0x3c,0x02,0x80,0x01,0x24,0x42,0x00,0x00,0x3c,0x03,0x80,0x01, +0x24,0x63,0x03,0x50,0x3c,0x04,0xb0,0x00,0x8c,0x85,0x00,0x00,0x00,0x00,0x00,0x00, +0xac,0x45,0x00,0x00,0x24,0x42,0x00,0x04,0x24,0x84,0x00,0x04,0x00,0x43,0x08,0x2a, +0x14,0x20,0xff,0xf9,0x00,0x00,0x00,0x00,0x0c,0x00,0x13,0x1c,0x00,0x00,0x00,0x00, +0x3c,0x0a,0x80,0x00,0x25,0x4a,0x4c,0x70,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20, +0x3c,0x02,0x80,0x01,0x24,0x42,0x03,0x50,0x3c,0x03,0x80,0x01,0x24,0x63,0x3f,0x24, +0xac,0x40,0x00,0x00,0xac,0x40,0x00,0x04,0xac,0x40,0x00,0x08,0xac,0x40,0x00,0x0c, +0x24,0x42,0x00,0x10,0x00,0x43,0x08,0x2a,0x14,0x20,0xff,0xf9,0x00,0x00,0x00,0x00, +0x3c,0x0a,0x80,0x00,0x25,0x4a,0x4c,0xb0,0x3c,0x0b,0xb0,0x03,0xad,0x6a,0x00,0x20, +0x3c,0x1c,0x80,0x01,0x27,0x9c,0x7f,0xf0,0x27,0x9d,0x8b,0xe0,0x00,0x00,0x00,0x00, +0x27,0x9d,0x8f,0xc8,0x3c,0x0a,0x80,0x00,0x25,0x4a,0x4c,0xd4,0x3c,0x0b,0xb0,0x03, +0xad,0x6a,0x00,0x20,0x40,0x80,0x68,0x00,0x40,0x08,0x60,0x00,0x00,0x00,0x00,0x00, +0x35,0x08,0xff,0x01,0x40,0x88,0x60,0x00,0x00,0x00,0x00,0x00,0x0c,0x00,0x15,0x62, +0x00,0x00,0x00,0x00,0x24,0x84,0xf8,0x00,0x30,0x87,0x00,0x03,0x00,0x04,0x30,0x40, +0x00,0xc7,0x20,0x23,0x3c,0x02,0xb0,0x0a,0x27,0xbd,0xff,0xe0,0x24,0x03,0xff,0xff, +0x00,0x82,0x20,0x21,0xaf,0xb1,0x00,0x14,0xac,0x83,0x10,0x00,0xaf,0xbf,0x00,0x18, +0xaf,0xb0,0x00,0x10,0x00,0xa0,0x88,0x21,0x24,0x03,0x00,0x01,0x8c,0x82,0x10,0x00, +0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x00,0xc7,0x10,0x23,0x3c,0x03,0xb0,0x0a, +0x00,0x43,0x10,0x21,0x8c,0x50,0x00,0x00,0x0c,0x00,0x13,0x99,0x02,0x20,0x20,0x21, +0x02,0x11,0x80,0x24,0x00,0x50,0x80,0x06,0x02,0x00,0x10,0x21,0x8f,0xbf,0x00,0x18, +0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x27,0xbd,0xff,0xd8, +0xaf,0xb2,0x00,0x18,0x00,0xa0,0x90,0x21,0x24,0x05,0xff,0xff,0xaf,0xb3,0x00,0x1c, +0xaf,0xbf,0x00,0x20,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0x00,0xc0,0x98,0x21, +0x12,0x45,0x00,0x23,0x24,0x84,0xf8,0x00,0x30,0x83,0x00,0x03,0x00,0x04,0x10,0x40, +0x00,0x40,0x88,0x21,0x00,0x60,0x20,0x21,0x00,0x43,0x10,0x23,0x3c,0x03,0xb0,0x0a, +0x00,0x43,0x10,0x21,0xac,0x45,0x10,0x00,0x00,0x40,0x18,0x21,0x24,0x05,0x00,0x01, +0x8c,0x62,0x10,0x00,0x00,0x00,0x00,0x00,0x14,0x45,0xff,0xfd,0x3c,0x02,0xb0,0x0a, +0x02,0x24,0x88,0x23,0x02,0x22,0x88,0x21,0x8e,0x30,0x00,0x00,0x0c,0x00,0x13,0x99, +0x02,0x40,0x20,0x21,0x00,0x12,0x18,0x27,0x02,0x03,0x80,0x24,0x00,0x53,0x10,0x04, +0x02,0x02,0x80,0x25,0xae,0x30,0x00,0x00,0x24,0x03,0x00,0x01,0x8e,0x22,0x10,0x00, +0x00,0x00,0x00,0x00,0x14,0x43,0xff,0xfd,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x20, +0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28, +0x30,0x82,0x00,0x03,0x00,0x04,0x18,0x40,0x00,0x62,0x18,0x23,0x3c,0x04,0xb0,0x0a, +0x00,0x64,0x18,0x21,0xac,0x66,0x00,0x00,0x24,0x04,0x00,0x01,0x8c,0x62,0x10,0x00, +0x00,0x00,0x00,0x00,0x14,0x44,0xff,0xfd,0x00,0x00,0x00,0x00,0x08,0x00,0x13,0x87, +0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x21,0x00,0x64,0x10,0x06,0x30,0x42,0x00,0x01, +0x14,0x40,0x00,0x05,0x00,0x00,0x00,0x00,0x24,0x63,0x00,0x01,0x2c,0x62,0x00,0x20, +0x14,0x40,0xff,0xf9,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x60,0x10,0x21, +0x27,0xbd,0xff,0xe0,0x3c,0x03,0xb0,0x05,0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14, +0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x1c,0x00,0x80,0x90,0x21,0x00,0xa0,0x80,0x21, +0x00,0xc0,0x88,0x21,0x34,0x63,0x02,0x2e,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00, +0x30,0x42,0x00,0x01,0x14,0x40,0xff,0xfc,0x24,0x04,0x08,0x24,0x3c,0x05,0x00,0xc0, +0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x03,0x24,0x04,0x08,0x34,0x3c,0x05,0x00,0xc0, +0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x03,0x3c,0x02,0xc0,0x00,0x00,0x10,0x1c,0x00, +0x34,0x42,0x04,0x00,0x3c,0x04,0xb0,0x05,0x3c,0x05,0xb0,0x05,0x24,0x63,0x16,0x09, +0x02,0x22,0x10,0x21,0x34,0x84,0x04,0x20,0x34,0xa5,0x04,0x24,0x3c,0x06,0xb0,0x05, +0xac,0x83,0x00,0x00,0x24,0x07,0x00,0x01,0xac,0xa2,0x00,0x00,0x34,0xc6,0x02,0x28, +0x24,0x02,0x00,0x20,0xae,0x47,0x00,0x3c,0x24,0x04,0x08,0x24,0xa0,0xc2,0x00,0x00, +0x3c,0x05,0x00,0xc0,0xa2,0x47,0x00,0x11,0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x01, +0x24,0x04,0x08,0x34,0x3c,0x05,0x00,0xc0,0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x01, +0x8f,0xbf,0x00,0x1c,0x8f,0xb2,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x20,0x24,0x02,0x00,0x06,0xac,0x82,0x00,0x0c,0xa0,0x80,0x00,0x50, +0xac,0x80,0x00,0x00,0xac,0x80,0x00,0x04,0xac,0x80,0x00,0x08,0xac,0x80,0x00,0x14, +0xac,0x80,0x00,0x18,0xac,0x80,0x00,0x1c,0xa4,0x80,0x00,0x20,0xac,0x80,0x00,0x24, +0xac,0x80,0x00,0x28,0xac,0x80,0x00,0x2c,0xa0,0x80,0x00,0x30,0xa0,0x80,0x00,0x31, +0xac,0x80,0x00,0x34,0xac,0x80,0x00,0x38,0xa0,0x80,0x00,0x3c,0xac,0x82,0x00,0x10, +0xa0,0x80,0x00,0x44,0xac,0x80,0x00,0x48,0x03,0xe0,0x00,0x08,0xac,0x80,0x00,0x4c, +0x3c,0x04,0xb0,0x06,0x34,0x84,0x80,0x00,0x8c,0x83,0x00,0x00,0x3c,0x02,0x12,0x00, +0x3c,0x05,0xb0,0x03,0x00,0x62,0x18,0x25,0x34,0xa5,0x00,0x8b,0x24,0x02,0xff,0x80, +0xac,0x83,0x00,0x00,0x03,0xe0,0x00,0x08,0xa0,0xa2,0x00,0x00,0x3c,0x04,0xb0,0x03, +0x34,0x84,0x00,0x0b,0x24,0x02,0x00,0x22,0x3c,0x05,0xb0,0x01,0x3c,0x06,0x45,0x67, +0x3c,0x0a,0xb0,0x09,0xa0,0x82,0x00,0x00,0x34,0xa5,0x00,0x04,0x34,0xc6,0x89,0xaa, +0x35,0x4a,0x00,0x04,0x24,0x02,0x01,0x23,0x3c,0x0b,0xb0,0x09,0x3c,0x07,0x01,0x23, +0x3c,0x0c,0xb0,0x09,0x3c,0x01,0xb0,0x01,0xac,0x20,0x00,0x00,0x27,0xbd,0xff,0xe0, +0xac,0xa0,0x00,0x00,0x35,0x6b,0x00,0x08,0x3c,0x01,0xb0,0x09,0xac,0x26,0x00,0x00, +0x34,0xe7,0x45,0x66,0xa5,0x42,0x00,0x00,0x35,0x8c,0x00,0x0c,0x24,0x02,0xcd,0xef, +0x3c,0x0d,0xb0,0x09,0x3c,0x08,0xcd,0xef,0x3c,0x0e,0xb0,0x09,0xad,0x67,0x00,0x00, +0xaf,0xb7,0x00,0x1c,0xa5,0x82,0x00,0x00,0xaf,0xb6,0x00,0x18,0xaf,0xb5,0x00,0x14, +0xaf,0xb4,0x00,0x10,0xaf,0xb3,0x00,0x0c,0xaf,0xb2,0x00,0x08,0xaf,0xb1,0x00,0x04, +0xaf,0xb0,0x00,0x00,0x35,0xad,0x00,0x10,0x35,0x08,0x01,0x22,0x35,0xce,0x00,0x14, +0x24,0x02,0x89,0xab,0x3c,0x0f,0xb0,0x09,0x3c,0x09,0x89,0xab,0x3c,0x10,0xb0,0x09, +0x3c,0x11,0xb0,0x09,0x3c,0x12,0xb0,0x09,0x3c,0x13,0xb0,0x09,0x3c,0x14,0xb0,0x09, +0x3c,0x15,0xb0,0x09,0x3c,0x16,0xb0,0x09,0x3c,0x17,0xb0,0x09,0xad,0xa8,0x00,0x00, +0x24,0x03,0xff,0xff,0xa5,0xc2,0x00,0x00,0x35,0xef,0x00,0x18,0x35,0x29,0xcd,0xee, +0x36,0x10,0x00,0x1c,0x36,0x31,0x00,0x20,0x36,0x52,0x00,0x24,0x36,0x73,0x00,0x28, +0x36,0x94,0x00,0x2c,0x36,0xb5,0x00,0x30,0x36,0xd6,0x00,0x34,0x36,0xf7,0x00,0x38, +0x24,0x02,0x45,0x67,0xad,0xe9,0x00,0x00,0xa6,0x02,0x00,0x00,0xae,0x23,0x00,0x00, +0x8f,0xb0,0x00,0x00,0xa6,0x43,0x00,0x00,0x8f,0xb1,0x00,0x04,0xae,0x63,0x00,0x00, +0x8f,0xb2,0x00,0x08,0xa6,0x83,0x00,0x00,0x8f,0xb3,0x00,0x0c,0xae,0xa3,0x00,0x00, +0x8f,0xb4,0x00,0x10,0xa6,0xc3,0x00,0x00,0x8f,0xb5,0x00,0x14,0xae,0xe3,0x00,0x00, +0x7b,0xb6,0x00,0xfc,0x3c,0x18,0xb0,0x09,0x37,0x18,0x00,0x3c,0xa7,0x03,0x00,0x00, +0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00, +0x34,0x63,0x00,0x20,0x24,0x42,0x51,0x48,0xac,0x62,0x00,0x00,0x8c,0x83,0x00,0x34, +0x34,0x02,0xff,0xff,0x00,0x43,0x10,0x2a,0x14,0x40,0x01,0x04,0x00,0x80,0x28,0x21, +0x8c,0x86,0x00,0x08,0x24,0x02,0x00,0x03,0x10,0xc2,0x00,0xf7,0x00,0x00,0x00,0x00, +0x8c,0xa2,0x00,0x2c,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x4f,0x24,0x02,0x00,0x06, +0x3c,0x03,0xb0,0x05,0x34,0x63,0x04,0x50,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00, +0x30,0x42,0x00,0xff,0x14,0x40,0x00,0xdd,0xac,0xa2,0x00,0x2c,0x24,0x02,0x00,0x01, +0x10,0xc2,0x00,0xdc,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xc2,0x00,0xca, +0x00,0x00,0x00,0x00,0x8c,0xa7,0x00,0x04,0x24,0x02,0x00,0x02,0x10,0xe2,0x00,0xc0, +0x00,0x00,0x00,0x00,0x8c,0xa2,0x00,0x14,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x09, +0x24,0x02,0x00,0x01,0x3c,0x03,0xb0,0x09,0x34,0x63,0x01,0x60,0x90,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0x10,0x40,0x00,0x05,0xac,0xa2,0x00,0x14, +0x24,0x02,0x00,0x01,0xac,0xa2,0x00,0x00,0x03,0xe0,0x00,0x08,0xac,0xa0,0x00,0x14, +0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xd0,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00, +0x04,0x61,0x00,0x19,0x3c,0x02,0xb0,0x03,0x3c,0x03,0xb0,0x05,0x34,0x63,0x02,0x2e, +0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,0x14,0x40,0x00,0x12, +0x3c,0x02,0xb0,0x03,0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x42,0x90,0x43,0x00,0x00, +0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x0c,0x3c,0x02,0xb0,0x03,0x80,0xa2,0x00,0x50, +0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x08,0x3c,0x02,0xb0,0x03,0x14,0xc0,0x00,0x07, +0x34,0x42,0x00,0x3f,0x24,0x02,0x00,0x0e,0x24,0x03,0x00,0x01,0xac,0xa2,0x00,0x00, +0x03,0xe0,0x00,0x08,0xa0,0xa3,0x00,0x50,0x34,0x42,0x00,0x3f,0x90,0x44,0x00,0x00, +0x24,0x03,0x00,0x01,0x10,0x64,0x00,0x7f,0x3c,0x03,0xb0,0x05,0x80,0xa2,0x00,0x31, +0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0a,0x3c,0x02,0xb0,0x06,0x34,0x42,0x80,0x18, +0x8c,0x43,0x00,0x00,0x3c,0x04,0xf0,0x00,0x3c,0x02,0x80,0x00,0x00,0x64,0x18,0x24, +0x10,0x62,0x00,0x03,0x24,0x02,0x00,0x09,0x03,0xe0,0x00,0x08,0xac,0xa2,0x00,0x00, +0x8c,0xa2,0x00,0x40,0x00,0x00,0x00,0x00,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00, +0x10,0x60,0x00,0x09,0x3c,0x03,0xb0,0x03,0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2c, +0x8c,0x43,0x00,0x00,0x3c,0x04,0x00,0x02,0x00,0x64,0x18,0x24,0x14,0x60,0xff,0xf2, +0x24,0x02,0x00,0x10,0x3c,0x03,0xb0,0x03,0x34,0x63,0x02,0x01,0x90,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x80,0x10,0x40,0x00,0x0e,0x00,0x00,0x00,0x00, +0x8c,0xa3,0x00,0x0c,0x00,0x00,0x00,0x00,0xac,0xa3,0x00,0x10,0x3c,0x02,0xb0,0x03, +0x90,0x42,0x02,0x01,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x0f,0xac,0xa2,0x00,0x0c, +0x90,0xa3,0x00,0x0f,0x24,0x02,0x00,0x0d,0x3c,0x01,0xb0,0x03,0x08,0x00,0x14,0xb2, +0xa0,0x23,0x02,0x01,0x3c,0x02,0xb0,0x09,0x34,0x42,0x01,0x80,0x90,0x44,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x04,0x1e,0x00,0x00,0x03,0x1e,0x03,0x10,0x60,0x00,0x15, +0xa0,0xa4,0x00,0x44,0x24,0x02,0x00,0x01,0x10,0x62,0x00,0x0b,0x24,0x02,0x00,0x02, +0x10,0x62,0x00,0x03,0x24,0x03,0x00,0x0d,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00, +0x8c,0xa2,0x00,0x0c,0xac,0xa3,0x00,0x00,0x24,0x03,0x00,0x04,0xac,0xa2,0x00,0x10, +0x03,0xe0,0x00,0x08,0xac,0xa3,0x00,0x0c,0x24,0x02,0x00,0x0d,0xac,0xa2,0x00,0x00, +0x24,0x03,0x00,0x04,0x24,0x02,0x00,0x06,0xac,0xa3,0x00,0x10,0x03,0xe0,0x00,0x08, +0xac,0xa2,0x00,0x0c,0x8c,0xa3,0x00,0x38,0x24,0x04,0x00,0x01,0x10,0x64,0x00,0x2d, +0x24,0x02,0x00,0x02,0x10,0x60,0x00,0x19,0x00,0x00,0x00,0x00,0x10,0x62,0x00,0x10, +0x24,0x02,0x00,0x04,0x10,0x62,0x00,0x04,0x00,0x00,0x00,0x00,0xac,0xa0,0x00,0x38, +0x03,0xe0,0x00,0x08,0xac,0xa0,0x00,0x00,0x10,0xe4,0x00,0x07,0x24,0x02,0x00,0x03, +0x80,0xa2,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x02,0x18,0x0b,0xac,0xa3,0x00,0x00, +0x03,0xe0,0x00,0x08,0xac,0xa0,0x00,0x38,0x08,0x00,0x15,0x04,0xac,0xa2,0x00,0x00, +0x10,0xe4,0x00,0x02,0x24,0x02,0x00,0x03,0x24,0x02,0x00,0x0c,0xac,0xa2,0x00,0x00, +0x24,0x02,0x00,0x04,0x03,0xe0,0x00,0x08,0xac,0xa2,0x00,0x38,0x10,0xe4,0x00,0x0e, +0x3c,0x03,0xb0,0x06,0x34,0x63,0x80,0x24,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00, +0x30,0x42,0x00,0xff,0x10,0x40,0x00,0x06,0xac,0xa2,0x00,0x18,0x24,0x02,0x00,0x02, +0xac,0xa2,0x00,0x00,0xac,0xa0,0x00,0x18,0x08,0x00,0x15,0x0d,0x24,0x02,0x00,0x01, +0x08,0x00,0x15,0x1a,0xac,0xa0,0x00,0x00,0x24,0x02,0x00,0x03,0x08,0x00,0x15,0x1a, +0xac,0xa2,0x00,0x00,0x24,0x03,0x00,0x0b,0xac,0xa2,0x00,0x38,0x03,0xe0,0x00,0x08, +0xac,0xa3,0x00,0x00,0x34,0x63,0x02,0x2e,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00, +0x30,0x42,0x00,0x01,0x14,0x40,0xff,0x7d,0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x42, +0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x60,0xff,0x78,0x00,0x00,0x00,0x00, +0x10,0xc0,0xff,0x81,0x24,0x02,0x00,0x0e,0x08,0x00,0x14,0xa7,0x00,0x00,0x00,0x00, +0x80,0xa2,0x00,0x30,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0x3e,0x24,0x02,0x00,0x04, +0x08,0x00,0x14,0xb2,0x00,0x00,0x00,0x00,0x84,0xa2,0x00,0x20,0x00,0x00,0x00,0x00, +0x10,0x40,0xff,0x75,0x24,0x02,0x00,0x06,0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2e, +0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x01,0x30,0x63,0x00,0xff, +0x00,0x60,0x10,0x21,0x14,0x40,0xff,0x2b,0xa4,0xa3,0x00,0x20,0x08,0x00,0x14,0xb2, +0x24,0x02,0x00,0x06,0x8c,0xa2,0x00,0x1c,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0x66, +0x24,0x02,0x00,0x05,0x3c,0x03,0xb0,0x05,0x34,0x63,0x02,0x2c,0x8c,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0x10,0x40,0xff,0x1b,0xac,0xa2,0x00,0x1c, +0x08,0x00,0x14,0xb2,0x24,0x02,0x00,0x05,0x3c,0x02,0xb0,0x05,0x8c,0x42,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x02,0x17,0x42,0x30,0x42,0x00,0x01,0x14,0x40,0xff,0x56, +0x24,0x02,0x00,0x06,0x08,0x00,0x14,0x60,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x0a, +0x03,0xe0,0x00,0x08,0xac,0x82,0x00,0x00,0x27,0xbd,0xff,0xd8,0xaf,0xb0,0x00,0x10, +0x27,0x90,0x86,0x58,0xaf,0xbf,0x00,0x20,0xaf,0xb3,0x00,0x1c,0xaf,0xb2,0x00,0x18, +0x0c,0x00,0x29,0xd5,0xaf,0xb1,0x00,0x14,0xaf,0x90,0x8f,0xe0,0x48,0x02,0x00,0x00, +0x0c,0x00,0x13,0xf0,0x00,0x00,0x00,0x00,0x0c,0x00,0x18,0x1f,0x02,0x00,0x20,0x21, +0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x3a,0x94,0x43,0x00,0x00,0x00,0x00,0x00,0x00, +0xa3,0x83,0x8f,0xe4,0x0c,0x00,0x00,0x34,0x00,0x00,0x00,0x00,0x0c,0x00,0x13,0xfb, +0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x98,0x0c,0x00,0x27,0x59,0x00,0x00,0x00,0x00, +0x93,0x84,0x80,0x10,0x0c,0x00,0x21,0x3f,0x00,0x00,0x00,0x00,0x27,0x84,0x89,0x18, +0x0c,0x00,0x06,0xe5,0x00,0x00,0x00,0x00,0x0c,0x00,0x01,0x39,0x00,0x00,0x00,0x00, +0x27,0x84,0x84,0x40,0x0c,0x00,0x13,0xd9,0x00,0x00,0x00,0x00,0x27,0x82,0x89,0x4c, +0xaf,0x82,0x84,0x80,0x0c,0x00,0x00,0x5f,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03, +0x34,0x63,0x01,0x08,0x3c,0x04,0xb0,0x09,0x3c,0x05,0xb0,0x09,0x8c,0x66,0x00,0x00, +0x34,0x84,0x01,0x68,0x34,0xa5,0x01,0x40,0x24,0x02,0xc8,0x80,0x24,0x03,0x00,0x0a, +0xa4,0x82,0x00,0x00,0xa4,0xa3,0x00,0x00,0x3c,0x04,0xb0,0x03,0x8c,0x82,0x00,0x00, +0x8f,0x85,0x84,0x40,0xaf,0x86,0x84,0x38,0x34,0x42,0x00,0x20,0xac,0x82,0x00,0x00, +0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x58,0x8c,0x43,0x00,0x00,0x2c,0xa4,0x00,0x11, +0x34,0x63,0x01,0x00,0xac,0x43,0x00,0x00,0x10,0x80,0xff,0xfa,0x3c,0x02,0xb0,0x03, +0x3c,0x03,0x80,0x01,0x00,0x05,0x10,0x80,0x24,0x63,0x02,0x00,0x00,0x43,0x10,0x21, +0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x08,0x00,0x00,0x00,0x00, +0x27,0x84,0x84,0x98,0x0c,0x00,0x26,0x8e,0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x40, +0x0c,0x00,0x14,0x52,0x00,0x00,0x00,0x00,0x93,0x83,0x81,0xf1,0x24,0x02,0x00,0x01, +0x10,0x62,0x00,0x08,0x00,0x00,0x00,0x00,0x8f,0x85,0x84,0x40,0x8f,0x82,0x84,0x74, +0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x01,0xaf,0x82,0x84,0x74,0x08,0x00,0x15,0x9d, +0x3c,0x02,0xb0,0x03,0x27,0x84,0x84,0x98,0x0c,0x00,0x27,0x0d,0x00,0x00,0x00,0x00, +0x08,0x00,0x15,0xb6,0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x98,0x0c,0x00,0x28,0xdd, +0x00,0x00,0x00,0x00,0xa3,0x82,0x84,0x71,0x8f,0x82,0x84,0x74,0xaf,0x80,0x84,0x40, +0x24,0x42,0x00,0x01,0xaf,0x82,0x84,0x74,0x08,0x00,0x15,0x9c,0x00,0x00,0x28,0x21, +0x27,0x84,0x86,0x58,0x0c,0x00,0x19,0x5b,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff, +0x14,0x40,0x00,0x05,0x3c,0x03,0xb0,0x05,0xaf,0x80,0x84,0x40,0xaf,0x80,0x84,0x44, +0x08,0x00,0x15,0xb6,0x00,0x00,0x00,0x00,0x34,0x63,0x04,0x50,0x90,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0xaf,0x82,0x84,0x6c,0x14,0x40,0x00,0x20, +0x24,0x02,0x00,0x01,0x8f,0x84,0x84,0x48,0x00,0x00,0x00,0x00,0x10,0x82,0x00,0x20, +0x3c,0x03,0xb0,0x09,0x34,0x63,0x01,0x60,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00, +0x30,0x42,0x00,0xff,0xaf,0x82,0x84,0x54,0x14,0x40,0x00,0x15,0x24,0x02,0x00,0x01, +0x24,0x02,0x00,0x02,0x10,0x82,0x00,0x07,0x00,0x00,0x00,0x00,0x24,0x05,0x00,0x03, +0x24,0x02,0x00,0x01,0xaf,0x82,0x84,0x44,0xaf,0x85,0x84,0x40,0x08,0x00,0x15,0xb6, +0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2e,0x90,0x43,0x00,0x00, +0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x01,0x30,0x63,0x00,0xff,0x00,0x60,0x10,0x21, +0xa7,0x83,0x84,0x60,0x14,0x40,0xff,0xf1,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01, +0xaf,0x82,0x84,0x44,0xaf,0x80,0x84,0x40,0x08,0x00,0x15,0xb6,0x00,0x00,0x00,0x00, +0x3c,0x03,0xb0,0x05,0x34,0x63,0x02,0x2c,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00, +0x30,0x42,0x00,0xff,0xaf,0x82,0x84,0x5c,0x14,0x40,0xff,0xf5,0x24,0x02,0x00,0x01, +0x08,0x00,0x15,0xe1,0x3c,0x03,0xb0,0x09,0x27,0x84,0x86,0x58,0x0c,0x00,0x1a,0xd1, +0x00,0x00,0x00,0x00,0x83,0x82,0x84,0x70,0x00,0x00,0x00,0x00,0x14,0x40,0xff,0xec, +0x24,0x02,0x00,0x02,0x3c,0x03,0xb0,0x05,0x34,0x63,0x04,0x50,0x90,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0xaf,0x82,0x84,0x6c,0x14,0x40,0xff,0xe4, +0x24,0x02,0x00,0x02,0x8f,0x84,0x84,0x48,0x24,0x02,0x00,0x01,0x10,0x82,0x00,0x12, +0x24,0x02,0x00,0x02,0x10,0x82,0x00,0x04,0x00,0x00,0x00,0x00,0x24,0x05,0x00,0x04, +0x08,0x00,0x15,0xed,0x24,0x02,0x00,0x02,0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2e, +0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x01,0x30,0x63,0x00,0xff, +0x00,0x60,0x10,0x21,0xa7,0x83,0x84,0x60,0x14,0x40,0xff,0xf4,0x00,0x00,0x00,0x00, +0x08,0x00,0x15,0xfc,0x24,0x02,0x00,0x02,0x3c,0x03,0xb0,0x05,0x34,0x63,0x02,0x2c, +0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xff,0xaf,0x82,0x84,0x5c, +0x14,0x40,0xff,0xf7,0x00,0x00,0x00,0x00,0x08,0x00,0x16,0x1d,0x24,0x02,0x00,0x02, +0x27,0x84,0x89,0x18,0x0c,0x00,0x0b,0x55,0x00,0x00,0x00,0x00,0x8f,0x83,0x84,0x44, +0xaf,0x82,0x84,0x5c,0x38,0x64,0x00,0x02,0x00,0x04,0x18,0x0a,0xaf,0x83,0x84,0x44, +0x14,0x40,0xff,0xad,0x24,0x05,0x00,0x05,0x8f,0x82,0x89,0x58,0xaf,0x80,0x84,0x40, +0x10,0x40,0x00,0x02,0x24,0x04,0x00,0x01,0xaf,0x84,0x84,0x48,0x93,0x82,0x89,0x66, +0x00,0x00,0x00,0x00,0x10,0x40,0xff,0x6c,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x05, +0x34,0x42,0x00,0x08,0x8c,0x43,0x00,0x00,0x3c,0x04,0x20,0x00,0x00,0x64,0x18,0x24, +0x10,0x60,0xff,0x65,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xa0, +0x8c,0x43,0x00,0x00,0x3c,0x04,0x80,0x00,0xaf,0x80,0x89,0x40,0x24,0x63,0x00,0x01, +0xac,0x43,0x00,0x00,0x3c,0x01,0xb0,0x05,0xac,0x24,0x00,0x08,0xaf,0x80,0x89,0x3c, +0xaf,0x80,0x89,0x44,0xaf,0x80,0x89,0x48,0xaf,0x80,0x89,0x54,0xaf,0x80,0x89,0x4c, +0x08,0x00,0x15,0xb6,0x00,0x00,0x00,0x00,0x83,0x82,0x84,0x90,0x00,0x00,0x00,0x00, +0x10,0x40,0x00,0x02,0x24,0x02,0x00,0x20,0xaf,0x82,0x84,0x5c,0x8f,0x85,0x84,0x5c, +0x27,0x84,0x89,0x18,0x0c,0x00,0x0d,0x30,0x00,0x00,0x00,0x00,0x00,0x02,0x1e,0x00, +0xa3,0x82,0x84,0x70,0xaf,0x80,0x84,0x5c,0x10,0x60,0xff,0x8e,0x00,0x00,0x00,0x00, +0x3c,0x02,0xb0,0x05,0x34,0x42,0x02,0x2e,0x90,0x43,0x00,0x00,0x00,0x00,0x00,0x00, +0x30,0x63,0x00,0x01,0x30,0x63,0x00,0xff,0x00,0x60,0x10,0x21,0xa7,0x83,0x84,0x60, +0x10,0x40,0x00,0x04,0x24,0x04,0x00,0x02,0xaf,0x84,0x84,0x48,0x08,0x00,0x15,0xfd, +0x00,0x00,0x00,0x00,0x08,0x00,0x15,0xee,0x24,0x05,0x00,0x06,0x27,0x84,0x84,0x40, +0x27,0x85,0x89,0x18,0x0c,0x00,0x0d,0xfd,0x00,0x00,0x00,0x00,0x8f,0x82,0x84,0x64, +0xaf,0x80,0x84,0x6c,0x14,0x40,0x00,0x19,0x00,0x40,0x18,0x21,0x8f,0x82,0x84,0x68, +0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x15,0x24,0x02,0x00,0x02,0x8f,0x83,0x84,0x48, +0x00,0x00,0x00,0x00,0x10,0x62,0x00,0x0b,0x3c,0x02,0x40,0x00,0x8f,0x83,0x84,0x44, +0x24,0x02,0x00,0x01,0x10,0x62,0x00,0x02,0x24,0x05,0x00,0x03,0x24,0x05,0x00,0x06, +0xaf,0x85,0x84,0x40,0x24,0x04,0x00,0x03,0xaf,0x84,0x84,0x48,0x08,0x00,0x15,0xb6, +0x00,0x00,0x00,0x00,0x34,0x42,0x00,0x14,0x3c,0x01,0xb0,0x05,0xac,0x22,0x00,0x00, +0xaf,0x80,0x84,0x40,0x08,0x00,0x16,0x96,0x24,0x04,0x00,0x03,0x10,0x60,0x00,0x10, +0x00,0x00,0x00,0x00,0x27,0x85,0x89,0x18,0x27,0x84,0x84,0x40,0x0c,0x00,0x0e,0x21, +0x00,0x00,0x00,0x00,0x8f,0x83,0x84,0x44,0x24,0x02,0x00,0x01,0xa3,0x80,0x84,0x70, +0xaf,0x80,0x84,0x48,0x10,0x62,0x00,0x02,0x24,0x05,0x00,0x03,0x24,0x05,0x00,0x04, +0xaf,0x85,0x84,0x40,0xaf,0x80,0x84,0x64,0x08,0x00,0x15,0xb6,0x00,0x00,0x00,0x00, +0x83,0x82,0x84,0x90,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x04,0x00,0x00,0x00,0x00, +0x27,0x84,0x89,0x18,0x0c,0x00,0x10,0x69,0x00,0x00,0x00,0x00,0x8f,0x82,0x84,0x44, +0xa3,0x80,0x84,0x70,0xaf,0x80,0x84,0x40,0xaf,0x80,0x84,0x48,0x14,0x40,0x00,0x03, +0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0xaf,0x82,0x84,0x44,0xaf,0x80,0x84,0x68, +0x08,0x00,0x15,0xb6,0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x40,0x27,0x85,0x89,0x18, +0x0c,0x00,0x0e,0x21,0x00,0x00,0x00,0x00,0x8f,0x82,0x84,0x44,0xa3,0x80,0x84,0x70, +0xaf,0x80,0x84,0x40,0xaf,0x80,0x84,0x48,0x14,0x40,0xfe,0xeb,0x00,0x00,0x00,0x00, +0x24,0x02,0x00,0x02,0xaf,0x82,0x84,0x44,0x08,0x00,0x15,0xb6,0x00,0x00,0x00,0x00, +0x27,0x84,0x89,0x18,0x0c,0x00,0x10,0x69,0x00,0x00,0x00,0x00,0x08,0x00,0x16,0xc6, +0x00,0x00,0x00,0x00,0x27,0x84,0x84,0x98,0x0c,0x00,0x29,0x73,0x00,0x00,0x00,0x00, +0x08,0x00,0x15,0xc5,0x00,0x00,0x00,0x00,0x0c,0x00,0x24,0x05,0x00,0x00,0x00,0x00, +0x0c,0x00,0x26,0xff,0x00,0x00,0x00,0x00,0x0c,0x00,0x18,0x11,0x00,0x00,0x00,0x00, +0x93,0x83,0xbc,0x18,0x00,0x00,0x00,0x00,0x14,0x60,0x00,0x2b,0x3c,0x02,0xb0,0x03, +0x34,0x42,0x01,0x08,0x8c,0x44,0x00,0x00,0x8f,0x83,0xbc,0x10,0x8f,0x82,0xbc,0x14, +0x00,0x83,0x18,0x23,0x00,0x43,0x10,0x2b,0x10,0x40,0x00,0x23,0x3c,0x02,0xb0,0x03, +0x24,0x04,0x05,0xa0,0x34,0x42,0x01,0x18,0x8c,0x42,0x00,0x00,0x0c,0x00,0x06,0xd1, +0x00,0x00,0x00,0x00,0x24,0x04,0x05,0xa4,0x0c,0x00,0x06,0xd1,0x00,0x02,0x84,0x02, +0x30,0x51,0xff,0xff,0x24,0x04,0x05,0xa8,0x00,0x02,0x94,0x02,0x0c,0x00,0x06,0xd1, +0x3a,0x10,0xff,0xff,0x3a,0x31,0xff,0xff,0x30,0x42,0xff,0xff,0x2e,0x10,0x00,0x01, +0x2e,0x31,0x00,0x01,0x3a,0x52,0xff,0xff,0x02,0x11,0x80,0x25,0x2e,0x52,0x00,0x01, +0x38,0x42,0xff,0xff,0x02,0x12,0x80,0x25,0x2c,0x42,0x00,0x01,0x02,0x02,0x80,0x25, +0x16,0x00,0x00,0x02,0x24,0x04,0x00,0x02,0x00,0x00,0x20,0x21,0x0c,0x00,0x05,0x6e, +0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x34,0x42,0x01,0x08,0x8c,0x43,0x00,0x00, +0x00,0x00,0x00,0x00,0xaf,0x83,0xbc,0x10,0x0c,0x00,0x01,0xe9,0x00,0x00,0x00,0x00, +0xaf,0x80,0x84,0x40,0xaf,0x80,0x84,0x74,0x08,0x00,0x15,0x9c,0x00,0x00,0x28,0x21, +0x27,0x90,0xb4,0x00,0x24,0x11,0x00,0x12,0x8e,0x04,0x00,0x00,0x00,0x00,0x00,0x00, +0x90,0x82,0x00,0x10,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x03,0x00,0x00,0x00,0x00, +0x0c,0x00,0x18,0xd0,0x00,0x00,0x00,0x00,0x26,0x31,0xff,0xff,0x06,0x21,0xff,0xf6, +0x26,0x10,0x00,0x04,0xaf,0x80,0x84,0x40,0x08,0x00,0x15,0xb7,0x00,0x00,0x28,0x21, +0x3c,0x02,0xb0,0x03,0x34,0x42,0x01,0x08,0x8c,0x44,0x00,0x00,0x8f,0x82,0x84,0x38, +0x00,0x04,0x19,0xc2,0x00,0x02,0x11,0xc2,0x10,0x62,0xff,0xf6,0x00,0x00,0x00,0x00, +0x3c,0x02,0xb0,0x03,0x34,0x42,0x01,0x02,0x90,0x43,0x00,0x00,0x3c,0x12,0xb0,0x05, +0xaf,0x84,0x84,0x38,0x30,0x63,0x00,0xff,0x00,0x03,0x11,0x40,0x00,0x43,0x10,0x23, +0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x00,0x02,0x99,0x00,0x00,0x00,0x88,0x21, +0x36,0x52,0x02,0x2c,0x27,0x90,0xb4,0x00,0x8e,0x04,0x00,0x00,0x00,0x00,0x00,0x00, +0x90,0x83,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x62,0x00,0x03,0x10,0x40,0x00,0x06, +0x30,0x62,0x00,0x1c,0x14,0x40,0x00,0x04,0x00,0x00,0x00,0x00,0x8f,0x85,0x84,0x38, +0x0c,0x00,0x1e,0x94,0x02,0x60,0x30,0x21,0x8e,0x42,0x00,0x00,0x00,0x00,0x00,0x00, +0x30,0x42,0x00,0xff,0x14,0x40,0xff,0xd7,0x00,0x00,0x00,0x00,0x26,0x31,0x00,0x01, +0x2a,0x22,0x00,0x13,0x14,0x40,0xff,0xec,0x26,0x10,0x00,0x04,0x08,0x00,0x17,0x21, +0x00,0x00,0x00,0x00,0x8f,0x84,0x84,0x4c,0x27,0x85,0x89,0x18,0x0c,0x00,0x17,0xa4, +0x00,0x00,0x00,0x00,0x8f,0x83,0x84,0x4c,0x24,0x02,0x00,0x04,0x14,0x62,0xfe,0xa5, +0x00,0x00,0x00,0x00,0x08,0x00,0x15,0xee,0x24,0x05,0x00,0x05,0x3c,0x02,0xb0,0x03, +0x34,0x42,0x00,0x3f,0x90,0x44,0x00,0x00,0x24,0x03,0x00,0x01,0x10,0x64,0x00,0x08, +0x00,0x00,0x00,0x00,0x27,0x84,0x89,0x18,0x0c,0x00,0x24,0x2c,0x00,0x00,0x00,0x00, +0x24,0x05,0x00,0x05,0xaf,0x85,0x84,0x40,0x08,0x00,0x15,0xb7,0x00,0x00,0x00,0x00, +0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x14,0x8c,0x44,0x00,0x00,0x0c,0x00,0x24,0x49, +0x00,0x00,0x00,0x00,0x08,0x00,0x17,0x65,0x24,0x05,0x00,0x05,0x8f,0x82,0x89,0x4c, +0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0d,0x00,0x00,0x00,0x00,0x8f,0x84,0xb4,0x40, +0xaf,0x80,0x89,0x4c,0x94,0x85,0x00,0x14,0x0c,0x00,0x1b,0x66,0x00,0x00,0x00,0x00, +0x93,0x82,0x8b,0x71,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x02,0x10,0x40,0x00,0x03, +0x00,0x00,0x00,0x00,0x0c,0x00,0x01,0x57,0x00,0x00,0x20,0x21,0x8f,0x84,0xb4,0x40, +0x0c,0x00,0x18,0xd0,0x00,0x00,0x00,0x00,0x08,0x00,0x17,0x21,0x00,0x00,0x00,0x00, +0x3c,0x02,0xff,0x90,0x27,0xbd,0xff,0xe8,0x00,0x80,0x18,0x21,0x34,0x42,0x00,0x01, +0x27,0x84,0x89,0x18,0x10,0x62,0x00,0x05,0xaf,0xbf,0x00,0x10,0x8f,0xbf,0x00,0x10, +0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x0c,0x00,0x06,0xe5, +0x00,0x00,0x00,0x00,0x27,0x84,0x86,0x58,0x0c,0x00,0x18,0x1f,0x00,0x00,0x00,0x00, +0x27,0x84,0x84,0x40,0x0c,0x00,0x13,0xd9,0x00,0x00,0x00,0x00,0x08,0x00,0x17,0x8b, +0x00,0x00,0x00,0x00,0x8f,0x82,0x89,0x58,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x05, +0x00,0x00,0x18,0x21,0x8f,0x82,0x84,0x48,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x02, +0x00,0x00,0x00,0x00,0x24,0x03,0x00,0x01,0x03,0xe0,0x00,0x08,0x00,0x60,0x10,0x21, +0x27,0xbd,0xff,0xe0,0x3c,0x06,0xb0,0x03,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10, +0x34,0xc6,0x00,0x5f,0xaf,0xbf,0x00,0x18,0x90,0xc3,0x00,0x00,0x3c,0x07,0xb0,0x03, +0x34,0xe7,0x00,0x5d,0x34,0x63,0x00,0x01,0x3c,0x09,0xb0,0x03,0x24,0x02,0x00,0x01, +0xa0,0xc3,0x00,0x00,0x00,0x80,0x80,0x21,0xa0,0xe2,0x00,0x00,0x00,0xa0,0x88,0x21, +0x35,0x29,0x00,0x5e,0x00,0xe0,0x40,0x21,0x24,0x04,0x00,0x01,0x91,0x22,0x00,0x00, +0x91,0x03,0x00,0x00,0x30,0x42,0x00,0x01,0x14,0x83,0x00,0x03,0x30,0x42,0x00,0x01, +0x14,0x40,0xff,0xfa,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x04,0x12,0x02,0x00,0x2c, +0x24,0x05,0x0f,0x00,0x24,0x02,0x00,0x06,0x12,0x02,0x00,0x08,0x24,0x05,0x00,0x0f, +0x3c,0x02,0xb0,0x03,0x34,0x42,0x02,0x00,0xa0,0x50,0x00,0x00,0x8f,0xbf,0x00,0x18, +0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x24,0x04,0x0c,0x04, +0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x0f,0x24,0x04,0x0d,0x04,0x24,0x05,0x00,0x0f, +0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x0f,0x24,0x04,0x08,0x80,0x24,0x05,0x1e,0x00, +0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x0f,0x24,0x04,0x08,0x8c,0x24,0x05,0x0f,0x00, +0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x0f,0x24,0x04,0x08,0x24,0x3c,0x05,0x00,0x30, +0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x02,0x24,0x04,0x08,0x2c,0x3c,0x05,0x00,0x30, +0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x02,0x24,0x04,0x08,0x34,0x3c,0x05,0x00,0x30, +0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x02,0x24,0x04,0x08,0x3c,0x3c,0x05,0x00,0x30, +0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x02,0x08,0x00,0x17,0xc5,0x3c,0x02,0xb0,0x03, +0x24,0x04,0x08,0x8c,0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x04,0x24,0x04,0x08,0x80, +0x24,0x05,0x1e,0x00,0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x04,0x24,0x04,0x0c,0x04, +0x24,0x05,0x00,0x0f,0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x04,0x24,0x04,0x0d,0x04, +0x24,0x05,0x00,0x0f,0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x04,0x24,0x04,0x08,0x24, +0x3c,0x05,0x00,0x30,0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x03,0x24,0x04,0x08,0x2c, +0x3c,0x05,0x00,0x30,0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x03,0x24,0x04,0x08,0x34, +0x3c,0x05,0x00,0x30,0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x02,0x3c,0x05,0x00,0x30, +0x24,0x06,0x00,0x03,0x0c,0x00,0x13,0x5f,0x24,0x04,0x08,0x3c,0x02,0x20,0x20,0x21, +0x24,0x05,0x00,0x14,0x0c,0x00,0x13,0xa4,0x24,0x06,0x01,0x07,0x08,0x00,0x17,0xc5, +0x3c,0x02,0xb0,0x03,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x73,0x90,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x02,0x14,0x40,0x00,0x04,0x00,0x00,0x00,0x00, +0xa3,0x80,0x81,0x58,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01, +0xa3,0x82,0x81,0x58,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03, +0x3c,0x02,0x80,0x00,0x00,0x80,0x70,0x21,0x34,0x63,0x00,0x20,0x24,0x42,0x60,0x7c, +0x3c,0x04,0xb0,0x03,0xac,0x62,0x00,0x00,0x34,0x84,0x00,0x30,0xad,0xc0,0x02,0xb8, +0x8c,0x83,0x00,0x00,0x24,0x02,0x00,0xff,0xa5,0xc0,0x00,0x0a,0x00,0x00,0x30,0x21, +0xa7,0x82,0x8f,0xf0,0x27,0x88,0x90,0x00,0xa5,0xc3,0x00,0x08,0x3c,0x07,0xb0,0x08, +0x30,0xc2,0xff,0xff,0x00,0x02,0x20,0xc0,0x24,0xc3,0x00,0x01,0x00,0x82,0x10,0x21, +0x00,0x60,0x30,0x21,0x00,0x02,0x10,0x80,0x30,0x63,0xff,0xff,0x00,0x48,0x10,0x21, +0x00,0x87,0x20,0x21,0x28,0xc5,0x00,0xff,0xac,0x83,0x00,0x00,0x14,0xa0,0xff,0xf4, +0xa4,0x43,0x00,0x00,0x3c,0x02,0xb0,0x08,0x34,0x03,0xff,0xff,0x25,0xc4,0x00,0x0c, +0x24,0x0a,0x00,0x02,0x34,0x42,0x07,0xf8,0x3c,0x06,0xb0,0x03,0xa7,0x83,0xb3,0xdc, +0xac,0x43,0x00,0x00,0xaf,0x84,0xb4,0x00,0x34,0xc6,0x00,0x64,0xa0,0x8a,0x00,0x18, +0x94,0xc5,0x00,0x00,0x8f,0x82,0xb4,0x00,0x25,0xc4,0x00,0x30,0x24,0x08,0x00,0x03, +0x3c,0x03,0xb0,0x03,0xa0,0x45,0x00,0x21,0x34,0x63,0x00,0x66,0xaf,0x84,0xb4,0x04, +0xa0,0x88,0x00,0x18,0x94,0x65,0x00,0x00,0x8f,0x82,0xb4,0x04,0x25,0xc4,0x00,0x54, +0x25,0xc7,0x00,0x78,0xa0,0x45,0x00,0x21,0xaf,0x84,0xb4,0x08,0xa0,0x88,0x00,0x18, +0x94,0x65,0x00,0x00,0x8f,0x82,0xb4,0x08,0x25,0xc8,0x00,0x9c,0x24,0x09,0x00,0x01, +0xa0,0x45,0x00,0x21,0xaf,0x87,0xb4,0x0c,0xa0,0xea,0x00,0x18,0x94,0xc4,0x00,0x00, +0x8f,0x82,0xb4,0x0c,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x62,0xa0,0x44,0x00,0x21, +0xaf,0x88,0xb4,0x10,0xa1,0x09,0x00,0x18,0x94,0x65,0x00,0x00,0x8f,0x82,0xb4,0x10, +0x25,0xc4,0x00,0xc0,0x3c,0x06,0xb0,0x03,0xa0,0x45,0x00,0x21,0xaf,0x84,0xb4,0x14, +0xa0,0x89,0x00,0x18,0x94,0x65,0x00,0x00,0x8f,0x82,0xb4,0x14,0x25,0xc4,0x00,0xe4, +0x34,0xc6,0x00,0x60,0xa0,0x45,0x00,0x21,0xaf,0x84,0xb4,0x18,0xa0,0x80,0x00,0x18, +0x94,0xc5,0x00,0x00,0x8f,0x82,0xb4,0x18,0x25,0xc3,0x01,0x08,0x25,0xc7,0x01,0x2c, +0xa0,0x45,0x00,0x21,0xaf,0x83,0xb4,0x1c,0xa0,0x60,0x00,0x18,0x94,0xc8,0x00,0x00, +0x8f,0x82,0xb4,0x1c,0x25,0xc4,0x01,0x50,0x25,0xc5,0x01,0x74,0xa0,0x48,0x00,0x21, +0x25,0xc6,0x01,0x98,0x25,0xc9,0x01,0xbc,0x25,0xca,0x01,0xe0,0x25,0xcb,0x02,0x04, +0x25,0xcc,0x02,0x28,0x25,0xcd,0x02,0x4c,0x24,0x02,0x00,0x10,0x3c,0x03,0xb0,0x03, +0xaf,0x87,0xb4,0x20,0x34,0x63,0x00,0x38,0xa0,0xe0,0x00,0x18,0xaf,0x84,0xb4,0x24, +0xa0,0x80,0x00,0x18,0xaf,0x85,0xb4,0x28,0xa0,0xa0,0x00,0x18,0xaf,0x86,0xb4,0x2c, +0xa0,0xc0,0x00,0x18,0xaf,0x89,0xb4,0x30,0xa1,0x20,0x00,0x18,0xaf,0x8a,0xb4,0x34, +0xa1,0x40,0x00,0x18,0xaf,0x8b,0xb4,0x38,0xa1,0x60,0x00,0x18,0xaf,0x8c,0xb4,0x3c, +0xa1,0x80,0x00,0x18,0xaf,0x8d,0xb4,0x40,0xa1,0xa2,0x00,0x18,0x94,0x64,0x00,0x00, +0x8f,0x82,0xb4,0x40,0x25,0xc5,0x02,0x70,0x3c,0x03,0xb0,0x03,0xa0,0x44,0x00,0x21, +0x24,0x02,0x00,0x11,0xaf,0x85,0xb4,0x44,0x34,0x63,0x00,0x6e,0xa0,0xa2,0x00,0x18, +0x94,0x64,0x00,0x00,0x8f,0x82,0xb4,0x44,0x25,0xc5,0x02,0x94,0x3c,0x03,0xb0,0x03, +0xa0,0x44,0x00,0x21,0x24,0x02,0x00,0x12,0xaf,0x85,0xb4,0x48,0x34,0x63,0x00,0x6c, +0xa0,0xa2,0x00,0x18,0x94,0x64,0x00,0x00,0x8f,0x82,0xb4,0x48,0x24,0x05,0xff,0xff, +0x24,0x07,0x00,0x01,0xa0,0x44,0x00,0x21,0x24,0x06,0x00,0x12,0x27,0x84,0xb4,0x00, +0x8c,0x82,0x00,0x00,0x24,0xc6,0xff,0xff,0xa0,0x40,0x00,0x04,0x8c,0x83,0x00,0x00, +0xa4,0x45,0x00,0x00,0xa4,0x45,0x00,0x02,0xa0,0x60,0x00,0x0a,0x8c,0x82,0x00,0x00, +0xa4,0x65,0x00,0x06,0xa4,0x65,0x00,0x08,0xa0,0x40,0x00,0x10,0x8c,0x83,0x00,0x00, +0xa4,0x45,0x00,0x0c,0xa4,0x45,0x00,0x0e,0xa0,0x60,0x00,0x12,0x8c,0x82,0x00,0x00, +0x00,0x00,0x00,0x00,0xa0,0x40,0x00,0x16,0x8c,0x83,0x00,0x00,0xa4,0x45,0x00,0x14, +0xa0,0x67,0x00,0x17,0x8c,0x82,0x00,0x00,0x24,0x84,0x00,0x04,0xa0,0x40,0x00,0x20, +0x04,0xc1,0xff,0xe7,0xac,0x40,0x00,0x1c,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00, +0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x00,0x34,0x42,0x00,0x20,0x24,0x63,0x63,0x40, +0xac,0x43,0x00,0x00,0x90,0x82,0x00,0x10,0x00,0x80,0x60,0x21,0x10,0x40,0x00,0x56, +0x00,0x00,0x70,0x21,0x97,0x82,0x8f,0xf0,0x94,0x8a,0x00,0x0c,0x27,0x87,0x90,0x00, +0x00,0x02,0x40,0xc0,0x01,0x02,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x47,0x10,0x21, +0x90,0x8b,0x00,0x18,0xa4,0x4a,0x00,0x00,0x94,0x83,0x00,0x0e,0x39,0x64,0x00,0x10, +0x2c,0x84,0x00,0x01,0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x34,0x85,0x00,0x02, +0x39,0x63,0x00,0x11,0x00,0x83,0x28,0x0b,0x34,0xa3,0x00,0x08,0x39,0x64,0x00,0x12, +0x00,0x02,0x10,0x80,0x00,0xa4,0x18,0x0b,0x00,0x47,0x10,0x21,0x94,0x49,0x00,0x04, +0x34,0x64,0x00,0x20,0x00,0x6b,0x20,0x0b,0x34,0x83,0x00,0x40,0x39,0x62,0x00,0x01, +0x00,0x82,0x18,0x0b,0x00,0x09,0x30,0xc0,0x34,0x64,0x00,0x80,0x00,0xc9,0x28,0x21, +0x39,0x62,0x00,0x02,0x00,0x60,0x68,0x21,0x00,0x82,0x68,0x0a,0x00,0x05,0x28,0x80, +0x3c,0x02,0xb0,0x08,0x00,0xa7,0x28,0x21,0x00,0xc2,0x30,0x21,0x01,0x02,0x40,0x21, +0x34,0x03,0xff,0xff,0x35,0xa4,0x01,0x00,0x39,0x62,0x00,0x03,0x2d,0x67,0x00,0x13, +0xad,0x0a,0x00,0x00,0xa4,0xa3,0x00,0x00,0xac,0xc3,0x00,0x00,0xa7,0x89,0x8f,0xf0, +0x10,0xe0,0x00,0x0f,0x00,0x82,0x68,0x0a,0x3c,0x03,0x80,0x01,0x00,0x0b,0x10,0x80, +0x24,0x63,0x02,0x44,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x80,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x60, +0x94,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x14,0x00,0x00,0x02,0x74,0x03, +0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x3a,0x94,0x44,0x00,0x00,0x93,0x83,0x8f,0xe4, +0x91,0x82,0x00,0x21,0x01,0xc4,0x20,0x21,0x91,0x85,0x00,0x10,0x00,0x04,0x24,0x00, +0x00,0x62,0x18,0x21,0x00,0x04,0x74,0x03,0x00,0x6e,0x18,0x23,0x00,0x65,0x10,0x2a, +0x00,0xa2,0x18,0x0a,0x00,0x0d,0x24,0x00,0x3c,0x02,0xb0,0x06,0x24,0x05,0xff,0xff, +0x00,0x64,0x18,0x25,0x34,0x42,0x80,0x20,0xac,0x43,0x00,0x00,0xa5,0x85,0x00,0x0e, +0xa1,0x80,0x00,0x10,0xa5,0x85,0x00,0x0c,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00, +0x3c,0x03,0xb0,0x03,0x08,0x00,0x19,0x14,0x34,0x63,0x00,0x62,0x3c,0x03,0xb0,0x03, +0x08,0x00,0x19,0x14,0x34,0x63,0x00,0x64,0x3c,0x03,0xb0,0x03,0x08,0x00,0x19,0x14, +0x34,0x63,0x00,0x66,0x3c,0x03,0xb0,0x03,0x08,0x00,0x19,0x14,0x34,0x63,0x00,0x38, +0x3c,0x03,0xb0,0x03,0x08,0x00,0x19,0x14,0x34,0x63,0x00,0x6e,0x3c,0x03,0xb0,0x03, +0x08,0x00,0x19,0x14,0x34,0x63,0x00,0x6c,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00, +0x34,0x63,0x00,0x20,0x24,0x42,0x65,0x08,0x00,0x05,0x28,0x40,0xac,0x62,0x00,0x00, +0x00,0xa6,0x28,0x21,0x2c,0xe2,0x00,0x10,0x14,0x80,0x00,0x06,0x00,0x00,0x18,0x21, +0x10,0x40,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0xe0,0x18,0x21,0x03,0xe0,0x00,0x08, +0x00,0x60,0x10,0x21,0x24,0x02,0x00,0x20,0x10,0xe2,0x00,0x06,0x2c,0xe4,0x00,0x10, +0x24,0xa2,0x00,0x01,0x10,0x80,0xff,0xf9,0x00,0x02,0x11,0x00,0x08,0x00,0x19,0x4f, +0x00,0x47,0x18,0x21,0x08,0x00,0x19,0x4f,0x24,0xa3,0x00,0x50,0x27,0xbd,0xff,0xc8, +0xaf,0xb3,0x00,0x1c,0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xbf,0x00,0x30, +0xaf,0xb7,0x00,0x2c,0xaf,0xb6,0x00,0x28,0xaf,0xb5,0x00,0x24,0xaf,0xb4,0x00,0x20, +0xaf,0xb0,0x00,0x10,0x00,0x80,0x88,0x21,0x84,0x84,0x00,0x08,0x3c,0x05,0xb0,0x03, +0x3c,0x02,0x80,0x00,0x34,0xa5,0x00,0x20,0x24,0x42,0x65,0x6c,0x3c,0x03,0xb0,0x06, +0x00,0x04,0x20,0x80,0xac,0xa2,0x00,0x00,0x00,0x83,0x20,0x21,0x3c,0x06,0xb0,0x06, +0x8c,0x82,0x00,0x00,0x34,0xc6,0x80,0x24,0x8c,0x88,0x00,0x00,0x8c,0xc4,0x00,0x00, +0x96,0x25,0x00,0x08,0x30,0x52,0xff,0xff,0x00,0x08,0x44,0x02,0x34,0x84,0x01,0x00, +0x3c,0x02,0xb0,0x00,0x00,0x08,0x18,0xc0,0x00,0x12,0x3a,0x00,0xac,0xc4,0x00,0x00, +0x00,0xe2,0x38,0x21,0xae,0x32,0x02,0xb8,0x00,0x68,0x18,0x21,0x24,0xa5,0x00,0x02, +0x8c,0xf6,0x00,0x00,0x30,0xa5,0x01,0xff,0x8c,0xf4,0x00,0x04,0x27,0x86,0x90,0x00, +0x00,0x03,0x18,0x80,0x00,0x12,0x98,0xc0,0xa6,0x25,0x00,0x08,0x00,0x66,0x18,0x21, +0x02,0x72,0x10,0x21,0x94,0x65,0x00,0x00,0x00,0x02,0x48,0x80,0x01,0x26,0x30,0x21, +0x24,0x02,0xff,0xff,0x00,0x14,0x1a,0x02,0x27,0x84,0x90,0x10,0xa4,0xc2,0x00,0x02, +0x30,0x63,0x00,0x1f,0x24,0x02,0x00,0x10,0x01,0x24,0x20,0x21,0xa4,0xc8,0x00,0x04, +0x8c,0xf0,0x00,0x08,0xa6,0x23,0x00,0x06,0xa6,0x25,0x00,0x0a,0xa0,0x82,0x00,0x06, +0x86,0x25,0x00,0x06,0x27,0x82,0x90,0x04,0x01,0x22,0x10,0x21,0x24,0x03,0x00,0x13, +0x10,0xa3,0x00,0xee,0xac,0x47,0x00,0x18,0x3c,0x03,0xb0,0x03,0x34,0x63,0x01,0x00, +0xa6,0x20,0x00,0x02,0x3c,0x02,0xb0,0x03,0x90,0x64,0x00,0x00,0x34,0x42,0x01,0x08, +0x8c,0x45,0x00,0x00,0x00,0x10,0x1b,0xc2,0x00,0x04,0x20,0x82,0x30,0x63,0x00,0x01, +0xac,0xc5,0x00,0x08,0x10,0x60,0x00,0xc7,0x30,0x97,0x00,0x01,0x00,0x10,0x16,0x82, +0x30,0x46,0x00,0x01,0x00,0x10,0x12,0x02,0x00,0x10,0x19,0xc2,0x00,0x10,0x26,0x02, +0x00,0x10,0x2e,0x42,0x30,0x48,0x00,0x7f,0x24,0x02,0x00,0x01,0x30,0x75,0x00,0x01, +0x30,0x84,0x00,0x01,0x10,0xc2,0x00,0xb3,0x30,0xa3,0x00,0x01,0x00,0x60,0x28,0x21, +0x0c,0x00,0x19,0x42,0x01,0x00,0x38,0x21,0x02,0x72,0x18,0x21,0x00,0x03,0x18,0x80, +0x2c,0x46,0x00,0x54,0x27,0x85,0x90,0x10,0x27,0x84,0x90,0x08,0x00,0x06,0x10,0x0a, +0x00,0x65,0x28,0x21,0x26,0xa6,0x00,0x02,0x00,0x64,0x18,0x21,0xa0,0xa2,0x00,0x02, +0xa0,0x66,0x00,0x06,0xa0,0x62,0x00,0x07,0xa0,0xa2,0x00,0x01,0x02,0x72,0x28,0x21, +0x00,0x05,0x28,0x80,0x27,0x82,0x90,0x04,0x00,0xa2,0x58,0x21,0x8d,0x64,0x00,0x18, +0x00,0x10,0x15,0xc2,0x30,0x42,0x00,0x01,0x8c,0x83,0x00,0x0c,0x27,0x84,0x90,0x20, +0x00,0xa4,0x48,0x21,0xa6,0x22,0x00,0x00,0xa6,0x36,0x00,0x04,0x8d,0x26,0x00,0x00, +0x00,0x03,0x19,0x42,0x3c,0x02,0xff,0xef,0x34,0x42,0xff,0xff,0x30,0x63,0x00,0x01, +0x00,0xc2,0x40,0x24,0x00,0x03,0x1d,0x00,0x01,0x03,0x40,0x25,0x00,0x08,0x15,0x02, +0x00,0x14,0x19,0x82,0x00,0x14,0x25,0x82,0x00,0x10,0x34,0x42,0x00,0x10,0x3c,0x82, +0x00,0x10,0x2c,0x02,0x30,0x42,0x00,0x01,0x30,0xcd,0x00,0x01,0x30,0x6c,0x00,0x01, +0x30,0xe6,0x00,0x01,0x30,0x8a,0x00,0x03,0x32,0x94,0x00,0x07,0x30,0xa5,0x00,0x01, +0xad,0x28,0x00,0x00,0x10,0x40,0x00,0x0b,0x32,0x07,0x00,0x7f,0x8d,0x64,0x00,0x18, +0x3c,0x03,0xff,0xf0,0x34,0x63,0xff,0xff,0x8c,0x82,0x00,0x0c,0x01,0x03,0x18,0x24, +0x00,0x02,0x13,0x82,0x30,0x42,0x00,0x0f,0x00,0x02,0x14,0x00,0x00,0x62,0x18,0x25, +0xad,0x23,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xc2,0x00,0x6a,0x00,0x00,0x00,0x00, +0x15,0x80,0x00,0x03,0x00,0x00,0x00,0x00,0x15,0x40,0x00,0x5b,0x24,0x02,0x00,0x01, +0x96,0x22,0x00,0x04,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x04,0xa6,0x22,0x00,0x04, +0x00,0xa0,0x20,0x21,0x0c,0x00,0x19,0x42,0x01,0xa0,0x28,0x21,0x02,0x72,0x18,0x21, +0x00,0x03,0x40,0x80,0x2c,0x45,0x00,0x54,0x27,0x84,0x90,0x10,0x01,0x04,0x20,0x21, +0x00,0x05,0x10,0x0a,0xa0,0x82,0x00,0x00,0xa0,0x80,0x00,0x04,0xa0,0x80,0x00,0x05, +0x96,0x23,0x00,0x04,0x27,0x82,0x90,0x00,0x01,0x02,0x10,0x21,0xa4,0x43,0x00,0x06, +0x27,0x82,0x90,0x04,0x92,0x26,0x00,0x01,0x01,0x02,0x10,0x21,0x8c,0x45,0x00,0x18, +0x27,0x83,0x90,0x20,0x01,0x03,0x18,0x21,0xa0,0x60,0x00,0x00,0xa0,0x86,0x00,0x07, +0x94,0xa2,0x00,0x10,0x24,0x03,0x00,0x04,0x30,0x42,0x00,0x0f,0x10,0x43,0x00,0x36, +0x24,0xa5,0x00,0x10,0x94,0xa3,0x00,0x16,0x27,0x87,0x90,0x18,0x01,0x07,0x10,0x21, +0xa4,0x43,0x00,0x02,0x94,0xa2,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01, +0x14,0x40,0x00,0x24,0x02,0x72,0x20,0x21,0x94,0xa2,0x00,0x00,0x24,0x03,0x00,0xa4, +0x30,0x42,0x00,0xff,0x10,0x43,0x00,0x1f,0x00,0x00,0x00,0x00,0x94,0xa2,0x00,0x00, +0x24,0x03,0x00,0x88,0x30,0x42,0x00,0x88,0x10,0x43,0x00,0x14,0x02,0x72,0x18,0x21, +0x27,0x84,0x90,0x20,0x00,0x03,0x18,0x80,0x00,0x64,0x18,0x21,0x8c,0x62,0x00,0x00, +0x3c,0x04,0x00,0x80,0x00,0x44,0x10,0x25,0xac,0x62,0x00,0x00,0x02,0x72,0x10,0x21, +0x00,0x02,0x10,0x80,0x00,0x47,0x10,0x21,0xa0,0x54,0x00,0x00,0x8f,0xbf,0x00,0x30, +0x7b,0xb6,0x01,0x7c,0x7b,0xb4,0x01,0x3c,0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc, +0x24,0x02,0x00,0x01,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x38,0x94,0xa2,0x00,0x18, +0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x60,0x10,0x40,0xff,0xe9,0x02,0x72,0x18,0x21, +0x02,0x72,0x20,0x21,0x27,0x82,0x90,0x20,0x00,0x04,0x20,0x80,0x00,0x82,0x20,0x21, +0x8c,0x83,0x00,0x00,0x3c,0x02,0xff,0x7f,0x34,0x42,0xff,0xff,0x00,0x62,0x18,0x24, +0x08,0x00,0x1a,0x37,0xac,0x83,0x00,0x00,0x27,0x87,0x90,0x18,0x01,0x07,0x10,0x21, +0x08,0x00,0x1a,0x21,0xa4,0x40,0x00,0x02,0x11,0x42,0x00,0x07,0x00,0x00,0x00,0x00, +0x2d,0x42,0x00,0x02,0x14,0x40,0xff,0xa7,0x00,0xa0,0x20,0x21,0x96,0x22,0x00,0x04, +0x08,0x00,0x19,0xff,0x24,0x42,0x00,0x0c,0x96,0x22,0x00,0x04,0x08,0x00,0x19,0xff, +0x24,0x42,0x00,0x08,0x16,0xe6,0xff,0x96,0x3c,0x02,0xff,0xfb,0x8d,0x63,0x00,0x18, +0x34,0x42,0xff,0xff,0x02,0x02,0x10,0x24,0xac,0x62,0x00,0x08,0x08,0x00,0x19,0xf8, +0x00,0x00,0x30,0x21,0x16,0xe6,0xff,0x4e,0x00,0x60,0x28,0x21,0x3c,0x02,0xfb,0xff, +0x34,0x42,0xff,0xff,0x02,0x02,0x10,0x24,0xac,0xe2,0x00,0x08,0x08,0x00,0x19,0xb7, +0x00,0x00,0x30,0x21,0x93,0x87,0xbb,0x14,0x00,0x10,0x1e,0x42,0x00,0x10,0x26,0x82, +0x27,0x82,0x90,0x08,0x2c,0xe5,0x00,0x0c,0x01,0x22,0x48,0x21,0x30,0x63,0x00,0x01, +0x30,0x86,0x00,0x01,0x14,0xa0,0x00,0x06,0x00,0xe0,0x40,0x21,0x00,0x03,0x10,0x40, +0x00,0x46,0x10,0x21,0x00,0x02,0x11,0x00,0x00,0xe2,0x10,0x21,0x24,0x48,0x00,0x04, +0x02,0x72,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x84,0x90,0x10,0x27,0x83,0x90,0x08, +0x00,0x44,0x20,0x21,0x00,0x43,0x10,0x21,0xa1,0x28,0x00,0x07,0xa0,0x40,0x00,0x06, +0xa0,0x80,0x00,0x02,0x08,0x00,0x19,0xc7,0xa0,0x80,0x00,0x01,0x24,0x02,0x00,0x01, +0xa6,0x22,0x00,0x02,0x0c,0x00,0x01,0xc2,0x00,0xe0,0x20,0x21,0x08,0x00,0x1a,0x3b, +0x00,0x00,0x00,0x00,0x30,0xa7,0xff,0xff,0x00,0x07,0x18,0xc0,0x00,0x67,0x18,0x21, +0x3c,0x06,0xb0,0x03,0x3c,0x02,0x80,0x00,0x24,0x42,0x6a,0x44,0x27,0x85,0x90,0x10, +0x00,0x03,0x18,0x80,0x34,0xc6,0x00,0x20,0x00,0x65,0x18,0x21,0xac,0xc2,0x00,0x00, +0x80,0x62,0x00,0x07,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x29,0x00,0x80,0x28,0x21, +0x90,0x82,0x00,0x16,0x00,0x00,0x00,0x00,0x34,0x42,0x00,0x02,0x30,0x43,0x00,0x01, +0x14,0x60,0x00,0x02,0xa0,0x82,0x00,0x16,0xa0,0x80,0x00,0x17,0x90,0xa2,0x00,0x04, +0x3c,0x03,0xb0,0x03,0x27,0x86,0x90,0x00,0x14,0x40,0x00,0x06,0x34,0x63,0x00,0x20, +0x24,0x02,0x00,0x01,0xa0,0xa2,0x00,0x04,0xa4,0xa7,0x00,0x02,0x03,0xe0,0x00,0x08, +0xa4,0xa7,0x00,0x00,0x94,0xa4,0x00,0x02,0x3c,0x02,0x80,0x01,0x24,0x42,0x82,0x6c, +0xac,0x62,0x00,0x00,0x00,0x04,0x18,0xc0,0x00,0x64,0x18,0x21,0x00,0x03,0x18,0x80, +0x00,0x66,0x18,0x21,0x94,0x62,0x00,0x04,0xa4,0x67,0x00,0x02,0x3c,0x03,0xb0,0x08, +0x00,0x02,0x20,0xc0,0x00,0x82,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x46,0x10,0x21, +0x00,0x83,0x20,0x21,0xa4,0x47,0x00,0x00,0xac,0x87,0x00,0x00,0x90,0xa2,0x00,0x04, +0xa4,0xa7,0x00,0x02,0x24,0x42,0x00,0x01,0x03,0xe0,0x00,0x08,0xa0,0xa2,0x00,0x04, +0x90,0x82,0x00,0x16,0x24,0x85,0x00,0x06,0x34,0x42,0x00,0x01,0x30,0x43,0x00,0x02, +0x14,0x60,0xff,0xda,0xa0,0x82,0x00,0x16,0x24,0x02,0x00,0x01,0x08,0x00,0x1a,0xa7, +0xa0,0x82,0x00,0x17,0x27,0xbd,0xff,0xe8,0xaf,0xbf,0x00,0x10,0x00,0x80,0x38,0x21, +0x84,0x84,0x00,0x02,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x3c,0x0a,0xb0,0x06, +0x34,0x63,0x00,0x20,0x24,0x42,0x6b,0x44,0x3c,0x0b,0xb0,0x08,0x27,0x89,0x90,0x00, +0x34,0x0c,0xff,0xff,0x35,0x4a,0x80,0x20,0x10,0x80,0x00,0x30,0xac,0x62,0x00,0x00, +0x97,0x82,0x8f,0xf0,0x94,0xe6,0x02,0xba,0x00,0x02,0x18,0xc0,0x00,0x6b,0x28,0x21, +0xac,0xa6,0x00,0x00,0x8c,0xe4,0x02,0xb8,0x00,0x62,0x18,0x21,0x00,0x03,0x18,0x80, +0x00,0x04,0x10,0xc0,0x00,0x44,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x49,0x10,0x21, +0x94,0x48,0x00,0x04,0x00,0x69,0x18,0x21,0xa4,0x66,0x00,0x00,0x00,0x08,0x28,0xc0, +0x00,0xab,0x10,0x21,0xac,0x4c,0x00,0x00,0x8c,0xe4,0x02,0xb8,0x27,0x82,0x90,0x04, +0x00,0xa8,0x28,0x21,0x00,0x04,0x18,0xc0,0x00,0x64,0x18,0x21,0x00,0x03,0x18,0x80, +0x00,0x62,0x10,0x21,0x8c,0x46,0x00,0x18,0x27,0x84,0x90,0x10,0x00,0x64,0x18,0x21, +0x8c,0xc2,0x00,0x00,0x80,0x67,0x00,0x06,0x00,0x05,0x28,0x80,0x30,0x42,0xff,0xff, +0x00,0x47,0x10,0x21,0x30,0x43,0x00,0xff,0x00,0x03,0x18,0x2b,0x00,0x02,0x12,0x02, +0x00,0x43,0x10,0x21,0x3c,0x04,0x00,0x04,0x00,0xa9,0x28,0x21,0x00,0x44,0x10,0x25, +0xa4,0xac,0x00,0x00,0xad,0x42,0x00,0x00,0xa7,0x88,0x8f,0xf0,0x8f,0xbf,0x00,0x10, +0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x84,0xe3,0x00,0x06, +0x27,0x82,0xb4,0x00,0x94,0xe5,0x02,0xba,0x00,0x03,0x18,0x80,0x00,0x62,0x18,0x21, +0x8c,0x64,0x00,0x00,0x0c,0x00,0x1a,0x91,0x00,0x00,0x00,0x00,0x08,0x00,0x1b,0x0b, +0x00,0x00,0x00,0x00,0x94,0x88,0x00,0x00,0x00,0x80,0x58,0x21,0x27,0x8a,0x90,0x00, +0x00,0x08,0x18,0xc0,0x00,0x68,0x18,0x21,0x3c,0x04,0xb0,0x03,0x00,0x03,0x18,0x80, +0x3c,0x02,0x80,0x00,0x00,0x6a,0x18,0x21,0x34,0x84,0x00,0x20,0x24,0x42,0x6c,0x64, +0x30,0xa5,0xff,0xff,0xac,0x82,0x00,0x00,0x94,0x67,0x00,0x02,0x11,0x05,0x00,0x35, +0x24,0x04,0x00,0x01,0x91,0x66,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x86,0x10,0x2a, +0x10,0x40,0x00,0x10,0x00,0xc0,0x48,0x21,0x3c,0x0d,0xb0,0x03,0x01,0x40,0x60,0x21, +0x35,0xad,0x00,0x20,0x10,0xe5,0x00,0x0d,0x24,0x84,0x00,0x01,0x00,0x07,0x10,0xc0, +0x00,0x47,0x10,0x21,0x00,0x02,0x10,0x80,0x01,0x20,0x30,0x21,0x00,0x4a,0x10,0x21, +0x00,0x86,0x18,0x2a,0x00,0xe0,0x40,0x21,0x94,0x47,0x00,0x02,0x14,0x60,0xff,0xf5, +0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x10,0x21,0x00,0x08,0x20,0xc0, +0x00,0x88,0x20,0x21,0x24,0xc2,0xff,0xff,0x00,0x04,0x20,0x80,0xa1,0x62,0x00,0x04, +0x00,0x8c,0x20,0x21,0x94,0x83,0x00,0x04,0x00,0x07,0x10,0xc0,0x00,0x47,0x10,0x21, +0x00,0x02,0x10,0x80,0x00,0x4c,0x10,0x21,0x00,0x03,0x28,0xc0,0x94,0x46,0x00,0x02, +0x00,0xa3,0x18,0x21,0x00,0x03,0x18,0x80,0x00,0x6c,0x18,0x21,0xa4,0x66,0x00,0x00, +0xa4,0x86,0x00,0x02,0x95,0x64,0x00,0x02,0x3c,0x03,0xb0,0x08,0x3c,0x02,0x80,0x01, +0x00,0xa3,0x28,0x21,0x24,0x42,0x82,0x6c,0xad,0xa2,0x00,0x00,0x10,0x87,0x00,0x03, +0xac,0xa6,0x00,0x00,0x03,0xe0,0x00,0x08,0x24,0x02,0x00,0x01,0x08,0x00,0x1b,0x59, +0xa5,0x68,0x00,0x02,0x91,0x62,0x00,0x04,0xa5,0x67,0x00,0x00,0x24,0x42,0xff,0xff, +0x30,0x43,0x00,0xff,0x14,0x60,0xff,0xf7,0xa1,0x62,0x00,0x04,0x24,0x02,0xff,0xff, +0x08,0x00,0x1b,0x59,0xa5,0x62,0x00,0x02,0x00,0x05,0x40,0xc0,0x01,0x05,0x30,0x21, +0x27,0xbd,0xff,0xd8,0x00,0x06,0x30,0x80,0x27,0x82,0x90,0x04,0xaf,0xb2,0x00,0x18, +0xaf,0xb1,0x00,0x14,0xaf,0xbf,0x00,0x20,0xaf,0xb3,0x00,0x1c,0xaf,0xb0,0x00,0x10, +0x00,0xc2,0x10,0x21,0x8c,0x47,0x00,0x18,0x00,0xa0,0x90,0x21,0x3c,0x02,0x80,0x00, +0x3c,0x05,0xb0,0x03,0x34,0xa5,0x00,0x20,0x24,0x42,0x6d,0x98,0xac,0xa2,0x00,0x00, +0x27,0x83,0x90,0x10,0x00,0xc3,0x30,0x21,0x8c,0xe2,0x00,0x00,0x80,0xc5,0x00,0x06, +0x00,0x80,0x88,0x21,0x30,0x42,0xff,0xff,0x00,0x45,0x10,0x21,0x30,0x43,0x00,0xff, +0x10,0x60,0x00,0x02,0x00,0x02,0x12,0x02,0x24,0x42,0x00,0x01,0x30,0x53,0x00,0xff, +0x01,0x12,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x10,0x00,0x43,0x10,0x21, +0x80,0x44,0x00,0x07,0x00,0x00,0x00,0x00,0x10,0x80,0x00,0x4b,0x26,0x24,0x00,0x06, +0x32,0x50,0xff,0xff,0x02,0x20,0x20,0x21,0x0c,0x00,0x1b,0x19,0x02,0x00,0x28,0x21, +0x92,0x22,0x00,0x10,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x2e,0x3c,0x03,0xb0,0x08, +0x3c,0x09,0x80,0x01,0x27,0x88,0x90,0x00,0xa6,0x32,0x00,0x0c,0x00,0x10,0x20,0xc0, +0x00,0x90,0x20,0x21,0x00,0x04,0x20,0x80,0x00,0x88,0x20,0x21,0x94,0x82,0x00,0x04, +0x3c,0x03,0xb0,0x08,0x3c,0x07,0xb0,0x03,0x00,0x02,0x28,0xc0,0x00,0xa2,0x10,0x21, +0x00,0x02,0x10,0x80,0x00,0x48,0x10,0x21,0x00,0xa3,0x28,0x21,0x25,0x26,0x82,0x6c, +0x34,0x03,0xff,0xff,0x34,0xe7,0x00,0x20,0xac,0xe6,0x00,0x00,0xa4,0x83,0x00,0x02, +0xa4,0x43,0x00,0x00,0xac,0xa3,0x00,0x00,0x92,0x22,0x00,0x10,0x92,0x23,0x00,0x0a, +0xa6,0x32,0x00,0x0e,0x02,0x62,0x10,0x21,0x14,0x60,0x00,0x05,0xa2,0x22,0x00,0x10, +0x92,0x22,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xfe,0xa2,0x22,0x00,0x16, +0x92,0x22,0x00,0x04,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x05,0x00,0x00,0x00,0x00, +0x92,0x22,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xfd,0xa2,0x22,0x00,0x16, +0x8f,0xbf,0x00,0x20,0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x28,0x96,0x22,0x00,0x0e,0x27,0x88,0x90,0x00,0x00,0x02,0x20,0xc0, +0x00,0x82,0x20,0x21,0x00,0x04,0x20,0x80,0x00,0x88,0x20,0x21,0x94,0x82,0x00,0x04, +0x3c,0x06,0xb0,0x03,0x3c,0x09,0x80,0x01,0x00,0x02,0x28,0xc0,0x00,0xa2,0x10,0x21, +0x00,0x02,0x10,0x80,0x00,0xa3,0x28,0x21,0x00,0x48,0x10,0x21,0x34,0xc6,0x00,0x20, +0x25,0x23,0x82,0x6c,0xac,0xc3,0x00,0x00,0xa4,0x50,0x00,0x00,0xac,0xb0,0x00,0x00, +0x08,0x00,0x1b,0x97,0xa4,0x90,0x00,0x02,0x08,0x00,0x1b,0x8e,0x32,0x50,0xff,0xff, +0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00,0x24,0x42,0x6f,0x60,0x34,0x63,0x00,0x20, +0xac,0x62,0x00,0x00,0x90,0x82,0x00,0x04,0x97,0xaa,0x00,0x12,0x00,0x80,0x60,0x21, +0x30,0xa8,0xff,0xff,0x00,0x4a,0x20,0x23,0x34,0x09,0xff,0xff,0x30,0xcf,0xff,0xff, +0x30,0xee,0xff,0xff,0x11,0x09,0x00,0x73,0xa1,0x84,0x00,0x04,0x00,0x0e,0xc0,0xc0, +0x00,0x08,0x10,0xc0,0x00,0x48,0x10,0x21,0x03,0x0e,0x20,0x21,0x27,0x8d,0x90,0x00, +0x00,0x04,0x20,0x80,0x00,0x02,0x10,0x80,0x00,0x4d,0x10,0x21,0x00,0x8d,0x20,0x21, +0x94,0x86,0x00,0x02,0x94,0x43,0x00,0x04,0x3c,0x19,0x80,0x01,0xa4,0x46,0x00,0x02, +0x00,0x03,0x28,0xc0,0x00,0xa3,0x18,0x21,0x94,0x87,0x00,0x02,0x3c,0x02,0xb0,0x08, +0x00,0x03,0x18,0x80,0x00,0xa2,0x28,0x21,0x00,0x6d,0x18,0x21,0x27,0x22,0x82,0x6c, +0x3c,0x01,0xb0,0x03,0xac,0x22,0x00,0x20,0xa4,0x66,0x00,0x00,0x10,0xe9,0x00,0x57, +0xac,0xa6,0x00,0x00,0x01,0xe0,0x30,0x21,0x11,0x40,0x00,0x1d,0x00,0x00,0x48,0x21, +0x01,0x40,0x38,0x21,0x27,0x8b,0x90,0x04,0x27,0x8a,0x90,0x10,0x00,0x06,0x40,0xc0, +0x01,0x06,0x18,0x21,0x00,0x03,0x18,0x80,0x00,0x6b,0x10,0x21,0x8c,0x44,0x00,0x18, +0x00,0x6a,0x18,0x21,0x80,0x65,0x00,0x06,0x8c,0x82,0x00,0x00,0x00,0x00,0x00,0x00, +0x30,0x42,0xff,0xff,0x00,0x45,0x10,0x21,0x30,0x44,0x00,0xff,0x00,0x02,0x12,0x02, +0x01,0x22,0x18,0x21,0x24,0x62,0x00,0x01,0x14,0x80,0x00,0x02,0x30,0x49,0x00,0xff, +0x30,0x69,0x00,0xff,0x01,0x06,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x4d,0x10,0x21, +0x24,0xe7,0xff,0xff,0x94,0x46,0x00,0x02,0x14,0xe0,0xff,0xe9,0x00,0x06,0x40,0xc0, +0x91,0x82,0x00,0x10,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x20,0x3c,0x06,0xb0,0x03, +0xa5,0x8f,0x00,0x0c,0x03,0x0e,0x20,0x21,0x00,0x04,0x20,0x80,0x00,0x8d,0x20,0x21, +0x94,0x82,0x00,0x04,0x3c,0x03,0xb0,0x08,0x3c,0x07,0xb0,0x03,0x00,0x02,0x28,0xc0, +0x00,0xa2,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x4d,0x10,0x21,0x00,0xa3,0x28,0x21, +0x27,0x26,0x82,0x6c,0x34,0x03,0xff,0xff,0x34,0xe7,0x00,0x20,0xac,0xe6,0x00,0x00, +0xa4,0x83,0x00,0x02,0xa4,0x43,0x00,0x00,0xac,0xa3,0x00,0x00,0x91,0x82,0x00,0x10, +0x91,0x83,0x00,0x04,0xa5,0x8e,0x00,0x0e,0x01,0x22,0x10,0x21,0x14,0x60,0x00,0x05, +0xa1,0x82,0x00,0x10,0x91,0x82,0x00,0x16,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0xfd, +0xa1,0x82,0x00,0x16,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x95,0x82,0x00,0x0e, +0x3c,0x03,0xb0,0x08,0x00,0x02,0x20,0xc0,0x00,0x82,0x20,0x21,0x00,0x04,0x20,0x80, +0x00,0x8d,0x20,0x21,0x94,0x82,0x00,0x04,0x34,0xc6,0x00,0x20,0x27,0x27,0x82,0x6c, +0x00,0x02,0x28,0xc0,0x00,0xa2,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0xa3,0x28,0x21, +0x00,0x4d,0x10,0x21,0xac,0xc7,0x00,0x00,0xa4,0x8f,0x00,0x02,0xa4,0x4f,0x00,0x00, +0xac,0xaf,0x00,0x00,0x08,0x00,0x1c,0x26,0x03,0x0e,0x20,0x21,0x08,0x00,0x1c,0x01, +0xa5,0x88,0x00,0x02,0x00,0x0e,0xc0,0xc0,0x03,0x0e,0x10,0x21,0x00,0x02,0x10,0x80, +0x27,0x8d,0x90,0x00,0x00,0x4d,0x10,0x21,0x94,0x43,0x00,0x02,0x30,0x84,0x00,0xff, +0x14,0x80,0x00,0x05,0xa5,0x83,0x00,0x00,0x24,0x02,0xff,0xff,0x3c,0x19,0x80,0x01, +0x08,0x00,0x1c,0x01,0xa5,0x82,0x00,0x02,0x08,0x00,0x1c,0x01,0x3c,0x19,0x80,0x01, +0x3c,0x08,0xb0,0x03,0x3c,0x02,0x80,0x00,0x27,0xbd,0xff,0x78,0x35,0x08,0x00,0x20, +0x24,0x42,0x71,0xa0,0xaf,0xb2,0x00,0x68,0xaf,0xb1,0x00,0x64,0xaf,0xb0,0x00,0x60, +0xad,0x02,0x00,0x00,0xaf,0xbf,0x00,0x84,0xaf,0xbe,0x00,0x80,0xaf,0xb7,0x00,0x7c, +0xaf,0xb6,0x00,0x78,0xaf,0xb5,0x00,0x74,0xaf,0xb4,0x00,0x70,0xaf,0xb3,0x00,0x6c, +0xaf,0xa4,0x00,0x88,0x90,0x83,0x00,0x0a,0x27,0x82,0xb4,0x00,0xaf,0xa6,0x00,0x90, +0x00,0x03,0x18,0x80,0x00,0x62,0x18,0x21,0x8c,0x63,0x00,0x00,0xaf,0xa7,0x00,0x94, +0x27,0x86,0x90,0x04,0xaf,0xa3,0x00,0x1c,0x94,0x63,0x00,0x14,0x30,0xb1,0xff,0xff, +0x24,0x08,0x00,0x01,0x00,0x03,0x20,0xc0,0xaf,0xa3,0x00,0x18,0x00,0x83,0x18,0x21, +0xaf,0xa4,0x00,0x54,0x00,0x03,0x18,0x80,0x27,0x84,0x90,0x10,0x00,0x64,0x20,0x21, +0x80,0x82,0x00,0x06,0x00,0x66,0x18,0x21,0x8c,0x66,0x00,0x18,0x24,0x42,0x00,0x02, +0x00,0x02,0x1f,0xc2,0x8c,0xc4,0x00,0x08,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x43, +0x00,0x02,0x10,0x40,0x00,0x04,0x2f,0xc2,0x00,0x04,0x1c,0x82,0x00,0xc2,0x38,0x21, +0x00,0x04,0x24,0x42,0x8f,0xa2,0x00,0x1c,0x30,0x63,0x00,0x01,0x30,0x84,0x00,0x01, +0xaf,0xa5,0x00,0x3c,0xaf,0xa3,0x00,0x34,0xaf,0xa4,0x00,0x38,0xaf,0xa0,0x00,0x40, +0xaf,0xa0,0x00,0x44,0xaf,0xa0,0x00,0x50,0xaf,0xa8,0x00,0x20,0x80,0x42,0x00,0x12, +0x8f,0xb2,0x00,0x18,0xaf,0xa2,0x00,0x28,0x8c,0xd0,0x00,0x0c,0x14,0xa0,0x01,0xe4, +0x00,0x60,0x30,0x21,0x00,0x10,0x10,0x82,0x30,0x45,0x00,0x07,0x10,0xa0,0x00,0x11, +0xaf,0xa0,0x00,0x30,0x8f,0xa4,0x00,0x98,0x27,0x82,0x80,0x1c,0x00,0x04,0x18,0x40, +0x00,0x62,0x18,0x21,0x24,0xa2,0x00,0x06,0x8f,0xa5,0x00,0x20,0x94,0x64,0x00,0x00, +0x00,0x45,0x10,0x04,0x00,0x44,0x00,0x1a,0x14,0x80,0x00,0x02,0x00,0x00,0x00,0x00, +0x00,0x07,0x00,0x0d,0x00,0x00,0x10,0x12,0x24,0x42,0x00,0x20,0x30,0x42,0xff,0xfc, +0xaf,0xa2,0x00,0x30,0x8f,0xa3,0x00,0x18,0x8f,0xa4,0x00,0x28,0x34,0x02,0xff,0xff, +0xaf,0xa0,0x00,0x2c,0xaf,0xa2,0x00,0x48,0xaf,0xa3,0x00,0x4c,0x00,0x60,0xf0,0x21, +0x00,0x00,0xb8,0x21,0x18,0x80,0x00,0x48,0xaf,0xa0,0x00,0x24,0x00,0x11,0x89,0x02, +0xaf,0xb1,0x00,0x58,0x00,0x80,0xa8,0x21,0x00,0x12,0x10,0xc0,0x00,0x52,0x18,0x21, +0x00,0x03,0x80,0x80,0x27,0x85,0x90,0x00,0x02,0x40,0x20,0x21,0x00,0x40,0xa0,0x21, +0x02,0x05,0x10,0x21,0x94,0x56,0x00,0x02,0x0c,0x00,0x12,0x8b,0x00,0x00,0x28,0x21, +0x90,0x42,0x00,0x00,0x24,0x03,0x00,0x08,0x30,0x42,0x00,0x0c,0x10,0x43,0x01,0x9e, +0x24,0x04,0x00,0x01,0x24,0x02,0x00,0x01,0x10,0x82,0x01,0x7c,0x3c,0x02,0xb0,0x03, +0x8f,0xa6,0x00,0x88,0x34,0x42,0x01,0x04,0x84,0xc5,0x00,0x0c,0x02,0x92,0x18,0x21, +0x94,0x46,0x00,0x00,0x00,0x05,0x20,0xc0,0x00,0x85,0x20,0x21,0x00,0x03,0x18,0x80, +0x27,0x82,0x90,0x10,0x27,0x85,0x90,0x08,0x00,0x65,0x28,0x21,0x00,0x62,0x18,0x21, +0x80,0x71,0x00,0x05,0x80,0x73,0x00,0x04,0x8f,0xa3,0x00,0x88,0x30,0xd0,0xff,0xff, +0x00,0x10,0x3a,0x03,0x32,0x08,0x00,0xff,0x27,0x82,0x90,0x20,0x00,0x04,0x20,0x80, +0x80,0xa6,0x00,0x06,0x00,0x82,0x20,0x21,0xa4,0x67,0x00,0x44,0xa4,0x68,0x00,0x46, +0x8c,0x84,0x00,0x00,0x38,0xc6,0x00,0x00,0x01,0x00,0x80,0x21,0x00,0x04,0x15,0x02, +0x30,0x42,0x00,0x01,0x10,0x40,0x00,0x03,0x00,0xe6,0x80,0x0a,0x00,0x04,0x14,0x02, +0x30,0x50,0x00,0x0f,0x12,0x20,0x01,0x50,0x02,0x40,0x20,0x21,0x02,0x71,0x10,0x21, +0x00,0x50,0x10,0x2a,0x14,0x40,0x00,0xed,0x02,0x92,0x10,0x21,0x93,0x82,0x8b,0x71, +0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01,0x14,0x40,0x00,0xe0,0x02,0x92,0x28,0x21, +0x26,0xe2,0x00,0x01,0x30,0x57,0xff,0xff,0x02,0x40,0xf0,0x21,0x26,0xb5,0xff,0xff, +0x16,0xa0,0xff,0xbd,0x02,0xc0,0x90,0x21,0x16,0xe0,0x00,0xd0,0x00,0x00,0x00,0x00, +0x8f,0xa3,0x00,0x98,0x00,0x00,0x00,0x00,0x2c,0x62,0x00,0x10,0x10,0x40,0x00,0x2e, +0x00,0x00,0x00,0x00,0x8f,0xa4,0x00,0x24,0x00,0x00,0x00,0x00,0x18,0x80,0x00,0x2a, +0x24,0x03,0x00,0x01,0x8f,0xa5,0x00,0x1c,0x27,0x84,0x90,0x04,0x94,0xb2,0x00,0x14, +0xa0,0xa3,0x00,0x12,0x8f,0xa6,0x00,0x3c,0x00,0x12,0x10,0xc0,0x00,0x52,0x10,0x21, +0x00,0x02,0x80,0x80,0x27,0x82,0x90,0x10,0x02,0x02,0x10,0x21,0x80,0x43,0x00,0x06, +0x02,0x04,0x20,0x21,0x8c,0x85,0x00,0x18,0x24,0x63,0x00,0x02,0x00,0x03,0x17,0xc2, +0x00,0x62,0x18,0x21,0x00,0x03,0x18,0x43,0x00,0x03,0x18,0x40,0x14,0xc0,0x00,0x0e, +0x00,0xa3,0x38,0x21,0x27,0x82,0x90,0x00,0x02,0x02,0x10,0x21,0x94,0x43,0x00,0x06, +0x8f,0xa8,0x00,0x1c,0x24,0x02,0x00,0x01,0xa5,0x03,0x00,0x1a,0x7b,0xbe,0x04,0x3c, +0x7b,0xb6,0x03,0xfc,0x7b,0xb4,0x03,0xbc,0x7b,0xb2,0x03,0x7c,0x7b,0xb0,0x03,0x3c, +0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x88,0x8f,0xa4,0x00,0x98,0x8f,0xa5,0x00,0x38, +0x8f,0xa6,0x00,0x34,0xaf,0xa0,0x00,0x10,0x0c,0x00,0x09,0x0a,0xaf,0xa0,0x00,0x14, +0x08,0x00,0x1d,0x2d,0x00,0x00,0x00,0x00,0x8f,0xa3,0x00,0x44,0x93,0x82,0x81,0x58, +0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x61,0x30,0x69,0x00,0x03,0x8f,0xa4,0x00,0x24, +0x8f,0xa5,0x00,0x28,0x00,0x00,0x00,0x00,0x00,0x85,0x10,0x2a,0x10,0x40,0x00,0x8f, +0x00,0x00,0x00,0x00,0x8f,0xa6,0x00,0x1c,0x00,0x00,0x00,0x00,0x90,0xc4,0x00,0x04, +0x00,0x00,0x00,0x00,0x30,0x83,0x00,0xff,0x00,0xa3,0x10,0x2a,0x10,0x40,0x00,0x87, +0x00,0x00,0x00,0x00,0x8f,0xa8,0x00,0x24,0x00,0x00,0x00,0x00,0x11,0x00,0x00,0x83, +0x00,0x65,0x10,0x23,0x00,0xa8,0x18,0x23,0x00,0x62,0x10,0x2a,0x14,0x40,0x00,0x7d, +0x30,0x63,0x00,0xff,0x00,0x85,0x10,0x23,0x30,0x42,0x00,0xff,0xaf,0xa2,0x00,0x50, +0x8f,0xa2,0x00,0x50,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x73,0x00,0x00,0xa8,0x21, +0x27,0x8c,0x90,0x00,0x3c,0x0b,0x80,0xff,0x24,0x10,0x00,0x04,0x27,0x91,0x90,0x04, +0x35,0x6b,0xff,0xff,0x3c,0x0d,0x7f,0x00,0x27,0x8e,0x90,0x10,0x01,0x80,0x78,0x21, +0x00,0x12,0x30,0xc0,0x00,0xd2,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x4c,0x10,0x21, +0x94,0x42,0x00,0x06,0x8f,0xa3,0x00,0x2c,0x8f,0xa4,0x00,0x30,0xaf,0xa2,0x00,0x44, +0x8f,0xa5,0x00,0x44,0x30,0x49,0x00,0x03,0x02,0x09,0x10,0x23,0x30,0x42,0x00,0x03, +0x00,0xa2,0x10,0x21,0x8f,0xa8,0x00,0x30,0x24,0x42,0x00,0x04,0x30,0x42,0xff,0xff, +0x00,0x64,0x38,0x21,0x01,0x02,0x28,0x23,0x00,0x62,0x18,0x21,0x00,0x48,0x10,0x2b, +0x10,0x40,0x00,0x52,0x00,0x00,0x20,0x21,0x30,0xe7,0xff,0xff,0x30,0xa4,0xff,0xff, +0xaf,0xa7,0x00,0x2c,0x00,0xd2,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x51,0x18,0x21, +0x8c,0x65,0x00,0x18,0x00,0x04,0x25,0x40,0x00,0x8d,0x20,0x24,0x8c,0xa8,0x00,0x04, +0x00,0x4e,0x18,0x21,0x00,0x4f,0x50,0x21,0x01,0x0b,0x40,0x24,0x01,0x04,0x40,0x25, +0xac,0xa8,0x00,0x04,0x8f,0xa4,0x00,0x98,0x8f,0xa2,0x00,0x50,0x26,0xb5,0x00,0x01, +0xa0,0x64,0x00,0x00,0x8c,0xa4,0x00,0x08,0x00,0x00,0x00,0x00,0x04,0x81,0x00,0x0c, +0x02,0xa2,0x30,0x2a,0x80,0x62,0x00,0x06,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x02, +0x00,0x02,0x1f,0xc2,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x43,0x00,0x02,0x10,0x40, +0x00,0xa2,0x38,0x21,0x8f,0xa5,0x00,0x40,0x00,0x00,0x00,0x00,0xa4,0xe5,0x00,0x00, +0x95,0x52,0x00,0x02,0x14,0xc0,0xff,0xc7,0x00,0x12,0x30,0xc0,0x8f,0xa4,0x00,0x24, +0x8f,0xa5,0x00,0x50,0x8f,0xa6,0x00,0x1c,0x8f,0xa3,0x00,0x2c,0x00,0x85,0x80,0x21, +0xa0,0xd0,0x00,0x12,0x00,0x09,0x10,0x23,0x30,0x42,0x00,0x03,0x8f,0xa8,0x00,0x88, +0x00,0x62,0x10,0x23,0xa4,0xc2,0x00,0x1a,0x85,0x03,0x00,0x0c,0x00,0x00,0x00,0x00, +0x00,0x03,0x10,0xc0,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x04, +0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x18,0x00,0x00,0x00,0x00,0x8c,0x83,0x00,0x04, +0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x10,0x14,0x60,0xff,0x74,0x02,0x00,0x10,0x21, +0x8f,0xa3,0x00,0x54,0x8f,0xa4,0x00,0x18,0x8f,0xa5,0x00,0x24,0x00,0x64,0x10,0x21, +0x00,0x02,0x10,0x80,0x27,0x83,0x90,0x18,0x00,0x43,0x10,0x21,0x90,0x44,0x00,0x00, +0x10,0xa0,0x00,0x03,0x00,0x00,0x30,0x21,0x08,0x00,0x1d,0x33,0x02,0x00,0x10,0x21, +0x93,0x82,0x80,0x10,0x00,0x00,0x28,0x21,0x00,0x00,0x38,0x21,0x0c,0x00,0x21,0x9a, +0xaf,0xa2,0x00,0x10,0x08,0x00,0x1d,0x33,0x02,0x00,0x10,0x21,0x30,0x63,0xff,0xff, +0x08,0x00,0x1d,0x85,0xaf,0xa3,0x00,0x2c,0x8f,0xa8,0x00,0x44,0x08,0x00,0x1d,0xa7, +0x31,0x09,0x00,0x03,0x08,0x00,0x1d,0x60,0xaf,0xa3,0x00,0x50,0x8f,0xa6,0x00,0x44, +0xaf,0xa0,0x00,0x50,0x08,0x00,0x1d,0xa7,0x30,0xc9,0x00,0x03,0x8f,0xa5,0x00,0x48, +0x8f,0xa6,0x00,0x4c,0x8f,0xa4,0x00,0x1c,0x03,0xc0,0x38,0x21,0x0c,0x00,0x1b,0xd8, +0xaf,0xb7,0x00,0x10,0x08,0x00,0x1d,0x10,0x00,0x00,0x00,0x00,0x00,0x05,0x28,0x80, +0x27,0x82,0x90,0x00,0x00,0xa2,0x28,0x21,0x00,0x00,0x20,0x21,0x0c,0x00,0x01,0x49, +0x00,0x00,0x00,0x00,0x08,0x00,0x1d,0x09,0x26,0xe2,0x00,0x01,0x00,0x02,0x80,0x80, +0x27,0x83,0x90,0x10,0x8f,0xa4,0x00,0x1c,0x02,0x03,0x18,0x21,0x26,0x31,0x00,0x01, +0x02,0x40,0x28,0x21,0x0c,0x00,0x1e,0xea,0xa0,0x71,0x00,0x05,0x14,0x40,0xff,0x13, +0x00,0x00,0x00,0x00,0x16,0xe0,0x00,0x4d,0x03,0xc0,0x38,0x21,0x8f,0xa4,0x00,0x24, +0x8f,0xa5,0x00,0x20,0x24,0x02,0x00,0x01,0x24,0x84,0x00,0x01,0xaf,0xb2,0x00,0x48, +0xaf,0xb6,0x00,0x4c,0x02,0xc0,0xf0,0x21,0x10,0xa2,0x00,0x41,0xaf,0xa4,0x00,0x24, +0x27,0x82,0x90,0x00,0x02,0x02,0x10,0x21,0x94,0x42,0x00,0x06,0x8f,0xa4,0x00,0x30, +0xaf,0xa0,0x00,0x20,0xaf,0xa2,0x00,0x44,0x30,0x49,0x00,0x03,0x8f,0xa8,0x00,0x44, +0x00,0x09,0x10,0x23,0x30,0x42,0x00,0x03,0x01,0x02,0x10,0x21,0x24,0x42,0x00,0x04, +0x30,0x42,0xff,0xff,0x00,0x44,0x18,0x2b,0x10,0x60,0x00,0x2b,0x00,0x00,0x00,0x00, +0x8f,0xa5,0x00,0x2c,0x00,0x82,0x10,0x23,0x00,0xa4,0x18,0x21,0x30,0x63,0xff,0xff, +0x30,0x44,0xff,0xff,0xaf,0xa3,0x00,0x2c,0x02,0x92,0x28,0x21,0x00,0x05,0x28,0x80, +0x27,0x82,0x90,0x04,0x00,0xa2,0x10,0x21,0x8c,0x46,0x00,0x18,0x3c,0x03,0x80,0xff, +0x3c,0x02,0x7f,0x00,0x8c,0xc8,0x00,0x04,0x00,0x04,0x25,0x40,0x34,0x63,0xff,0xff, +0x00,0x82,0x20,0x24,0x01,0x03,0x40,0x24,0x01,0x04,0x40,0x25,0xac,0xc8,0x00,0x04, +0x8f,0xa8,0x00,0x98,0x27,0x82,0x90,0x10,0x00,0xa2,0x10,0x21,0xa0,0x48,0x00,0x00, +0x8c,0xc4,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x04,0x27,0xc2,0x10,0x80,0xfe,0xdb, +0xaf,0xa4,0x00,0x3c,0x80,0x42,0x00,0x06,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x02, +0x00,0x02,0x1f,0xc2,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x43,0x00,0x02,0x10,0x40, +0x00,0xc2,0x38,0x21,0x8f,0xa2,0x00,0x40,0x00,0x00,0x00,0x00,0xa4,0xe2,0x00,0x00, +0x08,0x00,0x1d,0x0c,0x26,0xb5,0xff,0xff,0x8f,0xa6,0x00,0x2c,0x00,0x00,0x20,0x21, +0x00,0xc2,0x10,0x21,0x30,0x42,0xff,0xff,0x08,0x00,0x1e,0x1a,0xaf,0xa2,0x00,0x2c, +0x8f,0xa6,0x00,0x1c,0x08,0x00,0x1e,0x04,0xa4,0xd2,0x00,0x14,0x8f,0xa5,0x00,0x48, +0x8f,0xa6,0x00,0x4c,0x8f,0xa4,0x00,0x1c,0x0c,0x00,0x1b,0xd8,0xaf,0xb7,0x00,0x10, +0x08,0x00,0x1d,0xfb,0x00,0x00,0xb8,0x21,0x0c,0x00,0x12,0x8b,0x00,0x00,0x28,0x21, +0x00,0x40,0x18,0x21,0x94,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x34,0x42,0x08,0x00, +0xa4,0x62,0x00,0x00,0x08,0x00,0x1d,0x00,0x02,0x71,0x10,0x21,0x02,0x92,0x18,0x21, +0x00,0x03,0x80,0x80,0x27,0x82,0x90,0x04,0x02,0x02,0x10,0x21,0x8c,0x44,0x00,0x18, +0x00,0x00,0x00,0x00,0x8c,0x83,0x00,0x04,0x00,0x00,0x00,0x00,0x30,0x63,0x00,0x10, +0x10,0x60,0x00,0x09,0x24,0x06,0x00,0x01,0x93,0x82,0x8b,0x71,0x00,0x00,0x00,0x00, +0x30,0x42,0x00,0x01,0x10,0x40,0xfe,0xa2,0x3c,0x04,0x00,0x80,0x27,0x85,0x90,0x00, +0x08,0x00,0x1d,0xeb,0x02,0x05,0x28,0x21,0x27,0x83,0x90,0x18,0x27,0x82,0x90,0x10, +0x02,0x03,0x18,0x21,0x02,0x02,0x10,0x21,0x90,0x64,0x00,0x00,0x90,0x45,0x00,0x05, +0x93,0x83,0x80,0x10,0x00,0x00,0x38,0x21,0x0c,0x00,0x21,0x9a,0xaf,0xa3,0x00,0x10, +0x08,0x00,0x1e,0x62,0x00,0x00,0x00,0x00,0x27,0x82,0x90,0x18,0x02,0x02,0x10,0x21, +0x94,0x43,0x00,0x02,0x8f,0xa6,0x00,0x58,0x00,0x03,0x19,0x02,0x00,0x66,0x18,0x23, +0x30,0x63,0x0f,0xff,0x28,0x62,0x00,0x20,0x10,0x40,0x00,0x06,0x28,0x62,0x00,0x40, +0x8f,0xa8,0x00,0x90,0x00,0x00,0x00,0x00,0x00,0x68,0x10,0x06,0x08,0x00,0x1c,0xd9, +0x30,0x44,0x00,0x01,0x10,0x40,0x00,0x04,0x00,0x00,0x00,0x00,0x8f,0xa4,0x00,0x94, +0x08,0x00,0x1e,0x83,0x00,0x64,0x10,0x06,0x08,0x00,0x1c,0xd9,0x00,0x00,0x20,0x21, +0x8f,0xa4,0x00,0x98,0x8f,0xa5,0x00,0x38,0xaf,0xa0,0x00,0x10,0x0c,0x00,0x09,0x0a, +0xaf,0xa8,0x00,0x14,0x30,0x42,0xff,0xff,0x08,0x00,0x1c,0xa9,0xaf,0xa2,0x00,0x40, +0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x00,0x27,0xbd,0xff,0xe0,0x34,0x42,0x00,0x20, +0x24,0x63,0x7a,0x50,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x18, +0xac,0x43,0x00,0x00,0x90,0x82,0x00,0x0a,0x00,0x80,0x80,0x21,0x14,0x40,0x00,0x45, +0x00,0x00,0x88,0x21,0x92,0x02,0x00,0x04,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x3c, +0x00,0x00,0x00,0x00,0x12,0x20,0x00,0x18,0x00,0x00,0x00,0x00,0x92,0x02,0x00,0x16, +0x92,0x05,0x00,0x0a,0x30,0x42,0x00,0xfc,0x10,0xa0,0x00,0x03,0xa2,0x02,0x00,0x16, +0x34,0x42,0x00,0x01,0xa2,0x02,0x00,0x16,0x92,0x04,0x00,0x04,0x00,0x00,0x00,0x00, +0x30,0x83,0x00,0xff,0x10,0x60,0x00,0x05,0x00,0x00,0x00,0x00,0x92,0x02,0x00,0x16, +0x00,0x00,0x00,0x00,0x34,0x42,0x00,0x02,0xa2,0x02,0x00,0x16,0x10,0x60,0x00,0x0a, +0x00,0x00,0x00,0x00,0x14,0xa0,0x00,0x08,0x00,0x00,0x00,0x00,0x96,0x02,0x00,0x00, +0xa2,0x00,0x00,0x17,0xa6,0x02,0x00,0x14,0x8f,0xbf,0x00,0x18,0x7b,0xb0,0x00,0xbc, +0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x14,0x80,0x00,0x05,0x24,0x02,0x00,0x01, +0x96,0x03,0x00,0x06,0xa2,0x02,0x00,0x17,0x08,0x00,0x1e,0xbe,0xa6,0x03,0x00,0x14, +0x96,0x04,0x00,0x00,0x96,0x05,0x00,0x06,0x27,0x86,0x90,0x00,0x00,0x04,0x10,0xc0, +0x00,0x05,0x18,0xc0,0x00,0x44,0x10,0x21,0x00,0x65,0x18,0x21,0x00,0x02,0x10,0x80, +0x00,0x03,0x18,0x80,0x00,0x66,0x18,0x21,0x00,0x46,0x10,0x21,0x8c,0x65,0x00,0x08, +0x8c,0x44,0x00,0x08,0x0c,0x00,0x12,0x7c,0x00,0x00,0x00,0x00,0x30,0x43,0x00,0xff, +0x10,0x60,0x00,0x04,0xa2,0x02,0x00,0x17,0x96,0x02,0x00,0x06,0x08,0x00,0x1e,0xbe, +0xa6,0x02,0x00,0x14,0x96,0x02,0x00,0x00,0x08,0x00,0x1e,0xbe,0xa6,0x02,0x00,0x14, +0x96,0x05,0x00,0x00,0x0c,0x00,0x1e,0xea,0x02,0x00,0x20,0x21,0x08,0x00,0x1e,0xa5, +0x02,0x22,0x88,0x21,0x94,0x85,0x00,0x06,0x0c,0x00,0x1e,0xea,0x00,0x00,0x00,0x00, +0x08,0x00,0x1e,0xa1,0x00,0x40,0x88,0x21,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x00, +0x34,0x63,0x00,0x20,0x24,0x42,0x7b,0xa8,0x27,0xbd,0xff,0xf0,0xac,0x62,0x00,0x00, +0x00,0x00,0x10,0x21,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x10,0x3c,0x03,0xb0,0x03, +0x3c,0x02,0x80,0x00,0x34,0x63,0x00,0x20,0x24,0x42,0x7b,0xcc,0xac,0x62,0x00,0x00, +0x90,0x89,0x00,0x0a,0x00,0x80,0x30,0x21,0x11,0x20,0x00,0x05,0x00,0xa0,0x50,0x21, +0x90,0x82,0x00,0x17,0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x1b,0x00,0x00,0x00,0x00, +0x90,0xc7,0x00,0x04,0x00,0x00,0x00,0x00,0x10,0xe0,0x00,0x1b,0x00,0x00,0x00,0x00, +0x94,0xc8,0x00,0x00,0x27,0x83,0x90,0x00,0x93,0x85,0x8b,0x70,0x00,0x08,0x10,0xc0, +0x00,0x48,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x08, +0x00,0xe5,0x28,0x2b,0x10,0xa0,0x00,0x06,0x01,0x44,0x18,0x23,0x8f,0x82,0x8b,0x88, +0x00,0x00,0x00,0x00,0x00,0x43,0x10,0x2b,0x10,0x40,0x00,0x05,0x00,0x00,0x00,0x00, +0x24,0x03,0x00,0x10,0xa4,0xc8,0x00,0x14,0x03,0xe0,0x00,0x08,0x00,0x60,0x10,0x21, +0x11,0x20,0x00,0x05,0x00,0x00,0x00,0x00,0x94,0xc2,0x00,0x06,0x24,0x03,0x00,0x08, +0x08,0x00,0x1f,0x16,0xa4,0xc2,0x00,0x14,0x08,0x00,0x1f,0x16,0x00,0x00,0x18,0x21, +0x27,0xbd,0xff,0xc8,0xaf,0xb5,0x00,0x2c,0xaf,0xb4,0x00,0x28,0xaf,0xb3,0x00,0x24, +0xaf,0xb0,0x00,0x18,0xaf,0xbf,0x00,0x30,0xaf,0xb2,0x00,0x20,0xaf,0xb1,0x00,0x1c, +0x94,0x91,0x00,0x06,0x00,0x80,0xa0,0x21,0x3c,0x02,0x80,0x00,0x3c,0x04,0xb0,0x03, +0x00,0x11,0xa8,0xc0,0x34,0x84,0x00,0x20,0x24,0x42,0x7c,0x80,0x02,0xb1,0x48,0x21, +0xac,0x82,0x00,0x00,0x00,0x09,0x48,0x80,0x24,0x03,0x00,0x01,0x27,0x82,0x90,0x10, +0xa2,0x83,0x00,0x12,0x01,0x22,0x10,0x21,0x27,0x84,0x90,0x04,0x01,0x24,0x20,0x21, +0x80,0x48,0x00,0x06,0x8c,0x8a,0x00,0x18,0x27,0x83,0x90,0x20,0x01,0x23,0x48,0x21, +0x8d,0x24,0x00,0x00,0x25,0x08,0x00,0x02,0x8d,0x42,0x00,0x00,0x8d,0x49,0x00,0x04, +0x00,0x08,0x17,0xc2,0x8d,0x43,0x00,0x08,0x01,0x02,0x40,0x21,0x00,0x04,0x25,0xc2, +0x00,0x08,0x40,0x43,0x30,0x84,0x00,0x01,0x00,0x03,0x1f,0xc2,0x00,0x08,0x40,0x40, +0x00,0xe0,0x80,0x21,0x00,0x64,0x18,0x24,0x00,0x09,0x49,0x42,0x01,0x48,0x10,0x21, +0x00,0xa0,0x98,0x21,0x00,0xa0,0x20,0x21,0x00,0x40,0x38,0x21,0x02,0x00,0x28,0x21, +0x14,0x60,0x00,0x19,0x31,0x29,0x00,0x01,0x94,0x42,0x00,0x00,0x02,0xb1,0x88,0x21, +0x02,0x00,0x28,0x21,0x00,0x11,0x88,0x80,0x27,0x90,0x90,0x00,0x02,0x30,0x80,0x21, +0x96,0x03,0x00,0x06,0x30,0x52,0xff,0xff,0x02,0x60,0x20,0x21,0x00,0x60,0x30,0x21, +0xa6,0x83,0x00,0x1a,0x27,0x82,0x90,0x08,0x0c,0x00,0x08,0xe3,0x02,0x22,0x88,0x21, +0x00,0x52,0x10,0x21,0x96,0x03,0x00,0x06,0xa6,0x22,0x00,0x04,0x8f,0xbf,0x00,0x30, +0x7b,0xb4,0x01,0x7c,0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc,0x00,0x60,0x10,0x21, +0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x38,0xaf,0xa9,0x00,0x10,0x0c,0x00,0x09,0x0a, +0xaf,0xa0,0x00,0x14,0x08,0x00,0x1f,0x54,0x02,0xb1,0x88,0x21,0x27,0xbd,0xff,0xc0, +0xaf,0xbe,0x00,0x38,0xaf,0xb7,0x00,0x34,0xaf,0xb6,0x00,0x30,0xaf,0xb5,0x00,0x2c, +0xaf,0xb3,0x00,0x24,0xaf,0xb1,0x00,0x1c,0xaf,0xbf,0x00,0x3c,0xaf,0xb4,0x00,0x28, +0xaf,0xb2,0x00,0x20,0xaf,0xb0,0x00,0x18,0x94,0x90,0x00,0x00,0x3c,0x08,0xb0,0x03, +0x35,0x08,0x00,0x20,0x00,0x10,0x10,0xc0,0x00,0x50,0x18,0x21,0x00,0x40,0x88,0x21, +0x3c,0x02,0x80,0x00,0x00,0x03,0x48,0x80,0x24,0x42,0x7d,0xbc,0x00,0x80,0x98,0x21, +0x27,0x84,0x90,0x10,0x01,0x24,0x20,0x21,0x93,0xb7,0x00,0x53,0xad,0x02,0x00,0x00, +0x80,0x83,0x00,0x06,0x27,0x82,0x90,0x04,0x01,0x22,0x10,0x21,0x8c,0x44,0x00,0x18, +0x24,0x63,0x00,0x02,0x00,0x03,0x17,0xc2,0x8c,0x88,0x00,0x08,0x00,0x62,0x18,0x21, +0x00,0x03,0x18,0x43,0x00,0x03,0x18,0x40,0xaf,0xa7,0x00,0x4c,0x2c,0xa2,0x00,0x10, +0x00,0xa0,0xa8,0x21,0x00,0x83,0x50,0x21,0x00,0x08,0x47,0xc2,0x00,0xc0,0x58,0x21, +0x00,0x00,0xb0,0x21,0x8c,0x92,0x00,0x0c,0x14,0x40,0x00,0x13,0x00,0x00,0xf0,0x21, +0x92,0x67,0x00,0x04,0x24,0x14,0x00,0x01,0x12,0x87,0x00,0x10,0x02,0x30,0x10,0x21, +0x27,0x83,0x90,0x18,0x01,0x23,0x18,0x21,0x80,0x64,0x00,0x00,0x27,0x83,0xb5,0x70, +0x00,0x04,0x11,0x00,0x00,0x44,0x10,0x23,0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x23, +0x00,0x02,0x10,0x80,0x00,0x43,0x10,0x21,0x90,0x44,0x00,0x04,0x00,0x00,0x00,0x00, +0x10,0x80,0x00,0x23,0x00,0x00,0x00,0x00,0x02,0x30,0x10,0x21,0x00,0x02,0x80,0x80, +0x24,0x04,0x00,0x01,0x27,0x83,0x90,0x20,0xa2,0x64,0x00,0x12,0x02,0x03,0x18,0x21, +0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x15,0xc2,0x30,0x42,0x00,0x01, +0x01,0x02,0x10,0x24,0x14,0x40,0x00,0x0e,0x02,0xa0,0x20,0x21,0x27,0x82,0x90,0x00, +0x02,0x02,0x10,0x21,0x94,0x43,0x00,0x06,0x00,0x00,0x00,0x00,0xa6,0x63,0x00,0x1a, +0x94,0x42,0x00,0x06,0x7b,0xbe,0x01,0xfc,0x7b,0xb6,0x01,0xbc,0x7b,0xb4,0x01,0x7c, +0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x40, +0x8f,0xa5,0x00,0x4c,0x01,0x60,0x30,0x21,0x01,0x40,0x38,0x21,0xaf,0xa0,0x00,0x10, +0x0c,0x00,0x09,0x0a,0xaf,0xa0,0x00,0x14,0x08,0x00,0x1f,0xbb,0x00,0x00,0x00,0x00, +0x27,0x83,0x90,0x20,0x01,0x23,0x18,0x21,0x8c,0x62,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x02,0x15,0xc2,0x30,0x42,0x00,0x01,0x01,0x02,0x10,0x24,0x14,0x40,0x00,0xaf, +0x00,0xa0,0x20,0x21,0x32,0x4f,0x00,0x03,0x00,0x12,0x10,0x82,0x25,0xe3,0x00,0x0d, +0x30,0x45,0x00,0x07,0x00,0x74,0x78,0x04,0x10,0xa0,0x00,0x0e,0x00,0x00,0x90,0x21, +0x27,0x82,0x80,0x1c,0x00,0x15,0x18,0x40,0x00,0x62,0x18,0x21,0x94,0x64,0x00,0x00, +0x24,0xa2,0x00,0x06,0x00,0x54,0x10,0x04,0x00,0x44,0x00,0x1a,0x14,0x80,0x00,0x02, +0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x0d,0x00,0x00,0x10,0x12,0x24,0x42,0x00,0x20, +0x30,0x52,0xff,0xfc,0x02,0x30,0x10,0x21,0x27,0x83,0x90,0x10,0x00,0x02,0x10,0x80, +0x00,0x43,0x10,0x21,0x90,0x44,0x00,0x03,0x00,0x00,0x00,0x00,0x30,0x83,0x00,0xff, +0x2c,0x62,0x00,0x0c,0x14,0x40,0x00,0x04,0x2c,0x62,0x00,0x19,0x30,0x82,0x00,0x0f, +0x24,0x43,0x00,0x0c,0x2c,0x62,0x00,0x19,0x10,0x40,0x00,0x19,0x24,0x0e,0x00,0x20, +0x24,0x62,0xff,0xe9,0x2c,0x42,0x00,0x02,0x14,0x40,0x00,0x15,0x24,0x0e,0x00,0x10, +0x24,0x62,0xff,0xeb,0x2c,0x42,0x00,0x02,0x14,0x40,0x00,0x11,0x24,0x0e,0x00,0x08, +0x24,0x02,0x00,0x14,0x10,0x62,0x00,0x0e,0x24,0x0e,0x00,0x02,0x24,0x62,0xff,0xef, +0x2c,0x42,0x00,0x03,0x14,0x40,0x00,0x0a,0x24,0x0e,0x00,0x10,0x24,0x62,0xff,0xf1, +0x2c,0x42,0x00,0x02,0x14,0x40,0x00,0x06,0x24,0x0e,0x00,0x08,0x24,0x62,0xff,0xf3, +0x2c,0x42,0x00,0x02,0x24,0x0e,0x00,0x04,0x24,0x03,0x00,0x02,0x00,0x62,0x70,0x0a, +0x30,0xe2,0x00,0xff,0x00,0x00,0x48,0x21,0x00,0x00,0x68,0x21,0x10,0x40,0x00,0x6d, +0x00,0x00,0x58,0x21,0x3c,0x14,0x80,0xff,0x27,0x99,0x90,0x00,0x01,0xf2,0xc0,0x23, +0x36,0x94,0xff,0xff,0x01,0xc9,0x10,0x2a,0x14,0x40,0x00,0x64,0x24,0x03,0x00,0x04, +0x00,0x10,0x28,0xc0,0x00,0xb0,0x10,0x21,0x00,0x02,0x10,0x80,0x00,0x59,0x10,0x21, +0x94,0x56,0x00,0x06,0x00,0x00,0x00,0x00,0x32,0xcc,0x00,0x03,0x00,0x6c,0x10,0x23, +0x30,0x42,0x00,0x03,0x02,0xc2,0x10,0x21,0x24,0x42,0x00,0x04,0x30,0x51,0xff,0xff, +0x02,0x32,0x18,0x2b,0x10,0x60,0x00,0x4d,0x01,0xf1,0x10,0x23,0x02,0x51,0x10,0x23, +0x01,0x78,0x18,0x2b,0x10,0x60,0x00,0x34,0x30,0x44,0xff,0xff,0x29,0x22,0x00,0x40, +0x10,0x40,0x00,0x31,0x01,0x72,0x18,0x21,0x25,0x22,0x00,0x01,0x00,0x02,0x16,0x00, +0x00,0x02,0x4e,0x03,0x00,0xb0,0x10,0x21,0x00,0x02,0x30,0x80,0x27,0x82,0x90,0x04, +0x30,0x6b,0xff,0xff,0x00,0xc2,0x18,0x21,0x8c,0x67,0x00,0x18,0x00,0x04,0x25,0x40, +0x3c,0x03,0x7f,0x00,0x8c,0xe2,0x00,0x04,0x00,0x83,0x20,0x24,0x27,0x83,0x90,0x10, +0x00,0x54,0x10,0x24,0x00,0xc3,0x28,0x21,0x00,0x44,0x10,0x25,0xac,0xe2,0x00,0x04, +0x16,0xe0,0x00,0x02,0xa0,0xb5,0x00,0x00,0xa0,0xb5,0x00,0x03,0x27,0x84,0x90,0x20, +0x00,0xc4,0x18,0x21,0x8c,0x62,0x00,0x00,0x8c,0xe8,0x00,0x08,0x00,0x02,0x15,0xc2, +0x00,0x08,0x47,0xc2,0x30,0x42,0x00,0x01,0x01,0x02,0x10,0x24,0x10,0x40,0x00,0x0a, +0x00,0x00,0x00,0x00,0x80,0xa2,0x00,0x06,0x00,0x00,0x00,0x00,0x24,0x42,0x00,0x02, +0x00,0x02,0x1f,0xc2,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x43,0x00,0x02,0x10,0x40, +0x00,0xe2,0x50,0x21,0xa5,0x5e,0x00,0x00,0x92,0x62,0x00,0x04,0x25,0xad,0x00,0x01, +0x27,0x84,0x90,0x00,0x00,0xc4,0x18,0x21,0x01,0xa2,0x10,0x2a,0x94,0x70,0x00,0x02, +0x14,0x40,0xff,0xb8,0x00,0x00,0x00,0x00,0x96,0x63,0x00,0x14,0x00,0x0c,0x10,0x23, +0xa2,0x69,0x00,0x12,0x30,0x42,0x00,0x03,0x01,0x62,0x10,0x23,0x00,0x03,0x80,0xc0, +0x8f,0xa5,0x00,0x4c,0x30,0x4b,0xff,0xff,0x02,0x03,0x80,0x21,0x27,0x82,0x90,0x08, +0x00,0x10,0x80,0x80,0xa6,0x6b,0x00,0x1a,0x02,0xa0,0x20,0x21,0x01,0x60,0x30,0x21, +0x01,0x60,0x88,0x21,0x0c,0x00,0x08,0xe3,0x02,0x02,0x80,0x21,0x00,0x5e,0x10,0x21, +0xa6,0x02,0x00,0x04,0x08,0x00,0x1f,0xc1,0x02,0x20,0x10,0x21,0x01,0x62,0x10,0x2b, +0x10,0x40,0xff,0xe9,0x00,0x00,0x20,0x21,0x29,0x22,0x00,0x40,0x10,0x40,0xff,0xe6, +0x01,0x71,0x18,0x21,0x08,0x00,0x20,0x37,0x25,0x22,0x00,0x01,0x08,0x00,0x20,0x66, +0x32,0xcc,0x00,0x03,0x08,0x00,0x20,0x66,0x00,0x00,0x60,0x21,0x8f,0xa5,0x00,0x4c, +0x01,0x40,0x38,0x21,0xaf,0xa0,0x00,0x10,0x0c,0x00,0x09,0x0a,0xaf,0xb4,0x00,0x14, +0x92,0x67,0x00,0x04,0x08,0x00,0x1f,0xd9,0x30,0x5e,0xff,0xff,0x30,0x84,0xff,0xff, +0x00,0x04,0x30,0xc0,0x00,0xc4,0x20,0x21,0x00,0x04,0x20,0x80,0x27,0x82,0x90,0x00, +0x3c,0x03,0xb0,0x08,0x30,0xa5,0xff,0xff,0x00,0x82,0x20,0x21,0x00,0xc3,0x30,0x21, +0xac,0xc5,0x00,0x00,0x03,0xe0,0x00,0x08,0xa4,0x85,0x00,0x00,0x30,0x84,0xff,0xff, +0x00,0x04,0x30,0xc0,0x00,0xc4,0x30,0x21,0x27,0x88,0x90,0x00,0x00,0x06,0x30,0x80, +0x00,0xc8,0x30,0x21,0x94,0xc3,0x00,0x04,0x3c,0x02,0xb0,0x08,0x3c,0x07,0xb0,0x03, +0x00,0x03,0x20,0xc0,0x00,0x83,0x18,0x21,0x00,0x03,0x18,0x80,0x00,0x82,0x20,0x21, +0x3c,0x02,0x80,0x01,0x30,0xa5,0xff,0xff,0x00,0x68,0x18,0x21,0x34,0xe7,0x00,0x20, +0x24,0x42,0x82,0x6c,0xac,0xe2,0x00,0x00,0xa4,0xc5,0x00,0x02,0xa4,0x65,0x00,0x00, +0x03,0xe0,0x00,0x08,0xac,0x85,0x00,0x00,0x30,0x84,0xff,0xff,0x00,0x04,0x10,0xc0, +0x00,0x44,0x10,0x21,0x27,0x89,0x90,0x00,0x00,0x02,0x10,0x80,0x00,0x49,0x10,0x21, +0x97,0x83,0x8f,0xf0,0x94,0x4a,0x00,0x04,0x3c,0x02,0xb0,0x08,0x00,0x03,0x38,0xc0, +0x00,0x0a,0x40,0xc0,0x00,0xe3,0x18,0x21,0x01,0x0a,0x28,0x21,0x00,0xe2,0x38,0x21, +0x01,0x02,0x40,0x21,0x00,0x03,0x18,0x80,0x00,0x05,0x28,0x80,0x3c,0x06,0xb0,0x03, +0x3c,0x02,0x80,0x01,0x00,0xa9,0x28,0x21,0x00,0x69,0x18,0x21,0x34,0xc6,0x00,0x20, +0x34,0x09,0xff,0xff,0x24,0x42,0x82,0xc8,0xac,0xc2,0x00,0x00,0xa4,0x64,0x00,0x00, +0xac,0xe4,0x00,0x00,0xa4,0xa9,0x00,0x00,0xad,0x09,0x00,0x00,0xa7,0x8a,0x8f,0xf0, +0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x01, +0x34,0x63,0x00,0x20,0x24,0x42,0x83,0x48,0x3c,0x04,0xb0,0x03,0xac,0x62,0x00,0x00, +0x34,0x84,0x01,0x10,0x8c,0x82,0x00,0x00,0x97,0x83,0x81,0x60,0x30,0x42,0xff,0xff, +0x10,0x62,0x00,0x16,0x24,0x0a,0x00,0x01,0xa7,0x82,0x81,0x60,0xaf,0x80,0xb4,0x50, +0x00,0x40,0x28,0x21,0x24,0x06,0x00,0x01,0x27,0x84,0xb4,0x54,0x25,0x43,0xff,0xff, +0x00,0x66,0x10,0x04,0x00,0xa2,0x10,0x24,0x14,0x40,0x00,0x07,0x00,0x00,0x00,0x00, +0x8c,0x83,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x66,0x10,0x04,0x00,0xa2,0x10,0x24, +0x38,0x42,0x00,0x00,0x01,0x42,0x18,0x0a,0x25,0x4a,0x00,0x01,0x2d,0x42,0x00,0x14, +0xac,0x83,0x00,0x00,0x14,0x40,0xff,0xf1,0x24,0x84,0x00,0x04,0x3c,0x0b,0xb0,0x03, +0x00,0x00,0x50,0x21,0x3c,0x0c,0x80,0x00,0x27,0x89,0xb4,0xa0,0x35,0x6b,0x01,0x20, +0x8d,0x68,0x00,0x00,0x8d,0x23,0x00,0x04,0x01,0x0c,0x10,0x24,0x00,0x02,0x17,0xc2, +0x11,0x03,0x00,0x37,0xa1,0x22,0x00,0xdc,0xa1,0x20,0x00,0xd5,0xa1,0x20,0x00,0xd6, +0x01,0x20,0x30,0x21,0x00,0x00,0x38,0x21,0x00,0x00,0x28,0x21,0x01,0x20,0x20,0x21, +0x00,0xa8,0x10,0x06,0x30,0x42,0x00,0x01,0x10,0xe0,0x00,0x10,0xa0,0x82,0x00,0x0a, +0x90,0x82,0x00,0x07,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x31,0x24,0xa2,0xff,0xff, +0xa0,0x82,0x00,0x08,0x90,0x82,0x00,0x0a,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x09, +0x00,0x00,0x00,0x00,0x90,0x83,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x03,0x10,0x40, +0x00,0x43,0x10,0x21,0x00,0x46,0x10,0x21,0xa0,0x45,0x00,0x09,0x90,0x82,0x00,0x0a, +0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x07,0x00,0x00,0x00,0x00,0x14,0xe0,0x00,0x04, +0x00,0x00,0x00,0x00,0xa0,0xc5,0x00,0xd5,0x24,0x07,0x00,0x01,0xa0,0x85,0x00,0x08, +0xa0,0xc5,0x00,0xd6,0x24,0xa5,0x00,0x01,0x2c,0xa2,0x00,0x1c,0x14,0x40,0xff,0xe0, +0x24,0x84,0x00,0x03,0x90,0xc4,0x00,0xd5,0x00,0x00,0x28,0x21,0x00,0xa4,0x10,0x2b, +0x10,0x40,0x00,0x0b,0x00,0x00,0x00,0x00,0x00,0xc0,0x18,0x21,0xa0,0x64,0x00,0x08, +0x90,0xc2,0x00,0xd5,0x24,0xa5,0x00,0x01,0xa0,0x62,0x00,0x09,0x90,0xc4,0x00,0xd5, +0x00,0x00,0x00,0x00,0x00,0xa4,0x10,0x2b,0x14,0x40,0xff,0xf8,0x24,0x63,0x00,0x03, +0x25,0x4a,0x00,0x01,0x2d,0x42,0x00,0x08,0xad,0x28,0x00,0x04,0x25,0x6b,0x00,0x04, +0x14,0x40,0xff,0xbf,0x25,0x29,0x00,0xec,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00, +0x90,0x82,0x00,0x05,0x08,0x00,0x21,0x0d,0xa0,0x82,0x00,0x08,0x97,0x85,0x8b,0x7a, +0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x01,0x27,0xbd,0xff,0xe8,0x34,0x63,0x00,0x20, +0x24,0x42,0x84,0xfc,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,0xac,0x62,0x00,0x00, +0x30,0x90,0x00,0xff,0x00,0x05,0x28,0x42,0x00,0x00,0x48,0x21,0x27,0x8f,0xb4,0xa4, +0x00,0x00,0x50,0x21,0x00,0x00,0x58,0x21,0x27,0x98,0xb5,0x84,0x27,0x99,0xb5,0x80, +0x27,0x8e,0xb5,0x7e,0x27,0x8c,0xb4,0xa8,0x27,0x8d,0xb5,0x00,0x27,0x88,0xb5,0x78, +0x00,0x0a,0x18,0x80,0x01,0x6f,0x10,0x21,0xac,0x40,0x00,0x00,0xac,0x45,0x00,0x58, +0x00,0x6e,0x20,0x21,0x00,0x78,0x10,0x21,0xa1,0x00,0xff,0xfc,0xad,0x00,0x00,0x00, +0xa1,0x00,0x00,0x04,0xa1,0x00,0x00,0x05,0xad,0x00,0xff,0xf8,0x00,0x79,0x18,0x21, +0x24,0x06,0x00,0x01,0x24,0xc6,0xff,0xff,0xa0,0x80,0x00,0x00,0xa4,0x60,0x00,0x00, +0xac,0x40,0x00,0x00,0x24,0x63,0x00,0x02,0x24,0x42,0x00,0x04,0x04,0xc1,0xff,0xf9, +0x24,0x84,0x00,0x01,0x00,0x0a,0x10,0x80,0x00,0x4d,0x20,0x21,0x00,0x00,0x30,0x21, +0x00,0x4c,0x18,0x21,0x27,0x87,0x81,0x64,0x8c,0xe2,0x00,0x00,0x24,0xe7,0x00,0x04, +0xac,0x82,0x00,0x00,0xa0,0x66,0x00,0x00,0xa0,0x66,0x00,0x01,0x24,0xc6,0x00,0x01, +0x28,0xc2,0x00,0x1c,0xa0,0x60,0x00,0x02,0x24,0x84,0x00,0x04,0x14,0x40,0xff,0xf6, +0x24,0x63,0x00,0x03,0x25,0x29,0x00,0x01,0x29,0x22,0x00,0x08,0x25,0x4a,0x00,0x3b, +0x25,0x08,0x00,0xec,0x14,0x40,0xff,0xd6,0x25,0x6b,0x00,0xec,0xa7,0x80,0x81,0x60, +0x00,0x00,0x48,0x21,0x27,0x83,0xb4,0x50,0xac,0x69,0x00,0x00,0x25,0x29,0x00,0x01, +0x29,0x22,0x00,0x0c,0x14,0x40,0xff,0xfc,0x24,0x63,0x00,0x04,0x0c,0x00,0x20,0xd2, +0x00,0x00,0x00,0x00,0x2e,0x04,0x00,0x14,0x27,0x83,0xb4,0xa0,0x24,0x09,0x00,0x07, +0x10,0x80,0x00,0x0a,0x00,0x00,0x00,0x00,0x90,0x62,0x00,0xd5,0x25,0x29,0xff,0xff, +0xa0,0x62,0x00,0x00,0x05,0x21,0xff,0xfa,0x24,0x63,0x00,0xec,0x8f,0xbf,0x00,0x14, +0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x90,0x62,0x00,0xd6, +0x08,0x00,0x21,0x90,0x25,0x29,0xff,0xff,0x30,0x84,0x00,0xff,0x00,0x04,0x11,0x00, +0x00,0x44,0x10,0x23,0x00,0x02,0x10,0x80,0x00,0x44,0x10,0x23,0x00,0x02,0x10,0x80, +0x27,0x83,0xb4,0xa0,0x00,0x43,0x60,0x21,0x3c,0x04,0xb0,0x03,0x3c,0x02,0x80,0x01, +0x34,0x84,0x00,0x20,0x24,0x42,0x86,0x68,0x30,0xc6,0x00,0xff,0x93,0xaa,0x00,0x13, +0x30,0xa5,0x00,0xff,0x30,0xe7,0x00,0xff,0xac,0x82,0x00,0x00,0x10,0xc0,0x00,0xe8, +0x25,0x8f,0x00,0xd0,0x91,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x24,0x42,0xff,0xfc, +0x2c,0x43,0x00,0x18,0x10,0x60,0x00,0xc7,0x3c,0x03,0x80,0x01,0x00,0x02,0x10,0x80, +0x24,0x63,0x02,0x90,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x80,0x00,0x08,0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x30,0x14,0x40,0x00,0x1c, +0x00,0x00,0x00,0x00,0x10,0xa0,0x00,0x17,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01, +0x10,0xa2,0x00,0x11,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x0c, +0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x03,0x10,0xa2,0x00,0x06,0x00,0x00,0x00,0x00, +0x8d,0x82,0x00,0xd0,0x00,0x00,0x00,0x00,0x24,0x42,0xff,0xe0,0x03,0xe0,0x00,0x08, +0xad,0x82,0x00,0xd0,0x8d,0x82,0x00,0xd0,0x08,0x00,0x21,0xcb,0x24,0x42,0xff,0xe8, +0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,0x08,0x00,0x21,0xcb, +0x24,0x42,0x00,0x01,0x8d,0x82,0x00,0xd0,0x08,0x00,0x21,0xcb,0x24,0x42,0x00,0x02, +0x10,0xa0,0xff,0xf9,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0x00,0x0a, +0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xe9,0x00,0x00,0x00,0x00, +0x24,0x02,0x00,0x03,0x10,0xa2,0xff,0xe6,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0, +0x08,0x00,0x21,0xcb,0x24,0x42,0xff,0xd0,0x8d,0x82,0x00,0xd0,0x08,0x00,0x21,0xcb, +0x24,0x42,0xff,0xfc,0x10,0xa0,0xff,0xeb,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01, +0x10,0xa2,0xff,0xe5,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xe0, +0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0xdb,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0, +0x08,0x00,0x21,0xcb,0x24,0x42,0xff,0xf8,0x2d,0x42,0x00,0x19,0x14,0x40,0xff,0xc5, +0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xdb,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01, +0x10,0xa2,0xff,0xd5,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xd0, +0x24,0x02,0x00,0x03,0x10,0xa2,0xff,0xf1,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0, +0x08,0x00,0x21,0xcb,0x24,0x42,0xff,0xf0,0x2d,0x42,0x00,0x1b,0x10,0x40,0xff,0xf1, +0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xcb,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01, +0x10,0xa2,0xff,0xc5,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x14,0xa2,0xff,0xb5, +0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,0x08,0x00,0x21,0xcb,0x24,0x42,0xff,0xf4, +0x2d,0x42,0x00,0x1e,0x10,0x40,0xff,0xe3,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xbd, +0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xb5,0x24,0x02,0x00,0x02, +0x10,0xa2,0xff,0xd6,0x00,0x00,0x00,0x00,0x08,0x00,0x21,0xc6,0x24,0x02,0x00,0x03, +0x2d,0x42,0x00,0x23,0x10,0x40,0xff,0xd7,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xae, +0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xa9,0x24,0x02,0x00,0x02, +0x14,0xa2,0xff,0xb7,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0x03,0x00,0x00,0x00,0x00, +0x2d,0x42,0x00,0x25,0x10,0x40,0xff,0xcb,0x00,0x00,0x00,0x00,0x08,0x00,0x21,0xd8, +0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x16,0x14,0x40,0x00,0x0e,0x00,0x00,0x00,0x00, +0x10,0xa0,0xff,0xa0,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x9a, +0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x95,0x24,0x02,0x00,0x03, +0x14,0xa2,0xff,0xb6,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,0x08,0x00,0x21,0xcb, +0x24,0x42,0xff,0xfa,0x10,0xa0,0xff,0x93,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01, +0x10,0xa2,0xff,0x8d,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x88, +0x00,0x00,0x00,0x00,0x08,0x00,0x21,0xf3,0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x17, +0x14,0x40,0xff,0xac,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0x34,0x00,0x00,0x00,0x00, +0x2d,0x42,0x00,0x19,0x10,0x40,0xff,0xe2,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0x81, +0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x7b,0x00,0x00,0x00,0x00, +0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x76,0x24,0x02,0x00,0x03,0x10,0xa2,0xff,0x97, +0x00,0x00,0x00,0x00,0x08,0x00,0x21,0xc8,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0x51, +0x2d,0x42,0x00,0x1b,0x2d,0x42,0x00,0x1e,0x10,0x40,0xff,0xde,0x00,0x00,0x00,0x00, +0x10,0xa0,0xff,0x70,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x6a, +0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x65,0x24,0x02,0x00,0x03, +0x10,0xa2,0xff,0x96,0x00,0x00,0x00,0x00,0x08,0x00,0x21,0xc8,0x00,0x00,0x00,0x00, +0x2d,0x42,0x00,0x23,0x14,0x40,0xff,0xf2,0x00,0x00,0x00,0x00,0x08,0x00,0x21,0xf9, +0x00,0x00,0x00,0x00,0x08,0x00,0x21,0xf7,0x2d,0x42,0x00,0x25,0x08,0x00,0x22,0x2d, +0x2d,0x42,0x00,0x27,0x10,0xa0,0xff,0x5b,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01, +0x10,0xa2,0xff,0x55,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x50, +0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0x71,0x00,0x00,0x00,0x00,0x08,0x00,0x21,0xe6, +0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x27,0x14,0x40,0xff,0xad,0x00,0x00,0x00,0x00, +0x08,0x00,0x22,0x79,0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x2a,0x14,0x40,0xff,0xd8, +0x00,0x00,0x00,0x00,0x08,0x00,0x21,0xe9,0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x2c, +0x14,0x40,0xff,0x78,0x00,0x00,0x00,0x00,0x08,0x00,0x21,0xbd,0x00,0x00,0x00,0x00, +0x91,0x86,0x00,0x00,0x91,0x83,0x00,0xd4,0x25,0x8d,0x00,0x5c,0x30,0xc4,0x00,0xff, +0x00,0x04,0x10,0x40,0x00,0x44,0x10,0x21,0x00,0x04,0x48,0x80,0x01,0x82,0x58,0x21, +0x01,0x89,0x40,0x21,0x25,0x78,0x00,0x08,0x10,0x60,0x00,0x37,0x25,0x0e,0x00,0x60, +0x2c,0xa2,0x00,0x03,0x14,0x40,0x00,0x25,0x00,0x00,0x00,0x00,0x91,0x82,0x00,0xdd, +0x00,0x00,0x00,0x00,0x14,0x40,0x00,0x1e,0x00,0x00,0x00,0x00,0x27,0x87,0x81,0x64, +0x01,0x27,0x10,0x21,0x8c,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0xad,0x03,0x00,0x60, +0x91,0x62,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x40,0x30,0x21,0xa1,0x82,0x00,0x00, +0x30,0xc2,0x00,0xff,0x00,0x02,0x10,0x80,0x00,0x47,0x10,0x21,0x8c,0x43,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x03,0x18,0x42,0xad,0xa3,0x00,0x00,0x91,0x84,0x00,0x00, +0x8d,0xc5,0x00,0x00,0x00,0x04,0x20,0x80,0x00,0x87,0x10,0x21,0x8c,0x43,0x00,0x00, +0x00,0x05,0x28,0x40,0x00,0x8c,0x20,0x21,0x00,0x03,0x18,0x80,0x00,0xa3,0x10,0x2b, +0x00,0x62,0x28,0x0a,0xac,0x85,0x00,0x60,0x03,0xe0,0x00,0x08,0xa1,0x80,0x00,0xd4, +0x27,0x87,0x81,0x64,0x08,0x00,0x22,0xb0,0xa1,0x80,0x00,0xdd,0x27,0x82,0x81,0xd4, +0x8d,0x83,0x00,0xd8,0x00,0x82,0x10,0x21,0x90,0x44,0x00,0x00,0x24,0x63,0x00,0x01, +0x00,0x64,0x20,0x2b,0x14,0x80,0xff,0x02,0xad,0x83,0x00,0xd8,0x8d,0x02,0x00,0x60, +0xa1,0x80,0x00,0xd4,0x00,0x02,0x1f,0xc2,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x43, +0x03,0xe0,0x00,0x08,0xad,0x82,0x00,0x5c,0x10,0xe0,0x00,0x1d,0x24,0x83,0xff,0xfc, +0x2c,0x62,0x00,0x18,0x10,0x40,0x01,0x10,0x00,0x03,0x10,0x80,0x3c,0x03,0x80,0x01, +0x24,0x63,0x02,0xf0,0x00,0x43,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x80,0x00,0x08,0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x30,0x14,0x40,0x00,0x65, +0x00,0x00,0x00,0x00,0x10,0xa0,0x00,0x60,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01, +0x10,0xa2,0x00,0x5a,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x08, +0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x03,0x10,0xa2,0x00,0x51,0x00,0x00,0x00,0x00, +0x8d,0x82,0x00,0xd0,0x00,0x00,0x00,0x00,0x24,0x42,0xff,0xe0,0xad,0x82,0x00,0xd0, +0x8d,0xe3,0x00,0x00,0x8d,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x43,0x10,0x21, +0xad,0xa2,0x00,0x00,0xad,0xe0,0x00,0x00,0x8d,0xa3,0x00,0x00,0x8d,0xc4,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x83,0x10,0x2a,0x10,0x40,0x00,0x22,0x00,0x00,0x00,0x00, +0x93,0x05,0x00,0x01,0x91,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x45,0x00,0x05, +0x24,0x02,0x00,0x01,0xa1,0x85,0x00,0x00,0xa1,0x82,0x00,0xd4,0x03,0xe0,0x00,0x08, +0xad,0x80,0x00,0xd8,0x91,0x82,0x00,0xdd,0x24,0x03,0x00,0x01,0x10,0x43,0x00,0x05, +0x00,0x00,0x00,0x00,0xa1,0x83,0x00,0xd4,0xad,0x80,0x00,0xd8,0x03,0xe0,0x00,0x08, +0xa1,0x83,0x00,0xdd,0x00,0x04,0x17,0xc2,0x00,0x82,0x10,0x21,0x00,0x02,0x10,0x43, +0xad,0xa2,0x00,0x00,0x91,0x83,0x00,0x00,0x27,0x82,0x81,0x64,0x8d,0xc5,0x00,0x00, +0x00,0x03,0x18,0x80,0x00,0x62,0x18,0x21,0x8c,0x64,0x00,0x00,0x00,0x05,0x28,0x40, +0x00,0x04,0x18,0x80,0x00,0xa3,0x10,0x2b,0x00,0x62,0x28,0x0a,0x08,0x00,0x22,0xc2, +0xad,0xc5,0x00,0x00,0x97,0x82,0x8b,0x7c,0x00,0x00,0x00,0x00,0x00,0x62,0x10,0x2a, +0x10,0x40,0xfe,0xab,0x00,0x00,0x00,0x00,0x91,0x82,0x00,0xdd,0x00,0x00,0x00,0x00, +0x14,0x40,0x00,0x15,0x00,0x00,0x00,0x00,0x91,0x83,0x00,0x00,0x27,0x82,0x81,0x64, +0x00,0x03,0x18,0x80,0x00,0x62,0x10,0x21,0x8c,0x44,0x00,0x00,0x00,0x6c,0x18,0x21, +0xac,0x64,0x00,0x60,0x93,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x10,0x80, +0x01,0x82,0x10,0x21,0x24,0x4e,0x00,0x60,0xa1,0x85,0x00,0x00,0x8d,0xc2,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x02,0x1f,0xc2,0x00,0x43,0x10,0x21,0x00,0x02,0x10,0x43, +0x03,0xe0,0x00,0x08,0xad,0xa2,0x00,0x00,0x08,0x00,0x23,0x37,0xa1,0x80,0x00,0xdd, +0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0xf3,0x24,0x42,0xff,0xe8,0x8d,0x82,0x00,0xd0, +0x08,0x00,0x22,0xf3,0x24,0x42,0x00,0x01,0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0xf3, +0x24,0x42,0x00,0x02,0x10,0xa0,0xff,0xf9,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01, +0x10,0xa2,0x00,0x0a,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xa0, +0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x03,0x10,0xa2,0xff,0x9d,0x00,0x00,0x00,0x00, +0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0xf3,0x24,0x42,0xff,0xd0,0x8d,0x82,0x00,0xd0, +0x08,0x00,0x22,0xf3,0x24,0x42,0xff,0xfc,0x10,0xa0,0xff,0xeb,0x00,0x00,0x00,0x00, +0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xe5,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02, +0x10,0xa2,0xff,0x93,0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0xdd,0x00,0x00,0x00,0x00, +0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0xf3,0x24,0x42,0xff,0xf8,0x2d,0x42,0x00,0x19, +0x14,0x40,0xff,0x7c,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xdb,0x00,0x00,0x00,0x00, +0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xd5,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02, +0x10,0xa2,0xff,0x83,0x24,0x02,0x00,0x03,0x10,0xa2,0xff,0xf1,0x00,0x00,0x00,0x00, +0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0xf3,0x24,0x42,0xff,0xf0,0x2d,0x42,0x00,0x1b, +0x10,0x40,0xff,0xf1,0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xcb,0x00,0x00,0x00,0x00, +0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0xc5,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02, +0x14,0xa2,0xff,0x6c,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0,0x08,0x00,0x22,0xf3, +0x24,0x42,0xff,0xf4,0x2d,0x42,0x00,0x1e,0x10,0x40,0xff,0xe3,0x00,0x00,0x00,0x00, +0x10,0xa0,0xff,0xbd,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x68, +0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0xd6,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0xee, +0x24,0x02,0x00,0x03,0x2d,0x42,0x00,0x23,0x10,0x40,0xff,0xd7,0x00,0x00,0x00,0x00, +0x10,0xa0,0xff,0xae,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x5c, +0x24,0x02,0x00,0x02,0x14,0xa2,0xff,0xb7,0x00,0x00,0x00,0x00,0x08,0x00,0x23,0x74, +0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x25,0x10,0x40,0xff,0xcb,0x00,0x00,0x00,0x00, +0x08,0x00,0x23,0x49,0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x16,0x14,0x40,0x00,0x0e, +0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0xa0,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01, +0x10,0xa2,0xff,0x9a,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x48, +0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0xb6,0x00,0x00,0x00,0x00,0x8d,0x82,0x00,0xd0, +0x08,0x00,0x22,0xf3,0x24,0x42,0xff,0xfa,0x10,0xa0,0xff,0x93,0x00,0x00,0x00,0x00, +0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x8d,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02, +0x10,0xa2,0xff,0x3b,0x00,0x00,0x00,0x00,0x08,0x00,0x23,0x64,0x00,0x00,0x00,0x00, +0x2d,0x42,0x00,0x17,0x14,0x40,0xff,0xac,0x00,0x00,0x00,0x00,0x08,0x00,0x23,0xa5, +0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x19,0x10,0x40,0xff,0xe2,0x00,0x00,0x00,0x00, +0x10,0xa0,0xff,0x81,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x7b, +0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x29,0x24,0x02,0x00,0x03, +0x10,0xa2,0xff,0x97,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0xf0,0x00,0x00,0x00,0x00, +0x08,0x00,0x23,0xc2,0x2d,0x42,0x00,0x1b,0x2d,0x42,0x00,0x1e,0x10,0x40,0xff,0xde, +0x00,0x00,0x00,0x00,0x10,0xa0,0xff,0x70,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01, +0x10,0xa2,0xff,0x6a,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0xa2,0xff,0x18, +0x24,0x02,0x00,0x03,0x10,0xa2,0xff,0x96,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0xf0, +0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x23,0x14,0x40,0xff,0xf2,0x00,0x00,0x00,0x00, +0x08,0x00,0x23,0x6a,0x00,0x00,0x00,0x00,0x08,0x00,0x23,0x68,0x2d,0x42,0x00,0x25, +0x08,0x00,0x23,0x9e,0x2d,0x42,0x00,0x27,0x10,0xa0,0xff,0x5b,0x00,0x00,0x00,0x00, +0x24,0x02,0x00,0x01,0x10,0xa2,0xff,0x55,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02, +0x10,0xa2,0xff,0x03,0x24,0x02,0x00,0x03,0x14,0xa2,0xff,0x71,0x00,0x00,0x00,0x00, +0x08,0x00,0x23,0x57,0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x27,0x14,0x40,0xff,0xad, +0x00,0x00,0x00,0x00,0x08,0x00,0x23,0xea,0x00,0x00,0x00,0x00,0x2d,0x42,0x00,0x2a, +0x14,0x40,0xff,0xd8,0x00,0x00,0x00,0x00,0x08,0x00,0x23,0x5a,0x00,0x00,0x00,0x00, +0x2d,0x42,0x00,0x2c,0x14,0x40,0xff,0x78,0x00,0x00,0x00,0x00,0x08,0x00,0x22,0xe5, +0x00,0x00,0x00,0x00,0x27,0xbd,0xff,0xe8,0x3c,0x02,0xb0,0x03,0xaf,0xbf,0x00,0x14, +0xaf,0xb0,0x00,0x10,0x34,0x42,0x01,0x18,0x3c,0x03,0xb0,0x03,0x8c,0x50,0x00,0x00, +0x34,0x63,0x01,0x2c,0x90,0x62,0x00,0x00,0x32,0x05,0x00,0x01,0xa3,0x82,0x80,0x10, +0x14,0xa0,0x00,0x14,0x30,0x44,0x00,0xff,0x32,0x02,0x01,0x00,0x14,0x40,0x00,0x09, +0x00,0x00,0x00,0x00,0x32,0x02,0x08,0x00,0x10,0x40,0x00,0x02,0x24,0x02,0x00,0x01, +0xa3,0x82,0xbc,0x18,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x18,0x0c,0x00,0x05,0x37,0x00,0x00,0x00,0x00,0x26,0x02,0xff,0x00, +0xa3,0x80,0xbc,0x18,0x3c,0x01,0xb0,0x03,0xac,0x22,0x01,0x18,0x08,0x00,0x24,0x16, +0x32,0x02,0x08,0x00,0x0c,0x00,0x21,0x3f,0x00,0x00,0x00,0x00,0x26,0x02,0xff,0xff, +0x3c,0x01,0xb0,0x03,0xac,0x22,0x01,0x18,0x08,0x00,0x24,0x13,0x32,0x02,0x01,0x00, +0x27,0xbd,0xff,0xe0,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0xd0,0xaf,0xbf,0x00,0x18, +0x8c,0x43,0x00,0x00,0x3c,0x02,0x00,0x40,0x24,0x07,0x0f,0xff,0x00,0x03,0x33,0x02, +0x00,0x03,0x2d,0x02,0x00,0x03,0x43,0x02,0x30,0x69,0x0f,0xff,0x00,0x62,0x18,0x24, +0x30,0xa5,0x00,0x03,0x30,0xc6,0x00,0xff,0x10,0x60,0x00,0x08,0x31,0x08,0x00,0xff, +0x01,0x00,0x30,0x21,0x0c,0x00,0x24,0xdf,0xaf,0xa9,0x00,0x10,0x8f,0xbf,0x00,0x18, +0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x0c,0x00,0x25,0x31, +0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0xd4,0x08,0x00,0x24,0x3f, +0xac,0x62,0x00,0x00,0x27,0xbd,0xff,0xc0,0x3c,0x02,0xb0,0x03,0xaf,0xbe,0x00,0x38, +0xaf,0xb5,0x00,0x2c,0xaf,0xb1,0x00,0x1c,0xaf,0xb0,0x00,0x18,0xaf,0xbf,0x00,0x3c, +0xaf,0xb7,0x00,0x34,0xaf,0xb6,0x00,0x30,0xaf,0xb4,0x00,0x28,0xaf,0xb3,0x00,0x24, +0xaf,0xb2,0x00,0x20,0x34,0x42,0x00,0x3f,0x90,0x43,0x00,0x00,0x00,0x80,0x80,0x21, +0x00,0x00,0xf0,0x21,0x00,0x00,0x88,0x21,0x10,0x60,0x00,0x76,0x00,0x00,0xa8,0x21, +0x3c,0x01,0xb0,0x03,0xa0,0x20,0x00,0x3f,0x00,0x10,0x12,0x02,0x24,0x04,0x06,0x14, +0x0c,0x00,0x06,0xd1,0x30,0x54,0x00,0x0f,0x24,0x04,0x06,0x14,0x0c,0x00,0x06,0xd1, +0xaf,0xa2,0x00,0x10,0x3c,0x03,0x00,0xff,0x34,0x63,0xff,0xff,0x32,0x10,0x00,0x7f, +0x00,0x43,0x10,0x24,0x00,0x10,0x86,0x00,0x02,0x02,0x80,0x25,0x02,0x00,0x28,0x21, +0x24,0x04,0x06,0x14,0x3c,0x13,0xbf,0xff,0x0c,0x00,0x06,0xbf,0x3c,0x16,0xb0,0x03, +0x00,0x00,0x90,0x21,0x3c,0x17,0x40,0x00,0x36,0x73,0xff,0xff,0x36,0xd6,0x00,0x3e, +0x0c,0x00,0x06,0xd1,0x24,0x04,0x04,0x00,0x00,0x57,0x10,0x25,0x00,0x40,0x28,0x21, +0x0c,0x00,0x06,0xbf,0x24,0x04,0x04,0x00,0x00,0x00,0x80,0x21,0x0c,0x00,0x25,0xf9, +0x00,0x00,0x00,0x00,0x26,0x03,0x00,0x01,0x10,0x40,0x00,0x46,0x30,0x70,0x00,0xff, +0x12,0x00,0xff,0xfa,0x00,0x00,0x00,0x00,0x0c,0x00,0x06,0xd1,0x24,0x04,0x04,0x00, +0x00,0x53,0x10,0x24,0x00,0x40,0x28,0x21,0x0c,0x00,0x06,0xbf,0x24,0x04,0x04,0x00, +0x24,0x02,0x00,0x01,0x12,0x82,0x00,0x37,0x00,0x00,0x00,0x00,0x12,0x80,0x00,0x35, +0x00,0x00,0x00,0x00,0x32,0x31,0x00,0x7f,0x12,0x20,0x00,0x04,0x24,0x03,0x00,0x04, +0x27,0xc2,0x00,0x01,0x30,0x5e,0x00,0xff,0x02,0xb1,0xa8,0x21,0x12,0x43,0x00,0x2a, +0x3c,0x03,0xb0,0x03,0x02,0x43,0x10,0x21,0xa0,0x51,0x00,0x34,0x26,0x42,0x00,0x01, +0x30,0x52,0x00,0xff,0x2e,0x43,0x00,0x05,0x14,0x60,0xff,0xd9,0x00,0x00,0x00,0x00, +0x8f,0xa5,0x00,0x10,0x0c,0x00,0x06,0xbf,0x24,0x04,0x06,0x14,0x12,0xa0,0x00,0x0e, +0x3c,0x02,0xb0,0x03,0x13,0xc0,0x00,0x0d,0x34,0x42,0x00,0x3c,0x00,0x15,0x10,0x40, +0x00,0x55,0x10,0x21,0x00,0x02,0x10,0xc0,0x00,0x55,0x10,0x21,0x00,0x02,0xa8,0x80, +0x02,0xbe,0x00,0x1b,0x17,0xc0,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x0d, +0x00,0x00,0xa8,0x12,0x3c,0x02,0xb0,0x03,0x34,0x42,0x00,0x3c,0x3c,0x03,0xb0,0x03, +0x3c,0x04,0xb0,0x03,0xa4,0x55,0x00,0x00,0x34,0x63,0x00,0x1c,0x34,0x84,0x00,0x1d, +0x24,0x02,0x00,0x01,0xa0,0x60,0x00,0x00,0xa0,0x82,0x00,0x00,0x7b,0xbe,0x01,0xfc, +0x7b,0xb6,0x01,0xbc,0x7b,0xb4,0x01,0x7c,0x7b,0xb2,0x01,0x3c,0x7b,0xb0,0x00,0xfc, +0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x40,0xa2,0xd1,0x00,0x00,0x08,0x00,0x24,0x98, +0x26,0x42,0x00,0x01,0x0c,0x00,0x06,0xd1,0x24,0x04,0x04,0xfc,0x08,0x00,0x24,0x8d, +0x00,0x40,0x88,0x21,0x3c,0x03,0xb0,0x03,0x34,0x63,0x00,0x3c,0x3c,0x04,0xb0,0x03, +0x3c,0x05,0xb0,0x03,0xa4,0x60,0x00,0x00,0x34,0x84,0x00,0x1c,0x34,0xa5,0x00,0x1d, +0x24,0x02,0x00,0x02,0x24,0x03,0x00,0x01,0xa0,0x82,0x00,0x00,0x08,0x00,0x24,0xb7, +0xa0,0xa3,0x00,0x00,0x0c,0x00,0x17,0x99,0x00,0x00,0x00,0x00,0x10,0x40,0xff,0x8b, +0x00,0x10,0x12,0x02,0x3c,0x02,0xb0,0x03,0x3c,0x04,0xb0,0x03,0x34,0x42,0x00,0x3c, +0x34,0x84,0x00,0x14,0x24,0x03,0x00,0x01,0xa4,0x40,0x00,0x00,0x3c,0x01,0xb0,0x03, +0xa0,0x23,0x00,0x3f,0x08,0x00,0x24,0xb7,0xac,0x90,0x00,0x00,0x27,0xbd,0xff,0xd8, +0xaf,0xb0,0x00,0x10,0x30,0xd0,0x00,0xff,0x2e,0x02,0x00,0x2e,0xaf,0xb2,0x00,0x18, +0xaf,0xb1,0x00,0x14,0xaf,0xbf,0x00,0x20,0xaf,0xb3,0x00,0x1c,0x30,0xb1,0x00,0xff, +0x14,0x40,0x00,0x06,0x00,0x80,0x90,0x21,0x8f,0xbf,0x00,0x20,0x7b,0xb2,0x00,0xfc, +0x7b,0xb0,0x00,0xbc,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28,0x2e,0x13,0x00,0x10, +0x24,0x05,0x00,0x14,0x0c,0x00,0x13,0xa4,0x24,0x06,0x01,0x07,0x12,0x60,0x00,0x38, +0x02,0x00,0x30,0x21,0x8f,0xa2,0x00,0x38,0x30,0xc3,0x00,0x3f,0x3c,0x04,0xb0,0x09, +0x00,0x02,0x14,0x00,0x00,0x43,0x30,0x25,0x34,0x84,0x01,0x60,0x90,0x82,0x00,0x00, +0x00,0x00,0x00,0x00,0x14,0x40,0xff,0xfd,0x24,0x02,0x00,0x01,0x12,0x22,0x00,0x2a, +0x2a,0x22,0x00,0x02,0x14,0x40,0x00,0x24,0x24,0x02,0x00,0x02,0x12,0x22,0x00,0x20, +0x24,0x02,0x00,0x03,0x12,0x22,0x00,0x19,0x00,0x00,0x00,0x00,0x16,0x60,0xff,0xe2, +0x24,0x02,0x00,0x01,0x12,0x22,0x00,0x13,0x2a,0x22,0x00,0x02,0x14,0x40,0x00,0x0d, +0x24,0x02,0x00,0x02,0x12,0x22,0x00,0x09,0x24,0x02,0x00,0x03,0x16,0x22,0xff,0xda, +0x00,0x00,0x00,0x00,0x24,0x04,0x08,0x4c,0x24,0x05,0xff,0xff,0x0c,0x00,0x13,0x5f, +0x3c,0x06,0x0c,0xb8,0x08,0x00,0x24,0xea,0x00,0x00,0x00,0x00,0x08,0x00,0x25,0x12, +0x24,0x04,0x08,0x48,0x16,0x20,0xff,0xd0,0x00,0x00,0x00,0x00,0x08,0x00,0x25,0x12, +0x24,0x04,0x08,0x40,0x08,0x00,0x25,0x12,0x24,0x04,0x08,0x44,0x24,0x04,0x08,0x4c, +0x0c,0x00,0x13,0x5f,0x24,0x05,0xff,0xff,0x08,0x00,0x25,0x07,0x00,0x00,0x00,0x00, +0x08,0x00,0x25,0x20,0x24,0x04,0x08,0x48,0x16,0x20,0xff,0xe0,0x00,0x00,0x00,0x00, +0x08,0x00,0x25,0x20,0x24,0x04,0x08,0x40,0x08,0x00,0x25,0x20,0x24,0x04,0x08,0x44, +0x02,0x40,0x20,0x21,0x0c,0x00,0x25,0x71,0x02,0x20,0x28,0x21,0x08,0x00,0x24,0xf5, +0x00,0x40,0x30,0x21,0x27,0xbd,0xff,0xd8,0x2c,0xc2,0x00,0x2e,0xaf,0xb2,0x00,0x18, +0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x20,0xaf,0xb3,0x00,0x1c, +0x00,0xc0,0x80,0x21,0x30,0xb1,0x00,0xff,0x00,0x80,0x90,0x21,0x14,0x40,0x00,0x07, +0x00,0x00,0x18,0x21,0x8f,0xbf,0x00,0x20,0x7b,0xb2,0x00,0xfc,0x7b,0xb0,0x00,0xbc, +0x00,0x60,0x10,0x21,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x28,0x2e,0x13,0x00,0x10, +0x24,0x05,0x00,0x14,0x0c,0x00,0x13,0xa4,0x24,0x06,0x01,0x07,0x12,0x60,0x00,0x24, +0x02,0x00,0x30,0x21,0x3c,0x03,0xb0,0x09,0x34,0x63,0x01,0x60,0x90,0x62,0x00,0x00, +0x00,0x00,0x00,0x00,0x14,0x40,0xff,0xfd,0x30,0xc5,0x00,0x3f,0x0c,0x00,0x25,0xae, +0x02,0x20,0x20,0x21,0x16,0x60,0x00,0x0a,0x00,0x40,0x80,0x21,0x24,0x02,0x00,0x01, +0x12,0x22,0x00,0x15,0x2a,0x22,0x00,0x02,0x14,0x40,0x00,0x0f,0x24,0x02,0x00,0x02, +0x12,0x22,0x00,0x0b,0x24,0x02,0x00,0x03,0x12,0x22,0x00,0x03,0x00,0x00,0x00,0x00, +0x08,0x00,0x25,0x3d,0x02,0x00,0x18,0x21,0x24,0x04,0x08,0x4c,0x24,0x05,0xff,0xff, +0x0c,0x00,0x13,0x5f,0x3c,0x06,0x0c,0xb8,0x08,0x00,0x25,0x3d,0x02,0x00,0x18,0x21, +0x08,0x00,0x25,0x5f,0x24,0x04,0x08,0x48,0x16,0x20,0xff,0xf5,0x00,0x00,0x00,0x00, +0x08,0x00,0x25,0x5f,0x24,0x04,0x08,0x40,0x08,0x00,0x25,0x5f,0x24,0x04,0x08,0x44, +0x02,0x40,0x20,0x21,0x0c,0x00,0x25,0x71,0x02,0x20,0x28,0x21,0x08,0x00,0x25,0x49, +0x00,0x40,0x30,0x21,0x27,0xbd,0xff,0xe8,0x2c,0xc2,0x00,0x1f,0xaf,0xb0,0x00,0x10, +0xaf,0xbf,0x00,0x14,0x00,0xc0,0x80,0x21,0x14,0x40,0x00,0x1d,0x30,0xa5,0x00,0xff, +0x24,0x02,0x00,0x01,0x10,0xa2,0x00,0x18,0x28,0xa2,0x00,0x02,0x14,0x40,0x00,0x12, +0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x0e,0x24,0x02,0x00,0x03,0x10,0xa2,0x00,0x07, +0x24,0x04,0x08,0x4c,0x26,0x10,0xff,0xe2,0x02,0x00,0x10,0x21,0x8f,0xbf,0x00,0x14, +0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x24,0x05,0xff,0xff, +0x0c,0x00,0x13,0x5f,0x3c,0x06,0x0d,0xf8,0x08,0x00,0x25,0x82,0x26,0x10,0xff,0xe2, +0x08,0x00,0x25,0x87,0x24,0x04,0x08,0x48,0x14,0xa0,0xff,0xf2,0x24,0x04,0x08,0x40, +0x08,0x00,0x25,0x88,0x24,0x05,0xff,0xff,0x08,0x00,0x25,0x87,0x24,0x04,0x08,0x44, +0x2c,0xc2,0x00,0x10,0x14,0x40,0xff,0xec,0x24,0x02,0x00,0x01,0x10,0xa2,0x00,0x14, +0x28,0xa2,0x00,0x02,0x14,0x40,0x00,0x0e,0x24,0x02,0x00,0x02,0x10,0xa2,0x00,0x0a, +0x24,0x02,0x00,0x03,0x10,0xa2,0x00,0x03,0x24,0x04,0x08,0x4c,0x08,0x00,0x25,0x82, +0x26,0x10,0xff,0xf1,0x24,0x05,0xff,0xff,0x0c,0x00,0x13,0x5f,0x3c,0x06,0x0d,0xb8, +0x08,0x00,0x25,0x82,0x26,0x10,0xff,0xf1,0x08,0x00,0x25,0xa1,0x24,0x04,0x08,0x48, +0x14,0xa0,0xff,0xf6,0x24,0x04,0x08,0x40,0x08,0x00,0x25,0xa2,0x24,0x05,0xff,0xff, +0x08,0x00,0x25,0xa1,0x24,0x04,0x08,0x44,0x27,0xbd,0xff,0xe8,0x30,0x84,0x00,0xff, +0x24,0x02,0x00,0x01,0x10,0x82,0x00,0x39,0xaf,0xbf,0x00,0x10,0x28,0x82,0x00,0x02, +0x14,0x40,0x00,0x27,0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x02,0x10,0x82,0x00,0x17, +0x00,0xa0,0x30,0x21,0x24,0x02,0x00,0x03,0x10,0x82,0x00,0x05,0x24,0x04,0x08,0x3c, +0x8f,0xbf,0x00,0x10,0x00,0x00,0x00,0x00,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18, +0x0c,0x00,0x13,0x5f,0x3c,0x05,0x3f,0x00,0x24,0x04,0x08,0x3c,0x3c,0x05,0x80,0x00, +0x0c,0x00,0x13,0x5f,0x00,0x00,0x30,0x21,0x24,0x04,0x08,0x3c,0x3c,0x05,0x80,0x00, +0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x01,0x24,0x04,0x08,0xac,0x0c,0x00,0x13,0x41, +0x24,0x05,0x0f,0xff,0x08,0x00,0x25,0xbc,0x00,0x00,0x00,0x00,0x24,0x04,0x08,0x34, +0x0c,0x00,0x13,0x5f,0x3c,0x05,0x3f,0x00,0x24,0x04,0x08,0x34,0x3c,0x05,0x80,0x00, +0x0c,0x00,0x13,0x5f,0x00,0x00,0x30,0x21,0x24,0x04,0x08,0x34,0x3c,0x05,0x80,0x00, +0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x01,0x08,0x00,0x25,0xcb,0x24,0x04,0x08,0xa8, +0x14,0x80,0xff,0xdf,0x00,0xa0,0x30,0x21,0x24,0x04,0x08,0x24,0x0c,0x00,0x13,0x5f, +0x3c,0x05,0x3f,0x00,0x24,0x04,0x08,0x24,0x3c,0x05,0x80,0x00,0x0c,0x00,0x13,0x5f, +0x00,0x00,0x30,0x21,0x24,0x04,0x08,0x24,0x3c,0x05,0x80,0x00,0x0c,0x00,0x13,0x5f, +0x24,0x06,0x00,0x01,0x08,0x00,0x25,0xcb,0x24,0x04,0x08,0xa0,0x00,0xa0,0x30,0x21, +0x24,0x04,0x08,0x2c,0x0c,0x00,0x13,0x5f,0x3c,0x05,0x3f,0x00,0x24,0x04,0x08,0x2c, +0x3c,0x05,0x80,0x00,0x0c,0x00,0x13,0x5f,0x00,0x00,0x30,0x21,0x24,0x04,0x08,0x2c, +0x3c,0x05,0x80,0x00,0x0c,0x00,0x13,0x5f,0x24,0x06,0x00,0x01,0x08,0x00,0x25,0xcb, +0x24,0x04,0x08,0xa4,0x3c,0x05,0x00,0x14,0x3c,0x02,0xb0,0x05,0x34,0x42,0x04,0x20, +0x3c,0x06,0xc0,0x00,0x3c,0x03,0xb0,0x05,0x3c,0x04,0xb0,0x05,0x34,0xa5,0x17,0x09, +0xac,0x45,0x00,0x00,0x34,0xc6,0x05,0x07,0x34,0x63,0x04,0x24,0x34,0x84,0x02,0x28, +0x3c,0x07,0xb0,0x05,0x24,0x02,0x00,0x20,0xac,0x66,0x00,0x00,0x34,0xe7,0x04,0x50, +0xa0,0x82,0x00,0x00,0x90,0xe2,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x03, +0x10,0x40,0xff,0xfc,0x24,0x02,0x00,0x01,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00, +0x93,0x85,0x81,0xf1,0x24,0x02,0x00,0x01,0x14,0xa2,0x00,0x53,0x00,0x80,0x40,0x21, +0x8c,0x89,0x00,0x04,0x3c,0x02,0xb0,0x01,0x01,0x22,0x30,0x21,0x8c,0xc3,0x00,0x04, +0x3c,0x02,0x01,0x00,0x00,0x62,0x10,0x24,0x10,0x40,0x00,0x4b,0x30,0x62,0x00,0x08, +0x10,0x45,0x00,0x59,0x00,0x00,0x00,0x00,0x94,0xc2,0x00,0x38,0x24,0x03,0x00,0xb4, +0x30,0x44,0x00,0xff,0x10,0x83,0x00,0x61,0x24,0x02,0x00,0xc4,0x10,0x82,0x00,0x54, +0x24,0x02,0x00,0x94,0x10,0x82,0x00,0x45,0x00,0x00,0x00,0x00,0x94,0xc2,0x00,0x38, +0x00,0x00,0x00,0x00,0x30,0x47,0xff,0xff,0x30,0xe3,0x40,0xff,0x24,0x02,0x40,0x88, +0x14,0x62,0x00,0x39,0x30,0xe3,0x03,0x00,0x24,0x02,0x03,0x00,0x10,0x62,0x00,0x38, +0x00,0x00,0x00,0x00,0x94,0xc2,0x00,0x56,0x00,0x00,0x00,0x00,0x30,0x47,0xff,0xff, +0x30,0xe2,0x00,0x80,0x14,0x40,0x00,0x30,0x3c,0x02,0xb0,0x01,0x01,0x22,0x30,0x21, +0x94,0xc3,0x00,0x60,0x24,0x02,0x00,0x08,0x14,0x43,0x00,0x3b,0x00,0x00,0x00,0x00, +0x90,0xc2,0x00,0x62,0x24,0x03,0x00,0x04,0x00,0x02,0x39,0x02,0x10,0xe3,0x00,0x15, +0x24,0x02,0x00,0x06,0x14,0xe2,0x00,0x34,0x00,0x00,0x00,0x00,0x8d,0x05,0x01,0xac, +0x94,0xc4,0x00,0x66,0x27,0x82,0x89,0x68,0x00,0x05,0x28,0x80,0x30,0x87,0xff,0xff, +0x00,0xa2,0x28,0x21,0x00,0x07,0x1a,0x00,0x8c,0xa4,0x00,0x00,0x00,0x07,0x12,0x02, +0x00,0x43,0x10,0x25,0x24,0x42,0x00,0x5e,0x24,0x03,0xc0,0x00,0x30,0x47,0xff,0xff, +0x00,0x83,0x20,0x24,0x00,0x87,0x20,0x25,0xac,0xa4,0x00,0x00,0x08,0x00,0x26,0x76, +0xad,0x07,0x00,0x10,0x8d,0x05,0x01,0xac,0x94,0xc4,0x00,0x64,0x27,0x82,0x89,0x68, +0x00,0x05,0x28,0x80,0x30,0x87,0xff,0xff,0x00,0xa2,0x28,0x21,0x00,0x07,0x1a,0x00, +0x8c,0xa4,0x00,0x00,0x00,0x07,0x12,0x02,0x00,0x43,0x10,0x25,0x24,0x42,0x00,0x36, +0x3c,0x03,0xff,0xff,0x30,0x47,0xff,0xff,0x00,0x83,0x20,0x24,0x00,0x87,0x20,0x25, +0xac,0xa4,0x00,0x00,0xad,0x07,0x00,0x10,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00, +0x94,0xc2,0x00,0x50,0x08,0x00,0x26,0x34,0x30,0x47,0xff,0xff,0x8d,0x04,0x01,0xac, +0x27,0x83,0x89,0x68,0x00,0x04,0x20,0x80,0x00,0x83,0x20,0x21,0x8c,0x82,0x00,0x00, +0x3c,0x03,0xff,0xff,0x00,0x43,0x10,0x24,0x34,0x42,0x00,0x2e,0xac,0x82,0x00,0x00, +0x24,0x03,0x00,0x2e,0xad,0x03,0x00,0x10,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00, +0x8d,0x04,0x01,0xac,0x27,0x83,0x89,0x68,0x00,0x04,0x20,0x80,0x00,0x83,0x20,0x21, +0x8c,0x82,0x00,0x00,0x3c,0x03,0xff,0xff,0x00,0x43,0x10,0x24,0x34,0x42,0x00,0x0e, +0x24,0x03,0x00,0x0e,0x08,0x00,0x26,0x75,0xac,0x82,0x00,0x00,0x8d,0x04,0x01,0xac, +0x27,0x83,0x89,0x68,0x00,0x04,0x20,0x80,0x00,0x83,0x20,0x21,0x8c,0x82,0x00,0x00, +0x3c,0x03,0xff,0xff,0x00,0x43,0x10,0x24,0x34,0x42,0x00,0x14,0x24,0x03,0x00,0x14, +0x08,0x00,0x26,0x75,0xac,0x82,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00, +0x30,0xc6,0x00,0xff,0x00,0x06,0x48,0x40,0x01,0x26,0x10,0x21,0x00,0x02,0x10,0x80, +0x27,0x8b,0xbc,0x30,0x27,0x83,0xbc,0x36,0x00,0x4b,0x40,0x21,0x00,0x43,0x10,0x21, +0x94,0x47,0x00,0x00,0x30,0xa2,0x3f,0xff,0x10,0xe2,0x00,0x29,0x30,0x8a,0xff,0xff, +0x95,0x02,0x00,0x02,0x24,0x03,0x00,0x01,0x00,0x02,0x11,0x82,0x30,0x42,0x00,0x01, +0x10,0x43,0x00,0x18,0x00,0x00,0x00,0x00,0x01,0x26,0x10,0x21,0x00,0x02,0x10,0x80, +0x00,0x4b,0x30,0x21,0x94,0xc4,0x00,0x02,0x27,0x83,0xbc,0x36,0x27,0x85,0xbc,0x34, +0x00,0x45,0x28,0x21,0x30,0x84,0xff,0xdf,0x00,0x43,0x10,0x21,0xa4,0xc4,0x00,0x02, +0xa4,0x40,0x00,0x00,0xa4,0xa0,0x00,0x00,0x94,0xc3,0x00,0x02,0x3c,0x04,0xb0,0x01, +0x01,0x44,0x20,0x21,0x30,0x63,0xff,0xbf,0xa4,0xc3,0x00,0x02,0xa0,0xc0,0x00,0x00, +0x8c,0x82,0x00,0x04,0x24,0x03,0xf0,0xff,0x00,0x43,0x10,0x24,0x03,0xe0,0x00,0x08, +0xac,0x82,0x00,0x04,0x24,0x02,0xc0,0x00,0x91,0x04,0x00,0x01,0x00,0xa2,0x10,0x24, +0x00,0x47,0x28,0x25,0x3c,0x03,0xb0,0x01,0x24,0x02,0x00,0x02,0x14,0x82,0xff,0xe2, +0x01,0x43,0x18,0x21,0xac,0x65,0x00,0x00,0x08,0x00,0x26,0xa3,0x01,0x26,0x10,0x21, +0x08,0x00,0x26,0xa3,0x01,0x26,0x10,0x21,0x93,0x83,0x81,0xf1,0x24,0x02,0x00,0x01, +0x14,0x62,0x00,0x0d,0x3c,0x02,0xb0,0x01,0x8c,0x84,0x00,0x04,0x3c,0x06,0xb0,0x09, +0x00,0x82,0x20,0x21,0x8c,0x85,0x00,0x08,0x8c,0x83,0x00,0x04,0x3c,0x02,0x01,0x00, +0x34,0xc6,0x01,0x00,0x00,0x62,0x18,0x24,0x14,0x60,0x00,0x05,0x30,0xa5,0x20,0x00, +0x24,0x02,0x00,0x06,0xa0,0xc2,0x00,0x00,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00, +0x3c,0x03,0xb0,0x09,0x10,0xa0,0xff,0xfc,0x34,0x63,0x01,0x00,0x24,0x02,0x00,0x0e, +0x08,0x00,0x26,0xd6,0xa0,0x62,0x00,0x00,0x3c,0x02,0xb0,0x01,0x30,0xa5,0xff,0xff, +0x00,0xa2,0x28,0x21,0x8c,0xa3,0x00,0x00,0x3c,0x02,0x10,0x00,0x00,0x80,0x30,0x21, +0x00,0x62,0x18,0x24,0x8c,0xa2,0x00,0x04,0x10,0x60,0x00,0x04,0x00,0x00,0x00,0x00, +0x30,0x42,0x80,0x00,0x10,0x40,0x00,0x13,0x00,0x00,0x00,0x00,0x8c,0xc2,0x01,0xa8, +0x00,0x00,0x00,0x00,0x24,0x44,0x00,0x01,0x28,0x83,0x00,0x00,0x24,0x42,0x00,0x40, +0x00,0x83,0x10,0x0a,0x93,0x83,0x81,0xf0,0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80, +0x00,0x82,0x20,0x23,0x24,0x63,0xff,0xff,0xac,0xc4,0x01,0xa8,0xa3,0x83,0x81,0xf0, +0x8c,0xc4,0x01,0xac,0x8c,0xc2,0x01,0xa8,0x00,0x00,0x00,0x00,0x00,0x44,0x10,0x26, +0x00,0x02,0x10,0x2b,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x3c,0x03,0xb0,0x03, +0x34,0x63,0x00,0x73,0x90,0x62,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x42,0x00,0x01, +0x14,0x40,0x00,0x04,0x00,0x00,0x00,0x00,0xa3,0x80,0x81,0xf1,0x03,0xe0,0x00,0x08, +0x00,0x00,0x00,0x00,0x24,0x02,0x00,0x01,0xa3,0x82,0x81,0xf1,0x03,0xe0,0x00,0x08, +0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x04,0x3c,0x05,0xb0,0x01,0x00,0x80,0x50,0x21, +0x00,0x45,0x10,0x21,0x8c,0x43,0x00,0x04,0x24,0x02,0x00,0x05,0x00,0x03,0x1a,0x02, +0x30,0x69,0x00,0x0f,0x11,0x22,0x00,0x0b,0x24,0x02,0x00,0x07,0x11,0x22,0x00,0x09, +0x24,0x02,0x00,0x0a,0x11,0x22,0x00,0x07,0x24,0x02,0x00,0x0b,0x11,0x22,0x00,0x05, +0x24,0x02,0x00,0x01,0x93,0x83,0x81,0xf0,0x3c,0x04,0xb0,0x06,0x10,0x62,0x00,0x03, +0x34,0x84,0x80,0x18,0x03,0xe0,0x00,0x08,0x00,0x00,0x00,0x00,0x8c,0x82,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x02,0x17,0x02,0x14,0x40,0xff,0xfa,0x00,0x00,0x00,0x00, +0x8d,0x43,0x01,0xa8,0x27,0x82,0x89,0x68,0x00,0x03,0x18,0x80,0x00,0x6a,0x20,0x21, +0x8c,0x87,0x00,0xa8,0x00,0x62,0x18,0x21,0x8c,0x68,0x00,0x00,0x00,0xe5,0x28,0x21, +0x8c,0xa9,0x00,0x00,0x3c,0x02,0xff,0xff,0x27,0x83,0x8a,0x68,0x01,0x22,0x10,0x24, +0x00,0x48,0x10,0x25,0xac,0xa2,0x00,0x00,0x8d,0x44,0x01,0xa8,0x00,0x07,0x30,0xc2, +0x3c,0x02,0x00,0x80,0x00,0x04,0x20,0x80,0x00,0x83,0x20,0x21,0x00,0x06,0x32,0x00, +0x8c,0xa9,0x00,0x04,0x00,0xc2,0x30,0x25,0x8c,0x82,0x00,0x00,0x3c,0x03,0x80,0x00, +0x01,0x22,0x10,0x25,0x00,0x43,0x10,0x25,0xac,0xa2,0x00,0x04,0xaf,0x87,0xbc,0x20, +0x8c,0xa2,0x00,0x00,0x00,0x00,0x00,0x00,0xaf,0x82,0xbc,0x28,0x8c,0xa3,0x00,0x04, +0x3c,0x01,0xb0,0x07,0xac,0x26,0x80,0x18,0x8d,0x42,0x01,0xa8,0xaf,0x83,0xbc,0x24, +0x93,0x85,0x81,0xf0,0x24,0x44,0x00,0x01,0x28,0x83,0x00,0x00,0x24,0x42,0x00,0x40, +0x00,0x83,0x10,0x0a,0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x24,0xa5,0xff,0xff, +0x00,0x82,0x20,0x23,0xad,0x44,0x01,0xa8,0xa3,0x85,0x81,0xf0,0x08,0x00,0x27,0x21, +0x00,0x00,0x00,0x00,0x3c,0x05,0xb0,0x03,0x3c,0x02,0x80,0x01,0x34,0xa5,0x00,0x20, +0x24,0x42,0x9d,0x64,0xac,0xa2,0x00,0x00,0x24,0x02,0x00,0x02,0x24,0x03,0x00,0x20, +0xac,0x82,0x00,0x64,0x3c,0x02,0x80,0x01,0xac,0x83,0x00,0x60,0xac,0x80,0x00,0x00, +0xac,0x80,0x00,0x04,0xac,0x80,0x00,0x08,0xac,0x80,0x00,0x4c,0xac,0x80,0x00,0x50, +0xac,0x80,0x00,0x54,0xac,0x80,0x00,0x0c,0xac,0x80,0x00,0x58,0xa0,0x80,0x00,0x5c, +0x24,0x42,0x9e,0x28,0x24,0x83,0x00,0x68,0x24,0x05,0x00,0x0f,0x24,0xa5,0xff,0xff, +0xac,0x62,0x00,0x00,0x04,0xa1,0xff,0xfd,0x24,0x63,0x00,0x04,0x3c,0x02,0x80,0x01, +0x24,0x42,0x9f,0x10,0xac,0x82,0x00,0x78,0x3c,0x03,0x80,0x01,0x3c,0x02,0x80,0x01, +0x24,0x63,0xa0,0x9c,0x24,0x42,0xa0,0x08,0xac,0x83,0x00,0x88,0xac,0x82,0x00,0x98, +0x3c,0x03,0x80,0x01,0x3c,0x02,0x80,0x01,0x24,0x63,0xa1,0x44,0x24,0x42,0xa2,0x5c, +0xac,0x83,0x00,0xa0,0xac,0x82,0x00,0xa4,0xa0,0x80,0x01,0xba,0xac,0x80,0x01,0xa8, +0xac,0x80,0x01,0xac,0xac,0x80,0x01,0xb0,0xac,0x80,0x01,0xb4,0xa0,0x80,0x01,0xb8, +0x03,0xe0,0x00,0x08,0xa0,0x80,0x01,0xb9,0x3c,0x03,0xb0,0x03,0x3c,0x02,0x80,0x01, +0x34,0x63,0x00,0x20,0x24,0x42,0x9e,0x28,0x03,0xe0,0x00,0x08,0xac,0x62,0x00,0x00, +0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x34,0x42,0x00,0x20,0x24,0x63,0x9e,0x40, +0xac,0x43,0x00,0x00,0x8c,0x82,0x00,0x10,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x11, +0x00,0x80,0x28,0x21,0x8c,0x82,0x00,0x14,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0d, +0x00,0x00,0x00,0x00,0x8c,0x84,0x00,0x10,0x8c,0xa3,0x00,0x14,0x8c,0xa2,0x00,0x04, +0x00,0x83,0x20,0x21,0x00,0x44,0x10,0x21,0x30,0x43,0x00,0xff,0x00,0x03,0x18,0x2b, +0x00,0x02,0x12,0x02,0x00,0x43,0x10,0x21,0x00,0x02,0x12,0x00,0x30,0x42,0x3f,0xff, +0xac,0xa2,0x00,0x04,0xac,0xa0,0x00,0x00,0xac,0xa0,0x00,0x4c,0xac,0xa0,0x00,0x50, +0xac,0xa0,0x00,0x54,0x03,0xe0,0x00,0x08,0xac,0xa0,0x00,0x0c,0x3c,0x03,0xb0,0x03, +0x3c,0x02,0x80,0x01,0x34,0x63,0x00,0x20,0x24,0x42,0x9e,0xbc,0xac,0x62,0x00,0x00, +0x8c,0x86,0x00,0x04,0x3c,0x02,0xb0,0x01,0x24,0x03,0x00,0x01,0x00,0xc2,0x10,0x21, +0x8c,0x45,0x00,0x00,0xac,0x83,0x00,0x4c,0x00,0x05,0x14,0x02,0x30,0xa3,0x3f,0xff, +0x30,0x42,0x00,0xff,0xac,0x83,0x00,0x10,0xac,0x82,0x00,0x14,0x8c,0x83,0x00,0x14, +0xac,0x85,0x00,0x40,0x00,0xc3,0x30,0x21,0x03,0xe0,0x00,0x08,0xac,0x86,0x00,0x08, +0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe8,0x34,0x42,0x00,0x20, +0x24,0x63,0x9f,0x10,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,0xac,0x43,0x00,0x00, +0x8c,0x82,0x00,0x4c,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x0a,0x00,0x80,0x80,0x21, +0xae,0x00,0x00,0x00,0xae,0x00,0x00,0x4c,0xae,0x00,0x00,0x50,0xae,0x00,0x00,0x54, +0xae,0x00,0x00,0x0c,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x18,0x0c,0x00,0x27,0xaf,0x00,0x00,0x00,0x00,0x08,0x00,0x27,0xd1, +0xae,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe8, +0x34,0x42,0x00,0x20,0x24,0x63,0x9f,0x74,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14, +0xac,0x43,0x00,0x00,0x8c,0x82,0x00,0x4c,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x16, +0x00,0x80,0x80,0x21,0x8e,0x03,0x00,0x08,0x3c,0x02,0xb0,0x01,0x8e,0x04,0x00,0x44, +0x00,0x62,0x18,0x21,0x90,0x65,0x00,0x00,0x24,0x02,0x00,0x01,0xae,0x02,0x00,0x50, +0x30,0xa3,0x00,0xff,0x00,0x03,0x10,0x82,0x00,0x04,0x23,0x02,0x30,0x84,0x00,0x0f, +0x30,0x42,0x00,0x03,0x00,0x03,0x19,0x02,0xae,0x04,0x00,0x34,0xae,0x02,0x00,0x2c, +0xae,0x03,0x00,0x30,0xa2,0x05,0x00,0x48,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10, +0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x0c,0x00,0x27,0xaf,0x00,0x00,0x00,0x00, +0x08,0x00,0x27,0xe9,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01, +0x27,0xbd,0xff,0xe8,0x34,0x42,0x00,0x20,0x24,0x63,0xa0,0x08,0xaf,0xb0,0x00,0x10, +0xaf,0xbf,0x00,0x14,0xac,0x43,0x00,0x00,0x8c,0x82,0x00,0x50,0x00,0x00,0x00,0x00, +0x10,0x40,0x00,0x16,0x00,0x80,0x80,0x21,0x92,0x03,0x00,0x44,0x8e,0x02,0x00,0x40, +0x83,0x85,0x8b,0xd4,0x92,0x04,0x00,0x41,0x30,0x63,0x00,0x01,0x00,0x02,0x16,0x02, +0xae,0x04,0x00,0x14,0x00,0x00,0x30,0x21,0xae,0x02,0x00,0x18,0x10,0xa0,0x00,0x04, +0xae,0x03,0x00,0x3c,0x10,0x60,0x00,0x03,0x24,0x02,0x00,0x01,0x24,0x06,0x00,0x01, +0x24,0x02,0x00,0x01,0xa3,0x86,0x8b,0xd4,0x8f,0xbf,0x00,0x14,0xae,0x02,0x00,0x54, +0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x0c,0x00,0x27,0xdd, +0x00,0x00,0x00,0x00,0x08,0x00,0x28,0x0e,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03, +0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe8,0x34,0x42,0x00,0x20,0x24,0x63,0xa0,0x9c, +0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,0xac,0x43,0x00,0x00,0x8c,0x82,0x00,0x50, +0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x1b,0x00,0x80,0x80,0x21,0x3c,0x02,0xb0,0x03, +0x8c,0x42,0x00,0x00,0x92,0x04,0x00,0x44,0x8e,0x03,0x00,0x40,0x83,0x86,0x8b,0xd4, +0x92,0x05,0x00,0x41,0x30,0x42,0x08,0x00,0x30,0x84,0x00,0x01,0x00,0x02,0x12,0xc2, +0x00,0x03,0x1e,0x02,0x00,0x82,0x20,0x25,0xae,0x05,0x00,0x14,0x00,0x00,0x38,0x21, +0xae,0x03,0x00,0x18,0x10,0xc0,0x00,0x04,0xae,0x04,0x00,0x3c,0x10,0x80,0x00,0x03, +0x24,0x02,0x00,0x01,0x24,0x07,0x00,0x01,0x24,0x02,0x00,0x01,0xa3,0x87,0x8b,0xd4, +0x8f,0xbf,0x00,0x14,0xae,0x02,0x00,0x54,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x18,0x0c,0x00,0x27,0xdd,0x00,0x00,0x00,0x00,0x08,0x00,0x28,0x33, +0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe8, +0x34,0x42,0x00,0x20,0x24,0x63,0xa1,0x44,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14, +0xac,0x43,0x00,0x00,0x8c,0x82,0x00,0x54,0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x37, +0x00,0x80,0x80,0x21,0x8e,0x04,0x00,0x04,0x8e,0x03,0x00,0x44,0x3c,0x02,0x80,0x00, +0x3c,0x05,0xb0,0x01,0x34,0x42,0x00,0x10,0x00,0x85,0x20,0x21,0x00,0x62,0x18,0x25, +0xac,0x83,0x00,0x04,0x8e,0x02,0x00,0x04,0x8e,0x03,0x01,0xac,0x02,0x00,0x20,0x21, +0x00,0x45,0x10,0x21,0x8c,0x46,0x00,0x00,0x00,0x03,0x18,0x80,0x27,0x82,0x89,0x68, +0x00,0x62,0x18,0x21,0xac,0x66,0x00,0x00,0x8e,0x02,0x00,0x04,0x8e,0x03,0x01,0xac, +0x00,0x45,0x10,0x21,0x8c,0x46,0x00,0x04,0x00,0x03,0x18,0x80,0x27,0x82,0x8a,0x68, +0x00,0x62,0x18,0x21,0x0c,0x00,0x26,0x10,0xac,0x66,0x00,0x00,0x8e,0x03,0x01,0xac, +0x8e,0x07,0x00,0x04,0x3c,0x06,0xb0,0x03,0x24,0x65,0x00,0x01,0x28,0xa4,0x00,0x00, +0x24,0x62,0x00,0x40,0x00,0xa4,0x10,0x0a,0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80, +0x00,0x03,0x18,0x80,0x00,0xa2,0x28,0x23,0x00,0x70,0x18,0x21,0xae,0x05,0x01,0xac, +0xac,0x67,0x00,0xa8,0x34,0xc6,0x00,0x30,0x8c,0xc3,0x00,0x00,0x93,0x82,0x81,0xf0, +0x02,0x00,0x20,0x21,0x24,0x63,0x00,0x01,0x24,0x42,0x00,0x01,0xac,0xc3,0x00,0x00, +0xa3,0x82,0x81,0xf0,0x0c,0x00,0x27,0x90,0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x14, +0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x18,0x0c,0x00,0x28,0x27, +0x00,0x00,0x00,0x00,0x08,0x00,0x28,0x5d,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03, +0x3c,0x03,0x80,0x01,0x27,0xbd,0xff,0xe8,0x34,0x42,0x00,0x20,0x24,0x63,0xa2,0x5c, +0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x14,0xac,0x43,0x00,0x00,0x8c,0x82,0x00,0x54, +0x00,0x00,0x00,0x00,0x10,0x40,0x00,0x37,0x00,0x80,0x80,0x21,0x8e,0x04,0x00,0x04, +0x8e,0x03,0x00,0x44,0x3c,0x02,0x80,0x00,0x3c,0x05,0xb0,0x01,0x34,0x42,0x00,0x10, +0x00,0x85,0x20,0x21,0x00,0x62,0x18,0x25,0xac,0x83,0x00,0x04,0x8e,0x02,0x00,0x04, +0x8e,0x03,0x01,0xac,0x02,0x00,0x20,0x21,0x00,0x45,0x10,0x21,0x8c,0x46,0x00,0x00, +0x00,0x03,0x18,0x80,0x27,0x82,0x89,0x68,0x00,0x62,0x18,0x21,0xac,0x66,0x00,0x00, +0x8e,0x02,0x00,0x04,0x8e,0x03,0x01,0xac,0x00,0x45,0x10,0x21,0x8c,0x46,0x00,0x04, +0x00,0x03,0x18,0x80,0x27,0x82,0x8a,0x68,0x00,0x62,0x18,0x21,0x0c,0x00,0x26,0x10, +0xac,0x66,0x00,0x00,0x8e,0x03,0x01,0xac,0x8e,0x07,0x00,0x04,0x3c,0x06,0xb0,0x03, +0x24,0x65,0x00,0x01,0x28,0xa4,0x00,0x00,0x24,0x62,0x00,0x40,0x00,0xa4,0x10,0x0a, +0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x00,0x03,0x18,0x80,0x00,0xa2,0x28,0x23, +0x00,0x70,0x18,0x21,0xae,0x05,0x01,0xac,0xac,0x67,0x00,0xa8,0x34,0xc6,0x00,0x30, +0x8c,0xc3,0x00,0x00,0x93,0x82,0x81,0xf0,0x02,0x00,0x20,0x21,0x24,0x63,0x00,0x01, +0x24,0x42,0x00,0x01,0xac,0xc3,0x00,0x00,0xa3,0x82,0x81,0xf0,0x0c,0x00,0x27,0x90, +0x00,0x00,0x00,0x00,0x8f,0xbf,0x00,0x14,0x8f,0xb0,0x00,0x10,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x18,0x0c,0x00,0x28,0x27,0x00,0x00,0x00,0x00,0x08,0x00,0x28,0xa3, +0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03,0x3c,0x03,0x80,0x01,0x34,0x42,0x00,0x20, +0x24,0x63,0xa3,0x74,0x27,0xbd,0xff,0xe0,0xac,0x43,0x00,0x00,0x3c,0x02,0x80,0x01, +0xaf,0xb2,0x00,0x18,0xaf,0xb1,0x00,0x14,0xaf,0xb0,0x00,0x10,0xaf,0xbf,0x00,0x1c, +0x00,0x80,0x80,0x21,0x24,0x52,0x9e,0x28,0x00,0x00,0x88,0x21,0x3c,0x03,0xb0,0x09, +0x34,0x63,0x00,0x06,0x8e,0x06,0x00,0x04,0x90,0x62,0x00,0x00,0x00,0x06,0x22,0x02, +0x00,0x44,0x10,0x23,0x24,0x44,0x00,0x40,0x28,0x83,0x00,0x00,0x24,0x42,0x00,0x7f, +0x00,0x83,0x10,0x0a,0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x24,0x84,0xff,0xff, +0x10,0x44,0x00,0x68,0x00,0x00,0x28,0x21,0x3c,0x02,0xb0,0x01,0x00,0xc2,0x10,0x21, +0x8c,0x44,0x00,0x04,0x3c,0x03,0x7c,0x00,0x34,0x63,0x00,0xf0,0x00,0x83,0x18,0x24, +0xae,0x04,0x00,0x44,0x8c,0x44,0x00,0x00,0x10,0x60,0x00,0x69,0x00,0x00,0x38,0x21, +0x3c,0x09,0xb0,0x03,0x3c,0x06,0x7c,0x00,0x35,0x29,0x00,0x99,0x3c,0x0a,0xb0,0x01, +0x24,0x08,0x00,0x40,0x34,0xc6,0x00,0xf0,0x3c,0x0b,0xff,0xff,0x3c,0x0c,0x28,0x38, +0x16,0x20,0x00,0x06,0x24,0xa5,0x00,0x01,0x93,0x82,0x81,0xf6,0x24,0x11,0x00,0x01, +0x24,0x42,0x00,0x01,0xa1,0x22,0x00,0x00,0xa3,0x82,0x81,0xf6,0x8e,0x02,0x00,0x04, +0x24,0x07,0x00,0x01,0x24,0x42,0x01,0x00,0x30,0x42,0x3f,0xff,0xae,0x02,0x00,0x04, +0x00,0x4a,0x10,0x21,0x8c,0x43,0x00,0x04,0x00,0x00,0x00,0x00,0xae,0x03,0x00,0x44, +0x8c,0x44,0x00,0x00,0x10,0xa8,0x00,0x2d,0x00,0x66,0x18,0x24,0x14,0x60,0xff,0xec, +0x00,0x8b,0x10,0x24,0x14,0x4c,0xff,0xea,0x24,0x02,0x00,0x01,0x10,0xe2,0x00,0x2f, +0x3c,0x03,0xb0,0x09,0x8e,0x02,0x00,0x44,0x8e,0x04,0x00,0x60,0x00,0x02,0x1e,0x42, +0x00,0x02,0x12,0x02,0x30,0x42,0x00,0x0f,0x30,0x63,0x00,0x01,0xae,0x02,0x00,0x00, +0x10,0x44,0x00,0x1a,0xae,0x03,0x00,0x58,0x8e,0x02,0x00,0x64,0x8e,0x04,0x00,0x58, +0x00,0x00,0x00,0x00,0x10,0x82,0x00,0x05,0x00,0x00,0x00,0x00,0xae,0x00,0x00,0x4c, +0xae,0x00,0x00,0x50,0xae,0x00,0x00,0x54,0xae,0x00,0x00,0x0c,0x8e,0x03,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x03,0x10,0x80,0x00,0x50,0x10,0x21,0x8c,0x42,0x00,0x68, +0x00,0x00,0x00,0x00,0x10,0x52,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x40,0xf8,0x09, +0x02,0x00,0x20,0x21,0x8e,0x04,0x00,0x58,0x8e,0x03,0x00,0x00,0x00,0x00,0x00,0x00, +0xae,0x03,0x00,0x60,0x08,0x00,0x28,0xeb,0xae,0x04,0x00,0x64,0x8e,0x02,0x00,0x64, +0x00,0x00,0x00,0x00,0x14,0x62,0xff,0xe5,0x00,0x00,0x00,0x00,0x7a,0x02,0x0d,0x7c, +0x8f,0xbf,0x00,0x1c,0x8f,0xb2,0x00,0x18,0x7b,0xb0,0x00,0xbc,0x00,0x43,0x10,0x26, +0x00,0x02,0x10,0x2b,0x03,0xe0,0x00,0x08,0x27,0xbd,0x00,0x20,0x34,0x63,0x00,0x06, +0x8e,0x04,0x00,0x04,0x90,0x62,0x00,0x00,0x00,0x04,0x22,0x02,0x00,0x44,0x10,0x23, +0x24,0x44,0x00,0x40,0x28,0x83,0x00,0x00,0x24,0x42,0x00,0x7f,0x00,0x83,0x10,0x0a, +0x00,0x02,0x11,0x83,0x00,0x02,0x11,0x80,0x00,0x82,0x20,0x23,0x14,0x87,0xff,0xc5, +0x00,0x00,0x00,0x00,0x8e,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x2c,0x62,0x00,0x03, +0x14,0x40,0x00,0x05,0x24,0x02,0x00,0x0d,0x10,0x62,0x00,0x03,0x24,0x02,0x00,0x01, +0x08,0x00,0x29,0x4b,0xa2,0x02,0x00,0x5c,0x08,0x00,0x29,0x4b,0xa2,0x00,0x00,0x5c, +0x3c,0x02,0xff,0xff,0x00,0x82,0x10,0x24,0x3c,0x03,0x28,0x38,0x14,0x43,0xff,0x94, +0x24,0x02,0x00,0x01,0x08,0x00,0x29,0x23,0x00,0x00,0x00,0x00,0x3c,0x02,0xb0,0x03, +0x3c,0x03,0x80,0x01,0x34,0x42,0x00,0x20,0x24,0x63,0xa5,0xcc,0xac,0x43,0x00,0x00, +0x8c,0x83,0x01,0xa8,0x8c,0x82,0x01,0xac,0x00,0x80,0x40,0x21,0x10,0x62,0x00,0x20, +0x00,0x00,0x20,0x21,0x93,0x82,0x81,0xf1,0x00,0x03,0x28,0x80,0x3c,0x07,0xb0,0x06, +0x00,0xa8,0x18,0x21,0x24,0x04,0x00,0x01,0x8c,0x66,0x00,0xa8,0x10,0x44,0x00,0x1c, +0x34,0xe7,0x80,0x18,0x3c,0x05,0xb0,0x01,0xaf,0x86,0xbc,0x20,0x00,0xc5,0x28,0x21, +0x8c,0xa3,0x00,0x00,0x00,0x06,0x20,0xc2,0x3c,0x02,0x00,0x80,0x00,0x04,0x22,0x00, +0x00,0x82,0x20,0x25,0xaf,0x83,0xbc,0x28,0x8c,0xa2,0x00,0x04,0xac,0xe4,0x00,0x00, +0x8d,0x03,0x01,0xa8,0xaf,0x82,0xbc,0x24,0x24,0x64,0x00,0x01,0x04,0x80,0x00,0x0a, +0x00,0x80,0x10,0x21,0x00,0x02,0x11,0x83,0x8d,0x03,0x01,0xac,0x00,0x02,0x11,0x80, +0x00,0x82,0x10,0x23,0x00,0x43,0x18,0x26,0xad,0x02,0x01,0xa8,0x00,0x03,0x20,0x2b, +0x03,0xe0,0x00,0x08,0x00,0x80,0x10,0x21,0x08,0x00,0x29,0x95,0x24,0x62,0x00,0x40, +0x27,0x82,0x89,0x68,0x00,0x06,0x20,0xc2,0x00,0x04,0x22,0x00,0x00,0xa2,0x48,0x21, +0x3c,0x02,0x00,0x80,0x00,0x82,0x58,0x25,0x93,0x82,0x81,0xf0,0x3c,0x0a,0xb0,0x06, +0x3c,0x03,0xb0,0x01,0x2c,0x42,0x00,0x02,0x00,0xc3,0x38,0x21,0x35,0x4a,0x80,0x18, +0x14,0x40,0xff,0xef,0x00,0x00,0x20,0x21,0x8c,0xe5,0x00,0x00,0x8d,0x23,0x00,0x00, +0x24,0x02,0xc0,0x00,0x00,0xa2,0x10,0x24,0x00,0x43,0x10,0x25,0xac,0xe2,0x00,0x00, +0x8d,0x04,0x01,0xa8,0x27,0x83,0x8a,0x68,0x8c,0xe5,0x00,0x04,0x00,0x04,0x20,0x80, +0x00,0x83,0x20,0x21,0x8c,0x82,0x00,0x00,0x3c,0x03,0x80,0x00,0x00,0xa2,0x10,0x25, +0x00,0x43,0x10,0x25,0xac,0xe2,0x00,0x04,0xaf,0x86,0xbc,0x20,0x8c,0xe2,0x00,0x00, +0x93,0x85,0x81,0xf0,0xaf,0x82,0xbc,0x28,0x8c,0xe3,0x00,0x04,0xad,0x4b,0x00,0x00, +0x8d,0x02,0x01,0xa8,0xaf,0x83,0xbc,0x24,0x24,0xa5,0xff,0xff,0x24,0x44,0x00,0x01, +0x28,0x83,0x00,0x00,0x24,0x42,0x00,0x40,0x00,0x83,0x10,0x0a,0x00,0x02,0x11,0x83, +0x00,0x02,0x11,0x80,0x00,0x82,0x20,0x23,0xad,0x04,0x01,0xa8,0xa3,0x85,0x81,0xf0, +0x79,0x02,0x0d,0x7c,0x00,0x00,0x00,0x00,0x00,0x43,0x10,0x26,0x08,0x00,0x29,0x9c, +0x00,0x02,0x20,0x2b,0x3c,0x04,0xb0,0x03,0x3c,0x06,0xb0,0x07,0x3c,0x02,0x80,0x01, +0x34,0xc6,0x00,0x18,0x34,0x84,0x00,0x20,0x24,0x42,0xa7,0x54,0x24,0x03,0xff,0x83, +0xac,0x82,0x00,0x00,0xa0,0xc3,0x00,0x00,0x90,0xc4,0x00,0x00,0x27,0xbd,0xff,0xf8, +0x3c,0x03,0xb0,0x07,0x24,0x02,0xff,0x82,0xa3,0xa4,0x00,0x00,0xa0,0x62,0x00,0x00, +0x90,0x64,0x00,0x00,0x3c,0x02,0xb0,0x07,0x34,0x42,0x00,0x08,0xa3,0xa4,0x00,0x01, +0xa0,0x40,0x00,0x00,0x90,0x43,0x00,0x00,0x24,0x02,0x00,0x03,0x3c,0x05,0xb0,0x07, +0xa3,0xa3,0x00,0x00,0xa0,0xc2,0x00,0x00,0x90,0xc4,0x00,0x00,0x34,0xa5,0x00,0x10, +0x24,0x02,0x00,0x06,0x3c,0x03,0xb0,0x07,0xa3,0xa4,0x00,0x00,0x34,0x63,0x00,0x38, +0xa0,0xa2,0x00,0x00,0x90,0x64,0x00,0x00,0x3c,0x02,0xb0,0x07,0x34,0x42,0x00,0x20, +0xa3,0xa4,0x00,0x00,0xa0,0xa0,0x00,0x00,0x90,0xa3,0x00,0x00,0xaf,0x82,0xbf,0x30, +0xa3,0xa3,0x00,0x00,0xa0,0x40,0x00,0x00,0x90,0x43,0x00,0x00,0x03,0xe0,0x00,0x08, +0x27,0xbd,0x00,0x08,}; + +u8 Rtl8192PciEFwDataArray[DataArrayLengthPciE] = { +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x10,0x00,0x08,0x00, +0x02,0xe9,0x01,0x74,0x02,0xab,0x01,0xc7,0x01,0x55,0x00,0xe4,0x00,0xab,0x00,0x72, +0x00,0x55,0x00,0x4c,0x00,0x4c,0x00,0x4c,0x00,0x4c,0x00,0x4c,0x02,0x76,0x01,0x3b, +0x00,0xd2,0x00,0x9e,0x00,0x69,0x00,0x4f,0x00,0x46,0x00,0x3f,0x01,0x3b,0x00,0x9e, +0x00,0x69,0x00,0x4f,0x00,0x35,0x00,0x27,0x00,0x23,0x00,0x20,0x01,0x2f,0x00,0x98, +0x00,0x65,0x00,0x4c,0x00,0x33,0x00,0x26,0x00,0x22,0x00,0x1e,0x00,0x98,0x00,0x4c, +0x00,0x33,0x00,0x26,0x00,0x19,0x00,0x13,0x00,0x11,0x00,0x0f,0x02,0x39,0x01,0x1c, +0x00,0xbd,0x00,0x8e,0x00,0x5f,0x00,0x47,0x00,0x3f,0x00,0x39,0x01,0x1c,0x00,0x8e, +0x00,0x5f,0x00,0x47,0x00,0x2f,0x00,0x23,0x00,0x20,0x00,0x1c,0x01,0x11,0x00,0x89, +0x00,0x5b,0x00,0x44,0x00,0x2e,0x00,0x22,0x00,0x1e,0x00,0x1b,0x00,0x89,0x00,0x44, +0x00,0x2e,0x00,0x22,0x00,0x17,0x00,0x11,0x00,0x0f,0x00,0x0e,0x02,0xab,0x02,0xab, +0x02,0x66,0x02,0x66,0x07,0x06,0x06,0x06,0x05,0x06,0x07,0x08,0x04,0x06,0x07,0x08, +0x09,0x0a,0x0b,0x0b,0x49,0x6e,0x74,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x54,0x4c, +0x42,0x4d,0x4f,0x44,0x00,0x00,0x00,0x00,0x54,0x4c,0x42,0x4c,0x5f,0x64,0x61,0x74, +0x61,0x00,0x54,0x4c,0x42,0x53,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x64,0x45,0x4c, +0x5f,0x64,0x61,0x74,0x61,0x00,0x41,0x64,0x45,0x53,0x00,0x00,0x00,0x00,0x00,0x00, +0x45,0x78,0x63,0x43,0x6f,0x64,0x65,0x36,0x00,0x00,0x45,0x78,0x63,0x43,0x6f,0x64, +0x65,0x37,0x00,0x00,0x53,0x79,0x73,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x70, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x52,0x49,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x43,0x70,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x4f,0x76,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x01,0x0b,0x63, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x2c, +0x00,0x00,0x00,0x58,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x60, +0x00,0x00,0x00,0x90,0x00,0x00,0x00,0xc0,0x00,0x00,0x01,0x20,0x00,0x00,0x01,0x80, +0x00,0x00,0x01,0xb0,0x00,0x00,0x00,0x34,0x00,0x00,0x00,0x68,0x00,0x00,0x00,0x9c, +0x00,0x00,0x00,0xd0,0x00,0x00,0x01,0x38,0x00,0x00,0x01,0xa0,0x00,0x00,0x01,0xd4, +0x00,0x00,0x02,0x08,0x00,0x00,0x00,0x68,0x00,0x00,0x00,0xd0,0x00,0x00,0x01,0x38, +0x00,0x00,0x01,0xa0,0x00,0x00,0x02,0x6f,0x00,0x00,0x03,0x40,0x00,0x00,0x03,0xa8, +0x00,0x00,0x04,0x10,0x01,0x01,0x01,0x02,0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04, +0x01,0x01,0x02,0x02,0x03,0x03,0x04,0x04,0x02,0x03,0x03,0x04,0x05,0x06,0x07,0x08, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x07,0x6c,0x80,0x00,0x07,0x80, +0x80,0x00,0x07,0x80,0x80,0x00,0x07,0x70,0x80,0x00,0x07,0x70,0x80,0x00,0x07,0x94, +0x80,0x00,0x56,0xb0,0x80,0x00,0x57,0x08,0x80,0x00,0x57,0x30,0x80,0x00,0x58,0x28, +0x80,0x00,0x58,0xe0,0x80,0x00,0x59,0x88,0x80,0x00,0x59,0xfc,0x80,0x00,0x5b,0x08, +0x80,0x00,0x5b,0x40,0x80,0x00,0x5b,0x54,0x80,0x00,0x5b,0x68,0x80,0x00,0x5c,0x50, +0x80,0x00,0x5c,0x90,0x80,0x00,0x5d,0x44,0x80,0x00,0x5d,0x6c,0x80,0x00,0x56,0x70, +0x80,0x00,0x5d,0xbc,0x80,0x00,0x64,0x48,0x80,0x00,0x64,0xc0,0x80,0x00,0x64,0xcc, +0x80,0x00,0x64,0xd8,0x80,0x00,0x64,0x60,0x80,0x00,0x64,0x60,0x80,0x00,0x64,0x60, +0x80,0x00,0x64,0x60,0x80,0x00,0x64,0x60,0x80,0x00,0x64,0x60,0x80,0x00,0x64,0x60, +0x80,0x00,0x64,0x60,0x80,0x00,0x64,0x60,0x80,0x00,0x64,0x60,0x80,0x00,0x64,0x60, +0x80,0x00,0x64,0x60,0x80,0x00,0x64,0xe4,0x80,0x00,0x64,0xf0,0x80,0x00,0x64,0xfc, +0x80,0x00,0x87,0xa4,0x80,0x00,0x87,0xa4,0x80,0x00,0x87,0xa4,0x80,0x00,0x87,0xd8, +0x80,0x00,0x88,0x18,0x80,0x00,0x88,0x50,0x80,0x00,0x88,0x80,0x80,0x00,0x88,0xb0, +0x80,0x00,0x88,0xc4,0x80,0x00,0x89,0x2c,0x80,0x00,0x89,0x40,0x80,0x00,0x89,0x7c, +0x80,0x00,0x89,0x84,0x80,0x00,0x89,0xc0,0x80,0x00,0x89,0xd4,0x80,0x00,0x89,0xdc, +0x80,0x00,0x89,0xe4,0x80,0x00,0x89,0xe4,0x80,0x00,0x89,0xe4,0x80,0x00,0x89,0xe4, +0x80,0x00,0x8a,0x14,0x80,0x00,0x8a,0x28,0x80,0x00,0x8a,0x3c,0x80,0x00,0x86,0xe8, +0x80,0x00,0x8d,0x68,0x80,0x00,0x8d,0x68,0x80,0x00,0x8d,0x68,0x80,0x00,0x8d,0x9c, +0x80,0x00,0x8d,0xdc,0x80,0x00,0x8e,0x14,0x80,0x00,0x8e,0x44,0x80,0x00,0x8e,0x74, +0x80,0x00,0x8e,0x88,0x80,0x00,0x8e,0xf0,0x80,0x00,0x8f,0x04,0x80,0x00,0x8f,0x40, +0x80,0x00,0x8f,0x48,0x80,0x00,0x8f,0x84,0x80,0x00,0x8f,0x98,0x80,0x00,0x8f,0xa0, +0x80,0x00,0x8f,0xa8,0x80,0x00,0x8f,0xa8,0x80,0x00,0x8f,0xa8,0x80,0x00,0x8f,0xa8, +0x80,0x00,0x8f,0xd8,0x80,0x00,0x8f,0xec,0x80,0x00,0x90,0x00,0x80,0x00,0x8b,0x88, +}; + +u32 Rtl8192PciEPHY_REGArray[PHY_REGArrayLengthPciE] = {0x0,}; + +u32 Rtl8192PciEPHY_REG_1T2RArray[PHY_REG_1T2RArrayLengthPciE] = { + 0x800, 0x00000000, + 0x804, 0x00000001, + 0x808, 0x0000fc00, + 0x80c, 0x0000001c, + 0x810, 0x801010aa, + 0x814, 0x008514d0, + 0x818, 0x00000040, + 0x81c, 0x00000000, + 0x820, 0x00000004, + 0x824, 0x00690000, + 0x828, 0x00000004, + 0x82c, 0x00e90000, + 0x830, 0x00000004, + 0x834, 0x00690000, + 0x838, 0x00000004, + 0x83c, 0x00e90000, + 0x840, 0x00000000, + 0x844, 0x00000000, + 0x848, 0x00000000, + 0x84c, 0x00000000, + 0x850, 0x00000000, + 0x854, 0x00000000, + 0x858, 0x65a965a9, + 0x85c, 0x65a965a9, + 0x860, 0x001f0010, + 0x864, 0x007f0010, + 0x868, 0x001f0010, + 0x86c, 0x007f0010, + 0x870, 0x0f100f70, + 0x874, 0x0f100f70, + 0x878, 0x00000000, + 0x87c, 0x00000000, + 0x880, 0x6870e36c, + 0x884, 0xe3573600, + 0x888, 0x4260c340, + 0x88c, 0x0000ff00, + 0x890, 0x00000000, + 0x894, 0xfffffffe, + 0x898, 0x4c42382f, + 0x89c, 0x00656056, + 0x8b0, 0x00000000, + 0x8e0, 0x00000000, + 0x8e4, 0x00000000, + 0x900, 0x00000000, + 0x904, 0x00000023, + 0x908, 0x00000000, + 0x90c, 0x31121311, + 0xa00, 0x00d0c7d8, + 0xa04, 0x811f0008, + 0xa08, 0x80cd8300, + 0xa0c, 0x2e62740f, + 0xa10, 0x95009b78, + 0xa14, 0x11145008, + 0xa18, 0x00881117, + 0xa1c, 0x89140fa0, + 0xa20, 0x1a1b0000, + 0xa24, 0x090e1317, + 0xa28, 0x00000204, + 0xa2c, 0x00000000, + 0xc00, 0x00000040, + 0xc04, 0x00005433, + 0xc08, 0x000000e4, + 0xc0c, 0x6c6c6c6c, + 0xc10, 0x08800000, + 0xc14, 0x40000100, + 0xc18, 0x08000000, + 0xc1c, 0x40000100, + 0xc20, 0x08000000, + 0xc24, 0x40000100, + 0xc28, 0x08000000, + 0xc2c, 0x40000100, + 0xc30, 0x6de9ac44, + 0xc34, 0x465c52cd, + 0xc38, 0x497f5994, + 0xc3c, 0x0a969764, + 0xc40, 0x1f7c403f, + 0xc44, 0x000100b7, + 0xc48, 0xec020000, + 0xc4c, 0x00000300, + 0xc50, 0x69543420, + 0xc54, 0x433c0094, + 0xc58, 0x69543420, + 0xc5c, 0x433c0094, + 0xc60, 0x69543420, + 0xc64, 0x433c0094, + 0xc68, 0x69543420, + 0xc6c, 0x433c0094, + 0xc70, 0x2c7f000d, + 0xc74, 0x0186175b, + 0xc78, 0x0000001f, + 0xc7c, 0x00b91612, + 0xc80, 0x40000100, + 0xc84, 0x20000000, + 0xc88, 0x40000100, + 0xc8c, 0x20200000, + 0xc90, 0x40000100, + 0xc94, 0x00000000, + 0xc98, 0x40000100, + 0xc9c, 0x00000000, + 0xca0, 0x00492492, + 0xca4, 0x00000000, + 0xca8, 0x00000000, + 0xcac, 0x00000000, + 0xcb0, 0x00000000, + 0xcb4, 0x00000000, + 0xcb8, 0x00000000, + 0xcbc, 0x00492492, + 0xcc0, 0x00000000, + 0xcc4, 0x00000000, + 0xcc8, 0x00000000, + 0xccc, 0x00000000, + 0xcd0, 0x00000000, + 0xcd4, 0x00000000, + 0xcd8, 0x64b22427, + 0xcdc, 0x00766932, + 0xce0, 0x00222222, + 0xd00, 0x00000750, + 0xd04, 0x00000403, + 0xd08, 0x0000907f, + 0xd0c, 0x00000001, + 0xd10, 0xa0633333, + 0xd14, 0x33333c63, + 0xd18, 0x6a8f5b6b, + 0xd1c, 0x00000000, + 0xd20, 0x00000000, + 0xd24, 0x00000000, + 0xd28, 0x00000000, + 0xd2c, 0xcc979975, + 0xd30, 0x00000000, + 0xd34, 0x00000000, + 0xd38, 0x00000000, + 0xd3c, 0x00027293, + 0xd40, 0x00000000, + 0xd44, 0x00000000, + 0xd48, 0x00000000, + 0xd4c, 0x00000000, + 0xd50, 0x6437140a, + 0xd54, 0x024dbd02, + 0xd58, 0x00000000, + 0xd5c, 0x04032064, + 0xe00, 0x161a1a1a, + 0xe04, 0x12121416, + 0xe08, 0x00001800, + 0xe0c, 0x00000000, + 0xe10, 0x161a1a1a, + 0xe14, 0x12121416, + 0xe18, 0x161a1a1a, + 0xe1c, 0x12121416, +}; + +u32 Rtl8192PciERadioA_Array[RadioA_ArrayLengthPciE] = { + 0x019, 0x00000003, + 0x000, 0x000000bf, + 0x001, 0x00000ee0, + 0x002, 0x0000004c, + 0x003, 0x000007f1, + 0x004, 0x00000975, + 0x005, 0x00000c58, + 0x006, 0x00000ae6, + 0x007, 0x000000ca, + 0x008, 0x00000e1c, + 0x009, 0x000007f0, + 0x00a, 0x000009d0, + 0x00b, 0x000001ba, + 0x00c, 0x00000240, + 0x00e, 0x00000020, + 0x00f, 0x00000990, + 0x012, 0x00000806, + 0x014, 0x000005ab, + 0x015, 0x00000f80, + 0x016, 0x00000020, + 0x017, 0x00000597, + 0x018, 0x0000050a, + 0x01a, 0x00000f80, + 0x01b, 0x00000f5e, + 0x01c, 0x00000008, + 0x01d, 0x00000607, + 0x01e, 0x000006cc, + 0x01f, 0x00000000, + 0x020, 0x000001a5, + 0x01f, 0x00000001, + 0x020, 0x00000165, + 0x01f, 0x00000002, + 0x020, 0x000000c6, + 0x01f, 0x00000003, + 0x020, 0x00000086, + 0x01f, 0x00000004, + 0x020, 0x00000046, + 0x01f, 0x00000005, + 0x020, 0x000001e6, + 0x01f, 0x00000006, + 0x020, 0x000001a6, + 0x01f, 0x00000007, + 0x020, 0x00000166, + 0x01f, 0x00000008, + 0x020, 0x000000c7, + 0x01f, 0x00000009, + 0x020, 0x00000087, + 0x01f, 0x0000000a, + 0x020, 0x000000f7, + 0x01f, 0x0000000b, + 0x020, 0x000000d7, + 0x01f, 0x0000000c, + 0x020, 0x000000b7, + 0x01f, 0x0000000d, + 0x020, 0x00000097, + 0x01f, 0x0000000e, + 0x020, 0x00000077, + 0x01f, 0x0000000f, + 0x020, 0x00000057, + 0x01f, 0x00000010, + 0x020, 0x00000037, + 0x01f, 0x00000011, + 0x020, 0x000000fb, + 0x01f, 0x00000012, + 0x020, 0x000000db, + 0x01f, 0x00000013, + 0x020, 0x000000bb, + 0x01f, 0x00000014, + 0x020, 0x000000ff, + 0x01f, 0x00000015, + 0x020, 0x000000e3, + 0x01f, 0x00000016, + 0x020, 0x000000c3, + 0x01f, 0x00000017, + 0x020, 0x000000a3, + 0x01f, 0x00000018, + 0x020, 0x00000083, + 0x01f, 0x00000019, + 0x020, 0x00000063, + 0x01f, 0x0000001a, + 0x020, 0x00000043, + 0x01f, 0x0000001b, + 0x020, 0x00000023, + 0x01f, 0x0000001c, + 0x020, 0x00000003, + 0x01f, 0x0000001d, + 0x020, 0x000001e3, + 0x01f, 0x0000001e, + 0x020, 0x000001c3, + 0x01f, 0x0000001f, + 0x020, 0x000001a3, + 0x01f, 0x00000020, + 0x020, 0x00000183, + 0x01f, 0x00000021, + 0x020, 0x00000163, + 0x01f, 0x00000022, + 0x020, 0x00000143, + 0x01f, 0x00000023, + 0x020, 0x00000123, + 0x01f, 0x00000024, + 0x020, 0x00000103, + 0x023, 0x00000203, + 0x024, 0x00000100, + 0x00b, 0x000001ba, + 0x02c, 0x000003d7, + 0x02d, 0x00000ff0, + 0x000, 0x00000037, + 0x004, 0x00000160, + 0x007, 0x00000080, + 0x002, 0x0000088d, + 0x0fe, 0x00000000, + 0x0fe, 0x00000000, + 0x016, 0x00000200, + 0x016, 0x00000380, + 0x016, 0x00000020, + 0x016, 0x000001a0, + 0x000, 0x000000bf, + 0x00d, 0x0000001f, + 0x00d, 0x00000c9f, + 0x002, 0x0000004d, + 0x000, 0x00000cbf, + 0x004, 0x00000975, + 0x007, 0x00000700, +}; + +u32 Rtl8192PciERadioB_Array[RadioB_ArrayLengthPciE] = { + 0x019, 0x00000003, + 0x000, 0x000000bf, + 0x001, 0x000006e0, + 0x002, 0x0000004c, + 0x003, 0x000007f1, + 0x004, 0x00000975, + 0x005, 0x00000c58, + 0x006, 0x00000ae6, + 0x007, 0x000000ca, + 0x008, 0x00000e1c, + 0x000, 0x000000b7, + 0x00a, 0x00000850, + 0x000, 0x000000bf, + 0x00b, 0x000001ba, + 0x00c, 0x00000240, + 0x00e, 0x00000020, + 0x015, 0x00000f80, + 0x016, 0x00000020, + 0x017, 0x00000597, + 0x018, 0x0000050a, + 0x01a, 0x00000e00, + 0x01b, 0x00000f5e, + 0x01d, 0x00000607, + 0x01e, 0x000006cc, + 0x00b, 0x000001ba, + 0x023, 0x00000203, + 0x024, 0x00000100, + 0x000, 0x00000037, + 0x004, 0x00000160, + 0x016, 0x00000200, + 0x016, 0x00000380, + 0x016, 0x00000020, + 0x016, 0x000001a0, + 0x00d, 0x00000ccc, + 0x000, 0x000000bf, + 0x002, 0x0000004d, + 0x000, 0x00000cbf, + 0x004, 0x00000975, + 0x007, 0x00000700, +}; + +u32 Rtl8192PciERadioC_Array[RadioC_ArrayLengthPciE] = { + 0x0, }; + +u32 Rtl8192PciERadioD_Array[RadioD_ArrayLengthPciE] = { + 0x0, }; + +u32 Rtl8192PciEMACPHY_Array[] = { + 0x03c, 0xffff0000, 0x00000f0f, + 0x340, 0xffffffff, 0x161a1a1a, + 0x344, 0xffffffff, 0x12121416, + 0x348, 0x0000ffff, 0x00001818, + 0x12c, 0xffffffff, 0x04000802, + 0x318, 0x00000fff, 0x00000100, +}; + +u32 Rtl8192PciEMACPHY_Array_PG[] = { + 0x03c, 0xffff0000, 0x00000f0f, + 0xe00, 0xffffffff, 0x06090909, + 0xe04, 0xffffffff, 0x00030306, + 0xe08, 0x0000ff00, 0x00000000, + 0xe10, 0xffffffff, 0x0a0c0d0f, + 0xe14, 0xffffffff, 0x06070809, + 0xe18, 0xffffffff, 0x0a0c0d0f, + 0xe1c, 0xffffffff, 0x06070809, + 0x12c, 0xffffffff, 0x04000802, + 0x318, 0x00000fff, 0x00000800, +}; + +u32 Rtl8192PciEAGCTAB_Array[AGCTAB_ArrayLengthPciE] = { + 0xc78, 0x7d000001, + 0xc78, 0x7d010001, + 0xc78, 0x7d020001, + 0xc78, 0x7d030001, + 0xc78, 0x7d040001, + 0xc78, 0x7d050001, + 0xc78, 0x7c060001, + 0xc78, 0x7b070001, + 0xc78, 0x7a080001, + 0xc78, 0x79090001, + 0xc78, 0x780a0001, + 0xc78, 0x770b0001, + 0xc78, 0x760c0001, + 0xc78, 0x750d0001, + 0xc78, 0x740e0001, + 0xc78, 0x730f0001, + 0xc78, 0x72100001, + 0xc78, 0x71110001, + 0xc78, 0x70120001, + 0xc78, 0x6f130001, + 0xc78, 0x6e140001, + 0xc78, 0x6d150001, + 0xc78, 0x6c160001, + 0xc78, 0x6b170001, + 0xc78, 0x6a180001, + 0xc78, 0x69190001, + 0xc78, 0x681a0001, + 0xc78, 0x671b0001, + 0xc78, 0x661c0001, + 0xc78, 0x651d0001, + 0xc78, 0x641e0001, + 0xc78, 0x491f0001, + 0xc78, 0x48200001, + 0xc78, 0x47210001, + 0xc78, 0x46220001, + 0xc78, 0x45230001, + 0xc78, 0x44240001, + 0xc78, 0x43250001, + 0xc78, 0x28260001, + 0xc78, 0x27270001, + 0xc78, 0x26280001, + 0xc78, 0x25290001, + 0xc78, 0x242a0001, + 0xc78, 0x232b0001, + 0xc78, 0x222c0001, + 0xc78, 0x212d0001, + 0xc78, 0x202e0001, + 0xc78, 0x0a2f0001, + 0xc78, 0x08300001, + 0xc78, 0x06310001, + 0xc78, 0x05320001, + 0xc78, 0x04330001, + 0xc78, 0x03340001, + 0xc78, 0x02350001, + 0xc78, 0x01360001, + 0xc78, 0x00370001, + 0xc78, 0x00380001, + 0xc78, 0x00390001, + 0xc78, 0x003a0001, + 0xc78, 0x003b0001, + 0xc78, 0x003c0001, + 0xc78, 0x003d0001, + 0xc78, 0x003e0001, + 0xc78, 0x003f0001, + 0xc78, 0x7d400001, + 0xc78, 0x7d410001, + 0xc78, 0x7d420001, + 0xc78, 0x7d430001, + 0xc78, 0x7d440001, + 0xc78, 0x7d450001, + 0xc78, 0x7c460001, + 0xc78, 0x7b470001, + 0xc78, 0x7a480001, + 0xc78, 0x79490001, + 0xc78, 0x784a0001, + 0xc78, 0x774b0001, + 0xc78, 0x764c0001, + 0xc78, 0x754d0001, + 0xc78, 0x744e0001, + 0xc78, 0x734f0001, + 0xc78, 0x72500001, + 0xc78, 0x71510001, + 0xc78, 0x70520001, + 0xc78, 0x6f530001, + 0xc78, 0x6e540001, + 0xc78, 0x6d550001, + 0xc78, 0x6c560001, + 0xc78, 0x6b570001, + 0xc78, 0x6a580001, + 0xc78, 0x69590001, + 0xc78, 0x685a0001, + 0xc78, 0x675b0001, + 0xc78, 0x665c0001, + 0xc78, 0x655d0001, + 0xc78, 0x645e0001, + 0xc78, 0x495f0001, + 0xc78, 0x48600001, + 0xc78, 0x47610001, + 0xc78, 0x46620001, + 0xc78, 0x45630001, + 0xc78, 0x44640001, + 0xc78, 0x43650001, + 0xc78, 0x28660001, + 0xc78, 0x27670001, + 0xc78, 0x26680001, + 0xc78, 0x25690001, + 0xc78, 0x246a0001, + 0xc78, 0x236b0001, + 0xc78, 0x226c0001, + 0xc78, 0x216d0001, + 0xc78, 0x206e0001, + 0xc78, 0x0a6f0001, + 0xc78, 0x08700001, + 0xc78, 0x06710001, + 0xc78, 0x05720001, + 0xc78, 0x04730001, + 0xc78, 0x03740001, + 0xc78, 0x02750001, + 0xc78, 0x01760001, + 0xc78, 0x00770001, + 0xc78, 0x00780001, + 0xc78, 0x00790001, + 0xc78, 0x007a0001, + 0xc78, 0x007b0001, + 0xc78, 0x007c0001, + 0xc78, 0x007d0001, + 0xc78, 0x007e0001, + 0xc78, 0x007f0001, + 0xc78, 0x2e00001e, + 0xc78, 0x2e01001e, + 0xc78, 0x2e02001e, + 0xc78, 0x2e03001e, + 0xc78, 0x2e04001e, + 0xc78, 0x2e05001e, + 0xc78, 0x3006001e, + 0xc78, 0x3407001e, + 0xc78, 0x3908001e, + 0xc78, 0x3c09001e, + 0xc78, 0x3f0a001e, + 0xc78, 0x420b001e, + 0xc78, 0x440c001e, + 0xc78, 0x450d001e, + 0xc78, 0x460e001e, + 0xc78, 0x460f001e, + 0xc78, 0x4710001e, + 0xc78, 0x4811001e, + 0xc78, 0x4912001e, + 0xc78, 0x4a13001e, + 0xc78, 0x4b14001e, + 0xc78, 0x4b15001e, + 0xc78, 0x4c16001e, + 0xc78, 0x4d17001e, + 0xc78, 0x4e18001e, + 0xc78, 0x4f19001e, + 0xc78, 0x4f1a001e, + 0xc78, 0x501b001e, + 0xc78, 0x511c001e, + 0xc78, 0x521d001e, + 0xc78, 0x521e001e, + 0xc78, 0x531f001e, + 0xc78, 0x5320001e, + 0xc78, 0x5421001e, + 0xc78, 0x5522001e, + 0xc78, 0x5523001e, + 0xc78, 0x5624001e, + 0xc78, 0x5725001e, + 0xc78, 0x5726001e, + 0xc78, 0x5827001e, + 0xc78, 0x5828001e, + 0xc78, 0x5929001e, + 0xc78, 0x592a001e, + 0xc78, 0x5a2b001e, + 0xc78, 0x5b2c001e, + 0xc78, 0x5c2d001e, + 0xc78, 0x5c2e001e, + 0xc78, 0x5d2f001e, + 0xc78, 0x5e30001e, + 0xc78, 0x5f31001e, + 0xc78, 0x6032001e, + 0xc78, 0x6033001e, + 0xc78, 0x6134001e, + 0xc78, 0x6235001e, + 0xc78, 0x6336001e, + 0xc78, 0x6437001e, + 0xc78, 0x6438001e, + 0xc78, 0x6539001e, + 0xc78, 0x663a001e, + 0xc78, 0x673b001e, + 0xc78, 0x673c001e, + 0xc78, 0x683d001e, + 0xc78, 0x693e001e, + 0xc78, 0x6a3f001e, +}; diff --git a/drivers/staging/rtl8192e/r8192E_hwimg.h b/drivers/staging/rtl8192e/r8192E_hwimg.h new file mode 100644 index 0000000..019836b --- /dev/null +++ b/drivers/staging/rtl8192e/r8192E_hwimg.h @@ -0,0 +1,51 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> +******************************************************************************/ +#ifndef __INC_HAL8192PciE_FW_IMG_H +#define __INC_HAL8192PciE_FW_IMG_H + +/*Created on 2008/11/18, 3: 7*/ + +#include <linux/types.h> + +#define BootArrayLengthPciE 344 +extern u8 Rtl8192PciEFwBootArray[BootArrayLengthPciE]; +#define MainArrayLengthPciE 43012 +extern u8 Rtl8192PciEFwMainArray[MainArrayLengthPciE]; +#define DataArrayLengthPciE 848 +extern u8 Rtl8192PciEFwDataArray[DataArrayLengthPciE]; +#define PHY_REGArrayLengthPciE 1 +extern u32 Rtl8192PciEPHY_REGArray[PHY_REGArrayLengthPciE]; +#define PHY_REG_1T2RArrayLengthPciE 296 +extern u32 Rtl8192PciEPHY_REG_1T2RArray[PHY_REG_1T2RArrayLengthPciE]; +#define RadioA_ArrayLengthPciE 246 +extern u32 Rtl8192PciERadioA_Array[RadioA_ArrayLengthPciE] ; +#define RadioB_ArrayLengthPciE 78 +extern u32 Rtl8192PciERadioB_Array[RadioB_ArrayLengthPciE] ; +#define RadioC_ArrayLengthPciE 2 +extern u32 Rtl8192PciERadioC_Array[RadioC_ArrayLengthPciE] ; +#define RadioD_ArrayLengthPciE 2 +extern u32 Rtl8192PciERadioD_Array[RadioD_ArrayLengthPciE] ; +#define MACPHY_ArrayLengthPciE 18 +extern u32 Rtl8192PciEMACPHY_Array[MACPHY_ArrayLengthPciE] ; +#define MACPHY_Array_PGLengthPciE 30 +extern u32 Rtl8192PciEMACPHY_Array_PG[MACPHY_Array_PGLengthPciE] ; +#define AGCTAB_ArrayLengthPciE 384 +extern u32 Rtl8192PciEAGCTAB_Array[AGCTAB_ArrayLengthPciE] ; + +#endif diff --git a/drivers/staging/rtl8192e/r8192E_phy.c b/drivers/staging/rtl8192e/r8192E_phy.c new file mode 100644 index 0000000..83e00d7 --- /dev/null +++ b/drivers/staging/rtl8192e/r8192E_phy.c @@ -0,0 +1,1633 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> +******************************************************************************/ + +#include "rtl_core.h" +#include "r8192E_hw.h" +#include "r8192E_phyreg.h" +#include "r8190P_rtl8256.h" +#include "r8192E_phy.h" +#include "rtl_dm.h" +#include "dot11d.h" + +#include "r8192E_hwimg.h" + +static u32 RF_CHANNEL_TABLE_ZEBRA[] = { + 0, + 0x085c, + 0x08dc, + 0x095c, + 0x09dc, + 0x0a5c, + 0x0adc, + 0x0b5c, + 0x0bdc, + 0x0c5c, + 0x0cdc, + 0x0d5c, + 0x0ddc, + 0x0e5c, + 0x0f72, +}; + +/*************************Define local function prototype**********************/ + +static u32 phy_FwRFSerialRead(struct net_device *dev, + enum rf90_radio_path eRFPath, + u32 Offset); +static void phy_FwRFSerialWrite(struct net_device *dev, + enum rf90_radio_path eRFPath, + u32 Offset, u32 Data); + +static u32 rtl8192_CalculateBitShift(u32 dwBitMask) +{ + u32 i; + for (i = 0; i <= 31; i++) { + if (((dwBitMask >> i) & 0x1) == 1) + break; + } + return i; +} + +u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device *dev, u32 eRFPath) +{ + u8 ret = 1; + struct r8192_priv *priv = rtllib_priv(dev); + if (priv->rf_type == RF_2T4R) + ret = 0; + else if (priv->rf_type == RF_1T2R) { + if (eRFPath == RF90_PATH_A || eRFPath == RF90_PATH_B) + ret = 1; + else if (eRFPath == RF90_PATH_C || eRFPath == RF90_PATH_D) + ret = 0; + } + return ret; +} + +void rtl8192_setBBreg(struct net_device *dev, u32 dwRegAddr, u32 dwBitMask, + u32 dwData) +{ + + u32 OriginalValue, BitShift, NewValue; + + if (dwBitMask != bMaskDWord) { + OriginalValue = read_nic_dword(dev, dwRegAddr); + BitShift = rtl8192_CalculateBitShift(dwBitMask); + NewValue = (((OriginalValue) & (~dwBitMask)) | + (dwData << BitShift)); + write_nic_dword(dev, dwRegAddr, NewValue); + } else + write_nic_dword(dev, dwRegAddr, dwData); + return; +} + +u32 rtl8192_QueryBBReg(struct net_device *dev, u32 dwRegAddr, u32 dwBitMask) +{ + u32 Ret = 0, OriginalValue, BitShift; + + OriginalValue = read_nic_dword(dev, dwRegAddr); + BitShift = rtl8192_CalculateBitShift(dwBitMask); + Ret = (OriginalValue & dwBitMask) >> BitShift; + + return Ret; +} +static u32 rtl8192_phy_RFSerialRead(struct net_device *dev, + enum rf90_radio_path eRFPath, u32 Offset) +{ + struct r8192_priv *priv = rtllib_priv(dev); + u32 ret = 0; + u32 NewOffset = 0; + struct bb_reg_definition *pPhyReg = &priv->PHYRegDef[eRFPath]; + Offset &= 0x3f; + + if (priv->rf_chip == RF_8256) { + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0x0); + if (Offset >= 31) { + priv->RfReg0Value[eRFPath] |= 0x140; + rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, + bMaskDWord, + (priv->RfReg0Value[eRFPath]<<16)); + NewOffset = Offset - 30; + } else if (Offset >= 16) { + priv->RfReg0Value[eRFPath] |= 0x100; + priv->RfReg0Value[eRFPath] &= (~0x40); + rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, + bMaskDWord, + (priv->RfReg0Value[eRFPath]<<16)); + + NewOffset = Offset - 15; + } else + NewOffset = Offset; + } else { + RT_TRACE((COMP_PHY|COMP_ERR), "check RF type here, need" + " to be 8256\n"); + NewOffset = Offset; + } + rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, bLSSIReadAddress, + NewOffset); + rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, bLSSIReadEdge, 0x0); + rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, bLSSIReadEdge, 0x1); + + mdelay(1); + + ret = rtl8192_QueryBBReg(dev, pPhyReg->rfLSSIReadBack, + bLSSIReadBackData); + + if (priv->rf_chip == RF_8256) { + priv->RfReg0Value[eRFPath] &= 0xebf; + + rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, + (priv->RfReg0Value[eRFPath] << 16)); + + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300, 0x3); + } + + + return ret; + +} + +static void rtl8192_phy_RFSerialWrite(struct net_device *dev, + enum rf90_radio_path eRFPath, u32 Offset, + u32 Data) +{ + struct r8192_priv *priv = rtllib_priv(dev); + u32 DataAndAddr = 0, NewOffset = 0; + struct bb_reg_definition *pPhyReg = &priv->PHYRegDef[eRFPath]; + + Offset &= 0x3f; + if (priv->rf_chip == RF_8256) { + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0x0); + + if (Offset >= 31) { + priv->RfReg0Value[eRFPath] |= 0x140; + rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, + bMaskDWord, + (priv->RfReg0Value[eRFPath] << 16)); + NewOffset = Offset - 30; + } else if (Offset >= 16) { + priv->RfReg0Value[eRFPath] |= 0x100; + priv->RfReg0Value[eRFPath] &= (~0x40); + rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, + bMaskDWord, + (priv->RfReg0Value[eRFPath] << 16)); + NewOffset = Offset - 15; + } else + NewOffset = Offset; + } else { + RT_TRACE((COMP_PHY|COMP_ERR), "check RF type here, need to be" + " 8256\n"); + NewOffset = Offset; + } + + DataAndAddr = (Data<<16) | (NewOffset&0x3f); + + rtl8192_setBBreg(dev, pPhyReg->rf3wireOffset, bMaskDWord, DataAndAddr); + + if (Offset == 0x0) + priv->RfReg0Value[eRFPath] = Data; + + if (priv->rf_chip == RF_8256) { + if (Offset != 0) { + priv->RfReg0Value[eRFPath] &= 0xebf; + rtl8192_setBBreg( + dev, + pPhyReg->rf3wireOffset, + bMaskDWord, + (priv->RfReg0Value[eRFPath] << 16)); + } + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300, 0x3); + } + return; +} + +void rtl8192_phy_SetRFReg(struct net_device *dev, enum rf90_radio_path eRFPath, + u32 RegAddr, u32 BitMask, u32 Data) +{ + struct r8192_priv *priv = rtllib_priv(dev); + u32 Original_Value, BitShift, New_Value; + + if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath)) + return; + if (priv->rtllib->eRFPowerState != eRfOn && !priv->being_init_adapter) + return; + + RT_TRACE(COMP_PHY, "FW RF CTRL is not ready now\n"); + if (priv->Rf_Mode == RF_OP_By_FW) { + if (BitMask != bMask12Bits) { + Original_Value = phy_FwRFSerialRead(dev, eRFPath, + RegAddr); + BitShift = rtl8192_CalculateBitShift(BitMask); + New_Value = (((Original_Value) & (~BitMask)) | + (Data << BitShift)); + + phy_FwRFSerialWrite(dev, eRFPath, RegAddr, New_Value); + } else + phy_FwRFSerialWrite(dev, eRFPath, RegAddr, Data); + udelay(200); + + } else { + if (BitMask != bMask12Bits) { + Original_Value = rtl8192_phy_RFSerialRead(dev, eRFPath, + RegAddr); + BitShift = rtl8192_CalculateBitShift(BitMask); + New_Value = (((Original_Value) & (~BitMask)) | + (Data << BitShift)); + + rtl8192_phy_RFSerialWrite(dev, eRFPath, RegAddr, + New_Value); + } else + rtl8192_phy_RFSerialWrite(dev, eRFPath, RegAddr, Data); + } + return; +} + +u32 rtl8192_phy_QueryRFReg(struct net_device *dev, enum rf90_radio_path eRFPath, + u32 RegAddr, u32 BitMask) +{ + u32 Original_Value, Readback_Value, BitShift; + struct r8192_priv *priv = rtllib_priv(dev); + if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath)) + return 0; + if (priv->rtllib->eRFPowerState != eRfOn && !priv->being_init_adapter) + return 0; + down(&priv->rf_sem); + if (priv->Rf_Mode == RF_OP_By_FW) { + Original_Value = phy_FwRFSerialRead(dev, eRFPath, RegAddr); + udelay(200); + } else { + Original_Value = rtl8192_phy_RFSerialRead(dev, eRFPath, + RegAddr); + } + BitShift = rtl8192_CalculateBitShift(BitMask); + Readback_Value = (Original_Value & BitMask) >> BitShift; + up(&priv->rf_sem); + return Readback_Value; +} + +static u32 phy_FwRFSerialRead(struct net_device *dev, + enum rf90_radio_path eRFPath, u32 Offset) +{ + u32 retValue = 0; + u32 Data = 0; + u8 time = 0; + Data |= ((Offset & 0xFF) << 12); + Data |= ((eRFPath & 0x3) << 20); + Data |= 0x80000000; + while (read_nic_dword(dev, QPNR)&0x80000000) { + if (time++ < 100) + udelay(10); + else + break; + } + write_nic_dword(dev, QPNR, Data); + while (read_nic_dword(dev, QPNR) & 0x80000000) { + if (time++ < 100) + udelay(10); + else + return 0; + } + retValue = read_nic_dword(dev, RF_DATA); + + return retValue; + +} /* phy_FwRFSerialRead */ + +static void phy_FwRFSerialWrite(struct net_device *dev, + enum rf90_radio_path eRFPath, + u32 Offset, u32 Data) +{ + u8 time = 0; + + Data |= ((Offset & 0xFF) << 12); + Data |= ((eRFPath & 0x3) << 20); + Data |= 0x400000; + Data |= 0x80000000; + + while (read_nic_dword(dev, QPNR) & 0x80000000) { + if (time++ < 100) + udelay(10); + else + break; + } + write_nic_dword(dev, QPNR, Data); + +} /* phy_FwRFSerialWrite */ + + +void rtl8192_phy_configmac(struct net_device *dev) +{ + u32 dwArrayLen = 0, i = 0; + u32 *pdwArray = NULL; + struct r8192_priv *priv = rtllib_priv(dev); + + if (priv->bTXPowerDataReadFromEEPORM) { + RT_TRACE(COMP_PHY, "Rtl819XMACPHY_Array_PG\n"); + dwArrayLen = MACPHY_Array_PGLength; + pdwArray = Rtl819XMACPHY_Array_PG; + + } else { + RT_TRACE(COMP_PHY, "Read rtl819XMACPHY_Array\n"); + dwArrayLen = MACPHY_ArrayLength; + pdwArray = Rtl819XMACPHY_Array; + } + for (i = 0; i < dwArrayLen; i += 3) { + RT_TRACE(COMP_DBG, "The Rtl8190MACPHY_Array[0] is %x Rtl8190MAC" + "PHY_Array[1] is %x Rtl8190MACPHY_Array[2] is %x\n", + pdwArray[i], pdwArray[i+1], pdwArray[i+2]); + if (pdwArray[i] == 0x318) + pdwArray[i+2] = 0x00000800; + rtl8192_setBBreg(dev, pdwArray[i], pdwArray[i+1], + pdwArray[i+2]); + } + return; + +} + +void rtl8192_phyConfigBB(struct net_device *dev, u8 ConfigType) +{ + int i; + u32 *Rtl819XPHY_REGArray_Table = NULL; + u32 *Rtl819XAGCTAB_Array_Table = NULL; + u16 AGCTAB_ArrayLen, PHY_REGArrayLen = 0; + struct r8192_priv *priv = rtllib_priv(dev); + + AGCTAB_ArrayLen = AGCTAB_ArrayLength; + Rtl819XAGCTAB_Array_Table = Rtl819XAGCTAB_Array; + if (priv->rf_type == RF_2T4R) { + PHY_REGArrayLen = PHY_REGArrayLength; + Rtl819XPHY_REGArray_Table = Rtl819XPHY_REGArray; + } else if (priv->rf_type == RF_1T2R) { + PHY_REGArrayLen = PHY_REG_1T2RArrayLength; + Rtl819XPHY_REGArray_Table = Rtl819XPHY_REG_1T2RArray; + } + + if (ConfigType == BaseBand_Config_PHY_REG) { + for (i = 0; i < PHY_REGArrayLen; i += 2) { + rtl8192_setBBreg(dev, Rtl819XPHY_REGArray_Table[i], + bMaskDWord, + Rtl819XPHY_REGArray_Table[i+1]); + RT_TRACE(COMP_DBG, "i: %x, The Rtl819xUsbPHY_REGArray" + "[0] is %x Rtl819xUsbPHY_REGArray[1] is %x\n", + i, Rtl819XPHY_REGArray_Table[i], + Rtl819XPHY_REGArray_Table[i+1]); + } + } else if (ConfigType == BaseBand_Config_AGC_TAB) { + for (i = 0; i < AGCTAB_ArrayLen; i += 2) { + rtl8192_setBBreg(dev, Rtl819XAGCTAB_Array_Table[i], + bMaskDWord, + Rtl819XAGCTAB_Array_Table[i+1]); + RT_TRACE(COMP_DBG, "i:%x, The rtl819XAGCTAB_Array[0] " + "is %x rtl819XAGCTAB_Array[1] is %x\n", i, + Rtl819XAGCTAB_Array_Table[i], + Rtl819XAGCTAB_Array_Table[i+1]); + } + } + return; +} + +static void rtl8192_InitBBRFRegDef(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + priv->PHYRegDef[RF90_PATH_A].rfintfs = rFPGA0_XAB_RFInterfaceSW; + priv->PHYRegDef[RF90_PATH_B].rfintfs = rFPGA0_XAB_RFInterfaceSW; + priv->PHYRegDef[RF90_PATH_C].rfintfs = rFPGA0_XCD_RFInterfaceSW; + priv->PHYRegDef[RF90_PATH_D].rfintfs = rFPGA0_XCD_RFInterfaceSW; + + priv->PHYRegDef[RF90_PATH_A].rfintfi = rFPGA0_XAB_RFInterfaceRB; + priv->PHYRegDef[RF90_PATH_B].rfintfi = rFPGA0_XAB_RFInterfaceRB; + priv->PHYRegDef[RF90_PATH_C].rfintfi = rFPGA0_XCD_RFInterfaceRB; + priv->PHYRegDef[RF90_PATH_D].rfintfi = rFPGA0_XCD_RFInterfaceRB; + + priv->PHYRegDef[RF90_PATH_A].rfintfo = rFPGA0_XA_RFInterfaceOE; + priv->PHYRegDef[RF90_PATH_B].rfintfo = rFPGA0_XB_RFInterfaceOE; + priv->PHYRegDef[RF90_PATH_C].rfintfo = rFPGA0_XC_RFInterfaceOE; + priv->PHYRegDef[RF90_PATH_D].rfintfo = rFPGA0_XD_RFInterfaceOE; + + priv->PHYRegDef[RF90_PATH_A].rfintfe = rFPGA0_XA_RFInterfaceOE; + priv->PHYRegDef[RF90_PATH_B].rfintfe = rFPGA0_XB_RFInterfaceOE; + priv->PHYRegDef[RF90_PATH_C].rfintfe = rFPGA0_XC_RFInterfaceOE; + priv->PHYRegDef[RF90_PATH_D].rfintfe = rFPGA0_XD_RFInterfaceOE; + + priv->PHYRegDef[RF90_PATH_A].rf3wireOffset = rFPGA0_XA_LSSIParameter; + priv->PHYRegDef[RF90_PATH_B].rf3wireOffset = rFPGA0_XB_LSSIParameter; + priv->PHYRegDef[RF90_PATH_C].rf3wireOffset = rFPGA0_XC_LSSIParameter; + priv->PHYRegDef[RF90_PATH_D].rf3wireOffset = rFPGA0_XD_LSSIParameter; + + priv->PHYRegDef[RF90_PATH_A].rfLSSI_Select = rFPGA0_XAB_RFParameter; + priv->PHYRegDef[RF90_PATH_B].rfLSSI_Select = rFPGA0_XAB_RFParameter; + priv->PHYRegDef[RF90_PATH_C].rfLSSI_Select = rFPGA0_XCD_RFParameter; + priv->PHYRegDef[RF90_PATH_D].rfLSSI_Select = rFPGA0_XCD_RFParameter; + + priv->PHYRegDef[RF90_PATH_A].rfTxGainStage = rFPGA0_TxGainStage; + priv->PHYRegDef[RF90_PATH_B].rfTxGainStage = rFPGA0_TxGainStage; + priv->PHYRegDef[RF90_PATH_C].rfTxGainStage = rFPGA0_TxGainStage; + priv->PHYRegDef[RF90_PATH_D].rfTxGainStage = rFPGA0_TxGainStage; + + priv->PHYRegDef[RF90_PATH_A].rfHSSIPara1 = rFPGA0_XA_HSSIParameter1; + priv->PHYRegDef[RF90_PATH_B].rfHSSIPara1 = rFPGA0_XB_HSSIParameter1; + priv->PHYRegDef[RF90_PATH_C].rfHSSIPara1 = rFPGA0_XC_HSSIParameter1; + priv->PHYRegDef[RF90_PATH_D].rfHSSIPara1 = rFPGA0_XD_HSSIParameter1; + + priv->PHYRegDef[RF90_PATH_A].rfHSSIPara2 = rFPGA0_XA_HSSIParameter2; + priv->PHYRegDef[RF90_PATH_B].rfHSSIPara2 = rFPGA0_XB_HSSIParameter2; + priv->PHYRegDef[RF90_PATH_C].rfHSSIPara2 = rFPGA0_XC_HSSIParameter2; + priv->PHYRegDef[RF90_PATH_D].rfHSSIPara2 = rFPGA0_XD_HSSIParameter2; + + priv->PHYRegDef[RF90_PATH_A].rfSwitchControl = rFPGA0_XAB_SwitchControl; + priv->PHYRegDef[RF90_PATH_B].rfSwitchControl = rFPGA0_XAB_SwitchControl; + priv->PHYRegDef[RF90_PATH_C].rfSwitchControl = rFPGA0_XCD_SwitchControl; + priv->PHYRegDef[RF90_PATH_D].rfSwitchControl = rFPGA0_XCD_SwitchControl; + + priv->PHYRegDef[RF90_PATH_A].rfAGCControl1 = rOFDM0_XAAGCCore1; + priv->PHYRegDef[RF90_PATH_B].rfAGCControl1 = rOFDM0_XBAGCCore1; + priv->PHYRegDef[RF90_PATH_C].rfAGCControl1 = rOFDM0_XCAGCCore1; + priv->PHYRegDef[RF90_PATH_D].rfAGCControl1 = rOFDM0_XDAGCCore1; + + priv->PHYRegDef[RF90_PATH_A].rfAGCControl2 = rOFDM0_XAAGCCore2; + priv->PHYRegDef[RF90_PATH_B].rfAGCControl2 = rOFDM0_XBAGCCore2; + priv->PHYRegDef[RF90_PATH_C].rfAGCControl2 = rOFDM0_XCAGCCore2; + priv->PHYRegDef[RF90_PATH_D].rfAGCControl2 = rOFDM0_XDAGCCore2; + + priv->PHYRegDef[RF90_PATH_A].rfRxIQImbalance = rOFDM0_XARxIQImbalance; + priv->PHYRegDef[RF90_PATH_B].rfRxIQImbalance = rOFDM0_XBRxIQImbalance; + priv->PHYRegDef[RF90_PATH_C].rfRxIQImbalance = rOFDM0_XCRxIQImbalance; + priv->PHYRegDef[RF90_PATH_D].rfRxIQImbalance = rOFDM0_XDRxIQImbalance; + + priv->PHYRegDef[RF90_PATH_A].rfRxAFE = rOFDM0_XARxAFE; + priv->PHYRegDef[RF90_PATH_B].rfRxAFE = rOFDM0_XBRxAFE; + priv->PHYRegDef[RF90_PATH_C].rfRxAFE = rOFDM0_XCRxAFE; + priv->PHYRegDef[RF90_PATH_D].rfRxAFE = rOFDM0_XDRxAFE; + + priv->PHYRegDef[RF90_PATH_A].rfTxIQImbalance = rOFDM0_XATxIQImbalance; + priv->PHYRegDef[RF90_PATH_B].rfTxIQImbalance = rOFDM0_XBTxIQImbalance; + priv->PHYRegDef[RF90_PATH_C].rfTxIQImbalance = rOFDM0_XCTxIQImbalance; + priv->PHYRegDef[RF90_PATH_D].rfTxIQImbalance = rOFDM0_XDTxIQImbalance; + + priv->PHYRegDef[RF90_PATH_A].rfTxAFE = rOFDM0_XATxAFE; + priv->PHYRegDef[RF90_PATH_B].rfTxAFE = rOFDM0_XBTxAFE; + priv->PHYRegDef[RF90_PATH_C].rfTxAFE = rOFDM0_XCTxAFE; + priv->PHYRegDef[RF90_PATH_D].rfTxAFE = rOFDM0_XDTxAFE; + + priv->PHYRegDef[RF90_PATH_A].rfLSSIReadBack = rFPGA0_XA_LSSIReadBack; + priv->PHYRegDef[RF90_PATH_B].rfLSSIReadBack = rFPGA0_XB_LSSIReadBack; + priv->PHYRegDef[RF90_PATH_C].rfLSSIReadBack = rFPGA0_XC_LSSIReadBack; + priv->PHYRegDef[RF90_PATH_D].rfLSSIReadBack = rFPGA0_XD_LSSIReadBack; + +} + +bool rtl8192_phy_checkBBAndRF(struct net_device *dev, + enum hw90_block CheckBlock, + enum rf90_radio_path eRFPath) +{ + bool ret = true; + u32 i, CheckTimes = 4, dwRegRead = 0; + u32 WriteAddr[4]; + u32 WriteData[] = {0xfffff027, 0xaa55a02f, 0x00000027, 0x55aa502f}; + + WriteAddr[HW90_BLOCK_MAC] = 0x100; + WriteAddr[HW90_BLOCK_PHY0] = 0x900; + WriteAddr[HW90_BLOCK_PHY1] = 0x800; + WriteAddr[HW90_BLOCK_RF] = 0x3; + RT_TRACE(COMP_PHY, "=======>%s(), CheckBlock:%d\n", __func__, + CheckBlock); + for (i = 0; i < CheckTimes; i++) { + switch (CheckBlock) { + case HW90_BLOCK_MAC: + RT_TRACE(COMP_ERR, "PHY_CheckBBRFOK(): Never Write " + "0x100 here!"); + break; + + case HW90_BLOCK_PHY0: + case HW90_BLOCK_PHY1: + write_nic_dword(dev, WriteAddr[CheckBlock], + WriteData[i]); + dwRegRead = read_nic_dword(dev, WriteAddr[CheckBlock]); + break; + + case HW90_BLOCK_RF: + WriteData[i] &= 0xfff; + rtl8192_phy_SetRFReg(dev, eRFPath, + WriteAddr[HW90_BLOCK_RF], + bMask12Bits, WriteData[i]); + mdelay(10); + dwRegRead = rtl8192_phy_QueryRFReg(dev, eRFPath, + WriteAddr[HW90_BLOCK_RF], + bMaskDWord); + mdelay(10); + break; + + default: + ret = false; + break; + } + + + if (dwRegRead != WriteData[i]) { + RT_TRACE(COMP_ERR, "====>error=====dwRegRead: %x, " + "WriteData: %x\n", dwRegRead, WriteData[i]); + ret = false; + break; + } + } + + return ret; +} + +static bool rtl8192_BB_Config_ParaFile(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + bool rtStatus = true; + u8 bRegValue = 0, eCheckItem = 0; + u32 dwRegValue = 0; + + bRegValue = read_nic_byte(dev, BB_GLOBAL_RESET); + write_nic_byte(dev, BB_GLOBAL_RESET, (bRegValue|BB_GLOBAL_RESET_BIT)); + + dwRegValue = read_nic_dword(dev, CPU_GEN); + write_nic_dword(dev, CPU_GEN, (dwRegValue&(~CPU_GEN_BB_RST))); + + for (eCheckItem = (enum hw90_block)HW90_BLOCK_PHY0; + eCheckItem <= HW90_BLOCK_PHY1; eCheckItem++) { + rtStatus = rtl8192_phy_checkBBAndRF(dev, + (enum hw90_block)eCheckItem, + (enum rf90_radio_path)0); + if (rtStatus != true) { + RT_TRACE((COMP_ERR | COMP_PHY), "PHY_RF8256_Config():" + "Check PHY%d Fail!!\n", eCheckItem-1); + return rtStatus; + } + } + rtl8192_setBBreg(dev, rFPGA0_RFMOD, bCCKEn|bOFDMEn, 0x0); + rtl8192_phyConfigBB(dev, BaseBand_Config_PHY_REG); + + dwRegValue = read_nic_dword(dev, CPU_GEN); + write_nic_dword(dev, CPU_GEN, (dwRegValue|CPU_GEN_BB_RST)); + + rtl8192_phyConfigBB(dev, BaseBand_Config_AGC_TAB); + + if (priv->IC_Cut > VERSION_8190_BD) { + if (priv->rf_type == RF_2T4R) + dwRegValue = (priv->AntennaTxPwDiff[2]<<8 | + priv->AntennaTxPwDiff[1]<<4 | + priv->AntennaTxPwDiff[0]); + else + dwRegValue = 0x0; + rtl8192_setBBreg(dev, rFPGA0_TxGainStage, + (bXBTxAGC|bXCTxAGC|bXDTxAGC), dwRegValue); + + + dwRegValue = priv->CrystalCap; + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, bXtalCap92x, + dwRegValue); + } + + return rtStatus; +} +bool rtl8192_BBConfig(struct net_device *dev) +{ + bool rtStatus = true; + + rtl8192_InitBBRFRegDef(dev); + rtStatus = rtl8192_BB_Config_ParaFile(dev); + return rtStatus; +} + +void rtl8192_phy_getTxPower(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + priv->MCSTxPowerLevelOriginalOffset[0] = + read_nic_dword(dev, rTxAGC_Rate18_06); + priv->MCSTxPowerLevelOriginalOffset[1] = + read_nic_dword(dev, rTxAGC_Rate54_24); + priv->MCSTxPowerLevelOriginalOffset[2] = + read_nic_dword(dev, rTxAGC_Mcs03_Mcs00); + priv->MCSTxPowerLevelOriginalOffset[3] = + read_nic_dword(dev, rTxAGC_Mcs07_Mcs04); + priv->MCSTxPowerLevelOriginalOffset[4] = + read_nic_dword(dev, rTxAGC_Mcs11_Mcs08); + priv->MCSTxPowerLevelOriginalOffset[5] = + read_nic_dword(dev, rTxAGC_Mcs15_Mcs12); + + priv->DefaultInitialGain[0] = read_nic_byte(dev, rOFDM0_XAAGCCore1); + priv->DefaultInitialGain[1] = read_nic_byte(dev, rOFDM0_XBAGCCore1); + priv->DefaultInitialGain[2] = read_nic_byte(dev, rOFDM0_XCAGCCore1); + priv->DefaultInitialGain[3] = read_nic_byte(dev, rOFDM0_XDAGCCore1); + RT_TRACE(COMP_INIT, "Default initial gain (c50=0x%x, c58=0x%x, " + "c60=0x%x, c68=0x%x)\n", + priv->DefaultInitialGain[0], priv->DefaultInitialGain[1], + priv->DefaultInitialGain[2], priv->DefaultInitialGain[3]); + + priv->framesync = read_nic_byte(dev, rOFDM0_RxDetector3); + priv->framesyncC34 = read_nic_dword(dev, rOFDM0_RxDetector2); + RT_TRACE(COMP_INIT, "Default framesync (0x%x) = 0x%x\n", + rOFDM0_RxDetector3, priv->framesync); + priv->SifsTime = read_nic_word(dev, SIFS); + return; +} + +void rtl8192_phy_setTxPower(struct net_device *dev, u8 channel) +{ + struct r8192_priv *priv = rtllib_priv(dev); + u8 powerlevel = 0, powerlevelOFDM24G = 0; + char ant_pwr_diff; + u32 u4RegValue; + + if (priv->epromtype == EEPROM_93C46) { + powerlevel = priv->TxPowerLevelCCK[channel-1]; + powerlevelOFDM24G = priv->TxPowerLevelOFDM24G[channel-1]; + } else if (priv->epromtype == EEPROM_93C56) { + if (priv->rf_type == RF_1T2R) { + powerlevel = priv->TxPowerLevelCCK_C[channel-1]; + powerlevelOFDM24G = priv->TxPowerLevelOFDM24G_C[channel-1]; + } else if (priv->rf_type == RF_2T4R) { + powerlevel = priv->TxPowerLevelCCK_A[channel-1]; + powerlevelOFDM24G = priv->TxPowerLevelOFDM24G_A[channel-1]; + + ant_pwr_diff = priv->TxPowerLevelOFDM24G_C[channel-1] + - priv->TxPowerLevelOFDM24G_A[channel-1]; + + priv->RF_C_TxPwDiff = ant_pwr_diff; + + ant_pwr_diff &= 0xf; + + priv->AntennaTxPwDiff[2] = 0; + priv->AntennaTxPwDiff[1] = (u8)(ant_pwr_diff); + priv->AntennaTxPwDiff[0] = 0; + + u4RegValue = (priv->AntennaTxPwDiff[2]<<8 | + priv->AntennaTxPwDiff[1]<<4 | + priv->AntennaTxPwDiff[0]); + + rtl8192_setBBreg(dev, rFPGA0_TxGainStage, + (bXBTxAGC|bXCTxAGC|bXDTxAGC), u4RegValue); + } + } + switch (priv->rf_chip) { + case RF_8225: + break; + case RF_8256: + PHY_SetRF8256CCKTxPower(dev, powerlevel); + PHY_SetRF8256OFDMTxPower(dev, powerlevelOFDM24G); + break; + case RF_8258: + break; + default: + RT_TRACE(COMP_ERR, "unknown rf chip in funtion %s()\n", + __func__); + break; + } + return; +} + +bool rtl8192_phy_RFConfig(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + bool rtStatus = true; + switch (priv->rf_chip) { + case RF_8225: + break; + case RF_8256: + rtStatus = PHY_RF8256_Config(dev); + break; + + case RF_8258: + break; + case RF_PSEUDO_11N: + break; + + default: + RT_TRACE(COMP_ERR, "error chip id\n"); + break; + } + return rtStatus; +} + +void rtl8192_phy_updateInitGain(struct net_device *dev) +{ + return; +} + +u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device *dev, + enum rf90_radio_path eRFPath) +{ + + int i; + u8 ret = 0; + + switch (eRFPath) { + case RF90_PATH_A: + for (i = 0; i < RadioA_ArrayLength; i += 2) { + if (Rtl819XRadioA_Array[i] == 0xfe) { + msleep(100); + continue; + } + rtl8192_phy_SetRFReg(dev, eRFPath, + Rtl819XRadioA_Array[i], + bMask12Bits, + Rtl819XRadioA_Array[i+1]); + + } + break; + case RF90_PATH_B: + for (i = 0; i < RadioB_ArrayLength; i += 2) { + if (Rtl819XRadioB_Array[i] == 0xfe) { + msleep(100); + continue; + } + rtl8192_phy_SetRFReg(dev, eRFPath, + Rtl819XRadioB_Array[i], + bMask12Bits, + Rtl819XRadioB_Array[i+1]); + + } + break; + case RF90_PATH_C: + for (i = 0; i < RadioC_ArrayLength; i += 2) { + if (Rtl819XRadioC_Array[i] == 0xfe) { + msleep(100); + continue; + } + rtl8192_phy_SetRFReg(dev, eRFPath, + Rtl819XRadioC_Array[i], + bMask12Bits, + Rtl819XRadioC_Array[i+1]); + + } + break; + case RF90_PATH_D: + for (i = 0; i < RadioD_ArrayLength; i += 2) { + if (Rtl819XRadioD_Array[i] == 0xfe) { + msleep(100); + continue; + } + rtl8192_phy_SetRFReg(dev, eRFPath, + Rtl819XRadioD_Array[i], bMask12Bits, + Rtl819XRadioD_Array[i+1]); + + } + break; + default: + break; + } + + return ret; + +} +static void rtl8192_SetTxPowerLevel(struct net_device *dev, u8 channel) +{ + struct r8192_priv *priv = rtllib_priv(dev); + u8 powerlevel = priv->TxPowerLevelCCK[channel-1]; + u8 powerlevelOFDM24G = priv->TxPowerLevelOFDM24G[channel-1]; + + switch (priv->rf_chip) { + case RF_8225: + break; + + case RF_8256: + PHY_SetRF8256CCKTxPower(dev, powerlevel); + PHY_SetRF8256OFDMTxPower(dev, powerlevelOFDM24G); + break; + + case RF_8258: + break; + default: + RT_TRACE(COMP_ERR, "unknown rf chip ID in rtl8192_SetTxPower" + "Level()\n"); + break; + } + return; +} + +static u8 rtl8192_phy_SetSwChnlCmdArray(struct sw_chnl_cmd *CmdTable, + u32 CmdTableIdx, u32 CmdTableSz, + enum sw_chnl_cmd_id CmdID, + u32 Para1, u32 Para2, u32 msDelay) +{ + struct sw_chnl_cmd *pCmd; + + if (CmdTable == NULL) { + RT_TRACE(COMP_ERR, "phy_SetSwChnlCmdArray(): CmdTable cannot " + "be NULL.\n"); + return false; + } + if (CmdTableIdx >= CmdTableSz) { + RT_TRACE(COMP_ERR, "phy_SetSwChnlCmdArray(): Access invalid" + " index, please check size of the table, CmdTableIdx:" + "%d, CmdTableSz:%d\n", + CmdTableIdx, CmdTableSz); + return false; + } + + pCmd = CmdTable + CmdTableIdx; + pCmd->CmdID = CmdID; + pCmd->Para1 = Para1; + pCmd->Para2 = Para2; + pCmd->msDelay = msDelay; + + return true; +} + +static u8 rtl8192_phy_SwChnlStepByStep(struct net_device *dev, u8 channel, + u8 *stage, u8 *step, u32 *delay) +{ + struct r8192_priv *priv = rtllib_priv(dev); + struct sw_chnl_cmd PreCommonCmd[MAX_PRECMD_CNT]; + u32 PreCommonCmdCnt; + struct sw_chnl_cmd PostCommonCmd[MAX_POSTCMD_CNT]; + u32 PostCommonCmdCnt; + struct sw_chnl_cmd RfDependCmd[MAX_RFDEPENDCMD_CNT]; + u32 RfDependCmdCnt; + struct sw_chnl_cmd *CurrentCmd = NULL; + u8 eRFPath; + + RT_TRACE(COMP_TRACE, "====>%s()====stage:%d, step:%d, channel:%d\n", + __func__, *stage, *step, channel); + + if (!IsLegalChannel(priv->rtllib, channel)) { + RT_TRACE(COMP_ERR, "=============>set to illegal channel:%d\n", + channel); + return true; + } + + { + PreCommonCmdCnt = 0; + rtl8192_phy_SetSwChnlCmdArray(PreCommonCmd, PreCommonCmdCnt++, + MAX_PRECMD_CNT, CmdID_SetTxPowerLevel, + 0, 0, 0); + rtl8192_phy_SetSwChnlCmdArray(PreCommonCmd, PreCommonCmdCnt++, + MAX_PRECMD_CNT, CmdID_End, 0, 0, 0); + + PostCommonCmdCnt = 0; + + rtl8192_phy_SetSwChnlCmdArray(PostCommonCmd, PostCommonCmdCnt++, + MAX_POSTCMD_CNT, CmdID_End, 0, 0, 0); + + RfDependCmdCnt = 0; + switch (priv->rf_chip) { + case RF_8225: + if (!(channel >= 1 && channel <= 14)) { + RT_TRACE(COMP_ERR, "illegal channel for Zebra " + "8225: %d\n", channel); + return false; + } + rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, + RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT, + CmdID_RF_WriteReg, rZebra1_Channel, + RF_CHANNEL_TABLE_ZEBRA[channel], 10); + rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, + RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT, + CmdID_End, 0, 0, 0); + break; + + case RF_8256: + if (!(channel >= 1 && channel <= 14)) { + RT_TRACE(COMP_ERR, "illegal channel for Zebra" + " 8256: %d\n", channel); + return false; + } + rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, + RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT, + CmdID_RF_WriteReg, rZebra1_Channel, channel, + 10); + rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, + RfDependCmdCnt++, + MAX_RFDEPENDCMD_CNT, + CmdID_End, 0, 0, 0); + break; + + case RF_8258: + break; + + default: + RT_TRACE(COMP_ERR, "Unknown RFChipID: %d\n", + priv->rf_chip); + return false; + break; + } + + + do { + switch (*stage) { + case 0: + CurrentCmd = &PreCommonCmd[*step]; + break; + case 1: + CurrentCmd = &RfDependCmd[*step]; + break; + case 2: + CurrentCmd = &PostCommonCmd[*step]; + break; + } + + if (CurrentCmd->CmdID == CmdID_End) { + if ((*stage) == 2) { + return true; + } else { + (*stage)++; + (*step) = 0; + continue; + } + } + + switch (CurrentCmd->CmdID) { + case CmdID_SetTxPowerLevel: + if (priv->IC_Cut > (u8)VERSION_8190_BD) + rtl8192_SetTxPowerLevel(dev, channel); + break; + case CmdID_WritePortUlong: + write_nic_dword(dev, CurrentCmd->Para1, + CurrentCmd->Para2); + break; + case CmdID_WritePortUshort: + write_nic_word(dev, CurrentCmd->Para1, + (u16)CurrentCmd->Para2); + break; + case CmdID_WritePortUchar: + write_nic_byte(dev, CurrentCmd->Para1, + (u8)CurrentCmd->Para2); + break; + case CmdID_RF_WriteReg: + for (eRFPath = 0; eRFPath < + priv->NumTotalRFPath; eRFPath++) + rtl8192_phy_SetRFReg(dev, + (enum rf90_radio_path)eRFPath, + CurrentCmd->Para1, bMask12Bits, + CurrentCmd->Para2<<7); + break; + default: + break; + } + + break; + } while (true); + } /*for (Number of RF paths)*/ + + (*delay) = CurrentCmd->msDelay; + (*step)++; + return false; +} + +static void rtl8192_phy_FinishSwChnlNow(struct net_device *dev, u8 channel) +{ + struct r8192_priv *priv = rtllib_priv(dev); + u32 delay = 0; + + while (!rtl8192_phy_SwChnlStepByStep(dev, channel, &priv->SwChnlStage, + &priv->SwChnlStep, &delay)) { + if (delay > 0) + msleep(delay); + if (IS_NIC_DOWN(priv)) + break; + } +} +void rtl8192_SwChnl_WorkItem(struct net_device *dev) +{ + + struct r8192_priv *priv = rtllib_priv(dev); + + RT_TRACE(COMP_TRACE, "==> SwChnlCallback819xUsbWorkItem()\n"); + + RT_TRACE(COMP_TRACE, "=====>--%s(), set chan:%d, priv:%p\n", __func__, + priv->chan, priv); + + rtl8192_phy_FinishSwChnlNow(dev , priv->chan); + + RT_TRACE(COMP_TRACE, "<== SwChnlCallback819xUsbWorkItem()\n"); +} + +u8 rtl8192_phy_SwChnl(struct net_device *dev, u8 channel) +{ + struct r8192_priv *priv = rtllib_priv(dev); + RT_TRACE(COMP_PHY, "=====>%s()\n", __func__); + if (IS_NIC_DOWN(priv)) { + RT_TRACE(COMP_ERR, "%s(): ERR !! driver is not up\n", __func__); + return false; + } + if (priv->SwChnlInProgress) + return false; + + + switch (priv->rtllib->mode) { + case WIRELESS_MODE_A: + case WIRELESS_MODE_N_5G: + if (channel <= 14) { + RT_TRACE(COMP_ERR, "WIRELESS_MODE_A but channel<=14"); + return false; + } + break; + case WIRELESS_MODE_B: + if (channel > 14) { + RT_TRACE(COMP_ERR, "WIRELESS_MODE_B but channel>14"); + return false; + } + break; + case WIRELESS_MODE_G: + case WIRELESS_MODE_N_24G: + if (channel > 14) { + RT_TRACE(COMP_ERR, "WIRELESS_MODE_G but channel>14"); + return false; + } + break; + } + + priv->SwChnlInProgress = true; + if (channel == 0) + channel = 1; + + priv->chan = channel; + + priv->SwChnlStage = 0; + priv->SwChnlStep = 0; + + if (!IS_NIC_DOWN(priv)) + rtl8192_SwChnl_WorkItem(dev); + priv->SwChnlInProgress = false; + return true; +} + +static void CCK_Tx_Power_Track_BW_Switch_TSSI(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + switch (priv->CurrentChannelBW) { + case HT_CHANNEL_WIDTH_20: + priv->CCKPresentAttentuation = + priv->CCKPresentAttentuation_20Mdefault + + priv->CCKPresentAttentuation_difference; + + if (priv->CCKPresentAttentuation > + (CCKTxBBGainTableLength-1)) + priv->CCKPresentAttentuation = + CCKTxBBGainTableLength-1; + if (priv->CCKPresentAttentuation < 0) + priv->CCKPresentAttentuation = 0; + + RT_TRACE(COMP_POWER_TRACKING, "20M, priv->CCKPresent" + "Attentuation = %d\n", + priv->CCKPresentAttentuation); + + if (priv->rtllib->current_network.channel == 14 && + !priv->bcck_in_ch14) { + priv->bcck_in_ch14 = true; + dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); + } else if (priv->rtllib->current_network.channel != + 14 && priv->bcck_in_ch14) { + priv->bcck_in_ch14 = false; + dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); + } else { + dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); + } + break; + + case HT_CHANNEL_WIDTH_20_40: + priv->CCKPresentAttentuation = + priv->CCKPresentAttentuation_40Mdefault + + priv->CCKPresentAttentuation_difference; + + RT_TRACE(COMP_POWER_TRACKING, "40M, priv->CCKPresent" + "Attentuation = %d\n", + priv->CCKPresentAttentuation); + if (priv->CCKPresentAttentuation > + (CCKTxBBGainTableLength - 1)) + priv->CCKPresentAttentuation = + CCKTxBBGainTableLength-1; + if (priv->CCKPresentAttentuation < 0) + priv->CCKPresentAttentuation = 0; + + if (priv->rtllib->current_network.channel == 14 && + !priv->bcck_in_ch14) { + priv->bcck_in_ch14 = true; + dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); + } else if (priv->rtllib->current_network.channel != 14 + && priv->bcck_in_ch14) { + priv->bcck_in_ch14 = false; + dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); + } else { + dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); + } + break; + } +} + +static void CCK_Tx_Power_Track_BW_Switch_ThermalMeter(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + if (priv->rtllib->current_network.channel == 14 && + !priv->bcck_in_ch14) + priv->bcck_in_ch14 = true; + else if (priv->rtllib->current_network.channel != 14 && + priv->bcck_in_ch14) + priv->bcck_in_ch14 = false; + + switch (priv->CurrentChannelBW) { + case HT_CHANNEL_WIDTH_20: + if (priv->Record_CCK_20Mindex == 0) + priv->Record_CCK_20Mindex = 6; + priv->CCK_index = priv->Record_CCK_20Mindex; + RT_TRACE(COMP_POWER_TRACKING, "20MHz, CCK_Tx_Power_Track_BW_" + "Switch_ThermalMeter(),CCK_index = %d\n", + priv->CCK_index); + break; + + case HT_CHANNEL_WIDTH_20_40: + priv->CCK_index = priv->Record_CCK_40Mindex; + RT_TRACE(COMP_POWER_TRACKING, "40MHz, CCK_Tx_Power_Track_BW_" + "Switch_ThermalMeter(), CCK_index = %d\n", + priv->CCK_index); + break; + } + dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); +} + +static void CCK_Tx_Power_Track_BW_Switch(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + if (priv->IC_Cut >= IC_VersionCut_D) + CCK_Tx_Power_Track_BW_Switch_TSSI(dev); + else + CCK_Tx_Power_Track_BW_Switch_ThermalMeter(dev); +} + +void rtl8192_SetBWModeWorkItem(struct net_device *dev) +{ + + struct r8192_priv *priv = rtllib_priv(dev); + u8 regBwOpMode; + + RT_TRACE(COMP_SWBW, "==>rtl8192_SetBWModeWorkItem() Switch to %s " + "bandwidth\n", priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 ? + "20MHz" : "40MHz") + + + if (priv->rf_chip == RF_PSEUDO_11N) { + priv->SetBWModeInProgress = false; + return; + } + if (IS_NIC_DOWN(priv)) { + RT_TRACE(COMP_ERR, "%s(): ERR!! driver is not up\n", __func__); + return; + } + regBwOpMode = read_nic_byte(dev, BW_OPMODE); + + switch (priv->CurrentChannelBW) { + case HT_CHANNEL_WIDTH_20: + regBwOpMode |= BW_OPMODE_20MHZ; + write_nic_byte(dev, BW_OPMODE, regBwOpMode); + break; + + case HT_CHANNEL_WIDTH_20_40: + regBwOpMode &= ~BW_OPMODE_20MHZ; + write_nic_byte(dev, BW_OPMODE, regBwOpMode); + break; + + default: + RT_TRACE(COMP_ERR, "SetChannelBandwidth819xUsb(): unknown " + "Bandwidth: %#X\n", priv->CurrentChannelBW); + break; + } + + switch (priv->CurrentChannelBW) { + case HT_CHANNEL_WIDTH_20: + rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x0); + rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x0); + + if (!priv->btxpower_tracking) { + write_nic_dword(dev, rCCK0_TxFilter1, 0x1a1b0000); + write_nic_dword(dev, rCCK0_TxFilter2, 0x090e1317); + write_nic_dword(dev, rCCK0_DebugPort, 0x00000204); + } else { + CCK_Tx_Power_Track_BW_Switch(dev); + } + + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x00100000, 1); + + break; + case HT_CHANNEL_WIDTH_20_40: + rtl8192_setBBreg(dev, rFPGA0_RFMOD, bRFMOD, 0x1); + rtl8192_setBBreg(dev, rFPGA1_RFMOD, bRFMOD, 0x1); + + if (!priv->btxpower_tracking) { + write_nic_dword(dev, rCCK0_TxFilter1, 0x35360000); + write_nic_dword(dev, rCCK0_TxFilter2, 0x121c252e); + write_nic_dword(dev, rCCK0_DebugPort, 0x00000409); + } else { + CCK_Tx_Power_Track_BW_Switch(dev); + } + + rtl8192_setBBreg(dev, rCCK0_System, bCCKSideBand, + (priv->nCur40MhzPrimeSC>>1)); + rtl8192_setBBreg(dev, rOFDM1_LSTF, 0xC00, + priv->nCur40MhzPrimeSC); + + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x00100000, 0); + break; + default: + RT_TRACE(COMP_ERR, "SetChannelBandwidth819xUsb(): unknown " + "Bandwidth: %#X\n", priv->CurrentChannelBW); + break; + + } + + switch (priv->rf_chip) { + case RF_8225: + break; + + case RF_8256: + PHY_SetRF8256Bandwidth(dev, priv->CurrentChannelBW); + break; + + case RF_8258: + break; + + case RF_PSEUDO_11N: + break; + + default: + RT_TRACE(COMP_ERR, "Unknown RFChipID: %d\n", priv->rf_chip); + break; + } + + atomic_dec(&(priv->rtllib->atm_swbw)); + priv->SetBWModeInProgress = false; + + RT_TRACE(COMP_SWBW, "<==SetBWMode819xUsb()"); +} + +void rtl8192_SetBWMode(struct net_device *dev, enum ht_channel_width Bandwidth, + enum ht_extchnl_offset Offset) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + + if (priv->SetBWModeInProgress) + return; + + atomic_inc(&(priv->rtllib->atm_swbw)); + priv->SetBWModeInProgress = true; + + priv->CurrentChannelBW = Bandwidth; + + if (Offset == HT_EXTCHNL_OFFSET_LOWER) + priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_UPPER; + else if (Offset == HT_EXTCHNL_OFFSET_UPPER) + priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_LOWER; + else + priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_DONT_CARE; + + rtl8192_SetBWModeWorkItem(dev); + +} + +void InitialGain819xPci(struct net_device *dev, u8 Operation) +{ +#define SCAN_RX_INITIAL_GAIN 0x17 +#define POWER_DETECTION_TH 0x08 + struct r8192_priv *priv = rtllib_priv(dev); + u32 BitMask; + u8 initial_gain; + + if (!IS_NIC_DOWN(priv)) { + switch (Operation) { + case IG_Backup: + RT_TRACE(COMP_SCAN, "IG_Backup, backup the initial" + " gain.\n"); + initial_gain = SCAN_RX_INITIAL_GAIN; + BitMask = bMaskByte0; + if (dm_digtable.dig_algorithm == + DIG_ALGO_BY_FALSE_ALARM) + rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); + priv->initgain_backup.xaagccore1 = + (u8)rtl8192_QueryBBReg(dev, rOFDM0_XAAGCCore1, + BitMask); + priv->initgain_backup.xbagccore1 = + (u8)rtl8192_QueryBBReg(dev, rOFDM0_XBAGCCore1, + BitMask); + priv->initgain_backup.xcagccore1 = + (u8)rtl8192_QueryBBReg(dev, rOFDM0_XCAGCCore1, + BitMask); + priv->initgain_backup.xdagccore1 = + (u8)rtl8192_QueryBBReg(dev, rOFDM0_XDAGCCore1, + BitMask); + BitMask = bMaskByte2; + priv->initgain_backup.cca = (u8)rtl8192_QueryBBReg(dev, + rCCK0_CCA, BitMask); + + RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc50 is" + " %x\n", priv->initgain_backup.xaagccore1); + RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc58 is" + " %x\n", priv->initgain_backup.xbagccore1); + RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc60 is" + " %x\n", priv->initgain_backup.xcagccore1); + RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc68 is" + " %x\n", priv->initgain_backup.xdagccore1); + RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xa0a is" + " %x\n", priv->initgain_backup.cca); + + RT_TRACE(COMP_SCAN, "Write scan initial gain = 0x%x\n", + initial_gain); + write_nic_byte(dev, rOFDM0_XAAGCCore1, initial_gain); + write_nic_byte(dev, rOFDM0_XBAGCCore1, initial_gain); + write_nic_byte(dev, rOFDM0_XCAGCCore1, initial_gain); + write_nic_byte(dev, rOFDM0_XDAGCCore1, initial_gain); + RT_TRACE(COMP_SCAN, "Write scan 0xa0a = 0x%x\n", + POWER_DETECTION_TH); + write_nic_byte(dev, 0xa0a, POWER_DETECTION_TH); + break; + case IG_Restore: + RT_TRACE(COMP_SCAN, "IG_Restore, restore the initial " + "gain.\n"); + BitMask = 0x7f; + if (dm_digtable.dig_algorithm == + DIG_ALGO_BY_FALSE_ALARM) + rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); + + rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, BitMask, + (u32)priv->initgain_backup.xaagccore1); + rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, BitMask, + (u32)priv->initgain_backup.xbagccore1); + rtl8192_setBBreg(dev, rOFDM0_XCAGCCore1, BitMask, + (u32)priv->initgain_backup.xcagccore1); + rtl8192_setBBreg(dev, rOFDM0_XDAGCCore1, BitMask, + (u32)priv->initgain_backup.xdagccore1); + BitMask = bMaskByte2; + rtl8192_setBBreg(dev, rCCK0_CCA, BitMask, + (u32)priv->initgain_backup.cca); + + RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc50" + " is %x\n", priv->initgain_backup.xaagccore1); + RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc58" + " is %x\n", priv->initgain_backup.xbagccore1); + RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc60" + " is %x\n", priv->initgain_backup.xcagccore1); + RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc68" + " is %x\n", priv->initgain_backup.xdagccore1); + RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xa0a" + " is %x\n", priv->initgain_backup.cca); + + rtl8192_phy_setTxPower(dev, + priv->rtllib->current_network.channel); + + if (dm_digtable.dig_algorithm == + DIG_ALGO_BY_FALSE_ALARM) + rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1); + break; + default: + RT_TRACE(COMP_SCAN, "Unknown IG Operation.\n"); + break; + } + } +} + +void PHY_SetRtl8192eRfOff(struct net_device *dev) +{ + + rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x0); + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0x300, 0x0); + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x18, 0x0); + rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0xf, 0x0); + rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0xf, 0x0); + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x0); + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x4, 0x0); + write_nic_byte(dev, ANAPAR_FOR_8192PciE, 0x07); + +} + +static bool SetRFPowerState8190(struct net_device *dev, + enum rt_rf_power_state eRFPowerState) +{ + struct r8192_priv *priv = rtllib_priv(dev); + struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) + (&(priv->rtllib->PowerSaveControl)); + bool bResult = true; + u8 i = 0, QueueID = 0; + struct rtl8192_tx_ring *ring = NULL; + + if (priv->SetRFPowerStateInProgress == true) + return false; + RT_TRACE(COMP_PS, "===========> SetRFPowerState8190()!\n"); + priv->SetRFPowerStateInProgress = true; + + switch (priv->rf_chip) { + case RF_8256: + switch (eRFPowerState) { + case eRfOn: + RT_TRACE(COMP_PS, "SetRFPowerState8190() eRfOn!\n"); + if ((priv->rtllib->eRFPowerState == eRfOff) && + RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC)) { + bool rtstatus = true; + u32 InitilizeCount = 3; + do { + InitilizeCount--; + priv->RegRfOff = false; + rtstatus = NicIFEnableNIC(dev); + } while ((rtstatus != true) && + (InitilizeCount > 0)); + + if (rtstatus != true) { + RT_TRACE(COMP_ERR, "%s():Initialize Ada" + "pter fail,return\n", + __func__); + priv->SetRFPowerStateInProgress = false; + return false; + } + + RT_CLEAR_PS_LEVEL(pPSC, + RT_RF_OFF_LEVL_HALT_NIC); + } else { + write_nic_byte(dev, ANAPAR, 0x37); + mdelay(1); + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, + 0x4, 0x1); + priv->bHwRfOffAction = 0; + + rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, + BIT4, 0x1); + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, + 0x300, 0x3); + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, + 0x18, 0x3); + rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x3, + 0x3); + rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x3, + 0x3); + rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, + 0x60, 0x3); + + } + + break; + + case eRfSleep: + if (priv->rtllib->eRFPowerState == eRfOff) + break; + + + for (QueueID = 0, i = 0; QueueID < MAX_TX_QUEUE; ) { + ring = &priv->tx_ring[QueueID]; + + if (skb_queue_len(&ring->queue) == 0) { + QueueID++; + continue; + } else { + RT_TRACE((COMP_POWER|COMP_RF), "eRf Off" + "/Sleep: %d times TcbBusyQueue" + "[%d] !=0 before doze!\n", + (i+1), QueueID); + udelay(10); + i++; + } + + if (i >= MAX_DOZE_WAITING_TIMES_9x) { + RT_TRACE(COMP_POWER, "\n\n\n TimeOut!! " + "SetRFPowerState8190(): eRfOff" + ": %d times TcbBusyQueue[%d] " + "!= 0 !!!\n", + MAX_DOZE_WAITING_TIMES_9x, + QueueID); + break; + } + } + PHY_SetRtl8192eRfOff(dev); + break; + + case eRfOff: + RT_TRACE(COMP_PS, "SetRFPowerState8190() eRfOff/" + "Sleep !\n"); + + for (QueueID = 0, i = 0; QueueID < MAX_TX_QUEUE; ) { + ring = &priv->tx_ring[QueueID]; + + if (skb_queue_len(&ring->queue) == 0) { + QueueID++; + continue; + } else { + RT_TRACE(COMP_POWER, "eRf Off/Sleep: %d" + " times TcbBusyQueue[%d] !=0 b" + "efore doze!\n", (i+1), + QueueID); + udelay(10); + i++; + } + + if (i >= MAX_DOZE_WAITING_TIMES_9x) { + RT_TRACE(COMP_POWER, "\n\n\n SetZebra: " + "RFPowerState8185B(): eRfOff:" + " %d times TcbBusyQueue[%d] " + "!= 0 !!!\n", + MAX_DOZE_WAITING_TIMES_9x, + QueueID); + break; + } + } + + if (pPSC->RegRfPsLevel & RT_RF_OFF_LEVL_HALT_NIC && + !RT_IN_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC)) { + NicIFDisableNIC(dev); + RT_SET_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC); + } else if (!(pPSC->RegRfPsLevel & + RT_RF_OFF_LEVL_HALT_NIC)) { + PHY_SetRtl8192eRfOff(dev); + } + + break; + + default: + bResult = false; + RT_TRACE(COMP_ERR, "SetRFPowerState8190(): unknow state" + " to set: 0x%X!!!\n", eRFPowerState); + break; + } + + break; + + default: + RT_TRACE(COMP_ERR, "SetRFPowerState8190(): Unknown RF type\n"); + break; + } + + if (bResult) { + priv->rtllib->eRFPowerState = eRFPowerState; + + switch (priv->rf_chip) { + case RF_8256: + break; + + default: + RT_TRACE(COMP_ERR, "SetRFPowerState8190(): Unknown " + "RF type\n"); + break; + } + } + + priv->SetRFPowerStateInProgress = false; + RT_TRACE(COMP_PS, "<=========== SetRFPowerState8190() bResult = %d!\n", + bResult); + return bResult; +} + +bool SetRFPowerState(struct net_device *dev, + enum rt_rf_power_state eRFPowerState) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + bool bResult = false; + + RT_TRACE(COMP_PS, "---------> SetRFPowerState(): eRFPowerState(%d)\n", + eRFPowerState); + if (eRFPowerState == priv->rtllib->eRFPowerState && + priv->bHwRfOffAction == 0) { + RT_TRACE(COMP_PS, "<--------- SetRFPowerState(): discard the " + "request for eRFPowerState(%d) is the same.\n", + eRFPowerState); + return bResult; + } + + bResult = SetRFPowerState8190(dev, eRFPowerState); + + RT_TRACE(COMP_PS, "<--------- SetRFPowerState(): bResult(%d)\n", + bResult); + + return bResult; +} + +void PHY_ScanOperationBackup8192(struct net_device *dev, u8 Operation) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + if (priv->up) { + switch (Operation) { + case SCAN_OPT_BACKUP: + priv->rtllib->InitialGainHandler(dev, IG_Backup); + break; + + case SCAN_OPT_RESTORE: + priv->rtllib->InitialGainHandler(dev, IG_Restore); + break; + + default: + RT_TRACE(COMP_SCAN, "Unknown Scan Backup Operation.\n"); + break; + } + } + +} diff --git a/drivers/staging/rtl8192e/r8192E_phy.h b/drivers/staging/rtl8192e/r8192E_phy.h new file mode 100644 index 0000000..86c6acd --- /dev/null +++ b/drivers/staging/rtl8192e/r8192E_phy.h @@ -0,0 +1,144 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> +******************************************************************************/ +#ifndef _R819XU_PHY_H +#define _R819XU_PHY_H + +#define MAX_DOZE_WAITING_TIMES_9x 64 + +#define MAX_PRECMD_CNT 16 +#define MAX_RFDEPENDCMD_CNT 16 +#define MAX_POSTCMD_CNT 16 + +#define AGCTAB_ArrayLength AGCTAB_ArrayLengthPciE +#define MACPHY_ArrayLength MACPHY_ArrayLengthPciE +#define RadioA_ArrayLength RadioA_ArrayLengthPciE +#define RadioB_ArrayLength RadioB_ArrayLengthPciE +#define MACPHY_Array_PGLength MACPHY_Array_PGLengthPciE +#define RadioC_ArrayLength RadioC_ArrayLengthPciE +#define RadioD_ArrayLength RadioD_ArrayLengthPciE +#define PHY_REGArrayLength PHY_REGArrayLengthPciE +#define PHY_REG_1T2RArrayLength PHY_REG_1T2RArrayLengthPciE + +#define Rtl819XMACPHY_Array_PG Rtl8192PciEMACPHY_Array_PG +#define Rtl819XMACPHY_Array Rtl8192PciEMACPHY_Array +#define Rtl819XRadioA_Array Rtl8192PciERadioA_Array +#define Rtl819XRadioB_Array Rtl8192PciERadioB_Array +#define Rtl819XRadioC_Array Rtl8192PciERadioC_Array +#define Rtl819XRadioD_Array Rtl8192PciERadioD_Array +#define Rtl819XAGCTAB_Array Rtl8192PciEAGCTAB_Array +#define Rtl819XPHY_REGArray Rtl8192PciEPHY_REGArray +#define Rtl819XPHY_REG_1T2RArray Rtl8192PciEPHY_REG_1T2RArray + + + +enum sw_chnl_cmd_id { + CmdID_End, + CmdID_SetTxPowerLevel, + CmdID_BBRegWrite10, + CmdID_WritePortUlong, + CmdID_WritePortUshort, + CmdID_WritePortUchar, + CmdID_RF_WriteReg, +}; + +/*--------------------------------Define structure----------------------------*/ +struct sw_chnl_cmd { + enum sw_chnl_cmd_id CmdID; + u32 Para1; + u32 Para2; + u32 msDelay; +} __packed; + +extern u32 rtl819XMACPHY_Array_PG[]; +extern u32 rtl819XPHY_REG_1T2RArray[]; +extern u32 rtl819XAGCTAB_Array[]; +extern u32 rtl819XRadioA_Array[]; +extern u32 rtl819XRadioB_Array[]; +extern u32 rtl819XRadioC_Array[]; +extern u32 rtl819XRadioD_Array[]; + +enum hw90_block { + HW90_BLOCK_MAC = 0, + HW90_BLOCK_PHY0 = 1, + HW90_BLOCK_PHY1 = 2, + HW90_BLOCK_RF = 3, + HW90_BLOCK_MAXIMUM = 4, +}; + +enum rf90_radio_path { + RF90_PATH_A = 0, + RF90_PATH_B = 1, + RF90_PATH_C = 2, + RF90_PATH_D = 3, + RF90_PATH_MAX +}; + +#define bMaskByte0 0xff +#define bMaskByte1 0xff00 +#define bMaskByte2 0xff0000 +#define bMaskByte3 0xff000000 +#define bMaskHWord 0xffff0000 +#define bMaskLWord 0x0000ffff +#define bMaskDWord 0xffffffff + +extern u8 rtl8192_phy_CheckIsLegalRFPath(struct net_device *dev, + u32 eRFPath); +extern void rtl8192_setBBreg(struct net_device *dev, u32 dwRegAddr, + u32 dwBitMask, u32 dwData); +extern u32 rtl8192_QueryBBReg(struct net_device *dev, u32 dwRegAddr, + u32 dwBitMask); +extern void rtl8192_phy_SetRFReg(struct net_device *dev, + enum rf90_radio_path eRFPath, + u32 RegAddr, u32 BitMask, u32 Data); +extern u32 rtl8192_phy_QueryRFReg(struct net_device *dev, + enum rf90_radio_path eRFPath, + u32 RegAddr, u32 BitMask); +extern void rtl8192_phy_configmac(struct net_device *dev); +extern void rtl8192_phyConfigBB(struct net_device *dev, u8 ConfigType); +extern bool rtl8192_phy_checkBBAndRF(struct net_device *dev, + enum hw90_block CheckBlock, + enum rf90_radio_path eRFPath); +extern bool rtl8192_BBConfig(struct net_device *dev); +extern void rtl8192_phy_getTxPower(struct net_device *dev); +extern void rtl8192_phy_setTxPower(struct net_device *dev, u8 channel); +extern bool rtl8192_phy_RFConfig(struct net_device *dev); +extern void rtl8192_phy_updateInitGain(struct net_device *dev); +extern u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device *dev, + enum rf90_radio_path eRFPath); + +extern u8 rtl8192_phy_SwChnl(struct net_device *dev, u8 channel); +extern void rtl8192_SetBWMode(struct net_device *dev, + enum ht_channel_width Bandwidth, + enum ht_extchnl_offset Offset); +extern void rtl8192_SwChnl_WorkItem(struct net_device *dev); +extern void rtl8192_SetBWModeWorkItem(struct net_device *dev); +extern void InitialGain819xPci(struct net_device *dev, u8 Operation); + +extern void PHY_SetRtl8192eRfOff(struct net_device *dev); + +bool +SetRFPowerState( + struct net_device *dev, + enum rt_rf_power_state eRFPowerState + ); +#define PHY_SetRFPowerState SetRFPowerState + +extern void PHY_ScanOperationBackup8192(struct net_device *dev, u8 Operation); + +#endif diff --git a/drivers/staging/rtl8192e/r8192E_phyreg.h b/drivers/staging/rtl8192e/r8192E_phyreg.h new file mode 100644 index 0000000..7899dd5 --- /dev/null +++ b/drivers/staging/rtl8192e/r8192E_phyreg.h @@ -0,0 +1,852 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> +******************************************************************************/ +#ifndef _R819XU_PHYREG_H +#define _R819XU_PHYREG_H + + +#define RF_DATA 0x1d4 + +#define rPMAC_Reset 0x100 +#define rPMAC_TxStart 0x104 +#define rPMAC_TxLegacySIG 0x108 +#define rPMAC_TxHTSIG1 0x10c +#define rPMAC_TxHTSIG2 0x110 +#define rPMAC_PHYDebug 0x114 +#define rPMAC_TxPacketNum 0x118 +#define rPMAC_TxIdle 0x11c +#define rPMAC_TxMACHeader0 0x120 +#define rPMAC_TxMACHeader1 0x124 +#define rPMAC_TxMACHeader2 0x128 +#define rPMAC_TxMACHeader3 0x12c +#define rPMAC_TxMACHeader4 0x130 +#define rPMAC_TxMACHeader5 0x134 +#define rPMAC_TxDataType 0x138 +#define rPMAC_TxRandomSeed 0x13c +#define rPMAC_CCKPLCPPreamble 0x140 +#define rPMAC_CCKPLCPHeader 0x144 +#define rPMAC_CCKCRC16 0x148 +#define rPMAC_OFDMRxCRC32OK 0x170 +#define rPMAC_OFDMRxCRC32Er 0x174 +#define rPMAC_OFDMRxParityEr 0x178 +#define rPMAC_OFDMRxCRC8Er 0x17c +#define rPMAC_CCKCRxRC16Er 0x180 +#define rPMAC_CCKCRxRC32Er 0x184 +#define rPMAC_CCKCRxRC32OK 0x188 +#define rPMAC_TxStatus 0x18c + +#define MCS_TXAGC 0x340 +#define CCK_TXAGC 0x348 + +/*---------------------0x400~0x4ff----------------------*/ +#define MacBlkCtrl 0x403 + +#define rFPGA0_RFMOD 0x800 +#define rFPGA0_TxInfo 0x804 +#define rFPGA0_PSDFunction 0x808 +#define rFPGA0_TxGainStage 0x80c +#define rFPGA0_RFTiming1 0x810 +#define rFPGA0_RFTiming2 0x814 +#define rFPGA0_XA_HSSIParameter1 0x820 +#define rFPGA0_XA_HSSIParameter2 0x824 +#define rFPGA0_XB_HSSIParameter1 0x828 +#define rFPGA0_XB_HSSIParameter2 0x82c +#define rFPGA0_XC_HSSIParameter1 0x830 +#define rFPGA0_XC_HSSIParameter2 0x834 +#define rFPGA0_XD_HSSIParameter1 0x838 +#define rFPGA0_XD_HSSIParameter2 0x83c +#define rFPGA0_XA_LSSIParameter 0x840 +#define rFPGA0_XB_LSSIParameter 0x844 +#define rFPGA0_XC_LSSIParameter 0x848 +#define rFPGA0_XD_LSSIParameter 0x84c +#define rFPGA0_RFWakeUpParameter 0x850 +#define rFPGA0_RFSleepUpParameter 0x854 +#define rFPGA0_XAB_SwitchControl 0x858 +#define rFPGA0_XCD_SwitchControl 0x85c +#define rFPGA0_XA_RFInterfaceOE 0x860 +#define rFPGA0_XB_RFInterfaceOE 0x864 +#define rFPGA0_XC_RFInterfaceOE 0x868 +#define rFPGA0_XD_RFInterfaceOE 0x86c +#define rFPGA0_XAB_RFInterfaceSW 0x870 +#define rFPGA0_XCD_RFInterfaceSW 0x874 +#define rFPGA0_XAB_RFParameter 0x878 +#define rFPGA0_XCD_RFParameter 0x87c +#define rFPGA0_AnalogParameter1 0x880 +#define rFPGA0_AnalogParameter2 0x884 +#define rFPGA0_AnalogParameter3 0x888 +#define rFPGA0_AnalogParameter4 0x88c +#define rFPGA0_XA_LSSIReadBack 0x8a0 +#define rFPGA0_XB_LSSIReadBack 0x8a4 +#define rFPGA0_XC_LSSIReadBack 0x8a8 +#define rFPGA0_XD_LSSIReadBack 0x8ac +#define rFPGA0_PSDReport 0x8b4 +#define rFPGA0_XAB_RFInterfaceRB 0x8e0 +#define rFPGA0_XCD_RFInterfaceRB 0x8e4 + +#define rFPGA1_RFMOD 0x900 +#define rFPGA1_TxBlock 0x904 +#define rFPGA1_DebugSelect 0x908 +#define rFPGA1_TxInfo 0x90c + +#define rCCK0_System 0xa00 +#define rCCK0_AFESetting 0xa04 +#define rCCK0_CCA 0xa08 +#define rCCK0_RxAGC1 0xa0c +#define rCCK0_RxAGC2 0xa10 +#define rCCK0_RxHP 0xa14 +#define rCCK0_DSPParameter1 0xa18 +#define rCCK0_DSPParameter2 0xa1c +#define rCCK0_TxFilter1 0xa20 +#define rCCK0_TxFilter2 0xa24 +#define rCCK0_DebugPort 0xa28 +#define rCCK0_FalseAlarmReport 0xa2c +#define rCCK0_TRSSIReport 0xa50 +#define rCCK0_RxReport 0xa54 +#define rCCK0_FACounterLower 0xa5c +#define rCCK0_FACounterUpper 0xa58 + +#define rOFDM0_LSTF 0xc00 +#define rOFDM0_TRxPathEnable 0xc04 +#define rOFDM0_TRMuxPar 0xc08 +#define rOFDM0_TRSWIsolation 0xc0c +#define rOFDM0_XARxAFE 0xc10 +#define rOFDM0_XARxIQImbalance 0xc14 +#define rOFDM0_XBRxAFE 0xc18 +#define rOFDM0_XBRxIQImbalance 0xc1c +#define rOFDM0_XCRxAFE 0xc20 +#define rOFDM0_XCRxIQImbalance 0xc24 +#define rOFDM0_XDRxAFE 0xc28 +#define rOFDM0_XDRxIQImbalance 0xc2c +#define rOFDM0_RxDetector1 0xc30 +#define rOFDM0_RxDetector2 0xc34 +#define rOFDM0_RxDetector3 0xc38 +#define rOFDM0_RxDetector4 0xc3c +#define rOFDM0_RxDSP 0xc40 +#define rOFDM0_CFOandDAGC 0xc44 +#define rOFDM0_CCADropThreshold 0xc48 +#define rOFDM0_ECCAThreshold 0xc4c +#define rOFDM0_XAAGCCore1 0xc50 +#define rOFDM0_XAAGCCore2 0xc54 +#define rOFDM0_XBAGCCore1 0xc58 +#define rOFDM0_XBAGCCore2 0xc5c +#define rOFDM0_XCAGCCore1 0xc60 +#define rOFDM0_XCAGCCore2 0xc64 +#define rOFDM0_XDAGCCore1 0xc68 +#define rOFDM0_XDAGCCore2 0xc6c +#define rOFDM0_AGCParameter1 0xc70 +#define rOFDM0_AGCParameter2 0xc74 +#define rOFDM0_AGCRSSITable 0xc78 +#define rOFDM0_HTSTFAGC 0xc7c +#define rOFDM0_XATxIQImbalance 0xc80 +#define rOFDM0_XATxAFE 0xc84 +#define rOFDM0_XBTxIQImbalance 0xc88 +#define rOFDM0_XBTxAFE 0xc8c +#define rOFDM0_XCTxIQImbalance 0xc90 +#define rOFDM0_XCTxAFE 0xc94 +#define rOFDM0_XDTxIQImbalance 0xc98 +#define rOFDM0_XDTxAFE 0xc9c +#define rOFDM0_RxHPParameter 0xce0 +#define rOFDM0_TxPseudoNoiseWgt 0xce4 +#define rOFDM0_FrameSync 0xcf0 +#define rOFDM0_DFSReport 0xcf4 +#define rOFDM0_TxCoeff1 0xca4 +#define rOFDM0_TxCoeff2 0xca8 +#define rOFDM0_TxCoeff3 0xcac +#define rOFDM0_TxCoeff4 0xcb0 +#define rOFDM0_TxCoeff5 0xcb4 +#define rOFDM0_TxCoeff6 0xcb8 + + +#define rOFDM1_LSTF 0xd00 +#define rOFDM1_TRxPathEnable 0xd04 +#define rOFDM1_CFO 0xd08 +#define rOFDM1_CSI1 0xd10 +#define rOFDM1_SBD 0xd14 +#define rOFDM1_CSI2 0xd18 +#define rOFDM1_CFOTracking 0xd2c +#define rOFDM1_TRxMesaure1 0xd34 +#define rOFDM1_IntfDet 0xd3c +#define rOFDM1_PseudoNoiseStateAB 0xd50 +#define rOFDM1_PseudoNoiseStateCD 0xd54 +#define rOFDM1_RxPseudoNoiseWgt 0xd58 +#define rOFDM_PHYCounter1 0xda0 +#define rOFDM_PHYCounter2 0xda4 +#define rOFDM_PHYCounter3 0xda8 +#define rOFDM_ShortCFOAB 0xdac +#define rOFDM_ShortCFOCD 0xdb0 +#define rOFDM_LongCFOAB 0xdb4 +#define rOFDM_LongCFOCD 0xdb8 +#define rOFDM_TailCFOAB 0xdbc +#define rOFDM_TailCFOCD 0xdc0 +#define rOFDM_PWMeasure1 0xdc4 +#define rOFDM_PWMeasure2 0xdc8 +#define rOFDM_BWReport 0xdcc +#define rOFDM_AGCReport 0xdd0 +#define rOFDM_RxSNR 0xdd4 +#define rOFDM_RxEVMCSI 0xdd8 +#define rOFDM_SIGReport 0xddc + +#define rTxAGC_Rate18_06 0xe00 +#define rTxAGC_Rate54_24 0xe04 +#define rTxAGC_CCK_Mcs32 0xe08 +#define rTxAGC_Mcs03_Mcs00 0xe10 +#define rTxAGC_Mcs07_Mcs04 0xe14 +#define rTxAGC_Mcs11_Mcs08 0xe18 +#define rTxAGC_Mcs15_Mcs12 0xe1c + + +#define rZebra1_HSSIEnable 0x0 +#define rZebra1_TRxEnable1 0x1 +#define rZebra1_TRxEnable2 0x2 +#define rZebra1_AGC 0x4 +#define rZebra1_ChargePump 0x5 +#define rZebra1_Channel 0x7 +#define rZebra1_TxGain 0x8 +#define rZebra1_TxLPF 0x9 +#define rZebra1_RxLPF 0xb +#define rZebra1_RxHPFCorner 0xc + +#define rGlobalCtrl 0 +#define rRTL8256_TxLPF 19 +#define rRTL8256_RxLPF 11 + +#define rRTL8258_TxLPF 0x11 +#define rRTL8258_RxLPF 0x13 +#define rRTL8258_RSSILPF 0xa + +#define bBBResetB 0x100 +#define bGlobalResetB 0x200 +#define bOFDMTxStart 0x4 +#define bCCKTxStart 0x8 +#define bCRC32Debug 0x100 +#define bPMACLoopback 0x10 +#define bTxLSIG 0xffffff +#define bOFDMTxRate 0xf +#define bOFDMTxReserved 0x10 +#define bOFDMTxLength 0x1ffe0 +#define bOFDMTxParity 0x20000 +#define bTxHTSIG1 0xffffff +#define bTxHTMCSRate 0x7f +#define bTxHTBW 0x80 +#define bTxHTLength 0xffff00 +#define bTxHTSIG2 0xffffff +#define bTxHTSmoothing 0x1 +#define bTxHTSounding 0x2 +#define bTxHTReserved 0x4 +#define bTxHTAggreation 0x8 +#define bTxHTSTBC 0x30 +#define bTxHTAdvanceCoding 0x40 +#define bTxHTShortGI 0x80 +#define bTxHTNumberHT_LTF 0x300 +#define bTxHTCRC8 0x3fc00 +#define bCounterReset 0x10000 +#define bNumOfOFDMTx 0xffff +#define bNumOfCCKTx 0xffff0000 +#define bTxIdleInterval 0xffff +#define bOFDMService 0xffff0000 +#define bTxMACHeader 0xffffffff +#define bTxDataInit 0xff +#define bTxHTMode 0x100 +#define bTxDataType 0x30000 +#define bTxRandomSeed 0xffffffff +#define bCCKTxPreamble 0x1 +#define bCCKTxSFD 0xffff0000 +#define bCCKTxSIG 0xff +#define bCCKTxService 0xff00 +#define bCCKLengthExt 0x8000 +#define bCCKTxLength 0xffff0000 +#define bCCKTxCRC16 0xffff +#define bCCKTxStatus 0x1 +#define bOFDMTxStatus 0x2 + +#define bRFMOD 0x1 +#define bJapanMode 0x2 +#define bCCKTxSC 0x30 +#define bCCKEn 0x1000000 +#define bOFDMEn 0x2000000 +#define bOFDMRxADCPhase 0x10000 +#define bOFDMTxDACPhase 0x40000 +#define bXATxAGC 0x3f +#define bXBTxAGC 0xf00 +#define bXCTxAGC 0xf000 +#define bXDTxAGC 0xf0000 +#define bPAStart 0xf0000000 +#define bTRStart 0x00f00000 +#define bRFStart 0x0000f000 +#define bBBStart 0x000000f0 +#define bBBCCKStart 0x0000000f +#define bPAEnd 0xf +#define bTREnd 0x0f000000 +#define bRFEnd 0x000f0000 +#define bCCAMask 0x000000f0 +#define bR2RCCAMask 0x00000f00 +#define bHSSI_R2TDelay 0xf8000000 +#define bHSSI_T2RDelay 0xf80000 +#define bContTxHSSI 0x400 +#define bIGFromCCK 0x200 +#define bAGCAddress 0x3f +#define bRxHPTx 0x7000 +#define bRxHPT2R 0x38000 +#define bRxHPCCKIni 0xc0000 +#define bAGCTxCode 0xc00000 +#define bAGCRxCode 0x300000 +#define b3WireDataLength 0x800 +#define b3WireAddressLength 0x400 +#define b3WireRFPowerDown 0x1 +#define b5GPAPEPolarity 0x40000000 +#define b2GPAPEPolarity 0x80000000 +#define bRFSW_TxDefaultAnt 0x3 +#define bRFSW_TxOptionAnt 0x30 +#define bRFSW_RxDefaultAnt 0x300 +#define bRFSW_RxOptionAnt 0x3000 +#define bRFSI_3WireData 0x1 +#define bRFSI_3WireClock 0x2 +#define bRFSI_3WireLoad 0x4 +#define bRFSI_3WireRW 0x8 +#define bRFSI_3Wire 0xf +#define bRFSI_RFENV 0x10 +#define bRFSI_TRSW 0x20 +#define bRFSI_TRSWB 0x40 +#define bRFSI_ANTSW 0x100 +#define bRFSI_ANTSWB 0x200 +#define bRFSI_PAPE 0x400 +#define bRFSI_PAPE5G 0x800 +#define bBandSelect 0x1 +#define bHTSIG2_GI 0x80 +#define bHTSIG2_Smoothing 0x01 +#define bHTSIG2_Sounding 0x02 +#define bHTSIG2_Aggreaton 0x08 +#define bHTSIG2_STBC 0x30 +#define bHTSIG2_AdvCoding 0x40 +#define bHTSIG2_NumOfHTLTF 0x300 +#define bHTSIG2_CRC8 0x3fc +#define bHTSIG1_MCS 0x7f +#define bHTSIG1_BandWidth 0x80 +#define bHTSIG1_HTLength 0xffff +#define bLSIG_Rate 0xf +#define bLSIG_Reserved 0x10 +#define bLSIG_Length 0x1fffe +#define bLSIG_Parity 0x20 +#define bCCKRxPhase 0x4 +#define bLSSIReadAddress 0x3f000000 +#define bLSSIReadEdge 0x80000000 +#define bLSSIReadBackData 0xfff +#define bLSSIReadOKFlag 0x1000 +#define bCCKSampleRate 0x8 + +#define bRegulator0Standby 0x1 +#define bRegulatorPLLStandby 0x2 +#define bRegulator1Standby 0x4 +#define bPLLPowerUp 0x8 +#define bDPLLPowerUp 0x10 +#define bDA10PowerUp 0x20 +#define bAD7PowerUp 0x200 +#define bDA6PowerUp 0x2000 +#define bXtalPowerUp 0x4000 +#define b40MDClkPowerUP 0x8000 +#define bDA6DebugMode 0x20000 +#define bDA6Swing 0x380000 +#define bADClkPhase 0x4000000 +#define b80MClkDelay 0x18000000 +#define bAFEWatchDogEnable 0x20000000 +#define bXtalCap 0x0f000000 +#define bXtalCap01 0xc0000000 +#define bXtalCap23 0x3 +#define bXtalCap92x 0x0f000000 +#define bIntDifClkEnable 0x400 +#define bExtSigClkEnable 0x800 +#define bBandgapMbiasPowerUp 0x10000 +#define bAD11SHGain 0xc0000 +#define bAD11InputRange 0x700000 +#define bAD11OPCurrent 0x3800000 +#define bIPathLoopback 0x4000000 +#define bQPathLoopback 0x8000000 +#define bAFELoopback 0x10000000 +#define bDA10Swing 0x7e0 +#define bDA10Reverse 0x800 +#define bDAClkSource 0x1000 +#define bAD7InputRange 0x6000 +#define bAD7Gain 0x38000 +#define bAD7OutputCMMode 0x40000 +#define bAD7InputCMMode 0x380000 +#define bAD7Current 0xc00000 +#define bRegulatorAdjust 0x7000000 +#define bAD11PowerUpAtTx 0x1 +#define bDA10PSAtTx 0x10 +#define bAD11PowerUpAtRx 0x100 +#define bDA10PSAtRx 0x1000 + +#define bCCKRxAGCFormat 0x200 + +#define bPSDFFTSamplepPoint 0xc000 +#define bPSDAverageNum 0x3000 +#define bIQPathControl 0xc00 +#define bPSDFreq 0x3ff +#define bPSDAntennaPath 0x30 +#define bPSDIQSwitch 0x40 +#define bPSDRxTrigger 0x400000 +#define bPSDTxTrigger 0x80000000 +#define bPSDSineToneScale 0x7f000000 +#define bPSDReport 0xffff + +#define bOFDMTxSC 0x30000000 +#define bCCKTxOn 0x1 +#define bOFDMTxOn 0x2 +#define bDebugPage 0xfff +#define bDebugItem 0xff +#define bAntL 0x10 +#define bAntNonHT 0x100 +#define bAntHT1 0x1000 +#define bAntHT2 0x10000 +#define bAntHT1S1 0x100000 +#define bAntNonHTS1 0x1000000 + +#define bCCKBBMode 0x3 +#define bCCKTxPowerSaving 0x80 +#define bCCKRxPowerSaving 0x40 +#define bCCKSideBand 0x10 +#define bCCKScramble 0x8 +#define bCCKAntDiversity 0x8000 +#define bCCKCarrierRecovery 0x4000 +#define bCCKTxRate 0x3000 +#define bCCKDCCancel 0x0800 +#define bCCKISICancel 0x0400 +#define bCCKMatchFilter 0x0200 +#define bCCKEqualizer 0x0100 +#define bCCKPreambleDetect 0x800000 +#define bCCKFastFalseCCA 0x400000 +#define bCCKChEstStart 0x300000 +#define bCCKCCACount 0x080000 +#define bCCKcs_lim 0x070000 +#define bCCKBistMode 0x80000000 +#define bCCKCCAMask 0x40000000 +#define bCCKTxDACPhase 0x4 +#define bCCKRxADCPhase 0x20000000 +#define bCCKr_cp_mode0 0x0100 +#define bCCKTxDCOffset 0xf0 +#define bCCKRxDCOffset 0xf +#define bCCKCCAMode 0xc000 +#define bCCKFalseCS_lim 0x3f00 +#define bCCKCS_ratio 0xc00000 +#define bCCKCorgBit_sel 0x300000 +#define bCCKPD_lim 0x0f0000 +#define bCCKNewCCA 0x80000000 +#define bCCKRxHPofIG 0x8000 +#define bCCKRxIG 0x7f00 +#define bCCKLNAPolarity 0x800000 +#define bCCKRx1stGain 0x7f0000 +#define bCCKRFExtend 0x20000000 +#define bCCKRxAGCSatLevel 0x1f000000 +#define bCCKRxAGCSatCount 0xe0 +#define bCCKRxRFSettle 0x1f +#define bCCKFixedRxAGC 0x8000 +#define bCCKAntennaPolarity 0x2000 +#define bCCKTxFilterType 0x0c00 +#define bCCKRxAGCReportType 0x0300 +#define bCCKRxDAGCEn 0x80000000 +#define bCCKRxDAGCPeriod 0x20000000 +#define bCCKRxDAGCSatLevel 0x1f000000 +#define bCCKTimingRecovery 0x800000 +#define bCCKTxC0 0x3f0000 +#define bCCKTxC1 0x3f000000 +#define bCCKTxC2 0x3f +#define bCCKTxC3 0x3f00 +#define bCCKTxC4 0x3f0000 +#define bCCKTxC5 0x3f000000 +#define bCCKTxC6 0x3f +#define bCCKTxC7 0x3f00 +#define bCCKDebugPort 0xff0000 +#define bCCKDACDebug 0x0f000000 +#define bCCKFalseAlarmEnable 0x8000 +#define bCCKFalseAlarmRead 0x4000 +#define bCCKTRSSI 0x7f +#define bCCKRxAGCReport 0xfe +#define bCCKRxReport_AntSel 0x80000000 +#define bCCKRxReport_MFOff 0x40000000 +#define bCCKRxRxReport_SQLoss 0x20000000 +#define bCCKRxReport_Pktloss 0x10000000 +#define bCCKRxReport_Lockedbit 0x08000000 +#define bCCKRxReport_RateError 0x04000000 +#define bCCKRxReport_RxRate 0x03000000 +#define bCCKRxFACounterLower 0xff +#define bCCKRxFACounterUpper 0xff000000 +#define bCCKRxHPAGCStart 0xe000 +#define bCCKRxHPAGCFinal 0x1c00 + +#define bCCKRxFalseAlarmEnable 0x8000 +#define bCCKFACounterFreeze 0x4000 + +#define bCCKTxPathSel 0x10000000 +#define bCCKDefaultRxPath 0xc000000 +#define bCCKOptionRxPath 0x3000000 + +#define bNumOfSTF 0x3 +#define bShift_L 0xc0 +#define bGI_TH 0xc +#define bRxPathA 0x1 +#define bRxPathB 0x2 +#define bRxPathC 0x4 +#define bRxPathD 0x8 +#define bTxPathA 0x1 +#define bTxPathB 0x2 +#define bTxPathC 0x4 +#define bTxPathD 0x8 +#define bTRSSIFreq 0x200 +#define bADCBackoff 0x3000 +#define bDFIRBackoff 0xc000 +#define bTRSSILatchPhase 0x10000 +#define bRxIDCOffset 0xff +#define bRxQDCOffset 0xff00 +#define bRxDFIRMode 0x1800000 +#define bRxDCNFType 0xe000000 +#define bRXIQImb_A 0x3ff +#define bRXIQImb_B 0xfc00 +#define bRXIQImb_C 0x3f0000 +#define bRXIQImb_D 0xffc00000 +#define bDC_dc_Notch 0x60000 +#define bRxNBINotch 0x1f000000 +#define bPD_TH 0xf +#define bPD_TH_Opt2 0xc000 +#define bPWED_TH 0x700 +#define bIfMF_Win_L 0x800 +#define bPD_Option 0x1000 +#define bMF_Win_L 0xe000 +#define bBW_Search_L 0x30000 +#define bwin_enh_L 0xc0000 +#define bBW_TH 0x700000 +#define bED_TH2 0x3800000 +#define bBW_option 0x4000000 +#define bRatio_TH 0x18000000 +#define bWindow_L 0xe0000000 +#define bSBD_Option 0x1 +#define bFrame_TH 0x1c +#define bFS_Option 0x60 +#define bDC_Slope_check 0x80 +#define bFGuard_Counter_DC_L 0xe00 +#define bFrame_Weight_Short 0x7000 +#define bSub_Tune 0xe00000 +#define bFrame_DC_Length 0xe000000 +#define bSBD_start_offset 0x30000000 +#define bFrame_TH_2 0x7 +#define bFrame_GI2_TH 0x38 +#define bGI2_Sync_en 0x40 +#define bSarch_Short_Early 0x300 +#define bSarch_Short_Late 0xc00 +#define bSarch_GI2_Late 0x70000 +#define bCFOAntSum 0x1 +#define bCFOAcc 0x2 +#define bCFOStartOffset 0xc +#define bCFOLookBack 0x70 +#define bCFOSumWeight 0x80 +#define bDAGCEnable 0x10000 +#define bTXIQImb_A 0x3ff +#define bTXIQImb_B 0xfc00 +#define bTXIQImb_C 0x3f0000 +#define bTXIQImb_D 0xffc00000 +#define bTxIDCOffset 0xff +#define bTxQDCOffset 0xff00 +#define bTxDFIRMode 0x10000 +#define bTxPesudoNoiseOn 0x4000000 +#define bTxPesudoNoise_A 0xff +#define bTxPesudoNoise_B 0xff00 +#define bTxPesudoNoise_C 0xff0000 +#define bTxPesudoNoise_D 0xff000000 +#define bCCADropOption 0x20000 +#define bCCADropThres 0xfff00000 +#define bEDCCA_H 0xf +#define bEDCCA_L 0xf0 +#define bLambda_ED 0x300 +#define bRxInitialGain 0x7f +#define bRxAntDivEn 0x80 +#define bRxAGCAddressForLNA 0x7f00 +#define bRxHighPowerFlow 0x8000 +#define bRxAGCFreezeThres 0xc0000 +#define bRxFreezeStep_AGC1 0x300000 +#define bRxFreezeStep_AGC2 0xc00000 +#define bRxFreezeStep_AGC3 0x3000000 +#define bRxFreezeStep_AGC0 0xc000000 +#define bRxRssi_Cmp_En 0x10000000 +#define bRxQuickAGCEn 0x20000000 +#define bRxAGCFreezeThresMode 0x40000000 +#define bRxOverFlowCheckType 0x80000000 +#define bRxAGCShift 0x7f +#define bTRSW_Tri_Only 0x80 +#define bPowerThres 0x300 +#define bRxAGCEn 0x1 +#define bRxAGCTogetherEn 0x2 +#define bRxAGCMin 0x4 +#define bRxHP_Ini 0x7 +#define bRxHP_TRLNA 0x70 +#define bRxHP_RSSI 0x700 +#define bRxHP_BBP1 0x7000 +#define bRxHP_BBP2 0x70000 +#define bRxHP_BBP3 0x700000 +#define bRSSI_H 0x7f0000 +#define bRSSI_Gen 0x7f000000 +#define bRxSettle_TRSW 0x7 +#define bRxSettle_LNA 0x38 +#define bRxSettle_RSSI 0x1c0 +#define bRxSettle_BBP 0xe00 +#define bRxSettle_RxHP 0x7000 +#define bRxSettle_AntSW_RSSI 0x38000 +#define bRxSettle_AntSW 0xc0000 +#define bRxProcessTime_DAGC 0x300000 +#define bRxSettle_HSSI 0x400000 +#define bRxProcessTime_BBPPW 0x800000 +#define bRxAntennaPowerShift 0x3000000 +#define bRSSITableSelect 0xc000000 +#define bRxHP_Final 0x7000000 +#define bRxHTSettle_BBP 0x7 +#define bRxHTSettle_HSSI 0x8 +#define bRxHTSettle_RxHP 0x70 +#define bRxHTSettle_BBPPW 0x80 +#define bRxHTSettle_Idle 0x300 +#define bRxHTSettle_Reserved 0x1c00 +#define bRxHTRxHPEn 0x8000 +#define bRxHTAGCFreezeThres 0x30000 +#define bRxHTAGCTogetherEn 0x40000 +#define bRxHTAGCMin 0x80000 +#define bRxHTAGCEn 0x100000 +#define bRxHTDAGCEn 0x200000 +#define bRxHTRxHP_BBP 0x1c00000 +#define bRxHTRxHP_Final 0xe0000000 +#define bRxPWRatioTH 0x3 +#define bRxPWRatioEn 0x4 +#define bRxMFHold 0x3800 +#define bRxPD_Delay_TH1 0x38 +#define bRxPD_Delay_TH2 0x1c0 +#define bRxPD_DC_COUNT_MAX 0x600 +#define bRxPD_Delay_TH 0x8000 +#define bRxProcess_Delay 0xf0000 +#define bRxSearchrange_GI2_Early 0x700000 +#define bRxFrame_Guard_Counter_L 0x3800000 +#define bRxSGI_Guard_L 0xc000000 +#define bRxSGI_Search_L 0x30000000 +#define bRxSGI_TH 0xc0000000 +#define bDFSCnt0 0xff +#define bDFSCnt1 0xff00 +#define bDFSFlag 0xf0000 + +#define bMFWeightSum 0x300000 +#define bMinIdxTH 0x7f000000 + +#define bDAFormat 0x40000 + +#define bTxChEmuEnable 0x01000000 + +#define bTRSWIsolation_A 0x7f +#define bTRSWIsolation_B 0x7f00 +#define bTRSWIsolation_C 0x7f0000 +#define bTRSWIsolation_D 0x7f000000 + +#define bExtLNAGain 0x7c00 + +#define bSTBCEn 0x4 +#define bAntennaMapping 0x10 +#define bNss 0x20 +#define bCFOAntSumD 0x200 +#define bPHYCounterReset 0x8000000 +#define bCFOReportGet 0x4000000 +#define bOFDMContinueTx 0x10000000 +#define bOFDMSingleCarrier 0x20000000 +#define bOFDMSingleTone 0x40000000 +#define bHTDetect 0x100 +#define bCFOEn 0x10000 +#define bCFOValue 0xfff00000 +#define bSigTone_Re 0x3f +#define bSigTone_Im 0x7f00 +#define bCounter_CCA 0xffff +#define bCounter_ParityFail 0xffff0000 +#define bCounter_RateIllegal 0xffff +#define bCounter_CRC8Fail 0xffff0000 +#define bCounter_MCSNoSupport 0xffff +#define bCounter_FastSync 0xffff +#define bShortCFO 0xfff +#define bShortCFOTLength 12 +#define bShortCFOFLength 11 +#define bLongCFO 0x7ff +#define bLongCFOTLength 11 +#define bLongCFOFLength 11 +#define bTailCFO 0x1fff +#define bTailCFOTLength 13 +#define bTailCFOFLength 12 + +#define bmax_en_pwdB 0xffff +#define bCC_power_dB 0xffff0000 +#define bnoise_pwdB 0xffff +#define bPowerMeasTLength 10 +#define bPowerMeasFLength 3 +#define bRx_HT_BW 0x1 +#define bRxSC 0x6 +#define bRx_HT 0x8 + +#define bNB_intf_det_on 0x1 +#define bIntf_win_len_cfg 0x30 +#define bNB_Intf_TH_cfg 0x1c0 + +#define bRFGain 0x3f +#define bTableSel 0x40 +#define bTRSW 0x80 + +#define bRxSNR_A 0xff +#define bRxSNR_B 0xff00 +#define bRxSNR_C 0xff0000 +#define bRxSNR_D 0xff000000 +#define bSNREVMTLength 8 +#define bSNREVMFLength 1 + +#define bCSI1st 0xff +#define bCSI2nd 0xff00 +#define bRxEVM1st 0xff0000 +#define bRxEVM2nd 0xff000000 + +#define bSIGEVM 0xff +#define bPWDB 0xff00 +#define bSGIEN 0x10000 + +#define bSFactorQAM1 0xf +#define bSFactorQAM2 0xf0 +#define bSFactorQAM3 0xf00 +#define bSFactorQAM4 0xf000 +#define bSFactorQAM5 0xf0000 +#define bSFactorQAM6 0xf0000 +#define bSFactorQAM7 0xf00000 +#define bSFactorQAM8 0xf000000 +#define bSFactorQAM9 0xf0000000 +#define bCSIScheme 0x100000 + +#define bNoiseLvlTopSet 0x3 +#define bChSmooth 0x4 +#define bChSmoothCfg1 0x38 +#define bChSmoothCfg2 0x1c0 +#define bChSmoothCfg3 0xe00 +#define bChSmoothCfg4 0x7000 +#define bMRCMode 0x800000 +#define bTHEVMCfg 0x7000000 + +#define bLoopFitType 0x1 +#define bUpdCFO 0x40 +#define bUpdCFOOffData 0x80 +#define bAdvUpdCFO 0x100 +#define bAdvTimeCtrl 0x800 +#define bUpdClko 0x1000 +#define bFC 0x6000 +#define bTrackingMode 0x8000 +#define bPhCmpEnable 0x10000 +#define bUpdClkoLTF 0x20000 +#define bComChCFO 0x40000 +#define bCSIEstiMode 0x80000 +#define bAdvUpdEqz 0x100000 +#define bUChCfg 0x7000000 +#define bUpdEqz 0x8000000 + +#define bTxAGCRate18_06 0x7f7f7f7f +#define bTxAGCRate54_24 0x7f7f7f7f +#define bTxAGCRateMCS32 0x7f +#define bTxAGCRateCCK 0x7f00 +#define bTxAGCRateMCS3_MCS0 0x7f7f7f7f +#define bTxAGCRateMCS7_MCS4 0x7f7f7f7f +#define bTxAGCRateMCS11_MCS8 0x7f7f7f7f +#define bTxAGCRateMCS15_MCS12 0x7f7f7f7f + + +#define bRxPesudoNoiseOn 0x20000000 +#define bRxPesudoNoise_A 0xff +#define bRxPesudoNoise_B 0xff00 +#define bRxPesudoNoise_C 0xff0000 +#define bRxPesudoNoise_D 0xff000000 +#define bPesudoNoiseState_A 0xffff +#define bPesudoNoiseState_B 0xffff0000 +#define bPesudoNoiseState_C 0xffff +#define bPesudoNoiseState_D 0xffff0000 + +#define bZebra1_HSSIEnable 0x8 +#define bZebra1_TRxControl 0xc00 +#define bZebra1_TRxGainSetting 0x07f +#define bZebra1_RxCorner 0xc00 +#define bZebra1_TxChargePump 0x38 +#define bZebra1_RxChargePump 0x7 +#define bZebra1_ChannelNum 0xf80 +#define bZebra1_TxLPFBW 0x400 +#define bZebra1_RxLPFBW 0x600 + +#define bRTL8256RegModeCtrl1 0x100 +#define bRTL8256RegModeCtrl0 0x40 +#define bRTL8256_TxLPFBW 0x18 +#define bRTL8256_RxLPFBW 0x600 + +#define bRTL8258_TxLPFBW 0xc +#define bRTL8258_RxLPFBW 0xc00 +#define bRTL8258_RSSILPFBW 0xc0 + +#define bByte0 0x1 +#define bByte1 0x2 +#define bByte2 0x4 +#define bByte3 0x8 +#define bWord0 0x3 +#define bWord1 0xc +#define bDWord 0xf + +#define bMaskByte0 0xff +#define bMaskByte1 0xff00 +#define bMaskByte2 0xff0000 +#define bMaskByte3 0xff000000 +#define bMaskHWord 0xffff0000 +#define bMaskLWord 0x0000ffff +#define bMaskDWord 0xffffffff + +#define bMask12Bits 0xfff + +#define bEnable 0x1 +#define bDisable 0x0 + +#define LeftAntenna 0x0 +#define RightAntenna 0x1 + +#define tCheckTxStatus 500 +#define tUpdateRxCounter 100 + +#define rateCCK 0 +#define rateOFDM 1 +#define rateHT 2 + +#define bPMAC_End 0x1ff +#define bFPGAPHY0_End 0x8ff +#define bFPGAPHY1_End 0x9ff +#define bCCKPHY0_End 0xaff +#define bOFDMPHY0_End 0xcff +#define bOFDMPHY1_End 0xdff + + +#define bPMACControl 0x0 +#define bWMACControl 0x1 +#define bWNICControl 0x2 + +#define PathA 0x0 +#define PathB 0x1 +#define PathC 0x2 +#define PathD 0x3 + +#define rRTL8256RxMixerPole 0xb +#define bZebraRxMixerPole 0x6 +#define rRTL8256TxBBOPBias 0x9 +#define bRTL8256TxBBOPBias 0x400 +#define rRTL8256TxBBBW 19 +#define bRTL8256TxBBBW 0x18 + +#endif diff --git a/drivers/staging/rtl8192e/r8192E_wx.c b/drivers/staging/rtl8192e/r8192E_wx.c deleted file mode 100644 index adad91b..0000000 --- a/drivers/staging/rtl8192e/r8192E_wx.c +++ /dev/null @@ -1,1163 +0,0 @@ -/* - This file contains wireless extension handlers. - - This is part of rtl8180 OpenSource driver. - Copyright (C) Andrea Merello 2004-2005 <andreamrl@tiscali.it> - Released under the terms of GPL (General Public Licence) - - Parts of this driver are based on the GPL part - of the official realtek driver. - - Parts of this driver are based on the rtl8180 driver skeleton - from Patric Schenke & Andres Salomon. - - Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver. - - We want to tanks the Authors of those projects and the Ndiswrapper - project Authors. -*/ - -#include <linux/string.h> -#include "r8192E.h" -#include "r8192E_hw.h" -#include "r8192E_wx.h" -#ifdef ENABLE_DOT11D -#include "ieee80211/dot11d.h" -#endif - -#define RATE_COUNT 12 -static const u32 rtl8180_rates[] = {1000000,2000000,5500000,11000000, - 6000000,9000000,12000000,18000000,24000000,36000000,48000000,54000000}; - - -#ifndef ENETDOWN -#define ENETDOWN 1 -#endif -static int r8192_wx_get_freq(struct net_device *dev, - struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - return ieee80211_wx_get_freq(priv->ieee80211,a,wrqu,b); -} - - -static int r8192_wx_get_mode(struct net_device *dev, struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - struct r8192_priv *priv=ieee80211_priv(dev); - - return ieee80211_wx_get_mode(priv->ieee80211,a,wrqu,b); -} - - - -static int r8192_wx_get_rate(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - return ieee80211_wx_get_rate(priv->ieee80211,info,wrqu,extra); -} - - - -static int r8192_wx_set_rate(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - int ret; - struct r8192_priv *priv = ieee80211_priv(dev); - - if (priv->bHwRadioOff) - return 0; - - down(&priv->wx_sem); - - ret = ieee80211_wx_set_rate(priv->ieee80211,info,wrqu,extra); - - up(&priv->wx_sem); - - return ret; -} - - -static int r8192_wx_set_rts(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - int ret; - struct r8192_priv *priv = ieee80211_priv(dev); - - if (priv->bHwRadioOff) - return 0; - - down(&priv->wx_sem); - - ret = ieee80211_wx_set_rts(priv->ieee80211,info,wrqu,extra); - - up(&priv->wx_sem); - - return ret; -} - -static int r8192_wx_get_rts(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - return ieee80211_wx_get_rts(priv->ieee80211,info,wrqu,extra); -} - -static int r8192_wx_set_power(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - int ret; - struct r8192_priv *priv = ieee80211_priv(dev); - - if (priv->bHwRadioOff) - return 0; - - down(&priv->wx_sem); - - ret = ieee80211_wx_set_power(priv->ieee80211,info,wrqu,extra); - - up(&priv->wx_sem); - - return ret; -} - -static int r8192_wx_get_power(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - return ieee80211_wx_get_power(priv->ieee80211,info,wrqu,extra); -} - -static int r8192_wx_set_rawtx(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - int ret; - - if (priv->bHwRadioOff) - return 0; - - down(&priv->wx_sem); - - ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra); - - up(&priv->wx_sem); - - return ret; - -} - -static int r8192_wx_force_reset(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - down(&priv->wx_sem); - - printk("%s(): force reset ! extra is %d\n",__FUNCTION__, *extra); - priv->force_reset = *extra; - up(&priv->wx_sem); - return 0; - -} - - -static int r8192_wx_set_crcmon(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - int *parms = (int *)extra; - int enable = (parms[0] > 0); - short prev = priv->crcmon; - - if (priv->bHwRadioOff) - return 0; - - down(&priv->wx_sem); - - if(enable) - priv->crcmon=1; - else - priv->crcmon=0; - - DMESG("bad CRC in monitor mode are %s", - priv->crcmon ? "accepted" : "rejected"); - - if(prev != priv->crcmon && priv->up){ - //rtl8180_down(dev); - //rtl8180_up(dev); - } - - up(&priv->wx_sem); - - return 0; -} - -static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - RT_RF_POWER_STATE rtState; - int ret; - - if (priv->bHwRadioOff) - return 0; - - rtState = priv->eRFPowerState; - down(&priv->wx_sem); -#ifdef ENABLE_IPS - if(wrqu->mode == IW_MODE_ADHOC){ - - if (priv->PowerSaveControl.bInactivePs) { - if(rtState == eRfOff){ - if(priv->RfOffReason > RF_CHANGE_BY_IPS) - { - RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__); - up(&priv->wx_sem); - return -1; - } - else{ - RT_TRACE(COMP_ERR, "%s(): IPSLeave\n",__FUNCTION__); - down(&priv->ieee80211->ips_sem); - IPSLeave(priv); - up(&priv->ieee80211->ips_sem); - } - } - } - } -#endif - ret = ieee80211_wx_set_mode(priv->ieee80211,a,wrqu,b); - - //rtl8187_set_rxconf(dev); - - up(&priv->wx_sem); - return ret; -} - -struct iw_range_with_scan_capa -{ - /* Informative stuff (to choose between different interface) */ - __u32 throughput; /* To give an idea... */ - /* In theory this value should be the maximum benchmarked - * TCP/IP throughput, because with most of these devices the - * bit rate is meaningless (overhead an co) to estimate how - * fast the connection will go and pick the fastest one. - * I suggest people to play with Netperf or any benchmark... - */ - - /* NWID (or domain id) */ - __u32 min_nwid; /* Minimal NWID we are able to set */ - __u32 max_nwid; /* Maximal NWID we are able to set */ - - /* Old Frequency (backward compat - moved lower ) */ - __u16 old_num_channels; - __u8 old_num_frequency; - - /* Scan capabilities */ - __u8 scan_capa; -}; -static int rtl8180_wx_get_range(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct iw_range *range = (struct iw_range *)extra; - struct iw_range_with_scan_capa* tmp = (struct iw_range_with_scan_capa*)range; - struct r8192_priv *priv = ieee80211_priv(dev); - u16 val; - int i; - - wrqu->data.length = sizeof(*range); - memset(range, 0, sizeof(*range)); - - /* Let's try to keep this struct in the same order as in - * linux/include/wireless.h - */ - - /* TODO: See what values we can set, and remove the ones we can't - * set, or fill them with some default data. - */ - - /* ~5 Mb/s real (802.11b) */ - range->throughput = 130 * 1000 * 1000; - - // TODO: Not used in 802.11b? -// range->min_nwid; /* Minimal NWID we are able to set */ - // TODO: Not used in 802.11b? -// range->max_nwid; /* Maximal NWID we are able to set */ - - /* Old Frequency (backward compat - moved lower ) */ -// range->old_num_channels; -// range->old_num_frequency; -// range->old_freq[6]; /* Filler to keep "version" at the same offset */ - - range->max_qual.qual = 100; - /* TODO: Find real max RSSI and stick here */ - range->max_qual.level = 0; - range->max_qual.noise = -98; - range->max_qual.updated = 7; /* Updated all three */ - - range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */ - /* TODO: Find real 'good' to 'bad' threshold value for RSSI */ - range->avg_qual.level = 20 + -98; - range->avg_qual.noise = 0; - range->avg_qual.updated = 7; /* Updated all three */ - - range->num_bitrates = RATE_COUNT; - - for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++) { - range->bitrate[i] = rtl8180_rates[i]; - } - - range->min_frag = MIN_FRAG_THRESHOLD; - range->max_frag = MAX_FRAG_THRESHOLD; - - range->min_pmp=0; - range->max_pmp = 5000000; - range->min_pmt = 0; - range->max_pmt = 65535*1000; - range->pmp_flags = IW_POWER_PERIOD; - range->pmt_flags = IW_POWER_TIMEOUT; - range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R; - range->we_version_compiled = WIRELESS_EXT; - range->we_version_source = 18; - -// range->retry_capa; /* What retry options are supported */ -// range->retry_flags; /* How to decode max/min retry limit */ -// range->r_time_flags; /* How to decode max/min retry life */ -// range->min_retry; /* Minimal number of retries */ -// range->max_retry; /* Maximal number of retries */ -// range->min_r_time; /* Minimal retry lifetime */ -// range->max_r_time; /* Maximal retry lifetime */ - - - for (i = 0, val = 0; i < 14; i++) { - - // Include only legal frequencies for some countries -#ifdef ENABLE_DOT11D - if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) { -#else - if ((priv->ieee80211->channel_map)[i+1]) { -#endif - range->freq[val].i = i + 1; - range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000; - range->freq[val].e = 1; - val++; - } else { - // FIXME: do we need to set anything for channels - // we don't use ? - } - - if (val == IW_MAX_FREQUENCIES) - break; - } - range->num_frequency = val; - range->num_channels = val; - - range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2| - IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP; - - tmp->scan_capa = 0x01; - return 0; -} - - -static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - struct ieee80211_device* ieee = priv->ieee80211; - RT_RF_POWER_STATE rtState; - int ret; - - if (priv->bHwRadioOff) - return 0; - - rtState = priv->eRFPowerState; - - if(!priv->up) return -ENETDOWN; - if (priv->ieee80211->LinkDetectInfo.bBusyTraffic == true) - return -EAGAIN; - - if (wrqu->data.flags & IW_SCAN_THIS_ESSID) - { - struct iw_scan_req* req = (struct iw_scan_req*)b; - if (req->essid_len) - { - //printk("==**&*&*&**===>scan set ssid:%s\n", req->essid); - ieee->current_network.ssid_len = req->essid_len; - memcpy(ieee->current_network.ssid, req->essid, req->essid_len); - //printk("=====>network ssid:%s\n", ieee->current_network.ssid); - } - } - - down(&priv->wx_sem); -#ifdef ENABLE_IPS - priv->ieee80211->actscanning = true; - if(priv->ieee80211->state != IEEE80211_LINKED){ - if (priv->PowerSaveControl.bInactivePs) { - if(rtState == eRfOff){ - if(priv->RfOffReason > RF_CHANGE_BY_IPS) - { - RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n",__FUNCTION__); - up(&priv->wx_sem); - return -1; - } - else{ - //RT_TRACE(COMP_PS, "%s(): IPSLeave\n",__FUNCTION__); - down(&priv->ieee80211->ips_sem); - IPSLeave(priv); - up(&priv->ieee80211->ips_sem); - } - } - } - priv->ieee80211->scanning = 0; - ieee80211_softmac_scan_syncro(priv->ieee80211); - ret = 0; - } - else -#else - - if(priv->ieee80211->state != IEEE80211_LINKED){ - priv->ieee80211->scanning = 0; - ieee80211_softmac_scan_syncro(priv->ieee80211); - ret = 0; - } - else -#endif - ret = ieee80211_wx_set_scan(priv->ieee80211,a,wrqu,b); - - up(&priv->wx_sem); - return ret; -} - - -static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - - int ret; - struct r8192_priv *priv = ieee80211_priv(dev); - - if (priv->bHwRadioOff) - return 0; - - if(!priv->up) return -ENETDOWN; - - down(&priv->wx_sem); - - ret = ieee80211_wx_get_scan(priv->ieee80211,a,wrqu,b); - - up(&priv->wx_sem); - - return ret; -} - -static int r8192_wx_set_essid(struct net_device *dev, - struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - RT_RF_POWER_STATE rtState; - int ret; - - if (priv->bHwRadioOff) - return 0; - - rtState = priv->eRFPowerState; - down(&priv->wx_sem); - -#ifdef ENABLE_IPS - down(&priv->ieee80211->ips_sem); - IPSLeave(priv); - up(&priv->ieee80211->ips_sem); -#endif - ret = ieee80211_wx_set_essid(priv->ieee80211,a,wrqu,b); - - up(&priv->wx_sem); - - return ret; -} - - - - -static int r8192_wx_get_essid(struct net_device *dev, - struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - int ret; - struct r8192_priv *priv = ieee80211_priv(dev); - - down(&priv->wx_sem); - - ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b); - - up(&priv->wx_sem); - - return ret; -} - - -static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a, - union iwreq_data *wrqu, char *b) -{ - int ret; - struct r8192_priv *priv = ieee80211_priv(dev); - - if (priv->bHwRadioOff) - return 0; - - down(&priv->wx_sem); - - ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b); - - up(&priv->wx_sem); - return ret; -} - -static int r8192_wx_get_name(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra); -} - - -static int r8192_wx_set_frag(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - if (priv->bHwRadioOff) - return 0; - - if (wrqu->frag.disabled) - priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD; - else { - if (wrqu->frag.value < MIN_FRAG_THRESHOLD || - wrqu->frag.value > MAX_FRAG_THRESHOLD) - return -EINVAL; - - priv->ieee80211->fts = wrqu->frag.value & ~0x1; - } - - return 0; -} - - -static int r8192_wx_get_frag(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - wrqu->frag.value = priv->ieee80211->fts; - wrqu->frag.fixed = 0; /* no auto select */ - wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD); - - return 0; -} - - -static int r8192_wx_set_wap(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *awrq, - char *extra) -{ - - int ret; - struct r8192_priv *priv = ieee80211_priv(dev); -// struct sockaddr *temp = (struct sockaddr *)awrq; - - if (priv->bHwRadioOff) - return 0; - - down(&priv->wx_sem); - -#ifdef ENABLE_IPS - down(&priv->ieee80211->ips_sem); - IPSLeave(priv); - up(&priv->ieee80211->ips_sem); -#endif - ret = ieee80211_wx_set_wap(priv->ieee80211,info,awrq,extra); - - up(&priv->wx_sem); - - return ret; - -} - - -static int r8192_wx_get_wap(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - return ieee80211_wx_get_wap(priv->ieee80211,info,wrqu,extra); -} - - -static int r8192_wx_get_enc(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *key) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key); -} - -static int r8192_wx_set_enc(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *key) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - int ret; - - struct ieee80211_device *ieee = priv->ieee80211; - //u32 TargetContent; - u32 hwkey[4]={0,0,0,0}; - u8 mask=0xff; - u32 key_idx=0; - u8 zero_addr[4][6] ={{0x00,0x00,0x00,0x00,0x00,0x00}, - {0x00,0x00,0x00,0x00,0x00,0x01}, - {0x00,0x00,0x00,0x00,0x00,0x02}, - {0x00,0x00,0x00,0x00,0x00,0x03} }; - int i; - - if (priv->bHwRadioOff) - return 0; - - if(!priv->up) return -ENETDOWN; - - priv->ieee80211->wx_set_enc = 1; -#ifdef ENABLE_IPS - down(&priv->ieee80211->ips_sem); - IPSLeave(priv); - up(&priv->ieee80211->ips_sem); -#endif - - down(&priv->wx_sem); - - RT_TRACE(COMP_SEC, "Setting SW wep key\n"); - ret = ieee80211_wx_set_encode(priv->ieee80211,info,wrqu,key); - - up(&priv->wx_sem); - - //sometimes, the length is zero while we do not type key value - if(wrqu->encoding.length!=0){ - - for(i=0 ; i<4 ; i++){ - hwkey[i] |= key[4*i+0]&mask; - if(i==1&&(4*i+1)==wrqu->encoding.length) mask=0x00; - if(i==3&&(4*i+1)==wrqu->encoding.length) mask=0x00; - hwkey[i] |= (key[4*i+1]&mask)<<8; - hwkey[i] |= (key[4*i+2]&mask)<<16; - hwkey[i] |= (key[4*i+3]&mask)<<24; - } - - #define CONF_WEP40 0x4 - #define CONF_WEP104 0x14 - - switch(wrqu->encoding.flags & IW_ENCODE_INDEX){ - case 0: key_idx = ieee->tx_keyidx; break; - case 1: key_idx = 0; break; - case 2: key_idx = 1; break; - case 3: key_idx = 2; break; - case 4: key_idx = 3; break; - default: break; - } - - //printk("-------====>length:%d, key_idx:%d, flag:%x\n", wrqu->encoding.length, key_idx, wrqu->encoding.flags); - if(wrqu->encoding.length==0x5){ - ieee->pairwise_key_type = KEY_TYPE_WEP40; - EnableHWSecurityConfig8192(priv); - setKey(priv, key_idx, key_idx, KEY_TYPE_WEP40, - zero_addr[key_idx], 0, hwkey); - } - - else if(wrqu->encoding.length==0xd){ - ieee->pairwise_key_type = KEY_TYPE_WEP104; - EnableHWSecurityConfig8192(priv); - setKey(priv, key_idx, key_idx, KEY_TYPE_WEP104, - zero_addr[key_idx], 0, hwkey); - } - else printk("wrong type in WEP, not WEP40 and WEP104\n"); - } - - priv->ieee80211->wx_set_enc = 0; - - return ret; -} - - -static int r8192_wx_set_scan_type(struct net_device *dev, struct iw_request_info *aa, union - iwreq_data *wrqu, char *p){ - - struct r8192_priv *priv = ieee80211_priv(dev); - int *parms=(int*)p; - int mode=parms[0]; - - priv->ieee80211->active_scan = mode; - - return 1; -} - - - -static int r8192_wx_set_retry(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - int err = 0; - - if (priv->bHwRadioOff) - return 0; - - down(&priv->wx_sem); - - if (wrqu->retry.flags & IW_RETRY_LIFETIME || - wrqu->retry.disabled){ - err = -EINVAL; - goto exit; - } - if (!(wrqu->retry.flags & IW_RETRY_LIMIT)){ - err = -EINVAL; - goto exit; - } - - if(wrqu->retry.value > R8180_MAX_RETRY){ - err= -EINVAL; - goto exit; - } - if (wrqu->retry.flags & IW_RETRY_MAX) { - priv->retry_rts = wrqu->retry.value; - DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value); - - }else { - priv->retry_data = wrqu->retry.value; - DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value); - } - - /* FIXME ! - * We might try to write directly the TX config register - * or to restart just the (R)TX process. - * I'm unsure if whole reset is really needed - */ - - rtl8192_commit(priv); - /* - if(priv->up){ - rtl8180_rtx_disable(dev); - rtl8180_rx_enable(dev); - rtl8180_tx_enable(dev); - - } - */ -exit: - up(&priv->wx_sem); - - return err; -} - -static int r8192_wx_get_retry(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - - - wrqu->retry.disabled = 0; /* can't be disabled */ - - if ((wrqu->retry.flags & IW_RETRY_TYPE) == - IW_RETRY_LIFETIME) - return -EINVAL; - - if (wrqu->retry.flags & IW_RETRY_MAX) { - wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MAX; - wrqu->retry.value = priv->retry_rts; - } else { - wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MIN; - wrqu->retry.value = priv->retry_data; - } - //DMESG("returning %d",wrqu->retry.value); - - - return 0; -} - -static int r8192_wx_get_sens(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - if(priv->rf_set_sens == NULL) - return -1; /* we have not this support for this radio */ - wrqu->sens.value = priv->sens; - return 0; -} - - -static int r8192_wx_set_sens(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - - struct r8192_priv *priv = ieee80211_priv(dev); - - short err = 0; - - if (priv->bHwRadioOff) - return 0; - - down(&priv->wx_sem); - //DMESG("attempt to set sensivity to %ddb",wrqu->sens.value); - if(priv->rf_set_sens == NULL) { - err= -1; /* we have not this support for this radio */ - goto exit; - } - if(priv->rf_set_sens(dev, wrqu->sens.value) == 0) - priv->sens = wrqu->sens.value; - else - err= -EINVAL; - -exit: - up(&priv->wx_sem); - - return err; -} - -static int r8192_wx_set_enc_ext(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - int ret=0; - struct r8192_priv *priv = ieee80211_priv(dev); - struct ieee80211_device* ieee = priv->ieee80211; - - if (priv->bHwRadioOff) - return 0; - - down(&priv->wx_sem); - - priv->ieee80211->wx_set_enc = 1; - -#ifdef ENABLE_IPS - down(&priv->ieee80211->ips_sem); - IPSLeave(priv); - up(&priv->ieee80211->ips_sem); -#endif - - ret = ieee80211_wx_set_encode_ext(ieee, info, wrqu, extra); - - { - u8 broadcast_addr[6] = {0xff,0xff,0xff,0xff,0xff,0xff}; - u8 zero[6] = {0}; - u32 key[4] = {0}; - struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; - struct iw_point *encoding = &wrqu->encoding; - u8 idx = 0, alg = 0, group = 0; - - if ((encoding->flags & IW_ENCODE_DISABLED) || - ext->alg == IW_ENCODE_ALG_NONE) //none is not allowed to use hwsec WB 2008.07.01 - { - ieee->pairwise_key_type = ieee->group_key_type = KEY_TYPE_NA; - CamResetAllEntry(priv); - goto end_hw_sec; - } - alg = (ext->alg == IW_ENCODE_ALG_CCMP)?KEY_TYPE_CCMP:ext->alg; // as IW_ENCODE_ALG_CCMP is defined to be 3 and KEY_TYPE_CCMP is defined to 4; - idx = encoding->flags & IW_ENCODE_INDEX; - if (idx) - idx --; - group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY; - - if ((!group) || (IW_MODE_ADHOC == ieee->iw_mode) || (alg == KEY_TYPE_WEP40)) - { - if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40) ) - alg = KEY_TYPE_WEP104; - ieee->pairwise_key_type = alg; - EnableHWSecurityConfig8192(priv); - } - memcpy((u8*)key, ext->key, 16); //we only get 16 bytes key.why? WB 2008.7.1 - - if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode !=2) ) - { - if (ext->key_len == 13) - ieee->pairwise_key_type = alg = KEY_TYPE_WEP104; - setKey(priv, idx, idx, alg, zero, 0, key); - } - else if (group) - { - ieee->group_key_type = alg; - setKey(priv, idx, idx, alg, broadcast_addr, 0, key); - } - else //pairwise key - { - if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) && ieee->pHTInfo->bCurrentHTSupport){ - write_nic_byte(priv, 0x173, 1); //fix aes bug - } - setKey(priv, 4, idx, alg, - (u8*)ieee->ap_mac_addr, 0, key); - } - - - } - -end_hw_sec: - priv->ieee80211->wx_set_enc = 0; - up(&priv->wx_sem); - return ret; - -} -static int r8192_wx_set_auth(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *data, char *extra) -{ - int ret=0; - //printk("====>%s()\n", __FUNCTION__); - struct r8192_priv *priv = ieee80211_priv(dev); - - if (priv->bHwRadioOff) - return 0; - - down(&priv->wx_sem); - ret = ieee80211_wx_set_auth(priv->ieee80211, info, &(data->param), extra); - up(&priv->wx_sem); - return ret; -} - -static int r8192_wx_set_mlme(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - //printk("====>%s()\n", __FUNCTION__); - - int ret=0; - struct r8192_priv *priv = ieee80211_priv(dev); - - if (priv->bHwRadioOff) - return 0; - - down(&priv->wx_sem); - ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra); - up(&priv->wx_sem); - return ret; -} - -static int r8192_wx_set_gen_ie(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *data, char *extra) -{ - //printk("====>%s(), len:%d\n", __FUNCTION__, data->length); - int ret=0; - struct r8192_priv *priv = ieee80211_priv(dev); - - if (priv->bHwRadioOff) - return 0; - - down(&priv->wx_sem); - ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, data->data.length); - up(&priv->wx_sem); - //printk("<======%s(), ret:%d\n", __FUNCTION__, ret); - return ret; -} - -static int dummy(struct net_device *dev, struct iw_request_info *a, - union iwreq_data *wrqu,char *b) -{ - return -1; -} - -// check ac/dc status with the help of user space application */ -static int r8192_wx_adapter_power_status(struct net_device *dev, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) -{ - struct r8192_priv *priv = ieee80211_priv(dev); -#ifdef ENABLE_LPS - PRT_POWER_SAVE_CONTROL pPSC = &priv->PowerSaveControl; - struct ieee80211_device* ieee = priv->ieee80211; -#endif - down(&priv->wx_sem); - -#ifdef ENABLE_LPS - RT_TRACE(COMP_POWER, "%s(): %s\n",__FUNCTION__, (*extra == 6)?"DC power":"AC power"); - // ieee->ps shall not be set under DC mode, otherwise it conflict - // with Leisure power save mode setting. - // - if(*extra || priv->force_lps) { - priv->ps_force = false; - pPSC->bLeisurePs = true; - } else { - //LZM for PS-Poll AID issue. 090429 - if(priv->ieee80211->state == IEEE80211_LINKED) - LeisurePSLeave(priv->ieee80211); - - priv->ps_force = true; - pPSC->bLeisurePs = false; - ieee->ps = *extra; - } - -#endif - up(&priv->wx_sem); - return 0; - -} - - -static iw_handler r8192_wx_handlers[] = -{ - NULL, /* SIOCSIWCOMMIT */ - r8192_wx_get_name, /* SIOCGIWNAME */ - dummy, /* SIOCSIWNWID */ - dummy, /* SIOCGIWNWID */ - r8192_wx_set_freq, /* SIOCSIWFREQ */ - r8192_wx_get_freq, /* SIOCGIWFREQ */ - r8192_wx_set_mode, /* SIOCSIWMODE */ - r8192_wx_get_mode, /* SIOCGIWMODE */ - r8192_wx_set_sens, /* SIOCSIWSENS */ - r8192_wx_get_sens, /* SIOCGIWSENS */ - NULL, /* SIOCSIWRANGE */ - rtl8180_wx_get_range, /* SIOCGIWRANGE */ - NULL, /* SIOCSIWPRIV */ - NULL, /* SIOCGIWPRIV */ - NULL, /* SIOCSIWSTATS */ - NULL, /* SIOCGIWSTATS */ - dummy, /* SIOCSIWSPY */ - dummy, /* SIOCGIWSPY */ - NULL, /* SIOCGIWTHRSPY */ - NULL, /* SIOCWIWTHRSPY */ - r8192_wx_set_wap, /* SIOCSIWAP */ - r8192_wx_get_wap, /* SIOCGIWAP */ - r8192_wx_set_mlme, /* MLME-- */ - dummy, /* SIOCGIWAPLIST -- depricated */ - r8192_wx_set_scan, /* SIOCSIWSCAN */ - r8192_wx_get_scan, /* SIOCGIWSCAN */ - r8192_wx_set_essid, /* SIOCSIWESSID */ - r8192_wx_get_essid, /* SIOCGIWESSID */ - dummy, /* SIOCSIWNICKN */ - dummy, /* SIOCGIWNICKN */ - NULL, /* -- hole -- */ - NULL, /* -- hole -- */ - r8192_wx_set_rate, /* SIOCSIWRATE */ - r8192_wx_get_rate, /* SIOCGIWRATE */ - r8192_wx_set_rts, /* SIOCSIWRTS */ - r8192_wx_get_rts, /* SIOCGIWRTS */ - r8192_wx_set_frag, /* SIOCSIWFRAG */ - r8192_wx_get_frag, /* SIOCGIWFRAG */ - dummy, /* SIOCSIWTXPOW */ - dummy, /* SIOCGIWTXPOW */ - r8192_wx_set_retry, /* SIOCSIWRETRY */ - r8192_wx_get_retry, /* SIOCGIWRETRY */ - r8192_wx_set_enc, /* SIOCSIWENCODE */ - r8192_wx_get_enc, /* SIOCGIWENCODE */ - r8192_wx_set_power, /* SIOCSIWPOWER */ - r8192_wx_get_power, /* SIOCGIWPOWER */ - NULL, /*---hole---*/ - NULL, /*---hole---*/ - r8192_wx_set_gen_ie,//NULL, /* SIOCSIWGENIE */ - NULL, /* SIOCSIWGENIE */ - r8192_wx_set_auth,//NULL, /* SIOCSIWAUTH */ - NULL,//r8192_wx_get_auth,//NULL, /* SIOCSIWAUTH */ - r8192_wx_set_enc_ext, /* SIOCSIWENCODEEXT */ - NULL,//r8192_wx_get_enc_ext,//NULL, /* SIOCSIWENCODEEXT */ - NULL, /* SIOCSIWPMKSA */ - NULL, /*---hole---*/ - -}; - - -static const struct iw_priv_args r8192_private_args[] = { - - { - SIOCIWFIRSTPRIV + 0x0, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc" - }, - - { - SIOCIWFIRSTPRIV + 0x1, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan" - - }, - { - SIOCIWFIRSTPRIV + 0x2, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx" - } - , - { - SIOCIWFIRSTPRIV + 0x3, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset" - - } - , - { - SIOCIWFIRSTPRIV + 0x4, - IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED|1, IW_PRIV_TYPE_NONE, - "set_power" - } - -}; - - -static iw_handler r8192_private_handler[] = { - r8192_wx_set_crcmon, /*SIOCIWSECONDPRIV*/ - r8192_wx_set_scan_type, - r8192_wx_set_rawtx, - r8192_wx_force_reset, - r8192_wx_adapter_power_status, -}; - -static struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev) -{ - struct r8192_priv *priv = ieee80211_priv(dev); - struct ieee80211_device* ieee = priv->ieee80211; - struct iw_statistics* wstats = &priv->wstats; - int tmp_level = 0; - int tmp_qual = 0; - int tmp_noise = 0; - if(ieee->state < IEEE80211_LINKED) - { - wstats->qual.qual = 0; - wstats->qual.level = 0; - wstats->qual.noise = 0; - wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; - return wstats; - } - - tmp_level = (&ieee->current_network)->stats.rssi; - tmp_qual = (&ieee->current_network)->stats.signal; - tmp_noise = (&ieee->current_network)->stats.noise; - //printk("level:%d, qual:%d, noise:%d\n", tmp_level, tmp_qual, tmp_noise); - - wstats->qual.level = tmp_level; - wstats->qual.qual = tmp_qual; - wstats->qual.noise = tmp_noise; - wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; - return wstats; -} - - -struct iw_handler_def r8192_wx_handlers_def={ - .standard = r8192_wx_handlers, - .num_standard = sizeof(r8192_wx_handlers) / sizeof(iw_handler), - .private = r8192_private_handler, - .num_private = sizeof(r8192_private_handler) / sizeof(iw_handler), - .num_private_args = sizeof(r8192_private_args) / sizeof(struct iw_priv_args), - .get_wireless_stats = r8192_get_wireless_stats, - .private_args = (struct iw_priv_args *)r8192_private_args, -}; diff --git a/drivers/staging/rtl8192e/r8192E_wx.h b/drivers/staging/rtl8192e/r8192E_wx.h deleted file mode 100644 index 25f06c1..0000000 --- a/drivers/staging/rtl8192e/r8192E_wx.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - This is part of rtl8180 OpenSource driver - v 0.3 - Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it> - Released under the terms of GPL (General Public Licence) - - Parts of this driver are based on the GPL part of the official realtek driver - Parts of this driver are based on the rtl8180 driver skeleton from Patric Schenke & Andres Salomon - Parts of this driver are based on the Intel Pro Wireless 2100 GPL driver - - We want to tanks the Authors of such projects and the Ndiswrapper project Authors. -*/ - -/* this file (will) contains wireless extension handlers*/ - -#ifndef R8180_WX_H -#define R8180_WX_H -extern struct iw_handler_def r8192_wx_handlers_def; -#endif diff --git a/drivers/staging/rtl8192e/r8192_pm.c b/drivers/staging/rtl8192e/r8192_pm.c deleted file mode 100644 index 7bcc4a3..0000000 --- a/drivers/staging/rtl8192e/r8192_pm.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - Power management interface routines. - Written by Mariusz Matuszek. - This code is currently just a placeholder for later work and - does not do anything useful. - - This is part of rtl8180 OpenSource driver. - Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it> - Released under the terms of GPL (General Public Licence) -*/ - -#include "r8192E.h" -#include "r8192E_hw.h" -#include "r8192_pm.h" -#include "r8190_rtl8256.h" - -int rtl8192E_save_state (struct pci_dev *dev, pm_message_t state) -{ - printk(KERN_NOTICE "r8192E save state call (state %u).\n", state.event); - return -EAGAIN; -} - - -int rtl8192E_suspend (struct pci_dev *pdev, pm_message_t state) -{ - struct net_device *dev = pci_get_drvdata(pdev); - struct r8192_priv *priv = ieee80211_priv(dev); - u32 ulRegRead; - - RT_TRACE(COMP_POWER, "============> r8192E suspend call.\n"); - if (!netif_running(dev)) - goto out_pci_suspend; - - if (dev->netdev_ops->ndo_stop) - dev->netdev_ops->ndo_stop(dev); - - // Call MgntActSet_RF_State instead to prevent RF config race condition. - if(!priv->ieee80211->bSupportRemoteWakeUp) { - MgntActSet_RF_State(priv, eRfOff, RF_CHANGE_BY_INIT); - // 2006.11.30. System reset bit - ulRegRead = read_nic_dword(priv, CPU_GEN); - ulRegRead|=CPU_GEN_SYSTEM_RESET; - write_nic_dword(priv, CPU_GEN, ulRegRead); - } else { - //2008.06.03 for WOL - write_nic_dword(priv, WFCRC0, 0xffffffff); - write_nic_dword(priv, WFCRC1, 0xffffffff); - write_nic_dword(priv, WFCRC2, 0xffffffff); - //Write PMR register - write_nic_byte(priv, PMR, 0x5); - //Disable tx, enanble rx - write_nic_byte(priv, MacBlkCtrl, 0xa); - } - -out_pci_suspend: - RT_TRACE(COMP_POWER, "r8192E support WOL call??????????????????????\n"); - if(priv->ieee80211->bSupportRemoteWakeUp) { - RT_TRACE(COMP_POWER, "r8192E support WOL call!!!!!!!!!!!!!!!!!!.\n"); - } - netif_device_detach(dev); - pci_save_state(pdev); - pci_disable_device(pdev); - pci_enable_wake(pdev, pci_choose_state(pdev,state), - priv->ieee80211->bSupportRemoteWakeUp?1:0); - pci_set_power_state(pdev,pci_choose_state(pdev,state)); - - return 0; -} - -int rtl8192E_resume (struct pci_dev *pdev) -{ - struct net_device *dev = pci_get_drvdata(pdev); - int err; - u32 val; - - RT_TRACE(COMP_POWER, "================>r8192E resume call.\n"); - - pci_set_power_state(pdev, PCI_D0); - - err = pci_enable_device(pdev); - if(err) { - printk(KERN_ERR "%s: pci_enable_device failed on resume\n", - dev->name); - return err; - } - - pci_restore_state(pdev); - - /* - * Suspend/Resume resets the PCI configuration space, so we have to - * re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries - * from interfering with C3 CPU state. pci_restore_state won't help - * here since it only restores the first 64 bytes pci config header. - */ - pci_read_config_dword(pdev, 0x40, &val); - if ((val & 0x0000ff00) != 0) { - pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); - } - - - - pci_enable_wake(pdev, PCI_D0, 0); - - if(!netif_running(dev)) - goto out; - - netif_device_attach(dev); - - if (dev->netdev_ops->ndo_open) - dev->netdev_ops->ndo_open(dev); - -out: - RT_TRACE(COMP_POWER, "<================r8192E resume call.\n"); - return 0; -} - - -int rtl8192E_enable_wake (struct pci_dev *dev, pm_message_t state, int enable) -{ - printk(KERN_NOTICE "r8192E enable wake call (state %u, enable %d).\n", - state.event, enable); - return -EAGAIN; -} diff --git a/drivers/staging/rtl8192e/r8192_pm.h b/drivers/staging/rtl8192e/r8192_pm.h deleted file mode 100644 index 4da9b46..0000000 --- a/drivers/staging/rtl8192e/r8192_pm.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - Power management interface routines. - Written by Mariusz Matuszek. - This code is currently just a placeholder for later work and - does not do anything useful. - - This is part of rtl8180 OpenSource driver. - Copyright (C) Andrea Merello 2004 <andreamrl@tiscali.it> - Released under the terms of GPL (General Public Licence) - -*/ - -#ifndef R8192E_PM_H -#define R8192E_PM_H - -#include <linux/types.h> -#include <linux/pci.h> - -int rtl8192E_save_state (struct pci_dev *dev, pm_message_t state); -int rtl8192E_suspend (struct pci_dev *dev, pm_message_t state); -int rtl8192E_resume (struct pci_dev *dev); -int rtl8192E_enable_wake (struct pci_dev *dev, pm_message_t state, int enable); - -#endif //R8192E_PM_H diff --git a/drivers/staging/rtl8192e/r819xE_cmdpkt.c b/drivers/staging/rtl8192e/r819xE_cmdpkt.c deleted file mode 100644 index 756e066..0000000 --- a/drivers/staging/rtl8192e/r819xE_cmdpkt.c +++ /dev/null @@ -1,444 +0,0 @@ -/****************************************************************************** - - (c) Copyright 2008, RealTEK Technologies Inc. All Rights Reserved. - - Module: r819xusb_cmdpkt.c (RTL8190 TX/RX command packet handler Source C File) - - Note: The module is responsible for handling TX and RX command packet. - 1. TX : Send set and query configuration command packet. - 2. RX : Receive tx feedback, beacon state, query configuration - command packet. - - Function: - - Export: - - Abbrev: - - History: - Data Who Remark - - 05/06/2008 amy Create initial version porting from windows driver. - -******************************************************************************/ -#include "r8192E.h" -#include "r8192E_hw.h" -#include "r819xE_cmdpkt.h" - -/* - * Driver internal module can call the API to send message to - * firmware side. For example, you can send a debug command packet. - * Or you can send a request for FW to modify RLX4181 LBUS HW bank. - * Otherwise, you can change MAC/PHT/RF register by firmware at - * run time. We do not support message more than one segment now. - */ -RT_STATUS cmpk_message_handle_tx( - struct r8192_priv *priv, - u8* code_virtual_address, - u32 packettype, - u32 buffer_len) -{ - RT_STATUS rt_status = RT_STATUS_SUCCESS; - u16 frag_threshold; - u16 frag_length = 0, frag_offset = 0; - rt_firmware *pfirmware = priv->pFirmware; - struct sk_buff *skb; - unsigned char *seg_ptr; - cb_desc *tcb_desc; - u8 bLastIniPkt; - - PTX_FWINFO_8190PCI pTxFwInfo = NULL; - int i; - - RT_TRACE(COMP_CMDPKT,"%s(),buffer_len is %d\n",__FUNCTION__,buffer_len); - firmware_init_param(priv); - //Fragmentation might be required - frag_threshold = pfirmware->cmdpacket_frag_thresold; - do { - if((buffer_len - frag_offset) > frag_threshold) { - frag_length = frag_threshold ; - bLastIniPkt = 0; - - } else { - frag_length =(u16)(buffer_len - frag_offset); - bLastIniPkt = 1; - - } - - /* Allocate skb buffer to contain firmware info and tx descriptor info - * add 4 to avoid packet appending overflow. - * */ - skb = dev_alloc_skb(frag_length + priv->ieee80211->tx_headroom + 4); - if(skb == NULL) { - rt_status = RT_STATUS_FAILURE; - goto Failed; - } - - tcb_desc = (cb_desc*)(skb->cb + MAX_DEV_ADDR_SIZE); - tcb_desc->queue_index = TXCMD_QUEUE; - tcb_desc->bCmdOrInit = packettype; - tcb_desc->bLastIniPkt = bLastIniPkt; - tcb_desc->pkt_size = frag_length; - - //seg_ptr = skb_put(skb, frag_length + priv->ieee80211->tx_headroom); - seg_ptr = skb_put(skb, priv->ieee80211->tx_headroom); - - pTxFwInfo = (PTX_FWINFO_8190PCI)seg_ptr; - memset(pTxFwInfo,0,sizeof(TX_FWINFO_8190PCI)); - memset(pTxFwInfo,0x12,8); - - seg_ptr +=sizeof(TX_FWINFO_8190PCI); - - /* - * Transform from little endian to big endian - * and pending zero - */ - seg_ptr = skb_tail_pointer(skb); - for(i=0 ; i < frag_length; i+=4) { - *seg_ptr++ = ((i+0)<frag_length)?code_virtual_address[i+3]:0; - *seg_ptr++ = ((i+1)<frag_length)?code_virtual_address[i+2]:0; - *seg_ptr++ = ((i+2)<frag_length)?code_virtual_address[i+1]:0; - *seg_ptr++ = ((i+3)<frag_length)?code_virtual_address[i+0]:0; - } - skb_put(skb, i); - priv->ieee80211->softmac_hard_start_xmit(skb, priv->ieee80211); - - code_virtual_address += frag_length; - frag_offset += frag_length; - - }while(frag_offset < buffer_len); - -Failed: - return rt_status; -} - -static void cmpk_count_txstatistic(struct r8192_priv *priv, cmpk_txfb_t *pstx_fb) -{ -#ifdef ENABLE_PS - RT_RF_POWER_STATE rtState; - - pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState)); - - // When RF is off, we should not count the packet for hw/sw synchronize - // reason, ie. there may be a duration while sw switch is changed and hw - // switch is being changed. 2006.12.04, by shien chang. - if (rtState == eRfOff) - { - return; - } -#endif - -#ifdef TODO - if(pAdapter->bInHctTest) - return; -#endif - /* We can not know the packet length and transmit type: broadcast or uni - or multicast. So the relative statistics must be collected in tx - feedback info. */ - if (pstx_fb->tok) - { - priv->stats.txoktotal++; - - /* We can not make sure broadcast/multicast or unicast mode. */ - if (pstx_fb->pkt_type != PACKET_MULTICAST && - pstx_fb->pkt_type != PACKET_BROADCAST) { - priv->stats.txbytesunicast += pstx_fb->pkt_length; - } - } -} - - - -/* - * The function is responsible for extract the message inside TX - * feedbck message from firmware. It will contain dedicated info in - * ws-06-0063-rtl8190-command-packet-specification. Please - * refer to chapter "TX Feedback Element". We have to read 20 bytes - * in the command packet. - */ -static void cmpk_handle_tx_feedback(struct r8192_priv *priv, u8 *pmsg) -{ - cmpk_txfb_t rx_tx_fb; /* */ - - priv->stats.txfeedback++; - - memcpy((u8*)&rx_tx_fb, pmsg, sizeof(cmpk_txfb_t)); - /* Use tx feedback info to count TX statistics. */ - cmpk_count_txstatistic(priv, &rx_tx_fb); -} - - -/* - * The function is responsible for extract the message from - * firmware. It will contain dedicated info in - * ws-07-0063-v06-rtl819x-command-packet-specification-070315.doc. - * Please refer to chapter "Interrupt Status Element". - */ -static void cmpk_handle_interrupt_status(struct r8192_priv *priv, u8 *pmsg) -{ - cmpk_intr_sta_t rx_intr_status; /* */ - - DMESG("---> cmpk_Handle_Interrupt_Status()\n"); - - /* 1. Extract TX feedback info from RFD to temp structure buffer. */ - /* It seems that FW use big endian(MIPS) and DRV use little endian in - windows OS. So we have to read the content byte by byte or transfer - endian type before copy the message copy. */ - //rx_bcn_state.Element_ID = pMsg[0]; - //rx_bcn_state.Length = pMsg[1]; - rx_intr_status.length = pmsg[1]; - if (rx_intr_status.length != (sizeof(cmpk_intr_sta_t) - 2)) - { - DMESG("cmpk_Handle_Interrupt_Status: wrong length!\n"); - return; - } - - - // Statistics of beacon for ad-hoc mode. - if( priv->ieee80211->iw_mode == IW_MODE_ADHOC) - { - //2 maybe need endian transform? - rx_intr_status.interrupt_status = *((u32 *)(pmsg + 4)); - //rx_intr_status.InterruptStatus = N2H4BYTE(*((UINT32 *)(pMsg + 4))); - - DMESG("interrupt status = 0x%x\n", rx_intr_status.interrupt_status); - - if (rx_intr_status.interrupt_status & ISR_TxBcnOk) - { - priv->ieee80211->bibsscoordinator = true; - priv->stats.txbeaconokint++; - } - else if (rx_intr_status.interrupt_status & ISR_TxBcnErr) - { - priv->ieee80211->bibsscoordinator = false; - priv->stats.txbeaconerr++; - } - } - - // Other informations in interrupt status we need? - - - DMESG("<---- cmpk_handle_interrupt_status()\n"); - -} - - -/* - * The function is responsible for extract the message from - * firmware. It will contain dedicated info in - * ws-06-0063-rtl8190-command-packet-specification. Please - * refer to chapter "Beacon State Element". - */ -static void cmpk_handle_query_config_rx(struct r8192_priv *priv, u8 *pmsg) -{ - cmpk_query_cfg_t rx_query_cfg; /* */ - - /* 0. Display received message. */ - //cmpk_Display_Message(CMPK_RX_BEACON_STATE_SIZE, pMsg); - - /* 1. Extract TX feedback info from RFD to temp structure buffer. */ - /* It seems that FW use big endian(MIPS) and DRV use little endian in - windows OS. So we have to read the content byte by byte or transfer - endian type before copy the message copy. */ - //rx_query_cfg.Element_ID = pMsg[0]; - //rx_query_cfg.Length = pMsg[1]; - rx_query_cfg.cfg_action = (pmsg[4] & 0x80000000)>>31; - rx_query_cfg.cfg_type = (pmsg[4] & 0x60) >> 5; - rx_query_cfg.cfg_size = (pmsg[4] & 0x18) >> 3; - rx_query_cfg.cfg_page = (pmsg[6] & 0x0F) >> 0; - rx_query_cfg.cfg_offset = pmsg[7]; - rx_query_cfg.value = (pmsg[8] << 24) | (pmsg[9] << 16) | - (pmsg[10] << 8) | (pmsg[11] << 0); - rx_query_cfg.mask = (pmsg[12] << 24) | (pmsg[13] << 16) | - (pmsg[14] << 8) | (pmsg[15] << 0); - -} - - -/* - * Count aggregated tx status from firmwar of one type rx command - * packet element id = RX_TX_STATUS. - */ -static void cmpk_count_tx_status(struct r8192_priv *priv, cmpk_tx_status_t *pstx_status) -{ - -#ifdef ENABLE_PS - - RT_RF_POWER_STATE rtstate; - - pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState)); - - // When RF is off, we should not count the packet for hw/sw synchronize - // reason, ie. there may be a duration while sw switch is changed and hw - // switch is being changed. 2006.12.04, by shien chang. - if (rtState == eRfOff) - { - return; - } -#endif - - priv->stats.txfeedbackok += pstx_status->txok; - priv->stats.txoktotal += pstx_status->txok; - - priv->stats.txbytesunicast += pstx_status->txuclength; -} - - - -/* - * Firmware add a new tx feedback status to reduce rx command - * packet buffer operation load. - */ -static void cmpk_handle_tx_status(struct r8192_priv *priv, u8 *pmsg) -{ - cmpk_tx_status_t rx_tx_sts; /* */ - - memcpy((void*)&rx_tx_sts, (void*)pmsg, sizeof(cmpk_tx_status_t)); - /* 2. Use tx feedback info to count TX statistics. */ - cmpk_count_tx_status(priv, &rx_tx_sts); - -} - - -/* Firmware add a new tx rate history */ -static void cmpk_handle_tx_rate_history(struct r8192_priv *priv, u8 *pmsg) -{ - u8 i; - u16 length = sizeof(cmpk_tx_rahis_t); - u32 *ptemp; - -#ifdef ENABLE_PS - pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState)); - - // When RF is off, we should not count the packet for hw/sw synchronize - // reason, ie. there may be a duration while sw switch is changed and hw - // switch is being changed. 2006.12.04, by shien chang. - if (rtState == eRfOff) - { - return; - } -#endif - - ptemp = (u32 *)pmsg; - - // - // Do endian transfer to word alignment(16 bits) for windows system. - // You must do different endian transfer for linux and MAC OS - // - for (i = 0; i < (length/4); i++) - { - u16 temp1, temp2; - - temp1 = ptemp[i]&0x0000FFFF; - temp2 = ptemp[i]>>16; - ptemp[i] = (temp1<<16)|temp2; - } -} - - -/* - * In the function, we will capture different RX command packet - * info. Every RX command packet element has different message - * length and meaning in content. We only support three type of RX - * command packet now. Please refer to document - * ws-06-0063-rtl8190-command-packet-specification. - */ -u32 cmpk_message_handle_rx(struct r8192_priv *priv, struct ieee80211_rx_stats *pstats) -{ -// u32 debug_level = DBG_LOUD; - int total_length; - u8 cmd_length, exe_cnt = 0; - u8 element_id; - u8 *pcmd_buff; - - RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx()\n"); - - /* 0. Check inpt arguments. If is is a command queue message or pointer is - null. */ - if (/*(prfd->queue_id != CMPK_RX_QUEUE_ID) || */(pstats== NULL)) - { - /* Print error message. */ - /*RT_TRACE(COMP_SEND, DebugLevel, - ("\n\r[CMPK]-->Err queue id or pointer"));*/ - return 0; /* This is not a command packet. */ - } - - /* 1. Read received command packet message length from RFD. */ - total_length = pstats->Length; - - /* 2. Read virtual address from RFD. */ - pcmd_buff = pstats->virtual_address; - - /* 3. Read command pakcet element id and length. */ - element_id = pcmd_buff[0]; - /*RT_TRACE(COMP_SEND, DebugLevel, - ("\n\r[CMPK]-->element ID=%d Len=%d", element_id, total_length));*/ - - /* 4. Check every received command packet conent according to different - element type. Because FW may aggregate RX command packet to minimize - transmit time between DRV and FW.*/ - // Add a counter to prevent to locked in the loop too long - while (total_length > 0 || exe_cnt++ >100) - { - /* 2007/01/17 MH We support aggregation of different cmd in the same packet. */ - element_id = pcmd_buff[0]; - - switch(element_id) - { - case RX_TX_FEEDBACK: - - RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():RX_TX_FEEDBACK\n"); - cmpk_handle_tx_feedback(priv, pcmd_buff); - cmd_length = CMPK_RX_TX_FB_SIZE; - break; - - case RX_INTERRUPT_STATUS: - - RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():RX_INTERRUPT_STATUS\n"); - cmpk_handle_interrupt_status(priv, pcmd_buff); - cmd_length = sizeof(cmpk_intr_sta_t); - break; - - case BOTH_QUERY_CONFIG: - - RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():BOTH_QUERY_CONFIG\n"); - cmpk_handle_query_config_rx(priv, pcmd_buff); - cmd_length = CMPK_BOTH_QUERY_CONFIG_SIZE; - break; - - case RX_TX_STATUS: - - RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():RX_TX_STATUS\n"); - cmpk_handle_tx_status(priv, pcmd_buff); - cmd_length = CMPK_RX_TX_STS_SIZE; - break; - - case RX_TX_PER_PKT_FEEDBACK: - // You must at lease add a switch case element here, - // Otherwise, we will jump to default case. - //DbgPrint("CCX Test\r\n"); - RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():RX_TX_PER_PKT_FEEDBACK\n"); - cmd_length = CMPK_RX_TX_FB_SIZE; - break; - - case RX_TX_RATE_HISTORY: - //DbgPrint(" rx tx rate history\r\n"); - - RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():RX_TX_HISTORY\n"); - cmpk_handle_tx_rate_history(priv, pcmd_buff); - cmd_length = CMPK_TX_RAHIS_SIZE; - break; - - default: - - RT_TRACE(COMP_EVENTS, "---->cmpk_message_handle_rx():unknown CMD Element\n"); - return 1; /* This is a command packet. */ - } - - total_length -= cmd_length; - pcmd_buff += cmd_length; - } /* while (total_length > 0) */ - return 1; /* This is a command packet. */ - - RT_TRACE(COMP_EVENTS, "<----cmpk_message_handle_rx()\n"); -} diff --git a/drivers/staging/rtl8192e/r819xE_cmdpkt.h b/drivers/staging/rtl8192e/r819xE_cmdpkt.h deleted file mode 100644 index 312e4f8..0000000 --- a/drivers/staging/rtl8192e/r819xE_cmdpkt.h +++ /dev/null @@ -1,207 +0,0 @@ -#ifndef R819XUSB_CMDPKT_H -#define R819XUSB_CMDPKT_H -/* Different command packet have dedicated message length and definition. */ -#define CMPK_RX_TX_FB_SIZE sizeof(cmpk_txfb_t) //20 -#define CMPK_TX_SET_CONFIG_SIZE sizeof(cmpk_set_cfg_t) //16 -#define CMPK_BOTH_QUERY_CONFIG_SIZE sizeof(cmpk_set_cfg_t) //16 -#define CMPK_RX_TX_STS_SIZE sizeof(cmpk_tx_status_t)// -#define CMPK_RX_DBG_MSG_SIZE sizeof(cmpk_rx_dbginfo_t)// -#define CMPK_TX_RAHIS_SIZE sizeof(cmpk_tx_rahis_t) - -/* 2008/05/08 amy For USB constant. */ -#define ISR_TxBcnOk BIT27 // Transmit Beacon OK -#define ISR_TxBcnErr BIT26 // Transmit Beacon Error -#define ISR_BcnTimerIntr BIT13 // Beacon Timer Interrupt - -#if 0 -/* Define packet type. */ -typedef enum tag_packet_type -{ - PACKET_BROADCAST, - PACKET_MULTICAST, - PACKET_UNICAST, - PACKET_TYPE_MAX -}cmpk_pkt_type_e; -#endif - -/* Define element ID of command packet. */ - -/*------------------------------Define structure----------------------------*/ -/* Define different command packet structure. */ -/* 1. RX side: TX feedback packet. */ -typedef struct tag_cmd_pkt_tx_feedback -{ - // DWORD 0 - u8 element_id; /* Command packet type. */ - u8 length; /* Command packet length. */ - /* 2007/07/05 MH Change tx feedback info field. */ - /*------TX Feedback Info Field */ - u8 TID:4; /* */ - u8 fail_reason:3; /* */ - u8 tok:1; /* Transmit ok. */ - u8 reserve1:4; /* */ - u8 pkt_type:2; /* */ - u8 bandwidth:1; /* */ - u8 qos_pkt:1; /* */ - - // DWORD 1 - u8 reserve2; /* */ - /*------TX Feedback Info Field */ - u8 retry_cnt; /* */ - u16 pkt_id; /* */ - - // DWORD 3 - u16 seq_num; /* */ - u8 s_rate; /* Start rate. */ - u8 f_rate; /* Final rate. */ - - // DWORD 4 - u8 s_rts_rate; /* */ - u8 f_rts_rate; /* */ - u16 pkt_length; /* */ - - // DWORD 5 - u16 reserve3; /* */ - u16 duration; /* */ -}cmpk_txfb_t; - -/* 2. RX side: Interrupt status packet. It includes Beacon State, - Beacon Timer Interrupt and other useful informations in MAC ISR Reg. */ -typedef struct tag_cmd_pkt_interrupt_status -{ - u8 element_id; /* Command packet type. */ - u8 length; /* Command packet length. */ - u16 reserve; - u32 interrupt_status; /* Interrupt Status. */ -}cmpk_intr_sta_t; - - -/* 3. TX side: Set configuration packet. */ -typedef struct tag_cmd_pkt_set_configuration -{ - u8 element_id; /* Command packet type. */ - u8 length; /* Command packet length. */ - u16 reserve1; /* */ - u8 cfg_reserve1:3; - u8 cfg_size:2; /* Configuration info. */ - u8 cfg_type:2; /* Configuration info. */ - u8 cfg_action:1; /* Configuration info. */ - u8 cfg_reserve2; /* Configuration info. */ - u8 cfg_page:4; /* Configuration info. */ - u8 cfg_reserve3:4; /* Configuration info. */ - u8 cfg_offset; /* Configuration info. */ - u32 value; /* */ - u32 mask; /* */ -}cmpk_set_cfg_t; - -/* 4. Both side : TX/RX query configuraton packet. The query structure is the - same as set configuration. */ -#define cmpk_query_cfg_t cmpk_set_cfg_t - -/* 5. Multi packet feedback status. */ -typedef struct tag_tx_stats_feedback // PJ quick rxcmd 09042007 -{ - // For endian transfer --> Driver will not the same as firmware structure. - // DW 0 - u16 reserve1; - u8 length; // Command packet length - u8 element_id; // Command packet type - - // DW 1 - u16 txfail; // Tx Fail count - u16 txok; // Tx ok count - - // DW 2 - u16 txmcok; // tx multicast - u16 txretry; // Tx Retry count - - // DW 3 - u16 txucok; // tx unicast - u16 txbcok; // tx broadcast - - // DW 4 - u16 txbcfail; // - u16 txmcfail; // - - // DW 5 - u16 reserve2; // - u16 txucfail; // - - // DW 6-8 - u32 txmclength; - u32 txbclength; - u32 txuclength; - - // DW 9 - u16 reserve3_23; - u8 reserve3_1; - u8 rate; -}__attribute__((packed)) cmpk_tx_status_t; - -/* 6. Debug feedback message. */ -/* 2007/10/23 MH Define RX debug message */ -typedef struct tag_rx_debug_message_feedback -{ - // For endian transfer --> for driver - // DW 0 - u16 reserve1; - u8 length; // Command packet length - u8 element_id; // Command packet type - - // DW 1-?? - // Variable debug message. - -}cmpk_rx_dbginfo_t; - -/* 2008/03/20 MH Define transmit rate history. For big endian format. */ -typedef struct tag_tx_rate_history -{ - // For endian transfer --> for driver - // DW 0 - u8 element_id; // Command packet type - u8 length; // Command packet length - u16 reserved1; - - // DW 1-2 CCK rate counter - u16 cck[4]; - - // DW 3-6 - u16 ofdm[8]; - - // DW 7-14 - //UINT16 MCS_BW0_SG0[16]; - - // DW 15-22 - //UINT16 MCS_BW1_SG0[16]; - - // DW 23-30 - //UINT16 MCS_BW0_SG1[16]; - - // DW 31-38 - //UINT16 MCS_BW1_SG1[16]; - - // DW 7-14 BW=0 SG=0 - // DW 15-22 BW=1 SG=0 - // DW 23-30 BW=0 SG=1 - // DW 31-38 BW=1 SG=1 - u16 ht_mcs[4][16]; - -}__attribute__((packed)) cmpk_tx_rahis_t; - -typedef enum tag_command_packet_directories -{ - RX_TX_FEEDBACK = 0, - RX_INTERRUPT_STATUS = 1, - TX_SET_CONFIG = 2, - BOTH_QUERY_CONFIG = 3, - RX_TX_STATUS = 4, - RX_DBGINFO_FEEDBACK = 5, - RX_TX_PER_PKT_FEEDBACK = 6, - RX_TX_RATE_HISTORY = 7, - RX_CMD_ELE_MAX -}cmpk_element_e; - -u32 cmpk_message_handle_rx(struct r8192_priv *priv, struct ieee80211_rx_stats *pstats); - - -#endif diff --git a/drivers/staging/rtl8192e/r819xE_firmware.c b/drivers/staging/rtl8192e/r819xE_firmware.c deleted file mode 100644 index d9e8b5a..0000000 --- a/drivers/staging/rtl8192e/r819xE_firmware.c +++ /dev/null @@ -1,351 +0,0 @@ -/* - * Procedure: Init boot code/firmware code/data session - * - * Description: This routine will initialize firmware. If any error occurs - * during the initialization process, the routine shall terminate - * immediately and return fail. - */ - -#include "r8192E.h" -#include "r8192E_hw.h" - -#include <linux/firmware.h> - -/* It should be double word alignment */ -#define GET_COMMAND_PACKET_FRAG_THRESHOLD(v) (4 * (v / 4) - 8) - -enum firmware_init_step { - FW_INIT_STEP0_BOOT = 0, - FW_INIT_STEP1_MAIN = 1, - FW_INIT_STEP2_DATA = 2, -}; - -enum opt_rst_type { - OPT_SYSTEM_RESET = 0, - OPT_FIRMWARE_RESET = 1, -}; - -void firmware_init_param(struct r8192_priv *priv) -{ - rt_firmware *pfirmware = priv->pFirmware; - - pfirmware->cmdpacket_frag_thresold = - GET_COMMAND_PACKET_FRAG_THRESHOLD(MAX_TRANSMIT_BUFFER_SIZE); -} - -/* - * segment the img and use the ptr and length to remember info on each segment - */ -static bool fw_download_code(struct r8192_priv *priv, u8 *code_virtual_address, - u32 buffer_len) -{ - bool rt_status = true; - u16 frag_threshold; - u16 frag_length, frag_offset = 0; - int i; - - rt_firmware *pfirmware = priv->pFirmware; - struct sk_buff *skb; - unsigned char *seg_ptr; - cb_desc *tcb_desc; - u8 bLastIniPkt; - - firmware_init_param(priv); - - /* Fragmentation might be required */ - frag_threshold = pfirmware->cmdpacket_frag_thresold; - do { - if ((buffer_len - frag_offset) > frag_threshold) { - frag_length = frag_threshold ; - bLastIniPkt = 0; - } else { - frag_length = buffer_len - frag_offset; - bLastIniPkt = 1; - } - - /* - * Allocate skb buffer to contain firmware info and tx - * descriptor info add 4 to avoid packet appending overflow. - */ - skb = dev_alloc_skb(frag_length + 4); - tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); - tcb_desc->queue_index = TXCMD_QUEUE; - tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_INIT; - tcb_desc->bLastIniPkt = bLastIniPkt; - - seg_ptr = skb->data; - - /* - * Transform from little endian to big endian and pending zero - */ - for (i = 0; i < frag_length; i += 4) { - *seg_ptr++ = ((i+0) < frag_length) ? - code_virtual_address[i+3] : 0; - - *seg_ptr++ = ((i+1) < frag_length) ? - code_virtual_address[i+2] : 0; - - *seg_ptr++ = ((i+2) < frag_length) ? - code_virtual_address[i+1] : 0; - - *seg_ptr++ = ((i+3) < frag_length) ? - code_virtual_address[i+0] : 0; - } - tcb_desc->txbuf_size = (u16)i; - skb_put(skb, i); - priv->ieee80211->softmac_hard_start_xmit(skb, priv->ieee80211); - - code_virtual_address += frag_length; - frag_offset += frag_length; - - } while (frag_offset < buffer_len); - - return rt_status; -} - -/* - * Check whether main code is download OK. If OK, turn on CPU - * - * CPU register locates in different page against general - * register. Switch to CPU register in the begin and switch - * back before return - */ -static bool CPUcheck_maincodeok_turnonCPU(struct r8192_priv *priv) -{ - unsigned long timeout; - bool rt_status = true; - u32 CPU_status = 0; - - /* Check whether put code OK */ - timeout = jiffies + msecs_to_jiffies(20); - while (time_before(jiffies, timeout)) { - CPU_status = read_nic_dword(priv, CPU_GEN); - - if (CPU_status & CPU_GEN_PUT_CODE_OK) - break; - msleep(2); - } - - if (!(CPU_status & CPU_GEN_PUT_CODE_OK)) { - RT_TRACE(COMP_ERR, "Download Firmware: Put code fail!\n"); - goto CPUCheckMainCodeOKAndTurnOnCPU_Fail; - } else { - RT_TRACE(COMP_FIRMWARE, "Download Firmware: Put code ok!\n"); - } - - /* Turn On CPU */ - CPU_status = read_nic_dword(priv, CPU_GEN); - write_nic_byte(priv, CPU_GEN, - (u8)((CPU_status | CPU_GEN_PWR_STB_CPU) & 0xff)); - mdelay(1); - - /* Check whether CPU boot OK */ - timeout = jiffies + msecs_to_jiffies(20); - while (time_before(jiffies, timeout)) { - CPU_status = read_nic_dword(priv, CPU_GEN); - - if (CPU_status & CPU_GEN_BOOT_RDY) - break; - msleep(2); - } - - if (!(CPU_status & CPU_GEN_BOOT_RDY)) - goto CPUCheckMainCodeOKAndTurnOnCPU_Fail; - else - RT_TRACE(COMP_FIRMWARE, "Download Firmware: Boot ready!\n"); - - return rt_status; - -CPUCheckMainCodeOKAndTurnOnCPU_Fail: - RT_TRACE(COMP_ERR, "ERR in %s()\n", __func__); - rt_status = FALSE; - return rt_status; -} - -static bool CPUcheck_firmware_ready(struct r8192_priv *priv) -{ - unsigned long timeout; - bool rt_status = true; - u32 CPU_status = 0; - - /* Check Firmware Ready */ - timeout = jiffies + msecs_to_jiffies(20); - while (time_before(jiffies, timeout)) { - CPU_status = read_nic_dword(priv, CPU_GEN); - - if (CPU_status & CPU_GEN_FIRM_RDY) - break; - msleep(2); - } - - if (!(CPU_status & CPU_GEN_FIRM_RDY)) - goto CPUCheckFirmwareReady_Fail; - else - RT_TRACE(COMP_FIRMWARE, "Download Firmware: Firmware ready!\n"); - - return rt_status; - -CPUCheckFirmwareReady_Fail: - RT_TRACE(COMP_ERR, "ERR in %s()\n", __func__); - rt_status = false; - return rt_status; - -} - -bool init_firmware(struct r8192_priv *priv) -{ - bool rt_status = true; - u32 file_length = 0; - u8 *mapped_file = NULL; - u32 init_step = 0; - enum opt_rst_type rst_opt = OPT_SYSTEM_RESET; - enum firmware_init_step starting_state = FW_INIT_STEP0_BOOT; - - rt_firmware *pfirmware = priv->pFirmware; - const struct firmware *fw_entry; - const char *fw_name[3] = { "RTL8192E/boot.img", - "RTL8192E/main.img", - "RTL8192E/data.img"}; - int rc; - - RT_TRACE(COMP_FIRMWARE, " PlatformInitFirmware()==>\n"); - - if (pfirmware->firmware_status == FW_STATUS_0_INIT) { - /* it is called by reset */ - rst_opt = OPT_SYSTEM_RESET; - starting_state = FW_INIT_STEP0_BOOT; - /* TODO: system reset */ - - } else if (pfirmware->firmware_status == FW_STATUS_5_READY) { - /* it is called by Initialize */ - rst_opt = OPT_FIRMWARE_RESET; - starting_state = FW_INIT_STEP2_DATA; - } else { - RT_TRACE(COMP_FIRMWARE, - "PlatformInitFirmware: undefined firmware state\n"); - } - - /* - * Download boot, main, and data image for System reset. - * Download data image for firmware reseta - */ - for (init_step = starting_state; init_step <= FW_INIT_STEP2_DATA; - init_step++) { - /* - * Open Image file, and map file to contineous memory if open file success. - * or read image file from array. Default load from IMG file - */ - if (rst_opt == OPT_SYSTEM_RESET) { - if (pfirmware->firmware_buf_size[init_step] == 0) { - rc = request_firmware(&fw_entry, - fw_name[init_step], &priv->pdev->dev); - - if (rc < 0) { - RT_TRACE(COMP_FIRMWARE, "request firmware fail!\n"); - goto download_firmware_fail; - } - - if (fw_entry->size > sizeof(pfirmware->firmware_buf[init_step])) { - RT_TRACE(COMP_FIRMWARE, - "img file size exceed the container buffer fail!\n"); - goto download_firmware_fail; - } - - if (init_step != FW_INIT_STEP1_MAIN) { - memcpy(pfirmware->firmware_buf[init_step], - fw_entry->data, fw_entry->size); - pfirmware->firmware_buf_size[init_step] = fw_entry->size; - - } else { - memset(pfirmware->firmware_buf[init_step], 0, 128); - memcpy(&pfirmware->firmware_buf[init_step][128], fw_entry->data, - fw_entry->size); - pfirmware->firmware_buf_size[init_step] = fw_entry->size+128; - } - - if (rst_opt == OPT_SYSTEM_RESET) - release_firmware(fw_entry); - } - mapped_file = pfirmware->firmware_buf[init_step]; - file_length = pfirmware->firmware_buf_size[init_step]; - - } else if (rst_opt == OPT_FIRMWARE_RESET) { - /* we only need to download data.img here */ - mapped_file = pfirmware->firmware_buf[init_step]; - file_length = pfirmware->firmware_buf_size[init_step]; - } - - /* Download image file */ - /* The firmware download process is just as following, - * 1. that is each packet will be segmented and inserted to the - * wait queue. - * 2. each packet segment will be put in the skb_buff packet. - * 3. each skb_buff packet data content will already include - * the firmware info and Tx descriptor info - */ - rt_status = fw_download_code(priv, mapped_file, file_length); - if (rt_status != TRUE) - goto download_firmware_fail; - - switch (init_step) { - case FW_INIT_STEP0_BOOT: - /* Download boot - * initialize command descriptor. - * will set polling bit when firmware code is also - * configured - */ - pfirmware->firmware_status = FW_STATUS_1_MOVE_BOOT_CODE; - /* mdelay(1000); */ - /* - * To initialize IMEM, CPU move code from 0x80000080, - * hence, we send 0x80 byte packet - */ - break; - - case FW_INIT_STEP1_MAIN: - /* Download firmware code. - * Wait until Boot Ready and Turn on CPU */ - pfirmware->firmware_status = FW_STATUS_2_MOVE_MAIN_CODE; - - /* Check Put Code OK and Turn On CPU */ - rt_status = CPUcheck_maincodeok_turnonCPU(priv); - if (rt_status != TRUE) { - RT_TRACE(COMP_FIRMWARE, - "CPUcheck_maincodeok_turnonCPU fail!\n"); - goto download_firmware_fail; - } - - pfirmware->firmware_status = FW_STATUS_3_TURNON_CPU; - break; - - case FW_INIT_STEP2_DATA: - /* download initial data code */ - pfirmware->firmware_status = FW_STATUS_4_MOVE_DATA_CODE; - mdelay(1); - - rt_status = CPUcheck_firmware_ready(priv); - if (rt_status != TRUE) { - RT_TRACE(COMP_FIRMWARE, - "CPUcheck_firmware_ready fail(%d)!\n", - rt_status); - goto download_firmware_fail; - } - - /* wait until data code is initialized ready.*/ - pfirmware->firmware_status = FW_STATUS_5_READY; - break; - } - } - - RT_TRACE(COMP_FIRMWARE, "Firmware Download Success\n"); - return rt_status; - -download_firmware_fail: - RT_TRACE(COMP_ERR, "ERR in %s() step %d\n", __func__, init_step); - rt_status = false; - return rt_status; -} - -MODULE_FIRMWARE("RTL8192E/boot.img"); -MODULE_FIRMWARE("RTL8192E/main.img"); -MODULE_FIRMWARE("RTL8192E/data.img"); diff --git a/drivers/staging/rtl8192e/r819xE_phy.c b/drivers/staging/rtl8192e/r819xE_phy.c deleted file mode 100644 index 9e7828e..0000000 --- a/drivers/staging/rtl8192e/r819xE_phy.c +++ /dev/null @@ -1,2225 +0,0 @@ -#include "r8192E.h" -#include "r8192E_hw.h" -#include "r819xE_phyreg.h" -#include "r8190_rtl8256.h" -#include "r819xE_phy.h" -#include "r8192E_dm.h" -#ifdef ENABLE_DOT11D -#include "ieee80211/dot11d.h" -#endif -static const u32 RF_CHANNEL_TABLE_ZEBRA[] = { - 0, - 0x085c, //2412 1 - 0x08dc, //2417 2 - 0x095c, //2422 3 - 0x09dc, //2427 4 - 0x0a5c, //2432 5 - 0x0adc, //2437 6 - 0x0b5c, //2442 7 - 0x0bdc, //2447 8 - 0x0c5c, //2452 9 - 0x0cdc, //2457 10 - 0x0d5c, //2462 11 - 0x0ddc, //2467 12 - 0x0e5c, //2472 13 - 0x0f72, //2484 -}; - -static u32 Rtl8192PciEMACPHY_Array[] = { -0x03c,0xffff0000,0x00000f0f, -0x340,0xffffffff,0x161a1a1a, -0x344,0xffffffff,0x12121416, -0x348,0x0000ffff,0x00001818, -0x12c,0xffffffff,0x04000802, -0x318,0x00000fff,0x00000100, -}; -static u32 Rtl8192PciEMACPHY_Array_PG[] = { -0x03c,0xffff0000,0x00000f0f, -0xe00,0xffffffff,0x06090909, -0xe04,0xffffffff,0x00030306, -0xe08,0x0000ff00,0x00000000, -0xe10,0xffffffff,0x0a0c0d0f, -0xe14,0xffffffff,0x06070809, -0xe18,0xffffffff,0x0a0c0d0f, -0xe1c,0xffffffff,0x06070809, -0x12c,0xffffffff,0x04000802, -0x318,0x00000fff,0x00000800, -}; -static u32 Rtl8192PciEAGCTAB_Array[AGCTAB_ArrayLength] = { -0xc78,0x7d000001, -0xc78,0x7d010001, -0xc78,0x7d020001, -0xc78,0x7d030001, -0xc78,0x7d040001, -0xc78,0x7d050001, -0xc78,0x7c060001, -0xc78,0x7b070001, -0xc78,0x7a080001, -0xc78,0x79090001, -0xc78,0x780a0001, -0xc78,0x770b0001, -0xc78,0x760c0001, -0xc78,0x750d0001, -0xc78,0x740e0001, -0xc78,0x730f0001, -0xc78,0x72100001, -0xc78,0x71110001, -0xc78,0x70120001, -0xc78,0x6f130001, -0xc78,0x6e140001, -0xc78,0x6d150001, -0xc78,0x6c160001, -0xc78,0x6b170001, -0xc78,0x6a180001, -0xc78,0x69190001, -0xc78,0x681a0001, -0xc78,0x671b0001, -0xc78,0x661c0001, -0xc78,0x651d0001, -0xc78,0x641e0001, -0xc78,0x491f0001, -0xc78,0x48200001, -0xc78,0x47210001, -0xc78,0x46220001, -0xc78,0x45230001, -0xc78,0x44240001, -0xc78,0x43250001, -0xc78,0x28260001, -0xc78,0x27270001, -0xc78,0x26280001, -0xc78,0x25290001, -0xc78,0x242a0001, -0xc78,0x232b0001, -0xc78,0x222c0001, -0xc78,0x212d0001, -0xc78,0x202e0001, -0xc78,0x0a2f0001, -0xc78,0x08300001, -0xc78,0x06310001, -0xc78,0x05320001, -0xc78,0x04330001, -0xc78,0x03340001, -0xc78,0x02350001, -0xc78,0x01360001, -0xc78,0x00370001, -0xc78,0x00380001, -0xc78,0x00390001, -0xc78,0x003a0001, -0xc78,0x003b0001, -0xc78,0x003c0001, -0xc78,0x003d0001, -0xc78,0x003e0001, -0xc78,0x003f0001, -0xc78,0x7d400001, -0xc78,0x7d410001, -0xc78,0x7d420001, -0xc78,0x7d430001, -0xc78,0x7d440001, -0xc78,0x7d450001, -0xc78,0x7c460001, -0xc78,0x7b470001, -0xc78,0x7a480001, -0xc78,0x79490001, -0xc78,0x784a0001, -0xc78,0x774b0001, -0xc78,0x764c0001, -0xc78,0x754d0001, -0xc78,0x744e0001, -0xc78,0x734f0001, -0xc78,0x72500001, -0xc78,0x71510001, -0xc78,0x70520001, -0xc78,0x6f530001, -0xc78,0x6e540001, -0xc78,0x6d550001, -0xc78,0x6c560001, -0xc78,0x6b570001, -0xc78,0x6a580001, -0xc78,0x69590001, -0xc78,0x685a0001, -0xc78,0x675b0001, -0xc78,0x665c0001, -0xc78,0x655d0001, -0xc78,0x645e0001, -0xc78,0x495f0001, -0xc78,0x48600001, -0xc78,0x47610001, -0xc78,0x46620001, -0xc78,0x45630001, -0xc78,0x44640001, -0xc78,0x43650001, -0xc78,0x28660001, -0xc78,0x27670001, -0xc78,0x26680001, -0xc78,0x25690001, -0xc78,0x246a0001, -0xc78,0x236b0001, -0xc78,0x226c0001, -0xc78,0x216d0001, -0xc78,0x206e0001, -0xc78,0x0a6f0001, -0xc78,0x08700001, -0xc78,0x06710001, -0xc78,0x05720001, -0xc78,0x04730001, -0xc78,0x03740001, -0xc78,0x02750001, -0xc78,0x01760001, -0xc78,0x00770001, -0xc78,0x00780001, -0xc78,0x00790001, -0xc78,0x007a0001, -0xc78,0x007b0001, -0xc78,0x007c0001, -0xc78,0x007d0001, -0xc78,0x007e0001, -0xc78,0x007f0001, -0xc78,0x2e00001e, -0xc78,0x2e01001e, -0xc78,0x2e02001e, -0xc78,0x2e03001e, -0xc78,0x2e04001e, -0xc78,0x2e05001e, -0xc78,0x3006001e, -0xc78,0x3407001e, -0xc78,0x3908001e, -0xc78,0x3c09001e, -0xc78,0x3f0a001e, -0xc78,0x420b001e, -0xc78,0x440c001e, -0xc78,0x450d001e, -0xc78,0x460e001e, -0xc78,0x460f001e, -0xc78,0x4710001e, -0xc78,0x4811001e, -0xc78,0x4912001e, -0xc78,0x4a13001e, -0xc78,0x4b14001e, -0xc78,0x4b15001e, -0xc78,0x4c16001e, -0xc78,0x4d17001e, -0xc78,0x4e18001e, -0xc78,0x4f19001e, -0xc78,0x4f1a001e, -0xc78,0x501b001e, -0xc78,0x511c001e, -0xc78,0x521d001e, -0xc78,0x521e001e, -0xc78,0x531f001e, -0xc78,0x5320001e, -0xc78,0x5421001e, -0xc78,0x5522001e, -0xc78,0x5523001e, -0xc78,0x5624001e, -0xc78,0x5725001e, -0xc78,0x5726001e, -0xc78,0x5827001e, -0xc78,0x5828001e, -0xc78,0x5929001e, -0xc78,0x592a001e, -0xc78,0x5a2b001e, -0xc78,0x5b2c001e, -0xc78,0x5c2d001e, -0xc78,0x5c2e001e, -0xc78,0x5d2f001e, -0xc78,0x5e30001e, -0xc78,0x5f31001e, -0xc78,0x6032001e, -0xc78,0x6033001e, -0xc78,0x6134001e, -0xc78,0x6235001e, -0xc78,0x6336001e, -0xc78,0x6437001e, -0xc78,0x6438001e, -0xc78,0x6539001e, -0xc78,0x663a001e, -0xc78,0x673b001e, -0xc78,0x673c001e, -0xc78,0x683d001e, -0xc78,0x693e001e, -0xc78,0x6a3f001e, -}; -static u32 Rtl8192PciEPHY_REGArray[PHY_REGArrayLength] = { -0x0, }; -static u32 Rtl8192PciEPHY_REG_1T2RArray[PHY_REG_1T2RArrayLength] = { -0x800,0x00000000, -0x804,0x00000001, -0x808,0x0000fc00, -0x80c,0x0000001c, -0x810,0x801010aa, -0x814,0x008514d0, -0x818,0x00000040, -0x81c,0x00000000, -0x820,0x00000004, -0x824,0x00690000, -0x828,0x00000004, -0x82c,0x00e90000, -0x830,0x00000004, -0x834,0x00690000, -0x838,0x00000004, -0x83c,0x00e90000, -0x840,0x00000000, -0x844,0x00000000, -0x848,0x00000000, -0x84c,0x00000000, -0x850,0x00000000, -0x854,0x00000000, -0x858,0x65a965a9, -0x85c,0x65a965a9, -0x860,0x001f0010, -0x864,0x007f0010, -0x868,0x001f0010, -0x86c,0x007f0010, -0x870,0x0f100f70, -0x874,0x0f100f70, -0x878,0x00000000, -0x87c,0x00000000, -0x880,0x6870e36c, -0x884,0xe3573600, -0x888,0x4260c340, -0x88c,0x0000ff00, -0x890,0x00000000, -0x894,0xfffffffe, -0x898,0x4c42382f, -0x89c,0x00656056, -0x8b0,0x00000000, -0x8e0,0x00000000, -0x8e4,0x00000000, -0x900,0x00000000, -0x904,0x00000023, -0x908,0x00000000, -0x90c,0x31121311, -0xa00,0x00d0c7d8, -0xa04,0x811f0008, -0xa08,0x80cd8300, -0xa0c,0x2e62740f, -0xa10,0x95009b78, -0xa14,0x11145008, -0xa18,0x00881117, -0xa1c,0x89140fa0, -0xa20,0x1a1b0000, -0xa24,0x090e1317, -0xa28,0x00000204, -0xa2c,0x00000000, -0xc00,0x00000040, -0xc04,0x00005433, -0xc08,0x000000e4, -0xc0c,0x6c6c6c6c, -0xc10,0x08800000, -0xc14,0x40000100, -0xc18,0x08000000, -0xc1c,0x40000100, -0xc20,0x08000000, -0xc24,0x40000100, -0xc28,0x08000000, -0xc2c,0x40000100, -0xc30,0x6de9ac44, -0xc34,0x465c52cd, -0xc38,0x497f5994, -0xc3c,0x0a969764, -0xc40,0x1f7c403f, -0xc44,0x000100b7, -0xc48,0xec020000, -0xc4c,0x00000300, -0xc50,0x69543420, -0xc54,0x433c0094, -0xc58,0x69543420, -0xc5c,0x433c0094, -0xc60,0x69543420, -0xc64,0x433c0094, -0xc68,0x69543420, -0xc6c,0x433c0094, -0xc70,0x2c7f000d, -0xc74,0x0186175b, -0xc78,0x0000001f, -0xc7c,0x00b91612, -0xc80,0x40000100, -0xc84,0x20000000, -0xc88,0x40000100, -0xc8c,0x20200000, -0xc90,0x40000100, -0xc94,0x00000000, -0xc98,0x40000100, -0xc9c,0x00000000, -0xca0,0x00492492, -0xca4,0x00000000, -0xca8,0x00000000, -0xcac,0x00000000, -0xcb0,0x00000000, -0xcb4,0x00000000, -0xcb8,0x00000000, -0xcbc,0x00492492, -0xcc0,0x00000000, -0xcc4,0x00000000, -0xcc8,0x00000000, -0xccc,0x00000000, -0xcd0,0x00000000, -0xcd4,0x00000000, -0xcd8,0x64b22427, -0xcdc,0x00766932, -0xce0,0x00222222, -0xd00,0x00000750, -0xd04,0x00000403, -0xd08,0x0000907f, -0xd0c,0x00000001, -0xd10,0xa0633333, -0xd14,0x33333c63, -0xd18,0x6a8f5b6b, -0xd1c,0x00000000, -0xd20,0x00000000, -0xd24,0x00000000, -0xd28,0x00000000, -0xd2c,0xcc979975, -0xd30,0x00000000, -0xd34,0x00000000, -0xd38,0x00000000, -0xd3c,0x00027293, -0xd40,0x00000000, -0xd44,0x00000000, -0xd48,0x00000000, -0xd4c,0x00000000, -0xd50,0x6437140a, -0xd54,0x024dbd02, -0xd58,0x00000000, -0xd5c,0x04032064, -0xe00,0x161a1a1a, -0xe04,0x12121416, -0xe08,0x00001800, -0xe0c,0x00000000, -0xe10,0x161a1a1a, -0xe14,0x12121416, -0xe18,0x161a1a1a, -0xe1c,0x12121416, -}; -static u32 Rtl8192PciERadioA_Array[RadioA_ArrayLength] = { -0x019,0x00000003, -0x000,0x000000bf, -0x001,0x00000ee0, -0x002,0x0000004c, -0x003,0x000007f1, -0x004,0x00000975, -0x005,0x00000c58, -0x006,0x00000ae6, -0x007,0x000000ca, -0x008,0x00000e1c, -0x009,0x000007f0, -0x00a,0x000009d0, -0x00b,0x000001ba, -0x00c,0x00000240, -0x00e,0x00000020, -0x00f,0x00000990, -0x012,0x00000806, -0x014,0x000005ab, -0x015,0x00000f80, -0x016,0x00000020, -0x017,0x00000597, -0x018,0x0000050a, -0x01a,0x00000f80, -0x01b,0x00000f5e, -0x01c,0x00000008, -0x01d,0x00000607, -0x01e,0x000006cc, -0x01f,0x00000000, -0x020,0x000001a5, -0x01f,0x00000001, -0x020,0x00000165, -0x01f,0x00000002, -0x020,0x000000c6, -0x01f,0x00000003, -0x020,0x00000086, -0x01f,0x00000004, -0x020,0x00000046, -0x01f,0x00000005, -0x020,0x000001e6, -0x01f,0x00000006, -0x020,0x000001a6, -0x01f,0x00000007, -0x020,0x00000166, -0x01f,0x00000008, -0x020,0x000000c7, -0x01f,0x00000009, -0x020,0x00000087, -0x01f,0x0000000a, -0x020,0x000000f7, -0x01f,0x0000000b, -0x020,0x000000d7, -0x01f,0x0000000c, -0x020,0x000000b7, -0x01f,0x0000000d, -0x020,0x00000097, -0x01f,0x0000000e, -0x020,0x00000077, -0x01f,0x0000000f, -0x020,0x00000057, -0x01f,0x00000010, -0x020,0x00000037, -0x01f,0x00000011, -0x020,0x000000fb, -0x01f,0x00000012, -0x020,0x000000db, -0x01f,0x00000013, -0x020,0x000000bb, -0x01f,0x00000014, -0x020,0x000000ff, -0x01f,0x00000015, -0x020,0x000000e3, -0x01f,0x00000016, -0x020,0x000000c3, -0x01f,0x00000017, -0x020,0x000000a3, -0x01f,0x00000018, -0x020,0x00000083, -0x01f,0x00000019, -0x020,0x00000063, -0x01f,0x0000001a, -0x020,0x00000043, -0x01f,0x0000001b, -0x020,0x00000023, -0x01f,0x0000001c, -0x020,0x00000003, -0x01f,0x0000001d, -0x020,0x000001e3, -0x01f,0x0000001e, -0x020,0x000001c3, -0x01f,0x0000001f, -0x020,0x000001a3, -0x01f,0x00000020, -0x020,0x00000183, -0x01f,0x00000021, -0x020,0x00000163, -0x01f,0x00000022, -0x020,0x00000143, -0x01f,0x00000023, -0x020,0x00000123, -0x01f,0x00000024, -0x020,0x00000103, -0x023,0x00000203, -0x024,0x00000100, -0x00b,0x000001ba, -0x02c,0x000003d7, -0x02d,0x00000ff0, -0x000,0x00000037, -0x004,0x00000160, -0x007,0x00000080, -0x002,0x0000088d, -0x0fe,0x00000000, -0x0fe,0x00000000, -0x016,0x00000200, -0x016,0x00000380, -0x016,0x00000020, -0x016,0x000001a0, -0x000,0x000000bf, -0x00d,0x0000001f, -0x00d,0x00000c9f, -0x002,0x0000004d, -0x000,0x00000cbf, -0x004,0x00000975, -0x007,0x00000700, -}; -static u32 Rtl8192PciERadioB_Array[RadioB_ArrayLength] = { -0x019,0x00000003, -0x000,0x000000bf, -0x001,0x000006e0, -0x002,0x0000004c, -0x003,0x000007f1, -0x004,0x00000975, -0x005,0x00000c58, -0x006,0x00000ae6, -0x007,0x000000ca, -0x008,0x00000e1c, -0x000,0x000000b7, -0x00a,0x00000850, -0x000,0x000000bf, -0x00b,0x000001ba, -0x00c,0x00000240, -0x00e,0x00000020, -0x015,0x00000f80, -0x016,0x00000020, -0x017,0x00000597, -0x018,0x0000050a, -0x01a,0x00000e00, -0x01b,0x00000f5e, -0x01d,0x00000607, -0x01e,0x000006cc, -0x00b,0x000001ba, -0x023,0x00000203, -0x024,0x00000100, -0x000,0x00000037, -0x004,0x00000160, -0x016,0x00000200, -0x016,0x00000380, -0x016,0x00000020, -0x016,0x000001a0, -0x00d,0x00000ccc, -0x000,0x000000bf, -0x002,0x0000004d, -0x000,0x00000cbf, -0x004,0x00000975, -0x007,0x00000700, -}; -static u32 Rtl8192PciERadioC_Array[RadioC_ArrayLength] = { -0x0, }; -static u32 Rtl8192PciERadioD_Array[RadioD_ArrayLength] = { -0x0, }; - -/*************************Define local function prototype**********************/ - -static u32 phy_FwRFSerialRead(struct r8192_priv *priv, RF90_RADIO_PATH_E eRFPath, u32 Offset); -static void phy_FwRFSerialWrite(struct r8192_priv *priv, RF90_RADIO_PATH_E eRFPath, u32 Offset, u32 Data); - -/*************************Define local function prototype**********************/ -/****************************************************************************** - *function: This function read BB parameters from Header file we gen, - * and do register read/write - * input: u32 dwBitMask //taget bit pos in the addr to be modified - * output: none - * return: u32 return the shift bit bit position of the mask - * ****************************************************************************/ -static u32 rtl8192_CalculateBitShift(u32 dwBitMask) -{ - u32 i; - for (i=0; i<=31; i++) - { - if (((dwBitMask>>i)&0x1) == 1) - break; - } - return i; -} -/****************************************************************************** - *function: This function check different RF type to execute legal judgement. If RF Path is illegal, we will return false. - * input: none - * output: none - * return: 0(illegal, false), 1(legal,true) - * ***************************************************************************/ -u8 rtl8192_phy_CheckIsLegalRFPath(struct r8192_priv *priv, u32 eRFPath) -{ - u8 ret = 1; - - if (priv->rf_type == RF_2T4R) - ret = 0; - else if (priv->rf_type == RF_1T2R) - { - if (eRFPath == RF90_PATH_A || eRFPath == RF90_PATH_B) - ret = 1; - else if (eRFPath == RF90_PATH_C || eRFPath == RF90_PATH_D) - ret = 0; - } - - return ret; -} -/****************************************************************************** - *function: This function set specific bits to BB register - * input: net_device dev - * u32 dwRegAddr //target addr to be modified - * u32 dwBitMask //taget bit pos in the addr to be modified - * u32 dwData //value to be write - * output: none - * return: none - * notice: - * ****************************************************************************/ -void rtl8192_setBBreg(struct r8192_priv *priv, u32 dwRegAddr, u32 dwBitMask, u32 dwData) -{ - u32 OriginalValue, BitShift, NewValue; - - if(dwBitMask!= bMaskDWord) - {//if not "double word" write - OriginalValue = read_nic_dword(priv, dwRegAddr); - BitShift = rtl8192_CalculateBitShift(dwBitMask); - NewValue = (((OriginalValue) & (~dwBitMask)) | (dwData << BitShift)); - write_nic_dword(priv, dwRegAddr, NewValue); - }else - write_nic_dword(priv, dwRegAddr, dwData); -} -/****************************************************************************** - *function: This function reads specific bits from BB register - * input: net_device dev - * u32 dwRegAddr //target addr to be readback - * u32 dwBitMask //taget bit pos in the addr to be readback - * output: none - * return: u32 Data //the readback register value - * notice: - * ****************************************************************************/ -u32 rtl8192_QueryBBReg(struct r8192_priv *priv, u32 dwRegAddr, u32 dwBitMask) -{ - u32 OriginalValue, BitShift; - - OriginalValue = read_nic_dword(priv, dwRegAddr); - BitShift = rtl8192_CalculateBitShift(dwBitMask); - return (OriginalValue & dwBitMask) >> BitShift; -} -/****************************************************************************** - *function: This function read register from RF chip - * input: net_device dev - * RF90_RADIO_PATH_E eRFPath //radio path of A/B/C/D - * u32 Offset //target address to be read - * output: none - * return: u32 readback value - * notice: There are three types of serial operations:(1) Software serial write.(2)Hardware LSSI-Low Speed Serial Interface.(3)Hardware HSSI-High speed serial write. Driver here need to implement (1) and (2)---need more spec for this information. - * ****************************************************************************/ -static u32 rtl8192_phy_RFSerialRead(struct r8192_priv *priv, - RF90_RADIO_PATH_E eRFPath, u32 Offset) -{ - u32 ret = 0; - u32 NewOffset = 0; - BB_REGISTER_DEFINITION_T* pPhyReg = &priv->PHYRegDef[eRFPath]; - //rtl8192_setBBreg(dev, pPhyReg->rfLSSIReadBack, bLSSIReadBackData, 0); - //make sure RF register offset is correct - Offset &= 0x3f; - - //switch page for 8256 RF IC - //analog to digital off, for protection - rtl8192_setBBreg(priv, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8] - if (Offset >= 31) - { - priv->RfReg0Value[eRFPath] |= 0x140; - //Switch to Reg_Mode2 for Reg 31-45 - rtl8192_setBBreg(priv, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath]<<16) ); - //modify offset - NewOffset = Offset -30; - } - else if (Offset >= 16) - { - priv->RfReg0Value[eRFPath] |= 0x100; - priv->RfReg0Value[eRFPath] &= (~0x40); - //Switch to Reg_Mode 1 for Reg16-30 - rtl8192_setBBreg(priv, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath]<<16) ); - - NewOffset = Offset - 15; - } - else - NewOffset = Offset; - - //put desired read addr to LSSI control Register - rtl8192_setBBreg(priv, pPhyReg->rfHSSIPara2, bLSSIReadAddress, NewOffset); - //Issue a posedge trigger - // - rtl8192_setBBreg(priv, pPhyReg->rfHSSIPara2, bLSSIReadEdge, 0x0); - rtl8192_setBBreg(priv, pPhyReg->rfHSSIPara2, bLSSIReadEdge, 0x1); - - - // TODO: we should not delay such a long time. Ask help from SD3 - msleep(1); - - ret = rtl8192_QueryBBReg(priv, pPhyReg->rfLSSIReadBack, bLSSIReadBackData); - - - // Switch back to Reg_Mode0; - priv->RfReg0Value[eRFPath] &= 0xebf; - - rtl8192_setBBreg( - priv, - pPhyReg->rf3wireOffset, - bMaskDWord, - (priv->RfReg0Value[eRFPath] << 16)); - - //analog to digital on - rtl8192_setBBreg(priv, rFPGA0_AnalogParameter4, 0x300, 0x3);// 0x88c[9:8] - - return ret; -} - -/****************************************************************************** - *function: This function write data to RF register - * input: net_device dev - * RF90_RADIO_PATH_E eRFPath //radio path of A/B/C/D - * u32 Offset //target address to be written - * u32 Data //The new register data to be written - * output: none - * return: none - * notice: For RF8256 only. - =========================================================== - *Reg Mode RegCTL[1] RegCTL[0] Note - * (Reg00[12]) (Reg00[10]) - *=========================================================== - *Reg_Mode0 0 x Reg 0 ~15(0x0 ~ 0xf) - *------------------------------------------------------------------ - *Reg_Mode1 1 0 Reg 16 ~30(0x1 ~ 0xf) - *------------------------------------------------------------------ - * Reg_Mode2 1 1 Reg 31 ~ 45(0x1 ~ 0xf) - *------------------------------------------------------------------ - * ****************************************************************************/ -static void rtl8192_phy_RFSerialWrite(struct r8192_priv *priv, - RF90_RADIO_PATH_E eRFPath, u32 Offset, - u32 Data) -{ - u32 DataAndAddr = 0, NewOffset = 0; - BB_REGISTER_DEFINITION_T *pPhyReg = &priv->PHYRegDef[eRFPath]; - - Offset &= 0x3f; - - //analog to digital off, for protection - rtl8192_setBBreg(priv, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8] - - if (Offset >= 31) - { - priv->RfReg0Value[eRFPath] |= 0x140; - rtl8192_setBBreg(priv, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath] << 16)); - NewOffset = Offset - 30; - } - else if (Offset >= 16) - { - priv->RfReg0Value[eRFPath] |= 0x100; - priv->RfReg0Value[eRFPath] &= (~0x40); - rtl8192_setBBreg(priv, pPhyReg->rf3wireOffset, bMaskDWord, (priv->RfReg0Value[eRFPath]<<16)); - NewOffset = Offset - 15; - } - else - NewOffset = Offset; - - // Put write addr in [5:0] and write data in [31:16] - DataAndAddr = (Data<<16) | (NewOffset&0x3f); - - // Write Operation - rtl8192_setBBreg(priv, pPhyReg->rf3wireOffset, bMaskDWord, DataAndAddr); - - - if(Offset==0x0) - priv->RfReg0Value[eRFPath] = Data; - - // Switch back to Reg_Mode0; - if(Offset != 0) - { - priv->RfReg0Value[eRFPath] &= 0xebf; - rtl8192_setBBreg( - priv, - pPhyReg->rf3wireOffset, - bMaskDWord, - (priv->RfReg0Value[eRFPath] << 16)); - } - //analog to digital on - rtl8192_setBBreg(priv, rFPGA0_AnalogParameter4, 0x300, 0x3);// 0x88c[9:8] -} - -/****************************************************************************** - *function: This function set specific bits to RF register - * input: RF90_RADIO_PATH_E eRFPath //radio path of A/B/C/D - * u32 RegAddr //target addr to be modified - * u32 BitMask //taget bit pos in the addr to be modified - * u32 Data //value to be write - * output: none - * return: none - * notice: - * ****************************************************************************/ -void rtl8192_phy_SetRFReg(struct r8192_priv *priv, RF90_RADIO_PATH_E eRFPath, - u32 RegAddr, u32 BitMask, u32 Data) -{ - u32 Original_Value, BitShift, New_Value; -// u8 time = 0; - - if (!rtl8192_phy_CheckIsLegalRFPath(priv, eRFPath)) - return; - if (priv->eRFPowerState != eRfOn && !priv->being_init_adapter) - return; - //down(&priv->rf_sem); - - RT_TRACE(COMP_PHY, "FW RF CTRL is not ready now\n"); - if (priv->Rf_Mode == RF_OP_By_FW) - { - if (BitMask != bMask12Bits) // RF data is 12 bits only - { - Original_Value = phy_FwRFSerialRead(priv, eRFPath, RegAddr); - BitShift = rtl8192_CalculateBitShift(BitMask); - New_Value = (((Original_Value) & (~BitMask)) | (Data<< BitShift)); - - phy_FwRFSerialWrite(priv, eRFPath, RegAddr, New_Value); - }else - phy_FwRFSerialWrite(priv, eRFPath, RegAddr, Data); - udelay(200); - - } - else - { - if (BitMask != bMask12Bits) // RF data is 12 bits only - { - Original_Value = rtl8192_phy_RFSerialRead(priv, eRFPath, RegAddr); - BitShift = rtl8192_CalculateBitShift(BitMask); - New_Value = (((Original_Value) & (~BitMask)) | (Data<< BitShift)); - - rtl8192_phy_RFSerialWrite(priv, eRFPath, RegAddr, New_Value); - }else - rtl8192_phy_RFSerialWrite(priv, eRFPath, RegAddr, Data); - } - //up(&priv->rf_sem); -} - -/****************************************************************************** - *function: This function reads specific bits from RF register - * input: net_device dev - * u32 RegAddr //target addr to be readback - * u32 BitMask //taget bit pos in the addr to be readback - * output: none - * return: u32 Data //the readback register value - * notice: - * ****************************************************************************/ -u32 rtl8192_phy_QueryRFReg(struct r8192_priv *priv, RF90_RADIO_PATH_E eRFPath, - u32 RegAddr, u32 BitMask) -{ - u32 Original_Value, Readback_Value, BitShift; - - if (!rtl8192_phy_CheckIsLegalRFPath(priv, eRFPath)) - return 0; - if (priv->eRFPowerState != eRfOn && !priv->being_init_adapter) - return 0; - down(&priv->rf_sem); - if (priv->Rf_Mode == RF_OP_By_FW) - { - Original_Value = phy_FwRFSerialRead(priv, eRFPath, RegAddr); - udelay(200); - } - else - { - Original_Value = rtl8192_phy_RFSerialRead(priv, eRFPath, RegAddr); - - } - BitShift = rtl8192_CalculateBitShift(BitMask); - Readback_Value = (Original_Value & BitMask) >> BitShift; - up(&priv->rf_sem); -// udelay(200); - return Readback_Value; -} - -/****************************************************************************** - *function: We support firmware to execute RF-R/W. - * input: dev - * output: none - * return: none - * notice: - * ***************************************************************************/ -static u32 phy_FwRFSerialRead(struct r8192_priv *priv, - RF90_RADIO_PATH_E eRFPath, u32 Offset) -{ - u32 Data = 0; - u8 time = 0; - //DbgPrint("FW RF CTRL\n\r"); - /* 2007/11/02 MH Firmware RF Write control. By Francis' suggestion, we can - not execute the scheme in the initial step. Otherwise, RF-R/W will waste - much time. This is only for site survey. */ - // 1. Read operation need not insert data. bit 0-11 - //Data &= bMask12Bits; - // 2. Write RF register address. Bit 12-19 - Data |= ((Offset&0xFF)<<12); - // 3. Write RF path. bit 20-21 - Data |= ((eRFPath&0x3)<<20); - // 4. Set RF read indicator. bit 22=0 - //Data |= 0x00000; - // 5. Trigger Fw to operate the command. bit 31 - Data |= 0x80000000; - // 6. We can not execute read operation if bit 31 is 1. - while (read_nic_dword(priv, QPNR)&0x80000000) - { - // If FW can not finish RF-R/W for more than ?? times. We must reset FW. - if (time++ < 100) - { - //DbgPrint("FW not finish RF-R Time=%d\n\r", time); - udelay(10); - } - else - break; - } - // 7. Execute read operation. - write_nic_dword(priv, QPNR, Data); - // 8. Check if firmawre send back RF content. - while (read_nic_dword(priv, QPNR)&0x80000000) - { - // If FW can not finish RF-R/W for more than ?? times. We must reset FW. - if (time++ < 100) - { - //DbgPrint("FW not finish RF-W Time=%d\n\r", time); - udelay(10); - } - else - return 0; - } - return read_nic_dword(priv, RF_DATA); -} - -/****************************************************************************** - *function: We support firmware to execute RF-R/W. - * input: dev - * output: none - * return: none - * notice: - * ***************************************************************************/ -static void phy_FwRFSerialWrite(struct r8192_priv *priv, - RF90_RADIO_PATH_E eRFPath, u32 Offset, u32 Data) -{ - u8 time = 0; - - //DbgPrint("N FW RF CTRL RF-%d OF%02x DATA=%03x\n\r", eRFPath, Offset, Data); - /* 2007/11/02 MH Firmware RF Write control. By Francis' suggestion, we can - not execute the scheme in the initial step. Otherwise, RF-R/W will waste - much time. This is only for site survey. */ - - // 1. Set driver write bit and 12 bit data. bit 0-11 - //Data &= bMask12Bits; // Done by uper layer. - // 2. Write RF register address. bit 12-19 - Data |= ((Offset&0xFF)<<12); - // 3. Write RF path. bit 20-21 - Data |= ((eRFPath&0x3)<<20); - // 4. Set RF write indicator. bit 22=1 - Data |= 0x400000; - // 5. Trigger Fw to operate the command. bit 31=1 - Data |= 0x80000000; - - // 6. Write operation. We can not write if bit 31 is 1. - while (read_nic_dword(priv, QPNR)&0x80000000) - { - // If FW can not finish RF-R/W for more than ?? times. We must reset FW. - if (time++ < 100) - { - //DbgPrint("FW not finish RF-W Time=%d\n\r", time); - udelay(10); - } - else - break; - } - // 7. No matter check bit. We always force the write. Because FW will - // not accept the command. - write_nic_dword(priv, QPNR, Data); - /* 2007/11/02 MH Acoording to test, we must delay 20us to wait firmware - to finish RF write operation. */ - /* 2008/01/17 MH We support delay in firmware side now. */ - //delay_us(20); - -} - - -/****************************************************************************** - *function: This function read BB parameters from Header file we gen, - * and do register read/write - * input: dev - * output: none - * return: none - * notice: BB parameters may change all the time, so please make - * sure it has been synced with the newest. - * ***************************************************************************/ -void rtl8192_phy_configmac(struct r8192_priv *priv) -{ - u32 dwArrayLen = 0, i = 0; - u32* pdwArray = NULL; -#ifdef TO_DO_LIST -if(Adapter->bInHctTest) - { - RT_TRACE(COMP_PHY, "Rtl819XMACPHY_ArrayDTM\n"); - dwArrayLen = MACPHY_ArrayLengthDTM; - pdwArray = Rtl819XMACPHY_ArrayDTM; - } - else if(priv->bTXPowerDataReadFromEEPORM) -#endif - if(priv->bTXPowerDataReadFromEEPORM) - { - RT_TRACE(COMP_PHY, "Rtl819XMACPHY_Array_PG\n"); - dwArrayLen = MACPHY_Array_PGLength; - pdwArray = Rtl819XMACPHY_Array_PG; - - } - else - { - RT_TRACE(COMP_PHY,"Read rtl819XMACPHY_Array\n"); - dwArrayLen = MACPHY_ArrayLength; - pdwArray = Rtl819XMACPHY_Array; - } - for(i = 0; i<dwArrayLen; i=i+3){ - RT_TRACE(COMP_DBG, "The Rtl8190MACPHY_Array[0] is %x Rtl8190MACPHY_Array[1] is %x Rtl8190MACPHY_Array[2] is %x\n", - pdwArray[i], pdwArray[i+1], pdwArray[i+2]); - if(pdwArray[i] == 0x318) - { - pdwArray[i+2] = 0x00000800; - //DbgPrint("ptrArray[i], ptrArray[i+1], ptrArray[i+2] = %x, %x, %x\n", - // ptrArray[i], ptrArray[i+1], ptrArray[i+2]); - } - rtl8192_setBBreg(priv, pdwArray[i], pdwArray[i+1], pdwArray[i+2]); - } -} - -/****************************************************************************** - *function: This function do dirty work - * input: dev - * output: none - * return: none - * notice: BB parameters may change all the time, so please make - * sure it has been synced with the newest. - * ***************************************************************************/ - -void rtl8192_phyConfigBB(struct r8192_priv *priv, u8 ConfigType) -{ - int i; - //u8 ArrayLength; - u32* Rtl819XPHY_REGArray_Table = NULL; - u32* Rtl819XAGCTAB_Array_Table = NULL; - u16 AGCTAB_ArrayLen, PHY_REGArrayLen = 0; -#ifdef TO_DO_LIST - u32 *rtl8192PhyRegArrayTable = NULL, *rtl8192AgcTabArrayTable = NULL; - if(Adapter->bInHctTest) - { - AGCTAB_ArrayLen = AGCTAB_ArrayLengthDTM; - Rtl819XAGCTAB_Array_Table = Rtl819XAGCTAB_ArrayDTM; - - if(priv->RF_Type == RF_2T4R) - { - PHY_REGArrayLen = PHY_REGArrayLengthDTM; - Rtl819XPHY_REGArray_Table = Rtl819XPHY_REGArrayDTM; - } - else if (priv->RF_Type == RF_1T2R) - { - PHY_REGArrayLen = PHY_REG_1T2RArrayLengthDTM; - Rtl819XPHY_REGArray_Table = Rtl819XPHY_REG_1T2RArrayDTM; - } - } - else -#endif - { - AGCTAB_ArrayLen = AGCTAB_ArrayLength; - Rtl819XAGCTAB_Array_Table = Rtl819XAGCTAB_Array; - if(priv->rf_type == RF_2T4R) - { - PHY_REGArrayLen = PHY_REGArrayLength; - Rtl819XPHY_REGArray_Table = Rtl819XPHY_REGArray; - } - else if (priv->rf_type == RF_1T2R) - { - PHY_REGArrayLen = PHY_REG_1T2RArrayLength; - Rtl819XPHY_REGArray_Table = Rtl819XPHY_REG_1T2RArray; - } - } - - if (ConfigType == BaseBand_Config_PHY_REG) - { - for (i=0; i<PHY_REGArrayLen; i+=2) - { - rtl8192_setBBreg(priv, Rtl819XPHY_REGArray_Table[i], bMaskDWord, Rtl819XPHY_REGArray_Table[i+1]); - RT_TRACE(COMP_DBG, "i: %x, The Rtl819xUsbPHY_REGArray[0] is %x Rtl819xUsbPHY_REGArray[1] is %x\n",i, Rtl819XPHY_REGArray_Table[i], Rtl819XPHY_REGArray_Table[i+1]); - } - } - else if (ConfigType == BaseBand_Config_AGC_TAB) - { - for (i=0; i<AGCTAB_ArrayLen; i+=2) - { - rtl8192_setBBreg(priv, Rtl819XAGCTAB_Array_Table[i], bMaskDWord, Rtl819XAGCTAB_Array_Table[i+1]); - RT_TRACE(COMP_DBG, "i:%x, The rtl819XAGCTAB_Array[0] is %x rtl819XAGCTAB_Array[1] is %x\n",i, Rtl819XAGCTAB_Array_Table[i], Rtl819XAGCTAB_Array_Table[i+1]); - } - } -} -/****************************************************************************** - *function: This function initialize Register definition offset for Radio Path - * A/B/C/D - * input: net_device dev - * output: none - * return: none - * notice: Initialization value here is constant and it should never be changed - * ***************************************************************************/ -static void rtl8192_InitBBRFRegDef(struct r8192_priv *priv) -{ -// RF Interface Sowrtware Control - priv->PHYRegDef[RF90_PATH_A].rfintfs = rFPGA0_XAB_RFInterfaceSW; // 16 LSBs if read 32-bit from 0x870 - priv->PHYRegDef[RF90_PATH_B].rfintfs = rFPGA0_XAB_RFInterfaceSW; // 16 MSBs if read 32-bit from 0x870 (16-bit for 0x872) - priv->PHYRegDef[RF90_PATH_C].rfintfs = rFPGA0_XCD_RFInterfaceSW;// 16 LSBs if read 32-bit from 0x874 - priv->PHYRegDef[RF90_PATH_D].rfintfs = rFPGA0_XCD_RFInterfaceSW;// 16 MSBs if read 32-bit from 0x874 (16-bit for 0x876) - - // RF Interface Readback Value - priv->PHYRegDef[RF90_PATH_A].rfintfi = rFPGA0_XAB_RFInterfaceRB; // 16 LSBs if read 32-bit from 0x8E0 - priv->PHYRegDef[RF90_PATH_B].rfintfi = rFPGA0_XAB_RFInterfaceRB;// 16 MSBs if read 32-bit from 0x8E0 (16-bit for 0x8E2) - priv->PHYRegDef[RF90_PATH_C].rfintfi = rFPGA0_XCD_RFInterfaceRB;// 16 LSBs if read 32-bit from 0x8E4 - priv->PHYRegDef[RF90_PATH_D].rfintfi = rFPGA0_XCD_RFInterfaceRB;// 16 MSBs if read 32-bit from 0x8E4 (16-bit for 0x8E6) - - // RF Interface Output (and Enable) - priv->PHYRegDef[RF90_PATH_A].rfintfo = rFPGA0_XA_RFInterfaceOE; // 16 LSBs if read 32-bit from 0x860 - priv->PHYRegDef[RF90_PATH_B].rfintfo = rFPGA0_XB_RFInterfaceOE; // 16 LSBs if read 32-bit from 0x864 - priv->PHYRegDef[RF90_PATH_C].rfintfo = rFPGA0_XC_RFInterfaceOE;// 16 LSBs if read 32-bit from 0x868 - priv->PHYRegDef[RF90_PATH_D].rfintfo = rFPGA0_XD_RFInterfaceOE;// 16 LSBs if read 32-bit from 0x86C - - // RF Interface (Output and) Enable - priv->PHYRegDef[RF90_PATH_A].rfintfe = rFPGA0_XA_RFInterfaceOE; // 16 MSBs if read 32-bit from 0x860 (16-bit for 0x862) - priv->PHYRegDef[RF90_PATH_B].rfintfe = rFPGA0_XB_RFInterfaceOE; // 16 MSBs if read 32-bit from 0x864 (16-bit for 0x866) - priv->PHYRegDef[RF90_PATH_C].rfintfe = rFPGA0_XC_RFInterfaceOE;// 16 MSBs if read 32-bit from 0x86A (16-bit for 0x86A) - priv->PHYRegDef[RF90_PATH_D].rfintfe = rFPGA0_XD_RFInterfaceOE;// 16 MSBs if read 32-bit from 0x86C (16-bit for 0x86E) - - //Addr of LSSI. Wirte RF register by driver - priv->PHYRegDef[RF90_PATH_A].rf3wireOffset = rFPGA0_XA_LSSIParameter; //LSSI Parameter - priv->PHYRegDef[RF90_PATH_B].rf3wireOffset = rFPGA0_XB_LSSIParameter; - priv->PHYRegDef[RF90_PATH_C].rf3wireOffset = rFPGA0_XC_LSSIParameter; - priv->PHYRegDef[RF90_PATH_D].rf3wireOffset = rFPGA0_XD_LSSIParameter; - - // RF parameter - priv->PHYRegDef[RF90_PATH_A].rfLSSI_Select = rFPGA0_XAB_RFParameter; //BB Band Select - priv->PHYRegDef[RF90_PATH_B].rfLSSI_Select = rFPGA0_XAB_RFParameter; - priv->PHYRegDef[RF90_PATH_C].rfLSSI_Select = rFPGA0_XCD_RFParameter; - priv->PHYRegDef[RF90_PATH_D].rfLSSI_Select = rFPGA0_XCD_RFParameter; - - // Tx AGC Gain Stage (same for all path. Should we remove this?) - priv->PHYRegDef[RF90_PATH_A].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage - priv->PHYRegDef[RF90_PATH_B].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage - priv->PHYRegDef[RF90_PATH_C].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage - priv->PHYRegDef[RF90_PATH_D].rfTxGainStage = rFPGA0_TxGainStage; //Tx gain stage - - // Tranceiver A~D HSSI Parameter-1 - priv->PHYRegDef[RF90_PATH_A].rfHSSIPara1 = rFPGA0_XA_HSSIParameter1; //wire control parameter1 - priv->PHYRegDef[RF90_PATH_B].rfHSSIPara1 = rFPGA0_XB_HSSIParameter1; //wire control parameter1 - priv->PHYRegDef[RF90_PATH_C].rfHSSIPara1 = rFPGA0_XC_HSSIParameter1; //wire control parameter1 - priv->PHYRegDef[RF90_PATH_D].rfHSSIPara1 = rFPGA0_XD_HSSIParameter1; //wire control parameter1 - - // Tranceiver A~D HSSI Parameter-2 - priv->PHYRegDef[RF90_PATH_A].rfHSSIPara2 = rFPGA0_XA_HSSIParameter2; //wire control parameter2 - priv->PHYRegDef[RF90_PATH_B].rfHSSIPara2 = rFPGA0_XB_HSSIParameter2; //wire control parameter2 - priv->PHYRegDef[RF90_PATH_C].rfHSSIPara2 = rFPGA0_XC_HSSIParameter2; //wire control parameter2 - priv->PHYRegDef[RF90_PATH_D].rfHSSIPara2 = rFPGA0_XD_HSSIParameter2; //wire control parameter1 - - // RF switch Control - priv->PHYRegDef[RF90_PATH_A].rfSwitchControl = rFPGA0_XAB_SwitchControl; //TR/Ant switch control - priv->PHYRegDef[RF90_PATH_B].rfSwitchControl = rFPGA0_XAB_SwitchControl; - priv->PHYRegDef[RF90_PATH_C].rfSwitchControl = rFPGA0_XCD_SwitchControl; - priv->PHYRegDef[RF90_PATH_D].rfSwitchControl = rFPGA0_XCD_SwitchControl; - - // AGC control 1 - priv->PHYRegDef[RF90_PATH_A].rfAGCControl1 = rOFDM0_XAAGCCore1; - priv->PHYRegDef[RF90_PATH_B].rfAGCControl1 = rOFDM0_XBAGCCore1; - priv->PHYRegDef[RF90_PATH_C].rfAGCControl1 = rOFDM0_XCAGCCore1; - priv->PHYRegDef[RF90_PATH_D].rfAGCControl1 = rOFDM0_XDAGCCore1; - - // AGC control 2 - priv->PHYRegDef[RF90_PATH_A].rfAGCControl2 = rOFDM0_XAAGCCore2; - priv->PHYRegDef[RF90_PATH_B].rfAGCControl2 = rOFDM0_XBAGCCore2; - priv->PHYRegDef[RF90_PATH_C].rfAGCControl2 = rOFDM0_XCAGCCore2; - priv->PHYRegDef[RF90_PATH_D].rfAGCControl2 = rOFDM0_XDAGCCore2; - - // RX AFE control 1 - priv->PHYRegDef[RF90_PATH_A].rfRxIQImbalance = rOFDM0_XARxIQImbalance; - priv->PHYRegDef[RF90_PATH_B].rfRxIQImbalance = rOFDM0_XBRxIQImbalance; - priv->PHYRegDef[RF90_PATH_C].rfRxIQImbalance = rOFDM0_XCRxIQImbalance; - priv->PHYRegDef[RF90_PATH_D].rfRxIQImbalance = rOFDM0_XDRxIQImbalance; - - // RX AFE control 1 - priv->PHYRegDef[RF90_PATH_A].rfRxAFE = rOFDM0_XARxAFE; - priv->PHYRegDef[RF90_PATH_B].rfRxAFE = rOFDM0_XBRxAFE; - priv->PHYRegDef[RF90_PATH_C].rfRxAFE = rOFDM0_XCRxAFE; - priv->PHYRegDef[RF90_PATH_D].rfRxAFE = rOFDM0_XDRxAFE; - - // Tx AFE control 1 - priv->PHYRegDef[RF90_PATH_A].rfTxIQImbalance = rOFDM0_XATxIQImbalance; - priv->PHYRegDef[RF90_PATH_B].rfTxIQImbalance = rOFDM0_XBTxIQImbalance; - priv->PHYRegDef[RF90_PATH_C].rfTxIQImbalance = rOFDM0_XCTxIQImbalance; - priv->PHYRegDef[RF90_PATH_D].rfTxIQImbalance = rOFDM0_XDTxIQImbalance; - - // Tx AFE control 2 - priv->PHYRegDef[RF90_PATH_A].rfTxAFE = rOFDM0_XATxAFE; - priv->PHYRegDef[RF90_PATH_B].rfTxAFE = rOFDM0_XBTxAFE; - priv->PHYRegDef[RF90_PATH_C].rfTxAFE = rOFDM0_XCTxAFE; - priv->PHYRegDef[RF90_PATH_D].rfTxAFE = rOFDM0_XDTxAFE; - - // Tranceiver LSSI Readback - priv->PHYRegDef[RF90_PATH_A].rfLSSIReadBack = rFPGA0_XA_LSSIReadBack; - priv->PHYRegDef[RF90_PATH_B].rfLSSIReadBack = rFPGA0_XB_LSSIReadBack; - priv->PHYRegDef[RF90_PATH_C].rfLSSIReadBack = rFPGA0_XC_LSSIReadBack; - priv->PHYRegDef[RF90_PATH_D].rfLSSIReadBack = rFPGA0_XD_LSSIReadBack; - -} -/****************************************************************************** - *function: This function is to write register and then readback to make sure whether BB and RF is OK - * input: net_device dev - * HW90_BLOCK_E CheckBlock - * RF90_RADIO_PATH_E eRFPath //only used when checkblock is HW90_BLOCK_RF - * output: none - * return: return whether BB and RF is ok(0:OK; 1:Fail) - * notice: This function may be removed in the ASIC - * ***************************************************************************/ -RT_STATUS rtl8192_phy_checkBBAndRF(struct r8192_priv *priv, - HW90_BLOCK_E CheckBlock, - RF90_RADIO_PATH_E eRFPath) -{ -// BB_REGISTER_DEFINITION_T *pPhyReg = &priv->PHYRegDef[eRFPath]; - RT_STATUS ret = RT_STATUS_SUCCESS; - u32 i, CheckTimes = 4, dwRegRead = 0; - u32 WriteAddr[4]; - u32 WriteData[] = {0xfffff027, 0xaa55a02f, 0x00000027, 0x55aa502f}; - // Initialize register address offset to be checked - WriteAddr[HW90_BLOCK_MAC] = 0x100; - WriteAddr[HW90_BLOCK_PHY0] = 0x900; - WriteAddr[HW90_BLOCK_PHY1] = 0x800; - WriteAddr[HW90_BLOCK_RF] = 0x3; - RT_TRACE(COMP_PHY, "=======>%s(), CheckBlock:%d\n", __FUNCTION__, CheckBlock); - for(i=0 ; i < CheckTimes ; i++) - { - - // - // Write Data to register and readback - // - switch(CheckBlock) - { - case HW90_BLOCK_MAC: - RT_TRACE(COMP_ERR, "PHY_CheckBBRFOK(): Never Write 0x100 here!\n"); - break; - - case HW90_BLOCK_PHY0: - case HW90_BLOCK_PHY1: - write_nic_dword(priv, WriteAddr[CheckBlock], WriteData[i]); - dwRegRead = read_nic_dword(priv, WriteAddr[CheckBlock]); - break; - - case HW90_BLOCK_RF: - WriteData[i] &= 0xfff; - rtl8192_phy_SetRFReg(priv, eRFPath, WriteAddr[HW90_BLOCK_RF], bMask12Bits, WriteData[i]); - // TODO: we should not delay for such a long time. Ask SD3 - mdelay(10); - dwRegRead = rtl8192_phy_QueryRFReg(priv, eRFPath, WriteAddr[HW90_BLOCK_RF], bMaskDWord); - mdelay(10); - break; - - default: - ret = RT_STATUS_FAILURE; - break; - } - - - // - // Check whether readback data is correct - // - if(dwRegRead != WriteData[i]) - { - RT_TRACE(COMP_ERR, "====>error=====dwRegRead: %x, WriteData: %x\n", dwRegRead, WriteData[i]); - ret = RT_STATUS_FAILURE; - break; - } - } - - return ret; -} - - -/****************************************************************************** - *function: This function initialize BB&RF - * input: net_device dev - * output: none - * return: none - * notice: Initialization value may change all the time, so please make - * sure it has been synced with the newest. - * ***************************************************************************/ -static RT_STATUS rtl8192_BB_Config_ParaFile(struct r8192_priv *priv) -{ - RT_STATUS rtStatus = RT_STATUS_SUCCESS; - - u8 bRegValue = 0, eCheckItem = 0; - u32 dwRegValue = 0; - /************************************** - //<1>Initialize BaseBand - **************************************/ - - /*--set BB Global Reset--*/ - bRegValue = read_nic_byte(priv, BB_GLOBAL_RESET); - write_nic_byte(priv, BB_GLOBAL_RESET,(bRegValue|BB_GLOBAL_RESET_BIT)); - - /*---set BB reset Active---*/ - dwRegValue = read_nic_dword(priv, CPU_GEN); - write_nic_dword(priv, CPU_GEN, (dwRegValue&(~CPU_GEN_BB_RST))); - - /*----Ckeck FPGAPHY0 and PHY1 board is OK----*/ - // TODO: this function should be removed on ASIC , Emily 2007.2.2 - for(eCheckItem=(HW90_BLOCK_E)HW90_BLOCK_PHY0; eCheckItem<=HW90_BLOCK_PHY1; eCheckItem++) - { - rtStatus = rtl8192_phy_checkBBAndRF(priv, (HW90_BLOCK_E)eCheckItem, (RF90_RADIO_PATH_E)0); //don't care RF path - if(rtStatus != RT_STATUS_SUCCESS) - { - RT_TRACE((COMP_ERR | COMP_PHY), "PHY_RF8256_Config():Check PHY%d Fail!!\n", eCheckItem-1); - return rtStatus; - } - } - /*---- Set CCK and OFDM Block "OFF"----*/ - rtl8192_setBBreg(priv, rFPGA0_RFMOD, bCCKEn|bOFDMEn, 0x0); - /*----BB Register Initilazation----*/ - //==m==>Set PHY REG From Header<==m== - rtl8192_phyConfigBB(priv, BaseBand_Config_PHY_REG); - - /*----Set BB reset de-Active----*/ - dwRegValue = read_nic_dword(priv, CPU_GEN); - write_nic_dword(priv, CPU_GEN, (dwRegValue|CPU_GEN_BB_RST)); - - /*----BB AGC table Initialization----*/ - //==m==>Set PHY REG From Header<==m== - rtl8192_phyConfigBB(priv, BaseBand_Config_AGC_TAB); - - if (priv->card_8192_version > VERSION_8190_BD) - { - if(priv->rf_type == RF_2T4R) - { - // Antenna gain offset from B/C/D to A - dwRegValue = ( priv->AntennaTxPwDiff[2]<<8 | - priv->AntennaTxPwDiff[1]<<4 | - priv->AntennaTxPwDiff[0]); - } - else - dwRegValue = 0x0; //Antenna gain offset doesn't make sense in RF 1T2R. - rtl8192_setBBreg(priv, rFPGA0_TxGainStage, - (bXBTxAGC|bXCTxAGC|bXDTxAGC), dwRegValue); - - - //XSTALLCap - dwRegValue = priv->CrystalCap; - rtl8192_setBBreg(priv, rFPGA0_AnalogParameter1, bXtalCap92x, dwRegValue); - } - - // Check if the CCK HighPower is turned ON. - // This is used to calculate PWDB. -// priv->bCckHighPower = (u8)(rtl8192_QueryBBReg(dev, rFPGA0_XA_HSSIParameter2, 0x200)); - return rtStatus; -} -/****************************************************************************** - *function: This function initialize BB&RF - * input: net_device dev - * output: none - * return: none - * notice: Initialization value may change all the time, so please make - * sure it has been synced with the newest. - * ***************************************************************************/ -RT_STATUS rtl8192_BBConfig(struct r8192_priv *priv) -{ - rtl8192_InitBBRFRegDef(priv); - //config BB&RF. As hardCode based initialization has not been well - //implemented, so use file first.FIXME:should implement it for hardcode? - return rtl8192_BB_Config_ParaFile(priv); -} - -/****************************************************************************** - *function: This function obtains the initialization value of Tx power Level offset - * input: net_device dev - * output: none - * return: none - * ***************************************************************************/ -void rtl8192_phy_getTxPower(struct r8192_priv *priv) -{ - priv->MCSTxPowerLevelOriginalOffset[0] = - read_nic_dword(priv, rTxAGC_Rate18_06); - priv->MCSTxPowerLevelOriginalOffset[1] = - read_nic_dword(priv, rTxAGC_Rate54_24); - priv->MCSTxPowerLevelOriginalOffset[2] = - read_nic_dword(priv, rTxAGC_Mcs03_Mcs00); - priv->MCSTxPowerLevelOriginalOffset[3] = - read_nic_dword(priv, rTxAGC_Mcs07_Mcs04); - priv->MCSTxPowerLevelOriginalOffset[4] = - read_nic_dword(priv, rTxAGC_Mcs11_Mcs08); - priv->MCSTxPowerLevelOriginalOffset[5] = - read_nic_dword(priv, rTxAGC_Mcs15_Mcs12); - - // read rx initial gain - priv->DefaultInitialGain[0] = read_nic_byte(priv, rOFDM0_XAAGCCore1); - priv->DefaultInitialGain[1] = read_nic_byte(priv, rOFDM0_XBAGCCore1); - priv->DefaultInitialGain[2] = read_nic_byte(priv, rOFDM0_XCAGCCore1); - priv->DefaultInitialGain[3] = read_nic_byte(priv, rOFDM0_XDAGCCore1); - RT_TRACE(COMP_INIT, "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x)\n", - priv->DefaultInitialGain[0], priv->DefaultInitialGain[1], - priv->DefaultInitialGain[2], priv->DefaultInitialGain[3]); - - // read framesync - priv->framesync = read_nic_byte(priv, rOFDM0_RxDetector3); - priv->framesyncC34 = read_nic_dword(priv, rOFDM0_RxDetector2); - RT_TRACE(COMP_INIT, "Default framesync (0x%x) = 0x%x\n", - rOFDM0_RxDetector3, priv->framesync); - // read SIFS (save the value read fome MACPHY_REG.txt) - priv->SifsTime = read_nic_word(priv, SIFS); -} - -/****************************************************************************** - *function: This function obtains the initialization value of Tx power Level offset - * input: net_device dev - * output: none - * return: none - * ***************************************************************************/ -void rtl8192_phy_setTxPower(struct r8192_priv *priv, u8 channel) -{ - u8 powerlevel = 0,powerlevelOFDM24G = 0; - char ant_pwr_diff; - u32 u4RegValue; - - if(priv->epromtype == EPROM_93c46) - { - powerlevel = priv->TxPowerLevelCCK[channel-1]; - powerlevelOFDM24G = priv->TxPowerLevelOFDM24G[channel-1]; - } - else if(priv->epromtype == EPROM_93c56) - { - if(priv->rf_type == RF_1T2R) - { - powerlevel = priv->TxPowerLevelCCK_C[channel-1]; - powerlevelOFDM24G = priv->TxPowerLevelOFDM24G_C[channel-1]; - } - else if(priv->rf_type == RF_2T4R) - { - // Mainly we use RF-A Tx Power to write the Tx Power registers, but the RF-C Tx - // Power must be calculated by the antenna diff. - // So we have to rewrite Antenna gain offset register here. - powerlevel = priv->TxPowerLevelCCK_A[channel-1]; - powerlevelOFDM24G = priv->TxPowerLevelOFDM24G_A[channel-1]; - - ant_pwr_diff = priv->TxPowerLevelOFDM24G_C[channel-1] - -priv->TxPowerLevelOFDM24G_A[channel-1]; - ant_pwr_diff &= 0xf; - - priv->AntennaTxPwDiff[2] = 0;// RF-D, don't care - priv->AntennaTxPwDiff[1] = (u8)(ant_pwr_diff);// RF-C - priv->AntennaTxPwDiff[0] = 0;// RF-B, don't care - - // Antenna gain offset from B/C/D to A - u4RegValue = ( priv->AntennaTxPwDiff[2]<<8 | - priv->AntennaTxPwDiff[1]<<4 | - priv->AntennaTxPwDiff[0]); - - rtl8192_setBBreg(priv, rFPGA0_TxGainStage, - (bXBTxAGC|bXCTxAGC|bXDTxAGC), u4RegValue); - } - } -#ifdef TODO - // - // CCX 2 S31, AP control of client transmit power: - // 1. We shall not exceed Cell Power Limit as possible as we can. - // 2. Tolerance is +/- 5dB. - // 3. 802.11h Power Contraint takes higher precedence over CCX Cell Power Limit. - // - // TODO: - // 1. 802.11h power contraint - // - // 071011, by rcnjko. - // - if( pMgntInfo->OpMode == RT_OP_MODE_INFRASTRUCTURE && - pMgntInfo->bWithCcxCellPwr && - channel == pMgntInfo->dot11CurrentChannelNumber) - { - u8 CckCellPwrIdx = DbmToTxPwrIdx(Adapter, WIRELESS_MODE_B, pMgntInfo->CcxCellPwr); - u8 LegacyOfdmCellPwrIdx = DbmToTxPwrIdx(Adapter, WIRELESS_MODE_G, pMgntInfo->CcxCellPwr); - u8 OfdmCellPwrIdx = DbmToTxPwrIdx(Adapter, WIRELESS_MODE_N_24G, pMgntInfo->CcxCellPwr); - - RT_TRACE(COMP_TXAGC, DBG_LOUD, - ("CCX Cell Limit: %d dbm => CCK Tx power index : %d, Legacy OFDM Tx power index : %d, OFDM Tx power index: %d\n", - pMgntInfo->CcxCellPwr, CckCellPwrIdx, LegacyOfdmCellPwrIdx, OfdmCellPwrIdx)); - RT_TRACE(COMP_TXAGC, DBG_LOUD, - ("EEPROM channel(%d) => CCK Tx power index: %d, Legacy OFDM Tx power index : %d, OFDM Tx power index: %d\n", - channel, powerlevel, powerlevelOFDM24G + pHalData->LegacyHTTxPowerDiff, powerlevelOFDM24G)); - - // CCK - if(powerlevel > CckCellPwrIdx) - powerlevel = CckCellPwrIdx; - // Legacy OFDM, HT OFDM - if(powerlevelOFDM24G + pHalData->LegacyHTTxPowerDiff > OfdmCellPwrIdx) - { - if((OfdmCellPwrIdx - pHalData->LegacyHTTxPowerDiff) > 0) - { - powerlevelOFDM24G = OfdmCellPwrIdx - pHalData->LegacyHTTxPowerDiff; - } - else - { - LegacyOfdmCellPwrIdx = 0; - } - } - - RT_TRACE(COMP_TXAGC, DBG_LOUD, - ("Altered CCK Tx power index : %d, Legacy OFDM Tx power index: %d, OFDM Tx power index: %d\n", - powerlevel, powerlevelOFDM24G + pHalData->LegacyHTTxPowerDiff, powerlevelOFDM24G)); - } - - pHalData->CurrentCckTxPwrIdx = powerlevel; - pHalData->CurrentOfdm24GTxPwrIdx = powerlevelOFDM24G; -#endif - PHY_SetRF8256CCKTxPower(priv, powerlevel); //need further implement - PHY_SetRF8256OFDMTxPower(priv, powerlevelOFDM24G); -} - -/****************************************************************************** - *function: This function check Rf chip to do RF config - * input: net_device dev - * output: none - * return: only 8256 is supported - * ***************************************************************************/ -RT_STATUS rtl8192_phy_RFConfig(struct r8192_priv *priv) -{ - return PHY_RF8256_Config(priv); -} - -/****************************************************************************** - *function: This function update Initial gain - * input: net_device dev - * output: none - * return: As Windows has not implemented this, wait for complement - * ***************************************************************************/ -void rtl8192_phy_updateInitGain(struct r8192_priv *priv) -{ -} - -/****************************************************************************** - *function: This function read RF parameters from general head file, and do RF 3-wire - * input: net_device dev - * output: none - * return: return code show if RF configuration is successful(0:pass, 1:fail) - * Note: Delay may be required for RF configuration - * ***************************************************************************/ -u8 rtl8192_phy_ConfigRFWithHeaderFile(struct r8192_priv *priv, - RF90_RADIO_PATH_E eRFPath) -{ - - int i; - //u32* pRFArray; - u8 ret = 0; - - switch(eRFPath){ - case RF90_PATH_A: - for(i = 0;i<RadioA_ArrayLength; i=i+2){ - - if(Rtl819XRadioA_Array[i] == 0xfe){ - msleep(100); - continue; - } - rtl8192_phy_SetRFReg(priv, eRFPath, Rtl819XRadioA_Array[i], bMask12Bits, Rtl819XRadioA_Array[i+1]); - //msleep(1); - - } - break; - case RF90_PATH_B: - for(i = 0;i<RadioB_ArrayLength; i=i+2){ - - if(Rtl819XRadioB_Array[i] == 0xfe){ - msleep(100); - continue; - } - rtl8192_phy_SetRFReg(priv, eRFPath, Rtl819XRadioB_Array[i], bMask12Bits, Rtl819XRadioB_Array[i+1]); - //msleep(1); - - } - break; - case RF90_PATH_C: - for(i = 0;i<RadioC_ArrayLength; i=i+2){ - - if(Rtl819XRadioC_Array[i] == 0xfe){ - msleep(100); - continue; - } - rtl8192_phy_SetRFReg(priv, eRFPath, Rtl819XRadioC_Array[i], bMask12Bits, Rtl819XRadioC_Array[i+1]); - //msleep(1); - - } - break; - case RF90_PATH_D: - for(i = 0;i<RadioD_ArrayLength; i=i+2){ - - if(Rtl819XRadioD_Array[i] == 0xfe){ - msleep(100); - continue; - } - rtl8192_phy_SetRFReg(priv, eRFPath, Rtl819XRadioD_Array[i], bMask12Bits, Rtl819XRadioD_Array[i+1]); - //msleep(1); - - } - break; - default: - break; - } - - return ret; - -} -/****************************************************************************** - *function: This function set Tx Power of the channel - * input: struct net_device *dev - * u8 channel - * output: none - * return: none - * Note: - * ***************************************************************************/ -static void rtl8192_SetTxPowerLevel(struct r8192_priv *priv, u8 channel) -{ - u8 powerlevel = priv->TxPowerLevelCCK[channel-1]; - u8 powerlevelOFDM24G = priv->TxPowerLevelOFDM24G[channel-1]; - - PHY_SetRF8256CCKTxPower(priv, powerlevel); - PHY_SetRF8256OFDMTxPower(priv, powerlevelOFDM24G); -} - -/**************************************************************************************** - *function: This function set command table variable(struct SwChnlCmd). - * input: SwChnlCmd* CmdTable //table to be set. - * u32 CmdTableIdx //variable index in table to be set - * u32 CmdTableSz //table size. - * SwChnlCmdID CmdID //command ID to set. - * u32 Para1 - * u32 Para2 - * u32 msDelay - * output: - * return: true if finished, false otherwise - * Note: - * ************************************************************************************/ -static u8 rtl8192_phy_SetSwChnlCmdArray( - SwChnlCmd* CmdTable, - u32 CmdTableIdx, - u32 CmdTableSz, - SwChnlCmdID CmdID, - u32 Para1, - u32 Para2, - u32 msDelay - ) -{ - SwChnlCmd* pCmd; - - if(CmdTable == NULL) - { - RT_TRACE(COMP_ERR, "phy_SetSwChnlCmdArray(): CmdTable cannot be NULL.\n"); - return false; - } - if(CmdTableIdx >= CmdTableSz) - { - RT_TRACE(COMP_ERR, "phy_SetSwChnlCmdArray(): Access invalid index, please check size of the table, CmdTableIdx:%d, CmdTableSz:%d\n", - CmdTableIdx, CmdTableSz); - return false; - } - - pCmd = CmdTable + CmdTableIdx; - pCmd->CmdID = CmdID; - pCmd->Para1 = Para1; - pCmd->Para2 = Para2; - pCmd->msDelay = msDelay; - - return true; -} -/****************************************************************************** - *function: This function set channel step by step - * input: struct net_device *dev - * u8 channel - * u8* stage //3 stages - * u8* step // - * u32* delay //whether need to delay - * output: store new stage, step and delay for next step(combine with function above) - * return: true if finished, false otherwise - * Note: Wait for simpler function to replace it //wb - * ***************************************************************************/ -static u8 rtl8192_phy_SwChnlStepByStep(struct r8192_priv *priv, u8 channel, - u8* stage, u8* step, u32* delay) -{ -// PCHANNEL_ACCESS_SETTING pChnlAccessSetting; - SwChnlCmd PreCommonCmd[MAX_PRECMD_CNT]; - u32 PreCommonCmdCnt; - SwChnlCmd PostCommonCmd[MAX_POSTCMD_CNT]; - u32 PostCommonCmdCnt; - SwChnlCmd RfDependCmd[MAX_RFDEPENDCMD_CNT]; - u32 RfDependCmdCnt; - SwChnlCmd *CurrentCmd = NULL; - //RF90_RADIO_PATH_E eRFPath; - u8 eRFPath; -// u32 RfRetVal; -// u8 RetryCnt; - - RT_TRACE(COMP_TRACE, "====>%s()====stage:%d, step:%d, channel:%d\n", __FUNCTION__, *stage, *step, channel); -// RT_ASSERT(IsLegalChannel(Adapter, channel), ("illegal channel: %d\n", channel)); - -#ifdef ENABLE_DOT11D - if (!IsLegalChannel(priv->ieee80211, channel)) - { - RT_TRACE(COMP_ERR, "=============>set to illegal channel:%d\n", channel); - return true; //return true to tell upper caller function this channel setting is finished! Or it will in while loop. - } -#endif - - //for(eRFPath = RF90_PATH_A; eRFPath <pHalData->NumTotalRFPath; eRFPath++) - //for(eRFPath = 0; eRFPath <RF90_PATH_MAX; eRFPath++) - { - //if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath)) - // return false; - // <1> Fill up pre common command. - PreCommonCmdCnt = 0; - rtl8192_phy_SetSwChnlCmdArray(PreCommonCmd, PreCommonCmdCnt++, MAX_PRECMD_CNT, - CmdID_SetTxPowerLevel, 0, 0, 0); - rtl8192_phy_SetSwChnlCmdArray(PreCommonCmd, PreCommonCmdCnt++, MAX_PRECMD_CNT, - CmdID_End, 0, 0, 0); - - // <2> Fill up post common command. - PostCommonCmdCnt = 0; - - rtl8192_phy_SetSwChnlCmdArray(PostCommonCmd, PostCommonCmdCnt++, MAX_POSTCMD_CNT, - CmdID_End, 0, 0, 0); - - // <3> Fill up RF dependent command. - RfDependCmdCnt = 0; - - // TEST!! This is not the table for 8256!! - if (!(channel >= 1 && channel <= 14)) - { - RT_TRACE(COMP_ERR, "illegal channel for Zebra 8256: %d\n", channel); - return false; - } - rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT, - CmdID_RF_WriteReg, rZebra1_Channel, channel, 10); - rtl8192_phy_SetSwChnlCmdArray(RfDependCmd, RfDependCmdCnt++, MAX_RFDEPENDCMD_CNT, - CmdID_End, 0, 0, 0); - - do{ - switch(*stage) - { - case 0: - CurrentCmd=&PreCommonCmd[*step]; - break; - case 1: - CurrentCmd=&RfDependCmd[*step]; - break; - case 2: - CurrentCmd=&PostCommonCmd[*step]; - break; - } - - if(CurrentCmd->CmdID==CmdID_End) - { - if((*stage)==2) - { - return true; - } - else - { - (*stage)++; - (*step)=0; - continue; - } - } - - switch(CurrentCmd->CmdID) - { - case CmdID_SetTxPowerLevel: - if(priv->card_8192_version > (u8)VERSION_8190_BD) //xiong: consider it later! - rtl8192_SetTxPowerLevel(priv, channel); - break; - case CmdID_WritePortUlong: - write_nic_dword(priv, CurrentCmd->Para1, CurrentCmd->Para2); - break; - case CmdID_WritePortUshort: - write_nic_word(priv, CurrentCmd->Para1, (u16)CurrentCmd->Para2); - break; - case CmdID_WritePortUchar: - write_nic_byte(priv, CurrentCmd->Para1, (u8)CurrentCmd->Para2); - break; - case CmdID_RF_WriteReg: - for(eRFPath = 0; eRFPath <priv->NumTotalRFPath; eRFPath++) - rtl8192_phy_SetRFReg(priv, (RF90_RADIO_PATH_E)eRFPath, CurrentCmd->Para1, bMask12Bits, CurrentCmd->Para2<<7); - break; - default: - break; - } - - break; - }while(true); - }/*for(Number of RF paths)*/ - - (*delay)=CurrentCmd->msDelay; - (*step)++; - return false; -} - -/****************************************************************************** - *function: This function does acturally set channel work - * input: struct net_device *dev - * u8 channel - * output: none - * return: noin - * Note: We should not call this function directly - * ***************************************************************************/ -static void rtl8192_phy_FinishSwChnlNow(struct r8192_priv *priv, u8 channel) -{ - u32 delay = 0; - - while (!rtl8192_phy_SwChnlStepByStep(priv, channel, &priv->SwChnlStage, &priv->SwChnlStep, &delay)) - { - if(delay>0) - msleep(delay);//or mdelay? need further consideration - if(!priv->up) - break; - } -} -/****************************************************************************** - *function: Callback routine of the work item for switch channel. - * input: - * - * output: none - * return: noin - * ***************************************************************************/ -void rtl8192_SwChnl_WorkItem(struct r8192_priv *priv) -{ - RT_TRACE(COMP_TRACE, "==> SwChnlCallback819xUsbWorkItem()\n"); - - RT_TRACE(COMP_TRACE, "=====>--%s(), set chan:%d, priv:%p\n", __FUNCTION__, priv->chan, priv); - - rtl8192_phy_FinishSwChnlNow(priv, priv->chan); - - RT_TRACE(COMP_TRACE, "<== SwChnlCallback819xUsbWorkItem()\n"); -} - -/****************************************************************************** - *function: This function scheduled actural workitem to set channel - * input: net_device dev - * u8 channel //channel to set - * output: none - * return: return code show if workitem is scheduled(1:pass, 0:fail) - * Note: Delay may be required for RF configuration - * ***************************************************************************/ -u8 rtl8192_phy_SwChnl(struct ieee80211_device *ieee80211, u8 channel) -{ - struct r8192_priv *priv = ieee80211_priv(ieee80211->dev); - - RT_TRACE(COMP_PHY, "=====>%s()\n", __FUNCTION__); - if(!priv->up) - return false; - if(priv->SwChnlInProgress) - return false; - -// if(pHalData->SetBWModeInProgress) -// return; - - //-------------------------------------------- - switch(priv->ieee80211->mode) - { - case WIRELESS_MODE_A: - case WIRELESS_MODE_N_5G: - if (channel<=14){ - RT_TRACE(COMP_ERR, "WIRELESS_MODE_A but channel<=14\n"); - return false; - } - break; - case WIRELESS_MODE_B: - if (channel>14){ - RT_TRACE(COMP_ERR, "WIRELESS_MODE_B but channel>14\n"); - return false; - } - break; - case WIRELESS_MODE_G: - case WIRELESS_MODE_N_24G: - if (channel>14){ - RT_TRACE(COMP_ERR, "WIRELESS_MODE_G but channel>14\n"); - return false; - } - break; - } - //-------------------------------------------- - - priv->SwChnlInProgress = true; - if(channel == 0) - channel = 1; - - priv->chan=channel; - - priv->SwChnlStage=0; - priv->SwChnlStep=0; - if (priv->up) - rtl8192_SwChnl_WorkItem(priv); - - priv->SwChnlInProgress = false; - return true; -} - -static void CCK_Tx_Power_Track_BW_Switch_TSSI(struct r8192_priv *priv) -{ - switch(priv->CurrentChannelBW) - { - /* 20 MHz channel*/ - case HT_CHANNEL_WIDTH_20: - //added by vivi, cck,tx power track, 20080703 - priv->CCKPresentAttentuation = - priv->CCKPresentAttentuation_20Mdefault + priv->CCKPresentAttentuation_difference; - - if(priv->CCKPresentAttentuation > (CCKTxBBGainTableLength-1)) - priv->CCKPresentAttentuation = CCKTxBBGainTableLength-1; - if(priv->CCKPresentAttentuation < 0) - priv->CCKPresentAttentuation = 0; - - RT_TRACE(COMP_POWER_TRACKING, "20M, priv->CCKPresentAttentuation = %d\n", priv->CCKPresentAttentuation); - - if(priv->ieee80211->current_network.channel== 14 && !priv->bcck_in_ch14) - { - priv->bcck_in_ch14 = TRUE; - dm_cck_txpower_adjust(priv, priv->bcck_in_ch14); - } - else if(priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14) - { - priv->bcck_in_ch14 = FALSE; - dm_cck_txpower_adjust(priv, priv->bcck_in_ch14); - } - else - dm_cck_txpower_adjust(priv, priv->bcck_in_ch14); - break; - - /* 40 MHz channel*/ - case HT_CHANNEL_WIDTH_20_40: - //added by vivi, cck,tx power track, 20080703 - priv->CCKPresentAttentuation = - priv->CCKPresentAttentuation_40Mdefault + priv->CCKPresentAttentuation_difference; - - RT_TRACE(COMP_POWER_TRACKING, "40M, priv->CCKPresentAttentuation = %d\n", priv->CCKPresentAttentuation); - if(priv->CCKPresentAttentuation > (CCKTxBBGainTableLength-1)) - priv->CCKPresentAttentuation = CCKTxBBGainTableLength-1; - if(priv->CCKPresentAttentuation < 0) - priv->CCKPresentAttentuation = 0; - - if(priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14) - { - priv->bcck_in_ch14 = TRUE; - dm_cck_txpower_adjust(priv, priv->bcck_in_ch14); - } - else if(priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14) - { - priv->bcck_in_ch14 = FALSE; - dm_cck_txpower_adjust(priv, priv->bcck_in_ch14); - } - else - dm_cck_txpower_adjust(priv, priv->bcck_in_ch14); - break; - } -} - -static void CCK_Tx_Power_Track_BW_Switch_ThermalMeter(struct r8192_priv *priv) -{ - if(priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14) - priv->bcck_in_ch14 = TRUE; - else if(priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14) - priv->bcck_in_ch14 = FALSE; - - //write to default index and tx power track will be done in dm. - switch(priv->CurrentChannelBW) - { - /* 20 MHz channel*/ - case HT_CHANNEL_WIDTH_20: - if(priv->Record_CCK_20Mindex == 0) - priv->Record_CCK_20Mindex = 6; //set default value. - priv->CCK_index = priv->Record_CCK_20Mindex;//6; - RT_TRACE(COMP_POWER_TRACKING, "20MHz, CCK_Tx_Power_Track_BW_Switch_ThermalMeter(),CCK_index = %d\n", priv->CCK_index); - break; - - /* 40 MHz channel*/ - case HT_CHANNEL_WIDTH_20_40: - priv->CCK_index = priv->Record_CCK_40Mindex;//0; - RT_TRACE(COMP_POWER_TRACKING, "40MHz, CCK_Tx_Power_Track_BW_Switch_ThermalMeter(), CCK_index = %d\n", priv->CCK_index); - break; - } - dm_cck_txpower_adjust(priv, priv->bcck_in_ch14); -} - -static void CCK_Tx_Power_Track_BW_Switch(struct r8192_priv *priv) -{ - - //if(pHalData->bDcut == TRUE) - if(priv->IC_Cut >= IC_VersionCut_D) - CCK_Tx_Power_Track_BW_Switch_TSSI(priv); - else - CCK_Tx_Power_Track_BW_Switch_ThermalMeter(priv); -} - - -// -/****************************************************************************** - *function: Callback routine of the work item for set bandwidth mode. - * input: struct net_device *dev - * HT_CHANNEL_WIDTH Bandwidth //20M or 40M - * HT_EXTCHNL_OFFSET Offset //Upper, Lower, or Don't care - * output: none - * return: none - * Note: I doubt whether SetBWModeInProgress flag is necessary as we can - * test whether current work in the queue or not.//do I? - * ***************************************************************************/ -void rtl8192_SetBWModeWorkItem(struct r8192_priv *priv) -{ - u8 regBwOpMode; - - RT_TRACE(COMP_SWBW, "==>rtl8192_SetBWModeWorkItem() Switch to %s bandwidth\n", - priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20?"20MHz":"40MHz") - - - if(!priv->up) - { - priv->SetBWModeInProgress= false; - return; - } - //<1>Set MAC register - regBwOpMode = read_nic_byte(priv, BW_OPMODE); - - switch(priv->CurrentChannelBW) - { - case HT_CHANNEL_WIDTH_20: - regBwOpMode |= BW_OPMODE_20MHZ; - // 2007/02/07 Mark by Emily because we have not verify whether this register works - write_nic_byte(priv, BW_OPMODE, regBwOpMode); - break; - - case HT_CHANNEL_WIDTH_20_40: - regBwOpMode &= ~BW_OPMODE_20MHZ; - // 2007/02/07 Mark by Emily because we have not verify whether this register works - write_nic_byte(priv, BW_OPMODE, regBwOpMode); - break; - - default: - RT_TRACE(COMP_ERR, "SetChannelBandwidth819xUsb(): unknown Bandwidth: %#X\n",priv->CurrentChannelBW); - break; - } - - //<2>Set PHY related register - switch(priv->CurrentChannelBW) - { - case HT_CHANNEL_WIDTH_20: - // Add by Vivi 20071119 - rtl8192_setBBreg(priv, rFPGA0_RFMOD, bRFMOD, 0x0); - rtl8192_setBBreg(priv, rFPGA1_RFMOD, bRFMOD, 0x0); -// rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x00100000, 1); - - // Correct the tx power for CCK rate in 20M. Suggest by YN, 20071207 -// write_nic_dword(dev, rCCK0_TxFilter1, 0x1a1b0000); -// write_nic_dword(dev, rCCK0_TxFilter2, 0x090e1317); -// write_nic_dword(dev, rCCK0_DebugPort, 0x00000204); - if(!priv->btxpower_tracking) - { - write_nic_dword(priv, rCCK0_TxFilter1, 0x1a1b0000); - write_nic_dword(priv, rCCK0_TxFilter2, 0x090e1317); - write_nic_dword(priv, rCCK0_DebugPort, 0x00000204); - } - else - CCK_Tx_Power_Track_BW_Switch(priv); - - rtl8192_setBBreg(priv, rFPGA0_AnalogParameter1, 0x00100000, 1); - break; - case HT_CHANNEL_WIDTH_20_40: - // Add by Vivi 20071119 - rtl8192_setBBreg(priv, rFPGA0_RFMOD, bRFMOD, 0x1); - rtl8192_setBBreg(priv, rFPGA1_RFMOD, bRFMOD, 0x1); - //rtl8192_setBBreg(dev, rCCK0_System, bCCKSideBand, (priv->nCur40MhzPrimeSC>>1)); - //rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x00100000, 0); - //rtl8192_setBBreg(dev, rOFDM1_LSTF, 0xC00, priv->nCur40MhzPrimeSC); - - // Correct the tx power for CCK rate in 40M. Suggest by YN, 20071207 - //write_nic_dword(dev, rCCK0_TxFilter1, 0x35360000); - //write_nic_dword(dev, rCCK0_TxFilter2, 0x121c252e); - //write_nic_dword(dev, rCCK0_DebugPort, 0x00000409); - if(!priv->btxpower_tracking) - { - write_nic_dword(priv, rCCK0_TxFilter1, 0x35360000); - write_nic_dword(priv, rCCK0_TxFilter2, 0x121c252e); - write_nic_dword(priv, rCCK0_DebugPort, 0x00000409); - } - else - CCK_Tx_Power_Track_BW_Switch(priv); - - // Set Control channel to upper or lower. These settings are required only for 40MHz - rtl8192_setBBreg(priv, rCCK0_System, bCCKSideBand, (priv->nCur40MhzPrimeSC>>1)); - rtl8192_setBBreg(priv, rOFDM1_LSTF, 0xC00, priv->nCur40MhzPrimeSC); - - - rtl8192_setBBreg(priv, rFPGA0_AnalogParameter1, 0x00100000, 0); - break; - default: - RT_TRACE(COMP_ERR, "SetChannelBandwidth819xUsb(): unknown Bandwidth: %#X\n" ,priv->CurrentChannelBW); - break; - - } - //Skip over setting of J-mode in BB register here. Default value is "None J mode". Emily 20070315 - - //<3>Set RF related register - PHY_SetRF8256Bandwidth(priv, priv->CurrentChannelBW); - - atomic_dec(&(priv->ieee80211->atm_swbw)); - priv->SetBWModeInProgress= false; - - RT_TRACE(COMP_SWBW, "<==SetBWMode819xUsb()\n"); -} - -/****************************************************************************** - *function: This function schedules bandwidth switch work. - * input: struct net_device *dev - * HT_CHANNEL_WIDTH Bandwidth //20M or 40M - * HT_EXTCHNL_OFFSET Offset //Upper, Lower, or Don't care - * output: none - * return: none - * Note: I doubt whether SetBWModeInProgress flag is necessary as we can - * test whether current work in the queue or not.//do I? - * ***************************************************************************/ -void rtl8192_SetBWMode(struct ieee80211_device *ieee, HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset) -{ - struct r8192_priv *priv = ieee80211_priv(ieee->dev); - - - if(priv->SetBWModeInProgress) - return; - - atomic_inc(&(priv->ieee80211->atm_swbw)); - priv->SetBWModeInProgress= true; - - priv->CurrentChannelBW = Bandwidth; - - if(Offset==HT_EXTCHNL_OFFSET_LOWER) - priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_UPPER; - else if(Offset==HT_EXTCHNL_OFFSET_UPPER) - priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_LOWER; - else - priv->nCur40MhzPrimeSC = HAL_PRIME_CHNL_OFFSET_DONT_CARE; - - //queue_work(priv->priv_wq, &(priv->SetBWModeWorkItem)); - // schedule_work(&(priv->SetBWModeWorkItem)); - rtl8192_SetBWModeWorkItem(priv); - -} - - -void InitialGain819xPci(struct ieee80211_device *ieee, u8 Operation) -{ -#define SCAN_RX_INITIAL_GAIN 0x17 -#define POWER_DETECTION_TH 0x08 - struct r8192_priv *priv = ieee80211_priv(ieee->dev); - u32 BitMask; - u8 initial_gain; - - if(priv->up) - { - switch(Operation) - { - case IG_Backup: - RT_TRACE(COMP_SCAN, "IG_Backup, backup the initial gain.\n"); - initial_gain = SCAN_RX_INITIAL_GAIN;//pHalData->DefaultInitialGain[0];// - BitMask = bMaskByte0; - if(dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM) - rtl8192_setBBreg(priv, UFWP, bMaskByte1, 0x8); // FW DIG OFF - priv->initgain_backup.xaagccore1 = (u8)rtl8192_QueryBBReg(priv, rOFDM0_XAAGCCore1, BitMask); - priv->initgain_backup.xbagccore1 = (u8)rtl8192_QueryBBReg(priv, rOFDM0_XBAGCCore1, BitMask); - priv->initgain_backup.xcagccore1 = (u8)rtl8192_QueryBBReg(priv, rOFDM0_XCAGCCore1, BitMask); - priv->initgain_backup.xdagccore1 = (u8)rtl8192_QueryBBReg(priv, rOFDM0_XDAGCCore1, BitMask); - BitMask = bMaskByte2; - priv->initgain_backup.cca = (u8)rtl8192_QueryBBReg(priv, rCCK0_CCA, BitMask); - - RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc50 is %x\n",priv->initgain_backup.xaagccore1); - RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc58 is %x\n",priv->initgain_backup.xbagccore1); - RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc60 is %x\n",priv->initgain_backup.xcagccore1); - RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xc68 is %x\n",priv->initgain_backup.xdagccore1); - RT_TRACE(COMP_SCAN, "Scan InitialGainBackup 0xa0a is %x\n",priv->initgain_backup.cca); - - RT_TRACE(COMP_SCAN, "Write scan initial gain = 0x%x \n", initial_gain); - write_nic_byte(priv, rOFDM0_XAAGCCore1, initial_gain); - write_nic_byte(priv, rOFDM0_XBAGCCore1, initial_gain); - write_nic_byte(priv, rOFDM0_XCAGCCore1, initial_gain); - write_nic_byte(priv, rOFDM0_XDAGCCore1, initial_gain); - RT_TRACE(COMP_SCAN, "Write scan 0xa0a = 0x%x \n", POWER_DETECTION_TH); - write_nic_byte(priv, 0xa0a, POWER_DETECTION_TH); - break; - case IG_Restore: - RT_TRACE(COMP_SCAN, "IG_Restore, restore the initial gain.\n"); - BitMask = 0x7f; //Bit0~ Bit6 - if(dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM) - rtl8192_setBBreg(priv, UFWP, bMaskByte1, 0x8); // FW DIG OFF - - rtl8192_setBBreg(priv, rOFDM0_XAAGCCore1, BitMask, (u32)priv->initgain_backup.xaagccore1); - rtl8192_setBBreg(priv, rOFDM0_XBAGCCore1, BitMask, (u32)priv->initgain_backup.xbagccore1); - rtl8192_setBBreg(priv, rOFDM0_XCAGCCore1, BitMask, (u32)priv->initgain_backup.xcagccore1); - rtl8192_setBBreg(priv, rOFDM0_XDAGCCore1, BitMask, (u32)priv->initgain_backup.xdagccore1); - BitMask = bMaskByte2; - rtl8192_setBBreg(priv, rCCK0_CCA, BitMask, (u32)priv->initgain_backup.cca); - - RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc50 is %x\n",priv->initgain_backup.xaagccore1); - RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc58 is %x\n",priv->initgain_backup.xbagccore1); - RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc60 is %x\n",priv->initgain_backup.xcagccore1); - RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xc68 is %x\n",priv->initgain_backup.xdagccore1); - RT_TRACE(COMP_SCAN, "Scan BBInitialGainRestore 0xa0a is %x\n",priv->initgain_backup.cca); - - rtl8192_phy_setTxPower(priv, priv->ieee80211->current_network.channel); - - - if(dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM) - rtl8192_setBBreg(priv, UFWP, bMaskByte1, 0x1); // FW DIG ON - break; - default: - RT_TRACE(COMP_SCAN, "Unknown IG Operation.\n"); - break; - } - } -} - diff --git a/drivers/staging/rtl8192e/r819xE_phy.h b/drivers/staging/rtl8192e/r819xE_phy.h deleted file mode 100644 index 496e76f..0000000 --- a/drivers/staging/rtl8192e/r819xE_phy.h +++ /dev/null @@ -1,131 +0,0 @@ -#ifndef _R819XU_PHY_H -#define _R819XU_PHY_H - -/* Channel switch: the size of command tables for switch channel */ -#define MAX_PRECMD_CNT 16 -#define MAX_RFDEPENDCMD_CNT 16 -#define MAX_POSTCMD_CNT 16 - -#define MACPHY_Array_PGLength 30 -#define Rtl819XMACPHY_Array_PG Rtl8192PciEMACPHY_Array_PG -#define Rtl819XMACPHY_Array Rtl8192PciEMACPHY_Array -#define RadioC_ArrayLength 1 -#define RadioD_ArrayLength 1 -#define Rtl819XRadioA_Array Rtl8192PciERadioA_Array -#define Rtl819XRadioB_Array Rtl8192PciERadioB_Array -#define Rtl819XRadioC_Array Rtl8192PciERadioC_Array -#define Rtl819XRadioD_Array Rtl8192PciERadioD_Array -#define Rtl819XAGCTAB_Array Rtl8192PciEAGCTAB_Array -#define PHY_REGArrayLength 1 -#define Rtl819XPHY_REGArray Rtl8192PciEPHY_REGArray -#define PHY_REG_1T2RArrayLength 296 -#define Rtl819XPHY_REG_1T2RArray Rtl8192PciEPHY_REG_1T2RArray - -#define AGCTAB_ArrayLength 384 -#define MACPHY_ArrayLength 18 - -#define RadioA_ArrayLength 246 -#define RadioB_ArrayLength 78 - - -typedef enum _SwChnlCmdID { - CmdID_End, - CmdID_SetTxPowerLevel, - CmdID_BBRegWrite10, - CmdID_WritePortUlong, - CmdID_WritePortUshort, - CmdID_WritePortUchar, - CmdID_RF_WriteReg, -} SwChnlCmdID; - -/* switch channel data structure */ -typedef struct _SwChnlCmd { - SwChnlCmdID CmdID; - u32 Para1; - u32 Para2; - u32 msDelay; -} __attribute__ ((packed)) SwChnlCmd; - -extern u32 rtl819XMACPHY_Array_PG[]; -extern u32 rtl819XPHY_REG_1T2RArray[]; -extern u32 rtl819XAGCTAB_Array[]; -extern u32 rtl819XRadioA_Array[]; -extern u32 rtl819XRadioB_Array[]; -extern u32 rtl819XRadioC_Array[]; -extern u32 rtl819XRadioD_Array[]; - -typedef enum _HW90_BLOCK { - HW90_BLOCK_MAC = 0, - HW90_BLOCK_PHY0 = 1, - HW90_BLOCK_PHY1 = 2, - HW90_BLOCK_RF = 3, - /* Don't ever use this. */ - HW90_BLOCK_MAXIMUM = 4, -} HW90_BLOCK_E, *PHW90_BLOCK_E; - -typedef enum _RF90_RADIO_PATH { - /* Radio paths */ - RF90_PATH_A = 0, - RF90_PATH_B = 1, - RF90_PATH_C = 2, - RF90_PATH_D = 3, - - /* Max RF number 92 support */ - RF90_PATH_MAX -} RF90_RADIO_PATH_E, *PRF90_RADIO_PATH_E; - -#define bMaskByte0 0xff -#define bMaskByte1 0xff00 -#define bMaskByte2 0xff0000 -#define bMaskByte3 0xff000000 -#define bMaskHWord 0xffff0000 -#define bMaskLWord 0x0000ffff -#define bMaskDWord 0xffffffff - -u8 rtl8192_phy_CheckIsLegalRFPath(struct r8192_priv *priv, u32 eRFPath); - -void rtl8192_setBBreg(struct r8192_priv *priv, u32 dwRegAddr, - u32 dwBitMask, u32 dwData); - -u32 rtl8192_QueryBBReg(struct r8192_priv *priv, u32 dwRegAddr, - u32 dwBitMask); - -void rtl8192_phy_SetRFReg(struct r8192_priv *priv, - RF90_RADIO_PATH_E eRFPath, u32 RegAddr, - u32 BitMask, u32 Data); - -u32 rtl8192_phy_QueryRFReg(struct r8192_priv *priv, - RF90_RADIO_PATH_E eRFPath, u32 RegAddr, u32 BitMask); - -void rtl8192_phy_configmac(struct r8192_priv *priv); - -void rtl8192_phyConfigBB(struct r8192_priv *priv, u8 ConfigType); - -RT_STATUS rtl8192_phy_checkBBAndRF(struct r8192_priv *priv, - HW90_BLOCK_E CheckBlock, RF90_RADIO_PATH_E eRFPath); - -RT_STATUS rtl8192_BBConfig(struct r8192_priv *priv); - -void rtl8192_phy_getTxPower(struct r8192_priv *priv); - -void rtl8192_phy_setTxPower(struct r8192_priv *priv, u8 channel); - -RT_STATUS rtl8192_phy_RFConfig(struct r8192_priv *priv); - -void rtl8192_phy_updateInitGain(struct r8192_priv *priv); - -u8 rtl8192_phy_ConfigRFWithHeaderFile(struct r8192_priv *priv, - RF90_RADIO_PATH_E eRFPath); - -u8 rtl8192_phy_SwChnl(struct ieee80211_device *ieee80211, u8 channel); - -void rtl8192_SetBWMode(struct ieee80211_device *ieee80211, - HT_CHANNEL_WIDTH Bandwidth, HT_EXTCHNL_OFFSET Offset); - -void rtl8192_SwChnl_WorkItem(struct r8192_priv *priv); - -void rtl8192_SetBWModeWorkItem(struct r8192_priv *priv); - -void InitialGain819xPci(struct ieee80211_device *ieee, u8 Operation); - -#endif /* _R819XU_PHY_H */ diff --git a/drivers/staging/rtl8192e/rtl819x_BA.h b/drivers/staging/rtl8192e/rtl819x_BA.h new file mode 100644 index 0000000..613e14c --- /dev/null +++ b/drivers/staging/rtl8192e/rtl819x_BA.h @@ -0,0 +1,77 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> +******************************************************************************/ +#ifndef _BATYPE_H_ +#define _BATYPE_H_ + +#define TOTAL_TXBA_NUM 16 +#define TOTAL_RXBA_NUM 16 + +#define BA_SETUP_TIMEOUT 200 +#define BA_INACT_TIMEOUT 60000 + +#define BA_POLICY_DELAYED 0 +#define BA_POLICY_IMMEDIATE 1 + +#define ADDBA_STATUS_SUCCESS 0 +#define ADDBA_STATUS_REFUSED 37 +#define ADDBA_STATUS_INVALID_PARAM 38 + +#define DELBA_REASON_QSTA_LEAVING 36 +#define DELBA_REASON_END_BA 37 +#define DELBA_REASON_UNKNOWN_BA 38 +#define DELBA_REASON_TIMEOUT 39 +union sequence_control { + u16 ShortData; + struct { + u16 FragNum:4; + u16 SeqNum:12; + } field; +}; + +union ba_param_set { + u8 charData[2]; + u16 shortData; + struct { + u16 AMSDU_Support:1; + u16 BAPolicy:1; + u16 TID:4; + u16 BufferSize:10; + } field; +}; + +union delba_param_set { + u8 charData[2]; + u16 shortData; + struct { + u16 Reserved:11; + u16 Initiator:1; + u16 TID:4; + } field; +}; + +struct ba_record { + struct timer_list Timer; + u8 bValid; + u8 DialogToken; + union ba_param_set BaParamSet; + u16 BaTimeoutValue; + union sequence_control BaStartSeqCtrl; +}; + +#endif diff --git a/drivers/staging/rtl8192e/rtl819x_BAProc.c b/drivers/staging/rtl8192e/rtl819x_BAProc.c new file mode 100644 index 0000000..48f9f71 --- /dev/null +++ b/drivers/staging/rtl8192e/rtl819x_BAProc.c @@ -0,0 +1,566 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> +******************************************************************************/ +#include "rtllib.h" +#include "rtl819x_BA.h" +#include "rtl_core.h" + +static void ActivateBAEntry(struct rtllib_device *ieee, struct ba_record *pBA, + u16 Time) +{ + pBA->bValid = true; + if (Time != 0) + mod_timer(&pBA->Timer, jiffies + MSECS(Time)); +} + +static void DeActivateBAEntry(struct rtllib_device *ieee, struct ba_record *pBA) +{ + pBA->bValid = false; + del_timer_sync(&pBA->Timer); +} + +static u8 TxTsDeleteBA(struct rtllib_device *ieee, struct tx_ts_record *pTxTs) +{ + struct ba_record *pAdmittedBa = &pTxTs->TxAdmittedBARecord; + struct ba_record *pPendingBa = &pTxTs->TxPendingBARecord; + u8 bSendDELBA = false; + + if (pPendingBa->bValid) { + DeActivateBAEntry(ieee, pPendingBa); + bSendDELBA = true; + } + + if (pAdmittedBa->bValid) { + DeActivateBAEntry(ieee, pAdmittedBa); + bSendDELBA = true; + } + return bSendDELBA; +} + +static u8 RxTsDeleteBA(struct rtllib_device *ieee, struct rx_ts_record *pRxTs) +{ + struct ba_record *pBa = &pRxTs->RxAdmittedBARecord; + u8 bSendDELBA = false; + + if (pBa->bValid) { + DeActivateBAEntry(ieee, pBa); + bSendDELBA = true; + } + + return bSendDELBA; +} + +void ResetBaEntry(struct ba_record *pBA) +{ + pBA->bValid = false; + pBA->BaParamSet.shortData = 0; + pBA->BaTimeoutValue = 0; + pBA->DialogToken = 0; + pBA->BaStartSeqCtrl.ShortData = 0; +} +static struct sk_buff *rtllib_ADDBA(struct rtllib_device *ieee, u8 *Dst, + struct ba_record *pBA, + u16 StatusCode, u8 type) +{ + struct sk_buff *skb = NULL; + struct rtllib_hdr_3addr *BAReq = NULL; + u8 *tag = NULL; + u16 tmp = 0; + u16 len = ieee->tx_headroom + 9; + RTLLIB_DEBUG(RTLLIB_DL_TRACE | RTLLIB_DL_BA, "========>%s(), frame(%d)" + " sentd to: %pM, ieee->dev:%p\n", __func__, + type, Dst, ieee->dev); + if (pBA == NULL || ieee == NULL) { + RTLLIB_DEBUG(RTLLIB_DL_ERR, "pBA(%p) is NULL or ieee(%p) is " + "NULL\n", pBA, ieee); + return NULL; + } + skb = dev_alloc_skb(len + sizeof(struct rtllib_hdr_3addr)); + if (skb == NULL) { + RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't alloc skb for ADDBA_REQ\n"); + return NULL; + } + + memset(skb->data, 0, sizeof(struct rtllib_hdr_3addr)); + + skb_reserve(skb, ieee->tx_headroom); + + BAReq = (struct rtllib_hdr_3addr *)skb_put(skb, + sizeof(struct rtllib_hdr_3addr)); + + memcpy(BAReq->addr1, Dst, ETH_ALEN); + memcpy(BAReq->addr2, ieee->dev->dev_addr, ETH_ALEN); + + memcpy(BAReq->addr3, ieee->current_network.bssid, ETH_ALEN); + BAReq->frame_ctl = cpu_to_le16(RTLLIB_STYPE_MANAGE_ACT); + + tag = (u8 *)skb_put(skb, 9); + *tag ++= ACT_CAT_BA; + *tag ++= type; + *tag ++= pBA->DialogToken; + + if (ACT_ADDBARSP == type) { + RT_TRACE(COMP_DBG, "====>to send ADDBARSP\n"); + tmp = cpu_to_le16(StatusCode); + memcpy(tag, (u8 *)&tmp, 2); + tag += 2; + } + tmp = cpu_to_le16(pBA->BaParamSet.shortData); + memcpy(tag, (u8 *)&tmp, 2); + tag += 2; + tmp = cpu_to_le16(pBA->BaTimeoutValue); + memcpy(tag, (u8 *)&tmp, 2); + tag += 2; + + if (ACT_ADDBAREQ == type) { + memcpy(tag, (u8 *)&(pBA->BaStartSeqCtrl), 2); + tag += 2; + } + + RTLLIB_DEBUG_DATA(RTLLIB_DL_DATA|RTLLIB_DL_BA, skb->data, skb->len); + return skb; +} + +static struct sk_buff *rtllib_DELBA(struct rtllib_device *ieee, u8 *dst, + struct ba_record *pBA, + enum tr_select TxRxSelect, u16 ReasonCode) +{ + union delba_param_set DelbaParamSet; + struct sk_buff *skb = NULL; + struct rtllib_hdr_3addr *Delba = NULL; + u8 *tag = NULL; + u16 tmp = 0; + u16 len = 6 + ieee->tx_headroom; + + if (net_ratelimit()) + RTLLIB_DEBUG(RTLLIB_DL_TRACE | RTLLIB_DL_BA, + "========>%s(), Reason" + "Code(%d) sentd to: %pM\n", __func__, + ReasonCode, dst); + + memset(&DelbaParamSet, 0, 2); + + DelbaParamSet.field.Initiator = (TxRxSelect == TX_DIR) ? 1 : 0; + DelbaParamSet.field.TID = pBA->BaParamSet.field.TID; + + skb = dev_alloc_skb(len + sizeof(struct rtllib_hdr_3addr)); + if (skb == NULL) { + RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't alloc skb for ADDBA_REQ\n"); + return NULL; + } + + skb_reserve(skb, ieee->tx_headroom); + + Delba = (struct rtllib_hdr_3addr *) skb_put(skb, + sizeof(struct rtllib_hdr_3addr)); + + memcpy(Delba->addr1, dst, ETH_ALEN); + memcpy(Delba->addr2, ieee->dev->dev_addr, ETH_ALEN); + memcpy(Delba->addr3, ieee->current_network.bssid, ETH_ALEN); + Delba->frame_ctl = cpu_to_le16(RTLLIB_STYPE_MANAGE_ACT); + + tag = (u8 *)skb_put(skb, 6); + + *tag ++= ACT_CAT_BA; + *tag ++= ACT_DELBA; + + tmp = cpu_to_le16(DelbaParamSet.shortData); + memcpy(tag, (u8 *)&tmp, 2); + tag += 2; + tmp = cpu_to_le16(ReasonCode); + memcpy(tag, (u8 *)&tmp, 2); + tag += 2; + + RTLLIB_DEBUG_DATA(RTLLIB_DL_DATA|RTLLIB_DL_BA, skb->data, skb->len); + if (net_ratelimit()) + RTLLIB_DEBUG(RTLLIB_DL_TRACE | RTLLIB_DL_BA, "<=====%s()\n", + __func__); + return skb; +} + +static void rtllib_send_ADDBAReq(struct rtllib_device *ieee, u8 *dst, + struct ba_record *pBA) +{ + struct sk_buff *skb = NULL; + skb = rtllib_ADDBA(ieee, dst, pBA, 0, ACT_ADDBAREQ); + + if (skb) { + RT_TRACE(COMP_DBG, "====>to send ADDBAREQ!!!!!\n"); + softmac_mgmt_xmit(skb, ieee); + } else { + RTLLIB_DEBUG(RTLLIB_DL_ERR, "alloc skb error in function" + " %s()\n", __func__); + } + return; +} + +static void rtllib_send_ADDBARsp(struct rtllib_device *ieee, u8 *dst, + struct ba_record *pBA, u16 StatusCode) +{ + struct sk_buff *skb = NULL; + skb = rtllib_ADDBA(ieee, dst, pBA, StatusCode, ACT_ADDBARSP); + if (skb) + softmac_mgmt_xmit(skb, ieee); + else + RTLLIB_DEBUG(RTLLIB_DL_ERR, "alloc skb error in function" + " %s()\n", __func__); + return; +} + +static void rtllib_send_DELBA(struct rtllib_device *ieee, u8 *dst, + struct ba_record *pBA, enum tr_select TxRxSelect, + u16 ReasonCode) +{ + struct sk_buff *skb = NULL; + skb = rtllib_DELBA(ieee, dst, pBA, TxRxSelect, ReasonCode); + if (skb) + softmac_mgmt_xmit(skb, ieee); + else + RTLLIB_DEBUG(RTLLIB_DL_ERR, "alloc skb error in func" + "tion %s()\n", __func__); + return ; +} + +int rtllib_rx_ADDBAReq(struct rtllib_device *ieee, struct sk_buff *skb) +{ + struct rtllib_hdr_3addr *req = NULL; + u16 rc = 0; + u8 *dst = NULL, *pDialogToken = NULL, *tag = NULL; + struct ba_record *pBA = NULL; + union ba_param_set *pBaParamSet = NULL; + u16 *pBaTimeoutVal = NULL; + union sequence_control *pBaStartSeqCtrl = NULL; + struct rx_ts_record *pTS = NULL; + + if (skb->len < sizeof(struct rtllib_hdr_3addr) + 9) { + RTLLIB_DEBUG(RTLLIB_DL_ERR, " Invalid skb len in BAREQ(%d / " + "%d)\n", (int)skb->len, + (int)(sizeof(struct rtllib_hdr_3addr) + 9)); + return -1; + } + + RTLLIB_DEBUG_DATA(RTLLIB_DL_DATA|RTLLIB_DL_BA, skb->data, skb->len); + + req = (struct rtllib_hdr_3addr *) skb->data; + tag = (u8 *)req; + dst = (u8 *)(&req->addr2[0]); + tag += sizeof(struct rtllib_hdr_3addr); + pDialogToken = tag + 2; + pBaParamSet = (union ba_param_set *)(tag + 3); + pBaTimeoutVal = (u16 *)(tag + 5); + pBaStartSeqCtrl = (union sequence_control *)(req + 7); + + RT_TRACE(COMP_DBG, "====>rx ADDBAREQ from : %pM\n", dst); + if (ieee->current_network.qos_data.active == 0 || + (ieee->pHTInfo->bCurrentHTSupport == false) || + (ieee->pHTInfo->IOTAction & HT_IOT_ACT_REJECT_ADDBA_REQ)) { + rc = ADDBA_STATUS_REFUSED; + RTLLIB_DEBUG(RTLLIB_DL_ERR, "Failed to reply on ADDBA_REQ as " + "some capability is not ready(%d, %d)\n", + ieee->current_network.qos_data.active, + ieee->pHTInfo->bCurrentHTSupport); + goto OnADDBAReq_Fail; + } + if (!GetTs(ieee, (struct ts_common_info **)(&pTS), dst, + (u8)(pBaParamSet->field.TID), RX_DIR, true)) { + rc = ADDBA_STATUS_REFUSED; + RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't get TS in %s()\n", __func__); + goto OnADDBAReq_Fail; + } + pBA = &pTS->RxAdmittedBARecord; + + if (pBaParamSet->field.BAPolicy == BA_POLICY_DELAYED) { + rc = ADDBA_STATUS_INVALID_PARAM; + RTLLIB_DEBUG(RTLLIB_DL_ERR, "BA Policy is not correct in " + "%s()\n", __func__); + goto OnADDBAReq_Fail; + } + + rtllib_FlushRxTsPendingPkts(ieee, pTS); + + DeActivateBAEntry(ieee, pBA); + pBA->DialogToken = *pDialogToken; + pBA->BaParamSet = *pBaParamSet; + pBA->BaTimeoutValue = *pBaTimeoutVal; + pBA->BaStartSeqCtrl = *pBaStartSeqCtrl; + + if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev) || + (ieee->pHTInfo->IOTAction & HT_IOT_ACT_ALLOW_PEER_AGG_ONE_PKT)) + pBA->BaParamSet.field.BufferSize = 1; + else + pBA->BaParamSet.field.BufferSize = 32; + + ActivateBAEntry(ieee, pBA, 0); + rtllib_send_ADDBARsp(ieee, dst, pBA, ADDBA_STATUS_SUCCESS); + + return 0; + +OnADDBAReq_Fail: + { + struct ba_record BA; + BA.BaParamSet = *pBaParamSet; + BA.BaTimeoutValue = *pBaTimeoutVal; + BA.DialogToken = *pDialogToken; + BA.BaParamSet.field.BAPolicy = BA_POLICY_IMMEDIATE; + rtllib_send_ADDBARsp(ieee, dst, &BA, rc); + return 0; + } +} + +int rtllib_rx_ADDBARsp(struct rtllib_device *ieee, struct sk_buff *skb) +{ + struct rtllib_hdr_3addr *rsp = NULL; + struct ba_record *pPendingBA, *pAdmittedBA; + struct tx_ts_record *pTS = NULL; + u8 *dst = NULL, *pDialogToken = NULL, *tag = NULL; + u16 *pStatusCode = NULL, *pBaTimeoutVal = NULL; + union ba_param_set *pBaParamSet = NULL; + u16 ReasonCode; + + if (skb->len < sizeof(struct rtllib_hdr_3addr) + 9) { + RTLLIB_DEBUG(RTLLIB_DL_ERR, " Invalid skb len in BARSP(%d / " + "%d)\n", (int)skb->len, + (int)(sizeof(struct rtllib_hdr_3addr) + 9)); + return -1; + } + rsp = (struct rtllib_hdr_3addr *)skb->data; + tag = (u8 *)rsp; + dst = (u8 *)(&rsp->addr2[0]); + tag += sizeof(struct rtllib_hdr_3addr); + pDialogToken = tag + 2; + pStatusCode = (u16 *)(tag + 3); + pBaParamSet = (union ba_param_set *)(tag + 5); + pBaTimeoutVal = (u16 *)(tag + 7); + + RT_TRACE(COMP_DBG, "====>rx ADDBARSP from : %pM\n", dst); + if (ieee->current_network.qos_data.active == 0 || + ieee->pHTInfo->bCurrentHTSupport == false || + ieee->pHTInfo->bCurrentAMPDUEnable == false) { + RTLLIB_DEBUG(RTLLIB_DL_ERR, "reject to ADDBA_RSP as some capab" + "ility is not ready(%d, %d, %d)\n", + ieee->current_network.qos_data.active, + ieee->pHTInfo->bCurrentHTSupport, + ieee->pHTInfo->bCurrentAMPDUEnable); + ReasonCode = DELBA_REASON_UNKNOWN_BA; + goto OnADDBARsp_Reject; + } + + + if (!GetTs(ieee, (struct ts_common_info **)(&pTS), dst, + (u8)(pBaParamSet->field.TID), TX_DIR, false)) { + RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't get TS in %s()\n", __func__); + ReasonCode = DELBA_REASON_UNKNOWN_BA; + goto OnADDBARsp_Reject; + } + + pTS->bAddBaReqInProgress = false; + pPendingBA = &pTS->TxPendingBARecord; + pAdmittedBA = &pTS->TxAdmittedBARecord; + + + if ((pAdmittedBA->bValid == true)) { + RTLLIB_DEBUG(RTLLIB_DL_BA, "OnADDBARsp(): Recv ADDBA Rsp." + " Drop because already admit it!\n"); + return -1; + } else if ((pPendingBA->bValid == false) || + (*pDialogToken != pPendingBA->DialogToken)) { + RTLLIB_DEBUG(RTLLIB_DL_ERR, "OnADDBARsp(): Recv ADDBA Rsp. " + "BA invalid, DELBA!\n"); + ReasonCode = DELBA_REASON_UNKNOWN_BA; + goto OnADDBARsp_Reject; + } else { + RTLLIB_DEBUG(RTLLIB_DL_BA, "OnADDBARsp(): Recv ADDBA Rsp. BA " + "is admitted! Status code:%X\n", *pStatusCode); + DeActivateBAEntry(ieee, pPendingBA); + } + + + if (*pStatusCode == ADDBA_STATUS_SUCCESS) { + if (pBaParamSet->field.BAPolicy == BA_POLICY_DELAYED) { + pTS->bAddBaReqDelayed = true; + DeActivateBAEntry(ieee, pAdmittedBA); + ReasonCode = DELBA_REASON_END_BA; + goto OnADDBARsp_Reject; + } + + + pAdmittedBA->DialogToken = *pDialogToken; + pAdmittedBA->BaTimeoutValue = *pBaTimeoutVal; + pAdmittedBA->BaStartSeqCtrl = pPendingBA->BaStartSeqCtrl; + pAdmittedBA->BaParamSet = *pBaParamSet; + DeActivateBAEntry(ieee, pAdmittedBA); + ActivateBAEntry(ieee, pAdmittedBA, *pBaTimeoutVal); + } else { + pTS->bAddBaReqDelayed = true; + pTS->bDisable_AddBa = true; + ReasonCode = DELBA_REASON_END_BA; + goto OnADDBARsp_Reject; + } + + return 0; + +OnADDBARsp_Reject: + { + struct ba_record BA; + BA.BaParamSet = *pBaParamSet; + rtllib_send_DELBA(ieee, dst, &BA, TX_DIR, ReasonCode); + return 0; + } +} + +int rtllib_rx_DELBA(struct rtllib_device *ieee, struct sk_buff *skb) +{ + struct rtllib_hdr_3addr *delba = NULL; + union delba_param_set *pDelBaParamSet = NULL; + u16 *pReasonCode = NULL; + u8 *dst = NULL; + + if (skb->len < sizeof(struct rtllib_hdr_3addr) + 6) { + RTLLIB_DEBUG(RTLLIB_DL_ERR, " Invalid skb len in DELBA(%d /" + " %d)\n", (int)skb->len, + (int)(sizeof(struct rtllib_hdr_3addr) + 6)); + return -1; + } + + if (ieee->current_network.qos_data.active == 0 || + ieee->pHTInfo->bCurrentHTSupport == false) { + RTLLIB_DEBUG(RTLLIB_DL_ERR, "received DELBA while QOS or HT " + "is not supported(%d, %d)\n", + ieee->current_network. qos_data.active, + ieee->pHTInfo->bCurrentHTSupport); + return -1; + } + + RTLLIB_DEBUG_DATA(RTLLIB_DL_DATA|RTLLIB_DL_BA, skb->data, skb->len); + delba = (struct rtllib_hdr_3addr *)skb->data; + dst = (u8 *)(&delba->addr2[0]); + delba += sizeof(struct rtllib_hdr_3addr); + pDelBaParamSet = (union delba_param_set *)(delba+2); + pReasonCode = (u16 *)(delba+4); + + if (pDelBaParamSet->field.Initiator == 1) { + struct rx_ts_record *pRxTs; + + if (!GetTs(ieee, (struct ts_common_info **)&pRxTs, dst, + (u8)pDelBaParamSet->field.TID, RX_DIR, false)) { + RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't get TS for RXTS in " + "%s().dst: %pM TID:%d\n", __func__, dst, + (u8)pDelBaParamSet->field.TID); + return -1; + } + + RxTsDeleteBA(ieee, pRxTs); + } else { + struct tx_ts_record *pTxTs; + + if (!GetTs(ieee, (struct ts_common_info **)&pTxTs, dst, + (u8)pDelBaParamSet->field.TID, TX_DIR, false)) { + RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't get TS for TXTS in " + "%s()\n", __func__); + return -1; + } + + pTxTs->bUsingBa = false; + pTxTs->bAddBaReqInProgress = false; + pTxTs->bAddBaReqDelayed = false; + del_timer_sync(&pTxTs->TsAddBaTimer); + TxTsDeleteBA(ieee, pTxTs); + } + return 0; +} + +void TsInitAddBA(struct rtllib_device *ieee, struct tx_ts_record *pTS, + u8 Policy, u8 bOverwritePending) +{ + struct ba_record *pBA = &pTS->TxPendingBARecord; + + if (pBA->bValid == true && bOverwritePending == false) + return; + + DeActivateBAEntry(ieee, pBA); + + pBA->DialogToken++; + pBA->BaParamSet.field.AMSDU_Support = 0; + pBA->BaParamSet.field.BAPolicy = Policy; + pBA->BaParamSet.field.TID = + pTS->TsCommonInfo.TSpec.f.TSInfo.field.ucTSID; + pBA->BaParamSet.field.BufferSize = 32; + pBA->BaTimeoutValue = 0; + pBA->BaStartSeqCtrl.field.SeqNum = (pTS->TxCurSeq + 3) % 4096; + + ActivateBAEntry(ieee, pBA, BA_SETUP_TIMEOUT); + + rtllib_send_ADDBAReq(ieee, pTS->TsCommonInfo.Addr, pBA); +} + +void TsInitDelBA(struct rtllib_device *ieee, + struct ts_common_info *pTsCommonInfo, + enum tr_select TxRxSelect) +{ + if (TxRxSelect == TX_DIR) { + struct tx_ts_record *pTxTs = + (struct tx_ts_record *)pTsCommonInfo; + + if (TxTsDeleteBA(ieee, pTxTs)) + rtllib_send_DELBA(ieee, pTsCommonInfo->Addr, + (pTxTs->TxAdmittedBARecord.bValid) ? + (&pTxTs->TxAdmittedBARecord) : + (&pTxTs->TxPendingBARecord), + TxRxSelect, DELBA_REASON_END_BA); + } else if (TxRxSelect == RX_DIR) { + struct rx_ts_record *pRxTs = + (struct rx_ts_record *)pTsCommonInfo; + if (RxTsDeleteBA(ieee, pRxTs)) + rtllib_send_DELBA(ieee, pTsCommonInfo->Addr, + &pRxTs->RxAdmittedBARecord, + TxRxSelect, DELBA_REASON_END_BA); + } +} + +void BaSetupTimeOut(unsigned long data) +{ + struct tx_ts_record *pTxTs = (struct tx_ts_record *)data; + + pTxTs->bAddBaReqInProgress = false; + pTxTs->bAddBaReqDelayed = true; + pTxTs->TxPendingBARecord.bValid = false; +} + +void TxBaInactTimeout(unsigned long data) +{ + struct tx_ts_record *pTxTs = (struct tx_ts_record *)data; + struct rtllib_device *ieee = container_of(pTxTs, struct rtllib_device, + TxTsRecord[pTxTs->num]); + TxTsDeleteBA(ieee, pTxTs); + rtllib_send_DELBA(ieee, pTxTs->TsCommonInfo.Addr, + &pTxTs->TxAdmittedBARecord, TX_DIR, + DELBA_REASON_TIMEOUT); +} + +void RxBaInactTimeout(unsigned long data) +{ + struct rx_ts_record *pRxTs = (struct rx_ts_record *)data; + struct rtllib_device *ieee = container_of(pRxTs, struct rtllib_device, + RxTsRecord[pRxTs->num]); + + RxTsDeleteBA(ieee, pRxTs); + rtllib_send_DELBA(ieee, pRxTs->TsCommonInfo.Addr, + &pRxTs->RxAdmittedBARecord, RX_DIR, + DELBA_REASON_TIMEOUT); + return ; +} diff --git a/drivers/staging/rtl8192e/rtl819x_HT.h b/drivers/staging/rtl8192e/rtl819x_HT.h new file mode 100644 index 0000000..13f4105 --- /dev/null +++ b/drivers/staging/rtl8192e/rtl819x_HT.h @@ -0,0 +1,475 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> +******************************************************************************/ +#ifndef _RTL819XU_HTTYPE_H_ +#define _RTL819XU_HTTYPE_H_ + + +#define HT_OPMODE_NO_PROTECT 0 +#define HT_OPMODE_OPTIONAL 1 +#define HT_OPMODE_40MHZ_PROTECT 2 +#define HT_OPMODE_MIXED 3 + +#define MIMO_PS_STATIC 0 +#define MIMO_PS_DYNAMIC 1 +#define MIMO_PS_NOLIMIT 3 + + + +#define sHTCLng 4 + + +#define HT_SUPPORTED_MCS_1SS_BITMAP 0x000000ff +#define HT_SUPPORTED_MCS_2SS_BITMAP 0x0000ff00 +#define HT_SUPPORTED_MCS_1SS_2SS_BITMAP \ + (HT_MCS_1SS_BITMAP | HT_MCS_1SS_2SS_BITMAP) + +enum ht_mcs_rate { + HT_MCS0 = 0x00000001, + HT_MCS1 = 0x00000002, + HT_MCS2 = 0x00000004, + HT_MCS3 = 0x00000008, + HT_MCS4 = 0x00000010, + HT_MCS5 = 0x00000020, + HT_MCS6 = 0x00000040, + HT_MCS7 = 0x00000080, + HT_MCS8 = 0x00000100, + HT_MCS9 = 0x00000200, + HT_MCS10 = 0x00000400, + HT_MCS11 = 0x00000800, + HT_MCS12 = 0x00001000, + HT_MCS13 = 0x00002000, + HT_MCS14 = 0x00004000, + HT_MCS15 = 0x00008000, +}; + +enum ht_channel_width { + HT_CHANNEL_WIDTH_20 = 0, + HT_CHANNEL_WIDTH_20_40 = 1, +}; + +enum ht_extchnl_offset { + HT_EXTCHNL_OFFSET_NO_EXT = 0, + HT_EXTCHNL_OFFSET_UPPER = 1, + HT_EXTCHNL_OFFSET_NO_DEF = 2, + HT_EXTCHNL_OFFSET_LOWER = 3, +}; + +enum chnl_op { + CHNLOP_NONE = 0, + CHNLOP_SCAN = 1, + CHNLOP_SWBW = 2, + CHNLOP_SWCHNL = 3, +}; + +#define CHHLOP_IN_PROGRESS(_pHTInfo) \ + ((_pHTInfo)->ChnlOp > CHNLOP_NONE) ? true : false + +/* +union ht_capability { + u16 ShortData; + u8 CharData[2]; + struct + { + u16 AdvCoding:1; + u16 ChlWidth:1; + u16 MimoPwrSave:2; + u16 GreenField:1; + u16 ShortGI20Mhz:1; + u16 ShortGI40Mhz:1; + u16 STBC:1; + u16 BeamForm:1; + u16 DelayBA:1; + u16 MaxAMSDUSize:1; + u16 DssCCk:1; + u16 PSMP:1; + u16 Rsvd:3; + }Field; +}; + +union ht_capability_macpara { + u8 ShortData; + u8 CharData[1]; + struct + { + u8 MaxRxAMPDU:2; + u8 MPDUDensity:2; + u8 Rsvd:4; + }Field; +}; +*/ + +enum ht_action { + ACT_RECOMMAND_WIDTH = 0, + ACT_MIMO_PWR_SAVE = 1, + ACT_PSMP = 2, + ACT_SET_PCO_PHASE = 3, + ACT_MIMO_CHL_MEASURE = 4, + ACT_RECIPROCITY_CORRECT = 5, + ACT_MIMO_CSI_MATRICS = 6, + ACT_MIMO_NOCOMPR_STEER = 7, + ACT_MIMO_COMPR_STEER = 8, + ACT_ANTENNA_SELECT = 9, +}; + + +enum ht_bw40_sc { + SC_MODE_DUPLICATE = 0, + SC_MODE_LOWER = 1, + SC_MODE_UPPER = 2, + SC_MODE_FULL40MHZ = 3, +}; + +struct ht_capab_ele { + + u8 AdvCoding:1; + u8 ChlWidth:1; + u8 MimoPwrSave:2; + u8 GreenField:1; + u8 ShortGI20Mhz:1; + u8 ShortGI40Mhz:1; + u8 TxSTBC:1; + u8 RxSTBC:2; + u8 DelayBA:1; + u8 MaxAMSDUSize:1; + u8 DssCCk:1; + u8 PSMP:1; + u8 Rsvd1:1; + u8 LSigTxopProtect:1; + + u8 MaxRxAMPDUFactor:2; + u8 MPDUDensity:3; + u8 Rsvd2:3; + + u8 MCS[16]; + + + u16 ExtHTCapInfo; + + u8 TxBFCap[4]; + + u8 ASCap; + +} __packed; + + +struct ht_info_ele { + u8 ControlChl; + + u8 ExtChlOffset:2; + u8 RecommemdedTxWidth:1; + u8 RIFS:1; + u8 PSMPAccessOnly:1; + u8 SrvIntGranularity:3; + + u8 OptMode:2; + u8 NonGFDevPresent:1; + u8 Revd1:5; + u8 Revd2:8; + + u8 Rsvd3:6; + u8 DualBeacon:1; + u8 DualCTSProtect:1; + + u8 SecondaryBeacon:1; + u8 LSigTxopProtectFull:1; + u8 PcoActive:1; + u8 PcoPhase:1; + u8 Rsvd4:4; + + u8 BasicMSC[16]; +} __packed; + +struct mimops_ctrl { + u8 MimoPsEnable:1; + u8 MimoPsMode:1; + u8 Reserved:6; +}; + +enum ht_spec_ver { + HT_SPEC_VER_IEEE = 0, + HT_SPEC_VER_EWC = 1, +}; + +enum ht_aggre_mode { + HT_AGG_AUTO = 0, + HT_AGG_FORCE_ENABLE = 1, + HT_AGG_FORCE_DISABLE = 2, +}; + + +struct rt_hi_throughput { + u8 bEnableHT; + u8 bCurrentHTSupport; + + u8 bRegBW40MHz; + u8 bCurBW40MHz; + + u8 bRegShortGI40MHz; + u8 bCurShortGI40MHz; + + u8 bRegShortGI20MHz; + u8 bCurShortGI20MHz; + + u8 bRegSuppCCK; + u8 bCurSuppCCK; + + enum ht_spec_ver ePeerHTSpecVer; + + + struct ht_capab_ele SelfHTCap; + struct ht_info_ele SelfHTInfo; + + u8 PeerHTCapBuf[32]; + u8 PeerHTInfoBuf[32]; + + + u8 bAMSDU_Support; + u16 nAMSDU_MaxSize; + u8 bCurrent_AMSDU_Support; + u16 nCurrent_AMSDU_MaxSize; + + u8 bAMPDUEnable; + u8 bCurrentAMPDUEnable; + u8 AMPDU_Factor; + u8 CurrentAMPDUFactor; + u8 MPDU_Density; + u8 CurrentMPDUDensity; + + enum ht_aggre_mode ForcedAMPDUMode; + u8 ForcedAMPDUFactor; + u8 ForcedMPDUDensity; + + enum ht_aggre_mode ForcedAMSDUMode; + u16 ForcedAMSDUMaxSize; + + u8 bForcedShortGI; + + u8 CurrentOpMode; + + u8 SelfMimoPs; + u8 PeerMimoPs; + + enum ht_extchnl_offset CurSTAExtChnlOffset; + u8 bCurTxBW40MHz; + u8 PeerBandwidth; + + u8 bSwBwInProgress; + enum chnl_op ChnlOp; + u8 SwBwStep; + + u8 bRegRT2RTAggregation; + u8 RT2RT_HT_Mode; + u8 bCurrentRT2RTAggregation; + u8 bCurrentRT2RTLongSlotTime; + u8 szRT2RTAggBuffer[10]; + + u8 bRegRxReorderEnable; + u8 bCurRxReorderEnable; + u8 RxReorderWinSize; + u8 RxReorderPendingTime; + u16 RxReorderDropCounter; + + u8 bIsPeerBcm; + + u8 IOTPeer; + u32 IOTAction; + u8 IOTRaFunc; + + u8 bWAIotBroadcom; + u8 WAIotTH; + + u8 bAcceptAddbaReq; +} __packed; + + + +struct rt_htinfo_sta_entry { + u8 bEnableHT; + + u8 bSupportCck; + + u16 AMSDU_MaxSize; + + u8 AMPDU_Factor; + u8 MPDU_Density; + + u8 HTHighestOperaRate; + + u8 bBw40MHz; + + u8 bCurTxBW40MHz; + + u8 bCurShortGI20MHz; + + u8 bCurShortGI40MHz; + + u8 MimoPs; + + u8 McsRateSet[16]; + + u8 bCurRxReorderEnable; + + u16 nAMSDU_MaxSize; + +}; + + + + + + +struct bss_ht { + + u8 bdSupportHT; + + u8 bdHTCapBuf[32]; + u16 bdHTCapLen; + u8 bdHTInfoBuf[32]; + u16 bdHTInfoLen; + + enum ht_spec_ver bdHTSpecVer; + enum ht_channel_width bdBandWidth; + + u8 bdRT2RTAggregation; + u8 bdRT2RTLongSlotTime; + u8 RT2RT_HT_Mode; + u8 bdHT1R; +}; + +struct mimo_rssi { + u32 EnableAntenna; + u32 AntennaA; + u32 AntennaB; + u32 AntennaC; + u32 AntennaD; + u32 Average; +}; + +struct mimo_evm { + u32 EVM1; + u32 EVM2; +}; + +struct false_alarm_stats { + u32 Cnt_Parity_Fail; + u32 Cnt_Rate_Illegal; + u32 Cnt_Crc8_fail; + u32 Cnt_Mcs_fail; + u32 Cnt_Ofdm_fail; + u32 Cnt_Cck_fail; + u32 Cnt_all; +}; + + +extern u8 MCS_FILTER_ALL[16]; +extern u8 MCS_FILTER_1SS[16]; + +#define PICK_RATE(_nLegacyRate, _nMcsRate) \ + ((_nMcsRate == 0) ? (_nLegacyRate&0x7f) : (_nMcsRate)) +#define LEGACY_WIRELESS_MODE IEEE_MODE_MASK + +#define CURRENT_RATE(WirelessMode, LegacyRate, HTRate) \ + ((WirelessMode & (LEGACY_WIRELESS_MODE)) != 0) ? \ + (LegacyRate) : (PICK_RATE(LegacyRate, HTRate)) + + + +#define RATE_ADPT_1SS_MASK 0xFF +#define RATE_ADPT_2SS_MASK 0xF0 +#define RATE_ADPT_MCS32_MASK 0x01 + +#define IS_11N_MCS_RATE(rate) (rate&0x80) + +enum ht_aggre_size { + HT_AGG_SIZE_8K = 0, + HT_AGG_SIZE_16K = 1, + HT_AGG_SIZE_32K = 2, + HT_AGG_SIZE_64K = 3, +}; + +enum ht_iot_peer { + HT_IOT_PEER_UNKNOWN = 0, + HT_IOT_PEER_REALTEK = 1, + HT_IOT_PEER_REALTEK_92SE = 2, + HT_IOT_PEER_BROADCOM = 3, + HT_IOT_PEER_RALINK = 4, + HT_IOT_PEER_ATHEROS = 5, + HT_IOT_PEER_CISCO = 6, + HT_IOT_PEER_MARVELL = 7, + HT_IOT_PEER_92U_SOFTAP = 8, + HT_IOT_PEER_SELF_SOFTAP = 9, + HT_IOT_PEER_AIRGO = 10, + HT_IOT_PEER_MAX = 11, +}; + +enum ht_iot_peer_subtype { + HT_IOT_PEER_ATHEROS_DIR635 = 0, +}; + +enum ht_iot_action { + HT_IOT_ACT_TX_USE_AMSDU_4K = 0x00000001, + HT_IOT_ACT_TX_USE_AMSDU_8K = 0x00000002, + HT_IOT_ACT_DISABLE_MCS14 = 0x00000004, + HT_IOT_ACT_DISABLE_MCS15 = 0x00000008, + HT_IOT_ACT_DISABLE_ALL_2SS = 0x00000010, + HT_IOT_ACT_DISABLE_EDCA_TURBO = 0x00000020, + HT_IOT_ACT_MGNT_USE_CCK_6M = 0x00000040, + HT_IOT_ACT_CDD_FSYNC = 0x00000080, + HT_IOT_ACT_PURE_N_MODE = 0x00000100, + HT_IOT_ACT_FORCED_CTS2SELF = 0x00000200, + HT_IOT_ACT_FORCED_RTS = 0x00000400, + HT_IOT_ACT_AMSDU_ENABLE = 0x00000800, + HT_IOT_ACT_REJECT_ADDBA_REQ = 0x00001000, + HT_IOT_ACT_ALLOW_PEER_AGG_ONE_PKT = 0x00002000, + HT_IOT_ACT_EDCA_BIAS_ON_RX = 0x00004000, + + HT_IOT_ACT_HYBRID_AGGREGATION = 0x00010000, + HT_IOT_ACT_DISABLE_SHORT_GI = 0x00020000, + HT_IOT_ACT_DISABLE_HIGH_POWER = 0x00040000, + HT_IOT_ACT_DISABLE_TX_40_MHZ = 0x00080000, + HT_IOT_ACT_TX_NO_AGGREGATION = 0x00100000, + HT_IOT_ACT_DISABLE_TX_2SS = 0x00200000, + + HT_IOT_ACT_MID_HIGHPOWER = 0x00400000, + HT_IOT_ACT_NULL_DATA_POWER_SAVING = 0x00800000, + + HT_IOT_ACT_DISABLE_CCK_RATE = 0x01000000, + HT_IOT_ACT_FORCED_ENABLE_BE_TXOP = 0x02000000, + HT_IOT_ACT_WA_IOT_Broadcom = 0x04000000, + + HT_IOT_ACT_DISABLE_RX_40MHZ_SHORT_GI = 0x08000000, + +}; + +enum ht_iot_rafunc { + HT_IOT_RAFUNC_DISABLE_ALL = 0x00, + HT_IOT_RAFUNC_PEER_1R = 0x01, + HT_IOT_RAFUNC_TX_AMSDU = 0x02, +}; + +enum rt_ht_capability { + RT_HT_CAP_USE_TURBO_AGGR = 0x01, + RT_HT_CAP_USE_LONG_PREAMBLE = 0x02, + RT_HT_CAP_USE_AMPDU = 0x04, + RT_HT_CAP_USE_WOW = 0x8, + RT_HT_CAP_USE_SOFTAP = 0x10, + RT_HT_CAP_USE_92SE = 0x20, +}; + +#endif diff --git a/drivers/staging/rtl8192e/rtl819x_HTProc.c b/drivers/staging/rtl8192e/rtl819x_HTProc.c new file mode 100644 index 0000000..b1c0c56 --- /dev/null +++ b/drivers/staging/rtl8192e/rtl819x_HTProc.c @@ -0,0 +1,1075 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> +******************************************************************************/ +#include "rtllib.h" +#include "rtl819x_HT.h" +u8 MCS_FILTER_ALL[16] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +u8 MCS_FILTER_1SS[16] = { + 0xff, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} +; + +u16 MCS_DATA_RATE[2][2][77] = { + {{13, 26, 39, 52, 78, 104, 117, 130, 26, 52, 78, 104, 156, 208, 234, + 260, 39, 78, 117, 234, 312, 351, 390, 52, 104, 156, 208, 312, 416, + 468, 520, 0, 78, 104, 130, 117, 156, 195, 104, 130, 130, 156, 182, + 182, 208, 156, 195, 195, 234, 273, 273, 312, 130, 156, 181, 156, + 181, 208, 234, 208, 234, 260, 260, 286, 195, 234, 273, 234, 273, + 312, 351, 312, 351, 390, 390, 429} , + {14, 29, 43, 58, 87, 116, 130, 144, 29, 58, 87, 116, 173, 231, 260, 289, + 43, 87, 130, 173, 260, 347, 390, 433, 58, 116, 173, 231, 347, 462, 520, + 578, 0, 87, 116, 144, 130, 173, 217, 116, 144, 144, 173, 202, 202, 231, + 173, 217, 217, 260, 303, 303, 347, 144, 173, 202, 173, 202, 231, 260, + 231, 260, 289, 289, 318, 217, 260, 303, 260, 303, 347, 390, 347, 390, + 433, 433, 477} } , + {{27, 54, 81, 108, 162, 216, 243, 270, 54, 108, 162, 216, 324, 432, 486, + 540, 81, 162, 243, 324, 486, 648, 729, 810, 108, 216, 324, 432, 648, + 864, 972, 1080, 12, 162, 216, 270, 243, 324, 405, 216, 270, 270, 324, + 378, 378, 432, 324, 405, 405, 486, 567, 567, 648, 270, 324, 378, 324, + 378, 432, 486, 432, 486, 540, 540, 594, 405, 486, 567, 486, 567, 648, + 729, 648, 729, 810, 810, 891}, + {30, 60, 90, 120, 180, 240, 270, 300, 60, 120, 180, 240, 360, 480, 540, + 600, 90, 180, 270, 360, 540, 720, 810, 900, 120, 240, 360, 480, 720, + 960, 1080, 1200, 13, 180, 240, 300, 270, 360, 450, 240, 300, 300, 360, + 420, 420, 480, 360, 450, 450, 540, 630, 630, 720, 300, 360, 420, 360, + 420, 480, 540, 480, 540, 600, 600, 660, 450, 540, 630, 540, 630, 720, + 810, 720, 810, 900, 900, 990} } +}; + +static u8 UNKNOWN_BORADCOM[3] = {0x00, 0x14, 0xbf}; + +static u8 LINKSYSWRT330_LINKSYSWRT300_BROADCOM[3] = {0x00, 0x1a, 0x70}; + +static u8 LINKSYSWRT350_LINKSYSWRT150_BROADCOM[3] = {0x00, 0x1d, 0x7e}; + +static u8 BELKINF5D8233V1_RALINK[3] = {0x00, 0x17, 0x3f}; + +static u8 BELKINF5D82334V3_RALINK[3] = {0x00, 0x1c, 0xdf}; + +static u8 PCI_RALINK[3] = {0x00, 0x90, 0xcc}; + +static u8 EDIMAX_RALINK[3] = {0x00, 0x0e, 0x2e}; + +static u8 AIRLINK_RALINK[3] = {0x00, 0x18, 0x02}; + +static u8 DLINK_ATHEROS_1[3] = {0x00, 0x1c, 0xf0}; + +static u8 DLINK_ATHEROS_2[3] = {0x00, 0x21, 0x91}; + +static u8 CISCO_BROADCOM[3] = {0x00, 0x17, 0x94}; + +static u8 LINKSYS_MARVELL_4400N[3] = {0x00, 0x14, 0xa4}; + +void HTUpdateDefaultSetting(struct rtllib_device *ieee) +{ + struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; + + pHTInfo->bAcceptAddbaReq = 1; + + pHTInfo->bRegShortGI20MHz = 1; + pHTInfo->bRegShortGI40MHz = 1; + + pHTInfo->bRegBW40MHz = 1; + + if (pHTInfo->bRegBW40MHz) + pHTInfo->bRegSuppCCK = 1; + else + pHTInfo->bRegSuppCCK = true; + + pHTInfo->nAMSDU_MaxSize = 7935UL; + pHTInfo->bAMSDU_Support = 0; + + pHTInfo->bAMPDUEnable = 1; + pHTInfo->AMPDU_Factor = 2; + pHTInfo->MPDU_Density = 0; + + pHTInfo->SelfMimoPs = 3; + if (pHTInfo->SelfMimoPs == 2) + pHTInfo->SelfMimoPs = 3; + ieee->bTxDisableRateFallBack = 0; + ieee->bTxUseDriverAssingedRate = 0; + + ieee->bTxEnableFwCalcDur = 1; + + pHTInfo->bRegRT2RTAggregation = 1; + + pHTInfo->bRegRxReorderEnable = 1; + pHTInfo->RxReorderWinSize = 64; + pHTInfo->RxReorderPendingTime = 30; +} + +void HTDebugHTCapability(u8 *CapIE, u8 *TitleString) +{ + + static u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; + struct ht_capab_ele *pCapELE; + + if (!memcmp(CapIE, EWC11NHTCap, sizeof(EWC11NHTCap))) { + RTLLIB_DEBUG(RTLLIB_DL_HT, "EWC IE in %s()\n", __func__); + pCapELE = (struct ht_capab_ele *)(&CapIE[4]); + } else + pCapELE = (struct ht_capab_ele *)(&CapIE[0]); + + RTLLIB_DEBUG(RTLLIB_DL_HT, "<Log HT Capability>. Called by %s\n", + TitleString); + + RTLLIB_DEBUG(RTLLIB_DL_HT, "\tSupported Channel Width = %s\n", + (pCapELE->ChlWidth) ? "20MHz" : "20/40MHz"); + RTLLIB_DEBUG(RTLLIB_DL_HT, "\tSupport Short GI for 20M = %s\n", + (pCapELE->ShortGI20Mhz) ? "YES" : "NO"); + RTLLIB_DEBUG(RTLLIB_DL_HT, "\tSupport Short GI for 40M = %s\n", + (pCapELE->ShortGI40Mhz) ? "YES" : "NO"); + RTLLIB_DEBUG(RTLLIB_DL_HT, "\tSupport TX STBC = %s\n", + (pCapELE->TxSTBC) ? "YES" : "NO"); + RTLLIB_DEBUG(RTLLIB_DL_HT, "\tMax AMSDU Size = %s\n", + (pCapELE->MaxAMSDUSize) ? "3839" : "7935"); + RTLLIB_DEBUG(RTLLIB_DL_HT, "\tSupport CCK in 20/40 mode = %s\n", + (pCapELE->DssCCk) ? "YES" : "NO"); + RTLLIB_DEBUG(RTLLIB_DL_HT, "\tMax AMPDU Factor = %d\n", + pCapELE->MaxRxAMPDUFactor); + RTLLIB_DEBUG(RTLLIB_DL_HT, "\tMPDU Density = %d\n", + pCapELE->MPDUDensity); + RTLLIB_DEBUG(RTLLIB_DL_HT, "\tMCS Rate Set = [%x][%x][%x][%x][%x]\n", + pCapELE->MCS[0], pCapELE->MCS[1], pCapELE->MCS[2], + pCapELE->MCS[3], pCapELE->MCS[4]); + return; + +} + +void HTDebugHTInfo(u8 *InfoIE, u8 *TitleString) +{ + + static u8 EWC11NHTInfo[] = {0x00, 0x90, 0x4c, 0x34}; + struct ht_info_ele *pHTInfoEle; + + if (!memcmp(InfoIE, EWC11NHTInfo, sizeof(EWC11NHTInfo))) { + RTLLIB_DEBUG(RTLLIB_DL_HT, "EWC IE in %s()\n", __func__); + pHTInfoEle = (struct ht_info_ele *)(&InfoIE[4]); + } else + pHTInfoEle = (struct ht_info_ele *)(&InfoIE[0]); + + + RTLLIB_DEBUG(RTLLIB_DL_HT, "<Log HT Information Element>. " + "Called by %s\n", TitleString); + + RTLLIB_DEBUG(RTLLIB_DL_HT, "\tPrimary channel = %d\n", + pHTInfoEle->ControlChl); + RTLLIB_DEBUG(RTLLIB_DL_HT, "\tSenondary channel ="); + switch (pHTInfoEle->ExtChlOffset) { + case 0: + RTLLIB_DEBUG(RTLLIB_DL_HT, "Not Present\n"); + break; + case 1: + RTLLIB_DEBUG(RTLLIB_DL_HT, "Upper channel\n"); + break; + case 2: + RTLLIB_DEBUG(RTLLIB_DL_HT, "Reserved. Eooro!!!\n"); + break; + case 3: + RTLLIB_DEBUG(RTLLIB_DL_HT, "Lower Channel\n"); + break; + } + RTLLIB_DEBUG(RTLLIB_DL_HT, "\tRecommended channel width = %s\n", + (pHTInfoEle->RecommemdedTxWidth) ? "20Mhz" : "40Mhz"); + + RTLLIB_DEBUG(RTLLIB_DL_HT, "\tOperation mode for protection = "); + switch (pHTInfoEle->OptMode) { + case 0: + RTLLIB_DEBUG(RTLLIB_DL_HT, "No Protection\n"); + break; + case 1: + RTLLIB_DEBUG(RTLLIB_DL_HT, "HT non-member protection mode\n"); + break; + case 2: + RTLLIB_DEBUG(RTLLIB_DL_HT, "Suggest to open protection\n"); + break; + case 3: + RTLLIB_DEBUG(RTLLIB_DL_HT, "HT mixed mode\n"); + break; + } + + RTLLIB_DEBUG(RTLLIB_DL_HT, "\tBasic MCS Rate Set = [%x][%x][%x][%x]" + "[%x]\n", pHTInfoEle->BasicMSC[0], pHTInfoEle->BasicMSC[1], + pHTInfoEle->BasicMSC[2], pHTInfoEle->BasicMSC[3], + pHTInfoEle->BasicMSC[4]); + return; +} + +static bool IsHTHalfNmode40Bandwidth(struct rtllib_device *ieee) +{ + bool retValue = false; + struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; + + if (pHTInfo->bCurrentHTSupport == false) + retValue = false; + else if (pHTInfo->bRegBW40MHz == false) + retValue = false; + else if (!ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) + retValue = false; + else if (((struct ht_capab_ele *)(pHTInfo->PeerHTCapBuf))->ChlWidth) + retValue = true; + else + retValue = false; + + return retValue; +} + +static bool IsHTHalfNmodeSGI(struct rtllib_device *ieee, bool is40MHz) +{ + bool retValue = false; + struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; + + if (pHTInfo->bCurrentHTSupport == false) + retValue = false; + else if (!ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) + retValue = false; + else if (is40MHz) { + if (((struct ht_capab_ele *) + (pHTInfo->PeerHTCapBuf))->ShortGI40Mhz) + retValue = true; + else + retValue = false; + } else { + if (((struct ht_capab_ele *) + (pHTInfo->PeerHTCapBuf))->ShortGI20Mhz) + retValue = true; + else + retValue = false; + } + + return retValue; +} + +u16 HTHalfMcsToDataRate(struct rtllib_device *ieee, u8 nMcsRate) +{ + + u8 is40MHz; + u8 isShortGI; + + is40MHz = (IsHTHalfNmode40Bandwidth(ieee)) ? 1 : 0; + isShortGI = (IsHTHalfNmodeSGI(ieee, is40MHz)) ? 1 : 0; + + return MCS_DATA_RATE[is40MHz][isShortGI][(nMcsRate & 0x7f)]; +} + + +u16 HTMcsToDataRate(struct rtllib_device *ieee, u8 nMcsRate) +{ + struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; + + u8 is40MHz = (pHTInfo->bCurBW40MHz) ? 1 : 0; + u8 isShortGI = (pHTInfo->bCurBW40MHz) ? + ((pHTInfo->bCurShortGI40MHz) ? 1 : 0) : + ((pHTInfo->bCurShortGI20MHz) ? 1 : 0); + return MCS_DATA_RATE[is40MHz][isShortGI][(nMcsRate & 0x7f)]; +} + +u16 TxCountToDataRate(struct rtllib_device *ieee, u8 nDataRate) +{ + u16 CCKOFDMRate[12] = {0x02, 0x04, 0x0b, 0x16, 0x0c, 0x12, 0x18, + 0x24, 0x30, 0x48, 0x60, 0x6c}; + u8 is40MHz = 0; + u8 isShortGI = 0; + + if (nDataRate < 12) { + return CCKOFDMRate[nDataRate]; + } else { + if (nDataRate >= 0x10 && nDataRate <= 0x1f) { + is40MHz = 0; + isShortGI = 0; + } else if (nDataRate >= 0x20 && nDataRate <= 0x2f) { + is40MHz = 1; + isShortGI = 0; + + } else if (nDataRate >= 0x30 && nDataRate <= 0x3f) { + is40MHz = 0; + isShortGI = 1; + } else if (nDataRate >= 0x40 && nDataRate <= 0x4f) { + is40MHz = 1; + isShortGI = 1; + } + return MCS_DATA_RATE[is40MHz][isShortGI][nDataRate&0xf]; + } +} + +bool IsHTHalfNmodeAPs(struct rtllib_device *ieee) +{ + bool retValue = false; + struct rtllib_network *net = &ieee->current_network; + + if ((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3) == 0) || + (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3) == 0) || + (memcmp(net->bssid, PCI_RALINK, 3) == 0) || + (memcmp(net->bssid, EDIMAX_RALINK, 3) == 0) || + (memcmp(net->bssid, AIRLINK_RALINK, 3) == 0) || + (net->ralink_cap_exist)) + retValue = true; + else if (!memcmp(net->bssid, UNKNOWN_BORADCOM, 3) || + !memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3) || + !memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3) || + (net->broadcom_cap_exist)) + retValue = true; + else if (net->bssht.bdRT2RTAggregation) + retValue = true; + else + retValue = false; + + return retValue; +} + +static void HTIOTPeerDetermine(struct rtllib_device *ieee) +{ + struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; + struct rtllib_network *net = &ieee->current_network; + if (net->bssht.bdRT2RTAggregation) { + pHTInfo->IOTPeer = HT_IOT_PEER_REALTEK; + if (net->bssht.RT2RT_HT_Mode & RT_HT_CAP_USE_92SE) + pHTInfo->IOTPeer = HT_IOT_PEER_REALTEK_92SE; + if (net->bssht.RT2RT_HT_Mode & RT_HT_CAP_USE_SOFTAP) + pHTInfo->IOTPeer = HT_IOT_PEER_92U_SOFTAP; + } else if (net->broadcom_cap_exist) + pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM; + else if (!memcmp(net->bssid, UNKNOWN_BORADCOM, 3) || + !memcmp(net->bssid, LINKSYSWRT330_LINKSYSWRT300_BROADCOM, 3) || + !memcmp(net->bssid, LINKSYSWRT350_LINKSYSWRT150_BROADCOM, 3)) + pHTInfo->IOTPeer = HT_IOT_PEER_BROADCOM; + else if ((memcmp(net->bssid, BELKINF5D8233V1_RALINK, 3) == 0) || + (memcmp(net->bssid, BELKINF5D82334V3_RALINK, 3) == 0) || + (memcmp(net->bssid, PCI_RALINK, 3) == 0) || + (memcmp(net->bssid, EDIMAX_RALINK, 3) == 0) || + (memcmp(net->bssid, AIRLINK_RALINK, 3) == 0) || + net->ralink_cap_exist) + pHTInfo->IOTPeer = HT_IOT_PEER_RALINK; + else if ((net->atheros_cap_exist) || + (memcmp(net->bssid, DLINK_ATHEROS_1, 3) == 0) || + (memcmp(net->bssid, DLINK_ATHEROS_2, 3) == 0)) + pHTInfo->IOTPeer = HT_IOT_PEER_ATHEROS; + else if ((memcmp(net->bssid, CISCO_BROADCOM, 3) == 0) || + net->cisco_cap_exist) + pHTInfo->IOTPeer = HT_IOT_PEER_CISCO; + else if ((memcmp(net->bssid, LINKSYS_MARVELL_4400N, 3) == 0) || + net->marvell_cap_exist) + pHTInfo->IOTPeer = HT_IOT_PEER_MARVELL; + else if (net->airgo_cap_exist) + pHTInfo->IOTPeer = HT_IOT_PEER_AIRGO; + else + pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN; + + RTLLIB_DEBUG(RTLLIB_DL_IOT, "Joseph debug!! IOTPEER: %x\n", + pHTInfo->IOTPeer); +} + +static u8 HTIOTActIsDisableMCS14(struct rtllib_device *ieee, u8 *PeerMacAddr) +{ + return 0; +} + + +static bool HTIOTActIsDisableMCS15(struct rtllib_device *ieee) +{ + bool retValue = false; + + return retValue; +} + +static bool HTIOTActIsDisableMCSTwoSpatialStream(struct rtllib_device *ieee) +{ + return false; +} + +static u8 HTIOTActIsDisableEDCATurbo(struct rtllib_device *ieee, u8 *PeerMacAddr) +{ + return false; +} + +static u8 HTIOTActIsMgntUseCCK6M(struct rtllib_device *ieee, + struct rtllib_network *network) +{ + u8 retValue = 0; + + + if (ieee->pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) + retValue = 1; + + return retValue; +} + +static u8 HTIOTActIsCCDFsync(struct rtllib_device *ieee) +{ + u8 retValue = 0; + + if (ieee->pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) + retValue = 1; + return retValue; +} + +static void HTIOTActDetermineRaFunc(struct rtllib_device *ieee, bool bPeerRx2ss) +{ + struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; + pHTInfo->IOTRaFunc &= HT_IOT_RAFUNC_DISABLE_ALL; + + if (pHTInfo->IOTPeer == HT_IOT_PEER_RALINK && !bPeerRx2ss) + pHTInfo->IOTRaFunc |= HT_IOT_RAFUNC_PEER_1R; + + if (pHTInfo->IOTAction & HT_IOT_ACT_AMSDU_ENABLE) + pHTInfo->IOTRaFunc |= HT_IOT_RAFUNC_TX_AMSDU; + +} + +void HTResetIOTSetting(struct rt_hi_throughput *pHTInfo) +{ + pHTInfo->IOTAction = 0; + pHTInfo->IOTPeer = HT_IOT_PEER_UNKNOWN; + pHTInfo->IOTRaFunc = 0; +} + +void HTConstructCapabilityElement(struct rtllib_device *ieee, u8 *posHTCap, + u8 *len, u8 IsEncrypt, bool bAssoc) +{ + struct rt_hi_throughput *pHT = ieee->pHTInfo; + struct ht_capab_ele *pCapELE = NULL; + + if ((posHTCap == NULL) || (pHT == NULL)) { + RTLLIB_DEBUG(RTLLIB_DL_ERR, "posHTCap or pHTInfo can't be " + "null in HTConstructCapabilityElement()\n"); + return; + } + memset(posHTCap, 0, *len); + + if ((bAssoc) && (pHT->ePeerHTSpecVer == HT_SPEC_VER_EWC)) { + u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; + memcpy(posHTCap, EWC11NHTCap, sizeof(EWC11NHTCap)); + pCapELE = (struct ht_capab_ele *)&(posHTCap[4]); + *len = 30 + 2; + } else { + pCapELE = (struct ht_capab_ele *)posHTCap; + *len = 26 + 2; + } + + pCapELE->AdvCoding = 0; + if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) + pCapELE->ChlWidth = 0; + else + pCapELE->ChlWidth = (pHT->bRegBW40MHz ? 1 : 0); + + pCapELE->MimoPwrSave = pHT->SelfMimoPs; + pCapELE->GreenField = 0; + pCapELE->ShortGI20Mhz = 1; + pCapELE->ShortGI40Mhz = 1; + + pCapELE->TxSTBC = 1; + pCapELE->RxSTBC = 0; + pCapELE->DelayBA = 0; + pCapELE->MaxAMSDUSize = (MAX_RECEIVE_BUFFER_SIZE >= 7935) ? 1 : 0; + pCapELE->DssCCk = ((pHT->bRegBW40MHz) ? (pHT->bRegSuppCCK ? 1 : 0) : 0); + pCapELE->PSMP = 0; + pCapELE->LSigTxopProtect = 0; + + + RTLLIB_DEBUG(RTLLIB_DL_HT, "TX HT cap/info ele BW=%d MaxAMSDUSize:%d " + "DssCCk:%d\n", pCapELE->ChlWidth, pCapELE->MaxAMSDUSize, + pCapELE->DssCCk); + + if (IsEncrypt) { + pCapELE->MPDUDensity = 7; + pCapELE->MaxRxAMPDUFactor = 2; + } else { + pCapELE->MaxRxAMPDUFactor = 3; + pCapELE->MPDUDensity = 0; + } + + memcpy(pCapELE->MCS, ieee->Regdot11HTOperationalRateSet, 16); + memset(&pCapELE->ExtHTCapInfo, 0, 2); + memset(pCapELE->TxBFCap, 0, 4); + + pCapELE->ASCap = 0; + + if (bAssoc) { + if (pHT->IOTAction & HT_IOT_ACT_DISABLE_MCS15) + pCapELE->MCS[1] &= 0x7f; + + if (pHT->IOTAction & HT_IOT_ACT_DISABLE_MCS14) + pCapELE->MCS[1] &= 0xbf; + + if (pHT->IOTAction & HT_IOT_ACT_DISABLE_ALL_2SS) + pCapELE->MCS[1] &= 0x00; + + if (pHT->IOTAction & HT_IOT_ACT_DISABLE_RX_40MHZ_SHORT_GI) + pCapELE->ShortGI40Mhz = 0; + + if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) { + pCapELE->ChlWidth = 0; + pCapELE->MCS[1] = 0; + } + } + return; +} + +void HTConstructInfoElement(struct rtllib_device *ieee, u8 *posHTInfo, + u8 *len, u8 IsEncrypt) +{ + struct rt_hi_throughput *pHT = ieee->pHTInfo; + struct ht_info_ele *pHTInfoEle = (struct ht_info_ele *)posHTInfo; + if ((posHTInfo == NULL) || (pHTInfoEle == NULL)) { + RTLLIB_DEBUG(RTLLIB_DL_ERR, "posHTInfo or pHTInfoEle can't be " + "null in HTConstructInfoElement()\n"); + return; + } + + memset(posHTInfo, 0, *len); + if ((ieee->iw_mode == IW_MODE_ADHOC) || + (ieee->iw_mode == IW_MODE_MASTER)) { + pHTInfoEle->ControlChl = ieee->current_network.channel; + pHTInfoEle->ExtChlOffset = ((pHT->bRegBW40MHz == false) ? + HT_EXTCHNL_OFFSET_NO_EXT : + (ieee->current_network.channel <= 6) + ? HT_EXTCHNL_OFFSET_UPPER : + HT_EXTCHNL_OFFSET_LOWER); + pHTInfoEle->RecommemdedTxWidth = pHT->bRegBW40MHz; + pHTInfoEle->RIFS = 0; + pHTInfoEle->PSMPAccessOnly = 0; + pHTInfoEle->SrvIntGranularity = 0; + pHTInfoEle->OptMode = pHT->CurrentOpMode; + pHTInfoEle->NonGFDevPresent = 0; + pHTInfoEle->DualBeacon = 0; + pHTInfoEle->SecondaryBeacon = 0; + pHTInfoEle->LSigTxopProtectFull = 0; + pHTInfoEle->PcoActive = 0; + pHTInfoEle->PcoPhase = 0; + + memset(pHTInfoEle->BasicMSC, 0, 16); + + + *len = 22 + 2; + + } else { + *len = 0; + } + return; +} + +void HTConstructRT2RTAggElement(struct rtllib_device *ieee, u8 *posRT2RTAgg, + u8 *len) +{ + if (posRT2RTAgg == NULL) { + RTLLIB_DEBUG(RTLLIB_DL_ERR, "posRT2RTAgg can't be null in " + "HTConstructRT2RTAggElement()\n"); + return; + } + memset(posRT2RTAgg, 0, *len); + *posRT2RTAgg++ = 0x00; + *posRT2RTAgg++ = 0xe0; + *posRT2RTAgg++ = 0x4c; + *posRT2RTAgg++ = 0x02; + *posRT2RTAgg++ = 0x01; + + *posRT2RTAgg = 0x30; + + if (ieee->bSupportRemoteWakeUp) + *posRT2RTAgg |= RT_HT_CAP_USE_WOW; + + *len = 6 + 2; + + return; +} + +static u8 HT_PickMCSRate(struct rtllib_device *ieee, u8 *pOperateMCS) +{ + u8 i; + if (pOperateMCS == NULL) { + RTLLIB_DEBUG(RTLLIB_DL_ERR, "pOperateMCS can't be null" + " in HT_PickMCSRate()\n"); + return false; + } + + switch (ieee->mode) { + case IEEE_A: + case IEEE_B: + case IEEE_G: + for (i = 0; i <= 15; i++) + pOperateMCS[i] = 0; + break; + case IEEE_N_24G: + case IEEE_N_5G: + pOperateMCS[0] &= RATE_ADPT_1SS_MASK; + pOperateMCS[1] &= RATE_ADPT_2SS_MASK; + pOperateMCS[3] &= RATE_ADPT_MCS32_MASK; + break; + default: + break; + + } + + return true; +} + +u8 HTGetHighestMCSRate(struct rtllib_device *ieee, u8 *pMCSRateSet, + u8 *pMCSFilter) +{ + u8 i, j; + u8 bitMap; + u8 mcsRate = 0; + u8 availableMcsRate[16]; + if (pMCSRateSet == NULL || pMCSFilter == NULL) { + RTLLIB_DEBUG(RTLLIB_DL_ERR, "pMCSRateSet or pMCSFilter can't " + "be null in HTGetHighestMCSRate()\n"); + return false; + } + for (i = 0; i < 16; i++) + availableMcsRate[i] = pMCSRateSet[i] & pMCSFilter[i]; + + for (i = 0; i < 16; i++) { + if (availableMcsRate[i] != 0) + break; + } + if (i == 16) + return false; + + for (i = 0; i < 16; i++) { + if (availableMcsRate[i] != 0) { + bitMap = availableMcsRate[i]; + for (j = 0; j < 8; j++) { + if ((bitMap%2) != 0) { + if (HTMcsToDataRate(ieee, (8*i+j)) > + HTMcsToDataRate(ieee, mcsRate)) + mcsRate = (8*i+j); + } + bitMap = bitMap>>1; + } + } + } + return mcsRate | 0x80; +} + +u8 HTFilterMCSRate(struct rtllib_device *ieee, u8 *pSupportMCS, u8 *pOperateMCS) +{ + + u8 i; + + for (i = 0; i <= 15; i++) + pOperateMCS[i] = ieee->Regdot11TxHTOperationalRateSet[i] & + pSupportMCS[i]; + + HT_PickMCSRate(ieee, pOperateMCS); + + if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) + pOperateMCS[1] = 0; + + for (i = 2; i <= 15; i++) + pOperateMCS[i] = 0; + + return true; +} + +void HTSetConnectBwMode(struct rtllib_device *ieee, + enum ht_channel_width Bandwidth, + enum ht_extchnl_offset Offset); + +void HTOnAssocRsp(struct rtllib_device *ieee) +{ + struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; + struct ht_capab_ele *pPeerHTCap = NULL; + struct ht_info_ele *pPeerHTInfo = NULL; + u16 nMaxAMSDUSize = 0; + u8 *pMcsFilter = NULL; + + static u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; + static u8 EWC11NHTInfo[] = {0x00, 0x90, 0x4c, 0x34}; + + if (pHTInfo->bCurrentHTSupport == false) { + RTLLIB_DEBUG(RTLLIB_DL_ERR, "<=== HTOnAssocRsp(): " + "HT_DISABLE\n"); + return; + } + RTLLIB_DEBUG(RTLLIB_DL_HT, "===> HTOnAssocRsp_wq(): HT_ENABLE\n"); + + if (!memcmp(pHTInfo->PeerHTCapBuf, EWC11NHTCap, sizeof(EWC11NHTCap))) + pPeerHTCap = (struct ht_capab_ele *)(&pHTInfo->PeerHTCapBuf[4]); + else + pPeerHTCap = (struct ht_capab_ele *)(pHTInfo->PeerHTCapBuf); + + if (!memcmp(pHTInfo->PeerHTInfoBuf, EWC11NHTInfo, sizeof(EWC11NHTInfo))) + pPeerHTInfo = (struct ht_info_ele *) + (&pHTInfo->PeerHTInfoBuf[4]); + else + pPeerHTInfo = (struct ht_info_ele *)(pHTInfo->PeerHTInfoBuf); + + RTLLIB_DEBUG_DATA(RTLLIB_DL_DATA | RTLLIB_DL_HT, pPeerHTCap, + sizeof(struct ht_capab_ele)); + HTSetConnectBwMode(ieee, (enum ht_channel_width)(pPeerHTCap->ChlWidth), + (enum ht_extchnl_offset)(pPeerHTInfo->ExtChlOffset)); + pHTInfo->bCurTxBW40MHz = ((pPeerHTInfo->RecommemdedTxWidth == 1) ? + true : false); + + pHTInfo->bCurShortGI20MHz = ((pHTInfo->bRegShortGI20MHz) ? + ((pPeerHTCap->ShortGI20Mhz == 1) ? + true : false) : false); + pHTInfo->bCurShortGI40MHz = ((pHTInfo->bRegShortGI40MHz) ? + ((pPeerHTCap->ShortGI40Mhz == 1) ? + true : false) : false); + + pHTInfo->bCurSuppCCK = ((pHTInfo->bRegSuppCCK) ? + ((pPeerHTCap->DssCCk == 1) ? true : + false) : false); + + + pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support; + + nMaxAMSDUSize = (pPeerHTCap->MaxAMSDUSize == 0) ? 3839 : 7935; + + if (pHTInfo->nAMSDU_MaxSize > nMaxAMSDUSize) + pHTInfo->nCurrent_AMSDU_MaxSize = nMaxAMSDUSize; + else + pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize; + + pHTInfo->bCurrentAMPDUEnable = pHTInfo->bAMPDUEnable; + if (ieee->rtllib_ap_sec_type && + (ieee->rtllib_ap_sec_type(ieee)&(SEC_ALG_WEP|SEC_ALG_TKIP))) { + if ((pHTInfo->IOTPeer == HT_IOT_PEER_ATHEROS) || + (pHTInfo->IOTPeer == HT_IOT_PEER_UNKNOWN)) + pHTInfo->bCurrentAMPDUEnable = false; + } + + if (!pHTInfo->bRegRT2RTAggregation) { + if (pHTInfo->AMPDU_Factor > pPeerHTCap->MaxRxAMPDUFactor) + pHTInfo->CurrentAMPDUFactor = + pPeerHTCap->MaxRxAMPDUFactor; + else + pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor; + + } else { + if (ieee->current_network.bssht.bdRT2RTAggregation) { + if (ieee->pairwise_key_type != KEY_TYPE_NA) + pHTInfo->CurrentAMPDUFactor = + pPeerHTCap->MaxRxAMPDUFactor; + else + pHTInfo->CurrentAMPDUFactor = HT_AGG_SIZE_64K; + } else { + if (pPeerHTCap->MaxRxAMPDUFactor < HT_AGG_SIZE_32K) + pHTInfo->CurrentAMPDUFactor = + pPeerHTCap->MaxRxAMPDUFactor; + else + pHTInfo->CurrentAMPDUFactor = HT_AGG_SIZE_32K; + } + } + if (pHTInfo->MPDU_Density > pPeerHTCap->MPDUDensity) + pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density; + else + pHTInfo->CurrentMPDUDensity = pPeerHTCap->MPDUDensity; + if (pHTInfo->IOTAction & HT_IOT_ACT_TX_USE_AMSDU_8K) { + pHTInfo->bCurrentAMPDUEnable = false; + pHTInfo->ForcedAMSDUMode = HT_AGG_FORCE_ENABLE; + pHTInfo->ForcedAMSDUMaxSize = 7935; + } + pHTInfo->bCurRxReorderEnable = pHTInfo->bRegRxReorderEnable; + + if (pPeerHTCap->MCS[0] == 0) + pPeerHTCap->MCS[0] = 0xff; + + HTIOTActDetermineRaFunc(ieee, ((pPeerHTCap->MCS[1]) != 0)); + + HTFilterMCSRate(ieee, pPeerHTCap->MCS, ieee->dot11HTOperationalRateSet); + + pHTInfo->PeerMimoPs = pPeerHTCap->MimoPwrSave; + if (pHTInfo->PeerMimoPs == MIMO_PS_STATIC) + pMcsFilter = MCS_FILTER_1SS; + else + pMcsFilter = MCS_FILTER_ALL; + ieee->HTHighestOperaRate = HTGetHighestMCSRate(ieee, + ieee->dot11HTOperationalRateSet, pMcsFilter); + ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate; + + pHTInfo->CurrentOpMode = pPeerHTInfo->OptMode; +} + +void HTInitializeHTInfo(struct rtllib_device *ieee) +{ + struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; + + RTLLIB_DEBUG(RTLLIB_DL_HT, "===========>%s()\n", __func__); + pHTInfo->bCurrentHTSupport = false; + + pHTInfo->bCurBW40MHz = false; + pHTInfo->bCurTxBW40MHz = false; + + pHTInfo->bCurShortGI20MHz = false; + pHTInfo->bCurShortGI40MHz = false; + pHTInfo->bForcedShortGI = false; + + pHTInfo->bCurSuppCCK = true; + + pHTInfo->bCurrent_AMSDU_Support = false; + pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize; + pHTInfo->CurrentMPDUDensity = pHTInfo->MPDU_Density; + pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor; + + memset((void *)(&(pHTInfo->SelfHTCap)), 0, + sizeof(pHTInfo->SelfHTCap)); + memset((void *)(&(pHTInfo->SelfHTInfo)), 0, + sizeof(pHTInfo->SelfHTInfo)); + memset((void *)(&(pHTInfo->PeerHTCapBuf)), 0, + sizeof(pHTInfo->PeerHTCapBuf)); + memset((void *)(&(pHTInfo->PeerHTInfoBuf)), 0, + sizeof(pHTInfo->PeerHTInfoBuf)); + + pHTInfo->bSwBwInProgress = false; + pHTInfo->ChnlOp = CHNLOP_NONE; + + pHTInfo->ePeerHTSpecVer = HT_SPEC_VER_IEEE; + + pHTInfo->bCurrentRT2RTAggregation = false; + pHTInfo->bCurrentRT2RTLongSlotTime = false; + pHTInfo->RT2RT_HT_Mode = (enum rt_ht_capability)0; + + pHTInfo->IOTPeer = 0; + pHTInfo->IOTAction = 0; + pHTInfo->IOTRaFunc = 0; + + { + u8 *RegHTSuppRateSets = &(ieee->RegHTSuppRateSet[0]); + RegHTSuppRateSets[0] = 0xFF; + RegHTSuppRateSets[1] = 0xFF; + RegHTSuppRateSets[4] = 0x01; + } +} + +void HTInitializeBssDesc(struct bss_ht *pBssHT) +{ + + pBssHT->bdSupportHT = false; + memset(pBssHT->bdHTCapBuf, 0, sizeof(pBssHT->bdHTCapBuf)); + pBssHT->bdHTCapLen = 0; + memset(pBssHT->bdHTInfoBuf, 0, sizeof(pBssHT->bdHTInfoBuf)); + pBssHT->bdHTInfoLen = 0; + + pBssHT->bdHTSpecVer = HT_SPEC_VER_IEEE; + + pBssHT->bdRT2RTAggregation = false; + pBssHT->bdRT2RTLongSlotTime = false; + pBssHT->RT2RT_HT_Mode = (enum rt_ht_capability)0; +} + +void HTResetSelfAndSavePeerSetting(struct rtllib_device *ieee, + struct rtllib_network *pNetwork) +{ + struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; + u8 bIOTAction = 0; + + RTLLIB_DEBUG(RTLLIB_DL_HT, "==============>%s()\n", __func__); + /* unmark bEnableHT flag here is the same reason why unmarked in + * function rtllib_softmac_new_net. WB 2008.09.10*/ + if (pNetwork->bssht.bdSupportHT) { + pHTInfo->bCurrentHTSupport = true; + pHTInfo->ePeerHTSpecVer = pNetwork->bssht.bdHTSpecVer; + + if (pNetwork->bssht.bdHTCapLen > 0 && + pNetwork->bssht.bdHTCapLen <= sizeof(pHTInfo->PeerHTCapBuf)) + memcpy(pHTInfo->PeerHTCapBuf, + pNetwork->bssht.bdHTCapBuf, + pNetwork->bssht.bdHTCapLen); + + if (pNetwork->bssht.bdHTInfoLen > 0 && + pNetwork->bssht.bdHTInfoLen <= + sizeof(pHTInfo->PeerHTInfoBuf)) + memcpy(pHTInfo->PeerHTInfoBuf, + pNetwork->bssht.bdHTInfoBuf, + pNetwork->bssht.bdHTInfoLen); + + if (pHTInfo->bRegRT2RTAggregation) { + pHTInfo->bCurrentRT2RTAggregation = + pNetwork->bssht.bdRT2RTAggregation; + pHTInfo->bCurrentRT2RTLongSlotTime = + pNetwork->bssht.bdRT2RTLongSlotTime; + pHTInfo->RT2RT_HT_Mode = pNetwork->bssht.RT2RT_HT_Mode; + } else { + pHTInfo->bCurrentRT2RTAggregation = false; + pHTInfo->bCurrentRT2RTLongSlotTime = false; + pHTInfo->RT2RT_HT_Mode = (enum rt_ht_capability)0; + } + + HTIOTPeerDetermine(ieee); + + pHTInfo->IOTAction = 0; + bIOTAction = HTIOTActIsDisableMCS14(ieee, pNetwork->bssid); + if (bIOTAction) + pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_MCS14; + + bIOTAction = HTIOTActIsDisableMCS15(ieee); + if (bIOTAction) + pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_MCS15; + + bIOTAction = HTIOTActIsDisableMCSTwoSpatialStream(ieee); + if (bIOTAction) + pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_ALL_2SS; + + + bIOTAction = HTIOTActIsDisableEDCATurbo(ieee, pNetwork->bssid); + if (bIOTAction) + pHTInfo->IOTAction |= HT_IOT_ACT_DISABLE_EDCA_TURBO; + + bIOTAction = HTIOTActIsMgntUseCCK6M(ieee, pNetwork); + if (bIOTAction) + pHTInfo->IOTAction |= HT_IOT_ACT_MGNT_USE_CCK_6M; + bIOTAction = HTIOTActIsCCDFsync(ieee); + if (bIOTAction) + pHTInfo->IOTAction |= HT_IOT_ACT_CDD_FSYNC; + } else { + pHTInfo->bCurrentHTSupport = false; + pHTInfo->bCurrentRT2RTAggregation = false; + pHTInfo->bCurrentRT2RTLongSlotTime = false; + pHTInfo->RT2RT_HT_Mode = (enum rt_ht_capability)0; + + pHTInfo->IOTAction = 0; + pHTInfo->IOTRaFunc = 0; + } +} + +void HTUpdateSelfAndPeerSetting(struct rtllib_device *ieee, + struct rtllib_network *pNetwork) +{ + struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; + struct ht_info_ele *pPeerHTInfo = + (struct ht_info_ele *)pNetwork->bssht.bdHTInfoBuf; + + if (pHTInfo->bCurrentHTSupport) { + if (pNetwork->bssht.bdHTInfoLen != 0) + pHTInfo->CurrentOpMode = pPeerHTInfo->OptMode; + } +} + +void HTUseDefaultSetting(struct rtllib_device *ieee) +{ + struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; + + if (pHTInfo->bEnableHT) { + pHTInfo->bCurrentHTSupport = true; + pHTInfo->bCurSuppCCK = pHTInfo->bRegSuppCCK; + + pHTInfo->bCurBW40MHz = pHTInfo->bRegBW40MHz; + pHTInfo->bCurShortGI20MHz = pHTInfo->bRegShortGI20MHz; + + pHTInfo->bCurShortGI40MHz = pHTInfo->bRegShortGI40MHz; + + if (ieee->iw_mode == IW_MODE_ADHOC) + ieee->current_network.qos_data.active = + ieee->current_network.qos_data.supported; + pHTInfo->bCurrent_AMSDU_Support = pHTInfo->bAMSDU_Support; + pHTInfo->nCurrent_AMSDU_MaxSize = pHTInfo->nAMSDU_MaxSize; + + pHTInfo->bCurrentAMPDUEnable = pHTInfo->bAMPDUEnable; + pHTInfo->CurrentAMPDUFactor = pHTInfo->AMPDU_Factor; + + pHTInfo->CurrentMPDUDensity = pHTInfo->CurrentMPDUDensity; + + HTFilterMCSRate(ieee, ieee->Regdot11TxHTOperationalRateSet, + ieee->dot11HTOperationalRateSet); + ieee->HTHighestOperaRate = HTGetHighestMCSRate(ieee, + ieee->dot11HTOperationalRateSet, + MCS_FILTER_ALL); + ieee->HTCurrentOperaRate = ieee->HTHighestOperaRate; + + } else { + pHTInfo->bCurrentHTSupport = false; + } + return; +} + +u8 HTCCheck(struct rtllib_device *ieee, u8 *pFrame) +{ + if (ieee->pHTInfo->bCurrentHTSupport) { + if ((IsQoSDataFrame(pFrame) && Frame_Order(pFrame)) == 1) { + RTLLIB_DEBUG(RTLLIB_DL_HT, "HT CONTROL FILED " + "EXIST!!\n"); + return true; + } + } + return false; +} + +static void HTSetConnectBwModeCallback(struct rtllib_device *ieee) +{ + struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; + + RTLLIB_DEBUG(RTLLIB_DL_HT, "======>%s()\n", __func__); + if (pHTInfo->bCurBW40MHz) { + if (pHTInfo->CurSTAExtChnlOffset == HT_EXTCHNL_OFFSET_UPPER) + ieee->set_chan(ieee->dev, + ieee->current_network.channel + 2); + else if (pHTInfo->CurSTAExtChnlOffset == + HT_EXTCHNL_OFFSET_LOWER) + ieee->set_chan(ieee->dev, + ieee->current_network.channel - 2); + else + ieee->set_chan(ieee->dev, + ieee->current_network.channel); + + ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20_40, + pHTInfo->CurSTAExtChnlOffset); + } else { + ieee->set_chan(ieee->dev, ieee->current_network.channel); + ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20, + HT_EXTCHNL_OFFSET_NO_EXT); + } + + pHTInfo->bSwBwInProgress = false; +} + +void HTSetConnectBwMode(struct rtllib_device *ieee, + enum ht_channel_width Bandwidth, + enum ht_extchnl_offset Offset) +{ + struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; + + if (pHTInfo->bRegBW40MHz == false) + return; + + if (ieee->GetHalfNmodeSupportByAPsHandler(ieee->dev)) + Bandwidth = HT_CHANNEL_WIDTH_20; + + if (pHTInfo->bSwBwInProgress) { + printk(KERN_INFO "%s: bSwBwInProgress!!\n", __func__); + return; + } + if (Bandwidth == HT_CHANNEL_WIDTH_20_40) { + if (ieee->current_network.channel < 2 && + Offset == HT_EXTCHNL_OFFSET_LOWER) + Offset = HT_EXTCHNL_OFFSET_NO_EXT; + if (Offset == HT_EXTCHNL_OFFSET_UPPER || + Offset == HT_EXTCHNL_OFFSET_LOWER) { + pHTInfo->bCurBW40MHz = true; + pHTInfo->CurSTAExtChnlOffset = Offset; + } else { + pHTInfo->bCurBW40MHz = false; + pHTInfo->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT; + } + } else { + pHTInfo->bCurBW40MHz = false; + pHTInfo->CurSTAExtChnlOffset = HT_EXTCHNL_OFFSET_NO_EXT; + } + + printk(KERN_INFO "%s():pHTInfo->bCurBW40MHz:%x\n", __func__, + pHTInfo->bCurBW40MHz); + + pHTInfo->bSwBwInProgress = true; + + HTSetConnectBwModeCallback(ieee); +} diff --git a/drivers/staging/rtl8192e/rtl819x_Qos.h b/drivers/staging/rtl8192e/rtl819x_Qos.h new file mode 100644 index 0000000..5ecd556 --- /dev/null +++ b/drivers/staging/rtl8192e/rtl819x_Qos.h @@ -0,0 +1,444 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> +******************************************************************************/ +#ifndef __INC_QOS_TYPE_H +#define __INC_QOS_TYPE_H + +#include "rtllib_endianfree.h" + +#define BIT0 0x00000001 +#define BIT1 0x00000002 +#define BIT2 0x00000004 +#define BIT3 0x00000008 +#define BIT4 0x00000010 +#define BIT5 0x00000020 +#define BIT6 0x00000040 +#define BIT7 0x00000080 +#define BIT8 0x00000100 +#define BIT9 0x00000200 +#define BIT10 0x00000400 +#define BIT11 0x00000800 +#define BIT12 0x00001000 +#define BIT13 0x00002000 +#define BIT14 0x00004000 +#define BIT15 0x00008000 +#define BIT16 0x00010000 +#define BIT17 0x00020000 +#define BIT18 0x00040000 +#define BIT19 0x00080000 +#define BIT20 0x00100000 +#define BIT21 0x00200000 +#define BIT22 0x00400000 +#define BIT23 0x00800000 +#define BIT24 0x01000000 +#define BIT25 0x02000000 +#define BIT26 0x04000000 +#define BIT27 0x08000000 +#define BIT28 0x10000000 +#define BIT29 0x20000000 +#define BIT30 0x40000000 +#define BIT31 0x80000000 + +union qos_tsinfo { + u8 charData[3]; + struct { + u8 ucTrafficType:1; + u8 ucTSID:4; + u8 ucDirection:2; + u8 ucAccessPolicy:2; + u8 ucAggregation:1; + u8 ucPSB:1; + u8 ucUP:3; + u8 ucTSInfoAckPolicy:2; + u8 ucSchedule:1; + u8 ucReserved:7; + } field; +}; + +union tspec_body { + u8 charData[55]; + + struct { + union qos_tsinfo TSInfo; + u16 NominalMSDUsize; + u16 MaxMSDUsize; + u32 MinServiceItv; + u32 MaxServiceItv; + u32 InactivityItv; + u32 SuspenItv; + u32 ServiceStartTime; + u32 MinDataRate; + u32 MeanDataRate; + u32 PeakDataRate; + u32 MaxBurstSize; + u32 DelayBound; + u32 MinPhyRate; + u16 SurplusBandwidthAllowance; + u16 MediumTime; + } f; +}; + +struct wmm_tspec { + u8 ID; + u8 Length; + u8 OUI[3]; + u8 OUI_Type; + u8 OUI_SubType; + u8 Version; + union tspec_body Body; +}; + +struct octet_string { + u8 *Octet; + u16 Length; +}; + +#define MAX_WMMELE_LENGTH 64 + +#define QOS_MODE u32 + +#define QOS_DISABLE 0 +#define QOS_WMM 1 +#define QOS_WMMSA 2 +#define QOS_EDCA 4 +#define QOS_HCCA 8 +#define QOS_WMM_UAPSD 16 + +#define WMM_PARAM_ELE_BODY_LEN 18 + +#define MAX_STA_TS_COUNT 16 +#define MAX_AP_TS_COUNT 32 +#define QOS_TSTREAM_KEY_SIZE 13 + +#define WMM_ACTION_CATEGORY_CODE 17 +#define WMM_PARAM_ELE_BODY_LEN 18 + +#define MAX_TSPEC_TSID 15 +#define SESSION_REJECT_TSID 0xfe +#define DEFAULT_TSID 0xff + +#define ADDTS_TIME_SLOT 100 + +#define ACM_TIMEOUT 1000 +#define SESSION_REJECT_TIMEOUT 60000 + +enum ack_policy { + eAckPlc0_ACK = 0x00, + eAckPlc1_NoACK = 0x01, +}; + + +#define SET_WMM_QOS_INFO_FIELD(_pStart, _val) \ + WriteEF1Byte(_pStart, _val) + +#define GET_WMM_QOS_INFO_FIELD_PARAMETERSET_COUNT(_pStart) \ + LE_BITS_TO_1BYTE(_pStart, 0, 4) +#define SET_WMM_QOS_INFO_FIELD_PARAMETERSET_COUNT(_pStart, _val) \ + SET_BITS_TO_LE_1BYTE(_pStart, 0, 4, _val) + +#define GET_WMM_QOS_INFO_FIELD_AP_UAPSD(_pStart) \ + LE_BITS_TO_1BYTE(_pStart, 7, 1) +#define SET_WMM_QOS_INFO_FIELD_AP_UAPSD(_pStart, _val) \ + SET_BITS_TO_LE_1BYTE(_pStart, 7, 1, _val) + +#define GET_WMM_QOS_INFO_FIELD_STA_AC_VO_UAPSD(_pStart) \ + LE_BITS_TO_1BYTE(_pStart, 0, 1) +#define SET_WMM_QOS_INFO_FIELD_STA_AC_VO_UAPSD(_pStart, _val) \ + SET_BITS_TO_LE_1BYTE(_pStart, 0, 1, _val) + +#define GET_WMM_QOS_INFO_FIELD_STA_AC_VI_UAPSD(_pStart) \ + LE_BITS_TO_1BYTE(_pStart, 1, 1) +#define SET_WMM_QOS_INFO_FIELD_STA_AC_VI_UAPSD(_pStart, _val) \ + SET_BITS_TO_LE_1BYTE(_pStart, 1, 1, _val) + +#define GET_WMM_QOS_INFO_FIELD_STA_AC_BE_UAPSD(_pStart) \ + LE_BITS_TO_1BYTE(_pStart, 2, 1) +#define SET_WMM_QOS_INFO_FIELD_STA_AC_BE_UAPSD(_pStart, _val) \ + SET_BITS_TO_LE_1BYTE(_pStart, 2, 1, _val) + +#define GET_WMM_QOS_INFO_FIELD_STA_AC_BK_UAPSD(_pStart) \ + LE_BITS_TO_1BYTE(_pStart, 3, 1) +#define SET_WMM_QOS_INFO_FIELD_STA_AC_BK_UAPSD(_pStart, _val) \ + SET_BITS_TO_LE_1BYTE(_pStart, 3, 1, _val) + +#define GET_WMM_QOS_INFO_FIELD_STA_MAX_SP_LEN(_pStart) \ + LE_BITS_TO_1BYTE(_pStart, 5, 2) +#define SET_WMM_QOS_INFO_FIELD_STA_MAX_SP_LEN(_pStart, _val) \ + SET_BITS_TO_LE_1BYTE(_pStart, 5, 2, _val) + +enum qos_ie_source { + QOSIE_SRC_ADDTSREQ, + QOSIE_SRC_ADDTSRSP, + QOSIE_SRC_REASOCREQ, + QOSIE_SRC_REASOCRSP, + QOSIE_SRC_DELTS, +}; + + +#define AC_CODING u32 + +#define AC0_BE 0 +#define AC1_BK 1 +#define AC2_VI 2 +#define AC3_VO 3 +#define AC_MAX 4 + + +#define AC_PARAM_SIZE 4 + +#define GET_WMM_AC_PARAM_AIFSN(_pStart) \ + ((u8)LE_BITS_TO_4BYTE(_pStart, 0, 4)) +#define SET_WMM_AC_PARAM_AIFSN(_pStart, _val) \ + SET_BITS_TO_LE_4BYTE(_pStart, 0, 4, _val) + +#define GET_WMM_AC_PARAM_ACM(_pStart) \ + ((u8)LE_BITS_TO_4BYTE(_pStart, 4, 1)) +#define SET_WMM_AC_PARAM_ACM(_pStart, _val) \ + SET_BITS_TO_LE_4BYTE(_pStart, 4, 1, _val) + +#define GET_WMM_AC_PARAM_ACI(_pStart) \ + ((u8)LE_BITS_TO_4BYTE(_pStart, 5, 2)) +#define SET_WMM_AC_PARAM_ACI(_pStart, _val) \ + SET_BITS_TO_LE_4BYTE(_pStart, 5, 2, _val) + +#define GET_WMM_AC_PARAM_ACI_AIFSN(_pStart) \ + ((u8)LE_BITS_TO_4BYTE(_pStart, 0, 8)) +#define SET_WMM_AC_PARAM_ACI_AIFSN(_pStart, _val) \ + SET_BITS_TO_LE_4BYTE(_pStart, 0, 8, _val) + +#define GET_WMM_AC_PARAM_ECWMIN(_pStart) \ + ((u8)LE_BITS_TO_4BYTE(_pStart, 8, 4)) +#define SET_WMM_AC_PARAM_ECWMIN(_pStart, _val) \ + SET_BITS_TO_LE_4BYTE(_pStart, 8, 4, _val) + +#define GET_WMM_AC_PARAM_ECWMAX(_pStart) \ + ((u8)LE_BITS_TO_4BYTE(_pStart, 12, 4)) +#define SET_WMM_AC_PARAM_ECWMAX(_pStart, _val) \ + SET_BITS_TO_LE_4BYTE(_pStart, 12, 4, _val) + +#define GET_WMM_AC_PARAM_TXOP_LIMIT(_pStart) \ + ((u8)LE_BITS_TO_4BYTE(_pStart, 16, 16)) +#define SET_WMM_AC_PARAM_TXOP_LIMIT(_pStart, _val) \ + SET_BITS_TO_LE_4BYTE(_pStart, 16, 16, _val) + + + +#define WMM_PARAM_ELEMENT_SIZE (8+(4*AC_PARAM_SIZE)) + +enum qos_ele_subtype { + QOSELE_TYPE_INFO = 0x00, + QOSELE_TYPE_PARAM = 0x01, +}; + + +enum direction_value { + DIR_UP = 0, + DIR_DOWN = 1, + DIR_DIRECT = 2, + DIR_BI_DIR = 3, +}; + +enum acm_method { + eAcmWay0_SwAndHw = 0, + eAcmWay1_HW = 1, + eAcmWay2_SW = 2, +}; + + +struct acm { + u64 UsedTime; + u64 MediumTime; + u8 HwAcmCtl; +}; + + + +#define AC_UAPSD u8 + +#define GET_VO_UAPSD(_apsd) ((_apsd) & BIT0) +#define SET_VO_UAPSD(_apsd) ((_apsd) |= BIT0) + +#define GET_VI_UAPSD(_apsd) ((_apsd) & BIT1) +#define SET_VI_UAPSD(_apsd) ((_apsd) |= BIT1) + +#define GET_BK_UAPSD(_apsd) ((_apsd) & BIT2) +#define SET_BK_UAPSD(_apsd) ((_apsd) |= BIT2) + +#define GET_BE_UAPSD(_apsd) ((_apsd) & BIT3) +#define SET_BE_UAPSD(_apsd) ((_apsd) |= BIT3) + +union qos_tclas { + + struct _TYPE_GENERAL { + u8 Priority; + u8 ClassifierType; + u8 Mask; + } TYPE_GENERAL; + + struct _TYPE0_ETH { + u8 Priority; + u8 ClassifierType; + u8 Mask; + u8 SrcAddr[6]; + u8 DstAddr[6]; + u16 Type; + } TYPE0_ETH; + + struct _TYPE1_IPV4 { + u8 Priority; + u8 ClassifierType; + u8 Mask; + u8 Version; + u8 SrcIP[4]; + u8 DstIP[4]; + u16 SrcPort; + u16 DstPort; + u8 DSCP; + u8 Protocol; + u8 Reserved; + } TYPE1_IPV4; + + struct _TYPE1_IPV6 { + u8 Priority; + u8 ClassifierType; + u8 Mask; + u8 Version; + u8 SrcIP[16]; + u8 DstIP[16]; + u16 SrcPort; + u16 DstPort; + u8 FlowLabel[3]; + } TYPE1_IPV6; + + struct _TYPE2_8021Q { + u8 Priority; + u8 ClassifierType; + u8 Mask; + u16 TagType; + } TYPE2_8021Q; +}; + +struct qos_tstream { + + bool bUsed; + u16 MsduLifetime; + bool bEstablishing; + u8 TimeSlotCount; + u8 DialogToken; + struct wmm_tspec TSpec; + struct wmm_tspec OutStandingTSpec; + u8 NominalPhyRate; +}; + +struct sta_qos { + u8 WMMIEBuf[MAX_WMMELE_LENGTH]; + u8 *WMMIE; + + QOS_MODE QosCapability; + QOS_MODE CurrentQosMode; + + AC_UAPSD b4ac_Uapsd; + AC_UAPSD Curr4acUapsd; + u8 bInServicePeriod; + u8 MaxSPLength; + int NumBcnBeforeTrigger; + + u8 *pWMMInfoEle; + u8 WMMParamEle[WMM_PARAM_ELEMENT_SIZE]; + + struct acm acm[4]; + enum acm_method AcmMethod; + + struct qos_tstream StaTsArray[MAX_STA_TS_COUNT]; + u8 DialogToken; + struct wmm_tspec TSpec; + + u8 QBssWirelessMode; + + bool bNoAck; + + bool bEnableRxImmBA; + +}; + +#define QBSS_LOAD_SIZE 5 +#define GET_QBSS_LOAD_STA_COUNT(__pStart) \ + ReadEF2Byte(__pStart) +#define SET_QBSS_LOAD_STA_COUNT(__pStart, __Value) \ + WriteEF2Byte(__pStart, __Value) +#define GET_QBSS_LOAD_CHNL_UTILIZATION(__pStart) \ + ReadEF1Byte((u8 *)(__pStart) + 2) +#define SET_QBSS_LOAD_CHNL_UTILIZATION(__pStart, __Value) \ + WriteEF1Byte((u8 *)(__pStart) + 2, __Value) +#define GET_QBSS_LOAD_AVAILABLE_CAPACITY(__pStart) \ + ReadEF2Byte((u8 *)(__pStart) + 3) +#define SET_QBSS_LOAD_AVAILABLE_CAPACITY(__pStart, __Value) \ + WriteEF2Byte((u8 *)(__pStart) + 3, __Value) + +struct bss_qos { + QOS_MODE bdQoSMode; + u8 bdWMMIEBuf[MAX_WMMELE_LENGTH]; + struct octet_string bdWMMIE; + + enum qos_ele_subtype EleSubType; + + u8 *pWMMInfoEle; + u8 *pWMMParamEle; + + u8 QBssLoad[QBSS_LOAD_SIZE]; + bool bQBssLoadValid; +}; + +#define sQoSCtlLng 2 +#define QOS_CTRL_LEN(_QosMode) ((_QosMode > QOS_DISABLE) ? sQoSCtlLng : 0) + + +#define IsACValid(ac) ((ac >= 0 && ac <= 7) ? true : false) + + +union aci_aifsn { + u8 charData; + + struct { + u8 AIFSN:4; + u8 acm:1; + u8 ACI:2; + u8 Reserved:1; + } f; +}; + +union ecw { + u8 charData; + struct { + u8 ECWmin:4; + u8 ECWmax:4; + } f; +}; + +union ac_param { + u32 longData; + u8 charData[4]; + + struct { + union aci_aifsn AciAifsn; + union ecw Ecw; + u16 TXOPLimit; + } f; +}; + +#endif diff --git a/drivers/staging/rtl8192e/rtl819x_TS.h b/drivers/staging/rtl8192e/rtl819x_TS.h new file mode 100644 index 0000000..8601b1a --- /dev/null +++ b/drivers/staging/rtl8192e/rtl819x_TS.h @@ -0,0 +1,73 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> +******************************************************************************/ +#ifndef _TSTYPE_H_ +#define _TSTYPE_H_ +#include "rtl819x_Qos.h" +#define TS_SETUP_TIMEOUT 60 +#define TS_INACT_TIMEOUT 60 +#define TS_ADDBA_DELAY 60 + +#define TOTAL_TS_NUM 16 +#define TCLAS_NUM 4 + +enum tr_select { + TX_DIR = 0, + RX_DIR = 1, +}; + +struct ts_common_info { + struct list_head List; + struct timer_list SetupTimer; + struct timer_list InactTimer; + u8 Addr[6]; + union tspec_body TSpec; + union qos_tclas TClass[TCLAS_NUM]; + u8 TClasProc; + u8 TClasNum; +}; + +struct tx_ts_record { + struct ts_common_info TsCommonInfo; + u16 TxCurSeq; + struct ba_record TxPendingBARecord; + struct ba_record TxAdmittedBARecord; + u8 bAddBaReqInProgress; + u8 bAddBaReqDelayed; + u8 bUsingBa; + u8 bDisable_AddBa; + struct timer_list TsAddBaTimer; + u8 num; +}; + +struct rx_ts_record { + struct ts_common_info TsCommonInfo; + u16 RxIndicateSeq; + u16 RxTimeoutIndicateSeq; + struct list_head RxPendingPktList; + struct timer_list RxPktPendingTimer; + struct ba_record RxAdmittedBARecord; + u16 RxLastSeqNum; + u8 RxLastFragNum; + u8 num; +}; + +void _setup_timer(struct timer_list *, void *, unsigned long); + + +#endif diff --git a/drivers/staging/rtl8192e/rtl819x_TSProc.c b/drivers/staging/rtl8192e/rtl819x_TSProc.c new file mode 100644 index 0000000..ccec382 --- /dev/null +++ b/drivers/staging/rtl8192e/rtl819x_TSProc.c @@ -0,0 +1,549 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> +******************************************************************************/ +#include "rtllib.h" +#include <linux/etherdevice.h> +#include "rtl819x_TS.h" + +static void TsSetupTimeOut(unsigned long data) +{ +} + +static void TsInactTimeout(unsigned long data) +{ +} + +static void RxPktPendingTimeout(unsigned long data) +{ + struct rx_ts_record *pRxTs = (struct rx_ts_record *)data; + struct rtllib_device *ieee = container_of(pRxTs, struct rtllib_device, + RxTsRecord[pRxTs->num]); + + struct rx_reorder_entry *pReorderEntry = NULL; + + unsigned long flags = 0; + struct rtllib_rxb *stats_IndicateArray[REORDER_WIN_SIZE]; + u8 index = 0; + bool bPktInBuf = false; + + spin_lock_irqsave(&(ieee->reorder_spinlock), flags); + if (pRxTs->RxTimeoutIndicateSeq != 0xffff) { + while (!list_empty(&pRxTs->RxPendingPktList)) { + pReorderEntry = (struct rx_reorder_entry *) + list_entry(pRxTs->RxPendingPktList.prev, + struct rx_reorder_entry, List); + if (index == 0) + pRxTs->RxIndicateSeq = pReorderEntry->SeqNum; + + if (SN_LESS(pReorderEntry->SeqNum, pRxTs->RxIndicateSeq) || + SN_EQUAL(pReorderEntry->SeqNum, pRxTs->RxIndicateSeq)) { + list_del_init(&pReorderEntry->List); + + if (SN_EQUAL(pReorderEntry->SeqNum, + pRxTs->RxIndicateSeq)) + pRxTs->RxIndicateSeq = + (pRxTs->RxIndicateSeq + 1) % 4096; + + RTLLIB_DEBUG(RTLLIB_DL_REORDER, "%s(): Indicate" + " SeqNum: %d\n", __func__, + pReorderEntry->SeqNum); + stats_IndicateArray[index] = + pReorderEntry->prxb; + index++; + + list_add_tail(&pReorderEntry->List, + &ieee->RxReorder_Unused_List); + } else { + bPktInBuf = true; + break; + } + } + } + + if (index > 0) { + pRxTs->RxTimeoutIndicateSeq = 0xffff; + + if (index > REORDER_WIN_SIZE) { + RTLLIB_DEBUG(RTLLIB_DL_ERR, "RxReorderIndicatePacket():" + " Rx Reorer struct buffer full!!\n"); + spin_unlock_irqrestore(&(ieee->reorder_spinlock), + flags); + return; + } + rtllib_indicate_packets(ieee, stats_IndicateArray, index); + bPktInBuf = false; + } + + if (bPktInBuf && (pRxTs->RxTimeoutIndicateSeq == 0xffff)) { + pRxTs->RxTimeoutIndicateSeq = pRxTs->RxIndicateSeq; + mod_timer(&pRxTs->RxPktPendingTimer, jiffies + + MSECS(ieee->pHTInfo->RxReorderPendingTime)); + } + spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags); +} + +static void TsAddBaProcess(unsigned long data) +{ + struct tx_ts_record *pTxTs = (struct tx_ts_record *)data; + u8 num = pTxTs->num; + struct rtllib_device *ieee = container_of(pTxTs, struct rtllib_device, + TxTsRecord[num]); + + TsInitAddBA(ieee, pTxTs, BA_POLICY_IMMEDIATE, false); + RTLLIB_DEBUG(RTLLIB_DL_BA, "TsAddBaProcess(): ADDBA Req is " + "started!!\n"); +} + +static void ResetTsCommonInfo(struct ts_common_info *pTsCommonInfo) +{ + memset(pTsCommonInfo->Addr, 0, 6); + memset(&pTsCommonInfo->TSpec, 0, sizeof(union tspec_body)); + memset(&pTsCommonInfo->TClass, 0, sizeof(union qos_tclas)*TCLAS_NUM); + pTsCommonInfo->TClasProc = 0; + pTsCommonInfo->TClasNum = 0; +} + +static void ResetTxTsEntry(struct tx_ts_record *pTS) +{ + ResetTsCommonInfo(&pTS->TsCommonInfo); + pTS->TxCurSeq = 0; + pTS->bAddBaReqInProgress = false; + pTS->bAddBaReqDelayed = false; + pTS->bUsingBa = false; + pTS->bDisable_AddBa = false; + ResetBaEntry(&pTS->TxAdmittedBARecord); + ResetBaEntry(&pTS->TxPendingBARecord); +} + +static void ResetRxTsEntry(struct rx_ts_record *pTS) +{ + ResetTsCommonInfo(&pTS->TsCommonInfo); + pTS->RxIndicateSeq = 0xffff; + pTS->RxTimeoutIndicateSeq = 0xffff; + ResetBaEntry(&pTS->RxAdmittedBARecord); +} + +void TSInitialize(struct rtllib_device *ieee) +{ + struct tx_ts_record *pTxTS = ieee->TxTsRecord; + struct rx_ts_record *pRxTS = ieee->RxTsRecord; + struct rx_reorder_entry *pRxReorderEntry = ieee->RxReorderEntry; + u8 count = 0; + RTLLIB_DEBUG(RTLLIB_DL_TS, "==========>%s()\n", __func__); + INIT_LIST_HEAD(&ieee->Tx_TS_Admit_List); + INIT_LIST_HEAD(&ieee->Tx_TS_Pending_List); + INIT_LIST_HEAD(&ieee->Tx_TS_Unused_List); + + for (count = 0; count < TOTAL_TS_NUM; count++) { + pTxTS->num = count; + _setup_timer(&pTxTS->TsCommonInfo.SetupTimer, + TsSetupTimeOut, + (unsigned long) pTxTS); + + _setup_timer(&pTxTS->TsCommonInfo.InactTimer, + TsInactTimeout, + (unsigned long) pTxTS); + + _setup_timer(&pTxTS->TsAddBaTimer, + TsAddBaProcess, + (unsigned long) pTxTS); + + _setup_timer(&pTxTS->TxPendingBARecord.Timer, + BaSetupTimeOut, + (unsigned long) pTxTS); + _setup_timer(&pTxTS->TxAdmittedBARecord.Timer, + TxBaInactTimeout, + (unsigned long) pTxTS); + + ResetTxTsEntry(pTxTS); + list_add_tail(&pTxTS->TsCommonInfo.List, + &ieee->Tx_TS_Unused_List); + pTxTS++; + } + + INIT_LIST_HEAD(&ieee->Rx_TS_Admit_List); + INIT_LIST_HEAD(&ieee->Rx_TS_Pending_List); + INIT_LIST_HEAD(&ieee->Rx_TS_Unused_List); + for (count = 0; count < TOTAL_TS_NUM; count++) { + pRxTS->num = count; + INIT_LIST_HEAD(&pRxTS->RxPendingPktList); + + _setup_timer(&pRxTS->TsCommonInfo.SetupTimer, + TsSetupTimeOut, + (unsigned long) pRxTS); + + _setup_timer(&pRxTS->TsCommonInfo.InactTimer, + TsInactTimeout, + (unsigned long) pRxTS); + + _setup_timer(&pRxTS->RxAdmittedBARecord.Timer, + RxBaInactTimeout, + (unsigned long) pRxTS); + + _setup_timer(&pRxTS->RxPktPendingTimer, + RxPktPendingTimeout, + (unsigned long) pRxTS); + + ResetRxTsEntry(pRxTS); + list_add_tail(&pRxTS->TsCommonInfo.List, + &ieee->Rx_TS_Unused_List); + pRxTS++; + } + INIT_LIST_HEAD(&ieee->RxReorder_Unused_List); + for (count = 0; count < REORDER_ENTRY_NUM; count++) { + list_add_tail(&pRxReorderEntry->List, + &ieee->RxReorder_Unused_List); + if (count == (REORDER_ENTRY_NUM-1)) + break; + pRxReorderEntry = &ieee->RxReorderEntry[count+1]; + } + +} + +static void AdmitTS(struct rtllib_device *ieee, + struct ts_common_info *pTsCommonInfo, u32 InactTime) +{ + del_timer_sync(&pTsCommonInfo->SetupTimer); + del_timer_sync(&pTsCommonInfo->InactTimer); + + if (InactTime != 0) + mod_timer(&pTsCommonInfo->InactTimer, jiffies + + MSECS(InactTime)); +} + +static struct ts_common_info *SearchAdmitTRStream(struct rtllib_device *ieee, + u8 *Addr, u8 TID, + enum tr_select TxRxSelect) +{ + u8 dir; + bool search_dir[4] = {0}; + struct list_head *psearch_list; + struct ts_common_info *pRet = NULL; + if (ieee->iw_mode == IW_MODE_MASTER) { + if (TxRxSelect == TX_DIR) { + search_dir[DIR_DOWN] = true; + search_dir[DIR_BI_DIR] = true; + } else { + search_dir[DIR_UP] = true; + search_dir[DIR_BI_DIR] = true; + } + } else if (ieee->iw_mode == IW_MODE_ADHOC) { + if (TxRxSelect == TX_DIR) + search_dir[DIR_UP] = true; + else + search_dir[DIR_DOWN] = true; + } else { + if (TxRxSelect == TX_DIR) { + search_dir[DIR_UP] = true; + search_dir[DIR_BI_DIR] = true; + search_dir[DIR_DIRECT] = true; + } else { + search_dir[DIR_DOWN] = true; + search_dir[DIR_BI_DIR] = true; + search_dir[DIR_DIRECT] = true; + } + } + + if (TxRxSelect == TX_DIR) + psearch_list = &ieee->Tx_TS_Admit_List; + else + psearch_list = &ieee->Rx_TS_Admit_List; + + for (dir = 0; dir <= DIR_BI_DIR; dir++) { + if (search_dir[dir] == false) + continue; + list_for_each_entry(pRet, psearch_list, List) { + if (memcmp(pRet->Addr, Addr, 6) == 0) + if (pRet->TSpec.f.TSInfo.field.ucTSID == TID) + if (pRet->TSpec.f.TSInfo.field.ucDirection == dir) + break; + + } + if (&pRet->List != psearch_list) + break; + } + + if (&pRet->List != psearch_list) + return pRet ; + else + return NULL; +} + +static void MakeTSEntry(struct ts_common_info *pTsCommonInfo, u8 *Addr, + union tspec_body *pTSPEC, union qos_tclas *pTCLAS, + u8 TCLAS_Num, u8 TCLAS_Proc) +{ + u8 count; + + if (pTsCommonInfo == NULL) + return; + + memcpy(pTsCommonInfo->Addr, Addr, 6); + + if (pTSPEC != NULL) + memcpy((u8 *)(&(pTsCommonInfo->TSpec)), (u8 *)pTSPEC, + sizeof(union tspec_body)); + + for (count = 0; count < TCLAS_Num; count++) + memcpy((u8 *)(&(pTsCommonInfo->TClass[count])), + (u8 *)pTCLAS, sizeof(union qos_tclas)); + + pTsCommonInfo->TClasProc = TCLAS_Proc; + pTsCommonInfo->TClasNum = TCLAS_Num; +} + +bool GetTs(struct rtllib_device *ieee, struct ts_common_info **ppTS, + u8 *Addr, u8 TID, enum tr_select TxRxSelect, bool bAddNewTs) +{ + u8 UP = 0; + if (is_broadcast_ether_addr(Addr) || is_multicast_ether_addr(Addr)) { + RTLLIB_DEBUG(RTLLIB_DL_ERR, "ERR! get TS for Broadcast or " + "Multicast\n"); + return false; + } + if (ieee->current_network.qos_data.supported == 0) { + UP = 0; + } else { + if (!IsACValid(TID)) { + RTLLIB_DEBUG(RTLLIB_DL_ERR, "ERR! in %s(), TID(%d) is " + "not valid\n", __func__, TID); + return false; + } + + switch (TID) { + case 0: + case 3: + UP = 0; + break; + case 1: + case 2: + UP = 2; + break; + case 4: + case 5: + UP = 5; + break; + case 6: + case 7: + UP = 7; + break; + } + } + + *ppTS = SearchAdmitTRStream(ieee, Addr, UP, TxRxSelect); + if (*ppTS != NULL) { + return true; + } else { + if (bAddNewTs == false) { + RTLLIB_DEBUG(RTLLIB_DL_TS, "add new TS failed" + "(tid:%d)\n", UP); + return false; + } else { + union tspec_body TSpec; + union qos_tsinfo *pTSInfo = &TSpec.f.TSInfo; + struct list_head *pUnusedList = + (TxRxSelect == TX_DIR) ? + (&ieee->Tx_TS_Unused_List) : + (&ieee->Rx_TS_Unused_List); + + struct list_head *pAddmitList = + (TxRxSelect == TX_DIR) ? + (&ieee->Tx_TS_Admit_List) : + (&ieee->Rx_TS_Admit_List); + + enum direction_value Dir = + (ieee->iw_mode == IW_MODE_MASTER) ? + ((TxRxSelect == TX_DIR) ? DIR_DOWN : DIR_UP) : + ((TxRxSelect == TX_DIR) ? DIR_UP : DIR_DOWN); + RTLLIB_DEBUG(RTLLIB_DL_TS, "to add Ts\n"); + if (!list_empty(pUnusedList)) { + (*ppTS) = list_entry(pUnusedList->next, + struct ts_common_info, List); + list_del_init(&(*ppTS)->List); + if (TxRxSelect == TX_DIR) { + struct tx_ts_record *tmp = + container_of(*ppTS, + struct tx_ts_record, + TsCommonInfo); + ResetTxTsEntry(tmp); + } else { + struct rx_ts_record *tmp = + container_of(*ppTS, + struct rx_ts_record, + TsCommonInfo); + ResetRxTsEntry(tmp); + } + + RTLLIB_DEBUG(RTLLIB_DL_TS, "to init current TS" + ", UP:%d, Dir:%d, addr: %pM" + " ppTs=%p\n", UP, Dir, + Addr, *ppTS); + pTSInfo->field.ucTrafficType = 0; + pTSInfo->field.ucTSID = UP; + pTSInfo->field.ucDirection = Dir; + pTSInfo->field.ucAccessPolicy = 1; + pTSInfo->field.ucAggregation = 0; + pTSInfo->field.ucPSB = 0; + pTSInfo->field.ucUP = UP; + pTSInfo->field.ucTSInfoAckPolicy = 0; + pTSInfo->field.ucSchedule = 0; + + MakeTSEntry(*ppTS, Addr, &TSpec, NULL, 0, 0); + AdmitTS(ieee, *ppTS, 0); + list_add_tail(&((*ppTS)->List), pAddmitList); + + return true; + } else { + RTLLIB_DEBUG(RTLLIB_DL_ERR, "ERR!!in function " + "%s() There is not enough dir=%d" + "(0=up down=1) TS record to be " + "used!!", __func__, Dir); + return false; + } + } + } +} + +static void RemoveTsEntry(struct rtllib_device *ieee, struct ts_common_info *pTs, + enum tr_select TxRxSelect) +{ + del_timer_sync(&pTs->SetupTimer); + del_timer_sync(&pTs->InactTimer); + TsInitDelBA(ieee, pTs, TxRxSelect); + + if (TxRxSelect == RX_DIR) { + struct rx_reorder_entry *pRxReorderEntry; + struct rx_ts_record *pRxTS = (struct rx_ts_record *)pTs; + + if (timer_pending(&pRxTS->RxPktPendingTimer)) + del_timer_sync(&pRxTS->RxPktPendingTimer); + + while (!list_empty(&pRxTS->RxPendingPktList)) { + pRxReorderEntry = (struct rx_reorder_entry *) + list_entry(pRxTS->RxPendingPktList.prev, + struct rx_reorder_entry, List); + RTLLIB_DEBUG(RTLLIB_DL_REORDER, "%s(): Delete SeqNum " + "%d!\n", __func__, + pRxReorderEntry->SeqNum); + list_del_init(&pRxReorderEntry->List); + { + int i = 0; + struct rtllib_rxb *prxb = pRxReorderEntry->prxb; + if (unlikely(!prxb)) + return; + for (i = 0; i < prxb->nr_subframes; i++) + dev_kfree_skb(prxb->subframes[i]); + kfree(prxb); + prxb = NULL; + } + list_add_tail(&pRxReorderEntry->List, + &ieee->RxReorder_Unused_List); + } + } else { + struct tx_ts_record *pTxTS = (struct tx_ts_record *)pTs; + del_timer_sync(&pTxTS->TsAddBaTimer); + } +} + +void RemovePeerTS(struct rtllib_device *ieee, u8 *Addr) +{ + struct ts_common_info *pTS, *pTmpTS; + printk(KERN_INFO "===========>RemovePeerTS, %pM\n", Addr); + + list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List) { + if (memcmp(pTS->Addr, Addr, 6) == 0) { + RemoveTsEntry(ieee, pTS, TX_DIR); + list_del_init(&pTS->List); + list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List); + } + } + + list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Admit_List, List) { + if (memcmp(pTS->Addr, Addr, 6) == 0) { + printk(KERN_INFO "====>remove Tx_TS_admin_list\n"); + RemoveTsEntry(ieee, pTS, TX_DIR); + list_del_init(&pTS->List); + list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List); + } + } + + list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Pending_List, List) { + if (memcmp(pTS->Addr, Addr, 6) == 0) { + RemoveTsEntry(ieee, pTS, RX_DIR); + list_del_init(&pTS->List); + list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List); + } + } + + list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Admit_List, List) { + if (memcmp(pTS->Addr, Addr, 6) == 0) { + RemoveTsEntry(ieee, pTS, RX_DIR); + list_del_init(&pTS->List); + list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List); + } + } +} + +void RemoveAllTS(struct rtllib_device *ieee) +{ + struct ts_common_info *pTS, *pTmpTS; + + list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Pending_List, List) { + RemoveTsEntry(ieee, pTS, TX_DIR); + list_del_init(&pTS->List); + list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List); + } + + list_for_each_entry_safe(pTS, pTmpTS, &ieee->Tx_TS_Admit_List, List) { + RemoveTsEntry(ieee, pTS, TX_DIR); + list_del_init(&pTS->List); + list_add_tail(&pTS->List, &ieee->Tx_TS_Unused_List); + } + + list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Pending_List, List) { + RemoveTsEntry(ieee, pTS, RX_DIR); + list_del_init(&pTS->List); + list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List); + } + + list_for_each_entry_safe(pTS, pTmpTS, &ieee->Rx_TS_Admit_List, List) { + RemoveTsEntry(ieee, pTS, RX_DIR); + list_del_init(&pTS->List); + list_add_tail(&pTS->List, &ieee->Rx_TS_Unused_List); + } +} + +void TsStartAddBaProcess(struct rtllib_device *ieee, struct tx_ts_record *pTxTS) +{ + if (pTxTS->bAddBaReqInProgress == false) { + pTxTS->bAddBaReqInProgress = true; + + if (pTxTS->bAddBaReqDelayed) { + RTLLIB_DEBUG(RTLLIB_DL_BA, "TsStartAddBaProcess(): " + "Delayed Start ADDBA after 60 sec!!\n"); + mod_timer(&pTxTS->TsAddBaTimer, jiffies + + MSECS(TS_ADDBA_DELAY)); + } else { + RTLLIB_DEBUG(RTLLIB_DL_BA, "TsStartAddBaProcess(): " + "Immediately Start ADDBA now!!\n"); + mod_timer(&pTxTS->TsAddBaTimer, jiffies+10); + } + } else + RTLLIB_DEBUG(RTLLIB_DL_BA, "%s()==>BA timer is already added\n", + __func__); +} diff --git a/drivers/staging/rtl8192e/rtl_cam.c b/drivers/staging/rtl8192e/rtl_cam.c new file mode 100644 index 0000000..baf3b63 --- /dev/null +++ b/drivers/staging/rtl8192e/rtl_cam.c @@ -0,0 +1,304 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * Based on the r8180 driver, which is: + * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al. + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> +******************************************************************************/ +#include "rtl_core.h" +#include "r8192E_phy.h" +#include "r8192E_phyreg.h" +#include "r8190P_rtl8256.h" /* RTL8225 Radio frontend */ +#include "r8192E_cmdpkt.h" + +extern int hwwep; +void CamResetAllEntry(struct net_device *dev) +{ + u32 ulcommand = 0; + + ulcommand |= BIT31|BIT30; + write_nic_dword(dev, RWCAM, ulcommand); +} + +void write_cam(struct net_device *dev, u8 addr, u32 data) +{ + write_nic_dword(dev, WCAMI, data); + write_nic_dword(dev, RWCAM, BIT31|BIT16|(addr&0xff)); +} + +u32 read_cam(struct net_device *dev, u8 addr) +{ + write_nic_dword(dev, RWCAM, 0x80000000|(addr&0xff)); + return read_nic_dword(dev, 0xa8); +} + +void EnableHWSecurityConfig8192(struct net_device *dev) +{ + u8 SECR_value = 0x0; + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + struct rtllib_device *ieee = priv->rtllib; + SECR_value = SCR_TxEncEnable | SCR_RxDecEnable; + if (((KEY_TYPE_WEP40 == ieee->pairwise_key_type) || + (KEY_TYPE_WEP104 == ieee->pairwise_key_type)) && + (priv->rtllib->auth_mode != 2)) { + SECR_value |= SCR_RxUseDK; + SECR_value |= SCR_TxUseDK; + } else if ((ieee->iw_mode == IW_MODE_ADHOC) && + (ieee->pairwise_key_type & (KEY_TYPE_CCMP | + KEY_TYPE_TKIP))) { + SECR_value |= SCR_RxUseDK; + SECR_value |= SCR_TxUseDK; + } + + + ieee->hwsec_active = 1; + if ((ieee->pHTInfo->IOTAction&HT_IOT_ACT_PURE_N_MODE) || !hwwep) { + ieee->hwsec_active = 0; + SECR_value &= ~SCR_RxDecEnable; + } + + RT_TRACE(COMP_SEC, "%s:, hwsec:%d, pairwise_key:%d, SECR_value:%x\n", + __func__, ieee->hwsec_active, ieee->pairwise_key_type, + SECR_value); + write_nic_byte(dev, SECR, SECR_value); +} + +void set_swcam(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType, + u8 *MacAddr, u8 DefaultKey, u32 *KeyContent, u8 is_mesh) +{ + struct r8192_priv *priv = rtllib_priv(dev); + struct rtllib_device *ieee = priv->rtllib; + RT_TRACE(COMP_DBG, "===========>%s():EntryNo is %d,KeyIndex is " + "%d,KeyType is %d,is_mesh is %d\n", __func__, EntryNo, + KeyIndex, KeyType, is_mesh); + if (!is_mesh) { + ieee->swcamtable[EntryNo].bused = true; + ieee->swcamtable[EntryNo].key_index = KeyIndex; + ieee->swcamtable[EntryNo].key_type = KeyType; + memcpy(ieee->swcamtable[EntryNo].macaddr, MacAddr, 6); + ieee->swcamtable[EntryNo].useDK = DefaultKey; + memcpy(ieee->swcamtable[EntryNo].key_buf, (u8 *)KeyContent, 16); + } +} + +void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType, + u8 *MacAddr, u8 DefaultKey, u32 *KeyContent) +{ + u32 TargetCommand = 0; + u32 TargetContent = 0; + u16 usConfig = 0; + u8 i; + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + enum rt_rf_power_state rtState; + rtState = priv->rtllib->eRFPowerState; + if (priv->rtllib->PowerSaveControl.bInactivePs) { + if (rtState == eRfOff) { + if (priv->rtllib->RfOffReason > RF_CHANGE_BY_IPS) { + RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n", + __func__); + return ; + } else { + down(&priv->rtllib->ips_sem); + IPSLeave(dev); + up(&priv->rtllib->ips_sem); + } + } + } + priv->rtllib->is_set_key = true; + if (EntryNo >= TOTAL_CAM_ENTRY) + RT_TRACE(COMP_ERR, "cam entry exceeds in setKey()\n"); + + RT_TRACE(COMP_SEC, "====>to setKey(), dev:%p, EntryNo:%d, KeyIndex:%d," + "KeyType:%d, MacAddr %pM\n", dev, EntryNo, KeyIndex, + KeyType, MacAddr); + + if (DefaultKey) + usConfig |= BIT15 | (KeyType<<2); + else + usConfig |= BIT15 | (KeyType<<2) | KeyIndex; + + + for (i = 0; i < CAM_CONTENT_COUNT; i++) { + TargetCommand = i + CAM_CONTENT_COUNT * EntryNo; + TargetCommand |= BIT31|BIT16; + + if (i == 0) { + TargetContent = (u32)(*(MacAddr+0)) << 16 | + (u32)(*(MacAddr+1)) << 24 | + (u32)usConfig; + + write_nic_dword(dev, WCAMI, TargetContent); + write_nic_dword(dev, RWCAM, TargetCommand); + } else if (i == 1) { + TargetContent = (u32)(*(MacAddr+2)) | + (u32)(*(MacAddr+3)) << 8 | + (u32)(*(MacAddr+4)) << 16 | + (u32)(*(MacAddr+5)) << 24; + write_nic_dword(dev, WCAMI, TargetContent); + write_nic_dword(dev, RWCAM, TargetCommand); + } else { + if (KeyContent != NULL) { + write_nic_dword(dev, WCAMI, + (u32)(*(KeyContent+i-2))); + write_nic_dword(dev, RWCAM, TargetCommand); + udelay(100); + } + } + } + RT_TRACE(COMP_SEC, "=========>after set key, usconfig:%x\n", usConfig); +} + +void CAM_read_entry(struct net_device *dev, u32 iIndex) +{ + u32 target_command = 0; + u32 target_content = 0; + u8 entry_i = 0; + u32 ulStatus; + s32 i = 100; + for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) { + target_command = entry_i+CAM_CONTENT_COUNT*iIndex; + target_command = target_command | BIT31; + + while ((i--) >= 0) { + ulStatus = read_nic_dword(dev, RWCAM); + if (ulStatus & BIT31) + continue; + else + break; + } + write_nic_dword(dev, RWCAM, target_command); + RT_TRACE(COMP_SEC, "CAM_read_entry(): WRITE A0: %x\n", + target_command); + target_content = read_nic_dword(dev, RCAMO); + RT_TRACE(COMP_SEC, "CAM_read_entry(): WRITE A8: %x\n", + target_content); + } + printk(KERN_INFO "\n"); +} + +void CamRestoreAllEntry(struct net_device *dev) +{ + u8 EntryId = 0; + struct r8192_priv *priv = rtllib_priv(dev); + u8 *MacAddr = priv->rtllib->current_network.bssid; + + static u8 CAM_CONST_ADDR[4][6] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} + }; + static u8 CAM_CONST_BROAD[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + }; + + RT_TRACE(COMP_SEC, "CamRestoreAllEntry:\n"); + + + if ((priv->rtllib->pairwise_key_type == KEY_TYPE_WEP40) || + (priv->rtllib->pairwise_key_type == KEY_TYPE_WEP104)) { + + for (EntryId = 0; EntryId < 4; EntryId++) { + MacAddr = CAM_CONST_ADDR[EntryId]; + if (priv->rtllib->swcamtable[EntryId].bused) { + setKey(dev, EntryId , EntryId, + priv->rtllib->pairwise_key_type, MacAddr, + 0, (u32 *)(&priv->rtllib->swcamtable + [EntryId].key_buf[0])); + } + } + + } else if (priv->rtllib->pairwise_key_type == KEY_TYPE_TKIP) { + if (priv->rtllib->iw_mode == IW_MODE_ADHOC) { + setKey(dev, 4, 0, priv->rtllib->pairwise_key_type, + (u8 *)dev->dev_addr, 0, + (u32 *)(&priv->rtllib->swcamtable[4].key_buf[0])); + } else { + setKey(dev, 4, 0, priv->rtllib->pairwise_key_type, + MacAddr, 0, + (u32 *)(&priv->rtllib->swcamtable[4].key_buf[0])); + } + + } else if (priv->rtllib->pairwise_key_type == KEY_TYPE_CCMP) { + if (priv->rtllib->iw_mode == IW_MODE_ADHOC) { + setKey(dev, 4, 0, + priv->rtllib->pairwise_key_type, + (u8 *)dev->dev_addr, 0, + (u32 *)(&priv->rtllib->swcamtable[4]. + key_buf[0])); + } else { + setKey(dev, 4, 0, + priv->rtllib->pairwise_key_type, MacAddr, + 0, (u32 *)(&priv->rtllib->swcamtable[4]. + key_buf[0])); + } + } + + if (priv->rtllib->group_key_type == KEY_TYPE_TKIP) { + MacAddr = CAM_CONST_BROAD; + for (EntryId = 1; EntryId < 4; EntryId++) { + if (priv->rtllib->swcamtable[EntryId].bused) { + setKey(dev, EntryId, EntryId, + priv->rtllib->group_key_type, + MacAddr, 0, + (u32 *)(&priv->rtllib->swcamtable[EntryId].key_buf[0]) + ); + } + } + if (priv->rtllib->iw_mode == IW_MODE_ADHOC) { + if (priv->rtllib->swcamtable[0].bused) { + setKey(dev, 0, 0, + priv->rtllib->group_key_type, + CAM_CONST_ADDR[0], 0, + (u32 *)(&priv->rtllib->swcamtable[0].key_buf[0]) + ); + } else { + RT_TRACE(COMP_ERR, "===>%s():ERR!! ADHOC TKIP " + ",but 0 entry is have no data\n", + __func__); + return; + } + } + } else if (priv->rtllib->group_key_type == KEY_TYPE_CCMP) { + MacAddr = CAM_CONST_BROAD; + for (EntryId = 1; EntryId < 4; EntryId++) { + if (priv->rtllib->swcamtable[EntryId].bused) { + setKey(dev, EntryId , EntryId, + priv->rtllib->group_key_type, + MacAddr, 0, + (u32 *)(&priv->rtllib->swcamtable[EntryId].key_buf[0])); + } + } + + if (priv->rtllib->iw_mode == IW_MODE_ADHOC) { + if (priv->rtllib->swcamtable[0].bused) { + setKey(dev, 0 , 0, + priv->rtllib->group_key_type, + CAM_CONST_ADDR[0], 0, + (u32 *)(&priv->rtllib->swcamtable[0].key_buf[0])); + } else { + RT_TRACE(COMP_ERR, "===>%s():ERR!! ADHOC CCMP ," + "but 0 entry is have no data\n", + __func__); + return; + } + } + } +} diff --git a/drivers/staging/rtl8192e/rtl_cam.h b/drivers/staging/rtl8192e/rtl_cam.h new file mode 100644 index 0000000..fa607f9 --- /dev/null +++ b/drivers/staging/rtl8192e/rtl_cam.h @@ -0,0 +1,46 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * Based on the r8180 driver, which is: + * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al. + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> +******************************************************************************/ +#ifndef _RTL_CAM_H +#define _RTL_CAM_H + +#include <linux/types.h> +struct net_device; + +void CamResetAllEntry(struct net_device *dev); +void EnableHWSecurityConfig8192(struct net_device *dev); +void setKey(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType, + u8 *MacAddr, u8 DefaultKey, u32 *KeyContent); +void set_swcam(struct net_device *dev, u8 EntryNo, u8 KeyIndex, u16 KeyType, + u8 *MacAddr, u8 DefaultKey, u32 *KeyContent, u8 is_mesh); +void CamPrintDbgReg(struct net_device *dev); + +u32 read_cam(struct net_device *dev, u8 addr); +void write_cam(struct net_device *dev, u8 addr, u32 data); + +void CamRestoreAllEntry(struct net_device *dev); + +void CAM_read_entry(struct net_device *dev, u32 iIndex); + +#endif diff --git a/drivers/staging/rtl8192e/rtl_core.c b/drivers/staging/rtl8192e/rtl_core.c new file mode 100644 index 0000000..6530058 --- /dev/null +++ b/drivers/staging/rtl8192e/rtl_core.c @@ -0,0 +1,3230 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * Based on the r8180 driver, which is: + * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al. + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> +******************************************************************************/ +#undef RX_DONT_PASS_UL +#undef DEBUG_EPROM +#undef DEBUG_RX_VERBOSE +#undef DUMMY_RX +#undef DEBUG_ZERO_RX +#undef DEBUG_RX_SKB +#undef DEBUG_TX_FRAG +#undef DEBUG_RX_FRAG +#undef DEBUG_TX_FILLDESC +#undef DEBUG_TX +#undef DEBUG_IRQ +#undef DEBUG_RX +#undef DEBUG_RXALLOC +#undef DEBUG_REGISTERS +#undef DEBUG_RING +#undef DEBUG_IRQ_TASKLET +#undef DEBUG_TX_ALLOC +#undef DEBUG_TX_DESC + +#include <linux/uaccess.h> +#include <linux/pci.h> +#include <linux/vmalloc.h> +#include "rtl_core.h" +#include "r8192E_phy.h" +#include "r8192E_phyreg.h" +#include "r8190P_rtl8256.h" +#include "r8192E_cmdpkt.h" + +#include "rtl_wx.h" +#include "rtl_dm.h" + +#ifdef CONFIG_PM_RTL +#include "rtl_pm.h" +#endif + +int hwwep = 1; +static int channels = 0x3fff; +static char *ifname = "wlan%d"; + + +static struct rtl819x_ops rtl819xp_ops = { + .nic_type = NIC_8192E, + .get_eeprom_size = rtl8192_get_eeprom_size, + .init_adapter_variable = rtl8192_InitializeVariables, + .initialize_adapter = rtl8192_adapter_start, + .link_change = rtl8192_link_change, + .tx_fill_descriptor = rtl8192_tx_fill_desc, + .tx_fill_cmd_descriptor = rtl8192_tx_fill_cmd_desc, + .rx_query_status_descriptor = rtl8192_rx_query_status_desc, + .rx_command_packet_handler = NULL, + .stop_adapter = rtl8192_halt_adapter, + .update_ratr_table = rtl8192_update_ratr_table, + .irq_enable = rtl8192_EnableInterrupt, + .irq_disable = rtl8192_DisableInterrupt, + .irq_clear = rtl8192_ClearInterrupt, + .rx_enable = rtl8192_enable_rx, + .tx_enable = rtl8192_enable_tx, + .interrupt_recognized = rtl8192_interrupt_recognized, + .TxCheckStuckHandler = rtl8192_HalTxCheckStuck, + .RxCheckStuckHandler = rtl8192_HalRxCheckStuck, +}; + +static struct pci_device_id rtl8192_pci_id_tbl[] __devinitdata = { + {RTL_PCI_DEVICE(0x10ec, 0x8192, rtl819xp_ops)}, + {RTL_PCI_DEVICE(0x07aa, 0x0044, rtl819xp_ops)}, + {RTL_PCI_DEVICE(0x07aa, 0x0047, rtl819xp_ops)}, + {} +}; + +MODULE_DEVICE_TABLE(pci, rtl8192_pci_id_tbl); + +static int __devinit rtl8192_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *id); +static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev); + +static struct pci_driver rtl8192_pci_driver = { + .name = DRV_NAME, /* Driver name */ + .id_table = rtl8192_pci_id_tbl, /* PCI_ID table */ + .probe = rtl8192_pci_probe, /* probe fn */ + .remove = __devexit_p(rtl8192_pci_disconnect), /* remove fn */ + .suspend = rtl8192E_suspend, /* PM suspend fn */ + .resume = rtl8192E_resume, /* PM resume fn */ +}; + +/**************************************************************************** + -----------------------------IO STUFF------------------------- +*****************************************************************************/ +static bool PlatformIOCheckPageLegalAndGetRegMask(u32 u4bPage, u8 *pu1bPageMask) +{ + bool bReturn = false; + + *pu1bPageMask = 0xfe; + + switch (u4bPage) { + case 1: case 2: case 3: case 4: + case 8: case 9: case 10: case 12: case 13: + bReturn = true; + *pu1bPageMask = 0xf0; + break; + + default: + bReturn = false; + break; + } + + return bReturn; +} + +void write_nic_io_byte(struct net_device *dev, int x, u8 y) +{ + u32 u4bPage = (x >> 8); + u8 u1PageMask = 0; + bool bIsLegalPage = false; + + if (u4bPage == 0) { + outb(y&0xff, dev->base_addr + x); + + } else { + bIsLegalPage = PlatformIOCheckPageLegalAndGetRegMask(u4bPage, + &u1PageMask); + if (bIsLegalPage) { + u8 u1bPsr = read_nic_io_byte(dev, PSR); + + write_nic_io_byte(dev, PSR, ((u1bPsr & u1PageMask) | + (u8)u4bPage)); + write_nic_io_byte(dev, (x & 0xff), y); + write_nic_io_byte(dev, PSR, (u1bPsr & u1PageMask)); + } + } +} + +void write_nic_io_word(struct net_device *dev, int x, u16 y) +{ + u32 u4bPage = (x >> 8); + u8 u1PageMask = 0; + bool bIsLegalPage = false; + + if (u4bPage == 0) { + outw(y, dev->base_addr + x); + } else { + bIsLegalPage = PlatformIOCheckPageLegalAndGetRegMask(u4bPage, + &u1PageMask); + if (bIsLegalPage) { + u8 u1bPsr = read_nic_io_byte(dev, PSR); + + write_nic_io_byte(dev, PSR, ((u1bPsr & u1PageMask) | + (u8)u4bPage)); + write_nic_io_word(dev, (x & 0xff), y); + write_nic_io_byte(dev, PSR, (u1bPsr & u1PageMask)); + + } + } +} + +void write_nic_io_dword(struct net_device *dev, int x, u32 y) +{ + u32 u4bPage = (x >> 8); + u8 u1PageMask = 0; + bool bIsLegalPage = false; + + if (u4bPage == 0) { + outl(y, dev->base_addr + x); + } else { + bIsLegalPage = PlatformIOCheckPageLegalAndGetRegMask(u4bPage, + &u1PageMask); + if (bIsLegalPage) { + u8 u1bPsr = read_nic_io_byte(dev, PSR); + + write_nic_io_byte(dev, PSR, ((u1bPsr & u1PageMask) | + (u8)u4bPage)); + write_nic_io_dword(dev, (x & 0xff), y); + write_nic_io_byte(dev, PSR, (u1bPsr & u1PageMask)); + } + } +} + +u8 read_nic_io_byte(struct net_device *dev, int x) +{ + u32 u4bPage = (x >> 8); + u8 u1PageMask = 0; + bool bIsLegalPage = false; + u8 Data = 0; + + if (u4bPage == 0) { + return 0xff&inb(dev->base_addr + x); + } else { + bIsLegalPage = PlatformIOCheckPageLegalAndGetRegMask(u4bPage, + &u1PageMask); + if (bIsLegalPage) { + u8 u1bPsr = read_nic_io_byte(dev, PSR); + + write_nic_io_byte(dev, PSR, ((u1bPsr & u1PageMask) | + (u8)u4bPage)); + Data = read_nic_io_byte(dev, (x & 0xff)); + write_nic_io_byte(dev, PSR, (u1bPsr & u1PageMask)); + } + } + + return Data; +} + +u16 read_nic_io_word(struct net_device *dev, int x) +{ + u32 u4bPage = (x >> 8); + u8 u1PageMask = 0; + bool bIsLegalPage = false; + u16 Data = 0; + + if (u4bPage == 0) { + return inw(dev->base_addr + x); + } else { + bIsLegalPage = PlatformIOCheckPageLegalAndGetRegMask(u4bPage, + &u1PageMask); + if (bIsLegalPage) { + u8 u1bPsr = read_nic_io_byte(dev, PSR); + + write_nic_io_byte(dev, PSR, ((u1bPsr & u1PageMask) | + (u8)u4bPage)); + Data = read_nic_io_word(dev, (x & 0xff)); + write_nic_io_byte(dev, PSR, (u1bPsr & u1PageMask)); + + } + } + + return Data; +} + +u32 read_nic_io_dword(struct net_device *dev, int x) +{ + u32 u4bPage = (x >> 8); + u8 u1PageMask = 0; + bool bIsLegalPage = false; + u32 Data = 0; + + if (u4bPage == 0) { + return inl(dev->base_addr + x); + } else { + bIsLegalPage = PlatformIOCheckPageLegalAndGetRegMask(u4bPage, + &u1PageMask); + if (bIsLegalPage) { + u8 u1bPsr = read_nic_io_byte(dev, PSR); + + write_nic_io_byte(dev, PSR, ((u1bPsr & u1PageMask) | + (u8)u4bPage)); + Data = read_nic_io_dword(dev, (x & 0xff)); + write_nic_io_byte(dev, PSR, (u1bPsr & u1PageMask)); + + } + } + + return Data; +} + +u8 read_nic_byte(struct net_device *dev, int x) +{ + return 0xff & readb((u8 __iomem *)dev->mem_start + x); +} + +u32 read_nic_dword(struct net_device *dev, int x) +{ + return readl((u8 __iomem *)dev->mem_start + x); +} + +u16 read_nic_word(struct net_device *dev, int x) +{ + return readw((u8 __iomem *)dev->mem_start + x); +} + +void write_nic_byte(struct net_device *dev, int x, u8 y) +{ + writeb(y, (u8 __iomem *)dev->mem_start + x); + + udelay(20); +} + +void write_nic_dword(struct net_device *dev, int x, u32 y) +{ + writel(y, (u8 __iomem *)dev->mem_start + x); + + udelay(20); +} + +void write_nic_word(struct net_device *dev, int x, u16 y) +{ + writew(y, (u8 __iomem *)dev->mem_start + x); + + udelay(20); +} + +/**************************************************************************** + -----------------------------GENERAL FUNCTION------------------------- +*****************************************************************************/ +bool MgntActSet_RF_State(struct net_device *dev, + enum rt_rf_power_state StateToSet, + RT_RF_CHANGE_SOURCE ChangeSource, + bool ProtectOrNot) +{ + struct r8192_priv *priv = rtllib_priv(dev); + struct rtllib_device *ieee = priv->rtllib; + bool bActionAllowed = false; + bool bConnectBySSID = false; + enum rt_rf_power_state rtState; + u16 RFWaitCounter = 0; + unsigned long flag; + RT_TRACE((COMP_PS | COMP_RF), "===>MgntActSet_RF_State(): " + "StateToSet(%d)\n", StateToSet); + + ProtectOrNot = false; + + + if (!ProtectOrNot) { + while (true) { + spin_lock_irqsave(&priv->rf_ps_lock, flag); + if (priv->RFChangeInProgress) { + spin_unlock_irqrestore(&priv->rf_ps_lock, flag); + RT_TRACE((COMP_PS | COMP_RF), + "MgntActSet_RF_State(): RF Change in " + "progress! Wait to set..StateToSet" + "(%d).\n", StateToSet); + + while (priv->RFChangeInProgress) { + RFWaitCounter++; + RT_TRACE((COMP_PS | COMP_RF), + "MgntActSet_RF_State(): Wait 1" + " ms (%d times)...\n", + RFWaitCounter); + mdelay(1); + + if (RFWaitCounter > 100) { + RT_TRACE(COMP_ERR, "MgntActSet_" + "RF_State(): Wait too " + "logn to set RF\n"); + return false; + } + } + } else { + priv->RFChangeInProgress = true; + spin_unlock_irqrestore(&priv->rf_ps_lock, flag); + break; + } + } + } + + rtState = priv->rtllib->eRFPowerState; + + switch (StateToSet) { + case eRfOn: + priv->rtllib->RfOffReason &= (~ChangeSource); + + if ((ChangeSource == RF_CHANGE_BY_HW) && + (priv->bHwRadioOff == true)) + priv->bHwRadioOff = false; + + if (!priv->rtllib->RfOffReason) { + priv->rtllib->RfOffReason = 0; + bActionAllowed = true; + + + if (rtState == eRfOff && + ChangeSource >= RF_CHANGE_BY_HW) + bConnectBySSID = true; + } else { + RT_TRACE((COMP_PS | COMP_RF), "MgntActSet_RF_State - " + "eRfon reject pMgntInfo->RfOffReason= 0x%x," + " ChangeSource=0x%X\n", + priv->rtllib->RfOffReason, ChangeSource); + } + + break; + + case eRfOff: + + if ((priv->rtllib->iw_mode == IW_MODE_INFRA) || + (priv->rtllib->iw_mode == IW_MODE_ADHOC)) { + if ((priv->rtllib->RfOffReason > RF_CHANGE_BY_IPS) || + (ChangeSource > RF_CHANGE_BY_IPS)) { + if (ieee->state == RTLLIB_LINKED) + priv->blinked_ingpio = true; + else + priv->blinked_ingpio = false; + rtllib_MgntDisconnect(priv->rtllib, + disas_lv_ss); + } + } + if ((ChangeSource == RF_CHANGE_BY_HW) && + (priv->bHwRadioOff == false)) + priv->bHwRadioOff = true; + priv->rtllib->RfOffReason |= ChangeSource; + bActionAllowed = true; + break; + + case eRfSleep: + priv->rtllib->RfOffReason |= ChangeSource; + bActionAllowed = true; + break; + + default: + break; + } + + if (bActionAllowed) { + RT_TRACE((COMP_PS | COMP_RF), "MgntActSet_RF_State(): Action is" + " allowed.... StateToSet(%d), RfOffReason(%#X)\n", + StateToSet, priv->rtllib->RfOffReason); + PHY_SetRFPowerState(dev, StateToSet); + if (StateToSet == eRfOn) { + + if (bConnectBySSID && (priv->blinked_ingpio == true)) { + queue_delayed_work_rsl(ieee->wq, + &ieee->associate_procedure_wq, 0); + priv->blinked_ingpio = false; + } + } + } else { + RT_TRACE((COMP_PS | COMP_RF), "MgntActSet_RF_State(): " + "Action is rejected.... StateToSet(%d), ChangeSource" + "(%#X), RfOffReason(%#X)\n", StateToSet, ChangeSource, + priv->rtllib->RfOffReason); + } + + if (!ProtectOrNot) { + spin_lock_irqsave(&priv->rf_ps_lock, flag); + priv->RFChangeInProgress = false; + spin_unlock_irqrestore(&priv->rf_ps_lock, flag); + } + + RT_TRACE((COMP_PS && COMP_RF), "<===MgntActSet_RF_State()\n"); + return bActionAllowed; +} + + +static short rtl8192_get_nic_desc_num(struct net_device *dev, int prio) +{ + struct r8192_priv *priv = rtllib_priv(dev); + struct rtl8192_tx_ring *ring = &priv->tx_ring[prio]; + + /* For now, we reserved two free descriptor as a safety boundary + * between the tail and the head + */ + if ((prio == MGNT_QUEUE) && (skb_queue_len(&ring->queue) > 10)) + RT_TRACE(COMP_DBG, "-----[%d]---------ring->idx=%d " + "queue_len=%d---------\n", prio, ring->idx, + skb_queue_len(&ring->queue)); + return skb_queue_len(&ring->queue); +} + +static short rtl8192_check_nic_enough_desc(struct net_device *dev, int prio) +{ + struct r8192_priv *priv = rtllib_priv(dev); + struct rtl8192_tx_ring *ring = &priv->tx_ring[prio]; + + if (ring->entries - skb_queue_len(&ring->queue) >= 2) + return 1; + return 0; +} + +void rtl8192_tx_timeout(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + schedule_work(&priv->reset_wq); + printk(KERN_INFO "TXTIMEOUT"); +} + +void rtl8192_irq_enable(struct net_device *dev) +{ + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + priv->irq_enabled = 1; + + priv->ops->irq_enable(dev); +} + +void rtl8192_irq_disable(struct net_device *dev) +{ + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + + priv->ops->irq_disable(dev); + + priv->irq_enabled = 0; +} + +void rtl8192_set_chan(struct net_device *dev, short ch) +{ + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + + RT_TRACE(COMP_CH, "=====>%s()====ch:%d\n", __func__, ch); + if (priv->chan_forced) + return; + + priv->chan = ch; + + if (priv->rf_set_chan) + priv->rf_set_chan(dev, priv->chan); +} + +void rtl8192_update_cap(struct net_device *dev, u16 cap) +{ + struct r8192_priv *priv = rtllib_priv(dev); + struct rtllib_network *net = &priv->rtllib->current_network; + bool ShortPreamble; + + if (cap & WLAN_CAPABILITY_SHORT_PREAMBLE) { + if (priv->dot11CurrentPreambleMode != PREAMBLE_SHORT) { + ShortPreamble = true; + priv->dot11CurrentPreambleMode = PREAMBLE_SHORT; + RT_TRACE(COMP_DBG, "%s(): WLAN_CAPABILITY_SHORT_" + "PREAMBLE\n", __func__); + priv->rtllib->SetHwRegHandler(dev, HW_VAR_ACK_PREAMBLE, + (unsigned char *)&ShortPreamble); + } + } else { + if (priv->dot11CurrentPreambleMode != PREAMBLE_LONG) { + ShortPreamble = false; + priv->dot11CurrentPreambleMode = PREAMBLE_LONG; + RT_TRACE(COMP_DBG, "%s(): WLAN_CAPABILITY_LONG_" + "PREAMBLE\n", __func__); + priv->rtllib->SetHwRegHandler(dev, HW_VAR_ACK_PREAMBLE, + (unsigned char *)&ShortPreamble); + } + } + + if (net->mode & (IEEE_G|IEEE_N_24G)) { + u8 slot_time_val; + u8 CurSlotTime = priv->slot_time; + + if ((cap & WLAN_CAPABILITY_SHORT_SLOT_TIME) && + (!priv->rtllib->pHTInfo->bCurrentRT2RTLongSlotTime)) { + if (CurSlotTime != SHORT_SLOT_TIME) { + slot_time_val = SHORT_SLOT_TIME; + priv->rtllib->SetHwRegHandler(dev, + HW_VAR_SLOT_TIME, &slot_time_val); + } + } else { + if (CurSlotTime != NON_SHORT_SLOT_TIME) { + slot_time_val = NON_SHORT_SLOT_TIME; + priv->rtllib->SetHwRegHandler(dev, + HW_VAR_SLOT_TIME, &slot_time_val); + } + } + } +} + +static struct rtllib_qos_parameters def_qos_parameters = { + {3, 3, 3, 3}, + {7, 7, 7, 7}, + {2, 2, 2, 2}, + {0, 0, 0, 0}, + {0, 0, 0, 0} +}; + +static void rtl8192_update_beacon(void *data) +{ + struct r8192_priv *priv = container_of_work_rsl(data, struct r8192_priv, + update_beacon_wq.work); + struct net_device *dev = priv->rtllib->dev; + struct rtllib_device *ieee = priv->rtllib; + struct rtllib_network *net = &ieee->current_network; + + if (ieee->pHTInfo->bCurrentHTSupport) + HTUpdateSelfAndPeerSetting(ieee, net); + ieee->pHTInfo->bCurrentRT2RTLongSlotTime = + net->bssht.bdRT2RTLongSlotTime; + ieee->pHTInfo->RT2RT_HT_Mode = net->bssht.RT2RT_HT_Mode; + rtl8192_update_cap(dev, net->capability); +} + +#define MOVE_INTO_HANDLER +int WDCAPARA_ADD[] = {EDCAPARA_BE, EDCAPARA_BK, EDCAPARA_VI, EDCAPARA_VO}; + +static void rtl8192_qos_activate(void *data) +{ + struct r8192_priv *priv = container_of_work_rsl(data, struct r8192_priv, + qos_activate); + struct net_device *dev = priv->rtllib->dev; +#ifndef MOVE_INTO_HANDLER + struct rtllib_qos_parameters *qos_parameters = + &priv->rtllib->current_network.qos_data.parameters; + u8 mode = priv->rtllib->current_network.mode; + u8 u1bAIFS; + u32 u4bAcParam; +#endif + int i; + + if (priv == NULL) + return; + + mutex_lock(&priv->mutex); + if (priv->rtllib->state != RTLLIB_LINKED) + goto success; + RT_TRACE(COMP_QOS, "qos active process with associate response " + "received\n"); + + for (i = 0; i < QOS_QUEUE_NUM; i++) { +#ifndef MOVE_INTO_HANDLER + u1bAIFS = qos_parameters->aifs[i] * + ((mode&(IEEE_G|IEEE_N_24G)) ? 9 : 20) + aSifsTime; + u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[i])) << + AC_PARAM_TXOP_LIMIT_OFFSET) | + (((u32)(qos_parameters->cw_max[i])) << + AC_PARAM_ECW_MAX_OFFSET) | + (((u32)(qos_parameters->cw_min[i])) << + AC_PARAM_ECW_MIN_OFFSET) | + ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET)); + RT_TRACE(COMP_DBG, "===>ACI:%d:u4bAcParam:%x\n", i, u4bAcParam); + write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam); +#else + priv->rtllib->SetHwRegHandler(dev, HW_VAR_AC_PARAM, (u8 *)(&i)); +#endif + } + +success: + mutex_unlock(&priv->mutex); +} + +static int rtl8192_qos_handle_probe_response(struct r8192_priv *priv, + int active_network, + struct rtllib_network *network) +{ + int ret = 0; + u32 size = sizeof(struct rtllib_qos_parameters); + + if (priv->rtllib->state != RTLLIB_LINKED) + return ret; + + if ((priv->rtllib->iw_mode != IW_MODE_INFRA)) + return ret; + + if (network->flags & NETWORK_HAS_QOS_MASK) { + if (active_network && + (network->flags & NETWORK_HAS_QOS_PARAMETERS)) + network->qos_data.active = network->qos_data.supported; + + if ((network->qos_data.active == 1) && (active_network == 1) && + (network->flags & NETWORK_HAS_QOS_PARAMETERS) && + (network->qos_data.old_param_count != + network->qos_data.param_count)) { + network->qos_data.old_param_count = + network->qos_data.param_count; + priv->rtllib->wmm_acm = network->qos_data.wmm_acm; + queue_work_rsl(priv->priv_wq, &priv->qos_activate); + RT_TRACE(COMP_QOS, "QoS parameters change call " + "qos_activate\n"); + } + } else { + memcpy(&priv->rtllib->current_network.qos_data.parameters, + &def_qos_parameters, size); + + if ((network->qos_data.active == 1) && (active_network == 1)) { + queue_work_rsl(priv->priv_wq, &priv->qos_activate); + RT_TRACE(COMP_QOS, "QoS was disabled call qos_" + "activate\n"); + } + network->qos_data.active = 0; + network->qos_data.supported = 0; + } + + return 0; +} + +static int rtl8192_handle_beacon(struct net_device *dev, + struct rtllib_beacon *beacon, + struct rtllib_network *network) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + rtl8192_qos_handle_probe_response(priv, 1, network); + + queue_delayed_work_rsl(priv->priv_wq, &priv->update_beacon_wq, 0); + return 0; + +} + +static int rtl8192_qos_association_resp(struct r8192_priv *priv, + struct rtllib_network *network) +{ + int ret = 0; + unsigned long flags; + u32 size = sizeof(struct rtllib_qos_parameters); + int set_qos_param = 0; + + if ((priv == NULL) || (network == NULL)) + return ret; + + if (priv->rtllib->state != RTLLIB_LINKED) + return ret; + + if ((priv->rtllib->iw_mode != IW_MODE_INFRA)) + return ret; + + spin_lock_irqsave(&priv->rtllib->lock, flags); + if (network->flags & NETWORK_HAS_QOS_PARAMETERS) { + memcpy(&priv->rtllib->current_network.qos_data.parameters, + &network->qos_data.parameters, + sizeof(struct rtllib_qos_parameters)); + priv->rtllib->current_network.qos_data.active = 1; + priv->rtllib->wmm_acm = network->qos_data.wmm_acm; + set_qos_param = 1; + priv->rtllib->current_network.qos_data.old_param_count = + priv->rtllib->current_network.qos_data.param_count; + priv->rtllib->current_network.qos_data.param_count = + network->qos_data.param_count; + } else { + memcpy(&priv->rtllib->current_network.qos_data.parameters, + &def_qos_parameters, size); + priv->rtllib->current_network.qos_data.active = 0; + priv->rtllib->current_network.qos_data.supported = 0; + set_qos_param = 1; + } + + spin_unlock_irqrestore(&priv->rtllib->lock, flags); + + RT_TRACE(COMP_QOS, "%s: network->flags = %d,%d\n", __func__, + network->flags, priv->rtllib->current_network.qos_data.active); + if (set_qos_param == 1) { + dm_init_edca_turbo(priv->rtllib->dev); + queue_work_rsl(priv->priv_wq, &priv->qos_activate); + } + return ret; +} + +static int rtl8192_handle_assoc_response(struct net_device *dev, + struct rtllib_assoc_response_frame *resp, + struct rtllib_network *network) +{ + struct r8192_priv *priv = rtllib_priv(dev); + rtl8192_qos_association_resp(priv, network); + return 0; +} + +static void rtl8192_prepare_beacon(struct r8192_priv *priv) +{ + struct net_device *dev = priv->rtllib->dev; + struct sk_buff *pskb = NULL, *pnewskb = NULL; + struct cb_desc *tcb_desc = NULL; + struct rtl8192_tx_ring *ring = NULL; + struct tx_desc *pdesc = NULL; + + ring = &priv->tx_ring[BEACON_QUEUE]; + pskb = __skb_dequeue(&ring->queue); + if (pskb) + kfree_skb(pskb); + + pnewskb = rtllib_get_beacon(priv->rtllib); + if (!pnewskb) + return; + + tcb_desc = (struct cb_desc *)(pnewskb->cb + 8); + tcb_desc->queue_index = BEACON_QUEUE; + tcb_desc->data_rate = 2; + tcb_desc->RATRIndex = 7; + tcb_desc->bTxDisableRateFallBack = 1; + tcb_desc->bTxUseDriverAssingedRate = 1; + skb_push(pnewskb, priv->rtllib->tx_headroom); + + pdesc = &ring->desc[0]; + priv->ops->tx_fill_descriptor(dev, pdesc, tcb_desc, pnewskb); + __skb_queue_tail(&ring->queue, pnewskb); + pdesc->OWN = 1; + + return; +} + +static void rtl8192_stop_beacon(struct net_device *dev) +{ +} + +void rtl8192_config_rate(struct net_device *dev, u16 *rate_config) +{ + struct r8192_priv *priv = rtllib_priv(dev); + struct rtllib_network *net; + u8 i = 0, basic_rate = 0; + net = &priv->rtllib->current_network; + + for (i = 0; i < net->rates_len; i++) { + basic_rate = net->rates[i] & 0x7f; + switch (basic_rate) { + case MGN_1M: + *rate_config |= RRSR_1M; + break; + case MGN_2M: + *rate_config |= RRSR_2M; + break; + case MGN_5_5M: + *rate_config |= RRSR_5_5M; + break; + case MGN_11M: + *rate_config |= RRSR_11M; + break; + case MGN_6M: + *rate_config |= RRSR_6M; + break; + case MGN_9M: + *rate_config |= RRSR_9M; + break; + case MGN_12M: + *rate_config |= RRSR_12M; + break; + case MGN_18M: + *rate_config |= RRSR_18M; + break; + case MGN_24M: + *rate_config |= RRSR_24M; + break; + case MGN_36M: + *rate_config |= RRSR_36M; + break; + case MGN_48M: + *rate_config |= RRSR_48M; + break; + case MGN_54M: + *rate_config |= RRSR_54M; + break; + } + } + + for (i = 0; i < net->rates_ex_len; i++) { + basic_rate = net->rates_ex[i] & 0x7f; + switch (basic_rate) { + case MGN_1M: + *rate_config |= RRSR_1M; + break; + case MGN_2M: + *rate_config |= RRSR_2M; + break; + case MGN_5_5M: + *rate_config |= RRSR_5_5M; + break; + case MGN_11M: + *rate_config |= RRSR_11M; + break; + case MGN_6M: + *rate_config |= RRSR_6M; + break; + case MGN_9M: + *rate_config |= RRSR_9M; + break; + case MGN_12M: + *rate_config |= RRSR_12M; + break; + case MGN_18M: + *rate_config |= RRSR_18M; + break; + case MGN_24M: + *rate_config |= RRSR_24M; + break; + case MGN_36M: + *rate_config |= RRSR_36M; + break; + case MGN_48M: + *rate_config |= RRSR_48M; + break; + case MGN_54M: + *rate_config |= RRSR_54M; + break; + } + } +} + +static void rtl8192_refresh_supportrate(struct r8192_priv *priv) +{ + struct rtllib_device *ieee = priv->rtllib; + if (ieee->mode == WIRELESS_MODE_N_24G || + ieee->mode == WIRELESS_MODE_N_5G) { + memcpy(ieee->Regdot11HTOperationalRateSet, + ieee->RegHTSuppRateSet, 16); + memcpy(ieee->Regdot11TxHTOperationalRateSet, + ieee->RegHTSuppRateSet, 16); + + } else { + memset(ieee->Regdot11HTOperationalRateSet, 0, 16); + } + return; +} + +static u8 rtl8192_getSupportedWireleeMode(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + u8 ret = 0; + + switch (priv->rf_chip) { + case RF_8225: + case RF_8256: + case RF_6052: + case RF_PSEUDO_11N: + ret = (WIRELESS_MODE_N_24G|WIRELESS_MODE_G | WIRELESS_MODE_B); + break; + case RF_8258: + ret = (WIRELESS_MODE_A | WIRELESS_MODE_N_5G); + break; + default: + ret = WIRELESS_MODE_B; + break; + } + return ret; +} + +void rtl8192_SetWirelessMode(struct net_device *dev, u8 wireless_mode) +{ + struct r8192_priv *priv = rtllib_priv(dev); + u8 bSupportMode = rtl8192_getSupportedWireleeMode(dev); + + if ((wireless_mode == WIRELESS_MODE_AUTO) || + ((wireless_mode & bSupportMode) == 0)) { + if (bSupportMode & WIRELESS_MODE_N_24G) { + wireless_mode = WIRELESS_MODE_N_24G; + } else if (bSupportMode & WIRELESS_MODE_N_5G) { + wireless_mode = WIRELESS_MODE_N_5G; + } else if ((bSupportMode & WIRELESS_MODE_A)) { + wireless_mode = WIRELESS_MODE_A; + } else if ((bSupportMode & WIRELESS_MODE_G)) { + wireless_mode = WIRELESS_MODE_G; + } else if ((bSupportMode & WIRELESS_MODE_B)) { + wireless_mode = WIRELESS_MODE_B; + } else { + RT_TRACE(COMP_ERR, "%s(), No valid wireless mode " + "supported (%x)!!!\n", __func__, bSupportMode); + wireless_mode = WIRELESS_MODE_B; + } + } + + if ((wireless_mode & (WIRELESS_MODE_B | WIRELESS_MODE_G)) == + (WIRELESS_MODE_G | WIRELESS_MODE_B)) + wireless_mode = WIRELESS_MODE_G; + + priv->rtllib->mode = wireless_mode; + + ActUpdateChannelAccessSetting(dev, wireless_mode, + &priv->ChannelAccessSetting); + + if ((wireless_mode == WIRELESS_MODE_N_24G) || + (wireless_mode == WIRELESS_MODE_N_5G)) { + priv->rtllib->pHTInfo->bEnableHT = 1; + RT_TRACE(COMP_DBG, "%s(), wireless_mode:%x, bEnableHT = 1\n", + __func__, wireless_mode); + } else { + priv->rtllib->pHTInfo->bEnableHT = 0; + RT_TRACE(COMP_DBG, "%s(), wireless_mode:%x, bEnableHT = 0\n", + __func__, wireless_mode); + } + + RT_TRACE(COMP_INIT, "Current Wireless Mode is %x\n", wireless_mode); + rtl8192_refresh_supportrate(priv); +} + +static int _rtl8192_sta_up(struct net_device *dev, bool is_silent_reset) +{ + struct r8192_priv *priv = rtllib_priv(dev); + struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) + (&(priv->rtllib->PowerSaveControl)); + bool init_status = true; + priv->bDriverIsGoingToUnload = false; + priv->bdisable_nic = false; + + priv->up = 1; + priv->rtllib->ieee_up = 1; + + priv->up_first_time = 0; + RT_TRACE(COMP_INIT, "Bringing up iface"); + priv->bfirst_init = true; + init_status = priv->ops->initialize_adapter(dev); + if (init_status != true) { + RT_TRACE(COMP_ERR, "ERR!!! %s(): initialization is failed!\n", + __func__); + priv->bfirst_init = false; + return -1; + } + + RT_TRACE(COMP_INIT, "start adapter finished\n"); + RT_CLEAR_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC); + priv->bfirst_init = false; + + if (priv->polling_timer_on == 0) + check_rfctrl_gpio_timer((unsigned long)dev); + + if (priv->rtllib->state != RTLLIB_LINKED) + rtllib_softmac_start_protocol(priv->rtllib, 0); + rtllib_reset_queue(priv->rtllib); + watch_dog_timer_callback((unsigned long) dev); + + if (!netif_queue_stopped(dev)) + netif_start_queue(dev); + else + netif_wake_queue(dev); + + return 0; +} + +static int rtl8192_sta_down(struct net_device *dev, bool shutdownrf) +{ + struct r8192_priv *priv = rtllib_priv(dev); + unsigned long flags = 0; + u8 RFInProgressTimeOut = 0; + + if (priv->up == 0) + return -1; + + if (priv->rtllib->rtllib_ips_leave != NULL) + priv->rtllib->rtllib_ips_leave(dev); + + if (priv->rtllib->state == RTLLIB_LINKED) + LeisurePSLeave(dev); + + priv->bDriverIsGoingToUnload = true; + priv->up = 0; + priv->rtllib->ieee_up = 0; + priv->bfirst_after_down = 1; + RT_TRACE(COMP_DOWN, "==========>%s()\n", __func__); + if (!netif_queue_stopped(dev)) + netif_stop_queue(dev); + + priv->rtllib->wpa_ie_len = 0; + kfree(priv->rtllib->wpa_ie); + priv->rtllib->wpa_ie = NULL; + CamResetAllEntry(dev); + memset(priv->rtllib->swcamtable, 0, sizeof(struct sw_cam_table) * 32); + rtl8192_irq_disable(dev); + + del_timer_sync(&priv->watch_dog_timer); + rtl8192_cancel_deferred_work(priv); + cancel_delayed_work(&priv->rtllib->hw_wakeup_wq); + + rtllib_softmac_stop_protocol(priv->rtllib, 0, true); + spin_lock_irqsave(&priv->rf_ps_lock, flags); + while (priv->RFChangeInProgress) { + spin_unlock_irqrestore(&priv->rf_ps_lock, flags); + if (RFInProgressTimeOut > 100) { + spin_lock_irqsave(&priv->rf_ps_lock, flags); + break; + } + RT_TRACE(COMP_DBG, "===>%s():RF is in progress, need to wait " + "until rf chang is done.\n", __func__); + mdelay(1); + RFInProgressTimeOut++; + spin_lock_irqsave(&priv->rf_ps_lock, flags); + } + priv->RFChangeInProgress = true; + spin_unlock_irqrestore(&priv->rf_ps_lock, flags); + priv->ops->stop_adapter(dev, false); + spin_lock_irqsave(&priv->rf_ps_lock, flags); + priv->RFChangeInProgress = false; + spin_unlock_irqrestore(&priv->rf_ps_lock, flags); + udelay(100); + memset(&priv->rtllib->current_network, 0, + offsetof(struct rtllib_network, list)); + RT_TRACE(COMP_DOWN, "<==========%s()\n", __func__); + + return 0; +} + +static void rtl8192_init_priv_handler(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + priv->rtllib->softmac_hard_start_xmit = rtl8192_hard_start_xmit; + priv->rtllib->set_chan = rtl8192_set_chan; + priv->rtllib->link_change = priv->ops->link_change; + priv->rtllib->softmac_data_hard_start_xmit = rtl8192_hard_data_xmit; + priv->rtllib->data_hard_stop = rtl8192_data_hard_stop; + priv->rtllib->data_hard_resume = rtl8192_data_hard_resume; + priv->rtllib->check_nic_enough_desc = rtl8192_check_nic_enough_desc; + priv->rtllib->get_nic_desc_num = rtl8192_get_nic_desc_num; + priv->rtllib->handle_assoc_response = rtl8192_handle_assoc_response; + priv->rtllib->handle_beacon = rtl8192_handle_beacon; + priv->rtllib->SetWirelessMode = rtl8192_SetWirelessMode; + priv->rtllib->LeisurePSLeave = LeisurePSLeave; + priv->rtllib->SetBWModeHandler = rtl8192_SetBWMode; + priv->rf_set_chan = rtl8192_phy_SwChnl; + + priv->rtllib->start_send_beacons = rtl8192e_start_beacon; + priv->rtllib->stop_send_beacons = rtl8192_stop_beacon; + + priv->rtllib->sta_wake_up = rtl8192_hw_wakeup; + priv->rtllib->enter_sleep_state = rtl8192_hw_to_sleep; + priv->rtllib->ps_is_queue_empty = rtl8192_is_tx_queue_empty; + + priv->rtllib->GetNmodeSupportBySecCfg = rtl8192_GetNmodeSupportBySecCfg; + priv->rtllib->GetHalfNmodeSupportByAPsHandler = + rtl8192_GetHalfNmodeSupportByAPs; + + priv->rtllib->SetHwRegHandler = rtl8192e_SetHwReg; + priv->rtllib->AllowAllDestAddrHandler = rtl8192_AllowAllDestAddr; + priv->rtllib->SetFwCmdHandler = NULL; + priv->rtllib->InitialGainHandler = InitialGain819xPci; + priv->rtllib->rtllib_ips_leave_wq = rtllib_ips_leave_wq; + priv->rtllib->rtllib_ips_leave = rtllib_ips_leave; + + priv->rtllib->LedControlHandler = NULL; + priv->rtllib->UpdateBeaconInterruptHandler = NULL; + + priv->rtllib->ScanOperationBackupHandler = PHY_ScanOperationBackup8192; + + priv->rtllib->rtllib_rfkill_poll = NULL; +} + +static void rtl8192_init_priv_constant(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) + &(priv->rtllib->PowerSaveControl); + + pPSC->RegMaxLPSAwakeIntvl = 5; + + priv->RegPciASPM = 2; + + priv->RegDevicePciASPMSetting = 0x03; + + priv->RegHostPciASPMSetting = 0x02; + + priv->RegHwSwRfOffD3 = 2; + + priv->RegSupportPciASPM = 2; +} + + +static void rtl8192_init_priv_variable(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + u8 i; + + priv->AcmMethod = eAcmWay2_SW; + priv->dot11CurrentPreambleMode = PREAMBLE_AUTO; + priv->rtllib->hwscan_sem_up = 1; + priv->rtllib->status = 0; + priv->H2CTxCmdSeq = 0; + priv->bDisableFrameBursting = 0; + priv->bDMInitialGainEnable = 1; + priv->polling_timer_on = 0; + priv->up_first_time = 1; + priv->blinked_ingpio = false; + priv->bDriverIsGoingToUnload = false; + priv->being_init_adapter = false; + priv->initialized_at_probe = false; + priv->sw_radio_on = true; + priv->bdisable_nic = false; + priv->bfirst_init = false; + priv->txringcount = 64; + priv->rxbuffersize = 9100; + priv->rxringcount = MAX_RX_COUNT; + priv->irq_enabled = 0; + priv->chan = 1; + priv->RegWirelessMode = WIRELESS_MODE_AUTO; + priv->RegChannelPlan = 0xf; + priv->nrxAMPDU_size = 0; + priv->nrxAMPDU_aggr_num = 0; + priv->last_rxdesc_tsf_high = 0; + priv->last_rxdesc_tsf_low = 0; + priv->rtllib->mode = WIRELESS_MODE_AUTO; + priv->rtllib->iw_mode = IW_MODE_INFRA; + priv->rtllib->bNetPromiscuousMode = false; + priv->rtllib->IntelPromiscuousModeInfo.bPromiscuousOn = false; + priv->rtllib->IntelPromiscuousModeInfo.bFilterSourceStationFrame = + false; + priv->rtllib->ieee_up = 0; + priv->retry_rts = DEFAULT_RETRY_RTS; + priv->retry_data = DEFAULT_RETRY_DATA; + priv->rtllib->rts = DEFAULT_RTS_THRESHOLD; + priv->rtllib->rate = 110; + priv->rtllib->short_slot = 1; + priv->promisc = (dev->flags & IFF_PROMISC) ? 1 : 0; + priv->bcck_in_ch14 = false; + priv->bfsync_processing = false; + priv->CCKPresentAttentuation = 0; + priv->rfa_txpowertrackingindex = 0; + priv->rfc_txpowertrackingindex = 0; + priv->CckPwEnl = 6; + priv->ScanDelay = 50; + priv->ResetProgress = RESET_TYPE_NORESET; + priv->bForcedSilentReset = 0; + priv->bDisableNormalResetCheck = false; + priv->force_reset = false; + memset(priv->rtllib->swcamtable, 0, sizeof(struct sw_cam_table) * 32); + + memset(&priv->InterruptLog, 0, sizeof(struct log_int_8190)); + priv->RxCounter = 0; + priv->rtllib->wx_set_enc = 0; + priv->bHwRadioOff = false; + priv->RegRfOff = 0; + priv->isRFOff = false; + priv->bInPowerSaveMode = false; + priv->rtllib->RfOffReason = 0; + priv->RFChangeInProgress = false; + priv->bHwRfOffAction = 0; + priv->SetRFPowerStateInProgress = false; + priv->rtllib->PowerSaveControl.bInactivePs = true; + priv->rtllib->PowerSaveControl.bIPSModeBackup = false; + priv->rtllib->PowerSaveControl.bLeisurePs = true; + priv->rtllib->PowerSaveControl.bFwCtrlLPS = false; + priv->rtllib->LPSDelayCnt = 0; + priv->rtllib->sta_sleep = LPS_IS_WAKE; + priv->rtllib->eRFPowerState = eRfOn; + + priv->txpower_checkcnt = 0; + priv->thermal_readback_index = 0; + priv->txpower_tracking_callback_cnt = 0; + priv->ccktxpower_adjustcnt_ch14 = 0; + priv->ccktxpower_adjustcnt_not_ch14 = 0; + + priv->rtllib->current_network.beacon_interval = DEFAULT_BEACONINTERVAL; + priv->rtllib->iw_mode = IW_MODE_INFRA; + priv->rtllib->active_scan = 1; + priv->rtllib->be_scan_inprogress = false; + priv->rtllib->modulation = RTLLIB_CCK_MODULATION | + RTLLIB_OFDM_MODULATION; + priv->rtllib->host_encrypt = 1; + priv->rtllib->host_decrypt = 1; + + priv->rtllib->dot11PowerSaveMode = eActive; + priv->rtllib->fts = DEFAULT_FRAG_THRESHOLD; + priv->rtllib->MaxMssDensity = 0; + priv->rtllib->MinSpaceCfg = 0; + + priv->card_type = PCI; + + priv->AcmControl = 0; + priv->pFirmware = vzalloc(sizeof(struct rt_firmware)); + if (!priv->pFirmware) + printk(KERN_ERR "rtl8193e: Unable to allocate space " + "for firmware\n"); + + skb_queue_head_init(&priv->rx_queue); + skb_queue_head_init(&priv->skb_queue); + + for (i = 0; i < MAX_QUEUE_SIZE; i++) + skb_queue_head_init(&priv->rtllib->skb_waitQ[i]); + for (i = 0; i < MAX_QUEUE_SIZE; i++) + skb_queue_head_init(&priv->rtllib->skb_aggQ[i]); +} + +static void rtl8192_init_priv_lock(struct r8192_priv *priv) +{ + spin_lock_init(&priv->fw_scan_lock); + spin_lock_init(&priv->tx_lock); + spin_lock_init(&priv->irq_lock); + spin_lock_init(&priv->irq_th_lock); + spin_lock_init(&priv->rf_ps_lock); + spin_lock_init(&priv->ps_lock); + spin_lock_init(&priv->rf_lock); + spin_lock_init(&priv->rt_h2c_lock); + sema_init(&priv->wx_sem, 1); + sema_init(&priv->rf_sem, 1); + mutex_init(&priv->mutex); +} + +static void rtl8192_init_priv_task(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + priv->priv_wq = create_workqueue(DRV_NAME); + INIT_WORK_RSL(&priv->reset_wq, (void *)rtl8192_restart, dev); + INIT_WORK_RSL(&priv->rtllib->ips_leave_wq, (void *)IPSLeave_wq, dev); + INIT_DELAYED_WORK_RSL(&priv->watch_dog_wq, + (void *)rtl819x_watchdog_wqcallback, dev); + INIT_DELAYED_WORK_RSL(&priv->txpower_tracking_wq, + (void *)dm_txpower_trackingcallback, dev); + INIT_DELAYED_WORK_RSL(&priv->rfpath_check_wq, + (void *)dm_rf_pathcheck_workitemcallback, dev); + INIT_DELAYED_WORK_RSL(&priv->update_beacon_wq, + (void *)rtl8192_update_beacon, dev); + INIT_WORK_RSL(&priv->qos_activate, (void *)rtl8192_qos_activate, dev); + INIT_DELAYED_WORK_RSL(&priv->rtllib->hw_wakeup_wq, + (void *) rtl8192_hw_wakeup_wq, dev); + INIT_DELAYED_WORK_RSL(&priv->rtllib->hw_sleep_wq, + (void *) rtl8192_hw_sleep_wq, dev); + tasklet_init(&priv->irq_rx_tasklet, + (void(*)(unsigned long))rtl8192_irq_rx_tasklet, + (unsigned long)priv); + tasklet_init(&priv->irq_tx_tasklet, + (void(*)(unsigned long))rtl8192_irq_tx_tasklet, + (unsigned long)priv); + tasklet_init(&priv->irq_prepare_beacon_tasklet, + (void(*)(unsigned long))rtl8192_prepare_beacon, + (unsigned long)priv); +} + +static short rtl8192_get_channel_map(struct net_device *dev) +{ + int i; + + struct r8192_priv *priv = rtllib_priv(dev); + if ((priv->rf_chip != RF_8225) && (priv->rf_chip != RF_8256) + && (priv->rf_chip != RF_6052)) { + RT_TRACE(COMP_ERR, "%s: unknown rf chip, can't set channel " + "map\n", __func__); + return -1; + } + + if (priv->ChannelPlan > COUNTRY_CODE_MAX) { + printk(KERN_INFO "rtl819x_init:Error channel plan! Set to " + "default.\n"); + priv->ChannelPlan = COUNTRY_CODE_FCC; + } + RT_TRACE(COMP_INIT, "Channel plan is %d\n", priv->ChannelPlan); + Dot11d_Init(priv->rtllib); + Dot11d_Channelmap(priv->ChannelPlan, priv->rtllib); + for (i = 1; i <= 11; i++) + (priv->rtllib->active_channel_map)[i] = 1; + (priv->rtllib->active_channel_map)[12] = 2; + (priv->rtllib->active_channel_map)[13] = 2; + + return 0; +} + +static short rtl8192_init(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + memset(&(priv->stats), 0, sizeof(struct rt_stats)); + + rtl8192_dbgp_flag_init(dev); + rtl8192_init_priv_handler(dev); + rtl8192_init_priv_constant(dev); + rtl8192_init_priv_variable(dev); + rtl8192_init_priv_lock(priv); + rtl8192_init_priv_task(dev); + priv->ops->get_eeprom_size(dev); + priv->ops->init_adapter_variable(dev); + rtl8192_get_channel_map(dev); + + init_hal_dm(dev); + + init_timer(&priv->watch_dog_timer); + setup_timer(&priv->watch_dog_timer, + watch_dog_timer_callback, + (unsigned long) dev); + + init_timer(&priv->gpio_polling_timer); + setup_timer(&priv->gpio_polling_timer, + check_rfctrl_gpio_timer, + (unsigned long)dev); + + rtl8192_irq_disable(dev); + if (request_irq(dev->irq, (void *)rtl8192_interrupt_rsl, IRQF_SHARED, + dev->name, dev)) { + printk(KERN_ERR "Error allocating IRQ %d", dev->irq); + return -1; + } else { + priv->irq = dev->irq; + RT_TRACE(COMP_INIT, "IRQ %d\n", dev->irq); + } + + if (rtl8192_pci_initdescring(dev) != 0) { + printk(KERN_ERR "Endopoints initialization failed"); + return -1; + } + + return 0; +} + +/*************************************************************************** + -------------------------------WATCHDOG STUFF--------------------------- +***************************************************************************/ +short rtl8192_is_tx_queue_empty(struct net_device *dev) +{ + int i = 0; + struct r8192_priv *priv = rtllib_priv(dev); + for (i = 0; i <= MGNT_QUEUE; i++) { + if ((i == TXCMD_QUEUE) || (i == HCCA_QUEUE)) + continue; + if (skb_queue_len(&(&priv->tx_ring[i])->queue) > 0) { + printk(KERN_INFO "===>tx queue is not empty:%d, %d\n", + i, skb_queue_len(&(&priv->tx_ring[i])->queue)); + return 0; + } + } + return 1; +} + +static enum reset_type rtl819x_TxCheckStuck(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + u8 QueueID; + u8 ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE; + bool bCheckFwTxCnt = false; + struct rtl8192_tx_ring *ring = NULL; + struct sk_buff *skb = NULL; + struct cb_desc *tcb_desc = NULL; + unsigned long flags = 0; + + switch (priv->rtllib->ps) { + case RTLLIB_PS_DISABLED: + ResetThreshold = NIC_SEND_HANG_THRESHOLD_NORMAL; + break; + case (RTLLIB_PS_MBCAST|RTLLIB_PS_UNICAST): + ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE; + break; + default: + ResetThreshold = NIC_SEND_HANG_THRESHOLD_POWERSAVE; + break; + } + spin_lock_irqsave(&priv->irq_th_lock, flags); + for (QueueID = 0; QueueID < MAX_TX_QUEUE; QueueID++) { + if (QueueID == TXCMD_QUEUE) + continue; + + if (QueueID == BEACON_QUEUE) + continue; + + ring = &priv->tx_ring[QueueID]; + + if (skb_queue_len(&ring->queue) == 0) { + continue; + } else { + skb = (&ring->queue)->next; + tcb_desc = (struct cb_desc *)(skb->cb + + MAX_DEV_ADDR_SIZE); + tcb_desc->nStuckCount++; + bCheckFwTxCnt = true; + if (tcb_desc->nStuckCount > 1) + printk(KERN_INFO "%s: QueueID=%d tcb_desc->n" + "StuckCount=%d\n", __func__, QueueID, + tcb_desc->nStuckCount); + } + } + spin_unlock_irqrestore(&priv->irq_th_lock, flags); + + if (bCheckFwTxCnt) { + if (priv->ops->TxCheckStuckHandler(dev)) { + RT_TRACE(COMP_RESET, "TxCheckStuck(): Fw indicates no" + " Tx condition!\n"); + return RESET_TYPE_SILENT; + } + } + + return RESET_TYPE_NORESET; +} + +static enum reset_type rtl819x_RxCheckStuck(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + if (priv->ops->RxCheckStuckHandler(dev)) { + RT_TRACE(COMP_RESET, "RxStuck Condition\n"); + return RESET_TYPE_SILENT; + } + + return RESET_TYPE_NORESET; +} + +static enum reset_type rtl819x_ifcheck_resetornot(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + enum reset_type TxResetType = RESET_TYPE_NORESET; + enum reset_type RxResetType = RESET_TYPE_NORESET; + enum rt_rf_power_state rfState; + + rfState = priv->rtllib->eRFPowerState; + + if (rfState == eRfOn) + TxResetType = rtl819x_TxCheckStuck(dev); + + if (rfState == eRfOn && + (priv->rtllib->iw_mode == IW_MODE_INFRA) && + (priv->rtllib->state == RTLLIB_LINKED)) + RxResetType = rtl819x_RxCheckStuck(dev); + + if (TxResetType == RESET_TYPE_NORMAL || + RxResetType == RESET_TYPE_NORMAL) { + printk(KERN_INFO "%s(): TxResetType is %d, RxResetType is %d\n", + __func__, TxResetType, RxResetType); + return RESET_TYPE_NORMAL; + } else if (TxResetType == RESET_TYPE_SILENT || + RxResetType == RESET_TYPE_SILENT) { + printk(KERN_INFO "%s(): TxResetType is %d, RxResetType is %d\n", + __func__, TxResetType, RxResetType); + return RESET_TYPE_SILENT; + } else { + return RESET_TYPE_NORESET; + } + +} + +static void rtl819x_silentreset_mesh_bk(struct net_device *dev, u8 IsPortal) +{ +} + +static void rtl819x_ifsilentreset(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + u8 reset_times = 0; + int reset_status = 0; + struct rtllib_device *ieee = priv->rtllib; + unsigned long flag; + + u8 IsPortal = 0; + + + if (priv->ResetProgress == RESET_TYPE_NORESET) { + + RT_TRACE(COMP_RESET, "=========>Reset progress!!\n"); + + priv->ResetProgress = RESET_TYPE_SILENT; + + spin_lock_irqsave(&priv->rf_ps_lock, flag); + if (priv->RFChangeInProgress) { + spin_unlock_irqrestore(&priv->rf_ps_lock, flag); + goto END; + } + priv->RFChangeInProgress = true; + priv->bResetInProgress = true; + spin_unlock_irqrestore(&priv->rf_ps_lock, flag); + +RESET_START: + + down(&priv->wx_sem); + + if (priv->rtllib->state == RTLLIB_LINKED) + LeisurePSLeave(dev); + + if (IS_NIC_DOWN(priv)) { + RT_TRACE(COMP_ERR, "%s():the driver is not up! " + "return\n", __func__); + up(&priv->wx_sem); + return ; + } + priv->up = 0; + + RT_TRACE(COMP_RESET, "%s():======>start to down the driver\n", + __func__); + mdelay(1000); + RT_TRACE(COMP_RESET, "%s():111111111111111111111111======>start" + " to down the driver\n", __func__); + + if (!netif_queue_stopped(dev)) + netif_stop_queue(dev); + + rtl8192_irq_disable(dev); + del_timer_sync(&priv->watch_dog_timer); + rtl8192_cancel_deferred_work(priv); + deinit_hal_dm(dev); + rtllib_stop_scan_syncro(ieee); + + if (ieee->state == RTLLIB_LINKED) { + SEM_DOWN_IEEE_WX(&ieee->wx_sem); + printk(KERN_INFO "ieee->state is RTLLIB_LINKED\n"); + rtllib_stop_send_beacons(priv->rtllib); + del_timer_sync(&ieee->associate_timer); + cancel_delayed_work(&ieee->associate_retry_wq); + rtllib_stop_scan(ieee); + netif_carrier_off(dev); + SEM_UP_IEEE_WX(&ieee->wx_sem); + } else { + printk(KERN_INFO "ieee->state is NOT LINKED\n"); + rtllib_softmac_stop_protocol(priv->rtllib, 0 , true); + } + + dm_backup_dynamic_mechanism_state(dev); + + up(&priv->wx_sem); + RT_TRACE(COMP_RESET, "%s():<==========down process is " + "finished\n", __func__); + + RT_TRACE(COMP_RESET, "%s():<===========up process start\n", + __func__); + reset_status = _rtl8192_up(dev, true); + + RT_TRACE(COMP_RESET, "%s():<===========up process is " + "finished\n", __func__); + if (reset_status == -1) { + if (reset_times < 3) { + reset_times++; + goto RESET_START; + } else { + RT_TRACE(COMP_ERR, " ERR!!! %s(): Reset " + "Failed!!\n", __func__); + } + } + + ieee->is_silent_reset = 1; + + spin_lock_irqsave(&priv->rf_ps_lock, flag); + priv->RFChangeInProgress = false; + spin_unlock_irqrestore(&priv->rf_ps_lock, flag); + + EnableHWSecurityConfig8192(dev); + + if (ieee->state == RTLLIB_LINKED && ieee->iw_mode == + IW_MODE_INFRA) { + ieee->set_chan(ieee->dev, + ieee->current_network.channel); + + queue_work_rsl(ieee->wq, &ieee->associate_complete_wq); + + } else if (ieee->state == RTLLIB_LINKED && ieee->iw_mode == + IW_MODE_ADHOC) { + ieee->set_chan(ieee->dev, + ieee->current_network.channel); + ieee->link_change(ieee->dev); + + notify_wx_assoc_event(ieee); + + rtllib_start_send_beacons(ieee); + + if (ieee->data_hard_resume) + ieee->data_hard_resume(ieee->dev); + netif_carrier_on(ieee->dev); + } else if (ieee->iw_mode == IW_MODE_MESH) { + rtl819x_silentreset_mesh_bk(dev, IsPortal); + } + + CamRestoreAllEntry(dev); + dm_restore_dynamic_mechanism_state(dev); +END: + priv->ResetProgress = RESET_TYPE_NORESET; + priv->reset_count++; + + priv->bForcedSilentReset = false; + priv->bResetInProgress = false; + + write_nic_byte(dev, UFWP, 1); + RT_TRACE(COMP_RESET, "Reset finished!! ====>[%d]\n", + priv->reset_count); + } +} + +static void rtl819x_update_rxcounts(struct r8192_priv *priv, u32 *TotalRxBcnNum, + u32 *TotalRxDataNum) +{ + u16 SlotIndex; + u8 i; + + *TotalRxBcnNum = 0; + *TotalRxDataNum = 0; + + SlotIndex = (priv->rtllib->LinkDetectInfo.SlotIndex++) % + (priv->rtllib->LinkDetectInfo.SlotNum); + priv->rtllib->LinkDetectInfo.RxBcnNum[SlotIndex] = + priv->rtllib->LinkDetectInfo.NumRecvBcnInPeriod; + priv->rtllib->LinkDetectInfo.RxDataNum[SlotIndex] = + priv->rtllib->LinkDetectInfo.NumRecvDataInPeriod; + for (i = 0; i < priv->rtllib->LinkDetectInfo.SlotNum; i++) { + *TotalRxBcnNum += priv->rtllib->LinkDetectInfo.RxBcnNum[i]; + *TotalRxDataNum += priv->rtllib->LinkDetectInfo.RxDataNum[i]; + } +} + + +void rtl819x_watchdog_wqcallback(void *data) +{ + struct r8192_priv *priv = container_of_dwork_rsl(data, + struct r8192_priv, watch_dog_wq); + struct net_device *dev = priv->rtllib->dev; + struct rtllib_device *ieee = priv->rtllib; + enum reset_type ResetType = RESET_TYPE_NORESET; + static u8 check_reset_cnt; + unsigned long flags; + struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) + (&(priv->rtllib->PowerSaveControl)); + bool bBusyTraffic = false; + bool bHigherBusyTraffic = false; + bool bHigherBusyRxTraffic = false; + bool bEnterPS = false; + + if (IS_NIC_DOWN(priv) || (priv->bHwRadioOff == true)) + return; + + if (priv->rtllib->state >= RTLLIB_LINKED) { + if (priv->rtllib->CntAfterLink < 2) + priv->rtllib->CntAfterLink++; + } else { + priv->rtllib->CntAfterLink = 0; + } + + hal_dm_watchdog(dev); + + if (rtllib_act_scanning(priv->rtllib, false) == false) { + if ((ieee->iw_mode == IW_MODE_INFRA) && (ieee->state == + RTLLIB_NOLINK) && + (ieee->eRFPowerState == eRfOn) && !ieee->is_set_key && + (!ieee->proto_stoppping) && !ieee->wx_set_enc) { + if ((ieee->PowerSaveControl.ReturnPoint == + IPS_CALLBACK_NONE) && + (!ieee->bNetPromiscuousMode)) { + RT_TRACE(COMP_PS, "====================>haha: " + "IPSEnter()\n"); + IPSEnter(dev); + } + } + } + if ((ieee->state == RTLLIB_LINKED) && (ieee->iw_mode == + IW_MODE_INFRA) && (!ieee->bNetPromiscuousMode)) { + if (ieee->LinkDetectInfo.NumRxOkInPeriod > 100 || + ieee->LinkDetectInfo.NumTxOkInPeriod > 100) + bBusyTraffic = true; + + + if (ieee->LinkDetectInfo.NumRxOkInPeriod > 4000 || + ieee->LinkDetectInfo.NumTxOkInPeriod > 4000) { + bHigherBusyTraffic = true; + if (ieee->LinkDetectInfo.NumRxOkInPeriod > 5000) + bHigherBusyRxTraffic = true; + else + bHigherBusyRxTraffic = false; + } + + if (((ieee->LinkDetectInfo.NumRxUnicastOkInPeriod + + ieee->LinkDetectInfo.NumTxOkInPeriod) > 8) || + (ieee->LinkDetectInfo.NumRxUnicastOkInPeriod > 2)) + bEnterPS = false; + else + bEnterPS = true; + + if (ieee->current_network.beacon_interval < 95) + bEnterPS = false; + + if (bEnterPS) + LeisurePSEnter(dev); + else + LeisurePSLeave(dev); + + } else { + RT_TRACE(COMP_LPS, "====>no link LPS leave\n"); + LeisurePSLeave(dev); + } + + ieee->LinkDetectInfo.NumRxOkInPeriod = 0; + ieee->LinkDetectInfo.NumTxOkInPeriod = 0; + ieee->LinkDetectInfo.NumRxUnicastOkInPeriod = 0; + ieee->LinkDetectInfo.bBusyTraffic = bBusyTraffic; + + ieee->LinkDetectInfo.bHigherBusyTraffic = bHigherBusyTraffic; + ieee->LinkDetectInfo.bHigherBusyRxTraffic = bHigherBusyRxTraffic; + + if (ieee->state == RTLLIB_LINKED && ieee->iw_mode == IW_MODE_INFRA) { + u32 TotalRxBcnNum = 0; + u32 TotalRxDataNum = 0; + + rtl819x_update_rxcounts(priv, &TotalRxBcnNum, &TotalRxDataNum); + + if ((TotalRxBcnNum+TotalRxDataNum) == 0) + priv->check_roaming_cnt++; + else + priv->check_roaming_cnt = 0; + + + if (priv->check_roaming_cnt > 0) { + if (ieee->eRFPowerState == eRfOff) + RT_TRACE(COMP_ERR, "========>%s()\n", __func__); + + printk(KERN_INFO "===>%s(): AP is power off, chan:%d," + " connect another one\n", __func__, priv->chan); + + ieee->state = RTLLIB_ASSOCIATING; + + RemovePeerTS(priv->rtllib, + priv->rtllib->current_network.bssid); + ieee->is_roaming = true; + ieee->is_set_key = false; + ieee->link_change(dev); + if (ieee->LedControlHandler) + ieee->LedControlHandler(ieee->dev, + LED_CTL_START_TO_LINK); + + notify_wx_assoc_event(ieee); + + if (!(ieee->rtllib_ap_sec_type(ieee) & + (SEC_ALG_CCMP|SEC_ALG_TKIP))) + queue_delayed_work_rsl(ieee->wq, + &ieee->associate_procedure_wq, 0); + + priv->check_roaming_cnt = 0; + } + ieee->LinkDetectInfo.NumRecvBcnInPeriod = 0; + ieee->LinkDetectInfo.NumRecvDataInPeriod = 0; + + } + + spin_lock_irqsave(&priv->tx_lock, flags); + if ((check_reset_cnt++ >= 3) && (!ieee->is_roaming) && + (!priv->RFChangeInProgress) && (!pPSC->bSwRfProcessing)) { + ResetType = rtl819x_ifcheck_resetornot(dev); + check_reset_cnt = 3; + } + spin_unlock_irqrestore(&priv->tx_lock, flags); + + if (!priv->bDisableNormalResetCheck && ResetType == RESET_TYPE_NORMAL) { + priv->ResetProgress = RESET_TYPE_NORMAL; + RT_TRACE(COMP_RESET, "%s(): NOMAL RESET\n", __func__); + return; + } + + if (((priv->force_reset) || (!priv->bDisableNormalResetCheck && + ResetType == RESET_TYPE_SILENT))) + rtl819x_ifsilentreset(dev); + priv->force_reset = false; + priv->bForcedSilentReset = false; + priv->bResetInProgress = false; + RT_TRACE(COMP_TRACE, " <==RtUsbCheckForHangWorkItemCallback()\n"); +} + +void watch_dog_timer_callback(unsigned long data) +{ + struct r8192_priv *priv = rtllib_priv((struct net_device *)data); + queue_delayed_work_rsl(priv->priv_wq, &priv->watch_dog_wq, 0); + mod_timer(&priv->watch_dog_timer, jiffies + + MSECS(RTLLIB_WATCH_DOG_TIME)); +} + +/**************************************************************************** + ---------------------------- NIC TX/RX STUFF--------------------------- +*****************************************************************************/ +void rtl8192_rx_enable(struct net_device *dev) +{ + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + priv->ops->rx_enable(dev); +} + +void rtl8192_tx_enable(struct net_device *dev) +{ + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + + priv->ops->tx_enable(dev); + + rtllib_reset_queue(priv->rtllib); +} + + +static void rtl8192_free_rx_ring(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + int i, rx_queue_idx; + + for (rx_queue_idx = 0; rx_queue_idx < MAX_RX_QUEUE; + rx_queue_idx++) { + for (i = 0; i < priv->rxringcount; i++) { + struct sk_buff *skb = priv->rx_buf[rx_queue_idx][i]; + if (!skb) + continue; + + pci_unmap_single(priv->pdev, + *((dma_addr_t *)skb->cb), + priv->rxbuffersize, PCI_DMA_FROMDEVICE); + kfree_skb(skb); + } + + pci_free_consistent(priv->pdev, + sizeof(*priv->rx_ring[rx_queue_idx]) * + priv->rxringcount, + priv->rx_ring[rx_queue_idx], + priv->rx_ring_dma[rx_queue_idx]); + priv->rx_ring[rx_queue_idx] = NULL; + } +} + +static void rtl8192_free_tx_ring(struct net_device *dev, unsigned int prio) +{ + struct r8192_priv *priv = rtllib_priv(dev); + struct rtl8192_tx_ring *ring = &priv->tx_ring[prio]; + + while (skb_queue_len(&ring->queue)) { + struct tx_desc *entry = &ring->desc[ring->idx]; + struct sk_buff *skb = __skb_dequeue(&ring->queue); + + pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr), + skb->len, PCI_DMA_TODEVICE); + kfree_skb(skb); + ring->idx = (ring->idx + 1) % ring->entries; + } + + pci_free_consistent(priv->pdev, sizeof(*ring->desc)*ring->entries, + ring->desc, ring->dma); + ring->desc = NULL; +} + +void rtl8192_data_hard_stop(struct net_device *dev) +{ +} + + +void rtl8192_data_hard_resume(struct net_device *dev) +{ +} + +void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, + int rate) +{ + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + int ret; + struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + + MAX_DEV_ADDR_SIZE); + u8 queue_index = tcb_desc->queue_index; + + if ((priv->rtllib->eRFPowerState == eRfOff) || IS_NIC_DOWN(priv) || + priv->bResetInProgress) { + kfree_skb(skb); + return; + } + + assert(queue_index != TXCMD_QUEUE); + + + memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev)); + skb_push(skb, priv->rtllib->tx_headroom); + ret = rtl8192_tx(dev, skb); + if (ret != 0) { + kfree_skb(skb); + }; + + if (queue_index != MGNT_QUEUE) { + priv->rtllib->stats.tx_bytes += (skb->len - + priv->rtllib->tx_headroom); + priv->rtllib->stats.tx_packets++; + } + + + return; +} + +int rtl8192_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) +{ + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + int ret; + struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + + MAX_DEV_ADDR_SIZE); + u8 queue_index = tcb_desc->queue_index; + + if (queue_index != TXCMD_QUEUE) { + if ((priv->rtllib->eRFPowerState == eRfOff) || + IS_NIC_DOWN(priv) || priv->bResetInProgress) { + kfree_skb(skb); + return 0; + } + } + + memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev)); + if (queue_index == TXCMD_QUEUE) { + rtl8192_tx_cmd(dev, skb); + ret = 0; + return ret; + } else { + tcb_desc->RATRIndex = 7; + tcb_desc->bTxDisableRateFallBack = 1; + tcb_desc->bTxUseDriverAssingedRate = 1; + tcb_desc->bTxEnableFwCalcDur = 1; + skb_push(skb, priv->rtllib->tx_headroom); + ret = rtl8192_tx(dev, skb); + if (ret != 0) { + kfree_skb(skb); + }; + } + + + + return ret; + +} + +static void rtl8192_tx_isr(struct net_device *dev, int prio) +{ + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + + struct rtl8192_tx_ring *ring = &priv->tx_ring[prio]; + + while (skb_queue_len(&ring->queue)) { + struct tx_desc *entry = &ring->desc[ring->idx]; + struct sk_buff *skb; + + if (prio != BEACON_QUEUE) { + if (entry->OWN) + return; + ring->idx = (ring->idx + 1) % ring->entries; + } + + skb = __skb_dequeue(&ring->queue); + pci_unmap_single(priv->pdev, le32_to_cpu(entry->TxBuffAddr), + skb->len, PCI_DMA_TODEVICE); + + kfree_skb(skb); + } + if (prio != BEACON_QUEUE) + tasklet_schedule(&priv->irq_tx_tasklet); +} + +void rtl8192_tx_cmd(struct net_device *dev, struct sk_buff *skb) +{ + struct r8192_priv *priv = rtllib_priv(dev); + struct rtl8192_tx_ring *ring; + struct tx_desc_cmd *entry; + unsigned int idx; + struct cb_desc *tcb_desc; + unsigned long flags; + + spin_lock_irqsave(&priv->irq_th_lock, flags); + ring = &priv->tx_ring[TXCMD_QUEUE]; + + idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries; + entry = (struct tx_desc_cmd *) &ring->desc[idx]; + + tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); + + priv->ops->tx_fill_cmd_descriptor(dev, entry, tcb_desc, skb); + + __skb_queue_tail(&ring->queue, skb); + spin_unlock_irqrestore(&priv->irq_th_lock, flags); + + return; +} + +short rtl8192_tx(struct net_device *dev, struct sk_buff *skb) +{ + struct r8192_priv *priv = rtllib_priv(dev); + struct rtl8192_tx_ring *ring; + unsigned long flags; + struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + + MAX_DEV_ADDR_SIZE); + struct tx_desc *pdesc = NULL; + struct rtllib_hdr_1addr *header = NULL; + u16 fc = 0, type = 0, stype = 0; + bool multi_addr = false, broad_addr = false, uni_addr = false; + u8 *pda_addr = NULL; + int idx; + u32 fwinfo_size = 0; + + if (priv->bdisable_nic) { + RT_TRACE(COMP_ERR, "%s: ERR!! Nic is disabled! Can't tx packet" + " len=%d qidx=%d!!!\n", __func__, skb->len, + tcb_desc->queue_index); + return skb->len; + } + + priv->rtllib->bAwakePktSent = true; + + fwinfo_size = sizeof(struct tx_fwinfo_8190pci); + + header = (struct rtllib_hdr_1addr *)(((u8 *)skb->data) + fwinfo_size); + fc = header->frame_ctl; + type = WLAN_FC_GET_TYPE(fc); + stype = WLAN_FC_GET_STYPE(fc); + pda_addr = header->addr1; + + if (is_multicast_ether_addr(pda_addr)) + multi_addr = true; + else if (is_broadcast_ether_addr(pda_addr)) + broad_addr = true; + else + uni_addr = true; + + if (uni_addr) + priv->stats.txbytesunicast += skb->len - fwinfo_size; + else if (multi_addr) + priv->stats.txbytesmulticast += skb->len - fwinfo_size; + else + priv->stats.txbytesbroadcast += skb->len - fwinfo_size; + + spin_lock_irqsave(&priv->irq_th_lock, flags); + ring = &priv->tx_ring[tcb_desc->queue_index]; + if (tcb_desc->queue_index != BEACON_QUEUE) + idx = (ring->idx + skb_queue_len(&ring->queue)) % ring->entries; + else + idx = 0; + + pdesc = &ring->desc[idx]; + if ((pdesc->OWN == 1) && (tcb_desc->queue_index != BEACON_QUEUE)) { + RT_TRACE(COMP_ERR, "No more TX desc@%d, ring->idx = %d, idx = " + "%d, skblen = 0x%x queuelen=%d", + tcb_desc->queue_index, ring->idx, idx, skb->len, + skb_queue_len(&ring->queue)); + spin_unlock_irqrestore(&priv->irq_th_lock, flags); + return skb->len; + } + + if (type == RTLLIB_FTYPE_DATA) { + if (priv->rtllib->LedControlHandler) + priv->rtllib->LedControlHandler(dev, LED_CTL_TX); + } + priv->ops->tx_fill_descriptor(dev, pdesc, tcb_desc, skb); + __skb_queue_tail(&ring->queue, skb); + pdesc->OWN = 1; + spin_unlock_irqrestore(&priv->irq_th_lock, flags); + dev->trans_start = jiffies; + + write_nic_word(dev, TPPoll, 0x01 << tcb_desc->queue_index); + return 0; +} + +static short rtl8192_alloc_rx_desc_ring(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + struct rx_desc *entry = NULL; + int i, rx_queue_idx; + + for (rx_queue_idx = 0; rx_queue_idx < MAX_RX_QUEUE; rx_queue_idx++) { + priv->rx_ring[rx_queue_idx] = pci_alloc_consistent(priv->pdev, + sizeof(*priv->rx_ring[rx_queue_idx]) * + priv->rxringcount, + &priv->rx_ring_dma[rx_queue_idx]); + + if (!priv->rx_ring[rx_queue_idx] || + (unsigned long)priv->rx_ring[rx_queue_idx] & 0xFF) { + RT_TRACE(COMP_ERR, "Cannot allocate RX ring\n"); + return -ENOMEM; + } + + memset(priv->rx_ring[rx_queue_idx], 0, + sizeof(*priv->rx_ring[rx_queue_idx]) * + priv->rxringcount); + priv->rx_idx[rx_queue_idx] = 0; + + for (i = 0; i < priv->rxringcount; i++) { + struct sk_buff *skb = dev_alloc_skb(priv->rxbuffersize); + dma_addr_t *mapping; + entry = &priv->rx_ring[rx_queue_idx][i]; + if (!skb) + return 0; + skb->dev = dev; + priv->rx_buf[rx_queue_idx][i] = skb; + mapping = (dma_addr_t *)skb->cb; + *mapping = pci_map_single(priv->pdev, + skb_tail_pointer_rsl(skb), + priv->rxbuffersize, + PCI_DMA_FROMDEVICE); + + entry->BufferAddress = cpu_to_le32(*mapping); + + entry->Length = priv->rxbuffersize; + entry->OWN = 1; + } + + entry->EOR = 1; + } + return 0; +} + +static int rtl8192_alloc_tx_desc_ring(struct net_device *dev, + unsigned int prio, unsigned int entries) +{ + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + struct tx_desc *ring; + dma_addr_t dma; + int i; + + ring = pci_alloc_consistent(priv->pdev, sizeof(*ring) * entries, &dma); + if (!ring || (unsigned long)ring & 0xFF) { + RT_TRACE(COMP_ERR, "Cannot allocate TX ring (prio = %d)\n", + prio); + return -ENOMEM; + } + + memset(ring, 0, sizeof(*ring)*entries); + priv->tx_ring[prio].desc = ring; + priv->tx_ring[prio].dma = dma; + priv->tx_ring[prio].idx = 0; + priv->tx_ring[prio].entries = entries; + skb_queue_head_init(&priv->tx_ring[prio].queue); + + for (i = 0; i < entries; i++) + ring[i].NextDescAddress = + cpu_to_le32((u32)dma + ((i + 1) % entries) * + sizeof(*ring)); + + return 0; +} + + +short rtl8192_pci_initdescring(struct net_device *dev) +{ + u32 ret; + int i; + struct r8192_priv *priv = rtllib_priv(dev); + + ret = rtl8192_alloc_rx_desc_ring(dev); + if (ret) + return ret; + + for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) { + ret = rtl8192_alloc_tx_desc_ring(dev, i, priv->txringcount); + if (ret) + goto err_free_rings; + } + + return 0; + +err_free_rings: + rtl8192_free_rx_ring(dev); + for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) + if (priv->tx_ring[i].desc) + rtl8192_free_tx_ring(dev, i); + return 1; +} + +void rtl8192_pci_resetdescring(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + int i, rx_queue_idx; + unsigned long flags = 0; + + for (rx_queue_idx = 0; rx_queue_idx < MAX_RX_QUEUE; rx_queue_idx++) { + if (priv->rx_ring[rx_queue_idx]) { + struct rx_desc *entry = NULL; + for (i = 0; i < priv->rxringcount; i++) { + entry = &priv->rx_ring[rx_queue_idx][i]; + entry->OWN = 1; + } + priv->rx_idx[rx_queue_idx] = 0; + } + } + + spin_lock_irqsave(&priv->irq_th_lock, flags); + for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) { + if (priv->tx_ring[i].desc) { + struct rtl8192_tx_ring *ring = &priv->tx_ring[i]; + + while (skb_queue_len(&ring->queue)) { + struct tx_desc *entry = &ring->desc[ring->idx]; + struct sk_buff *skb = + __skb_dequeue(&ring->queue); + + pci_unmap_single(priv->pdev, + le32_to_cpu(entry->TxBuffAddr), + skb->len, PCI_DMA_TODEVICE); + kfree_skb(skb); + ring->idx = (ring->idx + 1) % ring->entries; + } + ring->idx = 0; + } + } + spin_unlock_irqrestore(&priv->irq_th_lock, flags); +} + +void rtl819x_UpdateRxPktTimeStamp(struct net_device *dev, + struct rtllib_rx_stats *stats) +{ + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + + if (stats->bIsAMPDU && !stats->bFirstMPDU) + stats->mac_time = priv->LastRxDescTSF; + else + priv->LastRxDescTSF = stats->mac_time; +} + +long rtl819x_translate_todbm(struct r8192_priv *priv, u8 signal_strength_index) +{ + long signal_power; + + signal_power = (long)((signal_strength_index + 1) >> 1); + signal_power -= 95; + + return signal_power; +} + + +void +rtl819x_update_rxsignalstatistics8190pci( + struct r8192_priv *priv, + struct rtllib_rx_stats *pprevious_stats + ) +{ + int weighting = 0; + + + if (priv->stats.recv_signal_power == 0) + priv->stats.recv_signal_power = + pprevious_stats->RecvSignalPower; + + if (pprevious_stats->RecvSignalPower > priv->stats.recv_signal_power) + weighting = 5; + else if (pprevious_stats->RecvSignalPower < + priv->stats.recv_signal_power) + weighting = (-5); + priv->stats.recv_signal_power = (priv->stats.recv_signal_power * 5 + + pprevious_stats->RecvSignalPower + + weighting) / 6; +} + +void rtl819x_process_cck_rxpathsel(struct r8192_priv *priv, + struct rtllib_rx_stats *pprevious_stats) +{ +} + + +u8 rtl819x_query_rxpwrpercentage(char antpower) +{ + if ((antpower <= -100) || (antpower >= 20)) + return 0; + else if (antpower >= 0) + return 100; + else + return 100 + antpower; + +} /* QueryRxPwrPercentage */ + +u8 +rtl819x_evm_dbtopercentage( + char value + ) +{ + char ret_val; + + ret_val = value; + + if (ret_val >= 0) + ret_val = 0; + if (ret_val <= -33) + ret_val = -33; + ret_val = 0 - ret_val; + ret_val *= 3; + if (ret_val == 99) + ret_val = 100; + return ret_val; +} + +void +rtl8192_record_rxdesc_forlateruse( + struct rtllib_rx_stats *psrc_stats, + struct rtllib_rx_stats *ptarget_stats +) +{ + ptarget_stats->bIsAMPDU = psrc_stats->bIsAMPDU; + ptarget_stats->bFirstMPDU = psrc_stats->bFirstMPDU; +} + + + +static void rtl8192_rx_normal(struct net_device *dev) +{ + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + struct rtllib_hdr_1addr *rtllib_hdr = NULL; + bool unicast_packet = false; + bool bLedBlinking = true; + u16 fc = 0, type = 0; + u32 skb_len = 0; + int rx_queue_idx = RX_MPDU_QUEUE; + + struct rtllib_rx_stats stats = { + .signal = 0, + .noise = -98, + .rate = 0, + .freq = RTLLIB_24GHZ_BAND, + }; + unsigned int count = priv->rxringcount; + + stats.nic_type = NIC_8192E; + + while (count--) { + struct rx_desc *pdesc = &priv->rx_ring[rx_queue_idx] + [priv->rx_idx[rx_queue_idx]]; + struct sk_buff *skb = priv->rx_buf[rx_queue_idx] + [priv->rx_idx[rx_queue_idx]]; + + if (pdesc->OWN) { + return; + } else { + struct sk_buff *new_skb; + + if (!priv->ops->rx_query_status_descriptor(dev, &stats, + pdesc, skb)) + goto done; + new_skb = dev_alloc_skb(priv->rxbuffersize); + /* if allocation of new skb failed - drop current packet + * and reuse skb */ + if (unlikely(!new_skb)) + goto done; + + pci_unmap_single(priv->pdev, + *((dma_addr_t *)skb->cb), + priv->rxbuffersize, + PCI_DMA_FROMDEVICE); + + skb_put(skb, pdesc->Length); + skb_reserve(skb, stats.RxDrvInfoSize + + stats.RxBufShift); + skb_trim(skb, skb->len - 4/*sCrcLng*/); + rtllib_hdr = (struct rtllib_hdr_1addr *)skb->data; + if (!is_broadcast_ether_addr(rtllib_hdr->addr1) && + !is_multicast_ether_addr(rtllib_hdr->addr1)) { + /* unicast packet */ + unicast_packet = true; + } + fc = le16_to_cpu(rtllib_hdr->frame_ctl); + type = WLAN_FC_GET_TYPE(fc); + if (type == RTLLIB_FTYPE_MGMT) + bLedBlinking = false; + + if (bLedBlinking) + if (priv->rtllib->LedControlHandler) + priv->rtllib->LedControlHandler(dev, + LED_CTL_RX); + + if (stats.bCRC) { + if (type != RTLLIB_FTYPE_MGMT) + priv->stats.rxdatacrcerr++; + else + priv->stats.rxmgmtcrcerr++; + } + + skb_len = skb->len; + + if (!rtllib_rx(priv->rtllib, skb, &stats)) { + dev_kfree_skb_any(skb); + } else { + priv->stats.rxok++; + if (unicast_packet) + priv->stats.rxbytesunicast += skb_len; + } + + skb = new_skb; + skb->dev = dev; + + priv->rx_buf[rx_queue_idx][priv->rx_idx[rx_queue_idx]] = + skb; + *((dma_addr_t *) skb->cb) = pci_map_single(priv->pdev, + skb_tail_pointer_rsl(skb), + priv->rxbuffersize, + PCI_DMA_FROMDEVICE); + + } +done: + pdesc->BufferAddress = cpu_to_le32(*((dma_addr_t *)skb->cb)); + pdesc->OWN = 1; + pdesc->Length = priv->rxbuffersize; + if (priv->rx_idx[rx_queue_idx] == priv->rxringcount-1) + pdesc->EOR = 1; + priv->rx_idx[rx_queue_idx] = (priv->rx_idx[rx_queue_idx] + 1) % + priv->rxringcount; + } + +} + +static void rtl8192_rx_cmd(struct net_device *dev) +{ +} + + +static void rtl8192_tx_resume(struct net_device *dev) +{ + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + struct rtllib_device *ieee = priv->rtllib; + struct sk_buff *skb; + int queue_index; + + for (queue_index = BK_QUEUE; + queue_index < MAX_QUEUE_SIZE; queue_index++) { + while ((!skb_queue_empty(&ieee->skb_waitQ[queue_index])) && + (priv->rtllib->check_nic_enough_desc(dev, queue_index) > 0)) { + skb = skb_dequeue(&ieee->skb_waitQ[queue_index]); + ieee->softmac_data_hard_start_xmit(skb, dev, 0); + } + } +} + +void rtl8192_irq_tx_tasklet(struct r8192_priv *priv) +{ + rtl8192_tx_resume(priv->rtllib->dev); +} + +void rtl8192_irq_rx_tasklet(struct r8192_priv *priv) +{ + rtl8192_rx_normal(priv->rtllib->dev); + + if (MAX_RX_QUEUE > 1) + rtl8192_rx_cmd(priv->rtllib->dev); + + write_nic_dword(priv->rtllib->dev, INTA_MASK, + read_nic_dword(priv->rtllib->dev, INTA_MASK) | IMR_RDU); +} + +/**************************************************************************** + ---------------------------- NIC START/CLOSE STUFF--------------------------- +*****************************************************************************/ +void rtl8192_cancel_deferred_work(struct r8192_priv *priv) +{ + cancel_delayed_work(&priv->watch_dog_wq); + cancel_delayed_work(&priv->update_beacon_wq); + cancel_delayed_work(&priv->rtllib->hw_sleep_wq); + cancel_work_sync(&priv->reset_wq); + cancel_work_sync(&priv->qos_activate); +} + +int _rtl8192_up(struct net_device *dev, bool is_silent_reset) +{ + if (_rtl8192_sta_up(dev, is_silent_reset) == -1) + return -1; + return 0; +} + + +static int rtl8192_open(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + int ret; + + down(&priv->wx_sem); + ret = rtl8192_up(dev); + up(&priv->wx_sem); + return ret; + +} + + +int rtl8192_up(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + if (priv->up == 1) + return -1; + return _rtl8192_up(dev, false); +} + + +static int rtl8192_close(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + int ret; + + if ((rtllib_act_scanning(priv->rtllib, false)) && + !(priv->rtllib->softmac_features & IEEE_SOFTMAC_SCAN)) { + rtllib_stop_scan(priv->rtllib); + } + + down(&priv->wx_sem); + + ret = rtl8192_down(dev, true); + + up(&priv->wx_sem); + + return ret; + +} + +int rtl8192_down(struct net_device *dev, bool shutdownrf) +{ + if (rtl8192_sta_down(dev, shutdownrf) == -1) + return -1; + + return 0; +} + +void rtl8192_commit(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + if (priv->up == 0) + return; + rtllib_softmac_stop_protocol(priv->rtllib, 0 , true); + rtl8192_irq_disable(dev); + priv->ops->stop_adapter(dev, true); + _rtl8192_up(dev, false); +} + +void rtl8192_restart(void *data) +{ + struct r8192_priv *priv = container_of_work_rsl(data, struct r8192_priv, + reset_wq); + struct net_device *dev = priv->rtllib->dev; + + down(&priv->wx_sem); + + rtl8192_commit(dev); + + up(&priv->wx_sem); +} + +static void r8192_set_multicast(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + short promisc; + + promisc = (dev->flags & IFF_PROMISC) ? 1 : 0; + priv->promisc = promisc; + +} + + +static int r8192_set_mac_adr(struct net_device *dev, void *mac) +{ + struct r8192_priv *priv = rtllib_priv(dev); + struct sockaddr *addr = mac; + + down(&priv->wx_sem); + + memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); + + schedule_work(&priv->reset_wq); + up(&priv->wx_sem); + + return 0; +} + +/* based on ipw2200 driver */ +static int rtl8192_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +{ + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + struct iwreq *wrq = (struct iwreq *)rq; + int ret = -1; + struct rtllib_device *ieee = priv->rtllib; + u32 key[4]; + u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + u8 zero_addr[6] = {0}; + struct iw_point *p = &wrq->u.data; + struct ieee_param *ipw = NULL; + + down(&priv->wx_sem); + + switch (cmd) { + case RTL_IOCTL_WPA_SUPPLICANT: + if (p->length < sizeof(struct ieee_param) || !p->pointer) { + ret = -EINVAL; + goto out; + } + + ipw = kmalloc(p->length, GFP_KERNEL); + if (ipw == NULL) { + ret = -ENOMEM; + goto out; + } + if (copy_from_user(ipw, p->pointer, p->length)) { + kfree(ipw); + ret = -EFAULT; + goto out; + } + + if (ipw->cmd == IEEE_CMD_SET_ENCRYPTION) { + if (ipw->u.crypt.set_tx) { + if (strcmp(ipw->u.crypt.alg, "CCMP") == 0) + ieee->pairwise_key_type = KEY_TYPE_CCMP; + else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0) + ieee->pairwise_key_type = KEY_TYPE_TKIP; + else if (strcmp(ipw->u.crypt.alg, "WEP") == 0) { + if (ipw->u.crypt.key_len == 13) + ieee->pairwise_key_type = + KEY_TYPE_WEP104; + else if (ipw->u.crypt.key_len == 5) + ieee->pairwise_key_type = + KEY_TYPE_WEP40; + } else { + ieee->pairwise_key_type = KEY_TYPE_NA; + } + + if (ieee->pairwise_key_type) { + if (memcmp(ieee->ap_mac_addr, zero_addr, + 6) == 0) + ieee->iw_mode = IW_MODE_ADHOC; + memcpy((u8 *)key, ipw->u.crypt.key, 16); + EnableHWSecurityConfig8192(dev); + set_swcam(dev, 4, ipw->u.crypt.idx, + ieee->pairwise_key_type, + (u8 *)ieee->ap_mac_addr, + 0, key, 0); + setKey(dev, 4, ipw->u.crypt.idx, + ieee->pairwise_key_type, + (u8 *)ieee->ap_mac_addr, 0, key); + if (ieee->iw_mode == IW_MODE_ADHOC) { + set_swcam(dev, ipw->u.crypt.idx, + ipw->u.crypt.idx, + ieee->pairwise_key_type, + (u8 *)ieee->ap_mac_addr, + 0, key, 0); + setKey(dev, ipw->u.crypt.idx, + ipw->u.crypt.idx, + ieee->pairwise_key_type, + (u8 *)ieee->ap_mac_addr, + 0, key); + } + } + if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) + && ieee->pHTInfo->bCurrentHTSupport) { + write_nic_byte(dev, 0x173, 1); + } + + } else { + memcpy((u8 *)key, ipw->u.crypt.key, 16); + if (strcmp(ipw->u.crypt.alg, "CCMP") == 0) + ieee->group_key_type = KEY_TYPE_CCMP; + else if (strcmp(ipw->u.crypt.alg, "TKIP") == 0) + ieee->group_key_type = KEY_TYPE_TKIP; + else if (strcmp(ipw->u.crypt.alg, "WEP") == 0) { + if (ipw->u.crypt.key_len == 13) + ieee->group_key_type = + KEY_TYPE_WEP104; + else if (ipw->u.crypt.key_len == 5) + ieee->group_key_type = + KEY_TYPE_WEP40; + } else + ieee->group_key_type = KEY_TYPE_NA; + + if (ieee->group_key_type) { + set_swcam(dev, ipw->u.crypt.idx, + ipw->u.crypt.idx, + ieee->group_key_type, + broadcast_addr, 0, key, 0); + setKey(dev, ipw->u.crypt.idx, + ipw->u.crypt.idx, + ieee->group_key_type, + broadcast_addr, 0, key); + } + } + } + + ret = rtllib_wpa_supplicant_ioctl(priv->rtllib, &wrq->u.data, + 0); + kfree(ipw); + break; + default: + ret = -EOPNOTSUPP; + break; + } + +out: + up(&priv->wx_sem); + + return ret; +} + + +irqreturn_type rtl8192_interrupt(int irq, void *netdev, struct pt_regs *regs) +{ + struct net_device *dev = (struct net_device *) netdev; + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + unsigned long flags; + u32 inta; + u32 intb; + intb = 0; + + if (priv->irq_enabled == 0) + goto done; + + spin_lock_irqsave(&priv->irq_th_lock, flags); + + priv->ops->interrupt_recognized(dev, &inta, &intb); + priv->stats.shints++; + + if (!inta) { + spin_unlock_irqrestore(&priv->irq_th_lock, flags); + goto done; + } + + if (inta == 0xffff) { + spin_unlock_irqrestore(&priv->irq_th_lock, flags); + goto done; + } + + priv->stats.ints++; + + if (!netif_running(dev)) { + spin_unlock_irqrestore(&priv->irq_th_lock, flags); + goto done; + } + + if (inta & IMR_TBDOK) { + RT_TRACE(COMP_INTR, "beacon ok interrupt!\n"); + priv->stats.txbeaconokint++; + } + + if (inta & IMR_TBDER) { + RT_TRACE(COMP_INTR, "beacon ok interrupt!\n"); + priv->stats.txbeaconerr++; + } + + if (inta & IMR_BDOK) + RT_TRACE(COMP_INTR, "beacon interrupt!\n"); + + if (inta & IMR_MGNTDOK) { + RT_TRACE(COMP_INTR, "Manage ok interrupt!\n"); + priv->stats.txmanageokint++; + rtl8192_tx_isr(dev, MGNT_QUEUE); + spin_unlock_irqrestore(&priv->irq_th_lock, flags); + if (priv->rtllib->ack_tx_to_ieee) { + if (rtl8192_is_tx_queue_empty(dev)) { + priv->rtllib->ack_tx_to_ieee = 0; + rtllib_ps_tx_ack(priv->rtllib, 1); + } + } + spin_lock_irqsave(&priv->irq_th_lock, flags); + } + + if (inta & IMR_COMDOK) { + priv->stats.txcmdpktokint++; + rtl8192_tx_isr(dev, TXCMD_QUEUE); + } + + if (inta & IMR_HIGHDOK) + rtl8192_tx_isr(dev, HIGH_QUEUE); + + if (inta & IMR_ROK) { + priv->stats.rxint++; + priv->InterruptLog.nIMR_ROK++; + tasklet_schedule(&priv->irq_rx_tasklet); + } + + if (inta & IMR_BcnInt) { + RT_TRACE(COMP_INTR, "prepare beacon for interrupt!\n"); + tasklet_schedule(&priv->irq_prepare_beacon_tasklet); + } + + if (inta & IMR_RDU) { + RT_TRACE(COMP_INTR, "rx descriptor unavailable!\n"); + priv->stats.rxrdu++; + write_nic_dword(dev, INTA_MASK, + read_nic_dword(dev, INTA_MASK) & ~IMR_RDU); + tasklet_schedule(&priv->irq_rx_tasklet); + } + + if (inta & IMR_RXFOVW) { + RT_TRACE(COMP_INTR, "rx overflow !\n"); + priv->stats.rxoverflow++; + tasklet_schedule(&priv->irq_rx_tasklet); + } + + if (inta & IMR_TXFOVW) + priv->stats.txoverflow++; + + if (inta & IMR_BKDOK) { + RT_TRACE(COMP_INTR, "BK Tx OK interrupt!\n"); + priv->stats.txbkokint++; + priv->rtllib->LinkDetectInfo.NumTxOkInPeriod++; + rtl8192_tx_isr(dev, BK_QUEUE); + } + + if (inta & IMR_BEDOK) { + RT_TRACE(COMP_INTR, "BE TX OK interrupt!\n"); + priv->stats.txbeokint++; + priv->rtllib->LinkDetectInfo.NumTxOkInPeriod++; + rtl8192_tx_isr(dev, BE_QUEUE); + } + + if (inta & IMR_VIDOK) { + RT_TRACE(COMP_INTR, "VI TX OK interrupt!\n"); + priv->stats.txviokint++; + priv->rtllib->LinkDetectInfo.NumTxOkInPeriod++; + rtl8192_tx_isr(dev, VI_QUEUE); + } + + if (inta & IMR_VODOK) { + priv->stats.txvookint++; + RT_TRACE(COMP_INTR, "Vo TX OK interrupt!\n"); + priv->rtllib->LinkDetectInfo.NumTxOkInPeriod++; + rtl8192_tx_isr(dev, VO_QUEUE); + } + + spin_unlock_irqrestore(&priv->irq_th_lock, flags); + +done: + + return IRQ_HANDLED; +} + + + +/**************************************************************************** + ---------------------------- PCI_STUFF--------------------------- +*****************************************************************************/ +#ifdef HAVE_NET_DEVICE_OPS +static const struct net_device_ops rtl8192_netdev_ops = { + .ndo_open = rtl8192_open, + .ndo_stop = rtl8192_close, + .ndo_tx_timeout = rtl8192_tx_timeout, + .ndo_do_ioctl = rtl8192_ioctl, + .ndo_set_rx_mode = r8192_set_multicast, + .ndo_set_mac_address = r8192_set_mac_adr, + .ndo_validate_addr = eth_validate_addr, + .ndo_change_mtu = eth_change_mtu, + .ndo_start_xmit = rtllib_xmit, +}; +#endif + +static int __devinit rtl8192_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *id) +{ + unsigned long ioaddr = 0; + struct net_device *dev = NULL; + struct r8192_priv *priv = NULL; + struct rtl819x_ops *ops = (struct rtl819x_ops *)(id->driver_data); + unsigned long pmem_start, pmem_len, pmem_flags; + int err = 0; + bool bdma64 = false; + u8 revision_id; + + RT_TRACE(COMP_INIT, "Configuring chip resources"); + + if (pci_enable_device(pdev)) { + RT_TRACE(COMP_ERR, "Failed to enable PCI device"); + return -EIO; + } + + pci_set_master(pdev); + + if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { + if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) { + printk(KERN_INFO "Unable to obtain 32bit DMA for consistent allocations\n"); + pci_disable_device(pdev); + return -ENOMEM; + } + } + dev = alloc_rtllib(sizeof(struct r8192_priv)); + if (!dev) + return -ENOMEM; + + if (bdma64) + dev->features |= NETIF_F_HIGHDMA; + + pci_set_drvdata(pdev, dev); + SET_NETDEV_DEV(dev, &pdev->dev); + priv = rtllib_priv(dev); + priv->rtllib = (struct rtllib_device *)netdev_priv_rsl(dev); + priv->pdev = pdev; + priv->rtllib->pdev = pdev; + if ((pdev->subsystem_vendor == PCI_VENDOR_ID_DLINK) && + (pdev->subsystem_device == 0x3304)) + priv->rtllib->bSupportRemoteWakeUp = 1; + else + priv->rtllib->bSupportRemoteWakeUp = 0; + + pmem_start = pci_resource_start(pdev, 1); + pmem_len = pci_resource_len(pdev, 1); + pmem_flags = pci_resource_flags(pdev, 1); + + if (!(pmem_flags & IORESOURCE_MEM)) { + RT_TRACE(COMP_ERR, "region #1 not a MMIO resource, aborting"); + goto fail; + } + + printk(KERN_INFO "Memory mapped space start: 0x%08lx\n", pmem_start); + if (!request_mem_region(pmem_start, pmem_len, DRV_NAME)) { + RT_TRACE(COMP_ERR, "request_mem_region failed!"); + goto fail; + } + + + ioaddr = (unsigned long)ioremap_nocache(pmem_start, pmem_len); + if (ioaddr == (unsigned long)NULL) { + RT_TRACE(COMP_ERR, "ioremap failed!"); + goto fail1; + } + + dev->mem_start = ioaddr; + dev->mem_end = ioaddr + pci_resource_len(pdev, 0); + + pci_read_config_byte(pdev, 0x08, &revision_id); + /* If the revisionid is 0x10, the device uses rtl8192se. */ + if (pdev->device == 0x8192 && revision_id == 0x10) + goto fail1; + + priv->ops = ops; + + if (rtl8192_pci_findadapter(pdev, dev) == false) + goto fail1; + + dev->irq = pdev->irq; + priv->irq = 0; + +#ifdef HAVE_NET_DEVICE_OPS + dev->netdev_ops = &rtl8192_netdev_ops; +#else + dev->open = rtl8192_open; + dev->stop = rtl8192_close; + dev->tx_timeout = rtl8192_tx_timeout; + dev->do_ioctl = rtl8192_ioctl; + dev->set_multicast_list = r8192_set_multicast; + dev->set_mac_address = r8192_set_mac_adr; + dev->hard_start_xmit = rtllib_xmit; +#endif + + dev->wireless_handlers = (struct iw_handler_def *) + &r8192_wx_handlers_def; + dev->ethtool_ops = &rtl819x_ethtool_ops; + + dev->type = ARPHRD_ETHER; + dev->watchdog_timeo = HZ * 3; + + if (dev_alloc_name(dev, ifname) < 0) { + RT_TRACE(COMP_INIT, "Oops: devname already taken! Trying " + "wlan%%d...\n"); + dev_alloc_name(dev, ifname); + } + + RT_TRACE(COMP_INIT, "Driver probe completed1\n"); + if (rtl8192_init(dev) != 0) { + RT_TRACE(COMP_ERR, "Initialization failed"); + goto fail1; + } + + netif_carrier_off(dev); + netif_stop_queue(dev); + + register_netdev(dev); + RT_TRACE(COMP_INIT, "dev name: %s\n", dev->name); + err = rtl_debug_module_init(priv, dev->name); + if (err) + RT_TRACE(COMP_DBG, "failed to create debugfs files. Ignoring " + "error: %d\n", err); + rtl8192_proc_init_one(dev); + + if (priv->polling_timer_on == 0) + check_rfctrl_gpio_timer((unsigned long)dev); + + RT_TRACE(COMP_INIT, "Driver probe completed\n"); + return 0; + +fail1: + if (dev->mem_start != (unsigned long)NULL) { + iounmap((void *)dev->mem_start); + release_mem_region(pci_resource_start(pdev, 1), + pci_resource_len(pdev, 1)); + } + +fail: + if (dev) { + if (priv->irq) { + free_irq(dev->irq, dev); + priv->irq = 0; + } + free_rtllib(dev); + } + + pci_disable_device(pdev); + + DMESG("wlan driver load failed\n"); + pci_set_drvdata(pdev, NULL); + return -ENODEV; + +} + +static void __devexit rtl8192_pci_disconnect(struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct r8192_priv *priv ; + u32 i; + + if (dev) { + unregister_netdev(dev); + + priv = rtllib_priv(dev); + + del_timer_sync(&priv->gpio_polling_timer); + cancel_delayed_work(&priv->gpio_change_rf_wq); + priv->polling_timer_on = 0; + rtl_debug_module_remove(priv); + rtl8192_proc_remove_one(dev); + rtl8192_down(dev, true); + deinit_hal_dm(dev); + if (priv->pFirmware) { + vfree(priv->pFirmware); + priv->pFirmware = NULL; + } + destroy_workqueue(priv->priv_wq); + rtl8192_free_rx_ring(dev); + for (i = 0; i < MAX_TX_QUEUE_COUNT; i++) + rtl8192_free_tx_ring(dev, i); + + if (priv->irq) { + printk(KERN_INFO "Freeing irq %d\n", dev->irq); + free_irq(dev->irq, dev); + priv->irq = 0; + } + free_rtllib(dev); + + kfree(priv->scan_cmd); + + if (dev->mem_start != 0) { + iounmap((void __iomem *)dev->mem_start); + release_mem_region(pci_resource_start(pdev, 1), + pci_resource_len(pdev, 1)); + } + } else { + priv = rtllib_priv(dev); + } + + pci_disable_device(pdev); + RT_TRACE(COMP_DOWN, "wlan driver removed\n"); +} + +bool NicIFEnableNIC(struct net_device *dev) +{ + bool init_status = true; + struct r8192_priv *priv = rtllib_priv(dev); + struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) + (&(priv->rtllib->PowerSaveControl)); + + if (IS_NIC_DOWN(priv)) { + RT_TRACE(COMP_ERR, "ERR!!! %s(): Driver is already down!\n", + __func__); + priv->bdisable_nic = false; + return RT_STATUS_FAILURE; + } + + RT_TRACE(COMP_PS, "===========>%s()\n", __func__); + priv->bfirst_init = true; + init_status = priv->ops->initialize_adapter(dev); + if (init_status != true) { + RT_TRACE(COMP_ERR, "ERR!!! %s(): initialization is failed!\n", + __func__); + priv->bdisable_nic = false; + return -1; + } + RT_TRACE(COMP_INIT, "start adapter finished\n"); + RT_CLEAR_PS_LEVEL(pPSC, RT_RF_OFF_LEVL_HALT_NIC); + priv->bfirst_init = false; + + rtl8192_irq_enable(dev); + priv->bdisable_nic = false; + RT_TRACE(COMP_PS, "<===========%s()\n", __func__); + return init_status; +} +bool NicIFDisableNIC(struct net_device *dev) +{ + bool status = true; + struct r8192_priv *priv = rtllib_priv(dev); + u8 tmp_state = 0; + RT_TRACE(COMP_PS, "=========>%s()\n", __func__); + priv->bdisable_nic = true; + tmp_state = priv->rtllib->state; + rtllib_softmac_stop_protocol(priv->rtllib, 0, false); + priv->rtllib->state = tmp_state; + rtl8192_cancel_deferred_work(priv); + rtl8192_irq_disable(dev); + + priv->ops->stop_adapter(dev, false); + RT_TRACE(COMP_PS, "<=========%s()\n", __func__); + + return status; +} + +static int __init rtl8192_pci_module_init(void) +{ + int ret; + int error; + + ret = rtllib_init(); + if (ret) { + printk(KERN_ERR "rtllib_init() failed %d\n", ret); + return ret; + } + ret = rtllib_crypto_init(); + if (ret) { + printk(KERN_ERR "rtllib_crypto_init() failed %d\n", ret); + return ret; + } + ret = rtllib_crypto_tkip_init(); + if (ret) { + printk(KERN_ERR "rtllib_crypto_tkip_init() failed %d\n", ret); + return ret; + } + ret = rtllib_crypto_ccmp_init(); + if (ret) { + printk(KERN_ERR "rtllib_crypto_ccmp_init() failed %d\n", ret); + return ret; + } + ret = rtllib_crypto_wep_init(); + if (ret) { + printk(KERN_ERR "rtllib_crypto_wep_init() failed %d\n", ret); + return ret; + } + printk(KERN_INFO "\nLinux kernel driver for RTL8192E WLAN cards\n"); + printk(KERN_INFO "Copyright (c) 2007-2008, Realsil Wlan Driver\n"); + + error = rtl_create_debugfs_root(); + if (error) { + RT_TRACE(COMP_DBG, "Create debugfs root fail: %d\n", error); + goto err_out; + } + + rtl8192_proc_module_init(); + if (0 != pci_register_driver(&rtl8192_pci_driver)) { + DMESG("No device found"); + /*pci_unregister_driver (&rtl8192_pci_driver);*/ + return -ENODEV; + } + return 0; +err_out: + return error; + +} + +static void __exit rtl8192_pci_module_exit(void) +{ + pci_unregister_driver(&rtl8192_pci_driver); + + RT_TRACE(COMP_DOWN, "Exiting"); + rtl8192_proc_module_remove(); + rtl_remove_debugfs_root(); + rtllib_crypto_tkip_exit(); + rtllib_crypto_ccmp_exit(); + rtllib_crypto_wep_exit(); + rtllib_crypto_deinit(); + rtllib_exit(); +} + +void check_rfctrl_gpio_timer(unsigned long data) +{ + struct r8192_priv *priv = rtllib_priv((struct net_device *)data); + + priv->polling_timer_on = 1; + + queue_delayed_work_rsl(priv->priv_wq, &priv->gpio_change_rf_wq, 0); + + mod_timer(&priv->gpio_polling_timer, jiffies + + MSECS(RTLLIB_WATCH_DOG_TIME)); +} + +/*************************************************************************** + ------------------- module init / exit stubs ---------------- +****************************************************************************/ +module_init(rtl8192_pci_module_init); +module_exit(rtl8192_pci_module_exit); + +MODULE_DESCRIPTION("Linux driver for Realtek RTL819x WiFi cards"); +MODULE_AUTHOR(DRV_COPYRIGHT " " DRV_AUTHOR); +MODULE_VERSION(DRV_VERSION); +MODULE_LICENSE("GPL"); + +module_param(ifname, charp, S_IRUGO|S_IWUSR); +module_param(hwwep, int, S_IRUGO|S_IWUSR); +module_param(channels, int, S_IRUGO|S_IWUSR); + +MODULE_PARM_DESC(ifname, " Net interface name, wlan%d=default"); +MODULE_PARM_DESC(hwwep, " Try to use hardware WEP support(default use hw. set 0 to use software security)"); +MODULE_PARM_DESC(channels, " Channel bitmask for specific locales. NYI"); diff --git a/drivers/staging/rtl8192e/rtl_core.h b/drivers/staging/rtl8192e/rtl_core.h new file mode 100644 index 0000000..5b78530 --- /dev/null +++ b/drivers/staging/rtl8192e/rtl_core.h @@ -0,0 +1,1124 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * Based on the r8180 driver, which is: + * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al. + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> +******************************************************************************/ + +#ifndef _RTL_CORE_H +#define _RTL_CORE_H + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/ioport.h> +#include <linux/sched.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/slab.h> +#include <linux/netdevice.h> +#include <linux/pci.h> +#include <linux/etherdevice.h> +#include <linux/delay.h> +#include <linux/rtnetlink.h> +#include <linux/wireless.h> +#include <linux/timer.h> +#include <linux/proc_fs.h> +#include <linux/if_arp.h> +#include <linux/random.h> +#include <linux/version.h> +#include <linux/io.h> +#include "rtllib.h" + +#include "dot11d.h" + +#include "r8192E_firmware.h" +#include "r8192E_hw.h" + +#include "r8190P_def.h" +#include "r8192E_dev.h" + +#include "rtl_debug.h" +#include "rtl_eeprom.h" +#include "rtl_ps.h" +#include "rtl_pci.h" +#include "rtl_cam.h" + +#define DRV_COPYRIGHT \ + "Copyright(c) 2008 - 2010 Realsil Semiconductor Corporation" +#define DRV_AUTHOR "<wlanfae@realtek.com>" +#define DRV_VERSION "0014.0401.2010" + +#define DRV_NAME "rtl819xE" + +#define IS_HARDWARE_TYPE_819xP(_priv) \ + ((((struct r8192_priv *)rtllib_priv(dev))->card_8192 == NIC_8190P) || \ + (((struct r8192_priv *)rtllib_priv(dev))->card_8192 == NIC_8192E)) +#define IS_HARDWARE_TYPE_8192SE(_priv) \ + (((struct r8192_priv *)rtllib_priv(dev))->card_8192 == NIC_8192SE) +#define IS_HARDWARE_TYPE_8192CE(_priv) \ + (((struct r8192_priv *)rtllib_priv(dev))->card_8192 == NIC_8192CE) +#define IS_HARDWARE_TYPE_8192CU(_priv) \ + (((struct r8192_priv *)rtllib_priv(dev))->card_8192 == NIC_8192CU) +#define IS_HARDWARE_TYPE_8192DE(_priv) \ + (((struct r8192_priv *)rtllib_priv(dev))->card_8192 == NIC_8192DE) +#define IS_HARDWARE_TYPE_8192DU(_priv) \ + (((struct r8192_priv *)rtllib_priv(dev))->card_8192 == NIC_8192DU) + +#define RTL_PCI_DEVICE(vend, dev, cfg) \ + .vendor = (vend), .device = (dev), \ + .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID , \ + .driver_data = (kernel_ulong_t)&(cfg) + +#define irqreturn_type irqreturn_t + +#define rtl8192_interrupt(x, y, z) rtl8192_interrupt_rsl(x, y) + +#define RTL_MAX_SCAN_SIZE 128 + +#define RTL_RATE_MAX 30 + +#define TOTAL_CAM_ENTRY 32 +#define CAM_CONTENT_COUNT 8 + +#ifndef BIT +#define BIT(_i) (1<<(_i)) +#endif + +#define IS_NIC_DOWN(priv) (!(priv)->up) + +#define IS_ADAPTER_SENDS_BEACON(dev) 0 + +#define IS_UNDER_11N_AES_MODE(_rtllib) \ + ((_rtllib->pHTInfo->bCurrentHTSupport == true) && \ + (_rtllib->pairwise_key_type == KEY_TYPE_CCMP)) + +#define HAL_MEMORY_MAPPED_IO_RANGE_8190PCI 0x1000 +#define HAL_HW_PCI_REVISION_ID_8190PCI 0x00 +#define HAL_MEMORY_MAPPED_IO_RANGE_8192PCIE 0x4000 +#define HAL_HW_PCI_REVISION_ID_8192PCIE 0x01 +#define HAL_MEMORY_MAPPED_IO_RANGE_8192SE 0x4000 +#define HAL_HW_PCI_REVISION_ID_8192SE 0x10 +#define HAL_HW_PCI_REVISION_ID_8192CE 0x1 +#define HAL_MEMORY_MAPPED_IO_RANGE_8192CE 0x4000 +#define HAL_HW_PCI_REVISION_ID_8192DE 0x0 +#define HAL_MEMORY_MAPPED_IO_RANGE_8192DE 0x4000 + +#define HAL_HW_PCI_8180_DEVICE_ID 0x8180 +#define HAL_HW_PCI_8185_DEVICE_ID 0x8185 +#define HAL_HW_PCI_8188_DEVICE_ID 0x8188 +#define HAL_HW_PCI_8198_DEVICE_ID 0x8198 +#define HAL_HW_PCI_8190_DEVICE_ID 0x8190 +#define HAL_HW_PCI_8192_DEVICE_ID 0x8192 +#define HAL_HW_PCI_8192SE_DEVICE_ID 0x8192 +#define HAL_HW_PCI_8174_DEVICE_ID 0x8174 +#define HAL_HW_PCI_8173_DEVICE_ID 0x8173 +#define HAL_HW_PCI_8172_DEVICE_ID 0x8172 +#define HAL_HW_PCI_8171_DEVICE_ID 0x8171 +#define HAL_HW_PCI_0045_DEVICE_ID 0x0045 +#define HAL_HW_PCI_0046_DEVICE_ID 0x0046 +#define HAL_HW_PCI_0044_DEVICE_ID 0x0044 +#define HAL_HW_PCI_0047_DEVICE_ID 0x0047 +#define HAL_HW_PCI_700F_DEVICE_ID 0x700F +#define HAL_HW_PCI_701F_DEVICE_ID 0x701F +#define HAL_HW_PCI_DLINK_DEVICE_ID 0x3304 +#define HAL_HW_PCI_8192CET_DEVICE_ID 0x8191 +#define HAL_HW_PCI_8192CE_DEVICE_ID 0x8178 +#define HAL_HW_PCI_8191CE_DEVICE_ID 0x8177 +#define HAL_HW_PCI_8188CE_DEVICE_ID 0x8176 +#define HAL_HW_PCI_8192CU_DEVICE_ID 0x8191 +#define HAL_HW_PCI_8192DE_DEVICE_ID 0x092D +#define HAL_HW_PCI_8192DU_DEVICE_ID 0x092D + +#define RTL819X_DEFAULT_RF_TYPE RF_1T2R + +#define RTLLIB_WATCH_DOG_TIME 2000 + +#define MAX_DEV_ADDR_SIZE 8 /*support till 64 bit bus width OS*/ +#define MAX_FIRMWARE_INFORMATION_SIZE 32 +#define MAX_802_11_HEADER_LENGTH (40 + MAX_FIRMWARE_INFORMATION_SIZE) +#define ENCRYPTION_MAX_OVERHEAD 128 +#define MAX_FRAGMENT_COUNT 8 +#define MAX_TRANSMIT_BUFFER_SIZE \ + (1600 + (MAX_802_11_HEADER_LENGTH + ENCRYPTION_MAX_OVERHEAD) * \ + MAX_FRAGMENT_COUNT) + +#define scrclng 4 + +#define DEFAULT_FRAG_THRESHOLD 2342U +#define MIN_FRAG_THRESHOLD 256U +#define DEFAULT_BEACONINTERVAL 0x64U + +#define DEFAULT_SSID "" +#define DEFAULT_RETRY_RTS 7 +#define DEFAULT_RETRY_DATA 7 +#define PRISM_HDR_SIZE 64 + +#define PHY_RSSI_SLID_WIN_MAX 100 + +#define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV + 30) + +#define TxBBGainTableLength 37 +#define CCKTxBBGainTableLength 23 + +#define CHANNEL_PLAN_LEN 10 +#define sCrcLng 4 + +#define NIC_SEND_HANG_THRESHOLD_NORMAL 4 +#define NIC_SEND_HANG_THRESHOLD_POWERSAVE 8 + +#define MAX_TX_QUEUE 9 + +#define MAX_RX_QUEUE 1 + +#define MAX_RX_COUNT 64 +#define MAX_TX_QUEUE_COUNT 9 + +enum RTL819x_PHY_PARAM { + RTL819X_PHY_MACPHY_REG = 0, + RTL819X_PHY_MACPHY_REG_PG = 1, + RTL8188C_PHY_MACREG = 2, + RTL8192C_PHY_MACREG = 3, + RTL819X_PHY_REG = 4, + RTL819X_PHY_REG_1T2R = 5, + RTL819X_PHY_REG_to1T1R = 6, + RTL819X_PHY_REG_to1T2R = 7, + RTL819X_PHY_REG_to2T2R = 8, + RTL819X_PHY_REG_PG = 9, + RTL819X_AGC_TAB = 10, + RTL819X_PHY_RADIO_A = 11, + RTL819X_PHY_RADIO_A_1T = 12, + RTL819X_PHY_RADIO_A_2T = 13, + RTL819X_PHY_RADIO_B = 14, + RTL819X_PHY_RADIO_B_GM = 15, + RTL819X_PHY_RADIO_C = 16, + RTL819X_PHY_RADIO_D = 17, + RTL819X_EEPROM_MAP = 18, + RTL819X_EFUSE_MAP = 19, +}; + +enum RTL_DEBUG { + COMP_TRACE = BIT0, + COMP_DBG = BIT1, + COMP_INIT = BIT2, + COMP_RECV = BIT3, + COMP_SEND = BIT4, + COMP_CMD = BIT5, + COMP_POWER = BIT6, + COMP_EPROM = BIT7, + COMP_SWBW = BIT8, + COMP_SEC = BIT9, + COMP_LPS = BIT10, + COMP_QOS = BIT11, + COMP_RATE = BIT12, + COMP_RXDESC = BIT13, + COMP_PHY = BIT14, + COMP_DIG = BIT15, + COMP_TXAGC = BIT16, + COMP_HALDM = BIT17, + COMP_POWER_TRACKING = BIT18, + COMP_CH = BIT19, + COMP_RF = BIT20, + COMP_FIRMWARE = BIT21, + COMP_HT = BIT22, + COMP_RESET = BIT23, + COMP_CMDPKT = BIT24, + COMP_SCAN = BIT25, + COMP_PS = BIT26, + COMP_DOWN = BIT27, + COMP_INTR = BIT28, + COMP_LED = BIT29, + COMP_MLME = BIT30, + COMP_ERR = BIT31 +}; + +enum nic_t { + NIC_UNKNOWN = 0, + NIC_8192E = 1, + NIC_8190P = 2, + NIC_8192SE = 4, + NIC_8192CE = 5, + NIC_8192CU = 6, + NIC_8192DE = 7, + NIC_8192DU = 8, +}; + +enum rt_eeprom_type { + EEPROM_93C46, + EEPROM_93C56, + EEPROM_BOOT_EFUSE, +}; + +enum dcmg_txcmd_op { + TXCMD_TXRA_HISTORY_CTRL = 0xFF900000, + TXCMD_RESET_TX_PKT_BUFF = 0xFF900001, + TXCMD_RESET_RX_PKT_BUFF = 0xFF900002, + TXCMD_SET_TX_DURATION = 0xFF900003, + TXCMD_SET_RX_RSSI = 0xFF900004, + TXCMD_SET_TX_PWR_TRACKING = 0xFF900005, + TXCMD_XXXX_CTRL, +}; + +enum rt_rf_type_819xu { + RF_TYPE_MIN = 0, + RF_8225, + RF_8256, + RF_8258, + RF_6052 = 4, + RF_PSEUDO_11N = 5, +}; + +enum rf_step { + RF_STEP_INIT = 0, + RF_STEP_NORMAL, + RF_STEP_MAX +}; + +enum rt_status { + RT_STATUS_SUCCESS, + RT_STATUS_FAILURE, + RT_STATUS_PENDING, + RT_STATUS_RESOURCE +}; + +enum rt_customer_id { + RT_CID_DEFAULT = 0, + RT_CID_8187_ALPHA0 = 1, + RT_CID_8187_SERCOMM_PS = 2, + RT_CID_8187_HW_LED = 3, + RT_CID_8187_NETGEAR = 4, + RT_CID_WHQL = 5, + RT_CID_819x_CAMEO = 6, + RT_CID_819x_RUNTOP = 7, + RT_CID_819x_Senao = 8, + RT_CID_TOSHIBA = 9, + RT_CID_819x_Netcore = 10, + RT_CID_Nettronix = 11, + RT_CID_DLINK = 12, + RT_CID_PRONET = 13, + RT_CID_COREGA = 14, + RT_CID_819x_ALPHA = 15, + RT_CID_819x_Sitecom = 16, + RT_CID_CCX = 17, + RT_CID_819x_Lenovo = 18, + RT_CID_819x_QMI = 19, + RT_CID_819x_Edimax_Belkin = 20, + RT_CID_819x_Sercomm_Belkin = 21, + RT_CID_819x_CAMEO1 = 22, + RT_CID_819x_MSI = 23, + RT_CID_819x_Acer = 24, + RT_CID_819x_HP = 27, + RT_CID_819x_CLEVO = 28, + RT_CID_819x_Arcadyan_Belkin = 29, + RT_CID_819x_SAMSUNG = 30, + RT_CID_819x_WNC_COREGA = 31, +}; + +enum reset_type { + RESET_TYPE_NORESET = 0x00, + RESET_TYPE_NORMAL = 0x01, + RESET_TYPE_SILENT = 0x02 +}; + +enum ic_inferiority_8192s { + IC_INFERIORITY_A = 0, + IC_INFERIORITY_B = 1, +}; + +enum pci_bridge_vendor { + PCI_BRIDGE_VENDOR_INTEL = 0x0, + PCI_BRIDGE_VENDOR_ATI, + PCI_BRIDGE_VENDOR_AMD, + PCI_BRIDGE_VENDOR_SIS , + PCI_BRIDGE_VENDOR_UNKNOWN, + PCI_BRIDGE_VENDOR_MAX , +}; + +struct buffer { + struct buffer *next; + u32 *buf; + dma_addr_t dma; + +}; + +struct rtl_reg_debug { + unsigned int cmd; + struct { + unsigned char type; + unsigned char addr; + unsigned char page; + unsigned char length; + } head; + unsigned char buf[0xff]; +}; + +struct rt_tx_rahis { + u32 cck[4]; + u32 ofdm[8]; + u32 ht_mcs[4][16]; +}; + +struct rt_smooth_data_4rf { + char elements[4][100]; + u32 index; + u32 TotalNum; + u32 TotalVal[4]; +}; + +struct rt_stats { + unsigned long txrdu; + unsigned long rxrdu; + unsigned long rxok; + unsigned long rxframgment; + unsigned long rxcmdpkt[4]; + unsigned long rxurberr; + unsigned long rxstaterr; + unsigned long rxdatacrcerr; + unsigned long rxmgmtcrcerr; + unsigned long rxcrcerrmin; + unsigned long rxcrcerrmid; + unsigned long rxcrcerrmax; + unsigned long received_rate_histogram[4][32]; + unsigned long received_preamble_GI[2][32]; + unsigned long rx_AMPDUsize_histogram[5]; + unsigned long rx_AMPDUnum_histogram[5]; + unsigned long numpacket_matchbssid; + unsigned long numpacket_toself; + unsigned long num_process_phyinfo; + unsigned long numqry_phystatus; + unsigned long numqry_phystatusCCK; + unsigned long numqry_phystatusHT; + unsigned long received_bwtype[5]; + unsigned long txnperr; + unsigned long txnpdrop; + unsigned long txresumed; + unsigned long rxoverflow; + unsigned long rxint; + unsigned long txnpokint; + unsigned long ints; + unsigned long shints; + unsigned long txoverflow; + unsigned long txlpokint; + unsigned long txlpdrop; + unsigned long txlperr; + unsigned long txbeokint; + unsigned long txbedrop; + unsigned long txbeerr; + unsigned long txbkokint; + unsigned long txbkdrop; + unsigned long txbkerr; + unsigned long txviokint; + unsigned long txvidrop; + unsigned long txvierr; + unsigned long txvookint; + unsigned long txvodrop; + unsigned long txvoerr; + unsigned long txbeaconokint; + unsigned long txbeacondrop; + unsigned long txbeaconerr; + unsigned long txmanageokint; + unsigned long txmanagedrop; + unsigned long txmanageerr; + unsigned long txcmdpktokint; + unsigned long txdatapkt; + unsigned long txfeedback; + unsigned long txfeedbackok; + unsigned long txoktotal; + unsigned long txokbytestotal; + unsigned long txokinperiod; + unsigned long txmulticast; + unsigned long txbytesmulticast; + unsigned long txbroadcast; + unsigned long txbytesbroadcast; + unsigned long txunicast; + unsigned long txbytesunicast; + unsigned long rxbytesunicast; + unsigned long txfeedbackfail; + unsigned long txerrtotal; + unsigned long txerrbytestotal; + unsigned long txerrmulticast; + unsigned long txerrbroadcast; + unsigned long txerrunicast; + unsigned long txretrycount; + unsigned long txfeedbackretry; + u8 last_packet_rate; + unsigned long slide_signal_strength[100]; + unsigned long slide_evm[100]; + unsigned long slide_rssi_total; + unsigned long slide_evm_total; + long signal_strength; + long signal_quality; + long last_signal_strength_inpercent; + long recv_signal_power; + u8 rx_rssi_percentage[4]; + u8 rx_evm_percentage[2]; + long rxSNRdB[4]; + struct rt_tx_rahis txrate; + u32 Slide_Beacon_pwdb[100]; + u32 Slide_Beacon_Total; + struct rt_smooth_data_4rf cck_adc_pwdb; + u32 CurrentShowTxate; +}; + +struct channel_access_setting { + u16 SIFS_Timer; + u16 DIFS_Timer; + u16 SlotTimeTimer; + u16 EIFS_Timer; + u16 CWminIndex; + u16 CWmaxIndex; +}; + +enum two_port_status { + TWO_PORT_STATUS__DEFAULT_ONLY, + TWO_PORT_STATUS__EXTENSION_ONLY, + TWO_PORT_STATUS__EXTENSION_FOLLOW_DEFAULT, + TWO_PORT_STATUS__DEFAULT_G_EXTENSION_N20, + TWO_PORT_STATUS__ADHOC, + TWO_PORT_STATUS__WITHOUT_ANY_ASSOCIATE +}; + +struct txbbgain_struct { + long txbb_iq_amplifygain; + u32 txbbgain_value; +}; + +struct ccktxbbgain { + u8 ccktxbb_valuearray[8]; +}; + +struct init_gain { + u8 xaagccore1; + u8 xbagccore1; + u8 xcagccore1; + u8 xdagccore1; + u8 cca; + +}; + +struct tx_ring { + u32 *desc; + u8 nStuckCount; + struct tx_ring *next; +} __packed; + +struct rtl8192_tx_ring { + struct tx_desc *desc; + dma_addr_t dma; + unsigned int idx; + unsigned int entries; + struct sk_buff_head queue; +}; + + + +struct rtl819x_ops { + enum nic_t nic_type; + void (*get_eeprom_size)(struct net_device *dev); + void (*init_adapter_variable)(struct net_device *dev); + void (*init_before_adapter_start)(struct net_device *dev); + bool (*initialize_adapter)(struct net_device *dev); + void (*link_change)(struct net_device *dev); + void (*tx_fill_descriptor)(struct net_device *dev, + struct tx_desc *tx_desc, + struct cb_desc *cb_desc, + struct sk_buff *skb); + void (*tx_fill_cmd_descriptor)(struct net_device *dev, + struct tx_desc_cmd *entry, + struct cb_desc *cb_desc, + struct sk_buff *skb); + bool (*rx_query_status_descriptor)(struct net_device *dev, + struct rtllib_rx_stats *stats, + struct rx_desc *pdesc, + struct sk_buff *skb); + bool (*rx_command_packet_handler)(struct net_device *dev, + struct sk_buff *skb, + struct rx_desc *pdesc); + void (*stop_adapter)(struct net_device *dev, bool reset); + void (*update_ratr_table)(struct net_device *dev); + void (*irq_enable)(struct net_device *dev); + void (*irq_disable)(struct net_device *dev); + void (*irq_clear)(struct net_device *dev); + void (*rx_enable)(struct net_device *dev); + void (*tx_enable)(struct net_device *dev); + void (*interrupt_recognized)(struct net_device *dev, + u32 *p_inta, u32 *p_intb); + bool (*TxCheckStuckHandler)(struct net_device *dev); + bool (*RxCheckStuckHandler)(struct net_device *dev); +}; + +struct r8192_priv { + struct pci_dev *pdev; + struct pci_dev *bridge_pdev; + + bool bfirst_init; + bool bfirst_after_down; + bool initialized_at_probe; + bool being_init_adapter; + bool bDriverIsGoingToUnload; + + int irq; + short irq_enabled; + + short up; + short up_first_time; + struct delayed_work update_beacon_wq; + struct delayed_work watch_dog_wq; + struct delayed_work txpower_tracking_wq; + struct delayed_work rfpath_check_wq; + struct delayed_work gpio_change_rf_wq; + struct delayed_work initialgain_operate_wq; + struct delayed_work check_hw_scan_wq; + struct delayed_work hw_scan_simu_wq; + struct delayed_work start_hw_scan_wq; + + struct workqueue_struct *priv_wq; + + struct channel_access_setting ChannelAccessSetting; + + struct mp_adapter NdisAdapter; + + struct rtl819x_ops *ops; + struct rtllib_device *rtllib; + + struct work_struct reset_wq; + + struct log_int_8190 InterruptLog; + + enum rt_customer_id CustomerID; + + + enum rt_rf_type_819xu rf_chip; + enum ic_inferiority_8192s IC_Class; + enum ht_channel_width CurrentChannelBW; + struct bb_reg_definition PHYRegDef[4]; + struct rate_adaptive rate_adaptive; + + struct ccktxbbgain cck_txbbgain_table[CCKTxBBGainTableLength]; + struct ccktxbbgain cck_txbbgain_ch14_table[CCKTxBBGainTableLength]; + + struct txbbgain_struct txbbgain_table[TxBBGainTableLength]; + + enum acm_method AcmMethod; + + struct rt_firmware *pFirmware; + enum rtl819x_loopback LoopbackMode; + enum firmware_source firmware_source; + + struct timer_list watch_dog_timer; + struct timer_list fsync_timer; + struct timer_list gpio_polling_timer; + + spinlock_t fw_scan_lock; + spinlock_t irq_lock; + spinlock_t irq_th_lock; + spinlock_t tx_lock; + spinlock_t rf_ps_lock; + spinlock_t rw_lock; + spinlock_t rt_h2c_lock; + spinlock_t rf_lock; + spinlock_t ps_lock; + + struct sk_buff_head rx_queue; + struct sk_buff_head skb_queue; + + struct tasklet_struct irq_rx_tasklet; + struct tasklet_struct irq_tx_tasklet; + struct tasklet_struct irq_prepare_beacon_tasklet; + + struct semaphore wx_sem; + struct semaphore rf_sem; + struct mutex mutex; + + struct rt_stats stats; + struct iw_statistics wstats; + struct proc_dir_entry *dir_dev; + + short (*rf_set_sens)(struct net_device *dev, short sens); + u8 (*rf_set_chan)(struct net_device *dev, u8 ch); + void (*rf_close)(struct net_device *dev); + void (*rf_init)(struct net_device *dev); + + struct rx_desc *rx_ring[MAX_RX_QUEUE]; + struct sk_buff *rx_buf[MAX_RX_QUEUE][MAX_RX_COUNT]; + dma_addr_t rx_ring_dma[MAX_RX_QUEUE]; + unsigned int rx_idx[MAX_RX_QUEUE]; + int rxringcount; + u16 rxbuffersize; + + u64 LastRxDescTSF; + + u16 EarlyRxThreshold; + u32 ReceiveConfig; + u8 AcmControl; + u8 RFProgType; + u8 retry_data; + u8 retry_rts; + u16 rts; + + struct rtl8192_tx_ring tx_ring[MAX_TX_QUEUE_COUNT]; + int txringcount; + int txbuffsize; + int txfwbuffersize; + atomic_t tx_pending[0x10]; + + u16 ShortRetryLimit; + u16 LongRetryLimit; + u32 TransmitConfig; + u8 RegCWinMin; + u8 keepAliveLevel; + + bool sw_radio_on; + bool bHwRadioOff; + bool pwrdown; + bool blinked_ingpio; + u8 polling_timer_on; + + /**********************************************************/ + + enum card_type { + PCI, MINIPCI, + CARDBUS, USB + } card_type; + + struct work_struct qos_activate; + + u8 bIbssCoordinator; + + short promisc; + short crcmon; + + int txbeaconcount; + + short chan; + short sens; + short max_sens; + u32 rx_prevlen; + + u8 ScanDelay; + bool ps_force; + + u32 irq_mask[2]; + + u8 Rf_Mode; + enum nic_t card_8192; + u8 card_8192_version; + + short enable_gpio0; + + u8 rf_type; + u8 IC_Cut; + char nick[IW_ESSID_MAX_SIZE + 1]; + + u8 RegBcnCtrlVal; + bool bHwAntDiv; + + bool bTKIPinNmodeFromReg; + bool bWEPinNmodeFromReg; + + bool bLedOpenDrain; + + u8 check_roaming_cnt; + + bool bIgnoreSilentReset; + u32 SilentResetRxSoltNum; + u32 SilentResetRxSlotIndex; + u32 SilentResetRxStuckEvent[MAX_SILENT_RESET_RX_SLOT_NUM]; + + void *scan_cmd; + u8 hwscan_bw_40; + + u16 nrxAMPDU_size; + u8 nrxAMPDU_aggr_num; + + u32 last_rxdesc_tsf_high; + u32 last_rxdesc_tsf_low; + + u16 basic_rate; + u8 short_preamble; + u8 dot11CurrentPreambleMode; + u8 slot_time; + u16 SifsTime; + + u8 RegWirelessMode; + + u8 firmware_version; + u16 FirmwareSubVersion; + u16 rf_pathmap; + bool AutoloadFailFlag; + + u8 RegPciASPM; + u8 RegAMDPciASPM; + u8 RegHwSwRfOffD3; + u8 RegSupportPciASPM; + bool bSupportASPM; + + u32 RfRegChnlVal[2]; + + u8 ShowRateMode; + u8 RATRTableBitmap; + + u8 EfuseMap[2][HWSET_MAX_SIZE_92S]; + u16 EfuseUsedBytes; + u8 EfuseUsedPercentage; + + short epromtype; + u16 eeprom_vid; + u16 eeprom_did; + u16 eeprom_svid; + u16 eeprom_smid; + u8 eeprom_CustomerID; + u16 eeprom_ChannelPlan; + u8 eeprom_version; + + u8 EEPROMRegulatory; + u8 EEPROMPwrGroup[2][3]; + u8 EEPROMOptional; + + u8 EEPROMTxPowerLevelCCK[14]; + u8 EEPROMTxPowerLevelOFDM24G[14]; + u8 EEPROMTxPowerLevelOFDM5G[24]; + u8 EEPROMRfACCKChnl1TxPwLevel[3]; + u8 EEPROMRfAOfdmChnlTxPwLevel[3]; + u8 EEPROMRfCCCKChnl1TxPwLevel[3]; + u8 EEPROMRfCOfdmChnlTxPwLevel[3]; + u16 EEPROMTxPowerDiff; + u16 EEPROMAntPwDiff; + u8 EEPROMThermalMeter; + u8 EEPROMPwDiff; + u8 EEPROMCrystalCap; + + u8 EEPROMBluetoothCoexist; + u8 EEPROMBluetoothType; + u8 EEPROMBluetoothAntNum; + u8 EEPROMBluetoothAntIsolation; + u8 EEPROMBluetoothRadioShared; + + + u8 EEPROMSupportWoWLAN; + u8 EEPROMBoardType; + u8 EEPROM_Def_Ver; + u8 EEPROMHT2T_TxPwr[6]; + u8 EEPROMTSSI_A; + u8 EEPROMTSSI_B; + u8 EEPROMTxPowerLevelCCK_V1[3]; + u8 EEPROMLegacyHTTxPowerDiff; + + u8 BluetoothCoexist; + + u8 CrystalCap; + u8 ThermalMeter[2]; + + u16 FwCmdIOMap; + u32 FwCmdIOParam; + + u8 SwChnlInProgress; + u8 SwChnlStage; + u8 SwChnlStep; + u8 SetBWModeInProgress; + + u8 nCur40MhzPrimeSC; + + u32 RfReg0Value[4]; + u8 NumTotalRFPath; + bool brfpath_rxenable[4]; + + bool bTXPowerDataReadFromEEPORM; + + u16 RegChannelPlan; + u16 ChannelPlan; + bool bChnlPlanFromHW; + + bool RegRfOff; + bool isRFOff; + bool bInPowerSaveMode; + u8 bHwRfOffAction; + + bool aspm_clkreq_enable; + u32 pci_bridge_vendor; + u8 RegHostPciASPMSetting; + u8 RegDevicePciASPMSetting; + + bool RFChangeInProgress; + bool SetRFPowerStateInProgress; + bool bdisable_nic; + + u8 pwrGroupCnt; + + u8 ThermalValue_LCK; + u8 ThermalValue_IQK; + bool bRfPiEnable; + + u32 APKoutput[2][2]; + bool bAPKdone; + + long RegE94; + long RegE9C; + long RegEB4; + long RegEBC; + + u32 RegC04; + u32 Reg874; + u32 RegC08; + u32 ADDA_backup[16]; + u32 IQK_MAC_backup[3]; + + bool SetFwCmdInProgress; + u8 CurrentFwCmdIO; + + u8 rssi_level; + + bool bInformFWDriverControlDM; + u8 PwrGroupHT20[2][14]; + u8 PwrGroupHT40[2][14]; + + u8 ThermalValue; + long EntryMinUndecoratedSmoothedPWDB; + long EntryMaxUndecoratedSmoothedPWDB; + u8 DynamicTxHighPowerLvl; + u8 LastDTPLvl; + u32 CurrentRATR0; + struct false_alarm_stats FalseAlmCnt; + + u8 DMFlag; + u8 DM_Type; + + u8 CckPwEnl; + u16 TSSI_13dBm; + u32 Pwr_Track; + u8 CCKPresentAttentuation_20Mdefault; + u8 CCKPresentAttentuation_40Mdefault; + char CCKPresentAttentuation_difference; + char CCKPresentAttentuation; + u8 bCckHighPower; + long undecorated_smoothed_pwdb; + long undecorated_smoothed_cck_adc_pwdb[4]; + + u32 MCSTxPowerLevelOriginalOffset[6]; + u32 CCKTxPowerLevelOriginalOffset; + u8 TxPowerLevelCCK[14]; + u8 TxPowerLevelCCK_A[14]; + u8 TxPowerLevelCCK_C[14]; + u8 TxPowerLevelOFDM24G[14]; + u8 TxPowerLevelOFDM5G[14]; + u8 TxPowerLevelOFDM24G_A[14]; + u8 TxPowerLevelOFDM24G_C[14]; + u8 LegacyHTTxPowerDiff; + u8 TxPowerDiff; + s8 RF_C_TxPwDiff; + s8 RF_B_TxPwDiff; + u8 RfTxPwrLevelCck[2][14]; + u8 RfTxPwrLevelOfdm1T[2][14]; + u8 RfTxPwrLevelOfdm2T[2][14]; + u8 AntennaTxPwDiff[3]; + u8 TxPwrHt20Diff[2][14]; + u8 TxPwrLegacyHtDiff[2][14]; + u8 TxPwrSafetyFlag; + u8 HT2T_TxPwr_A[14]; + u8 HT2T_TxPwr_B[14]; + u8 CurrentCckTxPwrIdx; + u8 CurrentOfdm24GTxPwrIdx; + + bool bdynamic_txpower; + bool bDynamicTxHighPower; + bool bDynamicTxLowPower; + bool bLastDTPFlag_High; + bool bLastDTPFlag_Low; + + bool bstore_last_dtpflag; + bool bstart_txctrl_bydtp; + + u8 rfa_txpowertrackingindex; + u8 rfa_txpowertrackingindex_real; + u8 rfa_txpowertracking_default; + u8 rfc_txpowertrackingindex; + u8 rfc_txpowertrackingindex_real; + u8 rfc_txpowertracking_default; + bool btxpower_tracking; + bool bcck_in_ch14; + + u8 TxPowerTrackControl; + u8 txpower_count; + bool btxpower_trackingInit; + + u8 OFDM_index[2]; + u8 CCK_index; + + u8 Record_CCK_20Mindex; + u8 Record_CCK_40Mindex; + + struct init_gain initgain_backup; + u8 DefaultInitialGain[4]; + bool bis_any_nonbepkts; + bool bcurrent_turbo_EDCA; + bool bis_cur_rdlstate; + + bool bCCKinCH14; + + u8 MidHighPwrTHR_L1; + u8 MidHighPwrTHR_L2; + + bool bfsync_processing; + u32 rate_record; + u32 rateCountDiffRecord; + u32 ContiuneDiffCount; + bool bswitch_fsync; + u8 framesync; + u32 framesyncC34; + u8 framesyncMonitor; + + bool bDMInitialGainEnable; + bool MutualAuthenticationFail; + + bool bDisableFrameBursting; + + u32 reset_count; + bool bpbc_pressed; + + u32 txpower_checkcnt; + u32 txpower_tracking_callback_cnt; + u8 thermal_read_val[40]; + u8 thermal_readback_index; + u32 ccktxpower_adjustcnt_not_ch14; + u32 ccktxpower_adjustcnt_ch14; + + enum reset_type ResetProgress; + bool bForcedSilentReset; + bool bDisableNormalResetCheck; + u16 TxCounter; + u16 RxCounter; + int IrpPendingCount; + bool bResetInProgress; + bool force_reset; + bool force_lps; + u8 InitialGainOperateType; + + bool chan_forced; + bool bSingleCarrier; + bool RegBoard; + bool bCckContTx; + bool bOfdmContTx; + bool bStartContTx; + u8 RegPaModel; + u8 btMpCckTxPower; + u8 btMpOfdmTxPower; + + u32 MptActType; + u32 MptIoOffset; + u32 MptIoValue; + u32 MptRfPath; + + u32 MptBandWidth; + u32 MptRateIndex; + u8 MptChannelToSw; + u32 MptRCR; + + u8 PwrDomainProtect; + u8 H2CTxCmdSeq; + + +}; + +extern const struct ethtool_ops rtl819x_ethtool_ops; + +void rtl8192_tx_cmd(struct net_device *dev, struct sk_buff *skb); +short rtl8192_tx(struct net_device *dev, struct sk_buff *skb); + +u8 read_nic_io_byte(struct net_device *dev, int x); +u32 read_nic_io_dword(struct net_device *dev, int x); +u16 read_nic_io_word(struct net_device *dev, int x) ; +void write_nic_io_byte(struct net_device *dev, int x, u8 y); +void write_nic_io_word(struct net_device *dev, int x, u16 y); +void write_nic_io_dword(struct net_device *dev, int x, u32 y); + +u8 read_nic_byte(struct net_device *dev, int x); +u32 read_nic_dword(struct net_device *dev, int x); +u16 read_nic_word(struct net_device *dev, int x) ; +void write_nic_byte(struct net_device *dev, int x, u8 y); +void write_nic_word(struct net_device *dev, int x, u16 y); +void write_nic_dword(struct net_device *dev, int x, u32 y); + +void force_pci_posting(struct net_device *dev); + +void rtl8192_rx_enable(struct net_device *); +void rtl8192_tx_enable(struct net_device *); + +int rtl8192_hard_start_xmit(struct sk_buff *skb, struct net_device *dev); +void rtl8192_hard_data_xmit(struct sk_buff *skb, struct net_device *dev, + int rate); +void rtl8192_data_hard_stop(struct net_device *dev); +void rtl8192_data_hard_resume(struct net_device *dev); +void rtl8192_restart(void *data); +void rtl819x_watchdog_wqcallback(void *data); +void rtl8192_hw_sleep_wq(void *data); +void watch_dog_timer_callback(unsigned long data); +void rtl8192_irq_rx_tasklet(struct r8192_priv *priv); +void rtl8192_irq_tx_tasklet(struct r8192_priv *priv); +int rtl8192_down(struct net_device *dev, bool shutdownrf); +int rtl8192_up(struct net_device *dev); +void rtl8192_commit(struct net_device *dev); +void rtl8192_set_chan(struct net_device *dev, short ch); + +void check_rfctrl_gpio_timer(unsigned long data); + +void rtl8192_hw_wakeup_wq(void *data); +irqreturn_type rtl8192_interrupt(int irq, void *netdev, struct pt_regs *regs); + +short rtl8192_pci_initdescring(struct net_device *dev); + +void rtl8192_cancel_deferred_work(struct r8192_priv *priv); + +int _rtl8192_up(struct net_device *dev, bool is_silent_reset); + +short rtl8192_is_tx_queue_empty(struct net_device *dev); +void rtl8192_irq_disable(struct net_device *dev); + +void rtl8192_tx_timeout(struct net_device *dev); +void rtl8192_pci_resetdescring(struct net_device *dev); +void rtl8192_SetWirelessMode(struct net_device *dev, u8 wireless_mode); +void rtl8192_irq_enable(struct net_device *dev); +void rtl8192_config_rate(struct net_device *dev, u16 *rate_config); +void rtl8192_update_cap(struct net_device *dev, u16 cap); +void rtl8192_irq_disable(struct net_device *dev); + +void rtl819x_UpdateRxPktTimeStamp(struct net_device *dev, + struct rtllib_rx_stats *stats); +long rtl819x_translate_todbm(struct r8192_priv *priv, u8 signal_strength_index); +void rtl819x_update_rxsignalstatistics8190pci(struct r8192_priv *priv, + struct rtllib_rx_stats *pprevious_stats); +u8 rtl819x_evm_dbtopercentage(char value); +void rtl819x_process_cck_rxpathsel(struct r8192_priv *priv, + struct rtllib_rx_stats *pprevious_stats); +u8 rtl819x_query_rxpwrpercentage(char antpower); +void rtl8192_record_rxdesc_forlateruse(struct rtllib_rx_stats *psrc_stats, + struct rtllib_rx_stats *ptarget_stats); +bool NicIFEnableNIC(struct net_device *dev); +bool NicIFDisableNIC(struct net_device *dev); + +bool MgntActSet_RF_State(struct net_device *dev, + enum rt_rf_power_state StateToSet, + RT_RF_CHANGE_SOURCE ChangeSource, + bool ProtectOrNot); +void ActUpdateChannelAccessSetting(struct net_device *dev, + enum wireless_mode WirelessMode, + struct channel_access_setting *ChnlAccessSetting); + +#endif diff --git a/drivers/staging/rtl8192e/ieee80211/rtl_crypto.h b/drivers/staging/rtl8192e/rtl_crypto.h index ccf6ae7..ee57c0f 100644 --- a/drivers/staging/rtl8192e/ieee80211/rtl_crypto.h +++ b/drivers/staging/rtl8192e/rtl_crypto.h @@ -22,7 +22,7 @@ #include <linux/list.h> #include <linux/string.h> #include <asm/page.h> -#include <asm/errno.h> +#include <linux/errno.h> #define crypto_register_alg crypto_register_alg_rsl #define crypto_unregister_alg crypto_unregister_alg_rsl @@ -52,10 +52,10 @@ #define CRYPTO_TFM_REQ_WEAK_KEY 0x00000100 #define CRYPTO_TFM_RES_WEAK_KEY 0x00100000 -#define CRYPTO_TFM_RES_BAD_KEY_LEN 0x00200000 -#define CRYPTO_TFM_RES_BAD_KEY_SCHED 0x00400000 -#define CRYPTO_TFM_RES_BAD_BLOCK_LEN 0x00800000 -#define CRYPTO_TFM_RES_BAD_FLAGS 0x01000000 +#define CRYPTO_TFM_RES_BAD_KEY_LEN 0x00200000 +#define CRYPTO_TFM_RES_BAD_KEY_SCHED 0x00400000 +#define CRYPTO_TFM_RES_BAD_BLOCK_LEN 0x00800000 +#define CRYPTO_TFM_RES_BAD_FLAGS 0x01000000 /* * Miscellaneous stuff. @@ -73,7 +73,7 @@ struct cipher_alg { unsigned int cia_min_keysize; unsigned int cia_max_keysize; int (*cia_setkey)(void *ctx, const u8 *key, - unsigned int keylen, u32 *flags); + unsigned int keylen, u32 *flags); void (*cia_encrypt)(void *ctx, u8 *dst, const u8 *src); void (*cia_decrypt)(void *ctx, u8 *dst, const u8 *src); }; @@ -84,16 +84,16 @@ struct digest_alg { void (*dia_update)(void *ctx, const u8 *data, unsigned int len); void (*dia_final)(void *ctx, u8 *out); int (*dia_setkey)(void *ctx, const u8 *key, - unsigned int keylen, u32 *flags); + unsigned int keylen, u32 *flags); }; struct compress_alg { int (*coa_init)(void *ctx); void (*coa_exit)(void *ctx); int (*coa_compress)(void *ctx, const u8 *src, unsigned int slen, - u8 *dst, unsigned int *dlen); + u8 *dst, unsigned int *dlen); int (*coa_decompress)(void *ctx, const u8 *src, unsigned int slen, - u8 *dst, unsigned int *dlen); + u8 *dst, unsigned int *dlen); }; #define cra_cipher cra_u.cipher @@ -139,15 +139,15 @@ struct cipher_tfm { unsigned int cit_ivsize; u32 cit_mode; int (*cit_setkey)(struct crypto_tfm *tfm, - const u8 *key, unsigned int keylen); + const u8 *key, unsigned int keylen); int (*cit_encrypt)(struct crypto_tfm *tfm, struct scatterlist *dst, struct scatterlist *src, unsigned int nbytes); int (*cit_encrypt_iv)(struct crypto_tfm *tfm, - struct scatterlist *dst, - struct scatterlist *src, - unsigned int nbytes, u8 *iv); + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes, u8 *iv); int (*cit_decrypt)(struct crypto_tfm *tfm, struct scatterlist *dst, struct scatterlist *src, @@ -162,24 +162,21 @@ struct cipher_tfm { struct digest_tfm { void (*dit_init)(struct crypto_tfm *tfm); void (*dit_update)(struct crypto_tfm *tfm, - struct scatterlist *sg, unsigned int nsg); + struct scatterlist *sg, unsigned int nsg); void (*dit_final)(struct crypto_tfm *tfm, u8 *out); void (*dit_digest)(struct crypto_tfm *tfm, struct scatterlist *sg, - unsigned int nsg, u8 *out); + unsigned int nsg, u8 *out); int (*dit_setkey)(struct crypto_tfm *tfm, - const u8 *key, unsigned int keylen); -#ifdef CONFIG_CRYPTO_HMAC - void *dit_hmac_block; -#endif + const u8 *key, unsigned int keylen); }; struct compress_tfm { int (*cot_compress)(struct crypto_tfm *tfm, - const u8 *src, unsigned int slen, - u8 *dst, unsigned int *dlen); + const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen); int (*cot_decompress)(struct crypto_tfm *tfm, - const u8 *src, unsigned int slen, - u8 *dst, unsigned int *dlen); + const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen); }; #define crt_cipher crt_u.cipher @@ -277,8 +274,8 @@ static inline void crypto_digest_init(struct crypto_tfm *tfm) } static inline void crypto_digest_update(struct crypto_tfm *tfm, - struct scatterlist *sg, - unsigned int nsg) + struct scatterlist *sg, + unsigned int nsg) { BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); tfm->crt_digest.dit_update(tfm, sg, nsg); @@ -291,15 +288,15 @@ static inline void crypto_digest_final(struct crypto_tfm *tfm, u8 *out) } static inline void crypto_digest_digest(struct crypto_tfm *tfm, - struct scatterlist *sg, - unsigned int nsg, u8 *out) + struct scatterlist *sg, + unsigned int nsg, u8 *out) { BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); tfm->crt_digest.dit_digest(tfm, sg, nsg, out); } static inline int crypto_digest_setkey(struct crypto_tfm *tfm, - const u8 *key, unsigned int keylen) + const u8 *key, unsigned int keylen) { BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_DIGEST); if (tfm->crt_digest.dit_setkey == NULL) @@ -308,25 +305,25 @@ static inline int crypto_digest_setkey(struct crypto_tfm *tfm, } static inline int crypto_cipher_setkey(struct crypto_tfm *tfm, - const u8 *key, unsigned int keylen) + const u8 *key, unsigned int keylen) { BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); return tfm->crt_cipher.cit_setkey(tfm, key, keylen); } static inline int crypto_cipher_encrypt(struct crypto_tfm *tfm, - struct scatterlist *dst, - struct scatterlist *src, - unsigned int nbytes) + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) { BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); return tfm->crt_cipher.cit_encrypt(tfm, dst, src, nbytes); } static inline int crypto_cipher_encrypt_iv(struct crypto_tfm *tfm, - struct scatterlist *dst, - struct scatterlist *src, - unsigned int nbytes, u8 *iv) + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes, u8 *iv) { BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); BUG_ON(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB); @@ -334,18 +331,18 @@ static inline int crypto_cipher_encrypt_iv(struct crypto_tfm *tfm, } static inline int crypto_cipher_decrypt(struct crypto_tfm *tfm, - struct scatterlist *dst, - struct scatterlist *src, - unsigned int nbytes) + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes) { BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); return tfm->crt_cipher.cit_decrypt(tfm, dst, src, nbytes); } static inline int crypto_cipher_decrypt_iv(struct crypto_tfm *tfm, - struct scatterlist *dst, - struct scatterlist *src, - unsigned int nbytes, u8 *iv) + struct scatterlist *dst, + struct scatterlist *src, + unsigned int nbytes, u8 *iv) { BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); BUG_ON(tfm->crt_cipher.cit_mode == CRYPTO_TFM_MODE_ECB); @@ -353,47 +350,33 @@ static inline int crypto_cipher_decrypt_iv(struct crypto_tfm *tfm, } static inline void crypto_cipher_set_iv(struct crypto_tfm *tfm, - const u8 *src, unsigned int len) + const u8 *src, unsigned int len) { BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); memcpy(tfm->crt_cipher.cit_iv, src, len); } static inline void crypto_cipher_get_iv(struct crypto_tfm *tfm, - u8 *dst, unsigned int len) + u8 *dst, unsigned int len) { BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_CIPHER); memcpy(dst, tfm->crt_cipher.cit_iv, len); } static inline int crypto_comp_compress(struct crypto_tfm *tfm, - const u8 *src, unsigned int slen, - u8 *dst, unsigned int *dlen) + const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen) { BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS); return tfm->crt_compress.cot_compress(tfm, src, slen, dst, dlen); } static inline int crypto_comp_decompress(struct crypto_tfm *tfm, - const u8 *src, unsigned int slen, - u8 *dst, unsigned int *dlen) + const u8 *src, unsigned int slen, + u8 *dst, unsigned int *dlen) { BUG_ON(crypto_tfm_alg_type(tfm) != CRYPTO_ALG_TYPE_COMPRESS); return tfm->crt_compress.cot_decompress(tfm, src, slen, dst, dlen); } -/* - * HMAC support. - */ -#ifdef CONFIG_CRYPTO_HMAC -void crypto_hmac_init(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen); -void crypto_hmac_update(struct crypto_tfm *tfm, - struct scatterlist *sg, unsigned int nsg); -void crypto_hmac_final(struct crypto_tfm *tfm, u8 *key, - unsigned int *keylen, u8 *out); -void crypto_hmac(struct crypto_tfm *tfm, u8 *key, unsigned int *keylen, - struct scatterlist *sg, unsigned int nsg, u8 *out); -#endif /* CONFIG_CRYPTO_HMAC */ - #endif /* _LINUX_CRYPTO_H */ - diff --git a/drivers/staging/rtl8192e/rtl_debug.c b/drivers/staging/rtl8192e/rtl_debug.c new file mode 100644 index 0000000..22bc2dd --- /dev/null +++ b/drivers/staging/rtl8192e/rtl_debug.c @@ -0,0 +1,1108 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * Based on the r8180 driver, which is: + * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al. + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> +******************************************************************************/ +#include "rtl_debug.h" +#include "rtl_core.h" +#include "r8192E_phy.h" +#include "r8192E_phyreg.h" +#include "r8190P_rtl8256.h" /* RTL8225 Radio frontend */ +#include "r8192E_cmdpkt.h" + +u32 rt_global_debug_component = \ + COMP_ERR ; + +/*------------------Declare variable-----------------------*/ +u32 DBGP_Type[DBGP_TYPE_MAX]; + +/*----------------------------------------------------------------------------- + * Function: DBGP_Flag_Init + * + * Overview: Refresh all debug print control flag content to zero. + * + * Input: NONE + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 10/20/2006 MHC Create Version 0. + * + *---------------------------------------------------------------------------*/ +void rtl8192_dbgp_flag_init(struct net_device *dev) +{ + u8 i; + + for (i = 0; i < DBGP_TYPE_MAX; i++) + DBGP_Type[i] = 0; + + +} /* DBGP_Flag_Init */ + +/* this is only for debugging */ +void print_buffer(u32 *buffer, int len) +{ + int i; + u8 *buf = (u8 *)buffer; + + printk(KERN_INFO "ASCII BUFFER DUMP (len: %x):\n", len); + + for (i = 0; i < len; i++) + printk(KERN_INFO "%c", buf[i]); + + printk(KERN_INFO "\nBINARY BUFFER DUMP (len: %x):\n", len); + + for (i = 0; i < len; i++) + printk(KERN_INFO "%x", buf[i]); + + printk(KERN_INFO "\n"); +} + +/* this is only for debug */ +void dump_eprom(struct net_device *dev) +{ + int i; + + for (i = 0; i < 0xff; i++) + RT_TRACE(COMP_INIT, "EEPROM addr %x : %x", i, + eprom_read(dev, i)); +} + +/* this is only for debug */ +void rtl8192_dump_reg(struct net_device *dev) +{ + int i; + int n; + int max = 0x5ff; + + RT_TRACE(COMP_INIT, "Dumping NIC register map"); + + for (n = 0; n <= max; ) { + printk(KERN_INFO "\nD: %2x> ", n); + for (i = 0; i < 16 && n <= max; i++, n++) + printk(KERN_INFO "%2x ", read_nic_byte(dev, n)); + } + printk(KERN_INFO "\n"); +} + +/**************************************************************************** + -----------------------------PROCFS STUFF------------------------- +*****************************************************************************/ +/*This part is related to PROC, which will record some statistics. */ +static struct proc_dir_entry *rtl8192_proc; + +static int proc_get_stats_ap(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + struct rtllib_device *ieee = priv->rtllib; + struct rtllib_network *target; + int len = 0; + + list_for_each_entry(target, &ieee->network_list, list) { + + len += snprintf(page + len, count - len, + "%s ", target->ssid); + + if (target->wpa_ie_len > 0 || target->rsn_ie_len > 0) + len += snprintf(page + len, count - len, + "WPA\n"); + else + len += snprintf(page + len, count - len, + "non_WPA\n"); + + } + + *eof = 1; + return len; +} + +static int proc_get_registers_0(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + + int len = 0; + int i, n, page0; + + int max = 0xff; + page0 = 0x000; + + len += snprintf(page + len, count - len, + "\n####################page %x##################\n ", + (page0>>8)); + len += snprintf(page + len, count - len, + "\nD: OF > 00 01 02 03 04 05 06 07 08 09 0A 0B " + "0C 0D 0E 0F"); + for (n = 0; n <= max;) { + len += snprintf(page + len, count - len, "\nD: %2x > ", n); + for (i = 0; i < 16 && n <= max; n++, i++) + len += snprintf(page + len, count - len, + "%2.2x ", read_nic_byte(dev, + (page0 | n))); + } + len += snprintf(page + len, count - len, "\n"); + *eof = 1; + return len; + +} +static int proc_get_registers_1(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + + int len = 0; + int i, n, page0; + + int max = 0xff; + page0 = 0x100; + + /* This dump the current register page */ + len += snprintf(page + len, count - len, + "\n####################page %x##################\n ", + (page0>>8)); + len += snprintf(page + len, count - len, + "\nD: OF > 00 01 02 03 04 05 06 07 08 09 0A 0B " + "0C 0D 0E 0F"); + for (n = 0; n <= max;) { + len += snprintf(page + len, count - len, + "\nD: %2x > ", n); + for (i = 0; i < 16 && n <= max; i++, n++) + len += snprintf(page + len, count - len, + "%2.2x ", read_nic_byte(dev, + (page0 | n))); + } + len += snprintf(page + len, count - len, "\n"); + *eof = 1; + return len; + +} +static int proc_get_registers_2(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + + int len = 0; + int i, n, page0; + + int max = 0xff; + page0 = 0x200; + + /* This dump the current register page */ + len += snprintf(page + len, count - len, + "\n####################page %x##################\n ", + (page0 >> 8)); + len += snprintf(page + len, count - len, + "\nD: OF > 00 01 02 03 04 05 06 07 08 09 0A 0B 0C " + "0D 0E 0F"); + for (n = 0; n <= max;) { + len += snprintf(page + len, count - len, + "\nD: %2x > ", n); + for (i = 0; i < 16 && n <= max; i++, n++) + len += snprintf(page + len, count - len, + "%2.2x ", read_nic_byte(dev, + (page0 | n))); + } + len += snprintf(page + len, count - len, "\n"); + *eof = 1; + return len; + +} +static int proc_get_registers_3(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + + int len = 0; + int i, n, page0; + + int max = 0xff; + page0 = 0x300; + + /* This dump the current register page */ + len += snprintf(page + len, count - len, + "\n####################page %x##################\n ", + (page0>>8)); + len += snprintf(page + len, count - len, + "\nD: OF > 00 01 02 03 04 05 06 07 08 09 0A 0B " + "0C 0D 0E 0F"); + for (n = 0; n <= max;) { + len += snprintf(page + len, count - len, + "\nD: %2x > ", n); + for (i = 0; i < 16 && n <= max; i++, n++) + len += snprintf(page + len, count - len, + "%2.2x ", read_nic_byte(dev, + (page0 | n))); + } + len += snprintf(page + len, count - len, "\n"); + *eof = 1; + return len; + +} +static int proc_get_registers_4(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + + int len = 0; + int i, n, page0; + + int max = 0xff; + page0 = 0x400; + + /* This dump the current register page */ + len += snprintf(page + len, count - len, + "\n####################page %x##################\n ", + (page0>>8)); + len += snprintf(page + len, count - len, + "\nD: OF > 00 01 02 03 04 05 06 07 08 09 0A 0B " + "0C 0D 0E 0F"); + for (n = 0; n <= max;) { + len += snprintf(page + len, count - len, + "\nD: %2x > ", n); + for (i = 0; i < 16 && n <= max; i++, n++) + len += snprintf(page + len, count - len, + "%2.2x ", read_nic_byte(dev, + (page0 | n))); + } + len += snprintf(page + len, count - len, "\n"); + *eof = 1; + return len; + +} +static int proc_get_registers_5(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + + int len = 0; + int i, n, page0; + + int max = 0xff; + page0 = 0x500; + + /* This dump the current register page */ + len += snprintf(page + len, count - len, + "\n####################page %x##################\n ", + (page0 >> 8)); + len += snprintf(page + len, count - len, + "\nD: OF > 00 01 02 03 04 05 06 07 08 09 0A 0B " + "0C 0D 0E 0F"); + for (n = 0; n <= max;) { + len += snprintf(page + len, count - len, + "\nD: %2x > ", n); + for (i = 0; i < 16 && n <= max; i++, n++) + len += snprintf(page + len, count - len, + "%2.2x ", read_nic_byte(dev, + (page0 | n))); + } + len += snprintf(page + len, count - len, "\n"); + *eof = 1; + return len; + +} +static int proc_get_registers_6(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + + int len = 0; + int i, n, page0; + + int max = 0xff; + page0 = 0x600; + + /* This dump the current register page */ + len += snprintf(page + len, count - len, + "\n####################page %x##################\n ", + (page0>>8)); + len += snprintf(page + len, count - len, + "\nD: OF > 00 01 02 03 04 05 06 07 08 09 0A 0B " + "0C 0D 0E 0F"); + for (n = 0; n <= max;) { + len += snprintf(page + len, count - len, + "\nD: %2x > ", n); + for (i = 0; i < 16 && n <= max; i++, n++) + len += snprintf(page + len, count - len, + "%2.2x ", read_nic_byte(dev, + (page0 | n))); + } + len += snprintf(page + len, count - len, "\n"); + *eof = 1; + return len; + +} +static int proc_get_registers_7(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + + int len = 0; + int i, n, page0; + + int max = 0xff; + page0 = 0x700; + + /* This dump the current register page */ + len += snprintf(page + len, count - len, + "\n####################page %x##################\n ", + (page0 >> 8)); + len += snprintf(page + len, count - len, + "\nD: OF > 00 01 02 03 04 05 06 07 08 09 0A 0B 0C " + "0D 0E 0F"); + for (n = 0; n <= max;) { + len += snprintf(page + len, count - len, + "\nD: %2x > ", n); + for (i = 0; i < 16 && n <= max; i++, n++) + len += snprintf(page + len, count - len, + "%2.2x ", read_nic_byte(dev, + (page0 | n))); + } + len += snprintf(page + len, count - len, "\n"); + *eof = 1; + return len; + +} +static int proc_get_registers_8(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + + int len = 0; + int i, n, page0; + + int max = 0xff; + page0 = 0x800; + + /* This dump the current register page */ + len += snprintf(page + len, count - len, + "\n####################page %x##################\n", + (page0 >> 8)); + for (n = 0; n <= max;) { + len += snprintf(page + len, count - len, "\nD: %2x > ", n); + for (i = 0; i < 4 && n <= max; n += 4, i++) + len += snprintf(page + len, count - len, + "%8.8x ", rtl8192_QueryBBReg(dev, + (page0 | n), bMaskDWord)); + } + len += snprintf(page + len, count - len, "\n"); + *eof = 1; + return len; + +} +static int proc_get_registers_9(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + + int len = 0; + int i, n, page0; + + int max = 0xff; + page0 = 0x900; + + /* This dump the current register page */ + len += snprintf(page + len, count - len, + "\n####################page %x##################\n", + (page0>>8)); + for (n = 0; n <= max;) { + len += snprintf(page + len, count - len, "\nD: %2x > ", n); + for (i = 0; i < 4 && n <= max; n += 4, i++) + len += snprintf(page + len, count - len, + "%8.8x ", rtl8192_QueryBBReg(dev, + (page0 | n), bMaskDWord)); + } + len += snprintf(page + len, count - len, "\n"); + *eof = 1; + return len; +} +static int proc_get_registers_a(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + + int len = 0; + int i, n, page0; + + int max = 0xff; + page0 = 0xa00; + + /* This dump the current register page */ + len += snprintf(page + len, count - len, + "\n####################page %x##################\n", + (page0>>8)); + for (n = 0; n <= max;) { + len += snprintf(page + len, count - len, "\nD: %2x > ", n); + for (i = 0; i < 4 && n <= max; n += 4, i++) + len += snprintf(page + len, count - len, + "%8.8x ", rtl8192_QueryBBReg(dev, + (page0 | n), bMaskDWord)); + } + len += snprintf(page + len, count - len, "\n"); + *eof = 1; + return len; +} +static int proc_get_registers_b(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + + int len = 0; + int i, n, page0; + + int max = 0xff; + page0 = 0xb00; + + /* This dump the current register page */ + len += snprintf(page + len, count - len, + "\n####################page %x##################\n", + (page0 >> 8)); + for (n = 0; n <= max;) { + len += snprintf(page + len, count - len, "\nD: %2x > ", n); + for (i = 0; i < 4 && n <= max; n += 4, i++) + len += snprintf(page + len, count - len, + "%8.8x ", rtl8192_QueryBBReg(dev, + (page0 | n), bMaskDWord)); + } + len += snprintf(page + len, count - len, "\n"); + *eof = 1; + return len; +} +static int proc_get_registers_c(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + + int len = 0; + int i, n, page0; + + int max = 0xff; + page0 = 0xc00; + + /* This dump the current register page */ + len += snprintf(page + len, count - len, + "\n####################page %x##################\n", + (page0>>8)); + for (n = 0; n <= max;) { + len += snprintf(page + len, count - len, "\nD: %2x > ", n); + for (i = 0; i < 4 && n <= max; n += 4, i++) + len += snprintf(page + len, count - len, + "%8.8x ", rtl8192_QueryBBReg(dev, + (page0 | n), bMaskDWord)); + } + len += snprintf(page + len, count - len, "\n"); + *eof = 1; + return len; +} +static int proc_get_registers_d(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + + int len = 0; + int i, n, page0; + + int max = 0xff; + page0 = 0xd00; + + /* This dump the current register page */ + len += snprintf(page + len, count - len, + "\n####################page %x##################\n", + (page0>>8)); + for (n = 0; n <= max;) { + len += snprintf(page + len, count - len, "\nD: %2x > ", n); + for (i = 0; i < 4 && n <= max; n += 4, i++) + len += snprintf(page + len, count - len, + "%8.8x ", rtl8192_QueryBBReg(dev, + (page0 | n), bMaskDWord)); + } + len += snprintf(page + len, count - len, "\n"); + *eof = 1; + return len; +} +static int proc_get_registers_e(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + + int len = 0; + int i, n, page0; + + int max = 0xff; + page0 = 0xe00; + + /* This dump the current register page */ + len += snprintf(page + len, count - len, + "\n####################page %x##################\n", + (page0>>8)); + for (n = 0; n <= max;) { + len += snprintf(page + len, count - len, "\nD: %2x > ", n); + for (i = 0; i < 4 && n <= max; n += 4, i++) + len += snprintf(page + len, count - len, + "%8.8x ", rtl8192_QueryBBReg(dev, + (page0 | n), bMaskDWord)); + } + len += snprintf(page + len, count - len, "\n"); + *eof = 1; + return len; +} + +static int proc_get_reg_rf_a(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + + int len = 0; + int i, n; + + int max = 0xff; + + /* This dump the current register page */ + len += snprintf(page + len, count - len, + "\n#################### RF-A ##################\n "); + for (n = 0; n <= max;) { + len += snprintf(page + len, count - len, "\nD: %2x > ", n); + for (i = 0; i < 4 && n <= max; n += 4, i++) + len += snprintf(page + len, count - len, + "%8.8x ", rtl8192_phy_QueryRFReg(dev, + (enum rf90_radio_path)RF90_PATH_A, n, + bMaskDWord)); + } + len += snprintf(page + len, count - len, "\n"); + *eof = 1; + return len; +} + +static int proc_get_reg_rf_b(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + + int len = 0; + int i, n; + + int max = 0xff; + + /* This dump the current register page */ + len += snprintf(page + len, count - len, + "\n#################### RF-B ##################\n "); + for (n = 0; n <= max;) { + len += snprintf(page + len, count - len, "\nD: %2x > ", n); + for (i = 0; i < 4 && n <= max; n += 4, i++) + len += snprintf(page + len, count - len, + "%8.8x ", rtl8192_phy_QueryRFReg(dev, + (enum rf90_radio_path)RF90_PATH_B, n, + bMaskDWord)); + } + len += snprintf(page + len, count - len, "\n"); + *eof = 1; + return len; +} + +static int proc_get_reg_rf_c(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + + int len = 0; + int i, n; + + int max = 0xff; + + /* This dump the current register page */ + len += snprintf(page + len, count - len, + "\n#################### RF-C ##################\n"); + for (n = 0; n <= max;) { + len += snprintf(page + len, count - len, "\nD: %2x > ", n); + for (i = 0; i < 4 && n <= max; n += 4, i++) + len += snprintf(page + len, count - len, + "%8.8x ", rtl8192_phy_QueryRFReg(dev, + (enum rf90_radio_path)RF90_PATH_C, n, + bMaskDWord)); + } + len += snprintf(page + len, count - len, "\n"); + *eof = 1; + return len; +} + +static int proc_get_reg_rf_d(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + + int len = 0; + int i, n; + + int max = 0xff; + + /* This dump the current register page */ + len += snprintf(page + len, count - len, + "\n#################### RF-D ##################\n "); + for (n = 0; n <= max;) { + len += snprintf(page + len, count - len, "\nD: %2x > ", n); + for (i = 0; i < 4 && n <= max; n += 4, i++) + len += snprintf(page + len, count - len, + "%8.8x ", rtl8192_phy_QueryRFReg(dev, + (enum rf90_radio_path)RF90_PATH_D, n, + bMaskDWord)); + } + len += snprintf(page + len, count - len, "\n"); + *eof = 1; + return len; +} + +static int proc_get_cam_register_1(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + u32 target_command = 0; + u32 target_content = 0; + u8 entry_i = 0; + u32 ulStatus; + int len = 0; + int i = 100, j = 0; + + /* This dump the current register page */ + len += snprintf(page + len, count - len, + "\n#################### SECURITY CAM (0-10) ######" + "############\n "); + for (j = 0; j < 11; j++) { + len += snprintf(page + len, count - len, "\nD: %2x > ", j); + for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) { + target_command = entry_i+CAM_CONTENT_COUNT*j; + target_command = target_command | BIT31; + + while ((i--) >= 0) { + ulStatus = read_nic_dword(dev, RWCAM); + if (ulStatus & BIT31) + continue; + else + break; + } + write_nic_dword(dev, RWCAM, target_command); + target_content = read_nic_dword(dev, RCAMO); + len += snprintf(page + len, count - len, "%8.8x ", + target_content); + } + } + + len += snprintf(page + len, count - len, "\n"); + *eof = 1; + return len; +} + +static int proc_get_cam_register_2(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + u32 target_command = 0; + u32 target_content = 0; + u8 entry_i = 0; + u32 ulStatus; + int len = 0; + int i = 100, j = 0; + + /* This dump the current register page */ + len += snprintf(page + len, count - len, + "\n#################### SECURITY CAM (11-21) " + "##################\n "); + for (j = 11; j < 22; j++) { + len += snprintf(page + len, count - len, "\nD: %2x > ", j); + for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) { + target_command = entry_i + CAM_CONTENT_COUNT * j; + target_command = target_command | BIT31; + + while ((i--) >= 0) { + ulStatus = read_nic_dword(dev, RWCAM); + if (ulStatus & BIT31) + continue; + else + break; + } + write_nic_dword(dev, RWCAM, target_command); + target_content = read_nic_dword(dev, RCAMO); + len += snprintf(page + len, count - len, "%8.8x ", + target_content); + } + } + + len += snprintf(page + len, count - len, "\n"); + *eof = 1; + return len; +} + +static int proc_get_cam_register_3(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + u32 target_command = 0; + u32 target_content = 0; + u8 entry_i = 0; + u32 ulStatus; + int len = 0; + int i = 100, j = 0; + + /* This dump the current register page */ + len += snprintf(page + len, count - len, + "\n#################### SECURITY CAM (22-31) ######" + "############\n "); + for (j = 22; j < TOTAL_CAM_ENTRY; j++) { + len += snprintf(page + len, count - len, "\nD: %2x > ", j); + for (entry_i = 0; entry_i < CAM_CONTENT_COUNT; entry_i++) { + target_command = entry_i + CAM_CONTENT_COUNT * j; + target_command = target_command | BIT31; + + while ((i--) >= 0) { + ulStatus = read_nic_dword(dev, RWCAM); + if (ulStatus & BIT31) + continue; + else + break; + } + write_nic_dword(dev, RWCAM, target_command); + target_content = read_nic_dword(dev, RCAMO); + len += snprintf(page + len, count - len, "%8.8x ", + target_content); + } + } + + len += snprintf(page + len, count - len, "\n"); + *eof = 1; + return len; +} +static int proc_get_stats_tx(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + + int len = 0; + + len += snprintf(page + len, count - len, + "TX VI priority ok int: %lu\n" + "TX VO priority ok int: %lu\n" + "TX BE priority ok int: %lu\n" + "TX BK priority ok int: %lu\n" + "TX MANAGE priority ok int: %lu\n" + "TX BEACON priority ok int: %lu\n" + "TX BEACON priority error int: %lu\n" + "TX CMDPKT priority ok int: %lu\n" + "TX queue stopped?: %d\n" + "TX fifo overflow: %lu\n" + "TX total data packets %lu\n" + "TX total data bytes :%lu\n", + priv->stats.txviokint, + priv->stats.txvookint, + priv->stats.txbeokint, + priv->stats.txbkokint, + priv->stats.txmanageokint, + priv->stats.txbeaconokint, + priv->stats.txbeaconerr, + priv->stats.txcmdpktokint, + netif_queue_stopped(dev), + priv->stats.txoverflow, + priv->rtllib->stats.tx_packets, + priv->rtllib->stats.tx_bytes + + + ); + + *eof = 1; + return len; +} + + + +static int proc_get_stats_rx(char *page, char **start, + off_t offset, int count, + int *eof, void *data) +{ + struct net_device *dev = data; + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + + int len = 0; + + len += snprintf(page + len, count - len, + "RX packets: %lu\n" + "RX data crc err: %lu\n" + "RX mgmt crc err: %lu\n" + "RX desc err: %lu\n" + "RX rx overflow error: %lu\n", + priv->stats.rxint, + priv->stats.rxdatacrcerr, + priv->stats.rxmgmtcrcerr, + priv->stats.rxrdu, + priv->stats.rxoverflow); + + *eof = 1; + return len; +} + +void rtl8192_proc_module_init(void) +{ + RT_TRACE(COMP_INIT, "Initializing proc filesystem"); + rtl8192_proc = create_proc_entry(DRV_NAME, S_IFDIR, init_net.proc_net); +} + + +void rtl8192_proc_module_remove(void) +{ + remove_proc_entry(DRV_NAME, init_net.proc_net); +} + + +void rtl8192_proc_remove_one(struct net_device *dev) +{ + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + + printk(KERN_INFO "dev name %s\n", dev->name); + + if (priv->dir_dev) { + remove_proc_entry("stats-tx", priv->dir_dev); + remove_proc_entry("stats-rx", priv->dir_dev); + remove_proc_entry("stats-ap", priv->dir_dev); + remove_proc_entry("registers-0", priv->dir_dev); + remove_proc_entry("registers-1", priv->dir_dev); + remove_proc_entry("registers-2", priv->dir_dev); + remove_proc_entry("registers-3", priv->dir_dev); + remove_proc_entry("registers-4", priv->dir_dev); + remove_proc_entry("registers-5", priv->dir_dev); + remove_proc_entry("registers-6", priv->dir_dev); + remove_proc_entry("registers-7", priv->dir_dev); + remove_proc_entry("registers-8", priv->dir_dev); + remove_proc_entry("registers-9", priv->dir_dev); + remove_proc_entry("registers-a", priv->dir_dev); + remove_proc_entry("registers-b", priv->dir_dev); + remove_proc_entry("registers-c", priv->dir_dev); + remove_proc_entry("registers-d", priv->dir_dev); + remove_proc_entry("registers-e", priv->dir_dev); + remove_proc_entry("RF-A", priv->dir_dev); + remove_proc_entry("RF-B", priv->dir_dev); + remove_proc_entry("RF-C", priv->dir_dev); + remove_proc_entry("RF-D", priv->dir_dev); + remove_proc_entry("SEC-CAM-1", priv->dir_dev); + remove_proc_entry("SEC-CAM-2", priv->dir_dev); + remove_proc_entry("SEC-CAM-3", priv->dir_dev); + remove_proc_entry("wlan0", rtl8192_proc); + priv->dir_dev = NULL; + } +} + + +void rtl8192_proc_init_one(struct net_device *dev) +{ + struct proc_dir_entry *e; + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + + priv->dir_dev = create_proc_entry(dev->name, + S_IFDIR | S_IRUGO | S_IXUGO, + rtl8192_proc); + if (!priv->dir_dev) { + RT_TRACE(COMP_ERR, "Unable to initialize /proc/net/rtl8192" + "/%s\n", dev->name); + return; + } + e = create_proc_read_entry("stats-rx", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_stats_rx, dev); + + if (!e) + RT_TRACE(COMP_ERR, "Unable to initialize " + "/proc/net/rtl8192/%s/stats-rx\n", + dev->name); + + e = create_proc_read_entry("stats-tx", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_stats_tx, dev); + + if (!e) + RT_TRACE(COMP_ERR, "Unable to initialize " + "/proc/net/rtl8192/%s/stats-tx\n", + dev->name); + + e = create_proc_read_entry("stats-ap", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_stats_ap, dev); + + if (!e) + RT_TRACE(COMP_ERR, "Unable to initialize " + "/proc/net/rtl8192/%s/stats-ap\n", + dev->name); + + e = create_proc_read_entry("registers-0", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_registers_0, dev); + if (!e) + RT_TRACE(COMP_ERR, "Unable to initialize " + "/proc/net/rtl8192/%s/registers-0\n", + dev->name); + e = create_proc_read_entry("registers-1", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_registers_1, dev); + if (!e) + RT_TRACE(COMP_ERR, "Unable to initialize " + "/proc/net/rtl8192/%s/registers-1\n", + dev->name); + e = create_proc_read_entry("registers-2", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_registers_2, dev); + if (!e) + RT_TRACE(COMP_ERR, "Unable to initialize " + "/proc/net/rtl8192/%s/registers-2\n", + dev->name); + e = create_proc_read_entry("registers-3", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_registers_3, dev); + if (!e) + RT_TRACE(COMP_ERR, "Unable to initialize " + "/proc/net/rtl8192/%s/registers-3\n", + dev->name); + e = create_proc_read_entry("registers-4", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_registers_4, dev); + if (!e) + RT_TRACE(COMP_ERR, "Unable to initialize " + "/proc/net/rtl8192/%s/registers-4\n", + dev->name); + e = create_proc_read_entry("registers-5", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_registers_5, dev); + if (!e) + RT_TRACE(COMP_ERR, "Unable to initialize " + "/proc/net/rtl8192/%s/registers-5\n", + dev->name); + e = create_proc_read_entry("registers-6", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_registers_6, dev); + if (!e) + RT_TRACE(COMP_ERR, "Unable to initialize " + "/proc/net/rtl8192/%s/registers-6\n", + dev->name); + e = create_proc_read_entry("registers-7", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_registers_7, dev); + if (!e) + RT_TRACE(COMP_ERR, "Unable to initialize " + "/proc/net/rtl8192/%s/registers-7\n", + dev->name); + e = create_proc_read_entry("registers-8", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_registers_8, dev); + if (!e) + RT_TRACE(COMP_ERR, "Unable to initialize " + "/proc/net/rtl8192/%s/registers-8\n", + dev->name); + e = create_proc_read_entry("registers-9", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_registers_9, dev); + if (!e) + RT_TRACE(COMP_ERR, "Unable to initialize " + "/proc/net/rtl8192/%s/registers-9\n", + dev->name); + e = create_proc_read_entry("registers-a", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_registers_a, dev); + if (!e) + RT_TRACE(COMP_ERR, "Unable to initialize " + "/proc/net/rtl8192/%s/registers-a\n", + dev->name); + e = create_proc_read_entry("registers-b", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_registers_b, dev); + if (!e) + RT_TRACE(COMP_ERR, "Unable to initialize " + "/proc/net/rtl8192/%s/registers-b\n", + dev->name); + e = create_proc_read_entry("registers-c", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_registers_c, dev); + if (!e) + RT_TRACE(COMP_ERR, "Unable to initialize " + "/proc/net/rtl8192/%s/registers-c\n", + dev->name); + e = create_proc_read_entry("registers-d", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_registers_d, dev); + if (!e) + RT_TRACE(COMP_ERR, "Unable to initialize " + "/proc/net/rtl8192/%s/registers-d\n", + dev->name); + e = create_proc_read_entry("registers-e", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_registers_e, dev); + if (!e) + RT_TRACE(COMP_ERR, "Unable to initialize " + "/proc/net/rtl8192/%s/registers-e\n", + dev->name); + e = create_proc_read_entry("RF-A", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_reg_rf_a, dev); + if (!e) + RT_TRACE(COMP_ERR, "Unable to initialize " + "/proc/net/rtl8192/%s/RF-A\n", + dev->name); + e = create_proc_read_entry("RF-B", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_reg_rf_b, dev); + if (!e) + RT_TRACE(COMP_ERR, "Unable to initialize " + "/proc/net/rtl8192/%s/RF-B\n", + dev->name); + e = create_proc_read_entry("RF-C", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_reg_rf_c, dev); + if (!e) + RT_TRACE(COMP_ERR, "Unable to initialize " + "/proc/net/rtl8192/%s/RF-C\n", + dev->name); + e = create_proc_read_entry("RF-D", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_reg_rf_d, dev); + if (!e) + RT_TRACE(COMP_ERR, "Unable to initialize " + "/proc/net/rtl8192/%s/RF-D\n", + dev->name); + e = create_proc_read_entry("SEC-CAM-1", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_cam_register_1, dev); + if (!e) + RT_TRACE(COMP_ERR, "Unable to initialize " + "/proc/net/rtl8192/%s/SEC-CAM-1\n", + dev->name); + e = create_proc_read_entry("SEC-CAM-2", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_cam_register_2, dev); + if (!e) + RT_TRACE(COMP_ERR, "Unable to initialize " + "/proc/net/rtl8192/%s/SEC-CAM-2\n", + dev->name); + e = create_proc_read_entry("SEC-CAM-3", S_IFREG | S_IRUGO, + priv->dir_dev, proc_get_cam_register_3, dev); + if (!e) + RT_TRACE(COMP_ERR, "Unable to initialize " + "/proc/net/rtl8192/%s/SEC-CAM-3\n", + dev->name); +} diff --git a/drivers/staging/rtl8192e/rtl_debug.h b/drivers/staging/rtl8192e/rtl_debug.h new file mode 100644 index 0000000..50fb9a9 --- /dev/null +++ b/drivers/staging/rtl8192e/rtl_debug.h @@ -0,0 +1,299 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * Based on the r8180 driver, which is: + * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al. + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> +******************************************************************************/ +#ifndef _RTL_DEBUG_H +#define _RTL_DEBUG_H +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/version.h> +#include <linux/debugfs.h> + +struct r8192_priv; +struct _tx_desc_8192se; +struct _TX_DESC_8192CE; +struct net_device; + +#define DBG_LOUD 4 + +#define RT_ASSERT(_Exp, Fmt) \ + if (!(_Exp)) { \ + printk("Rtl819x: "); \ + printk Fmt; \ + } + +enum dbgp_flag { + FQoS = 0, + FTX = 1, + FRX = 2, + FSEC = 3, + FMGNT = 4, + FMLME = 5, + FRESOURCE = 6, + FBEACON = 7, + FISR = 8, + FPHY = 9, + FMP = 10, + FEEPROM = 11, + FPWR = 12, + FDM = 13, + FDBGCtrl = 14, + FC2H = 15, + FBT = 16, + FINIT = 17, + FIOCTL = 18, + DBGP_TYPE_MAX +}; + +#define QoS_INIT BIT0 +#define QoS_VISTA BIT1 + +#define TX_DESC BIT0 +#define TX_DESC_TID BIT1 + +#define RX_DATA BIT0 +#define RX_PHY_STS BIT1 +#define RX_PHY_SS BIT2 +#define RX_PHY_SQ BIT3 +#define RX_PHY_ASTS BIT4 +#define RX_ERR_LEN BIT5 +#define RX_DEFRAG BIT6 +#define RX_ERR_RATE BIT7 + + + +#define MEDIA_STS BIT0 +#define LINK_STS BIT1 + +#define OS_CHK BIT0 + +#define BCN_SHOW BIT0 +#define BCN_PEER BIT1 + +#define ISR_CHK BIT0 + +#define PHY_BBR BIT0 +#define PHY_BBW BIT1 +#define PHY_RFR BIT2 +#define PHY_RFW BIT3 +#define PHY_MACR BIT4 +#define PHY_MACW BIT5 +#define PHY_ALLR BIT6 +#define PHY_ALLW BIT7 +#define PHY_TXPWR BIT8 +#define PHY_PWRDIFF BIT9 + +#define MP_RX BIT0 +#define MP_SWICH_CH BIT1 + +#define EEPROM_W BIT0 +#define EFUSE_PG BIT1 +#define EFUSE_READ_ALL BIT2 + +#define LPS BIT0 +#define IPS BIT1 +#define PWRSW BIT2 +#define PWRHW BIT3 +#define PWRHAL BIT4 + +#define WA_IOT BIT0 +#define DM_PWDB BIT1 +#define DM_Monitor BIT2 +#define DM_DIG BIT3 +#define DM_EDCA_Turbo BIT4 + +#define DbgCtrl_Trace BIT0 +#define DbgCtrl_InbandNoise BIT1 + +#define BT_TRACE BIT0 +#define BT_RFPoll BIT1 + +#define C2H_Summary BIT0 +#define C2H_PacketData BIT1 +#define C2H_ContentData BIT2 +#define BT_TRACE BIT0 +#define BT_RFPoll BIT1 + +#define INIT_EEPROM BIT0 +#define INIT_TxPower BIT1 +#define INIT_IQK BIT2 +#define INIT_RF BIT3 + +#define IOCTL_TRACE BIT0 +#define IOCTL_BT_EVENT BIT1 +#define IOCTL_BT_EVENT_DETAIL BIT2 +#define IOCTL_BT_TX_ACLDATA BIT3 +#define IOCTL_BT_TX_ACLDATA_DETAIL BIT4 +#define IOCTL_BT_RX_ACLDATA BIT5 +#define IOCTL_BT_RX_ACLDATA_DETAIL BIT6 +#define IOCTL_BT_HCICMD BIT7 +#define IOCTL_BT_HCICMD_DETAIL BIT8 +#define IOCTL_IRP BIT9 +#define IOCTL_IRP_DETAIL BIT10 +#define IOCTL_CALLBACK_FUN BIT11 +#define IOCTL_STATE BIT12 +#define IOCTL_BT_TP BIT13 +#define IOCTL_BT_LOGO BIT14 + +/* 2007/07/13 MH ------For DeBuG Print modeue------*/ +/*------------------------------Define structure----------------------------*/ + + +/*------------------------Export Marco Definition---------------------------*/ +#define DEBUG_PRINT 1 + +#if (DEBUG_PRINT == 1) +#define RTPRINT(dbgtype, dbgflag, printstr) \ +{ \ + if (DBGP_Type[dbgtype] & dbgflag) { \ + printk printstr; \ + } \ +} + +#define RTPRINT_ADDR(dbgtype, dbgflag, printstr, _Ptr) \ +{ \ + if (DBGP_Type[dbgtype] & dbgflag) { \ + int __i; \ + u8 *ptr = (u8 *)_Ptr; \ + printk printstr; \ + printk(" "); \ + for (__i = 0; __i < 6; __i++) \ + printk("%02X%s", ptr[__i], \ + (__i == 5) ? "" : "-"); \ + printk("\n"); \ + } \ +} + +#define RTPRINT_DATA(dbgtype, dbgflag, _TitleString, _HexData, _HexDataLen)\ +{ \ + if (DBGP_Type[dbgtype] & dbgflag) { \ + int __i; \ + u8 *ptr = (u8 *)_HexData; \ + printk(_TitleString); \ + for (__i = 0; __i < (int)_HexDataLen; __i++) { \ + printk("%02X%s", ptr[__i], (((__i + 1) \ + % 4) == 0) ? " " : " "); \ + if (((__i + 1) % 16) == 0) \ + printk("\n"); \ + } \ + printk("\n"); \ + } \ +} +#else +#define RTPRINT(dbgtype, dbgflag, printstr) +#define RTPRINT_ADDR(dbgtype, dbgflag, printstr, _Ptr) +#define RTPRINT_DATA(dbgtype, dbgflag, _TitleString, _HexData, _HexDataLen) +#endif + +extern u32 DBGP_Type[DBGP_TYPE_MAX]; + +#define RT_PRINT_DATA(_Comp, _Level, _TitleString, _HexData, _HexDataLen) \ +do {\ + if (((_Comp) & rt_global_debug_component) && \ + (_Level <= rt_global_debug_component)) { \ + int __i; \ + u8* ptr = (u8 *)_HexData; \ + printk(KERN_INFO "Rtl819x: "); \ + printk(_TitleString); \ + for (__i = 0; __i < (int)_HexDataLen; __i++) { \ + printk("%02X%s", ptr[__i], (((__i + 1) % \ + 4) == 0) ? " " : " "); \ + if (((__i + 1) % 16) == 0) \ + printk("\n"); \ + } \ + printk("\n"); \ + } \ +} while (0); + +#define DMESG(x, a...) +#define DMESGW(x, a...) +#define DMESGE(x, a...) +extern u32 rt_global_debug_component; +#define RT_TRACE(component, x, args...) \ +do { \ + if (rt_global_debug_component & component) \ + printk(KERN_DEBUG DRV_NAME ":" x "\n" , \ + ##args);\ +} while (0); + +#define assert(expr) \ + if (!(expr)) { \ + printk(KERN_INFO "Assertion failed! %s,%s,%s,line=%d\n", \ + #expr, __FILE__, __func__, __LINE__); \ + } +#define RT_DEBUG_DATA(level, data, datalen) \ + do { \ + if ((rt_global_debug_component & (level)) == (level)) {\ + int _i; \ + u8 *_pdata = (u8 *)data; \ + printk(KERN_DEBUG DRV_NAME ": %s()\n", __func__); \ + for (_i = 0; _i < (int)(datalen); _i++) { \ + printk(KERN_INFO "%2x ", _pdata[_i]); \ + if ((_i+1) % 16 == 0) \ + printk("\n"); \ + } \ + printk(KERN_INFO "\n"); \ + } \ + } while (0) + +struct rtl_fs_debug { + const char *name; + struct dentry *dir_drv; + struct dentry *debug_register; + u32 hw_type; + u32 hw_offset; + bool hw_holding; +}; + +void print_buffer(u32 *buffer, int len); +void dump_eprom(struct net_device *dev); +void rtl8192_dump_reg(struct net_device *dev); + +/* debugfs stuff */ +static inline int rtl_debug_module_init(struct r8192_priv *priv, + const char *name) +{ + return 0; +} + +static inline void rtl_debug_module_remove(struct r8192_priv *priv) +{ +} + +static inline int rtl_create_debugfs_root(void) +{ + return 0; +} + +static inline void rtl_remove_debugfs_root(void) +{ +} + +/* proc stuff */ +void rtl8192_proc_init_one(struct net_device *dev); +void rtl8192_proc_remove_one(struct net_device *dev); +void rtl8192_proc_module_init(void); +void rtl8192_proc_module_remove(void); +void rtl8192_dbgp_flag_init(struct net_device *dev); + +#endif diff --git a/drivers/staging/rtl8192e/rtl_dm.c b/drivers/staging/rtl8192e/rtl_dm.c new file mode 100644 index 0000000..a7fa9aa --- /dev/null +++ b/drivers/staging/rtl8192e/rtl_dm.c @@ -0,0 +1,2995 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> +******************************************************************************/ +#include "rtl_core.h" +#include "rtl_dm.h" +#include "r8192E_hw.h" +#include "r8192E_phy.h" +#include "r8192E_phyreg.h" +#include "r8190P_rtl8256.h" +#include "r8192E_cmdpkt.h" + +/*---------------------------Define Local Constant---------------------------*/ +static u32 edca_setting_DL[HT_IOT_PEER_MAX] = { + 0x5e4322, + 0x5e4322, + 0x5ea44f, + 0x5e4322, + 0x604322, + 0xa44f, + 0x5e4322, + 0x5e4332 +}; + +static u32 edca_setting_DL_GMode[HT_IOT_PEER_MAX] = { + 0x5e4322, + 0x5e4322, + 0x5e4322, + 0x5e4322, + 0x604322, + 0xa44f, + 0x5e4322, + 0x5e4322 +}; + +static u32 edca_setting_UL[HT_IOT_PEER_MAX] = { + 0x5e4322, + 0xa44f, + 0x5ea44f, + 0x5e4322, + 0x604322, + 0x5e4322, + 0x5e4322, + 0x5e4332 +}; + +#define RTK_UL_EDCA 0xa44f +#define RTK_DL_EDCA 0x5e4322 +/*---------------------------Define Local Constant---------------------------*/ + + +/*------------------------Define global variable-----------------------------*/ +struct dig_t dm_digtable; +u8 dm_shadow[16][256] = { + {0} +}; + +struct drx_path_sel DM_RxPathSelTable; +/*------------------------Define global variable-----------------------------*/ + + +/*------------------------Define local variable------------------------------*/ +/*------------------------Define local variable------------------------------*/ + + + +/*---------------------Define local function prototype-----------------------*/ +static void dm_check_rate_adaptive(struct net_device *dev); + +static void dm_init_bandwidth_autoswitch(struct net_device *dev); +static void dm_bandwidth_autoswitch(struct net_device *dev); + + +static void dm_check_txpower_tracking(struct net_device *dev); + + + + + +static void dm_bb_initialgain_restore(struct net_device *dev); + + +static void dm_bb_initialgain_backup(struct net_device *dev); + +static void dm_dig_init(struct net_device *dev); +static void dm_ctrl_initgain_byrssi(struct net_device *dev); +static void dm_ctrl_initgain_byrssi_highpwr(struct net_device *dev); +static void dm_ctrl_initgain_byrssi_by_driverrssi(struct net_device *dev); +static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(struct net_device *dev); +static void dm_initial_gain(struct net_device *dev); +static void dm_pd_th(struct net_device *dev); +static void dm_cs_ratio(struct net_device *dev); + +static void dm_init_ctstoself(struct net_device *dev); +static void dm_Init_WA_Broadcom_IOT(struct net_device *dev); + +static void dm_check_edca_turbo(struct net_device *dev); + +static void dm_check_pbc_gpio(struct net_device *dev); + + +static void dm_check_rx_path_selection(struct net_device *dev); +static void dm_init_rxpath_selection(struct net_device *dev); +static void dm_rxpath_sel_byrssi(struct net_device *dev); + + +static void dm_init_fsync(struct net_device *dev); +static void dm_deInit_fsync(struct net_device *dev); + +static void dm_check_txrateandretrycount(struct net_device *dev); +static void dm_check_ac_dc_power(struct net_device *dev); + +/*---------------------Define local function prototype-----------------------*/ + +static void dm_init_dynamic_txpower(struct net_device *dev); +static void dm_dynamic_txpower(struct net_device *dev); + + +static void dm_send_rssi_tofw(struct net_device *dev); +static void dm_ctstoself(struct net_device *dev); +/*---------------------------Define function prototype------------------------*/ + +void init_hal_dm(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + priv->DM_Type = DM_Type_ByDriver; + + priv->undecorated_smoothed_pwdb = -1; + + dm_init_dynamic_txpower(dev); + + init_rate_adaptive(dev); + + dm_dig_init(dev); + dm_init_edca_turbo(dev); + dm_init_bandwidth_autoswitch(dev); + dm_init_fsync(dev); + dm_init_rxpath_selection(dev); + dm_init_ctstoself(dev); + if (IS_HARDWARE_TYPE_8192SE(dev)) + dm_Init_WA_Broadcom_IOT(dev); + + INIT_DELAYED_WORK_RSL(&priv->gpio_change_rf_wq, (void *)dm_CheckRfCtrlGPIO, dev); +} + +void deinit_hal_dm(struct net_device *dev) +{ + + dm_deInit_fsync(dev); + +} + +void hal_dm_watchdog(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + if (priv->being_init_adapter) + return; + + dm_check_ac_dc_power(dev); + + dm_check_pbc_gpio(dev); + dm_check_txrateandretrycount(dev); + dm_check_edca_turbo(dev); + + dm_check_rate_adaptive(dev); + dm_dynamic_txpower(dev); + dm_check_txpower_tracking(dev); + + dm_ctrl_initgain_byrssi(dev); + dm_bandwidth_autoswitch(dev); + + dm_check_rx_path_selection(dev); + dm_check_fsync(dev); + + dm_send_rssi_tofw(dev); + dm_ctstoself(dev); +} + +static void dm_check_ac_dc_power(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + static char *ac_dc_check_script_path = "/etc/acpi/wireless-rtl-ac-dc-power.sh"; + char *argv[] = {ac_dc_check_script_path, DRV_NAME, NULL}; + static char *envp[] = {"HOME=/", + "TERM=linux", + "PATH=/usr/bin:/bin", + NULL}; + + if (priv->ResetProgress == RESET_TYPE_SILENT) { + RT_TRACE((COMP_INIT | COMP_POWER | COMP_RF), + "GPIOChangeRFWorkItemCallBack(): Silent Reseting!!!!!!!\n"); + return; + } + + if (priv->rtllib->state != RTLLIB_LINKED) + return; + call_usermodehelper(ac_dc_check_script_path, argv, envp, 1); + + return; +}; + + +void init_rate_adaptive(struct net_device *dev) +{ + + struct r8192_priv *priv = rtllib_priv(dev); + struct rate_adaptive *pra = (struct rate_adaptive *)&priv->rate_adaptive; + + pra->ratr_state = DM_RATR_STA_MAX; + pra->high2low_rssi_thresh_for_ra = RateAdaptiveTH_High; + pra->low2high_rssi_thresh_for_ra20M = RateAdaptiveTH_Low_20M+5; + pra->low2high_rssi_thresh_for_ra40M = RateAdaptiveTH_Low_40M+5; + + pra->high_rssi_thresh_for_ra = RateAdaptiveTH_High+5; + pra->low_rssi_thresh_for_ra20M = RateAdaptiveTH_Low_20M; + pra->low_rssi_thresh_for_ra40M = RateAdaptiveTH_Low_40M; + + if (priv->CustomerID == RT_CID_819x_Netcore) + pra->ping_rssi_enable = 1; + else + pra->ping_rssi_enable = 0; + pra->ping_rssi_thresh_for_ra = 15; + + + if (priv->rf_type == RF_2T4R) { + pra->upper_rssi_threshold_ratr = 0x8f0f0000; + pra->middle_rssi_threshold_ratr = 0x8f0ff000; + pra->low_rssi_threshold_ratr = 0x8f0ff001; + pra->low_rssi_threshold_ratr_40M = 0x8f0ff005; + pra->low_rssi_threshold_ratr_20M = 0x8f0ff001; + pra->ping_rssi_ratr = 0x0000000d; + } else if (priv->rf_type == RF_1T2R) { + pra->upper_rssi_threshold_ratr = 0x000fc000; + pra->middle_rssi_threshold_ratr = 0x000ff000; + pra->low_rssi_threshold_ratr = 0x000ff001; + pra->low_rssi_threshold_ratr_40M = 0x000ff005; + pra->low_rssi_threshold_ratr_20M = 0x000ff001; + pra->ping_rssi_ratr = 0x0000000d; + } + +} + + +static void dm_check_rate_adaptive(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + struct rt_hi_throughput *pHTInfo = priv->rtllib->pHTInfo; + struct rate_adaptive *pra = (struct rate_adaptive *)&priv->rate_adaptive; + u32 currentRATR, targetRATR = 0; + u32 LowRSSIThreshForRA = 0, HighRSSIThreshForRA = 0; + bool bshort_gi_enabled = false; + static u8 ping_rssi_state; + + if (IS_NIC_DOWN(priv)) { + RT_TRACE(COMP_RATE, "<---- dm_check_rate_adaptive(): driver is going to unload\n"); + return; + } + + if (pra->rate_adaptive_disabled) + return; + + if (!(priv->rtllib->mode == WIRELESS_MODE_N_24G || + priv->rtllib->mode == WIRELESS_MODE_N_5G)) + return; + + if (priv->rtllib->state == RTLLIB_LINKED) { + + bshort_gi_enabled = (pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI40MHz) || + (!pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI20MHz); + + + pra->upper_rssi_threshold_ratr = + (pra->upper_rssi_threshold_ratr & (~BIT31)) | ((bshort_gi_enabled) ? BIT31 : 0); + + pra->middle_rssi_threshold_ratr = + (pra->middle_rssi_threshold_ratr & (~BIT31)) | ((bshort_gi_enabled) ? BIT31 : 0); + + if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) { + pra->low_rssi_threshold_ratr = + (pra->low_rssi_threshold_ratr_40M & (~BIT31)) | ((bshort_gi_enabled) ? BIT31 : 0); + } else { + pra->low_rssi_threshold_ratr = + (pra->low_rssi_threshold_ratr_20M & (~BIT31)) | ((bshort_gi_enabled) ? BIT31 : 0); + } + pra->ping_rssi_ratr = + (pra->ping_rssi_ratr & (~BIT31)) | ((bshort_gi_enabled) ? BIT31 : 0); + + if (pra->ratr_state == DM_RATR_STA_HIGH) { + HighRSSIThreshForRA = pra->high2low_rssi_thresh_for_ra; + LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ? + (pra->low_rssi_thresh_for_ra40M) : (pra->low_rssi_thresh_for_ra20M); + } else if (pra->ratr_state == DM_RATR_STA_LOW) { + HighRSSIThreshForRA = pra->high_rssi_thresh_for_ra; + LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ? + (pra->low2high_rssi_thresh_for_ra40M) : (pra->low2high_rssi_thresh_for_ra20M); + } else { + HighRSSIThreshForRA = pra->high_rssi_thresh_for_ra; + LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ? + (pra->low_rssi_thresh_for_ra40M) : (pra->low_rssi_thresh_for_ra20M); + } + + if (priv->undecorated_smoothed_pwdb >= (long)HighRSSIThreshForRA) { + pra->ratr_state = DM_RATR_STA_HIGH; + targetRATR = pra->upper_rssi_threshold_ratr; + } else if (priv->undecorated_smoothed_pwdb >= (long)LowRSSIThreshForRA) { + pra->ratr_state = DM_RATR_STA_MIDDLE; + targetRATR = pra->middle_rssi_threshold_ratr; + } else { + pra->ratr_state = DM_RATR_STA_LOW; + targetRATR = pra->low_rssi_threshold_ratr; + } + + if (pra->ping_rssi_enable) { + if (priv->undecorated_smoothed_pwdb < (long)(pra->ping_rssi_thresh_for_ra+5)) { + if ((priv->undecorated_smoothed_pwdb < (long)pra->ping_rssi_thresh_for_ra) || + ping_rssi_state) { + pra->ratr_state = DM_RATR_STA_LOW; + targetRATR = pra->ping_rssi_ratr; + ping_rssi_state = 1; + } + } else { + ping_rssi_state = 0; + } + } + + if (priv->rtllib->GetHalfNmodeSupportByAPsHandler(dev)) + targetRATR &= 0xf00fffff; + + currentRATR = read_nic_dword(dev, RATR0); + if (targetRATR != currentRATR) { + u32 ratr_value; + ratr_value = targetRATR; + RT_TRACE(COMP_RATE, + "currentRATR = %x, targetRATR = %x\n", + currentRATR, targetRATR); + if (priv->rf_type == RF_1T2R) + ratr_value &= ~(RATE_ALL_OFDM_2SS); + write_nic_dword(dev, RATR0, ratr_value); + write_nic_byte(dev, UFWP, 1); + + pra->last_ratr = targetRATR; + } + + } else { + pra->ratr_state = DM_RATR_STA_MAX; + } +} + +static void dm_init_bandwidth_autoswitch(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + priv->rtllib->bandwidth_auto_switch.threshold_20Mhzto40Mhz = BW_AUTO_SWITCH_LOW_HIGH; + priv->rtllib->bandwidth_auto_switch.threshold_40Mhzto20Mhz = BW_AUTO_SWITCH_HIGH_LOW; + priv->rtllib->bandwidth_auto_switch.bforced_tx20Mhz = false; + priv->rtllib->bandwidth_auto_switch.bautoswitch_enable = false; +} + +static void dm_bandwidth_autoswitch(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 || + !priv->rtllib->bandwidth_auto_switch.bautoswitch_enable) { + return; + } else { + if (priv->rtllib->bandwidth_auto_switch.bforced_tx20Mhz == false) { + if (priv->undecorated_smoothed_pwdb <= + priv->rtllib->bandwidth_auto_switch.threshold_40Mhzto20Mhz) + priv->rtllib->bandwidth_auto_switch.bforced_tx20Mhz = true; + } else { + if (priv->undecorated_smoothed_pwdb >= + priv->rtllib->bandwidth_auto_switch.threshold_20Mhzto40Mhz) + priv->rtllib->bandwidth_auto_switch.bforced_tx20Mhz = false; + + } + } +} + +static u32 OFDMSwingTable[OFDM_Table_Length] = { + 0x7f8001fe, + 0x71c001c7, + 0x65400195, + 0x5a400169, + 0x50800142, + 0x47c0011f, + 0x40000100, + 0x390000e4, + 0x32c000cb, + 0x2d4000b5, + 0x288000a2, + 0x24000090, + 0x20000080, + 0x1c800072, + 0x19800066, + 0x26c0005b, + 0x24400051, + 0x12000048, + 0x10000040 +}; + +static u8 CCKSwingTable_Ch1_Ch13[CCK_Table_length][8] = { + {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, + {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, + {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, + {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, + {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, + {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, + {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, + {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, + {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, + {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, + {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, + {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01} +}; + +static u8 CCKSwingTable_Ch14[CCK_Table_length][8] = { + {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, + {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, + {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, + {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, + {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, + {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, + {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, + {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, + {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, + {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, + {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, + {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00} +}; + +#define Pw_Track_Flag 0x11d +#define Tssi_Mea_Value 0x13c +#define Tssi_Report_Value1 0x134 +#define Tssi_Report_Value2 0x13e +#define FW_Busy_Flag 0x13f + +static void dm_TXPowerTrackingCallback_TSSI(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + bool bHighpowerstate, viviflag = false; + struct dcmd_txcmd tx_cmd; + u8 powerlevelOFDM24G; + int i = 0, j = 0, k = 0; + u8 RF_Type, tmp_report[5] = {0, 0, 0, 0, 0}; + u32 Value; + u8 Pwr_Flag; + u16 Avg_TSSI_Meas, TSSI_13dBm, Avg_TSSI_Meas_from_driver = 0; + u32 delta = 0; + + RT_TRACE(COMP_POWER_TRACKING, "%s()\n", __func__); + write_nic_byte(dev, Pw_Track_Flag, 0); + write_nic_byte(dev, FW_Busy_Flag, 0); + priv->rtllib->bdynamic_txpower_enable = false; + bHighpowerstate = priv->bDynamicTxHighPower; + + powerlevelOFDM24G = (u8)(priv->Pwr_Track>>24); + RF_Type = priv->rf_type; + Value = (RF_Type<<8) | powerlevelOFDM24G; + + RT_TRACE(COMP_POWER_TRACKING, "powerlevelOFDM24G = %x\n", + powerlevelOFDM24G); + + + for (j = 0; j <= 30; j++) { + + tx_cmd.Op = TXCMD_SET_TX_PWR_TRACKING; + tx_cmd.Length = 4; + tx_cmd.Value = Value; + cmpk_message_handle_tx(dev, (u8 *)&tx_cmd, + DESC_PACKET_TYPE_INIT, + sizeof(struct dcmd_txcmd)); + mdelay(1); + for (i = 0; i <= 30; i++) { + Pwr_Flag = read_nic_byte(dev, Pw_Track_Flag); + + if (Pwr_Flag == 0) { + mdelay(1); + + if (priv->bResetInProgress) { + RT_TRACE(COMP_POWER_TRACKING, + "we are in slient reset progress, so return\n"); + write_nic_byte(dev, Pw_Track_Flag, 0); + write_nic_byte(dev, FW_Busy_Flag, 0); + return; + } + if ((priv->rtllib->eRFPowerState != eRfOn)) { + RT_TRACE(COMP_POWER_TRACKING, + "we are in power save, so return\n"); + write_nic_byte(dev, Pw_Track_Flag, 0); + write_nic_byte(dev, FW_Busy_Flag, 0); + return; + } + + continue; + } + + Avg_TSSI_Meas = read_nic_word(dev, Tssi_Mea_Value); + + if (Avg_TSSI_Meas == 0) { + write_nic_byte(dev, Pw_Track_Flag, 0); + write_nic_byte(dev, FW_Busy_Flag, 0); + return; + } + + for (k = 0; k < 5; k++) { + if (k != 4) + tmp_report[k] = read_nic_byte(dev, + Tssi_Report_Value1+k); + else + tmp_report[k] = read_nic_byte(dev, + Tssi_Report_Value2); + + RT_TRACE(COMP_POWER_TRACKING, + "TSSI_report_value = %d\n", + tmp_report[k]); + + if (tmp_report[k] <= 20) { + viviflag = true; + break; + } + } + + if (viviflag == true) { + write_nic_byte(dev, Pw_Track_Flag, 0); + viviflag = false; + RT_TRACE(COMP_POWER_TRACKING, "we filted this data\n"); + for (k = 0; k < 5; k++) + tmp_report[k] = 0; + break; + } + + for (k = 0; k < 5; k++) + Avg_TSSI_Meas_from_driver += tmp_report[k]; + + Avg_TSSI_Meas_from_driver = Avg_TSSI_Meas_from_driver*100/5; + RT_TRACE(COMP_POWER_TRACKING, + "Avg_TSSI_Meas_from_driver = %d\n", + Avg_TSSI_Meas_from_driver); + TSSI_13dBm = priv->TSSI_13dBm; + RT_TRACE(COMP_POWER_TRACKING, "TSSI_13dBm = %d\n", TSSI_13dBm); + + if (Avg_TSSI_Meas_from_driver > TSSI_13dBm) + delta = Avg_TSSI_Meas_from_driver - TSSI_13dBm; + else + delta = TSSI_13dBm - Avg_TSSI_Meas_from_driver; + + if (delta <= E_FOR_TX_POWER_TRACK) { + priv->rtllib->bdynamic_txpower_enable = true; + write_nic_byte(dev, Pw_Track_Flag, 0); + write_nic_byte(dev, FW_Busy_Flag, 0); + RT_TRACE(COMP_POWER_TRACKING, + "tx power track is done\n"); + RT_TRACE(COMP_POWER_TRACKING, + "priv->rfa_txpowertrackingindex = %d\n", + priv->rfa_txpowertrackingindex); + RT_TRACE(COMP_POWER_TRACKING, + "priv->rfa_txpowertrackingindex_real = %d\n", + priv->rfa_txpowertrackingindex_real); + RT_TRACE(COMP_POWER_TRACKING, + "priv->CCKPresentAttentuation_difference = %d\n", + priv->CCKPresentAttentuation_difference); + RT_TRACE(COMP_POWER_TRACKING, + "priv->CCKPresentAttentuation = %d\n", + priv->CCKPresentAttentuation); + return; + } else { + if (Avg_TSSI_Meas_from_driver < TSSI_13dBm - E_FOR_TX_POWER_TRACK) { + if (RF_Type == RF_2T4R) { + + if ((priv->rfa_txpowertrackingindex > 0) && + (priv->rfc_txpowertrackingindex > 0)) { + priv->rfa_txpowertrackingindex--; + if (priv->rfa_txpowertrackingindex_real > 4) { + priv->rfa_txpowertrackingindex_real--; + rtl8192_setBBreg(dev, + rOFDM0_XATxIQImbalance, + bMaskDWord, + priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value); + } + + priv->rfc_txpowertrackingindex--; + if (priv->rfc_txpowertrackingindex_real > 4) { + priv->rfc_txpowertrackingindex_real--; + rtl8192_setBBreg(dev, + rOFDM0_XCTxIQImbalance, + bMaskDWord, + priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value); + } + } else { + rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, + bMaskDWord, + priv->txbbgain_table[4].txbbgain_value); + rtl8192_setBBreg(dev, + rOFDM0_XCTxIQImbalance, + bMaskDWord, priv->txbbgain_table[4].txbbgain_value); + } + } else { + if (priv->rfa_txpowertrackingindex > 0) { + priv->rfa_txpowertrackingindex--; + if (priv->rfa_txpowertrackingindex_real > 4) { + priv->rfa_txpowertrackingindex_real--; + rtl8192_setBBreg(dev, + rOFDM0_XATxIQImbalance, + bMaskDWord, + priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value); + } + } else + rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, + bMaskDWord, priv->txbbgain_table[4].txbbgain_value); + + } + } else { + if (RF_Type == RF_2T4R) { + if ((priv->rfa_txpowertrackingindex < + TxBBGainTableLength - 1) && + (priv->rfc_txpowertrackingindex < + TxBBGainTableLength - 1)) { + priv->rfa_txpowertrackingindex++; + priv->rfa_txpowertrackingindex_real++; + rtl8192_setBBreg(dev, + rOFDM0_XATxIQImbalance, + bMaskDWord, + priv->txbbgain_table + [priv->rfa_txpowertrackingindex_real].txbbgain_value); + priv->rfc_txpowertrackingindex++; + priv->rfc_txpowertrackingindex_real++; + rtl8192_setBBreg(dev, + rOFDM0_XCTxIQImbalance, + bMaskDWord, + priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value); + } else { + rtl8192_setBBreg(dev, + rOFDM0_XATxIQImbalance, + bMaskDWord, + priv->txbbgain_table[TxBBGainTableLength - 1].txbbgain_value); + rtl8192_setBBreg(dev, + rOFDM0_XCTxIQImbalance, + bMaskDWord, priv->txbbgain_table[TxBBGainTableLength - 1].txbbgain_value); + } + } else { + if (priv->rfa_txpowertrackingindex < (TxBBGainTableLength - 1)) { + priv->rfa_txpowertrackingindex++; + priv->rfa_txpowertrackingindex_real++; + rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, + bMaskDWord, + priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value); + } else + rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, + bMaskDWord, + priv->txbbgain_table[TxBBGainTableLength - 1].txbbgain_value); + } + } + if (RF_Type == RF_2T4R) { + priv->CCKPresentAttentuation_difference + = priv->rfa_txpowertrackingindex - priv->rfa_txpowertracking_default; + } else { + priv->CCKPresentAttentuation_difference + = priv->rfa_txpowertrackingindex_real - priv->rfa_txpowertracking_default; + } + + if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20) + priv->CCKPresentAttentuation = + priv->CCKPresentAttentuation_20Mdefault + + priv->CCKPresentAttentuation_difference; + else + priv->CCKPresentAttentuation = + priv->CCKPresentAttentuation_40Mdefault + + priv->CCKPresentAttentuation_difference; + + if (priv->CCKPresentAttentuation > (CCKTxBBGainTableLength-1)) + priv->CCKPresentAttentuation = CCKTxBBGainTableLength-1; + if (priv->CCKPresentAttentuation < 0) + priv->CCKPresentAttentuation = 0; + + if (priv->CCKPresentAttentuation > -1 && + priv->CCKPresentAttentuation < CCKTxBBGainTableLength) { + if (priv->rtllib->current_network.channel == 14 && + !priv->bcck_in_ch14) { + priv->bcck_in_ch14 = true; + dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); + } else if (priv->rtllib->current_network.channel != 14 && priv->bcck_in_ch14) { + priv->bcck_in_ch14 = false; + dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); + } else + dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); + } + RT_TRACE(COMP_POWER_TRACKING, + "priv->rfa_txpowertrackingindex = %d\n", + priv->rfa_txpowertrackingindex); + RT_TRACE(COMP_POWER_TRACKING, + "priv->rfa_txpowertrackingindex_real = %d\n", + priv->rfa_txpowertrackingindex_real); + RT_TRACE(COMP_POWER_TRACKING, + "priv->CCKPresentAttentuation_difference = %d\n", + priv->CCKPresentAttentuation_difference); + RT_TRACE(COMP_POWER_TRACKING, + "priv->CCKPresentAttentuation = %d\n", + priv->CCKPresentAttentuation); + + if (priv->CCKPresentAttentuation_difference <= -12 || priv->CCKPresentAttentuation_difference >= 24) { + priv->rtllib->bdynamic_txpower_enable = true; + write_nic_byte(dev, Pw_Track_Flag, 0); + write_nic_byte(dev, FW_Busy_Flag, 0); + RT_TRACE(COMP_POWER_TRACKING, "tx power track--->limited\n"); + return; + } + } + write_nic_byte(dev, Pw_Track_Flag, 0); + Avg_TSSI_Meas_from_driver = 0; + for (k = 0; k < 5; k++) + tmp_report[k] = 0; + break; + } + write_nic_byte(dev, FW_Busy_Flag, 0); + } + priv->rtllib->bdynamic_txpower_enable = true; + write_nic_byte(dev, Pw_Track_Flag, 0); +} + +static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device *dev) +{ +#define ThermalMeterVal 9 + struct r8192_priv *priv = rtllib_priv(dev); + u32 tmpRegA, TempCCk; + u8 tmpOFDMindex, tmpCCKindex, tmpCCK20Mindex, tmpCCK40Mindex, tmpval; + int i = 0, CCKSwingNeedUpdate = 0; + + if (!priv->btxpower_trackingInit) { + tmpRegA = rtl8192_QueryBBReg(dev, rOFDM0_XATxIQImbalance, bMaskDWord); + for (i = 0; i < OFDM_Table_Length; i++) { + if (tmpRegA == OFDMSwingTable[i]) { + priv->OFDM_index[0] = (u8)i; + RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x = 0x%x, OFDM_index = 0x%x\n", + rOFDM0_XATxIQImbalance, tmpRegA, priv->OFDM_index[0]); + } + } + + TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2); + for (i = 0; i < CCK_Table_length; i++) { + if (TempCCk == (u32)CCKSwingTable_Ch1_Ch13[i][0]) { + priv->CCK_index = (u8) i; + RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x" + " = 0x%x, CCK_index = 0x%x\n", + rCCK0_TxFilter1, TempCCk, + priv->CCK_index); + break; + } + } + priv->btxpower_trackingInit = true; + return; + } + + tmpRegA = rtl8192_phy_QueryRFReg(dev, RF90_PATH_A, 0x12, 0x078); + RT_TRACE(COMP_POWER_TRACKING, "Readback ThermalMeterA = %d\n", tmpRegA); + if (tmpRegA < 3 || tmpRegA > 13) + return; + if (tmpRegA >= 12) + tmpRegA = 12; + RT_TRACE(COMP_POWER_TRACKING, "Valid ThermalMeterA = %d\n", tmpRegA); + priv->ThermalMeter[0] = ThermalMeterVal; + priv->ThermalMeter[1] = ThermalMeterVal; + + if (priv->ThermalMeter[0] >= (u8)tmpRegA) { + tmpOFDMindex = tmpCCK20Mindex = 6+(priv->ThermalMeter[0] - + (u8)tmpRegA); + tmpCCK40Mindex = tmpCCK20Mindex - 6; + if (tmpOFDMindex >= OFDM_Table_Length) + tmpOFDMindex = OFDM_Table_Length-1; + if (tmpCCK20Mindex >= CCK_Table_length) + tmpCCK20Mindex = CCK_Table_length-1; + if (tmpCCK40Mindex >= CCK_Table_length) + tmpCCK40Mindex = CCK_Table_length-1; + } else { + tmpval = ((u8)tmpRegA - priv->ThermalMeter[0]); + if (tmpval >= 6) + tmpOFDMindex = tmpCCK20Mindex = 0; + else + tmpOFDMindex = tmpCCK20Mindex = 6 - tmpval; + tmpCCK40Mindex = 0; + } + if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) + tmpCCKindex = tmpCCK40Mindex; + else + tmpCCKindex = tmpCCK20Mindex; + + priv->Record_CCK_20Mindex = tmpCCK20Mindex; + priv->Record_CCK_40Mindex = tmpCCK40Mindex; + RT_TRACE(COMP_POWER_TRACKING, "Record_CCK_20Mindex / Record_CCK_40" + "Mindex = %d / %d.\n", + priv->Record_CCK_20Mindex, priv->Record_CCK_40Mindex); + + if (priv->rtllib->current_network.channel == 14 && + !priv->bcck_in_ch14) { + priv->bcck_in_ch14 = true; + CCKSwingNeedUpdate = 1; + } else if (priv->rtllib->current_network.channel != 14 && + priv->bcck_in_ch14) { + priv->bcck_in_ch14 = false; + CCKSwingNeedUpdate = 1; + } + + if (priv->CCK_index != tmpCCKindex) { + priv->CCK_index = tmpCCKindex; + CCKSwingNeedUpdate = 1; + } + + if (CCKSwingNeedUpdate) + dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); + if (priv->OFDM_index[0] != tmpOFDMindex) { + priv->OFDM_index[0] = tmpOFDMindex; + rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, + OFDMSwingTable[priv->OFDM_index[0]]); + RT_TRACE(COMP_POWER_TRACKING, "Update OFDMSwing[%d] = 0x%x\n", + priv->OFDM_index[0], + OFDMSwingTable[priv->OFDM_index[0]]); + } + priv->txpower_count = 0; +} + +void dm_txpower_trackingcallback(void *data) +{ + struct r8192_priv *priv = container_of_dwork_rsl(data, + struct r8192_priv, txpower_tracking_wq); + struct net_device *dev = priv->rtllib->dev; + + if (priv->IC_Cut >= IC_VersionCut_D) + dm_TXPowerTrackingCallback_TSSI(dev); + else + dm_TXPowerTrackingCallback_ThermalMeter(dev); +} + +static void dm_InitializeTXPowerTracking_TSSI(struct net_device *dev) +{ + + struct r8192_priv *priv = rtllib_priv(dev); + + priv->txbbgain_table[0].txbb_iq_amplifygain = 12; + priv->txbbgain_table[0].txbbgain_value = 0x7f8001fe; + priv->txbbgain_table[1].txbb_iq_amplifygain = 11; + priv->txbbgain_table[1].txbbgain_value = 0x788001e2; + priv->txbbgain_table[2].txbb_iq_amplifygain = 10; + priv->txbbgain_table[2].txbbgain_value = 0x71c001c7; + priv->txbbgain_table[3].txbb_iq_amplifygain = 9; + priv->txbbgain_table[3].txbbgain_value = 0x6b8001ae; + priv->txbbgain_table[4].txbb_iq_amplifygain = 8; + priv->txbbgain_table[4].txbbgain_value = 0x65400195; + priv->txbbgain_table[5].txbb_iq_amplifygain = 7; + priv->txbbgain_table[5].txbbgain_value = 0x5fc0017f; + priv->txbbgain_table[6].txbb_iq_amplifygain = 6; + priv->txbbgain_table[6].txbbgain_value = 0x5a400169; + priv->txbbgain_table[7].txbb_iq_amplifygain = 5; + priv->txbbgain_table[7].txbbgain_value = 0x55400155; + priv->txbbgain_table[8].txbb_iq_amplifygain = 4; + priv->txbbgain_table[8].txbbgain_value = 0x50800142; + priv->txbbgain_table[9].txbb_iq_amplifygain = 3; + priv->txbbgain_table[9].txbbgain_value = 0x4c000130; + priv->txbbgain_table[10].txbb_iq_amplifygain = 2; + priv->txbbgain_table[10].txbbgain_value = 0x47c0011f; + priv->txbbgain_table[11].txbb_iq_amplifygain = 1; + priv->txbbgain_table[11].txbbgain_value = 0x43c0010f; + priv->txbbgain_table[12].txbb_iq_amplifygain = 0; + priv->txbbgain_table[12].txbbgain_value = 0x40000100; + priv->txbbgain_table[13].txbb_iq_amplifygain = -1; + priv->txbbgain_table[13].txbbgain_value = 0x3c8000f2; + priv->txbbgain_table[14].txbb_iq_amplifygain = -2; + priv->txbbgain_table[14].txbbgain_value = 0x390000e4; + priv->txbbgain_table[15].txbb_iq_amplifygain = -3; + priv->txbbgain_table[15].txbbgain_value = 0x35c000d7; + priv->txbbgain_table[16].txbb_iq_amplifygain = -4; + priv->txbbgain_table[16].txbbgain_value = 0x32c000cb; + priv->txbbgain_table[17].txbb_iq_amplifygain = -5; + priv->txbbgain_table[17].txbbgain_value = 0x300000c0; + priv->txbbgain_table[18].txbb_iq_amplifygain = -6; + priv->txbbgain_table[18].txbbgain_value = 0x2d4000b5; + priv->txbbgain_table[19].txbb_iq_amplifygain = -7; + priv->txbbgain_table[19].txbbgain_value = 0x2ac000ab; + priv->txbbgain_table[20].txbb_iq_amplifygain = -8; + priv->txbbgain_table[20].txbbgain_value = 0x288000a2; + priv->txbbgain_table[21].txbb_iq_amplifygain = -9; + priv->txbbgain_table[21].txbbgain_value = 0x26000098; + priv->txbbgain_table[22].txbb_iq_amplifygain = -10; + priv->txbbgain_table[22].txbbgain_value = 0x24000090; + priv->txbbgain_table[23].txbb_iq_amplifygain = -11; + priv->txbbgain_table[23].txbbgain_value = 0x22000088; + priv->txbbgain_table[24].txbb_iq_amplifygain = -12; + priv->txbbgain_table[24].txbbgain_value = 0x20000080; + priv->txbbgain_table[25].txbb_iq_amplifygain = -13; + priv->txbbgain_table[25].txbbgain_value = 0x1a00006c; + priv->txbbgain_table[26].txbb_iq_amplifygain = -14; + priv->txbbgain_table[26].txbbgain_value = 0x1c800072; + priv->txbbgain_table[27].txbb_iq_amplifygain = -15; + priv->txbbgain_table[27].txbbgain_value = 0x18000060; + priv->txbbgain_table[28].txbb_iq_amplifygain = -16; + priv->txbbgain_table[28].txbbgain_value = 0x19800066; + priv->txbbgain_table[29].txbb_iq_amplifygain = -17; + priv->txbbgain_table[29].txbbgain_value = 0x15800056; + priv->txbbgain_table[30].txbb_iq_amplifygain = -18; + priv->txbbgain_table[30].txbbgain_value = 0x26c0005b; + priv->txbbgain_table[31].txbb_iq_amplifygain = -19; + priv->txbbgain_table[31].txbbgain_value = 0x14400051; + priv->txbbgain_table[32].txbb_iq_amplifygain = -20; + priv->txbbgain_table[32].txbbgain_value = 0x24400051; + priv->txbbgain_table[33].txbb_iq_amplifygain = -21; + priv->txbbgain_table[33].txbbgain_value = 0x1300004c; + priv->txbbgain_table[34].txbb_iq_amplifygain = -22; + priv->txbbgain_table[34].txbbgain_value = 0x12000048; + priv->txbbgain_table[35].txbb_iq_amplifygain = -23; + priv->txbbgain_table[35].txbbgain_value = 0x11000044; + priv->txbbgain_table[36].txbb_iq_amplifygain = -24; + priv->txbbgain_table[36].txbbgain_value = 0x10000040; + + priv->cck_txbbgain_table[0].ccktxbb_valuearray[0] = 0x36; + priv->cck_txbbgain_table[0].ccktxbb_valuearray[1] = 0x35; + priv->cck_txbbgain_table[0].ccktxbb_valuearray[2] = 0x2e; + priv->cck_txbbgain_table[0].ccktxbb_valuearray[3] = 0x25; + priv->cck_txbbgain_table[0].ccktxbb_valuearray[4] = 0x1c; + priv->cck_txbbgain_table[0].ccktxbb_valuearray[5] = 0x12; + priv->cck_txbbgain_table[0].ccktxbb_valuearray[6] = 0x09; + priv->cck_txbbgain_table[0].ccktxbb_valuearray[7] = 0x04; + + priv->cck_txbbgain_table[1].ccktxbb_valuearray[0] = 0x33; + priv->cck_txbbgain_table[1].ccktxbb_valuearray[1] = 0x32; + priv->cck_txbbgain_table[1].ccktxbb_valuearray[2] = 0x2b; + priv->cck_txbbgain_table[1].ccktxbb_valuearray[3] = 0x23; + priv->cck_txbbgain_table[1].ccktxbb_valuearray[4] = 0x1a; + priv->cck_txbbgain_table[1].ccktxbb_valuearray[5] = 0x11; + priv->cck_txbbgain_table[1].ccktxbb_valuearray[6] = 0x08; + priv->cck_txbbgain_table[1].ccktxbb_valuearray[7] = 0x04; + + priv->cck_txbbgain_table[2].ccktxbb_valuearray[0] = 0x30; + priv->cck_txbbgain_table[2].ccktxbb_valuearray[1] = 0x2f; + priv->cck_txbbgain_table[2].ccktxbb_valuearray[2] = 0x29; + priv->cck_txbbgain_table[2].ccktxbb_valuearray[3] = 0x21; + priv->cck_txbbgain_table[2].ccktxbb_valuearray[4] = 0x19; + priv->cck_txbbgain_table[2].ccktxbb_valuearray[5] = 0x10; + priv->cck_txbbgain_table[2].ccktxbb_valuearray[6] = 0x08; + priv->cck_txbbgain_table[2].ccktxbb_valuearray[7] = 0x03; + + priv->cck_txbbgain_table[3].ccktxbb_valuearray[0] = 0x2d; + priv->cck_txbbgain_table[3].ccktxbb_valuearray[1] = 0x2d; + priv->cck_txbbgain_table[3].ccktxbb_valuearray[2] = 0x27; + priv->cck_txbbgain_table[3].ccktxbb_valuearray[3] = 0x1f; + priv->cck_txbbgain_table[3].ccktxbb_valuearray[4] = 0x18; + priv->cck_txbbgain_table[3].ccktxbb_valuearray[5] = 0x0f; + priv->cck_txbbgain_table[3].ccktxbb_valuearray[6] = 0x08; + priv->cck_txbbgain_table[3].ccktxbb_valuearray[7] = 0x03; + + priv->cck_txbbgain_table[4].ccktxbb_valuearray[0] = 0x2b; + priv->cck_txbbgain_table[4].ccktxbb_valuearray[1] = 0x2a; + priv->cck_txbbgain_table[4].ccktxbb_valuearray[2] = 0x25; + priv->cck_txbbgain_table[4].ccktxbb_valuearray[3] = 0x1e; + priv->cck_txbbgain_table[4].ccktxbb_valuearray[4] = 0x16; + priv->cck_txbbgain_table[4].ccktxbb_valuearray[5] = 0x0e; + priv->cck_txbbgain_table[4].ccktxbb_valuearray[6] = 0x07; + priv->cck_txbbgain_table[4].ccktxbb_valuearray[7] = 0x03; + + priv->cck_txbbgain_table[5].ccktxbb_valuearray[0] = 0x28; + priv->cck_txbbgain_table[5].ccktxbb_valuearray[1] = 0x28; + priv->cck_txbbgain_table[5].ccktxbb_valuearray[2] = 0x22; + priv->cck_txbbgain_table[5].ccktxbb_valuearray[3] = 0x1c; + priv->cck_txbbgain_table[5].ccktxbb_valuearray[4] = 0x15; + priv->cck_txbbgain_table[5].ccktxbb_valuearray[5] = 0x0d; + priv->cck_txbbgain_table[5].ccktxbb_valuearray[6] = 0x07; + priv->cck_txbbgain_table[5].ccktxbb_valuearray[7] = 0x03; + + priv->cck_txbbgain_table[6].ccktxbb_valuearray[0] = 0x26; + priv->cck_txbbgain_table[6].ccktxbb_valuearray[1] = 0x25; + priv->cck_txbbgain_table[6].ccktxbb_valuearray[2] = 0x21; + priv->cck_txbbgain_table[6].ccktxbb_valuearray[3] = 0x1b; + priv->cck_txbbgain_table[6].ccktxbb_valuearray[4] = 0x14; + priv->cck_txbbgain_table[6].ccktxbb_valuearray[5] = 0x0d; + priv->cck_txbbgain_table[6].ccktxbb_valuearray[6] = 0x06; + priv->cck_txbbgain_table[6].ccktxbb_valuearray[7] = 0x03; + + priv->cck_txbbgain_table[7].ccktxbb_valuearray[0] = 0x24; + priv->cck_txbbgain_table[7].ccktxbb_valuearray[1] = 0x23; + priv->cck_txbbgain_table[7].ccktxbb_valuearray[2] = 0x1f; + priv->cck_txbbgain_table[7].ccktxbb_valuearray[3] = 0x19; + priv->cck_txbbgain_table[7].ccktxbb_valuearray[4] = 0x13; + priv->cck_txbbgain_table[7].ccktxbb_valuearray[5] = 0x0c; + priv->cck_txbbgain_table[7].ccktxbb_valuearray[6] = 0x06; + priv->cck_txbbgain_table[7].ccktxbb_valuearray[7] = 0x03; + + priv->cck_txbbgain_table[8].ccktxbb_valuearray[0] = 0x22; + priv->cck_txbbgain_table[8].ccktxbb_valuearray[1] = 0x21; + priv->cck_txbbgain_table[8].ccktxbb_valuearray[2] = 0x1d; + priv->cck_txbbgain_table[8].ccktxbb_valuearray[3] = 0x18; + priv->cck_txbbgain_table[8].ccktxbb_valuearray[4] = 0x11; + priv->cck_txbbgain_table[8].ccktxbb_valuearray[5] = 0x0b; + priv->cck_txbbgain_table[8].ccktxbb_valuearray[6] = 0x06; + priv->cck_txbbgain_table[8].ccktxbb_valuearray[7] = 0x02; + + priv->cck_txbbgain_table[9].ccktxbb_valuearray[0] = 0x20; + priv->cck_txbbgain_table[9].ccktxbb_valuearray[1] = 0x20; + priv->cck_txbbgain_table[9].ccktxbb_valuearray[2] = 0x1b; + priv->cck_txbbgain_table[9].ccktxbb_valuearray[3] = 0x16; + priv->cck_txbbgain_table[9].ccktxbb_valuearray[4] = 0x11; + priv->cck_txbbgain_table[9].ccktxbb_valuearray[5] = 0x08; + priv->cck_txbbgain_table[9].ccktxbb_valuearray[6] = 0x05; + priv->cck_txbbgain_table[9].ccktxbb_valuearray[7] = 0x02; + + priv->cck_txbbgain_table[10].ccktxbb_valuearray[0] = 0x1f; + priv->cck_txbbgain_table[10].ccktxbb_valuearray[1] = 0x1e; + priv->cck_txbbgain_table[10].ccktxbb_valuearray[2] = 0x1a; + priv->cck_txbbgain_table[10].ccktxbb_valuearray[3] = 0x15; + priv->cck_txbbgain_table[10].ccktxbb_valuearray[4] = 0x10; + priv->cck_txbbgain_table[10].ccktxbb_valuearray[5] = 0x0a; + priv->cck_txbbgain_table[10].ccktxbb_valuearray[6] = 0x05; + priv->cck_txbbgain_table[10].ccktxbb_valuearray[7] = 0x02; + + priv->cck_txbbgain_table[11].ccktxbb_valuearray[0] = 0x1d; + priv->cck_txbbgain_table[11].ccktxbb_valuearray[1] = 0x1c; + priv->cck_txbbgain_table[11].ccktxbb_valuearray[2] = 0x18; + priv->cck_txbbgain_table[11].ccktxbb_valuearray[3] = 0x14; + priv->cck_txbbgain_table[11].ccktxbb_valuearray[4] = 0x0f; + priv->cck_txbbgain_table[11].ccktxbb_valuearray[5] = 0x0a; + priv->cck_txbbgain_table[11].ccktxbb_valuearray[6] = 0x05; + priv->cck_txbbgain_table[11].ccktxbb_valuearray[7] = 0x02; + + priv->cck_txbbgain_table[12].ccktxbb_valuearray[0] = 0x1b; + priv->cck_txbbgain_table[12].ccktxbb_valuearray[1] = 0x1a; + priv->cck_txbbgain_table[12].ccktxbb_valuearray[2] = 0x17; + priv->cck_txbbgain_table[12].ccktxbb_valuearray[3] = 0x13; + priv->cck_txbbgain_table[12].ccktxbb_valuearray[4] = 0x0e; + priv->cck_txbbgain_table[12].ccktxbb_valuearray[5] = 0x09; + priv->cck_txbbgain_table[12].ccktxbb_valuearray[6] = 0x04; + priv->cck_txbbgain_table[12].ccktxbb_valuearray[7] = 0x02; + + priv->cck_txbbgain_table[13].ccktxbb_valuearray[0] = 0x1a; + priv->cck_txbbgain_table[13].ccktxbb_valuearray[1] = 0x19; + priv->cck_txbbgain_table[13].ccktxbb_valuearray[2] = 0x16; + priv->cck_txbbgain_table[13].ccktxbb_valuearray[3] = 0x12; + priv->cck_txbbgain_table[13].ccktxbb_valuearray[4] = 0x0d; + priv->cck_txbbgain_table[13].ccktxbb_valuearray[5] = 0x09; + priv->cck_txbbgain_table[13].ccktxbb_valuearray[6] = 0x04; + priv->cck_txbbgain_table[13].ccktxbb_valuearray[7] = 0x02; + + priv->cck_txbbgain_table[14].ccktxbb_valuearray[0] = 0x18; + priv->cck_txbbgain_table[14].ccktxbb_valuearray[1] = 0x17; + priv->cck_txbbgain_table[14].ccktxbb_valuearray[2] = 0x15; + priv->cck_txbbgain_table[14].ccktxbb_valuearray[3] = 0x11; + priv->cck_txbbgain_table[14].ccktxbb_valuearray[4] = 0x0c; + priv->cck_txbbgain_table[14].ccktxbb_valuearray[5] = 0x08; + priv->cck_txbbgain_table[14].ccktxbb_valuearray[6] = 0x04; + priv->cck_txbbgain_table[14].ccktxbb_valuearray[7] = 0x02; + + priv->cck_txbbgain_table[15].ccktxbb_valuearray[0] = 0x17; + priv->cck_txbbgain_table[15].ccktxbb_valuearray[1] = 0x16; + priv->cck_txbbgain_table[15].ccktxbb_valuearray[2] = 0x13; + priv->cck_txbbgain_table[15].ccktxbb_valuearray[3] = 0x10; + priv->cck_txbbgain_table[15].ccktxbb_valuearray[4] = 0x0c; + priv->cck_txbbgain_table[15].ccktxbb_valuearray[5] = 0x08; + priv->cck_txbbgain_table[15].ccktxbb_valuearray[6] = 0x04; + priv->cck_txbbgain_table[15].ccktxbb_valuearray[7] = 0x02; + + priv->cck_txbbgain_table[16].ccktxbb_valuearray[0] = 0x16; + priv->cck_txbbgain_table[16].ccktxbb_valuearray[1] = 0x15; + priv->cck_txbbgain_table[16].ccktxbb_valuearray[2] = 0x12; + priv->cck_txbbgain_table[16].ccktxbb_valuearray[3] = 0x0f; + priv->cck_txbbgain_table[16].ccktxbb_valuearray[4] = 0x0b; + priv->cck_txbbgain_table[16].ccktxbb_valuearray[5] = 0x07; + priv->cck_txbbgain_table[16].ccktxbb_valuearray[6] = 0x04; + priv->cck_txbbgain_table[16].ccktxbb_valuearray[7] = 0x01; + + priv->cck_txbbgain_table[17].ccktxbb_valuearray[0] = 0x14; + priv->cck_txbbgain_table[17].ccktxbb_valuearray[1] = 0x14; + priv->cck_txbbgain_table[17].ccktxbb_valuearray[2] = 0x11; + priv->cck_txbbgain_table[17].ccktxbb_valuearray[3] = 0x0e; + priv->cck_txbbgain_table[17].ccktxbb_valuearray[4] = 0x0b; + priv->cck_txbbgain_table[17].ccktxbb_valuearray[5] = 0x07; + priv->cck_txbbgain_table[17].ccktxbb_valuearray[6] = 0x03; + priv->cck_txbbgain_table[17].ccktxbb_valuearray[7] = 0x02; + + priv->cck_txbbgain_table[18].ccktxbb_valuearray[0] = 0x13; + priv->cck_txbbgain_table[18].ccktxbb_valuearray[1] = 0x13; + priv->cck_txbbgain_table[18].ccktxbb_valuearray[2] = 0x10; + priv->cck_txbbgain_table[18].ccktxbb_valuearray[3] = 0x0d; + priv->cck_txbbgain_table[18].ccktxbb_valuearray[4] = 0x0a; + priv->cck_txbbgain_table[18].ccktxbb_valuearray[5] = 0x06; + priv->cck_txbbgain_table[18].ccktxbb_valuearray[6] = 0x03; + priv->cck_txbbgain_table[18].ccktxbb_valuearray[7] = 0x01; + + priv->cck_txbbgain_table[19].ccktxbb_valuearray[0] = 0x12; + priv->cck_txbbgain_table[19].ccktxbb_valuearray[1] = 0x12; + priv->cck_txbbgain_table[19].ccktxbb_valuearray[2] = 0x0f; + priv->cck_txbbgain_table[19].ccktxbb_valuearray[3] = 0x0c; + priv->cck_txbbgain_table[19].ccktxbb_valuearray[4] = 0x09; + priv->cck_txbbgain_table[19].ccktxbb_valuearray[5] = 0x06; + priv->cck_txbbgain_table[19].ccktxbb_valuearray[6] = 0x03; + priv->cck_txbbgain_table[19].ccktxbb_valuearray[7] = 0x01; + + priv->cck_txbbgain_table[20].ccktxbb_valuearray[0] = 0x11; + priv->cck_txbbgain_table[20].ccktxbb_valuearray[1] = 0x11; + priv->cck_txbbgain_table[20].ccktxbb_valuearray[2] = 0x0f; + priv->cck_txbbgain_table[20].ccktxbb_valuearray[3] = 0x0c; + priv->cck_txbbgain_table[20].ccktxbb_valuearray[4] = 0x09; + priv->cck_txbbgain_table[20].ccktxbb_valuearray[5] = 0x06; + priv->cck_txbbgain_table[20].ccktxbb_valuearray[6] = 0x03; + priv->cck_txbbgain_table[20].ccktxbb_valuearray[7] = 0x01; + + priv->cck_txbbgain_table[21].ccktxbb_valuearray[0] = 0x10; + priv->cck_txbbgain_table[21].ccktxbb_valuearray[1] = 0x10; + priv->cck_txbbgain_table[21].ccktxbb_valuearray[2] = 0x0e; + priv->cck_txbbgain_table[21].ccktxbb_valuearray[3] = 0x0b; + priv->cck_txbbgain_table[21].ccktxbb_valuearray[4] = 0x08; + priv->cck_txbbgain_table[21].ccktxbb_valuearray[5] = 0x05; + priv->cck_txbbgain_table[21].ccktxbb_valuearray[6] = 0x03; + priv->cck_txbbgain_table[21].ccktxbb_valuearray[7] = 0x01; + + priv->cck_txbbgain_table[22].ccktxbb_valuearray[0] = 0x0f; + priv->cck_txbbgain_table[22].ccktxbb_valuearray[1] = 0x0f; + priv->cck_txbbgain_table[22].ccktxbb_valuearray[2] = 0x0d; + priv->cck_txbbgain_table[22].ccktxbb_valuearray[3] = 0x0b; + priv->cck_txbbgain_table[22].ccktxbb_valuearray[4] = 0x08; + priv->cck_txbbgain_table[22].ccktxbb_valuearray[5] = 0x05; + priv->cck_txbbgain_table[22].ccktxbb_valuearray[6] = 0x03; + priv->cck_txbbgain_table[22].ccktxbb_valuearray[7] = 0x01; + + priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[0] = 0x36; + priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[1] = 0x35; + priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[2] = 0x2e; + priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[3] = 0x1b; + priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[0] = 0x33; + priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[1] = 0x32; + priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[2] = 0x2b; + priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[3] = 0x19; + priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[0] = 0x30; + priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[1] = 0x2f; + priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[2] = 0x29; + priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[3] = 0x18; + priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[0] = 0x2d; + priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[1] = 0x2d; + priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[2] = 0x27; + priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[3] = 0x17; + priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[0] = 0x2b; + priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[1] = 0x2a; + priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[2] = 0x25; + priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[3] = 0x15; + priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[0] = 0x28; + priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[1] = 0x28; + priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[2] = 0x22; + priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[3] = 0x14; + priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[0] = 0x26; + priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[1] = 0x25; + priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[2] = 0x21; + priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[3] = 0x13; + priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[0] = 0x24; + priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[1] = 0x23; + priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[2] = 0x1f; + priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[3] = 0x12; + priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[0] = 0x22; + priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[1] = 0x21; + priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[2] = 0x1d; + priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[3] = 0x11; + priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[0] = 0x20; + priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[1] = 0x20; + priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[2] = 0x1b; + priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[3] = 0x10; + priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[0] = 0x1f; + priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[1] = 0x1e; + priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[2] = 0x1a; + priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[3] = 0x0f; + priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[0] = 0x1d; + priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[1] = 0x1c; + priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[2] = 0x18; + priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[3] = 0x0e; + priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[0] = 0x1b; + priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[1] = 0x1a; + priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[2] = 0x17; + priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[3] = 0x0e; + priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[0] = 0x1a; + priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[1] = 0x19; + priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[2] = 0x16; + priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[3] = 0x0d; + priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[0] = 0x18; + priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[1] = 0x17; + priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[2] = 0x15; + priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[3] = 0x0c; + priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[0] = 0x17; + priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[1] = 0x16; + priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[2] = 0x13; + priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[3] = 0x0b; + priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[0] = 0x16; + priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[1] = 0x15; + priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[2] = 0x12; + priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[3] = 0x0b; + priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[0] = 0x14; + priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[1] = 0x14; + priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[2] = 0x11; + priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[3] = 0x0a; + priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[0] = 0x13; + priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[1] = 0x13; + priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[2] = 0x10; + priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[3] = 0x0a; + priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[0] = 0x12; + priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[1] = 0x12; + priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[2] = 0x0f; + priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[3] = 0x09; + priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[0] = 0x11; + priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[1] = 0x11; + priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[2] = 0x0f; + priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[3] = 0x09; + priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[0] = 0x10; + priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[1] = 0x10; + priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[2] = 0x0e; + priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[3] = 0x08; + priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[7] = 0x00; + + priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[0] = 0x0f; + priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[1] = 0x0f; + priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[2] = 0x0d; + priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[3] = 0x08; + priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[4] = 0x00; + priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[5] = 0x00; + priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[6] = 0x00; + priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[7] = 0x00; + + priv->btxpower_tracking = true; + priv->txpower_count = 0; + priv->btxpower_trackingInit = false; + +} + +static void dm_InitializeTXPowerTracking_ThermalMeter(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + + if (priv->rtllib->FwRWRF) + priv->btxpower_tracking = true; + else + priv->btxpower_tracking = false; + priv->txpower_count = 0; + priv->btxpower_trackingInit = false; + RT_TRACE(COMP_POWER_TRACKING, "pMgntInfo->bTXPowerTracking = %d\n", + priv->btxpower_tracking); +} + +void dm_initialize_txpower_tracking(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + if (priv->IC_Cut >= IC_VersionCut_D) + dm_InitializeTXPowerTracking_TSSI(dev); + else + dm_InitializeTXPowerTracking_ThermalMeter(dev); +} + +static void dm_CheckTXPowerTracking_TSSI(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + static u32 tx_power_track_counter; + RT_TRACE(COMP_POWER_TRACKING, "%s()\n", __func__); + if (read_nic_byte(dev, 0x11e) == 1) + return; + if (!priv->btxpower_tracking) + return; + tx_power_track_counter++; + + + if (tx_power_track_counter >= 180) { + queue_delayed_work_rsl(priv->priv_wq, &priv->txpower_tracking_wq, 0); + tx_power_track_counter = 0; + } + +} +static void dm_CheckTXPowerTracking_ThermalMeter(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + static u8 TM_Trigger; + u8 TxPowerCheckCnt = 0; + + if (IS_HARDWARE_TYPE_8192SE(dev)) + TxPowerCheckCnt = 5; + else + TxPowerCheckCnt = 2; + if (!priv->btxpower_tracking) { + return; + } else { + if (priv->txpower_count <= TxPowerCheckCnt) { + priv->txpower_count++; + return; + } + } + + if (!TM_Trigger) { + { + rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d); + rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f); + rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d); + rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f); + } + TM_Trigger = 1; + return; + } else { + printk(KERN_INFO "===============>Schedule TxPowerTrackingWorkItem\n"); + + queue_delayed_work_rsl(priv->priv_wq, &priv->txpower_tracking_wq, 0); + TM_Trigger = 0; + } + + } + +static void dm_check_txpower_tracking(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + if (priv->IC_Cut >= IC_VersionCut_D) + dm_CheckTXPowerTracking_TSSI(dev); + else + dm_CheckTXPowerTracking_ThermalMeter(dev); +} + +static void dm_CCKTxPowerAdjust_TSSI(struct net_device *dev, bool bInCH14) +{ + u32 TempVal; + struct r8192_priv *priv = rtllib_priv(dev); + TempVal = 0; + if (!bInCH14) { + TempVal = (u32)(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[0] + + (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[1]<<8)) ; + + rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal); + TempVal = 0; + TempVal = (u32)(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[2] + + (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[3]<<8) + + (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[4]<<16)+ + (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[5]<<24)); + rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal); + TempVal = 0; + TempVal = (u32)(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[6] + + (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[7]<<8)) ; + + rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal); + } else { + TempVal = (u32)(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[0] + + (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[1]<<8)) ; + + rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal); + TempVal = 0; + TempVal = (u32)(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[2] + + (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[3]<<8) + + (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[4]<<16)+ + (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[5]<<24)); + rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal); + TempVal = 0; + TempVal = (u32)(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[6] + + (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[7]<<8)) ; + + rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal); + } + + +} + +static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH14) +{ + u32 TempVal; + struct r8192_priv *priv = rtllib_priv(dev); + + TempVal = 0; + if (!bInCH14) { + TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][0] + + (CCKSwingTable_Ch1_Ch13[priv->CCK_index][1]<<8) ; + rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal); + RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n", + rCCK0_TxFilter1, TempVal); + TempVal = 0; + TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][2] + + (CCKSwingTable_Ch1_Ch13[priv->CCK_index][3]<<8) + + (CCKSwingTable_Ch1_Ch13[priv->CCK_index][4]<<16)+ + (CCKSwingTable_Ch1_Ch13[priv->CCK_index][5]<<24); + rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal); + RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n", + rCCK0_TxFilter2, TempVal); + TempVal = 0; + TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][6] + + (CCKSwingTable_Ch1_Ch13[priv->CCK_index][7]<<8) ; + + rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal); + RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n", + rCCK0_DebugPort, TempVal); + } else { + TempVal = CCKSwingTable_Ch14[priv->CCK_index][0] + + (CCKSwingTable_Ch14[priv->CCK_index][1]<<8) ; + + rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal); + RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n", + rCCK0_TxFilter1, TempVal); + TempVal = 0; + TempVal = CCKSwingTable_Ch14[priv->CCK_index][2] + + (CCKSwingTable_Ch14[priv->CCK_index][3]<<8) + + (CCKSwingTable_Ch14[priv->CCK_index][4]<<16)+ + (CCKSwingTable_Ch14[priv->CCK_index][5]<<24); + rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal); + RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n", + rCCK0_TxFilter2, TempVal); + TempVal = 0; + TempVal = CCKSwingTable_Ch14[priv->CCK_index][6] + + (CCKSwingTable_Ch14[priv->CCK_index][7]<<8) ; + + rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal); + RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n", + rCCK0_DebugPort, TempVal); + } + } + +void dm_cck_txpower_adjust(struct net_device *dev, bool binch14) +{ + struct r8192_priv *priv = rtllib_priv(dev); + if (priv->IC_Cut >= IC_VersionCut_D) + dm_CCKTxPowerAdjust_TSSI(dev, binch14); + else + dm_CCKTxPowerAdjust_ThermalMeter(dev, binch14); +} + +static void dm_txpower_reset_recovery(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + RT_TRACE(COMP_POWER_TRACKING, "Start Reset Recovery ==>\n"); + rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, + priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbbgain_value); + RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc80 is %08x\n", + priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbbgain_value); + RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in RFA_txPowerTrackingIndex is %x\n", + priv->rfa_txpowertrackingindex); + RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery : RF A I/Q Amplify Gain is %ld\n", + priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbb_iq_amplifygain); + RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: CCK Attenuation is %d dB\n", + priv->CCKPresentAttentuation); + dm_cck_txpower_adjust(dev, priv->bcck_in_ch14); + + rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, + priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbbgain_value); + RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc90 is %08x\n", + priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbbgain_value); + RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in RFC_txPowerTrackingIndex is %x\n", + priv->rfc_txpowertrackingindex); + RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery : RF C I/Q Amplify Gain is %ld\n", + priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbb_iq_amplifygain); + +} + +void dm_restore_dynamic_mechanism_state(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + u32 reg_ratr = priv->rate_adaptive.last_ratr; + u32 ratr_value; + + if (IS_NIC_DOWN(priv)) { + RT_TRACE(COMP_RATE, "<---- dm_restore_dynamic_mechanism_state(): driver is going to unload\n"); + return; + } + + if (priv->rate_adaptive.rate_adaptive_disabled) + return; + if (!(priv->rtllib->mode == WIRELESS_MODE_N_24G || + priv->rtllib->mode == WIRELESS_MODE_N_5G)) + return; + ratr_value = reg_ratr; + if (priv->rf_type == RF_1T2R) + ratr_value &= ~(RATE_ALL_OFDM_2SS); + write_nic_dword(dev, RATR0, ratr_value); + write_nic_byte(dev, UFWP, 1); + if (priv->btxpower_trackingInit && priv->btxpower_tracking) + dm_txpower_reset_recovery(dev); + + dm_bb_initialgain_restore(dev); + +} + +static void dm_bb_initialgain_restore(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + u32 bit_mask = 0x7f; + + if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI) + return; + + rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); + rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, bit_mask, (u32)priv->initgain_backup.xaagccore1); + rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, bit_mask, (u32)priv->initgain_backup.xbagccore1); + rtl8192_setBBreg(dev, rOFDM0_XCAGCCore1, bit_mask, (u32)priv->initgain_backup.xcagccore1); + rtl8192_setBBreg(dev, rOFDM0_XDAGCCore1, bit_mask, (u32)priv->initgain_backup.xdagccore1); + bit_mask = bMaskByte2; + rtl8192_setBBreg(dev, rCCK0_CCA, bit_mask, (u32)priv->initgain_backup.cca); + + RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc50 is %x\n", priv->initgain_backup.xaagccore1); + RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc58 is %x\n", priv->initgain_backup.xbagccore1); + RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc60 is %x\n", priv->initgain_backup.xcagccore1); + RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc68 is %x\n", priv->initgain_backup.xdagccore1); + RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xa0a is %x\n", priv->initgain_backup.cca); + rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1); + +} + + +void dm_backup_dynamic_mechanism_state(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + priv->bswitch_fsync = false; + priv->bfsync_processing = false; + dm_bb_initialgain_backup(dev); + +} + + +static void dm_bb_initialgain_backup(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + u32 bit_mask = bMaskByte0; + + if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI) + return; + + rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); + priv->initgain_backup.xaagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XAAGCCore1, bit_mask); + priv->initgain_backup.xbagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XBAGCCore1, bit_mask); + priv->initgain_backup.xcagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XCAGCCore1, bit_mask); + priv->initgain_backup.xdagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XDAGCCore1, bit_mask); + bit_mask = bMaskByte2; + priv->initgain_backup.cca = (u8)rtl8192_QueryBBReg(dev, rCCK0_CCA, bit_mask); + + RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc50 is %x\n", priv->initgain_backup.xaagccore1); + RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc58 is %x\n", priv->initgain_backup.xbagccore1); + RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc60 is %x\n", priv->initgain_backup.xcagccore1); + RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc68 is %x\n", priv->initgain_backup.xdagccore1); + RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xa0a is %x\n", priv->initgain_backup.cca); + +} + +void dm_change_dynamic_initgain_thresh(struct net_device *dev, + u32 dm_type, u32 dm_value) +{ + if (dm_type == DIG_TYPE_THRESH_HIGH) { + dm_digtable.rssi_high_thresh = dm_value; + } else if (dm_type == DIG_TYPE_THRESH_LOW) { + dm_digtable.rssi_low_thresh = dm_value; + } else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH) { + dm_digtable.rssi_high_power_highthresh = dm_value; + } else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH) { + dm_digtable.rssi_high_power_highthresh = dm_value; + } else if (dm_type == DIG_TYPE_ENABLE) { + dm_digtable.dig_state = DM_STA_DIG_MAX; + dm_digtable.dig_enable_flag = true; + } else if (dm_type == DIG_TYPE_DISABLE) { + dm_digtable.dig_state = DM_STA_DIG_MAX; + dm_digtable.dig_enable_flag = false; + } else if (dm_type == DIG_TYPE_DBG_MODE) { + if (dm_value >= DM_DBG_MAX) + dm_value = DM_DBG_OFF; + dm_digtable.dbg_mode = (u8)dm_value; + } else if (dm_type == DIG_TYPE_RSSI) { + if (dm_value > 100) + dm_value = 30; + dm_digtable.rssi_val = (long)dm_value; + } else if (dm_type == DIG_TYPE_ALGORITHM) { + if (dm_value >= DIG_ALGO_MAX) + dm_value = DIG_ALGO_BY_FALSE_ALARM; + if (dm_digtable.dig_algorithm != (u8)dm_value) + dm_digtable.dig_algorithm_switch = 1; + dm_digtable.dig_algorithm = (u8)dm_value; + } else if (dm_type == DIG_TYPE_BACKOFF) { + if (dm_value > 30) + dm_value = 30; + dm_digtable.backoff_val = (u8)dm_value; + } else if (dm_type == DIG_TYPE_RX_GAIN_MIN) { + if (dm_value == 0) + dm_value = 0x1; + dm_digtable.rx_gain_range_min = (u8)dm_value; + } else if (dm_type == DIG_TYPE_RX_GAIN_MAX) { + if (dm_value > 0x50) + dm_value = 0x50; + dm_digtable.rx_gain_range_max = (u8)dm_value; + } +} + +static void dm_dig_init(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + dm_digtable.dig_enable_flag = true; + dm_digtable.Backoff_Enable_Flag = true; + + dm_digtable.dig_algorithm = DIG_ALGO_BY_RSSI; + + dm_digtable.Dig_TwoPort_Algorithm = DIG_TWO_PORT_ALGO_RSSI; + dm_digtable.Dig_Ext_Port_Stage = DIG_EXT_PORT_STAGE_MAX; + dm_digtable.dbg_mode = DM_DBG_OFF; + dm_digtable.dig_algorithm_switch = 0; + + dm_digtable.dig_state = DM_STA_DIG_MAX; + dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX; + dm_digtable.CurSTAConnectState = dm_digtable.PreSTAConnectState = DIG_STA_DISCONNECT; + dm_digtable.CurAPConnectState = dm_digtable.PreAPConnectState = DIG_AP_DISCONNECT; + dm_digtable.initialgain_lowerbound_state = false; + + dm_digtable.rssi_low_thresh = DM_DIG_THRESH_LOW; + dm_digtable.rssi_high_thresh = DM_DIG_THRESH_HIGH; + + dm_digtable.FALowThresh = DM_FALSEALARM_THRESH_LOW; + dm_digtable.FAHighThresh = DM_FALSEALARM_THRESH_HIGH; + + dm_digtable.rssi_high_power_lowthresh = DM_DIG_HIGH_PWR_THRESH_LOW; + dm_digtable.rssi_high_power_highthresh = DM_DIG_HIGH_PWR_THRESH_HIGH; + + dm_digtable.rssi_val = 50; + dm_digtable.backoff_val = DM_DIG_BACKOFF; + dm_digtable.rx_gain_range_max = DM_DIG_MAX; + if (priv->CustomerID == RT_CID_819x_Netcore) + dm_digtable.rx_gain_range_min = DM_DIG_MIN_Netcore; + else + dm_digtable.rx_gain_range_min = DM_DIG_MIN; + + dm_digtable.BackoffVal_range_max = DM_DIG_BACKOFF_MAX; + dm_digtable.BackoffVal_range_min = DM_DIG_BACKOFF_MIN; +} + +static void dm_ctrl_initgain_byrssi(struct net_device *dev) +{ + + if (dm_digtable.dig_enable_flag == false) + return; + + if (dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM) + dm_ctrl_initgain_byrssi_by_fwfalse_alarm(dev); + else if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI) + dm_ctrl_initgain_byrssi_by_driverrssi(dev); + else + return; +} + +/*----------------------------------------------------------------------------- + * Function: dm_CtrlInitGainBeforeConnectByRssiAndFalseAlarm() + * + * Overview: Driver monitor RSSI and False Alarm to change initial gain. + Only change initial gain during link in progress. + * + * Input: IN PADAPTER pAdapter + * + * Output: NONE + * + * Return: NONE + * + * Revised History: + * When Who Remark + * 03/04/2009 hpfan Create Version 0. + * + *---------------------------------------------------------------------------*/ + +static void dm_ctrl_initgain_byrssi_by_driverrssi( + struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + u8 i; + static u8 fw_dig; + + if (dm_digtable.dig_enable_flag == false) + return; + + if (dm_digtable.dig_algorithm_switch) + fw_dig = 0; + if (fw_dig <= 3) { + for (i = 0; i < 3; i++) + rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); + fw_dig++; + dm_digtable.dig_state = DM_STA_DIG_OFF; + } + + if (priv->rtllib->state == RTLLIB_LINKED) + dm_digtable.CurSTAConnectState = DIG_STA_CONNECT; + else + dm_digtable.CurSTAConnectState = DIG_STA_DISCONNECT; + + + if (dm_digtable.dbg_mode == DM_DBG_OFF) + dm_digtable.rssi_val = priv->undecorated_smoothed_pwdb; + dm_initial_gain(dev); + dm_pd_th(dev); + dm_cs_ratio(dev); + if (dm_digtable.dig_algorithm_switch) + dm_digtable.dig_algorithm_switch = 0; + dm_digtable.PreSTAConnectState = dm_digtable.CurSTAConnectState; + +} + +static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm( + struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + static u32 reset_cnt; + u8 i; + + if (dm_digtable.dig_enable_flag == false) + return; + + if (dm_digtable.dig_algorithm_switch) { + dm_digtable.dig_state = DM_STA_DIG_MAX; + for (i = 0; i < 3; i++) + rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1); + dm_digtable.dig_algorithm_switch = 0; + } + + if (priv->rtllib->state != RTLLIB_LINKED) + return; + + if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_low_thresh) && + (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_thresh)) + return; + if ((priv->undecorated_smoothed_pwdb <= dm_digtable.rssi_low_thresh)) { + if (dm_digtable.dig_state == DM_STA_DIG_OFF && + (priv->reset_count == reset_cnt)) + return; + else + reset_cnt = priv->reset_count; + + dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX; + dm_digtable.dig_state = DM_STA_DIG_OFF; + + rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8); + + write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x17); + write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x17); + write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x17); + write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x17); + + if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) + write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00); + else + write_nic_byte(dev, rOFDM0_RxDetector1, 0x42); + + write_nic_byte(dev, 0xa0a, 0x08); + + return; + } + + if ((priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh)) { + u8 reset_flag = 0; + + if (dm_digtable.dig_state == DM_STA_DIG_ON && + (priv->reset_count == reset_cnt)) { + dm_ctrl_initgain_byrssi_highpwr(dev); + return; + } else { + if (priv->reset_count != reset_cnt) + reset_flag = 1; + + reset_cnt = priv->reset_count; + } + + dm_digtable.dig_state = DM_STA_DIG_ON; + + if (reset_flag == 1) { + write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x2c); + write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x2c); + write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x2c); + write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x2c); + } else { + write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x20); + write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x20); + write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x20); + write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x20); + } + + if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) + write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20); + else + write_nic_byte(dev, rOFDM0_RxDetector1, 0x44); + + write_nic_byte(dev, 0xa0a, 0xcd); + + rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1); + } + dm_ctrl_initgain_byrssi_highpwr(dev); +} + + +static void dm_ctrl_initgain_byrssi_highpwr(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + static u32 reset_cnt_highpwr; + + if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_high_power_lowthresh) && + (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_highthresh)) + return; + + if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_power_highthresh) { + if (dm_digtable.dig_highpwr_state == DM_STA_DIG_ON && + (priv->reset_count == reset_cnt_highpwr)) + return; + else + dm_digtable.dig_highpwr_state = DM_STA_DIG_ON; + + if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) + write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10); + else + write_nic_byte(dev, rOFDM0_RxDetector1, 0x43); + } else { + if (dm_digtable.dig_highpwr_state == DM_STA_DIG_OFF && + (priv->reset_count == reset_cnt_highpwr)) + return; + else + dm_digtable.dig_highpwr_state = DM_STA_DIG_OFF; + + if (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_lowthresh && + priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) { + if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) + write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20); + else + write_nic_byte(dev, rOFDM0_RxDetector1, 0x44); + } + } + reset_cnt_highpwr = priv->reset_count; +} + +static void dm_initial_gain(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + u8 initial_gain = 0; + static u8 initialized, force_write; + static u32 reset_cnt; + + if (dm_digtable.dig_algorithm_switch) { + initialized = 0; + reset_cnt = 0; + } + + if (rtllib_act_scanning(priv->rtllib, true) == true) { + force_write = 1; + return; + } + + if (dm_digtable.PreSTAConnectState == dm_digtable.CurSTAConnectState) { + if (dm_digtable.CurSTAConnectState == DIG_STA_CONNECT) { + if ((dm_digtable.rssi_val+10-dm_digtable.backoff_val) > dm_digtable.rx_gain_range_max) + dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_max; + else if ((dm_digtable.rssi_val+10-dm_digtable.backoff_val) < dm_digtable.rx_gain_range_min) + dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_min; + else + dm_digtable.cur_ig_value = dm_digtable.rssi_val+10-dm_digtable.backoff_val; + } else { + if (dm_digtable.cur_ig_value == 0) + dm_digtable.cur_ig_value = priv->DefaultInitialGain[0]; + else + dm_digtable.cur_ig_value = dm_digtable.pre_ig_value; + } + } else { + dm_digtable.cur_ig_value = priv->DefaultInitialGain[0]; + dm_digtable.pre_ig_value = 0; + } + + if (priv->reset_count != reset_cnt) { + force_write = 1; + reset_cnt = priv->reset_count; + } + + if (dm_digtable.pre_ig_value != read_nic_byte(dev, rOFDM0_XAAGCCore1)) + force_write = 1; + + if ((dm_digtable.pre_ig_value != dm_digtable.cur_ig_value) + || !initialized || force_write) { + initial_gain = (u8)dm_digtable.cur_ig_value; + write_nic_byte(dev, rOFDM0_XAAGCCore1, initial_gain); + write_nic_byte(dev, rOFDM0_XBAGCCore1, initial_gain); + write_nic_byte(dev, rOFDM0_XCAGCCore1, initial_gain); + write_nic_byte(dev, rOFDM0_XDAGCCore1, initial_gain); + dm_digtable.pre_ig_value = dm_digtable.cur_ig_value; + initialized = 1; + force_write = 0; + } +} + +static void dm_pd_th(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + static u8 initialized, force_write; + static u32 reset_cnt; + + if (dm_digtable.dig_algorithm_switch) { + initialized = 0; + reset_cnt = 0; + } + + if (dm_digtable.PreSTAConnectState == dm_digtable.CurSTAConnectState) { + if (dm_digtable.CurSTAConnectState == DIG_STA_CONNECT) { + if (dm_digtable.rssi_val >= dm_digtable.rssi_high_power_highthresh) + dm_digtable.curpd_thstate = DIG_PD_AT_HIGH_POWER; + else if ((dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh)) + dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER; + else if ((dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh) && + (dm_digtable.rssi_val < dm_digtable.rssi_high_power_lowthresh)) + dm_digtable.curpd_thstate = DIG_PD_AT_NORMAL_POWER; + else + dm_digtable.curpd_thstate = dm_digtable.prepd_thstate; + } else { + dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER; + } + } else { + dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER; + } + + if (priv->reset_count != reset_cnt) { + force_write = 1; + reset_cnt = priv->reset_count; + } + + if ((dm_digtable.prepd_thstate != dm_digtable.curpd_thstate) || + (initialized <= 3) || force_write) { + if (dm_digtable.curpd_thstate == DIG_PD_AT_LOW_POWER) { + if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) + write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00); + else + write_nic_byte(dev, rOFDM0_RxDetector1, 0x42); + } else if (dm_digtable.curpd_thstate == DIG_PD_AT_NORMAL_POWER) { + if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) + write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20); + else + write_nic_byte(dev, rOFDM0_RxDetector1, 0x44); + } else if (dm_digtable.curpd_thstate == DIG_PD_AT_HIGH_POWER) { + if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) + write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10); + else + write_nic_byte(dev, rOFDM0_RxDetector1, 0x43); + } + dm_digtable.prepd_thstate = dm_digtable.curpd_thstate; + if (initialized <= 3) + initialized++; + force_write = 0; + } +} + +static void dm_cs_ratio(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + static u8 initialized, force_write; + static u32 reset_cnt; + + if (dm_digtable.dig_algorithm_switch) { + initialized = 0; + reset_cnt = 0; + } + + if (dm_digtable.PreSTAConnectState == dm_digtable.CurSTAConnectState) { + if (dm_digtable.CurSTAConnectState == DIG_STA_CONNECT) { + if ((dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh)) + dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER; + else if ((dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh)) + dm_digtable.curcs_ratio_state = DIG_CS_RATIO_HIGHER; + else + dm_digtable.curcs_ratio_state = dm_digtable.precs_ratio_state; + } else { + dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER; + } + } else { + dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER; + } + + if (priv->reset_count != reset_cnt) { + force_write = 1; + reset_cnt = priv->reset_count; + } + + + if ((dm_digtable.precs_ratio_state != dm_digtable.curcs_ratio_state) || + !initialized || force_write) { + if (dm_digtable.curcs_ratio_state == DIG_CS_RATIO_LOWER) + write_nic_byte(dev, 0xa0a, 0x08); + else if (dm_digtable.curcs_ratio_state == DIG_CS_RATIO_HIGHER) + write_nic_byte(dev, 0xa0a, 0xcd); + dm_digtable.precs_ratio_state = dm_digtable.curcs_ratio_state; + initialized = 1; + force_write = 0; + } +} + +void dm_init_edca_turbo(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + priv->bcurrent_turbo_EDCA = false; + priv->rtllib->bis_any_nonbepkts = false; + priv->bis_cur_rdlstate = false; +} + +static void dm_check_edca_turbo(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + struct rt_hi_throughput *pHTInfo = priv->rtllib->pHTInfo; + + static unsigned long lastTxOkCnt; + static unsigned long lastRxOkCnt; + unsigned long curTxOkCnt = 0; + unsigned long curRxOkCnt = 0; + + if (priv->rtllib->iw_mode == IW_MODE_ADHOC) + goto dm_CheckEdcaTurbo_EXIT; + if (priv->rtllib->state != RTLLIB_LINKED) + goto dm_CheckEdcaTurbo_EXIT; + if (priv->rtllib->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_EDCA_TURBO) + goto dm_CheckEdcaTurbo_EXIT; + + { + u8 *peername[11] = { + "unknown", "realtek_90", "realtek_92se", "broadcom", + "ralink", "atheros", "cisco", "marvell", "92u_softap", + "self_softap" + }; + static int wb_tmp; + if (wb_tmp == 0) { + printk(KERN_INFO "%s():iot peer is %s, bssid:" + " %pM\n", __func__, + peername[pHTInfo->IOTPeer], + priv->rtllib->current_network.bssid); + wb_tmp = 1; + } + } + if (!priv->rtllib->bis_any_nonbepkts) { + curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt; + curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt; + if (pHTInfo->IOTAction & HT_IOT_ACT_EDCA_BIAS_ON_RX) { + if (curTxOkCnt > 4*curRxOkCnt) { + if (priv->bis_cur_rdlstate || + !priv->bcurrent_turbo_EDCA) { + write_nic_dword(dev, EDCAPARA_BE, + edca_setting_UL[pHTInfo->IOTPeer]); + priv->bis_cur_rdlstate = false; + } + } else { + if (!priv->bis_cur_rdlstate || + !priv->bcurrent_turbo_EDCA) { + if (priv->rtllib->mode == WIRELESS_MODE_G) + write_nic_dword(dev, EDCAPARA_BE, + edca_setting_DL_GMode[pHTInfo->IOTPeer]); + else + write_nic_dword(dev, EDCAPARA_BE, + edca_setting_DL[pHTInfo->IOTPeer]); + priv->bis_cur_rdlstate = true; + } + } + priv->bcurrent_turbo_EDCA = true; + } else { + if (curRxOkCnt > 4*curTxOkCnt) { + if (!priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA) { + if (priv->rtllib->mode == WIRELESS_MODE_G) + write_nic_dword(dev, EDCAPARA_BE, + edca_setting_DL_GMode[pHTInfo->IOTPeer]); + else + write_nic_dword(dev, EDCAPARA_BE, + edca_setting_DL[pHTInfo->IOTPeer]); + priv->bis_cur_rdlstate = true; + } + } else { + if (priv->bis_cur_rdlstate || + !priv->bcurrent_turbo_EDCA) { + write_nic_dword(dev, EDCAPARA_BE, + edca_setting_UL[pHTInfo->IOTPeer]); + priv->bis_cur_rdlstate = false; + } + + } + + priv->bcurrent_turbo_EDCA = true; + } + } else { + if (priv->bcurrent_turbo_EDCA) { + u8 tmp = AC0_BE; + priv->rtllib->SetHwRegHandler(dev, HW_VAR_AC_PARAM, (u8 *)(&tmp)); + priv->bcurrent_turbo_EDCA = false; + } + } + + +dm_CheckEdcaTurbo_EXIT: + priv->rtllib->bis_any_nonbepkts = false; + lastTxOkCnt = priv->stats.txbytesunicast; + lastRxOkCnt = priv->stats.rxbytesunicast; +} + +static void dm_init_ctstoself(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv((struct net_device *)dev); + + priv->rtllib->bCTSToSelfEnable = true; + priv->rtllib->CTSToSelfTH = CTSToSelfTHVal; +} + +static void dm_ctstoself(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv((struct net_device *)dev); + struct rt_hi_throughput *pHTInfo = priv->rtllib->pHTInfo; + static unsigned long lastTxOkCnt; + static unsigned long lastRxOkCnt; + unsigned long curTxOkCnt = 0; + unsigned long curRxOkCnt = 0; + + if (priv->rtllib->bCTSToSelfEnable != true) { + pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF; + return; + } + if (pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) { + curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt; + curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt; + if (curRxOkCnt > 4*curTxOkCnt) + pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF; + else + pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF; + + lastTxOkCnt = priv->stats.txbytesunicast; + lastRxOkCnt = priv->stats.rxbytesunicast; + } +} + + +static void dm_Init_WA_Broadcom_IOT(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv((struct net_device *)dev); + struct rt_hi_throughput *pHTInfo = priv->rtllib->pHTInfo; + + pHTInfo->bWAIotBroadcom = false; + pHTInfo->WAIotTH = WAIotTHVal; +} + +static void dm_check_pbc_gpio(struct net_device *dev) +{ +} + +void dm_CheckRfCtrlGPIO(void *data) +{ + struct r8192_priv *priv = container_of_dwork_rsl(data, + struct r8192_priv, gpio_change_rf_wq); + struct net_device *dev = priv->rtllib->dev; + u8 tmp1byte; + enum rt_rf_power_state eRfPowerStateToSet; + bool bActuallySet = false; + char *argv[3]; + static char *RadioPowerPath = "/etc/acpi/events/RadioPower.sh"; + static char *envp[] = {"HOME=/", "TERM=linux", "PATH=/usr/bin:/bin", NULL}; + + bActuallySet = false; + + if ((priv->up_first_time == 1) || (priv->being_init_adapter)) + return; + + if (priv->bfirst_after_down) { + priv->bfirst_after_down = 1; + return; + } + + tmp1byte = read_nic_byte(dev, GPI); + + eRfPowerStateToSet = (tmp1byte&BIT1) ? eRfOn : eRfOff; + + if ((priv->bHwRadioOff == true) && (eRfPowerStateToSet == eRfOn)) { + RT_TRACE(COMP_RF, "gpiochangeRF - HW Radio ON\n"); + printk(KERN_INFO "gpiochangeRF - HW Radio ON\n"); + priv->bHwRadioOff = false; + bActuallySet = true; + } else if ((priv->bHwRadioOff == false) && (eRfPowerStateToSet == eRfOff)) { + RT_TRACE(COMP_RF, "gpiochangeRF - HW Radio OFF\n"); + printk(KERN_INFO "gpiochangeRF - HW Radio OFF\n"); + priv->bHwRadioOff = true; + bActuallySet = true; + } + + if (bActuallySet) { + mdelay(1000); + priv->bHwRfOffAction = 1; + MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW, true); + if (priv->bHwRadioOff == true) + argv[1] = "RFOFF"; + else + argv[1] = "RFON"; + + argv[0] = RadioPowerPath; + argv[2] = NULL; + call_usermodehelper(RadioPowerPath, argv, envp, 1); + } +} + +void dm_rf_pathcheck_workitemcallback(void *data) +{ + struct r8192_priv *priv = container_of_dwork_rsl(data, + struct r8192_priv, + rfpath_check_wq); + struct net_device *dev = priv->rtllib->dev; + u8 rfpath = 0, i; + + rfpath = read_nic_byte(dev, 0xc04); + + for (i = 0; i < RF90_PATH_MAX; i++) { + if (rfpath & (0x01<<i)) + priv->brfpath_rxenable[i] = 1; + else + priv->brfpath_rxenable[i] = 0; + } + if (!DM_RxPathSelTable.Enable) + return; + + dm_rxpath_sel_byrssi(dev); +} + +static void dm_init_rxpath_selection(struct net_device *dev) +{ + u8 i; + struct r8192_priv *priv = rtllib_priv(dev); + + DM_RxPathSelTable.Enable = 1; + DM_RxPathSelTable.SS_TH_low = RxPathSelection_SS_TH_low; + DM_RxPathSelTable.diff_TH = RxPathSelection_diff_TH; + if (priv->CustomerID == RT_CID_819x_Netcore) + DM_RxPathSelTable.cck_method = CCK_Rx_Version_2; + else + DM_RxPathSelTable.cck_method = CCK_Rx_Version_1; + DM_RxPathSelTable.DbgMode = DM_DBG_OFF; + DM_RxPathSelTable.disabledRF = 0; + for (i = 0; i < 4; i++) { + DM_RxPathSelTable.rf_rssi[i] = 50; + DM_RxPathSelTable.cck_pwdb_sta[i] = -64; + DM_RxPathSelTable.rf_enable_rssi_th[i] = 100; + } +} + +#define PWDB_IN_RANGE ((cur_cck_pwdb < tmp_cck_max_pwdb) && \ + (cur_cck_pwdb > tmp_cck_sec_pwdb)) + +static void dm_rxpath_sel_byrssi(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + u8 i, max_rssi_index = 0, min_rssi_index = 0; + u8 sec_rssi_index = 0, rf_num = 0; + u8 tmp_max_rssi = 0, tmp_min_rssi = 0, tmp_sec_rssi = 0; + u8 cck_default_Rx = 0x2; + u8 cck_optional_Rx = 0x3; + long tmp_cck_max_pwdb = 0, tmp_cck_min_pwdb = 0, tmp_cck_sec_pwdb = 0; + u8 cck_rx_ver2_max_index = 0, cck_rx_ver2_min_index = 0; + u8 cck_rx_ver2_sec_index = 0; + u8 cur_rf_rssi; + long cur_cck_pwdb; + static u8 disabled_rf_cnt, cck_Rx_Path_initialized; + u8 update_cck_rx_path; + + if (priv->rf_type != RF_2T4R) + return; + + if (!cck_Rx_Path_initialized) { + DM_RxPathSelTable.cck_Rx_path = (read_nic_byte(dev, 0xa07)&0xf); + cck_Rx_Path_initialized = 1; + } + + DM_RxPathSelTable.disabledRF = 0xf; + DM_RxPathSelTable.disabledRF &= ~(read_nic_byte(dev, 0xc04)); + + if (priv->rtllib->mode == WIRELESS_MODE_B) + DM_RxPathSelTable.cck_method = CCK_Rx_Version_2; + + for (i = 0; i < RF90_PATH_MAX; i++) { + if (!DM_RxPathSelTable.DbgMode) + DM_RxPathSelTable.rf_rssi[i] = priv->stats.rx_rssi_percentage[i]; + + if (priv->brfpath_rxenable[i]) { + rf_num++; + cur_rf_rssi = DM_RxPathSelTable.rf_rssi[i]; + + if (rf_num == 1) { + max_rssi_index = min_rssi_index = sec_rssi_index = i; + tmp_max_rssi = tmp_min_rssi = tmp_sec_rssi = cur_rf_rssi; + } else if (rf_num == 2) { + if (cur_rf_rssi >= tmp_max_rssi) { + tmp_max_rssi = cur_rf_rssi; + max_rssi_index = i; + } else { + tmp_sec_rssi = tmp_min_rssi = cur_rf_rssi; + sec_rssi_index = min_rssi_index = i; + } + } else { + if (cur_rf_rssi > tmp_max_rssi) { + tmp_sec_rssi = tmp_max_rssi; + sec_rssi_index = max_rssi_index; + tmp_max_rssi = cur_rf_rssi; + max_rssi_index = i; + } else if (cur_rf_rssi == tmp_max_rssi) { + tmp_sec_rssi = cur_rf_rssi; + sec_rssi_index = i; + } else if ((cur_rf_rssi < tmp_max_rssi) && + (cur_rf_rssi > tmp_sec_rssi)) { + tmp_sec_rssi = cur_rf_rssi; + sec_rssi_index = i; + } else if (cur_rf_rssi == tmp_sec_rssi) { + if (tmp_sec_rssi == tmp_min_rssi) { + tmp_sec_rssi = cur_rf_rssi; + sec_rssi_index = i; + } + } else if ((cur_rf_rssi < tmp_sec_rssi) && + (cur_rf_rssi > tmp_min_rssi)) { + ; + } else if (cur_rf_rssi == tmp_min_rssi) { + if (tmp_sec_rssi == tmp_min_rssi) { + tmp_min_rssi = cur_rf_rssi; + min_rssi_index = i; + } + } else if (cur_rf_rssi < tmp_min_rssi) { + tmp_min_rssi = cur_rf_rssi; + min_rssi_index = i; + } + } + } + } + + rf_num = 0; + if (DM_RxPathSelTable.cck_method == CCK_Rx_Version_2) { + for (i = 0; i < RF90_PATH_MAX; i++) { + if (priv->brfpath_rxenable[i]) { + rf_num++; + cur_cck_pwdb = + DM_RxPathSelTable.cck_pwdb_sta[i]; + + if (rf_num == 1) { + cck_rx_ver2_max_index = i; + cck_rx_ver2_min_index = i; + cck_rx_ver2_sec_index = i; + tmp_cck_max_pwdb = cur_cck_pwdb; + tmp_cck_min_pwdb = cur_cck_pwdb; + tmp_cck_sec_pwdb = cur_cck_pwdb; + } else if (rf_num == 2) { + if (cur_cck_pwdb >= tmp_cck_max_pwdb) { + tmp_cck_max_pwdb = cur_cck_pwdb; + cck_rx_ver2_max_index = i; + } else { + tmp_cck_sec_pwdb = cur_cck_pwdb; + tmp_cck_min_pwdb = cur_cck_pwdb; + cck_rx_ver2_sec_index = i; + cck_rx_ver2_min_index = i; + } + } else { + if (cur_cck_pwdb > tmp_cck_max_pwdb) { + tmp_cck_sec_pwdb = + tmp_cck_max_pwdb; + cck_rx_ver2_sec_index = + cck_rx_ver2_max_index; + tmp_cck_max_pwdb = cur_cck_pwdb; + cck_rx_ver2_max_index = i; + } else if (cur_cck_pwdb == + tmp_cck_max_pwdb) { + tmp_cck_sec_pwdb = cur_cck_pwdb; + cck_rx_ver2_sec_index = i; + } else if (PWDB_IN_RANGE) { + tmp_cck_sec_pwdb = cur_cck_pwdb; + cck_rx_ver2_sec_index = i; + } else if (cur_cck_pwdb == + tmp_cck_sec_pwdb) { + if (tmp_cck_sec_pwdb == + tmp_cck_min_pwdb) { + tmp_cck_sec_pwdb = + cur_cck_pwdb; + cck_rx_ver2_sec_index = + i; + } + } else if ((cur_cck_pwdb < tmp_cck_sec_pwdb) && + (cur_cck_pwdb > tmp_cck_min_pwdb)) { + ; + } else if (cur_cck_pwdb == tmp_cck_min_pwdb) { + if (tmp_cck_sec_pwdb == tmp_cck_min_pwdb) { + tmp_cck_min_pwdb = cur_cck_pwdb; + cck_rx_ver2_min_index = i; + } + } else if (cur_cck_pwdb < tmp_cck_min_pwdb) { + tmp_cck_min_pwdb = cur_cck_pwdb; + cck_rx_ver2_min_index = i; + } + } + + } + } + } + + update_cck_rx_path = 0; + if (DM_RxPathSelTable.cck_method == CCK_Rx_Version_2) { + cck_default_Rx = cck_rx_ver2_max_index; + cck_optional_Rx = cck_rx_ver2_sec_index; + if (tmp_cck_max_pwdb != -64) + update_cck_rx_path = 1; + } + + if (tmp_min_rssi < DM_RxPathSelTable.SS_TH_low && disabled_rf_cnt < 2) { + if ((tmp_max_rssi - tmp_min_rssi) >= + DM_RxPathSelTable.diff_TH) { + DM_RxPathSelTable.rf_enable_rssi_th[min_rssi_index] = + tmp_max_rssi+5; + rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, + 0x1<<min_rssi_index, 0x0); + rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, + 0x1<<min_rssi_index, 0x0); + disabled_rf_cnt++; + } + if (DM_RxPathSelTable.cck_method == CCK_Rx_Version_1) { + cck_default_Rx = max_rssi_index; + cck_optional_Rx = sec_rssi_index; + if (tmp_max_rssi) + update_cck_rx_path = 1; + } + } + + if (update_cck_rx_path) { + DM_RxPathSelTable.cck_Rx_path = (cck_default_Rx<<2) | + (cck_optional_Rx); + rtl8192_setBBreg(dev, rCCK0_AFESetting, 0x0f000000, + DM_RxPathSelTable.cck_Rx_path); + } + + if (DM_RxPathSelTable.disabledRF) { + for (i = 0; i < 4; i++) { + if ((DM_RxPathSelTable.disabledRF>>i) & 0x1) { + if (tmp_max_rssi >= + DM_RxPathSelTable.rf_enable_rssi_th[i]) { + rtl8192_setBBreg(dev, + rOFDM0_TRxPathEnable, 0x1 << i, + 0x1); + rtl8192_setBBreg(dev, + rOFDM1_TRxPathEnable, + 0x1 << i, 0x1); + DM_RxPathSelTable.rf_enable_rssi_th[i] + = 100; + disabled_rf_cnt--; + } + } + } + } +} + +static void dm_check_rx_path_selection(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + queue_delayed_work_rsl(priv->priv_wq, &priv->rfpath_check_wq, 0); +} + + +static void dm_init_fsync(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + priv->rtllib->fsync_time_interval = 500; + priv->rtllib->fsync_rate_bitmap = 0x0f000800; + priv->rtllib->fsync_rssi_threshold = 30; + priv->rtllib->bfsync_enable = false; + priv->rtllib->fsync_multiple_timeinterval = 3; + priv->rtllib->fsync_firstdiff_ratethreshold = 100; + priv->rtllib->fsync_seconddiff_ratethreshold = 200; + priv->rtllib->fsync_state = Default_Fsync; + priv->framesyncMonitor = 1; + + init_timer(&priv->fsync_timer); + setup_timer(&priv->fsync_timer, dm_fsync_timer_callback, + (unsigned long) dev); +} + + +static void dm_deInit_fsync(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + del_timer_sync(&priv->fsync_timer); +} + +void dm_fsync_timer_callback(unsigned long data) +{ + struct net_device *dev = (struct net_device *)data; + struct r8192_priv *priv = rtllib_priv((struct net_device *)data); + u32 rate_index, rate_count = 0, rate_count_diff = 0; + bool bSwitchFromCountDiff = false; + bool bDoubleTimeInterval = false; + + if (priv->rtllib->state == RTLLIB_LINKED && + priv->rtllib->bfsync_enable && + (priv->rtllib->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC)) { + u32 rate_bitmap; + for (rate_index = 0; rate_index <= 27; rate_index++) { + rate_bitmap = 1 << rate_index; + if (priv->rtllib->fsync_rate_bitmap & rate_bitmap) + rate_count += + priv->stats.received_rate_histogram[1] + [rate_index]; + } + + if (rate_count < priv->rate_record) + rate_count_diff = 0xffffffff - rate_count + + priv->rate_record; + else + rate_count_diff = rate_count - priv->rate_record; + if (rate_count_diff < priv->rateCountDiffRecord) { + + u32 DiffNum = priv->rateCountDiffRecord - + rate_count_diff; + if (DiffNum >= + priv->rtllib->fsync_seconddiff_ratethreshold) + priv->ContiuneDiffCount++; + else + priv->ContiuneDiffCount = 0; + + if (priv->ContiuneDiffCount >= 2) { + bSwitchFromCountDiff = true; + priv->ContiuneDiffCount = 0; + } + } else { + priv->ContiuneDiffCount = 0; + } + + if (rate_count_diff <= + priv->rtllib->fsync_firstdiff_ratethreshold) { + bSwitchFromCountDiff = true; + priv->ContiuneDiffCount = 0; + } + priv->rate_record = rate_count; + priv->rateCountDiffRecord = rate_count_diff; + RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rate" + "Countdiff %d bSwitchFsync %d\n", priv->rate_record, + rate_count, rate_count_diff, priv->bswitch_fsync); + if (priv->undecorated_smoothed_pwdb > + priv->rtllib->fsync_rssi_threshold && + bSwitchFromCountDiff) { + bDoubleTimeInterval = true; + priv->bswitch_fsync = !priv->bswitch_fsync; + if (priv->bswitch_fsync) { + write_nic_byte(dev, 0xC36, 0x1c); + write_nic_byte(dev, 0xC3e, 0x90); + } else { + write_nic_byte(dev, 0xC36, 0x5c); + write_nic_byte(dev, 0xC3e, 0x96); + } + } else if (priv->undecorated_smoothed_pwdb <= + priv->rtllib->fsync_rssi_threshold) { + if (priv->bswitch_fsync) { + priv->bswitch_fsync = false; + write_nic_byte(dev, 0xC36, 0x5c); + write_nic_byte(dev, 0xC3e, 0x96); + } + } + if (bDoubleTimeInterval) { + if (timer_pending(&priv->fsync_timer)) + del_timer_sync(&priv->fsync_timer); + priv->fsync_timer.expires = jiffies + + MSECS(priv->rtllib->fsync_time_interval * + priv->rtllib->fsync_multiple_timeinterval); + add_timer(&priv->fsync_timer); + } else { + if (timer_pending(&priv->fsync_timer)) + del_timer_sync(&priv->fsync_timer); + priv->fsync_timer.expires = jiffies + + MSECS(priv->rtllib->fsync_time_interval); + add_timer(&priv->fsync_timer); + } + } else { + if (priv->bswitch_fsync) { + priv->bswitch_fsync = false; + write_nic_byte(dev, 0xC36, 0x5c); + write_nic_byte(dev, 0xC3e, 0x96); + } + priv->ContiuneDiffCount = 0; + write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd); + } + RT_TRACE(COMP_HALDM, "ContiuneDiffCount %d\n", priv->ContiuneDiffCount); + RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d " + "bSwitchFsync %d\n", priv->rate_record, rate_count, + rate_count_diff, priv->bswitch_fsync); +} + +static void dm_StartHWFsync(struct net_device *dev) +{ + u8 rf_timing = 0x77; + struct r8192_priv *priv = rtllib_priv(dev); + RT_TRACE(COMP_HALDM, "%s\n", __func__); + write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c12cf); + priv->rtllib->SetHwRegHandler(dev, HW_VAR_RF_TIMING, + (u8 *)(&rf_timing)); + write_nic_byte(dev, 0xc3b, 0x41); +} + +static void dm_EndHWFsync(struct net_device *dev) +{ + u8 rf_timing = 0xaa; + struct r8192_priv *priv = rtllib_priv(dev); + RT_TRACE(COMP_HALDM, "%s\n", __func__); + write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd); + priv->rtllib->SetHwRegHandler(dev, HW_VAR_RF_TIMING, (u8 *) + (&rf_timing)); + write_nic_byte(dev, 0xc3b, 0x49); +} + +static void dm_EndSWFsync(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + RT_TRACE(COMP_HALDM, "%s\n", __func__); + del_timer_sync(&(priv->fsync_timer)); + + if (priv->bswitch_fsync) { + priv->bswitch_fsync = false; + + write_nic_byte(dev, 0xC36, 0x5c); + + write_nic_byte(dev, 0xC3e, 0x96); + } + + priv->ContiuneDiffCount = 0; + write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd); +} + +static void dm_StartSWFsync(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + u32 rateIndex; + u32 rateBitmap; + + RT_TRACE(COMP_HALDM, "%s\n", __func__); + priv->rate_record = 0; + priv->ContiuneDiffCount = 0; + priv->rateCountDiffRecord = 0; + priv->bswitch_fsync = false; + + if (priv->rtllib->mode == WIRELESS_MODE_N_24G) { + priv->rtllib->fsync_firstdiff_ratethreshold = 600; + priv->rtllib->fsync_seconddiff_ratethreshold = 0xffff; + } else { + priv->rtllib->fsync_firstdiff_ratethreshold = 200; + priv->rtllib->fsync_seconddiff_ratethreshold = 200; + } + for (rateIndex = 0; rateIndex <= 27; rateIndex++) { + rateBitmap = 1 << rateIndex; + if (priv->rtllib->fsync_rate_bitmap & rateBitmap) + priv->rate_record += + priv->stats.received_rate_histogram[1] + [rateIndex]; + } + if (timer_pending(&priv->fsync_timer)) + del_timer_sync(&priv->fsync_timer); + priv->fsync_timer.expires = jiffies + + MSECS(priv->rtllib->fsync_time_interval); + add_timer(&priv->fsync_timer); + + write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c12cd); + +} + +void dm_check_fsync(struct net_device *dev) +{ +#define RegC38_Default 0 +#define RegC38_NonFsync_Other_AP 1 +#define RegC38_Fsync_AP_BCM 2 + struct r8192_priv *priv = rtllib_priv(dev); + static u8 reg_c38_State = RegC38_Default; + static u32 reset_cnt; + + RT_TRACE(COMP_HALDM, "RSSI %d TimeInterval %d MultipleTimeInterval " + "%d\n", priv->rtllib->fsync_rssi_threshold, + priv->rtllib->fsync_time_interval, + priv->rtllib->fsync_multiple_timeinterval); + RT_TRACE(COMP_HALDM, "RateBitmap 0x%x FirstDiffRateThreshold %d Second" + "DiffRateThreshold %d\n", priv->rtllib->fsync_rate_bitmap, + priv->rtllib->fsync_firstdiff_ratethreshold, + priv->rtllib->fsync_seconddiff_ratethreshold); + + if (priv->rtllib->state == RTLLIB_LINKED && + priv->rtllib->pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) { + if (priv->rtllib->bfsync_enable == 0) { + switch (priv->rtllib->fsync_state) { + case Default_Fsync: + dm_StartHWFsync(dev); + priv->rtllib->fsync_state = HW_Fsync; + break; + case SW_Fsync: + dm_EndSWFsync(dev); + dm_StartHWFsync(dev); + priv->rtllib->fsync_state = HW_Fsync; + break; + case HW_Fsync: + default: + break; + } + } else { + switch (priv->rtllib->fsync_state) { + case Default_Fsync: + dm_StartSWFsync(dev); + priv->rtllib->fsync_state = SW_Fsync; + break; + case HW_Fsync: + dm_EndHWFsync(dev); + dm_StartSWFsync(dev); + priv->rtllib->fsync_state = SW_Fsync; + break; + case SW_Fsync: + default: + break; + + } + } + if (priv->framesyncMonitor) { + if (reg_c38_State != RegC38_Fsync_AP_BCM) { + write_nic_byte(dev, rOFDM0_RxDetector3, 0x95); + + reg_c38_State = RegC38_Fsync_AP_BCM; + } + } + } else { + switch (priv->rtllib->fsync_state) { + case HW_Fsync: + dm_EndHWFsync(dev); + priv->rtllib->fsync_state = Default_Fsync; + break; + case SW_Fsync: + dm_EndSWFsync(dev); + priv->rtllib->fsync_state = Default_Fsync; + break; + case Default_Fsync: + default: + break; + } + + if (priv->framesyncMonitor) { + if (priv->rtllib->state == RTLLIB_LINKED) { + if (priv->undecorated_smoothed_pwdb <= + RegC38_TH) { + if (reg_c38_State != + RegC38_NonFsync_Other_AP) { + write_nic_byte(dev, + rOFDM0_RxDetector3, + 0x90); + + reg_c38_State = + RegC38_NonFsync_Other_AP; + } + } else if (priv->undecorated_smoothed_pwdb >= + (RegC38_TH+5)) { + if (reg_c38_State) { + write_nic_byte(dev, + rOFDM0_RxDetector3, + priv->framesync); + reg_c38_State = RegC38_Default; + } + } + } else { + if (reg_c38_State) { + write_nic_byte(dev, rOFDM0_RxDetector3, + priv->framesync); + reg_c38_State = RegC38_Default; + } + } + } + } + if (priv->framesyncMonitor) { + if (priv->reset_count != reset_cnt) { + write_nic_byte(dev, rOFDM0_RxDetector3, + priv->framesync); + reg_c38_State = RegC38_Default; + reset_cnt = priv->reset_count; + } + } else { + if (reg_c38_State) { + write_nic_byte(dev, rOFDM0_RxDetector3, + priv->framesync); + reg_c38_State = RegC38_Default; + } + } +} + +void dm_shadow_init(struct net_device *dev) +{ + u8 page; + u16 offset; + + for (page = 0; page < 5; page++) + for (offset = 0; offset < 256; offset++) + dm_shadow[page][offset] = read_nic_byte(dev, + offset+page * 256); + + for (page = 8; page < 11; page++) + for (offset = 0; offset < 256; offset++) + dm_shadow[page][offset] = read_nic_byte(dev, + offset+page * 256); + + for (page = 12; page < 15; page++) + for (offset = 0; offset < 256; offset++) + dm_shadow[page][offset] = read_nic_byte(dev, + offset+page*256); + +} + +/*---------------------------Define function prototype------------------------*/ +static void dm_init_dynamic_txpower(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + priv->rtllib->bdynamic_txpower_enable = true; + priv->bLastDTPFlag_High = false; + priv->bLastDTPFlag_Low = false; + priv->bDynamicTxHighPower = false; + priv->bDynamicTxLowPower = false; +} + +static void dm_dynamic_txpower(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + unsigned int txhipower_threshhold = 0; + unsigned int txlowpower_threshold = 0; + if (priv->rtllib->bdynamic_txpower_enable != true) { + priv->bDynamicTxHighPower = false; + priv->bDynamicTxLowPower = false; + return; + } + if ((priv->rtllib->pHTInfo->IOTPeer == HT_IOT_PEER_ATHEROS) && + (priv->rtllib->mode == IEEE_G)) { + txhipower_threshhold = TX_POWER_ATHEROAP_THRESH_HIGH; + txlowpower_threshold = TX_POWER_ATHEROAP_THRESH_LOW; + } else { + txhipower_threshhold = TX_POWER_NEAR_FIELD_THRESH_HIGH; + txlowpower_threshold = TX_POWER_NEAR_FIELD_THRESH_LOW; + } + + RT_TRACE(COMP_TXAGC, "priv->undecorated_smoothed_pwdb = %ld\n", + priv->undecorated_smoothed_pwdb); + + if (priv->rtllib->state == RTLLIB_LINKED) { + if (priv->undecorated_smoothed_pwdb >= txhipower_threshhold) { + priv->bDynamicTxHighPower = true; + priv->bDynamicTxLowPower = false; + } else { + if (priv->undecorated_smoothed_pwdb < + txlowpower_threshold && + priv->bDynamicTxHighPower == true) + priv->bDynamicTxHighPower = false; + if (priv->undecorated_smoothed_pwdb < 35) + priv->bDynamicTxLowPower = true; + else if (priv->undecorated_smoothed_pwdb >= 40) + priv->bDynamicTxLowPower = false; + } + } else { + priv->bDynamicTxHighPower = false; + priv->bDynamicTxLowPower = false; + } + + if ((priv->bDynamicTxHighPower != priv->bLastDTPFlag_High) || + (priv->bDynamicTxLowPower != priv->bLastDTPFlag_Low)) { + RT_TRACE(COMP_TXAGC, "SetTxPowerLevel8190() channel = %d\n", + priv->rtllib->current_network.channel); + + rtl8192_phy_setTxPower(dev, + priv->rtllib->current_network.channel); + } + priv->bLastDTPFlag_High = priv->bDynamicTxHighPower; + priv->bLastDTPFlag_Low = priv->bDynamicTxLowPower; + +} + +static void dm_check_txrateandretrycount(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + struct rtllib_device *ieee = priv->rtllib; + + ieee->softmac_stats.CurrentShowTxate = read_nic_byte(dev, + Current_Tx_Rate_Reg); + + ieee->softmac_stats.last_packet_rate = read_nic_byte(dev, + Initial_Tx_Rate_Reg); + + ieee->softmac_stats.txretrycount = read_nic_dword(dev, + Tx_Retry_Count_Reg); +} + +static void dm_send_rssi_tofw(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + write_nic_byte(dev, DRIVER_RSSI, (u8)priv->undecorated_smoothed_pwdb); +} diff --git a/drivers/staging/rtl8192e/rtl_dm.h b/drivers/staging/rtl8192e/rtl_dm.h new file mode 100644 index 0000000..ab44a9a --- /dev/null +++ b/drivers/staging/rtl8192e/rtl_dm.h @@ -0,0 +1,324 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> +******************************************************************************/ +#ifndef __R8192UDM_H__ +#define __R8192UDM_H__ + + +/*--------------------------Define Parameters-------------------------------*/ +#define OFDM_Table_Length 19 +#define CCK_Table_length 12 + +#define DM_DIG_THRESH_HIGH 40 +#define DM_DIG_THRESH_LOW 35 + +#define DM_FALSEALARM_THRESH_LOW 40 +#define DM_FALSEALARM_THRESH_HIGH 1000 + +#define DM_DIG_HIGH_PWR_THRESH_HIGH 75 +#define DM_DIG_HIGH_PWR_THRESH_LOW 70 + +#define BW_AUTO_SWITCH_HIGH_LOW 25 +#define BW_AUTO_SWITCH_LOW_HIGH 30 + +#define DM_check_fsync_time_interval 500 + + +#define DM_DIG_BACKOFF 12 +#define DM_DIG_MAX 0x36 +#define DM_DIG_MIN 0x1c +#define DM_DIG_MIN_Netcore 0x12 + +#define DM_DIG_BACKOFF_MAX 12 +#define DM_DIG_BACKOFF_MIN -4 + +#define RxPathSelection_SS_TH_low 30 +#define RxPathSelection_diff_TH 18 + +#define RateAdaptiveTH_High 50 +#define RateAdaptiveTH_Low_20M 30 +#define RateAdaptiveTH_Low_40M 10 +#define VeryLowRSSI 15 + +#define CTSToSelfTHVal 35 + +#define WAIotTHVal 25 + +#define E_FOR_TX_POWER_TRACK 300 +#define TX_POWER_NEAR_FIELD_THRESH_HIGH 68 +#define TX_POWER_NEAR_FIELD_THRESH_LOW 62 +#define TX_POWER_ATHEROAP_THRESH_HIGH 78 +#define TX_POWER_ATHEROAP_THRESH_LOW 72 + +#define Current_Tx_Rate_Reg 0x1e0 +#define Initial_Tx_Rate_Reg 0x1e1 +#define Tx_Retry_Count_Reg 0x1ac +#define RegC38_TH 20 + +#define TX_POWER_NEAR_FIELD_THRESH_LVL2 74 +#define TX_POWER_NEAR_FIELD_THRESH_LVL1 67 + +#define TxHighPwrLevel_Normal 0 +#define TxHighPwrLevel_Level1 1 +#define TxHighPwrLevel_Level2 2 + +#define DM_Type_ByFW 0 +#define DM_Type_ByDriver 1 + +/*--------------------------Define Parameters-------------------------------*/ + + +/*------------------------------Define structure----------------------------*/ +struct dig_t { + u8 dig_enable_flag; + u8 dig_algorithm; + u8 Dig_TwoPort_Algorithm; + u8 Dig_Ext_Port_Stage; + u8 dbg_mode; + u8 dig_algorithm_switch; + + long rssi_low_thresh; + long rssi_high_thresh; + + u32 FALowThresh; + u32 FAHighThresh; + + long rssi_high_power_lowthresh; + long rssi_high_power_highthresh; + + u8 dig_state; + u8 dig_highpwr_state; + u8 CurSTAConnectState; + u8 PreSTAConnectState; + u8 CurAPConnectState; + u8 PreAPConnectState; + + u8 curpd_thstate; + u8 prepd_thstate; + u8 curcs_ratio_state; + u8 precs_ratio_state; + + u32 pre_ig_value; + u32 cur_ig_value; + + u8 Backoff_Enable_Flag; + u8 backoff_val; + char BackoffVal_range_max; + char BackoffVal_range_min; + u8 rx_gain_range_max; + u8 rx_gain_range_min; + bool initialgain_lowerbound_state; + + long rssi_val; +}; + +enum dm_dig_sta { + DM_STA_DIG_OFF = 0, + DM_STA_DIG_ON, + DM_STA_DIG_MAX +}; + + +enum dm_ratr_sta { + DM_RATR_STA_HIGH = 0, + DM_RATR_STA_MIDDLE = 1, + DM_RATR_STA_LOW = 2, + DM_RATR_STA_MAX +}; + +enum dm_dig_op_sta { + DIG_TYPE_THRESH_HIGH = 0, + DIG_TYPE_THRESH_LOW = 1, + DIG_TYPE_THRESH_HIGHPWR_HIGH = 2, + DIG_TYPE_THRESH_HIGHPWR_LOW = 3, + DIG_TYPE_DBG_MODE = 4, + DIG_TYPE_RSSI = 5, + DIG_TYPE_ALGORITHM = 6, + DIG_TYPE_BACKOFF = 7, + DIG_TYPE_PWDB_FACTOR = 8, + DIG_TYPE_RX_GAIN_MIN = 9, + DIG_TYPE_RX_GAIN_MAX = 10, + DIG_TYPE_ENABLE = 20, + DIG_TYPE_DISABLE = 30, + DIG_OP_TYPE_MAX +}; + +enum dm_dig_alg { + DIG_ALGO_BY_FALSE_ALARM = 0, + DIG_ALGO_BY_RSSI = 1, + DIG_ALGO_BEFORE_CONNECT_BY_RSSI_AND_ALARM = 2, + DIG_ALGO_BY_TOW_PORT = 3, + DIG_ALGO_MAX +}; + +enum dm_dig_two_port_alg { + DIG_TWO_PORT_ALGO_RSSI = 0, + DIG_TWO_PORT_ALGO_FALSE_ALARM = 1, +}; + + +enum dm_dig_ext_port_alg { + DIG_EXT_PORT_STAGE_0 = 0, + DIG_EXT_PORT_STAGE_1 = 1, + DIG_EXT_PORT_STAGE_2 = 2, + DIG_EXT_PORT_STAGE_3 = 3, + DIG_EXT_PORT_STAGE_MAX = 4, +}; + +enum dm_dig_dbg { + DIG_DBG_OFF = 0, + DIG_DBG_ON = 1, + DIG_DBG_MAX +}; + +enum dm_dig_connect { + DIG_STA_DISCONNECT = 0, + DIG_STA_CONNECT = 1, + DIG_STA_BEFORE_CONNECT = 2, + DIG_AP_DISCONNECT = 3, + DIG_AP_CONNECT = 4, + DIG_AP_ADD_STATION = 5, + DIG_CONNECT_MAX +}; + +enum dm_dig_pd_th { + DIG_PD_AT_LOW_POWER = 0, + DIG_PD_AT_NORMAL_POWER = 1, + DIG_PD_AT_HIGH_POWER = 2, + DIG_PD_MAX +}; + +enum dm_dig_cs_ratio { + DIG_CS_RATIO_LOWER = 0, + DIG_CS_RATIO_HIGHER = 1, + DIG_CS_MAX +}; + +struct drx_path_sel { + u8 Enable; + u8 DbgMode; + u8 cck_method; + u8 cck_Rx_path; + + u8 SS_TH_low; + u8 diff_TH; + u8 disabledRF; + u8 reserved; + + u8 rf_rssi[4]; + u8 rf_enable_rssi_th[4]; + long cck_pwdb_sta[4]; +}; + +enum dm_cck_rx_path_method { + CCK_Rx_Version_1 = 0, + CCK_Rx_Version_2 = 1, + CCK_Rx_Version_MAX +}; + + +enum dm_dbg { + DM_DBG_OFF = 0, + DM_DBG_ON = 1, + DM_DBG_MAX +}; + +struct dcmd_txcmd { + u32 Op; + u32 Length; + u32 Value; +}; +/*------------------------------Define structure----------------------------*/ + + +/*------------------------Export global variable----------------------------*/ +extern struct dig_t dm_digtable; +extern u8 dm_shadow[16][256]; +extern struct drx_path_sel DM_RxPathSelTable; + +extern u8 test_flag; +/*------------------------Export global variable----------------------------*/ + + +/*------------------------Export Marco Definition---------------------------*/ +#define DM_APInitGainChangeNotify(Event) \ + { \ + dm_digtable.CurAPConnectState = Event; \ + } +/*------------------------Export Marco Definition---------------------------*/ + + +/*--------------------------Exported Function prototype---------------------*/ +/*--------------------------Exported Function prototype---------------------*/ +extern void init_hal_dm(struct net_device *dev); +extern void deinit_hal_dm(struct net_device *dev); + +extern void hal_dm_watchdog(struct net_device *dev); + + +extern void init_rate_adaptive(struct net_device *dev); +extern void dm_txpower_trackingcallback(void *data); + +extern void dm_cck_txpower_adjust(struct net_device *dev, bool binch14); + +extern void dm_restore_dynamic_mechanism_state(struct net_device *dev); +extern void dm_backup_dynamic_mechanism_state(struct net_device *dev); +extern void dm_change_dynamic_initgain_thresh(struct net_device *dev, + u32 dm_type, + u32 dm_value); +extern void DM_ChangeFsyncSetting(struct net_device *dev, + s32 DM_Type, + s32 DM_Value); +extern void dm_force_tx_fw_info(struct net_device *dev, + u32 force_type, + u32 force_value); +extern void dm_init_edca_turbo(struct net_device *dev); +extern void dm_rf_operation_test_callback(unsigned long data); +extern void dm_rf_pathcheck_workitemcallback(void *data); +extern void dm_fsync_timer_callback(unsigned long data); +extern void dm_check_fsync(struct net_device *dev); +extern void dm_shadow_init(struct net_device *dev); +extern void dm_initialize_txpower_tracking(struct net_device *dev); +extern void dm_CheckRfCtrlGPIO(void *data); +extern void dm_InitRateAdaptiveMask(struct net_device *dev); +extern void init_hal_dm(struct net_device *dev); +extern void deinit_hal_dm(struct net_device *dev); +extern void hal_dm_watchdog(struct net_device *dev); +extern void init_rate_adaptive(struct net_device *dev); +extern void dm_txpower_trackingcallback(void *data); +extern void dm_restore_dynamic_mechanism_state(struct net_device *dev); +extern void dm_backup_dynamic_mechanism_state(struct net_device *dev); +extern void dm_change_dynamic_initgain_thresh(struct net_device *dev, + u32 dm_type, + u32 dm_value); +extern void DM_ChangeFsyncSetting(struct net_device *dev, + s32 DM_Type, + s32 DM_Value); +extern void dm_force_tx_fw_info(struct net_device *dev, + u32 force_type, + u32 force_value); +extern void dm_init_edca_turbo(struct net_device *dev); +extern void dm_rf_operation_test_callback(unsigned long data); +extern void dm_rf_pathcheck_workitemcallback(void *data); +extern void dm_fsync_timer_callback(unsigned long data); +extern void dm_check_fsync(struct net_device *dev); +extern void dm_shadow_init(struct net_device *dev); +extern void dm_initialize_txpower_tracking(struct net_device *dev); +extern void dm_CheckRfCtrlGPIO(void *data); + +#endif /*__R8192UDM_H__ */ diff --git a/drivers/staging/rtl8192e/rtl_eeprom.c b/drivers/staging/rtl8192e/rtl_eeprom.c new file mode 100644 index 0000000..c1ccff4 --- /dev/null +++ b/drivers/staging/rtl8192e/rtl_eeprom.c @@ -0,0 +1,139 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * Based on the r8180 driver, which is: + * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al. + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> +******************************************************************************/ +#include "rtl_core.h" +#include "rtl_eeprom.h" + +static void eprom_cs(struct net_device *dev, short bit) +{ + if (bit) + write_nic_byte(dev, EPROM_CMD, + (1 << EPROM_CS_SHIFT) | + read_nic_byte(dev, EPROM_CMD)); + else + write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev, EPROM_CMD) + & ~(1<<EPROM_CS_SHIFT)); + + udelay(EPROM_DELAY); +} + + +static void eprom_ck_cycle(struct net_device *dev) +{ + write_nic_byte(dev, EPROM_CMD, + (1<<EPROM_CK_SHIFT) | read_nic_byte(dev, EPROM_CMD)); + udelay(EPROM_DELAY); + write_nic_byte(dev, EPROM_CMD, + read_nic_byte(dev, EPROM_CMD) & ~(1<<EPROM_CK_SHIFT)); + udelay(EPROM_DELAY); +} + + +static void eprom_w(struct net_device *dev, short bit) +{ + if (bit) + write_nic_byte(dev, EPROM_CMD, (1<<EPROM_W_SHIFT) | + read_nic_byte(dev, EPROM_CMD)); + else + write_nic_byte(dev, EPROM_CMD, read_nic_byte(dev, EPROM_CMD) + & ~(1<<EPROM_W_SHIFT)); + + udelay(EPROM_DELAY); +} + + +static short eprom_r(struct net_device *dev) +{ + short bit; + + bit = (read_nic_byte(dev, EPROM_CMD) & (1<<EPROM_R_SHIFT)); + udelay(EPROM_DELAY); + + if (bit) + return 1; + return 0; +} + +static void eprom_send_bits_string(struct net_device *dev, short b[], int len) +{ + int i; + + for (i = 0; i < len; i++) { + eprom_w(dev, b[i]); + eprom_ck_cycle(dev); + } +} + +u32 eprom_read(struct net_device *dev, u32 addr) +{ + struct r8192_priv *priv = rtllib_priv(dev); + short read_cmd[] = {1, 1, 0}; + short addr_str[8]; + int i; + int addr_len; + u32 ret; + + ret = 0; + write_nic_byte(dev, EPROM_CMD, + (EPROM_CMD_PROGRAM << EPROM_CMD_OPERATING_MODE_SHIFT)); + udelay(EPROM_DELAY); + + if (priv->epromtype == EEPROM_93C56) { + addr_str[7] = addr & 1; + addr_str[6] = addr & (1<<1); + addr_str[5] = addr & (1<<2); + addr_str[4] = addr & (1<<3); + addr_str[3] = addr & (1<<4); + addr_str[2] = addr & (1<<5); + addr_str[1] = addr & (1<<6); + addr_str[0] = addr & (1<<7); + addr_len = 8; + } else { + addr_str[5] = addr & 1; + addr_str[4] = addr & (1<<1); + addr_str[3] = addr & (1<<2); + addr_str[2] = addr & (1<<3); + addr_str[1] = addr & (1<<4); + addr_str[0] = addr & (1<<5); + addr_len = 6; + } + eprom_cs(dev, 1); + eprom_ck_cycle(dev); + eprom_send_bits_string(dev, read_cmd, 3); + eprom_send_bits_string(dev, addr_str, addr_len); + + eprom_w(dev, 0); + + for (i = 0; i < 16; i++) { + eprom_ck_cycle(dev); + ret |= (eprom_r(dev)<<(15-i)); + } + + eprom_cs(dev, 0); + eprom_ck_cycle(dev); + + write_nic_byte(dev, EPROM_CMD, + (EPROM_CMD_NORMAL<<EPROM_CMD_OPERATING_MODE_SHIFT)); + return ret; +} diff --git a/drivers/staging/rtl8192e/rtl_eeprom.h b/drivers/staging/rtl8192e/rtl_eeprom.h new file mode 100644 index 0000000..9452e16 --- /dev/null +++ b/drivers/staging/rtl8192e/rtl_eeprom.h @@ -0,0 +1,29 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * Based on the r8180 driver, which is: + * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al. + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> +******************************************************************************/ + + +#define EPROM_DELAY 10 + +u32 eprom_read(struct net_device *dev, u32 addr); diff --git a/drivers/staging/rtl8192e/rtl_ethtool.c b/drivers/staging/rtl8192e/rtl_ethtool.c new file mode 100644 index 0000000..36452fb --- /dev/null +++ b/drivers/staging/rtl8192e/rtl_ethtool.c @@ -0,0 +1,53 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * Based on the r8180 driver, which is: + * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al. + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> + ***************************************************************************** + */ +#include <linux/netdevice.h> +#include <linux/ethtool.h> +#include <linux/delay.h> + +#include "rtl_core.h" + +static void rtl819x_ethtool_get_drvinfo(struct net_device *dev, + struct ethtool_drvinfo *info) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + strcpy(info->bus_info, pci_name(priv->pdev)); +} + +static u32 rtl819x_ethtool_get_link(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + return ((priv->rtllib->state == RTLLIB_LINKED) || + (priv->rtllib->state == RTLLIB_LINKED_SCANNING)); +} + +const struct ethtool_ops rtl819x_ethtool_ops = { + .get_drvinfo = rtl819x_ethtool_get_drvinfo, + .get_link = rtl819x_ethtool_get_link, +}; diff --git a/drivers/staging/rtl8192e/rtl_pci.c b/drivers/staging/rtl8192e/rtl_pci.c new file mode 100644 index 0000000..ddadcc3 --- /dev/null +++ b/drivers/staging/rtl8192e/rtl_pci.c @@ -0,0 +1,97 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * Based on the r8180 driver, which is: + * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al. + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> + *****************************************************************************/ +#include "rtl_pci.h" +#include "rtl_core.h" + +static void rtl8192_parse_pci_configuration(struct pci_dev *pdev, + struct net_device *dev) +{ + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + + u8 tmp; + int pos; + u8 LinkCtrlReg; + + pos = pci_find_capability(priv->pdev, PCI_CAP_ID_EXP); + pci_read_config_byte(priv->pdev, pos + PCI_EXP_LNKCTL, &LinkCtrlReg); + priv->NdisAdapter.LinkCtrlReg = LinkCtrlReg; + + RT_TRACE(COMP_INIT, "Link Control Register =%x\n", + priv->NdisAdapter.LinkCtrlReg); + + pci_read_config_byte(pdev, 0x98, &tmp); + tmp |= BIT4; + pci_write_config_byte(pdev, 0x98, tmp); + + tmp = 0x17; + pci_write_config_byte(pdev, 0x70f, tmp); +} + +bool rtl8192_pci_findadapter(struct pci_dev *pdev, struct net_device *dev) +{ + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + u16 VenderID; + u16 DeviceID; + u8 RevisionID; + u16 IrqLine; + + VenderID = pdev->vendor; + DeviceID = pdev->device; + RevisionID = pdev->revision; + pci_read_config_word(pdev, 0x3C, &IrqLine); + + priv->card_8192 = priv->ops->nic_type; + + if (DeviceID == 0x8172) { + switch (RevisionID) { + case HAL_HW_PCI_REVISION_ID_8192PCIE: + printk(KERN_INFO "Adapter(8192 PCI-E) is found - " + "DeviceID=%x\n", DeviceID); + priv->card_8192 = NIC_8192E; + break; + case HAL_HW_PCI_REVISION_ID_8192SE: + printk(KERN_INFO "Adapter(8192SE) is found - " + "DeviceID=%x\n", DeviceID); + priv->card_8192 = NIC_8192SE; + break; + default: + printk(KERN_INFO "UNKNOWN nic type(%4x:%4x)\n", + pdev->vendor, pdev->device); + priv->card_8192 = NIC_UNKNOWN; + return false; + } + } + + if (priv->ops->nic_type != priv->card_8192) { + printk(KERN_INFO "Detect info(%x) and hardware info(%x) not match!\n", + priv->ops->nic_type, priv->card_8192); + printk(KERN_INFO "Please select proper driver before install!!!!\n"); + return false; + } + + rtl8192_parse_pci_configuration(pdev, dev); + + return true; +} diff --git a/drivers/staging/rtl8192e/rtl_pci.h b/drivers/staging/rtl8192e/rtl_pci.h new file mode 100644 index 0000000..7ea5a47 --- /dev/null +++ b/drivers/staging/rtl8192e/rtl_pci.h @@ -0,0 +1,104 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * Based on the r8180 driver, which is: + * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al. + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> + ******************************************************************************/ +#ifndef _RTL_PCI_H +#define _RTL_PCI_H + +#include <linux/types.h> +#include <linux/pci.h> +#include "rtllib.h" + +static inline void NdisRawWritePortUlong(u32 port, u32 val) +{ + outl(val, port); +} + +static inline void NdisRawWritePortUchar(u32 port, u8 val) +{ + outb(val, port); +} + +static inline void NdisRawReadPortUchar(u32 port, u8 *pval) +{ + *pval = inb(port); +} + +static inline void NdisRawReadPortUshort(u32 port, u16 *pval) +{ + *pval = inw(port); +} + +static inline void NdisRawReadPortUlong(u32 port, u32 *pval) +{ + *pval = inl(port); +} + +struct mp_adapter { + u8 LinkCtrlReg; + + u8 BusNumber; + u8 DevNumber; + u8 FuncNumber; + + u8 PciBridgeBusNum; + u8 PciBridgeDevNum; + u8 PciBridgeFuncNum; + u8 PciBridgeVendor; + u16 PciBridgeVendorId; + u16 PciBridgeDeviceId; + u8 PciBridgePCIeHdrOffset; + u8 PciBridgeLinkCtrlReg; +}; + +struct rt_pci_capab_header { + unsigned char CapabilityID; + unsigned char Next; +}; + +#define PCI_MAX_BRIDGE_NUMBER 255 +#define PCI_MAX_DEVICES 32 +#define PCI_MAX_FUNCTION 8 + +#define PCI_CONF_ADDRESS 0x0CF8 +#define PCI_CONF_DATA 0x0CFC + +#define PCI_CLASS_BRIDGE_DEV 0x06 +#define PCI_SUBCLASS_BR_PCI_TO_PCI 0x04 + +#define U1DONTCARE 0xFF +#define U2DONTCARE 0xFFFF +#define U4DONTCARE 0xFFFFFFFF + +#define INTEL_VENDOR_ID 0x8086 +#define SIS_VENDOR_ID 0x1039 +#define ATI_VENDOR_ID 0x1002 +#define ATI_DEVICE_ID 0x7914 +#define AMD_VENDOR_ID 0x1022 + +#define PCI_CAPABILITY_ID_PCI_EXPRESS 0x10 + +struct net_device; +bool rtl8192_pci_findadapter(struct pci_dev *pdev, struct net_device *dev); + +#endif diff --git a/drivers/staging/rtl8192e/rtl_pm.c b/drivers/staging/rtl8192e/rtl_pm.c new file mode 100644 index 0000000..92e2fde --- /dev/null +++ b/drivers/staging/rtl8192e/rtl_pm.c @@ -0,0 +1,136 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> +******************************************************************************/ + +#ifdef CONFIG_PM_RTL +#include "rtl_core.h" +#include "r8192E_hw.h" +#include "r8190P_rtl8256.h" +#include "rtl_pm.h" + +int rtl8192E_save_state(struct pci_dev *dev, pm_message_t state) +{ + printk(KERN_NOTICE "r8192E save state call (state %u).\n", state.event); + return -EAGAIN; +} + + +int rtl8192E_suspend(struct pci_dev *pdev, pm_message_t state) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct r8192_priv *priv = rtllib_priv(dev); + u32 ulRegRead; + + printk(KERN_INFO "============> r8192E suspend call.\n"); + del_timer_sync(&priv->gpio_polling_timer); + cancel_delayed_work(&priv->gpio_change_rf_wq); + priv->polling_timer_on = 0; + + if (!netif_running(dev)) { + printk(KERN_INFO "RTL819XE:UI is open out of suspend " + "function\n"); + goto out_pci_suspend; + } + + if (dev->netdev_ops->ndo_stop) + dev->netdev_ops->ndo_stop(dev); + netif_device_detach(dev); + + if (!priv->rtllib->bSupportRemoteWakeUp) { + MgntActSet_RF_State(dev, eRfOff, RF_CHANGE_BY_INIT, true); + ulRegRead = read_nic_dword(dev, CPU_GEN); + ulRegRead |= CPU_GEN_SYSTEM_RESET; + write_nic_dword(dev, CPU_GEN, ulRegRead); + } else { + write_nic_dword(dev, WFCRC0, 0xffffffff); + write_nic_dword(dev, WFCRC1, 0xffffffff); + write_nic_dword(dev, WFCRC2, 0xffffffff); + write_nic_byte(dev, PMR, 0x5); + write_nic_byte(dev, MacBlkCtrl, 0xa); + } +out_pci_suspend: + printk("r8192E support WOL call??????????????????????\n"); + if (priv->rtllib->bSupportRemoteWakeUp) + RT_TRACE(COMP_POWER, "r8192E support WOL call!!!!!!!" + "!!!!!!!!!!!.\n"); + pci_save_state(pdev); + pci_disable_device(pdev); + pci_enable_wake(pdev, pci_choose_state(pdev, state), + priv->rtllib->bSupportRemoteWakeUp ? 1 : 0); + pci_set_power_state(pdev, pci_choose_state(pdev, state)); + + mdelay(20); + + return 0; +} + +int rtl8192E_resume(struct pci_dev *pdev) +{ + struct net_device *dev = pci_get_drvdata(pdev); + struct r8192_priv *priv = rtllib_priv(dev); + int err; + u32 val; + + printk(KERN_INFO "================>r8192E resume call.\n"); + + pci_set_power_state(pdev, PCI_D0); + + err = pci_enable_device(pdev); + if (err) { + printk(KERN_ERR "%s: pci_enable_device failed on resume\n", + dev->name); + return err; + } + pci_restore_state(pdev); + + pci_read_config_dword(pdev, 0x40, &val); + if ((val & 0x0000ff00) != 0) + pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); + + pci_enable_wake(pdev, PCI_D0, 0); + + if (priv->polling_timer_on == 0) + check_rfctrl_gpio_timer((unsigned long)dev); + + if (!netif_running(dev)) { + printk(KERN_INFO "RTL819XE:UI is open out of resume " + "function\n"); + goto out; + } + + netif_device_attach(dev); + if (dev->netdev_ops->ndo_open) + dev->netdev_ops->ndo_open(dev); + + if (!priv->rtllib->bSupportRemoteWakeUp) + MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_INIT, true); + +out: + RT_TRACE(COMP_POWER, "<================r8192E resume call.\n"); + return 0; +} + + +int rtl8192E_enable_wake(struct pci_dev *dev, pm_message_t state, int enable) +{ + printk(KERN_NOTICE "r8192E enable wake call (state %u, enable %d).\n", + state.event, enable); + return -EAGAIN; +} + +#endif diff --git a/drivers/staging/rtl8192e/rtl_pm.h b/drivers/staging/rtl8192e/rtl_pm.h new file mode 100644 index 0000000..4d7f406 --- /dev/null +++ b/drivers/staging/rtl8192e/rtl_pm.h @@ -0,0 +1,35 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> +******************************************************************************/ + +#ifdef CONFIG_PM_RTL + +#ifndef R8192E_PM_H +#define R8192E_PM_H + +#include <linux/types.h> +#include <linux/pci.h> + +int rtl8192E_save_state(struct pci_dev *dev, pm_message_t state); +int rtl8192E_suspend(struct pci_dev *dev, pm_message_t state); +int rtl8192E_resume(struct pci_dev *dev); +int rtl8192E_enable_wake(struct pci_dev *dev, pm_message_t state, int enable); + +#endif + +#endif diff --git a/drivers/staging/rtl8192e/rtl_ps.c b/drivers/staging/rtl8192e/rtl_ps.c new file mode 100644 index 0000000..c9a7c56 --- /dev/null +++ b/drivers/staging/rtl8192e/rtl_ps.c @@ -0,0 +1,310 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * Based on the r8180 driver, which is: + * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al. + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> + *****************************************************************************/ +#include "rtl_ps.h" +#include "rtl_core.h" +#include "r8192E_phy.h" +#include "r8192E_phyreg.h" +#include "r8190P_rtl8256.h" /* RTL8225 Radio frontend */ +#include "r8192E_cmdpkt.h" + +static void rtl8192_hw_sleep_down(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + unsigned long flags = 0; + spin_lock_irqsave(&priv->rf_ps_lock, flags); + if (priv->RFChangeInProgress) { + spin_unlock_irqrestore(&priv->rf_ps_lock, flags); + RT_TRACE(COMP_DBG, "rtl8192_hw_sleep_down(): RF Change in " + "progress!\n"); + return; + } + spin_unlock_irqrestore(&priv->rf_ps_lock, flags); + RT_TRACE(COMP_DBG, "%s()============>come to sleep down\n", __func__); + + MgntActSet_RF_State(dev, eRfSleep, RF_CHANGE_BY_PS, false); +} + +void rtl8192_hw_sleep_wq(void *data) +{ + struct rtllib_device *ieee = container_of_dwork_rsl(data, + struct rtllib_device, hw_sleep_wq); + struct net_device *dev = ieee->dev; + rtl8192_hw_sleep_down(dev); +} + +void rtl8192_hw_wakeup(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + unsigned long flags = 0; + spin_lock_irqsave(&priv->rf_ps_lock, flags); + if (priv->RFChangeInProgress) { + spin_unlock_irqrestore(&priv->rf_ps_lock, flags); + RT_TRACE(COMP_DBG, "rtl8192_hw_wakeup(): RF Change in " + "progress!\n"); + queue_delayed_work_rsl(priv->rtllib->wq, + &priv->rtllib->hw_wakeup_wq, MSECS(10)); + return; + } + spin_unlock_irqrestore(&priv->rf_ps_lock, flags); + RT_TRACE(COMP_PS, "%s()============>come to wake up\n", __func__); + MgntActSet_RF_State(dev, eRfOn, RF_CHANGE_BY_PS, false); +} + +void rtl8192_hw_wakeup_wq(void *data) +{ + struct rtllib_device *ieee = container_of_dwork_rsl(data, + struct rtllib_device, hw_wakeup_wq); + struct net_device *dev = ieee->dev; + rtl8192_hw_wakeup(dev); + +} + +#define MIN_SLEEP_TIME 50 +#define MAX_SLEEP_TIME 10000 +void rtl8192_hw_to_sleep(struct net_device *dev, u64 time) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + u32 tmp; + unsigned long flags; + + spin_lock_irqsave(&priv->ps_lock, flags); + + time -= MSECS(8+16+7); + + if ((time - jiffies) <= MSECS(MIN_SLEEP_TIME)) { + spin_unlock_irqrestore(&priv->ps_lock, flags); + printk(KERN_INFO "too short to sleep::%lld < %ld\n", + time - jiffies, MSECS(MIN_SLEEP_TIME)); + return; + } + + if ((time - jiffies) > MSECS(MAX_SLEEP_TIME)) { + printk(KERN_INFO "========>too long to sleep:%lld > %ld\n", + time - jiffies, MSECS(MAX_SLEEP_TIME)); + spin_unlock_irqrestore(&priv->ps_lock, flags); + return; + } + tmp = time - jiffies; + queue_delayed_work_rsl(priv->rtllib->wq, + &priv->rtllib->hw_wakeup_wq, tmp); + queue_delayed_work_rsl(priv->rtllib->wq, + (void *)&priv->rtllib->hw_sleep_wq, 0); + spin_unlock_irqrestore(&priv->ps_lock, flags); +} + +static void InactivePsWorkItemCallback(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) + &(priv->rtllib->PowerSaveControl); + + RT_TRACE(COMP_PS, "InactivePsWorkItemCallback() --------->\n"); + pPSC->bSwRfProcessing = true; + + RT_TRACE(COMP_PS, "InactivePsWorkItemCallback(): Set RF to %s.\n", + pPSC->eInactivePowerState == eRfOff ? "OFF" : "ON"); + MgntActSet_RF_State(dev, pPSC->eInactivePowerState, RF_CHANGE_BY_IPS, + false); + + pPSC->bSwRfProcessing = false; + RT_TRACE(COMP_PS, "InactivePsWorkItemCallback() <---------\n"); +} + +void IPSEnter(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) + &(priv->rtllib->PowerSaveControl); + enum rt_rf_power_state rtState; + + if (pPSC->bInactivePs) { + rtState = priv->rtllib->eRFPowerState; + if (rtState == eRfOn && !pPSC->bSwRfProcessing && + (priv->rtllib->state != RTLLIB_LINKED) && + (priv->rtllib->iw_mode != IW_MODE_MASTER)) { + RT_TRACE(COMP_PS, "IPSEnter(): Turn off RF.\n"); + pPSC->eInactivePowerState = eRfOff; + priv->isRFOff = true; + priv->bInPowerSaveMode = true; + InactivePsWorkItemCallback(dev); + } + } +} + +void IPSLeave(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) + &(priv->rtllib->PowerSaveControl); + enum rt_rf_power_state rtState; + + if (pPSC->bInactivePs) { + rtState = priv->rtllib->eRFPowerState; + if (rtState != eRfOn && !pPSC->bSwRfProcessing && + priv->rtllib->RfOffReason <= RF_CHANGE_BY_IPS) { + RT_TRACE(COMP_PS, "IPSLeave(): Turn on RF.\n"); + pPSC->eInactivePowerState = eRfOn; + priv->bInPowerSaveMode = false; + InactivePsWorkItemCallback(dev); + } + } +} + +void IPSLeave_wq(void *data) +{ + struct rtllib_device *ieee = container_of_work_rsl(data, + struct rtllib_device, ips_leave_wq); + struct net_device *dev = ieee->dev; + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + down(&priv->rtllib->ips_sem); + IPSLeave(dev); + up(&priv->rtllib->ips_sem); +} + +void rtllib_ips_leave_wq(struct net_device *dev) +{ + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + enum rt_rf_power_state rtState; + rtState = priv->rtllib->eRFPowerState; + + if (priv->rtllib->PowerSaveControl.bInactivePs) { + if (rtState == eRfOff) { + if (priv->rtllib->RfOffReason > RF_CHANGE_BY_IPS) { + RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n", + __func__); + return; + } else { + printk(KERN_INFO "=========>%s(): IPSLeave\n", + __func__); + queue_work_rsl(priv->rtllib->wq, + &priv->rtllib->ips_leave_wq); + } + } + } +} + +void rtllib_ips_leave(struct net_device *dev) +{ + struct r8192_priv *priv = (struct r8192_priv *)rtllib_priv(dev); + down(&priv->rtllib->ips_sem); + IPSLeave(dev); + up(&priv->rtllib->ips_sem); +} + +static bool MgntActSet_802_11_PowerSaveMode(struct net_device *dev, + u8 rtPsMode) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + if (priv->rtllib->iw_mode == IW_MODE_ADHOC) + return false; + + RT_TRACE(COMP_LPS, "%s(): set ieee->ps = %x\n", __func__, rtPsMode); + if (!priv->ps_force) + priv->rtllib->ps = rtPsMode; + if (priv->rtllib->sta_sleep != LPS_IS_WAKE && + rtPsMode == RTLLIB_PS_DISABLED) { + unsigned long flags; + + rtl8192_hw_wakeup(dev); + priv->rtllib->sta_sleep = LPS_IS_WAKE; + + spin_lock_irqsave(&(priv->rtllib->mgmt_tx_lock), flags); + RT_TRACE(COMP_DBG, "LPS leave: notify AP we are awaked" + " ++++++++++ SendNullFunctionData\n"); + rtllib_sta_ps_send_null_frame(priv->rtllib, 0); + spin_unlock_irqrestore(&(priv->rtllib->mgmt_tx_lock), flags); + } + + return true; +} + +void LeisurePSEnter(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) + &(priv->rtllib->PowerSaveControl); + + RT_TRACE(COMP_PS, "LeisurePSEnter()...\n"); + RT_TRACE(COMP_PS, "pPSC->bLeisurePs = %d, ieee->ps = %d,pPSC->LpsIdle" + "Count is %d,RT_CHECK_FOR_HANG_PERIOD is %d\n", + pPSC->bLeisurePs, priv->rtllib->ps, pPSC->LpsIdleCount, + RT_CHECK_FOR_HANG_PERIOD); + + if (!((priv->rtllib->iw_mode == IW_MODE_INFRA) && + (priv->rtllib->state == RTLLIB_LINKED)) + || (priv->rtllib->iw_mode == IW_MODE_ADHOC) || + (priv->rtllib->iw_mode == IW_MODE_MASTER)) + return; + + if (pPSC->bLeisurePs) { + if (pPSC->LpsIdleCount >= RT_CHECK_FOR_HANG_PERIOD) { + + if (priv->rtllib->ps == RTLLIB_PS_DISABLED) { + + RT_TRACE(COMP_LPS, "LeisurePSEnter(): Enter " + "802.11 power save mode...\n"); + + if (!pPSC->bFwCtrlLPS) { + if (priv->rtllib->SetFwCmdHandler) + priv->rtllib->SetFwCmdHandler( + dev, FW_CMD_LPS_ENTER); + } + MgntActSet_802_11_PowerSaveMode(dev, + RTLLIB_PS_MBCAST | + RTLLIB_PS_UNICAST); + } + } else + pPSC->LpsIdleCount++; + } +} + +void LeisurePSLeave(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) + &(priv->rtllib->PowerSaveControl); + + + RT_TRACE(COMP_PS, "LeisurePSLeave()...\n"); + RT_TRACE(COMP_PS, "pPSC->bLeisurePs = %d, ieee->ps = %d\n", + pPSC->bLeisurePs, priv->rtllib->ps); + + if (pPSC->bLeisurePs) { + if (priv->rtllib->ps != RTLLIB_PS_DISABLED) { + RT_TRACE(COMP_LPS, "LeisurePSLeave(): Busy Traffic , " + "Leave 802.11 power save..\n"); + MgntActSet_802_11_PowerSaveMode(dev, + RTLLIB_PS_DISABLED); + + if (!pPSC->bFwCtrlLPS) { + if (priv->rtllib->SetFwCmdHandler) + priv->rtllib->SetFwCmdHandler(dev, + FW_CMD_LPS_LEAVE); + } + } + } +} diff --git a/drivers/staging/rtl8192e/rtl_ps.h b/drivers/staging/rtl8192e/rtl_ps.h new file mode 100644 index 0000000..a9c2d79 --- /dev/null +++ b/drivers/staging/rtl8192e/rtl_ps.h @@ -0,0 +1,47 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * Based on the r8180 driver, which is: + * Copyright 2004-2005 Andrea Merello <andreamrl@tiscali.it>, et al. + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> + ******************************************************************************/ +#ifndef _RTL_PS_H +#define _RTL_PS_H + +#include <linux/types.h> +#include "rtllib.h" +struct net_device; + +#define RT_CHECK_FOR_HANG_PERIOD 2 +#define INIT_DEFAULT_CHAN 1 + +void rtl8192_hw_wakeup(struct net_device *dev); +void rtl8192_hw_to_sleep(struct net_device *dev, u64 time); +void rtllib_ips_leave_wq(struct net_device *dev); +void rtllib_ips_leave(struct net_device *dev); +void IPSLeave_wq(void *data); + +void IPSEnter(struct net_device *dev); +void IPSLeave(struct net_device *dev); + +void LeisurePSEnter(struct net_device *dev); +void LeisurePSLeave(struct net_device *dev); + +#endif diff --git a/drivers/staging/rtl8192e/rtl_wx.c b/drivers/staging/rtl8192e/rtl_wx.c new file mode 100644 index 0000000..77ea4bb --- /dev/null +++ b/drivers/staging/rtl8192e/rtl_wx.c @@ -0,0 +1,1332 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> +******************************************************************************/ + +#include <linux/string.h> +#include "rtl_core.h" +#include "dot11d.h" + +#define RATE_COUNT 12 +static u32 rtl8192_rates[] = { + 1000000, 2000000, 5500000, 11000000, 6000000, 9000000, 12000000, + 18000000, 24000000, 36000000, 48000000, 54000000 +}; + +#ifndef ENETDOWN +#define ENETDOWN 1 +#endif + +static int r8192_wx_get_freq(struct net_device *dev, + struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + return rtllib_wx_get_freq(priv->rtllib, a, wrqu, b); +} + + +static int r8192_wx_get_mode(struct net_device *dev, struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + return rtllib_wx_get_mode(priv->rtllib, a, wrqu, b); +} + +static int r8192_wx_get_rate(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = rtllib_priv(dev); + return rtllib_wx_get_rate(priv->rtllib, info, wrqu, extra); +} + + + +static int r8192_wx_set_rate(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + struct r8192_priv *priv = rtllib_priv(dev); + + if (priv->bHwRadioOff == true) + return 0; + + down(&priv->wx_sem); + + ret = rtllib_wx_set_rate(priv->rtllib, info, wrqu, extra); + + up(&priv->wx_sem); + + return ret; +} + + +static int r8192_wx_set_rts(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + struct r8192_priv *priv = rtllib_priv(dev); + + if (priv->bHwRadioOff == true) + return 0; + + down(&priv->wx_sem); + + ret = rtllib_wx_set_rts(priv->rtllib, info, wrqu, extra); + + up(&priv->wx_sem); + + return ret; +} + +static int r8192_wx_get_rts(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = rtllib_priv(dev); + return rtllib_wx_get_rts(priv->rtllib, info, wrqu, extra); +} + +static int r8192_wx_set_power(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret; + struct r8192_priv *priv = rtllib_priv(dev); + + if (priv->bHwRadioOff == true) { + RT_TRACE(COMP_ERR, "%s():Hw is Radio Off, we can't set " + "Power,return\n", __func__); + return 0; + } + down(&priv->wx_sem); + + ret = rtllib_wx_set_power(priv->rtllib, info, wrqu, extra); + + up(&priv->wx_sem); + + return ret; +} + +static int r8192_wx_get_power(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = rtllib_priv(dev); + return rtllib_wx_get_power(priv->rtllib, info, wrqu, extra); +} + +static int r8192_wx_set_rawtx(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = rtllib_priv(dev); + int ret; + + if (priv->bHwRadioOff == true) + return 0; + + down(&priv->wx_sem); + + ret = rtllib_wx_set_rawtx(priv->rtllib, info, wrqu, extra); + + up(&priv->wx_sem); + + return ret; + +} + +static int r8192_wx_force_reset(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + down(&priv->wx_sem); + + RT_TRACE(COMP_DBG, "%s(): force reset ! extra is %d\n", + __func__, *extra); + priv->force_reset = *extra; + up(&priv->wx_sem); + return 0; + +} + +static int r8192_wx_force_mic_error(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = rtllib_priv(dev); + struct rtllib_device *ieee = priv->rtllib; + + down(&priv->wx_sem); + + RT_TRACE(COMP_DBG, "%s(): force mic error !\n", __func__); + ieee->force_mic_error = true; + up(&priv->wx_sem); + return 0; + +} + +#define MAX_ADHOC_PEER_NUM 64 +struct adhoc_peer_entry { + unsigned char MacAddr[ETH_ALEN]; + unsigned char WirelessMode; + unsigned char bCurTxBW40MHz; +}; +struct adhoc_peers_info { + struct adhoc_peer_entry Entry[MAX_ADHOC_PEER_NUM]; + unsigned char num; +}; + +static int r8192_wx_get_adhoc_peers(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + return 0; +} + + +static int r8191se_wx_get_firm_version(struct net_device *dev, + struct iw_request_info *info, + struct iw_param *wrqu, char *extra) +{ + return 0; +} + +static int r8192_wx_adapter_power_status(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = rtllib_priv(dev); + struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) + (&(priv->rtllib->PowerSaveControl)); + struct rtllib_device *ieee = priv->rtllib; + + down(&priv->wx_sem); + + RT_TRACE(COMP_POWER, "%s(): %s\n", __func__, (*extra == 6) ? + "DC power" : "AC power"); + if (*extra || priv->force_lps) { + priv->ps_force = false; + pPSC->bLeisurePs = true; + } else { + if (priv->rtllib->state == RTLLIB_LINKED) + LeisurePSLeave(dev); + + priv->ps_force = true; + pPSC->bLeisurePs = false; + ieee->ps = *extra; + } + + up(&priv->wx_sem); + + return 0; +} + +static int r8192se_wx_set_radio(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + down(&priv->wx_sem); + + printk(KERN_INFO "%s(): set radio ! extra is %d\n", __func__, *extra); + if ((*extra != 0) && (*extra != 1)) { + RT_TRACE(COMP_ERR, "%s(): set radio an err value,must 0(radio " + "off) or 1(radio on)\n", __func__); + return -1; + } + priv->sw_radio_on = *extra; + up(&priv->wx_sem); + return 0; + +} + +static int r8192se_wx_set_lps_awake_interval(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = rtllib_priv(dev); + struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) + (&(priv->rtllib->PowerSaveControl)); + + down(&priv->wx_sem); + + printk(KERN_INFO "%s(): set lps awake interval ! extra is %d\n", + __func__, *extra); + + pPSC->RegMaxLPSAwakeIntvl = *extra; + up(&priv->wx_sem); + return 0; +} + +static int r8192se_wx_set_force_lps(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + down(&priv->wx_sem); + + printk(KERN_INFO "%s(): force LPS ! extra is %d (1 is open 0 is " + "close)\n", __func__, *extra); + priv->force_lps = *extra; + up(&priv->wx_sem); + return 0; + +} + +static int r8192_wx_set_debugflag(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = rtllib_priv(dev); + u8 c = *extra; + + if (priv->bHwRadioOff == true) + return 0; + + printk(KERN_INFO "=====>%s(), *extra:%x, debugflag:%x\n", __func__, + *extra, rt_global_debug_component); + if (c > 0) + rt_global_debug_component |= (1<<c); + else + rt_global_debug_component &= BIT31; + return 0; +} + +static int r8192_wx_set_mode(struct net_device *dev, struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + struct r8192_priv *priv = rtllib_priv(dev); + struct rtllib_device *ieee = netdev_priv_rsl(dev); + + enum rt_rf_power_state rtState; + int ret; + + if (priv->bHwRadioOff == true) + return 0; + rtState = priv->rtllib->eRFPowerState; + down(&priv->wx_sem); + if (wrqu->mode == IW_MODE_ADHOC || wrqu->mode == IW_MODE_MONITOR || + ieee->bNetPromiscuousMode) { + if (priv->rtllib->PowerSaveControl.bInactivePs) { + if (rtState == eRfOff) { + if (priv->rtllib->RfOffReason > + RF_CHANGE_BY_IPS) { + RT_TRACE(COMP_ERR, "%s(): RF is OFF.\n", + __func__); + up(&priv->wx_sem); + return -1; + } else { + printk(KERN_INFO "=========>%s(): " + "IPSLeave\n", __func__); + down(&priv->rtllib->ips_sem); + IPSLeave(dev); + up(&priv->rtllib->ips_sem); + } + } + } + } + ret = rtllib_wx_set_mode(priv->rtllib, a, wrqu, b); + + up(&priv->wx_sem); + return ret; +} + +struct iw_range_with_scan_capa { + /* Informative stuff (to choose between different interface) */ + __u32 throughput; /* To give an idea... */ + /* In theory this value should be the maximum benchmarked + * TCP/IP throughput, because with most of these devices the + * bit rate is meaningless (overhead an co) to estimate how + * fast the connection will go and pick the fastest one. + * I suggest people to play with Netperf or any benchmark... + */ + + /* NWID (or domain id) */ + __u32 min_nwid; /* Minimal NWID we are able to set */ + __u32 max_nwid; /* Maximal NWID we are able to set */ + + /* Old Frequency (backward compat - moved lower ) */ + __u16 old_num_channels; + __u8 old_num_frequency; + + /* Scan capabilities */ + __u8 scan_capa; +}; + +static int rtl8192_wx_get_range(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct iw_range *range = (struct iw_range *)extra; + struct r8192_priv *priv = rtllib_priv(dev); + u16 val; + int i; + + wrqu->data.length = sizeof(*range); + memset(range, 0, sizeof(*range)); + + /* ~130 Mb/s real (802.11n) */ + range->throughput = 130 * 1000 * 1000; + + if (priv->rf_set_sens != NULL) { + /* signal level threshold range */ + range->sensitivity = priv->max_sens; + } + + range->max_qual.qual = 100; + range->max_qual.level = 0; + range->max_qual.noise = 0; + range->max_qual.updated = 7; /* Updated all three */ + + range->avg_qual.qual = 70; /* > 8% missed beacons is 'bad' */ + range->avg_qual.level = 0; + range->avg_qual.noise = 0; + range->avg_qual.updated = 7; /* Updated all three */ + + range->num_bitrates = min(RATE_COUNT, IW_MAX_BITRATES); + + for (i = 0; i < range->num_bitrates; i++) + range->bitrate[i] = rtl8192_rates[i]; + + range->max_rts = DEFAULT_RTS_THRESHOLD; + range->min_frag = MIN_FRAG_THRESHOLD; + range->max_frag = MAX_FRAG_THRESHOLD; + + range->min_pmp = 0; + range->max_pmp = 5000000; + range->min_pmt = 0; + range->max_pmt = 65535*1000; + range->pmp_flags = IW_POWER_PERIOD; + range->pmt_flags = IW_POWER_TIMEOUT; + range->pm_capa = IW_POWER_PERIOD | IW_POWER_TIMEOUT | IW_POWER_ALL_R; + range->we_version_compiled = WIRELESS_EXT; + range->we_version_source = 18; + + for (i = 0, val = 0; i < 14; i++) { + if ((priv->rtllib->active_channel_map)[i+1]) { + range->freq[val].i = i + 1; + range->freq[val].m = rtllib_wlan_frequencies[i] * + 100000; + range->freq[val].e = 1; + val++; + } + + if (val == IW_MAX_FREQUENCIES) + break; + } + range->num_frequency = val; + range->num_channels = val; + range->enc_capa = IW_ENC_CAPA_WPA|IW_ENC_CAPA_WPA2| + IW_ENC_CAPA_CIPHER_TKIP|IW_ENC_CAPA_CIPHER_CCMP; + range->scan_capa = IW_SCAN_CAPA_ESSID | IW_SCAN_CAPA_TYPE; + + /* Event capability (kernel + driver) */ + + return 0; +} + +static int r8192_wx_set_scan(struct net_device *dev, struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + struct r8192_priv *priv = rtllib_priv(dev); + struct rtllib_device *ieee = priv->rtllib; + enum rt_rf_power_state rtState; + int ret; + + if (!(ieee->softmac_features & IEEE_SOFTMAC_SCAN)) { + if ((ieee->state >= RTLLIB_ASSOCIATING) && + (ieee->state <= RTLLIB_ASSOCIATING_AUTHENTICATED)) + return 0; + if ((priv->rtllib->state == RTLLIB_LINKED) && + (priv->rtllib->CntAfterLink < 2)) + return 0; + } + + if (priv->bHwRadioOff == true) { + printk(KERN_INFO "================>%s(): hwradio off\n", + __func__); + return 0; + } + rtState = priv->rtllib->eRFPowerState; + if (!priv->up) + return -ENETDOWN; + if (priv->rtllib->LinkDetectInfo.bBusyTraffic == true) + return -EAGAIN; + + if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { + struct iw_scan_req *req = (struct iw_scan_req *)b; + if (req->essid_len) { + ieee->current_network.ssid_len = req->essid_len; + memcpy(ieee->current_network.ssid, req->essid, + req->essid_len); + } + } + + down(&priv->wx_sem); + + priv->rtllib->FirstIe_InScan = true; + + if (priv->rtllib->state != RTLLIB_LINKED) { + if (priv->rtllib->PowerSaveControl.bInactivePs) { + if (rtState == eRfOff) { + if (priv->rtllib->RfOffReason > + RF_CHANGE_BY_IPS) { + RT_TRACE(COMP_ERR, "%s(): RF is " + "OFF.\n", __func__); + up(&priv->wx_sem); + return -1; + } else { + RT_TRACE(COMP_PS, "=========>%s(): " + "IPSLeave\n", __func__); + down(&priv->rtllib->ips_sem); + IPSLeave(dev); + up(&priv->rtllib->ips_sem); + } + } + } + rtllib_stop_scan(priv->rtllib); + if (priv->rtllib->LedControlHandler) + priv->rtllib->LedControlHandler(dev, + LED_CTL_SITE_SURVEY); + + if (priv->rtllib->eRFPowerState != eRfOff) { + priv->rtllib->actscanning = true; + + if (ieee->ScanOperationBackupHandler) + ieee->ScanOperationBackupHandler(ieee->dev, + SCAN_OPT_BACKUP); + + rtllib_start_scan_syncro(priv->rtllib, 0); + + if (ieee->ScanOperationBackupHandler) + ieee->ScanOperationBackupHandler(ieee->dev, + SCAN_OPT_RESTORE); + } + ret = 0; + } else { + priv->rtllib->actscanning = true; + ret = rtllib_wx_set_scan(priv->rtllib, a, wrqu, b); + } + + up(&priv->wx_sem); + return ret; +} + + +static int r8192_wx_get_scan(struct net_device *dev, struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + + int ret; + struct r8192_priv *priv = rtllib_priv(dev); + + if (!priv->up) + return -ENETDOWN; + + if (priv->bHwRadioOff == true) + return 0; + + + down(&priv->wx_sem); + + ret = rtllib_wx_get_scan(priv->rtllib, a, wrqu, b); + + up(&priv->wx_sem); + + return ret; +} + +static int r8192_wx_set_essid(struct net_device *dev, + struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + struct r8192_priv *priv = rtllib_priv(dev); + int ret; + + if ((rtllib_act_scanning(priv->rtllib, false)) && + !(priv->rtllib->softmac_features & IEEE_SOFTMAC_SCAN)) { + ; /* TODO - get rid of if */ + } + if (priv->bHwRadioOff == true) { + printk(KERN_INFO "=========>%s():hw radio off,or Rf state is " + "eRfOff, return\n", __func__); + return 0; + } + down(&priv->wx_sem); + ret = rtllib_wx_set_essid(priv->rtllib, a, wrqu, b); + + up(&priv->wx_sem); + + return ret; +} + +static int r8192_wx_get_essid(struct net_device *dev, + struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + int ret; + struct r8192_priv *priv = rtllib_priv(dev); + + down(&priv->wx_sem); + + ret = rtllib_wx_get_essid(priv->rtllib, a, wrqu, b); + + up(&priv->wx_sem); + + return ret; +} + +static int r8192_wx_set_nick(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + if (wrqu->data.length > IW_ESSID_MAX_SIZE) + return -E2BIG; + down(&priv->wx_sem); + wrqu->data.length = min((size_t) wrqu->data.length, sizeof(priv->nick)); + memset(priv->nick, 0, sizeof(priv->nick)); + memcpy(priv->nick, extra, wrqu->data.length); + up(&priv->wx_sem); + return 0; + +} + +static int r8192_wx_get_nick(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + down(&priv->wx_sem); + wrqu->data.length = strlen(priv->nick); + memcpy(extra, priv->nick, wrqu->data.length); + wrqu->data.flags = 1; /* active */ + up(&priv->wx_sem); + return 0; +} + +static int r8192_wx_set_freq(struct net_device *dev, struct iw_request_info *a, + union iwreq_data *wrqu, char *b) +{ + int ret; + struct r8192_priv *priv = rtllib_priv(dev); + + if (priv->bHwRadioOff == true) + return 0; + + down(&priv->wx_sem); + + ret = rtllib_wx_set_freq(priv->rtllib, a, wrqu, b); + + up(&priv->wx_sem); + return ret; +} + +static int r8192_wx_get_name(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = rtllib_priv(dev); + return rtllib_wx_get_name(priv->rtllib, info, wrqu, extra); +} + + +static int r8192_wx_set_frag(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + if (priv->bHwRadioOff == true) + return 0; + + if (wrqu->frag.disabled) + priv->rtllib->fts = DEFAULT_FRAG_THRESHOLD; + else { + if (wrqu->frag.value < MIN_FRAG_THRESHOLD || + wrqu->frag.value > MAX_FRAG_THRESHOLD) + return -EINVAL; + + priv->rtllib->fts = wrqu->frag.value & ~0x1; + } + + return 0; +} + + +static int r8192_wx_get_frag(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + wrqu->frag.value = priv->rtllib->fts; + wrqu->frag.fixed = 0; /* no auto select */ + wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD); + + return 0; +} + + +static int r8192_wx_set_wap(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *awrq, + char *extra) +{ + int ret; + struct r8192_priv *priv = rtllib_priv(dev); + + if ((rtllib_act_scanning(priv->rtllib, false)) && + !(priv->rtllib->softmac_features & IEEE_SOFTMAC_SCAN)) { + ; /* TODO - get rid of if */ + } + + if (priv->bHwRadioOff == true) + return 0; + + down(&priv->wx_sem); + + ret = rtllib_wx_set_wap(priv->rtllib, info, awrq, extra); + + up(&priv->wx_sem); + + return ret; + +} + + +static int r8192_wx_get_wap(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + return rtllib_wx_get_wap(priv->rtllib, info, wrqu, extra); +} + + +static int r8192_wx_get_enc(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *key) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + return rtllib_wx_get_encode(priv->rtllib, info, wrqu, key); +} + +static int r8192_wx_set_enc(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *key) +{ + struct r8192_priv *priv = rtllib_priv(dev); + int ret; + + struct rtllib_device *ieee = priv->rtllib; + u32 hwkey[4] = {0, 0, 0, 0}; + u8 mask = 0xff; + u32 key_idx = 0; + u8 zero_addr[4][6] = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} }; + int i; + + if ((rtllib_act_scanning(priv->rtllib, false)) && + !(priv->rtllib->softmac_features & IEEE_SOFTMAC_SCAN)) + ; /* TODO - get rid of if */ + if (priv->bHwRadioOff == true) + return 0; + + if (!priv->up) + return -ENETDOWN; + + priv->rtllib->wx_set_enc = 1; + down(&priv->rtllib->ips_sem); + IPSLeave(dev); + up(&priv->rtllib->ips_sem); + down(&priv->wx_sem); + + RT_TRACE(COMP_SEC, "Setting SW wep key"); + ret = rtllib_wx_set_encode(priv->rtllib, info, wrqu, key); + up(&priv->wx_sem); + + + if (wrqu->encoding.flags & IW_ENCODE_DISABLED) { + ieee->pairwise_key_type = ieee->group_key_type = KEY_TYPE_NA; + CamResetAllEntry(dev); + memset(priv->rtllib->swcamtable, 0, + sizeof(struct sw_cam_table) * 32); + goto end_hw_sec; + } + if (wrqu->encoding.length != 0) { + + for (i = 0; i < 4; i++) { + hwkey[i] |= key[4*i+0]&mask; + if (i == 1 && (4 * i + 1) == wrqu->encoding.length) + mask = 0x00; + if (i == 3 && (4 * i + 1) == wrqu->encoding.length) + mask = 0x00; + hwkey[i] |= (key[4 * i + 1] & mask) << 8; + hwkey[i] |= (key[4 * i + 2] & mask) << 16; + hwkey[i] |= (key[4 * i + 3] & mask) << 24; + } + + #define CONF_WEP40 0x4 + #define CONF_WEP104 0x14 + + switch (wrqu->encoding.flags & IW_ENCODE_INDEX) { + case 0: + key_idx = ieee->tx_keyidx; + break; + case 1: + key_idx = 0; + break; + case 2: + key_idx = 1; + break; + case 3: + key_idx = 2; + break; + case 4: + key_idx = 3; + break; + default: + break; + } + if (wrqu->encoding.length == 0x5) { + ieee->pairwise_key_type = KEY_TYPE_WEP40; + EnableHWSecurityConfig8192(dev); + } + + else if (wrqu->encoding.length == 0xd) { + ieee->pairwise_key_type = KEY_TYPE_WEP104; + EnableHWSecurityConfig8192(dev); + setKey(dev, key_idx, key_idx, KEY_TYPE_WEP104, + zero_addr[key_idx], 0, hwkey); + set_swcam(dev, key_idx, key_idx, KEY_TYPE_WEP104, + zero_addr[key_idx], 0, hwkey, 0); + } else { + printk(KERN_INFO "wrong type in WEP, not WEP40 and WEP104\n"); + } + } + +end_hw_sec: + priv->rtllib->wx_set_enc = 0; + return ret; +} + +static int r8192_wx_set_scan_type(struct net_device *dev, + struct iw_request_info *aa, + union iwreq_data *wrqu, char *p) +{ + struct r8192_priv *priv = rtllib_priv(dev); + int *parms = (int *)p; + int mode = parms[0]; + + if (priv->bHwRadioOff == true) + return 0; + + priv->rtllib->active_scan = mode; + + return 1; +} + + + +#define R8192_MAX_RETRY 255 +static int r8192_wx_set_retry(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = rtllib_priv(dev); + int err = 0; + + if (priv->bHwRadioOff == true) + return 0; + + down(&priv->wx_sem); + + if (wrqu->retry.flags & IW_RETRY_LIFETIME || + wrqu->retry.disabled) { + err = -EINVAL; + goto exit; + } + if (!(wrqu->retry.flags & IW_RETRY_LIMIT)) { + err = -EINVAL; + goto exit; + } + + if (wrqu->retry.value > R8192_MAX_RETRY) { + err = -EINVAL; + goto exit; + } + if (wrqu->retry.flags & IW_RETRY_MAX) { + priv->retry_rts = wrqu->retry.value; + DMESG("Setting retry for RTS/CTS data to %d", + wrqu->retry.value); + + } else { + priv->retry_data = wrqu->retry.value; + DMESG("Setting retry for non RTS/CTS data to %d", + wrqu->retry.value); + } + + + rtl8192_commit(dev); +exit: + up(&priv->wx_sem); + + return err; +} + +static int r8192_wx_get_retry(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = rtllib_priv(dev); + + + wrqu->retry.disabled = 0; /* can't be disabled */ + + if ((wrqu->retry.flags & IW_RETRY_TYPE) == + IW_RETRY_LIFETIME) + return -EINVAL; + + if (wrqu->retry.flags & IW_RETRY_MAX) { + wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MAX; + wrqu->retry.value = priv->retry_rts; + } else { + wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MIN; + wrqu->retry.value = priv->retry_data; + } + return 0; +} + +static int r8192_wx_get_sens(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = rtllib_priv(dev); + if (priv->rf_set_sens == NULL) + return -1; /* we have not this support for this radio */ + wrqu->sens.value = priv->sens; + return 0; +} + + +static int r8192_wx_set_sens(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + struct r8192_priv *priv = rtllib_priv(dev); + + short err = 0; + + if (priv->bHwRadioOff == true) + return 0; + + down(&priv->wx_sem); + if (priv->rf_set_sens == NULL) { + err = -1; /* we have not this support for this radio */ + goto exit; + } + if (priv->rf_set_sens(dev, wrqu->sens.value) == 0) + priv->sens = wrqu->sens.value; + else + err = -EINVAL; + +exit: + up(&priv->wx_sem); + + return err; +} + +static int r8192_wx_set_enc_ext(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + struct r8192_priv *priv = rtllib_priv(dev); + struct rtllib_device *ieee = priv->rtllib; + + if (priv->bHwRadioOff == true) + return 0; + + down(&priv->wx_sem); + + priv->rtllib->wx_set_enc = 1; + down(&priv->rtllib->ips_sem); + IPSLeave(dev); + up(&priv->rtllib->ips_sem); + + ret = rtllib_wx_set_encode_ext(ieee, info, wrqu, extra); + { + u8 broadcast_addr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + u8 zero[6] = {0}; + u32 key[4] = {0}; + struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; + struct iw_point *encoding = &wrqu->encoding; + u8 idx = 0, alg = 0, group = 0; + if ((encoding->flags & IW_ENCODE_DISABLED) || + ext->alg == IW_ENCODE_ALG_NONE) { + ieee->pairwise_key_type = ieee->group_key_type + = KEY_TYPE_NA; + CamResetAllEntry(dev); + memset(priv->rtllib->swcamtable, 0, + sizeof(struct sw_cam_table) * 32); + goto end_hw_sec; + } + alg = (ext->alg == IW_ENCODE_ALG_CCMP) ? KEY_TYPE_CCMP : + ext->alg; + idx = encoding->flags & IW_ENCODE_INDEX; + if (idx) + idx--; + group = ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY; + + if ((!group) || (IW_MODE_ADHOC == ieee->iw_mode) || + (alg == KEY_TYPE_WEP40)) { + if ((ext->key_len == 13) && (alg == KEY_TYPE_WEP40)) + alg = KEY_TYPE_WEP104; + ieee->pairwise_key_type = alg; + EnableHWSecurityConfig8192(dev); + } + memcpy((u8 *)key, ext->key, 16); + + if ((alg & KEY_TYPE_WEP40) && (ieee->auth_mode != 2)) { + if (ext->key_len == 13) + ieee->pairwise_key_type = alg = KEY_TYPE_WEP104; + setKey(dev, idx, idx, alg, zero, 0, key); + set_swcam(dev, idx, idx, alg, zero, 0, key, 0); + } else if (group) { + ieee->group_key_type = alg; + setKey(dev, idx, idx, alg, broadcast_addr, 0, key); + set_swcam(dev, idx, idx, alg, broadcast_addr, 0, + key, 0); + } else { + if ((ieee->pairwise_key_type == KEY_TYPE_CCMP) && + ieee->pHTInfo->bCurrentHTSupport) + write_nic_byte(dev, 0x173, 1); + setKey(dev, 4, idx, alg, (u8 *)ieee->ap_mac_addr, + 0, key); + set_swcam(dev, 4, idx, alg, (u8 *)ieee->ap_mac_addr, + 0, key, 0); + } + + + } + +end_hw_sec: + priv->rtllib->wx_set_enc = 0; + up(&priv->wx_sem); + return ret; + +} +static int r8192_wx_set_auth(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *data, char *extra) +{ + int ret = 0; + + struct r8192_priv *priv = rtllib_priv(dev); + + if (priv->bHwRadioOff == true) + return 0; + + down(&priv->wx_sem); + ret = rtllib_wx_set_auth(priv->rtllib, info, &(data->param), extra); + up(&priv->wx_sem); + return ret; +} + +static int r8192_wx_set_mlme(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + + int ret = 0; + + struct r8192_priv *priv = rtllib_priv(dev); + + if (priv->bHwRadioOff == true) + return 0; + + down(&priv->wx_sem); + ret = rtllib_wx_set_mlme(priv->rtllib, info, wrqu, extra); + up(&priv->wx_sem); + return ret; +} + +static int r8192_wx_set_gen_ie(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *data, char *extra) +{ + int ret = 0; + + struct r8192_priv *priv = rtllib_priv(dev); + + if (priv->bHwRadioOff == true) + return 0; + + down(&priv->wx_sem); + ret = rtllib_wx_set_gen_ie(priv->rtllib, extra, data->data.length); + up(&priv->wx_sem); + return ret; +} + +static int r8192_wx_get_gen_ie(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *data, char *extra) +{ + int ret = 0; + struct r8192_priv *priv = rtllib_priv(dev); + struct rtllib_device *ieee = priv->rtllib; + + if (ieee->wpa_ie_len == 0 || ieee->wpa_ie == NULL) { + data->data.length = 0; + return 0; + } + + if (data->data.length < ieee->wpa_ie_len) + return -E2BIG; + + data->data.length = ieee->wpa_ie_len; + memcpy(extra, ieee->wpa_ie, ieee->wpa_ie_len); + return ret; +} + +#define OID_RT_INTEL_PROMISCUOUS_MODE 0xFF0101F6 + +static int r8192_wx_set_PromiscuousMode(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = rtllib_priv(dev); + struct rtllib_device *ieee = priv->rtllib; + + u32 *info_buf = (u32 *)(wrqu->data.pointer); + + u32 oid = info_buf[0]; + u32 bPromiscuousOn = info_buf[1]; + u32 bFilterSourceStationFrame = info_buf[2]; + + if (OID_RT_INTEL_PROMISCUOUS_MODE == oid) { + ieee->IntelPromiscuousModeInfo.bPromiscuousOn = + (bPromiscuousOn) ? (true) : (false); + ieee->IntelPromiscuousModeInfo.bFilterSourceStationFrame = + (bFilterSourceStationFrame) ? (true) : (false); + (bPromiscuousOn) ? + (rtllib_EnableIntelPromiscuousMode(dev, false)) : + (rtllib_DisableIntelPromiscuousMode(dev, false)); + + printk(KERN_INFO "=======>%s(), on = %d, filter src sta = %d\n", + __func__, bPromiscuousOn, bFilterSourceStationFrame); + } else { + return -1; + } + + return 0; +} + + +static int r8192_wx_get_PromiscuousMode(struct net_device *dev, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct r8192_priv *priv = rtllib_priv(dev); + struct rtllib_device *ieee = priv->rtllib; + + down(&priv->wx_sem); + + snprintf(extra, 45, "PromiscuousMode:%d, FilterSrcSTAFrame:%d", + ieee->IntelPromiscuousModeInfo.bPromiscuousOn, + ieee->IntelPromiscuousModeInfo.bFilterSourceStationFrame); + wrqu->data.length = strlen(extra) + 1; + + up(&priv->wx_sem); + + return 0; +} + + +#define IW_IOCTL(x) [(x)-SIOCSIWCOMMIT] +static iw_handler r8192_wx_handlers[] = { + IW_IOCTL(SIOCGIWNAME) = r8192_wx_get_name, + IW_IOCTL(SIOCSIWFREQ) = r8192_wx_set_freq, + IW_IOCTL(SIOCGIWFREQ) = r8192_wx_get_freq, + IW_IOCTL(SIOCSIWMODE) = r8192_wx_set_mode, + IW_IOCTL(SIOCGIWMODE) = r8192_wx_get_mode, + IW_IOCTL(SIOCSIWSENS) = r8192_wx_set_sens, + IW_IOCTL(SIOCGIWSENS) = r8192_wx_get_sens, + IW_IOCTL(SIOCGIWRANGE) = rtl8192_wx_get_range, + IW_IOCTL(SIOCSIWAP) = r8192_wx_set_wap, + IW_IOCTL(SIOCGIWAP) = r8192_wx_get_wap, + IW_IOCTL(SIOCSIWSCAN) = r8192_wx_set_scan, + IW_IOCTL(SIOCGIWSCAN) = r8192_wx_get_scan, + IW_IOCTL(SIOCSIWESSID) = r8192_wx_set_essid, + IW_IOCTL(SIOCGIWESSID) = r8192_wx_get_essid, + IW_IOCTL(SIOCSIWNICKN) = r8192_wx_set_nick, + IW_IOCTL(SIOCGIWNICKN) = r8192_wx_get_nick, + IW_IOCTL(SIOCSIWRATE) = r8192_wx_set_rate, + IW_IOCTL(SIOCGIWRATE) = r8192_wx_get_rate, + IW_IOCTL(SIOCSIWRTS) = r8192_wx_set_rts, + IW_IOCTL(SIOCGIWRTS) = r8192_wx_get_rts, + IW_IOCTL(SIOCSIWFRAG) = r8192_wx_set_frag, + IW_IOCTL(SIOCGIWFRAG) = r8192_wx_get_frag, + IW_IOCTL(SIOCSIWRETRY) = r8192_wx_set_retry, + IW_IOCTL(SIOCGIWRETRY) = r8192_wx_get_retry, + IW_IOCTL(SIOCSIWENCODE) = r8192_wx_set_enc, + IW_IOCTL(SIOCGIWENCODE) = r8192_wx_get_enc, + IW_IOCTL(SIOCSIWPOWER) = r8192_wx_set_power, + IW_IOCTL(SIOCGIWPOWER) = r8192_wx_get_power, + IW_IOCTL(SIOCSIWGENIE) = r8192_wx_set_gen_ie, + IW_IOCTL(SIOCGIWGENIE) = r8192_wx_get_gen_ie, + IW_IOCTL(SIOCSIWMLME) = r8192_wx_set_mlme, + IW_IOCTL(SIOCSIWAUTH) = r8192_wx_set_auth, + IW_IOCTL(SIOCSIWENCODEEXT) = r8192_wx_set_enc_ext, +}; + +/* + * the following rule need to be follwing, + * Odd : get (world access), + * even : set (root access) + * */ +static const struct iw_priv_args r8192_private_args[] = { + { + SIOCIWFIRSTPRIV + 0x0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_debugflag" + }, { + SIOCIWFIRSTPRIV + 0x1, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan" + }, { + SIOCIWFIRSTPRIV + 0x2, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx" + }, { + SIOCIWFIRSTPRIV + 0x3, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "forcereset" + }, { + SIOCIWFIRSTPRIV + 0x4, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "force_mic_error" + }, { + SIOCIWFIRSTPRIV + 0x5, + IW_PRIV_TYPE_NONE, IW_PRIV_TYPE_INT|IW_PRIV_SIZE_FIXED|1, + "firm_ver" + }, { + SIOCIWFIRSTPRIV + 0x6, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED|1, IW_PRIV_TYPE_NONE, + "set_power" + }, { + SIOCIWFIRSTPRIV + 0x9, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED|1, IW_PRIV_TYPE_NONE, + "radio" + }, { + SIOCIWFIRSTPRIV + 0xa, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED|1, IW_PRIV_TYPE_NONE, + "lps_interv" + }, { + SIOCIWFIRSTPRIV + 0xb, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED|1, IW_PRIV_TYPE_NONE, + "lps_force" + }, { + SIOCIWFIRSTPRIV + 0xc, + 0, IW_PRIV_TYPE_CHAR|2047, "adhoc_peer_list" + }, { + SIOCIWFIRSTPRIV + 0x16, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 3, 0, "setpromisc" + }, { + SIOCIWFIRSTPRIV + 0x17, + 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 45, "getpromisc" + } + +}; + +static iw_handler r8192_private_handler[] = { + (iw_handler)r8192_wx_set_debugflag, /*SIOCIWSECONDPRIV*/ + (iw_handler)r8192_wx_set_scan_type, + (iw_handler)r8192_wx_set_rawtx, + (iw_handler)r8192_wx_force_reset, + (iw_handler)r8192_wx_force_mic_error, + (iw_handler)r8191se_wx_get_firm_version, + (iw_handler)r8192_wx_adapter_power_status, + (iw_handler)NULL, + (iw_handler)NULL, + (iw_handler)r8192se_wx_set_radio, + (iw_handler)r8192se_wx_set_lps_awake_interval, + (iw_handler)r8192se_wx_set_force_lps, + (iw_handler)r8192_wx_get_adhoc_peers, + (iw_handler)NULL, + (iw_handler)NULL, + (iw_handler)NULL, + (iw_handler)NULL, + (iw_handler)NULL, + (iw_handler)NULL, + (iw_handler)NULL, + (iw_handler)NULL, + (iw_handler)NULL, + (iw_handler)r8192_wx_set_PromiscuousMode, + (iw_handler)r8192_wx_get_PromiscuousMode, +}; + +static struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev) +{ + struct r8192_priv *priv = rtllib_priv(dev); + struct rtllib_device *ieee = priv->rtllib; + struct iw_statistics *wstats = &priv->wstats; + int tmp_level = 0; + int tmp_qual = 0; + int tmp_noise = 0; + if (ieee->state < RTLLIB_LINKED) { + wstats->qual.qual = 10; + wstats->qual.level = 0; + wstats->qual.noise = -100; + wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; + return wstats; + } + + tmp_level = (&ieee->current_network)->stats.rssi; + tmp_qual = (&ieee->current_network)->stats.signal; + tmp_noise = (&ieee->current_network)->stats.noise; + + wstats->qual.level = tmp_level; + wstats->qual.qual = tmp_qual; + wstats->qual.noise = tmp_noise; + wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; + return wstats; +} + +struct iw_handler_def r8192_wx_handlers_def = { + .standard = r8192_wx_handlers, + .num_standard = sizeof(r8192_wx_handlers) / sizeof(iw_handler), + .private = r8192_private_handler, + .num_private = sizeof(r8192_private_handler) / sizeof(iw_handler), + .num_private_args = sizeof(r8192_private_args) / + sizeof(struct iw_priv_args), + .get_wireless_stats = r8192_get_wireless_stats, + .private_args = (struct iw_priv_args *)r8192_private_args, +}; diff --git a/drivers/staging/rtl8192e/rtl_wx.h b/drivers/staging/rtl8192e/rtl_wx.h new file mode 100644 index 0000000..6a51a25 --- /dev/null +++ b/drivers/staging/rtl8192e/rtl_wx.h @@ -0,0 +1,31 @@ +/****************************************************************************** + * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * The full GNU General Public License is included in this distribution in the + * file called LICENSE. + * + * Contact Information: + * wlanfae <wlanfae@realtek.com> +******************************************************************************/ + +#ifndef R819x_WX_H +#define R819x_WX_H + +struct net_device; +struct iw_handler_def; +struct iw_statistics; + +extern struct iw_handler_def r8192_wx_handlers_def; +struct iw_statistics *r8192_get_wireless_stats(struct net_device *dev); +u16 rtl8192_11n_user_show_rates(struct net_device *dev); + +#endif diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h new file mode 100644 index 0000000..b33cacc --- /dev/null +++ b/drivers/staging/rtl8192e/rtllib.h @@ -0,0 +1,3112 @@ +/* + * Merged with mainline rtllib.h in Aug 2004. Original ieee802_11 + * remains copyright by the original authors + * + * Portions of the merged code are based on Host AP (software wireless + * LAN access point) driver for Intersil Prism2/2.5/3. + * + * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen + * <jkmaline@cc.hut.fi> + * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi> + * + * Adaption to a generic IEEE 802.11 stack by James Ketrenos + * <jketreno@linux.intel.com> + * Copyright (c) 2004, Intel Corporation + * + * Modified for Realtek's wi-fi cards by Andrea Merello + * <andreamrl@tiscali.it> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. See README and COPYING for + * more details. + */ +#ifndef RTLLIB_H +#define RTLLIB_H +#include <linux/if_ether.h> /* ETH_ALEN */ +#include <linux/kernel.h> /* ARRAY_SIZE */ +#include <linux/version.h> +#include <linux/module.h> +#include <linux/interrupt.h> +#include <linux/jiffies.h> +#include <linux/timer.h> +#include <linux/sched.h> + +#include <linux/delay.h> +#include <linux/wireless.h> + +#include "rtl819x_HT.h" +#include "rtl819x_BA.h" +#include "rtl819x_TS.h" + +#include <linux/netdevice.h> +#include <linux/if_arp.h> /* ARPHRD_ETHER */ + +#ifndef WIRELESS_SPY +#define WIRELESS_SPY +#endif +#include <net/iw_handler.h> + +#ifndef IW_MODE_MONITOR +#define IW_MODE_MONITOR 6 +#endif + +#ifndef IWEVCUSTOM +#define IWEVCUSTOM 0x8c02 +#endif + +#ifndef IW_CUSTOM_MAX +/* Max number of char in custom event - use multiple of them if needed */ +#define IW_CUSTOM_MAX 256 /* In bytes */ +#endif + +#ifndef container_of +/** + * container_of - cast a member of a structure out to the containing structure + * + * @ptr: the pointer to the member. + * @type: the type of the container struct this is embedded in. + * @member: the name of the member within the struct. + * + */ +#define container_of(ptr, type, member) ({ \ + const typeof(((type *)0)->member)*__mptr = (ptr); \ + (type *)((char *)__mptr - offsetof(type, member)); }) +#endif + +#define skb_tail_pointer_rsl(skb) skb_tail_pointer(skb) + +#define EXPORT_SYMBOL_RSL(x) EXPORT_SYMBOL(x) + + +#define queue_delayed_work_rsl(x, y, z) queue_delayed_work(x, y, z) +#define INIT_DELAYED_WORK_RSL(x, y, z) INIT_DELAYED_WORK(x, y) + +#define queue_work_rsl(x, y) queue_work(x, y) +#define INIT_WORK_RSL(x, y, z) INIT_WORK(x, y) + +#define container_of_work_rsl(x, y, z) container_of(x, y, z) +#define container_of_dwork_rsl(x, y, z) \ + container_of(container_of(x, struct delayed_work, work), y, z) + +#define iwe_stream_add_event_rsl(info, start, stop, iwe, len) \ + iwe_stream_add_event(info, start, stop, iwe, len) + +#define iwe_stream_add_point_rsl(info, start, stop, iwe, p) \ + iwe_stream_add_point(info, start, stop, iwe, p) + +#define usb_alloc_urb_rsl(x, y) usb_alloc_urb(x, y) +#define usb_submit_urb_rsl(x, y) usb_submit_urb(x, y) + +static inline void *netdev_priv_rsl(struct net_device *dev) +{ + return netdev_priv(dev); +} + +#define KEY_TYPE_NA 0x0 +#define KEY_TYPE_WEP40 0x1 +#define KEY_TYPE_TKIP 0x2 +#define KEY_TYPE_CCMP 0x4 +#define KEY_TYPE_WEP104 0x5 +/* added for rtl819x tx procedure */ +#define MAX_QUEUE_SIZE 0x10 + +#define BK_QUEUE 0 +#define BE_QUEUE 1 +#define VI_QUEUE 2 +#define VO_QUEUE 3 +#define HCCA_QUEUE 4 +#define TXCMD_QUEUE 5 +#define MGNT_QUEUE 6 +#define HIGH_QUEUE 7 +#define BEACON_QUEUE 8 + +#define LOW_QUEUE BE_QUEUE +#define NORMAL_QUEUE MGNT_QUEUE + +#ifndef IW_MODE_MESH +#define IW_MODE_MESH 7 +#endif +#define AMSDU_SUBHEADER_LEN 14 +#define SWRF_TIMEOUT 50 + +#define IE_CISCO_FLAG_POSITION 0x08 +#define SUPPORT_CKIP_MIC 0x08 +#define SUPPORT_CKIP_PK 0x10 +#define RT_RF_OFF_LEVL_ASPM BIT0 +#define RT_RF_OFF_LEVL_CLK_REQ BIT1 +#define RT_RF_OFF_LEVL_PCI_D3 BIT2 +#define RT_RF_OFF_LEVL_HALT_NIC BIT3 +#define RT_RF_OFF_LEVL_FREE_FW BIT4 +#define RT_RF_OFF_LEVL_FW_32K BIT5 +#define RT_RF_PS_LEVEL_ALWAYS_ASPM BIT6 +#define RT_RF_LPS_DISALBE_2R BIT30 +#define RT_RF_LPS_LEVEL_ASPM BIT31 +#define RT_IN_PS_LEVEL(pPSC, _PS_FLAG) \ + ((pPSC->CurPsLevel & _PS_FLAG) ? true : false) +#define RT_CLEAR_PS_LEVEL(pPSC, _PS_FLAG) \ + (pPSC->CurPsLevel &= (~(_PS_FLAG))) +#define RT_SET_PS_LEVEL(pPSC, _PS_FLAG) (pPSC->CurPsLevel |= _PS_FLAG) + +/* defined for skb cb field */ +/* At most 28 byte */ +struct cb_desc { + /* Tx Desc Related flags (8-9) */ + u8 bLastIniPkt:1; + u8 bCmdOrInit:1; + u8 bFirstSeg:1; + u8 bLastSeg:1; + u8 bEncrypt:1; + u8 bTxDisableRateFallBack:1; + u8 bTxUseDriverAssingedRate:1; + u8 bHwSec:1; + + u8 nStuckCount; + + /* Tx Firmware Relaged flags (10-11)*/ + u8 bCTSEnable:1; + u8 bRTSEnable:1; + u8 bUseShortGI:1; + u8 bUseShortPreamble:1; + u8 bTxEnableFwCalcDur:1; + u8 bAMPDUEnable:1; + u8 bRTSSTBC:1; + u8 RTSSC:1; + + u8 bRTSBW:1; + u8 bPacketBW:1; + u8 bRTSUseShortPreamble:1; + u8 bRTSUseShortGI:1; + u8 bMulticast:1; + u8 bBroadcast:1; + u8 drv_agg_enable:1; + u8 reserved2:1; + + /* Tx Desc related element(12-19) */ + u8 rata_index; + u8 queue_index; + u16 txbuf_size; + u8 RATRIndex; + u8 bAMSDU:1; + u8 bFromAggrQ:1; + u8 reserved6:6; + u8 macId; + u8 priority; + + /* Tx firmware related element(20-27) */ + u8 data_rate; + u8 rts_rate; + u8 ampdu_factor; + u8 ampdu_density; + u8 DrvAggrNum; + u8 bdhcp; + u16 pkt_size; + u8 bIsSpecialDataFrame; + + u8 bBTTxPacket; + u8 bIsBTProbRsp; +}; + +/*--------------------------Define -------------------------------------------*/ +#define MGN_1M 0x02 +#define MGN_2M 0x04 +#define MGN_5_5M 0x0b +#define MGN_11M 0x16 + +#define MGN_6M 0x0c +#define MGN_9M 0x12 +#define MGN_12M 0x18 +#define MGN_18M 0x24 +#define MGN_24M 0x30 +#define MGN_36M 0x48 +#define MGN_48M 0x60 +#define MGN_54M 0x6c + +#define MGN_MCS0 0x80 +#define MGN_MCS1 0x81 +#define MGN_MCS2 0x82 +#define MGN_MCS3 0x83 +#define MGN_MCS4 0x84 +#define MGN_MCS5 0x85 +#define MGN_MCS6 0x86 +#define MGN_MCS7 0x87 +#define MGN_MCS8 0x88 +#define MGN_MCS9 0x89 +#define MGN_MCS10 0x8a +#define MGN_MCS11 0x8b +#define MGN_MCS12 0x8c +#define MGN_MCS13 0x8d +#define MGN_MCS14 0x8e +#define MGN_MCS15 0x8f +#define MGN_MCS0_SG 0x90 +#define MGN_MCS1_SG 0x91 +#define MGN_MCS2_SG 0x92 +#define MGN_MCS3_SG 0x93 +#define MGN_MCS4_SG 0x94 +#define MGN_MCS5_SG 0x95 +#define MGN_MCS6_SG 0x96 +#define MGN_MCS7_SG 0x97 +#define MGN_MCS8_SG 0x98 +#define MGN_MCS9_SG 0x99 +#define MGN_MCS10_SG 0x9a +#define MGN_MCS11_SG 0x9b +#define MGN_MCS12_SG 0x9c +#define MGN_MCS13_SG 0x9d +#define MGN_MCS14_SG 0x9e +#define MGN_MCS15_SG 0x9f + + +enum _ReasonCode { + unspec_reason = 0x1, + auth_not_valid = 0x2, + deauth_lv_ss = 0x3, + inactivity = 0x4, + ap_overload = 0x5, + class2_err = 0x6, + class3_err = 0x7, + disas_lv_ss = 0x8, + asoc_not_auth = 0x9, + + mic_failure = 0xe, + + invalid_IE = 0x0d, + four_way_tmout = 0x0f, + two_way_tmout = 0x10, + IE_dismatch = 0x11, + invalid_Gcipher = 0x12, + invalid_Pcipher = 0x13, + invalid_AKMP = 0x14, + unsup_RSNIEver = 0x15, + invalid_RSNIE = 0x16, + auth_802_1x_fail = 0x17, + ciper_reject = 0x18, + + QoS_unspec = 0x20, + QAP_bandwidth = 0x21, + poor_condition = 0x22, + no_facility = 0x23, + req_declined = 0x25, + invalid_param = 0x26, + req_not_honored = 0x27, + TS_not_created = 0x2F, + DL_not_allowed = 0x30, + dest_not_exist = 0x31, + dest_not_QSTA = 0x32, +}; + +enum hal_def_variable { + HAL_DEF_TPC_ENABLE, + HAL_DEF_INIT_GAIN, + HAL_DEF_PROT_IMP_MODE, + HAL_DEF_HIGH_POWER_MECHANISM, + HAL_DEF_RATE_ADAPTIVE_MECHANISM, + HAL_DEF_ANTENNA_DIVERSITY_MECHANISM, + HAL_DEF_LED, + HAL_DEF_CW_MAX_MIN, + + HAL_DEF_WOWLAN, + HAL_DEF_ENDPOINTS, + HAL_DEF_MIN_TX_POWER_DBM, + HAL_DEF_MAX_TX_POWER_DBM, + HW_DEF_EFUSE_REPG_SECTION1_FLAG, + HW_DEF_EFUSE_REPG_DATA, + HW_DEF_GPIO, + HAL_DEF_PCI_SUPPORT_ASPM, + HAL_DEF_THERMAL_VALUE, + HAL_DEF_USB_IN_TOKEN_REV, +}; + +enum hw_variables { + HW_VAR_ETHER_ADDR, + HW_VAR_MULTICAST_REG, + HW_VAR_BASIC_RATE, + HW_VAR_BSSID, + HW_VAR_MEDIA_STATUS, + HW_VAR_SECURITY_CONF, + HW_VAR_BEACON_INTERVAL, + HW_VAR_ATIM_WINDOW, + HW_VAR_LISTEN_INTERVAL, + HW_VAR_CS_COUNTER, + HW_VAR_DEFAULTKEY0, + HW_VAR_DEFAULTKEY1, + HW_VAR_DEFAULTKEY2, + HW_VAR_DEFAULTKEY3, + HW_VAR_SIFS, + HW_VAR_DIFS, + HW_VAR_EIFS, + HW_VAR_SLOT_TIME, + HW_VAR_ACK_PREAMBLE, + HW_VAR_CW_CONFIG, + HW_VAR_CW_VALUES, + HW_VAR_RATE_FALLBACK_CONTROL, + HW_VAR_CONTENTION_WINDOW, + HW_VAR_RETRY_COUNT, + HW_VAR_TR_SWITCH, + HW_VAR_COMMAND, + HW_VAR_WPA_CONFIG, + HW_VAR_AMPDU_MIN_SPACE, + HW_VAR_SHORTGI_DENSITY, + HW_VAR_AMPDU_FACTOR, + HW_VAR_MCS_RATE_AVAILABLE, + HW_VAR_AC_PARAM, + HW_VAR_ACM_CTRL, + HW_VAR_DIS_Req_Qsize, + HW_VAR_CCX_CHNL_LOAD, + HW_VAR_CCX_NOISE_HISTOGRAM, + HW_VAR_CCX_CLM_NHM, + HW_VAR_TxOPLimit, + HW_VAR_TURBO_MODE, + HW_VAR_RF_STATE, + HW_VAR_RF_OFF_BY_HW, + HW_VAR_BUS_SPEED, + HW_VAR_SET_DEV_POWER, + + HW_VAR_RCR, + HW_VAR_RATR_0, + HW_VAR_RRSR, + HW_VAR_CPU_RST, + HW_VAR_CECHK_BSSID, + HW_VAR_LBK_MODE, + HW_VAR_AES_11N_FIX, + HW_VAR_USB_RX_AGGR, + HW_VAR_USER_CONTROL_TURBO_MODE, + HW_VAR_RETRY_LIMIT, + HW_VAR_INIT_TX_RATE, + HW_VAR_TX_RATE_REG, + HW_VAR_EFUSE_USAGE, + HW_VAR_EFUSE_BYTES, + HW_VAR_AUTOLOAD_STATUS, + HW_VAR_RF_2R_DISABLE, + HW_VAR_SET_RPWM, + HW_VAR_H2C_FW_PWRMODE, + HW_VAR_H2C_FW_JOINBSSRPT, + HW_VAR_1X1_RECV_COMBINE, + HW_VAR_STOP_SEND_BEACON, + HW_VAR_TSF_TIMER, + HW_VAR_IO_CMD, + + HW_VAR_RF_RECOVERY, + HW_VAR_H2C_FW_UPDATE_GTK, + HW_VAR_WF_MASK, + HW_VAR_WF_CRC, + HW_VAR_WF_IS_MAC_ADDR, + HW_VAR_H2C_FW_OFFLOAD, + HW_VAR_RESET_WFCRC, + + HW_VAR_HANDLE_FW_C2H, + HW_VAR_DL_FW_RSVD_PAGE, + HW_VAR_AID, + HW_VAR_HW_SEQ_ENABLE, + HW_VAR_CORRECT_TSF, + HW_VAR_BCN_VALID, + HW_VAR_FWLPS_RF_ON, + HW_VAR_DUAL_TSF_RST, + HW_VAR_SWITCH_EPHY_WoWLAN, + HW_VAR_INT_MIGRATION, + HW_VAR_INT_AC, + HW_VAR_RF_TIMING, +}; + +enum rt_op_mode { + RT_OP_MODE_AP, + RT_OP_MODE_INFRASTRUCTURE, + RT_OP_MODE_IBSS, + RT_OP_MODE_NO_LINK, +}; + + +#define aSifsTime \ + (((priv->rtllib->current_network.mode == IEEE_A) \ + || (priv->rtllib->current_network.mode == IEEE_N_24G) \ + || (priv->rtllib->current_network.mode == IEEE_N_5G)) ? 16 : 10) + +#define MGMT_QUEUE_NUM 5 + +#define IEEE_CMD_SET_WPA_PARAM 1 +#define IEEE_CMD_SET_WPA_IE 2 +#define IEEE_CMD_SET_ENCRYPTION 3 +#define IEEE_CMD_MLME 4 + +#define IEEE_PARAM_WPA_ENABLED 1 +#define IEEE_PARAM_TKIP_COUNTERMEASURES 2 +#define IEEE_PARAM_DROP_UNENCRYPTED 3 +#define IEEE_PARAM_PRIVACY_INVOKED 4 +#define IEEE_PARAM_AUTH_ALGS 5 +#define IEEE_PARAM_IEEE_802_1X 6 +#define IEEE_PARAM_WPAX_SELECT 7 +#define IEEE_PROTO_WPA 1 +#define IEEE_PROTO_RSN 2 +#define IEEE_WPAX_USEGROUP 0 +#define IEEE_WPAX_WEP40 1 +#define IEEE_WPAX_TKIP 2 +#define IEEE_WPAX_WRAP 3 +#define IEEE_WPAX_CCMP 4 +#define IEEE_WPAX_WEP104 5 + +#define IEEE_KEY_MGMT_IEEE8021X 1 +#define IEEE_KEY_MGMT_PSK 2 + +#define IEEE_MLME_STA_DEAUTH 1 +#define IEEE_MLME_STA_DISASSOC 2 + + +#define IEEE_CRYPT_ERR_UNKNOWN_ALG 2 +#define IEEE_CRYPT_ERR_UNKNOWN_ADDR 3 +#define IEEE_CRYPT_ERR_CRYPT_INIT_FAILED 4 +#define IEEE_CRYPT_ERR_KEY_SET_FAILED 5 +#define IEEE_CRYPT_ERR_TX_KEY_SET_FAILED 6 +#define IEEE_CRYPT_ERR_CARD_CONF_FAILED 7 +#define IEEE_CRYPT_ALG_NAME_LEN 16 + +#define MAX_IE_LEN 0xff +#define RT_ASSERT_RET(_Exp) do {} while (0) +#define RT_ASSERT_RET_VALUE(_Exp, Ret) \ + do {} while (0) + +struct ieee_param { + u32 cmd; + u8 sta_addr[ETH_ALEN]; + union { + struct { + u8 name; + u32 value; + } wpa_param; + struct { + u32 len; + u8 reserved[32]; + u8 data[0]; + } wpa_ie; + struct { + int command; + int reason_code; + } mlme; + struct { + u8 alg[IEEE_CRYPT_ALG_NAME_LEN]; + u8 set_tx; + u32 err; + u8 idx; + u8 seq[8]; /* sequence counter (set: RX, get: TX) */ + u16 key_len; + u8 key[0]; + } crypt; + } u; +}; + + +#if WIRELESS_EXT < 17 +#define IW_QUAL_QUAL_INVALID 0x10 +#define IW_QUAL_LEVEL_INVALID 0x20 +#define IW_QUAL_NOISE_INVALID 0x40 +#define IW_QUAL_QUAL_UPDATED 0x1 +#define IW_QUAL_LEVEL_UPDATED 0x2 +#define IW_QUAL_NOISE_UPDATED 0x4 +#endif + +#define MSECS(t) msecs_to_jiffies(t) +#define msleep_interruptible_rsl msleep_interruptible + +#define RTLLIB_DATA_LEN 2304 +/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section + 6.2.1.1.2. + + The figure in section 7.1.2 suggests a body size of up to 2312 + bytes is allowed, which is a bit confusing, I suspect this + represents the 2304 bytes of real data, plus a possible 8 bytes of + WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */ +#define RTLLIB_1ADDR_LEN 10 +#define RTLLIB_2ADDR_LEN 16 +#define RTLLIB_3ADDR_LEN 24 +#define RTLLIB_4ADDR_LEN 30 +#define RTLLIB_FCS_LEN 4 +#define RTLLIB_HLEN (RTLLIB_4ADDR_LEN) +#define RTLLIB_FRAME_LEN (RTLLIB_DATA_LEN + RTLLIB_HLEN) +#define RTLLIB_MGMT_HDR_LEN 24 +#define RTLLIB_DATA_HDR3_LEN 24 +#define RTLLIB_DATA_HDR4_LEN 30 + +#define RTLLIB_SKBBUFFER_SIZE 2500 + +#define MIN_FRAG_THRESHOLD 256U +#define MAX_FRAG_THRESHOLD 2346U +#define MAX_HT_DATA_FRAG_THRESHOLD 0x2000 + +#define HT_AMSDU_SIZE_4K 3839 +#define HT_AMSDU_SIZE_8K 7935 + +/* Frame control field constants */ +#define RTLLIB_FCTL_VERS 0x0003 +#define RTLLIB_FCTL_FTYPE 0x000c +#define RTLLIB_FCTL_STYPE 0x00f0 +#define RTLLIB_FCTL_FRAMETYPE 0x00fc +#define RTLLIB_FCTL_TODS 0x0100 +#define RTLLIB_FCTL_FROMDS 0x0200 +#define RTLLIB_FCTL_DSTODS 0x0300 +#define RTLLIB_FCTL_MOREFRAGS 0x0400 +#define RTLLIB_FCTL_RETRY 0x0800 +#define RTLLIB_FCTL_PM 0x1000 +#define RTLLIB_FCTL_MOREDATA 0x2000 +#define RTLLIB_FCTL_WEP 0x4000 +#define RTLLIB_FCTL_ORDER 0x8000 + +#define RTLLIB_FTYPE_MGMT 0x0000 +#define RTLLIB_FTYPE_CTL 0x0004 +#define RTLLIB_FTYPE_DATA 0x0008 + +/* management */ +#define RTLLIB_STYPE_ASSOC_REQ 0x0000 +#define RTLLIB_STYPE_ASSOC_RESP 0x0010 +#define RTLLIB_STYPE_REASSOC_REQ 0x0020 +#define RTLLIB_STYPE_REASSOC_RESP 0x0030 +#define RTLLIB_STYPE_PROBE_REQ 0x0040 +#define RTLLIB_STYPE_PROBE_RESP 0x0050 +#define RTLLIB_STYPE_BEACON 0x0080 +#define RTLLIB_STYPE_ATIM 0x0090 +#define RTLLIB_STYPE_DISASSOC 0x00A0 +#define RTLLIB_STYPE_AUTH 0x00B0 +#define RTLLIB_STYPE_DEAUTH 0x00C0 +#define RTLLIB_STYPE_MANAGE_ACT 0x00D0 + +/* control */ +#define RTLLIB_STYPE_PSPOLL 0x00A0 +#define RTLLIB_STYPE_RTS 0x00B0 +#define RTLLIB_STYPE_CTS 0x00C0 +#define RTLLIB_STYPE_ACK 0x00D0 +#define RTLLIB_STYPE_CFEND 0x00E0 +#define RTLLIB_STYPE_CFENDACK 0x00F0 +#define RTLLIB_STYPE_BLOCKACK 0x0094 + +/* data */ +#define RTLLIB_STYPE_DATA 0x0000 +#define RTLLIB_STYPE_DATA_CFACK 0x0010 +#define RTLLIB_STYPE_DATA_CFPOLL 0x0020 +#define RTLLIB_STYPE_DATA_CFACKPOLL 0x0030 +#define RTLLIB_STYPE_NULLFUNC 0x0040 +#define RTLLIB_STYPE_CFACK 0x0050 +#define RTLLIB_STYPE_CFPOLL 0x0060 +#define RTLLIB_STYPE_CFACKPOLL 0x0070 +#define RTLLIB_STYPE_QOS_DATA 0x0080 +#define RTLLIB_STYPE_QOS_NULL 0x00C0 + +#define RTLLIB_SCTL_FRAG 0x000F +#define RTLLIB_SCTL_SEQ 0xFFF0 + +/* QOS control */ +#define RTLLIB_QCTL_TID 0x000F + +#define FC_QOS_BIT BIT7 +#define IsDataFrame(pdu) (((pdu[0] & 0x0C) == 0x08) ? true : false) +#define IsLegacyDataFrame(pdu) (IsDataFrame(pdu) && (!(pdu[0]&FC_QOS_BIT))) +#define IsQoSDataFrame(pframe) \ + ((*(u16 *)pframe&(RTLLIB_STYPE_QOS_DATA|RTLLIB_FTYPE_DATA)) == \ + (RTLLIB_STYPE_QOS_DATA|RTLLIB_FTYPE_DATA)) +#define Frame_Order(pframe) (*(u16 *)pframe&RTLLIB_FCTL_ORDER) +#define SN_LESS(a, b) (((a-b)&0x800) != 0) +#define SN_EQUAL(a, b) (a == b) +#define MAX_DEV_ADDR_SIZE 8 + +enum act_category { + ACT_CAT_QOS = 1, + ACT_CAT_DLS = 2, + ACT_CAT_BA = 3, + ACT_CAT_HT = 7, + ACT_CAT_WMM = 17, +}; + +enum ts_action { + ACT_ADDTSREQ = 0, + ACT_ADDTSRSP = 1, + ACT_DELTS = 2, + ACT_SCHEDULE = 3, +}; + +enum ba_action { + ACT_ADDBAREQ = 0, + ACT_ADDBARSP = 1, + ACT_DELBA = 2, +}; + +enum init_gain_op_type { + IG_Backup = 0, + IG_Restore, + IG_Max +}; + +enum led_ctl_mode { + LED_CTL_POWER_ON = 1, + LED_CTL_LINK = 2, + LED_CTL_NO_LINK = 3, + LED_CTL_TX = 4, + LED_CTL_RX = 5, + LED_CTL_SITE_SURVEY = 6, + LED_CTL_POWER_OFF = 7, + LED_CTL_START_TO_LINK = 8, + LED_CTL_START_WPS = 9, + LED_CTL_STOP_WPS = 10, + LED_CTL_START_WPS_BOTTON = 11, + LED_CTL_STOP_WPS_FAIL = 12, + LED_CTL_STOP_WPS_FAIL_OVERLAP = 13, +}; + +enum rt_rf_type_def { + RF_1T2R = 0, + RF_2T4R, + RF_2T2R, + RF_1T1R, + RF_2T2R_GREEN, + RF_819X_MAX_TYPE +}; + +enum wireless_mode { + WIRELESS_MODE_UNKNOWN = 0x00, + WIRELESS_MODE_A = 0x01, + WIRELESS_MODE_B = 0x02, + WIRELESS_MODE_G = 0x04, + WIRELESS_MODE_AUTO = 0x08, + WIRELESS_MODE_N_24G = 0x10, + WIRELESS_MODE_N_5G = 0x20 +}; + +enum wireless_network_type { + WIRELESS_11B = 1, + WIRELESS_11G = 2, + WIRELESS_11A = 4, + WIRELESS_11N = 8 +}; + +#define OUI_SUBTYPE_WMM_INFO 0 +#define OUI_SUBTYPE_WMM_PARAM 1 +#define OUI_SUBTYPE_QOS_CAPABI 5 + +/* debug macros */ +extern u32 rtllib_debug_level; +#define RTLLIB_DEBUG(level, fmt, args...) \ +do { \ + if (rtllib_debug_level & (level)) \ + printk(KERN_DEBUG "rtllib: " fmt, ## args); \ +} while (0) + +#define RTLLIB_DEBUG_DATA(level, data, datalen) \ + do { \ + if ((rtllib_debug_level & (level)) == (level)) { \ + int i; \ + u8 *pdata = (u8 *)data; \ + printk(KERN_DEBUG "rtllib: %s()\n", __func__); \ + for (i = 0; i < (int)(datalen); i++) { \ + printk("%2.2x ", pdata[i]); \ + if ((i+1)%16 == 0) \ + printk("\n"); \ + } \ + printk("\n"); \ + } \ + } while (0) + +/* + * To use the debug system; + * + * If you are defining a new debug classification, simply add it to the #define + * list here in the form of: + * + * #define RTLLIB_DL_xxxx VALUE + * + * shifting value to the left one bit from the previous entry. xxxx should be + * the name of the classification (for example, WEP) + * + * You then need to either add a RTLLIB_xxxx_DEBUG() macro definition for your + * classification, or use RTLLIB_DEBUG(RTLLIB_DL_xxxx, ...) whenever you want + * to send output to that classification. + * + * To add your debug level to the list of levels seen when you perform + * + * % cat /proc/net/ipw/debug_level + * + * you simply need to add your entry to the ipw_debug_levels array. + * + * + */ + +#define RTLLIB_DL_INFO (1<<0) +#define RTLLIB_DL_WX (1<<1) +#define RTLLIB_DL_SCAN (1<<2) +#define RTLLIB_DL_STATE (1<<3) +#define RTLLIB_DL_MGMT (1<<4) +#define RTLLIB_DL_FRAG (1<<5) +#define RTLLIB_DL_EAP (1<<6) +#define RTLLIB_DL_DROP (1<<7) + +#define RTLLIB_DL_TX (1<<8) +#define RTLLIB_DL_RX (1<<9) + +#define RTLLIB_DL_HT (1<<10) +#define RTLLIB_DL_BA (1<<11) +#define RTLLIB_DL_TS (1<<12) +#define RTLLIB_DL_QOS (1<<13) +#define RTLLIB_DL_REORDER (1<<14) +#define RTLLIB_DL_IOT (1<<15) +#define RTLLIB_DL_IPS (1<<16) +#define RTLLIB_DL_TRACE (1<<29) +#define RTLLIB_DL_DATA (1<<30) +#define RTLLIB_DL_ERR (1<<31) +#define RTLLIB_ERROR(f, a...) printk(KERN_ERR "rtllib: " f, ## a) +#define RTLLIB_WARNING(f, a...) printk(KERN_WARNING "rtllib: " f, ## a) +#define RTLLIB_DEBUG_INFO(f, a...) RTLLIB_DEBUG(RTLLIB_DL_INFO, f, ## a) + +#define RTLLIB_DEBUG_WX(f, a...) RTLLIB_DEBUG(RTLLIB_DL_WX, f, ## a) +#define RTLLIB_DEBUG_SCAN(f, a...) RTLLIB_DEBUG(RTLLIB_DL_SCAN, f, ## a) +#define RTLLIB_DEBUG_STATE(f, a...) RTLLIB_DEBUG(RTLLIB_DL_STATE, f, ## a) +#define RTLLIB_DEBUG_MGMT(f, a...) RTLLIB_DEBUG(RTLLIB_DL_MGMT, f, ## a) +#define RTLLIB_DEBUG_FRAG(f, a...) RTLLIB_DEBUG(RTLLIB_DL_FRAG, f, ## a) +#define RTLLIB_DEBUG_EAP(f, a...) RTLLIB_DEBUG(RTLLIB_DL_EAP, f, ## a) +#define RTLLIB_DEBUG_DROP(f, a...) RTLLIB_DEBUG(RTLLIB_DL_DROP, f, ## a) +#define RTLLIB_DEBUG_TX(f, a...) RTLLIB_DEBUG(RTLLIB_DL_TX, f, ## a) +#define RTLLIB_DEBUG_RX(f, a...) RTLLIB_DEBUG(RTLLIB_DL_RX, f, ## a) +#define RTLLIB_DEBUG_QOS(f, a...) RTLLIB_DEBUG(RTLLIB_DL_QOS, f, ## a) + +/* Added by Annie, 2005-11-22. */ +#define MAX_STR_LEN 64 +/* I want to see ASCII 33 to 126 only. Otherwise, I print '?'. */ +#define PRINTABLE(_ch) (_ch > '!' && _ch < '~') +#define RTLLIB_PRINT_STR(_Comp, _TitleString, _Ptr, _Len) \ + if ((_Comp) & level) { \ + int __i; \ + u8 struct buffer[MAX_STR_LEN]; \ + int length = (_Len < MAX_STR_LEN) ? _Len : (MAX_STR_LEN-1) ;\ + memset(struct buffer, 0, MAX_STR_LEN); \ + memcpy(struct buffer, (u8 *)_Ptr, length); \ + for (__i = 0; __i < MAX_STR_LEN; __i++) { \ + if (!PRINTABLE(struct buffer[__i])) \ + struct buffer[__i] = '?'; \ + } \ + struct buffer[length] = '\0'; \ + printk(KERN_INFO "Rtl819x: "); \ + printk(_TitleString); \ + printk(": %d, <%s>\n", _Len, struct buffer); \ + } +#ifndef ETH_P_PAE +#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */ +#define ETH_P_IP 0x0800 /* Internet Protocol packet */ +#define ETH_P_ARP 0x0806 /* Address Resolution packet */ +#endif /* ETH_P_PAE */ + +#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */ + +#ifndef ETH_P_80211_RAW +#define ETH_P_80211_RAW (ETH_P_ECONET + 1) +#endif + +/* IEEE 802.11 defines */ + +#define P80211_OUI_LEN 3 + +struct rtllib_snap_hdr { + + u8 dsap; /* always 0xAA */ + u8 ssap; /* always 0xAA */ + u8 ctrl; /* always 0x03 */ + u8 oui[P80211_OUI_LEN]; /* organizational universal id */ + +} __packed; + +enum _REG_PREAMBLE_MODE { + PREAMBLE_LONG = 1, + PREAMBLE_AUTO = 2, + PREAMBLE_SHORT = 3, +}; + +#define SNAP_SIZE sizeof(struct rtllib_snap_hdr) + +#define WLAN_FC_GET_VERS(fc) ((fc) & RTLLIB_FCTL_VERS) +#define WLAN_FC_GET_TYPE(fc) ((fc) & RTLLIB_FCTL_FTYPE) +#define WLAN_FC_GET_STYPE(fc) ((fc) & RTLLIB_FCTL_STYPE) +#define WLAN_FC_MORE_DATA(fc) ((fc) & RTLLIB_FCTL_MOREDATA) + +#define WLAN_FC_GET_FRAMETYPE(fc) ((fc) & RTLLIB_FCTL_FRAMETYPE) +#define WLAN_GET_SEQ_FRAG(seq) ((seq) & RTLLIB_SCTL_FRAG) +#define WLAN_GET_SEQ_SEQ(seq) (((seq) & RTLLIB_SCTL_SEQ) >> 4) + +/* Authentication algorithms */ +#define WLAN_AUTH_OPEN 0 +#define WLAN_AUTH_SHARED_KEY 1 +#define WLAN_AUTH_LEAP 128 + +#define WLAN_AUTH_CHALLENGE_LEN 128 + +#define WLAN_CAPABILITY_ESS (1<<0) +#define WLAN_CAPABILITY_IBSS (1<<1) +#define WLAN_CAPABILITY_CF_POLLABLE (1<<2) +#define WLAN_CAPABILITY_CF_POLL_REQUEST (1<<3) +#define WLAN_CAPABILITY_PRIVACY (1<<4) +#define WLAN_CAPABILITY_SHORT_PREAMBLE (1<<5) +#define WLAN_CAPABILITY_PBCC (1<<6) +#define WLAN_CAPABILITY_CHANNEL_AGILITY (1<<7) +#define WLAN_CAPABILITY_SPECTRUM_MGMT (1<<8) +#define WLAN_CAPABILITY_QOS (1<<9) +#define WLAN_CAPABILITY_SHORT_SLOT_TIME (1<<10) +#define WLAN_CAPABILITY_DSSS_OFDM (1<<13) + +/* 802.11g ERP information element */ +#define WLAN_ERP_NON_ERP_PRESENT (1<<0) +#define WLAN_ERP_USE_PROTECTION (1<<1) +#define WLAN_ERP_BARKER_PREAMBLE (1<<2) + +/* Status codes */ +enum rtllib_statuscode { + WLAN_STATUS_SUCCESS = 0, + WLAN_STATUS_UNSPECIFIED_FAILURE = 1, + WLAN_STATUS_CAPS_UNSUPPORTED = 10, + WLAN_STATUS_REASSOC_NO_ASSOC = 11, + WLAN_STATUS_ASSOC_DENIED_UNSPEC = 12, + WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG = 13, + WLAN_STATUS_UNKNOWN_AUTH_TRANSACTION = 14, + WLAN_STATUS_CHALLENGE_FAIL = 15, + WLAN_STATUS_AUTH_TIMEOUT = 16, + WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA = 17, + WLAN_STATUS_ASSOC_DENIED_RATES = 18, + /* 802.11b */ + WLAN_STATUS_ASSOC_DENIED_NOSHORTPREAMBLE = 19, + WLAN_STATUS_ASSOC_DENIED_NOPBCC = 20, + WLAN_STATUS_ASSOC_DENIED_NOAGILITY = 21, + /* 802.11h */ + WLAN_STATUS_ASSOC_DENIED_NOSPECTRUM = 22, + WLAN_STATUS_ASSOC_REJECTED_BAD_POWER = 23, + WLAN_STATUS_ASSOC_REJECTED_BAD_SUPP_CHAN = 24, + /* 802.11g */ + WLAN_STATUS_ASSOC_DENIED_NOSHORTTIME = 25, + WLAN_STATUS_ASSOC_DENIED_NODSSSOFDM = 26, + /* 802.11i */ + WLAN_STATUS_INVALID_IE = 40, + WLAN_STATUS_INVALID_GROUP_CIPHER = 41, + WLAN_STATUS_INVALID_PAIRWISE_CIPHER = 42, + WLAN_STATUS_INVALID_AKMP = 43, + WLAN_STATUS_UNSUPP_RSN_VERSION = 44, + WLAN_STATUS_INVALID_RSN_IE_CAP = 45, + WLAN_STATUS_CIPHER_SUITE_REJECTED = 46, +}; + +/* Reason codes */ +enum rtllib_reasoncode { + WLAN_REASON_UNSPECIFIED = 1, + WLAN_REASON_PREV_AUTH_NOT_VALID = 2, + WLAN_REASON_DEAUTH_LEAVING = 3, + WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY = 4, + WLAN_REASON_DISASSOC_AP_BUSY = 5, + WLAN_REASON_CLASS2_FRAME_FROM_NONAUTH_STA = 6, + WLAN_REASON_CLASS3_FRAME_FROM_NONASSOC_STA = 7, + WLAN_REASON_DISASSOC_STA_HAS_LEFT = 8, + WLAN_REASON_STA_REQ_ASSOC_WITHOUT_AUTH = 9, + /* 802.11h */ + WLAN_REASON_DISASSOC_BAD_POWER = 10, + WLAN_REASON_DISASSOC_BAD_SUPP_CHAN = 11, + /* 802.11i */ + WLAN_REASON_INVALID_IE = 13, + WLAN_REASON_MIC_FAILURE = 14, + WLAN_REASON_4WAY_HANDSHAKE_TIMEOUT = 15, + WLAN_REASON_GROUP_KEY_HANDSHAKE_TIMEOUT = 16, + WLAN_REASON_IE_DIFFERENT = 17, + WLAN_REASON_INVALID_GROUP_CIPHER = 18, + WLAN_REASON_INVALID_PAIRWISE_CIPHER = 19, + WLAN_REASON_INVALID_AKMP = 20, + WLAN_REASON_UNSUPP_RSN_VERSION = 21, + WLAN_REASON_INVALID_RSN_IE_CAP = 22, + WLAN_REASON_IEEE8021X_FAILED = 23, + WLAN_REASON_CIPHER_SUITE_REJECTED = 24, +}; + +#define RTLLIB_STATMASK_SIGNAL (1<<0) +#define RTLLIB_STATMASK_RSSI (1<<1) +#define RTLLIB_STATMASK_NOISE (1<<2) +#define RTLLIB_STATMASK_RATE (1<<3) +#define RTLLIB_STATMASK_WEMASK 0x7 + +#define RTLLIB_CCK_MODULATION (1<<0) +#define RTLLIB_OFDM_MODULATION (1<<1) + +#define RTLLIB_24GHZ_BAND (1<<0) +#define RTLLIB_52GHZ_BAND (1<<1) + +#define RTLLIB_CCK_RATE_LEN 4 +#define RTLLIB_CCK_RATE_1MB 0x02 +#define RTLLIB_CCK_RATE_2MB 0x04 +#define RTLLIB_CCK_RATE_5MB 0x0B +#define RTLLIB_CCK_RATE_11MB 0x16 +#define RTLLIB_OFDM_RATE_LEN 8 +#define RTLLIB_OFDM_RATE_6MB 0x0C +#define RTLLIB_OFDM_RATE_9MB 0x12 +#define RTLLIB_OFDM_RATE_12MB 0x18 +#define RTLLIB_OFDM_RATE_18MB 0x24 +#define RTLLIB_OFDM_RATE_24MB 0x30 +#define RTLLIB_OFDM_RATE_36MB 0x48 +#define RTLLIB_OFDM_RATE_48MB 0x60 +#define RTLLIB_OFDM_RATE_54MB 0x6C +#define RTLLIB_BASIC_RATE_MASK 0x80 + +#define RTLLIB_CCK_RATE_1MB_MASK (1<<0) +#define RTLLIB_CCK_RATE_2MB_MASK (1<<1) +#define RTLLIB_CCK_RATE_5MB_MASK (1<<2) +#define RTLLIB_CCK_RATE_11MB_MASK (1<<3) +#define RTLLIB_OFDM_RATE_6MB_MASK (1<<4) +#define RTLLIB_OFDM_RATE_9MB_MASK (1<<5) +#define RTLLIB_OFDM_RATE_12MB_MASK (1<<6) +#define RTLLIB_OFDM_RATE_18MB_MASK (1<<7) +#define RTLLIB_OFDM_RATE_24MB_MASK (1<<8) +#define RTLLIB_OFDM_RATE_36MB_MASK (1<<9) +#define RTLLIB_OFDM_RATE_48MB_MASK (1<<10) +#define RTLLIB_OFDM_RATE_54MB_MASK (1<<11) + +#define RTLLIB_CCK_RATES_MASK 0x0000000F +#define RTLLIB_CCK_BASIC_RATES_MASK (RTLLIB_CCK_RATE_1MB_MASK | \ + RTLLIB_CCK_RATE_2MB_MASK) +#define RTLLIB_CCK_DEFAULT_RATES_MASK (RTLLIB_CCK_BASIC_RATES_MASK | \ + RTLLIB_CCK_RATE_5MB_MASK | \ + RTLLIB_CCK_RATE_11MB_MASK) + +#define RTLLIB_OFDM_RATES_MASK 0x00000FF0 +#define RTLLIB_OFDM_BASIC_RATES_MASK (RTLLIB_OFDM_RATE_6MB_MASK | \ + RTLLIB_OFDM_RATE_12MB_MASK | \ + RTLLIB_OFDM_RATE_24MB_MASK) +#define RTLLIB_OFDM_DEFAULT_RATES_MASK (RTLLIB_OFDM_BASIC_RATES_MASK | \ + RTLLIB_OFDM_RATE_9MB_MASK | \ + RTLLIB_OFDM_RATE_18MB_MASK | \ + RTLLIB_OFDM_RATE_36MB_MASK | \ + RTLLIB_OFDM_RATE_48MB_MASK | \ + RTLLIB_OFDM_RATE_54MB_MASK) +#define RTLLIB_DEFAULT_RATES_MASK (RTLLIB_OFDM_DEFAULT_RATES_MASK | \ + RTLLIB_CCK_DEFAULT_RATES_MASK) + +#define RTLLIB_NUM_OFDM_RATES 8 +#define RTLLIB_NUM_CCK_RATES 4 +#define RTLLIB_OFDM_SHIFT_MASK_A 4 + + +/* this is stolen and modified from the madwifi driver*/ +#define RTLLIB_FC0_TYPE_MASK 0x0c +#define RTLLIB_FC0_TYPE_DATA 0x08 +#define RTLLIB_FC0_SUBTYPE_MASK 0xB0 +#define RTLLIB_FC0_SUBTYPE_QOS 0x80 + +#define RTLLIB_QOS_HAS_SEQ(fc) \ + (((fc) & (RTLLIB_FC0_TYPE_MASK | RTLLIB_FC0_SUBTYPE_MASK)) == \ + (RTLLIB_FC0_TYPE_DATA | RTLLIB_FC0_SUBTYPE_QOS)) + +/* this is stolen from ipw2200 driver */ +#define IEEE_IBSS_MAC_HASH_SIZE 31 +struct ieee_ibss_seq { + u8 mac[ETH_ALEN]; + u16 seq_num[17]; + u16 frag_num[17]; + unsigned long packet_time[17]; + struct list_head list; +}; + +/* NOTE: This data is for statistical purposes; not all hardware provides this + * information for frames received. Not setting these will not cause + * any adverse affects. */ +struct rtllib_rx_stats { + u64 mac_time; + s8 rssi; + u8 signal; + u8 noise; + u16 rate; /* in 100 kbps */ + u8 received_channel; + u8 control; + u8 mask; + u8 freq; + u16 len; + u64 tsf; + u32 beacon_time; + u8 nic_type; + u16 Length; + u8 SignalQuality; + s32 RecvSignalPower; + s8 RxPower; + u8 SignalStrength; + u16 bHwError:1; + u16 bCRC:1; + u16 bICV:1; + u16 bShortPreamble:1; + u16 Antenna:1; + u16 Decrypted:1; + u16 Wakeup:1; + u16 Reserved0:1; + u8 AGC; + u32 TimeStampLow; + u32 TimeStampHigh; + bool bShift; + bool bIsQosData; + u8 UserPriority; + + u8 RxDrvInfoSize; + u8 RxBufShift; + bool bIsAMPDU; + bool bFirstMPDU; + bool bContainHTC; + bool RxIs40MHzPacket; + u32 RxPWDBAll; + u8 RxMIMOSignalStrength[4]; + s8 RxMIMOSignalQuality[2]; + bool bPacketMatchBSSID; + bool bIsCCK; + bool bPacketToSelf; + u8 *virtual_address; + u16 packetlength; + u16 fraglength; + u16 fragoffset; + u16 ntotalfrag; + bool bisrxaggrsubframe; + bool bPacketBeacon; + bool bToSelfBA; + char cck_adc_pwdb[4]; + u16 Seq_Num; + u8 nTotalAggPkt; +}; + +/* IEEE 802.11 requires that STA supports concurrent reception of at least + * three fragmented frames. This define can be increased to support more + * concurrent frames, but it should be noted that each entry can consume about + * 2 kB of RAM and increasing cache size will slow down frame reassembly. */ +#define RTLLIB_FRAG_CACHE_LEN 4 + +struct rtllib_frag_entry { + unsigned long first_frag_time; + unsigned int seq; + unsigned int last_frag; + struct sk_buff *skb; + u8 src_addr[ETH_ALEN]; + u8 dst_addr[ETH_ALEN]; +}; + +struct rtllib_stats { + unsigned int tx_unicast_frames; + unsigned int tx_multicast_frames; + unsigned int tx_fragments; + unsigned int tx_unicast_octets; + unsigned int tx_multicast_octets; + unsigned int tx_deferred_transmissions; + unsigned int tx_single_retry_frames; + unsigned int tx_multiple_retry_frames; + unsigned int tx_retry_limit_exceeded; + unsigned int tx_discards; + unsigned int rx_unicast_frames; + unsigned int rx_multicast_frames; + unsigned int rx_fragments; + unsigned int rx_unicast_octets; + unsigned int rx_multicast_octets; + unsigned int rx_fcs_errors; + unsigned int rx_discards_no_buffer; + unsigned int tx_discards_wrong_sa; + unsigned int rx_discards_undecryptable; + unsigned int rx_message_in_msg_fragments; + unsigned int rx_message_in_bad_msg_fragments; +}; + +struct rtllib_device; + +#include "rtllib_crypt.h" + +#define SEC_KEY_1 (1<<0) +#define SEC_KEY_2 (1<<1) +#define SEC_KEY_3 (1<<2) +#define SEC_KEY_4 (1<<3) +#define SEC_ACTIVE_KEY (1<<4) +#define SEC_AUTH_MODE (1<<5) +#define SEC_UNICAST_GROUP (1<<6) +#define SEC_LEVEL (1<<7) +#define SEC_ENABLED (1<<8) +#define SEC_ENCRYPT (1<<9) + +#define SEC_LEVEL_0 0 /* None */ +#define SEC_LEVEL_1 1 /* WEP 40 and 104 bit */ +#define SEC_LEVEL_2 2 /* Level 1 + TKIP */ +#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */ +#define SEC_LEVEL_3 4 /* Level 2 + CCMP */ + +#define SEC_ALG_NONE 0 +#define SEC_ALG_WEP 1 +#define SEC_ALG_TKIP 2 +#define SEC_ALG_CCMP 4 + +#define WEP_KEYS 4 +#define WEP_KEY_LEN 13 +#define SCM_KEY_LEN 32 +#define SCM_TEMPORAL_KEY_LENGTH 16 + +struct rtllib_security { + u16 active_key:2, + enabled:1, + auth_mode:2, + auth_algo:4, + unicast_uses_group:1, + encrypt:1; + u8 key_sizes[WEP_KEYS]; + u8 keys[WEP_KEYS][SCM_KEY_LEN]; + u8 level; + u16 flags; +} __packed; + + +/* + 802.11 data frame from AP + ,-------------------------------------------------------------------. +Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 | + |------|------|---------|---------|---------|------|---------|------| +Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | frame | fcs | + | | tion | (BSSID) | | | ence | data | | + `-------------------------------------------------------------------' +Total: 28-2340 bytes +*/ + +/* Management Frame Information Element Types */ +enum rtllib_mfie { + MFIE_TYPE_SSID = 0, + MFIE_TYPE_RATES = 1, + MFIE_TYPE_FH_SET = 2, + MFIE_TYPE_DS_SET = 3, + MFIE_TYPE_CF_SET = 4, + MFIE_TYPE_TIM = 5, + MFIE_TYPE_IBSS_SET = 6, + MFIE_TYPE_COUNTRY = 7, + MFIE_TYPE_HOP_PARAMS = 8, + MFIE_TYPE_HOP_TABLE = 9, + MFIE_TYPE_REQUEST = 10, + MFIE_TYPE_CHALLENGE = 16, + MFIE_TYPE_POWER_CONSTRAINT = 32, + MFIE_TYPE_POWER_CAPABILITY = 33, + MFIE_TYPE_TPC_REQUEST = 34, + MFIE_TYPE_TPC_REPORT = 35, + MFIE_TYPE_SUPP_CHANNELS = 36, + MFIE_TYPE_CSA = 37, + MFIE_TYPE_MEASURE_REQUEST = 38, + MFIE_TYPE_MEASURE_REPORT = 39, + MFIE_TYPE_QUIET = 40, + MFIE_TYPE_IBSS_DFS = 41, + MFIE_TYPE_ERP = 42, + MFIE_TYPE_HT_CAP = 45, + MFIE_TYPE_RSN = 48, + MFIE_TYPE_RATES_EX = 50, + MFIE_TYPE_HT_INFO = 61, + MFIE_TYPE_AIRONET = 133, + MFIE_TYPE_GENERIC = 221, + MFIE_TYPE_QOS_PARAMETER = 222, +}; + +/* Minimal header; can be used for passing 802.11 frames with sufficient + * information to determine what type of underlying data type is actually + * stored in the data. */ +struct rtllib_pspoll_hdr { + __le16 frame_ctl; + __le16 aid; + u8 bssid[ETH_ALEN]; + u8 ta[ETH_ALEN]; +} __packed; + +struct rtllib_hdr { + __le16 frame_ctl; + __le16 duration_id; + u8 payload[0]; +} __packed; + +struct rtllib_hdr_1addr { + __le16 frame_ctl; + __le16 duration_id; + u8 addr1[ETH_ALEN]; + u8 payload[0]; +} __packed; + +struct rtllib_hdr_2addr { + __le16 frame_ctl; + __le16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 payload[0]; +} __packed; + +struct rtllib_hdr_3addr { + __le16 frame_ctl; + __le16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + __le16 seq_ctl; + u8 payload[0]; +} __packed; + +struct rtllib_hdr_4addr { + __le16 frame_ctl; + __le16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + __le16 seq_ctl; + u8 addr4[ETH_ALEN]; + u8 payload[0]; +} __packed; + +struct rtllib_hdr_3addrqos { + __le16 frame_ctl; + __le16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + __le16 seq_ctl; + __le16 qos_ctl; + u8 payload[0]; +} __packed; + +struct rtllib_hdr_4addrqos { + __le16 frame_ctl; + __le16 duration_id; + u8 addr1[ETH_ALEN]; + u8 addr2[ETH_ALEN]; + u8 addr3[ETH_ALEN]; + __le16 seq_ctl; + u8 addr4[ETH_ALEN]; + __le16 qos_ctl; + u8 payload[0]; +} __packed; + +struct rtllib_info_element { + u8 id; + u8 len; + u8 data[0]; +} __packed; + +struct rtllib_authentication { + struct rtllib_hdr_3addr header; + __le16 algorithm; + __le16 transaction; + __le16 status; + /*challenge*/ + struct rtllib_info_element info_element[0]; +} __packed; + +struct rtllib_disauth { + struct rtllib_hdr_3addr header; + __le16 reason; +} __packed; + +struct rtllib_disassoc { + struct rtllib_hdr_3addr header; + __le16 reason; +} __packed; + +struct rtllib_probe_request { + struct rtllib_hdr_3addr header; + /* SSID, supported rates */ + struct rtllib_info_element info_element[0]; +} __packed; + +struct rtllib_probe_response { + struct rtllib_hdr_3addr header; + u32 time_stamp[2]; + __le16 beacon_interval; + __le16 capability; + /* SSID, supported rates, FH params, DS params, + * CF params, IBSS params, TIM (if beacon), RSN */ + struct rtllib_info_element info_element[0]; +} __packed; + +/* Alias beacon for probe_response */ +#define rtllib_beacon rtllib_probe_response + +struct rtllib_assoc_request_frame { + struct rtllib_hdr_3addr header; + __le16 capability; + __le16 listen_interval; + /* SSID, supported rates, RSN */ + struct rtllib_info_element info_element[0]; +} __packed; + +struct rtllib_reassoc_request_frame { + struct rtllib_hdr_3addr header; + __le16 capability; + __le16 listen_interval; + u8 current_ap[ETH_ALEN]; + /* SSID, supported rates, RSN */ + struct rtllib_info_element info_element[0]; +} __packed; + +struct rtllib_assoc_response_frame { + struct rtllib_hdr_3addr header; + __le16 capability; + __le16 status; + __le16 aid; + struct rtllib_info_element info_element[0]; /* supported rates */ +} __packed; + +struct rtllib_txb { + u8 nr_frags; + u8 encrypted; + u8 queue_index; + u8 rts_included; + u16 reserved; + __le16 frag_size; + __le16 payload_size; + struct sk_buff *fragments[0]; +}; + +#define MAX_TX_AGG_COUNT 16 +struct rtllib_drv_agg_txb { + u8 nr_drv_agg_frames; + struct sk_buff *tx_agg_frames[MAX_TX_AGG_COUNT]; +} __packed; + +#define MAX_SUBFRAME_COUNT 64 +struct rtllib_rxb { + u8 nr_subframes; + struct sk_buff *subframes[MAX_SUBFRAME_COUNT]; + u8 dst[ETH_ALEN]; + u8 src[ETH_ALEN]; +} __packed; + +union frameqos { + u16 shortdata; + u8 chardata[2]; + struct { + u16 tid:4; + u16 eosp:1; + u16 ack_policy:2; + u16 reserved:1; + u16 txop:8; + } field; +}; + +/* SWEEP TABLE ENTRIES NUMBER*/ +#define MAX_SWEEP_TAB_ENTRIES 42 +#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET 7 +/* MAX_RATES_LENGTH needs to be 12. The spec says 8, and many APs + * only use 8, and then use extended rates for the remaining supported + * rates. Other APs, however, stick all of their supported rates on the + * main rates information element... */ +#define MAX_RATES_LENGTH ((u8)12) +#define MAX_RATES_EX_LENGTH ((u8)16) +#define MAX_NETWORK_COUNT 96 + +#define MAX_CHANNEL_NUMBER 161 +#define RTLLIB_SOFTMAC_SCAN_TIME 100 +#define RTLLIB_SOFTMAC_ASSOC_RETRY_TIME (HZ * 2) + +#define CRC_LENGTH 4U + +#define MAX_WPA_IE_LEN 64 +#define MAX_WZC_IE_LEN 256 + +#define NETWORK_EMPTY_ESSID (1<<0) +#define NETWORK_HAS_OFDM (1<<1) +#define NETWORK_HAS_CCK (1<<2) + +/* QoS structure */ +#define NETWORK_HAS_QOS_PARAMETERS (1<<3) +#define NETWORK_HAS_QOS_INFORMATION (1<<4) +#define NETWORK_HAS_QOS_MASK (NETWORK_HAS_QOS_PARAMETERS | \ + NETWORK_HAS_QOS_INFORMATION) +/* 802.11h */ +#define NETWORK_HAS_POWER_CONSTRAINT (1<<5) +#define NETWORK_HAS_CSA (1<<6) +#define NETWORK_HAS_QUIET (1<<7) +#define NETWORK_HAS_IBSS_DFS (1<<8) +#define NETWORK_HAS_TPC_REPORT (1<<9) + +#define NETWORK_HAS_ERP_VALUE (1<<10) + +#define QOS_QUEUE_NUM 4 +#define QOS_OUI_LEN 3 +#define QOS_OUI_TYPE 2 +#define QOS_ELEMENT_ID 221 +#define QOS_OUI_INFO_SUB_TYPE 0 +#define QOS_OUI_PARAM_SUB_TYPE 1 +#define QOS_VERSION_1 1 +#define QOS_AIFSN_MIN_VALUE 2 + +struct rtllib_qos_information_element { + u8 elementID; + u8 length; + u8 qui[QOS_OUI_LEN]; + u8 qui_type; + u8 qui_subtype; + u8 version; + u8 ac_info; +} __packed; + +struct rtllib_qos_ac_parameter { + u8 aci_aifsn; + u8 ecw_min_max; + __le16 tx_op_limit; +} __packed; + +struct rtllib_qos_parameter_info { + struct rtllib_qos_information_element info_element; + u8 reserved; + struct rtllib_qos_ac_parameter ac_params_record[QOS_QUEUE_NUM]; +} __packed; + +struct rtllib_qos_parameters { + __le16 cw_min[QOS_QUEUE_NUM]; + __le16 cw_max[QOS_QUEUE_NUM]; + u8 aifs[QOS_QUEUE_NUM]; + u8 flag[QOS_QUEUE_NUM]; + __le16 tx_op_limit[QOS_QUEUE_NUM]; +} __packed; + +struct rtllib_qos_data { + struct rtllib_qos_parameters parameters; + unsigned int wmm_acm; + int active; + int supported; + u8 param_count; + u8 old_param_count; +}; + +struct rtllib_tim_parameters { + u8 tim_count; + u8 tim_period; +} __packed; + +struct rtllib_wmm_ac_param { + u8 ac_aci_acm_aifsn; + u8 ac_ecwmin_ecwmax; + u16 ac_txop_limit; +}; + +struct rtllib_wmm_ts_info { + u8 ac_dir_tid; + u8 ac_up_psb; + u8 reserved; +} __packed; + +struct rtllib_wmm_tspec_elem { + struct rtllib_wmm_ts_info ts_info; + u16 norm_msdu_size; + u16 max_msdu_size; + u32 min_serv_inter; + u32 max_serv_inter; + u32 inact_inter; + u32 suspen_inter; + u32 serv_start_time; + u32 min_data_rate; + u32 mean_data_rate; + u32 peak_data_rate; + u32 max_burst_size; + u32 delay_bound; + u32 min_phy_rate; + u16 surp_band_allow; + u16 medium_time; +} __packed; + +enum eap_type { + EAP_PACKET = 0, + EAPOL_START, + EAPOL_LOGOFF, + EAPOL_KEY, + EAPOL_ENCAP_ASF_ALERT +}; + +static const char *eap_types[] = { + [EAP_PACKET] = "EAP-Packet", + [EAPOL_START] = "EAPOL-Start", + [EAPOL_LOGOFF] = "EAPOL-Logoff", + [EAPOL_KEY] = "EAPOL-Key", + [EAPOL_ENCAP_ASF_ALERT] = "EAPOL-Encap-ASF-Alert" +}; + +static inline const char *eap_get_type(int type) +{ + return ((u32)type >= ARRAY_SIZE(eap_types)) ? "Unknown" : + eap_types[type]; +} +static inline u8 Frame_QoSTID(u8 *buf) +{ + struct rtllib_hdr_3addr *hdr; + u16 fc; + hdr = (struct rtllib_hdr_3addr *)buf; + fc = le16_to_cpu(hdr->frame_ctl); + return (u8)((union frameqos *)(buf + (((fc & RTLLIB_FCTL_TODS) && + (fc & RTLLIB_FCTL_FROMDS)) ? 30 : 24)))->field.tid; +} + + +struct eapol { + u8 snap[6]; + u16 ethertype; + u8 version; + u8 type; + u16 length; +} __packed; + +struct rtllib_softmac_stats { + unsigned int rx_ass_ok; + unsigned int rx_ass_err; + unsigned int rx_probe_rq; + unsigned int tx_probe_rs; + unsigned int tx_beacons; + unsigned int rx_auth_rq; + unsigned int rx_auth_rs_ok; + unsigned int rx_auth_rs_err; + unsigned int tx_auth_rq; + unsigned int no_auth_rs; + unsigned int no_ass_rs; + unsigned int tx_ass_rq; + unsigned int rx_ass_rq; + unsigned int tx_probe_rq; + unsigned int reassoc; + unsigned int swtxstop; + unsigned int swtxawake; + unsigned char CurrentShowTxate; + unsigned char last_packet_rate; + unsigned int txretrycount; +}; + +#define BEACON_PROBE_SSID_ID_POSITION 12 + +struct rtllib_info_element_hdr { + u8 id; + u8 len; +} __packed; + +/* + * These are the data types that can make up management packets + * + u16 auth_algorithm; + u16 auth_sequence; + u16 beacon_interval; + u16 capability; + u8 current_ap[ETH_ALEN]; + u16 listen_interval; + struct { + u16 association_id:14, reserved:2; + } __packed; + u32 time_stamp[2]; + u16 reason; + u16 status; +*/ + +#define RTLLIB_DEFAULT_TX_ESSID "Penguin" +#define RTLLIB_DEFAULT_BASIC_RATE 2 + +enum {WMM_all_frame, WMM_two_frame, WMM_four_frame, WMM_six_frame}; +#define MAX_SP_Len (WMM_all_frame << 4) +#define RTLLIB_QOS_TID 0x0f +#define QOS_CTL_NOTCONTAIN_ACK (0x01 << 5) + +#define RTLLIB_DTIM_MBCAST 4 +#define RTLLIB_DTIM_UCAST 2 +#define RTLLIB_DTIM_VALID 1 +#define RTLLIB_DTIM_INVALID 0 + +#define RTLLIB_PS_DISABLED 0 +#define RTLLIB_PS_UNICAST RTLLIB_DTIM_UCAST +#define RTLLIB_PS_MBCAST RTLLIB_DTIM_MBCAST + +#define WME_AC_BK 0x00 +#define WME_AC_BE 0x01 +#define WME_AC_VI 0x02 +#define WME_AC_VO 0x03 +#define WME_ACI_MASK 0x03 +#define WME_AIFSN_MASK 0x03 +#define WME_AC_PRAM_LEN 16 + +#define MAX_RECEIVE_BUFFER_SIZE 9100 + +#define UP2AC(up) ( \ + ((up) < 1) ? WME_AC_BE : \ + ((up) < 3) ? WME_AC_BK : \ + ((up) < 4) ? WME_AC_BE : \ + ((up) < 6) ? WME_AC_VI : \ + WME_AC_VO) + +#define AC2UP(_ac) ( \ + ((_ac) == WME_AC_VO) ? 6 : \ + ((_ac) == WME_AC_VI) ? 5 : \ + ((_ac) == WME_AC_BK) ? 1 : \ + 0) + +#define ETHER_ADDR_LEN 6 /* length of an Ethernet address */ +#define ETHERNET_HEADER_SIZE 14 /* length of two Ethernet address + * plus ether type*/ + +struct ether_header { + u8 ether_dhost[ETHER_ADDR_LEN]; + u8 ether_shost[ETHER_ADDR_LEN]; + u16 ether_type; +} __packed; + +#ifndef ETHERTYPE_PAE +#define ETHERTYPE_PAE 0x888e /* EAPOL PAE/802.1x */ +#endif +#ifndef ETHERTYPE_IP +#define ETHERTYPE_IP 0x0800 /* IP protocol */ +#endif + + +enum erp_t { + ERP_NonERPpresent = 0x01, + ERP_UseProtection = 0x02, + ERP_BarkerPreambleMode = 0x04, +}; + +struct rtllib_network { + /* These entries are used to identify a unique network */ + u8 bssid[ETH_ALEN]; + u8 channel; + /* Ensure null-terminated for any debug msgs */ + u8 ssid[IW_ESSID_MAX_SIZE + 1]; + u8 ssid_len; + u8 hidden_ssid[IW_ESSID_MAX_SIZE + 1]; + u8 hidden_ssid_len; + struct rtllib_qos_data qos_data; + + bool bWithAironetIE; + bool bCkipSupported; + bool bCcxRmEnable; + u16 CcxRmState[2]; + bool bMBssidValid; + u8 MBssidMask; + u8 MBssid[6]; + bool bWithCcxVerNum; + u8 BssCcxVerNumber; + /* These are network statistics */ + struct rtllib_rx_stats stats; + u16 capability; + u8 rates[MAX_RATES_LENGTH]; + u8 rates_len; + u8 rates_ex[MAX_RATES_EX_LENGTH]; + u8 rates_ex_len; + unsigned long last_scanned; + u8 mode; + u32 flags; + u32 last_associate; + u32 time_stamp[2]; + u16 beacon_interval; + u16 listen_interval; + u16 atim_window; + u8 erp_value; + u8 wpa_ie[MAX_WPA_IE_LEN]; + size_t wpa_ie_len; + u8 rsn_ie[MAX_WPA_IE_LEN]; + size_t rsn_ie_len; + u8 wzc_ie[MAX_WZC_IE_LEN]; + size_t wzc_ie_len; + + struct rtllib_tim_parameters tim; + u8 dtim_period; + u8 dtim_data; + u64 last_dtim_sta_time; + + u8 wmm_info; + struct rtllib_wmm_ac_param wmm_param[4]; + u8 Turbo_Enable; + u16 CountryIeLen; + u8 CountryIeBuf[MAX_IE_LEN]; + struct bss_ht bssht; + bool broadcom_cap_exist; + bool realtek_cap_exit; + bool marvell_cap_exist; + bool ralink_cap_exist; + bool atheros_cap_exist; + bool cisco_cap_exist; + bool airgo_cap_exist; + bool unknown_cap_exist; + bool berp_info_valid; + bool buseprotection; + bool bIsNetgear854T; + u8 SignalStrength; + u8 RSSI; + struct list_head list; +}; + +#if 1 +enum rtllib_state { + + /* the card is not linked at all */ + RTLLIB_NOLINK = 0, + + /* RTLLIB_ASSOCIATING* are for BSS client mode + * the driver shall not perform RX filtering unless + * the state is LINKED. + * The driver shall just check for the state LINKED and + * defaults to NOLINK for ALL the other states (including + * LINKED_SCANNING) + */ + + /* the association procedure will start (wq scheduling)*/ + RTLLIB_ASSOCIATING, + RTLLIB_ASSOCIATING_RETRY, + + /* the association procedure is sending AUTH request*/ + RTLLIB_ASSOCIATING_AUTHENTICATING, + + /* the association procedure has successfully authentcated + * and is sending association request + */ + RTLLIB_ASSOCIATING_AUTHENTICATED, + + /* the link is ok. the card associated to a BSS or linked + * to a ibss cell or acting as an AP and creating the bss + */ + RTLLIB_LINKED, + + /* same as LINKED, but the driver shall apply RX filter + * rules as we are in NO_LINK mode. As the card is still + * logically linked, but it is doing a syncro site survey + * then it will be back to LINKED state. + */ + RTLLIB_LINKED_SCANNING, +}; +#else +enum rtllib_state { + RTLLIB_UNINITIALIZED = 0, + RTLLIB_INITIALIZED, + RTLLIB_ASSOCIATING, + RTLLIB_ASSOCIATED, + RTLLIB_AUTHENTICATING, + RTLLIB_AUTHENTICATED, + RTLLIB_SHUTDOWN +}; +#endif + +#define DEFAULT_MAX_SCAN_AGE (15 * HZ) +#define DEFAULT_FTS 2346 + +#define CFG_RTLLIB_RESERVE_FCS (1<<0) +#define CFG_RTLLIB_COMPUTE_FCS (1<<1) +#define CFG_RTLLIB_RTS (1<<2) + +#define RTLLIB_24GHZ_MIN_CHANNEL 1 +#define RTLLIB_24GHZ_MAX_CHANNEL 14 +#define RTLLIB_24GHZ_CHANNELS (RTLLIB_24GHZ_MAX_CHANNEL - \ + RTLLIB_24GHZ_MIN_CHANNEL + 1) + +#define RTLLIB_52GHZ_MIN_CHANNEL 34 +#define RTLLIB_52GHZ_MAX_CHANNEL 165 +#define RTLLIB_52GHZ_CHANNELS (RTLLIB_52GHZ_MAX_CHANNEL - \ + RTLLIB_52GHZ_MIN_CHANNEL + 1) +#ifndef eqMacAddr +#define eqMacAddr(a, b) \ + (((a)[0] == (b)[0] && (a)[1] == (b)[1] && (a)[2] == (b)[2] && \ + (a)[3] == (b)[3] && (a)[4] == (b)[4] && (a)[5] == (b)[5]) ? 1 : 0) +#endif +struct tx_pending { + int frag; + struct rtllib_txb *txb; +}; + +struct bandwidth_autoswitch { + long threshold_20Mhzto40Mhz; + long threshold_40Mhzto20Mhz; + bool bforced_tx20Mhz; + bool bautoswitch_enable; +}; + + + +#define REORDER_WIN_SIZE 128 +#define REORDER_ENTRY_NUM 128 +struct rx_reorder_entry { + struct list_head List; + u16 SeqNum; + struct rtllib_rxb *prxb; +}; +enum fsync_state { + Default_Fsync, + HW_Fsync, + SW_Fsync +}; + +enum rt_ps_mode { + eActive, + eMaxPs, + eFastPs, + eAutoPs, +}; + +enum ips_callback_function { + IPS_CALLBACK_NONE = 0, + IPS_CALLBACK_MGNT_LINK_REQUEST = 1, + IPS_CALLBACK_JOIN_REQUEST = 2, +}; + +enum rt_join_action { + RT_JOIN_INFRA = 1, + RT_JOIN_IBSS = 2, + RT_START_IBSS = 3, + RT_NO_ACTION = 4, +}; + +struct ibss_parms { + u16 atimWin; +}; +#define MAX_NUM_RATES 264 + +enum rt_rf_power_state { + eRfOn, + eRfSleep, + eRfOff +}; + +#define MAX_SUPPORT_WOL_PATTERN_NUM 8 + +#define MAX_WOL_BIT_MASK_SIZE 16 +#define MAX_WOL_PATTERN_SIZE 128 + +enum wol_pattern_type { + eNetBIOS = 0, + eIPv4IPv6ARP, + eIPv4IPv6TCPSYN, + eMACIDOnly, + eNoDefined, +}; + +struct rt_pm_wol_info { + u32 PatternId; + u32 Mask[4]; + u16 CrcRemainder; + u8 WFMIndex; + enum wol_pattern_type PatternType; +}; + +struct rt_pwr_save_ctrl { + + bool bInactivePs; + bool bIPSModeBackup; + bool bHaltAdapterClkRQ; + bool bSwRfProcessing; + enum rt_rf_power_state eInactivePowerState; + struct work_struct InactivePsWorkItem; + struct timer_list InactivePsTimer; + + enum ips_callback_function ReturnPoint; + + bool bTmpBssDesc; + enum rt_join_action tmpJoinAction; + struct rtllib_network tmpBssDesc; + + bool bTmpScanOnly; + bool bTmpActiveScan; + bool bTmpFilterHiddenAP; + bool bTmpUpdateParms; + u8 tmpSsidBuf[33]; + struct octet_string tmpSsid2Scan; + bool bTmpSsid2Scan; + u8 tmpNetworkType; + u8 tmpChannelNumber; + u16 tmpBcnPeriod; + u8 tmpDtimPeriod; + u16 tmpmCap; + struct octet_string tmpSuppRateSet; + u8 tmpSuppRateBuf[MAX_NUM_RATES]; + bool bTmpSuppRate; + struct ibss_parms tmpIbpm; + bool bTmpIbpm; + + bool bLeisurePs; + u32 PowerProfile; + u8 LpsIdleCount; + u8 RegMaxLPSAwakeIntvl; + u8 LPSAwakeIntvl; + + u32 CurPsLevel; + u32 RegRfPsLevel; + + bool bFwCtrlLPS; + u8 FWCtrlPSMode; + + bool LinkReqInIPSRFOffPgs; + bool BufConnectinfoBefore; + + + bool bGpioRfSw; + + u8 RegAMDPciASPM; + + u8 oWLANMode; + struct rt_pm_wol_info PmWoLPatternInfo[MAX_SUPPORT_WOL_PATTERN_NUM]; + +}; + +#define RT_RF_CHANGE_SOURCE u32 + +#define RF_CHANGE_BY_SW BIT31 +#define RF_CHANGE_BY_HW BIT30 +#define RF_CHANGE_BY_PS BIT29 +#define RF_CHANGE_BY_IPS BIT28 +#define RF_CHANGE_BY_INIT 0 + +enum country_code_type { + COUNTRY_CODE_FCC = 0, + COUNTRY_CODE_IC = 1, + COUNTRY_CODE_ETSI = 2, + COUNTRY_CODE_SPAIN = 3, + COUNTRY_CODE_FRANCE = 4, + COUNTRY_CODE_MKK = 5, + COUNTRY_CODE_MKK1 = 6, + COUNTRY_CODE_ISRAEL = 7, + COUNTRY_CODE_TELEC = 8, + COUNTRY_CODE_MIC = 9, + COUNTRY_CODE_GLOBAL_DOMAIN = 10, + COUNTRY_CODE_WORLD_WIDE_13 = 11, + COUNTRY_CODE_TELEC_NETGEAR = 12, + COUNTRY_CODE_MAX +}; + +enum scan_op_backup_opt { + SCAN_OPT_BACKUP = 0, + SCAN_OPT_RESTORE, + SCAN_OPT_MAX +}; + +enum fw_cmd_io_type { + FW_CMD_DIG_ENABLE = 0, + FW_CMD_DIG_DISABLE = 1, + FW_CMD_DIG_HALT = 2, + FW_CMD_DIG_RESUME = 3, + FW_CMD_HIGH_PWR_ENABLE = 4, + FW_CMD_HIGH_PWR_DISABLE = 5, + FW_CMD_RA_RESET = 6, + FW_CMD_RA_ACTIVE = 7, + FW_CMD_RA_REFRESH_N = 8, + FW_CMD_RA_REFRESH_BG = 9, + FW_CMD_RA_INIT = 10, + FW_CMD_IQK_ENABLE = 11, + FW_CMD_TXPWR_TRACK_ENABLE = 12, + FW_CMD_TXPWR_TRACK_DISABLE = 13, + FW_CMD_TXPWR_TRACK_THERMAL = 14, + FW_CMD_PAUSE_DM_BY_SCAN = 15, + FW_CMD_RESUME_DM_BY_SCAN = 16, + FW_CMD_RA_REFRESH_N_COMB = 17, + FW_CMD_RA_REFRESH_BG_COMB = 18, + FW_CMD_ANTENNA_SW_ENABLE = 19, + FW_CMD_ANTENNA_SW_DISABLE = 20, + FW_CMD_TX_FEEDBACK_CCX_ENABLE = 21, + FW_CMD_LPS_ENTER = 22, + FW_CMD_LPS_LEAVE = 23, + FW_CMD_DIG_MODE_SS = 24, + FW_CMD_DIG_MODE_FA = 25, + FW_CMD_ADD_A2_ENTRY = 26, + FW_CMD_CTRL_DM_BY_DRIVER = 27, + FW_CMD_CTRL_DM_BY_DRIVER_NEW = 28, + FW_CMD_PAPE_CONTROL = 29, + FW_CMD_CHAN_SET = 30, +}; + +#define RT_MAX_LD_SLOT_NUM 10 +struct rt_link_detect { + + u32 NumRecvBcnInPeriod; + u32 NumRecvDataInPeriod; + + u32 RxBcnNum[RT_MAX_LD_SLOT_NUM]; + u32 RxDataNum[RT_MAX_LD_SLOT_NUM]; + u16 SlotNum; + u16 SlotIndex; + + u32 NumTxOkInPeriod; + u32 NumRxOkInPeriod; + u32 NumRxUnicastOkInPeriod; + bool bBusyTraffic; + bool bHigherBusyTraffic; + bool bHigherBusyRxTraffic; + u8 IdleCount; + u32 NumTxUnicastOkInPeriod; + u32 LastNumTxUnicast; + u32 LastNumRxUnicast; +}; + +struct sw_cam_table { + + u8 macaddr[6]; + bool bused; + u8 key_buf[16]; + u16 key_type; + u8 useDK; + u8 key_index; + +}; +#define TOTAL_CAM_ENTRY 32 +struct rate_adaptive { + u8 rate_adaptive_disabled; + u8 ratr_state; + u16 reserve; + + u32 high_rssi_thresh_for_ra; + u32 high2low_rssi_thresh_for_ra; + u8 low2high_rssi_thresh_for_ra40M; + u32 low_rssi_thresh_for_ra40M; + u8 low2high_rssi_thresh_for_ra20M; + u32 low_rssi_thresh_for_ra20M; + u32 upper_rssi_threshold_ratr; + u32 middle_rssi_threshold_ratr; + u32 low_rssi_threshold_ratr; + u32 low_rssi_threshold_ratr_40M; + u32 low_rssi_threshold_ratr_20M; + u8 ping_rssi_enable; + u32 ping_rssi_ratr; + u32 ping_rssi_thresh_for_ra; + u32 last_ratr; + u8 PreRATRState; + +}; +enum ratr_table_mode_8192s { + RATR_INX_WIRELESS_NGB = 0, + RATR_INX_WIRELESS_NG = 1, + RATR_INX_WIRELESS_NB = 2, + RATR_INX_WIRELESS_N = 3, + RATR_INX_WIRELESS_GB = 4, + RATR_INX_WIRELESS_G = 5, + RATR_INX_WIRELESS_B = 6, + RATR_INX_WIRELESS_MC = 7, + RATR_INX_WIRELESS_A = 8, +}; + +#define NUM_PMKID_CACHE 16 +struct rt_pmkid_list { + u8 bUsed; + u8 Bssid[6]; + u8 PMKID[16]; + u8 SsidBuf[33]; + u8 *ssid_octet; + u16 ssid_length; +}; + +struct rt_intel_promisc_mode { + bool bPromiscuousOn; + bool bFilterSourceStationFrame; +}; + + +/*************** DRIVER STATUS *****/ +#define STATUS_SCANNING 0 +#define STATUS_SCAN_HW 1 +#define STATUS_SCAN_ABORTING 2 +#define STATUS_SETTING_CHAN 3 +/*************** DRIVER STATUS *****/ + +enum { + NO_USE = 0, + USED = 1, + HW_SEC = 2, + SW_SEC = 3, +}; + +enum { + LPS_IS_WAKE = 0, + LPS_IS_SLEEP = 1, + LPS_WAIT_NULL_DATA_SEND = 2, +}; + +struct rtllib_device { + struct pci_dev *pdev; + struct net_device *dev; + struct rtllib_security sec; + + bool disable_mgnt_queue; + + unsigned long status; + short hwscan_ch_bk; + enum ht_extchnl_offset chan_offset_bk; + enum ht_channel_width bandwidth_bk; + u8 hwscan_sem_up; + u8 CntAfterLink; + + enum rt_op_mode OpMode; + + u8 VersionID; + /* The last AssocReq/Resp IEs */ + u8 *assocreq_ies, *assocresp_ies; + size_t assocreq_ies_len, assocresp_ies_len; + + bool b_customer_lenovo_id; + bool bForcedShowRxRate; + bool bForcedShowRateStill; + u8 SystemQueryDataRateCount; + bool bForcedBgMode; + bool bUseRAMask; + bool b1x1RecvCombine; + u8 RF_Type; + bool b1SSSupport; + + u8 hwsec_active; + bool is_silent_reset; + bool force_mic_error; + bool is_roaming; + bool ieee_up; + bool cannot_notify; + bool bSupportRemoteWakeUp; + enum rt_ps_mode dot11PowerSaveMode; + bool actscanning; + bool FirstIe_InScan; + bool be_scan_inprogress; + bool beinretry; + enum rt_rf_power_state eRFPowerState; + RT_RF_CHANGE_SOURCE RfOffReason; + bool is_set_key; + bool wx_set_enc; + struct rt_hi_throughput *pHTInfo; + spinlock_t bw_spinlock; + + spinlock_t reorder_spinlock; + u8 Regdot11HTOperationalRateSet[16]; + u8 Regdot11TxHTOperationalRateSet[16]; + u8 dot11HTOperationalRateSet[16]; + u8 RegHTSuppRateSet[16]; + u8 HTCurrentOperaRate; + u8 HTHighestOperaRate; + u8 MinSpaceCfg; + u8 MaxMssDensity; + u8 bTxDisableRateFallBack; + u8 bTxUseDriverAssingedRate; + u8 bTxEnableFwCalcDur; + atomic_t atm_chnlop; + atomic_t atm_swbw; + + struct list_head Tx_TS_Admit_List; + struct list_head Tx_TS_Pending_List; + struct list_head Tx_TS_Unused_List; + struct tx_ts_record TxTsRecord[TOTAL_TS_NUM]; + struct list_head Rx_TS_Admit_List; + struct list_head Rx_TS_Pending_List; + struct list_head Rx_TS_Unused_List; + struct rx_ts_record RxTsRecord[TOTAL_TS_NUM]; + struct rx_reorder_entry RxReorderEntry[128]; + struct list_head RxReorder_Unused_List; + u8 ForcedPriority; + + + /* Bookkeeping structures */ + struct net_device_stats stats; + struct rtllib_stats ieee_stats; + struct rtllib_softmac_stats softmac_stats; + + /* Probe / Beacon management */ + struct list_head network_free_list; + struct list_head network_list; + struct rtllib_network *networks; + int scans; + int scan_age; + + int iw_mode; /* operating mode (IW_MODE_*) */ + bool bNetPromiscuousMode; + struct rt_intel_promisc_mode IntelPromiscuousModeInfo; + + struct iw_spy_data spy_data; + + spinlock_t lock; + spinlock_t wpax_suitlist_lock; + + int tx_headroom; /* Set to size of any additional room needed at front + * of allocated Tx SKBs */ + u32 config; + + /* WEP and other encryption related settings at the device level */ + int open_wep; /* Set to 1 to allow unencrypted frames */ + int auth_mode; + int reset_on_keychange; /* Set to 1 if the HW needs to be reset on + * WEP key changes */ + + /* If the host performs {en,de}cryption, then set to 1 */ + int host_encrypt; + int host_encrypt_msdu; + int host_decrypt; + /* host performs multicast decryption */ + int host_mc_decrypt; + + /* host should strip IV and ICV from protected frames */ + /* meaningful only when hardware decryption is being used */ + int host_strip_iv_icv; + + int host_open_frag; + int host_build_iv; + int ieee802_1x; /* is IEEE 802.1X used */ + + /* WPA data */ + bool bHalfNMode; + bool bHalfWirelessN24GMode; + int wpa_enabled; + int drop_unencrypted; + int tkip_countermeasures; + int privacy_invoked; + size_t wpa_ie_len; + u8 *wpa_ie; + size_t wps_ie_len; + u8 *wps_ie; + u8 ap_mac_addr[6]; + u16 pairwise_key_type; + u16 group_key_type; + struct list_head crypt_deinit_list; + struct rtllib_crypt_data *crypt[WEP_KEYS]; + + int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */ + struct sw_cam_table swcamtable[TOTAL_CAM_ENTRY]; + struct timer_list crypt_deinit_timer; + int crypt_quiesced; + + int bcrx_sta_key; /* use individual keys to override default keys even + * with RX of broad/multicast frames */ + + struct rt_pmkid_list PMKIDList[NUM_PMKID_CACHE]; + + /* Fragmentation structures */ + struct rtllib_frag_entry frag_cache[17][RTLLIB_FRAG_CACHE_LEN]; + unsigned int frag_next_idx[17]; + u16 fts; /* Fragmentation Threshold */ +#define DEFAULT_RTS_THRESHOLD 2346U +#define MIN_RTS_THRESHOLD 1 +#define MAX_RTS_THRESHOLD 2346U + u16 rts; /* RTS threshold */ + + /* Association info */ + u8 bssid[ETH_ALEN]; + + /* This stores infos for the current network. + * Either the network we are associated in INFRASTRUCTURE + * or the network that we are creating in MASTER mode. + * ad-hoc is a mixture ;-). + * Note that in infrastructure mode, even when not associated, + * fields bssid and essid may be valid (if wpa_set and essid_set + * are true) as thy carry the value set by the user via iwconfig + */ + struct rtllib_network current_network; + + enum rtllib_state state; + + int short_slot; + int reg_mode; + int mode; /* A, B, G */ + int modulation; /* CCK, OFDM */ + int freq_band; /* 2.4Ghz, 5.2Ghz, Mixed */ + int abg_true; /* ABG flag */ + + /* used for forcing the ibss workqueue to terminate + * without wait for the syncro scan to terminate + */ + short sync_scan_hurryup; + u16 scan_watch_dog; + int perfect_rssi; + int worst_rssi; + + u16 prev_seq_ctl; /* used to drop duplicate frames */ + + /* map of allowed channels. 0 is dummy */ + void *pDot11dInfo; + bool bGlobalDomain; + u8 active_channel_map[MAX_CHANNEL_NUMBER+1]; + + u8 IbssStartChnl; + u8 ibss_maxjoin_chal; + + int rate; /* current rate */ + int basic_rate; + u32 currentRate; + + short active_scan; + + /* this contains flags for selectively enable softmac support */ + u16 softmac_features; + + /* if the sequence control field is not filled by HW */ + u16 seq_ctrl[5]; + + /* association procedure transaction sequence number */ + u16 associate_seq; + + /* AID for RTXed association responses */ + u16 assoc_id; + + /* power save mode related*/ + u8 ack_tx_to_ieee; + short ps; + short sta_sleep; + int ps_timeout; + int ps_period; + struct tasklet_struct ps_task; + u64 ps_time; + bool polling; + + short raw_tx; + /* used if IEEE_SOFTMAC_TX_QUEUE is set */ + short queue_stop; + short scanning_continue ; + short proto_started; + short proto_stoppping; + + struct semaphore wx_sem; + struct semaphore scan_sem; + struct semaphore ips_sem; + + spinlock_t mgmt_tx_lock; + spinlock_t beacon_lock; + + short beacon_txing; + + short wap_set; + short ssid_set; + + /* set on initialization */ + u8 qos_support; + unsigned int wmm_acm; + + /* for discarding duplicated packets in IBSS */ + struct list_head ibss_mac_hash[IEEE_IBSS_MAC_HASH_SIZE]; + + /* for discarding duplicated packets in BSS */ + u16 last_rxseq_num[17]; /* rx seq previous per-tid */ + u16 last_rxfrag_num[17];/* tx frag previous per-tid */ + unsigned long last_packet_time[17]; + + /* for PS mode */ + unsigned long last_rx_ps_time; + bool bAwakePktSent; + u8 LPSDelayCnt; + + /* used if IEEE_SOFTMAC_SINGLE_QUEUE is set */ + struct sk_buff *mgmt_queue_ring[MGMT_QUEUE_NUM]; + int mgmt_queue_head; + int mgmt_queue_tail; +#define RTLLIB_QUEUE_LIMIT 128 + u8 AsocRetryCount; + unsigned int hw_header; + struct sk_buff_head skb_waitQ[MAX_QUEUE_SIZE]; + struct sk_buff_head skb_aggQ[MAX_QUEUE_SIZE]; + struct sk_buff_head skb_drv_aggQ[MAX_QUEUE_SIZE]; + u32 sta_edca_param[4]; + bool aggregation; + bool enable_rx_imm_BA; + bool bibsscoordinator; + + bool bdynamic_txpower_enable; + + bool bCTSToSelfEnable; + u8 CTSToSelfTH; + + u32 fsync_time_interval; + u32 fsync_rate_bitmap; + u8 fsync_rssi_threshold; + bool bfsync_enable; + + u8 fsync_multiple_timeinterval; + u32 fsync_firstdiff_ratethreshold; + u32 fsync_seconddiff_ratethreshold; + enum fsync_state fsync_state; + bool bis_any_nonbepkts; + struct bandwidth_autoswitch bandwidth_auto_switch; + bool FwRWRF; + + struct rt_link_detect LinkDetectInfo; + bool bIsAggregateFrame; + struct rt_pwr_save_ctrl PowerSaveControl; + u8 amsdu_in_process; + + /* used if IEEE_SOFTMAC_TX_QUEUE is set */ + struct tx_pending tx_pending; + + /* used if IEEE_SOFTMAC_ASSOCIATE is set */ + struct timer_list associate_timer; + + /* used if IEEE_SOFTMAC_BEACONS is set */ + struct timer_list beacon_timer; + u8 need_sw_enc; + struct work_struct associate_complete_wq; + struct work_struct ips_leave_wq; + struct delayed_work associate_procedure_wq; + struct delayed_work softmac_scan_wq; + struct delayed_work softmac_hint11d_wq; + struct delayed_work associate_retry_wq; + struct delayed_work start_ibss_wq; + struct delayed_work hw_wakeup_wq; + struct delayed_work hw_sleep_wq; + struct delayed_work link_change_wq; + struct work_struct wx_sync_scan_wq; + + struct workqueue_struct *wq; + + /* Callback functions */ + void (*set_security)(struct net_device *dev, + struct rtllib_security *sec); + + /* Used to TX data frame by using txb structs. + * this is not used if in the softmac_features + * is set the flag IEEE_SOFTMAC_TX_QUEUE + */ + int (*hard_start_xmit)(struct rtllib_txb *txb, + struct net_device *dev); + + int (*reset_port)(struct net_device *dev); + int (*is_queue_full)(struct net_device *dev, int pri); + + int (*handle_management)(struct net_device *dev, + struct rtllib_network *network, u16 type); + int (*is_qos_active)(struct net_device *dev, struct sk_buff *skb); + + /* Softmac-generated frames (mamagement) are TXed via this + * callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is + * not set. As some cards may have different HW queues that + * one might want to use for data and management frames + * the option to have two callbacks might be useful. + * This fucntion can't sleep. + */ + int (*softmac_hard_start_xmit)(struct sk_buff *skb, + struct net_device *dev); + + /* used instead of hard_start_xmit (not softmac_hard_start_xmit) + * if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data + * frames. I the option IEEE_SOFTMAC_SINGLE_QUEUE is also set + * then also management frames are sent via this callback. + * This function can't sleep. + */ + void (*softmac_data_hard_start_xmit)(struct sk_buff *skb, + struct net_device *dev, int rate); + + /* stops the HW queue for DATA frames. Useful to avoid + * waste time to TX data frame when we are reassociating + * This function can sleep. + */ + void (*data_hard_stop)(struct net_device *dev); + + /* OK this is complementar to data_poll_hard_stop */ + void (*data_hard_resume)(struct net_device *dev); + + /* ask to the driver to retune the radio . + * This function can sleep. the driver should ensure + * the radio has been swithced before return. + */ + void (*set_chan)(struct net_device *dev, short ch); + + /* These are not used if the ieee stack takes care of + * scanning (IEEE_SOFTMAC_SCAN feature set). + * In this case only the set_chan is used. + * + * The syncro version is similar to the start_scan but + * does not return until all channels has been scanned. + * this is called in user context and should sleep, + * it is called in a work_queue when swithcing to ad-hoc mode + * or in behalf of iwlist scan when the card is associated + * and root user ask for a scan. + * the fucntion stop_scan should stop both the syncro and + * background scanning and can sleep. + * The fucntion start_scan should initiate the background + * scanning and can't sleep. + */ + void (*scan_syncro)(struct net_device *dev); + void (*start_scan)(struct net_device *dev); + void (*stop_scan)(struct net_device *dev); + + void (*rtllib_start_hw_scan)(struct net_device *dev); + void (*rtllib_stop_hw_scan)(struct net_device *dev); + + /* indicate the driver that the link state is changed + * for example it may indicate the card is associated now. + * Driver might be interested in this to apply RX filter + * rules or simply light the LINK led + */ + void (*link_change)(struct net_device *dev); + + /* these two function indicates to the HW when to start + * and stop to send beacons. This is used when the + * IEEE_SOFTMAC_BEACONS is not set. For now the + * stop_send_bacons is NOT guaranteed to be called only + * after start_send_beacons. + */ + void (*start_send_beacons)(struct net_device *dev); + void (*stop_send_beacons)(struct net_device *dev); + + /* power save mode related */ + void (*sta_wake_up)(struct net_device *dev); + void (*enter_sleep_state)(struct net_device *dev, u64 time); + short (*ps_is_queue_empty)(struct net_device *dev); + int (*handle_beacon)(struct net_device *dev, + struct rtllib_beacon *beacon, + struct rtllib_network *network); + int (*handle_assoc_response)(struct net_device *dev, + struct rtllib_assoc_response_frame *resp, + struct rtllib_network *network); + + + /* check whether Tx hw resouce available */ + short (*check_nic_enough_desc)(struct net_device *dev, int queue_index); + short (*get_nic_desc_num)(struct net_device *dev, int queue_index); + void (*SetBWModeHandler)(struct net_device *dev, + enum ht_channel_width Bandwidth, + enum ht_extchnl_offset Offset); + bool (*GetNmodeSupportBySecCfg)(struct net_device *dev); + void (*SetWirelessMode)(struct net_device *dev, u8 wireless_mode); + bool (*GetHalfNmodeSupportByAPsHandler)(struct net_device *dev); + u8 (*rtllib_ap_sec_type)(struct rtllib_device *ieee); + void (*HalUsbRxAggrHandler)(struct net_device *dev, bool Value); + void (*InitialGainHandler)(struct net_device *dev, u8 Operation); + bool (*SetFwCmdHandler)(struct net_device *dev, + enum fw_cmd_io_type FwCmdIO); + void (*UpdateHalRAMaskHandler)(struct net_device *dev, bool bMulticast, + u8 macId, u8 MimoPs, u8 WirelessMode, + u8 bCurTxBW40MHz, u8 rssi_level); + void (*UpdateBeaconInterruptHandler)(struct net_device *dev, + bool start); + void (*UpdateInterruptMaskHandler)(struct net_device *dev, u32 AddMSR, + u32 RemoveMSR); + u16 (*rtl_11n_user_show_rates)(struct net_device *dev); + void (*ScanOperationBackupHandler)(struct net_device *dev, + u8 Operation); + void (*LedControlHandler)(struct net_device *dev, + enum led_ctl_mode LedAction); + void (*SetHwRegHandler)(struct net_device *dev, u8 variable, u8 *val); + void (*GetHwRegHandler)(struct net_device *dev, u8 variable, u8 *val); + + void (*AllowAllDestAddrHandler)(struct net_device *dev, + bool bAllowAllDA, bool WriteIntoReg); + + void (*rtllib_ips_leave_wq) (struct net_device *dev); + void (*rtllib_ips_leave)(struct net_device *dev); + void (*LeisurePSLeave)(struct net_device *dev); + void (*rtllib_rfkill_poll)(struct net_device *dev); + + /* This must be the last item so that it points to the data + * allocated beyond this structure by alloc_rtllib */ + u8 priv[0]; +}; + +#define IEEE_A (1<<0) +#define IEEE_B (1<<1) +#define IEEE_G (1<<2) +#define IEEE_N_24G (1<<4) +#define IEEE_N_5G (1<<5) +#define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G) + +/* Generate a 802.11 header */ + +/* Uses the channel change callback directly + * instead of [start/stop] scan callbacks + */ +#define IEEE_SOFTMAC_SCAN (1<<2) + +/* Perform authentication and association handshake */ +#define IEEE_SOFTMAC_ASSOCIATE (1<<3) + +/* Generate probe requests */ +#define IEEE_SOFTMAC_PROBERQ (1<<4) + +/* Generate respones to probe requests */ +#define IEEE_SOFTMAC_PROBERS (1<<5) + +/* The ieee802.11 stack will manages the netif queue + * wake/stop for the driver, taking care of 802.11 + * fragmentation. See softmac.c for details. */ +#define IEEE_SOFTMAC_TX_QUEUE (1<<7) + +/* Uses only the softmac_data_hard_start_xmit + * even for TX management frames. + */ +#define IEEE_SOFTMAC_SINGLE_QUEUE (1<<8) + +/* Generate beacons. The stack will enqueue beacons + * to the card + */ +#define IEEE_SOFTMAC_BEACONS (1<<6) + + +static inline void *rtllib_priv(struct net_device *dev) +{ + return ((struct rtllib_device *)netdev_priv(dev))->priv; +} + +extern inline int rtllib_is_empty_essid(const char *essid, int essid_len) +{ + /* Single white space is for Linksys APs */ + if (essid_len == 1 && essid[0] == ' ') + return 1; + + /* Otherwise, if the entire essid is 0, we assume it is hidden */ + while (essid_len) { + essid_len--; + if (essid[essid_len] != '\0') + return 0; + } + + return 1; +} + +extern inline int rtllib_is_valid_mode(struct rtllib_device *ieee, int mode) +{ + /* + * It is possible for both access points and our device to support + * combinations of modes, so as long as there is one valid combination + * of ap/device supported modes, then return success + * + */ + if ((mode & IEEE_A) && + (ieee->modulation & RTLLIB_OFDM_MODULATION) && + (ieee->freq_band & RTLLIB_52GHZ_BAND)) + return 1; + + if ((mode & IEEE_G) && + (ieee->modulation & RTLLIB_OFDM_MODULATION) && + (ieee->freq_band & RTLLIB_24GHZ_BAND)) + return 1; + + if ((mode & IEEE_B) && + (ieee->modulation & RTLLIB_CCK_MODULATION) && + (ieee->freq_band & RTLLIB_24GHZ_BAND)) + return 1; + + return 0; +} + +extern inline int rtllib_get_hdrlen(u16 fc) +{ + int hdrlen = RTLLIB_3ADDR_LEN; + + switch (WLAN_FC_GET_TYPE(fc)) { + case RTLLIB_FTYPE_DATA: + if ((fc & RTLLIB_FCTL_FROMDS) && (fc & RTLLIB_FCTL_TODS)) + hdrlen = RTLLIB_4ADDR_LEN; /* Addr4 */ + if (RTLLIB_QOS_HAS_SEQ(fc)) + hdrlen += 2; /* QOS ctrl*/ + break; + case RTLLIB_FTYPE_CTL: + switch (WLAN_FC_GET_STYPE(fc)) { + case RTLLIB_STYPE_CTS: + case RTLLIB_STYPE_ACK: + hdrlen = RTLLIB_1ADDR_LEN; + break; + default: + hdrlen = RTLLIB_2ADDR_LEN; + break; + } + break; + } + + return hdrlen; +} + +static inline u8 *rtllib_get_payload(struct rtllib_hdr *hdr) +{ + switch (rtllib_get_hdrlen(le16_to_cpu(hdr->frame_ctl))) { + case RTLLIB_1ADDR_LEN: + return ((struct rtllib_hdr_1addr *)hdr)->payload; + case RTLLIB_2ADDR_LEN: + return ((struct rtllib_hdr_2addr *)hdr)->payload; + case RTLLIB_3ADDR_LEN: + return ((struct rtllib_hdr_3addr *)hdr)->payload; + case RTLLIB_4ADDR_LEN: + return ((struct rtllib_hdr_4addr *)hdr)->payload; + } + return NULL; +} + +static inline int rtllib_is_ofdm_rate(u8 rate) +{ + switch (rate & ~RTLLIB_BASIC_RATE_MASK) { + case RTLLIB_OFDM_RATE_6MB: + case RTLLIB_OFDM_RATE_9MB: + case RTLLIB_OFDM_RATE_12MB: + case RTLLIB_OFDM_RATE_18MB: + case RTLLIB_OFDM_RATE_24MB: + case RTLLIB_OFDM_RATE_36MB: + case RTLLIB_OFDM_RATE_48MB: + case RTLLIB_OFDM_RATE_54MB: + return 1; + } + return 0; +} + +static inline int rtllib_is_cck_rate(u8 rate) +{ + switch (rate & ~RTLLIB_BASIC_RATE_MASK) { + case RTLLIB_CCK_RATE_1MB: + case RTLLIB_CCK_RATE_2MB: + case RTLLIB_CCK_RATE_5MB: + case RTLLIB_CCK_RATE_11MB: + return 1; + } + return 0; +} + + +/* rtllib.c */ +extern void free_rtllib(struct net_device *dev); +extern struct net_device *alloc_rtllib(int sizeof_priv); + +extern int rtllib_set_encryption(struct rtllib_device *ieee); + +/* rtllib_tx.c */ + +extern int rtllib_encrypt_fragment( + struct rtllib_device *ieee, + struct sk_buff *frag, + int hdr_len); + +extern int rtllib_xmit(struct sk_buff *skb, struct net_device *dev); +extern int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev); +extern void rtllib_txb_free(struct rtllib_txb *); + +/* rtllib_rx.c */ +extern int rtllib_rx(struct rtllib_device *ieee, struct sk_buff *skb, + struct rtllib_rx_stats *rx_stats); +extern void rtllib_rx_mgt(struct rtllib_device *ieee, + struct sk_buff *skb, + struct rtllib_rx_stats *stats); +extern void rtllib_rx_probe_rq(struct rtllib_device *ieee, + struct sk_buff *skb); +extern int IsLegalChannel(struct rtllib_device *rtllib, u8 channel); + +/* rtllib_wx.c */ +extern int rtllib_wx_get_scan(struct rtllib_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *key); +extern int rtllib_wx_set_encode(struct rtllib_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *key); +extern int rtllib_wx_get_encode(struct rtllib_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *key); +#if WIRELESS_EXT >= 18 +extern int rtllib_wx_get_encode_ext(struct rtllib_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); +extern int rtllib_wx_set_encode_ext(struct rtllib_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); +#endif +extern int rtllib_wx_set_auth(struct rtllib_device *ieee, + struct iw_request_info *info, + struct iw_param *data, char *extra); +extern int rtllib_wx_set_mlme(struct rtllib_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); +extern int rtllib_wx_set_gen_ie(struct rtllib_device *ieee, u8 *ie, size_t len); + +/* rtllib_softmac.c */ +extern short rtllib_is_54g(struct rtllib_network *net); +extern short rtllib_is_shortslot(struct rtllib_network net); +extern int rtllib_rx_frame_softmac(struct rtllib_device *ieee, + struct sk_buff *skb, + struct rtllib_rx_stats *rx_stats, u16 type, + u16 stype); +extern void rtllib_softmac_new_net(struct rtllib_device *ieee, + struct rtllib_network *net); + +void SendDisassociation(struct rtllib_device *ieee, bool deauth, u16 asRsn); +extern void rtllib_softmac_xmit(struct rtllib_txb *txb, + struct rtllib_device *ieee); + +extern void rtllib_stop_send_beacons(struct rtllib_device *ieee); +extern void notify_wx_assoc_event(struct rtllib_device *ieee); +extern void rtllib_softmac_check_all_nets(struct rtllib_device *ieee); +extern void rtllib_start_bss(struct rtllib_device *ieee); +extern void rtllib_start_master_bss(struct rtllib_device *ieee); +extern void rtllib_start_ibss(struct rtllib_device *ieee); +extern void rtllib_softmac_init(struct rtllib_device *ieee); +extern void rtllib_softmac_free(struct rtllib_device *ieee); +extern void rtllib_associate_abort(struct rtllib_device *ieee); +extern void rtllib_disassociate(struct rtllib_device *ieee); +extern void rtllib_stop_scan(struct rtllib_device *ieee); +extern bool rtllib_act_scanning(struct rtllib_device *ieee, bool sync_scan); +extern void rtllib_stop_scan_syncro(struct rtllib_device *ieee); +extern void rtllib_start_scan_syncro(struct rtllib_device *ieee, u8 is_mesh); +extern inline struct sk_buff *rtllib_probe_req(struct rtllib_device *ieee); +extern u8 MgntQuery_MgntFrameTxRate(struct rtllib_device *ieee); +extern void rtllib_sta_ps_send_null_frame(struct rtllib_device *ieee, + short pwr); +extern void rtllib_sta_wakeup(struct rtllib_device *ieee, short nl); +extern void rtllib_sta_ps_send_pspoll_frame(struct rtllib_device *ieee); +extern void rtllib_check_all_nets(struct rtllib_device *ieee); +extern void rtllib_start_protocol(struct rtllib_device *ieee); +extern void rtllib_stop_protocol(struct rtllib_device *ieee, u8 shutdown); + +extern void rtllib_EnableNetMonitorMode(struct net_device *dev, + bool bInitState); +extern void rtllib_DisableNetMonitorMode(struct net_device *dev, + bool bInitState); +extern void rtllib_EnableIntelPromiscuousMode(struct net_device *dev, + bool bInitState); +extern void rtllib_DisableIntelPromiscuousMode(struct net_device *dev, + bool bInitState); +extern void rtllib_send_probe_requests(struct rtllib_device *ieee, u8 is_mesh); + +extern void rtllib_softmac_stop_protocol(struct rtllib_device *ieee, + u8 mesh_flag, u8 shutdown); +extern void rtllib_softmac_start_protocol(struct rtllib_device *ieee, + u8 mesh_flag); + +extern void rtllib_reset_queue(struct rtllib_device *ieee); +extern void rtllib_wake_queue(struct rtllib_device *ieee); +extern void rtllib_stop_queue(struct rtllib_device *ieee); +extern void rtllib_wake_all_queues(struct rtllib_device *ieee); +extern void rtllib_stop_all_queues(struct rtllib_device *ieee); +extern struct sk_buff *rtllib_get_beacon(struct rtllib_device *ieee); +extern void rtllib_start_send_beacons(struct rtllib_device *ieee); +extern void rtllib_stop_send_beacons(struct rtllib_device *ieee); +extern int rtllib_wpa_supplicant_ioctl(struct rtllib_device *ieee, + struct iw_point *p, u8 is_mesh); + +extern void notify_wx_assoc_event(struct rtllib_device *ieee); +extern void rtllib_ps_tx_ack(struct rtllib_device *ieee, short success); + +extern void softmac_mgmt_xmit(struct sk_buff *skb, + struct rtllib_device *ieee); +extern u16 rtllib_query_seqnum(struct rtllib_device *ieee, + struct sk_buff *skb, u8 *dst); +extern u8 rtllib_ap_sec_type(struct rtllib_device *ieee); + +/* rtllib_crypt_ccmp&tkip&wep.c */ +extern void rtllib_tkip_null(void); +extern void rtllib_wep_null(void); +extern void rtllib_ccmp_null(void); + +/* rtllib_softmac_wx.c */ + +extern int rtllib_wx_get_wap(struct rtllib_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *ext); + +extern int rtllib_wx_set_wap(struct rtllib_device *ieee, + struct iw_request_info *info, + union iwreq_data *awrq, + char *extra); + +extern int rtllib_wx_get_essid(struct rtllib_device *ieee, + struct iw_request_info *a, + union iwreq_data *wrqu, char *b); + +extern int rtllib_wx_set_rate(struct rtllib_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int rtllib_wx_get_rate(struct rtllib_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int rtllib_wx_set_mode(struct rtllib_device *ieee, + struct iw_request_info *a, + union iwreq_data *wrqu, char *b); + +extern int rtllib_wx_set_scan(struct rtllib_device *ieee, + struct iw_request_info *a, + union iwreq_data *wrqu, char *b); + +extern int rtllib_wx_set_essid(struct rtllib_device *ieee, + struct iw_request_info *a, + union iwreq_data *wrqu, char *extra); + +extern int rtllib_wx_get_mode(struct rtllib_device *ieee, + struct iw_request_info *a, + union iwreq_data *wrqu, char *b); + +extern int rtllib_wx_set_freq(struct rtllib_device *ieee, + struct iw_request_info *a, + union iwreq_data *wrqu, char *b); + +extern int rtllib_wx_get_freq(struct rtllib_device *ieee, + struct iw_request_info *a, + union iwreq_data *wrqu, char *b); +extern void rtllib_wx_sync_scan_wq(void *data); + +extern int rtllib_wx_set_rawtx(struct rtllib_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int rtllib_wx_get_name(struct rtllib_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int rtllib_wx_set_power(struct rtllib_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int rtllib_wx_get_power(struct rtllib_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int rtllib_wx_set_rts(struct rtllib_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); + +extern int rtllib_wx_get_rts(struct rtllib_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra); +#define MAX_RECEIVE_BUFFER_SIZE 9100 +extern void HTDebugHTCapability(u8 *CapIE, u8 *TitleString); +extern void HTDebugHTInfo(u8 *InfoIE, u8 *TitleString); + +void HTSetConnectBwMode(struct rtllib_device *ieee, + enum ht_channel_width Bandwidth, + enum ht_extchnl_offset Offset); +extern void HTUpdateDefaultSetting(struct rtllib_device *ieee); +extern void HTConstructCapabilityElement(struct rtllib_device *ieee, + u8 *posHTCap, u8 *len, + u8 isEncrypt, bool bAssoc); +extern void HTConstructInfoElement(struct rtllib_device *ieee, + u8 *posHTInfo, u8 *len, u8 isEncrypt); +extern void HTConstructRT2RTAggElement(struct rtllib_device *ieee, + u8 *posRT2RTAgg, u8* len); +extern void HTOnAssocRsp(struct rtllib_device *ieee); +extern void HTInitializeHTInfo(struct rtllib_device *ieee); +extern void HTInitializeBssDesc(struct bss_ht *pBssHT); +extern void HTResetSelfAndSavePeerSetting(struct rtllib_device *ieee, + struct rtllib_network *pNetwork); +extern void HTUpdateSelfAndPeerSetting(struct rtllib_device *ieee, + struct rtllib_network *pNetwork); +extern u8 HTGetHighestMCSRate(struct rtllib_device *ieee, u8 *pMCSRateSet, + u8 *pMCSFilter); +extern u8 MCS_FILTER_ALL[]; +extern u16 MCS_DATA_RATE[2][2][77] ; +extern u8 HTCCheck(struct rtllib_device *ieee, u8 *pFrame); +extern void HTResetIOTSetting(struct rt_hi_throughput *pHTInfo); +extern bool IsHTHalfNmodeAPs(struct rtllib_device *ieee); +extern u16 HTHalfMcsToDataRate(struct rtllib_device *ieee, u8 nMcsRate); +extern u16 HTMcsToDataRate(struct rtllib_device *ieee, u8 nMcsRate); +extern u16 TxCountToDataRate(struct rtllib_device *ieee, u8 nDataRate); +extern int rtllib_rx_ADDBAReq(struct rtllib_device *ieee, struct sk_buff *skb); +extern int rtllib_rx_ADDBARsp(struct rtllib_device *ieee, struct sk_buff *skb); +extern int rtllib_rx_DELBA(struct rtllib_device *ieee, struct sk_buff *skb); +extern void TsInitAddBA(struct rtllib_device *ieee, struct tx_ts_record *pTS, + u8 Policy, u8 bOverwritePending); +extern void TsInitDelBA(struct rtllib_device *ieee, + struct ts_common_info *pTsCommonInfo, + enum tr_select TxRxSelect); +extern void BaSetupTimeOut(unsigned long data); +extern void TxBaInactTimeout(unsigned long data); +extern void RxBaInactTimeout(unsigned long data); +extern void ResetBaEntry(struct ba_record *pBA); +extern bool GetTs( + struct rtllib_device *ieee, + struct ts_common_info **ppTS, + u8 *Addr, + u8 TID, + enum tr_select TxRxSelect, + bool bAddNewTs +); +extern void TSInitialize(struct rtllib_device *ieee); +extern void TsStartAddBaProcess(struct rtllib_device *ieee, + struct tx_ts_record *pTxTS); +extern void RemovePeerTS(struct rtllib_device *ieee, u8 *Addr); +extern void RemoveAllTS(struct rtllib_device *ieee); +void rtllib_softmac_scan_syncro(struct rtllib_device *ieee, u8 is_mesh); + +extern const long rtllib_wlan_frequencies[]; + +extern inline void rtllib_increment_scans(struct rtllib_device *ieee) +{ + ieee->scans++; +} + +extern inline int rtllib_get_scans(struct rtllib_device *ieee) +{ + return ieee->scans; +} + +static inline const char *escape_essid(const char *essid, u8 essid_len) +{ + static char escaped[IW_ESSID_MAX_SIZE * 2 + 1]; + const char *s = essid; + char *d = escaped; + + if (rtllib_is_empty_essid(essid, essid_len)) { + memcpy(escaped, "<hidden>", sizeof("<hidden>")); + return escaped; + } + + essid_len = min(essid_len, (u8)IW_ESSID_MAX_SIZE); + while (essid_len--) { + if (*s == '\0') { + *d++ = '\\'; + *d++ = '0'; + s++; + } else { + *d++ = *s++; + } + } + *d = '\0'; + return escaped; +} + +#define CONVERT_RATE(_ieee, _MGN_RATE) \ + ((_MGN_RATE < MGN_MCS0) ? (_MGN_RATE) : \ + (HTMcsToDataRate(_ieee, (u8)_MGN_RATE))) + +/* fun with the built-in rtllib stack... */ +int rtllib_init(void); +void rtllib_exit(void); +int rtllib_crypto_init(void); +void rtllib_crypto_deinit(void); +int rtllib_crypto_tkip_init(void); +void rtllib_crypto_tkip_exit(void); +int rtllib_crypto_ccmp_init(void); +void rtllib_crypto_ccmp_exit(void); +int rtllib_crypto_wep_init(void); +void rtllib_crypto_wep_exit(void); + +void rtllib_MgntDisconnectIBSS(struct rtllib_device *rtllib); +void rtllib_MlmeDisassociateRequest(struct rtllib_device *rtllib, u8 *asSta, + u8 asRsn); +void rtllib_MgntDisconnectAP(struct rtllib_device *rtllib, u8 asRsn); +bool rtllib_MgntDisconnect(struct rtllib_device *rtllib, u8 asRsn); + + +/* For the function is more related to hardware setting, it's better to use the + * ieee handler to refer to it. + */ +extern void rtllib_update_active_chan_map(struct rtllib_device *ieee); +extern void rtllib_FlushRxTsPendingPkts(struct rtllib_device *ieee, + struct rx_ts_record *pTS); +extern int rtllib_data_xmit(struct sk_buff *skb, struct net_device *dev); +extern int rtllib_parse_info_param(struct rtllib_device *ieee, + struct rtllib_info_element *info_element, + u16 length, + struct rtllib_network *network, + struct rtllib_rx_stats *stats); + +void rtllib_indicate_packets(struct rtllib_device *ieee, + struct rtllib_rxb **prxbIndicateArray, u8 index); +extern u8 HTFilterMCSRate(struct rtllib_device *ieee, u8 *pSupportMCS, + u8 *pOperateMCS); +extern void HTUseDefaultSetting(struct rtllib_device *ieee); +#define RT_ASOC_RETRY_LIMIT 5 +u8 MgntQuery_TxRateExcludeCCKRates(struct rtllib_device *ieee); +extern void rtllib_TURBO_Info(struct rtllib_device *ieee, u8 **tag_p); +#ifndef ENABLE_LOCK_DEBUG +#define SPIN_LOCK_IEEE(plock) spin_lock_irqsave((plock), flags) +#define SPIN_UNLOCK_IEEE(plock) spin_unlock_irqrestore((plock), flags) +#define SPIN_LOCK_IEEE_REORDER(plock) spin_lock_irqsave((plock), flags) +#define SPIN_UNLOCK_IEEE_REORDER(plock) spin_unlock_irqrestore((plock), flags) +#define SPIN_LOCK_IEEE_WPAX(plock) spin_lock_irqsave((plock), flags) +#define SPIN_UNLOCK_IEEE_WPAX(plock) spin_unlock_irqrestore((plock), flags) +#define SPIN_LOCK_IEEE_MGNTTX(plock) spin_lock_irqsave((plock), flags) +#define SPIN_UNLOCK_IEEE_MGNTTX(plock) spin_unlock_irqrestore((plock), flags) +#define SPIN_LOCK_IEEE_BCN(plock) spin_lock_irqsave((plock), flags) +#define SPIN_UNLOCK_IEEE_BCN(plock) spin_unlock_irqrestore((plock), flags) +#define SPIN_LOCK_MSH_STAINFO(plock) spin_lock_irqsave((plock), flags) +#define SPIN_UNLOCK_MSH_STAINFO(plock) spin_unlock_irqrestore((plock), flags) +#define SPIN_LOCK_MSH_PREQ(plock) spin_lock_irqsave((plock), flags) +#define SPIN_UNLOCK_MSH_PREQ(plock) spin_unlock_irqrestore((plock), flags) +#define SPIN_LOCK_MSH_QUEUE(plock) spin_lock_irqsave((plock), flags) +#define SPIN_UNLOCK_MSH_QUEUE(plock) spin_unlock_irqrestore((plock), flags) +#define SPIN_LOCK_PRIV_RFPS(plock) spin_lock_irqsave((plock), flags) +#define SPIN_UNLOCK_PRIV_RFPS(plock) spin_unlock_irqrestore((plock), flags) +#define SPIN_LOCK_PRIV_IRQTH(plock) spin_lock_irqsave((plock), flags) +#define SPIN_UNLOCK_PRIV_IRQTH(plock) spin_unlock_irqrestore((plock), flags) +#define SPIN_LOCK_PRIV_TX(plock) spin_lock_irqsave((plock), flags) +#define SPIN_UNLOCK_PRIV_TX(plock) spin_unlock_irqrestore((plock), flags) +#define SPIN_LOCK_PRIV_D3(plock) spin_lock_irqsave((plock), flags) +#define SPIN_UNLOCK_PRIV_D3(plock) spin_unlock_irqrestore((plock), flags) +#define SPIN_LOCK_PRIV_RF(plock) spin_lock_irqsave((plock), flags) +#define SPIN_UNLOCK_PRIV_RF(plock) spin_unlock_irqrestore((plock), flags) +#define SPIN_LOCK_PRIV_PS(plock) spin_lock_irqsave((plock), flags) +#define SPIN_UNLOCK_PRIV_PS(plock) spin_unlock_irqrestore((plock), flags) +#define SEM_DOWN_IEEE_WX(psem) down(psem) +#define SEM_UP_IEEE_WX(psem) up(psem) +#define SEM_DOWN_IEEE_SCAN(psem) down(psem) +#define SEM_UP_IEEE_SCAN(psem) up(psem) +#define SEM_DOWN_IEEE_IPS(psem) down(psem) +#define SEM_UP_IEEE_IPS(psem) up(psem) +#define SEM_DOWN_PRIV_WX(psem) down(psem) +#define SEM_UP_PRIV_WX(psem) up(psem) +#define SEM_DOWN_PRIV_RF(psem) down(psem) +#define SEM_UP_PRIV_RF(psem) up(psem) +#define MUTEX_LOCK_PRIV(pmutex) mutex_lock(pmutex) +#define MUTEX_UNLOCK_PRIV(pmutex) mutex_unlock(pmutex) +#endif +static inline void dump_buf(u8 *buf, u32 len) +{ + u32 i; + printk(KERN_INFO "-----------------Len %d----------------\n", len); + for (i = 0; i < len; i++) + printk("%2.2x-", *(buf+i)); + printk("\n"); +} +#endif /* RTLLIB_H */ diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8192e/rtllib_crypt.c index 61fd4ce..acda37b 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.c +++ b/drivers/staging/rtl8192e/rtllib_crypt.c @@ -11,41 +11,37 @@ * */ -//#include <linux/config.h> +#include <linux/version.h> #include <linux/module.h> #include <linux/init.h> #include <linux/slab.h> -#include <asm/string.h> -#include <asm/errno.h> +#include <linux/string.h> +#include <linux/errno.h> -#include "ieee80211.h" +#include "rtllib.h" -//MODULE_AUTHOR("Jouni Malinen"); -//MODULE_DESCRIPTION("HostAP crypto"); -//MODULE_LICENSE("GPL"); - -struct ieee80211_crypto_alg { +struct rtllib_crypto_alg { struct list_head list; - struct ieee80211_crypto_ops *ops; + struct rtllib_crypto_ops *ops; }; -struct ieee80211_crypto { +struct rtllib_crypto { struct list_head algs; spinlock_t lock; }; -static struct ieee80211_crypto *hcrypt; +static struct rtllib_crypto *hcrypt; -void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, +void rtllib_crypt_deinit_entries(struct rtllib_device *ieee, int force) { struct list_head *ptr, *n; - struct ieee80211_crypt_data *entry; + struct rtllib_crypt_data *entry; for (ptr = ieee->crypt_deinit_list.next, n = ptr->next; ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) { - entry = list_entry(ptr, struct ieee80211_crypt_data, list); + entry = list_entry(ptr, struct rtllib_crypt_data, list); if (atomic_read(&entry->refcnt) != 0 && !force) continue; @@ -58,13 +54,13 @@ void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, } } -void ieee80211_crypt_deinit_handler(unsigned long data) +void rtllib_crypt_deinit_handler(unsigned long data) { - struct ieee80211_device *ieee = (struct ieee80211_device *)data; + struct rtllib_device *ieee = (struct rtllib_device *)data; unsigned long flags; spin_lock_irqsave(&ieee->lock, flags); - ieee80211_crypt_deinit_entries(ieee, 0); + rtllib_crypt_deinit_entries(ieee, 0); if (!list_empty(&ieee->crypt_deinit_list)) { printk(KERN_DEBUG "%s: entries remaining in delayed crypt " "deletion list\n", ieee->dev->name); @@ -75,10 +71,10 @@ void ieee80211_crypt_deinit_handler(unsigned long data) } -void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee, - struct ieee80211_crypt_data **crypt) +void rtllib_crypt_delayed_deinit(struct rtllib_device *ieee, + struct rtllib_crypt_data **crypt) { - struct ieee80211_crypt_data *tmp; + struct rtllib_crypt_data *tmp; unsigned long flags; if (*crypt == NULL) @@ -100,43 +96,44 @@ void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee, spin_unlock_irqrestore(&ieee->lock, flags); } -int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops) +int rtllib_register_crypto_ops(struct rtllib_crypto_ops *ops) { unsigned long flags; - struct ieee80211_crypto_alg *alg; + struct rtllib_crypto_alg *alg; if (hcrypt == NULL) return -1; - alg = kzalloc(sizeof(*alg), GFP_KERNEL); + alg = kmalloc(sizeof(*alg), GFP_KERNEL); if (alg == NULL) return -ENOMEM; + memset(alg, 0, sizeof(*alg)); alg->ops = ops; spin_lock_irqsave(&hcrypt->lock, flags); list_add(&alg->list, &hcrypt->algs); spin_unlock_irqrestore(&hcrypt->lock, flags); - printk(KERN_DEBUG "ieee80211_crypt: registered algorithm '%s'\n", + printk(KERN_DEBUG "rtllib_crypt: registered algorithm '%s'\n", ops->name); return 0; } -int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops) +int rtllib_unregister_crypto_ops(struct rtllib_crypto_ops *ops) { unsigned long flags; struct list_head *ptr; - struct ieee80211_crypto_alg *del_alg = NULL; + struct rtllib_crypto_alg *del_alg = NULL; if (hcrypt == NULL) return -1; spin_lock_irqsave(&hcrypt->lock, flags); for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) { - struct ieee80211_crypto_alg *alg = - (struct ieee80211_crypto_alg *) ptr; + struct rtllib_crypto_alg *alg = + (struct rtllib_crypto_alg *) ptr; if (alg->ops == ops) { list_del(&alg->list); del_alg = alg; @@ -146,7 +143,7 @@ int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops) spin_unlock_irqrestore(&hcrypt->lock, flags); if (del_alg) { - printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm " + printk(KERN_DEBUG "rtllib_crypt: unregistered algorithm " "'%s'\n", ops->name); kfree(del_alg); } @@ -155,19 +152,19 @@ int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops) } -struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name) +struct rtllib_crypto_ops *rtllib_get_crypto_ops(const char *name) { unsigned long flags; struct list_head *ptr; - struct ieee80211_crypto_alg *found_alg = NULL; + struct rtllib_crypto_alg *found_alg = NULL; if (hcrypt == NULL) return NULL; spin_lock_irqsave(&hcrypt->lock, flags); for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) { - struct ieee80211_crypto_alg *alg = - (struct ieee80211_crypto_alg *) ptr; + struct rtllib_crypto_alg *alg = + (struct rtllib_crypto_alg *) ptr; if (strcmp(alg->ops->name, name) == 0) { found_alg = alg; break; @@ -182,13 +179,13 @@ struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name) } -static void * ieee80211_crypt_null_init(int keyidx) { return (void *) 1; } -static void ieee80211_crypt_null_deinit(void *priv) {} +static void * rtllib_crypt_null_init(int keyidx) { return (void *) 1; } +static void rtllib_crypt_null_deinit(void *priv) {} -static struct ieee80211_crypto_ops ieee80211_crypt_null = { +static struct rtllib_crypto_ops rtllib_crypt_null = { .name = "NULL", - .init = ieee80211_crypt_null_init, - .deinit = ieee80211_crypt_null_deinit, + .init = rtllib_crypt_null_init, + .deinit = rtllib_crypt_null_deinit, .encrypt_mpdu = NULL, .decrypt_mpdu = NULL, .encrypt_msdu = NULL, @@ -201,18 +198,19 @@ static struct ieee80211_crypto_ops ieee80211_crypt_null = { }; -int __init ieee80211_crypto_init(void) +int __init rtllib_crypto_init(void) { int ret = -ENOMEM; - hcrypt = kzalloc(sizeof(*hcrypt), GFP_KERNEL); + hcrypt = kmalloc(sizeof(*hcrypt), GFP_KERNEL); if (!hcrypt) goto out; + memset(hcrypt, 0, sizeof(*hcrypt)); INIT_LIST_HEAD(&hcrypt->algs); spin_lock_init(&hcrypt->lock); - ret = ieee80211_register_crypto_ops(&ieee80211_crypt_null); + ret = rtllib_register_crypto_ops(&rtllib_crypt_null); if (ret < 0) { kfree(hcrypt); hcrypt = NULL; @@ -222,7 +220,7 @@ out: } -void ieee80211_crypto_deinit(void) +void __exit rtllib_crypto_deinit(void) { struct list_head *ptr, *n; @@ -231,14 +229,13 @@ void ieee80211_crypto_deinit(void) for (ptr = hcrypt->algs.next, n = ptr->next; ptr != &hcrypt->algs; ptr = n, n = ptr->next) { - struct ieee80211_crypto_alg *alg = - (struct ieee80211_crypto_alg *) ptr; + struct rtllib_crypto_alg *alg = + (struct rtllib_crypto_alg *) ptr; list_del(ptr); - printk(KERN_DEBUG "ieee80211_crypt: unregistered algorithm " + printk(KERN_DEBUG "rtllib_crypt: unregistered algorithm " "'%s' (deinit)\n", alg->ops->name); kfree(alg); } kfree(hcrypt); } - diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.h b/drivers/staging/rtl8192e/rtllib_crypt.h index ca7dd0d..49b90b7 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt.h +++ b/drivers/staging/rtl8192e/rtllib_crypt.h @@ -18,14 +18,14 @@ */ /* - * This file defines the interface to the ieee80211 crypto module. + * This file defines the interface to the rtllib crypto module. */ -#ifndef IEEE80211_CRYPT_H -#define IEEE80211_CRYPT_H +#ifndef RTLLIB_CRYPT_H +#define RTLLIB_CRYPT_H #include <linux/skbuff.h> -struct ieee80211_crypto_ops { +struct rtllib_crypto_ops { const char *name; /* init new crypto context (e.g., allocate private data space, @@ -49,7 +49,7 @@ struct ieee80211_crypto_ops { * These can be NULL if full MSDU operations are not needed. */ int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv); int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len, - void *priv); + void *priv, struct rtllib_device* ieee); int (*set_key)(void *key, int len, u8 *seq, void *priv); int (*get_key)(void *key, int len, u8 *seq, void *priv); @@ -61,25 +61,25 @@ struct ieee80211_crypto_ops { /* maximum number of bytes added by encryption; encrypt buf is * allocated with extra_prefix_len bytes, copy of in_buf, and * extra_postfix_len; encrypt need not use all this space, but - * the result must start at the beginning of the buffer and correct - * length must be returned */ + * the result must start at the beginning of the struct buffer and + * correct length must be returned */ int extra_prefix_len, extra_postfix_len; struct module *owner; }; -struct ieee80211_crypt_data { +struct rtllib_crypt_data { struct list_head list; /* delayed deletion list */ - struct ieee80211_crypto_ops *ops; + struct rtllib_crypto_ops *ops; void *priv; atomic_t refcnt; }; -int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops); -int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops); -struct ieee80211_crypto_ops * ieee80211_get_crypto_ops(const char *name); -void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int); -void ieee80211_crypt_deinit_handler(unsigned long); -void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee, - struct ieee80211_crypt_data **crypt); +int rtllib_register_crypto_ops(struct rtllib_crypto_ops *ops); +int rtllib_unregister_crypto_ops(struct rtllib_crypto_ops *ops); +struct rtllib_crypto_ops *rtllib_get_crypto_ops(const char *name); +void rtllib_crypt_deinit_entries(struct rtllib_device *, int); +void rtllib_crypt_deinit_handler(unsigned long); +void rtllib_crypt_delayed_deinit(struct rtllib_device *ieee, + struct rtllib_crypt_data **crypt); #endif diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8192e/rtllib_crypt_ccmp.c index 48267a0..6196b9a 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_ccmp.c +++ b/drivers/staging/rtl8192e/rtllib_crypt_ccmp.c @@ -9,7 +9,7 @@ * more details. */ -//#include <linux/config.h> +#include <linux/version.h> #include <linux/module.h> #include <linux/init.h> #include <linux/slab.h> @@ -18,22 +18,13 @@ #include <linux/netdevice.h> #include <linux/if_ether.h> #include <linux/if_arp.h> -#include <asm/string.h> +#include <linux/string.h> #include <linux/wireless.h> - -#include "ieee80211.h" +#include "rtllib.h" #include <linux/crypto.h> - #include <linux/scatterlist.h> - -MODULE_AUTHOR("Jouni Malinen"); -MODULE_DESCRIPTION("Host AP crypt: CCMP"); -MODULE_LICENSE("GPL"); - -#ifndef OPENSUSE_SLED -#define OPENSUSE_SLED 0 -#endif +#include <linux/scatterlist.h> #define AES_BLOCK_LEN 16 #define CCMP_HDR_LEN 8 @@ -41,7 +32,7 @@ MODULE_LICENSE("GPL"); #define CCMP_TK_LEN 16 #define CCMP_PN_LEN 6 -struct ieee80211_ccmp_data { +struct rtllib_ccmp_data { u8 key[CCMP_TK_LEN]; int key_set; @@ -62,24 +53,25 @@ struct ieee80211_ccmp_data { u8 rx_b0[AES_BLOCK_LEN], rx_b[AES_BLOCK_LEN], rx_a[AES_BLOCK_LEN]; }; -void ieee80211_ccmp_aes_encrypt(struct crypto_tfm *tfm, +static void rtllib_ccmp_aes_encrypt(struct crypto_tfm *tfm, const u8 pt[16], u8 ct[16]) { - crypto_cipher_encrypt_one((void*)tfm, ct, pt); + crypto_cipher_encrypt_one((void *)tfm, ct, pt); } -static void * ieee80211_ccmp_init(int key_idx) +static void *rtllib_ccmp_init(int key_idx) { - struct ieee80211_ccmp_data *priv; + struct rtllib_ccmp_data *priv; - priv = kzalloc(sizeof(*priv), GFP_ATOMIC); + priv = kmalloc(sizeof(*priv), GFP_ATOMIC); if (priv == NULL) goto fail; + memset(priv, 0, sizeof(*priv)); priv->key_idx = key_idx; - priv->tfm = (void*)crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); + priv->tfm = (void *)crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(priv->tfm)) { - printk(KERN_DEBUG "ieee80211_crypt_ccmp: could not allocate " + printk(KERN_DEBUG "rtllib_crypt_ccmp: could not allocate " "crypto API aes\n"); priv->tfm = NULL; goto fail; @@ -89,7 +81,7 @@ static void * ieee80211_ccmp_init(int key_idx) fail: if (priv) { if (priv->tfm) - crypto_free_cipher((void*)priv->tfm); + crypto_free_cipher((void *)priv->tfm); kfree(priv); } @@ -97,11 +89,11 @@ fail: } -static void ieee80211_ccmp_deinit(void *priv) +static void rtllib_ccmp_deinit(void *priv) { - struct ieee80211_ccmp_data *_priv = priv; + struct rtllib_ccmp_data *_priv = priv; if (_priv && _priv->tfm) - crypto_free_cipher((void*)_priv->tfm); + crypto_free_cipher((void *)_priv->tfm); kfree(priv); } @@ -116,7 +108,7 @@ static inline void xor_block(u8 *b, u8 *a, size_t len) static void ccmp_init_blocks(struct crypto_tfm *tfm, - struct ieee80211_hdr_4addr *hdr, + struct rtllib_hdr_4addr *hdr, u8 *pn, size_t dlen, u8 *b0, u8 *auth, u8 *s0) { @@ -127,14 +119,13 @@ static void ccmp_init_blocks(struct crypto_tfm *tfm, u8 aad[2 * AES_BLOCK_LEN]; fc = le16_to_cpu(hdr->frame_ctl); - a4_included = ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == - (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)); + a4_included = ((fc & (RTLLIB_FCTL_TODS | RTLLIB_FCTL_FROMDS)) == + (RTLLIB_FCTL_TODS | RTLLIB_FCTL_FROMDS)); /* - qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) && + qc_included = ((WLAN_FC_GET_TYPE(fc) == RTLLIB_FTYPE_DATA) && (WLAN_FC_GET_STYPE(fc) & 0x08)); - */ - // fixed by David :2006.9.6 - qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) && + */ + qc_included = ((WLAN_FC_GET_TYPE(fc) == RTLLIB_FTYPE_DATA) && (WLAN_FC_GET_STYPE(fc) & 0x80)); aad_len = 22; if (a4_included) @@ -183,26 +174,26 @@ static void ccmp_init_blocks(struct crypto_tfm *tfm, } /* Start with the first block and AAD */ - ieee80211_ccmp_aes_encrypt(tfm, b0, auth); + rtllib_ccmp_aes_encrypt(tfm, b0, auth); xor_block(auth, aad, AES_BLOCK_LEN); - ieee80211_ccmp_aes_encrypt(tfm, auth, auth); + rtllib_ccmp_aes_encrypt(tfm, auth, auth); xor_block(auth, &aad[AES_BLOCK_LEN], AES_BLOCK_LEN); - ieee80211_ccmp_aes_encrypt(tfm, auth, auth); + rtllib_ccmp_aes_encrypt(tfm, auth, auth); b0[0] &= 0x07; b0[14] = b0[15] = 0; - ieee80211_ccmp_aes_encrypt(tfm, b0, s0); + rtllib_ccmp_aes_encrypt(tfm, b0, s0); } -static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv) +static int rtllib_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv) { - struct ieee80211_ccmp_data *key = priv; + struct rtllib_ccmp_data *key = priv; int data_len, i; u8 *pos; - struct ieee80211_hdr_4addr *hdr; - cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); - + struct rtllib_hdr_4addr *hdr; + struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + + MAX_DEV_ADDR_SIZE); if (skb_headroom(skb) < CCMP_HDR_LEN || skb_tailroom(skb) < CCMP_MIC_LEN || skb->len < hdr_len) @@ -212,7 +203,6 @@ static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv) pos = skb_push(skb, CCMP_HDR_LEN); memmove(pos, pos + CCMP_HDR_LEN, hdr_len); pos += hdr_len; -// mic = skb_put(skb, CCMP_MIC_LEN); i = CCMP_PN_LEN - 1; while (i >= 0) { @@ -232,9 +222,8 @@ static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv) *pos++ = key->tx_pn[0]; - hdr = (struct ieee80211_hdr_4addr *) skb->data; - if (!tcb_desc->bHwSec) - { + hdr = (struct rtllib_hdr_4addr *) skb->data; + if (!tcb_desc->bHwSec) { int blocks, last, len; u8 *mic; u8 *b0 = key->tx_b0; @@ -242,10 +231,10 @@ static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv) u8 *e = key->tx_e; u8 *s0 = key->tx_s0; - //mic is moved to here by john mic = skb_put(skb, CCMP_MIC_LEN); - ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0); + ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, + b0, b, s0); blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN; last = data_len % AES_BLOCK_LEN; @@ -254,11 +243,11 @@ static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv) len = (i == blocks && last) ? last : AES_BLOCK_LEN; /* Authentication */ xor_block(b, pos, len); - ieee80211_ccmp_aes_encrypt(key->tfm, b, b); + rtllib_ccmp_aes_encrypt(key->tfm, b, b); /* Encryption, with counter */ b0[14] = (i >> 8) & 0xff; b0[15] = i & 0xff; - ieee80211_ccmp_aes_encrypt(key->tfm, b0, e); + rtllib_ccmp_aes_encrypt(key->tfm, b0, e); xor_block(pos, e, len); pos += len; } @@ -270,12 +259,13 @@ static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv) } -static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) +static int rtllib_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) { - struct ieee80211_ccmp_data *key = priv; + struct rtllib_ccmp_data *key = priv; u8 keyidx, *pos; - struct ieee80211_hdr_4addr *hdr; - cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); + struct rtllib_hdr_4addr *hdr; + struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + + MAX_DEV_ADDR_SIZE); u8 pn[6]; if (skb->len < hdr_len + CCMP_HDR_LEN + CCMP_MIC_LEN) { @@ -283,7 +273,7 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) return -1; } - hdr = (struct ieee80211_hdr_4addr *) skb->data; + hdr = (struct rtllib_hdr_4addr *) skb->data; pos = skb->data + hdr_len; keyidx = pos[3]; if (!(keyidx & (1 << 5))) { @@ -316,14 +306,13 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) pn[4] = pos[1]; pn[5] = pos[0]; pos += 8; - if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) { key->dot11RSNAStatsCCMPReplays++; return -4; } - if (!tcb_desc->bHwSec) - { - size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN - CCMP_MIC_LEN; + if (!tcb_desc->bHwSec) { + size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN - + CCMP_MIC_LEN; u8 *mic = skb->data + skb->len - CCMP_MIC_LEN; u8 *b0 = key->rx_b0; u8 *b = key->rx_b; @@ -342,18 +331,18 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) /* Decrypt, with counter */ b0[14] = (i >> 8) & 0xff; b0[15] = i & 0xff; - ieee80211_ccmp_aes_encrypt(key->tfm, b0, b); + rtllib_ccmp_aes_encrypt(key->tfm, b0, b); xor_block(pos, b, len); /* Authentication */ xor_block(a, pos, len); - ieee80211_ccmp_aes_encrypt(key->tfm, a, a); + rtllib_ccmp_aes_encrypt(key->tfm, a, a); pos += len; } if (memcmp(mic, a, CCMP_MIC_LEN) != 0) { if (net_ratelimit()) { printk(KERN_DEBUG "CCMP: decrypt failed: STA=" - "%pM\n", hdr->addr2); + " %pM\n", hdr->addr2); } key->dot11RSNAStatsCCMPDecryptErrors++; return -5; @@ -370,9 +359,9 @@ static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv) } -static int ieee80211_ccmp_set_key(void *key, int len, u8 *seq, void *priv) +static int rtllib_ccmp_set_key(void *key, int len, u8 *seq, void *priv) { - struct ieee80211_ccmp_data *data = priv; + struct rtllib_ccmp_data *data = priv; int keyidx; struct crypto_tfm *tfm = data->tfm; @@ -391,7 +380,7 @@ static int ieee80211_ccmp_set_key(void *key, int len, u8 *seq, void *priv) data->rx_pn[4] = seq[1]; data->rx_pn[5] = seq[0]; } - crypto_cipher_setkey((void*)data->tfm, data->key, CCMP_TK_LEN); + crypto_cipher_setkey((void *)data->tfm, data->key, CCMP_TK_LEN); } else if (len == 0) data->key_set = 0; else @@ -401,9 +390,9 @@ static int ieee80211_ccmp_set_key(void *key, int len, u8 *seq, void *priv) } -static int ieee80211_ccmp_get_key(void *key, int len, u8 *seq, void *priv) +static int rtllib_ccmp_get_key(void *key, int len, u8 *seq, void *priv) { - struct ieee80211_ccmp_data *data = priv; + struct rtllib_ccmp_data *data = priv; if (len < CCMP_TK_LEN) return -1; @@ -425,22 +414,14 @@ static int ieee80211_ccmp_get_key(void *key, int len, u8 *seq, void *priv) } -static char * ieee80211_ccmp_print_stats(char *p, void *priv) +static char *rtllib_ccmp_print_stats(char *p, void *priv) { - struct ieee80211_ccmp_data *ccmp = priv; - int i; - - p += sprintf(p, "key[%d] alg=CCMP key_set=%d tx_pn=", - ccmp->key_idx, ccmp->key_set); - - for (i = 0; i < ARRAY_SIZE(ccmp->tx_pn); i++) - p += sprintf(p, "%02x", ccmp->tx_pn[i]); - - sprintf(p, " rx_pn="); - for (i = 0; i < ARRAY_SIZE(ccmp->rx_pn); i++) - p += sprintf(p, "%02x", ccmp->tx_pn[i]); - - p += sprintf(p, " format_errors=%d replays=%d decrypt_errors=%d\n", + struct rtllib_ccmp_data *ccmp = priv; + p += sprintf(p, "key[%d] alg=CCMP key_set=%d " + "tx_pn=%pM rx_pn=%pM " + "format_errors=%d replays=%d decrypt_errors=%d\n", + ccmp->key_idx, ccmp->key_set, + ccmp->tx_pn, ccmp->rx_pn, ccmp->dot11RSNAStatsCCMPFormatErrors, ccmp->dot11RSNAStatsCCMPReplays, ccmp->dot11RSNAStatsCCMPDecryptErrors); @@ -448,36 +429,35 @@ static char * ieee80211_ccmp_print_stats(char *p, void *priv) return p; } -void ieee80211_ccmp_null(void) +void rtllib_ccmp_null(void) { return; } -static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = { +static struct rtllib_crypto_ops rtllib_crypt_ccmp = { .name = "CCMP", - .init = ieee80211_ccmp_init, - .deinit = ieee80211_ccmp_deinit, - .encrypt_mpdu = ieee80211_ccmp_encrypt, - .decrypt_mpdu = ieee80211_ccmp_decrypt, + .init = rtllib_ccmp_init, + .deinit = rtllib_ccmp_deinit, + .encrypt_mpdu = rtllib_ccmp_encrypt, + .decrypt_mpdu = rtllib_ccmp_decrypt, .encrypt_msdu = NULL, .decrypt_msdu = NULL, - .set_key = ieee80211_ccmp_set_key, - .get_key = ieee80211_ccmp_get_key, - .print_stats = ieee80211_ccmp_print_stats, + .set_key = rtllib_ccmp_set_key, + .get_key = rtllib_ccmp_get_key, + .print_stats = rtllib_ccmp_print_stats, .extra_prefix_len = CCMP_HDR_LEN, .extra_postfix_len = CCMP_MIC_LEN, .owner = THIS_MODULE, }; -int __init ieee80211_crypto_ccmp_init(void) +int __init rtllib_crypto_ccmp_init(void) { - return ieee80211_register_crypto_ops(&ieee80211_crypt_ccmp); + return rtllib_register_crypto_ops(&rtllib_crypt_ccmp); } -void ieee80211_crypto_ccmp_exit(void) +void __exit rtllib_crypto_ccmp_exit(void) { - ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp); + rtllib_unregister_crypto_ops(&rtllib_crypt_ccmp); } - diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8192e/rtllib_crypt_tkip.c index ed623a9..6a0c878 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_tkip.c +++ b/drivers/staging/rtl8192e/rtllib_crypt_tkip.c @@ -9,7 +9,7 @@ * more details. */ -//#include <linux/config.h> +#include <linux/version.h> #include <linux/module.h> #include <linux/init.h> #include <linux/slab.h> @@ -18,25 +18,14 @@ #include <linux/netdevice.h> #include <linux/if_ether.h> #include <linux/if_arp.h> -#include <asm/string.h> - -#include "ieee80211.h" - - +#include <linux/string.h> #include <linux/crypto.h> #include <linux/scatterlist.h> - #include <linux/crc32.h> -MODULE_AUTHOR("Jouni Malinen"); -MODULE_DESCRIPTION("Host AP crypt: TKIP"); -MODULE_LICENSE("GPL"); +#include "rtllib.h" -#ifndef OPENSUSE_SLED -#define OPENSUSE_SLED 0 -#endif - -struct ieee80211_tkip_data { +struct rtllib_tkip_data { #define TKIP_KEY_LEN 32 u8 key[TKIP_KEY_LEN]; int key_set; @@ -48,6 +37,7 @@ struct ieee80211_tkip_data { u32 rx_iv32; u16 rx_iv16; + bool initialized; u16 rx_ttak[5]; int rx_phase1_done; u32 rx_iv32_new; @@ -66,18 +56,19 @@ struct ieee80211_tkip_data { u8 rx_hdr[16], tx_hdr[16]; }; -static void * ieee80211_tkip_init(int key_idx) +static void *rtllib_tkip_init(int key_idx) { - struct ieee80211_tkip_data *priv; + struct rtllib_tkip_data *priv; - priv = kzalloc(sizeof(*priv), GFP_ATOMIC); + priv = kmalloc(sizeof(*priv), GFP_ATOMIC); if (priv == NULL) goto fail; + memset(priv, 0, sizeof(*priv)); priv->key_idx = key_idx; priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(priv->tx_tfm_arc4)) { - printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " + printk(KERN_DEBUG "rtllib_crypt_tkip: could not allocate " "crypto API arc4\n"); priv->tx_tfm_arc4 = NULL; goto fail; @@ -86,7 +77,7 @@ static void * ieee80211_tkip_init(int key_idx) priv->tx_tfm_michael = crypto_alloc_hash("michael_mic", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(priv->tx_tfm_michael)) { - printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " + printk(KERN_DEBUG "rtllib_crypt_tkip: could not allocate " "crypto API michael_mic\n"); priv->tx_tfm_michael = NULL; goto fail; @@ -95,7 +86,7 @@ static void * ieee80211_tkip_init(int key_idx) priv->rx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(priv->rx_tfm_arc4)) { - printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " + printk(KERN_DEBUG "rtllib_crypt_tkip: could not allocate " "crypto API arc4\n"); priv->rx_tfm_arc4 = NULL; goto fail; @@ -104,7 +95,7 @@ static void * ieee80211_tkip_init(int key_idx) priv->rx_tfm_michael = crypto_alloc_hash("michael_mic", 0, CRYPTO_ALG_ASYNC); if (IS_ERR(priv->rx_tfm_michael)) { - printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate " + printk(KERN_DEBUG "rtllib_crypt_tkip: could not allocate " "crypto API michael_mic\n"); priv->rx_tfm_michael = NULL; goto fail; @@ -128,9 +119,10 @@ fail: } -static void ieee80211_tkip_deinit(void *priv) +static void rtllib_tkip_deinit(void *priv) { - struct ieee80211_tkip_data *_priv = priv; + struct rtllib_tkip_data *_priv = priv; + if (_priv) { if (_priv->tx_tfm_michael) crypto_free_hash(_priv->tx_tfm_michael); @@ -187,8 +179,7 @@ static inline u16 Mk16_le(u16 *v) } -static const u16 Sbox[256] = -{ +static const u16 Sbox[256] = { 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154, 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A, 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B, @@ -303,14 +294,14 @@ static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK, } -static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) +static int rtllib_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) { - struct ieee80211_tkip_data *tkey = priv; + struct rtllib_tkip_data *tkey = priv; int len; u8 *pos; - struct ieee80211_hdr_4addr *hdr; - cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); - + struct rtllib_hdr_4addr *hdr; + struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + + MAX_DEV_ADDR_SIZE); struct blkcipher_desc desc = {.tfm = tkey->tx_tfm_arc4}; int ret = 0; u8 rc4key[16], *icv; @@ -321,18 +312,17 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) skb->len < hdr_len) return -1; - hdr = (struct ieee80211_hdr_4addr *) skb->data; + hdr = (struct rtllib_hdr_4addr *) skb->data; - if (!tcb_desc->bHwSec) - { + if (!tcb_desc->bHwSec) { if (!tkey->tx_phase1_done) { tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2, tkey->tx_iv32); tkey->tx_phase1_done = 1; } - tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16); - } - else + tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, + tkey->tx_iv16); + } else tkey->tx_phase1_done = 1; @@ -341,14 +331,11 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) memmove(pos, pos + 8, hdr_len); pos += hdr_len; - if (tcb_desc->bHwSec) - { + if (tcb_desc->bHwSec) { *pos++ = Hi8(tkey->tx_iv16); *pos++ = (Hi8(tkey->tx_iv16) | 0x20) & 0x7F; *pos++ = Lo8(tkey->tx_iv16); - } - else - { + } else { *pos++ = rc4key[0]; *pos++ = rc4key[1]; *pos++ = rc4key[2]; @@ -360,18 +347,19 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) *pos++ = (tkey->tx_iv32 >> 16) & 0xff; *pos++ = (tkey->tx_iv32 >> 24) & 0xff; - if (!tcb_desc->bHwSec) - { + if (!tcb_desc->bHwSec) { icv = skb_put(skb, 4); crc = ~crc32_le(~0, pos, len); icv[0] = crc; icv[1] = crc >> 8; icv[2] = crc >> 16; icv[3] = crc >> 24; - crypto_blkcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16); + sg_init_one(&sg, pos, len+4); - ret= crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4); + + crypto_blkcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16); + ret = crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4); } tkey->tx_iv16++; @@ -383,19 +371,20 @@ static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv) if (!tcb_desc->bHwSec) return ret; else - return 0; + return 0; } -static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) +static int rtllib_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) { - struct ieee80211_tkip_data *tkey = priv; + struct rtllib_tkip_data *tkey = priv; u8 keyidx, *pos; u32 iv32; u16 iv16; - struct ieee80211_hdr_4addr *hdr; - cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); + struct rtllib_hdr_4addr *hdr; + struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + + MAX_DEV_ADDR_SIZE); struct blkcipher_desc desc = {.tfm = tkey->rx_tfm_arc4}; u8 rc4key[16]; u8 icv[4]; @@ -405,7 +394,7 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (skb->len < hdr_len + 8 + 4) return -1; - hdr = (struct ieee80211_hdr_4addr *) skb->data; + hdr = (struct rtllib_hdr_4addr *) skb->data; pos = skb->data + hdr_len; keyidx = pos[3]; if (!(keyidx & (1 << 5))) { @@ -433,35 +422,38 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24); pos += 8; - if (!tcb_desc->bHwSec) - { - if (iv32 < tkey->rx_iv32 || - (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) { + if (!tcb_desc->bHwSec || (skb->cb[0] == 1)) { + if ((iv32 < tkey->rx_iv32 || + (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) && + tkey->initialized) { if (net_ratelimit()) { - printk(KERN_DEBUG "TKIP: replay detected: STA=%pM" - " previous TSC %08x%04x received TSC " - "%08x%04x\n", hdr->addr2, - tkey->rx_iv32, tkey->rx_iv16, iv32, iv16); + printk(KERN_DEBUG "TKIP: replay detected: STA=" + " %pM previous TSC %08x%04x received " + "TSC %08x%04x\n",hdr->addr2, + tkey->rx_iv32, tkey->rx_iv16, iv32, iv16); } tkey->dot11RSNAStatsTKIPReplays++; return -4; } + tkey->initialized = true; if (iv32 != tkey->rx_iv32 || !tkey->rx_phase1_done) { - tkip_mixing_phase1(tkey->rx_ttak, tkey->key, hdr->addr2, iv32); + tkip_mixing_phase1(tkey->rx_ttak, tkey->key, + hdr->addr2, iv32); tkey->rx_phase1_done = 1; } tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16); plen = skb->len - hdr_len - 12; - crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16); sg_init_one(&sg, pos, plen+4); + + crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16); if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) { if (net_ratelimit()) { printk(KERN_DEBUG ": TKIP: failed to decrypt " - "received packet from %pM\n", - hdr->addr2); + "received packet from %pM\n", + hdr->addr2); } return -7; } @@ -474,14 +466,14 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) if (memcmp(icv, pos + plen, 4) != 0) { if (iv32 != tkey->rx_iv32) { - /* Previously cached Phase1 result was already lost, so - * it needs to be recalculated for the next packet. */ + /* Previously cached Phase1 result was already + * lost, so it needs to be recalculated for the + * next packet. */ tkey->rx_phase1_done = 0; } if (net_ratelimit()) { - printk(KERN_DEBUG - "TKIP: ICV error detected: STA=%pM\n", - hdr->addr2); + printk(KERN_DEBUG "TKIP: ICV error detected: STA=" + " %pM\n", hdr->addr2); } tkey->dot11RSNAStatsTKIPICVErrors++; return -5; @@ -503,46 +495,44 @@ static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv) } -static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr, - u8 * data, size_t data_len, u8 * mic) +static int michael_mic(struct crypto_hash *tfm_michael, u8 *key, u8 *hdr, + u8 *data, size_t data_len, u8 *mic) { - struct hash_desc desc; - struct scatterlist sg[2]; - - if (tfm_michael == NULL) { - printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n"); - return -1; - } - sg_init_table(sg, 2); - sg_set_buf(&sg[0], hdr, 16); - sg_set_buf(&sg[1], data, data_len); - - if (crypto_hash_setkey(tfm_michael, key, 8)) - return -1; - - desc.tfm = tfm_michael; - desc.flags = 0; - return crypto_hash_digest(&desc, sg, data_len + 16, mic); -} + struct hash_desc desc; + struct scatterlist sg[2]; + if (tfm_michael == NULL) { + printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n"); + return -1; + } + sg_init_table(sg, 2); + sg_set_buf(&sg[0], hdr, 16); + sg_set_buf(&sg[1], data, data_len); + + if (crypto_hash_setkey(tfm_michael, key, 8)) + return -1; + desc.tfm = tfm_michael; + desc.flags = 0; + return crypto_hash_digest(&desc, sg, data_len + 16, mic); +} static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr) { - struct ieee80211_hdr_4addr *hdr11; + struct rtllib_hdr_4addr *hdr11; - hdr11 = (struct ieee80211_hdr_4addr *) skb->data; + hdr11 = (struct rtllib_hdr_4addr *) skb->data; switch (le16_to_cpu(hdr11->frame_ctl) & - (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) { - case IEEE80211_FCTL_TODS: + (RTLLIB_FCTL_FROMDS | RTLLIB_FCTL_TODS)) { + case RTLLIB_FCTL_TODS: memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */ memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */ break; - case IEEE80211_FCTL_FROMDS: + case RTLLIB_FCTL_FROMDS: memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */ memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */ break; - case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS: + case RTLLIB_FCTL_FROMDS | RTLLIB_FCTL_TODS: memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */ memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */ break; @@ -558,13 +548,13 @@ static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr) } -static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv) +static int rtllib_michael_mic_add(struct sk_buff *skb, int hdr_len, void *priv) { - struct ieee80211_tkip_data *tkey = priv; + struct rtllib_tkip_data *tkey = priv; u8 *pos; - struct ieee80211_hdr_4addr *hdr; + struct rtllib_hdr_4addr *hdr; - hdr = (struct ieee80211_hdr_4addr *) skb->data; + hdr = (struct rtllib_hdr_4addr *) skb->data; if (skb_tailroom(skb) < 8 || skb->len < hdr_len) { printk(KERN_DEBUG "Invalid packet for Michael MIC add " @@ -575,24 +565,19 @@ static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len, void *pri michael_mic_hdr(skb, tkey->tx_hdr); - // { david, 2006.9.1 - // fix the wpa process with wmm enabled. - if(IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) { + if (RTLLIB_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) tkey->tx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07; - } - // } pos = skb_put(skb, 8); if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr, - skb->data + hdr_len, skb->len - 8 - hdr_len, pos)) + skb->data + hdr_len, skb->len - 8 - hdr_len, pos)) return -1; return 0; } -#if WIRELESS_EXT >= 18 -static void ieee80211_michael_mic_failure(struct net_device *dev, - struct ieee80211_hdr_4addr *hdr, +static void rtllib_michael_mic_failure(struct net_device *dev, + struct rtllib_hdr_4addr *hdr, int keyidx) { union iwreq_data wrqu; @@ -611,63 +596,45 @@ static void ieee80211_michael_mic_failure(struct net_device *dev, wrqu.data.length = sizeof(ev); wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *) &ev); } -#elif WIRELESS_EXT >= 15 -static void ieee80211_michael_mic_failure(struct net_device *dev, - struct ieee80211_hdr_4addr *hdr, - int keyidx) -{ - union iwreq_data wrqu; - char buf[128]; - - /* TODO: needed parameters: count, keyid, key type, TSC */ - sprintf(buf, "MLME-MICHAELMICFAILURE.indication(keyid=%d %scast addr=" - "%pM)", keyidx, hdr->addr1[0] & 0x01 ? "broad" : "uni", - hdr->addr2); - memset(&wrqu, 0, sizeof(wrqu)); - wrqu.data.length = strlen(buf); - wireless_send_event(dev, IWEVCUSTOM, &wrqu, buf); -} -#else /* WIRELESS_EXT >= 15 */ -static inline void ieee80211_michael_mic_failure(struct net_device *dev, - struct ieee80211_hdr_4addr *hdr, - int keyidx) -{ -} -#endif /* WIRELESS_EXT >= 15 */ -static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx, - int hdr_len, void *priv) +static int rtllib_michael_mic_verify(struct sk_buff *skb, int keyidx, + int hdr_len, void *priv, + struct rtllib_device *ieee) { - struct ieee80211_tkip_data *tkey = priv; + struct rtllib_tkip_data *tkey = priv; u8 mic[8]; - struct ieee80211_hdr_4addr *hdr; + struct rtllib_hdr_4addr *hdr; - hdr = (struct ieee80211_hdr_4addr *) skb->data; + hdr = (struct rtllib_hdr_4addr *) skb->data; if (!tkey->key_set) return -1; michael_mic_hdr(skb, tkey->rx_hdr); - // { david, 2006.9.1 - // fix the wpa process with wmm enabled. - if(IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) { + if (RTLLIB_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl))) tkey->rx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07; - } - // } if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr, - skb->data + hdr_len, skb->len - 8 - hdr_len, mic)) - return -1; - if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) { - struct ieee80211_hdr_4addr *hdr; - hdr = (struct ieee80211_hdr_4addr *) skb->data; + skb->data + hdr_len, skb->len - 8 - hdr_len, mic)) + return -1; + + if ((memcmp(mic, skb->data + skb->len - 8, 8) != 0) || + (ieee->force_mic_error)) { + struct rtllib_hdr_4addr *hdr; + hdr = (struct rtllib_hdr_4addr *) skb->data; printk(KERN_DEBUG "%s: Michael MIC verification failed for " "MSDU from %pM keyidx=%d\n", skb->dev ? skb->dev->name : "N/A", hdr->addr2, keyidx); - if (skb->dev) - ieee80211_michael_mic_failure(skb->dev, hdr, keyidx); + printk(KERN_DEBUG "%d, force_mic_error = %d\n", + (memcmp(mic, skb->data + skb->len - 8, 8) != 0),\ + ieee->force_mic_error); + if (skb->dev) { + printk(KERN_INFO "skb->dev != NULL\n"); + rtllib_michael_mic_failure(skb->dev, hdr, keyidx); + } tkey->dot11RSNAStatsTKIPLocalMICFailures++; + ieee->force_mic_error = false; return -1; } @@ -682,9 +649,9 @@ static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx, } -static int ieee80211_tkip_set_key(void *key, int len, u8 *seq, void *priv) +static int rtllib_tkip_set_key(void *key, int len, u8 *seq, void *priv) { - struct ieee80211_tkip_data *tkey = priv; + struct rtllib_tkip_data *tkey = priv; int keyidx; struct crypto_hash *tfm = tkey->tx_tfm_michael; struct crypto_blkcipher *tfm2 = tkey->tx_tfm_arc4; @@ -717,9 +684,9 @@ static int ieee80211_tkip_set_key(void *key, int len, u8 *seq, void *priv) } -static int ieee80211_tkip_get_key(void *key, int len, u8 *seq, void *priv) +static int rtllib_tkip_get_key(void *key, int len, u8 *seq, void *priv) { - struct ieee80211_tkip_data *tkey = priv; + struct rtllib_tkip_data *tkey = priv; if (len < TKIP_KEY_LEN) return -1; @@ -747,9 +714,9 @@ static int ieee80211_tkip_get_key(void *key, int len, u8 *seq, void *priv) } -static char * ieee80211_tkip_print_stats(char *p, void *priv) +static char *rtllib_tkip_print_stats(char *p, void *priv) { - struct ieee80211_tkip_data *tkip = priv; + struct rtllib_tkip_data *tkip = priv; p += sprintf(p, "key[%d] alg=TKIP key_set=%d " "tx_pn=%02x%02x%02x%02x%02x%02x " "rx_pn=%02x%02x%02x%02x%02x%02x " @@ -774,36 +741,35 @@ static char * ieee80211_tkip_print_stats(char *p, void *priv) } -static struct ieee80211_crypto_ops ieee80211_crypt_tkip = { +static struct rtllib_crypto_ops rtllib_crypt_tkip = { .name = "TKIP", - .init = ieee80211_tkip_init, - .deinit = ieee80211_tkip_deinit, - .encrypt_mpdu = ieee80211_tkip_encrypt, - .decrypt_mpdu = ieee80211_tkip_decrypt, - .encrypt_msdu = ieee80211_michael_mic_add, - .decrypt_msdu = ieee80211_michael_mic_verify, - .set_key = ieee80211_tkip_set_key, - .get_key = ieee80211_tkip_get_key, - .print_stats = ieee80211_tkip_print_stats, + .init = rtllib_tkip_init, + .deinit = rtllib_tkip_deinit, + .encrypt_mpdu = rtllib_tkip_encrypt, + .decrypt_mpdu = rtllib_tkip_decrypt, + .encrypt_msdu = rtllib_michael_mic_add, + .decrypt_msdu = rtllib_michael_mic_verify, + .set_key = rtllib_tkip_set_key, + .get_key = rtllib_tkip_get_key, + .print_stats = rtllib_tkip_print_stats, .extra_prefix_len = 4 + 4, /* IV + ExtIV */ .extra_postfix_len = 8 + 4, /* MIC + ICV */ - .owner = THIS_MODULE, + .owner = THIS_MODULE, }; -int __init ieee80211_crypto_tkip_init(void) +int __init rtllib_crypto_tkip_init(void) { - return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip); + return rtllib_register_crypto_ops(&rtllib_crypt_tkip); } -void ieee80211_crypto_tkip_exit(void) +void __exit rtllib_crypto_tkip_exit(void) { - ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip); + rtllib_unregister_crypto_ops(&rtllib_crypt_tkip); } -void ieee80211_tkip_null(void) +void rtllib_tkip_null(void) { - return; + return; } - diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_wep.c b/drivers/staging/rtl8192e/rtllib_crypt_wep.c index 5504391..c59bf10 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_crypt_wep.c +++ b/drivers/staging/rtl8192e/rtllib_crypt_wep.c @@ -9,62 +9,55 @@ * more details. */ +#include <linux/version.h> #include <linux/module.h> #include <linux/init.h> #include <linux/slab.h> #include <linux/random.h> #include <linux/skbuff.h> -#include <asm/string.h> - -#include "ieee80211.h" - +#include <linux/string.h> +#include "rtllib.h" #include <linux/crypto.h> #include <linux/scatterlist.h> #include <linux/crc32.h> -MODULE_AUTHOR("Jouni Malinen"); -MODULE_DESCRIPTION("Host AP crypt: WEP"); -MODULE_LICENSE("GPL"); -#ifndef OPENSUSE_SLED -#define OPENSUSE_SLED 0 -#endif - struct prism2_wep_data { u32 iv; #define WEP_KEY_LEN 13 u8 key[WEP_KEY_LEN + 1]; u8 key_len; u8 key_idx; - struct crypto_blkcipher *tx_tfm; - struct crypto_blkcipher *rx_tfm; + struct crypto_blkcipher *tx_tfm; + struct crypto_blkcipher *rx_tfm; }; -static void * prism2_wep_init(int keyidx) +static void *prism2_wep_init(int keyidx) { struct prism2_wep_data *priv; - priv = kzalloc(sizeof(*priv), GFP_ATOMIC); + priv = kmalloc(sizeof(*priv), GFP_ATOMIC); if (priv == NULL) goto fail; + memset(priv, 0, sizeof(*priv)); priv->key_idx = keyidx; priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); - if (IS_ERR(priv->tx_tfm)) { - printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate " - "crypto API arc4\n"); - priv->tx_tfm = NULL; - goto fail; - } - priv->rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); - if (IS_ERR(priv->rx_tfm)) { - printk(KERN_DEBUG "ieee80211_crypt_wep: could not allocate " - "crypto API arc4\n"); - priv->rx_tfm = NULL; - goto fail; - } + if (IS_ERR(priv->tx_tfm)) { + printk(KERN_DEBUG "rtllib_crypt_wep: could not allocate " + "crypto API arc4\n"); + priv->tx_tfm = NULL; + goto fail; + } + priv->rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC); + if (IS_ERR(priv->rx_tfm)) { + printk(KERN_DEBUG "rtllib_crypt_wep: could not allocate " + "crypto API arc4\n"); + priv->rx_tfm = NULL; + goto fail; + } /* start WEP IV from a random value */ get_random_bytes(&priv->iv, 4); @@ -73,12 +66,12 @@ static void * prism2_wep_init(int keyidx) fail: if (priv) { - if (priv->tx_tfm) - crypto_free_blkcipher(priv->tx_tfm); - if (priv->rx_tfm) - crypto_free_blkcipher(priv->rx_tfm); - kfree(priv); - } + if (priv->tx_tfm) + crypto_free_blkcipher(priv->tx_tfm); + if (priv->rx_tfm) + crypto_free_blkcipher(priv->rx_tfm); + kfree(priv); + } return NULL; } @@ -86,12 +79,13 @@ fail: static void prism2_wep_deinit(void *priv) { struct prism2_wep_data *_priv = priv; + if (_priv) { - if (_priv->tx_tfm) - crypto_free_blkcipher(_priv->tx_tfm); - if (_priv->rx_tfm) - crypto_free_blkcipher(_priv->rx_tfm); - } + if (_priv->tx_tfm) + crypto_free_blkcipher(_priv->tx_tfm); + if (_priv->rx_tfm) + crypto_free_blkcipher(_priv->rx_tfm); + } kfree(priv); } @@ -107,15 +101,19 @@ static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv) u32 klen, len; u8 key[WEP_KEY_LEN + 3]; u8 *pos; - cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); + struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + + MAX_DEV_ADDR_SIZE); struct blkcipher_desc desc = {.tfm = wep->tx_tfm}; u32 crc; u8 *icv; struct scatterlist sg; if (skb_headroom(skb) < 4 || skb_tailroom(skb) < 4 || - skb->len < hdr_len) + skb->len < hdr_len){ + printk(KERN_ERR "Error!!! headroom=%d tailroom=%d skblen=%d" + " hdr_len=%d\n", skb_headroom(skb), skb_tailroom(skb), + skb->len, hdr_len); return -1; - + } len = skb->len - hdr_len; pos = skb_push(skb, 4); memmove(pos, pos + 4, hdr_len); @@ -143,8 +141,7 @@ static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv) /* Copy rest of the WEP key (the secret part) */ memcpy(key + 3, wep->key, wep->key_len); - if (!tcb_desc->bHwSec) - { + if (!tcb_desc->bHwSec) { /* Append little-endian CRC32 and encrypt it to produce ICV */ crc = ~crc32_le(~0, pos, len); @@ -154,8 +151,8 @@ static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv) icv[2] = crc >> 16; icv[3] = crc >> 24; - crypto_blkcipher_setkey(wep->tx_tfm, key, klen); sg_init_one(&sg, pos, len+4); + crypto_blkcipher_setkey(wep->tx_tfm, key, klen); return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4); } @@ -163,8 +160,8 @@ static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv) } -/* Perform WEP decryption on given buffer. Buffer includes whole WEP part of - * the frame: IV (4 bytes), encrypted payload (including SNAP header), +/* Perform WEP decryption on given struct buffer. Buffer includes whole WEP + * part of the frame: IV (4 bytes), encrypted payload (including SNAP header), * ICV (4 bytes). len includes both IV and ICV. * * Returns 0 if frame was decrypted successfully and ICV was correct and -1 on @@ -176,7 +173,8 @@ static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv) u32 klen, plen; u8 key[WEP_KEY_LEN + 3]; u8 keyidx, *pos; - cb_desc *tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); + struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + + MAX_DEV_ADDR_SIZE); struct blkcipher_desc desc = {.tfm = wep->rx_tfm}; u32 crc; u8 icv[4]; @@ -200,10 +198,9 @@ static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv) /* Apply RC4 to data and compute CRC32 over decrypted data */ plen = skb->len - hdr_len - 8; - if (!tcb_desc->bHwSec) - { - crypto_blkcipher_setkey(wep->rx_tfm, key, klen); + if (!tcb_desc->bHwSec) { sg_init_one(&sg, pos, plen+4); + crypto_blkcipher_setkey(wep->rx_tfm, key, klen); if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) return -7; crc = ~crc32_le(~0, pos, plen); @@ -252,7 +249,7 @@ static int prism2_wep_get_key(void *key, int len, u8 *seq, void *priv) } -static char * prism2_wep_print_stats(char *p, void *priv) +static char *prism2_wep_print_stats(char *p, void *priv) { struct prism2_wep_data *wep = priv; p += sprintf(p, "key[%d] alg=WEP len=%d\n", @@ -261,7 +258,7 @@ static char * prism2_wep_print_stats(char *p, void *priv) } -static struct ieee80211_crypto_ops ieee80211_crypt_wep = { +static struct rtllib_crypto_ops rtllib_crypt_wep = { .name = "WEP", .init = prism2_wep_init, .deinit = prism2_wep_deinit, @@ -278,19 +275,18 @@ static struct ieee80211_crypto_ops ieee80211_crypt_wep = { }; -int __init ieee80211_crypto_wep_init(void) +int __init rtllib_crypto_wep_init(void) { - return ieee80211_register_crypto_ops(&ieee80211_crypt_wep); + return rtllib_register_crypto_ops(&rtllib_crypt_wep); } -void __exit ieee80211_crypto_wep_exit(void) +void __exit rtllib_crypto_wep_exit(void) { - ieee80211_unregister_crypto_ops(&ieee80211_crypt_wep); + rtllib_unregister_crypto_ops(&rtllib_crypt_wep); } -void ieee80211_wep_null(void) +void rtllib_wep_null(void) { - return; + return; } - diff --git a/drivers/staging/rtl8192e/rtllib_endianfree.h b/drivers/staging/rtl8192e/rtllib_endianfree.h new file mode 100644 index 0000000..b268605 --- /dev/null +++ b/drivers/staging/rtl8192e/rtllib_endianfree.h @@ -0,0 +1,160 @@ +#ifndef __INC_ENDIANFREE_H +#define __INC_ENDIANFREE_H + +/* + * Call endian free function when + * 1. Read/write packet content. + * 2. Before write integer to IO. + * 3. After read integer from IO. + */ + +#define __MACHINE_LITTLE_ENDIAN 1234 /* LSB first: i386, vax */ +#define __MACHINE_BIG_ENDIAN 4321 /* MSB first: 68000, ibm, net, ppc */ + +#define BYTE_ORDER __MACHINE_LITTLE_ENDIAN + +#if BYTE_ORDER == __MACHINE_LITTLE_ENDIAN +#define EF1Byte(_val) ((u8)(_val)) +#define EF2Byte(_val) ((u16)(_val)) +#define EF4Byte(_val) ((u32)(_val)) + +#else +#define EF1Byte(_val) ((u8)(_val)) +#define EF2Byte(_val) \ + (((((u16)(_val))&0x00ff)<<8)|((((u16)(_val))&0xff00)>>8)) +#define EF4Byte(_val) \ + (((((u32)(_val))&0x000000ff)<<24)|\ + ((((u32)(_val))&0x0000ff00)<<8)|\ + ((((u32)(_val))&0x00ff0000)>>8)|\ + ((((u32)(_val))&0xff000000)>>24)) +#endif + +#define ReadEF1Byte(_ptr) EF1Byte(*((u8 *)(_ptr))) +#define ReadEF2Byte(_ptr) EF2Byte(*((u16 *)(_ptr))) +#define ReadEF4Byte(_ptr) EF4Byte(*((u32 *)(_ptr))) + +#define WriteEF1Byte(_ptr, _val) (*((u8 *)(_ptr))) = EF1Byte(_val) +#define WriteEF2Byte(_ptr, _val) (*((u16 *)(_ptr))) = EF2Byte(_val) +#define WriteEF4Byte(_ptr, _val) (*((u32 *)(_ptr))) = EF4Byte(_val) +#if BYTE_ORDER == __MACHINE_LITTLE_ENDIAN +#define H2N1BYTE(_val) ((u8)(_val)) +#define H2N2BYTE(_val) (((((u16)(_val))&0x00ff)<<8)|\ + ((((u16)(_val))&0xff00)>>8)) +#define H2N4BYTE(_val) (((((u32)(_val))&0x000000ff)<<24)|\ + ((((u32)(_val))&0x0000ff00)<<8) |\ + ((((u32)(_val))&0x00ff0000)>>8) |\ + ((((u32)(_val))&0xff000000)>>24)) +#else +#define H2N1BYTE(_val) ((u8)(_val)) +#define H2N2BYTE(_val) ((u16)(_val)) +#define H2N4BYTE(_val) ((u32)(_val)) +#endif + +#if BYTE_ORDER == __MACHINE_LITTLE_ENDIAN +#define N2H1BYTE(_val) ((u8)(_val)) +#define N2H2BYTE(_val) (((((u16)(_val))&0x00ff)<<8)|\ + ((((u16)(_val))&0xff00)>>8)) +#define N2H4BYTE(_val) (((((u32)(_val))&0x000000ff)<<24)|\ + ((((u32)(_val))&0x0000ff00)<<8) |\ + ((((u32)(_val))&0x00ff0000)>>8) |\ + ((((u32)(_val))&0xff000000)>>24)) +#else +#define N2H1BYTE(_val) ((u8)(_val)) +#define N2H2BYTE(_val) ((u16)(_val)) +#define N2H4BYTE(_val) ((u32)(_val)) +#endif + +#define BIT_LEN_MASK_32(__BitLen) (0xFFFFFFFF >> (32 - (__BitLen))) +#define BIT_OFFSET_LEN_MASK_32(__BitOffset, __BitLen) \ + (BIT_LEN_MASK_32(__BitLen) << (__BitOffset)) + +#define LE_P4BYTE_TO_HOST_4BYTE(__pStart) (EF4Byte(*((u32 *)(__pStart)))) + +#define LE_BITS_TO_4BYTE(__pStart, __BitOffset, __BitLen) \ + ( \ + (LE_P4BYTE_TO_HOST_4BYTE(__pStart) >> (__BitOffset)) \ + & \ + BIT_LEN_MASK_32(__BitLen) \ + ) + +#define LE_BITS_CLEARED_TO_4BYTE(__pStart, __BitOffset, __BitLen) \ + ( \ + LE_P4BYTE_TO_HOST_4BYTE(__pStart) \ + & \ + (~BIT_OFFSET_LEN_MASK_32(__BitOffset, __BitLen)) \ + ) + +#define SET_BITS_TO_LE_4BYTE(__pStart, __BitOffset, __BitLen, __Value) \ + *((u32 *)(__pStart)) = \ + EF4Byte( \ + LE_BITS_CLEARED_TO_4BYTE(__pStart, __BitOffset, __BitLen) \ + | \ + ((((u32)__Value) & BIT_LEN_MASK_32(__BitLen)) << (__BitOffset)) \ + ); + + +#define BIT_LEN_MASK_16(__BitLen) \ + (0xFFFF >> (16 - (__BitLen))) + +#define BIT_OFFSET_LEN_MASK_16(__BitOffset, __BitLen) \ + (BIT_LEN_MASK_16(__BitLen) << (__BitOffset)) + +#define LE_P2BYTE_TO_HOST_2BYTE(__pStart) \ + (EF2Byte(*((u16 *)(__pStart)))) + +#define LE_BITS_TO_2BYTE(__pStart, __BitOffset, __BitLen) \ + ( \ + (LE_P2BYTE_TO_HOST_2BYTE(__pStart) >> (__BitOffset)) \ + & \ + BIT_LEN_MASK_16(__BitLen) \ + ) + +#define LE_BITS_CLEARED_TO_2BYTE(__pStart, __BitOffset, __BitLen) \ + ( \ + LE_P2BYTE_TO_HOST_2BYTE(__pStart) \ + & \ + (~BIT_OFFSET_LEN_MASK_16(__BitOffset, __BitLen)) \ + ) + +#define SET_BITS_TO_LE_2BYTE(__pStart, __BitOffset, __BitLen, __Value) \ + *((u16 *)(__pStart)) = \ + EF2Byte( \ + LE_BITS_CLEARED_TO_2BYTE(__pStart, __BitOffset, __BitLen) \ + | ((((u16)__Value) & BIT_LEN_MASK_16(__BitLen)) << \ + (__BitOffset)) \ + ); + +#define BIT_LEN_MASK_8(__BitLen) \ + (0xFF >> (8 - (__BitLen))) + +#define BIT_OFFSET_LEN_MASK_8(__BitOffset, __BitLen) \ + (BIT_LEN_MASK_8(__BitLen) << (__BitOffset)) + +#define LE_P1BYTE_TO_HOST_1BYTE(__pStart) \ + (EF1Byte(*((u8 *)(__pStart)))) + +#define LE_BITS_TO_1BYTE(__pStart, __BitOffset, __BitLen) \ + ( \ + (LE_P1BYTE_TO_HOST_1BYTE(__pStart) >> (__BitOffset)) \ + & \ + BIT_LEN_MASK_8(__BitLen) \ + ) + +#define LE_BITS_CLEARED_TO_1BYTE(__pStart, __BitOffset, __BitLen) \ + ( \ + LE_P1BYTE_TO_HOST_1BYTE(__pStart) \ + & \ + (~BIT_OFFSET_LEN_MASK_8(__BitOffset, __BitLen)) \ + ) + +#define SET_BITS_TO_LE_1BYTE(__pStart, __BitOffset, __BitLen, __Value) \ + *((u8 *)(__pStart)) = EF1Byte( \ + LE_BITS_CLEARED_TO_1BYTE(__pStart, __BitOffset, __BitLen) \ + | ((((u8)__Value) & BIT_LEN_MASK_8(__BitLen)) << \ + (__BitOffset)) \ + ); + +#define N_BYTE_ALIGMENT(__Value, __Aligment) \ + ((__Aligment == 1) ? (__Value) : (((__Value + __Aligment - 1) / \ + __Aligment) * __Aligment)) +#endif diff --git a/drivers/staging/rtl8192e/rtllib_module.c b/drivers/staging/rtl8192e/rtllib_module.c new file mode 100644 index 0000000..0fe67a5 --- /dev/null +++ b/drivers/staging/rtl8192e/rtllib_module.c @@ -0,0 +1,290 @@ +/******************************************************************************* + + Copyright(c) 2004 Intel Corporation. All rights reserved. + + Portions of this file are based on the WEP enablement code provided by the + Host AP project hostap-drivers v0.1.3 + Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen + <jkmaline@cc.hut.fi> + Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi> + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2 of the GNU General Public License as + published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., 59 + Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + The full GNU General Public License is included in this distribution in the + file called LICENSE. + + Contact Information: + James P. Ketrenos <ipw2100-admin@linux.intel.com> + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + +*******************************************************************************/ + +#include <linux/compiler.h> +#include <linux/errno.h> +#include <linux/if_arp.h> +#include <linux/in6.h> +#include <linux/in.h> +#include <linux/ip.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/netdevice.h> +#include <linux/pci.h> +#include <linux/proc_fs.h> +#include <linux/skbuff.h> +#include <linux/slab.h> +#include <linux/tcp.h> +#include <linux/types.h> +#include <linux/version.h> +#include <linux/wireless.h> +#include <linux/etherdevice.h> +#include <linux/uaccess.h> +#include <net/arp.h> + +#include "rtllib.h" + + +#define DRV_NAME "rtllib_92e" + +void _setup_timer(struct timer_list *ptimer, void *fun, unsigned long data) +{ + ptimer->function = fun; + ptimer->data = data; + init_timer(ptimer); +} + +static inline int rtllib_networks_allocate(struct rtllib_device *ieee) +{ + if (ieee->networks) + return 0; + + ieee->networks = kzalloc( + MAX_NETWORK_COUNT * sizeof(struct rtllib_network), + GFP_KERNEL); + if (!ieee->networks) { + printk(KERN_WARNING "%s: Out of memory allocating beacons\n", + ieee->dev->name); + return -ENOMEM; + } + + return 0; +} + +static inline void rtllib_networks_free(struct rtllib_device *ieee) +{ + if (!ieee->networks) + return; + kfree(ieee->networks); + ieee->networks = NULL; +} + +static inline void rtllib_networks_initialize(struct rtllib_device *ieee) +{ + int i; + + INIT_LIST_HEAD(&ieee->network_free_list); + INIT_LIST_HEAD(&ieee->network_list); + for (i = 0; i < MAX_NETWORK_COUNT; i++) + list_add_tail(&ieee->networks[i].list, + &ieee->network_free_list); +} + +struct net_device *alloc_rtllib(int sizeof_priv) +{ + struct rtllib_device *ieee = NULL; + struct net_device *dev; + int i, err; + + RTLLIB_DEBUG_INFO("Initializing...\n"); + + dev = alloc_etherdev(sizeof(struct rtllib_device) + sizeof_priv); + if (!dev) { + RTLLIB_ERROR("Unable to network device.\n"); + goto failed; + } + ieee = (struct rtllib_device *)netdev_priv_rsl(dev); + memset(ieee, 0, sizeof(struct rtllib_device)+sizeof_priv); + ieee->dev = dev; + + err = rtllib_networks_allocate(ieee); + if (err) { + RTLLIB_ERROR("Unable to allocate beacon storage: %d\n", + err); + goto failed; + } + rtllib_networks_initialize(ieee); + + + /* Default fragmentation threshold is maximum payload size */ + ieee->fts = DEFAULT_FTS; + ieee->scan_age = DEFAULT_MAX_SCAN_AGE; + ieee->open_wep = 1; + + /* Default to enabling full open WEP with host based encrypt/decrypt */ + ieee->host_encrypt = 1; + ieee->host_decrypt = 1; + ieee->ieee802_1x = 1; /* Default to supporting 802.1x */ + + INIT_LIST_HEAD(&ieee->crypt_deinit_list); + _setup_timer(&ieee->crypt_deinit_timer, + rtllib_crypt_deinit_handler, + (unsigned long) ieee); + ieee->rtllib_ap_sec_type = rtllib_ap_sec_type; + + spin_lock_init(&ieee->lock); + spin_lock_init(&ieee->wpax_suitlist_lock); + spin_lock_init(&ieee->bw_spinlock); + spin_lock_init(&ieee->reorder_spinlock); + atomic_set(&(ieee->atm_chnlop), 0); + atomic_set(&(ieee->atm_swbw), 0); + + ieee->bHalfNMode = false; + ieee->wpa_enabled = 0; + ieee->tkip_countermeasures = 0; + ieee->drop_unencrypted = 0; + ieee->privacy_invoked = 0; + ieee->ieee802_1x = 1; + ieee->raw_tx = 0; + ieee->hwsec_active = 0; + + memset(ieee->swcamtable, 0, sizeof(struct sw_cam_table) * 32); + rtllib_softmac_init(ieee); + + ieee->pHTInfo = kzalloc(sizeof(struct rt_hi_throughput), GFP_KERNEL); + if (ieee->pHTInfo == NULL) { + RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't alloc memory for HTInfo\n"); + return NULL; + } + HTUpdateDefaultSetting(ieee); + HTInitializeHTInfo(ieee); + TSInitialize(ieee); + for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++) + INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]); + + for (i = 0; i < 17; i++) { + ieee->last_rxseq_num[i] = -1; + ieee->last_rxfrag_num[i] = -1; + ieee->last_packet_time[i] = 0; + } + + rtllib_tkip_null(); + rtllib_wep_null(); + rtllib_ccmp_null(); + + return dev; + + failed: + if (dev) + free_netdev(dev); + return NULL; +} + +void free_rtllib(struct net_device *dev) +{ + struct rtllib_device *ieee = (struct rtllib_device *) + netdev_priv_rsl(dev); + int i; + if (ieee->pHTInfo != NULL) { + kfree(ieee->pHTInfo); + ieee->pHTInfo = NULL; + } + rtllib_softmac_free(ieee); + del_timer_sync(&ieee->crypt_deinit_timer); + rtllib_crypt_deinit_entries(ieee, 1); + + for (i = 0; i < WEP_KEYS; i++) { + struct rtllib_crypt_data *crypt = ieee->crypt[i]; + if (crypt) { + if (crypt->ops) + crypt->ops->deinit(crypt->priv); + kfree(crypt); + ieee->crypt[i] = NULL; + } + } + + rtllib_networks_free(ieee); + free_netdev(dev); +} + +u32 rtllib_debug_level; +static int debug = \ + RTLLIB_DL_ERR + ; +static struct proc_dir_entry *rtllib_proc; + +static int show_debug_level(char *page, char **start, off_t offset, + int count, int *eof, void *data) +{ + return snprintf(page, count, "0x%08X\n", rtllib_debug_level); +} + +static int store_debug_level(struct file *file, const char __user *buffer, + unsigned long count, void *data) +{ + char buf[] = "0x00000000"; + unsigned long len = min((unsigned long)sizeof(buf) - 1, count); + char *p = (char *)buf; + unsigned long val; + + if (copy_from_user(buf, buffer, len)) + return count; + buf[len] = 0; + if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') { + p++; + if (p[0] == 'x' || p[0] == 'X') + p++; + val = simple_strtoul(p, &p, 16); + } else + val = simple_strtoul(p, &p, 10); + if (p == buf) + printk(KERN_INFO DRV_NAME + ": %s is not in hex or decimal form.\n", buf); + else + rtllib_debug_level = val; + + return strnlen(buf, count); +} + +int __init rtllib_init(void) +{ + struct proc_dir_entry *e; + + rtllib_debug_level = debug; + rtllib_proc = create_proc_entry(DRV_NAME, S_IFDIR, init_net.proc_net); + if (rtllib_proc == NULL) { + RTLLIB_ERROR("Unable to create " DRV_NAME + " proc directory\n"); + return -EIO; + } + e = create_proc_entry("debug_level", S_IFREG | S_IRUGO | S_IWUSR, + rtllib_proc); + if (!e) { + remove_proc_entry(DRV_NAME, init_net.proc_net); + rtllib_proc = NULL; + return -EIO; + } + e->read_proc = show_debug_level; + e->write_proc = store_debug_level; + e->data = NULL; + + return 0; +} + +void __exit rtllib_exit(void) +{ + if (rtllib_proc) { + remove_proc_entry("debug_level", rtllib_proc); + remove_proc_entry(DRV_NAME, init_net.proc_net); + rtllib_proc = NULL; + } +} diff --git a/drivers/staging/rtl8192e/rtllib_rx.c b/drivers/staging/rtl8192e/rtllib_rx.c new file mode 100644 index 0000000..745ae08 --- /dev/null +++ b/drivers/staging/rtl8192e/rtllib_rx.c @@ -0,0 +1,2722 @@ +/* + * Original code based Host AP (software wireless LAN access point) driver + * for Intersil Prism2/2.5/3 - hostap.o module, common routines + * + * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen + * <jkmaline@cc.hut.fi> + * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi> + * Copyright (c) 2004, Intel Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. See README and COPYING for + * more details. + ****************************************************************************** + + Few modifications for Realtek's Wi-Fi drivers by + Andrea Merello <andreamrl@tiscali.it> + + A special thanks goes to Realtek for their support ! + +******************************************************************************/ + + +#include <linux/compiler.h> +#include <linux/errno.h> +#include <linux/if_arp.h> +#include <linux/in6.h> +#include <linux/in.h> +#include <linux/ip.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/netdevice.h> +#include <linux/pci.h> +#include <linux/proc_fs.h> +#include <linux/skbuff.h> +#include <linux/slab.h> +#include <linux/tcp.h> +#include <linux/types.h> +#include <linux/version.h> +#include <linux/wireless.h> +#include <linux/etherdevice.h> +#include <linux/uaccess.h> +#include <linux/ctype.h> + +#include "rtllib.h" +#include "dot11d.h" + +static inline void rtllib_monitor_rx(struct rtllib_device *ieee, + struct sk_buff *skb, struct rtllib_rx_stats *rx_status, + size_t hdr_length) +{ + skb->dev = ieee->dev; + skb_reset_mac_header(skb); + skb_pull(skb, hdr_length); + skb->pkt_type = PACKET_OTHERHOST; + skb->protocol = __constant_htons(ETH_P_80211_RAW); + memset(skb->cb, 0, sizeof(skb->cb)); + netif_rx(skb); +} + +/* Called only as a tasklet (software IRQ) */ +static struct rtllib_frag_entry * +rtllib_frag_cache_find(struct rtllib_device *ieee, unsigned int seq, + unsigned int frag, u8 tid, u8 *src, u8 *dst) +{ + struct rtllib_frag_entry *entry; + int i; + + for (i = 0; i < RTLLIB_FRAG_CACHE_LEN; i++) { + entry = &ieee->frag_cache[tid][i]; + if (entry->skb != NULL && + time_after(jiffies, entry->first_frag_time + 2 * HZ)) { + RTLLIB_DEBUG_FRAG( + "expiring fragment cache entry " + "seq=%u last_frag=%u\n", + entry->seq, entry->last_frag); + dev_kfree_skb_any(entry->skb); + entry->skb = NULL; + } + + if (entry->skb != NULL && entry->seq == seq && + (entry->last_frag + 1 == frag || frag == -1) && + memcmp(entry->src_addr, src, ETH_ALEN) == 0 && + memcmp(entry->dst_addr, dst, ETH_ALEN) == 0) + return entry; + } + + return NULL; +} + +/* Called only as a tasklet (software IRQ) */ +static struct sk_buff * +rtllib_frag_cache_get(struct rtllib_device *ieee, + struct rtllib_hdr_4addr *hdr) +{ + struct sk_buff *skb = NULL; + u16 fc = le16_to_cpu(hdr->frame_ctl); + u16 sc = le16_to_cpu(hdr->seq_ctl); + unsigned int frag = WLAN_GET_SEQ_FRAG(sc); + unsigned int seq = WLAN_GET_SEQ_SEQ(sc); + struct rtllib_frag_entry *entry; + struct rtllib_hdr_3addrqos *hdr_3addrqos; + struct rtllib_hdr_4addrqos *hdr_4addrqos; + u8 tid; + + if (((fc & RTLLIB_FCTL_DSTODS) == RTLLIB_FCTL_DSTODS) && RTLLIB_QOS_HAS_SEQ(fc)) { + hdr_4addrqos = (struct rtllib_hdr_4addrqos *)hdr; + tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & RTLLIB_QCTL_TID; + tid = UP2AC(tid); + tid++; + } else if (RTLLIB_QOS_HAS_SEQ(fc)) { + hdr_3addrqos = (struct rtllib_hdr_3addrqos *)hdr; + tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & RTLLIB_QCTL_TID; + tid = UP2AC(tid); + tid++; + } else { + tid = 0; + } + + if (frag == 0) { + /* Reserve enough space to fit maximum frame length */ + skb = dev_alloc_skb(ieee->dev->mtu + + sizeof(struct rtllib_hdr_4addr) + + 8 /* LLC */ + + 2 /* alignment */ + + 8 /* WEP */ + + ETH_ALEN /* WDS */ + + (RTLLIB_QOS_HAS_SEQ(fc) ? 2 : 0) /* QOS Control */); + if (skb == NULL) + return NULL; + + entry = &ieee->frag_cache[tid][ieee->frag_next_idx[tid]]; + ieee->frag_next_idx[tid]++; + if (ieee->frag_next_idx[tid] >= RTLLIB_FRAG_CACHE_LEN) + ieee->frag_next_idx[tid] = 0; + + if (entry->skb != NULL) + dev_kfree_skb_any(entry->skb); + + entry->first_frag_time = jiffies; + entry->seq = seq; + entry->last_frag = frag; + entry->skb = skb; + memcpy(entry->src_addr, hdr->addr2, ETH_ALEN); + memcpy(entry->dst_addr, hdr->addr1, ETH_ALEN); + } else { + /* received a fragment of a frame for which the head fragment + * should have already been received */ + entry = rtllib_frag_cache_find(ieee, seq, frag, tid, hdr->addr2, + hdr->addr1); + if (entry != NULL) { + entry->last_frag = frag; + skb = entry->skb; + } + } + + return skb; +} + + +/* Called only as a tasklet (software IRQ) */ +static int rtllib_frag_cache_invalidate(struct rtllib_device *ieee, + struct rtllib_hdr_4addr *hdr) +{ + u16 fc = le16_to_cpu(hdr->frame_ctl); + u16 sc = le16_to_cpu(hdr->seq_ctl); + unsigned int seq = WLAN_GET_SEQ_SEQ(sc); + struct rtllib_frag_entry *entry; + struct rtllib_hdr_3addrqos *hdr_3addrqos; + struct rtllib_hdr_4addrqos *hdr_4addrqos; + u8 tid; + + if (((fc & RTLLIB_FCTL_DSTODS) == RTLLIB_FCTL_DSTODS) && RTLLIB_QOS_HAS_SEQ(fc)) { + hdr_4addrqos = (struct rtllib_hdr_4addrqos *)hdr; + tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & RTLLIB_QCTL_TID; + tid = UP2AC(tid); + tid++; + } else if (RTLLIB_QOS_HAS_SEQ(fc)) { + hdr_3addrqos = (struct rtllib_hdr_3addrqos *)hdr; + tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & RTLLIB_QCTL_TID; + tid = UP2AC(tid); + tid++; + } else { + tid = 0; + } + + entry = rtllib_frag_cache_find(ieee, seq, -1, tid, hdr->addr2, + hdr->addr1); + + if (entry == NULL) { + RTLLIB_DEBUG_FRAG( + "could not invalidate fragment cache " + "entry (seq=%u)\n", seq); + return -1; + } + + entry->skb = NULL; + return 0; +} + +/* rtllib_rx_frame_mgtmt + * + * Responsible for handling management control frames + * + * Called by rtllib_rx */ +static inline int +rtllib_rx_frame_mgmt(struct rtllib_device *ieee, struct sk_buff *skb, + struct rtllib_rx_stats *rx_stats, u16 type, + u16 stype) +{ + /* On the struct stats definition there is written that + * this is not mandatory.... but seems that the probe + * response parser uses it + */ + struct rtllib_hdr_3addr * hdr = (struct rtllib_hdr_3addr *)skb->data; + + rx_stats->len = skb->len; + rtllib_rx_mgt(ieee, skb, rx_stats); + if ((memcmp(hdr->addr1, ieee->dev->dev_addr, ETH_ALEN))) { + dev_kfree_skb_any(skb); + return 0; + } + rtllib_rx_frame_softmac(ieee, skb, rx_stats, type, stype); + + dev_kfree_skb_any(skb); + + return 0; +} + +/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */ +/* Ethernet-II snap header (RFC1042 for most EtherTypes) */ +static unsigned char rfc1042_header[] = { + 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 +}; +/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */ +static unsigned char bridge_tunnel_header[] = { + 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 +}; +/* No encapsulation header if EtherType < 0x600 (=length) */ + +/* Called by rtllib_rx_frame_decrypt */ +static int rtllib_is_eapol_frame(struct rtllib_device *ieee, + struct sk_buff *skb, size_t hdrlen) +{ + struct net_device *dev = ieee->dev; + u16 fc, ethertype; + struct rtllib_hdr_4addr *hdr; + u8 *pos; + + if (skb->len < 24) + return 0; + + hdr = (struct rtllib_hdr_4addr *) skb->data; + fc = le16_to_cpu(hdr->frame_ctl); + + /* check that the frame is unicast frame to us */ + if ((fc & (RTLLIB_FCTL_TODS | RTLLIB_FCTL_FROMDS)) == + RTLLIB_FCTL_TODS && + memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0 && + memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) { + /* ToDS frame with own addr BSSID and DA */ + } else if ((fc & (RTLLIB_FCTL_TODS | RTLLIB_FCTL_FROMDS)) == + RTLLIB_FCTL_FROMDS && + memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) { + /* FromDS frame with own addr as DA */ + } else + return 0; + + if (skb->len < 24 + 8) + return 0; + + /* check for port access entity Ethernet type */ + pos = skb->data + hdrlen; + ethertype = (pos[6] << 8) | pos[7]; + if (ethertype == ETH_P_PAE) + return 1; + + return 0; +} + +/* Called only as a tasklet (software IRQ), by rtllib_rx */ +static inline int +rtllib_rx_frame_decrypt(struct rtllib_device *ieee, struct sk_buff *skb, + struct rtllib_crypt_data *crypt) +{ + struct rtllib_hdr_4addr *hdr; + int res, hdrlen; + + if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL) + return 0; + + if (ieee->hwsec_active) { + struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); + tcb_desc->bHwSec = 1; + + if (ieee->need_sw_enc) + tcb_desc->bHwSec = 0; + } + + hdr = (struct rtllib_hdr_4addr *) skb->data; + hdrlen = rtllib_get_hdrlen(le16_to_cpu(hdr->frame_ctl)); + + atomic_inc(&crypt->refcnt); + res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv); + atomic_dec(&crypt->refcnt); + if (res < 0) { + RTLLIB_DEBUG_DROP( + "decryption failed (SA= %pM" + ") res=%d\n", hdr->addr2, res); + if (res == -2) + RTLLIB_DEBUG_DROP("Decryption failed ICV " + "mismatch (key %d)\n", + skb->data[hdrlen + 3] >> 6); + ieee->ieee_stats.rx_discards_undecryptable++; + return -1; + } + + return res; +} + + +/* Called only as a tasklet (software IRQ), by rtllib_rx */ +static inline int +rtllib_rx_frame_decrypt_msdu(struct rtllib_device *ieee, struct sk_buff *skb, + int keyidx, struct rtllib_crypt_data *crypt) +{ + struct rtllib_hdr_4addr *hdr; + int res, hdrlen; + + if (crypt == NULL || crypt->ops->decrypt_msdu == NULL) + return 0; + if (ieee->hwsec_active) { + struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); + tcb_desc->bHwSec = 1; + + if (ieee->need_sw_enc) + tcb_desc->bHwSec = 0; + } + + hdr = (struct rtllib_hdr_4addr *) skb->data; + hdrlen = rtllib_get_hdrlen(le16_to_cpu(hdr->frame_ctl)); + + atomic_inc(&crypt->refcnt); + res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv, ieee); + atomic_dec(&crypt->refcnt); + if (res < 0) { + printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed" + " (SA= %pM keyidx=%d)\n", + ieee->dev->name, hdr->addr2, keyidx); + return -1; + } + + return 0; +} + + +/* this function is stolen from ipw2200 driver*/ +#define IEEE_PACKET_RETRY_TIME (5*HZ) +static int is_duplicate_packet(struct rtllib_device *ieee, + struct rtllib_hdr_4addr *header) +{ + u16 fc = le16_to_cpu(header->frame_ctl); + u16 sc = le16_to_cpu(header->seq_ctl); + u16 seq = WLAN_GET_SEQ_SEQ(sc); + u16 frag = WLAN_GET_SEQ_FRAG(sc); + u16 *last_seq, *last_frag; + unsigned long *last_time; + struct rtllib_hdr_3addrqos *hdr_3addrqos; + struct rtllib_hdr_4addrqos *hdr_4addrqos; + u8 tid; + + if (((fc & RTLLIB_FCTL_DSTODS) == RTLLIB_FCTL_DSTODS) && RTLLIB_QOS_HAS_SEQ(fc)) { + hdr_4addrqos = (struct rtllib_hdr_4addrqos *)header; + tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & RTLLIB_QCTL_TID; + tid = UP2AC(tid); + tid++; + } else if (RTLLIB_QOS_HAS_SEQ(fc)) { + hdr_3addrqos = (struct rtllib_hdr_3addrqos *)header; + tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & RTLLIB_QCTL_TID; + tid = UP2AC(tid); + tid++; + } else { + tid = 0; + } + + switch (ieee->iw_mode) { + case IW_MODE_ADHOC: + { + struct list_head *p; + struct ieee_ibss_seq *entry = NULL; + u8 *mac = header->addr2; + int index = mac[5] % IEEE_IBSS_MAC_HASH_SIZE; + list_for_each(p, &ieee->ibss_mac_hash[index]) { + entry = list_entry(p, struct ieee_ibss_seq, list); + if (!memcmp(entry->mac, mac, ETH_ALEN)) + break; + } + if (p == &ieee->ibss_mac_hash[index]) { + entry = kmalloc(sizeof(struct ieee_ibss_seq), GFP_ATOMIC); + if (!entry) { + printk(KERN_WARNING "Cannot malloc new mac entry\n"); + return 0; + } + memcpy(entry->mac, mac, ETH_ALEN); + entry->seq_num[tid] = seq; + entry->frag_num[tid] = frag; + entry->packet_time[tid] = jiffies; + list_add(&entry->list, &ieee->ibss_mac_hash[index]); + return 0; + } + last_seq = &entry->seq_num[tid]; + last_frag = &entry->frag_num[tid]; + last_time = &entry->packet_time[tid]; + break; + } + + case IW_MODE_INFRA: + last_seq = &ieee->last_rxseq_num[tid]; + last_frag = &ieee->last_rxfrag_num[tid]; + last_time = &ieee->last_packet_time[tid]; + break; + default: + return 0; + } + + if ((*last_seq == seq) && + time_after(*last_time + IEEE_PACKET_RETRY_TIME, jiffies)) { + if (*last_frag == frag) + goto drop; + if (*last_frag + 1 != frag) + /* out-of-order fragment */ + goto drop; + } else + *last_seq = seq; + + *last_frag = frag; + *last_time = jiffies; + return 0; + +drop: + + return 1; +} + +static bool AddReorderEntry(struct rx_ts_record *pTS, + struct rx_reorder_entry *pReorderEntry) +{ + struct list_head *pList = &pTS->RxPendingPktList; + + while (pList->next != &pTS->RxPendingPktList) { + if (SN_LESS(pReorderEntry->SeqNum, ((struct rx_reorder_entry *) + list_entry(pList->next, struct rx_reorder_entry, + List))->SeqNum)) + pList = pList->next; + else if (SN_EQUAL(pReorderEntry->SeqNum, + ((struct rx_reorder_entry *)list_entry(pList->next, + struct rx_reorder_entry, List))->SeqNum)) + return false; + else + break; + } + pReorderEntry->List.next = pList->next; + pReorderEntry->List.next->prev = &pReorderEntry->List; + pReorderEntry->List.prev = pList; + pList->next = &pReorderEntry->List; + + return true; +} + +void rtllib_indicate_packets(struct rtllib_device *ieee, struct rtllib_rxb **prxbIndicateArray, u8 index) +{ + struct net_device_stats *stats = &ieee->stats; + u8 i = 0 , j = 0; + u16 ethertype; + for (j = 0; j < index; j++) { + struct rtllib_rxb *prxb = prxbIndicateArray[j]; + for (i = 0; i < prxb->nr_subframes; i++) { + struct sk_buff *sub_skb = prxb->subframes[i]; + + /* convert hdr + possible LLC headers into Ethernet header */ + ethertype = (sub_skb->data[6] << 8) | sub_skb->data[7]; + if (sub_skb->len >= 8 && + ((memcmp(sub_skb->data, rfc1042_header, SNAP_SIZE) == 0 && + ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) || + memcmp(sub_skb->data, bridge_tunnel_header, SNAP_SIZE) == 0)) { + /* remove RFC1042 or Bridge-Tunnel encapsulation + * and replace EtherType */ + skb_pull(sub_skb, SNAP_SIZE); + memcpy(skb_push(sub_skb, ETH_ALEN), prxb->src, ETH_ALEN); + memcpy(skb_push(sub_skb, ETH_ALEN), prxb->dst, ETH_ALEN); + } else { + u16 len; + /* Leave Ethernet header part of hdr and full payload */ + len = htons(sub_skb->len); + memcpy(skb_push(sub_skb, 2), &len, 2); + memcpy(skb_push(sub_skb, ETH_ALEN), prxb->src, ETH_ALEN); + memcpy(skb_push(sub_skb, ETH_ALEN), prxb->dst, ETH_ALEN); + } + + /* Indicat the packets to upper layer */ + if (sub_skb) { + stats->rx_packets++; + stats->rx_bytes += sub_skb->len; + + memset(sub_skb->cb, 0, sizeof(sub_skb->cb)); + sub_skb->protocol = eth_type_trans(sub_skb, ieee->dev); + sub_skb->dev = ieee->dev; + sub_skb->dev->stats.rx_packets++; + sub_skb->dev->stats.rx_bytes += sub_skb->len; + sub_skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */ + ieee->last_rx_ps_time = jiffies; + netif_rx(sub_skb); + } + } + kfree(prxb); + prxb = NULL; + } +} + +void rtllib_FlushRxTsPendingPkts(struct rtllib_device *ieee, struct rx_ts_record *pTS) +{ + struct rx_reorder_entry *pRxReorderEntry; + struct rtllib_rxb *RfdArray[REORDER_WIN_SIZE]; + u8 RfdCnt = 0; + + del_timer_sync(&pTS->RxPktPendingTimer); + while (!list_empty(&pTS->RxPendingPktList)) { + if (RfdCnt >= REORDER_WIN_SIZE) { + printk(KERN_INFO "-------------->%s() error! RfdCnt >= REORDER_WIN_SIZE\n", __func__); + break; + } + + pRxReorderEntry = (struct rx_reorder_entry *)list_entry(pTS->RxPendingPktList.prev, struct rx_reorder_entry, List); + RTLLIB_DEBUG(RTLLIB_DL_REORDER, "%s(): Indicate SeqNum %d!\n", __func__, pRxReorderEntry->SeqNum); + list_del_init(&pRxReorderEntry->List); + + RfdArray[RfdCnt] = pRxReorderEntry->prxb; + + RfdCnt = RfdCnt + 1; + list_add_tail(&pRxReorderEntry->List, &ieee->RxReorder_Unused_List); + } + rtllib_indicate_packets(ieee, RfdArray, RfdCnt); + + pTS->RxIndicateSeq = 0xffff; +} + +static void RxReorderIndicatePacket(struct rtllib_device *ieee, + struct rtllib_rxb *prxb, + struct rx_ts_record *pTS, u16 SeqNum) +{ + struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; + struct rx_reorder_entry *pReorderEntry = NULL; + struct rtllib_rxb *prxbIndicateArray[REORDER_WIN_SIZE]; + u8 WinSize = pHTInfo->RxReorderWinSize; + u16 WinEnd = 0; + u8 index = 0; + bool bMatchWinStart = false, bPktInBuf = false; + unsigned long flags; + + RTLLIB_DEBUG(RTLLIB_DL_REORDER, "%s(): Seq is %d, pTS->RxIndicateSeq" + " is %d, WinSize is %d\n", __func__, SeqNum, + pTS->RxIndicateSeq, WinSize); + + spin_lock_irqsave(&(ieee->reorder_spinlock), flags); + + WinEnd = (pTS->RxIndicateSeq + WinSize - 1) % 4096; + /* Rx Reorder initialize condition.*/ + if (pTS->RxIndicateSeq == 0xffff) + pTS->RxIndicateSeq = SeqNum; + + /* Drop out the packet which SeqNum is smaller than WinStart */ + if (SN_LESS(SeqNum, pTS->RxIndicateSeq)) { + RTLLIB_DEBUG(RTLLIB_DL_REORDER, "Packet Drop! IndicateSeq: %d, NewSeq: %d\n", + pTS->RxIndicateSeq, SeqNum); + pHTInfo->RxReorderDropCounter++; + { + int i; + for (i = 0; i < prxb->nr_subframes; i++) + dev_kfree_skb(prxb->subframes[i]); + kfree(prxb); + prxb = NULL; + } + spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags); + return; + } + + /* + * Sliding window manipulation. Conditions includes: + * 1. Incoming SeqNum is equal to WinStart =>Window shift 1 + * 2. Incoming SeqNum is larger than the WinEnd => Window shift N + */ + if (SN_EQUAL(SeqNum, pTS->RxIndicateSeq)) { + pTS->RxIndicateSeq = (pTS->RxIndicateSeq + 1) % 4096; + bMatchWinStart = true; + } else if (SN_LESS(WinEnd, SeqNum)) { + if (SeqNum >= (WinSize - 1)) + pTS->RxIndicateSeq = SeqNum + 1 - WinSize; + else + pTS->RxIndicateSeq = 4095 - (WinSize - (SeqNum + 1)) + 1; + RTLLIB_DEBUG(RTLLIB_DL_REORDER, "Window Shift! IndicateSeq: %d," + " NewSeq: %d\n", pTS->RxIndicateSeq, SeqNum); + } + + /* + * Indication process. + * After Packet dropping and Sliding Window shifting as above, we can + * now just indicate the packets with the SeqNum smaller than latest + * WinStart and struct buffer other packets. + */ + /* For Rx Reorder condition: + * 1. All packets with SeqNum smaller than WinStart => Indicate + * 2. All packets with SeqNum larger than or equal to + * WinStart => Buffer it. + */ + if (bMatchWinStart) { + /* Current packet is going to be indicated.*/ + RTLLIB_DEBUG(RTLLIB_DL_REORDER, "Packets indication!! " + "IndicateSeq: %d, NewSeq: %d\n", + pTS->RxIndicateSeq, SeqNum); + prxbIndicateArray[0] = prxb; + index = 1; + } else { + /* Current packet is going to be inserted into pending list.*/ + if (!list_empty(&ieee->RxReorder_Unused_List)) { + pReorderEntry = (struct rx_reorder_entry *) + list_entry(ieee->RxReorder_Unused_List.next, + struct rx_reorder_entry, List); + list_del_init(&pReorderEntry->List); + + /* Make a reorder entry and insert into a the packet list.*/ + pReorderEntry->SeqNum = SeqNum; + pReorderEntry->prxb = prxb; + + if (!AddReorderEntry(pTS, pReorderEntry)) { + RTLLIB_DEBUG(RTLLIB_DL_REORDER, + "%s(): Duplicate packet is " + "dropped!! IndicateSeq: %d, " + "NewSeq: %d\n", + __func__, pTS->RxIndicateSeq, + SeqNum); + list_add_tail(&pReorderEntry->List, + &ieee->RxReorder_Unused_List); { + int i; + for (i = 0; i < prxb->nr_subframes; i++) + dev_kfree_skb(prxb->subframes[i]); + kfree(prxb); + prxb = NULL; + } + } else { + RTLLIB_DEBUG(RTLLIB_DL_REORDER, + "Pkt insert into struct buffer!! " + "IndicateSeq: %d, NewSeq: %d\n", + pTS->RxIndicateSeq, SeqNum); + } + } else { + /* + * Packets are dropped if there are not enough reorder + * entries. This part should be modified!! We can just + * indicate all the packets in struct buffer and get + * reorder entries. + */ + RTLLIB_DEBUG(RTLLIB_DL_ERR, "RxReorderIndicatePacket():" + " There is no reorder entry!! Packet is " + "dropped!!\n"); + { + int i; + for (i = 0; i < prxb->nr_subframes; i++) + dev_kfree_skb(prxb->subframes[i]); + kfree(prxb); + prxb = NULL; + } + } + } + + /* Check if there is any packet need indicate.*/ + while (!list_empty(&pTS->RxPendingPktList)) { + RTLLIB_DEBUG(RTLLIB_DL_REORDER, "%s(): start RREORDER indicate\n", __func__); + + pReorderEntry = (struct rx_reorder_entry *)list_entry(pTS->RxPendingPktList.prev, + struct rx_reorder_entry, List); + if (SN_LESS(pReorderEntry->SeqNum, pTS->RxIndicateSeq) || + SN_EQUAL(pReorderEntry->SeqNum, pTS->RxIndicateSeq)) { + /* This protect struct buffer from overflow. */ + if (index >= REORDER_WIN_SIZE) { + RTLLIB_DEBUG(RTLLIB_DL_ERR, "RxReorderIndicate" + "Packet(): Buffer overflow!!\n"); + bPktInBuf = true; + break; + } + + list_del_init(&pReorderEntry->List); + + if (SN_EQUAL(pReorderEntry->SeqNum, pTS->RxIndicateSeq)) + pTS->RxIndicateSeq = (pTS->RxIndicateSeq + 1) % 4096; + + prxbIndicateArray[index] = pReorderEntry->prxb; + RTLLIB_DEBUG(RTLLIB_DL_REORDER, "%s(): Indicate SeqNum" + " %d!\n", __func__, pReorderEntry->SeqNum); + index++; + + list_add_tail(&pReorderEntry->List, + &ieee->RxReorder_Unused_List); + } else { + bPktInBuf = true; + break; + } + } + + /* Handling pending timer. Set this timer to prevent from long time + * Rx buffering.*/ + if (index > 0) { + if (timer_pending(&pTS->RxPktPendingTimer)) + del_timer_sync(&pTS->RxPktPendingTimer); + pTS->RxTimeoutIndicateSeq = 0xffff; + + if (index > REORDER_WIN_SIZE) { + RTLLIB_DEBUG(RTLLIB_DL_ERR, "RxReorderIndicatePacket():" + " Rx Reorer struct buffer full!!\n"); + spin_unlock_irqrestore(&(ieee->reorder_spinlock), + flags); + return; + } + rtllib_indicate_packets(ieee, prxbIndicateArray, index); + bPktInBuf = false; + } + + if (bPktInBuf && pTS->RxTimeoutIndicateSeq == 0xffff) { + RTLLIB_DEBUG(RTLLIB_DL_REORDER, "%s(): SET rx timeout timer\n", + __func__); + pTS->RxTimeoutIndicateSeq = pTS->RxIndicateSeq; + mod_timer(&pTS->RxPktPendingTimer, jiffies + + MSECS(pHTInfo->RxReorderPendingTime)); + } + spin_unlock_irqrestore(&(ieee->reorder_spinlock), flags); +} + +static u8 parse_subframe(struct rtllib_device *ieee, struct sk_buff *skb, + struct rtllib_rx_stats *rx_stats, + struct rtllib_rxb *rxb, u8 *src, u8 *dst) +{ + struct rtllib_hdr_3addr *hdr = (struct rtllib_hdr_3addr *)skb->data; + u16 fc = le16_to_cpu(hdr->frame_ctl); + + u16 LLCOffset = sizeof(struct rtllib_hdr_3addr); + u16 ChkLength; + bool bIsAggregateFrame = false; + u16 nSubframe_Length; + u8 nPadding_Length = 0; + u16 SeqNum = 0; + struct sk_buff *sub_skb; + u8 *data_ptr; + /* just for debug purpose */ + SeqNum = WLAN_GET_SEQ_SEQ(le16_to_cpu(hdr->seq_ctl)); + if ((RTLLIB_QOS_HAS_SEQ(fc)) && + (((union frameqos *)(skb->data + RTLLIB_3ADDR_LEN))->field.reserved)) + bIsAggregateFrame = true; + + if (RTLLIB_QOS_HAS_SEQ(fc)) + LLCOffset += 2; + if (rx_stats->bContainHTC) + LLCOffset += sHTCLng; + + ChkLength = LLCOffset; + + if (skb->len <= ChkLength) + return 0; + + skb_pull(skb, LLCOffset); + ieee->bIsAggregateFrame = bIsAggregateFrame; + if (!bIsAggregateFrame) { + rxb->nr_subframes = 1; + + /* altered by clark 3/30/2010 + * The struct buffer size of the skb indicated to upper layer + * must be less than 5000, or the defraged IP datagram + * in the IP layer will exceed "ipfrag_high_tresh" and be + * discarded. so there must not use the function + * "skb_copy" and "skb_clone" for "skb". + */ + + /* Allocate new skb for releasing to upper layer */ + sub_skb = dev_alloc_skb(RTLLIB_SKBBUFFER_SIZE); + skb_reserve(sub_skb, 12); + data_ptr = (u8 *)skb_put(sub_skb, skb->len); + memcpy(data_ptr, skb->data, skb->len); + sub_skb->dev = ieee->dev; + + rxb->subframes[0] = sub_skb; + + memcpy(rxb->src, src, ETH_ALEN); + memcpy(rxb->dst, dst, ETH_ALEN); + rxb->subframes[0]->dev = ieee->dev; + return 1; + } else { + rxb->nr_subframes = 0; + memcpy(rxb->src, src, ETH_ALEN); + memcpy(rxb->dst, dst, ETH_ALEN); + while (skb->len > ETHERNET_HEADER_SIZE) { + /* Offset 12 denote 2 mac address */ + nSubframe_Length = *((u16 *)(skb->data + 12)); + nSubframe_Length = (nSubframe_Length >> 8) + + (nSubframe_Length << 8); + + if (skb->len < (ETHERNET_HEADER_SIZE + nSubframe_Length)) { + printk(KERN_INFO "%s: A-MSDU parse error!! " + "pRfd->nTotalSubframe : %d\n",\ + __func__, rxb->nr_subframes); + printk(KERN_INFO "%s: A-MSDU parse error!! " + "Subframe Length: %d\n", __func__, + nSubframe_Length); + printk(KERN_INFO "nRemain_Length is %d and " + "nSubframe_Length is : %d\n", skb->len, + nSubframe_Length); + printk(KERN_INFO "The Packet SeqNum is %d\n", SeqNum); + return 0; + } + + /* move the data point to data content */ + skb_pull(skb, ETHERNET_HEADER_SIZE); + + /* altered by clark 3/30/2010 + * The struct buffer size of the skb indicated to upper layer + * must be less than 5000, or the defraged IP datagram + * in the IP layer will exceed "ipfrag_high_tresh" and be + * discarded. so there must not use the function + * "skb_copy" and "skb_clone" for "skb". + */ + + /* Allocate new skb for releasing to upper layer */ + sub_skb = dev_alloc_skb(nSubframe_Length + 12); + skb_reserve(sub_skb, 12); + data_ptr = (u8 *)skb_put(sub_skb, nSubframe_Length); + memcpy(data_ptr, skb->data, nSubframe_Length); + + sub_skb->dev = ieee->dev; + rxb->subframes[rxb->nr_subframes++] = sub_skb; + if (rxb->nr_subframes >= MAX_SUBFRAME_COUNT) { + RTLLIB_DEBUG_RX("ParseSubframe(): Too many " + "Subframes! Packets dropped!\n"); + break; + } + skb_pull(skb, nSubframe_Length); + + if (skb->len != 0) { + nPadding_Length = 4 - ((nSubframe_Length + + ETHERNET_HEADER_SIZE) % 4); + if (nPadding_Length == 4) + nPadding_Length = 0; + + if (skb->len < nPadding_Length) + return 0; + + skb_pull(skb, nPadding_Length); + } + } + + return rxb->nr_subframes; + } +} + + +static size_t rtllib_rx_get_hdrlen(struct rtllib_device *ieee, + struct sk_buff *skb, + struct rtllib_rx_stats *rx_stats) +{ + struct rtllib_hdr_4addr *hdr = (struct rtllib_hdr_4addr *)skb->data; + u16 fc = le16_to_cpu(hdr->frame_ctl); + size_t hdrlen = 0; + + hdrlen = rtllib_get_hdrlen(fc); + if (HTCCheck(ieee, skb->data)) { + if (net_ratelimit()) + printk(KERN_INFO "%s: find HTCControl!\n", __func__); + hdrlen += 4; + rx_stats->bContainHTC = 1; + } + + if (RTLLIB_QOS_HAS_SEQ(fc)) + rx_stats->bIsQosData = 1; + + return hdrlen; +} + +static int rtllib_rx_check_duplicate(struct rtllib_device *ieee, + struct sk_buff *skb, u8 multicast) +{ + struct rtllib_hdr_4addr *hdr = (struct rtllib_hdr_4addr *)skb->data; + u16 fc, sc; + u8 frag, type, stype; + + fc = le16_to_cpu(hdr->frame_ctl); + type = WLAN_FC_GET_TYPE(fc); + stype = WLAN_FC_GET_STYPE(fc); + sc = le16_to_cpu(hdr->seq_ctl); + frag = WLAN_GET_SEQ_FRAG(sc); + + if ((ieee->pHTInfo->bCurRxReorderEnable == false) || + !ieee->current_network.qos_data.active || + !IsDataFrame(skb->data) || + IsLegacyDataFrame(skb->data)) { + if (!((type == RTLLIB_FTYPE_MGMT) && (stype == RTLLIB_STYPE_BEACON))) { + if (is_duplicate_packet(ieee, hdr)) + return -1; + } + } else { + struct rx_ts_record *pRxTS = NULL; + if (GetTs(ieee, (struct ts_common_info **) &pRxTS, hdr->addr2, + (u8)Frame_QoSTID((u8 *)(skb->data)), RX_DIR, true)) { + if ((fc & (1<<11)) && (frag == pRxTS->RxLastFragNum) && + (WLAN_GET_SEQ_SEQ(sc) == pRxTS->RxLastSeqNum)) { + return -1; + } else { + pRxTS->RxLastFragNum = frag; + pRxTS->RxLastSeqNum = WLAN_GET_SEQ_SEQ(sc); + } + } else { + RTLLIB_DEBUG(RTLLIB_DL_ERR, "ERR!!%s(): No TS!! Skip" + " the check!!\n", __func__); + return -1; + } + } + + return 0; +} + +static void rtllib_rx_extract_addr(struct rtllib_device *ieee, + struct rtllib_hdr_4addr *hdr, u8 *dst, + u8 *src, u8 *bssid) +{ + u16 fc = le16_to_cpu(hdr->frame_ctl); + + switch (fc & (RTLLIB_FCTL_FROMDS | RTLLIB_FCTL_TODS)) { + case RTLLIB_FCTL_FROMDS: + memcpy(dst, hdr->addr1, ETH_ALEN); + memcpy(src, hdr->addr3, ETH_ALEN); + memcpy(bssid, hdr->addr2, ETH_ALEN); + break; + case RTLLIB_FCTL_TODS: + memcpy(dst, hdr->addr3, ETH_ALEN); + memcpy(src, hdr->addr2, ETH_ALEN); + memcpy(bssid, hdr->addr1, ETH_ALEN); + break; + case RTLLIB_FCTL_FROMDS | RTLLIB_FCTL_TODS: + memcpy(dst, hdr->addr3, ETH_ALEN); + memcpy(src, hdr->addr4, ETH_ALEN); + memcpy(bssid, ieee->current_network.bssid, ETH_ALEN); + break; + case 0: + memcpy(dst, hdr->addr1, ETH_ALEN); + memcpy(src, hdr->addr2, ETH_ALEN); + memcpy(bssid, hdr->addr3, ETH_ALEN); + break; + } +} + +static int rtllib_rx_data_filter(struct rtllib_device *ieee, u16 fc, + u8 *dst, u8 *src, u8 *bssid, u8 *addr2) +{ + u8 zero_addr[ETH_ALEN] = {0}; + u8 type, stype; + + type = WLAN_FC_GET_TYPE(fc); + stype = WLAN_FC_GET_STYPE(fc); + + /* Filter frames from different BSS */ + if (((fc & RTLLIB_FCTL_DSTODS) != RTLLIB_FCTL_DSTODS) + && (compare_ether_addr(ieee->current_network.bssid, bssid) != 0) + && memcmp(ieee->current_network.bssid, zero_addr, ETH_ALEN)) { + return -1; + } + + /* Filter packets sent by an STA that will be forwarded by AP */ + if (ieee->IntelPromiscuousModeInfo.bPromiscuousOn && + ieee->IntelPromiscuousModeInfo.bFilterSourceStationFrame) { + if ((fc & RTLLIB_FCTL_TODS) && !(fc & RTLLIB_FCTL_FROMDS) && + (compare_ether_addr(dst, ieee->current_network.bssid) != 0) && + (compare_ether_addr(bssid, ieee->current_network.bssid) == 0)) { + return -1; + } + } + + /* Nullfunc frames may have PS-bit set, so they must be passed to + * hostap_handle_sta_rx() before being dropped here. */ + if (!ieee->IntelPromiscuousModeInfo.bPromiscuousOn) { + if (stype != RTLLIB_STYPE_DATA && + stype != RTLLIB_STYPE_DATA_CFACK && + stype != RTLLIB_STYPE_DATA_CFPOLL && + stype != RTLLIB_STYPE_DATA_CFACKPOLL && + stype != RTLLIB_STYPE_QOS_DATA) { + if (stype != RTLLIB_STYPE_NULLFUNC) + RTLLIB_DEBUG_DROP( + "RX: dropped data frame " + "with no data (type=0x%02x, " + "subtype=0x%02x)\n", + type, stype); + return -1; + } + } + + if (ieee->iw_mode != IW_MODE_MESH) { + /* packets from our adapter are dropped (echo) */ + if (!memcmp(src, ieee->dev->dev_addr, ETH_ALEN)) + return -1; + + /* {broad,multi}cast packets to our BSS go through */ + if (is_multicast_ether_addr(dst) || is_broadcast_ether_addr(dst)) { + if (memcmp(bssid, ieee->current_network.bssid, ETH_ALEN)) + return -1; + } + } + return 0; +} + +static int rtllib_rx_get_crypt(struct rtllib_device *ieee, struct sk_buff *skb, + struct rtllib_crypt_data **crypt, size_t hdrlen) +{ + struct rtllib_hdr_4addr *hdr = (struct rtllib_hdr_4addr *)skb->data; + u16 fc = le16_to_cpu(hdr->frame_ctl); + int idx = 0; + + if (ieee->host_decrypt) { + if (skb->len >= hdrlen + 3) + idx = skb->data[hdrlen + 3] >> 6; + + *crypt = ieee->crypt[idx]; + /* allow NULL decrypt to indicate an station specific override + * for default encryption */ + if (*crypt && ((*crypt)->ops == NULL || + (*crypt)->ops->decrypt_mpdu == NULL)) + *crypt = NULL; + + if (!*crypt && (fc & RTLLIB_FCTL_WEP)) { + /* This seems to be triggered by some (multicast?) + * frames from other than current BSS, so just drop the + * frames silently instead of filling system log with + * these reports. */ + RTLLIB_DEBUG_DROP("Decryption failed (not set)" + " (SA= %pM)\n", + hdr->addr2); + ieee->ieee_stats.rx_discards_undecryptable++; + return -1; + } + } + + return 0; +} + +static int rtllib_rx_decrypt(struct rtllib_device *ieee, struct sk_buff *skb, + struct rtllib_rx_stats *rx_stats, + struct rtllib_crypt_data *crypt, size_t hdrlen) +{ + struct rtllib_hdr_4addr *hdr; + int keyidx = 0; + u16 fc, sc; + u8 frag; + + hdr = (struct rtllib_hdr_4addr *)skb->data; + fc = le16_to_cpu(hdr->frame_ctl); + sc = le16_to_cpu(hdr->seq_ctl); + frag = WLAN_GET_SEQ_FRAG(sc); + + if ((!rx_stats->Decrypted)) + ieee->need_sw_enc = 1; + else + ieee->need_sw_enc = 0; + + keyidx = rtllib_rx_frame_decrypt(ieee, skb, crypt); + if (ieee->host_decrypt && (fc & RTLLIB_FCTL_WEP) && (keyidx < 0)) { + printk(KERN_INFO "%s: decrypt frame error\n", __func__); + return -1; + } + + hdr = (struct rtllib_hdr_4addr *) skb->data; + if ((frag != 0 || (fc & RTLLIB_FCTL_MOREFRAGS))) { + int flen; + struct sk_buff *frag_skb = rtllib_frag_cache_get(ieee, hdr); + RTLLIB_DEBUG_FRAG("Rx Fragment received (%u)\n", frag); + + if (!frag_skb) { + RTLLIB_DEBUG(RTLLIB_DL_RX | RTLLIB_DL_FRAG, + "Rx cannot get skb from fragment " + "cache (morefrag=%d seq=%u frag=%u)\n", + (fc & RTLLIB_FCTL_MOREFRAGS) != 0, + WLAN_GET_SEQ_SEQ(sc), frag); + return -1; + } + flen = skb->len; + if (frag != 0) + flen -= hdrlen; + + if (frag_skb->tail + flen > frag_skb->end) { + printk(KERN_WARNING "%s: host decrypted and " + "reassembled frame did not fit skb\n", + __func__); + rtllib_frag_cache_invalidate(ieee, hdr); + return -1; + } + + if (frag == 0) { + /* copy first fragment (including full headers) into + * beginning of the fragment cache skb */ + memcpy(skb_put(frag_skb, flen), skb->data, flen); + } else { + /* append frame payload to the end of the fragment + * cache skb */ + memcpy(skb_put(frag_skb, flen), skb->data + hdrlen, + flen); + } + dev_kfree_skb_any(skb); + skb = NULL; + + if (fc & RTLLIB_FCTL_MOREFRAGS) { + /* more fragments expected - leave the skb in fragment + * cache for now; it will be delivered to upper layers + * after all fragments have been received */ + return -2; + } + + /* this was the last fragment and the frame will be + * delivered, so remove skb from fragment cache */ + skb = frag_skb; + hdr = (struct rtllib_hdr_4addr *) skb->data; + rtllib_frag_cache_invalidate(ieee, hdr); + } + + /* skb: hdr + (possible reassembled) full MSDU payload; possibly still + * encrypted/authenticated */ + if (ieee->host_decrypt && (fc & RTLLIB_FCTL_WEP) && + rtllib_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt)) { + printk(KERN_INFO "%s: ==>decrypt msdu error\n", __func__); + return -1; + } + + hdr = (struct rtllib_hdr_4addr *) skb->data; + if (crypt && !(fc & RTLLIB_FCTL_WEP) && !ieee->open_wep) { + if (/*ieee->ieee802_1x &&*/ + rtllib_is_eapol_frame(ieee, skb, hdrlen)) { + + /* pass unencrypted EAPOL frames even if encryption is + * configured */ + struct eapol *eap = (struct eapol *)(skb->data + + 24); + RTLLIB_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n", + eap_get_type(eap->type)); + } else { + RTLLIB_DEBUG_DROP( + "encryption configured, but RX " + "frame not encrypted (SA= %pM)\n", + hdr->addr2); + return -1; + } + } + + if (crypt && !(fc & RTLLIB_FCTL_WEP) && + rtllib_is_eapol_frame(ieee, skb, hdrlen)) { + struct eapol *eap = (struct eapol *)(skb->data + + 24); + RTLLIB_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n", + eap_get_type(eap->type)); + } + + if (crypt && !(fc & RTLLIB_FCTL_WEP) && !ieee->open_wep && + !rtllib_is_eapol_frame(ieee, skb, hdrlen)) { + RTLLIB_DEBUG_DROP( + "dropped unencrypted RX data " + "frame from %pM" + " (drop_unencrypted=1)\n", + hdr->addr2); + return -1; + } + + if (rtllib_is_eapol_frame(ieee, skb, hdrlen)) + printk(KERN_WARNING "RX: IEEE802.1X EAPOL frame!\n"); + + return 0; +} + +static void rtllib_rx_check_leave_lps(struct rtllib_device *ieee, u8 unicast, u8 nr_subframes) +{ + if (unicast) { + + if ((ieee->state == RTLLIB_LINKED)) { + if (((ieee->LinkDetectInfo.NumRxUnicastOkInPeriod + + ieee->LinkDetectInfo.NumTxOkInPeriod) > 8) || + (ieee->LinkDetectInfo.NumRxUnicastOkInPeriod > 2)) { + if (ieee->LeisurePSLeave) + ieee->LeisurePSLeave(ieee->dev); + } + } + } + ieee->last_rx_ps_time = jiffies; +} + +static void rtllib_rx_indicate_pkt_legacy(struct rtllib_device *ieee, + struct rtllib_rx_stats *rx_stats, + struct rtllib_rxb *rxb, + u8 *dst, + u8 *src) +{ + struct net_device *dev = ieee->dev; + u16 ethertype; + int i = 0; + + if (rxb == NULL) { + printk(KERN_INFO "%s: rxb is NULL!!\n", __func__); + return ; + } + + for (i = 0; i < rxb->nr_subframes; i++) { + struct sk_buff *sub_skb = rxb->subframes[i]; + + if (sub_skb) { + /* convert hdr + possible LLC headers into Ethernet header */ + ethertype = (sub_skb->data[6] << 8) | sub_skb->data[7]; + if (sub_skb->len >= 8 && + ((memcmp(sub_skb->data, rfc1042_header, SNAP_SIZE) == 0 && + ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) || + memcmp(sub_skb->data, bridge_tunnel_header, SNAP_SIZE) == 0)) { + /* remove RFC1042 or Bridge-Tunnel encapsulation and + * replace EtherType */ + skb_pull(sub_skb, SNAP_SIZE); + memcpy(skb_push(sub_skb, ETH_ALEN), src, ETH_ALEN); + memcpy(skb_push(sub_skb, ETH_ALEN), dst, ETH_ALEN); + } else { + u16 len; + /* Leave Ethernet header part of hdr and full payload */ + len = htons(sub_skb->len); + memcpy(skb_push(sub_skb, 2), &len, 2); + memcpy(skb_push(sub_skb, ETH_ALEN), src, ETH_ALEN); + memcpy(skb_push(sub_skb, ETH_ALEN), dst, ETH_ALEN); + } + + ieee->stats.rx_packets++; + ieee->stats.rx_bytes += sub_skb->len; + + if (is_multicast_ether_addr(dst)) + ieee->stats.multicast++; + + /* Indicat the packets to upper layer */ + memset(sub_skb->cb, 0, sizeof(sub_skb->cb)); + sub_skb->protocol = eth_type_trans(sub_skb, dev); + sub_skb->dev = dev; + sub_skb->dev->stats.rx_packets++; + sub_skb->dev->stats.rx_bytes += sub_skb->len; + sub_skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */ + netif_rx(sub_skb); + } + } + kfree(rxb); + rxb = NULL; +} + +static int rtllib_rx_InfraAdhoc(struct rtllib_device *ieee, struct sk_buff *skb, + struct rtllib_rx_stats *rx_stats) +{ + struct net_device *dev = ieee->dev; + struct rtllib_hdr_4addr *hdr = (struct rtllib_hdr_4addr *)skb->data; + struct rtllib_crypt_data *crypt = NULL; + struct rtllib_rxb *rxb = NULL; + struct rx_ts_record *pTS = NULL; + u16 fc, sc, SeqNum = 0; + u8 type, stype, multicast = 0, unicast = 0, nr_subframes = 0, TID = 0; + u8 dst[ETH_ALEN], src[ETH_ALEN], bssid[ETH_ALEN] = {0}, *payload; + size_t hdrlen = 0; + bool bToOtherSTA = false; + int ret = 0, i = 0; + + hdr = (struct rtllib_hdr_4addr *)skb->data; + fc = le16_to_cpu(hdr->frame_ctl); + type = WLAN_FC_GET_TYPE(fc); + stype = WLAN_FC_GET_STYPE(fc); + sc = le16_to_cpu(hdr->seq_ctl); + + /*Filter pkt not to me*/ + multicast = is_multicast_ether_addr(hdr->addr1)|is_broadcast_ether_addr(hdr->addr1); + unicast = !multicast; + if (unicast && (compare_ether_addr(dev->dev_addr, hdr->addr1) != 0)) { + if (ieee->bNetPromiscuousMode) + bToOtherSTA = true; + else + goto rx_dropped; + } + + /*Filter pkt has too small length */ + hdrlen = rtllib_rx_get_hdrlen(ieee, skb, rx_stats); + if (skb->len < hdrlen) { + printk(KERN_INFO "%s():ERR!!! skb->len is smaller than hdrlen\n", __func__); + goto rx_dropped; + } + + /* Filter Duplicate pkt */ + ret = rtllib_rx_check_duplicate(ieee, skb, multicast); + if (ret < 0) + goto rx_dropped; + + /* Filter CTRL Frame */ + if (type == RTLLIB_FTYPE_CTL) + goto rx_dropped; + + /* Filter MGNT Frame */ + if (type == RTLLIB_FTYPE_MGMT) { + if (bToOtherSTA) + goto rx_dropped; + if (rtllib_rx_frame_mgmt(ieee, skb, rx_stats, type, stype)) + goto rx_dropped; + else + goto rx_exit; + } + + /* Filter WAPI DATA Frame */ + + /* Update statstics for AP roaming */ + if (!bToOtherSTA) { + ieee->LinkDetectInfo.NumRecvDataInPeriod++; + ieee->LinkDetectInfo.NumRxOkInPeriod++; + } + dev->last_rx = jiffies; + + /* Data frame - extract src/dst addresses */ + rtllib_rx_extract_addr(ieee, hdr, dst, src, bssid); + + /* Filter Data frames */ + ret = rtllib_rx_data_filter(ieee, fc, dst, src, bssid, hdr->addr2); + if (ret < 0) + goto rx_dropped; + + if (skb->len == hdrlen) + goto rx_dropped; + + /* Send pspoll based on moredata */ + if ((ieee->iw_mode == IW_MODE_INFRA) && (ieee->sta_sleep == LPS_IS_SLEEP) + && (ieee->polling) && (!bToOtherSTA)) { + if (WLAN_FC_MORE_DATA(fc)) { + /* more data bit is set, let's request a new frame from the AP */ + rtllib_sta_ps_send_pspoll_frame(ieee); + } else { + ieee->polling = false; + } + } + + /* Get crypt if encrypted */ + ret = rtllib_rx_get_crypt(ieee, skb, &crypt, hdrlen); + if (ret == -1) + goto rx_dropped; + + /* Decrypt data frame (including reassemble) */ + ret = rtllib_rx_decrypt(ieee, skb, rx_stats, crypt, hdrlen); + if (ret == -1) + goto rx_dropped; + else if (ret == -2) + goto rx_exit; + + /* Get TS for Rx Reorder */ + hdr = (struct rtllib_hdr_4addr *) skb->data; + if (ieee->current_network.qos_data.active && IsQoSDataFrame(skb->data) + && !is_multicast_ether_addr(hdr->addr1) && !is_broadcast_ether_addr(hdr->addr1) + && (!bToOtherSTA)) { + TID = Frame_QoSTID(skb->data); + SeqNum = WLAN_GET_SEQ_SEQ(sc); + GetTs(ieee, (struct ts_common_info **) &pTS, hdr->addr2, TID, RX_DIR, true); + if (TID != 0 && TID != 3) + ieee->bis_any_nonbepkts = true; + } + + /* Parse rx data frame (For AMSDU) */ + /* skb: hdr + (possible reassembled) full plaintext payload */ + payload = skb->data + hdrlen; + rxb = kmalloc(sizeof(struct rtllib_rxb), GFP_ATOMIC); + if (rxb == NULL) { + RTLLIB_DEBUG(RTLLIB_DL_ERR, + "%s(): kmalloc rxb error\n", __func__); + goto rx_dropped; + } + /* to parse amsdu packets */ + /* qos data packets & reserved bit is 1 */ + if (parse_subframe(ieee, skb, rx_stats, rxb, src, dst) == 0) { + /* only to free rxb, and not submit the packets to upper layer */ + for (i = 0; i < rxb->nr_subframes; i++) + dev_kfree_skb(rxb->subframes[i]); + kfree(rxb); + rxb = NULL; + goto rx_dropped; + } + + /* Update WAPI PN */ + + /* Check if leave LPS */ + if (!bToOtherSTA) { + if (ieee->bIsAggregateFrame) + nr_subframes = rxb->nr_subframes; + else + nr_subframes = 1; + if (unicast) + ieee->LinkDetectInfo.NumRxUnicastOkInPeriod += nr_subframes; + rtllib_rx_check_leave_lps(ieee, unicast, nr_subframes); + } + + /* Indicate packets to upper layer or Rx Reorder */ + if (ieee->pHTInfo->bCurRxReorderEnable == false || pTS == NULL || bToOtherSTA) + rtllib_rx_indicate_pkt_legacy(ieee, rx_stats, rxb, dst, src); + else + RxReorderIndicatePacket(ieee, rxb, pTS, SeqNum); + + dev_kfree_skb(skb); + + rx_exit: + return 1; + + rx_dropped: + if (rxb != NULL) { + kfree(rxb); + rxb = NULL; + } + ieee->stats.rx_dropped++; + + /* Returning 0 indicates to caller that we have not handled the SKB-- + * so it is still allocated and can be used again by underlying + * hardware as a DMA target */ + return 0; +} + +static int rtllib_rx_Master(struct rtllib_device *ieee, struct sk_buff *skb, + struct rtllib_rx_stats *rx_stats) +{ + return 0; +} + +static int rtllib_rx_Monitor(struct rtllib_device *ieee, struct sk_buff *skb, + struct rtllib_rx_stats *rx_stats) +{ + struct rtllib_hdr_4addr *hdr = (struct rtllib_hdr_4addr *)skb->data; + u16 fc = le16_to_cpu(hdr->frame_ctl); + size_t hdrlen = rtllib_get_hdrlen(fc); + + if (skb->len < hdrlen) { + printk(KERN_INFO "%s():ERR!!! skb->len is smaller than hdrlen\n", __func__); + return 0; + } + + if (HTCCheck(ieee, skb->data)) { + if (net_ratelimit()) + printk(KERN_INFO "%s: Find HTCControl!\n", __func__); + hdrlen += 4; + } + + rtllib_monitor_rx(ieee, skb, rx_stats, hdrlen); + ieee->stats.rx_packets++; + ieee->stats.rx_bytes += skb->len; + + return 1; +} + +static int rtllib_rx_Mesh(struct rtllib_device *ieee, struct sk_buff *skb, + struct rtllib_rx_stats *rx_stats) +{ + return 0; +} + +/* All received frames are sent to this function. @skb contains the frame in + * IEEE 802.11 format, i.e., in the format it was sent over air. + * This function is called only as a tasklet (software IRQ). */ +int rtllib_rx(struct rtllib_device *ieee, struct sk_buff *skb, + struct rtllib_rx_stats *rx_stats) +{ + int ret = 0; + + if ((NULL == ieee) || (NULL == skb) || (NULL == rx_stats)) { + printk(KERN_INFO "%s: Input parameters NULL!\n", __func__); + goto rx_dropped; + } + if (skb->len < 10) { + printk(KERN_INFO "%s: SKB length < 10\n", __func__); + goto rx_dropped; + } + + switch (ieee->iw_mode) { + case IW_MODE_ADHOC: + case IW_MODE_INFRA: + ret = rtllib_rx_InfraAdhoc(ieee, skb, rx_stats); + break; + case IW_MODE_MASTER: + case IW_MODE_REPEAT: + ret = rtllib_rx_Master(ieee, skb, rx_stats); + break; + case IW_MODE_MONITOR: + ret = rtllib_rx_Monitor(ieee, skb, rx_stats); + break; + case IW_MODE_MESH: + ret = rtllib_rx_Mesh(ieee, skb, rx_stats); + break; + default: + printk(KERN_INFO"%s: ERR iw mode!!!\n", __func__); + break; + } + + return ret; + + rx_dropped: + ieee->stats.rx_dropped++; + return 0; +} + +static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 }; + +/* +* Make ther structure we read from the beacon packet has +* the right values +*/ +static int rtllib_verify_qos_info(struct rtllib_qos_information_element + *info_element, int sub_type) +{ + + if (info_element->qui_subtype != sub_type) + return -1; + if (memcmp(info_element->qui, qos_oui, QOS_OUI_LEN)) + return -1; + if (info_element->qui_type != QOS_OUI_TYPE) + return -1; + if (info_element->version != QOS_VERSION_1) + return -1; + + return 0; +} + + +/* + * Parse a QoS parameter element + */ +static int rtllib_read_qos_param_element(struct rtllib_qos_parameter_info + *element_param, struct rtllib_info_element + *info_element) +{ + int ret = 0; + u16 size = sizeof(struct rtllib_qos_parameter_info) - 2; + + if ((info_element == NULL) || (element_param == NULL)) + return -1; + + if (info_element->id == QOS_ELEMENT_ID && info_element->len == size) { + memcpy(element_param->info_element.qui, info_element->data, + info_element->len); + element_param->info_element.elementID = info_element->id; + element_param->info_element.length = info_element->len; + } else + ret = -1; + if (ret == 0) + ret = rtllib_verify_qos_info(&element_param->info_element, + QOS_OUI_PARAM_SUB_TYPE); + return ret; +} + +/* + * Parse a QoS information element + */ +static int rtllib_read_qos_info_element(struct + rtllib_qos_information_element + *element_info, struct rtllib_info_element + *info_element) +{ + int ret = 0; + u16 size = sizeof(struct rtllib_qos_information_element) - 2; + + if (element_info == NULL) + return -1; + if (info_element == NULL) + return -1; + + if ((info_element->id == QOS_ELEMENT_ID) && (info_element->len == size)) { + memcpy(element_info->qui, info_element->data, + info_element->len); + element_info->elementID = info_element->id; + element_info->length = info_element->len; + } else + ret = -1; + + if (ret == 0) + ret = rtllib_verify_qos_info(element_info, + QOS_OUI_INFO_SUB_TYPE); + return ret; +} + + +/* + * Write QoS parameters from the ac parameters. + */ +static int rtllib_qos_convert_ac_to_parameters(struct rtllib_qos_parameter_info *param_elm, + struct rtllib_qos_data *qos_data) +{ + struct rtllib_qos_ac_parameter *ac_params; + struct rtllib_qos_parameters *qos_param = &(qos_data->parameters); + int rc = 0; + int i; + u8 aci; + u8 acm; + + qos_data->wmm_acm = 0; + for (i = 0; i < QOS_QUEUE_NUM; i++) { + ac_params = &(param_elm->ac_params_record[i]); + + aci = (ac_params->aci_aifsn & 0x60) >> 5; + acm = (ac_params->aci_aifsn & 0x10) >> 4; + + if (aci >= QOS_QUEUE_NUM) + continue; + switch (aci) { + case 1: + /* BIT(0) | BIT(3) */ + if (acm) + qos_data->wmm_acm |= (0x01<<0)|(0x01<<3); + break; + case 2: + /* BIT(4) | BIT(5) */ + if (acm) + qos_data->wmm_acm |= (0x01<<4)|(0x01<<5); + break; + case 3: + /* BIT(6) | BIT(7) */ + if (acm) + qos_data->wmm_acm |= (0x01<<6)|(0x01<<7); + break; + case 0: + default: + /* BIT(1) | BIT(2) */ + if (acm) + qos_data->wmm_acm |= (0x01<<1)|(0x01<<2); + break; + } + + qos_param->aifs[aci] = (ac_params->aci_aifsn) & 0x0f; + + /* WMM spec P.11: The minimum value for AIFSN shall be 2 */ + qos_param->aifs[aci] = (qos_param->aifs[aci] < 2) ? 2 : qos_param->aifs[aci]; + + qos_param->cw_min[aci] = ac_params->ecw_min_max & 0x0F; + + qos_param->cw_max[aci] = (ac_params->ecw_min_max & 0xF0) >> 4; + + qos_param->flag[aci] = + (ac_params->aci_aifsn & 0x10) ? 0x01 : 0x00; + qos_param->tx_op_limit[aci] = le16_to_cpu(ac_params->tx_op_limit); + } + return rc; +} + +/* + * we have a generic data element which it may contain QoS information or + * parameters element. check the information element length to decide + * which type to read + */ +static int rtllib_parse_qos_info_param_IE(struct rtllib_info_element + *info_element, + struct rtllib_network *network) +{ + int rc = 0; + struct rtllib_qos_information_element qos_info_element; + + rc = rtllib_read_qos_info_element(&qos_info_element, info_element); + + if (rc == 0) { + network->qos_data.param_count = qos_info_element.ac_info & 0x0F; + network->flags |= NETWORK_HAS_QOS_INFORMATION; + } else { + struct rtllib_qos_parameter_info param_element; + + rc = rtllib_read_qos_param_element(¶m_element, + info_element); + if (rc == 0) { + rtllib_qos_convert_ac_to_parameters(¶m_element, + &(network->qos_data)); + network->flags |= NETWORK_HAS_QOS_PARAMETERS; + network->qos_data.param_count = + param_element.info_element.ac_info & 0x0F; + } + } + + if (rc == 0) { + RTLLIB_DEBUG_QOS("QoS is supported\n"); + network->qos_data.supported = 1; + } + return rc; +} + +#define MFIE_STRING(x) case MFIE_TYPE_ ##x: return #x + +static const char *get_info_element_string(u16 id) +{ + switch (id) { + MFIE_STRING(SSID); + MFIE_STRING(RATES); + MFIE_STRING(FH_SET); + MFIE_STRING(DS_SET); + MFIE_STRING(CF_SET); + MFIE_STRING(TIM); + MFIE_STRING(IBSS_SET); + MFIE_STRING(COUNTRY); + MFIE_STRING(HOP_PARAMS); + MFIE_STRING(HOP_TABLE); + MFIE_STRING(REQUEST); + MFIE_STRING(CHALLENGE); + MFIE_STRING(POWER_CONSTRAINT); + MFIE_STRING(POWER_CAPABILITY); + MFIE_STRING(TPC_REQUEST); + MFIE_STRING(TPC_REPORT); + MFIE_STRING(SUPP_CHANNELS); + MFIE_STRING(CSA); + MFIE_STRING(MEASURE_REQUEST); + MFIE_STRING(MEASURE_REPORT); + MFIE_STRING(QUIET); + MFIE_STRING(IBSS_DFS); + MFIE_STRING(RSN); + MFIE_STRING(RATES_EX); + MFIE_STRING(GENERIC); + MFIE_STRING(QOS_PARAMETER); + default: + return "UNKNOWN"; + } +} + +static inline void rtllib_extract_country_ie( + struct rtllib_device *ieee, + struct rtllib_info_element *info_element, + struct rtllib_network *network, + u8 *addr2) +{ + if (IS_DOT11D_ENABLE(ieee)) { + if (info_element->len != 0) { + memcpy(network->CountryIeBuf, info_element->data, info_element->len); + network->CountryIeLen = info_element->len; + + if (!IS_COUNTRY_IE_VALID(ieee)) { + if ((rtllib_act_scanning(ieee, false) == true) && (ieee->FirstIe_InScan == 1)) + printk(KERN_INFO "Received beacon ContryIE, SSID: <%s>\n", network->ssid); + Dot11d_UpdateCountryIe(ieee, addr2, info_element->len, info_element->data); + } + } + + if (IS_EQUAL_CIE_SRC(ieee, addr2)) + UPDATE_CIE_WATCHDOG(ieee); + } + +} + +int rtllib_parse_info_param(struct rtllib_device *ieee, + struct rtllib_info_element *info_element, + u16 length, + struct rtllib_network *network, + struct rtllib_rx_stats *stats) +{ + u8 i; + short offset; + u16 tmp_htcap_len = 0; + u16 tmp_htinfo_len = 0; + u16 ht_realtek_agg_len = 0; + u8 ht_realtek_agg_buf[MAX_IE_LEN]; + char rates_str[64]; + char *p; + + while (length >= sizeof(*info_element)) { + if (sizeof(*info_element) + info_element->len > length) { + RTLLIB_DEBUG_MGMT("Info elem: parse failed: " + "info_element->len + 2 > left : " + "info_element->len+2=%zd left=%d, id=%d.\n", + info_element->len + + sizeof(*info_element), + length, info_element->id); + /* We stop processing but don't return an error here + * because some misbehaviour APs break this rule. ie. + * Orinoco AP1000. */ + break; + } + + switch (info_element->id) { + case MFIE_TYPE_SSID: + if (rtllib_is_empty_essid(info_element->data, + info_element->len)) { + network->flags |= NETWORK_EMPTY_ESSID; + break; + } + + network->ssid_len = min(info_element->len, + (u8) IW_ESSID_MAX_SIZE); + memcpy(network->ssid, info_element->data, network->ssid_len); + if (network->ssid_len < IW_ESSID_MAX_SIZE) + memset(network->ssid + network->ssid_len, 0, + IW_ESSID_MAX_SIZE - network->ssid_len); + + RTLLIB_DEBUG_MGMT("MFIE_TYPE_SSID: '%s' len=%d.\n", + network->ssid, network->ssid_len); + break; + + case MFIE_TYPE_RATES: + p = rates_str; + network->rates_len = min(info_element->len, + MAX_RATES_LENGTH); + for (i = 0; i < network->rates_len; i++) { + network->rates[i] = info_element->data[i]; + p += snprintf(p, sizeof(rates_str) - + (p - rates_str), "%02X ", + network->rates[i]); + if (rtllib_is_ofdm_rate + (info_element->data[i])) { + network->flags |= NETWORK_HAS_OFDM; + if (info_element->data[i] & + RTLLIB_BASIC_RATE_MASK) + network->flags &= + ~NETWORK_HAS_CCK; + } + + if (rtllib_is_cck_rate + (info_element->data[i])) { + network->flags |= NETWORK_HAS_CCK; + } + } + + RTLLIB_DEBUG_MGMT("MFIE_TYPE_RATES: '%s' (%d)\n", + rates_str, network->rates_len); + break; + + case MFIE_TYPE_RATES_EX: + p = rates_str; + network->rates_ex_len = min(info_element->len, + MAX_RATES_EX_LENGTH); + for (i = 0; i < network->rates_ex_len; i++) { + network->rates_ex[i] = info_element->data[i]; + p += snprintf(p, sizeof(rates_str) - + (p - rates_str), "%02X ", + network->rates[i]); + if (rtllib_is_ofdm_rate + (info_element->data[i])) { + network->flags |= NETWORK_HAS_OFDM; + if (info_element->data[i] & + RTLLIB_BASIC_RATE_MASK) + network->flags &= + ~NETWORK_HAS_CCK; + } + } + + RTLLIB_DEBUG_MGMT("MFIE_TYPE_RATES_EX: '%s' (%d)\n", + rates_str, network->rates_ex_len); + break; + + case MFIE_TYPE_DS_SET: + RTLLIB_DEBUG_MGMT("MFIE_TYPE_DS_SET: %d\n", + info_element->data[0]); + network->channel = info_element->data[0]; + break; + + case MFIE_TYPE_FH_SET: + RTLLIB_DEBUG_MGMT("MFIE_TYPE_FH_SET: ignored\n"); + break; + + case MFIE_TYPE_CF_SET: + RTLLIB_DEBUG_MGMT("MFIE_TYPE_CF_SET: ignored\n"); + break; + + case MFIE_TYPE_TIM: + if (info_element->len < 4) + break; + + network->tim.tim_count = info_element->data[0]; + network->tim.tim_period = info_element->data[1]; + + network->dtim_period = info_element->data[1]; + if (ieee->state != RTLLIB_LINKED) + break; + network->last_dtim_sta_time = jiffies; + + network->dtim_data = RTLLIB_DTIM_VALID; + + + if (info_element->data[2] & 1) + network->dtim_data |= RTLLIB_DTIM_MBCAST; + + offset = (info_element->data[2] >> 1)*2; + + + if (ieee->assoc_id < 8*offset || + ieee->assoc_id > 8*(offset + info_element->len - 3)) + break; + + offset = (ieee->assoc_id / 8) - offset; + if (info_element->data[3 + offset] & + (1 << (ieee->assoc_id % 8))) + network->dtim_data |= RTLLIB_DTIM_UCAST; + + network->listen_interval = network->dtim_period; + break; + + case MFIE_TYPE_ERP: + network->erp_value = info_element->data[0]; + network->flags |= NETWORK_HAS_ERP_VALUE; + RTLLIB_DEBUG_MGMT("MFIE_TYPE_ERP_SET: %d\n", + network->erp_value); + break; + case MFIE_TYPE_IBSS_SET: + network->atim_window = info_element->data[0]; + RTLLIB_DEBUG_MGMT("MFIE_TYPE_IBSS_SET: %d\n", + network->atim_window); + break; + + case MFIE_TYPE_CHALLENGE: + RTLLIB_DEBUG_MGMT("MFIE_TYPE_CHALLENGE: ignored\n"); + break; + + case MFIE_TYPE_GENERIC: + RTLLIB_DEBUG_MGMT("MFIE_TYPE_GENERIC: %d bytes\n", + info_element->len); + if (!rtllib_parse_qos_info_param_IE(info_element, + network)) + break; + if (info_element->len >= 4 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x50 && + info_element->data[2] == 0xf2 && + info_element->data[3] == 0x01) { + network->wpa_ie_len = min(info_element->len + 2, + MAX_WPA_IE_LEN); + memcpy(network->wpa_ie, info_element, + network->wpa_ie_len); + break; + } + if (info_element->len == 7 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0xe0 && + info_element->data[2] == 0x4c && + info_element->data[3] == 0x01 && + info_element->data[4] == 0x02) + network->Turbo_Enable = 1; + + if (tmp_htcap_len == 0) { + if (info_element->len >= 4 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x90 && + info_element->data[2] == 0x4c && + info_element->data[3] == 0x033) { + + tmp_htcap_len = min(info_element->len, (u8)MAX_IE_LEN); + if (tmp_htcap_len != 0) { + network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC; + network->bssht.bdHTCapLen = tmp_htcap_len > sizeof(network->bssht.bdHTCapBuf) ? + sizeof(network->bssht.bdHTCapBuf) : tmp_htcap_len; + memcpy(network->bssht.bdHTCapBuf, info_element->data, network->bssht.bdHTCapLen); + } + } + if (tmp_htcap_len != 0) { + network->bssht.bdSupportHT = true; + network->bssht.bdHT1R = ((((struct ht_capab_ele *)(network->bssht.bdHTCapBuf))->MCS[1]) == 0); + } else { + network->bssht.bdSupportHT = false; + network->bssht.bdHT1R = false; + } + } + + + if (tmp_htinfo_len == 0) { + if (info_element->len >= 4 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x90 && + info_element->data[2] == 0x4c && + info_element->data[3] == 0x034) { + tmp_htinfo_len = min(info_element->len, (u8)MAX_IE_LEN); + if (tmp_htinfo_len != 0) { + network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC; + if (tmp_htinfo_len) { + network->bssht.bdHTInfoLen = tmp_htinfo_len > sizeof(network->bssht.bdHTInfoBuf) ? + sizeof(network->bssht.bdHTInfoBuf) : tmp_htinfo_len; + memcpy(network->bssht.bdHTInfoBuf, info_element->data, network->bssht.bdHTInfoLen); + } + + } + + } + } + + if (ieee->aggregation) { + if (network->bssht.bdSupportHT) { + if (info_element->len >= 4 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0xe0 && + info_element->data[2] == 0x4c && + info_element->data[3] == 0x02) { + ht_realtek_agg_len = min(info_element->len, (u8)MAX_IE_LEN); + memcpy(ht_realtek_agg_buf, info_element->data, info_element->len); + } + if (ht_realtek_agg_len >= 5) { + network->realtek_cap_exit = true; + network->bssht.bdRT2RTAggregation = true; + + if ((ht_realtek_agg_buf[4] == 1) && (ht_realtek_agg_buf[5] & 0x02)) + network->bssht.bdRT2RTLongSlotTime = true; + + if ((ht_realtek_agg_buf[4] == 1) && (ht_realtek_agg_buf[5] & RT_HT_CAP_USE_92SE)) + network->bssht.RT2RT_HT_Mode |= RT_HT_CAP_USE_92SE; + } + } + if (ht_realtek_agg_len >= 5) { + if ((ht_realtek_agg_buf[5] & RT_HT_CAP_USE_SOFTAP)) + network->bssht.RT2RT_HT_Mode |= RT_HT_CAP_USE_SOFTAP; + } + } + + if ((info_element->len >= 3 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x05 && + info_element->data[2] == 0xb5) || + (info_element->len >= 3 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x0a && + info_element->data[2] == 0xf7) || + (info_element->len >= 3 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x10 && + info_element->data[2] == 0x18)) { + network->broadcom_cap_exist = true; + } + if (info_element->len >= 3 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x0c && + info_element->data[2] == 0x43) + network->ralink_cap_exist = true; + if ((info_element->len >= 3 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x03 && + info_element->data[2] == 0x7f) || + (info_element->len >= 3 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x13 && + info_element->data[2] == 0x74)) + network->atheros_cap_exist = true; + + if ((info_element->len >= 3 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x50 && + info_element->data[2] == 0x43)) + network->marvell_cap_exist = true; + if (info_element->len >= 3 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x40 && + info_element->data[2] == 0x96) + network->cisco_cap_exist = true; + + + if (info_element->len >= 3 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x0a && + info_element->data[2] == 0xf5) + network->airgo_cap_exist = true; + + if (info_element->len > 4 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x40 && + info_element->data[2] == 0x96 && + info_element->data[3] == 0x01) { + if (info_element->len == 6) { + memcpy(network->CcxRmState, &info_element[4], 2); + if (network->CcxRmState[0] != 0) + network->bCcxRmEnable = true; + else + network->bCcxRmEnable = false; + network->MBssidMask = network->CcxRmState[1] & 0x07; + if (network->MBssidMask != 0) { + network->bMBssidValid = true; + network->MBssidMask = 0xff << (network->MBssidMask); + memcpy(network->MBssid, network->bssid, ETH_ALEN); + network->MBssid[5] &= network->MBssidMask; + } else { + network->bMBssidValid = false; + } + } else { + network->bCcxRmEnable = false; + } + } + if (info_element->len > 4 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x40 && + info_element->data[2] == 0x96 && + info_element->data[3] == 0x03) { + if (info_element->len == 5) { + network->bWithCcxVerNum = true; + network->BssCcxVerNumber = info_element->data[4]; + } else { + network->bWithCcxVerNum = false; + network->BssCcxVerNumber = 0; + } + } + if (info_element->len > 4 && + info_element->data[0] == 0x00 && + info_element->data[1] == 0x50 && + info_element->data[2] == 0xf2 && + info_element->data[3] == 0x04) { + RTLLIB_DEBUG_MGMT("MFIE_TYPE_WZC: %d bytes\n", + info_element->len); + network->wzc_ie_len = min(info_element->len+2, + MAX_WZC_IE_LEN); + memcpy(network->wzc_ie, info_element, + network->wzc_ie_len); + } + break; + + case MFIE_TYPE_RSN: + RTLLIB_DEBUG_MGMT("MFIE_TYPE_RSN: %d bytes\n", + info_element->len); + network->rsn_ie_len = min(info_element->len + 2, + MAX_WPA_IE_LEN); + memcpy(network->rsn_ie, info_element, + network->rsn_ie_len); + break; + + case MFIE_TYPE_HT_CAP: + RTLLIB_DEBUG_SCAN("MFIE_TYPE_HT_CAP: %d bytes\n", + info_element->len); + tmp_htcap_len = min(info_element->len, (u8)MAX_IE_LEN); + if (tmp_htcap_len != 0) { + network->bssht.bdHTSpecVer = HT_SPEC_VER_EWC; + network->bssht.bdHTCapLen = tmp_htcap_len > sizeof(network->bssht.bdHTCapBuf) ? + sizeof(network->bssht.bdHTCapBuf) : tmp_htcap_len; + memcpy(network->bssht.bdHTCapBuf, + info_element->data, + network->bssht.bdHTCapLen); + + network->bssht.bdSupportHT = true; + network->bssht.bdHT1R = ((((struct ht_capab_ele *) + network->bssht.bdHTCapBuf))->MCS[1]) == 0; + + network->bssht.bdBandWidth = (enum ht_channel_width) + (((struct ht_capab_ele *) + (network->bssht.bdHTCapBuf))->ChlWidth); + } else { + network->bssht.bdSupportHT = false; + network->bssht.bdHT1R = false; + network->bssht.bdBandWidth = HT_CHANNEL_WIDTH_20; + } + break; + + + case MFIE_TYPE_HT_INFO: + RTLLIB_DEBUG_SCAN("MFIE_TYPE_HT_INFO: %d bytes\n", + info_element->len); + tmp_htinfo_len = min(info_element->len, (u8)MAX_IE_LEN); + if (tmp_htinfo_len) { + network->bssht.bdHTSpecVer = HT_SPEC_VER_IEEE; + network->bssht.bdHTInfoLen = tmp_htinfo_len > + sizeof(network->bssht.bdHTInfoBuf) ? + sizeof(network->bssht.bdHTInfoBuf) : + tmp_htinfo_len; + memcpy(network->bssht.bdHTInfoBuf, + info_element->data, + network->bssht.bdHTInfoLen); + } + break; + + case MFIE_TYPE_AIRONET: + RTLLIB_DEBUG_SCAN("MFIE_TYPE_AIRONET: %d bytes\n", + info_element->len); + if (info_element->len > IE_CISCO_FLAG_POSITION) { + network->bWithAironetIE = true; + + if ((info_element->data[IE_CISCO_FLAG_POSITION] + & SUPPORT_CKIP_MIC) || + (info_element->data[IE_CISCO_FLAG_POSITION] + & SUPPORT_CKIP_PK)) + network->bCkipSupported = true; + else + network->bCkipSupported = false; + } else { + network->bWithAironetIE = false; + network->bCkipSupported = false; + } + break; + case MFIE_TYPE_QOS_PARAMETER: + printk(KERN_ERR + "QoS Error need to parse QOS_PARAMETER IE\n"); + break; + + case MFIE_TYPE_COUNTRY: + RTLLIB_DEBUG_SCAN("MFIE_TYPE_COUNTRY: %d bytes\n", + info_element->len); + rtllib_extract_country_ie(ieee, info_element, network, + network->bssid); + break; +/* TODO */ + default: + RTLLIB_DEBUG_MGMT + ("Unsupported info element: %s (%d)\n", + get_info_element_string(info_element->id), + info_element->id); + break; + } + + length -= sizeof(*info_element) + info_element->len; + info_element = + (struct rtllib_info_element *)&info_element-> + data[info_element->len]; + } + + if (!network->atheros_cap_exist && !network->broadcom_cap_exist && + !network->cisco_cap_exist && !network->ralink_cap_exist && + !network->bssht.bdRT2RTAggregation) + network->unknown_cap_exist = true; + else + network->unknown_cap_exist = false; + return 0; +} + +static inline u8 rtllib_SignalStrengthTranslate(u8 CurrSS) +{ + u8 RetSS; + + if (CurrSS >= 71 && CurrSS <= 100) + RetSS = 90 + ((CurrSS - 70) / 3); + else if (CurrSS >= 41 && CurrSS <= 70) + RetSS = 78 + ((CurrSS - 40) / 3); + else if (CurrSS >= 31 && CurrSS <= 40) + RetSS = 66 + (CurrSS - 30); + else if (CurrSS >= 21 && CurrSS <= 30) + RetSS = 54 + (CurrSS - 20); + else if (CurrSS >= 5 && CurrSS <= 20) + RetSS = 42 + (((CurrSS - 5) * 2) / 3); + else if (CurrSS == 4) + RetSS = 36; + else if (CurrSS == 3) + RetSS = 27; + else if (CurrSS == 2) + RetSS = 18; + else if (CurrSS == 1) + RetSS = 9; + else + RetSS = CurrSS; + + return RetSS; +} + +static long rtllib_translate_todbm(u8 signal_strength_index) +{ + long signal_power; + + signal_power = (long)((signal_strength_index + 1) >> 1); + signal_power -= 95; + + return signal_power; +} + +static inline int rtllib_network_init( + struct rtllib_device *ieee, + struct rtllib_probe_response *beacon, + struct rtllib_network *network, + struct rtllib_rx_stats *stats) +{ + + /* + network->qos_data.active = 0; + network->qos_data.supported = 0; + network->qos_data.param_count = 0; + network->qos_data.old_param_count = 0; + */ + memset(&network->qos_data, 0, sizeof(struct rtllib_qos_data)); + + /* Pull out fixed field data */ + memcpy(network->bssid, beacon->header.addr3, ETH_ALEN); + network->capability = le16_to_cpu(beacon->capability); + network->last_scanned = jiffies; + network->time_stamp[0] = le32_to_cpu(beacon->time_stamp[0]); + network->time_stamp[1] = le32_to_cpu(beacon->time_stamp[1]); + network->beacon_interval = le32_to_cpu(beacon->beacon_interval); + /* Where to pull this? beacon->listen_interval;*/ + network->listen_interval = 0x0A; + network->rates_len = network->rates_ex_len = 0; + network->last_associate = 0; + network->ssid_len = 0; + network->hidden_ssid_len = 0; + memset(network->hidden_ssid, 0, sizeof(network->hidden_ssid)); + network->flags = 0; + network->atim_window = 0; + network->erp_value = (network->capability & WLAN_CAPABILITY_IBSS) ? + 0x3 : 0x0; + network->berp_info_valid = false; + network->broadcom_cap_exist = false; + network->ralink_cap_exist = false; + network->atheros_cap_exist = false; + network->cisco_cap_exist = false; + network->unknown_cap_exist = false; + network->realtek_cap_exit = false; + network->marvell_cap_exist = false; + network->airgo_cap_exist = false; + network->Turbo_Enable = 0; + network->SignalStrength = stats->SignalStrength; + network->RSSI = stats->SignalStrength; + network->CountryIeLen = 0; + memset(network->CountryIeBuf, 0, MAX_IE_LEN); + HTInitializeBssDesc(&network->bssht); + if (stats->freq == RTLLIB_52GHZ_BAND) { + /* for A band (No DS info) */ + network->channel = stats->received_channel; + } else + network->flags |= NETWORK_HAS_CCK; + + network->wpa_ie_len = 0; + network->rsn_ie_len = 0; + network->wzc_ie_len = 0; + + if (rtllib_parse_info_param(ieee, + beacon->info_element, + (stats->len - sizeof(*beacon)), + network, + stats)) + return 1; + + network->mode = 0; + if (stats->freq == RTLLIB_52GHZ_BAND) + network->mode = IEEE_A; + else { + if (network->flags & NETWORK_HAS_OFDM) + network->mode |= IEEE_G; + if (network->flags & NETWORK_HAS_CCK) + network->mode |= IEEE_B; + } + + if (network->mode == 0) { + RTLLIB_DEBUG_SCAN("Filtered out '%s (%pM)' " + "network.\n", + escape_essid(network->ssid, + network->ssid_len), + network->bssid); + return 1; + } + + if (network->bssht.bdSupportHT) { + if (network->mode == IEEE_A) + network->mode = IEEE_N_5G; + else if (network->mode & (IEEE_G | IEEE_B)) + network->mode = IEEE_N_24G; + } + if (rtllib_is_empty_essid(network->ssid, network->ssid_len)) + network->flags |= NETWORK_EMPTY_ESSID; + stats->signal = 30 + (stats->SignalStrength * 70) / 100; + stats->noise = rtllib_translate_todbm((u8)(100-stats->signal)) - 25; + + memcpy(&network->stats, stats, sizeof(network->stats)); + + return 0; +} + +static inline int is_same_network(struct rtllib_network *src, + struct rtllib_network *dst, u8 ssidbroad) +{ + /* A network is only a duplicate if the channel, BSSID, ESSID + * and the capability field (in particular IBSS and BSS) all match. + * We treat all <hidden> with the same BSSID and channel + * as one network */ + return (((src->ssid_len == dst->ssid_len) || (!ssidbroad)) && + (src->channel == dst->channel) && + !memcmp(src->bssid, dst->bssid, ETH_ALEN) && + (!memcmp(src->ssid, dst->ssid, src->ssid_len) || + (!ssidbroad)) && + ((src->capability & WLAN_CAPABILITY_IBSS) == + (dst->capability & WLAN_CAPABILITY_IBSS)) && + ((src->capability & WLAN_CAPABILITY_ESS) == + (dst->capability & WLAN_CAPABILITY_ESS))); +} + +static inline void update_ibss_network(struct rtllib_network *dst, + struct rtllib_network *src) +{ + memcpy(&dst->stats, &src->stats, sizeof(struct rtllib_rx_stats)); + dst->last_scanned = jiffies; +} + + +static inline void update_network(struct rtllib_network *dst, + struct rtllib_network *src) +{ + int qos_active; + u8 old_param; + + memcpy(&dst->stats, &src->stats, sizeof(struct rtllib_rx_stats)); + dst->capability = src->capability; + memcpy(dst->rates, src->rates, src->rates_len); + dst->rates_len = src->rates_len; + memcpy(dst->rates_ex, src->rates_ex, src->rates_ex_len); + dst->rates_ex_len = src->rates_ex_len; + if (src->ssid_len > 0) { + if (dst->ssid_len == 0) { + memset(dst->hidden_ssid, 0, sizeof(dst->hidden_ssid)); + dst->hidden_ssid_len = src->ssid_len; + memcpy(dst->hidden_ssid, src->ssid, src->ssid_len); + } else { + memset(dst->ssid, 0, dst->ssid_len); + dst->ssid_len = src->ssid_len; + memcpy(dst->ssid, src->ssid, src->ssid_len); + } + } + dst->mode = src->mode; + dst->flags = src->flags; + dst->time_stamp[0] = src->time_stamp[0]; + dst->time_stamp[1] = src->time_stamp[1]; + if (src->flags & NETWORK_HAS_ERP_VALUE) { + dst->erp_value = src->erp_value; + dst->berp_info_valid = src->berp_info_valid = true; + } + dst->beacon_interval = src->beacon_interval; + dst->listen_interval = src->listen_interval; + dst->atim_window = src->atim_window; + dst->dtim_period = src->dtim_period; + dst->dtim_data = src->dtim_data; + dst->last_dtim_sta_time = src->last_dtim_sta_time; + memcpy(&dst->tim, &src->tim, sizeof(struct rtllib_tim_parameters)); + + dst->bssht.bdSupportHT = src->bssht.bdSupportHT; + dst->bssht.bdRT2RTAggregation = src->bssht.bdRT2RTAggregation; + dst->bssht.bdHTCapLen = src->bssht.bdHTCapLen; + memcpy(dst->bssht.bdHTCapBuf, src->bssht.bdHTCapBuf, + src->bssht.bdHTCapLen); + dst->bssht.bdHTInfoLen = src->bssht.bdHTInfoLen; + memcpy(dst->bssht.bdHTInfoBuf, src->bssht.bdHTInfoBuf, + src->bssht.bdHTInfoLen); + dst->bssht.bdHTSpecVer = src->bssht.bdHTSpecVer; + dst->bssht.bdRT2RTLongSlotTime = src->bssht.bdRT2RTLongSlotTime; + dst->broadcom_cap_exist = src->broadcom_cap_exist; + dst->ralink_cap_exist = src->ralink_cap_exist; + dst->atheros_cap_exist = src->atheros_cap_exist; + dst->realtek_cap_exit = src->realtek_cap_exit; + dst->marvell_cap_exist = src->marvell_cap_exist; + dst->cisco_cap_exist = src->cisco_cap_exist; + dst->airgo_cap_exist = src->airgo_cap_exist; + dst->unknown_cap_exist = src->unknown_cap_exist; + memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len); + dst->wpa_ie_len = src->wpa_ie_len; + memcpy(dst->rsn_ie, src->rsn_ie, src->rsn_ie_len); + dst->rsn_ie_len = src->rsn_ie_len; + memcpy(dst->wzc_ie, src->wzc_ie, src->wzc_ie_len); + dst->wzc_ie_len = src->wzc_ie_len; + + dst->last_scanned = jiffies; + /* qos related parameters */ + qos_active = dst->qos_data.active; + old_param = dst->qos_data.param_count; + dst->qos_data.supported = src->qos_data.supported; + if (dst->flags & NETWORK_HAS_QOS_PARAMETERS) + memcpy(&dst->qos_data, &src->qos_data, + sizeof(struct rtllib_qos_data)); + if (dst->qos_data.supported == 1) { + if (dst->ssid_len) + RTLLIB_DEBUG_QOS + ("QoS the network %s is QoS supported\n", + dst->ssid); + else + RTLLIB_DEBUG_QOS + ("QoS the network is QoS supported\n"); + } + dst->qos_data.active = qos_active; + dst->qos_data.old_param_count = old_param; + + /* dst->last_associate is not overwritten */ + dst->wmm_info = src->wmm_info; + if (src->wmm_param[0].ac_aci_acm_aifsn || + src->wmm_param[1].ac_aci_acm_aifsn || + src->wmm_param[2].ac_aci_acm_aifsn || + src->wmm_param[1].ac_aci_acm_aifsn) + memcpy(dst->wmm_param, src->wmm_param, WME_AC_PRAM_LEN); + + dst->SignalStrength = src->SignalStrength; + dst->RSSI = src->RSSI; + dst->Turbo_Enable = src->Turbo_Enable; + + dst->CountryIeLen = src->CountryIeLen; + memcpy(dst->CountryIeBuf, src->CountryIeBuf, src->CountryIeLen); + + dst->bWithAironetIE = src->bWithAironetIE; + dst->bCkipSupported = src->bCkipSupported; + memcpy(dst->CcxRmState, src->CcxRmState, 2); + dst->bCcxRmEnable = src->bCcxRmEnable; + dst->MBssidMask = src->MBssidMask; + dst->bMBssidValid = src->bMBssidValid; + memcpy(dst->MBssid, src->MBssid, 6); + dst->bWithCcxVerNum = src->bWithCcxVerNum; + dst->BssCcxVerNumber = src->BssCcxVerNumber; +} + +static inline int is_beacon(__le16 fc) +{ + return (WLAN_FC_GET_STYPE(le16_to_cpu(fc)) == RTLLIB_STYPE_BEACON); +} + +static int IsPassiveChannel(struct rtllib_device *rtllib, u8 channel) +{ + if (MAX_CHANNEL_NUMBER < channel) { + printk(KERN_INFO "%s(): Invalid Channel\n", __func__); + return 0; + } + + if (rtllib->active_channel_map[channel] == 2) + return 1; + + return 0; +} + +int IsLegalChannel(struct rtllib_device *rtllib, u8 channel) +{ + if (MAX_CHANNEL_NUMBER < channel) { + printk(KERN_INFO "%s(): Invalid Channel\n", __func__); + return 0; + } + if (rtllib->active_channel_map[channel] > 0) + return 1; + + return 0; +} + +static inline void rtllib_process_probe_response( + struct rtllib_device *ieee, + struct rtllib_probe_response *beacon, + struct rtllib_rx_stats *stats) +{ + struct rtllib_network *target; + struct rtllib_network *oldest = NULL; + struct rtllib_info_element *info_element = &beacon->info_element[0]; + unsigned long flags; + short renew; + struct rtllib_network *network = kzalloc(sizeof(struct rtllib_network), + GFP_ATOMIC); + + if (!network) + return; + + RTLLIB_DEBUG_SCAN( + "'%s' ( %pM ): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n", + escape_essid(info_element->data, info_element->len), + beacon->header.addr3, + (beacon->capability & (1<<0xf)) ? '1' : '0', + (beacon->capability & (1<<0xe)) ? '1' : '0', + (beacon->capability & (1<<0xd)) ? '1' : '0', + (beacon->capability & (1<<0xc)) ? '1' : '0', + (beacon->capability & (1<<0xb)) ? '1' : '0', + (beacon->capability & (1<<0xa)) ? '1' : '0', + (beacon->capability & (1<<0x9)) ? '1' : '0', + (beacon->capability & (1<<0x8)) ? '1' : '0', + (beacon->capability & (1<<0x7)) ? '1' : '0', + (beacon->capability & (1<<0x6)) ? '1' : '0', + (beacon->capability & (1<<0x5)) ? '1' : '0', + (beacon->capability & (1<<0x4)) ? '1' : '0', + (beacon->capability & (1<<0x3)) ? '1' : '0', + (beacon->capability & (1<<0x2)) ? '1' : '0', + (beacon->capability & (1<<0x1)) ? '1' : '0', + (beacon->capability & (1<<0x0)) ? '1' : '0'); + + if (rtllib_network_init(ieee, beacon, network, stats)) { + RTLLIB_DEBUG_SCAN("Dropped '%s' ( %pM) via %s.\n", + escape_essid(info_element->data, + info_element->len), + beacon->header.addr3, + WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == + RTLLIB_STYPE_PROBE_RESP ? + "PROBE RESPONSE" : "BEACON"); + goto free_network; + } + + + if (!IsLegalChannel(ieee, network->channel)) + goto free_network; + + if (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == + RTLLIB_STYPE_PROBE_RESP) { + if (IsPassiveChannel(ieee, network->channel)) { + printk(KERN_INFO "GetScanInfo(): For Global Domain, " + "filter probe response at channel(%d).\n", + network->channel); + goto free_network; + } + } + + /* The network parsed correctly -- so now we scan our known networks + * to see if we can find it in our list. + * + * NOTE: This search is definitely not optimized. Once its doing + * the "right thing" we'll optimize it for efficiency if + * necessary */ + + /* Search for this entry in the list and update it if it is + * already there. */ + + spin_lock_irqsave(&ieee->lock, flags); + if (is_same_network(&ieee->current_network, network, + (network->ssid_len ? 1 : 0))) { + update_network(&ieee->current_network, network); + if ((ieee->current_network.mode == IEEE_N_24G || + ieee->current_network.mode == IEEE_G) + && ieee->current_network.berp_info_valid) { + if (ieee->current_network.erp_value & ERP_UseProtection) + ieee->current_network.buseprotection = true; + else + ieee->current_network.buseprotection = false; + } + if (is_beacon(beacon->header.frame_ctl)) { + if (ieee->state >= RTLLIB_LINKED) + ieee->LinkDetectInfo.NumRecvBcnInPeriod++; + } + } + list_for_each_entry(target, &ieee->network_list, list) { + if (is_same_network(target, network, + (target->ssid_len ? 1 : 0))) + break; + if ((oldest == NULL) || + (target->last_scanned < oldest->last_scanned)) + oldest = target; + } + + /* If we didn't find a match, then get a new network slot to initialize + * with this beacon's information */ + if (&target->list == &ieee->network_list) { + if (list_empty(&ieee->network_free_list)) { + /* If there are no more slots, expire the oldest */ + list_del(&oldest->list); + target = oldest; + RTLLIB_DEBUG_SCAN("Expired '%s' ( %pM) from " + "network list.\n", + escape_essid(target->ssid, + target->ssid_len), + target->bssid); + } else { + /* Otherwise just pull from the free list */ + target = list_entry(ieee->network_free_list.next, + struct rtllib_network, list); + list_del(ieee->network_free_list.next); + } + + + RTLLIB_DEBUG_SCAN("Adding '%s' ( %pM) via %s.\n", + escape_essid(network->ssid, + network->ssid_len), network->bssid, + WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == + RTLLIB_STYPE_PROBE_RESP ? + "PROBE RESPONSE" : "BEACON"); + memcpy(target, network, sizeof(*target)); + list_add_tail(&target->list, &ieee->network_list); + if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) + rtllib_softmac_new_net(ieee, network); + } else { + RTLLIB_DEBUG_SCAN("Updating '%s' ( %pM) via %s.\n", + escape_essid(target->ssid, + target->ssid_len), target->bssid, + WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == + RTLLIB_STYPE_PROBE_RESP ? + "PROBE RESPONSE" : "BEACON"); + + /* we have an entry and we are going to update it. But this + * entry may be already expired. In this case we do the same + * as we found a new net and call the new_net handler + */ + renew = !time_after(target->last_scanned + ieee->scan_age, + jiffies); + if ((!target->ssid_len) && + (((network->ssid_len > 0) && (target->hidden_ssid_len == 0)) + || ((ieee->current_network.ssid_len == network->ssid_len) && + (strncmp(ieee->current_network.ssid, network->ssid, + network->ssid_len) == 0) && + (ieee->state == RTLLIB_NOLINK)))) + renew = 1; + update_network(target, network); + if (renew && (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE)) + rtllib_softmac_new_net(ieee, network); + } + + spin_unlock_irqrestore(&ieee->lock, flags); + if (is_beacon(beacon->header.frame_ctl) && + is_same_network(&ieee->current_network, network, + (network->ssid_len ? 1 : 0)) && + (ieee->state == RTLLIB_LINKED)) { + if (ieee->handle_beacon != NULL) + ieee->handle_beacon(ieee->dev, beacon, + &ieee->current_network); + } +free_network: + kfree(network); + return; +} + +void rtllib_rx_mgt(struct rtllib_device *ieee, + struct sk_buff *skb, + struct rtllib_rx_stats *stats) +{ + struct rtllib_hdr_4addr *header = (struct rtllib_hdr_4addr *)skb->data ; + + if (WLAN_FC_GET_STYPE(header->frame_ctl) != RTLLIB_STYPE_PROBE_RESP && + WLAN_FC_GET_STYPE(header->frame_ctl) != RTLLIB_STYPE_BEACON) + ieee->last_rx_ps_time = jiffies; + + switch (WLAN_FC_GET_STYPE(header->frame_ctl)) { + + case RTLLIB_STYPE_BEACON: + RTLLIB_DEBUG_MGMT("received BEACON (%d)\n", + WLAN_FC_GET_STYPE(header->frame_ctl)); + RTLLIB_DEBUG_SCAN("Beacon\n"); + rtllib_process_probe_response( + ieee, (struct rtllib_probe_response *)header, + stats); + + if (ieee->sta_sleep || (ieee->ps != RTLLIB_PS_DISABLED && + ieee->iw_mode == IW_MODE_INFRA && + ieee->state == RTLLIB_LINKED)) + tasklet_schedule(&ieee->ps_task); + + break; + + case RTLLIB_STYPE_PROBE_RESP: + RTLLIB_DEBUG_MGMT("received PROBE RESPONSE (%d)\n", + WLAN_FC_GET_STYPE(header->frame_ctl)); + RTLLIB_DEBUG_SCAN("Probe response\n"); + rtllib_process_probe_response(ieee, + (struct rtllib_probe_response *)header, stats); + break; + case RTLLIB_STYPE_PROBE_REQ: + RTLLIB_DEBUG_MGMT("received PROBE RESQUEST (%d)\n", + WLAN_FC_GET_STYPE(header->frame_ctl)); + RTLLIB_DEBUG_SCAN("Probe request\n"); + if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) && + ((ieee->iw_mode == IW_MODE_ADHOC || + ieee->iw_mode == IW_MODE_MASTER) && + ieee->state == RTLLIB_LINKED)) + rtllib_rx_probe_rq(ieee, skb); + break; + } +} diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c new file mode 100644 index 0000000..a420ed1 --- /dev/null +++ b/drivers/staging/rtl8192e/rtllib_softmac.c @@ -0,0 +1,3743 @@ +/* IEEE 802.11 SoftMAC layer + * Copyright (c) 2005 Andrea Merello <andreamrl@tiscali.it> + * + * Mostly extracted from the rtl8180-sa2400 driver for the + * in-kernel generic ieee802.11 stack. + * + * Few lines might be stolen from other part of the rtllib + * stack. Copyright who own it's copyright + * + * WPA code stolen from the ipw2200 driver. + * Copyright who own it's copyright. + * + * released under the GPL + */ + + +#include "rtllib.h" +#include "rtl_core.h" + +#include <linux/random.h> +#include <linux/delay.h> +#include <linux/version.h> +#include <linux/uaccess.h> +#include "dot11d.h" + +short rtllib_is_54g(struct rtllib_network *net) +{ + return (net->rates_ex_len > 0) || (net->rates_len > 4); +} + +short rtllib_is_shortslot(struct rtllib_network net) +{ + return net.capability & WLAN_CAPABILITY_SHORT_SLOT_TIME; +} + +/* returns the total length needed for pleacing the RATE MFIE + * tag and the EXTENDED RATE MFIE tag if needed. + * It encludes two bytes per tag for the tag itself and its len + */ +static unsigned int rtllib_MFIE_rate_len(struct rtllib_device *ieee) +{ + unsigned int rate_len = 0; + + if (ieee->modulation & RTLLIB_CCK_MODULATION) + rate_len = RTLLIB_CCK_RATE_LEN + 2; + + if (ieee->modulation & RTLLIB_OFDM_MODULATION) + + rate_len += RTLLIB_OFDM_RATE_LEN + 2; + + return rate_len; +} + +/* pleace the MFIE rate, tag to the memory (double) poined. + * Then it updates the pointer so that + * it points after the new MFIE tag added. + */ +static void rtllib_MFIE_Brate(struct rtllib_device *ieee, u8 **tag_p) +{ + u8 *tag = *tag_p; + + if (ieee->modulation & RTLLIB_CCK_MODULATION) { + *tag++ = MFIE_TYPE_RATES; + *tag++ = 4; + *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_1MB; + *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_2MB; + *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_5MB; + *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_11MB; + } + + /* We may add an option for custom rates that specific HW + * might support */ + *tag_p = tag; +} + +static void rtllib_MFIE_Grate(struct rtllib_device *ieee, u8 **tag_p) +{ + u8 *tag = *tag_p; + + if (ieee->modulation & RTLLIB_OFDM_MODULATION) { + *tag++ = MFIE_TYPE_RATES_EX; + *tag++ = 8; + *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_6MB; + *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_9MB; + *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_12MB; + *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_18MB; + *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_24MB; + *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_36MB; + *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_48MB; + *tag++ = RTLLIB_BASIC_RATE_MASK | RTLLIB_OFDM_RATE_54MB; + } + /* We may add an option for custom rates that specific HW might + * support */ + *tag_p = tag; +} + +static void rtllib_WMM_Info(struct rtllib_device *ieee, u8 **tag_p) +{ + u8 *tag = *tag_p; + + *tag++ = MFIE_TYPE_GENERIC; + *tag++ = 7; + *tag++ = 0x00; + *tag++ = 0x50; + *tag++ = 0xf2; + *tag++ = 0x02; + *tag++ = 0x00; + *tag++ = 0x01; + *tag++ = MAX_SP_Len; + *tag_p = tag; +} + +void rtllib_TURBO_Info(struct rtllib_device *ieee, u8 **tag_p) +{ + u8 *tag = *tag_p; + + *tag++ = MFIE_TYPE_GENERIC; + *tag++ = 7; + *tag++ = 0x00; + *tag++ = 0xe0; + *tag++ = 0x4c; + *tag++ = 0x01; + *tag++ = 0x02; + *tag++ = 0x11; + *tag++ = 0x00; + + *tag_p = tag; + printk(KERN_ALERT "This is enable turbo mode IE process\n"); +} + +static void enqueue_mgmt(struct rtllib_device *ieee, struct sk_buff *skb) +{ + int nh; + nh = (ieee->mgmt_queue_head + 1) % MGMT_QUEUE_NUM; + +/* + * if the queue is full but we have newer frames then + * just overwrites the oldest. + * + * if (nh == ieee->mgmt_queue_tail) + * return -1; + */ + ieee->mgmt_queue_head = nh; + ieee->mgmt_queue_ring[nh] = skb; + +} + +static struct sk_buff *dequeue_mgmt(struct rtllib_device *ieee) +{ + struct sk_buff *ret; + + if (ieee->mgmt_queue_tail == ieee->mgmt_queue_head) + return NULL; + + ret = ieee->mgmt_queue_ring[ieee->mgmt_queue_tail]; + + ieee->mgmt_queue_tail = + (ieee->mgmt_queue_tail+1) % MGMT_QUEUE_NUM; + + return ret; +} + +static void init_mgmt_queue(struct rtllib_device *ieee) +{ + ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0; +} + + +u8 +MgntQuery_TxRateExcludeCCKRates(struct rtllib_device *ieee) +{ + u16 i; + u8 QueryRate = 0; + u8 BasicRate; + + + for (i = 0; i < ieee->current_network.rates_len; i++) { + BasicRate = ieee->current_network.rates[i]&0x7F; + if (!rtllib_is_cck_rate(BasicRate)) { + if (QueryRate == 0) { + QueryRate = BasicRate; + } else { + if (BasicRate < QueryRate) + QueryRate = BasicRate; + } + } + } + + if (QueryRate == 0) { + QueryRate = 12; + printk(KERN_INFO "No BasicRate found!!\n"); + } + return QueryRate; +} + +u8 MgntQuery_MgntFrameTxRate(struct rtllib_device *ieee) +{ + struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; + u8 rate; + + if (pHTInfo->IOTAction & HT_IOT_ACT_MGNT_USE_CCK_6M) + rate = 0x0c; + else + rate = ieee->basic_rate & 0x7f; + + if (rate == 0) { + if (ieee->mode == IEEE_A || + ieee->mode == IEEE_N_5G || + (ieee->mode == IEEE_N_24G && !pHTInfo->bCurSuppCCK)) + rate = 0x0c; + else + rate = 0x02; + } + + return rate; +} + +inline void softmac_mgmt_xmit(struct sk_buff *skb, struct rtllib_device *ieee) +{ + unsigned long flags; + short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE; + struct rtllib_hdr_3addr *header = + (struct rtllib_hdr_3addr *) skb->data; + + struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + 8); + spin_lock_irqsave(&ieee->lock, flags); + + /* called with 2nd param 0, no mgmt lock required */ + rtllib_sta_wakeup(ieee, 0); + + if (header->frame_ctl == RTLLIB_STYPE_BEACON) + tcb_desc->queue_index = BEACON_QUEUE; + else + tcb_desc->queue_index = MGNT_QUEUE; + + if (ieee->disable_mgnt_queue) + tcb_desc->queue_index = HIGH_QUEUE; + + tcb_desc->data_rate = MgntQuery_MgntFrameTxRate(ieee); + tcb_desc->RATRIndex = 7; + tcb_desc->bTxDisableRateFallBack = 1; + tcb_desc->bTxUseDriverAssingedRate = 1; + if (single) { + if (ieee->queue_stop) { + enqueue_mgmt(ieee, skb); + } else { + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4); + + if (ieee->seq_ctrl[0] == 0xFFF) + ieee->seq_ctrl[0] = 0; + else + ieee->seq_ctrl[0]++; + + /* avoid watchdog triggers */ + ieee->softmac_data_hard_start_xmit(skb, ieee->dev, + ieee->basic_rate); + } + + spin_unlock_irqrestore(&ieee->lock, flags); + } else { + spin_unlock_irqrestore(&ieee->lock, flags); + spin_lock_irqsave(&ieee->mgmt_tx_lock, flags); + + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); + + if (ieee->seq_ctrl[0] == 0xFFF) + ieee->seq_ctrl[0] = 0; + else + ieee->seq_ctrl[0]++; + + /* check wether the managed packet queued greater than 5 */ + if (!ieee->check_nic_enough_desc(ieee->dev, tcb_desc->queue_index) || + (skb_queue_len(&ieee->skb_waitQ[tcb_desc->queue_index]) != 0) || + (ieee->queue_stop)) { + /* insert the skb packet to the management queue */ + /* as for the completion function, it does not need + * to check it any more. + * */ + printk(KERN_INFO "%s():insert to waitqueue, queue_index" + ":%d!\n", __func__, tcb_desc->queue_index); + skb_queue_tail(&ieee->skb_waitQ[tcb_desc->queue_index], + skb); + } else { + ieee->softmac_hard_start_xmit(skb, ieee->dev); + } + spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags); + } +} + +inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, + struct rtllib_device *ieee) +{ + short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE; + struct rtllib_hdr_3addr *header = + (struct rtllib_hdr_3addr *) skb->data; + u16 fc, type, stype; + struct cb_desc *tcb_desc = (struct cb_desc *)(skb->cb + 8); + + fc = header->frame_ctl; + type = WLAN_FC_GET_TYPE(fc); + stype = WLAN_FC_GET_STYPE(fc); + + + if (stype != RTLLIB_STYPE_PSPOLL) + tcb_desc->queue_index = MGNT_QUEUE; + else + tcb_desc->queue_index = HIGH_QUEUE; + + if (ieee->disable_mgnt_queue) + tcb_desc->queue_index = HIGH_QUEUE; + + + tcb_desc->data_rate = MgntQuery_MgntFrameTxRate(ieee); + tcb_desc->RATRIndex = 7; + tcb_desc->bTxDisableRateFallBack = 1; + tcb_desc->bTxUseDriverAssingedRate = 1; + if (single) { + if (type != RTLLIB_FTYPE_CTL) { + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); + + if (ieee->seq_ctrl[0] == 0xFFF) + ieee->seq_ctrl[0] = 0; + else + ieee->seq_ctrl[0]++; + + } + /* avoid watchdog triggers */ + ieee->softmac_data_hard_start_xmit(skb, ieee->dev, + ieee->basic_rate); + + } else { + if (type != RTLLIB_FTYPE_CTL) { + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); + + if (ieee->seq_ctrl[0] == 0xFFF) + ieee->seq_ctrl[0] = 0; + else + ieee->seq_ctrl[0]++; + } + ieee->softmac_hard_start_xmit(skb, ieee->dev); + + } +} + +inline struct sk_buff *rtllib_probe_req(struct rtllib_device *ieee) +{ + unsigned int len, rate_len; + u8 *tag; + struct sk_buff *skb; + struct rtllib_probe_request *req; + + len = ieee->current_network.ssid_len; + + rate_len = rtllib_MFIE_rate_len(ieee); + + skb = dev_alloc_skb(sizeof(struct rtllib_probe_request) + + 2 + len + rate_len + ieee->tx_headroom); + + if (!skb) + return NULL; + + skb_reserve(skb, ieee->tx_headroom); + + req = (struct rtllib_probe_request *) skb_put(skb, + sizeof(struct rtllib_probe_request)); + req->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_PROBE_REQ); + req->header.duration_id = 0; + + memset(req->header.addr1, 0xff, ETH_ALEN); + memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN); + memset(req->header.addr3, 0xff, ETH_ALEN); + + tag = (u8 *) skb_put(skb, len + 2 + rate_len); + + *tag++ = MFIE_TYPE_SSID; + *tag++ = len; + memcpy(tag, ieee->current_network.ssid, len); + tag += len; + + rtllib_MFIE_Brate(ieee, &tag); + rtllib_MFIE_Grate(ieee, &tag); + + return skb; +} + +struct sk_buff *rtllib_get_beacon_(struct rtllib_device *ieee); + +static void rtllib_send_beacon(struct rtllib_device *ieee) +{ + struct sk_buff *skb; + if (!ieee->ieee_up) + return; + skb = rtllib_get_beacon_(ieee); + + if (skb) { + softmac_mgmt_xmit(skb, ieee); + ieee->softmac_stats.tx_beacons++; + } + + if (ieee->beacon_txing && ieee->ieee_up) + mod_timer(&ieee->beacon_timer, jiffies + + (MSECS(ieee->current_network.beacon_interval - 5))); +} + + +static void rtllib_send_beacon_cb(unsigned long _ieee) +{ + struct rtllib_device *ieee = + (struct rtllib_device *) _ieee; + unsigned long flags; + + spin_lock_irqsave(&ieee->beacon_lock, flags); + rtllib_send_beacon(ieee); + spin_unlock_irqrestore(&ieee->beacon_lock, flags); +} + +/* + * Description: + * Enable network monitor mode, all rx packets will be received. + */ +void rtllib_EnableNetMonitorMode(struct net_device *dev, + bool bInitState) +{ + struct rtllib_device *ieee = netdev_priv_rsl(dev); + + printk(KERN_INFO "========>Enter Monitor Mode\n"); + + ieee->AllowAllDestAddrHandler(dev, true, !bInitState); +} + + +/* + * Description: + * Disable network network monitor mode, only packets destinated to + * us will be received. + */ +void rtllib_DisableNetMonitorMode(struct net_device *dev, + bool bInitState) +{ + struct rtllib_device *ieee = netdev_priv_rsl(dev); + + printk(KERN_INFO "========>Exit Monitor Mode\n"); + + ieee->AllowAllDestAddrHandler(dev, false, !bInitState); +} + + +/* + * Description: + * This enables the specialized promiscuous mode required by Intel. + * In this mode, Intel intends to hear traffics from/to other STAs in the + * same BSS. Therefore we don't have to disable checking BSSID and we only need + * to allow all dest. BUT: if we enable checking BSSID then we can't recv + * packets from other STA. + */ +void rtllib_EnableIntelPromiscuousMode(struct net_device *dev, + bool bInitState) +{ + bool bFilterOutNonAssociatedBSSID = false; + + struct rtllib_device *ieee = netdev_priv_rsl(dev); + + printk(KERN_INFO "========>Enter Intel Promiscuous Mode\n"); + + ieee->AllowAllDestAddrHandler(dev, true, !bInitState); + ieee->SetHwRegHandler(dev, HW_VAR_CECHK_BSSID, + (u8 *)&bFilterOutNonAssociatedBSSID); + + ieee->bNetPromiscuousMode = true; +} + + +/* + * Description: + * This disables the specialized promiscuous mode required by Intel. + * See MgntEnableIntelPromiscuousMode for detail. + */ +void rtllib_DisableIntelPromiscuousMode(struct net_device *dev, + bool bInitState) +{ + bool bFilterOutNonAssociatedBSSID = true; + + struct rtllib_device *ieee = netdev_priv_rsl(dev); + + printk(KERN_INFO "========>Exit Intel Promiscuous Mode\n"); + + ieee->AllowAllDestAddrHandler(dev, false, !bInitState); + ieee->SetHwRegHandler(dev, HW_VAR_CECHK_BSSID, + (u8 *)&bFilterOutNonAssociatedBSSID); + + ieee->bNetPromiscuousMode = false; +} + +static void rtllib_send_probe(struct rtllib_device *ieee, u8 is_mesh) +{ + struct sk_buff *skb; + skb = rtllib_probe_req(ieee); + if (skb) { + softmac_mgmt_xmit(skb, ieee); + ieee->softmac_stats.tx_probe_rq++; + } +} + + +void rtllib_send_probe_requests(struct rtllib_device *ieee, u8 is_mesh) +{ + if (ieee->active_scan && (ieee->softmac_features & + IEEE_SOFTMAC_PROBERQ)) { + rtllib_send_probe(ieee, 0); + rtllib_send_probe(ieee, 0); + } +} + +static void rtllib_softmac_hint11d_wq(void *data) +{ +} + +void rtllib_update_active_chan_map(struct rtllib_device *ieee) +{ + memcpy(ieee->active_channel_map, GET_DOT11D_INFO(ieee)->channel_map, + MAX_CHANNEL_NUMBER+1); +} + +/* this performs syncro scan blocking the caller until all channels + * in the allowed channel map has been checked. + */ +void rtllib_softmac_scan_syncro(struct rtllib_device *ieee, u8 is_mesh) +{ + union iwreq_data wrqu; + short ch = 0; + + rtllib_update_active_chan_map(ieee); + + ieee->be_scan_inprogress = true; + + down(&ieee->scan_sem); + + while (1) { + do { + ch++; + if (ch > MAX_CHANNEL_NUMBER) + goto out; /* scan completed */ + } while (!ieee->active_channel_map[ch]); + + /* this fuction can be called in two situations + * 1- We have switched to ad-hoc mode and we are + * performing a complete syncro scan before conclude + * there are no interesting cell and to create a + * new one. In this case the link state is + * RTLLIB_NOLINK until we found an interesting cell. + * If so the ieee8021_new_net, called by the RX path + * will set the state to RTLLIB_LINKED, so we stop + * scanning + * 2- We are linked and the root uses run iwlist scan. + * So we switch to RTLLIB_LINKED_SCANNING to remember + * that we are still logically linked (not interested in + * new network events, despite for updating the net list, + * but we are temporarly 'unlinked' as the driver shall + * not filter RX frames and the channel is changing. + * So the only situation in witch are interested is to check + * if the state become LINKED because of the #1 situation + */ + + if (ieee->state == RTLLIB_LINKED) + goto out; + if (ieee->sync_scan_hurryup) { + printk(KERN_INFO "============>sync_scan_hurryup out\n"); + goto out; + } + + ieee->set_chan(ieee->dev, ch); + if (ieee->active_channel_map[ch] == 1) + rtllib_send_probe_requests(ieee, 0); + + /* this prevent excessive time wait when we + * need to wait for a syncro scan to end.. + */ + msleep_interruptible_rsl(RTLLIB_SOFTMAC_SCAN_TIME); + } +out: + ieee->actscanning = false; + ieee->sync_scan_hurryup = 0; + + if (ieee->state >= RTLLIB_LINKED) { + if (IS_DOT11D_ENABLE(ieee)) + DOT11D_ScanComplete(ieee); + } + up(&ieee->scan_sem); + + ieee->be_scan_inprogress = false; + + memset(&wrqu, 0, sizeof(wrqu)); + wireless_send_event(ieee->dev, SIOCGIWSCAN, &wrqu, NULL); +} + +static void rtllib_softmac_scan_wq(void *data) +{ + struct rtllib_device *ieee = container_of_dwork_rsl(data, + struct rtllib_device, softmac_scan_wq); + u8 last_channel = ieee->current_network.channel; + + rtllib_update_active_chan_map(ieee); + + if (!ieee->ieee_up) + return; + if (rtllib_act_scanning(ieee, true) == true) + return; + + down(&ieee->scan_sem); + + if (ieee->eRFPowerState == eRfOff) { + printk(KERN_INFO "======>%s():rf state is eRfOff, return\n", + __func__); + goto out1; + } + + do { + ieee->current_network.channel = + (ieee->current_network.channel + 1) % + MAX_CHANNEL_NUMBER; + if (ieee->scan_watch_dog++ > MAX_CHANNEL_NUMBER) { + if (!ieee->active_channel_map[ieee->current_network.channel]) + ieee->current_network.channel = 6; + goto out; /* no good chans */ + } + } while (!ieee->active_channel_map[ieee->current_network.channel]); + + if (ieee->scanning_continue == 0) + goto out; + + ieee->set_chan(ieee->dev, ieee->current_network.channel); + + if (ieee->active_channel_map[ieee->current_network.channel] == 1) + rtllib_send_probe_requests(ieee, 0); + + queue_delayed_work_rsl(ieee->wq, &ieee->softmac_scan_wq, + MSECS(RTLLIB_SOFTMAC_SCAN_TIME)); + + up(&ieee->scan_sem); + return; + +out: + if (IS_DOT11D_ENABLE(ieee)) + DOT11D_ScanComplete(ieee); + ieee->current_network.channel = last_channel; + +out1: + ieee->actscanning = false; + ieee->scan_watch_dog = 0; + ieee->scanning_continue = 0; + up(&ieee->scan_sem); +} + + + +static void rtllib_beacons_start(struct rtllib_device *ieee) +{ + unsigned long flags; + spin_lock_irqsave(&ieee->beacon_lock, flags); + + ieee->beacon_txing = 1; + rtllib_send_beacon(ieee); + + spin_unlock_irqrestore(&ieee->beacon_lock, flags); +} + +static void rtllib_beacons_stop(struct rtllib_device *ieee) +{ + unsigned long flags; + + spin_lock_irqsave(&ieee->beacon_lock, flags); + + ieee->beacon_txing = 0; + del_timer_sync(&ieee->beacon_timer); + + spin_unlock_irqrestore(&ieee->beacon_lock, flags); + +} + + +void rtllib_stop_send_beacons(struct rtllib_device *ieee) +{ + if (ieee->stop_send_beacons) + ieee->stop_send_beacons(ieee->dev); + if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS) + rtllib_beacons_stop(ieee); +} + + +void rtllib_start_send_beacons(struct rtllib_device *ieee) +{ + if (ieee->start_send_beacons) + ieee->start_send_beacons(ieee->dev); + if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS) + rtllib_beacons_start(ieee); +} + + +static void rtllib_softmac_stop_scan(struct rtllib_device *ieee) +{ + down(&ieee->scan_sem); + ieee->scan_watch_dog = 0; + if (ieee->scanning_continue == 1) { + ieee->scanning_continue = 0; + ieee->actscanning = 0; + + cancel_delayed_work(&ieee->softmac_scan_wq); + } + + up(&ieee->scan_sem); +} + +void rtllib_stop_scan(struct rtllib_device *ieee) +{ + if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) { + rtllib_softmac_stop_scan(ieee); + } else { + if (ieee->rtllib_stop_hw_scan) + ieee->rtllib_stop_hw_scan(ieee->dev); + } +} + +void rtllib_stop_scan_syncro(struct rtllib_device *ieee) +{ + if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) { + ieee->sync_scan_hurryup = 1; + } else { + if (ieee->rtllib_stop_hw_scan) + ieee->rtllib_stop_hw_scan(ieee->dev); + } +} + +bool rtllib_act_scanning(struct rtllib_device *ieee, bool sync_scan) +{ + if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) { + if (sync_scan) + return ieee->be_scan_inprogress; + else + return ieee->actscanning || ieee->be_scan_inprogress; + } else { + return test_bit(STATUS_SCANNING, &ieee->status); + } +} + +/* called with ieee->lock held */ +static void rtllib_start_scan(struct rtllib_device *ieee) +{ + RT_TRACE(COMP_DBG, "===>%s()\n", __func__); + if (ieee->rtllib_ips_leave_wq != NULL) + ieee->rtllib_ips_leave_wq(ieee->dev); + + if (IS_DOT11D_ENABLE(ieee)) { + if (IS_COUNTRY_IE_VALID(ieee)) + RESET_CIE_WATCHDOG(ieee); + } + if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) { + if (ieee->scanning_continue == 0) { + ieee->actscanning = true; + ieee->scanning_continue = 1; + queue_delayed_work_rsl(ieee->wq, + &ieee->softmac_scan_wq, 0); + } + } else { + if (ieee->rtllib_start_hw_scan) + ieee->rtllib_start_hw_scan(ieee->dev); + } +} + +/* called with wx_sem held */ +void rtllib_start_scan_syncro(struct rtllib_device *ieee, u8 is_mesh) +{ + if (IS_DOT11D_ENABLE(ieee)) { + if (IS_COUNTRY_IE_VALID(ieee)) + RESET_CIE_WATCHDOG(ieee); + } + ieee->sync_scan_hurryup = 0; + if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) { + rtllib_softmac_scan_syncro(ieee, is_mesh); + } else { + if (ieee->rtllib_start_hw_scan) + ieee->rtllib_start_hw_scan(ieee->dev); + } +} + +inline struct sk_buff *rtllib_authentication_req(struct rtllib_network *beacon, + struct rtllib_device *ieee, int challengelen, u8 *daddr) +{ + struct sk_buff *skb; + struct rtllib_authentication *auth; + int len = 0; + len = sizeof(struct rtllib_authentication) + challengelen + + ieee->tx_headroom + 4; + skb = dev_alloc_skb(len); + + if (!skb) + return NULL; + + skb_reserve(skb, ieee->tx_headroom); + + auth = (struct rtllib_authentication *) + skb_put(skb, sizeof(struct rtllib_authentication)); + + auth->header.frame_ctl = RTLLIB_STYPE_AUTH; + if (challengelen) + auth->header.frame_ctl |= RTLLIB_FCTL_WEP; + + auth->header.duration_id = 0x013a; + memcpy(auth->header.addr1, beacon->bssid, ETH_ALEN); + memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN); + memcpy(auth->header.addr3, beacon->bssid, ETH_ALEN); + if (ieee->auth_mode == 0) + auth->algorithm = WLAN_AUTH_OPEN; + else if (ieee->auth_mode == 1) + auth->algorithm = WLAN_AUTH_SHARED_KEY; + else if (ieee->auth_mode == 2) + auth->algorithm = WLAN_AUTH_OPEN; + auth->transaction = cpu_to_le16(ieee->associate_seq); + ieee->associate_seq++; + + auth->status = cpu_to_le16(WLAN_STATUS_SUCCESS); + + return skb; +} + +static struct sk_buff *rtllib_probe_resp(struct rtllib_device *ieee, u8 *dest) +{ + u8 *tag; + int beacon_size; + struct rtllib_probe_response *beacon_buf; + struct sk_buff *skb = NULL; + int encrypt; + int atim_len, erp_len; + struct rtllib_crypt_data *crypt; + + char *ssid = ieee->current_network.ssid; + int ssid_len = ieee->current_network.ssid_len; + int rate_len = ieee->current_network.rates_len+2; + int rate_ex_len = ieee->current_network.rates_ex_len; + int wpa_ie_len = ieee->wpa_ie_len; + u8 erpinfo_content = 0; + + u8 *tmp_ht_cap_buf = NULL; + u8 tmp_ht_cap_len = 0; + u8 *tmp_ht_info_buf = NULL; + u8 tmp_ht_info_len = 0; + struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; + u8 *tmp_generic_ie_buf = NULL; + u8 tmp_generic_ie_len = 0; + + if (rate_ex_len > 0) + rate_ex_len += 2; + + if (ieee->current_network.capability & WLAN_CAPABILITY_IBSS) + atim_len = 4; + else + atim_len = 0; + + if ((ieee->current_network.mode == IEEE_G) || + (ieee->current_network.mode == IEEE_N_24G && + ieee->pHTInfo->bCurSuppCCK)) { + erp_len = 3; + erpinfo_content = 0; + if (ieee->current_network.buseprotection) + erpinfo_content |= ERP_UseProtection; + } else + erp_len = 0; + + crypt = ieee->crypt[ieee->tx_keyidx]; + encrypt = ieee->host_encrypt && crypt && crypt->ops && + ((0 == strcmp(crypt->ops->name, "WEP") || wpa_ie_len)); + if (ieee->pHTInfo->bCurrentHTSupport) { + tmp_ht_cap_buf = (u8 *) &(ieee->pHTInfo->SelfHTCap); + tmp_ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap); + tmp_ht_info_buf = (u8 *) &(ieee->pHTInfo->SelfHTInfo); + tmp_ht_info_len = sizeof(ieee->pHTInfo->SelfHTInfo); + HTConstructCapabilityElement(ieee, tmp_ht_cap_buf, + &tmp_ht_cap_len, encrypt, false); + HTConstructInfoElement(ieee, tmp_ht_info_buf, &tmp_ht_info_len, + encrypt); + + if (pHTInfo->bRegRT2RTAggregation) { + tmp_generic_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer; + tmp_generic_ie_len = + sizeof(ieee->pHTInfo->szRT2RTAggBuffer); + HTConstructRT2RTAggElement(ieee, tmp_generic_ie_buf, + &tmp_generic_ie_len); + } + } + + beacon_size = sizeof(struct rtllib_probe_response)+2+ + ssid_len + 3 + rate_len + rate_ex_len + atim_len + erp_len + + wpa_ie_len + ieee->tx_headroom; + skb = dev_alloc_skb(beacon_size); + if (!skb) + return NULL; + + skb_reserve(skb, ieee->tx_headroom); + + beacon_buf = (struct rtllib_probe_response *) skb_put(skb, + (beacon_size - ieee->tx_headroom)); + memcpy(beacon_buf->header.addr1, dest, ETH_ALEN); + memcpy(beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN); + memcpy(beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN); + + beacon_buf->header.duration_id = 0; + beacon_buf->beacon_interval = + cpu_to_le16(ieee->current_network.beacon_interval); + beacon_buf->capability = + cpu_to_le16(ieee->current_network.capability & + WLAN_CAPABILITY_IBSS); + beacon_buf->capability |= + cpu_to_le16(ieee->current_network.capability & + WLAN_CAPABILITY_SHORT_PREAMBLE); + + if (ieee->short_slot && (ieee->current_network.capability & + WLAN_CAPABILITY_SHORT_SLOT_TIME)) + cpu_to_le16((beacon_buf->capability |= + WLAN_CAPABILITY_SHORT_SLOT_TIME)); + + crypt = ieee->crypt[ieee->tx_keyidx]; + if (encrypt) + beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY); + + + beacon_buf->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_PROBE_RESP); + beacon_buf->info_element[0].id = MFIE_TYPE_SSID; + beacon_buf->info_element[0].len = ssid_len; + + tag = (u8 *) beacon_buf->info_element[0].data; + + memcpy(tag, ssid, ssid_len); + + tag += ssid_len; + + *(tag++) = MFIE_TYPE_RATES; + *(tag++) = rate_len-2; + memcpy(tag, ieee->current_network.rates, rate_len-2); + tag += rate_len-2; + + *(tag++) = MFIE_TYPE_DS_SET; + *(tag++) = 1; + *(tag++) = ieee->current_network.channel; + + if (atim_len) { + u16 val16; + *(tag++) = MFIE_TYPE_IBSS_SET; + *(tag++) = 2; + val16 = cpu_to_le16(ieee->current_network.atim_window); + memcpy((u8 *)tag, (u8 *)&val16, 2); + tag += 2; + } + + if (erp_len) { + *(tag++) = MFIE_TYPE_ERP; + *(tag++) = 1; + *(tag++) = erpinfo_content; + } + if (rate_ex_len) { + *(tag++) = MFIE_TYPE_RATES_EX; + *(tag++) = rate_ex_len-2; + memcpy(tag, ieee->current_network.rates_ex, rate_ex_len-2); + tag += rate_ex_len-2; + } + + if (wpa_ie_len) { + if (ieee->iw_mode == IW_MODE_ADHOC) + memcpy(&ieee->wpa_ie[14], &ieee->wpa_ie[8], 4); + memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len); + tag += ieee->wpa_ie_len; + } + return skb; +} + +static struct sk_buff *rtllib_assoc_resp(struct rtllib_device *ieee, u8 *dest) +{ + struct sk_buff *skb; + u8 *tag; + + struct rtllib_crypt_data *crypt; + struct rtllib_assoc_response_frame *assoc; + short encrypt; + + unsigned int rate_len = rtllib_MFIE_rate_len(ieee); + int len = sizeof(struct rtllib_assoc_response_frame) + rate_len + + ieee->tx_headroom; + + skb = dev_alloc_skb(len); + + if (!skb) + return NULL; + + skb_reserve(skb, ieee->tx_headroom); + + assoc = (struct rtllib_assoc_response_frame *) + skb_put(skb, sizeof(struct rtllib_assoc_response_frame)); + + assoc->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_ASSOC_RESP); + memcpy(assoc->header.addr1, dest, ETH_ALEN); + memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN); + memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN); + assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ? + WLAN_CAPABILITY_ESS : WLAN_CAPABILITY_IBSS); + + + if (ieee->short_slot) + assoc->capability |= + cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME); + + if (ieee->host_encrypt) + crypt = ieee->crypt[ieee->tx_keyidx]; + else + crypt = NULL; + + encrypt = (crypt && crypt->ops); + + if (encrypt) + assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY); + + assoc->status = 0; + assoc->aid = cpu_to_le16(ieee->assoc_id); + if (ieee->assoc_id == 0x2007) + ieee->assoc_id = 0; + else + ieee->assoc_id++; + + tag = (u8 *) skb_put(skb, rate_len); + rtllib_MFIE_Brate(ieee, &tag); + rtllib_MFIE_Grate(ieee, &tag); + + return skb; +} + +static struct sk_buff *rtllib_auth_resp(struct rtllib_device *ieee, int status, + u8 *dest) +{ + struct sk_buff *skb = NULL; + struct rtllib_authentication *auth; + int len = ieee->tx_headroom + sizeof(struct rtllib_authentication) + 1; + skb = dev_alloc_skb(len); + if (!skb) + return NULL; + + skb->len = sizeof(struct rtllib_authentication); + + skb_reserve(skb, ieee->tx_headroom); + + auth = (struct rtllib_authentication *) + skb_put(skb, sizeof(struct rtllib_authentication)); + + auth->status = cpu_to_le16(status); + auth->transaction = cpu_to_le16(2); + auth->algorithm = cpu_to_le16(WLAN_AUTH_OPEN); + + memcpy(auth->header.addr3, ieee->dev->dev_addr, ETH_ALEN); + memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN); + memcpy(auth->header.addr1, dest, ETH_ALEN); + auth->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_AUTH); + return skb; + + +} + +static struct sk_buff *rtllib_null_func(struct rtllib_device *ieee, short pwr) +{ + struct sk_buff *skb; + struct rtllib_hdr_3addr *hdr; + + skb = dev_alloc_skb(sizeof(struct rtllib_hdr_3addr)+ieee->tx_headroom); + if (!skb) + return NULL; + + skb_reserve(skb, ieee->tx_headroom); + + hdr = (struct rtllib_hdr_3addr *)skb_put(skb, + sizeof(struct rtllib_hdr_3addr)); + + memcpy(hdr->addr1, ieee->current_network.bssid, ETH_ALEN); + memcpy(hdr->addr2, ieee->dev->dev_addr, ETH_ALEN); + memcpy(hdr->addr3, ieee->current_network.bssid, ETH_ALEN); + + hdr->frame_ctl = cpu_to_le16(RTLLIB_FTYPE_DATA | + RTLLIB_STYPE_NULLFUNC | RTLLIB_FCTL_TODS | + (pwr ? RTLLIB_FCTL_PM : 0)); + + return skb; + + +} + +static struct sk_buff *rtllib_pspoll_func(struct rtllib_device *ieee) +{ + struct sk_buff *skb; + struct rtllib_pspoll_hdr *hdr; + + skb = dev_alloc_skb(sizeof(struct rtllib_pspoll_hdr)+ieee->tx_headroom); + if (!skb) + return NULL; + + skb_reserve(skb, ieee->tx_headroom); + + hdr = (struct rtllib_pspoll_hdr *)skb_put(skb, + sizeof(struct rtllib_pspoll_hdr)); + + memcpy(hdr->bssid, ieee->current_network.bssid, ETH_ALEN); + memcpy(hdr->ta, ieee->dev->dev_addr, ETH_ALEN); + + hdr->aid = cpu_to_le16(ieee->assoc_id | 0xc000); + hdr->frame_ctl = cpu_to_le16(RTLLIB_FTYPE_CTL | RTLLIB_STYPE_PSPOLL | + RTLLIB_FCTL_PM); + + return skb; + +} + +static void rtllib_resp_to_assoc_rq(struct rtllib_device *ieee, u8 *dest) +{ + struct sk_buff *buf = rtllib_assoc_resp(ieee, dest); + + if (buf) + softmac_mgmt_xmit(buf, ieee); +} + + +static void rtllib_resp_to_auth(struct rtllib_device *ieee, int s, u8 *dest) +{ + struct sk_buff *buf = rtllib_auth_resp(ieee, s, dest); + + if (buf) + softmac_mgmt_xmit(buf, ieee); +} + + +static void rtllib_resp_to_probe(struct rtllib_device *ieee, u8 *dest) +{ + + struct sk_buff *buf = rtllib_probe_resp(ieee, dest); + if (buf) + softmac_mgmt_xmit(buf, ieee); +} + + +inline int SecIsInPMKIDList(struct rtllib_device *ieee, u8 *bssid) +{ + int i = 0; + + do { + if ((ieee->PMKIDList[i].bUsed) && + (memcmp(ieee->PMKIDList[i].Bssid, bssid, ETH_ALEN) == 0)) + break; + else + i++; + } while (i < NUM_PMKID_CACHE); + + if (i == NUM_PMKID_CACHE) + i = -1; + return i; +} + +inline struct sk_buff *rtllib_association_req(struct rtllib_network *beacon, + struct rtllib_device *ieee) +{ + struct sk_buff *skb; + struct rtllib_assoc_request_frame *hdr; + u8 *tag, *ies; + int i; + u8 *ht_cap_buf = NULL; + u8 ht_cap_len = 0; + u8 *realtek_ie_buf = NULL; + u8 realtek_ie_len = 0; + int wpa_ie_len = ieee->wpa_ie_len; + int wps_ie_len = ieee->wps_ie_len; + unsigned int ckip_ie_len = 0; + unsigned int ccxrm_ie_len = 0; + unsigned int cxvernum_ie_len = 0; + struct rtllib_crypt_data *crypt; + int encrypt; + int PMKCacheIdx; + + unsigned int rate_len = (beacon->rates_len ? + (beacon->rates_len + 2) : 0) + + (beacon->rates_ex_len ? (beacon->rates_ex_len) + + 2 : 0); + + unsigned int wmm_info_len = beacon->qos_data.supported ? 9 : 0; + unsigned int turbo_info_len = beacon->Turbo_Enable ? 9 : 0; + + int len = 0; + crypt = ieee->crypt[ieee->tx_keyidx]; + if (crypt != NULL) + encrypt = ieee->host_encrypt && crypt && crypt->ops && + ((0 == strcmp(crypt->ops->name, "WEP") || + wpa_ie_len)); + else + encrypt = 0; + + if ((ieee->rtllib_ap_sec_type && + (ieee->rtllib_ap_sec_type(ieee) & SEC_ALG_TKIP)) || + (ieee->bForcedBgMode == true)) { + ieee->pHTInfo->bEnableHT = 0; + ieee->mode = WIRELESS_MODE_G; + } + + if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT) { + ht_cap_buf = (u8 *)&(ieee->pHTInfo->SelfHTCap); + ht_cap_len = sizeof(ieee->pHTInfo->SelfHTCap); + HTConstructCapabilityElement(ieee, ht_cap_buf, &ht_cap_len, + encrypt, true); + if (ieee->pHTInfo->bCurrentRT2RTAggregation) { + realtek_ie_buf = ieee->pHTInfo->szRT2RTAggBuffer; + realtek_ie_len = + sizeof(ieee->pHTInfo->szRT2RTAggBuffer); + HTConstructRT2RTAggElement(ieee, realtek_ie_buf, + &realtek_ie_len); + } + } + + if (beacon->bCkipSupported) + ckip_ie_len = 30+2; + if (beacon->bCcxRmEnable) + ccxrm_ie_len = 6+2; + if (beacon->BssCcxVerNumber >= 2) + cxvernum_ie_len = 5+2; + + PMKCacheIdx = SecIsInPMKIDList(ieee, ieee->current_network.bssid); + if (PMKCacheIdx >= 0) { + wpa_ie_len += 18; + printk(KERN_INFO "[PMK cache]: WPA2 IE length: %x\n", + wpa_ie_len); + } + len = sizeof(struct rtllib_assoc_request_frame) + 2 + + beacon->ssid_len + + rate_len + + wpa_ie_len + + wps_ie_len + + wmm_info_len + + turbo_info_len + + ht_cap_len + + realtek_ie_len + + ckip_ie_len + + ccxrm_ie_len + + cxvernum_ie_len + + ieee->tx_headroom; + + skb = dev_alloc_skb(len); + + if (!skb) + return NULL; + + skb_reserve(skb, ieee->tx_headroom); + + hdr = (struct rtllib_assoc_request_frame *) + skb_put(skb, sizeof(struct rtllib_assoc_request_frame) + 2); + + + hdr->header.frame_ctl = RTLLIB_STYPE_ASSOC_REQ; + hdr->header.duration_id = 37; + memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN); + memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN); + memcpy(hdr->header.addr3, beacon->bssid, ETH_ALEN); + + memcpy(ieee->ap_mac_addr, beacon->bssid, ETH_ALEN); + + hdr->capability = cpu_to_le16(WLAN_CAPABILITY_ESS); + if (beacon->capability & WLAN_CAPABILITY_PRIVACY) + hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY); + + if (beacon->capability & WLAN_CAPABILITY_SHORT_PREAMBLE) + hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE); + + if (ieee->short_slot && + (beacon->capability&WLAN_CAPABILITY_SHORT_SLOT_TIME)) + hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME); + + + hdr->listen_interval = beacon->listen_interval; + + hdr->info_element[0].id = MFIE_TYPE_SSID; + + hdr->info_element[0].len = beacon->ssid_len; + tag = skb_put(skb, beacon->ssid_len); + memcpy(tag, beacon->ssid, beacon->ssid_len); + + tag = skb_put(skb, rate_len); + + if (beacon->rates_len) { + *tag++ = MFIE_TYPE_RATES; + *tag++ = beacon->rates_len; + for (i = 0; i < beacon->rates_len; i++) + *tag++ = beacon->rates[i]; + } + + if (beacon->rates_ex_len) { + *tag++ = MFIE_TYPE_RATES_EX; + *tag++ = beacon->rates_ex_len; + for (i = 0; i < beacon->rates_ex_len; i++) + *tag++ = beacon->rates_ex[i]; + } + + if (beacon->bCkipSupported) { + static u8 AironetIeOui[] = {0x00, 0x01, 0x66}; + u8 CcxAironetBuf[30]; + struct octet_string osCcxAironetIE; + + memset(CcxAironetBuf, 0, 30); + osCcxAironetIE.Octet = CcxAironetBuf; + osCcxAironetIE.Length = sizeof(CcxAironetBuf); + memcpy(osCcxAironetIE.Octet, AironetIeOui, + sizeof(AironetIeOui)); + + osCcxAironetIE.Octet[IE_CISCO_FLAG_POSITION] |= + (SUPPORT_CKIP_PK|SUPPORT_CKIP_MIC); + tag = skb_put(skb, ckip_ie_len); + *tag++ = MFIE_TYPE_AIRONET; + *tag++ = osCcxAironetIE.Length; + memcpy(tag, osCcxAironetIE.Octet, osCcxAironetIE.Length); + tag += osCcxAironetIE.Length; + } + + if (beacon->bCcxRmEnable) { + static u8 CcxRmCapBuf[] = {0x00, 0x40, 0x96, 0x01, 0x01, 0x00}; + struct octet_string osCcxRmCap; + + osCcxRmCap.Octet = CcxRmCapBuf; + osCcxRmCap.Length = sizeof(CcxRmCapBuf); + tag = skb_put(skb, ccxrm_ie_len); + *tag++ = MFIE_TYPE_GENERIC; + *tag++ = osCcxRmCap.Length; + memcpy(tag, osCcxRmCap.Octet, osCcxRmCap.Length); + tag += osCcxRmCap.Length; + } + + if (beacon->BssCcxVerNumber >= 2) { + u8 CcxVerNumBuf[] = {0x00, 0x40, 0x96, 0x03, 0x00}; + struct octet_string osCcxVerNum; + CcxVerNumBuf[4] = beacon->BssCcxVerNumber; + osCcxVerNum.Octet = CcxVerNumBuf; + osCcxVerNum.Length = sizeof(CcxVerNumBuf); + tag = skb_put(skb, cxvernum_ie_len); + *tag++ = MFIE_TYPE_GENERIC; + *tag++ = osCcxVerNum.Length; + memcpy(tag, osCcxVerNum.Octet, osCcxVerNum.Length); + tag += osCcxVerNum.Length; + } + if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT) { + if (ieee->pHTInfo->ePeerHTSpecVer != HT_SPEC_VER_EWC) { + tag = skb_put(skb, ht_cap_len); + *tag++ = MFIE_TYPE_HT_CAP; + *tag++ = ht_cap_len - 2; + memcpy(tag, ht_cap_buf, ht_cap_len - 2); + tag += ht_cap_len - 2; + } + } + + if (wpa_ie_len) { + tag = skb_put(skb, ieee->wpa_ie_len); + memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len); + + if (PMKCacheIdx >= 0) { + tag = skb_put(skb, 18); + *tag = 1; + *(tag + 1) = 0; + memcpy((tag + 2), &ieee->PMKIDList[PMKCacheIdx].PMKID, + 16); + } + } + if (wmm_info_len) { + tag = skb_put(skb, wmm_info_len); + rtllib_WMM_Info(ieee, &tag); + } + + if (wps_ie_len && ieee->wps_ie) { + tag = skb_put(skb, wps_ie_len); + memcpy(tag, ieee->wps_ie, wps_ie_len); + } + + tag = skb_put(skb, turbo_info_len); + if (turbo_info_len) + rtllib_TURBO_Info(ieee, &tag); + + if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT) { + if (ieee->pHTInfo->ePeerHTSpecVer == HT_SPEC_VER_EWC) { + tag = skb_put(skb, ht_cap_len); + *tag++ = MFIE_TYPE_GENERIC; + *tag++ = ht_cap_len - 2; + memcpy(tag, ht_cap_buf, ht_cap_len - 2); + tag += ht_cap_len - 2; + } + + if (ieee->pHTInfo->bCurrentRT2RTAggregation) { + tag = skb_put(skb, realtek_ie_len); + *tag++ = MFIE_TYPE_GENERIC; + *tag++ = realtek_ie_len - 2; + memcpy(tag, realtek_ie_buf, realtek_ie_len - 2); + } + } + + kfree(ieee->assocreq_ies); + ieee->assocreq_ies = NULL; + ies = &(hdr->info_element[0].id); + ieee->assocreq_ies_len = (skb->data + skb->len) - ies; + ieee->assocreq_ies = kmalloc(ieee->assocreq_ies_len, GFP_ATOMIC); + if (ieee->assocreq_ies) + memcpy(ieee->assocreq_ies, ies, ieee->assocreq_ies_len); + else { + printk(KERN_INFO "%s()Warning: can't alloc memory for assocreq" + "_ies\n", __func__); + ieee->assocreq_ies_len = 0; + } + return skb; +} + +void rtllib_associate_abort(struct rtllib_device *ieee) +{ + + unsigned long flags; + spin_lock_irqsave(&ieee->lock, flags); + + ieee->associate_seq++; + + /* don't scan, and avoid to have the RX path possibily + * try again to associate. Even do not react to AUTH or + * ASSOC response. Just wait for the retry wq to be scheduled. + * Here we will check if there are good nets to associate + * with, so we retry or just get back to NO_LINK and scanning + */ + if (ieee->state == RTLLIB_ASSOCIATING_AUTHENTICATING) { + RTLLIB_DEBUG_MGMT("Authentication failed\n"); + ieee->softmac_stats.no_auth_rs++; + } else { + RTLLIB_DEBUG_MGMT("Association failed\n"); + ieee->softmac_stats.no_ass_rs++; + } + + ieee->state = RTLLIB_ASSOCIATING_RETRY; + + queue_delayed_work_rsl(ieee->wq, &ieee->associate_retry_wq, + RTLLIB_SOFTMAC_ASSOC_RETRY_TIME); + + spin_unlock_irqrestore(&ieee->lock, flags); +} + +static void rtllib_associate_abort_cb(unsigned long dev) +{ + rtllib_associate_abort((struct rtllib_device *) dev); +} + +static void rtllib_associate_step1(struct rtllib_device *ieee, u8 * daddr) +{ + struct rtllib_network *beacon = &ieee->current_network; + struct sk_buff *skb; + + RTLLIB_DEBUG_MGMT("Stopping scan\n"); + + ieee->softmac_stats.tx_auth_rq++; + + skb = rtllib_authentication_req(beacon, ieee, 0, daddr); + + if (!skb) + rtllib_associate_abort(ieee); + else { + ieee->state = RTLLIB_ASSOCIATING_AUTHENTICATING ; + RTLLIB_DEBUG_MGMT("Sending authentication request\n"); + softmac_mgmt_xmit(skb, ieee); + if (!timer_pending(&ieee->associate_timer)) { + ieee->associate_timer.expires = jiffies + (HZ / 2); + add_timer(&ieee->associate_timer); + } + } +} + +static void rtllib_auth_challenge(struct rtllib_device *ieee, u8 *challenge, int chlen) +{ + u8 *c; + struct sk_buff *skb; + struct rtllib_network *beacon = &ieee->current_network; + + ieee->associate_seq++; + ieee->softmac_stats.tx_auth_rq++; + + skb = rtllib_authentication_req(beacon, ieee, chlen + 2, beacon->bssid); + + if (!skb) + rtllib_associate_abort(ieee); + else { + c = skb_put(skb, chlen+2); + *(c++) = MFIE_TYPE_CHALLENGE; + *(c++) = chlen; + memcpy(c, challenge, chlen); + + RTLLIB_DEBUG_MGMT("Sending authentication challenge " + "response\n"); + + rtllib_encrypt_fragment(ieee, skb, + sizeof(struct rtllib_hdr_3addr)); + + softmac_mgmt_xmit(skb, ieee); + mod_timer(&ieee->associate_timer, jiffies + (HZ/2)); + } + kfree(challenge); +} + +static void rtllib_associate_step2(struct rtllib_device *ieee) +{ + struct sk_buff *skb; + struct rtllib_network *beacon = &ieee->current_network; + + del_timer_sync(&ieee->associate_timer); + + RTLLIB_DEBUG_MGMT("Sending association request\n"); + + ieee->softmac_stats.tx_ass_rq++; + skb = rtllib_association_req(beacon, ieee); + if (!skb) + rtllib_associate_abort(ieee); + else { + softmac_mgmt_xmit(skb, ieee); + mod_timer(&ieee->associate_timer, jiffies + (HZ/2)); + } +} + +#define CANCELLED 2 +static void rtllib_associate_complete_wq(void *data) +{ + struct rtllib_device *ieee = (struct rtllib_device *) + container_of_work_rsl(data, + struct rtllib_device, + associate_complete_wq); + struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) + (&(ieee->PowerSaveControl)); + printk(KERN_INFO "Associated successfully\n"); + if (ieee->is_silent_reset == 0) { + printk(KERN_INFO "normal associate\n"); + notify_wx_assoc_event(ieee); + } + + netif_carrier_on(ieee->dev); + ieee->is_roaming = false; + if (rtllib_is_54g(&ieee->current_network) && + (ieee->modulation & RTLLIB_OFDM_MODULATION)) { + ieee->rate = 108; + printk(KERN_INFO"Using G rates:%d\n", ieee->rate); + } else { + ieee->rate = 22; + ieee->SetWirelessMode(ieee->dev, IEEE_B); + printk(KERN_INFO"Using B rates:%d\n", ieee->rate); + } + if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT) { + printk(KERN_INFO "Successfully associated, ht enabled\n"); + HTOnAssocRsp(ieee); + } else { + printk(KERN_INFO "Successfully associated, ht not " + "enabled(%d, %d)\n", + ieee->pHTInfo->bCurrentHTSupport, + ieee->pHTInfo->bEnableHT); + memset(ieee->dot11HTOperationalRateSet, 0, 16); + } + ieee->LinkDetectInfo.SlotNum = 2 * (1 + + ieee->current_network.beacon_interval / + 500); + if (ieee->LinkDetectInfo.NumRecvBcnInPeriod == 0 || + ieee->LinkDetectInfo.NumRecvDataInPeriod == 0) { + ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1; + ieee->LinkDetectInfo.NumRecvDataInPeriod = 1; + } + pPSC->LpsIdleCount = 0; + ieee->link_change(ieee->dev); + + if (ieee->is_silent_reset == 1) { + printk(KERN_INFO "silent reset associate\n"); + ieee->is_silent_reset = 0; + } + + if (ieee->data_hard_resume) + ieee->data_hard_resume(ieee->dev); + +} + +static void rtllib_sta_send_associnfo(struct rtllib_device *ieee) +{ +} + +static void rtllib_associate_complete(struct rtllib_device *ieee) +{ + del_timer_sync(&ieee->associate_timer); + + ieee->state = RTLLIB_LINKED; + rtllib_sta_send_associnfo(ieee); + + queue_work_rsl(ieee->wq, &ieee->associate_complete_wq); +} + +static void rtllib_associate_procedure_wq(void *data) +{ + struct rtllib_device *ieee = container_of_dwork_rsl(data, + struct rtllib_device, + associate_procedure_wq); + rtllib_stop_scan_syncro(ieee); + if (ieee->rtllib_ips_leave != NULL) + ieee->rtllib_ips_leave(ieee->dev); + down(&ieee->wx_sem); + + if (ieee->data_hard_stop) + ieee->data_hard_stop(ieee->dev); + + rtllib_stop_scan(ieee); + RT_TRACE(COMP_DBG, "===>%s(), chan:%d\n", __func__, + ieee->current_network.channel); + HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); + if (ieee->eRFPowerState == eRfOff) { + RT_TRACE(COMP_DBG, "=============>%s():Rf state is eRfOff," + " schedule ipsleave wq again,return\n", __func__); + if (ieee->rtllib_ips_leave_wq != NULL) + ieee->rtllib_ips_leave_wq(ieee->dev); + up(&ieee->wx_sem); + return; + } + ieee->associate_seq = 1; + + rtllib_associate_step1(ieee, ieee->current_network.bssid); + + up(&ieee->wx_sem); +} + +inline void rtllib_softmac_new_net(struct rtllib_device *ieee, + struct rtllib_network *net) +{ + u8 tmp_ssid[IW_ESSID_MAX_SIZE + 1]; + int tmp_ssid_len = 0; + + short apset, ssidset, ssidbroad, apmatch, ssidmatch; + + /* we are interested in new new only if we are not associated + * and we are not associating / authenticating + */ + if (ieee->state != RTLLIB_NOLINK) + return; + + if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability & + WLAN_CAPABILITY_ESS)) + return; + + if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & + WLAN_CAPABILITY_IBSS)) + return; + + if ((ieee->iw_mode == IW_MODE_ADHOC) && + (net->channel > ieee->ibss_maxjoin_chal)) + return; + if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC) { + /* if the user specified the AP MAC, we need also the essid + * This could be obtained by beacons or, if the network does not + * broadcast it, it can be put manually. + */ + apset = ieee->wap_set; + ssidset = ieee->ssid_set; + ssidbroad = !(net->ssid_len == 0 || net->ssid[0] == '\0'); + apmatch = (memcmp(ieee->current_network.bssid, net->bssid, + ETH_ALEN) == 0); + if (!ssidbroad) { + ssidmatch = (ieee->current_network.ssid_len == + net->hidden_ssid_len) && + (!strncmp(ieee->current_network.ssid, + net->hidden_ssid, net->hidden_ssid_len)); + if (net->hidden_ssid_len > 0) { + strncpy(net->ssid, net->hidden_ssid, + net->hidden_ssid_len); + net->ssid_len = net->hidden_ssid_len; + ssidbroad = 1; + } + } else + ssidmatch = + (ieee->current_network.ssid_len == net->ssid_len) && + (!strncmp(ieee->current_network.ssid, net->ssid, + net->ssid_len)); + + /* if the user set the AP check if match. + * if the network does not broadcast essid we check the + * user supplyed ANY essid + * if the network does broadcast and the user does not set + * essid it is OK + * if the network does broadcast and the user did set essid + * check if essid match + * if the ap is not set, check that the user set the bssid + * and the network does bradcast and that those two bssid match + */ + if ((apset && apmatch && + ((ssidset && ssidbroad && ssidmatch) || + (ssidbroad && !ssidset) || (!ssidbroad && ssidset))) || + (!apset && ssidset && ssidbroad && ssidmatch) || + (ieee->is_roaming && ssidset && ssidbroad && ssidmatch)) { + /* if the essid is hidden replace it with the + * essid provided by the user. + */ + if (!ssidbroad) { + strncpy(tmp_ssid, ieee->current_network.ssid, + IW_ESSID_MAX_SIZE); + tmp_ssid_len = ieee->current_network.ssid_len; + } + memcpy(&ieee->current_network, net, + sizeof(struct rtllib_network)); + if (!ssidbroad) { + strncpy(ieee->current_network.ssid, tmp_ssid, + IW_ESSID_MAX_SIZE); + ieee->current_network.ssid_len = tmp_ssid_len; + } + printk(KERN_INFO"Linking with %s,channel:%d, qos:%d, " + "myHT:%d, networkHT:%d, mode:%x cur_net.flags" + ":0x%x\n", ieee->current_network.ssid, + ieee->current_network.channel, + ieee->current_network.qos_data.supported, + ieee->pHTInfo->bEnableHT, + ieee->current_network.bssht.bdSupportHT, + ieee->current_network.mode, + ieee->current_network.flags); + + if ((rtllib_act_scanning(ieee, false)) && + !(ieee->softmac_features & IEEE_SOFTMAC_SCAN)) + rtllib_stop_scan_syncro(ieee); + + ieee->hwscan_ch_bk = ieee->current_network.channel; + HTResetIOTSetting(ieee->pHTInfo); + ieee->wmm_acm = 0; + if (ieee->iw_mode == IW_MODE_INFRA) { + /* Join the network for the first time */ + ieee->AsocRetryCount = 0; + if ((ieee->current_network.qos_data.supported == 1) && + ieee->current_network.bssht.bdSupportHT) + HTResetSelfAndSavePeerSetting(ieee, + &(ieee->current_network)); + else + ieee->pHTInfo->bCurrentHTSupport = + false; + + ieee->state = RTLLIB_ASSOCIATING; + if (ieee->LedControlHandler != NULL) + ieee->LedControlHandler(ieee->dev, + LED_CTL_START_TO_LINK); + queue_delayed_work_rsl(ieee->wq, + &ieee->associate_procedure_wq, 0); + } else { + if (rtllib_is_54g(&ieee->current_network) && + (ieee->modulation & RTLLIB_OFDM_MODULATION)) { + ieee->rate = 108; + ieee->SetWirelessMode(ieee->dev, IEEE_G); + printk(KERN_INFO"Using G rates\n"); + } else { + ieee->rate = 22; + ieee->SetWirelessMode(ieee->dev, IEEE_B); + printk(KERN_INFO"Using B rates\n"); + } + memset(ieee->dot11HTOperationalRateSet, 0, 16); + ieee->state = RTLLIB_LINKED; + } + } + } +} + +void rtllib_softmac_check_all_nets(struct rtllib_device *ieee) +{ + unsigned long flags; + struct rtllib_network *target; + + spin_lock_irqsave(&ieee->lock, flags); + + list_for_each_entry(target, &ieee->network_list, list) { + + /* if the state become different that NOLINK means + * we had found what we are searching for + */ + + if (ieee->state != RTLLIB_NOLINK) + break; + + if (ieee->scan_age == 0 || time_after(target->last_scanned + + ieee->scan_age, jiffies)) + rtllib_softmac_new_net(ieee, target); + } + spin_unlock_irqrestore(&ieee->lock, flags); +} + +static inline u16 auth_parse(struct sk_buff *skb, u8** challenge, int *chlen) +{ + struct rtllib_authentication *a; + u8 *t; + if (skb->len < (sizeof(struct rtllib_authentication) - + sizeof(struct rtllib_info_element))) { + RTLLIB_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len); + return 0xcafe; + } + *challenge = NULL; + a = (struct rtllib_authentication *) skb->data; + if (skb->len > (sizeof(struct rtllib_authentication) + 3)) { + t = skb->data + sizeof(struct rtllib_authentication); + + if (*(t++) == MFIE_TYPE_CHALLENGE) { + *chlen = *(t++); + *challenge = kmalloc(*chlen, GFP_ATOMIC); + memcpy(*challenge, t, *chlen); /*TODO - check here*/ + } + } + return cpu_to_le16(a->status); +} + +static int auth_rq_parse(struct sk_buff *skb, u8 *dest) +{ + struct rtllib_authentication *a; + + if (skb->len < (sizeof(struct rtllib_authentication) - + sizeof(struct rtllib_info_element))) { + RTLLIB_DEBUG_MGMT("invalid len in auth request: %d\n", + skb->len); + return -1; + } + a = (struct rtllib_authentication *) skb->data; + + memcpy(dest, a->header.addr2, ETH_ALEN); + + if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN) + return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG; + + return WLAN_STATUS_SUCCESS; +} + +static short probe_rq_parse(struct rtllib_device *ieee, struct sk_buff *skb, + u8 *src) +{ + u8 *tag; + u8 *skbend; + u8 *ssid = NULL; + u8 ssidlen = 0; + struct rtllib_hdr_3addr *header = + (struct rtllib_hdr_3addr *) skb->data; + bool bssid_match; + + if (skb->len < sizeof(struct rtllib_hdr_3addr)) + return -1; /* corrupted */ + + bssid_match = + (memcmp(header->addr3, ieee->current_network.bssid, ETH_ALEN) != 0) && + (memcmp(header->addr3, "\xff\xff\xff\xff\xff\xff", ETH_ALEN) != 0); + if (bssid_match) + return -1; + + memcpy(src, header->addr2, ETH_ALEN); + + skbend = (u8 *)skb->data + skb->len; + + tag = skb->data + sizeof(struct rtllib_hdr_3addr); + + while (tag + 1 < skbend) { + if (*tag == 0) { + ssid = tag + 2; + ssidlen = *(tag + 1); + break; + } + tag++; /* point to the len field */ + tag = tag + *(tag); /* point to the last data byte of the tag */ + tag++; /* point to the next tag */ + } + + if (ssidlen == 0) + return 1; + + if (!ssid) + return 1; /* ssid not found in tagged param */ + + return !strncmp(ssid, ieee->current_network.ssid, ssidlen); +} + +static int assoc_rq_parse(struct sk_buff *skb, u8 *dest) +{ + struct rtllib_assoc_request_frame *a; + + if (skb->len < (sizeof(struct rtllib_assoc_request_frame) - + sizeof(struct rtllib_info_element))) { + + RTLLIB_DEBUG_MGMT("invalid len in auth request:%d\n", skb->len); + return -1; + } + + a = (struct rtllib_assoc_request_frame *) skb->data; + + memcpy(dest, a->header.addr2, ETH_ALEN); + + return 0; +} + +static inline u16 assoc_parse(struct rtllib_device *ieee, struct sk_buff *skb, + int *aid) +{ + struct rtllib_assoc_response_frame *response_head; + u16 status_code; + + if (skb->len < sizeof(struct rtllib_assoc_response_frame)) { + RTLLIB_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len); + return 0xcafe; + } + + response_head = (struct rtllib_assoc_response_frame *) skb->data; + *aid = le16_to_cpu(response_head->aid) & 0x3fff; + + status_code = le16_to_cpu(response_head->status); + if ((status_code == WLAN_STATUS_ASSOC_DENIED_RATES || + status_code == WLAN_STATUS_CAPS_UNSUPPORTED) && + ((ieee->mode == IEEE_G) && + (ieee->current_network.mode == IEEE_N_24G) && + (ieee->AsocRetryCount++ < (RT_ASOC_RETRY_LIMIT-1)))) { + ieee->pHTInfo->IOTAction |= HT_IOT_ACT_PURE_N_MODE; + } else { + ieee->AsocRetryCount = 0; + } + + return le16_to_cpu(response_head->status); +} + +void rtllib_rx_probe_rq(struct rtllib_device *ieee, struct sk_buff *skb) +{ + u8 dest[ETH_ALEN]; + ieee->softmac_stats.rx_probe_rq++; + if (probe_rq_parse(ieee, skb, dest) > 0) { + ieee->softmac_stats.tx_probe_rs++; + rtllib_resp_to_probe(ieee, dest); + } +} + +static inline void rtllib_rx_auth_rq(struct rtllib_device *ieee, + struct sk_buff *skb) +{ + u8 dest[ETH_ALEN]; + int status; + ieee->softmac_stats.rx_auth_rq++; + + status = auth_rq_parse(skb, dest); + if (status != -1) + rtllib_resp_to_auth(ieee, status, dest); +} + +static inline void rtllib_rx_assoc_rq(struct rtllib_device *ieee, + struct sk_buff *skb) +{ + + u8 dest[ETH_ALEN]; + + ieee->softmac_stats.rx_ass_rq++; + if (assoc_rq_parse(skb, dest) != -1) + rtllib_resp_to_assoc_rq(ieee, dest); + + printk(KERN_INFO"New client associated: %pM\n", dest); +} + +void rtllib_sta_ps_send_null_frame(struct rtllib_device *ieee, short pwr) +{ + + struct sk_buff *buf = rtllib_null_func(ieee, pwr); + + if (buf) + softmac_ps_mgmt_xmit(buf, ieee); +} + +void rtllib_sta_ps_send_pspoll_frame(struct rtllib_device *ieee) +{ + struct sk_buff *buf = rtllib_pspoll_func(ieee); + + if (buf) + softmac_ps_mgmt_xmit(buf, ieee); +} + +static short rtllib_sta_ps_sleep(struct rtllib_device *ieee, u64 *time) +{ + int timeout = ieee->ps_timeout; + u8 dtim; + struct rt_pwr_save_ctrl *pPSC = (struct rt_pwr_save_ctrl *) + (&(ieee->PowerSaveControl)); + + if (ieee->LPSDelayCnt) { + ieee->LPSDelayCnt--; + return 0; + } + + dtim = ieee->current_network.dtim_data; + if (!(dtim & RTLLIB_DTIM_VALID)) + return 0; + timeout = ieee->current_network.beacon_interval; + ieee->current_network.dtim_data = RTLLIB_DTIM_INVALID; + /* there's no need to nofity AP that I find you buffered + * with broadcast packet */ + if (dtim & (RTLLIB_DTIM_UCAST & ieee->ps)) + return 2; + + if (!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout))) + return 0; + if (!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout))) + return 0; + if ((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE) && + (ieee->mgmt_queue_tail != ieee->mgmt_queue_head)) + return 0; + + if (time) { + if (ieee->bAwakePktSent == true) { + pPSC->LPSAwakeIntvl = 1; + } else { + u8 MaxPeriod = 1; + + if (pPSC->LPSAwakeIntvl == 0) + pPSC->LPSAwakeIntvl = 1; + if (pPSC->RegMaxLPSAwakeIntvl == 0) + MaxPeriod = 1; + else if (pPSC->RegMaxLPSAwakeIntvl == 0xFF) + MaxPeriod = ieee->current_network.dtim_period; + else + MaxPeriod = pPSC->RegMaxLPSAwakeIntvl; + pPSC->LPSAwakeIntvl = (pPSC->LPSAwakeIntvl >= + MaxPeriod) ? MaxPeriod : + (pPSC->LPSAwakeIntvl + 1); + } + { + u8 LPSAwakeIntvl_tmp = 0; + u8 period = ieee->current_network.dtim_period; + u8 count = ieee->current_network.tim.tim_count; + if (count == 0) { + if (pPSC->LPSAwakeIntvl > period) + LPSAwakeIntvl_tmp = period + + (pPSC->LPSAwakeIntvl - + period) - + ((pPSC->LPSAwakeIntvl-period) % + period); + else + LPSAwakeIntvl_tmp = pPSC->LPSAwakeIntvl; + + } else { + if (pPSC->LPSAwakeIntvl > + ieee->current_network.tim.tim_count) + LPSAwakeIntvl_tmp = count + + (pPSC->LPSAwakeIntvl - count) - + ((pPSC->LPSAwakeIntvl-count)%period); + else + LPSAwakeIntvl_tmp = pPSC->LPSAwakeIntvl; + } + + *time = ieee->current_network.last_dtim_sta_time + + MSECS(ieee->current_network.beacon_interval * + LPSAwakeIntvl_tmp); + } + } + + return 1; + + +} + +static inline void rtllib_sta_ps(struct rtllib_device *ieee) +{ + u64 time; + short sleep; + unsigned long flags, flags2; + + spin_lock_irqsave(&ieee->lock, flags); + + if ((ieee->ps == RTLLIB_PS_DISABLED || + ieee->iw_mode != IW_MODE_INFRA || + ieee->state != RTLLIB_LINKED)) { + RT_TRACE(COMP_DBG, "=====>%s(): no need to ps,wake up!! " + "ieee->ps is %d, ieee->iw_mode is %d, ieee->state" + " is %d\n", __func__, ieee->ps, ieee->iw_mode, + ieee->state); + spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); + rtllib_sta_wakeup(ieee, 1); + + spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2); + } + sleep = rtllib_sta_ps_sleep(ieee, &time); + /* 2 wake, 1 sleep, 0 do nothing */ + if (sleep == 0) + goto out; + if (sleep == 1) { + if (ieee->sta_sleep == LPS_IS_SLEEP) { + ieee->enter_sleep_state(ieee->dev, time); + } else if (ieee->sta_sleep == LPS_IS_WAKE) { + spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); + + if (ieee->ps_is_queue_empty(ieee->dev)) { + ieee->sta_sleep = LPS_WAIT_NULL_DATA_SEND; + ieee->ack_tx_to_ieee = 1; + rtllib_sta_ps_send_null_frame(ieee, 1); + ieee->ps_time = time; + } + spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2); + + } + + ieee->bAwakePktSent = false; + + } else if (sleep == 2) { + spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); + + rtllib_sta_wakeup(ieee, 1); + + spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2); + } + +out: + spin_unlock_irqrestore(&ieee->lock, flags); + +} + +void rtllib_sta_wakeup(struct rtllib_device *ieee, short nl) +{ + if (ieee->sta_sleep == LPS_IS_WAKE) { + if (nl) { + if (ieee->pHTInfo->IOTAction & + HT_IOT_ACT_NULL_DATA_POWER_SAVING) { + ieee->ack_tx_to_ieee = 1; + rtllib_sta_ps_send_null_frame(ieee, 0); + } else { + ieee->ack_tx_to_ieee = 1; + rtllib_sta_ps_send_pspoll_frame(ieee); + } + } + return; + + } + + if (ieee->sta_sleep == LPS_IS_SLEEP) + ieee->sta_wake_up(ieee->dev); + if (nl) { + if (ieee->pHTInfo->IOTAction & + HT_IOT_ACT_NULL_DATA_POWER_SAVING) { + ieee->ack_tx_to_ieee = 1; + rtllib_sta_ps_send_null_frame(ieee, 0); + } else { + ieee->ack_tx_to_ieee = 1; + ieee->polling = true; + rtllib_sta_ps_send_pspoll_frame(ieee); + } + + } else { + ieee->sta_sleep = LPS_IS_WAKE; + ieee->polling = false; + } +} + +void rtllib_ps_tx_ack(struct rtllib_device *ieee, short success) +{ + unsigned long flags, flags2; + + spin_lock_irqsave(&ieee->lock, flags); + + if (ieee->sta_sleep == LPS_WAIT_NULL_DATA_SEND) { + /* Null frame with PS bit set */ + if (success) { + ieee->sta_sleep = LPS_IS_SLEEP; + ieee->enter_sleep_state(ieee->dev, ieee->ps_time); + } + /* if the card report not success we can't be sure the AP + * has not RXed so we can't assume the AP believe us awake + */ + } else {/* 21112005 - tx again null without PS bit if lost */ + + if ((ieee->sta_sleep == LPS_IS_WAKE) && !success) { + spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2); + if (ieee->pHTInfo->IOTAction & + HT_IOT_ACT_NULL_DATA_POWER_SAVING) + rtllib_sta_ps_send_null_frame(ieee, 0); + else + rtllib_sta_ps_send_pspoll_frame(ieee); + spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2); + } + } + spin_unlock_irqrestore(&ieee->lock, flags); +} + +static void rtllib_process_action(struct rtllib_device *ieee, struct sk_buff *skb) +{ + struct rtllib_hdr_3addr *header = (struct rtllib_hdr_3addr *) skb->data; + u8 *act = rtllib_get_payload((struct rtllib_hdr *)header); + u8 category = 0; + + if (act == NULL) { + RTLLIB_DEBUG(RTLLIB_DL_ERR, "error to get payload of " + "action frame\n"); + return; + } + + category = *act; + act++; + switch (category) { + case ACT_CAT_BA: + switch (*act) { + case ACT_ADDBAREQ: + rtllib_rx_ADDBAReq(ieee, skb); + break; + case ACT_ADDBARSP: + rtllib_rx_ADDBARsp(ieee, skb); + break; + case ACT_DELBA: + rtllib_rx_DELBA(ieee, skb); + break; + } + break; + default: + break; + } + return; +} + +inline int rtllib_rx_assoc_resp(struct rtllib_device *ieee, struct sk_buff *skb, + struct rtllib_rx_stats *rx_stats) +{ + u16 errcode; + int aid; + u8 *ies; + struct rtllib_assoc_response_frame *assoc_resp; + struct rtllib_hdr_3addr *header = (struct rtllib_hdr_3addr *) skb->data; + + RTLLIB_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n", + WLAN_FC_GET_STYPE(header->frame_ctl)); + + if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) && + ieee->state == RTLLIB_ASSOCIATING_AUTHENTICATED && + (ieee->iw_mode == IW_MODE_INFRA)) { + errcode = assoc_parse(ieee, skb, &aid); + if (0 == errcode) { + struct rtllib_network *network = + kzalloc(sizeof(struct rtllib_network), + GFP_ATOMIC); + + if (!network) + return 1; + memset(network, 0, sizeof(*network)); + ieee->state = RTLLIB_LINKED; + ieee->assoc_id = aid; + ieee->softmac_stats.rx_ass_ok++; + /* station support qos */ + /* Let the register setting default with Legacy station */ + assoc_resp = (struct rtllib_assoc_response_frame *)skb->data; + if (ieee->current_network.qos_data.supported == 1) { + if (rtllib_parse_info_param(ieee, assoc_resp->info_element, + rx_stats->len - sizeof(*assoc_resp), + network, rx_stats)) { + kfree(network); + return 1; + } else { + memcpy(ieee->pHTInfo->PeerHTCapBuf, + network->bssht.bdHTCapBuf, + network->bssht.bdHTCapLen); + memcpy(ieee->pHTInfo->PeerHTInfoBuf, + network->bssht.bdHTInfoBuf, + network->bssht.bdHTInfoLen); + } + if (ieee->handle_assoc_response != NULL) + ieee->handle_assoc_response(ieee->dev, + (struct rtllib_assoc_response_frame *)header, + network); + kfree(network); + } + + kfree(ieee->assocresp_ies); + ieee->assocresp_ies = NULL; + ies = &(assoc_resp->info_element[0].id); + ieee->assocresp_ies_len = (skb->data + skb->len) - ies; + ieee->assocresp_ies = kmalloc(ieee->assocresp_ies_len, + GFP_ATOMIC); + if (ieee->assocresp_ies) + memcpy(ieee->assocresp_ies, ies, + ieee->assocresp_ies_len); + else { + printk(KERN_INFO "%s()Warning: can't alloc " + "memory for assocresp_ies\n", __func__); + ieee->assocresp_ies_len = 0; + } + rtllib_associate_complete(ieee); + } else { + /* aid could not been allocated */ + ieee->softmac_stats.rx_ass_err++; + printk(KERN_INFO "Association response status code 0x%x\n", + errcode); + RTLLIB_DEBUG_MGMT( + "Association response status code 0x%x\n", + errcode); + if (ieee->AsocRetryCount < RT_ASOC_RETRY_LIMIT) + queue_delayed_work_rsl(ieee->wq, + &ieee->associate_procedure_wq, 0); + else + rtllib_associate_abort(ieee); + } + } + return 0; +} + +inline int rtllib_rx_auth(struct rtllib_device *ieee, struct sk_buff *skb, + struct rtllib_rx_stats *rx_stats) +{ + u16 errcode; + u8 *challenge; + int chlen = 0; + bool bSupportNmode = true, bHalfSupportNmode = false; + + if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) { + if (ieee->state == RTLLIB_ASSOCIATING_AUTHENTICATING && + (ieee->iw_mode == IW_MODE_INFRA)) { + RTLLIB_DEBUG_MGMT("Received authentication response"); + + errcode = auth_parse(skb, &challenge, &chlen); + if (0 == errcode) { + if (ieee->open_wep || !challenge) { + ieee->state = RTLLIB_ASSOCIATING_AUTHENTICATED; + ieee->softmac_stats.rx_auth_rs_ok++; + if (!(ieee->pHTInfo->IOTAction & + HT_IOT_ACT_PURE_N_MODE)) { + if (!ieee->GetNmodeSupportBySecCfg(ieee->dev)) { + if (IsHTHalfNmodeAPs(ieee)) { + bSupportNmode = true; + bHalfSupportNmode = true; + } else { + bSupportNmode = false; + bHalfSupportNmode = false; + } + } + } + /* Dummy wirless mode setting to avoid + * encryption issue */ + if (bSupportNmode) { + ieee->SetWirelessMode(ieee->dev, + ieee->current_network.mode); + } else { + /*TODO*/ + ieee->SetWirelessMode(ieee->dev, + IEEE_G); + } + + if (ieee->current_network.mode == + IEEE_N_24G && + bHalfSupportNmode == true) { + printk(KERN_INFO "======>enter " + "half N mode\n"); + ieee->bHalfWirelessN24GMode = + true; + } else + ieee->bHalfWirelessN24GMode = + false; + + rtllib_associate_step2(ieee); + } else { + rtllib_auth_challenge(ieee, challenge, + chlen); + } + } else { + ieee->softmac_stats.rx_auth_rs_err++; + RTLLIB_DEBUG_MGMT("Authentication respose" + " status code 0x%x", errcode); + + printk(KERN_INFO "Authentication respose " + "status code 0x%x", errcode); + rtllib_associate_abort(ieee); + } + + } else if (ieee->iw_mode == IW_MODE_MASTER) { + rtllib_rx_auth_rq(ieee, skb); + } + } + return 0; +} + +inline int rtllib_rx_deauth(struct rtllib_device *ieee, struct sk_buff *skb) +{ + struct rtllib_hdr_3addr *header = (struct rtllib_hdr_3addr *) skb->data; + + if (memcmp(header->addr3, ieee->current_network.bssid, ETH_ALEN) != 0) + return 0; + + /* FIXME for now repeat all the association procedure + * both for disassociation and deauthentication + */ + if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) && + ieee->state == RTLLIB_LINKED && + (ieee->iw_mode == IW_MODE_INFRA)) { + printk(KERN_INFO "==========>received disassoc/deauth(%x) " + "frame, reason code:%x\n", + WLAN_FC_GET_STYPE(header->frame_ctl), + ((struct rtllib_disassoc *)skb->data)->reason); + ieee->state = RTLLIB_ASSOCIATING; + ieee->softmac_stats.reassoc++; + ieee->is_roaming = true; + ieee->LinkDetectInfo.bBusyTraffic = false; + rtllib_disassociate(ieee); + RemovePeerTS(ieee, header->addr2); + if (ieee->LedControlHandler != NULL) + ieee->LedControlHandler(ieee->dev, + LED_CTL_START_TO_LINK); + + if (!(ieee->rtllib_ap_sec_type(ieee) & + (SEC_ALG_CCMP|SEC_ALG_TKIP))) + queue_delayed_work_rsl(ieee->wq, + &ieee->associate_procedure_wq, 5); + } + return 0; +} + +inline int rtllib_rx_frame_softmac(struct rtllib_device *ieee, + struct sk_buff *skb, + struct rtllib_rx_stats *rx_stats, u16 type, + u16 stype) +{ + struct rtllib_hdr_3addr *header = (struct rtllib_hdr_3addr *) skb->data; + + if (!ieee->proto_started) + return 0; + + switch (WLAN_FC_GET_STYPE(header->frame_ctl)) { + case RTLLIB_STYPE_ASSOC_RESP: + case RTLLIB_STYPE_REASSOC_RESP: + if (rtllib_rx_assoc_resp(ieee, skb, rx_stats) == 1) + return 1; + break; + case RTLLIB_STYPE_ASSOC_REQ: + case RTLLIB_STYPE_REASSOC_REQ: + if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) && + ieee->iw_mode == IW_MODE_MASTER) + rtllib_rx_assoc_rq(ieee, skb); + break; + case RTLLIB_STYPE_AUTH: + rtllib_rx_auth(ieee, skb, rx_stats); + break; + case RTLLIB_STYPE_DISASSOC: + case RTLLIB_STYPE_DEAUTH: + rtllib_rx_deauth(ieee, skb); + break; + case RTLLIB_STYPE_MANAGE_ACT: + rtllib_process_action(ieee, skb); + break; + default: + return -1; + break; + } + return 0; +} + +/* following are for a simplier TX queue management. + * Instead of using netif_[stop/wake]_queue the driver + * will uses these two function (plus a reset one), that + * will internally uses the kernel netif_* and takes + * care of the ieee802.11 fragmentation. + * So the driver receives a fragment per time and might + * call the stop function when it want without take care + * to have enought room to TX an entire packet. + * This might be useful if each fragment need it's own + * descriptor, thus just keep a total free memory > than + * the max fragmentation treshold is not enought.. If the + * ieee802.11 stack passed a TXB struct then you needed + * to keep N free descriptors where + * N = MAX_PACKET_SIZE / MIN_FRAG_TRESHOLD + * In this way you need just one and the 802.11 stack + * will take care of buffering fragments and pass them to + * to the driver later, when it wakes the queue. + */ +void rtllib_softmac_xmit(struct rtllib_txb *txb, struct rtllib_device *ieee) +{ + + unsigned int queue_index = txb->queue_index; + unsigned long flags; + int i; + struct cb_desc *tcb_desc = NULL; + unsigned long queue_len = 0; + + spin_lock_irqsave(&ieee->lock, flags); + + /* called with 2nd parm 0, no tx mgmt lock required */ + rtllib_sta_wakeup(ieee, 0); + + /* update the tx status */ + tcb_desc = (struct cb_desc *)(txb->fragments[0]->cb + + MAX_DEV_ADDR_SIZE); + if (tcb_desc->bMulticast) + ieee->stats.multicast++; + + /* if xmit available, just xmit it immediately, else just insert it to + * the wait queue */ + for (i = 0; i < txb->nr_frags; i++) { + queue_len = skb_queue_len(&ieee->skb_waitQ[queue_index]); + if ((queue_len != 0) ||\ + (!ieee->check_nic_enough_desc(ieee->dev, queue_index)) || + (ieee->queue_stop)) { + /* insert the skb packet to the wait queue */ + /* as for the completion function, it does not need + * to check it any more. + * */ + if (queue_len < 200) + skb_queue_tail(&ieee->skb_waitQ[queue_index], + txb->fragments[i]); + else + kfree_skb(txb->fragments[i]); + } else { + ieee->softmac_data_hard_start_xmit( + txb->fragments[i], + ieee->dev, ieee->rate); + } + } + + rtllib_txb_free(txb); + + spin_unlock_irqrestore(&ieee->lock, flags); + +} + +/* called with ieee->lock acquired */ +static void rtllib_resume_tx(struct rtllib_device *ieee) +{ + int i; + for (i = ieee->tx_pending.frag; i < ieee->tx_pending.txb->nr_frags; + i++) { + + if (ieee->queue_stop) { + ieee->tx_pending.frag = i; + return; + } else { + + ieee->softmac_data_hard_start_xmit( + ieee->tx_pending.txb->fragments[i], + ieee->dev, ieee->rate); + ieee->stats.tx_packets++; + } + } + + rtllib_txb_free(ieee->tx_pending.txb); + ieee->tx_pending.txb = NULL; +} + + +void rtllib_reset_queue(struct rtllib_device *ieee) +{ + unsigned long flags; + + spin_lock_irqsave(&ieee->lock, flags); + init_mgmt_queue(ieee); + if (ieee->tx_pending.txb) { + rtllib_txb_free(ieee->tx_pending.txb); + ieee->tx_pending.txb = NULL; + } + ieee->queue_stop = 0; + spin_unlock_irqrestore(&ieee->lock, flags); + +} + +void rtllib_wake_queue(struct rtllib_device *ieee) +{ + + unsigned long flags; + struct sk_buff *skb; + struct rtllib_hdr_3addr *header; + + spin_lock_irqsave(&ieee->lock, flags); + if (!ieee->queue_stop) + goto exit; + + ieee->queue_stop = 0; + + if (ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE) { + while (!ieee->queue_stop && (skb = dequeue_mgmt(ieee))) { + + header = (struct rtllib_hdr_3addr *) skb->data; + + header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); + + if (ieee->seq_ctrl[0] == 0xFFF) + ieee->seq_ctrl[0] = 0; + else + ieee->seq_ctrl[0]++; + + ieee->softmac_data_hard_start_xmit(skb, ieee->dev, + ieee->basic_rate); + } + } + if (!ieee->queue_stop && ieee->tx_pending.txb) + rtllib_resume_tx(ieee); + + if (!ieee->queue_stop && netif_queue_stopped(ieee->dev)) { + ieee->softmac_stats.swtxawake++; + netif_wake_queue(ieee->dev); + } + +exit: + spin_unlock_irqrestore(&ieee->lock, flags); +} + + +void rtllib_stop_queue(struct rtllib_device *ieee) +{ + + if (!netif_queue_stopped(ieee->dev)) { + netif_stop_queue(ieee->dev); + ieee->softmac_stats.swtxstop++; + } + ieee->queue_stop = 1; + +} + +void rtllib_stop_all_queues(struct rtllib_device *ieee) +{ + unsigned int i; + for (i = 0; i < ieee->dev->num_tx_queues; i++) + netdev_get_tx_queue(ieee->dev, i)->trans_start = jiffies; + + netif_tx_stop_all_queues(ieee->dev); +} + +void rtllib_wake_all_queues(struct rtllib_device *ieee) +{ + netif_tx_wake_all_queues(ieee->dev); +} + +inline void rtllib_randomize_cell(struct rtllib_device *ieee) +{ + + get_random_bytes(ieee->current_network.bssid, ETH_ALEN); + + /* an IBSS cell address must have the two less significant + * bits of the first byte = 2 + */ + ieee->current_network.bssid[0] &= ~0x01; + ieee->current_network.bssid[0] |= 0x02; +} + +/* called in user context only */ +void rtllib_start_master_bss(struct rtllib_device *ieee) +{ + ieee->assoc_id = 1; + + if (ieee->current_network.ssid_len == 0) { + strncpy(ieee->current_network.ssid, + RTLLIB_DEFAULT_TX_ESSID, + IW_ESSID_MAX_SIZE); + + ieee->current_network.ssid_len = + strlen(RTLLIB_DEFAULT_TX_ESSID); + ieee->ssid_set = 1; + } + + memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN); + + ieee->set_chan(ieee->dev, ieee->current_network.channel); + ieee->state = RTLLIB_LINKED; + ieee->link_change(ieee->dev); + notify_wx_assoc_event(ieee); + + if (ieee->data_hard_resume) + ieee->data_hard_resume(ieee->dev); + + netif_carrier_on(ieee->dev); +} + +static void rtllib_start_monitor_mode(struct rtllib_device *ieee) +{ + /* reset hardware status */ + if (ieee->raw_tx) { + if (ieee->data_hard_resume) + ieee->data_hard_resume(ieee->dev); + + netif_carrier_on(ieee->dev); + } +} + +static void rtllib_start_ibss_wq(void *data) +{ + struct rtllib_device *ieee = container_of_dwork_rsl(data, + struct rtllib_device, start_ibss_wq); + /* iwconfig mode ad-hoc will schedule this and return + * on the other hand this will block further iwconfig SET + * operations because of the wx_sem hold. + * Anyway some most set operations set a flag to speed-up + * (abort) this wq (when syncro scanning) before sleeping + * on the semaphore + */ + if (!ieee->proto_started) { + printk(KERN_INFO "==========oh driver down return\n"); + return; + } + down(&ieee->wx_sem); + + if (ieee->current_network.ssid_len == 0) { + strcpy(ieee->current_network.ssid, RTLLIB_DEFAULT_TX_ESSID); + ieee->current_network.ssid_len = strlen(RTLLIB_DEFAULT_TX_ESSID); + ieee->ssid_set = 1; + } + + ieee->state = RTLLIB_NOLINK; + ieee->mode = IEEE_G; + /* check if we have this cell in our network list */ + rtllib_softmac_check_all_nets(ieee); + + + /* if not then the state is not linked. Maybe the user swithced to + * ad-hoc mode just after being in monitor mode, or just after + * being very few time in managed mode (so the card have had no + * time to scan all the chans..) or we have just run up the iface + * after setting ad-hoc mode. So we have to give another try.. + * Here, in ibss mode, should be safe to do this without extra care + * (in bss mode we had to make sure no-one tryed to associate when + * we had just checked the ieee->state and we was going to start the + * scan) beacause in ibss mode the rtllib_new_net function, when + * finds a good net, just set the ieee->state to RTLLIB_LINKED, + * so, at worst, we waste a bit of time to initiate an unneeded syncro + * scan, that will stop at the first round because it sees the state + * associated. + */ + if (ieee->state == RTLLIB_NOLINK) + rtllib_start_scan_syncro(ieee, 0); + + /* the network definitively is not here.. create a new cell */ + if (ieee->state == RTLLIB_NOLINK) { + printk(KERN_INFO "creating new IBSS cell\n"); + ieee->current_network.channel = ieee->IbssStartChnl; + if (!ieee->wap_set) + rtllib_randomize_cell(ieee); + + if (ieee->modulation & RTLLIB_CCK_MODULATION) { + + ieee->current_network.rates_len = 4; + + ieee->current_network.rates[0] = + RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_1MB; + ieee->current_network.rates[1] = + RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_2MB; + ieee->current_network.rates[2] = + RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_5MB; + ieee->current_network.rates[3] = + RTLLIB_BASIC_RATE_MASK | RTLLIB_CCK_RATE_11MB; + + } else + ieee->current_network.rates_len = 0; + + if (ieee->modulation & RTLLIB_OFDM_MODULATION) { + ieee->current_network.rates_ex_len = 8; + + ieee->current_network.rates_ex[0] = + RTLLIB_OFDM_RATE_6MB; + ieee->current_network.rates_ex[1] = + RTLLIB_OFDM_RATE_9MB; + ieee->current_network.rates_ex[2] = + RTLLIB_OFDM_RATE_12MB; + ieee->current_network.rates_ex[3] = + RTLLIB_OFDM_RATE_18MB; + ieee->current_network.rates_ex[4] = + RTLLIB_OFDM_RATE_24MB; + ieee->current_network.rates_ex[5] = + RTLLIB_OFDM_RATE_36MB; + ieee->current_network.rates_ex[6] = + RTLLIB_OFDM_RATE_48MB; + ieee->current_network.rates_ex[7] = + RTLLIB_OFDM_RATE_54MB; + + ieee->rate = 108; + } else { + ieee->current_network.rates_ex_len = 0; + ieee->rate = 22; + } + + ieee->current_network.qos_data.supported = 0; + ieee->SetWirelessMode(ieee->dev, IEEE_G); + ieee->current_network.mode = ieee->mode; + ieee->current_network.atim_window = 0; + ieee->current_network.capability = WLAN_CAPABILITY_IBSS; + } + + printk(KERN_INFO "%s(): ieee->mode = %d\n", __func__, ieee->mode); + if ((ieee->mode == IEEE_N_24G) || (ieee->mode == IEEE_N_5G)) + HTUseDefaultSetting(ieee); + else + ieee->pHTInfo->bCurrentHTSupport = false; + + ieee->SetHwRegHandler(ieee->dev, HW_VAR_MEDIA_STATUS, + (u8 *)(&ieee->state)); + + ieee->state = RTLLIB_LINKED; + ieee->link_change(ieee->dev); + + HTSetConnectBwMode(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); + if (ieee->LedControlHandler != NULL) + ieee->LedControlHandler(ieee->dev, LED_CTL_LINK); + + rtllib_start_send_beacons(ieee); + + notify_wx_assoc_event(ieee); + + if (ieee->data_hard_resume) + ieee->data_hard_resume(ieee->dev); + + netif_carrier_on(ieee->dev); + + up(&ieee->wx_sem); +} + +inline void rtllib_start_ibss(struct rtllib_device *ieee) +{ + queue_delayed_work_rsl(ieee->wq, &ieee->start_ibss_wq, MSECS(150)); +} + +/* this is called only in user context, with wx_sem held */ +void rtllib_start_bss(struct rtllib_device *ieee) +{ + unsigned long flags; + if (IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee)) { + if (!ieee->bGlobalDomain) + return; + } + /* check if we have already found the net we + * are interested in (if any). + * if not (we are disassociated and we are not + * in associating / authenticating phase) start the background scanning. + */ + rtllib_softmac_check_all_nets(ieee); + + /* ensure no-one start an associating process (thus setting + * the ieee->state to rtllib_ASSOCIATING) while we + * have just cheked it and we are going to enable scan. + * The rtllib_new_net function is always called with + * lock held (from both rtllib_softmac_check_all_nets and + * the rx path), so we cannot be in the middle of such function + */ + spin_lock_irqsave(&ieee->lock, flags); + + if (ieee->state == RTLLIB_NOLINK) + rtllib_start_scan(ieee); + spin_unlock_irqrestore(&ieee->lock, flags); +} + +static void rtllib_link_change_wq(void *data) +{ + struct rtllib_device *ieee = container_of_dwork_rsl(data, + struct rtllib_device, link_change_wq); + ieee->link_change(ieee->dev); +} +/* called only in userspace context */ +void rtllib_disassociate(struct rtllib_device *ieee) +{ + netif_carrier_off(ieee->dev); + if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE) + rtllib_reset_queue(ieee); + + if (ieee->data_hard_stop) + ieee->data_hard_stop(ieee->dev); + if (IS_DOT11D_ENABLE(ieee)) + Dot11d_Reset(ieee); + ieee->state = RTLLIB_NOLINK; + ieee->is_set_key = false; + ieee->wap_set = 0; + + queue_delayed_work_rsl(ieee->wq, &ieee->link_change_wq, 0); + + notify_wx_assoc_event(ieee); +} + +static void rtllib_associate_retry_wq(void *data) +{ + struct rtllib_device *ieee = container_of_dwork_rsl(data, + struct rtllib_device, associate_retry_wq); + unsigned long flags; + + down(&ieee->wx_sem); + if (!ieee->proto_started) + goto exit; + + if (ieee->state != RTLLIB_ASSOCIATING_RETRY) + goto exit; + + /* until we do not set the state to RTLLIB_NOLINK + * there are no possibility to have someone else trying + * to start an association procdure (we get here with + * ieee->state = RTLLIB_ASSOCIATING). + * When we set the state to RTLLIB_NOLINK it is possible + * that the RX path run an attempt to associate, but + * both rtllib_softmac_check_all_nets and the + * RX path works with ieee->lock held so there are no + * problems. If we are still disassociated then start a scan. + * the lock here is necessary to ensure no one try to start + * an association procedure when we have just checked the + * state and we are going to start the scan. + */ + ieee->beinretry = true; + ieee->state = RTLLIB_NOLINK; + + rtllib_softmac_check_all_nets(ieee); + + spin_lock_irqsave(&ieee->lock, flags); + + if (ieee->state == RTLLIB_NOLINK) + rtllib_start_scan(ieee); + spin_unlock_irqrestore(&ieee->lock, flags); + + ieee->beinretry = false; +exit: + up(&ieee->wx_sem); +} + +struct sk_buff *rtllib_get_beacon_(struct rtllib_device *ieee) +{ + u8 broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; + + struct sk_buff *skb; + struct rtllib_probe_response *b; + skb = rtllib_probe_resp(ieee, broadcast_addr); + + if (!skb) + return NULL; + + b = (struct rtllib_probe_response *) skb->data; + b->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_BEACON); + + return skb; + +} + +struct sk_buff *rtllib_get_beacon(struct rtllib_device *ieee) +{ + struct sk_buff *skb; + struct rtllib_probe_response *b; + + skb = rtllib_get_beacon_(ieee); + if (!skb) + return NULL; + + b = (struct rtllib_probe_response *) skb->data; + b->header.seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); + + if (ieee->seq_ctrl[0] == 0xFFF) + ieee->seq_ctrl[0] = 0; + else + ieee->seq_ctrl[0]++; + + return skb; +} + +void rtllib_softmac_stop_protocol(struct rtllib_device *ieee, u8 mesh_flag, + u8 shutdown) +{ + rtllib_stop_scan_syncro(ieee); + down(&ieee->wx_sem); + rtllib_stop_protocol(ieee, shutdown); + up(&ieee->wx_sem); +} + + +void rtllib_stop_protocol(struct rtllib_device *ieee, u8 shutdown) +{ + if (!ieee->proto_started) + return; + + if (shutdown) { + ieee->proto_started = 0; + ieee->proto_stoppping = 1; + if (ieee->rtllib_ips_leave != NULL) + ieee->rtllib_ips_leave(ieee->dev); + } + + rtllib_stop_send_beacons(ieee); + del_timer_sync(&ieee->associate_timer); + cancel_delayed_work(&ieee->associate_retry_wq); + cancel_delayed_work(&ieee->start_ibss_wq); + cancel_delayed_work(&ieee->link_change_wq); + rtllib_stop_scan(ieee); + + if (ieee->state <= RTLLIB_ASSOCIATING_AUTHENTICATED) + ieee->state = RTLLIB_NOLINK; + + if (ieee->state == RTLLIB_LINKED) { + if (ieee->iw_mode == IW_MODE_INFRA) + SendDisassociation(ieee, 1, deauth_lv_ss); + rtllib_disassociate(ieee); + } + + if (shutdown) { + RemoveAllTS(ieee); + ieee->proto_stoppping = 0; + } + kfree(ieee->assocreq_ies); + ieee->assocreq_ies = NULL; + ieee->assocreq_ies_len = 0; + kfree(ieee->assocresp_ies); + ieee->assocresp_ies = NULL; + ieee->assocresp_ies_len = 0; +} + +void rtllib_softmac_start_protocol(struct rtllib_device *ieee, u8 mesh_flag) +{ + down(&ieee->wx_sem); + rtllib_start_protocol(ieee); + up(&ieee->wx_sem); +} + +void rtllib_start_protocol(struct rtllib_device *ieee) +{ + short ch = 0; + int i = 0; + + rtllib_update_active_chan_map(ieee); + + if (ieee->proto_started) + return; + + ieee->proto_started = 1; + + if (ieee->current_network.channel == 0) { + do { + ch++; + if (ch > MAX_CHANNEL_NUMBER) + return; /* no channel found */ + } while (!ieee->active_channel_map[ch]); + ieee->current_network.channel = ch; + } + + if (ieee->current_network.beacon_interval == 0) + ieee->current_network.beacon_interval = 100; + + for (i = 0; i < 17; i++) { + ieee->last_rxseq_num[i] = -1; + ieee->last_rxfrag_num[i] = -1; + ieee->last_packet_time[i] = 0; + } + + if (ieee->UpdateBeaconInterruptHandler) + ieee->UpdateBeaconInterruptHandler(ieee->dev, false); + + ieee->wmm_acm = 0; + /* if the user set the MAC of the ad-hoc cell and then + * switch to managed mode, shall we make sure that association + * attempts does not fail just because the user provide the essid + * and the nic is still checking for the AP MAC ?? + */ + if (ieee->iw_mode == IW_MODE_INFRA) { + rtllib_start_bss(ieee); + } else if (ieee->iw_mode == IW_MODE_ADHOC) { + if (ieee->UpdateBeaconInterruptHandler) + ieee->UpdateBeaconInterruptHandler(ieee->dev, true); + + rtllib_start_ibss(ieee); + + } else if (ieee->iw_mode == IW_MODE_MASTER) { + rtllib_start_master_bss(ieee); + } else if (ieee->iw_mode == IW_MODE_MONITOR) { + rtllib_start_monitor_mode(ieee); + } +} + +void rtllib_softmac_init(struct rtllib_device *ieee) +{ + int i; + memset(&ieee->current_network, 0, sizeof(struct rtllib_network)); + + ieee->state = RTLLIB_NOLINK; + for (i = 0; i < 5; i++) + ieee->seq_ctrl[i] = 0; + ieee->pDot11dInfo = kmalloc(sizeof(struct rt_dot11d_info), GFP_ATOMIC); + if (!ieee->pDot11dInfo) + RTLLIB_DEBUG(RTLLIB_DL_ERR, "can't alloc memory for DOT11D\n"); + memset(ieee->pDot11dInfo, 0, sizeof(struct rt_dot11d_info)); + ieee->LinkDetectInfo.SlotIndex = 0; + ieee->LinkDetectInfo.SlotNum = 2; + ieee->LinkDetectInfo.NumRecvBcnInPeriod = 0; + ieee->LinkDetectInfo.NumRecvDataInPeriod = 0; + ieee->LinkDetectInfo.NumTxOkInPeriod = 0; + ieee->LinkDetectInfo.NumRxOkInPeriod = 0; + ieee->LinkDetectInfo.NumRxUnicastOkInPeriod = 0; + ieee->bIsAggregateFrame = false; + ieee->assoc_id = 0; + ieee->queue_stop = 0; + ieee->scanning_continue = 0; + ieee->softmac_features = 0; + ieee->wap_set = 0; + ieee->ssid_set = 0; + ieee->proto_started = 0; + ieee->proto_stoppping = 0; + ieee->basic_rate = RTLLIB_DEFAULT_BASIC_RATE; + ieee->rate = 22; + ieee->ps = RTLLIB_PS_DISABLED; + ieee->sta_sleep = LPS_IS_WAKE; + + ieee->Regdot11HTOperationalRateSet[0] = 0xff; + ieee->Regdot11HTOperationalRateSet[1] = 0xff; + ieee->Regdot11HTOperationalRateSet[4] = 0x01; + + ieee->Regdot11TxHTOperationalRateSet[0] = 0xff; + ieee->Regdot11TxHTOperationalRateSet[1] = 0xff; + ieee->Regdot11TxHTOperationalRateSet[4] = 0x01; + + ieee->FirstIe_InScan = false; + ieee->actscanning = false; + ieee->beinretry = false; + ieee->is_set_key = false; + init_mgmt_queue(ieee); + + ieee->sta_edca_param[0] = 0x0000A403; + ieee->sta_edca_param[1] = 0x0000A427; + ieee->sta_edca_param[2] = 0x005E4342; + ieee->sta_edca_param[3] = 0x002F3262; + ieee->aggregation = true; + ieee->enable_rx_imm_BA = 1; + ieee->tx_pending.txb = NULL; + + _setup_timer(&ieee->associate_timer, + rtllib_associate_abort_cb, + (unsigned long) ieee); + + _setup_timer(&ieee->beacon_timer, + rtllib_send_beacon_cb, + (unsigned long) ieee); + + + ieee->wq = create_workqueue(DRV_NAME); + + INIT_DELAYED_WORK_RSL(&ieee->link_change_wq, + (void *)rtllib_link_change_wq, ieee); + INIT_DELAYED_WORK_RSL(&ieee->start_ibss_wq, + (void *)rtllib_start_ibss_wq, ieee); + INIT_WORK_RSL(&ieee->associate_complete_wq, + (void *)rtllib_associate_complete_wq, ieee); + INIT_DELAYED_WORK_RSL(&ieee->associate_procedure_wq, + (void *)rtllib_associate_procedure_wq, ieee); + INIT_DELAYED_WORK_RSL(&ieee->softmac_scan_wq, + (void *)rtllib_softmac_scan_wq, ieee); + INIT_DELAYED_WORK_RSL(&ieee->softmac_hint11d_wq, + (void *)rtllib_softmac_hint11d_wq, ieee); + INIT_DELAYED_WORK_RSL(&ieee->associate_retry_wq, + (void *)rtllib_associate_retry_wq, ieee); + INIT_WORK_RSL(&ieee->wx_sync_scan_wq, (void *)rtllib_wx_sync_scan_wq, + ieee); + + sema_init(&ieee->wx_sem, 1); + sema_init(&ieee->scan_sem, 1); + sema_init(&ieee->ips_sem, 1); + + spin_lock_init(&ieee->mgmt_tx_lock); + spin_lock_init(&ieee->beacon_lock); + + tasklet_init(&ieee->ps_task, + (void(*)(unsigned long)) rtllib_sta_ps, + (unsigned long)ieee); + +} + +void rtllib_softmac_free(struct rtllib_device *ieee) +{ + down(&ieee->wx_sem); + if (NULL != ieee->pDot11dInfo) { + kfree(ieee->pDot11dInfo); + ieee->pDot11dInfo = NULL; + } + del_timer_sync(&ieee->associate_timer); + + cancel_delayed_work(&ieee->associate_retry_wq); + destroy_workqueue(ieee->wq); + up(&ieee->wx_sem); +} + +/******************************************************** + * Start of WPA code. * + * this is stolen from the ipw2200 driver * + ********************************************************/ + + +static int rtllib_wpa_enable(struct rtllib_device *ieee, int value) +{ + /* This is called when wpa_supplicant loads and closes the driver + * interface. */ + printk(KERN_INFO "%s WPA\n", value ? "enabling" : "disabling"); + ieee->wpa_enabled = value; + memset(ieee->ap_mac_addr, 0, 6); + return 0; +} + + +static void rtllib_wpa_assoc_frame(struct rtllib_device *ieee, char *wpa_ie, + int wpa_ie_len) +{ + /* make sure WPA is enabled */ + rtllib_wpa_enable(ieee, 1); + + rtllib_disassociate(ieee); +} + + +static int rtllib_wpa_mlme(struct rtllib_device *ieee, int command, int reason) +{ + + int ret = 0; + + switch (command) { + case IEEE_MLME_STA_DEAUTH: + break; + + case IEEE_MLME_STA_DISASSOC: + rtllib_disassociate(ieee); + break; + + default: + printk(KERN_INFO "Unknown MLME request: %d\n", command); + ret = -EOPNOTSUPP; + } + + return ret; +} + + +static int rtllib_wpa_set_wpa_ie(struct rtllib_device *ieee, + struct ieee_param *param, int plen) +{ + u8 *buf; + + if (param->u.wpa_ie.len > MAX_WPA_IE_LEN || + (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL)) + return -EINVAL; + + if (param->u.wpa_ie.len) { + buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL); + if (buf == NULL) + return -ENOMEM; + + memcpy(buf, param->u.wpa_ie.data, param->u.wpa_ie.len); + kfree(ieee->wpa_ie); + ieee->wpa_ie = buf; + ieee->wpa_ie_len = param->u.wpa_ie.len; + } else { + kfree(ieee->wpa_ie); + ieee->wpa_ie = NULL; + ieee->wpa_ie_len = 0; + } + + rtllib_wpa_assoc_frame(ieee, ieee->wpa_ie, ieee->wpa_ie_len); + return 0; +} + +#define AUTH_ALG_OPEN_SYSTEM 0x1 +#define AUTH_ALG_SHARED_KEY 0x2 +#define AUTH_ALG_LEAP 0x4 +static int rtllib_wpa_set_auth_algs(struct rtllib_device *ieee, int value) +{ + + struct rtllib_security sec = { + .flags = SEC_AUTH_MODE, + }; + int ret = 0; + + if (value & AUTH_ALG_SHARED_KEY) { + sec.auth_mode = WLAN_AUTH_SHARED_KEY; + ieee->open_wep = 0; + ieee->auth_mode = 1; + } else if (value & AUTH_ALG_OPEN_SYSTEM) { + sec.auth_mode = WLAN_AUTH_OPEN; + ieee->open_wep = 1; + ieee->auth_mode = 0; + } else if (value & AUTH_ALG_LEAP) { + sec.auth_mode = WLAN_AUTH_LEAP >> 6; + ieee->open_wep = 1; + ieee->auth_mode = 2; + } + + + if (ieee->set_security) + ieee->set_security(ieee->dev, &sec); + + return ret; +} + +static int rtllib_wpa_set_param(struct rtllib_device *ieee, u8 name, u32 value) +{ + int ret = 0; + unsigned long flags; + + switch (name) { + case IEEE_PARAM_WPA_ENABLED: + ret = rtllib_wpa_enable(ieee, value); + break; + + case IEEE_PARAM_TKIP_COUNTERMEASURES: + ieee->tkip_countermeasures = value; + break; + + case IEEE_PARAM_DROP_UNENCRYPTED: + { + /* HACK: + * + * wpa_supplicant calls set_wpa_enabled when the driver + * is loaded and unloaded, regardless of if WPA is being + * used. No other calls are made which can be used to + * determine if encryption will be used or not prior to + * association being expected. If encryption is not being + * used, drop_unencrypted is set to false, else true -- we + * can use this to determine if the CAP_PRIVACY_ON bit should + * be set. + */ + struct rtllib_security sec = { + .flags = SEC_ENABLED, + .enabled = value, + }; + ieee->drop_unencrypted = value; + /* We only change SEC_LEVEL for open mode. Others + * are set by ipw_wpa_set_encryption. + */ + if (!value) { + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_0; + } else { + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_1; + } + if (ieee->set_security) + ieee->set_security(ieee->dev, &sec); + break; + } + + case IEEE_PARAM_PRIVACY_INVOKED: + ieee->privacy_invoked = value; + break; + + case IEEE_PARAM_AUTH_ALGS: + ret = rtllib_wpa_set_auth_algs(ieee, value); + break; + + case IEEE_PARAM_IEEE_802_1X: + ieee->ieee802_1x = value; + break; + case IEEE_PARAM_WPAX_SELECT: + spin_lock_irqsave(&ieee->wpax_suitlist_lock, flags); + spin_unlock_irqrestore(&ieee->wpax_suitlist_lock, flags); + break; + + default: + printk(KERN_INFO "Unknown WPA param: %d\n", name); + ret = -EOPNOTSUPP; + } + + return ret; +} + +/* implementation borrowed from hostap driver */ +static int rtllib_wpa_set_encryption(struct rtllib_device *ieee, + struct ieee_param *param, int param_len, + u8 is_mesh) +{ + int ret = 0; + struct rtllib_crypto_ops *ops; + struct rtllib_crypt_data **crypt; + + struct rtllib_security sec = { + .flags = 0, + }; + + param->u.crypt.err = 0; + param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0'; + + if (param_len != + (int) ((char *) param->u.crypt.key - (char *) param) + + param->u.crypt.key_len) { + printk(KERN_INFO "Len mismatch %d, %d\n", param_len, + param->u.crypt.key_len); + return -EINVAL; + } + if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff && + param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff && + param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) { + if (param->u.crypt.idx >= WEP_KEYS) + return -EINVAL; + crypt = &ieee->crypt[param->u.crypt.idx]; + } else { + return -EINVAL; + } + + if (strcmp(param->u.crypt.alg, "none") == 0) { + if (crypt) { + sec.enabled = 0; + sec.level = SEC_LEVEL_0; + sec.flags |= SEC_ENABLED | SEC_LEVEL; + rtllib_crypt_delayed_deinit(ieee, crypt); + } + goto done; + } + sec.enabled = 1; + sec.flags |= SEC_ENABLED; + + /* IPW HW cannot build TKIP MIC, host decryption still needed. */ + if (!(ieee->host_encrypt || ieee->host_decrypt) && + strcmp(param->u.crypt.alg, "TKIP")) + goto skip_host_crypt; + + ops = rtllib_get_crypto_ops(param->u.crypt.alg); + if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) { + request_module("rtllib_crypt_wep"); + ops = rtllib_get_crypto_ops(param->u.crypt.alg); + } else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) { + request_module("rtllib_crypt_tkip"); + ops = rtllib_get_crypto_ops(param->u.crypt.alg); + } else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) { + request_module("rtllib_crypt_ccmp"); + ops = rtllib_get_crypto_ops(param->u.crypt.alg); + } + if (ops == NULL) { + printk(KERN_INFO "unknown crypto alg '%s'\n", + param->u.crypt.alg); + param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG; + ret = -EINVAL; + goto done; + } + if (*crypt == NULL || (*crypt)->ops != ops) { + struct rtllib_crypt_data *new_crypt; + + rtllib_crypt_delayed_deinit(ieee, crypt); + + new_crypt = (struct rtllib_crypt_data *) + kmalloc(sizeof(*new_crypt), GFP_KERNEL); + if (new_crypt == NULL) { + ret = -ENOMEM; + goto done; + } + memset(new_crypt, 0, sizeof(struct rtllib_crypt_data)); + new_crypt->ops = ops; + if (new_crypt->ops) + new_crypt->priv = + new_crypt->ops->init(param->u.crypt.idx); + + if (new_crypt->priv == NULL) { + kfree(new_crypt); + param->u.crypt.err = IEEE_CRYPT_ERR_CRYPT_INIT_FAILED; + ret = -EINVAL; + goto done; + } + + *crypt = new_crypt; + } + + if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key && + (*crypt)->ops->set_key(param->u.crypt.key, + param->u.crypt.key_len, param->u.crypt.seq, + (*crypt)->priv) < 0) { + printk(KERN_INFO "key setting failed\n"); + param->u.crypt.err = IEEE_CRYPT_ERR_KEY_SET_FAILED; + ret = -EINVAL; + goto done; + } + + skip_host_crypt: + if (param->u.crypt.set_tx) { + ieee->tx_keyidx = param->u.crypt.idx; + sec.active_key = param->u.crypt.idx; + sec.flags |= SEC_ACTIVE_KEY; + } else + sec.flags &= ~SEC_ACTIVE_KEY; + + if (param->u.crypt.alg != NULL) { + memcpy(sec.keys[param->u.crypt.idx], + param->u.crypt.key, + param->u.crypt.key_len); + sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len; + sec.flags |= (1 << param->u.crypt.idx); + + if (strcmp(param->u.crypt.alg, "WEP") == 0) { + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_1; + } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) { + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_2; + } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) { + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_3; + } + } + done: + if (ieee->set_security) + ieee->set_security(ieee->dev, &sec); + + /* Do not reset port if card is in Managed mode since resetting will + * generate new IEEE 802.11 authentication which may end up in looping + * with IEEE 802.1X. If your hardware requires a reset after WEP + * configuration (for example... Prism2), implement the reset_port in + * the callbacks structures used to initialize the 802.11 stack. */ + if (ieee->reset_on_keychange && + ieee->iw_mode != IW_MODE_INFRA && + ieee->reset_port && + ieee->reset_port(ieee->dev)) { + printk(KERN_INFO "reset_port failed\n"); + param->u.crypt.err = IEEE_CRYPT_ERR_CARD_CONF_FAILED; + return -EINVAL; + } + + return ret; +} + +inline struct sk_buff *rtllib_disauth_skb(struct rtllib_network *beacon, + struct rtllib_device *ieee, u16 asRsn) +{ + struct sk_buff *skb; + struct rtllib_disauth *disauth; + int len = sizeof(struct rtllib_disauth) + ieee->tx_headroom; + + skb = dev_alloc_skb(len); + if (!skb) + return NULL; + + skb_reserve(skb, ieee->tx_headroom); + + disauth = (struct rtllib_disauth *) skb_put(skb, + sizeof(struct rtllib_disauth)); + disauth->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_DEAUTH); + disauth->header.duration_id = 0; + + memcpy(disauth->header.addr1, beacon->bssid, ETH_ALEN); + memcpy(disauth->header.addr2, ieee->dev->dev_addr, ETH_ALEN); + memcpy(disauth->header.addr3, beacon->bssid, ETH_ALEN); + + disauth->reason = cpu_to_le16(asRsn); + return skb; +} + +inline struct sk_buff *rtllib_disassociate_skb(struct rtllib_network *beacon, + struct rtllib_device *ieee, u16 asRsn) +{ + struct sk_buff *skb; + struct rtllib_disassoc *disass; + int len = sizeof(struct rtllib_disassoc) + ieee->tx_headroom; + skb = dev_alloc_skb(len); + + if (!skb) + return NULL; + + skb_reserve(skb, ieee->tx_headroom); + + disass = (struct rtllib_disassoc *) skb_put(skb, + sizeof(struct rtllib_disassoc)); + disass->header.frame_ctl = cpu_to_le16(RTLLIB_STYPE_DISASSOC); + disass->header.duration_id = 0; + + memcpy(disass->header.addr1, beacon->bssid, ETH_ALEN); + memcpy(disass->header.addr2, ieee->dev->dev_addr, ETH_ALEN); + memcpy(disass->header.addr3, beacon->bssid, ETH_ALEN); + + disass->reason = cpu_to_le16(asRsn); + return skb; +} + +void SendDisassociation(struct rtllib_device *ieee, bool deauth, u16 asRsn) +{ + struct rtllib_network *beacon = &ieee->current_network; + struct sk_buff *skb; + + if (deauth) + skb = rtllib_disauth_skb(beacon, ieee, asRsn); + else + skb = rtllib_disassociate_skb(beacon, ieee, asRsn); + + if (skb) + softmac_mgmt_xmit(skb, ieee); +} + +u8 rtllib_ap_sec_type(struct rtllib_device *ieee) +{ + static u8 ccmp_ie[4] = {0x00, 0x50, 0xf2, 0x04}; + static u8 ccmp_rsn_ie[4] = {0x00, 0x0f, 0xac, 0x04}; + int wpa_ie_len = ieee->wpa_ie_len; + struct rtllib_crypt_data *crypt; + int encrypt; + + crypt = ieee->crypt[ieee->tx_keyidx]; + encrypt = (ieee->current_network.capability & WLAN_CAPABILITY_PRIVACY) + || (ieee->host_encrypt && crypt && crypt->ops && + (0 == strcmp(crypt->ops->name, "WEP"))); + + /* simply judge */ + if (encrypt && (wpa_ie_len == 0)) { + return SEC_ALG_WEP; + } else if ((wpa_ie_len != 0)) { + if (((ieee->wpa_ie[0] == 0xdd) && + (!memcmp(&(ieee->wpa_ie[14]), ccmp_ie, 4))) || + ((ieee->wpa_ie[0] == 0x30) && + (!memcmp(&ieee->wpa_ie[10], ccmp_rsn_ie, 4)))) + return SEC_ALG_CCMP; + else + return SEC_ALG_TKIP; + } else { + return SEC_ALG_NONE; + } +} + +int rtllib_wpa_supplicant_ioctl(struct rtllib_device *ieee, struct iw_point *p, + u8 is_mesh) +{ + struct ieee_param *param; + int ret = 0; + + down(&ieee->wx_sem); + + if (p->length < sizeof(struct ieee_param) || !p->pointer) { + ret = -EINVAL; + goto out; + } + + param = kmalloc(p->length, GFP_KERNEL); + if (param == NULL) { + ret = -ENOMEM; + goto out; + } + if (copy_from_user(param, p->pointer, p->length)) { + kfree(param); + ret = -EFAULT; + goto out; + } + + switch (param->cmd) { + case IEEE_CMD_SET_WPA_PARAM: + ret = rtllib_wpa_set_param(ieee, param->u.wpa_param.name, + param->u.wpa_param.value); + break; + + case IEEE_CMD_SET_WPA_IE: + ret = rtllib_wpa_set_wpa_ie(ieee, param, p->length); + break; + + case IEEE_CMD_SET_ENCRYPTION: + ret = rtllib_wpa_set_encryption(ieee, param, p->length, 0); + break; + + case IEEE_CMD_MLME: + ret = rtllib_wpa_mlme(ieee, param->u.mlme.command, + param->u.mlme.reason_code); + break; + + default: + printk(KERN_INFO "Unknown WPA supplicant request: %d\n", + param->cmd); + ret = -EOPNOTSUPP; + break; + } + + if (ret == 0 && copy_to_user(p->pointer, param, p->length)) + ret = -EFAULT; + + kfree(param); +out: + up(&ieee->wx_sem); + + return ret; +} + +void rtllib_MgntDisconnectIBSS(struct rtllib_device *rtllib) +{ + u8 OpMode; + u8 i; + bool bFilterOutNonAssociatedBSSID = false; + + rtllib->state = RTLLIB_NOLINK; + + for (i = 0; i < 6; i++) + rtllib->current_network.bssid[i] = 0x55; + + rtllib->OpMode = RT_OP_MODE_NO_LINK; + rtllib->SetHwRegHandler(rtllib->dev, HW_VAR_BSSID, + rtllib->current_network.bssid); + OpMode = RT_OP_MODE_NO_LINK; + rtllib->SetHwRegHandler(rtllib->dev, HW_VAR_MEDIA_STATUS, &OpMode); + rtllib_stop_send_beacons(rtllib); + + bFilterOutNonAssociatedBSSID = false; + rtllib->SetHwRegHandler(rtllib->dev, HW_VAR_CECHK_BSSID, + (u8 *)(&bFilterOutNonAssociatedBSSID)); + notify_wx_assoc_event(rtllib); + +} + +void rtllib_MlmeDisassociateRequest(struct rtllib_device *rtllib, u8 *asSta, + u8 asRsn) +{ + u8 i; + u8 OpMode; + + RemovePeerTS(rtllib, asSta); + + + if (memcpy(rtllib->current_network.bssid, asSta, 6) == NULL) { + rtllib->state = RTLLIB_NOLINK; + + for (i = 0; i < 6; i++) + rtllib->current_network.bssid[i] = 0x22; + OpMode = RT_OP_MODE_NO_LINK; + rtllib->OpMode = RT_OP_MODE_NO_LINK; + rtllib->SetHwRegHandler(rtllib->dev, HW_VAR_MEDIA_STATUS, + (u8 *)(&OpMode)); + rtllib_disassociate(rtllib); + + rtllib->SetHwRegHandler(rtllib->dev, HW_VAR_BSSID, + rtllib->current_network.bssid); + + } + +} + +void +rtllib_MgntDisconnectAP( + struct rtllib_device *rtllib, + u8 asRsn +) +{ + bool bFilterOutNonAssociatedBSSID = false; + + bFilterOutNonAssociatedBSSID = false; + rtllib->SetHwRegHandler(rtllib->dev, HW_VAR_CECHK_BSSID, + (u8 *)(&bFilterOutNonAssociatedBSSID)); + rtllib_MlmeDisassociateRequest(rtllib, rtllib->current_network.bssid, + asRsn); + + rtllib->state = RTLLIB_NOLINK; +} + +bool rtllib_MgntDisconnect(struct rtllib_device *rtllib, u8 asRsn) +{ + if (rtllib->ps != RTLLIB_PS_DISABLED) + rtllib->sta_wake_up(rtllib->dev); + + if (rtllib->state == RTLLIB_LINKED) { + if (rtllib->iw_mode == IW_MODE_ADHOC) + rtllib_MgntDisconnectIBSS(rtllib); + if (rtllib->iw_mode == IW_MODE_INFRA) + rtllib_MgntDisconnectAP(rtllib, asRsn); + + } + + return true; +} + +void notify_wx_assoc_event(struct rtllib_device *ieee) +{ + union iwreq_data wrqu; + + if (ieee->cannot_notify) + return; + + wrqu.ap_addr.sa_family = ARPHRD_ETHER; + if (ieee->state == RTLLIB_LINKED) + memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid, + ETH_ALEN); + else { + + printk(KERN_INFO "%s(): Tell user space disconnected\n", + __func__); + memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN); + } + wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL); +} diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8192e/rtllib_softmac_wx.c index d8a068e..22988fb 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_softmac_wx.c +++ b/drivers/staging/rtl8192e/rtllib_softmac_wx.c @@ -14,13 +14,12 @@ */ -#include "ieee80211.h" -#ifdef ENABLE_DOT11D +#include "rtllib.h" +#include "rtl_core.h" #include "dot11d.h" -#endif /* FIXME: add A freqs */ -const long ieee80211_wlan_frequencies[] = { +const long rtllib_wlan_frequencies[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442, 2447, 2452, 2457, 2462, 2467, @@ -28,16 +27,16 @@ const long ieee80211_wlan_frequencies[] = { }; -int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info *a, +int rtllib_wx_set_freq(struct rtllib_device *ieee, struct iw_request_info *a, union iwreq_data *wrqu, char *b) { int ret; - struct iw_freq *fwrq = & wrqu->freq; + struct iw_freq *fwrq = &wrqu->freq; down(&ieee->wx_sem); - if(ieee->iw_mode == IW_MODE_INFRA){ - ret = -EOPNOTSUPP; + if (ieee->iw_mode == IW_MODE_INFRA) { + ret = 0; goto out; } @@ -48,7 +47,7 @@ int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info int f = fwrq->m / 100000; int c = 0; - while ((c < 14) && (f != ieee80211_wlan_frequencies[c])) + while ((c < 14) && (f != rtllib_wlan_frequencies[c])) c++; /* hack to fall through */ @@ -57,26 +56,24 @@ int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info } } - if (fwrq->e > 0 || fwrq->m > 14 || fwrq->m < 1 ){ + if (fwrq->e > 0 || fwrq->m > 14 || fwrq->m < 1) { ret = -EOPNOTSUPP; goto out; - }else { /* Set the channel */ + } else { /* Set the channel */ -#ifdef ENABLE_DOT11D - if (!(GET_DOT11D_INFO(ieee)->channel_map)[fwrq->m]) { + if (ieee->active_channel_map[fwrq->m] != 1) { ret = -EINVAL; goto out; } -#endif ieee->current_network.channel = fwrq->m; - ieee->set_chan(ieee, ieee->current_network.channel); - - if(ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER) - if(ieee->state == IEEE80211_LINKED){ + ieee->set_chan(ieee->dev, ieee->current_network.channel); - ieee80211_stop_send_beacons(ieee); - ieee80211_start_send_beacons(ieee); + if (ieee->iw_mode == IW_MODE_ADHOC || + ieee->iw_mode == IW_MODE_MASTER) + if (ieee->state == RTLLIB_LINKED) { + rtllib_stop_send_beacons(ieee); + rtllib_start_send_beacons(ieee); } } @@ -87,26 +84,26 @@ out: } -int ieee80211_wx_get_freq(struct ieee80211_device *ieee, +int rtllib_wx_get_freq(struct rtllib_device *ieee, struct iw_request_info *a, union iwreq_data *wrqu, char *b) { - struct iw_freq *fwrq = & wrqu->freq; + struct iw_freq *fwrq = &wrqu->freq; if (ieee->current_network.channel == 0) return -1; - //NM 0.7.0 will not accept channel any more. - fwrq->m = ieee80211_wlan_frequencies[ieee->current_network.channel-1] * 100000; + fwrq->m = rtllib_wlan_frequencies[ieee->current_network.channel-1] * + 100000; fwrq->e = 1; - return 0; } -int ieee80211_wx_get_wap(struct ieee80211_device *ieee, +int rtllib_wx_get_wap(struct rtllib_device *ieee, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { unsigned long flags; + wrqu->ap_addr.sa_family = ARPHRD_ETHER; if (ieee->iw_mode == IW_MODE_MONITOR) @@ -115,8 +112,8 @@ int ieee80211_wx_get_wap(struct ieee80211_device *ieee, /* We want avoid to give to the user inconsistent infos*/ spin_lock_irqsave(&ieee->lock, flags); - if (ieee->state != IEEE80211_LINKED && - ieee->state != IEEE80211_LINKED_SCANNING && + if (ieee->state != RTLLIB_LINKED && + ieee->state != RTLLIB_LINKED_SCANNING && ieee->wap_set == 0) memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN); @@ -130,56 +127,68 @@ int ieee80211_wx_get_wap(struct ieee80211_device *ieee, } -int ieee80211_wx_set_wap(struct ieee80211_device *ieee, +int rtllib_wx_set_wap(struct rtllib_device *ieee, struct iw_request_info *info, union iwreq_data *awrq, char *extra) { int ret = 0; - u8 zero[] = {0,0,0,0,0,0}; + u8 zero[] = {0, 0, 0, 0, 0, 0}; unsigned long flags; - short ifup = ieee->proto_started;//dev->flags & IFF_UP; + short ifup = ieee->proto_started; struct sockaddr *temp = (struct sockaddr *)awrq; - ieee->sync_scan_hurryup = 1; + rtllib_stop_scan_syncro(ieee); down(&ieee->wx_sem); /* use ifconfig hw ether */ - if (ieee->iw_mode == IW_MODE_MASTER){ + if (ieee->iw_mode == IW_MODE_MASTER) { ret = -1; goto out; } - if (temp->sa_family != ARPHRD_ETHER){ + if (temp->sa_family != ARPHRD_ETHER) { ret = -EINVAL; goto out; } + if (memcmp(temp->sa_data, zero, ETH_ALEN) == 0) { + spin_lock_irqsave(&ieee->lock, flags); + memcpy(ieee->current_network.bssid, temp->sa_data, ETH_ALEN); + ieee->wap_set = 0; + spin_unlock_irqrestore(&ieee->lock, flags); + ret = -1; + goto out; + } + + if (ifup) - ieee80211_stop_protocol(ieee,true); + rtllib_stop_protocol(ieee, true); /* just to avoid to give inconsistent infos in the * get wx method. not really needed otherwise */ spin_lock_irqsave(&ieee->lock, flags); + ieee->cannot_notify = false; memcpy(ieee->current_network.bssid, temp->sa_data, ETH_ALEN); - ieee->wap_set = memcmp(temp->sa_data, zero,ETH_ALEN)!=0; + ieee->wap_set = (memcmp(temp->sa_data, zero, ETH_ALEN) != 0); spin_unlock_irqrestore(&ieee->lock, flags); if (ifup) - ieee80211_start_protocol(ieee); + rtllib_start_protocol(ieee); out: up(&ieee->wx_sem); return ret; } - int ieee80211_wx_get_essid(struct ieee80211_device *ieee, struct iw_request_info *a,union iwreq_data *wrqu,char *b) +int rtllib_wx_get_essid(struct rtllib_device *ieee, struct iw_request_info *a, + union iwreq_data *wrqu, char *b) { - int len,ret = 0; + int len, ret = 0; unsigned long flags; if (ieee->iw_mode == IW_MODE_MONITOR) @@ -189,20 +198,20 @@ out: spin_lock_irqsave(&ieee->lock, flags); if (ieee->current_network.ssid[0] == '\0' || - ieee->current_network.ssid_len == 0){ + ieee->current_network.ssid_len == 0) { ret = -1; goto out; } - if (ieee->state != IEEE80211_LINKED && - ieee->state != IEEE80211_LINKED_SCANNING && - ieee->ssid_set == 0){ + if (ieee->state != RTLLIB_LINKED && + ieee->state != RTLLIB_LINKED_SCANNING && + ieee->ssid_set == 0) { ret = -1; goto out; } len = ieee->current_network.ssid_len; wrqu->essid.length = len; - strncpy(b,ieee->current_network.ssid,len); + strncpy(b, ieee->current_network.ssid, len); wrqu->essid.flags = 1; out: @@ -212,7 +221,7 @@ out: } -int ieee80211_wx_set_rate(struct ieee80211_device *ieee, +int rtllib_wx_set_rate(struct rtllib_device *ieee, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { @@ -220,33 +229,29 @@ int ieee80211_wx_set_rate(struct ieee80211_device *ieee, u32 target_rate = wrqu->bitrate.value; ieee->rate = target_rate/100000; - //FIXME: we might want to limit rate also in management protocols. return 0; } - - -int ieee80211_wx_get_rate(struct ieee80211_device *ieee, +int rtllib_wx_get_rate(struct rtllib_device *ieee, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { - u32 tmp_rate; - tmp_rate = TxCountToDataRate(ieee, ieee->softmac_stats.CurrentShowTxate); - + u32 tmp_rate = 0; + tmp_rate = TxCountToDataRate(ieee, + ieee->softmac_stats.CurrentShowTxate); wrqu->bitrate.value = tmp_rate * 500000; return 0; } -int ieee80211_wx_set_rts(struct ieee80211_device *ieee, +int rtllib_wx_set_rts(struct rtllib_device *ieee, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { if (wrqu->rts.disabled || !wrqu->rts.fixed) ieee->rts = DEFAULT_RTS_THRESHOLD; - else - { + else { if (wrqu->rts.value < MIN_RTS_THRESHOLD || wrqu->rts.value > MAX_RTS_THRESHOLD) return -EINVAL; @@ -255,7 +260,7 @@ int ieee80211_wx_set_rts(struct ieee80211_device *ieee, return 0; } -int ieee80211_wx_get_rts(struct ieee80211_device *ieee, +int rtllib_wx_get_rts(struct rtllib_device *ieee, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { @@ -264,126 +269,157 @@ int ieee80211_wx_get_rts(struct ieee80211_device *ieee, wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD); return 0; } -int ieee80211_wx_set_mode(struct ieee80211_device *ieee, struct iw_request_info *a, + +int rtllib_wx_set_mode(struct rtllib_device *ieee, struct iw_request_info *a, union iwreq_data *wrqu, char *b) { + int set_mode_status = 0; - ieee->sync_scan_hurryup = 1; - + rtllib_stop_scan_syncro(ieee); down(&ieee->wx_sem); + switch (wrqu->mode) { + case IW_MODE_MONITOR: + case IW_MODE_ADHOC: + case IW_MODE_INFRA: + break; + case IW_MODE_AUTO: + wrqu->mode = IW_MODE_INFRA; + break; + default: + set_mode_status = -EINVAL; + goto out; + } if (wrqu->mode == ieee->iw_mode) goto out; - if (wrqu->mode == IW_MODE_MONITOR){ - + if (wrqu->mode == IW_MODE_MONITOR) { ieee->dev->type = ARPHRD_IEEE80211; - }else{ + rtllib_EnableNetMonitorMode(ieee->dev, false); + } else { ieee->dev->type = ARPHRD_ETHER; + if (ieee->iw_mode == IW_MODE_MONITOR) + rtllib_DisableNetMonitorMode(ieee->dev, false); } - if (!ieee->proto_started){ + if (!ieee->proto_started) { ieee->iw_mode = wrqu->mode; - }else{ - ieee80211_stop_protocol(ieee,true); + } else { + rtllib_stop_protocol(ieee, true); ieee->iw_mode = wrqu->mode; - ieee80211_start_protocol(ieee); + rtllib_start_protocol(ieee); } out: up(&ieee->wx_sem); - return 0; + return set_mode_status; } -void ieee80211_wx_sync_scan_wq(struct work_struct *work) +void rtllib_wx_sync_scan_wq(void *data) { - struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, wx_sync_scan_wq); + struct rtllib_device *ieee = container_of_work_rsl(data, + struct rtllib_device, wx_sync_scan_wq); short chan; - HT_EXTCHNL_OFFSET chan_offset=0; - HT_CHANNEL_WIDTH bandwidth=0; + enum ht_extchnl_offset chan_offset = 0; + enum ht_channel_width bandwidth = 0; int b40M = 0; - static int count = 0; - chan = ieee->current_network.channel; + static int count; -#ifdef ENABLE_LPS - if (ieee->LeisurePSLeave) { - ieee->LeisurePSLeave(ieee); + if (!(ieee->softmac_features & IEEE_SOFTMAC_SCAN)) { + rtllib_start_scan_syncro(ieee, 0); + goto out; } - /* notify AP to be in PS mode */ - ieee80211_sta_ps_send_null_frame(ieee, 1); - ieee80211_sta_ps_send_null_frame(ieee, 1); -#endif + chan = ieee->current_network.channel; - if (ieee->data_hard_stop) - ieee->data_hard_stop(ieee); + if (ieee->LeisurePSLeave) + ieee->LeisurePSLeave(ieee->dev); + /* notify AP to be in PS mode */ + rtllib_sta_ps_send_null_frame(ieee, 1); + rtllib_sta_ps_send_null_frame(ieee, 1); - ieee80211_stop_send_beacons(ieee); + rtllib_stop_all_queues(ieee); - ieee->state = IEEE80211_LINKED_SCANNING; - ieee->link_change(ieee); - ieee->InitialGainHandler(ieee, IG_Backup); - if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT && ieee->pHTInfo->bCurBW40MHz) { + if (ieee->data_hard_stop) + ieee->data_hard_stop(ieee->dev); + rtllib_stop_send_beacons(ieee); + ieee->state = RTLLIB_LINKED_SCANNING; + ieee->link_change(ieee->dev); + /* wait for ps packet to be kicked out successfully */ + msleep(50); + + if (ieee->ScanOperationBackupHandler) + ieee->ScanOperationBackupHandler(ieee->dev, SCAN_OPT_BACKUP); + + if (ieee->pHTInfo->bCurrentHTSupport && ieee->pHTInfo->bEnableHT && + ieee->pHTInfo->bCurBW40MHz) { b40M = 1; chan_offset = ieee->pHTInfo->CurSTAExtChnlOffset; - bandwidth = (HT_CHANNEL_WIDTH)ieee->pHTInfo->bCurBW40MHz; - printk("Scan in 40M, force to 20M first:%d, %d\n", chan_offset, bandwidth); - ieee->SetBWModeHandler(ieee, HT_CHANNEL_WIDTH_20, HT_EXTCHNL_OFFSET_NO_EXT); - } - ieee80211_start_scan_syncro(ieee); + bandwidth = (enum ht_channel_width)ieee->pHTInfo->bCurBW40MHz; + RT_TRACE(COMP_DBG, "Scan in 40M, force to 20M first:%d, %d\n", + chan_offset, bandwidth); + ieee->SetBWModeHandler(ieee->dev, HT_CHANNEL_WIDTH_20, + HT_EXTCHNL_OFFSET_NO_EXT); + } + + rtllib_start_scan_syncro(ieee, 0); + if (b40M) { - printk("Scan in 20M, back to 40M\n"); + RT_TRACE(COMP_DBG, "Scan in 20M, back to 40M\n"); if (chan_offset == HT_EXTCHNL_OFFSET_UPPER) - ieee->set_chan(ieee, chan + 2); + ieee->set_chan(ieee->dev, chan + 2); else if (chan_offset == HT_EXTCHNL_OFFSET_LOWER) - ieee->set_chan(ieee, chan - 2); + ieee->set_chan(ieee->dev, chan - 2); else - ieee->set_chan(ieee, chan); - ieee->SetBWModeHandler(ieee, bandwidth, chan_offset); + ieee->set_chan(ieee->dev, chan); + ieee->SetBWModeHandler(ieee->dev, bandwidth, chan_offset); } else { - ieee->set_chan(ieee, chan); + ieee->set_chan(ieee->dev, chan); } - ieee->InitialGainHandler(ieee, IG_Restore); - ieee->state = IEEE80211_LINKED; - ieee->link_change(ieee); + if (ieee->ScanOperationBackupHandler) + ieee->ScanOperationBackupHandler(ieee->dev, SCAN_OPT_RESTORE); + + ieee->state = RTLLIB_LINKED; + ieee->link_change(ieee->dev); -#ifdef ENABLE_LPS /* Notify AP that I wake up again */ - ieee80211_sta_ps_send_null_frame(ieee, 0); -#endif + rtllib_sta_ps_send_null_frame(ieee, 0); - // To prevent the immediately calling watch_dog after scan. - if(ieee->LinkDetectInfo.NumRecvBcnInPeriod==0||ieee->LinkDetectInfo.NumRecvDataInPeriod==0 ) - { + if (ieee->LinkDetectInfo.NumRecvBcnInPeriod == 0 || + ieee->LinkDetectInfo.NumRecvDataInPeriod == 0) { ieee->LinkDetectInfo.NumRecvBcnInPeriod = 1; - ieee->LinkDetectInfo.NumRecvDataInPeriod= 1; + ieee->LinkDetectInfo.NumRecvDataInPeriod = 1; } + if (ieee->data_hard_resume) - ieee->data_hard_resume(ieee); + ieee->data_hard_resume(ieee->dev); - if(ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER) - ieee80211_start_send_beacons(ieee); + if (ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER) + rtllib_start_send_beacons(ieee); + + rtllib_wake_all_queues(ieee); count = 0; +out: up(&ieee->wx_sem); } -int ieee80211_wx_set_scan(struct ieee80211_device *ieee, struct iw_request_info *a, +int rtllib_wx_set_scan(struct rtllib_device *ieee, struct iw_request_info *a, union iwreq_data *wrqu, char *b) { int ret = 0; down(&ieee->wx_sem); - if (ieee->iw_mode == IW_MODE_MONITOR || !(ieee->proto_started)){ + if (ieee->iw_mode == IW_MODE_MONITOR || !(ieee->proto_started)) { ret = -1; goto out; } - if ( ieee->state == IEEE80211_LINKED){ - queue_work(ieee->wq, &ieee->wx_sync_scan_wq); + if (ieee->state == RTLLIB_LINKED) { + queue_work_rsl(ieee->wq, &ieee->wx_sync_scan_wq); /* intentionally forget to up sem */ return 0; } @@ -393,34 +429,43 @@ out: return ret; } -int ieee80211_wx_set_essid(struct ieee80211_device *ieee, - struct iw_request_info *a, - union iwreq_data *wrqu, char *extra) +int rtllib_wx_set_essid(struct rtllib_device *ieee, + struct iw_request_info *a, + union iwreq_data *wrqu, char *extra) { - int ret=0,len; + int ret = 0, len, i; short proto_started; unsigned long flags; - ieee->sync_scan_hurryup = 1; + rtllib_stop_scan_syncro(ieee); down(&ieee->wx_sem); proto_started = ieee->proto_started; - if (wrqu->essid.length > IW_ESSID_MAX_SIZE){ - ret= -E2BIG; + len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ? wrqu->essid.length : + IW_ESSID_MAX_SIZE; + + if (len > IW_ESSID_MAX_SIZE) { + ret = -E2BIG; goto out; } - if (ieee->iw_mode == IW_MODE_MONITOR){ - ret= -1; + if (ieee->iw_mode == IW_MODE_MONITOR) { + ret = -1; goto out; } - if(proto_started){ - ieee80211_stop_protocol(ieee,true); + for (i = 0; i < len; i++) { + if (extra[i] < 0) { + ret = -1; + goto out; + } } + if (proto_started) + rtllib_stop_protocol(ieee, true); + /* this is just to be sure that the GET wx callback * has consisten infos. not needed otherwise @@ -428,13 +473,11 @@ int ieee80211_wx_set_essid(struct ieee80211_device *ieee, spin_lock_irqsave(&ieee->lock, flags); if (wrqu->essid.flags && wrqu->essid.length) { - //first flush current network.ssid - len = ((wrqu->essid.length-1) < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length-1) : IW_ESSID_MAX_SIZE; - strncpy(ieee->current_network.ssid, extra, len+1); - ieee->current_network.ssid_len = len+1; + strncpy(ieee->current_network.ssid, extra, len); + ieee->current_network.ssid_len = len; + ieee->cannot_notify = false; ieee->ssid_set = 1; - } - else{ + } else { ieee->ssid_set = 0; ieee->current_network.ssid[0] = '\0'; ieee->current_network.ssid_len = 0; @@ -442,23 +485,22 @@ int ieee80211_wx_set_essid(struct ieee80211_device *ieee, spin_unlock_irqrestore(&ieee->lock, flags); if (proto_started) - ieee80211_start_protocol(ieee); + rtllib_start_protocol(ieee); out: up(&ieee->wx_sem); return ret; } - int ieee80211_wx_get_mode(struct ieee80211_device *ieee, struct iw_request_info *a, - union iwreq_data *wrqu, char *b) +int rtllib_wx_get_mode(struct rtllib_device *ieee, struct iw_request_info *a, + union iwreq_data *wrqu, char *b) { - wrqu->mode = ieee->iw_mode; return 0; } - int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee, - struct iw_request_info *info, - union iwreq_data *wrqu, char *extra) +int rtllib_wx_set_rawtx(struct rtllib_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) { int *parms = (int *)extra; @@ -467,7 +509,7 @@ out: down(&ieee->wx_sem); - if(enable) + if (enable) ieee->raw_tx = 1; else ieee->raw_tx = 0; @@ -475,16 +517,15 @@ out: printk(KERN_INFO"raw TX is %s\n", ieee->raw_tx ? "enabled" : "disabled"); - if(ieee->iw_mode == IW_MODE_MONITOR) - { - if(prev == 0 && ieee->raw_tx){ + if (ieee->iw_mode == IW_MODE_MONITOR) { + if (prev == 0 && ieee->raw_tx) { if (ieee->data_hard_resume) - ieee->data_hard_resume(ieee); + ieee->data_hard_resume(ieee->dev); netif_carrier_on(ieee->dev); } - if(prev && ieee->raw_tx == 1) + if (prev && ieee->raw_tx == 1) netif_carrier_off(ieee->dev); } @@ -493,14 +534,15 @@ out: return 0; } -int ieee80211_wx_get_name(struct ieee80211_device *ieee, +int rtllib_wx_get_name(struct rtllib_device *ieee, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { strcpy(wrqu->name, "802.11"); - if(ieee->modulation & IEEE80211_CCK_MODULATION) + + if (ieee->modulation & RTLLIB_CCK_MODULATION) strcat(wrqu->name, "b"); - if(ieee->modulation & IEEE80211_OFDM_MODULATION) + if (ieee->modulation & RTLLIB_OFDM_MODULATION) strcat(wrqu->name, "g"); if (ieee->mode & (IEEE_N_24G | IEEE_N_5G)) strcat(wrqu->name, "n"); @@ -509,42 +551,45 @@ int ieee80211_wx_get_name(struct ieee80211_device *ieee, /* this is mostly stolen from hostap */ -int ieee80211_wx_set_power(struct ieee80211_device *ieee, +int rtllib_wx_set_power(struct rtllib_device *ieee, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { int ret = 0; - if( - (!ieee->sta_wake_up) || - (!ieee->enter_sleep_state) || - (!ieee->ps_is_queue_empty)){ - + if ((!ieee->sta_wake_up) || + (!ieee->enter_sleep_state) || + (!ieee->ps_is_queue_empty)) { + RTLLIB_DEBUG(RTLLIB_DL_ERR, "%s(): PS mode is tryied to be use " + "but driver missed a callback\n\n", __func__); return -1; } down(&ieee->wx_sem); - if (wrqu->power.disabled){ - ieee->ps = IEEE80211_PS_DISABLED; + if (wrqu->power.disabled) { + RT_TRACE(COMP_DBG, "===>%s(): power disable\n", __func__); + ieee->ps = RTLLIB_PS_DISABLED; goto exit; } if (wrqu->power.flags & IW_POWER_TIMEOUT) { ieee->ps_timeout = wrqu->power.value / 1000; + RT_TRACE(COMP_DBG, "===>%s():ps_timeout is %d\n", __func__, + ieee->ps_timeout); } - if (wrqu->power.flags & IW_POWER_PERIOD) { + if (wrqu->power.flags & IW_POWER_PERIOD) ieee->ps_period = wrqu->power.value / 1000; - } + switch (wrqu->power.flags & IW_POWER_MODE) { case IW_POWER_UNICAST_R: - ieee->ps = IEEE80211_PS_UNICAST; + ieee->ps = RTLLIB_PS_UNICAST; break; case IW_POWER_MULTICAST_R: - ieee->ps = IEEE80211_PS_MBCAST; + ieee->ps = RTLLIB_PS_MBCAST; break; case IW_POWER_ALL_R: - ieee->ps = IEEE80211_PS_UNICAST | IEEE80211_PS_MBCAST; + ieee->ps = RTLLIB_PS_UNICAST | RTLLIB_PS_MBCAST; break; case IW_POWER_ON: @@ -562,15 +607,15 @@ exit: } /* this is stolen from hostap */ -int ieee80211_wx_get_power(struct ieee80211_device *ieee, +int rtllib_wx_get_power(struct rtllib_device *ieee, struct iw_request_info *info, union iwreq_data *wrqu, char *extra) { - int ret =0; + int ret = 0; down(&ieee->wx_sem); - if(ieee->ps == IEEE80211_PS_DISABLED){ + if (ieee->ps == RTLLIB_PS_DISABLED) { wrqu->power.disabled = 1; goto exit; } @@ -585,9 +630,10 @@ int ieee80211_wx_get_power(struct ieee80211_device *ieee, wrqu->power.value = ieee->ps_period * 1000; } - if ((ieee->ps & (IEEE80211_PS_MBCAST | IEEE80211_PS_UNICAST)) == (IEEE80211_PS_MBCAST | IEEE80211_PS_UNICAST)) - wrqu->power.flags |= IW_POWER_ALL_R; - else if (ieee->ps & IEEE80211_PS_MBCAST) + if ((ieee->ps & (RTLLIB_PS_MBCAST | RTLLIB_PS_UNICAST)) == + (RTLLIB_PS_MBCAST | RTLLIB_PS_UNICAST)) + wrqu->power.flags |= IW_POWER_ALL_R; + else if (ieee->ps & RTLLIB_PS_MBCAST) wrqu->power.flags |= IW_POWER_MULTICAST_R; else wrqu->power.flags |= IW_POWER_UNICAST_R; @@ -597,4 +643,3 @@ exit: return ret; } - diff --git a/drivers/staging/rtl8192e/rtllib_tx.c b/drivers/staging/rtl8192e/rtllib_tx.c new file mode 100644 index 0000000..44e8006 --- /dev/null +++ b/drivers/staging/rtl8192e/rtllib_tx.c @@ -0,0 +1,967 @@ +/****************************************************************************** + + Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved. + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2 of the GNU General Public License as + published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., 59 + Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + The full GNU General Public License is included in this distribution in the + file called LICENSE. + + Contact Information: + James P. Ketrenos <ipw2100-admin@linux.intel.com> + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + +****************************************************************************** + + Few modifications for Realtek's Wi-Fi drivers by + Andrea Merello <andreamrl@tiscali.it> + + A special thanks goes to Realtek for their support ! + +******************************************************************************/ + +#include <linux/compiler.h> +#include <linux/errno.h> +#include <linux/if_arp.h> +#include <linux/in6.h> +#include <linux/in.h> +#include <linux/ip.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/netdevice.h> +#include <linux/pci.h> +#include <linux/proc_fs.h> +#include <linux/skbuff.h> +#include <linux/slab.h> +#include <linux/tcp.h> +#include <linux/types.h> +#include <linux/version.h> +#include <linux/wireless.h> +#include <linux/etherdevice.h> +#include <linux/uaccess.h> +#include <linux/if_vlan.h> + +#include "rtllib.h" + +/* + + +802.11 Data Frame + + +802.11 frame_contorl for data frames - 2 bytes + ,-----------------------------------------------------------------------------------------. +bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e | + |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------| +val | 0 | 0 | 0 | 1 | x | 0 | 0 | 0 | 1 | 0 | x | x | x | x | x | + |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------| +desc | ^-ver-^ | ^type-^ | ^-----subtype-----^ | to |from |more |retry| pwr |more |wep | + | | | x=0 data,x=1 data+ack | DS | DS |frag | | mgm |data | | + '-----------------------------------------------------------------------------------------' + /\ + | +802.11 Data Frame | + ,--------- 'ctrl' expands to >-----------' + | + ,--'---,-------------------------------------------------------------. +Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 | + |------|------|---------|---------|---------|------|---------|------| +Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | Frame | fcs | + | | tion | (BSSID) | | | ence | data | | + `--------------------------------------------------| |------' +Total: 28 non-data bytes `----.----' + | + .- 'Frame data' expands to <---------------------------' + | + V + ,---------------------------------------------------. +Bytes | 1 | 1 | 1 | 3 | 2 | 0-2304 | + |------|------|---------|----------|------|---------| +Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP | + | DSAP | SSAP | | | | Packet | + | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8| | | + `-----------------------------------------| | +Total: 8 non-data bytes `----.----' + | + .- 'IP Packet' expands, if WEP enabled, to <--' + | + V + ,-----------------------. +Bytes | 4 | 0-2296 | 4 | + |-----|-----------|-----| +Desc. | IV | Encrypted | ICV | + | | IP Packet | | + `-----------------------' +Total: 8 non-data bytes + + +802.3 Ethernet Data Frame + + ,-----------------------------------------. +Bytes | 6 | 6 | 2 | Variable | 4 | + |-------|-------|------|-----------|------| +Desc. | Dest. | Source| Type | IP Packet | fcs | + | MAC | MAC | | | | + `-----------------------------------------' +Total: 18 non-data bytes + +In the event that fragmentation is required, the incoming payload is split into +N parts of size ieee->fts. The first fragment contains the SNAP header and the +remaining packets are just data. + +If encryption is enabled, each fragment payload size is reduced by enough space +to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP) +So if you have 1500 bytes of payload with ieee->fts set to 500 without +encryption it will take 3 frames. With WEP it will take 4 frames as the +payload of each frame is reduced to 492 bytes. + +* SKB visualization +* +* ,- skb->data +* | +* | ETHERNET HEADER ,-<-- PAYLOAD +* | | 14 bytes from skb->data +* | 2 bytes for Type --> ,T. | (sizeof ethhdr) +* | | | | +* |,-Dest.--. ,--Src.---. | | | +* | 6 bytes| | 6 bytes | | | | +* v | | | | | | +* 0 | v 1 | v | v 2 +* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 +* ^ | ^ | ^ | +* | | | | | | +* | | | | `T' <---- 2 bytes for Type +* | | | | +* | | '---SNAP--' <-------- 6 bytes for SNAP +* | | +* `-IV--' <-------------------- 4 bytes for IV (WEP) +* +* SNAP HEADER +* +*/ + +static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 }; +static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 }; + +inline int rtllib_put_snap(u8 *data, u16 h_proto) +{ + struct rtllib_snap_hdr *snap; + u8 *oui; + + snap = (struct rtllib_snap_hdr *)data; + snap->dsap = 0xaa; + snap->ssap = 0xaa; + snap->ctrl = 0x03; + + if (h_proto == 0x8137 || h_proto == 0x80f3) + oui = P802_1H_OUI; + else + oui = RFC1042_OUI; + snap->oui[0] = oui[0]; + snap->oui[1] = oui[1]; + snap->oui[2] = oui[2]; + + *(u16 *)(data + SNAP_SIZE) = htons(h_proto); + + return SNAP_SIZE + sizeof(u16); +} + +int rtllib_encrypt_fragment(struct rtllib_device *ieee, struct sk_buff *frag, + int hdr_len) +{ + struct rtllib_crypt_data *crypt = NULL; + int res; + + crypt = ieee->crypt[ieee->tx_keyidx]; + + if (!(crypt && crypt->ops)) { + printk(KERN_INFO "=========>%s(), crypt is null\n", __func__); + return -1; + } + /* To encrypt, frame format is: + * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes) */ + + /* Host-based IEEE 802.11 fragmentation for TX is not yet supported, so + * call both MSDU and MPDU encryption functions from here. */ + atomic_inc(&crypt->refcnt); + res = 0; + if (crypt->ops->encrypt_msdu) + res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv); + if (res == 0 && crypt->ops->encrypt_mpdu) + res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv); + + atomic_dec(&crypt->refcnt); + if (res < 0) { + printk(KERN_INFO "%s: Encryption failed: len=%d.\n", + ieee->dev->name, frag->len); + ieee->ieee_stats.tx_discards++; + return -1; + } + + return 0; +} + + +void rtllib_txb_free(struct rtllib_txb *txb) +{ + if (unlikely(!txb)) + return; + kfree(txb); +} + +static struct rtllib_txb *rtllib_alloc_txb(int nr_frags, int txb_size, + gfp_t gfp_mask) +{ + struct rtllib_txb *txb; + int i; + txb = kmalloc(sizeof(struct rtllib_txb) + (sizeof(u8 *) * nr_frags), + gfp_mask); + if (!txb) + return NULL; + + memset(txb, 0, sizeof(struct rtllib_txb)); + txb->nr_frags = nr_frags; + txb->frag_size = txb_size; + + for (i = 0; i < nr_frags; i++) { + txb->fragments[i] = dev_alloc_skb(txb_size); + if (unlikely(!txb->fragments[i])) { + i--; + break; + } + memset(txb->fragments[i]->cb, 0, sizeof(txb->fragments[i]->cb)); + } + if (unlikely(i != nr_frags)) { + while (i >= 0) + dev_kfree_skb_any(txb->fragments[i--]); + kfree(txb); + return NULL; + } + return txb; +} + +static int rtllib_classify(struct sk_buff *skb, u8 bIsAmsdu) +{ + struct ethhdr *eth; + struct iphdr *ip; + + eth = (struct ethhdr *)skb->data; + if (eth->h_proto != htons(ETH_P_IP)) + return 0; + + RTLLIB_DEBUG_DATA(RTLLIB_DL_DATA, skb->data, skb->len); + ip = ip_hdr(skb); + switch (ip->tos & 0xfc) { + case 0x20: + return 2; + case 0x40: + return 1; + case 0x60: + return 3; + case 0x80: + return 4; + case 0xa0: + return 5; + case 0xc0: + return 6; + case 0xe0: + return 7; + default: + return 0; + } +} + +static void rtllib_tx_query_agg_cap(struct rtllib_device *ieee, + struct sk_buff *skb, + struct cb_desc *tcb_desc) +{ + struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; + struct tx_ts_record *pTxTs = NULL; + struct rtllib_hdr_1addr* hdr = (struct rtllib_hdr_1addr *)skb->data; + + if (rtllib_act_scanning(ieee, false)) + return; + + if (!pHTInfo->bCurrentHTSupport || !pHTInfo->bEnableHT) + return; + if (!IsQoSDataFrame(skb->data)) + return; + if (is_multicast_ether_addr(hdr->addr1) || + is_broadcast_ether_addr(hdr->addr1)) + return; + + if (tcb_desc->bdhcp || ieee->CntAfterLink < 2) + return; + + if (pHTInfo->IOTAction & HT_IOT_ACT_TX_NO_AGGREGATION) + return; + + if (!ieee->GetNmodeSupportBySecCfg(ieee->dev)) + return; + if (pHTInfo->bCurrentAMPDUEnable) { + if (!GetTs(ieee, (struct ts_common_info **)(&pTxTs), hdr->addr1, + skb->priority, TX_DIR, true)) { + printk(KERN_INFO "%s: can't get TS\n", __func__); + return; + } + if (pTxTs->TxAdmittedBARecord.bValid == false) { + if (ieee->wpa_ie_len && (ieee->pairwise_key_type == + KEY_TYPE_NA)) { + ; + } else if (tcb_desc->bdhcp == 1) { + ; + } else if (!pTxTs->bDisable_AddBa) { + TsStartAddBaProcess(ieee, pTxTs); + } + goto FORCED_AGG_SETTING; + } else if (pTxTs->bUsingBa == false) { + if (SN_LESS(pTxTs->TxAdmittedBARecord.BaStartSeqCtrl.field.SeqNum, + (pTxTs->TxCurSeq+1)%4096)) + pTxTs->bUsingBa = true; + else + goto FORCED_AGG_SETTING; + } + if (ieee->iw_mode == IW_MODE_INFRA) { + tcb_desc->bAMPDUEnable = true; + tcb_desc->ampdu_factor = pHTInfo->CurrentAMPDUFactor; + tcb_desc->ampdu_density = pHTInfo->CurrentMPDUDensity; + } + } +FORCED_AGG_SETTING: + switch (pHTInfo->ForcedAMPDUMode) { + case HT_AGG_AUTO: + break; + + case HT_AGG_FORCE_ENABLE: + tcb_desc->bAMPDUEnable = true; + tcb_desc->ampdu_density = pHTInfo->ForcedMPDUDensity; + tcb_desc->ampdu_factor = pHTInfo->ForcedAMPDUFactor; + break; + + case HT_AGG_FORCE_DISABLE: + tcb_desc->bAMPDUEnable = false; + tcb_desc->ampdu_density = 0; + tcb_desc->ampdu_factor = 0; + break; + } + return; +} + +static void rtllib_qurey_ShortPreambleMode(struct rtllib_device *ieee, + struct cb_desc *tcb_desc) +{ + tcb_desc->bUseShortPreamble = false; + if (tcb_desc->data_rate == 2) + return; + else if (ieee->current_network.capability & + WLAN_CAPABILITY_SHORT_PREAMBLE) + tcb_desc->bUseShortPreamble = true; + return; +} + +static void rtllib_query_HTCapShortGI(struct rtllib_device *ieee, + struct cb_desc *tcb_desc) +{ + struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; + + tcb_desc->bUseShortGI = false; + + if (!pHTInfo->bCurrentHTSupport || !pHTInfo->bEnableHT) + return; + + if (pHTInfo->bForcedShortGI) { + tcb_desc->bUseShortGI = true; + return; + } + + if ((pHTInfo->bCurBW40MHz == true) && pHTInfo->bCurShortGI40MHz) + tcb_desc->bUseShortGI = true; + else if ((pHTInfo->bCurBW40MHz == false) && pHTInfo->bCurShortGI20MHz) + tcb_desc->bUseShortGI = true; +} + +static void rtllib_query_BandwidthMode(struct rtllib_device *ieee, + struct cb_desc *tcb_desc) +{ + struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; + + tcb_desc->bPacketBW = false; + + if (!pHTInfo->bCurrentHTSupport || !pHTInfo->bEnableHT) + return; + + if (tcb_desc->bMulticast || tcb_desc->bBroadcast) + return; + + if ((tcb_desc->data_rate & 0x80) == 0) + return; + if (pHTInfo->bCurBW40MHz && pHTInfo->bCurTxBW40MHz && + !ieee->bandwidth_auto_switch.bforced_tx20Mhz) + tcb_desc->bPacketBW = true; + return; +} + +static void rtllib_query_protectionmode(struct rtllib_device *ieee, + struct cb_desc *tcb_desc, + struct sk_buff *skb) +{ + tcb_desc->bRTSSTBC = false; + tcb_desc->bRTSUseShortGI = false; + tcb_desc->bCTSEnable = false; + tcb_desc->RTSSC = 0; + tcb_desc->bRTSBW = false; + + if (tcb_desc->bBroadcast || tcb_desc->bMulticast) + return; + + if (is_broadcast_ether_addr(skb->data+16)) + return; + + if (ieee->mode < IEEE_N_24G) { + if (skb->len > ieee->rts) { + tcb_desc->bRTSEnable = true; + tcb_desc->rts_rate = MGN_24M; + } else if (ieee->current_network.buseprotection) { + tcb_desc->bRTSEnable = true; + tcb_desc->bCTSEnable = true; + tcb_desc->rts_rate = MGN_24M; + } + return; + } else { + struct rt_hi_throughput *pHTInfo = ieee->pHTInfo; + while (true) { + if (pHTInfo->IOTAction & HT_IOT_ACT_FORCED_CTS2SELF) { + tcb_desc->bCTSEnable = true; + tcb_desc->rts_rate = MGN_24M; + tcb_desc->bRTSEnable = true; + break; + } else if (pHTInfo->IOTAction & (HT_IOT_ACT_FORCED_RTS | + HT_IOT_ACT_PURE_N_MODE)) { + tcb_desc->bRTSEnable = true; + tcb_desc->rts_rate = MGN_24M; + break; + } + if (ieee->current_network.buseprotection) { + tcb_desc->bRTSEnable = true; + tcb_desc->bCTSEnable = true; + tcb_desc->rts_rate = MGN_24M; + break; + } + if (pHTInfo->bCurrentHTSupport && pHTInfo->bEnableHT) { + u8 HTOpMode = pHTInfo->CurrentOpMode; + if ((pHTInfo->bCurBW40MHz && (HTOpMode == 2 || + HTOpMode == 3)) || + (!pHTInfo->bCurBW40MHz && HTOpMode == 3)) { + tcb_desc->rts_rate = MGN_24M; + tcb_desc->bRTSEnable = true; + break; + } + } + if (skb->len > ieee->rts) { + tcb_desc->rts_rate = MGN_24M; + tcb_desc->bRTSEnable = true; + break; + } + if (tcb_desc->bAMPDUEnable) { + tcb_desc->rts_rate = MGN_24M; + tcb_desc->bRTSEnable = false; + break; + } + goto NO_PROTECTION; + } + } + if (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_PREAMBLE) + tcb_desc->bUseShortPreamble = true; + if (ieee->iw_mode == IW_MODE_MASTER) + goto NO_PROTECTION; + return; +NO_PROTECTION: + tcb_desc->bRTSEnable = false; + tcb_desc->bCTSEnable = false; + tcb_desc->rts_rate = 0; + tcb_desc->RTSSC = 0; + tcb_desc->bRTSBW = false; +} + + +static void rtllib_txrate_selectmode(struct rtllib_device *ieee, + struct cb_desc *tcb_desc) +{ + if (ieee->bTxDisableRateFallBack) + tcb_desc->bTxDisableRateFallBack = true; + + if (ieee->bTxUseDriverAssingedRate) + tcb_desc->bTxUseDriverAssingedRate = true; + if (!tcb_desc->bTxDisableRateFallBack || + !tcb_desc->bTxUseDriverAssingedRate) { + if (ieee->iw_mode == IW_MODE_INFRA || + ieee->iw_mode == IW_MODE_ADHOC) + tcb_desc->RATRIndex = 0; + } +} + +u16 rtllib_query_seqnum(struct rtllib_device *ieee, struct sk_buff *skb, + u8 *dst) +{ + u16 seqnum = 0; + + if (is_multicast_ether_addr(dst) || is_broadcast_ether_addr(dst)) + return 0; + if (IsQoSDataFrame(skb->data)) { + struct tx_ts_record *pTS = NULL; + if (!GetTs(ieee, (struct ts_common_info **)(&pTS), dst, + skb->priority, TX_DIR, true)) + return 0; + seqnum = pTS->TxCurSeq; + pTS->TxCurSeq = (pTS->TxCurSeq+1)%4096; + return seqnum; + } + return 0; +} + +static int wme_downgrade_ac(struct sk_buff *skb) +{ + switch (skb->priority) { + case 6: + case 7: + skb->priority = 5; /* VO -> VI */ + return 0; + case 4: + case 5: + skb->priority = 3; /* VI -> BE */ + return 0; + case 0: + case 3: + skb->priority = 1; /* BE -> BK */ + return 0; + default: + return -1; + } +} + +int rtllib_xmit_inter(struct sk_buff *skb, struct net_device *dev) +{ + struct rtllib_device *ieee = (struct rtllib_device *) + netdev_priv_rsl(dev); + struct rtllib_txb *txb = NULL; + struct rtllib_hdr_3addrqos *frag_hdr; + int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size; + unsigned long flags; + struct net_device_stats *stats = &ieee->stats; + int ether_type = 0, encrypt; + int bytes, fc, qos_ctl = 0, hdr_len; + struct sk_buff *skb_frag; + struct rtllib_hdr_3addrqos header = { /* Ensure zero initialized */ + .duration_id = 0, + .seq_ctl = 0, + .qos_ctl = 0 + }; + u8 dest[ETH_ALEN], src[ETH_ALEN]; + int qos_actived = ieee->current_network.qos_data.active; + struct rtllib_crypt_data *crypt = NULL; + struct cb_desc *tcb_desc; + u8 bIsMulticast = false; + u8 IsAmsdu = false; + bool bdhcp = false; + + spin_lock_irqsave(&ieee->lock, flags); + + /* If there is no driver handler to take the TXB, dont' bother + * creating it... */ + if ((!ieee->hard_start_xmit && !(ieee->softmac_features & + IEEE_SOFTMAC_TX_QUEUE)) || + ((!ieee->softmac_data_hard_start_xmit && + (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) { + printk(KERN_WARNING "%s: No xmit handler.\n", + ieee->dev->name); + goto success; + } + + + if (likely(ieee->raw_tx == 0)) { + if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) { + printk(KERN_WARNING "%s: skb too small (%d).\n", + ieee->dev->name, skb->len); + goto success; + } + /* Save source and destination addresses */ + memcpy(dest, skb->data, ETH_ALEN); + memcpy(src, skb->data+ETH_ALEN, ETH_ALEN); + + memset(skb->cb, 0, sizeof(skb->cb)); + ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto); + + if (ieee->iw_mode == IW_MODE_MONITOR) { + txb = rtllib_alloc_txb(1, skb->len, GFP_ATOMIC); + if (unlikely(!txb)) { + printk(KERN_WARNING "%s: Could not allocate " + "TXB\n", + ieee->dev->name); + goto failed; + } + + txb->encrypted = 0; + txb->payload_size = skb->len; + memcpy(skb_put(txb->fragments[0], skb->len), skb->data, + skb->len); + + goto success; + } + + if (skb->len > 282) { + if (ETH_P_IP == ether_type) { + const struct iphdr *ip = (struct iphdr *) + ((u8 *)skb->data+14); + if (IPPROTO_UDP == ip->protocol) { + struct udphdr *udp; + + udp = (struct udphdr *)((u8 *)ip + + (ip->ihl << 2)); + if (((((u8 *)udp)[1] == 68) && + (((u8 *)udp)[3] == 67)) || + ((((u8 *)udp)[1] == 67) && + (((u8 *)udp)[3] == 68))) { + bdhcp = true; + ieee->LPSDelayCnt = 200; + } + } + } else if (ETH_P_ARP == ether_type) { + printk(KERN_INFO "=================>DHCP " + "Protocol start tx ARP pkt!!\n"); + bdhcp = true; + ieee->LPSDelayCnt = + ieee->current_network.tim.tim_count; + } + } + + skb->priority = rtllib_classify(skb, IsAmsdu); + crypt = ieee->crypt[ieee->tx_keyidx]; + encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) && + ieee->host_encrypt && crypt && crypt->ops; + if (!encrypt && ieee->ieee802_1x && + ieee->drop_unencrypted && ether_type != ETH_P_PAE) { + stats->tx_dropped++; + goto success; + } + if (crypt && !encrypt && ether_type == ETH_P_PAE) { + struct eapol *eap = (struct eapol *)(skb->data + + sizeof(struct ethhdr) - SNAP_SIZE - + sizeof(u16)); + RTLLIB_DEBUG_EAP("TX: IEEE 802.11 EAPOL frame: %s\n", + eap_get_type(eap->type)); + } + + /* Advance the SKB to the start of the payload */ + skb_pull(skb, sizeof(struct ethhdr)); + + /* Determine total amount of storage required for TXB packets */ + bytes = skb->len + SNAP_SIZE + sizeof(u16); + + if (encrypt) + fc = RTLLIB_FTYPE_DATA | RTLLIB_FCTL_WEP; + else + fc = RTLLIB_FTYPE_DATA; + + if (qos_actived) + fc |= RTLLIB_STYPE_QOS_DATA; + else + fc |= RTLLIB_STYPE_DATA; + + if (ieee->iw_mode == IW_MODE_INFRA) { + fc |= RTLLIB_FCTL_TODS; + /* To DS: Addr1 = BSSID, Addr2 = SA, + Addr3 = DA */ + memcpy(&header.addr1, ieee->current_network.bssid, + ETH_ALEN); + memcpy(&header.addr2, &src, ETH_ALEN); + if (IsAmsdu) + memcpy(&header.addr3, + ieee->current_network.bssid, ETH_ALEN); + else + memcpy(&header.addr3, &dest, ETH_ALEN); + } else if (ieee->iw_mode == IW_MODE_ADHOC) { + /* not From/To DS: Addr1 = DA, Addr2 = SA, + Addr3 = BSSID */ + memcpy(&header.addr1, dest, ETH_ALEN); + memcpy(&header.addr2, src, ETH_ALEN); + memcpy(&header.addr3, ieee->current_network.bssid, + ETH_ALEN); + } + + bIsMulticast = is_broadcast_ether_addr(header.addr1) || + is_multicast_ether_addr(header.addr1); + + header.frame_ctl = cpu_to_le16(fc); + + /* Determine fragmentation size based on destination (multicast + * and broadcast are not fragmented) */ + if (bIsMulticast) { + frag_size = MAX_FRAG_THRESHOLD; + qos_ctl |= QOS_CTL_NOTCONTAIN_ACK; + } else { + frag_size = ieee->fts; + qos_ctl = 0; + } + + if (qos_actived) { + hdr_len = RTLLIB_3ADDR_LEN + 2; + + /* in case we are a client verify acm is not set for this ac */ + while (unlikely(ieee->wmm_acm & (0x01 << skb->priority))) { + printk(KERN_INFO "skb->priority = %x\n", skb->priority); + if (wme_downgrade_ac(skb)) + break; + printk(KERN_INFO "converted skb->priority = %x\n", + skb->priority); + } + qos_ctl |= skb->priority; + header.qos_ctl = cpu_to_le16(qos_ctl & RTLLIB_QOS_TID); + } else { + hdr_len = RTLLIB_3ADDR_LEN; + } + /* Determine amount of payload per fragment. Regardless of if + * this stack is providing the full 802.11 header, one will + * eventually be affixed to this fragment -- so we must account + * for it when determining the amount of payload space. */ + bytes_per_frag = frag_size - hdr_len; + if (ieee->config & + (CFG_RTLLIB_COMPUTE_FCS | CFG_RTLLIB_RESERVE_FCS)) + bytes_per_frag -= RTLLIB_FCS_LEN; + + /* Each fragment may need to have room for encryptiong + * pre/postfix */ + if (encrypt) { + bytes_per_frag -= crypt->ops->extra_prefix_len + + crypt->ops->extra_postfix_len; + } + /* Number of fragments is the total bytes_per_frag / + * payload_per_fragment */ + nr_frags = bytes / bytes_per_frag; + bytes_last_frag = bytes % bytes_per_frag; + if (bytes_last_frag) + nr_frags++; + else + bytes_last_frag = bytes_per_frag; + + /* When we allocate the TXB we allocate enough space for the + * reserve and full fragment bytes (bytes_per_frag doesn't + * include prefix, postfix, header, FCS, etc.) */ + txb = rtllib_alloc_txb(nr_frags, frag_size + + ieee->tx_headroom, GFP_ATOMIC); + if (unlikely(!txb)) { + printk(KERN_WARNING "%s: Could not allocate TXB\n", + ieee->dev->name); + goto failed; + } + txb->encrypted = encrypt; + txb->payload_size = bytes; + + if (qos_actived) + txb->queue_index = UP2AC(skb->priority); + else + txb->queue_index = WME_AC_BE; + + for (i = 0; i < nr_frags; i++) { + skb_frag = txb->fragments[i]; + tcb_desc = (struct cb_desc *)(skb_frag->cb + + MAX_DEV_ADDR_SIZE); + if (qos_actived) { + skb_frag->priority = skb->priority; + tcb_desc->queue_index = UP2AC(skb->priority); + } else { + skb_frag->priority = WME_AC_BE; + tcb_desc->queue_index = WME_AC_BE; + } + skb_reserve(skb_frag, ieee->tx_headroom); + + if (encrypt) { + if (ieee->hwsec_active) + tcb_desc->bHwSec = 1; + else + tcb_desc->bHwSec = 0; + skb_reserve(skb_frag, + crypt->ops->extra_prefix_len); + } else { + tcb_desc->bHwSec = 0; + } + frag_hdr = (struct rtllib_hdr_3addrqos *) + skb_put(skb_frag, hdr_len); + memcpy(frag_hdr, &header, hdr_len); + + /* If this is not the last fragment, then add the + * MOREFRAGS bit to the frame control */ + if (i != nr_frags - 1) { + frag_hdr->frame_ctl = cpu_to_le16( + fc | RTLLIB_FCTL_MOREFRAGS); + bytes = bytes_per_frag; + + } else { + /* The last fragment has the remaining length */ + bytes = bytes_last_frag; + } + if ((qos_actived) && (!bIsMulticast)) { + frag_hdr->seq_ctl = + rtllib_query_seqnum(ieee, skb_frag, + header.addr1); + frag_hdr->seq_ctl = + cpu_to_le16(frag_hdr->seq_ctl<<4 | i); + } else { + frag_hdr->seq_ctl = + cpu_to_le16(ieee->seq_ctrl[0]<<4 | i); + } + /* Put a SNAP header on the first fragment */ + if (i == 0) { + rtllib_put_snap( + skb_put(skb_frag, SNAP_SIZE + + sizeof(u16)), ether_type); + bytes -= SNAP_SIZE + sizeof(u16); + } + + memcpy(skb_put(skb_frag, bytes), skb->data, bytes); + + /* Advance the SKB... */ + skb_pull(skb, bytes); + + /* Encryption routine will move the header forward in + * order to insert the IV between the header and the + * payload */ + if (encrypt) + rtllib_encrypt_fragment(ieee, skb_frag, + hdr_len); + if (ieee->config & + (CFG_RTLLIB_COMPUTE_FCS | CFG_RTLLIB_RESERVE_FCS)) + skb_put(skb_frag, 4); + } + + if ((qos_actived) && (!bIsMulticast)) { + if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF) + ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0; + else + ieee->seq_ctrl[UP2AC(skb->priority) + 1]++; + } else { + if (ieee->seq_ctrl[0] == 0xFFF) + ieee->seq_ctrl[0] = 0; + else + ieee->seq_ctrl[0]++; + } + } else { + if (unlikely(skb->len < sizeof(struct rtllib_hdr_3addr))) { + printk(KERN_WARNING "%s: skb too small (%d).\n", + ieee->dev->name, skb->len); + goto success; + } + + txb = rtllib_alloc_txb(1, skb->len, GFP_ATOMIC); + if (!txb) { + printk(KERN_WARNING "%s: Could not allocate TXB\n", + ieee->dev->name); + goto failed; + } + + txb->encrypted = 0; + txb->payload_size = skb->len; + memcpy(skb_put(txb->fragments[0], skb->len), skb->data, + skb->len); + } + + success: + if (txb) { + struct cb_desc *tcb_desc = (struct cb_desc *) + (txb->fragments[0]->cb + MAX_DEV_ADDR_SIZE); + tcb_desc->bTxEnableFwCalcDur = 1; + tcb_desc->priority = skb->priority; + + if (ether_type == ETH_P_PAE) { + if (ieee->pHTInfo->IOTAction & + HT_IOT_ACT_WA_IOT_Broadcom) { + tcb_desc->data_rate = + MgntQuery_TxRateExcludeCCKRates(ieee); + tcb_desc->bTxDisableRateFallBack = false; + } else { + tcb_desc->data_rate = ieee->basic_rate; + tcb_desc->bTxDisableRateFallBack = 1; + } + + + tcb_desc->RATRIndex = 7; + tcb_desc->bTxUseDriverAssingedRate = 1; + } else { + if (is_multicast_ether_addr(header.addr1)) + tcb_desc->bMulticast = 1; + if (is_broadcast_ether_addr(header.addr1)) + tcb_desc->bBroadcast = 1; + rtllib_txrate_selectmode(ieee, tcb_desc); + if (tcb_desc->bMulticast || tcb_desc->bBroadcast) + tcb_desc->data_rate = ieee->basic_rate; + else + tcb_desc->data_rate = CURRENT_RATE(ieee->mode, + ieee->rate, ieee->HTCurrentOperaRate); + + if (bdhcp == true) { + if (ieee->pHTInfo->IOTAction & + HT_IOT_ACT_WA_IOT_Broadcom) { + tcb_desc->data_rate = + MgntQuery_TxRateExcludeCCKRates(ieee); + tcb_desc->bTxDisableRateFallBack = false; + } else { + tcb_desc->data_rate = MGN_1M; + tcb_desc->bTxDisableRateFallBack = 1; + } + + + tcb_desc->RATRIndex = 7; + tcb_desc->bTxUseDriverAssingedRate = 1; + tcb_desc->bdhcp = 1; + } + + rtllib_qurey_ShortPreambleMode(ieee, tcb_desc); + rtllib_tx_query_agg_cap(ieee, txb->fragments[0], + tcb_desc); + rtllib_query_HTCapShortGI(ieee, tcb_desc); + rtllib_query_BandwidthMode(ieee, tcb_desc); + rtllib_query_protectionmode(ieee, tcb_desc, + txb->fragments[0]); + } + } + spin_unlock_irqrestore(&ieee->lock, flags); + dev_kfree_skb_any(skb); + if (txb) { + if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE) { + dev->stats.tx_packets++; + dev->stats.tx_bytes += txb->payload_size; + rtllib_softmac_xmit(txb, ieee); + } else { + if ((*ieee->hard_start_xmit)(txb, dev) == 0) { + stats->tx_packets++; + stats->tx_bytes += txb->payload_size; + return 0; + } + rtllib_txb_free(txb); + } + } + + return 0; + + failed: + spin_unlock_irqrestore(&ieee->lock, flags); + netif_stop_queue(dev); + stats->tx_errors++; + return 1; + +} +int rtllib_xmit(struct sk_buff *skb, struct net_device *dev) +{ + memset(skb->cb, 0, sizeof(skb->cb)); + return rtllib_xmit_inter(skb, dev); +} diff --git a/drivers/staging/rtl8192e/rtllib_wx.c b/drivers/staging/rtl8192e/rtllib_wx.c new file mode 100644 index 0000000..8cea4a6 --- /dev/null +++ b/drivers/staging/rtl8192e/rtllib_wx.c @@ -0,0 +1,876 @@ +/****************************************************************************** + + Copyright(c) 2004 Intel Corporation. All rights reserved. + + Portions of this file are based on the WEP enablement code provided by the + Host AP project hostap-drivers v0.1.3 + Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen + <jkmaline@cc.hut.fi> + Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi> + + This program is free software; you can redistribute it and/or modify it + under the terms of version 2 of the GNU General Public License as + published by the Free Software Foundation. + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + more details. + + You should have received a copy of the GNU General Public License along with + this program; if not, write to the Free Software Foundation, Inc., 59 + Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + The full GNU General Public License is included in this distribution in the + file called LICENSE. + + Contact Information: + James P. Ketrenos <ipw2100-admin@linux.intel.com> + Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 + +******************************************************************************/ +#include <linux/wireless.h> +#include <linux/version.h> +#include <linux/kmod.h> +#include <linux/module.h> + +#include "rtllib.h" +struct modes_unit { + char *mode_string; + int mode_size; +}; +static struct modes_unit rtllib_modes[] = { + {"a", 1}, + {"b", 1}, + {"g", 1}, + {"?", 1}, + {"N-24G", 5}, + {"N-5G", 4}, +}; + +#define MAX_CUSTOM_LEN 64 +static inline char *rtl819x_translate_scan(struct rtllib_device *ieee, + char *start, char *stop, + struct rtllib_network *network, + struct iw_request_info *info) +{ + char custom[MAX_CUSTOM_LEN]; + char proto_name[IFNAMSIZ]; + char *pname = proto_name; + char *p; + struct iw_event iwe; + int i, j; + u16 max_rate, rate; + static u8 EWC11NHTCap[] = {0x00, 0x90, 0x4c, 0x33}; + + /* First entry *MUST* be the AP MAC address */ + iwe.cmd = SIOCGIWAP; + iwe.u.ap_addr.sa_family = ARPHRD_ETHER; + memcpy(iwe.u.ap_addr.sa_data, network->bssid, ETH_ALEN); + start = iwe_stream_add_event_rsl(info, start, stop, + &iwe, IW_EV_ADDR_LEN); + /* Remaining entries will be displayed in the order we provide them */ + + /* Add the ESSID */ + iwe.cmd = SIOCGIWESSID; + iwe.u.data.flags = 1; + if (network->ssid_len > 0) { + iwe.u.data.length = min(network->ssid_len, (u8)32); + start = iwe_stream_add_point_rsl(info, start, stop, &iwe, + network->ssid); + } else if (network->hidden_ssid_len == 0) { + iwe.u.data.length = sizeof("<hidden>"); + start = iwe_stream_add_point_rsl(info, start, stop, + &iwe, "<hidden>"); + } else { + iwe.u.data.length = min(network->hidden_ssid_len, (u8)32); + start = iwe_stream_add_point_rsl(info, start, stop, &iwe, + network->hidden_ssid); + } + /* Add the protocol name */ + iwe.cmd = SIOCGIWNAME; + for (i = 0; i < (sizeof(rtllib_modes)/sizeof(rtllib_modes[0])); i++) { + if (network->mode&(1<<i)) { + sprintf(pname, rtllib_modes[i].mode_string, + rtllib_modes[i].mode_size); + pname += rtllib_modes[i].mode_size; + } + } + *pname = '\0'; + snprintf(iwe.u.name, IFNAMSIZ, "IEEE802.11%s", proto_name); + start = iwe_stream_add_event_rsl(info, start, stop, + &iwe, IW_EV_CHAR_LEN); + /* Add mode */ + iwe.cmd = SIOCGIWMODE; + if (network->capability & + (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) { + if (network->capability & WLAN_CAPABILITY_ESS) + iwe.u.mode = IW_MODE_MASTER; + else + iwe.u.mode = IW_MODE_ADHOC; + start = iwe_stream_add_event_rsl(info, start, stop, + &iwe, IW_EV_UINT_LEN); + } + + /* Add frequency/channel */ + iwe.cmd = SIOCGIWFREQ; +/* iwe.u.freq.m = rtllib_frequency(network->channel, network->mode); + iwe.u.freq.e = 3; */ + iwe.u.freq.m = network->channel; + iwe.u.freq.e = 0; + iwe.u.freq.i = 0; + start = iwe_stream_add_event_rsl(info, start, stop, &iwe, + IW_EV_FREQ_LEN); + + /* Add encryption capability */ + iwe.cmd = SIOCGIWENCODE; + if (network->capability & WLAN_CAPABILITY_PRIVACY) + iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; + else + iwe.u.data.flags = IW_ENCODE_DISABLED; + iwe.u.data.length = 0; + start = iwe_stream_add_point_rsl(info, start, stop, + &iwe, network->ssid); + /* Add basic and extended rates */ + max_rate = 0; + p = custom; + p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): "); + for (i = 0, j = 0; i < network->rates_len;) { + if (j < network->rates_ex_len && + ((network->rates_ex[j] & 0x7F) < + (network->rates[i] & 0x7F))) + rate = network->rates_ex[j++] & 0x7F; + else + rate = network->rates[i++] & 0x7F; + if (rate > max_rate) + max_rate = rate; + p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), + "%d%s ", rate >> 1, (rate & 1) ? ".5" : ""); + } + for (; j < network->rates_ex_len; j++) { + rate = network->rates_ex[j] & 0x7F; + p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), + "%d%s ", rate >> 1, (rate & 1) ? ".5" : ""); + if (rate > max_rate) + max_rate = rate; + } + + if (network->mode >= IEEE_N_24G) { + struct ht_capab_ele *ht_cap = NULL; + bool is40M = false, isShortGI = false; + u8 max_mcs = 0; + if (!memcmp(network->bssht.bdHTCapBuf, EWC11NHTCap, 4)) + ht_cap = (struct ht_capab_ele *) + &network->bssht.bdHTCapBuf[4]; + else + ht_cap = (struct ht_capab_ele *) + &network->bssht.bdHTCapBuf[0]; + is40M = (ht_cap->ChlWidth) ? 1 : 0; + isShortGI = (ht_cap->ChlWidth) ? + ((ht_cap->ShortGI40Mhz) ? 1 : 0) : + ((ht_cap->ShortGI20Mhz) ? 1 : 0); + + max_mcs = HTGetHighestMCSRate(ieee, ht_cap->MCS, + MCS_FILTER_ALL); + rate = MCS_DATA_RATE[is40M][isShortGI][max_mcs & 0x7f]; + if (rate > max_rate) + max_rate = rate; + } + iwe.cmd = SIOCGIWRATE; + iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; + iwe.u.bitrate.value = max_rate * 500000; + start = iwe_stream_add_event_rsl(info, start, stop, &iwe, + IW_EV_PARAM_LEN); + iwe.cmd = IWEVCUSTOM; + iwe.u.data.length = p - custom; + if (iwe.u.data.length) + start = iwe_stream_add_point_rsl(info, start, stop, + &iwe, custom); + /* Add quality statistics */ + /* TODO: Fix these values... */ + iwe.cmd = IWEVQUAL; + iwe.u.qual.qual = network->stats.signal; + iwe.u.qual.level = network->stats.rssi; + iwe.u.qual.noise = network->stats.noise; + iwe.u.qual.updated = network->stats.mask & RTLLIB_STATMASK_WEMASK; + if (!(network->stats.mask & RTLLIB_STATMASK_RSSI)) + iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID; + if (!(network->stats.mask & RTLLIB_STATMASK_NOISE)) + iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID; + if (!(network->stats.mask & RTLLIB_STATMASK_SIGNAL)) + iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID; + iwe.u.qual.updated = 7; + start = iwe_stream_add_event_rsl(info, start, stop, &iwe, + IW_EV_QUAL_LEN); + + iwe.cmd = IWEVCUSTOM; + p = custom; + iwe.u.data.length = p - custom; + if (iwe.u.data.length) + start = iwe_stream_add_point_rsl(info, start, stop, + &iwe, custom); + + memset(&iwe, 0, sizeof(iwe)); + if (network->wpa_ie_len) { + char buf[MAX_WPA_IE_LEN]; + memcpy(buf, network->wpa_ie, network->wpa_ie_len); + iwe.cmd = IWEVGENIE; + iwe.u.data.length = network->wpa_ie_len; + start = iwe_stream_add_point_rsl(info, start, stop, &iwe, buf); + } + memset(&iwe, 0, sizeof(iwe)); + if (network->rsn_ie_len) { + char buf[MAX_WPA_IE_LEN]; + memcpy(buf, network->rsn_ie, network->rsn_ie_len); + iwe.cmd = IWEVGENIE; + iwe.u.data.length = network->rsn_ie_len; + start = iwe_stream_add_point_rsl(info, start, stop, &iwe, buf); + } + + /* add info for WZC */ + memset(&iwe, 0, sizeof(iwe)); + if (network->wzc_ie_len) { + char buf[MAX_WZC_IE_LEN]; + memcpy(buf, network->wzc_ie, network->wzc_ie_len); + iwe.cmd = IWEVGENIE; + iwe.u.data.length = network->wzc_ie_len; + start = iwe_stream_add_point_rsl(info, start, stop, &iwe, buf); + } + + /* Add EXTRA: Age to display seconds since last beacon/probe response + * for given network. */ + iwe.cmd = IWEVCUSTOM; + p = custom; + p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), + " Last beacon: %lums ago", + (jiffies - network->last_scanned) / (HZ / 100)); + iwe.u.data.length = p - custom; + if (iwe.u.data.length) + start = iwe_stream_add_point_rsl(info, start, stop, + &iwe, custom); + + return start; +} + +int rtllib_wx_get_scan(struct rtllib_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct rtllib_network *network; + unsigned long flags; + + char *ev = extra; + char *stop = ev + wrqu->data.length; + int i = 0; + int err = 0; + RTLLIB_DEBUG_WX("Getting scan\n"); + down(&ieee->wx_sem); + spin_lock_irqsave(&ieee->lock, flags); + + list_for_each_entry(network, &ieee->network_list, list) { + i++; + if ((stop - ev) < 200) { + err = -E2BIG; + break; + } + if (ieee->scan_age == 0 || + time_after(network->last_scanned + ieee->scan_age, jiffies)) + ev = rtl819x_translate_scan(ieee, ev, stop, network, + info); + else + RTLLIB_DEBUG_SCAN("Not showing network '%s (" + " %pM)' due to age (%lums).\n", + escape_essid(network->ssid, + network->ssid_len), + network->bssid, + (jiffies - network->last_scanned) / (HZ / 100)); + } + + spin_unlock_irqrestore(&ieee->lock, flags); + up(&ieee->wx_sem); + wrqu->data.length = ev - extra; + wrqu->data.flags = 0; + + RTLLIB_DEBUG_WX("exit: %d networks returned.\n", i); + + return err; +} + +int rtllib_wx_set_encode(struct rtllib_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *keybuf) +{ + struct iw_point *erq = &(wrqu->encoding); + struct net_device *dev = ieee->dev; + struct rtllib_security sec = { + .flags = 0 + }; + int i, key, key_provided, len; + struct rtllib_crypt_data **crypt; + + RTLLIB_DEBUG_WX("SET_ENCODE\n"); + + key = erq->flags & IW_ENCODE_INDEX; + if (key) { + if (key > WEP_KEYS) + return -EINVAL; + key--; + key_provided = 1; + } else { + key_provided = 0; + key = ieee->tx_keyidx; + } + + RTLLIB_DEBUG_WX("Key: %d [%s]\n", key, key_provided ? + "provided" : "default"); + crypt = &ieee->crypt[key]; + if (erq->flags & IW_ENCODE_DISABLED) { + if (key_provided && *crypt) { + RTLLIB_DEBUG_WX("Disabling encryption on key %d.\n", + key); + rtllib_crypt_delayed_deinit(ieee, crypt); + } else + RTLLIB_DEBUG_WX("Disabling encryption.\n"); + + /* Check all the keys to see if any are still configured, + * and if no key index was provided, de-init them all */ + for (i = 0; i < WEP_KEYS; i++) { + if (ieee->crypt[i] != NULL) { + if (key_provided) + break; + rtllib_crypt_delayed_deinit(ieee, + &ieee->crypt[i]); + } + } + + if (i == WEP_KEYS) { + sec.enabled = 0; + sec.level = SEC_LEVEL_0; + sec.flags |= SEC_ENABLED | SEC_LEVEL; + } + + goto done; + } + + + + sec.enabled = 1; + sec.flags |= SEC_ENABLED; + + if (*crypt != NULL && (*crypt)->ops != NULL && + strcmp((*crypt)->ops->name, "WEP") != 0) { + /* changing to use WEP; deinit previously used algorithm + * on this key */ + rtllib_crypt_delayed_deinit(ieee, crypt); + } + + if (*crypt == NULL) { + struct rtllib_crypt_data *new_crypt; + + /* take WEP into use */ + new_crypt = kmalloc(sizeof(struct rtllib_crypt_data), + GFP_KERNEL); + if (new_crypt == NULL) + return -ENOMEM; + memset(new_crypt, 0, sizeof(struct rtllib_crypt_data)); + new_crypt->ops = rtllib_get_crypto_ops("WEP"); + if (!new_crypt->ops) { + request_module("rtllib_crypt_wep"); + new_crypt->ops = rtllib_get_crypto_ops("WEP"); + } + + if (new_crypt->ops) + new_crypt->priv = new_crypt->ops->init(key); + + if (!new_crypt->ops || !new_crypt->priv) { + kfree(new_crypt); + new_crypt = NULL; + + printk(KERN_WARNING "%s: could not initialize WEP: " + "load module rtllib_crypt_wep\n", + dev->name); + return -EOPNOTSUPP; + } + *crypt = new_crypt; + } + + /* If a new key was provided, set it up */ + if (erq->length > 0) { + len = erq->length <= 5 ? 5 : 13; + memcpy(sec.keys[key], keybuf, erq->length); + if (len > erq->length) + memset(sec.keys[key] + erq->length, 0, + len - erq->length); + RTLLIB_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n", + key, escape_essid(sec.keys[key], len), + erq->length, len); + sec.key_sizes[key] = len; + (*crypt)->ops->set_key(sec.keys[key], len, NULL, + (*crypt)->priv); + sec.flags |= (1 << key); + /* This ensures a key will be activated if no key is + * explicitely set */ + if (key == sec.active_key) + sec.flags |= SEC_ACTIVE_KEY; + ieee->tx_keyidx = key; + + } else { + len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN, + NULL, (*crypt)->priv); + if (len == 0) { + /* Set a default key of all 0 */ + printk(KERN_INFO "Setting key %d to all zero.\n", + key); + + RTLLIB_DEBUG_WX("Setting key %d to all zero.\n", + key); + memset(sec.keys[key], 0, 13); + (*crypt)->ops->set_key(sec.keys[key], 13, NULL, + (*crypt)->priv); + sec.key_sizes[key] = 13; + sec.flags |= (1 << key); + } + + /* No key data - just set the default TX key index */ + if (key_provided) { + RTLLIB_DEBUG_WX( + "Setting key %d to default Tx key.\n", key); + ieee->tx_keyidx = key; + sec.active_key = key; + sec.flags |= SEC_ACTIVE_KEY; + } + } + done: + ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED); + ieee->auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : + WLAN_AUTH_SHARED_KEY; + sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY; + sec.flags |= SEC_AUTH_MODE; + RTLLIB_DEBUG_WX("Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ? + "OPEN" : "SHARED KEY"); + + /* For now we just support WEP, so only set that security level... + * TODO: When WPA is added this is one place that needs to change */ + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */ + + if (ieee->set_security) + ieee->set_security(dev, &sec); + + /* Do not reset port if card is in Managed mode since resetting will + * generate new IEEE 802.11 authentication which may end up in looping + * with IEEE 802.1X. If your hardware requires a reset after WEP + * configuration (for example... Prism2), implement the reset_port in + * the callbacks structures used to initialize the 802.11 stack. */ + if (ieee->reset_on_keychange && + ieee->iw_mode != IW_MODE_INFRA && + ieee->reset_port && ieee->reset_port(dev)) { + printk(KERN_DEBUG "%s: reset_port failed\n", dev->name); + return -EINVAL; + } + return 0; +} + +int rtllib_wx_get_encode(struct rtllib_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *keybuf) +{ + struct iw_point *erq = &(wrqu->encoding); + int len, key; + struct rtllib_crypt_data *crypt; + + RTLLIB_DEBUG_WX("GET_ENCODE\n"); + + if (ieee->iw_mode == IW_MODE_MONITOR) + return -1; + + key = erq->flags & IW_ENCODE_INDEX; + if (key) { + if (key > WEP_KEYS) + return -EINVAL; + key--; + } else { + key = ieee->tx_keyidx; + } + crypt = ieee->crypt[key]; + + erq->flags = key + 1; + + if (crypt == NULL || crypt->ops == NULL) { + erq->length = 0; + erq->flags |= IW_ENCODE_DISABLED; + return 0; + } + len = crypt->ops->get_key(keybuf, SCM_KEY_LEN, NULL, crypt->priv); + erq->length = (len >= 0 ? len : 0); + + erq->flags |= IW_ENCODE_ENABLED; + + if (ieee->open_wep) + erq->flags |= IW_ENCODE_OPEN; + else + erq->flags |= IW_ENCODE_RESTRICTED; + + return 0; +} + +int rtllib_wx_set_encode_ext(struct rtllib_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + int ret = 0; + struct net_device *dev = ieee->dev; + struct iw_point *encoding = &wrqu->encoding; + struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; + int i, idx; + int group_key = 0; + const char *alg, *module; + struct rtllib_crypto_ops *ops; + struct rtllib_crypt_data **crypt; + + struct rtllib_security sec = { + .flags = 0, + }; + idx = encoding->flags & IW_ENCODE_INDEX; + if (idx) { + if (idx < 1 || idx > WEP_KEYS) + return -EINVAL; + idx--; + } else{ + idx = ieee->tx_keyidx; + } + if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) { + crypt = &ieee->crypt[idx]; + group_key = 1; + } else { + /* some Cisco APs use idx>0 for unicast in dynamic WEP */ + if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP) + return -EINVAL; + if (ieee->iw_mode == IW_MODE_INFRA) + crypt = &ieee->crypt[idx]; + else + return -EINVAL; + } + + sec.flags |= SEC_ENABLED; + if ((encoding->flags & IW_ENCODE_DISABLED) || + ext->alg == IW_ENCODE_ALG_NONE) { + if (*crypt) + rtllib_crypt_delayed_deinit(ieee, crypt); + + for (i = 0; i < WEP_KEYS; i++) { + if (ieee->crypt[i] != NULL) + break; + } + if (i == WEP_KEYS) { + sec.enabled = 0; + sec.level = SEC_LEVEL_0; + sec.flags |= SEC_LEVEL; + } + goto done; + } + + sec.enabled = 1; + switch (ext->alg) { + case IW_ENCODE_ALG_WEP: + alg = "WEP"; + module = "rtllib_crypt_wep"; + break; + case IW_ENCODE_ALG_TKIP: + alg = "TKIP"; + module = "rtllib_crypt_tkip"; + break; + case IW_ENCODE_ALG_CCMP: + alg = "CCMP"; + module = "rtllib_crypt_ccmp"; + break; + default: + RTLLIB_DEBUG_WX("%s: unknown crypto alg %d\n", + dev->name, ext->alg); + ret = -EINVAL; + goto done; + } + printk(KERN_INFO "alg name:%s\n", alg); + + ops = rtllib_get_crypto_ops(alg); + if (ops == NULL) { + char tempbuf[100]; + + memset(tempbuf, 0x00, 100); + sprintf(tempbuf, "%s", module); + request_module("%s", tempbuf); + ops = rtllib_get_crypto_ops(alg); + } + if (ops == NULL) { + RTLLIB_DEBUG_WX("%s: unknown crypto alg %d\n", + dev->name, ext->alg); + printk(KERN_INFO "========>unknown crypto alg %d\n", ext->alg); + ret = -EINVAL; + goto done; + } + + if (*crypt == NULL || (*crypt)->ops != ops) { + struct rtllib_crypt_data *new_crypt; + + rtllib_crypt_delayed_deinit(ieee, crypt); + + new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL); + if (new_crypt == NULL) { + ret = -ENOMEM; + goto done; + } + new_crypt->ops = ops; + if (new_crypt->ops) + new_crypt->priv = new_crypt->ops->init(idx); + + if (new_crypt->priv == NULL) { + kfree(new_crypt); + ret = -EINVAL; + goto done; + } + *crypt = new_crypt; + + } + + if (ext->key_len > 0 && (*crypt)->ops->set_key && + (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq, + (*crypt)->priv) < 0) { + RTLLIB_DEBUG_WX("%s: key setting failed\n", dev->name); + printk(KERN_INFO "key setting failed\n"); + ret = -EINVAL; + goto done; + } + if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { + ieee->tx_keyidx = idx; + sec.active_key = idx; + sec.flags |= SEC_ACTIVE_KEY; + } + if (ext->alg != IW_ENCODE_ALG_NONE) { + sec.key_sizes[idx] = ext->key_len; + sec.flags |= (1 << idx); + if (ext->alg == IW_ENCODE_ALG_WEP) { + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_1; + } else if (ext->alg == IW_ENCODE_ALG_TKIP) { + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_2; + } else if (ext->alg == IW_ENCODE_ALG_CCMP) { + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_3; + } + /* Don't set sec level for group keys. */ + if (group_key) + sec.flags &= ~SEC_LEVEL; + } +done: + if (ieee->set_security) + ieee->set_security(ieee->dev, &sec); + + if (ieee->reset_on_keychange && + ieee->iw_mode != IW_MODE_INFRA && + ieee->reset_port && ieee->reset_port(dev)) { + RTLLIB_DEBUG_WX("%s: reset_port failed\n", dev->name); + return -EINVAL; + } + return ret; +} + +int rtllib_wx_get_encode_ext(struct rtllib_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + struct iw_point *encoding = &wrqu->encoding; + struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; + struct rtllib_crypt_data *crypt; + int idx, max_key_len; + + max_key_len = encoding->length - sizeof(*ext); + if (max_key_len < 0) + return -EINVAL; + + idx = encoding->flags & IW_ENCODE_INDEX; + if (idx) { + if (idx < 1 || idx > WEP_KEYS) + return -EINVAL; + idx--; + } else { + idx = ieee->tx_keyidx; + } + if (!(ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) && + (ext->alg != IW_ENCODE_ALG_WEP)) + if (idx != 0 || (ieee->iw_mode != IW_MODE_INFRA)) + return -EINVAL; + + crypt = ieee->crypt[idx]; + + encoding->flags = idx + 1; + memset(ext, 0, sizeof(*ext)); + + if (crypt == NULL || crypt->ops == NULL) { + ext->alg = IW_ENCODE_ALG_NONE; + ext->key_len = 0; + encoding->flags |= IW_ENCODE_DISABLED; + } else { + if (strcmp(crypt->ops->name, "WEP") == 0) + ext->alg = IW_ENCODE_ALG_WEP; + else if (strcmp(crypt->ops->name, "TKIP")) + ext->alg = IW_ENCODE_ALG_TKIP; + else if (strcmp(crypt->ops->name, "CCMP")) + ext->alg = IW_ENCODE_ALG_CCMP; + else + return -EINVAL; + ext->key_len = crypt->ops->get_key(ext->key, SCM_KEY_LEN, + NULL, crypt->priv); + encoding->flags |= IW_ENCODE_ENABLED; + if (ext->key_len && + (ext->alg == IW_ENCODE_ALG_TKIP || + ext->alg == IW_ENCODE_ALG_CCMP)) + ext->ext_flags |= IW_ENCODE_EXT_TX_SEQ_VALID; + + } + + return 0; +} + +int rtllib_wx_set_mlme(struct rtllib_device *ieee, + struct iw_request_info *info, + union iwreq_data *wrqu, char *extra) +{ + u8 i = 0; + bool deauth = false; + struct iw_mlme *mlme = (struct iw_mlme *) extra; + + if (ieee->state != RTLLIB_LINKED) + return -ENOLINK; + + down(&ieee->wx_sem); + + switch (mlme->cmd) { + case IW_MLME_DEAUTH: + deauth = true; + /* leave break out intentionly */ + + case IW_MLME_DISASSOC: + if (deauth == true) + printk(KERN_INFO "disauth packet !\n"); + else + printk(KERN_INFO "dis associate packet!\n"); + + ieee->cannot_notify = true; + + SendDisassociation(ieee, deauth, mlme->reason_code); + rtllib_disassociate(ieee); + + ieee->wap_set = 0; + for (i = 0; i < 6; i++) + ieee->current_network.bssid[i] = 0x55; + + ieee->ssid_set = 0; + ieee->current_network.ssid[0] = '\0'; + ieee->current_network.ssid_len = 0; + break; + default: + up(&ieee->wx_sem); + return -EOPNOTSUPP; + } + + up(&ieee->wx_sem); + + return 0; +} + +int rtllib_wx_set_auth(struct rtllib_device *ieee, + struct iw_request_info *info, + struct iw_param *data, char *extra) +{ + switch (data->flags & IW_AUTH_INDEX) { + case IW_AUTH_WPA_VERSION: + break; + case IW_AUTH_CIPHER_PAIRWISE: + case IW_AUTH_CIPHER_GROUP: + case IW_AUTH_KEY_MGMT: + /* + * Host AP driver does not use these parameters and allows + * wpa_supplicant to control them internally. + */ + break; + case IW_AUTH_TKIP_COUNTERMEASURES: + ieee->tkip_countermeasures = data->value; + break; + case IW_AUTH_DROP_UNENCRYPTED: + ieee->drop_unencrypted = data->value; + break; + + case IW_AUTH_80211_AUTH_ALG: + if (data->value & IW_AUTH_ALG_SHARED_KEY) { + ieee->open_wep = 0; + ieee->auth_mode = 1; + } else if (data->value & IW_AUTH_ALG_OPEN_SYSTEM) { + ieee->open_wep = 1; + ieee->auth_mode = 0; + } else if (data->value & IW_AUTH_ALG_LEAP) { + ieee->open_wep = 1; + ieee->auth_mode = 2; + } else + return -EINVAL; + break; + + case IW_AUTH_WPA_ENABLED: + ieee->wpa_enabled = (data->value) ? 1 : 0; + break; + + case IW_AUTH_RX_UNENCRYPTED_EAPOL: + ieee->ieee802_1x = data->value; + break; + case IW_AUTH_PRIVACY_INVOKED: + ieee->privacy_invoked = data->value; + break; + default: + return -EOPNOTSUPP; + } + return 0; +} + +int rtllib_wx_set_gen_ie(struct rtllib_device *ieee, u8 *ie, size_t len) +{ + u8 *buf; + u8 eid, wps_oui[4] = {0x0, 0x50, 0xf2, 0x04}; + + if (len > MAX_WPA_IE_LEN || (len && ie == NULL)) + return -EINVAL; + + if (len) { + eid = ie[0]; + if ((eid == MFIE_TYPE_GENERIC) && (!memcmp(&ie[2], + wps_oui, 4))) { + + ieee->wps_ie_len = (len < MAX_WZC_IE_LEN) ? (len) : + (MAX_WZC_IE_LEN); + buf = kmalloc(ieee->wps_ie_len, GFP_KERNEL); + if (buf == NULL) + return -ENOMEM; + memcpy(buf, ie, ieee->wps_ie_len); + ieee->wps_ie = buf; + return 0; + } + } + ieee->wps_ie_len = 0; + kfree(ieee->wps_ie); + ieee->wps_ie = NULL; + if (len) { + if (len != ie[1]+2) + return -EINVAL; + buf = kmalloc(len, GFP_KERNEL); + if (buf == NULL) + return -ENOMEM; + memcpy(buf, ie, len); + kfree(ieee->wpa_ie); + ieee->wpa_ie = buf; + ieee->wpa_ie_len = len; + } else { + kfree(ieee->wpa_ie); + ieee->wpa_ie = NULL; + ieee->wpa_ie_len = 0; + } + return 0; +} diff --git a/drivers/staging/rtl8192u/ieee80211/compress.c b/drivers/staging/rtl8192u/ieee80211/compress.c index 86c23c9..5416ab6 100644 --- a/drivers/staging/rtl8192u/ieee80211/compress.c +++ b/drivers/staging/rtl8192u/ieee80211/compress.c @@ -12,10 +12,10 @@ * */ #include <linux/types.h> -//#include <linux/crypto.h> +/*#include <linux/crypto.h>*/ #include "rtl_crypto.h" #include <linux/errno.h> -#include <asm/scatterlist.h> +#include <linux/scatterlist.h> #include <linux/string.h> #include "internal.h" diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211.h b/drivers/staging/rtl8192u/ieee80211/ieee80211.h index 463cc26..1c0a1db 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211.h @@ -2416,8 +2416,8 @@ extern int ieee80211_wx_set_mlme(struct ieee80211_device *ieee, extern int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len); /* ieee80211_softmac.c */ -extern short ieee80211_is_54g(struct ieee80211_network net); -extern short ieee80211_is_shortslot(struct ieee80211_network net); +extern short ieee80211_is_54g(const struct ieee80211_network *net); +extern short ieee80211_is_shortslot(const struct ieee80211_network *net); extern int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats, u16 type, u16 stype); diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c index b00eb0e..c2ab5fa 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c @@ -31,14 +31,14 @@ u8 rsn_authen_cipher_suite[16][4] = { {0x00,0x0F,0xAC,0x05}, //WEP-104 }; -short ieee80211_is_54g(struct ieee80211_network net) +short ieee80211_is_54g(const struct ieee80211_network *net) { - return ((net.rates_ex_len > 0) || (net.rates_len > 4)); + return (net->rates_ex_len > 0) || (net->rates_len > 4); } -short ieee80211_is_shortslot(struct ieee80211_network net) +short ieee80211_is_shortslot(const struct ieee80211_network *net) { - return (net.capability & WLAN_CAPABILITY_SHORT_SLOT); + return net->capability & WLAN_CAPABILITY_SHORT_SLOT; } /* returns the total length needed for pleacing the RATE MFIE @@ -718,7 +718,7 @@ static struct sk_buff* ieee80211_probe_resp(struct ieee80211_device *ieee, u8 *d else atim_len = 0; - if(ieee80211_is_54g(ieee->current_network)) + if(ieee80211_is_54g(&ieee->current_network)) erp_len = 3; else erp_len = 0; @@ -1333,7 +1333,7 @@ void ieee80211_associate_complete_wq(struct work_struct *work) { struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_complete_wq); printk(KERN_INFO "Associated successfully\n"); - if(ieee80211_is_54g(ieee->current_network) && + if(ieee80211_is_54g(&ieee->current_network) && (ieee->modulation & IEEE80211_OFDM_MODULATION)){ ieee->rate = 108; @@ -1489,7 +1489,7 @@ inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee, struct ieee ieee->state = IEEE80211_ASSOCIATING; queue_work(ieee->wq, &ieee->associate_procedure_wq); }else{ - if(ieee80211_is_54g(ieee->current_network) && + if(ieee80211_is_54g(&ieee->current_network) && (ieee->modulation & IEEE80211_OFDM_MODULATION)){ ieee->rate = 108; ieee->SetWirelessMode(ieee->dev, IEEE_G); diff --git a/drivers/staging/rtl8712/big_endian.h b/drivers/staging/rtl8712/big_endian.h index 8512d1b..b16f8ec 100644 --- a/drivers/staging/rtl8712/big_endian.h +++ b/drivers/staging/rtl8712/big_endian.h @@ -1,3 +1,28 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Modifications for inclusion into the Linux staging tree are + * Copyright(c) 2010 Larry Finger. All rights reserved. + * + * Contact information: + * WLAN FAE <wlanfae@realtek.com> + * Larry Finger <Larry.Finger@lwfinger.net> + * + ******************************************************************************/ #ifndef _LINUX_BYTEORDER_BIG_ENDIAN_H #define _LINUX_BYTEORDER_BIG_ENDIAN_H diff --git a/drivers/staging/rtl8712/drv_types.h b/drivers/staging/rtl8712/drv_types.h index 4f380a6..c5303c3 100644 --- a/drivers/staging/rtl8712/drv_types.h +++ b/drivers/staging/rtl8712/drv_types.h @@ -117,6 +117,11 @@ struct dvobj_priv { struct usb_device *pusbdev; }; +/** + * struct _adapter - the main adapter structure for this device. + * + * bup: True indicates that the interface is Up. + */ struct _adapter { struct dvobj_priv dvobjpriv; struct mlme_priv mlmepriv; diff --git a/drivers/staging/rtl8712/ethernet.h b/drivers/staging/rtl8712/ethernet.h index ba8d777..882d61b 100644 --- a/drivers/staging/rtl8712/ethernet.h +++ b/drivers/staging/rtl8712/ethernet.h @@ -1,3 +1,28 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Modifications for inclusion into the Linux staging tree are + * Copyright(c) 2010 Larry Finger. All rights reserved. + * + * Contact information: + * WLAN FAE <wlanfae@realtek.com> + * Larry Finger <Larry.Finger@lwfinger.net> + * + ******************************************************************************/ #ifndef __INC_ETHERNET_H #define __INC_ETHERNET_H diff --git a/drivers/staging/rtl8712/generic.h b/drivers/staging/rtl8712/generic.h index 742424b..8868c9f 100644 --- a/drivers/staging/rtl8712/generic.h +++ b/drivers/staging/rtl8712/generic.h @@ -1,3 +1,28 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Modifications for inclusion into the Linux staging tree are + * Copyright(c) 2010 Larry Finger. All rights reserved. + * + * Contact information: + * WLAN FAE <wlanfae@realtek.com> + * Larry Finger <Larry.Finger@lwfinger.net> + * + ******************************************************************************/ #ifndef _LINUX_BYTEORDER_GENERIC_H #define _LINUX_BYTEORDER_GENERIC_H diff --git a/drivers/staging/rtl8712/if_ether.h b/drivers/staging/rtl8712/if_ether.h index 0e9753b..2bbe527 100644 --- a/drivers/staging/rtl8712/if_ether.h +++ b/drivers/staging/rtl8712/if_ether.h @@ -1,3 +1,28 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Modifications for inclusion into the Linux staging tree are + * Copyright(c) 2010 Larry Finger. All rights reserved. + * + * Contact information: + * WLAN FAE <wlanfae@realtek.com> + * Larry Finger <Larry.Finger@lwfinger.net> + * + ******************************************************************************/ /* * INET An implementation of the TCP/IP protocol suite for the LINUX * operating system. INET is implemented using the BSD Socket diff --git a/drivers/staging/rtl8712/little_endian.h b/drivers/staging/rtl8712/little_endian.h index 0248c14..cd57d6c 100644 --- a/drivers/staging/rtl8712/little_endian.h +++ b/drivers/staging/rtl8712/little_endian.h @@ -1,3 +1,28 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Modifications for inclusion into the Linux staging tree are + * Copyright(c) 2010 Larry Finger. All rights reserved. + * + * Contact information: + * WLAN FAE <wlanfae@realtek.com> + * Larry Finger <Larry.Finger@lwfinger.net> + * + ******************************************************************************/ #ifndef _LINUX_BYTEORDER_LITTLE_ENDIAN_H #define _LINUX_BYTEORDER_LITTLE_ENDIAN_H diff --git a/drivers/staging/rtl8712/mlme_osdep.h b/drivers/staging/rtl8712/mlme_osdep.h index 968e787..a20fe81 100644 --- a/drivers/staging/rtl8712/mlme_osdep.h +++ b/drivers/staging/rtl8712/mlme_osdep.h @@ -1,3 +1,28 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Modifications for inclusion into the Linux staging tree are + * Copyright(c) 2010 Larry Finger. All rights reserved. + * + * Contact information: + * WLAN FAE <wlanfae@realtek.com> + * Larry Finger <Larry.Finger@lwfinger.net> + * + ******************************************************************************/ #ifndef __MLME_OSDEP_H_ #define __MLME_OSDEP_H_ diff --git a/drivers/staging/rtl8712/mp_custom_oid.h b/drivers/staging/rtl8712/mp_custom_oid.h index a9e0b34..4051008 100644 --- a/drivers/staging/rtl8712/mp_custom_oid.h +++ b/drivers/staging/rtl8712/mp_custom_oid.h @@ -1,3 +1,28 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Modifications for inclusion into the Linux staging tree are + * Copyright(c) 2010 Larry Finger. All rights reserved. + * + * Contact information: + * WLAN FAE <wlanfae@realtek.com> + * Larry Finger <Larry.Finger@lwfinger.net> + * + ******************************************************************************/ #ifndef __CUSTOM_OID_H #define __CUSTOM_OID_H diff --git a/drivers/staging/rtl8712/os_intfs.c b/drivers/staging/rtl8712/os_intfs.c index 3f38e8e..6697941 100644 --- a/drivers/staging/rtl8712/os_intfs.c +++ b/drivers/staging/rtl8712/os_intfs.c @@ -375,6 +375,12 @@ static void enable_video_mode(struct _adapter *padapter, int cbw40_value) r8712_fw_cmd(padapter, intcmd); } +/** + * + * This function intends to handle the activation of an interface + * i.e. when it is brought Up/Active from a Down state. + * + */ static int netdev_open(struct net_device *pnetdev) { struct _adapter *padapter = (struct _adapter *)_netdev_priv(pnetdev); @@ -434,6 +440,12 @@ netdev_open_error: return -1; } +/** + * + * This function intends to handle the shutdown of an interface + * i.e. when it is brought Down from an Up/Active state. + * + */ static int netdev_close(struct net_device *pnetdev) { struct _adapter *padapter = (struct _adapter *) _netdev_priv(pnetdev); @@ -458,6 +470,8 @@ static int netdev_close(struct net_device *pnetdev) r8712_free_network_queue(padapter); /*Stop driver mlme relation timer*/ stop_drv_timers(padapter); + /* The interface is no longer Up: */ + padapter->bup = false; return 0; } diff --git a/drivers/staging/rtl8712/osdep_service.h b/drivers/staging/rtl8712/osdep_service.h index c683d76..aac97bb 100644 --- a/drivers/staging/rtl8712/osdep_service.h +++ b/drivers/staging/rtl8712/osdep_service.h @@ -203,7 +203,6 @@ static inline unsigned char _cancel_timer_ex(struct timer_list *ptimer) static inline void thread_enter(void *context) { - daemonize("%s", "RTKTHREAD"); allow_signal(SIGTERM); } diff --git a/drivers/staging/rtl8712/recv_osdep.h b/drivers/staging/rtl8712/recv_osdep.h index 60a54dd..f4384ef 100644 --- a/drivers/staging/rtl8712/recv_osdep.h +++ b/drivers/staging/rtl8712/recv_osdep.h @@ -1,3 +1,28 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Modifications for inclusion into the Linux staging tree are + * Copyright(c) 2010 Larry Finger. All rights reserved. + * + * Contact information: + * WLAN FAE <wlanfae@realtek.com> + * Larry Finger <Larry.Finger@lwfinger.net> + * + ******************************************************************************/ #ifndef __RECV_OSDEP_H_ #define __RECV_OSDEP_H_ diff --git a/drivers/staging/rtl8712/rtl8712_bitdef.h b/drivers/staging/rtl8712/rtl8712_bitdef.h index 356184f..bff57a8 100644 --- a/drivers/staging/rtl8712/rtl8712_bitdef.h +++ b/drivers/staging/rtl8712/rtl8712_bitdef.h @@ -1,3 +1,24 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ + + #ifndef __RTL8712_BITDEF_H__ #define __RTL8712_BITDEF_H__ diff --git a/drivers/staging/rtl8712/rtl8712_cmdctrl_bitdef.h b/drivers/staging/rtl8712/rtl8712_cmdctrl_bitdef.h index 6c49903..8dffe10 100644 --- a/drivers/staging/rtl8712/rtl8712_cmdctrl_bitdef.h +++ b/drivers/staging/rtl8712/rtl8712_cmdctrl_bitdef.h @@ -1,3 +1,22 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ #ifndef __RTL8712_CMDCTRL_BITDEF_H__ #define __RTL8712_CMDCTRL_BITDEF_H__ diff --git a/drivers/staging/rtl8712/rtl8712_cmdctrl_regdef.h b/drivers/staging/rtl8712/rtl8712_cmdctrl_regdef.h index 5d9a3f2..9374f1c 100644 --- a/drivers/staging/rtl8712/rtl8712_cmdctrl_regdef.h +++ b/drivers/staging/rtl8712/rtl8712_cmdctrl_regdef.h @@ -1,3 +1,22 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ #ifndef __RTL8712_CMDCTRL_REGDEF_H__ #define __RTL8712_CMDCTRL_REGDEF_H__ diff --git a/drivers/staging/rtl8712/rtl8712_debugctrl_bitdef.h b/drivers/staging/rtl8712/rtl8712_debugctrl_bitdef.h index 7b34d40..8bd4837 100644 --- a/drivers/staging/rtl8712/rtl8712_debugctrl_bitdef.h +++ b/drivers/staging/rtl8712/rtl8712_debugctrl_bitdef.h @@ -1,3 +1,22 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ #ifndef __RTL8712_DEBUGCTRL_BITDEF_H__ #define __RTL8712_DEBUGCTRL_BITDEF_H__ diff --git a/drivers/staging/rtl8712/rtl8712_debugctrl_regdef.h b/drivers/staging/rtl8712/rtl8712_debugctrl_regdef.h index 27cad71..43630bb 100644 --- a/drivers/staging/rtl8712/rtl8712_debugctrl_regdef.h +++ b/drivers/staging/rtl8712/rtl8712_debugctrl_regdef.h @@ -1,3 +1,22 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ #ifndef __RTL8712_DEBUGCTRL_REGDEF_H__ #define __RTL8712_DEBUGCTRL_REGDEF_H__ diff --git a/drivers/staging/rtl8712/rtl8712_edcasetting_bitdef.h b/drivers/staging/rtl8712/rtl8712_edcasetting_bitdef.h index c69b1b7..32dab81 100644 --- a/drivers/staging/rtl8712/rtl8712_edcasetting_bitdef.h +++ b/drivers/staging/rtl8712/rtl8712_edcasetting_bitdef.h @@ -1,3 +1,28 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Modifications for inclusion into the Linux staging tree are + * Copyright(c) 2010 Larry Finger. All rights reserved. + * + * Contact information: + * WLAN FAE <wlanfae@realtek.com> + * Larry Finger <Larry.Finger@lwfinger.net> + * + ******************************************************************************/ #ifndef __RTL8712_EDCASETTING_BITDEF_H__ #define __RTL8712_EDCASETTING_BITDEF_H__ diff --git a/drivers/staging/rtl8712/rtl8712_edcasetting_regdef.h b/drivers/staging/rtl8712/rtl8712_edcasetting_regdef.h index de3d3e2..d992cb8 100644 --- a/drivers/staging/rtl8712/rtl8712_edcasetting_regdef.h +++ b/drivers/staging/rtl8712/rtl8712_edcasetting_regdef.h @@ -1,3 +1,22 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ #ifndef __RTL8712_EDCASETTING_REGDEF_H__ #define __RTL8712_EDCASETTING_REGDEF_H__ diff --git a/drivers/staging/rtl8712/rtl8712_fifoctrl_bitdef.h b/drivers/staging/rtl8712/rtl8712_fifoctrl_bitdef.h index e5df19f..c564dc8 100644 --- a/drivers/staging/rtl8712/rtl8712_fifoctrl_bitdef.h +++ b/drivers/staging/rtl8712/rtl8712_fifoctrl_bitdef.h @@ -1,3 +1,22 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ #ifndef __RTL8712_FIFOCTRL_BITDEF_H__ #define __RTL8712_FIFOCTRL_BITDEF_H__ diff --git a/drivers/staging/rtl8712/rtl8712_fifoctrl_regdef.h b/drivers/staging/rtl8712/rtl8712_fifoctrl_regdef.h index c2e3af2..29b89c4 100644 --- a/drivers/staging/rtl8712/rtl8712_fifoctrl_regdef.h +++ b/drivers/staging/rtl8712/rtl8712_fifoctrl_regdef.h @@ -1,3 +1,22 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ #ifndef __RTL8712_FIFOCTRL_REGDEF_H__ #define __RTL8712_FIFOCTRL_REGDEF_H__ diff --git a/drivers/staging/rtl8712/rtl8712_gp_bitdef.h b/drivers/staging/rtl8712/rtl8712_gp_bitdef.h index 35ca809..884a821 100644 --- a/drivers/staging/rtl8712/rtl8712_gp_bitdef.h +++ b/drivers/staging/rtl8712/rtl8712_gp_bitdef.h @@ -1,3 +1,28 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Modifications for inclusion into the Linux staging tree are + * Copyright(c) 2010 Larry Finger. All rights reserved. + * + * Contact information: + * WLAN FAE <wlanfae@realtek.com> + * Larry Finger <Larry.Finger@lwfinger.net> + * + ******************************************************************************/ #ifndef __RTL8712_GP_BITDEF_H__ #define __RTL8712_GP_BITDEF_H__ diff --git a/drivers/staging/rtl8712/rtl8712_gp_regdef.h b/drivers/staging/rtl8712/rtl8712_gp_regdef.h index 17e72bd..8fc68f6 100644 --- a/drivers/staging/rtl8712/rtl8712_gp_regdef.h +++ b/drivers/staging/rtl8712/rtl8712_gp_regdef.h @@ -1,3 +1,28 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Modifications for inclusion into the Linux staging tree are + * Copyright(c) 2010 Larry Finger. All rights reserved. + * + * Contact information: + * WLAN FAE <wlanfae@realtek.com> + * Larry Finger <Larry.Finger@lwfinger.net> + * + ******************************************************************************/ #ifndef __RTL8712_GP_REGDEF_H__ #define __RTL8712_GP_REGDEF_H__ diff --git a/drivers/staging/rtl8712/rtl8712_hal.h b/drivers/staging/rtl8712/rtl8712_hal.h index c696dd8..665e718 100644 --- a/drivers/staging/rtl8712/rtl8712_hal.h +++ b/drivers/staging/rtl8712/rtl8712_hal.h @@ -1,3 +1,28 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Modifications for inclusion into the Linux staging tree are + * Copyright(c) 2010 Larry Finger. All rights reserved. + * + * Contact information: + * WLAN FAE <wlanfae@realtek.com> + * Larry Finger <Larry.Finger@lwfinger.net> + * + ******************************************************************************/ #ifndef __RTL8712_HAL_H__ #define __RTL8712_HAL_H__ diff --git a/drivers/staging/rtl8712/rtl8712_interrupt_bitdef.h b/drivers/staging/rtl8712/rtl8712_interrupt_bitdef.h index 02f2480..49598c3 100644 --- a/drivers/staging/rtl8712/rtl8712_interrupt_bitdef.h +++ b/drivers/staging/rtl8712/rtl8712_interrupt_bitdef.h @@ -1,3 +1,22 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ #ifndef __RTL8712_INTERRUPT_BITDEF_H__ #define __RTL8712_INTERRUPT_BITDEF_H__ diff --git a/drivers/staging/rtl8712/rtl8712_macsetting_bitdef.h b/drivers/staging/rtl8712/rtl8712_macsetting_bitdef.h index 74800cd..28e0a7e 100644 --- a/drivers/staging/rtl8712/rtl8712_macsetting_bitdef.h +++ b/drivers/staging/rtl8712/rtl8712_macsetting_bitdef.h @@ -1,3 +1,22 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ #ifndef __RTL8712_MACSETTING_BITDEF_H__ #define __RTL8712_MACSETTING_BITDEF_H__ diff --git a/drivers/staging/rtl8712/rtl8712_macsetting_regdef.h b/drivers/staging/rtl8712/rtl8712_macsetting_regdef.h index 00b003b..ced0da9 100644 --- a/drivers/staging/rtl8712/rtl8712_macsetting_regdef.h +++ b/drivers/staging/rtl8712/rtl8712_macsetting_regdef.h @@ -1,3 +1,22 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ #ifndef __RTL8712_MACSETTING_REGDEF_H__ #define __RTL8712_MACSETTING_REGDEF_H__ diff --git a/drivers/staging/rtl8712/rtl8712_powersave_bitdef.h b/drivers/staging/rtl8712/rtl8712_powersave_bitdef.h index 0922a8d..8fc6894 100644 --- a/drivers/staging/rtl8712/rtl8712_powersave_bitdef.h +++ b/drivers/staging/rtl8712/rtl8712_powersave_bitdef.h @@ -1,3 +1,22 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ #ifndef __RTL8712_POWERSAVE_BITDEF_H__ #define __RTL8712_POWERSAVE_BITDEF_H__ diff --git a/drivers/staging/rtl8712/rtl8712_powersave_regdef.h b/drivers/staging/rtl8712/rtl8712_powersave_regdef.h index 72927df..4632ddd 100644 --- a/drivers/staging/rtl8712/rtl8712_powersave_regdef.h +++ b/drivers/staging/rtl8712/rtl8712_powersave_regdef.h @@ -1,3 +1,22 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ #ifndef __RTL8712_POWERSAVE_REGDEF_H__ #define __RTL8712_POWERSAVE_REGDEF_H__ diff --git a/drivers/staging/rtl8712/rtl8712_ratectrl_bitdef.h b/drivers/staging/rtl8712/rtl8712_ratectrl_bitdef.h index 87048b3..6d3d6e8 100644 --- a/drivers/staging/rtl8712/rtl8712_ratectrl_bitdef.h +++ b/drivers/staging/rtl8712/rtl8712_ratectrl_bitdef.h @@ -1,3 +1,22 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ #ifndef __RTL8712_RATECTRL_BITDEF_H__ #define __RTL8712_RATECTRL_BITDEF_H__ diff --git a/drivers/staging/rtl8712/rtl8712_ratectrl_regdef.h b/drivers/staging/rtl8712/rtl8712_ratectrl_regdef.h index 31c8363..73dfc36 100644 --- a/drivers/staging/rtl8712/rtl8712_ratectrl_regdef.h +++ b/drivers/staging/rtl8712/rtl8712_ratectrl_regdef.h @@ -1,3 +1,28 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Modifications for inclusion into the Linux staging tree are + * Copyright(c) 2010 Larry Finger. All rights reserved. + * + * Contact information: + * WLAN FAE <wlanfae@realtek.com> + * Larry Finger <Larry.Finger@lwfinger.net> + * + ******************************************************************************/ #ifndef __RTL8712_RATECTRL_REGDEF_H__ #define __RTL8712_RATECTRL_REGDEF_H__ diff --git a/drivers/staging/rtl8712/rtl8712_regdef.h b/drivers/staging/rtl8712/rtl8712_regdef.h index 5b0de2a..e7bca55 100644 --- a/drivers/staging/rtl8712/rtl8712_regdef.h +++ b/drivers/staging/rtl8712/rtl8712_regdef.h @@ -1,3 +1,28 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Modifications for inclusion into the Linux staging tree are + * Copyright(c) 2010 Larry Finger. All rights reserved. + * + * Contact information: + * WLAN FAE <wlanfae@realtek.com> + * Larry Finger <Larry.Finger@lwfinger.net> + * + ******************************************************************************/ #ifndef __RTL8712_REGDEF_H__ #define __RTL8712_REGDEF_H__ diff --git a/drivers/staging/rtl8712/rtl8712_security_bitdef.h b/drivers/staging/rtl8712/rtl8712_security_bitdef.h index 8df4bf4..05dafa0 100644 --- a/drivers/staging/rtl8712/rtl8712_security_bitdef.h +++ b/drivers/staging/rtl8712/rtl8712_security_bitdef.h @@ -1,3 +1,22 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ #ifndef __RTL8712_SECURITY_BITDEF_H__ #define __RTL8712_SECURITY_BITDEF_H__ diff --git a/drivers/staging/rtl8712/rtl8712_spec.h b/drivers/staging/rtl8712/rtl8712_spec.h index 3f181ee..af11b44 100644 --- a/drivers/staging/rtl8712/rtl8712_spec.h +++ b/drivers/staging/rtl8712/rtl8712_spec.h @@ -1,3 +1,28 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Modifications for inclusion into the Linux staging tree are + * Copyright(c) 2010 Larry Finger. All rights reserved. + * + * Contact information: + * WLAN FAE <wlanfae@realtek.com> + * Larry Finger <Larry.Finger@lwfinger.net> + * + ******************************************************************************/ #ifndef __RTL8712_SPEC_H__ #define __RTL8712_SPEC_H__ diff --git a/drivers/staging/rtl8712/rtl8712_syscfg_bitdef.h b/drivers/staging/rtl8712/rtl8712_syscfg_bitdef.h index dce15c2..eed09c8 100644 --- a/drivers/staging/rtl8712/rtl8712_syscfg_bitdef.h +++ b/drivers/staging/rtl8712/rtl8712_syscfg_bitdef.h @@ -1,3 +1,28 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Modifications for inclusion into the Linux staging tree are + * Copyright(c) 2010 Larry Finger. All rights reserved. + * + * Contact information: + * WLAN FAE <wlanfae@realtek.com> + * Larry Finger <Larry.Finger@lwfinger.net> + * + ******************************************************************************/ #ifndef __RTL8712_SYSCFG_BITDEF_H__ #define __RTL8712_SYSCFG_BITDEF_H__ diff --git a/drivers/staging/rtl8712/rtl8712_syscfg_regdef.h b/drivers/staging/rtl8712/rtl8712_syscfg_regdef.h index 687e1b7..767dfdf 100644 --- a/drivers/staging/rtl8712/rtl8712_syscfg_regdef.h +++ b/drivers/staging/rtl8712/rtl8712_syscfg_regdef.h @@ -1,3 +1,28 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Modifications for inclusion into the Linux staging tree are + * Copyright(c) 2010 Larry Finger. All rights reserved. + * + * Contact information: + * WLAN FAE <wlanfae@realtek.com> + * Larry Finger <Larry.Finger@lwfinger.net> + * + ******************************************************************************/ #ifndef __RTL8712_SYSCFG_REGDEF_H__ #define __RTL8712_SYSCFG_REGDEF_H__ diff --git a/drivers/staging/rtl8712/rtl8712_timectrl_bitdef.h b/drivers/staging/rtl8712/rtl8712_timectrl_bitdef.h index 32ce9fa..7244215 100644 --- a/drivers/staging/rtl8712/rtl8712_timectrl_bitdef.h +++ b/drivers/staging/rtl8712/rtl8712_timectrl_bitdef.h @@ -1,3 +1,22 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ #ifndef __RTL8712_TIMECTRL_BITDEF_H__ #define __RTL8712_TIMECTRL_BITDEF_H__ diff --git a/drivers/staging/rtl8712/rtl8712_timectrl_regdef.h b/drivers/staging/rtl8712/rtl8712_timectrl_regdef.h index 8a3dd56..106916c 100644 --- a/drivers/staging/rtl8712/rtl8712_timectrl_regdef.h +++ b/drivers/staging/rtl8712/rtl8712_timectrl_regdef.h @@ -1,3 +1,22 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ #ifndef __RTL8712_TIMECTRL_REGDEF_H__ #define __RTL8712_TIMECTRL_REGDEF_H__ diff --git a/drivers/staging/rtl8712/rtl8712_wmac_bitdef.h b/drivers/staging/rtl8712/rtl8712_wmac_bitdef.h index 6d3be2a..61a3603 100644 --- a/drivers/staging/rtl8712/rtl8712_wmac_bitdef.h +++ b/drivers/staging/rtl8712/rtl8712_wmac_bitdef.h @@ -1,3 +1,28 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Modifications for inclusion into the Linux staging tree are + * Copyright(c) 2010 Larry Finger. All rights reserved. + * + * Contact information: + * WLAN FAE <wlanfae@realtek.com> + * Larry Finger <Larry.Finger@lwfinger.net> + * + ******************************************************************************/ #ifndef __RTL8712_WMAC_BITDEF_H__ #define __RTL8712_WMAC_BITDEF_H__ diff --git a/drivers/staging/rtl8712/rtl8712_wmac_regdef.h b/drivers/staging/rtl8712/rtl8712_wmac_regdef.h index ac80dfb..d9f8347 100644 --- a/drivers/staging/rtl8712/rtl8712_wmac_regdef.h +++ b/drivers/staging/rtl8712/rtl8712_wmac_regdef.h @@ -1,3 +1,28 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Modifications for inclusion into the Linux staging tree are + * Copyright(c) 2010 Larry Finger. All rights reserved. + * + * Contact information: + * WLAN FAE <wlanfae@realtek.com> + * Larry Finger <Larry.Finger@lwfinger.net> + * + ******************************************************************************/ #ifndef __RTL8712_WMAC_REGDEF_H__ #define __RTL8712_WMAC_REGDEF_H__ diff --git a/drivers/staging/rtl8712/rtl871x_byteorder.h b/drivers/staging/rtl8712/rtl871x_byteorder.h index 07707e2..bd3703b 100644 --- a/drivers/staging/rtl8712/rtl871x_byteorder.h +++ b/drivers/staging/rtl8712/rtl871x_byteorder.h @@ -1,3 +1,22 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ #ifndef _RTL871X_BYTEORDER_H_ #define _RTL871X_BYTEORDER_H_ diff --git a/drivers/staging/rtl8712/rtl871x_eeprom.h b/drivers/staging/rtl8712/rtl871x_eeprom.h index fb15f5b..497276e 100644 --- a/drivers/staging/rtl8712/rtl871x_eeprom.h +++ b/drivers/staging/rtl8712/rtl871x_eeprom.h @@ -1,3 +1,22 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * + ******************************************************************************/ #ifndef __RTL871X_EEPROM_H__ #define __RTL871X_EEPROM_H__ diff --git a/drivers/staging/rtl8712/rtl871x_event.h b/drivers/staging/rtl8712/rtl871x_event.h index 6ce0676..e03ee90 100644 --- a/drivers/staging/rtl8712/rtl871x_event.h +++ b/drivers/staging/rtl8712/rtl871x_event.h @@ -1,3 +1,28 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Modifications for inclusion into the Linux staging tree are + * Copyright(c) 2010 Larry Finger. All rights reserved. + * + * Contact information: + * WLAN FAE <wlanfae@realtek.com> + * Larry Finger <Larry.Finger@lwfinger.net> + * + ******************************************************************************/ #ifndef _RTL871x_EVENT_H_ #define _RTL871x_EVENT_H_ diff --git a/drivers/staging/rtl8712/rtl871x_ht.h b/drivers/staging/rtl8712/rtl871x_ht.h index 612203d..41872d9 100644 --- a/drivers/staging/rtl8712/rtl871x_ht.h +++ b/drivers/staging/rtl8712/rtl871x_ht.h @@ -1,3 +1,28 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Modifications for inclusion into the Linux staging tree are + * Copyright(c) 2010 Larry Finger. All rights reserved. + * + * Contact information: + * WLAN FAE <wlanfae@realtek.com> + * Larry Finger <Larry.Finger@lwfinger.net> + * + ******************************************************************************/ #ifndef _RTL871X_HT_H_ #define _RTL871X_HT_H_ diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c index 40e6b5c..d310a61 100644 --- a/drivers/staging/rtl8712/rtl871x_ioctl_linux.c +++ b/drivers/staging/rtl8712/rtl871x_ioctl_linux.c @@ -975,6 +975,13 @@ static int r871x_wx_set_priv(struct net_device *dev, * s2. set_802_11_authentication_mode() * s3. set_802_11_encryption_mode() * s4. set_802_11_bssid() + * + * This function intends to handle the Set AP command, which specifies the + * MAC# of a preferred Access Point. + * Currently, the request comes via Wireless Extensions' SIOCSIWAP ioctl. + * + * For this operation to succeed, there is no need for the interface to be Up. + * */ static int r8711_wx_set_wap(struct net_device *dev, struct iw_request_info *info, @@ -992,8 +999,6 @@ static int r8711_wx_set_wap(struct net_device *dev, struct wlan_network *pnetwork = NULL; enum NDIS_802_11_AUTHENTICATION_MODE authmode; - if (padapter->bup == false) - return -1; if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY) == true) return -1; if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING) == true) @@ -1074,6 +1079,14 @@ static int r871x_wx_set_mlme(struct net_device *dev, return ret; } +/** + * + * This function intends to handle the Set Scan command. + * Currently, the request comes via Wireless Extensions' SIOCSIWSCAN ioctl. + * + * For this operation to succeed, the interface is brought Up beforehand. + * + */ static int r8711_wx_set_scan(struct net_device *dev, struct iw_request_info *a, union iwreq_data *wrqu, char *extra) @@ -1169,6 +1182,12 @@ static int r8711_wx_get_scan(struct net_device *dev, * s2. set_802_11_authenticaion_mode() * s3. set_802_11_encryption_mode() * s4. set_802_11_ssid() + * + * This function intends to handle the Set ESSID command. + * Currently, the request comes via the Wireless Extensions' SIOCSIWESSID ioctl. + * + * For this operation to succeed, there is no need for the interface to be Up. + * */ static int r8711_wx_set_essid(struct net_device *dev, struct iw_request_info *a, @@ -1184,8 +1203,6 @@ static int r8711_wx_set_essid(struct net_device *dev, struct list_head *phead; u32 len; - if (padapter->bup == false) - return -1; if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY)) return -1; if (check_fwstate(pmlmepriv, _FW_UNDER_LINKING)) @@ -2072,9 +2089,10 @@ static int wpa_supplicant_ioctl(struct net_device *dev, struct iw_point *p) param = (struct ieee_param *)_malloc(p->length); if (param == NULL) return -ENOMEM; - if (copy_from_user(param, p->pointer, p->length)) + if (copy_from_user(param, p->pointer, p->length)) { kfree((u8 *)param); return -EFAULT; + } switch (param->cmd) { case IEEE_CMD_SET_WPA_PARAM: ret = wpa_set_param(dev, param->u.wpa_param.name, diff --git a/drivers/staging/rtl8712/rtl871x_ioctl_set.h b/drivers/staging/rtl8712/rtl871x_ioctl_set.h index 8dff2b1..de0a848 100644 --- a/drivers/staging/rtl8712/rtl871x_ioctl_set.h +++ b/drivers/staging/rtl8712/rtl871x_ioctl_set.h @@ -1,3 +1,28 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Modifications for inclusion into the Linux staging tree are + * Copyright(c) 2010 Larry Finger. All rights reserved. + * + * Contact information: + * WLAN FAE <wlanfae@realtek.com> + * Larry Finger <Larry.Finger@lwfinger.net> + * + ******************************************************************************/ #ifndef __IOCTL_SET_H #define __IOCTL_SET_H diff --git a/drivers/staging/rtl8712/rtl871x_mp.h b/drivers/staging/rtl8712/rtl871x_mp.h index 805aba0..a42d4f4 100644 --- a/drivers/staging/rtl8712/rtl871x_mp.h +++ b/drivers/staging/rtl8712/rtl871x_mp.h @@ -1,3 +1,28 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Modifications for inclusion into the Linux staging tree are + * Copyright(c) 2010 Larry Finger. All rights reserved. + * + * Contact information: + * WLAN FAE <wlanfae@realtek.com> + * Larry Finger <Larry.Finger@lwfinger.net> + * + ******************************************************************************/ #ifndef __RTL871X_MP_H_ #define __RTL871X_MP_H_ diff --git a/drivers/staging/rtl8712/rtl871x_pwrctrl.h b/drivers/staging/rtl8712/rtl871x_pwrctrl.h index 34f074a..b41ca28 100644 --- a/drivers/staging/rtl8712/rtl871x_pwrctrl.h +++ b/drivers/staging/rtl8712/rtl871x_pwrctrl.h @@ -1,3 +1,28 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Modifications for inclusion into the Linux staging tree are + * Copyright(c) 2010 Larry Finger. All rights reserved. + * + * Contact information: + * WLAN FAE <wlanfae@realtek.com> + * Larry Finger <Larry.Finger@lwfinger.net> + * + ******************************************************************************/ #ifndef __RTL871X_PWRCTRL_H_ #define __RTL871X_PWRCTRL_H_ diff --git a/drivers/staging/rtl8712/rtl871x_rf.h b/drivers/staging/rtl8712/rtl871x_rf.h index 6c54966..133ed64 100644 --- a/drivers/staging/rtl8712/rtl871x_rf.h +++ b/drivers/staging/rtl8712/rtl871x_rf.h @@ -1,3 +1,28 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Modifications for inclusion into the Linux staging tree are + * Copyright(c) 2010 Larry Finger. All rights reserved. + * + * Contact information: + * WLAN FAE <wlanfae@realtek.com> + * Larry Finger <Larry.Finger@lwfinger.net> + * + ******************************************************************************/ #ifndef __RTL871X_RF_H_ #define __RTL871X_RF_H_ diff --git a/drivers/staging/rtl8712/rtl871x_security.h b/drivers/staging/rtl8712/rtl871x_security.h index bff71d2..a13395f 100644 --- a/drivers/staging/rtl8712/rtl871x_security.h +++ b/drivers/staging/rtl8712/rtl871x_security.h @@ -1,3 +1,28 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Modifications for inclusion into the Linux staging tree are + * Copyright(c) 2010 Larry Finger. All rights reserved. + * + * Contact information: + * WLAN FAE <wlanfae@realtek.com> + * Larry Finger <Larry.Finger@lwfinger.net> + * + ******************************************************************************/ #ifndef __RTL871X_SECURITY_H_ #define __RTL871X_SECURITY_H_ diff --git a/drivers/staging/rtl8712/rtl871x_wlan_sme.h b/drivers/staging/rtl8712/rtl871x_wlan_sme.h index d9733ac..44924d5 100644 --- a/drivers/staging/rtl8712/rtl871x_wlan_sme.h +++ b/drivers/staging/rtl8712/rtl871x_wlan_sme.h @@ -1,3 +1,28 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Modifications for inclusion into the Linux staging tree are + * Copyright(c) 2010 Larry Finger. All rights reserved. + * + * Contact information: + * WLAN FAE <wlanfae@realtek.com> + * Larry Finger <Larry.Finger@lwfinger.net> + * + ******************************************************************************/ #ifndef _RTL871X_WLAN_SME_H_ #define _RTL871X_WLAN_SME_H_ diff --git a/drivers/staging/rtl8712/swab.h b/drivers/staging/rtl8712/swab.h index 44709a9..f127818 100644 --- a/drivers/staging/rtl8712/swab.h +++ b/drivers/staging/rtl8712/swab.h @@ -1,3 +1,28 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Modifications for inclusion into the Linux staging tree are + * Copyright(c) 2010 Larry Finger. All rights reserved. + * + * Contact information: + * WLAN FAE <wlanfae@realtek.com> + * Larry Finger <Larry.Finger@lwfinger.net> + * + ******************************************************************************/ #ifndef _LINUX_BYTEORDER_SWAB_H #define _LINUX_BYTEORDER_SWAB_H diff --git a/drivers/staging/rtl8712/usb_ops.h b/drivers/staging/rtl8712/usb_ops.h index dc0611a..78e775a 100644 --- a/drivers/staging/rtl8712/usb_ops.h +++ b/drivers/staging/rtl8712/usb_ops.h @@ -1,3 +1,28 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Modifications for inclusion into the Linux staging tree are + * Copyright(c) 2010 Larry Finger. All rights reserved. + * + * Contact information: + * WLAN FAE <wlanfae@realtek.com> + * Larry Finger <Larry.Finger@lwfinger.net> + * + ******************************************************************************/ #ifndef __USB_OPS_H_ #define __USB_OPS_H_ diff --git a/drivers/staging/rtl8712/usb_osintf.h b/drivers/staging/rtl8712/usb_osintf.h index 0da6c1d..d397a82 100644 --- a/drivers/staging/rtl8712/usb_osintf.h +++ b/drivers/staging/rtl8712/usb_osintf.h @@ -1,3 +1,28 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Modifications for inclusion into the Linux staging tree are + * Copyright(c) 2010 Larry Finger. All rights reserved. + * + * Contact information: + * WLAN FAE <wlanfae@realtek.com> + * Larry Finger <Larry.Finger@lwfinger.net> + * + ******************************************************************************/ #ifndef __USB_OSINTF_H #define __USB_OSINTF_H diff --git a/drivers/staging/rtl8712/usb_vendor_req.h b/drivers/staging/rtl8712/usb_vendor_req.h index d35c538..82335a8 100644 --- a/drivers/staging/rtl8712/usb_vendor_req.h +++ b/drivers/staging/rtl8712/usb_vendor_req.h @@ -1,3 +1,28 @@ +/****************************************************************************** + * + * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA + * + * Modifications for inclusion into the Linux staging tree are + * Copyright(c) 2010 Larry Finger. All rights reserved. + * + * Contact information: + * WLAN FAE <wlanfae@realtek.com> + * Larry Finger <Larry.Finger@lwfinger.net> + * + ******************************************************************************/ #ifndef _USB_VENDOR_REQUEST_H_ #define _USB_VENDOR_REQUEST_H_ diff --git a/drivers/staging/rts5139/Kconfig b/drivers/staging/rts5139/Kconfig new file mode 100644 index 0000000..afd526b --- /dev/null +++ b/drivers/staging/rts5139/Kconfig @@ -0,0 +1,16 @@ +config RTS5139 + tristate "Realtek RTS5139 USB card reader support" + depends on USB && SCSI + help + Say Y here to include driver code to support the Realtek + RTS5139 USB card readers. + + If this driver is compiled as a module, it will be named rts5139. + +config RTS5139_DEBUG + bool "Realtek RTS5139 Card Reader verbose debug" + depends on RTS5139 + help + Say Y here in order to have the rts5139 code generate + verbose debugging messages. + diff --git a/drivers/staging/rts5139/Makefile b/drivers/staging/rts5139/Makefile new file mode 100644 index 0000000..82b8958 --- /dev/null +++ b/drivers/staging/rts5139/Makefile @@ -0,0 +1,37 @@ +# Driver for Realtek RTS51xx USB card reader +# +# Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2, or (at your option) any +# later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, see <http://www.gnu.org/licenses/>. +# +# Author: +# wwang (wei_wang@realsil.com.cn) +# No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China +# Maintainer: +# Edwin Rong (edwin_rong@realsil.com.cn) +# No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China +# +# Makefile for the RTS51xx USB Card Reader drivers. +# + +TARGET_MODULE := rts5139 + +EXTRA_CFLAGS := -Idrivers/scsi -I$(PWD) + +obj-m += $(TARGET_MODULE).o + +common-obj := rts51x_transport.o rts51x_scsi.o rts51x_fop.o + +$(TARGET_MODULE)-objs := $(common-obj) rts51x.o rts51x_chip.o rts51x_card.o \ + xd.o sd.o ms.o sd_cprm.o ms_mg.o diff --git a/drivers/staging/rts5139/TODO b/drivers/staging/rts5139/TODO new file mode 100644 index 0000000..4bde726 --- /dev/null +++ b/drivers/staging/rts5139/TODO @@ -0,0 +1,5 @@ +TODO: +- support more USB card reader of Realtek family +- use kernel coding style +- checkpatch.pl fixes + diff --git a/drivers/staging/rts5139/debug.h b/drivers/staging/rts5139/debug.h new file mode 100644 index 0000000..73dec13 --- /dev/null +++ b/drivers/staging/rts5139/debug.h @@ -0,0 +1,46 @@ +/* Driver for Realtek RTS51xx USB card reader + * Header file + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + * Maintainer: + * Edwin Rong (edwin_rong@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#ifndef __RTS51X_DEBUG_H +#define __RTS51X_DEBUG_H + +#include <linux/kernel.h> + +#define RTS51X_TIP "rts51x: " + +#ifdef CONFIG_RTS5139_DEBUG +#define RTS51X_DEBUGP(x...) printk(KERN_DEBUG RTS51X_TIP x) +#define RTS51X_DEBUGPN(x...) printk(KERN_DEBUG x) +#define RTS51X_DEBUGPX(x...) printk(x) +#define RTS51X_DEBUG(x) x +#else +#define RTS51X_DEBUGP(x...) +#define RTS51X_DEBUGPN(x...) +#define RTS51X_DEBUGPX(x...) +#define RTS51X_DEBUG(x) +#endif + +#endif /* __RTS51X_DEBUG_H */ diff --git a/drivers/staging/rts5139/ms.c b/drivers/staging/rts5139/ms.c new file mode 100644 index 0000000..b0e9071 --- /dev/null +++ b/drivers/staging/rts5139/ms.c @@ -0,0 +1,4191 @@ +/* Driver for Realtek RTS51xx USB card reader + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + * Maintainer: + * Edwin Rong (edwin_rong@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#include <linux/blkdev.h> +#include <linux/kthread.h> +#include <linux/sched.h> +#include <linux/slab.h> +#include <linux/vmalloc.h> + +#include "debug.h" +#include "trace.h" +#include "rts51x.h" +#include "rts51x_transport.h" +#include "rts51x_scsi.h" +#include "rts51x_card.h" +#include "ms.h" + +static inline void ms_set_err_code(struct rts51x_chip *chip, u8 err_code) +{ + struct ms_info *ms_card = &(chip->ms_card); + + ms_card->err_code = err_code; +} + +static inline int ms_check_err_code(struct rts51x_chip *chip, u8 err_code) +{ + struct ms_info *ms_card = &(chip->ms_card); + + return (ms_card->err_code == err_code); +} + +static int ms_parse_err_code(struct rts51x_chip *chip) +{ + TRACE_RET(chip, STATUS_FAIL); +} + +static int ms_transfer_tpc(struct rts51x_chip *chip, u8 trans_mode, u8 tpc, + u8 cnt, u8 cfg) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + + RTS51X_DEBUGP("ms_transfer_tpc: tpc = 0x%x\n", tpc); + + rts51x_init_cmd(chip); + + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt); + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, + PINGPONG_BUFFER); + + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, + MS_TRANSFER_START | trans_mode); + rts51x_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, MS_TRANSFER_END, + MS_TRANSFER_END); + + rts51x_add_cmd(chip, READ_REG_CMD, MS_TRANS_CFG, 0, 0); + + retval = rts51x_send_cmd(chip, MODE_CR, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = rts51x_get_rsp(chip, 2, 5000); + if (CHECK_MS_TRANS_FAIL(chip, retval)) { + rts51x_clear_ms_error(chip); + ms_set_err_code(chip, MS_TO_ERROR); + TRACE_RET(chip, ms_parse_err_code(chip)); + } + + if (!(tpc & 0x08)) { /* Read Packet */ + /* Check CRC16 & Ready Timeout */ + if (chip->rsp_buf[1] & MS_CRC16_ERR) { + ms_set_err_code(chip, MS_CRC16_ERROR); + TRACE_RET(chip, ms_parse_err_code(chip)); + } + } else { /* Write Packet */ + if (CHK_MSPRO(ms_card) && !(chip->rsp_buf[1] & 0x80)) { + if (chip->rsp_buf[1] & (MS_INT_ERR | MS_INT_CMDNK)) { + ms_set_err_code(chip, MS_CMD_NK); + TRACE_RET(chip, ms_parse_err_code(chip)); + } + } + } + + /* Check Timeout of Ready Signal */ + if (chip->rsp_buf[1] & MS_RDY_TIMEOUT) { + rts51x_clear_ms_error(chip); + ms_set_err_code(chip, MS_TO_ERROR); + TRACE_RET(chip, ms_parse_err_code(chip)); + } + + return STATUS_SUCCESS; +} + +int ms_transfer_data(struct rts51x_chip *chip, u8 trans_mode, u8 tpc, + u16 sec_cnt, u8 cfg, int mode_2k, int use_sg, void *buf, + int buf_len) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + u8 val, err_code = 0, flag = 0; + enum dma_data_direction dir; + unsigned int pipe; + + if (!buf || !buf_len) + TRACE_RET(chip, STATUS_FAIL); + + if (trans_mode == MS_TM_AUTO_READ) { + pipe = RCV_BULK_PIPE(chip); + dir = DMA_FROM_DEVICE; + flag = MODE_CDIR; + err_code = MS_FLASH_READ_ERROR; + } else if (trans_mode == MS_TM_AUTO_WRITE) { + pipe = SND_BULK_PIPE(chip); + dir = DMA_TO_DEVICE; + flag = MODE_CDOR; + err_code = MS_FLASH_WRITE_ERROR; + } else { + TRACE_RET(chip, STATUS_FAIL); + } + + rts51x_init_cmd(chip); + + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_SECTOR_CNT_H, 0xFF, + (u8) (sec_cnt >> 8)); + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_SECTOR_CNT_L, 0xFF, + (u8) sec_cnt); + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, + RING_BUFFER); + + if (mode_2k) + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_CFG, MS_2K_SECTOR_MODE, + MS_2K_SECTOR_MODE); + else + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_CFG, MS_2K_SECTOR_MODE, + 0); + + trans_dma_enable(dir, chip, sec_cnt * 512, DMA_512); + + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, + MS_TRANSFER_START | trans_mode); + rts51x_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, MS_TRANSFER_END, + MS_TRANSFER_END); + + retval = rts51x_send_cmd(chip, flag | STAGE_MS_STATUS, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = + rts51x_transfer_data_rcc(chip, pipe, buf, buf_len, use_sg, NULL, + 15000, flag); + if (retval != STATUS_SUCCESS) { + ms_set_err_code(chip, err_code); + rts51x_clear_ms_error(chip); + TRACE_RET(chip, retval); + } + + retval = rts51x_get_rsp(chip, 3, 15000); + if (CHECK_MS_TRANS_FAIL(chip, retval)) { + ms_set_err_code(chip, err_code); + rts51x_clear_ms_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + ms_card->last_rw_int = val = chip->rsp_buf[1]; + if (val & (MS_INT_CMDNK | MS_INT_ERR | MS_CRC16_ERR | MS_RDY_TIMEOUT)) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +int ms_write_bytes(struct rts51x_chip *chip, u8 tpc, u8 cnt, u8 cfg, u8 *data, + int data_len) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i; + + if (!data || (data_len < cnt)) + TRACE_RET(chip, STATUS_ERROR); + + rts51x_init_cmd(chip); + + for (i = 0; i < cnt; i++) { + rts51x_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2 + i, 0xFF, + data[i]); + } + if (cnt % 2) + rts51x_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2 + i, + 0xFF, 0xFF); + + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt); + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, + PINGPONG_BUFFER); + + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, + MS_TRANSFER_START | MS_TM_WRITE_BYTES); + rts51x_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, MS_TRANSFER_END, + MS_TRANSFER_END); + + retval = rts51x_send_cmd(chip, MODE_CR, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = rts51x_get_rsp(chip, 1, 5000); + if (CHECK_MS_TRANS_FAIL(chip, retval)) { + u8 val = 0; + + rts51x_ep0_read_register(chip, MS_TRANS_CFG, &val); + RTS51X_DEBUGP("MS_TRANS_CFG: 0x%02x\n", val); + + rts51x_clear_ms_error(chip); + + if (!(tpc & 0x08)) { /* Read Packet */ + /* Check CRC16 & Ready Timeout */ + if (val & MS_CRC16_ERR) { + ms_set_err_code(chip, MS_CRC16_ERROR); + TRACE_RET(chip, ms_parse_err_code(chip)); + } + } else { /* Write Packet */ + if (CHK_MSPRO(ms_card) && !(val & 0x80)) { + if (val & (MS_INT_ERR | MS_INT_CMDNK)) { + ms_set_err_code(chip, MS_CMD_NK); + TRACE_RET(chip, + ms_parse_err_code(chip)); + } + } + } + + /* Check Timeout of Ready Signal */ + if (val & MS_RDY_TIMEOUT) { + ms_set_err_code(chip, MS_TO_ERROR); + TRACE_RET(chip, ms_parse_err_code(chip)); + } + + ms_set_err_code(chip, MS_TO_ERROR); + TRACE_RET(chip, ms_parse_err_code(chip)); + } + + return STATUS_SUCCESS; +} + +int ms_read_bytes(struct rts51x_chip *chip, u8 tpc, u8 cnt, u8 cfg, u8 *data, + int data_len) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i; + + if (!data) + TRACE_RET(chip, STATUS_ERROR); + + rts51x_init_cmd(chip); + + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, tpc); + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_BYTE_CNT, 0xFF, cnt); + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, + PINGPONG_BUFFER); + + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, + MS_TRANSFER_START | MS_TM_READ_BYTES); + rts51x_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, MS_TRANSFER_END, + MS_TRANSFER_END); + + for (i = 0; i < data_len - 1; i++) + rts51x_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + i, 0, 0); + + if (data_len % 2) + rts51x_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + data_len, 0, + 0); + else + rts51x_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + data_len - 1, + 0, 0); + + retval = rts51x_send_cmd(chip, MODE_CR, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = rts51x_get_rsp(chip, data_len + 1, 5000); + if (CHECK_MS_TRANS_FAIL(chip, retval)) { + u8 val = 0; + + rts51x_ep0_read_register(chip, MS_TRANS_CFG, &val); + RTS51X_DEBUGP("MS_TRANS_CFG: 0x%02x\n", val); + + rts51x_clear_ms_error(chip); + + if (!(tpc & 0x08)) { /* Read Packet */ + /* Check CRC16 & Ready Timeout */ + if (val & MS_CRC16_ERR) { + ms_set_err_code(chip, MS_CRC16_ERROR); + TRACE_RET(chip, ms_parse_err_code(chip)); + } + } else { /* Write Packet */ + if (CHK_MSPRO(ms_card) && !(val & 0x80)) { + if (val & (MS_INT_ERR | MS_INT_CMDNK)) { + ms_set_err_code(chip, MS_CMD_NK); + TRACE_RET(chip, + ms_parse_err_code(chip)); + } + } + } + + /* Check Timeout of Ready Signal */ + if (val & MS_RDY_TIMEOUT) { + ms_set_err_code(chip, MS_TO_ERROR); + TRACE_RET(chip, ms_parse_err_code(chip)); + } + + ms_set_err_code(chip, MS_TO_ERROR); + TRACE_RET(chip, ms_parse_err_code(chip)); + } + + rts51x_read_rsp_buf(chip, 1, data, data_len); + + return STATUS_SUCCESS; +} + +int ms_set_rw_reg_addr(struct rts51x_chip *chip, + u8 read_start, u8 read_cnt, u8 write_start, u8 write_cnt) +{ + int retval, i; + u8 data[4]; + + data[0] = read_start; + data[1] = read_cnt; + data[2] = write_start; + data[3] = write_cnt; + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = + ms_write_bytes(chip, SET_RW_REG_ADRS, 4, NO_WAIT_INT, data, + 4); + if (retval == STATUS_SUCCESS) + return STATUS_SUCCESS; + rts51x_clear_ms_error(chip); + } + + TRACE_RET(chip, STATUS_FAIL); +} + +static int ms_send_cmd(struct rts51x_chip *chip, u8 cmd, u8 cfg) +{ + u8 data[2]; + + data[0] = cmd; + data[1] = 0; + + return ms_write_bytes(chip, PRO_SET_CMD, 1, cfg, data, 1); +} + +static int ms_set_cmd(struct rts51x_chip *chip, + u8 read_start, u8 read_count, + u8 write_start, u8 write_count, + u8 cmd, u8 cfg, u8 *data, int data_len, u8 *int_stat) +{ + int retval, i; + u8 val; + + if (!data || (data_len <= 0) || (data_len > 128)) { + RTS51X_DEBUGP("ms_set_cmd (data_len = %d)\n", data_len); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = + ms_set_rw_reg_addr(chip, read_start, read_count, write_start, + write_count); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = + ms_write_bytes(chip, WRITE_REG, write_count, NO_WAIT_INT, + data, data_len); + if (retval == STATUS_SUCCESS) + break; + } + if (i == MS_MAX_RETRY_COUNT) + TRACE_RET(chip, STATUS_FAIL); + + ms_set_err_code(chip, MS_NO_ERROR); + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = ms_send_cmd(chip, cmd, WAIT_INT); + if (retval == STATUS_SUCCESS) + break; + } + if (i == MS_MAX_RETRY_COUNT) + TRACE_RET(chip, STATUS_FAIL); + /* GET_INT Register */ + ms_set_err_code(chip, MS_NO_ERROR); + retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + if (int_stat) + *int_stat = val; + + return STATUS_SUCCESS; +} + +#ifdef MS_SPEEDUP +static int ms_auto_set_cmd(struct rts51x_chip *chip, + u8 read_start, u8 read_count, + u8 write_start, u8 write_count, + u8 cmd, u8 cfg, u8 *data, int data_len, + u8 *int_stat) +{ + int retval; + int i; + + if (!data || (data_len <= 0) || (data_len > 128)) { + RTS51X_DEBUGP("ms_auto_set_cmd (data_len = %d)\n", data_len); + TRACE_RET(chip, STATUS_FAIL); + } + + rts51x_init_cmd(chip); + + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_READ_START, 0xFF, read_start); + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_READ_COUNT, 0xFF, read_count); + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_WRITE_START, 0xFF, write_start); + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_WRITE_COUNT, 0xFF, write_count); + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_COMMAND, 0xFF, cmd); + + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, cfg); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, + PINGPONG_BUFFER); + + for (i = 0; i < data_len; i++) { + rts51x_add_cmd(chip, WRITE_REG_CMD, PPBUF_BASE2 + i, 0xFF, + data[i]); + } + + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, + MS_TRANSFER_START | MS_TM_SET_CMD); + rts51x_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, MS_TRANSFER_END, + MS_TRANSFER_END); + + retval = rts51x_send_cmd(chip, MODE_CR | STAGE_MS_STATUS, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = rts51x_get_rsp(chip, 3, 5000); + + if (CHECK_MS_TRANS_FAIL(chip, retval)) { + rts51x_clear_ms_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + if (int_stat) + *int_stat = chip->rsp_buf[2]; + + return STATUS_SUCCESS; +} +#endif + +static int ms_set_init_para(struct rts51x_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + + if (CHK_HG8BIT(ms_card)) { + if (chip->asic_code) + ms_card->ms_clock = chip->option.asic_ms_hg_clk; + else + ms_card->ms_clock = chip->option.fpga_ms_hg_clk; + } else if (CHK_MSPRO(ms_card) || CHK_MS4BIT(ms_card)) { + if (chip->asic_code) + ms_card->ms_clock = chip->option.asic_ms_4bit_clk; + else + ms_card->ms_clock = chip->option.fpga_ms_4bit_clk; + } else { + if (chip->asic_code) + ms_card->ms_clock = 38; + else + ms_card->ms_clock = CLK_40; + } + + retval = switch_clock(chip, ms_card->ms_clock); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = rts51x_select_card(chip, MS_CARD); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + return STATUS_SUCCESS; +} + +int ms_switch_clock(struct rts51x_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + + retval = rts51x_select_card(chip, MS_CARD); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = switch_clock(chip, ms_card->ms_clock); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + return STATUS_SUCCESS; +} + +static void ms_pull_ctl_disable(struct rts51x_chip *chip) +{ + if (CHECK_PKG(chip, LQFP48)) { + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x55); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x95); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x55); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0xA5); + } else { + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x65); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x95); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x56); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0x59); + } +} + +static void ms_pull_ctl_enable(struct rts51x_chip *chip) +{ + if (CHECK_PKG(chip, LQFP48)) { + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x55); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x95); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x55); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0xA5); + } else { + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x65); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x95); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x55); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0x59); + } +} + +static int ms_prepare_reset(struct rts51x_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + + ms_card->ms_type = 0; + ms_card->check_ms_flow = 0; + ms_card->switch_8bit_fail = 0; + ms_card->delay_write.delay_write_flag = 0; + + ms_card->pro_under_formatting = 0; + + rts51x_init_cmd(chip); + + if (chip->asic_code) { + ms_pull_ctl_enable(chip); + } else { + rts51x_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, + FPGA_MS_PULL_CTL_BIT | 0x20, 0); + } + /* Tri-state MS output */ + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_OE, MS_OUTPUT_EN, 0); + + if (!chip->option.FT2_fast_mode) { + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, POWER_MASK, + POWER_OFF); + } + + retval = rts51x_send_cmd(chip, MODE_C, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + if (!chip->option.FT2_fast_mode) { + wait_timeout(250); + + card_power_on(chip, MS_CARD); + wait_timeout(150); + +#ifdef SUPPORT_OCP + rts51x_get_card_status(chip, &(chip->card_status)); + /* get OCP status */ + chip->ocp_stat = (chip->card_status >> 4) & 0x03; + + if (chip->ocp_stat & (MS_OCP_NOW | MS_OCP_EVER)) { + RTS51X_DEBUGP("Over current, OCPSTAT is 0x%x\n", + chip->ocp_stat); + TRACE_RET(chip, STATUS_FAIL); + } +#endif + } + + rts51x_init_cmd(chip); + + /* Enable MS Output */ + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_OE, MS_OUTPUT_EN, + MS_OUTPUT_EN); + + /* Reset Registers */ + if (chip->asic_code) + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_CFG, 0xFF, + SAMPLE_TIME_RISING | PUSH_TIME_DEFAULT | + NO_EXTEND_TOGGLE | MS_BUS_WIDTH_1); + else + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_CFG, 0xFF, + SAMPLE_TIME_FALLING | PUSH_TIME_DEFAULT | + NO_EXTEND_TOGGLE | MS_BUS_WIDTH_1); + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, + NO_WAIT_INT | NO_AUTO_READ_INT_REG); + + retval = rts51x_send_cmd(chip, MODE_C, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + return ms_set_init_para(chip); +} + +static int ms_identify_media_type(struct rts51x_chip *chip, int switch_8bit_bus) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i; + u8 val; + + retval = ms_set_rw_reg_addr(chip, Pro_StatusReg, 6, SystemParm, 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + /* Get Register form MS-PRO card */ + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = + ms_transfer_tpc(chip, MS_TM_READ_BYTES, READ_REG, 6, + NO_WAIT_INT); + if (retval == STATUS_SUCCESS) + break; + } + if (i == MS_MAX_RETRY_COUNT) + TRACE_RET(chip, STATUS_FAIL); + + RTS51X_READ_REG(chip, PPBUF_BASE2 + 2, &val); + RTS51X_DEBUGP("Type register: 0x%x\n", val); + if (val != 0x01) { + if (val != 0x02) + ms_card->check_ms_flow = 1; + TRACE_RET(chip, STATUS_FAIL); + } + /* Category Register */ + RTS51X_READ_REG(chip, PPBUF_BASE2 + 4, &val); + RTS51X_DEBUGP("Category register: 0x%x\n", val); + if (val != 0) { + ms_card->check_ms_flow = 1; + TRACE_RET(chip, STATUS_FAIL); + } + /* Class Register */ + RTS51X_READ_REG(chip, PPBUF_BASE2 + 5, &val); + RTS51X_DEBUGP("Class register: 0x%x\n", val); + if (val == 0) { + RTS51X_READ_REG(chip, PPBUF_BASE2, &val); + if (val & WRT_PRTCT) + chip->card_wp |= MS_CARD; + else + chip->card_wp &= ~MS_CARD; + } else if ((val == 0x01) || (val == 0x02) || (val == 0x03)) { + chip->card_wp |= MS_CARD; + } else { + ms_card->check_ms_flow = 1; + TRACE_RET(chip, STATUS_FAIL); + } + + ms_card->ms_type |= TYPE_MSPRO; + + /* Check MSPro-HG Card, use IF Mode Register to distinguish */ + RTS51X_READ_REG(chip, PPBUF_BASE2 + 3, &val); + RTS51X_DEBUGP("IF Mode register: 0x%x\n", val); + if (val == 0) { + ms_card->ms_type &= 0x0F; + } else if (val == 7) { + if (switch_8bit_bus) + ms_card->ms_type |= MS_HG; + else + ms_card->ms_type &= 0x0F; + } else { + TRACE_RET(chip, STATUS_FAIL); + } + + /* end Procedure to identify Media Type */ + return STATUS_SUCCESS; +} + +static int ms_confirm_cpu_startup(struct rts51x_chip *chip) +{ + int retval, i, k; + u8 val; + + /* Confirm CPU StartUp */ + k = 0; + do { + if (monitor_card_cd(chip, MS_CARD) == CD_NOT_EXIST) + TRACE_RET(chip, STATUS_FAIL); + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = + ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, + 1); + if (retval == STATUS_SUCCESS) + break; + } + if (i == MS_MAX_RETRY_COUNT) + TRACE_RET(chip, STATUS_FAIL); + + if (k > 100) + TRACE_RET(chip, STATUS_FAIL); + k++; + wait_timeout(100); + } while (!(val & INT_REG_CED)); + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); + if (retval == STATUS_SUCCESS) + break; + } + if (i == MS_MAX_RETRY_COUNT) + TRACE_RET(chip, STATUS_FAIL); + + if (val & INT_REG_ERR) { + if (val & INT_REG_CMDNK) { /* CMDNK = 1 */ + chip->card_wp |= (MS_CARD); + } else { /* CMDNK = 0 */ + TRACE_RET(chip, STATUS_FAIL); + } + } + /*-- end confirm CPU startup */ + + return STATUS_SUCCESS; +} + +static int ms_switch_parallel_bus(struct rts51x_chip *chip) +{ + int retval, i; + u8 data[2]; + + data[0] = PARALLEL_4BIT_IF; + data[1] = 0; + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = + ms_write_bytes(chip, WRITE_REG, 1, NO_WAIT_INT, data, 2); + if (retval == STATUS_SUCCESS) + break; + } + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + return STATUS_SUCCESS; +} + +static int ms_switch_8bit_bus(struct rts51x_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i; + u8 data[2]; + + data[0] = PARALLEL_8BIT_IF; + data[1] = 0; + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = + ms_write_bytes(chip, WRITE_REG, 1, NO_WAIT_INT, data, 2); + if (retval == STATUS_SUCCESS) + break; + } + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + RTS51X_WRITE_REG(chip, MS_CFG, 0x98, + MS_BUS_WIDTH_8 | SAMPLE_TIME_FALLING); + ms_card->ms_type |= MS_8BIT; + + retval = ms_set_init_para(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = + ms_transfer_tpc(chip, MS_TM_READ_BYTES, GET_INT, 1, + NO_WAIT_INT); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } + + return STATUS_SUCCESS; +} + +static int ms_pro_reset_flow(struct rts51x_chip *chip, int switch_8bit_bus) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i; + + for (i = 0; i < 3; i++) { + retval = ms_prepare_reset(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = ms_identify_media_type(chip, switch_8bit_bus); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = ms_confirm_cpu_startup(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = ms_switch_parallel_bus(chip); + if (retval != STATUS_SUCCESS) { + if (monitor_card_cd(chip, MS_CARD) == CD_NOT_EXIST) + TRACE_RET(chip, STATUS_FAIL); + continue; + } else { + break; + } + } + + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + RTS51X_WRITE_REG(chip, MS_CFG, 0x18, MS_BUS_WIDTH_4); + + RTS51X_WRITE_REG(chip, MS_CFG, PUSH_TIME_ODD, PUSH_TIME_ODD); + + retval = ms_set_init_para(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + if (CHK_MSHG(ms_card) && switch_8bit_bus) { + retval = ms_switch_8bit_bus(chip); + if (retval != STATUS_SUCCESS) { + ms_card->switch_8bit_fail = 1; + TRACE_RET(chip, retval); + } + } + + return STATUS_SUCCESS; +} + +#ifdef XC_POWERCLASS +static int msxc_change_power(struct rts51x_chip *chip, u8 mode) +{ + int retval; + u8 buf[6]; + + ms_cleanup_work(chip); + + /* Set Parameter Register */ + retval = ms_set_rw_reg_addr(chip, 0, 0, Pro_DataCount1, 6); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + buf[0] = 0; + buf[1] = mode; + buf[2] = 0; + buf[3] = 0; + buf[4] = 0; + buf[5] = 0; + + retval = ms_write_bytes(chip, PRO_WRITE_REG, 6, NO_WAIT_INT, buf, 6); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = ms_send_cmd(chip, XC_CHG_POWER, WAIT_INT); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + RTS51X_READ_REG(chip, MS_TRANS_CFG, buf); + if (buf[0] & (MS_INT_CMDNK | MS_INT_ERR)) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} +#endif + +static int ms_read_attribute_info(struct rts51x_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i; + u8 val, *buf, class_code, device_type, sub_class, data[16]; + u16 total_blk = 0, blk_size = 0; +#ifdef SUPPORT_MSXC + u32 xc_total_blk = 0, xc_blk_size = 0; +#endif + u32 sys_info_addr = 0, sys_info_size; +#ifdef SUPPORT_PCGL_1P18 + u32 model_name_addr = 0, model_name_size; + int found_sys_info = 0, found_model_name = 0; +#endif + + retval = ms_set_rw_reg_addr(chip, Pro_IntReg, 2, Pro_SystemParm, 7); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + if (CHK_MS8BIT(ms_card)) + data[0] = PARALLEL_8BIT_IF; + else + data[0] = PARALLEL_4BIT_IF; + data[1] = 0; + + data[2] = 0x40; + data[3] = 0; + data[4] = 0; + data[5] = 0; + /* Start address 0 */ + data[6] = 0; + data[7] = 0; + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = + ms_write_bytes(chip, PRO_WRITE_REG, 7, NO_WAIT_INT, data, + 8); + if (retval == STATUS_SUCCESS) + break; + } + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + buf = kmalloc(64 * 512, GFP_KERNEL); + if (buf == NULL) + TRACE_RET(chip, STATUS_NOMEM); + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = ms_send_cmd(chip, PRO_READ_ATRB, WAIT_INT); + if (retval != STATUS_SUCCESS) + continue; + + retval = rts51x_read_register(chip, MS_TRANS_CFG, &val); + if (retval != STATUS_SUCCESS) { + kfree(buf); + TRACE_RET(chip, STATUS_FAIL); + } + if (!(val & MS_INT_BREQ)) { + kfree(buf); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = + ms_transfer_data(chip, MS_TM_AUTO_READ, PRO_READ_LONG_DATA, + 0x40, WAIT_INT, 0, 0, buf, 64 * 512); + if (retval == STATUS_SUCCESS) + break; + else + rts51x_clear_ms_error(chip); + } + if (retval != STATUS_SUCCESS) { + kfree(buf); + TRACE_RET(chip, retval); + } + + i = 0; + do { + retval = rts51x_read_register(chip, MS_TRANS_CFG, &val); + if (retval != STATUS_SUCCESS) { + kfree(buf); + TRACE_RET(chip, retval); + } + + if ((val & MS_INT_CED) || !(val & MS_INT_BREQ)) + break; + + retval = + ms_transfer_tpc(chip, MS_TM_NORMAL_READ, PRO_READ_LONG_DATA, + 0, WAIT_INT); + if (retval != STATUS_SUCCESS) { + kfree(buf); + TRACE_RET(chip, retval); + } + + i++; + } while (i < 1024); + + if (retval != STATUS_SUCCESS) { + kfree(buf); + TRACE_RET(chip, retval); + } + + if ((buf[0] != 0xa5) && (buf[1] != 0xc3)) { + /* Signature code is wrong */ + kfree(buf); + TRACE_RET(chip, STATUS_FAIL); + } + + if ((buf[4] < 1) || (buf[4] > 12)) { + kfree(buf); + TRACE_RET(chip, STATUS_FAIL); + } + + for (i = 0; i < buf[4]; i++) { + int cur_addr_off = 16 + i * 12; + +#ifdef SUPPORT_MSXC + if ((buf[cur_addr_off + 8] == 0x10) + || (buf[cur_addr_off + 8] == 0x13)) { +#else + if (buf[cur_addr_off + 8] == 0x10) { +#endif + sys_info_addr = ((u32) buf[cur_addr_off + 0] << 24) | + ((u32) buf[cur_addr_off + 1] << 16) | + ((u32) buf[cur_addr_off + 2] << 8) | + buf[cur_addr_off + 3]; + sys_info_size = + ((u32) buf[cur_addr_off + 4] << 24) | + ((u32) buf[cur_addr_off + 5] << 16) | + ((u32) buf[cur_addr_off + 6] << 8) | + buf[cur_addr_off + 7]; + RTS51X_DEBUGP("sys_info_addr = 0x%x," + "sys_info_size = 0x%x\n", + sys_info_addr, sys_info_size); + if (sys_info_size != 96) { + kfree(buf); + TRACE_RET(chip, STATUS_FAIL); + } + if (sys_info_addr < 0x1A0) { + kfree(buf); + TRACE_RET(chip, STATUS_FAIL); + } + if ((sys_info_size + sys_info_addr) > 0x8000) { + kfree(buf); + TRACE_RET(chip, STATUS_FAIL); + } +#ifdef SUPPORT_MSXC + if (buf[cur_addr_off + 8] == 0x13) + ms_card->ms_type |= MS_XC; +#endif +#ifdef SUPPORT_PCGL_1P18 + found_sys_info = 1; +#else + break; +#endif + } +#ifdef SUPPORT_PCGL_1P18 + if (buf[cur_addr_off + 8] == 0x15) { + model_name_addr = ((u32) buf[cur_addr_off + 0] << 24) | + ((u32) buf[cur_addr_off + 1] << 16) | + ((u32) buf[cur_addr_off + 2] << 8) | + buf[cur_addr_off + 3]; + model_name_size = + ((u32) buf[cur_addr_off + 4] << 24) | + ((u32) buf[cur_addr_off + 5] << 16) | + ((u32) buf[cur_addr_off + 6] << 8) | + buf[cur_addr_off + 7]; + RTS51X_DEBUGP("model_name_addr = 0x%x," + "model_name_size = 0x%x\n", + model_name_addr, model_name_size); + if (model_name_size != 48) { + kfree(buf); + TRACE_RET(chip, STATUS_FAIL); + } + if (model_name_addr < 0x1A0) { + kfree(buf); + TRACE_RET(chip, STATUS_FAIL); + } + if ((model_name_size + model_name_addr) > 0x8000) { + kfree(buf); + TRACE_RET(chip, STATUS_FAIL); + } + + found_model_name = 1; + } + + if (found_sys_info && found_model_name) + break; +#endif + } + + if (i == buf[4]) { + kfree(buf); + TRACE_RET(chip, STATUS_FAIL); + } + + class_code = buf[sys_info_addr + 0]; + device_type = buf[sys_info_addr + 56]; + sub_class = buf[sys_info_addr + 46]; +#ifdef SUPPORT_MSXC + if (CHK_MSXC(ms_card)) { + xc_total_blk = ((u32) buf[sys_info_addr + 6] << 24) | + ((u32) buf[sys_info_addr + 7] << 16) | + ((u32) buf[sys_info_addr + 8] << 8) | + buf[sys_info_addr + 9]; + xc_blk_size = ((u32) buf[sys_info_addr + 32] << 24) | + ((u32) buf[sys_info_addr + 33] << 16) | + ((u32) buf[sys_info_addr + 34] << 8) | + buf[sys_info_addr + 35]; + RTS51X_DEBUGP("xc_total_blk = 0x%x, xc_blk_size = 0x%x\n", + xc_total_blk, xc_blk_size); + } else { + total_blk = + ((u16) buf[sys_info_addr + 6] << 8) | buf[sys_info_addr + + 7]; + blk_size = + ((u16) buf[sys_info_addr + 2] << 8) | buf[sys_info_addr + + 3]; + RTS51X_DEBUGP("total_blk = 0x%x, blk_size = 0x%x\n", total_blk, + blk_size); + } +#else + total_blk = + ((u16) buf[sys_info_addr + 6] << 8) | buf[sys_info_addr + 7]; + blk_size = ((u16) buf[sys_info_addr + 2] << 8) | buf[sys_info_addr + 3]; + RTS51X_DEBUGP("total_blk = 0x%x, blk_size = 0x%x\n", total_blk, + blk_size); +#endif + + RTS51X_DEBUGP("class_code = 0x%x, device_type = 0x%x," + "sub_class = 0x%x\n", + class_code, device_type, sub_class); + + memcpy(ms_card->raw_sys_info, buf + sys_info_addr, 96); +#ifdef SUPPORT_PCGL_1P18 + memcpy(ms_card->raw_model_name, buf + model_name_addr, 48); +#endif + + kfree(buf); + + /* Confirm System Information */ +#ifdef SUPPORT_MSXC + if (CHK_MSXC(ms_card)) { + if (class_code != 0x03) + TRACE_RET(chip, STATUS_FAIL); + } else { + if (class_code != 0x02) + TRACE_RET(chip, STATUS_FAIL); + } +#else + if (class_code != 0x02) + TRACE_RET(chip, STATUS_FAIL); +#endif + + if (device_type != 0x00) { + if ((device_type == 0x01) || (device_type == 0x02) + || (device_type == 0x03)) + chip->card_wp |= MS_CARD; + else + TRACE_RET(chip, STATUS_FAIL); + } + if (sub_class & 0xC0) + TRACE_RET(chip, STATUS_FAIL); + + RTS51X_DEBUGP("class_code: 0x%x, device_type: 0x%x, sub_class: 0x%x\n", + class_code, device_type, sub_class); + +#ifdef SUPPORT_MSXC + if (CHK_MSXC(ms_card)) { + chip->capacity[chip->card2lun[MS_CARD]] = ms_card->capacity = + xc_total_blk * xc_blk_size; + } else { + chip->capacity[chip->card2lun[MS_CARD]] = ms_card->capacity = + total_blk * blk_size; + } +#else + chip->capacity[chip->card2lun[MS_CARD]] = ms_card->capacity = + total_blk * blk_size; +#endif + + return STATUS_SUCCESS; +} + +#ifdef SUPPORT_MAGIC_GATE +int mg_set_tpc_para_sub(struct rts51x_chip *chip, int type, u8 mg_entry_num); +#endif + +static int reset_ms_pro(struct rts51x_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; +#ifdef XC_POWERCLASS + u8 change_power_class = 2; +#endif + +#ifdef XC_POWERCLASS +Retry: +#endif + retval = ms_pro_reset_flow(chip, 1); + if (retval != STATUS_SUCCESS) { + if (ms_card->switch_8bit_fail) { + retval = ms_pro_reset_flow(chip, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } else { + TRACE_RET(chip, retval); + } + } + + retval = ms_read_attribute_info(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); +#ifdef XC_POWERCLASS + if (CHK_HG8BIT(ms_card)) + change_power_class = 0; + + if (change_power_class && CHK_MSXC(ms_card)) { + u8 power_class_mode = (ms_card->raw_sys_info[46] & 0x18) >> 3; + RTS51X_DEBUGP("power_class_mode = 0x%x", power_class_mode); + if (change_power_class > power_class_mode) + change_power_class = power_class_mode; + if (change_power_class) { + retval = msxc_change_power(chip, change_power_class); + if (retval != STATUS_SUCCESS) { + change_power_class--; + goto Retry; + } + } + } +#endif + +#ifdef SUPPORT_MAGIC_GATE + retval = mg_set_tpc_para_sub(chip, 0, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); +#endif + + if (CHK_HG8BIT(ms_card)) + chip->card_bus_width[chip->card2lun[MS_CARD]] = 8; + else + chip->card_bus_width[chip->card2lun[MS_CARD]] = 4; + + return STATUS_SUCCESS; +} + +static int ms_read_status_reg(struct rts51x_chip *chip) +{ + int retval; + u8 val[2]; + + retval = ms_set_rw_reg_addr(chip, StatusReg0, 2, 0, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = ms_read_bytes(chip, READ_REG, 2, NO_WAIT_INT, val, 2); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + if (val[1] & (STS_UCDT | STS_UCEX | STS_UCFG)) { + ms_set_err_code(chip, MS_FLASH_READ_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int ms_check_boot_block(struct rts51x_chip *chip, u16 block_addr) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + u8 extra[MS_EXTRA_SIZE], data[10], val = 0; + + if (CHK_MS4BIT(ms_card)) { + /* Parallel interface */ + data[0] = 0x88; + } else { + /* Serial interface */ + data[0] = 0x80; + } + /* Block Address */ + data[1] = 0; + data[2] = (u8) (block_addr >> 8); + data[3] = (u8) block_addr; + /* Page Number + * Extra data access mode */ + data[4] = 0x40; + data[5] = 0; + + retval = ms_set_cmd(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6, + BLOCK_READ, WAIT_INT, data, 6, &val); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + if (val & INT_REG_CMDNK) { + ms_set_err_code(chip, MS_CMD_NK); + TRACE_RET(chip, STATUS_FAIL); + } + if (val & INT_REG_CED) { + if (val & INT_REG_ERR) { + retval = ms_read_status_reg(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + retval = + ms_set_rw_reg_addr(chip, OverwriteFlag, + MS_EXTRA_SIZE, SystemParm, 6); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } + } + + retval = + ms_read_bytes(chip, READ_REG, MS_EXTRA_SIZE, NO_WAIT_INT, extra, + MS_EXTRA_SIZE); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + if (!(extra[0] & BLOCK_OK) || (extra[1] & NOT_BOOT_BLOCK)) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +static int ms_read_extra_data(struct rts51x_chip *chip, + u16 block_addr, u8 page_num, u8 *buf, + int buf_len) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + u8 val = 0, data[10]; + + if (CHK_MS4BIT(ms_card)) { + /* Parallel interface */ + data[0] = 0x88; + } else { + /* Serial interface */ + data[0] = 0x80; + } + /* Block Address */ + data[1] = 0; + data[2] = (u8) (block_addr >> 8); + data[3] = (u8) block_addr; + /* Page Number + * Extra data access mode */ + data[4] = 0x40; + data[5] = page_num; + +#ifdef MS_SPEEDUP + retval = + ms_auto_set_cmd(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6, + BLOCK_READ, WAIT_INT, data, 6, &val); +#else + retval = ms_set_cmd(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6, + BLOCK_READ, WAIT_INT, data, 6, &val); +#endif + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + if (val & INT_REG_CMDNK) { + ms_set_err_code(chip, MS_CMD_NK); + TRACE_RET(chip, STATUS_FAIL); + } + if (val & INT_REG_CED) { + if (val & INT_REG_ERR) { + retval = ms_read_status_reg(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + retval = + ms_set_rw_reg_addr(chip, OverwriteFlag, + MS_EXTRA_SIZE, SystemParm, 6); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } + } + + retval = + ms_read_bytes(chip, READ_REG, MS_EXTRA_SIZE, NO_WAIT_INT, data, + MS_EXTRA_SIZE); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + if (buf && buf_len) { + if (buf_len > MS_EXTRA_SIZE) + buf_len = MS_EXTRA_SIZE; + memcpy(buf, data, buf_len); + } + + return STATUS_SUCCESS; +} + +static int ms_write_extra_data(struct rts51x_chip *chip, + u16 block_addr, u8 page_num, u8 *buf, + int buf_len) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i; + u8 val = 0, data[16]; + + if (!buf || (buf_len < MS_EXTRA_SIZE)) + TRACE_RET(chip, STATUS_FAIL); + /* Write REG */ + if (CHK_MS4BIT(ms_card)) { + /* Parallel interface */ + data[0] = 0x88; + } else { + /* Serial interface */ + data[0] = 0x80; + } + /* Block Address */ + data[1] = 0; + data[2] = (u8) (block_addr >> 8); + data[3] = (u8) block_addr; + /* Page Number + * Extra data access mode */ + data[4] = 0x40; + data[5] = page_num; + + for (i = 6; i < MS_EXTRA_SIZE + 6; i++) + data[i] = buf[i - 6]; + +#ifdef MS_SPEEDUP + retval = + ms_auto_set_cmd(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, + 6 + MS_EXTRA_SIZE, BLOCK_WRITE, WAIT_INT, data, 16, + &val); +#else + retval = + ms_set_cmd(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, + 6 + MS_EXTRA_SIZE, BLOCK_WRITE, WAIT_INT, data, 16, + &val); +#endif + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + if (val & INT_REG_CMDNK) { + ms_set_err_code(chip, MS_CMD_NK); + TRACE_RET(chip, STATUS_FAIL); + } + if (val & INT_REG_CED) { + if (val & INT_REG_ERR) { + ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + return STATUS_SUCCESS; +} + +static int ms_read_page(struct rts51x_chip *chip, u16 block_addr, u8 page_num) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + u8 val = 0, data[6]; + + if (CHK_MS4BIT(ms_card)) { + /* Parallel interface */ + data[0] = 0x88; + } else { + /* Serial interface */ + data[0] = 0x80; + } + /* Block Address */ + data[1] = 0; + data[2] = (u8) (block_addr >> 8); + data[3] = (u8) block_addr; + /* Page Number + * Single page access mode */ + data[4] = 0x20; + data[5] = page_num; + + retval = ms_set_cmd(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6, + BLOCK_READ, WAIT_INT, data, 6, &val); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + if (val & INT_REG_CMDNK) { + ms_set_err_code(chip, MS_CMD_NK); + TRACE_RET(chip, STATUS_FAIL); + } + + if (val & INT_REG_CED) { + if (val & INT_REG_ERR) { + if (!(val & INT_REG_BREQ)) { + ms_set_err_code(chip, MS_FLASH_READ_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + retval = ms_read_status_reg(chip); + if (retval != STATUS_SUCCESS) + ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); + } else { + if (!(val & INT_REG_BREQ)) { + ms_set_err_code(chip, MS_BREQ_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } + } + + retval = + ms_transfer_tpc(chip, MS_TM_NORMAL_READ, READ_PAGE_DATA, 0, + NO_WAIT_INT); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + if (ms_check_err_code(chip, MS_FLASH_WRITE_ERROR)) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +static int ms_set_bad_block(struct rts51x_chip *chip, u16 phy_blk) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + u8 val = 0, data[8], extra[MS_EXTRA_SIZE]; + + retval = ms_read_extra_data(chip, phy_blk, 0, extra, MS_EXTRA_SIZE); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + ms_set_err_code(chip, MS_NO_ERROR); + + if (CHK_MS4BIT(ms_card)) { + /* Parallel interface */ + data[0] = 0x88; + } else { + /* Serial interface */ + data[0] = 0x80; + } + /* Block Address */ + data[1] = 0; + data[2] = (u8) (phy_blk >> 8); + data[3] = (u8) phy_blk; + data[4] = 0x80; + data[5] = 0; + data[6] = extra[0] & 0x7F; + data[7] = 0xFF; + +#ifdef MS_SPEEDUP + retval = ms_set_cmd(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 7, + BLOCK_WRITE, WAIT_INT, data, 7, &val); +#else + retval = ms_set_cmd(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 7, + BLOCK_WRITE, WAIT_INT, data, 7, &val); +#endif + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + if (val & INT_REG_CMDNK) { + ms_set_err_code(chip, MS_CMD_NK); + TRACE_RET(chip, STATUS_FAIL); + } + + if (val & INT_REG_CED) { + if (val & INT_REG_ERR) { + ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + return STATUS_SUCCESS; +} + +static int ms_erase_block(struct rts51x_chip *chip, u16 phy_blk) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i = 0; + u8 val = 0, data[6]; + + retval = + ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, + 6); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + ms_set_err_code(chip, MS_NO_ERROR); + + if (CHK_MS4BIT(ms_card)) { + /* Parallel interface */ + data[0] = 0x88; + } else { + /* Serial interface */ + data[0] = 0x80; + } + /* Block Address */ + data[1] = 0; + data[2] = (u8) (phy_blk >> 8); + data[3] = (u8) phy_blk; + data[4] = 0; + data[5] = 0; + +ERASE_RTY: +#ifdef MS_SPEEDUP + retval = + ms_auto_set_cmd(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6, + BLOCK_ERASE, WAIT_INT, data, 6, &val); +#else + retval = ms_set_cmd(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6, + BLOCK_ERASE, WAIT_INT, data, 6, &val); +#endif + + if (val & INT_REG_CMDNK) { + if (i < 3) { + i++; + goto ERASE_RTY; + } + ms_set_err_code(chip, MS_CMD_NK); + ms_set_bad_block(chip, phy_blk); + TRACE_RET(chip, STATUS_FAIL); + } + + if (val & INT_REG_CED) { + if (val & INT_REG_ERR) { + ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + return STATUS_SUCCESS; +} + +static void ms_set_page_status(u16 log_blk, u8 type, u8 *extra, int extra_len) +{ + if (!extra || (extra_len < MS_EXTRA_SIZE)) + return; + + memset(extra, 0xFF, MS_EXTRA_SIZE); + + if (type == setPS_NG) + extra[0] = 0xB8; + else + extra[0] = 0x98; + + extra[2] = (u8) (log_blk >> 8); + extra[3] = (u8) log_blk; +} + +static int ms_init_page(struct rts51x_chip *chip, u16 phy_blk, u16 log_blk, + u8 start_page, u8 end_page) +{ + int retval; + u8 extra[MS_EXTRA_SIZE], i; + + memset(extra, 0xff, MS_EXTRA_SIZE); + + extra[0] = 0xf8; /* Block, page OK, data erased */ + extra[1] = 0xff; + extra[2] = (u8) (log_blk >> 8); + extra[3] = (u8) log_blk; + + for (i = start_page; i < end_page; i++) { + if (monitor_card_cd(chip, MS_CARD) == CD_NOT_EXIST) + TRACE_RET(chip, STATUS_FAIL); + + retval = + ms_write_extra_data(chip, phy_blk, i, extra, MS_EXTRA_SIZE); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } + + return STATUS_SUCCESS; +} + +static int ms_copy_page(struct rts51x_chip *chip, u16 old_blk, u16 new_blk, + u16 log_blk, u8 start_page, u8 end_page) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, rty_cnt, uncorrect_flag = 0; + u8 extra[MS_EXTRA_SIZE], val, i, j, data[16]; + + RTS51X_DEBUGP("Copy page from 0x%x to 0x%x, logical block is 0x%x\n", + old_blk, new_blk, log_blk); + RTS51X_DEBUGP("start_page = %d, end_page = %d\n", start_page, + end_page); + + retval = ms_read_extra_data(chip, new_blk, 0, extra, MS_EXTRA_SIZE); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = ms_read_status_reg(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + RTS51X_READ_REG(chip, PPBUF_BASE2, &val); + + if (val & BUF_FULL) { + /* Clear Buffer */ + retval = ms_send_cmd(chip, CLEAR_BUF, WAIT_INT); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + /* GET_INT Register */ + retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + if (!(val & INT_REG_CED)) { + ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + for (i = start_page; i < end_page; i++) { + if (monitor_card_cd(chip, MS_CARD) == CD_NOT_EXIST) + TRACE_RET(chip, STATUS_FAIL); + + ms_read_extra_data(chip, old_blk, i, extra, MS_EXTRA_SIZE); + + retval = + ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, + SystemParm, 6); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + /* Write REG */ + ms_set_err_code(chip, MS_NO_ERROR); + + if (CHK_MS4BIT(ms_card)) { + /* Parallel interface */ + data[0] = 0x88; + } else { + /* Serial interface */ + data[0] = 0x80; + } + /* Block Address */ + data[1] = 0; + data[2] = (u8) (old_blk >> 8); + data[3] = (u8) old_blk; + data[4] = 0x20; + data[5] = i; + + retval = + ms_write_bytes(chip, WRITE_REG, 6, NO_WAIT_INT, data, 6); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = ms_send_cmd(chip, BLOCK_READ, WAIT_INT); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + ms_set_err_code(chip, MS_NO_ERROR); + retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + if (val & INT_REG_CMDNK) { + ms_set_err_code(chip, MS_CMD_NK); + TRACE_RET(chip, STATUS_FAIL); + } + + if (val & INT_REG_CED) { + if (val & INT_REG_ERR) { + retval = ms_read_status_reg(chip); + if (retval != STATUS_SUCCESS) { + uncorrect_flag = 1; + RTS51X_DEBUGP("Uncorrectable" + "error\n"); + } else { + uncorrect_flag = 0; + } + + retval = + ms_transfer_tpc(chip, MS_TM_NORMAL_READ, + READ_PAGE_DATA, 0, NO_WAIT_INT); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + if (uncorrect_flag) { + ms_set_page_status(log_blk, setPS_NG, + extra, MS_EXTRA_SIZE); + if (i == 0) + extra[0] &= 0xEF; + ms_write_extra_data(chip, old_blk, i, + extra, + MS_EXTRA_SIZE); + RTS51X_DEBUGP("page %d :" + "extra[0] = 0x%x\n", + i, extra[0]); + MS_SET_BAD_BLOCK_FLG(ms_card); + + ms_set_page_status(log_blk, setPS_Error, + extra, MS_EXTRA_SIZE); + ms_write_extra_data(chip, new_blk, i, + extra, MS_EXTRA_SIZE); + continue; + } + + for (rty_cnt = 0; rty_cnt < MS_MAX_RETRY_COUNT; + rty_cnt++) { + retval = + ms_transfer_tpc(chip, + MS_TM_NORMAL_WRITE, + WRITE_PAGE_DATA, 0, + NO_WAIT_INT); + if (retval == STATUS_SUCCESS) + break; + } + if (rty_cnt == MS_MAX_RETRY_COUNT) + TRACE_RET(chip, STATUS_FAIL); + } + + if (!(val & INT_REG_BREQ)) { + ms_set_err_code(chip, MS_BREQ_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + retval = ms_set_rw_reg_addr(chip, OverwriteFlag, + MS_EXTRA_SIZE, SystemParm, + (6 + MS_EXTRA_SIZE)); + + /* Write REG */ + ms_set_err_code(chip, MS_NO_ERROR); + + if (CHK_MS4BIT(ms_card)) { + /* Parallel interface */ + data[0] = 0x88; + } else { + /* Serial interface */ + data[0] = 0x80; + } + /* Block Address */ + data[1] = 0; + data[2] = (u8) (new_blk >> 8); + data[3] = (u8) new_blk; + data[4] = 0x20; + data[5] = i; + + /* for MS check procedure */ + if ((extra[0] & 0x60) != 0x60) + data[6] = extra[0]; + else + data[6] = 0xF8; + + data[6 + 1] = 0xFF; + data[6 + 2] = (u8) (log_blk >> 8); + data[6 + 3] = (u8) log_blk; + + for (j = 4; j <= MS_EXTRA_SIZE; j++) + data[6 + j] = 0xFF; + + retval = + ms_write_bytes(chip, WRITE_REG, (6 + MS_EXTRA_SIZE), + NO_WAIT_INT, data, 16); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + /* GET_INT Register */ + ms_set_err_code(chip, MS_NO_ERROR); + retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + if (val & INT_REG_CMDNK) { + ms_set_err_code(chip, MS_CMD_NK); + TRACE_RET(chip, STATUS_FAIL); + } + + if (val & INT_REG_CED) { + if (val & INT_REG_ERR) { + ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + if (i == 0) { + retval = + ms_set_rw_reg_addr(chip, OverwriteFlag, + MS_EXTRA_SIZE, SystemParm, 7); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + ms_set_err_code(chip, MS_NO_ERROR); + + if (CHK_MS4BIT(ms_card)) { + /* Parallel interface */ + data[0] = 0x88; + } else { + /* Serial interface */ + data[0] = 0x80; + } + /* Block Address */ + data[1] = 0; + data[2] = (u8) (old_blk >> 8); + data[3] = (u8) old_blk; + data[4] = 0x80; + data[5] = 0; + data[6] = 0xEF; + data[7] = 0xFF; + + retval = + ms_write_bytes(chip, WRITE_REG, 7, NO_WAIT_INT, + data, 8); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + ms_set_err_code(chip, MS_NO_ERROR); + retval = + ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, + 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + if (val & INT_REG_CMDNK) { + ms_set_err_code(chip, MS_CMD_NK); + TRACE_RET(chip, STATUS_FAIL); + } + + if (val & INT_REG_CED) { + if (val & INT_REG_ERR) { + ms_set_err_code(chip, + MS_FLASH_WRITE_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } + } + } + + return STATUS_SUCCESS; +} + +#ifdef MS_SPEEDUP +static int ms_auto_copy_page(struct rts51x_chip *chip, u16 old_blk, u16 new_blk, + u16 log_blk, u8 start_page, u8 end_page) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + u8 page_len, bus_width, val = 0; + u8 extra[MS_EXTRA_SIZE]; + + RTS51X_DEBUGP("Auto copy page from 0x%x to 0x%x," + "logical block is 0x%x\n", + old_blk, new_blk, log_blk); + RTS51X_DEBUGP("start_page = %d, end_page = %d\n", start_page, + end_page); + + page_len = end_page - start_page; + + retval = ms_read_extra_data(chip, new_blk, 0, extra, MS_EXTRA_SIZE); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = ms_read_status_reg(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + RTS51X_READ_REG(chip, PPBUF_BASE2, &val); + + if (val & BUF_FULL) { + retval = ms_send_cmd(chip, CLEAR_BUF, WAIT_INT); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + if (!(val & INT_REG_CED)) { + ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + if (CHK_MS4BIT(ms_card)) { + /* Parallel interface */ + bus_width = 0x88; + } else { + /* Serial interface */ + bus_width = 0x80; + } + + rts51x_init_cmd(chip); + + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_OLD_BLOCK_0, 0xFF, (u8) old_blk); + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_OLD_BLOCK_1, 0xFF, + (u8) (old_blk >> 8)); + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_NEW_BLOCK_0, 0xFF, (u8) new_blk); + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_NEW_BLOCK_1, 0xFF, + (u8) (new_blk >> 8)); + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_LOG_BLOCK_0, 0xFF, (u8) log_blk); + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_LOG_BLOCK_1, 0xFF, + (u8) (log_blk >> 8)); + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_PAGE_START, 0xFF, start_page); + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_PAGE_LENGTH, 0xFF, page_len); + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_BUS_WIDTH, 0xFF, bus_width); + + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, + MS_TRANSFER_START | MS_TM_COPY_PAGE); + rts51x_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, MS_TRANSFER_END, + MS_TRANSFER_END); + + retval = rts51x_send_cmd(chip, MODE_CR, 100); + if (retval != STATUS_SUCCESS) { + rts51x_clear_ms_error(chip); + TRACE_RET(chip, retval); + } + + retval = rts51x_get_rsp(chip, 1, 5000); + + if (CHECK_MS_TRANS_FAIL(chip, retval)) { + rts51x_clear_ms_error(chip); + if (retval == STATUS_TIMEDOUT) + TRACE_RET(chip, retval); + TRACE_GOTO(chip, Fail); + } + + return STATUS_SUCCESS; + +Fail: + retval = ms_erase_block(chip, new_blk); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = + ms_copy_page(chip, old_blk, new_blk, log_blk, start_page, end_page); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + return STATUS_SUCCESS; +} +#endif + +static int reset_ms(struct rts51x_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + u16 i, reg_addr, block_size; + u8 val, j, *ptr; +#ifndef SUPPORT_MAGIC_GATE + u16 eblock_cnt; +#endif + + retval = ms_prepare_reset(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + ms_card->ms_type |= TYPE_MS; + + retval = ms_send_cmd(chip, MS_RESET, NO_WAIT_INT); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = ms_read_status_reg(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + RTS51X_READ_REG(chip, PPBUF_BASE2, &val); + if (val & WRT_PRTCT) + chip->card_wp |= MS_CARD; + else + chip->card_wp &= ~MS_CARD; + + i = 0; + +RE_SEARCH: + /* Search For Boot Block */ + while (i < (MAX_DEFECTIVE_BLOCK + 2)) { + if (monitor_card_cd(chip, MS_CARD) == CD_NOT_EXIST) + TRACE_RET(chip, STATUS_FAIL); + + retval = ms_check_boot_block(chip, i); + if (retval != STATUS_SUCCESS) { + i++; + continue; + } + + ms_card->boot_block = i; + break; + } + + if (i == (MAX_DEFECTIVE_BLOCK + 2)) { + RTS51X_DEBUGP("No boot block found!"); + TRACE_RET(chip, STATUS_FAIL); + } + for (j = 0; j < 3; j++) { + retval = ms_read_page(chip, ms_card->boot_block, j); + if (retval != STATUS_SUCCESS) { + if (ms_check_err_code(chip, MS_FLASH_WRITE_ERROR)) { + i = ms_card->boot_block + 1; + ms_set_err_code(chip, MS_NO_ERROR); + goto RE_SEARCH; + } + } + } + + /* Read boot block contents */ + retval = ms_read_page(chip, ms_card->boot_block, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + /* Read MS system information as sys_info */ + retval = + rts51x_seq_read_register(chip, PPBUF_BASE2 + 0x1A0, 96, + ms_card->raw_sys_info); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + /* Read useful block contents */ + rts51x_init_cmd(chip); + + rts51x_add_cmd(chip, READ_REG_CMD, HEADER_ID0, 0, 0); + rts51x_add_cmd(chip, READ_REG_CMD, HEADER_ID1, 0, 0); + + for (reg_addr = DISABLED_BLOCK0; reg_addr <= DISABLED_BLOCK3; + reg_addr++) { + rts51x_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0); + } + + for (reg_addr = BLOCK_SIZE_0; reg_addr <= PAGE_SIZE_1; reg_addr++) + rts51x_add_cmd(chip, READ_REG_CMD, reg_addr, 0, 0); + + rts51x_add_cmd(chip, READ_REG_CMD, MS_Device_Type, 0, 0); + rts51x_add_cmd(chip, READ_REG_CMD, MS_4bit_Support, 0, 0); + + retval = rts51x_send_cmd(chip, MODE_CR, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = rts51x_get_rsp(chip, 16, 100); + + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + ptr = rts51x_get_rsp_data(chip); + + RTS51X_DEBUGP("Boot block data:\n"); + RTS51X_DUMP(ptr, 16); + + if (ptr[0] != 0x00 || ptr[1] != 0x01) { + i = ms_card->boot_block + 1; + goto RE_SEARCH; + } + if (ptr[12] != 0x02 || ptr[13] != 0x00) { + i = ms_card->boot_block + 1; + goto RE_SEARCH; + } + if ((ptr[14] == 1) || (ptr[14] == 3)) + chip->card_wp |= MS_CARD; + block_size = ((u16) ptr[6] << 8) | ptr[7]; + if (block_size == 0x0010) { + ms_card->block_shift = 5; + ms_card->page_off = 0x1F; + } else if (block_size == 0x0008) { + ms_card->block_shift = 4; + ms_card->page_off = 0x0F; + } + ms_card->total_block = ((u16) ptr[8] << 8) | ptr[9]; + +#ifdef SUPPORT_MAGIC_GATE + j = ptr[10]; + + if (ms_card->block_shift == 4) { + if (j < 2) + ms_card->capacity = 0x1EE0; + else + ms_card->capacity = 0x3DE0; + } else { + if (j < 5) + ms_card->capacity = 0x7BC0; + else if (j < 0xA) + ms_card->capacity = 0xF7C0; + else if (j < 0x11) + ms_card->capacity = 0x1EF80; + else + ms_card->capacity = 0x3DF00; + } +#else + eblock_cnt = ((u16) ptr[10] << 8) | ptr[11]; + + ms_card->capacity = ((u32) eblock_cnt - 2) << ms_card->block_shift; +#endif + + chip->capacity[chip->card2lun[MS_CARD]] = ms_card->capacity; + + if (ptr[15]) { + retval = ms_set_rw_reg_addr(chip, 0, 0, SystemParm, 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + RTS51X_WRITE_REG(chip, PPBUF_BASE2, 0xFF, 0x88); + RTS51X_WRITE_REG(chip, PPBUF_BASE2 + 1, 0xFF, 0); + + retval = + ms_transfer_tpc(chip, MS_TM_WRITE_BYTES, WRITE_REG, 1, + NO_WAIT_INT); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + RTS51X_WRITE_REG(chip, MS_CFG, 0x58 | MS_NO_CHECK_INT, + MS_BUS_WIDTH_4 | PUSH_TIME_ODD | + MS_NO_CHECK_INT); + + ms_card->ms_type |= MS_4BIT; + } + + if (CHK_MS4BIT(ms_card)) + chip->card_bus_width[chip->card2lun[MS_CARD]] = 4; + else + chip->card_bus_width[chip->card2lun[MS_CARD]] = 1; + + return STATUS_SUCCESS; +} + +static int ms_init_l2p_tbl(struct rts51x_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int size, i, seg_no, retval; + u16 defect_block, reg_addr; + u8 val1, val2; + + ms_card->segment_cnt = ms_card->total_block >> 9; + RTS51X_DEBUGP("ms_card->segment_cnt = %d\n", ms_card->segment_cnt); + + size = ms_card->segment_cnt * sizeof(struct zone_entry); + ms_card->segment = vmalloc(size); + if (ms_card->segment == NULL) + TRACE_RET(chip, STATUS_FAIL); + memset(ms_card->segment, 0, size); + + retval = ms_read_page(chip, ms_card->boot_block, 1); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, INIT_FAIL); + + reg_addr = PPBUF_BASE2; + for (i = 0; i < (((ms_card->total_block >> 9) * 10) + 1); i++) { + retval = rts51x_read_register(chip, reg_addr++, &val1); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, INIT_FAIL); + retval = rts51x_read_register(chip, reg_addr++, &val2); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, INIT_FAIL); + + defect_block = ((u16) val1 << 8) | val2; + if (defect_block == 0xFFFF) + break; + seg_no = defect_block / 512; + ms_card->segment[seg_no].defect_list[ms_card->segment[seg_no]. + disable_count++] = + defect_block; + } + + for (i = 0; i < ms_card->segment_cnt; i++) { + ms_card->segment[i].build_flag = 0; + ms_card->segment[i].l2p_table = NULL; + ms_card->segment[i].free_table = NULL; + ms_card->segment[i].get_index = 0; + ms_card->segment[i].set_index = 0; + ms_card->segment[i].unused_blk_cnt = 0; + + RTS51X_DEBUGP("defective block count of segment %d is %d\n", + i, ms_card->segment[i].disable_count); + } + + return STATUS_SUCCESS; + +INIT_FAIL: + if (ms_card->segment) { + vfree(ms_card->segment); + ms_card->segment = NULL; + } + + return STATUS_FAIL; +} + +static u16 ms_get_l2p_tbl(struct rts51x_chip *chip, int seg_no, u16 log_off) +{ + struct ms_info *ms_card = &(chip->ms_card); + struct zone_entry *segment; + + if (ms_card->segment == NULL) + return 0xFFFF; + + segment = &(ms_card->segment[seg_no]); + + if (segment->l2p_table) + return segment->l2p_table[log_off]; + + return 0xFFFF; +} + +static void ms_set_l2p_tbl(struct rts51x_chip *chip, int seg_no, u16 log_off, + u16 phy_blk) +{ + struct ms_info *ms_card = &(chip->ms_card); + struct zone_entry *segment; + + if (ms_card->segment == NULL) + return; + + segment = &(ms_card->segment[seg_no]); + if (segment->l2p_table) + segment->l2p_table[log_off] = phy_blk; +} + +static void ms_set_unused_block(struct rts51x_chip *chip, u16 phy_blk) +{ + struct ms_info *ms_card = &(chip->ms_card); + struct zone_entry *segment; + int seg_no; + + seg_no = (int)phy_blk >> 9; + segment = &(ms_card->segment[seg_no]); + + segment->free_table[segment->set_index++] = phy_blk; + if (segment->set_index >= MS_FREE_TABLE_CNT) + segment->set_index = 0; + segment->unused_blk_cnt++; +} + +static u16 ms_get_unused_block(struct rts51x_chip *chip, int seg_no) +{ + struct ms_info *ms_card = &(chip->ms_card); + struct zone_entry *segment; + u16 phy_blk; + + segment = &(ms_card->segment[seg_no]); + + if (segment->unused_blk_cnt <= 0) + return 0xFFFF; + + phy_blk = segment->free_table[segment->get_index]; + segment->free_table[segment->get_index++] = 0xFFFF; + if (segment->get_index >= MS_FREE_TABLE_CNT) + segment->get_index = 0; + segment->unused_blk_cnt--; + + return phy_blk; +} + +static const unsigned short ms_start_idx[] = { + 0, 494, 990, 1486, 1982, 2478, 2974, 3470, + 3966, 4462, 4958, 5454, 5950, 6446, 6942, 7438, 7934 +}; + +static int ms_arbitrate_l2p(struct rts51x_chip *chip, u16 phy_blk, u16 log_off, + u8 us1, u8 us2) +{ + struct ms_info *ms_card = &(chip->ms_card); + struct zone_entry *segment; + int seg_no; + u16 tmp_blk; + + seg_no = (int)phy_blk >> 9; + segment = &(ms_card->segment[seg_no]); + tmp_blk = segment->l2p_table[log_off]; + + if (us1 != us2) { + if (us1 == 0) { + if (!(chip->card_wp & MS_CARD)) + ms_erase_block(chip, tmp_blk); + ms_set_unused_block(chip, tmp_blk); + segment->l2p_table[log_off] = phy_blk; + } else { + if (!(chip->card_wp & MS_CARD)) + ms_erase_block(chip, phy_blk); + ms_set_unused_block(chip, phy_blk); + } + } else { + if (phy_blk < tmp_blk) { + if (!(chip->card_wp & MS_CARD)) + ms_erase_block(chip, phy_blk); + ms_set_unused_block(chip, phy_blk); + } else { + if (!(chip->card_wp & MS_CARD)) + ms_erase_block(chip, tmp_blk); + ms_set_unused_block(chip, tmp_blk); + segment->l2p_table[log_off] = phy_blk; + } + } + + return STATUS_SUCCESS; +} + +static int ms_build_l2p_tbl(struct rts51x_chip *chip, int seg_no) +{ + struct ms_info *ms_card = &(chip->ms_card); + struct zone_entry *segment; + int retval, table_size, disable_cnt, defect_flag, i; + u16 start, end, phy_blk, log_blk, tmp_blk; + u8 extra[MS_EXTRA_SIZE], us1, us2; + + RTS51X_DEBUGP("ms_build_l2p_tbl: %d\n", seg_no); + + if (ms_card->segment == NULL) { + retval = ms_init_l2p_tbl(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } + + if (ms_card->segment[seg_no].build_flag) { + RTS51X_DEBUGP("l2p table of segment %d has been built\n", + seg_no); + return STATUS_SUCCESS; + } + + if (seg_no == 0) + table_size = 494; + else + table_size = 496; + + segment = &(ms_card->segment[seg_no]); + + if (segment->l2p_table == NULL) { + segment->l2p_table = vmalloc(table_size * 2); + if (segment->l2p_table == NULL) + TRACE_GOTO(chip, BUILD_FAIL); + } + memset((u8 *) (segment->l2p_table), 0xff, table_size * 2); + + if (segment->free_table == NULL) { + segment->free_table = vmalloc(MS_FREE_TABLE_CNT * 2); + if (segment->free_table == NULL) + TRACE_GOTO(chip, BUILD_FAIL); + } + memset((u8 *) (segment->free_table), 0xff, MS_FREE_TABLE_CNT * 2); + + start = (u16) seg_no << 9; + end = (u16) (seg_no + 1) << 9; + + disable_cnt = segment->disable_count; + + segment->get_index = segment->set_index = 0; + segment->unused_blk_cnt = 0; + + for (phy_blk = start; phy_blk < end; phy_blk++) { + if (disable_cnt) { + defect_flag = 0; + for (i = 0; i < segment->disable_count; i++) { + if (phy_blk == segment->defect_list[i]) { + defect_flag = 1; + break; + } + } + if (defect_flag) { + disable_cnt--; + continue; + } + } + + retval = + ms_read_extra_data(chip, phy_blk, 0, extra, MS_EXTRA_SIZE); + if (retval != STATUS_SUCCESS) { + RTS51X_DEBUGP("read extra data fail\n"); + ms_set_bad_block(chip, phy_blk); + continue; + } + + if (seg_no == ms_card->segment_cnt - 1) { + if (!(extra[1] & NOT_TRANSLATION_TABLE)) { + if (!(chip->card_wp & MS_CARD)) { + retval = ms_erase_block(chip, phy_blk); + if (retval != STATUS_SUCCESS) + continue; + extra[2] = 0xff; + extra[3] = 0xff; + } + } + } + + if (!(extra[0] & BLOCK_OK)) + continue; + if (!(extra[1] & NOT_BOOT_BLOCK)) + continue; + if ((extra[0] & PAGE_OK) != PAGE_OK) + continue; + + log_blk = ((u16) extra[2] << 8) | extra[3]; + + if (log_blk == 0xFFFF) { + if (!(chip->card_wp & MS_CARD)) { + retval = ms_erase_block(chip, phy_blk); + if (retval != STATUS_SUCCESS) + continue; + } + ms_set_unused_block(chip, phy_blk); + continue; + } + + if ((log_blk < ms_start_idx[seg_no]) || + (log_blk >= ms_start_idx[seg_no + 1])) { + if (!(chip->card_wp & MS_CARD)) { + retval = ms_erase_block(chip, phy_blk); + if (retval != STATUS_SUCCESS) + continue; + } + ms_set_unused_block(chip, phy_blk); + continue; + } + + if (segment->l2p_table[log_blk - ms_start_idx[seg_no]] == + 0xFFFF) { + segment->l2p_table[log_blk - ms_start_idx[seg_no]] = + phy_blk; + continue; + } + + us1 = extra[0] & 0x10; + tmp_blk = segment->l2p_table[log_blk - ms_start_idx[seg_no]]; + retval = + ms_read_extra_data(chip, tmp_blk, 0, extra, MS_EXTRA_SIZE); + if (retval != STATUS_SUCCESS) + continue; + us2 = extra[0] & 0x10; + + (void)ms_arbitrate_l2p(chip, phy_blk, + log_blk - ms_start_idx[seg_no], us1, + us2); + continue; + } + + segment->build_flag = 1; + + RTS51X_DEBUGP("unused block count: %d\n", segment->unused_blk_cnt); + + if (seg_no == ms_card->segment_cnt - 1) { + if (segment->unused_blk_cnt < 2) + chip->card_wp |= MS_CARD; + } else { + if (segment->unused_blk_cnt < 1) + chip->card_wp |= MS_CARD; + } + + if (chip->card_wp & MS_CARD) + return STATUS_SUCCESS; + + for (log_blk = ms_start_idx[seg_no]; log_blk < ms_start_idx[seg_no + 1]; + log_blk++) { + if (segment->l2p_table[log_blk - ms_start_idx[seg_no]] == + 0xFFFF) { + phy_blk = ms_get_unused_block(chip, seg_no); + if (phy_blk == 0xFFFF) { + chip->card_wp |= MS_CARD; + return STATUS_SUCCESS; + } + retval = ms_init_page(chip, phy_blk, log_blk, 0, 1); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, BUILD_FAIL); + segment->l2p_table[log_blk - ms_start_idx[seg_no]] = + phy_blk; + if (seg_no == ms_card->segment_cnt - 1) { + if (segment->unused_blk_cnt < 2) { + chip->card_wp |= MS_CARD; + return STATUS_SUCCESS; + } + } else { + if (segment->unused_blk_cnt < 1) { + chip->card_wp |= MS_CARD; + return STATUS_SUCCESS; + } + } + } + } + + if (seg_no == 0) { + for (log_blk = 0; log_blk < 494; log_blk++) { + tmp_blk = segment->l2p_table[log_blk]; + if (tmp_blk < ms_card->boot_block) { + RTS51X_DEBUGP("Boot block is not the first" + "normal block.\n"); + + if (chip->card_wp & MS_CARD) + break; + + phy_blk = ms_get_unused_block(chip, 0); +#ifdef MS_SPEEDUP + retval = + ms_auto_copy_page(chip, tmp_blk, phy_blk, + log_blk, 0, + ms_card->page_off + 1); +#else + retval = ms_copy_page(chip, tmp_blk, phy_blk, + log_blk, 0, + ms_card->page_off + 1); +#endif + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + segment->l2p_table[log_blk] = phy_blk; + + retval = ms_set_bad_block(chip, tmp_blk); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } + } + } + + return STATUS_SUCCESS; + +BUILD_FAIL: + segment->build_flag = 0; + if (segment->l2p_table) { + vfree(segment->l2p_table); + segment->l2p_table = NULL; + } + if (segment->free_table) { + vfree(segment->free_table); + segment->free_table = NULL; + } + + return STATUS_FAIL; +} + +int reset_ms_card(struct rts51x_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + + memset(ms_card, 0, sizeof(struct ms_info)); + + enable_card_clock(chip, MS_CARD); + + retval = rts51x_select_card(chip, MS_CARD); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + ms_card->ms_type = 0; + ms_card->last_rw_int = 0; + + retval = reset_ms_pro(chip); + if (retval != STATUS_SUCCESS) { + if (ms_card->check_ms_flow) { + retval = reset_ms(chip); + if (retval != STATUS_SUCCESS) { + if (chip->option.reset_or_rw_fail_set_pad_drive) { + rts51x_write_register(chip, + CARD_DRIVE_SEL, SD20_DRIVE_MASK, + DRIVE_8mA); + } + TRACE_RET(chip, retval); + } + } else { + if (chip->option.reset_or_rw_fail_set_pad_drive) { + rts51x_write_register(chip, CARD_DRIVE_SEL, + SD20_DRIVE_MASK, + DRIVE_8mA); + } + TRACE_RET(chip, retval); + } + } + + retval = ms_set_init_para(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + if (!CHK_MSPRO(ms_card)) { + retval = ms_build_l2p_tbl(chip, ms_card->total_block / 512 - 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } + + RTS51X_DEBUGP("ms_card->ms_type = 0x%x\n", ms_card->ms_type); + + return STATUS_SUCCESS; +} + +static int mspro_set_rw_cmd(struct rts51x_chip *chip, u32 start_sec, + u16 sec_cnt, u8 cmd) +{ + int retval, i; + u8 data[8]; + + data[0] = cmd; + data[1] = (u8) (sec_cnt >> 8); + data[2] = (u8) sec_cnt; + data[3] = (u8) (start_sec >> 24); + data[4] = (u8) (start_sec >> 16); + data[5] = (u8) (start_sec >> 8); + data[6] = (u8) start_sec; + data[7] = 0; + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = + ms_write_bytes(chip, PRO_EX_SET_CMD, 7, WAIT_INT, data, 8); + if (retval == STATUS_SUCCESS) + break; + } + if (i == MS_MAX_RETRY_COUNT) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +void mspro_stop_seq_mode(struct rts51x_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + + if (ms_card->seq_mode) { + retval = ms_switch_clock(chip); + if (retval != STATUS_SUCCESS) + return; + + ms_card->seq_mode = 0; + ms_card->total_sec_cnt = 0; + ms_card->last_rw_int = 0; + ms_send_cmd(chip, PRO_STOP, WAIT_INT); + + rts51x_ep0_write_register(chip, MC_FIFO_CTL, FIFO_FLUSH, + FIFO_FLUSH); + } +} + +static inline int ms_auto_tune_clock(struct rts51x_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + + if (chip->asic_code) { + if (ms_card->ms_clock > 30) + ms_card->ms_clock -= 20; + } else { + if (ms_card->ms_clock == CLK_80) + ms_card->ms_clock = CLK_60; + else if (ms_card->ms_clock == CLK_60) + ms_card->ms_clock = CLK_40; + } + + retval = ms_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + return STATUS_SUCCESS; +} + +static int mspro_rw_multi_sector(struct scsi_cmnd *srb, + struct rts51x_chip *chip, u32 start_sector, + u16 sector_cnt) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, mode_2k = 0; + u16 count; + u8 val, trans_mode, rw_tpc, rw_cmd; + + ms_set_err_code(chip, MS_NO_ERROR); + + ms_card->counter = 0; + + if (CHK_MSHG(ms_card)) { + if ((start_sector % 4) || (sector_cnt % 4)) { + if (srb->sc_data_direction == DMA_FROM_DEVICE) { + rw_tpc = PRO_READ_LONG_DATA; + rw_cmd = PRO_READ_DATA; + } else { + rw_tpc = PRO_WRITE_LONG_DATA; + rw_cmd = PRO_WRITE_DATA; + } + } else { + if (srb->sc_data_direction == DMA_FROM_DEVICE) { + rw_tpc = PRO_READ_QUAD_DATA; + rw_cmd = PRO_READ_2K_DATA; + } else { + rw_tpc = PRO_WRITE_QUAD_DATA; + rw_cmd = PRO_WRITE_2K_DATA; + } + mode_2k = 1; + } + } else { + if (srb->sc_data_direction == DMA_FROM_DEVICE) { + rw_tpc = PRO_READ_LONG_DATA; + rw_cmd = PRO_READ_DATA; + } else { + rw_tpc = PRO_WRITE_LONG_DATA; + rw_cmd = PRO_WRITE_DATA; + } + } + + retval = ms_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + if (srb->sc_data_direction == DMA_FROM_DEVICE) + trans_mode = MS_TM_AUTO_READ; + else + trans_mode = MS_TM_AUTO_WRITE; + + val = ms_card->last_rw_int; + + if (ms_card->seq_mode) { + if ((ms_card->pre_dir != srb->sc_data_direction) + || ((ms_card->pre_sec_addr + ms_card->pre_sec_cnt) != + start_sector) + || (mode_2k && (ms_card->seq_mode & MODE_512_SEQ)) + || (!mode_2k && (ms_card->seq_mode & MODE_2K_SEQ)) + || !(val & MS_INT_BREQ) + || ((ms_card->total_sec_cnt + sector_cnt) > 0xFE00)) { + ms_card->seq_mode = 0; + ms_card->total_sec_cnt = 0; + ms_card->last_rw_int = 0; + if (val & MS_INT_BREQ) { + retval = ms_send_cmd(chip, PRO_STOP, WAIT_INT); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + rts51x_ep0_write_register(chip, MC_FIFO_CTL, + FIFO_FLUSH, FIFO_FLUSH); + } + } + } + + if (!ms_card->seq_mode) { + ms_card->total_sec_cnt = 0; + if (sector_cnt >= 0x80) { + if ((ms_card->capacity - start_sector) > 0xFE00) + count = 0xFE00; + else + count = + (u16) (ms_card->capacity - start_sector); + if (count > sector_cnt) { + if (mode_2k) + ms_card->seq_mode |= MODE_2K_SEQ; + else + ms_card->seq_mode |= MODE_512_SEQ; + } + } else { + count = sector_cnt; + } + retval = mspro_set_rw_cmd(chip, start_sector, count, rw_cmd); + if (retval != STATUS_SUCCESS) { + ms_card->seq_mode = 0; + TRACE_RET(chip, retval); + } + } + + retval = + ms_transfer_data(chip, trans_mode, rw_tpc, sector_cnt, WAIT_INT, + mode_2k, scsi_sg_count(srb), scsi_sglist(srb), + scsi_bufflen(srb)); + if (retval != STATUS_SUCCESS) { + ms_card->seq_mode = 0; + rts51x_ep0_read_register(chip, MS_TRANS_CFG, &val); + rts51x_clear_ms_error(chip); + if (val & MS_INT_BREQ) + ms_send_cmd(chip, PRO_STOP, WAIT_INT); + if (val & (MS_CRC16_ERR | MS_RDY_TIMEOUT)) { + RTS51X_DEBUGP("MSPro CRC error, tune clock!\n"); + ms_auto_tune_clock(chip); + } + + TRACE_RET(chip, retval); + } + + ms_card->pre_sec_addr = start_sector; + ms_card->pre_sec_cnt = sector_cnt; + ms_card->pre_dir = srb->sc_data_direction; + ms_card->total_sec_cnt += sector_cnt; + + return STATUS_SUCCESS; +} + +static int mspro_read_format_progress(struct rts51x_chip *chip, + const int short_data_len) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i; + u32 total_progress, cur_progress; + u8 cnt, tmp; + u8 data[8]; + + ms_card->format_status = FORMAT_FAIL; + + retval = ms_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + RTS51X_READ_REG(chip, MS_TRANS_CFG, &tmp); + + if ((tmp & (MS_INT_CED | MS_INT_CMDNK | MS_INT_ERR)) == MS_INT_CED) { + ms_card->format_status = FORMAT_SUCCESS; + ms_card->pro_under_formatting = 0; + return STATUS_SUCCESS; + } + if (! + ((tmp & (MS_INT_BREQ | MS_INT_CED | MS_INT_CMDNK | MS_INT_ERR)) == + MS_INT_BREQ)) { + ms_card->pro_under_formatting = 0; + TRACE_RET(chip, STATUS_FAIL); + } + + if (short_data_len >= 256) + cnt = 0; + else + cnt = (u8) short_data_len; + + retval = + ms_read_bytes(chip, PRO_READ_SHORT_DATA, cnt, WAIT_INT, data, 8); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + total_progress = + (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; + cur_progress = + (data[4] << 24) | (data[5] << 16) | (data[6] << 8) | data[7]; + + RTS51X_DEBUGP("total_progress = %d, cur_progress = %d\n", + total_progress, cur_progress); + + if (total_progress == 0) { + ms_card->progress = 0; + } else { + u64 ulltmp = (u64) cur_progress * (u64) 65535; + do_div(ulltmp, total_progress); + ms_card->progress = (u16) ulltmp; + } + RTS51X_DEBUGP("progress = %d\n", ms_card->progress); + + for (i = 0; i < 2500; i++) { + RTS51X_READ_REG(chip, MS_TRANS_CFG, &tmp); + if (tmp & + (MS_INT_CED | MS_INT_CMDNK | MS_INT_BREQ | MS_INT_ERR)) + break; + + wait_timeout(1); + } + + if (i == 2500) + TRACE_RET(chip, STATUS_FAIL); + + RTS51X_DEBUGP("MSPro format tmp:%d\n", tmp); + + if (tmp & (MS_INT_CMDNK | MS_INT_ERR)) + TRACE_RET(chip, STATUS_FAIL); + if (tmp & MS_INT_CED) { + ms_card->format_status = FORMAT_SUCCESS; + ms_card->pro_under_formatting = 0; + } else if (tmp & MS_INT_BREQ) { + ms_card->format_status = FORMAT_IN_PROGRESS; + } else { + ms_card->format_status = FORMAT_FAIL; + ms_card->pro_under_formatting = 0; + TRACE_RET(chip, STATUS_FAIL); + } + + RTS51X_DEBUGP("MSPro format format_status:%d\n", + ms_card->format_status); + + return STATUS_SUCCESS; +} + +void mspro_polling_format_status(struct rts51x_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int i; + + if (ms_card->pro_under_formatting) { + for (i = 0; i < 65535; i++) { + mspro_read_format_progress(chip, MS_SHORT_DATA_LEN); + if (ms_card->format_status != FORMAT_IN_PROGRESS) + break; + } + } + + return; +} + +void mspro_format_sense(struct rts51x_chip *chip, unsigned int lun) +{ + struct ms_info *ms_card = &(chip->ms_card); + + if (CHK_FORMAT_STATUS(ms_card, FORMAT_SUCCESS)) { + set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); + ms_card->pro_under_formatting = 0; + ms_card->progress = 0; + } else if (CHK_FORMAT_STATUS(ms_card, FORMAT_IN_PROGRESS)) { + set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04, + 0, (u16) (ms_card->progress)); + } else { + set_sense_type(chip, lun, SENSE_TYPE_FORMAT_CMD_FAILED); + ms_card->pro_under_formatting = 0; + ms_card->progress = 0; + } +} + +int mspro_format(struct scsi_cmnd *srb, struct rts51x_chip *chip, + int short_data_len, int quick_format) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i; + u8 buf[8], tmp; + u16 para; + + retval = ms_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = ms_set_rw_reg_addr(chip, 0x00, 0x00, Pro_TPCParm, 0x01); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + memset(buf, 0, 2); + switch (short_data_len) { + case 32: + buf[0] = 0; + break; + case 64: + buf[0] = 1; + break; + case 128: + buf[0] = 2; + break; + case 256: + default: + buf[0] = 3; + break; + } + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = + ms_write_bytes(chip, PRO_WRITE_REG, 1, NO_WAIT_INT, buf, 2); + if (retval == STATUS_SUCCESS) + break; + } + if (i == MS_MAX_RETRY_COUNT) + TRACE_RET(chip, STATUS_FAIL); + /* Format command */ + if (quick_format) + para = 0x0000; + else + para = 0x0001; + retval = mspro_set_rw_cmd(chip, 0, para, PRO_FORMAT); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + /* Check INT */ + RTS51X_READ_REG(chip, MS_TRANS_CFG, &tmp); + if (tmp & (MS_INT_CMDNK | MS_INT_ERR)) + TRACE_RET(chip, STATUS_FAIL); + + if ((tmp & (MS_INT_BREQ | MS_INT_CED)) == MS_INT_BREQ) { + ms_card->pro_under_formatting = 1; + ms_card->progress = 0; + ms_card->format_status = FORMAT_IN_PROGRESS; + return STATUS_SUCCESS; + } + + if (tmp & MS_INT_CED) { + ms_card->pro_under_formatting = 0; + ms_card->progress = 0; + ms_card->format_status = FORMAT_SUCCESS; + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_NO_SENSE); + return STATUS_SUCCESS; + } + + TRACE_RET(chip, STATUS_FAIL); +} + +#ifdef MS_SPEEDUP +static int ms_read_multiple_pages(struct rts51x_chip *chip, u16 phy_blk, + u16 log_blk, u8 start_page, u8 end_page, + u8 *buf, void **ptr, unsigned int *offset) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + int send_blkend; + u8 extra[MS_EXTRA_SIZE], val1, val2, data[6]; + u8 page_cnt = end_page - start_page, page_addr, sec_cnt; + + if (end_page != (ms_card->page_off + 1)) + send_blkend = 1; + else + send_blkend = 0; + + retval = + ms_read_extra_data(chip, phy_blk, start_page, extra, MS_EXTRA_SIZE); + if (retval == STATUS_SUCCESS) { + if ((extra[1] & 0x30) != 0x30) { + ms_set_err_code(chip, MS_FLASH_READ_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + if (CHK_MS4BIT(ms_card)) { + /* Parallel interface */ + data[0] = 0x88; + } else { + /* Serial interface */ + data[0] = 0x80; + } + /* Block Address */ + data[1] = 0; + data[2] = (u8) (phy_blk >> 8); + data[3] = (u8) phy_blk; + /* Page Number + * Extra data access mode */ + data[4] = 0; + data[5] = start_page; + + retval = + ms_auto_set_cmd(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, 6, + BLOCK_READ, WAIT_INT, data, 6, &val1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + rts51x_init_cmd(chip); + + if (send_blkend) + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_BLKEND, SET_BLKEND, + SET_BLKEND); + else + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_BLKEND, SET_BLKEND, 0); + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, WAIT_INT, + NO_WAIT_INT); + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_SECTOR_CNT_L, 0xFF, + (u8) page_cnt); + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_SECTOR_CNT_H, 0xFF, 0); + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, READ_PAGE_DATA); + + trans_dma_enable(DMA_FROM_DEVICE, chip, 512 * page_cnt, DMA_512); + + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, + MS_TRANSFER_START | MS_TM_MULTI_READ); + rts51x_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, MS_TRANSFER_END, + MS_TRANSFER_END); + + retval = rts51x_send_cmd(chip, MODE_CDIR | STAGE_MS_STATUS, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = + rts51x_transfer_data_partial(chip, RCV_BULK_PIPE(chip), (void *)buf, + ptr, offset, 512 * page_cnt, + scsi_sg_count(chip->srb), NULL, 2000); + if (retval != STATUS_SUCCESS) { + rts51x_clear_ms_error(chip); + if (retval == STATUS_TIMEDOUT) + TRACE_RET(chip, retval); + TRACE_GOTO(chip, Fail); + } + retval = rts51x_get_rsp(chip, 3, 200); + if (CHECK_MS_TRANS_FAIL(chip, retval)) { + rts51x_clear_ms_error(chip); + if (retval == STATUS_TIMEDOUT) + TRACE_RET(chip, retval); + TRACE_GOTO(chip, Fail); + } + + return STATUS_SUCCESS; + +Fail: + rts51x_init_cmd(chip); + + rts51x_add_cmd(chip, READ_REG_CMD, MS_SECTOR_CNT_L, 0, 0); + + retval = rts51x_send_cmd(chip, MODE_CR | STAGE_MS_STATUS, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = rts51x_get_rsp(chip, 3, 200); + + if (CHECK_MS_TRANS_FAIL(chip, retval)) + TRACE_RET(chip, STATUS_FAIL); + + sec_cnt = chip->rsp_buf[0]; + RTS51X_DEBUGP("%d pages need be trasferred, %d pages remained\n", + (int)page_cnt, (int)sec_cnt); + page_addr = start_page + (page_cnt - sec_cnt); + + if (CHK_MS4BIT(ms_card)) { + val1 = chip->rsp_buf[1]; + RTS51X_DEBUGP("MS_TRANS_CFG: 0x%x\n", val1); + } else { + val1 = 0; + } + + val2 = chip->rsp_buf[2]; + RTS51X_DEBUGP("GET_INT: 0x%x\n", val2); + + if ((val1 & INT_CMDNK) || (val2 & INT_REG_CMDNK)) { + ms_set_err_code(chip, MS_CMD_NK); + TRACE_RET(chip, STATUS_FAIL); + } + + if ((val1 & INT_ERR) || (val2 & INT_REG_ERR)) { + if ((val1 & INT_BREQ) || (val2 & INT_REG_BREQ)) { + retval = ms_read_status_reg(chip); + if (retval != STATUS_SUCCESS) { + if (!(chip->card_wp & MS_CARD)) { + reset_ms(chip); + ms_set_page_status(log_blk, setPS_NG, + extra, MS_EXTRA_SIZE); + ms_write_extra_data(chip, phy_blk, + page_addr, extra, + MS_EXTRA_SIZE); + } + ms_set_err_code(chip, MS_FLASH_READ_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } else { + ms_set_err_code(chip, MS_FLASH_READ_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } else { + if (CHK_MS4BIT(ms_card)) { + if (!(val1 & INT_BREQ) && !(val2 & INT_REG_BREQ)) { + ms_set_err_code(chip, MS_BREQ_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } else { + if (!(val2 & INT_REG_BREQ)) { + ms_set_err_code(chip, MS_BREQ_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } + } + + TRACE_RET(chip, STATUS_FAIL); +} + +static int ms_write_multiple_pages(struct rts51x_chip *chip, u16 old_blk, + u16 new_blk, u16 log_blk, u8 start_page, + u8 end_page, u8 *buf, void **ptr, + unsigned int *offset) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i; + int send_blkend; + u8 val, data[16]; + u8 page_cnt = end_page - start_page; + + if ((end_page == (ms_card->page_off + 1)) || (page_cnt == 1)) + send_blkend = 0; + else + send_blkend = 1; + + if (!start_page) { + if (CHK_MS4BIT(ms_card)) { + /* Parallel interface */ + data[0] = 0x88; + } else { + /* Serial interface */ + data[0] = 0x80; + } + /* Block Address */ + data[1] = 0; + data[2] = (u8) (old_blk >> 8); + data[3] = (u8) old_blk; + data[4] = 0x80; + data[5] = 0; + data[6] = 0xEF; + data[7] = 0xFF; + + retval = + ms_auto_set_cmd(chip, OverwriteFlag, MS_EXTRA_SIZE, + SystemParm, 7, BLOCK_WRITE, WAIT_INT, data, + 7, &val); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } + + retval = + ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, + (6 + MS_EXTRA_SIZE)); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + ms_set_err_code(chip, MS_NO_ERROR); + + if (CHK_MS4BIT(ms_card)) { + /* Parallel interface */ + data[0] = 0x88; + } else { + /* Serial interface */ + data[0] = 0x80; + } + /* Block Address */ + data[1] = 0; + data[2] = (u8) (new_blk >> 8); + data[3] = (u8) new_blk; + /* Page Number + * Extra data access mode */ + if (page_cnt == 1) { + /* Single page access mode */ + data[4] = 0x20; + } else { + /* Block access mode */ + data[4] = 0; + } + data[5] = start_page; + data[6] = 0xF8; + data[7] = 0xFF; + data[8] = (u8) (log_blk >> 8); + data[9] = (u8) log_blk; + + for (i = 0x0A; i < 0x10; i++) { + /* ECC */ + data[i] = 0xFF; + } + + retval = + ms_auto_set_cmd(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, + (6 + MS_EXTRA_SIZE), BLOCK_WRITE, WAIT_INT, data, + 16, &val); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + rts51x_init_cmd(chip); + + if (send_blkend) + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_BLKEND, SET_BLKEND, + SET_BLKEND); + else + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_BLKEND, SET_BLKEND, 0); + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, WAIT_INT, + NO_WAIT_INT); + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_SECTOR_CNT_L, 0xFF, + (u8) page_cnt); + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_SECTOR_CNT_H, 0xFF, 0); + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, WRITE_PAGE_DATA); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, + RING_BUFFER); + + trans_dma_enable(DMA_TO_DEVICE, chip, 512 * page_cnt, DMA_512); + + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, + MS_TRANSFER_START | MS_TM_MULTI_WRITE); + rts51x_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, MS_TRANSFER_END, + MS_TRANSFER_END); + + retval = rts51x_send_cmd(chip, MODE_CDOR | STAGE_MS_STATUS, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = + rts51x_transfer_data_partial(chip, SND_BULK_PIPE(chip), (void *)buf, + ptr, offset, 512 * page_cnt, + scsi_sg_count(chip->srb), NULL, 2000); + if (retval != STATUS_SUCCESS) { + rts51x_clear_ms_error(chip); + TRACE_RET(chip, retval); + } + + retval = rts51x_get_rsp(chip, 3, 2000); + + + if (CHECK_MS_TRANS_FAIL(chip, retval)) { + rts51x_clear_ms_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +#else + +static int ms_read_multiple_pages(struct rts51x_chip *chip, u16 phy_blk, + u16 log_blk, u8 start_page, u8 end_page, + u8 *buf, void **ptr, unsigned int *offset) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i; + u8 extra[MS_EXTRA_SIZE], page_addr, val, trans_cfg, data[6]; + + retval = + ms_read_extra_data(chip, phy_blk, start_page, extra, MS_EXTRA_SIZE); + if (retval == STATUS_SUCCESS) { + if ((extra[1] & 0x30) != 0x30) { + ms_set_err_code(chip, MS_FLASH_READ_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + retval = + ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, + 6); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + /* Write REG */ + if (CHK_MS4BIT(ms_card)) { + /* Parallel interface */ + data[0] = 0x88; + } else { + /* Serial interface */ + data[0] = 0x80; + } + /* Block Address */ + data[1] = 0; + data[2] = (u8) (phy_blk >> 8); + data[3] = (u8) phy_blk; + /* Page Number + * Extra data access mode */ + data[4] = 0; + data[5] = start_page; + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = + ms_write_bytes(chip, WRITE_REG, 6, NO_WAIT_INT, data, 6); + if (retval == STATUS_SUCCESS) + break; + } + if (i == MS_MAX_RETRY_COUNT) + TRACE_RET(chip, STATUS_FAIL); + + ms_set_err_code(chip, MS_NO_ERROR); + + retval = ms_send_cmd(chip, BLOCK_READ, WAIT_INT); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + for (page_addr = start_page; page_addr < end_page; page_addr++) { + ms_set_err_code(chip, MS_NO_ERROR); + + if (monitor_card_cd(chip, MS_CARD) == CD_NOT_EXIST) { + ms_set_err_code(chip, MS_NO_CARD); + chip->card_exist &= ~MS_CARD; + chip->card_ready &= ~MS_CARD; + TRACE_RET(chip, STATUS_FAIL); + } + /* GET_INT Register */ + retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + if (val & INT_REG_CMDNK) { + ms_set_err_code(chip, MS_CMD_NK); + TRACE_RET(chip, STATUS_FAIL); + } + if (val & INT_REG_ERR) { + if (val & INT_REG_BREQ) { + retval = ms_read_status_reg(chip); + if (retval != STATUS_SUCCESS) { + if (!(chip->card_wp & MS_CARD)) { + reset_ms(chip); + ms_set_page_status(log_blk, + setPS_NG, extra, + MS_EXTRA_SIZE); + ms_write_extra_data(chip, + phy_blk, page_addr, + extra, MS_EXTRA_SIZE); + } + ms_set_err_code(chip, + MS_FLASH_READ_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } else { + ms_set_err_code(chip, MS_FLASH_READ_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } else { + if (!(val & INT_REG_BREQ)) { + ms_set_err_code(chip, MS_BREQ_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + if (page_addr == (end_page - 1)) { + if (!(val & INT_REG_CED)) { + retval = ms_send_cmd(chip, BLOCK_END, WAIT_INT); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } + retval = + ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, + 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + if (!(val & INT_REG_CED)) { + ms_set_err_code(chip, MS_FLASH_READ_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + + trans_cfg = NO_WAIT_INT; + } else { + trans_cfg = WAIT_INT; + } + + rts51x_init_cmd(chip); + + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, + READ_PAGE_DATA); + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, + trans_cfg); + + trans_dma_enable(DMA_FROM_DEVICE, chip, 512, DMA_512); + + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, + MS_TRANSFER_START | MS_TM_NORMAL_READ); + rts51x_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, + MS_TRANSFER_END, MS_TRANSFER_END); + + retval = rts51x_send_cmd(chip, MODE_CDIR, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = + rts51x_transfer_data_partial(chip, RCV_BULK_PIPE(chip), + (void *)buf, ptr, offset, 512, + scsi_sg_count(chip->srb), NULL, + 2000); + if (retval != STATUS_SUCCESS) { + if (retval == STATUS_TIMEDOUT) { + ms_set_err_code(chip, MS_TO_ERROR); + rts51x_clear_ms_error(chip); + TRACE_RET(chip, retval); + } + + retval = + rts51x_ep0_read_register(chip, MS_TRANS_CFG, &val); + if (retval != STATUS_SUCCESS) { + ms_set_err_code(chip, MS_TO_ERROR); + rts51x_clear_ms_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + if (val & (MS_CRC16_ERR | MS_RDY_TIMEOUT)) { + ms_set_err_code(chip, MS_CRC16_ERROR); + rts51x_clear_ms_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + } + + retval = rts51x_get_rsp(chip, 1, 2000); + if (CHECK_MS_TRANS_FAIL(chip, retval)) { + if (retval == STATUS_TIMEDOUT) { + ms_set_err_code(chip, MS_TO_ERROR); + rts51x_clear_ms_error(chip); + TRACE_RET(chip, retval); + } + + retval = + rts51x_ep0_read_register(chip, MS_TRANS_CFG, &val); + if (retval != STATUS_SUCCESS) { + ms_set_err_code(chip, MS_TO_ERROR); + rts51x_clear_ms_error(chip); + TRACE_RET(chip, retval); + } + if (val & (MS_CRC16_ERR | MS_RDY_TIMEOUT)) { + ms_set_err_code(chip, MS_CRC16_ERROR); + rts51x_clear_ms_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + } + } + + return STATUS_SUCCESS; +} + +static int ms_write_multiple_pages(struct rts51x_chip *chip, u16 old_blk, + u16 new_blk, u16 log_blk, u8 start_page, + u8 end_page, u8 *buf, void **ptr, + unsigned int *offset) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i; + u8 page_addr, val, data[16]; + + if (!start_page) { + retval = + ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, + SystemParm, 7); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + if (CHK_MS4BIT(ms_card)) { + /* Parallel interface */ + data[0] = 0x88; + } else { + /* Serial interface */ + data[0] = 0x80; + } + /* Block Address */ + data[1] = 0; + data[2] = (u8) (old_blk >> 8); + data[3] = (u8) old_blk; + data[4] = 0x80; + data[5] = 0; + data[6] = 0xEF; + data[7] = 0xFF; + + retval = + ms_write_bytes(chip, WRITE_REG, 7, NO_WAIT_INT, data, 8); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + /* GET_INT Register */ + ms_set_err_code(chip, MS_NO_ERROR); + retval = + ms_transfer_tpc(chip, MS_TM_READ_BYTES, GET_INT, 1, + NO_WAIT_INT); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } + + retval = + ms_set_rw_reg_addr(chip, OverwriteFlag, MS_EXTRA_SIZE, SystemParm, + (6 + MS_EXTRA_SIZE)); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + ms_set_err_code(chip, MS_NO_ERROR); + + if (CHK_MS4BIT(ms_card)) { + /* Parallel interface */ + data[0] = 0x88; + } else { + /* Serial interface */ + data[0] = 0x80; + } + /* Block Address */ + data[1] = 0; + data[2] = (u8) (new_blk >> 8); + data[3] = (u8) new_blk; + /* Page Number + * Extra data access mode */ + if ((end_page - start_page) == 1) { + /* Single page access mode */ + data[4] = 0x20; + } else { + /* Block access mode */ + data[4] = 0; + } + data[5] = start_page; + data[6] = 0xF8; + data[7] = 0xFF; + data[8] = (u8) (log_blk >> 8); + data[9] = (u8) log_blk; + + for (i = 0x0A; i < 0x10; i++) { + /* ECC */ + data[i] = 0xFF; + } + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = + ms_write_bytes(chip, WRITE_REG, 6 + MS_EXTRA_SIZE, + NO_WAIT_INT, data, 16); + if (retval == STATUS_SUCCESS) + break; + } + if (i == MS_MAX_RETRY_COUNT) + TRACE_RET(chip, STATUS_FAIL); + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = ms_send_cmd(chip, BLOCK_WRITE, WAIT_INT); + if (retval == STATUS_SUCCESS) + break; + } + if (i == MS_MAX_RETRY_COUNT) + TRACE_RET(chip, STATUS_FAIL); + /* GET_INT Register */ + retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + for (page_addr = start_page; page_addr < end_page; page_addr++) { + ms_set_err_code(chip, MS_NO_ERROR); + + if (monitor_card_cd(chip, MS_CARD) == CD_NOT_EXIST) { + ms_set_err_code(chip, MS_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + + if (val & INT_REG_CMDNK) { + ms_set_err_code(chip, MS_CMD_NK); + TRACE_RET(chip, STATUS_FAIL); + } + if (val & INT_REG_ERR) { + ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + if (!(val & INT_REG_BREQ)) { + ms_set_err_code(chip, MS_BREQ_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + + udelay(30); + + rts51x_init_cmd(chip); + + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, + WRITE_PAGE_DATA); + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, + WAIT_INT); + + trans_dma_enable(DMA_TO_DEVICE, chip, 512, DMA_512); + + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, + MS_TRANSFER_START | MS_TM_NORMAL_WRITE); + rts51x_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, + MS_TRANSFER_END, MS_TRANSFER_END); + + retval = rts51x_send_cmd(chip, MODE_CDOR, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = + rts51x_transfer_data_partial(chip, SND_BULK_PIPE(chip), + (void *)buf, ptr, offset, 512, + scsi_sg_count(chip->srb), NULL, + 2000); + if (retval != STATUS_SUCCESS) { + ms_set_err_code(chip, MS_TO_ERROR); + rts51x_clear_ms_error(chip); + + if (retval == STATUS_TIMEDOUT) + TRACE_RET(chip, STATUS_TIMEDOUT); + else + TRACE_RET(chip, STATUS_FAIL); + } + + retval = rts51x_get_rsp(chip, 1, 2000); + if (CHECK_MS_TRANS_FAIL(chip, retval)) { + ms_set_err_code(chip, MS_TO_ERROR); + rts51x_clear_ms_error(chip); + + if (retval == STATUS_TIMEDOUT) + TRACE_RET(chip, STATUS_TIMEDOUT); + else + TRACE_RET(chip, STATUS_FAIL); + } + /* GET_INT Register */ + retval = ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, &val, 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + if ((end_page - start_page) == 1) { + if (!(val & INT_REG_CED)) { + /* Command can not be executed */ + ms_set_err_code(chip, MS_FLASH_WRITE_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } else { + if (page_addr == (end_page - 1)) { + if (!(val & INT_REG_CED)) { + retval = + ms_send_cmd(chip, BLOCK_END, + WAIT_INT); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } + /* GET_INT Register */ + retval = + ms_read_bytes(chip, GET_INT, 1, NO_WAIT_INT, + &val, 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } + + if ((page_addr == (end_page - 1)) + || (page_addr == ms_card->page_off)) { + if (!(val & INT_REG_CED)) { + ms_set_err_code(chip, + MS_FLASH_WRITE_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } + } + } + + return STATUS_SUCCESS; +} +#endif + +static int ms_finish_write(struct rts51x_chip *chip, u16 old_blk, u16 new_blk, + u16 log_blk, u8 page_off) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, seg_no; + +#ifdef MS_SPEEDUP + retval = ms_auto_copy_page(chip, old_blk, new_blk, log_blk, + page_off, ms_card->page_off + 1); +#else + retval = ms_copy_page(chip, old_blk, new_blk, log_blk, + page_off, ms_card->page_off + 1); +#endif + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + seg_no = old_blk >> 9; + + if (MS_TST_BAD_BLOCK_FLG(ms_card)) { + MS_CLR_BAD_BLOCK_FLG(ms_card); + ms_set_bad_block(chip, old_blk); + } else { + retval = ms_erase_block(chip, old_blk); + if (retval == STATUS_SUCCESS) + ms_set_unused_block(chip, old_blk); + } + + ms_set_l2p_tbl(chip, seg_no, log_blk - ms_start_idx[seg_no], new_blk); + + return STATUS_SUCCESS; +} + +static int ms_prepare_write(struct rts51x_chip *chip, u16 old_blk, u16 new_blk, + u16 log_blk, u8 start_page) +{ + int retval; + + if (start_page) { +#ifdef MS_SPEEDUP + retval = + ms_auto_copy_page(chip, old_blk, new_blk, log_blk, 0, + start_page); +#else + retval = + ms_copy_page(chip, old_blk, new_blk, log_blk, 0, + start_page); +#endif + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } + + return STATUS_SUCCESS; +} + +int ms_delay_write(struct rts51x_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + struct ms_delay_write_tag *delay_write = &(ms_card->delay_write); + int retval; + + if (delay_write->delay_write_flag) { + retval = ms_set_init_para(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + delay_write->delay_write_flag = 0; + retval = ms_finish_write(chip, + delay_write->old_phyblock, + delay_write->new_phyblock, + delay_write->logblock, + delay_write->pageoff); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } + + return STATUS_SUCCESS; +} + +static inline void ms_rw_fail(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + if (srb->sc_data_direction == DMA_FROM_DEVICE) + set_sense_type(chip, SCSI_LUN(srb), + SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + else + set_sense_type(chip, SCSI_LUN(srb), SENSE_TYPE_MEDIA_WRITE_ERR); +} + +static int ms_rw_multi_sector(struct scsi_cmnd *srb, struct rts51x_chip *chip, + u32 start_sector, u16 sector_cnt) +{ + struct ms_info *ms_card = &(chip->ms_card); + unsigned int lun = SCSI_LUN(srb); + int retval, seg_no; + unsigned int offset = 0; + u16 old_blk = 0, new_blk = 0, log_blk, total_sec_cnt = sector_cnt; + u8 start_page, end_page = 0, page_cnt; + u8 *buf; + void *ptr = NULL; + struct ms_delay_write_tag *delay_write = &(ms_card->delay_write); + + ms_set_err_code(chip, MS_NO_ERROR); + + ms_card->counter = 0; + + buf = (u8 *) scsi_sglist(srb); + + retval = ms_switch_clock(chip); + if (retval != STATUS_SUCCESS) { + ms_rw_fail(srb, chip); + TRACE_RET(chip, retval); + } + + log_blk = (u16) (start_sector >> ms_card->block_shift); + start_page = (u8) (start_sector & ms_card->page_off); + + for (seg_no = 0; seg_no < sizeof(ms_start_idx) / 2; seg_no++) { + if (log_blk < ms_start_idx[seg_no + 1]) + break; + } + + if (ms_card->segment[seg_no].build_flag == 0) { + retval = ms_build_l2p_tbl(chip, seg_no); + if (retval != STATUS_SUCCESS) { + chip->card_fail |= MS_CARD; + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, retval); + } + } + + if (srb->sc_data_direction == DMA_TO_DEVICE) { + if (delay_write->delay_write_flag && + (delay_write->logblock == log_blk) && + (start_page > delay_write->pageoff)) { + delay_write->delay_write_flag = 0; +#ifdef MS_SPEEDUP + retval = ms_auto_copy_page(chip, + delay_write->old_phyblock, + delay_write->new_phyblock, + log_blk, + delay_write->pageoff, + start_page); +#else + retval = ms_copy_page(chip, + delay_write->old_phyblock, + delay_write->new_phyblock, + log_blk, delay_write->pageoff, + start_page); +#endif + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, retval); + } + old_blk = delay_write->old_phyblock; + new_blk = delay_write->new_phyblock; + } else if (delay_write->delay_write_flag && + (delay_write->logblock == log_blk) && + (start_page == delay_write->pageoff)) { + delay_write->delay_write_flag = 0; + old_blk = delay_write->old_phyblock; + new_blk = delay_write->new_phyblock; + } else { + retval = ms_delay_write(chip); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, retval); + } + old_blk = + ms_get_l2p_tbl(chip, seg_no, + log_blk - ms_start_idx[seg_no]); + new_blk = ms_get_unused_block(chip, seg_no); + if ((old_blk == 0xFFFF) || (new_blk == 0xFFFF)) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = + ms_prepare_write(chip, old_blk, new_blk, log_blk, + start_page); + if (retval != STATUS_SUCCESS) { + if (monitor_card_cd(chip, MS_CARD) == + CD_NOT_EXIST) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, STATUS_FAIL); + } + + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, retval); + } + } + } else { + retval = ms_delay_write(chip); + if (retval != STATUS_SUCCESS) { + if (monitor_card_cd(chip, MS_CARD) == CD_NOT_EXIST) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, STATUS_FAIL); + } + + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, retval); + } + old_blk = + ms_get_l2p_tbl(chip, seg_no, + log_blk - ms_start_idx[seg_no]); + if (old_blk == 0xFFFF) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + RTS51X_DEBUGP("seg_no = %d, old_blk = 0x%x, new_blk = 0x%x\n", seg_no, + old_blk, new_blk); + + while (total_sec_cnt) { + if ((start_page + total_sec_cnt) > (ms_card->page_off + 1)) + end_page = ms_card->page_off + 1; + else + end_page = start_page + (u8) total_sec_cnt; + page_cnt = end_page - start_page; + + RTS51X_DEBUGP("start_page = %d, end_page = %d," + "page_cnt = %d\n", + start_page, end_page, page_cnt); + + if (srb->sc_data_direction == DMA_FROM_DEVICE) + retval = ms_read_multiple_pages(chip, + old_blk, log_blk, + start_page, end_page, + buf, &ptr, &offset); + else + retval = ms_write_multiple_pages(chip, old_blk, + new_blk, log_blk, + start_page, end_page, + buf, &ptr, &offset); + + if (retval != STATUS_SUCCESS) { + if (monitor_card_cd(chip, MS_CARD) == CD_NOT_EXIST) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, STATUS_FAIL); + } + + ms_rw_fail(srb, chip); + TRACE_RET(chip, retval); + } + /* Update L2P table if need */ + if (srb->sc_data_direction == DMA_TO_DEVICE) { + if (end_page == (ms_card->page_off + 1)) { + retval = ms_erase_block(chip, old_blk); + if (retval == STATUS_SUCCESS) + ms_set_unused_block(chip, old_blk); + ms_set_l2p_tbl(chip, seg_no, + log_blk - ms_start_idx[seg_no], + new_blk); + } + } + + total_sec_cnt -= page_cnt; + + if (total_sec_cnt == 0) + break; + + log_blk++; + + for (seg_no = 0; seg_no < sizeof(ms_start_idx) / 2; seg_no++) { + if (log_blk < ms_start_idx[seg_no + 1]) + break; + } + + if (ms_card->segment[seg_no].build_flag == 0) { + retval = ms_build_l2p_tbl(chip, seg_no); + if (retval != STATUS_SUCCESS) { + chip->card_fail |= MS_CARD; + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, retval); + } + } + + old_blk = + ms_get_l2p_tbl(chip, seg_no, + log_blk - ms_start_idx[seg_no]); + if (old_blk == 0xFFFF) { + ms_rw_fail(srb, chip); + TRACE_RET(chip, STATUS_FAIL); + } + + if (srb->sc_data_direction == DMA_TO_DEVICE) { + new_blk = ms_get_unused_block(chip, seg_no); + if (new_blk == 0xFFFF) { + ms_rw_fail(srb, chip); + TRACE_RET(chip, STATUS_FAIL); + } + } + + RTS51X_DEBUGP("seg_no = %d, old_blk = 0x%x, new_blk = 0x%x\n", + seg_no, old_blk, new_blk); + + start_page = 0; + } + + if (srb->sc_data_direction == DMA_TO_DEVICE) { + if (end_page < (ms_card->page_off + 1)) { + delay_write->delay_write_flag = 1; + delay_write->old_phyblock = old_blk; + delay_write->new_phyblock = new_blk; + delay_write->logblock = log_blk; + delay_write->pageoff = end_page; + } + } + + scsi_set_resid(srb, 0); + + return STATUS_SUCCESS; +} + +int ms_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, + u16 sector_cnt) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + + if (CHK_MSPRO(ms_card)) + retval = + mspro_rw_multi_sector(srb, chip, start_sector, sector_cnt); + else + retval = + ms_rw_multi_sector(srb, chip, start_sector, sector_cnt); + + return retval; +} + +void ms_free_l2p_tbl(struct rts51x_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int i = 0; + + if (ms_card->segment != NULL) { + for (i = 0; i < ms_card->segment_cnt; i++) { + if (ms_card->segment[i].l2p_table != NULL) { + vfree(ms_card->segment[i].l2p_table); + ms_card->segment[i].l2p_table = NULL; + } + if (ms_card->segment[i].free_table != NULL) { + vfree(ms_card->segment[i].free_table); + ms_card->segment[i].free_table = NULL; + } + } + vfree(ms_card->segment); + ms_card->segment = NULL; + } +} + +void ms_cleanup_work(struct rts51x_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + + if (CHK_MSPRO(ms_card)) { + if (ms_card->seq_mode) { + RTS51X_DEBUGP("MS Pro: stop transmission\n"); + mspro_stop_seq_mode(chip); + ms_card->counter = 0; + } + if (CHK_MSHG(ms_card)) { + u8 value; + rts51x_read_register(chip, MS_CFG, &value); + if (value & MS_2K_SECTOR_MODE) + rts51x_write_register(chip, MS_CFG, + MS_2K_SECTOR_MODE, 0x00); + } + } else if ((!CHK_MSPRO(ms_card)) + && ms_card->delay_write.delay_write_flag) { + RTS51X_DEBUGP("MS: delay write\n"); + ms_delay_write(chip); + ms_card->counter = 0; + } +} + +int ms_power_off_card3v3(struct rts51x_chip *chip) +{ + int retval; + + rts51x_init_cmd(chip); + + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_CLK_EN, MS_CLK_EN, 0); + if (chip->asic_code) + ms_pull_ctl_disable(chip); + else + rts51x_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, + FPGA_MS_PULL_CTL_BIT | 0x20, + FPGA_MS_PULL_CTL_BIT); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_OE, MS_OUTPUT_EN, 0); + if (!chip->option.FT2_fast_mode) { + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, POWER_MASK, + POWER_OFF); + } + + retval = rts51x_send_cmd(chip, MODE_C, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + return STATUS_SUCCESS; +} + +int release_ms_card(struct rts51x_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + + RTS51X_DEBUGP("release_ms_card\n"); + + ms_card->delay_write.delay_write_flag = 0; + ms_card->pro_under_formatting = 0; + + chip->card_ready &= ~MS_CARD; + chip->card_fail &= ~MS_CARD; + chip->card_wp &= ~MS_CARD; + + ms_free_l2p_tbl(chip); + + rts51x_write_register(chip, SFSM_ED, HW_CMD_STOP, HW_CMD_STOP); + + memset(ms_card->raw_sys_info, 0, 96); +#ifdef SUPPORT_PCGL_1P18 + memset(ms_card->raw_model_name, 0, 48); +#endif + + retval = ms_power_off_card3v3(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + return STATUS_SUCCESS; +} diff --git a/drivers/staging/rts5139/ms.h b/drivers/staging/rts5139/ms.h new file mode 100644 index 0000000..f9d46d2 --- /dev/null +++ b/drivers/staging/rts5139/ms.h @@ -0,0 +1,263 @@ +/* Driver for Realtek RTS51xx USB card reader + * Header file + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + * Maintainer: + * Edwin Rong (edwin_rong@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#ifndef __RTS51X_MS_H +#define __RTS51X_MS_H + +#include "rts51x_chip.h" + +#define MS_MAX_RETRY_COUNT 3 + +#define MS_EXTRA_SIZE 0x9 + +#define WRT_PRTCT 0x01 + +/* Error Code */ +#define MS_NO_ERROR 0x00 +#define MS_CRC16_ERROR 0x80 +#define MS_TO_ERROR 0x40 +#define MS_NO_CARD 0x20 +#define MS_NO_MEMORY 0x10 +#define MS_CMD_NK 0x08 +#define MS_FLASH_READ_ERROR 0x04 +#define MS_FLASH_WRITE_ERROR 0x02 +#define MS_BREQ_ERROR 0x01 +#define MS_NOT_FOUND 0x03 + +/* Transfer Protocol Command */ +#define READ_PAGE_DATA 0x02 +#define READ_REG 0x04 +#define GET_INT 0x07 +#define WRITE_PAGE_DATA 0x0D +#define WRITE_REG 0x0B +#define SET_RW_REG_ADRS 0x08 +#define SET_CMD 0x0E + +#define PRO_READ_LONG_DATA 0x02 +#define PRO_READ_SHORT_DATA 0x03 +#define PRO_READ_REG 0x04 +#define PRO_READ_QUAD_DATA 0x05 +#define PRO_GET_INT 0x07 +#define PRO_WRITE_LONG_DATA 0x0D +#define PRO_WRITE_SHORT_DATA 0x0C +#define PRO_WRITE_QUAD_DATA 0x0A +#define PRO_WRITE_REG 0x0B +#define PRO_SET_RW_REG_ADRS 0x08 +#define PRO_SET_CMD 0x0E +#define PRO_EX_SET_CMD 0x09 + +#ifdef SUPPORT_MAGIC_GATE +#define MG_GET_ID 0x40 +#define MG_SET_LID 0x41 +#define MG_GET_LEKB 0x42 +#define MG_SET_RD 0x43 +#define MG_MAKE_RMS 0x44 +#define MG_MAKE_KSE 0x45 +#define MG_SET_IBD 0x46 +#define MG_GET_IBD 0x47 +#endif + +#ifdef XC_POWERCLASS +#define XC_CHG_POWER 0x16 +#endif + +/* ++ CMD over Memory Stick */ +/* Flash CMD */ +#define BLOCK_READ 0xAA +#define BLOCK_WRITE 0x55 +#define BLOCK_END 0x33 +#define BLOCK_ERASE 0x99 +#define FLASH_STOP 0xCC + +/* Function CMD */ +#define SLEEP 0x5A +#define CLEAR_BUF 0xC3 +#define MS_RESET 0x3C +/* -- CMD over Memory Stick */ + +/* ++ CMD over Memory Stick Pro */ +/* Flash CMD */ +#define PRO_READ_DATA 0x20 +#define PRO_WRITE_DATA 0x21 +#define PRO_READ_ATRB 0x24 +#define PRO_STOP 0x25 +#define PRO_ERASE 0x26 +#define PRO_READ_2K_DATA 0x27 +#define PRO_WRITE_2K_DATA 0x28 + +/* Function CMD */ +#define PRO_FORMAT 0x10 +#define PRO_SLEEP 0x11 +/* -- CMD over Memory Stick Pro */ + +/* register inside memory stick */ +#define IntReg 0x01 +#define StatusReg0 0x02 +#define StatusReg1 0x03 + +#define SystemParm 0x10 +#define BlockAdrs 0x11 +#define CMDParm 0x14 +#define PageAdrs 0x15 + +#define OverwriteFlag 0x16 +#define ManagemenFlag 0x17 +#define LogicalAdrs 0x18 +#define ReserveArea 0x1A + +/* register inside memory pro */ +#define Pro_IntReg 0x01 +#define Pro_StatusReg 0x02 +#define Pro_TypeReg 0x04 +#define Pro_IFModeReg 0x05 +#define Pro_CatagoryReg 0x06 +#define Pro_ClassReg 0x07 + +#define Pro_SystemParm 0x10 +#define Pro_DataCount1 0x11 +#define Pro_DataCount0 0x12 +#define Pro_DataAddr3 0x13 +#define Pro_DataAddr2 0x14 +#define Pro_DataAddr1 0x15 +#define Pro_DataAddr0 0x16 + +#define Pro_TPCParm 0x17 +#define Pro_CMDParm 0x18 + +/* define for INT Register */ +#define INT_REG_CED 0x80 +#define INT_REG_ERR 0x40 +#define INT_REG_BREQ 0x20 +#define INT_REG_CMDNK 0x01 + +/* INT signal */ +#define INT_CED 0x01 +#define INT_ERR 0x02 +#define INT_BREQ 0x04 +#define INT_CMDNK 0x08 + +/* define for OverwriteFlag Register */ +#define BLOCK_BOOT 0xC0 +#define BLOCK_OK 0x80 +#define PAGE_OK 0x60 +#define DATA_COMPL 0x10 + +/* define for ManagemenFlag Register */ +#define NOT_BOOT_BLOCK 0x4 +#define NOT_TRANSLATION_TABLE 0x8 + +/* Header */ +#define HEADER_ID0 (PPBUF_BASE2) /* 0 */ +#define HEADER_ID1 (PPBUF_BASE2 + 1) /* 1 */ +/* System Entry */ +#define DISABLED_BLOCK0 (PPBUF_BASE2 + 0x170 + 4) /* 2 */ +#define DISABLED_BLOCK1 (PPBUF_BASE2 + 0x170 + 5) /* 3 */ +#define DISABLED_BLOCK2 (PPBUF_BASE2 + 0x170 + 6) /* 4 */ +#define DISABLED_BLOCK3 (PPBUF_BASE2 + 0x170 + 7) /* 5 */ +/* Boot & Attribute Information */ +#define BLOCK_SIZE_0 (PPBUF_BASE2 + 0x1a0 + 2) /* 6 */ +#define BLOCK_SIZE_1 (PPBUF_BASE2 + 0x1a0 + 3) /* 7 */ +#define BLOCK_COUNT_0 (PPBUF_BASE2 + 0x1a0 + 4) /* 8 */ +#define BLOCK_COUNT_1 (PPBUF_BASE2 + 0x1a0 + 5) /* 9 */ +#define EBLOCK_COUNT_0 (PPBUF_BASE2 + 0x1a0 + 6) /* 10 */ +#define EBLOCK_COUNT_1 (PPBUF_BASE2 + 0x1a0 + 7) /* 11 */ +#define PAGE_SIZE_0 (PPBUF_BASE2 + 0x1a0 + 8) /* 12 */ +#define PAGE_SIZE_1 (PPBUF_BASE2 + 0x1a0 + 9) /* 13 */ + +/* joey 2004-08-07 for MS check Procedure */ +#define MS_Device_Type (PPBUF_BASE2 + 0x1D8) /* 14 */ +/* end */ + +/* joey 2004-05-03 */ +#define MS_4bit_Support (PPBUF_BASE2 + 0x1D3) /* 15 */ +/* end */ + +#define setPS_NG 1 +#define setPS_Error 0 + +/* define for Pro_SystemParm Register */ +#define PARALLEL_8BIT_IF 0x40 +#define PARALLEL_4BIT_IF 0x00 +#define SERIAL_IF 0x80 + +/* define for StatusReg0 Register */ +#define BUF_FULL 0x10 +#define BUF_EMPTY 0x20 + +/* define for StatusReg1 Register */ +#define MEDIA_BUSY 0x80 +#define FLASH_BUSY 0x40 +#define DATA_ERROR 0x20 +#define STS_UCDT 0x10 +#define EXTRA_ERROR 0x08 +#define STS_UCEX 0x04 +#define FLAG_ERROR 0x02 +#define STS_UCFG 0x01 + +#define MS_SHORT_DATA_LEN 32 + +#define FORMAT_SUCCESS 0 +#define FORMAT_FAIL 1 +#define FORMAT_IN_PROGRESS 2 + +#define MS_SET_BAD_BLOCK_FLG(ms_card) ((ms_card)->multi_flag |= 0x80) +#define MS_CLR_BAD_BLOCK_FLG(ms_card) ((ms_card)->multi_flag &= 0x7F) +#define MS_TST_BAD_BLOCK_FLG(ms_card) ((ms_card)->multi_flag & 0x80) + +#define CHECK_MS_TRANS_FAIL(chip, retval) \ + (((retval) != STATUS_SUCCESS) || \ + (chip->rsp_buf[0] & MS_TRANSFER_ERR)) + +void mspro_polling_format_status(struct rts51x_chip *chip); +void mspro_format_sense(struct rts51x_chip *chip, unsigned int lun); + +void mspro_stop_seq_mode(struct rts51x_chip *chip); +int reset_ms_card(struct rts51x_chip *chip); +int ms_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, + u16 sector_cnt); +int mspro_format(struct scsi_cmnd *srb, struct rts51x_chip *chip, + int short_data_len, int quick_format); +void ms_free_l2p_tbl(struct rts51x_chip *chip); +void ms_cleanup_work(struct rts51x_chip *chip); +int ms_power_off_card3v3(struct rts51x_chip *chip); +int release_ms_card(struct rts51x_chip *chip); +int ms_delay_write(struct rts51x_chip *chip); + +#ifdef SUPPORT_MAGIC_GATE + +int ms_switch_clock(struct rts51x_chip *chip); +int ms_write_bytes(struct rts51x_chip *chip, u8 tpc, u8 cnt, u8 cfg, u8 * data, + int data_len); +int ms_read_bytes(struct rts51x_chip *chip, u8 tpc, u8 cnt, u8 cfg, u8 * data, + int data_len); +int ms_set_rw_reg_addr(struct rts51x_chip *chip, u8 read_start, u8 read_cnt, + u8 write_start, u8 write_cnt); +int ms_transfer_data(struct rts51x_chip *chip, u8 trans_mode, u8 tpc, + u16 sec_cnt, u8 cfg, int mode_2k, int use_sg, void *buf, + int buf_len); +#endif + +#endif /* __RTS51X_MS_H */ diff --git a/drivers/staging/rts5139/ms_mg.c b/drivers/staging/rts5139/ms_mg.c new file mode 100644 index 0000000..154b523 --- /dev/null +++ b/drivers/staging/rts5139/ms_mg.c @@ -0,0 +1,642 @@ +/* Driver for Realtek RTS51xx USB card reader + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + * Maintainer: + * Edwin Rong (edwin_rong@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#include <linux/blkdev.h> +#include <linux/kthread.h> +#include <linux/sched.h> +#include <linux/slab.h> + +#include "debug.h" +#include "trace.h" +#include "rts51x.h" +#include "rts51x_transport.h" +#include "rts51x_scsi.h" +#include "rts51x_card.h" +#include "ms.h" + +#ifdef SUPPORT_MAGIC_GATE + +int mg_check_int_error(struct rts51x_chip *chip) +{ + u8 value; + + rts51x_read_register(chip, MS_TRANS_CFG, &value); + if (value & (INT_ERR | INT_CMDNK)) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +static int mg_send_ex_cmd(struct rts51x_chip *chip, u8 cmd, u8 entry_num) +{ + int retval, i; + u8 data[8]; + + data[0] = cmd; + data[1] = 0; + data[2] = 0; + data[3] = 0; + data[4] = 0; + data[5] = 0; + data[6] = entry_num; + data[7] = 0; + + for (i = 0; i < MS_MAX_RETRY_COUNT; i++) { + retval = + ms_write_bytes(chip, PRO_EX_SET_CMD, 7, WAIT_INT, data, 8); + if (retval == STATUS_SUCCESS) + break; + } + if (i == MS_MAX_RETRY_COUNT) + TRACE_RET(chip, STATUS_FAIL); + retval = mg_check_int_error(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +int mg_set_tpc_para_sub(struct rts51x_chip *chip, int type, u8 mg_entry_num) +{ + int retval; + u8 buf[6]; + + RTS51X_DEBUGP("--%s--\n", __func__); + + if (type == 0) + retval = ms_set_rw_reg_addr(chip, 0, 0, Pro_TPCParm, 1); + else + retval = ms_set_rw_reg_addr(chip, 0, 0, Pro_DataCount1, 6); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + buf[0] = 0; + buf[1] = 0; + if (type == 1) { + buf[2] = 0; + buf[3] = 0; + buf[4] = 0; + buf[5] = mg_entry_num; + } + retval = + ms_write_bytes(chip, PRO_WRITE_REG, (type == 0) ? 1 : 6, + NO_WAIT_INT, buf, 6); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + return STATUS_SUCCESS; +} + +/** + * Get MagciGate ID and set Leaf ID to medium. + + * After receiving this SCSI command, adapter shall fulfill 2 tasks + * below in order: + * 1. send GET_ID TPC command to get MagicGate ID and hold it till + * Response&challenge CMD. + * 2. send SET_ID TPC command to medium with Leaf ID released by host + * in this SCSI CMD. + */ +int mg_set_leaf_id(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + int retval; + int i; + unsigned int lun = SCSI_LUN(srb); + u8 buf1[32], buf2[12]; + + RTS51X_DEBUGP("--%s--\n", __func__); + + if (scsi_bufflen(srb) < 12) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, STATUS_FAIL); + } + ms_cleanup_work(chip); + + retval = ms_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = mg_send_ex_cmd(chip, MG_SET_LID, 0); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); + TRACE_RET(chip, retval); + } + + memset(buf1, 0, 32); + rts51x_get_xfer_buf(buf2, min(12, (int)scsi_bufflen(srb)), srb); + for (i = 0; i < 8; i++) + buf1[8 + i] = buf2[4 + i]; + retval = + ms_write_bytes(chip, PRO_WRITE_SHORT_DATA, 32, WAIT_INT, buf1, 32); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); + TRACE_RET(chip, retval); + } + retval = mg_check_int_error(chip); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); + TRACE_RET(chip, retval); + } + + return STATUS_SUCCESS; +} + +/** + * Send Local EKB to host. + + * After receiving this SCSI command, adapter shall read the divided + * data(1536 bytes totally) from medium by using READ_LONG_DATA TPC + * for 3 times, and report data to host with data-length is 1052 bytes. + */ +int mg_get_local_EKB(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + int retval = STATUS_FAIL; + int bufflen; + unsigned int lun = SCSI_LUN(srb); + u8 *buf = NULL; + + RTS51X_DEBUGP("--%s--\n", __func__); + + ms_cleanup_work(chip); + + retval = ms_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + buf = kmalloc(1540, GFP_KERNEL); + if (!buf) + TRACE_RET(chip, STATUS_NOMEM); + + buf[0] = 0x04; + buf[1] = 0x1A; + buf[2] = 0x00; + buf[3] = 0x00; + + retval = mg_send_ex_cmd(chip, MG_GET_LEKB, 0); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + TRACE_GOTO(chip, GetEKBFinish); + } + + retval = ms_transfer_data(chip, MS_TM_AUTO_READ, PRO_READ_LONG_DATA, + 3, WAIT_INT, 0, 0, buf + 4, 1536); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + rts51x_write_register(chip, CARD_STOP, MS_STOP | MS_CLR_ERR, + MS_STOP | MS_CLR_ERR); + TRACE_GOTO(chip, GetEKBFinish); + } + retval = mg_check_int_error(chip); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + TRACE_GOTO(chip, GetEKBFinish); + } + + bufflen = min(1052, (int)scsi_bufflen(srb)); + rts51x_set_xfer_buf(buf, bufflen, srb); + +GetEKBFinish: + kfree(buf); + return retval; +} + +/** + * Send challenge(host) to medium. + + * After receiving this SCSI command, adapter shall sequentially issues + * TPC commands to the medium for writing 8-bytes data as challenge + * by host within a short data packet. + */ +int mg_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + int bufflen; + int i; + unsigned int lun = SCSI_LUN(srb); + u8 buf[32], tmp; + + RTS51X_DEBUGP("--%s--\n", __func__); + + ms_cleanup_work(chip); + + retval = ms_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = mg_send_ex_cmd(chip, MG_GET_ID, 0); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); + TRACE_RET(chip, retval); + } + + retval = + ms_read_bytes(chip, PRO_READ_SHORT_DATA, 32, WAIT_INT, buf, 32); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); + TRACE_RET(chip, retval); + } + retval = mg_check_int_error(chip); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); + TRACE_RET(chip, retval); + } + + memcpy(ms_card->magic_gate_id, buf, 16); + + for (i = 0; i < 2500; i++) { + RTS51X_READ_REG(chip, MS_TRANS_CFG, &tmp); + if (tmp & + (MS_INT_CED | MS_INT_CMDNK | MS_INT_BREQ | MS_INT_ERR)) + break; + + wait_timeout(1); + } + + if (i == 2500) { + set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = mg_send_ex_cmd(chip, MG_SET_RD, 0); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); + TRACE_RET(chip, retval); + } + + bufflen = min(12, (int)scsi_bufflen(srb)); + rts51x_get_xfer_buf(buf, bufflen, srb); + + for (i = 0; i < 8; i++) + buf[i] = buf[4 + i]; + for (i = 0; i < 24; i++) + buf[8 + i] = 0; + retval = + ms_write_bytes(chip, PRO_WRITE_SHORT_DATA, 32, WAIT_INT, buf, 32); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); + TRACE_RET(chip, retval); + } + retval = mg_check_int_error(chip); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); + TRACE_RET(chip, retval); + } + + ms_card->mg_auth = 0; + + return STATUS_SUCCESS; +} + +/** + * Send Response and Challenge data to host. + + * After receiving this SCSI command, adapter shall communicates with + * the medium, get parameters(HRd, Rms, MagicGateID) by using READ_SHORT_DATA + * TPC and send the data to host according to certain format required by + * MG-R specification. + * The paremeter MagicGateID is the one that adapter has obtained from + * the medium by TPC commands in Set Leaf ID command phase previously. + */ +int mg_get_rsp_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval, i; + int bufflen; + unsigned int lun = SCSI_LUN(srb); + u8 buf1[32], buf2[36], tmp; + + RTS51X_DEBUGP("--%s--\n", __func__); + + ms_cleanup_work(chip); + + retval = ms_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = mg_send_ex_cmd(chip, MG_MAKE_RMS, 0); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + TRACE_RET(chip, retval); + } + + retval = + ms_read_bytes(chip, PRO_READ_SHORT_DATA, 32, WAIT_INT, buf1, 32); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + TRACE_RET(chip, retval); + } + retval = mg_check_int_error(chip); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + TRACE_RET(chip, retval); + } + + buf2[0] = 0x00; + buf2[1] = 0x22; + buf2[2] = 0x00; + buf2[3] = 0x00; + + memcpy(buf2 + 4, ms_card->magic_gate_id, 16); + memcpy(buf2 + 20, buf1, 16); + + bufflen = min(36, (int)scsi_bufflen(srb)); + rts51x_set_xfer_buf(buf2, bufflen, srb); + + for (i = 0; i < 2500; i++) { + RTS51X_READ_REG(chip, MS_TRANS_CFG, &tmp); + if (tmp & (MS_INT_CED | MS_INT_CMDNK | + MS_INT_BREQ | MS_INT_ERR)) + break; + + wait_timeout(1); + } + + if (i == 2500) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +/** + * Send response(host) to medium. + + * After receiving this SCSI command, adapter shall sequentially + * issues TPC commands to the medium for writing 8-bytes data as + * challenge by host within a short data packet. + */ +int mg_rsp(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + int i; + int bufflen; + unsigned int lun = SCSI_LUN(srb); + u8 buf[32]; + + RTS51X_DEBUGP("--%s--\n", __func__); + + ms_cleanup_work(chip); + + retval = ms_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = mg_send_ex_cmd(chip, MG_MAKE_KSE, 0); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + TRACE_RET(chip, retval); + } + + bufflen = min(12, (int)scsi_bufflen(srb)); + rts51x_get_xfer_buf(buf, bufflen, srb); + + for (i = 0; i < 8; i++) + buf[i] = buf[4 + i]; + for (i = 0; i < 24; i++) + buf[8 + i] = 0; + retval = + ms_write_bytes(chip, PRO_WRITE_SHORT_DATA, 32, WAIT_INT, buf, 32); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + TRACE_RET(chip, retval); + } + retval = mg_check_int_error(chip); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN); + TRACE_RET(chip, retval); + } + + ms_card->mg_auth = 1; + + return STATUS_SUCCESS; +} + +/** * Send ICV data to host. + + * After receiving this SCSI command, adapter shall read the divided + * data(1024 bytes totally) from medium by using READ_LONG_DATA TPC + * for 2 times, and report data to host with data-length is 1028 bytes. + * + * Since the extra 4 bytes data is just only a prefix to original data + * that read from medium, so that the 4-byte data pushed into Ring buffer + * precedes data tramsinssion from medium to Ring buffer by DMA mechanisim + * in order to get maximum performance and minimum code size simultaneously. + */ +int mg_get_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + int bufflen; + unsigned int lun = SCSI_LUN(srb); + u8 *buf = NULL; + + RTS51X_DEBUGP("--%s--\n", __func__); + + ms_cleanup_work(chip); + + retval = ms_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + buf = kmalloc(1028, GFP_KERNEL); + if (!buf) + TRACE_RET(chip, STATUS_NOMEM); + + buf[0] = 0x04; + buf[1] = 0x02; + buf[2] = 0x00; + buf[3] = 0x00; + + retval = mg_send_ex_cmd(chip, MG_GET_IBD, ms_card->mg_entry_num); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_GOTO(chip, GetICVFinish); + } + + retval = ms_transfer_data(chip, MS_TM_AUTO_READ, PRO_READ_LONG_DATA, + 2, WAIT_INT, 0, 0, buf + 4, 1024); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + rts51x_write_register(chip, CARD_STOP, MS_STOP | MS_CLR_ERR, + MS_STOP | MS_CLR_ERR); + TRACE_GOTO(chip, GetICVFinish); + } + retval = mg_check_int_error(chip); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_GOTO(chip, GetICVFinish); + } + + bufflen = min(1028, (int)scsi_bufflen(srb)); + rts51x_set_xfer_buf(buf, bufflen, srb); + +GetICVFinish: + kfree(buf); + return retval; +} + +/** + * Send ICV data to medium. + + * After receiving this SCSI command, adapter shall receive 1028 bytes + * and write the later 1024 bytes to medium by WRITE_LONG_DATA TPC + * consecutively. + * + * Since the first 4-bytes data is just only a prefix to original data + * that sent by host, and it should be skipped by shifting DMA pointer + * before writing 1024 bytes to medium. + */ +int mg_set_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + int retval; + int bufflen; +#ifdef MG_SET_ICV_SLOW + int i; +#endif + unsigned int lun = SCSI_LUN(srb); + u8 *buf = NULL; + + RTS51X_DEBUGP("--%s--\n", __func__); + + ms_cleanup_work(chip); + + retval = ms_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + buf = kmalloc(1028, GFP_KERNEL); + if (!buf) + TRACE_RET(chip, STATUS_NOMEM); + + bufflen = min(1028, (int)scsi_bufflen(srb)); + rts51x_get_xfer_buf(buf, bufflen, srb); + + retval = mg_send_ex_cmd(chip, MG_SET_IBD, ms_card->mg_entry_num); + if (retval != STATUS_SUCCESS) { + if (ms_card->mg_auth == 0) { + if ((buf[5] & 0xC0) != 0) + set_sense_type(chip, lun, + SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); + else + set_sense_type(chip, lun, + SENSE_TYPE_MG_WRITE_ERR); + } else { + set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); + } + TRACE_GOTO(chip, SetICVFinish); + } + +#ifdef MG_SET_ICV_SLOW + for (i = 0; i < 2; i++) { + udelay(50); + + rts51x_init_cmd(chip); + + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TPC, 0xFF, + PRO_WRITE_LONG_DATA); + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANS_CFG, 0xFF, + WAIT_INT); + + trans_dma_enable(DMA_TO_DEVICE, chip, 512, DMA_512); + + rts51x_add_cmd(chip, WRITE_REG_CMD, MS_TRANSFER, 0xFF, + MS_TRANSFER_START | MS_TM_NORMAL_WRITE); + rts51x_add_cmd(chip, CHECK_REG_CMD, MS_TRANSFER, + MS_TRANSFER_END, MS_TRANSFER_END); + + retval = rts51x_send_cmd(chip, MODE_CDOR, 100); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); + TRACE_GOTO(chip, SetICVFinish); + } + + retval = rts51x_transfer_data_rcc(chip, SND_BULK_PIPE(chip), + buf + 4 + i * 512, 512, 0, + NULL, 3000, STAGE_DO); + if (retval != STATUS_SUCCESS) { + rts51x_clear_ms_error(chip); + if (ms_card->mg_auth == 0) { + if ((buf[5] & 0xC0) != 0) + set_sense_type(chip, lun, + SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); + else + set_sense_type(chip, lun, + SENSE_TYPE_MG_WRITE_ERR); + } else { + set_sense_type(chip, lun, + SENSE_TYPE_MG_WRITE_ERR); + } + retval = STATUS_FAIL; + TRACE_GOTO(chip, SetICVFinish); + } + + retval = rts51x_get_rsp(chip, 1, 3000); + if (CHECK_MS_TRANS_FAIL(chip, retval) + || mg_check_int_error(chip)) { + rts51x_clear_ms_error(chip); + if (ms_card->mg_auth == 0) { + if ((buf[5] & 0xC0) != 0) + set_sense_type(chip, lun, + SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); + else + set_sense_type(chip, lun, + SENSE_TYPE_MG_WRITE_ERR); + } else { + set_sense_type(chip, lun, + SENSE_TYPE_MG_WRITE_ERR); + } + retval = STATUS_FAIL; + TRACE_GOTO(chip, SetICVFinish); + } + } +#else + retval = ms_transfer_data(chip, MS_TM_AUTO_WRITE, PRO_WRITE_LONG_DATA, + 2, WAIT_INT, 0, 0, buf + 4, 1024); + if (retval != STATUS_SUCCESS) { + rts51x_clear_ms_error(chip); + if (ms_card->mg_auth == 0) { + if ((buf[5] & 0xC0) != 0) + set_sense_type(chip, lun, + SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB); + else + set_sense_type(chip, lun, + SENSE_TYPE_MG_WRITE_ERR); + } else { + set_sense_type(chip, lun, SENSE_TYPE_MG_WRITE_ERR); + } + TRACE_GOTO(chip, SetICVFinish); + } +#endif + +SetICVFinish: + kfree(buf); + return retval; +} + +#endif /* SUPPORT_MAGIC_GATE */ diff --git a/drivers/staging/rts5139/ms_mg.h b/drivers/staging/rts5139/ms_mg.h new file mode 100644 index 0000000..e2ca550 --- /dev/null +++ b/drivers/staging/rts5139/ms_mg.h @@ -0,0 +1,41 @@ +/* Driver for Realtek RTS51xx USB card reader + * Header file + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + * Maintainer: + * Edwin Rong (edwin_rong@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#ifndef __RTS51X_MS_MG_H +#define __RTS51X_MS_MG_H + +#include "rts51x_chip.h" +#include "ms.h" + +int mg_set_leaf_id(struct scsi_cmnd *srb, struct rts51x_chip *chip); +int mg_get_local_EKB(struct scsi_cmnd *srb, struct rts51x_chip *chip); +int mg_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip); +int mg_get_rsp_chg(struct scsi_cmnd *srb, struct rts51x_chip *chip); +int mg_rsp(struct scsi_cmnd *srb, struct rts51x_chip *chip); +int mg_get_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip); +int mg_set_ICV(struct scsi_cmnd *srb, struct rts51x_chip *chip); + +#endif /* __RTS51X_MS_MG_H */ diff --git a/drivers/staging/rts5139/rts51x.c b/drivers/staging/rts5139/rts51x.c new file mode 100644 index 0000000..d9cee6d --- /dev/null +++ b/drivers/staging/rts5139/rts51x.c @@ -0,0 +1,967 @@ +/* Driver for Realtek RTS51xx USB card reader + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + * Maintainer: + * Edwin Rong (edwin_rong@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#include <linux/blkdev.h> +#include <linux/kthread.h> +#include <linux/sched.h> +#include <linux/workqueue.h> +#include <linux/errno.h> +#include <linux/freezer.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/slab.h> +#include <linux/mutex.h> +#include <linux/utsname.h> +#include <linux/usb.h> + +#include <scsi/scsi.h> +#include <scsi/scsi_cmnd.h> +#include <scsi/scsi_device.h> +#include <scsi/scsi_devinfo.h> +#include <scsi/scsi_eh.h> +#include <scsi/scsi_host.h> + +#include "debug.h" +#include "ms.h" +#include "rts51x.h" +#include "rts51x_chip.h" +#include "rts51x_card.h" +#include "rts51x_scsi.h" +#include "rts51x_transport.h" +#include "rts51x_fop.h" + +MODULE_DESCRIPTION(RTS51X_DESC); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRIVER_VERSION); + +#ifdef SCSI_SCAN_DELAY +static unsigned int delay_use = 5; +module_param(delay_use, uint, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(delay_use, "seconds to delay before using a new device"); +#endif + +static int auto_delink_en; +module_param(auto_delink_en, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(auto_delink_en, "enable auto delink"); + +static int ss_en; +module_param(ss_en, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(ss_en, "enable selective suspend"); + +static int ss_delay = 50; +module_param(ss_delay, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(ss_delay, + "seconds to delay before entering selective suspend"); + +static int needs_remote_wakeup; +module_param(needs_remote_wakeup, int, S_IRUGO | S_IWUSR); +MODULE_PARM_DESC(needs_remote_wakeup, "ss state needs remote wakeup supported"); + +#ifdef SUPPORT_FILE_OP +static const struct file_operations rts51x_fops = { + .owner = THIS_MODULE, + .read = rts51x_read, + .write = rts51x_write, + .unlocked_ioctl = rts51x_ioctl, + .open = rts51x_open, + .release = rts51x_release, +}; + +/* + * usb class driver info in order to get a minor number from the usb core, + * and to have the device registered with the driver core + */ +static struct usb_class_driver rts51x_class = { + .name = "rts51x%d", + .fops = &rts51x_fops, + .minor_base = 192, +}; +#endif + +#ifdef CONFIG_PM /* Minimal support for suspend and resume */ + +static inline void usb_autopm_enable(struct usb_interface *intf) +{ + atomic_set(&intf->pm_usage_cnt, 1); + usb_autopm_put_interface(intf); +} + +static inline void usb_autopm_disable(struct usb_interface *intf) +{ + atomic_set(&intf->pm_usage_cnt, 0); + usb_autopm_get_interface(intf); +} + +void rts51x_try_to_enter_ss(struct rts51x_chip *chip) +{ + RTS51X_DEBUGP("Ready to enter SS state\n"); + usb_autopm_enable(chip->usb->pusb_intf); +} + +void rts51x_try_to_exit_ss(struct rts51x_chip *chip) +{ + RTS51X_DEBUGP("Exit from SS state\n"); + usb_autopm_disable(chip->usb->pusb_intf); +} + +int rts51x_suspend(struct usb_interface *iface, pm_message_t message) +{ + struct rts51x_chip *chip = usb_get_intfdata(iface); + + RTS51X_DEBUGP("%s, message.event = 0x%x\n", __func__, message.event); + + /* Wait until no command is running */ + mutex_lock(&chip->usb->dev_mutex); + + chip->fake_card_ready = chip->card_ready; + rts51x_do_before_power_down(chip); + + if (message.event == PM_EVENT_AUTO_SUSPEND) { + RTS51X_DEBUGP("Enter SS state"); + chip->resume_from_scsi = 0; + RTS51X_SET_STAT(chip, STAT_SS); + } else { + RTS51X_DEBUGP("Enter SUSPEND state"); + RTS51X_SET_STAT(chip, STAT_SUSPEND); + } + + /* When runtime PM is working, we'll set a flag to indicate + * whether we should autoresume when a SCSI request arrives. */ + + mutex_unlock(&chip->usb->dev_mutex); + return 0; +} + +int rts51x_resume(struct usb_interface *iface) +{ + struct rts51x_chip *chip = usb_get_intfdata(iface); + + RTS51X_DEBUGP("%s\n", __func__); + + if (!RTS51X_CHK_STAT(chip, STAT_SS) || !chip->resume_from_scsi) { + mutex_lock(&chip->usb->dev_mutex); + + if (chip->option.ss_en) { + if (GET_PM_USAGE_CNT(chip) <= 0) { + /* Remote wake up, increase pm_usage_cnt */ + RTS51X_DEBUGP("Incr pm_usage_cnt\n"); + SET_PM_USAGE_CNT(chip, 1); + } + } + + RTS51X_SET_STAT(chip, STAT_RUN); + + rts51x_init_chip(chip); + rts51x_init_cards(chip); + + mutex_unlock(&chip->usb->dev_mutex); + } + + return 0; +} + +int rts51x_reset_resume(struct usb_interface *iface) +{ + struct rts51x_chip *chip = usb_get_intfdata(iface); + + RTS51X_DEBUGP("%s\n", __func__); + + mutex_lock(&chip->usb->dev_mutex); + + RTS51X_SET_STAT(chip, STAT_RUN); + + if (chip->option.ss_en) + SET_PM_USAGE_CNT(chip, 1); + + rts51x_init_chip(chip); + rts51x_init_cards(chip); + + mutex_unlock(&chip->usb->dev_mutex); + + /* FIXME: Notify the subdrivers that they need to reinitialize + * the device */ + return 0; +} + +#else /* CONFIG_PM */ + +void rts51x_try_to_enter_ss(struct rts51x_chip *chip) +{ +} + +void rts51x_try_to_exit_ss(struct rts51x_chip *chip) +{ +} + +#endif /* CONFIG_PM */ + +/* + * The next two routines get called just before and just after + * a USB port reset, whether from this driver or a different one. + */ + +int rts51x_pre_reset(struct usb_interface *iface) +{ + struct rts51x_chip *chip = usb_get_intfdata(iface); + + RTS51X_DEBUGP("%s\n", __func__); + + /* Make sure no command runs during the reset */ + mutex_lock(&chip->usb->dev_mutex); + return 0; +} + +int rts51x_post_reset(struct usb_interface *iface) +{ + struct rts51x_chip *chip = usb_get_intfdata(iface); + + RTS51X_DEBUGP("%s\n", __func__); + + /* Report the reset to the SCSI core */ + /* usb_stor_report_bus_reset(us); */ + + /* FIXME: Notify the subdrivers that they need to reinitialize + * the device */ + + mutex_unlock(&chip->usb->dev_mutex); + return 0; +} + +static int rts51x_control_thread(void *__chip) +{ + struct rts51x_chip *chip = (struct rts51x_chip *)__chip; + struct Scsi_Host *host = rts51x_to_host(chip); + + for (;;) { + if (wait_for_completion_interruptible(&chip->usb->cmnd_ready)) + break; + + if (test_bit(FLIDX_DISCONNECTING, &chip->usb->dflags)) { + RTS51X_DEBUGP("-- exiting from rts51x-control\n"); + break; + } + + /* lock the device pointers */ + mutex_lock(&(chip->usb->dev_mutex)); + + /* lock access to the state */ + scsi_lock(host); + + /* When we are called with no command pending, we're done */ + if (chip->srb == NULL) { + scsi_unlock(host); + mutex_unlock(&chip->usb->dev_mutex); + RTS51X_DEBUGP("-- exiting from control thread\n"); + break; + } + + /* has the command timed out *already* ? */ + if (test_bit(FLIDX_TIMED_OUT, &chip->usb->dflags)) { + chip->srb->result = DID_ABORT << 16; + goto SkipForAbort; + } + + scsi_unlock(host); + + /* reject the command if the direction indicator + * is UNKNOWN + */ + if (chip->srb->sc_data_direction == DMA_BIDIRECTIONAL) { + RTS51X_DEBUGP("UNKNOWN data direction\n"); + chip->srb->result = DID_ERROR << 16; + } + + /* reject if target != 0 or if LUN is higher than + * the maximum known LUN + */ + else if (chip->srb->device->id) { + RTS51X_DEBUGP("Bad target number (%d:%d)\n", + chip->srb->device->id, + chip->srb->device->lun); + chip->srb->result = DID_BAD_TARGET << 16; + } + + else if (chip->srb->device->lun > chip->max_lun) { + RTS51X_DEBUGP("Bad LUN (%d:%d)\n", + chip->srb->device->id, + chip->srb->device->lun); + chip->srb->result = DID_BAD_TARGET << 16; + } + + /* we've got a command, let's do it! */ + else { + RTS51X_DEBUG(scsi_show_command(chip->srb)); + rts51x_invoke_transport(chip->srb, chip); + } + + /* lock access to the state */ + scsi_lock(host); + + /* indicate that the command is done */ + if (chip->srb->result != DID_ABORT << 16) + chip->srb->scsi_done(chip->srb); + else +SkipForAbort : + RTS51X_DEBUGP("scsi command aborted\n"); + + /* If an abort request was received we need to signal that + * the abort has finished. The proper test for this is + * the TIMED_OUT flag, not srb->result == DID_ABORT, because + * the timeout might have occurred after the command had + * already completed with a different result code. */ + if (test_bit(FLIDX_TIMED_OUT, &chip->usb->dflags)) { + complete(&(chip->usb->notify)); + + /* Allow USB transfers to resume */ + clear_bit(FLIDX_ABORTING, &chip->usb->dflags); + clear_bit(FLIDX_TIMED_OUT, &chip->usb->dflags); + } + + /* finished working on this command */ + chip->srb = NULL; + scsi_unlock(host); + + /* unlock the device pointers */ + mutex_unlock(&chip->usb->dev_mutex); + } /* for (;;) */ + + complete(&chip->usb->control_exit); + + /* Wait until we are told to stop */ +/* for (;;) { + set_current_state(TASK_INTERRUPTIBLE); + if (kthread_should_stop()) + break; + schedule(); + } + __set_current_state(TASK_RUNNING);*/ + return 0; +} + +static int rts51x_polling_thread(void *__chip) +{ + struct rts51x_chip *chip = (struct rts51x_chip *)__chip; + +#ifdef SCSI_SCAN_DELAY + /* Wait until SCSI scan finished */ + wait_timeout((delay_use + 5) * HZ); +#endif + + for (;;) { + wait_timeout(POLLING_INTERVAL); + + /* if the device has disconnected, we are free to exit */ + if (test_bit(FLIDX_DISCONNECTING, &chip->usb->dflags)) { + RTS51X_DEBUGP("-- exiting from rts51x-polling\n"); + break; + } + + /* if the device has disconnected, we are free to exit */ + /* if (kthread_should_stop()) { + printk(KERN_INFO "Stop polling thread!\n"); + break; + } */ + +#ifdef CONFIG_PM + if (RTS51X_CHK_STAT(chip, STAT_SS) || + RTS51X_CHK_STAT(chip, STAT_SS_PRE) || + RTS51X_CHK_STAT(chip, STAT_SUSPEND)) { + continue; + } + + if (ss_en) { + if (RTS51X_CHK_STAT(chip, STAT_IDLE)) { + if (chip->ss_counter < + (ss_delay * 1000 / POLLING_INTERVAL)) { + chip->ss_counter++; + } else { + /* Prepare SS state */ + RTS51X_SET_STAT(chip, STAT_SS_PRE); + rts51x_try_to_enter_ss(chip); + continue; + } + } else { + chip->ss_counter = 0; + } + } +#endif + + mspro_polling_format_status(chip); + + /* lock the device pointers */ + mutex_lock(&(chip->usb->dev_mutex)); + + rts51x_polling_func(chip); + + /* unlock the device pointers */ + mutex_unlock(&chip->usb->dev_mutex); + } /* for (;;) */ + + complete(&chip->usb->polling_exit); + + /* Wait until we are told to stop */ + /* for (;;) { + set_current_state(TASK_INTERRUPTIBLE); + if (kthread_should_stop()) + break; + schedule(); + } + __set_current_state(TASK_RUNNING); */ + return 0; +} + +#ifdef SCSI_SCAN_DELAY +/* Thread to carry out delayed SCSI-device scanning */ +static int rts51x_scan_thread(void *__chip) +{ + struct rts51x_chip *chip = (struct rts51x_chip *)__chip; + + printk(KERN_DEBUG + "rts51x: device found at %d\n", chip->usb->pusb_dev->devnum); + + set_freezable(); + /* Wait for the timeout to expire or for a disconnect */ + if (delay_use > 0) { + printk(KERN_DEBUG "rts51x: waiting for device " + "to settle before scanning\n"); + wait_event_freezable_timeout(chip->usb->delay_wait, + test_bit(FLIDX_DONT_SCAN, + &chip->usb->dflags), + delay_use * HZ); + } + + /* If the device is still connected, perform the scanning */ + if (!test_bit(FLIDX_DONT_SCAN, &chip->usb->dflags)) { + scsi_scan_host(rts51x_to_host(chip)); + printk(KERN_DEBUG "rts51x: device scan complete\n"); + + /* Should we unbind if no devices were detected? */ + } + + complete_and_exit(&chip->usb->scanning_done, 0); +} +#endif + +/* Associate our private data with the USB device */ +static int associate_dev(struct rts51x_chip *chip, struct usb_interface *intf) +{ + struct rts51x_usb *rts51x = chip->usb; +#ifdef SUPPORT_FILE_OP + int retval; +#endif + + /* Fill in the device-related fields */ + rts51x->pusb_dev = interface_to_usbdev(intf); + rts51x->pusb_intf = intf; + rts51x->ifnum = intf->cur_altsetting->desc.bInterfaceNumber; + RTS51X_DEBUGP("Vendor: 0x%04x, Product: 0x%04x, Revision: 0x%04x\n", + le16_to_cpu(rts51x->pusb_dev->descriptor.idVendor), + le16_to_cpu(rts51x->pusb_dev->descriptor.idProduct), + le16_to_cpu(rts51x->pusb_dev->descriptor.bcdDevice)); + RTS51X_DEBUGP("Interface Subclass: 0x%02x, Protocol: 0x%02x\n", + intf->cur_altsetting->desc.bInterfaceSubClass, + intf->cur_altsetting->desc.bInterfaceProtocol); + + /* Store our private data in the interface */ + usb_set_intfdata(intf, chip); + +#ifdef SUPPORT_FILE_OP + /* we can register the device now, as it is ready */ + retval = usb_register_dev(intf, &rts51x_class); + if (retval) { + /* something prevented us from registering this driver */ + RTS51X_DEBUGP("Not able to get a minor for this device."); + usb_set_intfdata(intf, NULL); + return -ENOMEM; + } +#endif + + /* Allocate the device-related DMA-mapped buffers */ + rts51x->cr = usb_buffer_alloc(rts51x->pusb_dev, sizeof(*rts51x->cr), + GFP_KERNEL, &rts51x->cr_dma); + if (!rts51x->cr) { + RTS51X_DEBUGP("usb_ctrlrequest allocation failed\n"); + usb_set_intfdata(intf, NULL); + return -ENOMEM; + } + + rts51x->iobuf = usb_buffer_alloc(rts51x->pusb_dev, RTS51X_IOBUF_SIZE, + GFP_KERNEL, &rts51x->iobuf_dma); + if (!rts51x->iobuf) { + RTS51X_DEBUGP("I/O buffer allocation failed\n"); + usb_set_intfdata(intf, NULL); + return -ENOMEM; + } + return 0; +} + +static void rts51x_init_options(struct rts51x_chip *chip) +{ + struct rts51x_option *option = &(chip->option); + + option->led_blink_speed = 7; + option->mspro_formatter_enable = 1; + + option->fpga_sd_sdr104_clk = CLK_100; + option->fpga_sd_sdr50_clk = CLK_100; + option->fpga_sd_ddr50_clk = CLK_100; + option->fpga_sd_hs_clk = CLK_100; + option->fpga_mmc_52m_clk = CLK_80; + option->fpga_ms_hg_clk = CLK_80; + option->fpga_ms_4bit_clk = CLK_80; + + option->asic_sd_sdr104_clk = 98; + option->asic_sd_sdr50_clk = 98; + option->asic_sd_ddr50_clk = 98; + option->asic_sd_hs_clk = 97; + option->asic_mmc_52m_clk = 95; + option->asic_ms_hg_clk = 116; + option->asic_ms_4bit_clk = 77; + + option->sd_ddr_tx_phase = 0; + option->mmc_ddr_tx_phase = 1; + + option->sd_speed_prior = 0; + option->sd_ctl = + SD_PUSH_POINT_AUTO | SD_SAMPLE_POINT_AUTO | SUPPORT_UHS50_MMC44; + + option->ss_en = ss_en; + option->ss_delay = ss_delay; + option->needs_remote_wakeup = needs_remote_wakeup; + + option->auto_delink_en = auto_delink_en; + + option->FT2_fast_mode = 0; + option->pwr_delay = 800; + option->xd_rw_step = 0; + option->D3318_off_delay = 50; + option->delink_delay = 100; + option->rts5129_D3318_off_enable = 0; + option->sd20_pad_drive = 0; + option->reset_or_rw_fail_set_pad_drive = 1; + option->rcc_fail_flag = 0; + option->rcc_bug_fix_en = 1; + option->debounce_num = 2; + option->polling_time = 100; + option->led_toggle_interval = 6; + option->xd_rwn_step = 0; + option->sd_send_status_en = 0; + option->sdr50_tx_phase = 0x01; + option->sdr50_rx_phase = 0x05; + option->ddr50_tx_phase = 0x09; + option->ddr50_rx_phase = 0x06; + option->sdr50_phase_sel = 0; + option->sd30_pad_drive = 1; + option->ms_errreg_fix = 0; + option->reset_mmc_first = 0; + option->speed_mmc = 1; + option->led_always_on = 0; +} + +/* Get the pipe settings */ +static int get_pipes(struct rts51x_chip *chip) +{ + struct rts51x_usb *rts51x = chip->usb; + struct usb_host_interface *altsetting = + rts51x->pusb_intf->cur_altsetting; + int i; + struct usb_endpoint_descriptor *ep; + struct usb_endpoint_descriptor *ep_in = NULL; + struct usb_endpoint_descriptor *ep_out = NULL; + struct usb_endpoint_descriptor *ep_int = NULL; + + /* + * Find the first endpoint of each type we need. + * We are expecting a minimum of 2 endpoints - in and out (bulk). + * An optional interrupt-in is OK (necessary for CBI protocol). + * We will ignore any others. + */ + for (i = 0; i < altsetting->desc.bNumEndpoints; i++) { + ep = &altsetting->endpoint[i].desc; + + if (usb_endpoint_xfer_bulk(ep)) { + if (usb_endpoint_dir_in(ep)) { + if (!ep_in) + ep_in = ep; + } else { + if (!ep_out) + ep_out = ep; + } + } + + else if (usb_endpoint_is_int_in(ep)) { + if (!ep_int) + ep_int = ep; + } + } + + if (!ep_in || !ep_out) { + RTS51X_DEBUGP("Endpoint sanity check failed!" + "Rejecting dev.\n"); + return -EIO; + } + + /* Calculate and store the pipe values */ + rts51x->send_ctrl_pipe = usb_sndctrlpipe(rts51x->pusb_dev, 0); + rts51x->recv_ctrl_pipe = usb_rcvctrlpipe(rts51x->pusb_dev, 0); + rts51x->send_bulk_pipe = usb_sndbulkpipe(rts51x->pusb_dev, + usb_endpoint_num(ep_out)); + rts51x->recv_bulk_pipe = usb_rcvbulkpipe(rts51x->pusb_dev, + usb_endpoint_num(ep_in)); + if (ep_int) { + rts51x->recv_intr_pipe = usb_rcvintpipe(rts51x->pusb_dev, + usb_endpoint_num + (ep_int)); + rts51x->ep_bInterval = ep_int->bInterval; + } + return 0; +} + +/* Initialize all the dynamic resources we need */ +static int rts51x_acquire_resources(struct rts51x_chip *chip) +{ + struct rts51x_usb *rts51x = chip->usb; + int retval; + + rts51x->current_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!rts51x->current_urb) { + RTS51X_DEBUGP("URB allocation failed\n"); + return -ENOMEM; + } + + rts51x->intr_urb = usb_alloc_urb(0, GFP_KERNEL); + if (!rts51x->intr_urb) { + RTS51X_DEBUGP("URB allocation failed\n"); + return -ENOMEM; + } + + chip->cmd_buf = chip->rsp_buf = rts51x->iobuf; + + rts51x_init_options(chip); + + /* Init rts51xx device */ + retval = rts51x_init_chip(chip); + if (retval != STATUS_SUCCESS) + return -EIO; + + return 0; +} + +/* Release all our dynamic resources */ +static void rts51x_release_resources(struct rts51x_chip *chip) +{ + RTS51X_DEBUGP("-- %s\n", __func__); + + /* Tell the control thread to exit. The SCSI host must + * already have been removed and the DISCONNECTING flag set + * so that we won't accept any more commands. + */ + RTS51X_DEBUGP("-- sending exit command to thread\n"); + complete(&chip->usb->cmnd_ready); + if (chip->usb->ctl_thread) + wait_for_completion(&chip->usb->control_exit); + /* kthread_stop(chip->usb->ctl_thread); */ + if (chip->usb->polling_thread) + wait_for_completion(&chip->usb->polling_exit); + + /* if (chip->usb->polling_thread) + kthread_stop(chip->usb->polling_thread); */ + + wait_timeout(200); + + /* Release rts51xx device here */ + rts51x_release_chip(chip); + + usb_free_urb(chip->usb->current_urb); + usb_free_urb(chip->usb->intr_urb); +} + +/* Dissociate from the USB device */ +static void dissociate_dev(struct rts51x_chip *chip) +{ + struct rts51x_usb *rts51x = chip->usb; + + RTS51X_DEBUGP("-- %s\n", __func__); + + /* Free the device-related DMA-mapped buffers */ + if (rts51x->cr) + usb_buffer_free(rts51x->pusb_dev, sizeof(*rts51x->cr), + rts51x->cr, rts51x->cr_dma); + if (rts51x->iobuf) + usb_buffer_free(rts51x->pusb_dev, RTS51X_IOBUF_SIZE, + rts51x->iobuf, rts51x->iobuf_dma); + + /* Remove our private data from the interface */ + usb_set_intfdata(rts51x->pusb_intf, NULL); + +#ifdef SUPPORT_FILE_OP + /* give back our minor */ + usb_deregister_dev(rts51x->pusb_intf, &rts51x_class); +#endif + + kfree(rts51x); + chip->usb = NULL; +} + +/* First stage of disconnect processing: stop SCSI scanning, + * remove the host, and stop accepting new commands + */ +static void quiesce_and_remove_host(struct rts51x_chip *chip) +{ + struct rts51x_usb *rts51x = chip->usb; + struct Scsi_Host *host = rts51x_to_host(chip); + + /* If the device is really gone, cut short reset delays */ + if (rts51x->pusb_dev->state == USB_STATE_NOTATTACHED) + set_bit(FLIDX_DISCONNECTING, &rts51x->dflags); + +#ifdef SCSI_SCAN_DELAY + /* Prevent SCSI-scanning (if it hasn't started yet) + * and wait for the SCSI-scanning thread to stop. + */ + set_bit(FLIDX_DONT_SCAN, &rts51x->dflags); + wake_up(&rts51x->delay_wait); + wait_for_completion(&rts51x->scanning_done); +#endif + + /* Removing the host will perform an orderly shutdown: caches + * synchronized, disks spun down, etc. + */ + scsi_remove_host(host); + + /* Prevent any new commands from being accepted and cut short + * reset delays. + */ + scsi_lock(host); + set_bit(FLIDX_DISCONNECTING, &rts51x->dflags); + scsi_unlock(host); +#ifdef SCSI_SCAN_DELAY + wake_up(&rts51x->delay_wait); +#endif +} + +/* Second stage of disconnect processing: deallocate all resources */ +static void release_everything(struct rts51x_chip *chip) +{ + rts51x_release_resources(chip); + dissociate_dev(chip); + + /* Drop our reference to the host; the SCSI core will free it + * (and "chip" along with it) when the refcount becomes 0. */ + scsi_host_put(rts51x_to_host(chip)); +} + +static int rts51x_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct Scsi_Host *host; + struct rts51x_chip *chip; + struct rts51x_usb *rts51x; + int result; + struct task_struct *th; + + RTS51X_DEBUGP("%s detected\n", RTS51X_NAME); + + rts51x = kzalloc(sizeof(struct rts51x_usb), GFP_KERNEL); + if (!rts51x) { + printk(KERN_WARNING RTS51X_TIP + "Unable to allocate rts51x_usb\n"); + return -ENOMEM; + } + + /* + * Ask the SCSI layer to allocate a host structure, with extra + * space at the end for our private us_data structure. + */ + host = scsi_host_alloc(&rts51x_host_template, sizeof(*chip)); + if (!host) { + printk(KERN_WARNING RTS51X_TIP + "Unable to allocate the scsi host\n"); + kfree(rts51x); + return -ENOMEM; + } + + /* + * Allow 16-byte CDBs and thus > 2TB + */ + host->max_cmd_len = 16; + chip = host_to_rts51x(host); + memset(chip, 0, sizeof(struct rts51x_chip)); + + chip->vendor_id = id->idVendor; + chip->product_id = id->idProduct; + + mutex_init(&(rts51x->dev_mutex)); + init_completion(&rts51x->cmnd_ready); + init_completion(&rts51x->control_exit); + init_completion(&rts51x->polling_exit); + init_completion(&(rts51x->notify)); +#ifdef SCSI_SCAN_DELAY + init_waitqueue_head(&rts51x->delay_wait); + init_completion(&rts51x->scanning_done); +#endif + + chip->usb = rts51x; + + /* Associate the us_data structure with the USB device */ + result = associate_dev(chip, intf); + if (result) + goto BadDevice; + + /* Find the endpoints and calculate pipe values */ + result = get_pipes(chip); + if (result) + goto BadDevice; + + /* Acquire all the other resources and add the host */ + result = rts51x_acquire_resources(chip); + if (result) + goto BadDevice; + + /* Start up our control thread */ + th = kthread_run(rts51x_control_thread, chip, RTS51X_CTL_THREAD); + if (IS_ERR(th)) { + printk(KERN_WARNING RTS51X_TIP + "Unable to start control thread\n"); + result = PTR_ERR(th); + goto BadDevice; + } + rts51x->ctl_thread = th; + + result = scsi_add_host(rts51x_to_host(chip), &rts51x->pusb_intf->dev); + if (result) { + printk(KERN_WARNING RTS51X_TIP "Unable to add the scsi host\n"); + goto BadDevice; + } +#ifdef SCSI_SCAN_DELAY + /* Start up the thread for delayed SCSI-device scanning */ + th = kthread_create(rts51x_scan_thread, chip, RTS51X_SCAN_THREAD); + if (IS_ERR(th)) { + printk(KERN_WARNING RTS51X_TIP + "Unable to start the device-scanning thread\n"); + complete(&rts51x->scanning_done); + quiesce_and_remove_host(chip); + result = PTR_ERR(th); + goto BadDevice; + } + + wake_up_process(th); +#else + scsi_scan_host(rts51x_to_host(chip)); +#endif + + /* Start up our polling thread */ + th = kthread_run(rts51x_polling_thread, chip, RTS51X_POLLING_THREAD); + if (IS_ERR(th)) { + printk(KERN_WARNING RTS51X_TIP + "Unable to start polling thread\n"); + result = PTR_ERR(th); + goto BadDevice; + } + rts51x->polling_thread = th; + +#ifdef CONFIG_PM + if (ss_en) { + rts51x->pusb_intf->needs_remote_wakeup = needs_remote_wakeup; + SET_PM_USAGE_CNT(chip, 1); + RTS51X_DEBUGP("pm_usage_cnt = %d\n", GET_PM_USAGE_CNT(chip)); + } +#endif + + return 0; + + /* We come here if there are any problems */ +BadDevice: + RTS51X_DEBUGP("rts51x_probe() failed\n"); + release_everything(chip); + return result; +} + +static void rts51x_disconnect(struct usb_interface *intf) +{ + struct rts51x_chip *chip = (struct rts51x_chip *)usb_get_intfdata(intf); + + RTS51X_DEBUGP("rts51x_disconnect() called\n"); + quiesce_and_remove_host(chip); + release_everything(chip); +} + +/*********************************************************************** + * Initialization and registration + ***********************************************************************/ + +struct usb_device_id rts5139_usb_ids[] = { + {USB_DEVICE(0x0BDA, 0x0139)}, + {USB_DEVICE(0x0BDA, 0x0129)}, + {} /* Terminating entry */ +}; +EXPORT_SYMBOL_GPL(rts5139_usb_ids); + +MODULE_DEVICE_TABLE(usb, rts5139_usb_ids); + +struct usb_driver rts51x_driver = { + .name = RTS51X_NAME, + .probe = rts51x_probe, + .disconnect = rts51x_disconnect, + .suspend = rts51x_suspend, + .resume = rts51x_resume, + .reset_resume = rts51x_reset_resume, + .pre_reset = rts51x_pre_reset, + .post_reset = rts51x_post_reset, + .id_table = rts5139_usb_ids, + .soft_unbind = 1, +}; + +static int __init rts51x_init(void) +{ + int retval; + + printk(KERN_INFO "Initializing %s USB card reader driver...\n", + RTS51X_NAME); + + /* register the driver, return usb_register return code if error */ + retval = usb_register(&rts51x_driver); + if (retval == 0) { + printk(KERN_INFO + "Realtek %s USB card reader support registered.\n", + RTS51X_NAME); + } + return retval; +} + +static void __exit rts51x_exit(void) +{ + RTS51X_DEBUGP("rts51x_exit() called\n"); + + /* Deregister the driver + * This will cause disconnect() to be called for each + * attached unit + */ + RTS51X_DEBUGP("-- calling usb_deregister()\n"); + usb_deregister(&rts51x_driver); +} + +module_init(rts51x_init); +module_exit(rts51x_exit); diff --git a/drivers/staging/rts5139/rts51x.h b/drivers/staging/rts5139/rts51x.h new file mode 100644 index 0000000..9415d5c --- /dev/null +++ b/drivers/staging/rts5139/rts51x.h @@ -0,0 +1,205 @@ +/* Driver for Realtek RTS51xx USB card reader + * Header file + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + * Maintainer: + * Edwin Rong (edwin_rong@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#ifndef __RTS51X_H +#define __RTS51X_H + +#include <linux/usb.h> +#include <linux/usb_usual.h> +#include <linux/blkdev.h> +#include <linux/completion.h> +#include <linux/mutex.h> +#include <linux/cdrom.h> +#include <linux/kernel.h> +#include <linux/version.h> + +#include <scsi/scsi.h> +#include <scsi/scsi_cmnd.h> +#include <scsi/scsi_device.h> +#include <scsi/scsi_devinfo.h> +#include <scsi/scsi_eh.h> +#include <scsi/scsi_host.h> + +#define DRIVER_VERSION "v1.04" + +#define RTS51X_DESC "Realtek RTS5139/29 USB card reader driver" +#define RTS51X_NAME "rts5139" +#define RTS51X_CTL_THREAD "rts5139-control" +#define RTS51X_SCAN_THREAD "rts5139-scan" +#define RTS51X_POLLING_THREAD "rts5139-polling" + +#define POLLING_IN_THREAD +/* #define SCSI_SCAN_DELAY */ +#define SUPPORT_FILE_OP + +#define wait_timeout_x(task_state, msecs) \ +do { \ + set_current_state((task_state)); \ + schedule_timeout((msecs) * HZ / 1000); \ +} while (0) + +#define wait_timeout(msecs) wait_timeout_x(TASK_INTERRUPTIBLE, (msecs)) + +#define SCSI_LUN(srb) ((srb)->device->lun) + +/* Size of the DMA-mapped I/O buffer */ +#define RTS51X_IOBUF_SIZE 1024 +/* Size of the autosense data buffer */ +#define RTS51X_SENSE_SIZE 18 + +/* Dynamic bitflag definitions (dflags): used in set_bit() etc. */ +#define FLIDX_URB_ACTIVE 0 /* current_urb is in use */ +#define FLIDX_SG_ACTIVE 1 /* current_sg is in use */ +#define FLIDX_ABORTING 2 /* abort is in progress */ +#define FLIDX_DISCONNECTING 3 /* disconnect in progress */ +#define FLIDX_RESETTING 4 /* device reset in progress */ +#define FLIDX_TIMED_OUT 5 /* SCSI midlayer timed out */ +#define FLIDX_DONT_SCAN 6 /* don't scan (disconnect) */ + +struct rts51x_chip; + +struct rts51x_usb { + /* The device we're working with + * It's important to note: + * (o) you must hold dev_mutex to change pusb_dev + */ + struct mutex dev_mutex; /* protect pusb_dev */ + struct usb_device *pusb_dev; /* this usb_device */ + struct usb_interface *pusb_intf; /* this interface */ + + unsigned long dflags; /* dynamic atomic bitflags */ + + unsigned int send_bulk_pipe; /* cached pipe values */ + unsigned int recv_bulk_pipe; + unsigned int send_ctrl_pipe; + unsigned int recv_ctrl_pipe; + unsigned int recv_intr_pipe; + + u8 ifnum; /* interface number */ + u8 ep_bInterval; /* interrupt interval */ + + /* control and bulk communications data */ + struct urb *current_urb; /* USB requests */ + struct urb *intr_urb; /* Interrupt USB request */ + struct usb_ctrlrequest *cr; /* control requests */ + struct usb_sg_request current_sg; /* scatter-gather req. */ + unsigned char *iobuf; /* I/O buffer */ + dma_addr_t cr_dma; /* buffer DMA addresses */ + dma_addr_t iobuf_dma; + struct task_struct *ctl_thread; /* the control thread */ + struct task_struct *polling_thread; /* the polling thread */ + + /* mutual exclusion and synchronization structures */ + struct completion cmnd_ready; /* to sleep thread on */ + struct completion control_exit; /* control thread exit */ + struct completion polling_exit; /* polling thread exit */ + struct completion notify; /* thread begin/end */ +#ifdef SCSI_SCAN_DELAY + wait_queue_head_t delay_wait; /* wait during scan, reset */ + struct completion scanning_done; /* wait for scan thread */ +#endif +}; + +extern struct usb_driver rts51x_driver; + +static inline void get_current_time(u8 *timeval_buf, int buf_len) +{ + struct timeval tv; + + if (!timeval_buf || (buf_len < 8)) + return; + + do_gettimeofday(&tv); + + timeval_buf[0] = (u8) (tv.tv_sec >> 24); + timeval_buf[1] = (u8) (tv.tv_sec >> 16); + timeval_buf[2] = (u8) (tv.tv_sec >> 8); + timeval_buf[3] = (u8) (tv.tv_sec); + timeval_buf[4] = (u8) (tv.tv_usec >> 24); + timeval_buf[5] = (u8) (tv.tv_usec >> 16); + timeval_buf[6] = (u8) (tv.tv_usec >> 8); + timeval_buf[7] = (u8) (tv.tv_usec); +} + +#define SND_CTRL_PIPE(chip) ((chip)->usb->send_ctrl_pipe) +#define RCV_CTRL_PIPE(chip) ((chip)->usb->recv_ctrl_pipe) +#define SND_BULK_PIPE(chip) ((chip)->usb->send_bulk_pipe) +#define RCV_BULK_PIPE(chip) ((chip)->usb->recv_bulk_pipe) +#define RCV_INTR_PIPE(chip) ((chip)->usb->recv_intr_pipe) + +/* The scsi_lock() and scsi_unlock() macros protect the sm_state and the + * single queue element srb for write access */ +#define scsi_unlock(host) spin_unlock_irq(host->host_lock) +#define scsi_lock(host) spin_lock_irq(host->host_lock) + +#define GET_PM_USAGE_CNT(chip) \ + atomic_read(&((chip)->usb->pusb_intf->pm_usage_cnt)) +#define SET_PM_USAGE_CNT(chip, cnt) \ + atomic_set(&((chip)->usb->pusb_intf->pm_usage_cnt), (cnt)) + +/* Compatible macros while we switch over */ +static inline void *usb_buffer_alloc(struct usb_device *dev, size_t size, + gfp_t mem_flags, dma_addr_t *dma) +{ + return usb_alloc_coherent(dev, size, mem_flags, dma); +} + +static inline void usb_buffer_free(struct usb_device *dev, size_t size, + void *addr, dma_addr_t dma) +{ + return usb_free_coherent(dev, size, addr, dma); +} + +/* Convert between us_data and the corresponding Scsi_Host */ +static inline struct Scsi_Host *rts51x_to_host(struct rts51x_chip *chip) +{ + return container_of((void *)chip, struct Scsi_Host, hostdata); +} + +static inline struct rts51x_chip *host_to_rts51x(struct Scsi_Host *host) +{ + return (struct rts51x_chip *)(host->hostdata); +} + +/* struct scsi_cmnd transfer buffer access utilities */ +enum xfer_buf_dir { TO_XFER_BUF, FROM_XFER_BUF }; + +/* General routines provided by the usb-storage standard core */ +#ifdef CONFIG_PM +void rts51x_try_to_enter_ss(struct rts51x_chip *chip); +void rts51x_try_to_exit_ss(struct rts51x_chip *chip); +int rts51x_suspend(struct usb_interface *iface, pm_message_t message); +int rts51x_resume(struct usb_interface *iface); +int rts51x_reset_resume(struct usb_interface *iface); +#else +#define rts51x_suspend NULL +#define rts51x_resume NULL +#define rts51x_reset_resume NULL +#endif + +extern struct scsi_host_template rts51x_host_template; + +#endif /* __RTS51X_H */ diff --git a/drivers/staging/rts5139/rts51x_card.c b/drivers/staging/rts5139/rts51x_card.c new file mode 100644 index 0000000..424a845 --- /dev/null +++ b/drivers/staging/rts5139/rts51x_card.c @@ -0,0 +1,986 @@ +/* Driver for Realtek RTS51xx USB card reader + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + * Maintainer: + * Edwin Rong (edwin_rong@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#include <linux/blkdev.h> +#include <linux/kthread.h> +#include <linux/sched.h> +#include <linux/workqueue.h> + +#include <scsi/scsi.h> +#include <scsi/scsi_eh.h> +#include <scsi/scsi_device.h> + +#include "debug.h" +#include "rts51x.h" +#include "rts51x_chip.h" +#include "rts51x_card.h" +#include "rts51x_transport.h" +#include "rts51x_sys.h" +#include "xd.h" +#include "sd.h" +#include "ms.h" + +void do_remaining_work(struct rts51x_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + struct xd_info *xd_card = &(chip->xd_card); + struct ms_info *ms_card = &(chip->ms_card); + + if (chip->card_ready & SD_CARD) { + if (sd_card->seq_mode) { + RTS51X_SET_STAT(chip, STAT_RUN); + sd_card->counter++; + } else { + sd_card->counter = 0; + } + } + + if (chip->card_ready & XD_CARD) { + if (xd_card->delay_write.delay_write_flag) { + RTS51X_SET_STAT(chip, STAT_RUN); + xd_card->counter++; + } else { + xd_card->counter = 0; + } + } + + if (chip->card_ready & MS_CARD) { + if (CHK_MSPRO(ms_card)) { + if (ms_card->seq_mode) { + RTS51X_SET_STAT(chip, STAT_RUN); + ms_card->counter++; + } else { + ms_card->counter = 0; + } + } else { + if (ms_card->delay_write.delay_write_flag) { + RTS51X_SET_STAT(chip, STAT_RUN); + ms_card->counter++; + } else { + ms_card->counter = 0; + } + } + } + + if (sd_card->counter > POLLING_WAIT_CNT) + sd_cleanup_work(chip); + + if (xd_card->counter > POLLING_WAIT_CNT) + xd_cleanup_work(chip); + + if (ms_card->counter > POLLING_WAIT_CNT) + ms_cleanup_work(chip); +} + +void do_reset_xd_card(struct rts51x_chip *chip) +{ + int retval; + + if (chip->card2lun[XD_CARD] >= MAX_ALLOWED_LUN_CNT) + return; + + retval = reset_xd_card(chip); + if (retval == STATUS_SUCCESS) { + chip->card_ready |= XD_CARD; + chip->card_fail &= ~XD_CARD; + chip->rw_card[chip->card2lun[XD_CARD]] = xd_rw; + } else { + chip->card_ready &= ~XD_CARD; + chip->card_fail |= XD_CARD; + chip->capacity[chip->card2lun[XD_CARD]] = 0; + chip->rw_card[chip->card2lun[XD_CARD]] = NULL; + + rts51x_init_cmd(chip); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_OE, XD_OUTPUT_EN, 0); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, POWER_MASK, + POWER_OFF); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_CLK_EN, XD_CLK_EN, 0); + rts51x_send_cmd(chip, MODE_C, 100); + } +} + +void do_reset_sd_card(struct rts51x_chip *chip) +{ + int retval; + + if (chip->card2lun[SD_CARD] >= MAX_ALLOWED_LUN_CNT) + return; + + retval = reset_sd_card(chip); + if (retval == STATUS_SUCCESS) { + chip->card_ready |= SD_CARD; + chip->card_fail &= ~SD_CARD; + chip->rw_card[chip->card2lun[SD_CARD]] = sd_rw; + } else { + chip->card_ready &= ~SD_CARD; + chip->card_fail |= SD_CARD; + chip->capacity[chip->card2lun[SD_CARD]] = 0; + chip->rw_card[chip->card2lun[SD_CARD]] = NULL; + + rts51x_init_cmd(chip); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_OE, SD_OUTPUT_EN, 0); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, POWER_MASK, + POWER_OFF); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_CLK_EN, SD_CLK_EN, 0); + rts51x_send_cmd(chip, MODE_C, 100); + } +} + +void do_reset_ms_card(struct rts51x_chip *chip) +{ + int retval; + + if (chip->card2lun[MS_CARD] >= MAX_ALLOWED_LUN_CNT) + return; + + retval = reset_ms_card(chip); + if (retval == STATUS_SUCCESS) { + chip->card_ready |= MS_CARD; + chip->card_fail &= ~MS_CARD; + chip->rw_card[chip->card2lun[MS_CARD]] = ms_rw; + } else { + chip->card_ready &= ~MS_CARD; + chip->card_fail |= MS_CARD; + chip->capacity[chip->card2lun[MS_CARD]] = 0; + chip->rw_card[chip->card2lun[MS_CARD]] = NULL; + + rts51x_init_cmd(chip); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_OE, MS_OUTPUT_EN, 0); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, POWER_MASK, + POWER_OFF); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_CLK_EN, MS_CLK_EN, 0); + rts51x_send_cmd(chip, MODE_C, 100); + } +} + +void card_cd_debounce(struct rts51x_chip *chip, u8 *need_reset, + u8 *need_release) +{ + int retval; + u8 release_map = 0, reset_map = 0; + u8 value; + + retval = rts51x_get_card_status(chip, &(chip->card_status)); +#ifdef SUPPORT_OCP + chip->ocp_stat = (chip->card_status >> 4) & 0x03; +#endif + + if (retval != STATUS_SUCCESS) + goto Exit_Debounce; + + if (chip->card_exist) { + rts51x_clear_start_time(chip); + retval = rts51x_read_register(chip, CARD_INT_PEND, &value); + if (retval != STATUS_SUCCESS) { + rts51x_ep0_write_register(chip, MC_FIFO_CTL, FIFO_FLUSH, + FIFO_FLUSH); + rts51x_ep0_write_register(chip, SFSM_ED, 0xf8, 0xf8); + value = 0; + } + + if (chip->card_exist & XD_CARD) { + if (!(chip->card_status & XD_CD)) + release_map |= XD_CARD; + } else if (chip->card_exist & SD_CARD) { + /* if (!(chip->card_status & SD_CD)) { */ + if (!(chip->card_status & SD_CD) || (value & SD_INT)) + release_map |= SD_CARD; + } else if (chip->card_exist & MS_CARD) { + /* if (!(chip->card_status & MS_CD)) { */ + if (!(chip->card_status & MS_CD) || (value & MS_INT)) + release_map |= MS_CARD; + } + } else { + if (chip->card_status & XD_CD) { + rts51x_clear_start_time(chip); + reset_map |= XD_CARD; + } else if (chip->card_status & SD_CD) { + rts51x_clear_start_time(chip); + reset_map |= SD_CARD; + } else if (chip->card_status & MS_CD) { + rts51x_clear_start_time(chip); + reset_map |= MS_CARD; + } else { + if (rts51x_check_start_time(chip)) + rts51x_set_start_time(chip); + } + } + + if (CHECK_PKG(chip, QFN24) && reset_map) { + if (chip->card_exist & XD_CARD) { + reset_map = 0; + goto Exit_Debounce; + } + } + + if (reset_map) { + int xd_cnt = 0, sd_cnt = 0, ms_cnt = 0; + int i; + + for (i = 0; i < (chip->option.debounce_num); i++) { + retval = + rts51x_get_card_status(chip, &(chip->card_status)); + if (retval != STATUS_SUCCESS) { + reset_map = release_map = 0; + goto Exit_Debounce; + } + if (chip->card_status & XD_CD) + xd_cnt++; + else + xd_cnt = 0; + if (chip->card_status & SD_CD) + sd_cnt++; + else + sd_cnt = 0; + if (chip->card_status & MS_CD) + ms_cnt++; + else + ms_cnt = 0; + wait_timeout(30); + } + + reset_map = 0; + if (!(chip->card_exist & XD_CARD) + && (xd_cnt > (chip->option.debounce_num - 1))) { + reset_map |= XD_CARD; + } + if (!(chip->card_exist & SD_CARD) + && (sd_cnt > (chip->option.debounce_num - 1))) { + reset_map |= SD_CARD; + } + if (!(chip->card_exist & MS_CARD) + && (ms_cnt > (chip->option.debounce_num - 1))) { + reset_map |= MS_CARD; + } + } + rts51x_write_register(chip, CARD_INT_PEND, XD_INT | MS_INT | SD_INT, + XD_INT | MS_INT | SD_INT); + +Exit_Debounce: + if (need_reset) + *need_reset = reset_map; + if (need_release) + *need_release = release_map; +} + +void rts51x_init_cards(struct rts51x_chip *chip) +{ + u8 need_reset = 0, need_release = 0; + + card_cd_debounce(chip, &need_reset, &need_release); + + if (need_release) { + RTS51X_DEBUGP("need_release = 0x%x\n", need_release); + + rts51x_prepare_run(chip); + RTS51X_SET_STAT(chip, STAT_RUN); + +#ifdef SUPPORT_OCP + if (chip->ocp_stat & (MS_OCP_NOW | MS_OCP_EVER)) { + rts51x_write_register(chip, OCPCTL, MS_OCP_CLEAR, + MS_OCP_CLEAR); + chip->ocp_stat = 0; + RTS51X_DEBUGP("Clear OCP status.\n"); + } +#endif + + if (need_release & XD_CARD) { + chip->card_exist &= ~XD_CARD; + chip->card_ejected = 0; + if (chip->card_ready & XD_CARD) { + release_xd_card(chip); + chip->rw_card[chip->card2lun[XD_CARD]] = NULL; + clear_bit(chip->card2lun[XD_CARD], + &(chip->lun_mc)); + } + } + + if (need_release & SD_CARD) { + chip->card_exist &= ~SD_CARD; + chip->card_ejected = 0; + if (chip->card_ready & SD_CARD) { + release_sd_card(chip); + chip->rw_card[chip->card2lun[SD_CARD]] = NULL; + clear_bit(chip->card2lun[SD_CARD], + &(chip->lun_mc)); + } + } + + if (need_release & MS_CARD) { + chip->card_exist &= ~MS_CARD; + chip->card_ejected = 0; + if (chip->card_ready & MS_CARD) { + release_ms_card(chip); + chip->rw_card[chip->card2lun[MS_CARD]] = NULL; + clear_bit(chip->card2lun[MS_CARD], + &(chip->lun_mc)); + } + } + } + + if (need_reset && !chip->card_ready) { + RTS51X_DEBUGP("need_reset = 0x%x\n", need_reset); + + rts51x_prepare_run(chip); + RTS51X_SET_STAT(chip, STAT_RUN); + + if (need_reset & XD_CARD) { + chip->card_exist |= XD_CARD; + do_reset_xd_card(chip); + } else if (need_reset & SD_CARD) { + chip->card_exist |= SD_CARD; + do_reset_sd_card(chip); + } else if (need_reset & MS_CARD) { + chip->card_exist |= MS_CARD; + do_reset_ms_card(chip); + } + } +} + +void rts51x_release_cards(struct rts51x_chip *chip) +{ + if (chip->card_ready & SD_CARD) { + sd_cleanup_work(chip); + release_sd_card(chip); + chip->card_ready &= ~SD_CARD; + } + + if (chip->card_ready & XD_CARD) { + xd_cleanup_work(chip); + release_xd_card(chip); + chip->card_ready &= ~XD_CARD; + } + + if (chip->card_ready & MS_CARD) { + ms_cleanup_work(chip); + release_ms_card(chip); + chip->card_ready &= ~MS_CARD; + } +} + +static inline u8 double_depth(u8 depth) +{ + return ((depth > 1) ? (depth - 1) : depth); +} + +int switch_ssc_clock(struct rts51x_chip *chip, int clk) +{ + struct sd_info *sd_card = &(chip->sd_card); + struct ms_info *ms_card = &(chip->ms_card); + int retval; + u8 N = (u8) (clk - 2), min_N, max_N; + u8 mcu_cnt, div, max_div, ssc_depth; + int sd_vpclk_phase_reset = 0; + + if (chip->cur_clk == clk) + return STATUS_SUCCESS; + + min_N = 60; + max_N = 120; + max_div = CLK_DIV_4; + + RTS51X_DEBUGP("Switch SSC clock to %dMHz\n", clk); + + if ((clk <= 2) || (N > max_N)) + TRACE_RET(chip, STATUS_FAIL); + + mcu_cnt = (u8) (60 / clk + 3); + if (mcu_cnt > 15) + mcu_cnt = 15; + /* To make sure that the SSC clock div_n is + * equal or greater than min_N */ + div = CLK_DIV_1; + while ((N < min_N) && (div < max_div)) { + N = (N + 2) * 2 - 2; + div++; + } + RTS51X_DEBUGP("N = %d, div = %d\n", N, div); + + if (chip->option.ssc_en) { + if (chip->cur_card == SD_CARD) { + if (CHK_SD_SDR104(sd_card)) { + ssc_depth = chip->option.ssc_depth_sd_sdr104; + } else if (CHK_SD_SDR50(sd_card)) { + ssc_depth = chip->option.ssc_depth_sd_sdr50; + } else if (CHK_SD_DDR50(sd_card)) { + ssc_depth = + double_depth(chip->option. + ssc_depth_sd_ddr50); + } else if (CHK_SD_HS(sd_card)) { + ssc_depth = + double_depth(chip->option.ssc_depth_sd_hs); + } else if (CHK_MMC_52M(sd_card) + || CHK_MMC_DDR52(sd_card)) { + ssc_depth = + double_depth(chip->option. + ssc_depth_mmc_52m); + } else { + ssc_depth = + double_depth(chip->option. + ssc_depth_low_speed); + } + } else if (chip->cur_card == MS_CARD) { + if (CHK_MSPRO(ms_card)) { + if (CHK_HG8BIT(ms_card)) { + ssc_depth = + double_depth(chip->option. + ssc_depth_ms_hg); + } else { + ssc_depth = + double_depth(chip->option. + ssc_depth_ms_4bit); + } + } else { + if (CHK_MS4BIT(ms_card)) { + ssc_depth = + double_depth(chip->option. + ssc_depth_ms_4bit); + } else { + ssc_depth = + double_depth(chip->option. + ssc_depth_low_speed); + } + } + } else { + ssc_depth = + double_depth(chip->option.ssc_depth_low_speed); + } + + if (ssc_depth) { + if (div == CLK_DIV_2) { + /* If clock divided by 2, ssc depth must + * be multiplied by 2 */ + if (ssc_depth > 1) + ssc_depth -= 1; + else + ssc_depth = SSC_DEPTH_2M; + } else if (div == CLK_DIV_4) { + /* If clock divided by 4, ssc depth must + * be multiplied by 4 */ + if (ssc_depth > 2) + ssc_depth -= 2; + else + ssc_depth = SSC_DEPTH_2M; + } + } + } else { + /* Disable SSC */ + ssc_depth = 0; + } + + RTS51X_DEBUGP("ssc_depth = %d\n", ssc_depth); + + rts51x_init_cmd(chip); + rts51x_add_cmd(chip, WRITE_REG_CMD, CLK_DIV, CLK_CHANGE, CLK_CHANGE); + rts51x_add_cmd(chip, WRITE_REG_CMD, CLK_DIV, 0x3F, + (div << 4) | mcu_cnt); + rts51x_add_cmd(chip, WRITE_REG_CMD, SSC_CTL1, SSC_RSTB, 0); + rts51x_add_cmd(chip, WRITE_REG_CMD, SSC_CTL2, SSC_DEPTH_MASK, + ssc_depth); + rts51x_add_cmd(chip, WRITE_REG_CMD, SSC_DIV_N_0, 0xFF, N); + if (sd_vpclk_phase_reset) { + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK0_CTL, + PHASE_NOT_RESET, 0); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK0_CTL, + PHASE_NOT_RESET, PHASE_NOT_RESET); + } + + retval = rts51x_send_cmd(chip, MODE_C, 2000); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + if (chip->option.ssc_en && ssc_depth) + rts51x_write_register(chip, SSC_CTL1, 0xff, 0xD0); + else + rts51x_write_register(chip, SSC_CTL1, 0xff, 0x50); + udelay(100); + RTS51X_WRITE_REG(chip, CLK_DIV, CLK_CHANGE, 0); + + chip->cur_clk = clk; + + return STATUS_SUCCESS; +} + +int switch_normal_clock(struct rts51x_chip *chip, int clk) +{ + int retval; + u8 sel, div, mcu_cnt; + int sd_vpclk_phase_reset = 0; + + if (chip->cur_clk == clk) + return STATUS_SUCCESS; + + if (chip->cur_card == SD_CARD) { + struct sd_info *sd_card = &(chip->sd_card); + if (CHK_SD30_SPEED(sd_card) || CHK_MMC_DDR52(sd_card)) + sd_vpclk_phase_reset = 1; + } + + switch (clk) { + case CLK_20: + RTS51X_DEBUGP("Switch clock to 20MHz\n"); + sel = SSC_80; + div = CLK_DIV_4; + mcu_cnt = 5; + break; + + case CLK_30: + RTS51X_DEBUGP("Switch clock to 30MHz\n"); + sel = SSC_60; + div = CLK_DIV_2; + mcu_cnt = 4; + break; + + case CLK_40: + RTS51X_DEBUGP("Switch clock to 40MHz\n"); + sel = SSC_80; + div = CLK_DIV_2; + mcu_cnt = 3; + break; + + case CLK_50: + RTS51X_DEBUGP("Switch clock to 50MHz\n"); + sel = SSC_100; + div = CLK_DIV_2; + mcu_cnt = 3; + break; + + case CLK_60: + RTS51X_DEBUGP("Switch clock to 60MHz\n"); + sel = SSC_60; + div = CLK_DIV_1; + mcu_cnt = 3; + break; + + case CLK_80: + RTS51X_DEBUGP("Switch clock to 80MHz\n"); + sel = SSC_80; + div = CLK_DIV_1; + mcu_cnt = 2; + break; + + case CLK_100: + RTS51X_DEBUGP("Switch clock to 100MHz\n"); + sel = SSC_100; + div = CLK_DIV_1; + mcu_cnt = 2; + break; + + /* case CLK_120: + RTS51X_DEBUGP("Switch clock to 120MHz\n"); + sel = SSC_120; + div = CLK_DIV_1; + mcu_cnt = 2; + break; + + case CLK_150: + RTS51X_DEBUGP("Switch clock to 150MHz\n"); + sel = SSC_150; + div = CLK_DIV_1; + mcu_cnt = 2; + break; */ + + default: + RTS51X_DEBUGP("Try to switch to an illegal clock (%d)\n", + clk); + TRACE_RET(chip, STATUS_FAIL); + } + + if (!sd_vpclk_phase_reset) { + rts51x_init_cmd(chip); + + rts51x_add_cmd(chip, WRITE_REG_CMD, CLK_DIV, CLK_CHANGE, + CLK_CHANGE); + rts51x_add_cmd(chip, WRITE_REG_CMD, CLK_DIV, 0x3F, + (div << 4) | mcu_cnt); + rts51x_add_cmd(chip, WRITE_REG_CMD, SSC_CLK_FPGA_SEL, 0xFF, + sel); + rts51x_add_cmd(chip, WRITE_REG_CMD, CLK_DIV, CLK_CHANGE, 0); + + retval = rts51x_send_cmd(chip, MODE_C, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } else { + rts51x_init_cmd(chip); + + rts51x_add_cmd(chip, WRITE_REG_CMD, CLK_DIV, CLK_CHANGE, + CLK_CHANGE); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK0_CTL, + PHASE_NOT_RESET, 0); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK1_CTL, + PHASE_NOT_RESET, 0); + rts51x_add_cmd(chip, WRITE_REG_CMD, CLK_DIV, 0x3F, + (div << 4) | mcu_cnt); + rts51x_add_cmd(chip, WRITE_REG_CMD, SSC_CLK_FPGA_SEL, 0xFF, + sel); + + retval = rts51x_send_cmd(chip, MODE_C, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + udelay(200); + + rts51x_init_cmd(chip); + + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK0_CTL, + PHASE_NOT_RESET, PHASE_NOT_RESET); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_VPCLK1_CTL, + PHASE_NOT_RESET, PHASE_NOT_RESET); + + retval = rts51x_send_cmd(chip, MODE_C, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + udelay(200); + + RTS51X_WRITE_REG(chip, CLK_DIV, CLK_CHANGE, 0); + } + + chip->cur_clk = clk; + + return STATUS_SUCCESS; +} + +int card_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 sec_addr, + u16 sec_cnt) +{ + int retval; + unsigned int lun = SCSI_LUN(srb); + int i; + + if (chip->rw_card[lun] == NULL) + return STATUS_FAIL; + + RTS51X_DEBUGP("%s card, sector addr: 0x%x, sector cnt: %d\n", + (srb->sc_data_direction == + DMA_TO_DEVICE) ? "Write" : "Read", sec_addr, sec_cnt); + + chip->rw_need_retry = 0; + for (i = 0; i < 3; i++) { + retval = chip->rw_card[lun] (srb, chip, sec_addr, sec_cnt); + if (retval != STATUS_SUCCESS) { + CATCH_TRIGGER(chip); + if (chip->option.reset_or_rw_fail_set_pad_drive) { + rts51x_write_register(chip, CARD_DRIVE_SEL, + SD20_DRIVE_MASK, + DRIVE_8mA); + } + } + + if (!chip->rw_need_retry) + break; + + RTS51X_DEBUGP("Retry RW, (i = %d\n)", i); + } + + return retval; +} + +u8 get_lun_card(struct rts51x_chip *chip, unsigned int lun) +{ + if ((chip->card_ready & chip->lun2card[lun]) == XD_CARD) + return (u8) XD_CARD; + else if ((chip->card_ready & chip->lun2card[lun]) == SD_CARD) + return (u8) SD_CARD; + else if ((chip->card_ready & chip->lun2card[lun]) == MS_CARD) + return (u8) MS_CARD; + + return 0; +} + +int card_share_mode(struct rts51x_chip *chip, int card) +{ + u8 value; + + if (card == SD_CARD) + value = CARD_SHARE_SD; + else if (card == MS_CARD) + value = CARD_SHARE_MS; + else if (card == XD_CARD) + value = CARD_SHARE_XD; + else + TRACE_RET(chip, STATUS_FAIL); + + RTS51X_WRITE_REG(chip, CARD_SHARE_MODE, CARD_SHARE_MASK, value); + + return STATUS_SUCCESS; +} + +int rts51x_select_card(struct rts51x_chip *chip, int card) +{ + int retval; + + if (chip->cur_card != card) { + u8 mod; + + if (card == SD_CARD) + mod = SD_MOD_SEL; + else if (card == MS_CARD) + mod = MS_MOD_SEL; + else if (card == XD_CARD) + mod = XD_MOD_SEL; + else + TRACE_RET(chip, STATUS_FAIL); + RTS51X_WRITE_REG(chip, CARD_SELECT, 0x07, mod); + chip->cur_card = card; + + retval = card_share_mode(chip, card); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } + + return STATUS_SUCCESS; +} + +void eject_card(struct rts51x_chip *chip, unsigned int lun) +{ + RTS51X_DEBUGP("eject card\n"); + RTS51X_SET_STAT(chip, STAT_RUN); + do_remaining_work(chip); + + if ((chip->card_ready & chip->lun2card[lun]) == SD_CARD) { + release_sd_card(chip); + chip->card_ejected |= SD_CARD; + chip->card_ready &= ~SD_CARD; + chip->capacity[lun] = 0; + } else if ((chip->card_ready & chip->lun2card[lun]) == XD_CARD) { + release_xd_card(chip); + chip->card_ejected |= XD_CARD; + chip->card_ready &= ~XD_CARD; + chip->capacity[lun] = 0; + } else if ((chip->card_ready & chip->lun2card[lun]) == MS_CARD) { + release_ms_card(chip); + chip->card_ejected |= MS_CARD; + chip->card_ready &= ~MS_CARD; + chip->capacity[lun] = 0; + } + rts51x_write_register(chip, CARD_INT_PEND, XD_INT | MS_INT | SD_INT, + XD_INT | MS_INT | SD_INT); +} + +void trans_dma_enable(enum dma_data_direction dir, struct rts51x_chip *chip, + u32 byte_cnt, u8 pack_size) +{ + if (pack_size > DMA_1024) + pack_size = DMA_512; + + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, + RING_BUFFER); + + rts51x_add_cmd(chip, WRITE_REG_CMD, MC_DMA_TC3, 0xFF, + (u8) (byte_cnt >> 24)); + rts51x_add_cmd(chip, WRITE_REG_CMD, MC_DMA_TC2, 0xFF, + (u8) (byte_cnt >> 16)); + rts51x_add_cmd(chip, WRITE_REG_CMD, MC_DMA_TC1, 0xFF, + (u8) (byte_cnt >> 8)); + rts51x_add_cmd(chip, WRITE_REG_CMD, MC_DMA_TC0, 0xFF, (u8) byte_cnt); + + if (dir == DMA_FROM_DEVICE) { + rts51x_add_cmd(chip, WRITE_REG_CMD, MC_DMA_CTL, + 0x03 | DMA_PACK_SIZE_MASK, + DMA_DIR_FROM_CARD | DMA_EN | pack_size); + } else { + rts51x_add_cmd(chip, WRITE_REG_CMD, MC_DMA_CTL, + 0x03 | DMA_PACK_SIZE_MASK, + DMA_DIR_TO_CARD | DMA_EN | pack_size); + } +} + +int enable_card_clock(struct rts51x_chip *chip, u8 card) +{ + u8 clk_en = 0; + + if (card & XD_CARD) + clk_en |= XD_CLK_EN; + if (card & SD_CARD) + clk_en |= SD_CLK_EN; + if (card & MS_CARD) + clk_en |= MS_CLK_EN; + + RTS51X_WRITE_REG(chip, CARD_CLK_EN, clk_en, clk_en); + + return STATUS_SUCCESS; +} + +int disable_card_clock(struct rts51x_chip *chip, u8 card) +{ + u8 clk_en = 0; + + if (card & XD_CARD) + clk_en |= XD_CLK_EN; + if (card & SD_CARD) + clk_en |= SD_CLK_EN; + if (card & MS_CARD) + clk_en |= MS_CLK_EN; + + RTS51X_WRITE_REG(chip, CARD_CLK_EN, clk_en, 0); + + return STATUS_SUCCESS; +} + +int card_power_on(struct rts51x_chip *chip, u8 card) +{ + u8 mask, val1, val2; + + mask = POWER_MASK; + val1 = PARTIAL_POWER_ON; + val2 = POWER_ON; + +#ifdef SD_XD_IO_FOLLOW_PWR + if ((card == SD_CARD) || (card == XD_CARD)) { + RTS51X_WRITE_REG(chip, CARD_PWR_CTL, mask | LDO3318_PWR_MASK, + val1 | LDO_SUSPEND); + /* RTS51X_WRITE_REG(chip, CARD_PWR_CTL, + LDO3318_PWR_MASK, LDO_SUSPEND); */ + } + /* else if(card==XD_CARD) + { + RTS51X_WRITE_REG(chip, CARD_PWR_CTL, + mask|LDO3318_PWR_MASK, val1|LDO_SUSPEND); + //RTS51X_WRITE_REG(chip, CARD_PWR_CTL, + // LDO3318_PWR_MASK, LDO_SUSPEND); + } */ + else { +#endif + RTS51X_WRITE_REG(chip, CARD_PWR_CTL, mask, val1); +#ifdef SD_XD_IO_FOLLOW_PWR + } +#endif + udelay(chip->option.pwr_delay); + RTS51X_WRITE_REG(chip, CARD_PWR_CTL, mask, val2); +#ifdef SD_XD_IO_FOLLOW_PWR + if (card == SD_CARD) { + rts51x_write_register(chip, CARD_PWR_CTL, LDO3318_PWR_MASK, + LDO_ON); + } +#endif + + return STATUS_SUCCESS; +} + +int card_power_off(struct rts51x_chip *chip, u8 card) +{ + u8 mask, val; + + mask = POWER_MASK; + val = POWER_OFF; + RTS51X_WRITE_REG(chip, CARD_PWR_CTL, mask, val); + + return STATUS_SUCCESS; +} + +int monitor_card_cd(struct rts51x_chip *chip, u8 card) +{ + int retval; + u8 card_cd[32] = { 0 }; + + card_cd[SD_CARD] = SD_CD; + card_cd[XD_CARD] = XD_CD; + card_cd[MS_CARD] = MS_CD; + + retval = rts51x_get_card_status(chip, &(chip->card_status)); + if (retval != STATUS_SUCCESS) + return CD_NOT_EXIST; + + if (chip->card_status & card_cd[card]) + return CD_EXIST; + + return CD_NOT_EXIST; +} + +int toggle_gpio(struct rts51x_chip *chip, u8 gpio) +{ + int retval; + u8 temp_reg; + u8 gpio_output[4] = { + 0x01, + }; + u8 gpio_oe[4] = { + 0x02, + }; + if (chip->rts5179) { + retval = rts51x_ep0_read_register(chip, CARD_GPIO, &temp_reg); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + temp_reg ^= gpio_oe[gpio]; + temp_reg &= 0xfe; /* bit 0 always set 0 */ + retval = + rts51x_ep0_write_register(chip, CARD_GPIO, 0x03, temp_reg); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } else { + retval = rts51x_ep0_read_register(chip, CARD_GPIO, &temp_reg); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + temp_reg ^= gpio_output[gpio]; + retval = + rts51x_ep0_write_register(chip, CARD_GPIO, 0xFF, + temp_reg | gpio_oe[gpio]); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +int turn_on_led(struct rts51x_chip *chip, u8 gpio) +{ + int retval; + u8 gpio_oe[4] = { + 0x02, + }; + u8 gpio_mask[4] = { + 0x03, + }; + + retval = + rts51x_ep0_write_register(chip, CARD_GPIO, gpio_mask[gpio], + gpio_oe[gpio]); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +int turn_off_led(struct rts51x_chip *chip, u8 gpio) +{ + int retval; + u8 gpio_output[4] = { + 0x01, + }; + u8 gpio_oe[4] = { + 0x02, + }; + u8 gpio_mask[4] = { + 0x03, + }; + + retval = + rts51x_ep0_write_register(chip, CARD_GPIO, gpio_mask[gpio], + gpio_oe[gpio] | gpio_output[gpio]); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} diff --git a/drivers/staging/rts5139/rts51x_card.h b/drivers/staging/rts5139/rts51x_card.h new file mode 100644 index 0000000..ac3c1e7 --- /dev/null +++ b/drivers/staging/rts5139/rts51x_card.h @@ -0,0 +1,881 @@ +/* Driver for Realtek RTS51xx USB card reader + * Header file + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + * Maintainer: + * Edwin Rong (edwin_rong@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#ifndef __RTS51X_CARD_H +#define __RTS51X_CARD_H + +#include "rts51x_chip.h" + +/* Register bit definition */ + +/* Card Power Control Register */ +#define POWER_OFF 0x03 +#define PARTIAL_POWER_ON 0x02 +#define POWER_ON 0x00 +#define POWER_MASK 0x03 +#define LDO3318_PWR_MASK 0x0C +#define LDO_ON 0x00 +#define LDO_SUSPEND 0x08 +#define LDO_OFF 0x0C +#define DV3318_AUTO_PWR_OFF 0x10 +#define FORCE_LDO_POWERB 0x60 + +/* Card Output Enable Register */ +#define XD_OUTPUT_EN 0x02 +#define SD_OUTPUT_EN 0x04 +#define MS_OUTPUT_EN 0x08 + +/* System Clock Control Register */ + +/* System Clock Divider Register */ +#define CLK_CHANGE 0x80 +#define CLK_DIV_1 0x00 +#define CLK_DIV_2 0x01 +#define CLK_DIV_4 0x02 +#define CLK_DIV_8 0x03 + +/* System Clock Select Register */ +#define SSC_60 0 +#define SSC_80 1 +#define SSC_100 2 +#define SSC_120 3 +#define SSC_150 4 + +/* Card Clock Enable Register */ +#define XD_CLK_EN 0x02 +#define SD_CLK_EN 0x04 +#define MS_CLK_EN 0x08 + +/* Card Select Register */ +#define XD_MOD_SEL 1 +#define SD_MOD_SEL 2 +#define MS_MOD_SEL 3 + +/* Card Transfer Reset Register */ +#define XD_STOP 0x02 +#define SD_STOP 0x04 +#define MS_STOP 0x08 +#define XD_CLR_ERR 0x20 +#define SD_CLR_ERR 0x40 +#define MS_CLR_ERR 0x80 + +/* SD30_drive_sel */ +#define SD30_DRIVE_MASK 0x07 + +/* CARD_DRIVE_SEL */ +#define SD20_DRIVE_MASK 0x03 +#define DRIVE_4mA 0x00 +#define DRIVE_8mA 0x01 +#define DRIVE_12mA 0x02 + +/* FPGA_PULL_CTL */ +#define FPGA_MS_PULL_CTL_EN 0xEF +#define FPGA_SD_PULL_CTL_EN 0xF7 +#define FPGA_XD_PULL_CTL_EN1 0xFE +#define FPGA_XD_PULL_CTL_EN2 0xFD +#define FPGA_XD_PULL_CTL_EN3 0xFB + +#define FPGA_MS_PULL_CTL_BIT 0x10 +#define FPGA_SD_PULL_CTL_BIT 0x08 + +/* Card Data Source Register */ +#define PINGPONG_BUFFER 0x01 +#define RING_BUFFER 0x00 + +/* SFSM_ED */ +#define HW_CMD_STOP 0x80 +#define CLR_STAGE_STALL 0x08 +#define CARD_ERR 0x10 + +/* CARD_SHARE_MODE */ +#define CARD_SHARE_LQFP48 0x04 +#define CARD_SHARE_QFN24 0x00 +#define CARD_SHARE_LQFP_SEL 0x04 +#define CARD_SHARE_XD 0x00 +#define CARD_SHARE_SD 0x01 +#define CARD_SHARE_MS 0x02 +#define CARD_SHARE_MASK 0x03 + +/* CARD_AUTO_BLINK */ +#define BLINK_ENABLE 0x08 +#define BLINK_SPEED_MASK 0x07 + +/* CARD_GPIO */ +#define GPIO_OE 0x02 +#define GPIO_OUTPUT 0x01 + +/* CARD_CLK_SOURCE */ +#define CRC_FIX_CLK (0x00 << 0) +#define CRC_VAR_CLK0 (0x01 << 0) +#define CRC_VAR_CLK1 (0x02 << 0) +#define SD30_FIX_CLK (0x00 << 2) +#define SD30_VAR_CLK0 (0x01 << 2) +#define SD30_VAR_CLK1 (0x02 << 2) +#define SAMPLE_FIX_CLK (0x00 << 4) +#define SAMPLE_VAR_CLK0 (0x01 << 4) +#define SAMPLE_VAR_CLK1 (0x02 << 4) + +/* DCM_DRP_CTL */ +#define DCM_RESET 0x08 +#define DCM_LOCKED 0x04 +#define DCM_208M 0x00 +#define DCM_TX 0x01 +#define DCM_RX 0x02 + +/* DCM_DRP_TRIG */ +#define DRP_START 0x80 +#define DRP_DONE 0x40 + +/* DCM_DRP_CFG */ +#define DRP_WRITE 0x80 +#define DRP_READ 0x00 +#define DCM_WRITE_ADDRESS_50 0x50 +#define DCM_WRITE_ADDRESS_51 0x51 +#define DCM_READ_ADDRESS_00 0x00 +#define DCM_READ_ADDRESS_51 0x51 + +/* HW_VERSION */ +#define FPGA_VER 0x80 +#define HW_VER_MASK 0x0F + +/* CD_DEGLITCH_EN */ +#define DISABLE_SD_CD 0x08 +#define DISABLE_MS_CD 0x10 +#define DISABLE_XD_CD 0x20 +#define SD_CD_DEGLITCH_EN 0x01 +#define MS_CD_DEGLITCH_EN 0x02 +#define XD_CD_DEGLITCH_EN 0x04 + +/* OCPCTL */ +#define CARD_OC_DETECT_EN 0x08 +#define CARD_OC_CLR 0x01 + +/* CARD_DMA1_CTL */ +#define EXTEND_DMA1_ASYNC_SIGNAL 0x02 + +/* HS_USB_STAT */ +#define USB_HI_SPEED 0x01 + +/* CFG_MODE_1 */ +#define RTS5179 0x02 + +/* SYS_DUMMY0 */ +#define NYET_EN 0x01 +#define NYET_MSAK 0x01 + +/* SSC_CTL1 */ +#define SSC_RSTB 0x80 +#define SSC_8X_EN 0x40 +#define SSC_FIX_FRAC 0x20 +#define SSC_SEL_1M 0x00 +#define SSC_SEL_2M 0x08 +#define SSC_SEL_4M 0x10 +#define SSC_SEL_8M 0x18 + +/* SSC_CTL2 */ +#define SSC_DEPTH_MASK 0x03 +#define SSC_DEPTH_DISALBE 0x00 +#define SSC_DEPTH_2M 0x01 +#define SSC_DEPTH_1M 0x02 +#define SSC_DEPTH_512K 0x03 + +/* LDO_POWER_CFG */ +#define TUNE_SD18_MASK 0x1C +#define TUNE_SD18_1V7 0x00 +#define TUNE_SD18_1V8 (0x01 << 2) +#define TUNE_SD18_1V9 (0x02 << 2) +#define TUNE_SD18_2V0 (0x03 << 2) +#define TUNE_SD18_2V7 (0x04 << 2) +#define TUNE_SD18_2V8 (0x05 << 2) +#define TUNE_SD18_2V9 (0x06 << 2) +#define TUNE_SD18_3V3 (0x07 << 2) + +/* XD_CP_WAITTIME */ +#define WAIT_1F 0x00 +#define WAIT_3F 0x01 +#define WAIT_7F 0x02 +#define WAIT_FF 0x03 + +/* XD_INIT */ +#define XD_PWR_OFF_DELAY0 0x00 +#define XD_PWR_OFF_DELAY1 0x02 +#define XD_PWR_OFF_DELAY2 0x04 +#define XD_PWR_OFF_DELAY3 0x06 +#define XD_AUTO_PWR_OFF_EN 0xF7 +#define XD_NO_AUTO_PWR_OFF 0x08 + +/* XD_DTCTL */ +/* XD_CATCTL */ +#define XD_TIME_RWN_1 0x00 +#define XD_TIME_RWN_STEP 0x20 +#define XD_TIME_RW_1 0x00 +#define XD_TIME_RW_STEP 0x04 +#define XD_TIME_SETUP_1 0x00 +#define XD_TIME_SETUP_STEP 0x01 + +/* XD_CTL */ +#define XD_ECC2_UNCORRECTABLE 0x80 +#define XD_ECC2_ERROR 0x40 +#define XD_ECC1_UNCORRECTABLE 0x20 +#define XD_ECC1_ERROR 0x10 +#define XD_RDY 0x04 +#define XD_CE_EN 0xFD +#define XD_CE_DISEN 0x02 +#define XD_WP_EN 0xFE +#define XD_WP_DISEN 0x01 + +/* XD_TRANSFER */ +#define XD_TRANSFER_START 0x80 +#define XD_TRANSFER_END 0x40 +#define XD_PPB_EMPTY 0x20 +#define XD_ERR 0x10 +#define XD_RESET 0x00 +#define XD_ERASE 0x01 +#define XD_READ_STATUS 0x02 +#define XD_READ_ID 0x03 +#define XD_READ_REDUNDANT 0x04 +#define XD_READ_PAGES 0x05 +#define XD_SET_CMD 0x06 +#define XD_NORMAL_READ 0x07 +#define XD_WRITE_PAGES 0x08 +#define XD_NORMAL_WRITE 0x09 +#define XD_WRITE_REDUNDANT 0x0A +#define XD_SET_ADDR 0x0B +#define XD_COPY_PAGES 0x0C + +/* XD_CFG */ +#define XD_PPB_TO_SIE 0x80 +#define XD_TO_PPB_ONLY 0x00 +#define XD_BA_TRANSFORM 0x40 +#define XD_BA_NO_TRANSFORM 0x00 +#define XD_NO_CALC_ECC 0x20 +#define XD_CALC_ECC 0x00 +#define XD_IGNORE_ECC 0x10 +#define XD_CHECK_ECC 0x00 +#define XD_DIRECT_TO_RB 0x08 +#define XD_ADDR_MASK 0x07 +#define XD_ADDR_LENGTH_0 0x00 +#define XD_ADDR_LENGTH_1 0x01 +#define XD_ADDR_LENGTH_2 0x02 +#define XD_ADDR_LENGTH_3 0x03 +#define XD_ADDR_LENGTH_4 0x04 + +/* XD_PAGE_STATUS */ +#define XD_GPG 0xFF +#define XD_BPG 0x00 + +/* XD_BLOCK_STATUS */ +#define XD_GBLK 0xFF +#define XD_LATER_BBLK 0xF0 + +/* XD_PARITY */ +#define XD_ECC2_ALL1 0x80 +#define XD_ECC1_ALL1 0x40 +#define XD_BA2_ALL0 0x20 +#define XD_BA1_ALL0 0x10 +#define XD_BA1_BA2_EQL 0x04 +#define XD_BA2_VALID 0x02 +#define XD_BA1_VALID 0x01 + +/* XD_CHK_DATA_STATUS */ +#define XD_PGSTS_ZEROBIT_OVER4 0x00 +#define XD_PGSTS_NOT_FF 0x02 +#define XD_AUTO_CHK_DATA_STATUS 0x01 + +/* SD_CFG1 */ +#define SD_CLK_DIVIDE_0 0x00 +#define SD_CLK_DIVIDE_256 0xC0 +#define SD_CLK_DIVIDE_128 0x80 +#define SD_CLK_DIVIDE_MASK 0xC0 +#define SD_BUS_WIDTH_1 0x00 +#define SD_BUS_WIDTH_4 0x01 +#define SD_BUS_WIDTH_8 0x02 +#define SD_ASYNC_FIFO_RST 0x10 +#define SD_20_MODE 0x00 +#define SD_DDR_MODE 0x04 +#define SD_30_MODE 0x08 + +/* SD_CFG2 */ +#define SD_CALCULATE_CRC7 0x00 +#define SD_NO_CALCULATE_CRC7 0x80 +#define SD_CHECK_CRC16 0x00 +#define SD_NO_CHECK_CRC16 0x40 +#define SD_WAIT_CRC_TO_EN 0x20 +#define SD_WAIT_BUSY_END 0x08 +#define SD_NO_WAIT_BUSY_END 0x00 +#define SD_CHECK_CRC7 0x00 +#define SD_NO_CHECK_CRC7 0x04 +#define SD_RSP_LEN_0 0x00 +#define SD_RSP_LEN_6 0x01 +#define SD_RSP_LEN_17 0x02 +/* SD/MMC Response Type Definition */ +/* SD_CALCULATE_CRC7, SD_CHECK_CRC16, + * SD_NO_WAIT_BUSY_END, SD_NO_CHECK_CRC7, + * SD_RSP_LEN_0 */ +#define SD_RSP_TYPE_R0 0x04 +/* SD_CALCULATE_CRC7, SD_CHECK_CRC16, + * SD_NO_WAIT_BUSY_END, SD_CHECK_CRC7, + * SD_RSP_LEN_6 */ +#define SD_RSP_TYPE_R1 0x01 +/* SD_CALCULATE_CRC7, SD_CHECK_CRC16, + * SD_WAIT_BUSY_END, SD_CHECK_CRC7, + * SD_RSP_LEN_6 */ +#define SD_RSP_TYPE_R1b 0x09 +/* SD_CALCULATE_CRC7, SD_CHECK_CRC16, + * SD_NO_WAIT_BUSY_END, SD_CHECK_CRC7, + * SD_RSP_LEN_17 */ +#define SD_RSP_TYPE_R2 0x02 +/* SD_CALCULATE_CRC7, SD_CHECK_CRC16, + * SD_NO_WAIT_BUSY_END, SD_NO_CHECK_CRC7, + * SD_RSP_LEN_6 */ +#define SD_RSP_TYPE_R3 0x05 +/* SD_CALCULATE_CRC7, SD_CHECK_CRC16, + * SD_NO_WAIT_BUSY_END, SD_NO_CHECK_CRC7, + * SD_RSP_LEN_6 */ +#define SD_RSP_TYPE_R4 0x05 +/* SD_CALCULATE_CRC7, SD_CHECK_CRC16, + * SD_NO_WAIT_BUSY_END, SD_CHECK_CRC7, + * SD_RSP_LEN_6 */ +#define SD_RSP_TYPE_R5 0x01 +/* SD_CALCULATE_CRC7, SD_CHECK_CRC16, + * SD_NO_WAIT_BUSY_END, SD_CHECK_CRC7, + * SD_RSP_LEN_6 */ +#define SD_RSP_TYPE_R6 0x01 +/* SD_CALCULATE_CRC7, SD_CHECK_CRC16, + * SD_NO_WAIT_BUSY_END, SD_CHECK_CRC7, + * SD_RSP_LEN_6 */ +#define SD_RSP_TYPE_R7 0x01 + +/* SD_CFG3 */ +#define SD_RSP_80CLK_TIMEOUT_EN 0x01 + +/* SD_STAT1 */ +#define SD_CRC7_ERR 0x80 +#define SD_CRC16_ERR 0x40 +#define SD_CRC_WRITE_ERR 0x20 +#define SD_CRC_WRITE_ERR_MASK 0x1C +#define GET_CRC_TIME_OUT 0x02 +#define SD_TUNING_COMPARE_ERR 0x01 + +/* SD_STAT2 */ +#define SD_RSP_80CLK_TIMEOUT 0x01 + +/* SD_BUS_STAT */ +#define SD_CLK_TOGGLE_EN 0x80 +#define SD_CLK_FORCE_STOP 0x40 +#define SD_DAT3_STATUS 0x10 +#define SD_DAT2_STATUS 0x08 +#define SD_DAT1_STATUS 0x04 +#define SD_DAT0_STATUS 0x02 +#define SD_CMD_STATUS 0x01 + +/* SD_PAD_CTL */ +#define SD_IO_USING_1V8 0x80 +#define SD_IO_USING_3V3 0x7F +#define TYPE_A_DRIVING 0x00 +#define TYPE_B_DRIVING 0x01 +#define TYPE_C_DRIVING 0x02 +#define TYPE_D_DRIVING 0x03 + +/* SD_SAMPLE_POINT_CTL */ +#define DDR_FIX_RX_DAT 0x00 +#define DDR_VAR_RX_DAT 0x80 +#define DDR_FIX_RX_DAT_EDGE 0x00 +#define DDR_FIX_RX_DAT_14_DELAY 0x40 +#define DDR_FIX_RX_CMD 0x00 +#define DDR_VAR_RX_CMD 0x20 +#define DDR_FIX_RX_CMD_POS_EDGE 0x00 +#define DDR_FIX_RX_CMD_14_DELAY 0x10 +#define SD20_RX_POS_EDGE 0x00 +#define SD20_RX_14_DELAY 0x08 +#define SD20_RX_SEL_MASK 0x08 + +/* SD_PUSH_POINT_CTL */ +#define DDR_FIX_TX_CMD_DAT 0x00 +#define DDR_VAR_TX_CMD_DAT 0x80 +#define DDR_FIX_TX_DAT_14_TSU 0x00 +#define DDR_FIX_TX_DAT_12_TSU 0x40 +#define DDR_FIX_TX_CMD_NEG_EDGE 0x00 +#define DDR_FIX_TX_CMD_14_AHEAD 0x20 +#define SD20_TX_NEG_EDGE 0x00 +#define SD20_TX_14_AHEAD 0x10 +#define SD20_TX_SEL_MASK 0x10 +#define DDR_VAR_SDCLK_POL_SWAP 0x01 + +/* SD_TRANSFER */ +#define SD_TRANSFER_START 0x80 +#define SD_TRANSFER_END 0x40 +#define SD_STAT_IDLE 0x20 +#define SD_TRANSFER_ERR 0x10 +/* SD Transfer Mode definition */ +#define SD_TM_NORMAL_WRITE 0x00 +#define SD_TM_AUTO_WRITE_3 0x01 +#define SD_TM_AUTO_WRITE_4 0x02 +#define SD_TM_AUTO_READ_3 0x05 +#define SD_TM_AUTO_READ_4 0x06 +#define SD_TM_CMD_RSP 0x08 +#define SD_TM_AUTO_WRITE_1 0x09 +#define SD_TM_AUTO_WRITE_2 0x0A +#define SD_TM_NORMAL_READ 0x0C +#define SD_TM_AUTO_READ_1 0x0D +#define SD_TM_AUTO_READ_2 0x0E +#define SD_TM_AUTO_TUNING 0x0F + +/* SD_VPTX_CTL / SD_VPRX_CTL */ +#define PHASE_CHANGE 0x80 +#define PHASE_NOT_RESET 0x40 + +/* SD_DCMPS_TX_CTL / SD_DCMPS_RX_CTL */ +#define DCMPS_CHANGE 0x80 +#define DCMPS_CHANGE_DONE 0x40 +#define DCMPS_ERROR 0x20 +#define DCMPS_CURRENT_PHASE 0x1F + +/* SD_CMD_STATE */ +#define SD_CMD_IDLE 0x80 + +/* SD_DATA_STATE */ +#define SD_DATA_IDLE 0x80 + +/* MS_BLKEND */ +#define SET_BLKEND 0x01 + +/* MS_CFG */ +#define SAMPLE_TIME_RISING 0x00 +#define SAMPLE_TIME_FALLING 0x80 +#define PUSH_TIME_DEFAULT 0x00 +#define PUSH_TIME_ODD 0x40 +#define NO_EXTEND_TOGGLE 0x00 +#define EXTEND_TOGGLE_CHK 0x20 +#define MS_BUS_WIDTH_1 0x00 +#define MS_BUS_WIDTH_4 0x10 +#define MS_BUS_WIDTH_8 0x18 +#define MS_2K_SECTOR_MODE 0x04 +#define MS_512_SECTOR_MODE 0x00 +#define MS_TOGGLE_TIMEOUT_EN 0x00 +#define MS_TOGGLE_TIMEOUT_DISEN 0x01 +#define MS_NO_CHECK_INT 0x02 + +/* MS_TRANS_CFG */ +#define WAIT_INT 0x80 +#define NO_WAIT_INT 0x00 +#define NO_AUTO_READ_INT_REG 0x00 +#define AUTO_READ_INT_REG 0x40 +#define MS_CRC16_ERR 0x20 +#define MS_RDY_TIMEOUT 0x10 +#define MS_INT_CMDNK 0x08 +#define MS_INT_BREQ 0x04 +#define MS_INT_ERR 0x02 +#define MS_INT_CED 0x01 + +/* MS_TRANSFER */ +#define MS_TRANSFER_START 0x80 +#define MS_TRANSFER_END 0x40 +#define MS_TRANSFER_ERR 0x20 +#define MS_BS_STATE 0x10 +#define MS_TM_READ_BYTES 0x00 +#define MS_TM_NORMAL_READ 0x01 +#define MS_TM_WRITE_BYTES 0x04 +#define MS_TM_NORMAL_WRITE 0x05 +#define MS_TM_AUTO_READ 0x08 +#define MS_TM_AUTO_WRITE 0x0C +#define MS_TM_SET_CMD 0x06 +#define MS_TM_COPY_PAGE 0x07 +#define MS_TM_MULTI_READ 0x02 +#define MS_TM_MULTI_WRITE 0x03 + +/* MC_DMA_CTL */ +#define DMA_TC_EQ_0 0x80 +#define DMA_DIR_TO_CARD 0x00 +#define DMA_DIR_FROM_CARD 0x02 +#define DMA_EN 0x01 +#define DMA_128 (0 << 2) +#define DMA_256 (1 << 2) +#define DMA_512 (2 << 2) +#define DMA_1024 (3 << 2) +#define DMA_PACK_SIZE_MASK 0x0C + +/* CARD_INT_PEND */ +#define XD_INT 0x10 +#define MS_INT 0x08 +#define SD_INT 0x04 + +/* MC_FIFO_CTL */ +#define FIFO_FLUSH 0x01 + +/* AUTO_DELINK_EN */ +#define AUTO_DELINK 0x02 +#define FORCE_DELINK 0x01 + +/* MC_DMA_RST */ +#define DMA_RESET 0x01 + +#define SSC_POWER_MASK 0x01 +#define SSC_POWER_DOWN 0x01 +#define SSC_POWER_ON 0x00 + +/* OCPCTL */ +#define MS_OCP_DETECT_EN 0x08 +#define MS_OCP_INT_EN 0x04 +#define MS_OCP_INT_CLR 0x02 +#define MS_OCP_CLEAR 0x01 + +/* OCPSTAT */ +#define MS_OCP_DETECT 0x80 +#define MS_OCP_NOW 0x02 +#define MS_OCP_EVER 0x01 + +/* MC_FIFO_STAT */ +#define FIFO_FULL 0x01 +#define FIFO_EMPTY 0x02 + +/* RCCTL */ +#define U_HW_CMD_EN_MASK 0x02 +#define U_HW_CMD_EN 0x02 +#define U_HW_CMD_DIS 0x00 + +/* Register address */ +#define FPDCTL 0xFC00 +#define SSC_DIV_N_0 0xFC07 +#define SSC_CTL1 0xFC09 +#define SSC_CTL2 0xFC0A +#define CFG_MODE_1 0xFC0F +#define RCCTL 0xFC14 +#define SYS_DUMMY0 0xFC30 +#define XD_CP_WAITTIME 0xFD00 +#define XD_CP_PAGELEN 0xFD01 +#define XD_CP_READADDR0 0xFD02 +#define XD_CP_READADDR1 0xFD03 +#define XD_CP_READADDR2 0xFD04 +#define XD_CP_READADDR3 0xFD05 +#define XD_CP_READADDR4 0xFD06 +#define XD_CP_WRITEADDR0 0xFD07 +#define XD_CP_WRITEADDR1 0xFD08 +#define XD_CP_WRITEADDR2 0xFD09 +#define XD_CP_WRITEADDR3 0xFD0A +#define XD_CP_WRITEADDR4 0xFD0B +#define XD_INIT 0xFD10 +#define XD_DTCTL 0xFD11 +#define XD_CTL 0xFD12 +#define XD_TRANSFER 0xFD13 +#define XD_CFG 0xFD14 +#define XD_ADDRESS0 0xFD15 +#define XD_ADDRESS1 0xFD16 +#define XD_ADDRESS2 0xFD17 +#define XD_ADDRESS3 0xFD18 +#define XD_ADDRESS4 0xFD19 +#define XD_DAT 0xFD1A +#define XD_PAGE_CNT 0xFD1B +#define XD_PAGE_STATUS 0xFD1C +#define XD_BLOCK_STATUS 0xFD1D +#define XD_BLOCK_ADDR1_L 0xFD1E +#define XD_BLOCK_ADDR1_H 0xFD1F +#define XD_BLOCK_ADDR2_L 0xFD20 +#define XD_BLOCK_ADDR2_H 0xFD21 +#define XD_BYTE_CNT_L 0xFD22 +#define XD_BYTE_CNT_H 0xFD23 +#define XD_PARITY 0xFD24 +#define XD_ECC_BIT1 0xFD25 +#define XD_ECC_BYTE1 0xFD26 +#define XD_ECC_BIT2 0xFD27 +#define XD_ECC_BYTE2 0xFD28 +#define XD_RESERVED0 0xFD29 +#define XD_RESERVED1 0xFD2A +#define XD_RESERVED2 0xFD2B +#define XD_RESERVED3 0xFD2C +#define XD_CHK_DATA_STATUS 0xFD2D +#define XD_CATCTL 0xFD2E + +#define MS_BLKEND 0xFD30 +#define MS_READ_START 0xFD31 +#define MS_READ_COUNT 0xFD32 +#define MS_WRITE_START 0xFD33 +#define MS_WRITE_COUNT 0xFD34 +#define MS_COMMAND 0xFD35 +#define MS_OLD_BLOCK_0 0xFD36 +#define MS_OLD_BLOCK_1 0xFD37 +#define MS_NEW_BLOCK_0 0xFD38 +#define MS_NEW_BLOCK_1 0xFD39 +#define MS_LOG_BLOCK_0 0xFD3A +#define MS_LOG_BLOCK_1 0xFD3B +#define MS_BUS_WIDTH 0xFD3C +#define MS_PAGE_START 0xFD3D +#define MS_PAGE_LENGTH 0xFD3E +#define MS_CFG 0xFD40 +#define MS_TPC 0xFD41 +#define MS_TRANS_CFG 0xFD42 +#define MS_TRANSFER 0xFD43 +#define MS_INT_REG 0xFD44 +#define MS_BYTE_CNT 0xFD45 +#define MS_SECTOR_CNT_L 0xFD46 +#define MS_SECTOR_CNT_H 0xFD47 +#define MS_DBUS_H 0xFD48 + +#define CARD_DMA1_CTL 0xFD5C +#define CARD_PULL_CTL1 0xFD60 +#define CARD_PULL_CTL2 0xFD61 +#define CARD_PULL_CTL3 0xFD62 +#define CARD_PULL_CTL4 0xFD63 +#define CARD_PULL_CTL5 0xFD64 +#define CARD_PULL_CTL6 0xFD65 +#define CARD_EXIST 0xFD6F +#define CARD_INT_PEND 0xFD71 + +#define LDO_POWER_CFG 0xFD7B + +#define SD_CFG1 0xFDA0 +#define SD_CFG2 0xFDA1 +#define SD_CFG3 0xFDA2 +#define SD_STAT1 0xFDA3 +#define SD_STAT2 0xFDA4 +#define SD_BUS_STAT 0xFDA5 +#define SD_PAD_CTL 0xFDA6 +#define SD_SAMPLE_POINT_CTL 0xFDA7 +#define SD_PUSH_POINT_CTL 0xFDA8 +#define SD_CMD0 0xFDA9 +#define SD_CMD1 0xFDAA +#define SD_CMD2 0xFDAB +#define SD_CMD3 0xFDAC +#define SD_CMD4 0xFDAD +#define SD_CMD5 0xFDAE +#define SD_BYTE_CNT_L 0xFDAF +#define SD_BYTE_CNT_H 0xFDB0 +#define SD_BLOCK_CNT_L 0xFDB1 +#define SD_BLOCK_CNT_H 0xFDB2 +#define SD_TRANSFER 0xFDB3 +#define SD_CMD_STATE 0xFDB5 +#define SD_DATA_STATE 0xFDB6 +#define SD_VPCLK0_CTL 0xFC2A +#define SD_VPCLK1_CTL 0xFC2B +#define SD_DCMPS0_CTL 0xFC2C +#define SD_DCMPS1_CTL 0xFC2D + +#define CARD_DMA1_CTL 0xFD5C + +#define HW_VERSION 0xFC01 + +#define SSC_CLK_FPGA_SEL 0xFC02 +#define CLK_DIV 0xFC03 +#define SFSM_ED 0xFC04 + +#define CD_DEGLITCH_WIDTH 0xFC20 +#define CD_DEGLITCH_EN 0xFC21 +#define AUTO_DELINK_EN 0xFC23 + +#define FPGA_PULL_CTL 0xFC1D +#define CARD_CLK_SOURCE 0xFC2E + +#define CARD_SHARE_MODE 0xFD51 +#define CARD_DRIVE_SEL 0xFD52 +#define CARD_STOP 0xFD53 +#define CARD_OE 0xFD54 +#define CARD_AUTO_BLINK 0xFD55 +#define CARD_GPIO 0xFD56 +#define SD30_DRIVE_SEL 0xFD57 + +#define CARD_DATA_SOURCE 0xFD5D +#define CARD_SELECT 0xFD5E + +#define CARD_CLK_EN 0xFD79 +#define CARD_PWR_CTL 0xFD7A + +#define OCPCTL 0xFD80 +#define OCPPARA1 0xFD81 +#define OCPPARA2 0xFD82 +#define OCPSTAT 0xFD83 + +#define HS_USB_STAT 0xFE01 +#define HS_VCONTROL 0xFE26 +#define HS_VSTAIN 0xFE27 +#define HS_VLOADM 0xFE28 +#define HS_VSTAOUT 0xFE29 + +#define MC_IRQ 0xFF00 +#define MC_IRQEN 0xFF01 +#define MC_FIFO_CTL 0xFF02 +#define MC_FIFO_BC0 0xFF03 +#define MC_FIFO_BC1 0xFF04 +#define MC_FIFO_STAT 0xFF05 +#define MC_FIFO_MODE 0xFF06 +#define MC_FIFO_RD_PTR0 0xFF07 +#define MC_FIFO_RD_PTR1 0xFF08 +#define MC_DMA_CTL 0xFF10 +#define MC_DMA_TC0 0xFF11 +#define MC_DMA_TC1 0xFF12 +#define MC_DMA_TC2 0xFF13 +#define MC_DMA_TC3 0xFF14 +#define MC_DMA_RST 0xFF15 + +/* Memory mapping */ +#define RBUF_SIZE_MASK 0xFBFF +#define RBUF_BASE 0xF000 +#define PPBUF_BASE1 0xF800 +#define PPBUF_BASE2 0xFA00 + +/* int monitor_card_cd */ +#define CD_EXIST 0 +#define CD_NOT_EXIST 1 + +#define DEBOUNCE_CNT 5 + +int monitor_card_cd(struct rts51x_chip *chip, u8 card); + +void do_remaining_work(struct rts51x_chip *chip); +void do_reset_xd_card(struct rts51x_chip *chip); +void do_reset_sd_card(struct rts51x_chip *chip); +void do_reset_ms_card(struct rts51x_chip *chip); +void rts51x_init_cards(struct rts51x_chip *chip); +void rts51x_release_cards(struct rts51x_chip *chip); +int switch_ssc_clock(struct rts51x_chip *chip, int clk); +int switch_normal_clock(struct rts51x_chip *chip, int clk); +int card_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 sec_addr, + u16 sec_cnt); +u8 get_lun_card(struct rts51x_chip *chip, unsigned int lun); +int card_share_mode(struct rts51x_chip *chip, int card); +int rts51x_select_card(struct rts51x_chip *chip, int card); +void eject_card(struct rts51x_chip *chip, unsigned int lun); +void trans_dma_enable(enum dma_data_direction dir, struct rts51x_chip *chip, + u32 byte_cnt, u8 pack_size); +int enable_card_clock(struct rts51x_chip *chip, u8 card); +int disable_card_clock(struct rts51x_chip *chip, u8 card); +int card_power_on(struct rts51x_chip *chip, u8 card); +int card_power_off(struct rts51x_chip *chip, u8 card); +int toggle_gpio(struct rts51x_chip *chip, u8 gpio); +int turn_on_led(struct rts51x_chip *chip, u8 gpio); +int turn_off_led(struct rts51x_chip *chip, u8 gpio); + +static inline int check_card_ready(struct rts51x_chip *chip, unsigned int lun) +{ + if (chip->card_ready & chip->lun2card[lun]) + return 1; + + return 0; +} + +static inline int check_card_exist(struct rts51x_chip *chip, unsigned int lun) +{ + if (chip->card_exist & chip->lun2card[lun]) + return 1; + + return 0; +} + +static inline int check_card_wp(struct rts51x_chip *chip, unsigned int lun) +{ + if (chip->card_wp & chip->lun2card[lun]) + return 1; + + return 0; +} + +static inline int check_card_fail(struct rts51x_chip *chip, unsigned int lun) +{ + if (chip->card_fail & chip->lun2card[lun]) + return 1; + + return 0; +} + +static inline int check_card_ejected(struct rts51x_chip *chip, unsigned int lun) +{ + if (chip->card_ejected & chip->lun2card[lun]) + return 1; + + return 0; +} + +static inline int check_fake_card_ready(struct rts51x_chip *chip, + unsigned int lun) +{ + if (chip->fake_card_ready & chip->lun2card[lun]) + return 1; + + return 0; +} + +static inline u8 get_lun2card(struct rts51x_chip *chip, unsigned int lun) +{ + return chip->lun2card[lun]; +} + +static inline int check_lun_mc(struct rts51x_chip *chip, unsigned int lun) +{ + return CHK_BIT(chip->lun_mc, lun); +} + +static inline void set_lun_mc(struct rts51x_chip *chip, unsigned int lun) +{ + SET_BIT(chip->lun_mc, lun); +} + +static inline void clear_lun_mc(struct rts51x_chip *chip, unsigned int lun) +{ + CLR_BIT(chip->lun_mc, lun); +} + +static inline int switch_clock(struct rts51x_chip *chip, int clk) +{ + int retval = 0; + + if (chip->asic_code) + retval = switch_ssc_clock(chip, clk); + else + retval = switch_normal_clock(chip, clk); + + return retval; +} + +static inline void rts51x_clear_xd_error(struct rts51x_chip *chip) +{ + rts51x_ep0_write_register(chip, CARD_STOP, + XD_STOP | XD_CLR_ERR, XD_STOP | XD_CLR_ERR); + + rts51x_ep0_write_register(chip, MC_FIFO_CTL, FIFO_FLUSH, FIFO_FLUSH); + rts51x_ep0_write_register(chip, MC_DMA_RST, DMA_RESET, DMA_RESET); + rts51x_ep0_write_register(chip, SFSM_ED, 0xf8, 0xf8); +} + +static inline void rts51x_clear_sd_error(struct rts51x_chip *chip) +{ + rts51x_ep0_write_register(chip, CARD_STOP, + SD_STOP | SD_CLR_ERR, SD_STOP | SD_CLR_ERR); + + rts51x_ep0_write_register(chip, MC_FIFO_CTL, FIFO_FLUSH, FIFO_FLUSH); + rts51x_ep0_write_register(chip, MC_DMA_RST, DMA_RESET, DMA_RESET); + rts51x_ep0_write_register(chip, SFSM_ED, 0xf8, 0xf8); +} + +static inline void rts51x_clear_ms_error(struct rts51x_chip *chip) +{ + rts51x_ep0_write_register(chip, CARD_STOP, + MS_STOP | MS_CLR_ERR, MS_STOP | MS_CLR_ERR); + + rts51x_ep0_write_register(chip, MC_FIFO_CTL, FIFO_FLUSH, FIFO_FLUSH); + rts51x_ep0_write_register(chip, MC_DMA_RST, DMA_RESET, DMA_RESET); + rts51x_ep0_write_register(chip, SFSM_ED, 0xf8, 0xf8); +} + +#endif /* __RTS51X_CARD_H */ diff --git a/drivers/staging/rts5139/rts51x_chip.c b/drivers/staging/rts5139/rts51x_chip.c new file mode 100644 index 0000000..adc0d00 --- /dev/null +++ b/drivers/staging/rts5139/rts51x_chip.c @@ -0,0 +1,1167 @@ +/* Driver for Realtek RTS51xx USB card reader + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + * Maintainer: + * Edwin Rong (edwin_rong@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#include <linux/blkdev.h> +#include <linux/kthread.h> +#include <linux/sched.h> +#include <linux/workqueue.h> + +#include "debug.h" +#include "trace.h" +#include "rts51x.h" +#include "rts51x_chip.h" +#include "rts51x_card.h" +#include "rts51x_transport.h" +#include "rts51x_sys.h" +#include "xd.h" +#include "ms.h" +#include "sd.h" + +static int check_sd_speed_prior(u32 sd_speed_prior) +{ + int i, fake_para = 0; + + /* Check the legality of sd_speed_prior */ + for (i = 0; i < 4; i++) { + u8 tmp = (u8) (sd_speed_prior >> (i * 8)); + if ((tmp < 0x01) || (tmp > 0x04)) { + fake_para = 1; + break; + } + } + + return !fake_para; +} + +int rts51x_reset_chip(struct rts51x_chip *chip) +{ + int retval; + + if (CHECK_PKG(chip, LQFP48)) { + RTS51X_WRITE_REG(chip, CARD_PWR_CTL, LDO3318_PWR_MASK, + LDO_SUSPEND); + RTS51X_WRITE_REG(chip, CARD_PWR_CTL, FORCE_LDO_POWERB, + FORCE_LDO_POWERB); + RTS51X_WRITE_REG(chip, CARD_PULL_CTL1, 0x30, 0x10); + RTS51X_WRITE_REG(chip, CARD_PULL_CTL5, 0x03, 0x01); + RTS51X_WRITE_REG(chip, CARD_PULL_CTL6, 0x0C, 0x04); + } + if (chip->asic_code) { + RTS51X_WRITE_REG(chip, SYS_DUMMY0, NYET_MSAK, NYET_EN); + RTS51X_WRITE_REG(chip, CD_DEGLITCH_WIDTH, 0xFF, 0x08); + rts51x_write_register(chip, CD_DEGLITCH_EN, XD_CD_DEGLITCH_EN, + 0x00); + rts51x_write_register(chip, SD30_DRIVE_SEL, SD30_DRIVE_MASK, + chip->option.sd30_pad_drive); + rts51x_write_register(chip, CARD_DRIVE_SEL, SD20_DRIVE_MASK, + chip->option.sd20_pad_drive); + if (chip->rts5179) + rts51x_write_register(chip, CARD_PULL_CTL5, 0x03, 0x01); + if (!chip->option.ww_enable) { + if (CHECK_PKG(chip, LQFP48)) { + rts51x_write_register(chip, CARD_PULL_CTL3, + 0x80, 0x80); + rts51x_write_register(chip, CARD_PULL_CTL6, + 0xf0, 0xA0); + } else { + rts51x_write_register(chip, CARD_PULL_CTL1, + 0x30, 0x20); + rts51x_write_register(chip, CARD_PULL_CTL3, + 0x80, 0x80); + rts51x_write_register(chip, CARD_PULL_CTL6, + 0x0c, 0x08); + } + } + } + if (chip->option.sd_ctl & SUPPORT_UHS50_MMC44) { + SET_UHS50(chip); + RTS51X_DEBUGP("option enable UHS50&MMC44,sd_ctl:0x%x\n", + chip->option.sd_ctl); + } else { + /* if(CHECK_PID(chip, 0x0139)&&CHECK_PKG(chip, LQFP48)) */ + if ((CHECK_PID(chip, 0x0139) && CHECK_PKG(chip, LQFP48)) + || chip->rts5179) { + SET_UHS50(chip); + RTS51X_DEBUGP("PID enable UHS50&MMC44\n"); + } else { + CLEAR_UHS50(chip); + RTS51X_DEBUGP("PID disable UHS50&MMC44\n"); + } + } + + if (chip->option.ms_errreg_fix && (chip->ic_version > 1)) + rts51x_write_register(chip, 0xFD4D, 0x01, 0x01); + retval = rts51x_write_phy_register(chip, 0xC2, 0x7C); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + rts51x_init_cmd(chip); + + /* GPIO OE */ + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_GPIO, GPIO_OE, GPIO_OE); +#ifdef LED_AUTO_BLINK + /* LED autoblink */ + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_AUTO_BLINK, + BLINK_ENABLE | BLINK_SPEED_MASK, + BLINK_ENABLE | chip->option.led_blink_speed); +#endif + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DMA1_CTL, + EXTEND_DMA1_ASYNC_SIGNAL, EXTEND_DMA1_ASYNC_SIGNAL); + + retval = rts51x_send_cmd(chip, MODE_C, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); +#ifdef SUPPORT_OCP + if (chip->asic_code) { + rts51x_write_register(chip, OCPCTL, MS_OCP_DETECT_EN, + MS_OCP_DETECT_EN); + RTS51X_DEBUGP("Enable OCP detect!\n"); + } +#endif + if (chip->option.FT2_fast_mode) { + card_power_on(chip, SD_CARD | MS_CARD | XD_CARD); + wait_timeout(10); + } + rts51x_clear_start_time(chip); + + return STATUS_SUCCESS; +} + +int rts51x_init_chip(struct rts51x_chip *chip) +{ + int retval; + u8 val; + + chip->max_lun = 0; + chip->cur_clk = 0; + chip->cur_card = 0; + + chip->card2lun[XD_CARD] = 0; + chip->card2lun[SD_CARD] = 0; + chip->card2lun[MS_CARD] = 0; + chip->card_ejected = 0; + + chip->lun2card[0] = XD_CARD | SD_CARD | MS_CARD; +#if 0 + chip->option.sdr50_tx_phase = 0x01; + chip->option.sdr50_rx_phase = 0x05; + chip->option.ddr50_tx_phase = 0x09; + chip->option.ddr50_rx_phase = 0x06; /* add for debug */ +#endif +#ifdef CLOSE_SSC_POWER + rts51x_write_register(chip, FPDCTL, SSC_POWER_MASK, SSC_POWER_ON); + udelay(100); + rts51x_write_register(chip, CLK_DIV, CLK_CHANGE, 0x00); +#endif + RTS51X_SET_STAT(chip, STAT_RUN); + + RTS51X_READ_REG(chip, HW_VERSION, &val); + if ((val & 0x0f) >= 2) + chip->option.rcc_bug_fix_en = 0; + RTS51X_DEBUGP("rcc bug fix enable:%d\n", chip->option.rcc_bug_fix_en); + RTS51X_DEBUGP("HW_VERSION: 0x%x\n", val); + if (val & FPGA_VER) { + chip->asic_code = 0; + RTS51X_DEBUGP("FPGA!\n"); + } else { + chip->asic_code = 1; + RTS51X_DEBUGP("ASIC!\n"); + } + chip->ic_version = val & HW_VER_MASK; + + if (!check_sd_speed_prior(chip->option.sd_speed_prior)) + chip->option.sd_speed_prior = 0x01020403; + RTS51X_DEBUGP("sd_speed_prior = 0x%08x\n", + chip->option.sd_speed_prior); + + RTS51X_READ_REG(chip, CARD_SHARE_MODE, &val); + if (val & CARD_SHARE_LQFP_SEL) { + chip->package = LQFP48; + RTS51X_DEBUGP("Package: LQFP48\n"); + } else { + chip->package = QFN24; + RTS51X_DEBUGP("Package: QFN24\n"); + } + + RTS51X_READ_REG(chip, HS_USB_STAT, &val); + if (val & USB_HI_SPEED) { + chip->usb_speed = USB_20; + RTS51X_DEBUGP("USB High Speed\n"); + } else { + chip->usb_speed = USB_11; + RTS51X_DEBUGP("USB Full Speed\n"); + } + + RTS51X_READ_REG(chip, CFG_MODE_1, &val); + if (val & RTS5179) { + chip->rts5179 = 1; + RTS51X_DEBUGP("device is rts5179\n"); + } else { + chip->rts5179 = 0; + } + + retval = rts51x_reset_chip(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +int rts51x_release_chip(struct rts51x_chip *chip) +{ + xd_free_l2p_tbl(chip); + ms_free_l2p_tbl(chip); + chip->card_ready = 0; + return STATUS_SUCCESS; +} + +#ifndef LED_AUTO_BLINK +static inline void rts51x_blink_led(struct rts51x_chip *chip) +{ + /* Read/Write */ + if (chip->card_ready) { + if (chip->led_toggle_counter < + chip->option.led_toggle_interval) { + chip->led_toggle_counter++; + } else { + chip->led_toggle_counter = 0; + toggle_gpio(chip, LED_GPIO); + } + } +} +#endif + +int rts51x_check_start_time(struct rts51x_chip *chip) +{ + return 0; +} + +void rts51x_set_start_time(struct rts51x_chip *chip) +{ +} + +void rts51x_clear_start_time(struct rts51x_chip *chip) +{ +} + +static void rts51x_auto_delink_cmd(struct rts51x_chip *chip) +{ + rts51x_write_register(chip, AUTO_DELINK_EN, + AUTO_DELINK, AUTO_DELINK); +} + +static void rts51x_auto_delink_force_cmd(struct rts51x_chip *chip) +{ + rts51x_write_register(chip, AUTO_DELINK_EN, + AUTO_DELINK | FORCE_DELINK, + AUTO_DELINK | FORCE_DELINK); +} + +#ifdef USING_POLLING_CYCLE_DELINK +/* using polling cycle as delink time */ +static void rts51x_auto_delink_polling_cycle(struct rts51x_chip *chip) +{ + if (chip->auto_delink_counter <= + chip->option.delink_delay * 2) { + if (chip->auto_delink_counter == + chip->option.delink_delay) { + clear_first_install_mark(chip); + if (chip->card_exist) { + /* False card */ + if (!chip->card_ejected) { + /* if card is not ejected or safely + * remove,then do force delink */ + RTS51X_DEBUGP("False card inserted," + "do force delink\n"); + rts51x_auto_delink_force_cmd(chip); + chip->auto_delink_counter = + chip->option.delink_delay * 2 + 1; + } + } else { + RTS51X_DEBUGP("No card inserted, do delink\n"); + /* rts51x_write_register(chip, CARD_PWR_CTL, + DV3318_AUTO_PWR_OFF, 0); */ + rts51x_auto_delink_cmd(chip); + } + } + if (chip->auto_delink_counter == + chip->option.delink_delay * 2) { + RTS51X_DEBUGP("Try to do force delink\n"); + rts51x_auto_delink_force_cmd(chip); + } + chip->auto_delink_counter++; + } +} + +static void rts51x_auto_delink(struct rts51x_chip *chip) +{ + rts51x_auto_delink_polling_cycle(chip); +} +#else +/* some of called funcs are not implemented, so comment it out */ +#if 0 +/* using precise time as delink time */ +static void rts51x_auto_delink_precise_time(struct rts51x_chip *chip) +{ + int retvalue = 0; + + retvalue = rts51x_get_card_status(chip, &chip->card_status); + /* get card CD status success and card CD not exist, + * then check whether delink */ + if ((retvalue == STATUS_SUCCESS) + && (!(chip->card_status & (SD_CD | MS_CD | XD_CD)))) { + if (rts51x_count_delink_time(chip) >= + chip->option.delink_delay) { + clear_first_install_mark(chip); + RTS51X_DEBUGP("No card inserted, do delink\n"); + /* sangdy2010-05-17:disable because there is error + * after SSC clock closed and card power + * has been closed before */ + /* rts51x_write_register(chip, CARD_PWR_CTL, + DV3318_AUTO_PWR_OFF, 0); */ + rts51x_auto_delink_cmd(chip); + } + /* card CD exist and not ready, then do force delink */ + if ((retvalue == STATUS_SUCCESS) + && (chip->card_status & (SD_CD | MS_CD | XD_CD))) { + /* if card is not ejected or safely remove, + * then do force delink */ + if (!chip->card_ejected) { + /* sangdy2010-11-16:polling at least 2 cycles + * then do force delink for card may force delink + * if card is extracted and insert quickly + * after ready. */ + if (chip->auto_delink_counter > 1) { + if (rts51x_count_delink_time(chip) > + chip->option.delink_delay * 2) { + RTS51X_DEBUGP("Try to do force" + "delink\n"); + rts51x_auto_delink_force_cmd(chip); + } + } + } + } + chip->auto_delink_counter++; +} +#else +static void rts51x_auto_delink_precise_time(struct rts51x_chip *chip) +{ +} +#endif + +static void rts51x_auto_delink(struct rts51x_chip *chip) +{ + rts51x_auto_delink_precise_time(chip); +} +#endif + +void rts51x_polling_func(struct rts51x_chip *chip) +{ +#ifdef SUPPORT_SD_LOCK + struct sd_info *sd_card = &(chip->sd_card); + + if (sd_card->sd_erase_status) { + if (chip->card_exist & SD_CARD) { + u8 val; + rts51x_read_register(chip, SD_BUS_STAT, &val); + if (val & SD_DAT0_STATUS) { + /* Erase completed */ + sd_card->sd_erase_status = SD_NOT_ERASE; + sd_card->sd_lock_notify = 1; + + /* SD card should be reinited, + * so we release it here. */ + sd_cleanup_work(chip); + release_sd_card(chip); + chip->card_ready &= ~SD_CARD; + chip->card_exist &= ~SD_CARD; + chip->rw_card[chip->card2lun[SD_CARD]] = NULL; + clear_bit(chip->card2lun[SD_CARD], + &(chip->lun_mc)); + } + } else { + sd_card->sd_erase_status = SD_NOT_ERASE; + } + } +#endif + + rts51x_init_cards(chip); + +#ifdef SUPPORT_OCP + /* if OCP happen and card exist, then close card OE */ + if ((chip->ocp_stat & (MS_OCP_NOW | MS_OCP_EVER)) && + (chip->card_exist)) { + + rts51x_prepare_run(chip); + + if (chip->card_exist & SD_CARD) + rts51x_write_register(chip, CARD_OE, SD_OUTPUT_EN, 0); + else if (chip->card_exist & MS_CARD) + rts51x_write_register(chip, CARD_OE, MS_OUTPUT_EN, 0); + else if (chip->card_exist & XD_CARD) + rts51x_write_register(chip, CARD_OE, XD_OUTPUT_EN, 0); + } +#endif + + if (chip->idle_counter < IDLE_MAX_COUNT) { + chip->idle_counter++; + } else { + if (!RTS51X_CHK_STAT(chip, STAT_IDLE)) { + RTS51X_DEBUGP("Idle state!\n"); + RTS51X_SET_STAT(chip, STAT_IDLE); +#ifndef LED_AUTO_BLINK + chip->led_toggle_counter = 0; +#endif + /* Idle state, turn off LED + * to reduce power consumption */ + if (chip->option.led_always_on + && (chip->card_exist & + (SD_CARD | MS_CARD | XD_CARD)) + && (!chip->card_ejected)) { + turn_on_led(chip, LED_GPIO); + } else { + if (chip->rts5179) { + rts51x_ep0_write_register(chip, + CARD_GPIO, + 0x03, 0x00); + } else { + turn_off_led(chip, LED_GPIO); + } + + } + +#ifdef CLOSE_SSC_POWER + if (!chip->card_ready) { + rts51x_write_register(chip, CLK_DIV, CLK_CHANGE, + CLK_CHANGE); + rts51x_write_register(chip, FPDCTL, + SSC_POWER_MASK, + SSC_POWER_DOWN); + RTS51X_DEBUGP("Close SSC clock power!\n"); + } +#endif + } + } + + switch (RTS51X_GET_STAT(chip)) { + case STAT_RUN: +#ifndef LED_AUTO_BLINK + rts51x_blink_led(chip); +#endif + do_remaining_work(chip); + break; + + case STAT_IDLE: + break; + + default: + break; + } + + if (chip->option.auto_delink_en && !chip->card_ready) { + rts51x_auto_delink(chip); + } else { + chip->auto_delink_counter = 0; + rts51x_clear_start_time(chip); + } +} + +void rts51x_add_cmd(struct rts51x_chip *chip, + u8 cmd_type, u16 reg_addr, u8 mask, u8 data) +{ + int i; + + if (chip->cmd_idx < ((CMD_BUF_LEN - CMD_OFFSET) / 4)) { + i = CMD_OFFSET + chip->cmd_idx * 4; + chip->cmd_buf[i++] = + ((cmd_type & 0x03) << 6) | (u8) ((reg_addr >> 8) & 0x3F); + chip->cmd_buf[i++] = (u8) reg_addr; + chip->cmd_buf[i++] = mask; + chip->cmd_buf[i++] = data; + chip->cmd_idx++; + } +} + +int rts51x_send_cmd(struct rts51x_chip *chip, u8 flag, int timeout) +{ + int result; + + chip->cmd_buf[CNT_H] = (u8) (chip->cmd_idx >> 8); + chip->cmd_buf[CNT_L] = (u8) (chip->cmd_idx); + chip->cmd_buf[STAGE_FLAG] = flag; + + result = rts51x_transfer_data_rcc(chip, SND_BULK_PIPE(chip), + (void *)(chip->cmd_buf), + chip->cmd_idx * 4 + CMD_OFFSET, + 0, NULL, timeout, MODE_C); + if (result != STATUS_SUCCESS) + TRACE_RET(chip, result); + + return STATUS_SUCCESS; +} + +int rts51x_get_rsp(struct rts51x_chip *chip, int rsp_len, int timeout) +{ + int result; + + if (rsp_len <= 0) + TRACE_RET(chip, STATUS_ERROR); + /* rsp_len must aligned to dword */ + if (rsp_len % 4) + rsp_len += (4 - rsp_len % 4); + + result = rts51x_transfer_data_rcc(chip, RCV_BULK_PIPE(chip), + (void *)chip->rsp_buf, rsp_len, + 0, NULL, timeout, STAGE_R); + if (result != STATUS_SUCCESS) + TRACE_RET(chip, result); + + return STATUS_SUCCESS; +} + +int rts51x_get_card_status(struct rts51x_chip *chip, u16 * status) +{ + int retval; + u16 val; + +#ifdef GET_CARD_STATUS_USING_EPC + retval = rts51x_get_epc_status(chip, &val); + + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); +#else + retval = rts51x_ctrl_transfer(chip, RCV_CTRL_PIPE(chip), 0x02, 0xC0, + 0, 0, &val, 2, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); +#endif + + if (status) + *status = val; + + return STATUS_SUCCESS; +} + +int rts51x_write_register(struct rts51x_chip *chip, u16 addr, u8 mask, u8 data) +{ + int retval; + + rts51x_init_cmd(chip); + rts51x_add_cmd(chip, WRITE_REG_CMD, addr, mask, data); + retval = rts51x_send_cmd(chip, MODE_C, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +int rts51x_read_register(struct rts51x_chip *chip, u16 addr, u8 * data) +{ + int retval; + + if (data) + *data = 0; + rts51x_init_cmd(chip); + rts51x_add_cmd(chip, READ_REG_CMD, addr, 0, 0); + retval = rts51x_send_cmd(chip, MODE_CR, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = rts51x_get_rsp(chip, 1, 100); + + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (data) + *data = chip->rsp_buf[0]; + + return STATUS_SUCCESS; +} + +int rts51x_ep0_write_register(struct rts51x_chip *chip, u16 addr, u8 mask, + u8 data) +{ + int retval; + u16 value = 0, index = 0; + + value |= (u16) (3 & 0x03) << 14; + value |= (u16) (addr & 0x3FFF); + index |= (u16) mask << 8; + index |= (u16) data; + + retval = rts51x_ctrl_transfer(chip, SND_CTRL_PIPE(chip), 0x00, 0x40, + cpu_to_be16(value), cpu_to_be16(index), + NULL, 0, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + return STATUS_SUCCESS; +} + +int rts51x_ep0_read_register(struct rts51x_chip *chip, u16 addr, u8 * data) +{ + int retval; + u16 value = 0; + u8 val; + + if (data) + *data = 0; + + value |= (u16) (2 & 0x03) << 14; + value |= (u16) (addr & 0x3FFF); + + retval = rts51x_ctrl_transfer(chip, RCV_CTRL_PIPE(chip), 0x00, 0xC0, + cpu_to_be16(value), 0, &val, 1, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + if (data) + *data = val; + + return STATUS_SUCCESS; +} + +int rts51x_seq_write_register(struct rts51x_chip *chip, u16 addr, u16 len, + u8 *data) +{ + int result; + u16 cmd_len = len + 12; + + if (!data) + TRACE_RET(chip, STATUS_ERROR); + + cmd_len = (cmd_len <= CMD_BUF_LEN) ? cmd_len : CMD_BUF_LEN; + + /* cmd_len must aligned to dword */ + if (cmd_len % 4) + cmd_len += (4 - cmd_len % 4); + + chip->cmd_buf[0] = 'R'; + chip->cmd_buf[1] = 'T'; + chip->cmd_buf[2] = 'C'; + chip->cmd_buf[3] = 'R'; + chip->cmd_buf[PACKET_TYPE] = SEQ_WRITE; + chip->cmd_buf[5] = (u8) (len >> 8); + chip->cmd_buf[6] = (u8) len; + chip->cmd_buf[STAGE_FLAG] = 0; + chip->cmd_buf[8] = (u8) (addr >> 8); + chip->cmd_buf[9] = (u8) addr; + + memcpy(chip->cmd_buf + 12, data, len); + + result = rts51x_transfer_data_rcc(chip, SND_BULK_PIPE(chip), + (void *)(chip->cmd_buf), cmd_len, 0, + NULL, 100, MODE_C); + if (result != STATUS_SUCCESS) + TRACE_RET(chip, result); + + return STATUS_SUCCESS; +} + +int rts51x_seq_read_register(struct rts51x_chip *chip, u16 addr, u16 len, + u8 *data) +{ + int result; + u16 rsp_len; + + if (!data) + TRACE_RET(chip, STATUS_ERROR); + /* rsp_len must aligned to dword */ + if (len % 4) + rsp_len = len + (4 - len % 4); + else + rsp_len = len; + + chip->cmd_buf[0] = 'R'; + chip->cmd_buf[1] = 'T'; + chip->cmd_buf[2] = 'C'; + chip->cmd_buf[3] = 'R'; + chip->cmd_buf[PACKET_TYPE] = SEQ_READ; + chip->cmd_buf[5] = (u8) (rsp_len >> 8); + chip->cmd_buf[6] = (u8) rsp_len; + chip->cmd_buf[STAGE_FLAG] = STAGE_R; + chip->cmd_buf[8] = (u8) (addr >> 8); + chip->cmd_buf[9] = (u8) addr; + + result = rts51x_transfer_data_rcc(chip, SND_BULK_PIPE(chip), + (void *)(chip->cmd_buf), 12, 0, NULL, + 100, MODE_C); + if (result != STATUS_SUCCESS) + TRACE_RET(chip, result); + + result = rts51x_transfer_data_rcc(chip, RCV_BULK_PIPE(chip), + (void *)data, rsp_len, 0, NULL, 100, + STAGE_DI); + if (result != STATUS_SUCCESS) + TRACE_RET(chip, result); + + return STATUS_SUCCESS; +} + +int rts51x_read_ppbuf(struct rts51x_chip *chip, u8 * buf, int buf_len) +{ + int retval; + + if (!buf) + TRACE_RET(chip, STATUS_ERROR); + + retval = + rts51x_seq_read_register(chip, PPBUF_BASE2, (u16) buf_len, buf); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + return STATUS_SUCCESS; +} + +int rts51x_write_ppbuf(struct rts51x_chip *chip, u8 * buf, int buf_len) +{ + int retval; + + if (!buf) + TRACE_RET(chip, STATUS_ERROR); + + retval = + rts51x_seq_write_register(chip, PPBUF_BASE2, (u16) buf_len, buf); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + return STATUS_SUCCESS; +} + +int rts51x_write_phy_register(struct rts51x_chip *chip, u8 addr, u8 val) +{ + int retval; + + RTS51X_DEBUGP("Write 0x%x to phy register 0x%x\n", val, addr); + + rts51x_init_cmd(chip); + + rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VSTAIN, 0xFF, val); + rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VCONTROL, 0xFF, addr & 0x0F); + rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x00); + rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x00); + rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x01); + rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VCONTROL, 0xFF, + (addr >> 4) & 0x0F); + rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x00); + rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x00); + rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x01); + + retval = rts51x_send_cmd(chip, MODE_C, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + return STATUS_SUCCESS; +} + +int rts51x_read_phy_register(struct rts51x_chip *chip, u8 addr, u8 * val) +{ + int retval; + + RTS51X_DEBUGP("Read from phy register 0x%x\n", addr); + + rts51x_init_cmd(chip); + + rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VCONTROL, 0xFF, 0x07); + rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x00); + rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x00); + rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x01); + rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VCONTROL, 0xFF, + (addr >> 4) & 0x0F); + rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x00); + rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x00); + rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x01); + rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VCONTROL, 0xFF, addr & 0x0F); + rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x00); + rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x00); + rts51x_add_cmd(chip, WRITE_REG_CMD, HS_VLOADM, 0xFF, 0x01); + rts51x_add_cmd(chip, READ_REG_CMD, HS_VSTAOUT, 0, 0); + + retval = rts51x_send_cmd(chip, MODE_CR, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = rts51x_get_rsp(chip, 1, 100); + + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + if (val) + *val = chip->rsp_buf[0]; + + RTS51X_DEBUGP("Return value: 0x%x\n", chip->rsp_buf[0]); + + return STATUS_SUCCESS; +} + +void rts51x_do_before_power_down(struct rts51x_chip *chip) +{ + RTS51X_DEBUGP("rts51x_do_before_power_down\n"); + + rts51x_prepare_run(chip); + + rts51x_release_cards(chip); + if (chip->rts5179) + rts51x_ep0_write_register(chip, CARD_GPIO, 0x03, 0x00); + else + turn_off_led(chip, LED_GPIO); + + chip->cur_clk = 0; + chip->card_exist = 0; + chip->cur_card = 0; + if (chip->asic_code && !chip->option.ww_enable) { + if (CHECK_PKG(chip, LQFP48)) { + rts51x_write_register(chip, CARD_PULL_CTL3, 0x80, 0x00); + rts51x_write_register(chip, CARD_PULL_CTL6, 0xf0, 0x50); + } else { + rts51x_write_register(chip, CARD_PULL_CTL1, 0x30, 0x10); + rts51x_write_register(chip, CARD_PULL_CTL3, 0x80, 0x00); + rts51x_write_register(chip, CARD_PULL_CTL6, 0x0c, 0x04); + } + } + if (CHECK_PKG(chip, LQFP48)) + rts51x_write_register(chip, CARD_PWR_CTL, LDO3318_PWR_MASK, + LDO_OFF); +} + +void rts51x_clear_hw_error(struct rts51x_chip *chip) +{ + rts51x_ep0_write_register(chip, SFSM_ED, 0xf8, 0xf8); +} + +void rts51x_prepare_run(struct rts51x_chip *chip) +{ +#ifdef CLOSE_SSC_POWER + if (RTS51X_CHK_STAT(chip, STAT_IDLE) && (!chip->card_ready)) { + rts51x_write_register(chip, FPDCTL, SSC_POWER_MASK, + SSC_POWER_ON); + udelay(100); + RTS51X_DEBUGP("Open SSC clock power.\n"); + + rts51x_write_register(chip, CLK_DIV, CLK_CHANGE, 0x00); + } +#endif +#if 0 + if (chip->option.ss_en && RTS51X_CHK_STAT(chip, STAT_SS)) { + rts51x_try_to_exit_ss(chip); + wait_timeout(100); + rts51x_init_chip(chip); + rts51x_init_cards(chip); + } + + RTS51X_SET_STAT(chip, STAT_RUN); +#endif +} + +#ifdef _MSG_TRACE +void rts51x_trace_msg(struct rts51x_chip *chip, unsigned char *buf, int clear) +{ + unsigned char *ptr; + int i, msg_cnt; + + if (!buf) + return; + + ptr = buf; + + if (chip->trace_msg[chip->msg_idx].valid) + msg_cnt = TRACE_ITEM_CNT; + else + msg_cnt = chip->msg_idx; + *(ptr++) = (u8) (msg_cnt >> 24); + *(ptr++) = (u8) (msg_cnt >> 16); + *(ptr++) = (u8) (msg_cnt >> 8); + *(ptr++) = (u8) msg_cnt; + RTS51X_DEBUGP("Trace message count is %d\n", msg_cnt); + + for (i = 1; i <= msg_cnt; i++) { + int j, idx; + + idx = chip->msg_idx - i; + if (idx < 0) + idx += TRACE_ITEM_CNT; + + *(ptr++) = (u8) (chip->trace_msg[idx].line >> 8); + *(ptr++) = (u8) (chip->trace_msg[idx].line); + for (j = 0; j < MSG_FUNC_LEN; j++) + *(ptr++) = chip->trace_msg[idx].func[j]; + for (j = 0; j < MSG_FILE_LEN; j++) + *(ptr++) = chip->trace_msg[idx].file[j]; + for (j = 0; j < TIME_VAL_LEN; j++) + *(ptr++) = chip->trace_msg[idx].timeval_buf[j]; + } + + if (clear) { + chip->msg_idx = 0; + for (i = 0; i < TRACE_ITEM_CNT; i++) + chip->trace_msg[i].valid = 0; + } +} +#endif + +void rts51x_pp_status(struct rts51x_chip *chip, unsigned int lun, u8 * status, + u8 status_len) +{ + struct sd_info *sd_card = &(chip->sd_card); + struct ms_info *ms_card = &(chip->ms_card); + u8 card = get_lun_card(chip, lun); +#ifdef SUPPORT_OC + u8 oc_now_mask = 0, oc_ever_mask = 0; +#endif + + if (!status || (status_len < 32)) + return; + /* IC Version */ + status[0] = (u8) RTS51X_GET_PID(chip); + status[1] = (u8) (chip->ic_version); + + /* Auto delink mode */ + if (chip->option.auto_delink_en) + status[2] = 0x10; + else + status[2] = 0x00; + + /* Spec version */ + status[3] = 20; + status[4] = 10; + status[5] = 05; + status[6] = 21; + + /* Card WP */ + if (chip->card_wp) + status[7] = 0x20; + else + status[7] = 0x00; + +#ifdef SUPPORT_OC + /* Over current status */ + status[8] = 0; + oc_now_mask = MS_OCP_NOW; + oc_ever_mask = MS_OCP_EVER; + + if (chip->ocp_stat & oc_now_mask) + status[8] |= 0x02; + if (chip->ocp_stat & oc_ever_mask) + status[8] |= 0x01; +#endif + + if (card == SD_CARD) { + if (CHK_SD(sd_card)) { + if (CHK_SD_HCXC(sd_card)) { + if (sd_card->capacity > 0x4000000) + /* SDXC */ + status[0x0E] = 0x02; + else /* SDHC */ + status[0x0E] = 0x01; + } else { /* SDSC */ + status[0x0E] = 0x00; + } + + if (CHK_SD_SDR104(sd_card)) + status[0x0F] = 0x03; + else if (CHK_SD_DDR50(sd_card)) + status[0x0F] = 0x04; + else if (CHK_SD_SDR50(sd_card)) + status[0x0F] = 0x02; + else if (CHK_SD_HS(sd_card)) + status[0x0F] = 0x01; + else + status[0x0F] = 0x00; /* Normal speed */ + } else { + if (CHK_MMC_SECTOR_MODE(sd_card)) + status[0x0E] = 0x01; /* High capacity */ + else + status[0x0E] = 0x00; /* Normal capacity */ + + if (CHK_MMC_DDR52(sd_card)) + status[0x0F] = 0x03; /* DDR 52M */ + else if (CHK_MMC_52M(sd_card)) + status[0x0F] = 0x02; /* SDR 52M */ + else if (CHK_MMC_26M(sd_card)) + status[0x0F] = 0x01; /* SDR 26M */ + else + status[0x0F] = 0x00; /* Normal speed */ + } + } else if (card == MS_CARD) { + if (CHK_MSPRO(ms_card)) { + if (CHK_MSXC(ms_card)) + status[0x0E] = 0x01; /* XC */ + else + status[0x0E] = 0x00; + + if (CHK_HG8BIT(ms_card)) + status[0x0F] = 0x01; + else + status[0x0F] = 0x00; + } + } +#ifdef SUPPORT_SD_LOCK + /* SD Lock/Unlock */ + if (card == SD_CARD) { + status[0x17] = 0x80; + if (sd_card->sd_erase_status) + status[0x17] |= 0x01; /* Under erasing */ + if (sd_card->sd_lock_status & SD_LOCKED) { + status[0x17] |= 0x02; /* Locked */ + status[0x07] |= 0x40; /* Read protected */ + } + if (sd_card->sd_lock_status & SD_PWD_EXIST) + status[0x17] |= 0x04; /* Contain PWD */ + } else { + status[0x17] = 0x00; + } + + RTS51X_DEBUGP("status[0x17] = 0x%x\n", status[0x17]); +#endif + + /* Function 0 + * Support Magic Gate, CPRM and PhyRegister R/W */ + status[0x18] = 0x8A; + + /* Function 2 + * Support OC LUN status & WP LUN status */ + status[0x1A] = 0x28; + + /* Function 7 */ +#ifdef SUPPORT_SD_LOCK + /* Support SD Lock/Unlock */ + status[0x1F] = 0x01; +#endif + + /* Function 2 + * Support OC LUN status & WP LUN status */ + status[0x1A] = 0x28; +} + +void rts51x_read_status(struct rts51x_chip *chip, unsigned int lun, + u8 *rts51x_status, u8 status_len) +{ + if (!rts51x_status || (status_len < 16)) + return; + /* VID */ + rts51x_status[0] = (u8) (RTS51X_GET_VID(chip) >> 8); + rts51x_status[1] = (u8) RTS51X_GET_VID(chip); + + /* PID */ + rts51x_status[2] = (u8) (RTS51X_GET_PID(chip) >> 8); + rts51x_status[3] = (u8) RTS51X_GET_PID(chip); + + /* gbLUN */ + rts51x_status[4] = (u8) lun; + + /* Lun Card Number */ + if (chip->card_exist) { + if (chip->card_exist & XD_CARD) + rts51x_status[5] = 4; /* xD Card */ + else if (chip->card_exist & SD_CARD) + rts51x_status[5] = 2; /* SD Card */ + else if (chip->card_exist & MS_CARD) + rts51x_status[5] = 3; /* MS Card */ + else + rts51x_status[5] = 7; /* Multi */ + } else { + rts51x_status[5] = 7; /* Multi */ + } + + /* Total LUNs */ + rts51x_status[6] = 1; + + /* IC Version */ + rts51x_status[7] = (u8) RTS51X_GET_PID(chip); + rts51x_status[8] = chip->ic_version; + + /* Physical Exist */ + if (check_card_exist(chip, lun)) + rts51x_status[9] = 1; + else + rts51x_status[9] = 0; + + /* Multi Flag */ + rts51x_status[10] = 1; + + /* LUN Valid Map */ + rts51x_status[11] = XD_CARD | SD_CARD | MS_CARD; + + /* Logical Exist */ + if (check_card_ready(chip, lun)) + rts51x_status[12] = 1; + else + rts51x_status[12] = 0; + + /* Detailed Type */ + if (get_lun_card(chip, lun) == XD_CARD) { + rts51x_status[13] = 0x40; + } else if (get_lun_card(chip, lun) == SD_CARD) { + struct sd_info *sd_card = &(chip->sd_card); + + rts51x_status[13] = 0x20; + if (CHK_SD(sd_card)) { + if (CHK_SD_HCXC(sd_card)) + rts51x_status[13] |= 0x04; /* Hi capacity SD */ + if (CHK_SD_HS(sd_card)) + rts51x_status[13] |= 0x02; /* Hi speed SD */ + } else { + rts51x_status[13] |= 0x08; /* MMC card */ + if (CHK_MMC_52M(sd_card)) + rts51x_status[13] |= 0x02; /* Hi speed */ + if (CHK_MMC_SECTOR_MODE(sd_card)) + rts51x_status[13] |= 0x04; /* Hi capacity */ + } + } else if (get_lun_card(chip, lun) == MS_CARD) { + struct ms_info *ms_card = &(chip->ms_card); + + if (CHK_MSPRO(ms_card)) { + rts51x_status[13] = 0x38; /* MS Pro */ + if (CHK_HG8BIT(ms_card)) + rts51x_status[13] |= 0x04; /* HG */ +#ifdef SUPPORT_MSXC + if (CHK_MSXC(ms_card)) + rts51x_status[13] |= 0x01; /* MSXC */ +#endif + } else { + rts51x_status[13] = 0x30; + } + } else { + rts51x_status[13] = 0x70; + } +/* Support OC, auto delink, vendor r/w, get bus width */ + rts51x_status[14] = 0x78; + + rts51x_status[15] = 0x82; +} + +int rts51x_transfer_data_rcc(struct rts51x_chip *chip, unsigned int pipe, + void *buf, unsigned int len, int use_sg, + unsigned int *act_len, int timeout, u8 stage_flag) +{ + int retval; + + retval = + rts51x_transfer_data(chip, pipe, buf, len, use_sg, act_len, + timeout); + + return retval; + +} diff --git a/drivers/staging/rts5139/rts51x_chip.h b/drivers/staging/rts5139/rts51x_chip.h new file mode 100644 index 0000000..321ece7 --- /dev/null +++ b/drivers/staging/rts5139/rts51x_chip.h @@ -0,0 +1,904 @@ +/* Driver for Realtek RTS51xx USB card reader + * Header file + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + * Maintainer: + * Edwin Rong (edwin_rong@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#ifndef __RTS51X_CHIP_H +#define __RTS51X_CHIP_H + +#include <linux/usb.h> +#include <linux/usb_usual.h> +#include <linux/blkdev.h> +#include <linux/completion.h> +#include <linux/mutex.h> +#include <scsi/scsi_host.h> + +#include "trace.h" + +#define SUPPORT_CPRM +#define SUPPORT_MAGIC_GATE +#define SUPPORT_MSXC +/* #define LED_AUTO_BLINK */ + +/* { wwang, 2010-07-26 + * Add support for SD lock/unlock */ +/* #define SUPPORT_SD_LOCK */ +/* } wwang, 2010-07-26 */ + +#ifdef SUPPORT_MAGIC_GA +/* Using NORMAL_WRITE instead of AUTO_WRITE to set ICVTE */ +#define MG_SET_ICV_SLOW +#endif + +#ifdef SUPPORT_MSXC +#define XC_POWERCLASS +#define SUPPORT_PCGL_1P18 +#endif + +#define GET_CARD_STATUS_USING_EPC + +#define CLOSE_SSC_POWER + +#define SUPPORT_OCP + +#define MS_SPEEDUP +/* #define XD_SPEEDUP */ + +#define SD_XD_IO_FOLLOW_PWR + +#define SD_NR 2 +#define MS_NR 3 +#define XD_NR 4 +#define SD_CARD (1 << SD_NR) +#define MS_CARD (1 << MS_NR) +#define XD_CARD (1 << XD_NR) + +#define SD_CD 0x01 +#define MS_CD 0x02 +#define XD_CD 0x04 +#define SD_WP 0x08 + +#define MAX_ALLOWED_LUN_CNT 8 +#define CMD_BUF_LEN 1024 +#define RSP_BUF_LEN 1024 +#define POLLING_INTERVAL 50 /* 50ms */ + +#define XD_FREE_TABLE_CNT 1200 +#define MS_FREE_TABLE_CNT 512 + +/* Bit Operation */ +#define SET_BIT(data, idx) ((data) |= 1 << (idx)) +#define CLR_BIT(data, idx) ((data) &= ~(1 << (idx))) +#define CHK_BIT(data, idx) ((data) & (1 << (idx))) + +/* Command type */ +#define READ_REG_CMD 0 +#define WRITE_REG_CMD 1 +#define CHECK_REG_CMD 2 + +#define PACKET_TYPE 4 +#define CNT_H 5 +#define CNT_L 6 +#define STAGE_FLAG 7 +#define CMD_OFFSET 8 + +/* Packet type */ +#define BATCH_CMD 0 +#define SEQ_READ 1 +#define SEQ_WRITE 2 + +/* Stage flag */ +#define STAGE_R 0x01 +#define STAGE_DI 0x02 +#define STAGE_DO 0x04 +/* Return MS_TRANS_CFG, GET_INT */ +#define STAGE_MS_STATUS 0x08 +/* Return XD_CFG, XD_CTL, XD_PAGE_STATUS */ +#define STAGE_XD_STATUS 0x10 +/* Command stage mode */ +#define MODE_C 0x00 +#define MODE_CR (STAGE_R) +#define MODE_CDIR (STAGE_R | STAGE_DI) +#define MODE_CDOR (STAGE_R | STAGE_DO) + +/* Function return code */ +#ifndef STATUS_SUCCESS +#define STATUS_SUCCESS 0 +#endif + +#define STATUS_FAIL 1 +#define STATUS_READ_FAIL 2 +#define STATUS_WRITE_FAIL 3 +#define STATUS_TIMEDOUT 4 +#define STATUS_NOMEM 5 +#define STATUS_TRANS_SHORT 6 +#define STATUS_TRANS_LONG 7 +#define STATUS_STALLED 8 +#define STATUS_ERROR 10 + +#define IDLE_MAX_COUNT 10 +#define POLLING_WAIT_CNT 1 +#define DELINK_DELAY 100 +#define LED_TOGGLE_INTERVAL 6 +#define LED_GPIO 0 + +/* package */ +#define QFN24 0 +#define LQFP48 1 + +#define USB_11 0 +#define USB_20 1 + +/* + * Transport return codes + */ +/* Transport good, command good */ +#define TRANSPORT_GOOD 0 +/* Transport good, command failed */ +#define TRANSPORT_FAILED 1 +/* Command failed, no auto-sense */ +#define TRANSPORT_NO_SENSE 2 +/* Transport bad (i.e. device dead) */ +#define TRANSPORT_ERROR 3 + +/* Supported Clock */ +enum card_clock { CLK_20 = 1, CLK_30, CLK_40, CLK_50, CLK_60, CLK_80, CLK_100 }; + +#ifdef _MSG_TRACE + +#define TRACE_ITEM_CNT 64 + +struct trace_msg_t { + u16 line; +#define MSG_FUNC_LEN 64 + char func[MSG_FUNC_LEN]; +#define MSG_FILE_LEN 32 + char file[MSG_FILE_LEN]; +#define TIME_VAL_LEN 16 + u8 timeval_buf[TIME_VAL_LEN]; + u8 valid; +}; + +#endif /* _MSG_TRACE */ + +/* Size of the autosense data buffer */ +#define SENSE_SIZE 18 + +/* Sense type */ +#define SENSE_TYPE_NO_SENSE 0 +#define SENSE_TYPE_MEDIA_CHANGE 1 +#define SENSE_TYPE_MEDIA_NOT_PRESENT 2 +#define SENSE_TYPE_MEDIA_LBA_OVER_RANGE 3 +#define SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT 4 +#define SENSE_TYPE_MEDIA_WRITE_PROTECT 5 +#define SENSE_TYPE_MEDIA_INVALID_CMD_FIELD 6 +#define SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR 7 +#define SENSE_TYPE_MEDIA_WRITE_ERR 8 +#define SENSE_TYPE_FORMAT_IN_PROGRESS 9 +#define SENSE_TYPE_FORMAT_CMD_FAILED 10 +#ifdef SUPPORT_MAGIC_GATE +/* COPY PROTECTION KEY EXCHANGE FAILURE - KEY NOT ESTABLISHED */ +#define SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB 0x0b +/* COPY PROTECTION KEY EXCHANGE FAILURE - AUTHENTICATION FAILURE */ +#define SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN 0x0c +/* INCOMPATIBLE MEDIUM INSTALLED */ +#define SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM 0x0d +/* WRITE ERROR */ +#define SENSE_TYPE_MG_WRITE_ERR 0x0e +#endif +#ifdef SUPPORT_SD_LOCK +/* FOR Locked SD card */ +#define SENSE_TYPE_MEDIA_READ_FORBIDDEN 0x10 +#endif + +/*---- sense key ----*/ +#define ILI 0x20 /* ILI bit is on */ + +#define NO_SENSE 0x00 /* not exist sense key */ +#define RECOVER_ERR 0x01 /* Target/Logical unit is recoverd */ +#define NOT_READY 0x02 /* Logical unit is not ready */ +#define MEDIA_ERR 0x03 /* medium/data error */ +#define HARDWARE_ERR 0x04 /* hardware error */ +#define ILGAL_REQ 0x05 /* CDB/parameter/identify msg error */ +#define UNIT_ATTENTION 0x06 /* unit attention condition occur */ +#define DAT_PRTCT 0x07 /* read/write is desable */ +#define BLNC_CHK 0x08 /* find blank/DOF in read */ + /* write to unblank area */ +#define CPY_ABRT 0x0a /* Copy/Compare/Copy&Verify illgal */ +#define ABRT_CMD 0x0b /* Target make the command in error */ +#define EQUAL 0x0c /* Search Data end with Equal */ +#define VLM_OVRFLW 0x0d /* Some data are left in buffer */ +#define MISCMP 0x0e /* find inequality */ + +/*----------------------------------- + SENSE_DATA +-----------------------------------*/ +/*---- valid ----*/ +#define SENSE_VALID 0x80 /* Sense data is valid as SCSI2 */ +#define SENSE_INVALID 0x00 /* Sense data is invalid as SCSI2 */ + +/*---- error code ----*/ +#define CUR_ERR 0x70 /* current error */ +#define DEF_ERR 0x71 /* specific command error */ + +/*---- sense key Infomation ----*/ +#define SNSKEYINFO_LEN 3 /* length of sense key infomation */ + +#define SKSV 0x80 +#define CDB_ILLEGAL 0x40 +#define DAT_ILLEGAL 0x00 +#define BPV 0x08 +#define BIT_ILLEGAL0 0 /* bit0 is illegal */ +#define BIT_ILLEGAL1 1 /* bit1 is illegal */ +#define BIT_ILLEGAL2 2 /* bit2 is illegal */ +#define BIT_ILLEGAL3 3 /* bit3 is illegal */ +#define BIT_ILLEGAL4 4 /* bit4 is illegal */ +#define BIT_ILLEGAL5 5 /* bit5 is illegal */ +#define BIT_ILLEGAL6 6 /* bit6 is illegal */ +#define BIT_ILLEGAL7 7 /* bit7 is illegal */ + +/*---- ASC ----*/ +#define ASC_NO_INFO 0x00 +#define ASC_MISCMP 0x1d +#define ASC_INVLD_CDB 0x24 +#define ASC_INVLD_PARA 0x26 +#define ASC_LU_NOT_READY 0x04 +#define ASC_WRITE_ERR 0x0c +#define ASC_READ_ERR 0x11 +#define ASC_LOAD_EJCT_ERR 0x53 +#define ASC_MEDIA_NOT_PRESENT 0x3A +#define ASC_MEDIA_CHANGED 0x28 +#define ASC_MEDIA_IN_PROCESS 0x04 +#define ASC_WRITE_PROTECT 0x27 +#define ASC_LUN_NOT_SUPPORTED 0x25 + +/*---- ASQC ----*/ +#define ASCQ_NO_INFO 0x00 +#define ASCQ_MEDIA_IN_PROCESS 0x01 +#define ASCQ_MISCMP 0x00 +#define ASCQ_INVLD_CDB 0x00 +#define ASCQ_INVLD_PARA 0x02 +#define ASCQ_LU_NOT_READY 0x02 +#define ASCQ_WRITE_ERR 0x02 +#define ASCQ_READ_ERR 0x00 +#define ASCQ_LOAD_EJCT_ERR 0x00 +#define ASCQ_WRITE_PROTECT 0x00 + +struct sense_data_t { + unsigned char err_code; /* error code */ + /* bit7 : valid */ + /* (1 : SCSI2) */ + /* (0 : Vendor specific) */ + /* bit6-0 : error code */ + /* (0x70 : current error) */ + /* (0x71 : specific command error) */ + unsigned char seg_no; /* segment No. */ + unsigned char sense_key; /* byte5 : ILI */ + /* bit3-0 : sense key */ + unsigned char info[4]; /* infomation */ + unsigned char ad_sense_len; /* additional sense data length */ + unsigned char cmd_info[4]; /* command specific infomation */ + unsigned char asc; /* ASC */ + unsigned char ascq; /* ASCQ */ + unsigned char rfu; /* FRU */ + unsigned char sns_key_info[3]; /* sense key specific infomation */ +}; + +/* sd_ctl bit map */ +/* SD push point control, bit 0, 1 */ +#define SD_PUSH_POINT_CTL_MASK 0x03 +#define SD_PUSH_POINT_DELAY 0x01 +#define SD_PUSH_POINT_AUTO 0x02 +/* SD sample point control, bit 2, 3 */ +#define SD_SAMPLE_POINT_CTL_MASK 0x0C +#define SD_SAMPLE_POINT_DELAY 0x04 +#define SD_SAMPLE_POINT_AUTO 0x08 +/* SD DDR Tx phase set by user, bit 4 */ +#define SD_DDR_TX_PHASE_SET_BY_USER 0x10 +/* MMC DDR Tx phase set by user, bit 5 */ +#define MMC_DDR_TX_PHASE_SET_BY_USER 0x20 +/* Support MMC DDR mode, bit 6 */ +/*#define SUPPORT_MMC_DDR_MODE 0x40 */ +#define SUPPORT_UHS50_MMC44 0x40 + +struct rts51x_option { + u8 led_blink_speed; + + int mspro_formatter_enable; + + /* card clock expected by user for fpga platform */ + int fpga_sd_sdr104_clk; + int fpga_sd_ddr50_clk; + int fpga_sd_sdr50_clk; + int fpga_sd_hs_clk; + int fpga_mmc_52m_clk; + int fpga_ms_hg_clk; + int fpga_ms_4bit_clk; + + /* card clock expected by user for asic platform */ + int asic_sd_sdr104_clk; + int asic_sd_ddr50_clk; + int asic_sd_sdr50_clk; + int asic_sd_hs_clk; + int asic_mmc_52m_clk; + int asic_ms_hg_clk; + int asic_ms_4bit_clk; + + u8 ssc_depth_sd_sdr104; /* sw */ + u8 ssc_depth_sd_ddr50; /* sw */ + u8 ssc_depth_sd_sdr50; /* sw */ + u8 ssc_depth_sd_hs; /* sw */ + u8 ssc_depth_mmc_52m; /* sw */ + u8 ssc_depth_ms_hg; /* sw */ + u8 ssc_depth_ms_4bit; /* sw */ + u8 ssc_depth_low_speed; /* sw */ + + /* SD/MMC Tx phase */ + int sd_ddr_tx_phase; /* Enabled by bit 4 of sd_ctl */ + int mmc_ddr_tx_phase; /* Enabled by bit 5 of sd_ctl */ + + /* priority of choosing sd speed funciton */ + u32 sd_speed_prior; + + /* sd card control */ + u32 sd_ctl; + + /* Enable Selective Suspend */ + int ss_en; + /* Interval to enter SS from IDLE state (second) */ + int ss_delay; + int needs_remote_wakeup; + u8 ww_enable; /* sangdy2010-08-03:add for remote wakeup */ + + /* Enable SSC clock */ + int ssc_en; + + int auto_delink_en; + + /* sangdy2010-07-13:add FT2 fast mode */ + int FT2_fast_mode; + /* sangdy2010-07-15: + * add for config delay between 1/4 PMOS and 3/4 PMOS */ + int pwr_delay; + + int xd_rw_step; /* add to tune xd tRP */ + int D3318_off_delay; /* add to tune D3318 off delay time */ + int delink_delay; /* add to tune delink delay time */ + /* add for rts5129 to enable/disable D3318 off */ + u8 rts5129_D3318_off_enable; + u8 sd20_pad_drive; /* add to config SD20 PAD drive */ + u8 sd30_pad_drive; /* add to config SD30 pad drive */ + /*if reset or rw fail,then set SD20 pad drive again */ + u8 reset_or_rw_fail_set_pad_drive; + + u8 rcc_fail_flag; /* add to indicate whether rcc bug happen */ + u8 rcc_bug_fix_en; /* if set,then support fixing rcc bug */ + u8 debounce_num; /* debounce number */ + int polling_time; /* polling delay time */ + u8 led_toggle_interval; /* used to control led toggle speed */ + int xd_rwn_step; + u8 sd_send_status_en; + /* used to store default phase which is + * used when phase tune all pass. */ + u8 ddr50_tx_phase; + u8 ddr50_rx_phase; + u8 sdr50_tx_phase; + u8 sdr50_rx_phase; + /* used to enable select sdr50 tx phase according to proportion. */ + u8 sdr50_phase_sel; + u8 ms_errreg_fix; + u8 reset_mmc_first; + u8 speed_mmc; /* when set, then try CMD55 only twice */ + u8 led_always_on; /* if set, then led always on when card exist */ + u8 dv18_voltage; /* add to tune dv18 voltage */ +}; + +#define MS_FORMATTER_ENABLED(chip) ((chip)->option.mspro_formatter_enable) + +struct rts51x_chip; + +typedef int (*card_rw_func) (struct scsi_cmnd *srb, struct rts51x_chip *chip, + u32 sec_addr, u16 sec_cnt); + +/* For MS Card */ +#define MAX_DEFECTIVE_BLOCK 10 + +struct zone_entry { + u16 *l2p_table; + u16 *free_table; + u16 defect_list[MAX_DEFECTIVE_BLOCK]; /* For MS card only */ + int set_index; + int get_index; + int unused_blk_cnt; + int disable_count; + /* To indicate whether the L2P table of this zone has been built. */ + int build_flag; +}; + +struct xd_delay_write_tag { + u32 old_phyblock; + u32 new_phyblock; + u32 logblock; + u8 pageoff; + u8 delay_write_flag; +}; + +struct xd_info { + u8 maker_code; + u8 device_code; + u8 block_shift; + u8 page_off; + u8 addr_cycle; + u16 cis_block; + u8 multi_flag; + u8 err_code; + u32 capacity; + + struct zone_entry *zone; + int zone_cnt; + + struct xd_delay_write_tag delay_write; + + int counter; + + int xd_clock; +}; + +#define TYPE_SD 0x0000 +#define TYPE_MMC 0x0001 + +/* TYPE_SD */ +#define SD_HS 0x0100 +#define SD_SDR50 0x0200 +#define SD_DDR50 0x0400 +#define SD_SDR104 0x0800 +#define SD_HCXC 0x1000 + +/* TYPE_MMC */ +#define MMC_26M 0x0100 +#define MMC_52M 0x0200 +#define MMC_4BIT 0x0400 +#define MMC_8BIT 0x0800 +#define MMC_SECTOR_MODE 0x1000 +#define MMC_DDR52 0x2000 + +/* SD card */ +#define CHK_SD(sd_card) (((sd_card)->sd_type & 0xFF) == TYPE_SD) +#define CHK_SD_HS(sd_card) \ + (CHK_SD(sd_card) && ((sd_card)->sd_type & SD_HS)) +#define CHK_SD_SDR50(sd_card) \ + (CHK_SD(sd_card) && ((sd_card)->sd_type & SD_SDR50)) +#define CHK_SD_DDR50(sd_card) \ + (CHK_SD(sd_card) && ((sd_card)->sd_type & SD_DDR50)) +#define CHK_SD_SDR104(sd_card) \ + (CHK_SD(sd_card) && ((sd_card)->sd_type & SD_SDR104)) +#define CHK_SD_HCXC(sd_card) \ + (CHK_SD(sd_card) && ((sd_card)->sd_type & SD_HCXC)) +#define CHK_SD30_SPEED(sd_card) \ + (CHK_SD_SDR50(sd_card) || CHK_SD_DDR50(sd_card) ||\ + CHK_SD_SDR104(sd_card)) + +#define SET_SD(sd_card) ((sd_card)->sd_type = TYPE_SD) +#define SET_SD_HS(sd_card) ((sd_card)->sd_type |= SD_HS) +#define SET_SD_SDR50(sd_card) ((sd_card)->sd_type |= SD_SDR50) +#define SET_SD_DDR50(sd_card) ((sd_card)->sd_type |= SD_DDR50) +#define SET_SD_SDR104(sd_card) ((sd_card)->sd_type |= SD_SDR104) +#define SET_SD_HCXC(sd_card) ((sd_card)->sd_type |= SD_HCXC) + +#define CLR_SD_HS(sd_card) ((sd_card)->sd_type &= ~SD_HS) +#define CLR_SD_SDR50(sd_card) ((sd_card)->sd_type &= ~SD_SDR50) +#define CLR_SD_DDR50(sd_card) ((sd_card)->sd_type &= ~SD_DDR50) +#define CLR_SD_SDR104(sd_card) ((sd_card)->sd_type &= ~SD_SDR104) +#define CLR_SD_HCXC(sd_card) ((sd_card)->sd_type &= ~SD_HCXC) +#define CLR_SD30_SPEED(sd_card) \ + ((sd_card)->sd_type &= ~(SD_SDR50|SD_DDR50|SD_SDR104)) + +/* MMC card */ +#define CHK_MMC(sd_card) \ + (((sd_card)->sd_type & 0xFF) == TYPE_MMC) +#define CHK_MMC_26M(sd_card) \ + (CHK_MMC(sd_card) && ((sd_card)->sd_type & MMC_26M)) +#define CHK_MMC_52M(sd_card) \ + (CHK_MMC(sd_card) && ((sd_card)->sd_type & MMC_52M)) +#define CHK_MMC_4BIT(sd_card) \ + (CHK_MMC(sd_card) && ((sd_card)->sd_type & MMC_4BIT)) +#define CHK_MMC_8BIT(sd_card) \ + (CHK_MMC(sd_card) && ((sd_card)->sd_type & MMC_8BIT)) +#define CHK_MMC_SECTOR_MODE(sd_card)\ + (CHK_MMC(sd_card) && ((sd_card)->sd_type & MMC_SECTOR_MODE)) +#define CHK_MMC_DDR52(sd_card) \ + (CHK_MMC(sd_card) && ((sd_card)->sd_type & MMC_DDR52)) + +#define SET_MMC(sd_card) ((sd_card)->sd_type = TYPE_MMC) +#define SET_MMC_26M(sd_card) ((sd_card)->sd_type |= MMC_26M) +#define SET_MMC_52M(sd_card) ((sd_card)->sd_type |= MMC_52M) +#define SET_MMC_4BIT(sd_card) ((sd_card)->sd_type |= MMC_4BIT) +#define SET_MMC_8BIT(sd_card) ((sd_card)->sd_type |= MMC_8BIT) +#define SET_MMC_SECTOR_MODE(sd_card) ((sd_card)->sd_type |= MMC_SECTOR_MODE) +#define SET_MMC_DDR52(sd_card) ((sd_card)->sd_type |= MMC_DDR52) + +#define CLR_MMC_26M(sd_card) ((sd_card)->sd_type &= ~MMC_26M) +#define CLR_MMC_52M(sd_card) ((sd_card)->sd_type &= ~MMC_52M) +#define CLR_MMC_4BIT(sd_card) ((sd_card)->sd_type &= ~MMC_4BIT) +#define CLR_MMC_8BIT(sd_card) ((sd_card)->sd_type &= ~MMC_8BIT) +#define CLR_MMC_SECTOR_MODE(sd_card) ((sd_card)->sd_type &= ~MMC_SECTOR_MODE) +#define CLR_MMC_DDR52(sd_card) ((sd_card)->sd_type &= ~MMC_DDR52) + +#define CHK_MMC_HS(sd_card) \ + (CHK_MMC_52M(sd_card) && CHK_MMC_26M(sd_card)) +#define CLR_MMC_HS(sd_card) \ +do { \ + CLR_MMC_DDR52(sd_card); \ + CLR_MMC_52M(sd_card); \ + CLR_MMC_26M(sd_card); \ +} while (0) + +#define SD_SUPPORT_CLASS_TEN 0x01 +#define SD_SUPPORT_1V8 0x02 + +#define SD_SET_CLASS_TEN(sd_card) \ + ((sd_card)->sd_setting |= SD_SUPPORT_CLASS_TEN) +#define SD_CHK_CLASS_TEN(sd_card) \ + ((sd_card)->sd_setting & SD_SUPPORT_CLASS_TEN) +#define SD_CLR_CLASS_TEN(sd_card) \ + ((sd_card)->sd_setting &= ~SD_SUPPORT_CLASS_TEN) +#define SD_SET_1V8(sd_card) \ + ((sd_card)->sd_setting |= SD_SUPPORT_1V8) +#define SD_CHK_1V8(sd_card) \ + ((sd_card)->sd_setting & SD_SUPPORT_1V8) +#define SD_CLR_1V8(sd_card) \ + ((sd_card)->sd_setting &= ~SD_SUPPORT_1V8) +#define CLR_RETRY_SD20_MODE(sd_card) \ + ((sd_card)->retry_SD20_mode = 0) +#define SET_RETRY_SD20_MODE(sd_card) \ + ((sd_card)->retry_SD20_mode = 1) +#define CHK_RETRY_SD20_MODE(sd_card) \ + ((sd_card)->retry_SD20_mode == 1) + +struct sd_info { + u16 sd_type; + u8 err_code; + u8 sd_data_buf_ready; + u32 sd_addr; + u32 capacity; + + u8 raw_csd[16]; + u8 raw_scr[8]; + + /* Sequential RW */ + int seq_mode; + enum dma_data_direction pre_dir; + u32 pre_sec_addr; + u16 pre_sec_cnt; + + int counter; + + int sd_clock; + +#ifdef SUPPORT_CPRM + int sd_pass_thru_en; + int pre_cmd_err; + u8 last_rsp_type; + u8 rsp[17]; +#endif + + u8 func_group1_mask; + u8 func_group2_mask; + u8 func_group3_mask; + u8 func_group4_mask; + + u8 sd_switch_fail; + u8 sd_read_phase; + u8 retry_SD20_mode; /* sangdy2010-06-10 */ + u8 sd_reset_fail; /* sangdy2010-07-01 */ + u8 sd_send_status_en; + +#ifdef SUPPORT_SD_LOCK + u8 sd_lock_status; + u8 sd_erase_status; + u8 sd_lock_notify; +#endif +}; + +#define MODE_512_SEQ 0x01 +#define MODE_2K_SEQ 0x02 + +#define TYPE_MS 0x0000 +#define TYPE_MSPRO 0x0001 + +#define MS_4BIT 0x0100 +#define MS_8BIT 0x0200 +#define MS_HG 0x0400 +#define MS_XC 0x0800 + +#define HG8BIT (MS_HG | MS_8BIT) + +#define CHK_MSPRO(ms_card) \ + (((ms_card)->ms_type & 0xFF) == TYPE_MSPRO) +#define CHK_HG8BIT(ms_card) \ + (CHK_MSPRO(ms_card) && (((ms_card)->ms_type & HG8BIT) == HG8BIT)) +#define CHK_MSXC(ms_card) \ + (CHK_MSPRO(ms_card) && ((ms_card)->ms_type & MS_XC)) +#define CHK_MSHG(ms_card) \ + (CHK_MSPRO(ms_card) && ((ms_card)->ms_type & MS_HG)) + +#define CHK_MS8BIT(ms_card) (((ms_card)->ms_type & MS_8BIT)) +#define CHK_MS4BIT(ms_card) (((ms_card)->ms_type & MS_4BIT)) + +struct ms_delay_write_tag { + u16 old_phyblock; + u16 new_phyblock; + u16 logblock; + u8 pageoff; + u8 delay_write_flag; +}; + +struct ms_info { + u16 ms_type; + u8 block_shift; + u8 page_off; + u16 total_block; + u16 boot_block; + u32 capacity; + + u8 check_ms_flow; + u8 switch_8bit_fail; + u8 err_code; + + struct zone_entry *segment; + int segment_cnt; + + int pro_under_formatting; + int format_status; + u16 progress; + u8 raw_sys_info[96]; +#ifdef SUPPORT_PCGL_1P18 + u8 raw_model_name[48]; +#endif + + u8 multi_flag; + + /* Sequential RW */ + u8 seq_mode; + enum dma_data_direction pre_dir; + u32 pre_sec_addr; + u16 pre_sec_cnt; + u32 total_sec_cnt; + u8 last_rw_int; + + struct ms_delay_write_tag delay_write; + + int counter; + + int ms_clock; + +#ifdef SUPPORT_MAGIC_GATE + u8 magic_gate_id[16]; + u8 mg_entry_num; + int mg_auth; /* flag to indicate authentication process */ +#endif +}; + +#define PRO_UNDER_FORMATTING(ms_card) \ + ((ms_card)->pro_under_formatting) +#define SET_FORMAT_STATUS(ms_card, status) \ + ((ms_card)->format_status = (status)) +#define CHK_FORMAT_STATUS(ms_card, status) \ + ((ms_card)->format_status == (status)) + +struct scsi_cmnd; + +enum CHIP_STAT { STAT_INIT, STAT_IDLE, STAT_RUN, STAT_SS_PRE, STAT_SS, + STAT_SUSPEND }; + +struct rts51x_chip { + u16 vendor_id; + u16 product_id; + char max_lun; + + struct scsi_cmnd *srb; + struct sense_data_t sense_buffer[MAX_ALLOWED_LUN_CNT]; + +#ifndef LED_AUTO_BLINK + int led_toggle_counter; +#endif + int ss_counter; + int idle_counter; + int auto_delink_counter; + enum CHIP_STAT chip_stat; + + int resume_from_scsi; + + /* Card information */ + struct xd_info xd_card; + struct sd_info sd_card; + struct ms_info ms_card; + + int cur_clk; /* current card clock */ + int cur_card; /* Current card module */ + + u8 card_exist; /* card exist bit map (physical exist) */ + u8 card_ready; /* card ready bit map (reset successfully) */ + u8 card_fail; /* card reset fail bit map */ + u8 card_ejected; /* card ejected bit map */ + u8 card_wp; /* card write protected bit map */ + + u8 fake_card_ready; + /* flag to indicate whether to answer MediaChange */ + unsigned long lun_mc; + + /* card bus width */ + u8 card_bus_width[MAX_ALLOWED_LUN_CNT]; + /* card capacity */ + u32 capacity[MAX_ALLOWED_LUN_CNT]; + + /* read/write card function pointer */ + card_rw_func rw_card[MAX_ALLOWED_LUN_CNT]; + /* read/write capacity, used for GPIO Toggle */ + u32 rw_cap[MAX_ALLOWED_LUN_CNT]; + /* card to lun mapping table */ + u8 card2lun[32]; + /* lun to card mapping table */ + u8 lun2card[MAX_ALLOWED_LUN_CNT]; + +#ifdef _MSG_TRACE + struct trace_msg_t trace_msg[TRACE_ITEM_CNT]; + int msg_idx; +#endif + + int rw_need_retry; + + /* ASIC or FPGA */ + int asic_code; + + /* QFN24 or LQFP48 */ + int package; + + /* Full Speed or High Speed */ + int usb_speed; + + /*sangdy:enable or disable UHS50 and MMC4.4 */ + int uhs50_mmc44_en; + + u8 ic_version; + + /* Command buffer */ + u8 *cmd_buf; + unsigned int cmd_idx; + /* Response buffer */ + u8 *rsp_buf; + + u16 card_status; + +#ifdef SUPPORT_OCP + u16 ocp_stat; +#endif + + struct rts51x_option option; + struct rts51x_usb *usb; + + u8 rcc_read_response; + int reset_need_retry; + u8 rts5179; +}; + +#define UHS50_EN 0x0001 +#define UHS50_DIS 0x0000 +#define SET_UHS50(chip) ((chip)->uhs50_mmc44_en = UHS50_EN) +#define CLEAR_UHS50(chip) ((chip)->uhs50_mmc44_en = UHS50_DIS) +#define CHECK_UHS50(chip) (((chip)->uhs50_mmc44_en&0xff) == UHS50_EN) + +#define RTS51X_GET_VID(chip) ((chip)->vendor_id) +#define RTS51X_GET_PID(chip) ((chip)->product_id) + +#define RTS51X_SET_STAT(chip, stat) \ +do { \ + if ((stat) != STAT_IDLE) { \ + (chip)->idle_counter = 0; \ + } \ + (chip)->chip_stat = (enum CHIP_STAT)(stat); \ +} while (0) +#define RTS51X_CHK_STAT(chip, stat) ((chip)->chip_stat == (stat)) +#define RTS51X_GET_STAT(chip) ((chip)->chip_stat) + +#define CHECK_PID(chip, pid) (RTS51X_GET_PID(chip) == (pid)) +#define CHECK_PKG(chip, pkg) ((chip)->package == (pkg)) +#define CHECK_USB(chip, speed) ((chip)->usb_speed == (speed)) + +int rts51x_reset_chip(struct rts51x_chip *chip); +int rts51x_init_chip(struct rts51x_chip *chip); +int rts51x_release_chip(struct rts51x_chip *chip); +void rts51x_polling_func(struct rts51x_chip *chip); + +static inline void rts51x_init_cmd(struct rts51x_chip *chip) +{ + chip->cmd_idx = 0; + chip->cmd_buf[0] = 'R'; + chip->cmd_buf[1] = 'T'; + chip->cmd_buf[2] = 'C'; + chip->cmd_buf[3] = 'R'; + chip->cmd_buf[PACKET_TYPE] = BATCH_CMD; +} + +void rts51x_add_cmd(struct rts51x_chip *chip, + u8 cmd_type, u16 reg_addr, u8 mask, u8 data); +int rts51x_send_cmd(struct rts51x_chip *chip, u8 flag, int timeout); +int rts51x_get_rsp(struct rts51x_chip *chip, int rsp_len, int timeout); + +static inline void rts51x_read_rsp_buf(struct rts51x_chip *chip, int offset, + u8 *buf, int buf_len) +{ + memcpy(buf, chip->rsp_buf + offset, buf_len); +} + +static inline u8 *rts51x_get_rsp_data(struct rts51x_chip *chip) +{ + return chip->rsp_buf; +} + +int rts51x_get_card_status(struct rts51x_chip *chip, u16 * status); +int rts51x_write_register(struct rts51x_chip *chip, u16 addr, u8 mask, u8 data); +int rts51x_read_register(struct rts51x_chip *chip, u16 addr, u8 * data); +int rts51x_ep0_write_register(struct rts51x_chip *chip, u16 addr, u8 mask, + u8 data); +int rts51x_ep0_read_register(struct rts51x_chip *chip, u16 addr, u8 * data); +int rts51x_seq_write_register(struct rts51x_chip *chip, u16 addr, u16 len, + u8 *data); +int rts51x_seq_read_register(struct rts51x_chip *chip, u16 addr, u16 len, + u8 *data); +int rts51x_read_ppbuf(struct rts51x_chip *chip, u8 *buf, int buf_len); +int rts51x_write_ppbuf(struct rts51x_chip *chip, u8 *buf, int buf_len); +int rts51x_write_phy_register(struct rts51x_chip *chip, u8 addr, u8 val); +int rts51x_read_phy_register(struct rts51x_chip *chip, u8 addr, u8 *val); +void rts51x_do_before_power_down(struct rts51x_chip *chip); +void rts51x_clear_hw_error(struct rts51x_chip *chip); +void rts51x_prepare_run(struct rts51x_chip *chip); +void rts51x_trace_msg(struct rts51x_chip *chip, unsigned char *buf, int clear); +void rts51x_pp_status(struct rts51x_chip *chip, unsigned int lun, u8 *status, + u8 status_len); +void rts51x_read_status(struct rts51x_chip *chip, unsigned int lun, + u8 *rts51x_status, u8 status_len); +int rts51x_transfer_data_rcc(struct rts51x_chip *chip, unsigned int pipe, + void *buf, unsigned int len, int use_sg, + unsigned int *act_len, int timeout, u8 stage_flag); + +#define RTS51X_WRITE_REG(chip, addr, mask, data) \ +do { \ + int _retval = rts51x_write_register((chip), \ + (addr), (mask), (data)); \ + if (_retval != STATUS_SUCCESS) { \ + TRACE_RET((chip), _retval); \ + } \ +} while (0) + +#define RTS51X_READ_REG(chip, addr, data) \ +do { \ + int _retval = rts51x_read_register((chip), \ + (addr), (data)); \ + if (_retval != STATUS_SUCCESS) { \ + TRACE_RET((chip), _retval); \ + } \ +} while (0) + +#endif /* __RTS51X_CHIP_H */ diff --git a/drivers/staging/rts5139/rts51x_fop.c b/drivers/staging/rts5139/rts51x_fop.c new file mode 100644 index 0000000..6eaebb6 --- /dev/null +++ b/drivers/staging/rts5139/rts51x_fop.c @@ -0,0 +1,298 @@ +/* Driver for Realtek RTS51xx USB card reader + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + * Maintainer: + * Edwin Rong (edwin_rong@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#include "rts51x.h" + +#ifdef SUPPORT_FILE_OP + +#include <linux/types.h> +#include <linux/stat.h> +#include <linux/kref.h> +#include <linux/slab.h> + +#include "rts51x_chip.h" +#include "rts51x_card.h" +#include "rts51x_fop.h" +#include "sd_cprm.h" +#include "rts51x.h" + +#define RTS5139_IOC_MAGIC 0x39 + +#define RTS5139_IOC_SD_DIRECT _IOWR(RTS5139_IOC_MAGIC, 0xA0, int) +#define RTS5139_IOC_SD_GET_RSP _IOWR(RTS5139_IOC_MAGIC, 0xA1, int) + +static int rts51x_sd_direct_cmnd(struct rts51x_chip *chip, + struct sd_direct_cmnd *cmnd) +{ + int retval; + u8 dir, cmd12, standby, acmd, cmd_idx, rsp_code; + u8 *buf; + u32 arg, len; + + dir = (cmnd->cmnd[0] >> 3) & 0x03; + cmd12 = (cmnd->cmnd[0] >> 2) & 0x01; + standby = (cmnd->cmnd[0] >> 1) & 0x01; + acmd = cmnd->cmnd[0] & 0x01; + cmd_idx = cmnd->cmnd[1]; + arg = ((u32) (cmnd->cmnd[2]) << 24) | ((u32) (cmnd->cmnd[3]) << 16) | + ((u32) (cmnd->cmnd[4]) << 8) | cmnd->cmnd[5]; + len = + ((u32) (cmnd->cmnd[6]) << 16) | ((u32) (cmnd->cmnd[7]) << 8) | + cmnd->cmnd[8]; + rsp_code = cmnd->cmnd[9]; + + if (dir) { + if (!cmnd->buf || (cmnd->buf_len < len)) + TRACE_RET(chip, STATUS_FAIL); + } + + switch (dir) { + case 0: + /* No data */ + retval = ext_sd_execute_no_data(chip, chip->card2lun[SD_CARD], + cmd_idx, standby, acmd, + rsp_code, arg); + if (retval != TRANSPORT_GOOD) + TRACE_RET(chip, STATUS_FAIL); + break; + + case 1: + /* Read from card */ + buf = kmalloc(cmnd->buf_len, GFP_KERNEL); + if (!buf) + TRACE_RET(chip, STATUS_NOMEM); + + retval = ext_sd_execute_read_data(chip, chip->card2lun[SD_CARD], + cmd_idx, cmd12, standby, acmd, + rsp_code, arg, len, buf, + cmnd->buf_len, 0); + if (retval != TRANSPORT_GOOD) { + kfree(buf); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = + copy_to_user((void *)cmnd->buf, (void *)buf, cmnd->buf_len); + if (retval) { + kfree(buf); + TRACE_RET(chip, STATUS_NOMEM); + } + + kfree(buf); + break; + + case 2: + /* Write to card */ + buf = kmalloc(cmnd->buf_len, GFP_KERNEL); + if (!buf) + TRACE_RET(chip, STATUS_NOMEM); + + retval = + copy_from_user((void *)buf, (void *)cmnd->buf, + cmnd->buf_len); + if (retval) { + kfree(buf); + TRACE_RET(chip, STATUS_NOMEM); + } + + retval = + ext_sd_execute_write_data(chip, chip->card2lun[SD_CARD], + cmd_idx, cmd12, standby, acmd, + rsp_code, arg, len, buf, + cmnd->buf_len, 0); + if (retval != TRANSPORT_GOOD) { + kfree(buf); + TRACE_RET(chip, STATUS_FAIL); + } + + kfree(buf); + + break; + + default: + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int rts51x_sd_get_rsp(struct rts51x_chip *chip, struct sd_rsp *rsp) +{ + struct sd_info *sd_card = &(chip->sd_card); + int count = 0, retval; + + if (sd_card->pre_cmd_err) { + sd_card->pre_cmd_err = 0; + TRACE_RET(chip, STATUS_FAIL); + } + + if (sd_card->last_rsp_type == SD_RSP_TYPE_R0) + TRACE_RET(chip, STATUS_FAIL); + else if (sd_card->last_rsp_type == SD_RSP_TYPE_R2) + count = (rsp->rsp_len < 17) ? rsp->rsp_len : 17; + else + count = (rsp->rsp_len < 6) ? rsp->rsp_len : 6; + + retval = copy_to_user((void *)rsp->rsp, (void *)sd_card->rsp, count); + if (retval) + TRACE_RET(chip, STATUS_NOMEM); + + RTS51X_DEBUGP("Response length: %d\n", count); + RTS51X_DEBUGP("Response: 0x%x 0x%x 0x%x 0x%x\n", + sd_card->rsp[0], sd_card->rsp[1], sd_card->rsp[2], + sd_card->rsp[3]); + + return STATUS_SUCCESS; +} + +int rts51x_open(struct inode *inode, struct file *filp) +{ + struct rts51x_chip *chip; + struct usb_interface *interface; + int subminor; + int retval = 0; + + subminor = iminor(inode); + + interface = usb_find_interface(&rts51x_driver, subminor); + if (!interface) { + RTS51X_DEBUGP("%s - error, can't find device for minor %d\n", + __func__, subminor); + retval = -ENODEV; + goto exit; + } + + chip = (struct rts51x_chip *)usb_get_intfdata(interface); + if (!chip) { + RTS51X_DEBUGP("Can't find chip\n"); + retval = -ENODEV; + goto exit; + } + + /* Increase our reference to the host */ + scsi_host_get(rts51x_to_host(chip)); + + /* lock the device pointers */ + mutex_lock(&(chip->usb->dev_mutex)); + + /* save our object in the file's private structure */ + filp->private_data = chip; + + /* unlock the device pointers */ + mutex_unlock(&chip->usb->dev_mutex); + +exit: + return retval; +} + +int rts51x_release(struct inode *inode, struct file *filp) +{ + struct rts51x_chip *chip; + + chip = (struct rts51x_chip *)filp->private_data; + if (chip == NULL) + return -ENODEV; + + /* Drop our reference to the host; the SCSI core will free it + * (and "chip" along with it) when the refcount becomes 0. */ + scsi_host_put(rts51x_to_host(chip)); + + return 0; +} + +ssize_t rts51x_read(struct file *filp, char __user *buf, size_t count, + loff_t *f_pos) +{ + return 0; +} + +ssize_t rts51x_write(struct file *filp, const char __user *buf, size_t count, + loff_t *f_pos) +{ + return 0; +} + +#if 0 /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) */ +int rts51x_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg) +#else +long rts51x_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +#endif +{ + struct rts51x_chip *chip; + struct sd_direct_cmnd cmnd; + struct sd_rsp rsp; + int retval = 0; + + chip = (struct rts51x_chip *)filp->private_data; + if (chip == NULL) + return -ENODEV; + + /* lock the device pointers */ + mutex_lock(&(chip->usb->dev_mutex)); + + switch (cmd) { + case RTS5139_IOC_SD_DIRECT: + retval = + copy_from_user((void *)&cmnd, (void *)arg, + sizeof(struct sd_direct_cmnd)); + if (retval) { + retval = -ENOMEM; + TRACE_GOTO(chip, exit); + } + retval = rts51x_sd_direct_cmnd(chip, &cmnd); + if (retval != STATUS_SUCCESS) { + retval = -EIO; + TRACE_GOTO(chip, exit); + } + break; + + case RTS5139_IOC_SD_GET_RSP: + retval = + copy_from_user((void *)&rsp, (void *)arg, + sizeof(struct sd_rsp)); + if (retval) { + retval = -ENOMEM; + TRACE_GOTO(chip, exit); + } + retval = rts51x_sd_get_rsp(chip, &rsp); + if (retval != STATUS_SUCCESS) { + retval = -EIO; + TRACE_GOTO(chip, exit); + } + break; + + default: + break; + } + +exit: + /* unlock the device pointers */ + mutex_unlock(&chip->usb->dev_mutex); + + return retval; +} + +#endif diff --git a/drivers/staging/rts5139/rts51x_fop.h b/drivers/staging/rts5139/rts51x_fop.h new file mode 100644 index 0000000..0453f57 --- /dev/null +++ b/drivers/staging/rts5139/rts51x_fop.h @@ -0,0 +1,62 @@ +/* Driver for Realtek RTS51xx USB card reader + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + * Maintainer: + * Edwin Rong (edwin_rong@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#ifndef __RTS51X_FOP_H +#define __RTS51X_FOP_H + +#include "rts51x.h" + +#ifdef SUPPORT_FILE_OP + +#include <linux/fs.h> +#include <linux/types.h> + +struct sd_direct_cmnd { + u8 cmnd[12]; + void *buf; + int buf_len; +}; + +struct sd_rsp { + void *rsp; + int rsp_len; +}; + +int rts51x_open(struct inode *inode, struct file *filp); +int rts51x_release(struct inode *inode, struct file *filp); +ssize_t rts51x_read(struct file *filp, char __user *buf, size_t count, + loff_t *f_pos); +ssize_t rts51x_write(struct file *filp, const char __user * buf, size_t count, + loff_t *f_pos); +#if 0 /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 36) */ +int rts51x_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg); +#else +long rts51x_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); +#endif + +#endif + +#endif /* __RTS51X_FOP_H */ diff --git a/drivers/staging/rts5139/rts51x_scsi.c b/drivers/staging/rts5139/rts51x_scsi.c new file mode 100644 index 0000000..3b32f9e --- /dev/null +++ b/drivers/staging/rts5139/rts51x_scsi.c @@ -0,0 +1,2234 @@ +/* Driver for Realtek RTS51xx USB card reader + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + * Maintainer: + * Edwin Rong (edwin_rong@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#include <linux/blkdev.h> +#include <linux/kthread.h> +#include <linux/sched.h> +#include <linux/slab.h> +#include <linux/vmalloc.h> + +#include <scsi/scsi.h> +#include <scsi/scsi_eh.h> +#include <scsi/scsi_device.h> + +#include "debug.h" +#include "rts51x.h" +#include "rts51x_chip.h" +#include "rts51x_scsi.h" +#include "rts51x_card.h" +#include "rts51x_transport.h" +#include "rts51x_sys.h" +#include "sd_cprm.h" +#include "ms_mg.h" +#include "trace.h" + +void scsi_show_command(struct scsi_cmnd *srb) +{ + char *what = NULL; + int i, unknown_cmd = 0; + + switch (srb->cmnd[0]) { + case TEST_UNIT_READY: + what = (char *)"TEST_UNIT_READY"; + break; + case REZERO_UNIT: + what = (char *)"REZERO_UNIT"; + break; + case REQUEST_SENSE: + what = (char *)"REQUEST_SENSE"; + break; + case FORMAT_UNIT: + what = (char *)"FORMAT_UNIT"; + break; + case READ_BLOCK_LIMITS: + what = (char *)"READ_BLOCK_LIMITS"; + break; + case 0x07: + what = (char *)"REASSIGN_BLOCKS"; + break; + case READ_6: + what = (char *)"READ_6"; + break; + case WRITE_6: + what = (char *)"WRITE_6"; + break; + case SEEK_6: + what = (char *)"SEEK_6"; + break; + case READ_REVERSE: + what = (char *)"READ_REVERSE"; + break; + case WRITE_FILEMARKS: + what = (char *)"WRITE_FILEMARKS"; + break; + case SPACE: + what = (char *)"SPACE"; + break; + case INQUIRY: + what = (char *)"INQUIRY"; + break; + case RECOVER_BUFFERED_DATA: + what = (char *)"RECOVER_BUFFERED_DATA"; + break; + case MODE_SELECT: + what = (char *)"MODE_SELECT"; + break; + case RESERVE: + what = (char *)"RESERVE"; + break; + case RELEASE: + what = (char *)"RELEASE"; + break; + case COPY: + what = (char *)"COPY"; + break; + case ERASE: + what = (char *)"ERASE"; + break; + case MODE_SENSE: + what = (char *)"MODE_SENSE"; + break; + case START_STOP: + what = (char *)"START_STOP"; + break; + case RECEIVE_DIAGNOSTIC: + what = (char *)"RECEIVE_DIAGNOSTIC"; + break; + case SEND_DIAGNOSTIC: + what = (char *)"SEND_DIAGNOSTIC"; + break; + case ALLOW_MEDIUM_REMOVAL: + what = (char *)"ALLOW_MEDIUM_REMOVAL"; + break; + case SET_WINDOW: + what = (char *)"SET_WINDOW"; + break; + case READ_CAPACITY: + what = (char *)"READ_CAPACITY"; + break; + case READ_10: + what = (char *)"READ_10"; + break; + case WRITE_10: + what = (char *)"WRITE_10"; + break; + case SEEK_10: + what = (char *)"SEEK_10"; + break; + case WRITE_VERIFY: + what = (char *)"WRITE_VERIFY"; + break; + case VERIFY: + what = (char *)"VERIFY"; + break; + case SEARCH_HIGH: + what = (char *)"SEARCH_HIGH"; + break; + case SEARCH_EQUAL: + what = (char *)"SEARCH_EQUAL"; + break; + case SEARCH_LOW: + what = (char *)"SEARCH_LOW"; + break; + case SET_LIMITS: + what = (char *)"SET_LIMITS"; + break; + case READ_POSITION: + what = (char *)"READ_POSITION"; + break; + case SYNCHRONIZE_CACHE: + what = (char *)"SYNCHRONIZE_CACHE"; + break; + case LOCK_UNLOCK_CACHE: + what = (char *)"LOCK_UNLOCK_CACHE"; + break; + case READ_DEFECT_DATA: + what = (char *)"READ_DEFECT_DATA"; + break; + case MEDIUM_SCAN: + what = (char *)"MEDIUM_SCAN"; + break; + case COMPARE: + what = (char *)"COMPARE"; + break; + case COPY_VERIFY: + what = (char *)"COPY_VERIFY"; + break; + case WRITE_BUFFER: + what = (char *)"WRITE_BUFFER"; + break; + case READ_BUFFER: + what = (char *)"READ_BUFFER"; + break; + case UPDATE_BLOCK: + what = (char *)"UPDATE_BLOCK"; + break; + case READ_LONG: + what = (char *)"READ_LONG"; + break; + case WRITE_LONG: + what = (char *)"WRITE_LONG"; + break; + case CHANGE_DEFINITION: + what = (char *)"CHANGE_DEFINITION"; + break; + case WRITE_SAME: + what = (char *)"WRITE_SAME"; + break; + case GPCMD_READ_SUBCHANNEL: + what = (char *)"READ SUBCHANNEL"; + break; + case READ_TOC: + what = (char *)"READ_TOC"; + break; + case GPCMD_READ_HEADER: + what = (char *)"READ HEADER"; + break; + case GPCMD_PLAY_AUDIO_10: + what = (char *)"PLAY AUDIO (10)"; + break; + case GPCMD_PLAY_AUDIO_MSF: + what = (char *)"PLAY AUDIO MSF"; + break; + case GPCMD_GET_EVENT_STATUS_NOTIFICATION: + what = (char *)"GET EVENT/STATUS NOTIFICATION"; + break; + case GPCMD_PAUSE_RESUME: + what = (char *)"PAUSE/RESUME"; + break; + case LOG_SELECT: + what = (char *)"LOG_SELECT"; + break; + case LOG_SENSE: + what = (char *)"LOG_SENSE"; + break; + case GPCMD_STOP_PLAY_SCAN: + what = (char *)"STOP PLAY/SCAN"; + break; + case GPCMD_READ_DISC_INFO: + what = (char *)"READ DISC INFORMATION"; + break; + case GPCMD_READ_TRACK_RZONE_INFO: + what = (char *)"READ TRACK INFORMATION"; + break; + case GPCMD_RESERVE_RZONE_TRACK: + what = (char *)"RESERVE TRACK"; + break; + case GPCMD_SEND_OPC: + what = (char *)"SEND OPC"; + break; + case MODE_SELECT_10: + what = (char *)"MODE_SELECT_10"; + break; + case GPCMD_REPAIR_RZONE_TRACK: + what = (char *)"REPAIR TRACK"; + break; + case 0x59: + what = (char *)"READ MASTER CUE"; + break; + case MODE_SENSE_10: + what = (char *)"MODE_SENSE_10"; + break; + case GPCMD_CLOSE_TRACK: + what = (char *)"CLOSE TRACK/SESSION"; + break; + case 0x5C: + what = (char *)"READ BUFFER CAPACITY"; + break; + case 0x5D: + what = (char *)"SEND CUE SHEET"; + break; + case GPCMD_BLANK: + what = (char *)"BLANK"; + break; + case REPORT_LUNS: + what = (char *)"REPORT LUNS"; + break; + case MOVE_MEDIUM: + what = (char *)"MOVE_MEDIUM or PLAY AUDIO (12)"; + break; + case READ_12: + what = (char *)"READ_12"; + break; + case WRITE_12: + what = (char *)"WRITE_12"; + break; + case WRITE_VERIFY_12: + what = (char *)"WRITE_VERIFY_12"; + break; + case SEARCH_HIGH_12: + what = (char *)"SEARCH_HIGH_12"; + break; + case SEARCH_EQUAL_12: + what = (char *)"SEARCH_EQUAL_12"; + break; + case SEARCH_LOW_12: + what = (char *)"SEARCH_LOW_12"; + break; + case SEND_VOLUME_TAG: + what = (char *)"SEND_VOLUME_TAG"; + break; + case READ_ELEMENT_STATUS: + what = (char *)"READ_ELEMENT_STATUS"; + break; + case GPCMD_READ_CD_MSF: + what = (char *)"READ CD MSF"; + break; + case GPCMD_SCAN: + what = (char *)"SCAN"; + break; + case GPCMD_SET_SPEED: + what = (char *)"SET CD SPEED"; + break; + case GPCMD_MECHANISM_STATUS: + what = (char *)"MECHANISM STATUS"; + break; + case GPCMD_READ_CD: + what = (char *)"READ CD"; + break; + case 0xE1: + what = (char *)"WRITE CONTINUE"; + break; + case WRITE_LONG_2: + what = (char *)"WRITE_LONG_2"; + break; + case VENDOR_CMND: + what = (char *)"Realtek's vendor command"; + break; + default: + what = (char *)"(unknown command)"; + unknown_cmd = 1; + break; + } + + if (srb->cmnd[0] != TEST_UNIT_READY) + RTS51X_DEBUGP("Command %s (%d bytes)\n", what, srb->cmd_len); + if (unknown_cmd) { + RTS51X_DEBUGP(""); + for (i = 0; i < srb->cmd_len && i < 16; i++) + RTS51X_DEBUGPN(" %02x", srb->cmnd[i]); + RTS51X_DEBUGPN("\n"); + } +} + +void set_sense_type(struct rts51x_chip *chip, unsigned int lun, int sense_type) +{ + switch (sense_type) { + case SENSE_TYPE_MEDIA_CHANGE: + set_sense_data(chip, lun, CUR_ERR, 0x06, 0, 0x28, 0, 0, 0); + break; + + case SENSE_TYPE_MEDIA_NOT_PRESENT: + set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x3A, 0, 0, 0); + break; + + case SENSE_TYPE_MEDIA_LBA_OVER_RANGE: + set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x21, 0, 0, 0); + break; + + case SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT: + set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x25, 0, 0, 0); + break; + + case SENSE_TYPE_MEDIA_WRITE_PROTECT: + set_sense_data(chip, lun, CUR_ERR, 0x07, 0, 0x27, 0, 0, 0); + break; + + case SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR: + set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x11, 0, 0, 0); + break; + + case SENSE_TYPE_MEDIA_WRITE_ERR: + set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x0C, 0x02, 0, 0); + break; + + case SENSE_TYPE_MEDIA_INVALID_CMD_FIELD: + set_sense_data(chip, lun, CUR_ERR, ILGAL_REQ, 0, + ASC_INVLD_CDB, ASCQ_INVLD_CDB, CDB_ILLEGAL, 1); + break; + + case SENSE_TYPE_FORMAT_IN_PROGRESS: + set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04, 0, 0); + break; + + case SENSE_TYPE_FORMAT_CMD_FAILED: + set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x31, 0x01, 0, 0); + break; + +#ifdef SUPPORT_MAGIC_GATE + case SENSE_TYPE_MG_KEY_FAIL_NOT_ESTAB: + set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x6F, 0x02, 0, 0); + break; + + case SENSE_TYPE_MG_KEY_FAIL_NOT_AUTHEN: + set_sense_data(chip, lun, CUR_ERR, 0x05, 0, 0x6F, 0x00, 0, 0); + break; + + case SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM: + set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x30, 0x00, 0, 0); + break; + + case SENSE_TYPE_MG_WRITE_ERR: + set_sense_data(chip, lun, CUR_ERR, 0x03, 0, 0x0C, 0x00, 0, 0); + break; +#endif + +#ifdef SUPPORT_SD_LOCK + case SENSE_TYPE_MEDIA_READ_FORBIDDEN: + set_sense_data(chip, lun, CUR_ERR, 0x07, 0, 0x11, 0x13, 0, 0); + break; +#endif + + case SENSE_TYPE_NO_SENSE: + default: + set_sense_data(chip, lun, CUR_ERR, 0, 0, 0, 0, 0, 0); + break; + } +} + +void set_sense_data(struct rts51x_chip *chip, unsigned int lun, u8 err_code, + u8 sense_key, u32 info, u8 asc, u8 ascq, u8 sns_key_info0, + u16 sns_key_info1) +{ + struct sense_data_t *sense = &(chip->sense_buffer[lun]); + + sense->err_code = err_code; + sense->sense_key = sense_key; + sense->info[0] = (u8) (info >> 24); + sense->info[1] = (u8) (info >> 16); + sense->info[2] = (u8) (info >> 8); + sense->info[3] = (u8) info; + + sense->ad_sense_len = sizeof(struct sense_data_t) - 8; + sense->asc = asc; + sense->ascq = ascq; + if (sns_key_info0 != 0) { + sense->sns_key_info[0] = SKSV | sns_key_info0; + sense->sns_key_info[1] = (sns_key_info1 & 0xf0) >> 8; + sense->sns_key_info[2] = sns_key_info1 & 0x0f; + } +} + +static int test_unit_ready(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + unsigned int lun = SCSI_LUN(srb); + + rts51x_init_cards(chip); + + if (!check_card_ready(chip, lun)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + return TRANSPORT_FAILED; + } + + if (!check_lun_mc(chip, lun)) { + set_lun_mc(chip, lun); + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); + return TRANSPORT_FAILED; + } +#ifdef SUPPORT_SD_LOCK + if (get_lun_card(chip, SCSI_LUN(srb)) == SD_CARD) { + struct sd_info *sd_card = &(chip->sd_card); + if (sd_card->sd_lock_notify) { + sd_card->sd_lock_notify = 0; + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); + return TRANSPORT_FAILED; + } else if (sd_card->sd_lock_status & SD_LOCKED) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_READ_FORBIDDEN); + return TRANSPORT_FAILED; + } + } +#endif + + return TRANSPORT_GOOD; +} + +unsigned char formatter_inquiry_str[20] = { + 'M', 'E', 'M', 'O', 'R', 'Y', 'S', 'T', 'I', 'C', 'K', + '-', 'M', 'G', /* Byte[47:49] */ + 0x0B, /* Byte[50]: MG, MS, MSPro, MSXC */ + 0x00, /* Byte[51]: Category Specific Commands */ + 0x00, /* Byte[52]: Access Control and feature */ + 0x20, 0x20, 0x20, /* Byte[53:55] */ +}; + +static int inquiry(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + unsigned int lun = SCSI_LUN(srb); + char *inquiry_default = (char *)"Generic-xD/SD/M.S. 1.00 "; + char *inquiry_string; + unsigned char sendbytes; + unsigned char *buf; + u8 card = get_lun_card(chip, lun); + int pro_formatter_flag = 0; + unsigned char inquiry_buf[] = { + QULIFIRE | DRCT_ACCESS_DEV, + RMB_DISC | 0x0D, + 0x00, + 0x01, + 0x1f, + 0x02, + 0, + REL_ADR | WBUS_32 | WBUS_16 | SYNC | LINKED | CMD_QUE | SFT_RE, + }; + + inquiry_string = inquiry_default; + + buf = vmalloc(scsi_bufflen(srb)); + if (buf == NULL) + TRACE_RET(chip, TRANSPORT_ERROR); + + if (MS_FORMATTER_ENABLED(chip) && (get_lun2card(chip, lun) & MS_CARD)) { + if (!card || (card == MS_CARD)) + pro_formatter_flag = 1; + } + + if (pro_formatter_flag) { + if (scsi_bufflen(srb) < 56) + sendbytes = (unsigned char)(scsi_bufflen(srb)); + else + sendbytes = 56; + } else { + if (scsi_bufflen(srb) < 36) + sendbytes = (unsigned char)(scsi_bufflen(srb)); + else + sendbytes = 36; + } + + if (sendbytes > 8) { + memcpy(buf, inquiry_buf, 8); + memcpy(buf + 8, inquiry_string, sendbytes - 8); + if (pro_formatter_flag) + buf[4] = 0x33; /* Additional Length */ + } else { + memcpy(buf, inquiry_buf, sendbytes); + } + + if (pro_formatter_flag) { + if (sendbytes > 36) + memcpy(buf + 36, formatter_inquiry_str, sendbytes - 36); + } + + scsi_set_resid(srb, 0); + + rts51x_set_xfer_buf(buf, scsi_bufflen(srb), srb); + vfree(buf); + + return TRANSPORT_GOOD; +} + +static int start_stop_unit(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + unsigned int lun = SCSI_LUN(srb); + + scsi_set_resid(srb, scsi_bufflen(srb)); + + if (srb->cmnd[1] == 1) + return TRANSPORT_GOOD; + + switch (srb->cmnd[0x4]) { + case STOP_MEDIUM: + /* Media disabled */ + return TRANSPORT_GOOD; + + case UNLOAD_MEDIUM: + /* Media shall be unload */ + if (check_card_ready(chip, lun)) + eject_card(chip, lun); + return TRANSPORT_GOOD; + + case MAKE_MEDIUM_READY: + case LOAD_MEDIUM: + if (check_card_ready(chip, lun)) { + return TRANSPORT_GOOD; + } else { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + break; + } + + TRACE_RET(chip, TRANSPORT_ERROR); +} + +static int allow_medium_removal(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + int prevent; + + prevent = srb->cmnd[4] & 0x1; + + scsi_set_resid(srb, 0); + + if (prevent) { + set_sense_type(chip, SCSI_LUN(srb), + SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + return TRANSPORT_GOOD; +} + +static void ms_mode_sense(struct rts51x_chip *chip, u8 cmd, + int lun, u8 *buf, int buf_len) +{ + struct ms_info *ms_card = &(chip->ms_card); + int sys_info_offset; + int data_size = buf_len; + int support_format = 0; + int i = 0; + + if (cmd == MODE_SENSE) { + sys_info_offset = 8; + if (data_size > 0x68) + data_size = 0x68; + buf[i++] = 0x67; /* Mode Data Length */ + } else { + sys_info_offset = 12; + if (data_size > 0x6C) + data_size = 0x6C; + buf[i++] = 0x00; /* Mode Data Length (MSB) */ + buf[i++] = 0x6A; /* Mode Data Length (LSB) */ + } + + /* Medium Type Code */ + if (check_card_ready(chip, lun)) { + if (CHK_MSXC(ms_card)) { + support_format = 1; + buf[i++] = 0x40; + } else if (CHK_MSPRO(ms_card)) { + support_format = 1; + buf[i++] = 0x20; + } else { + buf[i++] = 0x10; + } + + /* WP */ + if (check_card_wp(chip, lun)) + buf[i++] = 0x80; + else + buf[i++] = 0x00; + } else { + buf[i++] = 0x00; /* MediaType */ + buf[i++] = 0x00; /* WP */ + } + + buf[i++] = 0x00; /* Reserved */ + + if (cmd == MODE_SENSE_10) { + buf[i++] = 0x00; /* Reserved */ + buf[i++] = 0x00; /* Block descriptor length(MSB) */ + buf[i++] = 0x00; /* Block descriptor length(LSB) */ + + /* The Following Data is the content of "Page 0x20" */ + if (data_size >= 9) + buf[i++] = 0x20; /* Page Code */ + if (data_size >= 10) + buf[i++] = 0x62; /* Page Length */ + if (data_size >= 11) + buf[i++] = 0x00; /* No Access Control */ + if (data_size >= 12) { + if (support_format) + buf[i++] = 0xC0; /* SF, SGM */ + else + buf[i++] = 0x00; + } + } else { + /* The Following Data is the content of "Page 0x20" */ + if (data_size >= 5) + buf[i++] = 0x20; /* Page Code */ + if (data_size >= 6) + buf[i++] = 0x62; /* Page Length */ + if (data_size >= 7) + buf[i++] = 0x00; /* No Access Control */ + if (data_size >= 8) { + if (support_format) + buf[i++] = 0xC0; /* SF, SGM */ + else + buf[i++] = 0x00; + } + } + + if (data_size > sys_info_offset) { + /* 96 Bytes Attribute Data */ + int len = data_size - sys_info_offset; + len = (len < 96) ? len : 96; + + memcpy(buf + sys_info_offset, ms_card->raw_sys_info, len); + } +} + +static int mode_sense(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + unsigned int lun = SCSI_LUN(srb); + unsigned int dataSize; + int status; + int pro_formatter_flag; + unsigned char pageCode, *buf; + u8 card = get_lun_card(chip, lun); + + if (!check_card_ready(chip, lun)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + scsi_set_resid(srb, scsi_bufflen(srb)); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + pro_formatter_flag = 0; + dataSize = 8; + /* In Combo mode, device responses ModeSense command as a MS LUN + * when no card is inserted */ + if ((get_lun2card(chip, lun) & MS_CARD)) { + if (!card || (card == MS_CARD)) { + dataSize = 108; + if (chip->option.mspro_formatter_enable) + pro_formatter_flag = 1; + } + } + + buf = kmalloc(dataSize, GFP_KERNEL); + if (buf == NULL) + TRACE_RET(chip, TRANSPORT_ERROR); + + pageCode = srb->cmnd[2] & 0x3f; + + if ((pageCode == 0x3F) || (pageCode == 0x1C) || + (pageCode == 0x00) || (pro_formatter_flag && (pageCode == 0x20))) { + if (srb->cmnd[0] == MODE_SENSE) { + if ((pageCode == 0x3F) || (pageCode == 0x20)) { + ms_mode_sense(chip, srb->cmnd[0], lun, buf, + dataSize); + } else { + dataSize = 4; + buf[0] = 0x03; + buf[1] = 0x00; + if (check_card_wp(chip, lun)) + buf[2] = 0x80; + else + buf[3] = 0x00; + } + } else { + if ((pageCode == 0x3F) || (pageCode == 0x20)) { + ms_mode_sense(chip, srb->cmnd[0], lun, buf, + dataSize); + } else { + dataSize = 8; + buf[0] = 0x00; + buf[1] = 0x06; + buf[2] = 0x00; + if (check_card_wp(chip, lun)) + buf[3] = 0x80; + else + buf[3] = 0x00; + buf[4] = 0x00; + buf[5] = 0x00; + buf[6] = 0x00; + buf[7] = 0x00; + } + } + status = TRANSPORT_GOOD; + } else { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + scsi_set_resid(srb, scsi_bufflen(srb)); + status = TRANSPORT_FAILED; + } + + if (status == TRANSPORT_GOOD) { + unsigned int len = min(scsi_bufflen(srb), dataSize); + rts51x_set_xfer_buf(buf, len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - len); + } + kfree(buf); + + return status; +} + +static int request_sense(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + struct sense_data_t *sense; + unsigned int lun = SCSI_LUN(srb); + struct ms_info *ms_card = &(chip->ms_card); + unsigned char *tmp, *buf; + + sense = &(chip->sense_buffer[lun]); + + if ((get_lun_card(chip, lun) == MS_CARD) + && PRO_UNDER_FORMATTING(ms_card)) { + mspro_format_sense(chip, lun); + } + + buf = vmalloc(scsi_bufflen(srb)); + if (buf == NULL) + TRACE_RET(chip, TRANSPORT_ERROR); + + tmp = (unsigned char *)sense; + memcpy(buf, tmp, scsi_bufflen(srb)); + + rts51x_set_xfer_buf(buf, scsi_bufflen(srb), srb); + vfree(buf); + + scsi_set_resid(srb, 0); + /* Reset Sense Data */ + set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); + return TRANSPORT_GOOD; +} + +static int read_write(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ +#ifdef SUPPORT_SD_LOCK + struct sd_info *sd_card = &(chip->sd_card); +#endif + unsigned int lun = SCSI_LUN(srb); + int retval; + u32 start_sec; + u16 sec_cnt; + + if (!check_card_ready(chip, lun) || (chip->capacity[lun] == 0)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (!check_lun_mc(chip, lun)) { + set_lun_mc(chip, lun); + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); + return TRANSPORT_FAILED; + } + + rts51x_prepare_run(chip); + RTS51X_SET_STAT(chip, STAT_RUN); + +#ifdef SUPPORT_SD_LOCK + if (sd_card->sd_erase_status) { + /* Accessing to any card is forbidden + * until the erase procedure of SD is completed */ + RTS51X_DEBUGP("SD card being erased!\n"); + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_READ_FORBIDDEN); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (get_lun_card(chip, lun) == SD_CARD) { + if (sd_card->sd_lock_status & SD_LOCKED) { + RTS51X_DEBUGP("SD card locked!\n"); + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_READ_FORBIDDEN); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } +#endif + + if ((srb->cmnd[0] == READ_10) || (srb->cmnd[0] == WRITE_10)) { + start_sec = + ((u32) srb->cmnd[2] << 24) | + ((u32) srb->cmnd[3] << 16) | + ((u32) srb->cmnd[4] << 8) | + ((u32) srb->cmnd[5]); + sec_cnt = ((u16) (srb->cmnd[7]) << 8) | srb->cmnd[8]; + } else if ((srb->cmnd[0] == READ_6) || (srb->cmnd[0] == WRITE_6)) { + start_sec = ((u32) (srb->cmnd[1] & 0x1F) << 16) | + ((u32) srb->cmnd[2] << 8) | ((u32) srb->cmnd[3]); + sec_cnt = srb->cmnd[4]; + } else if ((srb->cmnd[0] == VENDOR_CMND) && + (srb->cmnd[1] == SCSI_APP_CMD) && + ((srb->cmnd[2] == PP_READ10) || + (srb->cmnd[2] == PP_WRITE10))) { + start_sec = ((u32) srb->cmnd[4] << 24) | + ((u32) srb->cmnd[5] << 16) | + ((u32) srb->cmnd[6] << 8) | + ((u32) srb->cmnd[7]); + sec_cnt = ((u16) (srb->cmnd[9]) << 8) | srb->cmnd[10]; + } else { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if ((start_sec > chip->capacity[lun]) || + ((start_sec + sec_cnt) > chip->capacity[lun])) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LBA_OVER_RANGE); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (sec_cnt == 0) { + scsi_set_resid(srb, 0); + return TRANSPORT_GOOD; + } + + if ((srb->sc_data_direction == DMA_TO_DEVICE) + && check_card_wp(chip, lun)) { + RTS51X_DEBUGP("Write protected card!\n"); + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_PROTECT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + retval = card_rw(srb, chip, start_sec, sec_cnt); + if (retval != STATUS_SUCCESS) { +#if 0 + if (chip->need_release & chip->lun2card[lun]) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + } else { +#endif + if (srb->sc_data_direction == DMA_FROM_DEVICE) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + } else { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); + } +#if 0 + } +#endif + TRACE_RET(chip, TRANSPORT_FAILED); + } + + scsi_set_resid(srb, 0); + + return TRANSPORT_GOOD; +} + +static int read_format_capacity(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + unsigned char *buf; + unsigned int lun = SCSI_LUN(srb); + unsigned int buf_len; + u8 card = get_lun_card(chip, lun); + int desc_cnt; + int i = 0; + + if (!check_card_ready(chip, lun)) { + if (!chip->option.mspro_formatter_enable) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } + + buf_len = (scsi_bufflen(srb) > 12) ? 0x14 : 12; + + buf = kmalloc(buf_len, GFP_KERNEL); + if (buf == NULL) + TRACE_RET(chip, TRANSPORT_ERROR); + + buf[i++] = 0; + buf[i++] = 0; + buf[i++] = 0; + + /* Capacity List Length */ + if ((buf_len > 12) && chip->option.mspro_formatter_enable && + (chip->lun2card[lun] & MS_CARD) && (!card || (card == MS_CARD))) { + buf[i++] = 0x10; + desc_cnt = 2; + } else { + buf[i++] = 0x08; + desc_cnt = 1; + } + + while (desc_cnt) { + if (check_card_ready(chip, lun)) { + buf[i++] = (unsigned char)((chip->capacity[lun]) >> 24); + buf[i++] = (unsigned char)((chip->capacity[lun]) >> 16); + buf[i++] = (unsigned char)((chip->capacity[lun]) >> 8); + buf[i++] = (unsigned char)(chip->capacity[lun]); + + if (desc_cnt == 2) + /* Byte[8]: Descriptor Type: Formatted medium */ + buf[i++] = 2; + else + buf[i++] = 0; /* Byte[16] */ + } else { + buf[i++] = 0xFF; + buf[i++] = 0xFF; + buf[i++] = 0xFF; + buf[i++] = 0xFF; + + if (desc_cnt == 2) + /* Byte[8]: Descriptor Type: No medium */ + buf[i++] = 3; + else + buf[i++] = 0; /*Byte[16] */ + } + + buf[i++] = 0x00; + buf[i++] = 0x02; + buf[i++] = 0x00; + + desc_cnt--; + } + + buf_len = min(scsi_bufflen(srb), buf_len); + rts51x_set_xfer_buf(buf, buf_len, srb); + kfree(buf); + + scsi_set_resid(srb, scsi_bufflen(srb) - buf_len); + + return TRANSPORT_GOOD; +} + +static int read_capacity(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + unsigned char *buf; + unsigned int lun = SCSI_LUN(srb); + + if (!check_card_ready(chip, lun)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (!check_lun_mc(chip, lun)) { + set_lun_mc(chip, lun); + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); + return TRANSPORT_FAILED; + } + + buf = kmalloc(8, GFP_KERNEL); + if (buf == NULL) + TRACE_RET(chip, TRANSPORT_ERROR); + + buf[0] = (unsigned char)((chip->capacity[lun] - 1) >> 24); + buf[1] = (unsigned char)((chip->capacity[lun] - 1) >> 16); + buf[2] = (unsigned char)((chip->capacity[lun] - 1) >> 8); + buf[3] = (unsigned char)(chip->capacity[lun] - 1); + + buf[4] = 0x00; + buf[5] = 0x00; + buf[6] = 0x02; + buf[7] = 0x00; + + rts51x_set_xfer_buf(buf, scsi_bufflen(srb), srb); + kfree(buf); + + scsi_set_resid(srb, 0); + + return TRANSPORT_GOOD; +} + +static int get_dev_status(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + unsigned int lun = SCSI_LUN(srb); + unsigned int buf_len; + u8 status[32] = { 0 }; + + rts51x_pp_status(chip, lun, status, 32); + + buf_len = min(scsi_bufflen(srb), (unsigned int)sizeof(status)); + rts51x_set_xfer_buf(status, buf_len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - buf_len); + + return TRANSPORT_GOOD; +} + +static int read_status(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + u8 rts51x_status[16]; + unsigned int buf_len; + unsigned int lun = SCSI_LUN(srb); + + rts51x_read_status(chip, lun, rts51x_status, 16); + + buf_len = min(scsi_bufflen(srb), (unsigned int)sizeof(rts51x_status)); + rts51x_set_xfer_buf(rts51x_status, buf_len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - buf_len); + + return TRANSPORT_GOOD; +} + +static int read_mem(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + unsigned int lun = SCSI_LUN(srb); + unsigned short addr, len, i; + int retval; + u8 *buf; + + rts51x_prepare_run(chip); + RTS51X_SET_STAT(chip, STAT_RUN); + + addr = ((u16) srb->cmnd[2] << 8) | srb->cmnd[3]; + len = ((u16) srb->cmnd[4] << 8) | srb->cmnd[5]; + + if (addr < 0xe000) { + RTS51X_DEBUGP("filter!addr=0x%x\n", addr); + return TRANSPORT_GOOD; + } + + buf = vmalloc(len); + if (!buf) + TRACE_RET(chip, TRANSPORT_ERROR); + + for (i = 0; i < len; i++) { + retval = rts51x_ep0_read_register(chip, addr + i, buf + i); + if (retval != STATUS_SUCCESS) { + vfree(buf); + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } + + len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len); + rts51x_set_xfer_buf(buf, len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - len); + + vfree(buf); + + return TRANSPORT_GOOD; +} + +static int write_mem(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + unsigned int lun = SCSI_LUN(srb); + unsigned short addr, len, i; + int retval; + u8 *buf; + + rts51x_prepare_run(chip); + RTS51X_SET_STAT(chip, STAT_RUN); + + addr = ((u16) srb->cmnd[2] << 8) | srb->cmnd[3]; + len = ((u16) srb->cmnd[4] << 8) | srb->cmnd[5]; + + if (addr < 0xe000) { + RTS51X_DEBUGP("filter!addr=0x%x\n", addr); + return TRANSPORT_GOOD; + } + + len = (unsigned short)min(scsi_bufflen(srb), (unsigned int)len); + buf = vmalloc(len); + if (!buf) + TRACE_RET(chip, TRANSPORT_ERROR); + + rts51x_get_xfer_buf(buf, len, srb); + + for (i = 0; i < len; i++) { + retval = + rts51x_ep0_write_register(chip, addr + i, 0xFF, buf[i]); + if (retval != STATUS_SUCCESS) { + vfree(buf); + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } + + vfree(buf); + scsi_set_resid(srb, scsi_bufflen(srb) - len); + + return TRANSPORT_GOOD; +} + +static int get_sd_csd(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + unsigned int lun = SCSI_LUN(srb); + + if (!check_card_ready(chip, lun)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (get_lun_card(chip, lun) != SD_CARD) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + scsi_set_resid(srb, 0); + rts51x_set_xfer_buf(sd_card->raw_csd, scsi_bufflen(srb), srb); + + return TRANSPORT_GOOD; +} + +static int read_phy_register(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + int retval; + u8 addr, len, i; + u8 *buf; + + rts51x_prepare_run(chip); + RTS51X_SET_STAT(chip, STAT_RUN); + + addr = srb->cmnd[5]; + len = srb->cmnd[7]; + + if (len) { + buf = vmalloc(len); + if (!buf) + TRACE_RET(chip, TRANSPORT_ERROR); + + for (i = 0; i < len; i++) { + retval = + rts51x_read_phy_register(chip, addr + i, buf + i); + if (retval != STATUS_SUCCESS) { + vfree(buf); + set_sense_type(chip, SCSI_LUN(srb), + SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } + + len = min(scsi_bufflen(srb), (unsigned int)len); + rts51x_set_xfer_buf(buf, len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - len); + + vfree(buf); + } + + return TRANSPORT_GOOD; +} + +static int write_phy_register(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + int retval; + u8 addr, len, i; + u8 *buf; + + rts51x_prepare_run(chip); + RTS51X_SET_STAT(chip, STAT_RUN); + + addr = srb->cmnd[5]; + len = srb->cmnd[7]; + + if (len) { + len = min(scsi_bufflen(srb), (unsigned int)len); + + buf = vmalloc(len); + if (buf == NULL) + TRACE_RET(chip, TRANSPORT_ERROR); + + rts51x_get_xfer_buf(buf, len, srb); + scsi_set_resid(srb, scsi_bufflen(srb) - len); + + for (i = 0; i < len; i++) { + retval = + rts51x_write_phy_register(chip, addr + i, buf[i]); + if (retval != STATUS_SUCCESS) { + vfree(buf); + set_sense_type(chip, SCSI_LUN(srb), + SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } + + vfree(buf); + } + + return TRANSPORT_GOOD; +} + +static int get_card_bus_width(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + unsigned int lun = SCSI_LUN(srb); + u8 card, bus_width; + + if (!check_card_ready(chip, lun)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + card = get_lun_card(chip, lun); + if ((card == SD_CARD) || (card == MS_CARD)) { + bus_width = chip->card_bus_width[lun]; + } else { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + scsi_set_resid(srb, 0); + rts51x_set_xfer_buf(&bus_width, scsi_bufflen(srb), srb); + + return TRANSPORT_GOOD; +} + +#ifdef _MSG_TRACE +static int trace_msg_cmd(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + unsigned char *buf = NULL; + u8 clear; + unsigned int buf_len; + + buf_len = + 4 + + ((2 + MSG_FUNC_LEN + MSG_FILE_LEN + TIME_VAL_LEN) * TRACE_ITEM_CNT); + + if ((scsi_bufflen(srb) < buf_len) || (scsi_sglist(srb) == NULL)) { + set_sense_type(chip, SCSI_LUN(srb), + SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + clear = srb->cmnd[2]; + + buf = vmalloc(scsi_bufflen(srb)); + if (buf == NULL) + TRACE_RET(chip, TRANSPORT_ERROR); + + rts51x_trace_msg(chip, buf, clear); + + rts51x_set_xfer_buf(buf, scsi_bufflen(srb), srb); + vfree(buf); + + scsi_set_resid(srb, 0); + return TRANSPORT_GOOD; +} +#endif + +static int rw_mem_cmd_buf(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + int retval = STATUS_SUCCESS; + unsigned int lun = SCSI_LUN(srb); + u8 cmd_type, mask, value, idx, mode, len; + u16 addr; + u32 timeout; + + rts51x_prepare_run(chip); + RTS51X_SET_STAT(chip, STAT_RUN); + + switch (srb->cmnd[3]) { + case INIT_BATCHCMD: + rts51x_init_cmd(chip); + break; + + case ADD_BATCHCMD: + cmd_type = srb->cmnd[4]; + if (cmd_type > 2) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + addr = (srb->cmnd[5] << 8) | srb->cmnd[6]; + mask = srb->cmnd[7]; + value = srb->cmnd[8]; + rts51x_add_cmd(chip, cmd_type, addr, mask, value); + break; + + case SEND_BATCHCMD: + mode = srb->cmnd[4]; + len = srb->cmnd[5]; + timeout = + ((u32) srb->cmnd[6] << 24) | ((u32) srb-> + cmnd[7] << 16) | ((u32) srb-> + cmnd[8] << + 8) | ((u32) + srb-> + cmnd + [9]); + retval = rts51x_send_cmd(chip, mode, 1000); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + if (mode & STAGE_R) { + retval = rts51x_get_rsp(chip, len, timeout); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } + break; + + case GET_BATCHRSP: + idx = srb->cmnd[4]; + value = chip->rsp_buf[idx]; + if (scsi_bufflen(srb) < 1) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + rts51x_set_xfer_buf(&value, 1, srb); + scsi_set_resid(srb, 0); + break; + + default: + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + return TRANSPORT_GOOD; +} + +static int suit_cmd(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + int result; + + switch (srb->cmnd[3]) { + case INIT_BATCHCMD: + case ADD_BATCHCMD: + case SEND_BATCHCMD: + case GET_BATCHRSP: + result = rw_mem_cmd_buf(srb, chip); + break; + default: + result = TRANSPORT_ERROR; + } + + return result; +} + +static int app_cmd(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + int result; + + switch (srb->cmnd[2]) { + case PP_READ10: + case PP_WRITE10: + result = read_write(srb, chip); + break; + + case SUIT_CMD: + result = suit_cmd(srb, chip); + break; + + case READ_PHY: + result = read_phy_register(srb, chip); + break; + + case WRITE_PHY: + result = write_phy_register(srb, chip); + break; + + case GET_DEV_STATUS: + result = get_dev_status(srb, chip); + break; + + default: + set_sense_type(chip, SCSI_LUN(srb), + SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + return result; +} + +static int vendor_cmnd(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + int result = TRANSPORT_GOOD; + + switch (srb->cmnd[1]) { + case READ_STATUS: + result = read_status(srb, chip); + break; + + case READ_MEM: + result = read_mem(srb, chip); + break; + + case WRITE_MEM: + result = write_mem(srb, chip); + break; + + case GET_BUS_WIDTH: + result = get_card_bus_width(srb, chip); + break; + + case GET_SD_CSD: + result = get_sd_csd(srb, chip); + break; + +#ifdef _MSG_TRACE + case TRACE_MSG: + result = trace_msg_cmd(srb, chip); + break; +#endif + + case SCSI_APP_CMD: + result = app_cmd(srb, chip); + break; + + default: + set_sense_type(chip, SCSI_LUN(srb), + SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + return result; +} + +static int ms_format_cmnd(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + unsigned int lun = SCSI_LUN(srb); + int retval, quick_format; + + if (get_lun_card(chip, lun) != MS_CARD) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if ((srb->cmnd[3] != 0x4D) || (srb->cmnd[4] != 0x47) + || (srb->cmnd[5] != 0x66) || (srb->cmnd[6] != 0x6D) + || (srb->cmnd[7] != 0x74)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (srb->cmnd[8] & 0x01) + quick_format = 0; + else + quick_format = 1; + + if (!(chip->card_ready & MS_CARD)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (chip->card_wp & MS_CARD) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_PROTECT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (!CHK_MSPRO(ms_card)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + rts51x_prepare_run(chip); + RTS51X_SET_STAT(chip, STAT_RUN); + + retval = mspro_format(srb, chip, MS_SHORT_DATA_LEN, quick_format); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_FORMAT_CMD_FAILED); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + scsi_set_resid(srb, 0); + return TRANSPORT_GOOD; +} + +#ifdef SUPPORT_PCGL_1P18 +int get_ms_information(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + unsigned int lun = SCSI_LUN(srb); + u8 dev_info_id, data_len; + u8 *buf; + unsigned int buf_len; + int i; + + if (!check_card_ready(chip, lun)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + if ((get_lun_card(chip, lun) != MS_CARD)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if ((srb->cmnd[2] != 0xB0) || (srb->cmnd[4] != 0x4D) || + (srb->cmnd[5] != 0x53) || (srb->cmnd[6] != 0x49) || + (srb->cmnd[7] != 0x44)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + dev_info_id = srb->cmnd[3]; + if ((CHK_MSXC(ms_card) && (dev_info_id == 0x10)) || + (!CHK_MSXC(ms_card) && (dev_info_id == 0x13)) || + !CHK_MSPRO(ms_card)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (dev_info_id == 0x15) + buf_len = data_len = 0x3A; + else + buf_len = data_len = 0x6A; + + buf = kmalloc(buf_len, GFP_KERNEL); + if (!buf) + TRACE_RET(chip, TRANSPORT_ERROR); + + i = 0; + /* GET Memory Stick Media Information Response Header */ + buf[i++] = 0x00; /* Data length MSB */ + buf[i++] = data_len; /* Data length LSB */ + /* Device Information Type Code */ + if (CHK_MSXC(ms_card)) + buf[i++] = 0x03; + else + buf[i++] = 0x02; + /* SGM bit */ + buf[i++] = 0x01; + /* Reserved */ + buf[i++] = 0x00; + buf[i++] = 0x00; + buf[i++] = 0x00; + /* Number of Device Information */ + buf[i++] = 0x01; + + /* Device Information Body + * Device Information ID Number */ + buf[i++] = dev_info_id; + /* Device Information Length */ + if (dev_info_id == 0x15) + data_len = 0x31; + else + data_len = 0x61; + buf[i++] = 0x00; /* Data length MSB */ + buf[i++] = data_len; /* Data length LSB */ + /* Valid Bit */ + buf[i++] = 0x80; + if ((dev_info_id == 0x10) || (dev_info_id == 0x13)) { + /* System Information */ + memcpy(buf + i, ms_card->raw_sys_info, 96); + } else { + /* Model Name */ + memcpy(buf + i, ms_card->raw_model_name, 48); + } + + rts51x_set_xfer_buf(buf, buf_len, srb); + + if (dev_info_id == 0x15) + scsi_set_resid(srb, scsi_bufflen(srb) - 0x3C); + else + scsi_set_resid(srb, scsi_bufflen(srb) - 0x6C); + + kfree(buf); + return STATUS_SUCCESS; +} +#endif + +static int ms_sp_cmnd(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + int retval = TRANSPORT_ERROR; + + if (srb->cmnd[2] == MS_FORMAT) + retval = ms_format_cmnd(srb, chip); +#ifdef SUPPORT_PCGL_1P18 + else if (srb->cmnd[2] == GET_MS_INFORMATION) + retval = get_ms_information(srb, chip); +#endif + + return retval; +} + +#ifdef SUPPORT_CPRM +static int sd_extention_cmnd(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + unsigned int lun = SCSI_LUN(srb); + int result; + + rts51x_prepare_run(chip); + RTS51X_SET_STAT(chip, STAT_RUN); + + sd_cleanup_work(chip); + + if (!check_card_ready(chip, lun)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + if ((get_lun_card(chip, lun) != SD_CARD)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + switch (srb->cmnd[0]) { + case SD_PASS_THRU_MODE: + result = sd_pass_thru_mode(srb, chip); + break; + + case SD_EXECUTE_NO_DATA: + result = sd_execute_no_data(srb, chip); + break; + + case SD_EXECUTE_READ: + result = sd_execute_read_data(srb, chip); + break; + + case SD_EXECUTE_WRITE: + result = sd_execute_write_data(srb, chip); + break; + + case SD_GET_RSP: + result = sd_get_cmd_rsp(srb, chip); + break; + + case SD_HW_RST: + result = sd_hw_rst(srb, chip); + break; + + default: + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + return result; +} +#endif + +#ifdef SUPPORT_MAGIC_GATE +int mg_report_key(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + unsigned int lun = SCSI_LUN(srb); + int retval; + u8 key_format; + + rts51x_prepare_run(chip); + RTS51X_SET_STAT(chip, STAT_RUN); + + ms_cleanup_work(chip); + + if (!check_card_ready(chip, lun)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + if ((get_lun_card(chip, lun) != MS_CARD)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (srb->cmnd[7] != KC_MG_R_PRO) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (!CHK_MSPRO(ms_card)) { + set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + key_format = srb->cmnd[10] & 0x3F; + + switch (key_format) { + case KF_GET_LOC_EKB: + if ((scsi_bufflen(srb) == 0x41C) && + (srb->cmnd[8] == 0x04) && (srb->cmnd[9] == 0x1C)) { + retval = mg_get_local_EKB(srb, chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); + } else { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + break; + + case KF_RSP_CHG: + if ((scsi_bufflen(srb) == 0x24) && + (srb->cmnd[8] == 0x00) && (srb->cmnd[9] == 0x24)) { + retval = mg_get_rsp_chg(srb, chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); + } else { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + break; + + case KF_GET_ICV: + ms_card->mg_entry_num = srb->cmnd[5]; + if ((scsi_bufflen(srb) == 0x404) && + (srb->cmnd[8] == 0x04) && + (srb->cmnd[9] == 0x04) && + (srb->cmnd[2] == 0x00) && + (srb->cmnd[3] == 0x00) && + (srb->cmnd[4] == 0x00) && (srb->cmnd[5] < 32)) { + retval = mg_get_ICV(srb, chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); + } else { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + break; + + default: + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + scsi_set_resid(srb, 0); + return TRANSPORT_GOOD; +} + +int mg_send_key(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + struct ms_info *ms_card = &(chip->ms_card); + unsigned int lun = SCSI_LUN(srb); + int retval; + u8 key_format; + + rts51x_prepare_run(chip); + RTS51X_SET_STAT(chip, STAT_RUN); + + ms_cleanup_work(chip); + + if (!check_card_ready(chip, lun)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + if (check_card_wp(chip, lun)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_PROTECT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + if ((get_lun_card(chip, lun) != MS_CARD)) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_LUN_NOT_SUPPORT); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (srb->cmnd[7] != KC_MG_R_PRO) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (!CHK_MSPRO(ms_card)) { + set_sense_type(chip, lun, SENSE_TYPE_MG_INCOMPATIBLE_MEDIUM); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + key_format = srb->cmnd[10] & 0x3F; + + switch (key_format) { + case KF_SET_LEAF_ID: + if ((scsi_bufflen(srb) == 0x0C) && + (srb->cmnd[8] == 0x00) && (srb->cmnd[9] == 0x0C)) { + retval = mg_set_leaf_id(srb, chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); + } else { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + break; + + case KF_CHG_HOST: + if ((scsi_bufflen(srb) == 0x0C) && + (srb->cmnd[8] == 0x00) && (srb->cmnd[9] == 0x0C)) { + retval = mg_chg(srb, chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); + } else { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + break; + + case KF_RSP_HOST: + if ((scsi_bufflen(srb) == 0x0C) && + (srb->cmnd[8] == 0x00) && (srb->cmnd[9] == 0x0C)) { + retval = mg_rsp(srb, chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); + } else { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + break; + + case KF_SET_ICV: + ms_card->mg_entry_num = srb->cmnd[5]; + if ((scsi_bufflen(srb) == 0x404) && + (srb->cmnd[8] == 0x04) && + (srb->cmnd[9] == 0x04) && + (srb->cmnd[2] == 0x00) && + (srb->cmnd[3] == 0x00) && + (srb->cmnd[4] == 0x00) && (srb->cmnd[5] < 32)) { + retval = mg_set_ICV(srb, chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); + } else { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + break; + + default: + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + scsi_set_resid(srb, 0); + return TRANSPORT_GOOD; +} +#endif + +int rts51x_scsi_handler(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ +#ifdef SUPPORT_SD_LOCK + struct sd_info *sd_card = &(chip->sd_card); +#endif + struct ms_info *ms_card = &(chip->ms_card); + unsigned int lun = SCSI_LUN(srb); + int result = TRANSPORT_GOOD; + +#ifdef SUPPORT_SD_LOCK + if (sd_card->sd_erase_status) { + /* Block all SCSI command except for REQUEST_SENSE + * and rs_ppstatus */ + if (! + ((srb->cmnd[0] == VENDOR_CMND) + && (srb->cmnd[1] == SCSI_APP_CMD) + && (srb->cmnd[2] == GET_DEV_STATUS)) + && (srb->cmnd[0] != REQUEST_SENSE)) { + /* Logical Unit Not Ready Format in Progress */ + set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04, + 0, 0); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } +#endif + + if ((get_lun_card(chip, lun) == MS_CARD) && + (ms_card->format_status == FORMAT_IN_PROGRESS)) { + if ((srb->cmnd[0] != REQUEST_SENSE) + && (srb->cmnd[0] != INQUIRY)) { + /* Logical Unit Not Ready Format in Progress */ + set_sense_data(chip, lun, CUR_ERR, 0x02, 0, 0x04, 0x04, + 0, (u16) (ms_card->progress)); + TRACE_RET(chip, TRANSPORT_FAILED); + } + } + + switch (srb->cmnd[0]) { + case READ_10: + case WRITE_10: + case READ_6: + case WRITE_6: + result = read_write(srb, chip); + break; + + case TEST_UNIT_READY: + result = test_unit_ready(srb, chip); + break; + + case INQUIRY: + result = inquiry(srb, chip); + break; + + case READ_CAPACITY: + result = read_capacity(srb, chip); + break; + + case START_STOP: + result = start_stop_unit(srb, chip); + break; + + case ALLOW_MEDIUM_REMOVAL: + result = allow_medium_removal(srb, chip); + break; + + case REQUEST_SENSE: + result = request_sense(srb, chip); + break; + + case MODE_SENSE: + case MODE_SENSE_10: + result = mode_sense(srb, chip); + break; + + case 0x23: + result = read_format_capacity(srb, chip); + break; + + case VENDOR_CMND: + result = vendor_cmnd(srb, chip); + break; + + case MS_SP_CMND: + result = ms_sp_cmnd(srb, chip); + break; + +#ifdef SUPPORT_CPRM + case SD_PASS_THRU_MODE: + case SD_EXECUTE_NO_DATA: + case SD_EXECUTE_READ: + case SD_EXECUTE_WRITE: + case SD_GET_RSP: + case SD_HW_RST: + result = sd_extention_cmnd(srb, chip); + break; +#endif + +#ifdef SUPPORT_MAGIC_GATE + case CMD_MSPRO_MG_RKEY: + result = mg_report_key(srb, chip); + break; + + case CMD_MSPRO_MG_SKEY: + result = mg_send_key(srb, chip); + break; +#endif + + case FORMAT_UNIT: + case MODE_SELECT: + case VERIFY: + result = TRANSPORT_GOOD; + break; + + default: + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + result = TRANSPORT_FAILED; + } + + return result; +} + +/*********************************************************************** + * Host functions + ***********************************************************************/ + +const char *host_info(struct Scsi_Host *host) +{ + return "SCSI emulation for RTS51xx USB driver-based card reader"; +} + +int slave_alloc(struct scsi_device *sdev) +{ + /* + * Set the INQUIRY transfer length to 36. We don't use any of + * the extra data and many devices choke if asked for more or + * less than 36 bytes. + */ + sdev->inquiry_len = 36; + return 0; +} + +int slave_configure(struct scsi_device *sdev) +{ + /* Scatter-gather buffers (all but the last) must have a length + * divisible by the bulk maxpacket size. Otherwise a data packet + * would end up being short, causing a premature end to the data + * transfer. Since high-speed bulk pipes have a maxpacket size + * of 512, we'll use that as the scsi device queue's DMA alignment + * mask. Guaranteeing proper alignment of the first buffer will + * have the desired effect because, except at the beginning and + * the end, scatter-gather buffers follow page boundaries. */ + blk_queue_dma_alignment(sdev->request_queue, (512 - 1)); + + /* Set the SCSI level to at least 2. We'll leave it at 3 if that's + * what is originally reported. We need this to avoid confusing + * the SCSI layer with devices that report 0 or 1, but need 10-byte + * commands (ala ATAPI devices behind certain bridges, or devices + * which simply have broken INQUIRY data). + * + * NOTE: This means /dev/sg programs (ala cdrecord) will get the + * actual information. This seems to be the preference for + * programs like that. + * + * NOTE: This also means that /proc/scsi/scsi and sysfs may report + * the actual value or the modified one, depending on where the + * data comes from. + */ + if (sdev->scsi_level < SCSI_2) + sdev->scsi_level = sdev->sdev_target->scsi_level = SCSI_2; + + return 0; +} + +/*********************************************************************** + * /proc/scsi/ functions + ***********************************************************************/ + +/* we use this macro to help us write into the buffer */ +#undef SPRINTF +#define SPRINTF(args...) \ + do { if (pos < buffer+length) pos += sprintf(pos, ## args); } while (0) + +int proc_info(struct Scsi_Host *host, char *buffer, + char **start, off_t offset, int length, int inout) +{ + char *pos = buffer; + + /* if someone is sending us data, just throw it away */ + if (inout) + return length; + + /* print the controller name */ + SPRINTF(" Host scsi%d: %s\n", host->host_no, RTS51X_NAME); + + /* print product, vendor, and driver version strings */ + SPRINTF(" Vendor: Realtek Corp.\n"); + SPRINTF(" Product: RTS51xx USB Card Reader\n"); + SPRINTF(" Version: %s\n", DRIVER_VERSION); + SPRINTF(" Build: %s\n", __TIME__); + + /* + * Calculate start of next buffer, and return value. + */ + *start = buffer + offset; + + if ((pos - buffer) < offset) + return 0; + else if ((pos - buffer - offset) < length) + return pos - buffer - offset; + else + return length; +} + +/* queue a command */ +/* This is always called with scsi_lock(host) held */ +int queuecommand_lck(struct scsi_cmnd *srb, void (*done) (struct scsi_cmnd *)) +{ + struct rts51x_chip *chip = host_to_rts51x(srb->device->host); + + /* check for state-transition errors */ + if (chip->srb != NULL) { + RTS51X_DEBUGP("Error in %s: chip->srb = %p\n", + __func__, chip->srb); + return SCSI_MLQUEUE_HOST_BUSY; + } + + /* fail the command if we are disconnecting */ + if (test_bit(FLIDX_DISCONNECTING, &chip->usb->dflags)) { + RTS51X_DEBUGP("Fail command during disconnect\n"); + srb->result = DID_NO_CONNECT << 16; + done(srb); + return 0; + } + + /* enqueue the command and wake up the control thread */ + srb->scsi_done = done; + chip->srb = srb; + complete(&chip->usb->cmnd_ready); + + return 0; +} + +#if 0 /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37) */ +int queuecommand(struct scsi_cmnd *srb, void (*done) (struct scsi_cmnd *)) +{ + return queuecommand_lck(srb, done); +} +#else +DEF_SCSI_QCMD(queuecommand) +#endif +/*********************************************************************** + * Error handling functions + ***********************************************************************/ +/* Command timeout and abort */ +int command_abort(struct scsi_cmnd *srb) +{ + struct rts51x_chip *chip = host_to_rts51x(srb->device->host); + + RTS51X_DEBUGP("%s called\n", __func__); + + /* us->srb together with the TIMED_OUT, RESETTING, and ABORTING + * bits are protected by the host lock. */ + scsi_lock(rts51x_to_host(chip)); + + /* Is this command still active? */ + if (chip->srb != srb) { + scsi_unlock(rts51x_to_host(chip)); + RTS51X_DEBUGP("-- nothing to abort\n"); + return FAILED; + } + + /* Set the TIMED_OUT bit. Also set the ABORTING bit, but only if + * a device reset isn't already in progress (to avoid interfering + * with the reset). Note that we must retain the host lock while + * calling usb_stor_stop_transport(); otherwise it might interfere + * with an auto-reset that begins as soon as we release the lock. */ + set_bit(FLIDX_TIMED_OUT, &chip->usb->dflags); + if (!test_bit(FLIDX_RESETTING, &chip->usb->dflags)) { + set_bit(FLIDX_ABORTING, &chip->usb->dflags); + /* rts51x_stop_transport(us); */ + } + scsi_unlock(rts51x_to_host(chip)); + + /* Wait for the aborted command to finish */ + wait_for_completion(&chip->usb->notify); + return SUCCESS; +} + +/* This invokes the transport reset mechanism to reset the state of the + * device */ +int device_reset(struct scsi_cmnd *srb) +{ + int result = 0; + + RTS51X_DEBUGP("%s called\n", __func__); + + return result < 0 ? FAILED : SUCCESS; +} + +/* Simulate a SCSI bus reset by resetting the device's USB port. */ +int bus_reset(struct scsi_cmnd *srb) +{ + int result = 0; + + RTS51X_DEBUGP("%s called\n", __func__); + + return result < 0 ? FAILED : SUCCESS; +} + +static const char *rts5139_info(struct Scsi_Host *host) +{ + return "SCSI emulation for RTS5139 USB card reader"; +} + +struct scsi_host_template rts51x_host_template = { + /* basic userland interface stuff */ + .name = RTS51X_NAME, + .proc_name = RTS51X_NAME, + .proc_info = proc_info, + .info = rts5139_info, + + /* command interface -- queued only */ + .queuecommand = queuecommand, + + /* error and abort handlers */ + .eh_abort_handler = command_abort, + .eh_device_reset_handler = device_reset, + .eh_bus_reset_handler = bus_reset, + + /* queue commands only, only one command per LUN */ + .can_queue = 1, + .cmd_per_lun = 1, + + /* unknown initiator id */ + .this_id = -1, + + .slave_alloc = slave_alloc, + .slave_configure = slave_configure, + + /* lots of sg segments can be handled */ + .sg_tablesize = SG_ALL, + + /* limit the total size of a transfer to 120 KB */ + .max_sectors = 240, + + /* merge commands... this seems to help performance, but + * periodically someone should test to see which setting is more + * optimal. + */ + .use_clustering = 1, + + /* emulated HBA */ + .emulated = 1, + + /* we do our own delay after a device or bus reset */ + .skip_settle_delay = 1, + + /* sysfs device attributes */ + /* .sdev_attrs = sysfs_device_attr_list, */ + + /* module management */ + .module = THIS_MODULE +}; + diff --git a/drivers/staging/rts5139/rts51x_scsi.h b/drivers/staging/rts5139/rts51x_scsi.h new file mode 100644 index 0000000..3a8ca06 --- /dev/null +++ b/drivers/staging/rts5139/rts51x_scsi.h @@ -0,0 +1,162 @@ +/* Driver for Realtek RTS51xx USB card reader + * Header file + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + * Maintainer: + * Edwin Rong (edwin_rong@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#ifndef __RTS51X_SCSI_H +#define __RTS51X_SCSI_H + +#include <linux/usb.h> +#include <linux/usb_usual.h> +#include <linux/blkdev.h> +#include <linux/completion.h> +#include <linux/mutex.h> +#include <scsi/scsi_host.h> + +#include "rts51x_chip.h" + +#define MS_SP_CMND 0xFA +#define MS_FORMAT 0xA0 +#define GET_MS_INFORMATION 0xB0 + +#define VENDOR_CMND 0xF0 + +#define READ_STATUS 0x09 + +#define READ_MEM 0x0D +#define WRITE_MEM 0x0E +#define GET_BUS_WIDTH 0x13 +#define GET_SD_CSD 0x14 +#define TOGGLE_GPIO 0x15 +#define TRACE_MSG 0x18 + +#define SCSI_APP_CMD 0x10 + +#define PP_READ10 0x1A +#define PP_WRITE10 0x0A +#define READ_HOST_REG 0x1D +#define WRITE_HOST_REG 0x0D +#define SET_VAR 0x05 +#define GET_VAR 0x15 +#define DMA_READ 0x16 +#define DMA_WRITE 0x06 +#define GET_DEV_STATUS 0x10 +#define SET_CHIP_MODE 0x27 +#define SUIT_CMD 0xE0 +#define WRITE_PHY 0x07 +#define READ_PHY 0x17 + +#define INIT_BATCHCMD 0x41 +#define ADD_BATCHCMD 0x42 +#define SEND_BATCHCMD 0x43 +#define GET_BATCHRSP 0x44 + +#ifdef SUPPORT_CPRM +/* SD Pass Through Command Extention */ +#define SD_PASS_THRU_MODE 0xD0 +#define SD_EXECUTE_NO_DATA 0xD1 +#define SD_EXECUTE_READ 0xD2 +#define SD_EXECUTE_WRITE 0xD3 +#define SD_GET_RSP 0xD4 +#define SD_HW_RST 0xD6 +#endif + +#ifdef SUPPORT_MAGIC_GATE +#define CMD_MSPRO_MG_RKEY 0xA4 /* Report Key Command */ +#define CMD_MSPRO_MG_SKEY 0xA3 /* Send Key Command */ + +/* CBWCB field: key class */ +#define KC_MG_R_PRO 0xBE /* MG-R PRO */ + +/* CBWCB field: key format */ +#define KF_SET_LEAF_ID 0x31 /* Set Leaf ID */ +#define KF_GET_LOC_EKB 0x32 /* Get Local EKB */ +#define KF_CHG_HOST 0x33 /* Challenge (host) */ +#define KF_RSP_CHG 0x34 /* Response and Challenge (device) */ +#define KF_RSP_HOST 0x35 /* Response (host) */ +#define KF_GET_ICV 0x36 /* Get ICV */ +#define KF_SET_ICV 0x37 /* SSet ICV */ +#endif + +struct rts51x_chip; + +/*----------------------------------- + Start-Stop-Unit +-----------------------------------*/ +#define STOP_MEDIUM 0x00 /* access disable */ +#define MAKE_MEDIUM_READY 0x01 /* access enable */ +#define UNLOAD_MEDIUM 0x02 /* unload */ +#define LOAD_MEDIUM 0x03 /* load */ + +/*----------------------------------- + STANDARD_INQUIRY +-----------------------------------*/ +#define QULIFIRE 0x00 +#define AENC_FNC 0x00 +#define TRML_IOP 0x00 +#define REL_ADR 0x00 +#define WBUS_32 0x00 +#define WBUS_16 0x00 +#define SYNC 0x00 +#define LINKED 0x00 +#define CMD_QUE 0x00 +#define SFT_RE 0x00 + +#define VEN_ID_LEN 8 /* Vendor ID Length */ +#define PRDCT_ID_LEN 16 /* Product ID Length */ +#define PRDCT_REV_LEN 4 /* Product LOT Length */ + +#define DRCT_ACCESS_DEV 0x00 /* Direct Access Device */ +#define RMB_DISC 0x80 /* The Device is Removable */ +#define ANSI_SCSI2 0x02 /* Based on ANSI-SCSI2 */ + +#define SCSI 0x00 /* Interface ID */ + +void scsi_show_command(struct scsi_cmnd *srb); +void set_sense_type(struct rts51x_chip *chip, unsigned int lun, int sense_type); +void set_sense_data(struct rts51x_chip *chip, unsigned int lun, u8 err_code, + u8 sense_key, u32 info, u8 asc, u8 ascq, u8 sns_key_info0, + u16 sns_key_info1); + +int rts51x_scsi_handler(struct scsi_cmnd *srb, struct rts51x_chip *chip); + +struct Scsi_Host; +struct scsi_device; +struct scsi_cmnd; + +const char *host_info(struct Scsi_Host *host); +int slave_alloc(struct scsi_device *sdev); +int slave_configure(struct scsi_device *sdev); +int proc_info(struct Scsi_Host *host, char *buffer, + char **start, off_t offset, int length, int inout); +#if 0 /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 37) */ +int queuecommand(struct scsi_cmnd *srb, void (*done) (struct scsi_cmnd *)); +#else +int queuecommand(struct Scsi_Host *, struct scsi_cmnd *); +#endif +int command_abort(struct scsi_cmnd *srb); +int device_reset(struct scsi_cmnd *srb); +int bus_reset(struct scsi_cmnd *srb); + +#endif /* __RTS51X_SCSI_H */ diff --git a/drivers/staging/rts5139/rts51x_sys.h b/drivers/staging/rts5139/rts51x_sys.h new file mode 100644 index 0000000..b09cd34 --- /dev/null +++ b/drivers/staging/rts5139/rts51x_sys.h @@ -0,0 +1,54 @@ +/* Driver for Realtek USB RTS51xx card reader + * Header file + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + * Maintainer: + * Edwin Rong (edwin_rong@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#ifndef __RTS51X_SYS_H +#define __RTS51X_SYS_H + +#include "rts51x.h" +#include "rts51x_chip.h" +#include "rts51x_card.h" + +#define USING_POLLING_CYCLE_DELINK + +extern int rts51x_check_start_time(struct rts51x_chip *chip); +extern void rts51x_set_start_time(struct rts51x_chip *chip); +extern void rts51x_clear_start_time(struct rts51x_chip *chip); + +/* typedef dma_addr_t ULONG_PTR; */ + +static inline void rts51x_reset_detected_cards(struct rts51x_chip *chip) +{ +/* rts51x_reset_cards(chip); */ +} + +static inline void clear_first_install_mark(struct rts51x_chip *chip) +{ +} + +void rts51x_enter_ss(struct rts51x_chip *chip); +void rts51x_exit_ss(struct rts51x_chip *chip); + +#endif /* __RTS51X_SYS_H */ diff --git a/drivers/staging/rts5139/rts51x_transport.c b/drivers/staging/rts5139/rts51x_transport.c new file mode 100644 index 0000000..e11467a --- /dev/null +++ b/drivers/staging/rts5139/rts51x_transport.c @@ -0,0 +1,1000 @@ +/* Driver for Realtek RTS51xx USB card reader + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + * Maintainer: + * Edwin Rong (edwin_rong@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#include <linux/blkdev.h> +#include <linux/kthread.h> +#include <linux/sched.h> +#include <linux/slab.h> + +#include <scsi/scsi.h> +#include <scsi/scsi_eh.h> +#include <scsi/scsi_device.h> + +#include "debug.h" +#include "rts51x.h" +#include "rts51x_chip.h" +#include "rts51x_card.h" +#include "rts51x_scsi.h" +#include "rts51x_transport.h" +#include "trace.h" + +/*********************************************************************** + * Scatter-gather transfer buffer access routines + ***********************************************************************/ + +/* Copy a buffer of length buflen to/from the srb's transfer buffer. + * Update the **sgptr and *offset variables so that the next copy will + * pick up from where this one left off. + */ + +unsigned int rts51x_access_sglist(unsigned char *buffer, + unsigned int buflen, void *sglist, + void **sgptr, unsigned int *offset, + enum xfer_buf_dir dir) +{ + unsigned int cnt; + struct scatterlist *sg = (struct scatterlist *)*sgptr; + + /* We have to go through the list one entry + * at a time. Each s-g entry contains some number of pages, and + * each page has to be kmap()'ed separately. If the page is already + * in kernel-addressable memory then kmap() will return its address. + * If the page is not directly accessible -- such as a user buffer + * located in high memory -- then kmap() will map it to a temporary + * position in the kernel's virtual address space. + */ + + if (!sg) + sg = (struct scatterlist *)sglist; + + /* This loop handles a single s-g list entry, which may + * include multiple pages. Find the initial page structure + * and the starting offset within the page, and update + * the *offset and **sgptr values for the next loop. + */ + cnt = 0; + while (cnt < buflen && sg) { + struct page *page = sg_page(sg) + + ((sg->offset + *offset) >> PAGE_SHIFT); + unsigned int poff = (sg->offset + *offset) & (PAGE_SIZE - 1); + unsigned int sglen = sg->length - *offset; + + if (sglen > buflen - cnt) { + + /* Transfer ends within this s-g entry */ + sglen = buflen - cnt; + *offset += sglen; + } else { + + /* Transfer continues to next s-g entry */ + *offset = 0; + sg = sg_next(sg); + } + + /* Transfer the data for all the pages in this + * s-g entry. For each page: call kmap(), do the + * transfer, and call kunmap() immediately after. */ + while (sglen > 0) { + unsigned int plen = min(sglen, (unsigned int) + PAGE_SIZE - poff); + unsigned char *ptr = kmap(page); + + if (dir == TO_XFER_BUF) + memcpy(ptr + poff, buffer + cnt, plen); + else + memcpy(buffer + cnt, ptr + poff, plen); + kunmap(page); + + /* Start at the beginning of the next page */ + poff = 0; + ++page; + cnt += plen; + sglen -= plen; + } + } + *sgptr = sg; + + /* Return the amount actually transferred */ + return cnt; +} + +unsigned int rts51x_access_xfer_buf(unsigned char *buffer, + unsigned int buflen, struct scsi_cmnd *srb, + struct scatterlist **sgptr, + unsigned int *offset, enum xfer_buf_dir dir) +{ + return rts51x_access_sglist(buffer, buflen, (void *)scsi_sglist(srb), + (void **)sgptr, offset, dir); +} + +/* Store the contents of buffer into srb's transfer buffer and set the + * SCSI residue. + */ +void rts51x_set_xfer_buf(unsigned char *buffer, + unsigned int buflen, struct scsi_cmnd *srb) +{ + unsigned int offset = 0; + struct scatterlist *sg = NULL; + + buflen = min(buflen, scsi_bufflen(srb)); + buflen = rts51x_access_xfer_buf(buffer, buflen, srb, &sg, &offset, + TO_XFER_BUF); + if (buflen < scsi_bufflen(srb)) + scsi_set_resid(srb, scsi_bufflen(srb) - buflen); +} + +void rts51x_get_xfer_buf(unsigned char *buffer, + unsigned int buflen, struct scsi_cmnd *srb) +{ + unsigned int offset = 0; + struct scatterlist *sg = NULL; + + buflen = min(buflen, scsi_bufflen(srb)); + buflen = rts51x_access_xfer_buf(buffer, buflen, srb, &sg, &offset, + FROM_XFER_BUF); + if (buflen < scsi_bufflen(srb)) + scsi_set_resid(srb, scsi_bufflen(srb) - buflen); +} + +/* This is the completion handler which will wake us up when an URB + * completes. + */ +static void urb_done_completion(struct urb *urb) +{ + struct completion *urb_done_ptr = urb->context; + + if (urb_done_ptr) + complete(urb_done_ptr); +} + +/* This is the common part of the URB message submission code + * + * All URBs from the driver involved in handling a queued scsi + * command _must_ pass through this function (or something like it) for the + * abort mechanisms to work properly. + */ +static int rts51x_msg_common(struct rts51x_chip *chip, struct urb *urb, + int timeout) +{ + struct rts51x_usb *rts51x = chip->usb; + struct completion urb_done; + long timeleft; + int status; + + /* don't submit URBs during abort processing */ + if (test_bit(FLIDX_ABORTING, &rts51x->dflags)) + TRACE_RET(chip, -EIO); + + /* set up data structures for the wakeup system */ + init_completion(&urb_done); + + /* fill the common fields in the URB */ + urb->context = &urb_done; + urb->actual_length = 0; + urb->error_count = 0; + urb->status = 0; + + /* we assume that if transfer_buffer isn't us->iobuf then it + * hasn't been mapped for DMA. Yes, this is clunky, but it's + * easier than always having the caller tell us whether the + * transfer buffer has already been mapped. */ + urb->transfer_flags = URB_NO_SETUP_DMA_MAP; + if (urb->transfer_buffer == rts51x->iobuf) { + urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + urb->transfer_dma = rts51x->iobuf_dma; + } + urb->setup_dma = rts51x->cr_dma; + + /* submit the URB */ + status = usb_submit_urb(urb, GFP_NOIO); + if (status) { + /* something went wrong */ + TRACE_RET(chip, status); + } + + /* since the URB has been submitted successfully, it's now okay + * to cancel it */ + set_bit(FLIDX_URB_ACTIVE, &rts51x->dflags); + + /* did an abort occur during the submission? */ + if (test_bit(FLIDX_ABORTING, &rts51x->dflags)) { + + /* cancel the URB, if it hasn't been cancelled already */ + if (test_and_clear_bit(FLIDX_URB_ACTIVE, &rts51x->dflags)) { + RTS51X_DEBUGP("-- cancelling URB\n"); + usb_unlink_urb(urb); + } + } + + /* wait for the completion of the URB */ + timeleft = + wait_for_completion_interruptible_timeout(&urb_done, + (timeout * HZ / + 1000) ? : + MAX_SCHEDULE_TIMEOUT); + + clear_bit(FLIDX_URB_ACTIVE, &rts51x->dflags); + + if (timeleft <= 0) { + RTS51X_DEBUGP("%s -- cancelling URB\n", + timeleft == 0 ? "Timeout" : "Signal"); + usb_kill_urb(urb); + if (timeleft == 0) + status = -ETIMEDOUT; + else + status = -EINTR; + } else { + status = urb->status; + } + + return status; +} + +/* + * Interpret the results of a URB transfer + */ +static int interpret_urb_result(struct rts51x_chip *chip, unsigned int pipe, + unsigned int length, int result, + unsigned int partial) +{ + int retval = STATUS_SUCCESS; + + /* RTS51X_DEBUGP("Status code %d; transferred %u/%u\n", + result, partial, length); */ + switch (result) { + /* no error code; did we send all the data? */ + case 0: + if (partial != length) { + RTS51X_DEBUGP("-- short transfer\n"); + TRACE_RET(chip, STATUS_TRANS_SHORT); + } + /* RTS51X_DEBUGP("-- transfer complete\n"); */ + return STATUS_SUCCESS; + /* stalled */ + case -EPIPE: + /* for control endpoints, (used by CB[I]) a stall indicates + * a failed command */ + if (usb_pipecontrol(pipe)) { + RTS51X_DEBUGP("-- stall on control pipe\n"); + TRACE_RET(chip, STATUS_STALLED); + } + /* for other sorts of endpoint, clear the stall */ + RTS51X_DEBUGP("clearing endpoint halt for pipe 0x%x\n", pipe); + if (rts51x_clear_halt(chip, pipe) < 0) + TRACE_RET(chip, STATUS_ERROR); + retval = STATUS_STALLED; + TRACE_GOTO(chip, Exit); + + /* babble - the device tried to send more than + * we wanted to read */ + case -EOVERFLOW: + RTS51X_DEBUGP("-- babble\n"); + retval = STATUS_TRANS_LONG; + TRACE_GOTO(chip, Exit); + + /* the transfer was cancelled by abort, + * disconnect, or timeout */ + case -ECONNRESET: + RTS51X_DEBUGP("-- transfer cancelled\n"); + retval = STATUS_ERROR; + TRACE_GOTO(chip, Exit); + + /* short scatter-gather read transfer */ + case -EREMOTEIO: + RTS51X_DEBUGP("-- short read transfer\n"); + retval = STATUS_TRANS_SHORT; + TRACE_GOTO(chip, Exit); + + /* abort or disconnect in progress */ + case -EIO: + RTS51X_DEBUGP("-- abort or disconnect in progress\n"); + retval = STATUS_ERROR; + TRACE_GOTO(chip, Exit); + + case -ETIMEDOUT: + RTS51X_DEBUGP("-- time out\n"); + retval = STATUS_TIMEDOUT; + TRACE_GOTO(chip, Exit); + + /* the catch-all error case */ + default: + RTS51X_DEBUGP("-- unknown error\n"); + retval = STATUS_ERROR; + TRACE_GOTO(chip, Exit); + } + +Exit: + if ((retval != STATUS_SUCCESS) && !usb_pipecontrol(pipe)) + rts51x_clear_hw_error(chip); + + return retval; +} + +int rts51x_ctrl_transfer(struct rts51x_chip *chip, unsigned int pipe, + u8 request, u8 requesttype, u16 value, u16 index, + void *data, u16 size, int timeout) +{ + struct rts51x_usb *rts51x = chip->usb; + int result; + + RTS51X_DEBUGP("%s: rq=%02x rqtype=%02x value=%04x index=%02x len=%u\n", + __func__, request, requesttype, value, index, size); + + /* fill in the devrequest structure */ + rts51x->cr->bRequestType = requesttype; + rts51x->cr->bRequest = request; + rts51x->cr->wValue = cpu_to_le16(value); + rts51x->cr->wIndex = cpu_to_le16(index); + rts51x->cr->wLength = cpu_to_le16(size); + + /* fill and submit the URB */ + usb_fill_control_urb(rts51x->current_urb, rts51x->pusb_dev, pipe, + (unsigned char *)rts51x->cr, data, size, + urb_done_completion, NULL); + result = rts51x_msg_common(chip, rts51x->current_urb, timeout); + + return interpret_urb_result(chip, pipe, size, result, + rts51x->current_urb->actual_length); +} + +int rts51x_clear_halt(struct rts51x_chip *chip, unsigned int pipe) +{ + int result; + int endp = usb_pipeendpoint(pipe); + + if (usb_pipein(pipe)) + endp |= USB_DIR_IN; + + result = rts51x_ctrl_transfer(chip, SND_CTRL_PIPE(chip), + USB_REQ_CLEAR_FEATURE, USB_RECIP_ENDPOINT, + USB_ENDPOINT_HALT, endp, NULL, 0, 3000); + if (result != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + usb_reset_endpoint(chip->usb->pusb_dev, endp); + + return STATUS_SUCCESS; +} + +int rts51x_reset_pipe(struct rts51x_chip *chip, char pipe) +{ + return rts51x_clear_halt(chip, pipe); +} + +static void rts51x_sg_clean(struct usb_sg_request *io) +{ + if (io->urbs) { + while (io->entries--) + usb_free_urb(io->urbs[io->entries]); + kfree(io->urbs); + io->urbs = NULL; + } +#if 0 /* LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) */ + if (io->dev->dev.dma_mask != NULL) + usb_buffer_unmap_sg(io->dev, usb_pipein(io->pipe), + io->sg, io->nents); +#endif + io->dev = NULL; +} +#if 0 +static void rts51x_sg_complete(struct urb *urb) +{ + struct usb_sg_request *io = urb->context; + int status = urb->status; + + spin_lock(&io->lock); + + /* In 2.5 we require hcds' endpoint queues not to progress after fault + * reports, until the completion callback (this!) returns. That lets + * device driver code (like this routine) unlink queued urbs first, + * if it needs to, since the HC won't work on them at all. So it's + * not possible for page N+1 to overwrite page N, and so on. + * + * That's only for "hard" faults; "soft" faults (unlinks) sometimes + * complete before the HCD can get requests away from hardware, + * though never during cleanup after a hard fault. + */ + if (io->status + && (io->status != -ECONNRESET + || status != -ECONNRESET) + && urb->actual_length) { + dev_err(io->dev->bus->controller, + "dev %s ep%d%s scatterlist error %d/%d\n", + io->dev->devpath, + usb_endpoint_num(&urb->ep->desc), + usb_urb_dir_in(urb) ? "in" : "out", + status, io->status); + /* BUG (); */ + } + + if (io->status == 0 && status && status != -ECONNRESET) { + int i, found, retval; + + io->status = status; + + /* the previous urbs, and this one, completed already. + * unlink pending urbs so they won't rx/tx bad data. + * careful: unlink can sometimes be synchronous... + */ + spin_unlock(&io->lock); + for (i = 0, found = 0; i < io->entries; i++) { + if (!io->urbs[i] || !io->urbs[i]->dev) + continue; + if (found) { + retval = usb_unlink_urb(io->urbs[i]); + if (retval != -EINPROGRESS && + retval != -ENODEV && + retval != -EBUSY) + dev_err(&io->dev->dev, + "%s, unlink --> %d\n", + __func__, retval); + } else if (urb == io->urbs[i]) + found = 1; + } + spin_lock(&io->lock); + } + urb->dev = NULL; + + /* on the last completion, signal usb_sg_wait() */ + io->bytes += urb->actual_length; + io->count--; + if (!io->count) + complete(&io->complete); + + spin_unlock(&io->lock); +} + +/* This function is ported from usb_sg_init, which can transfer + * sg list partially */ +int rts51x_sg_init_partial(struct usb_sg_request *io, struct usb_device *dev, + unsigned pipe, unsigned period, void *buf, struct scatterlist **sgptr, + unsigned int *offset, int nents, size_t length, gfp_t mem_flags) +{ + int i; + int urb_flags; + int dma; + struct scatterlist *sg = *sgptr, *first_sg; + + first_sg = (struct scatterlist *)buf; + if (!sg) + sg = first_sg; + + if (!io || !dev || !sg + || usb_pipecontrol(pipe) + || usb_pipeisoc(pipe) + || (nents <= 0)) + return -EINVAL; + + spin_lock_init(&io->lock); + io->dev = dev; + io->pipe = pipe; + io->sg = first_sg; /* used by unmap */ + io->nents = nents; + + RTS51X_DEBUGP("Before map, sg address: 0x%x\n", (unsigned int)sg); + RTS51X_DEBUGP("Before map, dev address: 0x%x\n", (unsigned int)dev); + + /* not all host controllers use DMA (like the mainstream pci ones); + * they can use PIO (sl811) or be software over another transport. + */ + dma = (dev->dev.dma_mask != NULL); + if (dma) { + /* map the whole sg list, because here we only know the + * total nents */ + io->entries = usb_buffer_map_sg(dev, usb_pipein(pipe), + first_sg, nents); + } else { + io->entries = nents; + } + + /* initialize all the urbs we'll use */ + if (io->entries <= 0) + return io->entries; + + io->urbs = kmalloc(io->entries * sizeof *io->urbs, mem_flags); + if (!io->urbs) + goto nomem; + + urb_flags = URB_NO_INTERRUPT; + if (dma) + urb_flags |= URB_NO_TRANSFER_DMA_MAP; + if (usb_pipein(pipe)) + urb_flags |= URB_SHORT_NOT_OK; + + RTS51X_DEBUGP("io->entries = %d\n", io->entries); + + for (i = 0; (sg != NULL) && (length > 0); i++) { + unsigned len; + + RTS51X_DEBUGP("sg address: 0x%x\n", (unsigned int)sg); + RTS51X_DEBUGP("length = %d, *offset = %d\n", length, *offset); + + io->urbs[i] = usb_alloc_urb(0, mem_flags); + if (!io->urbs[i]) { + io->entries = i; + goto nomem; + } + + io->urbs[i]->dev = NULL; + io->urbs[i]->pipe = pipe; + io->urbs[i]->interval = period; + io->urbs[i]->transfer_flags = urb_flags; + + io->urbs[i]->complete = rts51x_sg_complete; + io->urbs[i]->context = io; + + if (dma) { + io->urbs[i]->transfer_dma = + sg_dma_address(sg) + *offset; + len = sg_dma_len(sg) - *offset; + io->urbs[i]->transfer_buffer = NULL; + RTS51X_DEBUGP(" -- sg entry dma length = %d\n", + sg_dma_len(sg)); + } else { + /* hc may use _only_ transfer_buffer */ + io->urbs[i]->transfer_buffer = sg_virt(sg) + *offset; + len = sg->length - *offset; + RTS51X_DEBUGP(" -- sg entry length = %d\n", + sg->length); + } + + if (length >= len) { + *offset = 0; + io->urbs[i]->transfer_buffer_length = len; + length -= len; + sg = sg_next(sg); + } else { + *offset += length; + io->urbs[i]->transfer_buffer_length = length; + length = 0; + } + if (length == 0) + io->entries = i + 1; +#if 0 + if (length) { + len = min_t(unsigned, len, length); + length -= len; + if (length == 0) { + io->entries = i + 1; + *offset += len; + } else { + *offset = 0; + } + } +#endif + } + RTS51X_DEBUGP("In %s, urb count: %d\n", __func__, i); + io->urbs[--i]->transfer_flags &= ~URB_NO_INTERRUPT; + + RTS51X_DEBUGP("sg address stored in sgptr: 0x%x\n", (unsigned int)sg); + *sgptr = sg; + + /* transaction state */ + io->count = io->entries; + io->status = 0; + io->bytes = 0; + init_completion(&io->complete); + return 0; + +nomem: + rts51x_sg_clean(io); + return -ENOMEM; +} +#endif +int rts51x_sg_init(struct usb_sg_request *io, struct usb_device *dev, + unsigned pipe, unsigned period, struct scatterlist *sg, + int nents, size_t length, gfp_t mem_flags) +{ + return usb_sg_init(io, dev, pipe, period, sg, nents, length, mem_flags); +} + +int rts51x_sg_wait(struct usb_sg_request *io, int timeout) +{ + long timeleft; + int i; + int entries = io->entries; + + /* queue the urbs. */ + spin_lock_irq(&io->lock); + i = 0; + while (i < entries && !io->status) { + int retval; + + io->urbs[i]->dev = io->dev; + retval = usb_submit_urb(io->urbs[i], GFP_ATOMIC); + + /* after we submit, let completions or cancelations fire; + * we handshake using io->status. + */ + spin_unlock_irq(&io->lock); + switch (retval) { + /* maybe we retrying will recover */ + case -ENXIO: /* hc didn't queue this one */ + case -EAGAIN: + case -ENOMEM: + io->urbs[i]->dev = NULL; + retval = 0; + yield(); + break; + + /* no error? continue immediately. + * + * NOTE: to work better with UHCI (4K I/O buffer may + * need 3K of TDs) it may be good to limit how many + * URBs are queued at once; N milliseconds? + */ + case 0: + ++i; + cpu_relax(); + break; + + /* fail any uncompleted urbs */ + default: + io->urbs[i]->dev = NULL; + io->urbs[i]->status = retval; + dev_dbg(&io->dev->dev, "%s, submit --> %d\n", + __func__, retval); + usb_sg_cancel(io); + } + spin_lock_irq(&io->lock); + if (retval && (io->status == 0 || io->status == -ECONNRESET)) + io->status = retval; + } + io->count -= entries - i; + if (io->count == 0) + complete(&io->complete); + spin_unlock_irq(&io->lock); + + timeleft = + wait_for_completion_interruptible_timeout(&io->complete, + (timeout * HZ / + 1000) ? : + MAX_SCHEDULE_TIMEOUT); + if (timeleft <= 0) { + RTS51X_DEBUGP("%s -- cancelling SG request\n", + timeleft == 0 ? "Timeout" : "Signal"); + usb_sg_cancel(io); + if (timeleft == 0) + io->status = -ETIMEDOUT; + else + io->status = -EINTR; + } + + rts51x_sg_clean(io); + return io->status; +} + +/* + * Transfer a scatter-gather list via bulk transfer + * + * This function does basically the same thing as usb_stor_bulk_transfer_buf() + * above, but it uses the usbcore scatter-gather library. + */ +static int rts51x_bulk_transfer_sglist(struct rts51x_chip *chip, + unsigned int pipe, + struct scatterlist *sg, int num_sg, + unsigned int length, + unsigned int *act_len, int timeout) +{ + int result; + + /* don't submit s-g requests during abort processing */ + if (test_bit(FLIDX_ABORTING, &chip->usb->dflags)) + TRACE_RET(chip, STATUS_ERROR); + + /* initialize the scatter-gather request block */ + RTS51X_DEBUGP("%s: xfer %u bytes, %d entries\n", __func__, + length, num_sg); + result = + rts51x_sg_init(&chip->usb->current_sg, chip->usb->pusb_dev, pipe, 0, + sg, num_sg, length, GFP_NOIO); + if (result) { + RTS51X_DEBUGP("rts51x_sg_init returned %d\n", result); + TRACE_RET(chip, STATUS_ERROR); + } + + /* since the block has been initialized successfully, it's now + * okay to cancel it */ + set_bit(FLIDX_SG_ACTIVE, &chip->usb->dflags); + + /* did an abort occur during the submission? */ + if (test_bit(FLIDX_ABORTING, &chip->usb->dflags)) { + + /* cancel the request, if it hasn't been cancelled already */ + if (test_and_clear_bit(FLIDX_SG_ACTIVE, &chip->usb->dflags)) { + RTS51X_DEBUGP("-- cancelling sg request\n"); + usb_sg_cancel(&chip->usb->current_sg); + } + } + + /* wait for the completion of the transfer */ + result = rts51x_sg_wait(&chip->usb->current_sg, timeout); + + clear_bit(FLIDX_SG_ACTIVE, &chip->usb->dflags); + + /* result = us->current_sg.status; */ + if (act_len) + *act_len = chip->usb->current_sg.bytes; + return interpret_urb_result(chip, pipe, length, result, + chip->usb->current_sg.bytes); +} +#if 0 +static int rts51x_bulk_transfer_sglist_partial(struct rts51x_chip *chip, + unsigned int pipe, void *buf, struct scatterlist **sgptr, + unsigned int *offset, int num_sg, unsigned int length, + unsigned int *act_len, int timeout) +{ + int result; + + /* don't submit s-g requests during abort processing */ + if (test_bit(FLIDX_ABORTING, &chip->usb->dflags)) + TRACE_RET(chip, STATUS_ERROR); + + /* initialize the scatter-gather request block */ + RTS51X_DEBUGP("%s: xfer %u bytes, %d entries\n", __func__, + length, num_sg); + result = rts51x_sg_init_partial(&chip->usb->current_sg, + chip->usb->pusb_dev, pipe, 0, buf, sgptr, offset, + num_sg, length, GFP_NOIO); + if (result) { + RTS51X_DEBUGP("rts51x_sg_init_partial returned %d\n", result); + TRACE_RET(chip, STATUS_ERROR); + } + + /* since the block has been initialized successfully, it's now + * okay to cancel it */ + set_bit(FLIDX_SG_ACTIVE, &chip->usb->dflags); + + /* did an abort occur during the submission? */ + if (test_bit(FLIDX_ABORTING, &chip->usb->dflags)) { + + /* cancel the request, if it hasn't been cancelled already */ + if (test_and_clear_bit(FLIDX_SG_ACTIVE, &chip->usb->dflags)) { + RTS51X_DEBUGP("-- cancelling sg request\n"); + usb_sg_cancel(&chip->usb->current_sg); + } + } + + /* wait for the completion of the transfer */ + result = rts51x_sg_wait(&chip->usb->current_sg, timeout); + + clear_bit(FLIDX_SG_ACTIVE, &chip->usb->dflags); + + /* result = us->current_sg.status; */ + if (act_len) + *act_len = chip->usb->current_sg.bytes; + return interpret_urb_result(chip, pipe, length, result, + chip->usb->current_sg.bytes); +} +#endif +int rts51x_bulk_transfer_buf(struct rts51x_chip *chip, unsigned int pipe, + void *buf, unsigned int length, + unsigned int *act_len, int timeout) +{ + int result; + + /* fill and submit the URB */ + usb_fill_bulk_urb(chip->usb->current_urb, chip->usb->pusb_dev, pipe, + buf, length, urb_done_completion, NULL); + result = rts51x_msg_common(chip, chip->usb->current_urb, timeout); + + /* store the actual length of the data transferred */ + if (act_len) + *act_len = chip->usb->current_urb->actual_length; + return interpret_urb_result(chip, pipe, length, result, + chip->usb->current_urb->actual_length); +} + +int rts51x_transfer_data(struct rts51x_chip *chip, unsigned int pipe, + void *buf, unsigned int len, int use_sg, + unsigned int *act_len, int timeout) +{ + int result; + + if (timeout < 600) + timeout = 600; + + if (use_sg) { + result = + rts51x_bulk_transfer_sglist(chip, pipe, + (struct scatterlist *)buf, + use_sg, len, act_len, timeout); + } else { + result = + rts51x_bulk_transfer_buf(chip, pipe, buf, len, act_len, + timeout); + } + + return result; +} + +int rts51x_transfer_data_partial(struct rts51x_chip *chip, unsigned int pipe, + void *buf, void **ptr, unsigned int *offset, + unsigned int len, int use_sg, + unsigned int *act_len, int timeout) +{ + int result; + + if (timeout < 600) + timeout = 600; + + if (use_sg) { + void *tmp_buf = kmalloc(len, GFP_KERNEL); + if (!tmp_buf) + TRACE_RET(chip, STATUS_NOMEM); + + if (usb_pipeout(pipe)) { + rts51x_access_sglist(tmp_buf, len, buf, ptr, offset, + FROM_XFER_BUF); + } + result = + rts51x_bulk_transfer_buf(chip, pipe, tmp_buf, len, act_len, + timeout); + if (result == STATUS_SUCCESS) { + if (usb_pipein(pipe)) { + rts51x_access_sglist(tmp_buf, len, buf, ptr, + offset, TO_XFER_BUF); + } + } + + kfree(tmp_buf); +#if 0 + result = rts51x_bulk_transfer_sglist_partial(chip, pipe, buf, + (struct scatterlist **)ptr, offset, + use_sg, len, act_len, timeout); +#endif + } else { + unsigned int step = 0; + if (offset) + step = *offset; + result = + rts51x_bulk_transfer_buf(chip, pipe, buf + step, len, + act_len, timeout); + if (act_len) + step += *act_len; + else + step += len; + if (offset) + *offset = step; + } + + return result; +} + +int rts51x_get_epc_status(struct rts51x_chip *chip, u16 * status) +{ + unsigned int pipe = RCV_INTR_PIPE(chip); + struct usb_host_endpoint *ep; + struct completion urb_done; + int result; + + if (!status) + TRACE_RET(chip, STATUS_ERROR); + + /* set up data structures for the wakeup system */ + init_completion(&urb_done); + + ep = chip->usb->pusb_dev->ep_in[usb_pipeendpoint(pipe)]; + + /* fill and submit the URB */ + /* We set interval to 1 here, so the polling interval is controlled + * by our polling thread */ + usb_fill_int_urb(chip->usb->intr_urb, chip->usb->pusb_dev, pipe, + status, 2, urb_done_completion, &urb_done, 1); + + result = rts51x_msg_common(chip, chip->usb->intr_urb, 50); + + return interpret_urb_result(chip, pipe, 2, result, + chip->usb->intr_urb->actual_length); +} + +u8 media_not_present[] = { + 0x70, 0, 0x02, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0x3A, 0, 0, 0, 0, 0 }; +u8 invalid_cmd_field[] = { + 0x70, 0, 0x05, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0x24, 0, 0, 0, 0, 0 }; + +void rts51x_invoke_transport(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + int result; + +#ifdef CONFIG_PM + if (chip->option.ss_en) { + if (srb->cmnd[0] == TEST_UNIT_READY) { + if (RTS51X_CHK_STAT(chip, STAT_SS)) { + if (check_fake_card_ready(chip, + SCSI_LUN(srb))) { + srb->result = SAM_STAT_GOOD; + } else { + srb->result = SAM_STAT_CHECK_CONDITION; + memcpy(srb->sense_buffer, + media_not_present, SENSE_SIZE); + } + return; + } + } else if (srb->cmnd[0] == ALLOW_MEDIUM_REMOVAL) { + if (RTS51X_CHK_STAT(chip, STAT_SS)) { + int prevent = srb->cmnd[4] & 0x1; + + if (prevent) { + srb->result = SAM_STAT_CHECK_CONDITION; + memcpy(srb->sense_buffer, + invalid_cmd_field, SENSE_SIZE); + } else { + srb->result = SAM_STAT_GOOD; + } + return; + } + } else { + if (RTS51X_CHK_STAT(chip, STAT_SS) + || RTS51X_CHK_STAT(chip, STAT_SS_PRE)) { + /* Wake up device */ + RTS51X_DEBUGP("Try to wake up device\n"); + chip->resume_from_scsi = 1; + + rts51x_try_to_exit_ss(chip); + + if (RTS51X_CHK_STAT(chip, STAT_SS)) { + wait_timeout(3000); + + rts51x_init_chip(chip); + rts51x_init_cards(chip); + } + } + } + } +#endif + + result = rts51x_scsi_handler(srb, chip); + + /* if there is a transport error, reset and don't auto-sense */ + if (result == TRANSPORT_ERROR) { + RTS51X_DEBUGP("-- transport indicates error, resetting\n"); + srb->result = DID_ERROR << 16; + goto Handle_Errors; + } + + srb->result = SAM_STAT_GOOD; + + /* + * If we have a failure, we're going to do a REQUEST_SENSE + * automatically. Note that we differentiate between a command + * "failure" and an "error" in the transport mechanism. + */ + if (result == TRANSPORT_FAILED) { + /* set the result so the higher layers expect this data */ + srb->result = SAM_STAT_CHECK_CONDITION; + memcpy(srb->sense_buffer, + (unsigned char *)&(chip->sense_buffer[SCSI_LUN(srb)]), + sizeof(struct sense_data_t)); + } + + return; + + /* Error and abort processing: try to resynchronize with the device + * by issuing a port reset. If that fails, try a class-specific + * device reset. */ +Handle_Errors: + return; +} diff --git a/drivers/staging/rts5139/rts51x_transport.h b/drivers/staging/rts5139/rts51x_transport.h new file mode 100644 index 0000000..f7aa87f --- /dev/null +++ b/drivers/staging/rts5139/rts51x_transport.h @@ -0,0 +1,80 @@ +/* Driver for Realtek RTS51xx USB card reader + * Header file + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + * Maintainer: + * Edwin Rong (edwin_rong@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#ifndef __RTS51X_TRANSPORT_H +#define __RTS51X_TRANSPORT_H + +#include <linux/kernel.h> +#include <linux/version.h> + +#include "rts51x.h" +#include "rts51x_chip.h" + +#if 1 /* LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 34) */ +#define URB_NO_SETUP_DMA_MAP 0 +#endif + +unsigned int rts51x_access_sglist(unsigned char *buffer, + unsigned int buflen, void *sglist, + void **sgptr, unsigned int *offset, + enum xfer_buf_dir dir); +unsigned int rts51x_access_xfer_buf(unsigned char *buffer, unsigned int buflen, + struct scsi_cmnd *srb, + struct scatterlist **sgptr, + unsigned int *offset, + enum xfer_buf_dir dir); +void rts51x_set_xfer_buf(unsigned char *buffer, unsigned int buflen, + struct scsi_cmnd *srb); +void rts51x_get_xfer_buf(unsigned char *buffer, unsigned int buflen, + struct scsi_cmnd *srb); + +int rts51x_ctrl_transfer(struct rts51x_chip *chip, unsigned int pipe, + u8 request, u8 requesttype, u16 value, u16 index, + void *data, u16 size, int timeout); +int rts51x_clear_halt(struct rts51x_chip *chip, unsigned int pipe); +int rts51x_transfer_data(struct rts51x_chip *chip, unsigned int pipe, + void *buf, unsigned int len, int use_sg, + unsigned int *act_len, int timeout); +int rts51x_transfer_data_partial(struct rts51x_chip *chip, unsigned int pipe, + void *buf, void **ptr, unsigned int *offset, + unsigned int len, int use_sg, + unsigned int *act_len, int timeout); + +/* whichPipe: + * 0: bulk in pipe + * 1: bulk out pipe + * 2: intr in pipe */ +int rts51x_reset_pipe(struct rts51x_chip *chip, char pipe); + +#ifndef POLLING_IN_THREAD +int rts51x_start_epc_transfer(struct rts51x_chip *chip); +void rts51x_cancel_epc_transfer(struct rts51x_chip *chip); +#endif + +int rts51x_get_epc_status(struct rts51x_chip *chip, u16 * status); +void rts51x_invoke_transport(struct scsi_cmnd *srb, struct rts51x_chip *chip); + +#endif /* __RTS51X_TRANSPORT_H */ diff --git a/drivers/staging/rts5139/sd.c b/drivers/staging/rts5139/sd.c new file mode 100644 index 0000000..d5dd2f9 --- /dev/null +++ b/drivers/staging/rts5139/sd.c @@ -0,0 +1,3400 @@ +/* Driver for Realtek RTS51xx USB card reader + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + * Maintainer: + * Edwin Rong (edwin_rong@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#include <linux/blkdev.h> +#include <linux/kthread.h> +#include <linux/sched.h> + +#include "debug.h" +#include "trace.h" +#include "rts51x.h" +#include "rts51x_transport.h" +#include "rts51x_scsi.h" +#include "rts51x_card.h" +#include "sd.h" + +static inline void sd_set_reset_fail(struct rts51x_chip *chip, u8 err_code) +{ + struct sd_info *sd_card = &(chip->sd_card); + + sd_card->sd_reset_fail |= err_code; +} + +static inline void sd_clear_reset_fail(struct rts51x_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + + sd_card->sd_reset_fail = 0; +} + +static inline int sd_check_reset_fail(struct rts51x_chip *chip, u8 err_code) +{ + struct sd_info *sd_card = &(chip->sd_card); + + return sd_card->sd_reset_fail & err_code; +} + +static inline void sd_set_err_code(struct rts51x_chip *chip, u8 err_code) +{ + struct sd_info *sd_card = &(chip->sd_card); + + sd_card->err_code |= err_code; +} + +static inline void sd_clr_err_code(struct rts51x_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + + sd_card->err_code = 0; +} + +static inline int sd_check_err_code(struct rts51x_chip *chip, u8 err_code) +{ + struct sd_info *sd_card = &(chip->sd_card); + + return sd_card->err_code & err_code; +} + +static int sd_parse_err_code(struct rts51x_chip *chip) +{ + TRACE_RET(chip, STATUS_FAIL); +} + +int sd_check_data0_status(struct rts51x_chip *chip) +{ + int retval; + u8 stat; + + retval = rts51x_ep0_read_register(chip, SD_BUS_STAT, &stat); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + if (!(stat & SD_DAT0_STATUS)) { + sd_set_err_code(chip, SD_BUSY); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int sd_send_cmd_get_rsp(struct rts51x_chip *chip, u8 cmd_idx, + u32 arg, u8 rsp_type, u8 *rsp, int rsp_len) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + int timeout = 50; + u16 reg_addr; + u8 buf[17], stat; + int len = 2; + int rty_cnt = 0; + + sd_clr_err_code(chip); + + RTS51X_DEBUGP("SD/MMC CMD %d, arg = 0x%08x\n", cmd_idx, arg); + + if (rsp_type == SD_RSP_TYPE_R1b) + timeout = 3000; + +RTY_SEND_CMD: + + rts51x_init_cmd(chip); + + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD0, 0xFF, 0x40 | cmd_idx); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD1, 0xFF, (u8) (arg >> 24)); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD2, 0xFF, (u8) (arg >> 16)); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD3, 0xFF, (u8) (arg >> 8)); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD4, 0xFF, (u8) arg); + + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG2, 0xFF, rsp_type); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, + PINGPONG_BUFFER); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, 0xFF, + SD_TM_CMD_RSP | SD_TRANSFER_START); + rts51x_add_cmd(chip, CHECK_REG_CMD, SD_TRANSFER, + SD_TRANSFER_END | SD_STAT_IDLE, + SD_TRANSFER_END | SD_STAT_IDLE); + + rts51x_add_cmd(chip, READ_REG_CMD, SD_STAT1, 0, 0); + + if (CHECK_USB(chip, USB_20)) { + if (rsp_type == SD_RSP_TYPE_R2) { + /* Read data from ping-pong buffer */ + for (reg_addr = PPBUF_BASE2; + reg_addr < PPBUF_BASE2 + 16; reg_addr++) { + rts51x_add_cmd(chip, READ_REG_CMD, reg_addr, 0, + 0); + } + len = 18; + } else if (rsp_type != SD_RSP_TYPE_R0) { + /* Read data from SD_CMDx registers */ + for (reg_addr = SD_CMD0; reg_addr <= SD_CMD4; + reg_addr++) { + rts51x_add_cmd(chip, READ_REG_CMD, reg_addr, 0, + 0); + } + len = 7; + } else { + len = 2; + } + } else { + len = 2; + } + + retval = rts51x_send_cmd(chip, MODE_CR, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = rts51x_get_rsp(chip, len, timeout); + + if (CHECK_SD_TRANS_FAIL(chip, retval)) { + u8 val; + + rts51x_ep0_read_register(chip, SD_STAT1, &val); + RTS51X_DEBUGP("SD_STAT1: 0x%x\n", val); + + rts51x_ep0_read_register(chip, SD_STAT2, &val); + RTS51X_DEBUGP("SD_STAT2: 0x%x\n", val); + + if (val & SD_RSP_80CLK_TIMEOUT) + sd_set_err_code(chip, SD_RSP_TIMEOUT); + + rts51x_ep0_read_register(chip, SD_BUS_STAT, &val); + RTS51X_DEBUGP("SD_BUS_STAT: 0x%x\n", val); + + if (retval == STATUS_TIMEDOUT) { + if (rsp_type & SD_WAIT_BUSY_END) { + retval = sd_check_data0_status(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } else { + sd_set_err_code(chip, SD_TO_ERR); + } + } + rts51x_clear_sd_error(chip); + + TRACE_RET(chip, STATUS_FAIL); + } + + if (rsp_type == SD_RSP_TYPE_R0) + return STATUS_SUCCESS; + + if (CHECK_USB(chip, USB_20)) { + rts51x_read_rsp_buf(chip, 2, buf, len - 2); + } else { + if (rsp_type == SD_RSP_TYPE_R2) { + reg_addr = PPBUF_BASE2; + len = 16; + } else { + reg_addr = SD_CMD0; + len = 5; + } + retval = rts51x_seq_read_register(chip, reg_addr, + (unsigned short)len, buf); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } + stat = chip->rsp_buf[1]; + + /* Check (Start,Transmission) bit of Response */ + if ((buf[0] & 0xC0) != 0) { + sd_set_err_code(chip, SD_STS_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + /* Check CRC7 */ + if (!(rsp_type & SD_NO_CHECK_CRC7)) { + if (stat & SD_CRC7_ERR) { + if (cmd_idx == WRITE_MULTIPLE_BLOCK) { + sd_set_err_code(chip, SD_CRC_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + if (rty_cnt < SD_MAX_RETRY_COUNT) { + wait_timeout(20); + rty_cnt++; + goto RTY_SEND_CMD; + } else { + sd_set_err_code(chip, SD_CRC_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + } + } + /* Check Status */ + if ((rsp_type == SD_RSP_TYPE_R1) || (rsp_type == SD_RSP_TYPE_R1b)) { + if ((cmd_idx != SEND_RELATIVE_ADDR) + && (cmd_idx != SEND_IF_COND)) { + if (cmd_idx != STOP_TRANSMISSION) { + if (buf[1] & 0x80) + TRACE_RET(chip, STATUS_FAIL); + } +#ifdef SUPPORT_SD_LOCK + /* exclude bit25 CARD_IS_LOCKED */ + if (buf[1] & 0x7D) { +#else + if (buf[1] & 0x7F) { +#endif + RTS51X_DEBUGP("buf[1]: 0x%02x\n", buf[1]); + TRACE_RET(chip, STATUS_FAIL); + } + if (buf[2] & 0xFF) { + RTS51X_DEBUGP("buf[2]: 0x%02x\n", buf[2]); + TRACE_RET(chip, STATUS_FAIL); + } + if (buf[3] & 0x80) { + RTS51X_DEBUGP("buf[3]: 0x%02x\n", buf[3]); + TRACE_RET(chip, STATUS_FAIL); + } + if (buf[3] & 0x01) { + /* Get "READY_FOR_DATA" bit */ + sd_card->sd_data_buf_ready = 1; + } else { + sd_card->sd_data_buf_ready = 0; + } + } + } + + if (rsp && rsp_len) + memcpy(rsp, buf, rsp_len); + + return STATUS_SUCCESS; +} + +static inline void sd_print_debug_reg(struct rts51x_chip *chip) +{ +#ifdef CONFIG_RTS5139_DEBUG + u8 val = 0; + + rts51x_ep0_read_register(chip, SD_STAT1, &val); + RTS51X_DEBUGP("SD_STAT1: 0x%x\n", val); + rts51x_ep0_read_register(chip, SD_STAT2, &val); + RTS51X_DEBUGP("SD_STAT2: 0x%x\n", val); + rts51x_ep0_read_register(chip, SD_BUS_STAT, &val); + RTS51X_DEBUGP("SD_BUS_STAT: 0x%x\n", val); +#endif +} + +int sd_read_data(struct rts51x_chip *chip, u8 trans_mode, u8 *cmd, int cmd_len, + u16 byte_cnt, u16 blk_cnt, u8 bus_width, u8 *buf, int buf_len, + int timeout) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + int i; + + sd_clr_err_code(chip); + + if (!buf) + buf_len = 0; + + if (buf_len > 512) + /* This function can't read data more than one page */ + TRACE_RET(chip, STATUS_FAIL); + + rts51x_init_cmd(chip); + + if (cmd_len) { + RTS51X_DEBUGP("SD/MMC CMD %d\n", cmd[0] - 0x40); + for (i = 0; i < (cmd_len < 6 ? cmd_len : 6); i++) { + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD0 + i, 0xFF, + cmd[i]); + } + } + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, (u8) byte_cnt); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_H, 0xFF, + (u8) (byte_cnt >> 8)); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, (u8) blk_cnt); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, + (u8) (blk_cnt >> 8)); + + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG1, 0x03, bus_width); + + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG2, 0xFF, + SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | SD_NO_WAIT_BUSY_END + | SD_CHECK_CRC7 | SD_RSP_LEN_6); + if (trans_mode != SD_TM_AUTO_TUNING) { + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, + PINGPONG_BUFFER); + } + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, 0xFF, + trans_mode | SD_TRANSFER_START); + rts51x_add_cmd(chip, CHECK_REG_CMD, SD_TRANSFER, SD_TRANSFER_END, + SD_TRANSFER_END); + + retval = rts51x_send_cmd(chip, MODE_CR, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = rts51x_get_rsp(chip, 1, timeout); + + if (CHECK_SD_TRANS_FAIL(chip, retval)) { + sd_print_debug_reg(chip); + if (retval == STATUS_TIMEDOUT) { + sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0); + } + + TRACE_RET(chip, STATUS_FAIL); + } + + if (buf && buf_len) { + retval = rts51x_read_ppbuf(chip, buf, buf_len); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } + + return STATUS_SUCCESS; +} + +static int sd_write_data(struct rts51x_chip *chip, u8 trans_mode, + u8 *cmd, int cmd_len, u16 byte_cnt, u16 blk_cnt, + u8 bus_width, u8 *buf, int buf_len, int timeout) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + int i; + + sd_clr_err_code(chip); + + if (!buf) + buf_len = 0; + + /* This function can't write data more than one page */ + if (buf_len > 512) + TRACE_RET(chip, STATUS_FAIL); + + if (buf && buf_len) { + retval = rts51x_write_ppbuf(chip, buf, buf_len); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } + + rts51x_init_cmd(chip); + + if (cmd_len) { + RTS51X_DEBUGP("SD/MMC CMD %d\n", cmd[0] - 0x40); + for (i = 0; i < (cmd_len < 6 ? cmd_len : 6); i++) { + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD0 + i, 0xFF, + cmd[i]); + } + } + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, (u8) byte_cnt); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_H, 0xFF, + (u8) (byte_cnt >> 8)); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, (u8) blk_cnt); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, + (u8) (blk_cnt >> 8)); + + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG1, 0x03, bus_width); + + if (cmd_len) { + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG2, 0xFF, + SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | + SD_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_6); + + } else { + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG2, 0xFF, + SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | + SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | + SD_RSP_LEN_6); + } + + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, 0xFF, + trans_mode | SD_TRANSFER_START); + rts51x_add_cmd(chip, CHECK_REG_CMD, SD_TRANSFER, SD_TRANSFER_END, + SD_TRANSFER_END); + + retval = rts51x_send_cmd(chip, MODE_CR, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = rts51x_get_rsp(chip, 1, timeout); + + if (CHECK_SD_TRANS_FAIL(chip, retval)) { + sd_print_debug_reg(chip); + + if (retval == STATUS_TIMEDOUT) + sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0); + + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int sd_check_csd(struct rts51x_chip *chip, char check_wp) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + int i; + u8 csd_ver, trans_speed; + u8 rsp[16]; + + for (i = 0; i < 6; i++) { + if (monitor_card_cd(chip, SD_CARD) == CD_NOT_EXIST) { + sd_set_reset_fail(chip, SD_RESET_FAIL); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = + sd_send_cmd_get_rsp(chip, SEND_CSD, sd_card->sd_addr, + SD_RSP_TYPE_R2, rsp, 16); + if (retval == STATUS_SUCCESS) + break; + } + + if (i == 6) + TRACE_RET(chip, STATUS_FAIL); + memcpy(sd_card->raw_csd, rsp + 1, 15); + /* Get CRC7 */ + RTS51X_READ_REG(chip, SD_CMD5, sd_card->raw_csd + 15); + + RTS51X_DEBUGP("CSD Response:\n"); + RTS51X_DUMP(rsp, 16); + + /* Get CSD Version */ + csd_ver = (rsp[1] & 0xc0) >> 6; + RTS51X_DEBUGP("csd_ver = %d\n", csd_ver); + + trans_speed = rsp[4]; + if ((trans_speed & 0x07) == 0x02) { /* 10Mbits/s */ + if ((trans_speed & 0xf8) >= 0x30) { /* >25Mbits/s */ + if (chip->asic_code) + sd_card->sd_clock = 46; + else + sd_card->sd_clock = CLK_50; + } else if ((trans_speed & 0xf8) == 0x28) { /* 20Mbits/s */ + if (chip->asic_code) + sd_card->sd_clock = 39; + else + sd_card->sd_clock = CLK_40; + } else if ((trans_speed & 0xf8) == 0x20) { /* 15Mbits/s */ + if (chip->asic_code) + sd_card->sd_clock = 29; + else + sd_card->sd_clock = CLK_30; + } else if ((trans_speed & 0xf8) >= 0x10) { /* 12Mbits/s */ + if (chip->asic_code) + sd_card->sd_clock = 23; + else + sd_card->sd_clock = CLK_20; + } else if ((trans_speed & 0x08) >= 0x08) { /* 10Mbits/s */ + if (chip->asic_code) + sd_card->sd_clock = 19; + else + sd_card->sd_clock = CLK_20; + } /*else { */ + /*If this ,then slow card will use 30M clock */ + /* TRACE_RET(chip, STATUS_FAIL); */ + /* } */ + } + /*else { + TRACE_RET(chip, STATUS_FAIL); + } */ + if (CHK_MMC_SECTOR_MODE(sd_card)) { + sd_card->capacity = 0; + } else { + /* For High-Capacity Card, CSD_STRUCTURE always be "0x1" */ + if ((!CHK_SD_HCXC(sd_card)) || (csd_ver == 0)) { + /* Calculate total sector according to C_SIZE, + * C_SIZE_MULT & READ_BL_LEN */ + u8 blk_size, c_size_mult; + u16 c_size; + /* Get READ_BL_LEN */ + blk_size = rsp[6] & 0x0F; + /* Get C_SIZE */ + c_size = ((u16) (rsp[7] & 0x03) << 10) + + ((u16) rsp[8] << 2) + + ((u16) (rsp[9] & 0xC0) >> 6); + /* Get C_SIZE_MUL */ + c_size_mult = (u8) ((rsp[10] & 0x03) << 1); + c_size_mult += (rsp[11] & 0x80) >> 7; + /* Calculate total Capacity */ + sd_card->capacity = + (((u32) (c_size + 1)) * + (1 << (c_size_mult + 2))) << (blk_size - 9); + } else { + /* High Capacity Card and Use CSD2.0 Version */ + u32 total_sector = 0; + total_sector = (((u32) rsp[8] & 0x3f) << 16) | + ((u32) rsp[9] << 8) | (u32) rsp[10]; + /* Total Capacity= (C_SIZE+1) * + * 512K Byte = (C_SIZE+1)K Sector,1K = 1024 Bytes */ + sd_card->capacity = (total_sector + 1) << 10; + } + } + + /* We need check Write-Protected Status by Field PERM WP or TEMP WP */ + if (check_wp) { + if (rsp[15] & 0x30) + chip->card_wp |= SD_CARD; + RTS51X_DEBUGP("CSD WP Status: 0x%x\n", rsp[15]); + } + + return STATUS_SUCCESS; +} + +static int sd_set_sample_push_timing(struct rts51x_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + + rts51x_init_cmd(chip); + + if (CHK_SD_SDR104(sd_card) || CHK_SD_SDR50(sd_card)) { + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG1, + 0x0C | SD_ASYNC_FIFO_RST, + SD_30_MODE | SD_ASYNC_FIFO_RST); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_CLK_SOURCE, 0xFF, + CRC_VAR_CLK0 | SD30_FIX_CLK | SAMPLE_VAR_CLK1); + } else if (CHK_SD_DDR50(sd_card) || CHK_MMC_DDR52(sd_card)) { + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG1, + 0x0C | SD_ASYNC_FIFO_RST, + SD_DDR_MODE | SD_ASYNC_FIFO_RST); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_CLK_SOURCE, 0xFF, + CRC_VAR_CLK0 | SD30_FIX_CLK | SAMPLE_VAR_CLK1); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_PUSH_POINT_CTL, + DDR_VAR_TX_CMD_DAT, DDR_VAR_TX_CMD_DAT); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_SAMPLE_POINT_CTL, + DDR_VAR_RX_DAT | DDR_VAR_RX_CMD, + DDR_VAR_RX_DAT | DDR_VAR_RX_CMD); + } else { + u8 val = 0; + + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG1, 0x0C, SD_20_MODE); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_CLK_SOURCE, 0xFF, + CRC_FIX_CLK | SD30_VAR_CLK0 | SAMPLE_VAR_CLK1); + + if ((chip->option.sd_ctl & SD_PUSH_POINT_CTL_MASK) == + SD_PUSH_POINT_AUTO) { + val = SD20_TX_NEG_EDGE; + } else if ((chip->option.sd_ctl & SD_PUSH_POINT_CTL_MASK) == + SD_PUSH_POINT_DELAY) { + val = SD20_TX_14_AHEAD; + } else { + val = SD20_TX_NEG_EDGE; + } + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_PUSH_POINT_CTL, + SD20_TX_SEL_MASK, val); + + if ((chip->option.sd_ctl & SD_SAMPLE_POINT_CTL_MASK) == + SD_SAMPLE_POINT_AUTO) { + if (chip->asic_code) { + if (CHK_SD_HS(sd_card) || CHK_MMC_52M(sd_card)) + val = SD20_RX_14_DELAY; + else + val = SD20_RX_POS_EDGE; + } else { + val = SD20_RX_14_DELAY; + } + } else if ((chip->option.sd_ctl & SD_SAMPLE_POINT_CTL_MASK) == + SD_SAMPLE_POINT_DELAY) { + val = SD20_RX_14_DELAY; + } else { + val = SD20_RX_POS_EDGE; + } + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_SAMPLE_POINT_CTL, + SD20_RX_SEL_MASK, val); + } + + if (CHK_MMC_DDR52(sd_card) && CHK_MMC_8BIT(sd_card)) { + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DMA1_CTL, + EXTEND_DMA1_ASYNC_SIGNAL, 0); + } + + retval = rts51x_send_cmd(chip, MODE_C, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + return STATUS_SUCCESS; +} + +static void sd_choose_proper_clock(struct rts51x_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + + if (CHK_SD_SDR104(sd_card)) { + if (chip->asic_code) + sd_card->sd_clock = chip->option.asic_sd_sdr104_clk; + else + sd_card->sd_clock = chip->option.fpga_sd_sdr104_clk; + } else if (CHK_SD_DDR50(sd_card)) { + if (chip->asic_code) + sd_card->sd_clock = chip->option.asic_sd_ddr50_clk; + else + sd_card->sd_clock = chip->option.fpga_sd_ddr50_clk; + } else if (CHK_SD_SDR50(sd_card)) { + if (chip->asic_code) + sd_card->sd_clock = chip->option.asic_sd_sdr50_clk; + else + sd_card->sd_clock = chip->option.fpga_sd_sdr50_clk; + } else if (CHK_SD_HS(sd_card)) { + if (chip->asic_code) + sd_card->sd_clock = chip->option.asic_sd_hs_clk; + else + sd_card->sd_clock = chip->option.fpga_sd_hs_clk; + } else if (CHK_MMC_52M(sd_card) || CHK_MMC_DDR52(sd_card)) { + if (chip->asic_code) + sd_card->sd_clock = chip->option.asic_mmc_52m_clk; + else + sd_card->sd_clock = chip->option.fpga_mmc_52m_clk; + } else if (CHK_MMC_26M(sd_card)) { + if (chip->asic_code) { + sd_card->sd_clock = 46; + RTS51X_DEBUGP("Set MMC clock to 22.5MHz\n"); + } else { + sd_card->sd_clock = CLK_50; + } + } +} + +static int sd_set_init_para(struct rts51x_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + + retval = sd_set_sample_push_timing(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + sd_choose_proper_clock(chip); + + retval = switch_clock(chip, sd_card->sd_clock); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + return STATUS_SUCCESS; +} + +int sd_select_card(struct rts51x_chip *chip, int select) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + u8 cmd_idx, cmd_type; + u32 addr; + + if (select) { + cmd_idx = SELECT_CARD; + cmd_type = SD_RSP_TYPE_R1; + addr = sd_card->sd_addr; + } else { + cmd_idx = DESELECT_CARD; + cmd_type = SD_RSP_TYPE_R0; + addr = 0; + } + + retval = sd_send_cmd_get_rsp(chip, cmd_idx, addr, cmd_type, NULL, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + return STATUS_SUCCESS; +} + +#ifdef SUPPORT_SD_LOCK +int sd_update_lock_status(struct rts51x_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + u8 rsp[5]; + + retval = + sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, + SD_RSP_TYPE_R1, rsp, 5); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (rsp[1] & 0x02) + sd_card->sd_lock_status |= SD_LOCKED; + else + sd_card->sd_lock_status &= ~SD_LOCKED; + + RTS51X_DEBUGP("sd_card->sd_lock_status = 0x%x\n", + sd_card->sd_lock_status); + + if (rsp[1] & 0x01) { + /* LOCK_UNLOCK_FAILED */ + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} +#endif + +int sd_wait_currentstate_dataready(struct rts51x_chip *chip, u8 statechk, + u8 rdychk, u16 pollingcnt) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + u8 rsp[5]; + u16 i; + + for (i = 0; i < pollingcnt; i++) { + + retval = + sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, + SD_RSP_TYPE_R1, rsp, 5); + if (retval == STATUS_SUCCESS) { + if (((rsp[3] & 0x1E) == statechk) + && ((rsp[3] & 0x01) == rdychk)) { + return STATUS_SUCCESS; + } + } else { + rts51x_clear_sd_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + } + + return STATUS_TIMEDOUT; +} + +static int sd_voltage_switch(struct rts51x_chip *chip) +{ + int retval; + u8 stat; + + RTS51X_WRITE_REG(chip, SD_BUS_STAT, + SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, + SD_CLK_TOGGLE_EN); + + retval = + sd_send_cmd_get_rsp(chip, VOLTAGE_SWITCH, 0, SD_RSP_TYPE_R1, NULL, + 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + RTS51X_READ_REG(chip, SD_BUS_STAT, &stat); + if (stat & (SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS | + SD_DAT1_STATUS | SD_DAT0_STATUS)) + TRACE_RET(chip, STATUS_FAIL); + + rts51x_init_cmd(chip); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BUS_STAT, 0xFF, + SD_CLK_FORCE_STOP); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_PAD_CTL, SD_IO_USING_1V8, + SD_IO_USING_1V8); + if (chip->asic_code) + rts51x_add_cmd(chip, WRITE_REG_CMD, LDO_POWER_CFG, + TUNE_SD18_MASK, TUNE_SD18_1V8); + retval = rts51x_send_cmd(chip, MODE_C, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + wait_timeout(chip->option.D3318_off_delay); + + RTS51X_WRITE_REG(chip, SD_BUS_STAT, 0xFF, SD_CLK_TOGGLE_EN); + wait_timeout(10); + + RTS51X_READ_REG(chip, SD_BUS_STAT, &stat); + if ((stat & (SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS | + SD_DAT1_STATUS | SD_DAT0_STATUS)) != + (SD_CMD_STATUS | SD_DAT3_STATUS | SD_DAT2_STATUS | + SD_DAT1_STATUS | SD_DAT0_STATUS)) { + rts51x_init_cmd(chip); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BUS_STAT, 0xFF, + SD_CLK_FORCE_STOP); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_CLK_EN, 0xFF, 0); + rts51x_send_cmd(chip, MODE_C, 100); + TRACE_RET(chip, STATUS_FAIL); + } + RTS51X_WRITE_REG(chip, SD_BUS_STAT, + SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0); + + return STATUS_SUCCESS; +} + +static int sd_change_phase(struct rts51x_chip *chip, u8 sample_point, + u8 tune_dir) +{ + u16 SD_VP_CTL, SD_DCMPS_CTL; + u8 val; + int retval; + + RTS51X_DEBUGP("sd_change_phase (sample_point = %d, tune_dir = %d)\n", + sample_point, tune_dir); + + if (tune_dir == TUNE_RX) { + SD_VP_CTL = SD_VPCLK1_CTL; + SD_DCMPS_CTL = SD_DCMPS1_CTL; + } else { + SD_VP_CTL = SD_VPCLK0_CTL; + SD_DCMPS_CTL = SD_DCMPS0_CTL; + } + + if (chip->asic_code) { + RTS51X_WRITE_REG(chip, CLK_DIV, CLK_CHANGE, CLK_CHANGE); + RTS51X_WRITE_REG(chip, SD_VP_CTL, 0x1F, sample_point); + RTS51X_WRITE_REG(chip, SD_VPCLK0_CTL, PHASE_NOT_RESET, 0); + RTS51X_WRITE_REG(chip, SD_VPCLK0_CTL, PHASE_NOT_RESET, + PHASE_NOT_RESET); + RTS51X_WRITE_REG(chip, CLK_DIV, CLK_CHANGE, 0); + } else { +#ifdef CONFIG_RTS5139_DEBUG + RTS51X_READ_REG(chip, SD_VP_CTL, &val); + RTS51X_DEBUGP("SD_VP_CTL: 0x%x\n", val); + RTS51X_READ_REG(chip, SD_DCMPS_CTL, &val); + RTS51X_DEBUGP("SD_DCMPS_CTL: 0x%x\n", val); +#endif + + RTS51X_WRITE_REG(chip, CLK_DIV, CLK_CHANGE, CLK_CHANGE); + udelay(100); + RTS51X_WRITE_REG(chip, SD_VP_CTL, 0xFF, + PHASE_NOT_RESET | sample_point); + udelay(200); + + rts51x_init_cmd(chip); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_DCMPS_CTL, DCMPS_CHANGE, + DCMPS_CHANGE); + rts51x_add_cmd(chip, CHECK_REG_CMD, SD_DCMPS_CTL, + DCMPS_CHANGE_DONE, DCMPS_CHANGE_DONE); + retval = rts51x_send_cmd(chip, MODE_CR, 100); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, Fail); + + retval = rts51x_get_rsp(chip, 1, 500); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, Fail); + + val = chip->rsp_buf[0]; + if (val & DCMPS_ERROR) + TRACE_GOTO(chip, Fail); + if ((val & DCMPS_CURRENT_PHASE) != sample_point) + TRACE_GOTO(chip, Fail); + RTS51X_WRITE_REG(chip, SD_DCMPS_CTL, DCMPS_CHANGE, 0); + RTS51X_WRITE_REG(chip, CLK_DIV, CLK_CHANGE, 0); + udelay(100); + } + + RTS51X_WRITE_REG(chip, SD_CFG1, SD_ASYNC_FIFO_RST, 0); + + return STATUS_SUCCESS; + +Fail: +#ifdef CONFIG_RTS5139_DEBUG + rts51x_ep0_read_register(chip, SD_VP_CTL, &val); + RTS51X_DEBUGP("SD_VP_CTL: 0x%x\n", val); + rts51x_ep0_read_register(chip, SD_DCMPS_CTL, &val); + RTS51X_DEBUGP("SD_DCMPS_CTL: 0x%x\n", val); +#endif + + RTS51X_WRITE_REG(chip, SD_DCMPS_CTL, DCMPS_CHANGE, 0); + RTS51X_WRITE_REG(chip, SD_VP_CTL, PHASE_CHANGE, 0); + wait_timeout(10); + + return STATUS_FAIL; +} + +static int sd_check_spec(struct rts51x_chip *chip, u8 bus_width) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + u8 cmd[5], buf[8]; + + retval = + sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, SD_RSP_TYPE_R1, + NULL, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + cmd[0] = 0x40 | SEND_SCR; + cmd[1] = 0; + cmd[2] = 0; + cmd[3] = 0; + cmd[4] = 0; + + retval = + sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, 8, 1, bus_width, buf, + 8, 250); + if (retval != STATUS_SUCCESS) { + rts51x_clear_sd_error(chip); + TRACE_RET(chip, retval); + } + + memcpy(sd_card->raw_scr, buf, 8); + + if ((buf[0] & 0x0F) == 0) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +static int sd_query_switch_result(struct rts51x_chip *chip, u8 func_group, + u8 func_to_switch, u8 *buf, int buf_len) +{ + u8 support_mask = 0, query_switch = 0, switch_busy = 0; + int support_offset = 0, query_switch_offset = 0, check_busy_offset = 0; + + if (func_group == SD_FUNC_GROUP_1) { + support_offset = FUNCTION_GROUP1_SUPPORT_OFFSET; + query_switch_offset = FUNCTION_GROUP1_QUERY_SWITCH_OFFSET; + check_busy_offset = FUNCTION_GROUP1_CHECK_BUSY_OFFSET; + + switch (func_to_switch) { + case HS_SUPPORT: + support_mask = HS_SUPPORT_MASK; + query_switch = HS_QUERY_SWITCH_OK; + switch_busy = HS_SWITCH_BUSY; + break; + + case SDR50_SUPPORT: + support_mask = SDR50_SUPPORT_MASK; + query_switch = SDR50_QUERY_SWITCH_OK; + switch_busy = SDR50_SWITCH_BUSY; + break; + + case SDR104_SUPPORT: + support_mask = SDR104_SUPPORT_MASK; + query_switch = SDR104_QUERY_SWITCH_OK; + switch_busy = SDR104_SWITCH_BUSY; + break; + + case DDR50_SUPPORT: + support_mask = DDR50_SUPPORT_MASK; + query_switch = DDR50_QUERY_SWITCH_OK; + switch_busy = DDR50_SWITCH_BUSY; + break; + + default: + TRACE_RET(chip, STATUS_FAIL); + } + } else if (func_group == SD_FUNC_GROUP_3) { + support_offset = FUNCTION_GROUP3_SUPPORT_OFFSET; + query_switch_offset = FUNCTION_GROUP3_QUERY_SWITCH_OFFSET; + check_busy_offset = FUNCTION_GROUP3_CHECK_BUSY_OFFSET; + + switch (func_to_switch) { + case DRIVING_TYPE_A: + support_mask = DRIVING_TYPE_A_MASK; + query_switch = TYPE_A_QUERY_SWITCH_OK; + switch_busy = TYPE_A_SWITCH_BUSY; + break; + + case DRIVING_TYPE_C: + support_mask = DRIVING_TYPE_C_MASK; + query_switch = TYPE_C_QUERY_SWITCH_OK; + switch_busy = TYPE_C_SWITCH_BUSY; + break; + + case DRIVING_TYPE_D: + support_mask = DRIVING_TYPE_D_MASK; + query_switch = TYPE_D_QUERY_SWITCH_OK; + switch_busy = TYPE_D_SWITCH_BUSY; + break; + + default: + TRACE_RET(chip, STATUS_FAIL); + } + } else if (func_group == SD_FUNC_GROUP_4) { + support_offset = FUNCTION_GROUP4_SUPPORT_OFFSET; + query_switch_offset = FUNCTION_GROUP4_QUERY_SWITCH_OFFSET; + check_busy_offset = FUNCTION_GROUP4_CHECK_BUSY_OFFSET; + + switch (func_to_switch) { + case CURRENT_LIMIT_400: + support_mask = CURRENT_LIMIT_400_MASK; + query_switch = CURRENT_LIMIT_400_QUERY_SWITCH_OK; + switch_busy = CURRENT_LIMIT_400_SWITCH_BUSY; + break; + + case CURRENT_LIMIT_600: + support_mask = CURRENT_LIMIT_600_MASK; + query_switch = CURRENT_LIMIT_600_QUERY_SWITCH_OK; + switch_busy = CURRENT_LIMIT_600_SWITCH_BUSY; + break; + + case CURRENT_LIMIT_800: + support_mask = CURRENT_LIMIT_800_MASK; + query_switch = CURRENT_LIMIT_800_QUERY_SWITCH_OK; + switch_busy = CURRENT_LIMIT_800_SWITCH_BUSY; + break; + + default: + TRACE_RET(chip, STATUS_FAIL); + } + } else { + TRACE_RET(chip, STATUS_FAIL); + } + + if (func_group == SD_FUNC_GROUP_4) + buf[query_switch_offset] = + (buf[query_switch_offset] & 0xf0) >> 4; + if (!(buf[support_offset] & support_mask) || + ((buf[query_switch_offset] & 0x0F) != query_switch)) + TRACE_RET(chip, STATUS_FAIL); + + if ((buf[DATA_STRUCTURE_VER_OFFSET] == 0x01) && + ((buf[check_busy_offset] & switch_busy) == switch_busy)) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +static int sd_check_switch_mode(struct rts51x_chip *chip, u8 mode, + u8 func_group, u8 func_to_switch, u8 bus_width) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + u8 cmd[5], buf[64]; + + RTS51X_DEBUGP("sd_check_switch_mode (mode = %d, func_group = %d," + "func_to_switch = %d)\n", mode, func_group, func_to_switch); + + cmd[0] = 0x40 | SWITCH; + cmd[1] = mode; + + if (func_group == SD_FUNC_GROUP_1) { + cmd[2] = 0xFF; + cmd[3] = 0xFF; + cmd[4] = 0xF0 + func_to_switch; + } else if (func_group == SD_FUNC_GROUP_3) { + cmd[2] = 0xFF; + cmd[3] = 0xF0 + func_to_switch; + cmd[4] = 0xFF; + } else if (func_group == SD_FUNC_GROUP_4) { + cmd[2] = 0xFF; + cmd[3] = 0x0F + (func_to_switch << 4); + cmd[4] = 0xFF; + } else { + cmd[1] = SD_CHECK_MODE; + cmd[2] = 0xFF; + cmd[3] = 0xFF; + cmd[4] = 0xFF; + } + + retval = + sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, 64, 1, bus_width, buf, + 64, 250); + if (retval != STATUS_SUCCESS) { + rts51x_clear_sd_error(chip); + TRACE_RET(chip, retval); + } + + if (func_group == NO_ARGUMENT) { + sd_card->func_group1_mask = buf[0x0D]; + sd_card->func_group2_mask = buf[0x0B]; + sd_card->func_group3_mask = buf[0x09]; + sd_card->func_group4_mask = buf[0x07]; + + RTS51X_DEBUGP("func_group1_mask = 0x%02x\n", buf[0x0D]); + RTS51X_DEBUGP("func_group2_mask = 0x%02x\n", buf[0x0B]); + RTS51X_DEBUGP("func_group3_mask = 0x%02x\n", buf[0x09]); + RTS51X_DEBUGP("func_group4_mask = 0x%02x\n", buf[0x07]); + } else { + if ((buf[0] == 0) && (buf[1] == 0)) + TRACE_RET(chip, STATUS_FAIL); + retval = + sd_query_switch_result(chip, func_group, func_to_switch, + buf, 64); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } + + return STATUS_SUCCESS; +} + +static int sd_check_switch(struct rts51x_chip *chip, + u8 func_group, u8 func_to_switch, u8 bus_width) +{ + int retval; + int i; + int switch_good = 0; + + for (i = 0; i < 3; i++) { + if (monitor_card_cd(chip, SD_CARD) == CD_NOT_EXIST) { + sd_set_reset_fail(chip, SD_RESET_FAIL); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sd_check_switch_mode(chip, SD_CHECK_MODE, func_group, + func_to_switch, bus_width); + if (retval == STATUS_SUCCESS) { + u8 stat; + + retval = sd_check_switch_mode(chip, SD_SWITCH_MODE, + func_group, func_to_switch, bus_width); + if (retval == STATUS_SUCCESS) { + switch_good = 1; + break; + } + + RTS51X_READ_REG(chip, SD_STAT1, &stat); + + if (stat & SD_CRC16_ERR) { + RTS51X_DEBUGP("SD CRC16 error when switching" + "mode\n"); + TRACE_RET(chip, STATUS_FAIL); + } + } + + wait_timeout(20); + } + + if (!switch_good) + TRACE_RET(chip, STATUS_FAIL); + + return STATUS_SUCCESS; +} + +static int sd_switch_function(struct rts51x_chip *chip, u8 bus_width) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + int i; + u8 func_to_switch = 0; + + /* Get supported functions */ + retval = sd_check_switch_mode(chip, SD_CHECK_MODE, + NO_ARGUMENT, NO_ARGUMENT, bus_width); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + sd_card->func_group1_mask &= ~(sd_card->sd_switch_fail); + + for (i = 0; i < 4; i++) { + switch ((u8) (chip->option.sd_speed_prior >> (i * 8))) { + case DDR50_SUPPORT: + if ((sd_card->func_group1_mask & DDR50_SUPPORT_MASK) + && (CHECK_UHS50(chip))) + func_to_switch = DDR50_SUPPORT; + break; + + case SDR50_SUPPORT: + if ((sd_card->func_group1_mask & SDR50_SUPPORT_MASK) + && (CHECK_UHS50(chip))) + func_to_switch = SDR50_SUPPORT; + break; + + case HS_SUPPORT: + if (sd_card->func_group1_mask & HS_SUPPORT_MASK) + func_to_switch = HS_SUPPORT; + break; + + default: + continue; + } + + if (func_to_switch) + break; + } + RTS51X_DEBUGP("SD_FUNC_GROUP_1: func_to_switch = 0x%02x", + func_to_switch); + +#ifdef SUPPORT_SD_LOCK + if ((sd_card->sd_lock_status & SD_SDR_RST) + && (DDR50_SUPPORT == func_to_switch) + && (sd_card->func_group1_mask & SDR50_SUPPORT_MASK)) { + func_to_switch = SDR50_SUPPORT; + RTS51X_DEBUGP("Using SDR50 instead of DDR50 for SD Lock\n"); + } +#endif + + if (func_to_switch) { + retval = + sd_check_switch(chip, SD_FUNC_GROUP_1, func_to_switch, + bus_width); + if (retval != STATUS_SUCCESS) { + if (func_to_switch == SDR104_SUPPORT) + sd_card->sd_switch_fail = SDR104_SUPPORT_MASK; + else if (func_to_switch == DDR50_SUPPORT) + sd_card->sd_switch_fail = DDR50_SUPPORT_MASK; + else if (func_to_switch == SDR50_SUPPORT) + sd_card->sd_switch_fail = SDR50_SUPPORT_MASK; + else if (func_to_switch == HS_SUPPORT) + sd_card->sd_switch_fail = HS_SUPPORT_MASK; + + TRACE_RET(chip, retval); + } + + if (func_to_switch == SDR104_SUPPORT) + SET_SD_SDR104(sd_card); + else if (func_to_switch == DDR50_SUPPORT) + SET_SD_DDR50(sd_card); + else if (func_to_switch == SDR50_SUPPORT) + SET_SD_SDR50(sd_card); + else + SET_SD_HS(sd_card); + } + + if (CHK_SD_DDR50(sd_card)) + RTS51X_WRITE_REG(chip, SD_CFG1, 0x0C, SD_DDR_MODE); + + func_to_switch = 0; + if (sd_card->func_group4_mask & CURRENT_LIMIT_400_MASK) + func_to_switch = CURRENT_LIMIT_400; + + if (func_to_switch) { + RTS51X_DEBUGP("Try to switch current_limit_400\n"); + retval = + sd_check_switch(chip, SD_FUNC_GROUP_4, func_to_switch, + bus_width); + RTS51X_DEBUGP("Switch current_limit_400 status: (%d)\n", + retval); + } + + return STATUS_SUCCESS; +} + +static int sd_wait_data_idle(struct rts51x_chip *chip) +{ + int retval = STATUS_TIMEDOUT; + int i; + u8 val = 0; + + for (i = 0; i < 100; i++) { + retval = rts51x_ep0_read_register(chip, SD_DATA_STATE, &val); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + if (val & SD_DATA_IDLE) { + retval = STATUS_SUCCESS; + break; + } + udelay(100); + } + RTS51X_DEBUGP("SD_DATA_STATE: 0x%02x\n", val); + + return retval; +} + +static int sd_sdr_tuning_rx_cmd(struct rts51x_chip *chip, u8 sample_point) +{ + int retval; + u8 cmd[5]; + + retval = sd_change_phase(chip, sample_point, TUNE_RX); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + cmd[0] = 0x40 | SEND_TUNING_PATTERN; + cmd[1] = 0; + cmd[2] = 0; + cmd[3] = 0; + cmd[4] = 0; + + retval = sd_read_data(chip, SD_TM_AUTO_TUNING, + cmd, 5, 0x40, 1, SD_BUS_WIDTH_4, NULL, 0, 100); + if (retval != STATUS_SUCCESS) { + /* Wait till SD DATA IDLE */ + (void)sd_wait_data_idle(chip); + + rts51x_clear_sd_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int sd_ddr_tuning_rx_cmd(struct rts51x_chip *chip, u8 sample_point) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + u8 cmd[5]; + + retval = sd_change_phase(chip, sample_point, TUNE_RX); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + RTS51X_DEBUGP("sd ddr tuning rx\n"); + + retval = + sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, SD_RSP_TYPE_R1, + NULL, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + cmd[0] = 0x40 | SD_STATUS; + cmd[1] = 0; + cmd[2] = 0; + cmd[3] = 0; + cmd[4] = 0; + + retval = sd_read_data(chip, SD_TM_NORMAL_READ, + cmd, 5, 64, 1, SD_BUS_WIDTH_4, NULL, 0, 100); + if (retval != STATUS_SUCCESS) { + /* Wait till SD DATA IDLE */ + (void)sd_wait_data_idle(chip); + + rts51x_clear_sd_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int mmc_ddr_tunning_rx_cmd(struct rts51x_chip *chip, u8 sample_point) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + u8 cmd[5], bus_width; + + if (CHK_MMC_8BIT(sd_card)) + bus_width = SD_BUS_WIDTH_8; + else if (CHK_MMC_4BIT(sd_card)) + bus_width = SD_BUS_WIDTH_4; + else + bus_width = SD_BUS_WIDTH_1; + + retval = sd_change_phase(chip, sample_point, TUNE_RX); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + RTS51X_DEBUGP("mmc ddr tuning rx\n"); + + cmd[0] = 0x40 | SEND_EXT_CSD; + cmd[1] = 0; + cmd[2] = 0; + cmd[3] = 0; + cmd[4] = 0; + + retval = sd_read_data(chip, SD_TM_NORMAL_READ, + cmd, 5, 0x200, 1, bus_width, NULL, 0, 100); + if (retval != STATUS_SUCCESS) { + /* Wait till SD DATA IDLE */ + (void)sd_wait_data_idle(chip); + + rts51x_clear_sd_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int sd_sdr_tuning_tx_cmd(struct rts51x_chip *chip, u8 sample_point) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + + retval = sd_change_phase(chip, sample_point, TUNE_TX); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + RTS51X_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, + SD_RSP_80CLK_TIMEOUT_EN); + + retval = sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0); + if (retval != STATUS_SUCCESS) { + if (sd_check_err_code(chip, SD_RSP_TIMEOUT)) { + /* Tunning TX fail */ + rts51x_ep0_write_register(chip, SD_CFG3, + SD_RSP_80CLK_TIMEOUT_EN, 0); + TRACE_RET(chip, STATUS_FAIL); + } + } + + RTS51X_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, 0); + + return STATUS_SUCCESS; +} + +static int sd_ddr_tuning_tx_cmd(struct rts51x_chip *chip, u8 sample_point) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + u8 cmd[5], bus_width; + + retval = sd_change_phase(chip, sample_point, TUNE_TX); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + if (CHK_SD(sd_card)) { + bus_width = SD_BUS_WIDTH_4; + } else { + if (CHK_MMC_8BIT(sd_card)) + bus_width = SD_BUS_WIDTH_8; + else if (CHK_MMC_4BIT(sd_card)) + bus_width = SD_BUS_WIDTH_4; + else + bus_width = SD_BUS_WIDTH_1; + } + retval = sd_wait_currentstate_dataready(chip, 0x08, 1, 20); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + RTS51X_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, + SD_RSP_80CLK_TIMEOUT_EN); + + cmd[0] = 0x40 | PROGRAM_CSD; + cmd[1] = 0; + cmd[2] = 0; + cmd[3] = 0; + cmd[4] = 0; + + retval = sd_write_data(chip, SD_TM_AUTO_WRITE_2, + cmd, 5, 16, 1, bus_width, sd_card->raw_csd, 16, 100); + if (retval != STATUS_SUCCESS) { + rts51x_clear_sd_error(chip); + /* Tunning TX fail */ + rts51x_ep0_write_register(chip, SD_CFG3, + SD_RSP_80CLK_TIMEOUT_EN, 0); + TRACE_RET(chip, STATUS_FAIL); + } + + RTS51X_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, 0); + + sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, SD_RSP_TYPE_R1, + NULL, 0); + + return STATUS_SUCCESS; +} + +static u8 sd_search_final_phase(struct rts51x_chip *chip, u32 phase_map, + u8 tune_dir) +{ + struct sd_info *sd_card = &(chip->sd_card); + struct timing_phase_path path[MAX_PHASE + 1]; + int i, j, cont_path_cnt; + int new_block, max_len; + u8 final_phase = 0xFF; + int final_path_idx; + + if (phase_map == 0xffff) { + if (CHK_SD_DDR50(sd_card)) { + if (tune_dir == TUNE_TX) + final_phase = chip->option.ddr50_tx_phase; + else + final_phase = chip->option.ddr50_rx_phase; + RTS51X_DEBUGP("DDR50 tuning dir:%d all pass," + "so select default phase:0x%x.\n", + tune_dir, final_phase); + } else { + if (tune_dir == TUNE_TX) + final_phase = chip->option.sdr50_tx_phase; + else + final_phase = chip->option.sdr50_rx_phase; + RTS51X_DEBUGP("SDR50 tuning dir:%d all pass," + "so select default phase:0x%x.\n", + tune_dir, final_phase); + } + goto Search_Finish; + } + + cont_path_cnt = 0; + new_block = 1; + j = 0; + for (i = 0; i < MAX_PHASE + 1; i++) { + if (phase_map & (1 << i)) { + if (new_block) { + new_block = 0; + j = cont_path_cnt++; + path[j].start = i; + path[j].end = i; + } else { + path[j].end = i; + } + } else { + new_block = 1; + if (cont_path_cnt) { + int idx = cont_path_cnt - 1; + path[idx].len = + path[idx].end - path[idx].start + 1; + path[idx].mid = + path[idx].start + path[idx].len / 2; + } + } + } + + if (cont_path_cnt == 0) { + RTS51X_DEBUGP("No continuous phase path\n"); + goto Search_Finish; + } else { + int idx = cont_path_cnt - 1; + path[idx].len = path[idx].end - path[idx].start + 1; + path[idx].mid = path[idx].start + path[idx].len / 2; + } + + if ((path[0].start == 0) && + (path[cont_path_cnt - 1].end == MAX_PHASE)) { + path[0].start = path[cont_path_cnt - 1].start - MAX_PHASE - 1; + path[0].len += path[cont_path_cnt - 1].len; + path[0].mid = path[0].start + path[0].len / 2; + if (path[0].mid < 0) + path[0].mid += MAX_PHASE + 1; + cont_path_cnt--; + } + max_len = 0; + final_phase = 0; + final_path_idx = 0; + for (i = 0; i < cont_path_cnt; i++) { + if (path[i].len > max_len) { + max_len = path[i].len; + final_phase = (u8) path[i].mid; + final_path_idx = i; + } + + RTS51X_DEBUGP("path[%d].start = %d\n", i, path[i].start); + RTS51X_DEBUGP("path[%d].end = %d\n", i, path[i].end); + RTS51X_DEBUGP("path[%d].len = %d\n", i, path[i].len); + RTS51X_DEBUGP("path[%d].mid = %d\n", i, path[i].mid); + RTS51X_DEBUGP("\n"); + } + + if ((tune_dir == TUNE_TX) && (CHK_SD_SDR50(sd_card)) + && chip->option.sdr50_phase_sel) { + if (max_len > 6) { + int temp_mid = (max_len - 6) / 2; + int temp_final_phase = + path[final_path_idx].end - (max_len - + (3 + temp_mid)); + + if (temp_final_phase < 0) + final_phase = temp_final_phase + MAX_PHASE + 1; + else + final_phase = (u8) temp_final_phase; + } + } + +Search_Finish: + RTS51X_DEBUGP("Final choosen phase: %d\n", final_phase); + return final_phase; +} + +static int sd_tuning_rx(struct rts51x_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + int i, j; + u32 raw_phase_map[3], phase_map; + u8 final_phase; + int (*tuning_cmd) (struct rts51x_chip *chip, u8 sample_point); + + if (CHK_SD(sd_card)) { + if (CHK_SD_DDR50(sd_card)) + tuning_cmd = sd_ddr_tuning_rx_cmd; + else + tuning_cmd = sd_sdr_tuning_rx_cmd; + } else { + if (CHK_MMC_DDR52(sd_card)) + tuning_cmd = mmc_ddr_tunning_rx_cmd; + else + TRACE_RET(chip, STATUS_FAIL); + } + + for (i = 0; i < 3; i++) { + raw_phase_map[i] = 0; + for (j = MAX_PHASE; j >= 0; j--) { + if (monitor_card_cd(chip, SD_CARD) == CD_NOT_EXIST) { + sd_set_reset_fail(chip, SD_RESET_FAIL); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = tuning_cmd(chip, (u8) j); + if (retval == STATUS_SUCCESS) + raw_phase_map[i] |= 1 << j; + else + RTS51X_DEBUGP("Tuning phase %d fail\n", j); + } + } + + phase_map = raw_phase_map[0] & raw_phase_map[1] & raw_phase_map[2]; + for (i = 0; i < 3; i++) + RTS51X_DEBUGP("RX raw_phase_map[%d] = 0x%04x\n", i, + raw_phase_map[i]); + RTS51X_DEBUGP("RX phase_map = 0x%04x\n", phase_map); + + final_phase = sd_search_final_phase(chip, phase_map, TUNE_RX); + if (final_phase == 0xFF) + TRACE_RET(chip, STATUS_FAIL); + + retval = tuning_cmd(chip, final_phase); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + return STATUS_SUCCESS; +} + +static int sd_ddr_pre_tuning_tx(struct rts51x_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + u8 i; + u8 pre_tune_tx_phase; + u32 pre_tune_phase_map; + + RTS51X_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, + SD_RSP_80CLK_TIMEOUT_EN); + + pre_tune_tx_phase = 0xFF; + pre_tune_phase_map = 0x0000; + for (i = 0; i < MAX_PHASE + 1; i++) { + if (monitor_card_cd(chip, SD_CARD) == CD_NOT_EXIST) { + sd_set_reset_fail(chip, SD_RESET_FAIL); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = sd_change_phase(chip, (u8) i, TUNE_TX); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = + sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0); + if ((retval == STATUS_SUCCESS) + || !sd_check_err_code(chip, SD_RSP_TIMEOUT)) + pre_tune_phase_map |= (u32) 1 << i; + } + + RTS51X_WRITE_REG(chip, SD_CFG3, SD_RSP_80CLK_TIMEOUT_EN, 0); + + pre_tune_tx_phase = + sd_search_final_phase(chip, pre_tune_phase_map, TUNE_TX); + if (pre_tune_tx_phase == 0xFF) + TRACE_RET(chip, STATUS_FAIL); + + sd_change_phase(chip, pre_tune_tx_phase, TUNE_TX); + RTS51X_DEBUGP("DDR TX pre tune phase: %d\n", (int)pre_tune_tx_phase); + + return STATUS_SUCCESS; +} + +static int sd_tuning_tx(struct rts51x_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + int i, j; + u32 raw_phase_map[3], phase_map; + u8 final_phase; + int (*tuning_cmd) (struct rts51x_chip *chip, u8 sample_point); + + if (CHK_SD(sd_card)) { + if (CHK_SD_DDR50(sd_card)) + tuning_cmd = sd_ddr_tuning_tx_cmd; + else + tuning_cmd = sd_sdr_tuning_tx_cmd; + } else { + if (CHK_MMC_DDR52(sd_card)) + tuning_cmd = sd_ddr_tuning_tx_cmd; + else + TRACE_RET(chip, STATUS_FAIL); + } + + for (i = 0; i < 3; i++) { + raw_phase_map[i] = 0; + for (j = MAX_PHASE; j >= 0; j--) { + if (monitor_card_cd(chip, SD_CARD) == CD_NOT_EXIST) { + sd_set_reset_fail(chip, SD_RESET_FAIL); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = tuning_cmd(chip, (u8) j); + if (retval == STATUS_SUCCESS) + raw_phase_map[i] |= 1 << j; + else + RTS51X_DEBUGP("Tuning phase %d fail\n", j); + } + } + + phase_map = raw_phase_map[0] & raw_phase_map[1] & raw_phase_map[2]; + for (i = 0; i < 3; i++) + RTS51X_DEBUGP("TX raw_phase_map[%d] = 0x%04x\n", i, + raw_phase_map[i]); + RTS51X_DEBUGP("TX phase_map = 0x%04x\n", phase_map); + + final_phase = sd_search_final_phase(chip, phase_map, TUNE_TX); + if (final_phase == 0xFF) + TRACE_RET(chip, STATUS_FAIL); + + retval = tuning_cmd(chip, final_phase); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + return STATUS_SUCCESS; +} + +static int sd_sdr_tuning(struct rts51x_chip *chip) +{ + int retval; + + retval = sd_tuning_tx(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = sd_tuning_rx(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + return STATUS_SUCCESS; +} + +static int sd_ddr_tuning(struct rts51x_chip *chip) +{ + int retval; + + if (!(chip->option.sd_ctl & SD_DDR_TX_PHASE_SET_BY_USER)) { + retval = sd_ddr_pre_tuning_tx(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } else { + retval = + sd_change_phase(chip, (u8) chip->option.sd_ddr_tx_phase, + TUNE_TX); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } + + retval = sd_tuning_rx(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + if (!(chip->option.sd_ctl & SD_DDR_TX_PHASE_SET_BY_USER)) { + retval = sd_tuning_tx(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } + + return STATUS_SUCCESS; +} + +static int mmc_ddr_tuning(struct rts51x_chip *chip) +{ + int retval; + + if (!(chip->option.sd_ctl & MMC_DDR_TX_PHASE_SET_BY_USER)) { + retval = sd_ddr_pre_tuning_tx(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } else { + retval = + sd_change_phase(chip, (u8) chip->option.mmc_ddr_tx_phase, + TUNE_TX); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } + + retval = sd_tuning_rx(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + if (!(chip->option.sd_ctl & MMC_DDR_TX_PHASE_SET_BY_USER)) { + retval = sd_tuning_tx(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } + + return STATUS_SUCCESS; +} + +int sd_switch_clock(struct rts51x_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + int re_tuning = 0; + + retval = rts51x_select_card(chip, SD_CARD); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + if (CHK_SD30_SPEED(sd_card) || CHK_MMC_DDR52(sd_card)) { + if (sd_card->sd_clock != chip->cur_clk) + re_tuning = 1; + } + + retval = switch_clock(chip, sd_card->sd_clock); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + if (re_tuning) { + if (CHK_SD(sd_card)) { + if (CHK_SD_DDR50(sd_card)) + retval = sd_ddr_tuning(chip); + else + retval = sd_sdr_tuning(chip); + } else { + if (CHK_MMC_DDR52(sd_card)) + retval = mmc_ddr_tuning(chip); + } + + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } + + return STATUS_SUCCESS; +} + +static int sd_prepare_reset(struct rts51x_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + + if (chip->asic_code) + sd_card->sd_clock = 29; + else + sd_card->sd_clock = CLK_30; + + /* Set SD Clocks */ + retval = sd_set_init_para(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + rts51x_init_cmd(chip); + + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG1, 0xFF, + SD_CLK_DIVIDE_128 | SD_20_MODE | SD_BUS_WIDTH_1); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_SAMPLE_POINT_CTL, 0xFF, + SD20_RX_POS_EDGE); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_PUSH_POINT_CTL, 0xFF, 0); + + retval = rts51x_send_cmd(chip, MODE_C, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = rts51x_select_card(chip, SD_CARD); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + return STATUS_SUCCESS; +} + +static void sd_pull_ctl_disable(struct rts51x_chip *chip) +{ + if (CHECK_PKG(chip, LQFP48)) { + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x55); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x95); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x55); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0xA5); + } else { + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x65); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x95); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x56); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0x59); + } +} + +static void sd_pull_ctl_enable(struct rts51x_chip *chip) +{ + if (CHECK_PKG(chip, LQFP48)) { + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0xAA); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0xAA); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0xA9); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x55); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0xA5); + } else { + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0xA5); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x9A); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0xA5); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x9A); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x65); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0x5A); + } +} + +static int sd_init_power(struct rts51x_chip *chip) +{ + int retval; + + rts51x_init_cmd(chip); + + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, LDO3318_PWR_MASK, + LDO_ON); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_PAD_CTL, SD_IO_USING_1V8, + SD_IO_USING_3V3); + if (chip->asic_code) + rts51x_add_cmd(chip, WRITE_REG_CMD, LDO_POWER_CFG, + TUNE_SD18_MASK, TUNE_SD18_3V3); + if (chip->asic_code) + sd_pull_ctl_disable(chip); + else + rts51x_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, + FPGA_SD_PULL_CTL_BIT | 0x20, + FPGA_SD_PULL_CTL_BIT); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_OE, SD_OUTPUT_EN, 0); + if (!chip->option.FT2_fast_mode) + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, POWER_MASK, + POWER_OFF); + + retval = rts51x_send_cmd(chip, MODE_C, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + if (!chip->option.FT2_fast_mode) { +#ifdef SD_XD_IO_FOLLOW_PWR + if (CHECK_PKG(chip, LQFP48) + || chip->option.rts5129_D3318_off_enable) + rts51x_write_register(chip, CARD_PWR_CTL, + LDO_OFF, LDO_OFF); +#endif + wait_timeout(250); + +#ifdef SD_XD_IO_FOLLOW_PWR + if (CHECK_PKG(chip, LQFP48) + || chip->option.rts5129_D3318_off_enable) { + rts51x_init_cmd(chip); + if (chip->asic_code) + sd_pull_ctl_enable(chip); + else + rts51x_add_cmd(chip, WRITE_REG_CMD, + FPGA_PULL_CTL, + FPGA_SD_PULL_CTL_BIT | 0x20, 0); + retval = rts51x_send_cmd(chip, MODE_C, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } else { + if (chip->asic_code) + rts51x_write_register(chip, CARD_PULL_CTL6, + 0x03, 0x00); + } +#endif + + /* Power on card */ + retval = card_power_on(chip, SD_CARD); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + wait_timeout(260); + +#ifdef SUPPORT_OCP + rts51x_get_card_status(chip, &(chip->card_status)); + chip->ocp_stat = (chip->card_status >> 4) & 0x03; + + if (chip->ocp_stat & (MS_OCP_NOW | MS_OCP_EVER)) { + RTS51X_DEBUGP("Over current, OCPSTAT is 0x%x\n", + chip->ocp_stat); + TRACE_RET(chip, STATUS_FAIL); + } +#endif + } + + rts51x_init_cmd(chip); + if (chip->asic_code) { + sd_pull_ctl_enable(chip); + } else { + rts51x_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, + FPGA_SD_PULL_CTL_BIT | 0x20, 0); + } + retval = rts51x_send_cmd(chip, MODE_C, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); +#ifdef SD_XD_IO_FOLLOW_PWR + rts51x_write_register(chip, CARD_INT_PEND, XD_INT | MS_INT | SD_INT, + XD_INT | MS_INT | SD_INT); +#endif + + RTS51X_WRITE_REG(chip, CARD_OE, SD_OUTPUT_EN, SD_OUTPUT_EN); + + return STATUS_SUCCESS; +} + +static int sd_dummy_clock(struct rts51x_chip *chip) +{ + RTS51X_WRITE_REG(chip, SD_BUS_STAT, SD_CLK_TOGGLE_EN, SD_CLK_TOGGLE_EN); + wait_timeout(5); + RTS51X_WRITE_REG(chip, SD_BUS_STAT, SD_CLK_TOGGLE_EN, 0x00); + + return STATUS_SUCCESS; +} + +int reset_sd(struct rts51x_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval, i = 0, j = 0, k = 0, hi_cap_flow = 0; + int sd_dont_switch = 0; + int support_1v8 = 0; + u8 rsp[16]; + u8 switch_bus_width; + u32 voltage = 0; + u8 cmd[5], buf[64]; + u16 sd_card_type; + + SET_SD(sd_card); + CLR_RETRY_SD20_MODE(sd_card); +Switch_Fail: + i = 0; + j = 0; + k = 0; + hi_cap_flow = 0; + support_1v8 = 0; +#ifdef SUPPORT_SD_LOCK + if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON) + goto SD_UNLOCK_ENTRY; +#endif + + retval = sd_prepare_reset(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + sd_dummy_clock(chip); + + /* Start Initialization Process of SD Card */ +RTY_SD_RST: + retval = + sd_send_cmd_get_rsp(chip, GO_IDLE_STATE, 0, SD_RSP_TYPE_R0, NULL, + 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + wait_timeout(20); + + retval = + sd_send_cmd_get_rsp(chip, SEND_IF_COND, 0x000001AA, SD_RSP_TYPE_R7, + rsp, 5); + if (retval == STATUS_SUCCESS) { + if ((rsp[4] == 0xAA) && ((rsp[3] & 0x0f) == 0x01)) { + hi_cap_flow = 1; + if (CHK_RETRY_SD20_MODE(sd_card)) { + voltage = + SUPPORT_VOLTAGE | + SUPPORT_HIGH_AND_EXTENDED_CAPACITY; + } else { + voltage = + SUPPORT_VOLTAGE | + SUPPORT_HIGH_AND_EXTENDED_CAPACITY | + SUPPORT_MAX_POWER_PERMANCE | SUPPORT_1V8; + } + } + } + + if (!hi_cap_flow) { + voltage = SUPPORT_VOLTAGE; + + retval = + sd_send_cmd_get_rsp(chip, GO_IDLE_STATE, 0, SD_RSP_TYPE_R0, + NULL, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + wait_timeout(20); + } + + /* ACMD41 */ + do { + { + u8 temp = 0; + rts51x_read_register(chip, CARD_INT_PEND, &temp); + RTS51X_DEBUGP("CARD_INT_PEND:%x\n", temp); + if (temp & SD_INT) { + chip->reset_need_retry = 1; + rts51x_write_register(chip, CARD_INT_PEND, + XD_INT | SD_INT | MS_INT, + XD_INT | SD_INT | MS_INT); + sd_set_reset_fail(chip, SD_RESET_FAIL); + TRACE_RET(chip, STATUS_FAIL); + } + } + +RTY_CMD55: + retval = + sd_send_cmd_get_rsp(chip, APP_CMD, 0, SD_RSP_TYPE_R1, NULL, + 0); + if (retval != STATUS_SUCCESS) { + if (monitor_card_cd(chip, SD_CARD) == CD_NOT_EXIST) { + sd_set_reset_fail(chip, SD_RESET_FAIL); + TRACE_RET(chip, STATUS_FAIL); + } + + j++; + if (chip->option.speed_mmc) { + if (j < 2) + goto RTY_CMD55; + else + TRACE_RET(chip, STATUS_FAIL); + } else { + if (j < 3) + goto RTY_SD_RST; + else + TRACE_RET(chip, STATUS_FAIL); + } + } + + retval = + sd_send_cmd_get_rsp(chip, SD_APP_OP_COND, voltage, + SD_RSP_TYPE_R3, rsp, 5); + if (retval != STATUS_SUCCESS) { + k++; + if (k < 3) + goto RTY_SD_RST; + else + TRACE_RET(chip, STATUS_FAIL); + } + + i++; + wait_timeout(20); + } while (!(rsp[1] & 0x80) && (i < 255)); /* Not complete power on */ + + if (i == 255) { + /* Time out */ + TRACE_RET(chip, STATUS_FAIL); + } + + if (hi_cap_flow) { + if (rsp[1] & 0x40) + SET_SD_HCXC(sd_card); + else + CLR_SD_HCXC(sd_card); + if (!CHK_RETRY_SD20_MODE(sd_card)) { + if ((CHK_SD_HCXC(sd_card)) && (CHECK_UHS50(chip))) { + support_1v8 = (rsp[1] & 0x01) ? 1 : 0; + RTS51X_DEBUGP("support_1v8 = %d\n", + support_1v8); + } + } + } else { + CLR_SD_HCXC(sd_card); + support_1v8 = 0; + } + + /* CMD11: Switch Voltage */ + if (support_1v8 && CHECK_UHS50(chip) + && !(((u8) chip->option.sd_speed_prior & SDR104_SUPPORT) == + HS_SUPPORT)) { + retval = sd_voltage_switch(chip); + if (retval != STATUS_SUCCESS) { + SET_RETRY_SD20_MODE(sd_card); + sd_init_power(chip); + RTS51X_DEBUGP("1.8v switch fail\n"); + goto Switch_Fail; + } + } + + /* CMD 2 */ + retval = + sd_send_cmd_get_rsp(chip, ALL_SEND_CID, 0, SD_RSP_TYPE_R2, NULL, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + /* CMD 3 */ + retval = + sd_send_cmd_get_rsp(chip, SEND_RELATIVE_ADDR, 0, SD_RSP_TYPE_R6, + rsp, 5); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + sd_card->sd_addr = (u32) rsp[1] << 24; + sd_card->sd_addr += (u32) rsp[2] << 16; + + /* Get CSD register for Calculating Timing,Capacity, + * Check CSD to determaine as if this is the SD ROM card */ + retval = sd_check_csd(chip, 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + /* Select SD card */ + retval = sd_select_card(chip, 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); +#ifdef SUPPORT_SD_LOCK +SD_UNLOCK_ENTRY: + /* Get SD lock status */ + retval = sd_update_lock_status(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (sd_card->sd_lock_status & SD_LOCKED) { + sd_card->sd_lock_status |= (SD_LOCK_1BIT_MODE | SD_PWD_EXIST); + return STATUS_SUCCESS; + } else if (!(sd_card->sd_lock_status & SD_UNLOCK_POW_ON)) { + sd_card->sd_lock_status &= ~SD_PWD_EXIST; + } +#endif + + /* ACMD42 */ + retval = + sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, SD_RSP_TYPE_R1, + NULL, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = + sd_send_cmd_get_rsp(chip, SET_CLR_CARD_DETECT, 0, SD_RSP_TYPE_R1, + NULL, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + if (support_1v8) { + /* ACMD6 */ + retval = + sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + /* Enable 4 bit data bus */ + retval = + sd_send_cmd_get_rsp(chip, SET_BUS_WIDTH, 2, SD_RSP_TYPE_R1, + NULL, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + switch_bus_width = SD_BUS_WIDTH_4; + } else { + switch_bus_width = SD_BUS_WIDTH_1; + } + + /* Set block length 512 bytes for all block commands */ + retval = sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, + 0x200, SD_RSP_TYPE_R1, NULL, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + RTS51X_WRITE_REG(chip, SD_CFG1, SD_CLK_DIVIDE_MASK, SD_CLK_DIVIDE_0); + + if (!(sd_card->raw_csd[4] & 0x40)) { + sd_dont_switch = 1; + RTS51X_DEBUGP("Not support class ten\n"); + } + + if (!sd_dont_switch) { + /* Check the card whether flow SD1.1 spec or higher */ + retval = sd_check_spec(chip, switch_bus_width); + if (retval == STATUS_SUCCESS) { + retval = sd_switch_function(chip, switch_bus_width); + if (retval != STATUS_SUCCESS) { + if ((sd_card->sd_switch_fail == + SDR104_SUPPORT_MASK) + || (sd_card->sd_switch_fail == + DDR50_SUPPORT_MASK) + || (sd_card->sd_switch_fail == + SDR50_SUPPORT_MASK)) { + sd_init_power(chip); + SET_RETRY_SD20_MODE(sd_card); + } else if (sd_card->sd_switch_fail == + HS_SUPPORT_MASK) { + sd_dont_switch = 1; + } + goto Switch_Fail; + } + } else { + if (support_1v8) { + SET_RETRY_SD20_MODE(sd_card); + sd_init_power(chip); + sd_dont_switch = 1; + + goto Switch_Fail; + } + } + } + + if (!support_1v8) { + /* ACMD6 */ + retval = + sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + /* Enable 4 bit data bus */ + retval = + sd_send_cmd_get_rsp(chip, SET_BUS_WIDTH, 2, SD_RSP_TYPE_R1, + NULL, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } +#ifdef SUPPORT_SD_LOCK + /* clear 1 bit mode status */ + sd_card->sd_lock_status &= ~SD_LOCK_1BIT_MODE; +#endif + + if (CHK_SD30_SPEED(sd_card)) { + rts51x_write_register(chip, SD30_DRIVE_SEL, SD30_DRIVE_MASK, + 0x03); + + retval = sd_set_init_para(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + if (CHK_SD_DDR50(sd_card)) + retval = sd_ddr_tuning(chip); + else + retval = sd_sdr_tuning(chip); + + if (retval != STATUS_SUCCESS) { + SET_RETRY_SD20_MODE(sd_card); + RTS51X_DEBUGP("tuning phase fail,goto SD20 mode\n"); + sd_init_power(chip); + CLR_SD30_SPEED(sd_card); + goto Switch_Fail; + } + if (STATUS_SUCCESS == + sd_wait_currentstate_dataready(chip, 0x08, 1, 20)) { + cmd[0] = 0x40 | READ_SINGLE_BLOCK; + cmd[1] = 0x00; + cmd[2] = 0x00; + cmd[3] = 0x00; + cmd[4] = 0x00; + retval = + sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, 512, + 1, SD_BUS_WIDTH_4, NULL, 0, 600); + if (retval != STATUS_SUCCESS) { + SET_RETRY_SD20_MODE(sd_card); + RTS51X_DEBUGP("read lba0 fail," + "goto SD20 mode\n"); + sd_init_power(chip); + CLR_SD30_SPEED(sd_card); + goto Switch_Fail; + } + } + } + sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, SD_RSP_TYPE_R1, + NULL, 0); + + retval = sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0); + if (retval == STATUS_SUCCESS) { + int ret; + cmd[0] = 0x40 | SEND_STATUS; + cmd[1] = 0x00; + cmd[2] = 0x00; + cmd[3] = 0x00; + cmd[4] = 0x00; + ret = + sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, 64, 1, + SD_BUS_WIDTH_4, buf, 64, 600); + if (ret == STATUS_SUCCESS) { + sd_card_type = ((u16) buf[2] << 8) | (u16) buf[3]; + RTS51X_DEBUGP("sd_card_type:0x%4x\n", sd_card_type); + if ((sd_card_type == 0x0001) + || (sd_card_type == 0x0002)) + chip->card_wp |= SD_CARD; + } else { + rts51x_clear_sd_error(chip); + sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0); + } + } else { + rts51x_clear_sd_error(chip); + sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0); + } + + /* Check SD Machanical Write-Protect Switch */ + retval = rts51x_get_card_status(chip, &(chip->card_status)); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + if (chip->card_status & SD_WP) + chip->card_wp |= SD_CARD; + + chip->card_bus_width[chip->card2lun[SD_CARD]] = 4; + +#ifdef SUPPORT_SD_LOCK + if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON) { + rts51x_init_cmd(chip); + + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, 0x02); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, 0x00); + + retval = rts51x_send_cmd(chip, MODE_C, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } +#endif + + return STATUS_SUCCESS; +} + +static int mmc_test_switch_bus(struct rts51x_chip *chip, u8 width) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + u8 buf[8] = { 0 }, bus_width; + u16 byte_cnt; + int len; + + retval = + sd_send_cmd_get_rsp(chip, BUSTEST_W, 0, SD_RSP_TYPE_R1, NULL, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + if (width == MMC_8BIT_BUS) { + buf[0] = 0x55; + buf[1] = 0xAA; + len = 8; + byte_cnt = 8; + bus_width = SD_BUS_WIDTH_8; + } else { + buf[0] = 0x5A; + len = 4; + byte_cnt = 4; + bus_width = SD_BUS_WIDTH_4; + } + + retval = sd_write_data(chip, SD_TM_AUTO_WRITE_3, + NULL, 0, byte_cnt, 1, bus_width, buf, len, 100); + if (retval != STATUS_SUCCESS) { + u8 val1 = 0, val2 = 0; + rts51x_ep0_read_register(chip, SD_STAT1, &val1); + rts51x_ep0_read_register(chip, SD_STAT2, &val2); + rts51x_clear_sd_error(chip); + if ((val1 & 0xE0) || val2) + TRACE_RET(chip, STATUS_FAIL); + } + RTS51X_DEBUGP("SD/MMC CMD %d\n", BUSTEST_R); + + rts51x_init_cmd(chip); + + /* CMD14 */ + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD0, 0xFF, 0x40 | BUSTEST_R); + + if (width == MMC_8BIT_BUS) + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, 0x08); + else + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, 0x04); + + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, 1); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, 0); + + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG2, 0xFF, + SD_CALCULATE_CRC7 | SD_NO_CHECK_CRC16 | + SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_6); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, + PINGPONG_BUFFER); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, 0xFF, + SD_TM_NORMAL_READ | SD_TRANSFER_START); + rts51x_add_cmd(chip, CHECK_REG_CMD, SD_TRANSFER, SD_TRANSFER_END, + SD_TRANSFER_END); + + rts51x_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2, 0, 0); + if (width == MMC_8BIT_BUS) { + len = 3; + rts51x_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 1, 0, 0); + } else { + len = 2; + } + + retval = rts51x_send_cmd(chip, MODE_CR, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = rts51x_get_rsp(chip, len, 100); + if (CHECK_SD_TRANS_FAIL(chip, retval)) { + rts51x_clear_sd_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + rts51x_read_rsp_buf(chip, 1, buf, 2); + + if (width == MMC_8BIT_BUS) { + RTS51X_DEBUGP("BUSTEST_R [8bits]: 0x%02x 0x%02x\n", + buf[0], buf[1]); + if ((buf[0] == 0xAA) && (buf[1] == 0x55)) { + u8 rsp[5]; + u32 arg; + + if (CHK_MMC_DDR52(sd_card)) + arg = 0x03B70600; + else + arg = 0x03B70200; + /* Switch MMC to 8-bit mode */ + retval = + sd_send_cmd_get_rsp(chip, SWITCH, arg, + SD_RSP_TYPE_R1b, rsp, 5); + if ((retval == STATUS_SUCCESS) + && !(rsp[4] & MMC_SWITCH_ERR)) + return STATUS_SUCCESS; + } + } else { + RTS51X_DEBUGP("BUSTEST_R [4bits]: 0x%02x\n", buf[0]); + if (buf[0] == 0xA5) { + u8 rsp[5]; + u32 arg; + + if (CHK_MMC_DDR52(sd_card)) + arg = 0x03B70500; + else + arg = 0x03B70100; + /* Switch MMC to 4-bit mode */ + retval = + sd_send_cmd_get_rsp(chip, SWITCH, arg, + SD_RSP_TYPE_R1b, rsp, 5); + if ((retval == STATUS_SUCCESS) + && !(rsp[4] & MMC_SWITCH_ERR)) + return STATUS_SUCCESS; + } + } + + TRACE_RET(chip, STATUS_FAIL); +} + +static int mmc_switch_timing_bus(struct rts51x_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + u8 card_type, card_type_mask = 0; + u8 buf[6]; + + CLR_MMC_HS(sd_card); + + RTS51X_DEBUGP("SD/MMC CMD %d\n", SEND_EXT_CSD); + + rts51x_init_cmd(chip); + + /* SEND_EXT_CSD command */ + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD0, 0xFF, + 0x40 | SEND_EXT_CSD); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD1, 0xFF, 0); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD2, 0xFF, 0); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD3, 0xFF, 0); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD4, 0xFF, 0); + + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, 0); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_H, 0xFF, 2); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, 1); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, 0); + + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG2, 0xFF, + SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | SD_NO_WAIT_BUSY_END + | SD_CHECK_CRC7 | SD_RSP_LEN_6); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, + PINGPONG_BUFFER); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, 0xFF, + SD_TM_NORMAL_READ | SD_TRANSFER_START); + rts51x_add_cmd(chip, CHECK_REG_CMD, SD_TRANSFER, SD_TRANSFER_END, + SD_TRANSFER_END); + + rts51x_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 196, 0xFF, 0); + rts51x_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 212, 0xFF, 0); + rts51x_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 213, 0xFF, 0); + rts51x_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 214, 0xFF, 0); + rts51x_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + 215, 0xFF, 0); + + retval = rts51x_send_cmd(chip, MODE_CR, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = rts51x_get_rsp(chip, 6, 1000); + + if (CHECK_SD_TRANS_FAIL(chip, retval)) { + if (retval == STATUS_TIMEDOUT) { + rts51x_clear_sd_error(chip); + sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0); + } + TRACE_RET(chip, STATUS_FAIL); + } + + rts51x_read_rsp_buf(chip, 0, buf, 6); + + if (buf[0] & SD_TRANSFER_ERR) { + sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0); + TRACE_RET(chip, STATUS_FAIL); + } + if (CHK_MMC_SECTOR_MODE(sd_card)) + sd_card->capacity = + ((u32) buf[5] << 24) | ((u32) buf[4] << 16) | + ((u32) buf[3] << 8) | ((u32) buf[2]); +#ifdef SUPPORT_SD_LOCK + if (!(sd_card->sd_lock_status & SD_SDR_RST) && CHECK_UHS50(chip)) + card_type_mask = 0x07; + else + card_type_mask = 0x03; +#else + if (CHECK_UHS50(chip)) + card_type_mask = 0x07; + else + card_type_mask = 0x03; +#endif + + card_type = buf[1] & card_type_mask; + if (card_type) { + /* CARD TYPE FIELD = DDR52MHz, 52MHz or 26MHz */ + u8 rsp[5]; + + if (card_type & 0x04) + SET_MMC_DDR52(sd_card); + else if (card_type & 0x02) + SET_MMC_52M(sd_card); + else + SET_MMC_26M(sd_card); + + retval = + sd_send_cmd_get_rsp(chip, SWITCH, 0x03B90100, + SD_RSP_TYPE_R1b, rsp, 5); + if ((retval != STATUS_SUCCESS) || (rsp[4] & MMC_SWITCH_ERR)) + CLR_MMC_HS(sd_card); + } + sd_choose_proper_clock(chip); + retval = switch_clock(chip, sd_card->sd_clock); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + /* Test Bus Procedure */ + if (mmc_test_switch_bus(chip, MMC_8BIT_BUS) == STATUS_SUCCESS) { + SET_MMC_8BIT(sd_card); + chip->card_bus_width[chip->card2lun[SD_CARD]] = 8; +#ifdef SUPPORT_SD_LOCK + sd_card->sd_lock_status &= ~SD_LOCK_1BIT_MODE; +#endif + } else if (mmc_test_switch_bus(chip, MMC_4BIT_BUS) == STATUS_SUCCESS) { + SET_MMC_4BIT(sd_card); + chip->card_bus_width[chip->card2lun[SD_CARD]] = 4; +#ifdef SUPPORT_SD_LOCK + sd_card->sd_lock_status &= ~SD_LOCK_1BIT_MODE; +#endif + } else { + CLR_MMC_8BIT(sd_card); + CLR_MMC_4BIT(sd_card); + } + + return STATUS_SUCCESS; +} + +static int reset_mmc(struct rts51x_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval, i = 0, j = 0, k = 0; + u8 rsp[16]; + u8 spec_ver = 0; + u8 change_to_ddr52 = 1; + u8 cmd[5]; + +#ifdef SUPPORT_SD_LOCK + if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON) + goto MMC_UNLOCK_ENTRY; +#endif + +MMC_DDR_FAIL: + + retval = sd_prepare_reset(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + SET_MMC(sd_card); + +RTY_MMC_RST: + retval = + sd_send_cmd_get_rsp(chip, GO_IDLE_STATE, 0, SD_RSP_TYPE_R0, NULL, + 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + do { + { + u8 temp = 0; + rts51x_read_register(chip, CARD_INT_PEND, &temp); + if (temp & SD_INT) { + chip->reset_need_retry = 1; + rts51x_write_register(chip, CARD_INT_PEND, + XD_INT | SD_INT | MS_INT, + XD_INT | SD_INT | MS_INT); + sd_set_reset_fail(chip, MMC_RESET_FAIL); + TRACE_RET(chip, STATUS_FAIL); + } + } + + /* CMD 1 */ + retval = sd_send_cmd_get_rsp(chip, SEND_OP_COND, + (SUPPORT_VOLTAGE | 0x40000000), + SD_RSP_TYPE_R3, rsp, 5); + if (retval != STATUS_SUCCESS) { + if (monitor_card_cd(chip, SD_CARD) == CD_NOT_EXIST) { + sd_set_reset_fail(chip, MMC_RESET_FAIL); + TRACE_RET(chip, STATUS_FAIL); + } + + if (sd_check_err_code(chip, SD_BUSY) + || sd_check_err_code(chip, SD_TO_ERR)) { + k++; + if (k < 20) { + sd_clr_err_code(chip); + goto RTY_MMC_RST; + } else { + TRACE_RET(chip, STATUS_FAIL); + } + } else { + j++; + if (j < 100) { + sd_clr_err_code(chip); + goto RTY_MMC_RST; + } else { + TRACE_RET(chip, STATUS_FAIL); + } + } + } + + wait_timeout(20); + i++; + } while (!(rsp[1] & 0x80) && (i < 100)); /* Not complete power on */ + + if (i == 100) { + /* Time out */ + TRACE_RET(chip, STATUS_FAIL); + } + + if ((rsp[1] & 0x60) == 0x40) + SET_MMC_SECTOR_MODE(sd_card); + else + CLR_MMC_SECTOR_MODE(sd_card); + + /* CMD 2 */ + retval = + sd_send_cmd_get_rsp(chip, ALL_SEND_CID, 0, SD_RSP_TYPE_R2, NULL, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + /* CMD 3 */ + sd_card->sd_addr = 0x00100000; + retval = + sd_send_cmd_get_rsp(chip, SET_RELATIVE_ADDR, sd_card->sd_addr, + SD_RSP_TYPE_R6, rsp, 5); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + /* Get CSD register for Calculating Timing,Capacity + * Check CSD to determaine as if this is the SD ROM card */ + retval = sd_check_csd(chip, 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + /* Get MMC Spec_Ver in the CSD register */ + spec_ver = (sd_card->raw_csd[0] & 0x3C) >> 2; + + /* Select MMC card */ + retval = sd_select_card(chip, 1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + /* Set block length 512 bytes for all block commands */ + retval = + sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200, SD_RSP_TYPE_R1, NULL, + 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); +#ifdef SUPPORT_SD_LOCK +MMC_UNLOCK_ENTRY: + /* Get SD lock status */ + retval = sd_update_lock_status(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); +#endif + + RTS51X_WRITE_REG(chip, SD_CFG1, SD_CLK_DIVIDE_MASK, SD_CLK_DIVIDE_0); + + if (chip->ic_version < 2) + rts51x_write_register(chip, SD30_DRIVE_SEL, SD30_DRIVE_MASK, + 0x02); + rts51x_write_register(chip, CARD_DRIVE_SEL, SD20_DRIVE_MASK, DRIVE_8mA); + + chip->card_bus_width[chip->card2lun[SD_CARD]] = 1; + if (spec_ver == 4) { + /* MMC 4.x Cards */ + (void)mmc_switch_timing_bus(chip); + } + + if (CHK_MMC_SECTOR_MODE(sd_card) && (sd_card->capacity == 0)) + TRACE_RET(chip, STATUS_FAIL); + + if (CHK_MMC_DDR52(sd_card) && change_to_ddr52) { + /* Card is extracted while identifying */ + if (monitor_card_cd(chip, SD_CARD) == CD_NOT_EXIST) + TRACE_RET(chip, STATUS_FAIL); + + retval = sd_set_init_para(chip); + if (retval != STATUS_SUCCESS) { + CLR_MMC_DDR52(sd_card); + sd_init_power(chip); + change_to_ddr52 = 0; + goto MMC_DDR_FAIL; + } + + retval = mmc_ddr_tuning(chip); + if (retval != STATUS_SUCCESS) { + CLR_MMC_DDR52(sd_card); + sd_init_power(chip); + change_to_ddr52 = 0; + goto MMC_DDR_FAIL; + } + + if (STATUS_SUCCESS == + sd_wait_currentstate_dataready(chip, 0x08, 1, 20)) { + cmd[0] = 0x40 | READ_SINGLE_BLOCK; + cmd[1] = 0x00; + cmd[2] = 0x00; + cmd[3] = 0x00; + cmd[4] = 0x00; + if (CHK_MMC_8BIT(sd_card)) { + retval = + sd_read_data(chip, SD_TM_NORMAL_READ, cmd, + 5, 512, 1, SD_BUS_WIDTH_8, + NULL, 0, 600); + } else if (CHK_MMC_4BIT(sd_card)) { + retval = + sd_read_data(chip, SD_TM_NORMAL_READ, cmd, + 5, 512, 1, SD_BUS_WIDTH_4, + NULL, 0, 600); + } else { + retval = + sd_read_data(chip, SD_TM_NORMAL_READ, cmd, + 5, 512, 1, SD_BUS_WIDTH_1, + NULL, 0, 600); + } + + if (retval != STATUS_SUCCESS) { + CLR_MMC_DDR52(sd_card); + change_to_ddr52 = 0; + RTS51X_DEBUGP("read lba0 fail," + "goto SD20 mode\n"); + sd_init_power(chip); + goto MMC_DDR_FAIL; + } + } + } +#ifdef SUPPORT_SD_LOCK + if (sd_card->sd_lock_status & SD_UNLOCK_POW_ON) { + rts51x_init_cmd(chip); + + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, 0x02); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, 0x00); + + retval = rts51x_send_cmd(chip, MODE_C, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } +#endif + + retval = rts51x_get_card_status(chip, &(chip->card_status)); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + if (chip->card_status & SD_WP) + chip->card_wp |= SD_CARD; + + return STATUS_SUCCESS; +} + +int reset_sd_card(struct rts51x_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + int i; + + memset(sd_card, 0, sizeof(struct sd_info)); + + /* Init variables */ + sd_card->sd_type = 0; + sd_card->seq_mode = 0; + sd_card->sd_data_buf_ready = 0; + sd_card->capacity = 0; + sd_card->sd_switch_fail = 0; + +#ifdef SUPPORT_SD_LOCK + sd_card->sd_lock_status = 0; + sd_card->sd_erase_status = 0; +#endif + + sd_clear_reset_fail(chip); + enable_card_clock(chip, SD_CARD); + + sd_init_power(chip); + + chip->reset_need_retry = 0; + for (i = 0; i < 3; i++) { + if (!chip->option.reset_mmc_first) { /* reset sd first */ + retval = reset_sd(chip); + if (retval != STATUS_SUCCESS) { + /* Switch SD bus to 3V3 signal */ + RTS51X_WRITE_REG(chip, SD_PAD_CTL, + SD_IO_USING_1V8, 0); + if (sd_check_reset_fail(chip, SD_RESET_FAIL)) + sd_clear_reset_fail(chip); + else + retval = reset_mmc(chip); + } + } else { /* reset MMC first */ + retval = reset_mmc(chip); + if (retval != STATUS_SUCCESS) { + if (sd_check_reset_fail(chip, MMC_RESET_FAIL)) { + sd_clear_reset_fail(chip); + } else { + retval = reset_sd(chip); + if (retval != STATUS_SUCCESS) { + /* Switch SD bus to + * 3V3 signal */ + RTS51X_WRITE_REG(chip, + SD_PAD_CTL, + SD_IO_USING_1V8, 0); + } + } + } + } + + if ((retval == STATUS_SUCCESS) || (!chip->reset_need_retry)) { + /* if reset success or don't need retry,then break */ + break; + } + if (monitor_card_cd(chip, SD_CARD) == CD_NOT_EXIST) { + /* card is extracted */ + break; + } + RTS51X_DEBUGP("retry reset sd card,%d\n", i); + chip->reset_need_retry = 0; + } + + sd_clear_reset_fail(chip); + chip->reset_need_retry = 0; + + if (retval == STATUS_SUCCESS) { + rts51x_init_cmd(chip); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG1, SD_CLK_DIVIDE_MASK, + SD_CLK_DIVIDE_0); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, 0); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_H, 0xFF, 2); + retval = rts51x_send_cmd(chip, MODE_C, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } else { + chip->capacity[chip->card2lun[SD_CARD]] = sd_card->capacity = 0; + if (chip->option.reset_or_rw_fail_set_pad_drive) { + rts51x_write_register(chip, CARD_DRIVE_SEL, + SD20_DRIVE_MASK, DRIVE_8mA); + } + TRACE_RET(chip, STATUS_FAIL); + } + + chip->capacity[chip->card2lun[SD_CARD]] = sd_card->capacity; + + if (chip->option.sd_send_status_en) { + sd_card->sd_send_status_en = 1; + } else { + if (sd_card->capacity > 0x20000) { /* 64MB */ + sd_card->sd_send_status_en = 0; + } else { + sd_card->sd_send_status_en = 1; + } + } + RTS51X_DEBUGP("sd_card->sd_send_status = %d\n", + sd_card->sd_send_status_en); + + retval = sd_set_init_para(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + RTS51X_DEBUGP("sd_card->sd_type = 0x%x\n", sd_card->sd_type); + + return STATUS_SUCCESS; +} + +#define WAIT_DATA_READY_RTY_CNT 255 + +static int wait_data_buf_ready(struct rts51x_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int i, retval; + + for (i = 0; i < WAIT_DATA_READY_RTY_CNT; i++) { + if (monitor_card_cd(chip, SD_CARD) == CD_NOT_EXIST) + TRACE_RET(chip, STATUS_FAIL); + + sd_card->sd_data_buf_ready = 0; + + retval = sd_send_cmd_get_rsp(chip, SEND_STATUS, + sd_card->sd_addr, SD_RSP_TYPE_R1, + NULL, 0); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + if (sd_card->sd_data_buf_ready) + return sd_send_cmd_get_rsp(chip, SEND_STATUS, + sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0); + } + + sd_set_err_code(chip, SD_TO_ERR); + + TRACE_RET(chip, STATUS_FAIL); +} + +void sd_stop_seq_mode(struct rts51x_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + + if (sd_card->seq_mode) { + retval = sd_switch_clock(chip); + if (retval != STATUS_SUCCESS) + return; + + retval = sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, 0, + SD_RSP_TYPE_R1b, NULL, 0); + if (retval != STATUS_SUCCESS) + sd_set_err_code(chip, SD_STS_ERR); + sd_card->seq_mode = 0; + + rts51x_ep0_write_register(chip, MC_FIFO_CTL, FIFO_FLUSH, + FIFO_FLUSH); + } +} + +static inline int sd_auto_tune_clock(struct rts51x_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + + if (chip->asic_code) { + if (sd_card->sd_clock > 30) + sd_card->sd_clock -= 20; + } else { + if (sd_card->sd_clock == CLK_100) + sd_card->sd_clock = CLK_80; + else if (sd_card->sd_clock == CLK_80) + sd_card->sd_clock = CLK_60; + else if (sd_card->sd_clock == CLK_60) + sd_card->sd_clock = CLK_50; + } + + retval = sd_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + return STATUS_SUCCESS; +} + +int sd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, + u16 sector_cnt) +{ + struct sd_info *sd_card = &(chip->sd_card); + u32 data_addr; + int retval; + u8 flag; + unsigned int pipe; + u8 stageflag; + + sd_card->counter = 0; + + if (!CHK_SD_HCXC(sd_card) && !CHK_MMC_SECTOR_MODE(sd_card)) + data_addr = start_sector << 9; + else + data_addr = start_sector; + + RTS51X_DEBUGP("sd_rw, data_addr = 0x%x\n", data_addr); + + sd_clr_err_code(chip); + + retval = sd_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + if (sd_card->seq_mode && ((sd_card->pre_dir != srb->sc_data_direction) + || + ((sd_card->pre_sec_addr + + sd_card->pre_sec_cnt) != start_sector))) { + if ((sd_card->pre_dir == DMA_FROM_DEVICE) + && !CHK_SD30_SPEED(sd_card) + && !CHK_SD_HS(sd_card) + && !CHK_MMC_HS(sd_card) + && sd_card->sd_send_status_en) { + sd_send_cmd_get_rsp(chip, SEND_STATUS, + sd_card->sd_addr, SD_RSP_TYPE_R1, + NULL, 0); + } + + retval = + sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, 0, + SD_RSP_TYPE_R1b, NULL, 0); + if (retval != STATUS_SUCCESS) { + sd_set_err_code(chip, SD_STS_ERR); + TRACE_RET(chip, sd_parse_err_code(chip)); + } + + sd_card->seq_mode = 0; + + RTS51X_WRITE_REG(chip, MC_FIFO_CTL, FIFO_FLUSH, FIFO_FLUSH); + + if (!CHK_SD30_SPEED(sd_card) + && !CHK_SD_HS(sd_card) + && !CHK_MMC_HS(sd_card) + && sd_card->sd_send_status_en) { + /* random rw, so pre_sec_cnt < 0x80 */ + sd_send_cmd_get_rsp(chip, SEND_STATUS, + sd_card->sd_addr, SD_RSP_TYPE_R1, + NULL, 0); + } + } + + rts51x_init_cmd(chip); + + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, 0x00); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_H, 0xFF, 0x02); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, + (u8) sector_cnt); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, + (u8) (sector_cnt >> 8)); + + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, + RING_BUFFER); + + if (CHK_MMC_8BIT(sd_card)) + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG1, 0x03, + SD_BUS_WIDTH_8); + else if (CHK_MMC_4BIT(sd_card) || CHK_SD(sd_card)) + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG1, 0x03, + SD_BUS_WIDTH_4); + else + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG1, 0x03, + SD_BUS_WIDTH_1); + + if (sd_card->seq_mode) { + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG2, 0xFF, + SD_NO_CALCULATE_CRC7 | SD_CHECK_CRC16 | + SD_NO_WAIT_BUSY_END | SD_NO_CHECK_CRC7 | + SD_RSP_LEN_0); + + trans_dma_enable(srb->sc_data_direction, chip, sector_cnt * 512, + DMA_512); + + if (srb->sc_data_direction == DMA_FROM_DEVICE) { + flag = MODE_CDIR; + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, 0xFF, + SD_TM_AUTO_READ_3 | SD_TRANSFER_START); + } else { + flag = MODE_CDOR; + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, 0xFF, + SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START); + } + + rts51x_add_cmd(chip, CHECK_REG_CMD, SD_TRANSFER, + SD_TRANSFER_END, SD_TRANSFER_END); + + retval = rts51x_send_cmd(chip, flag, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } else { + if (srb->sc_data_direction == DMA_FROM_DEVICE) { + RTS51X_DEBUGP("SD/MMC CMD %d\n", READ_MULTIPLE_BLOCK); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD0, 0xFF, + 0x40 | READ_MULTIPLE_BLOCK); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD1, 0xFF, + (u8) (data_addr >> 24)); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD2, 0xFF, + (u8) (data_addr >> 16)); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD3, 0xFF, + (u8) (data_addr >> 8)); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD4, 0xFF, + (u8) data_addr); + + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG2, 0xFF, + SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | + SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | + SD_RSP_LEN_6); + + trans_dma_enable(srb->sc_data_direction, chip, + sector_cnt * 512, DMA_512); + + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, 0xFF, + SD_TM_AUTO_READ_2 | SD_TRANSFER_START); + rts51x_add_cmd(chip, CHECK_REG_CMD, SD_TRANSFER, + SD_TRANSFER_END, SD_TRANSFER_END); + + retval = rts51x_send_cmd(chip, MODE_CDIR, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } else { + retval = rts51x_send_cmd(chip, MODE_C, 50); + if (retval != STATUS_SUCCESS) { + rts51x_clear_sd_error(chip); + + sd_set_err_code(chip, SD_TO_ERR); + TRACE_RET(chip, sd_parse_err_code(chip)); + } + + retval = wait_data_buf_ready(chip); + if (retval != STATUS_SUCCESS) { + sd_set_err_code(chip, SD_TO_ERR); + TRACE_RET(chip, sd_parse_err_code(chip)); + } + + retval = sd_send_cmd_get_rsp(chip, WRITE_MULTIPLE_BLOCK, + data_addr, SD_RSP_TYPE_R1, + NULL, 0); + if (retval != STATUS_SUCCESS) { + sd_set_err_code(chip, SD_CRC_ERR); + TRACE_RET(chip, sd_parse_err_code(chip)); + } + + rts51x_init_cmd(chip); + + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG2, 0xFF, + SD_NO_CALCULATE_CRC7 | SD_CHECK_CRC16 | + SD_NO_WAIT_BUSY_END | SD_NO_CHECK_CRC7 | + SD_RSP_LEN_0); + + trans_dma_enable(srb->sc_data_direction, chip, + sector_cnt * 512, DMA_512); + + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, 0xFF, + SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START); + rts51x_add_cmd(chip, CHECK_REG_CMD, SD_TRANSFER, + SD_TRANSFER_END, SD_TRANSFER_END); + + retval = rts51x_send_cmd(chip, MODE_CDOR, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } + + sd_card->seq_mode = 1; + } + + if (srb->sc_data_direction == DMA_FROM_DEVICE) { + pipe = RCV_BULK_PIPE(chip); + stageflag = STAGE_DI; + } else { + pipe = SND_BULK_PIPE(chip); + stageflag = STAGE_DO; + } + + retval = + rts51x_transfer_data_rcc(chip, pipe, scsi_sglist(srb), + scsi_bufflen(srb), scsi_sg_count(srb), + NULL, 10000, stageflag); + if (retval != STATUS_SUCCESS) { + u8 stat = 0; + int err = retval; + + sd_print_debug_reg(chip); + + rts51x_ep0_read_register(chip, SD_STAT1, &stat); + RTS51X_DEBUGP("SD_STAT1: 0x%x\n", stat); + + rts51x_clear_sd_error(chip); + + retval = + sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, 0, + SD_RSP_TYPE_R1b, NULL, 0); + if (retval != STATUS_SUCCESS) { + sd_set_err_code(chip, SD_STS_ERR); + TRACE_RET(chip, retval); + } + + if (stat & (SD_CRC7_ERR | SD_CRC16_ERR | SD_CRC_WRITE_ERR)) { + RTS51X_DEBUGP("SD CRC error, tune clock!\n"); + sd_auto_tune_clock(chip); + } + + sd_card->seq_mode = 0; + + TRACE_RET(chip, err); + } + retval = rts51x_get_rsp(chip, 1, 2000); + if (CHECK_SD_TRANS_FAIL(chip, retval)) { + rts51x_clear_sd_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + sd_card->pre_sec_addr = start_sector; + sd_card->pre_sec_cnt = sector_cnt; + sd_card->pre_dir = srb->sc_data_direction; + + return STATUS_SUCCESS; +} + +void sd_cleanup_work(struct rts51x_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + + if (sd_card->seq_mode) { + RTS51X_DEBUGP("SD: stop transmission\n"); + sd_stop_seq_mode(chip); + sd_card->counter = 0; + } +} + +inline void sd_fill_power_off_card3v3(struct rts51x_chip *chip) +{ + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_CLK_EN, SD_CLK_EN, 0); + + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_OE, SD_OUTPUT_EN, 0); + if (!chip->option.FT2_fast_mode) { +#ifdef SD_XD_IO_FOLLOW_PWR + if (CHECK_PKG(chip, LQFP48) + || chip->option.rts5129_D3318_off_enable) + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, + POWER_MASK | LDO_OFF, + POWER_OFF | LDO_OFF); + else + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, + POWER_MASK, POWER_OFF); +#else + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, POWER_MASK, + POWER_OFF); +#endif + } +} + +int sd_power_off_card3v3(struct rts51x_chip *chip) +{ + int retval; + + rts51x_init_cmd(chip); + + sd_fill_power_off_card3v3(chip); + + retval = rts51x_send_cmd(chip, MODE_C, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); +#ifdef SD_XD_IO_FOLLOW_PWR + if (!chip->option.FT2_fast_mode) + wait_timeout(chip->option.D3318_off_delay); +#endif + + return STATUS_SUCCESS; +} + +int release_sd_card(struct rts51x_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + + RTS51X_DEBUGP("elease_sd_card\n"); + + chip->card_ready &= ~SD_CARD; + chip->card_fail &= ~SD_CARD; + chip->card_wp &= ~SD_CARD; + +#ifdef SUPPORT_SD_LOCK + sd_card->sd_lock_status = 0; + sd_card->sd_erase_status = 0; +#endif + + memset(sd_card->raw_csd, 0, 16); + memset(sd_card->raw_scr, 0, 8); + + rts51x_write_register(chip, SFSM_ED, HW_CMD_STOP, HW_CMD_STOP); + rts51x_write_register(chip, SD_PAD_CTL, SD_IO_USING_1V8, 0); + if (CHECK_PKG(chip, LQFP48) || chip->option.rts5129_D3318_off_enable) + sd_power_off_card3v3(chip); + + rts51x_init_cmd(chip); + if (!(CHECK_PKG(chip, LQFP48) || chip->option.rts5129_D3318_off_enable)) + sd_fill_power_off_card3v3(chip); + + if (chip->asic_code) + sd_pull_ctl_disable(chip); + else + rts51x_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, + FPGA_SD_PULL_CTL_BIT | 0x20, + FPGA_SD_PULL_CTL_BIT); + + /* Switch LDO3318 to 3.3V */ + rts51x_add_cmd(chip, WRITE_REG_CMD, LDO_POWER_CFG, TUNE_SD18_MASK, + TUNE_SD18_3V3); + + if (CHK_MMC_DDR52(sd_card) && CHK_MMC_8BIT(sd_card)) + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DMA1_CTL, + EXTEND_DMA1_ASYNC_SIGNAL, + EXTEND_DMA1_ASYNC_SIGNAL); + if (CHK_SD30_SPEED(sd_card) || CHK_MMC(sd_card)) + rts51x_add_cmd(chip, WRITE_REG_CMD, SD30_DRIVE_SEL, + SD30_DRIVE_MASK, chip->option.sd30_pad_drive); + /* Suspend LDO3318 */ + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, LDO3318_PWR_MASK, + LDO_SUSPEND); + + retval = rts51x_send_cmd(chip, MODE_C, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + wait_timeout(20); + + return STATUS_SUCCESS; +} diff --git a/drivers/staging/rts5139/sd.h b/drivers/staging/rts5139/sd.h new file mode 100644 index 0000000..0805edc --- /dev/null +++ b/drivers/staging/rts5139/sd.h @@ -0,0 +1,304 @@ +/* Driver for Realtek RTS51xx USB card reader + * Header file + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + * Maintainer: + * Edwin Rong (edwin_rong@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#ifndef __RTS51X_SD_H +#define __RTS51X_SD_H + +#include "rts51x_chip.h" + +#define SD_MAX_RETRY_COUNT 3 + +#define SUPPORT_VOLTAGE 0x003C0000 + +#define SD_RESET_FAIL 0x01 +#define MMC_RESET_FAIL 0x02 + +/* Error Code */ +#define SD_NO_ERROR 0x0 +#define SD_CRC_ERR 0x80 +#define SD_TO_ERR 0x40 +#define SD_NO_CARD 0x20 +#define SD_BUSY 0x10 +#define SD_STS_ERR 0x08 +#define SD_RSP_TIMEOUT 0x04 + +/* MMC/SD Command Index */ +/* Basic command (class 0) */ +#define GO_IDLE_STATE 0 +#define SEND_OP_COND 1 /* reserved for SD */ +#define ALL_SEND_CID 2 +#define SET_RELATIVE_ADDR 3 +#define SEND_RELATIVE_ADDR 3 +#define SET_DSR 4 +#define IO_SEND_OP_COND 5 +#define SWITCH 6 +#define SELECT_CARD 7 +#define DESELECT_CARD 7 +/* CMD8 is "SEND_EXT_CSD" for MMC4.x Spec + * while is "SEND_IF_COND" for SD 2.0 */ +#define SEND_EXT_CSD 8 +#define SEND_IF_COND 8 +/* end */ +#define SEND_CSD 9 +#define SEND_CID 10 +#define VOLTAGE_SWITCH 11 +#define READ_DAT_UTIL_STOP 11 /* reserved for SD */ +#define STOP_TRANSMISSION 12 +#define SEND_STATUS 13 +#define GO_INACTIVE_STATE 15 + +/* Block oriented read commands (class 2) */ +#define SET_BLOCKLEN 16 +#define READ_SINGLE_BLOCK 17 +#define READ_MULTIPLE_BLOCK 18 +#define SEND_TUNING_PATTERN 19 + +/* Bus Width Test */ +#define BUSTEST_R 14 +#define BUSTEST_W 19 +/* end */ + +/* Block oriented write commands (class 4) */ +#define WRITE_BLOCK 24 +#define WRITE_MULTIPLE_BLOCK 25 +#define PROGRAM_CSD 27 + +/* Erase commands */ +#define ERASE_WR_BLK_START 32 +#define ERASE_WR_BLK_END 33 +#define ERASE_CMD 38 + +/* Block Oriented Write Protection Commands */ +#define LOCK_UNLOCK 42 + +#define IO_RW_DIRECT 52 + +/* Application specific commands (class 8) */ +#define APP_CMD 55 +#define GEN_CMD 56 + +/* SD Application command Index */ +#define SET_BUS_WIDTH 6 +#define SD_STATUS 13 +#define SEND_NUM_WR_BLOCKS 22 +#define SET_WR_BLK_ERASE_COUNT 23 +#define SD_APP_OP_COND 41 +#define SET_CLR_CARD_DETECT 42 +#define SEND_SCR 51 + +/* SD TIMEOUT function return error */ +#define SD_READ_COMPLETE 0x00 +#define SD_READ_TO 0x01 +#define SD_READ_ADVENCE 0x02 + +/* SD v1.1 CMD6 SWITCH function */ +#define SD_CHECK_MODE 0x00 +#define SD_SWITCH_MODE 0x80 +#define SD_FUNC_GROUP_1 0x01 +#define SD_FUNC_GROUP_2 0x02 +#define SD_FUNC_GROUP_3 0x03 +#define SD_FUNC_GROUP_4 0x04 +#define SD_CHECK_SPEC_V1_1 0xFF + +/* SD Command Argument */ +#define NO_ARGUMENT 0x00 +#define CHECK_PATTERN 0x000000AA +#define VOLTAGE_SUPPLY_RANGE 0x00000100 /* 2.7~3.6V */ +#define SUPPORT_HIGH_AND_EXTENDED_CAPACITY 0x40000000 +#define SUPPORT_MAX_POWER_PERMANCE 0x10000000 +#define SUPPORT_1V8 0x01000000 + +/* Switch Command Error Code */ +#define SWTICH_NO_ERR 0x00 +#define CARD_NOT_EXIST 0x01 +#define SPEC_NOT_SUPPORT 0x02 +#define CHECK_MODE_ERR 0x03 +#define CHECK_NOT_READY 0x04 +#define SWITCH_CRC_ERR 0x05 +#define SWITCH_MODE_ERR 0x06 +#define SWITCH_PASS 0x07 + +#ifdef SUPPORT_SD_LOCK +/* CMD42 Parameter */ +#define SD_ERASE 0x08 +#define SD_LOCK 0x04 +#define SD_UNLOCK 0x00 +#define SD_CLR_PWD 0x02 +#define SD_SET_PWD 0x01 + +#define SD_PWD_LEN 0x10 + +/* SD lock unlock Status */ +#define SD_LOCKED 0x80 /* Global lock status */ +#define SD_LOCK_1BIT_MODE 0x40 /**/ +#define SD_PWD_EXIST 0x20 +#define SD_UNLOCK_POW_ON 0x01 /**/ +#define SD_SDR_RST 0x02 /* Reset SD30 card with current DDR mode to SDR mode. */ +/* g_bySDEraseStatus */ +#define SD_NOT_ERASE 0x00 +#define SD_UNDER_ERASING 0x01 +#define SD_COMPLETE_ERASE 0x02 +/* SD_RW FAIL status */ +#define SD_RW_FORBIDDEN 0x0F /* read/write is forbidden (SD card) */ +#endif +/* Function Group Definition */ +/* Function Group 1 */ +#define HS_SUPPORT 0x01 +#define SDR50_SUPPORT 0x02 +#define SDR104_SUPPORT 0x03 +#define DDR50_SUPPORT 0x04 +#define HS_SUPPORT_MASK 0x02 +#define SDR50_SUPPORT_MASK 0x04 +#define SDR104_SUPPORT_MASK 0x08 +#define DDR50_SUPPORT_MASK 0x10 +#define HS_QUERY_SWITCH_OK 0x01 +#define SDR50_QUERY_SWITCH_OK 0x02 +#define SDR104_QUERY_SWITCH_OK 0x03 +#define DDR50_QUERY_SWITCH_OK 0x04 +#define HS_SWITCH_BUSY 0x02 +#define SDR50_SWITCH_BUSY 0x04 +#define SDR104_SWITCH_BUSY 0x08 +#define DDR50_SWITCH_BUSY 0x10 +#define FUNCTION_GROUP1_SUPPORT_OFFSET 0x0D +#define FUNCTION_GROUP1_QUERY_SWITCH_OFFSET 0x10 +#define FUNCTION_GROUP1_CHECK_BUSY_OFFSET 0x1D +/* Function Group 3 */ +#define DRIVING_TYPE_A 0x01 +#define DRIVING_TYPE_B 0x00 +#define DRIVING_TYPE_C 0x02 +#define DRIVING_TYPE_D 0x03 +#define DRIVING_TYPE_A_MASK 0x02 +#define DRIVING_TYPE_B_MASK 0x01 +#define DRIVING_TYPE_C_MASK 0x04 +#define DRIVING_TYPE_D_MASK 0x08 +#define TYPE_A_QUERY_SWITCH_OK 0x01 +#define TYPE_B_QUERY_SWITCH_OK 0x00 +#define TYPE_C_QUERY_SWITCH_OK 0x02 +#define TYPE_D_QUERY_SWITCH_OK 0x03 +#define TYPE_A_SWITCH_BUSY 0x02 +#define TYPE_B_SWITCH_BUSY 0x01 +#define TYPE_C_SWITCH_BUSY 0x04 +#define TYPE_D_SWITCH_BUSY 0x08 +#define FUNCTION_GROUP3_SUPPORT_OFFSET 0x09 +#define FUNCTION_GROUP3_QUERY_SWITCH_OFFSET 0x0F +#define FUNCTION_GROUP3_CHECK_BUSY_OFFSET 0x19 +/* Function Group 4 */ +#define CURRENT_LIMIT_200 0x00 +#define CURRENT_LIMIT_400 0x01 +#define CURRENT_LIMIT_600 0x02 +#define CURRENT_LIMIT_800 0x03 +#define CURRENT_LIMIT_200_MASK 0x01 +#define CURRENT_LIMIT_400_MASK 0x02 +#define CURRENT_LIMIT_600_MASK 0x04 +#define CURRENT_LIMIT_800_MASK 0x08 +#define CURRENT_LIMIT_200_QUERY_SWITCH_OK 0x00 +#define CURRENT_LIMIT_400_QUERY_SWITCH_OK 0x01 +#define CURRENT_LIMIT_600_QUERY_SWITCH_OK 0x02 +#define CURRENT_LIMIT_800_QUERY_SWITCH_OK 0x03 +#define CURRENT_LIMIT_200_SWITCH_BUSY 0x01 +#define CURRENT_LIMIT_400_SWITCH_BUSY 0x02 +#define CURRENT_LIMIT_600_SWITCH_BUSY 0x04 +#define CURRENT_LIMIT_800_SWITCH_BUSY 0x08 +#define FUNCTION_GROUP4_SUPPORT_OFFSET 0x07 +#define FUNCTION_GROUP4_QUERY_SWITCH_OFFSET 0x0F +#define FUNCTION_GROUP4_CHECK_BUSY_OFFSET 0x17 +/* Switch Function Status Offset */ +#define DATA_STRUCTURE_VER_OFFSET 0x11 /* The high offset */ +#define MAX_PHASE 15 +/* #define TOTAL_READ_PHASE 0x20 */ +/* #define TOTAL_WRITE_PHASE 0x20 */ +/* MMC v4.0 */ +/* #define MMC_52MHZ_SPEED 0x0001 */ +/* #define MMC_26MHZ_SPEED 0x0002 */ +#define MMC_8BIT_BUS 0x0010 +#define MMC_4BIT_BUS 0x0020 +/* #define MMC_SECTOR_MODE 0x0100 */ +#define MMC_SWITCH_ERR 0x80 +/* Tuning direction RX or TX */ +#define TUNE_TX 0x00 +#define TUNE_RX 0x01 +/* For Change_DCM_FreqMode Function */ +#define CHANGE_TX 0x00 +#define CHANGE_RX 0x01 +#define DCM_HIGH_FREQUENCY_MODE 0x00 +#define DCM_LOW_FREQUENCY_MODE 0x01 +#define DCM_HIGH_FREQUENCY_MODE_SET 0x0C +#define DCM_Low_FREQUENCY_MODE_SET 0x00 +/* For Change_FPGA_SSCClock Function */ +#define MULTIPLY_BY_1 0x00 +#define MULTIPLY_BY_2 0x01 +#define MULTIPLY_BY_3 0x02 +#define MULTIPLY_BY_4 0x03 +#define MULTIPLY_BY_5 0x04 +#define MULTIPLY_BY_6 0x05 +#define MULTIPLY_BY_7 0x06 +#define MULTIPLY_BY_8 0x07 +#define MULTIPLY_BY_9 0x08 +#define MULTIPLY_BY_10 0x09 +#define DIVIDE_BY_2 0x01 +#define DIVIDE_BY_3 0x02 +#define DIVIDE_BY_4 0x03 +#define DIVIDE_BY_5 0x04 +#define DIVIDE_BY_6 0x05 +#define DIVIDE_BY_7 0x06 +#define DIVIDE_BY_8 0x07 +#define DIVIDE_BY_9 0x08 +#define DIVIDE_BY_10 0x09 +#define CHECK_SD_TRANS_FAIL(chip, retval) \ + (((retval) != STATUS_SUCCESS) || \ + (chip->rsp_buf[0] & SD_TRANSFER_ERR)) +/* SD Tuning Data Structure */ +/* Record continuous timing phase path */ +struct timing_phase_path { + int start; + int end; + int mid; + int len; +}; + +int sd_select_card(struct rts51x_chip *chip, int select); +int reset_sd_card(struct rts51x_chip *chip); +int sd_switch_clock(struct rts51x_chip *chip); +void sd_stop_seq_mode(struct rts51x_chip *chip); +int sd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, + u16 sector_cnt); +void sd_cleanup_work(struct rts51x_chip *chip); +int sd_power_off_card3v3(struct rts51x_chip *chip); +int release_sd_card(struct rts51x_chip *chip); + +#ifdef SUPPORT_SD_LOCK +int sd_update_lock_status(struct rts51x_chip *chip); +#endif + +#ifdef SUPPORT_CPRM +extern int reset_sd(struct rts51x_chip *chip); +extern int sd_check_data0_status(struct rts51x_chip *chip); +extern int sd_read_data(struct rts51x_chip *chip, u8 trans_mode, u8 *cmd, + int cmd_len, u16 byte_cnt, u16 blk_cnt, u8 bus_width, + u8 *buf, int buf_len, int timeout); +#endif + +#endif /* __RTS51X_SD_H */ diff --git a/drivers/staging/rts5139/sd_cprm.c b/drivers/staging/rts5139/sd_cprm.c new file mode 100644 index 0000000..407cd43 --- /dev/null +++ b/drivers/staging/rts5139/sd_cprm.c @@ -0,0 +1,1215 @@ +/* Driver for Realtek RTS51xx USB card reader + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + * Maintainer: + * Edwin Rong (edwin_rong@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#include <linux/blkdev.h> +#include <linux/kthread.h> +#include <linux/sched.h> +#include <linux/slab.h> + +#include "debug.h" +#include "trace.h" +#include "rts51x.h" +#include "rts51x_transport.h" +#include "rts51x_scsi.h" +#include "rts51x_card.h" +#include "rts51x_chip.h" +#include "sd.h" + +#ifdef SUPPORT_CPRM + +static inline int get_rsp_type(u8 rsp_code, u8 *rsp_type, int *rsp_len) +{ + if (!rsp_type || !rsp_len) + return STATUS_FAIL; + + switch (rsp_code) { + case 0x03: + *rsp_type = SD_RSP_TYPE_R0; /* no response */ + *rsp_len = 0; + break; + + case 0x04: + *rsp_type = SD_RSP_TYPE_R1; /* R1,R6(,R4,R5) */ + *rsp_len = 6; + break; + + case 0x05: + *rsp_type = SD_RSP_TYPE_R1b; /* R1b */ + *rsp_len = 6; + break; + + case 0x06: + *rsp_type = SD_RSP_TYPE_R2; /* R2 */ + *rsp_len = 17; + break; + + case 0x07: + *rsp_type = SD_RSP_TYPE_R3; /* R3 */ + *rsp_len = 6; + break; + + default: + return STATUS_FAIL; + } + + return STATUS_SUCCESS; +} + +int soft_reset_sd_card(struct rts51x_chip *chip) +{ + return reset_sd(chip); +} + +int ext_sd_send_cmd_get_rsp(struct rts51x_chip *chip, u8 cmd_idx, + u32 arg, u8 rsp_type, u8 *rsp, int rsp_len, + int special_check) +{ + int retval; + int timeout = 50; + u16 reg_addr; + u8 buf[17], stat; + int len = 2; + int rty_cnt = 0; + + RTS51X_DEBUGP("EXT SD/MMC CMD %d\n", cmd_idx); + + if (rsp_type == SD_RSP_TYPE_R1b) + timeout = 3000; + +RTY_SEND_CMD: + + rts51x_init_cmd(chip); + + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD0, 0xFF, 0x40 | cmd_idx); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD1, 0xFF, (u8) (arg >> 24)); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD2, 0xFF, (u8) (arg >> 16)); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD3, 0xFF, (u8) (arg >> 8)); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD4, 0xFF, (u8) arg); + + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG2, 0xFF, rsp_type); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, + 0x01, PINGPONG_BUFFER); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, + 0xFF, SD_TM_CMD_RSP | SD_TRANSFER_START); + rts51x_add_cmd(chip, CHECK_REG_CMD, SD_TRANSFER, SD_TRANSFER_END, + SD_TRANSFER_END); + + rts51x_add_cmd(chip, READ_REG_CMD, SD_STAT1, 0, 0); + + if (CHECK_USB(chip, USB_20)) { + if (rsp_type == SD_RSP_TYPE_R2) { + for (reg_addr = PPBUF_BASE2; + reg_addr < PPBUF_BASE2 + 16; reg_addr++) { + rts51x_add_cmd(chip, READ_REG_CMD, reg_addr, 0, + 0); + } + len = 19; + } else if (rsp_type != SD_RSP_TYPE_R0) { + /* Read data from SD_CMDx registers */ + for (reg_addr = SD_CMD0; reg_addr <= SD_CMD4; + reg_addr++) { + rts51x_add_cmd(chip, READ_REG_CMD, reg_addr, 0, + 0); + } + len = 8; + } else { + len = 3; + } + rts51x_add_cmd(chip, READ_REG_CMD, SD_CMD5, 0, 0); + } else { + len = 2; + } + + retval = rts51x_send_cmd(chip, MODE_CR, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = rts51x_get_rsp(chip, len, timeout); + + if (CHECK_SD_TRANS_FAIL(chip, retval)) { + rts51x_clear_sd_error(chip); + + if (retval == STATUS_TIMEDOUT) { + if (rsp_type & SD_WAIT_BUSY_END) { + retval = sd_check_data0_status(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } + } + TRACE_RET(chip, STATUS_FAIL); + } + + if (rsp_type == SD_RSP_TYPE_R0) + return STATUS_SUCCESS; + + if (CHECK_USB(chip, USB_20)) { + rts51x_read_rsp_buf(chip, 2, buf, len - 2); + } else { + if (rsp_type == SD_RSP_TYPE_R2) { + reg_addr = PPBUF_BASE2; + len = 16; + } else { + reg_addr = SD_CMD0; + len = 5; + } + retval = + rts51x_seq_read_register(chip, reg_addr, + (unsigned short)len, buf); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + RTS51X_READ_REG(chip, SD_CMD5, buf + len); + } + stat = chip->rsp_buf[1]; + + if ((buf[0] & 0xC0) != 0) + TRACE_RET(chip, STATUS_FAIL); + + if (!(rsp_type & SD_NO_CHECK_CRC7)) { + if (stat & SD_CRC7_ERR) { + if (cmd_idx == WRITE_MULTIPLE_BLOCK) + TRACE_RET(chip, STATUS_FAIL); + if (rty_cnt < SD_MAX_RETRY_COUNT) { + wait_timeout(20); + rty_cnt++; + goto RTY_SEND_CMD; + } else { + TRACE_RET(chip, STATUS_FAIL); + } + } + } + + if ((cmd_idx == SELECT_CARD) || (cmd_idx == APP_CMD) || + (cmd_idx == SEND_STATUS) || (cmd_idx == STOP_TRANSMISSION)) { + if ((cmd_idx != STOP_TRANSMISSION) && (special_check == 0)) { + if (buf[1] & 0x80) + TRACE_RET(chip, STATUS_FAIL); + } +#ifdef SUPPORT_SD_LOCK + if (buf[1] & 0x7D) { +#else + if (buf[1] & 0x7F) { +#endif + TRACE_RET(chip, STATUS_FAIL); + } + if (buf[2] & 0xF8) + TRACE_RET(chip, STATUS_FAIL); + + if (cmd_idx == SELECT_CARD) { + if (rsp_type == SD_RSP_TYPE_R2) { + if ((buf[3] & 0x1E) != 0x04) + TRACE_RET(chip, STATUS_FAIL); + } else if (rsp_type == SD_RSP_TYPE_R2) { + if ((buf[3] & 0x1E) != 0x03) + TRACE_RET(chip, STATUS_FAIL); + } + } + } + + if (rsp && rsp_len) + memcpy(rsp, buf, rsp_len); + + return STATUS_SUCCESS; +} + +int ext_sd_get_rsp(struct rts51x_chip *chip, int len, u8 * rsp, u8 rsp_type) +{ + int retval, rsp_len; + u16 reg_addr; + + if (rsp_type == SD_RSP_TYPE_R0) + return STATUS_SUCCESS; + + rts51x_init_cmd(chip); + + if (rsp_type == SD_RSP_TYPE_R2) { + for (reg_addr = PPBUF_BASE2; reg_addr < PPBUF_BASE2 + 16; + reg_addr++) { + rts51x_add_cmd(chip, READ_REG_CMD, reg_addr, 0xFF, 0); + } + rsp_len = 17; + } else if (rsp_type != SD_RSP_TYPE_R0) { + for (reg_addr = SD_CMD0; reg_addr <= SD_CMD4; reg_addr++) + rts51x_add_cmd(chip, READ_REG_CMD, reg_addr, 0xFF, 0); + rsp_len = 6; + } + rts51x_add_cmd(chip, READ_REG_CMD, SD_CMD5, 0xFF, 0); + + retval = rts51x_send_cmd(chip, MODE_CR, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = rts51x_get_rsp(chip, rsp_len, 100); + + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + if (rsp) { + int min_len = (rsp_len < len) ? rsp_len : len; + + memcpy(rsp, rts51x_get_rsp_data(chip), min_len); + + RTS51X_DEBUGP("min_len = %d\n", min_len); + RTS51X_DEBUGP("Response in cmd buf: 0x%x 0x%x 0x%x 0x%x\n", + rsp[0], rsp[1], rsp[2], rsp[3]); + } + + return STATUS_SUCCESS; +} + +int ext_sd_execute_no_data(struct rts51x_chip *chip, unsigned int lun, + u8 cmd_idx, u8 standby, u8 acmd, u8 rsp_code, + u32 arg) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval, rsp_len; + u8 rsp_type; + + retval = sd_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); + + if (sd_card->pre_cmd_err) { + sd_card->pre_cmd_err = 0; + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); + TRACE_RET(chip, TRANSPORT_FAILED); + } + retval = get_rsp_type(rsp_code, &rsp_type, &rsp_len); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + sd_card->last_rsp_type = rsp_type; + + retval = sd_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); +#ifdef SUPPORT_SD_LOCK + if ((sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) == 0) { + if (CHK_MMC_8BIT(sd_card)) { + retval = + rts51x_write_register(chip, SD_CFG1, 0x03, + SD_BUS_WIDTH_8); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); + } else if (CHK_SD(sd_card) || CHK_MMC_4BIT(sd_card)) { + retval = + rts51x_write_register(chip, SD_CFG1, 0x03, + SD_BUS_WIDTH_4); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); + } + } +#else + /* Set H/W SD/MMC Bus Width */ + rts51x_write_register(chip, SD_CFG1, 0x03, SD_BUS_WIDTH_4); +#endif + + if (standby) { + retval = sd_select_card(chip, 0); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Cmd_Failed); + } + + if (acmd) { + retval = + ext_sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0, 0); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Cmd_Failed); + } + + retval = ext_sd_send_cmd_get_rsp(chip, cmd_idx, arg, rsp_type, + sd_card->rsp, rsp_len, 0); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Cmd_Failed); + + if (standby) { + retval = sd_select_card(chip, 1); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Cmd_Failed); + } +#ifdef SUPPORT_SD_LOCK + /* Get SD lock status */ + retval = sd_update_lock_status(chip); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Cmd_Failed); +#endif + + return TRANSPORT_GOOD; + +SD_Execute_Cmd_Failed: + sd_card->pre_cmd_err = 1; + set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); + release_sd_card(chip); + do_reset_sd_card(chip); + if (!(chip->card_ready & SD_CARD)) + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + + TRACE_RET(chip, TRANSPORT_FAILED); +} + +int ext_sd_execute_read_data(struct rts51x_chip *chip, unsigned int lun, + u8 cmd_idx, u8 cmd12, u8 standby, + u8 acmd, u8 rsp_code, u32 arg, u32 data_len, + void *data_buf, unsigned int buf_len, int use_sg) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval, rsp_len, i; + int cmd13_checkbit = 0, read_err = 0; + u8 rsp_type, bus_width; + + if (sd_card->pre_cmd_err) { + sd_card->pre_cmd_err = 0; + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + retval = sd_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + retval = get_rsp_type(rsp_code, &rsp_type, &rsp_len); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + sd_card->last_rsp_type = rsp_type; + + retval = sd_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); +#ifdef SUPPORT_SD_LOCK + if ((sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) == 0) { + if (CHK_MMC_8BIT(sd_card)) + bus_width = SD_BUS_WIDTH_8; + else if (CHK_SD(sd_card) || CHK_MMC_4BIT(sd_card)) + bus_width = SD_BUS_WIDTH_4; + else + bus_width = SD_BUS_WIDTH_1; + } else { + bus_width = SD_BUS_WIDTH_4; + } + RTS51X_DEBUGP("bus_width = %d\n", bus_width); +#else + bus_width = SD_BUS_WIDTH_4; +#endif + + if (data_len < 512) { + retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, data_len, + SD_RSP_TYPE_R1, NULL, 0, 0); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); + } + + if (standby) { + retval = sd_select_card(chip, 0); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); + } + + if (acmd) { + retval = + ext_sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0, 0); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); + } + + if (data_len <= 512) { + int min_len; + u8 *buf; + u16 byte_cnt, blk_cnt; + u8 cmd[5]; + unsigned int offset = 0; + void *sg = NULL; + + byte_cnt = (u16) (data_len & 0x3FF); + blk_cnt = 1; + + cmd[0] = 0x40 | cmd_idx; + cmd[1] = (u8) (arg >> 24); + cmd[2] = (u8) (arg >> 16); + cmd[3] = (u8) (arg >> 8); + cmd[4] = (u8) arg; + + buf = kmalloc(data_len, GFP_KERNEL); + if (buf == NULL) + TRACE_RET(chip, TRANSPORT_ERROR); + + retval = sd_read_data(chip, SD_TM_NORMAL_READ, cmd, 5, byte_cnt, + blk_cnt, bus_width, buf, data_len, 2000); + if (retval != STATUS_SUCCESS) { + read_err = 1; + kfree(buf); + rts51x_write_register(chip, CARD_STOP, + SD_STOP | SD_CLR_ERR, + SD_STOP | SD_CLR_ERR); + TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); + } + + min_len = min(data_len, buf_len); + if (use_sg) + rts51x_access_sglist(buf, min_len, (void *)data_buf, + &sg, &offset, TO_XFER_BUF); + else + memcpy(data_buf, buf, min_len); + + kfree(buf); + } else if (!(data_len & 0x1FF)) { + rts51x_init_cmd(chip); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_H, 0xFF, 0x02); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, 0x00); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_H, + 0xFF, (u8) (data_len >> 17)); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_L, + 0xFF, (u8) ((data_len & 0x0001FE00) >> 9)); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD0, 0xFF, + 0x40 | cmd_idx); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD1, 0xFF, + (u8) (arg >> 24)); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD2, 0xFF, + (u8) (arg >> 16)); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD3, 0xFF, + (u8) (arg >> 8)); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CMD4, 0xFF, (u8) arg); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG1, 0x03, bus_width); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_CFG2, 0xFF, rsp_type); + trans_dma_enable(DMA_FROM_DEVICE, chip, data_len, DMA_512); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, 0xFF, + SD_TM_AUTO_READ_2 | SD_TRANSFER_START); + rts51x_add_cmd(chip, CHECK_REG_CMD, SD_TRANSFER, + SD_TRANSFER_END, SD_TRANSFER_END); + retval = rts51x_send_cmd(chip, MODE_CDIR, 100); + if (retval != STATUS_SUCCESS) { + read_err = 1; + rts51x_ep0_write_register(chip, CARD_STOP, + SD_STOP | SD_CLR_ERR, + SD_STOP | SD_CLR_ERR); + TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); + } + + retval = + rts51x_transfer_data_rcc(chip, RCV_BULK_PIPE(chip), + data_buf, buf_len, use_sg, NULL, + 10000, STAGE_DI); + if (retval != STATUS_SUCCESS) { + read_err = 1; + rts51x_ep0_write_register(chip, CARD_STOP, + SD_STOP | SD_CLR_ERR, + SD_STOP | SD_CLR_ERR); + TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); + } + retval = rts51x_get_rsp(chip, 1, 500); + if (CHECK_SD_TRANS_FAIL(chip, retval)) { + read_err = 1; + rts51x_ep0_write_register(chip, CARD_STOP, + SD_STOP | SD_CLR_ERR, + SD_STOP | SD_CLR_ERR); + TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); + } + } else { + TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); + } + + retval = ext_sd_get_rsp(chip, rsp_len, sd_card->rsp, rsp_type); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); + + if (standby) { + retval = sd_select_card(chip, 1); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); + } + + if (cmd12) { + retval = ext_sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, + 0, SD_RSP_TYPE_R1b, NULL, 0, + 0); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); + } + + if (data_len < 512) { + retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200, + SD_RSP_TYPE_R1, NULL, 0, 0); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); + + rts51x_write_register(chip, SD_BYTE_CNT_H, 0xFF, 0x02); + rts51x_write_register(chip, SD_BYTE_CNT_L, 0xFF, 0x00); + } + + if (standby || cmd12) + cmd13_checkbit = 1; + + for (i = 0; i < 3; i++) { + retval = + ext_sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0, + cmd13_checkbit); + if (retval == STATUS_SUCCESS) + break; + } + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Read_Cmd_Failed); + + return TRANSPORT_GOOD; + +SD_Execute_Read_Cmd_Failed: + sd_card->pre_cmd_err = 1; + set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); + if (read_err) + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + release_sd_card(chip); + do_reset_sd_card(chip); + if (!(chip->card_ready & SD_CARD)) + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + + TRACE_RET(chip, TRANSPORT_FAILED); +} + +int ext_sd_execute_write_data(struct rts51x_chip *chip, unsigned int lun, + u8 cmd_idx, u8 cmd12, u8 standby, u8 acmd, + u8 rsp_code, u32 arg, u32 data_len, + void *data_buf, unsigned int buf_len, int use_sg) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval, rsp_len; + int cmd13_checkbit = 0, write_err = 0; + u8 rsp_type; + u32 i; +#ifdef SUPPORT_SD_LOCK + int lock_cmd_fail = 0; + u8 sd_lock_state = 0; + u8 lock_cmd_type = 0; +#endif + + if (sd_card->pre_cmd_err) { + sd_card->pre_cmd_err = 0; + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + retval = sd_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); +#ifdef SUPPORT_SD_LOCK + if (cmd_idx == LOCK_UNLOCK) { + sd_lock_state = sd_card->sd_lock_status; + sd_lock_state &= SD_LOCKED; + } +#endif + + retval = get_rsp_type(rsp_code, &rsp_type, &rsp_len); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + sd_card->last_rsp_type = rsp_type; + + retval = sd_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); +#ifdef SUPPORT_SD_LOCK + if ((sd_card->sd_lock_status & SD_LOCK_1BIT_MODE) == 0) { + if (CHK_MMC_8BIT(sd_card)) { + retval = + rts51x_write_register(chip, SD_CFG1, 0x03, + SD_BUS_WIDTH_8); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); + } else if (CHK_SD(sd_card) || CHK_MMC_4BIT(sd_card)) { + retval = + rts51x_write_register(chip, SD_CFG1, 0x03, + SD_BUS_WIDTH_4); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, TRANSPORT_FAILED); + } + } +#else + rts51x_write_register(chip, SD_CFG1, 0x03, SD_BUS_WIDTH_4); +#endif + + if (data_len < 512) { + retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, data_len, + SD_RSP_TYPE_R1, NULL, 0, 0); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + } + + if (standby) { + retval = sd_select_card(chip, 0); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + } + + if (acmd) { + retval = + ext_sd_send_cmd_get_rsp(chip, APP_CMD, sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0, 0); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + } + + retval = ext_sd_send_cmd_get_rsp(chip, cmd_idx, arg, rsp_type, + sd_card->rsp, rsp_len, 0); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + + if (data_len <= 512) { + u8 *buf; + unsigned int offset = 0; + void *sg = NULL; + + buf = kmalloc(data_len, GFP_KERNEL); + if (buf == NULL) + TRACE_RET(chip, TRANSPORT_ERROR); + + if (use_sg) + rts51x_access_sglist(buf, data_len, (void *)data_buf, + &sg, &offset, FROM_XFER_BUF); + else + memcpy(buf, data_buf, data_len); + +#ifdef SUPPORT_SD_LOCK + if (cmd_idx == LOCK_UNLOCK) + lock_cmd_type = buf[0] & 0x0F; +#endif + + if (data_len > 256) { + rts51x_init_cmd(chip); + for (i = 0; i < 256; i++) { + rts51x_add_cmd(chip, WRITE_REG_CMD, + (u16) (PPBUF_BASE2 + i), 0xFF, + buf[i]); + } + retval = rts51x_send_cmd(chip, MODE_C, 250); + if (retval != STATUS_SUCCESS) { + kfree(buf); + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + } + + rts51x_init_cmd(chip); + for (i = 256; i < data_len; i++) { + rts51x_add_cmd(chip, WRITE_REG_CMD, + (u16) (PPBUF_BASE2 + i), 0xFF, + buf[i]); + } + retval = rts51x_send_cmd(chip, MODE_C, 250); + if (retval != STATUS_SUCCESS) { + kfree(buf); + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + } + } else { + rts51x_init_cmd(chip); + for (i = 0; i < data_len; i++) { + rts51x_add_cmd(chip, WRITE_REG_CMD, + (u16) (PPBUF_BASE2 + i), 0xFF, + buf[i]); + } + retval = rts51x_send_cmd(chip, MODE_C, 250); + if (retval != STATUS_SUCCESS) { + kfree(buf); + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + } + } + + kfree(buf); + + rts51x_init_cmd(chip); + + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_H, 0xFF, + (u8) ((data_len >> 8) & 0x03)); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, + (u8) data_len); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_H, 0xFF, 0x00); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_L, 0xFF, 0x01); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, + PINGPONG_BUFFER); + + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, 0xFF, + SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START); + rts51x_add_cmd(chip, CHECK_REG_CMD, SD_TRANSFER, + SD_TRANSFER_END, SD_TRANSFER_END); + + retval = rts51x_send_cmd(chip, MODE_CR, 100); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + + retval = rts51x_get_rsp(chip, 1, 250); + if (CHECK_SD_TRANS_FAIL(chip, retval)) + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + } else if (!(data_len & 0x1FF)) { + rts51x_init_cmd(chip); + + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_H, 0xFF, 0x02); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BYTE_CNT_L, 0xFF, 0x00); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_H, + 0xFF, (u8) (data_len >> 17)); + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_BLOCK_CNT_L, + 0xFF, (u8) ((data_len & 0x0001FE00) >> 9)); + + trans_dma_enable(DMA_TO_DEVICE, chip, data_len, DMA_512); + + rts51x_add_cmd(chip, WRITE_REG_CMD, SD_TRANSFER, 0xFF, + SD_TM_AUTO_WRITE_3 | SD_TRANSFER_START); + rts51x_add_cmd(chip, CHECK_REG_CMD, SD_TRANSFER, + SD_TRANSFER_END, SD_TRANSFER_END); + + retval = rts51x_send_cmd(chip, MODE_CDOR, 100); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + + retval = + rts51x_transfer_data_rcc(chip, SND_BULK_PIPE(chip), + data_buf, buf_len, use_sg, NULL, + 10000, STAGE_DO); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + + retval = rts51x_get_rsp(chip, 1, 10000); + if (CHECK_SD_TRANS_FAIL(chip, retval)) + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + + } else { + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + } + + if (retval < 0) { + write_err = 1; + rts51x_write_register(chip, CARD_STOP, SD_STOP | SD_CLR_ERR, + SD_STOP | SD_CLR_ERR); + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + } +#ifdef SUPPORT_SD_LOCK + if (cmd_idx == LOCK_UNLOCK) { + if (lock_cmd_type == SD_ERASE) { + sd_card->sd_erase_status = SD_UNDER_ERASING; + scsi_set_resid(srb, 0); + return TRANSPORT_GOOD; + } + + rts51x_init_cmd(chip); + rts51x_add_cmd(chip, CHECK_REG_CMD, SD_BUS_STAT, SD_DAT0_STATUS, + SD_DAT0_STATUS); + retval = rts51x_send_cmd(chip, MODE_CR, 250); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + rts51x_get_rsp(chip, 1, 200); /* Don't care return value */ + + retval = sd_update_lock_status(chip); + if (retval != STATUS_SUCCESS) { + RTS51X_DEBUGP("Lock command fail!\n"); + lock_cmd_fail = 1; + } + } +#endif /* SUPPORT_SD_LOCK */ + + if (standby) { + retval = sd_select_card(chip, 1); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + } + + if (cmd12) { + retval = ext_sd_send_cmd_get_rsp(chip, STOP_TRANSMISSION, + 0, SD_RSP_TYPE_R1b, NULL, 0, + 0); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + } + + if (data_len < 512) { + retval = ext_sd_send_cmd_get_rsp(chip, SET_BLOCKLEN, 0x200, + SD_RSP_TYPE_R1, NULL, 0, 0); + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); + + rts51x_write_register(chip, SD_BYTE_CNT_H, 0xFF, 0x02); + rts51x_write_register(chip, SD_BYTE_CNT_L, 0xFF, 0x00); + } + + if (cmd12 || standby) { + /* There is CMD7 or CMD12 sent before CMD13 */ + cmd13_checkbit = 1; + } + + for (i = 0; i < 3; i++) { + retval = + ext_sd_send_cmd_get_rsp(chip, SEND_STATUS, sd_card->sd_addr, + SD_RSP_TYPE_R1, NULL, 0, + cmd13_checkbit); + if (retval == STATUS_SUCCESS) + break; + } + if (retval != STATUS_SUCCESS) + TRACE_GOTO(chip, SD_Execute_Write_Cmd_Failed); +#ifdef SUPPORT_SD_LOCK + if (cmd_idx == LOCK_UNLOCK) { + if (!lock_cmd_fail) { + RTS51X_DEBUGP("lock_cmd_type = 0x%x\n", + lock_cmd_type); + if (lock_cmd_type & SD_CLR_PWD) + sd_card->sd_lock_status &= ~SD_PWD_EXIST; + if (lock_cmd_type & SD_SET_PWD) + sd_card->sd_lock_status |= SD_PWD_EXIST; + } + + RTS51X_DEBUGP("sd_lock_state = 0x%x," + "sd_card->sd_lock_status = 0x%x\n", + sd_lock_state, sd_card->sd_lock_status); + if (sd_lock_state ^ (sd_card->sd_lock_status & SD_LOCKED)) { + sd_card->sd_lock_notify = 1; + if (sd_lock_state) { + if (sd_card->sd_lock_status & + SD_LOCK_1BIT_MODE) { + sd_card->sd_lock_status |= + (SD_UNLOCK_POW_ON | SD_SDR_RST); + if (CHK_SD(sd_card)) { + retval = reset_sd(chip); + if (retval != STATUS_SUCCESS) { + sd_card->sd_lock_status + &= ~(SD_UNLOCK_POW_ON | + SD_SDR_RST); + TRACE_GOTO(chip, + SD_Execute_Write_Cmd_Failed); + } + } + + sd_card->sd_lock_status &= + ~(SD_UNLOCK_POW_ON | SD_SDR_RST); + } + } + } + } + + if (lock_cmd_fail) { + scsi_set_resid(srb, 0); + set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); + TRACE_RET(chip, TRANSPORT_FAILED); + } +#endif /* SUPPORT_SD_LOCK */ + + return TRANSPORT_GOOD; + +SD_Execute_Write_Cmd_Failed: + sd_card->pre_cmd_err = 1; + set_sense_type(chip, lun, SENSE_TYPE_NO_SENSE); + if (write_err) + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_WRITE_ERR); + release_sd_card(chip); + do_reset_sd_card(chip); + if (!(chip->card_ready & SD_CARD)) + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + + TRACE_RET(chip, TRANSPORT_FAILED); +} + +int sd_pass_thru_mode(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + unsigned int lun = SCSI_LUN(srb); + int len; + u8 buf[18] = { + 0x00, + 0x00, + 0x00, + 0x0E, + 0x00, /* Version Number */ + 0x00, /* WP | Media Type */ + 0x00, /* RCA (Low byte) */ + 0x00, /* RCA (High byte) */ + 0x53, /* 'S' */ + 0x44, /* 'D' */ + 0x20, /* ' ' */ + 0x43, /* 'C' */ + 0x61, /* 'a' */ + 0x72, /* 'r' */ + 0x64, /* 'd' */ + 0x00, /* Max LUN Number */ + 0x00, + 0x00, + }; + + sd_card->pre_cmd_err = 0; + + if (!(CHK_BIT(chip->lun_mc, lun))) { + SET_BIT(chip->lun_mc, lun); + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if ((0x53 != srb->cmnd[2]) || (0x44 != srb->cmnd[3]) + || (0x20 != srb->cmnd[4]) || (0x43 != srb->cmnd[5]) + || (0x61 != srb->cmnd[6]) || (0x72 != srb->cmnd[7]) + || (0x64 != srb->cmnd[8])) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + switch (srb->cmnd[1] & 0x0F) { + case 0: + sd_card->sd_pass_thru_en = 0; + break; + + case 1: + sd_card->sd_pass_thru_en = 1; + break; + + default: + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + /* 0x01:SD Memory Card; 0x02:Other Media; 0x03:Illegal Media; */ + buf[5] = (1 == CHK_SD(sd_card)) ? 0x01 : 0x02; + if (chip->card_wp & SD_CARD) + buf[5] |= 0x80; + + buf[6] = (u8) (sd_card->sd_addr >> 16); + buf[7] = (u8) (sd_card->sd_addr >> 24); + + buf[15] = chip->max_lun; + + len = min(18, (int)scsi_bufflen(srb)); + rts51x_set_xfer_buf(buf, len, srb); + + return TRANSPORT_GOOD; +} + +int sd_execute_no_data(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + unsigned int lun = SCSI_LUN(srb); + int retval; + u8 cmd_idx, rsp_code; + u8 standby = 0, acmd = 0; + u32 arg; + + if (!sd_card->sd_pass_thru_en) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + cmd_idx = srb->cmnd[2] & 0x3F; + if (srb->cmnd[1] & 0x02) + standby = 1; + if (srb->cmnd[1] & 0x01) + acmd = 1; + + arg = ((u32) srb->cmnd[3] << 24) | ((u32) srb->cmnd[4] << 16) | + ((u32) srb->cmnd[5] << 8) | srb->cmnd[6]; + + rsp_code = srb->cmnd[10]; + + retval = + ext_sd_execute_no_data(chip, lun, cmd_idx, standby, acmd, rsp_code, + arg); + scsi_set_resid(srb, 0); + return retval; +} + +int sd_execute_read_data(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + unsigned int lun = SCSI_LUN(srb); + u8 cmd_idx, rsp_code, send_cmd12 = 0, standby = 0, acmd = 0; + u32 arg, data_len; + + if (!sd_card->sd_pass_thru_en) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + cmd_idx = srb->cmnd[2] & 0x3F; + if (srb->cmnd[1] & 0x04) + send_cmd12 = 1; + if (srb->cmnd[1] & 0x02) + standby = 1; + if (srb->cmnd[1] & 0x01) + acmd = 1; + + arg = ((u32) srb->cmnd[3] << 24) | ((u32) srb->cmnd[4] << 16) | + ((u32) srb->cmnd[5] << 8) | srb->cmnd[6]; + + data_len = + ((u32) srb->cmnd[7] << 16) | ((u32) srb->cmnd[8] << 8) | + srb->cmnd[9]; + rsp_code = srb->cmnd[10]; + + retval = + ext_sd_execute_read_data(chip, lun, cmd_idx, send_cmd12, standby, + acmd, rsp_code, arg, data_len, + scsi_sglist(srb), scsi_bufflen(srb), + scsi_sg_count(srb)); + scsi_set_resid(srb, 0); + return retval; +} + +int sd_execute_write_data(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + int retval; + unsigned int lun = SCSI_LUN(srb); + u8 cmd_idx, rsp_code, send_cmd12 = 0, standby = 0, acmd = 0; + u32 data_len, arg; + + if (!sd_card->sd_pass_thru_en) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + cmd_idx = srb->cmnd[2] & 0x3F; + if (srb->cmnd[1] & 0x04) + send_cmd12 = 1; + if (srb->cmnd[1] & 0x02) + standby = 1; + if (srb->cmnd[1] & 0x01) + acmd = 1; + + data_len = + ((u32) srb->cmnd[7] << 16) | ((u32) srb->cmnd[8] << 8) | + srb->cmnd[9]; + arg = + ((u32) srb->cmnd[3] << 24) | ((u32) srb->cmnd[4] << 16) | + ((u32) srb->cmnd[5] << 8) | srb->cmnd[6]; + rsp_code = srb->cmnd[10]; + + retval = + ext_sd_execute_write_data(chip, lun, cmd_idx, send_cmd12, standby, + acmd, rsp_code, arg, data_len, + scsi_sglist(srb), scsi_bufflen(srb), + scsi_sg_count(srb)); + scsi_set_resid(srb, 0); + return retval; +} + +int sd_get_cmd_rsp(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + unsigned int lun = SCSI_LUN(srb); + int count; + u16 data_len; + + if (!sd_card->sd_pass_thru_en) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (sd_card->pre_cmd_err) { + sd_card->pre_cmd_err = 0; + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + data_len = ((u16) srb->cmnd[7] << 8) | srb->cmnd[8]; + + if (sd_card->last_rsp_type == SD_RSP_TYPE_R0) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } else if (sd_card->last_rsp_type == SD_RSP_TYPE_R2) { + count = (data_len < 17) ? data_len : 17; + } else { + count = (data_len < 6) ? data_len : 6; + } + rts51x_set_xfer_buf(sd_card->rsp, count, srb); + + RTS51X_DEBUGP("Response length: %d\n", data_len); + RTS51X_DEBUGP("Response: 0x%x 0x%x 0x%x 0x%x\n", + sd_card->rsp[0], sd_card->rsp[1], sd_card->rsp[2], + sd_card->rsp[3]); + + scsi_set_resid(srb, 0); + return TRANSPORT_GOOD; +} + +int sd_hw_rst(struct scsi_cmnd *srb, struct rts51x_chip *chip) +{ + struct sd_info *sd_card = &(chip->sd_card); + unsigned int lun = SCSI_LUN(srb); + int retval; + + if (!sd_card->sd_pass_thru_en) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if (sd_card->pre_cmd_err) { + sd_card->pre_cmd_err = 0; + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_CHANGE); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + if ((0x53 != srb->cmnd[2]) || (0x44 != srb->cmnd[3]) + || (0x20 != srb->cmnd[4]) || (0x43 != srb->cmnd[5]) + || (0x61 != srb->cmnd[6]) || (0x72 != srb->cmnd[7]) + || (0x64 != srb->cmnd[8])) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + switch (srb->cmnd[1] & 0x0F) { + case 0: + /* SD Card Power Off -> ON and Initialization */ +#ifdef SUPPORT_SD_LOCK + if (0x64 == srb->cmnd[9]) { + /* Command Mode */ + sd_card->sd_lock_status |= SD_SDR_RST; + } +#endif /* SUPPORT_SD_LOCK */ + retval = reset_sd_card(chip); + if (retval != STATUS_SUCCESS) { +#ifdef SUPPORT_SD_LOCK + sd_card->sd_lock_status &= ~SD_SDR_RST; +#endif + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + sd_card->pre_cmd_err = 1; + TRACE_RET(chip, TRANSPORT_FAILED); + } +#ifdef SUPPORT_SD_LOCK + sd_card->sd_lock_status &= ~SD_SDR_RST; +#endif + break; + + case 1: + /* reset CMD(CMD0) and Initialization + * (without SD Card Power Off -> ON) */ + retval = soft_reset_sd_card(chip); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + sd_card->pre_cmd_err = 1; + TRACE_RET(chip, TRANSPORT_FAILED); + } + break; + + default: + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_INVALID_CMD_FIELD); + TRACE_RET(chip, TRANSPORT_FAILED); + } + + scsi_set_resid(srb, 0); + return TRANSPORT_GOOD; +} +#endif diff --git a/drivers/staging/rts5139/sd_cprm.h b/drivers/staging/rts5139/sd_cprm.h new file mode 100644 index 0000000..75e263b --- /dev/null +++ b/drivers/staging/rts5139/sd_cprm.h @@ -0,0 +1,54 @@ +/* Driver for Realtek RTS51xx USB card reader + * Header file + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + * Maintainer: + * Edwin Rong (edwin_rong@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#ifndef __RTS51X_SD_CPRM_H +#define __RTS51X_SD_CPRM_H + +#include "rts51x_chip.h" +#include "sd.h" + +#ifdef SUPPORT_CPRM +int ext_sd_execute_no_data(struct rts51x_chip *chip, unsigned int lun, + u8 cmd_idx, u8 standby, u8 acmd, u8 rsp_code, + u32 arg); +int ext_sd_execute_read_data(struct rts51x_chip *chip, unsigned int lun, + u8 cmd_idx, u8 cmd12, u8 standby, u8 acmd, + u8 rsp_code, u32 arg, u32 data_len, void *data_buf, + unsigned int buf_len, int use_sg); +int ext_sd_execute_write_data(struct rts51x_chip *chip, unsigned int lun, + u8 cmd_idx, u8 cmd12, u8 standby, u8 acmd, + u8 rsp_code, u32 arg, u32 data_len, + void *data_buf, unsigned int buf_len, int use_sg); + +int sd_pass_thru_mode(struct scsi_cmnd *srb, struct rts51x_chip *chip); +int sd_execute_no_data(struct scsi_cmnd *srb, struct rts51x_chip *chip); +int sd_execute_read_data(struct scsi_cmnd *srb, struct rts51x_chip *chip); +int sd_execute_write_data(struct scsi_cmnd *srb, struct rts51x_chip *chip); +int sd_get_cmd_rsp(struct scsi_cmnd *srb, struct rts51x_chip *chip); +int sd_hw_rst(struct scsi_cmnd *srb, struct rts51x_chip *chip); +#endif + +#endif /* __RTS51X_SD_CPRM_H */ diff --git a/drivers/staging/rts5139/trace.h b/drivers/staging/rts5139/trace.h new file mode 100644 index 0000000..0584b8a --- /dev/null +++ b/drivers/staging/rts5139/trace.h @@ -0,0 +1,137 @@ +/* Driver for Realtek RTS51xx USB card reader + * Header file + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + * Maintainer: + * Edwin Rong (edwin_rong@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#ifndef __RTS51X_TRACE_H +#define __RTS51X_TRACE_H + +#include "debug.h" + +#define _MSG_TRACE + +#ifdef _MSG_TRACE +static inline char *filename(char *path) +{ + char *ptr; + + if (path == NULL) + return NULL; + + ptr = path; + + while (*ptr != '\0') { + if ((*ptr == '\\') || (*ptr == '/')) + path = ptr + 1; + ptr++; + } + + return path; +} + +#define TRACE_RET(chip, ret) \ +do { \ + char *_file = filename((char *)__FILE__); \ + RTS51X_DEBUGP("[%s][%s]:[%d]\n", _file, __func__, __LINE__); \ + (chip)->trace_msg[(chip)->msg_idx].line = (u16)(__LINE__); \ + strncpy((chip)->trace_msg[(chip)->msg_idx].func, \ + __func__, MSG_FUNC_LEN-1); \ + strncpy((chip)->trace_msg[(chip)->msg_idx].file, \ + _file, MSG_FILE_LEN-1); \ + get_current_time((chip)->trace_msg[(chip)->msg_idx].timeval_buf,\ + TIME_VAL_LEN); \ + (chip)->trace_msg[(chip)->msg_idx].valid = 1; \ + (chip)->msg_idx++; \ + if ((chip)->msg_idx >= TRACE_ITEM_CNT) { \ + (chip)->msg_idx = 0; \ + } \ + return ret; \ +} while (0) + +#define TRACE_GOTO(chip, label) \ +do { \ + char *_file = filename((char *)__FILE__); \ + RTS51X_DEBUGP("[%s][%s]:[%d]\n", _file, __func__, __LINE__); \ + (chip)->trace_msg[(chip)->msg_idx].line = (u16)(__LINE__); \ + strncpy((chip)->trace_msg[(chip)->msg_idx].func, \ + __func__, MSG_FUNC_LEN-1); \ + strncpy((chip)->trace_msg[(chip)->msg_idx].file, \ + _file, MSG_FILE_LEN-1); \ + get_current_time((chip)->trace_msg[(chip)->msg_idx].timeval_buf,\ + TIME_VAL_LEN); \ + (chip)->trace_msg[(chip)->msg_idx].valid = 1; \ + (chip)->msg_idx++; \ + if ((chip)->msg_idx >= TRACE_ITEM_CNT) { \ + (chip)->msg_idx = 0; \ + } \ + goto label; \ +} while (0) +#else +#define TRACE_RET(chip, ret) return (ret) +#define TRACE_GOTO(chip, label) goto label +#endif + +#ifdef CONFIG_RTS5139_DEBUG +static inline void rts51x_dump(u8 *buf, int buf_len) +{ + int i; + u8 tmp[16] = { 0 }; + u8 *_ptr = buf; + + for (i = 0; i < ((buf_len) / 16); i++) { + RTS51X_DEBUGP("%02x %02x %02x %02x %02x %02x %02x %02x " + "%02x %02x %02x %02x %02x %02x %02x %02x\n", + _ptr[0], _ptr[1], _ptr[2], _ptr[3], _ptr[4], + _ptr[5], _ptr[6], _ptr[7], _ptr[8], _ptr[9], + _ptr[10], _ptr[11], _ptr[12], _ptr[13], _ptr[14], + _ptr[15]); + _ptr += 16; + } + if ((buf_len) % 16) { + memcpy(tmp, _ptr, (buf_len) % 16); + _ptr = tmp; + RTS51X_DEBUGP("%02x %02x %02x %02x %02x %02x %02x %02x " + "%02x %02x %02x %02x %02x %02x %02x %02x\n", + _ptr[0], _ptr[1], _ptr[2], _ptr[3], _ptr[4], + _ptr[5], _ptr[6], _ptr[7], _ptr[8], _ptr[9], + _ptr[10], _ptr[11], _ptr[12], _ptr[13], _ptr[14], + _ptr[15]); + } +} + +#define RTS51X_DUMP(buf, buf_len) \ + rts51x_dump((u8 *)(buf), (buf_len)) + +#define CATCH_TRIGGER(chip) \ +do { \ + rts51x_ep0_write_register((chip), 0xFC31, 0x01, 0x01); \ + RTS51X_DEBUGP("Catch trigger!\n"); \ +} while (0) + +#else +#define RTS51X_DUMP(buf, buf_len) +#define CATCH_TRIGGER(chip) +#endif + +#endif /* __RTS51X_TRACE_H */ diff --git a/drivers/staging/rts5139/xd.c b/drivers/staging/rts5139/xd.c new file mode 100644 index 0000000..5820605 --- /dev/null +++ b/drivers/staging/rts5139/xd.c @@ -0,0 +1,2255 @@ +/* Driver for Realtek RTS51xx USB card reader + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + * Maintainer: + * Edwin Rong (edwin_rong@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#include <linux/blkdev.h> +#include <linux/kthread.h> +#include <linux/sched.h> +#include <linux/vmalloc.h> + +#include "debug.h" +#include "trace.h" +#include "rts51x.h" +#include "rts51x_transport.h" +#include "rts51x_scsi.h" +#include "rts51x_card.h" +#include "xd.h" + +static int xd_build_l2p_tbl(struct rts51x_chip *chip, int zone_no); +static int xd_init_page(struct rts51x_chip *chip, u32 phy_blk, u16 logoff, + u8 start_page, u8 end_page); + +static inline void xd_set_err_code(struct rts51x_chip *chip, u8 err_code) +{ + struct xd_info *xd_card = &(chip->xd_card); + + xd_card->err_code = err_code; +} + +static inline int xd_check_err_code(struct rts51x_chip *chip, u8 err_code) +{ + struct xd_info *xd_card = &(chip->xd_card); + + return (xd_card->err_code == err_code); +} + +static int xd_set_init_para(struct rts51x_chip *chip) +{ + struct xd_info *xd_card = &(chip->xd_card); + int retval; + + if (chip->asic_code) + xd_card->xd_clock = 47; + else + xd_card->xd_clock = CLK_50; + + retval = switch_clock(chip, xd_card->xd_clock); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + return STATUS_SUCCESS; +} + +static int xd_switch_clock(struct rts51x_chip *chip) +{ + struct xd_info *xd_card = &(chip->xd_card); + int retval; + + retval = rts51x_select_card(chip, XD_CARD); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = switch_clock(chip, xd_card->xd_clock); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + return STATUS_SUCCESS; +} + +static int xd_read_id(struct rts51x_chip *chip, u8 id_cmd, u8 *id_buf, + u8 buf_len) +{ + int retval, i; + + rts51x_init_cmd(chip); + + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_DAT, 0xFF, id_cmd); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, + XD_TRANSFER_START | XD_READ_ID); + rts51x_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, + XD_TRANSFER_END); + + for (i = 0; i < 4; i++) { + rts51x_add_cmd(chip, READ_REG_CMD, (u16) (XD_ADDRESS1 + i), 0, + 0); + } + + retval = rts51x_send_cmd(chip, MODE_CR, 20); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = rts51x_get_rsp(chip, 5, 20); + + if (retval != STATUS_SUCCESS) { + rts51x_clear_xd_error(chip); + TRACE_RET(chip, retval); + } + + if (id_buf && buf_len) { + if (buf_len > 4) + buf_len = 4; + rts51x_read_rsp_buf(chip, 1, id_buf, buf_len); + } + + return STATUS_SUCCESS; +} + +static void xd_assign_phy_addr(struct rts51x_chip *chip, u32 addr, u8 mode) +{ + struct xd_info *xd_card = &(chip->xd_card); + + switch (mode) { + case XD_RW_ADDR: + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS0, 0xFF, 0); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS1, 0xFF, + (u8) addr); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS2, 0xFF, + (u8) (addr >> 8)); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS3, 0xFF, + (u8) (addr >> 16)); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CFG, 0xFF, + xd_card->addr_cycle | XD_CALC_ECC | + XD_BA_NO_TRANSFORM); + break; + + case XD_ERASE_ADDR: + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS0, 0xFF, + (u8) addr); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS1, 0xFF, + (u8) (addr >> 8)); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_ADDRESS2, 0xFF, + (u8) (addr >> 16)); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CFG, 0xFF, + (xd_card->addr_cycle - 1) | + XD_CALC_ECC | XD_BA_NO_TRANSFORM); + break; + + default: + break; + } +} + +static int xd_read_redundant(struct rts51x_chip *chip, u32 page_addr, u8 *buf, + int buf_len) +{ + int retval, i; + + rts51x_init_cmd(chip); + + xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); + + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, + XD_TRANSFER_START | XD_READ_REDUNDANT); + rts51x_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, + XD_TRANSFER_END); + + for (i = 0; i < 6; i++) { + rts51x_add_cmd(chip, READ_REG_CMD, (u16) (XD_PAGE_STATUS + i), + 0, 0); + } + for (i = 0; i < 4; i++) { + rts51x_add_cmd(chip, READ_REG_CMD, (u16) (XD_RESERVED0 + i), 0, + 0); + } + rts51x_add_cmd(chip, READ_REG_CMD, XD_PARITY, 0, 0); + + retval = rts51x_send_cmd(chip, MODE_CR, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = rts51x_get_rsp(chip, 11, 500); + + if (retval != STATUS_SUCCESS) { + rts51x_clear_xd_error(chip); + TRACE_RET(chip, retval); + } + + if (buf && buf_len) { + if (buf_len > 11) + buf_len = 11; + rts51x_read_rsp_buf(chip, 1, buf, buf_len); + } + + return STATUS_SUCCESS; +} + +static int xd_read_data_from_ppb(struct rts51x_chip *chip, int offset, u8 *buf, + int buf_len) +{ + int retval, i; + + if (!buf || (buf_len <= 0)) + TRACE_RET(chip, STATUS_FAIL); + + rts51x_init_cmd(chip); + + for (i = 0; i < buf_len; i++) { + rts51x_add_cmd(chip, READ_REG_CMD, PPBUF_BASE2 + offset + i, 0, + 0); + } + + retval = rts51x_send_cmd(chip, MODE_CR, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = rts51x_get_rsp(chip, buf_len, 200); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + rts51x_read_rsp_buf(chip, 0, buf, buf_len); + + return STATUS_SUCCESS; +} + +static int xd_read_cis(struct rts51x_chip *chip, u32 page_addr, u8 *buf, + int buf_len) +{ + int retval; + u8 reg; + + if (!buf || (buf_len < 10)) + TRACE_RET(chip, STATUS_FAIL); + + rts51x_init_cmd(chip); + + xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); + + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, + PINGPONG_BUFFER); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, 1); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS, + XD_AUTO_CHK_DATA_STATUS, XD_AUTO_CHK_DATA_STATUS); + + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, + XD_TRANSFER_START | XD_READ_PAGES); + rts51x_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, + XD_TRANSFER_END | XD_PPB_EMPTY, + XD_TRANSFER_END | XD_PPB_EMPTY); + + retval = rts51x_send_cmd(chip, MODE_CR, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = rts51x_get_rsp(chip, 1, 500); + if (retval == STATUS_TIMEDOUT) { + rts51x_clear_xd_error(chip); + TRACE_RET(chip, retval); + } + + RTS51X_READ_REG(chip, XD_PAGE_STATUS, ®); + if (reg != XD_GPG) { + rts51x_clear_xd_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + RTS51X_READ_REG(chip, XD_CTL, ®); + + if (!(reg & XD_ECC1_ERROR) || !(reg & XD_ECC1_UNCORRECTABLE)) { + retval = xd_read_data_from_ppb(chip, 0, buf, buf_len); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + if (reg & XD_ECC1_ERROR) { /* correctable error */ + u8 ecc_bit, ecc_byte; + + RTS51X_READ_REG(chip, XD_ECC_BIT1, &ecc_bit); + RTS51X_READ_REG(chip, XD_ECC_BYTE1, &ecc_byte); + + RTS51X_DEBUGP("ECC_BIT1 = 0x%x, ECC_BYTE1 = 0x%x\n", + ecc_bit, ecc_byte); + if (ecc_byte < buf_len) { + RTS51X_DEBUGP("Before correct: 0x%x\n", + buf[ecc_byte]); + buf[ecc_byte] ^= (1 << ecc_bit); + RTS51X_DEBUGP("After correct: 0x%x\n", + buf[ecc_byte]); + } + } + } else if (!(reg & XD_ECC2_ERROR) || !(reg & XD_ECC2_UNCORRECTABLE)) { + RTS51X_WRITE_REG(chip, CARD_STOP, XD_STOP | XD_CLR_ERR, + XD_STOP | XD_CLR_ERR); + + retval = xd_read_data_from_ppb(chip, 256, buf, buf_len); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + if (reg & XD_ECC2_ERROR) { + u8 ecc_bit, ecc_byte; + + RTS51X_READ_REG(chip, XD_ECC_BIT2, &ecc_bit); + RTS51X_READ_REG(chip, XD_ECC_BYTE2, &ecc_byte); + + RTS51X_DEBUGP("ECC_BIT2 = 0x%x, ECC_BYTE2 = 0x%x\n", + ecc_bit, ecc_byte); + if (ecc_byte < buf_len) { + RTS51X_DEBUGP("Before correct: 0x%x\n", + buf[ecc_byte]); + buf[ecc_byte] ^= (1 << ecc_bit); + RTS51X_DEBUGP("After correct: 0x%x\n", + buf[ecc_byte]); + } + } + } else { + rts51x_clear_xd_error(chip); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static void xd_pull_ctl_disable(struct rts51x_chip *chip) +{ + if (CHECK_PKG(chip, LQFP48)) { + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x55); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x95); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x55); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0xA5); + } else { + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0x65); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x95); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x56); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0x59); + } +} + +static void xd_pull_ctl_enable(struct rts51x_chip *chip) +{ + if (CHECK_PKG(chip, LQFP48)) { + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0xAA); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x55); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x95); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x55); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0xA5); + } else { + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL1, 0xFF, 0xA5); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL2, 0xFF, 0x59); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL3, 0xFF, 0x95); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL4, 0xFF, 0x55); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL5, 0xFF, 0x55); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PULL_CTL6, 0xFF, 0x59); + } +} + +static int reset_xd(struct rts51x_chip *chip) +{ + struct xd_info *xd_card = &(chip->xd_card); + int retval, i, j; + u8 id_buf[4], redunt[11]; + + retval = rts51x_select_card(chip, XD_CARD); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + rts51x_init_cmd(chip); + + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS, 0xFF, + XD_PGSTS_NOT_FF); + if (chip->asic_code) + xd_pull_ctl_disable(chip); + else + rts51x_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, 0xFF, + (FPGA_XD_PULL_CTL_EN1 & FPGA_XD_PULL_CTL_EN3)); + + if (!chip->option.FT2_fast_mode) { + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_INIT, XD_NO_AUTO_PWR_OFF, + 0); + if (CHECK_PKG(chip, LQFP48) || + chip->option.rts5129_D3318_off_enable) { + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, + DV3318_AUTO_PWR_OFF, + DV3318_AUTO_PWR_OFF); + } + } + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_OE, XD_OUTPUT_EN, 0); + if (!chip->option.FT2_fast_mode) { + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, POWER_MASK, + POWER_OFF); + } + + retval = rts51x_send_cmd(chip, MODE_C, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + if (!chip->option.FT2_fast_mode) { +#ifdef SD_XD_IO_FOLLOW_PWR + if (CHECK_PKG(chip, LQFP48) + || chip->option.rts5129_D3318_off_enable) { + rts51x_write_register(chip, CARD_PWR_CTL, + LDO_OFF, LDO_OFF); + } +#endif + + wait_timeout(250); + +#ifdef SD_XD_IO_FOLLOW_PWR + if (CHECK_PKG(chip, LQFP48) + || chip->option.rts5129_D3318_off_enable) { + rts51x_init_cmd(chip); + if (chip->asic_code) { + xd_pull_ctl_enable(chip); + } else { + rts51x_add_cmd(chip, WRITE_REG_CMD, + FPGA_PULL_CTL, 0xFF, + (FPGA_XD_PULL_CTL_EN1 & + FPGA_XD_PULL_CTL_EN2)); + } + retval = rts51x_send_cmd(chip, MODE_C, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + } +#endif + + retval = card_power_on(chip, XD_CARD); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); +#ifdef SUPPORT_OCP + wait_timeout(50); + rts51x_get_card_status(chip, &(chip->card_status)); + chip->ocp_stat = (chip->card_status >> 4) & 0x03; + + if (chip->ocp_stat & (MS_OCP_NOW | MS_OCP_EVER)) { + RTS51X_DEBUGP("Over current, OCPSTAT is 0x%x\n", + chip->ocp_stat); + TRACE_RET(chip, STATUS_FAIL); + } +#endif + } + + rts51x_init_cmd(chip); + + if (chip->asic_code) + xd_pull_ctl_enable(chip); + else + rts51x_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, 0xFF, + (FPGA_XD_PULL_CTL_EN1 & FPGA_XD_PULL_CTL_EN2)); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_OE, XD_OUTPUT_EN, + XD_OUTPUT_EN); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CTL, XD_CE_DISEN, XD_CE_DISEN); + + retval = rts51x_send_cmd(chip, MODE_C, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + if (!chip->option.FT2_fast_mode) + wait_timeout(200); + + retval = xd_set_init_para(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + /* Read ID to check if the timing setting is right */ + for (i = 0; i < 4; i++) { + u8 xd_dat, xd_ctl; + + if (monitor_card_cd(chip, XD_CARD) == CD_NOT_EXIST) + TRACE_RET(chip, STATUS_FAIL); + + rts51x_init_cmd(chip); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_DTCTL, 0xFF, + XD_TIME_SETUP_STEP * 3 + XD_TIME_RW_STEP * + (2 + i + chip->option.xd_rw_step) + + XD_TIME_RWN_STEP * (i + chip->option.xd_rwn_step)); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CATCTL, 0xFF, + XD_TIME_SETUP_STEP * 3 + XD_TIME_RW_STEP * (4 + + i) + XD_TIME_RWN_STEP * (3 + i)); + + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, + XD_TRANSFER_START | XD_RESET); + rts51x_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, + XD_TRANSFER_END, XD_TRANSFER_END); + + rts51x_add_cmd(chip, READ_REG_CMD, XD_DAT, 0, 0); + rts51x_add_cmd(chip, READ_REG_CMD, XD_CTL, 0, 0); + + retval = rts51x_send_cmd(chip, MODE_CR, 100); + if (retval != STATUS_SUCCESS) { + rts51x_clear_xd_error(chip); + TRACE_RET(chip, retval); + } + + retval = rts51x_get_rsp(chip, 3, 100); + if (retval != STATUS_SUCCESS) { + rts51x_clear_xd_error(chip); + TRACE_RET(chip, retval); + } + + xd_dat = chip->rsp_buf[1]; + xd_ctl = chip->rsp_buf[2]; + RTS51X_DEBUGP("XD_DAT: 0x%x, XD_CTL: 0x%x\n", xd_dat, xd_ctl); + + if (((xd_dat & READY_FLAG) != READY_STATE) + || !(xd_ctl & XD_RDY)) + continue; + + retval = xd_read_id(chip, READ_ID, id_buf, 4); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + RTS51X_DEBUGP("READ_ID: 0x%x 0x%x 0x%x 0x%x\n", + id_buf[0], id_buf[1], id_buf[2], id_buf[3]); + + xd_card->device_code = id_buf[1]; + + switch (xd_card->device_code) { + case XD_4M_X8_512_1: + case XD_4M_X8_512_2: + xd_card->block_shift = 4; /* 16 pages per block */ + xd_card->page_off = 0x0F; + xd_card->addr_cycle = 3; + xd_card->zone_cnt = 1; + xd_card->capacity = 8000; /* 500 * 2 ^ 4 */ + XD_SET_4MB(xd_card); + break; + case XD_8M_X8_512: + xd_card->block_shift = 4; + xd_card->page_off = 0x0F; + xd_card->addr_cycle = 3; + xd_card->zone_cnt = 1; + xd_card->capacity = 16000; /* 1000 * 2 ^ 4 */ + break; + case XD_16M_X8_512: + XD_PAGE_512(xd_card); /* 32 pages per block */ + xd_card->addr_cycle = 3; + xd_card->zone_cnt = 1; + xd_card->capacity = 32000; /* 1000 * 2 ^ 5 */ + break; + case XD_32M_X8_512: + XD_PAGE_512(xd_card); + xd_card->addr_cycle = 3; + xd_card->zone_cnt = 2; + xd_card->capacity = 64000; /* 2000 * 2 ^ 5 */ + break; + case XD_64M_X8_512: + XD_PAGE_512(xd_card); + xd_card->addr_cycle = 4; + xd_card->zone_cnt = 4; + xd_card->capacity = 128000; /* 4000 * 2 ^ 5 */ + break; + case XD_128M_X8_512: + XD_PAGE_512(xd_card); + xd_card->addr_cycle = 4; + xd_card->zone_cnt = 8; + xd_card->capacity = 256000; /* 8000 * 2 ^ 5 */ + break; + case XD_256M_X8_512: + XD_PAGE_512(xd_card); + xd_card->addr_cycle = 4; + xd_card->zone_cnt = 16; + xd_card->capacity = 512000; /* 16000 * 2 ^ 5 */ + break; + case XD_512M_X8: + XD_PAGE_512(xd_card); + xd_card->addr_cycle = 4; + xd_card->zone_cnt = 32; + xd_card->capacity = 1024000; /* 32000 * 2 ^ 5 */ + break; + case xD_1G_X8_512: + XD_PAGE_512(xd_card); + xd_card->addr_cycle = 4; + xd_card->zone_cnt = 64; + xd_card->capacity = 2048000; /* 64000 * 2 ^ 5 */ + break; + case xD_2G_X8_512: + XD_PAGE_512(xd_card); + xd_card->addr_cycle = 4; + xd_card->zone_cnt = 128; + xd_card->capacity = 4096000; /* 128000 * 2 ^ 5 */ + break; + default: + continue; + } + + /* Confirm timing setting */ + for (j = 0; j < 10; j++) { + retval = xd_read_id(chip, READ_ID, id_buf, 4); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + if (id_buf[1] != xd_card->device_code) + break; + } + + /* Current timing pass */ + if (j == 10) + break; + } + + if (i == 4) { + xd_card->block_shift = 0; + xd_card->page_off = 0; + xd_card->addr_cycle = 0; + xd_card->capacity = 0; + + TRACE_RET(chip, STATUS_FAIL); + } + + retval = xd_read_id(chip, READ_xD_ID, id_buf, 4); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + RTS51X_DEBUGP("READ_xD_ID: 0x%x 0x%x 0x%x 0x%x\n", + id_buf[0], id_buf[1], id_buf[2], id_buf[3]); + if (id_buf[2] != XD_ID_CODE) + TRACE_RET(chip, STATUS_FAIL); + + /* Search CIS block */ + for (i = 0; i < 24; i++) { + u32 page_addr; + + if (monitor_card_cd(chip, XD_CARD) == CD_NOT_EXIST) + TRACE_RET(chip, STATUS_FAIL); + + page_addr = (u32) i << xd_card->block_shift; + + for (j = 0; j < 3; j++) { + retval = xd_read_redundant(chip, page_addr, redunt, 11); + if (retval == STATUS_SUCCESS) + break; + } + if (j == 3) + continue; + + if (redunt[BLOCK_STATUS] != XD_GBLK) + continue; + + j = 0; + /* Check page status */ + if (redunt[PAGE_STATUS] != XD_GPG) { + for (j = 1; j <= 8; j++) { + retval = + xd_read_redundant(chip, page_addr + j, + redunt, 11); + if (retval == STATUS_SUCCESS) { + if (redunt[PAGE_STATUS] == XD_GPG) + break; + } + } + + if (j == 9) + break; + } + + if ((redunt[BLOCK_STATUS] == XD_GBLK) + && (redunt[PARITY] & XD_BA1_ALL0)) { + u8 buf[10]; + + page_addr += j; + + retval = xd_read_cis(chip, page_addr, buf, 10); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + if ((buf[0] == 0x01) && (buf[1] == 0x03) + && (buf[2] == 0xD9) + && (buf[3] == 0x01) && (buf[4] == 0xFF) + && (buf[5] == 0x18) && (buf[6] == 0x02) + && (buf[7] == 0xDF) && (buf[8] == 0x01) + && (buf[9] == 0x20)) { + xd_card->cis_block = (u16) i; + } + } + + break; + } + + RTS51X_DEBUGP("CIS block: 0x%x\n", xd_card->cis_block); + if (xd_card->cis_block == 0xFFFF) + TRACE_RET(chip, STATUS_FAIL); + + chip->capacity[chip->card2lun[XD_CARD]] = xd_card->capacity; + + return STATUS_SUCCESS; +} + +static int xd_check_data_blank(u8 *redunt) +{ + int i; + + for (i = 0; i < 6; i++) { + if (redunt[PAGE_STATUS + i] != 0xFF) + return 0; + } + + if ((redunt[PARITY] & (XD_ECC1_ALL1 | XD_ECC2_ALL1)) != + (XD_ECC1_ALL1 | XD_ECC2_ALL1)) + return 0; + + for (i = 0; i < 4; i++) { + if (redunt[RESERVED0 + i] != 0xFF) + return 0; + } + + return 1; +} + +static u16 xd_load_log_block_addr(u8 *redunt) +{ + u16 addr = 0xFFFF; + + if (redunt[PARITY] & XD_BA1_BA2_EQL) + addr = + ((u16) redunt[BLOCK_ADDR1_H] << 8) | redunt[BLOCK_ADDR1_L]; + else if (redunt[PARITY] & XD_BA1_VALID) + addr = + ((u16) redunt[BLOCK_ADDR1_H] << 8) | redunt[BLOCK_ADDR1_L]; + else if (redunt[PARITY] & XD_BA2_VALID) + addr = + ((u16) redunt[BLOCK_ADDR2_H] << 8) | redunt[BLOCK_ADDR2_L]; + + return addr; +} + +static int xd_init_l2p_tbl(struct rts51x_chip *chip) +{ + struct xd_info *xd_card = &(chip->xd_card); + int size, i; + + RTS51X_DEBUGP("xd_init_l2p_tbl: zone_cnt = %d\n", xd_card->zone_cnt); + + if (xd_card->zone_cnt < 1) + TRACE_RET(chip, STATUS_FAIL); + + size = xd_card->zone_cnt * sizeof(struct zone_entry); + RTS51X_DEBUGP("Buffer size for l2p table is %d\n", size); + + xd_card->zone = vmalloc(size); + if (!xd_card->zone) + TRACE_RET(chip, STATUS_NOMEM); + + for (i = 0; i < xd_card->zone_cnt; i++) { + xd_card->zone[i].build_flag = 0; + xd_card->zone[i].l2p_table = NULL; + xd_card->zone[i].free_table = NULL; + xd_card->zone[i].get_index = 0; + xd_card->zone[i].set_index = 0; + xd_card->zone[i].unused_blk_cnt = 0; + } + + return STATUS_SUCCESS; +} + +static inline void free_zone(struct zone_entry *zone) +{ + RTS51X_DEBUGP("free_zone\n"); + if (!zone) + return; + zone->build_flag = 0; + zone->set_index = 0; + zone->get_index = 0; + zone->unused_blk_cnt = 0; + if (zone->l2p_table) { + vfree(zone->l2p_table); + zone->l2p_table = NULL; + } + if (zone->free_table) { + vfree(zone->free_table); + zone->free_table = NULL; + } +} + +static void xd_set_unused_block(struct rts51x_chip *chip, u32 phy_blk) +{ + struct xd_info *xd_card = &(chip->xd_card); + struct zone_entry *zone; + int zone_no; + + zone_no = (int)phy_blk >> 10; + if (zone_no >= xd_card->zone_cnt) { + RTS51X_DEBUGP("Set unused block to invalid zone" + "(zone_no = %d, zone_cnt = %d)\n", + zone_no, xd_card->zone_cnt); + return; + } + zone = &(xd_card->zone[zone_no]); + + if (zone->free_table == NULL) { + if (xd_build_l2p_tbl(chip, zone_no) != STATUS_SUCCESS) + return; + } + + if ((zone->set_index >= XD_FREE_TABLE_CNT) + || (zone->set_index < 0)) { + free_zone(zone); + RTS51X_DEBUGP("Set unused block fail, invalid set_index\n"); + return; + } + + RTS51X_DEBUGP("Set unused block to index %d\n", zone->set_index); + + zone->free_table[zone->set_index++] = (u16) (phy_blk & 0x3ff); + if (zone->set_index >= XD_FREE_TABLE_CNT) + zone->set_index = 0; + zone->unused_blk_cnt++; +} + +static u32 xd_get_unused_block(struct rts51x_chip *chip, int zone_no) +{ + struct xd_info *xd_card = &(chip->xd_card); + struct zone_entry *zone; + u32 phy_blk; + + if (zone_no >= xd_card->zone_cnt) { + RTS51X_DEBUGP("Get unused block from invalid zone" + "(zone_no = %d, zone_cnt = %d)\n", + zone_no, xd_card->zone_cnt); + TRACE_RET(chip, BLK_NOT_FOUND); + } + zone = &(xd_card->zone[zone_no]); + + if ((zone->unused_blk_cnt == 0) || + (zone->set_index == zone->get_index)) { + free_zone(zone); + RTS51X_DEBUGP("Get unused block fail," + "no unused block available\n"); + TRACE_RET(chip, BLK_NOT_FOUND); + } + if ((zone->get_index >= XD_FREE_TABLE_CNT) || (zone->get_index < 0)) { + free_zone(zone); + RTS51X_DEBUGP("Get unused block fail, invalid get_index\n"); + TRACE_RET(chip, BLK_NOT_FOUND); + } + + RTS51X_DEBUGP("Get unused block from index %d\n", zone->get_index); + + phy_blk = zone->free_table[zone->get_index]; + zone->free_table[zone->get_index++] = 0xFFFF; + if (zone->get_index >= XD_FREE_TABLE_CNT) + zone->get_index = 0; + zone->unused_blk_cnt--; + + phy_blk += ((u32) (zone_no) << 10); + return phy_blk; +} + +static void xd_set_l2p_tbl(struct rts51x_chip *chip, int zone_no, u16 log_off, + u16 phy_off) +{ + struct xd_info *xd_card = &(chip->xd_card); + struct zone_entry *zone; + + zone = &(xd_card->zone[zone_no]); + zone->l2p_table[log_off] = phy_off; +} + +static u32 xd_get_l2p_tbl(struct rts51x_chip *chip, int zone_no, u16 log_off) +{ + struct xd_info *xd_card = &(chip->xd_card); + struct zone_entry *zone; + int retval; + + zone = &(xd_card->zone[zone_no]); + if (zone->l2p_table[log_off] == 0xFFFF) { + u32 phy_blk = 0; + int i; + + retval = xd_delay_write(chip); + if (retval != STATUS_SUCCESS) { + RTS51X_DEBUGP("In xd_get_l2p_tbl," + "delay write fail!\n"); + TRACE_RET(chip, BLK_NOT_FOUND); + } + + if (zone->unused_blk_cnt <= 0) { + RTS51X_DEBUGP("No unused block!\n"); + TRACE_RET(chip, BLK_NOT_FOUND); + } + + for (i = 0; i < zone->unused_blk_cnt; i++) { + phy_blk = xd_get_unused_block(chip, zone_no); + if (phy_blk == BLK_NOT_FOUND) { + RTS51X_DEBUGP("No unused block available!\n"); + TRACE_RET(chip, BLK_NOT_FOUND); + } + + retval = + xd_init_page(chip, phy_blk, log_off, 0, + xd_card->page_off + 1); + if (retval == STATUS_SUCCESS) + break; + } + if (i >= zone->unused_blk_cnt) { + RTS51X_DEBUGP("No good unused block available!\n"); + TRACE_RET(chip, BLK_NOT_FOUND); + } + + xd_set_l2p_tbl(chip, zone_no, log_off, (u16) (phy_blk & 0x3FF)); + return phy_blk; + } + + return (u32) zone->l2p_table[log_off] + ((u32) (zone_no) << 10); +} + +int reset_xd_card(struct rts51x_chip *chip) +{ + struct xd_info *xd_card = &(chip->xd_card); + int retval; + + memset(xd_card, 0, sizeof(struct xd_info)); + + xd_card->block_shift = 0; + xd_card->page_off = 0; + xd_card->addr_cycle = 0; + xd_card->capacity = 0; + xd_card->zone_cnt = 0; + xd_card->cis_block = 0xFFFF; + xd_card->delay_write.delay_write_flag = 0; + + enable_card_clock(chip, XD_CARD); + + retval = reset_xd(chip); + if (retval != STATUS_SUCCESS) { + if (chip->option.reset_or_rw_fail_set_pad_drive) { + rts51x_write_register(chip, CARD_DRIVE_SEL, + SD20_DRIVE_MASK, DRIVE_8mA); + } + TRACE_RET(chip, retval); + } + + retval = xd_init_l2p_tbl(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + return STATUS_SUCCESS; +} + +static int xd_mark_bad_block(struct rts51x_chip *chip, u32 phy_blk) +{ + struct xd_info *xd_card = &(chip->xd_card); + int retval; + u32 page_addr; + u8 reg = 0; + + RTS51X_DEBUGP("mark block 0x%x as bad block\n", phy_blk); + + if (phy_blk == BLK_NOT_FOUND) + TRACE_RET(chip, STATUS_FAIL); + + rts51x_init_cmd(chip); + + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_STATUS, 0xFF, XD_GPG); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_STATUS, 0xFF, + XD_LATER_BBLK); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_H, 0xFF, 0xFF); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_L, 0xFF, 0xFF); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR2_H, 0xFF, 0xFF); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR2_L, 0xFF, 0xFF); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED0, 0xFF, 0xFF); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED1, 0xFF, 0xFF); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED2, 0xFF, 0xFF); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_RESERVED3, 0xFF, 0xFF); + + page_addr = phy_blk << xd_card->block_shift; + + xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); + + /* Specify page count */ + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, + xd_card->page_off + 1); + + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, + XD_TRANSFER_START | XD_WRITE_REDUNDANT); + rts51x_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, + XD_TRANSFER_END); + + retval = rts51x_send_cmd(chip, MODE_CR, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = rts51x_get_rsp(chip, 1, 100); + + if (retval != STATUS_SUCCESS) { + rts51x_clear_xd_error(chip); + rts51x_ep0_read_register(chip, XD_DAT, ®); + if (reg & PROGRAM_ERROR) + xd_set_err_code(chip, XD_PRG_ERROR); + else + xd_set_err_code(chip, XD_TO_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int xd_init_page(struct rts51x_chip *chip, u32 phy_blk, u16 logoff, + u8 start_page, u8 end_page) +{ + struct xd_info *xd_card = &(chip->xd_card); + int retval; + u32 page_addr; + u8 reg = 0; + + RTS51X_DEBUGP("Init block 0x%x\n", phy_blk); + + if (start_page > end_page) + TRACE_RET(chip, STATUS_FAIL); + if (phy_blk == BLK_NOT_FOUND) + TRACE_RET(chip, STATUS_FAIL); + + rts51x_init_cmd(chip); + + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_STATUS, 0xFF, 0xFF); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_STATUS, 0xFF, 0xFF); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_H, 0xFF, + (u8) (logoff >> 8)); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_L, 0xFF, + (u8) logoff); + + page_addr = (phy_blk << xd_card->block_shift) + start_page; + + xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); + + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CFG, XD_BA_TRANSFORM, + XD_BA_TRANSFORM); + + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, + (end_page - start_page)); + + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, + XD_TRANSFER_START | XD_WRITE_REDUNDANT); + rts51x_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, + XD_TRANSFER_END); + + retval = rts51x_send_cmd(chip, MODE_CR, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, STATUS_FAIL); + + retval = rts51x_get_rsp(chip, 1, 500); + + if (retval != STATUS_SUCCESS) { + rts51x_clear_xd_error(chip); + rts51x_ep0_read_register(chip, XD_DAT, ®); + if (reg & PROGRAM_ERROR) { + xd_mark_bad_block(chip, phy_blk); + xd_set_err_code(chip, XD_PRG_ERROR); + } else { + xd_set_err_code(chip, XD_TO_ERROR); + } + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; +} + +static int xd_copy_page(struct rts51x_chip *chip, + u32 old_blk, u32 new_blk, u8 start_page, u8 end_page) +{ + struct xd_info *xd_card = &(chip->xd_card); + u32 old_page, new_page; + u8 i, reg = 0; + int retval; + + RTS51X_DEBUGP("Copy page from block 0x%x to block 0x%x\n", old_blk, + new_blk); + + if (start_page > end_page) + TRACE_RET(chip, STATUS_FAIL); + + if ((old_blk == BLK_NOT_FOUND) || (new_blk == BLK_NOT_FOUND)) + TRACE_RET(chip, STATUS_FAIL); + + old_page = (old_blk << xd_card->block_shift) + start_page; + new_page = (new_blk << xd_card->block_shift) + start_page; + + XD_CLR_BAD_NEWBLK(xd_card); + + RTS51X_WRITE_REG(chip, CARD_DATA_SOURCE, 0x01, PINGPONG_BUFFER); + + for (i = start_page; i < end_page; i++) { + if (monitor_card_cd(chip, XD_CARD) == CD_NOT_EXIST) { + RTS51X_WRITE_REG(chip, CARD_STOP, XD_STOP | XD_CLR_ERR, + XD_STOP | XD_CLR_ERR); + xd_set_err_code(chip, XD_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + + rts51x_init_cmd(chip); + + xd_assign_phy_addr(chip, old_page, XD_RW_ADDR); + + /* Single page read */ + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, 1); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS, + XD_AUTO_CHK_DATA_STATUS, 0); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, + XD_TRANSFER_START | XD_READ_PAGES); + rts51x_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, + XD_TRANSFER_END, XD_TRANSFER_END); + + retval = rts51x_send_cmd(chip, MODE_CR | STAGE_XD_STATUS, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = rts51x_get_rsp(chip, 4, 500); + if ((retval != STATUS_SUCCESS) || + (chip->rsp_buf[2] & (XD_ECC1_ERROR | XD_ECC2_ERROR))) { + rts51x_clear_xd_error(chip); + reg = 0; + rts51x_ep0_read_register(chip, XD_CTL, ®); + if (reg & (XD_ECC1_ERROR | XD_ECC2_ERROR)) { + wait_timeout(100); + + if (monitor_card_cd(chip, XD_CARD) == + CD_NOT_EXIST) { + xd_set_err_code(chip, XD_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + + if (((reg & + (XD_ECC1_ERROR | XD_ECC1_UNCORRECTABLE)) + == (XD_ECC1_ERROR | XD_ECC1_UNCORRECTABLE)) + || ((reg & (XD_ECC2_ERROR | + XD_ECC2_UNCORRECTABLE)) == + (XD_ECC2_ERROR | XD_ECC2_UNCORRECTABLE))) { + RTS51X_WRITE_REG(chip, XD_PAGE_STATUS, + 0xFF, XD_BPG); + RTS51X_WRITE_REG(chip, XD_BLOCK_STATUS, + 0xFF, XD_GBLK); + XD_SET_BAD_OLDBLK(xd_card); + RTS51X_DEBUGP("old block 0x%x" + "ecc error\n", old_blk); + } + } else { + xd_set_err_code(chip, XD_TO_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + } + if (XD_CHK_BAD_OLDBLK(xd_card)) + rts51x_clear_xd_error(chip); + + rts51x_init_cmd(chip); + + xd_assign_phy_addr(chip, new_page, XD_RW_ADDR); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, 1); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, + XD_TRANSFER_START | XD_WRITE_PAGES); + rts51x_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, + XD_TRANSFER_END, XD_TRANSFER_END); + + retval = rts51x_send_cmd(chip, MODE_CR, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = rts51x_get_rsp(chip, 1, 300); + if (retval != STATUS_SUCCESS) { + rts51x_clear_xd_error(chip); + reg = 0; + rts51x_ep0_read_register(chip, XD_DAT, ®); + if (reg & PROGRAM_ERROR) { + xd_mark_bad_block(chip, new_blk); + xd_set_err_code(chip, XD_PRG_ERROR); + XD_SET_BAD_NEWBLK(xd_card); + } else { + xd_set_err_code(chip, XD_TO_ERROR); + } + TRACE_RET(chip, retval); + } + + old_page++; + new_page++; + } + + return STATUS_SUCCESS; +} + +#ifdef XD_SPEEDUP +static int xd_auto_copy_page(struct rts51x_chip *chip, + u32 old_blk, u32 new_blk, + u8 start_page, u8 end_page) +{ + struct xd_info *xd_card = &(chip->xd_card); + u32 old_page, new_page; + int retval; + u8 page_count; + + RTS51X_DEBUGP("Auto copy page from block 0x%x to block 0x%x\n", + old_blk, new_blk); + + if (start_page > end_page) + TRACE_RET(chip, STATUS_FAIL); + + page_count = end_page - start_page; + + if ((old_blk == BLK_NOT_FOUND) || (new_blk == BLK_NOT_FOUND)) + TRACE_RET(chip, STATUS_FAIL); + + old_page = (old_blk << xd_card->block_shift) + start_page; + new_page = (new_blk << xd_card->block_shift) + start_page; + + XD_CLR_BAD_NEWBLK(xd_card); + + rts51x_init_cmd(chip); + + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CP_WAITTIME, 0x03, WAIT_FF); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CP_PAGELEN, 0xFF, page_count); + + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CP_READADDR0, 0xFF, 0); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CP_READADDR1, 0xFF, + (u8) old_page); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CP_READADDR2, 0xFF, + (u8) (old_page >> 8)); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CP_READADDR3, 0xFF, + (u8) (old_page >> 16)); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CP_READADDR4, 0xFF, 0); + + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CP_WRITEADDR0, 0xFF, 0); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CP_WRITEADDR1, 0xFF, + (u8) new_page); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CP_WRITEADDR2, 0xFF, + (u8) (new_page >> 8)); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CP_WRITEADDR3, 0xFF, + (u8) (new_page >> 16)); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CP_WRITEADDR4, 0xFF, 0); + + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, + PINGPONG_BUFFER); + + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CFG, + XD_BA_TRANSFORM | XD_ADDR_MASK, 0 | xd_card->addr_cycle); + + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS, + XD_AUTO_CHK_DATA_STATUS, 0); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, + XD_TRANSFER_START | XD_COPY_PAGES); + rts51x_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, + XD_TRANSFER_END); + + retval = rts51x_send_cmd(chip, MODE_CR, 100); + if (retval != STATUS_SUCCESS) { + rts51x_clear_xd_error(chip); + TRACE_GOTO(chip, Copy_Fail); + } + + retval = rts51x_get_rsp(chip, 1, 800); + if (retval != STATUS_SUCCESS) { + rts51x_clear_xd_error(chip); + TRACE_GOTO(chip, Copy_Fail); + } + + return STATUS_SUCCESS; + +Copy_Fail: + retval = xd_copy_page(chip, old_blk, new_blk, start_page, end_page); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + return STATUS_SUCCESS; +} +#endif + +static int xd_reset_cmd(struct rts51x_chip *chip) +{ + int retval; + u8 xd_dat, xd_ctl; + + rts51x_init_cmd(chip); + + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, + XD_TRANSFER_START | XD_RESET); + rts51x_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, + XD_TRANSFER_END); + rts51x_add_cmd(chip, READ_REG_CMD, XD_DAT, 0, 0); + rts51x_add_cmd(chip, READ_REG_CMD, XD_CTL, 0, 0); + + retval = rts51x_send_cmd(chip, MODE_CR, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = rts51x_get_rsp(chip, 3, 100); + if (retval != STATUS_SUCCESS) { + rts51x_clear_xd_error(chip); + TRACE_RET(chip, retval); + } + + xd_dat = chip->rsp_buf[1]; + xd_ctl = chip->rsp_buf[2]; + if (((xd_dat & READY_FLAG) == READY_STATE) && (xd_ctl & XD_RDY)) + return STATUS_SUCCESS; + + TRACE_RET(chip, STATUS_FAIL); +} + +static int xd_erase_block(struct rts51x_chip *chip, u32 phy_blk) +{ + struct xd_info *xd_card = &(chip->xd_card); + u32 page_addr; + u8 reg = 0, xd_dat; + int i, retval; + + if (phy_blk == BLK_NOT_FOUND) + TRACE_RET(chip, STATUS_FAIL); + + page_addr = phy_blk << xd_card->block_shift; + + for (i = 0; i < 3; i++) { + rts51x_init_cmd(chip); + + xd_assign_phy_addr(chip, page_addr, XD_ERASE_ADDR); + + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, + XD_TRANSFER_START | XD_ERASE); + rts51x_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, + XD_TRANSFER_END, XD_TRANSFER_END); + rts51x_add_cmd(chip, READ_REG_CMD, XD_DAT, 0, 0); + + retval = rts51x_send_cmd(chip, MODE_CR, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = rts51x_get_rsp(chip, 2, 300); + if (retval != STATUS_SUCCESS) { + rts51x_clear_xd_error(chip); + rts51x_ep0_read_register(chip, XD_DAT, ®); + if (reg & PROGRAM_ERROR) { + xd_mark_bad_block(chip, phy_blk); + xd_set_err_code(chip, XD_PRG_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } else { + xd_set_err_code(chip, XD_ERASE_FAIL); + } + retval = xd_reset_cmd(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + continue; + } + xd_dat = chip->rsp_buf[1]; + if (xd_dat & PROGRAM_ERROR) { + xd_mark_bad_block(chip, phy_blk); + xd_set_err_code(chip, XD_PRG_ERROR); + TRACE_RET(chip, STATUS_FAIL); + } + + return STATUS_SUCCESS; + } + + xd_mark_bad_block(chip, phy_blk); + xd_set_err_code(chip, XD_ERASE_FAIL); + TRACE_RET(chip, STATUS_FAIL); +} + +static int xd_build_l2p_tbl(struct rts51x_chip *chip, int zone_no) +{ + struct xd_info *xd_card = &(chip->xd_card); + struct zone_entry *zone; + int retval; + u32 start, end, i; + u16 max_logoff, cur_fst_page_logoff, cur_lst_page_logoff, + ent_lst_page_logoff; + u8 redunt[11]; + + RTS51X_DEBUGP("xd_build_l2p_tbl: %d\n", zone_no); + + if (xd_card->zone == NULL) { + retval = xd_init_l2p_tbl(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } + + if (xd_card->zone[zone_no].build_flag) { + RTS51X_DEBUGP("l2p table of zone %d has been built\n", + zone_no); + return STATUS_SUCCESS; + } + + zone = &(xd_card->zone[zone_no]); + + if (zone->l2p_table == NULL) { + zone->l2p_table = vmalloc(2000); + if (zone->l2p_table == NULL) + TRACE_GOTO(chip, Build_Fail); + } + memset((u8 *) (zone->l2p_table), 0xff, 2000); + + if (zone->free_table == NULL) { + zone->free_table = vmalloc(XD_FREE_TABLE_CNT * 2); + if (zone->free_table == NULL) + TRACE_GOTO(chip, Build_Fail); + } + memset((u8 *) (zone->free_table), 0xff, XD_FREE_TABLE_CNT * 2); + + if (zone_no == 0) { + if (xd_card->cis_block == 0xFFFF) + start = 0; + else + start = xd_card->cis_block + 1; + if (XD_CHK_4MB(xd_card)) { + end = 0x200; + max_logoff = 499; + } else { + end = 0x400; + max_logoff = 999; + } + } else { + start = (u32) (zone_no) << 10; + end = (u32) (zone_no + 1) << 10; + max_logoff = 999; + } + + RTS51X_DEBUGP("start block 0x%x, end block 0x%x\n", start, end); + + zone->set_index = zone->get_index = 0; + zone->unused_blk_cnt = 0; + + for (i = start; i < end; i++) { + u32 page_addr = i << xd_card->block_shift; + u32 phy_block; + + retval = xd_read_redundant(chip, page_addr, redunt, 11); + if (retval != STATUS_SUCCESS) + continue; + + if (redunt[BLOCK_STATUS] != 0xFF) { + RTS51X_DEBUGP("bad block\n"); + continue; + } + + if (xd_check_data_blank(redunt)) { + RTS51X_DEBUGP("blank block\n"); + xd_set_unused_block(chip, i); + continue; + } + + cur_fst_page_logoff = xd_load_log_block_addr(redunt); + if ((cur_fst_page_logoff == 0xFFFF) + || (cur_fst_page_logoff > max_logoff)) { + retval = xd_erase_block(chip, i); + if (retval == STATUS_SUCCESS) + xd_set_unused_block(chip, i); + continue; + } + if ((zone_no == 0) && (cur_fst_page_logoff == 0) + && (redunt[PAGE_STATUS] != XD_GPG)) + XD_SET_MBR_FAIL(xd_card); + + if (zone->l2p_table[cur_fst_page_logoff] == 0xFFFF) { + zone->l2p_table[cur_fst_page_logoff] = + (u16) (i & 0x3FF); + continue; + } + + phy_block = + zone->l2p_table[cur_fst_page_logoff] + + ((u32) ((zone_no) << 10)); + + page_addr = ((i + 1) << xd_card->block_shift) - 1; + + retval = xd_read_redundant(chip, page_addr, redunt, 11); + if (retval != STATUS_SUCCESS) + continue; + + cur_lst_page_logoff = xd_load_log_block_addr(redunt); + if (cur_lst_page_logoff == cur_fst_page_logoff) { + int m; + + page_addr = + ((phy_block + 1) << xd_card->block_shift) - 1; + + for (m = 0; m < 3; m++) { + retval = + xd_read_redundant(chip, page_addr, redunt, + 11); + if (retval == STATUS_SUCCESS) + break; + } + + if (m == 3) { + zone->l2p_table[cur_fst_page_logoff] = + (u16) (i & 0x3FF); + retval = xd_erase_block(chip, phy_block); + if (retval == STATUS_SUCCESS) + xd_set_unused_block(chip, phy_block); + continue; + } + + ent_lst_page_logoff = xd_load_log_block_addr(redunt); + if (ent_lst_page_logoff != cur_fst_page_logoff) { + zone->l2p_table[cur_fst_page_logoff] = + (u16) (i & 0x3FF); + retval = xd_erase_block(chip, phy_block); + if (retval == STATUS_SUCCESS) + xd_set_unused_block(chip, phy_block); + continue; + } else { + retval = xd_erase_block(chip, i); + if (retval == STATUS_SUCCESS) + xd_set_unused_block(chip, i); + } + } else { + retval = xd_erase_block(chip, i); + if (retval == STATUS_SUCCESS) + xd_set_unused_block(chip, i); + } + } + + if (XD_CHK_4MB(xd_card)) + end = 500; + else + end = 1000; + + i = 0; + for (start = 0; start < end; start++) { + if (zone->l2p_table[start] == 0xFFFF) + i++; + } + + RTS51X_DEBUGP("Block count %d, invalid L2P entry %d\n", end, i); + RTS51X_DEBUGP("Total unused block: %d\n", zone->unused_blk_cnt); + + if ((zone->unused_blk_cnt - i) < 1) + chip->card_wp |= XD_CARD; + + zone->build_flag = 1; + + return STATUS_SUCCESS; + +Build_Fail: + if (zone->l2p_table) { + vfree(zone->l2p_table); + zone->l2p_table = NULL; + } + if (zone->free_table) { + vfree(zone->free_table); + zone->free_table = NULL; + } + + return STATUS_FAIL; +} + +static int xd_send_cmd(struct rts51x_chip *chip, u8 cmd) +{ + int retval; + + rts51x_init_cmd(chip); + + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_DAT, 0xFF, cmd); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, + XD_TRANSFER_START | XD_SET_CMD); + rts51x_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, + XD_TRANSFER_END); + + retval = rts51x_send_cmd(chip, MODE_CR, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = rts51x_get_rsp(chip, 1, 200); + if (retval != STATUS_SUCCESS) { + rts51x_clear_xd_error(chip); + TRACE_RET(chip, retval); + } + + return STATUS_SUCCESS; +} + +static int xd_read_multiple_pages(struct rts51x_chip *chip, u32 phy_blk, + u32 log_blk, u8 start_page, u8 end_page, + u8 *buf, void **ptr, unsigned int *offset) +{ + struct xd_info *xd_card = &(chip->xd_card); + u32 page_addr, new_blk; + u16 log_off; + u8 reg_val, page_cnt; + int zone_no, retval, i; + + if (start_page > end_page) + TRACE_RET(chip, STATUS_FAIL); + + page_cnt = end_page - start_page; + zone_no = (int)(log_blk / 1000); + log_off = (u16) (log_blk % 1000); + + if ((phy_blk & 0x3FF) == 0x3FF) { + for (i = 0; i < 256; i++) { + page_addr = ((u32) i) << xd_card->block_shift; + + retval = xd_read_redundant(chip, page_addr, NULL, 0); + if (retval == STATUS_SUCCESS) + break; + + if (monitor_card_cd(chip, XD_CARD) == CD_NOT_EXIST) { + xd_set_err_code(chip, XD_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + } + } + + page_addr = (phy_blk << xd_card->block_shift) + start_page; + + rts51x_init_cmd(chip); + + xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); + + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CFG, XD_PPB_TO_SIE, + XD_PPB_TO_SIE); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, + RING_BUFFER); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, page_cnt); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CHK_DATA_STATUS, + XD_AUTO_CHK_DATA_STATUS, XD_AUTO_CHK_DATA_STATUS); + + trans_dma_enable(chip->srb->sc_data_direction, chip, page_cnt * 512, + DMA_512); + + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, + XD_TRANSFER_START | XD_READ_PAGES); + rts51x_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, + XD_TRANSFER_END | XD_PPB_EMPTY, + XD_TRANSFER_END | XD_PPB_EMPTY); + + retval = rts51x_send_cmd(chip, MODE_CDIR, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = + rts51x_transfer_data_partial(chip, RCV_BULK_PIPE(chip), (void *)buf, + ptr, offset, page_cnt * 512, + scsi_sg_count(chip->srb), NULL, 2000); + if (retval != STATUS_SUCCESS) { + rts51x_clear_xd_error(chip); + + if (retval == STATUS_TIMEDOUT) { + xd_set_err_code(chip, XD_TO_ERROR); + TRACE_RET(chip, retval); + } else { + TRACE_GOTO(chip, Fail); + } + } + retval = rts51x_get_rsp(chip, 1, 200); + if (retval != STATUS_SUCCESS) { + rts51x_clear_xd_error(chip); + + if (retval == STATUS_TIMEDOUT) { + xd_set_err_code(chip, XD_TO_ERROR); + TRACE_RET(chip, retval); + } else { + TRACE_GOTO(chip, Fail); + } + } + + return STATUS_SUCCESS; + +Fail: + rts51x_ep0_read_register(chip, XD_PAGE_STATUS, ®_val); + RTS51X_DEBUGP("XD_PAGE_STATUS: 0x%x\n", reg_val); + + if (reg_val != XD_GPG) + xd_set_err_code(chip, XD_PRG_ERROR); + + rts51x_ep0_read_register(chip, XD_CTL, ®_val); + RTS51X_DEBUGP("XD_CTL: 0x%x\n", reg_val); + + /* Handle uncorrectable ECC error */ + if (((reg_val & (XD_ECC1_ERROR | XD_ECC1_UNCORRECTABLE)) + == (XD_ECC1_ERROR | XD_ECC1_UNCORRECTABLE)) + || ((reg_val & (XD_ECC2_ERROR | XD_ECC2_UNCORRECTABLE)) + == (XD_ECC2_ERROR | XD_ECC2_UNCORRECTABLE))) { + wait_timeout(100); + + if (monitor_card_cd(chip, XD_CARD) == CD_NOT_EXIST) { + xd_set_err_code(chip, XD_NO_CARD); + TRACE_RET(chip, STATUS_FAIL); + } + + xd_set_err_code(chip, XD_ECC_ERROR); + + new_blk = xd_get_unused_block(chip, zone_no); + if (new_blk == NO_NEW_BLK) { + XD_CLR_BAD_OLDBLK(xd_card); + TRACE_RET(chip, STATUS_FAIL); + } +#ifdef XD_SPEEDUP + retval = + xd_auto_copy_page(chip, phy_blk, new_blk, 0, + xd_card->page_off + 1); +#else + retval = + xd_copy_page(chip, phy_blk, new_blk, 0, + xd_card->page_off + 1); +#endif + if (retval != STATUS_SUCCESS) { + if (!XD_CHK_BAD_NEWBLK(xd_card)) { + retval = xd_erase_block(chip, new_blk); + if (retval == STATUS_SUCCESS) + xd_set_unused_block(chip, new_blk); + } else { + XD_CLR_BAD_NEWBLK(xd_card); + } + XD_CLR_BAD_OLDBLK(xd_card); + TRACE_RET(chip, STATUS_FAIL); + } + xd_set_l2p_tbl(chip, zone_no, log_off, (u16) (new_blk & 0x3FF)); + xd_erase_block(chip, phy_blk); + xd_mark_bad_block(chip, phy_blk); + XD_CLR_BAD_OLDBLK(xd_card); + } + + TRACE_RET(chip, STATUS_FAIL); +} + +static int xd_finish_write(struct rts51x_chip *chip, + u32 old_blk, u32 new_blk, u32 log_blk, u8 page_off) +{ + struct xd_info *xd_card = &(chip->xd_card); + int retval, zone_no; + u16 log_off; + + RTS51X_DEBUGP("xd_finish_write, old_blk = 0x%x, new_blk = 0x%x," + "log_blk = 0x%x\n", old_blk, new_blk, log_blk); + + if (page_off > xd_card->page_off) + TRACE_RET(chip, STATUS_FAIL); + + zone_no = (int)(log_blk / 1000); + log_off = (u16) (log_blk % 1000); + + if (old_blk == BLK_NOT_FOUND) { + retval = xd_init_page(chip, new_blk, log_off, + page_off, xd_card->page_off + 1); + if (retval != STATUS_SUCCESS) { + retval = xd_erase_block(chip, new_blk); + if (retval == STATUS_SUCCESS) + xd_set_unused_block(chip, new_blk); + TRACE_RET(chip, STATUS_FAIL); + } + } else { +#ifdef XD_SPEEDUP + retval = xd_auto_copy_page(chip, old_blk, new_blk, + page_off, xd_card->page_off + 1); +#else + retval = xd_copy_page(chip, old_blk, new_blk, + page_off, xd_card->page_off + 1); +#endif + if (retval != STATUS_SUCCESS) { + if (!XD_CHK_BAD_NEWBLK(xd_card)) { + retval = xd_erase_block(chip, new_blk); + if (retval == STATUS_SUCCESS) + xd_set_unused_block(chip, new_blk); + } + XD_CLR_BAD_NEWBLK(xd_card); + TRACE_RET(chip, STATUS_FAIL); + } + + retval = xd_erase_block(chip, old_blk); + if (retval == STATUS_SUCCESS) { + if (XD_CHK_BAD_OLDBLK(xd_card)) { + xd_mark_bad_block(chip, old_blk); + XD_CLR_BAD_OLDBLK(xd_card); + } else { + /* Add source block to unused block */ + xd_set_unused_block(chip, old_blk); + } + } else { + xd_set_err_code(chip, XD_NO_ERROR); + XD_CLR_BAD_OLDBLK(xd_card); + } + } + + /* Add target block to L2P table */ + xd_set_l2p_tbl(chip, zone_no, log_off, (u16) (new_blk & 0x3FF)); + + return STATUS_SUCCESS; +} + +static int xd_prepare_write(struct rts51x_chip *chip, + u32 old_blk, u32 new_blk, u32 log_blk, u8 page_off) +{ + int retval; + + RTS51X_DEBUGP("xd_prepare_write, old_blk = 0x%x, new_blk = 0x%x," + "log_blk = 0x%x, page_off = %d\n", + old_blk, new_blk, log_blk, (int)page_off); + + if (page_off) { +#ifdef XD_SPEEDUP + retval = xd_auto_copy_page(chip, old_blk, new_blk, 0, page_off); +#else + retval = xd_copy_page(chip, old_blk, new_blk, 0, page_off); +#endif + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } + + return STATUS_SUCCESS; +} + +static int xd_write_multiple_pages(struct rts51x_chip *chip, u32 old_blk, + u32 new_blk, u32 log_blk, u8 start_page, + u8 end_page, u8 *buf, void **ptr, + unsigned int *offset) +{ + struct xd_info *xd_card = &(chip->xd_card); + u32 page_addr; + int zone_no, retval; + u16 log_off; + u8 page_cnt, reg_val; + + RTS51X_DEBUGP("xd_write_multiple_pages, old_blk = 0x%x," + "new_blk = 0x%x, log_blk = 0x%x\n", + old_blk, new_blk, log_blk); + + if (start_page > end_page) + TRACE_RET(chip, STATUS_FAIL); + + page_cnt = end_page - start_page; + zone_no = (int)(log_blk / 1000); + log_off = (u16) (log_blk % 1000); + + page_addr = (new_blk << xd_card->block_shift) + start_page; + + /* Send index command */ + retval = xd_send_cmd(chip, READ1_1); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + rts51x_init_cmd(chip); + + /* Prepare redundant field */ + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_H, 0xFF, + (u8) (log_off >> 8)); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_ADDR1_L, 0xFF, + (u8) log_off); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_BLOCK_STATUS, 0xFF, XD_GBLK); + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_STATUS, 0xFF, XD_GPG); + + xd_assign_phy_addr(chip, page_addr, XD_RW_ADDR); + + /* Transform the block address by hardware */ + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_CFG, XD_BA_TRANSFORM, + XD_BA_TRANSFORM); + + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_PAGE_CNT, 0xFF, page_cnt); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_DATA_SOURCE, 0x01, + RING_BUFFER); + + trans_dma_enable(chip->srb->sc_data_direction, chip, page_cnt * 512, + DMA_512); + + rts51x_add_cmd(chip, WRITE_REG_CMD, XD_TRANSFER, 0xFF, + XD_TRANSFER_START | XD_WRITE_PAGES); + rts51x_add_cmd(chip, CHECK_REG_CMD, XD_TRANSFER, XD_TRANSFER_END, + XD_TRANSFER_END); + + retval = rts51x_send_cmd(chip, MODE_CDOR, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + retval = + rts51x_transfer_data_partial(chip, SND_BULK_PIPE(chip), (void *)buf, + ptr, offset, page_cnt * 512, + scsi_sg_count(chip->srb), NULL, 2000); + if (retval != STATUS_SUCCESS) { + rts51x_clear_xd_error(chip); + + if (retval == STATUS_TIMEDOUT) { + xd_set_err_code(chip, XD_TO_ERROR); + TRACE_RET(chip, retval); + } else { + TRACE_GOTO(chip, Fail); + } + } + retval = rts51x_get_rsp(chip, 1, 200); + if (retval != STATUS_SUCCESS) { + rts51x_clear_xd_error(chip); + + if (retval == STATUS_TIMEDOUT) { + xd_set_err_code(chip, XD_TO_ERROR); + TRACE_RET(chip, retval); + } else { + TRACE_GOTO(chip, Fail); + } + } + + if (end_page == (xd_card->page_off + 1)) { + xd_card->delay_write.delay_write_flag = 0; + + if (old_blk != BLK_NOT_FOUND) { + retval = xd_erase_block(chip, old_blk); + if (retval == STATUS_SUCCESS) { + if (XD_CHK_BAD_OLDBLK(xd_card)) { + xd_mark_bad_block(chip, old_blk); + XD_CLR_BAD_OLDBLK(xd_card); + } else { + xd_set_unused_block(chip, old_blk); + } + } else { + xd_set_err_code(chip, XD_NO_ERROR); + XD_CLR_BAD_OLDBLK(xd_card); + } + } + xd_set_l2p_tbl(chip, zone_no, log_off, (u16) (new_blk & 0x3FF)); + } + + return STATUS_SUCCESS; + +Fail: + rts51x_ep0_read_register(chip, XD_DAT, ®_val); + RTS51X_DEBUGP("XD_DAT: 0x%x\n", reg_val); + + if (reg_val & PROGRAM_ERROR) { + xd_set_err_code(chip, XD_PRG_ERROR); + xd_mark_bad_block(chip, new_blk); + } + + TRACE_RET(chip, STATUS_FAIL); +} + +int xd_delay_write(struct rts51x_chip *chip) +{ + struct xd_info *xd_card = &(chip->xd_card); + struct xd_delay_write_tag *delay_write = &(xd_card->delay_write); + int retval; + + if (delay_write->delay_write_flag) { + RTS51X_DEBUGP("xd_delay_write\n"); + retval = xd_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + delay_write->delay_write_flag = 0; + retval = xd_finish_write(chip, + delay_write->old_phyblock, + delay_write->new_phyblock, + delay_write->logblock, + delay_write->pageoff); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + } + + return STATUS_SUCCESS; +} + +int xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, + u16 sector_cnt) +{ + struct xd_info *xd_card = &(chip->xd_card); + unsigned int lun = SCSI_LUN(srb); + struct xd_delay_write_tag *delay_write = &(xd_card->delay_write); + int retval, zone_no; + u32 log_blk, old_blk = 0, new_blk = 0; + u16 log_off, total_sec_cnt = sector_cnt; + u8 start_page, end_page = 0, page_cnt; + u8 *buf; + void *ptr = NULL; + unsigned int offset = 0; + + xd_set_err_code(chip, XD_NO_ERROR); + + xd_card->counter = 0; + + RTS51X_DEBUGP("xd_rw: scsi_bufflen = %d, scsi_sg_count = %d\n", + scsi_bufflen(srb), scsi_sg_count(srb)); + RTS51X_DEBUGP("Data direction: %s\n", + (srb->sc_data_direction == + DMA_TO_DEVICE) ? "write" : "read"); + + buf = (u8 *) scsi_sglist(srb); + + retval = xd_switch_clock(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + log_blk = start_sector >> xd_card->block_shift; + start_page = (u8) start_sector & xd_card->page_off; + zone_no = (int)(log_blk / 1000); + log_off = (u16) (log_blk % 1000); + + RTS51X_DEBUGP("log_blk = 0x%x\n", log_blk); + + if (xd_card->zone[zone_no].build_flag == 0) { + retval = xd_build_l2p_tbl(chip, zone_no); + if (retval != STATUS_SUCCESS) { + chip->card_fail |= XD_CARD; + set_sense_type(chip, lun, SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, retval); + } + } + + if (srb->sc_data_direction == DMA_TO_DEVICE) { + if (delay_write->delay_write_flag && + (delay_write->logblock == log_blk) && + (start_page > delay_write->pageoff)) { + delay_write->delay_write_flag = 0; + if (delay_write->old_phyblock != BLK_NOT_FOUND) { +#ifdef XD_SPEEDUP + retval = xd_auto_copy_page(chip, + delay_write->old_phyblock, + delay_write->new_phyblock, + delay_write->pageoff, start_page); +#else + retval = xd_copy_page(chip, + delay_write->old_phyblock, + delay_write->new_phyblock, + delay_write->pageoff, + start_page); +#endif + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, retval); + } + } + old_blk = delay_write->old_phyblock; + new_blk = delay_write->new_phyblock; + } else if (delay_write->delay_write_flag && + (delay_write->logblock == log_blk) && + (start_page == delay_write->pageoff)) { + delay_write->delay_write_flag = 0; + old_blk = delay_write->old_phyblock; + new_blk = delay_write->new_phyblock; + } else { + retval = xd_delay_write(chip); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, retval); + } + old_blk = xd_get_l2p_tbl(chip, zone_no, log_off); + new_blk = xd_get_unused_block(chip, zone_no); + if ((old_blk == BLK_NOT_FOUND) + || (new_blk == BLK_NOT_FOUND)) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, retval); + } + + retval = + xd_prepare_write(chip, old_blk, new_blk, log_blk, + start_page); + if (retval != STATUS_SUCCESS) { + if (monitor_card_cd(chip, XD_CARD) == + CD_NOT_EXIST) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, STATUS_FAIL); + } + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, retval); + } + } + } else { + retval = xd_delay_write(chip); + if (retval != STATUS_SUCCESS) { + if (monitor_card_cd(chip, XD_CARD) == CD_NOT_EXIST) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, STATUS_FAIL); + } + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, retval); + } + + old_blk = xd_get_l2p_tbl(chip, zone_no, log_off); + if (old_blk == BLK_NOT_FOUND) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + RTS51X_DEBUGP("old_blk = 0x%x\n", old_blk); + if (srb->sc_data_direction == DMA_TO_DEVICE) + RTS51X_DEBUGP("new_blk = 0x%x\n", new_blk); + + while (total_sec_cnt) { + if ((start_page + total_sec_cnt) > (xd_card->page_off + 1)) + end_page = xd_card->page_off + 1; + else + end_page = start_page + (u8) total_sec_cnt; + page_cnt = end_page - start_page; + if (srb->sc_data_direction == DMA_FROM_DEVICE) { + retval = xd_read_multiple_pages(chip, old_blk, log_blk, + start_page, end_page, + buf, &ptr, &offset); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + } else { + retval = + xd_write_multiple_pages(chip, old_blk, new_blk, + log_blk, start_page, + end_page, buf, &ptr, + &offset); + if (retval != STATUS_SUCCESS) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + total_sec_cnt -= page_cnt; + + if (total_sec_cnt == 0) + break; + + log_blk++; + zone_no = (int)(log_blk / 1000); + log_off = (u16) (log_blk % 1000); + + if (xd_card->zone[zone_no].build_flag == 0) { + retval = xd_build_l2p_tbl(chip, zone_no); + if (retval != STATUS_SUCCESS) { + chip->card_fail |= XD_CARD; + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_NOT_PRESENT); + TRACE_RET(chip, retval); + } + } + + old_blk = xd_get_l2p_tbl(chip, zone_no, log_off); + if (old_blk == BLK_NOT_FOUND) { + if (srb->sc_data_direction == DMA_FROM_DEVICE) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_UNRECOVER_READ_ERR); + } else { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_WRITE_ERR); + } + TRACE_RET(chip, STATUS_FAIL); + } + + if (srb->sc_data_direction == DMA_TO_DEVICE) { + new_blk = xd_get_unused_block(chip, zone_no); + if (new_blk == BLK_NOT_FOUND) { + set_sense_type(chip, lun, + SENSE_TYPE_MEDIA_WRITE_ERR); + TRACE_RET(chip, STATUS_FAIL); + } + } + + start_page = 0; + } + + if ((srb->sc_data_direction == DMA_TO_DEVICE) && + (end_page != (xd_card->page_off + 1))) { + delay_write->delay_write_flag = 1; + delay_write->old_phyblock = old_blk; + delay_write->new_phyblock = new_blk; + delay_write->logblock = log_blk; + delay_write->pageoff = end_page; + } + + scsi_set_resid(srb, 0); + + return STATUS_SUCCESS; +} + +void xd_free_l2p_tbl(struct rts51x_chip *chip) +{ + struct xd_info *xd_card = &(chip->xd_card); + int i = 0; + + if (xd_card->zone != NULL) { + for (i = 0; i < xd_card->zone_cnt; i++) { + if (xd_card->zone[i].l2p_table != NULL) { + vfree(xd_card->zone[i].l2p_table); + xd_card->zone[i].l2p_table = NULL; + } + if (xd_card->zone[i].free_table != NULL) { + vfree(xd_card->zone[i].free_table); + xd_card->zone[i].free_table = NULL; + } + } + vfree(xd_card->zone); + xd_card->zone = NULL; + } +} + +void xd_cleanup_work(struct rts51x_chip *chip) +{ + struct xd_info *xd_card = &(chip->xd_card); + + if (xd_card->delay_write.delay_write_flag) { + RTS51X_DEBUGP("xD: delay write\n"); + xd_delay_write(chip); + xd_card->counter = 0; + } +} + +int xd_power_off_card3v3(struct rts51x_chip *chip) +{ + int retval; + + rts51x_init_cmd(chip); + + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_CLK_EN, XD_CLK_EN, 0); + + if (chip->asic_code) + xd_pull_ctl_disable(chip); + else + rts51x_add_cmd(chip, WRITE_REG_CMD, FPGA_PULL_CTL, 0xFF, 0xDF); + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_OE, XD_OUTPUT_EN, 0); + if (!chip->option.FT2_fast_mode) { + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, POWER_MASK, + POWER_OFF); + if (CHECK_PKG(chip, LQFP48) + || chip->option.rts5129_D3318_off_enable) + rts51x_add_cmd(chip, WRITE_REG_CMD, CARD_PWR_CTL, + DV3318_AUTO_PWR_OFF, 0); + } + + retval = rts51x_send_cmd(chip, MODE_C, 100); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + return STATUS_SUCCESS; +} + +int release_xd_card(struct rts51x_chip *chip) +{ + struct xd_info *xd_card = &(chip->xd_card); + int retval; + + RTS51X_DEBUGP("elease_xd_card\n"); + + chip->card_ready &= ~XD_CARD; + chip->card_fail &= ~XD_CARD; + chip->card_wp &= ~XD_CARD; + + xd_card->delay_write.delay_write_flag = 0; + + xd_free_l2p_tbl(chip); + + rts51x_write_register(chip, SFSM_ED, HW_CMD_STOP, HW_CMD_STOP); + + retval = xd_power_off_card3v3(chip); + if (retval != STATUS_SUCCESS) + TRACE_RET(chip, retval); + + if (chip->asic_code && CHECK_PKG(chip, QFN24)) + wait_timeout(20); + + return STATUS_SUCCESS; +} diff --git a/drivers/staging/rts5139/xd.h b/drivers/staging/rts5139/xd.h new file mode 100644 index 0000000..fa69590 --- /dev/null +++ b/drivers/staging/rts5139/xd.h @@ -0,0 +1,193 @@ +/* Driver for Realtek RTS51xx USB card reader + * Header file + * + * Copyright(c) 2009 Realtek Semiconductor Corp. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see <http://www.gnu.org/licenses/>. + * + * Author: + * wwang (wei_wang@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + * Maintainer: + * Edwin Rong (edwin_rong@realsil.com.cn) + * No. 450, Shenhu Road, Suzhou Industry Park, Suzhou, China + */ + +#ifndef __RTS51X_XD_H +#define __RTS51X_XD_H + +/* Error Codes */ +#define XD_NO_ERROR 0x00 +#define XD_NO_MEMORY 0x80 +#define XD_PRG_ERROR 0x40 +#define XD_NO_CARD 0x20 +#define XD_READ_FAIL 0x10 +#define XD_ERASE_FAIL 0x08 +#define XD_WRITE_FAIL 0x04 +#define XD_ECC_ERROR 0x02 +#define XD_TO_ERROR 0x01 + +/* XD Commands */ +#define READ1_1 0x00 +#define READ1_2 0x01 +#define READ2 0x50 +#define READ_ID 0x90 +#define RESET 0xff +#define PAGE_PRG_1 0x80 +#define PAGE_PRG_2 0x10 +#define BLK_ERASE_1 0x60 +#define BLK_ERASE_2 0xD0 +#define READ_STS 0x70 +#define READ_xD_ID 0x9A +#define COPY_BACK_512 0x8A +#define COPY_BACK_2K 0x85 +#define READ1_1_2 0x30 +#define READ1_1_3 0x35 +#define CHG_DAT_OUT_1 0x05 +#define RDM_DAT_OUT_1 0x05 +#define CHG_DAT_OUT_2 0xE0 +#define RDM_DAT_OUT_2 0xE0 +#define CHG_DAT_OUT_2 0xE0 +#define CHG_DAT_IN_1 0x85 +#define CACHE_PRG 0x15 + +/* Redundant Area Related */ +#define XD_EXTRA_SIZE 0x10 +#define XD_2K_EXTRA_SIZE 0x40 + +/* Define for XD Status */ +#define NOT_WRITE_PROTECTED 0x80 +#define READY_STATE 0x40 +#define PROGRAM_ERROR 0x01 +#define PROGRAM_ERROR_N_1 0x02 +#define INTERNAL_READY 0x20 +#define READY_FLAG 0x5F + +/* Define for device code */ +#define XD_8M_X8_512 0xE6 +#define XD_16M_X8_512 0x73 +#define XD_32M_X8_512 0x75 +#define XD_64M_X8_512 0x76 +#define XD_128M_X8_512 0x79 +#define XD_256M_X8_512 0x71 +#define XD_128M_X8_2048 0xF1 +#define XD_256M_X8_2048 0xDA +#define XD_512M_X8 0xDC +#define XD_128M_X16_2048 0xC1 +#define XD_4M_X8_512_1 0xE3 +#define XD_4M_X8_512_2 0xE5 +#define xD_1G_X8_512 0xD3 +#define xD_2G_X8_512 0xD5 + +#define XD_ID_CODE 0xB5 + +#define VENDOR_BLOCK 0xEFFF +#define CIS_BLOCK 0xDFFF + +#define BLK_NOT_FOUND 0xFFFFFFFF + +#define NO_NEW_BLK 0xFFFFFFFF + +#define PAGE_CORRECTABLE 0x0 +#define PAGE_NOTCORRECTABLE 0x1 + +#define NO_OFFSET 0x0 +#define WITH_OFFSET 0x1 + +#define Sect_Per_Page 4 +#define XD_ADDR_MODE_2C XD_ADDR_MODE_2A + +#define ZONE0_BAD_BLOCK 23 +#define NOT_ZONE0_BAD_BLOCK 24 + +/* Assign address mode */ +#define XD_RW_ADDR 0x01 +#define XD_ERASE_ADDR 0x02 + +/* Macro Definition */ +#define XD_PAGE_512(xd_card) \ + do { \ + (xd_card)->block_shift = 5; \ + (xd_card)->page_off = 0x1F; \ + } while (0) + +#define XD_SET_BAD_NEWBLK(xd_card) ((xd_card)->multi_flag |= 0x01) +#define XD_CLR_BAD_NEWBLK(xd_card) ((xd_card)->multi_flag &= ~0x01) +#define XD_CHK_BAD_NEWBLK(xd_card) ((xd_card)->multi_flag & 0x01) + +#define XD_SET_BAD_OLDBLK(xd_card) ((xd_card)->multi_flag |= 0x02) +#define XD_CLR_BAD_OLDBLK(xd_card) ((xd_card)->multi_flag &= ~0x02) +#define XD_CHK_BAD_OLDBLK(xd_card) ((xd_card)->multi_flag & 0x02) + +#define XD_SET_MBR_FAIL(xd_card) ((xd_card)->multi_flag |= 0x04) +#define XD_CLR_MBR_FAIL(xd_card) ((xd_card)->multi_flag &= ~0x04) +#define XD_CHK_MBR_FAIL(xd_card) ((xd_card)->multi_flag & 0x04) + +#define XD_SET_ECC_FLD_ERR(xd_card) ((xd_card)->multi_flag |= 0x08) +#define XD_CLR_ECC_FLD_ERR(xd_card) ((xd_card)->multi_flag &= ~0x08) +#define XD_CHK_ECC_FLD_ERR(xd_card) ((xd_card)->multi_flag & 0x08) + +#define XD_SET_4MB(xd_card) ((xd_card)->multi_flag |= 0x10) +#define XD_CLR_4MB(xd_card) ((xd_card)->multi_flag &= ~0x10) +#define XD_CHK_4MB(xd_card) ((xd_card)->multi_flag & 0x10) + +#define XD_SET_ECC_ERR(xd_card) ((xd_card)->multi_flag |= 0x40) +#define XD_CLR_ECC_ERR(xd_card) ((xd_card)->multi_flag &= ~0x40) +#define XD_CHK_ECC_ERR(xd_card) ((xd_card)->multi_flag & 0x40) + +/* Offset in xD redundant buffer */ +#define PAGE_STATUS 0 +#define BLOCK_STATUS 1 +#define BLOCK_ADDR1_L 2 +#define BLOCK_ADDR1_H 3 +#define BLOCK_ADDR2_L 4 +#define BLOCK_ADDR2_H 5 +#define RESERVED0 6 +#define RESERVED1 7 +#define RESERVED2 8 +#define RESERVED3 9 +#define PARITY 10 + +/* For CIS block */ +#define CIS0_0 0 +#define CIS0_1 1 +#define CIS0_2 2 +#define CIS0_3 3 +#define CIS0_4 4 +#define CIS0_5 5 +#define CIS0_6 6 +#define CIS0_7 7 +#define CIS0_8 8 +#define CIS0_9 9 +#define CIS1_0 256 +#define CIS1_1 (256 + 1) +#define CIS1_2 (256 + 2) +#define CIS1_3 (256 + 3) +#define CIS1_4 (256 + 4) +#define CIS1_5 (256 + 5) +#define CIS1_6 (256 + 6) +#define CIS1_7 (256 + 7) +#define CIS1_8 (256 + 8) +#define CIS1_9 (256 + 9) + +int reset_xd_card(struct rts51x_chip *chip); +int xd_delay_write(struct rts51x_chip *chip); +int xd_rw(struct scsi_cmnd *srb, struct rts51x_chip *chip, u32 start_sector, + u16 sector_cnt); +void xd_free_l2p_tbl(struct rts51x_chip *chip); +void xd_cleanup_work(struct rts51x_chip *chip); +int xd_power_off_card3v3(struct rts51x_chip *chip); +int release_xd_card(struct rts51x_chip *chip); + +#endif /* __RTS51X_XD_H */ diff --git a/drivers/staging/rts_pstor/Makefile b/drivers/staging/rts_pstor/Makefile index 61609ae..42533d3 100644 --- a/drivers/staging/rts_pstor/Makefile +++ b/drivers/staging/rts_pstor/Makefile @@ -1,4 +1,4 @@ -EXTRA_CFLAGS := -Idrivers/scsi +ccflags := -Idrivers/scsi obj-$(CONFIG_RTS_PSTOR) := rts_pstor.o diff --git a/drivers/staging/rts_pstor/rtsx_scsi.c b/drivers/staging/rts_pstor/rtsx_scsi.c index 7de1fae..f2e5842 100644 --- a/drivers/staging/rts_pstor/rtsx_scsi.c +++ b/drivers/staging/rts_pstor/rtsx_scsi.c @@ -2730,7 +2730,7 @@ static int get_ms_information(struct scsi_cmnd *srb, struct rtsx_chip *chip) buf_len = data_len = 0x6A; } - buf = (u8 *)kmalloc(buf_len, GFP_KERNEL); + buf = kmalloc(buf_len, GFP_KERNEL); if (!buf) { TRACE_RET(chip, TRANSPORT_ERROR); } diff --git a/drivers/staging/rts_pstor/sd.c b/drivers/staging/rts_pstor/sd.c index 8db14dd..fb62eaf 100644 --- a/drivers/staging/rts_pstor/sd.c +++ b/drivers/staging/rts_pstor/sd.c @@ -4139,7 +4139,7 @@ int sd_execute_read_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) cmd[3] = srb->cmnd[5]; cmd[4] = srb->cmnd[6]; - buf = (u8 *)kmalloc(data_len, GFP_KERNEL); + buf = kmalloc(data_len, GFP_KERNEL); if (buf == NULL) { TRACE_RET(chip, TRANSPORT_ERROR); } @@ -4385,7 +4385,7 @@ int sd_execute_write_data(struct scsi_cmnd *srb, struct rtsx_chip *chip) u16 i; u8 *buf; - buf = (u8 *)kmalloc(data_len, GFP_KERNEL); + buf = kmalloc(data_len, GFP_KERNEL); if (buf == NULL) { TRACE_RET(chip, TRANSPORT_ERROR); } diff --git a/drivers/staging/rts_pstor/spi.c b/drivers/staging/rts_pstor/spi.c index c803ba6..6b36cc5 100644 --- a/drivers/staging/rts_pstor/spi.c +++ b/drivers/staging/rts_pstor/spi.c @@ -463,7 +463,7 @@ int spi_read_flash_id(struct scsi_cmnd *srb, struct rtsx_chip *chip) } if (len) { - buf = (u8 *)kmalloc(len, GFP_KERNEL); + buf = kmalloc(len, GFP_KERNEL); if (!buf) TRACE_RET(chip, STATUS_ERROR); diff --git a/drivers/staging/serqt_usb2/serqt_usb2.c b/drivers/staging/serqt_usb2/serqt_usb2.c index 12f5eba..2ea82c1 100644 --- a/drivers/staging/serqt_usb2/serqt_usb2.c +++ b/drivers/staging/serqt_usb2/serqt_usb2.c @@ -190,7 +190,7 @@ struct quatech_port { struct usb_serial_port *port; /* owner of this object */ struct qt_get_device_data DeviceData; - spinlock_t lock; + struct mutex lock; bool read_urb_busy; int RxHolding; int ReadBulkStopped; @@ -745,7 +745,7 @@ static int qt_startup(struct usb_serial *serial) } return -ENOMEM; } - spin_lock_init(&qt_port->lock); + mutex_init(&qt_port->lock); usb_set_serial_port_data(port, qt_port); @@ -1160,7 +1160,6 @@ static int qt_write_room(struct tty_struct *tty) struct usb_serial_port *port = tty->driver_data; struct usb_serial *serial; struct quatech_port *qt_port; - unsigned long flags; int retval = -EINVAL; @@ -1176,7 +1175,7 @@ static int qt_write_room(struct tty_struct *tty) qt_port = qt_get_port_private(port); - spin_lock_irqsave(&qt_port->lock, flags); + mutex_lock(&qt_port->lock); dbg("%s - port %d\n", __func__, port->number); @@ -1185,7 +1184,7 @@ static int qt_write_room(struct tty_struct *tty) retval = port->bulk_out_size; } - spin_unlock_irqrestore(&qt_port->lock, flags); + mutex_unlock(&qt_port->lock); return retval; } @@ -1358,7 +1357,6 @@ static void qt_break(struct tty_struct *tty, int break_state) struct quatech_port *qt_port; u16 index, onoff; unsigned int result; - unsigned long flags; index = tty->index - serial->minor; @@ -1369,7 +1367,7 @@ static void qt_break(struct tty_struct *tty, int break_state) else onoff = 0; - spin_lock_irqsave(&qt_port->lock, flags); + mutex_lock(&qt_port->lock); dbg("%s - port %d\n", __func__, port->number); @@ -1377,7 +1375,7 @@ static void qt_break(struct tty_struct *tty, int break_state) usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), QT_BREAK_CONTROL, 0x40, onoff, index, NULL, 0, 300); - spin_unlock_irqrestore(&qt_port->lock, flags); + mutex_unlock(&qt_port->lock); } static inline int qt_real_tiocmget(struct tty_struct *tty, @@ -1466,21 +1464,20 @@ static int qt_tiocmget(struct tty_struct *tty) struct usb_serial *serial = get_usb_serial(port, __func__); struct quatech_port *qt_port = qt_get_port_private(port); int retval = -ENODEV; - unsigned long flags; dbg("In %s\n", __func__); if (!serial) return -ENODEV; - spin_lock_irqsave(&qt_port->lock, flags); + mutex_lock(&qt_port->lock); dbg("%s - port %d\n", __func__, port->number); dbg("%s - port->RxHolding = %d\n", __func__, qt_port->RxHolding); retval = qt_real_tiocmget(tty, port, serial); - spin_unlock_irqrestore(&qt_port->lock, flags); + mutex_unlock(&qt_port->lock); return retval; } @@ -1491,7 +1488,6 @@ static int qt_tiocmset(struct tty_struct *tty, struct usb_serial_port *port = tty->driver_data; struct usb_serial *serial = get_usb_serial(port, __func__); struct quatech_port *qt_port = qt_get_port_private(port); - unsigned long flags; int retval = -ENODEV; dbg("In %s\n", __func__); @@ -1499,14 +1495,14 @@ static int qt_tiocmset(struct tty_struct *tty, if (!serial) return -ENODEV; - spin_lock_irqsave(&qt_port->lock, flags); + mutex_lock(&qt_port->lock); dbg("%s - port %d\n", __func__, port->number); dbg("%s - qt_port->RxHolding = %d\n", __func__, qt_port->RxHolding); retval = qt_real_tiocmset(tty, port, serial, set); - spin_unlock_irqrestore(&qt_port->lock, flags); + mutex_unlock(&qt_port->lock); return retval; } @@ -1515,7 +1511,6 @@ static void qt_throttle(struct tty_struct *tty) struct usb_serial_port *port = tty->driver_data; struct usb_serial *serial = get_usb_serial(port, __func__); struct quatech_port *qt_port; - unsigned long flags; dbg("%s - port %d\n", __func__, port->number); @@ -1524,13 +1519,13 @@ static void qt_throttle(struct tty_struct *tty) qt_port = qt_get_port_private(port); - spin_lock_irqsave(&qt_port->lock, flags); + mutex_lock(&qt_port->lock); /* pass on to the driver specific version of this function */ qt_port->RxHolding = 1; dbg("%s - port->RxHolding = 1\n", __func__); - spin_unlock_irqrestore(&qt_port->lock, flags); + mutex_unlock(&qt_port->lock); return; } @@ -1539,7 +1534,6 @@ static void qt_unthrottle(struct tty_struct *tty) struct usb_serial_port *port = tty->driver_data; struct usb_serial *serial = get_usb_serial(port, __func__); struct quatech_port *qt_port; - unsigned long flags; unsigned int result; if (!serial) @@ -1547,7 +1541,7 @@ static void qt_unthrottle(struct tty_struct *tty) qt_port = qt_get_port_private(port); - spin_lock_irqsave(&qt_port->lock, flags); + mutex_lock(&qt_port->lock); dbg("%s - port %d\n", __func__, port->number); @@ -1573,7 +1567,7 @@ static void qt_unthrottle(struct tty_struct *tty) __func__, result); } } - spin_unlock_irqrestore(&qt_port->lock, flags); + mutex_unlock(&qt_port->lock); return; } diff --git a/drivers/staging/sm7xx/smtcfb.c b/drivers/staging/sm7xx/smtcfb.c index a164fc4..39dbf33 100644 --- a/drivers/staging/sm7xx/smtcfb.c +++ b/drivers/staging/sm7xx/smtcfb.c @@ -35,11 +35,13 @@ #include <linux/init.h> #include <linux/slab.h> #include <linux/uaccess.h> +#include <linux/module.h> #include <linux/console.h> #include <linux/screen_info.h> #ifdef CONFIG_PM #include <linux/pm.h> +#include <linux/module.h> #endif #include "smtcfb.h" diff --git a/drivers/staging/spectra/ffsport.c b/drivers/staging/spectra/ffsport.c index 506547b..86d556d 100644 --- a/drivers/staging/spectra/ffsport.c +++ b/drivers/staging/spectra/ffsport.c @@ -227,19 +227,12 @@ static int ioctl_write_page_data(unsigned long arg) if (copy_from_user(&info, (void __user *)arg, sizeof(info))) return -EFAULT; - buf = kmalloc(IdentifyDeviceData.PageDataSize, GFP_ATOMIC); - if (!buf) { - printk(KERN_ERR "ioctl_write_page_data: " - "failed to allocate memory\n"); - return -ENOMEM; - } - - if (copy_from_user(buf, (void __user *)info.data, - IdentifyDeviceData.PageDataSize)) { + buf = memdup_user((void __user *)info.data, + IdentifyDeviceData.PageDataSize); + if (IS_ERR(buf)) { printk(KERN_ERR "ioctl_write_page_data: " "failed to copy user data\n"); - kfree(buf); - return -EFAULT; + return PTR_ERR(buf); } mutex_lock(&spectra_lock); diff --git a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c index 36f4cb7..11728a0 100644 --- a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c +++ b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c @@ -30,6 +30,7 @@ #include <linux/i2c.h> #include <linux/interrupt.h> #include <linux/regulator/consumer.h> +#include <linux/module.h> #include "synaptics_i2c_rmi4.h" /* TODO: for multiple device support will need a per-device mutex */ diff --git a/drivers/staging/tidspbridge/gen/gh.c b/drivers/staging/tidspbridge/gen/gh.c index cd72503..60aa7b0 100644 --- a/drivers/staging/tidspbridge/gen/gh.c +++ b/drivers/staging/tidspbridge/gen/gh.c @@ -55,7 +55,7 @@ struct gh_t_hash_tab *gh_create(u16 max_bucket, u16 val_size, hash_tab->match = match; hash_tab->delete = delete == NULL ? noop : delete; - hash_tab->buckets = (struct element **) + hash_tab->buckets = kzalloc(sizeof(struct element *) * max_bucket, GFP_KERNEL); if (hash_tab->buckets == NULL) { gh_delete(hash_tab); diff --git a/drivers/staging/usbip/stub.h b/drivers/staging/usbip/stub.h index 132adc5..d407368 100644 --- a/drivers/staging/usbip/stub.h +++ b/drivers/staging/usbip/stub.h @@ -17,6 +17,9 @@ * USA. */ +#ifndef __USBIP_STUB_H +#define __USBIP_STUB_H + #include <linux/list.h> #include <linux/slab.h> #include <linux/spinlock.h> @@ -106,3 +109,5 @@ void stub_enqueue_ret_unlink(struct stub_device *sdev, __u32 seqnum, __u32 status); void stub_complete(struct urb *urb); int stub_tx_loop(void *data); + +#endif /* __USBIP_STUB_H */ diff --git a/drivers/staging/usbip/stub_dev.c b/drivers/staging/usbip/stub_dev.c index fce22f2..55c0b51 100644 --- a/drivers/staging/usbip/stub_dev.c +++ b/drivers/staging/usbip/stub_dev.c @@ -19,6 +19,7 @@ #include <linux/device.h> #include <linux/kthread.h> +#include <linux/module.h> #include "usbip_common.h" #include "stub.h" @@ -524,11 +525,11 @@ static void stub_disconnect(struct usb_interface *interface) } } -/* +/* * Presence of pre_reset and post_reset prevents the driver from being unbound * when the device is being reset */ - + int stub_pre_reset(struct usb_interface *interface) { dev_dbg(&interface->dev, "pre_reset\n"); @@ -548,4 +549,4 @@ struct usb_driver stub_driver = { .id_table = stub_table, .pre_reset = stub_pre_reset, .post_reset = stub_post_reset, - }; +}; diff --git a/drivers/staging/usbip/stub_main.c b/drivers/staging/usbip/stub_main.c index a34249a..2d63178 100644 --- a/drivers/staging/usbip/stub_main.c +++ b/drivers/staging/usbip/stub_main.c @@ -18,6 +18,7 @@ */ #include <linux/string.h> +#include <linux/module.h> #include "usbip_common.h" #include "stub.h" diff --git a/drivers/staging/usbip/stub_rx.c b/drivers/staging/usbip/stub_rx.c index 538fb9e..6b4e3e1 100644 --- a/drivers/staging/usbip/stub_rx.c +++ b/drivers/staging/usbip/stub_rx.c @@ -175,12 +175,11 @@ static int tweak_reset_device_cmd(struct urb *urb) dev_info(&urb->dev->dev, "usb_queue_reset_device\n"); /* - * With the implementation of pre_reset and post_reset the driver no + * With the implementation of pre_reset and post_reset the driver no * longer unbinds. This allows the use of synchronous reset. */ - if (usb_lock_device_for_reset(sdev->udev, sdev->interface)<0) - { + if (usb_lock_device_for_reset(sdev->udev, sdev->interface) < 0) { dev_err(&urb->dev->dev, "could not obtain lock to reset device\n"); return 0; } diff --git a/drivers/staging/usbip/usbip_protocol.txt b/drivers/staging/usbip/usbip_protocol.txt new file mode 100644 index 0000000..84e353b --- /dev/null +++ b/drivers/staging/usbip/usbip_protocol.txt @@ -0,0 +1,358 @@ +PRELIMINARY DRAFT, MAY CONTAIN MISTAKES! +28 Jun 2011 + +The USB/IP protocol follows a server/client architecture. The server exports the +USB devices and the clients imports them. The device driver for the exported +USB device runs on the client machine. + +The client may ask for the list of the exported USB devices. To get the list the +client opens a TCP/IP connection towards the server, and sends an OP_REQ_DEVLIST +packet on top of the TCP/IP connection (so the actual OP_REQ_DEVLIST may be sent +in one or more pieces at the low level transport layer). The server sends back +the OP_REP_DEVLIST packet which lists the exported USB devices. Finally the +TCP/IP connection is closed. + + virtual host controller usb host + "client" "server" + (imports USB devices) (exports USB devices) + | | + | OP_REQ_DEVLIST | + | ----------------------------------------------> | + | | + | OP_REP_DEVLIST | + | <---------------------------------------------- | + | | + +Once the client knows the list of exported USB devices it may decide to use one +of them. First the client opens a TCP/IP connection towards the server and +sends an OP_REQ_IMPORT packet. The server replies with OP_REP_IMPORT. If the +import was successful the TCP/IP connection remains open and will be used +to trasfer the URB traffic between the client and the server. The client may +send two types of packets: the USBIP_CMD_SUBMIT to submit an URB, and +USBIP_CMD_UNLINK to unlink a previously submitted URB. The answers of the +server may be USBIP_RET_SUBMIT and USBIP_RET_UNLINK respectively. + + virtual host controller usb host + "client" "server" + (imports USB devices) (exports USB devices) + | | + | OP_REQ_IMPORT | + | ----------------------------------------------> | + | | + | OP_REP_IMPORT | + | <---------------------------------------------- | + | | + | | + | USBIP_CMD_SUBMIT(seqnum = n) | + | ----------------------------------------------> | + | | + | USBIP_RET_SUBMIT(seqnum = n) | + | <---------------------------------------------- | + | . | + | : | + | | + | USBIP_CMD_SUBMIT(seqnum = m) | + | ----------------------------------------------> | + | | + | USBIP_CMD_SUBMIT(seqnum = m+1) | + | ----------------------------------------------> | + | | + | USBIP_CMD_SUBMIT(seqnum = m+2) | + | ----------------------------------------------> | + | | + | USBIP_RET_SUBMIT(seqnum = m) | + | <---------------------------------------------- | + | | + | USBIP_CMD_SUBMIT(seqnum = m+3) | + | ----------------------------------------------> | + | | + | USBIP_RET_SUBMIT(seqnum = m+1) | + | <---------------------------------------------- | + | | + | USBIP_CMD_SUBMIT(seqnum = m+4) | + | ----------------------------------------------> | + | | + | USBIP_RET_SUBMIT(seqnum = m+2) | + | <---------------------------------------------- | + | . | + | : | + | | + | USBIP_CMD_UNLINK | + | ----------------------------------------------> | + | | + | USBIP_RET_UNLINK | + | <---------------------------------------------- | + | | + +The fields are in network (big endian) byte order meaning that the most significant +byte (MSB) is stored at the lowest address. + + +OP_REQ_DEVLIST: Retrieve the list of exported USB devices. + + Offset | Length | Value | Description +-----------+--------+------------+--------------------------------------------------- + 0 | 2 | 0x0100 | Binary-coded decimal USBIP version number: v1.0.0 +-----------+--------+------------+--------------------------------------------------- + 2 | 2 | 0x8005 | Command code: Retrieve the list of exported USB + | | | devices. +-----------+--------+------------+--------------------------------------------------- + 4 | 4 | 0x00000000 | Status: unused, shall be set to 0 + +OP_REP_DEVLIST: Reply with the list of exported USB devices. + + Offset | Length | Value | Description +-----------+--------+------------+--------------------------------------------------- + 0 | 2 | 0x0100 | Binary-coded decimal USBIP version number: v1.0.0. +-----------+--------+------------+--------------------------------------------------- + 2 | 2 | 0x0005 | Reply code: The list of exported USB devices. +-----------+--------+------------+--------------------------------------------------- + 4 | 4 | 0x00000000 | Status: 0 for OK +-----------+--------+------------+--------------------------------------------------- + 8 | 4 | n | Number of exported devices: 0 means no exported + | | | devices. +-----------+--------+------------+--------------------------------------------------- + 0x0C | | | From now on the exported n devices are described, + | | | if any. If no devices are exported the message + | | | ends with the previous "number of exported + | | | devices" field. +-----------+--------+------------+--------------------------------------------------- + | 256 | | path: Path of the device on the host exporting the + | | | USB device, string closed with zero byte, e.g. + | | | "/sys/devices/pci0000:00/0000:00:1d.1/usb3/3-2" + | | | The unused bytes shall be filled with zero + | | | bytes. +-----------+--------+------------+--------------------------------------------------- + 0x10C | 32 | | busid: Bus ID of the exported device, string + | | | closed with zero byte, e.g. "3-2". The unused + | | | bytes shall be filled with zero bytes. +-----------+--------+------------+--------------------------------------------------- + 0x12C | 4 | | busnum +-----------+--------+------------+--------------------------------------------------- + 0x130 | 4 | | devnum +-----------+--------+------------+--------------------------------------------------- + 0x134 | 4 | | speed +-----------+--------+------------+--------------------------------------------------- + 0x138 | 2 | | idVendor +-----------+--------+------------+--------------------------------------------------- + 0x13A | 2 | | idProduct +-----------+--------+------------+--------------------------------------------------- + 0x13C | 2 | | bcdDevice +-----------+--------+------------+--------------------------------------------------- + 0x13E | 1 | | bDeviceClass +-----------+--------+------------+--------------------------------------------------- + 0x13F | 1 | | bDeviceSubClass +-----------+--------+------------+--------------------------------------------------- + 0x140 | 1 | | bDeviceProtocol +-----------+--------+------------+--------------------------------------------------- + 0x141 | 1 | | bConfigurationValue +-----------+--------+------------+--------------------------------------------------- + 0x142 | 1 | | bNumConfigurations +-----------+--------+------------+--------------------------------------------------- + 0x143 | 1 | | bNumInterfaces +-----------+--------+------------+--------------------------------------------------- + 0x144 | | m_0 | From now on each interface is described, all + | | | together bNumInterfaces times, with the + | | | the following 4 fields: +-----------+--------+------------+--------------------------------------------------- + | 1 | | bInterfaceClass +-----------+--------+------------+--------------------------------------------------- + 0x145 | 1 | | bInterfaceSubClass +-----------+--------+------------+--------------------------------------------------- + 0x146 | 1 | | bInterfaceProtocol +-----------+--------+------------+--------------------------------------------------- + 0x147 | 1 | | padding byte for alignment, shall be set to zero +-----------+--------+------------+--------------------------------------------------- + 0xC + | | | The second exported USB device starts at i=1 + i*0x138 + | | | with the busid field. + m_(i-1)*4 | | | + +OP_REQ_IMPORT: Request to import (attach) a remote USB device. + + Offset | Length | Value | Description +-----------+--------+------------+--------------------------------------------------- + 0 | 2 | 0x0100 | Binary-coded decimal USBIP version number: v1.0.0 +-----------+--------+------------+--------------------------------------------------- + 2 | 2 | 0x8003 | Command code: import a remote USB device. +-----------+--------+------------+--------------------------------------------------- + 4 | 4 | 0x00000000 | Status: unused, shall be set to 0 +-----------+--------+------------+--------------------------------------------------- + 8 | 32 | | busid: the busid of the exported device on the + | | | remote host. The possible values are taken + | | | from the message field OP_REP_DEVLIST.busid. + | | | A string closed with zero, the unused bytes + | | | shall be filled with zeros. +-----------+--------+------------+--------------------------------------------------- + +OP_REP_IMPORT: Reply to import (attach) a remote USB device. + + Offset | Length | Value | Description +-----------+--------+------------+--------------------------------------------------- + 0 | 2 | 0x0100 | Binary-coded decimal USBIP version number: v1.0.0 +-----------+--------+------------+--------------------------------------------------- + 2 | 2 | 0x0003 | Reply code: Reply to import. +-----------+--------+------------+--------------------------------------------------- + 4 | 4 | 0x00000000 | Status: 0 for OK + | | | 1 for error +-----------+--------+------------+--------------------------------------------------- + 8 | | | From now on comes the details of the imported + | | | device, if the previous status field was OK (0), + | | | otherwise the reply ends with the status field. +-----------+--------+------------+--------------------------------------------------- + | 256 | | path: Path of the device on the host exporting the + | | | USB device, string closed with zero byte, e.g. + | | | "/sys/devices/pci0000:00/0000:00:1d.1/usb3/3-2" + | | | The unused bytes shall be filled with zero + | | | bytes. +-----------+--------+------------+--------------------------------------------------- + 0x108 | 32 | | busid: Bus ID of the exported device, string + | | | closed with zero byte, e.g. "3-2". The unused + | | | bytes shall be filled with zero bytes. +-----------+--------+------------+--------------------------------------------------- + 0x128 | 4 | | busnum +-----------+--------+------------+--------------------------------------------------- + 0x12C | 4 | | devnum +-----------+--------+------------+--------------------------------------------------- + 0x130 | 4 | | speed +-----------+--------+------------+--------------------------------------------------- + 0x134 | 2 | | idVendor +-----------+--------+------------+--------------------------------------------------- + 0x136 | 2 | | idProduct +-----------+--------+------------+--------------------------------------------------- + 0x138 | 2 | | bcdDevice +-----------+--------+------------+--------------------------------------------------- + 0x139 | 1 | | bDeviceClass +-----------+--------+------------+--------------------------------------------------- + 0x13A | 1 | | bDeviceSubClass +-----------+--------+------------+--------------------------------------------------- + 0x13B | 1 | | bDeviceProtocol +-----------+--------+------------+--------------------------------------------------- + 0x13C | 1 | | bConfigurationValue +-----------+--------+------------+--------------------------------------------------- + 0x13D | 1 | | bNumConfigurations +-----------+--------+------------+--------------------------------------------------- + 0x13E | 1 | | bNumInterfaces + +USBIP_CMD_SUBMIT: Submit an URB + + Offset | Length | Value | Description +-----------+--------+------------+--------------------------------------------------- + 0 | 4 | 0x00000001 | command: Submit an URB +-----------+--------+------------+--------------------------------------------------- + 4 | 4 | | seqnum: the sequence number of the URB to submit +-----------+--------+------------+--------------------------------------------------- + 8 | 4 | | devid +-----------+--------+------------+--------------------------------------------------- + 0xC | 4 | | direction: 0: USBIP_DIR_IN + | | | 1: USBIP_DIR_OUT +-----------+--------+------------+--------------------------------------------------- + 0x10 | 4 | | ep: endpoint number, possible values are: 0...15 +-----------+--------+------------+--------------------------------------------------- + 0x14 | 4 | | transfer_flags: possible values depend on the + | | | URB transfer type, see below +-----------+--------+------------+--------------------------------------------------- + 0x18 | 4 | | transfer_buffer_length +-----------+--------+------------+--------------------------------------------------- + 0x1C | 4 | | start_frame: specify the selected frame to + | | | transmit an ISO frame, ignored if URB_ISO_ASAP + | | | is specified at transfer_flags +-----------+--------+------------+--------------------------------------------------- + 0x20 | 4 | | number_of_packets: number of ISO packets +-----------+--------+------------+--------------------------------------------------- + 0x24 | 4 | | interval: maximum time for the request on the + | | | server-side host controller +-----------+--------+------------+--------------------------------------------------- + 0x28 | 8 | | setup: data bytes for USB setup, filled with + | | | zeros if not used +-----------+--------+------------+--------------------------------------------------- + 0x30 | | | URB data. For ISO transfers the padding between + | | | each ISO packets is not transmitted. + + + Allowed transfer_flags | value | control | interrupt | bulk | isochronous + -------------------------+------------+---------+-----------+----------+------------- + URB_SHORT_NOT_OK | 0x00000001 | only in | only in | only in | no + URB_ISO_ASAP | 0x00000002 | no | no | no | yes + URB_NO_TRANSFER_DMA_MAP | 0x00000004 | yes | yes | yes | yes + URB_NO_FSBR | 0x00000020 | yes | no | no | no + URB_ZERO_PACKET | 0x00000040 | no | no | only out | no + URB_NO_INTERRUPT | 0x00000080 | yes | yes | yes | yes + URB_FREE_BUFFER | 0x00000100 | yes | yes | yes | yes + URB_DIR_MASK | 0x00000200 | yes | yes | yes | yes + + +USBIP_RET_SUBMIT: Reply for submitting an URB + + Offset | Length | Value | Description +-----------+--------+------------+--------------------------------------------------- + 0 | 4 | 0x00000002 | command +-----------+--------+------------+--------------------------------------------------- + 4 | 4 | | seqnum: URB sequence number +-----------+--------+------------+--------------------------------------------------- + 8 | 4 | | devid +-----------+--------+------------+--------------------------------------------------- + 0xC | 4 | | direction: 0: USBIP_DIR_IN + | | | 1: USBIP_DIR_OUT +-----------+--------+------------+--------------------------------------------------- + 0x10 | 4 | | ep: endpoint number +-----------+--------+------------+--------------------------------------------------- + 0x14 | 4 | | status: zero for successful URB transaction, + | | | otherwise some kind of error happened. +-----------+--------+------------+--------------------------------------------------- + 0x18 | 4 | n | actual_length: number of URB data bytes +-----------+--------+------------+--------------------------------------------------- + 0x1C | 4 | | start_frame: for an ISO frame the actually + | | | selected frame for transmit. +-----------+--------+------------+--------------------------------------------------- + 0x20 | 4 | | number_of_packets +-----------+--------+------------+--------------------------------------------------- + 0x24 | 4 | | error_count +-----------+--------+------------+--------------------------------------------------- + 0x28 | 8 | | setup: data bytes for USB setup, filled with + | | | zeros if not used +-----------+--------+------------+--------------------------------------------------- + 0x30 | n | | URB data bytes. For ISO transfers the padding + | | | between each ISO packets is not transmitted. + +USBIP_CMD_UNLINK: Unlink an URB + + Offset | Length | Value | Description +-----------+--------+------------+--------------------------------------------------- + 0 | 4 | 0x00000003 | command: URB unlink command +-----------+--------+------------+--------------------------------------------------- + 4 | 4 | | seqnum: URB sequence number to unlink: FIXME: is this so? +-----------+--------+------------+--------------------------------------------------- + 8 | 4 | | devid +-----------+--------+------------+--------------------------------------------------- + 0xC | 4 | | direction: 0: USBIP_DIR_IN + | | | 1: USBIP_DIR_OUT +-----------+--------+------------+--------------------------------------------------- + 0x10 | 4 | | ep: endpoint number: zero +-----------+--------+------------+--------------------------------------------------- + 0x14 | 4 | | seqnum: the URB sequence number given previously + | | | at USBIP_CMD_SUBMIT.seqnum field +-----------+--------+------------+--------------------------------------------------- + 0x30 | n | | URB data bytes. For ISO transfers the padding + | | | between each ISO packets is not transmitted. + +USBIP_RET_UNLINK: Reply for URB unlink + + Offset | Length | Value | Description +-----------+--------+------------+--------------------------------------------------- + 0 | 4 | 0x00000004 | command: reply for the URB unlink command +-----------+--------+------------+--------------------------------------------------- + 4 | 4 | | seqnum: the unlinked URB sequence number +-----------+--------+------------+--------------------------------------------------- + 8 | 4 | | devid +-----------+--------+------------+--------------------------------------------------- + 0xC | 4 | | direction: 0: USBIP_DIR_IN + | | | 1: USBIP_DIR_OUT +-----------+--------+------------+--------------------------------------------------- + 0x10 | 4 | | ep: endpoint number +-----------+--------+------------+--------------------------------------------------- + 0x14 | 4 | | status: This is the value contained in the + | | | urb->status in the URB completition handler. + | | | FIXME: a better explanation needed. +-----------+--------+------------+--------------------------------------------------- + 0x30 | n | | URB data bytes. For ISO transfers the padding + | | | between each ISO packets is not transmitted. diff --git a/drivers/staging/usbip/userspace/libsrc/vhci_driver.c b/drivers/staging/usbip/userspace/libsrc/vhci_driver.c index abbc285..2697877 100644 --- a/drivers/staging/usbip/userspace/libsrc/vhci_driver.c +++ b/drivers/staging/usbip/userspace/libsrc/vhci_driver.c @@ -133,7 +133,7 @@ static int check_usbip_device(struct sysfs_class_device *cdev) strlen(vhci_driver->hc_device->path))) { /* found usbip device */ usbip_cdev = calloc(1, sizeof(*usbip_cdev)); - if (!cdev) { + if (!usbip_cdev) { dbg("calloc failed"); return -1; } diff --git a/drivers/staging/usbip/userspace/src/usbip_attach.c b/drivers/staging/usbip/userspace/src/usbip_attach.c index b7885a2..bdf61c0 100644 --- a/drivers/staging/usbip/userspace/src/usbip_attach.c +++ b/drivers/staging/usbip/userspace/src/usbip_attach.c @@ -51,7 +51,9 @@ static int record_connection(char *host, char *port, char *busid, int rhport) char buff[MAX_BUFF+1]; int ret; - mkdir(VHCI_STATE_PATH, 0700); + ret = mkdir(VHCI_STATE_PATH, 0700); + if (ret < 0) + return -1; snprintf(path, PATH_MAX, VHCI_STATE_PATH"/port%d", rhport); diff --git a/drivers/staging/usbip/userspace/src/utils.h b/drivers/staging/usbip/userspace/src/utils.h index fdcb14d..5916fd3 100644 --- a/drivers/staging/usbip/userspace/src/utils.h +++ b/drivers/staging/usbip/userspace/src/utils.h @@ -22,3 +22,4 @@ int modify_match_busid(char *busid, int add); #endif /* __UTILS_H */ + diff --git a/drivers/staging/usbip/vhci.h b/drivers/staging/usbip/vhci.h index 71a586e..88b3298 100644 --- a/drivers/staging/usbip/vhci.h +++ b/drivers/staging/usbip/vhci.h @@ -8,6 +8,9 @@ * */ +#ifndef __USBIP_VHCI_H +#define __USBIP_VHCI_H + #include <linux/device.h> #include <linux/list.h> #include <linux/spinlock.h> @@ -129,3 +132,5 @@ static inline struct device *vhci_dev(struct vhci_hcd *vhci) { return vhci_to_hcd(vhci)->self.controller; } + +#endif /* __USBIP_VHCI_H */ diff --git a/drivers/staging/vme/bridges/vme_ca91cx42.c b/drivers/staging/vme/bridges/vme_ca91cx42.c index 5122c13..0e4feac 100644 --- a/drivers/staging/vme/bridges/vme_ca91cx42.c +++ b/drivers/staging/vme/bridges/vme_ca91cx42.c @@ -1500,6 +1500,28 @@ static int ca91cx42_slot_get(struct vme_bridge *ca91cx42_bridge) } +void *ca91cx42_alloc_consistent(struct device *parent, size_t size, + dma_addr_t *dma) +{ + struct pci_dev *pdev; + + /* Find pci_dev container of dev */ + pdev = container_of(parent, struct pci_dev, dev); + + return pci_alloc_consistent(pdev, size, dma); +} + +void ca91cx42_free_consistent(struct device *parent, size_t size, void *vaddr, + dma_addr_t dma) +{ + struct pci_dev *pdev; + + /* Find pci_dev container of dev */ + pdev = container_of(parent, struct pci_dev, dev); + + pci_free_consistent(pdev, size, vaddr, dma); +} + static int __init ca91cx42_init(void) { return pci_register_driver(&ca91cx42_driver); @@ -1769,6 +1791,8 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id) ca91cx42_bridge->lm_attach = ca91cx42_lm_attach; ca91cx42_bridge->lm_detach = ca91cx42_lm_detach; ca91cx42_bridge->slot_get = ca91cx42_slot_get; + ca91cx42_bridge->alloc_consistent = ca91cx42_alloc_consistent; + ca91cx42_bridge->free_consistent = ca91cx42_free_consistent; data = ioread32(ca91cx42_device->base + MISC_CTL); dev_info(&pdev->dev, "Board is%s the VME system controller\n", diff --git a/drivers/staging/vme/bridges/vme_tsi148.c b/drivers/staging/vme/bridges/vme_tsi148.c index 9c53951..6c1167c 100644 --- a/drivers/staging/vme/bridges/vme_tsi148.c +++ b/drivers/staging/vme/bridges/vme_tsi148.c @@ -2114,6 +2114,28 @@ static int tsi148_slot_get(struct vme_bridge *tsi148_bridge) return (int)slot; } +void *tsi148_alloc_consistent(struct device *parent, size_t size, + dma_addr_t *dma) +{ + struct pci_dev *pdev; + + /* Find pci_dev container of dev */ + pdev = container_of(parent, struct pci_dev, dev); + + return pci_alloc_consistent(pdev, size, dma); +} + +void tsi148_free_consistent(struct device *parent, size_t size, void *vaddr, + dma_addr_t dma) +{ + struct pci_dev *pdev; + + /* Find pci_dev container of dev */ + pdev = container_of(parent, struct pci_dev, dev); + + pci_free_consistent(pdev, size, vaddr, dma); +} + static int __init tsi148_init(void) { return pci_register_driver(&tsi148_driver); @@ -2443,6 +2465,8 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) tsi148_bridge->lm_attach = tsi148_lm_attach; tsi148_bridge->lm_detach = tsi148_lm_detach; tsi148_bridge->slot_get = tsi148_slot_get; + tsi148_bridge->alloc_consistent = tsi148_alloc_consistent; + tsi148_bridge->free_consistent = tsi148_free_consistent; data = ioread32be(tsi148_device->base + TSI148_LCSR_VSTAT); dev_info(&pdev->dev, "Board is%s the VME system controller\n", diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c index 91d2cc7..3cbeb2a 100644 --- a/drivers/staging/vme/devices/vme_user.c +++ b/drivers/staging/vme/devices/vme_user.c @@ -651,7 +651,7 @@ static int __init vme_user_init(void) /* Dynamically create the bind table based on module parameters */ - ids = kmalloc(sizeof(struct vme_device_id) * (bus_num + 1), GFP_KERNEL); + ids = kzalloc(sizeof(struct vme_device_id) * (bus_num + 1), GFP_KERNEL); if (ids == NULL) { printk(KERN_ERR "%s: Unable to allocate ID table\n", driver_name); @@ -659,8 +659,6 @@ static int __init vme_user_init(void) goto err_id; } - memset(ids, 0, (sizeof(struct vme_device_id) * (bus_num + 1))); - for (i = 0; i < bus_num; i++) { ids[i].bus = bus[i]; /* diff --git a/drivers/staging/vme/vme.c b/drivers/staging/vme/vme.c index c078ce3..b2968f8 100644 --- a/drivers/staging/vme/vme.c +++ b/drivers/staging/vme/vme.c @@ -34,9 +34,10 @@ #include "vme.h" #include "vme_bridge.h" -/* Bitmask and mutex to keep track of bridge numbers */ +/* Bitmask and list of registered buses both protected by common mutex */ static unsigned int vme_bus_numbers; -static DEFINE_MUTEX(vme_bus_num_mtx); +static LIST_HEAD(vme_bus_list); +static DEFINE_MUTEX(vme_buses_lock); static void __exit vme_exit(void); static int __init vme_init(void); @@ -83,15 +84,11 @@ static struct vme_bridge *find_bridge(struct vme_resource *resource) /* * Allocate a contiguous block of memory for use by the driver. This is used to * create the buffers for the slave windows. - * - * XXX VME bridges could be available on buses other than PCI. At the momment - * this framework only supports PCI devices. */ void *vme_alloc_consistent(struct vme_resource *resource, size_t size, dma_addr_t *dma) { struct vme_bridge *bridge; - struct pci_dev *pdev; if (resource == NULL) { printk(KERN_ERR "No resource\n"); @@ -104,28 +101,29 @@ void *vme_alloc_consistent(struct vme_resource *resource, size_t size, return NULL; } - /* Find pci_dev container of dev */ if (bridge->parent == NULL) { - printk(KERN_ERR "Dev entry NULL\n"); + printk(KERN_ERR "Dev entry NULL for" + " bridge %s\n", bridge->name); + return NULL; + } + + if (bridge->alloc_consistent == NULL) { + printk(KERN_ERR "alloc_consistent not supported by" + " bridge %s\n", bridge->name); return NULL; } - pdev = container_of(bridge->parent, struct pci_dev, dev); - return pci_alloc_consistent(pdev, size, dma); + return bridge->alloc_consistent(bridge->parent, size, dma); } EXPORT_SYMBOL(vme_alloc_consistent); /* * Free previously allocated contiguous block of memory. - * - * XXX VME bridges could be available on buses other than PCI. At the momment - * this framework only supports PCI devices. */ void vme_free_consistent(struct vme_resource *resource, size_t size, void *vaddr, dma_addr_t dma) { struct vme_bridge *bridge; - struct pci_dev *pdev; if (resource == NULL) { printk(KERN_ERR "No resource\n"); @@ -138,10 +136,19 @@ void vme_free_consistent(struct vme_resource *resource, size_t size, return; } - /* Find pci_dev container of dev */ - pdev = container_of(bridge->parent, struct pci_dev, dev); + if (bridge->parent == NULL) { + printk(KERN_ERR "Dev entry NULL for" + " bridge %s\n", bridge->name); + return; + } + + if (bridge->free_consistent == NULL) { + printk(KERN_ERR "free_consistent not supported by" + " bridge %s\n", bridge->name); + return; + } - pci_free_consistent(pdev, size, vaddr, dma); + bridge->free_consistent(bridge->parent, size, vaddr, dma); } EXPORT_SYMBOL(vme_free_consistent); @@ -1303,27 +1310,32 @@ EXPORT_SYMBOL(vme_slot_get); /* - Bridge Registration --------------------------------------------------- */ -static int vme_alloc_bus_num(void) +static int vme_add_bus(struct vme_bridge *bridge) { int i; + int ret = -1; - mutex_lock(&vme_bus_num_mtx); + mutex_lock(&vme_buses_lock); for (i = 0; i < sizeof(vme_bus_numbers) * 8; i++) { - if (((vme_bus_numbers >> i) & 0x1) == 0) { - vme_bus_numbers |= (0x1 << i); + if ((vme_bus_numbers & (1 << i)) == 0) { + vme_bus_numbers |= (1 << i); + bridge->num = i; + list_add_tail(&bridge->bus_list, &vme_bus_list); + ret = 0; break; } } - mutex_unlock(&vme_bus_num_mtx); + mutex_unlock(&vme_buses_lock); - return i; + return ret; } -static void vme_free_bus_num(int bus) +static void vme_remove_bus(struct vme_bridge *bridge) { - mutex_lock(&vme_bus_num_mtx); - vme_bus_numbers &= ~(0x1 << bus); - mutex_unlock(&vme_bus_num_mtx); + mutex_lock(&vme_buses_lock); + vme_bus_numbers &= ~(1 << bridge->num); + list_del(&bridge->bus_list); + mutex_unlock(&vme_buses_lock); } int vme_register_bridge(struct vme_bridge *bridge) @@ -1332,7 +1344,9 @@ int vme_register_bridge(struct vme_bridge *bridge) int retval; int i; - bridge->num = vme_alloc_bus_num(); + retval = vme_add_bus(bridge); + if (retval) + return retval; /* This creates 32 vme "slot" devices. This equates to a slot for each * ID available in a system conforming to the ANSI/VITA 1-1994 @@ -1364,7 +1378,7 @@ err_reg: dev = &bridge->dev[i]; device_unregister(dev); } - vme_free_bus_num(bridge->num); + vme_remove_bus(bridge); return retval; } EXPORT_SYMBOL(vme_register_bridge); @@ -1379,7 +1393,7 @@ void vme_unregister_bridge(struct vme_bridge *bridge) dev = &bridge->dev[i]; device_unregister(dev); } - vme_free_bus_num(bridge->num); + vme_remove_bus(bridge); } EXPORT_SYMBOL(vme_unregister_bridge); diff --git a/drivers/staging/vme/vme_bridge.h b/drivers/staging/vme/vme_bridge.h index 4c6ec31..8959670 100644 --- a/drivers/staging/vme/vme_bridge.h +++ b/drivers/staging/vme/vme_bridge.h @@ -98,8 +98,6 @@ struct vme_irq { /* This structure stores all the information about one bridge * The structure should be dynamically allocated by the driver and one instance * of the structure should be present for each VME chip present in the system. - * - * Currently we assume that all chips are PCI-based */ struct vme_bridge { char name[VMENAMSIZ]; @@ -112,8 +110,9 @@ struct vme_bridge { struct list_head vme_errors; /* List for errors generated on VME */ /* Bridge Info - XXX Move to private structure? */ - struct device *parent; /* Generic device struct (pdev->dev for PCI) */ + struct device *parent; /* Parent device (eg. pdev->dev for PCI) */ void *driver_priv; /* Private pointer for the bridge driver */ + struct list_head bus_list; /* list of VME buses */ struct device dev[VME_SLOTS_MAX]; /* Device registered with * device model on VME bus @@ -165,6 +164,12 @@ struct vme_bridge { /* CR/CSR space functions */ int (*slot_get) (struct vme_bridge *); + + /* Bridge parent interface */ + void *(*alloc_consistent)(struct device *dev, size_t size, + dma_addr_t *dma); + void (*free_consistent)(struct device *dev, size_t size, + void *vaddr, dma_addr_t dma); }; void vme_irq_handler(struct vme_bridge *, int, int); diff --git a/drivers/staging/vt6655/IEEE11h.c b/drivers/staging/vt6655/IEEE11h.c index e07ebd5..cf7364d 100644 --- a/drivers/staging/vt6655/IEEE11h.c +++ b/drivers/staging/vt6655/IEEE11h.c @@ -41,52 +41,52 @@ #include "channel.h" /*--------------------- Static Definitions -------------------------*/ -static int msglevel =MSG_LEVEL_INFO; +static int msglevel = MSG_LEVEL_INFO; #pragma pack(1) typedef struct _WLAN_FRAME_ACTION { - WLAN_80211HDR_A3 Header; - unsigned char byCategory; - unsigned char byAction; - unsigned char abyVars[1]; + WLAN_80211HDR_A3 Header; + unsigned char byCategory; + unsigned char byAction; + unsigned char abyVars[1]; } WLAN_FRAME_ACTION, *PWLAN_FRAME_ACTION; typedef struct _WLAN_FRAME_MSRREQ { - WLAN_80211HDR_A3 Header; - unsigned char byCategory; - unsigned char byAction; - unsigned char byDialogToken; - WLAN_IE_MEASURE_REQ sMSRReqEIDs[1]; + WLAN_80211HDR_A3 Header; + unsigned char byCategory; + unsigned char byAction; + unsigned char byDialogToken; + WLAN_IE_MEASURE_REQ sMSRReqEIDs[1]; } WLAN_FRAME_MSRREQ, *PWLAN_FRAME_MSRREQ; typedef struct _WLAN_FRAME_MSRREP { - WLAN_80211HDR_A3 Header; - unsigned char byCategory; - unsigned char byAction; - unsigned char byDialogToken; - WLAN_IE_MEASURE_REP sMSRRepEIDs[1]; + WLAN_80211HDR_A3 Header; + unsigned char byCategory; + unsigned char byAction; + unsigned char byDialogToken; + WLAN_IE_MEASURE_REP sMSRRepEIDs[1]; } WLAN_FRAME_MSRREP, *PWLAN_FRAME_MSRREP; typedef struct _WLAN_FRAME_TPCREQ { - WLAN_80211HDR_A3 Header; - unsigned char byCategory; - unsigned char byAction; - unsigned char byDialogToken; - WLAN_IE_TPC_REQ sTPCReqEIDs; + WLAN_80211HDR_A3 Header; + unsigned char byCategory; + unsigned char byAction; + unsigned char byDialogToken; + WLAN_IE_TPC_REQ sTPCReqEIDs; } WLAN_FRAME_TPCREQ, *PWLAN_FRAME_TPCREQ; typedef struct _WLAN_FRAME_TPCREP { - WLAN_80211HDR_A3 Header; - unsigned char byCategory; - unsigned char byAction; - unsigned char byDialogToken; - WLAN_IE_TPC_REP sTPCRepEIDs; + WLAN_80211HDR_A3 Header; + unsigned char byCategory; + unsigned char byAction; + unsigned char byDialogToken; + WLAN_IE_TPC_REP sTPCRepEIDs; } WLAN_FRAME_TPCREP, *PWLAN_FRAME_TPCREP; #pragma pack() -// action field reference ieee 802.11h Table 20e +/* action field reference ieee 802.11h Table 20e */ #define ACTION_MSRREQ 0 #define ACTION_MSRREP 1 #define ACTION_TPCREQ 2 @@ -101,84 +101,100 @@ typedef struct _WLAN_FRAME_TPCREP { static bool s_bRxMSRReq(PSMgmtObject pMgmt, PWLAN_FRAME_MSRREQ pMSRReq, unsigned int uLength) { - size_t uNumOfEIDs = 0; - bool bResult = true; - - if (uLength <= WLAN_A3FR_MAXLEN) { - memcpy(pMgmt->abyCurrentMSRReq, pMSRReq, uLength); - } - uNumOfEIDs = ((uLength - offsetof(WLAN_FRAME_MSRREQ, sMSRReqEIDs))/ (sizeof(WLAN_IE_MEASURE_REQ))); - pMgmt->pCurrMeasureEIDRep = &(((PWLAN_FRAME_MSRREP) (pMgmt->abyCurrentMSRRep))->sMSRRepEIDs[0]); - pMgmt->uLengthOfRepEIDs = 0; - bResult = CARDbStartMeasure(pMgmt->pAdapter, - ((PWLAN_FRAME_MSRREQ) (pMgmt->abyCurrentMSRReq))->sMSRReqEIDs, - uNumOfEIDs - ); - return (bResult); + size_t uNumOfEIDs = 0; + bool bResult = true; + + if (uLength <= WLAN_A3FR_MAXLEN) + memcpy(pMgmt->abyCurrentMSRReq, pMSRReq, uLength); + uNumOfEIDs = ((uLength - offsetof(WLAN_FRAME_MSRREQ, + sMSRReqEIDs))/ + (sizeof(WLAN_IE_MEASURE_REQ))); + pMgmt->pCurrMeasureEIDRep = &(((PWLAN_FRAME_MSRREP) + (pMgmt->abyCurrentMSRRep))->sMSRRepEIDs[0]); + pMgmt->uLengthOfRepEIDs = 0; + bResult = CARDbStartMeasure(pMgmt->pAdapter, + ((PWLAN_FRAME_MSRREQ) + (pMgmt->abyCurrentMSRReq))->sMSRReqEIDs, + uNumOfEIDs + ); + return bResult; } -static bool s_bRxTPCReq(PSMgmtObject pMgmt, PWLAN_FRAME_TPCREQ pTPCReq, unsigned char byRate, unsigned char byRSSI) +static bool s_bRxTPCReq(PSMgmtObject pMgmt, + PWLAN_FRAME_TPCREQ pTPCReq, + unsigned char byRate, + unsigned char byRSSI) { - PWLAN_FRAME_TPCREP pFrame; - PSTxMgmtPacket pTxPacket = NULL; - - - pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - - pFrame = (PWLAN_FRAME_TPCREP)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - - pFrame->Header.wFrameCtl = ( WLAN_SET_FC_FTYPE(WLAN_FTYPE_MGMT) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ACTION) - ); - - memcpy( pFrame->Header.abyAddr1, pTPCReq->Header.abyAddr2, WLAN_ADDR_LEN); - memcpy( pFrame->Header.abyAddr2, CARDpGetCurrentAddress(pMgmt->pAdapter), WLAN_ADDR_LEN); - memcpy( pFrame->Header.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - - pFrame->byCategory = 0; - pFrame->byAction = 3; - pFrame->byDialogToken = ((PWLAN_FRAME_MSRREQ) (pMgmt->abyCurrentMSRReq))->byDialogToken; - - pFrame->sTPCRepEIDs.byElementID = WLAN_EID_TPC_REP; - pFrame->sTPCRepEIDs.len = 2; - pFrame->sTPCRepEIDs.byTxPower = CARDbyGetTransmitPower(pMgmt->pAdapter); - switch (byRate) { - case RATE_54M: - pFrame->sTPCRepEIDs.byLinkMargin = 65 - byRSSI; - break; - case RATE_48M: - pFrame->sTPCRepEIDs.byLinkMargin = 66 - byRSSI; - break; - case RATE_36M: - pFrame->sTPCRepEIDs.byLinkMargin = 70 - byRSSI; - break; - case RATE_24M: - pFrame->sTPCRepEIDs.byLinkMargin = 74 - byRSSI; - break; - case RATE_18M: - pFrame->sTPCRepEIDs.byLinkMargin = 77 - byRSSI; - break; - case RATE_12M: - pFrame->sTPCRepEIDs.byLinkMargin = 79 - byRSSI; - break; - case RATE_9M: - pFrame->sTPCRepEIDs.byLinkMargin = 81 - byRSSI; - break; - case RATE_6M: - default: - pFrame->sTPCRepEIDs.byLinkMargin = 82 - byRSSI; - break; - } - - pTxPacket->cbMPDULen = sizeof(WLAN_FRAME_TPCREP); - pTxPacket->cbPayloadLen = sizeof(WLAN_FRAME_TPCREP) - WLAN_HDR_ADDR3_LEN; - if (csMgmt_xmit(pMgmt->pAdapter, pTxPacket) != CMD_STATUS_PENDING) - return (false); - return (true); -// return (CARDbSendPacket(pMgmt->pAdapter, pFrame, PKT_TYPE_802_11_MNG, sizeof(WLAN_FRAME_TPCREP))); + PWLAN_FRAME_TPCREP pFrame; + PSTxMgmtPacket pTxPacket = NULL; + + pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool; + memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN); + pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + +sizeof(STxMgmtPacket)); + + pFrame = (PWLAN_FRAME_TPCREP)((unsigned char *)pTxPacket + +sizeof(STxMgmtPacket)); + + pFrame->Header.wFrameCtl = (WLAN_SET_FC_FTYPE(WLAN_FTYPE_MGMT) | + WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ACTION) + ); + + memcpy(pFrame->Header.abyAddr1, + pTPCReq->Header.abyAddr2, + WLAN_ADDR_LEN); + memcpy(pFrame->Header.abyAddr2, + CARDpGetCurrentAddress(pMgmt->pAdapter), + WLAN_ADDR_LEN); + memcpy(pFrame->Header.abyAddr3, + pMgmt->abyCurrBSSID, + WLAN_BSSID_LEN); + + pFrame->byCategory = 0; + pFrame->byAction = 3; + pFrame->byDialogToken = ((PWLAN_FRAME_MSRREQ) +(pMgmt->abyCurrentMSRReq))->byDialogToken; + + pFrame->sTPCRepEIDs.byElementID = WLAN_EID_TPC_REP; + pFrame->sTPCRepEIDs.len = 2; + pFrame->sTPCRepEIDs.byTxPower = CARDbyGetTransmitPower(pMgmt->pAdapter); + switch (byRate) { + case RATE_54M: + pFrame->sTPCRepEIDs.byLinkMargin = 65 - byRSSI; + break; + case RATE_48M: + pFrame->sTPCRepEIDs.byLinkMargin = 66 - byRSSI; + break; + case RATE_36M: + pFrame->sTPCRepEIDs.byLinkMargin = 70 - byRSSI; + break; + case RATE_24M: + pFrame->sTPCRepEIDs.byLinkMargin = 74 - byRSSI; + break; + case RATE_18M: + pFrame->sTPCRepEIDs.byLinkMargin = 77 - byRSSI; + break; + case RATE_12M: + pFrame->sTPCRepEIDs.byLinkMargin = 79 - byRSSI; + break; + case RATE_9M: + pFrame->sTPCRepEIDs.byLinkMargin = 81 - byRSSI; + break; + case RATE_6M: + default: + pFrame->sTPCRepEIDs.byLinkMargin = 82 - byRSSI; + break; +} + + pTxPacket->cbMPDULen = sizeof(WLAN_FRAME_TPCREP); + pTxPacket->cbPayloadLen = sizeof(WLAN_FRAME_TPCREP) - +WLAN_HDR_ADDR3_LEN; + if (csMgmt_xmit(pMgmt->pAdapter, pTxPacket) != CMD_STATUS_PENDING) + return false; + return true; +/* return (CARDbSendPacket(pMgmt->pAdapter, pFrame, PKT_TYPE_802_11_MNG, +sizeof(WLAN_FRAME_TPCREP))); */ } @@ -204,102 +220,110 @@ static bool s_bRxTPCReq(PSMgmtObject pMgmt, PWLAN_FRAME_TPCREQ pTPCReq, unsigned * -*/ bool -IEEE11hbMgrRxAction ( - void *pMgmtHandle, - void *pRxPacket - ) +IEEE11hbMgrRxAction(void *pMgmtHandle, void *pRxPacket) { - PSMgmtObject pMgmt = (PSMgmtObject) pMgmtHandle; - PWLAN_FRAME_ACTION pAction = NULL; - unsigned int uLength = 0; - PWLAN_IE_CH_SW pChannelSwitch = NULL; - - - // decode the frame - uLength = ((PSRxMgmtPacket)pRxPacket)->cbMPDULen; - if (uLength > WLAN_A3FR_MAXLEN) { - return (false); - } - - - pAction = (PWLAN_FRAME_ACTION) (((PSRxMgmtPacket)pRxPacket)->p80211Header); - - if (pAction->byCategory == 0) { - switch (pAction->byAction) { - case ACTION_MSRREQ: - return (s_bRxMSRReq(pMgmt, (PWLAN_FRAME_MSRREQ) pAction, uLength)); - break; - case ACTION_MSRREP: - break; - case ACTION_TPCREQ: - return (s_bRxTPCReq(pMgmt, - (PWLAN_FRAME_TPCREQ) pAction, - ((PSRxMgmtPacket)pRxPacket)->byRxRate, - (unsigned char) ((PSRxMgmtPacket)pRxPacket)->uRSSI)); - break; - case ACTION_TPCREP: - break; - case ACTION_CHSW: - pChannelSwitch = (PWLAN_IE_CH_SW) (pAction->abyVars); - if ((pChannelSwitch->byElementID == WLAN_EID_CH_SWITCH) && - (pChannelSwitch->len == 3)) { - // valid element id - CARDbChannelSwitch( pMgmt->pAdapter, - pChannelSwitch->byMode, - get_channel_mapping(pMgmt->pAdapter, pChannelSwitch->byChannel, pMgmt->eCurrentPHYMode), - pChannelSwitch->byCount - ); - } - break; - default: - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Unknown Action = %d\n", pAction->byAction); - break; - } - } else { - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Unknown Category = %d\n", pAction->byCategory); - pAction->byCategory |= 0x80; - - //return (CARDbSendPacket(pMgmt->pAdapter, pAction, PKT_TYPE_802_11_MNG, uLength)); - return (true); - } - return (true); + PSMgmtObject pMgmt = (PSMgmtObject) pMgmtHandle; + PWLAN_FRAME_ACTION pAction = NULL; + unsigned int uLength = 0; + PWLAN_IE_CH_SW pChannelSwitch = NULL; + + /* decode the frame */ + uLength = ((PSRxMgmtPacket)pRxPacket)->cbMPDULen; + if (uLength > WLAN_A3FR_MAXLEN) + return false; + + pAction = (PWLAN_FRAME_ACTION) +(((PSRxMgmtPacket)pRxPacket)->p80211Header); + + if (pAction->byCategory == 0) { + switch (pAction->byAction) { + case ACTION_MSRREQ: + return s_bRxMSRReq(pMgmt, + (PWLAN_FRAME_MSRREQ) + pAction, + uLength); + break; + case ACTION_MSRREP: + break; + case ACTION_TPCREQ: + return s_bRxTPCReq(pMgmt, + (PWLAN_FRAME_TPCREQ) pAction, + ((PSRxMgmtPacket)pRxPacket)->byRxRate, + (unsigned char) + ((PSRxMgmtPacket)pRxPacket)->uRSSI); + break; + case ACTION_TPCREP: + break; + case ACTION_CHSW: + pChannelSwitch = (PWLAN_IE_CH_SW) (pAction->abyVars); + if ((pChannelSwitch->byElementID == WLAN_EID_CH_SWITCH) + && (pChannelSwitch->len == 3)) { + /* valid element id */ + CARDbChannelSwitch(pMgmt->pAdapter, + pChannelSwitch->byMode, + get_channel_mapping(pMgmt->pAdapter, + pChannelSwitch->byChannel, + pMgmt->eCurrentPHYMode), + pChannelSwitch->byCount); + } + break; + default: + DBG_PRT(MSG_LEVEL_DEBUG, + KERN_INFO"Unknown Action = %d\n", + pAction->byAction); + break; + } + } else { + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Unknown Category = %d\n", +pAction->byCategory); + pAction->byCategory |= 0x80; + + /*return (CARDbSendPacket(pMgmt->pAdapter, pAction, PKT_TYPE_802_11_MNG, +uLength));*/ + return true; + } + return true; } -bool IEEE11hbMSRRepTx ( - void *pMgmtHandle - ) +bool IEEE11hbMSRRepTx(void *pMgmtHandle) { - PSMgmtObject pMgmt = (PSMgmtObject) pMgmtHandle; - PWLAN_FRAME_MSRREP pMSRRep = (PWLAN_FRAME_MSRREP) (pMgmt->abyCurrentMSRRep + sizeof(STxMgmtPacket)); - size_t uLength = 0; - PSTxMgmtPacket pTxPacket = NULL; - - pTxPacket = (PSTxMgmtPacket)pMgmt->abyCurrentMSRRep; - memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN); - pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket)); - - - pMSRRep->Header.wFrameCtl = ( WLAN_SET_FC_FTYPE(WLAN_FTYPE_MGMT) | - WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ACTION) - ); - - memcpy( pMSRRep->Header.abyAddr1, ((PWLAN_FRAME_MSRREQ) (pMgmt->abyCurrentMSRReq))->Header.abyAddr2, WLAN_ADDR_LEN); - memcpy( pMSRRep->Header.abyAddr2, CARDpGetCurrentAddress(pMgmt->pAdapter), WLAN_ADDR_LEN); - memcpy( pMSRRep->Header.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); - - pMSRRep->byCategory = 0; - pMSRRep->byAction = 1; - pMSRRep->byDialogToken = ((PWLAN_FRAME_MSRREQ) (pMgmt->abyCurrentMSRReq))->byDialogToken; - - uLength = pMgmt->uLengthOfRepEIDs + offsetof(WLAN_FRAME_MSRREP, sMSRRepEIDs); - - pTxPacket->cbMPDULen = uLength; - pTxPacket->cbPayloadLen = uLength - WLAN_HDR_ADDR3_LEN; - if (csMgmt_xmit(pMgmt->pAdapter, pTxPacket) != CMD_STATUS_PENDING) - return (false); - return (true); -// return (CARDbSendPacket(pMgmt->pAdapter, pMSRRep, PKT_TYPE_802_11_MNG, uLength)); + PSMgmtObject pMgmt = (PSMgmtObject) pMgmtHandle; + PWLAN_FRAME_MSRREP pMSRRep = (PWLAN_FRAME_MSRREP) +(pMgmt->abyCurrentMSRRep + sizeof(STxMgmtPacket)); + size_t uLength = 0; + PSTxMgmtPacket pTxPacket = NULL; + + pTxPacket = (PSTxMgmtPacket)pMgmt->abyCurrentMSRRep; + memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN); + pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + +sizeof(STxMgmtPacket)); + + pMSRRep->Header.wFrameCtl = (WLAN_SET_FC_FTYPE(WLAN_FTYPE_MGMT) | + WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ACTION) + ); + + memcpy(pMSRRep->Header.abyAddr1, ((PWLAN_FRAME_MSRREQ) + (pMgmt->abyCurrentMSRReq))->Header.abyAddr2, WLAN_ADDR_LEN); + memcpy(pMSRRep->Header.abyAddr2, + CARDpGetCurrentAddress(pMgmt->pAdapter), WLAN_ADDR_LEN); + memcpy(pMSRRep->Header.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); + + pMSRRep->byCategory = 0; + pMSRRep->byAction = 1; + pMSRRep->byDialogToken = ((PWLAN_FRAME_MSRREQ) + (pMgmt->abyCurrentMSRReq))->byDialogToken; + + uLength = pMgmt->uLengthOfRepEIDs + offsetof(WLAN_FRAME_MSRREP, + sMSRRepEIDs); + + pTxPacket->cbMPDULen = uLength; + pTxPacket->cbPayloadLen = uLength - WLAN_HDR_ADDR3_LEN; + if (csMgmt_xmit(pMgmt->pAdapter, pTxPacket) != CMD_STATUS_PENDING) + return false; + return true; +/* return (CARDbSendPacket(pMgmt->pAdapter, pMSRRep, PKT_TYPE_802_11_MNG, +uLength)); */ } diff --git a/drivers/staging/vt6655/device_main.c b/drivers/staging/vt6655/device_main.c index 3d2a9ba..567df43 100644 --- a/drivers/staging/vt6655/device_main.c +++ b/drivers/staging/vt6655/device_main.c @@ -815,14 +815,8 @@ else CARDbRadioPowerOn(pDevice); pMgmt->eScanType = WMAC_SCAN_PASSIVE; // get Permanent network address SROMvReadEtherAddress(pDevice->PortOffset, pDevice->abyCurrentNetAddr); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Network address = %02x-%02x-%02x=%02x-%02x-%02x\n", - pDevice->abyCurrentNetAddr[0], - pDevice->abyCurrentNetAddr[1], - pDevice->abyCurrentNetAddr[2], - pDevice->abyCurrentNetAddr[3], - pDevice->abyCurrentNetAddr[4], - pDevice->abyCurrentNetAddr[5]); - + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Network address = %pM\n", + pDevice->abyCurrentNetAddr); // reset Tx pointer CARDvSafeResetRx(pDevice); diff --git a/drivers/staging/vt6655/dpc.c b/drivers/staging/vt6655/dpc.c index cf0deac..c0fab4b 100644 --- a/drivers/staging/vt6655/dpc.c +++ b/drivers/staging/vt6655/dpc.c @@ -1107,30 +1107,12 @@ static bool s_bAPModeRxCtl ( &Status ); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: send vMgrDeAuthenBeginSta 3\n"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BSSID:%02x-%02x-%02x=%02x-%02x-%02x \n", - p802_11Header->abyAddr3[0], - p802_11Header->abyAddr3[1], - p802_11Header->abyAddr3[2], - p802_11Header->abyAddr3[3], - p802_11Header->abyAddr3[4], - p802_11Header->abyAddr3[5] - ); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ADDR2:%02x-%02x-%02x=%02x-%02x-%02x \n", - p802_11Header->abyAddr2[0], - p802_11Header->abyAddr2[1], - p802_11Header->abyAddr2[2], - p802_11Header->abyAddr2[3], - p802_11Header->abyAddr2[4], - p802_11Header->abyAddr2[5] - ); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ADDR1:%02x-%02x-%02x=%02x-%02x-%02x \n", - p802_11Header->abyAddr1[0], - p802_11Header->abyAddr1[1], - p802_11Header->abyAddr1[2], - p802_11Header->abyAddr1[3], - p802_11Header->abyAddr1[4], - p802_11Header->abyAddr1[5] - ); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BSSID:%pM\n", + p802_11Header->abyAddr3); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ADDR2:%pM\n", + p802_11Header->abyAddr2); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ADDR1:%pM\n", + p802_11Header->abyAddr1); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: wFrameCtl= %x\n", p802_11Header->wFrameCtl ); VNSvInPortB(pDevice->PortOffset + MAC_REG_RCR, &(pDevice->byRxMode)); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc:pDevice->byRxMode = %x\n", pDevice->byRxMode ); diff --git a/drivers/staging/vt6655/wmgr.c b/drivers/staging/vt6655/wmgr.c index ab289c3..c46d519 100644 --- a/drivers/staging/vt6655/wmgr.c +++ b/drivers/staging/vt6655/wmgr.c @@ -2521,14 +2521,8 @@ vMgrCreateOwnIBSS( if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { // AP mode BSSID = MAC addr memcpy(pMgmt->abyCurrBSSID, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO"AP beacon created BSSID:%02x-%02x-%02x-%02x-%02x-%02x \n", - pMgmt->abyCurrBSSID[0], - pMgmt->abyCurrBSSID[1], - pMgmt->abyCurrBSSID[2], - pMgmt->abyCurrBSSID[3], - pMgmt->abyCurrBSSID[4], - pMgmt->abyCurrBSSID[5] - ); + DBG_PRT(MSG_LEVEL_INFO, KERN_INFO"AP beacon created BSSID:%pM\n", + pMgmt->abyCurrBSSID); } if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { @@ -2550,14 +2544,8 @@ vMgrCreateOwnIBSS( pMgmt->abyCurrBSSID[0] |= IEEE_ADDR_UNIVERSAL; - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO"Adhoc beacon created bssid:%02x-%02x-%02x-%02x-%02x-%02x \n", - pMgmt->abyCurrBSSID[0], - pMgmt->abyCurrBSSID[1], - pMgmt->abyCurrBSSID[2], - pMgmt->abyCurrBSSID[3], - pMgmt->abyCurrBSSID[4], - pMgmt->abyCurrBSSID[5] - ); + DBG_PRT(MSG_LEVEL_INFO, KERN_INFO"Adhoc beacon created bssid:%pM\n", + pMgmt->abyCurrBSSID); } // Set Capability Info @@ -2887,14 +2875,8 @@ vMgrJoinBSSBegin( // pDevice->bLinkPass = true; // memcpy(pDevice->abyBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Join IBSS ok:%02x-%02x-%02x-%02x-%02x-%02x \n", - pMgmt->abyCurrBSSID[0], - pMgmt->abyCurrBSSID[1], - pMgmt->abyCurrBSSID[2], - pMgmt->abyCurrBSSID[3], - pMgmt->abyCurrBSSID[4], - pMgmt->abyCurrBSSID[5] - ); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Join IBSS ok:%pM\n", + pMgmt->abyCurrBSSID); // Preamble type auto-switch: if AP can receive short-preamble cap, // and if registry setting is short preamble we can turn on too. @@ -2984,13 +2966,8 @@ s_vMgrSynchBSS ( MACvReadBSSIDAddress(pDevice->PortOffset, pMgmt->abyCurrBSSID); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Sync:set CurrBSSID address = %02x-%02x-%02x=%02x-%02x-%02x\n", - pMgmt->abyCurrBSSID[0], - pMgmt->abyCurrBSSID[1], - pMgmt->abyCurrBSSID[2], - pMgmt->abyCurrBSSID[3], - pMgmt->abyCurrBSSID[4], - pMgmt->abyCurrBSSID[5]); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Sync:set CurrBSSID address = " + "%pM\n", pMgmt->abyCurrBSSID); if (pCurr->eNetworkTypeInUse == PHY_TYPE_11A) { if ((pMgmt->eConfigPHYMode == PHY_TYPE_11A) || @@ -4462,14 +4439,8 @@ s_vMgrRxProbeRequest( sFrame.pBuf = (unsigned char *)pRxPacket->p80211Header; vMgrDecodeProbeRequest(&sFrame); /* - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request rx:MAC addr:%02x-%02x-%02x=%02x-%02x-%02x \n", - sFrame.pHdr->sA3.abyAddr2[0], - sFrame.pHdr->sA3.abyAddr2[1], - sFrame.pHdr->sA3.abyAddr2[2], - sFrame.pHdr->sA3.abyAddr2[3], - sFrame.pHdr->sA3.abyAddr2[4], - sFrame.pHdr->sA3.abyAddr2[5] - ); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request rx:MAC addr:%pM\n", + sFrame.pHdr->sA3.abyAddr2); */ if (sFrame.pSSID->len != 0) { if (sFrame.pSSID->len != ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c index cb817ce..c0edf97 100644 --- a/drivers/staging/vt6656/dpc.c +++ b/drivers/staging/vt6656/dpc.c @@ -1109,30 +1109,12 @@ static BOOL s_bAPModeRxCtl ( &Status ); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: send vMgrDeAuthenBeginSta 3\n"); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BSSID:%02x-%02x-%02x=%02x-%02x-%02x \n", - p802_11Header->abyAddr3[0], - p802_11Header->abyAddr3[1], - p802_11Header->abyAddr3[2], - p802_11Header->abyAddr3[3], - p802_11Header->abyAddr3[4], - p802_11Header->abyAddr3[5] - ); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ADDR2:%02x-%02x-%02x=%02x-%02x-%02x \n", - p802_11Header->abyAddr2[0], - p802_11Header->abyAddr2[1], - p802_11Header->abyAddr2[2], - p802_11Header->abyAddr2[3], - p802_11Header->abyAddr2[4], - p802_11Header->abyAddr2[5] - ); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ADDR1:%02x-%02x-%02x=%02x-%02x-%02x \n", - p802_11Header->abyAddr1[0], - p802_11Header->abyAddr1[1], - p802_11Header->abyAddr1[2], - p802_11Header->abyAddr1[3], - p802_11Header->abyAddr1[4], - p802_11Header->abyAddr1[5] - ); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "BSSID:%pM\n", + p802_11Header->abyAddr3); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ADDR2:%pM\n", + p802_11Header->abyAddr2); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "ADDR1:%pM\n", + p802_11Header->abyAddr1); DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "dpc: wFrameCtl= %x\n", p802_11Header->wFrameCtl ); return TRUE; } diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index e18efd4..73a0838 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c @@ -611,17 +611,10 @@ static BOOL device_init_registers(PSDevice pDevice, DEVICE_INIT_TYPE InitType) // if exist SW network address, use SW network address. - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Network address = %02x-%02x-%02x=%02x-%02x-%02x\n", - pDevice->abyCurrentNetAddr[0], - pDevice->abyCurrentNetAddr[1], - pDevice->abyCurrentNetAddr[2], - pDevice->abyCurrentNetAddr[3], - pDevice->abyCurrentNetAddr[4], - pDevice->abyCurrentNetAddr[5]); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Network address = %pM\n", + pDevice->abyCurrentNetAddr); } - - // Set BB and packet type at the same time. // Set Short Slot Time, xIFS, and RSPINF. if (pDevice->byBBType == BB_TYPE_11A) { diff --git a/drivers/staging/vt6656/wmgr.c b/drivers/staging/vt6656/wmgr.c index d67748f..f08e2d1 100644 --- a/drivers/staging/vt6656/wmgr.c +++ b/drivers/staging/vt6656/wmgr.c @@ -2477,14 +2477,8 @@ void vMgrCreateOwnIBSS(void *hDeviceContext, if (pMgmt->eCurrMode == WMAC_MODE_ESS_AP) { // AP mode BSSID = MAC addr memcpy(pMgmt->abyCurrBSSID, pMgmt->abyMACAddr, WLAN_ADDR_LEN); - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO"AP beacon created BSSID:%02x-%02x-%02x-%02x-%02x-%02x \n", - pMgmt->abyCurrBSSID[0], - pMgmt->abyCurrBSSID[1], - pMgmt->abyCurrBSSID[2], - pMgmt->abyCurrBSSID[3], - pMgmt->abyCurrBSSID[4], - pMgmt->abyCurrBSSID[5] - ); + DBG_PRT(MSG_LEVEL_INFO, KERN_INFO"AP beacon created BSSID:" + "%pM\n", pMgmt->abyCurrBSSID); } if (pMgmt->eCurrMode == WMAC_MODE_IBSS_STA) { @@ -2506,14 +2500,8 @@ void vMgrCreateOwnIBSS(void *hDeviceContext, pMgmt->abyCurrBSSID[0] |= IEEE_ADDR_UNIVERSAL; - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO"Adhoc beacon created bssid:%02x-%02x-%02x-%02x-%02x-%02x \n", - pMgmt->abyCurrBSSID[0], - pMgmt->abyCurrBSSID[1], - pMgmt->abyCurrBSSID[2], - pMgmt->abyCurrBSSID[3], - pMgmt->abyCurrBSSID[4], - pMgmt->abyCurrBSSID[5] - ); + DBG_PRT(MSG_LEVEL_INFO, KERN_INFO"Adhoc beacon created bssid:" + "%pM\n", pMgmt->abyCurrBSSID); } // set BSSID filter @@ -2878,14 +2866,8 @@ void vMgrJoinBSSBegin(void *hDeviceContext, PCMD_STATUS pStatus) ControlvMaskByte(pDevice,MESSAGE_REQUEST_MACREG,MAC_REG_PAPEDELAY,LEDSTS_STS,LEDSTS_INTER); memcpy(pDevice->abyBSSID, pCurr->abyBSSID, WLAN_BSSID_LEN); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Join IBSS ok:%02x-%02x-%02x-%02x-%02x-%02x \n", - pMgmt->abyCurrBSSID[0], - pMgmt->abyCurrBSSID[1], - pMgmt->abyCurrBSSID[2], - pMgmt->abyCurrBSSID[3], - pMgmt->abyCurrBSSID[4], - pMgmt->abyCurrBSSID[5] - ); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Join IBSS ok:%pM\n", + pMgmt->abyCurrBSSID); // Preamble type auto-switch: if AP can receive short-preamble cap, // and if registry setting is short preamble we can turn on too. @@ -2983,13 +2965,8 @@ s_vMgrSynchBSS ( memcpy(pMgmt->abyCurrBSSID, pCurr->abyBSSID, 6); - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Sync:set CurrBSSID address = %02x-%02x-%02x=%02x-%02x-%02x\n", - pMgmt->abyCurrBSSID[0], - pMgmt->abyCurrBSSID[1], - pMgmt->abyCurrBSSID[2], - pMgmt->abyCurrBSSID[3], - pMgmt->abyCurrBSSID[4], - pMgmt->abyCurrBSSID[5]); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Sync:set CurrBSSID address = " + "%pM\n", pMgmt->abyCurrBSSID); if (pCurr->eNetworkTypeInUse == PHY_TYPE_11A) { if ((pDevice->eConfigPHYMode == PHY_TYPE_11A) || @@ -4334,14 +4311,8 @@ s_vMgrRxProbeRequest( sFrame.pBuf = (PBYTE)pRxPacket->p80211Header; vMgrDecodeProbeRequest(&sFrame); /* - DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request rx:MAC addr:%02x-%02x-%02x=%02x-%02x-%02x \n", - sFrame.pHdr->sA3.abyAddr2[0], - sFrame.pHdr->sA3.abyAddr2[1], - sFrame.pHdr->sA3.abyAddr2[2], - sFrame.pHdr->sA3.abyAddr2[3], - sFrame.pHdr->sA3.abyAddr2[4], - sFrame.pHdr->sA3.abyAddr2[5] - ); + DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Probe request rx:MAC addr:%pM\n", + sFrame.pHdr->sA3.abyAddr2); */ if (sFrame.pSSID->len != 0) { if (sFrame.pSSID->len != ((PWLAN_IE_SSID)pMgmt->abyCurrSSID)->len) diff --git a/drivers/staging/winbond/phy_calibration.c b/drivers/staging/winbond/phy_calibration.c index c5a07fb..77a3fff 100644 --- a/drivers/staging/winbond/phy_calibration.c +++ b/drivers/staging/winbond/phy_calibration.c @@ -24,7 +24,7 @@ #define AG_CONST 0.6072529350 #define FIXED(X) ((s32)((X) * 32768.0)) -#define DEG2RAD(X) 0.017453 * (X) +#define DEG2RAD(X) (0.017453 * (X)) static const s32 Angles[] = { FIXED(DEG2RAD(45.0)), FIXED(DEG2RAD(26.565)), FIXED(DEG2RAD(14.0362)), @@ -51,7 +51,7 @@ s32 _s13_to_s32(u32 data) if ((data & BIT(12)) != 0) val |= 0xFFFFF000; - return ((s32) val); + return (s32) val; } u32 _s32_to_s13(s32 data) @@ -184,7 +184,7 @@ s32 _floor(s32 n) else n -= 5; - return (n/10); + return n/10; } /****************************************************************************/ @@ -455,7 +455,7 @@ void _txidac_dc_offset_cancellation_winbond(struct hw_data *phw_data) phy_set_rf_data(phw_data, 11, (11<<24)|0x1901D6); /* 0x05 0x24C60A ; 09318 ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized */ phy_set_rf_data(phw_data, 5, (5<<24)|0x24C48A); - /* 0x06 0x06880C ; 01A20 ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized */ + /* 0x06 0x06880C ; 01A20 ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized */ phy_set_rf_data(phw_data, 6, (6<<24)|0x06890C); /* 0x00 0xFDF1C0 ; 3F7C7 ; Calibration (6e). turn on IQ imbalance/Test mode */ phy_set_rf_data(phw_data, 0, (0<<24)|0xFDF1C0); @@ -577,7 +577,7 @@ void _txqdac_dc_offset_cacellation_winbond(struct hw_data *phw_data) phy_set_rf_data(phw_data, 11, (11<<24)|0x1901D6); /* 0x05 0x24C60A ; 09318 ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized */ phy_set_rf_data(phw_data, 5, (5<<24)|0x24C48A); - /* 0x06 0x06880C ; 01A20 ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized */ + /* 0x06 0x06880C ; 01A20 ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized */ phy_set_rf_data(phw_data, 6, (6<<24)|0x06890C); /* 0x00 0xFDF1C0 ; 3F7C7 ; Calibration (6e). turn on IQ imbalance/Test mode */ phy_set_rf_data(phw_data, 0, (0<<24)|0xFDF1C0); @@ -974,7 +974,7 @@ void _tx_iq_calibration_winbond(struct hw_data *phw_data) phy_set_rf_data(phw_data, 11, (11<<24)|0x19BDD6); /* 20060612.1.a 0x1905D6); */ /* 0x05 0x24C60A ; 09318 ; Calibration (6c). setting TX-VGA gain: TXGCH=2 & GPK=110 --> to be optimized */ phy_set_rf_data(phw_data, 5, (5<<24)|0x24C60A); /* 0x24C60A (high temperature) */ - /* 0x06 0x06880C ; 01A20 ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized */ + /* 0x06 0x06880C ; 01A20 ; Calibration (6d). RXGCH=00; RXGCL=100 000 (RXVGA=32) --> to be optimized */ phy_set_rf_data(phw_data, 6, (6<<24)|0x34880C); /* 20060612.1.a 0x06890C); */ /* 0x00 0xFDF1C0 ; 3F7C7 ; Calibration (6e). turn on IQ imbalance/Test mode */ phy_set_rf_data(phw_data, 0, (0<<24)|0xFDF1C0); diff --git a/drivers/staging/xgifb/XGI_main.h b/drivers/staging/xgifb/XGI_main.h index f6cd22d..59f7411 100644 --- a/drivers/staging/xgifb/XGI_main.h +++ b/drivers/staging/xgifb/XGI_main.h @@ -11,12 +11,6 @@ #define XGIFAIL(x) do { printk(x "\n"); return -EINVAL; } while (0) -#define VER_MAJOR 0 -#define VER_MINOR 8 -#define VER_LEVEL 1 - -#define DRIVER_DESC "XGI Volari Frame Buffer Module Version 0.8.1" - #ifndef PCI_VENDOR_ID_XG #define PCI_VENDOR_ID_XG 0x18CA #endif @@ -37,12 +31,6 @@ #define PCI_DEVICE_ID_XG_27 0x027 #endif - - -#define XGI_IOTYPE1 void __iomem -#define XGI_IOTYPE2 __iomem -#define XGIINITSTATIC static - static DEFINE_PCI_DEVICE_TABLE(xgifb_pci_table) = { {PCI_VENDOR_ID_XG, PCI_DEVICE_ID_XG_20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, @@ -58,31 +46,11 @@ static DEFINE_PCI_DEVICE_TABLE(xgifb_pci_table) = { MODULE_DEVICE_TABLE(pci, xgifb_pci_table); /* To be included in fb.h */ -#ifndef FB_ACCEL_XGI_GLAMOUR_2 -#define FB_ACCEL_XGI_GLAMOUR_2 40 /* XGI 315, 650, 740 */ -#endif #ifndef FB_ACCEL_XGI_XABRE #define FB_ACCEL_XGI_XABRE 41 /* XGI 330 ("Xabre") */ #endif -#define MAX_ROM_SCAN 0x10000 - -#define SEQ_ADR 0x14 #define SEQ_DATA 0x15 -#define DAC_ADR 0x18 -#define DAC_DATA 0x19 -#define CRTC_ADR 0x24 -#define CRTC_DATA 0x25 -#define DAC2_ADR (0x16-0x30) -#define DAC2_DATA (0x17-0x30) -#define VB_PART1_ADR (0x04-0x30) -#define VB_PART1_DATA (0x05-0x30) -#define VB_PART2_ADR (0x10-0x30) -#define VB_PART2_DATA (0x11-0x30) -#define VB_PART3_ADR (0x12-0x30) -#define VB_PART3_DATA (0x13-0x30) -#define VB_PART4_ADR (0x14-0x30) -#define VB_PART4_DATA (0x15-0x30) #define XGISR XGI_Pr.P3c4 #define XGICR XGI_Pr.P3d4 @@ -95,24 +63,12 @@ MODULE_DEVICE_TABLE(pci, xgifb_pci_table); #define XGIPART5 XGI_Pr.Part5Port #define XGIDAC2A XGIPART5 #define XGIDAC2D (XGIPART5 + 1) -#define XGIMISCR (XGI_Pr.RelIO + 0x1c) -#define XGIINPSTAT (XGI_Pr.RelIO + 0x2a) #define IND_XGI_PASSWORD 0x05 /* SRs */ -#define IND_XGI_COLOR_MODE 0x06 #define IND_XGI_RAMDAC_CONTROL 0x07 #define IND_XGI_DRAM_SIZE 0x14 -#define IND_XGI_SCRATCH_REG_16 0x16 -#define IND_XGI_SCRATCH_REG_17 0x17 -#define IND_XGI_SCRATCH_REG_1A 0x1A #define IND_XGI_MODULE_ENABLE 0x1E #define IND_XGI_PCI_ADDRESS_SET 0x20 -#define IND_XGI_TURBOQUEUE_ADR 0x26 -#define IND_XGI_TURBOQUEUE_SET 0x27 -#define IND_XGI_POWER_ON_TRAP 0x38 -#define IND_XGI_POWER_ON_TRAP2 0x39 -#define IND_XGI_CMDQUEUE_SET 0x26 -#define IND_XGI_CMDQUEUE_THRESHOLD 0x27 #define IND_XGI_SCRATCH_REG_CR30 0x30 /* CRs */ #define IND_XGI_SCRATCH_REG_CR31 0x31 @@ -120,23 +76,10 @@ MODULE_DEVICE_TABLE(pci, xgifb_pci_table); #define IND_XGI_SCRATCH_REG_CR33 0x33 #define IND_XGI_LCD_PANEL 0x36 #define IND_XGI_SCRATCH_REG_CR37 0x37 -#define IND_XGI_AGP_IO_PAD 0x48 - -#define IND_BRI_DRAM_STATUS 0x63 /* PCI config memory size offset */ -#define MMIO_QUEUE_PHYBASE 0x85C0 -#define MMIO_QUEUE_WRITEPORT 0x85C4 -#define MMIO_QUEUE_READPORT 0x85C8 - -#define IND_XGI_CRT2_WRITE_ENABLE_300 0x24 #define IND_XGI_CRT2_WRITE_ENABLE_315 0x2F #define XGI_PASSWORD 0x86 /* SR05 */ -#define XGI_INTERLACED_MODE 0x20 /* SR06 */ -#define XGI_8BPP_COLOR_MODE 0x0 -#define XGI_15BPP_COLOR_MODE 0x1 -#define XGI_16BPP_COLOR_MODE 0x2 -#define XGI_32BPP_COLOR_MODE 0x4 #define XGI_DRAM_SIZE_MASK 0xF0 /*SR14 */ #define XGI_DRAM_SIZE_1MB 0x00 @@ -148,27 +91,6 @@ MODULE_DEVICE_TABLE(pci, xgifb_pci_table); #define XGI_DRAM_SIZE_64MB 0x06 #define XGI_DRAM_SIZE_128MB 0x07 #define XGI_DRAM_SIZE_256MB 0x08 -#define XGI_DATA_BUS_MASK 0x02 -#define XGI_DATA_BUS_64 0x00 -#define XGI_DATA_BUS_128 0x01 -#define XGI_DUAL_CHANNEL_MASK 0x0C -#define XGI_SINGLE_CHANNEL_1_RANK 0x0 -#define XGI_SINGLE_CHANNEL_2_RANK 0x1 -#define XGI_ASYM_DDR 0x02 -#define XGI_DUAL_CHANNEL_1_RANK 0x3 - -#define XGI550_DRAM_SIZE_MASK 0x3F /* 550/650/740 SR14 */ -#define XGI550_DRAM_SIZE_4MB 0x00 -#define XGI550_DRAM_SIZE_8MB 0x01 -#define XGI550_DRAM_SIZE_16MB 0x03 -#define XGI550_DRAM_SIZE_24MB 0x05 -#define XGI550_DRAM_SIZE_32MB 0x07 -#define XGI550_DRAM_SIZE_64MB 0x0F -#define XGI550_DRAM_SIZE_96MB 0x17 -#define XGI550_DRAM_SIZE_128MB 0x1F -#define XGI550_DRAM_SIZE_256MB 0x3F - -#define XGI_SCRATCH_REG_1A_MASK 0x10 #define XGI_ENABLE_2D 0x40 /* SR1E */ @@ -176,7 +98,6 @@ MODULE_DEVICE_TABLE(pci, xgifb_pci_table); #define XGI_PCI_ADDR_ENABLE 0x80 #define XGI_SIMULTANEOUS_VIEW_ENABLE 0x01 /* CR30 */ -#define XGI_MODE_SELECT_CRT2 0x02 #define XGI_VB_OUTPUT_COMPOSITE 0x04 #define XGI_VB_OUTPUT_SVIDEO 0x08 #define XGI_VB_OUTPUT_SCART 0x10 @@ -199,35 +120,14 @@ MODULE_DEVICE_TABLE(pci, xgifb_pci_table); XGI_VB_SCART | XGI_VB_HIVISION|XGI_VB_YPBPR) #define XGI_EXTERNAL_CHIP_MASK 0x0E /* CR37 */ -#define XGI_EXTERNAL_CHIP_XGI301 0x01 /* in CR37 << 1 ! */ -#define XGI_EXTERNAL_CHIP_LVDS 0x02 /* in CR37 << 1 ! */ -#define XGI_EXTERNAL_CHIP_TRUMPION 0x03 /* in CR37 << 1 ! */ -#define XGI_EXTERNAL_CHIP_LVDS_CHRONTEL 0x04 /* in CR37 << 1 ! */ -#define XGI_EXTERNAL_CHIP_CHRONTEL 0x05 /* in CR37 << 1 ! */ #define XGI310_EXTERNAL_CHIP_LVDS 0x02 /* in CR37 << 1 ! */ #define XGI310_EXTERNAL_CHIP_LVDS_CHRONTEL 0x03 /* in CR37 << 1 ! */ -#define XGI_AGP_2X 0x20 /* CR48 */ - -#define BRI_DRAM_SIZE_MASK 0x70 /* PCI bridge config data */ -#define BRI_DRAM_SIZE_2MB 0x00 -#define BRI_DRAM_SIZE_4MB 0x01 -#define BRI_DRAM_SIZE_8MB 0x02 -#define BRI_DRAM_SIZE_16MB 0x03 -#define BRI_DRAM_SIZE_32MB 0x04 -#define BRI_DRAM_SIZE_64MB 0x05 - -#define SR_BUFFER_SIZE 5 -#define CR_BUFFER_SIZE 5 - /* ------------------- Global Variables ----------------------------- */ /* Fbcon variables */ static struct fb_info *fb_info; - -static int video_type = FB_TYPE_PACKED_PIXELS; - static struct fb_var_screeninfo default_var = { .xres = 0, .yres = 0, @@ -263,39 +163,30 @@ static struct fb_fix_screeninfo XGIfb_fix = { .xpanstep = 1, .ypanstep = 1, }; -static char myid[20]; static u32 pseudo_palette[17]; /* display status */ -static int XGIfb_off = 0; -static int XGIfb_crt1off = 0; +static int XGIfb_off; +static int XGIfb_crt1off; static int XGIfb_forcecrt1 = -1; -static int XGIfb_userom = 0; +static int XGIfb_userom ; /*static int XGIfb_useoem = -1; */ /* global flags */ -static int XGIfb_registered; -static int XGIfb_tvmode = 0; -static int XGIfb_pdc = 0; -static int enable_dstn = 0; +static int XGIfb_tvmode; +static int XGIfb_pdc; +static int enable_dstn; static int XGIfb_ypan = -1; -static int XGIfb_CRT2_write_enable = 0; +static int XGIfb_CRT2_write_enable; /* TW: CRT2 type (for overriding autodetection) */ static int XGIfb_crt2type = -1; /* PR: Tv plug type (for overriding autodetection) */ static int XGIfb_tvplug = -1; -static unsigned char XGIfb_detectedpdc = 0; - -static unsigned char XGIfb_detectedlcda = 0xff; - - - - /* TW: For ioctl XGIFB_GET_INFO */ /* XGIfb_info XGIfbinfo; */ @@ -424,7 +315,6 @@ static struct _XGIbios_mode { MD_XGI315}, {"1280x768x32", 0x25, 0x0000, 0x0000, 1280, 768, 32, 1, 160, 48, MD_XGI315}, -#define MODEINDEX_1280x960 48 {"1280x960x8", 0x7C, 0x0000, 0x0000, 1280, 960, 8, 1, 160, 60, MD_XGI300|MD_XGI315}, /* TW: Modenumbers being patched */ {"1280x960x16", 0x7D, 0x0000, 0x0000, 1280, 960, 16, 1, 160, 60, @@ -483,8 +373,8 @@ static int xgifb_mode_idx = 1; static int xgifb_mode_idx = -1; /* Use a default mode if we are inside the kernel */ #endif -static u8 XGIfb_mode_no = 0; -static u8 XGIfb_rate_idx = 0; +static u8 XGIfb_mode_no; +static u8 XGIfb_rate_idx; /* TW: CR36 evaluation */ static const unsigned short XGI300paneltype[] = { diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 4403e5f..7b36b7e 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -28,10 +28,6 @@ #include <linux/types.h> #include <linux/proc_fs.h> -#ifndef XGIFB_PAN -#define XGIFB_PAN -#endif - #include <linux/io.h> #ifdef CONFIG_MTRR #include <asm/mtrr.h> @@ -45,11 +41,9 @@ #include "vb_setmode.h" #define Index_CR_GPIO_Reg1 0x48 -#define Index_CR_GPIO_Reg2 0x49 #define Index_CR_GPIO_Reg3 0x4a #define GPIOG_EN (1<<6) -#define GPIOG_WRITE (1<<6) #define GPIOG_READ (1<<1) #define XGIFB_ROM_SIZE 65536 @@ -396,8 +390,8 @@ static unsigned char XGIfb_query_VGA_config_space( struct xgi_hw_device_info *pXGIhw_ext, unsigned long offset, unsigned long set, unsigned long *value) { - static struct pci_dev *pdev = NULL; - static unsigned char init = 0, valid_pdev = 0; + static struct pci_dev *pdev; + static unsigned char init, valid_pdev; if (!set) DPRINTK("XGIfb: Get VGA offset 0x%lx\n", offset); @@ -1363,7 +1357,6 @@ static int XGIfb_do_set_var(struct fb_var_screeninfo *var, int isactive, return 0; } -#ifdef XGIFB_PAN static int XGIfb_pan_var(struct fb_var_screeninfo *var) { unsigned int base; @@ -1416,7 +1409,6 @@ static int XGIfb_pan_var(struct fb_var_screeninfo *var) /* printk("End of pan_var"); */ return 0; } -#endif static int XGIfb_open(struct fb_info *info, int user) { @@ -1489,23 +1481,19 @@ static int XGIfb_get_fix(struct fb_fix_screeninfo *fix, int con, DEBUGPRN("inside get_fix"); memset(fix, 0, sizeof(struct fb_fix_screeninfo)); - strcpy(fix->id, myid); - fix->smem_start = xgi_video_info.video_base; fix->smem_len = xgi_video_info.video_size; - fix->type = video_type; + fix->type = FB_TYPE_PACKED_PIXELS; fix->type_aux = 0; if (xgi_video_info.video_bpp == 8) fix->visual = FB_VISUAL_PSEUDOCOLOR; else fix->visual = FB_VISUAL_DIRECTCOLOR; fix->xpanstep = 0; -#ifdef XGIFB_PAN if (XGIfb_ypan) fix->ypanstep = 1; -#endif fix->ywrapstep = 0; fix->line_length = xgi_video_info.video_linelength; fix->mmio_start = xgi_video_info.mmio_base; @@ -1673,7 +1661,6 @@ static int XGIfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) return 0; } -#ifdef XGIFB_PAN static int XGIfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) { @@ -1710,7 +1697,6 @@ static int XGIfb_pan_display(struct fb_var_screeninfo *var, /* printk("End of pan_display\n"); */ return 0; } -#endif static int XGIfb_blank(int blank, struct fb_info *info) { @@ -1736,9 +1722,7 @@ static struct fb_ops XGIfb_ops = { .fb_check_var = XGIfb_check_var, .fb_set_par = XGIfb_set_par, .fb_setcolreg = XGIfb_setcolreg, -#ifdef XGIFB_PAN .fb_pan_display = XGIfb_pan_display, -#endif .fb_blank = XGIfb_blank, .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, @@ -1949,7 +1933,7 @@ static void XGIfb_get_VB_type(void) } } -XGIINITSTATIC int __init XGIfb_setup(char *options) +static int __init XGIfb_setup(char *options) { char *this_opt; @@ -2060,8 +2044,6 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, if (XGIfb_off) return -ENXIO; - XGIfb_registered = 0; - memset(&XGIhw_ext, 0, sizeof(struct xgi_hw_device_info)); fb_info = framebuffer_alloc(sizeof(struct fb_info), &pdev->dev); if (!fb_info) @@ -2157,15 +2139,12 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, goto error; } - if ((xgifb_mode_idx < 0) || - ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) { - /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */ - xgifb_reg_or(XGISR, - IND_XGI_PCI_ADDRESS_SET, - (XGI_PCI_ADDR_ENABLE | XGI_MEM_MAP_IO_ENABLE)); - /* Enable 2D accelerator engine */ - xgifb_reg_or(XGISR, IND_XGI_MODULE_ENABLE, XGI_ENABLE_2D); - } + /* Enable PCI_LINEAR_ADDRESSING and MMIO_ENABLE */ + xgifb_reg_or(XGISR, + IND_XGI_PCI_ADDRESS_SET, + (XGI_PCI_ADDR_ENABLE | XGI_MEM_MAP_IO_ENABLE)); + /* Enable 2D accelerator engine */ + xgifb_reg_or(XGISR, IND_XGI_MODULE_ENABLE, XGI_ENABLE_2D); XGIhw_ext.ulVideoMemorySize = xgi_video_info.video_size; @@ -2209,297 +2188,282 @@ static int __devinit xgifb_probe(struct pci_dev *pdev, xgi_video_info.mtrr = (unsigned int) 0; - if ((xgifb_mode_idx < 0) || - ((XGIbios_mode[xgifb_mode_idx].mode_no) != 0xFF)) { + xgi_video_info.hasVB = HASVB_NONE; + if ((xgi_video_info.chip == XG20) || + (xgi_video_info.chip == XG27)) { xgi_video_info.hasVB = HASVB_NONE; - if ((xgi_video_info.chip == XG20) || - (xgi_video_info.chip == XG27)) { - xgi_video_info.hasVB = HASVB_NONE; - } else if (xgi_video_info.chip == XG21) { - CR38 = xgifb_reg_get(XGICR, 0x38); - if ((CR38&0xE0) == 0xC0) { - xgi_video_info.disp_state = DISPTYPE_LCD; - if (!XGIfb_GetXG21LVDSData()) { - int m; - for (m = 0; m < sizeof(XGI21_LCDCapList)/sizeof(struct XGI21_LVDSCapStruct); m++) { - if ((XGI21_LCDCapList[m].LVDSHDE == XGIbios_mode[xgifb_mode_idx].xres) && - (XGI21_LCDCapList[m].LVDSVDE == XGIbios_mode[xgifb_mode_idx].yres)) { - xgifb_reg_set(XGI_Pr.P3d4, 0x36, m); - } + } else if (xgi_video_info.chip == XG21) { + CR38 = xgifb_reg_get(XGICR, 0x38); + if ((CR38&0xE0) == 0xC0) { + xgi_video_info.disp_state = DISPTYPE_LCD; + if (!XGIfb_GetXG21LVDSData()) { + int m; + for (m = 0; m < sizeof(XGI21_LCDCapList)/sizeof(struct XGI21_LVDSCapStruct); m++) { + if ((XGI21_LCDCapList[m].LVDSHDE == XGIbios_mode[xgifb_mode_idx].xres) && + (XGI21_LCDCapList[m].LVDSVDE == XGIbios_mode[xgifb_mode_idx].yres)) { + xgifb_reg_set(XGI_Pr.P3d4, 0x36, m); } } - } else if ((CR38&0xE0) == 0x60) { - xgi_video_info.hasVB = HASVB_CHRONTEL; - } else { - xgi_video_info.hasVB = HASVB_NONE; } + } else if ((CR38&0xE0) == 0x60) { + xgi_video_info.hasVB = HASVB_CHRONTEL; } else { - XGIfb_get_VB_type(); + xgi_video_info.hasVB = HASVB_NONE; } + } else { + XGIfb_get_VB_type(); + } - XGIhw_ext.ujVBChipID = VB_CHIP_UNKNOWN; - - XGIhw_ext.ulExternalChip = 0; + XGIhw_ext.ujVBChipID = VB_CHIP_UNKNOWN; - switch (xgi_video_info.hasVB) { - case HASVB_301: - reg = xgifb_reg_get(XGIPART4, 0x01); - if (reg >= 0xE0) { - XGIhw_ext.ujVBChipID = VB_CHIP_302LV; - printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg); - } else if (reg >= 0xD0) { - XGIhw_ext.ujVBChipID = VB_CHIP_301LV; - printk(KERN_INFO "XGIfb: XGI301LV bridge detected (revision 0x%02x)\n", reg); - } - /* else if (reg >= 0xB0) { - XGIhw_ext.ujVBChipID = VB_CHIP_301B; - reg1 = xgifb_reg_get(XGIPART4, 0x23); - printk("XGIfb: XGI301B bridge detected\n"); - } */ - else { - XGIhw_ext.ujVBChipID = VB_CHIP_301; - printk("XGIfb: XGI301 bridge detected\n"); - } - break; - case HASVB_302: - reg = xgifb_reg_get(XGIPART4, 0x01); - if (reg >= 0xE0) { - XGIhw_ext.ujVBChipID = VB_CHIP_302LV; - printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg); - } else if (reg >= 0xD0) { - XGIhw_ext.ujVBChipID = VB_CHIP_301LV; - printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg); - } else if (reg >= 0xB0) { - reg1 = xgifb_reg_get(XGIPART4, 0x23); - - XGIhw_ext.ujVBChipID = VB_CHIP_302B; + XGIhw_ext.ulExternalChip = 0; - } else { - XGIhw_ext.ujVBChipID = VB_CHIP_302; - printk(KERN_INFO "XGIfb: XGI302 bridge detected\n"); - } - break; - case HASVB_LVDS: - XGIhw_ext.ulExternalChip = 0x1; - printk(KERN_INFO "XGIfb: LVDS transmitter detected\n"); - break; - case HASVB_TRUMPION: - XGIhw_ext.ulExternalChip = 0x2; - printk(KERN_INFO "XGIfb: Trumpion Zurac LVDS scaler detected\n"); - break; - case HASVB_CHRONTEL: - XGIhw_ext.ulExternalChip = 0x4; - printk(KERN_INFO "XGIfb: Chrontel TV encoder detected\n"); - break; - case HASVB_LVDS_CHRONTEL: - XGIhw_ext.ulExternalChip = 0x5; - printk(KERN_INFO "XGIfb: LVDS transmitter and Chrontel TV encoder detected\n"); - break; - default: - printk(KERN_INFO "XGIfb: No or unknown bridge type detected\n"); - break; + switch (xgi_video_info.hasVB) { + case HASVB_301: + reg = xgifb_reg_get(XGIPART4, 0x01); + if (reg >= 0xE0) { + XGIhw_ext.ujVBChipID = VB_CHIP_302LV; + printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg); + } else if (reg >= 0xD0) { + XGIhw_ext.ujVBChipID = VB_CHIP_301LV; + printk(KERN_INFO "XGIfb: XGI301LV bridge detected (revision 0x%02x)\n", reg); + } + /* else if (reg >= 0xB0) { + XGIhw_ext.ujVBChipID = VB_CHIP_301B; + reg1 = xgifb_reg_get(XGIPART4, 0x23); + printk("XGIfb: XGI301B bridge detected\n"); + } */ + else { + XGIhw_ext.ujVBChipID = VB_CHIP_301; + printk("XGIfb: XGI301 bridge detected\n"); } + break; + case HASVB_302: + reg = xgifb_reg_get(XGIPART4, 0x01); + if (reg >= 0xE0) { + XGIhw_ext.ujVBChipID = VB_CHIP_302LV; + printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg); + } else if (reg >= 0xD0) { + XGIhw_ext.ujVBChipID = VB_CHIP_301LV; + printk(KERN_INFO "XGIfb: XGI302LV bridge detected (revision 0x%02x)\n", reg); + } else if (reg >= 0xB0) { + reg1 = xgifb_reg_get(XGIPART4, 0x23); - if (xgi_video_info.hasVB != HASVB_NONE) - XGIfb_detect_VB(); + XGIhw_ext.ujVBChipID = VB_CHIP_302B; - if (xgi_video_info.disp_state & DISPTYPE_DISP2) { - if (XGIfb_crt1off) - xgi_video_info.disp_state |= DISPMODE_SINGLE; - else - xgi_video_info.disp_state |= (DISPMODE_MIRROR | - DISPTYPE_CRT1); } else { - xgi_video_info.disp_state = DISPMODE_SINGLE | - DISPTYPE_CRT1; + XGIhw_ext.ujVBChipID = VB_CHIP_302; + printk(KERN_INFO "XGIfb: XGI302 bridge detected\n"); } + break; + case HASVB_LVDS: + XGIhw_ext.ulExternalChip = 0x1; + printk(KERN_INFO "XGIfb: LVDS transmitter detected\n"); + break; + case HASVB_TRUMPION: + XGIhw_ext.ulExternalChip = 0x2; + printk(KERN_INFO "XGIfb: Trumpion Zurac LVDS scaler detected\n"); + break; + case HASVB_CHRONTEL: + XGIhw_ext.ulExternalChip = 0x4; + printk(KERN_INFO "XGIfb: Chrontel TV encoder detected\n"); + break; + case HASVB_LVDS_CHRONTEL: + XGIhw_ext.ulExternalChip = 0x5; + printk(KERN_INFO "XGIfb: LVDS transmitter and Chrontel TV encoder detected\n"); + break; + default: + printk(KERN_INFO "XGIfb: No or unknown bridge type detected\n"); + break; + } - if (xgi_video_info.disp_state & DISPTYPE_LCD) { - if (!enable_dstn) { - reg = xgifb_reg_get(XGICR, IND_XGI_LCD_PANEL); - reg &= 0x0f; - XGIhw_ext.ulCRT2LCDType = XGI310paneltype[reg]; - - } else { - /* TW: FSTN/DSTN */ - XGIhw_ext.ulCRT2LCDType = LCD_320x480; - } - } + if (xgi_video_info.hasVB != HASVB_NONE) + XGIfb_detect_VB(); - XGIfb_detectedpdc = 0; + if (xgi_video_info.disp_state & DISPTYPE_DISP2) { + if (XGIfb_crt1off) + xgi_video_info.disp_state |= DISPMODE_SINGLE; + else + xgi_video_info.disp_state |= (DISPMODE_MIRROR | + DISPTYPE_CRT1); + } else { + xgi_video_info.disp_state = DISPMODE_SINGLE | + DISPTYPE_CRT1; + } - XGIfb_detectedlcda = 0xff; + if (xgi_video_info.disp_state & DISPTYPE_LCD) { + if (!enable_dstn) { + reg = xgifb_reg_get(XGICR, IND_XGI_LCD_PANEL); + reg &= 0x0f; + XGIhw_ext.ulCRT2LCDType = XGI310paneltype[reg]; - /* TW: Try to find about LCDA */ + } else { + /* TW: FSTN/DSTN */ + XGIhw_ext.ulCRT2LCDType = LCD_320x480; + } + } - if ((XGIhw_ext.ujVBChipID == VB_CHIP_302B) || - (XGIhw_ext.ujVBChipID == VB_CHIP_301LV) || - (XGIhw_ext.ujVBChipID == VB_CHIP_302LV)) { - int tmp; - tmp = xgifb_reg_get(XGICR, 0x34); - if (tmp <= 0x13) { + if ((XGIhw_ext.ujVBChipID == VB_CHIP_302B) || + (XGIhw_ext.ujVBChipID == VB_CHIP_301LV) || + (XGIhw_ext.ujVBChipID == VB_CHIP_302LV)) { + int tmp; + tmp = xgifb_reg_get(XGICR, 0x34); + if (tmp <= 0x13) { + /* Currently on LCDA? + *(Some BIOSes leave CR38) */ + tmp = xgifb_reg_get(XGICR, 0x38); + if ((tmp & 0x03) == 0x03) { + /* XGI_Pr.XGI_UseLCDA = 1; */ + } else { /* Currently on LCDA? - *(Some BIOSes leave CR38) */ - tmp = xgifb_reg_get(XGICR, 0x38); - if ((tmp & 0x03) == 0x03) { + *(Some newer BIOSes set D0 in CR35) */ + tmp = xgifb_reg_get(XGICR, 0x35); + if (tmp & 0x01) { /* XGI_Pr.XGI_UseLCDA = 1; */ } else { - /* Currently on LCDA? - *(Some newer BIOSes set D0 in CR35) */ - tmp = xgifb_reg_get(XGICR, 0x35); - if (tmp & 0x01) { - /* XGI_Pr.XGI_UseLCDA = 1; */ - } else { - tmp = xgifb_reg_get(XGICR, - 0x30); - if (tmp & 0x20) { - tmp = xgifb_reg_get( - XGIPART1, 0x13); - if (tmp & 0x04) { - /* XGI_Pr.XGI_UseLCDA = 1; */ - } + tmp = xgifb_reg_get(XGICR, + 0x30); + if (tmp & 0x20) { + tmp = xgifb_reg_get( + XGIPART1, 0x13); + if (tmp & 0x04) { + /* XGI_Pr.XGI_UseLCDA = 1; */ } } } } - - } - - if (xgifb_mode_idx >= 0) - xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx); - - if (xgifb_mode_idx < 0) { - switch (xgi_video_info.disp_state & DISPTYPE_DISP2) { - case DISPTYPE_LCD: - xgifb_mode_idx = DEFAULT_LCDMODE; - if (xgi_video_info.chip == XG21) - xgifb_mode_idx = - XGIfb_GetXG21DefaultLVDSModeIdx(); - break; - case DISPTYPE_TV: - xgifb_mode_idx = DEFAULT_TVMODE; - break; - default: - xgifb_mode_idx = DEFAULT_MODE; - break; - } } - XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no; + } - /* yilin set default refresh rate */ - if (xgi_video_info.refresh_rate == 0) - xgi_video_info.refresh_rate = 60; - if (XGIfb_search_refresh_rate( - xgi_video_info.refresh_rate) == 0) { - XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx; - xgi_video_info.refresh_rate = 60; - } + if (xgifb_mode_idx >= 0) + xgifb_mode_idx = XGIfb_validate_mode(xgifb_mode_idx); - xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp; - xgi_video_info.video_vwidth = - xgi_video_info.video_width = - XGIbios_mode[xgifb_mode_idx].xres; - xgi_video_info.video_vheight = - xgi_video_info.video_height = - XGIbios_mode[xgifb_mode_idx].yres; - xgi_video_info.org_x = xgi_video_info.org_y = 0; - xgi_video_info.video_linelength = - xgi_video_info.video_width * - (xgi_video_info.video_bpp >> 3); - switch (xgi_video_info.video_bpp) { - case 8: - xgi_video_info.DstColor = 0x0000; - xgi_video_info.XGI310_AccelDepth = 0x00000000; - xgi_video_info.video_cmap_len = 256; - break; - case 16: - xgi_video_info.DstColor = 0x8000; - xgi_video_info.XGI310_AccelDepth = 0x00010000; - xgi_video_info.video_cmap_len = 16; + if (xgifb_mode_idx < 0) { + switch (xgi_video_info.disp_state & DISPTYPE_DISP2) { + case DISPTYPE_LCD: + xgifb_mode_idx = DEFAULT_LCDMODE; + if (xgi_video_info.chip == XG21) + xgifb_mode_idx = + XGIfb_GetXG21DefaultLVDSModeIdx(); break; - case 32: - xgi_video_info.DstColor = 0xC000; - xgi_video_info.XGI310_AccelDepth = 0x00020000; - xgi_video_info.video_cmap_len = 16; + case DISPTYPE_TV: + xgifb_mode_idx = DEFAULT_TVMODE; break; default: - xgi_video_info.video_cmap_len = 16; - printk(KERN_INFO "XGIfb: Unsupported depth %d", - xgi_video_info.video_bpp); + xgifb_mode_idx = DEFAULT_MODE; break; } + } - printk(KERN_INFO "XGIfb: Default mode is %dx%dx%d (%dHz)\n", - xgi_video_info.video_width, - xgi_video_info.video_height, - xgi_video_info.video_bpp, - xgi_video_info.refresh_rate); - - default_var.xres = - default_var.xres_virtual = - xgi_video_info.video_width; - default_var.yres = - default_var.yres_virtual = - xgi_video_info.video_height; - default_var.bits_per_pixel = xgi_video_info.video_bpp; - - XGIfb_bpp_to_var(&default_var); - - default_var.pixclock = (u32) (1000000000 / - XGIfb_mode_rate_to_dclock(&XGI_Pr, &XGIhw_ext, - XGIfb_mode_no, XGIfb_rate_idx)); - - if (XGIfb_mode_rate_to_ddata(&XGI_Pr, &XGIhw_ext, - XGIfb_mode_no, XGIfb_rate_idx, - &default_var.left_margin, &default_var.right_margin, - &default_var.upper_margin, &default_var.lower_margin, - &default_var.hsync_len, &default_var.vsync_len, - &default_var.sync, &default_var.vmode)) { - - if ((default_var.vmode & FB_VMODE_MASK) == - FB_VMODE_INTERLACED) { - default_var.yres <<= 1; - default_var.yres_virtual <<= 1; - } else if ((default_var.vmode & FB_VMODE_MASK) == - FB_VMODE_DOUBLE) { - default_var.pixclock >>= 1; - default_var.yres >>= 1; - default_var.yres_virtual >>= 1; - } - - } + XGIfb_mode_no = XGIbios_mode[xgifb_mode_idx].mode_no; - fb_info->flags = FBINFO_FLAG_DEFAULT; - fb_info->var = default_var; - fb_info->fix = XGIfb_fix; - fb_info->par = &xgi_video_info; - fb_info->screen_base = xgi_video_info.video_vbase; - fb_info->fbops = &XGIfb_ops; - XGIfb_get_fix(&fb_info->fix, -1, fb_info); - fb_info->pseudo_palette = pseudo_palette; + /* yilin set default refresh rate */ + if (xgi_video_info.refresh_rate == 0) + xgi_video_info.refresh_rate = 60; + if (XGIfb_search_refresh_rate( + xgi_video_info.refresh_rate) == 0) { + XGIfb_rate_idx = XGIbios_mode[xgifb_mode_idx].rate_idx; + xgi_video_info.refresh_rate = 60; + } - fb_alloc_cmap(&fb_info->cmap, 256 , 0); + xgi_video_info.video_bpp = XGIbios_mode[xgifb_mode_idx].bpp; + xgi_video_info.video_vwidth = + xgi_video_info.video_width = + XGIbios_mode[xgifb_mode_idx].xres; + xgi_video_info.video_vheight = + xgi_video_info.video_height = + XGIbios_mode[xgifb_mode_idx].yres; + xgi_video_info.org_x = xgi_video_info.org_y = 0; + xgi_video_info.video_linelength = + xgi_video_info.video_width * + (xgi_video_info.video_bpp >> 3); + switch (xgi_video_info.video_bpp) { + case 8: + xgi_video_info.DstColor = 0x0000; + xgi_video_info.XGI310_AccelDepth = 0x00000000; + xgi_video_info.video_cmap_len = 256; + break; + case 16: + xgi_video_info.DstColor = 0x8000; + xgi_video_info.XGI310_AccelDepth = 0x00010000; + xgi_video_info.video_cmap_len = 16; + break; + case 32: + xgi_video_info.DstColor = 0xC000; + xgi_video_info.XGI310_AccelDepth = 0x00020000; + xgi_video_info.video_cmap_len = 16; + break; + default: + xgi_video_info.video_cmap_len = 16; + printk(KERN_INFO "XGIfb: Unsupported depth %d", + xgi_video_info.video_bpp); + break; + } -#ifdef CONFIG_MTRR - xgi_video_info.mtrr = mtrr_add( - (unsigned int) xgi_video_info.video_base, - (unsigned int) xgi_video_info.video_size, - MTRR_TYPE_WRCOMB, 1); - if (xgi_video_info.mtrr) - printk(KERN_INFO "XGIfb: Added MTRRs\n"); -#endif + printk(KERN_INFO "XGIfb: Default mode is %dx%dx%d (%dHz)\n", + xgi_video_info.video_width, + xgi_video_info.video_height, + xgi_video_info.video_bpp, + xgi_video_info.refresh_rate); - if (register_framebuffer(fb_info) < 0) { - ret = -EINVAL; - goto error_1; + default_var.xres = + default_var.xres_virtual = + xgi_video_info.video_width; + default_var.yres = + default_var.yres_virtual = + xgi_video_info.video_height; + default_var.bits_per_pixel = xgi_video_info.video_bpp; + + XGIfb_bpp_to_var(&default_var); + + default_var.pixclock = (u32) (1000000000 / + XGIfb_mode_rate_to_dclock(&XGI_Pr, &XGIhw_ext, + XGIfb_mode_no, XGIfb_rate_idx)); + + if (XGIfb_mode_rate_to_ddata(&XGI_Pr, &XGIhw_ext, + XGIfb_mode_no, XGIfb_rate_idx, + &default_var.left_margin, &default_var.right_margin, + &default_var.upper_margin, &default_var.lower_margin, + &default_var.hsync_len, &default_var.vsync_len, + &default_var.sync, &default_var.vmode)) { + + if ((default_var.vmode & FB_VMODE_MASK) == + FB_VMODE_INTERLACED) { + default_var.yres <<= 1; + default_var.yres_virtual <<= 1; + } else if ((default_var.vmode & FB_VMODE_MASK) == + FB_VMODE_DOUBLE) { + default_var.pixclock >>= 1; + default_var.yres >>= 1; + default_var.yres_virtual >>= 1; } - XGIfb_registered = 1; + } + + fb_info->flags = FBINFO_FLAG_DEFAULT; + fb_info->var = default_var; + fb_info->fix = XGIfb_fix; + fb_info->par = &xgi_video_info; + fb_info->screen_base = xgi_video_info.video_vbase; + fb_info->fbops = &XGIfb_ops; + XGIfb_get_fix(&fb_info->fix, -1, fb_info); + fb_info->pseudo_palette = pseudo_palette; - printk(KERN_INFO "fb%d: %s frame buffer device, Version %d.%d.%02d\n", - fb_info->node, myid, VER_MAJOR, VER_MINOR, VER_LEVEL); + fb_alloc_cmap(&fb_info->cmap, 256 , 0); + +#ifdef CONFIG_MTRR + xgi_video_info.mtrr = mtrr_add( + (unsigned int) xgi_video_info.video_base, + (unsigned int) xgi_video_info.video_size, + MTRR_TYPE_WRCOMB, 1); + if (xgi_video_info.mtrr) + printk(KERN_INFO "XGIfb: Added MTRRs\n"); +#endif + if (register_framebuffer(fb_info) < 0) { + ret = -EINVAL; + goto error_1; } dumpVGAReg(); @@ -2543,7 +2507,7 @@ static struct pci_driver xgifb_driver = { .remove = __devexit_p(xgifb_remove) }; -XGIINITSTATIC int __init xgifb_init(void) +static int __init xgifb_init(void) { char *option = NULL; @@ -2564,26 +2528,26 @@ module_init(xgifb_init); #ifdef MODULE -static char *mode = NULL; -static int vesa = 0; -static unsigned int rate = 0; -static unsigned int mem = 0; -static char *forcecrt2type = NULL; +static char *mode; +static int vesa; +static unsigned int rate; +static unsigned int mem; +static char *forcecrt2type; static int forcecrt1 = -1; static int pdc = -1; static int pdc1 = -1; static int noypan = -1; static int userom = -1; static int useoem = -1; -static char *tvstandard = NULL; -static int nocrt2rate = 0; +static char *tvstandard; +static int nocrt2rate; static int scalelcd = -1; -static char *specialtiming = NULL; +static char *specialtiming; static int lvdshl = -1; -static int tvxposoffset = 0, tvyposoffset = 0; +static int tvxposoffset, tvyposoffset; #if !defined(__i386__) && !defined(__x86_64__) -static int resetcard = 0; -static int videoram = 0; +static int resetcard; +static int videoram; #endif MODULE_DESCRIPTION("Z7 Z9 Z9S Z11 framebuffer device driver"); diff --git a/drivers/staging/xgifb/XGIfb.h b/drivers/staging/xgifb/XGIfb.h index 45b6015..5d81cb6 100644 --- a/drivers/staging/xgifb/XGIfb.h +++ b/drivers/staging/xgifb/XGIfb.h @@ -7,11 +7,9 @@ #define DISPTYPE_CRT2 0x00000004L #define DISPTYPE_LCD 0x00000002L #define DISPTYPE_TV 0x00000001L -#define DISPTYPE_DISP1 DISPTYPE_CRT1 #define DISPTYPE_DISP2 (DISPTYPE_CRT2 | DISPTYPE_LCD | DISPTYPE_TV) #define DISPMODE_SINGLE 0x00000020L #define DISPMODE_MIRROR 0x00000010L -#define DISPMODE_DUALVIEW 0x00000040L #define HASVB_NONE 0x00 #define HASVB_301 0x01 @@ -19,13 +17,8 @@ #define HASVB_TRUMPION 0x04 #define HASVB_LVDS_CHRONTEL 0x10 #define HASVB_302 0x20 -#define HASVB_303 0x40 #define HASVB_CHRONTEL 0x80 -#ifndef XGIFB_ID -#define XGIFB_ID 0x53495346 /* Identify myself with 'XGIF' */ -#endif - enum XGI_CHIP_TYPE { XG40 = 32, XG41, @@ -47,11 +40,6 @@ enum xgi_tvtype { }; enum xgi_tv_plug { /* vicki@030226 */ -/* TVPLUG_Legacy = 0, */ -/* TVPLUG_COMPOSITE, */ -/* TVPLUG_SVIDEO, */ -/* TVPLUG_SCART, */ -/* TVPLUG_TOTAL */ TVPLUG_UNKNOWN = 0, TVPLUG_COMPOSITE = 1, TVPLUG_SVIDEO = 2, diff --git a/drivers/staging/xgifb/vb_def.h b/drivers/staging/xgifb/vb_def.h index 339c071..0684686 100644 --- a/drivers/staging/xgifb/vb_def.h +++ b/drivers/staging/xgifb/vb_def.h @@ -3,261 +3,48 @@ #ifndef _INITDEF_ #define _INITDEF_ -#ifndef NewScratch -#define NewScratch -#endif -/* shampoo */ - -#define SEQ_ADDRESS_PORT 0x0014 -#define SEQ_DATA_PORT 0x0015 -#define MISC_OUTPUT_REG_READ_PORT 0x001C -#define MISC_OUTPUT_REG_WRITE_PORT 0x0012 -#define GRAPH_DATA_PORT 0x1F -#define GRAPH_ADDRESS_PORT 0x1E -#define XGI_MASK_DUAL_CHIP 0x04 /* SR3A */ -#define CRTC_ADDRESS_PORT_COLOR 0x0024 -#define VIDEO_SUBSYSTEM_ENABLE_PORT 0x0013 -#define PCI_COMMAND 0x04 - -/* ~shampoo */ - - -#define VB_XGI301 0x0001 /*301b*/ -#define VB_XGI301B 0x0002 -#define VB_XGI302B 0x0004 -#define VB_XGI301LV 0x0008 /*301lv*/ -#define VB_XGI302LV 0x0010 #define VB_XGI301C 0x0020 /* for 301C */ -#define VB_NoLCD 0x8000 /*end 301b*/ -#define VB_YPbPrInfo 0x07 /*301lv*/ -#define VB_YPbPr525i 0x00 #define VB_YPbPr525p 0x01 #define VB_YPbPr750p 0x02 #define VB_YPbPr1080i 0x03 -/* #define CRT1Len 17 */ #define LVDSCRT1Len 15 -#define CHTVRegDataLen 5 - -/* #define ModeInfoFlag 0x07 */ -/* #define IsTextMode 0x07 */ -/* #define ModeText 0x00 */ -/* #define ModeCGA 0x01 */ -/* #define ModeEGA 0x02 */ -/* #define ModeVGA 0x03 */ -/* #define Mode15Bpp 0x04 */ -/* #define Mode16Bpp 0x05 */ -/* #define Mode24Bpp 0x06 */ -/* #define Mode32Bpp 0x07 */ - -/* #define DACInfoFlag 0x18 */ -/* #define MemoryInfoFlag 0x1E0 */ -/* #define MemorySizeShift 0x05 */ - -#define Charx8Dot 0x0200 -#define LineCompareOff 0x0400 -#define CRT2Mode 0x0800 -#define HalfDCLK 0x1000 -#define NoSupportSimuTV 0x2000 -#define DoubleScanMode 0x8000 - -#define SupportAllCRT2 0x0078 -#define SupportTV 0x0008 -#define SupportHiVisionTV 0x0010 -#define SupportLCD 0x0020 -#define SupportRAMDAC2 0x0040 -#define NoSupportTV 0x0070 -#define NoSupportHiVisionTV 0x0060 -#define NoSupportLCD 0x0058 + #define SupportCHTV 0x0800 #define SupportCRT2in301C 0x0100 /* for 301C */ -#define SupportTV1024 0x0800 /*301b*/ -#define SupportYPbPr 0x1000 /*301lv*/ -#define InterlaceMode 0x0080 -#define SyncPP 0x0000 -#define SyncPN 0x4000 -#define SyncNP 0x8000 -/* #define SyncNN 0xc000 */ -#define ECLKindex0 0x0000 -#define ECLKindex1 0x0100 -#define ECLKindex2 0x0200 -#define ECLKindex3 0x0300 -#define ECLKindex4 0x0400 - -#define SetSimuScanMode 0x0001 -#define SwitchToCRT2 0x0002 -/* #define SetCRT2ToTV 0x009C */ -#define SetCRT2ToAVIDEO 0x0004 -#define SetCRT2ToSVIDEO 0x0008 -#define SetCRT2ToSCART 0x0010 -#define SetCRT2ToLCD 0x0020 -#define SetCRT2ToRAMDAC 0x0040 -#define SetCRT2ToHiVisionTV 0x0080 -#define SetNTSCTV 0x0000 -/* #define SetPALTV 0x0100 */ -#define SetInSlaveMode 0x0200 -#define SetNotSimuMode 0x0400 -#define SetNotSimuTVMode 0x0400 -#define SetDispDevSwitch 0x0800 -#define LoadDACFlag 0x1000 -#define DisableCRT2Display 0x2000 -#define DriverMode 0x4000 -#define HotKeySwitch 0x8000 #define SetCHTVOverScan 0x8000 -/* #define SetCRT2ToLCDA 0x8000 301b */ #define PanelRGB18Bit 0x0100 #define PanelRGB24Bit 0x0000 -#define TVOverScan 0x10 -#define TVOverScanShift 4 -#define ClearBufferFlag 0x20 -#define EnableDualEdge 0x01 /*301b*/ -#define SetToLCDA 0x02 - -#define YPbPrModeInfo 0x38 -/* #define YPbPrMode525i 0x00 */ -/* #define YPbPrMode525p 0x08 */ -/* #define YPbPrMode750p 0x10 */ -/* #define YPbPrMode1080i 0x18 */ - -#define SetSCARTOutput 0x01 -#define BoardTVType 0x02 -#define EnablePALMN 0x40 -/* #define ProgrammingCRT2 0x01 */ -/* #define TVSimuMode 0x02 */ -/* #define RPLLDIV2XO 0x04 */ -/* #define LCDVESATiming 0x08 */ -/* #define EnableLVDSDDA 0x10 */ -#define SetDispDevSwitchFlag 0x20 -#define CheckWinDos 0x40 -#define SetJDOSMode 0x80 - #define Panel320x480 0x07 /*fstn*/ /* [ycchen] 02/12/03 Modify for Multi-Sync. LCD Support */ #define PanelResInfo 0x1F /* CR36 Panel Type/LCDResInfo */ -#define PanelRefInfo 0x60 #define Panel800x600 0x01 #define Panel1024x768 0x02 #define Panel1024x768x75 0x22 #define Panel1280x1024 0x03 #define Panel1280x1024x75 0x23 #define Panel640x480 0x04 -#define Panel1024x600 0x05 -#define Panel1152x864 0x06 #define Panel1280x960 0x07 -#define Panel1152x768 0x08 #define Panel1400x1050 0x09 -#define Panel1280x768 0x0A #define Panel1600x1200 0x0B #define PanelRef60Hz 0x00 #define PanelRef75Hz 0x20 -#define LCDRGB18Bit 0x01 - -#define ExtChipTrumpion 0x06 -#define ExtChipCH7005 0x08 -#define ExtChipMitacTV 0x0a -#define LCDNonExpanding 0x10 -#define LCDNonExpandingShift 4 -#define LCDSync 0x20 -#define LCDSyncBit 0xe0 -#define LCDSyncShift 6 - -/* #define DDC2DelayTime 300 */ #define CRT2DisplayFlag 0x2000 -/* #define LCDDataLen 8 */ -/* #define HiTVDataLen 12 */ -/* #define TVDataLen 16 */ -/* #define SetPALTV 0x0100 */ -#define HalfDCLK 0x1000 -#define NTSCHT 1716 -#define NTSCVT 525 -#define PALHT 1728 -#define PALVT 625 -#define StHiTVHT 892 -#define StHiTVVT 1126 -#define StHiTextTVHT 1000 -#define StHiTextTVVT 1126 -#define ExtHiTVHT 2100 -#define ExtHiTVVT 1125 - -#define St750pTVHT 1716 -#define St750pTVVT 525 -#define Ext750pTVHT 1716 -#define Ext750pTVVT 525 -#define St525pTVHT 1716 -#define St525pTVVT 525 -#define Ext525pTVHT 1716 -#define Ext525pTVVT 525 -#define St525iTVHT 1716 -#define St525iTVVT 525 -#define Ext525iTVHT 1716 -#define Ext525iTVVT 525 - -#define VCLKStartFreq 25 -#define SoftDramType 0x80 -#define VCLK40 0x04 - -#define VCLK162 0x21 - -#define LCDRGB18Bit 0x01 -#define LoadDACFlag 0x1000 -#define AfterLockCRT2 0x4000 -#define SetCRT2ToAVIDEO 0x0004 -#define SetCRT2ToSCART 0x0010 -#define Ext2StructSize 5 - #define YPbPr525iVCLK 0x03B #define YPbPr525iVCLK_2 0x03A -#define SwitchToCRT2 0x0002 -/* #define LCDVESATiming 0x08 */ -#define SetSCARTOutput 0x01 -#define AVIDEOSense 0x01 -#define SVIDEOSense 0x02 -#define SCARTSense 0x04 -#define LCDSense 0x08 -#define Monitor1Sense 0x20 -#define Monitor2Sense 0x10 -#define HiTVSense 0x40 -#define BoardTVType 0x02 -#define HotPlugFunction 0x08 -#define StStructSize 0x06 - - #define XGI_CRT2_PORT_00 (0x00 - 0x030) #define XGI_CRT2_PORT_04 (0x04 - 0x030) #define XGI_CRT2_PORT_10 (0x10 - 0x30) #define XGI_CRT2_PORT_12 (0x12 - 0x30) #define XGI_CRT2_PORT_14 (0x14 - 0x30) - -#define LCDNonExpanding 0x10 -#define ADR_CRT2PtrData 0x20E -#define offset_Zurac 0x210 -#define ADR_LVDSDesPtrData 0x212 -#define ADR_LVDSCRT1DataPtr 0x214 -#define ADR_CHTVVCLKPtr 0x216 -#define ADR_CHTVRegDataPtr 0x218 - -#define LVDSDataLen 6 -/* #define EnableLVDSDDA 0x10 */ -/* #define LVDSDesDataLen 3 */ -#define ActiveNonExpanding 0x40 -#define ActiveNonExpandingShift 6 -/* #define ActivePAL 0x20 */ -#define ActivePALShift 5 -/* #define ModeSwitchStatus 0x0F */ -#define SoftTVType 0x40 -#define SoftSettingAddr 0x52 -#define ModeSettingAddr 0x53 - -/* #define SelectCRT1Rate 0x4 */ - #define _PanelType00 0x00 #define _PanelType01 0x08 #define _PanelType02 0x10 @@ -275,173 +62,26 @@ #define _PanelType0E 0x70 #define _PanelType0F 0x78 -/* 1: XGI is primary vga 0:XGI is secondary vga */ -#define PRIMARY_VGA 0 -#define BIOSIDCodeAddr 0x235 -#define OEMUtilIDCodeAddr 0x237 -#define VBModeIDTableAddr 0x239 -#define OEMTVPtrAddr 0x241 -#define PhaseTableAddr 0x243 -#define NTSCFilterTableAddr 0x245 -#define PALFilterTableAddr 0x247 -#define OEMLCDPtr_1Addr 0x249 -#define OEMLCDPtr_2Addr 0x24B -#define LCDHPosTable_1Addr 0x24D -#define LCDHPosTable_2Addr 0x24F -#define LCDVPosTable_1Addr 0x251 -#define LCDVPosTable_2Addr 0x253 -#define OEMLCDPIDTableAddr 0x255 - -#define VBModeStructSize 5 -#define PhaseTableSize 4 -#define FilterTableSize 4 -#define LCDHPosTableSize 7 -#define LCDVPosTableSize 5 -#define OEMLVDSPIDTableSize 4 -#define LVDSHPosTableSize 4 -#define LVDSVPosTableSize 6 - -#define VB_ModeID 0 -#define VB_TVTableIndex 1 -#define VB_LCDTableIndex 2 -#define VB_LCDHIndex 3 -#define VB_LCDVIndex 4 - -#define OEMLCDEnable 0x0001 -#define OEMLCDDelayEnable 0x0002 -#define OEMLCDPOSEnable 0x0004 -#define OEMTVEnable 0x0100 -#define OEMTVDelayEnable 0x0200 -#define OEMTVFlickerEnable 0x0400 -#define OEMTVPhaseEnable 0x0800 -#define OEMTVFilterEnable 0x1000 - -#define OEMLCDPanelIDSupport 0x0080 - -/* #define LCDVESATiming 0x0001 //LCD Info CR37 */ -/* #define EnableLVDSDDA 0x0002 */ -#define EnableScalingLCD 0x0008 -#define SetPWDEnable 0x0004 -#define SetLCDtoNonExpanding 0x0010 -/* #define SetLCDPolarity 0x00E0 */ -#define SetLCDDualLink 0x0100 -#define SetLCDLowResolution 0x0200 -#define SetLCDStdMode 0x0400 -#define SetTVStdMode 0x0200 -#define SetTVLowResolution 0x0400 /* ============================================================= for 310 ============================================================== */ -#define SoftDRAMType 0x80 -#define SoftSetting_OFFSET 0x52 -#define SR07_OFFSET 0x7C -#define SR15_OFFSET 0x7D -#define SR16_OFFSET 0x81 -#define SR17_OFFSET 0x85 -#define SR19_OFFSET 0x8D -#define SR1F_OFFSET 0x99 -#define SR21_OFFSET 0x9A -#define SR22_OFFSET 0x9B -#define SR23_OFFSET 0x9C -#define SR24_OFFSET 0x9D -#define SR25_OFFSET 0x9E -#define SR31_OFFSET 0x9F -#define SR32_OFFSET 0xA0 -#define SR33_OFFSET 0xA1 - -#define CR40_OFFSET 0xA2 -#define SR25_1_OFFSET 0xF6 -#define CR49_OFFSET 0xF7 - -#define VB310Data_1_2_Offset 0xB6 -#define VB310Data_4_D_Offset 0xB7 -#define VB310Data_4_E_Offset 0xB8 -#define VB310Data_4_10_Offset 0xBB - -#define RGBSenseDataOffset 0xBD -#define YCSenseDataOffset 0xBF -#define VideoSenseDataOffset 0xC1 -#define OutputSelectOffset 0xF3 - -#define ECLK_MCLK_DISTANCE 0x14 -#define VBIOSTablePointerStart 0x200 -#define StandTablePtrOffset (VBIOSTablePointerStart+0x02) -#define EModeIDTablePtrOffset (VBIOSTablePointerStart+0x04) -#define CRT1TablePtrOffset (VBIOSTablePointerStart+0x06) -#define ScreenOffsetPtrOffset (VBIOSTablePointerStart+0x08) -#define VCLKDataPtrOffset (VBIOSTablePointerStart+0x0A) -#define MCLKDataPtrOffset (VBIOSTablePointerStart+0x0E) -#define CRT2PtrDataPtrOffset (VBIOSTablePointerStart+0x10) -#define TVAntiFlickPtrOffset (VBIOSTablePointerStart+0x12) -#define TVDelayPtr1Offset (VBIOSTablePointerStart+0x14) -#define TVPhaseIncrPtr1Offset (VBIOSTablePointerStart+0x16) -#define TVYFilterPtr1Offset (VBIOSTablePointerStart+0x18) -#define LCDDelayPtr1Offset (VBIOSTablePointerStart+0x20) -#define TVEdgePtr1Offset (VBIOSTablePointerStart+0x24) -#define CRT2Delay1Offset (VBIOSTablePointerStart+0x28) -#define LCDDataDesOffset (VBIOSTablePointerStart-0x02) -#define LCDDataPtrOffset (VBIOSTablePointerStart+0x2A) -#define LCDDesDataPtrOffset (VBIOSTablePointerStart+0x2C) /* add LCDDataList for GetLCDPtr */ #define LCDDataList (VBIOSTablePointerStart+0x22) -/* add TVDataList for GetTVPtr */ -#define TVDataList (VBIOSTablePointerStart+0x36) /* */ /* Modify from 310.inc */ /* */ /* */ - -#define ShowMsgFlag 0x20 /* SoftSetting */ -#define ShowVESAFlag 0x10 -#define HotPlugFunction 0x08 #define ModeSoftSetting 0x04 -#define TVSoftSetting 0x02 -#define LCDSoftSetting 0x01 -#define GatingCRTinLCDA 0x10 -#define SetHiTVOutput 0x08 -#define SetYPbPrOutput 0x04 #define BoardTVType 0x02 -#define SetSCARTOutput 0x01 - -/* TVModeSetting, Others as same as CR30 */ -#define ModeSettingYPbPr 0x02 - -/* TVModeSetting same as CR35 */ - -/* LCDModeSetting same as CR37 */ - -#define EnableNewTVFont 0x10 /* MiscCapability */ - -#define EnableLCDOutput 0x80 /* LCDCfgSetting */ #define SoftDRAMType 0x80 /* DRAMSetting */ -#define SoftDRAMConfig 0x40 -#define MosSelDRAMType 0x20 -#define SDRAM 000h -#define SGRAM 0x01 -#define ESDRAM 0x02 - -#define EnableAGPCfgSetting 0x01 /* AGPCfgSetting */ /* ---------------- SetMode Stack */ #define CRT1Len 15 #define VCLKLen 4 -#define DefThreshold 0x0100 -#define ExtRegsSize ((57+8+37+70+63+28+768+1)/64+1) - -#define VGA_XGI315 0x0001 /* VGA Type Info */ -#define VGA_SNewis315e 0x0002 /* 315 series */ -#define VGA_XGI550 0x0004 -#define VGA_XGI640 0x0008 -#define VGA_XGI740 0x0010 -#define VGA_XGI650 0x0020 -#define VGA_XGI650M 0x0040 -#define VGA_XGI651 0x0080 #define VGA_XGI340 0x0001 /* 340 series */ -#define VGA_XGI330 0x0001 /* 330 series */ -#define VGA_XGI660 0x0001 /* 660 series */ #define VB_XGI301 0x0001 /* VB Type Info */ #define VB_XGI301B 0x0002 /* 301 series */ @@ -452,32 +92,16 @@ #define VB_LVDS_NS 0x0001 /* 3rd party chip */ #define VB_CH7017 0x0002 #define VB_CH7007 0x0080 /* [Billy] 07/05/03 */ -/* #define VB_LVDS_SI 0x0004 */ #define ModeInfoFlag 0x0007 -#define IsTextMode 0x0007 #define ModeText 0x0000 -#define ModeCGA 0x0001 #define ModeEGA 0x0002 /* 16 colors mode */ #define ModeVGA 0x0003 /* 256 colors mode */ -#define Mode15Bpp 0x0004 /* 15 Bpp Color Mode */ -#define Mode16Bpp 0x0005 /* 16 Bpp Color Mode */ -#define Mode24Bpp 0x0006 /* 24 Bpp Color Mode */ -#define Mode32Bpp 0x0007 /* 32 Bpp Color Mode */ #define DACInfoFlag 0x0018 -#define MONODAC 0x0000 -#define CGADAC 0x0008 -#define EGADAC 0x0010 -#define VGADAC 0x0018 #define MemoryInfoFlag 0x01e0 #define MemorySizeShift 5 -#define Need1MSize 0x0000 -#define Need2MSize 0x0020 -#define Need4MSize 0x0060 -#define Need8MSize 0x00e0 -#define Need16MSize 0x01e0 #define Charx8Dot 0x0200 #define LineCompareOff 0x0400 @@ -487,11 +111,7 @@ #define DoubleScanMode 0x8000 /* -------------- Ext_InfoFlag */ -#define SupportModeInfo 0x0007 -#define Support256 0x0003 -#define Support15Bpp 0x0004 #define Support16Bpp 0x0005 -#define Support24Bpp 0x0006 #define Support32Bpp 0x0007 #define SupportAllCRT2 0x0078 @@ -513,7 +133,6 @@ /* -------------- SetMode Stack/Scratch */ #define SetSimuScanMode 0x0001 /* VBInfo/CR30 & CR31 */ #define SwitchToCRT2 0x0002 -#define SetCRT2ToTV1 0x009C #define SetCRT2ToTV 0x089C #define SetCRT2ToAVIDEO 0x0004 #define SetCRT2ToSVIDEO 0x0008 @@ -524,23 +143,16 @@ #define SetCRT2ToLCDA 0x0100 #define SetInSlaveMode 0x0200 #define SetNotSimuMode 0x0400 -#define HKEventMode 0x0800 #define SetCRT2ToYPbPr 0x0800 #define LoadDACFlag 0x1000 #define DisableCRT2Display 0x2000 #define DriverMode 0x4000 #define SetCRT2ToDualEdge 0x8000 -#define HotKeySwitch 0x8000 #define ProgrammingCRT2 0x0001 /* Set Flag */ #define EnableVCMode 0x0002 -#define SetHKEventMode 0x0004 #define ReserveTVOption 0x0008 -#define DisableRelocateIO 0x0010 #define Win9xDOSMode 0x0020 -#define JDOSMode 0x0040 -/* #define SetWin9xforJap 0x0080 // not used now */ -/* #define SetWin9xforKorea 0x0100 // not used now */ #define GatingCRT 0x0800 #define DisableChB 0x1000 #define EnableChB 0x2000 @@ -552,15 +164,11 @@ #define SetNTSCJ 0x0002 #define SetPALMTV 0x0004 #define SetPALNTV 0x0008 -#define SetCHTVUnderScan 0x0000 -/* #define SetCHTVOverScan 0x0010 */ #define SetYPbPrMode525i 0x0020 #define SetYPbPrMode525p 0x0040 #define SetYPbPrMode750p 0x0080 #define SetYPbPrMode1080i 0x0100 -#define SetTVStdMode 0x0200 #define SetTVLowResolution 0x0400 -#define SetTVSimuMode 0x0800 #define TVSimuMode 0x0800 #define RPLLDIV2XO 0x1000 #define NTSC1024x768 0x2000 @@ -571,38 +179,20 @@ #define EnableScalingLCD 0x0008 #define SetPWDEnable 0x0004 #define SetLCDtoNonExpanding 0x0010 -#define SetLCDPolarity 0x00e0 #define SetLCDDualLink 0x0100 #define SetLCDLowResolution 0x0200 #define SetLCDStdMode 0x0400 /* LCD Capability shampoo */ #define DefaultLCDCap 0x80ea -#define RLVDSDHL00 0x0000 -#define RLVDSDHL01 0x0001 -#define RLVDSDHL10 0x0002 /* default */ -#define RLVDSDHL11 0x0003 #define EnableLCD24bpp 0x0004 /* default */ #define DisableLCD24bpp 0x0000 -#define RLVDSClkSFT0 0x0000 -#define RLVDSClkSFT1 0x0008 /* default */ -#define EnableLVDSDCBal 0x0010 -#define DisableLVDSDCBal 0x0000 /* default */ -#define SinglePolarity 0x0020 /* default */ -#define MultiPolarity 0x0000 #define LCDPolarity 0x00c0 /* default: SyncNN */ -#define LCDSingleLink 0x0000 /* default */ #define LCDDualLink 0x0100 #define EnableSpectrum 0x0200 -#define DisableSpectrum 0x0000 /* default */ #define PWDEnable 0x0400 -#define PWDDisable 0x0000 /* default */ -#define PWMEnable 0x0800 -#define PWMDisable 0x0000 /* default */ #define EnableVBCLKDRVLOW 0x4000 -#define EnableVBCLKDRVHigh 0x0000 /* default */ #define EnablePLLSPLOW 0x8000 -#define EnablePLLSPHigh 0x0000 /* default */ #define LCDBToA 0x20 /* LCD SetFlag */ #define StLCDBToA 0x40 @@ -616,187 +206,51 @@ #define Monitor1Sense 0x20 #define HiTVSense 0x40 -#ifdef NewScratch #define YPbPrSense 0x80 /* NEW SCRATCH */ -#endif #define TVSense 0xc7 #define TVOverScan 0x10 /* CR35 */ -#define TVOverScanShift 4 -#ifdef NewScratch -#define NTSCMode 0x00 -#define PALMode 0x00 -#define NTSCJMode 0x02 -#define PALMNMode 0x0c #define YPbPrMode 0xe0 #define YPbPrMode525i 0x00 #define YPbPrMode525p 0x20 #define YPbPrMode750p 0x40 #define YPbPrMode1080i 0x60 -#else /* Old Scratch */ -#define ClearBufferFlag 0x20 -#endif #define LCDRGB18Bit 0x01 /* CR37 */ #define LCDNonExpanding 0x10 -#define LCDNonExpandingShift 4 #define LCDSync 0x20 #define LCDSyncBit 0xe0 /* H/V polarity & sync ID */ -#define LCDSyncShift 6 -#ifdef NewScratch #define ScalingLCD 0x08 -#else /* Old Scratch */ -#define ExtChipType 0x0e -#define ExtChip301 0x02 -#define ExtChipLVDS 0x04 -#define ExtChipCH7019 0x06 -#define ScalingLCD 0x10 -#endif #define EnableDualEdge 0x01 /* CR38 */ #define SetToLCDA 0x02 -#ifdef NewScratch #define SetYPbPr 0x04 -#define DisableChannelA 0x08 -#define DisableChannelB 0x10 -#define ExtChipType 0xe0 -#define ExtChip301 0x20 -#define ExtChipLVDS 0x40 -#define ExtChipCH7019 0x60 -#else /* Old Scratch */ -#define YPbPrSense 0x04 -#define SetYPbPr 0x08 -#define YPbPrMode 0x30 -#define YPbPrMode525i 0x00 -#define YPbPrMode525p 0x10 -#define YPbPrMode750p 0x20 -#define YPbPrMode1080i 0x30 -#define PALMNMode 0xc0 -#endif -#define BacklightControlBit 0x01 /* CR3A */ -#define Win9xforJap 0x40 -#define Win9xforKorea 0x80 - -#define ForceMDBits 0x07 /* CR3B */ -#define ForceMD_JDOS 0x00 -#define ForceMD_640x400T 0x01 -#define ForceMD_640x350T 0x02 -#define ForceMD_720x400T 0x03 -#define ForceMD_640x480E 0x04 -#define ForceMD_640x400E 0x05 -#define ForceP1Bit 0x10 -#define ForceP2Bit 0x20 -#define EnableForceMDinBIOS 0x40 -#define EnableForceMDinDrv 0x80 - -#ifdef NewScratch /* New Scratch */ /* ---------------------- VUMA Information */ -#define LCDSettingFromCMOS 0x04 /* CR3C */ -#define TVSettingFromCMOS 0x08 #define DisplayDeviceFromCMOS 0x10 -#define HKSupportInSBIOS 0x20 -#define OSDSupportInSBIOS 0x40 -#define DisableLogo 0x80 /* ---------------------- HK Evnet Definition */ -#define HKEvent 0x0f /* CR3D */ -#define HK_ModeSwitch 0x01 -#define HK_Expanding 0x02 -#define HK_OverScan 0x03 -#define HK_Brightness 0x04 -#define HK_Contrast 0x05 -#define HK_Mute 0x06 -#define HK_Volume 0x07 #define ModeSwitchStatus 0xf0 #define ActiveCRT1 0x10 #define ActiveLCD 0x0020 #define ActiveTV 0x40 #define ActiveCRT2 0x80 -#define TVSwitchStatus 0x1f /* CR3E */ #define ActiveAVideo 0x01 #define ActiveSVideo 0x02 #define ActiveSCART 0x04 #define ActiveHiTV 0x08 #define ActiveYPbPr 0x10 -#define EnableHKEvent 0x01 /* CR3F */ -#define EnableOSDEvent 0x02 -#define StartOSDEvent 0x04 -#define IgnoreHKEvent 0x08 -#define IgnoreOSDEvent 0x10 -#else /* Old Scratch */ -#define OSD_SBIOS 0x02 /* SR17 */ -#define DisableLogo 0x04 -#define SelectKDOS 0x08 -#define KorWinMode 0x10 -#define KorMode3Bit 0x0020 -#define PSCCtrlBit 0x40 -#define NPSCCtrlBitShift 6 -#define BlueScreenBit 0x80 - -#define HKEvent 0x0f /* CR79 */ -#define HK_ModeSwitch 0x01 -#define HK_Expanding 0x02 -#define HK_OverScan 0x03 -#define HK_Brightness 0x04 -#define HK_Contrast 0x05 -#define HK_Mute 0x06 -#define HK_Volume 0x07 -#define ActivePAL 0x0020 -#define ActivePALShift 5 -#define ActiveNonExpanding 0x40 -#define ActiveNonExpandingShift 6 -#define ActiveOverScan 0x80 -#define ActiveOverScanShift 7 - -#define ModeSwitchStatus 0x0b /* SR15 */ -#define ActiveCRT1 0x01 -#define ActiveLCD 0x02 -#define ActiveCRT2 0x08 - -#define TVSwitchStatus 0xf0 /* SR16 */ -#define TVConfigShift 3 -#define ActiveTV 0x01 -#define ActiveYPbPr 0x04 -#define ActiveAVideo 0x10 -#define ActiveSVideo 0x0020 -#define ActiveSCART 0x40 -#define ActiveHiTV 0x80 - -#define EnableHKEvent 0x01 /* CR7A */ -#define EnableOSDEvent 0x02 -#define StartOSDEvent 0x04 -#define CMOSSupport 0x08 -#define HotKeySupport 0x10 -#define IngoreHKOSDEvent 0x20 -#endif - -/* //------------- Misc. Definition */ -#define SelectCRT1Rate 00h -/* #define SelectCRT2Rate 04h */ - -#define DDC1DelayTime 1000 -#ifdef TRUMPION -#define DDC2DelayTime 15 -#else -#define DDC2DelayTime 150 -#endif - -#define R_FACTOR 04Dh -#define G_FACTOR 097h -#define B_FACTOR 01Ch /* --------------------------------------------------------- */ /* translated from asm code 301def.h */ /* */ /* --------------------------------------------------------- */ #define LCDDataLen 8 -#define HiTVDataLen 12 #define TVDataLen 12 #define LVDSCRT1Len_H 8 #define LVDSCRT1Len_V 7 @@ -806,7 +260,6 @@ #define LVDSDesDataLen2 8 #define LCDDesDataLen2 8 #define CHTVRegLen 16 -#define CHLVRegLen 12 #define StHiTVHT 892 #define StHiTVVT 1126 @@ -817,7 +270,6 @@ #define NTSCHT 1716 #define NTSCVT 525 #define NTSC1024x768HT 1908 -#define NTSC1024x768VT 525 #define PALHT 1728 #define PALVT 625 @@ -828,8 +280,6 @@ #define YPbPrTV750pHT 1650 #define YPbPrTV750pVT 750 -#define CRT2VCLKSel 0xc0 - #define CRT2Delay1 0x04 /* XGI301 */ #define CRT2Delay2 0x0A /* 301B,302 */ @@ -846,57 +296,41 @@ #define VCLK52_406 0x09 #define VCLK56_25 0x0A #define VCLK65 0x0B -#define VCLK67_765 0x0C #define VCLK68_179 0x0D #define VCLK72_852 0x0E #define VCLK75 0x0F -#define VCLK75_8 0x10 #define VCLK78_75 0x11 #define VCLK79_411 0x12 #define VCLK83_95 0x13 -#define VCLK84_8 0x14 #define VCLK86_6 0x15 #define VCLK94_5 0x16 -#define VCLK104_998 0x17 -#define VCLK105_882 0x18 #define VCLK108_2 0x19 -#define VCLK109_175 0x1A #define VCLK113_309 0x1B #define VCLK116_406 0x1C -#define VCLK132_258 0x1D #define VCLK135_5 0x1E #define VCLK139_054 0x1F #define VCLK157_5 0x20 #define VCLK162 0x21 #define VCLK175 0x22 #define VCLK189 0x23 -#define VCLK194_4 0x24 #define VCLK202_5 0x25 #define VCLK229_5 0x26 #define VCLK234 0x27 -#define VCLK252_699 0x28 #define VCLK254_817 0x29 -#define VCLK265_728 0x2A #define VCLK266_952 0x2B #define VCLK269_655 0x2C -#define VCLK272_042 0x2D #define VCLK277_015 0x2E -#define VCLK286_359 0x2F #define VCLK291_132 0x30 #define VCLK291_766 0x31 -#define VCLK309_789 0x32 #define VCLK315_195 0x33 #define VCLK323_586 0x34 #define VCLK330_615 0x35 -#define VCLK332_177 0x36 #define VCLK340_477 0x37 #define VCLK375_847 0x38 #define VCLK388_631 0x39 #define VCLK125_999 0x51 #define VCLK148_5 0x52 -#define VCLK178_992 0x54 #define VCLK217_325 0x55 -#define VCLK299_505 0x56 #define YPbPr750pVCLK 0x57 #define TVVCLKDIV2 0x3A @@ -906,34 +340,13 @@ #define HiTVSimuVCLK 0x3E #define HiTVTextVCLK 0x3F #define VCLK39_77 0x40 -/* #define YPbPr750pVCLK 0x0F */ #define YPbPr525pVCLK 0x3A -/* #define ;;YPbPr525iVCLK 0x3B */ -/* #define ;;YPbPr525iVCLK_2 0x3A */ #define NTSC1024VCLK 0x41 -#define VCLK25_175_41 0x42 /* ; ScaleLCD */ -#define VCLK25_175_42 0x43 -#define VCLK28_322_43 0x44 -#define VCLK40_44 0x45 -#define VCLKQVGA_1 0x46 /* ; QVGA */ -#define VCLKQVGA_2 0x47 -#define VCLKQVGA_3 0x48 #define VCLK35_2 0x49 /* ; 800x480 */ #define VCLK122_61 0x4A #define VCLK80_350 0x4B #define VCLK107_385 0x4C -#define CHTVVCLK30_2 0x50 /* ;;CHTV */ -#define CHTVVCLK28_1 0x51 -#define CHTVVCLK43_6 0x52 -#define CHTVVCLK26_4 0x53 -#define CHTVVCLK24_6 0x54 -#define CHTVVCLK47_8 0x55 -#define CHTVVCLK31_5 0x56 -#define CHTVVCLK26_2 0x57 -#define CHTVVCLK39 0x58 -#define CHTVVCLK36 0x59 - #define CH7007TVVCLK30_2 0x00 /* [Billy] 2007/05/18 For CH7007 */ #define CH7007TVVCLK28_1 0x01 #define CH7007TVVCLK43_6 0x02 @@ -1018,5 +431,4 @@ #define RES1280x960x85 0x46 #define RES1280x960x120 0x47 -#define LFBDRAMTrap 0x30 #endif diff --git a/drivers/staging/xgifb/vb_ext.h b/drivers/staging/xgifb/vb_ext.h index 814a446..0b1f55b 100644 --- a/drivers/staging/xgifb/vb_ext.h +++ b/drivers/staging/xgifb/vb_ext.h @@ -1,26 +1,6 @@ #ifndef _VBEXT_ #define _VBEXT_ -struct DWORDREGS { - unsigned long Eax, Ebx, Ecx, Edx, Esi, Edi, Ebp; -}; - -struct WORDREGS { - unsigned short ax, hi_ax, bx, hi_bx, cx, hi_cx, dx, hi_dx, si, - hi_si, di, hi_di, bp, hi_bp; -}; - -struct BYTEREGS { - unsigned char al, ah, hi_al, hi_ah, bl, bh, hi_bl, hi_bh, cl, ch, - hi_cl, hi_ch, dl, dh, hi_dl, hi_dh; -}; - -typedef union _X86_REGS { - struct DWORDREGS e; - struct WORDREGS x; - struct BYTEREGS h; -} X86_REGS, *PX86_REGS; - extern void XGI_GetSenseStatus(struct xgi_hw_device_info *HwDeviceExtension, struct vb_device_info *pVBInfo); extern unsigned short XGINew_SenseLCD(struct xgi_hw_device_info *, diff --git a/drivers/staging/xgifb/vb_setmode.c b/drivers/staging/xgifb/vb_setmode.c index dc4d6e6..845e036 100644 --- a/drivers/staging/xgifb/vb_setmode.c +++ b/drivers/staging/xgifb/vb_setmode.c @@ -14,9 +14,6 @@ #define IndexMask 0xff -#ifndef XGI_MASK_DUAL_CHIP -#define XGI_MASK_DUAL_CHIP 0x04 /* SR3A */ -#endif static unsigned short XGINew_MDA_DAC[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h index 377d27c..3ef79e0 100644 --- a/drivers/staging/xgifb/vb_struct.h +++ b/drivers/staging/xgifb/vb_struct.h @@ -1,16 +1,6 @@ #ifndef _VB_STRUCT_ #define _VB_STRUCT_ -#ifdef _INITNEW_ -#define EXTERN -#else -#define EXTERN extern -#endif - -struct XGI_PanelDelayTblStruct { - unsigned char timer[2]; -}; - struct XGI_LCDDataStruct { unsigned short RVBHCMAX; unsigned short RVBHCFACT; @@ -45,24 +35,6 @@ struct XGI_TVDataStruct { unsigned char RY4COE; }; -struct XGI_LVDSDataStruct { - unsigned short VGAHT; - unsigned short VGAVT; - unsigned short LCDHT; - unsigned short LCDVT; -}; - -struct XGI_LVDSDesStruct { - unsigned short LCDHDES; - unsigned short LCDVDES; -}; - -struct XGI_LVDSCRT1DataStruct { - unsigned char CR[15]; -}; - -/*add for LCDA*/ - struct XGI_StStruct { unsigned char St_ModeID; unsigned short St_ModeFlag; @@ -146,10 +118,6 @@ struct XGI_ModeResInfoStruct { unsigned char YChar; }; -struct XGI_LCDNBDesStruct { - unsigned char NB[12]; -}; - /*add for new UNIVGABIOS*/ struct XGI_LCDDesStruct { unsigned short LCDHDES; @@ -165,12 +133,6 @@ struct XGI_LCDDataTablStruct { unsigned short DATAPTR; }; -struct XGI_TVTablDataStruct { - unsigned short MASK; - unsigned short CAP; - unsigned short DATAPTR; -}; - struct XGI330_LCDDataDesStruct { unsigned short LCDHDES; unsigned short LCDHRS; @@ -258,10 +220,6 @@ struct XGI_XG21CRT1Struct { unsigned char ModeID, CR02, CR03, CR15, CR16; }; -struct XGI330_CHTVRegDataStruct { - unsigned char Reg[16]; -}; - struct XGI330_LCDCapStruct { unsigned char LCD_ID; unsigned short LCD_Capability; @@ -324,18 +282,6 @@ struct XGI301C_Tap4TimingStruct { unsigned char Reg[64]; /* C0-FF */ }; -struct XGI_New_StandTableStruct { - unsigned char CRT_COLS; - unsigned char ROWS; - unsigned char CHAR_HEIGHT; - unsigned short CRT_LEN; - unsigned char SR[4]; - unsigned char MISC; - unsigned char CRTC[0x19]; - unsigned char ATTR[0x14]; - unsigned char GRC[9]; -}; - struct vb_device_info { unsigned char ISXPDOS; unsigned long P3c4, P3d4, P3c0, P3ce, P3c2, P3cc; @@ -462,21 +408,4 @@ struct vb_device_info { struct XGI_XG21CRT1Struct *UpdateCRT1; }; /* _struct vb_device_info */ - -struct TimingInfo { - unsigned short Horizontal_ACTIVE; - unsigned short Horizontal_FP; - unsigned short Horizontal_SYNC; - unsigned short Horizontal_BP; - unsigned short Vertical_ACTIVE; - unsigned short Vertical_FP; - unsigned short Vertical_SYNC; - unsigned short Vertical_BP; - double DCLK; - unsigned char FrameRate; - unsigned char Interlace; - unsigned short Margin; -}; - -#define _VB_STRUCT_ #endif /* _VB_STRUCT_ */ diff --git a/drivers/staging/xgifb/vb_table.h b/drivers/staging/xgifb/vb_table.h index d10de48..0184292 100644 --- a/drivers/staging/xgifb/vb_table.h +++ b/drivers/staging/xgifb/vb_table.h @@ -173,37 +173,6 @@ static unsigned char XGI340_AGPReg[12] = { static unsigned char XGI340_SR16[4] = {0x03, 0x83, 0x03, 0x83}; -#if 0 -static unsigned char XGI330_SR15_1[8][8] = { - {0x0, 0x0, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00}, - {0x5, 0x15, 0x15, 0x15, 0x15, 0x15, 0x00, 0x00}, - {0xba, 0xba, 0xba, 0xba, 0xBA, 0xBA, 0x00, 0x00}, - {0x55, 0x57, 0x57, 0xAB, 0xAB, 0xAB, 0x00, 0x00}, - {0x60, 0x34, 0x34, 0x34, 0x34, 0x34, 0x00, 0x00}, - {0x0, 0x80, 0x80, 0x80, 0x83, 0x83, 0x00, 0x00}, - {0x50, 0x50, 0x50, 0x3C, 0x3C, 0x3C, 0x00, 0x00}, - {0x0, 0xa5, 0xfb, 0xf6, 0xF6, 0xF6, 0x00, 0x00} -}; - -static unsigned char XGI330_cr40_1[15][8] = { - {0x66, 0x40, 0x40, 0x28, 0x24, 0x24, 0x00, 0x00}, - {0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00}, - {0x00, 0xf0, 0xf0, 0xf0, 0xF0, 0xF0, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x10, 0x10, 0x10, 0x10, 0x20, 0x20, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x88, 0x88, 0x88, 0xAA, 0xAC, 0xAC, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x77, 0x77, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0xA2, 0x00, 0x00, 0xA2, 0xA2, 0x00, 0x00}, -}; -#endif - static unsigned char XGI330_sr25[] = {0x00, 0x0}; static unsigned char XGI330_sr31 = 0xc0; static unsigned char XGI330_sr32 = 0x11; @@ -1007,112 +976,6 @@ static struct XGI_CRT1TableStruct XGI_CRT1Table[] = { 0x03, 0xDE, 0xC0, 0x84, 0xBF, 0x04, 0x90} } /* 0x47 */ }; -#if 0 -static struct XGI330_CHTVRegDataStruct XGI_CHTVRegUNTSC[] = { - /* Index: 000h, 001h, 002h, 004h, 003h, 005h, 006h, 007h, - 008h, 015h, 01Fh, 00Ch, 00Dh, 00Eh, 00Fh, 010h */ - /* 00 (640x200,640x400) */ - { {0x4A, 0x77, 0xBB, 0x94, 0x84, 0x48, 0xFE, 0x50, - 0x04, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01 } }, - /* 01 (640x350) */ - { {0x4A, 0x77, 0xBB, 0x94, 0x84, 0x48, 0xFE, 0x50, - 0x04, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01 } }, - /* 02 (720x400) */ - { {0x4A, 0x77, 0xBB, 0x94, 0x84, 0x48, 0xFE, 0x50, - 0x04, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01 } }, - /* 03 (720x350) */ - { {0x4A, 0x77, 0xBB, 0x94, 0x84, 0x48, 0xFE, 0x50, - 0x04, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01 } }, - /* 04 (640x480) ;;5/6/02 */ - { {0x6A, 0x77, 0xBB, 0x6E, 0x84, 0x2E, 0x02, 0x5A, - 0x04, 0x00, 0x80, 0x20, 0x7E, 0x80, 0x97, 0x00 } }, - /* 05 (800x600) ;;1/12/02 */ - { {0xCF, 0x77, 0xB7, 0xC8, 0x84, 0x3B, 0x02, 0x5A, - 0x04, 0x00, 0x80, 0x19, 0x88, 0xAE, 0xA3, 0x00 } }, - /* 06 (1024x768) ;;5/6/02 */ - { {0xEE, 0x77, 0xBB, 0x66, 0x87, 0x32, 0x01, 0x5A, - 0x04, 0x00, 0x80, 0x1B, 0xD4, 0x2F, 0x6F, 0x00 } } -}; - -static struct XGI330_CHTVRegDataStruct XGI_CHTVRegONTSC[] = { - /* Index: 000h, 001h, 002h, 004h, 003h, 005h, 006h, 007h, - 008h, 015h, 01Fh, 00Ch, 00Dh, 00Eh, 00Fh, 010h */ - /* 00 (640x200,640x400) */ - { {0x49, 0x77, 0xBB, 0x7B, 0x84, 0x34, 0x00, 0x50, - 0x04, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01} }, - /* 01 (640x350) */ - { {0x49, 0x77, 0xBB, 0x7B, 0x84, 0x34, 0x00 , 0x50, - 0x04, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01} }, - /* 02 (720x400) */ - { {0x49, 0x77, 0xBB, 0x7B, 0x84, 0x34, 0x00 , 0x50, - 0x04, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01} }, - /* 03 (720x350) */ - { {0x49, 0x77, 0xBB, 0x7B, 0x84, 0x34, 0x00 , 0x50, - 0x04, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01} }, - /* 04 (640x480) ;;5/6/02 */ - { {0x69, 0x77, 0xBB, 0x6E, 0x84, 0x1E, 0x00 , 0x5A, - 0x04, 0x00, 0x80, 0x25, 0x1A, 0x80, 0x26, 0x00} }, - /* 05 (800x600) ;;5/6/02 */ - { {0xCE, 0x77, 0xB7, 0xB6, 0x83, 0x2C, 0x02 , 0x5A, - 0x04, 0x00, 0x80, 0x1C, 0x00, 0x82, 0x97, 0x00} }, - /* 06 (1024x768) ;;5/6/02 */ - { {0xED, 0x77, 0xBB, 0x66, 0x8C, 0x21, 0x02 , 0x5A, - 0x04, 0x00, 0x80, 0x1F, 0xA0, 0x7E, 0x73, 0x00} } -}; - -static struct XGI330_CHTVRegDataStruct XGI_CHTVRegUPAL[] = { - /* Index: 000h, 001h, 002h, 004h, 003h, 005h, 006h, 007h, - 008h, 015h, 01Fh, 00Ch, 00Dh, 00Eh, 00Fh, 010h */ - /* ; 00 (640x200,640x400) */ - { {0x41, 0x7F, 0xB7, 0x34, 0xAD, 0x50, 0x34, 0x83, - 0x05, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01} }, - /* ; 01 (640x350) */ - { {0x41, 0x7F, 0xB7, 0x80, 0x85, 0x50, 0x00, 0x83, - 0x05, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01} }, - /* ; 02 (720x400) */ - { {0x41, 0x7F, 0xB7, 0x34, 0xAD, 0x50, 0x34, 0x83, - 0x05, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01} }, - /* ; 03 (720x350) */ - { {0x41, 0x7F, 0xB7, 0x12, 0x85, 0x50, 0x00, 0x83, - 0x05, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01} }, - /* ; 04 (640x480) */ - { {0x61, 0x7F, 0xB7, 0x99, 0x84, 0x35, 0x04, 0x5A, - 0x05, 0x00, 0x80, 0x26, 0x2A, 0x55, 0x5D, 0x00} }, - /* ; 05 (800x600) ;;1/12/02 */ - { {0xC3, 0x7F, 0xB7, 0x7A, 0x84, 0x40, 0x02, 0x5A, - 0x05, 0x00, 0x80, 0x1F, 0x84, 0x3D, 0x28, 0x00} }, - /* ; 06 (1024x768) ;;1/12/02 */ - { {0xE5, 0x7F, 0xB7, 0x1D, 0xA7, 0x3E, 0x04, 0x5A, - 0x05, 0x00, 0x80, 0x20, 0x3E, 0xE4, 0x22, 0x00} } -}; - -static struct XGI330_CHTVRegDataStruct XGI_CHTVRegOPAL[] = { - /* Index: 000, 0x01, 0x02, 0x04, 0x03, 0x05, 0x06, 0x07, - 0x08, 0x15, 0x1F, 0x0C, 0x0D, 0x0E, 0x0F, 0x10h */ - /* 00 (640x200,640x400) */ - { {0x41, 0x7F, 0xB7, 0x36, 0xAD, 0x50, 0x34, 0x83, - 0x05, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01} }, - /* 01 (640x350) */ - { {0x41, 0x7F, 0xB7, 0x86, 0x85, 0x50, 0x00, 0x83, - 0x05, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01} }, - /* 02 (720x400) */ - { {0x41, 0x7F, 0xB7, 0x36, 0xAD, 0x50, 0x34, 0x83, - 0x05, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01} }, - /* 03 (720x350) */ - { {0x41, 0x7F, 0xB7, 0x86, 0x85, 0x50, 0x00, 0x83, - 0x05, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x01} }, - /* 04 (640x480) */ - { {0x61, 0x7F, 0xB7, 0x99, 0x84, 0x35, 0x04, 0x5A, - 0x05, 0x00, 0x80, 0x26, 0x2A, 0x55, 0x5D, 0x00} }, - /* 05 (800x600) ;;1/12/02 */ - { {0xC1, 0x7F, 0xB7, 0x4D, 0x8C, 0x1E, 0x31, 0x5A, - 0x05, 0x00, 0x80, 0x26, 0x78, 0x19, 0x34, 0x00} }, - /* 06 (1024x768) ;;1/12/02 */ - { {0xE4, 0x7F, 0xB7, 0x1E, 0xAF, 0x29, 0x37, 0x5A, - 0x05, 0x00, 0x80, 0x25, 0x8C, 0xB2, 0x2A, 0x00} } -}; -#endif - static unsigned char XGI_CH7017LV1024x768[] = { 0x60, 0x02, 0x00, 0x07, 0x40, 0xED, 0xA3, 0xC8, 0xC7, 0xAC, 0xE0, 0x02}; @@ -1151,16 +1014,6 @@ static struct XGI330_LCDDataStruct XGI_ExtLCD1024x768Data[] = { {1, 1, 1344, 806, 1344, 806} }; -/*struct XGI330_LCDDataStruct XGI_St2LCD1024x768Data[] = { - {62, 25, 800, 546, 1344, 806}, - {32, 15, 930, 546, 1344, 806}, - {62, 25, 800, 546, 1344, 806}, - {104, 45, 945, 496, 1344, 806}, - {62, 25, 800, 546, 1344, 806}, - {31, 18, 1008, 624, 1344, 806}, - {1, 1, 1344, 806, 1344, 806} -};*/ - static struct XGI330_LCDDataStruct XGI_CetLCD1024x768Data[] = { {1, 1, 1344, 806, 1344, 806}, /* ; 00 (320x200,320x400, 640x200,640x400) */ @@ -1194,19 +1047,6 @@ static struct XGI330_LCDDataStruct XGI_ExtLCD1280x1024Data[] = { {1, 1, 1688, 1066, 1688, 1066} }; -#if 0 -static struct XGI330_LCDDataStruct XGI_St2LCD1280x1024Data[] = { - {22, 5, 800, 510, 1650, 1088}, - {22, 5, 800, 510, 1650, 1088}, - {176, 45, 900, 510, 1650, 1088}, - {176, 45, 900, 510, 1650, 1088}, - {22, 5, 800, 510, 1650, 1088}, - {13, 5, 1024, 675, 1560, 1152}, - {16, 9, 1266, 804, 1688, 1072}, - {1, 1, 1688, 1066, 1688, 1066} -}; -#endif - static struct XGI330_LCDDataStruct XGI_CetLCD1280x1024Data[] = { {1, 1, 1688, 1066, 1688, 1066}, /* 00 (320x200,320x400, 640x200,640x400) */ @@ -1315,19 +1155,6 @@ static struct XGI330_LCDDataStruct XGI_ExtLCD1024x768x75Data[] = { {1, 1, 1312, 800, 1312, 800} /* ; 06 (1024x768x75Hz) */ }; -#if 0 -static struct XGI330_LCDDataStruct XGI_StLCD1024x768x75Data[] = { - {42, 25, 1536, 419, 1344, 806}, /* ; 00 (320x200,320x400, - 640x200,640x400) */ - {48, 25, 1536, 369, 1344, 806}, /* ; 01 (320x350,640x350) */ - {42, 25, 1536, 419, 1344, 806}, /* ; 02 (360x400,720x400) */ - {48, 25, 1536, 369, 1344, 806}, /* ; 03 (720x350) */ - {8, 5, 1312, 500, 1312, 800}, /* ; 04 (640x480x75Hz) */ - {41, 25, 1024, 625, 1312, 800}, /* ; 05 (800x600x75Hz) */ - {1, 1, 1312, 800, 1312, 800} /* ; 06 (1024x768x75Hz) */ -}; -#endif - static struct XGI330_LCDDataStruct XGI_CetLCD1024x768x75Data[] = { {1, 1, 1312, 800, 1312, 800}, /* ; 00 (320x200,320x400, 640x200,640x400) */ @@ -2041,63 +1868,6 @@ static unsigned char XGI330_Ren750pGroup3[] = { 0x18, 0x1D, 0x23, 0x28, 0x4C, 0xAA, 0x01 }; -#if 0 -static struct XGI_PanelDelayTblStruct XGI330_PanelDelayTbl[] = { - { {0x00, 0x00} }, - { {0x00, 0x00} }, - { {0x00, 0x00} }, - { {0x00, 0x00} }, - { {0x00, 0x00} }, - { {0x00, 0x00} }, - { {0x00, 0x00} }, - { {0x00, 0x00} }, - { {0x00, 0x00} }, - { {0x00, 0x00} }, - { {0x00, 0x00} }, - { {0x00, 0x00} }, - { {0x00, 0x00} }, - { {0x00, 0x00} }, - { {0x00, 0x00} }, - { {0x00, 0x00} } -}; - -static struct XGI330_LVDSDataStruct XGI330_LVDS320x480Data_1[] = { - {848, 433, 400, 525}, - {848, 389, 400, 525}, - {848, 433, 400, 525}, - {848, 389, 400, 525}, - {848, 518, 400, 525}, - {1056, 628, 400, 525}, - {400, 525, 400, 525}, - {800, 449, 1000, 644}, - {800, 525, 1000, 635} -}; - -static struct XGI330_LVDSDataStruct XGI330_LVDS800x600Data_1[] = { - {848, 433, 1060, 629}, - {848, 389, 1060, 629}, - {848, 433, 1060, 629}, - {848, 389, 1060, 629}, - {848, 518, 1060, 629}, - {1056, 628, 1056, 628}, - {1056, 628, 1056, 628}, - {800, 449, 1000, 644}, - {800, 525, 1000, 635} -}; - -static struct XGI330_LVDSDataStruct XGI330_LVDS800x600Data_2[] = { - {1056, 628, 1056, 628}, - {1056, 628, 1056, 628}, - {1056, 628, 1056, 628}, - {1056, 628, 1056, 628}, - {1056, 628, 1056, 628}, - {1056, 628, 1056, 628}, - {1056, 628, 1056, 628}, - {800, 449, 1000, 644}, - {800, 525, 1000, 635} -}; -#endif - static struct XGI330_LVDSDataStruct XGI_LVDS1024x768Data_1[] = { { 960, 438, 1344, 806}, /* 00 (320x200,320x400,640x200,640x400) */ { 960, 388, 1344, 806}, /* 01 (320x350,640x350) */ @@ -2143,79 +1913,7 @@ static struct XGI330_LVDSDataStruct XGI_LVDS1280x1024Data_2[] = { {800, 449, 1280, 801}, {800, 525, 1280, 813} }; -/* -struct XGI330_LVDSDataStruct XGI_LVDS1280x768Data_1[] = { - {768, 438, 1408, 806}, - {768, 388, 1408, 806}, - {768, 438, 1408, 806}, - {768, 388, 1408, 806}, - {768, 518, 1408, 806}, - {928, 638, 1408, 806}, - {1408, 806, 1408, 806}, - {1408, 806, 1408, 806}, - {1408, 806, 1408, 806} -}; - -struct XGI330_LVDSDataStruct XGI_LVDS1280x768Data_2[] = { - {1408, 806, 1408, 806}, - {1408, 806, 1408, 806}, - {1408, 806, 1408, 806}, - {1408, 806, 1408, 806}, - {1408, 806, 1408, 806}, - {1408, 806, 1408, 806}, - {1408, 806, 1408, 806}, - {1408, 806, 1408, 806}, - {1408, 806, 1408, 806} -}; - -struct XGI330_LVDSDataStruct XGI_LVDS1280x768NData_1[] = { - {704, 438, 1344, 806}, - {704, 388, 1344, 806}, - {704, 438, 1344, 806}, - {704, 388, 1344, 806}, - {704, 518, 1344, 806}, - {864, 638, 1344, 806}, - {1088, 806, 1344, 806}, - {1344, 806, 1344, 806}, - {1344, 806, 1344, 806} -}; -struct XGI330_LVDSDataStruct XGI_LVDS1280x768NData_2[] = { - {1344, 806, 1344, 806}, - {1344, 806, 1344, 806}, - {1344, 806, 1344, 806}, - {1344, 806, 1344, 806}, - {1344, 806, 1344, 806}, - {1344, 806, 1344, 806}, - {1344, 806, 1344, 806}, - {1344, 806, 1344, 806}, - {1344, 806, 1344, 806} -}; - -struct XGI330_LVDSDataStruct XGI_LVDS1280x768SData_1[] = { - {1048, 438, 1688, 806}, - {1048, 388, 1688, 806}, - {1148, 438, 1688, 806}, - {1148, 388, 1688, 806}, - {1048, 518, 1688, 806}, - {1208, 638, 1688, 806}, - {1432, 806, 1688, 806}, - {1688, 806, 1688, 806}, - {1688, 806, 1688, 806} -}; - -struct XGI330_LVDSDataStruct XGI_LVDS1280x768SData_2[] = { - {1688, 806, 1688, 806}, - {1688, 806, 1688, 806}, - {1688, 806, 1688, 806}, - {1688, 806, 1688, 806}, - {1688, 806, 1688, 806}, - {1688, 806, 1688, 806}, - {1688, 806, 1688, 806}, - {1688, 806, 1688, 806}, - {1688, 806, 1688, 806} -}; -*/ static struct XGI330_LVDSDataStruct XGI_LVDS1400x1050Data_1[] = { {928, 416, 1688, 1066}, {928, 366, 1688, 1066}, @@ -2502,20 +2200,6 @@ static struct XGI330_LCDDataDesStruct2 XGI_LVDSNoScalingDesDatax75[] = { {0, 1328, 0, 771, 112, 6} /* ; 0A (1280x768x75Hz) */ }; -#if 0 -static struct XGI330_LVDSDataStruct XGI330_LVDS640x480Data_1[] = { - { 800, 449, 800, 449}, - { 800, 449, 800, 449}, - { 800, 449, 800, 449}, - { 800, 449, 800, 449}, - { 800, 525, 800, 525}, - {1056, 628, 1056, 628}, - {1056, 628, 1056, 628}, - {1056, 628, 1056, 628}, - {1056, 628, 1056, 628} -}; -#endif - static struct XGI330_CHTVDataStruct XGI_CHTVUNTSCData[] = { { 840, 600, 840, 600}, { 840, 600, 840, 600}, @@ -2805,68 +2489,6 @@ static struct XGI_LVDSCRT1VDataStruct XGI_LVDSCRT11280x1024_2_Vx75[] = { { {0x28, 0x5A, 0x13, 0x87, 0xFF, 0x29, 0xA9} } /* ; 05 (x1024) */ }; -#if 0 -static struct XGI_LVDSCRT1DataStruct XGI_CHTVCRT1UNTSC[] = { - { {0x64, 0x4f, 0x88, 0x56, 0x9f, 0x56, 0x3e, - 0xe8, 0x84, 0x8f, 0x57, 0x20, 0x00, 0x01, 0x00 } }, - { {0x64, 0x4f, 0x88, 0x56, 0x9f, 0x56, 0x3e, - 0xd0, 0x82, 0x5d, 0x57, 0x00, 0x00, 0x01, 0x00 } }, - { {0x64, 0x4f, 0x88, 0x56, 0x9f, 0x56, 0x3e, - 0xe8, 0x84, 0x8f, 0x57, 0x20, 0x00, 0x01, 0x00 } }, - { {0x64, 0x4f, 0x88, 0x56, 0x9f, 0x56, 0x3e, - 0xd0, 0x82, 0x5d, 0x57, 0x00, 0x00, 0x01, 0x00 } }, - { {0x5d, 0x4f, 0x81, 0x53, 0x9c, 0x56, 0xba, - 0x18, 0x84, 0xdf, 0x57, 0x00, 0x00, 0x01, 0x00 } }, - { {0x80, 0x63, 0x84, 0x6c, 0x17, 0xec, 0xf0, - x90, 0x8c, 0x57, 0xed, 0x20, 0x00, 0x06, 0x01 } } -}; - -static struct XGI_LVDSCRT1DataStruct XGI_CHTVCRT1ONTSC[] = { - { {0x64, 0x4f, 0x88, 0x5a, 0x9f, 0x0b, 0x3e, - 0xc0, 0x84, 0x8f, 0x0c, 0x20, 0x00, 0x01, 0x00 } }, - { {0x64, 0x4f, 0x88, 0x5a, 0x9f, 0x0b, 0x3e, - 0xb0, 0x8d, 0x5d, 0x0c, 0x00, 0x00, 0x01, 0x00 } }, - { {0x64, 0x4f, 0x88, 0x5a, 0x9f, 0x0b, 0x3e, - 0xc0, 0x84, 0x8f, 0x0c, 0x20, 0x00, 0x01, 0x00 } }, - { {0x64, 0x4f, 0x88, 0x5a, 0x9f, 0x0b, 0x3e, - 0xb0, 0x8d, 0x5d, 0x0c, 0x00, 0x00, 0x01, 0x00 } }, - { {0x5d, 0x4f, 0x81, 0x56, 0x9c, 0x0b, 0x3e, - 0xe8, 0x84, 0xdf, 0x0c, 0x00, 0x00, 0x01, 0x00 } }, - { {0x7d, 0x63, 0x81, 0x6a, 0x16, 0xba, 0xf0, - x7f, 0x86, 0x57, 0xbb, 0x00, 0x00, 0x06, 0x01 } } -}; - -static struct XGI_LVDSCRT1DataStruct XGI_CHTVCRT1UPAL[] = { - { {0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e, - 0xf8, 0x83, 0x8f, 0x70, 0x20, 0x00, 0x05, 0x00 } }, - { {0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e, - 0xde, 0x81, 0x5d, 0x70, 0x00, 0x00, 0x05, 0x00 } }, - { {0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e, - 0xf8, 0x83, 0x8f, 0x70, 0x20, 0x00, 0x05, 0x00 } }, - { {0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e, - 0xde, 0x81, 0x5d, 0x70, 0x00, 0x00, 0x05, 0x00 } }, - { {0x64, 0x4f, 0x88, 0x55, 0x80, 0xec, 0xba, - 0x50, 0x84, 0xdf, 0xed, 0x00, 0x00, 0x05, 0x00 } }, - { {0x70, 0x63, 0x94, 0x68, 0x8d, 0x42, 0xf1, - xc8, 0x8c, 0x57, 0xe9, 0x20, 0x00, 0x05, 0x01 } } -}; - -static struct XGI_LVDSCRT1DataStruct XGI_CHTVCRT1OPAL[] = { - { {0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e, - 0xf0, 0x83, 0x8f, 0x70, 0x20, 0x00, 0x05, 0x00 } }, - { {0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e, - 0xde, 0x81, 0x5d, 0x70, 0x00, 0x00, 0x05, 0x00 } }, - { {0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e, - 0xf0, 0x83, 0x8f, 0x70, 0x20, 0x00, 0x05, 0x00 } }, - { {0x79, 0x4f, 0x9d, 0x5a, 0x90, 0x6f, 0x3e, - 0xde, 0x81, 0x5d, 0x70, 0x00, 0x00, 0x05, 0x00 } }, - { {0x64, 0x4f, 0x88, 0x55, 0x80, 0x6f, 0xba, - 0x20, 0x83, 0xdf, 0x70, 0x00, 0x00, 0x05, 0x00 } }, - { {0x73, 0x63, 0x97, 0x69, 0x8e, 0xec, 0xf0, - x90, 0x8c, 0x57, 0xed, 0x20, 0x00, 0x05, 0x01 } } -}; -#endif - /*add for new UNIVGABIOS*/ static struct XGI330_LCDDataTablStruct XGI_LCDDataTable[] = { {Panel1024x768, 0x0019, 0x0001, 0}, /* XGI_ExtLCD1024x768Data */ @@ -3007,19 +2629,6 @@ static struct XGI330_TVDataTablStruct XGI_TVDataTable[] = { {0xffff, 0x0000, 12} /* END */ }; -#if 0 -static unsigned short TVLenList[] = { - LVDSCRT1Len_H, - LVDSCRT1Len_V, - LVDSDataLen, - 0, - TVDataLen, - 0, - 0, - CHTVRegLen -}; -#endif - /* Chrontel 7017 TV CRT1 Timing List */ static struct XGI330_TVDataTablStruct XGI_EPLCHTVCRT1Ptr[] = { {0x0011, 0x0000, 0}, /* XGI_CHTVCRT1UNTSC */ @@ -3060,44 +2669,6 @@ static unsigned short LCDLenList[] = { 0 }; -#if 0 -/* 660, Dual link */ -static struct XGI330_LCDCapStruct XGI660_LCDDLCapList[] = { -/* LCDCap1024x768 */ - {Panel1024x768, DefaultLCDCap, 0, 0x014, 0x88, 0x06, VCLK65, - 0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00, - 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}, -/* LCDCap1280x1024 */ - {Panel1280x1024, LCDDualLink+DefaultLCDCap, StLCDBToA, - 0x053, 0x70, 0x03, VCLK108_2, - 0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00, - 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10}, -/* LCDCap1400x1050 */ - {Panel1400x1050, LCDDualLink+DefaultLCDCap, StLCDBToA, - 0x053, 0x70, 0x03, VCLK108_2, - 0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00, - 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10}, -/* LCDCap1600x1200 */ - {Panel1600x1200, LCDDualLink+DefaultLCDCap, LCDToFull, - 0x053, 0xC0, 0x03, VCLK162, - 0x43, 0x22, 0x70, 0x24, 0x02, 0x14, 0x0A, 0x02, 0x00, - 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10}, -/* LCDCap1024x768x75 */ - {Panel1024x768x75, DefaultLCDCap, 0, 0x014, 0x60, 0, VCLK78_75, - 0x2B, 0x61, 0x2B, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00, - 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}, -/* LCDCap1280x1024x75 */ - {Panel1280x1024x75, LCDDualLink+DefaultLCDCap, StLCDBToA, - 0x053, 0x90, 0x03, VCLK135_5, - 0x54, 0x42, 0x4A, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00, - 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10}, -/* LCDCapDefault */ - {0xFF, DefaultLCDCap, 0, 0x053, 0x88, 0x06, VCLK65, - 0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00, - 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10} -}; -#endif - /* Dual link only */ static struct XGI330_LCDCapStruct XGI_LCDDLCapList[] = { /* LCDCap1024x768 */ @@ -3134,40 +2705,6 @@ static struct XGI330_LCDCapStruct XGI_LCDDLCapList[] = { 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10} }; -#if 0 -static struct XGI330_LCDCapStruct XGI660_LCDCapList[] = { -/* LCDCap1024x768 */ - {Panel1024x768, DefaultLCDCap, 0, 0x014, 0x88, 0x06, VCLK65, - 0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00, - 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}, -/* LCDCap1280x1024 */ - {Panel1280x1024, DefaultLCDCap, StLCDBToA, 0x053, 0x70, 0x03, VCLK108_2, - 0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00, - 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10}, -/* LCDCap1400x1050 */ - {Panel1400x1050, DefaultLCDCap, StLCDBToA, 0x053, 0x70, 0x03, VCLK108_2, - 0x70, 0x44, 0xF8, 0x2F, 0x02, 0x14, 0x0A, 0x02, 0x00, - 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10}, -/* LCDCap1600x1200 */ - {Panel1600x1200, DefaultLCDCap, LCDToFull, 0x053, 0xC0, 0x03, VCLK162, - 0x5A, 0x23, 0x5A, 0x23, 0x02, 0x14, 0x0A, 0x02, 0x00, - 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10}, -/* LCDCap1024x768x75 */ - {Panel1024x768x75, DefaultLCDCap, 0, 0x014, 0x60, 0, VCLK78_75, - 0x2B, 0x61, 0x2B, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00, - 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10}, -/* LCDCap1280x1024x75 */ - {Panel1280x1024x75, + DefaultLCDCap, StLCDBToA, - 0x053, 0x90, 0x03, VCLK135_5, - 0x54, 0x42, 0x4A, 0x61, 0x02, 0x14, 0x0A, 0x02, 0x00, - 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x30, 0x10}, -/* LCDCapDefault */ - {0xFF, DefaultLCDCap, 0, 0x053, 0x88, 0x06, VCLK65, - 0x6C, 0xC3, 0x35, 0x62, 0x02, 0x14, 0x0A, 0x02, 0x00, - 0x30, 0x10, 0x5A, 0x10, 0x10, 0x0A, 0xC0, 0x28, 0x10} -}; -#endif - static struct XGI330_LCDCapStruct XGI_LCDCapList[] = { /* LCDCap1024x768 */ {Panel1024x768, DefaultLCDCap, 0, 0x012, 0x88, 0x06, VCLK65, @@ -3384,169 +2921,6 @@ static struct XGI_Ext2Struct XGI330_RefIndex[] = { 0x30, 0x47, 0x37, 1024, 768},/* 48 1024x768x160Hz */ }; - -#if 0 -static struct XGI330_VCLKDataStruct XGI330_VCLKData[] = { - {0x1b, 0xe1, 25}, /* 0x0 */ - {0x4e, 0xe4, 28}, /* 0x1 */ - {0x57, 0xe4, 31}, /* 0x2 */ - {0xc3, 0xc8, 36}, /* 0x3 */ - {0x42, 0xe2, 40}, /* 0x4 */ - {0xfe, 0xcd, 43}, /* 0x5 */ - {0x5d, 0xc4, 44}, /* 0x6 */ - {0x52, 0xe2, 49}, /* 0x7 */ - {0x53, 0xe2, 50}, /* 0x8 */ - {0x74, 0x67, 52}, /* 0x9 */ - {0x6d, 0x66, 56}, /* 0xa */ - {0x6c, 0xc3, 65}, /* 0xb */ - {0x46, 0x44, 67}, /* 0xc */ - {0xb1, 0x46, 68}, /* 0xd */ - {0xd3, 0x4a, 72}, /* 0xe */ - {0x29, 0x61, 75}, /* 0xf */ - {0x6e, 0x46, 76}, /* 0x10 */ - {0x2b, 0x61, 78}, /* 0x11 */ - {0x31, 0x42, 79}, /* 0x12 */ - {0xab, 0x44, 83}, /* 0x13 */ - {0x46, 0x25, 84}, /* 0x14 */ - {0x78, 0x29, 86}, /* 0x15 */ - {0x62, 0x44, 94}, /* 0x16 */ - {0x2b, 0x41, 104}, /* 0x17 */ - {0x3a, 0x23, 105}, /* 0x18 */ - {0x70, 0x44, 108}, /* 0x19 */ - {0x3c, 0x23, 109}, /* 0x1a */ - {0x5e, 0x43, 113}, /* 0x1b */ - {0xbc, 0x44, 116}, /* 0x1c */ - {0xe0, 0x46, 132}, /* 0x1d */ - {0x54, 0x42, 135}, /* 0x1e */ - {0xea, 0x2a, 139}, /* 0x1f */ - {0x41, 0x22, 157}, /* 0x20 */ - {0x70, 0x24, 162}, /* 0x21 */ - {0x30, 0x21, 175}, /* 0x22 */ - {0x4e, 0x22, 189}, /* 0x23 */ - {0xde, 0x26, 194}, /* 0x24 */ - {0x62, 0x06, 202}, /* 0x25 */ - {0x3f, 0x03, 229}, /* 0x26 */ - {0xb8, 0x06, 234}, /* 0x27 */ - {0x34, 0x02, 253}, /* 0x28 */ - {0x58, 0x04, 255}, /* 0x29 */ - {0x24, 0x01, 265}, /* 0x2a */ - {0x9b, 0x02, 267}, /* 0x2b */ - {0x70, 0x05, 270}, /* 0x2c */ - {0x25, 0x01, 272}, /* 0x2d */ - {0x9c, 0x02, 277}, /* 0x2e */ - {0x27, 0x01, 286}, /* 0x2f */ - {0x3c, 0x02, 291}, /* 0x30 */ - {0xef, 0x0a, 292}, /* 0x31 */ - {0xf6, 0x0a, 310}, /* 0x32 */ - {0x95, 0x01, 315}, /* 0x33 */ - {0xf0, 0x09, 324}, /* 0x34 */ - {0xfe, 0x0a, 331}, /* 0x35 */ - {0xf3, 0x09, 332}, /* 0x36 */ - {0xea, 0x08, 340}, /* 0x37 */ - {0xe8, 0x07, 376}, /* 0x38 */ - {0xde, 0x06, 389}, /* 0x39 */ - {0x52, 0x2a, 54}, /* 0x3a */ - {0x52, 0x6a, 27}, /* 0x3b */ - {0x62, 0x24, 70}, /* 0x3c */ - {0x62, 0x64, 70}, /* 0x3d */ - {0xa8, 0x4c, 30}, /* 0x3e */ - {0x20, 0x26, 33}, /* 0x3f */ - {0x31, 0xc2, 39}, /* 0x40 */ - {0x60, 0x36, 30}, /* 0x41 */ - {0x40, 0x4A, 28}, /* 0x42 */ - {0x9F, 0x46, 44}, /* 0x43 */ - {0x97, 0x2C, 26}, /* 0x44 */ - {0x44, 0xE4, 25}, /* 0x45 */ - {0x7E, 0x32, 47}, /* 0x46 */ - {0x08, 0x24, 31}, /* 0x47 */ - {0x97, 0x2c, 26}, /* 0x48 */ - {0xCE, 0x3c, 39}, /* 0x49 */ - {0x52, 0x4A, 36}, /* 0x4a */ - {0x2C, 0x61, 95}, /* 0x4b */ - {0x78, 0x27, 108}, /* 0x4c */ - {0x66, 0x43, 123}, /* 0x4d */ - {0x2c, 0x61, 80}, /* 0x4e */ - {0x3b, 0x61, 108} /* 0x4f */ -}; - -static struct XGI_VBVCLKDataStruct XGI330_VBVCLKData[] = { - {0x1b, 0xe1, 25}, /* 0x0 */ - {0x4e, 0xe4, 28}, /* 0x1 */ - {0x57, 0xe4, 31}, /* 0x2 */ - {0xc3, 0xc8, 36}, /* 0x3 */ - {0x42, 0x47, 40}, /* 0x4 */ - {0xfe, 0xcd, 43}, /* 0x5 */ - {0x5d, 0xc4, 44}, /* 0x6 */ - {0x52, 0x47, 49}, /* 0x7 */ - {0x53, 0x47, 50}, /* 0x8 */ - {0x74, 0x67, 52}, /* 0x9 */ - {0x6d, 0x66, 56}, /* 0xa */ - {0x5a, 0x64, 65}, /* 0xb */ - {0x46, 0x44, 67}, /* 0xc */ - {0xb1, 0x46, 68}, /* 0xd */ - {0xd3, 0x4a, 72}, /* 0xe */ - {0x29, 0x61, 75}, /* 0xf */ - {0x6d, 0x46, 75}, /* 0x10 */ - {0x41, 0x43, 78}, /* 0x11 */ - {0x31, 0x42, 79}, /* 0x12 */ - {0xab, 0x44, 83}, /* 0x13 */ - {0x46, 0x25, 84}, /* 0x14 */ - {0x78, 0x29, 86}, /* 0x15 */ - {0x62, 0x44, 94}, /* 0x16 */ - {0x2b, 0x22, 104}, /* 0x17 */ - {0x49, 0x24, 105}, /* 0x18 */ - {0xf8, 0x2f, 108}, /* 0x19 */ - {0x3c, 0x23, 109}, /* 0x1a */ - {0x5e, 0x43, 113}, /* 0x1b */ - {0xbc, 0x44, 116}, /* 0x1c */ - {0xe0, 0x46, 132}, /* 0x1d */ - {0xd4, 0x28, 135}, /* 0x1e */ - {0xea, 0x2a, 139}, /* 0x1f */ - {0x41, 0x22, 157}, /* 0x20 */ - {0x70, 0x24, 162}, /* 0x21 */ - {0x30, 0x21, 175}, /* 0x22 */ - {0x4e, 0x22, 189}, /* 0x23 */ - {0xde, 0x26, 194}, /* 0x24 */ - {0x70, 0x07, 202}, /* 0x25 */ - {0x3f, 0x03, 229}, /* 0x26 */ - {0xb8, 0x06, 234}, /* 0x27 */ - {0x34, 0x02, 253}, /* 0x28 */ - {0x58, 0x04, 255}, /* 0x29 */ - {0x24, 0x01, 265}, /* 0x2a */ - {0x9b, 0x02, 267}, /* 0x2b */ - {0x70, 0x05, 270}, /* 0x2c */ - {0x25, 0x01, 272}, /* 0x2d */ - {0x9c, 0x02, 277}, /* 0x2e */ - {0x27, 0x01, 286}, /* 0x2f */ - {0x3c, 0x02, 291}, /* 0x30 */ - {0xef, 0x0a, 292}, /* 0x31 */ - {0xf6, 0x0a, 310}, /* 0x32 */ - {0x95, 0x01, 315}, /* 0x33 */ - {0xf0, 0x09, 324}, /* 0x34 */ - {0xfe, 0x0a, 331}, /* 0x35 */ - {0xf3, 0x09, 332}, /* 0x36 */ - {0xea, 0x08, 340}, /* 0x37 */ - {0xe8, 0x07, 376}, /* 0x38 */ - {0xde, 0x06, 389}, /* 0x39 */ - {0x52, 0x2a, 54}, /* 0x3a */ - {0x52, 0x6a, 27}, /* 0x3b */ - {0x62, 0x24, 70}, /* 0x3c */ - {0x62, 0x64, 70}, /* 0x3d */ - {0xa8, 0x4c, 30}, /* 0x3e */ - {0x20, 0x26, 33}, /* 0x3f */ - {0x31, 0xc2, 39}, /* 0x40 */ - {0x2e, 0x48, 25}, /* 0x41 */ - {0x24, 0x46, 25}, /* 0x42 */ - {0x26, 0x64, 28}, /* 0x43 */ - {0x37, 0x64, 40}, /* 0x44 */ - {0xa1, 0x42, 108}, /* 0x45 */ - {0x37, 0x61, 100}, /* 0x46 */ - {0x78, 0x27, 108}, /* 0x47 */ - {0x5e, 0x64, 68}, /* 0x48 chiawen for fuj1280x768*/ - {0x70, 0x44, 108}, /* 0x49 chiawen for 1400x1050*/ -}; -#endif - static unsigned char XGI330_ScreenOffset[] = { 0x14, 0x19, 0x20, 0x28, 0x32, 0x40, 0x50, 0x64, 0x78, 0x80, 0x2d, 0x35, @@ -3591,46 +2965,13 @@ static unsigned char XGI330_OutputSelect = 0x40; static unsigned char XGI330_SoftSetting = 0x30; static unsigned char XGI330_SR07 = 0x18; -#if 0 -static unsigned char XGI330New_SR15[8][8] = { - { 0x0, 0x4, 0x60, 0x60}, - { 0xf, 0xf, 0xf, 0xf}, - {0xba, 0xba, 0xba, 0xba}, - {0xa9, 0xa9, 0xac, 0xac}, - {0xa0, 0xa0, 0xa0, 0xa8}, - { 0x0, 0x0, 0x2, 0x2}, - {0x30, 0x30, 0x40, 0x40}, - { 0x0, 0xa5, 0xfb, 0xf6} -}; - -static unsigned char XGI330New_CR40[5][8] = { - {0x77, 0x77, 0x44, 0x44}, - {0x77, 0x77, 0x44, 0x44}, - { 0x0, 0x0, 0x0, 0x0}, - {0x5b, 0x5b, 0xab, 0xab}, - { 0x0, 0x0, 0xf0, 0xf8} -}; -#endif - static unsigned char XGI330_CR49[] = {0xaa, 0x88}; static unsigned char XGI330_SR1F = 0x0; static unsigned char XGI330_SR21 = 0xa3; -#if 0 -static unsigned char XGI330_650_SR21 = 0xa7; -#endif static unsigned char XGI330_SR22 = 0xfb; static unsigned char XGI330_SR23 = 0xf6; static unsigned char XGI330_SR24 = 0xd; -#if 0 -static unsigned char XGI660_SR21 = 0xa3;/* 2003.0312 */ -static unsigned char XGI660_SR22 = 0xf3;/* 2003.0312 */ - -static unsigned char XGI330_LVDS_SR32 = 0x00; /* ynlai for 650 LVDS */ -static unsigned char XGI330_LVDS_SR33 = 0x00; /* chiawen for 650 LVDS */ -static unsigned char XGI330_650_SR31 = 0x40; -static unsigned char XGI330_650_SR33 = 0x04; -#endif static unsigned char XGI330_CRT2Data_1_2 = 0x0; static unsigned char XGI330_CRT2Data_4_D = 0x0; static unsigned char XGI330_CRT2Data_4_E = 0x0; @@ -3641,14 +2982,6 @@ static unsigned short XGI330_YCSenseData = 0xb3; static unsigned short XGI330_RGBSenseData2 = 0x0190; /*301b*/ static unsigned short XGI330_VideoSenseData2 = 0x0110; static unsigned short XGI330_YCSenseData2 = 0x016B; -#if 0 -static unsigned char XGI330_NTSCPhase[] = {0x21, 0xed, 0x8a, 0x8}; -static unsigned char XGI330_PALPhase[] = {0x2a, 0x5, 0xd3, 0x0}; -static unsigned char XGI330_NTSCPhase2[] = {0x21, 0xF0, 0x7B, 0xD6};/*301b*/ -static unsigned char XGI330_PALPhase2[] = {0x2a, 0x09, 0x86, 0xe9}; -static unsigned char XGI330_PALMPhase[] = {0x21, 0xE4, 0x2E, 0x9B}; /*palmn*/ -static unsigned char XGI330_PALNPhase[] = {0x21, 0xF4, 0x3E, 0xBA}; -#endif static unsigned char XG40_I2CDefinition = 0x00 ; static unsigned char XG20_CR97 = 0x10 ; @@ -3805,21 +3138,6 @@ static struct XGI330_VCLKDataStruct XGI_VCLKData[] = { {0x66, 0x43, 123}, /* 4A (122.61Mhz) */ {0x2C, 0x61, 80}, /* 4B (80.350Mhz) */ {0x3B, 0x61, 108}, /* 4C (107.385Mhz) */ -/* - {0x60, 0x36, 30},// 4D (30.200MHz) }// No use - {0x60, 0x36, 30},// 4E (30.200MHz) }// No use - {0x60, 0x36, 30},// 4F (30.200MHz) }// No use - {0x60, 0x36, 30},// 50 (30.200MHz) }// CHTV - {0x40, 0x4A, 28},// 51 (28.190MHz) - {0x9F, 0x46, 44},// 52 (43.600MHz) - {0x97, 0x2C, 26},// 53 (26.400MHz) - {0x44, 0xE4, 25},// 54 (24.600MHz) - {0x7E, 0x32, 47},// 55 (47.832MHz) - {0x8A, 0x24, 31},// 56 (31.500MHz) - {0x97, 0x2C, 26},// 57 (26.200MHz) - {0xCE, 0x3C, 39},// 58 (39.000MHz) - {0x52, 0x4A, 36},// 59 (36.000MHz) -*/ {0x69, 0x61, 191}, /* 4D (190.96MHz ) */ {0x4F, 0x22, 192}, /* 4E (192.069MHz) */ {0x28, 0x26, 322}, /* 4F (322.273MHz) */ @@ -3912,21 +3230,6 @@ static struct XGI330_VCLKDataStruct XGI_VBVCLKData[] = { {0x66, 0x43, 123}, /* 4A (122.61Mhz) */ {0x2C, 0x61, 80 }, /* 4B (80.350Mhz) */ {0x3B, 0x61, 108}, /* 4C (107.385Mhz) */ -/* - {0x60, 0x36, 30}, // 4D (30.200MHz) }// No use - {0x60, 0x36, 30}, // 4E (30.200MHz) }// No use - {0x60, 0x36, 30}, // 4F (30.200MHz) }// No use - {0x60, 0x36, 30}, // 50 (30.200MHz) }// CHTV - {0x40, 0x4A, 28}, // 51 (28.190MHz) - {0x9F, 0x46, 44}, // 52 (43.600MHz) - {0x97, 0x2C, 26}, // 53 (26.400MHz) - {0x44, 0xE4, 25}, // 54 (24.600MHz) - {0x7E, 0x32, 47}, // 55 (47.832MHz) - {0x8A, 0x24, 31}, // 56 (31.500MHz) - {0x97, 0x2C, 26}, // 57 (26.200MHz) - {0xCE, 0x3C, 39}, // 58 (39.000MHz) - {0x52, 0x4A, 36}, // 59 (36.000MHz) -*/ {0x69, 0x61, 191}, /* 4D (190.96MHz ) */ {0x4F, 0x22, 192}, /* 4E (192.069MHz) */ {0x28, 0x26, 322}, /* 4F (322.273MHz) */ @@ -3941,38 +3244,6 @@ static struct XGI330_VCLKDataStruct XGI_VBVCLKData[] = { {0xFF, 0x00, 0} /* End mark */ }; -#if 0 -static unsigned char XGI660_TVDelayList[] = { - 0x44, /* ; 0 ExtNTSCDelay */ - 0x44, /* ; 1 StNTSCDelay */ - 0x44, /* ; 2 ExtPALDelay */ - 0x44, /* ; 3 StPALDelay */ - 0x44, /* ; 4 ExtHiTVDelay(1080i) */ - 0x44, /* ; 5 StHiTVDelay(1080i) */ - 0x44, /* ; 6 ExtYPbPrDelay(525i) */ - 0x44, /* ; 7 StYPbPrDealy(525i) */ - 0x44, /* ; 8 ExtYPbPrDelay(525p) */ - 0x44, /* ; 9 StYPbPrDealy(525p) */ - 0x44, /* ; A ExtYPbPrDelay(750p) */ - 0x44 /* ; B StYPbPrDealy(750p) */ -}; - -static unsigned char XGI660_TVDelayList2[] = { - 0x44, /* ; 0 ExtNTSCDelay */ - 0x44, /* ; 1 StNTSCDelay */ - 0x44, /* ; 2 ExtPALDelay */ - 0x44, /* ; 3 StPALDelay */ - 0x44, /* ; 4 ExtHiTVDelay */ - 0x44, /* ; 5 StHiTVDelay */ - 0x44, /* ; 6 ExtYPbPrDelay(525i) */ - 0x44, /* ; 7 StYPbPrDealy(525i) */ - 0x44, /* ; 8 ExtYPbPrDelay(525p) */ - 0x44, /* ; 9 StYPbPrDealy(525p) */ - 0x44, /* ; A ExtYPbPrDelay(750p) */ - 0x44 /* ; B StYPbPrDealy(750p) */ -}; -#endif - static unsigned char XGI301TVDelayList[] = { 0x22, /* ; 0 ExtNTSCDelay */ 0x22, /* ; 1 StNTSCDelay */ diff --git a/drivers/staging/xgifb/vgatypes.h b/drivers/staging/xgifb/vgatypes.h index 5aeb3a4..7f911f1 100644 --- a/drivers/staging/xgifb/vgatypes.h +++ b/drivers/staging/xgifb/vgatypes.h @@ -47,11 +47,6 @@ enum XGI_LCD_TYPE { }; #endif -struct XGI_DSReg { - unsigned char jIdx; - unsigned char jVal; -}; - struct xgi_hw_device_info { unsigned long ulExternalChip; /* NO VB or other video bridge*/ /* if ujVBChipID = VB_CHIP_UNKNOWN, */ diff --git a/drivers/staging/zcache/zcache-main.c b/drivers/staging/zcache/zcache-main.c index a3f5162..fbb4001 100644 --- a/drivers/staging/zcache/zcache-main.c +++ b/drivers/staging/zcache/zcache-main.c @@ -651,7 +651,7 @@ static unsigned int zv_max_zsize = (PAGE_SIZE / 8) * 7; /* * byte count defining poor *mean* compression; pages with greater zsize * will be rejected until sufficient better-compressed pages are accepted - * driving the man below this threshold + * driving the mean below this threshold */ static unsigned int zv_max_mean_zsize = (PAGE_SIZE / 8) * 5; @@ -1668,7 +1668,7 @@ static int zcache_new_pool(uint16_t cli_id, uint32_t flags) if (cli == NULL) goto out; atomic_inc(&cli->refcount); - pool = kmalloc(sizeof(struct tmem_pool), GFP_KERNEL); + pool = kmalloc(sizeof(struct tmem_pool), GFP_ATOMIC); if (pool == NULL) { pr_info("zcache: pool creation failed: out of memory\n"); goto out; @@ -1993,7 +1993,7 @@ static int __init zcache_init(void) pr_info("zcache: frontswap enabled using kernel " "transcendent memory and xvmalloc\n"); if (old_ops.init != NULL) - pr_warning("ktmem: frontswap_ops overridden"); + pr_warning("zcache: frontswap_ops overridden"); } #endif out: diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c index d70ec1a..ec66b0a 100644 --- a/drivers/staging/zram/zram_drv.c +++ b/drivers/staging/zram/zram_drv.c @@ -37,10 +37,10 @@ /* Globals */ static int zram_major; -struct zram *devices; +struct zram *zram_devices; /* Module params (documentation at end) */ -unsigned int num_devices; +unsigned int zram_num_devices; static void zram_stat_inc(u32 *v) { @@ -780,9 +780,9 @@ static int __init zram_init(void) { int ret, dev_id; - if (num_devices > max_num_devices) { + if (zram_num_devices > max_num_devices) { pr_warning("Invalid value for num_devices: %u\n", - num_devices); + zram_num_devices); ret = -EINVAL; goto out; } @@ -794,21 +794,21 @@ static int __init zram_init(void) goto out; } - if (!num_devices) { + if (!zram_num_devices) { pr_info("num_devices not specified. Using default: 1\n"); - num_devices = 1; + zram_num_devices = 1; } /* Allocate the device array and initialize each one */ - pr_info("Creating %u devices ...\n", num_devices); - devices = kzalloc(num_devices * sizeof(struct zram), GFP_KERNEL); - if (!devices) { + pr_info("Creating %u devices ...\n", zram_num_devices); + zram_devices = kzalloc(zram_num_devices * sizeof(struct zram), GFP_KERNEL); + if (!zram_devices) { ret = -ENOMEM; goto unregister; } - for (dev_id = 0; dev_id < num_devices; dev_id++) { - ret = create_device(&devices[dev_id], dev_id); + for (dev_id = 0; dev_id < zram_num_devices; dev_id++) { + ret = create_device(&zram_devices[dev_id], dev_id); if (ret) goto free_devices; } @@ -817,8 +817,8 @@ static int __init zram_init(void) free_devices: while (dev_id) - destroy_device(&devices[--dev_id]); - kfree(devices); + destroy_device(&zram_devices[--dev_id]); + kfree(zram_devices); unregister: unregister_blkdev(zram_major, "zram"); out: @@ -830,8 +830,8 @@ static void __exit zram_exit(void) int i; struct zram *zram; - for (i = 0; i < num_devices; i++) { - zram = &devices[i]; + for (i = 0; i < zram_num_devices; i++) { + zram = &zram_devices[i]; destroy_device(zram); if (zram->init_done) @@ -840,12 +840,12 @@ static void __exit zram_exit(void) unregister_blkdev(zram_major, "zram"); - kfree(devices); + kfree(zram_devices); pr_debug("Cleanup done!\n"); } -module_param(num_devices, uint, 0); -MODULE_PARM_DESC(num_devices, "Number of zram devices"); +module_param(zram_num_devices, uint, 0); +MODULE_PARM_DESC(zram_num_devices, "Number of zram devices"); module_init(zram_init); module_exit(zram_exit); diff --git a/drivers/staging/zram/zram_drv.h b/drivers/staging/zram/zram_drv.h index abe5221..59b01d6 100644 --- a/drivers/staging/zram/zram_drv.h +++ b/drivers/staging/zram/zram_drv.h @@ -123,8 +123,8 @@ struct zram { struct zram_stats stats; }; -extern struct zram *devices; -extern unsigned int num_devices; +extern struct zram *zram_devices; +extern unsigned int zram_num_devices; #ifdef CONFIG_SYSFS extern struct attribute_group zram_disk_attr_group; #endif diff --git a/drivers/staging/zram/zram_sysfs.c b/drivers/staging/zram/zram_sysfs.c index a70cc01..df1f9dc 100644 --- a/drivers/staging/zram/zram_sysfs.c +++ b/drivers/staging/zram/zram_sysfs.c @@ -34,8 +34,8 @@ static struct zram *dev_to_zram(struct device *dev) int i; struct zram *zram = NULL; - for (i = 0; i < num_devices; i++) { - zram = &devices[i]; + for (i = 0; i < zram_num_devices; i++) { + zram = &zram_devices[i]; if (disk_to_dev(zram->disk) == dev) break; } |