Import FreeBSD's ath(4) of 2005-05-18

This commit is contained in:
dyoung 2005-06-21 20:37:47 +00:00
parent 93c901ce88
commit b9cea51a99
68 changed files with 82141 additions and 1363 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,58 @@
#
# Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer,
# without modification.
# 2. Redistributions in binary form must reproduce at minimum a disclaimer
# similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
# redistribution must be conditioned upon including a substantially
# similar Disclaimer requirement for further binary redistribution.
# 3. Neither the names of the above-listed copyright holders nor the names
# of any contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# Alternatively, this software may be distributed under the terms of the
# GNU General Public License ("GPL") version 2 as published by the Free
# Software Foundation.
#
# NO WARRANTY
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
# THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGES.
#
# $Id: athhal-x86_64-elf.inc,v 1.1.1.1 2005/06/21 20:37:54 dyoung Exp $
#
#
# Compilation configuration for building x86-64-elf.
#
#
ifndef TOOLPREFIX
TOOLPREFIX= /pub/gnu/bin/x86_64-linux-
endif
#
CC= ${TOOLPREFIX}gcc
LD= ${TOOLPREFIX}ld
STRIP= ${TOOLPREFIX}strip
OBJCOPY=${TOOLPREFIX}objcopy
NM= ${TOOLPREFIX}nm
COPTS+= -DAH_BYTE_ORDER=AH_LITTLE_ENDIAN
COPTS+= -mcmodel=kernel -mno-red-zone
ifndef CONFIG_FRAME_POINTER
COPTS+= -fomit-frame-pointer
endif

View File

@ -0,0 +1,6 @@
#define AH_SUPPORT_AR5210 1
#define AH_SUPPORT_AR5211 1
#define AH_SUPPORT_AR5212 1
#define AH_SUPPORT_5111 1
#define AH_SUPPORT_5112 1
#define AH_SUPPORT_2413 1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,77 @@
#
# Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer,
# without modification.
# 2. Redistributions in binary form must reproduce at minimum a disclaimer
# similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
# redistribution must be conditioned upon including a substantially
# similar Disclaimer requirement for further binary redistribution.
# 3. Neither the names of the above-listed copyright holders nor the names
# of any contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# Alternatively, this software may be distributed under the terms of the
# GNU General Public License ("GPL") version 2 as published by the Free
# Software Foundation.
#
# NO WARRANTY
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
# THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGES.
#
# $Id: athhal-arm9-le-thumb-elf.inc,v 1.1.1.1 2005/06/21 20:37:58 dyoung Exp $
#
#
# Compilation configuration for building little-endian ARM9/arm-elf.
#
# Known to work on:
# Arm940T
#
# Force register read/write operations to go through a function so
# ARM users can implement a windowing scheme to access registers in
# the PCI address space.
#
AH_REGOPS_FUNC=1
#
# Built with GNU cross-devel tools:
#
# PREFIX=/pub/gnu
# BINUTILS=binutils-2.14
# GCC=gcc-3.3.2
# target=arm-elf
#
# ${BINUTILS}/configure --target=$target --prefix=${PREFIX}
# ${GCC}/configure --target=$target --prefix=${PREFIX} \
# --enable-languages=c --with-gnu-as --with-gnu-ld \
# --with-newlib --with-gxx-include-dir=${PREFIX}/$target/include
#
ifndef TOOLPREFIX
TOOLPREFIX= /pub/gnu/bin/arm-elf-
endif
#
CC= ${TOOLPREFIX}gcc
LD= ${TOOLPREFIX}ld
STRIP= ${TOOLPREFIX}strip
OBJCOPY=${TOOLPREFIX}objcopy
NM= ${TOOLPREFIX}nm
LDOPTS= -EL
COPTS+= -DAH_BYTE_ORDER=AH_LITTLE_ENDIAN
COPTS+= -mthumb -mlittle-endian -mcpu=arm9 -ffunction-sections -fdata-sections

View File

@ -0,0 +1,7 @@
#define AH_SUPPORT_AR5210 1
#define AH_SUPPORT_AR5211 1
#define AH_SUPPORT_AR5212 1
#define AH_SUPPORT_5111 1
#define AH_SUPPORT_5112 1
#define AH_SUPPORT_2413 1
#define AH_REGOPS_FUNC 1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,68 @@
#
# Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer,
# without modification.
# 2. Redistributions in binary form must reproduce at minimum a disclaimer
# similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
# redistribution must be conditioned upon including a substantially
# similar Disclaimer requirement for further binary redistribution.
# 3. Neither the names of the above-listed copyright holders nor the names
# of any contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# Alternatively, this software may be distributed under the terms of the
# GNU General Public License ("GPL") version 2 as published by the Free
# Software Foundation.
#
# NO WARRANTY
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
# THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGES.
#
# $Id: athhal-armv4-be-elf.inc,v 1.1.1.1 2005/06/21 20:38:01 dyoung Exp $
#
#
# Compilation configuration for building big-endian ARMv4.
#
#
# Built with GNU cross-devel tools:
#
# PREFIX=/pub/gnu
# BINUTILS=binutils-2.14
# GCC=gcc-3.3.2
# target=arm-elf
#
# ${BINUTILS}/configure --target=$target --prefix=${PREFIX}
# ${GCC}/configure --target=$target --prefix=${PREFIX} \
# --enable-languages=c --with-gnu-as --with-gnu-ld \
# --with-newlib --with-gxx-include-dir=${PREFIX}/$target/include
#
ifndef TOOLPREFIX
TOOLPREFIX= /pub/gnu/bin/arm-elf-
endif
#
CC= ${TOOLPREFIX}gcc
LD= ${TOOLPREFIX}ld
STRIP= ${TOOLPREFIX}strip
OBJCOPY=${TOOLPREFIX}objcopy
NM= ${TOOLPREFIX}nm
LDOPTS= -EB
COPTS+= -DAH_BYTE_ORDER=AH_BIG_ENDIAN
COPTS+= -march=armv4 -mbig-endian -fno-strict-aliasing -fno-common

View File

@ -0,0 +1,6 @@
#define AH_SUPPORT_AR5210 1
#define AH_SUPPORT_AR5211 1
#define AH_SUPPORT_AR5212 1
#define AH_SUPPORT_5111 1
#define AH_SUPPORT_5112 1
#define AH_SUPPORT_2413 1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,68 @@
#
# Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer,
# without modification.
# 2. Redistributions in binary form must reproduce at minimum a disclaimer
# similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
# redistribution must be conditioned upon including a substantially
# similar Disclaimer requirement for further binary redistribution.
# 3. Neither the names of the above-listed copyright holders nor the names
# of any contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# Alternatively, this software may be distributed under the terms of the
# GNU General Public License ("GPL") version 2 as published by the Free
# Software Foundation.
#
# NO WARRANTY
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
# THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGES.
#
# $Id: athhal-armv4-le-elf.inc,v 1.1.1.1 2005/06/21 20:38:04 dyoung Exp $
#
#
# Compilation configuration for building little-endian ARMv4.
#
#
# Built with GNU cross-devel tools:
#
# PREFIX=/pub/gnu
# BINUTILS=binutils-2.14
# GCC=gcc-3.3.2
# target=arm-elf
#
# ${BINUTILS}/configure --target=$target --prefix=${PREFIX}
# ${GCC}/configure --target=$target --prefix=${PREFIX} \
# --enable-languages=c --with-gnu-as --with-gnu-ld \
# --with-newlib --with-gxx-include-dir=${PREFIX}/$target/include
#
ifndef TOOLPREFIX
TOOLPREFIX= /pub/gnu/bin/arm-elf-
endif
#
CC= ${TOOLPREFIX}gcc
LD= ${TOOLPREFIX}ld
STRIP= ${TOOLPREFIX}strip
OBJCOPY=${TOOLPREFIX}objcopy
NM= ${TOOLPREFIX}nm
LDOPTS= -EL
COPTS+= -DAH_BYTE_ORDER=AH_LITTLE_ENDIAN
COPTS+= -march=armv4 -mlittle-endian -fno-strict-aliasing -fno-common

View File

@ -0,0 +1,6 @@
#define AH_SUPPORT_AR5210 1
#define AH_SUPPORT_AR5211 1
#define AH_SUPPORT_AR5212 1
#define AH_SUPPORT_5111 1
#define AH_SUPPORT_5112 1
#define AH_SUPPORT_2413 1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,76 @@
#
# Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer,
# without modification.
# 2. Redistributions in binary form must reproduce at minimum a disclaimer
# similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
# redistribution must be conditioned upon including a substantially
# similar Disclaimer requirement for further binary redistribution.
# 3. Neither the names of the above-listed copyright holders nor the names
# of any contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# Alternatively, this software may be distributed under the terms of the
# GNU General Public License ("GPL") version 2 as published by the Free
# Software Foundation.
#
# NO WARRANTY
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
# THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGES.
#
# $Id: athhal-xscale-be-elf.inc,v 1.1.1.1 2005/06/21 20:38:07 dyoung Exp $
#
#
# Compilation configuration for building big-endian XScale/arm-elf.
#
# NB: built with AH_REGOPS_FUNC to so that register accesses
# can be done using the Linux readl/writel functions on
# systems that need it.
#
# Reported to work on:
# IXP425
#
#
# Built with GNU cross-devel tools:
#
# PREFIX=/pub/gnu
# BINUTILS=binutils-2.14
# GCC=gcc-3.3.2
# target=arm-elf
#
# ${BINUTILS}/configure --target=$target --prefix=${PREFIX}
# ${GCC}/configure --target=$target --prefix=${PREFIX} \
# --enable-languages=c --with-gnu-as --with-gnu-ld \
# --with-newlib --with-gxx-include-dir=${PREFIX}/$target/include
#
ifndef TOOLPREFIX
TOOLPREFIX= /pub/gnu/bin/arm-elf-
endif
#
CC= ${TOOLPREFIX}gcc
LD= ${TOOLPREFIX}ld
STRIP= ${TOOLPREFIX}strip
OBJCOPY=${TOOLPREFIX}objcopy
NM= ${TOOLPREFIX}nm
LDOPTS= -EB
COPTS+= -DAH_BYTE_ORDER=AH_BIG_ENDIAN -DAH_REGOPS_FUNC
COPTS+= -march=armv4 -mbig-endian -fno-strict-aliasing -fno-common -mapcs-32 \
-mtune=xscale -mshort-load-bytes -msoft-float -mfp=2

View File

@ -0,0 +1,6 @@
#define AH_SUPPORT_AR5210 1
#define AH_SUPPORT_AR5211 1
#define AH_SUPPORT_AR5212 1
#define AH_SUPPORT_5111 1
#define AH_SUPPORT_5112 1
#define AH_SUPPORT_2413 1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,77 @@
#
# Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer,
# without modification.
# 2. Redistributions in binary form must reproduce at minimum a disclaimer
# similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
# redistribution must be conditioned upon including a substantially
# similar Disclaimer requirement for further binary redistribution.
# 3. Neither the names of the above-listed copyright holders nor the names
# of any contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# Alternatively, this software may be distributed under the terms of the
# GNU General Public License ("GPL") version 2 as published by the Free
# Software Foundation.
#
# NO WARRANTY
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
# THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGES.
#
# $Id: athhal-xscale-le-elf.inc,v 1.1.1.1 2005/06/21 20:38:11 dyoung Exp $
#
#
# Compilation configuration for building little-endian XScale/arm-elf.
#
# NB: built with AH_REGOPS_FUNC to so that register accesses
# can be done using the Linux readl/writel functions on
# systems that need it.
#
# Reported to work on:
# Compulab's ARMBASE using ARMCORE GX
# (http://www.compulab.co.il/armbase.htm)
#
#
# Built with GNU cross-devel tools:
#
# PREFIX=/pub/gnu
# BINUTILS=binutils-2.14
# GCC=gcc-3.3.2
# target=arm-elf
#
# ${BINUTILS}/configure --target=$target --prefix=${PREFIX}
# ${GCC}/configure --target=$target --prefix=${PREFIX} \
# --enable-languages=c --with-gnu-as --with-gnu-ld \
# --with-newlib --with-gxx-include-dir=${PREFIX}/$target/include
#
ifndef TOOLPREFIX
TOOLPREFIX= /pub/gnu/bin/arm-elf-
endif
#
CC= ${TOOLPREFIX}gcc
LD= ${TOOLPREFIX}ld
STRIP= ${TOOLPREFIX}strip
OBJCOPY=${TOOLPREFIX}objcopy
NM= ${TOOLPREFIX}nm
LDOPTS= -EL
COPTS+= -DAH_BYTE_ORDER=AH_LITTLE_ENDIAN -DAH_REGOPS_FUNC
COPTS+= -march=armv4 -mlittle-endian -fno-strict-aliasing -fno-common \
-mapcs-32 -mtune=xscale -mshort-load-bytes -msoft-float -mfp=2

View File

@ -0,0 +1,6 @@
#define AH_SUPPORT_AR5210 1
#define AH_SUPPORT_AR5211 1
#define AH_SUPPORT_AR5212 1
#define AH_SUPPORT_5111 1
#define AH_SUPPORT_5112 1
#define AH_SUPPORT_2413 1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,58 @@
#
# Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer,
# without modification.
# 2. Redistributions in binary form must reproduce at minimum a disclaimer
# similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
# redistribution must be conditioned upon including a substantially
# similar Disclaimer requirement for further binary redistribution.
# 3. Neither the names of the above-listed copyright holders nor the names
# of any contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# Alternatively, this software may be distributed under the terms of the
# GNU General Public License ("GPL") version 2 as published by the Free
# Software Foundation.
#
# NO WARRANTY
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
# THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGES.
#
# $Id: athhal-i386-elf.inc,v 1.1.1.1 2005/06/21 20:38:13 dyoung Exp $
#
#
# Compilation configuration for building i386-elf.
# This assumes the build platform is also i386-elf.
#
#
ifndef TOOLPREFIX
TOOLPREFIX=
endif
#
CC= ${TOOLPREFIX}gcc
LD= ${TOOLPREFIX}ld
STRIP= ${TOOLPREFIX}strip
OBJCOPY=${TOOLPREFIX}objcopy
NM= ${TOOLPREFIX}nm
COPTS+= -DAH_BYTE_ORDER=AH_LITTLE_ENDIAN
ifndef CONFIG_FRAME_POINTER
COPTS+= -fomit-frame-pointer
endif

View File

@ -0,0 +1,6 @@
#define AH_SUPPORT_AR5210 1
#define AH_SUPPORT_AR5211 1
#define AH_SUPPORT_AR5212 1
#define AH_SUPPORT_5111 1
#define AH_SUPPORT_5112 1
#define AH_SUPPORT_2413 1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,70 @@
#
# Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer,
# without modification.
# 2. Redistributions in binary form must reproduce at minimum a disclaimer
# similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
# redistribution must be conditioned upon including a substantially
# similar Disclaimer requirement for further binary redistribution.
# 3. Neither the names of the above-listed copyright holders nor the names
# of any contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# Alternatively, this software may be distributed under the terms of the
# GNU General Public License ("GPL") version 2 as published by the Free
# Software Foundation.
#
# NO WARRANTY
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
# THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGES.
#
# $Id: athhal-mips-be-elf.inc,v 1.1.1.1 2005/06/21 20:38:17 dyoung Exp $
#
#
# Configuration for building big-endian MIPS2 using the 5.01
# linux-mips.org toolchain (manually moved to /pub/gnu from
# /pub/gnu/local where rpm --prefix=/pub/gnu bogusly installs them).
#
# Known to work on:
# AMD Au1500
#
# http://www.linux-mips.org/toolchain.html
#
# /pub/gnu/bin/mips-linux-gcc -v
# Reading specs from /pub/gnu/bin/../lib/gcc-lib/mips-linux/2.96-mips3264-000710/specs
# gcc version 2.96-mips3264-000710
# /pub/gnu/bin/mips-linux-as -v
# GNU assembler version 2.12.90.0.7 (mips-linux) using BFD version 2.12.90.0.7 20020423
#
ifndef TOOLPREFIX
TOOLPREFIX= /pub/gnu/bin/mips-linux-
endif
#
CC= ${TOOLPREFIX}gcc
LD= ${TOOLPREFIX}ld
STRIP= ${TOOLPREFIX}strip
OBJCOPY=${TOOLPREFIX}objcopy
NM= ${TOOLPREFIX}nm
LDOPTS= -EB
COPTS+= -DAH_BYTE_ORDER=AH_BIG_ENDIAN
COPTS+= -G 0 -EB -mno-abicalls -fno-pic -mips2 -Wa,--trap \
-fno-strict-aliasing -fno-common -fomit-frame-pointer -mlong-calls

View File

@ -0,0 +1,6 @@
#define AH_SUPPORT_AR5210 1
#define AH_SUPPORT_AR5211 1
#define AH_SUPPORT_AR5212 1
#define AH_SUPPORT_5111 1
#define AH_SUPPORT_5112 1
#define AH_SUPPORT_2413 1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,67 @@
#
# Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer,
# without modification.
# 2. Redistributions in binary form must reproduce at minimum a disclaimer
# similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
# redistribution must be conditioned upon including a substantially
# similar Disclaimer requirement for further binary redistribution.
# 3. Neither the names of the above-listed copyright holders nor the names
# of any contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# Alternatively, this software may be distributed under the terms of the
# GNU General Public License ("GPL") version 2 as published by the Free
# Software Foundation.
#
# NO WARRANTY
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
# THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGES.
#
# $Id: athhal-mips-le-elf.inc,v 1.1.1.1 2005/06/21 20:38:19 dyoung Exp $
#
#
# Configuration for building little-endian MIPS2 using the 5.01
# linux-mips.org toolchain (manually moved to /pub/gnu from
# /pub/gnu/local where rpm --prefix=/pub/gnu bogusly installs them).
#
# http://www.linux-mips.org/toolchain.html
#
# /pub/gnu/bin/mips-linux-gcc -v
# Reading specs from /pub/gnu/bin/../lib/gcc-lib/mips-linux/2.96-mips3264-000710/specs
# gcc version 2.96-mips3264-000710
# /pub/gnu/bin/mips-linux-as -v
# GNU assembler version 2.12.90.0.7 (mips-linux) using BFD version 2.12.90.0.7 20020423
#
ifndef TOOLPREFIX
TOOLPREFIX= /pub/gnu/bin/mips-linux-
endif
#
CC= ${TOOLPREFIX}gcc
LD= ${TOOLPREFIX}ld
STRIP= ${TOOLPREFIX}strip
OBJCOPY=${TOOLPREFIX}objcopy
NM= ${TOOLPREFIX}nm
LDOPTS= -EL
COPTS+= -DAH_BYTE_ORDER=AH_LITTLE_ENDIAN
COPTS+= -G 0 -EL -mno-abicalls -fno-pic -mips2 -Wa,--trap \
-fno-strict-aliasing -fno-common -fomit-frame-pointer -mlong-calls

View File

@ -0,0 +1,6 @@
#define AH_SUPPORT_AR5210 1
#define AH_SUPPORT_AR5211 1
#define AH_SUPPORT_AR5212 1
#define AH_SUPPORT_5111 1
#define AH_SUPPORT_5112 1
#define AH_SUPPORT_2413 1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,67 @@
#
# Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer,
# without modification.
# 2. Redistributions in binary form must reproduce at minimum a disclaimer
# similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
# redistribution must be conditioned upon including a substantially
# similar Disclaimer requirement for further binary redistribution.
# 3. Neither the names of the above-listed copyright holders nor the names
# of any contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# Alternatively, this software may be distributed under the terms of the
# GNU General Public License ("GPL") version 2 as published by the Free
# Software Foundation.
#
# NO WARRANTY
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
# THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGES.
#
# $Id: athhal-mips1-be-elf.inc,v 1.1.1.1 2005/06/21 20:38:23 dyoung Exp $
#
#
# Configuration for building big-endian MIPS1 using the 5.01
# linux-mips.org toolchain (manually moved to /pub/gnu from
# /pub/gnu/local where rpm --prefix=/pub/gnu bogusly installs them).
#
# http://www.linux-mips.org/toolchain.html
#
# /pub/gnu/bin/mips-linux-gcc -v
# Reading specs from /pub/gnu/bin/../lib/gcc-lib/mips-linux/2.96-mips3264-000710/specs
# gcc version 2.96-mips3264-000710
# /pub/gnu/bin/mips-linux-as -v
# GNU assembler version 2.12.90.0.7 (mips-linux) using BFD version 2.12.90.0.7 20020423
#
ifndef TOOLPREFIX
TOOLPREFIX= /pub/gnu/bin/mips-linux-
endif
#
CC= ${TOOLPREFIX}gcc
LD= ${TOOLPREFIX}ld
STRIP= ${TOOLPREFIX}strip
OBJCOPY=${TOOLPREFIX}objcopy
NM= ${TOOLPREFIX}nm
LDOPTS= -EB
COPTS+= -DAH_BYTE_ORDER=AH_BIG_ENDIAN
COPTS+= -G 0 -EB -mno-abicalls -fno-pic -mips1 -Wa,--trap \
-fno-strict-aliasing -fno-common -fomit-frame-pointer -mlong-calls

View File

@ -0,0 +1,6 @@
#define AH_SUPPORT_AR5210 1
#define AH_SUPPORT_AR5211 1
#define AH_SUPPORT_AR5212 1
#define AH_SUPPORT_5111 1
#define AH_SUPPORT_5112 1
#define AH_SUPPORT_2413 1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,67 @@
#
# Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer,
# without modification.
# 2. Redistributions in binary form must reproduce at minimum a disclaimer
# similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
# redistribution must be conditioned upon including a substantially
# similar Disclaimer requirement for further binary redistribution.
# 3. Neither the names of the above-listed copyright holders nor the names
# of any contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# Alternatively, this software may be distributed under the terms of the
# GNU General Public License ("GPL") version 2 as published by the Free
# Software Foundation.
#
# NO WARRANTY
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
# THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGES.
#
# $Id: athhal-mips1-le-elf.inc,v 1.1.1.1 2005/06/21 20:38:27 dyoung Exp $
#
#
# Configuration for building little-endian MIPS1 using the 5.01
# linux-mips.org toolchain (manually moved to /pub/gnu from
# /pub/gnu/local where rpm --prefix=/pub/gnu bogusly installs them).
#
# http://www.linux-mips.org/toolchain.html
#
# /pub/gnu/bin/mips-linux-gcc -v
# Reading specs from /pub/gnu/bin/../lib/gcc-lib/mips-linux/2.96-mips3264-000710/specs
# gcc version 2.96-mips3264-000710
# /pub/gnu/bin/mips-linux-as -v
# GNU assembler version 2.12.90.0.7 (mips-linux) using BFD version 2.12.90.0.7 20020423
#
ifndef TOOLPREFIX
TOOLPREFIX= /pub/gnu/bin/mips-linux-
endif
#
CC= ${TOOLPREFIX}gcc
LD= ${TOOLPREFIX}ld
STRIP= ${TOOLPREFIX}strip
OBJCOPY=${TOOLPREFIX}objcopy
NM= ${TOOLPREFIX}nm
LDOPTS= -EL
COPTS+= -DAH_BYTE_ORDER=AH_LITTLE_ENDIAN
COPTS+= -G 0 -EL -mno-abicalls -fno-pic -mips1 -Wa,--trap \
-fno-strict-aliasing -fno-common -fomit-frame-pointer -mlong-calls

View File

@ -0,0 +1,6 @@
#define AH_SUPPORT_AR5210 1
#define AH_SUPPORT_AR5211 1
#define AH_SUPPORT_AR5212 1
#define AH_SUPPORT_5111 1
#define AH_SUPPORT_5112 1
#define AH_SUPPORT_2413 1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,71 @@
#
# Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer,
# without modification.
# 2. Redistributions in binary form must reproduce at minimum a disclaimer
# similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
# redistribution must be conditioned upon including a substantially
# similar Disclaimer requirement for further binary redistribution.
# 3. Neither the names of the above-listed copyright holders nor the names
# of any contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# Alternatively, this software may be distributed under the terms of the
# GNU General Public License ("GPL") version 2 as published by the Free
# Software Foundation.
#
# NO WARRANTY
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
# THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGES.
#
# $Id: athhal-mipsisa32-be-elf.inc,v 1.1.1.1 2005/06/21 20:38:30 dyoung Exp $
#
#
# Compilation configuration for building big-endian mipsisa32-elf.
#
#
# Built with GNU cross-devel tools:
#
# PREFIX=/pub/gnu
# BINUTILS=binutils-2.14
# GCC=gcc-3.3.2
# target=mipsisa32-elf
#
# ${BINUTILS}/configure --target=$target --prefix=${PREFIX}
# ${GCC}/configure --target=$target --prefix=${PREFIX} \
# --enable-languages=c --with-gnu-as --with-gnu-ld \
# --with-newlib --with-gxx-include-dir=${PREFIX}/$target/include
#
ifndef TOOLPREFIX
TOOLPREFIX= /pub/gnu/bin/mipsisa32-elf-
endif
#
CC= ${TOOLPREFIX}gcc
LD= ${TOOLPREFIX}ld
STRIP= ${TOOLPREFIX}strip
OBJCOPY=${TOOLPREFIX}objcopy
NM= ${TOOLPREFIX}nm
LDOPTS+= -EB
COPTS+= -DAH_BYTE_ORDER=AH_BIG_ENDIAN
COPTS+= -G 0 -mno-abicalls -fno-pic -march=r4600 -Wa,--trap \
-fno-strict-aliasing -fno-common -fomit-frame-pointer -mlong-calls \
-isystem ${KERNELPATH}/include

View File

@ -0,0 +1,6 @@
#define AH_SUPPORT_AR5210 1
#define AH_SUPPORT_AR5211 1
#define AH_SUPPORT_AR5212 1
#define AH_SUPPORT_5111 1
#define AH_SUPPORT_5112 1
#define AH_SUPPORT_2413 1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,69 @@
#
# Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer,
# without modification.
# 2. Redistributions in binary form must reproduce at minimum a disclaimer
# similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
# redistribution must be conditioned upon including a substantially
# similar Disclaimer requirement for further binary redistribution.
# 3. Neither the names of the above-listed copyright holders nor the names
# of any contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# Alternatively, this software may be distributed under the terms of the
# GNU General Public License ("GPL") version 2 as published by the Free
# Software Foundation.
#
# NO WARRANTY
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
# THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGES.
#
# $Id: athhal-mipsisa32-le-elf.inc,v 1.1.1.1 2005/06/21 20:38:34 dyoung Exp $
#
#
# Compilation configuration for building little-endian mipsisa32-elf.
#
#
# Built with GNU cross-devel tools:
#
# PREFIX=/pub/gnu
# BINUTILS=binutils-2.14
# GCC=gcc-3.3.2
# target=mipsisa32-elf
#
# ${BINUTILS}/configure --target=$target --prefix=${PREFIX}
# ${GCC}/configure --target=$target --prefix=${PREFIX} \
# --enable-languages=c --with-gnu-as --with-gnu-ld \
# --with-newlib --with-gxx-include-dir=${PREFIX}/$target/include
#
ifndef TOOLPREFIX
TOOLPREFIX= /pub/gnu/bin/mipsisa32-elf-
endif
#
CC= ${TOOLPREFIX}gcc
LD= ${TOOLPREFIX}ld
STRIP= ${TOOLPREFIX}strip
OBJCOPY=${TOOLPREFIX}objcopy
NM= ${TOOLPREFIX}nm
LDOPTS= -EL
COPTS+= -DAH_BYTE_ORDER=AH_LITTLE_ENDIAN
COPTS+= -G 0 -EL -mno-abicalls -fno-pic -march=r4600 -Wa,--trap \
-fno-strict-aliasing -fno-common -fomit-frame-pointer -mlong-calls

