mirror of
https://github.com/torvalds/linux.git
synced 2026-06-09 23:23:53 +02:00
add atheros ar6003 wifi driver
need to remove bt support in menuconfig: Networking support ---> Bluetooth subsystem support.
This commit is contained in:
parent
b941652d87
commit
b38c45814d
|
|
@ -70,6 +70,7 @@ choice
|
|||
(4) Murata SP-8HEP-P
|
||||
|
||||
source "drivers/net/wireless/rtl8192c/Kconfig"
|
||||
source "drivers/net/wireless/ar6003/Kconfig"
|
||||
endchoice
|
||||
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -6,4 +6,5 @@ obj-$(CONFIG_BCM4329) += bcm4329/
|
|||
obj-$(CONFIG_MV8686) += mv8686/
|
||||
obj-$(CONFIG_BCM4319) += bcm4319/
|
||||
obj-$(CONFIG_RTL8192CU) += rtl8192c/
|
||||
obj-$(CONFIG_AR6003) += ar6003/
|
||||
#obj-m += wlan/
|
||||
|
|
|
|||
9
drivers/net/wireless/ar6003/Kconfig
Normal file
9
drivers/net/wireless/ar6003/Kconfig
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
config AR6003
|
||||
depends on WLAN_80211 && MMC
|
||||
select WIRELESS_EXT
|
||||
select IEEE80211
|
||||
select FW_LOADER
|
||||
bool "Atheros AR6003/AR6302 SDIO"
|
||||
---help---
|
||||
Atheros ROC AR6003/AR6302.
|
||||
|
||||
77
drivers/net/wireless/ar6003/Makefile
Normal file
77
drivers/net/wireless/ar6003/Makefile
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
AR6003_SRC_PATH := drivers/net/wireless/ar6003
|
||||
|
||||
EXTRA_CFLAGS += -I${AR6003_SRC_PATH}/host/include
|
||||
EXTRA_CFLAGS += -I${AR6003_SRC_PATH}/include
|
||||
EXTRA_CFLAGS += -I${AR6003_SRC_PATH}/host/wlan/include
|
||||
EXTRA_CFLAGS += -I${AR6003_SRC_PATH}/host/os/linux/include
|
||||
EXTRA_CFLAGS += -I${AR6003_SRC_PATH}/host/os/
|
||||
EXTRA_CFLAGS += -I${AR6003_SRC_PATH}/host/bmi/include
|
||||
EXTRA_CFLAGS += -I${AR6003_SRC_PATH}/include/AR6002
|
||||
EXTRA_CFLAGS += -I${AR6003_SRC_PATH}/host/hif/sdio/linux_sdio/include
|
||||
EXTRA_CFLAGS += -Idrivers/net/wireless
|
||||
|
||||
EXTRA_CFLAGS += -DLINUX -D__KERNEL__ -DTCMD -DSEND_EVENT_TO_APP -DUSER_KEYS -DNO_SYNC_FLUSH -DHTC_EP_STAT_PROFILING -DWLAN_HEADERS -DATH_AR6K_11N_SUPPORT -DATH_SUPPORT_DFS -DANDROID_ENV -D__linux__ -DINIT_MODE_DRV_ENABLED -DBMIENABLE_SET -DAR600x_SD31_XXX -DATH6KL_SKIP_ABI_VERSION_CHECK -DATH6KL_CONFIG_HIF_VIRTUAL_SCATTER -DCONFIG_HOST_TCMD_SUPPORT -DCONFIG_AP_VIRTUAL_ADAPTER_SUPPORT -DSOFTMAC_FILE_USED -DDEBUG -DATH_DEBUG_MODULE -DAR6002_HEADERS_DEF -DAR6003_HEADERS_DEF -DMCKINLEY_HEADERS_DEF -DKERNEL_2_6
|
||||
|
||||
ifeq ($(CONFIG_BT),y)
|
||||
EXTRA_CFLAGS += -DATH_AR6K_ENABLE_GMBOX
|
||||
EXTRA_CFLAGS += -DHCI_TRANSPORT_SDIO
|
||||
EXTRA_CFLAGS += -DSETUPHCI_ENABLED
|
||||
EXTRA_CFLAGS += -DSETUPBTDEV_ENABLED
|
||||
endif
|
||||
|
||||
EXTRA_CFLAGS += -DRK29
|
||||
EXTRA_CFLAGS += -DTCHIP
|
||||
|
||||
olca3-objs := host/hif/sdio/linux_sdio/src/hif.o \
|
||||
host/hif/sdio/linux_sdio/src/hif_scatter.o \
|
||||
host/hif/common/hif_bmi_reg_access.o \
|
||||
host/hif/common/hif_diag_reg_access.o \
|
||||
host/wmi/wmi.o \
|
||||
host/reorder/rcv_aggr.o \
|
||||
host/htc2/AR6000/ar6k.o \
|
||||
host/htc2/AR6000/ar6k_events.o \
|
||||
host/htc2/htc_services.o \
|
||||
host/htc2/htc.o \
|
||||
host/htc2/htc_send.o \
|
||||
host/htc2/htc_recv.o \
|
||||
host/wlan/src/wlan_recv_beacon.o \
|
||||
host/wlan/src/wlan_utils.o \
|
||||
host/wlan/src/wlan_node.o \
|
||||
host/bmi/src/bmi.o \
|
||||
host/miscdrv/credit_dist.o \
|
||||
host/miscdrv/common_drv.o \
|
||||
host/os/linux/hci_bridge.o \
|
||||
host/os/linux/netbuf.o \
|
||||
host/os/linux/ar6000_android.o \
|
||||
host/os/linux/ioctl.o \
|
||||
host/os/linux/wireless_ext.o \
|
||||
host/os/linux/ar6000_pm.o \
|
||||
host/os/linux/ar6000_raw_if.o \
|
||||
host/os/linux/ar6000_drv.o \
|
||||
host/os/linux/ar6k_pal.o \
|
||||
host/regtable/regtable.o \
|
||||
host/regtable/AR6002def.o \
|
||||
host/regtable/MCKINLEYdef.o \
|
||||
host/regtable/AR6003def.o \
|
||||
host/dfs/dfs_debug.o \
|
||||
host/dfs/dfs_process_phyerr.o \
|
||||
host/dfs/dfs.o \
|
||||
host/dfs/dfs_misc.o \
|
||||
host/dfs/dfs_bindetects.o \
|
||||
host/dfs/dfs_init.o \
|
||||
host/dfs/dfs_host_project.o \
|
||||
host/dfs/dfs_staggered.o \
|
||||
host/dfs/dfs_ar.o \
|
||||
host/dfs/dfs_process_radarevent.o \
|
||||
host/dfs/dfs_fcc_bin5.o
|
||||
|
||||
ifeq ($(CONFIG_BT),y)
|
||||
olca3-objs += host/htc2/AR6000/ar6k_gmbox.o \
|
||||
host/htc2/AR6000/ar6k_gmbox_hciuart.o \
|
||||
host/miscdrv/ar3kconfig.o \
|
||||
host/miscdrv/ar3kps/ar3kpsconfig.o \
|
||||
host/miscdrv/ar3kps/ar3kpsparser.o
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_AR6003) += olca3.o
|
||||
|
||||
5
drivers/net/wireless/ar6003/clean.sh
Normal file
5
drivers/net/wireless/ar6003/clean.sh
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#!/bin/bash
|
||||
find . \( -not -path "*.output*" -a -name '*.[oas]' -o -name core -o -name '.*.flags' -o -name '.ko' -o -name '.*.cmd' -o -name 'Module.symvers' -o -name 'modules.order' \) -type f -print \
|
||||
| grep -v lxdialog/ | xargs rm -f
|
||||
find . \( -name '.tmp_versions' \) -type d -print | grep -v lxdialog/ | xargs rm -rf
|
||||
|
||||
125
drivers/net/wireless/ar6003/host/Android.mk
Normal file
125
drivers/net/wireless/ar6003/host/Android.mk
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
#------------------------------------------------------------------------------
|
||||
# <copyright file="makefile" company="Atheros">
|
||||
# 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"
|
||||
#==============================================================================
|
||||
|
||||
ifneq ($(TARGET_SIMULATOR),true)
|
||||
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
ATH_ANDROID_SRC_BASE:= $(BOARD_WLAN_ATHEROS_SDK)
|
||||
export ATH_BUILD_TYPE=ANDROID_ARM_NATIVEMMC
|
||||
export ATH_BUS_TYPE=sdio
|
||||
export ATH_OS_SUB_TYPE=linux_2_6
|
||||
|
||||
ATH_ANDROID_ROOT:= $(CURDIR)
|
||||
export ATH_SRC_BASE:=$(ATH_ANDROID_ROOT)/$(BOARD_WLAN_ATHEROS_SDK)/host
|
||||
#ATH_CROSS_COMPILE_TYPE:=$(ATH_ANDROID_ROOT)/prebuilt/linux-x86/toolchain/arm-eabi-4.3.1/bin/arm-eabi-
|
||||
ATH_TARGET_OUTPUT:=$(ATH_ANDROID_ROOT)
|
||||
|
||||
ifeq ($(TARGET_PRODUCT),$(filter $(TARGET_PRODUCT),qsd8250_surf qsd8250_ffa msm7627_surf msm7627_ffa msm7627a msm7625_ffa msm7625_surf msm7630_surf))
|
||||
export ATH_LINUXPATH=$(TARGET_OUT_INTERMEDIATES)/KERNEL_OBJ
|
||||
ATH_CROSS_COMPILE_TYPE:=$(ATH_ANDROID_ROOT)/prebuilt/linux-x86/toolchain/arm-eabi-4.3.1/bin/arm-eabi-
|
||||
endif
|
||||
|
||||
ifndef ATH_LINUXPATH
|
||||
#check for Nvidia-base platform
|
||||
ifeq ($(TARGET_PRODUCT),$(filter $(TARGET_PRODUCT),harmony ventana))
|
||||
export ATH_LINUXPATH=$(ATH_ANDROID_ROOT)/$(TARGET_OUT_INTERMEDIATES)/KERNEL
|
||||
ATH_CROSS_COMPILE_TYPE:=$(CROSS_COMPILE)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifndef ATH_LINUXPATH
|
||||
#check for IMX51 platform
|
||||
ifeq ($(TARGET_PRODUCT),$(filter $(TARGET_PRODUCT),imx51_bbg))
|
||||
export ATH_LINUXPATH=$(ATH_ANDROID_ROOT)/kernel_imx
|
||||
ATH_CROSS_COMPILE_TYPE:=$(ATH_ANDROID_ROOT)/prebuilt/linux-x86/toolchain/arm-eabi-4.3.1/bin/arm-eabi-
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
ifndef ATH_LINUXPATH
|
||||
# Comment out the following variable and $(error) for your platform
|
||||
# Link your kernel into android SDK directory as 'kernel' directory
|
||||
# export ATH_LINUXPATH= [Your android/kernel path ]
|
||||
ATH_CROSS_COMPILE_TYPE:=$(ATH_ANDROID_ROOT)/prebuilt/linux-x86/toolchain/arm-eabi-4.3.1/bin/arm-eabi-
|
||||
$(error define your kernel path here for ATH_LINUXPATH)
|
||||
endif
|
||||
|
||||
export ATH_ARCH_CPU_TYPE=arm
|
||||
export ATH_BUS_SUBTYPE=linux_sdio
|
||||
export ATH_ANDROID_ENV=yes
|
||||
export ATH_SOFTMAC_FILE_USED=no
|
||||
export ATH_CFG80211_ENV=no
|
||||
export ATH_DEBUG_DRIVER=yes
|
||||
export ATH_HTC_RAW_INT_ENV=yes
|
||||
export ATH_AR6K_OTA_TEST_MODE=no
|
||||
export ATH_BUILD_P2P=yes
|
||||
|
||||
ATH_HIF_TYPE:=sdio
|
||||
|
||||
ifneq ($(PLATFORM_VERSION),$(filter $(PLATFORM_VERSION),1.5 1.6))
|
||||
|
||||
ifeq ($(TARGET_PRODUCT),$(filter $(TARGET_PRODUCT),msm7627_surf msm7627_ffa GT-I5500))
|
||||
ATH_ANDROID_BUILD_FLAGS=-D__LINUX_ARM_ARCH__=6 -march=armv6 -DUSE_4BYTE_REGISTER_ACCESS
|
||||
#-fstack-check="generic"
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET_PRODUCT),$(filter $(TARGET_PRODUCT),qsd8250_surf qsd8250_ffa msm7630_surf smdkc100))
|
||||
ATH_ANDROID_BUILD_FLAGS=-D__LINUX_ARM_ARCH__=7 -march=armv7-a -DUSE_4BYTE_REGISTER_ACCESS
|
||||
#-fstack-check="generic"
|
||||
endif
|
||||
|
||||
endif # ECLAIR
|
||||
|
||||
ifeq ($(TARGET_PRODUCT),$(filter $(TARGET_PRODUCT),smdk6410))
|
||||
ATH_ANDROID_BUILD_FLAGS += -DATH6KL_CONFIG_HIF_VIRTUAL_SCATTER
|
||||
endif
|
||||
|
||||
#Uncomment the following define in order to enable OTA mode
|
||||
#ATH_ANDROID_BUILD_FLAGS += -DATH6K_CONFIG_OTA_MODE
|
||||
|
||||
export ATH_ANDROID_BUILD_FLAGS
|
||||
|
||||
mod_cleanup := $(ATH_TARGET_OUTPUT)/$(ATH_ANDROID_SRC_BASE)/dummy
|
||||
|
||||
$(mod_cleanup) :
|
||||
rm -f `find $(ATH_TARGET_OUTPUT)/$(ATH_ANDROID_SRC_BASE) -name "*.o"`
|
||||
mkdir -p $(TARGET_OUT)/wifi/ath6k/AR6003/hw2.0/
|
||||
|
||||
mod_file := os/linux/ar6000.ko
|
||||
$(ATH_ANDROID_SRC_BASE)/host/$(mod_file) : $(mod_cleanup) $(TARGET_PREBUILT_KERNEL) $(ACP)
|
||||
$(MAKE) ARCH=arm CROSS_COMPILE=$(ATH_CROSS_COMPILE_TYPE) -C $(ATH_LINUXPATH) ATH_HIF_TYPE=$(ATH_HIF_TYPE) SUBDIRS=$(ATH_SRC_BASE)/os/linux modules
|
||||
$(ATH_CROSS_COMPILE_TYPE)strip -g -S -d $(ATH_ANDROID_SRC_BASE)/host/$(mod_file)
|
||||
$(ACP) -fpt $(ATH_ANDROID_SRC_BASE)/host/$(mod_file) $(TARGET_OUT)/wifi
|
||||
|
||||
LOCAL_MODULE := ar6000.ko
|
||||
LOCAL_MODULE_TAGS := debug eng optional
|
||||
LOCAL_MODULE_CLASS := ETC
|
||||
LOCAL_MODULE_PATH := $(TARGET_OUT)/wifi
|
||||
LOCAL_SRC_FILES := $(mod_file)
|
||||
include $(BUILD_PREBUILT)
|
||||
|
||||
include $(LOCAL_PATH)/tools/Android.mk
|
||||
|
||||
endif
|
||||
174
drivers/net/wireless/ar6003/host/Makefile
Normal file
174
drivers/net/wireless/ar6003/host/Makefile
Normal file
|
|
@ -0,0 +1,174 @@
|
|||
#------------------------------------------------------------------------------
|
||||
# <copyright file="makefile" company="Atheros">
|
||||
# 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"
|
||||
#==============================================================================
|
||||
# AR6K Host driver makefile
|
||||
#
|
||||
# Minimal build invocation:
|
||||
#
|
||||
# make (all | clean | clobber)
|
||||
#
|
||||
# Extended Make invocation:
|
||||
#
|
||||
# make ATH_BUILD_TYPE=<build type> ATH_SDIO_STACK_BASE=<sdio stack install path> (all | clean | clobber)
|
||||
#
|
||||
# Notes:
|
||||
# 1. This makefile must be invoked from the host/ directory
|
||||
# 2. The <build type> must match an entry in localmake.linux.inc.
|
||||
# 3. The localmake.linux.inc can be overridden using an include file outside the build tree.
|
||||
# This file (name and path) can be set via the ATH_MAKE_INCLUDE_OVERRIDE variable.
|
||||
# ** If ATH_MAKE_INCLUDE_OVERRIDE is used, you can define all build variables in that file
|
||||
# instead of using command line arguments **. This feature is provided for developers
|
||||
# that may want to customize the build using a single include file.
|
||||
#
|
||||
# For example :
|
||||
#
|
||||
# " make ATH_MAKE_INCLUDE_OVERRIDE=$HOME/mymake.inc "
|
||||
#
|
||||
# could be used, as long as "mymake.inc" defines all the required variables (see below)
|
||||
#
|
||||
# Required Variables:
|
||||
#
|
||||
# ATH_OS_SUB_TYPE - on linux, this must be "linux_2_4" for 2.4 kernels or left blank for 2.6 kernels.
|
||||
# ATH_LINUXPATH - linux kernel source path
|
||||
# ATH_CROSS_COMPILE_TYPE - optional cross compiler path , leave blank for local gcc compilation
|
||||
# ATH_ARCH_CPU_TYPE - CPU architecture type, leave blank for local gcc compilation
|
||||
# ATH_SDIO_STACK_BASE - SDIO Stack installation path to compile the SDIO HIF layer against an externally supplied
|
||||
# SDIO stack source.
|
||||
#
|
||||
# Override variables:
|
||||
#
|
||||
# ATH_MAKE_INCLUDE_OVERRIDE - full path to include file which overrides the default (localmake.linux.inc)
|
||||
# this file can contain other overrides specific to a developers
|
||||
# workspace environment.
|
||||
# ATH_BUILD_OUTPUT_OVERRIDE - output path override for compiled executable and
|
||||
# database image
|
||||
#
|
||||
|
||||
# Include local variables
|
||||
ifdef ATH_MAKE_INCLUDE_OVERRIDE
|
||||
_LOCALMAKE_INCLUDE = $(ATH_MAKE_INCLUDE_OVERRIDE)
|
||||
else
|
||||
_LOCALMAKE_INCLUDE = localmake.linux.inc
|
||||
endif
|
||||
|
||||
-include $(_LOCALMAKE_INCLUDE)
|
||||
|
||||
export ATH_SRC_BASE
|
||||
export ATH_BUILD_TYPE
|
||||
export ATH_OS_SUB_TYPE
|
||||
export ATH_LINUXPATH
|
||||
export ATH_CROSS_COMPILE_TYPE
|
||||
export ATH_ARCH_CPU_TYPE
|
||||
export ATH_SDIO_STACK_BASE
|
||||
export ATH_BUS_TYPE
|
||||
export ATH_BUS_SUBTYPE
|
||||
export ATH_HC_DRIVERS
|
||||
export ATH_HTC_RAW_INT_ENV
|
||||
export ATH_ANDROID_ENV
|
||||
export ATH_SOFTMAC_FILE_USED
|
||||
export ATH_CFG80211_ENV
|
||||
export ATH_DEBUG_DRIVER
|
||||
export ATH_AR6K_HCI_PAL
|
||||
export ATH_AR6K_DEBUG_ALLOC
|
||||
#export ATH_BUILD_P2P
|
||||
|
||||
ATH_SRC_BASE :=$(shell pwd)
|
||||
MAKE :=make
|
||||
CC :=$(ATH_CROSS_COMPILE_TYPE)gcc
|
||||
LD :=$(ATH_CROSS_COMPILE_TYPE)ld
|
||||
STRIP :=$(ATH_CROSS_COMPILE_TYPE)strip
|
||||
ATH_HIF_TYPE :=`echo $(ATH_BUS_TYPE) | tr [:upper:] [:lower:]`
|
||||
|
||||
export STRIP
|
||||
|
||||
#export compiler variables for 3rd party applications (like the WPA supplicant)
|
||||
export CC
|
||||
export LD
|
||||
export STRIP
|
||||
|
||||
# Set cross compile type (if any)
|
||||
ifdef ATH_CROSS_COMPILE_TYPE
|
||||
_CROSS_COMPILE_LINE := ARCH=$(ATH_ARCH_CPU_TYPE) CROSS_COMPILE=$(ATH_CROSS_COMPILE_TYPE)
|
||||
endif
|
||||
|
||||
# Figure out module extension
|
||||
ifneq ($(ATH_OS_SUB_TYPE),linux_2_4)
|
||||
KMOD_EXTENSION :=ko
|
||||
endif
|
||||
ifeq ($(ATH_OS_SUB_TYPE),linux_2_4)
|
||||
KMOD_EXTENSION :=o
|
||||
endif
|
||||
|
||||
# Set up object output areas
|
||||
ifdef ATH_BUILD_OUTPUT_OVERRIDE
|
||||
_COMPILED_OBJECTS_PATH :=$(ATH_BUILD_OUTPUT_OVERRIDE)
|
||||
COMPILED_BIN_OBJECTS_PATH :=$(ATH_BUILD_OUTPUT_OVERRIDE)
|
||||
COMPILED_IMAGE_OBJECTS_PATH :=$(ATH_BUILD_OUTPUT_OVERRIDE)
|
||||
_MAKE_IMAGE_OUTPUT_DIR :=
|
||||
_MAKE_BIN_OUTPUT_DIR :=
|
||||
_CLEAN_IMAGE_OUTPUT_DIR :=
|
||||
_CLEAN_BIN_OUTPUT_DIR :=
|
||||
else
|
||||
_COMPILED_OBJECTS_PATH := $(ATH_SRC_BASE)/.output/$(ATH_BUILD_TYPE)-$(ATH_BUS_TYPE)
|
||||
COMPILED_BIN_OBJECTS_PATH := $(ATH_SRC_BASE)/.output/bin
|
||||
COMPILED_IMAGE_OBJECTS_PATH :=$(_COMPILED_OBJECTS_PATH)/$(COMPILED_OBJECTS_PREFIX)image
|
||||
_MAKE_IMAGE_OUTPUT_DIR := mkdir --parents $(COMPILED_IMAGE_OBJECTS_PATH)
|
||||
_MAKE_BIN_OUTPUT_DIR := mkdir --parents $(COMPILED_BIN_OBJECTS_PATH)
|
||||
_CLEAN_IMAGE_OUTPUT_DIR := rm -R -f $(COMPILED_IMAGE_OBJECTS_PATH)
|
||||
_CLEAN_BIN_OUTPUT_DIR := rm -R -f $(COMPILED_BIN_OBJECTS_PATH)
|
||||
endif
|
||||
|
||||
# Export the required variables to other Makefiles in the system
|
||||
export COMPILED_IMAGE_OBJECTS_PATH
|
||||
export COMPILED_BIN_OBJECTS_PATH
|
||||
|
||||
all: modules
|
||||
|
||||
modules:
|
||||
ifndef ATH_BUILD_TYPE
|
||||
@echo "Please edit the $(_LOCALMAKE_INCLUDE) file"
|
||||
exit 1
|
||||
endif
|
||||
$(_MAKE_IMAGE_OUTPUT_DIR)
|
||||
$(_MAKE_BIN_OUTPUT_DIR)
|
||||
$(MAKE) $(_CROSS_COMPILE_LINE) -C $(ATH_LINUXPATH) ATH_HIF_TYPE=$(ATH_HIF_TYPE) SUBDIRS=$(ATH_SRC_BASE)/os/linux modules
|
||||
$(MAKE) -C hif/$(ATH_HIF_TYPE)
|
||||
# $(MAKE) -C tools/wmiconfig/
|
||||
# $(MAKE) -C tools/recEvent/
|
||||
cp -f $(ATH_SRC_BASE)/os/linux/ar6000.$(KMOD_EXTENSION) $(COMPILED_IMAGE_OBJECTS_PATH)
|
||||
$(STRIP) -g -S -d $(COMPILED_IMAGE_OBJECTS_PATH)/ar6000.$(KMOD_EXTENSION)
|
||||
# cp -f tools/wmiconfig/wmiconfig $(COMPILED_IMAGE_OBJECTS_PATH)
|
||||
# cp -f tools/recEvent/recEvent $(COMPILED_IMAGE_OBJECTS_PATH)
|
||||
# cp -f tools/recEvent/restore.sh $(COMPILED_IMAGE_OBJECTS_PATH)
|
||||
|
||||
clean:
|
||||
rm -f os/linux/ar6000.mod.c os/linux/*.o os/linux/*.ko wmi/*.o htc/AR6000/src/*.o htc/*.o \
|
||||
bmi/src/*.o wlan/src/*.o driver/* tools/wmiconfig/wmiconfig \
|
||||
tools/recEvent/recEvent
|
||||
|
||||
# The kernel module build process leaves some intermediate files, this will clean up all these files
|
||||
find $(ATH_SRC_BASE) \( -not -path "*.output*" -a -name '*.[oas]' -o -name core -o -name '.*.flags' -o -name '.ko' -o -name '.*.cmd' \) -type f -print \
|
||||
| grep -v lxdialog/ | xargs rm -f
|
||||
$(MAKE) -C hif/$(ATH_HIF_TYPE) clean
|
||||
|
||||
clobber:clean
|
||||
rm -rf .output
|
||||
40
drivers/net/wireless/ar6003/host/bmi/include/bmi_internal.h
Normal file
40
drivers/net/wireless/ar6003/host/bmi/include/bmi_internal.h
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <copyright file="bmi_internal.h" company="Atheros">
|
||||
// Copyright (c) 2004-2008 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_INTERNAL_H
|
||||
#define BMI_INTERNAL_H
|
||||
|
||||
#include "a_config.h"
|
||||
#include "athdefs.h"
|
||||
#include "a_types.h"
|
||||
#include "a_osapi.h"
|
||||
#define ATH_MODULE_NAME bmi
|
||||
#include "a_debug.h"
|
||||
#include "bmi_msg.h"
|
||||
|
||||
#define ATH_DEBUG_BMI ATH_DEBUG_MAKE_MODULE_MASK(0)
|
||||
|
||||
/* ------ Global Variable Declarations ------- */
|
||||
A_BOOL bmiDone;
|
||||
|
||||
#endif
|
||||
774
drivers/net/wireless/ar6003/host/bmi/src/bmi.c
Normal file
774
drivers/net/wireless/ar6003/host/bmi/src/bmi.c
Normal file
|
|
@ -0,0 +1,774 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <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"
|
||||
//==============================================================================
|
||||
|
||||
|
||||
#include "hif.h"
|
||||
#include "bmi.h"
|
||||
#include "bmi_internal.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
static 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 A_UCHAR *pBMICmdBuf;
|
||||
#define MAX_BMI_CMDBUF_SZ (BMI_DATASZ_MAX + \
|
||||
sizeof(A_UINT32) /* cmd */ + \
|
||||
sizeof(A_UINT32) /* addr */ + \
|
||||
sizeof(A_UINT32))/* length */
|
||||
#define BMI_COMMAND_FITS(sz) ((sz) <= MAX_BMI_CMDBUF_SZ)
|
||||
#define BMI_EXCHANGE_TIMEOUT_MS 1000
|
||||
|
||||
/* APIs visible to the driver */
|
||||
void
|
||||
BMIInit(void)
|
||||
{
|
||||
bmiDone = 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 (!pBMICmdBuf) {
|
||||
pBMICmdBuf = (A_UCHAR *)A_MALLOC_NOWAIT(MAX_BMI_CMDBUF_SZ);
|
||||
A_ASSERT(pBMICmdBuf);
|
||||
}
|
||||
|
||||
A_REGISTER_MODULE_DEBUG_INFO(bmi);
|
||||
}
|
||||
|
||||
void
|
||||
BMICleanup(void)
|
||||
{
|
||||
#if 0
|
||||
if (pBMICmdCredits) {
|
||||
A_FREE(pBMICmdCredits);
|
||||
pBMICmdCredits = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (pBMICmdBuf) {
|
||||
A_FREE(pBMICmdBuf);
|
||||
pBMICmdBuf = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
A_STATUS
|
||||
BMIDone(HIF_DEVICE *device)
|
||||
{
|
||||
A_STATUS status;
|
||||
A_UINT32 cid;
|
||||
|
||||
if (bmiDone) {
|
||||
AR_DEBUG_PRINTF (ATH_DEBUG_BMI, ("BMIDone skipped\n"));
|
||||
return A_OK;
|
||||
}
|
||||
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Done: Enter (device: 0x%p)\n", device));
|
||||
bmiDone = TRUE;
|
||||
cid = BMI_DONE;
|
||||
A_MEMCPY(pBMICmdBuf,&cid,sizeof(cid));
|
||||
|
||||
status = HIFExchangeBMIMsg(device, pBMICmdBuf, sizeof(cid), NULL, NULL, 0);
|
||||
if (status != A_OK) {
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
|
||||
return A_ERROR;
|
||||
}
|
||||
|
||||
if (pBMICmdBuf) {
|
||||
A_FREE(pBMICmdBuf);
|
||||
pBMICmdBuf = NULL;
|
||||
}
|
||||
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Done: Exit\n"));
|
||||
|
||||
return A_OK;
|
||||
}
|
||||
|
||||
#ifndef HIF_MESSAGE_BASED
|
||||
extern A_STATUS HIFRegBasedGetTargetInfo(HIF_DEVICE *device, struct bmi_target_info *targ_info);
|
||||
#endif
|
||||
|
||||
A_STATUS
|
||||
BMIGetTargetInfo(HIF_DEVICE *device, struct bmi_target_info *targ_info)
|
||||
{
|
||||
if (bmiDone) {
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI Get Target Info Command disallowed\n"));
|
||||
return A_ERROR;
|
||||
}
|
||||
|
||||
#ifndef HIF_MESSAGE_BASED
|
||||
/* getting the target ID requires special handling because of the variable length
|
||||
* message */
|
||||
return HIFRegBasedGetTargetInfo(device,targ_info);
|
||||
#else
|
||||
/* TODO */
|
||||
return A_ERROR;
|
||||
#endif
|
||||
}
|
||||
|
||||
A_STATUS
|
||||
BMIReadMemory(HIF_DEVICE *device,
|
||||
A_UINT32 address,
|
||||
A_UCHAR *buffer,
|
||||
A_UINT32 length)
|
||||
{
|
||||
A_UINT32 cid;
|
||||
A_STATUS status;
|
||||
A_UINT32 offset;
|
||||
A_UINT32 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;
|
||||
A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
|
||||
offset += sizeof(cid);
|
||||
A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address));
|
||||
offset += sizeof(address);
|
||||
A_MEMCPY(&(pBMICmdBuf[offset]), &rxlen, sizeof(rxlen));
|
||||
offset += sizeof(length);
|
||||
|
||||
status = HIFExchangeBMIMsg(device,
|
||||
pBMICmdBuf,
|
||||
offset,
|
||||
pBMICmdBuf, /* note we reuse the same buffer to receive on */
|
||||
&rxlen,
|
||||
BMI_EXCHANGE_TIMEOUT_MS);
|
||||
|
||||
if (status != A_OK) {
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n"));
|
||||
return A_ERROR;
|
||||
}
|
||||
A_MEMCPY(&buffer[length - remaining], pBMICmdBuf, rxlen);
|
||||
remaining -= rxlen; address += rxlen;
|
||||
}
|
||||
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read Memory: Exit\n"));
|
||||
return A_OK;
|
||||
}
|
||||
|
||||
A_STATUS
|
||||
BMIWriteMemory(HIF_DEVICE *device,
|
||||
A_UINT32 address,
|
||||
A_UCHAR *buffer,
|
||||
A_UINT32 length)
|
||||
{
|
||||
A_UINT32 cid;
|
||||
A_STATUS status;
|
||||
A_UINT32 offset;
|
||||
A_UINT32 remaining, txlen;
|
||||
const A_UINT32 header = sizeof(cid) + sizeof(address) + sizeof(length);
|
||||
A_UCHAR alignedBuffer[BMI_DATASZ_MAX];
|
||||
A_UCHAR *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;
|
||||
A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
|
||||
offset += sizeof(cid);
|
||||
A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address));
|
||||
offset += sizeof(address);
|
||||
A_MEMCPY(&(pBMICmdBuf[offset]), &txlen, sizeof(txlen));
|
||||
offset += sizeof(txlen);
|
||||
A_MEMCPY(&(pBMICmdBuf[offset]), src, txlen);
|
||||
offset += txlen;
|
||||
status = HIFExchangeBMIMsg(device, pBMICmdBuf, offset, NULL, NULL, BMI_EXCHANGE_TIMEOUT_MS);
|
||||
if (status != A_OK) {
|
||||
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 A_OK;
|
||||
}
|
||||
|
||||
A_STATUS
|
||||
BMIExecute(HIF_DEVICE *device,
|
||||
A_UINT32 address,
|
||||
A_UINT32 *param)
|
||||
{
|
||||
A_UINT32 cid;
|
||||
A_STATUS status;
|
||||
A_UINT32 offset;
|
||||
A_UINT32 paramLen;
|
||||
|
||||
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;
|
||||
A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
|
||||
offset += sizeof(cid);
|
||||
A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address));
|
||||
offset += sizeof(address);
|
||||
A_MEMCPY(&(pBMICmdBuf[offset]), param, sizeof(*param));
|
||||
offset += sizeof(*param);
|
||||
paramLen = sizeof(*param);
|
||||
status = HIFExchangeBMIMsg(device, pBMICmdBuf, offset, pBMICmdBuf, ¶mLen, 0);
|
||||
if (status != A_OK) {
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n"));
|
||||
return A_ERROR;
|
||||
}
|
||||
|
||||
A_MEMCPY(param, pBMICmdBuf, sizeof(*param));
|
||||
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Execute: Exit (param: %d)\n", *param));
|
||||
return A_OK;
|
||||
}
|
||||
|
||||
A_STATUS
|
||||
BMISetAppStart(HIF_DEVICE *device,
|
||||
A_UINT32 address)
|
||||
{
|
||||
A_UINT32 cid;
|
||||
A_STATUS status;
|
||||
A_UINT32 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;
|
||||
A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
|
||||
offset += sizeof(cid);
|
||||
A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address));
|
||||
offset += sizeof(address);
|
||||
|
||||
status = HIFExchangeBMIMsg(device, pBMICmdBuf, offset, NULL, NULL, 0);
|
||||
if (status != A_OK) {
|
||||
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 A_OK;
|
||||
}
|
||||
|
||||
A_STATUS
|
||||
BMIReadSOCRegister(HIF_DEVICE *device,
|
||||
A_UINT32 address,
|
||||
A_UINT32 *param)
|
||||
{
|
||||
A_UINT32 cid;
|
||||
A_STATUS status;
|
||||
A_UINT32 offset,paramLen;
|
||||
|
||||
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;
|
||||
A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
|
||||
offset += sizeof(cid);
|
||||
A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address));
|
||||
offset += sizeof(address);
|
||||
paramLen = sizeof(*param);
|
||||
status = HIFExchangeBMIMsg(device, pBMICmdBuf, offset, pBMICmdBuf, ¶mLen, BMI_EXCHANGE_TIMEOUT_MS);
|
||||
if (status != A_OK) {
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read from the device\n"));
|
||||
return A_ERROR;
|
||||
}
|
||||
A_MEMCPY(param, pBMICmdBuf, sizeof(*param));
|
||||
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Read SOC Register: Exit (value: %d)\n", *param));
|
||||
return A_OK;
|
||||
}
|
||||
|
||||
A_STATUS
|
||||
BMIWriteSOCRegister(HIF_DEVICE *device,
|
||||
A_UINT32 address,
|
||||
A_UINT32 param)
|
||||
{
|
||||
A_UINT32 cid;
|
||||
A_STATUS status;
|
||||
A_UINT32 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;
|
||||
A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
|
||||
offset += sizeof(cid);
|
||||
A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address));
|
||||
offset += sizeof(address);
|
||||
A_MEMCPY(&(pBMICmdBuf[offset]), ¶m, sizeof(param));
|
||||
offset += sizeof(param);
|
||||
status = HIFExchangeBMIMsg(device, pBMICmdBuf, offset, NULL, NULL, 0);
|
||||
if (status != A_OK) {
|
||||
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 A_OK;
|
||||
}
|
||||
|
||||
A_STATUS
|
||||
BMIrompatchInstall(HIF_DEVICE *device,
|
||||
A_UINT32 ROM_addr,
|
||||
A_UINT32 RAM_addr,
|
||||
A_UINT32 nbytes,
|
||||
A_UINT32 do_activate,
|
||||
A_UINT32 *rompatch_id)
|
||||
{
|
||||
A_UINT32 cid;
|
||||
A_STATUS status;
|
||||
A_UINT32 offset,responseLen;
|
||||
|
||||
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;
|
||||
A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
|
||||
offset += sizeof(cid);
|
||||
A_MEMCPY(&(pBMICmdBuf[offset]), &ROM_addr, sizeof(ROM_addr));
|
||||
offset += sizeof(ROM_addr);
|
||||
A_MEMCPY(&(pBMICmdBuf[offset]), &RAM_addr, sizeof(RAM_addr));
|
||||
offset += sizeof(RAM_addr);
|
||||
A_MEMCPY(&(pBMICmdBuf[offset]), &nbytes, sizeof(nbytes));
|
||||
offset += sizeof(nbytes);
|
||||
A_MEMCPY(&(pBMICmdBuf[offset]), &do_activate, sizeof(do_activate));
|
||||
offset += sizeof(do_activate);
|
||||
responseLen = sizeof(*rompatch_id);
|
||||
status = HIFExchangeBMIMsg(device, pBMICmdBuf, offset, pBMICmdBuf, &responseLen, BMI_EXCHANGE_TIMEOUT_MS);
|
||||
if (status != A_OK) {
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to install ROM patch\n"));
|
||||
return A_ERROR;
|
||||
}
|
||||
|
||||
A_MEMCPY(rompatch_id, pBMICmdBuf, sizeof(*rompatch_id));
|
||||
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI rompatch Install: (rompatch_id=%d)\n", *rompatch_id));
|
||||
return A_OK;
|
||||
}
|
||||
|
||||
A_STATUS
|
||||
BMIrompatchUninstall(HIF_DEVICE *device,
|
||||
A_UINT32 rompatch_id)
|
||||
{
|
||||
A_UINT32 cid;
|
||||
A_STATUS status;
|
||||
A_UINT32 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;
|
||||
A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
|
||||
offset += sizeof(cid);
|
||||
A_MEMCPY(&(pBMICmdBuf[offset]), &rompatch_id, sizeof(rompatch_id));
|
||||
offset += sizeof(rompatch_id);
|
||||
status = HIFExchangeBMIMsg(device, pBMICmdBuf, offset, NULL, NULL, 0);
|
||||
if (status != A_OK) {
|
||||
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 A_OK;
|
||||
}
|
||||
|
||||
static A_STATUS
|
||||
_BMIrompatchChangeActivation(HIF_DEVICE *device,
|
||||
A_UINT32 rompatch_count,
|
||||
A_UINT32 *rompatch_list,
|
||||
A_UINT32 do_activate)
|
||||
{
|
||||
A_UINT32 cid;
|
||||
A_STATUS status;
|
||||
A_UINT32 offset;
|
||||
A_UINT32 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;
|
||||
A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
|
||||
offset += sizeof(cid);
|
||||
A_MEMCPY(&(pBMICmdBuf[offset]), &rompatch_count, sizeof(rompatch_count));
|
||||
offset += sizeof(rompatch_count);
|
||||
length = rompatch_count * sizeof(*rompatch_list);
|
||||
A_MEMCPY(&(pBMICmdBuf[offset]), rompatch_list, length);
|
||||
offset += length;
|
||||
status = HIFExchangeBMIMsg(device, pBMICmdBuf, offset, NULL, NULL, 0);
|
||||
if (status != A_OK) {
|
||||
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 A_OK;
|
||||
}
|
||||
|
||||
A_STATUS
|
||||
BMIrompatchActivate(HIF_DEVICE *device,
|
||||
A_UINT32 rompatch_count,
|
||||
A_UINT32 *rompatch_list)
|
||||
{
|
||||
return _BMIrompatchChangeActivation(device, rompatch_count, rompatch_list, 1);
|
||||
}
|
||||
|
||||
A_STATUS
|
||||
BMIrompatchDeactivate(HIF_DEVICE *device,
|
||||
A_UINT32 rompatch_count,
|
||||
A_UINT32 *rompatch_list)
|
||||
{
|
||||
return _BMIrompatchChangeActivation(device, rompatch_count, rompatch_list, 0);
|
||||
}
|
||||
|
||||
A_STATUS
|
||||
BMILZData(HIF_DEVICE *device,
|
||||
A_UCHAR *buffer,
|
||||
A_UINT32 length)
|
||||
{
|
||||
A_UINT32 cid;
|
||||
A_STATUS status;
|
||||
A_UINT32 offset;
|
||||
A_UINT32 remaining, txlen;
|
||||
const A_UINT32 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;
|
||||
A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
|
||||
offset += sizeof(cid);
|
||||
A_MEMCPY(&(pBMICmdBuf[offset]), &txlen, sizeof(txlen));
|
||||
offset += sizeof(txlen);
|
||||
A_MEMCPY(&(pBMICmdBuf[offset]), &buffer[length - remaining], txlen);
|
||||
offset += txlen;
|
||||
status = HIFExchangeBMIMsg(device, pBMICmdBuf, offset, NULL, NULL, 0);
|
||||
if (status != A_OK) {
|
||||
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 A_OK;
|
||||
}
|
||||
|
||||
A_STATUS
|
||||
BMILZStreamStart(HIF_DEVICE *device,
|
||||
A_UINT32 address)
|
||||
{
|
||||
A_UINT32 cid;
|
||||
A_STATUS status;
|
||||
A_UINT32 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;
|
||||
A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
|
||||
offset += sizeof(cid);
|
||||
A_MEMCPY(&(pBMICmdBuf[offset]), &address, sizeof(address));
|
||||
offset += sizeof(address);
|
||||
status = HIFExchangeBMIMsg(device, pBMICmdBuf, offset, NULL, NULL, 0);
|
||||
if (status != A_OK) {
|
||||
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 A_OK;
|
||||
}
|
||||
|
||||
A_STATUS
|
||||
BMIFastDownload(HIF_DEVICE *device, A_UINT32 address, A_UCHAR *buffer, A_UINT32 length)
|
||||
{
|
||||
A_STATUS status = A_ERROR;
|
||||
A_UINT32 lastWord = 0;
|
||||
A_UINT32 lastWordOffset = length & ~0x3;
|
||||
A_UINT32 unalignedBytes = length & 0x3;
|
||||
|
||||
status = BMILZStreamStart (device, address);
|
||||
if (A_FAILED(status)) {
|
||||
return A_ERROR;
|
||||
}
|
||||
|
||||
if (unalignedBytes) {
|
||||
/* copy the last word into a zero padded buffer */
|
||||
A_MEMCPY(&lastWord, &buffer[lastWordOffset], unalignedBytes);
|
||||
}
|
||||
|
||||
status = BMILZData(device, buffer, lastWordOffset);
|
||||
|
||||
if (A_FAILED(status)) {
|
||||
return A_ERROR;
|
||||
}
|
||||
|
||||
if (unalignedBytes) {
|
||||
status = BMILZData(device, (A_UINT8 *)&lastWord, 4);
|
||||
}
|
||||
|
||||
if (A_SUCCESS(status)) {
|
||||
//
|
||||
// Close compressed stream and open a new (fake) one. This serves mainly to flush Target caches.
|
||||
//
|
||||
status = BMILZStreamStart (device, 0x00);
|
||||
if (A_FAILED(status)) {
|
||||
return A_ERROR;
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
A_STATUS
|
||||
BMInvramProcess(HIF_DEVICE *device, A_UCHAR *seg_name, A_UINT32 *retval)
|
||||
{
|
||||
A_UINT32 cid;
|
||||
A_STATUS status;
|
||||
A_UINT32 offset;
|
||||
A_UINT32 retvalLen;
|
||||
|
||||
A_ASSERT(BMI_COMMAND_FITS(sizeof(cid) + BMI_NVRAM_SEG_NAME_SZ));
|
||||
|
||||
if (bmiDone) {
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Command disallowed\n"));
|
||||
return A_ERROR;
|
||||
}
|
||||
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_BMI,
|
||||
("BMI NVRAM Process: Enter (device: 0x%p, name: %s)\n",
|
||||
device, seg_name));
|
||||
|
||||
cid = BMI_NVRAM_PROCESS;
|
||||
offset = 0;
|
||||
A_MEMCPY(&(pBMICmdBuf[offset]), &cid, sizeof(cid));
|
||||
offset += sizeof(cid);
|
||||
A_MEMCPY(&(pBMICmdBuf[offset]), seg_name, BMI_NVRAM_SEG_NAME_SZ);
|
||||
offset += BMI_NVRAM_SEG_NAME_SZ;
|
||||
retvalLen = sizeof(*retval);
|
||||
status = HIFExchangeBMIMsg(device, pBMICmdBuf, offset, pBMICmdBuf, &retvalLen, 0);
|
||||
if (status != A_OK) {
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to access the device\n"));
|
||||
return A_ERROR;
|
||||
}
|
||||
|
||||
A_MEMCPY(retval, pBMICmdBuf, sizeof(*retval));
|
||||
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI NVRAM Process: Exit\n"));
|
||||
|
||||
return A_OK;
|
||||
}
|
||||
|
||||
#ifdef HIF_MESSAGE_BASED
|
||||
|
||||
/* TODO.. stubs.. for message-based HIFs, the RAW access APIs need to be changed
|
||||
*/
|
||||
|
||||
A_STATUS
|
||||
BMIRawWrite(HIF_DEVICE *device, A_UCHAR *buffer, A_UINT32 length)
|
||||
{
|
||||
/* TODO */
|
||||
return A_ERROR;
|
||||
}
|
||||
|
||||
A_STATUS
|
||||
BMIRawRead(HIF_DEVICE *device, A_UCHAR *buffer, A_UINT32 length, A_BOOL want_timeout)
|
||||
{
|
||||
/* TODO */
|
||||
return A_ERROR;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
26
drivers/net/wireless/ar6003/host/bmi/src/makefile
Normal file
26
drivers/net/wireless/ar6003/host/bmi/src/makefile
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#------------------------------------------------------------------------------
|
||||
# <copyright file="makefile" company="Atheros">
|
||||
# Copyright (c) 2005-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"
|
||||
#==============================================================================
|
||||
!INCLUDE $(_MAKEENVROOT)\makefile.def
|
||||
|
||||
|
||||
|
||||
228
drivers/net/wireless/ar6003/host/dfs/dfs.c
Normal file
228
drivers/net/wireless/ar6003/host/dfs/dfs.c
Normal file
|
|
@ -0,0 +1,228 @@
|
|||
/*
|
||||
* Copyright (c) 2002-2006, Atheros Communications Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef ATH_SUPPORT_DFS
|
||||
#include "dfs_host.h"
|
||||
#include "dfs_common.h"
|
||||
|
||||
struct ath_dfs_host *dfs_attach_host(DEV_HDL dev, OS_HDL os, ATH_DFS_CAPINFO *cap_info)
|
||||
{
|
||||
int i,n;
|
||||
struct ath_dfs_host *dfs;
|
||||
|
||||
dfs = (struct ath_dfs_host *)DFS_MALLOC(os, sizeof(struct ath_dfs_host));
|
||||
|
||||
if (dfs == NULL) {
|
||||
A_PRINTF("%s: ath_dfs allocation failed\n", __func__);
|
||||
return dfs;
|
||||
}
|
||||
|
||||
OS_MEMZERO(dfs, sizeof (struct ath_dfs_host));
|
||||
|
||||
dfs->dev_hdl = dev;
|
||||
dfs->os_hdl = os;
|
||||
|
||||
dfs->dfs_debug_level=ATH_DEBUG_DFS;
|
||||
|
||||
ATH_DFSQ_LOCK_INIT(dfs);
|
||||
STAILQ_INIT(&dfs->dfs_radarq);
|
||||
ATH_ARQ_LOCK_INIT(dfs);
|
||||
STAILQ_INIT(&dfs->dfs_arq);
|
||||
STAILQ_INIT(&(dfs->dfs_eventq));
|
||||
ATH_DFSEVENTQ_LOCK_INIT(dfs);
|
||||
|
||||
OS_INIT_TIMER(&dfs->dfs_radar_task_timer, dfs_radar_task, dfs);
|
||||
|
||||
dfs->events = (struct dfs_event *)DFS_MALLOC(os,
|
||||
sizeof(struct dfs_event)*DFS_MAX_EVENTS);
|
||||
|
||||
if (dfs->events == NULL) {
|
||||
OS_FREE(dfs);
|
||||
dfs = NULL;
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS,
|
||||
"%s: events allocation failed\n", __func__);
|
||||
return dfs;
|
||||
}
|
||||
for (i=0; i< DFS_MAX_EVENTS; i++) {
|
||||
STAILQ_INSERT_TAIL(&(dfs->dfs_eventq), &dfs->events[i], re_list);
|
||||
}
|
||||
|
||||
dfs->pulses = (struct dfs_pulseline *)DFS_MALLOC(os, sizeof(struct dfs_pulseline));
|
||||
|
||||
if (dfs->pulses == NULL) {
|
||||
OS_FREE(dfs->events);
|
||||
dfs->events = NULL;
|
||||
OS_FREE(dfs);
|
||||
dfs = NULL;
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS,
|
||||
"%s: pulse buffer allocation failed\n", __func__);
|
||||
return dfs;
|
||||
}
|
||||
|
||||
dfs->pulses->pl_lastelem = DFS_MAX_PULSE_BUFFER_MASK;
|
||||
|
||||
#ifdef ATH_ENABLE_AR
|
||||
if(cap_info->enable_ar){
|
||||
dfs_reset_ar(dfs);
|
||||
dfs_reset_arq(dfs);
|
||||
dfs->dfs_proc_phyerr |= DFS_AR_EN;
|
||||
}
|
||||
#endif /* ATH_ENABLE_AR */
|
||||
|
||||
if(cap_info->enable_radar) {
|
||||
/* Allocate memory for radar filters */
|
||||
for (n=0; n<DFS_MAX_RADAR_TYPES; n++) {
|
||||
dfs->dfs_radarf[n] = (struct dfs_filtertype *)DFS_MALLOC(os, sizeof(struct dfs_filtertype));
|
||||
if (dfs->dfs_radarf[n] == NULL) {
|
||||
DFS_DPRINTK(dfs,ATH_DEBUG_DFS,
|
||||
"%s: cannot allocate memory for radar filter types\n",
|
||||
__func__);
|
||||
goto bad1;
|
||||
}
|
||||
}
|
||||
/* Allocate memory for radar table */
|
||||
dfs->dfs_radartable = (int8_t **)DFS_MALLOC(os, 256*sizeof(int8_t *));
|
||||
if (dfs->dfs_radartable == NULL) {
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: cannot allocate memory for radar table\n",
|
||||
__func__);
|
||||
goto bad1;
|
||||
}
|
||||
for (n=0; n<256; n++) {
|
||||
dfs->dfs_radartable[n] = DFS_MALLOC(os, DFS_MAX_RADAR_OVERLAP*sizeof(int8_t));
|
||||
if (dfs->dfs_radartable[n] == NULL) {
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS,
|
||||
"%s: cannot allocate memory for radar table entry\n",
|
||||
__func__);
|
||||
goto bad2;
|
||||
}
|
||||
}
|
||||
|
||||
/* Init the Bin5 chirping related data */
|
||||
dfs->dfs_rinfo.dfs_bin5_chirp_ts = cap_info->ext_chan_busy_ts;
|
||||
dfs->dfs_rinfo.dfs_last_bin5_dur = MAX_BIN5_DUR;
|
||||
|
||||
dfs->dfs_b5radars = NULL;
|
||||
}
|
||||
|
||||
return dfs;
|
||||
|
||||
bad2:
|
||||
OS_FREE(dfs->dfs_radartable);
|
||||
dfs->dfs_radartable = NULL;
|
||||
bad1:
|
||||
for (n=0; n<DFS_MAX_RADAR_TYPES; n++) {
|
||||
if (dfs->dfs_radarf[n] != NULL) {
|
||||
OS_FREE(dfs->dfs_radarf[n]);
|
||||
dfs->dfs_radarf[n] = NULL;
|
||||
}
|
||||
}
|
||||
if (dfs->pulses) {
|
||||
OS_FREE(dfs->pulses);
|
||||
dfs->pulses = NULL;
|
||||
}
|
||||
if (dfs->events) {
|
||||
OS_FREE(dfs->events);
|
||||
dfs->events = NULL;
|
||||
}
|
||||
|
||||
return dfs;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
dfs_detach_host(struct ath_dfs_host *dfs)
|
||||
{
|
||||
int n, empty;
|
||||
|
||||
if (dfs == NULL) {
|
||||
A_PRINTF("%s: sc_dfs is NULL\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
OS_CANCEL_TIMER(&dfs->dfs_radar_task_timer);
|
||||
|
||||
/* Return radar events to free q*/
|
||||
dfs_reset_radarq(dfs);
|
||||
dfs_reset_alldelaylines(dfs);
|
||||
|
||||
/* Free up pulse log*/
|
||||
if (dfs->pulses != NULL) {
|
||||
OS_FREE(dfs->pulses);
|
||||
dfs->pulses = NULL;
|
||||
}
|
||||
|
||||
for (n=0; n<DFS_MAX_RADAR_TYPES;n++) {
|
||||
if (dfs->dfs_radarf[n] != NULL) {
|
||||
OS_FREE(dfs->dfs_radarf[n]);
|
||||
dfs->dfs_radarf[n] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (dfs->dfs_radartable != NULL) {
|
||||
for (n=0; n<256; n++) {
|
||||
if (dfs->dfs_radartable[n] != NULL) {
|
||||
OS_FREE(dfs->dfs_radartable[n]);
|
||||
dfs->dfs_radartable[n] = NULL;
|
||||
}
|
||||
}
|
||||
OS_FREE(dfs->dfs_radartable);
|
||||
dfs->dfs_radartable = NULL;
|
||||
}
|
||||
|
||||
if (dfs->dfs_b5radars != NULL) {
|
||||
OS_FREE(dfs->dfs_b5radars);
|
||||
dfs->dfs_b5radars=NULL;
|
||||
}
|
||||
|
||||
dfs_reset_ar(dfs);
|
||||
|
||||
ATH_ARQ_LOCK(dfs);
|
||||
empty = STAILQ_EMPTY(&(dfs->dfs_arq));
|
||||
ATH_ARQ_UNLOCK(dfs);
|
||||
if (!empty) {
|
||||
dfs_reset_arq(dfs);
|
||||
}
|
||||
if (dfs->events != NULL) {
|
||||
OS_FREE(dfs->events);
|
||||
dfs->events = NULL;
|
||||
}
|
||||
OS_FREE(dfs);
|
||||
dfs = NULL;
|
||||
}
|
||||
|
||||
|
||||
void dfs_bangradar_enable(struct ath_dfs_host *dfs, u_int8_t enable)
|
||||
{
|
||||
dfs->dfs_bangradar = enable;
|
||||
}
|
||||
|
||||
void dfs_set_dur_multiplier(struct ath_dfs_host *dfs, u_int32_t dur_multiplier)
|
||||
{
|
||||
dfs->dur_multiplier = dur_multiplier;
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS3,
|
||||
"%s: duration multiplier is %d\n", __func__, dfs->dur_multiplier);
|
||||
}
|
||||
|
||||
void dfs_set_debug_level_host(struct ath_dfs_host *dfs, u_int32_t level)
|
||||
{
|
||||
dfs->dfs_debug_level = level;
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS3,
|
||||
"%s: debug level is %d\n", __func__, dfs->dfs_debug_level);
|
||||
|
||||
}
|
||||
|
||||
#endif /* ATH_UPPORT_DFS */
|
||||
262
drivers/net/wireless/ar6003/host/dfs/dfs_ar.c
Normal file
262
drivers/net/wireless/ar6003/host/dfs/dfs_ar.c
Normal file
|
|
@ -0,0 +1,262 @@
|
|||
/*
|
||||
* Copyright (c) 2002-2010, Atheros Communications Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef ATH_SUPPORT_DFS
|
||||
#include "dfs_host.h"
|
||||
|
||||
#define UPDATE_TOP_THREE_PEAKS(_histo, _peakPtrList, _currWidth) { \
|
||||
if ((_histo)[(_peakPtrList)[0]] < (_histo)[(_currWidth)]) { \
|
||||
(_peakPtrList)[2] = (_currWidth != (_peakPtrList)[1]) ? \
|
||||
(_peakPtrList)[1] : (_peakPtrList)[2]; \
|
||||
(_peakPtrList)[1] = (_peakPtrList)[0]; \
|
||||
(_peakPtrList)[0] = (_currWidth); \
|
||||
} else if ((_currWidth != (_peakPtrList)[0]) \
|
||||
&& ((_histo)[(_peakPtrList)[1]] < (_histo)[(_currWidth)])) { \
|
||||
(_peakPtrList)[2] = (_peakPtrList)[1]; \
|
||||
(_peakPtrList)[1] = (_currWidth); \
|
||||
} else if ((_currWidth != (_peakPtrList)[1]) \
|
||||
&& (_currWidth != (_peakPtrList)[0]) \
|
||||
&& ((_histo)[(_peakPtrList)[2]] < (_histo)[(_currWidth)])) { \
|
||||
(_peakPtrList)[2] = (_currWidth); \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
|
||||
u_int32_t dfs_process_ar_event(struct ath_dfs_host *dfs)
|
||||
{
|
||||
struct dfs_ar_state *ar;
|
||||
struct dfs_event *re=NULL;
|
||||
u_int32_t sumpeak=0,numpeaks,rssi,width,origregionsum=0, i;
|
||||
u_int16_t thistimestamp;
|
||||
int empty;
|
||||
u_int32_t result = 0;
|
||||
|
||||
if (dfs == NULL) {
|
||||
A_PRINTF("%s: sc_dfs is NULL\n", __func__);
|
||||
return result;
|
||||
}
|
||||
ar = (struct dfs_ar_state *) &(dfs->dfs_ar_state);
|
||||
ATH_ARQ_LOCK(dfs);
|
||||
empty = STAILQ_EMPTY(&(dfs->dfs_arq));
|
||||
ATH_ARQ_UNLOCK(dfs);
|
||||
while (!empty) {
|
||||
ATH_ARQ_LOCK(dfs);
|
||||
re = STAILQ_FIRST(&(dfs->dfs_arq));
|
||||
if (re != NULL)
|
||||
STAILQ_REMOVE_HEAD(&(dfs->dfs_arq), re_list);
|
||||
ATH_ARQ_UNLOCK(dfs);
|
||||
if (re == NULL)
|
||||
return result;
|
||||
|
||||
thistimestamp = re->re_ts;
|
||||
rssi = re->re_rssi;
|
||||
width = re->re_dur;
|
||||
|
||||
/* Return the dfs event to the free event list */
|
||||
OS_MEMZERO(re, sizeof(struct dfs_event));
|
||||
ATH_DFSEVENTQ_LOCK(dfs);
|
||||
STAILQ_INSERT_TAIL(&(dfs->dfs_eventq), re, re_list);
|
||||
ATH_DFSEVENTQ_UNLOCK(dfs);
|
||||
|
||||
/* determine if current radar is an extension of previous radar */
|
||||
if (ar->ar_prevwidth == 255) {
|
||||
/* tag on previous width for consideraion of low data rate ACKs */
|
||||
ar->ar_prevwidth += width;
|
||||
width = (width == 255) ? 255 : ar->ar_prevwidth;
|
||||
} else if ((width == 255) &&
|
||||
(ar->ar_prevwidth == 510 ||
|
||||
ar->ar_prevwidth == 765 ||
|
||||
ar->ar_prevwidth == 1020)) {
|
||||
/* Aggregate up to 5 consecuate max radar widths
|
||||
* to consider 11Mbps long preamble 1500-byte pkts
|
||||
*/
|
||||
ar->ar_prevwidth += width;
|
||||
} else if (ar->ar_prevwidth == 1275 && width != 255) {
|
||||
/* Found 5th consecute maxed out radar, reset history */
|
||||
width += ar->ar_prevwidth;
|
||||
ar->ar_prevwidth = 0;
|
||||
} else if (ar->ar_prevwidth > 255) {
|
||||
/* Ignore if there are less than 5 consecutive maxed out radars */
|
||||
ar->ar_prevwidth = width;
|
||||
width = 255;
|
||||
} else {
|
||||
ar->ar_prevwidth = width;
|
||||
}
|
||||
/* For ignoring noises with radar duration in ranges of 3-30: AP4x */
|
||||
if ((width >= 257 && width <= 278) || /* Region 7 - 5.5Mbps (long pre) ACK = 270 = 216 us */
|
||||
(width >= 295 && width <= 325) || /* Region 8 - 2Mbps (long pre) ACKC = 320 = 256us */
|
||||
(width >= 1280 && width <= 1300)) {
|
||||
u_int16_t wraparoundadj=0;
|
||||
u_int16_t base = (width >= 1280) ? 1275 : 255;
|
||||
if (thistimestamp < ar->ar_prevtimestamp) {
|
||||
wraparoundadj = 32768;
|
||||
}
|
||||
if ((thistimestamp + wraparoundadj - ar->ar_prevtimestamp) !=
|
||||
(width - base)) {
|
||||
width = 1;
|
||||
}
|
||||
}
|
||||
if (width <= 10) {
|
||||
ATH_ARQ_LOCK(dfs);
|
||||
empty = STAILQ_EMPTY(&(dfs->dfs_arq));
|
||||
ATH_ARQ_UNLOCK(dfs);
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* Overloading the width=2 in: Store a count of radars w/max duration
|
||||
* and high RSSI (not noise)
|
||||
*/
|
||||
if ((width == 255) && (rssi > DFS_AR_RSSI_THRESH_STRONG_PKTS))
|
||||
width = 2;
|
||||
/*
|
||||
* Overloading the width=3 bin:
|
||||
* Double and store a count of rdars of durtaion that matches 11Mbps (long preamble)
|
||||
* TCP ACKs or 1500-byte data packets
|
||||
*/
|
||||
if ((width >= 1280 && width <= 1300) ||
|
||||
(width >= 318 && width <= 325)) {
|
||||
width = 3;
|
||||
ar->ar_phyerrcount[3] += 2;
|
||||
ar->ar_acksum += 2;
|
||||
}
|
||||
/* build histogram of radar duration */
|
||||
if (width > 0 && width <= 510)
|
||||
ar->ar_phyerrcount[width]++;
|
||||
else {
|
||||
/* invalid radar width, throw it away */
|
||||
ATH_ARQ_LOCK(dfs);
|
||||
empty = STAILQ_EMPTY(&(dfs->dfs_arq));
|
||||
ATH_ARQ_UNLOCK(dfs);
|
||||
continue;
|
||||
}
|
||||
/* Received radar of interest (i.e., signature match), proceed to check if
|
||||
* there is enough neighboring traffic to drop out of Turbo
|
||||
*/
|
||||
if ((width >= 33 && width <= 38) || /* Region 0: 24Mbps ACK = 35 = 28us */
|
||||
(width >= 39 && width <= 44) || /* Region 1: 12Mbps ACK = 40 = 32us */
|
||||
(width >= 53 && width <= 58) || /* Region 2: 6Mbps ACK = 55 = 44us */
|
||||
(width >= 126 && width <= 140) || /* Region 3: 11Mbps ACK = 135 = 108us */
|
||||
(width >= 141 && width <= 160) || /* Region 4: 5.5Mbps ACK = 150 = 120us */
|
||||
(width >= 189 && width <= 210) || /* Region 5: 2Mbps ACK = 200 = 160us */
|
||||
(width >= 360 && width <= 380) || /* Region 6 1Mbps ACK = 400 = 320us */
|
||||
(width >= 257 && width <= 270) || /* Region 7 5.5Mbps (Long Pre) ACK = 270 = 216us */
|
||||
(width >= 295 && width <= 302) || /* Region 8 2Mbps (Long Pre) ACK = 320 = 256us */
|
||||
/* Ignoring Region 9 due to overlap with 255 which is same as board noise */
|
||||
/* Region 9 11Mbps (Long Pre) ACK = 255 = 204us */
|
||||
(width == 3)) {
|
||||
ar->ar_acksum++;
|
||||
/* double the count for strong radars that match one of the ACK signatures */
|
||||
if (rssi > DFS_AR_RSSI_DOUBLE_THRESHOLD) {
|
||||
ar->ar_phyerrcount[width]++;
|
||||
ar->ar_acksum++;
|
||||
}
|
||||
UPDATE_TOP_THREE_PEAKS(ar->ar_phyerrcount,
|
||||
ar->ar_peaklist, width);
|
||||
/* sum the counts of these peaks */
|
||||
numpeaks = DFS_AR_MAX_NUM_PEAKS;
|
||||
origregionsum = ar->ar_acksum;
|
||||
for (i=0; i<= DFS_AR_MAX_NUM_PEAKS; i++) {
|
||||
if (ar->ar_peaklist[i] > 0) {
|
||||
if ((i==0) &&
|
||||
(ar->ar_peaklist[i] == 3) &&
|
||||
(ar->ar_phyerrcount[3] <
|
||||
ar->ar_phyerrcount[2]) &&
|
||||
(ar->ar_phyerrcount[3] > 6)) {
|
||||
/*
|
||||
* If the top peak is one that
|
||||
* maches the 11Mbps long
|
||||
* preamble TCP Ack/1500-byte
|
||||
* data, include the count for
|
||||
* radars that hav emax
|
||||
* duration and high rssi
|
||||
* (width = 2) to boost the
|
||||
* sum for the PAR test that
|
||||
* follows */
|
||||
sumpeak += (ar->ar_phyerrcount[2]
|
||||
+ ar->ar_phyerrcount[3]);
|
||||
ar->ar_acksum += (ar->ar_phyerrcount[2]
|
||||
+ ar->ar_phyerrcount[3]);
|
||||
} else {
|
||||
sumpeak += ar->ar_phyerrcount[ar->ar_peaklist[i]];
|
||||
}
|
||||
} else
|
||||
numpeaks--;
|
||||
}
|
||||
/*
|
||||
* If sum of patterns matches exceeds packet threshold,
|
||||
* perform comparison between peak-to-avg ratio against parThreshold
|
||||
*/
|
||||
if ((ar->ar_acksum > ar->ar_packetthreshold) &&
|
||||
((sumpeak * DFS_AR_REGION_WIDTH) > (ar->ar_parthreshold * numpeaks *
|
||||
ar->ar_acksum))) {
|
||||
/* neighboring traffic detected, get out of Turbo */
|
||||
result = TRAFFIC_DETECTED;
|
||||
OS_MEMZERO(ar->ar_peaklist, sizeof(ar->ar_peaklist));
|
||||
ar->ar_acksum = 0;
|
||||
OS_MEMZERO(ar->ar_phyerrcount, sizeof(ar->ar_phyerrcount));
|
||||
} else {
|
||||
/*
|
||||
* reset sum of matches to discount the count of
|
||||
* strong radars with max duration
|
||||
*/
|
||||
ar->ar_acksum = origregionsum;
|
||||
}
|
||||
}
|
||||
ar->ar_prevtimestamp = thistimestamp;
|
||||
ATH_ARQ_LOCK(dfs);
|
||||
empty = STAILQ_EMPTY(&(dfs->dfs_arq));
|
||||
ATH_ARQ_UNLOCK(dfs);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void dfs_reset_ar(struct ath_dfs_host *dfs)
|
||||
{
|
||||
|
||||
if (dfs == NULL) {
|
||||
A_PRINTF("%s: sc_dfs is NULL\n", __func__);
|
||||
return;
|
||||
}
|
||||
OS_MEMZERO(&dfs->dfs_ar_state, sizeof(dfs->dfs_ar_state));
|
||||
dfs->dfs_ar_state.ar_packetthreshold = DFS_AR_PKT_COUNT_THRESH;
|
||||
dfs->dfs_ar_state.ar_parthreshold = DFS_AR_ACK_DETECT_PAR_THRESH;
|
||||
dfs->dfs_ar_state.ar_radarrssi = DFS_AR_RADAR_RSSI_THR;
|
||||
|
||||
}
|
||||
|
||||
void dfs_reset_arq(struct ath_dfs_host *dfs)
|
||||
{
|
||||
struct dfs_event *event;
|
||||
|
||||
if (dfs == NULL) {
|
||||
A_PRINTF("%s: sc_dfs is NULL\n", __func__);
|
||||
return;
|
||||
}
|
||||
ATH_ARQ_LOCK(dfs);
|
||||
ATH_DFSEVENTQ_LOCK(dfs);
|
||||
while (!STAILQ_EMPTY(&(dfs->dfs_arq))) {
|
||||
event = STAILQ_FIRST(&(dfs->dfs_arq));
|
||||
STAILQ_REMOVE_HEAD(&(dfs->dfs_arq), re_list);
|
||||
OS_MEMZERO(event, sizeof(struct dfs_event));
|
||||
STAILQ_INSERT_TAIL(&(dfs->dfs_eventq), event, re_list);
|
||||
}
|
||||
ATH_DFSEVENTQ_UNLOCK(dfs);
|
||||
ATH_ARQ_UNLOCK(dfs);
|
||||
}
|
||||
|
||||
|
||||
#endif /* ATH_SUPPORT_DFS */
|
||||
340
drivers/net/wireless/ar6003/host/dfs/dfs_bindetects.c
Normal file
340
drivers/net/wireless/ar6003/host/dfs/dfs_bindetects.c
Normal file
|
|
@ -0,0 +1,340 @@
|
|||
/*
|
||||
* Copyright (c) 2002-2010, Atheros Communications Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef ATH_SUPPORT_DFS
|
||||
#include "dfs_host.h"
|
||||
|
||||
int dfs_bin_fixedpattern_check(struct ath_dfs_host *dfs, struct dfs_filter *rf, u_int32_t dur, int ext_chan_flag, u_int32_t ext_chan_busy)
|
||||
{
|
||||
struct dfs_pulseline *pl = dfs->pulses;
|
||||
int i, n, refpri, primargin, numpulses=0;
|
||||
u_int64_t start_ts, end_ts, event_ts, prev_event_ts, next_event_ts, window_start, window_end;
|
||||
u_int32_t index, next_index, deltadur;
|
||||
|
||||
/* For fixed pattern types, rf->rf_patterntype=1*/
|
||||
primargin = dfs_get_pri_margin(ext_chan_flag, (rf->rf_patterntype==1),dfs->dfs_rinfo.rn_lastfull_ts, ext_chan_busy);
|
||||
|
||||
refpri = (rf->rf_minpri + rf->rf_maxpri)/2;
|
||||
index = pl->pl_lastelem;
|
||||
end_ts = pl->pl_elems[index].p_time;
|
||||
start_ts = end_ts - (refpri*rf->rf_numpulses);
|
||||
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS3, "lastelem ts=%llu start_ts=%llu, end_ts=%llu\n", (unsigned long long)pl->pl_elems[index].p_time, (unsigned long long)start_ts, (unsigned long long)end_ts);
|
||||
/* find the index of first element in our window of interest */
|
||||
for(i=0;i<pl->pl_numelems;i++) {
|
||||
index = (index-1) & DFS_MAX_PULSE_BUFFER_MASK;
|
||||
if(pl->pl_elems[index].p_time >= start_ts )
|
||||
continue;
|
||||
else {
|
||||
index = (index) & DFS_MAX_PULSE_BUFFER_MASK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (n=0;n<=rf->rf_numpulses; n++) {
|
||||
window_start = (start_ts + (refpri*n))-(primargin+n);
|
||||
window_end = window_start + 2*(primargin+n);
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,
|
||||
"window_start %u window_end %u \n",
|
||||
(u_int32_t)window_start, (u_int32_t)window_end);
|
||||
for(i=0;i<pl->pl_numelems;i++) {
|
||||
prev_event_ts = pl->pl_elems[index].p_time;
|
||||
index = (index+1) & DFS_MAX_PULSE_BUFFER_MASK;
|
||||
event_ts = pl->pl_elems[index].p_time;
|
||||
next_index = (index+1) & DFS_MAX_PULSE_BUFFER_MASK;
|
||||
next_event_ts = pl->pl_elems[next_index].p_time;
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,
|
||||
"ts %u \n", (u_int32_t)event_ts);
|
||||
if( (event_ts <= window_end) && (event_ts >= window_start)){
|
||||
deltadur = DFS_DIFF(pl->pl_elems[index].p_dur, dur);
|
||||
if( (pl->pl_elems[index].p_dur == 1) ||
|
||||
((dur != 1) && (deltadur <= 2))) {
|
||||
numpulses++;
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,
|
||||
"numpulses %u \n", numpulses);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if( event_ts > window_end) {
|
||||
index = (index-1) & DFS_MAX_PULSE_BUFFER_MASK;
|
||||
break;
|
||||
}
|
||||
else if( event_ts == prev_event_ts) {
|
||||
if( ((next_event_ts - event_ts) > refpri) ||
|
||||
((next_event_ts - event_ts) == 0)) {
|
||||
deltadur = DFS_DIFF(pl->pl_elems[index].p_dur, dur);
|
||||
if( (pl->pl_elems[index].p_dur == 1) ||
|
||||
((pl->pl_elems[index].p_dur != 1) && (deltadur <= 2))) {
|
||||
numpulses++;
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,
|
||||
"zero PRI: numpulses %u \n", numpulses);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (numpulses >= dfs_get_filter_threshold(rf, ext_chan_flag, dfs->dfs_rinfo.rn_lastfull_ts, ext_chan_busy)) {
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, "%s FOUND filterID=%u numpulses=%d unadj thresh=%d\n", __func__, rf->rf_pulseid, numpulses, rf->rf_threshold);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
dfs_add_pulse(struct ath_dfs_host *dfs, struct dfs_filter *rf, struct dfs_event *re,
|
||||
u_int32_t deltaT)
|
||||
{
|
||||
u_int32_t index,n, window, pri;
|
||||
struct dfs_delayline *dl;
|
||||
|
||||
dl = &rf->rf_dl;
|
||||
/* Circular buffer of size 2^n */
|
||||
index = (dl->dl_lastelem + 1) & DFS_MAX_DL_MASK;
|
||||
//if ((dl->dl_numelems+1) == DFS_MAX_DL_SIZE)
|
||||
if ((dl->dl_numelems) == DFS_MAX_DL_SIZE)
|
||||
dl->dl_firstelem = (dl->dl_firstelem + 1) & DFS_MAX_DL_MASK;
|
||||
else
|
||||
dl->dl_numelems++;
|
||||
dl->dl_lastelem = index;
|
||||
dl->dl_elems[index].de_time = deltaT;
|
||||
window = deltaT;
|
||||
dl->dl_elems[index].de_dur = re->re_dur;
|
||||
dl->dl_elems[index].de_rssi = re->re_rssi;
|
||||
|
||||
for (n=0;n<dl->dl_numelems-1; n++) {
|
||||
index = (index-1) & DFS_MAX_DL_MASK;
|
||||
pri = dl->dl_elems[index].de_time;
|
||||
window += pri;
|
||||
if (window > rf->rf_filterlen) {
|
||||
dl->dl_firstelem = (index+1) & DFS_MAX_DL_MASK;
|
||||
dl->dl_numelems = n+1;
|
||||
}
|
||||
}
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,
|
||||
"dl firstElem = %d lastElem = %d\n",dl->dl_firstelem,
|
||||
dl->dl_lastelem);
|
||||
}
|
||||
|
||||
|
||||
int dfs_bin_check(struct ath_dfs_host *dfs, struct dfs_filter *rf,
|
||||
u_int32_t deltaT, u_int32_t width, int ext_chan_flag, u_int32_t ext_chan_busy)
|
||||
{
|
||||
u_int32_t refpri, refdur, searchpri, deltapri, averagerefpri;
|
||||
u_int32_t n, i, primargin, durmargin, highscore, highscoreindex;
|
||||
int score[DFS_MAX_DL_SIZE], delayindex, dindex, found=0;
|
||||
struct dfs_delayline *dl;
|
||||
u_int32_t scoreindex, lowpriindex= 0, lowpri = 0xffff;
|
||||
int numpulses=0;
|
||||
|
||||
dl = &rf->rf_dl;
|
||||
if( dl->dl_numelems < (rf->rf_threshold-1)) {
|
||||
return 0;
|
||||
}
|
||||
if( deltaT > rf->rf_filterlen)
|
||||
return 0;
|
||||
|
||||
primargin = dfs_get_pri_margin(ext_chan_flag, (rf->rf_patterntype==1),
|
||||
dfs->dfs_rinfo.rn_lastfull_ts, ext_chan_busy);
|
||||
|
||||
|
||||
if(rf->rf_maxdur < 10) {
|
||||
durmargin = 4;
|
||||
}
|
||||
else {
|
||||
durmargin = 6;
|
||||
}
|
||||
|
||||
if( rf->rf_patterntype == 1 ){
|
||||
found = dfs_bin_fixedpattern_check(dfs, rf, width, ext_chan_flag, ext_chan_busy);
|
||||
if(found) {
|
||||
dl->dl_numelems = 0;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
OS_MEMZERO(score, sizeof(int)*DFS_MAX_DL_SIZE);
|
||||
/* find out the lowest pri */
|
||||
for (n=0;n<dl->dl_numelems; n++) {
|
||||
delayindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK;
|
||||
refpri = dl->dl_elems[delayindex].de_time;
|
||||
if( refpri == 0)
|
||||
continue;
|
||||
else if(refpri < lowpri) {
|
||||
lowpri = dl->dl_elems[delayindex].de_time;
|
||||
lowpriindex = n;
|
||||
}
|
||||
}
|
||||
/* find out the each delay element's pri score */
|
||||
for (n=0;n<dl->dl_numelems; n++) {
|
||||
delayindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK;
|
||||
refpri = dl->dl_elems[delayindex].de_time;
|
||||
if( refpri == 0)
|
||||
continue;
|
||||
for (i=0;i<dl->dl_numelems; i++) {
|
||||
dindex = (dl->dl_firstelem + i) & DFS_MAX_DL_MASK;
|
||||
searchpri = dl->dl_elems[dindex].de_time;
|
||||
deltapri = DFS_DIFF(searchpri, refpri);
|
||||
if( deltapri < primargin)
|
||||
score[n]++;
|
||||
}
|
||||
if( score[n] > rf->rf_threshold) {
|
||||
/* we got the most possible candidate,
|
||||
* no need to continue further */
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* find out the high scorer */
|
||||
highscore = 0;
|
||||
highscoreindex = 0;
|
||||
for (n=0;n<dl->dl_numelems; n++) {
|
||||
if( score[n] > highscore) {
|
||||
highscore = score[n];
|
||||
highscoreindex = n;
|
||||
}
|
||||
else if( score[n] == highscore ) {
|
||||
/*more than one pri has highscore take the least pri */
|
||||
delayindex = (dl->dl_firstelem + highscoreindex) & DFS_MAX_DL_MASK;
|
||||
dindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK;
|
||||
if( dl->dl_elems[dindex].de_time <=
|
||||
dl->dl_elems[delayindex].de_time ) {
|
||||
highscoreindex = n;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* find the average pri of pulses around the pri of highscore or
|
||||
* the pulses around the lowest pri */
|
||||
if( highscore < 3) {
|
||||
scoreindex = lowpriindex;
|
||||
}
|
||||
else {
|
||||
scoreindex = highscoreindex;
|
||||
}
|
||||
/* We got the possible pri, save its parameters as reference */
|
||||
delayindex = (dl->dl_firstelem + scoreindex) & DFS_MAX_DL_MASK;
|
||||
refdur = dl->dl_elems[delayindex].de_dur;
|
||||
refpri = dl->dl_elems[delayindex].de_time;
|
||||
averagerefpri = 0;
|
||||
|
||||
numpulses = dfs_bin_pri_check(dfs, rf, dl, score[scoreindex], refpri, refdur, ext_chan_flag, ext_chan_busy);
|
||||
if (numpulses >= dfs_get_filter_threshold(rf, ext_chan_flag, dfs->dfs_rinfo.rn_lastfull_ts, ext_chan_busy)) {
|
||||
found = 1;
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, "ext_flag=%d MATCH filter=%u numpulses=%u thresh=%u refpri=%d primargin=%d\n", ext_chan_flag, rf->rf_pulseid, numpulses,rf->rf_threshold, refpri, primargin);
|
||||
dfs_print_delayline(dfs, &rf->rf_dl);
|
||||
dfs_print_filter(dfs, rf);
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
int dfs_bin_pri_check(struct ath_dfs_host *dfs, struct dfs_filter *rf,
|
||||
struct dfs_delayline *dl, u_int32_t score,
|
||||
u_int32_t refpri, u_int32_t refdur, int ext_chan_flag, u_int32_t ext_chan_busy)
|
||||
{
|
||||
u_int32_t searchpri, searchdur, searchrssi, deltapri, deltadur, averagerefpri=0;
|
||||
int primultiples[6];
|
||||
int delayindex, dindex;
|
||||
u_int32_t i, j, primargin, durmargin, highscore=score, highscoreindex=0;
|
||||
int numpulses=1; //first pulse in the burst is most likely being filtered out based on maxfilterlen
|
||||
|
||||
//Use the adjusted PRI margin to reduce false alarms
|
||||
/* For non fixed pattern types, rf->rf_patterntype=0*/
|
||||
primargin = dfs_get_pri_margin(ext_chan_flag, (rf->rf_patterntype==1),
|
||||
dfs->dfs_rinfo.rn_lastfull_ts, ext_chan_busy);
|
||||
|
||||
|
||||
if(rf->rf_maxdur < 10) {
|
||||
durmargin = 4;
|
||||
}
|
||||
else {
|
||||
durmargin = 6;
|
||||
}
|
||||
if( score > 1) {
|
||||
for (i=0;i<dl->dl_numelems; i++) {
|
||||
dindex = (dl->dl_firstelem + i) & DFS_MAX_DL_MASK;
|
||||
searchpri = dl->dl_elems[dindex].de_time;
|
||||
deltapri = DFS_DIFF(searchpri, refpri);
|
||||
if( deltapri < primargin)
|
||||
averagerefpri += searchpri;
|
||||
}
|
||||
refpri = (averagerefpri/score); //average
|
||||
}
|
||||
/* Note: Following primultiple calculation should be done once per filter
|
||||
* during initialization stage (dfs_attach) and stored in its array
|
||||
* atleast for fixed frequency types like FCC Bin1 to save some CPU cycles.
|
||||
* multiplication, devide operators in the following code are left as it is
|
||||
* for readability hoping the complier will use left/right shifts wherever possible
|
||||
*/
|
||||
if( refpri > rf->rf_maxpri) {
|
||||
primultiples[0] = (refpri - refdur)/2;
|
||||
primultiples[1] = refpri;
|
||||
primultiples[2] = refpri + primultiples[0];
|
||||
primultiples[3] = (refpri - refdur)*2;
|
||||
primultiples[4] = primultiples[3] + primultiples[0];
|
||||
primultiples[5] = primultiples[3] + refpri;
|
||||
}
|
||||
else {
|
||||
primultiples[0] = refpri;
|
||||
primultiples[1] = refpri + primultiples[0];
|
||||
primultiples[2] = refpri + primultiples[1];
|
||||
primultiples[3] = refpri + primultiples[2];
|
||||
primultiples[4] = refpri + primultiples[3];
|
||||
primultiples[5] = refpri + primultiples[4];
|
||||
}
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,
|
||||
"pri0 = %d pri1 = %d pri2 = %d pri3 = %d pri4 = %d pri5 = %d\n",
|
||||
primultiples[0], primultiples[1], primultiples[2],
|
||||
primultiples[3], primultiples[4], primultiples[5]);
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,
|
||||
"refpri = %d high score = %d index = %d numpulses = %d\n",
|
||||
refpri, highscore, highscoreindex, numpulses);
|
||||
/* Count the other delay elements that have pri and dur with in the
|
||||
* acceptable range from the reference one */
|
||||
for (i=0; i<dl->dl_numelems; i++) {
|
||||
delayindex = (dl->dl_firstelem + i) & DFS_MAX_DL_MASK;
|
||||
searchpri = dl->dl_elems[delayindex].de_time;
|
||||
if( searchpri == 0) {
|
||||
/* This events PRI is zero, take it as a
|
||||
* valid pulse but decrement next event's PRI by refpri
|
||||
*/
|
||||
dindex = (delayindex+1)& DFS_MAX_DL_MASK;
|
||||
dl->dl_elems[dindex].de_time -= refpri;
|
||||
searchpri = refpri;
|
||||
}
|
||||
searchdur = dl->dl_elems[delayindex].de_dur;
|
||||
searchrssi = dl->dl_elems[delayindex].de_rssi;
|
||||
deltadur = DFS_DIFF(searchdur, refdur);
|
||||
for(j=0; j<6; j++) {
|
||||
deltapri = DFS_DIFF(searchpri, primultiples[j]);
|
||||
/* May need to revisit this as this increases the primargin by 5*/
|
||||
/* if( deltapri < (primargin+j)) { */
|
||||
if( deltapri < (primargin)) {
|
||||
if( deltadur < durmargin) {
|
||||
if( (refdur < 8) || ((refdur >=8)&&
|
||||
(searchrssi < 250))) {
|
||||
|
||||
numpulses++;
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,
|
||||
"rf->minpri=%d rf->maxpri=%d searchpri = %d index = %d numpulses = %d deltapri=%d j=%d\n",
|
||||
rf->rf_minpri, rf->rf_maxpri, searchpri, i, numpulses, deltapri, j);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return numpulses;
|
||||
}
|
||||
#endif /* ATH_SUPPORT_DFS */
|
||||
71
drivers/net/wireless/ar6003/host/dfs/dfs_debug.c
Normal file
71
drivers/net/wireless/ar6003/host/dfs/dfs_debug.c
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (c) 2002-2010, Atheros Communications Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef ATH_SUPPORT_DFS
|
||||
#include "dfs_host.h"
|
||||
|
||||
void
|
||||
dfs_print_delayline(struct ath_dfs_host *dfs, struct dfs_delayline *dl)
|
||||
{
|
||||
int i=0,index;
|
||||
struct dfs_delayelem *de;
|
||||
|
||||
index = dl->dl_lastelem;
|
||||
for (i=0; i<dl->dl_numelems; i++) {
|
||||
de = &dl->dl_elems[index];
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,
|
||||
"Elem %d: ts = %u (0x%x) dur=%u\n",i,
|
||||
de->de_time, de->de_time, de->de_dur);
|
||||
index = (index - 1)& DFS_MAX_DL_MASK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
dfs_print_filter(struct ath_dfs_host *dfs, struct dfs_filter *rf)
|
||||
{
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, "filterID[%d] rf_numpulses=%u; rf->rf_minpri=%u; rf->rf_maxpri=%u; rf->rf_threshold=%u; rf->rf_filterlen=%u; rf->rf_mindur=%u; rf->rf_maxdur=%u\n", rf->rf_pulseid, rf->rf_numpulses, rf->rf_minpri, rf->rf_maxpri, rf->rf_threshold, rf->rf_filterlen, rf->rf_mindur, rf->rf_maxdur);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
dfs_print_filters(struct ath_dfs_host *dfs)
|
||||
{
|
||||
struct dfs_filtertype *ft = NULL;
|
||||
struct dfs_filter *rf;
|
||||
int i,j;
|
||||
|
||||
if (dfs == NULL) {
|
||||
A_PRINTF("%s: sc_dfs is NULL\n", __func__);
|
||||
return;
|
||||
}
|
||||
for (i=0; i<DFS_MAX_RADAR_TYPES; i++) {
|
||||
if (dfs->dfs_radarf[i] != NULL) {
|
||||
ft = dfs->dfs_radarf[i];
|
||||
if((ft->ft_numfilters > DFS_MAX_NUM_RADAR_FILTERS) || (!ft->ft_numfilters))
|
||||
continue;
|
||||
printk("===========ft->ft_numfilters=%u===========\n", ft->ft_numfilters);
|
||||
for (j=0; j<ft->ft_numfilters; j++) {
|
||||
rf = &(ft->ft_filters[j]);
|
||||
printk("filter[%d] filterID = %d rf_numpulses=%u; rf->rf_minpri=%u; rf->rf_maxpri=%u; rf->rf_threshold=%u; rf->rf_filterlen=%u; rf->rf_mindur=%u; rf->rf_maxdur=%u\n",j, rf->rf_pulseid,
|
||||
rf->rf_numpulses, rf->rf_minpri, rf->rf_maxpri, rf->rf_threshold, rf->rf_filterlen, rf->rf_mindur, rf->rf_maxdur);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* ATH_SUPPORT_DFS */
|
||||
189
drivers/net/wireless/ar6003/host/dfs/dfs_fcc_bin5.c
Normal file
189
drivers/net/wireless/ar6003/host/dfs/dfs_fcc_bin5.c
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
/*
|
||||
* Copyright (c) 2002-2010, Atheros Communications Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef ATH_SUPPORT_DFS
|
||||
#include "dfs_host.h"
|
||||
|
||||
|
||||
int dfs_bin5_addpulse(struct ath_dfs_host *dfs, struct dfs_bin5radars *br,
|
||||
struct dfs_event *re, u_int64_t thists)
|
||||
{
|
||||
u_int32_t index,stop;
|
||||
u_int64_t tsDelta;
|
||||
|
||||
/* Check if this pulse is a valid pulse in terms of repetition,
|
||||
* if not, return without adding it to the queue.
|
||||
* PRI : Pulse Repitetion Interval
|
||||
* BRI : Burst Repitetion Interval */
|
||||
if( br->br_numelems != 0){
|
||||
index = br->br_lastelem;
|
||||
tsDelta = thists - br->br_elems[index].be_ts;
|
||||
if( (tsDelta < DFS_BIN5_PRI_LOWER_LIMIT) ||
|
||||
( (tsDelta > DFS_BIN5_PRI_HIGHER_LIMIT) &&
|
||||
(tsDelta < DFS_BIN5_BRI_LOWER_LIMIT))) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/* Circular buffer of size 2^n */
|
||||
index = (br->br_lastelem +1) & DFS_MAX_B5_MASK;
|
||||
br->br_lastelem = index;
|
||||
if (br->br_numelems == DFS_MAX_B5_SIZE)
|
||||
br->br_firstelem = (br->br_firstelem+1)&DFS_MAX_B5_MASK;
|
||||
else
|
||||
br->br_numelems++;
|
||||
br->br_elems[index].be_ts = thists;
|
||||
br->br_elems[index].be_rssi = re->re_rssi;
|
||||
br->br_elems[index].be_dur = re->re_dur;
|
||||
stop = 0;
|
||||
index = br->br_firstelem;
|
||||
while ((!stop) && (br->br_numelems-1) > 0) {
|
||||
if ((thists - br->br_elems[index].be_ts) >
|
||||
((u_int64_t) br->br_pulse.b5_timewindow)) {
|
||||
br->br_numelems--;
|
||||
br->br_firstelem = (br->br_firstelem +1) & DFS_MAX_B5_MASK;
|
||||
index = br->br_firstelem;
|
||||
} else
|
||||
stop = 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the dfs structure is NULL (which should be illegal if everyting is working
|
||||
* properly, then signify that a bin5 radar was found
|
||||
*/
|
||||
|
||||
int dfs_bin5_check(struct ath_dfs_host *dfs)
|
||||
{
|
||||
struct dfs_bin5radars *br;
|
||||
int index[DFS_MAX_B5_SIZE];
|
||||
u_int32_t n, i, this, prev, rssi_diff, width_diff, bursts= 0;
|
||||
u_int32_t total_diff=0, average_diff, total_width=0, average_width, numevents=0;
|
||||
u_int64_t pri;
|
||||
|
||||
if (dfs == NULL) {
|
||||
A_PRINTF("%s: sc_dfs is NULL\n", __func__);
|
||||
return 1;
|
||||
}
|
||||
for (n=0;n<dfs->dfs_rinfo.rn_numbin5radars; n++) {
|
||||
br = &(dfs->dfs_b5radars[n]);
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS1,
|
||||
"Num elems = %d\n", br->br_numelems);
|
||||
prev = br->br_firstelem;
|
||||
for(i=0;i<br->br_numelems;i++){
|
||||
this = ((br->br_firstelem +i) & DFS_MAX_B5_MASK);
|
||||
/* Rule 1: 1000 <= PRI <= 2000 + some margin */
|
||||
if( br->br_elems[this].be_ts >= br->br_elems[prev].be_ts ) {
|
||||
pri = br->br_elems[this].be_ts - br->br_elems[prev].be_ts;
|
||||
}
|
||||
else {//roll over case
|
||||
//pri = (0xffffffffffffffff - br->br_elems[prev].be_ts) + br->br_elems[this].be_ts;
|
||||
pri = br->br_elems[this].be_ts;
|
||||
}
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS2," pri=%llu this.ts=%llu prev.ts=%llu\n", pri, br->br_elems[this].be_ts, br->br_elems[prev].be_ts);
|
||||
if(( (pri >= DFS_BIN5_PRI_LOWER_LIMIT) && (pri <= DFS_BIN5_PRI_HIGHER_LIMIT))) { //pri: pulse repitition interval in us
|
||||
/* Rule 2: pulse width of the pulses in the burst should be same (+/- margin) */
|
||||
if( br->br_elems[this].be_dur >= br->br_elems[prev].be_dur) {
|
||||
width_diff = br->br_elems[this].be_dur - br->br_elems[prev].be_dur;
|
||||
}
|
||||
else {
|
||||
width_diff = br->br_elems[prev].be_dur - br->br_elems[this].be_dur;
|
||||
}
|
||||
if( width_diff <= DFS_BIN5_WIDTH_MARGIN ) {
|
||||
/* Rule 3: RSSI of the pulses in the burst should be same (+/- margin) */
|
||||
if( br->br_elems[this].be_rssi >= br->br_elems[prev].be_rssi) {
|
||||
rssi_diff = br->br_elems[this].be_rssi - br->br_elems[prev].be_rssi;
|
||||
}
|
||||
else {
|
||||
rssi_diff = br->br_elems[prev].be_rssi - br->br_elems[this].be_rssi;
|
||||
}
|
||||
if( rssi_diff <= DFS_BIN5_RSSI_MARGIN ) {
|
||||
bursts++;
|
||||
/* Save the indexes of this pair for later width variance check */
|
||||
if( numevents >= 2 ) {
|
||||
/* make sure the event is not duplicated,
|
||||
* possible in a 3 pulse burst */
|
||||
if( index[numevents-1] != prev) {
|
||||
index[numevents++] = prev;
|
||||
}
|
||||
}
|
||||
else {
|
||||
index[numevents++] = prev; }
|
||||
index[numevents++] = this;
|
||||
} else {
|
||||
DFS_DPRINTK(dfs,ATH_DEBUG_DFS2,"%s %d Bin5 rssi_diff=%d\n", __func__, __LINE__, rssi_diff);
|
||||
}
|
||||
} else {
|
||||
DFS_DPRINTK(dfs,ATH_DEBUG_DFS2,"%s %d Bin5 width_diff=%d\n", __func__, __LINE__, width_diff);
|
||||
}
|
||||
} else {
|
||||
DFS_DPRINTK(dfs,ATH_DEBUG_DFS2,"%s %d Bin5 PRI check fail pri=%llu\n", __func__, __LINE__,pri);
|
||||
}
|
||||
prev = this;
|
||||
}
|
||||
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "bursts=%u numevents=%u\n", bursts, numevents);
|
||||
if ( bursts >= br->br_pulse.b5_threshold) {
|
||||
if( (br->br_elems[br->br_lastelem].be_ts - br->br_elems[br->br_firstelem].be_ts) < 3000000 ) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
for (i=0; i<numevents; i++){
|
||||
total_width += br->br_elems[index[i]].be_dur;
|
||||
}
|
||||
average_width = total_width/numevents;
|
||||
for (i=0; i<numevents; i++){
|
||||
total_diff += DFS_DIFF(br->br_elems[index[i]].be_dur, average_width);
|
||||
}
|
||||
average_diff = total_diff/numevents;
|
||||
if( average_diff > DFS_BIN5_WIDTH_MARGIN ) {
|
||||
return 1;
|
||||
} else {
|
||||
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "bursts=%u numevents=%u total_width=%d average_width=%d total_diff=%d average_diff=%d\n", bursts, numevents, total_width, average_width, total_diff, average_diff);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
u_int8_t dfs_retain_bin5_burst_pattern(struct ath_dfs_host *dfs, u_int32_t diff_ts, u_int8_t old_dur)
|
||||
{
|
||||
|
||||
// Pulses may get split into 2 during chirping, this print is only to show that it happened, we do not handle this condition if we cannot detect the chirping
|
||||
// SPLIT pulses will have a time stamp difference of < 50
|
||||
if (diff_ts < 50) {
|
||||
DFS_DPRINTK(dfs,ATH_DEBUG_DFS1,"%s SPLIT pulse diffTs=%u dur=%d (old_dur=%d)\n", __func__, diff_ts, dfs->dfs_rinfo.dfs_last_bin5_dur, old_dur);
|
||||
}
|
||||
// Check if this is the 2nd or 3rd pulse in the same burst, PRI will be between 1000 and 2000 us
|
||||
if(((diff_ts >= DFS_BIN5_PRI_LOWER_LIMIT) && (diff_ts <= DFS_BIN5_PRI_HIGHER_LIMIT))) {
|
||||
|
||||
//This pulse belongs to the same burst as the pulse before, so return the same random duration for it
|
||||
DFS_DPRINTK(dfs,ATH_DEBUG_DFS1,"%s this pulse belongs to the same burst as before, give it same dur=%d (old_dur=%d)\n", __func__, dfs->dfs_rinfo.dfs_last_bin5_dur, old_dur);
|
||||
|
||||
return (dfs->dfs_rinfo.dfs_last_bin5_dur);
|
||||
}
|
||||
// This pulse does not belong to this burst, return unchanged duration
|
||||
return old_dur;
|
||||
}
|
||||
|
||||
|
||||
#endif /* ATH_SUPPORT_DFS */
|
||||
45
drivers/net/wireless/ar6003/host/dfs/dfs_host_project.c
Normal file
45
drivers/net/wireless/ar6003/host/dfs/dfs_host_project.c
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* Copyright (c) 2002-2010, Atheros Communications Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef ATH_SUPPORT_DFS
|
||||
#include "dfs_host.h"
|
||||
#include "dfs_target_api.h"
|
||||
|
||||
void dfs_radar_task (unsigned long arg)
|
||||
{
|
||||
struct ath_dfs_host *dfs = (struct ath_dfs_host *)arg;
|
||||
A_INT16 chan_index;
|
||||
A_UINT8 bangradar;
|
||||
|
||||
//printk("\n%s\n",__func__);
|
||||
|
||||
if(dfs_process_radarevent_host(dfs, &chan_index, &bangradar)){
|
||||
if(!bangradar){
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: Radar detected on channel idx %d\n",
|
||||
__func__, chan_index);
|
||||
}
|
||||
|
||||
/* TODO: The radar detected event is sent from host in timer
|
||||
* context which could potentially cause issues with sleepable
|
||||
* WMI. Change this to process context later. */
|
||||
DFS_RADAR_DETECTED(dfs->dev_hdl, chan_index, bangradar);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* ATH_SUPPORT_DFS */
|
||||
|
||||
|
||||
375
drivers/net/wireless/ar6003/host/dfs/dfs_init.c
Normal file
375
drivers/net/wireless/ar6003/host/dfs/dfs_init.c
Normal file
|
|
@ -0,0 +1,375 @@
|
|||
/*
|
||||
* Copyright (c) 2002-2010, Atheros Communications Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef ATH_SUPPORT_DFS
|
||||
#include "dfs_host.h"
|
||||
#include "dfs_target_api.h"
|
||||
|
||||
|
||||
struct dfs_pulse ar6000_etsi_radars[] = {
|
||||
/* TYPE 1 */
|
||||
{15, 2, 750, 750, 0, 24, 7, 0, 2, 21, 0, -10, 0},
|
||||
/* TYPE 2 */
|
||||
{10, 5, 200, 200, 0, 24, 5, 1, 9, 21, 0, 3, 1},
|
||||
{10, 5, 300, 300, 0, 24, 8, 1, 9, 21, 0, 3, 2},
|
||||
{10, 5, 500, 500, 0, 24, 8, 1, 9, 21, 1, 3, 3},
|
||||
{10, 5, 800, 800, 0, 24, 8, 1, 9, 21, 1, 3, 4},
|
||||
{10, 5, 1001, 1001, 0, 30, 8, 1, 9, 21, 0, 3, 5},
|
||||
/* TYPE 3 */
|
||||
{15, 16, 200, 200, 0, 24, 6, 10, 19, 22, 0, 3, 6},
|
||||
{15, 16, 300, 300, 0, 24, 6, 10, 19, 22, 0, 3, 7},
|
||||
{15, 16, 503, 503, 0, 24, 7, 10, 19, 22, 0, 3, 8},
|
||||
{15, 16, 809, 809, 0, 24, 7, 10, 19, 22, 0, 3, 9},
|
||||
{15, 16, 1014, 1014, 0, 30, 7, 10, 19, 22, 0, 3, 10},
|
||||
/* TYPE 4 */
|
||||
{15, 5, 1200, 1200, 0, 24, 7, 1, 9, 21, 0, 3, 11},
|
||||
{15, 5, 1500, 1500, 0, 30, 7, 1, 9, 21, 0, 3, 12},
|
||||
{15, 5, 1600, 1600, 0, 24, 7, 1, 9, 21, 0, 3, 13},
|
||||
{15, 16, 1200, 1200, 0, 30, 7, 10, 19, 22, 0, 3, 14},
|
||||
{15, 16, 1500, 1500, 0, 24, 7, 10, 19, 22, 0, 3, 15},
|
||||
{15, 16, 1600, 1600, 0, 24, 7, 10, 19, 22, 0, 3, 16},
|
||||
/* TYPE 5 */
|
||||
{25, 5, 2305, 2305, 0, 24, 12, 1, 9, 21, 0, 3, 17},
|
||||
{25, 5, 3009, 3009, 0, 24, 12, 1, 9, 21, 0, 3, 18},
|
||||
{25, 5, 3500, 3500, 0, 24, 12, 1, 9, 21, 0, 3, 19},
|
||||
{25, 5, 4000, 4000, 0, 24, 12, 1, 9, 21, 0, 3, 20},
|
||||
{25, 16, 2300, 2300, 0, 24, 12, 10, 20, 22, 0, 3, 21},
|
||||
{25, 16, 3000, 3000, 0, 24, 12, 10, 20, 22, 0, 3, 22},
|
||||
{25, 16, 3500, 3500, 0, 24, 12, 10, 20, 22, 0, 3, 23},
|
||||
{25, 16, 3850, 3850, 0, 24, 12, 10, 20, 22, 0, 3, 24},
|
||||
/* TYPE 6 */
|
||||
{20, 25, 2000, 2000, 0, 24, 10, 20, 26, 22, 0, 3, 25},
|
||||
{20, 25, 3000, 3000, 0, 24, 10, 20, 26, 22, 0, 3, 26},
|
||||
{20, 25, 4000, 4000, 0, 24, 10, 20, 26, 22, 0, 3, 27},
|
||||
{20, 37, 2000, 2000, 0, 24, 10, 30, 36, 22, 0, 3, 28},
|
||||
{20, 37, 3000, 3000, 0, 24, 10, 30, 36, 22, 0, 3, 29},
|
||||
{20, 37, 4000, 4000, 0, 24, 10, 30, 36, 22, 0, 3, 30},
|
||||
|
||||
/* TYPE staggered pulse */
|
||||
{20, 2, 300, 400, 2, 30, 10, 0, 2, 22, 0, 3, 31}, //0.8-2us, 2-3 bursts,300-400 PRF, 10 pulses each
|
||||
{30, 2, 400, 1200, 2, 30, 15, 0, 2, 22, 0, 3, 32}, //0.8-2us, 2-3 bursts, 400-1200 PRF, 15 pulses each
|
||||
|
||||
/* constant PRF based */
|
||||
{10, 5, 200, 1000, 0, 24, 6, 0, 8, 21, 0, -10, 33}, /*0.8-5us , 200-1000 PRF, 10 pulses */
|
||||
{15, 15, 200, 1600, 0, 24, 7, 0, 18, 21, 0, -10, 34}, /*0.8-15us , 200-1600 PRF, 15 pulses */
|
||||
{25, 15, 2300, 4000, 0, 24, 12, 0, 18, 21, 0, -10, 35}, /* 0.8-15 us, 2300-4000 PRF, 25 pulses*/
|
||||
{20, 30, 2000, 4000, 0, 24, 10, 19, 33, 21, 0, -10, 36}, /* 20-30us, 2000-4000 PRF, 20 pulses*/
|
||||
|
||||
};
|
||||
|
||||
/* The following are for FCC Bin 1-4 pulses */
|
||||
struct dfs_pulse ar6000_fcc_radars[] = {
|
||||
/* following two filters are specific to Japan/MKK4 */
|
||||
{18, 1, 720, 720, 1, 6, 6, 0, 1, 18, 0, 3, 17}, // 1389 +/- 6 us
|
||||
{18, 4, 250, 250, 1, 10, 5, 1, 6, 18, 0, 3, 18}, // 4000 +/- 6 us
|
||||
{18, 5, 260, 260, 1, 10, 6, 1, 6, 18, 0, 3, 19}, // 3846 +/- 7 us
|
||||
/* following filters are common to both FCC and JAPAN */
|
||||
{18, 1, 325, 1930, 0, 6, 7, 0, 1, 18, 0, 3, 0}, // 1428 +/- 7 us
|
||||
{9, 1, 3003, 3003, 1, 7, 5, 0, 1, 18, 0, 0, 1}, // 333 +/- 7 us
|
||||
|
||||
{23, 5, 6250, 6250, 0, 15, 11, 0, 7, 22, 0, 3, 2}, // 160 +/- 15 us
|
||||
{23, 5, 5263, 5263, 0, 18, 11, 0, 7, 22, 0, 3, 3}, // 190 +/- 15 us
|
||||
{23, 5, 4545, 4545, 0, 18, 11, 0, 7, 22, 0, 3, 4}, // 220 +/- 15 us
|
||||
|
||||
{18, 10, 4444, 4444, 0, 35, 6, 7, 13, 22, 0, 3, 5}, // 225 +/- 30 us
|
||||
{18, 10, 3636, 3636, 0, 25, 6, 7, 13, 22, 0, 3, 6}, // 275 +/- 25 us
|
||||
{18, 10, 3076, 3076, 0, 25, 8, 7, 13, 22, 0, 3, 7}, // 325 +/- 25 us
|
||||
{18, 10, 2666, 2666, 0, 25, 8, 7, 13, 22, 0, 3, 8}, // 375 +/- 25 us
|
||||
{18, 10, 2352, 2352, 0, 25, 8, 7, 13, 22, 0, 3, 9}, // 425 +/- 25 us
|
||||
{18, 10, 2105, 2105, 0, 30, 8, 7, 13, 22, 0, 3, 10}, // 475 +/- 30 us
|
||||
|
||||
{14, 15, 4444, 4444, 0, 35, 5, 13, 21, 22, 0, 3, 11}, // 225 +/- 30 us
|
||||
{14, 15, 3636, 3636, 0, 25, 5, 13, 24, 22, 0, 3, 12}, // 275 +/- 25 us
|
||||
{14, 15, 3076, 3076, 0, 25, 7, 13, 23, 22, 0, 3, 13}, // 325 +/- 25 us
|
||||
{14, 15, 2666, 2666, 0, 25, 7, 13, 23, 22, 0, 3, 14}, // 375 +/- 25 us
|
||||
{14, 15, 2352, 2352, 0, 25, 7, 13, 21, 22, 0, 3, 15}, // 425 +/- 25 us
|
||||
{12, 15, 2105, 2105, 0, 30, 7, 13, 21, 22, 0, 3, 16}, // 475 +/- 30 us
|
||||
};
|
||||
|
||||
struct dfs_bin5pulse ar6000_bin5pulses[] = {
|
||||
{4, 28, 105, 12, 22, 5},
|
||||
};
|
||||
|
||||
/*
|
||||
* Clear all delay lines for all filter types
|
||||
*/
|
||||
void dfs_reset_alldelaylines(struct ath_dfs_host *dfs)
|
||||
{
|
||||
struct dfs_filtertype *ft = NULL;
|
||||
struct dfs_filter *rf;
|
||||
struct dfs_delayline *dl;
|
||||
struct dfs_pulseline *pl;
|
||||
int i,j;
|
||||
|
||||
if (dfs == NULL) {
|
||||
A_PRINTF("%s: sc_dfs is NULL\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
pl = dfs->pulses;
|
||||
/* reset the pulse log */
|
||||
pl->pl_firstelem = pl->pl_numelems = 0;
|
||||
pl->pl_lastelem = DFS_MAX_PULSE_BUFFER_MASK;
|
||||
|
||||
for (i=0; i<DFS_MAX_RADAR_TYPES; i++) {
|
||||
if (dfs->dfs_radarf[i] != NULL) {
|
||||
ft = dfs->dfs_radarf[i];
|
||||
for (j=0; j<ft->ft_numfilters; j++) {
|
||||
rf = &(ft->ft_filters[j]);
|
||||
dl = &(rf->rf_dl);
|
||||
if(dl != NULL) {
|
||||
OS_MEMZERO(dl, sizeof(struct dfs_delayline));
|
||||
dl->dl_lastelem = (0xFFFFFFFF) & DFS_MAX_DL_MASK;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i=0; i<dfs->dfs_rinfo.rn_numbin5radars; i++) {
|
||||
OS_MEMZERO(&(dfs->dfs_b5radars[i].br_elems[0]), sizeof(struct dfs_bin5elem)*DFS_MAX_B5_SIZE);
|
||||
dfs->dfs_b5radars[i].br_firstelem = 0;
|
||||
dfs->dfs_b5radars[i].br_numelems = 0;
|
||||
dfs->dfs_b5radars[i].br_lastelem = (0xFFFFFFFF)&DFS_MAX_B5_MASK;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Clear only a single delay line
|
||||
*/
|
||||
|
||||
void dfs_reset_delayline(struct dfs_delayline *dl)
|
||||
{
|
||||
OS_MEMZERO(&(dl->dl_elems[0]), sizeof(dl->dl_elems));
|
||||
dl->dl_lastelem = (0xFFFFFFFF)&DFS_MAX_DL_MASK;
|
||||
}
|
||||
|
||||
void dfs_reset_filter_delaylines(struct dfs_filtertype *dft)
|
||||
{
|
||||
int i;
|
||||
struct dfs_filter *df;
|
||||
for (i=0; i< DFS_MAX_NUM_RADAR_FILTERS; i++) {
|
||||
df = &dft->ft_filters[i];
|
||||
dfs_reset_delayline(&(df->rf_dl));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dfs_reset_radarq(struct ath_dfs_host *dfs)
|
||||
{
|
||||
struct dfs_event *event;
|
||||
if (dfs == NULL) {
|
||||
A_PRINTF("%s: sc_dfs is NULL\n", __func__);
|
||||
return;
|
||||
}
|
||||
ATH_DFSQ_LOCK(dfs);
|
||||
ATH_DFSEVENTQ_LOCK(dfs);
|
||||
while (!STAILQ_EMPTY(&(dfs->dfs_radarq))) {
|
||||
event = STAILQ_FIRST(&(dfs->dfs_radarq));
|
||||
STAILQ_REMOVE_HEAD(&(dfs->dfs_radarq), re_list);
|
||||
OS_MEMZERO(event, sizeof(struct dfs_event));
|
||||
STAILQ_INSERT_TAIL(&(dfs->dfs_eventq), event, re_list);
|
||||
}
|
||||
ATH_DFSEVENTQ_UNLOCK(dfs);
|
||||
ATH_DFSQ_UNLOCK(dfs);
|
||||
}
|
||||
|
||||
struct dfs_pulse *dfs_get_radars(u_int32_t dfsdomain, u_int32_t *numradars, struct dfs_bin5pulse **bin5pulses, u_int32_t *numb5radars)
|
||||
{
|
||||
#define N(a) (sizeof(a)/sizeof(a[0]))
|
||||
struct dfs_pulse *dfs_radars = NULL;
|
||||
switch (dfsdomain) {
|
||||
case DFS_FCC_DOMAIN:
|
||||
dfs_radars = &ar6000_fcc_radars[3];
|
||||
*numradars= N(ar6000_fcc_radars)-3;
|
||||
*bin5pulses = &ar6000_bin5pulses[0];
|
||||
*numb5radars = N(ar6000_bin5pulses);
|
||||
break;
|
||||
case DFS_ETSI_DOMAIN:
|
||||
dfs_radars = &ar6000_etsi_radars[0];
|
||||
*numradars = N(ar6000_etsi_radars);
|
||||
*bin5pulses = &ar6000_bin5pulses[0];
|
||||
*numb5radars = N(ar6000_bin5pulses);
|
||||
break;
|
||||
case DFS_MKK4_DOMAIN:
|
||||
dfs_radars = &ar6000_fcc_radars[0];
|
||||
*numradars = N(ar6000_fcc_radars);
|
||||
*bin5pulses = &ar6000_bin5pulses[0];
|
||||
*numb5radars = N(ar6000_bin5pulses);
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return dfs_radars;
|
||||
|
||||
#undef N
|
||||
|
||||
}
|
||||
|
||||
int dfs_init_radar_filters_host( struct ath_dfs_host *dfs, struct ath_dfs_info *dfs_info)
|
||||
{
|
||||
u_int32_t T, Tmax;
|
||||
int numpulses,p,n, i;
|
||||
struct dfs_filtertype *ft = NULL;
|
||||
struct dfs_filter *rf=NULL;
|
||||
struct dfs_pulse *dfs_radars;
|
||||
struct dfs_bin5pulse *b5pulses;
|
||||
int32_t min_rssithresh=DFS_MAX_RSSI_VALUE;
|
||||
u_int32_t max_pulsedur=0;
|
||||
u_int32_t numb5radars;
|
||||
u_int32_t numradars;
|
||||
|
||||
dfs_radars = dfs_get_radars(dfs_info->dfs_domain, &numradars, &b5pulses, &numb5radars);
|
||||
/* If DFS not enabled return immediately.*/
|
||||
if (!dfs_radars) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
dfs->dfs_rinfo.rn_numradars = 0;
|
||||
|
||||
/* Clear filter type table */
|
||||
for (n=0; n<256; n++) {
|
||||
for (i=0;i<DFS_MAX_RADAR_OVERLAP; i++)
|
||||
(dfs->dfs_radartable[n])[i] = -1;
|
||||
}
|
||||
|
||||
/* Now, initialize the radar filters */
|
||||
for (p=0; p < numradars; p++) {
|
||||
ft = NULL;
|
||||
for (n=0; n<dfs->dfs_rinfo.rn_numradars; n++) {
|
||||
if ((dfs_radars[p].rp_pulsedur == dfs->dfs_radarf[n]->ft_filterdur) &&
|
||||
(dfs_radars[p].rp_numpulses == dfs->dfs_radarf[n]->ft_numpulses) &&
|
||||
(dfs_radars[p].rp_mindur == dfs->dfs_radarf[n]->ft_mindur) &&
|
||||
(dfs_radars[p].rp_maxdur == dfs->dfs_radarf[n]->ft_maxdur)) {
|
||||
ft = dfs->dfs_radarf[n];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ft == NULL) {
|
||||
/* No filter of the appropriate dur was found */
|
||||
if ((dfs->dfs_rinfo.rn_numradars+1) >DFS_MAX_RADAR_TYPES) {
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: Too many filter types\n",
|
||||
__func__);
|
||||
goto bad4;
|
||||
}
|
||||
|
||||
ft = dfs->dfs_radarf[dfs->dfs_rinfo.rn_numradars];
|
||||
ft->ft_numfilters = 0;
|
||||
ft->ft_numpulses = dfs_radars[p].rp_numpulses;
|
||||
ft->ft_patterntype = dfs_radars[p].rp_patterntype;
|
||||
ft->ft_mindur = dfs_radars[p].rp_mindur;
|
||||
ft->ft_maxdur = dfs_radars[p].rp_maxdur;
|
||||
ft->ft_filterdur = dfs_radars[p].rp_pulsedur;
|
||||
ft->ft_rssithresh = dfs_radars[p].rp_rssithresh;
|
||||
ft->ft_rssimargin = dfs_radars[p].rp_rssimargin;
|
||||
ft->ft_minpri = 1000000;
|
||||
|
||||
if (ft->ft_rssithresh < min_rssithresh)
|
||||
min_rssithresh = ft->ft_rssithresh;
|
||||
if (ft->ft_maxdur > max_pulsedur)
|
||||
max_pulsedur = ft->ft_maxdur;
|
||||
for (i=ft->ft_mindur; i<=ft->ft_maxdur; i++) {
|
||||
u_int32_t stop=0,tableindex=0;
|
||||
while ((tableindex < DFS_MAX_RADAR_OVERLAP) && (!stop)) {
|
||||
if ((dfs->dfs_radartable[i])[tableindex] == -1)
|
||||
stop = 1;
|
||||
else
|
||||
tableindex++;
|
||||
}
|
||||
if (stop) {
|
||||
(dfs->dfs_radartable[i])[tableindex] =
|
||||
(int8_t) (dfs->dfs_rinfo.rn_numradars);
|
||||
} else {
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS,
|
||||
"%s: Too many overlapping radar filters\n",
|
||||
__func__);
|
||||
goto bad4;
|
||||
}
|
||||
}
|
||||
dfs->dfs_rinfo.rn_numradars++;
|
||||
}
|
||||
rf = &(ft->ft_filters[ft->ft_numfilters++]);
|
||||
dfs_reset_delayline(&rf->rf_dl);
|
||||
numpulses = dfs_radars[p].rp_numpulses;
|
||||
|
||||
rf->rf_numpulses = numpulses;
|
||||
rf->rf_patterntype = dfs_radars[p].rp_patterntype;
|
||||
rf->rf_pulseid = dfs_radars[p].rp_pulseid;
|
||||
rf->rf_mindur = dfs_radars[p].rp_mindur;
|
||||
rf->rf_maxdur = dfs_radars[p].rp_maxdur;
|
||||
rf->rf_numpulses = dfs_radars[p].rp_numpulses;
|
||||
|
||||
T = (100000000/dfs_radars[p].rp_max_pulsefreq) -
|
||||
100*(dfs_radars[p].rp_meanoffset);
|
||||
rf->rf_minpri =
|
||||
dfs_round((int32_t)T - (100*(dfs_radars[p].rp_pulsevar)));
|
||||
Tmax = (100000000/dfs_radars[p].rp_pulsefreq) -
|
||||
100*(dfs_radars[p].rp_meanoffset);
|
||||
rf->rf_maxpri =
|
||||
dfs_round((int32_t)Tmax + (100*(dfs_radars[p].rp_pulsevar)));
|
||||
|
||||
if( rf->rf_minpri < ft->ft_minpri )
|
||||
ft->ft_minpri = rf->rf_minpri;
|
||||
|
||||
rf->rf_threshold = dfs_radars[p].rp_threshold;
|
||||
rf->rf_filterlen = rf->rf_maxpri * rf->rf_numpulses;
|
||||
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "minprf = %d maxprf = %d pulsevar = %d thresh=%d\n",
|
||||
dfs_radars[p].rp_pulsefreq, dfs_radars[p].rp_max_pulsefreq, dfs_radars[p].rp_pulsevar, rf->rf_threshold);
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,
|
||||
"minpri = %d maxpri = %d filterlen = %d filterID = %d\n",
|
||||
rf->rf_minpri, rf->rf_maxpri, rf->rf_filterlen, rf->rf_pulseid);
|
||||
}
|
||||
|
||||
#ifdef DFS_DEBUG
|
||||
dfs_print_filters(dfs);
|
||||
#endif
|
||||
|
||||
dfs->dfs_rinfo.rn_numbin5radars = numb5radars;
|
||||
if ( dfs->dfs_b5radars == NULL ) {
|
||||
dfs->dfs_b5radars = (struct dfs_bin5radars *)DFS_MALLOC(dfs->os_hdl, numb5radars * sizeof(struct dfs_bin5radars));
|
||||
if (dfs->dfs_b5radars == NULL) {
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS,
|
||||
"%s: cannot allocate memory for bin5 radars\n",
|
||||
__func__);
|
||||
goto bad4;
|
||||
}
|
||||
}
|
||||
for (n=0; n<numb5radars; n++) {
|
||||
dfs->dfs_b5radars[n].br_pulse = b5pulses[n];
|
||||
dfs->dfs_b5radars[n].br_pulse.b5_timewindow *= 1000000;
|
||||
if (dfs->dfs_b5radars[n].br_pulse.b5_rssithresh < min_rssithresh)
|
||||
min_rssithresh = dfs->dfs_b5radars[n].br_pulse.b5_rssithresh;
|
||||
if (dfs->dfs_b5radars[n].br_pulse.b5_maxdur > max_pulsedur )
|
||||
max_pulsedur = dfs->dfs_b5radars[n].br_pulse.b5_maxdur;
|
||||
}
|
||||
dfs_reset_alldelaylines(dfs);
|
||||
dfs_reset_radarq(dfs);
|
||||
|
||||
DFS_SET_MINRSSITHRESH(dfs->dev_hdl, min_rssithresh);
|
||||
DFS_SET_MAXPULSEDUR(dfs->dev_hdl, dfs_round((int32_t)((max_pulsedur*100/80)*100)));
|
||||
|
||||
|
||||
return 0;
|
||||
|
||||
bad4:
|
||||
for (n=0; n<ft->ft_numfilters; n++) {
|
||||
rf = &(ft->ft_filters[n]);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif /* ATH_SUPPORT_DFS */
|
||||
120
drivers/net/wireless/ar6003/host/dfs/dfs_misc.c
Normal file
120
drivers/net/wireless/ar6003/host/dfs/dfs_misc.c
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* Copyright (c) 2002-2010, Atheros Communications Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef ATH_SUPPORT_DFS
|
||||
#include "dfs_host.h"
|
||||
|
||||
int adjust_pri_per_chan_busy(int ext_chan_busy, int pri_margin)
|
||||
{
|
||||
int adjust_pri=0;
|
||||
|
||||
if(ext_chan_busy > DFS_EXT_CHAN_LOADING_THRESH) {
|
||||
|
||||
adjust_pri = (ext_chan_busy - DFS_EXT_CHAN_LOADING_THRESH) * (pri_margin);
|
||||
adjust_pri /= 100;
|
||||
|
||||
}
|
||||
return adjust_pri;
|
||||
}
|
||||
|
||||
int adjust_thresh_per_chan_busy(int ext_chan_busy, int thresh)
|
||||
{
|
||||
int adjust_thresh=0;
|
||||
|
||||
if(ext_chan_busy > DFS_EXT_CHAN_LOADING_THRESH) {
|
||||
|
||||
adjust_thresh = (ext_chan_busy - DFS_EXT_CHAN_LOADING_THRESH) * thresh;
|
||||
adjust_thresh /= 100;
|
||||
|
||||
}
|
||||
return adjust_thresh;
|
||||
}
|
||||
/* For the extension channel, if legacy traffic is present, we see a lot of false alarms,
|
||||
so make the PRI margin narrower depending on the busy % for the extension channel.*/
|
||||
|
||||
int dfs_get_pri_margin(int is_extchan_detect, int is_fixed_pattern, u_int64_t lastfull_ts, u_int32_t ext_chan_busy)
|
||||
{
|
||||
|
||||
int adjust_pri=0;
|
||||
int pri_margin;
|
||||
// struct ath_dfs_target *dfs = sc->sc_dfs_tgt;
|
||||
|
||||
if (is_fixed_pattern)
|
||||
pri_margin = DFS_DEFAULT_FIXEDPATTERN_PRI_MARGIN;
|
||||
else
|
||||
pri_margin = DFS_DEFAULT_PRI_MARGIN;
|
||||
|
||||
|
||||
/*XXX: Does cached value make sense here? */
|
||||
#if 0
|
||||
if(ext_chan_busy) {
|
||||
dfs->dfs_rinfo.ext_chan_busy_ts = ath_hal_gettsf64(sc->sc_ah);
|
||||
dfs->dfs_rinfo.dfs_ext_chan_busy = ext_chan_busy;
|
||||
} else {
|
||||
// Check to see if the cached value of ext_chan_busy can be used
|
||||
if (dfs->dfs_rinfo.dfs_ext_chan_busy) {
|
||||
if (lastfull_ts < dfs->dfs_rinfo.ext_chan_busy_ts) {
|
||||
ext_chan_busy = dfs->dfs_rinfo.dfs_ext_chan_busy;
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS2," PRI Use cached copy of ext_chan_busy extchanbusy=%d \n", ext_chan_busy);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
adjust_pri = adjust_pri_per_chan_busy(ext_chan_busy, pri_margin);
|
||||
|
||||
pri_margin -= adjust_pri;
|
||||
return pri_margin;
|
||||
}
|
||||
|
||||
/* For the extension channel, if legacy traffic is present, we see a lot of false alarms,
|
||||
so make the thresholds higher depending on the busy % for the extension channel.*/
|
||||
|
||||
int dfs_get_filter_threshold(struct dfs_filter *rf, int is_extchan_detect, u_int64_t lastfull_ts, u_int32_t ext_chan_busy)
|
||||
{
|
||||
int thresh, adjust_thresh=0;
|
||||
// struct ath_dfs_target *dfs = sc->sc_dfs_tgt;
|
||||
|
||||
thresh = rf->rf_threshold;
|
||||
|
||||
/*XXX: Does cached value make sense here? */
|
||||
#if 0
|
||||
if(ext_chan_busy) {
|
||||
dfs->dfs_rinfo.ext_chan_busy_ts = ath_hal_gettsf64(sc->sc_ah);
|
||||
dfs->dfs_rinfo.dfs_ext_chan_busy = ext_chan_busy;
|
||||
} else {
|
||||
// Check to see if the cached value of ext_chan_busy can be used
|
||||
if (dfs->dfs_rinfo.dfs_ext_chan_busy) {
|
||||
if (lastfull_ts < dfs->dfs_rinfo.ext_chan_busy_ts) {
|
||||
ext_chan_busy = dfs->dfs_rinfo.dfs_ext_chan_busy;
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS2," THRESH Use cached copy of ext_chan_busy extchanbusy=%d lastfull_ts=%llu ext_chan_busy_ts=%llu\n", ext_chan_busy ,lastfull_ts, dfs->dfs_rinfo.ext_chan_busy_ts);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
adjust_thresh = adjust_thresh_per_chan_busy(ext_chan_busy, thresh);
|
||||
|
||||
//DFS_DPRINTK(dfs, ATH_DEBUG_DFS2," filterID=%d extchanbusy=%d adjust_thresh=%d\n", rf->rf_pulseid, ext_chan_busy, adjust_thresh);
|
||||
|
||||
thresh += adjust_thresh;
|
||||
return thresh;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* ATH_SUPPORT_DFS */
|
||||
99
drivers/net/wireless/ar6003/host/dfs/dfs_process_phyerr.c
Normal file
99
drivers/net/wireless/ar6003/host/dfs/dfs_process_phyerr.c
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* Copyright (c) 2002-2010, Atheros Communications Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef ATH_SUPPORT_DFS
|
||||
#include "dfs_host.h"
|
||||
void
|
||||
dfs_queue_phyerr(struct ath_dfs_host *dfs, struct dfs_event_info *ev_info);
|
||||
|
||||
|
||||
void
|
||||
dfs_process_phyerr_host(struct ath_dfs_host *dfs, WMI_DFS_PHYERR_EVENT *ev)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i<ev->num_events; i++)
|
||||
dfs_queue_phyerr(dfs, &ev->ev_info[i]);
|
||||
}
|
||||
|
||||
void
|
||||
dfs_queue_phyerr(struct ath_dfs_host *dfs, struct dfs_event_info *ev_info)
|
||||
{
|
||||
struct dfs_event *event;
|
||||
int empty;
|
||||
|
||||
ATH_DFSEVENTQ_LOCK(dfs);
|
||||
empty = STAILQ_EMPTY(&(dfs->dfs_eventq));
|
||||
ATH_DFSEVENTQ_UNLOCK(dfs);
|
||||
if (empty) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* XXX: Lot of common code. Optimize */
|
||||
|
||||
if((ev_info->flags & EVENT_TYPE_MASK) == AR_EVENT){
|
||||
ATH_DFSEVENTQ_LOCK(dfs);
|
||||
event = STAILQ_FIRST(&(dfs->dfs_eventq));
|
||||
if (event == NULL) {
|
||||
ATH_DFSEVENTQ_UNLOCK(dfs);
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: no more events space left\n",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
STAILQ_REMOVE_HEAD(&(dfs->dfs_eventq), re_list);
|
||||
ATH_DFSEVENTQ_UNLOCK(dfs);
|
||||
event->re_rssi = ev_info->rssi;
|
||||
event->re_dur = ev_info->dur;
|
||||
event->re_full_ts = ev_info->full_ts;
|
||||
event->re_ts = ev_info->ts;
|
||||
event->re_chanindex = ev_info->chanindex;
|
||||
event->re_chanindextype = ev_info->flags & CH_TYPE_MASK;
|
||||
ATH_ARQ_LOCK(dfs);
|
||||
STAILQ_INSERT_TAIL(&(dfs->dfs_arq), event, re_list);
|
||||
ATH_ARQ_UNLOCK(dfs);
|
||||
}
|
||||
else { /* DFS event */
|
||||
ATH_DFSEVENTQ_LOCK(dfs);
|
||||
event = STAILQ_FIRST(&(dfs->dfs_eventq));
|
||||
if (event == NULL) {
|
||||
ATH_DFSEVENTQ_UNLOCK(dfs);
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: no more events space left\n",
|
||||
__func__);
|
||||
return;
|
||||
}
|
||||
STAILQ_REMOVE_HEAD(&(dfs->dfs_eventq), re_list);
|
||||
ATH_DFSEVENTQ_UNLOCK(dfs);
|
||||
event->re_rssi = ev_info->rssi;
|
||||
event->re_dur = ev_info->dur;
|
||||
event->re_full_ts = ev_info->full_ts;
|
||||
event->re_ts = ev_info->ts;
|
||||
event->re_chanindex = ev_info->chanindex;
|
||||
event->re_chanindextype = ev_info->flags & CH_TYPE_MASK;
|
||||
event->re_ext_chan_busy = ev_info->ext_chan_busy;
|
||||
|
||||
ATH_DFSQ_LOCK(dfs);
|
||||
STAILQ_INSERT_TAIL(&(dfs->dfs_radarq), event, re_list);
|
||||
ATH_DFSQ_UNLOCK(dfs);
|
||||
}
|
||||
|
||||
/* TODO: The radar detected event is sent from host in timer
|
||||
* context which could potentially cause issues with sleepable
|
||||
* WMI. Change this to process context later. */
|
||||
|
||||
A_TIMEOUT_MS(&dfs->dfs_radar_task_timer, 0, 0);
|
||||
|
||||
}
|
||||
|
||||
#endif /* ATH_SUPPORT_DFS */
|
||||
316
drivers/net/wireless/ar6003/host/dfs/dfs_process_radarevent.c
Normal file
316
drivers/net/wireless/ar6003/host/dfs/dfs_process_radarevent.c
Normal file
|
|
@ -0,0 +1,316 @@
|
|||
/*
|
||||
* Copyright (c) 2002-2010, Atheros Communications Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef ATH_SUPPORT_DFS
|
||||
#include "dfs_host.h"
|
||||
|
||||
static char debug_dup[33];
|
||||
static int debug_dup_cnt;
|
||||
|
||||
u_int32_t dfs_round(int32_t val)
|
||||
{
|
||||
u_int32_t ival,rem;
|
||||
|
||||
if (val < 0)
|
||||
return 0;
|
||||
ival = val/100;
|
||||
rem = val-(ival*100);
|
||||
if (rem <50)
|
||||
return ival;
|
||||
else
|
||||
return(ival+1);
|
||||
}
|
||||
|
||||
|
||||
static inline u_int8_t
|
||||
dfs_process_pulse_dur(struct ath_dfs_host *dfs, u_int8_t re_dur)
|
||||
{
|
||||
if (re_dur == 0) {
|
||||
return 1;
|
||||
} else {
|
||||
/* Convert 0.8us durations to TSF ticks (usecs) */
|
||||
return (u_int8_t)dfs_round((int32_t)((dfs->dur_multiplier)*re_dur));
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
dfs_process_radarevent_host(struct ath_dfs_host *dfs, int16_t *chan_index, u_int8_t *bangradar)
|
||||
{
|
||||
struct dfs_event re,*event;
|
||||
struct dfs_filtertype *ft;
|
||||
struct dfs_filter *rf;
|
||||
int found, retval=0,p, empty;
|
||||
int events_processed=0;
|
||||
u_int32_t tabledepth, index;
|
||||
u_int64_t deltafull_ts = 0,this_ts, deltaT;
|
||||
struct dfs_pulseline *pl;
|
||||
static u_int32_t test_ts = 0;
|
||||
static u_int32_t diff_ts = 0;
|
||||
|
||||
int ext_chan_event_flag=0;
|
||||
|
||||
if (dfs == NULL) {
|
||||
A_PRINTF("%s: sc_sfs is NULL\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
pl = dfs->pulses;
|
||||
/* TEST : Simulate radar bang, make sure we add the channel to NOL (bug 29968) */
|
||||
if (dfs->dfs_bangradar) {
|
||||
/* bangradar will always simulate radar found on the primary channel */
|
||||
*bangradar = 1;
|
||||
dfs->dfs_bangradar = 0; /* reset */
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: bangradar\n", __func__);
|
||||
retval = 1;
|
||||
}
|
||||
else
|
||||
*bangradar = 0;
|
||||
|
||||
ATH_DFSQ_LOCK(dfs);
|
||||
empty = STAILQ_EMPTY(&(dfs->dfs_radarq));
|
||||
ATH_DFSQ_UNLOCK(dfs);
|
||||
|
||||
while ((!empty) && (!retval) && (events_processed < MAX_EVENTS)) {
|
||||
ATH_DFSQ_LOCK(dfs);
|
||||
event = STAILQ_FIRST(&(dfs->dfs_radarq));
|
||||
if (event != NULL)
|
||||
STAILQ_REMOVE_HEAD(&(dfs->dfs_radarq), re_list);
|
||||
ATH_DFSQ_UNLOCK(dfs);
|
||||
|
||||
if (event == NULL) {
|
||||
empty = 1;
|
||||
break;
|
||||
}
|
||||
events_processed++;
|
||||
re = *event;
|
||||
|
||||
OS_MEMZERO(event, sizeof(struct dfs_event));
|
||||
ATH_DFSEVENTQ_LOCK(dfs);
|
||||
STAILQ_INSERT_TAIL(&(dfs->dfs_eventq), event, re_list);
|
||||
ATH_DFSEVENTQ_UNLOCK(dfs);
|
||||
|
||||
found = 0;
|
||||
if (re.re_chanindex < DFS_NUM_RADAR_STATES)
|
||||
*chan_index = re.re_chanindex;
|
||||
else {
|
||||
ATH_DFSQ_LOCK(dfs);
|
||||
empty = STAILQ_EMPTY(&(dfs->dfs_radarq));
|
||||
ATH_DFSQ_UNLOCK(dfs);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dfs->dfs_rinfo.rn_lastfull_ts == 0) {
|
||||
/*
|
||||
* Either not started, or 64-bit rollover exactly to zero
|
||||
* Just prepend zeros to the 15-bit ts
|
||||
*/
|
||||
dfs->dfs_rinfo.rn_ts_prefix = 0;
|
||||
this_ts = (u_int64_t) re.re_ts;
|
||||
} else {
|
||||
/* WAR 23031- patch duplicate ts on very short pulses */
|
||||
/* This pacth has two problems in linux environment.
|
||||
* 1)The time stamp created and hence PRI depends entirely on the latency.
|
||||
* If the latency is high, it possibly can split two consecutive
|
||||
* pulses in the same burst so far away (the same amount of latency)
|
||||
* that make them look like they are from differenct bursts. It is
|
||||
* observed to happen too often. It sure makes the detection fail.
|
||||
* 2)Even if the latency is not that bad, it simply shifts the duplicate
|
||||
* timestamps to a new duplicate timestamp based on how they are processed.
|
||||
* This is not worse but not good either.
|
||||
*
|
||||
* Take this pulse as a good one and create a probable PRI later
|
||||
*/
|
||||
if (re.re_dur == 0 && re.re_ts == dfs->dfs_rinfo.rn_last_unique_ts) {
|
||||
debug_dup[debug_dup_cnt++] = '1';
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, "\n %s deltaT is 0 \n", __func__);
|
||||
} else {
|
||||
dfs->dfs_rinfo.rn_last_unique_ts = re.re_ts;
|
||||
debug_dup[debug_dup_cnt++] = '0';
|
||||
}
|
||||
if (debug_dup_cnt >= 32){
|
||||
debug_dup_cnt = 0;
|
||||
}
|
||||
|
||||
|
||||
if (re.re_ts <= dfs->dfs_rinfo.rn_last_ts) {
|
||||
dfs->dfs_rinfo.rn_ts_prefix +=
|
||||
(((u_int64_t) 1) << DFS_TSSHIFT);
|
||||
/* Now, see if it's been more than 1 wrap */
|
||||
deltafull_ts = re.re_full_ts - dfs->dfs_rinfo.rn_lastfull_ts;
|
||||
if (deltafull_ts >
|
||||
((u_int64_t)((DFS_TSMASK - dfs->dfs_rinfo.rn_last_ts) + 1 + re.re_ts)))
|
||||
deltafull_ts -= (DFS_TSMASK - dfs->dfs_rinfo.rn_last_ts) + 1 + re.re_ts;
|
||||
deltafull_ts = deltafull_ts >> DFS_TSSHIFT;
|
||||
if (deltafull_ts > 1) {
|
||||
dfs->dfs_rinfo.rn_ts_prefix +=
|
||||
((deltafull_ts - 1) << DFS_TSSHIFT);
|
||||
}
|
||||
} else {
|
||||
deltafull_ts = re.re_full_ts - dfs->dfs_rinfo.rn_lastfull_ts;
|
||||
if (deltafull_ts > (u_int64_t) DFS_TSMASK) {
|
||||
deltafull_ts = deltafull_ts >> DFS_TSSHIFT;
|
||||
dfs->dfs_rinfo.rn_ts_prefix +=
|
||||
((deltafull_ts - 1) << DFS_TSSHIFT);
|
||||
}
|
||||
}
|
||||
this_ts = dfs->dfs_rinfo.rn_ts_prefix | ((u_int64_t) re.re_ts);
|
||||
}
|
||||
dfs->dfs_rinfo.rn_lastfull_ts = re.re_full_ts;
|
||||
dfs->dfs_rinfo.rn_last_ts = re.re_ts;
|
||||
|
||||
re.re_dur = dfs_process_pulse_dur(dfs, re.re_dur);
|
||||
if (re.re_dur != 1) {
|
||||
this_ts -= re.re_dur;
|
||||
}
|
||||
|
||||
/* Save the pulse parameters in the pulse buffer(pulse line) */
|
||||
index = (pl->pl_lastelem + 1) & DFS_MAX_PULSE_BUFFER_MASK;
|
||||
if (pl->pl_numelems == DFS_MAX_PULSE_BUFFER_SIZE)
|
||||
pl->pl_firstelem = (pl->pl_firstelem+1) & DFS_MAX_PULSE_BUFFER_MASK;
|
||||
else
|
||||
pl->pl_numelems++;
|
||||
pl->pl_lastelem = index;
|
||||
pl->pl_elems[index].p_time = this_ts;
|
||||
pl->pl_elems[index].p_dur = re.re_dur;
|
||||
pl->pl_elems[index].p_rssi = re.re_rssi;
|
||||
diff_ts = (u_int32_t)this_ts - test_ts;
|
||||
test_ts = (u_int32_t)this_ts;
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS1,"ts%u %u %u diff %u pl->pl_lastelem.p_time=%llu\n",(u_int32_t)this_ts, re.re_dur, re.re_rssi, diff_ts, (unsigned long long)pl->pl_elems[index].p_time);
|
||||
|
||||
found = 0;
|
||||
for (p=0; (p<dfs->dfs_rinfo.rn_numbin5radars)&&(!found); p++) {
|
||||
struct dfs_bin5radars *br;
|
||||
u_int32_t b5_rssithresh;
|
||||
br = &(dfs->dfs_b5radars[p]);
|
||||
b5_rssithresh = br->br_pulse.b5_rssithresh;
|
||||
|
||||
/* Adjust the filter threshold for rssi in non TURBO mode*/
|
||||
//XXX: If turbo mode, ar events would be used?
|
||||
//if( ! (sc->sc_curchan.channelFlags & CHANNEL_TURBO) ) {
|
||||
b5_rssithresh += br->br_pulse.b5_rssimargin;
|
||||
//}
|
||||
|
||||
if ((re.re_dur >= br->br_pulse.b5_mindur) &&
|
||||
(re.re_dur <= br->br_pulse.b5_maxdur) &&
|
||||
(re.re_rssi >= b5_rssithresh)) {
|
||||
|
||||
// This is a valid Bin5 pulse, check if it belongs to a burst
|
||||
re.re_dur = dfs_retain_bin5_burst_pattern(dfs, diff_ts, re.re_dur);
|
||||
// Remember our computed duration for the next pulse in the burst (if needed)
|
||||
dfs->dfs_rinfo.dfs_bin5_chirp_ts = this_ts;
|
||||
dfs->dfs_rinfo.dfs_last_bin5_dur = re.re_dur;
|
||||
|
||||
|
||||
if( dfs_bin5_addpulse(dfs, br, &re, this_ts) ) {
|
||||
found |= dfs_bin5_check(dfs);
|
||||
}
|
||||
} else
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS3, "%s too low to be Bin5 pulse (%d)\n", __func__, re.re_dur);
|
||||
}
|
||||
if (found) {
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "%s: Found bin5 radar\n", __func__);
|
||||
retval |= found;
|
||||
goto dfsfound;
|
||||
}
|
||||
tabledepth = 0;
|
||||
rf = NULL;
|
||||
|
||||
while ((tabledepth < DFS_MAX_RADAR_OVERLAP) &&
|
||||
((dfs->dfs_radartable[re.re_dur])[tabledepth] != -1) &&
|
||||
(!retval)) {
|
||||
ft = dfs->dfs_radarf[((dfs->dfs_radartable[re.re_dur])[tabledepth])];
|
||||
|
||||
if (re.re_rssi < ft->ft_rssithresh && re.re_dur > 4) {
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,"%s : Rejecting on rssi rssi=%u thresh=%u\n", __func__, re.re_rssi, ft->ft_rssithresh);
|
||||
tabledepth++;
|
||||
ATH_DFSQ_LOCK(dfs);
|
||||
empty = STAILQ_EMPTY(&(dfs->dfs_radarq));
|
||||
ATH_DFSQ_UNLOCK(dfs);
|
||||
continue;
|
||||
}
|
||||
deltaT = this_ts - ft->ft_last_ts;
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,"deltaT = %lld (ts: 0x%llx) (last ts: 0x%llx)\n",(unsigned long long)deltaT, (unsigned long long)this_ts, (unsigned long long)ft->ft_last_ts);
|
||||
if ((deltaT < ft->ft_minpri) && (deltaT !=0)){
|
||||
/* This check is for the whole filter type. Individual filters
|
||||
will check this again. This is first line of filtering.*/
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "%s: Rejecting on pri pri=%lld minpri=%u\n", __func__, (unsigned long long)deltaT, ft->ft_minpri);
|
||||
tabledepth++;
|
||||
continue;
|
||||
}
|
||||
for (p=0, found = 0; (p<ft->ft_numfilters) && (!found); p++) {
|
||||
rf = &(ft->ft_filters[p]);
|
||||
if ((re.re_dur >= rf->rf_mindur) && (re.re_dur <= rf->rf_maxdur)) {
|
||||
/* The above check is probably not necessary */
|
||||
deltaT = this_ts - rf->rf_dl.dl_last_ts;
|
||||
if (deltaT < 0)
|
||||
deltaT = (int64_t) ((DFS_TSF_WRAP - rf->rf_dl.dl_last_ts) + this_ts +1);
|
||||
if ((deltaT < rf->rf_minpri) && (deltaT != 0)) {
|
||||
/* Second line of PRI filtering. */
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,
|
||||
"filterID %d : Rejecting on individual filter min PRI deltaT=%lld rf->rf_minpri=%u\n",
|
||||
rf->rf_pulseid, (unsigned long long)deltaT, rf->rf_minpri);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((rf->rf_patterntype==2) && (deltaT > rf->rf_maxpri) ) {
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,
|
||||
"filterID %d : Staggered - Rejecting on individual filter max PRI deltaT=%lld rf->rf_maxpri=%u\n",
|
||||
rf->rf_pulseid, (unsigned long long)deltaT, rf->rf_maxpri);
|
||||
/* But update the last time stamp */
|
||||
rf->rf_dl.dl_last_ts = this_ts;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((rf->rf_patterntype!= 2) && (deltaT > rf->rf_maxpri) && (deltaT < (2*rf->rf_minpri))) {
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS2,
|
||||
"filterID %d : Rejecting on individual filter max PRI deltaT=%lld rf->rf_minpri=%u\n",
|
||||
rf->rf_pulseid, (unsigned long long)deltaT, rf->rf_minpri);
|
||||
/* But update the last time stamp */
|
||||
rf->rf_dl.dl_last_ts = this_ts;
|
||||
continue;
|
||||
}
|
||||
dfs_add_pulse(dfs, rf, &re, deltaT);
|
||||
/* If this is an extension channel event, flag it for false alarm reduction */
|
||||
if (re.re_chanindextype == EXT_CH)
|
||||
ext_chan_event_flag = 1;
|
||||
|
||||
if (rf->rf_patterntype == 2)
|
||||
found = dfs_staggered_check(dfs, rf, (u_int32_t) deltaT, re.re_dur, re.re_ext_chan_busy);
|
||||
else
|
||||
found = dfs_bin_check(dfs, rf, (u_int32_t) deltaT, re.re_dur, ext_chan_event_flag, re.re_ext_chan_busy);
|
||||
|
||||
dfs_print_delayline(dfs, &rf->rf_dl);
|
||||
rf->rf_dl.dl_last_ts = this_ts;
|
||||
}
|
||||
}
|
||||
ft->ft_last_ts = this_ts;
|
||||
retval |= found;
|
||||
if (found) {
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS,
|
||||
"Found on channel minDur = %d, filterId = %d\n",ft->ft_mindur,
|
||||
rf != NULL ? rf->rf_pulseid : -1);
|
||||
}
|
||||
tabledepth++;
|
||||
}
|
||||
ATH_DFSQ_LOCK(dfs);
|
||||
empty = STAILQ_EMPTY(&(dfs->dfs_radarq));
|
||||
ATH_DFSQ_UNLOCK(dfs);
|
||||
}
|
||||
dfsfound:
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#endif /* ATH_SUPPORT_DFS */
|
||||
202
drivers/net/wireless/ar6003/host/dfs/dfs_staggered.c
Normal file
202
drivers/net/wireless/ar6003/host/dfs/dfs_staggered.c
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
/*
|
||||
* Copyright (c) 2002-2010, Atheros Communications Inc.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifdef ATH_SUPPORT_DFS
|
||||
#include "dfs_host.h"
|
||||
|
||||
int is_pri_multiple(u_int32_t sample_pri, u_int32_t refpri)
|
||||
{
|
||||
#define MAX_ALLOWED_MISSED 3
|
||||
int i;
|
||||
|
||||
if (sample_pri < refpri || (!refpri))
|
||||
return 0;
|
||||
|
||||
for (i=1; i<= MAX_ALLOWED_MISSED; i++) {
|
||||
if((sample_pri%(i*refpri) <= 5)) {
|
||||
//printk("sample_pri=%d is a multiple of refpri=%d\n", sample_pri, refpri);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
#undef MAX_ALLOWED_MISSED
|
||||
}
|
||||
|
||||
int is_unique_pri(u_int32_t highestpri , u_int32_t midpri,
|
||||
u_int32_t lowestpri , u_int32_t refpri )
|
||||
{
|
||||
#define DFS_STAGGERED_PRI_MARGIN_MIN 20
|
||||
#define DFS_STAGGERED_PRI_MARGIN_MAX 400
|
||||
if ((DFS_DIFF(lowestpri, refpri) >= DFS_STAGGERED_PRI_MARGIN_MIN) &&
|
||||
(DFS_DIFF(midpri, refpri) >= DFS_STAGGERED_PRI_MARGIN_MIN) &&
|
||||
(DFS_DIFF(highestpri, refpri) >= DFS_STAGGERED_PRI_MARGIN_MIN)) {
|
||||
return 1;
|
||||
} else {
|
||||
if ((is_pri_multiple(refpri, highestpri)) || (is_pri_multiple(refpri, lowestpri)) ||
|
||||
(is_pri_multiple(refpri, midpri)))
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
#undef DFS_STAGGERED_PRI_MARGIN_MIN
|
||||
#undef DFS_STAGGERED_PRI_MARGIN_MAX
|
||||
}
|
||||
|
||||
|
||||
int dfs_staggered_check(struct ath_dfs_host *dfs, struct dfs_filter *rf,
|
||||
u_int32_t deltaT, u_int32_t width, u_int32_t ext_chan_busy)
|
||||
{
|
||||
|
||||
u_int32_t refpri, refdur, searchpri=0, deltapri;//, averagerefpri;
|
||||
u_int32_t n, i, primargin, durmargin;
|
||||
int score[DFS_MAX_DL_SIZE], delayindex, dindex, found=0;
|
||||
struct dfs_delayline *dl;
|
||||
u_int32_t scoreindex, lowpriindex= 0, lowpri = 0xffff;
|
||||
int numpulses=0, higherthan, lowerthan, numscores;
|
||||
u_int32_t lowestscore=0, lowestscoreindex=0, lowestpri=0;
|
||||
u_int32_t midscore=0, midscoreindex=0, midpri=0;
|
||||
u_int32_t highestscore=0, highestscoreindex=0, highestpri=0;
|
||||
|
||||
dl = &rf->rf_dl;
|
||||
if( dl->dl_numelems < (rf->rf_threshold-1)) {
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "numelems %d < threshold for filter %d\n", dl->dl_numelems, rf->rf_pulseid);
|
||||
return 0;
|
||||
}
|
||||
if( deltaT > rf->rf_filterlen) {
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "numelems %d < threshold for filter %d\n", dl->dl_numelems, rf->rf_pulseid);
|
||||
return 0;
|
||||
}
|
||||
primargin = 10;
|
||||
if(rf->rf_maxdur < 10) {
|
||||
durmargin = 4;
|
||||
}
|
||||
else {
|
||||
durmargin = 6;
|
||||
}
|
||||
|
||||
OS_MEMZERO(score, sizeof(int)*DFS_MAX_DL_SIZE);
|
||||
/* find out the lowest pri */
|
||||
for (n=0;n<dl->dl_numelems; n++) {
|
||||
delayindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK;
|
||||
refpri = dl->dl_elems[delayindex].de_time;
|
||||
if( refpri == 0)
|
||||
continue;
|
||||
else if(refpri < lowpri) {
|
||||
lowpri = dl->dl_elems[delayindex].de_time;
|
||||
lowpriindex = n;
|
||||
}
|
||||
}
|
||||
/* find out the each delay element's pri score */
|
||||
for (n=0;n<dl->dl_numelems; n++) {
|
||||
delayindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK;
|
||||
refpri = dl->dl_elems[delayindex].de_time;
|
||||
if( refpri == 0)
|
||||
continue;
|
||||
for (i=0;i<dl->dl_numelems; i++) {
|
||||
dindex = (dl->dl_firstelem + i) & DFS_MAX_DL_MASK;
|
||||
searchpri = dl->dl_elems[dindex].de_time;
|
||||
deltapri = DFS_DIFF(searchpri, refpri);
|
||||
if( deltapri < primargin)
|
||||
score[n]++;
|
||||
}
|
||||
if( score[n] > rf->rf_threshold) {
|
||||
/* we got the most possible candidate,
|
||||
* no need to continue further */
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "THRESH score[%d]=%d pri=%d\n", n, score[n], searchpri);
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (n=0;n<dl->dl_numelems; n++) {
|
||||
delayindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK;
|
||||
refdur = dl->dl_elems[delayindex].de_time;
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "score[%d]=%d pri=%d\n", n, score[n], refdur);
|
||||
}
|
||||
|
||||
/* find out the 2 or 3 highest scorers */
|
||||
scoreindex = 0;
|
||||
highestscore=0;
|
||||
highestscoreindex=0;
|
||||
highestpri=0; numscores=0; lowestscore=0;
|
||||
|
||||
for (n=0;n<dl->dl_numelems; n++) {
|
||||
higherthan=0;
|
||||
lowerthan=0;
|
||||
delayindex = (dl->dl_firstelem + n) & DFS_MAX_DL_MASK;
|
||||
refpri = dl->dl_elems[delayindex].de_time;
|
||||
|
||||
if ((score[n] >= highestscore) &&
|
||||
(is_unique_pri(highestpri, midpri, lowestpri, refpri))) {
|
||||
lowestscore = midscore;
|
||||
lowestpri = midpri;
|
||||
lowestscoreindex = midscoreindex;
|
||||
midscore = highestscore;
|
||||
midpri = highestpri;
|
||||
midscoreindex = highestscoreindex;
|
||||
highestscore = score[n];
|
||||
highestpri = refpri;
|
||||
highestscoreindex = n;
|
||||
} else {
|
||||
if ((score[n] >= midscore) &&
|
||||
(is_unique_pri(highestpri, midpri, lowestpri, refpri))) {
|
||||
lowestscore = midscore;
|
||||
lowestpri = midpri;
|
||||
lowestscoreindex = midscoreindex;
|
||||
midscore = score[n];
|
||||
midpri = refpri;
|
||||
midscoreindex = n;
|
||||
} else if ((score[n] >= lowestscore) &&
|
||||
(is_unique_pri(highestpri, midpri, lowestpri, refpri))) {
|
||||
lowestscore = score[n];
|
||||
lowestpri = refpri;
|
||||
lowestscoreindex = n;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, "FINAL highestscore=%d highestscoreindex=%d highestpri=%d\n", highestscore, highestscoreindex, highestpri);
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, "FINAL lowestscore=%d lowestscoreindex=%d lowpri=%d\n", lowestscore, lowestscoreindex, lowestpri);
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, "FINAL midscore=%d midscoreindex=%d midpri=%d\n", midscore, midscoreindex, midpri);
|
||||
|
||||
delayindex = (dl->dl_firstelem + highestscoreindex) & DFS_MAX_DL_MASK;
|
||||
refdur = dl->dl_elems[delayindex].de_dur;
|
||||
refpri = dl->dl_elems[delayindex].de_time;
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, "highscoreindex=%d refdur=%d refpri=%d\n", highestscoreindex, refdur, refpri);
|
||||
|
||||
numpulses += dfs_bin_pri_check(dfs, rf, dl, highestscore, refpri, refdur, 0, ext_chan_busy);
|
||||
|
||||
; delayindex = (dl->dl_firstelem + midscoreindex) & DFS_MAX_DL_MASK;
|
||||
refdur = dl->dl_elems[delayindex].de_dur;
|
||||
refpri = dl->dl_elems[delayindex].de_time;
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, "midscoreindex=%d refdur=%d refpri=%d\n", midscoreindex, refdur, refpri);
|
||||
|
||||
numpulses += dfs_bin_pri_check(dfs, rf, dl, midscore, refpri, refdur, 0, ext_chan_busy);
|
||||
;
|
||||
delayindex = (dl->dl_firstelem + lowestscoreindex) & DFS_MAX_DL_MASK;
|
||||
refdur = dl->dl_elems[delayindex].de_dur;
|
||||
refpri = dl->dl_elems[delayindex].de_time;
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS1, "lowestscoreindex=%d refdur=%d refpri=%d\n", lowestscoreindex, refdur, refpri);
|
||||
|
||||
numpulses += dfs_bin_pri_check(dfs, rf, dl, lowestscore, refpri, refdur, 0, ext_chan_busy);
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS2, "numpulses=%d\n",numpulses);
|
||||
|
||||
if (numpulses >= rf->rf_threshold) {
|
||||
found = 1;
|
||||
DFS_DPRINTK(dfs, ATH_DEBUG_DFS, "MATCH filter=%u numpulses=%u thresh=%u\n", rf->rf_pulseid, numpulses,rf->rf_threshold);
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
#endif /* ATH_SUPPORT_DFS */
|
||||
31
drivers/net/wireless/ar6003/host/dfs/dfs_target_api.h
Normal file
31
drivers/net/wireless/ar6003/host/dfs/dfs_target_api.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2005-2006 Atheros Communications, Inc.
|
||||
*
|
||||
* 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 _DFS_TARGET_API_H_
|
||||
#define _DFS_TARGET_API_H_
|
||||
|
||||
#ifdef ATH_SUPPORT_DFS
|
||||
|
||||
#include "ar6000_api.h"
|
||||
|
||||
#define DFS_SET_MINRSSITHRESH(dev_hdl, value) ar6000_dfs_set_minrssithresh_cmd((dev_hdl),(value))
|
||||
#define DFS_SET_MAXPULSEDUR(dev_hdl, value) ar6000_dfs_set_maxpulsedur_cmd((dev_hdl),(value))
|
||||
#define DFS_RADAR_DETECTED(dev_hdl, ch_idx, bangradar) ar6000_dfs_radar_detected_cmd((dev_hdl),(ch_idx),(bangradar))
|
||||
|
||||
#endif /* ATH_SUPPORT_DFS */
|
||||
|
||||
#endif /* _DFS_TARGET_API_ */
|
||||
26
drivers/net/wireless/ar6003/host/dfs/makefile
Normal file
26
drivers/net/wireless/ar6003/host/dfs/makefile
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#------------------------------------------------------------------------------
|
||||
# <copyright file="makefile" company="Atheros">
|
||||
# Copyright (c) 2005-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"
|
||||
#==============================================================================
|
||||
!INCLUDE $(_MAKEENVROOT)\makefile.def
|
||||
|
||||
|
||||
|
||||
379
drivers/net/wireless/ar6003/host/hif/common/hif_bmi_reg_access.c
Normal file
379
drivers/net/wireless/ar6003/host/hif/common/hif_bmi_reg_access.c
Normal file
|
|
@ -0,0 +1,379 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <copyright file="hif_bmi_diag_access.c" company="Atheros">
|
||||
// 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.
|
||||
//
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
//==============================================================================
|
||||
// common BMI access handling for register-based HIFs
|
||||
// This module implements BMI message exchanges on behalf of the BMI module for
|
||||
// HIFs that are based on a register access model
|
||||
//
|
||||
// Author(s): ="Atheros"
|
||||
//==============================================================================
|
||||
|
||||
#include "a_config.h"
|
||||
#include "athdefs.h"
|
||||
#include "a_types.h"
|
||||
#include "a_osapi.h"
|
||||
#define ATH_MODULE_NAME bmi
|
||||
#include "a_debug.h"
|
||||
#define ATH_DEBUG_BMI ATH_DEBUG_MAKE_MODULE_MASK(0)
|
||||
#include "hif.h"
|
||||
#include "bmi.h"
|
||||
#include "htc_api.h"
|
||||
#include "target_reg_table.h"
|
||||
#include "host_reg_table.h"
|
||||
|
||||
#define BMI_COMMUNICATION_TIMEOUT 100000
|
||||
|
||||
static A_BOOL pendingEventsFuncCheck = FALSE;
|
||||
static A_UINT32 commandCredits = 0;
|
||||
static A_UINT32 *pBMICmdCredits = &commandCredits;
|
||||
|
||||
/* BMI Access routines */
|
||||
static A_STATUS
|
||||
bmiBufferSend(HIF_DEVICE *device,
|
||||
A_UCHAR *buffer,
|
||||
A_UINT32 length)
|
||||
{
|
||||
A_STATUS status;
|
||||
A_UINT32 timeout;
|
||||
A_UINT32 address;
|
||||
A_UINT32 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, (A_UINT8 *)pBMICmdCredits, 4,
|
||||
HIF_RD_SYNC_BYTE_INC, NULL);
|
||||
if (status != A_OK) {
|
||||
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 != A_OK) {
|
||||
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;
|
||||
}
|
||||
|
||||
static A_STATUS
|
||||
bmiBufferReceive(HIF_DEVICE *device,
|
||||
A_UCHAR *buffer,
|
||||
A_UINT32 length,
|
||||
A_BOOL want_timeout)
|
||||
{
|
||||
A_STATUS status;
|
||||
A_UINT32 address;
|
||||
A_UINT32 mboxAddress[HTC_MAILBOX_NUM_MAX];
|
||||
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(HIF_PENDING_EVENTS_FUNC));
|
||||
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 A_UINT32 word_available;
|
||||
A_UINT32 timeout;
|
||||
|
||||
word_available = 0;
|
||||
timeout = BMI_COMMUNICATION_TIMEOUT;
|
||||
while((!want_timeout || timeout--) && !word_available) {
|
||||
|
||||
if (getPendingEventsFunc != NULL) {
|
||||
status = getPendingEventsFunc(device,
|
||||
&hifPendingEvents,
|
||||
NULL);
|
||||
if (status != A_OK) {
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("BMI: Failed to get pending events \n"));
|
||||
break;
|
||||
}
|
||||
|
||||
if (hifPendingEvents.AvailableRecvBytes >= sizeof(A_UINT32)) {
|
||||
word_available = 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
status = HIFReadWrite(device, RX_LOOKAHEAD_VALID_ADDRESS, (A_UINT8 *)&word_available,
|
||||
sizeof(word_available), HIF_RD_SYNC_BYTE_INC, NULL);
|
||||
if (status != A_OK) {
|
||||
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 */
|
||||
A_UINT32 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, (A_UINT8 *)pBMICmdCredits, sizeof(*pBMICmdCredits),
|
||||
HIF_RD_SYNC_BYTE_FIX, NULL);
|
||||
if (status != A_OK) {
|
||||
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 != A_OK) {
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to read the BMI data from the device\n"));
|
||||
return A_ERROR;
|
||||
}
|
||||
|
||||
return A_OK;
|
||||
}
|
||||
|
||||
|
||||
A_STATUS HIFRegBasedGetTargetInfo(HIF_DEVICE *device, struct bmi_target_info *targ_info)
|
||||
{
|
||||
A_STATUS status;
|
||||
A_UINT32 cid;
|
||||
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_BMI, ("BMI Get Target Info: Enter (device: 0x%p)\n", device));
|
||||
cid = BMI_GET_TARGET_INFO;
|
||||
|
||||
status = bmiBufferSend(device, (A_UCHAR *)&cid, sizeof(cid));
|
||||
if (status != A_OK) {
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to write to the device\n"));
|
||||
return A_ERROR;
|
||||
}
|
||||
|
||||
status = bmiBufferReceive(device, (A_UCHAR *)&targ_info->target_ver,
|
||||
sizeof(targ_info->target_ver), TRUE);
|
||||
if (status != A_OK) {
|
||||
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, (A_UCHAR *)&targ_info->target_info_byte_count,
|
||||
sizeof(targ_info->target_info_byte_count), TRUE);
|
||||
if (status != A_OK) {
|
||||
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,
|
||||
((A_UCHAR *)targ_info)+sizeof(targ_info->target_info_byte_count),
|
||||
sizeof(*targ_info)-sizeof(targ_info->target_info_byte_count), TRUE);
|
||||
if (status != A_OK) {
|
||||
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;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Target must be an AR6001 whose firmware does not
|
||||
* support BMI_GET_TARGET_INFO. Construct the data
|
||||
* that it would have sent.
|
||||
*/
|
||||
targ_info->target_info_byte_count=sizeof(*targ_info);
|
||||
targ_info->target_type=TARGET_TYPE_AR6001;
|
||||
}
|
||||
|
||||
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 A_OK;
|
||||
}
|
||||
|
||||
A_STATUS HIFExchangeBMIMsg(HIF_DEVICE *device,
|
||||
A_UINT8 *pSendMessage,
|
||||
A_UINT32 Length,
|
||||
A_UINT8 *pResponseMessage,
|
||||
A_UINT32 *pResponseLength,
|
||||
A_UINT32 TimeoutMS)
|
||||
{
|
||||
A_STATUS status = A_OK;
|
||||
|
||||
do {
|
||||
|
||||
status = bmiBufferSend(device, pSendMessage, Length);
|
||||
if (A_FAILED(status)) {
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI : Unable to Send Message to device \n"));
|
||||
break;
|
||||
}
|
||||
|
||||
if (pResponseMessage != NULL) {
|
||||
status = bmiBufferReceive(device, pResponseMessage, *pResponseLength, TimeoutMS ? TRUE : FALSE);
|
||||
if (A_FAILED(status)) {
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMI : Unable to read response from device \n"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} while (FALSE);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* TODO .. the following APIs are a relic of the old register based interface */
|
||||
|
||||
A_STATUS
|
||||
BMIRawWrite(HIF_DEVICE *device, A_UCHAR *buffer, A_UINT32 length)
|
||||
{
|
||||
return bmiBufferSend(device, buffer, length);
|
||||
}
|
||||
|
||||
A_STATUS
|
||||
BMIRawRead(HIF_DEVICE *device, A_UCHAR *buffer, A_UINT32 length, A_BOOL want_timeout)
|
||||
{
|
||||
return bmiBufferReceive(device, buffer, length, want_timeout);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,266 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <copyright file="hif_bmi_diag_access.c" company="Atheros">
|
||||
// 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.
|
||||
//
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
//==============================================================================
|
||||
// common Diagnostic access handling for register-based HIFs
|
||||
// This module implements diagnostic accesses on behalf of the diagnostic window module for
|
||||
// HIFs that are based on a register access model
|
||||
//
|
||||
//
|
||||
// Author(s): ="Atheros"
|
||||
//==============================================================================
|
||||
|
||||
|
||||
#include "a_config.h"
|
||||
#include "athdefs.h"
|
||||
#include "a_types.h"
|
||||
#include "a_osapi.h"
|
||||
#define ATH_MODULE_NAME misc
|
||||
#include "a_debug.h"
|
||||
|
||||
#include "targaddrs.h"
|
||||
#include "hif.h"
|
||||
#include "host_reg_table.h"
|
||||
|
||||
#define CPU_DBG_SEL_ADDRESS 0x00000483
|
||||
#define CPU_DBG_ADDRESS 0x00000484
|
||||
|
||||
#ifdef USE_4BYTE_REGISTER_ACCESS
|
||||
/* set the window address register (using 4-byte register access ).
|
||||
* 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. */
|
||||
static A_STATUS ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, A_UINT32 RegisterAddr, A_UINT32 Address)
|
||||
{
|
||||
A_STATUS status;
|
||||
static A_UINT8 addrValue[4];
|
||||
A_INT32 i;
|
||||
static A_UINT32 address;
|
||||
|
||||
address = Address;
|
||||
|
||||
|
||||
/* 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] = ((A_UINT8 *)&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 != A_OK) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (status != A_OK) {
|
||||
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,
|
||||
(A_UCHAR *)(&address),
|
||||
4,
|
||||
HIF_WR_SYNC_BYTE_INC,
|
||||
NULL);
|
||||
|
||||
if (status != A_OK) {
|
||||
AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write 0x%x to window reg: 0x%X \n",
|
||||
Address, RegisterAddr));
|
||||
return status;
|
||||
}
|
||||
|
||||
return A_OK;
|
||||
}
|
||||
#else
|
||||
|
||||
/* set the window address register */
|
||||
A_STATUS ar6000_SetAddressWindowRegister(HIF_DEVICE *hifDevice, A_UINT32 RegisterAddr, A_UINT32 Address)
|
||||
{
|
||||
A_STATUS 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 */
|
||||
((A_UCHAR *)(&Address))+1,
|
||||
sizeof(A_UINT32)-1,
|
||||
HIF_WR_SYNC_BYTE_INC,
|
||||
NULL);
|
||||
|
||||
if (status != A_OK) {
|
||||
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,
|
||||
(A_UCHAR *)(&Address),
|
||||
sizeof(A_UINT8),
|
||||
HIF_WR_SYNC_BYTE_INC,
|
||||
NULL);
|
||||
|
||||
if (status != A_OK) {
|
||||
AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write 0x%x to window reg: 0x%X \n",
|
||||
RegisterAddr, Address));
|
||||
return status;
|
||||
}
|
||||
|
||||
return A_OK;
|
||||
}
|
||||
#endif //USE_4BYTE_REGISTER_ACCESS
|
||||
|
||||
/*
|
||||
* Read from the AR6000 through its diagnostic window.
|
||||
* No cooperation from the Target is required for this.
|
||||
*/
|
||||
A_STATUS
|
||||
HIFDiagReadAccess(HIF_DEVICE *hifDevice, A_UINT32 address, A_UINT32 *data)
|
||||
{
|
||||
A_STATUS status;
|
||||
static A_UINT32 readvalue;
|
||||
|
||||
/* set window register to start read cycle */
|
||||
status = ar6000_SetAddressWindowRegister(hifDevice,
|
||||
WINDOW_READ_ADDR_ADDRESS,
|
||||
address);
|
||||
|
||||
if (status != A_OK) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* read the data */
|
||||
status = HIFReadWrite(hifDevice,
|
||||
WINDOW_DATA_ADDRESS,
|
||||
(A_UCHAR *)&readvalue,
|
||||
sizeof(A_UINT32),
|
||||
HIF_RD_SYNC_BYTE_INC,
|
||||
NULL);
|
||||
if (status != A_OK) {
|
||||
AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot read from WINDOW_DATA_ADDRESS\n"));
|
||||
return status;
|
||||
}
|
||||
|
||||
*data = readvalue;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write to the AR6000 through its diagnostic window.
|
||||
* No cooperation from the Target is required for this.
|
||||
*/
|
||||
A_STATUS HIFDiagWriteAccess(HIF_DEVICE *hifDevice, A_UINT32 address, A_UINT32 data)
|
||||
{
|
||||
A_STATUS status;
|
||||
static A_UINT32 writeValue;
|
||||
|
||||
writeValue = data;
|
||||
|
||||
/* set write data */
|
||||
status = HIFReadWrite(hifDevice,
|
||||
WINDOW_DATA_ADDRESS,
|
||||
(A_UCHAR *)&writeValue,
|
||||
sizeof(A_UINT32),
|
||||
HIF_WR_SYNC_BYTE_INC,
|
||||
NULL);
|
||||
if (status != A_OK) {
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/* TODO .. the following APIs are only available on register-based HIFs where the CPU_DBG_SEL_ADDRESS
|
||||
* register is available */
|
||||
|
||||
A_STATUS
|
||||
ar6k_ReadTargetRegister(HIF_DEVICE *hifDevice, int regsel, A_UINT32 *regval)
|
||||
{
|
||||
A_STATUS status;
|
||||
A_UCHAR vals[4];
|
||||
A_UCHAR 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 != A_OK) {
|
||||
AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Cannot write CPU_DBG_SEL (%d)\n", regsel));
|
||||
return status;
|
||||
}
|
||||
|
||||
status = HIFReadWrite(hifDevice,
|
||||
CPU_DBG_ADDRESS,
|
||||
(A_UCHAR *)vals,
|
||||
sizeof(vals),
|
||||
HIF_RD_SYNC_BYTE_INC,
|
||||
NULL);
|
||||
if (status != A_OK) {
|
||||
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(HIF_DEVICE *hifDevice, A_UINT32 *targregs)
|
||||
{
|
||||
int i;
|
||||
A_UINT32 val;
|
||||
|
||||
for (i=0; i<AR6003_FETCH_TARG_REGS_COUNT; i++) {
|
||||
val=0xffffffff;
|
||||
(void)ar6k_ReadTargetRegister(hifDevice, i, &val);
|
||||
targregs[i] = val;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
102
drivers/net/wireless/ar6003/host/hif/common/hif_sdio_common.h
Normal file
102
drivers/net/wireless/ar6003/host/hif/common/hif_sdio_common.h
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// 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_MCKINLEY_BASE 0x400 /*FIXME use the correct ID,
|
||||
Right now MCKINLEY masquerades as AR6002*/
|
||||
#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(A_UINT16 Manfid, HIF_DEVICE_MBOX_INFO *pInfo)
|
||||
{
|
||||
switch (Manfid & MANUFACTURER_ID_AR6K_BASE_MASK) {
|
||||
case MANUFACTURER_ID_AR6002_BASE :
|
||||
/* MBOX 0 has an extended range */
|
||||
|
||||
/**** FIXME .. MCKINLEY currently masquerades as an AR6002 device
|
||||
* and thus it's actual extended window size will be incorrectly
|
||||
* set. Temporarily force the location and size to match MCKINLEY ****/
|
||||
//pInfo->MboxProp[0].ExtendedAddress = HIF_MBOX0_EXTENDED_BASE_ADDR;
|
||||
//pInfo->MboxProp[0].ExtendedSize = HIF_MBOX0_EXTENDED_WIDTH_AR6002;
|
||||
|
||||
pInfo->MboxProp[0].ExtendedAddress = HIF_MBOX0_EXTENDED_BASE_ADDR_AR6003_V1;
|
||||
pInfo->MboxProp[0].ExtendedSize = HIF_MBOX0_EXTENDED_WIDTH_AR6003_V1;
|
||||
|
||||
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;
|
||||
case MANUFACTURER_ID_MCKINLEY_BASE :
|
||||
pInfo->MboxProp[0].ExtendedAddress = HIF_MBOX0_EXTENDED_BASE_ADDR_AR6003_V1; /* TBDXXX */
|
||||
pInfo->MboxProp[0].ExtendedSize = HIF_MBOX0_EXTENDED_WIDTH_AR6003_V1;
|
||||
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_*/
|
||||
12
drivers/net/wireless/ar6003/host/hif/common/makefile
Normal file
12
drivers/net/wireless/ar6003/host/hif/common/makefile
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#------------------------------------------------------------------------------
|
||||
# <copyright file="makefile" company="Atheros">
|
||||
# Copyright (c) 2005-2007 Atheros Corporation. All rights reserved.
|
||||
#
|
||||
#
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
#==============================================================================
|
||||
# Author(s): ="Atheros"
|
||||
#==============================================================================
|
||||
!INCLUDE $(_MAKEENVROOT)\makefile.def
|
||||
|
||||
90
drivers/net/wireless/ar6003/host/hif/sdio/Makefile
Normal file
90
drivers/net/wireless/ar6003/host/hif/sdio/Makefile
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
#------------------------------------------------------------------------------
|
||||
# <copyright file="makefile" company="Atheros">
|
||||
# Copyright (c) 2005-2008 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"
|
||||
#==============================================================================
|
||||
|
||||
#
|
||||
#SDIO HIF makefile for atheros SDIO stack
|
||||
#
|
||||
|
||||
# Check for SDIO stack
|
||||
ifdef ATH_SDIO_STACK_BASE
|
||||
# Someone already set it on entry, the stack resides outside this tree, we will try to build it
|
||||
_SDIO_STACK = YES
|
||||
else
|
||||
# Check for SDIO stack within this tree
|
||||
_SDIO_STACK = $(shell if [ -f $(ATH_SRC_BASE)/sdiostack/src/Makefile ]; then echo "YES"; else echo "NO"; fi)
|
||||
|
||||
ifeq ($(_SDIO_STACK), YES)
|
||||
# SDIO stack is part of the kit and will need to be compiled
|
||||
ATH_SDIO_STACK_BASE := $(ATH_SRC_BASE)/sdiostack
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
ifeq ($(ATH_BUS_SUBTYPE),linux_sdio)
|
||||
_HIF_SUB_TYPE = linux_sdio
|
||||
_SDIO_STACK = NO
|
||||
else
|
||||
_HIF_SUB_TYPE = linux_athsdio
|
||||
endif
|
||||
|
||||
|
||||
ifeq ($(_SDIO_STACK), YES)
|
||||
# Pass and translate build variables to the SDIO stack makefile
|
||||
_SDIO_STACK_MAKE_PARAMS := CT_BUILD_TYPE=$(ATH_BUILD_TYPE) \
|
||||
CT_OS_TYPE=linux \
|
||||
CT_OS_SUB_TYPE=$(ATH_OS_SUB_TYPE) \
|
||||
CT_LINUXPATH=$(ATH_LINUXPATH) \
|
||||
CT_BUILD_TYPE=$(ATH_BUILD_TYPE) \
|
||||
CT_CROSS_COMPILE_TYPE=$(ATH_CROSS_COMPILE_TYPE) \
|
||||
CT_ARCH_CPU_TYPE=$(ATH_ARCH_CPU_TYPE) \
|
||||
CT_HC_DRIVERS=$(ATH_HC_DRIVERS) \
|
||||
CT_MAKE_INCLUDE_OVERRIDE=$(_LOCALMAKE_INCLUDE) \
|
||||
CT_BUILD_OUTPUT_OVERRIDE=$(COMPILED_IMAGE_OBJECTS_PATH) \
|
||||
BUS_BUILD=1
|
||||
endif
|
||||
EXTRA_CFLAGS += -I$(ATH_SRC_BASE)/hif/sdio/$(_HIF_SUB_TYPE)/include
|
||||
EXTRA_CFLAGS += -DSDIO
|
||||
EXTRA_CFLAGS += -I$(ATH_SDIO_STACK_BASE)/src/include
|
||||
|
||||
ifeq ($(ATH_OS_SUB_TYPE),linux_2_4)
|
||||
obj-y += ../../hif/sdio/linux_athsdio/src/hif.o
|
||||
obj-y += ../../hif/sdio/linux_athsdio/src/hif_scatter.o
|
||||
endif
|
||||
|
||||
ifneq ($(ATH_OS_SUB_TYPE),linux_2_4)
|
||||
ar6000-objs := ../../hif/sdio/$(_HIF_SUB_TYPE)/src/hif.o \
|
||||
../../hif/sdio/$(_HIF_SUB_TYPE)/src/hif_scatter.o
|
||||
|
||||
|
||||
endif
|
||||
|
||||
all:
|
||||
ifeq ($(_SDIO_STACK),YES)
|
||||
$(MAKE) $(_SDIO_STACK_MAKE_PARAMS) -C $(ATH_SDIO_STACK_BASE)/src default
|
||||
-cp -f $(ATH_SDIO_STACK_BASE)/src/Module.symvers $(COMPILED_IMAGE_OBJECTS_PATH)
|
||||
endif
|
||||
|
||||
clean:
|
||||
ifeq ($(_SDIO_STACK),YES)
|
||||
$(MAKE) $(_SDIO_STACK_MAKE_PARAMS) -C $(ATH_SDIO_STACK_BASE)/src clean
|
||||
endif
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <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_types.h"
|
||||
#include "a_osapi.h"
|
||||
#include "hif.h"
|
||||
#include "../../../common/hif_sdio_common.h"
|
||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24)
|
||||
#include <linux/scatterlist.h>
|
||||
//#define HIF_LINUX_MMC_SCATTER_SUPPORT
|
||||
#endif
|
||||
|
||||
#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
|
||||
|
||||
struct _HIF_SCATTER_REQ_PRIV;
|
||||
|
||||
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;
|
||||
A_UINT32 address; /* request data */
|
||||
A_UCHAR *buffer;
|
||||
A_UINT32 length;
|
||||
A_UINT32 request;
|
||||
void *context;
|
||||
A_STATUS 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;
|
||||
A_UINT8 *dma_buffer;
|
||||
DL_LIST ScatterReqHead; /* scatter request list head */
|
||||
A_BOOL scatter_enabled; /* scatter enabled flag */
|
||||
A_BOOL is_suspend;
|
||||
A_BOOL is_disabled;
|
||||
atomic_t irqHandling;
|
||||
HIF_DEVICE_POWER_CHANGE_TYPE powerConfig;
|
||||
const struct sdio_device_id *id;
|
||||
struct mmc_host *host;
|
||||
};
|
||||
|
||||
#define HIF_DMA_BUFFER_SIZE (32 * 1024)
|
||||
#define CMD53_FIXED_ADDRESS 1
|
||||
#define CMD53_INCR_ADDRESS 2
|
||||
|
||||
BUS_REQUEST *hifAllocateBusRequest(HIF_DEVICE *device);
|
||||
void hifFreeBusRequest(HIF_DEVICE *device, BUS_REQUEST *busrequest);
|
||||
void AddToAsyncList(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
|
||||
|
||||
typedef struct _HIF_SCATTER_REQ_PRIV {
|
||||
HIF_SCATTER_REQ *pHifScatterReq; /* HIF scatter request with allocated entries */
|
||||
HIF_DEVICE *device; /* this device */
|
||||
BUS_REQUEST *busrequest; /* request associated with request */
|
||||
/* scatter list for linux */
|
||||
struct scatterlist sgentries[MAX_SCATTER_ENTRIES_PER_REQ];
|
||||
} HIF_SCATTER_REQ_PRIV;
|
||||
|
||||
#define ATH_DEBUG_SCATTER ATH_DEBUG_MAKE_MODULE_MASK(0)
|
||||
|
||||
A_STATUS SetupHIFScatterSupport(HIF_DEVICE *device, HIF_DEVICE_SCATTER_SUPPORT_INFO *pInfo);
|
||||
void CleanupHIFScatterResources(HIF_DEVICE *device);
|
||||
A_STATUS DoHifReadWriteScatter(HIF_DEVICE *device, BUS_REQUEST *busrequest);
|
||||
|
||||
#else // HIF_LINUX_MMC_SCATTER_SUPPORT
|
||||
|
||||
static inline A_STATUS SetupHIFScatterSupport(HIF_DEVICE *device, HIF_DEVICE_SCATTER_SUPPORT_INFO *pInfo)
|
||||
{
|
||||
return A_ENOTSUP;
|
||||
}
|
||||
|
||||
static inline A_STATUS DoHifReadWriteScatter(HIF_DEVICE *device, BUS_REQUEST *busrequest)
|
||||
{
|
||||
return A_ENOTSUP;
|
||||
}
|
||||
|
||||
#define CleanupHIFScatterResources(d) { }
|
||||
|
||||
#endif // HIF_LINUX_MMC_SCATTER_SUPPORT
|
||||
|
||||
#endif // _HIF_INTERNAL_H_
|
||||
|
||||
1504
drivers/net/wireless/ar6003/host/hif/sdio/linux_sdio/src/hif.c
Normal file
1504
drivers/net/wireless/ar6003/host/hif/sdio/linux_sdio/src/hif.c
Normal file
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,393 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// 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(HIF_DEVICE *device, 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 HIF_SCATTER_REQ *AllocScatterReq(HIF_DEVICE *device)
|
||||
{
|
||||
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, HIF_SCATTER_REQ, ListLink);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* called by async task to perform the operation synchronously using direct MMC APIs */
|
||||
A_STATUS DoHifReadWriteScatter(HIF_DEVICE *device, BUS_REQUEST *busrequest)
|
||||
{
|
||||
int i;
|
||||
A_UINT8 rw;
|
||||
A_UINT8 opcode;
|
||||
struct mmc_request mmcreq;
|
||||
struct mmc_command cmd;
|
||||
struct mmc_data data;
|
||||
HIF_SCATTER_REQ_PRIV *pReqPriv;
|
||||
HIF_SCATTER_REQ *pReq;
|
||||
A_STATUS status = A_OK;
|
||||
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 (A_FAILED(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 A_STATUS HifReadWriteScatter(HIF_DEVICE *device, HIF_SCATTER_REQ *pReq)
|
||||
{
|
||||
A_STATUS status = A_EINVAL;
|
||||
A_UINT32 request = pReq->Request;
|
||||
HIF_SCATTER_REQ_PRIV *pReqPriv = (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 = A_OK;
|
||||
}
|
||||
|
||||
} while (FALSE);
|
||||
|
||||
if (A_FAILED(status) && (request & HIF_ASYNCHRONOUS)) {
|
||||
pReq->CompletionStatus = status;
|
||||
pReq->CompletionRoutine(pReq);
|
||||
status = A_OK;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* setup of HIF scatter resources */
|
||||
A_STATUS SetupHIFScatterSupport(HIF_DEVICE *device, HIF_DEVICE_SCATTER_SUPPORT_INFO *pInfo)
|
||||
{
|
||||
A_STATUS status = A_ERROR;
|
||||
int i;
|
||||
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_hw_segs < MAX_SCATTER_ENTRIES_PER_REQ) {
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("HIF-SCATTER : host only supports scatter of : %d entries, need: %d \n",
|
||||
device->func->card->host->max_hw_segs, MAX_SCATTER_ENTRIES_PER_REQ));
|
||||
status = A_ENOTSUP;
|
||||
break;
|
||||
}
|
||||
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("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 = (HIF_SCATTER_REQ_PRIV *)A_MALLOC(sizeof(HIF_SCATTER_REQ_PRIV));
|
||||
if (NULL == pReqPriv) {
|
||||
break;
|
||||
}
|
||||
A_MEMZERO(pReqPriv, sizeof(HIF_SCATTER_REQ_PRIV));
|
||||
/* save the device instance*/
|
||||
pReqPriv->device = device;
|
||||
/* allocate the scatter request */
|
||||
pReqPriv->pHifScatterReq = (HIF_SCATTER_REQ *)A_MALLOC(sizeof(HIF_SCATTER_REQ) +
|
||||
(MAX_SCATTER_ENTRIES_PER_REQ - 1) * (sizeof(HIF_SCATTER_ITEM)));
|
||||
|
||||
if (NULL == pReqPriv->pHifScatterReq) {
|
||||
A_FREE(pReqPriv);
|
||||
break;
|
||||
}
|
||||
/* just zero the main part of the scatter request */
|
||||
A_MEMZERO(pReqPriv->pHifScatterReq, sizeof(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) {
|
||||
A_FREE(pReqPriv->pHifScatterReq);
|
||||
A_FREE(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 = A_OK;
|
||||
|
||||
} while (FALSE);
|
||||
|
||||
if (A_FAILED(status)) {
|
||||
CleanupHIFScatterResources(device);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* clean up scatter support */
|
||||
void CleanupHIFScatterResources(HIF_DEVICE *device)
|
||||
{
|
||||
HIF_SCATTER_REQ_PRIV *pReqPriv;
|
||||
HIF_SCATTER_REQ *pReq;
|
||||
|
||||
/* empty the free list */
|
||||
|
||||
while (1) {
|
||||
|
||||
pReq = AllocScatterReq(device);
|
||||
|
||||
if (NULL == pReq) {
|
||||
break;
|
||||
}
|
||||
|
||||
pReqPriv = (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) {
|
||||
A_FREE(pReqPriv->pHifScatterReq);
|
||||
pReqPriv->pHifScatterReq = NULL;
|
||||
}
|
||||
|
||||
A_FREE(pReqPriv);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // HIF_LINUX_MMC_SCATTER_SUPPORT
|
||||
1463
drivers/net/wireless/ar6003/host/htc2/AR6000/ar6k.c
Normal file
1463
drivers/net/wireless/ar6003/host/htc2/AR6000/ar6k.c
Normal file
File diff suppressed because it is too large
Load Diff
399
drivers/net/wireless/ar6003/host/htc2/AR6000/ar6k.h
Normal file
399
drivers/net/wireless/ar6003/host/htc2/AR6000/ar6k.h
Normal file
|
|
@ -0,0 +1,399 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <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
|
||||
|
||||
#include "athstartpack.h"
|
||||
typedef PREPACK struct _AR6K_IRQ_PROC_REGISTERS {
|
||||
A_UINT8 host_int_status;
|
||||
A_UINT8 cpu_int_status;
|
||||
A_UINT8 error_int_status;
|
||||
A_UINT8 counter_int_status;
|
||||
A_UINT8 mbox_frame;
|
||||
A_UINT8 rx_lookahead_valid;
|
||||
A_UINT8 host_int_status2;
|
||||
A_UINT8 gmbox_rx_avail;
|
||||
A_UINT32 rx_lookahead[2];
|
||||
A_UINT32 rx_gmbox_lookahead_alias[2];
|
||||
} POSTPACK AR6K_IRQ_PROC_REGISTERS;
|
||||
|
||||
#define AR6K_IRQ_PROC_REGS_SIZE sizeof(AR6K_IRQ_PROC_REGISTERS)
|
||||
|
||||
typedef PREPACK struct _AR6K_IRQ_ENABLE_REGISTERS {
|
||||
A_UINT8 int_status_enable;
|
||||
A_UINT8 cpu_int_status_enable;
|
||||
A_UINT8 error_status_enable;
|
||||
A_UINT8 counter_int_status_enable;
|
||||
} POSTPACK AR6K_IRQ_ENABLE_REGISTERS;
|
||||
|
||||
typedef PREPACK struct _AR6K_GMBOX_CTRL_REGISTERS {
|
||||
A_UINT8 int_status_enable;
|
||||
} POSTPACK AR6K_GMBOX_CTRL_REGISTERS;
|
||||
|
||||
#include "athendpack.h"
|
||||
|
||||
#define AR6K_IRQ_ENABLE_REGS_SIZE sizeof(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
|
||||
|
||||
/* buffers for ASYNC I/O */
|
||||
typedef struct AR6K_ASYNC_REG_IO_BUFFER {
|
||||
HTC_PACKET HtcPacket; /* we use an HTC packet as a wrapper for our async register-based I/O */
|
||||
A_UINT8 _Pad1[A_CACHE_LINE_PAD];
|
||||
A_UINT8 Buffer[AR6K_REG_IO_BUFFER_SIZE]; /* cache-line safe with pads around */
|
||||
A_UINT8 _Pad2[A_CACHE_LINE_PAD];
|
||||
} AR6K_ASYNC_REG_IO_BUFFER;
|
||||
|
||||
typedef struct _AR6K_GMBOX_INFO {
|
||||
void *pProtocolContext;
|
||||
A_STATUS (*pMessagePendingCallBack)(void *pContext, A_UINT8 LookAheadBytes[], int ValidBytes);
|
||||
A_STATUS (*pCreditsPendingCallback)(void *pContext, int NumCredits, A_BOOL CreditIRQEnabled);
|
||||
void (*pTargetFailureCallback)(void *pContext, A_STATUS Status);
|
||||
void (*pStateDumpCallback)(void *pContext);
|
||||
A_BOOL CreditCountIRQEnabled;
|
||||
} AR6K_GMBOX_INFO;
|
||||
|
||||
typedef struct _AR6K_DEVICE {
|
||||
A_MUTEX_T Lock;
|
||||
A_UINT8 _Pad1[A_CACHE_LINE_PAD];
|
||||
AR6K_IRQ_PROC_REGISTERS IrqProcRegisters; /* cache-line safe with pads around */
|
||||
A_UINT8 _Pad2[A_CACHE_LINE_PAD];
|
||||
AR6K_IRQ_ENABLE_REGISTERS IrqEnableRegisters; /* cache-line safe with pads around */
|
||||
A_UINT8 _Pad3[A_CACHE_LINE_PAD];
|
||||
void *HIFDevice;
|
||||
A_UINT32 BlockSize;
|
||||
A_UINT32 BlockMask;
|
||||
HIF_DEVICE_MBOX_INFO MailBoxInfo;
|
||||
HIF_PENDING_EVENTS_FUNC GetPendingEventsFunc;
|
||||
void *HTCContext;
|
||||
HTC_PACKET_QUEUE RegisterIOList;
|
||||
AR6K_ASYNC_REG_IO_BUFFER RegIOBuffers[AR6K_MAX_REG_IO_BUFFERS];
|
||||
void (*TargetFailureCallback)(void *Context);
|
||||
A_STATUS (*MessagePendingCallback)(void *Context,
|
||||
A_UINT32 LookAheads[],
|
||||
int NumLookAheads,
|
||||
A_BOOL *pAsyncProc,
|
||||
int *pNumPktsFetched);
|
||||
HIF_DEVICE_IRQ_PROCESSING_MODE HifIRQProcessingMode;
|
||||
HIF_MASK_UNMASK_RECV_EVENT HifMaskUmaskRecvEvent;
|
||||
A_BOOL HifAttached;
|
||||
HIF_DEVICE_IRQ_YIELD_PARAMS HifIRQYieldParams;
|
||||
A_BOOL DSRCanYield;
|
||||
int CurrentDSRRecvCount;
|
||||
HIF_DEVICE_SCATTER_SUPPORT_INFO HifScatterInfo;
|
||||
DL_LIST ScatterReqHead;
|
||||
A_BOOL ScatterIsVirtual;
|
||||
int MaxRecvBundleSize;
|
||||
int MaxSendBundleSize;
|
||||
AR6K_GMBOX_INFO GMboxInfo;
|
||||
A_BOOL GMboxEnabled;
|
||||
AR6K_GMBOX_CTRL_REGISTERS GMboxControlRegisters;
|
||||
int RecheckIRQStatusCnt;
|
||||
} AR6K_DEVICE;
|
||||
|
||||
#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 */
|
||||
|
||||
A_STATUS DevSetup(AR6K_DEVICE *pDev);
|
||||
void DevCleanup(AR6K_DEVICE *pDev);
|
||||
A_STATUS DevUnmaskInterrupts(AR6K_DEVICE *pDev);
|
||||
A_STATUS DevMaskInterrupts(AR6K_DEVICE *pDev);
|
||||
A_STATUS DevPollMboxMsgRecv(AR6K_DEVICE *pDev,
|
||||
A_UINT32 *pLookAhead,
|
||||
int TimeoutMS);
|
||||
A_STATUS DevRWCompletionHandler(void *context, A_STATUS status);
|
||||
A_STATUS DevDsrHandler(void *context);
|
||||
A_STATUS DevCheckPendingRecvMsgsAsync(void *context);
|
||||
void DevAsyncIrqProcessComplete(AR6K_DEVICE *pDev);
|
||||
void DevDumpRegisters(AR6K_DEVICE *pDev,
|
||||
AR6K_IRQ_PROC_REGISTERS *pIrqProcRegs,
|
||||
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
|
||||
A_STATUS DevStopRecv(AR6K_DEVICE *pDev, A_BOOL ASyncMode);
|
||||
A_STATUS DevEnableRecv(AR6K_DEVICE *pDev, A_BOOL ASyncMode);
|
||||
A_STATUS DevEnableInterrupts(AR6K_DEVICE *pDev);
|
||||
A_STATUS DevDisableInterrupts(AR6K_DEVICE *pDev);
|
||||
A_STATUS DevWaitForPendingRecv(AR6K_DEVICE *pDev,A_UINT32 TimeoutInMs,A_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 A_STATUS DevSendPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 SendLength) {
|
||||
A_UINT32 paddedLength;
|
||||
A_BOOL sync = (pPacket->Completion == NULL) ? TRUE : FALSE;
|
||||
A_STATUS 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 A_OK;
|
||||
}
|
||||
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 = A_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static INLINE A_STATUS DevRecvPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 RecvLength) {
|
||||
A_UINT32 paddedLength;
|
||||
A_STATUS status;
|
||||
A_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 A_OK;
|
||||
}
|
||||
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
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
A_STATUS DevCopyScatterListToFromDMABuffer(HIF_SCATTER_REQ *pReq, A_BOOL FromDMA);
|
||||
|
||||
/* copy any READ data back into scatter list */
|
||||
#define DEV_FINISH_SCATTER_OPERATION(pR) \
|
||||
if (A_SUCCESS((pR)->CompletionStatus) && \
|
||||
!((pR)->Request & HIF_WRITE) && \
|
||||
((pR)->ScatterMethod == HIF_SCATTER_DMA_BOUNCE)) { \
|
||||
(pR)->CompletionStatus = DevCopyScatterListToFromDMABuffer((pR),FROM_DMA_BUFFER); \
|
||||
}
|
||||
|
||||
/* copy any WRITE data to bounce buffer */
|
||||
static INLINE A_STATUS DEV_PREPARE_SCATTER_OPERATION(HIF_SCATTER_REQ *pReq) {
|
||||
if ((pReq->Request & HIF_WRITE) && (pReq->ScatterMethod == HIF_SCATTER_DMA_BOUNCE)) {
|
||||
return DevCopyScatterListToFromDMABuffer(pReq,TO_DMA_BUFFER);
|
||||
} else {
|
||||
return A_OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
A_STATUS DevSetupMsgBundling(AR6K_DEVICE *pDev, int MaxMsgsPerTransfer);
|
||||
|
||||
A_STATUS DevCleanupMsgBundling(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
|
||||
A_STATUS DevSubmitScatterRequest(AR6K_DEVICE *pDev, HIF_SCATTER_REQ *pScatterReq, A_BOOL Read, A_BOOL Async);
|
||||
|
||||
#ifdef MBOXHW_UNIT_TEST
|
||||
A_STATUS DoMboxHWTest(AR6K_DEVICE *pDev);
|
||||
#endif
|
||||
|
||||
/* completely virtual */
|
||||
typedef struct _DEV_SCATTER_DMA_VIRTUAL_INFO {
|
||||
A_UINT8 *pVirtDmaBuffer; /* dma-able buffer - CPU accessible address */
|
||||
A_UINT8 DataArea[1]; /* start of data area */
|
||||
} DEV_SCATTER_DMA_VIRTUAL_INFO;
|
||||
|
||||
|
||||
|
||||
void DumpAR6KDevState(AR6K_DEVICE *pDev);
|
||||
|
||||
/**************************************************/
|
||||
/****** GMBOX functions and definitions
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef ATH_AR6K_ENABLE_GMBOX
|
||||
|
||||
void DevCleanupGMbox(AR6K_DEVICE *pDev);
|
||||
A_STATUS DevSetupGMbox(AR6K_DEVICE *pDev);
|
||||
A_STATUS DevCheckGMboxInterrupts(AR6K_DEVICE *pDev);
|
||||
void DevNotifyGMboxTargetFailure(AR6K_DEVICE *pDev);
|
||||
|
||||
#else
|
||||
|
||||
/* compiled out */
|
||||
#define DevCleanupGMbox(p)
|
||||
#define DevCheckGMboxInterrupts(p) A_OK
|
||||
#define DevNotifyGMboxTargetFailure(p)
|
||||
|
||||
static INLINE A_STATUS DevSetupGMbox(AR6K_DEVICE *pDev) {
|
||||
pDev->GMboxEnabled = FALSE;
|
||||
return A_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef ATH_AR6K_ENABLE_GMBOX
|
||||
|
||||
/* GMBOX protocol modules must expose each of these internal APIs */
|
||||
HCI_TRANSPORT_HANDLE GMboxAttachProtocol(AR6K_DEVICE *pDev, HCI_TRANSPORT_CONFIG_INFO *pInfo);
|
||||
A_STATUS GMboxProtocolInstall(AR6K_DEVICE *pDev);
|
||||
void GMboxProtocolUninstall(AR6K_DEVICE *pDev);
|
||||
|
||||
/* API used by GMBOX protocol modules */
|
||||
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
|
||||
|
||||
A_STATUS DevGMboxWrite(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 WriteLength);
|
||||
A_STATUS DevGMboxRead(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 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;
|
||||
|
||||
A_STATUS DevGMboxIRQAction(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE, A_BOOL AsyncMode);
|
||||
A_STATUS DevGMboxReadCreditCounter(AR6K_DEVICE *pDev, A_BOOL AsyncMode, int *pCredits);
|
||||
A_STATUS DevGMboxReadCreditSize(AR6K_DEVICE *pDev, int *pCreditSize);
|
||||
A_STATUS DevGMboxRecvLookAheadPeek(AR6K_DEVICE *pDev, A_UINT8 *pLookAheadBuffer, int *pLookAheadBytes);
|
||||
A_STATUS DevGMboxSetTargetInterrupt(AR6K_DEVICE *pDev, int SignalNumber, int AckTimeoutMS);
|
||||
|
||||
#endif
|
||||
|
||||
#endif /*AR6K_H_*/
|
||||
767
drivers/net/wireless/ar6003/host/htc2/AR6000/ar6k_events.c
Normal file
767
drivers/net/wireless/ar6003/host/htc2/AR6000/ar6k_events.c
Normal file
|
|
@ -0,0 +1,767 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <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 "a_types.h"
|
||||
#include "a_osapi.h"
|
||||
#include "../htc_debug.h"
|
||||
#include "hif.h"
|
||||
#include "htc_packet.h"
|
||||
#include "ar6k.h"
|
||||
#include "target_reg_table.h"
|
||||
#include "host_reg_table.h"
|
||||
|
||||
extern void AR6KFreeIOPacket(AR6K_DEVICE *pDev, HTC_PACKET *pPacket);
|
||||
extern HTC_PACKET *AR6KAllocIOPacket(AR6K_DEVICE *pDev);
|
||||
|
||||
static A_STATUS DevServiceDebugInterrupt(AR6K_DEVICE *pDev);
|
||||
|
||||
#define DELAY_PER_INTERVAL_MS 10 /* 10 MS delay per polling interval */
|
||||
|
||||
/* completion routine for ALL HIF layer async I/O */
|
||||
A_STATUS DevRWCompletionHandler(void *context, A_STATUS status)
|
||||
{
|
||||
HTC_PACKET *pPacket = (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 A_OK;
|
||||
}
|
||||
|
||||
/* mailbox recv message polling */
|
||||
A_STATUS DevPollMboxMsgRecv(AR6K_DEVICE *pDev,
|
||||
A_UINT32 *pLookAhead,
|
||||
int TimeoutMS)
|
||||
{
|
||||
A_STATUS status = A_OK;
|
||||
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) {
|
||||
|
||||
HIF_PENDING_EVENTS_INFO events;
|
||||
|
||||
/* the HIF layer uses a special mechanism to get events, do this
|
||||
* synchronously */
|
||||
status = pDev->GetPendingEventsFunc(pDev->HIFDevice,
|
||||
&events,
|
||||
NULL);
|
||||
if (A_FAILED(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,
|
||||
(A_UINT8 *)&pDev->IrqProcRegisters,
|
||||
AR6K_IRQ_PROC_REGS_SIZE,
|
||||
HIF_RD_SYNC_BYTE_INC,
|
||||
NULL);
|
||||
|
||||
if (A_FAILED(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 A_STATUS DevServiceCPUInterrupt(AR6K_DEVICE *pDev)
|
||||
{
|
||||
A_STATUS status;
|
||||
A_UINT8 cpu_int_status;
|
||||
A_UINT8 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 == A_OK);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
static A_STATUS DevServiceErrorInterrupt(AR6K_DEVICE *pDev)
|
||||
{
|
||||
A_STATUS status;
|
||||
A_UINT8 error_int_status;
|
||||
A_UINT8 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 == A_OK);
|
||||
return status;
|
||||
}
|
||||
|
||||
static A_STATUS DevServiceDebugInterrupt(AR6K_DEVICE *pDev)
|
||||
{
|
||||
A_UINT32 dummy;
|
||||
A_STATUS 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,
|
||||
(A_UINT8 *)&dummy,
|
||||
4,
|
||||
HIF_RD_SYNC_BYTE_INC,
|
||||
NULL);
|
||||
|
||||
A_ASSERT(status == A_OK);
|
||||
return status;
|
||||
}
|
||||
|
||||
static A_STATUS DevServiceCounterInterrupt(AR6K_DEVICE *pDev)
|
||||
{
|
||||
A_UINT8 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 A_OK;
|
||||
}
|
||||
|
||||
/* callback when our fetch to get interrupt status registers completes */
|
||||
static void DevGetEventAsyncHandler(void *Context, HTC_PACKET *pPacket)
|
||||
{
|
||||
AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context;
|
||||
A_UINT32 lookAhead = 0;
|
||||
A_BOOL otherInts = FALSE;
|
||||
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevGetEventAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev));
|
||||
|
||||
do {
|
||||
|
||||
if (A_FAILED(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 */
|
||||
HIF_PENDING_EVENTS_INFO *pEvents = (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.... */
|
||||
AR6K_IRQ_PROC_REGISTERS *pReg = (AR6K_IRQ_PROC_REGISTERS *)pPacket->pBuffer;
|
||||
A_UINT8 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;
|
||||
A_STATUS 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 (A_SUCCESS(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 */
|
||||
A_STATUS DevCheckPendingRecvMsgsAsync(void *context)
|
||||
{
|
||||
AR6K_DEVICE *pDev = (AR6K_DEVICE *)context;
|
||||
A_STATUS status = A_OK;
|
||||
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,
|
||||
(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(AR6K_DEVICE *pDev)
|
||||
{
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("DevAsyncIrqProcessComplete - forcing HIF IRQ ACK \n"));
|
||||
HIFAckInterrupt(pDev->HIFDevice);
|
||||
}
|
||||
|
||||
/* process pending interrupts synchronously */
|
||||
static A_STATUS ProcessPendingIRQs(AR6K_DEVICE *pDev, A_BOOL *pDone, A_BOOL *pASyncProcessing)
|
||||
{
|
||||
A_STATUS status = A_OK;
|
||||
A_UINT8 host_int_status = 0;
|
||||
A_UINT32 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) {
|
||||
HIF_PENDING_EVENTS_INFO events;
|
||||
|
||||
/* the HIF layer uses a special mechanism to get events
|
||||
* get this synchronously */
|
||||
status = pDev->GetPendingEventsFunc(pDev->HIFDevice,
|
||||
&events,
|
||||
NULL);
|
||||
|
||||
if (A_FAILED(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);
|
||||
*
|
||||
*/
|
||||
status = HIFReadWrite(pDev->HIFDevice,
|
||||
HOST_INT_STATUS_ADDRESS,
|
||||
(A_UINT8 *)&pDev->IrqProcRegisters,
|
||||
AR6K_IRQ_PROC_REGS_SIZE,
|
||||
HIF_RD_SYNC_BYTE_INC,
|
||||
NULL);
|
||||
|
||||
if (A_FAILED(status)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_IRQ)) {
|
||||
DevDumpRegisters(pDev,
|
||||
&pDev->IrqProcRegisters,
|
||||
&pDev->IrqEnableRegisters);
|
||||
}
|
||||
|
||||
/* 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 (A_FAILED(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 (A_FAILED(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 (A_FAILED(status)){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (HOST_INT_STATUS_ERROR_GET(host_int_status)) {
|
||||
/* Error Interrupt */
|
||||
status = DevServiceErrorInterrupt(pDev);
|
||||
if (A_FAILED(status)){
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (HOST_INT_STATUS_COUNTER_GET(host_int_status)) {
|
||||
/* Counter Interrupt */
|
||||
status = DevServiceCounterInterrupt(pDev);
|
||||
if (A_FAILED(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.*/
|
||||
A_STATUS DevDsrHandler(void *context)
|
||||
{
|
||||
AR6K_DEVICE *pDev = (AR6K_DEVICE *)context;
|
||||
A_STATUS status = A_OK;
|
||||
A_BOOL done = FALSE;
|
||||
A_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 (A_FAILED(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 (A_SUCCESS(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;
|
||||
}
|
||||
|
||||
void DumpAR6KDevState(AR6K_DEVICE *pDev)
|
||||
{
|
||||
A_STATUS status;
|
||||
AR6K_IRQ_ENABLE_REGISTERS regs;
|
||||
AR6K_IRQ_PROC_REGISTERS procRegs;
|
||||
|
||||
LOCK_AR6K(pDev);
|
||||
/* copy into our temp area */
|
||||
A_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,
|
||||
(A_UINT8 *)&procRegs,
|
||||
AR6K_IRQ_PROC_REGS_SIZE,
|
||||
HIF_RD_SYNC_BYTE_INC,
|
||||
NULL);
|
||||
|
||||
if (A_FAILED(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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
757
drivers/net/wireless/ar6003/host/htc2/AR6000/ar6k_gmbox.c
Normal file
757
drivers/net/wireless/ar6003/host/htc2/AR6000/ar6k_gmbox.c
Normal file
|
|
@ -0,0 +1,757 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <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_types.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(AR6K_DEVICE *pDev, HTC_PACKET *pPacket);
|
||||
extern HTC_PACKET *AR6KAllocIOPacket(AR6K_DEVICE *pDev);
|
||||
|
||||
|
||||
/* callback when our fetch to enable/disable completes */
|
||||
static void DevGMboxIRQActionAsyncHandler(void *Context, HTC_PACKET *pPacket)
|
||||
{
|
||||
AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context;
|
||||
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevGMboxIRQActionAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev));
|
||||
|
||||
if (A_FAILED(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 A_STATUS DevGMboxCounterEnableDisable(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, A_BOOL AsyncMode)
|
||||
{
|
||||
A_STATUS status = A_OK;
|
||||
AR6K_IRQ_ENABLE_REGISTERS regs;
|
||||
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 */
|
||||
A_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 */
|
||||
A_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 (A_FAILED(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;
|
||||
}
|
||||
|
||||
|
||||
A_STATUS DevGMboxIRQAction(AR6K_DEVICE *pDev, GMBOX_IRQ_ACTION_TYPE IrqAction, A_BOOL AsyncMode)
|
||||
{
|
||||
A_STATUS status = A_OK;
|
||||
HTC_PACKET *pIOPacket = NULL;
|
||||
A_UINT8 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 */
|
||||
A_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 (A_FAILED(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(AR6K_DEVICE *pDev)
|
||||
{
|
||||
if (pDev->GMboxEnabled) {
|
||||
pDev->GMboxEnabled = FALSE;
|
||||
GMboxProtocolUninstall(pDev);
|
||||
}
|
||||
}
|
||||
|
||||
A_STATUS DevSetupGMbox(AR6K_DEVICE *pDev)
|
||||
{
|
||||
A_STATUS status = A_OK;
|
||||
A_UINT8 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 (A_FAILED(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 (A_FAILED(status)) {
|
||||
break;
|
||||
}
|
||||
|
||||
status = GMboxProtocolInstall(pDev);
|
||||
|
||||
if (A_FAILED(status)) {
|
||||
break;
|
||||
}
|
||||
|
||||
pDev->GMboxEnabled = TRUE;
|
||||
|
||||
} while (FALSE);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
A_STATUS DevCheckGMboxInterrupts(AR6K_DEVICE *pDev)
|
||||
{
|
||||
A_STATUS status = A_OK;
|
||||
A_UINT8 counter_int_status;
|
||||
int credits;
|
||||
A_UINT8 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 (A_FAILED(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,
|
||||
(A_UINT8 *)&pDev->IrqProcRegisters.rx_gmbox_lookahead_alias[0],
|
||||
pDev->IrqProcRegisters.gmbox_rx_avail);
|
||||
}
|
||||
}
|
||||
|
||||
if (A_FAILED(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 (A_FAILED(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;
|
||||
}
|
||||
|
||||
|
||||
A_STATUS DevGMboxWrite(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 WriteLength)
|
||||
{
|
||||
A_UINT32 paddedLength;
|
||||
A_BOOL sync = (pPacket->Completion == NULL) ? TRUE : FALSE;
|
||||
A_STATUS status;
|
||||
A_UINT32 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 = A_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
A_STATUS DevGMboxRead(AR6K_DEVICE *pDev, HTC_PACKET *pPacket, A_UINT32 ReadLength)
|
||||
{
|
||||
|
||||
A_UINT32 paddedLength;
|
||||
A_STATUS status;
|
||||
A_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 A_OK;
|
||||
}
|
||||
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(A_UINT8 *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, HTC_PACKET *pPacket)
|
||||
{
|
||||
AR6K_DEVICE *pDev = (AR6K_DEVICE *)Context;
|
||||
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_IRQ,("+DevGMboxReadCreditsAsyncHandler: (dev: 0x%lX)\n", (unsigned long)pDev));
|
||||
|
||||
if (A_FAILED(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"));
|
||||
}
|
||||
|
||||
A_STATUS DevGMboxReadCreditCounter(AR6K_DEVICE *pDev, A_BOOL AsyncMode, int *pCredits)
|
||||
{
|
||||
A_STATUS status = A_OK;
|
||||
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 (A_FAILED(status)) {
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
|
||||
(" DevGMboxReadCreditCounter failed! status:%d \n", status));
|
||||
}
|
||||
|
||||
if (pIOPacket != NULL) {
|
||||
if (A_SUCCESS(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;
|
||||
}
|
||||
|
||||
A_STATUS DevGMboxReadCreditSize(AR6K_DEVICE *pDev, int *pCreditSize)
|
||||
{
|
||||
A_STATUS status;
|
||||
A_UINT8 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 (A_SUCCESS(status)) {
|
||||
if (buffer[0] == 0) {
|
||||
*pCreditSize = 256;
|
||||
} else {
|
||||
*pCreditSize = buffer[0];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void DevNotifyGMboxTargetFailure(AR6K_DEVICE *pDev)
|
||||
{
|
||||
/* Target ASSERTED!!! */
|
||||
if (pDev->GMboxInfo.pTargetFailureCallback != NULL) {
|
||||
pDev->GMboxInfo.pTargetFailureCallback(pDev->GMboxInfo.pProtocolContext, A_HARDWARE);
|
||||
}
|
||||
}
|
||||
|
||||
A_STATUS DevGMboxRecvLookAheadPeek(AR6K_DEVICE *pDev, A_UINT8 *pLookAheadBuffer, int *pLookAheadBytes)
|
||||
{
|
||||
|
||||
A_STATUS status = A_OK;
|
||||
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,
|
||||
(A_UINT8 *)&procRegs,
|
||||
AR6K_IRQ_PROC_REGS_SIZE,
|
||||
HIF_RD_SYNC_BYTE_INC,
|
||||
NULL);
|
||||
|
||||
if (A_FAILED(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;
|
||||
A_MEMCPY(pLookAheadBuffer,&procRegs.rx_gmbox_lookahead_alias[0],bytes);
|
||||
*pLookAheadBytes = bytes;
|
||||
}
|
||||
|
||||
} while (FALSE);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
A_STATUS DevGMboxSetTargetInterrupt(AR6K_DEVICE *pDev, int Signal, int AckTimeoutMS)
|
||||
{
|
||||
A_STATUS status = A_OK;
|
||||
int i;
|
||||
A_UINT8 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 (A_FAILED(status)) {
|
||||
break;
|
||||
}
|
||||
|
||||
} while (FALSE);
|
||||
|
||||
|
||||
if (A_SUCCESS(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 (A_FAILED(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
|
||||
|
||||
|
||||
|
||||
|
||||
1289
drivers/net/wireless/ar6003/host/htc2/AR6000/ar6k_gmbox_hciuart.c
Normal file
1289
drivers/net/wireless/ar6003/host/htc2/AR6000/ar6k_gmbox_hciuart.c
Normal file
File diff suppressed because it is too large
Load Diff
26
drivers/net/wireless/ar6003/host/htc2/AR6000/makefile
Normal file
26
drivers/net/wireless/ar6003/host/htc2/AR6000/makefile
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#------------------------------------------------------------------------------
|
||||
# <copyright file="makefile" company="Atheros">
|
||||
# Copyright (c) 2005-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"
|
||||
#==============================================================================
|
||||
!INCLUDE $(_MAKEENVROOT)\makefile.def
|
||||
|
||||
|
||||
|
||||
578
drivers/net/wireless/ar6003/host/htc2/htc.c
Normal file
578
drivers/net/wireless/ar6003/host/htc2/htc.c
Normal file
|
|
@ -0,0 +1,578 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <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 DEBUG
|
||||
static 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(HTC_TARGET *target);
|
||||
|
||||
void HTCFreeControlBuffer(HTC_TARGET *target, HTC_PACKET *pPacket, HTC_PACKET_QUEUE *pList)
|
||||
{
|
||||
LOCK_HTC(target);
|
||||
HTC_PACKET_ENQUEUE(pList,pPacket);
|
||||
UNLOCK_HTC(target);
|
||||
}
|
||||
|
||||
HTC_PACKET *HTCAllocControlBuffer(HTC_TARGET *target, HTC_PACKET_QUEUE *pList)
|
||||
{
|
||||
HTC_PACKET *pPacket;
|
||||
|
||||
LOCK_HTC(target);
|
||||
pPacket = HTC_PACKET_DEQUEUE(pList);
|
||||
UNLOCK_HTC(target);
|
||||
|
||||
return pPacket;
|
||||
}
|
||||
|
||||
/* cleanup the HTC instance */
|
||||
static void HTCCleanup(HTC_TARGET *target)
|
||||
{
|
||||
A_INT32 i;
|
||||
|
||||
DevCleanup(&target->Device);
|
||||
|
||||
for (i = 0;i < NUM_CONTROL_BUFFERS;i++) {
|
||||
if (target->HTCControlBuffers[i].Buffer) {
|
||||
A_FREE(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 */
|
||||
A_FREE(target);
|
||||
}
|
||||
|
||||
/* registered target arrival callback from the HIF layer */
|
||||
HTC_HANDLE HTCCreate(void *hif_handle, HTC_INIT_INFO *pInfo)
|
||||
{
|
||||
HTC_TARGET *target = NULL;
|
||||
A_STATUS status = A_OK;
|
||||
int i;
|
||||
A_UINT32 ctrl_bufsz;
|
||||
A_UINT32 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 = (HTC_TARGET *)A_MALLOC(sizeof(HTC_TARGET))) == NULL) {
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Unable to allocate memory\n"));
|
||||
status = A_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
A_MEMZERO(target, sizeof(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;
|
||||
|
||||
A_MEMCPY(&target->HTCInitInfo,pInfo,sizeof(HTC_INIT_INFO));
|
||||
|
||||
ResetEndpointStates(target);
|
||||
|
||||
/* setup device layer */
|
||||
status = DevSetup(&target->Device);
|
||||
|
||||
if (A_FAILED(status)) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/* get the block sizes */
|
||||
status = HIFConfigureDevice(hif_handle, HIF_DEVICE_GET_MBOX_BLOCK_SIZE,
|
||||
blocksizes, sizeof(blocksizes));
|
||||
if (A_FAILED(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 (A_FAILED(status)) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* carve up buffers/packets for control messages */
|
||||
for (i = 0; i < NUM_CONTROL_RX_BUFFERS; i++) {
|
||||
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++) {
|
||||
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 (A_FAILED(status)) {
|
||||
if (target != NULL) {
|
||||
HTCCleanup(target);
|
||||
target = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCCreate - Exit\n"));
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
void HTCDestroy(HTC_HANDLE HTCHandle)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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 */
|
||||
A_STATUS HTCWaitTarget(HTC_HANDLE HTCHandle)
|
||||
{
|
||||
HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
|
||||
A_STATUS status;
|
||||
HTC_PACKET *pPacket = NULL;
|
||||
HTC_READY_EX_MSG *pRdyMsg;
|
||||
HTC_SERVICE_CONNECT_REQ connect;
|
||||
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 != A_OK) {
|
||||
break;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* we should be getting 1 control message that the target is ready */
|
||||
status = HTCWaitforControlMessage(target, &pPacket);
|
||||
|
||||
if (A_FAILED(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_INFO, (" 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 (A_FAILED(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));
|
||||
target->SendBundlingEnabled = TRUE;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
status = DevSetupGMbox(&target->Device);
|
||||
|
||||
if (A_FAILED(status)) {
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, (" GMbox set up Failed!!\n"));
|
||||
break;
|
||||
}
|
||||
|
||||
/* 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 (!A_FAILED(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 */
|
||||
A_STATUS HTCStart(HTC_HANDLE HTCHandle)
|
||||
{
|
||||
HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
|
||||
HTC_PACKET *pPacket;
|
||||
A_STATUS 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);
|
||||
|
||||
if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_TRC)) {
|
||||
DumpCreditDistStates(target);
|
||||
}
|
||||
|
||||
/* the caller is done connecting to services, so we can indicate to the
|
||||
* target that the setup phase is complete */
|
||||
status = HTCSendSetupComplete(target);
|
||||
|
||||
if (A_FAILED(status)) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* unmask interrupts */
|
||||
status = DevUnmaskInterrupts(&target->Device);
|
||||
|
||||
if (A_FAILED(status)) {
|
||||
HTCStop(target);
|
||||
}
|
||||
|
||||
} while (FALSE);
|
||||
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Exit\n"));
|
||||
return status;
|
||||
}
|
||||
|
||||
static void ResetEndpointStates(HTC_TARGET *target)
|
||||
{
|
||||
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;
|
||||
#ifdef HTC_EP_STAT_PROFILING
|
||||
A_MEMZERO(&pEndpoint->EndPointStats,sizeof(pEndpoint->EndPointStats));
|
||||
#endif
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
|
||||
/* flush all send packets */
|
||||
HTCFlushSendPkts(target);
|
||||
/* flush all recv buffers */
|
||||
HTCFlushRecvBuffers(target);
|
||||
|
||||
DevCleanupMsgBundling(&target->Device);
|
||||
|
||||
DevCleanupGMbox(&target->Device);
|
||||
|
||||
ResetEndpointStates(target);
|
||||
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("-HTCStop \n"));
|
||||
}
|
||||
|
||||
void HTCDumpCreditStates(HTC_HANDLE HTCHandle)
|
||||
{
|
||||
HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
|
||||
|
||||
LOCK_HTC_TX(target);
|
||||
|
||||
DumpCreditDistStates(target);
|
||||
|
||||
UNLOCK_HTC_TX(target);
|
||||
|
||||
DumpAR6KDevState(&target->Device);
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
HTC_TARGET *target = (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);
|
||||
}
|
||||
}
|
||||
|
||||
A_BOOL HTCGetEndpointStatistics(HTC_HANDLE HTCHandle,
|
||||
HTC_ENDPOINT_ID Endpoint,
|
||||
HTC_ENDPOINT_STAT_ACTION Action,
|
||||
HTC_ENDPOINT_STATS *pStats)
|
||||
{
|
||||
|
||||
#ifdef HTC_EP_STAT_PROFILING
|
||||
HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
|
||||
A_BOOL clearStats = FALSE;
|
||||
A_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);
|
||||
if (!(Endpoint < ENDPOINT_MAX)) {
|
||||
return FALSE; /* in case panic_on_assert==0 */
|
||||
}
|
||||
/* 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 */
|
||||
A_MEMCPY(pStats, &target->EndPoint[Endpoint].EndPointStats, sizeof(HTC_ENDPOINT_STATS));
|
||||
}
|
||||
|
||||
if (clearStats) {
|
||||
/* reset stats */
|
||||
A_MEMZERO(&target->EndPoint[Endpoint].EndPointStats, sizeof(HTC_ENDPOINT_STATS));
|
||||
}
|
||||
|
||||
UNLOCK_HTC_RX(target);
|
||||
UNLOCK_HTC_TX(target);
|
||||
|
||||
return TRUE;
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
AR6K_DEVICE *HTCGetAR6KDevice(void *HTCHandle)
|
||||
{
|
||||
HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
|
||||
return &target->Device;
|
||||
}
|
||||
|
||||
38
drivers/net/wireless/ar6003/host/htc2/htc_debug.h
Normal file
38
drivers/net/wireless/ar6003/host/htc2/htc_debug.h
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <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_*/
|
||||
217
drivers/net/wireless/ar6003/host/htc2/htc_internal.h
Normal file
217
drivers/net/wireless/ar6003/host/htc2/htc_internal.h
Normal file
|
|
@ -0,0 +1,217 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <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
|
||||
|
||||
//#define HTC_EP_STAT_PROFILING
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* Header files */
|
||||
|
||||
#include "a_config.h"
|
||||
#include "athdefs.h"
|
||||
#include "a_types.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)
|
||||
|
||||
typedef 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 */
|
||||
HTC_PACKET_QUEUE TxQueue; /* HTC frame buffer TX queue */
|
||||
HTC_PACKET_QUEUE RxBuffers; /* HTC frame buffer RX list */
|
||||
HTC_ENDPOINT_CREDIT_DIST CreditDist; /* credit distribution structure (exposed to driver layer) */
|
||||
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 */
|
||||
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 */
|
||||
A_UINT8 SeqNo; /* TX seq no (helpful) for debugging */
|
||||
A_UINT32 LocalConnectionFlags; /* local connection flags */
|
||||
#ifdef HTC_EP_STAT_PROFILING
|
||||
HTC_ENDPOINT_STATS EndPointStats; /* endpoint statistics */
|
||||
#endif
|
||||
} HTC_ENDPOINT;
|
||||
|
||||
#ifdef HTC_EP_STAT_PROFILING
|
||||
#define INC_HTC_EP_STAT(p,stat,count) (p)->EndPointStats.stat += (count);
|
||||
#else
|
||||
#define INC_HTC_EP_STAT(p,stat,count)
|
||||
#endif
|
||||
|
||||
#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)
|
||||
|
||||
typedef struct HTC_CONTROL_BUFFER {
|
||||
HTC_PACKET HtcPacket;
|
||||
A_UINT8 *Buffer;
|
||||
} HTC_CONTROL_BUFFER;
|
||||
|
||||
#define HTC_RECV_WAIT_BUFFERS (1 << 0)
|
||||
#define HTC_OP_STATE_STOPPING (1 << 0)
|
||||
|
||||
/* our HTC target state */
|
||||
typedef struct _HTC_TARGET {
|
||||
HTC_ENDPOINT EndPoint[ENDPOINT_MAX];
|
||||
HTC_CONTROL_BUFFER HTCControlBuffers[NUM_CONTROL_BUFFERS];
|
||||
HTC_ENDPOINT_CREDIT_DIST *EpCreditDistributionListHead;
|
||||
HTC_PACKET_QUEUE ControlBufferTXFreeList;
|
||||
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;
|
||||
AR6K_DEVICE Device; /* AR6K - specific state */
|
||||
A_UINT32 OpStateFlags;
|
||||
A_UINT32 RecvStateFlags;
|
||||
HTC_ENDPOINT_ID EpWaitingForBuffers;
|
||||
A_BOOL TargetFailure;
|
||||
#ifdef HTC_CAPTURE_LAST_FRAME
|
||||
HTC_FRAME_HDR LastFrameHdr; /* useful for debugging */
|
||||
A_UINT8 LastTrailer[256];
|
||||
A_UINT8 LastTrailerLength;
|
||||
#endif
|
||||
HTC_INIT_INFO HTCInitInfo;
|
||||
A_UINT8 HTCTargetVersion;
|
||||
int MaxMsgPerBundle; /* max messages per bundle for HTC */
|
||||
A_BOOL SendBundlingEnabled; /* run time enable for send bundling (dynamic) */
|
||||
int RecvBundlingEnabled; /* run time enable for recv bundling (dynamic) */
|
||||
} HTC_TARGET;
|
||||
|
||||
#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) ((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, HTC_PACKET *pPacket);
|
||||
void HTCControlRecv(void *Context, HTC_PACKET *pPacket);
|
||||
A_STATUS HTCWaitforControlMessage(HTC_TARGET *target, HTC_PACKET **ppControlPacket);
|
||||
HTC_PACKET *HTCAllocControlBuffer(HTC_TARGET *target, HTC_PACKET_QUEUE *pList);
|
||||
void HTCFreeControlBuffer(HTC_TARGET *target, HTC_PACKET *pPacket, HTC_PACKET_QUEUE *pList);
|
||||
A_STATUS HTCIssueSend(HTC_TARGET *target, HTC_PACKET *pPacket);
|
||||
void HTCRecvCompleteHandler(void *Context, HTC_PACKET *pPacket);
|
||||
A_STATUS HTCRecvMessagePendingHandler(void *Context, A_UINT32 MsgLookAheads[], int NumLookAheads, A_BOOL *pAsyncProc, int *pNumPktsFetched);
|
||||
void HTCProcessCreditRpt(HTC_TARGET *target, HTC_CREDIT_REPORT *pRpt, int NumEntries, HTC_ENDPOINT_ID FromEndpoint);
|
||||
A_STATUS HTCSendSetupComplete(HTC_TARGET *target);
|
||||
void HTCFlushRecvBuffers(HTC_TARGET *target);
|
||||
void HTCFlushSendPkts(HTC_TARGET *target);
|
||||
void DumpCreditDist(HTC_ENDPOINT_CREDIT_DIST *pEPDist);
|
||||
void DumpCreditDistStates(HTC_TARGET *target);
|
||||
void DebugDumpBytes(A_UCHAR *buffer, A_UINT16 length, char *pDescription);
|
||||
|
||||
static INLINE HTC_PACKET *HTC_ALLOC_CONTROL_TX(HTC_TARGET *target) {
|
||||
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) \
|
||||
{ \
|
||||
A_UINT8 *pHdrBuf; \
|
||||
(pP)->pBuffer -= HTC_HDR_LENGTH; \
|
||||
pHdrBuf = (pP)->pBuffer; \
|
||||
A_SET_UINT16_FIELD(pHdrBuf,HTC_FRAME_HDR,PayloadLen,(A_UINT16)(pP)->ActualLength); \
|
||||
A_SET_UINT8_FIELD(pHdrBuf,HTC_FRAME_HDR,Flags,(sendflags)); \
|
||||
A_SET_UINT8_FIELD(pHdrBuf,HTC_FRAME_HDR,EndpointID, (A_UINT8)(pP)->Endpoint); \
|
||||
A_SET_UINT8_FIELD(pHdrBuf,HTC_FRAME_HDR,ControlBytes[0], (A_UINT8)(ctrl0)); \
|
||||
A_SET_UINT8_FIELD(pHdrBuf,HTC_FRAME_HDR,ControlBytes[1], (A_UINT8)(ctrl1)); \
|
||||
}
|
||||
|
||||
#define HTC_UNPREPARE_SEND_PKT(pP) \
|
||||
(pP)->pBuffer += HTC_HDR_LENGTH; \
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _HTC_INTERNAL_H_ */
|
||||
1572
drivers/net/wireless/ar6003/host/htc2/htc_recv.c
Normal file
1572
drivers/net/wireless/ar6003/host/htc2/htc_recv.c
Normal file
File diff suppressed because it is too large
Load Diff
1024
drivers/net/wireless/ar6003/host/htc2/htc_send.c
Normal file
1024
drivers/net/wireless/ar6003/host/htc2/htc_send.c
Normal file
File diff suppressed because it is too large
Load Diff
449
drivers/net/wireless/ar6003/host/htc2/htc_services.c
Normal file
449
drivers/net/wireless/ar6003/host/htc2/htc_services.c
Normal file
|
|
@ -0,0 +1,449 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <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, 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, 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((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 + (A_UINT32)HTC_HDR_LENGTH));
|
||||
|
||||
/* dump header and message */
|
||||
DebugDumpBytes(pPacket->pBuffer - HTC_HDR_LENGTH,
|
||||
pPacket->ActualLength + HTC_HDR_LENGTH,
|
||||
"Unexpected ENDPOINT 0 Message");
|
||||
}
|
||||
|
||||
HTC_RECYCLE_RX_PKT((HTC_TARGET*)Context,pPacket,&((HTC_TARGET*)Context)->EndPoint[0]);
|
||||
}
|
||||
|
||||
A_STATUS HTCSendSetupComplete(HTC_TARGET *target)
|
||||
{
|
||||
HTC_PACKET *pSendPacket = NULL;
|
||||
A_STATUS 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;
|
||||
A_UINT32 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;
|
||||
}
|
||||
A_MEMCPY(&pSetupCompleteEx->SetupFlags, &setupFlags, sizeof(pSetupCompleteEx->SetupFlags));
|
||||
SET_HTC_PACKET_INFO_TX(pSendPacket,
|
||||
NULL,
|
||||
(A_UINT8 *)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,
|
||||
(A_UINT8 *)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;
|
||||
}
|
||||
|
||||
|
||||
A_STATUS HTCConnectService(HTC_HANDLE HTCHandle,
|
||||
HTC_SERVICE_CONNECT_REQ *pConnectReq,
|
||||
HTC_SERVICE_CONNECT_RESP *pConnectResp)
|
||||
{
|
||||
HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle);
|
||||
A_STATUS status = A_OK;
|
||||
HTC_PACKET *pRecvPacket = NULL;
|
||||
HTC_PACKET *pSendPacket = NULL;
|
||||
HTC_CONNECT_SERVICE_RESPONSE_MSG *pResponseMsg;
|
||||
HTC_CONNECT_SERVICE_MSG *pConnectMsg;
|
||||
HTC_ENDPOINT_ID assignedEndpoint = ENDPOINT_MAX;
|
||||
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 ) */
|
||||
A_MEMCPY((A_UINT8 *)pConnectMsg + sizeof(HTC_CONNECT_SERVICE_MSG),
|
||||
pConnectReq->pMetaData,
|
||||
pConnectReq->MetaDataLength);
|
||||
pConnectMsg->ServiceMetaLength = pConnectReq->MetaDataLength;
|
||||
}
|
||||
|
||||
SET_HTC_PACKET_INFO_TX(pSendPacket,
|
||||
NULL,
|
||||
(A_UINT8 *)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 (A_FAILED(status)) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* wait for response */
|
||||
status = HTCWaitforControlMessage(target, &pRecvPacket);
|
||||
|
||||
if (A_FAILED(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 */
|
||||
A_MEMCPY(pConnectResp->pMetaData,
|
||||
((A_UINT8 *)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 = A_OK;
|
||||
|
||||
} 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(HTC_TARGET *target, HTC_ENDPOINT_CREDIT_DIST *pEpDist)
|
||||
{
|
||||
HTC_ENDPOINT_CREDIT_DIST *pCurEntry = NULL;
|
||||
HTC_ENDPOINT_CREDIT_DIST *pLastEntry = NULL;
|
||||
|
||||
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,
|
||||
HTC_ENDPOINT_CREDIT_DIST *pEPList,
|
||||
int TotalCredits)
|
||||
{
|
||||
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,
|
||||
HTC_ENDPOINT_CREDIT_DIST *pEPDistList,
|
||||
HTC_CREDIT_DIST_REASON Reason)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
57
drivers/net/wireless/ar6003/host/include/a_config.h
Normal file
57
drivers/net/wireless/ar6003/host/include/a_config.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <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_
|
||||
|
||||
#ifdef ATHR_WM_NWF
|
||||
#include "../os/windows/include/config.h"
|
||||
#endif
|
||||
|
||||
#ifdef ATHR_CE_LEGACY
|
||||
#include "../os/windows/include/config.h"
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) && !defined(LINUX_EMULATION)
|
||||
#include "../os/linux/include/config_linux.h"
|
||||
#endif
|
||||
|
||||
#ifdef REXOS
|
||||
#include "../os/rexos/include/common/config_rexos.h"
|
||||
#endif
|
||||
|
||||
#ifdef ATHR_WIN_NWF
|
||||
#include "../os/windows/include/config.h"
|
||||
#pragma warning( disable:4242)
|
||||
#pragma warning( disable:4100)
|
||||
#pragma warning( disable:4189)
|
||||
#pragma warning( disable:4244)
|
||||
#pragma warning( disable:4701)
|
||||
#pragma warning( disable:4389)
|
||||
#pragma warning( disable:4057)
|
||||
#pragma warning( disable:28193)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
219
drivers/net/wireless/ar6003/host/include/a_debug.h
Normal file
219
drivers/net/wireless/ar6003/host/include/a_debug.h
Normal file
|
|
@ -0,0 +1,219 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <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_types.h>
|
||||
#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(A_UCHAR *buffer, A_UINT16 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 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
|
||||
|
||||
typedef struct {
|
||||
A_UINT32 Mask;
|
||||
A_CHAR Description[ATH_DEBUG_MAX_MASK_DESC_LENGTH];
|
||||
} ATH_DEBUG_MASK_DESCRIPTION;
|
||||
|
||||
#define ATH_DEBUG_INFO_FLAGS_REGISTERED (1 << 0)
|
||||
|
||||
typedef struct _ATH_DEBUG_MODULE_DBG_INFO{
|
||||
struct _ATH_DEBUG_MODULE_DBG_INFO *pNext;
|
||||
A_CHAR ModuleName[16];
|
||||
A_CHAR ModuleDescription[ATH_DEBUG_MAX_MOD_DESC_LENGTH];
|
||||
A_UINT32 Flags;
|
||||
A_UINT32 CurrentMask;
|
||||
int MaxDescriptions;
|
||||
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(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 DEBUG
|
||||
|
||||
/* 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 /* !DEBUG */
|
||||
/* NON DEBUG */
|
||||
#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
|
||||
|
||||
A_STATUS a_get_module_mask(A_CHAR *module_name, A_UINT32 *pMask);
|
||||
A_STATUS a_set_module_mask(A_CHAR *module_name, A_UINT32 Mask);
|
||||
void a_dump_module_debug_info_by_name(A_CHAR *module_name);
|
||||
void a_module_debug_support_init(void);
|
||||
void a_module_debug_support_cleanup(void);
|
||||
|
||||
#ifdef ATHR_WM_NWF
|
||||
#include "../os/windows/include/debug.h"
|
||||
#endif
|
||||
|
||||
#ifdef ATHR_CE_LEGACY
|
||||
#include "../os/windows/include/debug.h"
|
||||
#endif
|
||||
|
||||
#if defined(__linux__) && !defined(LINUX_EMULATION)
|
||||
#include "../os/linux/include/debug_linux.h"
|
||||
#endif
|
||||
|
||||
#ifdef REXOS
|
||||
#include "../os/rexos/include/common/debug_rexos.h"
|
||||
#endif
|
||||
|
||||
#if defined ART_WIN
|
||||
#include "../os/win_art/include/debug_win.h"
|
||||
#endif
|
||||
|
||||
#ifdef ATHR_WIN_NWF
|
||||
#include "../os/windows/include/win/debug_win.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif
|
||||
50
drivers/net/wireless/ar6003/host/include/a_drv.h
Normal file
50
drivers/net/wireless/ar6003/host/include/a_drv.h
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <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_
|
||||
|
||||
#if defined(__linux__) && !defined(LINUX_EMULATION)
|
||||
#include "../os/linux/include/athdrv_linux.h"
|
||||
#endif
|
||||
|
||||
#ifdef ATHR_WM_NWF
|
||||
#include "../os/windows/include/athdrv.h"
|
||||
#endif
|
||||
|
||||
#ifdef ATHR_CE_LEGACY
|
||||
#include "../os/windows/include/athdrv.h"
|
||||
#endif
|
||||
|
||||
#ifdef REXOS
|
||||
#include "../os/rexos/include/common/athdrv_rexos.h"
|
||||
#endif
|
||||
|
||||
#ifdef ATHR_WIN_NWF
|
||||
#include "../os/windows/include/athdrv.h"
|
||||
#endif
|
||||
|
||||
#endif /* _ADRV_H_ */
|
||||
333
drivers/net/wireless/ar6003/host/include/a_drv_api.h
Normal file
333
drivers/net/wireless/ar6003/host/include/a_drv_api.h
Normal file
|
|
@ -0,0 +1,333 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <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, pEvt) \
|
||||
ar6000_connect_event((devt), (pEvt))
|
||||
|
||||
#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
|
||||
|
||||
#ifdef P2P
|
||||
#define A_WMI_P2PGONEG_EVENT(devt, res, len)\
|
||||
p2p_go_neg_event((devt),(res), (len))
|
||||
|
||||
#define A_WMI_P2PGONEG_REQ_EVENT(devt, sa, dev_passwd_id)\
|
||||
p2p_go_neg_req_event((devt), (sa), (dev_passwd_id))
|
||||
|
||||
#define A_WMI_P2P_INVITE_SENT_RESULT_EVENT(devt, res, len)\
|
||||
p2p_invite_sent_result_event((devt), (res), (len))
|
||||
|
||||
#define A_WMI_P2P_INVITE_RCVD_RESULT_EVENT(devt, res, len)\
|
||||
p2p_invite_rcvd_result_event((devt), (res), (len))
|
||||
|
||||
#define A_WMI_P2PDEV_EVENT(devt, addr, dev_addr, \
|
||||
pri_dev_type, dev_name, dev_name_len, config_methods,\
|
||||
dev_capab, grp_capab)\
|
||||
ar6000_p2pdev_event((devt), (addr), (dev_addr),\
|
||||
(pri_dev_type), (dev_name), (dev_name_len), (config_methods),\
|
||||
(dev_capab), (grp_capab))
|
||||
|
||||
#define A_WMI_P2P_PROV_DISC_REQ_EVENT(devt, peer, config_methods, dev_addr, \
|
||||
pri_dev_type, dev_name, dev_name_len, supp_config_methods,\
|
||||
dev_capab, group_capab) \
|
||||
ar6000_p2p_prov_disc_req_event((devt), (peer), (config_methods), \
|
||||
(dev_addr), (pri_dev_type), (dev_name), (dev_name_len),\
|
||||
(supp_config_methods), (dev_capab), (group_capab))
|
||||
|
||||
#define A_WMI_P2P_PROV_DISC_RESP_EVENT(devt, peer, config_methods) \
|
||||
ar6000_p2p_prov_disc_resp_event((devt), (peer), (config_methods))
|
||||
|
||||
#define A_WMI_GET_P2P_CTX(devt) \
|
||||
get_p2p_ctx((devt))
|
||||
|
||||
#define A_WMI_GET_WMI_CTX(devt) \
|
||||
get_wmi_ctx((devt))
|
||||
|
||||
#define A_WMI_GET_DEV_NETWORK_SUBTYPE(devt) \
|
||||
get_network_subtype((devt))
|
||||
|
||||
#define A_WMI_P2P_SD_RX_EVENT(devt, ev) \
|
||||
ar6000_p2p_sd_rx_event((devt), (ev))
|
||||
#endif /* P2P */
|
||||
|
||||
#ifdef CONFIG_WLAN_RFKILL
|
||||
#define A_WMI_RFKILL_STATE_CHANGE_EVENT(devt,radiostate) \
|
||||
ar6000_rfkill_state_change_event((devt),(radiostate))
|
||||
|
||||
#define A_WMI_RFKILL_GET_MODE_CMD_EVENT(devt,datap,len) \
|
||||
ar6000_rfkill_get_mode_cmd_event_rx((devt),(datap));
|
||||
|
||||
#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))
|
||||
|
||||
#ifdef ATH_SUPPORT_DFS
|
||||
|
||||
#define A_WMI_DFS_ATTACH_EVENT(devt, capinfo) \
|
||||
ar6000_dfs_attach_event((devt),(capinfo))
|
||||
|
||||
#define A_WMI_DFS_INIT_EVENT(devt, capinfo) \
|
||||
ar6000_dfs_init_event((devt),(capinfo))
|
||||
|
||||
#define A_WMI_DFS_PHYERR_EVENT(devt, info) \
|
||||
ar6000_dfs_phyerr_event((devt),(info))
|
||||
|
||||
#define A_WMI_DFS_RESET_DELAYLINES_EVENT(devt) \
|
||||
ar6000_dfs_reset_delaylines_event((devt))
|
||||
|
||||
#define A_WMI_DFS_RESET_RADARQ_EVENT(devt) \
|
||||
ar6000_dfs_reset_radarq_event((devt))
|
||||
|
||||
#define A_WMI_DFS_RESET_AR_EVENT(devt) \
|
||||
ar6000_dfs_reset_ar_event((devt))
|
||||
|
||||
#define A_WMI_DFS_RESET_ARQ_EVENT(devt) \
|
||||
ar6000_dfs_reset_arq_event((devt))
|
||||
|
||||
#define A_WMI_DFS_SET_DUR_MULTIPLIER_EVENT(devt, value) \
|
||||
ar6000_dfs_set_dur_multiplier_event((devt), (value))
|
||||
|
||||
#define A_WMI_DFS_SET_BANGRADAR_EVENT(devt, value) \
|
||||
ar6000_dfs_set_bangradar_event((devt), (value))
|
||||
|
||||
#define A_WMI_DFS_SET_DEBUGLEVEL_EVENT(devt, value) \
|
||||
ar6000_dfs_set_debuglevel_event((devt), (value))
|
||||
|
||||
#endif /* ATH_SUPPORT_DFS */
|
||||
|
||||
#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(devt) \
|
||||
ar6000_dbglog_init_done(devt);
|
||||
|
||||
#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))
|
||||
|
||||
#define A_WMI_WACINFO_EVENT(devt, pStats, len) \
|
||||
ar6000_wacinfo_event((devt), (pStats), (len))
|
||||
|
||||
#ifdef CONFIG_HOST_GPIO_SUPPORT
|
||||
|
||||
#define A_WMI_GPIO_INTR_RX(devt, intr_mask, input_values) \
|
||||
ar6000_gpio_intr_rx((devt), (intr_mask), (input_values))
|
||||
|
||||
#define A_WMI_GPIO_DATA_RX(devt, reg_id, value) \
|
||||
ar6000_gpio_data_rx((devt), (reg_id), (value))
|
||||
|
||||
#define A_WMI_GPIO_ACK_RX(devt) \
|
||||
ar6000_gpio_ack_rx((devt))
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef SEND_EVENT_TO_APP
|
||||
|
||||
#define A_WMI_SEND_EVENT_TO_APP(ar, eventId, datap, len) \
|
||||
ar6000_send_event_to_app((ar), (eventId), (datap), (len))
|
||||
|
||||
#define A_WMI_SEND_GENERIC_EVENT_TO_APP(ar, eventId, datap, len) \
|
||||
ar6000_send_generic_event_to_app((ar), (eventId), (datap), (len))
|
||||
|
||||
#else
|
||||
|
||||
#define A_WMI_SEND_EVENT_TO_APP(ar, eventId, datap, len)
|
||||
#define A_WMI_SEND_GENERIC_EVENT_TO_APP(ar, eventId, datap, len)
|
||||
|
||||
#endif
|
||||
|
||||
#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))
|
||||
|
||||
#define A_WMI_PROBERESP_RECV_EVENT(devt, datap, len, bssid)\
|
||||
ar6000_indicate_proberesp((devt), (datap), (len), (bssid))
|
||||
|
||||
#define A_WMI_BEACON_RECV_EVENT(devt, datap, len, bssid)\
|
||||
ar6000_indicate_beacon((devt), (datap), (len), (bssid))
|
||||
|
||||
#define A_WMI_ASSOC_REQ_REPORT_EVENT(devt, status, rspType, datap, len)\
|
||||
ar6000_assoc_req_report_event((devt),(status),(rspType),(datap),(len))
|
||||
|
||||
#define A_WMI_GET_DEVICE_ADDR(devt, addr) \
|
||||
ar6000_get_device_addr((devt), (addr))
|
||||
|
||||
/****************************************************************************/
|
||||
/****************************************************************************/
|
||||
/** **/
|
||||
/** 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
|
||||
58
drivers/net/wireless/ar6003/host/include/a_osapi.h
Normal file
58
drivers/net/wireless/ar6003/host/include/a_osapi.h
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <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_
|
||||
|
||||
#if defined(__linux__) && !defined(LINUX_EMULATION)
|
||||
#include "../os/linux/include/osapi_linux.h"
|
||||
#endif
|
||||
|
||||
#ifdef ATHR_WM_NWF
|
||||
#include "../os/windows/include/osapi.h"
|
||||
#include "../os/windows/include/netbuf.h"
|
||||
#endif
|
||||
|
||||
#ifdef ATHR_CE_LEGACY
|
||||
#include "../os/windows/include/osapi.h"
|
||||
#include "../os/windows/include/netbuf.h"
|
||||
#endif
|
||||
|
||||
#ifdef REXOS
|
||||
#include "../os/rexos/include/common/osapi_rexos.h"
|
||||
#endif
|
||||
|
||||
#if defined ART_WIN
|
||||
#include "../os/win_art/include/osapi_win.h"
|
||||
#include "../os/win_art/include/netbuf.h"
|
||||
#endif
|
||||
|
||||
#ifdef ATHR_WIN_NWF
|
||||
#include "../os/windows/include/win/osapi_win.h"
|
||||
#include "../os/windows/include/netbuf.h"
|
||||
#endif
|
||||
|
||||
#endif /* _OSAPI_H_ */
|
||||
54
drivers/net/wireless/ar6003/host/include/a_types.h
Normal file
54
drivers/net/wireless/ar6003/host/include/a_types.h
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <copyright file="a_types.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_TYPES_H_
|
||||
#define _A_TYPES_H_
|
||||
|
||||
#if defined(__linux__) && !defined(LINUX_EMULATION)
|
||||
#include "../os/linux/include/athtypes_linux.h"
|
||||
#endif
|
||||
|
||||
#ifdef ATHR_WM_NWF
|
||||
#include "../os/windows/include/athtypes.h"
|
||||
#endif
|
||||
|
||||
#ifdef ATHR_CE_LEGACY
|
||||
#include "../os/windows/include/athtypes.h"
|
||||
#endif
|
||||
|
||||
#ifdef REXOS
|
||||
#include "../os/rexos/include/common/athtypes_rexos.h"
|
||||
#endif
|
||||
|
||||
#if defined ART_WIN
|
||||
#include "../os/win_art/include/athtypes_win.h"
|
||||
#endif
|
||||
|
||||
#ifdef ATHR_WIN_NWF
|
||||
#include <athtypes_win.h>
|
||||
#endif
|
||||
|
||||
#endif /* _ATHTYPES_H_ */
|
||||
156
drivers/net/wireless/ar6003/host/include/aggr_recv_api.h
Normal file
156
drivers/net/wireless/ar6003/host/include/aggr_recv_api.h
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
*
|
||||
* 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, A_UINT16 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.
|
||||
*
|
||||
* Also 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.
|
||||
* Returns A_OK if init success, else returns A_ERROR
|
||||
*/
|
||||
A_UINT8
|
||||
aggr_init(ALLOC_NETBUFS netbuf_allocator, RX_CALLBACK fn);
|
||||
|
||||
/*
|
||||
* aggr_init_conn:
|
||||
* Initialises the data structures, allocates data queues and
|
||||
* os buffers. Returns the context for a single conn aggr.
|
||||
* For each supported conn, this API should be called.
|
||||
*/
|
||||
void *
|
||||
aggr_init_conn(void);
|
||||
|
||||
/*
|
||||
* 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, A_UINT8 tid, A_UINT16 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 succesfully 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, A_UINT8 tid, A_UINT16 seq_no, A_UINT8 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, A_UINT8 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, A_UINT8 tid, A_UINT16 seq_no, A_BOOL is_amsdu, void **osbuf);
|
||||
|
||||
|
||||
/*
|
||||
* aggr_module_destroy:
|
||||
* Frees up all the queues and frames in them.
|
||||
*/
|
||||
void
|
||||
aggr_module_destroy(void);
|
||||
|
||||
/*
|
||||
* * aggr_module_destroy_timers:
|
||||
* * Disarm the timers.
|
||||
* */
|
||||
void
|
||||
aggr_module_destroy_timers(void *cntxt);
|
||||
|
||||
/*
|
||||
* aggr_module_destroy_conn:
|
||||
* Frees up all the queues and frames in them. Releases the cntxt to OS.
|
||||
*/
|
||||
void
|
||||
aggr_module_destroy_conn(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, void *dev);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*__AGGR_RECV_API_H__ */
|
||||
65
drivers/net/wireless/ar6003/host/include/ar3kconfig.h
Normal file
65
drivers/net/wireless/ar6003/host/include/ar3kconfig.h
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// 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)
|
||||
|
||||
|
||||
typedef struct {
|
||||
A_UINT32 Flags; /* config flags */
|
||||
void *pHCIDev; /* HCI bridge device */
|
||||
HCI_TRANSPORT_PROPERTIES *pHCIProps; /* HCI bridge props */
|
||||
HIF_DEVICE *pHIFDevice; /* HIF layer device */
|
||||
|
||||
A_UINT32 AR3KBaudRate; /* AR3K operational baud rate */
|
||||
A_UINT16 AR6KScale; /* AR6K UART scale value */
|
||||
A_UINT16 AR6KStep; /* AR6K UART step value */
|
||||
struct hci_dev *pBtStackHCIDev; /* BT Stack HCI dev */
|
||||
A_UINT32 PwrMgmtEnabled; /* TLPM enabled? */
|
||||
A_UINT32 IdleTimeout; /* TLPM idle timeout */
|
||||
A_UINT16 WakeupTimeout; /* TLPM wakeup timeout */
|
||||
A_UINT8 bdaddr[6]; /* Bluetooth device address */
|
||||
} AR3K_CONFIG_INFO;
|
||||
|
||||
A_STATUS AR3KConfigure(AR3K_CONFIG_INFO *pConfigInfo);
|
||||
|
||||
A_STATUS AR3KConfigureExit(void *config);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*AR3KCONFIG_H_*/
|
||||
54
drivers/net/wireless/ar6003/host/include/ar6000_api.h
Normal file
54
drivers/net/wireless/ar6003/host/include/ar6000_api.h
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <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_
|
||||
|
||||
#if defined(__linux__) && !defined(LINUX_EMULATION)
|
||||
#include "../os/linux/include/ar6xapi_linux.h"
|
||||
#endif
|
||||
|
||||
#ifdef ATHR_WM_NWF
|
||||
#include "../os/windows/include/ar6xapi.h"
|
||||
#endif
|
||||
|
||||
#ifdef ATHR_CE_LEGACY
|
||||
#include "../os/windows/include/ar6xapi.h"
|
||||
#endif
|
||||
|
||||
#ifdef REXOS
|
||||
#include "../os/rexos/include/common/ar6xapi_rexos.h"
|
||||
#endif
|
||||
|
||||
#if defined ART_WIN
|
||||
#include "../os/win_art/include/ar6xapi_win.h"
|
||||
#endif
|
||||
|
||||
#ifdef ATHR_WIN_NWF
|
||||
#include "../os/windows/include/ar6xapi.h"
|
||||
#endif
|
||||
|
||||
#endif /* _AR6000_API_H */
|
||||
|
||||
48
drivers/net/wireless/ar6003/host/include/ar6000_diag.h
Normal file
48
drivers/net/wireless/ar6003/host/include/ar6000_diag.h
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <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_
|
||||
|
||||
|
||||
A_STATUS
|
||||
ar6000_ReadRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data);
|
||||
|
||||
A_STATUS
|
||||
ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data);
|
||||
|
||||
A_STATUS
|
||||
ar6000_ReadDataDiag(HIF_DEVICE *hifDevice, A_UINT32 address,
|
||||
A_UCHAR *data, A_UINT32 length);
|
||||
|
||||
A_STATUS
|
||||
ar6000_WriteDataDiag(HIF_DEVICE *hifDevice, A_UINT32 address,
|
||||
A_UCHAR *data, A_UINT32 length);
|
||||
|
||||
A_STATUS
|
||||
ar6k_ReadTargetRegister(HIF_DEVICE *hifDevice, int regsel, A_UINT32 *regval);
|
||||
|
||||
void
|
||||
ar6k_FetchTargetRegs(HIF_DEVICE *hifDevice, A_UINT32 *targregs);
|
||||
|
||||
#endif /*AR6000_DIAG_H_*/
|
||||
46
drivers/net/wireless/ar6003/host/include/ar6kap_common.h
Normal file
46
drivers/net/wireless/ar6003/host/include/ar6kap_common.h
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
//------------------------------------------------------------------------------
|
||||
|
||||
// <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 {
|
||||
A_UINT8 mac[ATH_MAC_LEN];
|
||||
A_UINT8 aid;
|
||||
A_UINT8 keymgmt;
|
||||
A_UINT8 ucipher;
|
||||
A_UINT8 auth;
|
||||
A_UINT8 wmode;
|
||||
} station_t;
|
||||
|
||||
typedef struct {
|
||||
station_t sta[AP_MAX_NUM_STA];
|
||||
} ap_get_sta_t;
|
||||
#endif /* _AR6KAP_COMMON_H_ */
|
||||
135
drivers/net/wireless/ar6003/host/include/athbtfilter.h
Normal file
135
drivers/net/wireless/ar6003/host/include/athbtfilter.h
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <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);
|
||||
|
||||
typedef struct _ATHBT_FILTER_INSTANCE {
|
||||
#ifdef UNDER_CE
|
||||
WCHAR *pWlanAdapterName; /* filled in by user */
|
||||
#else
|
||||
A_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 */
|
||||
} ATH_BT_FILTER_INSTANCE;
|
||||
|
||||
|
||||
/* 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, A_UINT32 flags);
|
||||
void AthBtFilter_Detach(ATH_BT_FILTER_INSTANCE *pInstance);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*ATHBTFILTER_H_*/
|
||||
52
drivers/net/wireless/ar6003/host/include/athendpack.h
Normal file
52
drivers/net/wireless/ar6003/host/include/athendpack.h
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <copyright file="athendpack.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.
|
||||
//
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
//==============================================================================
|
||||
// end compiler-specific structure packing
|
||||
//
|
||||
// Author(s): ="Atheros"
|
||||
//==============================================================================
|
||||
#ifdef VXWORKS
|
||||
#endif /* VXWORKS */
|
||||
|
||||
#if defined(LINUX) || defined(__linux__)
|
||||
#endif /* LINUX */
|
||||
|
||||
#ifdef QNX
|
||||
#endif /* QNX */
|
||||
|
||||
#ifdef INTEGRITY
|
||||
#include "integrity/athendpack_integrity.h"
|
||||
#endif /* INTEGRITY */
|
||||
|
||||
#ifdef NUCLEUS
|
||||
#endif /* NUCLEUS */
|
||||
|
||||
|
||||
#ifdef ATHR_WM_NWF
|
||||
#include "../os/windows/include/athendpack.h"
|
||||
#endif
|
||||
|
||||
#ifdef ATHR_CE_LEGACY
|
||||
#include "../os/windows/include/athendpack.h"
|
||||
#endif /* WINCE */
|
||||
|
||||
#ifdef ATHR_WIN_NWF
|
||||
#include <athendpack_win.h>
|
||||
#endif
|
||||
69
drivers/net/wireless/ar6003/host/include/athstartpack.h
Normal file
69
drivers/net/wireless/ar6003/host/include/athstartpack.h
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <copyright file="athstartpack.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.
|
||||
//
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
//==============================================================================
|
||||
// start compiler-specific structure packing
|
||||
//
|
||||
// Author(s): ="Atheros"
|
||||
//==============================================================================
|
||||
#ifdef VXWORKS
|
||||
#endif /* VXWORKS */
|
||||
|
||||
#if defined(LINUX) || defined(__linux__)
|
||||
#endif /* LINUX */
|
||||
|
||||
#ifdef QNX
|
||||
#endif /* QNX */
|
||||
|
||||
#ifdef INTEGRITY
|
||||
#include "integrity/athstartpack_integrity.h"
|
||||
#endif /* INTEGRITY */
|
||||
|
||||
#ifdef NUCLEUS
|
||||
#endif /* NUCLEUS */
|
||||
|
||||
#ifdef ATHR_WM_NWF
|
||||
#include "../os/windows/include/athstartpack.h"
|
||||
#define PREPACK
|
||||
#endif
|
||||
|
||||
#ifdef ATHR_CE_LEGACY
|
||||
#include "../os/windows/include/athstartpack.h"
|
||||
#endif /* WINCE */
|
||||
|
||||
#ifdef ATHR_WIN_NWF
|
||||
|
||||
#ifndef PREPACK
|
||||
#define PREPACK __declspec(align(1))
|
||||
#endif
|
||||
|
||||
#include <athstartpack_win.h>
|
||||
#define __ATTRIB_PACK POSTPACK
|
||||
|
||||
#endif
|
||||
|
||||
#if __LONG_MAX__ == __INT_MAX__
|
||||
/* 32-bit compilation */
|
||||
#define PREPACK64
|
||||
#define POSTPACK64
|
||||
#else
|
||||
/* 64-bit compilation */
|
||||
#define PREPACK64 PREPACK
|
||||
#define POSTPACK64 POSTPACK
|
||||
#endif
|
||||
140
drivers/net/wireless/ar6003/host/include/bmi.h
Normal file
140
drivers/net/wireless/ar6003/host/include/bmi.h
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <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 "a_types.h"
|
||||
#include "hif.h"
|
||||
#include "a_osapi.h"
|
||||
#include "bmi_msg.h"
|
||||
|
||||
void
|
||||
BMIInit(void);
|
||||
|
||||
void
|
||||
BMICleanup(void);
|
||||
|
||||
A_STATUS
|
||||
BMIDone(HIF_DEVICE *device);
|
||||
|
||||
A_STATUS
|
||||
BMIGetTargetInfo(HIF_DEVICE *device, struct bmi_target_info *targ_info);
|
||||
|
||||
A_STATUS
|
||||
BMIReadMemory(HIF_DEVICE *device,
|
||||
A_UINT32 address,
|
||||
A_UCHAR *buffer,
|
||||
A_UINT32 length);
|
||||
|
||||
A_STATUS
|
||||
BMIWriteMemory(HIF_DEVICE *device,
|
||||
A_UINT32 address,
|
||||
A_UCHAR *buffer,
|
||||
A_UINT32 length);
|
||||
|
||||
A_STATUS
|
||||
BMIExecute(HIF_DEVICE *device,
|
||||
A_UINT32 address,
|
||||
A_UINT32 *param);
|
||||
|
||||
A_STATUS
|
||||
BMISetAppStart(HIF_DEVICE *device,
|
||||
A_UINT32 address);
|
||||
|
||||
A_STATUS
|
||||
BMIReadSOCRegister(HIF_DEVICE *device,
|
||||
A_UINT32 address,
|
||||
A_UINT32 *param);
|
||||
|
||||
A_STATUS
|
||||
BMIWriteSOCRegister(HIF_DEVICE *device,
|
||||
A_UINT32 address,
|
||||
A_UINT32 param);
|
||||
|
||||
A_STATUS
|
||||
BMIrompatchInstall(HIF_DEVICE *device,
|
||||
A_UINT32 ROM_addr,
|
||||
A_UINT32 RAM_addr,
|
||||
A_UINT32 nbytes,
|
||||
A_UINT32 do_activate,
|
||||
A_UINT32 *patch_id);
|
||||
|
||||
A_STATUS
|
||||
BMIrompatchUninstall(HIF_DEVICE *device,
|
||||
A_UINT32 rompatch_id);
|
||||
|
||||
A_STATUS
|
||||
BMIrompatchActivate(HIF_DEVICE *device,
|
||||
A_UINT32 rompatch_count,
|
||||
A_UINT32 *rompatch_list);
|
||||
|
||||
A_STATUS
|
||||
BMIrompatchDeactivate(HIF_DEVICE *device,
|
||||
A_UINT32 rompatch_count,
|
||||
A_UINT32 *rompatch_list);
|
||||
|
||||
A_STATUS
|
||||
BMILZStreamStart(HIF_DEVICE *device,
|
||||
A_UINT32 address);
|
||||
|
||||
A_STATUS
|
||||
BMILZData(HIF_DEVICE *device,
|
||||
A_UCHAR *buffer,
|
||||
A_UINT32 length);
|
||||
|
||||
A_STATUS
|
||||
BMIFastDownload(HIF_DEVICE *device,
|
||||
A_UINT32 address,
|
||||
A_UCHAR *buffer,
|
||||
A_UINT32 length);
|
||||
|
||||
A_STATUS
|
||||
BMInvramProcess(HIF_DEVICE *device,
|
||||
A_UCHAR *seg_name,
|
||||
A_UINT32 *retval);
|
||||
|
||||
A_STATUS
|
||||
BMIRawWrite(HIF_DEVICE *device,
|
||||
A_UCHAR *buffer,
|
||||
A_UINT32 length);
|
||||
|
||||
A_STATUS
|
||||
BMIRawRead(HIF_DEVICE *device,
|
||||
A_UCHAR *buffer,
|
||||
A_UINT32 length,
|
||||
A_BOOL want_timeout);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _BMI_H_ */
|
||||
107
drivers/net/wireless/ar6003/host/include/common_drv.h
Normal file
107
drivers/net/wireless/ar6003/host/include/common_drv.h
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// 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 */
|
||||
typedef 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 */
|
||||
HTC_ENDPOINT_CREDIT_DIST *pLowestPriEpDist; /* pointer to the lowest priority endpoint dist struct */
|
||||
} COMMON_CREDIT_STATE_INFO;
|
||||
|
||||
typedef struct {
|
||||
A_INT32 (*setupTransport)(void *ar);
|
||||
void (*cleanupTransport)(void *ar);
|
||||
} HCI_TRANSPORT_CALLBACKS;
|
||||
|
||||
typedef struct {
|
||||
void *netDevice;
|
||||
void *hifDevice;
|
||||
void *htcHandle;
|
||||
} HCI_TRANSPORT_MISC_HANDLES;
|
||||
|
||||
/* 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_REV2 0x20000188
|
||||
#define AR6003_VERSION_REV2 0x30000384
|
||||
|
||||
#define AR6002_CUST_DATA_SIZE 112
|
||||
#define AR6003_CUST_DATA_SIZE 16
|
||||
#define MCKINLEY_CUST_DATA_SIZE 16
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* OS-independent APIs */
|
||||
A_STATUS ar6000_setup_credit_dist(HTC_HANDLE HTCHandle, COMMON_CREDIT_STATE_INFO *pCredInfo);
|
||||
|
||||
A_STATUS ar6000_ReadRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data);
|
||||
|
||||
A_STATUS ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data);
|
||||
|
||||
A_STATUS ar6000_ReadDataDiag(HIF_DEVICE *hifDevice, A_UINT32 address, A_UCHAR *data, A_UINT32 length);
|
||||
|
||||
A_STATUS ar6000_reset_device(HIF_DEVICE *hifDevice, A_UINT32 TargetType, A_BOOL waitForCompletion, A_BOOL coldReset);
|
||||
|
||||
void ar6000_dump_target_assert_info(HIF_DEVICE *hifDevice, A_UINT32 TargetType);
|
||||
|
||||
A_STATUS ar6000_set_htc_params(HIF_DEVICE *hifDevice,
|
||||
A_UINT32 TargetType,
|
||||
A_UINT32 MboxIsrYieldValue,
|
||||
A_UINT8 HtcControlBuffers);
|
||||
|
||||
A_STATUS ar6000_prepare_target(HIF_DEVICE *hifDevice,
|
||||
A_UINT32 TargetType,
|
||||
A_UINT32 TargetVersion);
|
||||
|
||||
A_STATUS ar6000_set_hci_bridge_flags(HIF_DEVICE *hifDevice,
|
||||
A_UINT32 TargetType,
|
||||
A_UINT32 Flags);
|
||||
|
||||
void ar6000_copy_cust_data_from_target(HIF_DEVICE *hifDevice, A_UINT32 TargetType);
|
||||
|
||||
A_UINT8 *ar6000_get_cust_data_buffer(A_UINT32 TargetType);
|
||||
|
||||
A_STATUS ar6000_setBTState(void *context, A_UINT8 *pInBuf, A_UINT32 InBufSize);
|
||||
|
||||
A_STATUS ar6000_setDevicePowerState(void *context, A_UINT8 *pInBuf, A_UINT32 InBufSize);
|
||||
|
||||
A_STATUS ar6000_setWowMode(void *context, A_UINT8 *pInBuf, A_UINT32 InBufSize);
|
||||
|
||||
A_STATUS ar6000_setHostMode(void *context, A_UINT8 *pInBuf, A_UINT32 InBufSize);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*COMMON_DRV_H_*/
|
||||
58
drivers/net/wireless/ar6003/host/include/dbglog_api.h
Normal file
58
drivers/net/wireless/ar6003/host/include/dbglog_api.h
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <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)
|
||||
|
||||
/**
|
||||
@param lv 0->RAW info, 1->Breif translated info, 2->Full info
|
||||
@param logbuf dbglog buffer
|
||||
*/
|
||||
int dbg_formater(int lv, char *output, size_t len, A_UINT32 ts, A_INT32 *logbuf);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _DBGLOG_API_H_ */
|
||||
387
drivers/net/wireless/ar6003/host/include/dfs_host.h
Normal file
387
drivers/net/wireless/ar6003/host/include/dfs_host.h
Normal file
|
|
@ -0,0 +1,387 @@
|
|||
/*
|
||||
* Copyright (c) 2005-2006 Atheros Communications, Inc.
|
||||
*
|
||||
* 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 _DFS_HOST_H_
|
||||
#define _DFS_HOST_H_
|
||||
|
||||
#ifdef ATH_SUPPORT_DFS
|
||||
|
||||
#include "dfs_host_project.h"
|
||||
|
||||
#define DFS_MIN(a,b) ((a)<(b)?(a):(b))
|
||||
#define DFS_MAX(a,b) ((a)>(b)?(a):(b))
|
||||
#define DFS_DIFF(a,b) (DFS_MAX(a,b) - DFS_MIN(a,b))
|
||||
/*
|
||||
* Maximum number of radar events to be processed in a single iteration.
|
||||
* Allows soft watchdog to run.
|
||||
*/
|
||||
#define MAX_EVENTS 100
|
||||
|
||||
|
||||
#define DFS_MARGIN_EQUAL(a, b, margin) ((DFS_DIFF(a,b)) <= margin)
|
||||
#define DFS_MAX_STAGGERED_BURSTS 3
|
||||
|
||||
/* All filter thresholds in the radar filter tables are effective at a 50% channel loading */
|
||||
#define DFS_CHAN_LOADING_THRESH 50
|
||||
#define DFS_EXT_CHAN_LOADING_THRESH 30
|
||||
#define DFS_DEFAULT_PRI_MARGIN 10
|
||||
#define DFS_DEFAULT_FIXEDPATTERN_PRI_MARGIN 6
|
||||
|
||||
|
||||
#define ATH_DFSQ_LOCK(_dfs) spin_lock(&(_dfs)->dfs_radarqlock)
|
||||
#define ATH_DFSQ_UNLOCK(_dfs) spin_unlock(&(_dfs)->dfs_radarqlock)
|
||||
#define ATH_DFSQ_LOCK_INIT(_dfs) spin_lock_init(&(_dfs)->dfs_radarqlock)
|
||||
|
||||
#define ATH_ARQ_LOCK(_dfs) spin_lock(&(_dfs)->dfs_arqlock)
|
||||
#define ATH_ARQ_UNLOCK(_dfs) spin_unlock(&(_dfs)->dfs_arqlock)
|
||||
#define ATH_ARQ_LOCK_INIT(_dfs) spin_lock_init(&(_dfs)->dfs_arqlock)
|
||||
|
||||
#define ATH_DFSEVENTQ_LOCK(_dfs) spin_lock(&(_dfs)->dfs_eventqlock)
|
||||
#define ATH_DFSEVENTQ_UNLOCK(_dfs) spin_unlock(&(_dfs)->dfs_eventqlock)
|
||||
#define ATH_DFSEVENTQ_LOCK_INIT(_dfs) spin_lock_init(&(_dfs)->dfs_eventqlock)
|
||||
|
||||
|
||||
#define DFS_TSMASK 0xFFFFFFFF /* Mask for time stamp from descriptor */
|
||||
#define DFS_TSSHIFT 32 /* Shift for time stamp from descriptor */
|
||||
#define DFS_TSF_WRAP 0xFFFFFFFFFFFFFFFFULL /* 64 bit TSF wrap value */
|
||||
#define DFS_64BIT_TSFMASK 0x0000000000007FFFULL /* TS mask for 64 bit value */
|
||||
|
||||
|
||||
#define DFS_AR_RADAR_RSSI_THR 5 /* in dB */
|
||||
#define DFS_AR_RADAR_RESET_INT 1 /* in secs */
|
||||
#define DFS_AR_RADAR_MAX_HISTORY 500
|
||||
#define DFS_AR_REGION_WIDTH 128
|
||||
#define DFS_AR_RSSI_THRESH_STRONG_PKTS 17 /* in dB */
|
||||
#define DFS_AR_RSSI_DOUBLE_THRESHOLD 15 /* in dB */
|
||||
#define DFS_AR_MAX_NUM_ACK_REGIONS 9
|
||||
#define DFS_AR_ACK_DETECT_PAR_THRESH 20
|
||||
#define DFS_AR_PKT_COUNT_THRESH 20
|
||||
|
||||
#define DFS_MAX_DL_MASK 0x3F
|
||||
|
||||
#define DFS_NOL_TIME 30*60*1000000 /* 30 minutes in usecs */
|
||||
|
||||
#define DFS_WAIT_TIME 60*1000000 /* 1 minute in usecs */
|
||||
|
||||
#define DFS_DISABLE_TIME 3*60*1000000 /* 3 minutes in usecs */
|
||||
|
||||
#define DFS_MAX_B5_SIZE 128
|
||||
#define DFS_MAX_B5_MASK 0x0000007F /* 128 */
|
||||
|
||||
#define DFS_MAX_RADAR_OVERLAP 16 /* Max number of overlapping filters */
|
||||
|
||||
#define DFS_MAX_EVENTS 1024 /* Max number of dfs events which can be q'd */
|
||||
|
||||
#define DFS_RADAR_EN 0x80000000 /* Radar detect is capable */
|
||||
#define DFS_AR_EN 0x40000000 /* AR detect is capable */
|
||||
#define DFS_MAX_RSSI_VALUE 0x7fffffff /* Max rssi value */
|
||||
|
||||
#define DFS_BIN_MAX_PULSES 60 /* max num of pulses in a burst */
|
||||
#define DFS_BIN5_PRI_LOWER_LIMIT 990 /* us */
|
||||
#define DFS_BIN5_PRI_HIGHER_LIMIT 2010 /* us */
|
||||
#define DFS_BIN5_WIDTH_MARGIN 4 /* us */
|
||||
#define DFS_BIN5_RSSI_MARGIN 5 /* dBm */
|
||||
/*Following threshold is not specified but should be okay statistically*/
|
||||
#define DFS_BIN5_BRI_LOWER_LIMIT 300000 /* us */
|
||||
|
||||
#define DFS_MAX_PULSE_BUFFER_SIZE 1024 /* Max number of pulses kept in buffer */
|
||||
#define DFS_MAX_PULSE_BUFFER_MASK 0x3ff
|
||||
|
||||
#define DFS_FAST_CLOCK_MULTIPLIER (800/11)
|
||||
#define DFS_NO_FAST_CLOCK_MULTIPLIER (80)
|
||||
|
||||
typedef spinlock_t dfsq_lock_t;
|
||||
|
||||
struct dfs_pulse {
|
||||
A_UINT32 rp_numpulses; /* Num of pulses in radar burst */
|
||||
A_UINT32 rp_pulsedur; /* Duration of each pulse in usecs */
|
||||
A_UINT32 rp_pulsefreq; /* Frequency of pulses in burst */
|
||||
A_UINT32 rp_max_pulsefreq; /* Frequency of pulses in burst */
|
||||
A_UINT32 rp_patterntype; /*fixed or variable pattern type*/
|
||||
A_UINT32 rp_pulsevar; /* Time variation of pulse duration for
|
||||
matched filter (single-sided) in usecs */
|
||||
A_UINT32 rp_threshold; /* Thershold for MF output to indicate
|
||||
radar match */
|
||||
A_UINT32 rp_mindur; /* Min pulse duration to be considered for
|
||||
this pulse type */
|
||||
A_UINT32 rp_maxdur; /* Max pusle duration to be considered for
|
||||
this pulse type */
|
||||
A_UINT32 rp_rssithresh; /* Minimum rssi to be considered a radar pulse */
|
||||
A_UINT32 rp_meanoffset; /* Offset for timing adjustment */
|
||||
A_INT32 rp_rssimargin; /* rssi threshold margin. In Turbo Mode HW reports rssi 3dBm
|
||||
* lower than in non TURBO mode. This will be used to offset
|
||||
* that diff.*/
|
||||
A_UINT32 rp_pulseid; /* Unique ID for identifying filter */
|
||||
|
||||
};
|
||||
|
||||
struct dfs_bin5pulse {
|
||||
A_UINT32 b5_threshold; /* Number of bin5 pulses to indicate detection */
|
||||
A_UINT32 b5_mindur; /* Min duration for a bin5 pulse */
|
||||
A_UINT32 b5_maxdur; /* Max duration for a bin5 pulse */
|
||||
A_UINT32 b5_timewindow; /* Window over which to count bin5 pulses */
|
||||
A_UINT32 b5_rssithresh; /* Min rssi to be considered a pulse */
|
||||
A_UINT32 b5_rssimargin; /* rssi threshold margin. In Turbo Mode HW reports rssi 3dB */
|
||||
};
|
||||
|
||||
|
||||
#define DFS_MAX_DL_SIZE 64
|
||||
#include "athstartpack.h"
|
||||
PREPACK struct dfs_delayelem {
|
||||
u_int32_t de_time; /* Current "filter" time for start of pulse in usecs*/
|
||||
u_int8_t de_dur; /* Duration of pulse in usecs*/
|
||||
u_int8_t de_rssi; /* rssi of pulse in dB*/
|
||||
} POSTPACK adf_os_packed;
|
||||
|
||||
/* NB: The first element in the circular buffer is the oldest element */
|
||||
|
||||
PREPACK struct dfs_delayline {
|
||||
struct dfs_delayelem dl_elems[DFS_MAX_DL_SIZE]; /* Array of pulses in delay line */
|
||||
u_int64_t dl_last_ts; /* Last timestamp the delay line was used (in usecs) */
|
||||
u_int32_t dl_firstelem; /* Index of the first element */
|
||||
u_int32_t dl_lastelem; /* Index of the last element */
|
||||
u_int32_t dl_numelems; /* Number of elements in the delay line */
|
||||
} POSTPACK adf_os_packed;
|
||||
|
||||
|
||||
PREPACK struct dfs_filter {
|
||||
struct dfs_delayline rf_dl; /* Delay line of pulses for this filter */
|
||||
u_int32_t rf_numpulses; /* Number of pulses in the filter */
|
||||
u_int32_t rf_minpri; /* min pri to be considered for this filter*/
|
||||
u_int32_t rf_maxpri; /* max pri to be considered for this filter*/
|
||||
u_int32_t rf_threshold; /* match filter output threshold for radar detect */
|
||||
u_int32_t rf_filterlen; /* Length (in usecs) of the filter */
|
||||
u_int32_t rf_patterntype; /* fixed or variable pattern type */
|
||||
u_int32_t rf_mindur; /* Min duration for this radar filter */
|
||||
u_int32_t rf_maxdur; /* Max duration for this radar filter */
|
||||
u_int32_t rf_pulseid; /* Unique ID corresponding to the original filter ID */
|
||||
} POSTPACK adf_os_packed;
|
||||
|
||||
|
||||
|
||||
PREPACK struct dfs_pulseparams {
|
||||
u_int64_t p_time; /* time for start of pulse in usecs*/
|
||||
u_int8_t p_dur; /* Duration of pulse in usecs*/
|
||||
u_int8_t p_rssi; /* Duration of pulse in usecs*/
|
||||
} POSTPACK adf_os_packed;
|
||||
|
||||
PREPACK struct dfs_pulseline {
|
||||
/* pl_elems - array of pulses in delay line */
|
||||
struct dfs_pulseparams pl_elems[DFS_MAX_PULSE_BUFFER_SIZE];
|
||||
u_int32_t pl_firstelem; /* Index of the first element */
|
||||
u_int32_t pl_lastelem; /* Index of the last element */
|
||||
u_int32_t pl_numelems; /* Number of elements in the delay line */
|
||||
} POSTPACK adf_os_packed;
|
||||
|
||||
PREPACK struct dfs_event {
|
||||
u_int64_t re_full_ts; /* 64-bit full timestamp from interrupt time */
|
||||
u_int32_t re_ts; /* Original 15 bit recv timestamp */
|
||||
u_int32_t re_ext_chan_busy; /* Ext channel busy % */
|
||||
u_int8_t re_rssi; /* rssi of radar event */
|
||||
u_int8_t re_dur; /* duration of radar pulse */
|
||||
u_int8_t re_chanindex; /* Channel of event */
|
||||
u_int8_t re_chanindextype; /* Primary channel or extension channel */
|
||||
STAILQ_ENTRY(dfs_event) re_list; /* List of radar events */
|
||||
} POSTPACK adf_os_packed;
|
||||
#include "athendpack.h"
|
||||
|
||||
#define DFS_AR_MAX_ACK_RADAR_DUR 511
|
||||
#define DFS_AR_MAX_NUM_PEAKS 3
|
||||
#define DFS_AR_ARQ_SIZE 2048 /* 8K AR events for buffer size */
|
||||
#define DFS_AR_ARQ_SEQSIZE 2049 /* Sequence counter wrap for AR */
|
||||
|
||||
#define DFS_RADARQ_SIZE 512 /* 1K radar events for buffer size */
|
||||
#define DFS_RADARQ_SEQSIZE 513 /* Sequence counter wrap for radar */
|
||||
#define DFS_NUM_RADAR_STATES 64 /* Number of radar channels we keep state for */
|
||||
#define DFS_MAX_NUM_RADAR_FILTERS 10 /* Max number radar filters for each type */
|
||||
#define DFS_MAX_RADAR_TYPES 32 /* Number of different radar types */
|
||||
|
||||
struct dfs_ar_state {
|
||||
u_int32_t ar_prevwidth;
|
||||
u_int32_t ar_phyerrcount[DFS_AR_MAX_ACK_RADAR_DUR];
|
||||
u_int32_t ar_acksum;
|
||||
u_int32_t ar_packetthreshold; /* Thresh to determine traffic load */
|
||||
u_int32_t ar_parthreshold; /* Thresh to determine peak */
|
||||
u_int32_t ar_radarrssi; /* Rssi threshold for AR event */
|
||||
u_int16_t ar_prevtimestamp;
|
||||
u_int16_t ar_peaklist[DFS_AR_MAX_NUM_PEAKS];
|
||||
};
|
||||
|
||||
struct dfs_filtertype {
|
||||
struct dfs_filter ft_filters[DFS_MAX_NUM_RADAR_FILTERS];
|
||||
u_int32_t ft_filterdur; /* Duration of pulse which specifies filter type*/
|
||||
u_int32_t ft_numfilters; /* Num filters of this type */
|
||||
u_int64_t ft_last_ts; /* Last timestamp this filtertype was used
|
||||
* (in usecs) */
|
||||
u_int32_t ft_mindur; /* min pulse duration to be considered
|
||||
* for this filter type */
|
||||
u_int32_t ft_maxdur; /* max pulse duration to be considered
|
||||
* for this filter type */
|
||||
u_int32_t ft_rssithresh; /* min rssi to be considered
|
||||
* for this filter type */
|
||||
u_int32_t ft_numpulses; /* Num pulses in each filter of this type */
|
||||
u_int32_t ft_patterntype; /* fixed or variable pattern type */
|
||||
u_int32_t ft_minpri; /* min pri to be considered for this type */
|
||||
u_int32_t ft_rssimargin; /* rssi threshold margin. In Turbo Mode HW
|
||||
* reports rssi 3dB lower than in non TURBO
|
||||
* mode. This will offset that diff. */
|
||||
};
|
||||
|
||||
|
||||
#define DFS_NOL_TIMEOUT_S (30*60) /* 30 minutes in seconds */
|
||||
#define DFS_NOL_TIMEOUT_MS (DFS_NOL_TIMEOUT_S * 1000)
|
||||
#define DFS_NOL_TIMEOUT_US (DFS_NOL_TIMEOUT_MS * 1000)
|
||||
|
||||
#include "athstartpack.h"
|
||||
PREPACK struct dfs_info_host {
|
||||
u_int32_t rn_numradars; /* Number of different types of radars */
|
||||
u_int64_t rn_lastfull_ts; /* Last 64 bit timstamp from recv interrupt */
|
||||
u_int16_t rn_last_ts; /* last 15 bit ts from recv descriptor */
|
||||
u_int32_t rn_last_unique_ts; /* last unique 32 bit ts from recv descriptor */
|
||||
u_int64_t rn_ts_prefix; /* Prefix to prepend to 15 bit recv ts */
|
||||
u_int32_t rn_numbin5radars; /* Number of bin5 radar pulses to search for */
|
||||
u_int64_t dfs_bin5_chirp_ts;
|
||||
u_int8_t dfs_last_bin5_dur;
|
||||
} POSTPACK adf_os_packed;
|
||||
#include "athendpack.h"
|
||||
|
||||
struct dfs_bin5elem {
|
||||
u_int64_t be_ts; /* Timestamp for the bin5 element */
|
||||
u_int32_t be_rssi; /* Rssi for the bin5 element */
|
||||
u_int32_t be_dur; /* Duration of bin5 element */
|
||||
};
|
||||
|
||||
struct dfs_bin5radars {
|
||||
struct dfs_bin5elem br_elems[DFS_MAX_B5_SIZE]; /* List of bin5 elems that fall
|
||||
* within the time window */
|
||||
u_int32_t br_firstelem; /* Index of the first element */
|
||||
u_int32_t br_lastelem; /* Index of the last element */
|
||||
u_int32_t br_numelems; /* Number of elements in the delay line */
|
||||
struct dfs_bin5pulse br_pulse; /* Original info about bin5 pulse */
|
||||
};
|
||||
|
||||
|
||||
#define ATH_DFS_RESET_TIME_S 7
|
||||
#define ATH_DFS_WAIT (60 + ATH_DFS_RESET_TIME_S) /* 60 seconds */
|
||||
#define ATH_DFS_WAIT_MS ((ATH_DFS_WAIT) * 1000) /*in MS*/
|
||||
|
||||
#define ATH_DFS_WEATHER_CHANNEL_WAIT_MIN 10 /*10 minutes*/
|
||||
#define ATH_DFS_WEATHER_CHANNEL_WAIT_S (ATH_DFS_WEATHER_CHANNEL_WAIT_MIN * 60)
|
||||
#define ATH_DFS_WEATHER_CHANNEL_WAIT_MS ((ATH_DFS_WEATHER_CHANNEL_WAIT_S) * 1000) /*in MS*/
|
||||
|
||||
#define ATH_DFS_WAIT_POLL_PERIOD 2 /* 2 seconds */
|
||||
#define ATH_DFS_WAIT_POLL_PERIOD_MS ((ATH_DFS_WAIT_POLL_PERIOD) * 1000) /*in MS*/
|
||||
#define ATH_DFS_TEST_RETURN_PERIOD 2 /* 2 seconds */
|
||||
#define ATH_DFS_TEST_RETURN_PERIOD_MS ((ATH_DFS_TEST_RETURN_PERIOD) * 1000)/* n MS*/
|
||||
|
||||
#define IS_CHANNEL_WEATHER_RADAR(chan) ((chan->channel >= 5600) && (chan->channel <= 5650))
|
||||
|
||||
#define DFS_DEBUG_TIMEOUT_S 30 // debug timeout is 30 seconds
|
||||
#define DFS_DEBUG_TIMEOUT_MS (DFS_DEBUG_TIMEOUT_S * 1000)
|
||||
struct ath_dfs_host {
|
||||
DEV_HDL dev_hdl;
|
||||
u_int32_t dfs_debug_level;
|
||||
OS_HDL os_hdl;
|
||||
STAILQ_HEAD(,dfs_event) dfs_eventq; /* Q of free dfs event objects */
|
||||
dfsq_lock_t dfs_eventqlock; /* Lock for free dfs event list */
|
||||
STAILQ_HEAD(,dfs_event) dfs_radarq; /* Q of radar events */
|
||||
dfsq_lock_t dfs_radarqlock; /* Lock for dfs q */
|
||||
STAILQ_HEAD(,dfs_event) dfs_arq; /* Q of AR events */
|
||||
dfsq_lock_t dfs_arqlock; /* Lock for AR q */
|
||||
|
||||
struct dfs_pulseline *pulses; /* pulse history */
|
||||
struct dfs_event *events; /* Events structure */
|
||||
/* dfs_radarf - One filter for each radar pulse type */
|
||||
struct dfs_filtertype *dfs_radarf[DFS_MAX_RADAR_TYPES];
|
||||
|
||||
int8_t **dfs_radartable; /* map of radar durs to filter types */
|
||||
struct dfs_bin5radars *dfs_b5radars;/* array of bin5 radar events */
|
||||
struct dfs_ar_state dfs_ar_state; /* AR state */
|
||||
struct dfs_info_host dfs_rinfo; /* State vars for radar processing */
|
||||
u_int8_t dfs_bangradar;
|
||||
u_int32_t dur_multiplier;
|
||||
A_TIMER dfs_radar_task_timer;
|
||||
};
|
||||
|
||||
|
||||
#define HAL_CAP_RADAR 0
|
||||
#define HAL_CAP_AR 1
|
||||
#define HAL_CAP_STRONG_DIV 2
|
||||
|
||||
|
||||
/* Attach, detach, handle ioctl prototypes */
|
||||
struct ath_dfs_host *dfs_attach_host(DEV_HDL dev, OS_HDL os, ATH_DFS_CAPINFO *cap_info);
|
||||
void dfs_detach_host(struct ath_dfs_host *sc);
|
||||
|
||||
|
||||
/* PHY error and radar event handling */
|
||||
void dfs_process_phyerr_host(struct ath_dfs_host *dfs, WMI_DFS_PHYERR_EVENT *ev);
|
||||
int dfs_process_radarevent_host(struct ath_dfs_host *dfs, int16_t *chan_index, u_int8_t *bangradar);
|
||||
|
||||
|
||||
/* FCC Bin5 detection prototypes */
|
||||
int dfs_bin5_addpulse(struct ath_dfs_host *sc, struct dfs_bin5radars *br,
|
||||
struct dfs_event *re, u_int64_t thists);
|
||||
int dfs_bin5_check(struct ath_dfs_host *dfs);
|
||||
u_int8_t dfs_retain_bin5_burst_pattern(struct ath_dfs_host *dfs, u_int32_t diff_ts, u_int8_t old_dur);
|
||||
|
||||
/* Debug prototypes */
|
||||
void dfs_print_delayline(struct ath_dfs_host *dfs, struct dfs_delayline *dl);
|
||||
void dfs_print_filters(struct ath_dfs_host *dfs);
|
||||
void dfs_print_filter(struct ath_dfs_host *dfs, struct dfs_filter *rf);
|
||||
|
||||
/* Misc prototypes */
|
||||
u_int32_t dfs_round(int32_t val);
|
||||
|
||||
/* Reset and init data structures */
|
||||
|
||||
int dfs_init_radar_filters_host(struct ath_dfs_host *dfs, struct ath_dfs_info *dfs_info);
|
||||
void dfs_reset_alldelaylines(struct ath_dfs_host *dfs);
|
||||
void dfs_reset_delayline(struct dfs_delayline *dl);
|
||||
void dfs_reset_filter_delaylines(struct dfs_filtertype *dft);
|
||||
void dfs_reset_radarq(struct ath_dfs_host *dfs);
|
||||
|
||||
/* Detection algorithm prototypes */
|
||||
void dfs_add_pulse(struct ath_dfs_host *dfs, struct dfs_filter *rf,
|
||||
struct dfs_event *re, u_int32_t deltaT);
|
||||
|
||||
int dfs_bin_fixedpattern_check(struct ath_dfs_host *dfs, struct dfs_filter *rf, u_int32_t dur, int ext_chan_flag, u_int32_t ext_chan_busy);
|
||||
int dfs_bin_check(struct ath_dfs_host *dfs, struct dfs_filter *rf,
|
||||
u_int32_t deltaT, u_int32_t dur, int ext_chan_flag, u_int32_t ext_chan_busy);
|
||||
|
||||
|
||||
int dfs_bin_pri_check(struct ath_dfs_host *dfs, struct dfs_filter *rf,
|
||||
struct dfs_delayline *dl, u_int32_t score,
|
||||
u_int32_t refpri, u_int32_t refdur, int ext_chan_flag, u_int32_t ext_chan_busy);
|
||||
int dfs_staggered_check(struct ath_dfs_host *dfs, struct dfs_filter *rf,
|
||||
u_int32_t deltaT, u_int32_t width, u_int32_t ext_chan_busy);
|
||||
|
||||
/* AR related prototypes */
|
||||
u_int32_t dfs_process_ar_event(struct ath_dfs_host *dfs);
|
||||
void dfs_reset_ar(struct ath_dfs_host *dfs);
|
||||
void dfs_reset_arq(struct ath_dfs_host *dfs);
|
||||
|
||||
void dfs_bangradar_enable(struct ath_dfs_host *dfs, u_int8_t enable);
|
||||
void dfs_set_dur_multiplier(struct ath_dfs_host *dfs, u_int32_t dur_multiplier);
|
||||
void dfs_set_debug_level_host(struct ath_dfs_host *dfs, u_int32_t level);
|
||||
|
||||
/* False detection reduction */
|
||||
int dfs_get_pri_margin(int is_extchan_detect, int is_fixed_pattern, u_int64_t lastfull_ts, u_int32_t ext_chan_busy);
|
||||
int dfs_get_filter_threshold(struct dfs_filter *rf, int is_extchan_detect, u_int64_t lastfull_ts, u_int32_t ext_chan_busy);
|
||||
|
||||
#endif /* ATH_SUPPORT_DFS */
|
||||
#endif /* _DFS_H_ */
|
||||
57
drivers/net/wireless/ar6003/host/include/dfs_host_project.h
Normal file
57
drivers/net/wireless/ar6003/host/include/dfs_host_project.h
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (c) 2005-2006 Atheros Communications, Inc.
|
||||
*
|
||||
* 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 _DFS_PROJECT_H_
|
||||
#define _DFS_PROJECT_H_
|
||||
|
||||
#ifdef ATH_SUPPORT_DFS
|
||||
|
||||
#include <a_config.h>
|
||||
#include <athdefs.h>
|
||||
#include <a_types.h>
|
||||
#include <a_osapi.h>
|
||||
#include <a_debug.h>
|
||||
#include <queue.h> /* XXX: This is in target dir */
|
||||
#include "dfs_common.h"
|
||||
#include "ar6000_drv.h"
|
||||
#include "project.h"
|
||||
|
||||
#define ATH_DFS_CAPINFO WMI_DFS_HOST_ATTACH_EVENT
|
||||
|
||||
#define OS_HDL void *
|
||||
#define DEV_HDL void *
|
||||
|
||||
#define DFS_MALLOC(os_hdl, nbytes) A_MALLOC(nbytes)
|
||||
|
||||
#define DFS_DPRINTK(pDfs, _m, _fmt, ...) do { \
|
||||
if ((_m) <= pDfs->dfs_debug_level) { \
|
||||
A_PRINTF(_fmt, __VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
void dfs_radar_task (unsigned long arg);
|
||||
|
||||
#define adf_os_packed
|
||||
|
||||
typedef enum {
|
||||
AH_FALSE = 0, /* NB: lots of code assumes false is zero */
|
||||
AH_TRUE = 1,
|
||||
} HAL_BOOL;
|
||||
#endif /* ATH_SUPPORT_DFS */
|
||||
|
||||
#endif /* _DFS_PROJECT_H_ */
|
||||
153
drivers/net/wireless/ar6003/host/include/dl_list.h
Normal file
153
drivers/net/wireless/ar6003/host/include/dl_list.h
Normal file
|
|
@ -0,0 +1,153 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <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 */
|
||||
typedef struct _DL_LIST {
|
||||
struct _DL_LIST *pPrev;
|
||||
struct _DL_LIST *pNext;
|
||||
}DL_LIST, *PDL_LIST;
|
||||
/*
|
||||
* 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) \
|
||||
{ \
|
||||
PDL_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 PDL_LIST DL_ListInsertTail(PDL_LIST pList, PDL_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 PDL_LIST DL_ListInsertHead(PDL_LIST pList, PDL_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 PDL_LIST DL_ListRemove(PDL_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 PDL_LIST DL_ListRemoveItemFromHead(PDL_LIST pList) {
|
||||
PDL_LIST pItem = NULL;
|
||||
if (pList->pNext != pList) {
|
||||
pItem = pList->pNext;
|
||||
/* remove the first item from head */
|
||||
DL_ListRemove(pItem);
|
||||
}
|
||||
return pItem;
|
||||
}
|
||||
|
||||
static INLINE PDL_LIST DL_ListRemoveItemFromTail(PDL_LIST pList) {
|
||||
PDL_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(PDL_LIST pDest, PDL_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___ */
|
||||
65
drivers/net/wireless/ar6003/host/include/dset_api.h
Normal file
65
drivers/net/wireless/ar6003/host/include/dset_api.h
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <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. */
|
||||
A_STATUS wmi_dset_open_reply(struct wmi_t *wmip,
|
||||
A_UINT32 status,
|
||||
A_UINT32 access_cookie,
|
||||
A_UINT32 size,
|
||||
A_UINT32 version,
|
||||
A_UINT32 targ_handle,
|
||||
A_UINT32 targ_reply_fn,
|
||||
A_UINT32 targ_reply_arg);
|
||||
|
||||
/* Called to send a DataSet Data Reply back to the Target. */
|
||||
A_STATUS wmi_dset_data_reply(struct wmi_t *wmip,
|
||||
A_UINT32 status,
|
||||
A_UINT8 *host_buf,
|
||||
A_UINT32 length,
|
||||
A_UINT32 targ_buf,
|
||||
A_UINT32 targ_reply_fn,
|
||||
A_UINT32 targ_reply_arg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
#endif /* _DSET_API_H_ */
|
||||
59
drivers/net/wireless/ar6003/host/include/gpio_api.h
Normal file
59
drivers/net/wireless/ar6003/host/include/gpio_api.h
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <copyright file="gpio_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 General Purpose I/O API.
|
||||
//
|
||||
// Author(s): ="Atheros"
|
||||
//==============================================================================
|
||||
#ifndef _GPIO_API_H_
|
||||
#define _GPIO_API_H_
|
||||
|
||||
/*
|
||||
* Send a command to the Target in order to change output on GPIO pins.
|
||||
*/
|
||||
A_STATUS wmi_gpio_output_set(struct wmi_t *wmip,
|
||||
A_UINT32 set_mask,
|
||||
A_UINT32 clear_mask,
|
||||
A_UINT32 enable_mask,
|
||||
A_UINT32 disable_mask);
|
||||
|
||||
/*
|
||||
* Send a command to the Target requesting input state of GPIO pins.
|
||||
*/
|
||||
A_STATUS wmi_gpio_input_get(struct wmi_t *wmip);
|
||||
|
||||
/*
|
||||
* Send a command to the Target to change the value of a GPIO register.
|
||||
*/
|
||||
A_STATUS wmi_gpio_register_set(struct wmi_t *wmip,
|
||||
A_UINT32 gpioreg_id,
|
||||
A_UINT32 value);
|
||||
|
||||
/*
|
||||
* Send a command to the Target to fetch the value of a GPIO register.
|
||||
*/
|
||||
A_STATUS wmi_gpio_register_get(struct wmi_t *wmip, A_UINT32 gpioreg_id);
|
||||
|
||||
/*
|
||||
* Send a command to the Target, acknowledging some GPIO interrupts.
|
||||
*/
|
||||
A_STATUS wmi_gpio_intr_ack(struct wmi_t *wmip, A_UINT32 ack_mask);
|
||||
|
||||
#endif /* _GPIO_API_H_ */
|
||||
259
drivers/net/wireless/ar6003/host/include/hci_transport_api.h
Normal file
259
drivers/net/wireless/ar6003/host/include/hci_transport_api.h
Normal file
|
|
@ -0,0 +1,259 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// 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 *, HTC_PACKET *);
|
||||
/* callback when an HCI packet is received */
|
||||
typedef void (*HCI_TRANSPORT_RECV_PKT)(void *, 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 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 *, HTC_PACKET *);
|
||||
|
||||
typedef struct {
|
||||
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) */
|
||||
} HCI_TRANSPORT_PROPERTIES;
|
||||
|
||||
typedef 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, A_STATUS Status); /* transport failure callback */
|
||||
A_STATUS (*TransportReady)(HCI_TRANSPORT_HANDLE, 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;
|
||||
} HCI_TRANSPORT_CONFIG_INFO;
|
||||
|
||||
/* ------ 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, 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: A_OK 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:
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
||||
A_STATUS HCI_TransportAddReceivePkts(HCI_TRANSPORT_HANDLE HciTrans, 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: A_OK
|
||||
@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:
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
||||
A_STATUS HCI_TransportSendPkt(HCI_TRANSPORT_HANDLE HciTrans, HTC_PACKET *pPacket, A_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: A_OK 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:
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
||||
A_STATUS 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: A_OK on success
|
||||
@notes: This API must be called when HCI recv is handled synchronously
|
||||
@example:
|
||||
@see also:
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
||||
A_STATUS HCI_TransportEnableDisableAsyncRecv(HCI_TRANSPORT_HANDLE HciTrans, A_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: A_OK 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
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
||||
A_STATUS HCI_TransportRecvHCIEventSync(HCI_TRANSPORT_HANDLE HciTrans,
|
||||
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: A_OK on success
|
||||
@notes: This API should be used only after HCI device initialization
|
||||
@example:
|
||||
@see also:
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
||||
A_STATUS HCI_TransportSetBaudRate(HCI_TRANSPORT_HANDLE HciTrans, A_UINT32 Baud);
|
||||
|
||||
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
@desc: Enable/Disable HCI Transport Power Management
|
||||
@function name: HCI_TransportEnablePowerMgmt
|
||||
@input: HciTrans - hci transport handle
|
||||
Enable - 1 = Enable, 0 = Disable
|
||||
@output:
|
||||
@return: A_OK on success
|
||||
@notes:
|
||||
@example:
|
||||
@see also:
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
||||
A_STATUS HCI_TransportEnablePowerMgmt(HCI_TRANSPORT_HANDLE HciTrans, A_BOOL Enable);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _HCI_TRANSPORT_API_H_ */
|
||||
517
drivers/net/wireless/ar6003/host/include/hif.h
Normal file
517
drivers/net/wireless/ar6003/host/include/hif.h
Normal file
|
|
@ -0,0 +1,517 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <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_types.h"
|
||||
#include "a_osapi.h"
|
||||
#include "dl_list.h"
|
||||
|
||||
|
||||
typedef struct htc_callbacks HTC_CALLBACKS;
|
||||
typedef struct hif_device HIF_DEVICE;
|
||||
|
||||
#define HIF_TYPE_AR6002 2
|
||||
#define HIF_TYPE_AR6003 3
|
||||
#define HIF_TYPE_MCKINLEY 5
|
||||
|
||||
/*
|
||||
* 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 A_UINT32s
|
||||
* notes: block size is returned for each mailbox (4)
|
||||
*
|
||||
* HIF_DEVICE_GET_MBOX_ADDR
|
||||
* input : none
|
||||
* output : 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 : 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 : 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 : 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)
|
||||
*
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
A_UINT32 ExtendedAddress; /* extended address for larger writes */
|
||||
A_UINT32 ExtendedSize;
|
||||
} HIF_MBOX_PROPERTIES;
|
||||
|
||||
#define HIF_MBOX_FLAG_NO_BUNDLING (1 << 0) /* do not allow bundling over the mailbox */
|
||||
|
||||
typedef struct {
|
||||
A_UINT32 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 */
|
||||
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 */
|
||||
A_UINT32 GMboxAddress;
|
||||
A_UINT32 GMboxSize;
|
||||
A_UINT32 Flags; /* flags to describe mbox behavior or usage */
|
||||
} HIF_DEVICE_MBOX_INFO;
|
||||
|
||||
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;
|
||||
|
||||
typedef struct {
|
||||
int RecvPacketYieldCount; /* max number of packets to force DSR to return */
|
||||
} HIF_DEVICE_IRQ_YIELD_PARAMS;
|
||||
|
||||
|
||||
typedef struct _HIF_SCATTER_ITEM {
|
||||
A_UINT8 *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 */
|
||||
} HIF_SCATTER_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;
|
||||
|
||||
typedef struct _HIF_SCATTER_REQ {
|
||||
DL_LIST ListLink; /* link management */
|
||||
A_UINT32 Address; /* address for the read/write operation */
|
||||
A_UINT32 Request; /* request flags */
|
||||
A_UINT32 TotalLength; /* total length of entire transfer */
|
||||
A_UINT32 CallerFlags; /* caller specific flags can be stored here */
|
||||
HIF_SCATTER_COMP_CB CompletionRoutine; /* completion routine set by caller */
|
||||
A_STATUS 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 */
|
||||
A_UINT8 *pScatterBounceBuffer; /* bounce buffer for upper layers to copy to/from */
|
||||
HIF_SCATTER_ITEM ScatterList[1]; /* start of scatter list */
|
||||
} HIF_SCATTER_REQ;
|
||||
|
||||
typedef HIF_SCATTER_REQ * ( *HIF_ALLOCATE_SCATTER_REQUEST)(HIF_DEVICE *device);
|
||||
typedef void ( *HIF_FREE_SCATTER_REQUEST)(HIF_DEVICE *device, HIF_SCATTER_REQ *request);
|
||||
typedef A_STATUS ( *HIF_READWRITE_SCATTER)(HIF_DEVICE *device, HIF_SCATTER_REQ *request);
|
||||
|
||||
typedef 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;
|
||||
} HIF_DEVICE_SCATTER_SUPPORT_INFO;
|
||||
|
||||
typedef struct {
|
||||
void *pOSDevice;
|
||||
} HIF_DEVICE_OS_DEVICE_INFO;
|
||||
|
||||
#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 */
|
||||
A_STATUS (* rwCompletionHandler)(void *rwContext, A_STATUS status);
|
||||
A_STATUS (* 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 */
|
||||
A_STATUS (* deviceInsertedHandler)(void *context, void *hif_handle);
|
||||
A_STATUS (* deviceRemovedHandler)(void *claimedContext, void *hif_handle);
|
||||
A_STATUS (* deviceSuspendHandler)(void *context);
|
||||
A_STATUS (* deviceResumeHandler)(void *context);
|
||||
A_STATUS (* deviceWakeupHandler)(void *context);
|
||||
A_STATUS (* 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 */
|
||||
|
||||
typedef struct _HIF_PENDING_EVENTS_INFO {
|
||||
A_UINT32 Events;
|
||||
A_UINT32 LookAhead;
|
||||
A_UINT32 AvailableRecvBytes;
|
||||
} HIF_PENDING_EVENTS_INFO;
|
||||
|
||||
/* function to get pending events , some HIF modules use special mechanisms
|
||||
* to detect packet available and other interrupts */
|
||||
typedef A_STATUS ( *HIF_PENDING_EVENTS_FUNC)(HIF_DEVICE *device,
|
||||
HIF_PENDING_EVENTS_INFO *pEvents,
|
||||
void *AsyncContext);
|
||||
|
||||
#define HIF_MASK_RECV TRUE
|
||||
#define HIF_UNMASK_RECV FALSE
|
||||
/* function to mask recv events */
|
||||
typedef A_STATUS ( *HIF_MASK_UNMASK_RECV_EVENT)(HIF_DEVICE *device,
|
||||
A_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
|
||||
*
|
||||
*/
|
||||
A_STATUS 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(HIF_DEVICE *device, void *claimedContext);
|
||||
/* release the claimed device */
|
||||
void HIFReleaseDevice(HIF_DEVICE *device);
|
||||
|
||||
/* This API allows the HTC layer to attach to the HIF device */
|
||||
A_STATUS HIFAttachHTC(HIF_DEVICE *device, HTC_CALLBACKS *callbacks);
|
||||
/* This API detaches the HTC layer from the HIF device */
|
||||
void HIFDetachHTC(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.
|
||||
*/
|
||||
A_STATUS
|
||||
HIFReadWrite(HIF_DEVICE *device,
|
||||
A_UINT32 address,
|
||||
A_UCHAR *buffer,
|
||||
A_UINT32 length,
|
||||
A_UINT32 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(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(HIF_DEVICE *device);
|
||||
|
||||
void HIFMaskInterrupt(HIF_DEVICE *device);
|
||||
|
||||
void HIFUnMaskInterrupt(HIF_DEVICE *device);
|
||||
|
||||
A_STATUS
|
||||
HIFConfigureDevice(HIF_DEVICE *device, HIF_DEVICE_CONFIG_OPCODE opcode,
|
||||
void *config, A_UINT32 configLen);
|
||||
|
||||
/*
|
||||
* This API wait for the remaining MBOX messages to be drained
|
||||
* This should be moved to HTC AR6K layer
|
||||
*/
|
||||
A_STATUS hifWaitForPendingRecv(HIF_DEVICE *device);
|
||||
|
||||
/****************************************************************/
|
||||
/* message based HIF interfaces */
|
||||
/****************************************************************/
|
||||
|
||||
#define HIF_BMI_EXCHANGE_NO_TIMEOUT ((A_UINT32)(0))
|
||||
|
||||
struct _HIF_MSG_OBJ;
|
||||
|
||||
typedef void (* HIF_MSG_RECV_CALLBACK)(void *, struct _HIF_MSG_OBJ *);
|
||||
typedef void (* HIF_MSG_REQ_COMPLETION)(void *,struct _HIF_MSG_OBJ *);
|
||||
|
||||
typedef enum {
|
||||
HIF_MSG_SIMPLE_BUFFER = 0, /* a simple buffer ptr and length */
|
||||
HIF_MSG_NET_BUFFER = 1 /* advanced OS-specific network buffer */
|
||||
} HIF_MSG_BUFFER_TYPE;
|
||||
|
||||
/* object to pass HIF message requests from upper layers */
|
||||
typedef struct _HIF_MSG_OBJ {
|
||||
DL_LIST ListLink; /* for list management */
|
||||
A_INT32 PipeId; /* pipe number to send on or recv'd from*/
|
||||
HIF_MSG_BUFFER_TYPE BufferType;
|
||||
union {
|
||||
struct HIF_MSG_NET_BUFFER {
|
||||
void *pAppNetBuf; /* OS-specific net buf */
|
||||
} AsNetBuffer;
|
||||
struct HIF_MSG_SIMPLE_BUFFER {
|
||||
void *pBuffer; /* for future use.... */
|
||||
A_UINT32 Length;
|
||||
} AsSimpleBuffer;
|
||||
} BufferInfo;
|
||||
void *pContext; /* caller context of message */
|
||||
HIF_MSG_REQ_COMPLETION CompletionRoutine; /* completion routine */
|
||||
A_STATUS Status; /* completion status */
|
||||
A_UINT32 Flags; /* request flags */
|
||||
void *HIFPriv[4]; /* private contexts for HIF layer to use */
|
||||
|
||||
} HIF_MSG_OBJ;
|
||||
|
||||
/* API to handle HIF-specific BMI message exchanges, this API is synchronous
|
||||
* and only allowed to be called from a context that can block (sleep) */
|
||||
A_STATUS HIFExchangeBMIMsg(HIF_DEVICE *device,
|
||||
A_UINT8 *pSendMessage,
|
||||
A_UINT32 Length,
|
||||
A_UINT8 *pResponseMessage,
|
||||
A_UINT32 *pResponseLength,
|
||||
A_UINT32 TimeoutMS);
|
||||
|
||||
/* API to handle HIF specific diagnostic window read accesses, this API is synchronous
|
||||
* and only allowed to be called from a context that can block (sleep) */
|
||||
A_STATUS HIFDiagReadAccess(HIF_DEVICE *hifDevice, A_UINT32 address, A_UINT32 *data);
|
||||
|
||||
/* API to handle HIF specific diagnostic window write accesses, this API is synchronous
|
||||
* and only allowed to be called from a context that can block (sleep) */
|
||||
A_STATUS HIFDiagWriteAccess(HIF_DEVICE *hifDevice, A_UINT32 address, A_UINT32 data);
|
||||
|
||||
/* get the Pipe ID associated with the service ID */
|
||||
A_STATUS HIFGetPipeId(HIF_DEVICE *hifDevice, A_UINT16 ServiceId, A_INT32 *pId);
|
||||
|
||||
/* API to let HIF layer know that pipe communications should be enabled
|
||||
* caller will start to exchange messages on service pipes */
|
||||
A_STATUS HIFEnablePipes(HIF_DEVICE *hifDevice);
|
||||
|
||||
/* set the message recv handler for all incomming messages */
|
||||
void HIFSetMsgRecvHandler(HIF_DEVICE *hifDevice,
|
||||
HIF_MSG_RECV_CALLBACK Callback,
|
||||
void *pContext);
|
||||
|
||||
/* upper layers should return the HIF_MSG_OBJ back to HIF as it may be associated
|
||||
* with some recv resource. The objects could be returned in a chain (batch mode)
|
||||
* Note, upper layers can take ownership of the buffer (free it) if it is of the type
|
||||
* HIF_MSG_NET_BUFFER, in this case upper layers will set
|
||||
* BufferInfo.AsNetBuffer.pAppNetBuf to NULL */
|
||||
void HIFReturnRecvMsgObjects(HIF_DEVICE *hifDevice, HIF_MSG_OBJ *pMessageObj);
|
||||
|
||||
/* API for upper layers to send one or more messages. Note, HIF may
|
||||
* take ownership of the buffer (it will free it) if it is of the type
|
||||
* HIF_MSG_NET_BUFFER, in this case the HIF layer will set
|
||||
* BufferInfo.AsNetBuffer.pAppNetBuf to NULL */
|
||||
A_STATUS HIFSendMessages(HIF_DEVICE *hifDevice, HIF_MSG_OBJ *pMessages);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _HIF_H_ */
|
||||
226
drivers/net/wireless/ar6003/host/include/host_reg_table.h
Normal file
226
drivers/net/wireless/ar6003/host/include/host_reg_table.h
Normal file
|
|
@ -0,0 +1,226 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <copyright file="target_reg_table.h" company="Atheros">
|
||||
// Copyright (c) 2004-2008 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.
|
||||
//
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
//==============================================================================
|
||||
// Target register table macros and structure definitions
|
||||
//
|
||||
// Author(s): ="Atheros"
|
||||
//==============================================================================
|
||||
|
||||
#ifndef HOST_REG_TABLE_H_
|
||||
#define HOST_REG_TABLE_H_
|
||||
|
||||
#include "targaddrs.h"
|
||||
/*** WARNING : Add to the end of the TABLE! do not change the order ****/
|
||||
typedef struct hostdef_s {
|
||||
A_UINT32 d_INT_STATUS_ENABLE_ERROR_LSB;
|
||||
A_UINT32 d_INT_STATUS_ENABLE_ERROR_MASK;
|
||||
A_UINT32 d_INT_STATUS_ENABLE_CPU_LSB;
|
||||
A_UINT32 d_INT_STATUS_ENABLE_CPU_MASK;
|
||||
A_UINT32 d_INT_STATUS_ENABLE_COUNTER_LSB;
|
||||
A_UINT32 d_INT_STATUS_ENABLE_COUNTER_MASK;
|
||||
A_UINT32 d_INT_STATUS_ENABLE_MBOX_DATA_LSB;
|
||||
A_UINT32 d_INT_STATUS_ENABLE_MBOX_DATA_MASK;
|
||||
A_UINT32 d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB;
|
||||
A_UINT32 d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK;
|
||||
A_UINT32 d_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB;
|
||||
A_UINT32 d_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK;
|
||||
A_UINT32 d_COUNTER_INT_STATUS_ENABLE_BIT_LSB;
|
||||
A_UINT32 d_COUNTER_INT_STATUS_ENABLE_BIT_MASK;
|
||||
A_UINT32 d_INT_STATUS_ENABLE_ADDRESS;
|
||||
A_UINT32 d_CPU_INT_STATUS_ENABLE_BIT_LSB;
|
||||
A_UINT32 d_CPU_INT_STATUS_ENABLE_BIT_MASK;
|
||||
A_UINT32 d_HOST_INT_STATUS_ADDRESS;
|
||||
A_UINT32 d_CPU_INT_STATUS_ADDRESS;
|
||||
A_UINT32 d_ERROR_INT_STATUS_ADDRESS;
|
||||
A_UINT32 d_ERROR_INT_STATUS_WAKEUP_MASK;
|
||||
A_UINT32 d_ERROR_INT_STATUS_WAKEUP_LSB;
|
||||
A_UINT32 d_ERROR_INT_STATUS_RX_UNDERFLOW_MASK;
|
||||
A_UINT32 d_ERROR_INT_STATUS_RX_UNDERFLOW_LSB;
|
||||
A_UINT32 d_ERROR_INT_STATUS_TX_OVERFLOW_MASK;
|
||||
A_UINT32 d_ERROR_INT_STATUS_TX_OVERFLOW_LSB;
|
||||
A_UINT32 d_COUNT_DEC_ADDRESS;
|
||||
A_UINT32 d_HOST_INT_STATUS_CPU_MASK;
|
||||
A_UINT32 d_HOST_INT_STATUS_CPU_LSB;
|
||||
A_UINT32 d_HOST_INT_STATUS_ERROR_MASK;
|
||||
A_UINT32 d_HOST_INT_STATUS_ERROR_LSB;
|
||||
A_UINT32 d_HOST_INT_STATUS_COUNTER_MASK;
|
||||
A_UINT32 d_HOST_INT_STATUS_COUNTER_LSB;
|
||||
A_UINT32 d_RX_LOOKAHEAD_VALID_ADDRESS;
|
||||
A_UINT32 d_WINDOW_DATA_ADDRESS;
|
||||
A_UINT32 d_WINDOW_READ_ADDR_ADDRESS;
|
||||
A_UINT32 d_WINDOW_WRITE_ADDR_ADDRESS;
|
||||
} HOST_REGISTER_TABLE;
|
||||
|
||||
#if defined(MY_HOST_DEF) /* { */
|
||||
#if defined(ATHR_WIN_DEF)
|
||||
#define ATH_REG_TABLE_DIRECT_ASSIGN
|
||||
#endif
|
||||
#ifdef ATH_REG_TABLE_DIRECT_ASSIGN
|
||||
|
||||
static struct hostdef_s my_host_def = {
|
||||
INT_STATUS_ENABLE_ERROR_LSB,
|
||||
INT_STATUS_ENABLE_ERROR_MASK,
|
||||
INT_STATUS_ENABLE_CPU_LSB,
|
||||
INT_STATUS_ENABLE_CPU_MASK,
|
||||
INT_STATUS_ENABLE_COUNTER_LSB,
|
||||
INT_STATUS_ENABLE_COUNTER_MASK,
|
||||
INT_STATUS_ENABLE_MBOX_DATA_LSB,
|
||||
INT_STATUS_ENABLE_MBOX_DATA_MASK,
|
||||
ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB,
|
||||
ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK,
|
||||
ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB,
|
||||
ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK,
|
||||
COUNTER_INT_STATUS_ENABLE_BIT_LSB,
|
||||
COUNTER_INT_STATUS_ENABLE_BIT_MASK,
|
||||
INT_STATUS_ENABLE_ADDRESS,
|
||||
CPU_INT_STATUS_ENABLE_BIT_LSB,
|
||||
CPU_INT_STATUS_ENABLE_BIT_MASK,
|
||||
HOST_INT_STATUS_ADDRESS,
|
||||
CPU_INT_STATUS_ADDRESS,
|
||||
ERROR_INT_STATUS_ADDRESS,
|
||||
ERROR_INT_STATUS_WAKEUP_MASK,
|
||||
ERROR_INT_STATUS_WAKEUP_LSB,
|
||||
ERROR_INT_STATUS_RX_UNDERFLOW_MASK,
|
||||
ERROR_INT_STATUS_RX_UNDERFLOW_LSB,
|
||||
ERROR_INT_STATUS_TX_OVERFLOW_MASK,
|
||||
ERROR_INT_STATUS_TX_OVERFLOW_LSB,
|
||||
COUNT_DEC_ADDRESS,
|
||||
HOST_INT_STATUS_CPU_MASK,
|
||||
HOST_INT_STATUS_CPU_LSB,
|
||||
HOST_INT_STATUS_ERROR_MASK,
|
||||
HOST_INT_STATUS_ERROR_LSB,
|
||||
HOST_INT_STATUS_COUNTER_MASK,
|
||||
HOST_INT_STATUS_COUNTER_LSB,
|
||||
RX_LOOKAHEAD_VALID_ADDRESS,
|
||||
WINDOW_DATA_ADDRESS,
|
||||
WINDOW_READ_ADDR_ADDRESS,
|
||||
WINDOW_WRITE_ADDR_ADDRESS,
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
static struct hostdef_s my_host_def = {
|
||||
.d_INT_STATUS_ENABLE_ERROR_LSB = INT_STATUS_ENABLE_ERROR_LSB,
|
||||
.d_INT_STATUS_ENABLE_ERROR_MASK = INT_STATUS_ENABLE_ERROR_MASK,
|
||||
.d_INT_STATUS_ENABLE_CPU_LSB = INT_STATUS_ENABLE_CPU_LSB,
|
||||
.d_INT_STATUS_ENABLE_CPU_MASK = INT_STATUS_ENABLE_CPU_MASK,
|
||||
.d_INT_STATUS_ENABLE_COUNTER_LSB = INT_STATUS_ENABLE_COUNTER_LSB,
|
||||
.d_INT_STATUS_ENABLE_COUNTER_MASK = INT_STATUS_ENABLE_COUNTER_MASK,
|
||||
.d_INT_STATUS_ENABLE_MBOX_DATA_LSB = INT_STATUS_ENABLE_MBOX_DATA_LSB,
|
||||
.d_INT_STATUS_ENABLE_MBOX_DATA_MASK = INT_STATUS_ENABLE_MBOX_DATA_MASK,
|
||||
.d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB = ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB,
|
||||
.d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK = ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK,
|
||||
.d_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB = ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB,
|
||||
.d_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK = ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK,
|
||||
.d_COUNTER_INT_STATUS_ENABLE_BIT_LSB = COUNTER_INT_STATUS_ENABLE_BIT_LSB,
|
||||
.d_COUNTER_INT_STATUS_ENABLE_BIT_MASK = COUNTER_INT_STATUS_ENABLE_BIT_MASK,
|
||||
.d_INT_STATUS_ENABLE_ADDRESS = INT_STATUS_ENABLE_ADDRESS,
|
||||
.d_CPU_INT_STATUS_ENABLE_BIT_LSB = CPU_INT_STATUS_ENABLE_BIT_LSB,
|
||||
.d_CPU_INT_STATUS_ENABLE_BIT_MASK = CPU_INT_STATUS_ENABLE_BIT_MASK,
|
||||
.d_HOST_INT_STATUS_ADDRESS = HOST_INT_STATUS_ADDRESS,
|
||||
.d_CPU_INT_STATUS_ADDRESS = CPU_INT_STATUS_ADDRESS,
|
||||
.d_ERROR_INT_STATUS_ADDRESS = ERROR_INT_STATUS_ADDRESS,
|
||||
.d_ERROR_INT_STATUS_WAKEUP_MASK = ERROR_INT_STATUS_WAKEUP_MASK,
|
||||
.d_ERROR_INT_STATUS_WAKEUP_LSB = ERROR_INT_STATUS_WAKEUP_LSB,
|
||||
.d_ERROR_INT_STATUS_RX_UNDERFLOW_MASK = ERROR_INT_STATUS_RX_UNDERFLOW_MASK,
|
||||
.d_ERROR_INT_STATUS_RX_UNDERFLOW_LSB = ERROR_INT_STATUS_RX_UNDERFLOW_LSB,
|
||||
.d_ERROR_INT_STATUS_TX_OVERFLOW_MASK = ERROR_INT_STATUS_TX_OVERFLOW_MASK,
|
||||
.d_ERROR_INT_STATUS_TX_OVERFLOW_LSB = ERROR_INT_STATUS_TX_OVERFLOW_LSB,
|
||||
.d_COUNT_DEC_ADDRESS = COUNT_DEC_ADDRESS,
|
||||
.d_HOST_INT_STATUS_CPU_MASK = HOST_INT_STATUS_CPU_MASK,
|
||||
.d_HOST_INT_STATUS_CPU_LSB = HOST_INT_STATUS_CPU_LSB,
|
||||
.d_HOST_INT_STATUS_ERROR_MASK = HOST_INT_STATUS_ERROR_MASK,
|
||||
.d_HOST_INT_STATUS_ERROR_LSB = HOST_INT_STATUS_ERROR_LSB,
|
||||
.d_HOST_INT_STATUS_COUNTER_MASK = HOST_INT_STATUS_COUNTER_MASK,
|
||||
.d_HOST_INT_STATUS_COUNTER_LSB = HOST_INT_STATUS_COUNTER_LSB,
|
||||
.d_RX_LOOKAHEAD_VALID_ADDRESS = RX_LOOKAHEAD_VALID_ADDRESS,
|
||||
.d_WINDOW_DATA_ADDRESS = WINDOW_DATA_ADDRESS,
|
||||
.d_WINDOW_READ_ADDR_ADDRESS = WINDOW_READ_ADDR_ADDRESS,
|
||||
.d_WINDOW_WRITE_ADDR_ADDRESS = WINDOW_WRITE_ADDR_ADDRESS,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
struct hostdef_s *MY_HOST_DEF = &my_host_def;
|
||||
|
||||
#else /* } { */
|
||||
|
||||
#define INT_STATUS_ENABLE_ERROR_LSB (hostdef->d_INT_STATUS_ENABLE_ERROR_LSB)
|
||||
#define INT_STATUS_ENABLE_ERROR_MASK (hostdef->d_INT_STATUS_ENABLE_ERROR_MASK)
|
||||
#define INT_STATUS_ENABLE_CPU_LSB (hostdef->d_INT_STATUS_ENABLE_CPU_LSB)
|
||||
#define INT_STATUS_ENABLE_CPU_MASK (hostdef->d_INT_STATUS_ENABLE_CPU_MASK)
|
||||
#define INT_STATUS_ENABLE_COUNTER_LSB (hostdef->d_INT_STATUS_ENABLE_COUNTER_LSB)
|
||||
#define INT_STATUS_ENABLE_COUNTER_MASK (hostdef->d_INT_STATUS_ENABLE_COUNTER_MASK)
|
||||
#define INT_STATUS_ENABLE_MBOX_DATA_LSB (hostdef->d_INT_STATUS_ENABLE_MBOX_DATA_LSB)
|
||||
#define INT_STATUS_ENABLE_MBOX_DATA_MASK (hostdef->d_INT_STATUS_ENABLE_MBOX_DATA_MASK)
|
||||
#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB (hostdef->d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_LSB)
|
||||
#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK (hostdef->d_ERROR_STATUS_ENABLE_RX_UNDERFLOW_MASK)
|
||||
#define ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB (hostdef->d_ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB)
|
||||
#define ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK (hostdef->d_ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK)
|
||||
#define COUNTER_INT_STATUS_ENABLE_BIT_LSB (hostdef->d_COUNTER_INT_STATUS_ENABLE_BIT_LSB)
|
||||
#define COUNTER_INT_STATUS_ENABLE_BIT_MASK (hostdef->d_COUNTER_INT_STATUS_ENABLE_BIT_MASK)
|
||||
#define INT_STATUS_ENABLE_ADDRESS (hostdef->d_INT_STATUS_ENABLE_ADDRESS)
|
||||
#define CPU_INT_STATUS_ENABLE_BIT_LSB (hostdef->d_CPU_INT_STATUS_ENABLE_BIT_LSB)
|
||||
#define CPU_INT_STATUS_ENABLE_BIT_MASK (hostdef->d_CPU_INT_STATUS_ENABLE_BIT_MASK)
|
||||
#define HOST_INT_STATUS_ADDRESS (hostdef->d_HOST_INT_STATUS_ADDRESS)
|
||||
#define CPU_INT_STATUS_ADDRESS (hostdef->d_CPU_INT_STATUS_ADDRESS)
|
||||
#define ERROR_INT_STATUS_ADDRESS (hostdef->d_ERROR_INT_STATUS_ADDRESS)
|
||||
#define ERROR_INT_STATUS_WAKEUP_MASK (hostdef->d_ERROR_INT_STATUS_WAKEUP_MASK)
|
||||
#define ERROR_INT_STATUS_WAKEUP_LSB (hostdef->d_ERROR_INT_STATUS_WAKEUP_LSB)
|
||||
#define ERROR_INT_STATUS_RX_UNDERFLOW_MASK (hostdef->d_ERROR_INT_STATUS_RX_UNDERFLOW_MASK)
|
||||
#define ERROR_INT_STATUS_RX_UNDERFLOW_LSB (hostdef->d_ERROR_INT_STATUS_RX_UNDERFLOW_LSB)
|
||||
#define ERROR_INT_STATUS_TX_OVERFLOW_MASK (hostdef->d_ERROR_INT_STATUS_TX_OVERFLOW_MASK)
|
||||
#define ERROR_INT_STATUS_TX_OVERFLOW_LSB (hostdef->d_ERROR_INT_STATUS_TX_OVERFLOW_LSB)
|
||||
#define COUNT_DEC_ADDRESS (hostdef->d_COUNT_DEC_ADDRESS)
|
||||
#define HOST_INT_STATUS_CPU_MASK (hostdef->d_HOST_INT_STATUS_CPU_MASK)
|
||||
#define HOST_INT_STATUS_CPU_LSB (hostdef->d_HOST_INT_STATUS_CPU_LSB)
|
||||
#define HOST_INT_STATUS_ERROR_MASK (hostdef->d_HOST_INT_STATUS_ERROR_MASK)
|
||||
#define HOST_INT_STATUS_ERROR_LSB (hostdef->d_HOST_INT_STATUS_ERROR_LSB)
|
||||
#define HOST_INT_STATUS_COUNTER_MASK (hostdef->d_HOST_INT_STATUS_COUNTER_MASK)
|
||||
#define HOST_INT_STATUS_COUNTER_LSB (hostdef->d_HOST_INT_STATUS_COUNTER_LSB)
|
||||
#define RX_LOOKAHEAD_VALID_ADDRESS (hostdef->d_RX_LOOKAHEAD_VALID_ADDRESS)
|
||||
#define WINDOW_DATA_ADDRESS (hostdef->d_WINDOW_DATA_ADDRESS)
|
||||
#define WINDOW_READ_ADDR_ADDRESS (hostdef->d_WINDOW_READ_ADDR_ADDRESS)
|
||||
#define WINDOW_WRITE_ADDR_ADDRESS (hostdef->d_WINDOW_WRITE_ADDR_ADDRESS)
|
||||
|
||||
/* SET macros */
|
||||
#define INT_STATUS_ENABLE_ERROR_SET(x) (((x) << INT_STATUS_ENABLE_ERROR_LSB) & INT_STATUS_ENABLE_ERROR_MASK)
|
||||
#define INT_STATUS_ENABLE_CPU_SET(x) (((x) << INT_STATUS_ENABLE_CPU_LSB) & INT_STATUS_ENABLE_CPU_MASK)
|
||||
#define INT_STATUS_ENABLE_COUNTER_SET(x) (((x) << INT_STATUS_ENABLE_COUNTER_LSB) & INT_STATUS_ENABLE_COUNTER_MASK)
|
||||
#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_BIT_SET(x) (((x) << CPU_INT_STATUS_ENABLE_BIT_LSB) & CPU_INT_STATUS_ENABLE_BIT_MASK)
|
||||
#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_SET(x) (((x) << ERROR_STATUS_ENABLE_TX_OVERFLOW_LSB) & ERROR_STATUS_ENABLE_TX_OVERFLOW_MASK)
|
||||
#define COUNTER_INT_STATUS_ENABLE_BIT_SET(x) (((x) << COUNTER_INT_STATUS_ENABLE_BIT_LSB) & COUNTER_INT_STATUS_ENABLE_BIT_MASK)
|
||||
#define ERROR_INT_STATUS_WAKEUP_GET(x) (((x) & ERROR_INT_STATUS_WAKEUP_MASK) >> ERROR_INT_STATUS_WAKEUP_LSB)
|
||||
#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_TX_OVERFLOW_GET(x) (((x) & ERROR_INT_STATUS_TX_OVERFLOW_MASK) >> ERROR_INT_STATUS_TX_OVERFLOW_LSB)
|
||||
#define HOST_INT_STATUS_CPU_GET(x) (((x) & HOST_INT_STATUS_CPU_MASK) >> HOST_INT_STATUS_CPU_LSB)
|
||||
#define HOST_INT_STATUS_ERROR_GET(x) (((x) & HOST_INT_STATUS_ERROR_MASK) >> HOST_INT_STATUS_ERROR_LSB)
|
||||
#define HOST_INT_STATUS_COUNTER_GET(x) (((x) & HOST_INT_STATUS_COUNTER_MASK) >> HOST_INT_STATUS_COUNTER_LSB)
|
||||
|
||||
|
||||
extern struct hostdef_s *hostdef;
|
||||
|
||||
#endif /* } */
|
||||
|
||||
#endif /*HOST_REG_TABLE_H_*/
|
||||
|
||||
|
||||
52
drivers/net/wireless/ar6003/host/include/host_version.h
Normal file
52
drivers/net/wireless/ar6003/host/include/host_version.h
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <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_ */
|
||||
575
drivers/net/wireless/ar6003/host/include/htc_api.h
Normal file
575
drivers/net/wireless/ar6003/host/include/htc_api.h
Normal file
|
|
@ -0,0 +1,575 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <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 A_UINT16 HTC_SERVICE_ID;
|
||||
|
||||
typedef struct _HTC_INIT_INFO {
|
||||
void *pContext; /* context for target failure notification */
|
||||
void (*TargetFailure)(void *Instance, A_STATUS Status);
|
||||
} HTC_INIT_INFO;
|
||||
|
||||
/* per service connection send completion */
|
||||
typedef void (*HTC_EP_SEND_PKT_COMPLETE)(void *,HTC_PACKET *);
|
||||
/* per service connection callback when a plurality of packets have been sent
|
||||
* The 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 *,HTC_PACKET_QUEUE *);
|
||||
/* per service connection pkt received */
|
||||
typedef void (*HTC_EP_RECV_PKT)(void *,HTC_PACKET *);
|
||||
/* per service connection callback when a plurality of packets are received
|
||||
* The 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 *,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 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 *, HTC_PACKET *pPacket);
|
||||
|
||||
typedef 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 */
|
||||
} HTC_EP_CALLBACKS;
|
||||
|
||||
/* service connection information */
|
||||
typedef struct _HTC_SERVICE_CONNECT_REQ {
|
||||
HTC_SERVICE_ID ServiceID; /* service ID to connect to */
|
||||
A_UINT16 ConnectionFlags; /* connection flags, see htc protocol definition */
|
||||
A_UINT8 *pMetaData; /* ptr to optional service-specific meta-data */
|
||||
A_UINT8 MetaDataLength; /* optional meta data length */
|
||||
HTC_EP_CALLBACKS EpCallbacks; /* endpoint callbacks */
|
||||
int MaxSendQueueDepth; /* maximum depth of any send queue */
|
||||
A_UINT32 LocalConnectionFlags; /* HTC flags for the host-side (local) connection */
|
||||
unsigned int MaxSendMsgSize; /* override max message size in send direction */
|
||||
} HTC_SERVICE_CONNECT_REQ;
|
||||
|
||||
#define HTC_LOCAL_CONN_FLAGS_ENABLE_SEND_BUNDLE_PADDING (1 << 0) /* enable send bundle padding for this endpoint */
|
||||
|
||||
/* service connection response information */
|
||||
typedef struct _HTC_SERVICE_CONNECT_RESP {
|
||||
A_UINT8 *pMetaData; /* caller supplied buffer to optional meta-data */
|
||||
A_UINT8 BufferLength; /* length of caller supplied buffer */
|
||||
A_UINT8 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 */
|
||||
A_UINT8 ConnectRespCode; /* connect response code from target */
|
||||
} HTC_SERVICE_CONNECT_RESP;
|
||||
|
||||
/* endpoint distribution structure */
|
||||
typedef 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) */
|
||||
A_UINT32 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
|
||||
*/
|
||||
} HTC_ENDPOINT_CREDIT_DIST;
|
||||
|
||||
#define HTC_EP_ACTIVE ((A_UINT32) (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 occured (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,
|
||||
HTC_ENDPOINT_CREDIT_DIST *pEPList,
|
||||
HTC_CREDIT_DIST_REASON Reason);
|
||||
|
||||
typedef void (*HTC_CREDIT_INIT_CALLBACK)(void *Context,
|
||||
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 */
|
||||
typedef struct _HTC_ENDPOINT_STATS {
|
||||
A_UINT32 TxCreditLowIndications; /* number of times the host set the credit-low flag in a send message on
|
||||
this endpoint */
|
||||
A_UINT32 TxIssued; /* running count of total TX packets issued */
|
||||
A_UINT32 TxPacketsBundled; /* running count of TX packets that were issued in bundles */
|
||||
A_UINT32 TxBundles; /* running count of TX bundles that were issued */
|
||||
A_UINT32 TxDropped; /* tx packets that were dropped */
|
||||
A_UINT32 TxCreditRpts; /* running count of total credit reports received for this endpoint */
|
||||
A_UINT32 TxCreditRptsFromRx; /* credit reports received from this endpoint's RX packets */
|
||||
A_UINT32 TxCreditRptsFromOther; /* credit reports received from RX packets of other endpoints */
|
||||
A_UINT32 TxCreditRptsFromEp0; /* credit reports received from endpoint 0 RX packets */
|
||||
A_UINT32 TxCreditsFromRx; /* count of credits received via Rx packets on this endpoint */
|
||||
A_UINT32 TxCreditsFromOther; /* count of credits received via another endpoint */
|
||||
A_UINT32 TxCreditsFromEp0; /* count of credits received via another endpoint */
|
||||
A_UINT32 TxCreditsConsummed; /* count of consummed credits */
|
||||
A_UINT32 TxCreditsReturned; /* count of credits returned */
|
||||
A_UINT32 RxReceived; /* count of RX packets received */
|
||||
A_UINT32 RxLookAheads; /* count of lookahead records
|
||||
found in messages received on this endpoint */
|
||||
A_UINT32 RxPacketsBundled; /* count of recv packets received in a bundle */
|
||||
A_UINT32 RxBundleLookAheads; /* count of number of bundled lookaheads */
|
||||
A_UINT32 RxBundleIndFromHdr; /* count of the number of bundle indications from the HTC header */
|
||||
A_UINT32 RxAllocThreshHit; /* count of the number of times the recv allocation threshhold was hit */
|
||||
A_UINT32 RxAllocThreshBytes; /* total number of bytes */
|
||||
} HTC_ENDPOINT_STATS;
|
||||
|
||||
/* ------ 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, 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
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
||||
A_STATUS 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
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
||||
A_STATUS 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: A_OK 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:
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
||||
A_STATUS HTCAddReceivePkt(HTC_HANDLE HTCHandle, 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
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
||||
A_STATUS HTCConnectService(HTC_HANDLE HTCHandle,
|
||||
HTC_SERVICE_CONNECT_REQ *pReq,
|
||||
HTC_SERVICE_CONNECT_RESP *pResp);
|
||||
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
@desc: Send an HTC packet
|
||||
@function name: HTCSendPkt
|
||||
@input: HTCHandle - HTC handle
|
||||
pPacket - packet to send
|
||||
@output:
|
||||
@return: A_OK
|
||||
@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
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
||||
A_STATUS HTCSendPkt(HTC_HANDLE HTCHandle, 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: Destory 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,
|
||||
A_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:
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
||||
A_BOOL HTCGetEndpointStatistics(HTC_HANDLE HTCHandle,
|
||||
HTC_ENDPOINT_ID Endpoint,
|
||||
HTC_ENDPOINT_STAT_ACTION Action,
|
||||
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: A_OK
|
||||
@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 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
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
||||
A_STATUS HTCSendPktsMultiple(HTC_HANDLE HTCHandle, 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: A_OK 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 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:
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
||||
A_STATUS HTCAddReceivePktMultiple(HTC_HANDLE HTCHandle, 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:
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
|
||||
A_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);
|
||||
A_STATUS HTCWaitForPendingRecv(HTC_HANDLE HTCHandle,
|
||||
A_UINT32 TimeoutInMs,
|
||||
A_BOOL *pbIsRecvPending);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _HTC_API_H_ */
|
||||
227
drivers/net/wireless/ar6003/host/include/htc_packet.h
Normal file
227
drivers/net/wireless/ar6003/host/include/htc_packet.h
Normal file
|
|
@ -0,0 +1,227 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <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 A_UINT16 HTC_TX_TAG;
|
||||
|
||||
typedef 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) */
|
||||
A_UINT8 SendFlags; /* send flags (HTC internal) */
|
||||
int SeqNo; /* internal seq no for debugging (HTC internal) */
|
||||
} HTC_TX_PACKET_INFO;
|
||||
|
||||
#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 */
|
||||
|
||||
typedef struct _HTC_RX_PACKET_INFO {
|
||||
A_UINT32 ExpectedHdr; /* HTC internal use */
|
||||
A_UINT32 HTCRxFlags; /* HTC internal use */
|
||||
A_UINT32 IndicationFlags; /* indication flags set on each RX packet indication */
|
||||
} HTC_RX_PACKET_INFO;
|
||||
|
||||
#define HTC_RX_FLAGS_INDICATE_MORE_PKTS (1 << 0) /* more packets on this endpoint are being fetched */
|
||||
|
||||
/* wrapper around endpoint-specific packets */
|
||||
typedef struct _HTC_PACKET {
|
||||
DL_LIST ListLink; /* double link */
|
||||
void *pPktContext; /* caller's per packet specific context */
|
||||
|
||||
A_UINT8 *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
|
||||
*/
|
||||
A_UINT8 *pBuffer; /* payload start (RX/TX) */
|
||||
A_UINT32 BufferLength; /* length of buffer */
|
||||
A_UINT32 ActualLength; /* actual length of payload */
|
||||
HTC_ENDPOINT_ID Endpoint; /* endpoint that this packet was sent/recv'd from */
|
||||
A_STATUS Status; /* completion status */
|
||||
union {
|
||||
HTC_TX_PACKET_INFO AsTx; /* Tx Packet specific info */
|
||||
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 */
|
||||
} HTC_PACKET;
|
||||
|
||||
|
||||
|
||||
#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 */
|
||||
typedef struct _HTC_PACKET_QUEUE {
|
||||
DL_LIST QueueHead;
|
||||
int Depth;
|
||||
} HTC_PACKET_QUEUE;
|
||||
|
||||
/* 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 HTC_PACKET *HTC_GET_PKT_AT_HEAD(HTC_PACKET_QUEUE *queue) {
|
||||
if (queue->Depth == 0) {
|
||||
return NULL;
|
||||
}
|
||||
return A_CONTAINING_STRUCT((DL_LIST_GET_ITEM_AT_HEAD(&queue->QueueHead)),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 HTC_PACKET *HTC_PACKET_DEQUEUE(HTC_PACKET_QUEUE *queue) {
|
||||
DL_LIST *pItem = DL_ListRemoveItemFromHead(&queue->QueueHead);
|
||||
if (pItem != NULL) {
|
||||
queue->Depth--;
|
||||
return A_CONTAINING_STRUCT(pItem, HTC_PACKET, ListLink);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* dequeue an HTC packet from the tail of the queue */
|
||||
static INLINE HTC_PACKET *HTC_PACKET_DEQUEUE_TAIL(HTC_PACKET_QUEUE *queue) {
|
||||
DL_LIST *pItem = DL_ListRemoveItemFromTail(&queue->QueueHead);
|
||||
if (pItem != NULL) {
|
||||
queue->Depth--;
|
||||
return A_CONTAINING_STRUCT(pItem, 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), HTC_PACKET, ListLink)
|
||||
|
||||
#define HTC_PACKET_QUEUE_ITERATE_END ITERATE_END
|
||||
|
||||
#endif /*HTC_PACKET_H_*/
|
||||
116
drivers/net/wireless/ar6003/host/include/p2p_api.h
Normal file
116
drivers/net/wireless/ar6003/host/include/p2p_api.h
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <copyright file="p2p_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 definitions exported by the P2P host module.
|
||||
//
|
||||
// Author(s): ="Atheros"
|
||||
//==============================================================================
|
||||
|
||||
#ifndef _HOST_P2P_API_H_
|
||||
#define _HOST_P2P_API_H_
|
||||
|
||||
#include "utils_api.h"
|
||||
#include "wmi.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define P2P_OUI 0x99a6f50
|
||||
|
||||
static int __inline
|
||||
isp2poui(const A_UINT8 *frm)
|
||||
{
|
||||
return frm[1] > 3 && LE_READ_4(frm+2) == (P2P_OUI);
|
||||
}
|
||||
|
||||
/* API function declarations */
|
||||
|
||||
void *p2p_init(void *dev);
|
||||
|
||||
struct host_p2p_dev *p2p_get_device(void *p2p_dev_ctx, const A_UINT8 *addr);
|
||||
|
||||
void *p2p_bssinfo_rx(void *p2p_dev_ctx, WMI_BI_FTYPE fType, A_UINT8 *addr, A_UINT16 channel, const A_UINT8 *data, A_UINT32 len);
|
||||
|
||||
void p2p_go_neg_req_rx(void *p2p_dev_ctx, const A_UINT8 *datap, A_UINT8 len);
|
||||
|
||||
void p2p_invite_req_rx(void *p2p_dev_ctx, const A_UINT8 *datap, A_UINT8 len);
|
||||
|
||||
void p2p_prov_disc_req_rx(void *p2p_dev_ctx, const A_UINT8 *datap, A_UINT8 len);
|
||||
void p2p_prov_disc_resp_rx(void *p2p_dev_ctx,
|
||||
const A_UINT8 *datap, A_UINT8 len);
|
||||
void p2p_start_sdpd_event_rx(void *p2p_dev_ctx);
|
||||
void p2p_sdpd_rx_event_rx(void *p2p_dev_ctx,
|
||||
const A_UINT8 *datap, A_UINT8 len);
|
||||
void p2p_free_all_devices(void *ctx);
|
||||
void p2p_device_free(void *peer_dev);
|
||||
|
||||
A_STATUS p2p_auth_go_neg(void *ctx,
|
||||
WMI_P2P_GO_NEG_START_CMD *auth_go_neg_param);
|
||||
|
||||
A_STATUS p2p_auth_invite(void *ctx, A_UINT8 *auth_peer);
|
||||
|
||||
A_STATUS p2p_peer_reject(void *ctx, A_UINT8 *peer_addr);
|
||||
|
||||
A_STATUS p2p_go_neg_start(void *ctx, WMI_P2P_GO_NEG_START_CMD *go_neg_param);
|
||||
|
||||
A_STATUS p2p_invite_cmd(void *ctx, WMI_P2P_INVITE_CMD *invite_param);
|
||||
|
||||
A_STATUS p2p_prov_disc_req(void *ctx, A_UINT8 *peer, A_UINT16 wps_method);
|
||||
|
||||
A_STATUS p2p_peer(void *ctx, A_UINT8 *peer, A_UINT8 next);
|
||||
|
||||
A_STATUS p2p_get_device_p2p_buf(void *ctx, A_UINT8 *peer, A_UINT8 **p2p_buf, A_UINT8 *p2p_buf_len);
|
||||
|
||||
A_STATUS wmi_p2p_get_go_params(void *ctx, A_UINT8 *go_dev_addr,
|
||||
A_UINT16 *oper_freq, A_UINT8 *ssid, A_UINT8 *ssid_len);
|
||||
|
||||
A_STATUS p2p_get_devaddr (void *ctx, A_UINT8 *intf_addr);
|
||||
|
||||
A_STATUS p2p_get_ifaddr (void *ctx, A_UINT8 *dev_addr);
|
||||
|
||||
struct host_p2p_dev *p2p_get_device_intf_addrs(void *ctx, const A_UINT8 *intfaddr);
|
||||
|
||||
void p2p_increment_dev_ref_count(struct host_p2p_dev *dev);
|
||||
|
||||
void p2p_free_all_sd_queries(void *ctx);
|
||||
|
||||
A_STATUS p2p_sd_request(void *ctx, A_UINT8 *peer_addr, A_UINT8 *tlvbuf,
|
||||
A_UINT8 tlv_buflen, A_UINT32 *qid);
|
||||
|
||||
A_STATUS p2p_sdpd_tx_cmd(void *ctx, WMI_P2P_SDPD_TX_CMD *sdpd_tx_cmd, A_UINT32 *qid);
|
||||
|
||||
A_STATUS p2p_sd_cancel_request(void *ctx, A_UINT32 qid);
|
||||
|
||||
void p2p_go_neg_complete_rx(void *ctx, const A_UINT8 *datap, A_UINT8 len);
|
||||
|
||||
int p2p_get_peer_info(void *ctx, A_UINT8 *peer_addr, A_UINT8 *buf, A_UINT32 buflen);
|
||||
|
||||
int p2p_get_next_addr(void *ctx, A_UINT8 *addr, A_UINT8 *buf, A_UINT32 buflen, int first_element);
|
||||
|
||||
void p2p_clear_peers_reported_flag(void *ctx);
|
||||
|
||||
void p2p_clear_peers_authorized_flag(void *ctx, const A_UINT8 *addr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _HOST_P2P_API_H_ */
|
||||
36
drivers/net/wireless/ar6003/host/include/project.h
Normal file
36
drivers/net/wireless/ar6003/host/include/project.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright (c) 2008 Atheros Communications Inc.
|
||||
*
|
||||
* 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 _PROJECT_H_
|
||||
#define _PROJECT_H_
|
||||
#include "queue.h"
|
||||
|
||||
#define OS_TIMER_FUNC(fn) void fn(A_HANDLE hdl, void *context)
|
||||
#define OS_TIMER_FUNC_PTR(fn) void (* fn)(A_HANDLE hdl, void *context)
|
||||
#define OS_CANCEL_TIMER(timer_hdl) A_UNTIMEOUT(timer_hdl)
|
||||
#define OS_SET_TIMER(timer_hdl, period, repeat) A_TIMEOUT_MS(timer_hdl, period, repeat)
|
||||
#define OS_INIT_TIMER(timer_hdl, fn, arg) A_INIT_TIMER(timer_hdl, fn, arg)
|
||||
|
||||
typedef A_TIMER os_timer_t;
|
||||
|
||||
/* Memory related */
|
||||
#define OS_MEMZERO(ptr, size) A_MEMZERO(ptr, size)
|
||||
#define OS_MEMCPY(dst, src, len) A_MEMCPY(dst, src, len)
|
||||
#define OS_MALLOC(nbytes) A_MALLOC(nbytes)
|
||||
#define OS_FREE(ptr) A_FREE(ptr)
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
349
drivers/net/wireless/ar6003/host/include/target_reg_table.h
Normal file
349
drivers/net/wireless/ar6003/host/include/target_reg_table.h
Normal file
|
|
@ -0,0 +1,349 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <copyright file="target_reg_table.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.
|
||||
//
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
//==============================================================================
|
||||
// Target register table macros and structure definitions
|
||||
//
|
||||
// Author(s): ="Atheros"
|
||||
//==============================================================================
|
||||
|
||||
#ifndef TARGET_REG_TABLE_H_
|
||||
#define TARGET_REG_TABLE_H_
|
||||
|
||||
#include "targaddrs.h"
|
||||
/*** WARNING : Add to the end of the TABLE! do not change the order ****/
|
||||
typedef struct targetdef_s {
|
||||
A_UINT32 d_RTC_SOC_BASE_ADDRESS;
|
||||
A_UINT32 d_RTC_WMAC_BASE_ADDRESS;
|
||||
A_UINT32 d_SYSTEM_SLEEP_OFFSET;
|
||||
A_UINT32 d_WLAN_SYSTEM_SLEEP_OFFSET;
|
||||
A_UINT32 d_WLAN_SYSTEM_SLEEP_DISABLE_LSB;
|
||||
A_UINT32 d_WLAN_SYSTEM_SLEEP_DISABLE_MASK;
|
||||
A_UINT32 d_CLOCK_CONTROL_OFFSET;
|
||||
A_UINT32 d_CLOCK_CONTROL_SI0_CLK_MASK;
|
||||
A_UINT32 d_RESET_CONTROL_OFFSET;
|
||||
A_UINT32 d_RESET_CONTROL_MBOX_RST_MASK;
|
||||
A_UINT32 d_RESET_CONTROL_SI0_RST_MASK;
|
||||
A_UINT32 d_WLAN_RESET_CONTROL_OFFSET;
|
||||
A_UINT32 d_WLAN_RESET_CONTROL_COLD_RST_MASK;
|
||||
A_UINT32 d_WLAN_RESET_CONTROL_WARM_RST_MASK;
|
||||
A_UINT32 d_GPIO_BASE_ADDRESS;
|
||||
A_UINT32 d_GPIO_PIN0_OFFSET;
|
||||
A_UINT32 d_GPIO_PIN1_OFFSET;
|
||||
A_UINT32 d_GPIO_PIN0_CONFIG_MASK;
|
||||
A_UINT32 d_GPIO_PIN1_CONFIG_MASK;
|
||||
A_UINT32 d_SI_CONFIG_BIDIR_OD_DATA_LSB;
|
||||
A_UINT32 d_SI_CONFIG_BIDIR_OD_DATA_MASK;
|
||||
A_UINT32 d_SI_CONFIG_I2C_LSB;
|
||||
A_UINT32 d_SI_CONFIG_I2C_MASK;
|
||||
A_UINT32 d_SI_CONFIG_POS_SAMPLE_LSB;
|
||||
A_UINT32 d_SI_CONFIG_POS_SAMPLE_MASK;
|
||||
A_UINT32 d_SI_CONFIG_INACTIVE_CLK_LSB;
|
||||
A_UINT32 d_SI_CONFIG_INACTIVE_CLK_MASK;
|
||||
A_UINT32 d_SI_CONFIG_INACTIVE_DATA_LSB;
|
||||
A_UINT32 d_SI_CONFIG_INACTIVE_DATA_MASK;
|
||||
A_UINT32 d_SI_CONFIG_DIVIDER_LSB;
|
||||
A_UINT32 d_SI_CONFIG_DIVIDER_MASK;
|
||||
A_UINT32 d_SI_BASE_ADDRESS;
|
||||
A_UINT32 d_SI_CONFIG_OFFSET;
|
||||
A_UINT32 d_SI_TX_DATA0_OFFSET;
|
||||
A_UINT32 d_SI_TX_DATA1_OFFSET;
|
||||
A_UINT32 d_SI_RX_DATA0_OFFSET;
|
||||
A_UINT32 d_SI_RX_DATA1_OFFSET;
|
||||
A_UINT32 d_SI_CS_OFFSET;
|
||||
A_UINT32 d_SI_CS_DONE_ERR_MASK;
|
||||
A_UINT32 d_SI_CS_DONE_INT_MASK;
|
||||
A_UINT32 d_SI_CS_START_LSB;
|
||||
A_UINT32 d_SI_CS_START_MASK;
|
||||
A_UINT32 d_SI_CS_RX_CNT_LSB;
|
||||
A_UINT32 d_SI_CS_RX_CNT_MASK;
|
||||
A_UINT32 d_SI_CS_TX_CNT_LSB;
|
||||
A_UINT32 d_SI_CS_TX_CNT_MASK;
|
||||
A_UINT32 d_BOARD_DATA_SZ;
|
||||
A_UINT32 d_BOARD_EXT_DATA_SZ;
|
||||
A_UINT32 d_MBOX_BASE_ADDRESS;
|
||||
A_UINT32 d_LOCAL_SCRATCH_OFFSET;
|
||||
A_UINT32 d_CPU_CLOCK_OFFSET;
|
||||
A_UINT32 d_LPO_CAL_OFFSET;
|
||||
A_UINT32 d_GPIO_PIN10_OFFSET;
|
||||
A_UINT32 d_GPIO_PIN11_OFFSET;
|
||||
A_UINT32 d_GPIO_PIN12_OFFSET;
|
||||
A_UINT32 d_GPIO_PIN13_OFFSET;
|
||||
A_UINT32 d_CLOCK_GPIO_OFFSET;
|
||||
A_UINT32 d_CPU_CLOCK_STANDARD_LSB;
|
||||
A_UINT32 d_CPU_CLOCK_STANDARD_MASK;
|
||||
A_UINT32 d_LPO_CAL_ENABLE_LSB;
|
||||
A_UINT32 d_LPO_CAL_ENABLE_MASK;
|
||||
A_UINT32 d_CLOCK_GPIO_BT_CLK_OUT_EN_LSB;
|
||||
A_UINT32 d_CLOCK_GPIO_BT_CLK_OUT_EN_MASK;
|
||||
A_UINT32 d_ANALOG_INTF_BASE_ADDRESS;
|
||||
} TARGET_REGISTER_TABLE;
|
||||
|
||||
#define ATH_UNSUPPORTED_REG_OFFSET 0xffffffff
|
||||
#define ATH_SUPPORTED_BY_TARGET(reg_offset) ((reg_offset) != ATH_UNSUPPORTED_REG_OFFSET)
|
||||
|
||||
#define BOARD_DATA_SZ_MAX 2048
|
||||
|
||||
#if defined(MY_TARGET_DEF) /* { */
|
||||
#if defined(ATHR_WIN_DEF)
|
||||
#define ATH_REG_TABLE_DIRECT_ASSIGN
|
||||
#endif
|
||||
|
||||
/* Cross-platform compatibility */
|
||||
#if !defined(SOC_RESET_CONTROL_OFFSET) && defined(RESET_CONTROL_OFFSET)
|
||||
#define SOC_RESET_CONTROL_OFFSET RESET_CONTROL_OFFSET
|
||||
#endif
|
||||
#if !defined(CLOCK_GPIO_OFFSET)
|
||||
#define CLOCK_GPIO_OFFSET ATH_UNSUPPORTED_REG_OFFSET
|
||||
#define CLOCK_GPIO_BT_CLK_OUT_EN_LSB 0
|
||||
#define CLOCK_GPIO_BT_CLK_OUT_EN_MASK 0
|
||||
#endif
|
||||
|
||||
#ifdef ATH_REG_TABLE_DIRECT_ASSIGN
|
||||
|
||||
static struct targetdef_s my_target_def = {
|
||||
RTC_SOC_BASE_ADDRESS,
|
||||
RTC_WMAC_BASE_ADDRESS,
|
||||
SYSTEM_SLEEP_OFFSET,
|
||||
WLAN_SYSTEM_SLEEP_OFFSET,
|
||||
WLAN_SYSTEM_SLEEP_DISABLE_LSB,
|
||||
WLAN_SYSTEM_SLEEP_DISABLE_MASK,
|
||||
CLOCK_CONTROL_OFFSET,
|
||||
CLOCK_CONTROL_SI0_CLK_MASK,
|
||||
SOC_RESET_CONTROL_OFFSET,
|
||||
RESET_CONTROL_MBOX_RST_MASK,
|
||||
RESET_CONTROL_SI0_RST_MASK,
|
||||
WLAN_RESET_CONTROL_OFFSET,
|
||||
WLAN_RESET_CONTROL_COLD_RST_MASK,
|
||||
WLAN_RESET_CONTROL_WARM_RST_MASK,
|
||||
GPIO_BASE_ADDRESS,
|
||||
GPIO_PIN0_OFFSET,
|
||||
GPIO_PIN1_OFFSET,
|
||||
GPIO_PIN0_CONFIG_MASK,
|
||||
GPIO_PIN1_CONFIG_MASK,
|
||||
SI_CONFIG_BIDIR_OD_DATA_LSB,
|
||||
SI_CONFIG_BIDIR_OD_DATA_MASK,
|
||||
SI_CONFIG_I2C_LSB,
|
||||
SI_CONFIG_I2C_MASK,
|
||||
SI_CONFIG_POS_SAMPLE_LSB,
|
||||
SI_CONFIG_POS_SAMPLE_MASK,
|
||||
SI_CONFIG_INACTIVE_CLK_LSB,
|
||||
SI_CONFIG_INACTIVE_CLK_MASK,
|
||||
SI_CONFIG_INACTIVE_DATA_LSB,
|
||||
SI_CONFIG_INACTIVE_DATA_MASK,
|
||||
SI_CONFIG_DIVIDER_LSB,
|
||||
SI_CONFIG_DIVIDER_MASK,
|
||||
SI_BASE_ADDRESS,
|
||||
SI_CONFIG_OFFSET,
|
||||
SI_TX_DATA0_OFFSET,
|
||||
SI_TX_DATA1_OFFSET,
|
||||
SI_RX_DATA0_OFFSET,
|
||||
SI_RX_DATA1_OFFSET,
|
||||
SI_CS_OFFSET,
|
||||
SI_CS_DONE_ERR_MASK,
|
||||
SI_CS_DONE_INT_MASK,
|
||||
SI_CS_START_LSB,
|
||||
SI_CS_START_MASK,
|
||||
SI_CS_RX_CNT_LSB,
|
||||
SI_CS_RX_CNT_MASK,
|
||||
SI_CS_TX_CNT_LSB,
|
||||
SI_CS_TX_CNT_MASK,
|
||||
MY_TARGET_BOARD_DATA_SZ,
|
||||
MY_TARGET_BOARD_EXT_DATA_SZ,
|
||||
MBOX_BASE_ADDRESS,
|
||||
LOCAL_SCRATCH_OFFSET,
|
||||
CPU_CLOCK_OFFSET,
|
||||
LPO_CAL_OFFSET,
|
||||
GPIO_PIN10_OFFSET,
|
||||
GPIO_PIN11_OFFSET,
|
||||
GPIO_PIN12_OFFSET,
|
||||
GPIO_PIN13_OFFSET,
|
||||
CLOCK_GPIO_OFFSET,
|
||||
CPU_CLOCK_STANDARD_LSB,
|
||||
CPU_CLOCK_STANDARD_MASK,
|
||||
LPO_CAL_ENABLE_LSB,
|
||||
LPO_CAL_ENABLE_MASK,
|
||||
CLOCK_GPIO_BT_CLK_OUT_EN_LSB,
|
||||
CLOCK_GPIO_BT_CLK_OUT_EN_MASK,
|
||||
ANALOG_INTF_BASE_ADDRESS,
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
static struct targetdef_s my_target_def = {
|
||||
.d_RTC_SOC_BASE_ADDRESS = RTC_SOC_BASE_ADDRESS,
|
||||
.d_RTC_WMAC_BASE_ADDRESS = RTC_WMAC_BASE_ADDRESS,
|
||||
.d_SYSTEM_SLEEP_OFFSET = WLAN_SYSTEM_SLEEP_OFFSET,
|
||||
.d_WLAN_SYSTEM_SLEEP_OFFSET = WLAN_SYSTEM_SLEEP_OFFSET,
|
||||
.d_WLAN_SYSTEM_SLEEP_DISABLE_LSB = WLAN_SYSTEM_SLEEP_DISABLE_LSB,
|
||||
.d_WLAN_SYSTEM_SLEEP_DISABLE_MASK = WLAN_SYSTEM_SLEEP_DISABLE_MASK,
|
||||
.d_CLOCK_CONTROL_OFFSET = CLOCK_CONTROL_OFFSET,
|
||||
.d_CLOCK_CONTROL_SI0_CLK_MASK = CLOCK_CONTROL_SI0_CLK_MASK,
|
||||
.d_RESET_CONTROL_OFFSET = SOC_RESET_CONTROL_OFFSET,
|
||||
.d_RESET_CONTROL_MBOX_RST_MASK = RESET_CONTROL_MBOX_RST_MASK,
|
||||
.d_RESET_CONTROL_SI0_RST_MASK = RESET_CONTROL_SI0_RST_MASK,
|
||||
.d_WLAN_RESET_CONTROL_OFFSET = WLAN_RESET_CONTROL_OFFSET,
|
||||
.d_WLAN_RESET_CONTROL_COLD_RST_MASK = WLAN_RESET_CONTROL_COLD_RST_MASK,
|
||||
.d_WLAN_RESET_CONTROL_WARM_RST_MASK = WLAN_RESET_CONTROL_WARM_RST_MASK,
|
||||
.d_GPIO_BASE_ADDRESS = GPIO_BASE_ADDRESS,
|
||||
.d_GPIO_PIN0_OFFSET = GPIO_PIN0_OFFSET,
|
||||
.d_GPIO_PIN1_OFFSET = GPIO_PIN1_OFFSET,
|
||||
.d_GPIO_PIN0_CONFIG_MASK = GPIO_PIN0_CONFIG_MASK,
|
||||
.d_GPIO_PIN1_CONFIG_MASK = GPIO_PIN1_CONFIG_MASK,
|
||||
.d_SI_CONFIG_BIDIR_OD_DATA_LSB = SI_CONFIG_BIDIR_OD_DATA_LSB,
|
||||
.d_SI_CONFIG_BIDIR_OD_DATA_MASK = SI_CONFIG_BIDIR_OD_DATA_MASK,
|
||||
.d_SI_CONFIG_I2C_LSB = SI_CONFIG_I2C_LSB,
|
||||
.d_SI_CONFIG_I2C_MASK = SI_CONFIG_I2C_MASK,
|
||||
.d_SI_CONFIG_POS_SAMPLE_LSB = SI_CONFIG_POS_SAMPLE_LSB,
|
||||
.d_SI_CONFIG_POS_SAMPLE_MASK = SI_CONFIG_POS_SAMPLE_MASK,
|
||||
.d_SI_CONFIG_INACTIVE_CLK_LSB = SI_CONFIG_INACTIVE_CLK_LSB,
|
||||
.d_SI_CONFIG_INACTIVE_CLK_MASK = SI_CONFIG_INACTIVE_CLK_MASK,
|
||||
.d_SI_CONFIG_INACTIVE_DATA_LSB = SI_CONFIG_INACTIVE_DATA_LSB,
|
||||
.d_SI_CONFIG_INACTIVE_DATA_MASK = SI_CONFIG_INACTIVE_DATA_MASK,
|
||||
.d_SI_CONFIG_DIVIDER_LSB = SI_CONFIG_DIVIDER_LSB,
|
||||
.d_SI_CONFIG_DIVIDER_MASK = SI_CONFIG_DIVIDER_MASK,
|
||||
.d_SI_BASE_ADDRESS = SI_BASE_ADDRESS,
|
||||
.d_SI_CONFIG_OFFSET = SI_CONFIG_OFFSET,
|
||||
.d_SI_TX_DATA0_OFFSET = SI_TX_DATA0_OFFSET,
|
||||
.d_SI_TX_DATA1_OFFSET = SI_TX_DATA1_OFFSET,
|
||||
.d_SI_RX_DATA0_OFFSET = SI_RX_DATA0_OFFSET,
|
||||
.d_SI_RX_DATA1_OFFSET = SI_RX_DATA1_OFFSET,
|
||||
.d_SI_CS_OFFSET = SI_CS_OFFSET,
|
||||
.d_SI_CS_DONE_ERR_MASK = SI_CS_DONE_ERR_MASK,
|
||||
.d_SI_CS_DONE_INT_MASK = SI_CS_DONE_INT_MASK,
|
||||
.d_SI_CS_START_LSB = SI_CS_START_LSB,
|
||||
.d_SI_CS_START_MASK = SI_CS_START_MASK,
|
||||
.d_SI_CS_RX_CNT_LSB = SI_CS_RX_CNT_LSB,
|
||||
.d_SI_CS_RX_CNT_MASK = SI_CS_RX_CNT_MASK,
|
||||
.d_SI_CS_TX_CNT_LSB = SI_CS_TX_CNT_LSB,
|
||||
.d_SI_CS_TX_CNT_MASK = SI_CS_TX_CNT_MASK,
|
||||
.d_BOARD_DATA_SZ = MY_TARGET_BOARD_DATA_SZ,
|
||||
.d_BOARD_EXT_DATA_SZ = MY_TARGET_BOARD_EXT_DATA_SZ,
|
||||
.d_MBOX_BASE_ADDRESS = MBOX_BASE_ADDRESS,
|
||||
.d_LOCAL_SCRATCH_OFFSET = LOCAL_SCRATCH_OFFSET,
|
||||
.d_CPU_CLOCK_OFFSET = CPU_CLOCK_OFFSET,
|
||||
.d_LPO_CAL_OFFSET = LPO_CAL_OFFSET,
|
||||
.d_GPIO_PIN10_OFFSET = GPIO_PIN10_OFFSET,
|
||||
.d_GPIO_PIN11_OFFSET = GPIO_PIN11_OFFSET,
|
||||
.d_GPIO_PIN12_OFFSET = GPIO_PIN12_OFFSET,
|
||||
.d_GPIO_PIN13_OFFSET = GPIO_PIN13_OFFSET,
|
||||
.d_CLOCK_GPIO_OFFSET = CLOCK_GPIO_OFFSET,
|
||||
.d_CPU_CLOCK_STANDARD_LSB = CPU_CLOCK_STANDARD_LSB,
|
||||
.d_CPU_CLOCK_STANDARD_MASK = CPU_CLOCK_STANDARD_MASK,
|
||||
.d_LPO_CAL_ENABLE_LSB = LPO_CAL_ENABLE_LSB,
|
||||
.d_LPO_CAL_ENABLE_MASK = LPO_CAL_ENABLE_MASK,
|
||||
.d_CLOCK_GPIO_BT_CLK_OUT_EN_LSB = CLOCK_GPIO_BT_CLK_OUT_EN_LSB,
|
||||
.d_CLOCK_GPIO_BT_CLK_OUT_EN_MASK = CLOCK_GPIO_BT_CLK_OUT_EN_MASK,
|
||||
.d_ANALOG_INTF_BASE_ADDRESS = ANALOG_INTF_BASE_ADDRESS,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#if MY_TARGET_BOARD_DATA_SZ > BOARD_DATA_SZ_MAX
|
||||
#error "BOARD_DATA_SZ_MAX is too small"
|
||||
#endif
|
||||
|
||||
struct targetdef_s *MY_TARGET_DEF = &my_target_def;
|
||||
|
||||
#else /* } { */
|
||||
|
||||
#define RTC_SOC_BASE_ADDRESS (targetdef->d_RTC_SOC_BASE_ADDRESS)
|
||||
#define RTC_WMAC_BASE_ADDRESS (targetdef->d_RTC_WMAC_BASE_ADDRESS)
|
||||
#define SYSTEM_SLEEP_OFFSET (targetdef->d_SYSTEM_SLEEP_OFFSET)
|
||||
#define WLAN_SYSTEM_SLEEP_OFFSET (targetdef->d_WLAN_SYSTEM_SLEEP_OFFSET)
|
||||
#define WLAN_SYSTEM_SLEEP_DISABLE_LSB (targetdef->d_WLAN_SYSTEM_SLEEP_DISABLE_LSB)
|
||||
#define WLAN_SYSTEM_SLEEP_DISABLE_MASK (targetdef->d_WLAN_SYSTEM_SLEEP_DISABLE_MASK)
|
||||
#define CLOCK_CONTROL_OFFSET (targetdef->d_CLOCK_CONTROL_OFFSET)
|
||||
#define CLOCK_CONTROL_SI0_CLK_MASK (targetdef->d_CLOCK_CONTROL_SI0_CLK_MASK)
|
||||
#define RESET_CONTROL_OFFSET (targetdef->d_RESET_CONTROL_OFFSET)
|
||||
#define RESET_CONTROL_MBOX_RST_MASK (targetdef->d_RESET_CONTROL_MBOX_RST_MASK)
|
||||
#define RESET_CONTROL_SI0_RST_MASK (targetdef->d_RESET_CONTROL_SI0_RST_MASK)
|
||||
#define WLAN_RESET_CONTROL_OFFSET (targetdef->d_WLAN_RESET_CONTROL_OFFSET)
|
||||
#define WLAN_RESET_CONTROL_COLD_RST_MASK (targetdef->d_WLAN_RESET_CONTROL_COLD_RST_MASK)
|
||||
#define WLAN_RESET_CONTROL_WARM_RST_MASK (targetdef->d_WLAN_RESET_CONTROL_WARM_RST_MASK)
|
||||
#define GPIO_BASE_ADDRESS (targetdef->d_GPIO_BASE_ADDRESS)
|
||||
#define GPIO_PIN0_OFFSET (targetdef->d_GPIO_PIN0_OFFSET)
|
||||
#define GPIO_PIN1_OFFSET (targetdef->d_GPIO_PIN1_OFFSET)
|
||||
#define GPIO_PIN0_CONFIG_MASK (targetdef->d_GPIO_PIN0_CONFIG_MASK)
|
||||
#define GPIO_PIN1_CONFIG_MASK (targetdef->d_GPIO_PIN1_CONFIG_MASK)
|
||||
#define SI_CONFIG_BIDIR_OD_DATA_LSB (targetdef->d_SI_CONFIG_BIDIR_OD_DATA_LSB)
|
||||
#define SI_CONFIG_BIDIR_OD_DATA_MASK (targetdef->d_SI_CONFIG_BIDIR_OD_DATA_MASK)
|
||||
#define SI_CONFIG_I2C_LSB (targetdef->d_SI_CONFIG_I2C_LSB)
|
||||
#define SI_CONFIG_I2C_MASK (targetdef->d_SI_CONFIG_I2C_MASK)
|
||||
#define SI_CONFIG_POS_SAMPLE_LSB (targetdef->d_SI_CONFIG_POS_SAMPLE_LSB)
|
||||
#define SI_CONFIG_POS_SAMPLE_MASK (targetdef->d_SI_CONFIG_POS_SAMPLE_MASK)
|
||||
#define SI_CONFIG_INACTIVE_CLK_LSB (targetdef->d_SI_CONFIG_INACTIVE_CLK_LSB)
|
||||
#define SI_CONFIG_INACTIVE_CLK_MASK (targetdef->d_SI_CONFIG_INACTIVE_CLK_MASK)
|
||||
#define SI_CONFIG_INACTIVE_DATA_LSB (targetdef->d_SI_CONFIG_INACTIVE_DATA_LSB)
|
||||
#define SI_CONFIG_INACTIVE_DATA_MASK (targetdef->d_SI_CONFIG_INACTIVE_DATA_MASK)
|
||||
#define SI_CONFIG_DIVIDER_LSB (targetdef->d_SI_CONFIG_DIVIDER_LSB)
|
||||
#define SI_CONFIG_DIVIDER_MASK (targetdef->d_SI_CONFIG_DIVIDER_MASK)
|
||||
#define SI_BASE_ADDRESS (targetdef->d_SI_BASE_ADDRESS)
|
||||
#define SI_CONFIG_OFFSET (targetdef->d_SI_CONFIG_OFFSET)
|
||||
#define SI_TX_DATA0_OFFSET (targetdef->d_SI_TX_DATA0_OFFSET)
|
||||
#define SI_TX_DATA1_OFFSET (targetdef->d_SI_TX_DATA1_OFFSET)
|
||||
#define SI_RX_DATA0_OFFSET (targetdef->d_SI_RX_DATA0_OFFSET)
|
||||
#define SI_RX_DATA1_OFFSET (targetdef->d_SI_RX_DATA1_OFFSET)
|
||||
#define SI_CS_OFFSET (targetdef->d_SI_CS_OFFSET)
|
||||
#define SI_CS_DONE_ERR_MASK (targetdef->d_SI_CS_DONE_ERR_MASK)
|
||||
#define SI_CS_DONE_INT_MASK (targetdef->d_SI_CS_DONE_INT_MASK)
|
||||
#define SI_CS_START_LSB (targetdef->d_SI_CS_START_LSB)
|
||||
#define SI_CS_START_MASK (targetdef->d_SI_CS_START_MASK)
|
||||
#define SI_CS_RX_CNT_LSB (targetdef->d_SI_CS_RX_CNT_LSB)
|
||||
#define SI_CS_RX_CNT_MASK (targetdef->d_SI_CS_RX_CNT_MASK)
|
||||
#define SI_CS_TX_CNT_LSB (targetdef->d_SI_CS_TX_CNT_LSB)
|
||||
#define SI_CS_TX_CNT_MASK (targetdef->d_SI_CS_TX_CNT_MASK)
|
||||
#define EEPROM_SZ (targetdef->d_BOARD_DATA_SZ)
|
||||
#define EEPROM_EXT_SZ (targetdef->d_BOARD_EXT_DATA_SZ)
|
||||
#define MBOX_BASE_ADDRESS (targetdef->d_MBOX_BASE_ADDRESS)
|
||||
#define LOCAL_SCRATCH_OFFSET (targetdef->d_LOCAL_SCRATCH_OFFSET)
|
||||
#define CPU_CLOCK_OFFSET (targetdef->d_CPU_CLOCK_OFFSET)
|
||||
#define LPO_CAL_OFFSET (targetdef->d_LPO_CAL_OFFSET)
|
||||
#define GPIO_PIN10_OFFSET (targetdef->d_GPIO_PIN10_OFFSET)
|
||||
#define GPIO_PIN11_OFFSET (targetdef->d_GPIO_PIN11_OFFSET)
|
||||
#define GPIO_PIN12_OFFSET (targetdef->d_GPIO_PIN12_OFFSET)
|
||||
#define GPIO_PIN13_OFFSET (targetdef->d_GPIO_PIN13_OFFSET)
|
||||
#define CLOCK_GPIO_OFFSET (targetdef->d_CLOCK_GPIO_OFFSET)
|
||||
#define CPU_CLOCK_STANDARD_LSB (targetdef->d_CPU_CLOCK_STANDARD_LSB)
|
||||
#define CPU_CLOCK_STANDARD_MASK (targetdef->d_CPU_CLOCK_STANDARD_MASK)
|
||||
#define LPO_CAL_ENABLE_LSB (targetdef->d_LPO_CAL_ENABLE_LSB)
|
||||
#define LPO_CAL_ENABLE_MASK (targetdef->d_LPO_CAL_ENABLE_MASK)
|
||||
#define CLOCK_GPIO_BT_CLK_OUT_EN_LSB (targetdef->d_CLOCK_GPIO_BT_CLK_OUT_EN_LSB)
|
||||
#define CLOCK_GPIO_BT_CLK_OUT_EN_MASK (targetdef->d_CLOCK_GPIO_BT_CLK_OUT_EN_MASK)
|
||||
#define ANALOG_INTF_BASE_ADDRESS (targetdef->d_ANALOG_INTF_BASE_ADDRESS)
|
||||
|
||||
/* SET macros */
|
||||
#define WLAN_SYSTEM_SLEEP_DISABLE_SET(x) (((x) << WLAN_SYSTEM_SLEEP_DISABLE_LSB) & WLAN_SYSTEM_SLEEP_DISABLE_MASK)
|
||||
#define SI_CONFIG_BIDIR_OD_DATA_SET(x) (((x) << SI_CONFIG_BIDIR_OD_DATA_LSB) & SI_CONFIG_BIDIR_OD_DATA_MASK)
|
||||
#define SI_CONFIG_I2C_SET(x) (((x) << SI_CONFIG_I2C_LSB) & SI_CONFIG_I2C_MASK)
|
||||
#define SI_CONFIG_POS_SAMPLE_SET(x) (((x) << SI_CONFIG_POS_SAMPLE_LSB) & SI_CONFIG_POS_SAMPLE_MASK)
|
||||
#define SI_CONFIG_INACTIVE_CLK_SET(x) (((x) << SI_CONFIG_INACTIVE_CLK_LSB) & SI_CONFIG_INACTIVE_CLK_MASK)
|
||||
#define SI_CONFIG_INACTIVE_DATA_SET(x) (((x) << SI_CONFIG_INACTIVE_DATA_LSB) & SI_CONFIG_INACTIVE_DATA_MASK)
|
||||
#define SI_CONFIG_DIVIDER_SET(x) (((x) << SI_CONFIG_DIVIDER_LSB) & SI_CONFIG_DIVIDER_MASK)
|
||||
#define SI_CS_START_SET(x) (((x) << SI_CS_START_LSB) & SI_CS_START_MASK)
|
||||
#define SI_CS_RX_CNT_SET(x) (((x) << SI_CS_RX_CNT_LSB) & SI_CS_RX_CNT_MASK)
|
||||
#define SI_CS_TX_CNT_SET(x) (((x) << SI_CS_TX_CNT_LSB) & SI_CS_TX_CNT_MASK)
|
||||
#define LPO_CAL_ENABLE_SET(x) (((x) << LPO_CAL_ENABLE_LSB) & LPO_CAL_ENABLE_MASK)
|
||||
#define CPU_CLOCK_STANDARD_SET(x) (((x) << CPU_CLOCK_STANDARD_LSB) & CPU_CLOCK_STANDARD_MASK)
|
||||
#define CLOCK_GPIO_BT_CLK_OUT_EN_SET(x) (((x) << CLOCK_GPIO_BT_CLK_OUT_EN_LSB) & CLOCK_GPIO_BT_CLK_OUT_EN_MASK)
|
||||
extern struct targetdef_s *targetdef;
|
||||
|
||||
#endif /* } */
|
||||
|
||||
#endif /*TARGET_REG_TABLE_H_*/
|
||||
103
drivers/net/wireless/ar6003/host/include/utils_api.h
Normal file
103
drivers/net/wireless/ar6003/host/include/utils_api.h
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <copyright file="utils_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.
|
||||
//
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
//==============================================================================
|
||||
// Utility Macros & Functions common across OS.
|
||||
// Author(s): ="Atheros"
|
||||
//==============================================================================
|
||||
#ifndef _HOST_UTILS_API_H_
|
||||
#define _HOST_UTILS_API_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* unaligned little endian access */
|
||||
#define LE_READ_2(p) \
|
||||
((A_UINT16) \
|
||||
((((A_UINT8 *)(p))[0] ) | (((A_UINT8 *)(p))[1] << 8)))
|
||||
|
||||
#define LE_READ_4(p) \
|
||||
((A_UINT32) \
|
||||
((((A_UINT8 *)(p))[0] ) | (((A_UINT8 *)(p))[1] << 8) | \
|
||||
(((A_UINT8 *)(p))[2] << 16) | (((A_UINT8 *)(p))[3] << 24)))
|
||||
|
||||
#define WPA_GET_BE16(a) ((A_UINT16) (((a)[0] << 8) | (a)[1]))
|
||||
#define WPA_PUT_BE16(a, val) \
|
||||
do { \
|
||||
(a)[0] = ((A_UINT16) (val)) >> 8; \
|
||||
(a)[1] = ((A_UINT16) (val)) & 0xff; \
|
||||
} while (0)
|
||||
|
||||
#define WPA_GET_LE16(a) ((A_UINT16) (((a)[1] << 8) | (a)[0]))
|
||||
#define WPA_PUT_LE16(a, val) \
|
||||
do { \
|
||||
(a)[1] = ((A_UINT16) (val)) >> 8; \
|
||||
(a)[0] = ((A_UINT16) (val)) & 0xff; \
|
||||
} while (0)
|
||||
|
||||
#define WPA_GET_BE24(a) ((((A_UINT32) (a)[0]) << 16) | (((A_UINT32) (a)[1]) << 8) | \
|
||||
((A_UINT32) (a)[2]))
|
||||
#define WPA_PUT_BE24(a, val) \
|
||||
do { \
|
||||
(a)[0] = (A_UINT8) ((((A_UINT32) (val)) >> 16) & 0xff); \
|
||||
(a)[1] = (A_UINT8) ((((A_UINT32) (val)) >> 8) & 0xff); \
|
||||
(a)[2] = (A_UINT8) (((A_UINT32) (val)) & 0xff); \
|
||||
} while (0)
|
||||
|
||||
#define WPA_GET_BE32(a) ((((A_UINT32) (a)[0]) << 24) | (((A_UINT32) (a)[1]) << 16) | \
|
||||
(((A_UINT32) (a)[2]) << 8) | ((A_UINT32) (a)[3]))
|
||||
#define WPA_PUT_BE32(a, val) \
|
||||
do { \
|
||||
(a)[0] = (A_UINT8) ((((A_UINT32) (val)) >> 24) & 0xff); \
|
||||
(a)[1] = (A_UINT8) ((((A_UINT32) (val)) >> 16) & 0xff); \
|
||||
(a)[2] = (A_UINT8) ((((A_UINT32) (val)) >> 8) & 0xff); \
|
||||
(a)[3] = (A_UINT8) (((A_UINT32) (val)) & 0xff); \
|
||||
} while (0)
|
||||
|
||||
#define WPA_GET_LE32(a) ((((A_UINT32) (a)[3]) << 24) | (((A_UINT32) (a)[2]) << 16) | \
|
||||
(((A_UINT32) (a)[1]) << 8) | ((A_UINT32) (a)[0]))
|
||||
#define WPA_PUT_LE32(a, val) \
|
||||
do { \
|
||||
(a)[3] = (A_UINT8) ((((A_UINT32) (val)) >> 24) & 0xff); \
|
||||
(a)[2] = (A_UINT8) ((((A_UINT32) (val)) >> 16) & 0xff); \
|
||||
(a)[1] = (A_UINT8) ((((A_UINT32) (val)) >> 8) & 0xff); \
|
||||
(a)[0] = (A_UINT8) (((A_UINT32) (val)) & 0xff); \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define WPA_OUI 0xf25000
|
||||
|
||||
static int __inline
|
||||
iswscoui(const A_UINT8 *frm)
|
||||
{
|
||||
return frm[1] > 3 && LE_READ_4(frm+2) == ((0x04<<24)|WPA_OUI);
|
||||
}
|
||||
|
||||
static inline int is_zero_mac_addr(const A_UINT8 *addr)
|
||||
{
|
||||
return !(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]);
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _HOST_UTILS_API_H_ */
|
||||
137
drivers/net/wireless/ar6003/host/include/wlan_api.h
Normal file
137
drivers/net/wireless/ar6003/host/include/wlan_api.h
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// 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 {
|
||||
A_UINT16 ie_chan;
|
||||
A_UINT8 *ie_tstamp;
|
||||
A_UINT8 *ie_ssid;
|
||||
A_UINT8 *ie_rates;
|
||||
A_UINT8 *ie_xrates;
|
||||
A_UINT8 *ie_country;
|
||||
A_UINT8 *ie_wpa;
|
||||
A_UINT8 *ie_rsn;
|
||||
A_UINT8 *ie_wmm;
|
||||
A_UINT8 *ie_ath;
|
||||
A_UINT16 ie_capInfo;
|
||||
A_UINT16 ie_beaconInt;
|
||||
A_UINT8 *ie_tim;
|
||||
A_UINT8 *ie_chswitch;
|
||||
A_UINT8 ie_erp;
|
||||
A_UINT8 *ie_wsc;
|
||||
A_UINT8 *ie_htcap;
|
||||
A_UINT8 *ie_htop;
|
||||
#ifdef WAPI_ENABLE
|
||||
A_UINT8 *ie_wapi;
|
||||
#endif
|
||||
|
||||
|
||||
};
|
||||
|
||||
typedef struct bss {
|
||||
A_UINT8 ni_macaddr[6];
|
||||
A_UINT8 ni_snr;
|
||||
A_INT16 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;
|
||||
#ifdef P2P
|
||||
void *p2p_dev;
|
||||
#endif /* P2P */
|
||||
A_UINT8 *ni_buf;
|
||||
A_UINT16 ni_framelen;
|
||||
A_UINT8 ni_frametype; /* frame type in ni_buf */
|
||||
struct ieee80211_node_table *ni_table;
|
||||
A_UINT32 ni_refcnt;
|
||||
int ni_scangen;
|
||||
|
||||
A_UINT32 ni_tstamp;
|
||||
A_UINT32 ni_actcnt;
|
||||
#ifdef OS_ROAM_MANAGEMENT
|
||||
A_UINT32 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 A_UINT8 *macaddr);
|
||||
bss_t *wlan_find_node(struct ieee80211_node_table *nt, const A_UINT8 *macaddr);
|
||||
void wlan_node_reclaim(struct ieee80211_node_table *nt, bss_t *ni);
|
||||
A_STATUS wlan_node_buf_update(struct ieee80211_node_table *nt, bss_t *ni, A_UINT32 len);
|
||||
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);
|
||||
|
||||
A_STATUS wlan_parse_beacon(A_UINT8 *buf, int framelen,
|
||||
struct ieee80211_common_ie *cie);
|
||||
|
||||
A_UINT16 wlan_ieee2freq(int chan);
|
||||
A_UINT32 wlan_freq2ieee(A_UINT16 freq);
|
||||
|
||||
void wlan_set_nodeage(struct ieee80211_node_table *nt, A_UINT32 nodeAge);
|
||||
|
||||
void
|
||||
wlan_refresh_inactive_nodes (struct ieee80211_node_table *nt);
|
||||
|
||||
bss_t *
|
||||
wlan_find_Ssidnode (struct ieee80211_node_table *nt, A_UCHAR *pSsid,
|
||||
A_UINT32 ssidLength, A_BOOL bIsWPA2, A_BOOL bMatchSSID);
|
||||
|
||||
void
|
||||
wlan_node_return (struct ieee80211_node_table *nt, bss_t *ni);
|
||||
|
||||
bss_t *wlan_node_remove(struct ieee80211_node_table *nt, A_UINT8 *bssid);
|
||||
|
||||
bss_t *
|
||||
wlan_find_matching_Ssidnode (struct ieee80211_node_table *nt, A_UCHAR *pSsid,
|
||||
A_UINT32 ssidLength, A_UINT32 dot11AuthMode, A_UINT32 authMode,
|
||||
A_UINT32 pairwiseCryptoType, A_UINT32 grpwiseCryptoTyp);
|
||||
|
||||
void wlan_node_update_timestamp(struct ieee80211_node_table *nt, bss_t *ni);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _HOST_WLAN_API_H_ */
|
||||
565
drivers/net/wireless/ar6003/host/include/wmi_api.h
Normal file
565
drivers/net/wireless/ar6003/host/include/wmi_api.h
Normal file
|
|
@ -0,0 +1,565 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <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, int devid);
|
||||
|
||||
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);
|
||||
A_UINT16 wmi_get_mapped_qos_queue(struct wmi_t *, A_UINT8);
|
||||
A_STATUS wmi_dix_2_dot3(struct wmi_t *wmip, void *osbuf);
|
||||
A_STATUS wmi_data_hdr_add(struct wmi_t *wmip, void *osbuf, A_UINT8 msgType, A_UINT32 flags , WMI_DATA_HDR_DATA_TYPE data_type,A_UINT8 metaVersion, void *pTxMetaS);
|
||||
A_STATUS wmi_dot3_2_dix(void *osbuf);
|
||||
|
||||
A_STATUS wmi_dot11_hdr_remove (struct wmi_t *wmip, void *osbuf);
|
||||
A_STATUS wmi_dot11_hdr_add(struct wmi_t *wmip, void *osbuf, NETWORK_TYPE mode);
|
||||
|
||||
A_STATUS wmi_data_hdr_remove(struct wmi_t *wmip, void *osbuf);
|
||||
A_STATUS wmi_syncpoint(struct wmi_t *wmip);
|
||||
A_STATUS wmi_syncpoint_reset(struct wmi_t *wmip);
|
||||
A_UINT8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, A_UINT32 layer2Priority, A_BOOL wmmEnabled);
|
||||
|
||||
A_UINT8 wmi_determine_userPriority (A_UINT8 *pkt, A_UINT32 layer2Pri);
|
||||
|
||||
A_STATUS 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 A_UINT8 *macaddr);
|
||||
void wmi_free_node(struct wmi_t *wmip, const A_UINT8 *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;
|
||||
|
||||
A_STATUS wmi_cmd_send(struct wmi_t *wmip, void *osbuf, WMI_COMMAND_ID cmdId,
|
||||
WMI_SYNC_FLAG flag);
|
||||
|
||||
A_STATUS wmi_connect_cmd(struct wmi_t *wmip,
|
||||
NETWORK_TYPE netType,
|
||||
DOT11_AUTH_MODE dot11AuthMode,
|
||||
AUTH_MODE authMode,
|
||||
CRYPTO_TYPE pairwiseCrypto,
|
||||
A_UINT8 pairwiseCryptoLen,
|
||||
CRYPTO_TYPE groupCrypto,
|
||||
A_UINT8 groupCryptoLen,
|
||||
int ssidLength,
|
||||
A_UCHAR *ssid,
|
||||
A_UINT8 *bssid,
|
||||
A_UINT16 channel,
|
||||
A_UINT32 ctrl_flags);
|
||||
|
||||
A_STATUS wmi_set_div_param_cmd(struct wmi_t *wmip, A_UINT32 divIdleTime,
|
||||
A_UINT8 antRssiThresh, A_UINT8 divEnable, A_UINT16 active_treshold_rate);
|
||||
|
||||
|
||||
A_STATUS wmi_reconnect_cmd(struct wmi_t *wmip,
|
||||
A_UINT8 *bssid,
|
||||
A_UINT16 channel);
|
||||
A_STATUS wmi_disconnect_cmd(struct wmi_t *wmip);
|
||||
A_STATUS wmi_getrev_cmd(struct wmi_t *wmip);
|
||||
A_STATUS wmi_startscan_cmd(struct wmi_t *wmip, WMI_SCAN_TYPE scanType,
|
||||
A_BOOL forceFgScan, A_BOOL isLegacy,
|
||||
A_UINT32 homeDwellTime, A_UINT32 forceScanInterval,
|
||||
A_INT8 numChan, A_UINT16 *channelList);
|
||||
A_STATUS wmi_scanparams_cmd(struct wmi_t *wmip, A_UINT16 fg_start_sec,
|
||||
A_UINT16 fg_end_sec, A_UINT16 bg_sec,
|
||||
A_UINT16 minact_chdw_msec,
|
||||
A_UINT16 maxact_chdw_msec, A_UINT16 pas_chdw_msec,
|
||||
A_UINT8 shScanRatio, A_UINT8 scanCtrlFlags,
|
||||
A_UINT32 max_dfsch_act_time,
|
||||
A_UINT16 maxact_scan_per_ssid);
|
||||
A_STATUS wmi_bssfilter_cmd(struct wmi_t *wmip, A_UINT8 filter, A_UINT32 ieMask);
|
||||
A_STATUS wmi_probedSsid_cmd(struct wmi_t *wmip, A_UINT8 index, A_UINT8 flag,
|
||||
A_UINT8 ssidLength, A_UCHAR *ssid);
|
||||
A_STATUS wmi_listeninterval_cmd(struct wmi_t *wmip, A_UINT16 listenInterval, A_UINT16 listenBeacons);
|
||||
A_STATUS wmi_bmisstime_cmd(struct wmi_t *wmip, A_UINT16 bmisstime, A_UINT16 bmissbeacons);
|
||||
A_STATUS wmi_associnfo_cmd(struct wmi_t *wmip, A_UINT8 ieType,
|
||||
A_UINT8 ieLen, A_UINT8 *ieInfo);
|
||||
A_STATUS wmi_powermode_cmd(struct wmi_t *wmip, A_UINT8 powerMode);
|
||||
A_STATUS wmi_ibsspmcaps_cmd(struct wmi_t *wmip, A_UINT8 pmEnable, A_UINT8 ttl,
|
||||
A_UINT16 atim_windows, A_UINT16 timeout_value);
|
||||
A_STATUS wmi_apps_cmd(struct wmi_t *wmip, A_UINT8 psType, A_UINT32 idle_time,
|
||||
A_UINT32 ps_period, A_UINT8 sleep_period);
|
||||
A_STATUS wmi_pmparams_cmd(struct wmi_t *wmip, A_UINT16 idlePeriod,
|
||||
A_UINT16 psPollNum, A_UINT16 dtimPolicy,
|
||||
A_UINT16 wakup_tx_policy, A_UINT16 num_tx_to_wakeup,
|
||||
A_UINT16 ps_fail_event_policy);
|
||||
A_STATUS wmi_disctimeout_cmd(struct wmi_t *wmip, A_UINT8 timeout);
|
||||
A_STATUS wmi_sync_cmd(struct wmi_t *wmip, A_UINT8 syncNumber);
|
||||
A_STATUS wmi_create_pstream_cmd(struct wmi_t *wmip, WMI_CREATE_PSTREAM_CMD *pstream);
|
||||
A_STATUS wmi_delete_pstream_cmd(struct wmi_t *wmip, A_UINT8 trafficClass, A_UINT8 streamID);
|
||||
A_STATUS wmi_set_framerate_cmd(struct wmi_t *wmip, A_UINT8 bEnable, A_UINT8 type, A_UINT8 subType, A_UINT16 rateMask);
|
||||
A_STATUS wmi_set_bitrate_cmd(struct wmi_t *wmip, A_INT32 dataRate, A_INT32 mgmtRate, A_INT32 ctlRate);
|
||||
A_STATUS wmi_get_bitrate_cmd(struct wmi_t *wmip);
|
||||
A_INT8 wmi_validate_bitrate(struct wmi_t *wmip, A_INT32 rate, A_INT8 *rate_idx);
|
||||
A_STATUS wmi_get_regDomain_cmd(struct wmi_t *wmip);
|
||||
A_STATUS wmi_get_channelList_cmd(struct wmi_t *wmip);
|
||||
A_STATUS wmi_set_channelParams_cmd(struct wmi_t *wmip, A_UINT8 scanParam,
|
||||
WMI_PHY_MODE mode, A_INT8 numChan,
|
||||
A_UINT16 *channelList);
|
||||
|
||||
A_STATUS wmi_set_snr_threshold_params(struct wmi_t *wmip,
|
||||
WMI_SNR_THRESHOLD_PARAMS_CMD *snrCmd);
|
||||
A_STATUS wmi_set_rssi_threshold_params(struct wmi_t *wmip,
|
||||
WMI_RSSI_THRESHOLD_PARAMS_CMD *rssiCmd);
|
||||
A_STATUS wmi_clr_rssi_snr(struct wmi_t *wmip);
|
||||
A_STATUS wmi_set_lq_threshold_params(struct wmi_t *wmip,
|
||||
WMI_LQ_THRESHOLD_PARAMS_CMD *lqCmd);
|
||||
A_STATUS wmi_set_rts_cmd(struct wmi_t *wmip, A_UINT16 threshold);
|
||||
A_STATUS wmi_set_lpreamble_cmd(struct wmi_t *wmip, A_UINT8 status, A_UINT8 preamblePolicy);
|
||||
|
||||
A_STATUS wmi_set_error_report_bitmask(struct wmi_t *wmip, A_UINT32 bitmask);
|
||||
|
||||
A_STATUS wmi_get_challenge_resp_cmd(struct wmi_t *wmip, A_UINT32 cookie,
|
||||
A_UINT32 source);
|
||||
|
||||
A_STATUS wmi_config_debug_module_cmd(struct wmi_t *wmip, A_UINT16 mmask,
|
||||
A_UINT16 tsr, A_BOOL rep, A_UINT16 size,
|
||||
A_UINT32 valid);
|
||||
|
||||
A_STATUS wmi_get_stats_cmd(struct wmi_t *wmip);
|
||||
|
||||
A_STATUS wmi_addKey_cmd(struct wmi_t *wmip, A_UINT8 keyIndex,
|
||||
CRYPTO_TYPE keyType, A_UINT8 keyUsage,
|
||||
A_UINT8 keyLength,A_UINT8 *keyRSC,
|
||||
A_UINT8 *keyMaterial, A_UINT8 key_op_ctrl, A_UINT8 *mac,
|
||||
WMI_SYNC_FLAG sync_flag);
|
||||
A_STATUS wmi_add_krk_cmd(struct wmi_t *wmip, A_UINT8 *krk);
|
||||
A_STATUS wmi_delete_krk_cmd(struct wmi_t *wmip);
|
||||
A_STATUS wmi_deleteKey_cmd(struct wmi_t *wmip, A_UINT8 keyIndex);
|
||||
A_STATUS wmi_set_akmp_params_cmd(struct wmi_t *wmip,
|
||||
WMI_SET_AKMP_PARAMS_CMD *akmpParams);
|
||||
A_STATUS wmi_get_pmkid_list_cmd(struct wmi_t *wmip);
|
||||
A_STATUS wmi_set_pmkid_list_cmd(struct wmi_t *wmip,
|
||||
WMI_SET_PMKID_LIST_CMD *pmkInfo);
|
||||
A_STATUS wmi_abort_scan_cmd(struct wmi_t *wmip);
|
||||
A_STATUS wmi_set_txPwr_cmd(struct wmi_t *wmip, A_UINT8 dbM);
|
||||
A_STATUS wmi_get_txPwr_cmd(struct wmi_t *wmip);
|
||||
A_STATUS wmi_addBadAp_cmd(struct wmi_t *wmip, A_UINT8 apIndex, A_UINT8 *bssid);
|
||||
A_STATUS wmi_deleteBadAp_cmd(struct wmi_t *wmip, A_UINT8 apIndex);
|
||||
A_STATUS wmi_set_tkip_countermeasures_cmd(struct wmi_t *wmip, A_BOOL en);
|
||||
A_STATUS wmi_setPmkid_cmd(struct wmi_t *wmip, A_UINT8 *bssid, A_UINT8 *pmkId,
|
||||
A_BOOL set);
|
||||
A_STATUS wmi_set_access_params_cmd(struct wmi_t *wmip, A_UINT8 ac, A_UINT16 txop,
|
||||
A_UINT8 eCWmin, A_UINT8 eCWmax,
|
||||
A_UINT8 aifsn);
|
||||
A_STATUS wmi_set_retry_limits_cmd(struct wmi_t *wmip, A_UINT8 frameType,
|
||||
A_UINT8 trafficClass, A_UINT8 maxRetries,
|
||||
A_UINT8 enableNotify);
|
||||
|
||||
void wmi_get_current_bssid(struct wmi_t *wmip, A_UINT8 *bssid);
|
||||
|
||||
A_STATUS wmi_get_roam_tbl_cmd(struct wmi_t *wmip);
|
||||
A_STATUS wmi_get_roam_data_cmd(struct wmi_t *wmip, A_UINT8 roamDataType);
|
||||
A_STATUS wmi_set_roam_ctrl_cmd(struct wmi_t *wmip, WMI_SET_ROAM_CTRL_CMD *p,
|
||||
A_UINT8 size);
|
||||
A_STATUS wmi_set_powersave_timers_cmd(struct wmi_t *wmip,
|
||||
WMI_POWERSAVE_TIMERS_POLICY_CMD *pCmd,
|
||||
A_UINT8 size);
|
||||
|
||||
A_STATUS wmi_set_opt_mode_cmd(struct wmi_t *wmip, A_UINT8 optMode);
|
||||
A_STATUS wmi_opt_tx_frame_cmd(struct wmi_t *wmip,
|
||||
A_UINT8 frmType,
|
||||
A_UINT8 *dstMacAddr,
|
||||
A_UINT8 *bssid,
|
||||
A_UINT16 optIEDataLen,
|
||||
A_UINT8 *optIEData);
|
||||
|
||||
A_STATUS wmi_set_adhoc_bconIntvl_cmd(struct wmi_t *wmip, A_UINT16 intvl);
|
||||
A_STATUS wmi_set_voice_pkt_size_cmd(struct wmi_t *wmip, A_UINT16 voicePktSize);
|
||||
A_STATUS wmi_set_max_sp_len_cmd(struct wmi_t *wmip, A_UINT8 maxSpLen);
|
||||
A_UINT8 convert_userPriority_to_trafficClass(A_UINT8 userPriority);
|
||||
A_UINT8 wmi_get_power_mode_cmd(struct wmi_t *wmip);
|
||||
A_STATUS wmi_verify_tspec_params(WMI_CREATE_PSTREAM_CMD *pCmd, A_BOOL tspecCompliance);
|
||||
|
||||
#ifdef CONFIG_HOST_TCMD_SUPPORT
|
||||
A_STATUS wmi_test_cmd(struct wmi_t *wmip, A_UINT8 *buf, A_UINT32 len);
|
||||
#endif
|
||||
|
||||
A_STATUS wmi_set_bt_status_cmd(struct wmi_t *wmip, A_UINT8 streamType, A_UINT8 status);
|
||||
A_STATUS wmi_set_bt_params_cmd(struct wmi_t *wmip, WMI_SET_BT_PARAMS_CMD* cmd);
|
||||
|
||||
A_STATUS wmi_set_btcoex_fe_ant_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_FE_ANT_CMD * cmd);
|
||||
|
||||
A_STATUS wmi_set_btcoex_colocated_bt_dev_cmd(struct wmi_t *wmip,
|
||||
WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMD * cmd);
|
||||
|
||||
A_STATUS wmi_set_btcoex_btinquiry_page_config_cmd(struct wmi_t *wmip,
|
||||
WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMD *cmd);
|
||||
|
||||
A_STATUS wmi_set_btcoex_sco_config_cmd(struct wmi_t *wmip,
|
||||
WMI_SET_BTCOEX_SCO_CONFIG_CMD * cmd);
|
||||
|
||||
A_STATUS wmi_set_btcoex_a2dp_config_cmd(struct wmi_t *wmip,
|
||||
WMI_SET_BTCOEX_A2DP_CONFIG_CMD* cmd);
|
||||
|
||||
|
||||
A_STATUS wmi_set_btcoex_aclcoex_config_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMD* cmd);
|
||||
|
||||
A_STATUS wmi_set_btcoex_debug_cmd(struct wmi_t *wmip, WMI_SET_BTCOEX_DEBUG_CMD * cmd);
|
||||
|
||||
A_STATUS wmi_set_btcoex_bt_operating_status_cmd(struct wmi_t * wmip,
|
||||
WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMD * cmd);
|
||||
|
||||
A_STATUS wmi_get_btcoex_config_cmd(struct wmi_t * wmip, WMI_GET_BTCOEX_CONFIG_CMD * cmd);
|
||||
|
||||
A_STATUS wmi_get_btcoex_stats_cmd(struct wmi_t * wmip);
|
||||
|
||||
A_STATUS wmi_SGI_cmd(struct wmi_t *wmip, A_UINT32 *sgiMask, A_UINT8 sgiPERThreshold);
|
||||
|
||||
/*
|
||||
* This function is used to configure the fix rates mask to the target.
|
||||
*/
|
||||
A_STATUS wmi_set_fixrates_cmd(struct wmi_t *wmip, A_UINT32 *fixRatesMask);
|
||||
A_STATUS wmi_get_ratemask_cmd(struct wmi_t *wmip);
|
||||
|
||||
A_STATUS wmi_set_authmode_cmd(struct wmi_t *wmip, A_UINT8 mode);
|
||||
|
||||
A_STATUS wmi_set_reassocmode_cmd(struct wmi_t *wmip, A_UINT8 mode);
|
||||
|
||||
A_STATUS wmi_set_qos_supp_cmd(struct wmi_t *wmip,A_UINT8 status);
|
||||
A_STATUS wmi_set_wmm_cmd(struct wmi_t *wmip, WMI_WMM_STATUS status);
|
||||
A_STATUS wmi_set_wmm_txop(struct wmi_t *wmip, WMI_TXOP_CFG txEnable);
|
||||
A_STATUS wmi_set_country(struct wmi_t *wmip, A_UCHAR *countryCode);
|
||||
|
||||
A_STATUS wmi_get_keepalive_configured(struct wmi_t *wmip);
|
||||
A_UINT8 wmi_get_keepalive_cmd(struct wmi_t *wmip);
|
||||
A_STATUS wmi_set_keepalive_cmd(struct wmi_t *wmip, A_UINT8 keepaliveInterval);
|
||||
|
||||
A_STATUS wmi_set_appie_cmd(struct wmi_t *wmip, A_UINT8 mgmtFrmType,
|
||||
A_UINT8 ieLen,A_UINT8 *ieInfo);
|
||||
|
||||
A_STATUS wmi_set_halparam_cmd(struct wmi_t *wmip, A_UINT8 *cmd, A_UINT16 dataLen);
|
||||
|
||||
A_INT32 wmi_get_rate(A_INT8 rateindex);
|
||||
|
||||
A_STATUS wmi_set_ip_cmd(struct wmi_t *wmip, WMI_SET_IP_CMD *cmd);
|
||||
|
||||
/*Wake on Wireless WMI commands*/
|
||||
A_STATUS wmi_set_host_sleep_mode_cmd(struct wmi_t *wmip, WMI_SET_HOST_SLEEP_MODE_CMD *cmd);
|
||||
A_STATUS wmi_set_wow_mode_cmd(struct wmi_t *wmip, WMI_SET_WOW_MODE_CMD *cmd);
|
||||
A_STATUS wmi_get_wow_list_cmd(struct wmi_t *wmip, WMI_GET_WOW_LIST_CMD *cmd);
|
||||
A_STATUS wmi_add_wow_pattern_cmd(struct wmi_t *wmip,
|
||||
WMI_ADD_WOW_PATTERN_CMD *cmd, A_UINT8* pattern, A_UINT8* mask, A_UINT8 pattern_size);
|
||||
A_STATUS wmi_del_wow_pattern_cmd(struct wmi_t *wmip,
|
||||
WMI_DEL_WOW_PATTERN_CMD *cmd);
|
||||
A_STATUS wmi_set_wsc_status_cmd(struct wmi_t *wmip, A_UINT32 status);
|
||||
|
||||
A_STATUS
|
||||
wmi_set_params_cmd(struct wmi_t *wmip, A_UINT32 opcode, A_UINT32 length, A_CHAR* buffer);
|
||||
|
||||
A_STATUS
|
||||
wmi_set_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 *filter);
|
||||
|
||||
A_STATUS
|
||||
wmi_del_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 *filter);
|
||||
|
||||
A_STATUS
|
||||
wmi_mcast_filter_cmd(struct wmi_t *wmip, A_UINT8 enable);
|
||||
|
||||
bss_t *
|
||||
wmi_find_Ssidnode (struct wmi_t *wmip, A_UCHAR *pSsid,
|
||||
A_UINT32 ssidLength, A_BOOL bIsWPA2, A_BOOL bMatchSSID);
|
||||
|
||||
|
||||
void
|
||||
wmi_node_return (struct wmi_t *wmip, bss_t *bss);
|
||||
|
||||
void
|
||||
wmi_node_update_timestamp(struct wmi_t *wmip, bss_t *bss);
|
||||
|
||||
void wmi_setup_node(struct wmi_t *wmip, bss_t *bss, const A_UINT8 *bssid);
|
||||
|
||||
bss_t *wmi_node_alloc(struct wmi_t *wmip, A_UINT8 len);
|
||||
|
||||
void
|
||||
wmi_set_nodeage(struct wmi_t *wmip, A_UINT32 nodeAge);
|
||||
|
||||
#if defined(CONFIG_TARGET_PROFILE_SUPPORT)
|
||||
A_STATUS wmi_prof_cfg_cmd(struct wmi_t *wmip, A_UINT32 period, A_UINT32 nbins);
|
||||
A_STATUS wmi_prof_addr_set_cmd(struct wmi_t *wmip, A_UINT32 addr);
|
||||
A_STATUS wmi_prof_start_cmd(struct wmi_t *wmip);
|
||||
A_STATUS wmi_prof_stop_cmd(struct wmi_t *wmip);
|
||||
A_STATUS 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
|
||||
|
||||
A_STATUS
|
||||
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, A_UINT8 *id);
|
||||
A_STATUS wmi_add_current_bss (struct wmi_t *wmip, A_UINT8 *id, bss_t *bss);
|
||||
|
||||
|
||||
/*
|
||||
* AP mode
|
||||
*/
|
||||
A_STATUS
|
||||
wmi_ap_profile_commit(struct wmi_t *wmip, WMI_CONNECT_CMD *p);
|
||||
|
||||
A_STATUS
|
||||
wmi_ap_set_hidden_ssid(struct wmi_t *wmip, A_UINT8 hidden_ssid);
|
||||
|
||||
A_STATUS
|
||||
wmi_ap_set_num_sta(struct wmi_t *wmip, A_UINT8 num_sta);
|
||||
|
||||
A_STATUS
|
||||
wmi_ap_set_dfs(struct wmi_t *wmip, A_UINT8 enable);
|
||||
|
||||
A_STATUS
|
||||
wmi_ap_set_acl_policy(struct wmi_t *wmip, A_UINT8 policy);
|
||||
|
||||
A_STATUS
|
||||
wmi_ap_acl_mac_list(struct wmi_t *wmip, WMI_AP_ACL_MAC_CMD *a);
|
||||
|
||||
A_UINT8
|
||||
acl_add_del_mac(WMI_AP_ACL *a, WMI_AP_ACL_MAC_CMD *acl);
|
||||
|
||||
A_STATUS
|
||||
wmi_ap_set_mlme(struct wmi_t *wmip, A_UINT8 cmd, A_UINT8 *mac, A_UINT16 reason);
|
||||
|
||||
A_STATUS
|
||||
wmi_set_pvb_cmd(struct wmi_t *wmip, A_UINT16 aid, A_BOOL flag);
|
||||
|
||||
A_STATUS
|
||||
wmi_ap_conn_inact_time(struct wmi_t *wmip, A_UINT32 period);
|
||||
|
||||
A_STATUS
|
||||
wmi_ap_bgscan_time(struct wmi_t *wmip, A_UINT32 period, A_UINT32 dwell);
|
||||
|
||||
A_STATUS
|
||||
wmi_ap_set_dtim(struct wmi_t *wmip, A_UINT8 dtim);
|
||||
|
||||
A_STATUS
|
||||
wmi_ap_set_rateset(struct wmi_t *wmip, A_UINT8 rateset);
|
||||
|
||||
A_STATUS
|
||||
wmi_set_ht_cap_cmd(struct wmi_t *wmip, WMI_SET_HT_CAP_CMD *cmd);
|
||||
|
||||
A_STATUS
|
||||
wmi_get_ht_cap_cmd(struct wmi_t *wmip, WMI_SET_HT_CAP_CMD *cmd);
|
||||
|
||||
A_STATUS
|
||||
wmi_set_ht_op_cmd(struct wmi_t *wmip, A_UINT8 sta_chan_width);
|
||||
|
||||
A_STATUS
|
||||
wmi_send_hci_cmd(struct wmi_t *wmip, A_UINT8 *buf, A_UINT16 sz);
|
||||
|
||||
A_STATUS
|
||||
wmi_set_tx_select_rates_cmd(struct wmi_t *wmip, A_UINT32 *pMaskArray);
|
||||
|
||||
A_STATUS
|
||||
wmi_setup_aggr_cmd(struct wmi_t *wmip, A_UINT8 tid);
|
||||
|
||||
A_STATUS
|
||||
wmi_delete_aggr_cmd(struct wmi_t *wmip, A_UINT8 tid, A_BOOL uplink);
|
||||
|
||||
A_STATUS
|
||||
wmi_allow_aggr_cmd(struct wmi_t *wmip, A_UINT16 tx_tidmask, A_UINT16 rx_tidmask);
|
||||
|
||||
A_STATUS
|
||||
wmi_set_rx_frame_format_cmd(struct wmi_t *wmip, A_UINT8 rxMetaVersion, A_BOOL rxDot11Hdr, A_BOOL defragOnHost);
|
||||
|
||||
A_STATUS
|
||||
wmi_set_thin_mode_cmd(struct wmi_t *wmip, A_BOOL bThinMode);
|
||||
|
||||
A_STATUS
|
||||
wmi_set_wlan_conn_precedence_cmd(struct wmi_t *wmip, BT_WLAN_CONN_PRECEDENCE precedence);
|
||||
|
||||
A_STATUS
|
||||
wmi_set_pmk_cmd(struct wmi_t *wmip, A_UINT8 *pmk);
|
||||
|
||||
A_STATUS
|
||||
wmi_set_passphrase_cmd(struct wmi_t *wmip, WMI_SET_PASSPHRASE_CMD *cmd);
|
||||
|
||||
A_STATUS
|
||||
wmi_set_excess_tx_retry_thres_cmd(struct wmi_t *wmip, WMI_SET_EXCESS_TX_RETRY_THRES_CMD *cmd);
|
||||
|
||||
A_STATUS
|
||||
wmi_assoc_req_enable_cmd(struct wmi_t *wmip, A_UINT8 enable);
|
||||
|
||||
A_STATUS
|
||||
wmi_assoc_req_report_cmd (struct wmi_t *wmip, A_UINT8 host_accept, A_UINT8 host_reaspncode, A_UINT8 target_status, A_UINT8 *sta_mac_addr, A_UINT8 rspType);
|
||||
|
||||
#ifdef P2P
|
||||
A_STATUS
|
||||
wmi_p2p_discover(struct wmi_t *wmip, WMI_P2P_FIND_CMD *find_param);
|
||||
|
||||
A_STATUS
|
||||
wmi_p2p_stop_find(struct wmi_t *wmip);
|
||||
|
||||
A_STATUS
|
||||
wmi_p2p_cancel(struct wmi_t *wmip);
|
||||
|
||||
A_STATUS
|
||||
wmi_p2p_listen(struct wmi_t *wmip, A_UINT32 timeout);
|
||||
|
||||
A_STATUS
|
||||
wmi_p2p_go_neg_start(struct wmi_t *wmip, WMI_P2P_GO_NEG_START_CMD *go_param);
|
||||
|
||||
A_STATUS wmi_p2p_sdpd_tx_cmd(struct wmi_t *wmip, WMI_P2P_SDPD_TX_CMD *buf);
|
||||
|
||||
A_STATUS wmi_p2p_stop_sdpd(struct wmi_t *wmip);
|
||||
|
||||
A_STATUS wmi_p2p_go_neg_rsp_cmd(struct wmi_t *wmip, A_UINT8 status,
|
||||
A_UINT8 go_intent, A_UINT32 wps_method, A_UINT16 listen_freq,
|
||||
A_UINT8 *wpsbuf, A_UINT32 wpslen, A_UINT8 *p2pbuf, A_UINT32 p2plen,
|
||||
A_UINT8 dialog_token, A_UINT8 persistent_grp);
|
||||
|
||||
A_STATUS
|
||||
wmi_p2p_set_config(struct wmi_t *wmip, WMI_P2P_SET_CONFIG_CMD *config);
|
||||
|
||||
A_STATUS
|
||||
wmi_wps_set_config(struct wmi_t *wmip, WMI_WPS_SET_CONFIG_CMD *wps_config);
|
||||
|
||||
A_STATUS wmi_p2p_grp_init_cmd(struct wmi_t *wmip, WMI_P2P_GRP_INIT_CMD *buf);
|
||||
|
||||
A_STATUS wmi_p2p_grp_done_cmd(struct wmi_t *wmip,
|
||||
WMI_P2P_GRP_FORMATION_DONE_CMD *buf);
|
||||
|
||||
A_STATUS wmi_p2p_invite_cmd(struct wmi_t *wmip, WMI_P2P_INVITE_CMD *buf);
|
||||
|
||||
A_STATUS wmi_p2p_invite_req_rsp_cmd(struct wmi_t *wmip, A_UINT8 status,
|
||||
A_INT8 is_go, A_UINT8 *grp_bssid, A_UINT8 *p2pbuf,
|
||||
A_UINT8 p2plen, A_UINT8 dialog_token);
|
||||
|
||||
A_STATUS wmi_p2p_prov_disc_cmd(struct wmi_t *wmip,
|
||||
WMI_P2P_PROV_DISC_REQ_CMD *buf);
|
||||
|
||||
A_STATUS wmi_p2p_set_cmd(struct wmi_t *wmip, WMI_P2P_SET_CMD *buf);
|
||||
|
||||
#endif /* P2P */
|
||||
|
||||
A_UINT16
|
||||
wmi_ieee2freq (int chan);
|
||||
|
||||
A_UINT32
|
||||
wmi_freq2ieee (A_UINT16 freq);
|
||||
|
||||
bss_t *
|
||||
wmi_find_matching_Ssidnode (struct wmi_t *wmip, A_UCHAR *pSsid,
|
||||
A_UINT32 ssidLength,
|
||||
A_UINT32 dot11AuthMode, A_UINT32 authMode,
|
||||
A_UINT32 pairwiseCryptoType, A_UINT32 grpwiseCryptoTyp);
|
||||
|
||||
A_STATUS
|
||||
wmi_radarDetected_cmd(struct wmi_t *wmip, A_INT16 chan_index, A_INT8 bang_radar);
|
||||
|
||||
A_STATUS
|
||||
wmi_set_dfs_maxpulsedur_cmd(struct wmi_t *wmip, A_UINT32 value);
|
||||
|
||||
A_STATUS
|
||||
wmi_set_dfs_minrssithresh_cmd(struct wmi_t *wmip, A_INT32 rssi);
|
||||
|
||||
A_STATUS
|
||||
wmi_beacon2bssnode (struct wmi_t *wmip, A_UINT8 *datap, int len, A_UINT8 *bssid, A_UINT16 channel);
|
||||
|
||||
A_STATUS
|
||||
wmi_set_tx_mac_rules_cmd (struct wmi_t *wmip, A_UINT32 rules);
|
||||
|
||||
A_STATUS
|
||||
wmi_set_promiscuous_mode_cmd (struct wmi_t *wmip, A_BOOL bMode);
|
||||
|
||||
//WAC
|
||||
A_STATUS wmi_wac_enable_cmd(struct wmi_t *wmip, WMI_WAC_ENABLE_CMD *param);
|
||||
|
||||
A_STATUS
|
||||
wmi_wac_scan_reply_cmd(struct wmi_t *wmip, WAC_SUBCMD param);
|
||||
|
||||
A_STATUS
|
||||
wmi_wac_ctrl_req_cmd(struct wmi_t *wmip, WMI_WAC_CTRL_REQ_CMD *param);
|
||||
|
||||
#ifdef CONFIG_WLAN_RFKILL
|
||||
A_STATUS
|
||||
wmi_get_rfkill_mode_cmd(struct wmi_t *wmip);
|
||||
|
||||
A_STATUS
|
||||
wmi_set_rfkill_mode_cmd(struct wmi_t *wmip,WMI_RFKILL_MODE_CMD *pCmd);
|
||||
|
||||
#endif
|
||||
|
||||
A_STATUS
|
||||
wmi_force_target_assert(struct wmi_t *wmip);
|
||||
|
||||
A_STATUS
|
||||
wmi_ap_set_apsd(struct wmi_t *wmip, A_UINT8 enable);
|
||||
|
||||
A_STATUS
|
||||
wmi_set_apsd_buffered_traffic_cmd(struct wmi_t *wmip, A_UINT16 aid, A_UINT16 bitmap, A_UINT32 flags);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _WMI_API_H_ */
|
||||
46
drivers/net/wireless/ar6003/host/lib/wac/Makefile
Normal file
46
drivers/net/wireless/ar6003/host/lib/wac/Makefile
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
#------------------------------------------------------------------------------
|
||||
# <copyright file="makefile" company="Atheros">
|
||||
# Copyright (c) 2005-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"
|
||||
#==============================================================================
|
||||
CC := $(ATH_CROSS_COMPILE_TYPE)gcc
|
||||
KERNEL_SRC :=$(ATH_LINUXPATH)
|
||||
|
||||
ifndef CFLAGS
|
||||
#CFLAGS = -MMD -O2 -Wall -g
|
||||
CFLAGS = -Wall
|
||||
endif
|
||||
|
||||
CFLAGS += -DCONFIG_CTRL_IFACE_UNIX -DCONFIG_CTRL_IFACE -DWAPI_ENABLE
|
||||
|
||||
all:
|
||||
$(CC) $(CFLAGS) -I./ -I$(KERNEL_SRC)/include -I../../include -I../../../include -I../../wlan/include \
|
||||
-I../../os/linux/include -I../../3rdparty/supplicant/opensrc_0_6_9/src/common \
|
||||
-I../../os/linux/include -I../../3rdparty/supplicant/opensrc_0_6_9/src/utils wac.c -o wac
|
||||
|
||||
#wpa_ctrl.o: os_internal.o
|
||||
# $(CC) $(CFLAGS) -I./ -I$(KERNEL_SRC)/include -I../../include -I../../../include -I../../wlan/include \
|
||||
# -I../../os/linux/include -I../../3rdparty/supplicant/opensrc_0_6_9/src/utils \
|
||||
# -c ../../3rdparty/supplicant/opensrc_0_6_9/src/common/wpa_ctrl.c
|
||||
#
|
||||
#os_internal.o:
|
||||
# $(CC) $(CFLAGS) -I./ -I$(KERNEL_SRC)/include -I../../include -I../../../include -I../../wlan/include \
|
||||
# -I../../os/linux/include -I../../3rdparty/supplicant/opensrc_0_6_9/src/utils \
|
||||
# -c ../../3rdparty/supplicant/opensrc_0_6_9/src/utils/os_internal.c
|
||||
1446
drivers/net/wireless/ar6003/host/lib/wac/wac.c
Normal file
1446
drivers/net/wireless/ar6003/host/lib/wac/wac.c
Normal file
File diff suppressed because it is too large
Load Diff
92
drivers/net/wireless/ar6003/host/lib/wac/wac_lib_api.h
Normal file
92
drivers/net/wireless/ar6003/host/lib/wac/wac_lib_api.h
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// 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 __WAC_LIB_API_H__
|
||||
#define __WAC_LIB_API_H__
|
||||
|
||||
#include "wac_defs.h"
|
||||
|
||||
/*
|
||||
* Function to enable or disable the WAC feature. This is the entry point to WAC when the
|
||||
* user pushed a button on the remote
|
||||
* Input arguments:
|
||||
* s - open file descriptor of socket
|
||||
* enable - flag to enable/disable WAC. 1 = enable; 0 = disable
|
||||
* for disablethe remaining arguments are don't cares
|
||||
* period - time in milliseconds between consecutive scans when WAC is enabled
|
||||
* scan_thres - number of scan retries before the STA gave up on looking for WAC AP
|
||||
* rssi_thres - RSSI threshold the STA will check in beacon or probe response frames
|
||||
* to qualify a WAC AP. This is absolute value of the signal strength in dBm
|
||||
* Return value:
|
||||
* 0 = success; -1 = failure
|
||||
*
|
||||
* Examples:
|
||||
* To enable WAC: wac_enable(s, 1, 2000, 3, 25)
|
||||
* - WAC enabled with 2-second interval between scans for up to 3 tries. RSSI threshold is -25dBm
|
||||
* To disable WAC: wac_enable(s, 0, 0, 0, 0)
|
||||
* - When the flag is disable, the rest of arguments are don't cares
|
||||
*/
|
||||
int wac_enable(int s, int enable, unsigned int period, unsigned int scan_thres, int rssi_thres);
|
||||
|
||||
/*
|
||||
* Function for I/O Control Request for Samsung IE as specified version 1.2 protocol
|
||||
* Input arguments:
|
||||
* s - open file descriptor for socket
|
||||
* req - request type takes the possible values:
|
||||
* WAC_SET
|
||||
* WAC_GET
|
||||
* cmd - command takes the possible values:
|
||||
* WAC_ADD
|
||||
* WAC_DEL
|
||||
* WAC_GET_STATUS
|
||||
* frm - frame type takes the possible values:
|
||||
* PRBREQ (for STA)
|
||||
* PRBRSP (for AP)
|
||||
* BEACON (for AP)
|
||||
* ie - pointer to char string that contains the IE to set or get
|
||||
* ret_val - indicates whether the control request is successful
|
||||
* 0 = success; -1 = failure
|
||||
* status - status code returned by STA that takes possible values:
|
||||
* WAC_FAILED_NO_WAC_AP
|
||||
* WAC_FAILED_LOW_RSSI
|
||||
* WAC_FAILED_INVALID_PARAM
|
||||
* WAC_FAILED_REJECTED
|
||||
* WAC_SUCCESS
|
||||
* WAC_PROCEED_FIRST_PHASE
|
||||
* WAC_PROCEED_SECOND_PHASE
|
||||
* WAC_DISABLED
|
||||
* Examples:
|
||||
* To insert an IE into the probe request frame:
|
||||
* wac_control_request(WAC_SET, WAC_ADD, PRBREQ,
|
||||
* "0x0012fb0100010101083132333435363730" val, status)
|
||||
* To query the WAC status from STA:
|
||||
* wac_control_request(WAC_GET, WAC_GET_STATUS, NULL, NULL, val, status)
|
||||
*/
|
||||
void wac_control_request( int s,
|
||||
WAC_REQUEST_TYPE req,
|
||||
WAC_COMMAND cmd,
|
||||
WAC_FRAME_TYPE frm,
|
||||
char *ie,
|
||||
int *ret_val,
|
||||
WAC_STATUS *status );
|
||||
|
||||
#endif
|
||||
40
drivers/net/wireless/ar6003/host/localmake.linux.inc
Normal file
40
drivers/net/wireless/ar6003/host/localmake.linux.inc
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
#
|
||||
# Local Makefile includes for tool and kernel source paths
|
||||
#
|
||||
# Copyright 2004-2010 Atheros Communications, Inc.
|
||||
#
|
||||
# When creating a new build type, use the following template:
|
||||
# ifeq ($(ATH_BUILD_TYPE),<platform name>)
|
||||
# ATH_ARCH_CPU_TYPE := < cpu architecture >
|
||||
# ATH_CROSS_COMPILE_TYPE := < cross compiler path >
|
||||
# ATH_LINUXPATH := < kernel source path >
|
||||
|
||||
ATH_BUILD_TYPE := LOCAL_ARM_RK29
|
||||
ATH_BUS_TYPE := SDIO
|
||||
ATH_LINUXPATH := /home/ko/work/customer/yifang/trunk_exp
|
||||
ATH_CROSS_COMPILE_TYPE := /home/ko/work/customer/yifang/kernel_rk29_v0.1/toolchain/arm-eabi-4.4.0/bin/arm-eabi-
|
||||
ATH_ARCH_CPU_TYPE := arm
|
||||
|
||||
|
||||
$(info *************************)
|
||||
$(info PLATFORM: $(ATH_BUILD_TYPE))
|
||||
$(info BSP: $(ATH_BSP_TYPE))
|
||||
$(info *************************)
|
||||
# Some environment settings
|
||||
ATH_BUILD_TYPE=$(ATH_BSP_TYPE)_ARM_NATIVEMMC
|
||||
ATH_ANDROID_ENV := yes
|
||||
ATH_SOFTMAC_FILE_USED := no
|
||||
ATH_DEBUG_DRIVER := yes
|
||||
ATH_HTC_RAW_INT_ENV :=yes
|
||||
ATH_AR6K_OTA_TEST_MODE := no
|
||||
|
||||
# Some common variable
|
||||
ATH_BUS_TYPE := SDIO
|
||||
ATH_OS_SUB_TYPE := linux_2_6
|
||||
ATH_BUS_SUBTYPE := linux_sdio
|
||||
ATH_BUILD_3RDPARTY := no
|
||||
ATH_CFG80211_ENV := no
|
||||
ATH_BUILD_SYSTEM_TOOLS := no
|
||||
ATH_AR6K_HCI_PAL := no
|
||||
ATH_AR6K_DEBUG_ALLOC := no
|
||||
ATH_BUILD_P2P :=no
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
// based on 1, change DVDD=0.85V, LPO measure time to 8ms, 1300ms reCal interval
|
||||
// Radio table TAG
|
||||
#
|
||||
[H:S]012C
|
||||
[H:S]0042
|
||||
[H:A]B1 B1 12 00 02 00 01 30 06 00 02 00 00 20 02 00
|
||||
04 00 0C 40 01 00 48 00 00 48 54 9A 02 00 00 08
|
||||
02 00 48 00 89 EE 70 E6 38 00 D8 70 EF 52 02 00
|
||||
00 40 00 00 08 00 31 00 00 00 04 00 10 00 00 00
|
||||
B2 B2
|
||||
// System config TAG
|
||||
#
|
||||
[H:S]0013
|
||||
[H:S]009C
|
||||
[H:A]C1 C1 17 02 02 00 01 30 48 00 0E CC 33 06 01 08
|
||||
64 96 14 05 FF FF 05 80 00 00 FF CC 00 CC 01 00
|
||||
20 80 FF CC 02 CC 04 00 DF EC 43 F8 00 21 00 E0
|
||||
FF CC 03 CC 06 00 80 F0 08 28 80 F4 0C 20 80 F8
|
||||
0E 18 80 FC 14 10 80 00 18 08 80 04 16 00 FF CC
|
||||
04 CC 01 00 1A 12 40 96 01 C0 28 00 00 00 C0 01
|
||||
40 06 00 01 00 00 C8 00 00 F0 00 00 FF CC 0C CC
|
||||
08 00 01 03 00 7E 08 08 00 7E 01 01 00 7E 01 03
|
||||
00 7E 03 03 00 7E 61 63 00 7E 63 65 00 7E 6A 6C
|
||||
00 7E FF CC 09 CC 00 C9 FF CC C2 C2
|
||||
//Extern 32k + 24Mhz CPU
|
||||
//#
|
||||
//[H:S]0021
|
||||
//[H:S]0004
|
||||
//[H:A]09 00 00 00
|
||||
//Bdaddr
|
||||
//#
|
||||
//[H:S]0001
|
||||
//[H:S]0006
|
||||
//[H:A]89 60 41 7f 03 00
|
||||
//Audio
|
||||
#
|
||||
[H:S]0002
|
||||
[H:S]0004
|
||||
[H:A]23 08 01 33
|
||||
//Audio
|
||||
#
|
||||
[H:S]0003
|
||||
[H:S]0004
|
||||
[H:A]dd e5 2e 00
|
||||
//Audio
|
||||
#
|
||||
[H:S]0015
|
||||
[H:S]0004
|
||||
[H:A]12 00 00 00
|
||||
//Audio
|
||||
#
|
||||
[H:S]0016
|
||||
[H:S]0004
|
||||
[H:A]00 00 a7 02
|
||||
#
|
||||
//PLC
|
||||
[H:S]001F
|
||||
[H:S]0008
|
||||
[H:A]01 1A 06 14 50 B4 32 96
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
0569
|
||||
000000000e20000050800000000158000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d0915300d4915300d8915300dc91530098b0530064ce5300f8d2530008e7530008d253000cd2530098d95300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ff051001010101ffffff50500101010180019800c8019800f4029800d0039800380498001404980024059800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000366100ad0581c206bd01e00800bd0a17641c0c0abd05815d080c0ce00800bd02dd03ed05815c080c0ce00800c60400ad05c1f802922b11819903c09920926b11e008000c021df0003681001c0e516d030c0720d074d241107911d0cd90b805a0cc11cabbb90160e6030c2a609034972a026062003801e2c1102203068d07cc8260e613102000fd061df072631122011072434fc805204290a044114acc882c0c1980a00407e805820c4b07e8079c7aa20c4b07ea12a2c3340c0b0cfc0c198191029911e008000c1972434ec805e8114acca82cd20c4ba0a00416aa0590fd20f24c4bcc4e820349f65878a1b1039805a20a034a9992990980aa01a0a831909821809901909831a7294a0c5a81bc04bd02e00800cd0aad0281be04e805c0b0744ace920c4b0c4dd09920924c4be008009c7a72434a860400ad020c4b81bf0492a0fe909d10924c4be0080060e613102000ad061df00c1a81bd04bd02e00800cd0a46ecff0c5a81bd04bd02e00800cd0a86e8ff0000368100305074bd0120407481c206ad04e00800922a11216d0390920516890ba18804b16e03c0200040349091f204a03311822992c02000b08810a08820a8028269923aaab20a49d2ca48579b08c20a4bc0c204161c08b24a4ae1d104524d01eae5f20e7fe20e803c29f7be4a1c0b424110d9111c0c1c0f1c0552c110fd05cd0580e6030c2e80d034d72e02806200bd05b20500c20500a802c0bb90a0bb11baaa924a3480e613102000420500d811403490520d01a03311ad04b20d0081c204cd05e00800a802b2a0fb3aaa920a4b0c12b09910924a4b1df00c021df0364100811e0621c0098808921207ece8ecc9e1b103b21206a21ef1b73a210c0a817c03d21ef0c1d603f16c03c80ce20f44a0bd11e0bd93d1d209e00800a252071df00000364100817f04916c03880892092880801466180acc79810d04a2a064e008001df0000000364100c02000c16c03e1940391d9032178030c0dd2628bf20902c02000f0ed83e2628cc02000d2628dc02000d2628e820c43b20c28d19d0210bb01d0bb10cc580cba0c53c600000c0a0c83c020000c1dd2628fc02000a2628ac02000b26289a209020c088cfa661a040c1ac60300662a05a2190026ca040c0a8607000c0af0ba01e1da03a2090ce0bb100c1ea0ae93e1f40230aa11e0aa10b0aa20b1fd03c02000a26bc1f209020c18f62f040c098604009209070c1a909a930c2af09911a09910d09920c02000d17f04926bc6d80de20c28d0d014661d0acc7e810d04a2a064e00800c020003262881df00036410081c305c1900920b074e19605d16e09e80ec02000d22d82b94ed92ec02000b90c30e6030c2a309034972a02306200e00800c02000fd0391250382a10082698000710030e6131020001df0
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
|
||||
// Coex Configuration
|
||||
#
|
||||
[H:S]0017
|
||||
[H:S]0022
|
||||
[H:A]d1 d1 20 00 02 01 02 09 0c 00 24 0f 04 00 00 01
|
||||
00 01 00 01 01 01 01 01 01 00 00 00 01 00 00 00
|
||||
d2 d2
|
||||
// Radio table TAG
|
||||
#
|
||||
[H:S]012C
|
||||
[H:S]0042
|
||||
[H:A]B1 B1 12 00 06 00 01 30 06 00 02 00 00 20 02 00
|
||||
04 00 0C 40 01 00 48 00 00 48 54 9A 02 00 00 08
|
||||
02 00 48 00 89 EE 70 E6 38 00 D8 70 EF 52 02 00
|
||||
00 40 00 00 08 00 31 00 00 00 04 00 10 00 00 00
|
||||
B2 B2
|
||||
// System config TAG
|
||||
#
|
||||
[H:S]0013
|
||||
[H:S]00B6
|
||||
[H:A]C1 C1 17 02 06 00 01 30 55 00 0E CC 33 06 01 08
|
||||
64 96 14 05 FF FF 05 80 00 00 FF CC 00 CC 01 00
|
||||
20 80 FF CC 02 CC 04 00 DF EC 43 F8 00 21 00 E0
|
||||
FF CC 03 CC 06 00 80 F0 08 28 80 F4 0C 20 80 F8
|
||||
0E 18 80 FC 14 10 80 00 18 08 80 04 16 00 FF CC
|
||||
04 CC 01 00 1A 12 40 96 01 C0 28 00 00 00 C0 01
|
||||
40 06 00 01 00 00 C8 00 00 F0 00 00 FF CC 0C CC
|
||||
08 00 01 03 00 7E 08 08 00 7E 01 01 00 7E 01 03
|
||||
00 7E 03 03 00 7E 61 63 00 7E 63 65 00 7E 6A 6C
|
||||
00 7E FF CC 09 CC 00 C9 FF CC 0B CC 0A 17 07 B2
|
||||
5E 01 52 0A 60 09 05 06 14 4B 00 00 58 02 D0 07
|
||||
00 41 FF CC C2 C2
|
||||
//Extern 32k + 24Mhz CPU
|
||||
//#
|
||||
//[H:S]0021
|
||||
//[H:S]0004
|
||||
//[H:A]09 00 00 00
|
||||
//Bdaddr
|
||||
//#
|
||||
//[H:S]0001
|
||||
//[H:S]0006
|
||||
//[H:A]89 60 41 7f 03 00
|
||||
//Audio
|
||||
#
|
||||
[H:S]0002
|
||||
[H:S]0004
|
||||
[H:A]23 08 01 33
|
||||
//Audio
|
||||
#
|
||||
[H:S]0003
|
||||
[H:S]0004
|
||||
[H:A]dd e5 2e 00
|
||||
//Audio
|
||||
#
|
||||
[H:S]0015
|
||||
[H:S]0004
|
||||
[H:A]12 00 00 00
|
||||
//Audio
|
||||
#
|
||||
[H:S]0016
|
||||
[H:S]0004
|
||||
[H:A]00 00 a7 02
|
||||
#
|
||||
//PLC
|
||||
[H:S]001F
|
||||
[H:S]0008
|
||||
[H:A]01 1A 06 14 50 B4 32 96
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
|
||||
// Coex Configuration
|
||||
#
|
||||
[H:S]0017
|
||||
[H:S]0022
|
||||
[H:A]d1 d1 20 00 02 01 02 09 0c 00 24 0f 04 00 00 01
|
||||
00 01 00 01 01 01 01 01 01 00 00 00 01 00 00 00
|
||||
d2 d2
|
||||
// Radio table TAG
|
||||
#
|
||||
[H:S]012C
|
||||
[H:S]0042
|
||||
[H:A]B1 B1 12 00 06 00 01 30 06 00 02 00 00 20 02 00
|
||||
04 00 0C 40 01 00 48 00 00 48 54 9A 02 00 00 08
|
||||
02 00 48 00 89 EE 70 E6 38 00 D8 70 EF 52 02 00
|
||||
00 40 00 00 08 00 31 00 00 00 04 00 10 00 00 00
|
||||
B2 B2
|
||||
// System config TAG
|
||||
#
|
||||
[H:S]0013
|
||||
[H:S]00B6
|
||||
[H:A]C1 C1 17 02 06 00 01 30 55 00 0E CC 33 06 01 08
|
||||
64 96 14 05 FF FF 05 80 00 00 FF CC 00 CC 01 00
|
||||
20 80 FF CC 02 CC 04 00 DF EC 43 F8 00 21 00 E0
|
||||
FF CC 03 CC 06 00 80 F0 08 28 80 F4 0C 20 80 F8
|
||||
0E 18 80 FC 14 10 80 00 18 08 80 04 16 00 FF CC
|
||||
04 CC 01 00 1A 12 40 96 01 C0 28 00 00 00 C0 01
|
||||
40 06 00 01 00 00 C8 00 00 F0 00 00 FF CC 0C CC
|
||||
08 00 01 03 00 7E 08 08 00 7E 01 01 00 7E 01 03
|
||||
00 7E 03 03 00 7E 61 63 00 7E 63 65 00 7E 6A 6C
|
||||
00 7E FF CC 09 CC 00 C9 FF CC 0B CC 0A 17 07 B2
|
||||
5E 01 52 0A 60 09 05 06 14 4B 00 00 58 02 D0 07
|
||||
00 41 FF CC C2 C2
|
||||
//Extern 32k + 24Mhz CPU
|
||||
//#
|
||||
//[H:S]0021
|
||||
//[H:S]0004
|
||||
//[H:A]09 00 00 00
|
||||
//Bdaddr
|
||||
//#
|
||||
//[H:S]0001
|
||||
//[H:S]0006
|
||||
//[H:A]89 60 41 7f 03 00
|
||||
//Audio
|
||||
#
|
||||
[H:S]0002
|
||||
[H:S]0004
|
||||
[H:A]23 08 01 33
|
||||
//Audio
|
||||
#
|
||||
[H:S]0003
|
||||
[H:S]0004
|
||||
[H:A]dd e5 2e 00
|
||||
//Audio
|
||||
#
|
||||
[H:S]0015
|
||||
[H:S]0004
|
||||
[H:A]12 00 00 00
|
||||
//Audio
|
||||
#
|
||||
[H:S]0016
|
||||
[H:S]0004
|
||||
[H:A]00 00 a7 02
|
||||
#
|
||||
//PLC
|
||||
[H:S]001F
|
||||
[H:S]0008
|
||||
[H:A]01 1A 06 14 50 B4 32 96
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
|
||||
// Coex Configuration
|
||||
#
|
||||
[H:S]0017
|
||||
[H:S]0022
|
||||
[H:A]d1 d1 20 00 02 01 02 09 0c 00 24 0f 04 00 00 01
|
||||
00 01 00 00 01 01 01 01 01 00 00 00 01 00 00 00
|
||||
d2 d2
|
||||
// Radio table TAG
|
||||
#
|
||||
[H:S]012C
|
||||
[H:S]0042
|
||||
[H:A]B1 B1 12 00 06 00 01 30 06 00 02 00 00 20 02 00
|
||||
04 00 0C 40 01 00 48 00 00 48 54 9A 02 00 00 08
|
||||
02 00 48 00 89 EE 70 E6 38 00 D8 70 EF 52 02 00
|
||||
00 40 00 00 08 00 31 00 00 00 04 00 10 00 00 00
|
||||
B2 B2
|
||||
// System config TAG
|
||||
#
|
||||
[H:S]0013
|
||||
[H:S]00B6
|
||||
[H:A]C1 C1 17 02 06 00 01 30 55 00 0E CC 33 06 01 08
|
||||
64 96 14 05 FF FF 05 80 00 00 FF CC 00 CC 01 00
|
||||
20 80 FF CC 02 CC 04 00 DF EC 43 F8 00 21 00 E0
|
||||
FF CC 03 CC 06 00 80 F0 08 28 80 F4 0C 20 80 F8
|
||||
0E 18 80 FC 14 10 80 00 18 08 80 04 16 00 FF CC
|
||||
04 CC 01 00 1A 12 40 96 01 C0 28 00 00 00 C0 01
|
||||
40 06 00 01 00 00 C8 00 00 F0 00 00 FF CC 0C CC
|
||||
08 00 01 03 00 7E 08 08 00 7E 01 01 00 7E 01 03
|
||||
00 7E 03 03 00 7E 61 63 00 7E 63 65 00 7E 6A 6C
|
||||
00 7E FF CC 09 CC 00 C9 FF CC 0B CC 0A 17 07 B2
|
||||
5E 01 52 0A 60 09 05 06 14 4B 00 00 58 02 D0 07
|
||||
00 41 FF CC C2 C2
|
||||
//Extern 32k + 24Mhz CPU
|
||||
//#
|
||||
//[H:S]0021
|
||||
//[H:S]0004
|
||||
//[H:A]09 00 00 00
|
||||
//Bdaddr
|
||||
//#
|
||||
//[H:S]0001
|
||||
//[H:S]0006
|
||||
//[H:A]89 60 41 7f 03 00
|
||||
//Audio
|
||||
#
|
||||
[H:S]0002
|
||||
[H:S]0004
|
||||
[H:A]23 08 01 33
|
||||
//Audio
|
||||
#
|
||||
[H:S]0003
|
||||
[H:S]0004
|
||||
[H:A]dd e5 2e 00
|
||||
//Audio
|
||||
#
|
||||
[H:S]0015
|
||||
[H:S]0004
|
||||
[H:A]12 00 00 00
|
||||
//Audio
|
||||
#
|
||||
[H:S]0016
|
||||
[H:S]0004
|
||||
[H:A]00 00 a7 02
|
||||
#
|
||||
//PLC
|
||||
[H:S]001F
|
||||
[H:S]0008
|
||||
[H:A]01 1A 06 14 50 B4 32 96
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
0569
|
||||
000000000e20000050800000000158000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d0915300d4915300d8915300dc91530098b0530064ce5300f8d2530008e7530008d253000cd2530098d95300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ff051001010101ffffff50500101010180019800c8019800f4029800d0039800380498001404980024059800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000366100ad0581c206bd01e00800bd0a17641c0c0abd05815d080c0ce00800bd02dd03ed05815c080c0ce00800c60400ad05c1f802922b11819903c09920926b11e008000c021df0003681001c0e516d030c0720d074d241107911d0cd90b805a0cc11cabbb90160e6030c2a609034972a026062003801e2c1102203068d07cc8260e613102000fd061df072631122011072434fc805204290a044114acc882c0c1980a00407e805820c4b07e8079c7aa20c4b07ea12a2c3340c0b0cfc0c198191029911e008000c1972434ec805e8114acca82cd20c4ba0a00416aa0590fd20f24c4bcc4e820349f65878a1b1039805a20a034a9992990980aa01a0a831909821809901909831a7294a0c5a81bc04bd02e00800cd0aad0281be04e805c0b0744ace920c4b0c4dd09920924c4be008009c7a72434a860400ad020c4b81bf0492a0fe909d10924c4be0080060e613102000ad061df00c1a81bd04bd02e00800cd0a46ecff0c5a81bd04bd02e00800cd0a86e8ff0000368100305074bd0120407481c206ad04e00800922a11216d0390920516890ba18804b16e03c0200040349091f204a03311822992c02000b08810a08820a8028269923aaab20a49d2ca48579b08c20a4bc0c204161c08b24a4ae1d104524d01eae5f20e7fe20e803c29f7be4a1c0b424110d9111c0c1c0f1c0552c110fd05cd0580e6030c2e80d034d72e02806200bd05b20500c20500a802c0bb90a0bb11baaa924a3480e613102000420500d811403490520d01a03311ad04b20d0081c204cd05e00800a802b2a0fb3aaa920a4b0c12b09910924a4b1df00c021df0364100811e0621c0098808921207ece8ecc9e1b103b21206a21ef1b73a210c0a817c03d21ef0c1d603f16c03c80ce20f44a0bd11e0bd93d1d209e00800a252071df00000364100817f04916c03880892092880801466180acc79810d04a2a064e008001df0000000364100c02000c16c03e1940391d9032178030c0dd2628bf20902c02000f0ed83e2628cc02000d2628dc02000d2628e820c43b20c28d19d0210bb01d0bb10cc580cba0c53c600000c0a0c83c020000c1dd2628fc02000a2628ac02000b26289a209020c088cfa661a040c1ac60300662a05a2190026ca040c0a8607000c0af0ba01e1da03a2090ce0bb100c1ea0ae93e1f40230aa11e0aa10b0aa20b1fd03c02000a26bc1f209020c18f62f040c098604009209070c1a909a930c2af09911a09910d09920c02000d17f04926bc6d80de20c28d0d014661d0acc7e810d04a2a064e00800c020003262881df00036410081c305c1900920b074e19605d16e09e80ec02000d22d82b94ed92ec02000b90c30e6030c2a309034972a02306200e00800c02000fd0391250382a10082698000710030e6131020001df0
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
|
||||
// Radio table TAG
|
||||
#
|
||||
[H:S]012C
|
||||
[H:S]0042
|
||||
[H:A]B1 B1 12 00 08 00 01 30 06 00 02 00 00 20 02 00
|
||||
04 00 0C 40 01 00 48 00 00 48 54 9A 02 00 00 08
|
||||
02 00 48 00 89 EE 70 E6 38 00 D8 70 EF 52 02 00
|
||||
00 40 00 00 08 00 31 00 00 00 04 00 10 00 00 00
|
||||
B2 B2
|
||||
// System config TAG
|
||||
#
|
||||
[H:S]0013
|
||||
[H:S]009C
|
||||
[H:A]C1 C1 17 02 08 00 01 30 48 00 0E CC 33 26 01 08
|
||||
64 96 14 05 FF FF 05 80 00 00 FF CC 00 CC 01 00
|
||||
20 80 FF CC 02 CC 04 00 DF EC 43 F8 00 21 00 E0
|
||||
FF CC 03 CC 06 00 80 F0 08 28 80 F4 0C 20 80 F8
|
||||
0E 18 80 FC 14 10 80 00 18 08 80 04 16 00 FF CC
|
||||
04 CC 01 00 1A 12 40 96 01 C0 28 00 00 00 C0 01
|
||||
40 06 00 01 00 00 C8 00 00 F0 00 00 FF CC 0C CC
|
||||
08 00 01 03 00 7E 08 08 00 7E 01 01 00 7E 01 03
|
||||
00 7E 03 03 00 7E 61 63 00 7E 63 65 00 7E 6A 6C
|
||||
00 7E FF CC 09 CC 00 C9 FF CC C2 C2
|
||||
//Extern 32k + 24Mhz CPU
|
||||
//#
|
||||
//[H:S]0021
|
||||
//[H:S]0004
|
||||
//[H:A]09 00 00 00
|
||||
//Bdaddr
|
||||
//#
|
||||
//[H:S]0001
|
||||
//[H:S]0006
|
||||
//[H:A]89 60 41 7f 03 00
|
||||
//Audio
|
||||
#
|
||||
[H:S]0002
|
||||
[H:S]0004
|
||||
[H:A]23 08 01 33
|
||||
//Audio
|
||||
#
|
||||
[H:S]0003
|
||||
[H:S]0004
|
||||
[H:A]dd e5 2e 00
|
||||
//Audio
|
||||
#
|
||||
[H:S]0015
|
||||
[H:S]0004
|
||||
[H:A]12 00 00 00
|
||||
//Audio
|
||||
#
|
||||
[H:S]0016
|
||||
[H:S]0004
|
||||
[H:A]00 00 a7 02
|
||||
#
|
||||
//PLC
|
||||
[H:S]001F
|
||||
[H:S]0008
|
||||
[H:A]01 1A 06 14 50 B4 32 96
|
||||
//Sniff Recovery
|
||||
#
|
||||
[H:S]003D
|
||||
[H:S]0018
|
||||
[H:A]A0 0F 00 00 00 08 00 00 0F 00 7D 04 E8 03 01 00
|
||||
01 00 01 05 00 02 1F 01
|
||||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,22 @@
|
|||
-"PS_ASIC.pst"
|
||||
This file contains radio, system, and firwmare configurabilities.
|
||||
Details on how the ".pst" format and definitions can be found in the documents folder.
|
||||
|
||||
-"RamPatch.txt"
|
||||
This file contains firmware fixes for known defects. Atheros will release patch files as needed.
|
||||
|
||||
Both files are required for the system to be operational.
|
||||
|
||||
- "ar3kbdaddr.pst"
|
||||
This file contains the user configurable Bluetooth Address
|
||||
|
||||
Linux:
|
||||
|
||||
The files have to be copied to "\lib\firmware\" folder.
|
||||
|
||||
|
||||
Windows CE.
|
||||
|
||||
The files have to be copied to "platform\<HardWare Name>\Files" folder.
|
||||
|
||||
Please refer the corresponding documents for the exacts steps to be followed.
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
|
||||
// Coex Configuration
|
||||
#
|
||||
[H:S]0017
|
||||
[H:S]0022
|
||||
[H:A]d1 d1 20 00 02 01 02 09 0c 00 24 0f 04 00 00 01
|
||||
00 01 00 01 01 01 01 01 01 00 00 00 01 00 00 00
|
||||
d2 d2
|
||||
// Radio table TAG
|
||||
#
|
||||
[H:S]012C
|
||||
[H:S]0042
|
||||
[H:A]B1 B1 12 00 08 00 01 30 06 00 02 00 00 20 02 00
|
||||
04 00 0C 40 01 00 48 00 00 48 54 9A 02 00 00 08
|
||||
02 00 48 00 89 EE 70 E6 38 00 D8 70 EF 52 02 00
|
||||
00 40 00 00 08 00 31 00 00 00 04 00 10 00 00 00
|
||||
B2 B2
|
||||
// System config TAG
|
||||
#
|
||||
[H:S]0013
|
||||
[H:S]00B6
|
||||
[H:A]C1 C1 17 02 06 00 01 30 55 00 0E CC 33 06 01 08
|
||||
64 96 14 05 FF FF 05 80 00 00 FF CC 00 CC 01 00
|
||||
20 80 FF CC 02 CC 04 00 DF EC 43 F8 00 21 00 E0
|
||||
FF CC 03 CC 06 00 80 F0 08 28 80 F4 0C 20 80 F8
|
||||
0E 18 80 FC 14 10 80 00 18 08 80 04 16 00 FF CC
|
||||
04 CC 01 00 1A 12 40 96 01 C0 28 00 00 00 C0 01
|
||||
40 06 00 01 00 00 C8 00 00 F0 00 00 FF CC 0C CC
|
||||
08 00 01 03 00 7E 08 08 00 7E 01 01 00 7E 01 03
|
||||
00 7E 03 03 00 7E 61 63 00 7E 63 65 00 7E 6A 6C
|
||||
00 7E FF CC 09 CC 00 C9 FF CC 0B CC 0A 17 07 B2
|
||||
5E 01 52 0A 60 09 05 06 14 4B 00 00 58 02 D0 07
|
||||
00 41 FF CC C2 C2
|
||||
//Extern 32k + 24Mhz CPU
|
||||
//bit 7: sleep disable/enable, default to enable
|
||||
//e.g. to disable sleep, clear bit 7:
|
||||
//[H:A]08 00 00 00
|
||||
#
|
||||
[H:S]0021
|
||||
[H:S]0004
|
||||
[H:A]88 00 00 00
|
||||
//Bdaddr
|
||||
//#
|
||||
//[H:S]0001
|
||||
//[H:S]0006
|
||||
//[H:A]89 60 41 7f 03 00
|
||||
//Audio
|
||||
#
|
||||
[H:S]0002
|
||||
[H:S]0004
|
||||
[H:A]23 08 01 33
|
||||
//Audio
|
||||
#
|
||||
[H:S]0003
|
||||
[H:S]0004
|
||||
[H:A]dd e5 2e 00
|
||||
//Audio
|
||||
#
|
||||
[H:S]0015
|
||||
[H:S]0004
|
||||
[H:A]12 00 00 00
|
||||
//Audio
|
||||
#
|
||||
[H:S]0016
|
||||
[H:S]0004
|
||||
[H:A]00 00 a7 02
|
||||
#
|
||||
//PLC
|
||||
[H:S]001F
|
||||
[H:S]0008
|
||||
[H:A]01 1A 06 14 50 B4 32 96
|
||||
//Sniff Recovery
|
||||
#
|
||||
[H:S]003D
|
||||
[H:S]0018
|
||||
[H:A]A0 0F 00 00 00 08 00 00 0F 00 7D 04 E8 03 01 00
|
||||
01 00 01 05 00 02 1F 01
|
||||
//BRM Config
|
||||
#
|
||||
[H:S]0026
|
||||
[H:S]000C
|
||||
[H:A]01 20 46 01 0F 02 28 14 01 28 68 01
|
||||
//TLPM
|
||||
//[79:64] - TLPM wakeup timeout in ms, default 10
|
||||
//[127:96] - TLPM idle timeout in ms, default 1000
|
||||
//e.g. to change the wakeup timeout to 5 and idle timeout to 2000
|
||||
//[H:A]03 00 03 00 00 00 00 00 05 00 0A 00 D0 07 00 00
|
||||
// E8 03 00 00 E8 03 00 00
|
||||
#
|
||||
[H:S]0023
|
||||
[H:S]0018
|
||||
[H:A]03 00 03 00 00 00 00 00 0A 00 0A 00 E8 03 00 00
|
||||
E8 03 00 00 E8 03 00 00
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
|
||||
// Coex Configuration
|
||||
#
|
||||
[H:S]0017
|
||||
[H:S]0022
|
||||
[H:A]d1 d1 20 00 02 01 02 09 0c 00 24 0f 04 00 00 01
|
||||
00 01 00 01 01 01 01 01 01 00 00 00 01 00 00 00
|
||||
d2 d2
|
||||
// Radio table TAG
|
||||
#
|
||||
[H:S]012C
|
||||
[H:S]0042
|
||||
[H:A]B1 B1 12 00 08 00 01 30 06 00 02 00 00 20 02 00
|
||||
04 00 0C 40 01 00 48 00 00 48 54 9A 02 00 00 08
|
||||
02 00 48 00 89 EE 70 E6 38 00 D8 70 EF 52 02 00
|
||||
00 40 00 00 08 00 31 00 00 00 04 00 10 00 00 00
|
||||
B2 B2
|
||||
// System config TAG
|
||||
#
|
||||
[H:S]0013
|
||||
[H:S]00B6
|
||||
[H:A]C1 C1 17 02 06 00 01 30 55 00 0E CC 33 06 01 08
|
||||
64 96 14 05 FF FF 05 80 00 00 FF CC 00 CC 01 00
|
||||
20 80 FF CC 02 CC 04 00 DF EC 43 F8 00 21 00 E0
|
||||
FF CC 03 CC 06 00 80 F0 08 28 80 F4 0C 20 80 F8
|
||||
0E 18 80 FC 14 10 80 00 18 08 80 04 16 00 FF CC
|
||||
04 CC 01 00 1A 12 40 96 01 C0 28 00 00 00 C0 01
|
||||
40 06 00 01 00 00 C8 00 00 F0 00 00 FF CC 0C CC
|
||||
08 00 01 03 00 7E 08 08 00 7E 01 01 00 7E 01 03
|
||||
00 7E 03 03 00 7E 61 63 00 7E 63 65 00 7E 6A 6C
|
||||
00 7E FF CC 09 CC 00 C9 FF CC 0B CC 0A 17 07 B2
|
||||
5E 01 52 0A 60 09 05 06 14 4B 00 00 58 02 D0 07
|
||||
00 41 FF CC C2 C2
|
||||
//Extern 32k + 24Mhz CPU
|
||||
//bit 7: sleep disable/enable, default to enable
|
||||
//e.g. to disable sleep, clear bit 7:
|
||||
//[H:A]08 00 00 00
|
||||
#
|
||||
[H:S]0021
|
||||
[H:S]0004
|
||||
[H:A]88 00 00 00
|
||||
//Bdaddr
|
||||
//#
|
||||
//[H:S]0001
|
||||
//[H:S]0006
|
||||
//[H:A]89 60 41 7f 03 00
|
||||
//Audio
|
||||
#
|
||||
[H:S]0002
|
||||
[H:S]0004
|
||||
[H:A]23 08 01 33
|
||||
//Audio
|
||||
#
|
||||
[H:S]0003
|
||||
[H:S]0004
|
||||
[H:A]dd e5 2e 00
|
||||
//Audio
|
||||
#
|
||||
[H:S]0015
|
||||
[H:S]0004
|
||||
[H:A]12 00 00 00
|
||||
//Audio
|
||||
#
|
||||
[H:S]0016
|
||||
[H:S]0004
|
||||
[H:A]00 00 a7 02
|
||||
#
|
||||
//PLC
|
||||
[H:S]001F
|
||||
[H:S]0008
|
||||
[H:A]01 1A 06 14 50 B4 32 96
|
||||
//Sniff Recovery
|
||||
#
|
||||
[H:S]003D
|
||||
[H:S]0018
|
||||
[H:A]A0 0F 00 00 00 08 00 00 0F 00 7D 04 E8 03 01 00
|
||||
01 00 01 05 00 02 1F 01
|
||||
//BRM Config
|
||||
#
|
||||
[H:S]0026
|
||||
[H:S]000C
|
||||
[H:A]01 20 46 01 0F 02 28 14 01 28 68 01
|
||||
//TLPM
|
||||
//[79:64] - TLPM wakeup timeout in ms, default 10
|
||||
//[127:96] - TLPM idle timeout in ms, default 1000
|
||||
//e.g. to change the wakeup timeout to 5 and idle timeout to 2000
|
||||
//[H:A]03 00 03 00 00 00 00 00 05 00 0A 00 D0 07 00 00
|
||||
// E8 03 00 00 E8 03 00 00
|
||||
#
|
||||
[H:S]0023
|
||||
[H:S]0018
|
||||
[H:A]03 00 03 00 00 00 00 00 0A 00 0A 00 E8 03 00 00
|
||||
E8 03 00 00 E8 03 00 00
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
|
||||
// Coex Configuration
|
||||
#
|
||||
[H:S]0017
|
||||
[H:S]0022
|
||||
[H:A]d1 d1 20 00 02 01 02 09 0c 00 24 0f 04 00 00 01
|
||||
00 01 00 00 01 01 01 01 01 00 00 00 01 00 00 00
|
||||
d2 d2
|
||||
// Radio table TAG
|
||||
#
|
||||
[H:S]012C
|
||||
[H:S]0042
|
||||
[H:A]B1 B1 12 00 08 00 01 30 06 00 02 00 00 20 02 00
|
||||
04 00 0C 40 01 00 48 00 00 48 54 9A 02 00 00 08
|
||||
02 00 48 00 89 EE 70 E6 38 00 D8 70 EF 52 02 00
|
||||
00 40 00 00 08 00 31 00 00 00 04 00 10 00 00 00
|
||||
B2 B2
|
||||
// System config TAG
|
||||
#
|
||||
[H:S]0013
|
||||
[H:S]00B6
|
||||
[H:A]C1 C1 17 02 06 00 01 30 55 00 0E CC 33 06 01 08
|
||||
64 96 14 05 FF FF 05 80 00 00 FF CC 00 CC 01 00
|
||||
20 80 FF CC 02 CC 04 00 DF EC 43 F8 00 21 00 E0
|
||||
FF CC 03 CC 06 00 80 F0 08 28 80 F4 0C 20 80 F8
|
||||
0E 18 80 FC 14 10 80 00 18 08 80 04 16 00 FF CC
|
||||
04 CC 01 00 1A 12 40 96 01 C0 28 00 00 00 C0 01
|
||||
40 06 00 01 00 00 C8 00 00 F0 00 00 FF CC 0C CC
|
||||
08 00 01 03 00 7E 08 08 00 7E 01 01 00 7E 01 03
|
||||
00 7E 03 03 00 7E 61 63 00 7E 63 65 00 7E 6A 6C
|
||||
00 7E FF CC 09 CC 00 C9 FF CC 0B CC 0A 17 07 B2
|
||||
5E 01 52 0A 60 09 05 06 14 4B 00 00 58 02 D0 07
|
||||
00 41 FF CC C2 C2
|
||||
//Extern 32k + 24Mhz CPU
|
||||
//bit 7: sleep disable/enable, default to enable
|
||||
//e.g. to disable sleep, clear bit 7:
|
||||
//[H:A]08 00 00 00
|
||||
#
|
||||
[H:S]0021
|
||||
[H:S]0004
|
||||
[H:A]88 00 00 00
|
||||
//Bdaddr
|
||||
//#
|
||||
//[H:S]0001
|
||||
//[H:S]0006
|
||||
//[H:A]89 60 41 7f 03 00
|
||||
//Audio
|
||||
#
|
||||
[H:S]0002
|
||||
[H:S]0004
|
||||
[H:A]23 08 01 33
|
||||
//Audio
|
||||
#
|
||||
[H:S]0003
|
||||
[H:S]0004
|
||||
[H:A]dd e5 2e 00
|
||||
//Audio
|
||||
#
|
||||
[H:S]0015
|
||||
[H:S]0004
|
||||
[H:A]12 00 00 00
|
||||
//Audio
|
||||
#
|
||||
[H:S]0016
|
||||
[H:S]0004
|
||||
[H:A]00 00 a7 02
|
||||
#
|
||||
//PLC
|
||||
[H:S]001F
|
||||
[H:S]0008
|
||||
[H:A]01 1A 06 14 50 B4 32 96
|
||||
//Sniff Recovery
|
||||
#
|
||||
[H:S]003D
|
||||
[H:S]0018
|
||||
[H:A]A0 0F 00 00 00 08 00 00 0F 00 7D 04 E8 03 01 00
|
||||
01 00 01 05 00 02 1F 01
|
||||
//BRM Config
|
||||
#
|
||||
[H:S]0026
|
||||
[H:S]000C
|
||||
[H:A]01 20 46 01 0F 02 28 14 01 28 68 01
|
||||
//TLPM
|
||||
//[79:64] - TLPM wakeup timeout in ms, default 10
|
||||
//[127:96] - TLPM idle timeout in ms, default 1000
|
||||
//e.g. to change the wakeup timeout to 5 and idle timeout to 2000
|
||||
//[H:A]03 00 03 00 00 00 00 00 05 00 0A 00 D0 07 00 00
|
||||
// E8 03 00 00 E8 03 00 00
|
||||
#
|
||||
[H:S]0023
|
||||
[H:S]0018
|
||||
[H:A]03 00 03 00 00 00 00 00 0A 00 0A 00 E8 03 00 00
|
||||
E8 03 00 00 E8 03 00 00
|
||||
File diff suppressed because one or more lines are too long
569
drivers/net/wireless/ar6003/host/miscdrv/ar3kconfig.c
Normal file
569
drivers/net/wireless/ar6003/host/miscdrv/ar3kconfig.c
Normal file
|
|
@ -0,0 +1,569 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// 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_types.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
|
||||
|
||||
A_STATUS AthPSInitialize(AR3K_CONFIG_INFO *hdev);
|
||||
|
||||
static A_STATUS SendHCICommand(AR3K_CONFIG_INFO *pConfig,
|
||||
A_UINT8 *pBuffer,
|
||||
int Length)
|
||||
{
|
||||
HTC_PACKET *pPacket = NULL;
|
||||
A_STATUS status = A_OK;
|
||||
|
||||
do {
|
||||
|
||||
pPacket = (HTC_PACKET *)A_MALLOC(sizeof(HTC_PACKET));
|
||||
if (NULL == pPacket) {
|
||||
status = A_NO_MEMORY;
|
||||
break;
|
||||
}
|
||||
|
||||
A_MEMZERO(pPacket,sizeof(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) {
|
||||
A_FREE(pPacket);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static A_STATUS RecvHCIEvent(AR3K_CONFIG_INFO *pConfig,
|
||||
A_UINT8 *pBuffer,
|
||||
int *pLength)
|
||||
{
|
||||
A_STATUS status = A_OK;
|
||||
HTC_PACKET *pRecvPacket = NULL;
|
||||
|
||||
do {
|
||||
|
||||
pRecvPacket = (HTC_PACKET *)A_MALLOC(sizeof(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(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 (A_FAILED(status)) {
|
||||
break;
|
||||
}
|
||||
|
||||
*pLength = pRecvPacket->ActualLength;
|
||||
|
||||
} while (FALSE);
|
||||
|
||||
if (pRecvPacket != NULL) {
|
||||
A_FREE(pRecvPacket);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
A_STATUS SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig,
|
||||
A_UINT8 *pHCICommand,
|
||||
int CmdLength,
|
||||
A_UINT8 **ppEventBuffer,
|
||||
A_UINT8 **ppBufferToFree)
|
||||
{
|
||||
A_STATUS status = A_OK;
|
||||
A_UINT8 *pBuffer = NULL;
|
||||
A_UINT8 *pTemp;
|
||||
int length;
|
||||
A_BOOL commandComplete = FALSE;
|
||||
A_UINT8 opCodeBytes[2];
|
||||
|
||||
do {
|
||||
|
||||
length = max(HCI_MAX_EVT_RECV_LENGTH,CmdLength);
|
||||
length += pConfig->pHCIProps->HeadRoom + pConfig->pHCIProps->TailRoom;
|
||||
length += pConfig->pHCIProps->IOBlockPad;
|
||||
|
||||
pBuffer = (A_UINT8 *)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 */
|
||||
A_MEMCPY(pBuffer + pConfig->pHCIProps->HeadRoom,pHCICommand,CmdLength);
|
||||
/* send command */
|
||||
status = SendHCICommand(pConfig,
|
||||
pBuffer + pConfig->pHCIProps->HeadRoom,
|
||||
CmdLength);
|
||||
if (A_FAILED(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 (A_FAILED(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) {
|
||||
A_FREE(pBuffer);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static A_STATUS AR3KConfigureHCIBaud(AR3K_CONFIG_INFO *pConfig)
|
||||
{
|
||||
A_STATUS status = A_OK;
|
||||
A_UINT8 hciBaudChangeCommand[] = {0x0c,0xfc,0x2,0,0};
|
||||
A_UINT16 baudVal;
|
||||
A_UINT8 *pEvent = NULL;
|
||||
A_UINT8 *pBufferToFree = NULL;
|
||||
|
||||
do {
|
||||
|
||||
if (pConfig->Flags & AR3K_CONFIG_FLAG_SET_AR3K_BAUD) {
|
||||
baudVal = (A_UINT16)(pConfig->AR3KBaudRate / 100);
|
||||
hciBaudChangeCommand[3] = (A_UINT8)baudVal;
|
||||
hciBaudChangeCommand[4] = (A_UINT8)(baudVal >> 8);
|
||||
|
||||
status = SendHCICommandWaitCommandComplete(pConfig,
|
||||
hciBaudChangeCommand,
|
||||
sizeof(hciBaudChangeCommand),
|
||||
&pEvent,
|
||||
&pBufferToFree);
|
||||
if (A_FAILED(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 (A_FAILED(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) {
|
||||
A_FREE(pBufferToFree);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static A_STATUS AR3KExitMinBoot(AR3K_CONFIG_INFO *pConfig)
|
||||
{
|
||||
A_STATUS status;
|
||||
A_CHAR exitMinBootCmd[] = {0x25,0xFC,0x0c,0x03,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00};
|
||||
A_UINT8 *pEvent = NULL;
|
||||
A_UINT8 *pBufferToFree = NULL;
|
||||
|
||||
status = SendHCICommandWaitCommandComplete(pConfig,
|
||||
exitMinBootCmd,
|
||||
sizeof(exitMinBootCmd),
|
||||
&pEvent,
|
||||
&pBufferToFree);
|
||||
|
||||
if (A_SUCCESS(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) {
|
||||
A_FREE(pBufferToFree);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static A_STATUS AR3KConfigureSendHCIReset(AR3K_CONFIG_INFO *pConfig)
|
||||
{
|
||||
A_STATUS status = A_OK;
|
||||
A_UINT8 hciResetCommand[] = {0x03,0x0c,0x0};
|
||||
A_UINT8 *pEvent = NULL;
|
||||
A_UINT8 *pBufferToFree = NULL;
|
||||
|
||||
status = SendHCICommandWaitCommandComplete( pConfig,
|
||||
hciResetCommand,
|
||||
sizeof(hciResetCommand),
|
||||
&pEvent,
|
||||
&pBufferToFree );
|
||||
|
||||
if (A_FAILED(status)) {
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("AR3K Config: HCI reset failed! \n"));
|
||||
}
|
||||
|
||||
if (pBufferToFree != NULL) {
|
||||
A_FREE(pBufferToFree);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static A_STATUS AR3KEnableTLPM(AR3K_CONFIG_INFO *pConfig)
|
||||
{
|
||||
A_STATUS status;
|
||||
/* AR3K vendor specific command for Host Wakeup Config */
|
||||
A_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 */
|
||||
A_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 */
|
||||
A_CHAR hostWakeupEnable[] = {0x31,0xFC,0x4,
|
||||
0x01,0x00,0x00,0x00};
|
||||
/* AR3K vendor specific command for Target Wakeup Enable */
|
||||
A_CHAR targetWakeupEnable[] = {0x31,0xFC,0x4,
|
||||
0x06,0x00,0x00,0x00};
|
||||
/* AR3K vendor specific command for Sleep Enable */
|
||||
A_CHAR sleepEnable[] = {0x4,0xFC,0x1,
|
||||
0x1};
|
||||
A_UINT8 *pEvent = NULL;
|
||||
A_UINT8 *pBufferToFree = NULL;
|
||||
|
||||
if (0 != pConfig->IdleTimeout) {
|
||||
A_UINT8 idle_lsb = pConfig->IdleTimeout & 0xFF;
|
||||
A_UINT8 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) {
|
||||
A_FREE(pBufferToFree);
|
||||
}
|
||||
if (A_FAILED(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) {
|
||||
A_FREE(pBufferToFree);
|
||||
}
|
||||
if (A_FAILED(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) {
|
||||
A_FREE(pBufferToFree);
|
||||
}
|
||||
if (A_FAILED(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) {
|
||||
A_FREE(pBufferToFree);
|
||||
}
|
||||
if (A_FAILED(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) {
|
||||
A_FREE(pBufferToFree);
|
||||
}
|
||||
if (A_FAILED(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;
|
||||
}
|
||||
|
||||
A_STATUS AR3KConfigure(AR3K_CONFIG_INFO *pConfig)
|
||||
{
|
||||
A_STATUS status = A_OK;
|
||||
|
||||
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 (A_FAILED(status)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (pConfig->Flags & AR3K_CONFIG_FLAG_FORCE_MINBOOT_EXIT) {
|
||||
status = AR3KExitMinBoot(pConfig);
|
||||
if (A_FAILED(status)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Load patching and PST file if available*/
|
||||
if (A_OK != AthPSInitialize(pConfig)) {
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Patch Download Failed!\n"));
|
||||
}
|
||||
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_ANY,("TLPM - PwrMgmtEnabled=%d, IdleTimeout=%d, WakeupTimeout=%d\n",
|
||||
pConfig->PwrMgmtEnabled,
|
||||
pConfig->IdleTimeout,
|
||||
pConfig->WakeupTimeout));
|
||||
|
||||
/* Send HCI reset to make PS tags take effect*/
|
||||
AR3KConfigureSendHCIReset(pConfig);
|
||||
|
||||
if (pConfig->PwrMgmtEnabled) {
|
||||
/* the delay is required after the previous HCI reset before further
|
||||
* HCI commands can be issued
|
||||
*/
|
||||
A_MDELAY(200);
|
||||
AR3KEnableTLPM(pConfig);
|
||||
}
|
||||
|
||||
if (pConfig->Flags &
|
||||
(AR3K_CONFIG_FLAG_SET_AR3K_BAUD | AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP)) {
|
||||
status = AR3KConfigureHCIBaud(pConfig);
|
||||
if (A_FAILED(status)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* re-enable asynchronous recv */
|
||||
status = HCI_TransportEnableDisableAsyncRecv(pConfig->pHCIDev,TRUE);
|
||||
if (A_FAILED(status)) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
} while (FALSE);
|
||||
|
||||
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR3K Config: Configuration Complete (status = %d) \n",status));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
A_STATUS AR3KConfigureExit(void *config)
|
||||
{
|
||||
A_STATUS status = A_OK;
|
||||
AR3K_CONFIG_INFO *pConfig = (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 (A_FAILED(status)) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (pConfig->Flags &
|
||||
(AR3K_CONFIG_FLAG_SET_AR3K_BAUD | AR3K_CONFIG_FLAG_SET_AR6K_SCALE_STEP)) {
|
||||
status = AR3KConfigureHCIBaud(pConfig);
|
||||
if (A_FAILED(status)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* re-enable asynchronous recv */
|
||||
status = HCI_TransportEnableDisableAsyncRecv(pConfig->pHCIDev,TRUE);
|
||||
if (A_FAILED(status)) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
} while (FALSE);
|
||||
|
||||
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_INFO,("AR3K Config: Cleanup Complete (status = %d) \n",status));
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
694
drivers/net/wireless/ar6003/host/miscdrv/ar3kps/ar3kpsconfig.c
Normal file
694
drivers/net/wireless/ar6003/host/miscdrv/ar3kps/ar3kpsconfig.c
Normal file
|
|
@ -0,0 +1,694 @@
|
|||
/*
|
||||
* 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 {
|
||||
|
||||
PSCmdPacket *HciCmdList;
|
||||
A_UINT32 num_packets;
|
||||
AR3K_CONFIG_INFO *dev;
|
||||
}HciCommandListParam;
|
||||
|
||||
A_STATUS SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig,
|
||||
A_UINT8 *pHCICommand,
|
||||
int CmdLength,
|
||||
A_UINT8 **ppEventBuffer,
|
||||
A_UINT8 **ppBufferToFree);
|
||||
|
||||
void LoadHeader(A_UCHAR *HCI_PS_Command,A_UCHAR opcode,int length,int index);
|
||||
A_UINT32 Rom_Version;
|
||||
A_UINT32 Build_Version;
|
||||
extern A_BOOL BDADDR;
|
||||
extern A_UINT32 Patch_Count;
|
||||
|
||||
A_STATUS getDeviceType(AR3K_CONFIG_INFO *pConfig, A_UINT32 * code);
|
||||
A_STATUS ReadVersionInfo(AR3K_CONFIG_INFO *pConfig);
|
||||
A_STATUS set_patch_ram(AR3K_CONFIG_INFO *pConfig,A_UCHAR *patch_loc,A_UINT8 len);
|
||||
#ifndef HCI_TRANSPORT_SDIO
|
||||
|
||||
DECLARE_WAIT_QUEUE_HEAD(PsCompleteEvent);
|
||||
DECLARE_WAIT_QUEUE_HEAD(HciEvent);
|
||||
A_UCHAR *HciEventpacket;
|
||||
rwlock_t syncLock;
|
||||
wait_queue_t Eventwait;
|
||||
|
||||
int PSHciWritepacket(struct hci_dev*,A_UCHAR* Data, A_UINT32 len);
|
||||
extern char *bdaddr;
|
||||
#endif /* HCI_TRANSPORT_SDIO */
|
||||
|
||||
A_STATUS write_bdaddr(AR3K_CONFIG_INFO *pConfig,A_UCHAR *bdaddr,int type);
|
||||
|
||||
int PSSendOps(void *arg);
|
||||
|
||||
#ifdef BT_PS_DEBUG
|
||||
void Hci_log(A_UCHAR * log_string,A_UCHAR *data,A_UINT32 len)
|
||||
{
|
||||
int i;
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("%s : ",log_string));
|
||||
for (i = 0; i < len; i++) {
|
||||
printk("0x%02x ", data[i]);
|
||||
}
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("\n...................................\n"));
|
||||
}
|
||||
#else
|
||||
#define Hci_log(string,data,len)
|
||||
#endif /* BT_PS_DEBUG */
|
||||
|
||||
|
||||
|
||||
|
||||
A_STATUS AthPSInitialize(AR3K_CONFIG_INFO *hdev)
|
||||
{
|
||||
A_STATUS status = A_OK;
|
||||
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 ps_index;
|
||||
int status = 0;
|
||||
PSCmdPacket *HciCmdList; /* List storing the commands */
|
||||
const struct firmware* firmware;
|
||||
A_UINT32 numCmds;
|
||||
A_UINT8 *event;
|
||||
A_UINT8 *bufferToFree;
|
||||
struct hci_dev *device;
|
||||
A_UCHAR *buffer;
|
||||
A_UINT32 len;
|
||||
A_UINT32 DevType;
|
||||
A_UCHAR *PsFileName;
|
||||
A_UCHAR *patchFileName;
|
||||
A_UCHAR patch_loc[40];
|
||||
A_UCHAR *path = NULL;
|
||||
A_UCHAR *config_path = NULL;
|
||||
A_UCHAR config_bdaddr[MAX_BDADDR_FORMAT_LENGTH];
|
||||
AR3K_CONFIG_INFO *hdev = (AR3K_CONFIG_INFO*)arg;
|
||||
struct device *firmwareDev = NULL;
|
||||
A_UINT8 cFlags = 0;
|
||||
A_UINT8 bit7 = 0;
|
||||
|
||||
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 =(A_UCHAR *)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 = (A_UCHAR *) 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 = (A_UCHAR *)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);
|
||||
A_FREE(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 = (A_UCHAR *)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 */
|
||||
patch_loc[0] = '\0';
|
||||
status = AthDoParsePatch(buffer,len, patch_loc);
|
||||
|
||||
A_FREE(buffer);
|
||||
} else {
|
||||
A_RELEASE_FIRMWARE(firmware);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Create an HCI command list from the parsed PS and patch information */
|
||||
AthCreateCommandList(&HciCmdList,&numCmds);
|
||||
#define CONFIG_PLATFORM 0x21
|
||||
#define CONFIG_TLPM 0x23
|
||||
#define PLATFORM_CONFIG_BIT 0x01
|
||||
#define TLPM_CONFIG_BIT 0x02
|
||||
#define IDLE_TIMEOUT_OFFSET 12
|
||||
#define WAKEUP_TIMEOUT_OFFSET 8
|
||||
#define IDLE_TIMEOUT_DEFAULT_VAL 1000
|
||||
#define WAKEUP_TIMEOUT_DEFAULT_VAL 10
|
||||
|
||||
hdev->IdleTimeout = IDLE_TIMEOUT_DEFAULT_VAL;
|
||||
hdev->WakeupTimeout = WAKEUP_TIMEOUT_DEFAULT_VAL;
|
||||
hdev->PwrMgmtEnabled = 0;
|
||||
|
||||
ps_index = 2; /* CRC + PS Reset */
|
||||
if (Patch_Count)
|
||||
ps_index += Patch_Count + 1; /* Patches + Enable patch Cmd */
|
||||
|
||||
for(i = ps_index; i <numCmds; i++) {
|
||||
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Check PS ID %x\n", HciCmdList[i].Hcipacket[4]));
|
||||
/* search for Platform config and TLPM tags */
|
||||
if((HciCmdList[i].Hcipacket[4] == CONFIG_PLATFORM) &&
|
||||
(HciCmdList[i].Hcipacket[5] == 0)) {
|
||||
cFlags |= PLATFORM_CONFIG_BIT;
|
||||
bit7 = (HciCmdList[i].Hcipacket[7]) & (1<<7);
|
||||
if(bit7) {
|
||||
hdev->PwrMgmtEnabled = 1;
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("CONFIG PLATFORM present and Pwr Manage %x\n", hdev->PwrMgmtEnabled));
|
||||
}
|
||||
}
|
||||
else if((HciCmdList[i].Hcipacket[4] == CONFIG_TLPM) &&
|
||||
(HciCmdList[i].Hcipacket[5] == 0)) {
|
||||
cFlags |= TLPM_CONFIG_BIT;
|
||||
hdev->IdleTimeout = *((A_UINT32 *)&HciCmdList[i].Hcipacket[IDLE_TIMEOUT_OFFSET + 7]);
|
||||
hdev->WakeupTimeout = *((A_UINT16 *)&HciCmdList[i].Hcipacket[WAKEUP_TIMEOUT_OFFSET + 7]);
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("hdev->idletimeout %d hdev->WakeupTimeout %d",hdev->IdleTimeout, hdev->WakeupTimeout));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 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) == A_OK) {
|
||||
if(ReadPSEvent(event) == A_OK) { /* Exit if the status is success */
|
||||
if(bufferToFree != NULL) {
|
||||
A_FREE(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) {
|
||||
A_FREE(bufferToFree);
|
||||
}
|
||||
} else {
|
||||
status = 0;
|
||||
goto complete;
|
||||
}
|
||||
/* Set Patch location */
|
||||
if(patch_loc[0] != '\0') {
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("Setting Patch Location %s\n", patch_loc));
|
||||
set_patch_ram(hdev,patch_loc,sizeof(patch_loc));
|
||||
}
|
||||
for(i = 1; i <numCmds; i++) {
|
||||
Hci_log("PS/Patch Write -->",HciCmdList[i].Hcipacket,HciCmdList[i].packetLen);
|
||||
if(SendHCICommandWaitCommandComplete
|
||||
(hdev,
|
||||
HciCmdList[i].Hcipacket,
|
||||
HciCmdList[i].packetLen,
|
||||
&event,
|
||||
&bufferToFree) == A_OK) {
|
||||
if(ReadPSEvent(event) != A_OK) { /* Exit if the status is success */
|
||||
if(bufferToFree != NULL) {
|
||||
A_FREE(bufferToFree);
|
||||
}
|
||||
status = 1;
|
||||
goto complete;
|
||||
}
|
||||
if(bufferToFree != NULL) {
|
||||
A_FREE(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);
|
||||
|
||||
|
||||
/* if Platform config is present and TLPM is not available
|
||||
* write HCI command for TLPM with default timeout values */
|
||||
if(bit7 && !(cFlags & TLPM_CONFIG_BIT)) {
|
||||
A_UCHAR TLPMHciCmd[] = {0x0b, 0xfc, 0x1c, 0x01, 0x23, 0x00, 0x18,
|
||||
0x03, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x0a, 0x00, 0x0a, 0x00, 0xe8, 0x03,
|
||||
0x00, 0x00, 0xe8, 0x03, 0x00, 0x00, 0xe8,
|
||||
0x03, 0x00, 0x00 };
|
||||
int CmdLen = sizeof(TLPMHciCmd);
|
||||
|
||||
*((A_UINT32 *)&TLPMHciCmd[IDLE_TIMEOUT_OFFSET + 7]) = hdev->IdleTimeout;
|
||||
*((A_UINT16 *)&TLPMHciCmd[WAKEUP_TIMEOUT_OFFSET + 7]) = hdev->WakeupTimeout;
|
||||
|
||||
if(SendHCICommandWaitCommandComplete
|
||||
(hdev,
|
||||
TLPMHciCmd,
|
||||
CmdLen,
|
||||
&event,
|
||||
&bufferToFree) == A_OK) {
|
||||
if(ReadPSEvent(event) != A_OK) { /* Exit if the status is success */
|
||||
if(bufferToFree != NULL) {
|
||||
A_FREE(bufferToFree);
|
||||
}
|
||||
status = 1;
|
||||
goto complete;
|
||||
}
|
||||
if(bufferToFree != NULL) {
|
||||
A_FREE(bufferToFree);
|
||||
}
|
||||
} else {
|
||||
status = 0;
|
||||
goto complete;
|
||||
}
|
||||
}
|
||||
|
||||
#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,("BDADDR 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__ ));
|
||||
goto complete;
|
||||
}
|
||||
if(NULL == firmware || firmware->size == 0) {
|
||||
goto complete;
|
||||
}
|
||||
len = (firmware->size > MAX_BDADDR_FORMAT_LENGTH)? MAX_BDADDR_FORMAT_LENGTH: firmware->size;
|
||||
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) {
|
||||
A_FREE(path);
|
||||
}
|
||||
if(config_path) {
|
||||
A_FREE(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.
|
||||
*/
|
||||
A_STATUS SendHCICommandWaitCommandComplete(AR3K_CONFIG_INFO *pConfig,
|
||||
A_UINT8 *pHCICommand,
|
||||
int CmdLength,
|
||||
A_UINT8 **ppEventBuffer,
|
||||
A_UINT8 **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 A_OK;
|
||||
}
|
||||
#endif /* HCI_TRANSPORT_SDIO */
|
||||
|
||||
A_STATUS ReadPSEvent(A_UCHAR* Data){
|
||||
|
||||
if(Data[4] == 0xFC && Data[5] == 0x00)
|
||||
{
|
||||
switch(Data[3]){
|
||||
case 0x0B:
|
||||
return A_OK;
|
||||
break;
|
||||
case 0x0C:
|
||||
/* Change Baudrate */
|
||||
return A_OK;
|
||||
break;
|
||||
case 0x04:
|
||||
return A_OK;
|
||||
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 A_OK;
|
||||
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;
|
||||
}
|
||||
A_STATUS set_patch_ram(AR3K_CONFIG_INFO *pConfig,A_UCHAR *patch_loc,A_UINT8 len)
|
||||
{
|
||||
A_UCHAR cmd[] = { 0x0B, 0xFC, 0x07, 0x0D, 0x00, 0x00, 0x00, /* Loc */0x00, 0x00, 0x00, 0x00 };
|
||||
A_UCHAR i,j;
|
||||
unsigned char loc_byte[3];
|
||||
A_UINT8 *event;
|
||||
A_UINT8 *bufferToFree = NULL;
|
||||
A_STATUS result = A_ERROR;
|
||||
A_UCHAR *loc_ptr = &cmd[7];
|
||||
|
||||
if(!patch_loc)
|
||||
return result;
|
||||
|
||||
loc_byte[2] = '\0';
|
||||
|
||||
LoadHeader(cmd, 0x0D, 4, 0);
|
||||
for( i = 0,j = 3; i < 4; i++, j--) {
|
||||
loc_byte[0] = patch_loc[0];
|
||||
loc_byte[1] = patch_loc[1];
|
||||
loc_ptr[j] = A_STRTOL(loc_byte,NULL,16);
|
||||
patch_loc+=2;
|
||||
}
|
||||
Hci_log("Patch Ram Write -->",cmd, sizeof(cmd));
|
||||
if(A_OK == SendHCICommandWaitCommandComplete(pConfig,cmd,
|
||||
sizeof(cmd),
|
||||
&event,&bufferToFree)) {
|
||||
|
||||
result = ReadPSEvent(event);
|
||||
|
||||
}
|
||||
if(bufferToFree != NULL) {
|
||||
A_FREE(bufferToFree);
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
A_STATUS write_bdaddr(AR3K_CONFIG_INFO *pConfig,A_UCHAR *bdaddr,int type)
|
||||
{
|
||||
A_UCHAR bdaddr_cmd[] = { 0x0B, 0xFC, 0x0A, 0x01, 0x01,
|
||||
0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
A_UINT8 *event;
|
||||
A_UINT8 *bufferToFree = NULL;
|
||||
A_STATUS 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];
|
||||
}
|
||||
|
||||
Hci_log("BDADDR Write -->",bdaddr_cmd,sizeof(bdaddr_cmd));
|
||||
if(A_OK == SendHCICommandWaitCommandComplete(pConfig,bdaddr_cmd,
|
||||
sizeof(bdaddr_cmd),
|
||||
&event,&bufferToFree)) {
|
||||
|
||||
if(event[4] == 0xFC && event[5] == 0x00){
|
||||
if(event[3] == 0x0B){
|
||||
result = A_OK;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if(bufferToFree != NULL) {
|
||||
A_FREE(bufferToFree);
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
A_STATUS ReadVersionInfo(AR3K_CONFIG_INFO *pConfig)
|
||||
{
|
||||
A_UINT8 hciCommand[] = {0x1E,0xfc,0x00};
|
||||
A_UINT8 *event;
|
||||
A_UINT8 *bufferToFree = NULL;
|
||||
A_STATUS result = A_ERROR;
|
||||
Hci_log("Read Version -->",hciCommand,sizeof(hciCommand));
|
||||
if(A_OK == SendHCICommandWaitCommandComplete(pConfig,hciCommand,sizeof(hciCommand),&event,&bufferToFree)) {
|
||||
result = ReadPSEvent(event);
|
||||
|
||||
}
|
||||
if(bufferToFree != NULL) {
|
||||
A_FREE(bufferToFree);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
A_STATUS getDeviceType(AR3K_CONFIG_INFO *pConfig, A_UINT32 * code)
|
||||
{
|
||||
A_UINT8 hciCommand[] = {0x05,0xfc,0x05,0x00,0x00,0x00,0x00,0x04};
|
||||
A_UINT8 *event;
|
||||
A_UINT8 *bufferToFree = NULL;
|
||||
A_UINT32 reg;
|
||||
A_STATUS result = A_ERROR;
|
||||
*code = 0;
|
||||
hciCommand[3] = (A_UINT8)(FPGA_REGISTER & 0xFF);
|
||||
hciCommand[4] = (A_UINT8)((FPGA_REGISTER >> 8) & 0xFF);
|
||||
hciCommand[5] = (A_UINT8)((FPGA_REGISTER >> 16) & 0xFF);
|
||||
hciCommand[6] = (A_UINT8)((FPGA_REGISTER >> 24) & 0xFF);
|
||||
if(A_OK == 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 = A_OK;
|
||||
|
||||
break;
|
||||
case 0x06:
|
||||
//Sleep(500);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if(bufferToFree != NULL) {
|
||||
A_FREE(bufferToFree);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* 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/string.h>
|
||||
#include <linux/signal.h>
|
||||
#include <linux/timer.h>
|
||||
|
||||
|
||||
#include <linux/ioctl.h>
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/wait.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 AR3K_CONFIG_INFO struct hci_dev
|
||||
extern wait_queue_head_t HciEvent;
|
||||
extern wait_queue_t Eventwait;
|
||||
extern A_UCHAR *HciEventpacket;
|
||||
#endif /* #ifndef HCI_TRANSPORT_SDIO */
|
||||
|
||||
A_STATUS AthPSInitialize(AR3K_CONFIG_INFO *hdev);
|
||||
A_STATUS ReadPSEvent(A_UCHAR* Data);
|
||||
#endif /* __AR3KPSCONFIG_H */
|
||||
989
drivers/net/wireless/ar6003/host/miscdrv/ar3kps/ar3kpsparser.c
Normal file
989
drivers/net/wireless/ar6003/host/miscdrv/ar3kps/ar3kpsparser.c
Normal file
|
|
@ -0,0 +1,989 @@
|
|||
/*
|
||||
* 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"
|
||||
|
||||
#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++
|
||||
#define MIN(x, y) (((x) <= (y))? (x):(y))
|
||||
#define MAX(x, y) (((x) >= (y))? (x):(y))
|
||||
|
||||
#define UNUSED(x) (x=x)
|
||||
|
||||
#define IS_BETWEEN(x, lower, upper) (((lower) <= (x)) && ((x) <= (upper)))
|
||||
#define IS_DIGIT(c) (IS_BETWEEN((c), '0', '9'))
|
||||
#define IS_HEX(c) (IS_BETWEEN((c), '0', '9') || IS_BETWEEN((c), 'a', 'f') || IS_BETWEEN((c), 'A', 'F'))
|
||||
#define TO_LOWER(c) (IS_BETWEEN((c), 'A', 'Z') ? ((c) - 'A' + 'a') : (c))
|
||||
#define IS_BLANK(c) ((c) == ' ')
|
||||
#define CONV_DEC_DIGIT_TO_VALUE(c) ((c) - '0')
|
||||
#define CONV_HEX_DIGIT_TO_VALUE(c) (IS_DIGIT(c) ? ((c) - '0') : (IS_BETWEEN((c), 'A', 'Z') ? ((c) - 'A' + 10) : ((c) - 'a' + 10)))
|
||||
#define CONV_VALUE_TO_HEX(v) ((A_UINT8)( ((v & 0x0F) <= 9) ? ((v & 0x0F) + '0') : ((v & 0x0F) - 10 + 'A') ) )
|
||||
|
||||
|
||||
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
|
||||
{
|
||||
A_UINT32 TagId;
|
||||
A_UINT32 TagLen;
|
||||
A_UINT8 *TagData;
|
||||
} tPsTagEntry, *tpPsTagEntry;
|
||||
|
||||
typedef struct tRamPatch
|
||||
{
|
||||
A_UINT16 Len;
|
||||
A_UINT8 * Data;
|
||||
} tRamPatch, *ptRamPatch;
|
||||
|
||||
|
||||
|
||||
typedef struct ST_PS_DATA_FORMAT {
|
||||
enum eType eDataType;
|
||||
A_BOOL bIsArray;
|
||||
}ST_PS_DATA_FORMAT;
|
||||
|
||||
typedef struct ST_READ_STATUS {
|
||||
unsigned uTagID;
|
||||
unsigned uSection;
|
||||
unsigned uLineCount;
|
||||
unsigned uCharCount;
|
||||
unsigned uByteCount;
|
||||
}ST_READ_STATUS;
|
||||
|
||||
|
||||
/* Stores the number of PS Tags */
|
||||
static A_UINT32 Tag_Count = 0;
|
||||
|
||||
/* Stores the number of patch commands */
|
||||
A_UINT32 Patch_Count = 0;
|
||||
static A_UINT32 Total_tag_lenght = 0;
|
||||
A_BOOL BDADDR = FALSE;
|
||||
A_UINT32 StartTagId;
|
||||
|
||||
tPsTagEntry PsTagEntry[RAMPS_MAX_PS_TAGS_PER_FILE];
|
||||
tRamPatch RamPatch[MAX_NUM_PATCH_ENTRY];
|
||||
|
||||
|
||||
A_STATUS AthParseFilesUnified(A_UCHAR *srcbuffer,A_UINT32 srclen, int FileFormat);
|
||||
char AthReadChar(A_UCHAR *buffer, A_UINT32 len,A_UINT32 *pos);
|
||||
char * AthGetLine(char * buffer, int maxlen, A_UCHAR *srcbuffer,A_UINT32 len,A_UINT32 *pos);
|
||||
static A_STATUS AthPSCreateHCICommand(A_UCHAR Opcode, A_UINT32 Param1,PSCmdPacket *PSPatchPacket,A_UINT32 *index);
|
||||
|
||||
/* Function to reads the next character from the input buffer */
|
||||
char AthReadChar(A_UCHAR *buffer, A_UINT32 len,A_UINT32 *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, 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, 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);
|
||||
}
|
||||
}
|
||||
A_STATUS AthParseFilesUnified(A_UCHAR *srcbuffer,A_UINT32 srclen, int FileFormat)
|
||||
{
|
||||
char *Buffer;
|
||||
char *pCharLine;
|
||||
A_UINT8 TagCount;
|
||||
A_UINT16 ByteCount;
|
||||
A_UINT8 ParseSection=RAM_PS_SECTION;
|
||||
A_UINT32 pos;
|
||||
|
||||
|
||||
|
||||
int uReadCount;
|
||||
ST_PS_DATA_FORMAT stPS_DataFormat;
|
||||
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) {
|
||||
A_FREE(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) {
|
||||
A_FREE(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) {
|
||||
A_FREE(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) {
|
||||
A_FREE(Buffer);
|
||||
}
|
||||
return A_ERROR;
|
||||
}
|
||||
PsTagEntry[TagCount].TagLen = ByteCount;
|
||||
PsTagEntry[TagCount].TagData = (A_UINT8*)A_MALLOC(ByteCount);
|
||||
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) {
|
||||
A_FREE(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] =
|
||||
(A_UINT8)(CONV_HEX_DIGIT_TO_VALUE(pCharLine[stReadStatus.uCharCount]) << 4)
|
||||
| (A_UINT8)(CONV_HEX_DIGIT_TO_VALUE(pCharLine[stReadStatus.uCharCount + 1]));
|
||||
|
||||
PsTagEntry[TagCount].TagData[stReadStatus.uByteCount+1] =
|
||||
(A_UINT8)(CONV_HEX_DIGIT_TO_VALUE(pCharLine[stReadStatus.uCharCount + 3]) << 4)
|
||||
| (A_UINT8)(CONV_HEX_DIGIT_TO_VALUE(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) {
|
||||
A_FREE(Buffer);
|
||||
}
|
||||
return A_ERROR;
|
||||
//Sleep (3000);
|
||||
//exit(1);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
{
|
||||
if(Buffer != NULL) {
|
||||
A_FREE(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) {
|
||||
A_FREE(Buffer);
|
||||
}
|
||||
return A_ERROR;
|
||||
}
|
||||
|
||||
if(Buffer != NULL) {
|
||||
A_FREE(Buffer);
|
||||
}
|
||||
return A_OK;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/********************/
|
||||
|
||||
|
||||
A_STATUS GetNextTwoChar(A_UCHAR *srcbuffer,A_UINT32 len, A_UINT32 *pos, char * buffer)
|
||||
{
|
||||
unsigned char ch;
|
||||
|
||||
ch = AthReadChar(srcbuffer,len,pos);
|
||||
if(ch != '\0' && IS_HEX(ch)) {
|
||||
buffer[0] = ch;
|
||||
} else
|
||||
{
|
||||
return A_ERROR;
|
||||
}
|
||||
ch = AthReadChar(srcbuffer,len,pos);
|
||||
if(ch != '\0' && IS_HEX(ch)) {
|
||||
buffer[1] = ch;
|
||||
} else
|
||||
{
|
||||
return A_ERROR;
|
||||
}
|
||||
return A_OK;
|
||||
}
|
||||
#define PATCH_LOC_KEY "DA:"
|
||||
#define PATCH_LOC_STRING_LEN 8
|
||||
A_STATUS AthDoParsePatch(A_UCHAR *patchbuffer, A_UINT32 patchlen, A_UCHAR *patch_loc)
|
||||
{
|
||||
|
||||
char Byte[3];
|
||||
char Line[MAX_BYTE_LENGTH + 1];
|
||||
int ByteCount,ByteCount_Org;
|
||||
int count;
|
||||
int i,j,k;
|
||||
int data;
|
||||
A_UINT32 filepos;
|
||||
Byte[2] = '\0';
|
||||
j = 0;
|
||||
filepos = 0;
|
||||
Patch_Count = 0;
|
||||
|
||||
if(!patch_loc)
|
||||
return A_ERROR;
|
||||
|
||||
while(NULL != AthGetLine(Line,MAX_BYTE_LENGTH,patchbuffer,patchlen,&filepos)) {
|
||||
if(strlen(Line) <= 1) {
|
||||
continue;
|
||||
} else if (strstr(Line, PATCH_LOC_KEY) == Line) {
|
||||
strncpy(patch_loc, &Line[sizeof(PATCH_LOC_KEY) -1],PATCH_LOC_STRING_LEN);
|
||||
patch_loc[PATCH_LOC_STRING_LEN] = '\0';
|
||||
continue;
|
||||
} else if(IS_HEX(Line[0])){
|
||||
break;
|
||||
} else {
|
||||
return A_ERROR;
|
||||
}
|
||||
}
|
||||
ByteCount = A_STRTOL(Line, NULL, 16);
|
||||
ByteCount_Org = ByteCount;
|
||||
|
||||
if(!ByteCount)
|
||||
return A_ERROR;
|
||||
|
||||
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++) {
|
||||
A_FREE(RamPatch[i].Data);
|
||||
}
|
||||
return A_ERROR;
|
||||
}
|
||||
RamPatch[Patch_Count].Len= MAX_BYTE_LENGTH;
|
||||
RamPatch[Patch_Count].Data = (A_UINT8*)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 = (A_UINT8*)A_MALLOC(ByteCount);
|
||||
Patch_Count ++;
|
||||
}
|
||||
count = 0;
|
||||
while(ByteCount_Org > MAX_BYTE_LENGTH){
|
||||
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 A_OK;
|
||||
}
|
||||
|
||||
|
||||
/********************/
|
||||
A_STATUS AthDoParsePS(A_UCHAR *srcbuffer, A_UINT32 srclen)
|
||||
{
|
||||
A_STATUS status;
|
||||
int i;
|
||||
A_BOOL BDADDR_Present = A_ERROR;
|
||||
|
||||
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 = A_OK;
|
||||
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, A_UCHAR *srcbuffer,A_UINT32 len,A_UINT32 *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;
|
||||
}
|
||||
|
||||
void LoadHeader(A_UCHAR *HCI_PS_Command,A_UCHAR 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(PSCmdPacket **HciPacketList, A_UINT32 *numPackets)
|
||||
{
|
||||
|
||||
A_UINT8 count;
|
||||
A_UINT32 NumcmdEntry = 0;
|
||||
|
||||
A_UINT32 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,(A_UINT32)sizeof(PSCmdPacket) * NumcmdEntry));
|
||||
(*HciPacketList) = A_MALLOC(sizeof(PSCmdPacket) * 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"));
|
||||
|
||||
}
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_ERR,("PS Count %d Patch Count %d",Tag_Count, Patch_Count));
|
||||
for(count = 0; count < Patch_Count; count++) {
|
||||
|
||||
A_FREE(RamPatch[Patch_Count].Data);
|
||||
}
|
||||
|
||||
for(count = 0; count < Tag_Count; count++) {
|
||||
|
||||
A_FREE(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 A_STATUS AthPSCreateHCICommand(A_UCHAR Opcode, A_UINT32 Param1,PSCmdPacket *PSPatchPacket,A_UINT32 *index)
|
||||
{
|
||||
A_UCHAR *HCI_PS_Command;
|
||||
A_UINT32 Length;
|
||||
int i,j;
|
||||
|
||||
switch(Opcode)
|
||||
{
|
||||
case WRITE_PATCH:
|
||||
|
||||
|
||||
for(i=0;i< Param1;i++){
|
||||
|
||||
HCI_PS_Command = (A_UCHAR *) A_MALLOC(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 = (A_UCHAR *) 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 = (A_UCHAR *) 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 = (A_UCHAR *) 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 = (A_UCHAR *) 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 A_OK;
|
||||
}
|
||||
A_STATUS AthFreeCommandList(PSCmdPacket **HciPacketList, A_UINT32 numPackets)
|
||||
{
|
||||
int i;
|
||||
if(*HciPacketList == NULL) {
|
||||
return A_ERROR;
|
||||
}
|
||||
for(i = 0; i < numPackets;i++) {
|
||||
A_FREE((*HciPacketList)[i].Hcipacket);
|
||||
}
|
||||
A_FREE(*HciPacketList);
|
||||
return A_OK;
|
||||
}
|
||||
127
drivers/net/wireless/ar6003/host/miscdrv/ar3kps/ar3kpsparser.h
Normal file
127
drivers/net/wireless/ar6003/host/miscdrv/ar3kps/ar3kpsparser.h
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// 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_types.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 */
|
||||
|
||||
#ifndef A_UINT32
|
||||
#define A_UCHAR unsigned char
|
||||
#define A_UINT32 unsigned long
|
||||
#define A_UINT16 unsigned short
|
||||
#define A_UINT8 unsigned char
|
||||
#define A_BOOL unsigned char
|
||||
#endif /* A_UINT32 */
|
||||
|
||||
#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 */
|
||||
|
||||
|
||||
#ifndef A_FREE
|
||||
#define A_FREE(addr) kfree((addr))
|
||||
#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 30000
|
||||
|
||||
/* Maximum HCI packets that will be formed from the Patch file */
|
||||
#define MAX_NUM_PATCH_ENTRY (MAX_PATCH_SIZE/MAX_BYTE_LENGTH) + 1
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct PSCmdPacket
|
||||
{
|
||||
A_UCHAR *Hcipacket;
|
||||
int packetLen;
|
||||
} PSCmdPacket;
|
||||
|
||||
/* Parses a Patch information buffer and store it in global structure */
|
||||
A_STATUS AthDoParsePatch(A_UCHAR *, A_UINT32, A_UCHAR*);
|
||||
|
||||
/* parses a PS information buffer and stores it in a global structure */
|
||||
A_STATUS AthDoParsePS(A_UCHAR *, A_UINT32);
|
||||
|
||||
/*
|
||||
* 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(PSCmdPacket **, A_UINT32 *);
|
||||
|
||||
/* Cleanup the dynamically allicated HCI command list */
|
||||
A_STATUS AthFreeCommandList(PSCmdPacket **HciPacketList, A_UINT32 numPackets);
|
||||
#endif /* __AR3KPSPARSER_H */
|
||||
882
drivers/net/wireless/ar6003/host/miscdrv/common_drv.c
Normal file
882
drivers/net/wireless/ar6003/host/miscdrv/common_drv.c
Normal file
|
|
@ -0,0 +1,882 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <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 "a_types.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"
|
||||
#include "target_reg_table.h"
|
||||
#include "host_reg_table.h"
|
||||
|
||||
static ATH_DEBUG_MODULE_DBG_INFO *g_pModuleInfoHead = NULL;
|
||||
static A_MUTEX_T g_ModuleListLock;
|
||||
static A_BOOL g_ModuleDebugInit = FALSE;
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
ATH_DEBUG_INSTANTIATE_MODULE_VAR(misc,
|
||||
"misc",
|
||||
"Common and misc APIs",
|
||||
ATH_DEBUG_MASK_DEFAULTS,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
#endif
|
||||
|
||||
#define AR6001_LOCAL_COUNT_ADDRESS 0x0c014080
|
||||
#define AR6002_LOCAL_COUNT_ADDRESS 0x00018080
|
||||
#define AR6003_LOCAL_COUNT_ADDRESS 0x00018080
|
||||
|
||||
static A_UINT8 custDataAR6002[AR6002_CUST_DATA_SIZE];
|
||||
static A_UINT8 custDataAR6003[AR6003_CUST_DATA_SIZE];
|
||||
static A_UINT8 custDataMCKINLEY[MCKINLEY_CUST_DATA_SIZE];
|
||||
|
||||
|
||||
/*
|
||||
* Read from the AR6000 through its diagnostic window.
|
||||
* No cooperation from the Target is required for this.
|
||||
*/
|
||||
A_STATUS
|
||||
ar6000_ReadRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data)
|
||||
{
|
||||
return HIFDiagReadAccess(hifDevice, *address, data);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Write to the AR6000 through its diagnostic window.
|
||||
* No cooperation from the Target is required for this.
|
||||
*/
|
||||
A_STATUS
|
||||
ar6000_WriteRegDiag(HIF_DEVICE *hifDevice, A_UINT32 *address, A_UINT32 *data)
|
||||
{
|
||||
return HIFDiagWriteAccess(hifDevice, *address, *data);
|
||||
}
|
||||
|
||||
A_STATUS
|
||||
ar6000_ReadDataDiag(HIF_DEVICE *hifDevice, A_UINT32 address,
|
||||
A_UCHAR *data, A_UINT32 length)
|
||||
{
|
||||
A_UINT32 count;
|
||||
A_STATUS status = A_OK;
|
||||
|
||||
for (count = 0; count < length; count += 4, address += 4) {
|
||||
if ((status = HIFDiagReadAccess(hifDevice, address,
|
||||
(A_UINT32 *)&data[count])) != A_OK)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
A_STATUS
|
||||
ar6000_WriteDataDiag(HIF_DEVICE *hifDevice, A_UINT32 address,
|
||||
A_UCHAR *data, A_UINT32 length)
|
||||
{
|
||||
A_UINT32 count;
|
||||
A_STATUS status = A_OK;
|
||||
|
||||
for (count = 0; count < length; count += 4, address += 4) {
|
||||
if ((status = HIFDiagWriteAccess(hifDevice, address,
|
||||
*((A_UINT32 *)&data[count]))) != A_OK)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#ifdef HIF_MESSAGE_BASED
|
||||
|
||||
/* TODO : for message based interfaces there are no HOST registers. These are just
|
||||
* stub functions for now */
|
||||
|
||||
A_STATUS
|
||||
ar6k_ReadTargetRegister(HIF_DEVICE *hifDevice, int regsel, A_UINT32 *regval)
|
||||
{
|
||||
|
||||
/* TODO */
|
||||
return A_ERROR;
|
||||
}
|
||||
|
||||
void
|
||||
ar6k_FetchTargetRegs(HIF_DEVICE *hifDevice, A_UINT32 *targregs)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<AR6003_FETCH_TARG_REGS_COUNT; i++) {
|
||||
targregs[i] = 0xffffffff;
|
||||
}
|
||||
}
|
||||
|
||||
#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 A_STATUS
|
||||
_delay_until_target_alive(HIF_DEVICE *hifDevice, A_INT32 wait_msecs, A_UINT32 TargetType)
|
||||
{
|
||||
A_INT32 actual_wait;
|
||||
A_INT32 i;
|
||||
A_UINT32 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++) {
|
||||
A_UINT32 data;
|
||||
|
||||
A_MDELAY(100);
|
||||
actual_wait += 100;
|
||||
|
||||
data = 0;
|
||||
if (ar6000_ReadRegDiag(hifDevice, &address, &data) != A_OK) {
|
||||
return A_ERROR;
|
||||
}
|
||||
|
||||
if (data != 0) {
|
||||
/* No need to wait longer -- we have a BMI credit */
|
||||
return A_OK;
|
||||
}
|
||||
}
|
||||
return A_ERROR; /* timed out */
|
||||
}
|
||||
#endif
|
||||
|
||||
#define AR6001_RESET_CONTROL_ADDRESS 0x0C000000
|
||||
#define AR6002_RESET_CONTROL_ADDRESS 0x00004000
|
||||
#define AR6003_RESET_CONTROL_ADDRESS 0x00004000
|
||||
#define MCKINLEY_RESET_CONTROL_ADDRESS 0x00004000
|
||||
#define AR6001_WLAN_RESET_CONTROL_ADDRESS 0x0C000000
|
||||
#define AR6002_WLAN_RESET_CONTROL_ADDRESS 0x00004000
|
||||
#define AR6003_WLAN_RESET_CONTROL_ADDRESS 0x00004000
|
||||
#define MCKINLEY_WLAN_RESET_CONTROL_ADDRESS 0x00005000
|
||||
/* reset device */
|
||||
A_STATUS ar6000_reset_device(HIF_DEVICE *hifDevice, A_UINT32 TargetType, A_BOOL waitForCompletion, A_BOOL coldReset)
|
||||
{
|
||||
A_STATUS status = A_OK;
|
||||
A_UINT32 address = 0;
|
||||
A_UINT32 data;
|
||||
|
||||
do {
|
||||
// Workaround BEGIN
|
||||
// address = RESET_CONTROL_ADDRESS;
|
||||
|
||||
if (coldReset) {
|
||||
data = WLAN_RESET_CONTROL_COLD_RST_MASK;
|
||||
/* Hardcode the address of RESET_CONTROL_ADDRESS based on the target type */
|
||||
if (TargetType == TARGET_TYPE_AR6002) {
|
||||
address = AR6002_WLAN_RESET_CONTROL_ADDRESS;
|
||||
} else if (TargetType == TARGET_TYPE_AR6003) {
|
||||
address = AR6003_WLAN_RESET_CONTROL_ADDRESS;
|
||||
} else if (TargetType == TARGET_TYPE_MCKINLEY) {
|
||||
address = MCKINLEY_WLAN_RESET_CONTROL_ADDRESS;
|
||||
} else {
|
||||
A_ASSERT(0);
|
||||
}
|
||||
}
|
||||
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 if (TargetType == TARGET_TYPE_MCKINLEY) {
|
||||
address = MCKINLEY_RESET_CONTROL_ADDRESS;
|
||||
} else {
|
||||
A_ASSERT(0);
|
||||
}
|
||||
}
|
||||
|
||||
status = ar6000_WriteRegDiag(hifDevice, &address, &data);
|
||||
|
||||
if (A_FAILED(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 (A_FAILED(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 (A_FAILED(status)) {
|
||||
AR_DEBUG_PRINTF(ATH_LOG_ERR, ("Failed to reset target \n"));
|
||||
}
|
||||
|
||||
return A_OK;
|
||||
}
|
||||
|
||||
/* This should be called in BMI phase after firmware is downloaded */
|
||||
void
|
||||
ar6000_copy_cust_data_from_target(HIF_DEVICE *hifDevice, A_UINT32 TargetType)
|
||||
{
|
||||
A_UINT32 eepHeaderAddr;
|
||||
A_UINT8 AR6003CustDataShadow[AR6003_CUST_DATA_SIZE+4];
|
||||
A_UINT8 MCKINLEYCustDataShadow[MCKINLEY_CUST_DATA_SIZE+4];
|
||||
A_INT32 i;
|
||||
|
||||
if (BMIReadMemory(hifDevice,
|
||||
HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_board_data),
|
||||
(A_UCHAR *)&eepHeaderAddr,
|
||||
4)!= A_OK)
|
||||
{
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMIReadMemory for reading board data address failed \n"));
|
||||
return;
|
||||
}
|
||||
if (TargetType == TARGET_TYPE_MCKINLEY) {
|
||||
eepHeaderAddr += 36; /* MCKINLEY customer data section offset is 37 */
|
||||
|
||||
for (i=0; i<MCKINLEY_CUST_DATA_SIZE+4; i+=4){
|
||||
if (BMIReadSOCRegister(hifDevice, eepHeaderAddr, (A_UINT32 *)&MCKINLEYCustDataShadow[i])!= A_OK) {
|
||||
AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("BMIReadSOCRegister () failed \n"));
|
||||
return ;
|
||||
}
|
||||
eepHeaderAddr +=4;
|
||||
}
|
||||
|
||||
memcpy(custDataMCKINLEY, MCKINLEYCustDataShadow+1, MCKINLEY_CUST_DATA_SIZE);
|
||||
}
|
||||
|
||||
|
||||
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, (A_UINT32 *)&AR6003CustDataShadow[i])!= A_OK) {
|
||||
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, (A_UINT32 *)&custDataAR6002[i])!= A_OK) {
|
||||
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 */
|
||||
A_UINT8 *
|
||||
ar6000_get_cust_data_buffer(A_UINT32 TargetType)
|
||||
{
|
||||
if (TargetType == TARGET_TYPE_MCKINLEY)
|
||||
return custDataMCKINLEY;
|
||||
|
||||
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 REG_DUMP_COUNT_MCKINLEY 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
|
||||
#if REG_DUMP_COUNT_MCKINLEY > REGISTER_DUMP_LEN_MAX
|
||||
#error "REG_DUMP_COUNT_MCKINLEY too large"
|
||||
#endif
|
||||
|
||||
|
||||
void ar6000_dump_target_assert_info(HIF_DEVICE *hifDevice, A_UINT32 TargetType)
|
||||
{
|
||||
A_UINT32 address;
|
||||
A_UINT32 regDumpArea = 0;
|
||||
A_STATUS status;
|
||||
A_UINT32 regDumpValues[REGISTER_DUMP_LEN_MAX];
|
||||
A_UINT32 regDumpCount = 0;
|
||||
A_UINT32 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 if (TargetType == TARGET_TYPE_MCKINLEY) {
|
||||
regDumpCount = REG_DUMP_COUNT_MCKINLEY;
|
||||
} else {
|
||||
A_ASSERT(0);
|
||||
}
|
||||
|
||||
/* read RAM location through diagnostic window */
|
||||
status = ar6000_ReadRegDiag(hifDevice, &address, ®DumpArea);
|
||||
|
||||
if (A_FAILED(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,
|
||||
(A_UCHAR *)®DumpValues[0],
|
||||
regDumpCount * (sizeof(A_UINT32)));
|
||||
|
||||
if (A_FAILED(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++)
|
||||
{
|
||||
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 */
|
||||
A_STATUS ar6000_set_htc_params(HIF_DEVICE *hifDevice,
|
||||
A_UINT32 TargetType,
|
||||
A_UINT32 MboxIsrYieldValue,
|
||||
A_UINT8 HtcControlBuffers)
|
||||
{
|
||||
A_STATUS status;
|
||||
A_UINT32 blocksizes[HTC_MAILBOX_NUM_MAX];
|
||||
|
||||
do {
|
||||
/* get the block sizes */
|
||||
status = HIFConfigureDevice(hifDevice, HIF_DEVICE_GET_MBOX_BLOCK_SIZE,
|
||||
blocksizes, sizeof(blocksizes));
|
||||
|
||||
if (A_FAILED(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] |= ((A_UINT32)HtcControlBuffers) << 16;
|
||||
}
|
||||
|
||||
/* set the host interest area for the block size */
|
||||
status = BMIWriteMemory(hifDevice,
|
||||
HOST_INTEREST_ITEM_ADDRESS(TargetType, hi_mbox_io_block_sz),
|
||||
(A_UCHAR *)&blocksizes[1],
|
||||
4);
|
||||
|
||||
if (A_FAILED(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),
|
||||
(A_UCHAR *)&MboxIsrYieldValue,
|
||||
4);
|
||||
|
||||
if (A_FAILED(status)) {
|
||||
AR_DEBUG_PRINTF(ATH_LOG_ERR,("BMIWriteMemory for yield limit failed \n"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} while (FALSE);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
static A_STATUS prepare_ar6002(HIF_DEVICE *hifDevice, A_UINT32 TargetVersion)
|
||||
{
|
||||
A_STATUS status = A_OK;
|
||||
|
||||
/* placeholder */
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static A_STATUS prepare_ar6003(HIF_DEVICE *hifDevice, A_UINT32 TargetVersion)
|
||||
{
|
||||
A_STATUS status = A_OK;
|
||||
|
||||
/* placeholder */
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static A_STATUS prepare_MCKINLEY(HIF_DEVICE *hifDevice, A_UINT32 TargetVersion)
|
||||
{
|
||||
A_STATUS status = A_OK;
|
||||
A_UINT32 value = 0;
|
||||
|
||||
/* force the setting to disable sleep for Bringup FIXME_MK */
|
||||
value |= WLAN_SYSTEM_SLEEP_DISABLE_MASK;
|
||||
|
||||
status = BMIWriteMemory(hifDevice,
|
||||
HOST_INTEREST_ITEM_ADDRESS(TARGET_TYPE_AR6002, hi_system_sleep_setting),
|
||||
(A_UCHAR *)&value,
|
||||
4);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* this function assumes the caller has already initialized the BMI APIs */
|
||||
A_STATUS ar6000_prepare_target(HIF_DEVICE *hifDevice,
|
||||
A_UINT32 TargetType,
|
||||
A_UINT32 TargetVersion)
|
||||
{
|
||||
if (TargetType == TARGET_TYPE_AR6002) {
|
||||
/* do any preparations for AR6002 devices */
|
||||
return prepare_ar6002(hifDevice,TargetVersion);
|
||||
} else if (TargetType == TARGET_TYPE_AR6003) {
|
||||
return prepare_ar6003(hifDevice,TargetVersion);
|
||||
} else if (TargetType == TARGET_TYPE_MCKINLEY) {
|
||||
return prepare_MCKINLEY(hifDevice,TargetVersion);
|
||||
}
|
||||
|
||||
return A_OK;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_AR6002_REV1_FORCE_HOST)
|
||||
/*
|
||||
* Call this function just before the call to BMIInit
|
||||
* in order to force* AR6002 rev 1.x firmware to detect a Host.
|
||||
* THIS IS FOR USE ONLY WITH AR6002 REV 1.x.
|
||||
* TBDXXX: Remove this function when REV 1.x is desupported.
|
||||
*/
|
||||
A_STATUS
|
||||
ar6002_REV1_reset_force_host (HIF_DEVICE *hifDevice)
|
||||
{
|
||||
A_INT32 i;
|
||||
struct forceROM_s {
|
||||
A_UINT32 addr;
|
||||
A_UINT32 data;
|
||||
};
|
||||
struct forceROM_s *ForceROM;
|
||||
A_INT32 szForceROM;
|
||||
A_STATUS status = A_OK;
|
||||
A_UINT32 address;
|
||||
A_UINT32 data;
|
||||
|
||||
/* Force AR6002 REV1.x to recognize Host presence.
|
||||
*
|
||||
* Note: Use RAM at 0x52df80..0x52dfa0 with ROM Remap entry 0
|
||||
* so that this workaround functions with AR6002.war1.sh. We
|
||||
* could fold that entire workaround into this one, but it's not
|
||||
* worth the effort at this point. This workaround cannot be
|
||||
* merged into the other workaround because this must be done
|
||||
* before BMI.
|
||||
*/
|
||||
|
||||
static struct forceROM_s ForceROM_NEW[] = {
|
||||
{0x52df80, 0x20f31c07},
|
||||
{0x52df84, 0x92374420},
|
||||
{0x52df88, 0x1d120c03},
|
||||
{0x52df8c, 0xff8216f0},
|
||||
{0x52df90, 0xf01d120c},
|
||||
{0x52df94, 0x81004136},
|
||||
{0x52df98, 0xbc9100bd},
|
||||
{0x52df9c, 0x00bba100},
|
||||
|
||||
{0x00008000|MC_TCAM_TARGET_ADDRESS, 0x0012dfe0}, /* Use remap entry 0 */
|
||||
{0x00008000|MC_TCAM_COMPARE_ADDRESS, 0x000e2380},
|
||||
{0x00008000|MC_TCAM_MASK_ADDRESS, 0x00000000},
|
||||
{0x00008000|MC_TCAM_VALID_ADDRESS, 0x00000001},
|
||||
|
||||
{0x00018000|(LOCAL_COUNT_ADDRESS+0x10), 0}, /* clear BMI credit counter */
|
||||
|
||||
{0x00004000|AR6002_RESET_CONTROL_ADDRESS, RESET_CONTROL_WARM_RST_MASK},
|
||||
};
|
||||
|
||||
address = 0x004ed4b0; /* REV1 target software ID is stored here */
|
||||
status = ar6000_ReadRegDiag(hifDevice, &address, &data);
|
||||
if (A_FAILED(status) || (data != AR6002_VERSION_REV1)) {
|
||||
return A_ERROR; /* Not AR6002 REV1 */
|
||||
}
|
||||
|
||||
ForceROM = ForceROM_NEW;
|
||||
szForceROM = sizeof(ForceROM_NEW)/sizeof(*ForceROM);
|
||||
|
||||
ATH_DEBUG_PRINTF (DBG_MISC_DRV, ATH_DEBUG_TRC, ("Force Target to recognize Host....\n"));
|
||||
for (i = 0; i < szForceROM; i++)
|
||||
{
|
||||
if (ar6000_WriteRegDiag(hifDevice,
|
||||
&ForceROM[i].addr,
|
||||
&ForceROM[i].data) != A_OK)
|
||||
{
|
||||
ATH_DEBUG_PRINTF (DBG_MISC_DRV, ATH_DEBUG_TRC, ("Cannot force Target to recognize Host!\n"));
|
||||
return A_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
A_MDELAY(1000);
|
||||
|
||||
return A_OK;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_AR6002_REV1_FORCE_HOST */
|
||||
|
||||
void DebugDumpBytes(A_UCHAR *buffer, A_UINT16 length, char *pDescription)
|
||||
{
|
||||
A_CHAR stream[60];
|
||||
A_CHAR byteOffsetStr[10];
|
||||
A_UINT32 i;
|
||||
A_UINT16 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;
|
||||
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(A_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 (A_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(A_CHAR *module_name)
|
||||
{
|
||||
ATH_DEBUG_MODULE_DBG_INFO *pInfo = g_pModuleInfoHead;
|
||||
|
||||
if (!g_ModuleDebugInit) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (A_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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
A_STATUS a_get_module_mask(A_CHAR *module_name, A_UINT32 *pMask)
|
||||
{
|
||||
ATH_DEBUG_MODULE_DBG_INFO *pInfo = FindModule(module_name);
|
||||
|
||||
if (NULL == pInfo) {
|
||||
return A_ERROR;
|
||||
}
|
||||
|
||||
*pMask = pInfo->CurrentMask;
|
||||
return A_OK;
|
||||
}
|
||||
|
||||
A_STATUS a_set_module_mask(A_CHAR *module_name, A_UINT32 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 A_OK;
|
||||
}
|
||||
|
||||
|
||||
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 */
|
||||
A_STATUS ar6000_set_hci_bridge_flags(HIF_DEVICE *hifDevice,
|
||||
A_UINT32 TargetType,
|
||||
A_UINT32 Flags)
|
||||
{
|
||||
A_STATUS status = A_OK;
|
||||
|
||||
do {
|
||||
|
||||
if ((TargetType != TARGET_TYPE_AR6003) && (TargetType != TARGET_TYPE_MCKINLEY)) {
|
||||
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),
|
||||
(A_UCHAR *)&Flags,
|
||||
4);
|
||||
|
||||
|
||||
} while (FALSE);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user