View File

@ -0,0 +1,6 @@
#define AH_SUPPORT_AR5210 1
#define AH_SUPPORT_AR5211 1
#define AH_SUPPORT_AR5212 1
#define AH_SUPPORT_5111 1
#define AH_SUPPORT_5112 1
#define AH_SUPPORT_2413 1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,71 @@
#
# Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer,
# without modification.
# 2. Redistributions in binary form must reproduce at minimum a disclaimer
# similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
# redistribution must be conditioned upon including a substantially
# similar Disclaimer requirement for further binary redistribution.
# 3. Neither the names of the above-listed copyright holders nor the names
# of any contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# Alternatively, this software may be distributed under the terms of the
# GNU General Public License ("GPL") version 2 as published by the Free
# Software Foundation.
#
# NO WARRANTY
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
# THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGES.
#
# $Id: athhal-powerpc-be-eabi.inc,v 1.1.1.1 2005/06/21 20:38:37 dyoung Exp $
#
#
# Compilation configuration for building big-endian PowerPC/powerpc-eabi.
#
# Known to work on:
# IBM 450EP
#
# Built with GNU cross-devel tools:
#
# PREFIX=/pub/gnu
# BINUTILS=binutils-2.14
# GCC=gcc-3.3.2
# target=powerpc-eabi
#
# ${BINUTILS}/configure --target=$target --prefix=${PREFIX}
# ${GCC}/configure --target=$target --prefix=${PREFIX} \
# --enable-languages=c --with-gnu-as --with-gnu-ld \
# --with-newlib --with-gxx-include-dir=${PREFIX}/$target/include
#
ifndef TOOLPREFIX
TOOLPREFIX= /pub/gnu/bin/powerpc-eabi-
endif
#
CC= ${TOOLPREFIX}gcc
LD= ${TOOLPREFIX}ld
STRIP= ${TOOLPREFIX}strip
OBJCOPY=${TOOLPREFIX}objcopy
NM= ${TOOLPREFIX}nm
LDOPTS= -EB
COPTS+= -DAH_BYTE_ORDER=AH_BIG_ENDIAN -DAH_REGOPS_FUNC
COPTS+= -mbig-endian
COPTS+= -msoft-float -ffixed-r2

View File

@ -0,0 +1,6 @@
#define AH_SUPPORT_AR5210 1
#define AH_SUPPORT_AR5211 1
#define AH_SUPPORT_AR5212 1
#define AH_SUPPORT_5111 1
#define AH_SUPPORT_5112 1
#define AH_SUPPORT_2413 1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,70 @@
#
# Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer,
# without modification.
# 2. Redistributions in binary form must reproduce at minimum a disclaimer
# similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
# redistribution must be conditioned upon including a substantially
# similar Disclaimer requirement for further binary redistribution.
# 3. Neither the names of the above-listed copyright holders nor the names
# of any contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# Alternatively, this software may be distributed under the terms of the
# GNU General Public License ("GPL") version 2 as published by the Free
# Software Foundation.
#
# NO WARRANTY
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
# THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGES.
#
# $Id: athhal-powerpc-le-eabi.inc,v 1.1.1.1 2005/06/21 20:38:40 dyoung Exp $
#
#
# Compilation configuration for building little-endian PowerPC/powerpc-eabi.
#
#
# Built with GNU cross-devel tools:
#
# PREFIX=/pub/gnu
# BINUTILS=binutils-2.14
# GCC=gcc-3.3.2
# target=powerpc-eabi
#
# ${BINUTILS}/configure --target=$target --prefix=${PREFIX}
# ${GCC}/configure --target=$target --prefix=${PREFIX} \
# --enable-languages=c --with-gnu-as --with-gnu-ld \
# --with-newlib --with-gxx-include-dir=${PREFIX}/$target/include
#
ifndef TOOLPREFIX
TOOLPREFIX= /pub/gnu/bin/powerpc-eabi-
endif
#
CC= ${TOOLPREFIX}gcc
LD= ${TOOLPREFIX}ld
STRIP= ${TOOLPREFIX}strip
OBJCOPY=${TOOLPREFIX}objcopy
NM= ${TOOLPREFIX}nm
LDOPTS= -EL
COPTS+= -DAH_BYTE_ORDER=AH_LITTLE_ENDIAN -DAH_REGOPS_FUNC
COPTS+= -mlittle-endian
# NB: explicitly disable multiple and string instructions for little-endian
COPTS+= -msoft-float -ffixed-r2 -mno-multiple -mno-string

View File

@ -0,0 +1,6 @@
#define AH_SUPPORT_AR5210 1
#define AH_SUPPORT_AR5211 1
#define AH_SUPPORT_AR5212 1
#define AH_SUPPORT_5111 1
#define AH_SUPPORT_5112 1
#define AH_SUPPORT_2413 1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,62 @@
#
# Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer,
# without modification.
# 2. Redistributions in binary form must reproduce at minimum a disclaimer
# similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
# redistribution must be conditioned upon including a substantially
# similar Disclaimer requirement for further binary redistribution.
# 3. Neither the names of the above-listed copyright holders nor the names
# of any contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# Alternatively, this software may be distributed under the terms of the
# GNU General Public License ("GPL") version 2 as published by the Free
# Software Foundation.
#
# NO WARRANTY
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
# AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
# THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
# OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGES.
#
# $Id: athhal-sh4-le-elf.inc,v 1.1.1.1 2005/06/21 20:38:43 dyoung Exp $
#
#
# Compilation configuration for building little-endian SuperH/ELF.
#
#
# Built with pre-packaged tools for RedHat 7.3:
#
# http://mirror.sh-linux.org/rpm-index-2003/i386/ByName.html`
# binutils-sh-linux-2.13.90.0.18-1
# gcc-sh-linux-3.2.3-3
#
ifndef TOOLPREFIX
TOOLPREFIX= /pub/gnu/bin/sh-linux-
endif
#
CC= ${TOOLPREFIX}gcc
LD= ${TOOLPREFIX}ld
STRIP= ${TOOLPREFIX}strip
OBJCOPY=${TOOLPREFIX}objcopy
NM= ${TOOLPREFIX}nm
LDOPTS= -EL
COPTS+= -DAH_BYTE_ORDER=AH_LITTLE_ENDIAN
COPTS+= -ml -m4 -mno-implicit-fp

View File

@ -0,0 +1,6 @@
#define AH_SUPPORT_AR5210 1
#define AH_SUPPORT_AR5211 1
#define AH_SUPPORT_AR5212 1
#define AH_SUPPORT_5111 1
#define AH_SUPPORT_5112 1
#define AH_SUPPORT_2413 1

View File

@ -0,0 +1,42 @@
All files contained in this distribution are covered by the following
copyright unless explicitly identified otherwise. Note that this
copyright does _NOT_ contain a "or GPL" clause and does _NOT_ permit
redistribution with changes.
/*-
* Copyright (c) 2002-2004 Sam Leffler, Errno Consulting, Atheros
* Communications, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the following conditions are met:
* 1. The materials contained herein are unmodified and are used
* unmodified.
* 2. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following NO
* ''WARRANTY'' disclaimer below (''Disclaimer''), without
* modification.
* 3. Redistributions in binary form must reproduce at minimum a
* disclaimer similar to the Disclaimer below and any redistribution
* must be conditioned upon including a substantially similar
* Disclaimer requirement for further binary redistribution.
* 4. Neither the names of the above-listed copyright holders nor the
* names of any contributors may be used to endorse or promote
* product derived from this software without specific prior written
* permission.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT,
* MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
* FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGES.
*
* $Id: athhal-COPYRIGHT,v 1.1.1.1 2005/06/21 20:37:50 dyoung Exp $
*/

View File

@ -0,0 +1,64 @@
$Id: athhal-README,v 1.1.1.1 2005/06/21 20:37:50 dyoung Exp $
WARNING: THIS IS A BETA DISTRIBUTION. THIS SOFTWARE HAS KNOWN PROBLEMS AND
WARNING: LIMITATIONS THAT WILL BE CORRECTED BEFORE A PRODUCTION RELEASE.
WARNING: USE AT YOUR OWN RISK!
Atheros Hardware Access Layer (HAL)
===================================
* Copyright (c) 2002-2004 Sam Leffler.
* Copyright (c) 2002-2004 Atheros Communications, Inc.
* All rights reserved.
Read the file COPYRIGHT for the complete copyright.
This code manages much of the chip-specific operation of the Atheros driver.
The HAL is provided in a binary-only form in order to comply with FCC
regulations. In particular, a radio transmitter can only be operated at
power levels and on frequency channels for which it is approved. The FCC
requires that a software-defined radio cannot be configured by a user
to operate outside the approved power levels and frequency channels.
This makes it difficult to open-source code that enforces limits on
the power levels, frequency channels and other parameters of the radio
transmitter. See
http://ftp.fcc.gov/Bureaus/Engineering_Technology/Orders/2001/fcc01264.pdf
for the specific FCC regulation. Because the module is provided in a
binary-only form it is marked "Proprietary"; this means when you load
it you will see messages that your system is now "tainted".
If you wish to use this driver on a platform for which an ath_hal
module is not already provided please contact the author. Note that
this is only necessary for new _architectures_; the HAL is not tied to
any specific version of your operating system.
Atheros Hardware
================
There are currently 3 generations of Atheros 802.11 wireless devices:
5210 supports 11a only
5211 supports both 11a and 11b
5212 supports 11a, 11b, and 11g
These parts have been incorporated in a variety of retail products
including cardbus cards from DLink, Linksys, Netgear, and Proxim; and
mini-pci cards from some of these same vendors. In addition many
laptop vendors use Atheros mini-pci cards for their builtin wireless
support. An (incomplete) list of products that use Atheros parts is:
Netgear WAG511 D-Link DWL-AG520 Linksys WPC55AG
Netgear WAB501 D-Link DWL-AG650 Linksys WMP55AG
D-Link DWL-AB650 Linksys WPC51AB
In general, if a device is identified as ``11a only'' it is almost
certain to contain an Atheros 5210 part in it. All retail a+b
products use the 5211. The latest generation of universal a+b+g
combo products use the 5212. When in doubt check the PCI vendor
id with a tool like lspci, the Atheros vendor id is 0x168c; e.g.
00:13.0 Ethernet controller: Unknown device 168c:0012 (rev 01)

691
sys/contrib/dev/ic/athhal.h Normal file
View File

@ -0,0 +1,691 @@
/*-
* Copyright (c) 2002-2004 Sam Leffler, Errno Consulting, Atheros
* Communications, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the following conditions are met:
* 1. The materials contained herein are unmodified and are used
* unmodified.
* 2. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following NO
* ''WARRANTY'' disclaimer below (''Disclaimer''), without
* modification.
* 3. Redistributions in binary form must reproduce at minimum a
* disclaimer similar to the Disclaimer below and any redistribution
* must be conditioned upon including a substantially similar
* Disclaimer requirement for further binary redistribution.
* 4. Neither the names of the above-listed copyright holders nor the
* names of any contributors may be used to endorse or promote
* product derived from this software without specific prior written
* permission.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT,
* MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
* FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGES.
*
* $Id: athhal.h,v 1.1.1.1 2005/06/21 20:37:50 dyoung Exp $
*/
#ifndef _ATH_AH_H_
#define _ATH_AH_H_
/*
* Atheros Hardware Access Layer
*
* Clients of the HAL call ath_hal_attach to obtain a reference to an ath_hal
* structure for use with the device. Hardware-related operations that
* follow must call back into the HAL through interface, supplying the
* reference as the first parameter.
*/
#include "ah_osdep.h"
/*
* __ahdecl is analogous to _cdecl; it defines the calling
* convention used within the HAL. For most systems this
* can just default to be empty and the compiler will (should)
* use _cdecl. For systems where _cdecl is not compatible this
* must be defined. See linux/ah_osdep.h for an example.
*/
#ifndef __ahdecl
#define __ahdecl
#endif
/*
* Status codes that may be returned by the HAL. Note that
* interfaces that return a status code set it only when an
* error occurs--i.e. you cannot check it for success.
*/
typedef enum {
HAL_OK = 0, /* No error */
HAL_ENXIO = 1, /* No hardware present */
HAL_ENOMEM = 2, /* Memory allocation failed */
HAL_EIO = 3, /* Hardware didn't respond as expected */
HAL_EEMAGIC = 4, /* EEPROM magic number invalid */
HAL_EEVERSION = 5, /* EEPROM version invalid */
HAL_EELOCKED = 6, /* EEPROM unreadable */
HAL_EEBADSUM = 7, /* EEPROM checksum invalid */
HAL_EEREAD = 8, /* EEPROM read problem */
HAL_EEBADMAC = 9, /* EEPROM mac address invalid */
HAL_EESIZE = 10, /* EEPROM size not supported */
HAL_EEWRITE = 11, /* Attempt to change write-locked EEPROM */
HAL_EINVAL = 12, /* Invalid parameter to function */
HAL_ENOTSUPP = 13, /* Hardware revision not supported */
HAL_ESELFTEST = 14, /* Hardware self-test failed */
HAL_EINPROGRESS = 15, /* Operation incomplete */
} HAL_STATUS;
typedef enum {
AH_FALSE = 0, /* NB: lots of code assumes false is zero */
AH_TRUE = 1,
} HAL_BOOL;
typedef enum {
HAL_CAP_REG_DMN = 0, /* current regulatory domain */
HAL_CAP_CIPHER = 1, /* hardware supports cipher */
HAL_CAP_TKIP_MIC = 2, /* handle TKIP MIC in hardware */
HAL_CAP_TKIP_SPLIT = 3, /* hardware TKIP uses split keys */
HAL_CAP_PHYCOUNTERS = 4, /* hardware PHY error counters */
HAL_CAP_DIVERSITY = 5, /* hardware supports fast diversity */
HAL_CAP_KEYCACHE_SIZE = 6, /* number of entries in key cache */
HAL_CAP_NUM_TXQUEUES = 7, /* number of hardware xmit queues */
HAL_CAP_VEOL = 9, /* hardware supports virtual EOL */
HAL_CAP_PSPOLL = 10, /* hardware has working PS-Poll support */
HAL_CAP_DIAG = 11, /* hardware diagnostic support */
HAL_CAP_COMPRESSION = 12, /* hardware supports compression */
HAL_CAP_BURST = 13, /* hardware supports packet bursting */
HAL_CAP_FASTFRAME = 14, /* hardware supoprts fast frames */
HAL_CAP_TXPOW = 15, /* global tx power limit */
HAL_CAP_TPC = 16, /* per-packet tx power control */
} HAL_CAPABILITY_TYPE;
/*
* "States" for setting the LED. These correspond to
* the possible 802.11 operational states and there may
* be a many-to-one mapping between these states and the
* actual hardware states for the LED's (i.e. the hardware
* may have fewer states).
*/
typedef enum {
HAL_LED_INIT = 0,
HAL_LED_SCAN = 1,
HAL_LED_AUTH = 2,
HAL_LED_ASSOC = 3,
HAL_LED_RUN = 4
} HAL_LED_STATE;
/*
* Transmit queue types/numbers. These are used to tag
* each transmit queue in the hardware and to identify a set
* of transmit queues for operations such as start/stop dma.
*/
typedef enum {
HAL_TX_QUEUE_INACTIVE = 0, /* queue is inactive/unused */
HAL_TX_QUEUE_DATA = 1, /* data xmit q's */
HAL_TX_QUEUE_BEACON = 2, /* beacon xmit q */
HAL_TX_QUEUE_CAB = 3, /* "crap after beacon" xmit q */
HAL_TX_QUEUE_PSPOLL = 4, /* power-save poll xmit q */
} HAL_TX_QUEUE;
#define HAL_NUM_TX_QUEUES 10 /* max possible # of queues */
/*
* Transmit queue subtype. These map directly to
* WME Access Categories (except for UPSD). Refer
* to Table 5 of the WME spec.
*/
typedef enum {
HAL_WME_AC_BK = 0, /* background access category */
HAL_WME_AC_BE = 1, /* best effort access category*/
HAL_WME_AC_VI = 2, /* video access category */
HAL_WME_AC_VO = 3, /* voice access category */
HAL_WME_UPSD = 4, /* uplink power save */
} HAL_TX_QUEUE_SUBTYPE;
/*
* Transmit queue flags that control various
* operational parameters.
*/
typedef enum {
TXQ_FLAG_TXOKINT_ENABLE = 0x0001, /* enable TXOK interrupt */
TXQ_FLAG_TXERRINT_ENABLE = 0x0001, /* enable TXERR interrupt */
TXQ_FLAG_TXDESCINT_ENABLE = 0x0002, /* enable TXDESC interrupt */
TXQ_FLAG_TXEOLINT_ENABLE = 0x0004, /* enable TXEOL interrupt */
TXQ_FLAG_TXURNINT_ENABLE = 0x0008, /* enable TXURN interrupt */
TXQ_FLAG_BACKOFF_DISABLE = 0x0010, /* disable Post Backoff */
TXQ_FLAG_COMPRESSION_ENABLE = 0x0020, /* compression enabled */
TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE = 0x0040, /* enable ready time
expiry policy */
TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE = 0x0080, /* enable backoff while
sending fragment burst*/
} HAL_TX_QUEUE_FLAGS;
typedef struct {
u_int32_t tqi_ver; /* hal TXQ version */
HAL_TX_QUEUE_SUBTYPE tqi_subtype; /* subtype if applicable */
HAL_TX_QUEUE_FLAGS tqi_qflags; /* flags (see above) */
u_int32_t tqi_priority; /* (not used) */
u_int32_t tqi_aifs; /* aifs */
u_int32_t tqi_cwmin; /* cwMin */
u_int32_t tqi_cwmax; /* cwMax */
u_int16_t tqi_shretry; /* rts retry limit */
u_int16_t tqi_lgretry; /* long retry limit (not used)*/
u_int32_t tqi_cbrPeriod;
u_int32_t tqi_cbrOverflowLimit;
u_int32_t tqi_burstTime;
u_int32_t tqi_readyTime;
} HAL_TXQ_INFO;
/* token to use for aifs, cwmin, cwmax */
#define HAL_TXQ_USEDEFAULT ((u_int32_t) -1)
/*
* Transmit packet types. This belongs in ah_desc.h, but
* is here so we can give a proper type to various parameters
* (and not require everyone include the file).
*
* NB: These values are intentionally assigned for
* direct use when setting up h/w descriptors.
*/
typedef enum {
HAL_PKT_TYPE_NORMAL = 0,
HAL_PKT_TYPE_ATIM = 1,
HAL_PKT_TYPE_PSPOLL = 2,
HAL_PKT_TYPE_BEACON = 3,
HAL_PKT_TYPE_PROBE_RESP = 4,
} HAL_PKT_TYPE;
/* Rx Filter Frame Types */
typedef enum {
HAL_RX_FILTER_UCAST = 0x00000001, /* Allow unicast frames */
HAL_RX_FILTER_MCAST = 0x00000002, /* Allow multicast frames */
HAL_RX_FILTER_BCAST = 0x00000004, /* Allow broadcast frames */
HAL_RX_FILTER_CONTROL = 0x00000008, /* Allow control frames */
HAL_RX_FILTER_BEACON = 0x00000010, /* Allow beacon frames */
HAL_RX_FILTER_PROM = 0x00000020, /* Promiscuous mode */
HAL_RX_FILTER_PROBEREQ = 0x00000080, /* Allow probe request frames */
HAL_RX_FILTER_PHYERR = 0x00000100, /* Allow phy errors */
HAL_RX_FILTER_PHYRADAR = 0x00000200, /* Allow phy radar errors*/
} HAL_RX_FILTER;
typedef enum {
HAL_PM_UNDEFINED = 0,
HAL_PM_AUTO = 1,
HAL_PM_AWAKE = 2,
HAL_PM_FULL_SLEEP = 3,
HAL_PM_NETWORK_SLEEP = 4
} HAL_POWER_MODE;
/*
* NOTE WELL:
* These are mapped to take advantage of the common locations for many of
* the bits on all of the currently supported MAC chips. This is to make
* the ISR as efficient as possible, while still abstracting HW differences.
* When new hardware breaks this commonality this enumerated type, as well
* as the HAL functions using it, must be modified. All values are directly
* mapped unless commented otherwise.
*/
typedef enum {
HAL_INT_RX = 0x00000001, /* Non-common mapping */
HAL_INT_RXDESC = 0x00000002,
HAL_INT_RXNOFRM = 0x00000008,
HAL_INT_RXEOL = 0x00000010,
HAL_INT_RXORN = 0x00000020,
HAL_INT_TX = 0x00000040, /* Non-common mapping */
HAL_INT_TXDESC = 0x00000080,
HAL_INT_TXURN = 0x00000800,
HAL_INT_MIB = 0x00001000,
HAL_INT_RXPHY = 0x00004000,
HAL_INT_RXKCM = 0x00008000,
HAL_INT_SWBA = 0x00010000,
HAL_INT_BMISS = 0x00040000,
HAL_INT_BNR = 0x00100000, /* Non-common mapping */
HAL_INT_GPIO = 0x01000000,
HAL_INT_FATAL = 0x40000000, /* Non-common mapping */
HAL_INT_GLOBAL = 0x80000000, /* Set/clear IER */
/* Interrupt bits that map directly to ISR/IMR bits */
HAL_INT_COMMON = HAL_INT_RXNOFRM
| HAL_INT_RXDESC
| HAL_INT_RXEOL
| HAL_INT_RXORN
| HAL_INT_TXURN
| HAL_INT_TXDESC
| HAL_INT_MIB
| HAL_INT_RXPHY
| HAL_INT_RXKCM
| HAL_INT_SWBA
| HAL_INT_BMISS
| HAL_INT_GPIO,
HAL_INT_NOCARD = 0xffffffff /* To signal the card was removed */
} HAL_INT;
typedef enum {
HAL_RFGAIN_INACTIVE = 0,
HAL_RFGAIN_READ_REQUESTED = 1,
HAL_RFGAIN_NEED_CHANGE = 2
} HAL_RFGAIN;
/*
* Channels are specified by frequency.
*/
typedef struct {
u_int16_t channel; /* setting in Mhz */
u_int16_t channelFlags; /* see below */
} HAL_CHANNEL;
#define CHANNEL_RAD_INT 0x0001 /* Radar interference detected on channel */
#define CHANNEL_CW_INT 0x0002 /* CW interference detected on channel */
#define CHANNEL_BUSY 0x0004 /* Busy, occupied or overlap with adjoin chan */
#define CHANNEL_TURBO 0x0010 /* Turbo Channel */
#define CHANNEL_CCK 0x0020 /* CCK channel */
#define CHANNEL_OFDM 0x0040 /* OFDM channel */
#define CHANNEL_2GHZ 0x0080 /* 2 GHz spectrum channel. */
#define CHANNEL_5GHZ 0x0100 /* 5 GHz spectrum channel */
#define CHANNEL_PASSIVE 0x0200 /* Only passive scan allowed in the channel */
#define CHANNEL_DYN 0x0400 /* dynamic CCK-OFDM channel */
#define CHANNEL_XR 0x0800 /* XR channel */
#define CHANNEL_AR 0x8000 /* Software use: radar detected */
#define CHANNEL_A (CHANNEL_5GHZ|CHANNEL_OFDM)
#define CHANNEL_B (CHANNEL_2GHZ|CHANNEL_CCK)
#define CHANNEL_PUREG (CHANNEL_2GHZ|CHANNEL_OFDM)
#ifdef notdef
#define CHANNEL_G (CHANNEL_2GHZ|CHANNEL_DYN)
#else
#define CHANNEL_G (CHANNEL_2GHZ|CHANNEL_OFDM)
#endif
#define CHANNEL_T (CHANNEL_5GHZ|CHANNEL_OFDM|CHANNEL_TURBO)
#define CHANNEL_108G (CHANNEL_2GHZ|CHANNEL_OFDM|CHANNEL_TURBO)
#define CHANNEL_X (CHANNEL_5GHZ|CHANNEL_OFDM|CHANNEL_XR)
#define CHANNEL_ALL \
(CHANNEL_OFDM|CHANNEL_CCK|CHANNEL_5GHZ|CHANNEL_2GHZ|CHANNEL_TURBO)
#define CHANNEL_ALL_NOTURBO (CHANNEL_ALL &~ CHANNEL_TURBO)
typedef struct {
u_int32_t ackrcv_bad;
u_int32_t rts_bad;
u_int32_t rts_good;
u_int32_t fcs_bad;
u_int32_t beacons;
} HAL_MIB_STATS;
typedef u_int16_t HAL_CTRY_CODE; /* country code */
typedef u_int16_t HAL_REG_DOMAIN; /* regulatory domain code */
enum {
CTRY_DEBUG = 0x1ff, /* debug country code */
CTRY_DEFAULT = 0 /* default country code */
};
enum {
HAL_MODE_11A = 0x001,
HAL_MODE_TURBO = 0x002,
HAL_MODE_11B = 0x004,
HAL_MODE_PUREG = 0x008,
#ifdef notdef
HAL_MODE_11G = 0x010,
#else
HAL_MODE_11G = 0x008,
#endif
HAL_MODE_108G = 0x020,
HAL_MODE_ALL = 0xfff
};
typedef struct {
int rateCount; /* NB: for proper padding */
u_int8_t rateCodeToIndex[32]; /* back mapping */
struct {
u_int8_t valid; /* valid for rate control use */
u_int8_t phy; /* CCK/OFDM/XR */
u_int16_t rateKbps; /* transfer rate in kbs */
u_int8_t rateCode; /* rate for h/w descriptors */
u_int8_t shortPreamble; /* mask for enabling short
* preamble in CCK rate code */
u_int8_t dot11Rate; /* value for supported rates
* info element of MLME */
u_int8_t controlRate; /* index of next lower basic
* rate; used for dur. calcs */
u_int16_t lpAckDuration; /* long preamble ACK duration */
u_int16_t spAckDuration; /* short preamble ACK duration*/
} info[32];
} HAL_RATE_TABLE;
typedef struct {
u_int rs_count; /* number of valid entries */
u_int8_t rs_rates[32]; /* rates */
} HAL_RATE_SET;
typedef enum {
HAL_ANT_VARIABLE = 0, /* variable by programming */
HAL_ANT_FIXED_A = 1, /* fixed to 11a frequencies */
HAL_ANT_FIXED_B = 2, /* fixed to 11b frequencies */
} HAL_ANT_SETTING;
typedef enum {
HAL_M_STA = 1, /* infrastructure station */
HAL_M_IBSS = 0, /* IBSS (adhoc) station */
HAL_M_HOSTAP = 6, /* Software Access Point */
HAL_M_MONITOR = 8 /* Monitor mode */
} HAL_OPMODE;
typedef struct {
u_int8_t kv_type; /* one of HAL_CIPHER */
u_int8_t kv_pad;
u_int16_t kv_len; /* length in bits */
u_int8_t kv_val[16]; /* enough for 128-bit keys */
u_int8_t kv_mic[8]; /* TKIP MIC key */
} HAL_KEYVAL;
typedef enum {
HAL_CIPHER_WEP = 0,
HAL_CIPHER_AES_OCB = 1,
HAL_CIPHER_AES_CCM = 2,
HAL_CIPHER_CKIP = 3,
HAL_CIPHER_TKIP = 4,
HAL_CIPHER_CLR = 5, /* no encryption */
HAL_CIPHER_MIC = 127 /* TKIP-MIC, not a cipher */
} HAL_CIPHER;
enum {
HAL_SLOT_TIME_9 = 9,
HAL_SLOT_TIME_20 = 20,
};
/*
* Per-station beacon timer state. Note that the specified
* beacon interval (given in TU's) can also include flags
* to force a TSF reset and to enable the beacon xmit logic.
* If bs_cfpmaxduration is non-zero the hardware is setup to
* coexist with a PCF-capable AP.
*/
typedef struct {
u_int32_t bs_nexttbtt; /* next beacon in TU */
u_int32_t bs_nextdtim; /* next DTIM in TU */
u_int32_t bs_intval; /* beacon interval+flags */
#define HAL_BEACON_PERIOD 0x0000ffff /* beacon interval period */
#define HAL_BEACON_ENA 0x00800000 /* beacon xmit enable */
#define HAL_BEACON_RESET_TSF 0x01000000 /* clear TSF */
u_int32_t bs_dtimperiod;
u_int16_t bs_cfpperiod; /* CFP period in TU */
u_int16_t bs_cfpmaxduration; /* max CFP duration in TU */
u_int32_t bs_cfpnext; /* next CFP in TU */
u_int16_t bs_timoffset; /* byte offset to TIM bitmap */
u_int16_t bs_bmissthreshold; /* beacon miss threshold */
u_int32_t bs_sleepduration; /* max sleep duration */
} HAL_BEACON_STATE;
/*
* Per-node statistics maintained by the driver for use in
* optimizing signal quality and other operational aspects.
*/
typedef struct {
u_int32_t ns_avgbrssi; /* average beacon rssi */
u_int32_t ns_avgrssi; /* average data rssi */
u_int32_t ns_avgtxrssi; /* average tx rssi */
} HAL_NODE_STATS;
#define HAL_RSSI_EP_MULTIPLIER (1<<7) /* pow2 to optimize out * and / */
struct ath_desc;
/*
* Hardware Access Layer (HAL) API.
*
* Clients of the HAL call ath_hal_attach to obtain a reference to an
* ath_hal structure for use with the device. Hardware-related operations
* that follow must call back into the HAL through interface, supplying
* the reference as the first parameter. Note that before using the
* reference returned by ath_hal_attach the caller should verify the
* ABI version number.
*/
struct ath_hal {
u_int32_t ah_magic; /* consistency check magic number */
u_int32_t ah_abi; /* HAL ABI version */
#define HAL_ABI_VERSION 0x04112900 /* YYMMDDnn */
u_int16_t ah_devid; /* PCI device ID */
u_int16_t ah_subvendorid; /* PCI subvendor ID */
HAL_SOFTC ah_sc; /* back pointer to driver/os state */
HAL_BUS_TAG ah_st; /* params for register r+w */
HAL_BUS_HANDLE ah_sh;
HAL_CTRY_CODE ah_countryCode;
u_int32_t ah_macVersion; /* MAC version id */
u_int16_t ah_macRev; /* MAC revision */
u_int16_t ah_phyRev; /* PHY revision */
/* NB: when only one radio is present the rev is in 5Ghz */
u_int16_t ah_analog5GhzRev;/* 5GHz radio revision */
u_int16_t ah_analog2GhzRev;/* 2GHz radio revision */
const HAL_RATE_TABLE *__ahdecl(*ah_getRateTable)(struct ath_hal *,
u_int mode);
void __ahdecl(*ah_detach)(struct ath_hal*);
/* Reset functions */
HAL_BOOL __ahdecl(*ah_reset)(struct ath_hal *, HAL_OPMODE,
HAL_CHANNEL *, HAL_BOOL bChannelChange,
HAL_STATUS *status);
HAL_BOOL __ahdecl(*ah_phyDisable)(struct ath_hal *);
void __ahdecl(*ah_setPCUConfig)(struct ath_hal *);
HAL_BOOL __ahdecl(*ah_perCalibration)(struct ath_hal*, HAL_CHANNEL *);
HAL_BOOL __ahdecl(*ah_setTxPowerLimit)(struct ath_hal *, u_int32_t);
/* Transmit functions */
HAL_BOOL __ahdecl(*ah_updateTxTrigLevel)(struct ath_hal*,
HAL_BOOL incTrigLevel);
int __ahdecl(*ah_setupTxQueue)(struct ath_hal *, HAL_TX_QUEUE,
const HAL_TXQ_INFO *qInfo);
HAL_BOOL __ahdecl(*ah_setTxQueueProps)(struct ath_hal *, int q,
const HAL_TXQ_INFO *qInfo);
HAL_BOOL __ahdecl(*ah_getTxQueueProps)(struct ath_hal *, int q,
HAL_TXQ_INFO *qInfo);
HAL_BOOL __ahdecl(*ah_releaseTxQueue)(struct ath_hal *ah, u_int q);
HAL_BOOL __ahdecl(*ah_resetTxQueue)(struct ath_hal *ah, u_int q);
u_int32_t __ahdecl(*ah_getTxDP)(struct ath_hal*, u_int);
HAL_BOOL __ahdecl(*ah_setTxDP)(struct ath_hal*, u_int, u_int32_t txdp);
u_int32_t __ahdecl(*ah_numTxPending)(struct ath_hal *, u_int q);
HAL_BOOL __ahdecl(*ah_startTxDma)(struct ath_hal*, u_int);
HAL_BOOL __ahdecl(*ah_stopTxDma)(struct ath_hal*, u_int);
HAL_BOOL __ahdecl(*ah_updateCTSForBursting)(struct ath_hal *,
struct ath_desc *, struct ath_desc *,
struct ath_desc *, struct ath_desc *,
u_int32_t, u_int32_t);
HAL_BOOL __ahdecl(*ah_setupTxDesc)(struct ath_hal *, struct ath_desc *,
u_int pktLen, u_int hdrLen,
HAL_PKT_TYPE type, u_int txPower,
u_int txRate0, u_int txTries0,
u_int keyIx, u_int antMode, u_int flags,
u_int rtsctsRate, u_int rtsctsDuration);
HAL_BOOL __ahdecl(*ah_setupXTxDesc)(struct ath_hal *, struct ath_desc*,
u_int txRate1, u_int txTries1,
u_int txRate2, u_int txTries2,
u_int txRate3, u_int txTries3);
HAL_BOOL __ahdecl(*ah_fillTxDesc)(struct ath_hal *, struct ath_desc *,
u_int segLen, HAL_BOOL firstSeg,
HAL_BOOL lastSeg, const struct ath_desc *);
HAL_STATUS __ahdecl(*ah_procTxDesc)(struct ath_hal *, struct ath_desc*);
void __ahdecl(*ah_getTxIntrQueue)(struct ath_hal *, u_int32_t *);
/* Receive Functions */
u_int32_t __ahdecl(*ah_getRxDP)(struct ath_hal*);
void __ahdecl(*ah_setRxDP)(struct ath_hal*, u_int32_t rxdp);
void __ahdecl(*ah_enableReceive)(struct ath_hal*);
HAL_BOOL __ahdecl(*ah_stopDmaReceive)(struct ath_hal*);
void __ahdecl(*ah_startPcuReceive)(struct ath_hal*);
void __ahdecl(*ah_stopPcuReceive)(struct ath_hal*);
void __ahdecl(*ah_setMulticastFilter)(struct ath_hal*,
u_int32_t filter0, u_int32_t filter1);
HAL_BOOL __ahdecl(*ah_setMulticastFilterIndex)(struct ath_hal*,
u_int32_t index);
HAL_BOOL __ahdecl(*ah_clrMulticastFilterIndex)(struct ath_hal*,
u_int32_t index);
u_int32_t __ahdecl(*ah_getRxFilter)(struct ath_hal*);
void __ahdecl(*ah_setRxFilter)(struct ath_hal*, u_int32_t);
HAL_BOOL __ahdecl(*ah_setupRxDesc)(struct ath_hal *, struct ath_desc *,
u_int32_t size, u_int flags);
HAL_STATUS __ahdecl(*ah_procRxDesc)(struct ath_hal *, struct ath_desc *,
u_int32_t phyAddr, struct ath_desc *next);
void __ahdecl(*ah_rxMonitor)(struct ath_hal *,
const HAL_NODE_STATS *);
void __ahdecl(*ah_procMibEvent)(struct ath_hal *,
const HAL_NODE_STATS *);
/* Misc Functions */
HAL_STATUS __ahdecl(*ah_getCapability)(struct ath_hal *,
HAL_CAPABILITY_TYPE, u_int32_t capability,
u_int32_t *result);
HAL_BOOL __ahdecl(*ah_setCapability)(struct ath_hal *,
HAL_CAPABILITY_TYPE, u_int32_t capability,
u_int32_t setting, HAL_STATUS *);
HAL_BOOL __ahdecl(*ah_getDiagState)(struct ath_hal *, int request,
const void *args, u_int32_t argsize,
void **result, u_int32_t *resultsize);
void __ahdecl(*ah_getMacAddress)(struct ath_hal *, u_int8_t *);
HAL_BOOL __ahdecl(*ah_setMacAddress)(struct ath_hal *, const u_int8_t*);
HAL_BOOL __ahdecl(*ah_setRegulatoryDomain)(struct ath_hal*,
u_int16_t, HAL_STATUS *);
void __ahdecl(*ah_setLedState)(struct ath_hal*, HAL_LED_STATE);
void __ahdecl(*ah_writeAssocid)(struct ath_hal*,
const u_int8_t *bssid, u_int16_t assocId);
HAL_BOOL __ahdecl(*ah_gpioCfgOutput)(struct ath_hal *, u_int32_t gpio);
HAL_BOOL __ahdecl(*ah_gpioCfgInput)(struct ath_hal *, u_int32_t gpio);
u_int32_t __ahdecl(*ah_gpioGet)(struct ath_hal *, u_int32_t gpio);
HAL_BOOL __ahdecl(*ah_gpioSet)(struct ath_hal *,
u_int32_t gpio, u_int32_t val);
void __ahdecl(*ah_gpioSetIntr)(struct ath_hal*, u_int, u_int32_t);
u_int32_t __ahdecl(*ah_getTsf32)(struct ath_hal*);
u_int64_t __ahdecl(*ah_getTsf64)(struct ath_hal*);
void __ahdecl(*ah_resetTsf)(struct ath_hal*);
HAL_BOOL __ahdecl(*ah_detectCardPresent)(struct ath_hal*);
void __ahdecl(*ah_updateMibCounters)(struct ath_hal*,
HAL_MIB_STATS*);
HAL_RFGAIN __ahdecl(*ah_getRfGain)(struct ath_hal*);
u_int __ahdecl(*ah_getDefAntenna)(struct ath_hal*);
void __ahdecl(*ah_setDefAntenna)(struct ath_hal*, u_int);
HAL_BOOL __ahdecl(*ah_setSlotTime)(struct ath_hal*, u_int);
u_int __ahdecl(*ah_getSlotTime)(struct ath_hal*);
HAL_BOOL __ahdecl(*ah_setAckTimeout)(struct ath_hal*, u_int);
u_int __ahdecl(*ah_getAckTimeout)(struct ath_hal*);
HAL_BOOL __ahdecl(*ah_setCTSTimeout)(struct ath_hal*, u_int);
u_int __ahdecl(*ah_getCTSTimeout)(struct ath_hal*);
/* Key Cache Functions */
u_int32_t __ahdecl(*ah_getKeyCacheSize)(struct ath_hal*);
HAL_BOOL __ahdecl(*ah_resetKeyCacheEntry)(struct ath_hal*, u_int16_t);
HAL_BOOL __ahdecl(*ah_isKeyCacheEntryValid)(struct ath_hal *,
u_int16_t);
HAL_BOOL __ahdecl(*ah_setKeyCacheEntry)(struct ath_hal*,
u_int16_t, const HAL_KEYVAL *,
const u_int8_t *, int);
HAL_BOOL __ahdecl(*ah_setKeyCacheEntryMac)(struct ath_hal*,
u_int16_t, const u_int8_t *);
/* Power Management Functions */
HAL_BOOL __ahdecl(*ah_setPowerMode)(struct ath_hal*,
HAL_POWER_MODE mode, int setChip,
u_int16_t sleepDuration);
HAL_POWER_MODE __ahdecl(*ah_getPowerMode)(struct ath_hal*);
HAL_BOOL __ahdecl(*ah_initPSPoll)(struct ath_hal*);
HAL_BOOL __ahdecl(*ah_enablePSPoll)(struct ath_hal *,
u_int8_t *, u_int16_t);
HAL_BOOL __ahdecl(*ah_disablePSPoll)(struct ath_hal *);
/* Beacon Management Functions */
void __ahdecl(*ah_beaconInit)(struct ath_hal *,
u_int32_t nexttbtt, u_int32_t intval);
void __ahdecl(*ah_setStationBeaconTimers)(struct ath_hal*,
const HAL_BEACON_STATE *);
void __ahdecl(*ah_resetStationBeaconTimers)(struct ath_hal*);
HAL_BOOL __ahdecl(*ah_waitForBeaconDone)(struct ath_hal *,
HAL_BUS_ADDR);
/* Interrupt functions */
HAL_BOOL __ahdecl(*ah_isInterruptPending)(struct ath_hal*);
HAL_BOOL __ahdecl(*ah_getPendingInterrupts)(struct ath_hal*, HAL_INT*);
HAL_INT __ahdecl(*ah_getInterrupts)(struct ath_hal*);
HAL_INT __ahdecl(*ah_setInterrupts)(struct ath_hal*, HAL_INT);
};
/*
* Check the PCI vendor ID and device ID against Atheros' values
* and return a printable description for any Atheros hardware.
* AH_NULL is returned if the ID's do not describe Atheros hardware.
*/
extern const char *__ahdecl ath_hal_probe(u_int16_t vendorid, u_int16_t devid);
/*
* Attach the HAL for use with the specified device. The device is
* defined by the PCI device ID. The caller provides an opaque pointer
* to an upper-layer data structure (HAL_SOFTC) that is stored in the
* HAL state block for later use. Hardware register accesses are done
* using the specified bus tag and handle. On successful return a
* reference to a state block is returned that must be supplied in all
* subsequent HAL calls. Storage associated with this reference is
* dynamically allocated and must be freed by calling the ah_detach
* method when the client is done. If the attach operation fails a
* null (AH_NULL) reference will be returned and a status code will
* be returned if the status parameter is non-zero.
*/
extern struct ath_hal * __ahdecl ath_hal_attach(u_int16_t devid, HAL_SOFTC,
HAL_BUS_TAG, HAL_BUS_HANDLE, HAL_STATUS* status);
/*
* Return a list of channels available for use with the hardware.
* The list is based on what the hardware is capable of, the specified
* country code, the modeSelect mask, and whether or not outdoor
* channels are to be permitted.
*
* The channel list is returned in the supplied array. maxchans
* defines the maximum size of this array. nchans contains the actual
* number of channels returned. If a problem occurred or there were
* no channels that met the criteria then AH_FALSE is returned.
*/
extern HAL_BOOL __ahdecl ath_hal_init_channels(struct ath_hal *,
HAL_CHANNEL *chans, u_int maxchans, u_int *nchans,
HAL_CTRY_CODE cc, u_int16_t modeSelect,
HAL_BOOL enableOutdoor, HAL_BOOL enableExtendedChannels);
/*
* Return bit mask of wireless modes supported by the hardware.
*/
extern u_int __ahdecl ath_hal_getwirelessmodes(struct ath_hal*, HAL_CTRY_CODE);
/*
* Return rate table for specified mode (11a, 11b, 11g, etc).
*/
extern const HAL_RATE_TABLE * __ahdecl ath_hal_getratetable(struct ath_hal *,
u_int mode);
/*
* Calculate the transmit duration of a frame.
*/
extern u_int16_t __ahdecl ath_hal_computetxtime(struct ath_hal *,
const HAL_RATE_TABLE *rates, u_int32_t frameLen,
u_int16_t rateix, HAL_BOOL shortPreamble);
/*
* Convert between IEEE channel number and channel frequency
* using the specified channel flags; e.g. CHANNEL_2GHZ.
*/
extern u_int __ahdecl ath_hal_mhz2ieee(u_int mhz, u_int flags);
extern u_int __ahdecl ath_hal_ieee2mhz(u_int ieee, u_int flags);
/*
* Return a version string for the HAL release.
*/
extern char ath_hal_version[];
/*
* Return a NULL-terminated array of build/configuration options.
*/
extern const char* ath_hal_buildopts[];
#endif /* _ATH_AH_H_ */

View File

@ -0,0 +1,180 @@
/*-
* Copyright (c) 2002-2004 Sam Leffler, Errno Consulting, Atheros
* Communications, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the following conditions are met:
* 1. The materials contained herein are unmodified and are used
* unmodified.
* 2. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following NO
* ''WARRANTY'' disclaimer below (''Disclaimer''), without
* modification.
* 3. Redistributions in binary form must reproduce at minimum a
* disclaimer similar to the Disclaimer below and any redistribution
* must be conditioned upon including a substantially similar
* Disclaimer requirement for further binary redistribution.
* 4. Neither the names of the above-listed copyright holders nor the
* names of any contributors may be used to endorse or promote
* product derived from this software without specific prior written
* permission.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT,
* MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
* FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGES.
*
* $Id: athhal_desc.h,v 1.1.1.1 2005/06/21 20:37:50 dyoung Exp $
*/
#ifndef _DEV_ATH_DESC_H
#define _DEV_ATH_DESC_H
/*
* Transmit descriptor status. This structure is filled
* in only after the tx descriptor process method finds a
* ``done'' descriptor; at which point it returns something
* other than HAL_EINPROGRESS.
*
* Note that ts_antenna may not be valid for all h/w. It
* should be used only if non-zero.
*/
struct ath_tx_status {
u_int16_t ts_seqnum; /* h/w assigned sequence number */
u_int16_t ts_tstamp; /* h/w assigned timestamp */
u_int8_t ts_status; /* frame status, 0 => xmit ok */
u_int8_t ts_rate; /* h/w transmit rate index */
#define HAL_TXSTAT_ALTRATE 0x80 /* alternate xmit rate used */
int8_t ts_rssi; /* tx ack RSSI */
u_int8_t ts_shortretry; /* # short retries */
u_int8_t ts_longretry; /* # long retries */
u_int8_t ts_virtcol; /* virtual collision count */
u_int8_t ts_antenna; /* antenna information */
};
#define HAL_TXERR_XRETRY 0x01 /* excessive retries */
#define HAL_TXERR_FILT 0x02 /* blocked by tx filtering */
#define HAL_TXERR_FIFO 0x04 /* fifo underrun */
/*
* Receive descriptor status. This structure is filled
* in only after the rx descriptor process method finds a
* ``done'' descriptor; at which point it returns something
* other than HAL_EINPROGRESS.
*
* If rx_status is zero, then the frame was received ok;
* otherwise the error information is indicated and rs_phyerr
* contains a phy error code if HAL_RXERR_PHY is set. In general
* the frame contents is undefined when an error occurred thought
* for some errors (e.g. a decryption error), it may be meaningful.
*
* Note that the receive timestamp is expanded using the TSF to
* a full 16 bits (regardless of what the h/w provides directly).
*
* rx_rssi is in units of dbm above the noise floor. This value
* is measured during the preamble and PLCP; i.e. with the initial
* 4us of detection. The noise floor is typically a consistent
* -96dBm absolute power in a 20MHz channel.
*/
struct ath_rx_status {
u_int16_t rs_datalen; /* rx frame length */
u_int16_t rs_tstamp; /* h/w assigned timestamp */
u_int8_t rs_status; /* rx status, 0 => recv ok */
u_int8_t rs_phyerr; /* phy error code */
int8_t rs_rssi; /* rx frame RSSI */
u_int8_t rs_keyix; /* key cache index */
u_int8_t rs_rate; /* h/w receive rate index */
u_int8_t rs_antenna; /* antenna information */
u_int8_t rs_more; /* more descriptors follow */
};
#define HAL_RXERR_CRC 0x01 /* CRC error on frame */
#define HAL_RXERR_PHY 0x02 /* PHY error, rs_phyerr is valid */
#define HAL_RXERR_FIFO 0x04 /* fifo overrun */
#define HAL_RXERR_DECRYPT 0x08 /* non-Michael decrypt error */
#define HAL_RXERR_MIC 0x10 /* Michael MIC decrypt error */
enum {
HAL_PHYERR_UNDERRUN = 0, /* Transmit underrun */
HAL_PHYERR_TIMING = 1, /* Timing error */
HAL_PHYERR_PARITY = 2, /* Illegal parity */
HAL_PHYERR_RATE = 3, /* Illegal rate */
HAL_PHYERR_LENGTH = 4, /* Illegal length */
HAL_PHYERR_RADAR = 5, /* Radar detect */
HAL_PHYERR_SERVICE = 6, /* Illegal service */
HAL_PHYERR_TOR = 7, /* Transmit override receive */
/* NB: these are specific to the 5212 */
HAL_PHYERR_OFDM_TIMING = 17, /* */
HAL_PHYERR_OFDM_SIGNAL_PARITY = 18, /* */
HAL_PHYERR_OFDM_RATE_ILLEGAL = 19, /* */
HAL_PHYERR_OFDM_LENGTH_ILLEGAL = 20, /* */
HAL_PHYERR_OFDM_POWER_DROP = 21, /* */
HAL_PHYERR_OFDM_SERVICE = 22, /* */
HAL_PHYERR_OFDM_RESTART = 23, /* */
HAL_PHYERR_CCK_TIMING = 25, /* */
HAL_PHYERR_CCK_HEADER_CRC = 26, /* */
HAL_PHYERR_CCK_RATE_ILLEGAL = 27, /* */
HAL_PHYERR_CCK_SERVICE = 30, /* */
HAL_PHYERR_CCK_RESTART = 31, /* */
};
/* value found in rs_keyix to mark invalid entries */
#define HAL_RXKEYIX_INVALID ((u_int8_t) -1)
/* value used to specify no encryption key for xmit */
#define HAL_TXKEYIX_INVALID ((u_int) -1)
/* XXX rs_antenna definitions */
/*
* Definitions for the software frame/packet descriptors used by
* the Atheros HAL. This definition obscures hardware-specific
* details from the driver. Drivers are expected to fillin the
* portions of a descriptor that are not opaque then use HAL calls
* to complete the work. Status for completed frames is returned
* in a device-independent format.
*/
struct ath_desc {
/*
* The following definitions are passed directly
* the hardware and managed by the HAL. Drivers
* should not touch those elements marked opaque.
*/
u_int32_t ds_link; /* phys address of next descriptor */
u_int32_t ds_data; /* phys address of data buffer */
u_int32_t ds_ctl0; /* opaque DMA control 0 */
u_int32_t ds_ctl1; /* opaque DMA control 1 */
u_int32_t ds_hw[4]; /* opaque h/w region */
/*
* The remaining definitions are managed by software;
* these are valid only after the rx/tx process descriptor
* methods return a non-EINPROGRESS code.
*/
union {
struct ath_tx_status tx;/* xmit status */
struct ath_rx_status rx;/* recv status */
} ds_us;
} __packed;
#define ds_txstat ds_us.tx
#define ds_rxstat ds_us.rx
/* flags passed to tx descriptor setup methods */
#define HAL_TXDESC_CLRDMASK 0x0001 /* clear destination filter mask */
#define HAL_TXDESC_NOACK 0x0002 /* don't wait for ACK */
#define HAL_TXDESC_RTSENA 0x0004 /* enable RTS */
#define HAL_TXDESC_CTSENA 0x0008 /* enable CTS */
#define HAL_TXDESC_INTREQ 0x0010 /* enable per-descriptor interrupt */
#define HAL_TXDESC_VEOL 0x0020 /* mark virtual EOL */
/* flags passed to rx descriptor setup methods */
#define HAL_RXDESC_INTREQ 0x0020 /* enable per-descriptor interrupt */
#endif /* _DEV_ATH_AR521XDMA_H */

View File

@ -0,0 +1,87 @@
/*-
* Copyright (c) 2002-2004 Sam Leffler, Errno Consulting, Atheros
* Communications, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the following conditions are met:
* 1. The materials contained herein are unmodified and are used
* unmodified.
* 2. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following NO
* ''WARRANTY'' disclaimer below (''Disclaimer''), without
* modification.
* 3. Redistributions in binary form must reproduce at minimum a
* disclaimer similar to the Disclaimer below and any redistribution
* must be conditioned upon including a substantially similar
* Disclaimer requirement for further binary redistribution.
* 4. Neither the names of the above-listed copyright holders nor the
* names of any contributors may be used to endorse or promote
* product derived from this software without specific prior written
* permission.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT,
* MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
* FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGES.
*
* $Id: athhal_devid.h,v 1.1.1.1 2005/06/21 20:37:50 dyoung Exp $
*/
#ifndef _DEV_ATH_DEVID_H_
#define _DEV_ATH_DEVID_H_
#define ATHEROS_VENDOR_ID 0x168c /* Atheros PCI vendor ID */
/*
* NB: all Atheros-based devices should have a PCI vendor ID
* of 0x168c, but some vendors, in their infinite wisdom
* do not follow this so we must handle them specially.
*/
#define ATHEROS_3COM_VENDOR_ID 0xa727 /* 3Com 3CRPAG175 vendor ID */
#define ATHEROS_3COM2_VENDOR_ID 0x10b7 /* 3Com 3CRDAG675 vendor ID */
/* AR5210 (for reference) */
#define AR5210_DEFAULT 0x1107 /* No eeprom HW default */
#define AR5210_PROD 0x0007 /* Final device ID */
#define AR5210_AP 0x0207 /* Early AP11s */
/* AR5211 */
#define AR5211_DEFAULT 0x1112 /* No eeprom HW default */
#define AR5311_DEVID 0x0011 /* Final ar5311 devid */
#define AR5211_DEVID 0x0012 /* Final ar5211 devid */
#define AR5211_LEGACY 0xff12 /* Original emulation board */
#define AR5211_FPGA11B 0xf11b /* 11b emulation board */
/* AR5212 */
#define AR5212_DEFAULT 0x1113 /* No eeprom HW default */
#define AR5212_DEVID 0x0013 /* Final ar5212 devid */
#define AR5212_FPGA 0xf013 /* Emulation board */
#define AR5212_DEVID_IBM 0x1014 /* IBM minipci ID */
#define AR5212_AR5312_REV2 0x0052 /* AR5312 WMAC (AP31) */
#define AR5212_AR5312_REV7 0x0057 /* AR5312 WMAC (AP30-040) */
#define AR5212_AR2313_REV8 0x0058 /* AR2313 WMAC (AP43-030) */
/* AR5212 compatible devid's also attach to 5212 */
#define AR5212_DEVID_0014 0x0014
#define AR5212_DEVID_0015 0x0015
#define AR5212_DEVID_0016 0x0016
#define AR5212_DEVID_0017 0x0017
#define AR5212_DEVID_0018 0x0018
#define AR5212_DEVID_0019 0x0019
#define AR5212_AR2413 0x001a /* AR2413 aka Griffin-lite */
/* AR5213 */
#define AR5213_SREV_1_0 0x0055
#define AR5213_SREV_REG 0x4020
#define AR_SUBVENDOR_ID_NOG 0x0e11 /* No 11G subvendor ID */
#define AR_SUBVENDOR_ID_NEW_A 0x7065 /* Update device to new RD */
#endif /* _DEV_ATH_DEVID_H */

View File

@ -0,0 +1,90 @@
#
# Copyright (c) 2002-2004 Sam Leffler, Errno Consulting, Atheros
# Communications, Inc. All rights reserved.
#
# Redistribution and use in source and binary forms are permitted
# provided that the following conditions are met:
# 1. The materials contained herein are unmodified and are used
# unmodified.
# 2. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following NO
# ''WARRANTY'' disclaimer below (''Disclaimer''), without
# modification.
# 3. Redistributions in binary form must reproduce at minimum a
# disclaimer similar to the Disclaimer below and any redistribution
# must be conditioned upon including a substantially similar
# Disclaimer requirement for further binary redistribution.
# 4. Neither the names of the above-listed copyright holders nor the
# names of any contributors may be used to endorse or promote
# product derived from this software without specific prior written
# permission.
#
# NO WARRANTY
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT,
# MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
# FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGES.
#
# $Id: athhal_if.m,v 1.1.1.1 2005/06/21 20:37:50 dyoung Exp $
#
INTERFACE ath_hal;
METHOD const char* ath_hal_probe {
u_int16_t vendorID;
u_int16_ deviceID;
};
METHOD struct ath_hal* ath_hal_attach {
u_int16_t deviceID;
HAL_SOFTC sc;
HAL_BUS_TAG st;
HAL_BUS_HANDLE sh;
HAL_STATUS* error;
};
METHOD u_int ath_hal_init_channels {
struct ath_hal* ah;
HAL_CHANNEL* chans;
u_int maxchans;
u_int* nchans;
HAL_CTRY_CODE cc;
u_int16_t modeSelect;
int enableOutdoor;
};
METHOD u_int ath_hal_getwirelessmodes {
struct ath_hal* ah;
HAL_CTRY_CODE cc;
};
METHOD const HAL_RATE_TABLE* ath_hal_getratetable {
struct ath_hal* ah;
u_int mode;
};
METHOD u_int16_t ath_hal_computetxtime {
struct ath_hal* ah;
const HAL_RATE_TABLE* rates;
u_int32_t frameLength;
u_int16_t rateIndex;
HAL_BOOL shortPreamble;
};
METHOD u_int ath_hal_mhz2ieee {
u_int mhz;
u_int flags;
};
METHOD u_int ath_hal_ieee2mhz {
u_int ieee;
u_int flags;
};

View File

@ -0,0 +1,415 @@
/*-
* Copyright (c) 2002-2004 Sam Leffler, Errno Consulting, Atheros
* Communications, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the following conditions are met:
* 1. The materials contained herein are unmodified and are used
* unmodified.
* 2. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following NO
* ''WARRANTY'' disclaimer below (''Disclaimer''), without
* modification.
* 3. Redistributions in binary form must reproduce at minimum a
* disclaimer similar to the Disclaimer below and any redistribution
* must be conditioned upon including a substantially similar
* Disclaimer requirement for further binary redistribution.
* 4. Neither the names of the above-listed copyright holders nor the
* names of any contributors may be used to endorse or promote
* product derived from this software without specific prior written
* permission.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT,
* MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
* FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGES.
*
* $Id: athhal_osdep.c,v 1.1.1.1 2005/06/21 20:37:50 dyoung Exp $
*/
#include "opt_ah.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/sysctl.h>
#include <sys/bus.h>
#include <sys/malloc.h>
#include <sys/proc.h>
#include <machine/stdarg.h>
#include <net/ethernet.h> /* XXX for ether_sprintf */
#include <contrib/dev/ath/ah.h>
extern void ath_hal_printf(struct ath_hal *, const char*, ...)
__printflike(2,3);
extern void ath_hal_vprintf(struct ath_hal *, const char*, __va_list)
__printflike(2, 0);
extern const char* ath_hal_ether_sprintf(const u_int8_t *mac);
extern void *ath_hal_malloc(size_t);
extern void ath_hal_free(void *);
#ifdef AH_ASSERT
extern void ath_hal_assert_failed(const char* filename,
int lineno, const char* msg);
#endif
#ifdef AH_DEBUG
extern void HALDEBUG(struct ath_hal *ah, const char* fmt, ...);
extern void HALDEBUGn(struct ath_hal *ah, u_int level, const char* fmt, ...);
#endif /* AH_DEBUG */
/* NB: put this here instead of the driver to avoid circular references */
SYSCTL_NODE(_hw, OID_AUTO, ath, CTLFLAG_RD, 0, "Atheros driver parameters");
SYSCTL_NODE(_hw_ath, OID_AUTO, hal, CTLFLAG_RD, 0, "Atheros HAL parameters");
#ifdef AH_DEBUG
static int ath_hal_debug = 0;
SYSCTL_INT(_hw_ath_hal, OID_AUTO, debug, CTLFLAG_RW, &ath_hal_debug,
0, "Atheros HAL debugging printfs");
TUNABLE_INT("hw.ath.hal.debug", &ath_hal_debug);
#endif /* AH_DEBUG */
SYSCTL_STRING(_hw_ath_hal, OID_AUTO, version, CTLFLAG_RD, ath_hal_version, 0,
"Atheros HAL version");
int ath_hal_dma_beacon_response_time = 2; /* in TU's */
SYSCTL_INT(_hw_ath_hal, OID_AUTO, dma_brt, CTLFLAG_RW,
&ath_hal_dma_beacon_response_time, 0,
"Atheros HAL DMA beacon response time");
int ath_hal_sw_beacon_response_time = 10; /* in TU's */
SYSCTL_INT(_hw_ath_hal, OID_AUTO, sw_brt, CTLFLAG_RW,
&ath_hal_sw_beacon_response_time, 0,
"Atheros HAL software beacon response time");
int ath_hal_additional_swba_backoff = 0; /* in TU's */
SYSCTL_INT(_hw_ath_hal, OID_AUTO, swba_backoff, CTLFLAG_RW,
&ath_hal_additional_swba_backoff, 0,
"Atheros HAL additional SWBA backoff time");
void*
ath_hal_malloc(size_t size)
{
return malloc(size, M_DEVBUF, M_NOWAIT | M_ZERO);
}
void
ath_hal_free(void* p)
{
return free(p, M_DEVBUF);
}
void
ath_hal_vprintf(struct ath_hal *ah, const char* fmt, va_list ap)
{
vprintf(fmt, ap);
}
void
ath_hal_printf(struct ath_hal *ah, const char* fmt, ...)
{
va_list ap;
va_start(ap, fmt);
ath_hal_vprintf(ah, fmt, ap);
va_end(ap);
}
const char*
ath_hal_ether_sprintf(const u_int8_t *mac)
{
return ether_sprintf(mac);
}
#ifdef AH_DEBUG
void
HALDEBUG(struct ath_hal *ah, const char* fmt, ...)
{
if (ath_hal_debug) {
__va_list ap;
va_start(ap, fmt);
ath_hal_vprintf(ah, fmt, ap);
va_end(ap);
}
}
void
HALDEBUGn(struct ath_hal *ah, u_int level, const char* fmt, ...)
{
if (ath_hal_debug >= level) {
__va_list ap;
va_start(ap, fmt);
ath_hal_vprintf(ah, fmt, ap);
va_end(ap);
}
}
#endif /* AH_DEBUG */
#ifdef AH_DEBUG_ALQ
/*
* ALQ register tracing support.
*
* Setting hw.ath.hal.alq=1 enables tracing of all register reads and
* writes to the file /tmp/ath_hal.log. The file format is a simple
* fixed-size array of records. When done logging set hw.ath.hal.alq=0
* and then decode the file with the arcode program (that is part of the
* HAL). If you start+stop tracing the data will be appended to an
* existing file.
*
* NB: doesn't handle multiple devices properly; only one DEVICE record
* is emitted and the different devices are not identified.
*/
#include <sys/alq.h>
#include <sys/pcpu.h>
#include <contrib/dev/ath/ah_decode.h>
static struct alq *ath_hal_alq;
static int ath_hal_alq_emitdev; /* need to emit DEVICE record */
static u_int ath_hal_alq_lost; /* count of lost records */
static const char *ath_hal_logfile = "/tmp/ath_hal.log";
static u_int ath_hal_alq_qsize = 64*1024;
static int
ath_hal_setlogging(int enable)
{
int error;
if (enable) {
error = suser(curthread);
if (error == 0) {
error = alq_open(&ath_hal_alq, ath_hal_logfile,
curthread->td_ucred, ALQ_DEFAULT_CMODE,
sizeof (struct athregrec), ath_hal_alq_qsize);
ath_hal_alq_lost = 0;
ath_hal_alq_emitdev = 1;
printf("ath_hal: logging to %s enabled\n",
ath_hal_logfile);
}
} else {
if (ath_hal_alq)
alq_close(ath_hal_alq);
ath_hal_alq = NULL;
printf("ath_hal: logging disabled\n");
error = 0;
}
return (error);
}
static int
sysctl_hw_ath_hal_log(SYSCTL_HANDLER_ARGS)
{
int error, enable;
enable = (ath_hal_alq != NULL);
error = sysctl_handle_int(oidp, &enable, 0, req);
if (error || !req->newptr)
return (error);
else
return (ath_hal_setlogging(enable));
}
SYSCTL_PROC(_hw_ath_hal, OID_AUTO, alq, CTLTYPE_INT|CTLFLAG_RW,
0, 0, sysctl_hw_ath_hal_log, "I", "Enable HAL register logging");
SYSCTL_INT(_hw_ath_hal, OID_AUTO, alq_size, CTLFLAG_RW,
&ath_hal_alq_qsize, 0, "In-memory log size (#records)");
SYSCTL_INT(_hw_ath_hal, OID_AUTO, alq_lost, CTLFLAG_RW,
&ath_hal_alq_lost, 0, "Register operations not logged");
static struct ale *
ath_hal_alq_get(struct ath_hal *ah)
{
struct ale *ale;
if (ath_hal_alq_emitdev) {
ale = alq_get(ath_hal_alq, ALQ_NOWAIT);
if (ale) {
struct athregrec *r =
(struct athregrec *) ale->ae_data;
r->op = OP_DEVICE;
r->reg = 0;
r->val = ah->ah_devid;
alq_post(ath_hal_alq, ale);
ath_hal_alq_emitdev = 0;
} else
ath_hal_alq_lost++;
}
ale = alq_get(ath_hal_alq, ALQ_NOWAIT);
if (!ale)
ath_hal_alq_lost++;
return ale;
}
void
ath_hal_reg_write(struct ath_hal *ah, u_int32_t reg, u_int32_t val)
{
if (ath_hal_alq) {
struct ale *ale = ath_hal_alq_get(ah);
if (ale) {
struct athregrec *r = (struct athregrec *) ale->ae_data;
r->op = OP_WRITE;
r->reg = reg;
r->val = val;
alq_post(ath_hal_alq, ale);
}
}
#if _BYTE_ORDER == _BIG_ENDIAN
if (reg >= 0x4000 && reg < 0x5000)
bus_space_write_4(ah->ah_st, ah->ah_sh, reg, htole32(val));
else
#endif
bus_space_write_4(ah->ah_st, ah->ah_sh, reg, val);
}
u_int32_t
ath_hal_reg_read(struct ath_hal *ah, u_int32_t reg)
{
u_int32_t val;
val = bus_space_read_4(ah->ah_st, ah->ah_sh, reg);
#if _BYTE_ORDER == _BIG_ENDIAN
if (reg >= 0x4000 && reg < 0x5000)
val = le32toh(val);
#endif
if (ath_hal_alq) {
struct ale *ale = ath_hal_alq_get(ah);
if (ale) {
struct athregrec *r = (struct athregrec *) ale->ae_data;
r->op = OP_READ;
r->reg = reg;
r->val = val;
alq_post(ath_hal_alq, ale);
}
}
return val;
}
void
OS_MARK(struct ath_hal *ah, u_int id, u_int32_t v)
{
if (ath_hal_alq) {
struct ale *ale = ath_hal_alq_get(ah);
if (ale) {
struct athregrec *r = (struct athregrec *) ale->ae_data;
r->op = OP_MARK;
r->reg = id;
r->val = v;
alq_post(ath_hal_alq, ale);
}
}
}
#elif defined(AH_DEBUG) || defined(AH_REGOPS_FUNC)
/*
* Memory-mapped device register read/write. These are here
* as routines when debugging support is enabled and/or when
* explicitly configured to use function calls. The latter is
* for architectures that might need to do something before
* referencing memory (e.g. remap an i/o window).
*
* NB: see the comments in ah_osdep.h about byte-swapping register
* reads and writes to understand what's going on below.
*/
void
ath_hal_reg_write(struct ath_hal *ah, u_int32_t reg, u_int32_t val)
{
#if _BYTE_ORDER == _BIG_ENDIAN
if (reg >= 0x4000 && reg < 0x5000)
bus_space_write_4(ah->ah_st, ah->ah_sh, reg, htole32(val));
else
#endif
bus_space_write_4(ah->ah_st, ah->ah_sh, reg, val);
}
u_int32_t
ath_hal_reg_read(struct ath_hal *ah, u_int32_t reg)
{
u_int32_t val;
val = bus_space_read_4(ah->ah_st, ah->ah_sh, reg);
#if _BYTE_ORDER == _BIG_ENDIAN
if (reg >= 0x4000 && reg < 0x5000)
val = le32toh(val);
#endif
return val;
}
#endif /* AH_DEBUG || AH_REGOPS_FUNC */
#ifdef AH_ASSERT
void
ath_hal_assert_failed(const char* filename, int lineno, const char *msg)
{
printf("Atheros HAL assertion failure: %s: line %u: %s\n",
filename, lineno, msg);
panic("ath_hal_assert");
}
#endif /* AH_ASSERT */
/*
* Delay n microseconds.
*/
void
ath_hal_delay(int n)
{
DELAY(n);
}
u_int32_t
ath_hal_getuptime(struct ath_hal *ah)
{
struct bintime bt;
getbinuptime(&bt);
return (bt.sec * 1000) +
(((uint64_t)1000 * (uint32_t)(bt.frac >> 32)) >> 32);
}
void
ath_hal_memzero(void *dst, size_t n)
{
bzero(dst, n);
}
void *
ath_hal_memcpy(void *dst, const void *src, size_t n)
{
return memcpy(dst, src, n);
}
/*
* Module glue.
*/
static int
ath_hal_modevent(module_t mod, int type, void *unused)
{
const char *sep;
int i;
switch (type) {
case MOD_LOAD:
printf("ath_hal: %s (", ath_hal_version);
sep = "";
for (i = 0; ath_hal_buildopts[i] != NULL; i++) {
printf("%s%s", sep, ath_hal_buildopts[i]);
sep = ", ";
}
printf(")\n");
return 0;
case MOD_UNLOAD:
return 0;
}
return EINVAL;
}
static moduledata_t ath_hal_mod = {
"ath_hal",
ath_hal_modevent,
0
};
DECLARE_MODULE(ath_hal, ath_hal_mod, SI_SUB_DRIVERS, SI_ORDER_ANY);
MODULE_VERSION(ath_hal, 1);

View File

@ -0,0 +1,127 @@
/*-
* Copyright (c) 2002-2004 Sam Leffler, Errno Consulting, Atheros
* Communications, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the following conditions are met:
* 1. The materials contained herein are unmodified and are used
* unmodified.
* 2. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following NO
* ''WARRANTY'' disclaimer below (''Disclaimer''), without
* modification.
* 3. Redistributions in binary form must reproduce at minimum a
* disclaimer similar to the Disclaimer below and any redistribution
* must be conditioned upon including a substantially similar
* Disclaimer requirement for further binary redistribution.
* 4. Neither the names of the above-listed copyright holders nor the
* names of any contributors may be used to endorse or promote
* product derived from this software without specific prior written
* permission.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT,
* MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
* FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGES.
*
* $Id: athhal_osdep.h,v 1.1.1.1 2005/06/21 20:37:50 dyoung Exp $
*/
#ifndef _ATH_AH_OSDEP_H_
#define _ATH_AH_OSDEP_H_
/*
* Atheros Hardware Access Layer (HAL) OS Dependent Definitions.
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/endian.h>
#include <machine/bus.h>
typedef void* HAL_SOFTC;
typedef bus_space_tag_t HAL_BUS_TAG;
typedef bus_space_handle_t HAL_BUS_HANDLE;
typedef bus_addr_t HAL_BUS_ADDR;
/*
* Delay n microseconds.
*/
extern void ath_hal_delay(int);
#define OS_DELAY(_n) ath_hal_delay(_n)
#define OS_INLINE __inline
#define OS_MEMZERO(_a, _n) ath_hal_memzero((_a), (_n))
extern void ath_hal_memzero(void *, size_t);
#define OS_MEMCPY(_d, _s, _n) ath_hal_memcpy(_d,_s,_n)
extern void *ath_hal_memcpy(void *, const void *, size_t);
#define abs(_a) __builtin_abs(_a)
struct ath_hal;
extern u_int32_t ath_hal_getuptime(struct ath_hal *);
#define OS_GETUPTIME(_ah) ath_hal_getuptime(_ah)
/*
* Register read/write; we assume the registers will always
* be memory-mapped. Note that register accesses are done
* using target-specific functions when debugging is enabled
* (AH_DEBUG) or we are explicitly configured this way. The
* latter is used on some platforms where the full i/o space
* cannot be directly mapped.
*/
#if defined(AH_DEBUG) || defined(AH_REGOPS_FUNC) || defined(AH_DEBUG_ALQ)
#define OS_REG_WRITE(_ah, _reg, _val) ath_hal_reg_write(_ah, _reg, _val)
#define OS_REG_READ(_ah, _reg) ath_hal_reg_read(_ah, _reg)
extern void ath_hal_reg_write(struct ath_hal *ah, u_int reg, u_int32_t val);
extern u_int32_t ath_hal_reg_read(struct ath_hal *ah, u_int reg);
#else
/*
* The hardware registers are native little-endian byte order.
* Big-endian hosts are handled by enabling hardware byte-swap
* of register reads and writes at reset. But the PCI clock
* domain registers are not byte swapped! Thus, on big-endian
* platforms we have to byte-swap thoese registers specifically.
* Most of this code is collapsed at compile time because the
* register values are constants.
*/
#define AH_LITTLE_ENDIAN 1234
#define AH_BIG_ENDIAN 4321
#if _BYTE_ORDER == _BIG_ENDIAN
#define OS_REG_WRITE(_ah, _reg, _val) do { \
if ( (_reg) >= 0x4000 && (_reg) < 0x5000) \
bus_space_write_4((_ah)->ah_st, (_ah)->ah_sh, \
(_reg), htole32(_val)); \
else \
bus_space_write_4((_ah)->ah_st, (_ah)->ah_sh, \
(_reg), (_val)); \
} while (0)
#define OS_REG_READ(_ah, _reg) \
(((_reg) >= 0x4000 && (_reg) < 0x5000) ? \
le32toh(bus_space_read_4((_ah)->ah_st, (_ah)->ah_sh, \
(_reg))) : \
bus_space_read_4((_ah)->ah_st, (_ah)->ah_sh, (_reg)))
#else /* _BYTE_ORDER == _LITTLE_ENDIAN */
#define OS_REG_WRITE(_ah, _reg, _val) \
bus_space_write_4((_ah)->ah_st, (_ah)->ah_sh, (_reg), (_val))
#define OS_REG_READ(_ah, _reg) \
((u_int32_t) bus_space_read_4((_ah)->ah_st, (_ah)->ah_sh, (_reg)))
#endif /* _BYTE_ORDER */
#endif /* AH_DEBUG || AH_REGFUNC || AH_DEBUG_ALQ */
#ifdef AH_DEBUG_ALQ
extern void OS_MARK(struct ath_hal *, u_int id, u_int32_t value);
#else
#define OS_MARK(_ah, _id, _v)
#endif
#endif /* _ATH_AH_OSDEP_H_ */

View File

@ -0,0 +1,38 @@
/*-
* Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
* redistribution must be conditioned upon including a substantially
* similar Disclaimer requirement for further binary redistribution.
* 3. Neither the names of the above-listed copyright holders nor the names
* of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGES.
*
* $Id: athhal_version.h,v 1.1.1.1 2005/06/21 20:37:50 dyoung Exp $
*/
#define ATH_HAL_VERSION "0.9.14.9"

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -33,7 +33,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGES.
*
* $FreeBSD: src/sys/dev/ath/if_athioctl.h,v 1.7 2004/04/02 23:57:10 sam Exp $
* $FreeBSD: src/sys/dev/ath/if_athioctl.h,v 1.10 2005/03/30 20:13:08 sam Exp $
*/
/*
@ -46,10 +46,13 @@ struct ath_stats {
u_int32_t ast_watchdog; /* device reset by watchdog */
u_int32_t ast_hardware; /* fatal hardware error interrupts */
u_int32_t ast_bmiss; /* beacon miss interrupts */
u_int32_t ast_bstuck; /* beacon stuck interrupts */
u_int32_t ast_rxorn; /* rx overrun interrupts */
u_int32_t ast_rxeol; /* rx eol interrupts */
u_int32_t ast_txurn; /* tx underrun interrupts */
u_int32_t ast_mib; /* mib interrupts */
u_int32_t ast_intrcoal; /* interrupts coalesced */
u_int32_t ast_tx_packets; /* packet sent on the interface */
u_int32_t ast_tx_mgmt; /* management frames transmitted */
u_int32_t ast_tx_discard; /* frames discarded prior to assoc */
u_int32_t ast_tx_qstop; /* output stopped 'cuz no buffer */
@ -72,17 +75,25 @@ struct ath_stats {
u_int32_t ast_tx_shortpre;/* tx frames with short preamble */
u_int32_t ast_tx_altrate; /* tx frames with alternate rate */
u_int32_t ast_tx_protect; /* tx frames with protection */
u_int32_t ast_tx_ctsburst;/* tx frames with cts and bursting */
u_int32_t ast_tx_ctsext; /* tx frames with cts extension */
u_int32_t ast_rx_nombuf; /* rx setup failed 'cuz no mbuf */
u_int32_t ast_rx_busdma; /* rx setup failed for dma resrcs */
u_int32_t ast_rx_orn; /* rx failed 'cuz of desc overrun */
u_int32_t ast_rx_crcerr; /* rx failed 'cuz of bad CRC */
u_int32_t ast_rx_fifoerr; /* rx failed 'cuz of FIFO overrun */
u_int32_t ast_rx_badcrypt;/* rx failed 'cuz decryption */
u_int32_t ast_rx_badmic; /* rx failed 'cuz MIC failure */
u_int32_t ast_rx_phyerr; /* rx failed 'cuz of PHY err */
u_int32_t ast_rx_phy[32]; /* rx PHY error per-code counts */
u_int32_t ast_rx_tooshort;/* rx discarded 'cuz frame too short */
u_int32_t ast_rx_toobig; /* rx discarded 'cuz frame too large */
u_int32_t ast_rx_packets; /* packet recv on the interface */
u_int32_t ast_rx_mgt; /* management frames received */
u_int32_t ast_rx_ctl; /* rx discarded 'cuz ctl frame */
int8_t ast_tx_rssi; /* tx rssi of last ack */
int8_t ast_rx_rssi; /* rx rssi from histogram */
u_int32_t ast_be_xmit; /* beacons transmitted */
u_int32_t ast_be_nombuf; /* beacon setup failed 'cuz no mbuf */
u_int32_t ast_per_cal; /* periodic calibration calls */
u_int32_t ast_per_calfail;/* periodic calibration failed */
@ -90,15 +101,25 @@ struct ath_stats {
u_int32_t ast_rate_calls; /* rate control checks */
u_int32_t ast_rate_raise; /* rate control raised xmit rate */
u_int32_t ast_rate_drop; /* rate control dropped xmit rate */
u_int32_t ast_ant_defswitch;/* rx/default antenna switches */
u_int32_t ast_ant_txswitch;/* tx antenna switches */
u_int32_t ast_ant_rx[8]; /* rx frames with antenna */
u_int32_t ast_ant_tx[8]; /* tx frames with antenna */
};
#define SIOCGATHSTATS _IOWR('i', 137, struct ifreq)
struct ath_diag {
char ad_name[IFNAMSIZ]; /* if name, e.g. "ath0" */
u_int ad_id;
caddr_t ad_data;
u_int ad_size;
char ad_name[IFNAMSIZ]; /* if name, e.g. "ath0" */
u_int16_t ad_id;
#define ATH_DIAG_DYN 0x8000 /* allocate buffer in caller */
#define ATH_DIAG_IN 0x4000 /* copy in parameters */
#define ATH_DIAG_OUT 0x0000 /* copy out results (always) */
#define ATH_DIAG_ID 0x0fff
u_int16_t ad_in_size; /* pack to fit, yech */
caddr_t ad_in_data;
caddr_t ad_out_data;
u_int ad_out_size;
};
#define SIOCGATHDIAG _IOWR('i', 138, struct ath_diag)

547
sys/dev/ic/athrate-amrr.c Normal file
View File

@ -0,0 +1,547 @@
/*-
* Copyright (c) 2004 INRIA
* Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
* redistribution must be conditioned upon including a substantially
* similar Disclaimer requirement for further binary redistribution.
* 3. Neither the names of the above-listed copyright holders nor the names
* of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGES.
*
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/dev/ath/ath_rate/amrr/amrr.c,v 1.7 2005/04/02 18:54:30 sam Exp $");
/*
* AMRR rate control. See:
* http://www-sop.inria.fr/rapports/sophia/RR-5208.html
* "IEEE 802.11 Rate Adaptation: A Practical Approach" by
* Mathieu Lacage, Hossein Manshaei, Thierry Turletti
*/
#include "opt_inet.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/sysctl.h>
#include <sys/module.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/errno.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <sys/bus.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/if_media.h>
#include <net/if_arp.h>
#include <net/ethernet.h> /* XXX for ether_sprintf */
#include <net80211/ieee80211_var.h>
#include <net/bpf.h>
#ifdef INET
#include <netinet/in.h>
#include <netinet/if_ether.h>
#endif
#include <dev/ath/if_athvar.h>
#include <dev/ath/ath_rate/amrr/amrr.h>
#include <contrib/dev/ath/ah_desc.h>
#define AMRR_DEBUG
#ifdef AMRR_DEBUG
#define DPRINTF(sc, _fmt, ...) do { \
if (sc->sc_debug & 0x10) \
printf(_fmt, __VA_ARGS__); \
} while (0)
#else
#define DPRINTF(sc, _fmt, ...)
#endif
static int ath_rateinterval = 1000; /* rate ctl interval (ms) */
static int ath_rate_max_success_threshold = 10;
static int ath_rate_min_success_threshold = 1;
static void ath_ratectl(void *);
static void ath_rate_update(struct ath_softc *, struct ieee80211_node *,
int rate);
static void ath_rate_ctl_start(struct ath_softc *, struct ieee80211_node *);
static void ath_rate_ctl(void *, struct ieee80211_node *);
void
ath_rate_node_init(struct ath_softc *sc, struct ath_node *an)
{
/* NB: assumed to be zero'd by caller */
ath_rate_update(sc, &an->an_node, 0);
}
void
ath_rate_node_cleanup(struct ath_softc *sc, struct ath_node *an)
{
}
void
ath_rate_findrate(struct ath_softc *sc, struct ath_node *an,
int shortPreamble, size_t frameLen,
u_int8_t *rix, int *try0, u_int8_t *txrate)
{
struct amrr_node *amn = ATH_NODE_AMRR(an);
*rix = amn->amn_tx_rix0;
*try0 = amn->amn_tx_try0;
if (shortPreamble)
*txrate = amn->amn_tx_rate0sp;
else
*txrate = amn->amn_tx_rate0;
}
void
ath_rate_setupxtxdesc(struct ath_softc *sc, struct ath_node *an,
struct ath_desc *ds, int shortPreamble, u_int8_t rix)
{
struct amrr_node *amn = ATH_NODE_AMRR(an);
ath_hal_setupxtxdesc(sc->sc_ah, ds
, amn->amn_tx_rate1sp, amn->amn_tx_try1 /* series 1 */
, amn->amn_tx_rate2sp, amn->amn_tx_try2 /* series 2 */
, amn->amn_tx_rate3sp, amn->amn_tx_try3 /* series 3 */
);
}
void
ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an,
const struct ath_desc *ds, const struct ath_desc *ds0)
{
struct amrr_node *amn = ATH_NODE_AMRR(an);
int sr = ds->ds_txstat.ts_shortretry;
int lr = ds->ds_txstat.ts_longretry;
int retry_count = sr + lr;
amn->amn_tx_try0_cnt++;
if (retry_count == 1) {
amn->amn_tx_try1_cnt++;
} else if (retry_count == 2) {
amn->amn_tx_try1_cnt++;
amn->amn_tx_try2_cnt++;
} else if (retry_count == 3) {
amn->amn_tx_try1_cnt++;
amn->amn_tx_try2_cnt++;
amn->amn_tx_try3_cnt++;
} else if (retry_count > 3) {
amn->amn_tx_try1_cnt++;
amn->amn_tx_try2_cnt++;
amn->amn_tx_try3_cnt++;
amn->amn_tx_failure_cnt++;
}
}
void
ath_rate_newassoc(struct ath_softc *sc, struct ath_node *an, int isnew)
{
if (isnew)
ath_rate_ctl_start(sc, &an->an_node);
}
static void
node_reset (struct amrr_node *amn)
{
amn->amn_tx_try0_cnt = 0;
amn->amn_tx_try1_cnt = 0;
amn->amn_tx_try2_cnt = 0;
amn->amn_tx_try3_cnt = 0;
amn->amn_tx_failure_cnt = 0;
amn->amn_success = 0;
amn->amn_recovery = 0;
amn->amn_success_threshold = ath_rate_min_success_threshold;
}
/**
* The code below assumes that we are dealing with hardware multi rate retry
* I have no idea what will happen if you try to use this module with another
* type of hardware. Your machine might catch fire or it might work with
* horrible performance...
*/
static void
ath_rate_update(struct ath_softc *sc, struct ieee80211_node *ni, int rate)
{
struct ath_node *an = ATH_NODE(ni);
struct amrr_node *amn = ATH_NODE_AMRR(an);
const HAL_RATE_TABLE *rt = sc->sc_currates;
u_int8_t rix;
KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode));
DPRINTF(sc, "%s: set xmit rate for %s to %dM\n",
__func__, ether_sprintf(ni->ni_macaddr),
ni->ni_rates.rs_nrates > 0 ?
(ni->ni_rates.rs_rates[rate] & IEEE80211_RATE_VAL) / 2 : 0);
ni->ni_txrate = rate;
/* XXX management/control frames always go at the lowest speed */
an->an_tx_mgtrate = rt->info[0].rateCode;
an->an_tx_mgtratesp = an->an_tx_mgtrate | rt->info[0].shortPreamble;
/*
* Before associating a node has no rate set setup
* so we can't calculate any transmit codes to use.
* This is ok since we should never be sending anything
* but management frames and those always go at the
* lowest hardware rate.
*/
if (ni->ni_rates.rs_nrates > 0) {
amn->amn_tx_rix0 = sc->sc_rixmap[
ni->ni_rates.rs_rates[rate] & IEEE80211_RATE_VAL];
amn->amn_tx_rate0 = rt->info[amn->amn_tx_rix0].rateCode;
amn->amn_tx_rate0sp = amn->amn_tx_rate0 |
rt->info[amn->amn_tx_rix0].shortPreamble;
if (sc->sc_mrretry) {
amn->amn_tx_try0 = 1;
amn->amn_tx_try1 = 1;
amn->amn_tx_try2 = 1;
amn->amn_tx_try3 = 1;
if (--rate >= 0) {
rix = sc->sc_rixmap[
ni->ni_rates.rs_rates[rate]&IEEE80211_RATE_VAL];
amn->amn_tx_rate1 = rt->info[rix].rateCode;
amn->amn_tx_rate1sp = amn->amn_tx_rate1 |
rt->info[rix].shortPreamble;
} else {
amn->amn_tx_rate1 = amn->amn_tx_rate1sp = 0;
}
if (--rate >= 0) {
rix = sc->sc_rixmap[
ni->ni_rates.rs_rates[rate]&IEEE80211_RATE_VAL];
amn->amn_tx_rate2 = rt->info[rix].rateCode;
amn->amn_tx_rate2sp = amn->amn_tx_rate2 |
rt->info[rix].shortPreamble;
} else {
amn->amn_tx_rate2 = amn->amn_tx_rate2sp = 0;
}
if (rate > 0) {
/* NB: only do this if we didn't already do it above */
amn->amn_tx_rate3 = rt->info[0].rateCode;
amn->amn_tx_rate3sp =
an->an_tx_mgtrate | rt->info[0].shortPreamble;
} else {
amn->amn_tx_rate3 = amn->amn_tx_rate3sp = 0;
}
} else {
amn->amn_tx_try0 = ATH_TXMAXTRY;
/* theorically, these statements are useless because
* the code which uses them tests for an_tx_try0 == ATH_TXMAXTRY
*/
amn->amn_tx_try1 = 0;
amn->amn_tx_try2 = 0;
amn->amn_tx_try3 = 0;
amn->amn_tx_rate1 = amn->amn_tx_rate1sp = 0;
amn->amn_tx_rate2 = amn->amn_tx_rate2sp = 0;
amn->amn_tx_rate3 = amn->amn_tx_rate3sp = 0;
}
}
node_reset (amn);
}
/*
* Set the starting transmit rate for a node.
*/
static void
ath_rate_ctl_start(struct ath_softc *sc, struct ieee80211_node *ni)
{
#define RATE(_ix) (ni->ni_rates.rs_rates[(_ix)] & IEEE80211_RATE_VAL)
struct ieee80211com *ic = &sc->sc_ic;
int srate;
KASSERT(ni->ni_rates.rs_nrates > 0, ("no rates"));
if (ic->ic_fixed_rate == -1) {
/*
* No fixed rate is requested. For 11b start with
* the highest negotiated rate; otherwise, for 11g
* and 11a, we start "in the middle" at 24Mb or 36Mb.
*/
srate = ni->ni_rates.rs_nrates - 1;
if (sc->sc_curmode != IEEE80211_MODE_11B) {
/*
* Scan the negotiated rate set to find the
* closest rate.
*/
/* NB: the rate set is assumed sorted */
for (; srate >= 0 && RATE(srate) > 72; srate--)
;
KASSERT(srate >= 0, ("bogus rate set"));
}
} else {
/*
* A fixed rate is to be used; ic_fixed_rate is an
* index into the supported rate set. Convert this
* to the index into the negotiated rate set for
* the node. We know the rate is there because the
* rate set is checked when the station associates.
*/
const struct ieee80211_rateset *rs =
&ic->ic_sup_rates[ic->ic_curmode];
int r = rs->rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL;
/* NB: the rate set is assumed sorted */
srate = ni->ni_rates.rs_nrates - 1;
for (; srate >= 0 && RATE(srate) != r; srate--)
;
KASSERT(srate >= 0,
("fixed rate %d not in rate set", ic->ic_fixed_rate));
}
ath_rate_update(sc, ni, srate);
#undef RATE
}
static void
ath_rate_cb(void *arg, struct ieee80211_node *ni)
{
struct ath_softc *sc = arg;
ath_rate_update(sc, ni, 0);
}
/*
* Reset the rate control state for each 802.11 state transition.
*/
void
ath_rate_newstate(struct ath_softc *sc, enum ieee80211_state state)
{
struct amrr_softc *asc = (struct amrr_softc *) sc->sc_rc;
struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_node *ni;
if (state == IEEE80211_S_INIT) {
callout_stop(&asc->timer);
return;
}
if (ic->ic_opmode == IEEE80211_M_STA) {
/*
* Reset local xmit state; this is really only
* meaningful when operating in station mode.
*/
ni = ic->ic_bss;
if (state == IEEE80211_S_RUN) {
ath_rate_ctl_start(sc, ni);
} else {
ath_rate_update(sc, ni, 0);
}
} else {
/*
* When operating as a station the node table holds
* the AP's that were discovered during scanning.
* For any other operating mode we want to reset the
* tx rate state of each node.
*/
ieee80211_iterate_nodes(&ic->ic_sta, ath_rate_cb, sc);
ath_rate_update(sc, ic->ic_bss, 0);
}
if (ic->ic_fixed_rate == -1 && state == IEEE80211_S_RUN) {
int interval;
/*
* Start the background rate control thread if we
* are not configured to use a fixed xmit rate.
*/
interval = ath_rateinterval;
if (ic->ic_opmode == IEEE80211_M_STA)
interval /= 2;
callout_reset(&asc->timer, (interval * hz) / 1000,
ath_ratectl, &sc->sc_if);
}
}
/*
* Examine and potentially adjust the transmit rate.
*/
static void
ath_rate_ctl(void *arg, struct ieee80211_node *ni)
{
struct ath_softc *sc = arg;
struct amrr_node *amn = ATH_NODE_AMRR(ATH_NODE (ni));
int old_rate;
#define is_success(amn) \
(amn->amn_tx_try1_cnt < (amn->amn_tx_try0_cnt/10))
#define is_enough(amn) \
(amn->amn_tx_try0_cnt > 10)
#define is_failure(amn) \
(amn->amn_tx_try1_cnt > (amn->amn_tx_try0_cnt/3))
#define is_max_rate(ni) \
((ni->ni_txrate + 1) >= ni->ni_rates.rs_nrates)
#define is_min_rate(ni) \
(ni->ni_txrate == 0)
old_rate = ni->ni_txrate;
DPRINTF (sc, "cnt0: %d cnt1: %d cnt2: %d cnt3: %d -- threshold: %d\n",
amn->amn_tx_try0_cnt,
amn->amn_tx_try1_cnt,
amn->amn_tx_try2_cnt,
amn->amn_tx_try3_cnt,
amn->amn_success_threshold);
if (is_success (amn) && is_enough (amn)) {
amn->amn_success++;
if (amn->amn_success == amn->amn_success_threshold &&
!is_max_rate (ni)) {
amn->amn_recovery = 1;
amn->amn_success = 0;
ni->ni_txrate++;
DPRINTF (sc, "increase rate to %d\n", ni->ni_txrate);
} else {
amn->amn_recovery = 0;
}
} else if (is_failure (amn)) {
amn->amn_success = 0;
if (!is_min_rate (ni)) {
if (amn->amn_recovery) {
/* recovery failure. */
amn->amn_success_threshold *= 2;
amn->amn_success_threshold = min (amn->amn_success_threshold,
(u_int)ath_rate_max_success_threshold);
DPRINTF (sc, "decrease rate recovery thr: %d\n", amn->amn_success_threshold);
} else {
/* simple failure. */
amn->amn_success_threshold = ath_rate_min_success_threshold;
DPRINTF (sc, "decrease rate normal thr: %d\n", amn->amn_success_threshold);
}
amn->amn_recovery = 0;
ni->ni_txrate--;
} else {
amn->amn_recovery = 0;
}
}
if (is_enough (amn) || old_rate != ni->ni_txrate) {
/* reset counters. */
amn->amn_tx_try0_cnt = 0;
amn->amn_tx_try1_cnt = 0;
amn->amn_tx_try2_cnt = 0;
amn->amn_tx_try3_cnt = 0;
amn->amn_tx_failure_cnt = 0;
}
if (old_rate != ni->ni_txrate) {
ath_rate_update(sc, ni, ni->ni_txrate);
}
}
static void
ath_ratectl(void *arg)
{
struct ifnet *ifp = arg;
struct ath_softc *sc = ifp->if_softc;
struct amrr_softc *asc = (struct amrr_softc *) sc->sc_rc;
struct ieee80211com *ic = &sc->sc_ic;
int interval;
if (ifp->if_flags & IFF_RUNNING) {
sc->sc_stats.ast_rate_calls++;
if (ic->ic_opmode == IEEE80211_M_STA)
ath_rate_ctl(sc, ic->ic_bss); /* NB: no reference */
else
ieee80211_iterate_nodes(&ic->ic_sta, ath_rate_ctl, sc);
}
interval = ath_rateinterval;
if (ic->ic_opmode == IEEE80211_M_STA)
interval /= 2;
callout_reset(&asc->timer, (interval * hz) / 1000,
ath_ratectl, &sc->sc_if);
}
static void
ath_rate_sysctlattach(struct ath_softc *sc)
{
struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
"rate_interval", CTLFLAG_RW, &ath_rateinterval, 0,
"rate control: operation interval (ms)");
/* XXX bounds check values */
SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
"max_sucess_threshold", CTLFLAG_RW,
&ath_rate_max_success_threshold, 0, "");
SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
"min_sucess_threshold", CTLFLAG_RW,
&ath_rate_min_success_threshold, 0, "");
}
struct ath_ratectrl *
ath_rate_attach(struct ath_softc *sc)
{
struct amrr_softc *asc;
asc = malloc(sizeof(struct amrr_softc), M_DEVBUF, M_NOWAIT|M_ZERO);
if (asc == NULL)
return NULL;
asc->arc.arc_space = sizeof(struct amrr_node);
callout_init(&asc->timer, debug_mpsafenet ? CALLOUT_MPSAFE : 0);
ath_rate_sysctlattach(sc);
return &asc->arc;
}
void
ath_rate_detach(struct ath_ratectrl *arc)
{
struct amrr_softc *asc = (struct amrr_softc *) arc;
callout_drain(&asc->timer);
free(asc, M_DEVBUF);
}
/*
* Module glue.
*/
static int
amrr_modevent(module_t mod, int type, void *unused)
{
switch (type) {
case MOD_LOAD:
if (bootverbose)
printf("ath_rate: <AMRR rate control algorithm> version 0.1\n");
return 0;
case MOD_UNLOAD:
return 0;
}
return EINVAL;
}
static moduledata_t amrr_mod = {
"ath_rate",
amrr_modevent,
0
};
DECLARE_MODULE(ath_rate, amrr_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
MODULE_VERSION(ath_rate, 1);
MODULE_DEPEND(ath_rate, wlan, 1, 1, 1);

77
sys/dev/ic/athrate-amrr.h Normal file
View File

@ -0,0 +1,77 @@
/*-
* Copyright (c) 2004 INRIA
* Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer,
without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
* redistribution must be conditioned upon including a substantially
* similar Disclaimer requirement for further binary redistribution.
* 3. Neither the names of the above-listed copyright holders nor the names
* of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGES.
*
* $FreeBSD: src/sys/dev/ath/ath_rate/amrr/amrr.h,v 1.2 2004/12/31 22:41:45 sam Exp $
*/
#ifndef _DEV_ATH_RATE_AMRR_H
#define _DEV_ATH_RATE_AMRR_H
/* per-device state */
struct amrr_softc {
struct ath_ratectrl arc; /* base state */
struct callout timer; /* periodic timer */
};
/* per-node state */
struct amrr_node {
/* AMRR statistics for this node */
u_int amn_tx_try0_cnt;
u_int amn_tx_try1_cnt;
u_int amn_tx_try2_cnt;
u_int amn_tx_try3_cnt;
u_int amn_tx_failure_cnt;
/* AMRR algorithm state for this node */
u_int amn_success_threshold;
u_int amn_success;
u_int amn_recovery;
/* rate index et al. */
u_int8_t amn_tx_rix0; /* series 0 rate index */
u_int8_t amn_tx_rate0; /* series 0 h/w rate */
u_int8_t amn_tx_rate1; /* series 1 h/w rate */
u_int8_t amn_tx_rate2; /* series 2 h/w rate */
u_int8_t amn_tx_rate3; /* series 3 h/w rate */
u_int8_t amn_tx_rate0sp; /* series 0 short preamble h/w rate */
u_int8_t amn_tx_rate1sp; /* series 1 short preamble h/w rate */
u_int8_t amn_tx_rate2sp; /* series 2 short preamble h/w rate */
u_int8_t amn_tx_rate3sp; /* series 3 short preamble h/w rate */
u_int8_t amn_tx_try0; /* series 0 try count */
u_int amn_tx_try1; /* series 1 try count */
u_int amn_tx_try2; /* series 2 try count */
u_int amn_tx_try3; /* series 3 try count */
};
#define ATH_NODE_AMRR(an) ((struct amrr_node *)&an[1])
#endif /* _DEV_ATH_RATE_AMRR_H */

528
sys/dev/ic/athrate-onoe.c Normal file
View File

@ -0,0 +1,528 @@
/*-
* Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
* redistribution must be conditioned upon including a substantially
* similar Disclaimer requirement for further binary redistribution.
* 3. Neither the names of the above-listed copyright holders nor the names
* of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGES.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/dev/ath/ath_rate/onoe/onoe.c,v 1.7 2005/04/02 18:54:30 sam Exp $");
/*
* Atsushi Onoe's rate control algorithm.
*/
#include "opt_inet.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/sysctl.h>
#include <sys/module.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/errno.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <sys/bus.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/if_media.h>
#include <net/if_arp.h>
#include <net/ethernet.h> /* XXX for ether_sprintf */
#include <net80211/ieee80211_var.h>
#include <net/bpf.h>
#ifdef INET
#include <netinet/in.h>
#include <netinet/if_ether.h>
#endif
#include <dev/ath/if_athvar.h>
#include <dev/ath/ath_rate/onoe/onoe.h>
#include <contrib/dev/ath/ah_desc.h>
#define ONOE_DEBUG
#ifdef ONOE_DEBUG
enum {
ATH_DEBUG_RATE = 0x00000010, /* rate control */
};
#define DPRINTF(sc, _fmt, ...) do { \
if (sc->sc_debug & ATH_DEBUG_RATE) \
printf(_fmt, __VA_ARGS__); \
} while (0)
#else
#define DPRINTF(sc, _fmt, ...)
#endif
/*
* Default parameters for the rate control algorithm. These are
* all tunable with sysctls. The rate controller runs periodically
* (each ath_rateinterval ms) analyzing transmit statistics for each
* neighbor/station (when operating in station mode this is only the AP).
* If transmits look to be working well over a sampling period then
* it gives a "raise rate credit". If transmits look to not be working
* well than it deducts a credit. If the credits cross a threshold then
* the transmit rate is raised. Various error conditions force the
* the transmit rate to be dropped.
*
* The decision to issue/deduct a credit is based on the errors and
* retries accumulated over the sampling period. ath_rate_raise defines
* the percent of retransmits for which a credit is issued/deducted.
* ath_rate_raise_threshold defines the threshold on credits at which
* the transmit rate is increased.
*
* XXX this algorithm is flawed.
*/
static int ath_rateinterval = 1000; /* rate ctl interval (ms) */
static int ath_rate_raise = 10; /* add credit threshold */
static int ath_rate_raise_threshold = 10; /* rate ctl raise threshold */
static void ath_ratectl(void *);
static void ath_rate_update(struct ath_softc *, struct ieee80211_node *,
int rate);
static void ath_rate_ctl_start(struct ath_softc *, struct ieee80211_node *);
static void ath_rate_ctl(void *, struct ieee80211_node *);
void
ath_rate_node_init(struct ath_softc *sc, struct ath_node *an)
{
/* NB: assumed to be zero'd by caller */
ath_rate_update(sc, &an->an_node, 0);
}
void
ath_rate_node_cleanup(struct ath_softc *sc, struct ath_node *an)
{
}
void
ath_rate_findrate(struct ath_softc *sc, struct ath_node *an,
int shortPreamble, size_t frameLen,
u_int8_t *rix, int *try0, u_int8_t *txrate)
{
struct onoe_node *on = ATH_NODE_ONOE(an);
*rix = on->on_tx_rix0;
*try0 = on->on_tx_try0;
if (shortPreamble)
*txrate = on->on_tx_rate0sp;
else
*txrate = on->on_tx_rate0;
}
void
ath_rate_setupxtxdesc(struct ath_softc *sc, struct ath_node *an,
struct ath_desc *ds, int shortPreamble, u_int8_t rix)
{
struct onoe_node *on = ATH_NODE_ONOE(an);
ath_hal_setupxtxdesc(sc->sc_ah, ds
, on->on_tx_rate1sp, 2 /* series 1 */
, on->on_tx_rate2sp, 2 /* series 2 */
, on->on_tx_rate3sp, 2 /* series 3 */
);
}
void
ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an,
const struct ath_desc *ds, const struct ath_desc *ds0)
{
struct onoe_node *on = ATH_NODE_ONOE(an);
if (ds->ds_txstat.ts_status == 0)
on->on_tx_ok++;
else
on->on_tx_err++;
on->on_tx_retr += ds->ds_txstat.ts_shortretry
+ ds->ds_txstat.ts_longretry;
}
void
ath_rate_newassoc(struct ath_softc *sc, struct ath_node *an, int isnew)
{
if (isnew)
ath_rate_ctl_start(sc, &an->an_node);
}
static void
ath_rate_update(struct ath_softc *sc, struct ieee80211_node *ni, int rate)
{
struct ath_node *an = ATH_NODE(ni);
struct onoe_node *on = ATH_NODE_ONOE(an);
const HAL_RATE_TABLE *rt = sc->sc_currates;
u_int8_t rix;
KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode));
DPRINTF(sc, "%s: set xmit rate for %s to %dM\n",
__func__, ether_sprintf(ni->ni_macaddr),
ni->ni_rates.rs_nrates > 0 ?
(ni->ni_rates.rs_rates[rate] & IEEE80211_RATE_VAL) / 2 : 0);
ni->ni_txrate = rate;
/* XXX management/control frames always go at the lowest speed */
an->an_tx_mgtrate = rt->info[0].rateCode;
an->an_tx_mgtratesp = an->an_tx_mgtrate | rt->info[0].shortPreamble;
/*
* Before associating a node has no rate set setup
* so we can't calculate any transmit codes to use.
* This is ok since we should never be sending anything
* but management frames and those always go at the
* lowest hardware rate.
*/
if (ni->ni_rates.rs_nrates == 0)
goto done;
on->on_tx_rix0 = sc->sc_rixmap[
ni->ni_rates.rs_rates[rate] & IEEE80211_RATE_VAL];
on->on_tx_rate0 = rt->info[on->on_tx_rix0].rateCode;
on->on_tx_rate0sp = on->on_tx_rate0 |
rt->info[on->on_tx_rix0].shortPreamble;
if (sc->sc_mrretry) {
/*
* Hardware supports multi-rate retry; setup two
* step-down retry rates and make the lowest rate
* be the ``last chance''. We use 4, 2, 2, 2 tries
* respectively (4 is set here, the rest are fixed
* in the xmit routine).
*/
on->on_tx_try0 = 1 + 3; /* 4 tries at rate 0 */
if (--rate >= 0) {
rix = sc->sc_rixmap[
ni->ni_rates.rs_rates[rate]&IEEE80211_RATE_VAL];
on->on_tx_rate1 = rt->info[rix].rateCode;
on->on_tx_rate1sp = on->on_tx_rate1 |
rt->info[rix].shortPreamble;
} else {
on->on_tx_rate1 = on->on_tx_rate1sp = 0;
}
if (--rate >= 0) {
rix = sc->sc_rixmap[
ni->ni_rates.rs_rates[rate]&IEEE80211_RATE_VAL];
on->on_tx_rate2 = rt->info[rix].rateCode;
on->on_tx_rate2sp = on->on_tx_rate2 |
rt->info[rix].shortPreamble;
} else {
on->on_tx_rate2 = on->on_tx_rate2sp = 0;
}
if (rate > 0) {
/* NB: only do this if we didn't already do it above */
on->on_tx_rate3 = rt->info[0].rateCode;
on->on_tx_rate3sp =
an->an_tx_mgtrate | rt->info[0].shortPreamble;
} else {
on->on_tx_rate3 = on->on_tx_rate3sp = 0;
}
} else {
on->on_tx_try0 = ATH_TXMAXTRY; /* max tries at rate 0 */
on->on_tx_rate1 = on->on_tx_rate1sp = 0;
on->on_tx_rate2 = on->on_tx_rate2sp = 0;
on->on_tx_rate3 = on->on_tx_rate3sp = 0;
}
done:
on->on_tx_ok = on->on_tx_err = on->on_tx_retr = on->on_tx_upper = 0;
}
/*
* Set the starting transmit rate for a node.
*/
static void
ath_rate_ctl_start(struct ath_softc *sc, struct ieee80211_node *ni)
{
#define RATE(_ix) (ni->ni_rates.rs_rates[(_ix)] & IEEE80211_RATE_VAL)
struct ieee80211com *ic = &sc->sc_ic;
int srate;
KASSERT(ni->ni_rates.rs_nrates > 0, ("no rates"));
if (ic->ic_fixed_rate == -1) {
/*
* No fixed rate is requested. For 11b start with
* the highest negotiated rate; otherwise, for 11g
* and 11a, we start "in the middle" at 24Mb or 36Mb.
*/
srate = ni->ni_rates.rs_nrates - 1;
if (sc->sc_curmode != IEEE80211_MODE_11B) {
/*
* Scan the negotiated rate set to find the
* closest rate.
*/
/* NB: the rate set is assumed sorted */
for (; srate >= 0 && RATE(srate) > 72; srate--)
;
KASSERT(srate >= 0, ("bogus rate set"));
}
} else {
/*
* A fixed rate is to be used; ic_fixed_rate is an
* index into the supported rate set. Convert this
* to the index into the negotiated rate set for
* the node. We know the rate is there because the
* rate set is checked when the station associates.
*/
const struct ieee80211_rateset *rs =
&ic->ic_sup_rates[ic->ic_curmode];
int r = rs->rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL;
/* NB: the rate set is assumed sorted */
srate = ni->ni_rates.rs_nrates - 1;
for (; srate >= 0 && RATE(srate) != r; srate--)
;
KASSERT(srate >= 0,
("fixed rate %d not in rate set", ic->ic_fixed_rate));
}
ath_rate_update(sc, ni, srate);
#undef RATE
}
static void
ath_rate_cb(void *arg, struct ieee80211_node *ni)
{
struct ath_softc *sc = arg;
ath_rate_update(sc, ni, 0);
}
/*
* Reset the rate control state for each 802.11 state transition.
*/
void
ath_rate_newstate(struct ath_softc *sc, enum ieee80211_state state)
{
struct onoe_softc *osc = (struct onoe_softc *) sc->sc_rc;
struct ieee80211com *ic = &sc->sc_ic;
struct ieee80211_node *ni;
if (state == IEEE80211_S_INIT) {
callout_stop(&osc->timer);
return;
}
if (ic->ic_opmode == IEEE80211_M_STA) {
/*
* Reset local xmit state; this is really only
* meaningful when operating in station mode.
*/
ni = ic->ic_bss;
if (state == IEEE80211_S_RUN) {
ath_rate_ctl_start(sc, ni);
} else {
ath_rate_update(sc, ni, 0);
}
} else {
/*
* When operating as a station the node table holds
* the AP's that were discovered during scanning.
* For any other operating mode we want to reset the
* tx rate state of each node.
*/
ieee80211_iterate_nodes(&ic->ic_sta, ath_rate_cb, sc);
ath_rate_update(sc, ic->ic_bss, 0);
}
if (ic->ic_fixed_rate == -1 && state == IEEE80211_S_RUN) {
int interval;
/*
* Start the background rate control thread if we
* are not configured to use a fixed xmit rate.
*/
interval = ath_rateinterval;
if (ic->ic_opmode == IEEE80211_M_STA)
interval /= 2;
callout_reset(&osc->timer, (interval * hz) / 1000,
ath_ratectl, &sc->sc_if);
}
}
/*
* Examine and potentially adjust the transmit rate.
*/
static void
ath_rate_ctl(void *arg, struct ieee80211_node *ni)
{
struct ath_softc *sc = arg;
struct onoe_node *on = ATH_NODE_ONOE(ATH_NODE(ni));
struct ieee80211_rateset *rs = &ni->ni_rates;
int dir = 0, nrate, enough;
/*
* Rate control
* XXX: very primitive version.
*/
enough = (on->on_tx_ok + on->on_tx_err >= 10);
/* no packet reached -> down */
if (on->on_tx_err > 0 && on->on_tx_ok == 0)
dir = -1;
/* all packets needs retry in average -> down */
if (enough && on->on_tx_ok < on->on_tx_retr)
dir = -1;
/* no error and less than rate_raise% of packets need retry -> up */
if (enough && on->on_tx_err == 0 &&
on->on_tx_retr < (on->on_tx_ok * ath_rate_raise) / 100)
dir = 1;
DPRINTF(sc, "%s: ok %d err %d retr %d upper %d dir %d\n",
ether_sprintf(ni->ni_macaddr),
on->on_tx_ok, on->on_tx_err, on->on_tx_retr,
on->on_tx_upper, dir);
nrate = ni->ni_txrate;
switch (dir) {
case 0:
if (enough && on->on_tx_upper > 0)
on->on_tx_upper--;
break;
case -1:
if (nrate > 0) {
nrate--;
sc->sc_stats.ast_rate_drop++;
}
on->on_tx_upper = 0;
break;
case 1:
/* raise rate if we hit rate_raise_threshold */
if (++on->on_tx_upper < ath_rate_raise_threshold)
break;
on->on_tx_upper = 0;
if (nrate + 1 < rs->rs_nrates) {
nrate++;
sc->sc_stats.ast_rate_raise++;
}
break;
}
if (nrate != ni->ni_txrate) {
DPRINTF(sc, "%s: %dM -> %dM (%d ok, %d err, %d retr)\n",
__func__,
(rs->rs_rates[ni->ni_txrate] & IEEE80211_RATE_VAL) / 2,
(rs->rs_rates[nrate] & IEEE80211_RATE_VAL) / 2,
on->on_tx_ok, on->on_tx_err, on->on_tx_retr);
ath_rate_update(sc, ni, nrate);
} else if (enough)
on->on_tx_ok = on->on_tx_err = on->on_tx_retr = 0;
}
static void
ath_ratectl(void *arg)
{
struct ifnet *ifp = arg;
struct ath_softc *sc = ifp->if_softc;
struct onoe_softc *osc = (struct onoe_softc *) sc->sc_rc;
struct ieee80211com *ic = &sc->sc_ic;
int interval;
if (ifp->if_flags & IFF_RUNNING) {
sc->sc_stats.ast_rate_calls++;
if (ic->ic_opmode == IEEE80211_M_STA)
ath_rate_ctl(sc, ic->ic_bss); /* NB: no reference */
else
ieee80211_iterate_nodes(&ic->ic_sta, ath_rate_ctl, sc);
}
interval = ath_rateinterval;
if (ic->ic_opmode == IEEE80211_M_STA)
interval /= 2;
callout_reset(&osc->timer, (interval * hz) / 1000,
ath_ratectl, &sc->sc_if);
}
static void
ath_rate_sysctlattach(struct ath_softc *sc)
{
struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
"rate_interval", CTLFLAG_RW, &ath_rateinterval, 0,
"rate control: operation interval (ms)");
/* XXX bounds check values */
SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
"rate_raise", CTLFLAG_RW, &ath_rate_raise, 0,
"rate control: retry threshold to credit rate raise (%%)");
SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
"rate_raise_threshold", CTLFLAG_RW, &ath_rate_raise_threshold,0,
"rate control: # good periods before raising rate");
}
struct ath_ratectrl *
ath_rate_attach(struct ath_softc *sc)
{
struct onoe_softc *osc;
osc = malloc(sizeof(struct onoe_softc), M_DEVBUF, M_NOWAIT|M_ZERO);
if (osc == NULL)
return NULL;
osc->arc.arc_space = sizeof(struct onoe_node);
callout_init(&osc->timer, debug_mpsafenet ? CALLOUT_MPSAFE : 0);
ath_rate_sysctlattach(sc);
return &osc->arc;
}
void
ath_rate_detach(struct ath_ratectrl *arc)
{
struct onoe_softc *osc = (struct onoe_softc *) arc;
callout_drain(&osc->timer);
free(osc, M_DEVBUF);
}
/*
* Module glue.
*/
static int
onoe_modevent(module_t mod, int type, void *unused)
{
switch (type) {
case MOD_LOAD:
if (bootverbose)
printf("ath_rate: <Atsushi Onoe's rate control algorithm>\n");
return 0;
case MOD_UNLOAD:
return 0;
}
return EINVAL;
}
static moduledata_t onoe_mod = {
"ath_rate",
onoe_modevent,
0
};
DECLARE_MODULE(ath_rate, onoe_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
MODULE_VERSION(ath_rate, 1);
MODULE_DEPEND(ath_rate, wlan, 1, 1, 1);

69
sys/dev/ic/athrate-onoe.h Normal file
View File

@ -0,0 +1,69 @@
/*-
* Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer,
without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
* redistribution must be conditioned upon including a substantially
* similar Disclaimer requirement for further binary redistribution.
* 3. Neither the names of the above-listed copyright holders nor the names
* of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGES.
*
* $FreeBSD: src/sys/dev/ath/ath_rate/onoe/onoe.h,v 1.2 2004/12/31 22:41:45 sam Exp $
*/
/*
* Defintions for the Atheros Wireless LAN controller driver.
*/
#ifndef _DEV_ATH_RATE_ONOE_H
#define _DEV_ATH_RATE_ONOE_H
/* per-device state */
struct onoe_softc {
struct ath_ratectrl arc; /* base state */
struct callout timer; /* periodic timer */
};
/* per-node state */
struct onoe_node {
u_int on_tx_ok; /* tx ok pkt */
u_int on_tx_err; /* tx !ok pkt */
u_int on_tx_retr; /* tx retry count */
int on_tx_upper; /* tx upper rate req cnt */
u_int8_t on_tx_rix0; /* series 0 rate index */
u_int8_t on_tx_try0; /* series 0 try count */
u_int8_t on_tx_rate0; /* series 0 h/w rate */
u_int8_t on_tx_rate1; /* series 1 h/w rate */
u_int8_t on_tx_rate2; /* series 2 h/w rate */
u_int8_t on_tx_rate3; /* series 3 h/w rate */
u_int8_t on_tx_rate0sp; /* series 0 short preamble h/w rate */
u_int8_t on_tx_rate1sp; /* series 1 short preamble h/w rate */
u_int8_t on_tx_rate2sp; /* series 2 short preamble h/w rate */
u_int8_t on_tx_rate3sp; /* series 3 short preamble h/w rate */
};
#define ATH_NODE_ONOE(an) ((struct onoe_node *)&an[1])
#endif /* _DEV_ATH_RATE_ONOE_H */

843
sys/dev/ic/athrate-sample.c Normal file
View File

@ -0,0 +1,843 @@
/*-
* Copyright (c) 2005 John Bicket
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
* redistribution must be conditioned upon including a substantially
* similar Disclaimer requirement for further binary redistribution.
* 3. Neither the names of the above-listed copyright holders nor the names
* of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGES.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/dev/ath/ath_rate/sample/sample.c,v 1.8 2005/04/02 18:56:50 sam Exp $");
/*
* John Bicket's SampleRate control algorithm.
*/
#include "opt_inet.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/sysctl.h>
#include <sys/module.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/errno.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <sys/bus.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/if_media.h>
#include <net/if_arp.h>
#include <net/ethernet.h> /* XXX for ether_sprintf */
#include <net80211/ieee80211_var.h>
#include <net/bpf.h>
#ifdef INET
#include <netinet/in.h>
#include <netinet/if_ether.h>
#endif
#include <dev/ath/if_athvar.h>
#include <dev/ath/ath_rate/sample/sample.h>
#include <contrib/dev/ath/ah_desc.h>
#define SAMPLE_DEBUG
#ifdef SAMPLE_DEBUG
enum {
ATH_DEBUG_RATE = 0x00000010, /* rate control */
};
#define DPRINTF(sc, _fmt, ...) do { \
if (sc->sc_debug & ATH_DEBUG_RATE) \
printf(_fmt, __VA_ARGS__); \
} while (0)
#else
#define DPRINTF(sc, _fmt, ...)
#endif
/*
* This file is an implementation of the SampleRate algorithm
* in "Bit-rate Selection in Wireless Networks"
* (http://www.pdos.lcs.mit.edu/papers/jbicket-ms.ps)
*
* SampleRate chooses the bit-rate it predicts will provide the most
* throughput based on estimates of the expected per-packet
* transmission time for each bit-rate. SampleRate periodically sends
* packets at bit-rates other than the current one to estimate when
* another bit-rate will provide better performance. SampleRate
* switches to another bit-rate when its estimated per-packet
* transmission time becomes smaller than the current bit-rate's.
* SampleRate reduces the number of bit-rates it must sample by
* eliminating those that could not perform better than the one
* currently being used. SampleRate also stops probing at a bit-rate
* if it experiences several successive losses.
*
* The difference between the algorithm in the thesis and the one in this
* file is that the one in this file uses a ewma instead of a window.
*
*/
#define STALE_FAILURE_TIMEOUT_MS 10000
static void ath_rate_ctl_reset(struct ath_softc *, struct ieee80211_node *);
static __inline int size_to_bin(int size)
{
int x = 0;
for (x = 0; x < NUM_PACKET_SIZE_BINS; x++) {
if (size <= packet_size_bins[x]) {
return x;
}
}
return NUM_PACKET_SIZE_BINS-1;
}
static __inline int bin_to_size(int index) {
return packet_size_bins[index];
}
static __inline int rate_to_ndx(struct sample_node *sn, int rate) {
int x = 0;
for (x = 0; x < sn->num_rates; x++) {
if (sn->rates[x].rate == rate) {
return x;
}
}
return -1;
}
/*
* Setup rate codes for management/control frames. We force
* all such frames to the lowest rate.
*/
static void
ath_rate_setmgtrates(struct ath_softc *sc, struct ath_node *an)
{
const HAL_RATE_TABLE *rt = sc->sc_currates;
/* setup rates for management frames */
/* XXX management/control frames always go at lowest speed */
an->an_tx_mgtrate = rt->info[0].rateCode;
an->an_tx_mgtratesp = an->an_tx_mgtrate
| rt->info[0].shortPreamble;
}
void
ath_rate_node_init(struct ath_softc *sc, struct ath_node *an)
{
DPRINTF(sc, "%s:\n", __func__);
/* NB: assumed to be zero'd by caller */
ath_rate_setmgtrates(sc, an);
}
void
ath_rate_node_cleanup(struct ath_softc *sc, struct ath_node *an)
{
DPRINTF(sc, "%s:\n", __func__);
}
/*
* returns the ndx with the lowest average_tx_time,
* or -1 if all the average_tx_times are 0.
*/
static __inline int best_rate_ndx(struct sample_node *sn, int size_bin,
int require_acked_before)
{
int x = 0;
int best_rate_ndx = 0;
int best_rate_tt = 0;
for (x = 0; x < sn->num_rates; x++) {
int tt = sn->stats[size_bin][x].average_tx_time;
if (tt <= 0 || (require_acked_before &&
!sn->stats[size_bin][x].packets_acked)) {
continue;
}
if (!best_rate_tt || best_rate_tt > tt) {
best_rate_tt = tt;
best_rate_ndx = x;
}
}
return (best_rate_tt) ? best_rate_ndx : -1;
}
/*
* pick a ndx s.t. the perfect_tx_time
* is less than the best bit-rate's average_tx_time
* and the ndx has not had four successive failures.
*/
static __inline int pick_sample_ndx(struct sample_node *sn, int size_bin)
{
int x = 0;
int current_ndx = 0;
unsigned current_tt = 0;
current_ndx = sn->current_rate[size_bin];
if (current_ndx < 0) {
/* no successes yet, send at the lowest bit-rate */
return 0;
}
current_tt = sn->stats[size_bin][current_ndx].average_tx_time;
for (x = 0; x < sn->num_rates; x++) {
int ndx = (sn->last_sample_ndx[size_bin] + 1 + x) % sn->num_rates;
/*
* clear any stale stuff out.
*/
if (ticks - sn->stats[size_bin][ndx].last_tx > ((hz * STALE_FAILURE_TIMEOUT_MS)/1000)) {
sn->stats[size_bin][ndx].average_tx_time = sn->stats[size_bin][ndx].perfect_tx_time;
sn->stats[size_bin][ndx].successive_failures = 0;
sn->stats[size_bin][ndx].tries = 0;
sn->stats[size_bin][ndx].total_packets = 0;
sn->stats[size_bin][ndx].packets_acked = 0;
}
if (ndx != current_ndx &&
sn->stats[size_bin][ndx].perfect_tx_time < current_tt &&
sn->stats[size_bin][ndx].successive_failures < 4) {
sn->last_sample_ndx[size_bin] = ndx;
return ndx;
}
}
return current_ndx;
}
void
ath_rate_findrate(struct ath_softc *sc, struct ath_node *an,
int shortPreamble, size_t frameLen,
u_int8_t *rix, int *try0, u_int8_t *txrate)
{
struct sample_node *sn = ATH_NODE_SAMPLE(an);
struct sample_softc *ssc = ATH_SOFTC_SAMPLE(sc);
struct ieee80211com *ic = &sc->sc_ic;
int ndx, size_bin, mrr, best_ndx;
unsigned average_tx_time;
mrr = sc->sc_mrretry && !(ic->ic_flags & IEEE80211_F_USEPROT) &&
!(frameLen > ic->ic_rtsthreshold);
size_bin = size_to_bin(frameLen);
best_ndx = best_rate_ndx(sn, size_bin, !mrr);
if (best_ndx >= 0) {
average_tx_time = sn->stats[size_bin][best_ndx].average_tx_time;
} else {
average_tx_time = 0;
}
if (sn->static_rate_ndx != -1) {
ndx = sn->static_rate_ndx;
*try0 = ATH_TXMAXTRY;
} else {
ndx = 0;
*try0 = mrr ? 2 : ATH_TXMAXTRY;
DPRINTF(sc, "%s: %s size %d mrr %d packets_sent %d best_ndx %d "
"sample tt %d packets since %d\n"
, __func__, ether_sprintf(an->an_node.ni_macaddr)
, packet_size_bins[size_bin]
, mrr
, sn->packets_sent[size_bin]
, best_ndx
, sn->sample_tt[size_bin]
, sn->packets_since_sample[size_bin]
);
if (!sn->packets_sent[size_bin]) {
/* no packets sent */
if (best_ndx == -1) {
ndx = sn->num_rates - 1;
if (sc->sc_curmode != IEEE80211_MODE_11B) {
for (; ndx >= 0 && sn->rates[ndx].rate > 72; ndx--)
;
}
} else {
ndx = best_ndx;
}
} else if (best_ndx == -1) {
/* no packet has succeeded yet */
if (mrr) {
/*
* no packet has succeeded, try the
* highest bitrate that hasn't failed
*/
for (ndx = sn->num_rates-1; ndx >= 0; ndx--) {
if (sn->stats[size_bin][ndx].successive_failures == 0) {
break;
}
}
} else {
ndx = sn->num_rates - 1;
if (sc->sc_curmode != IEEE80211_MODE_11B) {
for (; ndx >= 0 && sn->rates[ndx].rate > 72; ndx--)
;
}
}
} else if (sn->sample_tt[size_bin] < (sn->packets_since_sample[size_bin]*ssc->ath_sample_rate/100) * average_tx_time &&
sn->packets_since_sample[size_bin] > 15) {
/*
* we want to limit the time measuring the performance
* of other bit-rates to ath_sample_rate% of the
* total transmission time.
*/
ndx = pick_sample_ndx(sn, size_bin);
if (ndx != sn->current_rate[size_bin]) {
DPRINTF(sc, "%s: %s size %d last sample tt %d sampling %d packets since %d\n",
__func__,
ether_sprintf(an->an_node.ni_macaddr),
packet_size_bins[size_bin],
sn->sample_tt[size_bin],
sn->rates[ndx].rate,
sn->packets_since_sample[size_bin]);
sn->current_sample_ndx[size_bin] = ndx;
} else {
sn->current_sample_ndx[size_bin] = -1;
}
sn->packets_since_sample[size_bin] = 0;
} else {
sn->packets_since_sample[size_bin]++;
/*
* don't switch bit-rates every packet. only
* switch during the first few packets we send
* or after 100 packets, or if the current
* bit-rate begins to perform twice as bad as
* another one.
*/
if (sn->packets_sent[size_bin] < 20 ||
ticks - ((hz*2000)/1000) > sn->jiffies_since_switch[size_bin] ||
average_tx_time * 2 < sn->stats[size_bin][sn->current_rate[size_bin]].average_tx_time ) {
if (sn->packets_sent[size_bin] > 20) {
DPRINTF(sc, "%s: %s size %d switch rate %d (%d/%d) -> %d (%d/%d) after %d packets mmr %d\n",
__func__,
ether_sprintf(an->an_node.ni_macaddr),
packet_size_bins[size_bin],
sn->rates[sn->current_rate[size_bin]].rate,
sn->stats[size_bin][sn->current_rate[size_bin]].average_tx_time,
sn->stats[size_bin][sn->current_rate[size_bin]].perfect_tx_time,
sn->rates[best_ndx].rate,
sn->stats[size_bin][best_ndx].average_tx_time,
sn->stats[size_bin][best_ndx].perfect_tx_time,
sn->packets_since_switch[size_bin],
mrr);
}
sn->packets_since_switch[size_bin] = 0;
sn->current_rate[size_bin] = best_ndx;
sn->jiffies_since_switch[size_bin] = ticks;
}
ndx = sn->current_rate[size_bin];
sn->packets_since_switch[size_bin]++;
}
}
if (ndx < 0) {
ndx = 0;
}
*rix = sn->rates[ndx].rix;
if (shortPreamble) {
*txrate = sn->rates[ndx].shortPreambleRateCode;
} else {
*txrate = sn->rates[ndx].rateCode;
}
sn->packets_sent[size_bin]++;
an->an_node.ni_txrate = ndx;
}
void
ath_rate_setupxtxdesc(struct ath_softc *sc, struct ath_node *an,
struct ath_desc *ds, int shortPreamble, u_int8_t rix)
{
struct sample_node *sn = ATH_NODE_SAMPLE(an);
int rateCode = -1;
int frame_size, size_bin, best_ndx, ndx;
frame_size = ds->ds_ctl0 & 0x0fff; /* low-order 12 bits of ds_ctl0 */
KASSERT(frame_size != 0, ("no frame size"));
size_bin = size_to_bin(frame_size);
best_ndx = best_rate_ndx(sn, size_bin, 0);
if (best_ndx == -1 || !sn->stats[size_bin][best_ndx].packets_acked) {
/*
* no packet has succeeded, so also try at the
* lowest bitate.
*/
ndx = 0;
} else {
/*
* we're trying a different bit-rate, and it could be lossy,
* so if it fails try at the best bit-rate.
*/
ndx = best_ndx;
}
KASSERT(0 <= ndx && ndx < IEEE80211_RATE_MAXSIZE,
("invalid ndx %d", ndx));
if (shortPreamble) {
rateCode = sn->rates[ndx].shortPreambleRateCode;
} else {
rateCode = sn->rates[ndx].rateCode;
}
ath_hal_setupxtxdesc(sc->sc_ah, ds
, rateCode, 3 /* series 1 */
, sn->rates[0].rateCode, 3 /* series 2 */
, 0, 0 /* series 3 */
);
}
static void
update_stats(struct ath_softc *sc, struct ath_node *an,
int frame_size,
int ndx0, int tries0,
int ndx1, int tries1,
int ndx2, int tries2,
int ndx3, int tries3,
int short_tries, int tries, int status)
{
struct sample_node *sn = ATH_NODE_SAMPLE(an);
struct sample_softc *ssc = ATH_SOFTC_SAMPLE(sc);
int tt = 0;
int tries_so_far = 0;
int size_bin = 0;
int size = 0;
int rate = 0;
size_bin = size_to_bin(frame_size);
size = bin_to_size(size_bin);
rate = sn->rates[ndx0].rate;
tt += calc_usecs_unicast_packet(sc, size, sn->rates[ndx0].rix,
short_tries-1,
MIN(tries0, tries) - 1);
tries_so_far += tries0;
if (tries1 && tries0 < tries) {
tt += calc_usecs_unicast_packet(sc, size, sn->rates[ndx1].rix,
short_tries-1,
MIN(tries1 + tries_so_far, tries) - tries_so_far - 1);
}
tries_so_far += tries1;
if (tries2 && tries0 + tries1 < tries) {
tt += calc_usecs_unicast_packet(sc, size, sn->rates[ndx2].rix,
short_tries-1,
MIN(tries2 + tries_so_far, tries) - tries_so_far - 1);
}
tries_so_far += tries2;
if (tries3 && tries0 + tries1 + tries2 < tries) {
tt += calc_usecs_unicast_packet(sc, size, sn->rates[ndx3].rix,
short_tries-1,
MIN(tries3 + tries_so_far, tries) - tries_so_far - 1);
}
#ifdef SAMPLE_DEBUG
if (short_tries + tries > 3 || status) {
DPRINTF(sc, "%s: %s size %d rate %d ndx %d tries (%d/%d) tries0 %d tt %d avg_tt %d perfect_tt %d status %d\n",
__func__, ether_sprintf(an->an_node.ni_macaddr),
size,
rate, ndx0, short_tries, tries, tries0, tt,
sn->stats[size_bin][ndx0].average_tx_time,
sn->stats[size_bin][ndx0].perfect_tx_time,
status);
}
#endif /* SAMPLE_DEBUG */
if (sn->stats[size_bin][ndx0].total_packets < (100 / (100 - ssc->ath_smoothing_rate))) {
/* just average the first few packets */
int avg_tx = sn->stats[size_bin][ndx0].average_tx_time;
int packets = sn->stats[size_bin][ndx0].total_packets;
sn->stats[size_bin][ndx0].average_tx_time = (tt+(avg_tx*packets))/(packets+1);
} else {
/* use a ewma */
sn->stats[size_bin][ndx0].average_tx_time =
((sn->stats[size_bin][ndx0].average_tx_time * ssc->ath_smoothing_rate) +
(tt * (100 - ssc->ath_smoothing_rate))) / 100;
}
if (status) {
/*
* this packet failed - count this as a failure
* for larger packets also, since we assume
* if a small packet fails at a lower bit-rate
* then a larger one will also.
*/
int y;
for (y = size_bin; y < NUM_PACKET_SIZE_BINS; y++) {
sn->stats[y][ndx0].successive_failures++;
sn->stats[y][ndx0].last_tx = ticks;
}
} else {
sn->stats[size_bin][ndx0].packets_acked++;
sn->stats[size_bin][ndx0].successive_failures = 0;
}
sn->stats[size_bin][ndx0].tries += tries;
sn->stats[size_bin][ndx0].last_tx = ticks;
sn->stats[size_bin][ndx0].total_packets++;
if (ndx0 == sn->current_sample_ndx[size_bin]) {
DPRINTF(sc, "%s: %s size %d sample rate %d tries (%d/%d) tt %d avg_tt (%d/%d) status %d\n",
__func__, ether_sprintf(an->an_node.ni_macaddr),
size, rate, short_tries, tries, tt,
sn->stats[size_bin][ndx0].average_tx_time,
sn->stats[size_bin][ndx0].perfect_tx_time,
status);
sn->sample_tt[size_bin] = tt;
sn->current_sample_ndx[size_bin] = -1;
}
}
void
ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an,
const struct ath_desc *ds, const struct ath_desc *ds0)
{
struct sample_node *sn = ATH_NODE_SAMPLE(an);
const struct ar5212_desc *ads = (const struct ar5212_desc *)&ds->ds_ctl0;
int final_rate, short_tries, long_tries, frame_size;
int ndx = -1;
final_rate = sc->sc_hwmap[ds->ds_txstat.ts_rate &~ HAL_TXSTAT_ALTRATE].ieeerate;
short_tries = ds->ds_txstat.ts_shortretry + 1;
long_tries = ds->ds_txstat.ts_longretry + 1;
frame_size = ds0->ds_ctl0 & 0x0fff; /* low-order 12 bits of ds_ctl0 */
if (frame_size == 0) /* NB: should not happen */
frame_size = 1500;
if (sn->num_rates <= 0) {
DPRINTF(sc, "%s: %s size %d status %d rate/try %d/%d "
"no rates yet\n",
__func__, ether_sprintf(an->an_node.ni_macaddr),
bin_to_size(size_to_bin(frame_size)),
ds->ds_txstat.ts_status,
short_tries, long_tries);
return;
}
if (sc->sc_mrretry && ds->ds_txstat.ts_status) {
/* this packet failed */
DPRINTF(sc, "%s: %s size %d rate/try %d/%d %d/%d %d/%d %d/%d status %s retries (%d/%d)\n",
__func__,
ether_sprintf(an->an_node.ni_macaddr),
bin_to_size(size_to_bin(frame_size)),
sc->sc_hwmap[ads->xmit_rate0].ieeerate,
ads->xmit_tries0,
sc->sc_hwmap[ads->xmit_rate1].ieeerate,
ads->xmit_tries1,
sc->sc_hwmap[ads->xmit_rate2].ieeerate,
ads->xmit_tries2,
sc->sc_hwmap[ads->xmit_rate3].ieeerate,
ads->xmit_tries3,
ds->ds_txstat.ts_status ? "FAIL" : "OK",
short_tries,
long_tries);
}
if (!(ds->ds_txstat.ts_rate & HAL_TXSTAT_ALTRATE)) {
/* only one rate was used */
ndx = rate_to_ndx(sn, final_rate);
DPRINTF(sc, "%s: %s size %d status %d rate/try %d/%d/%d\n",
__func__, ether_sprintf(an->an_node.ni_macaddr),
bin_to_size(size_to_bin(frame_size)),
ds->ds_txstat.ts_status,
ndx, short_tries, long_tries);
if (ndx >= 0 && ndx < sn->num_rates) {
update_stats(sc, an, frame_size,
ndx, long_tries,
0, 0,
0, 0,
0, 0,
short_tries, long_tries, ds->ds_txstat.ts_status);
}
} else {
int rate0, tries0, ndx0;
int rate1, tries1, ndx1;
int rate2, tries2, ndx2;
int rate3, tries3, ndx3;
int finalTSIdx = ads->final_ts_index;
/*
* Process intermediate rates that failed.
*/
rate0 = sc->sc_hwmap[ads->xmit_rate0].ieeerate;
tries0 = ads->xmit_tries0;
ndx0 = rate_to_ndx(sn, rate0);
rate1 = sc->sc_hwmap[ads->xmit_rate1].ieeerate;
tries1 = ads->xmit_tries1;
ndx1 = rate_to_ndx(sn, rate1);
rate2 = sc->sc_hwmap[ads->xmit_rate2].ieeerate;
tries2 = ads->xmit_tries2;
ndx2 = rate_to_ndx(sn, rate2);
rate3 = sc->sc_hwmap[ads->xmit_rate3].ieeerate;
tries3 = ads->xmit_tries3;
ndx3 = rate_to_ndx(sn, rate3);
#if 1
DPRINTF(sc, "%s: %s size %d finaltsidx %d tries %d status %d rate/try %d/%d %d/%d %d/%d %d/%d\n",
__func__, ether_sprintf(an->an_node.ni_macaddr),
bin_to_size(size_to_bin(frame_size)),
finalTSIdx,
long_tries,
ds->ds_txstat.ts_status,
rate0, tries0,
rate1, tries1,
rate2, tries2,
rate3, tries3);
#endif
if (tries0) {
update_stats(sc, an, frame_size,
ndx0, tries0,
ndx1, tries1,
ndx2, tries2,
ndx3, tries3,
short_tries, ds->ds_txstat.ts_longretry + 1,
ds->ds_txstat.ts_status);
}
if (tries1 && finalTSIdx > 0) {
update_stats(sc, an, frame_size,
ndx1, tries1,
ndx2, tries2,
ndx3, tries3,
0, 0,
short_tries, ds->ds_txstat.ts_longretry + 1 - tries0,
ds->ds_txstat.ts_status);
}
if (tries2 && finalTSIdx > 1) {
update_stats(sc, an, frame_size,
ndx2, tries2,
ndx3, tries3,
0, 0,
0, 0,
short_tries, ds->ds_txstat.ts_longretry + 1 - tries0 - tries1,
ds->ds_txstat.ts_status);
}
if (tries3 && finalTSIdx > 2) {
update_stats(sc, an, frame_size,
ndx3, tries3,
0, 0,
0, 0,
0, 0,
short_tries, ds->ds_txstat.ts_longretry + 1 - tries0 - tries1 - tries2,
ds->ds_txstat.ts_status);
}
}
}
void
ath_rate_newassoc(struct ath_softc *sc, struct ath_node *an, int isnew)
{
DPRINTF(sc, "%s: %s isnew %d\n", __func__,
ether_sprintf(an->an_node.ni_macaddr), isnew);
if (isnew)
ath_rate_ctl_reset(sc, &an->an_node);
}
/*
* Initialize the tables for a node.
*/
static void
ath_rate_ctl_reset(struct ath_softc *sc, struct ieee80211_node *ni)
{
#define RATE(_ix) (ni->ni_rates.rs_rates[(_ix)] & IEEE80211_RATE_VAL)
struct ieee80211com *ic = &sc->sc_ic;
struct ath_node *an = ATH_NODE(ni);
struct sample_node *sn = ATH_NODE_SAMPLE(an);
const HAL_RATE_TABLE *rt = sc->sc_currates;
int x, y, srate;
KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode));
sn->static_rate_ndx = -1;
if (ic->ic_fixed_rate != -1) {
/*
* A fixed rate is to be used; ic_fixed_rate is an
* index into the supported rate set. Convert this
* to the index into the negotiated rate set for
* the node. We know the rate is there because the
* rate set is checked when the station associates.
*/
const struct ieee80211_rateset *rs =
&ic->ic_sup_rates[ic->ic_curmode];
int r = rs->rs_rates[ic->ic_fixed_rate] & IEEE80211_RATE_VAL;
/* NB: the rate set is assumed sorted */
srate = ni->ni_rates.rs_nrates - 1;
for (; srate >= 0 && RATE(srate) != r; srate--)
;
KASSERT(srate >= 0,
("fixed rate %d not in rate set", ic->ic_fixed_rate));
sn->static_rate_ndx = srate;
}
DPRINTF(sc, "%s: %s size 1600 rate/tt", __func__, ether_sprintf(ni->ni_macaddr));
sn->num_rates = ni->ni_rates.rs_nrates;
for (x = 0; x < ni->ni_rates.rs_nrates; x++) {
sn->rates[x].rate = ni->ni_rates.rs_rates[x] & IEEE80211_RATE_VAL;
sn->rates[x].rix = sc->sc_rixmap[sn->rates[x].rate];
sn->rates[x].rateCode = rt->info[sn->rates[x].rix].rateCode;
sn->rates[x].shortPreambleRateCode =
rt->info[sn->rates[x].rix].rateCode |
rt->info[sn->rates[x].rix].shortPreamble;
DPRINTF(sc, " %d/%d", sn->rates[x].rate,
calc_usecs_unicast_packet(sc, 1600, sn->rates[x].rix,
0,0));
}
DPRINTF(sc, "%s\n", "");
/* set the visible bit-rate to the lowest one available */
ni->ni_txrate = 0;
sn->num_rates = ni->ni_rates.rs_nrates;
for (y = 0; y < NUM_PACKET_SIZE_BINS; y++) {
int size = bin_to_size(y);
sn->packets_sent[y] = 0;
sn->current_sample_ndx[y] = -1;
sn->last_sample_ndx[y] = 0;
for (x = 0; x < ni->ni_rates.rs_nrates; x++) {
sn->stats[y][x].successive_failures = 0;
sn->stats[y][x].tries = 0;
sn->stats[y][x].total_packets = 0;
sn->stats[y][x].packets_acked = 0;
sn->stats[y][x].last_tx = 0;
sn->stats[y][x].perfect_tx_time =
calc_usecs_unicast_packet(sc, size,
sn->rates[x].rix,
0, 0);
sn->stats[y][x].average_tx_time = sn->stats[y][x].perfect_tx_time;
}
}
#undef RATE
}
static void
rate_cb(void *arg, struct ieee80211_node *ni)
{
struct ath_softc *sc = arg;
ath_rate_newassoc(sc, ATH_NODE(ni), 1);
}
/*
* Reset the rate control state for each 802.11 state transition.
*/
void
ath_rate_newstate(struct ath_softc *sc, enum ieee80211_state state)
{
struct ieee80211com *ic = &sc->sc_ic;
if (state == IEEE80211_S_RUN) {
if (ic->ic_opmode != IEEE80211_M_STA) {
/*
* Sync rates for associated stations and neighbors.
*/
ieee80211_iterate_nodes(&ic->ic_sta, rate_cb, sc);
}
ath_rate_newassoc(sc, ATH_NODE(ic->ic_bss), 1);
}
}
static void
ath_rate_sysctlattach(struct ath_softc *sc, struct sample_softc *osc)
{
struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev);
struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev);
/* XXX bounds check [0..100] */
SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
"smoothing_rate", CTLFLAG_RW, &osc->ath_smoothing_rate, 0,
"rate control: retry threshold to credit rate raise (%%)");
/* XXX bounds check [2..100] */
SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO,
"sample_rate", CTLFLAG_RW, &osc->ath_sample_rate,0,
"rate control: # good periods before raising rate");
}
struct ath_ratectrl *
ath_rate_attach(struct ath_softc *sc)
{
struct sample_softc *osc;
DPRINTF(sc, "%s:\n", __func__);
osc = malloc(sizeof(struct sample_softc), M_DEVBUF, M_NOWAIT|M_ZERO);
if (osc == NULL)
return NULL;
osc->arc.arc_space = sizeof(struct sample_node);
osc->ath_smoothing_rate = 95; /* ewma percentage (out of 100) */
osc->ath_sample_rate = 10; /* send a different bit-rate 1/X packets */
ath_rate_sysctlattach(sc, osc);
return &osc->arc;
}
void
ath_rate_detach(struct ath_ratectrl *arc)
{
struct sample_softc *osc = (struct sample_softc *) arc;
free(osc, M_DEVBUF);
}
/*
* Module glue.
*/
static int
sample_modevent(module_t mod, int type, void *unused)
{
switch (type) {
case MOD_LOAD:
if (bootverbose)
printf("ath_rate: version 1.2 <SampleRate bit-rate selection algorithm>\n");
return 0;
case MOD_UNLOAD:
return 0;
}
return EINVAL;
}
static moduledata_t sample_mod = {
"ath_rate",
sample_modevent,
0
};
DECLARE_MODULE(ath_rate, sample_mod, SI_SUB_DRIVERS, SI_ORDER_FIRST);
MODULE_VERSION(ath_rate, 1);
MODULE_DEPEND(ath_rate, ath_hal, 1, 1, 1); /* Atheros HAL */
MODULE_DEPEND(ath_rate, wlan, 1, 1, 1);

250
sys/dev/ic/athrate-sample.h Normal file
View File

@ -0,0 +1,250 @@
/*-
* Copyright (c) 2005 John Bicket
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer,
* without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
* redistribution must be conditioned upon including a substantially
* similar Disclaimer requirement for further binary redistribution.
* 3. Neither the names of the above-listed copyright holders nor the names
* of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGES.
*
* $FreeBSD: src/sys/dev/ath/ath_rate/sample/sample.h,v 1.3 2005/03/20 01:27:33 sam Exp $
*/
/*
* Defintions for the Atheros Wireless LAN controller driver.
*/
#ifndef _DEV_ATH_RATE_SAMPLE_H
#define _DEV_ATH_RATE_SAMPLE_H
/* per-device state */
struct sample_softc {
struct ath_ratectrl arc; /* base state */
int ath_smoothing_rate; /* ewma percentage (out of 100) */
int ath_sample_rate; /* send a different bit-rate 1/X packets */
};
#define ATH_SOFTC_SAMPLE(sc) ((struct sample_softc *)sc->sc_rc)
struct rate_info {
int rate;
int rix;
int rateCode;
int shortPreambleRateCode;
};
struct rate_stats {
unsigned average_tx_time;
int successive_failures;
int tries;
int total_packets;
int packets_acked;
unsigned perfect_tx_time; /* transmit time for 0 retries */
int last_tx;
};
/*
* for now, we track performance for three different packet
* size buckets
*/
#define NUM_PACKET_SIZE_BINS 3
static int packet_size_bins[NUM_PACKET_SIZE_BINS] = {250, 1600, 3000};
/* per-node state */
struct sample_node {
int static_rate_ndx;
int num_rates;
struct rate_info rates[IEEE80211_RATE_MAXSIZE];
struct rate_stats stats[NUM_PACKET_SIZE_BINS][IEEE80211_RATE_MAXSIZE];
int last_sample_ndx[NUM_PACKET_SIZE_BINS];
int current_sample_ndx[NUM_PACKET_SIZE_BINS];
int packets_sent[NUM_PACKET_SIZE_BINS];
int current_rate[NUM_PACKET_SIZE_BINS];
int packets_since_switch[NUM_PACKET_SIZE_BINS];
unsigned jiffies_since_switch[NUM_PACKET_SIZE_BINS];
int packets_since_sample[NUM_PACKET_SIZE_BINS];
unsigned sample_tt[NUM_PACKET_SIZE_BINS];
};
#define ATH_NODE_SAMPLE(an) ((struct sample_node *)&an[1])
#ifndef MIN
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#endif
#ifndef MAX
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#endif
#define WIFI_CW_MIN 31
#define WIFI_CW_MAX 1023
struct ar5212_desc {
/*
* tx_control_0
*/
u_int32_t frame_len:12;
u_int32_t reserved_12_15:4;
u_int32_t xmit_power:6;
u_int32_t rts_cts_enable:1;
u_int32_t veol:1;
u_int32_t clear_dest_mask:1;
u_int32_t ant_mode_xmit:4;
u_int32_t inter_req:1;
u_int32_t encrypt_key_valid:1;
u_int32_t cts_enable:1;
/*
* tx_control_1
*/
u_int32_t buf_len:12;
u_int32_t more:1;
u_int32_t encrypt_key_index:7;
u_int32_t frame_type:4;
u_int32_t no_ack:1;
u_int32_t comp_proc:2;
u_int32_t comp_iv_len:2;
u_int32_t comp_icv_len:2;
u_int32_t reserved_31:1;
/*
* tx_control_2
*/
u_int32_t rts_duration:15;
u_int32_t duration_update_enable:1;
u_int32_t xmit_tries0:4;
u_int32_t xmit_tries1:4;
u_int32_t xmit_tries2:4;
u_int32_t xmit_tries3:4;
/*
* tx_control_3
*/
u_int32_t xmit_rate0:5;
u_int32_t xmit_rate1:5;
u_int32_t xmit_rate2:5;
u_int32_t xmit_rate3:5;
u_int32_t rts_cts_rate:5;
u_int32_t reserved_25_31:7;
/*
* tx_status_0
*/
u_int32_t frame_xmit_ok:1;
u_int32_t excessive_retries:1;
u_int32_t fifo_underrun:1;
u_int32_t filtered:1;
u_int32_t rts_fail_count:4;
u_int32_t data_fail_count:4;
u_int32_t virt_coll_count:4;
u_int32_t send_timestamp:16;
/*
* tx_status_1
*/
u_int32_t done:1;
u_int32_t seq_num:12;
u_int32_t ack_sig_strength:8;
u_int32_t final_ts_index:2;
u_int32_t comp_success:1;
u_int32_t xmit_antenna:1;
u_int32_t reserved_25_31_x:7;
} __packed;
/*
* Calculate the transmit duration of a frame.
*/
static unsigned calc_usecs_unicast_packet(struct ath_softc *sc,
int length,
int rix, int short_retries, int long_retries) {
const HAL_RATE_TABLE *rt = sc->sc_currates;
/* pg 205 ieee.802.11.pdf */
unsigned t_slot = 20;
unsigned t_difs = 50;
unsigned t_sifs = 10;
struct ieee80211com *ic = &sc->sc_ic;
int tt = 0;
int x = 0;
int cw = WIFI_CW_MIN;
int cix = rt->info[rix].controlRate;
int rts = 0;
int cts = 0;
KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode));
if (rt->info[rix].phy == IEEE80211_T_OFDM) {
t_slot = 9;
t_sifs = 9;
t_difs = 28;
}
if ((ic->ic_flags & IEEE80211_F_USEPROT) &&
rt->info[rix].phy == IEEE80211_T_OFDM) {
if (ic->ic_protmode == IEEE80211_PROT_RTSCTS)
rts = 1;
else if (ic->ic_protmode == IEEE80211_PROT_CTSONLY)
cts = 1;
cix = rt->info[sc->sc_protrix].controlRate;
}
if (length > ic->ic_rtsthreshold) {
rts = 1;
}
if (rts || cts) {
int ctsrate = rt->info[cix].rateCode;
int ctsduration = 0;
ctsrate |= rt->info[cix].shortPreamble;
if (rts) /* SIFS + CTS */
ctsduration += rt->info[cix].spAckDuration;
ctsduration += ath_hal_computetxtime(sc->sc_ah,
rt, length, rix, AH_TRUE);
if (cts) /* SIFS + ACK */
ctsduration += rt->info[cix].spAckDuration;
tt += (short_retries + 1) * ctsduration;
}
tt += t_difs;
tt += (long_retries+1)*(t_sifs + rt->info[cix].spAckDuration);
tt += (long_retries+1)*ath_hal_computetxtime(sc->sc_ah, rt, length,
rix, AH_TRUE);
for (x = 0; x <= short_retries + long_retries; x++) {
cw = MIN(WIFI_CW_MAX, (cw + 1) * 2);
tt += (t_slot * cw/2);
}
return tt;
}
#endif /* _DEV_ATH_RATE_SAMPLE_H */

140
sys/dev/ic/athrate.h Normal file
View File

@ -0,0 +1,140 @@
/*-
* Copyright (c) 2004-2005 Sam Leffler, Errno Consulting
* Copyright (c) 2004 Video54 Technologies, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer,
without modification.
* 2. Redistributions in binary form must reproduce at minimum a disclaimer
* similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
* redistribution must be conditioned upon including a substantially
* similar Disclaimer requirement for further binary redistribution.
* 3. Neither the names of the above-listed copyright holders nor the names
* of any contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* NO WARRANTY
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
* IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGES.
*
* $FreeBSD: src/sys/dev/ath/if_athrate.h,v 1.4 2005/04/02 18:54:30 sam Exp $
*/
#ifndef _ATH_RATECTRL_H_
#define _ATH_RATECTRL_H_
/*
* Interface definitions for transmit rate control modules for the
* Atheros driver.
*
* A rate control module is responsible for choosing the transmit rate
* for each data frame. Management+control frames are always sent at
* a fixed rate.
*
* Only one module may be present at a time; the driver references
* rate control interfaces by symbol name. If multiple modules are
* to be supported we'll need to switch to a registration-based scheme
* as is currently done, for example, for authentication modules.
*
* An instance of the rate control module is attached to each device
* at attach time and detached when the device is destroyed. The module
* may associate data with each device and each node (station). Both
* sets of storage are opaque except for the size of the per-node storage
* which must be provided when the module is attached.
*
* The rate control module is notified for each state transition and
* station association/reassociation. Otherwise it is queried for a
* rate for each outgoing frame and provided status from each transmitted
* frame. Any ancillary processing is the responsibility of the module
* (e.g. if periodic processing is required then the module should setup
* it's own timer).
*
* In addition to the transmit rate for each frame the module must also
* indicate the number of attempts to make at the specified rate. If this
* number is != ATH_TXMAXTRY then an additional callback is made to setup
* additional transmit state. The rate control code is assumed to write
* this additional data directly to the transmit descriptor.
*/
struct ath_softc;
struct ath_node;
struct ath_desc;
struct ath_ratectrl {
size_t arc_space; /* space required for per-node state */
};
/*
* Attach/detach a rate control module.
*/
struct ath_ratectrl *ath_rate_attach(struct ath_softc *);
void ath_rate_detach(struct ath_ratectrl *);
/*
* State storage handling.
*/
/*
* Initialize per-node state already allocated for the specified
* node; this space can be assumed initialized to zero.
*/
void ath_rate_node_init(struct ath_softc *, struct ath_node *);
/*
* Cleanup any per-node state prior to the node being reclaimed.
*/
void ath_rate_node_cleanup(struct ath_softc *, struct ath_node *);
/*
* Update rate control state on station associate/reassociate
* (when operating as an ap or for nodes discovered when operating
* in ibss mode).
*/
void ath_rate_newassoc(struct ath_softc *, struct ath_node *,
int isNewAssociation);
/*
* Update/reset rate control state for 802.11 state transitions.
* Important mostly as the analog to ath_rate_newassoc when operating
* in station mode.
*/
void ath_rate_newstate(struct ath_softc *, enum ieee80211_state);
/*
* Transmit handling.
*/
/*
* Return the transmit info for a data packet. If multi-rate state
* is to be setup then try0 should contain a value other than ATH_TXMATRY
* and ath_rate_setupxtxdesc will be called after deciding if the frame
* can be transmitted with multi-rate retry.
*/
void ath_rate_findrate(struct ath_softc *, struct ath_node *,
int shortPreamble, size_t frameLen,
u_int8_t *rix, int *try0, u_int8_t *txrate);
/*
* Setup any extended (multi-rate) descriptor state for a data packet.
* The rate index returned by ath_rate_findrate is passed back in.
*/
void ath_rate_setupxtxdesc(struct ath_softc *, struct ath_node *,
struct ath_desc *, int shortPreamble, u_int8_t rix);
/*
* Update rate control state for a packet associated with the
* supplied transmit descriptor. The routine is invoked both
* for packets that were successfully sent and for those that
* failed (consult the descriptor for details).
*/
void ath_rate_tx_complete(struct ath_softc *, struct ath_node *,
const struct ath_desc *last, const struct ath_desc *first);
#endif /* _ATH_RATECTRL_H_ */

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -33,7 +33,7 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGES.
*
* $FreeBSD: src/sys/dev/ath/if_athvar.h,v 1.14 2004/04/03 03:33:02 sam Exp $
* $FreeBSD: src/sys/dev/ath/if_athvar.h,v 1.23 2005/04/12 17:56:43 sam Exp $
*/
/*
@ -47,73 +47,177 @@
#include <contrib/dev/ath/ah.h>
#include <net80211/ieee80211_radiotap.h>
#include <dev/ath/if_athioctl.h>
#include <dev/ath/if_athrate.h>
#define ATH_TIMEOUT 1000
#define ATH_RXBUF 40 /* number of RX buffers */
#define ATH_TXBUF 60 /* number of TX buffers */
#define ATH_TXDESC 8 /* number of descriptors per buffer */
#define ATH_TXBUF 100 /* number of TX buffers */
#define ATH_TXDESC 10 /* number of descriptors per buffer */
#define ATH_TXMAXTRY 11 /* max number of transmit attempts */
#define ATH_TXINTR_PERIOD 5 /* max number of batched tx descriptors */
struct ath_recv_hist {
int arh_ticks; /* sample time by system clock */
u_int8_t arh_rssi; /* rssi */
u_int8_t arh_antenna; /* antenna */
};
#define ATH_RHIST_SIZE 16 /* number of samples */
#define ATH_RHIST_NOTIME (~0)
/* driver-specific node */
/* driver-specific node state */
struct ath_node {
struct ieee80211_node an_node; /* base class */
u_int an_tx_ok; /* tx ok pkt */
u_int an_tx_err; /* tx !ok pkt */
u_int an_tx_retr; /* tx retry count */
int an_tx_upper; /* tx upper rate req cnt */
u_int an_tx_antenna; /* antenna for last good frame */
u_int an_rx_antenna; /* antenna for last rcvd frame */
struct ath_recv_hist an_rx_hist[ATH_RHIST_SIZE];
u_int an_rx_hist_next;/* index of next ``free entry'' */
u_int8_t an_tx_mgtrate; /* h/w rate for management/ctl frames */
u_int8_t an_tx_mgtratesp;/* short preamble h/w rate for " " */
u_int32_t an_avgrssi; /* average rssi over all rx frames */
HAL_NODE_STATS an_halstats; /* rssi statistics used by hal */
/* variable-length rate control state follows */
};
#define ATH_NODE(_n) ((struct ath_node *)(_n))
#define ATH_NODE(ni) ((struct ath_node *)(ni))
#define ATH_NODE_CONST(ni) ((const struct ath_node *)(ni))
#define ATH_RSSI_LPF_LEN 10
#define ATH_RSSI_DUMMY_MARKER 0x127
#define ATH_EP_MUL(x, mul) ((x) * (mul))
#define ATH_RSSI_IN(x) (ATH_EP_MUL((x), HAL_RSSI_EP_MULTIPLIER))
#define ATH_LPF_RSSI(x, y, len) \
((x != ATH_RSSI_DUMMY_MARKER) ? (((x) * ((len) - 1) + (y)) / (len)) : (y))
#define ATH_RSSI_LPF(x, y) do { \
if ((y) >= -20) \
x = ATH_LPF_RSSI((x), ATH_RSSI_IN((y)), ATH_RSSI_LPF_LEN); \
} while (0)
struct ath_buf {
TAILQ_ENTRY(ath_buf) bf_list;
STAILQ_ENTRY(ath_buf) bf_list;
int bf_nseg;
bus_dmamap_t bf_dmamap; /* DMA map of the buffer */
struct ath_desc *bf_desc; /* virtual addr of desc */
bus_addr_t bf_daddr; /* physical addr of desc */
bus_dmamap_t bf_dmamap; /* DMA map for mbuf chain */
struct mbuf *bf_m; /* mbuf for buf */
struct ieee80211_node *bf_node; /* pointer to the node */
bus_size_t bf_mapsize;
#define ATH_MAX_SCATTER 64
#define ATH_MAX_SCATTER ATH_TXDESC /* max(tx,rx,beacon) desc's */
bus_dma_segment_t bf_segs[ATH_MAX_SCATTER];
};
typedef STAILQ_HEAD(, ath_buf) ath_bufhead;
/*
* DMA state for tx/rx descriptors.
*/
struct ath_descdma {
const char* dd_name;
struct ath_desc *dd_desc; /* descriptors */
bus_addr_t dd_desc_paddr; /* physical addr of dd_desc */
bus_addr_t dd_desc_len; /* size of dd_desc */
bus_dma_segment_t dd_dseg;
bus_dma_tag_t dd_dmat; /* bus DMA tag */
bus_dmamap_t dd_dmamap; /* DMA map for descriptors */
struct ath_buf *dd_bufptr; /* associated buffers */
};
/*
* Data transmit queue state. One of these exists for each
* hardware transmit queue. Packets sent to us from above
* are assigned to queues based on their priority. Not all
* devices support a complete set of hardware transmit queues.
* For those devices the array sc_ac2q will map multiple
* priorities to fewer hardware queues (typically all to one
* hardware queue).
*/
struct ath_txq {
u_int axq_qnum; /* hardware q number */
u_int axq_depth; /* queue depth (stat only) */
u_int axq_intrcnt; /* interrupt count */
u_int32_t *axq_link; /* link ptr in last TX desc */
STAILQ_HEAD(, ath_buf) axq_q; /* transmit queue */
struct mtx axq_lock; /* lock on q and link */
/*
* State for patching up CTS when bursting.
*/
struct ath_buf *axq_linkbuf; /* va of last buffer */
struct ath_desc *axq_lastdsWithCTS;
/* first desc of last descriptor
* that contains CTS
*/
struct ath_desc *axq_gatingds; /* final desc of the gating desc
* that determines whether
* lastdsWithCTS has been DMA'ed
* or not
*/
};
#define ATH_TXQ_LOCK_INIT(_sc, _tq) \
mtx_init(&(_tq)->axq_lock, \
device_get_nameunit((_sc)->sc_dev), "xmit q", MTX_DEF)
#define ATH_TXQ_LOCK_DESTROY(_tq) mtx_destroy(&(_tq)->axq_lock)
#define ATH_TXQ_LOCK(_tq) mtx_lock(&(_tq)->axq_lock)
#define ATH_TXQ_UNLOCK(_tq) mtx_unlock(&(_tq)->axq_lock)
#define ATH_TXQ_LOCK_ASSERT(_tq) mtx_assert(&(_tq)->axq_lock, MA_OWNED)
#define ATH_TXQ_INSERT_TAIL(_tq, _elm, _field) do { \
STAILQ_INSERT_TAIL(&(_tq)->axq_q, (_elm), _field); \
(_tq)->axq_depth++; \
} while (0)
#define ATH_TXQ_REMOVE_HEAD(_tq, _field) do { \
STAILQ_REMOVE_HEAD(&(_tq)->axq_q, _field); \
(_tq)->axq_depth--; \
} while (0)
struct ath_softc {
struct arpcom sc_arp; /* interface common */
struct ath_stats sc_stats; /* interface statistics */
struct ieee80211com sc_ic; /* IEEE 802.11 common */
int sc_regdomain;
int sc_countrycode;
int sc_debug;
void (*sc_recv_mgmt)(struct ieee80211com *,
struct mbuf *,
struct ieee80211_node *,
int, int, u_int32_t);
int (*sc_newstate)(struct ieee80211com *,
enum ieee80211_state, int);
void (*sc_node_free)(struct ieee80211com *,
struct ieee80211_node *);
void (*sc_node_copy)(struct ieee80211com *,
struct ieee80211_node *,
const struct ieee80211_node *);
void (*sc_node_free)(struct ieee80211_node *);
device_t sc_dev;
bus_space_tag_t sc_st; /* bus space tag */
bus_space_handle_t sc_sh; /* bus space handle */
bus_dma_tag_t sc_dmat; /* bus DMA tag */
struct mtx sc_mtx; /* master lock (recursive) */
struct ath_hal *sc_ah; /* Atheros HAL */
struct ath_ratectrl *sc_rc; /* tx rate control support */
void (*sc_setdefantenna)(struct ath_softc *, u_int);
unsigned int sc_invalid : 1,/* disable hardware accesses */
sc_doani : 1,/* dynamic noise immunity */
sc_probing : 1;/* probing AP on beacon miss */
sc_mrretry : 1, /* multi-rate retry support */
sc_softled : 1, /* enable LED gpio status */
sc_splitmic: 1, /* split TKIP MIC keys */
sc_needmib : 1, /* enable MIB stats intr */
sc_hasdiversity : 1,/* rx diversity available */
sc_diversity : 1,/* enable rx diversity */
sc_hasveol : 1, /* tx VEOL support */
sc_hastpc : 1, /* per-packet TPC support */
sc_ledstate: 1, /* LED on/off state */
sc_blinking: 1, /* LED blink operation active */
sc_mcastkey: 1; /* mcast key cache search */
/* rate tables */
const HAL_RATE_TABLE *sc_rates[IEEE80211_MODE_MAX];
const HAL_RATE_TABLE *sc_currates; /* current rate table */
enum ieee80211_phymode sc_curmode; /* current phy mode */
u_int16_t sc_curtxpow; /* current tx power limit */
HAL_CHANNEL sc_curchan; /* current h/w channel */
u_int8_t sc_rixmap[256]; /* IEEE to h/w rate table ix */
u_int8_t sc_hwmap[32]; /* h/w rate ix to IEEE table */
struct {
u_int8_t ieeerate; /* IEEE rate */
u_int8_t rxflags; /* radiotap rx flags */
u_int8_t txflags; /* radiotap tx flags */
u_int16_t ledon; /* softled on time */
u_int16_t ledoff; /* softled off time */
} sc_hwmap[32]; /* h/w rate ix mappings */
u_int8_t sc_protrix; /* protection rate index */
u_int sc_txantenna; /* tx antenna (fixed or auto) */
HAL_INT sc_imask; /* interrupt mask copy */
u_int sc_keymax; /* size of key cache */
u_int8_t sc_keymap[16]; /* bit map of key cache use */
u_int sc_ledpin; /* GPIO pin for driving LED */
u_int sc_ledon; /* pin setting for LED on */
u_int sc_ledidle; /* idle polling interval */
int sc_ledevent; /* time of last LED event */
u_int8_t sc_rxrate; /* current rx rate for LED */
u_int8_t sc_txrate; /* current tx rate for LED */
u_int16_t sc_ledoff; /* off time for current blink */
struct callout sc_ledtimer; /* led off timer */
struct bpf_if *sc_drvbpf;
union {
@ -127,37 +231,45 @@ struct ath_softc {
} u_rx_rt;
int sc_rx_th_len;
struct ath_desc *sc_desc; /* TX/RX descriptors */
bus_dma_segment_t sc_dseg;
bus_dmamap_t sc_ddmamap; /* DMA map for descriptors */
bus_addr_t sc_desc_paddr; /* physical addr of sc_desc */
bus_addr_t sc_desc_len; /* size of sc_desc */
struct task sc_fataltask; /* fatal int processing */
struct task sc_rxorntask; /* rxorn int processing */
TAILQ_HEAD(, ath_buf) sc_rxbuf; /* receive buffer */
struct ath_descdma sc_rxdma; /* RX descriptos */
ath_bufhead sc_rxbuf; /* receive buffer */
u_int32_t *sc_rxlink; /* link ptr in last RX desc */
struct task sc_rxtask; /* rx int processing */
struct task sc_rxorntask; /* rxorn int processing */
u_int8_t sc_defant; /* current default antenna */
u_int8_t sc_rxotherant; /* rx's on non-default antenna*/
u_int sc_txhalq; /* HAL q for outgoing frames */
u_int32_t *sc_txlink; /* link ptr in last TX desc */
int sc_tx_timer; /* transmit timeout */
TAILQ_HEAD(, ath_buf) sc_txbuf; /* transmit buffer */
struct ath_descdma sc_txdma; /* TX descriptors */
ath_bufhead sc_txbuf; /* transmit buffer */
struct mtx sc_txbuflock; /* txbuf lock */
TAILQ_HEAD(, ath_buf) sc_txq; /* transmitting queue */
struct mtx sc_txqlock; /* lock on txq and txlink */
int sc_tx_timer; /* transmit timeout */
u_int sc_txqsetup; /* h/w queues setup */
u_int sc_txintrperiod;/* tx interrupt batching */
struct ath_txq sc_txq[HAL_NUM_TX_QUEUES];
struct ath_txq *sc_ac2q[5]; /* WME AC -> h/w q map */
struct task sc_txtask; /* tx int processing */
struct ath_descdma sc_bdma; /* beacon descriptors */
ath_bufhead sc_bbuf; /* beacon buffers */
u_int sc_bhalq; /* HAL q for outgoing beacons */
struct ath_buf *sc_bcbuf; /* beacon buffer */
struct ath_buf *sc_bufptr; /* allocated buffer ptr */
u_int sc_bmisscount; /* missed beacon transmits */
u_int32_t sc_ant_tx[8]; /* recent tx frames/antenna */
struct ath_txq *sc_cabq; /* tx q for cab frames */
struct ieee80211_beacon_offsets sc_boff;/* dynamic update state */
struct task sc_bmisstask; /* bmiss int processing */
struct task sc_bstucktask; /* stuck beacon processing */
enum {
OK, /* no change needed */
UPDATE, /* update pending */
COMMIT /* beacon sent, commit change */
} sc_updateslot; /* slot time update fsm */
struct callout sc_cal_ch; /* callout handle for cals */
struct callout sc_scan_ch; /* callout handle for scan */
struct ath_stats sc_stats; /* interface statistics */
};
#define sc_if sc_arp.ac_if
#define sc_tx_th u_tx_rt.th
#define sc_rx_th u_rx_rt.th
@ -169,6 +281,8 @@ struct ath_softc {
#define ATH_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
#define ATH_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_mtx, MA_OWNED)
#define ATH_TXQ_SETUP(sc, i) ((sc)->sc_txqsetup & (1<<i))
#define ATH_TXBUF_LOCK_INIT(_sc) \
mtx_init(&(_sc)->sc_txbuflock, \
device_get_nameunit((_sc)->sc_dev), "xmit buf q", MTX_DEF)
@ -178,14 +292,6 @@ struct ath_softc {
#define ATH_TXBUF_LOCK_ASSERT(_sc) \
mtx_assert(&(_sc)->sc_txbuflock, MA_OWNED)
#define ATH_TXQ_LOCK_INIT(_sc) \
mtx_init(&(_sc)->sc_txqlock, \
device_get_nameunit((_sc)->sc_dev), "xmit q", MTX_DEF)
#define ATH_TXQ_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_txqlock)
#define ATH_TXQ_LOCK(_sc) mtx_lock(&(_sc)->sc_txqlock)
#define ATH_TXQ_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_txqlock)
#define ATH_TXQ_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_txqlock, MA_OWNED)
int ath_attach(u_int16_t, struct ath_softc *);
int ath_detach(struct ath_softc *);
void ath_resume(struct ath_softc *);
@ -196,17 +302,16 @@ void ath_intr(void *);
/*
* HAL definitions to comply with local coding convention.
*/
#define ath_hal_detach(_ah) \
((*(_ah)->ah_detach)((_ah)))
#define ath_hal_reset(_ah, _opmode, _chan, _outdoor, _pstatus) \
((*(_ah)->ah_reset)((_ah), (_opmode), (_chan), (_outdoor), (_pstatus)))
#define ath_hal_getratetable(_ah, _mode) \
((*(_ah)->ah_getRateTable)((_ah), (_mode)))
#define ath_hal_getregdomain(_ah) \
((*(_ah)->ah_getRegDomain)((_ah)))
#define ath_hal_getcountrycode(_ah) (_ah)->ah_countryCode
#define ath_hal_getmac(_ah, _mac) \
((*(_ah)->ah_getMacAddress)((_ah), (_mac)))
#define ath_hal_detach(_ah) \
((*(_ah)->ah_detach)((_ah)))
#define ath_hal_setmac(_ah, _mac) \
((*(_ah)->ah_setMacAddress)((_ah), (_mac)))
#define ath_hal_intrset(_ah, _mask) \
((*(_ah)->ah_setInterrupts)((_ah), (_mask)))
#define ath_hal_intrget(_ah) \
@ -219,10 +324,12 @@ void ath_intr(void *);
((*(_ah)->ah_updateTxTrigLevel)((_ah), (_inc)))
#define ath_hal_setpower(_ah, _mode, _sleepduration) \
((*(_ah)->ah_setPowerMode)((_ah), (_mode), AH_TRUE, (_sleepduration)))
#define ath_hal_keycachesize(_ah) \
((*(_ah)->ah_getKeyCacheSize)((_ah)))
#define ath_hal_keyreset(_ah, _ix) \
((*(_ah)->ah_resetKeyCacheEntry)((_ah), (_ix)))
#define ath_hal_keyset(_ah, _ix, _pk) \
((*(_ah)->ah_setKeyCacheEntry)((_ah), (_ix), (_pk), NULL, AH_FALSE))
#define ath_hal_keyset(_ah, _ix, _pk, _mac) \
((*(_ah)->ah_setKeyCacheEntry)((_ah), (_ix), (_pk), (_mac), AH_FALSE))
#define ath_hal_keyisvalid(_ah, _ix) \
(((*(_ah)->ah_isKeyCacheEntryValid)((_ah), (_ix))))
#define ath_hal_keysetmac(_ah, _ix, _mac) \
@ -249,6 +356,8 @@ void ath_intr(void *);
((*(_ah)->ah_setTxDP)((_ah), (_q), (_bufaddr)))
#define ath_hal_gettxbuf(_ah, _q) \
((*(_ah)->ah_getTxDP)((_ah), (_q)))
#define ath_hal_numtxpending(_ah, _q) \
((*(_ah)->ah_numTxPending)((_ah), (_q)))
#define ath_hal_getrxbuf(_ah) \
((*(_ah)->ah_getRxDP)((_ah)))
#define ath_hal_txstart(_ah, _q) \
@ -259,17 +368,18 @@ void ath_intr(void *);
((*(_ah)->ah_perCalibration)((_ah), (_chan)))
#define ath_hal_setledstate(_ah, _state) \
((*(_ah)->ah_setLedState)((_ah), (_state)))
#define ath_hal_beaconinit(_ah, _opmode, _nextb, _bperiod) \
((*(_ah)->ah_beaconInit)((_ah), (_opmode), (_nextb), (_bperiod)))
#define ath_hal_beaconinit(_ah, _nextb, _bperiod) \
((*(_ah)->ah_beaconInit)((_ah), (_nextb), (_bperiod)))
#define ath_hal_beaconreset(_ah) \
((*(_ah)->ah_resetStationBeaconTimers)((_ah)))
#define ath_hal_beacontimers(_ah, _bs, _tsf, _dc, _cc) \
((*(_ah)->ah_setStationBeaconTimers)((_ah), (_bs), (_tsf), \
(_dc), (_cc)))
#define ath_hal_beacontimers(_ah, _bs) \
((*(_ah)->ah_setStationBeaconTimers)((_ah), (_bs)))
#define ath_hal_setassocid(_ah, _bss, _associd) \
((*(_ah)->ah_writeAssocid)((_ah), (_bss), (_associd), 0))
#define ath_hal_setopmode(_ah, _opmode) \
((*(_ah)->ah_setPCUConfig)((_ah), (_opmode)))
((*(_ah)->ah_writeAssocid)((_ah), (_bss), (_associd)))
#define ath_hal_phydisable(_ah) \
((*(_ah)->ah_phyDisable)((_ah)))
#define ath_hal_setopmode(_ah) \
((*(_ah)->ah_setPCUConfig)((_ah)))
#define ath_hal_stoptxdma(_ah, _qnum) \
((*(_ah)->ah_stopTxDma)((_ah), (_qnum)))
#define ath_hal_stoppcurecv(_ah) \
@ -278,27 +388,90 @@ void ath_intr(void *);
((*(_ah)->ah_startPcuReceive)((_ah)))
#define ath_hal_stopdmarecv(_ah) \
((*(_ah)->ah_stopDmaReceive)((_ah)))
#define ath_hal_dumpstate(_ah) \
((*(_ah)->ah_dumpState)((_ah)))
#define ath_hal_getdiagstate(_ah, _id, _data, _size) \
((*(_ah)->ah_getDiagState)((_ah), (_id), (_data), (_size)))
#define ath_hal_getdiagstate(_ah, _id, _indata, _insize, _outdata, _outsize) \
((*(_ah)->ah_getDiagState)((_ah), (_id), \
(_indata), (_insize), (_outdata), (_outsize)))
#define ath_hal_setuptxqueue(_ah, _type, _irq) \
((*(_ah)->ah_setupTxQueue)((_ah), (_type), (_irq)))
#define ath_hal_resettxqueue(_ah, _q) \
((*(_ah)->ah_resetTxQueue)((_ah), (_q)))
#define ath_hal_releasetxqueue(_ah, _q) \
((*(_ah)->ah_releaseTxQueue)((_ah), (_q)))
#define ath_hal_hasveol(_ah) \
((*(_ah)->ah_hasVEOL)((_ah)))
#define ath_hal_gettxqueueprops(_ah, _q, _qi) \
((*(_ah)->ah_getTxQueueProps)((_ah), (_q), (_qi)))
#define ath_hal_settxqueueprops(_ah, _q, _qi) \
((*(_ah)->ah_setTxQueueProps)((_ah), (_q), (_qi)))
#define ath_hal_getrfgain(_ah) \
((*(_ah)->ah_getRfGain)((_ah)))
#define ath_hal_rxmonitor(_ah) \
((*(_ah)->ah_rxMonitor)((_ah)))
#define ath_hal_getdefantenna(_ah) \
((*(_ah)->ah_getDefAntenna)((_ah)))
#define ath_hal_setdefantenna(_ah, _ant) \
((*(_ah)->ah_setDefAntenna)((_ah), (_ant)))
#define ath_hal_rxmonitor(_ah, _arg) \
((*(_ah)->ah_rxMonitor)((_ah), (_arg)))
#define ath_hal_mibevent(_ah, _stats) \
((*(_ah)->ah_procMibEvent)((_ah), (_stats)))
#define ath_hal_setslottime(_ah, _us) \
((*(_ah)->ah_setSlotTime)((_ah), (_us)))
#define ath_hal_getslottime(_ah) \
((*(_ah)->ah_getSlotTime)((_ah)))
#define ath_hal_setacktimeout(_ah, _us) \
((*(_ah)->ah_setAckTimeout)((_ah), (_us)))
#define ath_hal_getacktimeout(_ah) \
((*(_ah)->ah_getAckTimeout)((_ah)))
#define ath_hal_setctstimeout(_ah, _us) \
((*(_ah)->ah_setCTSTimeout)((_ah), (_us)))
#define ath_hal_getctstimeout(_ah) \
((*(_ah)->ah_getCTSTimeout)((_ah)))
#define ath_hal_getcapability(_ah, _cap, _param, _result) \
((*(_ah)->ah_getCapability)((_ah), (_cap), (_param), (_result)))
#define ath_hal_setcapability(_ah, _cap, _param, _v, _status) \
((*(_ah)->ah_setCapability)((_ah), (_cap), (_param), (_v), (_status)))
#define ath_hal_ciphersupported(_ah, _cipher) \
(ath_hal_getcapability(_ah, HAL_CAP_CIPHER, _cipher, NULL) == HAL_OK)
#define ath_hal_getregdomain(_ah, _prd) \
ath_hal_getcapability(_ah, HAL_CAP_REG_DMN, 0, (_prd))
#define ath_hal_getcountrycode(_ah, _pcc) \
(*(_pcc) = (_ah)->ah_countryCode)
#define ath_hal_tkipsplit(_ah) \
(ath_hal_getcapability(_ah, HAL_CAP_TKIP_SPLIT, 0, NULL) == HAL_OK)
#define ath_hal_hwphycounters(_ah) \
(ath_hal_getcapability(_ah, HAL_CAP_PHYCOUNTERS, 0, NULL) == HAL_OK)
#define ath_hal_hasdiversity(_ah) \
(ath_hal_getcapability(_ah, HAL_CAP_DIVERSITY, 0, NULL) == HAL_OK)
#define ath_hal_getdiversity(_ah) \
(ath_hal_getcapability(_ah, HAL_CAP_DIVERSITY, 1, NULL) == HAL_OK)
#define ath_hal_setdiversity(_ah, _v) \
ath_hal_setcapability(_ah, HAL_CAP_DIVERSITY, 1, _v, NULL)
#define ath_hal_getdiag(_ah, _pv) \
(ath_hal_getcapability(_ah, HAL_CAP_DIAG, 0, _pv) == HAL_OK)
#define ath_hal_setdiag(_ah, _v) \
ath_hal_setcapability(_ah, HAL_CAP_DIAG, 0, _v, NULL)
#define ath_hal_getnumtxqueues(_ah, _pv) \
(ath_hal_getcapability(_ah, HAL_CAP_NUM_TXQUEUES, 0, _pv) == HAL_OK)
#define ath_hal_hasveol(_ah) \
(ath_hal_getcapability(_ah, HAL_CAP_VEOL, 0, NULL) == HAL_OK)
#define ath_hal_hastxpowlimit(_ah) \
(ath_hal_getcapability(_ah, HAL_CAP_TXPOW, 0, NULL) == HAL_OK)
#define ath_hal_settxpowlimit(_ah, _pow) \
((*(_ah)->ah_setTxPowerLimit)((_ah), (_pow)))
#define ath_hal_gettxpowlimit(_ah, _ppow) \
(ath_hal_getcapability(_ah, HAL_CAP_TXPOW, 1, _ppow) == HAL_OK)
#define ath_hal_getmaxtxpow(_ah, _ppow) \
(ath_hal_getcapability(_ah, HAL_CAP_TXPOW, 2, _ppow) == HAL_OK)
#define ath_hal_gettpscale(_ah, _scale) \
(ath_hal_getcapability(_ah, HAL_CAP_TXPOW, 3, _scale) == HAL_OK)
#define ath_hal_settpscale(_ah, _v) \
ath_hal_setcapability(_ah, HAL_CAP_TXPOW, 3, _v, NULL)
#define ath_hal_hastpc(_ah) \
(ath_hal_getcapability(_ah, HAL_CAP_TPC, 0, NULL) == HAL_OK)
#define ath_hal_gettpc(_ah) \
(ath_hal_getcapability(_ah, HAL_CAP_TPC, 1, NULL) == HAL_OK)
#define ath_hal_settpc(_ah, _v) \
ath_hal_setcapability(_ah, HAL_CAP_TPC, 1, _v, NULL)
#define ath_hal_hasbursting(_ah) \
(ath_hal_getcapability(_ah, HAL_CAP_BURST, 0, NULL) == HAL_OK)
#define ath_hal_setupbeacondesc(_ah, _ds, _opmode, _flen, _hlen, \
_rate, _antmode) \
((*(_ah)->ah_setupBeaconDesc)((_ah), (_ds), (_opmode), \
(_flen), (_hlen), (_rate), (_antmode)))
#define ath_hal_setuprxdesc(_ah, _ds, _size, _intreq) \
((*(_ah)->ah_setupRxDesc)((_ah), (_ds), (_size), (_intreq)))
#define ath_hal_rxprocdesc(_ah, _ds, _dspa, _dsnext) \
@ -309,13 +482,22 @@ void ath_intr(void *);
((*(_ah)->ah_setupTxDesc)((_ah), (_ds), (_plen), (_hlen), (_atype), \
(_txpow), (_txr0), (_txtr0), (_keyix), (_ant), \
(_flags), (_rtsrate), (_rtsdura)))
#define ath_hal_setupxtxdesc(_ah, _ds, _short, \
#define ath_hal_setupxtxdesc(_ah, _ds, \
_txr1, _txtr1, _txr2, _txtr2, _txr3, _txtr3) \
((*(_ah)->ah_setupXTxDesc)((_ah), (_ds), (_short), \
((*(_ah)->ah_setupXTxDesc)((_ah), (_ds), \
(_txr1), (_txtr1), (_txr2), (_txtr2), (_txr3), (_txtr3)))
#define ath_hal_filltxdesc(_ah, _ds, _l, _first, _last) \
((*(_ah)->ah_fillTxDesc)((_ah), (_ds), (_l), (_first), (_last)))
#define ath_hal_filltxdesc(_ah, _ds, _l, _first, _last, _ds0) \
((*(_ah)->ah_fillTxDesc)((_ah), (_ds), (_l), (_first), (_last), (_ds0)))
#define ath_hal_txprocdesc(_ah, _ds) \
((*(_ah)->ah_procTxDesc)((_ah), (_ds)))
#define ath_hal_updateCTSForBursting(_ah, _ds, _prevds, _prevdsWithCTS, \
_gatingds, _txOpLimit, _ctsDuration) \
((*(_ah)->ah_updateCTSForBursting)((_ah), (_ds), (_prevds), \
(_prevdsWithCTS), (_gatingds), (_txOpLimit), (_ctsDuration)))
#define ath_hal_gpioCfgOutput(_ah, _gpio) \
((*(_ah)->ah_gpioCfgOutput)((_ah), (_gpio)))
#define ath_hal_gpioset(_ah, _gpio, _b) \
((*(_ah)->ah_gpioSet)((_ah), (_gpio), (_b)))
#endif /* _DEV_ATH_ATHVAR_H */

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 2002-2004 Sam Leffler, Errno Consulting
* Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -35,49 +35,33 @@
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/dev/ath/if_ath_pci.c,v 1.8 2004/04/02 23:57:10 sam Exp $");
__FBSDID("$FreeBSD: src/sys/dev/ath/if_ath_pci.c,v 1.12 2005/03/05 19:06:12 imp Exp $");
/*
* PCI/Cardbus front-end for the Atheros Wireless LAN controller driver.
*/
#include "opt_inet.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/errno.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <sys/bus.h>
#include <sys/rman.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <net/if_media.h>
#include <net/ethernet.h>
#include <net/if_llc.h>
#include <net/if_arp.h>
#include <net80211/ieee80211.h>
#include <net80211/ieee80211_crypto.h>
#include <net80211/ieee80211_node.h>
#include <net80211/ieee80211_proto.h>
#include <net80211/ieee80211_var.h>
#ifdef INET
#include <netinet/in.h>
#include <netinet/if_ether.h>
#endif
#include <dev/ath/if_athvar.h>
#include <contrib/dev/ath/ah.h>
@ -92,13 +76,11 @@ struct ath_pci_softc {
struct ath_softc sc_sc;
struct resource *sc_sr; /* memory resource */
struct resource *sc_irq; /* irq resource */
void *sc_ih; /* intererupt handler */
u_int8_t sc_saved_intline;
u_int8_t sc_saved_cachelinesz;
u_int8_t sc_saved_lattimer;
void *sc_ih; /* interrupt handler */
};
#define BS_BAR 0x10
#define PCIR_RETRY_TIMEOUT 0x41
static int
ath_pci_probe(device_t dev)
@ -106,39 +88,55 @@ ath_pci_probe(device_t dev)
const char* devname;
devname = ath_hal_probe(pci_get_vendor(dev), pci_get_device(dev));
if (devname) {
if (devname != NULL) {
device_set_desc(dev, devname);
return 0;
return BUS_PROBE_DEFAULT;
}
return ENXIO;
}
static u_int32_t
ath_pci_setup(device_t dev)
{
u_int32_t cmd;
/*
* Enable memory mapping and bus mastering.
*/
cmd = pci_read_config(dev, PCIR_COMMAND, 4);
cmd |= PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN;
pci_write_config(dev, PCIR_COMMAND, cmd, 4);
cmd = pci_read_config(dev, PCIR_COMMAND, 4);
if ((cmd & PCIM_CMD_MEMEN) == 0) {
device_printf(dev, "failed to enable memory mapping\n");
return 0;
}
if ((cmd & PCIM_CMD_BUSMASTEREN) == 0) {
device_printf(dev, "failed to enable bus mastering\n");
return 0;
}
/*
* Disable retry timeout to keep PCI Tx retries from
* interfering with C3 CPU state.
*/
pci_write_config(dev, PCIR_RETRY_TIMEOUT, 0, 1);
return 1;
}
static int
ath_pci_attach(device_t dev)
{
struct ath_pci_softc *psc = device_get_softc(dev);
struct ath_softc *sc = &psc->sc_sc;
u_int32_t cmd;
int error = ENXIO;
int rid;
bzero(psc, sizeof (*psc));
sc->sc_dev = dev;
cmd = pci_read_config(dev, PCIR_COMMAND, 4);
cmd |= PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN;
pci_write_config(dev, PCIR_COMMAND, cmd, 4);
cmd = pci_read_config(dev, PCIR_COMMAND, 4);
if ((cmd & PCIM_CMD_MEMEN) == 0) {
device_printf(dev, "failed to enable memory mapping\n");
if (!ath_pci_setup(dev))
goto bad;
}
if ((cmd & PCIM_CMD_BUSMASTEREN) == 0) {
device_printf(dev, "failed to enable bus mastering\n");
goto bad;
}
/*
* Setup memory-mapping of PCI registers.
@ -185,7 +183,7 @@ ath_pci_attach(device_t dev)
NULL, NULL, /* filter, filterarg */
0x3ffff, /* maxsize XXX */
ATH_MAX_SCATTER, /* nsegments */
0xffff, /* maxsegsize XXX */
BUS_SPACE_MAXADDR, /* maxsegsize */
BUS_DMA_ALLOCNOW, /* flags */
NULL, /* lockfunc */
NULL, /* lockarg */
@ -251,10 +249,6 @@ ath_pci_suspend(device_t dev)
ath_suspend(&psc->sc_sc);
psc->sc_saved_intline = pci_read_config(dev, PCIR_INTLINE, 1);
psc->sc_saved_cachelinesz= pci_read_config(dev, PCIR_CACHELNSZ, 1);
psc->sc_saved_lattimer = pci_read_config(dev, PCIR_LATTIMER, 1);
return (0);
}
@ -262,16 +256,9 @@ static int
ath_pci_resume(device_t dev)
{
struct ath_pci_softc *psc = device_get_softc(dev);
u_int16_t cmd;
pci_write_config(dev, PCIR_INTLINE, psc->sc_saved_intline, 1);
pci_write_config(dev, PCIR_CACHELNSZ, psc->sc_saved_cachelinesz, 1);
pci_write_config(dev, PCIR_LATTIMER, psc->sc_saved_lattimer, 1);
/* re-enable mem-map and busmastering */
cmd = pci_read_config(dev, PCIR_COMMAND, 2);
cmd |= PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN;
pci_write_config(dev, PCIR_COMMAND, cmd, 2);
if (!ath_pci_setup(dev))
return ENXIO;
ath_resume(&psc->sc_sc);
@ -300,3 +287,4 @@ DRIVER_MODULE(if_ath, cardbus, ath_pci_driver, ath_devclass, 0, 0);
MODULE_VERSION(if_ath, 1);
MODULE_DEPEND(if_ath, ath_hal, 1, 1, 1); /* Atheros HAL */
MODULE_DEPEND(if_ath, wlan, 1, 1, 1); /* 802.11 media layer */
MODULE_DEPEND(if_ath, ath_rate, 1, 1, 1); /* rate control algorithm */